Here is your problem:
Code:
int DXE::DXEngine::iRunMessageLoop() /*Function Definition*/
{
MSG TempMessage; /*Create a temporary instance of the MSG struct*/
ZeroMemory(&TempMessage, /*Where to start filling with zero's*/
sizeof(MSG)); /*The size of the block of memory to fill with zero's*/
while(PeekMessage(&TempMessage, /*Message instance with the required information*/
0, /*Window handle, if NULL, then retrieve all messages belonging to the current thread*/
0, /*Specifies the first value in the message queue to be examined, if NULL, then return all available messages*/
0, /*Specifies the last value in the message queue to be examined, if NULL, then return all available messages*/
PM_REMOVE)) /*Remove the messages after they have been processed*/
{
TranslateMessage(&TempMessage); /*Function to translate virtual key messages into character messages*/
DispatchMessage(&TempMessage); /*Function to dispatch a message to the windows procedure*/
}
return TempMessage.wParam;
}
You should not return from this function until your game is over.
Code:
void App::EnterMessageLoop()
{
MSG msg;
float timeDelta = 0.0f;
LARGE_INTEGER freq;
LARGE_INTEGER nowTime;
LARGE_INTEGER lastTime;
QueryPerformanceFrequency(&freq);
QueryPerformanceCounter(&lastTime);
m_isRunning = true;
while (m_isRunning)
{
if(::PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
QueryPerformanceCounter(&nowTime);
float timeDelta = (nowTime.QuadPart - lastTime.QuadPart) * (1.0f / freq.QuadPart);
Update(timeDelta);
Render();
lastTime = nowTime;
}
}
The code I just posted will keep the loop running until m_isRunning is false. m_isRunning would be set by the user exiting the game. After this loop returns you should then allow the game to cleanup. Here is my main function:
Code:
SomeGameApp g_App;
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
unsigned int screenWidth = 800;
unsigned int screenHeight = 600;
bool windowed = true;
g_App.InitApp(screenWidth,screenHeight,true,0,windowed);
bool result = g_App.Setup();
if (!result)
{
::MessageBox(0,"Application setup FAILED - exiting.","ERROR",MB_OK | MB_ICONEXCLAMATION);
}
else
{
g_App.EnterMessageLoop();
g_App.Cleanup();
}
return 0;
}
SomeGameApp is derived from App which has 4 pure virtual functions. Setup(), Render(), Update(float timeDelta), and Cleanup(). EnterMessageLoop() is part of the base class. Base class InitApp() will setup Direct3D or whatever rendering API you are using. InitApp() can create it's own window or it can simply use an HWND that is passed to it. This allows the rendering engine to be used inside of an editor and the editor then passes the HWND to the engine.
Note that the window width, height is hard-coded and would not be in a release. At this point you could read in the height/width from XML or and ini file or some type of data file that had the necessary data in it.