From 4c596dcf0d294930ba174a657905804d7a237b93 Mon Sep 17 00:00:00 2001 From: Robert Beckebans Date: Thu, 5 Feb 2015 20:11:09 +0100 Subject: [PATCH] Fixed Gamepad LS and RS in PDA screen. refs #214 --- neo/sys/sdl/sdl_events.cpp | 380 +++++++++++++++++++++++-------------- 1 file changed, 237 insertions(+), 143 deletions(-) diff --git a/neo/sys/sdl/sdl_events.cpp b/neo/sys/sdl/sdl_events.cpp index 2dacbb4e..f5793d06 100644 --- a/neo/sys/sdl/sdl_events.cpp +++ b/neo/sys/sdl/sdl_events.cpp @@ -134,6 +134,7 @@ struct joystick_poll_t static idList joystick_polls; SDL_Joystick* joy = NULL; int SDL_joystick_has_hat = 0; +bool buttonStates[K_LAST_KEY]; // For keeping track of button up/down events #if SDL_VERSION_ATLEAST(2, 0, 0) @@ -164,39 +165,39 @@ static SDL_Scancode KeyNumToSDLScanCode( int keyNum ) } // both strings are expected to have at most SDL_TEXTINPUTEVENT_TEXT_SIZE chars/ints (including terminating null) -static void ConvertUTF8toUTF32(const char* utf8str, int32* utf32buf) +static void ConvertUTF8toUTF32( const char* utf8str, int32* utf32buf ) { - static SDL_iconv_t cd = SDL_iconv_t(-1); - - if( cd == SDL_iconv_t(-1) ) + static SDL_iconv_t cd = SDL_iconv_t( -1 ); + + if( cd == SDL_iconv_t( -1 ) ) { const char* toFormat = "UTF-32LE"; // TODO: what does d3bfg expect on big endian machines? - cd = SDL_iconv_open(toFormat, "UTF-8"); - if( cd == SDL_iconv_t(-1) ) + cd = SDL_iconv_open( toFormat, "UTF-8" ); + if( cd == SDL_iconv_t( -1 ) ) { - common->Warning("Couldn't initialize SDL_iconv for UTF-8 to UTF-32!"); // TODO: or error? + common->Warning( "Couldn't initialize SDL_iconv for UTF-8 to UTF-32!" ); // TODO: or error? return; } } - - size_t len = strlen(utf8str); - + + size_t len = strlen( utf8str ); + size_t inbytesleft = len; size_t outbytesleft = 4 * SDL_TEXTINPUTEVENT_TEXT_SIZE; // *4 because utf-32 needs 4x as much space as utf-8 - char* outbuf = (char*)utf32buf; - size_t n = SDL_iconv(cd, &utf8str, &inbytesleft, &outbuf, &outbytesleft); - - if( n == size_t(-1) ) // some error occured during iconv + char* outbuf = ( char* )utf32buf; + size_t n = SDL_iconv( cd, &utf8str, &inbytesleft, &outbuf, &outbytesleft ); + + if( n == size_t( -1 ) ) // some error occured during iconv { - common->Warning("Converting UTF-8 string \"%s\" from SDL_TEXTINPUT to UTF-32 failed!", utf8str); - + common->Warning( "Converting UTF-8 string \"%s\" from SDL_TEXTINPUT to UTF-32 failed!", utf8str ); + // clear utf32-buffer, just to be sure there's no garbage.. - memset(utf32buf, 0, SDL_TEXTINPUTEVENT_TEXT_SIZE*sizeof(int32)); + memset( utf32buf, 0, SDL_TEXTINPUTEVENT_TEXT_SIZE * sizeof( int32 ) ); } - + // reset cd so it can be used again - SDL_iconv(cd, NULL, &inbytesleft, NULL, &outbytesleft); - + SDL_iconv( cd, NULL, &inbytesleft, NULL, &outbytesleft ); + } #else // SDL1.2 @@ -218,22 +219,22 @@ static int SDL_KeyToDoom3Key( SDL_Keycode key, bool& isChar ) case SDLK_SPACE: return K_SPACE; - //case SDLK_EXCLAIM: - /* - SDLK_QUOTEDBL: - SDLK_HASH: - SDLK_DOLLAR: - SDLK_AMPERSAND: - SDLK_QUOTE = 39, - SDLK_LEFTPAREN = 40, - SDLK_RIGHTPAREN = 41, - SDLK_ASTERISK = 42, - SDLK_PLUS = 43, - SDLK_COMMA = 44, - SDLK_MINUS = 45, - SDLK_PERIOD = 46, - SDLK_SLASH = 47, - */ + //case SDLK_EXCLAIM: + /* + SDLK_QUOTEDBL: + SDLK_HASH: + SDLK_DOLLAR: + SDLK_AMPERSAND: + SDLK_QUOTE = 39, + SDLK_LEFTPAREN = 40, + SDLK_RIGHTPAREN = 41, + SDLK_ASTERISK = 42, + SDLK_PLUS = 43, + SDLK_COMMA = 44, + SDLK_MINUS = 45, + SDLK_PERIOD = 46, + SDLK_SLASH = 47, + */ case SDLK_0: return K_0; @@ -264,7 +265,7 @@ static int SDL_KeyToDoom3Key( SDL_Keycode key, bool& isChar ) case SDLK_9: return K_9; - // DG: add some missing keys.. + // DG: add some missing keys.. case SDLK_UNDERSCORE: return K_UNDERLINE; @@ -288,28 +289,28 @@ static int SDL_KeyToDoom3Key( SDL_Keycode key, bool& isChar ) case SDLK_EQUALS: return K_EQUALS; - // DG end + // DG end - /* - SDLK_COLON = 58, - SDLK_SEMICOLON = 59, - SDLK_LESS = 60, - SDLK_EQUALS = 61, - SDLK_GREATER = 62, - SDLK_QUESTION = 63, - SDLK_AT = 64, - */ - /* - Skip uppercase letters - */ - /* - SDLK_LEFTBRACKET = 91, - SDLK_BACKSLASH = 92, - SDLK_RIGHTBRACKET = 93, - SDLK_CARET = 94, - SDLK_UNDERSCORE = 95, - SDLK_BACKQUOTE = 96, - */ + /* + SDLK_COLON = 58, + SDLK_SEMICOLON = 59, + SDLK_LESS = 60, + SDLK_EQUALS = 61, + SDLK_GREATER = 62, + SDLK_QUESTION = 63, + SDLK_AT = 64, + */ + /* + Skip uppercase letters + */ + /* + SDLK_LEFTBRACKET = 91, + SDLK_BACKSLASH = 92, + SDLK_RIGHTBRACKET = 93, + SDLK_CARET = 94, + SDLK_UNDERSCORE = 95, + SDLK_BACKQUOTE = 96, + */ case SDLK_a: return K_A; @@ -398,13 +399,13 @@ static int SDL_KeyToDoom3Key( SDL_Keycode key, bool& isChar ) case SDLK_PAUSE: return K_PAUSE; - // DG: add tab key support + // DG: add tab key support case SDLK_TAB: return K_TAB; - // DG end + // DG end - //case SDLK_APPLICATION: - // return K_COMMAND; + //case SDLK_APPLICATION: + // return K_COMMAND; case SDLK_CAPSLOCK: return K_CAPSLOCK; @@ -431,8 +432,8 @@ static int SDL_KeyToDoom3Key( SDL_Keycode key, bool& isChar ) case SDLK_RGUI: return K_RWIN; - //case SDLK_MENU: - // return K_MENU; + //case SDLK_MENU: + // return K_MENU; case SDLK_LALT: return K_LALT; @@ -505,7 +506,7 @@ static int SDL_KeyToDoom3Key( SDL_Keycode key, bool& isChar ) case SDLK_F12: return K_F12; - // K_INVERTED_EXCLAMATION; + // K_INVERTED_EXCLAMATION; case SDLK_F13: return K_F13; @@ -554,11 +555,11 @@ static int SDL_KeyToDoom3Key( SDL_Keycode key, bool& isChar ) case SDLK_KP_DIVIDE: return K_KP_SLASH; - // K_SUPERSCRIPT_TWO; + // K_SUPERSCRIPT_TWO; case SDLK_KP_MINUS: return K_KP_MINUS; - // K_ACUTE_ACCENT; + // K_ACUTE_ACCENT; case SDLK_KP_PLUS: return K_KP_PLUS; @@ -572,30 +573,30 @@ static int SDL_KeyToDoom3Key( SDL_Keycode key, bool& isChar ) case SDLK_KP_EQUALS: return K_KP_EQUALS; - // K_MASCULINE_ORDINATOR; - // K_GRAVE_A; - // K_AUX1; - // K_CEDILLA_C; - // K_GRAVE_E; - // K_AUX2; - // K_AUX3; - // K_AUX4; - // K_GRAVE_I; - // K_AUX5; - // K_AUX6; - // K_AUX7; - // K_AUX8; - // K_TILDE_N; - // K_GRAVE_O; - // K_AUX9; - // K_AUX10; - // K_AUX11; - // K_AUX12; - // K_AUX13; - // K_AUX14; - // K_GRAVE_U; - // K_AUX15; - // K_AUX16; + // K_MASCULINE_ORDINATOR; + // K_GRAVE_A; + // K_AUX1; + // K_CEDILLA_C; + // K_GRAVE_E; + // K_AUX2; + // K_AUX3; + // K_AUX4; + // K_GRAVE_I; + // K_AUX5; + // K_AUX6; + // K_AUX7; + // K_AUX8; + // K_TILDE_N; + // K_GRAVE_O; + // K_AUX9; + // K_AUX10; + // K_AUX11; + // K_AUX12; + // K_AUX13; + // K_AUX14; + // K_GRAVE_U; + // K_AUX15; + // K_AUX16; case SDLK_PRINTSCREEN: return K_PRINTSCREEN; @@ -627,6 +628,8 @@ static void PushConsoleEvent( const char* s ) SDL_PushEvent( &event ); } + + /* ================= Sys_InitInput @@ -639,6 +642,8 @@ void Sys_InitInput() kbd_polls.SetGranularity( 64 ); mouse_polls.SetGranularity( 64 ); + memset( buttonStates, 0, sizeof( buttonStates ) ); + #if !SDL_VERSION_ATLEAST(2, 0, 0) SDL_EnableUNICODE( 1 ); SDL_EnableKeyRepeat( SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL ); @@ -710,6 +715,8 @@ void Sys_ShutdownInput() mouse_polls.Clear(); joystick_polls.Clear(); + memset( buttonStates, 0, sizeof( buttonStates ) ); + // Close any opened SDL Joystic if( joy ) { @@ -828,7 +835,7 @@ Sys_GetEvent sysEvent_t Sys_GetEvent() { sysEvent_t res = { }; - + SDL_Event ev; int key; @@ -842,23 +849,23 @@ sysEvent_t Sys_GetEvent() // utf-32 version of the textinput event static int32 uniStr[SDL_TEXTINPUTEVENT_TEXT_SIZE] = {0}; static size_t uniStrPos = 0; - - if(uniStr[0] != 0) + + if( uniStr[0] != 0 ) { res.evType = SE_CHAR; res.evValue = uniStr[uniStrPos]; - + ++uniStrPos; - + if( !uniStr[uniStrPos] || uniStrPos == SDL_TEXTINPUTEVENT_TEXT_SIZE ) { - memset(uniStr, 0, sizeof(uniStr)); + memset( uniStr, 0, sizeof( uniStr ) ); uniStrPos = 0; } - + return res; } - + // DG: fake a "mousewheel not pressed anymore" event for SDL2 // so scrolling in menus stops after one step static int mwheelRel = 0; @@ -875,16 +882,16 @@ sysEvent_t Sys_GetEvent() static int32 uniChar = 0; - if(uniChar) + if( uniChar ) { res.evType = SE_CHAR; res.evValue = uniChar; - + uniChar = 0; - + return res; } - + // loop until there is an event we care about (will return then) or no more events while( SDL_PollEvent( &ev ) ) { @@ -917,13 +924,13 @@ sysEvent_t Sys_GetEvent() cvarSystem->SetCVarBool( "com_pause", true ); // DG end break; - + case SDL_WINDOWEVENT_LEAVE: // mouse has left the window res.evType = SE_MOUSE_LEAVE; return res; - // DG: handle resizing and moving of window + // DG: handle resizing and moving of window case SDL_WINDOWEVENT_RESIZED: { int w = ev.window.data1; @@ -969,14 +976,14 @@ sysEvent_t Sys_GetEvent() } cvarSystem->SetCVarBool( "com_pause", pause ); - + if( ev.active.state == SDL_APPMOUSEFOCUS && !ev.active.gain ) { // the mouse has left the window. res.evType = SE_MOUSE_LEAVE; return res; } - + } continue; // handle next event @@ -984,7 +991,7 @@ sysEvent_t Sys_GetEvent() case SDL_VIDEOEXPOSE: continue; // handle next event - // DG: handle resizing and moving of window + // DG: handle resizing and moving of window case SDL_VIDEORESIZE: { int w = ev.resize.w; @@ -994,7 +1001,7 @@ sysEvent_t Sys_GetEvent() glConfig.nativeScreenWidth = w; glConfig.nativeScreenHeight = h; - + // for some reason this needs a vid_restart in SDL1 but not SDL2 so GLimp_SetScreenParms() is called PushConsoleEvent( "vid_restart" ); continue; // handle next event @@ -1039,7 +1046,7 @@ sysEvent_t Sys_GetEvent() // DG end #endif // SDL 1.2 - // fall through + // fall through case SDL_KEYUP: { bool isChar; @@ -1077,19 +1084,19 @@ sysEvent_t Sys_GetEvent() } else { - if(uniChar) + if( uniChar ) { res.evType = SE_CHAR; res.evValue = uniChar; - + uniChar = 0; - + return res; } if( ev.type == SDL_KEYDOWN ) // FIXME: don't complain if this was an ASCII char and the console is open? common->Warning( "unmapped SDL key %d (0x%x) scancode %d", ev.key.keysym.sym, ev.key.keysym.unicode, ev.key.keysym.scancode ); - + continue; // just handle next event } } @@ -1113,7 +1120,7 @@ sysEvent_t Sys_GetEvent() if( ev.text.text[0] != '\0' ) { // fill uniStr array for SE_CHAR events - ConvertUTF8toUTF32(ev.text.text, uniStr); + ConvertUTF8toUTF32( ev.text.text, uniStr ); // return an event with the first/only char res.evType = SE_CHAR; @@ -1121,7 +1128,7 @@ sysEvent_t Sys_GetEvent() uniStrPos = 1; - if( uniStr[1] == 0) + if( uniStr[1] == 0 ) { // it's just this one character, clear uniStr uniStr[0] = 0; @@ -1164,11 +1171,11 @@ sysEvent_t Sys_GetEvent() case SDL_MOUSEWHEEL: res.evType = SE_KEY; - res.evValue = (ev.wheel.y > 0) ? K_MWHEELUP : K_MWHEELDOWN; + res.evValue = ( ev.wheel.y > 0 ) ? K_MWHEELUP : K_MWHEELDOWN; mouse_polls.Append( mouse_poll_t( M_DELTAZ, ev.wheel.y ) ); - + res.evValue2 = 1; // for "pressed" - + // remember mousewheel direction to issue a "not pressed anymore" event mwheelRel = res.evValue; @@ -1206,7 +1213,7 @@ sysEvent_t Sys_GetEvent() mouse_polls.Append( mouse_poll_t( M_DELTAZ, -1 ) ); break; #endif // SDL1.2 - + default: // handle X1 button and above if( ev.button.button <= 16 ) // d3bfg doesn't support more than 16 mouse buttons @@ -1225,12 +1232,12 @@ sysEvent_t Sys_GetEvent() return res; - // WM0110 - // NOTE: it seems that the key bindings for the GUI and for the game are - // totally independant. I think the event returned by this function seems to work - // on the GUI and the event returned by Sys_ReturnJoystickInputEvent() works on - // the game. - // Also, remember that joystick keys must be binded to actions in order to work! + // WM0110 + // NOTE: it seems that the key bindings for the GUI and for the game are + // totally independant. I think the event returned by this function seems to work + // on the GUI and the event returned by Sys_ReturnJoystickInputEvent() works on + // the game. + // Also, remember that joystick keys must be binded to actions in order to work! case SDL_JOYBUTTONDOWN: case SDL_JOYBUTTONUP: // sys_public.h: evValue is an axis number and evValue2 is the current state (-127 to 127) @@ -1293,7 +1300,7 @@ sysEvent_t Sys_GetEvent() joystick_polls.Append( joystick_poll_t( J_ACTION11, ev.jbutton.state == SDL_PRESSED ? 1 : 0 ) ); break; - // D-PAD left (XBox 360 wireless) + // D-PAD left (XBox 360 wireless) case 11: // If joystick has a hat, then use the hat as D-PAD. If not, D-PAD is mapped // to buttons. @@ -1309,7 +1316,7 @@ sysEvent_t Sys_GetEvent() } break; - // D-PAD right + // D-PAD right case 12: if( SDL_joystick_has_hat ) { @@ -1323,7 +1330,7 @@ sysEvent_t Sys_GetEvent() } break; - // D-PAD up + // D-PAD up case 13: if( SDL_joystick_has_hat ) { @@ -1337,7 +1344,7 @@ sysEvent_t Sys_GetEvent() } break; - // D-PAD down + // D-PAD down case 14: if( SDL_joystick_has_hat ) { @@ -1448,47 +1455,134 @@ sysEvent_t Sys_GetEvent() // in void idUsercmdGenLocal::Joystick( int deviceNum ). switch( ev.jaxis.axis ) { - int trigger_value; + //const int range = 16384; + int triggerValue; + bool triggered; + int percent; + int axis; - // LEFT trigger + // LEFT trigger case 2: // Convert TRIGGER value from space (-32768, 32767) to (0, 32767) - trigger_value = ( ev.jaxis.value + 32768 ) / 2; + triggerValue = ( ev.jaxis.value + 32768 ) / 2; // common->Printf("Sys_GetEvent: LEFT trigger value = %i / converted value = %i\n", ev.jaxis.value, trigger_value); res.evValue = J_AXIS_LEFT_TRIG; - joystick_polls.Append( joystick_poll_t( J_AXIS_LEFT_TRIG, trigger_value ) ); + + joystick_polls.Append( joystick_poll_t( J_AXIS_LEFT_TRIG, triggerValue ) ); break; - // Right trigger + // Right trigger case 5: - trigger_value = ( ev.jaxis.value + 32768 ) / 2; + triggerValue = ( ev.jaxis.value + 32768 ) / 2; // common->Printf("Sys_GetEvent: RIGHT trigger value = %i / converted value = %i\n", ev.jaxis.value, trigger_value); res.evValue = J_AXIS_RIGHT_TRIG; - joystick_polls.Append( joystick_poll_t( J_AXIS_RIGHT_TRIG, trigger_value ) ); + + joystick_polls.Append( joystick_poll_t( J_AXIS_RIGHT_TRIG, triggerValue ) ); break; - // LEFT X + // LEFT X case 0: res.evValue = J_AXIS_LEFT_X; joystick_polls.Append( joystick_poll_t( J_AXIS_LEFT_X, ev.jaxis.value ) ); + + triggered = ( ev.jaxis.value > 16384 ); + if( buttonStates[K_JOY_STICK1_RIGHT] != triggered ) + { + buttonStates[K_JOY_STICK1_RIGHT] = triggered; + + res.evType = SE_KEY; + res.evValue = K_JOY_STICK1_RIGHT; + res.evValue2 = triggered; + } + + triggered = ( ev.jaxis.value < -16384 ); + if( buttonStates[K_JOY_STICK1_LEFT] != triggered ) + { + buttonStates[K_JOY_STICK1_LEFT] = triggered; + + res.evType = SE_KEY; + res.evValue = K_JOY_STICK1_LEFT; + res.evValue2 = triggered; + } break; - // LEFT Y + // LEFT Y case 1: res.evValue = J_AXIS_LEFT_Y; joystick_polls.Append( joystick_poll_t( J_AXIS_LEFT_Y, ev.jaxis.value ) ); + + triggered = ( ev.jaxis.value > 16384 ); + if( buttonStates[K_JOY_STICK1_DOWN] != triggered ) + { + buttonStates[K_JOY_STICK1_DOWN] = triggered; + + res.evType = SE_KEY; + res.evValue = K_JOY_STICK1_DOWN; + res.evValue2 = triggered; + } + + triggered = ( ev.jaxis.value < -16384 ); + if( buttonStates[K_JOY_STICK1_UP] != triggered ) + { + buttonStates[K_JOY_STICK1_UP] = triggered; + + res.evType = SE_KEY; + res.evValue = K_JOY_STICK1_UP; + res.evValue2 = triggered; + } + break; - // RIGHT X + // RIGHT X case 3: res.evValue = J_AXIS_RIGHT_X; joystick_polls.Append( joystick_poll_t( J_AXIS_RIGHT_X, ev.jaxis.value ) ); + + triggered = ( ev.jaxis.value > 16384 ); + if( buttonStates[K_JOY_STICK2_RIGHT] != triggered ) + { + buttonStates[K_JOY_STICK2_RIGHT] = triggered; + + res.evType = SE_KEY; + res.evValue = K_JOY_STICK2_RIGHT; + res.evValue2 = triggered; + } + + triggered = ( ev.jaxis.value < -16384 ); + if( buttonStates[K_JOY_STICK2_LEFT] != triggered ) + { + buttonStates[K_JOY_STICK2_LEFT] = triggered; + + res.evType = SE_KEY; + res.evValue = K_JOY_STICK2_LEFT; + res.evValue2 = triggered; + } break; - // RIGHT Y + // RIGHT Y case 4: res.evValue = J_AXIS_RIGHT_Y; joystick_polls.Append( joystick_poll_t( J_AXIS_RIGHT_Y, ev.jaxis.value ) ); + + triggered = ( ev.jaxis.value > 16384 ); + if( buttonStates[K_JOY_STICK2_DOWN] != triggered ) + { + buttonStates[K_JOY_STICK2_DOWN] = triggered; + + res.evType = SE_KEY; + res.evValue = K_JOY_STICK2_DOWN; + res.evValue2 = triggered; + } + + triggered = ( ev.jaxis.value < -16384 ); + if( buttonStates[K_JOY_STICK2_UP] != triggered ) + { + buttonStates[K_JOY_STICK2_UP] = triggered; + + res.evType = SE_KEY; + res.evValue = K_JOY_STICK2_UP; + res.evValue2 = triggered; + } break; default: @@ -1497,8 +1591,8 @@ sysEvent_t Sys_GetEvent() } return res; - // WM0110 - + // WM0110 + case SDL_QUIT: PushConsoleEvent( "quit" ); res = no_more_events; // don't handle next event, just quit.