changeset 75:57c0ce406a68 tip

Add main menu
author koryspansel <koryspansel@bendbroadband.com>
date Tue, 18 Oct 2011 17:08:17 -0700
parents 40c0b5305de8
children
files Assets/UI/Background05.PSD Data/Textures/MainMenu/Background.png LightClone/LightClone.vcproj LightClone/Source/Application.cpp LightClone/Source/Application.h LightClone/Source/Core.h LightClone/Source/Mediator.cpp LightClone/Source/Mediator.h LightClone/ToDo.txt
diffstat 9 files changed, 789 insertions(+), 512 deletions(-) [+]
line wrap: on
line diff
Binary file Assets/UI/Background05.PSD has changed
Binary file Data/Textures/MainMenu/Background.png has changed
--- a/LightClone/LightClone.vcproj	Tue Oct 18 11:56:49 2011 -0700
+++ b/LightClone/LightClone.vcproj	Tue Oct 18 17:08:17 2011 -0700
@@ -191,6 +191,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\Source\Application.cpp"
+				>
+			</File>
+			<File
 				RelativePath=".\Source\Bot.cpp"
 				>
 			</File>
@@ -341,6 +345,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\Source\Application.h"
+				>
+			</File>
+			<File
 				RelativePath=".\Source\Bot.h"
 				>
 			</File>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LightClone/Source/Application.cpp	Tue Oct 18 17:08:17 2011 -0700
