Skip to main content
gamedev.net
🔒 Locked

Direct Input problem

Started by PsychoDude 5 replies 2.6k views
Original Post
PsychoDude
PsychoDude
I have tried several direct input resources to try to create direct input working within my own project. But I just can't seem to get it to work and I don't know what I'm doing wrong. The first part of the code I have this: bool initDirectInput() { if(FAILED(DirectInput8Create(_pGame->GetInstance(), DIRECTINPUT_VERSION, IID_IDirectInput8, (void **)&pDI, NULL))) { // error - unable to obtiain DirectInput interface return false; } if(FAILED(pDI->CreateDevice(GUID_SysKeyboard,&pKeyboard,NULL))) return false; if (FAILED(pKeyboard->SetDataFormat(&c_dfDIKeyboard))) return false; if(FAILED(pKeyboard->SetCooperativeLevel(_pGame->GetWindow(), DISCL_FOREGROUND | DISCL_NONEXCLUSIVE))) return false; pKeyboard->Acquire(); return true; } But this all seems to work since it doesn't give me an error when it returns false, so I think it is ok. Now as second part in my HandleKeys function I got this piece of code: HRESULT hr; BYTE diks[256]; if( NULL == pKeyboard ) MessageBox(NULL, "No keyboard?", "ERROR", MB_OK); ZeroMemory( diks, sizeof(diks) ); if(FAILED(hr = pKeyboard->GetDeviceState(sizeof(diks[256]), diks))) { while(hr == DIERR_INPUTLOST) pKeyboard->Acquire(); if(hr == DIERR_OTHERAPPHASPRIO) MessageBox(NULL, "Other has priority", "ERROR", MB_OK); if(hr == DIERR_NOTACQUIRED) MessageBox(NULL, "Keyboard is not acquired", "ERROR", MB_OK); return false; } Here I am receiving the Keyboard is not acquired error. I don't know how to fix it though, have tried looking at multiple resources for several hours now but I just cant find what I'm missing or doing wrong.
Pipo DeClown
Pipo DeClown
pKeyboard->GetDeviceState(sizeof(diks[256]), diks);
This should be sizeof(char[256]) or just sizeof(diks).

[attention]sizeof(diks) is not a funny joke [grin]
PsychoDude
PsychoDude
Actually, taking out the second part results into this error:
Error 2 error C2660: 'IDirectInputDevice8A::GetDeviceState' : function does not take 1 arguments
Marlow Landscape
Marlow Landscape
Is this all the code?Because it is it looks like you forgot to create the DirectInput Object or well I am writing it in another way
"You have tried and failed miserably, the lesson is, never try"-Homer J. Simpson.
PsychoDude
PsychoDude
There's still the cleanup part and the declerations of the used variables, but that's it.
mumpo
mumpo
Note: The DirectInput specific issues I discuss below (items #2 and #3) assume version 8.1. I have been working on a powerful DI based system for some time, so I have tested the code I provide at the bottom of the post in a variety of situations. It works (baring errors introduced as a result of minor changes necessary to port the code to your setup, and assuming you integrate it properly).

You have several problems with this code block:
if(FAILED(hr = pKeyboard->GetDeviceState(sizeof(diks[256]), diks))){    while(hr == DIERR_INPUTLOST)        pKeyboard->Acquire();    if(hr == DIERR_OTHERAPPHASPRIO)        MessageBox(NULL, "Other has priority", "ERROR", MB_OK);    if(hr == DIERR_NOTACQUIRED)        MessageBox(NULL, "Keyboard is not acquired", "ERROR", MB_OK);    return false;}

1) As Pipo DeClown said, sizeof(diks[256]) is wrong. I believe that statment is equivalent to sizeof(BYTE). I would replace that piece of code with sizeof(BYTE)*256, but there are other valid ways of writing it. See Pipo DeClown's post.
2) while(hr == DIERR_INPUT_LOST) <- Don't do this! a) You are NOT updating hr in the loop, therefore even if Acquire() succeeds, your application will not know it and will keep on acquiring forever! b) If you use a while loop, your application cannot process ANYTHING until the keyboard is reacquired, nor will it update the screen. Instead, use if() and design your code to simply act like no keys were pressed that frame if GetDeviceState() fails. That way, your program will still try to reacquire the device every frame, but it will not be stuck in a tight loop where it cannot process other input or display output.
3) if(hr == DIERR_NOTACQUIRED)
MessageBox(NULL, "Keyboard is not acquired", "ERROR", MB_OK);
This piece is your main problem. DIERR_NOTACQUIRED does NOT mean that something is wrong. What it means is that for some reason, the keyboard is not acquired. That reason could be, and most likely is, that your window lost keyboard focus for a moment. If the error is DIERR_NOTACQUIRED, you should attempt to acquire the keyboard once and then move on, just like for DIERR_INPUTLOST.

Here is how I would suggest rewriting your code:
if(FAILED(hr = pKeyboard->GetDeviceState(sizeof(BYTE)*256, diks))){    memset(diks, 0, sizeof(BYTE)*256);  // this will make the buttons all appear to be up.  There is some other data stored in the diks array by GetDeviceState(), but I didn't have time to verify that it's default state is zero, so you might need to change this line if you want the other data to be valid to.    if(hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED)    {        pKeyboard->Acquire();    }    else    {        MessageBox(NULL, "Keyboard state could not be updated.", "ERROR", MB_OK);        return false;    }}// The rest of the function, presumably including a// return true; somewhere.


EDIT: Fixed some mistakes and added the memset() line.
PsychoDude
PsychoDude
Ok mumpo, thanks :). That got me past that problem ^_^.
Added a key function to test if it works:
if(KEYDOWN(diks,DIK_ESCAPE))
GameEnd();
It does something so the keyboard seems to be being handled kinda ok.

Now just getting an error when I press the escape key to quit the program (Unhandled exception at 0x0051cc40 in Example1.exe: 0xC0000005: Acces violation reading location 0xfeeeff12.). Now just gonna try to figure this out and hope I can create the esc button to do what I want :P.

Ok, nvm, just getting tired and forgot to post the PostQuitMessage, lol :P

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.