diff --git a/LEGO1/mxsmkpresenter.cpp b/LEGO1/mxsmkpresenter.cpp
index 66d63f7a..59687742 100644
--- a/LEGO1/mxsmkpresenter.cpp
+++ b/LEGO1/mxsmkpresenter.cpp
@@ -42,24 +42,25 @@ void MxSmkPresenter::Destroy(MxBool p_fromDestructor)
 }
 
 // OFFSET: LEGO1 0x100b3940 STUB
-void MxSmkPresenter::VTable0x5c(undefined4 p_unknown1)
+void MxSmkPresenter::LoadHeader(MxStreamChunk* p_chunk)
 {
+	// TODO
 }
 
 // OFFSET: LEGO1 0x100b3960
-void MxSmkPresenter::VTable0x60()
+void MxSmkPresenter::CreateBitmap()
 {
-	if (m_bitmap) {
+	if (m_bitmap)
 		delete m_bitmap;
-	}
 
-	m_bitmap = new MxBitmap();
+	m_bitmap = new MxBitmap;
 	m_bitmap->SetSize(m_mxSmack.m_smack.m_width, m_mxSmack.m_smack.m_height, NULL, FALSE);
 }
 
 // OFFSET: LEGO1 0x100b3a00 STUB
-void MxSmkPresenter::VTable0x68(undefined4 p_unknown1)
+void MxSmkPresenter::LoadFrame(MxStreamChunk* p_chunk)
 {
+	// TODO
 }
 
 // OFFSET: LEGO1 0x100b4260
diff --git a/LEGO1/mxsmkpresenter.h b/LEGO1/mxsmkpresenter.h
index 549c65b7..4a449e1e 100644
--- a/LEGO1/mxsmkpresenter.h
+++ b/LEGO1/mxsmkpresenter.h
@@ -26,12 +26,12 @@ public:
 		return !strcmp(name, MxSmkPresenter::ClassName()) || MxVideoPresenter::IsA(name);
 	}
 