@@ -0,0 +1,135 @@
+/*
+ * Application
+ */
+
+#include "Application.h"
+
+#pragma warning(disable:4355)
+
+/*
+ * Application
+ */
+Application::Application(float fRate) : kWindow(this), fPeriod(1.0f / fRate), fAccumulator(0.0f), bRunning(true)
+{
+}
+
+/*
+ * Run
+ */
+ErrorCode Application::Run()
+{
+	ErrorCode eCode = Initialize();
+	if(eCode == Error_Success)
+	{
+		kClock.Reset();
+
+		// force an update to occur before rendering
+		fAccumulator = fPeriod;
+		//while(nApplicationState != ApplicationState_Exit)
+		for(fAccumulator = fPeriod; bRunning; )
+		{
+			ProcessMessages();
+
+			const float fElapsed	= kClock.GetElapsed();
+			const float fDelta		= fElapsed;//Min(fElapsed, fPeriod);
+
+			//fAccumulator += Min(kClock.GetElapsed(), fUpdatePeriod);
+			fAccumulator += fDelta;
+
+			for(; fAccumulator >= fPeriod; fAccumulator -= fPeriod)
+			//while(fAccumulator >= fPeriod)
+			{
+				Update(fPeriod);
+				//fAccumulator -= fPeriod;
+			}
+
+			Render();
+		}
+
+		Terminate();
+	}
+
+	return eCode;
+}
+
+/*
+ * OnMessage
+ */
+int32 Application::OnMessage(Window* pInstance, uint32 nMessage, WPARAM wParam, LPARAM lParam)
+{
+	if(nMessage == WM_CLOSE)
+	{
+		pInstance->Terminate();
+		return 0;
+	}
+	else
+	
+	if(nMessage == WM_DESTROY)
+	{
+		PostQuitMessage(0);
+		return 0;
+	}
+
+	return DefWindowProc(pInstance->GetHandle(), nMessage, wParam, lParam);
+}
+
+/*
+ * Initialize
+ */
+ErrorCode Application::Initialize()
+{
+	ErrorCode eCode = kWindow.Initialize();
+	if(eCode != Error_Success)
+	{
+		TRACE("Error: Failed to initialize window\n");
+
+		Terminate();
+		return eCode;
+	}
+
+	bRunning = true;
+
+	return eCode;
+}
+
+/*
+ * Terminate
+ */
+void Application::Terminate()
+{
+}
+
+/*
+ * Update
+ */
+void Application::Update(float fElapsed)
+{
+}
+
+/*
+ * Render
+ */
+void Application::Render()
+{
+}
+
+/*
+ * ProcessMessages
+ */
+void Application::ProcessMessages()
+{
+	MSG kMessage;
+
+	while(PeekMessage(&kMessage, NULL, 0, 0, PM_REMOVE))
+	{
+		if(kMessage.message == WM_QUIT)
+		{
+			bRunning = false;
+		}
+		else
+		{
+			TranslateMessage(&kMessage);
+			DispatchMessage(&kMessage);
+		}
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LightClone/Source/Application.h	Tue Oct 18 17:08:17 2011 -0700
@@ -0,0 +1,91 @@
+/*
+ * Application
+ */
+
+#ifndef __APPLICATION_H__
+#define __APPLICATION_H__
+
+//#include "Core.h"
+#include "Clock.h"
+#include "Window.h"
+
+/*
+ * Application
+ */
+class Application : public WindowCallback
+{
+protected:
+
+	/*
+	 * kWindow
+	 */
+	Window kWindow;
+
+	/*
+	 * kClock
+	 */
+	Clock kClock;
+
+	/*
+	 * fPeriod
+	 */
+	float fPeriod;
+
+	/*
+	 * fAccumulator
+	 */
+	float fAccumulator;
+
+	/*
+	 * bRunning
+	 */
+	bool bRunning;
+
+public:
+
+	/*
+	 * Application
+	 */
+	Application(float fRate = 60.0f);
+
+	/*
+	 * Run
+	 */
+	ErrorCode Run();
+
+	/*
+	 * OnMessage
+	 */
+	virtual int32 OnMessage(Window* pInstance, uint32 nMessage, WPARAM wParam, LPARAM lParam);
+
+protected:
+
+	/*
+	 * Initialize
+	 */
+	virtual ErrorCode Initialize();
+
+	/*
+	 * Terminate
+	 */
+	virtual void Terminate();
+
+	/*
+	 * Update
+	 */
+	virtual void Update(float fElapsed);
+
+	/*
+	 * Render
+	 */
+	virtual void Render();
+
+private:
+
+	/*
+	 * ProcessMessages
+	 */
+	virtual void ProcessMessages();
+};
+
+#endif //__APPLICATION_H__
--- a/LightClone/Source/Core.h	Tue Oct 18 11:56:49 2011 -0700
+++ b/LightClone/Source/Core.h	Tue Oct 18 17:08:17 2011 -0700
@@ -26,7 +26,6 @@
 	ApplicationState_Game,
 	ApplicationState_Pause,
 	ApplicationState_Help,
-	ApplicationState_Confirm,
 	ApplicationState_Exit,
 };
 
@@ -37,8 +36,9 @@
 {
 	GameState_Load,
 	GameState_Active,
-	GameState_Complete,
+	GameState_Level,
 	GameState_Over,
+	GameState_Confirm,
 };
 
 /*
--- a/LightClone/Source/Mediator.cpp	Tue Oct 18 11:56:49 2011 -0700
+++ b/LightClone/Source/Mediator.cpp	Tue Oct 18 17:08:17 2011 -0700
@@ -5,77 +5,25 @@
 #include "Mediator.h"
 #include "VertexTypes.h"
 
-#pragma warning(disable:4355)
-
-/*
- * fUpdatePeriod
- */
-static const float fUpdatePeriod = 1.0f / 60.0f;
-
 /*
  * Mediator
  */
-Mediator::Mediator() : kWindow(this)
+Mediator::Mediator() : Application()
 {
 	pGraphicsDevice	= NULL;
 }
 
 /*
- * Run
- */
-ErrorCode Mediator::Run()
-{
-	ErrorCode eCode = Initialize();
-	if(eCode == Error_Success)
-	{
-		kClock.Reset();
-
-		fAccumulator = fUpdatePeriod;
-		while(nApplicationState != ApplicationState_Exit)
-		{
-			ProcessMessages();
-			ProcessUpdate();
-			ProcessRender();
-		}
-
-		Terminate();
-	}
-
-	return eCode;
-}
-
-/*
- * OnMessage
- */
-int32 Mediator::OnMessage(Window* pInstance, uint32 nMessage, WPARAM wParam, LPARAM lParam)
-{
-	if(nMessage == WM_CLOSE)
-	{
-		pInstance->Terminate();
-		return 0;
-	}
-	else
-	
-	if(nMessage == WM_DESTROY)
-	{
-		PostQuitMessage(0);
-		return 0;
-	}
-
-	return DefWindowProc(pInstance->GetHandle(), nMessage, wParam, lParam);
-}
-
-/*
  * Initialize
  */
 ErrorCode Mediator::Initialize()
 {
 	InitializeTrace(TraceFlag_Debug | TraceFlag_File);
 
-	ErrorCode eCode = kWindow.Initialize();
+	ErrorCode eCode = Application::Initialize();
 	if(eCode != Error_Success)
 	{
-		TRACE("Error: Failed to initialize window\n");
+		TRACE("Error: Failed to initialize application\n");
 
 		Terminate();
 		return eCode;
@@ -162,7 +110,7 @@
 		return eCode;
 	}
 
-	eCode = InitializeInterface(&kServiceProvider);				
+	eCode = kInterface.Initialize(&kServiceProvider);
 	if(eCode != Error_Success)
 	{
 		TRACE("Error: Failed to initialize interface\n");
@@ -171,9 +119,34 @@
 		return eCode;
 	}
 
-	nGameState			= GameState_Load;
-	nSimulationState	= SimulationState_Idle;
-	nCurrentLevel		= 0;
+	eCode = InitializeMainMenu();
+	if(eCode != Error_Success)
+	{
+		TRACE("Error: Failed to initialize main menu\n");
+
+		Terminate();
+		return eCode;
+	}
+
+	eCode = InitializeHelpMenu();
+	if(eCode != Error_Success)
+	{
+		TRACE("Error: Failed to initialize help menu\n");
+
+		Terminate();
+		return eCode;
+	}
+
+	eCode = InitializeHud();
+	if(eCode != Error_Success)
+	{
+		TRACE("Error: Failed to initialize HUD\n");
+
+		Terminate();
+		return eCode;
+	}
+
+	SetApplicationState(ApplicationState_Main);
 
 	return eCode;
 }
@@ -203,6 +176,8 @@
 {
 	kInputManager.Update(fElapsed);
 
+	UpdateInput(fElapsed);
+
 	if(nApplicationState == ApplicationState_Main)
 	{
 	}
@@ -210,7 +185,6 @@
 
 	if(nApplicationState == ApplicationState_Game)
 	{
-		UpdateInput(fElapsed);
 		UpdateLogic(fElapsed);
 
 		{
@@ -220,8 +194,41 @@
 			sprintf_s(kBuffer, "Camera: <%.2f, %.2f, %.2f> (%.2f, %.2f, %.2f)", kCameraPosition.x, kCameraPosition.y, kCameraPosition.z, kCameraController.fCameraDistance, kCameraController.fCameraYaw, kCameraController.fCameraPitch);
 			pDebugText->SetText(kBuffer);
 		}
+	}
+	else
 
-		kInterface.Update(fElapsed);
+	if(nApplicationState == ApplicationState_Pause)
+	{
+	}
+	else
+
+	if(nApplicationState == ApplicationState_Help)
+	{
+	}
+
+	kInterface.Update(fElapsed);
+}
+
+/*
+ * Render
+ */
+void Mediator::Render()
+{
+	const uint32 nColor = D3DCOLOR_XRGB(32, 32, 32);
+
+	kContext.Begin(nColor);
+
+	if(nApplicationState == ApplicationState_Main)
+	{
+	}
+	else
+
+	if(nApplicationState == ApplicationState_Game)
+	{
+		if(nGameState >= GameState_Active)
+		{
+			RenderGame();
+		}
 	}
 	else
 
@@ -233,125 +240,464 @@
 	if(nApplicationState == ApplicationState_Help)
 	{
 	}
-	else
+
+	RenderInterface();
+
+	kContext.End();
+}
 
-	if(nApplicationState == ApplicationState_Confirm)
-	{
-	}
+/*
+ * InitializeMainMenu
+ */
+ErrorCode Mediator::InitializeMainMenu()
+{
+	pMainBackground = new GuiImage();
+	pMainBackground->Initialize(&kServiceProvider);
+	pMainBackground->SetTexture("Data\\Textures\\MainMenu\\Background.png", true);
+	pMainBackground->SetPosition(0, 0);
+	pMainBackground->ClearFlag(GuiElementFlag_Visible);
+	pMainBackground->SetDepth(512.0f);
 
-	//kScreenManager.Update(fElapsed);
+	kInterface.Add(pMainBackground);
+
+	return Error_Success;
+}
+
+/*
+ * InitializeHelpMenu
+ */
+ErrorCode Mediator::InitializeHelpMenu()
+{
+	return Error_Success;
 }
 
 /*
- * Render
+ * InitializeHud
  */
-void Mediator::Render()
+ErrorCode Mediator::InitializeHud()
 {
-	const uint32 nColor = D3DCOLOR_XRGB(32, 32, 32);
+	pHudBackground = new GuiImage();
+	pHudBackground->Initialize(&kServiceProvider);
+	pHudBackground->SetTexture("Data\\Textures\\Background04.tga", true);
+	pHudBackground->SetPosition(ScreenSizeX - pHudBackground->GetWidth(), 0.0f);
+	pHudBackground->SetDepth(512.0f);
+	pHudBackground->ClearFlag(GuiElementFlag_Visible);
+
+	pToolbar = new ActionPanel(4, 2);
+	pToolbar->Initialize(&kServiceProvider);
+	pToolbar->SetTexture("Data\\Textures\\PanelA.png");
+	pToolbar->SetPosition(16, 16.0f);
+	pToolbar->SetAction(0, Action_Forward);
+	pToolbar->SetAction(1, Action_RotateCW);
+	pToolbar->SetAction(2, Action_RotateCCW);
+	pToolbar->SetAction(3, Action_Jump);
+	pToolbar->SetAction(4, Action_Light);
+	pToolbar->SetAction(5, Action_FunctionA);
+	pToolbar->SetAction(6, Action_FunctionB);
+	pToolbar->SetPermanent(true);
+	pToolbar->SetDepth(256.0f);
+
+	GuiLabel* pMainLabel = new GuiLabel();
+	pMainLabel->Initialize(&kServiceProvider);
+	pMainLabel->SetFont("Courier New", 16);
+	pMainLabel->SetText("Main:");
+	pMainLabel->SetColor(D3DCOLOR_XRGB(0, 0, 0));
+	pMainLabel->SetPosition(26.0f, 149.0f);
+	pMainLabel->SetDepth(256.0f);
+
+	pCode[0] = new ActionPanel(4, 3);
+	pCode[0]->Initialize(&kServiceProvider);
+	pCode[0]->SetTexture("Data\\Textures\\PanelB.png");
+	pCode[0]->SetPosition(16.0f, 160.0f);
+	pCode[0]->Subscribe(ActionPanel::EventAction, &Mediator::OnAction, this);
+	pCode[0]->SetDepth(256.0f);
+
+	GuiLabel* pFunctionALabel = new GuiLabel();
+	pFunctionALabel->Initialize(&kServiceProvider);
+	pFunctionALabel->SetFont("Courier New", 16);
+	pFunctionALabel->SetText("Function 1:");
+	pFunctionALabel->SetColor(D3DCOLOR_XRGB(0, 0, 0));
+	pFunctionALabel->SetPosition(26.0f, 349.0f);
+
+	pCode[1] = new ActionPanel(4, 2);
+	pCode[1]->Initialize(&kServiceProvider);
+	pCode[1]->SetTexture("Data\\Textures\\PanelA.png");
+	pCode[1]->SetPosition(16.0f, 360.0f);
+	pCode[1]->Subscribe(ActionPanel::EventAction, &Mediator::OnAction, this);
+
+	GuiLabel* pFunctionBLabel = new GuiLabel();
+	pFunctionBLabel->Initialize(&kServiceProvider);
+	pFunctionBLabel->SetFont("Courier New", 16);
+	pFunctionBLabel->SetText("Function 2:");
+	pFunctionBLabel->SetColor(D3DCOLOR_XRGB(0, 0, 0));
+	pFunctionBLabel->SetPosition(26.0f, 493.0f);
+
+	pCode[2] = new ActionPanel(4, 2);
+	pCode[2]->Initialize(&kServiceProvider);
+	pCode[2]->SetTexture("Data\\Textures\\PanelA.png");
+	pCode[2]->SetPosition(16.0f, 504.0f);
+	pCode[2]->Subscribe(ActionPanel::EventAction, &Mediator::OnAction, this);
+
+	const float fButtonPadding	= 32.0f;
+	const float fButtonSpacing	= 8.0f;
+	const float fButtonSize		= 48.0f;
+
+	pButtonPlay = new GuiButton();
+	pButtonPlay->Initialize(&kServiceProvider);
+	pButtonPlay->SetTexture(GuiButtonState_Normal, "Data\\Textures\\Button2N.png", true);
+	pButtonPlay->SetTexture(GuiButtonState_Hover, "Data\\Textures\\Button2H.png", true);
+	pButtonPlay->SetTexture(GuiButtonState_Down, "Data\\Textures\\Button2D.png", true);
+	pButtonPlay->SetFont("Courier New", 16, FW_BOLD);
+	pButtonPlay->SetText("Play");
+	pButtonPlay->SetColor(D3DCOLOR_XRGB(0, 0, 0));
+	pButtonPlay->SetPosition(fButtonPadding + 0.0f * (fButtonSize + fButtonSpacing), 652.0f);
+	pButtonPlay->Subscribe(GuiButton::EventClick, &Mediator::OnPlay, this);
 
-	kContext.Begin(nColor);
-	//kScreenManager.Render(kContext);
+	pButtonStop = new GuiButton();
+	pButtonStop->Initialize(&kServiceProvider);
+	pButtonStop->SetTexture(GuiButtonState_Normal, "Data\\Textures\\Button2N.png", true);
+	pButtonStop->SetTexture(GuiButtonState_Hover, "Data\\Textures\\Button2H.png", true);
+	pButtonStop->SetTexture(GuiButtonState_Down, "Data\\Textures\\Button2D.png", true);
+	pButtonStop->SetFont("Courier New", 16, FW_BOLD);
+	pButtonStop->SetText("Stop");
+	pButtonStop->SetColor(D3DCOLOR_XRGB(0, 0, 0));
+	pButtonStop->SetPosition(fButtonPadding + 1.0f * (fButtonSize + fButtonSpacing), 652.0f);
+	pButtonStop->Subscribe(GuiButton::EventClick, &Mediator::OnStop, this);
+
+	pButtonReset = new GuiButton();
+	pButtonReset->Initialize(&kServiceProvider);
+	pButtonReset->SetTexture(GuiButtonState_Normal, "Data\\Textures\\Button2N.png", true);
+	pButtonReset->SetTexture(GuiButtonState_Hover, "Data\\Textures\\Button2H.png", true);
+	pButtonReset->SetTexture(GuiButtonState_Down, "Data\\Textures\\Button2D.png", true);
+	pButtonReset->SetFont("Courier New", 16, FW_BOLD);
+	pButtonReset->SetText("Reset");
+	pButtonReset->SetColor(D3DCOLOR_XRGB(0, 0, 0));
+	pButtonReset->SetPosition(fButtonPadding + 2.0f * (fButtonSize + fButtonSpacing), 652.0f);
+	pButtonReset->Subscribe(GuiButton::EventClick, &Mediator::OnReset, this);
+
+	pButtonExit = new GuiButton();
+	pButtonExit->Initialize(&kServiceProvider);
+	pButtonExit->SetTexture(GuiButtonState_Normal, "Data\\Textures\\Button2N.png", true);
+	pButtonExit->SetTexture(GuiButtonState_Hover, "Data\\Textures\\Button2H.png", true);
+	pButtonExit->SetTexture(GuiButtonState_Down, "Data\\Textures\\Button2D.png", true);
+	pButtonExit->SetFont("Courier New", 16, FW_BOLD);
+	pButtonExit->SetText("Exit");
+	pButtonExit->SetColor(D3DCOLOR_XRGB(0, 0, 0));
+	pButtonExit->SetPosition(fButtonPadding + 3.0f * (fButtonSize + fButtonSpacing), 652.0f);
+	pButtonExit->Subscribe(GuiButton::EventClick, &Mediator::OnExit, this);
 
+	pHudBackground->Add(pToolbar);
+	pHudBackground->Add(pMainLabel);
+	pHudBackground->Add(pCode[0]);
+	pHudBackground->Add(pFunctionALabel);
+	pHudBackground->Add(pCode[1]);
+	pHudBackground->Add(pFunctionBLabel);
+	pHudBackground->Add(pCode[2]);
+	pHudBackground->Add(pButtonPlay);
+	pHudBackground->Add(pButtonStop);
+	pHudBackground->Add(pButtonReset);
+	pHudBackground->Add(pButtonExit);
+
+	pDebugText = new GuiLabel();
+	pDebugText->Initialize(&kServiceProvider);
+	pDebugText->SetFont("Courier New", 16);
+	pDebugText->SetPosition(10.0f, 10.0f);
+	pDebugText->SetText("Debug");
+	pDebugText->SetColor(D3DCOLOR_XRGB(255, 255, 255));
+
+	kInterface.Add(pHudBackground);
+	kInterface.Add(pDebugText);
+
+	return Error_Success;
+}
+
+/*
+ * UpdateInput
+ */
+void Mediator::UpdateInput(float fElapsed)
+{
 	if(nApplicationState == ApplicationState_Main)
 	{
+		if(kInputManager.IsKeyDown(DIK_SPACE))
+		{
+			nCurrentLevel		= 0;
+			nGameState			= GameState_Load;
+			nSimulationState	= SimulationState_Idle;
+
+			SetApplicationState(ApplicationState_Game);
+		}
+	}
+	else
+	
+	if(nApplicationState == ApplicationState_Help)
+	{
 	}
 	else
 
 	if(nApplicationState == ApplicationState_Game)
 	{
-		if(nGameState != GameState_Load)
+		#if defined(_DEBUG)
+		if(kInputManager.IsKeyDown(DIK_LEFT))
 		{
-			D3DVIEWPORT9 kOriginal;
-			kContext.GetViewport(&kOriginal);
+			kCameraController.Yaw(0.01f);
+		}
+		else
+
+		if(kInputManager.IsKeyDown(DIK_RIGHT))
+		{
+			kCameraController.Yaw(-0.01f);
+		}
 
-			D3DVIEWPORT9 kViewport;
-			kViewport.X			= 0;
-			kViewport.Y			= 0;
-			kViewport.Width		= ScreenSizeX - 280;	// minus size of interface
-			kViewport.Height	= ScreenSizeY;
-			kViewport.MinZ		= kOriginal.MinZ;
-			kViewport.MaxZ		= kOriginal.MaxZ;
+		if(kInputManager.IsKeyDown(DIK_UP))
+		{
+			kCameraController.Pitch(0.01f);
+		}
+		else
 
-			kContext.SetViewport(kViewport);
+		if(kInputManager.IsKeyDown(DIK_DOWN))
+		{
+			kCameraController.Pitch(-0.01f);
+		}
 
-			kCameraController.SetMode(CameraMode_3D);
-		
-			kEnvironment.Render(kContext, kCameraController);
-			kBot.Render(kContext, kCameraController);
+		if(kInputManager.IsKeyDown(DIK_NEXT))
+		{
+			kCameraController.Move(0.1f);
+		}
+		else
 
-			kContext.SetViewport(kOriginal);
+		if(kInputManager.IsKeyDown(DIK_PRIOR))
+		{
+			kCameraController.Move(-0.1f);
 		}
 
-		kCameraController.SetMode(CameraMode_2D);
-		kInterface.Render(kContext, kCameraController);
+		static bool bControl = false;
+		static uint32 nBuffer[4] = {0};
+		static uint32 nCount = 0;
+
+		if(bControl)
+		{
+			if(kInputManager.IsKeyDown(DIK_0) && !kInputManager.WasKeyDown(DIK_0))
+			{
+				nBuffer[nCount++] = 0;
+			}
+			else
+
+			if(kInputManager.IsKeyDown(DIK_1) && !kInputManager.WasKeyDown(DIK_1))
+			{
+				nBuffer[nCount++] = 1;
+			}
+			else
+
+			if(kInputManager.IsKeyDown(DIK_2) && !kInputManager.WasKeyDown(DIK_2))
+			{
+				nBuffer[nCount++] = 2;
+			}
+			else
+
+			if(kInputManager.IsKeyDown(DIK_3) && !kInputManager.WasKeyDown(DIK_3))
+			{
+				nBuffer[nCount++] = 3;
+			}
+			else
+
+			if(kInputManager.IsKeyDown(DIK_4) && !kInputManager.WasKeyDown(DIK_4))
+			{
+				nBuffer[nCount++] = 4;
+			}
+			else
+
+			if(kInputManager.IsKeyDown(DIK_5) && !kInputManager.WasKeyDown(DIK_5))
+			{
+				nBuffer[nCount++] = 5;
+			}
+			else
+
+			if(kInputManager.IsKeyDown(DIK_6) && !kInputManager.WasKeyDown(DIK_6))
+			{
+				nBuffer[nCount++] = 6;
+			}
+			else
+
+			if(kInputManager.IsKeyDown(DIK_7) && !kInputManager.WasKeyDown(DIK_7))
+			{
+				nBuffer[nCount++] = 7;
+			}
+			else
+
+			if(kInputManager.IsKeyDown(DIK_8) && !kInputManager.WasKeyDown(DIK_8))
+			{
+				nBuffer[nCount++] = 8;
+			}
+			else
+
+			if(kInputManager.IsKeyDown(DIK_9) && !kInputManager.WasKeyDown(DIK_9))
+			{
+				nBuffer[nCount++] = 9;
+			}
+
+			if(!kInputManager.IsKeyDown(DIK_LCONTROL))
+			{
+				if(nCount > 0)
+				{
+					nCurrentLevel	= 0;
+					nGameState		= GameState_Load;
+
+					for(uint32 i = 0; i < nCount; ++i)
+					{
+						nCurrentLevel += (uint32)(nBuffer[i] * powf(10.0f, (float)i));
+					}
+				}
+
+				bControl = false;
+			}
+		}
+		else
+		{
+			if(kInputManager.IsKeyDown(DIK_LCONTROL))
+			{
+				bControl = true;
+				nCount = 0;
+			}
+		}
+		#endif
+	}
+}
+
+/*
+ * UpdateLogic
+ */
+void Mediator::UpdateLogic(float fElapsed)
+{
+	if(nGameState == GameState_Load)
+	{
+		ErrorCode eCode = LoadLevel(nCurrentLevel++);
+		if(eCode == Error_Success)
+		{
+			kProgram.Clear();
+
+			for(uint32 i = 0; i < MaximumFunctionCount; ++i)
+			{
+				pCode[i]->Clear();
+			}
+
+			nGameState = GameState_Active;
+		}
+		else
+		{
+			pMessageDialog->SetButton(0, "Ok", DialogResult_Ok);
+			pMessageDialog->SetMessage("Congratulations!\nYou've won the game!");
+			pMessageDialog->Show();
+
+			nGameState = GameState_Over;
+		}
+
+		nSimulationState = SimulationState_Idle;
 	}
 	else
 
-	if(nApplicationState == ApplicationState_Pause)
+	if(nGameState == GameState_Active)
 	{
+		if(nSimulationState == SimulationState_Active)
+		{
+			if(kBot.Update(fElapsed))
+			{
+				if(kEnvironment.RequirementsMet())
+				{
+					pMessageDialog->SetButton(0, "Ok", DialogResult_Ok);
+					pMessageDialog->SetMessage("Congratulations!\nYou've completed level %d", nCurrentLevel);
+					pMessageDialog->Show();
+
+					nGameState = GameState_Level;
+				}
+			}
+		}
+	}
+}
+
+/*
+ * RenderGame
+ */
+void Mediator::RenderGame()
+{
+	D3DVIEWPORT9 kOriginal;
+	kContext.GetViewport(&kOriginal);
+
+	D3DVIEWPORT9 kViewport;
+	kViewport.X			= 0;
+	kViewport.Y			= 0;
+	kViewport.Width		= ScreenSizeX - 280;	// minus size of interface
+	kViewport.Height	= ScreenSizeY;
+	kViewport.MinZ		= kOriginal.MinZ;
+	kViewport.MaxZ		= kOriginal.MaxZ;
+
+	kContext.SetViewport(kViewport);
+
+	kCameraController.SetMode(CameraMode_3D);
+
+	kEnvironment.Render(kContext, kCameraController);
+	kBot.Render(kContext, kCameraController);
+
+	kContext.SetViewport(kOriginal);
+}
+
+/*
+ * RenderInterface
+ */
+void Mediator::RenderInterface()
+{
+	kCameraController.SetMode(CameraMode_2D);
+	kInterface.Render(kContext, kCameraController);
+}
+
+/*
+ * SetApplicationState
+ */
+void Mediator::SetApplicationState(uint32 nState)
+{
+	if(nApplicationState == ApplicationState_Main)
+	{
+		pMainBackground->ClearFlag(GuiElementFlag_Visible);
 	}
 	else
-
+	
 	if(nApplicationState == ApplicationState_Help)
 	{
 	}
 	else
 
-	if(nApplicationState == ApplicationState_Confirm)
+	if(nApplicationState == ApplicationState_Game)
 	{
+		pHudBackground->ClearFlag(GuiElementFlag_Visible);
 	}
 
-	kContext.End();
-}
-
-/*
- * ProcessMessages
- */
-void Mediator::ProcessMessages()
-{
-	MSG kMessage;
+	nApplicationState = nState;
 
-	while(PeekMessage(&kMessage, NULL, 0, 0, PM_REMOVE))
+	if(nApplicationState == ApplicationState_Main)
 	{
-		if(kMessage.message == WM_QUIT)
-		{
-			nApplicationState = ApplicationState_Exit;
-		}
-		else
-		{
-			TranslateMessage(&kMessage);
-			DispatchMessage(&kMessage);
-		}
+		pMainBackground->SetFlag(GuiElementFlag_Visible);
+	}
+	else
+	
+	if(nApplicationState == ApplicationState_Help)
+	{
+	}
+	else
+
+	if(nApplicationState == ApplicationState_Game)
+	{
+		pHudBackground->SetFlag(GuiElementFlag_Visible);
 	}
 }
 
 /*
- * ProcessUpdate
+ * LoadLevel
  */
-void Mediator::ProcessUpdate()
+ErrorCode Mediator::LoadLevel(uint32 nLevel)
 {
-	fAccumulator += Min(kClock.GetElapsed(), fUpdatePeriod);
-	while(fAccumulator >= fUpdatePeriod)
-	{
-		Update(fUpdatePeriod);
-		fAccumulator -= fUpdatePeriod;
-	}
-}
+	char kName[MAX_PATH];
+	sprintf(kName, "Data\\Maps\\Map%02d.map", nLevel);
 
-/*
- * ProcessRender
- */
-void Mediator::ProcessRender()
-{
-	Render();
-}
-
-/*
- * Load
- */
-ErrorCode Mediator::Load(const char* pName)
-{
-	ErrorCode eCode = kLoader.Load(pName);
+	ErrorCode eCode = kLoader.Load(kName);
 	if(eCode == Error_Success)
 	{
 		const Size& kSize = kLoader.GetSize();
@@ -371,8 +717,6 @@
 			kBot.Setup(&kEnvironment);
 			kBot.SetPosition(kLoader.GetInitialPosition());
 			kBot.SetDirection(kLoader.GetInitialDirection());
-
-			//kCameraController.SetDistance(
 		}
 	}
 
@@ -380,324 +724,17 @@
 }
 
 /*
- * InitializeInterface
+ * OnStart
  */
