Skip to main content
GameDev.net gamedev.net
🔒 Locked

Problem with buffered input with DirectInput wrapper.

Started by nickolay00 Nov 17, 2004 at 7:32 PM 8 replies 1k views
Original Post
nickolay00
nickolay00
I'm currently working on a project which involves making a wrapper for DirectInput. I've done so, but am having trouble getting the buffered input aspect of it working properly. Note that this is intended to be in a dll running in a game. I am attempting to inject input directly into this game from the dll. Can somebody please assist me? Thanks. Here are parts of the code: This class inherits from another, empty, wrapper. class KeyboardWrapper : public DirectInputDevice8AWrapper { public: KeyboardWrapper(IDirectInputDevice8A *pDirectInputDevice8A, DWORD CoopLevel); //virtual ~KeyboardWrapper(void); STDMETHOD(GetDeviceData)(THIS_ DWORD,LPDIDEVICEOBJECTDATA,LPDWORD,DWORD); STDMETHOD(GetDeviceState)(THIS_ DWORD,LPVOID); STDMETHOD(SetCooperativeLevel)(THIS_ HWND,DWORD); void SetKey(BYTE key, bool down); void SetKeyState(BYTE key, bool down); void InjectData(DIDEVICEOBJECTDATA data); void SetBlockInput(bool block); bool BlockInput; BYTE KeyState[256]; HWND Parent; DWORD Sequence; }; The following is from the KeyboardWRapper.cpp file: std::queue InjectedData; void KeyboardWrapper::SetKey(BYTE key, bool down) { InjectData(CreateKeyboardData(key, down)); SetKeyState(key, down); } void KeyboardWrapper::SetKeyState(BYTE key, bool down) { if(down) this->KeyState[key] = 0x80; else this->KeyState[key] = 0x00; } HRESULT KeyboardWrapper::GetDeviceData(THIS_ DWORD dword1, LPDIDEVICEOBJECTDATA lpdideviceobjectdata, LPDWORD lpdword, DWORD dword2) { //InjectData(CreateKeyboardData(DIK_A, true)); //InjectData(CreateKeyboardData(DIK_A, false)); //OutputDebugString("Keyboard - GetDeviceData"); bool block = false; if(GetForegroundWindowNext() != Parent || this->BlockInput) { block = true; } if(debugged == true) { } DWORD max = *lpdword; HRESULT result = this->DirectInputDevice8A->GetDeviceData(dword1, lpdideviceobjectdata, lpdword, dword2); if(*lpdword > 0) { if(lpdideviceobjectdata != NULL) { this->Sequence = lpdideviceobjectdata[*lpdword].dwSequence + 1; } } if(block) { *lpdword = 0; } else { *lpdword++; } if(lpdideviceobjectdata == NULL) return result; while(*lpdword < max && !InjectedData.empty()) { lpdideviceobjectdata[*lpdword] = InjectedData.back(); InjectedData.pop(); lpdideviceobjectdata[*lpdword].dwSequence = this->Sequence; this->Sequence++; *lpdword++; } return result; }
Dave Hunt
Dave Hunt
Could you be more specific as to your problem? "having trouble getting the buffered input aspect of it working properly" is just a bit vague.
nickolay00
nickolay00
Upon calling SetKey(), nothing happens. After meticulously debugging the code, I have not been able to find any bugs which would prevent it from working properly. Stepping through GetDeviceData shows expected behavior, but no expected results.
Dave Hunt
Dave Hunt
You say that SetKey does nothing. SetKey calls InjectData() and CreateKeyboardData(key, down), but I don't see those methods. It may be that SetKey does nothing because one of those methods isn't doing what you want it to.
nickolay00
nickolay00
Quote:
Original post by Dave Hunt
You say that SetKey does nothing. SetKey calls InjectData() and CreateKeyboardData(key, down), but I don't see those methods. It may be that SetKey does nothing because one of those methods isn't doing what you want it to.



Sorry about that. I should have posted the entire file instead.



void KeyboardWrapper::SetKeyState(BYTE key, bool down)
{
if(down)
this->KeyState[key] = 0x80;
else
this->KeyState[key] = 0x00;
}


void KeyboardWrapper::InjectData(DIDEVICEOBJECTDATA data)
{
this->InjectedData.push(data);
}

DIDEVICEOBJECTDATA CreateKeyboardData(DWORD key, bool down)
{
DIDEVICEOBJECTDATA data;
data.dwOfs = key;
if(down)
data.dwData = 0x80;
else
data.dwData = 0x00;
data.dwSequence = 0;
data.dwTimeStamp = GetTickCount();
data.uAppData = 0;
return data;
}



[Edited by - nickolay00 on November 18, 2004 2:20:32 PM]
Dave Hunt
Dave Hunt
Here are some things I noticed:

1. You don't check the return value from the IDirectInputDevice8A::GetDeviceData() call. (This won't affect your injected data, but is something you might want to consider doing.)

2. After the call to IDirectInputDevice8A::GetDeviceData(), lpdword will contain the number of elements retrieved. If lpdideviceobjectdata is not null, you then set Sequence based on the dwSequence at the index indicated by lpdword. However, since lpdword is the number of elements retrieved, you are indexing one beyond the last element retreived.

3. You then increment lpdword if block is false. Then you proceed to stuff any injected data into lpdideviceobjectdata beginning at this incremented index. However, by incrementing lpdword, you have now skipped a slot.

You might want to try stepping that code through the debugger again.
nickolay00
nickolay00
Thank you for catching those bugs. As you can see, I'm still a novice at this. Hopefully, it will work one I get a chance to test it tomorrow.
Dave Hunt
Dave Hunt
Glad to help. Good luck with your project.

Topic Locked

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

Sign in to reply to this topic.