-	virtual void Destroy() override;
-	virtual void VTable0x5c(undefined4 p_unknown1) override;
-	virtual void VTable0x60() override;
-	virtual void VTable0x68(undefined4 p_unknown1) override; // vtable+0x68
-	virtual void VTable0x70() override;
-	virtual MxU32 VTable0x88();
+	virtual void Destroy() override;                          // vtable+0x38
+	virtual void LoadHeader(MxStreamChunk* p_chunk) override; // vtable+0x5c
+	virtual void CreateBitmap() override;                     // vtable+0x60
+	virtual void LoadFrame(MxStreamChunk* p_chunk) override;  // vtable+0x68
+	virtual void VTable0x70() override;                       // vtable+0x70
+	virtual MxU32 VTable0x88();                               // vtable+0x88
 
 	struct MxSmack {
 		Smack m_smack;
diff --git a/LEGO1/mxstillpresenter.cpp b/LEGO1/mxstillpresenter.cpp
index 8f7124f0..d166d7b7 100644
--- a/LEGO1/mxstillpresenter.cpp
+++ b/LEGO1/mxstillpresenter.cpp
@@ -9,13 +9,120 @@ DECOMP_SIZE_ASSERT(MxStillPresenter, 0x6c);
 // 0x10101eb0
 const char* g_strBMP_ISMAP = "BMP_ISMAP";
 
+// OFFSET: LEGO1 0x10043550 TEMPLATE
+// MxStillPresenter::~MxStillPresenter
+
+// OFFSET: LEGO1 0x100435b0
+void MxStillPresenter::Destroy()
+{
+	Destroy(FALSE);
+}
+
+// OFFSET: LEGO1 0x100435c0 TEMPLATE
+// MxStillPresenter::ClassName
+
+// OFFSET: LEGO1 0x100435d0 TEMPLATE
+// MxStillPresenter::IsA
+
+// OFFSET: LEGO1 0x100436e0 TEMPLATE
+// MxStillPresenter::`scalar deleting destructor'
+
+// OFFSET: LEGO1 0x100b9c70
+void MxStillPresenter::Destroy(MxBool p_fromDestructor)
+{
+	m_criticalSection.Enter();
+
+	if (m_bitmapInfo)
+		delete m_bitmapInfo;
+	m_bitmapInfo = NULL;
+
+	m_criticalSection.Leave();
+
+	if (!p_fromDestructor)
+		MxVideoPresenter::Destroy(FALSE);
+}
+
+// OFFSET: LEGO1 0x100b9cc0
+void MxStillPresenter::LoadHeader(MxStreamChunk* p_chunk)
+{
+	if (m_bitmapInfo)
+		delete m_bitmapInfo;
+
+	MxU8* data = new MxU8[p_chunk->GetLength()];
+	m_bitmapInfo = (MxBITMAPINFO*) data;
+	memcpy(m_bitmapInfo, p_chunk->GetData(), p_chunk->GetLength());
+}
+
+// OFFSET: LEGO1 0x100b9d10
+void MxStillPresenter::CreateBitmap()
+{
+	if (m_bitmap)
+		delete m_bitmap;
+
+	m_bitmap = new MxBitmap;
+	m_bitmap->ImportBitmapInfo(m_bitmapInfo);
+
+	delete m_bitmapInfo;
+	m_bitmapInfo = NULL;
+}
+
+// OFFSET: LEGO1 0x100b9db0
+void MxStillPresenter::NextFrame()
+{
+	MxStreamChunk* chunk = NextChunk();
+	LoadFrame(chunk);
+	m_subscriber->FUN_100b8390(chunk);
+}
+
+// OFFSET: LEGO1 0x100b9dd0 STUB
+void MxStillPresenter::LoadFrame(MxStreamChunk* p_chunk)
+{
+	// TODO
+}
+
+// OFFSET: LEGO1 0x100b9f30 STUB
+void MxStillPresenter::VTable0x70()
+{
+	// TODO
+}
+
+// OFFSET: LEGO1 0x100b9f60 STUB
+void MxStillPresenter::StartingTickle()
+{
+	// TODO
+}
+
+// OFFSET: LEGO1 0x100b9f90 STUB
+void MxStillPresenter::StreamingTickle()
+{
+	// TODO
+}
+
+// OFFSET: LEGO1 0x100b9ff0 STUB
+void MxStillPresenter::RepeatingTickle()
+{
+	// TODO
+}
+
+// OFFSET: LEGO1 0x100ba040 STUB
+void MxStillPresenter::VTable0x88(undefined4, undefined4)
+{
+	// TODO
+}
+
+// OFFSET: LEGO1 0x100ba140 STUB
+void MxStillPresenter::Enable(MxBool p_enable)
+{
+	// TODO
+}
+
 // OFFSET: LEGO1 0x100ba1e0
 void MxStillPresenter::ParseExtra()
 {
 	MxPresenter::ParseExtra();
 
 	if (m_action->GetFlags() & MxDSAction::Flag_Bit5)
-		m_flags |= 0x8;
+		m_flags |= Flag_Bit4;
 
 	MxU32 len = m_action->GetExtraLength();
 
@@ -36,8 +143,15 @@ void MxStillPresenter::ParseExtra()
 	}
 
 	if (KeyValueStringParse(output, g_strBMP_ISMAP, buf)) {
-		m_flags |= 0x10;
-		m_flags &= ~0x2;
-		m_flags &= ~0x4;
+		m_flags |= Flag_Bit5;
+		m_flags &= ~Flag_Bit2;
+		m_flags &= ~Flag_Bit3;
 	}
 }
+
+// OFFSET: LEGO1 0x100ba2c0 STUB
+MxStillPresenter* MxStillPresenter::Clone()
+{
+	// TODO
+	return NULL;
+}
diff --git a/LEGO1/mxstillpresenter.h b/LEGO1/mxstillpresenter.h
index d2e89f59..4d665ca2 100644
--- a/LEGO1/mxstillpresenter.h
+++ b/LEGO1/mxstillpresenter.h
@@ -8,24 +8,39 @@
 // SIZE 0x6c
 class MxStillPresenter : public MxVideoPresenter {
 public:
-	// OFFSET: LEGO1 0x100435c0
+	MxStillPresenter() { m_bitmapInfo = NULL; }
+	virtual ~MxStillPresenter() override { Destroy(TRUE); }; // vtable+0x00
+
 	inline virtual const char* ClassName() const override // vtable+0xc
 	{
 		// 0x100f0184
 		return "MxStillPresenter";
 	}
 
-	// OFFSET: LEGO1 0x100435d0
 	inline virtual MxBool IsA(const char* name) const override // vtable+0x10
 	{
 		return !strcmp(name, MxStillPresenter::ClassName()) || MxVideoPresenter::IsA(name);
 	}
 
-	virtual void ParseExtra() override; // vtable+0x30
+	virtual void StartingTickle() override;                   // vtable+0x1c
+	virtual void StreamingTickle() override;                  // vtable+0x20
+	virtual void RepeatingTickle() override;                  // vtable+0x24
+	virtual void ParseExtra() override;                       // vtable+0x30
+	virtual void Destroy() override;                          // vtable+0x38
+	virtual void Enable(MxBool p_enable) override;            // vtable+0x54
+	virtual void LoadHeader(MxStreamChunk* p_chunk) override; // vtable+0x5c
+	virtual void CreateBitmap() override;                     // vtable+0x60
+	virtual void NextFrame() override;                        // vtable+0x64
+	virtual void LoadFrame(MxStreamChunk* p_chunk) override;  // vtable+0x68
+	virtual void VTable0x70() override;                       // vtable+0x70
+	virtual void VTable0x88(undefined4, undefined4);          // vtable+0x88
+	virtual MxStillPresenter* Clone();                        // vtable+0x8c
 
-	MxStillPresenter() { m_unk68 = 0; }
-	undefined4 m_unk64;
-	undefined4 m_unk68;
+private:
+	void Destroy(MxBool p_fromDestructor);
+
+	undefined4 m_unk64;         // 0x64
+	MxBITMAPINFO* m_bitmapInfo; // 0x68
 };
 
 #endif // MXSTILLPRESENTER_H