-ErrorCode Mediator::InitializeInterface(ServiceProvider* pServiceProvider)
+void Mediator::OnStart(GuiEventArguments& kArguments)
 {
-	ErrorCode eCode = kInterface.Initialize(pServiceProvider);
-	if(eCode == Error_Success)
-	{
-		pBackground = new GuiImage();
-		pBackground->Initialize(pServiceProvider);
-		pBackground->SetTexture("Data\\Textures\\Background04.tga", true);
-		pBackground->SetPosition(ScreenSizeX - pBackground->GetWidth(), 0.0f);
-		pBackground->SetDepth(512.0f);
-
-		pToolbar = new ActionPanel(4, 2);
-		pToolbar->Initialize(pServiceProvider);
-		pToolbar->SetTexture("Data\\Textures\\PanelA.png");
-		pToolbar->SetPosition(16, 16.0f);
-		pToolbar->SetAction(0, Action_Forward);
-		pToolbar->SetAction(1, Action_RotateCW);
-		pToolbar->SetAction(2, Action_RotateCCW);
-		pToolbar->SetAction(3, Action_Jump);
-		pToolbar->SetAction(4, Action_Light);
-		pToolbar->SetAction(5, Action_FunctionA);
-		pToolbar->SetAction(6, Action_FunctionB);
-		pToolbar->SetPermanent(true);
-		pToolbar->SetDepth(256.0f);
-
-		GuiLabel* pMainLabel = new GuiLabel();
-		pMainLabel->Initialize(pServiceProvider);
-		pMainLabel->SetFont("Courier New", 16);
-		pMainLabel->SetText("Main:");
-		pMainLabel->SetColor(D3DCOLOR_XRGB(0, 0, 0));
-		pMainLabel->SetPosition(26.0f, 149.0f);
-		pMainLabel->SetDepth(256.0f);
-
-		pCode[0] = new ActionPanel(4, 3);
-		pCode[0]->Initialize(pServiceProvider);
-		pCode[0]->SetTexture("Data\\Textures\\PanelB.png");
-		pCode[0]->SetPosition(16.0f, 160.0f);
-		pCode[0]->Subscribe(ActionPanel::EventAction, &Mediator::OnAction, this);
-		pCode[0]->SetDepth(256.0f);
-
-		GuiLabel* pFunctionALabel = new GuiLabel();
-		pFunctionALabel->Initialize(pServiceProvider);
-		pFunctionALabel->SetFont("Courier New", 16);
-		pFunctionALabel->SetText("Function 1:");
-		pFunctionALabel->SetColor(D3DCOLOR_XRGB(0, 0, 0));
-		pFunctionALabel->SetPosition(26.0f, 349.0f);
-
-		pCode[1] = new ActionPanel(4, 2);
-		pCode[1]->Initialize(pServiceProvider);
-		pCode[1]->SetTexture("Data\\Textures\\PanelA.png");
-		pCode[1]->SetPosition(16.0f, 360.0f);
-		pCode[1]->Subscribe(ActionPanel::EventAction, &Mediator::OnAction, this);
-
-		GuiLabel* pFunctionBLabel = new GuiLabel();
-		pFunctionBLabel->Initialize(pServiceProvider);
-		pFunctionBLabel->SetFont("Courier New", 16);
-		pFunctionBLabel->SetText("Function 2:");
-		pFunctionBLabel->SetColor(D3DCOLOR_XRGB(0, 0, 0));
-		pFunctionBLabel->SetPosition(26.0f, 493.0f);
-
-		pCode[2] = new ActionPanel(4, 2);
-		pCode[2]->Initialize(pServiceProvider);
-		pCode[2]->SetTexture("Data\\Textures\\PanelA.png");
-		pCode[2]->SetPosition(16.0f, 504.0f);
-		pCode[2]->Subscribe(ActionPanel::EventAction, &Mediator::OnAction, this);
-
-		const float fButtonPadding	= 32.0f;
-		const float fButtonSpacing	= 8.0f;
-		const float fButtonSize		= 48.0f;
-
-		pButtonPlay = new GuiButton();
-		pButtonPlay->Initialize(pServiceProvider);
-		pButtonPlay->SetTexture(GuiButtonState_Normal, "Data\\Textures\\Button2N.png", true);
-		pButtonPlay->SetTexture(GuiButtonState_Hover, "Data\\Textures\\Button2H.png", true);
-		pButtonPlay->SetTexture(GuiButtonState_Down, "Data\\Textures\\Button2D.png", true);
-		pButtonPlay->SetFont("Courier New", 16, FW_BOLD);
-		pButtonPlay->SetText("Play");
-		pButtonPlay->SetColor(D3DCOLOR_XRGB(0, 0, 0));
-		pButtonPlay->SetPosition(fButtonPadding + 0.0f * (fButtonSize + fButtonSpacing), 652.0f);
-		pButtonPlay->Subscribe(GuiButton::EventClick, &Mediator::OnPlay, this);
-
-		pButtonStop = new GuiButton();
-		pButtonStop->Initialize(pServiceProvider);
-		pButtonStop->SetTexture(GuiButtonState_Normal, "Data\\Textures\\Button2N.png", true);
-		pButtonStop->SetTexture(GuiButtonState_Hover, "Data\\Textures\\Button2H.png", true);
-		pButtonStop->SetTexture(GuiButtonState_Down, "Data\\Textures\\Button2D.png", true);
-		pButtonStop->SetFont("Courier New", 16, FW_BOLD);
-		pButtonStop->SetText("Stop");
-		pButtonStop->SetColor(D3DCOLOR_XRGB(0, 0, 0));
-		pButtonStop->SetPosition(fButtonPadding + 1.0f * (fButtonSize + fButtonSpacing), 652.0f);
-		pButtonStop->Subscribe(GuiButton::EventClick, &Mediator::OnStop, this);
-
-		pButtonReset = new GuiButton();
-		pButtonReset->Initialize(pServiceProvider);
-		pButtonReset->SetTexture(GuiButtonState_Normal, "Data\\Textures\\Button2N.png", true);
-		pButtonReset->SetTexture(GuiButtonState_Hover, "Data\\Textures\\Button2H.png", true);
-		pButtonReset->SetTexture(GuiButtonState_Down, "Data\\Textures\\Button2D.png", true);
-		pButtonReset->SetFont("Courier New", 16, FW_BOLD);
-		pButtonReset->SetText("Reset");
-		pButtonReset->SetColor(D3DCOLOR_XRGB(0, 0, 0));
-		pButtonReset->SetPosition(fButtonPadding + 2.0f * (fButtonSize + fButtonSpacing), 652.0f);
-		pButtonReset->Subscribe(GuiButton::EventClick, &Mediator::OnReset, this);
-
-		pButtonExit = new GuiButton();
-		pButtonExit->Initialize(pServiceProvider);
-		pButtonExit->SetTexture(GuiButtonState_Normal, "Data\\Textures\\Button2N.png", true);
-		pButtonExit->SetTexture(GuiButtonState_Hover, "Data\\Textures\\Button2H.png", true);
-		pButtonExit->SetTexture(GuiButtonState_Down, "Data\\Textures\\Button2D.png", true);
-		pButtonExit->SetFont("Courier New", 16, FW_BOLD);
-		pButtonExit->SetText("Exit");
-		pButtonExit->SetColor(D3DCOLOR_XRGB(0, 0, 0));
-		pButtonExit->SetPosition(fButtonPadding + 3.0f * (fButtonSize + fButtonSpacing), 652.0f);
-		pButtonExit->Subscribe(GuiButton::EventClick, &Mediator::OnExit, this);
-
-		pBackground->Add(pToolbar);
-		pBackground->Add(pMainLabel);
-		pBackground->Add(pCode[0]);
-		pBackground->Add(pFunctionALabel);
-		pBackground->Add(pCode[1]);
-		pBackground->Add(pFunctionBLabel);
-		pBackground->Add(pCode[2]);
-		pBackground->Add(pButtonPlay);
-		pBackground->Add(pButtonStop);
-		pBackground->Add(pButtonReset);
-		pBackground->Add(pButtonExit);
-
-		pDebugText = new GuiLabel();
-		pDebugText->Initialize(pServiceProvider);
-		pDebugText->SetFont("Courier New", 16);
-		pDebugText->SetPosition(10.0f, 10.0f);
-		pDebugText->SetText("Debug");
-		pDebugText->SetColor(D3DCOLOR_XRGB(255, 255, 255));
-
-		kInterface.Add(pBackground);
-		kInterface.Add(pDebugText);
-	}
-
-	return eCode;
 }
 
 /*
- * UpdateInput
+ * OnHelp
  */
