Skip to main content
gamedev.net
🔒 Locked

[solved]

Started by Holland Apr 2, 2009 at 4:06 PM 6 replies 3k views
Original Post
Holland
Holland
I have xinput working fine unbuffered...obviously...it's a peice of cake. I figured buffered input would be equally easy, but for some reason I can't get it to work. I have 2 variables for states. XINPUT_STATE m_xState and m_xBufferedState first I have the following two variables:

private:
    XINPUT_STATE m_xState;
    XINPUT_STATE m_xBufferedState;
Every single frame I'm doing this code:

bool PollXInput(void){
    DWORD result;
    ZeroMemory(&m_xState, sizeof(XINPUT_STATE));
    result = XInputGetState(0, &m_xState);
    if(result != ERROR_SUCCESS)
        return false;
    return true;
}
And then I have the function GetXButton(unsigned char _xButton):

bool GetXButton(unsigned char _xButton){
    return (m_xState.Gamepad.wButtons & _xButton);
}
this all works fine and dandy...but here's what i'm attempting to do for buffered input:

bool GetBufferedXButton(unsigned char _xButton){
    bool bTemp = GetXButton(_xButton);
    if(bTemp) return false;
    // at this point we know _xButton wasn't down already.
    DWORD result;
    ZeroMemory(&m_xBufferedState, sizeof(XINPUT_STATE));
    result = XInputGetState(0, &m_xBufferedState);
    if (result == ERROR_SUCCESS){
        return (m_xBufferedState.Gamepad.wButtons & _xButton);
    }
    return false;
}
When I debug through, it manages to go as far as result = XInputGetState(0, &m_xBufferedState); inside of GetBufferedXButton(uchar) but regardless of what is pressed down, it returns a state that has nothing pressed down. Even when the normal m_xState shows the correct button(s) being pressed, m_xBufferedState shows nothing. Is there something I'm missing? Or something I'm unaware of that XInputGetState() does? [edit]: I did this all by heart (the code isn't really that complicated..) so I may have made some typos or something. :) Thanks for the help! Hopefully I provided enough information. And yeah, I'm passing 0 into all of the functions because it's for a single player game. :) Thanks everyone. [Edited by - Holland on April 3, 2009 4:39:20 PM]
Holland
Holland
bump for day2...plus an update

UNSOLVED!! So I edited too soon. I found that using the VK code's with XINPUT_KEYSTROKE_KEYDOWN works great for buffered, but not for unbuffered. I need a uniform way to do both. I either need to use VK codes or XINPUT_GAMEPAD codes, but the way my system is now can't support both.

Perhaps is there some sort of function to go from VK to XINPUT. Sort of like MapVirtualKeyEx() and ToAsciiEx() are for DIK to VK and VK to Ascii.


I've attempted to use the XInputGetKeystroke() function instead, since it has information pertaining to if the button was pushed, released, or held down. This isn't even working. Here is the code I'm trying for that.

bool ReadXInput(void){	DWORD dwResult;	ZeroMemory(&m_xState, sizeof(XINPUT_KEYSTROKE));	dwResult = XInputGetKeystroke(0, XINPUT_FLAG_GAMEPAD, &m_xState);	if (dwResult == ERROR_SUCCESS)		return true;	return false;}bool GetBufferedXboxButton(BYTE xButton, int nNum){	if (m_xState.UserIndex == 0)	{		if (m_xState.VirtualKey == xButton)		{			if (m_xState.Flags & XINPUT_KEYSTROKE_KEYDOWN)				return true;		}	}	return false;}bool GetXboxButton(BYTE xButton, int nNum){	if (m_xState.UserIndex == 0)	{		if (m_xState.VirtualKey == xButton)		{			if (				(m_xState.Flags & XINPUT_KEYSTROKE_KEYDOWN)				|| (m_xState.Flags & XINPUT_KEYSTROKE_REPEAT)				)				return true;		}	}	return false;}


just like before, the ReadXInput() function is called per frame. The others are called perframe as well but only if needed. They are always returning false.

[Edited by - Holland on April 3, 2009 1:23:35 PM]
Rewdew
Rewdew
What are you trying to do exactly, know when a button changes state?
Holland
Holland
Quote:
Original post by Rewdew
What are you trying to do exactly, know when a button changes state?


Basically. For things like going through menus and such..I need to know only when the button has been pressed. Not held down or released or anything.

Got it working no problem using the same logic on the keyboard, using direct input, on the GBA, and DS. But somehow the same logic doesn't work for xinput.

I can get buffered input to work using XInputGetKeystroke, but that uses the VK values for the buttons (2 bytes). I can use XInputGetState to test of unbuffered input, but that uses XINPUT_GAMEPAD values (1 byte). I can use both, but I would really like a way to keep it uniform and use one or the other.

Even a function to convert from the VK_ value to the XINPUT_GAMEPAD_ value or vice-versa.

Rewdew, if you can help me with both problems in 1 day, beers are on me! :)

Thanks a lot.
Rewdew
Rewdew
Well I just store the last xinput info with something along those lines:

result = XInputGetState( xx, &state );...if (state.dwPacketNumber != previousstate.dwPacketNumber){    /* here compare state.Gamepad.wButtons & whatever with previousstate.Gamepad.wButtons & whatever */    if (different)    {       if (nowdown)          on_gamepad_down( xx, button );       else          on_gamepad_release( xx, button ); // this is your "button press"    }    ...    previousstate = state;}

That's a simplified version but you should get the idea... the only additional thing I do is check if a button still has a state down and keep sending "on_gamepad_pressed" for each frame... As for the translation, I suppose the closest I have is this, and loop on xinputbuttonmasks to get each button:

WORD const _xinputbuttonmasks[] ={	0x1000,	0x2000,	0x4000,	0x8000,	0x10,	0x20,	0x40,	0x80,	0x100,	0x200};gamepad_button::type const _xinputbuttontypes[] ={	gamepad_button::a,	gamepad_button::b,	gamepad_button::x,	gamepad_button::y,	gamepad_button::start,	gamepad_button::back,	gamepad_button::left_thumb,	gamepad_button::right_thumb,	gamepad_button::left_shoulder,	gamepad_button::right_shoulder};
Holland
Holland
Yeah..I ended up making a function that uses two arrays like you set up to make it work. Once I got done with that it dawned on me that I was being foolish. All I really needed was this.
XINPUT_STATE xCurrentState;XINPUT_STATE xPreviousState;bool ReadXInput(){    xPreviousState = xCurrentState;    // get current state here}


Working overtime for too many days causes the brain to malfunction. hahaha
FeverGames
FeverGames
This is just an idea

but maybe you should instead of removing thewhole title and making it "[solved]" combine both so that the search engine is helped as well, just as you are at this point.
Rewdew
Rewdew
Also, does that mean I get no beer? :'(

Topic Locked

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

Sign in to reply to this topic.