diff --git a/LEGO1/mxtransitionmanager.cpp b/LEGO1/mxtransitionmanager.cpp
index e96843a2..3cf5b687 100644
--- a/LEGO1/mxtransitionmanager.cpp
+++ b/LEGO1/mxtransitionmanager.cpp
@@ -574,7 +574,7 @@ void MxTransitionManager::SetupCopyRect(LPDDSURFACEDESC ddsc)
 		MxBool unkbool = FALSE;
 		displaySurface->vtable2c(
 			ddsc,
-			m_waitIndicator->m_bitmap,
+			m_waitIndicator->GetBitmap(),
 			0,
 			0,
 			m_waitIndicator->GetLocationX(),
@@ -588,7 +588,7 @@ void MxTransitionManager::SetupCopyRect(LPDDSURFACEDESC ddsc)
 		MxDisplaySurface* displaySurface = VideoManager()->GetDisplaySurface();
 		displaySurface->vtable24(
 			ddsc,
-			m_waitIndicator->m_bitmap,
+			m_waitIndicator->GetBitmap(),
 			0,
 			0,
 			m_waitIndicator->GetLocationX(),
diff --git a/LEGO1/mxvideopresenter.cpp b/LEGO1/mxvideopresenter.cpp
index 25a2d850..7df63490 100644
--- a/LEGO1/mxvideopresenter.cpp
+++ b/LEGO1/mxvideopresenter.cpp
@@ -8,19 +8,19 @@ DECOMP_SIZE_ASSERT(MxVideoPresenter, 0x64);
 DECOMP_SIZE_ASSERT(MxVideoPresenter::AlphaMask, 0xc);
 
 // OFFSET: LEGO1 0x1000c700
-void MxVideoPresenter::VTable0x5c(MxStreamChunk* p_chunk)
+void MxVideoPresenter::LoadHeader(MxStreamChunk* p_chunk)
 {
 	// Empty
 }
 
 // OFFSET: LEGO1 0x1000c710
-void MxVideoPresenter::VTable0x60()
+void MxVideoPresenter::CreateBitmap()
 {
 	// Empty
 }
 
 // OFFSET: LEGO1 0x1000c720
-void MxVideoPresenter::VTable0x68(MxStreamChunk* p_chunk)
+void MxVideoPresenter::LoadFrame(MxStreamChunk* p_chunk)
 {
 	// Empty
 }
@@ -235,7 +235,7 @@ void MxVideoPresenter::Destroy(MxBool p_fromDestructor)
 }
 
 // OFFSET: LEGO1 0x100b28b0
-void MxVideoPresenter::VTable0x64()
+void MxVideoPresenter::NextFrame()
 {
 	MxStreamChunk* chunk = NextChunk();
 
@@ -245,7 +245,7 @@ void MxVideoPresenter::VTable0x64()
 		m_currentTickleState = TickleState_Repeating;
 	}
 	else {
-		VTable0x68(chunk);
+		LoadFrame(chunk);
 		m_subscriber->FUN_100b8390(chunk);
 	}
 }