-void Mediator::UpdateInput(float fElapsed)
+void Mediator::OnHelp(GuiEventArguments& kArguments)
 {
-	#if defined(_DEBUG)
-	if(pInputManager->IsKeyDown(DIK_LEFT))
-	{
-		kCameraController.Yaw(0.01f);
-	}
-	else
-
-	if(pInputManager->IsKeyDown(DIK_RIGHT))
-	{
-		kCameraController.Yaw(-0.01f);
-	}
-
-	if(pInputManager->IsKeyDown(DIK_UP))
-	{
-		kCameraController.Pitch(0.01f);
-	}
-	else
-
-	if(pInputManager->IsKeyDown(DIK_DOWN))
-	{
-		kCameraController.Pitch(-0.01f);
-	}
-
-	if(pInputManager->IsKeyDown(DIK_NEXT))
-	{
-		kCameraController.Move(0.1f);
-	}
-	else
-
-	if(pInputManager->IsKeyDown(DIK_PRIOR))
-	{
-		kCameraController.Move(-0.1f);
-	}
-
-	static bool bControl = false;
-	static uint32 nBuffer[4] = {0};
-	static uint32 nCount = 0;
-
-	if(bControl)
-	{
-		if(pInputManager->IsKeyDown(DIK_0) && !pInputManager->WasKeyDown(DIK_0))
-		{
-			nBuffer[nCount++] = 0;
-		}
-		else
-
-		if(pInputManager->IsKeyDown(DIK_1) && !pInputManager->WasKeyDown(DIK_1))
-		{
-			nBuffer[nCount++] = 1;
-		}
-		else
-
-		if(pInputManager->IsKeyDown(DIK_2) && !pInputManager->WasKeyDown(DIK_2))
-		{
-			nBuffer[nCount++] = 2;
-		}
-		else
-
-		if(pInputManager->IsKeyDown(DIK_3) && !pInputManager->WasKeyDown(DIK_3))
-		{
-			nBuffer[nCount++] = 3;
-		}
-		else
-
-		if(pInputManager->IsKeyDown(DIK_4) && !pInputManager->WasKeyDown(DIK_4))
-		{
-			nBuffer[nCount++] = 4;
-		}
-		else
-
-		if(pInputManager->IsKeyDown(DIK_5) && !pInputManager->WasKeyDown(DIK_5))
-		{
-			nBuffer[nCount++] = 5;
-		}
-		else
-
-		if(pInputManager->IsKeyDown(DIK_6) && !pInputManager->WasKeyDown(DIK_6))
-		{
-			nBuffer[nCount++] = 6;
-		}
-		else
-
-		if(pInputManager->IsKeyDown(DIK_7) && !pInputManager->WasKeyDown(DIK_7))
-		{
-			nBuffer[nCount++] = 7;
-		}
-		else
-
-		if(pInputManager->IsKeyDown(DIK_8) && !pInputManager->WasKeyDown(DIK_8))
-		{
-			nBuffer[nCount++] = 8;
-		}
-		else
-
-		if(pInputManager->IsKeyDown(DIK_9) && !pInputManager->WasKeyDown(DIK_9))
-		{
-			nBuffer[nCount++] = 9;
-		}
-
-		if(!pInputManager->IsKeyDown(DIK_LCONTROL))
-		{
-			if(nCount > 0)
-			{
-				nCurrentLevel	= 0;
-				nGameState		= GameState_Load;
-
-				for(uint32 i = 0; i < nCount; ++i)
-				{
-					nCurrentLevel += (uint32)(nBuffer[i] * powf(10.0f, (float)i));
-				}
-			}
-
-			bControl = false;
-		}
-	}
-	else
-	{
-		if(pInputManager->IsKeyDown(DIK_LCONTROL))
-		{
-			bControl = true;
-			nCount = 0;
-		}
-	}
-	#endif
-}
-
-/*
- * UpdateLogic
- */
-void Mediator::UpdateLogic(float fElapsed)
-{
-	if(nGameState == GameState_Load)
-	{
-		char kBuffer[256];
-		sprintf(kBuffer, "Data\\Maps\\Map%02d.map", nCurrentLevel++);
-
-		ErrorCode eCode = Load(kBuffer);
-		if(eCode == Error_Success)
-		{
-			kProgram.Clear();
-
-			for(uint32 i = 0; i < MaximumFunctionCount; ++i)
-			{
-				pCode[i]->Clear();
-			}
-
-			nGameState = GameState_Active;
-		}
-		else
-		{
-			//pScreenManager->Push("GameOver");
-		}
-
-		nSimulationState = SimulationState_Idle;
-	}
-	else
-
-	if(nGameState == GameState_Active)
-	{
-		if(nSimulationState == SimulationState_Active)
-		{
-			if(kBot.Update(fElapsed))
-			{
-				if(kEnvironment.RequirementsMet())
-				{
-					nGameState = GameState_Load;
-					//pScreenManager->Push("LevelOver");
-				}
-			}
-		}
-	}
 }
 
 /*
@@ -770,4 +807,5 @@
 void Mediator::OnExit(GuiEventArguments& kArguments)
 {
 	//pScreenManager->Push("Confirm");
+	bRunning = false;
 }
--- a/LightClone/Source/Mediator.h	Tue Oct 18 11:56:49 2011 -0700
+++ b/LightClone/Source/Mediator.h	Tue Oct 18 17:08:17 2011 -0700
@@ -5,9 +5,8 @@
 #ifndef __MEDIATOR_H__
 #define __MEDIATOR_H__
 
+#include "Application.h"
 #include "Core.h"
-#include "Clock.h"
-#include "Window.h"
 #include "InputManager.h"
 #include "GraphicsDevice.h"
 #include "ResourceManager.h"
@@ -26,19 +25,9 @@
 /*
  * Mediator
  */
