diff --git a/LEGO1/lego/legoomni/include/infocenter.h b/LEGO1/lego/legoomni/include/infocenter.h
index 871fc1e9..46e6b463 100644
--- a/LEGO1/lego/legoomni/include/infocenter.h
+++ b/LEGO1/lego/legoomni/include/infocenter.h
@@ -61,11 +61,11 @@ public:
 		c_nickSelected = 33,
 		c_lauraSelected = 34,
 
-		c_unk40 = 40,
-		c_unk41 = 41,
-		c_unk42 = 42,
-		c_unk43 = 43,
-		c_unk44 = 44,
+		c_mamaMovie = 40,
+		c_papaMovie = 41,
+		c_pepperMovie = 42,
+		c_nickMovie = 43,
+		c_lauraMovie = 44,
 
 		c_goToRegBook = 70,
 		c_goToRegBookRed = 71,
diff --git a/LEGO1/lego/legoomni/include/infocenterstate.h b/LEGO1/lego/legoomni/include/infocenterstate.h
index 1bf64cc9..171e3c0b 100644
--- a/LEGO1/lego/legoomni/include/infocenterstate.h
+++ b/LEGO1/lego/legoomni/include/infocenterstate.h
@@ -34,6 +34,7 @@ public:
 	inline Playlist& GetUnknown0x14() { return m_unk0x14; }
 	inline Playlist& GetUnknown0x68() { return m_unk0x68; }
 	inline MxU32 GetUnknown0x74() { return m_unk0x74; }
+	inline Playlist* GetUnknown0x44() { return m_unk0x44; }
 
 	inline void SetUnknown0x74(MxU32 p_unk0x74) { m_unk0x74 = p_unk0x74; }
 
diff --git a/LEGO1/lego/legoomni/include/legocontrolmanager.h b/LEGO1/lego/legoomni/include/legocontrolmanager.h
index b4222164..46719167 100644
--- a/LEGO1/lego/legoomni/include/legocontrolmanager.h
+++ b/LEGO1/lego/legoomni/include/legocontrolmanager.h
@@ -6,6 +6,8 @@
 #include "mxcore.h"
 #include "mxpresenterlist.h"
 