@@ -324,7 +324,7 @@ void MxVideoPresenter::ReadyTickle()
 	MxStreamChunk* chunk = NextChunk();
 
 	if (chunk) {
-		VTable0x5c(chunk);
+		LoadHeader(chunk);
 		m_subscriber->FUN_100b8390(chunk);
 		ParseExtra();
 		m_previousTickleStates |= 1 << (unsigned char) m_currentTickleState;
@@ -338,7 +338,7 @@ void MxVideoPresenter::StartingTickle()
 	MxStreamChunk* chunk = FUN_100b5650();
 
 	if (chunk && m_action->GetElapsedTime() >= chunk->GetTime()) {
-		VTable0x60();
+		CreateBitmap();
 		m_previousTickleStates |= 1 << (unsigned char) m_currentTickleState;
 		m_currentTickleState = TickleState_Streaming;
 	}
@@ -352,7 +352,7 @@ void MxVideoPresenter::StreamingTickle()
 			MxMediaPresenter::StreamingTickle();
 
 		if (m_currentChunk) {
-			VTable0x68(m_currentChunk);
+			LoadFrame(m_currentChunk);
 			m_currentChunk = NULL;
 		}
 	}
@@ -368,7 +368,7 @@ void MxVideoPresenter::StreamingTickle()
 			if (m_action->GetElapsedTime() < m_currentChunk->GetTime())
 				break;
 
-			VTable0x68(m_currentChunk);
+			LoadFrame(m_currentChunk);
 			m_subscriber->FUN_100b8390(m_currentChunk);
 			m_currentChunk = NULL;
 			m_flags |= Flag_Bit1;
@@ -391,7 +391,7 @@ void MxVideoPresenter::RepeatingTickle()
 				MxMediaPresenter::RepeatingTickle();
 
 			if (m_currentChunk) {
-				VTable0x68(m_currentChunk);
+				LoadFrame(m_currentChunk);
 				m_currentChunk = NULL;
 			}
 		}
@@ -407,7 +407,7 @@ void MxVideoPresenter::RepeatingTickle()
 				if (m_action->GetElapsedTime() % m_action->GetLoopCount() < m_currentChunk->GetTime())
 					break;
 
-				VTable0x68(m_currentChunk);
+				LoadFrame(m_currentChunk);
 				m_currentChunk = NULL;
 				m_flags |= Flag_Bit1;
 
diff --git a/LEGO1/mxvideopresenter.h b/LEGO1/mxvideopresenter.h
index 34406255..d7ffb81e 100644
--- a/LEGO1/mxvideopresenter.h
+++ b/LEGO1/mxvideopresenter.h
@@ -11,6 +11,10 @@ class MxVideoPresenter : public MxMediaPresenter {
 public:
 	enum {
 		Flag_Bit1 = 0x01,
+		Flag_Bit2 = 0x02,
+		Flag_Bit3 = 0x04,
+		Flag_Bit4 = 0x08,
+		Flag_Bit5 = 0x10,
 	};
 
 	MxVideoPresenter() { Init(); }
@@ -29,9 +33,6 @@ public:
 		return !strcmp(name, MxVideoPresenter::ClassName()) || MxMediaPresenter::IsA(name);
 	}
 
-	void Init();
-	void Destroy(MxBool p_fromDestructor);
-
 	virtual void ReadyTickle() override;                 // vtable+0x18
 	virtual void StartingTickle() override;              // vtable+0x1c
 	virtual void StreamingTickle() override;             // vtable+0x20
@@ -42,10 +43,10 @@ public:
 	virtual void EndAction() override;                   // vtable+0x40
 	virtual undefined4 PutData() override;               // vtable+0x4c
 	virtual MxBool IsHit(MxS32 p_x, MxS32 p_y) override; // vtable+0x50
-	virtual void VTable0x5c(MxStreamChunk* p_chunk);     // vtable+0x5c
-	virtual void VTable0x60();                           // vtable+0x60
-	virtual void VTable0x64();                           // vtable+0x64
-	virtual void VTable0x68(MxStreamChunk* p_chunk);     // vtable+0x68
+	virtual void LoadHeader(MxStreamChunk* p_chunk);     // vtable+0x5c
+	virtual void CreateBitmap();                         // vtable+0x60
+	virtual void NextFrame();                            // vtable+0x64
+	virtual void LoadFrame(MxStreamChunk* p_chunk);      // vtable+0x68
 	virtual void VTable0x6c();                           // vtable+0x6c
 	virtual void VTable0x70();                           // vtable+0x70
 	virtual undefined VTable0x74();                      // vtable+0x74
@@ -67,6 +68,14 @@ public:
 		MxS32 IsHit(MxU32 p_x, MxU32 p_y);
 	};
 
+	inline MxBitmap* GetBitmap() { return m_bitmap; }
+
+private:
+	void Init();
+
+protected:
+	void Destroy(MxBool p_fromDestructor);
+
 	MxBitmap* m_bitmap;          // 0x50
 	AlphaMask* m_alpha;          // 0x54
 	LPDIRECTDRAWSURFACE m_unk58; // 0x58