-class Mediator : public WindowCallback
+class Mediator : public Application
 {
 	/*
-	 * kWindow
-	 */
-	Window kWindow;
-
-	/*
-	 * kClock
-	 */
-	Clock kClock;
-
-	/*
 	 * pGraphicsDevice
 	 */
 	GraphicsDevice* pGraphicsDevice;
@@ -64,21 +53,11 @@
 	ServiceProvider kServiceProvider;
 
 	/*
-	 * fAccumulator
-	 */
-	float fAccumulator;
-
-	/*
 	 * nApplicationState
 	 */
 	uint32 nApplicationState;
 
 	/*
-	 * pInputManager
-	 */
-	InputManager* pInputManager;
-
-	/*
 	 * kCameraController
 	 */
 	CameraController kCameraController;
@@ -124,9 +103,29 @@
 	GuiInterface kInterface;
 
 	/*
-	 * pBackground
+	 * pMainBackground
+	 */
+	GuiImage* pMainBackground;
+
+	/*
+	 * pMainStart
+	 */
+	GuiButton* pMainStart;
+
+	/*
+	 * pMainHelp
 	 */
-	GuiImage* pBackground;
+	GuiButton* pMainHelp;
+
+	/*
+	 * pMainQuit
+	 */
+	GuiButton* pMainQuit;
+
+	/*
+	 * pHudBackground
+	 */
+	GuiImage* pHudBackground;
 
 	/*
 	 * pButtonPlay
@@ -180,17 +179,7 @@
 	 */
 	Mediator();
 
-	/*
-	 * Run
-	 */
-	ErrorCode Run();
-
-	/*
-	 * OnMessage
-	 */
-	virtual int32 OnMessage(Window* pInstance, uint32 nMessage, WPARAM wParam, LPARAM lParam);
-
-private:
+public:
 
 	/*
 	 * Initialize
@@ -205,37 +194,29 @@
 	/*
 	 * Update
 	 */
-	void Update(float fElapsed);
+	virtual void Update(float fElapsed);
 
 	/*
 	 * Render
 	 */
-	void Render();
+	virtual void Render();
 
-	/*
-	 * ProcessMessages
-	 */
-	virtual void ProcessMessages();
-
-	/*
-	 * ProcessUpdate
-	 */
-	void ProcessUpdate();
+private:
 
 	/*
-	 * ProcessRender
+	 * InitializeMainMenu
 	 */
-	void ProcessRender();
+	ErrorCode InitializeMainMenu();
 
 	/*
-	 * Load
+	 * InitializeHelpMenu
 	 */
-	ErrorCode Load(const char* pName);
+	ErrorCode InitializeHelpMenu();
 
 	/*
-	 * InitializeInterface
+	 * InitializeHud
 	 */
-	ErrorCode InitializeInterface(ServiceProvider* pServiceProvider);
+	ErrorCode InitializeHud();
 
 	/*
 	 * UpdateInput
@@ -248,6 +229,36 @@
 	void UpdateLogic(float fElapsed);
 
 	/*
+	 * RenderGame
+	 */
+	void RenderGame();
+
+	/*
+	 * RenderInterface
+	 */
+	void RenderInterface();
+
+	/*
+	 * SetApplicationState
+	 */
+	void SetApplicationState(uint32 nState);
+
+	/*
+	 * LoadLevel
+	 */
+	ErrorCode LoadLevel(uint32 nLevel);
+
+	/*
+	 * OnStart
+	 */
+	void OnStart(GuiEventArguments& kArguments);
+
+	/*
+	 * OnHelp
+	 */
+	void OnHelp(GuiEventArguments& kArguments);
+
+	/*
 	 * OnAction
 	 */
 	void OnAction(GuiEventArguments& kArguments);
--- a/LightClone/ToDo.txt	Tue Oct 18 11:56:49 2011 -0700
+++ b/LightClone/ToDo.txt	Tue Oct 18 17:08:17 2011 -0700
@@ -1,14 +1,8 @@
 Required:
-1.	Main menu
-2.	Pause menu
-3.	Additional maps
-4.	Add memory leak detection
+1.	Pause menu
+2.	Additional maps
+3.	Add sound and music
+4.	Help interface
 
 Polish:
 1.	Button tool tips
-2.	Move resource manager into a service provider container
-3.	Add sound and music
-4.	Help interface
-
-Bugs:
-1.	Fix DX resource leaks
\ No newline at end of file