• Advertisement
Sign in to follow this  

Strange DInput error

This topic is 4837 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

That error was discovered while switching (alttabing) to and from my application (fullscreen directx), then after 1-5 switches application silently crashed to desktop. Using log and debugger I've located that error happened in the following code: DIDEVICEOBJECTDATA didod[DINPUT_BUFFERSIZE]; // Receives buffered data DWORD dwElements = 16; lpDIKeyboard->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), didod, &dwElements, 0 ); /*here are checks and acquiring*/ didod.dwData is OK, while didod[0].dwOfs == -858993460, that is FFFFFFFFCCCCCCCC in hex How should I eliminate that problem or at least skip it?

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by Archi

didod.dwData is OK, while
didod[0].dwOfs == -858993460, that is FFFFFFFFCCCCCCCC in hex


Quote:
Original post by Endurion
Shouldn't that be didod.dwOfs ?


Sure, I've miswrote. It was like that in the source
keybuffer[didod.dwOfs] = (didod.dwData & 0x80) ? 1 : 0;

didod.dwData is OK, while
didod.dwOfs == -858993460, that is FFFFFFFFCCCCCCCC in hex

Share this post


Link to post
Share on other sites
I never worked with buffered dinput, but i read into it a bit:

dwOfs may carry other values than the offset, depending on what device you use.

This is from the MSDN:

For IDirectInputDevice8::GetDeviceData, the offset into the current data format of the object whose data is being reported; that is, the location in which the dwData would have been stored if the data had been obtained by a call to the IDirectInputDevice8::GetDeviceState method. If the device is accessed as a mouse, keyboard, or joystick, the dwOfs member is one of the mouse device constants, keyboard device constants, or joystick device constants. If a custom data format has been set, it is an offset relative to the custom data format.
This member can be ignored if Action Mapping is being used. Instead, retrieve the action value from uAppData.


Maybe one of those is the cause?

Also, did you check the return value? Maybe the GetDeviceData fails for some reason?

Share this post


Link to post
Share on other sites
Quote:
Original post by Endurion
Also, did you check the return value? Maybe the GetDeviceData fails for some reason?


Don't think so. Here's the code (sorry, not formatted):


//------------------------------------------------------------------//
//- void diKeyboardProcess() -//
//------------------------------------------------------------------//
//- Description: This function processes the keyboard, by polling -//
//- it to make sure that it is still working fine. -//
//- A call to this function should be put at the start-//
//- of your main game loop, so it will get executed -//
//- everytime. -//
//------------------------------------------------------------------//
//- Sample use: -//
//- diKeyboardProcess(); -//
//------------------------------------------------------------------//
void diKeyboardProcess()
{
#ifdef _DEBUG
LogFile->Print("test A\n");
#endif

HRESULT result;
DIDEVICEOBJECTDATA didod[DINPUT_BUFFERSIZE]; // Receives buffered data
DWORD dwElements;

#ifdef _DEBUG
LogFile->Print("test B\n");
#endif

dwElements = DINPUT_BUFFERSIZE;
result = lpDIKeyboard->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), didod, &dwElements, 0 );
if (result != DI_OK)
{
#ifdef _DEBUG
LogFile->Print("test C\n");
#endif
// We got an error or we got DI_BUFFEROVERFLOW.
//
// Either way, it means that continuous contact with the
// device has been lost, either due to an external
// interruption, or because the buffer overflowed
// and some events were lost.
//
// Consequently, if a button was pressed at the time
// the buffer overflowed or the connection was broken,
// the corresponding "up" message might have been lost.
//
// But since our simple sample doesn't actually have
// any state associated with button up or down events,
// there is no state to reset. (In a real game, ignoring
// the buffer overflow would result in the game thinking
// a key was held down when in fact it isn't; it's just
// that the "up" event got lost because the buffer
// overflowed.)
//
// If we want to be cleverer, we could do a
// GetDeviceState() and compare the current state
// against the state we think the device is in,
// and process all the states that are currently
// different from our private state.
result = lpDIKeyboard->Acquire();
if (result != DI_OK)
{
#ifdef _DEBUG
LogFile->Print("test D\n");
#endif
#ifdef _DEBUG
LogFile->Print(GetDIErrorString(result));
#endif
}
}

#ifdef _DEBUG
LogFile->Print("test E\n");
#endif
// Clear keyboard state
diKeyboardClear();

#ifdef _DEBUG
LogFile->Print("test F\n");
#endif
// Study each of the buffer elements and process them.
for (unsigned char i = 0; i < dwElements; i++)
{
#ifdef _DEBUG
LogFile->Print("test = %d %d %d\n", i, didod.dwOfs, (didod.dwData & 0x80) ? 1 : 0);
#endif
if (didod.dwOfs<0)
return;
keybuffer[didod.dwOfs] = (didod.dwData & 0x80) ? 1 : 0;
}

#ifdef _DEBUG
LogFile->Print("test G\n");
#endif
}



and the log:

test A
test B
test C
test E
test F
test = 0 -858993460 1

Edited by Coder: Use [source][/source] tags.

[Edited by - Coder on October 24, 2004 1:45:57 PM]

Share this post


Link to post
Share on other sites
While Alt-Tabbing, you may have "lost" your device, you need to check for that possibility, and reacquire it.

Share this post


Link to post
Share on other sites
Quote:
Original post by Prozak
While Alt-Tabbing, you may have "lost" your device, you need to check for that possibility, and reacquire it.


See my post above. Judging by the log, reacquiring is succeseful

Share this post


Link to post
Share on other sites
2Coder: Thanks for editing tags, still can't get acquired to them ;)

2All: Any other suggestions? I don't like the thought about getting bunch of bugreports about that problem in a couple of days.

Share this post


Link to post
Share on other sites
The call to GetDeviceData() failed. That's why you see "test C" in the log. You did the right thing after that by calling Acquire(), but after that you started to read didod, even when GetDeviceData() failed and did not fill the buffer.

Share this post


Link to post
Share on other sites
Quote:
Original post by jacklin
The call to GetDeviceData() failed. That's why you see "test C" in the log. You did the right thing after that by calling Acquire(), but after that you started to read didod, even when GetDeviceData() failed and did not fill the buffer.


That sounds reasonable, I shall make some corrections later. Great thanks for brief but complete explanation.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement