04.09 - Game States and Variable Scope

Started by
21 comments, last by Teej 22 years, 8 months ago
Got it!

I figured out my link problem.

I had this:
#ifndef GLOBALS_OWNERSHIP
extern
#endif

enum GameState {GS_INTRO, GS_GAME, GS_GAMEOVER};

struct
{
...
}G;

This is WRONG. The extern keyword evaluates (from the compilers point of view) as "extern enum GamesState" when what we really want is "extern struct..."

So I put the enum line above the #ifndef GLOBALS_OWNERSHIP line and now all is well.

Thanks,
videns
EZ
Advertisement
Hi, I''m having a bit of a problem with my code here.. I''m trying to make a simple starting screen before the game starts, the screen works but the program doesn''t respond to the keybord input.. here''s the code:

void Game_Main()
{

if (G.gameState == GS_INTRO)
{
HRESULT hRet;

EraseBackground();

DIPROPDWORD dipdw;
DIDEVICEOBJECTDATA ddod[10];
DWORD dwor = 10;

dipdw.diph.dwSize = sizeof(DIPROPDWORD);
dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
dipdw.diph.dwObj = 0;
dipdw.diph.dwHow = DIPH_DEVICE;
dipdw.dwData = 10;

G.lpDIKeyboard->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph);

while (hRet = G.lpDIKeyboard->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), ddod, &dwor, 0) == DIERR_INPUTLOST)
if (FAILED(hRet = G.lpDIKeyboard->Acquire())) break;

if (KEYDOWN(DIK_SPACE))
G.gameState = GS_GAME;

MB_ICONEXCLAMATION | MB_OK | MB_SYSTEMMODAL);

RECT rectSrc, rectDest;

rectSrc.left = 1;
rectSrc.top = 65;
rectSrc.right = rectSrc.left + STARTSC_WIDTH;
rectSrc.bottom = rectSrc.top + STARTSC_HEIGHT;

rectDest.left = SCREEN_WIDTH/2 - (STARTSC_WIDTH/2);
rectDest.top = SCREEN_HEIGHT/2 - (STARTSC_HEIGHT/2);
rectDest.right = rectDest.left + STARTSC_WIDTH;
rectDest.bottom = rectDest.top + STARTSC_HEIGHT;

G.lpDDSBack->Blt(&rectDest, G.lpDDSRes, &rectSrc, DDBLT_KEYSRC | DDBLT_WAIT, NULL);

G.lpDDSPrimary->Flip(NULL, 0);

}
else
{ //The normal game function should be here later
EraseBackground();
}
}

I guess it''s the DI stuff where something isn''t working, I''m not completly sure how buffered data works and so on.. Thank you for your help,

-Lord Maz-
-Lord Maz-
Lord Maz: Hmm, you seem to be mis-matching DirectInput styles. The two modes of gathering input are (1) buffered, and (2) immediate. You''re setting up a DIDEVICEOBJECTDATA array to recieve buffered data ''packets'', but then you''re checking for the SPACE bar as if you have immediate data:

if (KEYDOWN(DIK_SPACE))

The KEYDOWN() macro checks the KeyState array for which keys are currently pressed, and this array is populated by DirectInput when you call GetDeviceState() on the keyboard object.

First, I guess that you need to make a decision: buffered or immediate data. With buffered data, DirectX sends us packets for every key that''s pressed, and with immediate data, we get a snapshot of the state of each key on the keyboard. Of course, you should learn to use both, but currently we''re using immediate data in our first project, so you may want to follow along and get the hang of it first.

Like I''ve said, immediate data is the simpler method to implement. First, we create an array of 256 UCHARS (unsigned characters) in our G structure:

UCHAR KeyState[256];

Then, we initialize DirectInput just as it is in the BASECODE templates. When it''s time to gather input, we make the following call:
while (hRet = G.lpDIKeyboard->GetDeviceState(256, G.KeyState) == DIERR_INPUTLOST){    if (FAILED(hRet = G.lpDIKeyboard->Acquire())) break;} 

This fills in our KeyState array. Now, you can go ahead and check for keys being down with the KEYDOWN() macro.

Always remember that the DirectX SDK has very decent documentation on using DirectX components, so you should take a trip there when you have a moment to spare. Also, BASECODE templates have working immediate data code.

Hope that helps,

Teej



This topic is closed to new replies.

Advertisement