I'm trying to create a class to manage the various game states for my engine (main menu, gamescreen, ect...) I think I'm on the right track here but I can't get anything to render to the screen.
Here is my manager class...
Code:
enum Purpose {
SM_INIT = 0,
SM_RESET,
SM_PROCESS,
SM_UPDATE,
SM_RENDER,
SM_LOST,
SM_SHUTDOWN,
SM_NO_PURPOSE
};
class CStateManager {
private:
typedef void(*pFunction)(LPDIRECT3DDEVICE9 pDevice, void* pCaller, UINT Purpose, void *DataPtr);
std::vector<pFunction> States;
std::vector<pFunction>::iterator StateIter;
public:
CStateManager() { }
~CStateManager() { PopAll(); }
bool Push(void (*Function)(LPDIRECT3DDEVICE9 pDevice, void* pCaller, UINT Purpose, void *DataPtr) );
bool Pop();
void PopAll() { States.clear(); }
bool Process(LPDIRECT3DDEVICE9 pDevice, void* pCaller, UINT Purpose, void* pData = NULL);
};
bool CStateManager::Push(void (*Function)(LPDIRECT3DDEVICE9 pDevice, void* pCaller, UINT Purpose, void* pData) ) {
// Don't push a NULL value
if(Function != NULL) {
// Push new function onto stack
States.push_back(Function);
return true;
} else return false;
}
bool CStateManager::Pop() {
// Remove the head of stack (if any)
if(!States.empty() ) {
States.pop_back();
}
// return TRUE if more states exist, FALSE otherwise
if(States.empty() )
return false;
return true;
}
bool CStateManager::Process(LPDIRECT3DDEVICE9 pDevice, void* pCaller, UINT Purpose, void* pData) {
// return an error if no more states
if(States.empty() )
return false;
// Process the top-most state
StateIter = States.end() - 1;
(*StateIter)(pDevice, pCaller, Purpose, pData);
return true;
}
My game state function prototypes and definitions...
Code:
class CGameApp {
public:
.....
static void GameFrame(LPDIRECT3DDEVICE9 pDevice, void* pCaller, UINT Purpose, void *DataPtr);
static void GameStart(LPDIRECT3DDEVICE9 pDevice, void* pCaller, UINT Purpose, void *DataPtr);
....
};
void CGameApp::GameStart(LPDIRECT3DDEVICE9 pDevice, void* pCaller, UINT Purpose, void *DataPtr) {
CGameApp *GameApp = (CGameApp*)pCaller;
if (Purpose == SM_RENDER) {
pDevice->SetTransform(D3DTS_VIEW, GameApp->m_camera.GetViewMatrix() );
GameApp->m_fps = GameApp->m_pFramework->GetFPS() + " fps";
pDevice->Clear(0,
0,
D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
D3DCOLOR_XRGB(0, 0, 0),
1.0f,
0);
pDevice->BeginScene();
GameApp->m_pTextSprite->Begin(D3DXSPRITE_ALPHABLEND | D3DXSPRITE_SORT_TEXTURE);
GameApp->m_font.Print(g_instructions1.c_str(), 5, 20, D3DCOLOR_XRGB(200, 200, 200), GameApp->m_pTextSprite);
GameApp->m_pTextSprite->End();
pDevice->EndScene();
pDevice->Present(0, 0, 0, 0);
}
if (Purpose == SM_PROCESS) {
sUserInput Input = *( (psUserInput)DataPtr);
if (Input.pPressedKeys[DIK_ESCAPE] ) {
GameApp->m_pFramework->LockKey(DIK_ESCAPE);
GameApp->m_StateManager.PopAll();
PostQuitMessage(0);
}
if (Input.pPressedKeys[DIK_SPACE]) {
GameApp->m_pFramework->LockKey(DIK_SPACE);
GameApp->m_StateManager.Push(GameApp->GameFrame);
}
}
return;
}
void CGameApp::GameFrame(LPDIRECT3DDEVICE9 pDevice, void* pCaller, UINT Purpose, void *DataPtr) {
CGameApp *GameApp = (CGameApp*)pCaller;
if (Purpose == SM_RENDER) {
pDevice->SetTransform(D3DTS_VIEW, GameApp->m_camera.GetViewMatrix() );
GameApp->m_fps = GameApp->m_pFramework->GetFPS() + " fps";
pDevice->Clear(0,
0,
D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
D3DCOLOR_XRGB(0, 0, 0),
1.0f,
0);
pDevice->BeginScene();
GameApp->m_pBall->Render(pDevice);
GameApp->m_pWall->Render(pDevice);
// Display framerate and instructions
GameApp->m_pTextSprite->Begin(D3DXSPRITE_ALPHABLEND | D3DXSPRITE_SORT_TEXTURE);
GameApp->m_font.Print(GameApp->m_fps.c_str(), 5, 5, D3DCOLOR_XRGB(255, 0, 0), GameApp->m_pTextSprite);
GameApp->m_font.Print(g_instructions2.c_str(), 5, 20, D3DCOLOR_XRGB(200, 200, 200), GameApp->m_pTextSprite);
GameApp->m_pTextSprite->End();
pDevice->EndScene();
pDevice->Present(0, 0, 0, 0);
}
if (Purpose == SM_PROCESS) {
sUserInput Input = *( (psUserInput)DataPtr);
if (Input.pPressedKeys[DIK_F1] ) {
GameApp->m_pFramework->LockKey(DIK_F1);
GameApp->m_pFramework->ToggleFullscreen();
}
if (Input.pPressedKeys[DIK_ESCAPE] ) {
GameApp->m_pFramework->LockKey(DIK_ESCAPE);
GameApp->m_StateManager.Pop();
}
}
return;
}
And here is how it is being used...
Code:
void CGameApp::OnCreateDevice(LPDIRECT3DDEVICE9 pDevice) {
m_StateManager.Push(GameStart);
....
}
void CGameApp::OnRenderFrame(LPDIRECT3DDEVICE9 pDevice, float ElapsedTime) {
m_StateManager.Process(pDevice, this, SM_RENDER);
return;
}
void CGameApp::ProcessInput(LPDIRECT3DDEVICE9 pDevice,
long xDelta,
long yDelta,
long zDelta,
bool* pMouseButtons,
bool* pPressedKeys,
float ElapsedTime) {
sUserInput Input = { xDelta, yDelta, zDelta, pMouseButtons, pPressedKeys };
m_StateManager.Process(pDevice, this, SM_PROCESS, (void*)&Input);
return;
}
I think I have all the relavent code listed, but if there is anything else you need please ask and I will post some more.
I'm not sure why this is not working, any ideas?