+class MxControlPresenter;
+
 // VTABLE: LEGO1 0x100d6a98
 // SIZE 0x2c
 class LegoControlManagerEvent : public LegoEventNotificationParam {
@@ -62,7 +64,7 @@ public:
 	void Unregister(MxCore* p_listener);
 	MxBool FUN_10029210(LegoEventNotificationParam& p_param, MxPresenter* p_presenter);
 	void FUN_100293c0(undefined4, const char*, undefined2);
-	void FUN_100294e0(MxS32 p_x, MxS32 p_y);
+	MxControlPresenter* FUN_100294e0(MxS32 p_x, MxS32 p_y);
 	MxBool FUN_10029630();
 	MxBool FUN_10029750();
 	void FUN_100292e0();
diff --git a/LEGO1/lego/legoomni/include/legogamestate.h b/LEGO1/lego/legoomni/include/legogamestate.h
index a799c570..0b45f11c 100644
--- a/LEGO1/lego/legoomni/include/legogamestate.h
+++ b/LEGO1/lego/legoomni/include/legogamestate.h
@@ -40,9 +40,12 @@ public:
 	inline MxS32 GetCurrentAct() { return m_currentAct; }
 	inline MxU32 GetCurrentArea() { return m_currentArea; }
 	inline MxU32 GetPreviousArea() { return m_previousArea; }
+	inline MxU32 GetUnknown0x42c() { return m_unk0x42c; }
 
 	inline void SetDirty(MxBool p_dirty) { m_isDirty = p_dirty; }
 	inline void SetCurrentArea(MxU32 p_currentArea) { m_currentArea = p_currentArea; }
+	inline void SetPreviousArea(MxU32 p_previousArea) { m_previousArea = p_previousArea; }
+	inline void SetUnknown0x0c(MxU8 p_unk0x0c) { m_unk0x0c = p_unk0x0c; }
 
 	void SetSomeEnumState(undefined4 p_state);
 	void FUN_1003ceb0();
diff --git a/LEGO1/lego/legoomni/include/mxcontrolpresenter.h b/LEGO1/lego/legoomni/include/mxcontrolpresenter.h
index b1c01fab..e12c1a25 100644
--- a/LEGO1/lego/legoomni/include/mxcontrolpresenter.h
+++ b/LEGO1/lego/legoomni/include/mxcontrolpresenter.h
@@ -40,10 +40,9 @@ public:
 	virtual void VTable0x6c(MxS16);                                  // vtable+0x6c
 
 	MxBool FUN_10044480(LegoControlManagerEvent* p_event, MxPresenter* p_presenter);
-
-private:
 	MxBool FUN_10044270(MxS32 p_x, MxS32 p_y, MxVideoPresenter* p_presenter);
 
+private:
 	undefined2 m_unk0x4c; // 0x4c
 	MxS16 m_unk0x4e;      // 0x4e
 	MxBool m_unk0x50;     // 0x50
diff --git a/LEGO1/lego/legoomni/src/common/legogamestate.cpp b/LEGO1/lego/legoomni/src/common/legogamestate.cpp
index 0637a22c..864bb258 100644
--- a/LEGO1/lego/legoomni/src/common/legogamestate.cpp
+++ b/LEGO1/lego/legoomni/src/common/legogamestate.cpp
@@ -6,6 +6,7 @@
 #include "legostate.h"
 #include "legoutil.h"
 #include "legovideomanager.h"
+#include "legoworld.h"
 #include "mxbackgroundaudiomanager.h"
 #include "mxobjectfactory.h"
 #include "mxstring.h"
@@ -446,6 +447,8 @@ void LegoGameState::SwitchArea(MxU32 p_area)
 	VideoManager()->SetUnk0x554(FALSE);
 
 	MxAtomId* script = g_isleScript;
+	LegoWorld* world;
+
 	switch (p_area) {
 	case 1:
 		break;
@@ -461,6 +464,24 @@ void LegoGameState::SwitchArea(MxU32 p_area)
 	case 5:
 		script = g_elevbottScript;
 		break;
+	case 6:
+	case 7:
+		world = FindWorld(*g_isleScript, 0);
+
+		if (world == NULL) {
+			InvokeAction(Extra::ActionType::e_opendisk, *g_isleScript, 0, NULL);
+		}
+		else {
+#ifdef COMPAT_MODE
+			{
+				MxNotificationParam param(c_notificationType20, NULL);
+				NotificationManager()->Send(world, &param);
+			}
+#else
+			NotificationManager()->Send(world, &MxNotificationParam(c_notificationType20, NULL));
+#endif
+		}
+		break;
 	case 12:
 		VideoManager()->SetUnk0x554(TRUE);
 		script = g_regbookScript;
diff --git a/LEGO1/lego/legoomni/src/control/legocontrolmanager.cpp b/LEGO1/lego/legoomni/src/control/legocontrolmanager.cpp
index 8bcf9999..01d5bb3a 100644
--- a/LEGO1/lego/legoomni/src/control/legocontrolmanager.cpp
+++ b/LEGO1/lego/legoomni/src/control/legocontrolmanager.cpp
@@ -1,6 +1,8 @@
 #include "legocontrolmanager.h"
 
 #include "legoeventnotificationparam.h"
+#include "legoomni.h"
+#include "legovideomanager.h"
 #include "mxcontrolpresenter.h"
 #include "mxpresenter.h"
 #include "mxticklemanager.h"
@@ -121,9 +123,24 @@ void LegoControlManager::FUN_100293c0(undefined4, const char*, undefined2)
 {
 }
 
-// STUB: LEGO1 0x100294e0
-void LegoControlManager::FUN_100294e0(MxS32 p_x, MxS32 p_y)
+// FUNCTION: LEGO1 0x100294e0
+MxControlPresenter* LegoControlManager::FUN_100294e0(MxS32 p_x, MxS32 p_y)
 {
+	if (m_presenterList) {
+		MxPresenterListCursor cursor(m_presenterList);
+		MxPresenter* control;
+		MxVideoPresenter* presenter = (MxVideoPresenter*) VideoManager()->GetPresenterAt(p_x, p_y);
+
+		if (presenter) {
+			while (cursor.Next(control)) {
+				if (((MxControlPresenter*) control)->FUN_10044270(p_x, p_y, presenter)) {
+					return (MxControlPresenter*) control;
+				}
+			}
+		}
+	}
+
+	return NULL;
 }
 
 // FUNCTION: LEGO1 0x10029600
diff --git a/LEGO1/lego/legoomni/src/infocenter/infocenter.cpp b/LEGO1/lego/legoomni/src/infocenter/infocenter.cpp
index ba357dc3..71bfef9b 100644
--- a/LEGO1/lego/legoomni/src/infocenter/infocenter.cpp
+++ b/LEGO1/lego/legoomni/src/infocenter/infocenter.cpp
@@ -10,6 +10,7 @@
 #include "legovideomanager.h"
 #include "mxactionnotificationparam.h"
 #include "mxbackgroundaudiomanager.h"
+#include "mxcontrolpresenter.h"
 #include "mxnotificationmanager.h"
 #include "mxstillpresenter.h"
 #include "mxticklemanager.h"
@@ -73,28 +74,54 @@ Infocenter::~Infocenter()
 	TickleManager()->UnregisterClient(this);
 }
 
-// STUB: LEGO1 0x1006ed90
+// FUNCTION: LEGO1 0x1006ed90
 MxResult Infocenter::Create(MxDSAction& p_dsAction)
 {
-	if (LegoWorld::Create(p_dsAction) == SUCCESS) {
+	MxResult result = LegoWorld::Create(p_dsAction);
+	if (result == SUCCESS) {
 		InputManager()->SetWorld(this);
 		ControlManager()->Register(this);
 	}
 
-	LegoGameState* gs = GameState();
-	m_infocenterState = (InfocenterState*) gs->GetState("InfocenterState");
+	m_infocenterState = (InfocenterState*) GameState()->GetState("InfocenterState");
 	if (!m_infocenterState) {
-		m_infocenterState = (InfocenterState*) gs->CreateState("InfocenterState");
+		m_infocenterState = (InfocenterState*) GameState()->CreateState("InfocenterState");
 		m_infocenterState->SetUnknown0x74(3);
 	}
 	else {
-		// TODO
+		if (m_infocenterState->GetUnknown0x74() != 8 && m_infocenterState->GetUnknown0x74() != 4 &&
+			m_infocenterState->GetUnknown0x74() != 15) {
+			m_infocenterState->SetUnknown0x74(2);
+		}
+
+		MxS16 count, i;
+		for (count = 0; count < m_infocenterState->GetInfocenterBufferSize(); count++) {
+			if (m_infocenterState->GetInfocenterBufferElement(count) == NULL) {
+				break;
+			}
+		}
+
+		for (i = 0; i < count; i++) {
+			if (m_infocenterState->GetInfocenterBufferElement(i)) {
+				m_infocenterState->GetInfocenterBufferElement(i)->Enable(TRUE);
+				m_infocenterState->GetInfocenterBufferElement(i)->SetTickleState(MxPresenter::e_repeating);
+				m_infocenterState->GetInfocenterBufferElement(i)->VTable0x88(((7 - count) / 2 + i) * 29 + 223, 45);
+			}
+		}
+	}
+
+	GameState()->SetCurrentArea(2);
+	GameState()->StopArea(0);
+
+	if (m_infocenterState->GetUnknown0x74() == 4) {
+		LegoGameState* state = GameState();
+		state->SetPreviousArea(GameState()->GetUnknown0x42c());
 	}
 
-	// TODO
 	InputManager()->Register(this);
 	SetIsWorldActive(FALSE);
-	return SUCCESS;
+
+	return result;
 }
 
 // FUNCTION: LEGO1 0x1006ef10
@@ -159,8 +186,9 @@ MxLong Infocenter::HandleEndAction(MxEndActionNotificationParam& p_param)
 	}
 
 	if (action->GetAtomId() == m_atom &&
-		(action->GetObjectId() == c_unk40 || action->GetObjectId() == c_unk41 || action->GetObjectId() == c_unk42 ||
-		 action->GetObjectId() == c_unk43 || action->GetObjectId() == c_unk44)) {
+		(action->GetObjectId() == c_mamaMovie || action->GetObjectId() == c_papaMovie ||
+		 action->GetObjectId() == c_pepperMovie || action->GetObjectId() == c_nickMovie ||
+		 action->GetObjectId() == c_lauraMovie)) {
 		if (m_unk0x1d4) {
 			m_unk0x1d4--;
 		}
@@ -509,9 +537,194 @@ MxLong Infocenter::HandleKeyPress(MxS8 p_key)
 	return result;
 }
 
-// STUB: LEGO1 0x1006feb0
+// FUNCTION: LEGO1 0x1006feb0
 MxU8 Infocenter::HandleButtonUp(MxS32 p_x, MxS32 p_y)
 {
+	if (m_unk0x11c) {
+		MxControlPresenter* control = InputManager()->GetControlManager()->FUN_100294e0(p_x - 1, p_y - 1);
+
+		switch (m_unk0x11c->GetAction()->GetObjectId()) {
+		case c_mamaSelected:
+			m_unk0xfc = 2;
+			break;
+		case c_papaSelected:
+			m_unk0xfc = 3;
+			break;
+		case c_pepperSelected:
+			m_unk0xfc = 1;
+			break;
+		case c_nickSelected:
+			m_unk0xfc = 4;
+			break;
+		case c_lauraSelected:
+			m_unk0xfc = 5;
+			break;
+		}
+
+		if (control != NULL) {
+			m_infoManDialogueTimer = 0;
+
+			switch (control->GetAction()->GetObjectId()) {
+			case c_mamaCtl:
+				if (m_unk0xfc == 2) {
+					m_radio.Stop();
+					BackgroundAudioManager()->Stop();
+					PlayAction(c_mamaMovie);
+					m_unk0x1d4++;
+				}
+				break;
+			case c_papaCtl:
+				if (m_unk0xfc == 3) {
+					m_radio.Stop();
+					BackgroundAudioManager()->Stop();
+					PlayAction(c_papaMovie);
+					m_unk0x1d4++;
+				}
+				break;
+			case c_pepperCtl:
+				if (m_unk0xfc == 1) {
+					m_radio.Stop();
+					BackgroundAudioManager()->Stop();
+					PlayAction(c_pepperMovie);
+					m_unk0x1d4++;
+				}
+				break;
+			case c_nickCtl:
+				if (m_unk0xfc == 4) {
+					m_radio.Stop();
+					BackgroundAudioManager()->Stop();
+					PlayAction(c_nickMovie);
+					m_unk0x1d4++;
+				}
+				break;
+			case c_lauraCtl:
+				if (m_unk0xfc == 5) {
+					m_radio.Stop();
+					BackgroundAudioManager()->Stop();
+					PlayAction(c_lauraMovie);
+					m_unk0x1d4++;
+				}
+				break;
+			}
+		}
+		else {
+			if (m_unk0x1c8 != -1) {
+				m_infoManDialogueTimer = 0;
+
+				switch (m_mapAreas[m_unk0x1c8].m_unk0x04) {
+				case 3:
+					GameState()->FUN_10039780(m_unk0xfc);
+
+					switch (m_unk0xfc) {
+					case 1:
+						PlayAction(c_pepperCharacterSelect);
+						break;
+					case 2:
+						PlayAction(c_mamaCharacterSelect);
+						break;
+					case 3:
+						PlayAction(c_papaCharacterSelect);
+						break;
+					case 4:
+						PlayAction(c_nickCharacterSelect);
+						break;
+					case 5:
+						PlayAction(c_lauraCharacterSelect);
+						break;
+					}
+					break;
+				case 10:
+					if (m_unk0xfc) {
+						m_transitionDestination = 16;
+						m_infocenterState->SetUnknown0x74(5);
+					}
+					break;
+				case 11:
+					if (m_unk0xfc) {
+						m_transitionDestination = 19;
+						m_infocenterState->SetUnknown0x74(5);
+					}
+					break;
+				case 12:
+					if (m_unk0xfc) {
+						m_transitionDestination = 22;
+						m_infocenterState->SetUnknown0x74(5);
+					}
+					break;
+				case 13:
+					if (m_unk0xfc) {
+						m_transitionDestination = 25;
+						m_infocenterState->SetUnknown0x74(5);
+					}
+					break;
+				case 14:
+					if (m_unk0xfc) {
+						m_transitionDestination = 29;
+						m_infocenterState->SetUnknown0x74(5);
+					}
+					break;
+				case 15:
+					if (m_unk0xfc) {
+						m_transitionDestination = 32;
+						m_infocenterState->SetUnknown0x74(5);
+					}
+					break;
+				}
+			}
+		}
+
+		m_unk0x11c->Enable(FALSE);
+		m_unk0x11c = NULL;
+
+		if (m_infocenterState->GetUnknown0x74() == 5) {
+			InfomainScript dialogueToPlay;
+
+			if (GameState()->GetUnknown10() == 0) {
+				if (m_infocenterState->GetInfocenterBufferElement(0) == NULL) {
+					m_infocenterState->SetUnknown0x74(2);
+					m_transitionDestination = 0;
+					dialogueToPlay = c_registerToContinueDialogue;
+				}
+				else {
+					switch (m_unk0xfc) {
+					case 1:
+						dialogueToPlay = c_pepperCharacterSelect;
+						break;
+					case 2:
+						dialogueToPlay = c_mamaCharacterSelect;
+						break;
+					case 3:
+						dialogueToPlay = c_papaCharacterSelect;
+						break;
+					case 4:
+						dialogueToPlay = c_nickCharacterSelect;
+						break;
+					case 5:
+						dialogueToPlay = c_lauraCharacterSelect;
+						GameState()->SetUnknown0x0c(m_unk0xfc);
+						break;
+					default:
+						dialogueToPlay =
+							(InfomainScript) m_infocenterState->GetUnknown0x44()[GameState()->GetUnknown10()].Next();
+						break;
+					}
+
+					InputManager()->DisableInputProcessing();
+					InputManager()->SetUnknown336(TRUE);
+				}
+			}
+			else {
+				dialogueToPlay =
+					(InfomainScript) m_infocenterState->GetUnknown0x44()[GameState()->GetUnknown10()].Next();
+			}
+
+			PlayAction(dialogueToPlay);
+		}
+
+		UpdateFrameHot(TRUE);
+		FUN_10070d10(0, 0);
+	}
+
 	return FALSE;
 }
 
@@ -694,9 +907,9 @@ MxLong Infocenter::HandleNotification0(MxNotificationParam& p_param)
 	}
 	else {
 		if (sender->IsA("Radio") && m_radio.GetState()->IsActive()) {
-			if (m_currentInfomainScript == c_unk40 || m_currentInfomainScript == c_unk41 ||
-				m_currentInfomainScript == c_unk42 || m_currentInfomainScript == c_unk43 ||
-				m_currentInfomainScript == c_unk44 || m_currentInfomainScript == c_unk557 ||
+			if (m_currentInfomainScript == c_mamaMovie || m_currentInfomainScript == c_papaMovie ||
+				m_currentInfomainScript == c_pepperMovie || m_currentInfomainScript == c_nickMovie ||
+				m_currentInfomainScript == c_lauraMovie || m_currentInfomainScript == c_unk557 ||
 				m_currentInfomainScript == c_boatCtlDescription || m_currentInfomainScript == c_raceCtlDescription ||
 				m_currentInfomainScript == c_pizzaCtlDescription || m_currentInfomainScript == c_gasCtlDescription ||
 				m_currentInfomainScript == c_medCtlDescription || m_currentInfomainScript == c_copCtlDescription) {
@@ -823,7 +1036,7 @@ void Infocenter::FUN_10070d10(MxS32 p_x, MxS32 p_y)
 
 	if (i != m_unk0x1c8) {
 		if (m_unk0x1c8 != -1) {
-			m_mapAreas[i].m_presenter->Enable(FALSE);
+			m_mapAreas[m_unk0x1c8].m_presenter->Enable(FALSE);
 		}
 
 		m_unk0x1c8 = i;
diff --git a/LEGO1/lego/legoomni/src/infocenter/infocenterdoor.cpp b/LEGO1/lego/legoomni/src/infocenter/infocenterdoor.cpp
index eaf1ba98..325b5eb0 100644
--- a/LEGO1/lego/legoomni/src/infocenter/infocenterdoor.cpp
+++ b/LEGO1/lego/legoomni/src/infocenter/infocenterdoor.cpp
@@ -120,6 +120,7 @@ MxLong InfocenterDoor::HandleClick(LegoControlManagerEvent& p_param)
 					action.SetAtomId(*g_infodoorScript);
 					BackgroundAudioManager()->LowerVolume();
 					Start(&action);
+					goto done;
 				}
 			}
 			else {
@@ -128,9 +129,12 @@ MxLong InfocenterDoor::HandleClick(LegoControlManagerEvent& p_param)
 				action.SetAtomId(*g_infodoorScript);
 				BackgroundAudioManager()->LowerVolume();
 				Start(&action);
+				goto done;
 			}
 
 			TransitionManager()->StartTransition(MxTransitionManager::e_pixelation, 50, FALSE, FALSE);
+
+		done:
 			result = 1;
 			break;
 		}
diff --git a/LEGO1/omni/src/common/mxmediapresenter.cpp b/LEGO1/omni/src/common/mxmediapresenter.cpp
index 17caece5..48450b58 100644
--- a/LEGO1/omni/src/common/mxmediapresenter.cpp
+++ b/LEGO1/omni/src/common/mxmediapresenter.cpp
@@ -229,8 +229,7 @@ void MxMediaPresenter::RepeatingTickle()
 // FUNCTION: LEGO1 0x100b5ef0
 void MxMediaPresenter::DoneTickle()
 {
-	m_previousTickleStates |= 1 << m_currentTickleState;
-	m_currentTickleState = e_idle;
+	ProgressTickleState(e_idle);
 	EndAction();
 }