From 6d6433422bf818259316c1baf0c24a72ab4da7b2 Mon Sep 17 00:00:00 2001 From: Fabian Greffrath Date: Thu, 9 Jan 2020 21:34:30 +0100 Subject: [PATCH] improve joystick handling code (#26) again, using code adapted from Chocolate Doom. While at it, implement prev/next weapon joystick buttons. TODO: Menu and Automap joystick buttons. --- Source/g_game.c | 38 +++++++++++--- Source/i_system.c | 92 +++++++++++++++++++--------------- Source/i_system.h | 3 +- Source/i_video.c | 124 ++++++++++++++++++++-------------------------- Source/m_menu.c | 16 +++--- Source/m_misc.c | 29 ++++++++--- 6 files changed, 167 insertions(+), 135 deletions(-) diff --git a/Source/g_game.c b/Source/g_game.c index 87bf3fb9..bf51eafa 100644 --- a/Source/g_game.c +++ b/Source/g_game.c @@ -191,6 +191,9 @@ int joybstrafeleft; int joybstraferight; int joybuse; int joybspeed; +// [FG] prev/next weapon joystick buttons +int joybprevweapon; +int joybnextweapon; #define MAXPLMOVE (forwardmove[1]) #define TURBOTHRESHOLD 0x32 @@ -716,6 +719,32 @@ static void G_DoLoadLevel(void) // Get info needed to make ticcmd_ts for the players. // +static void SetJoyButtons(unsigned int buttons_mask) +{ + int i; + + for (i=0; i<8; ++i) + { + int button_on = (buttons_mask & (1 << i)) != 0; + + // Detect button press: + + if (!joybuttons[i] && button_on) + { + if (i == joybprevweapon) + { + next_weapon = -1; + } + else if (i == joybnextweapon) + { + next_weapon = 1; + } + } + + joybuttons[i] = button_on; + } +} + static void SetMouseButtons(unsigned int buttons_mask) { int i; @@ -849,14 +878,7 @@ boolean G_Responder(event_t* ev) return true; // eat events case ev_joystick: - joybuttons[0] = ev->data1 & 1; - joybuttons[1] = ev->data1 & 2; - joybuttons[2] = ev->data1 & 4; - joybuttons[3] = ev->data1 & 8; - joybuttons[4] = ev->data1 & 16; - joybuttons[5] = ev->data1 & 32; - joybuttons[6] = ev->data1 & 64; - joybuttons[7] = ev->data1 & 128; + SetJoyButtons(ev->data1); joyxmove = ev->data2; joyymove = ev->data3; return true; // eat events diff --git a/Source/i_system.c b/Source/i_system.c index 1c9ae0ca..534fcf61 100644 --- a/Source/i_system.c +++ b/Source/i_system.c @@ -102,7 +102,6 @@ static int I_GetTime_Error() int (*I_GetTime)() = I_GetTime_Error; // killough -int mousepresent; int joystickpresent; // phares 4/3/98 int leds_always_off; // Tells it not to update LEDs @@ -117,46 +116,69 @@ SDL_Joystick *sdlJoystick = NULL; static SDL_Keymod oldmod; // haleyjd: save old modifier key state +static void I_ShutdownJoystick(void) +{ + if (sdlJoystick != NULL) + { + SDL_JoystickClose(sdlJoystick); + sdlJoystick = NULL; + } + + if (joystickpresent) + { + SDL_QuitSubSystem(SDL_INIT_JOYSTICK); + joystickpresent = false; + } +} + void I_Shutdown(void) { SDL_SetModState(oldmod); - - // haleyjd 04/15/02: shutdown joystick - if(joystickpresent && sdlJoystick && i_SDLJoystickNum >= 0) - { - if(SDL_JoystickGetAttached(sdlJoystick)) - SDL_JoystickClose(sdlJoystick); - - joystickpresent = false; - } + + I_ShutdownJoystick(); SDL_Quit(); } -// -// I_SetJoystickDevice -// -// haleyjd -// -boolean I_SetJoystickDevice(int deviceNum) +extern int usejoystick; + +void I_InitJoystick(void) { - if(deviceNum >= SDL_NumJoysticks()) - return false; - else - { - sdlJoystick = SDL_JoystickOpen(deviceNum); + if (!usejoystick) + { + I_ShutdownJoystick(); + return; + } - if(!sdlJoystick) - return false; + if (SDL_Init(SDL_INIT_JOYSTICK) < 0) + { + return; + } - // check that the device has at least 2 axes and - // 4 buttons - if(SDL_JoystickNumAxes(sdlJoystick) < 2 || - SDL_JoystickNumButtons(sdlJoystick) < 4) - return false; + joystickpresent = true; - return true; - } + // Open the joystick + + sdlJoystick = SDL_JoystickOpen(i_SDLJoystickNum); + + if (sdlJoystick == NULL) + { + printf("I_InitJoystick: Failed to open joystick #%i\n", i_SDLJoystickNum); + + I_ShutdownJoystick(); + return; + } + + if (SDL_JoystickNumAxes(sdlJoystick) < 2 || + SDL_JoystickNumButtons(sdlJoystick) < 4) + { + printf("I_InitJoystick: Invalid joystick axis for configured joystick #%i\n", i_SDLJoystickNum); + + I_ShutdownJoystick(); + return; + } + + SDL_JoystickEventState(SDL_ENABLE); } // haleyjd @@ -210,15 +232,7 @@ void I_Init(void) else I_GetTime = I_GetTime_RealTime; - // haleyjd - if(i_SDLJoystickNum != -1) - { - joystickpresent = I_SetJoystickDevice(i_SDLJoystickNum); - } - else - { - joystickpresent = false; - } + I_InitJoystick(); // killough 3/6/98: save keyboard state, initialize shift state and LEDs: diff --git a/Source/i_system.h b/Source/i_system.h index 07561d2e..8b9c4e9d 100644 --- a/Source/i_system.h +++ b/Source/i_system.h @@ -33,6 +33,7 @@ // Called by DoomMain. void I_Init(void); +void I_InitJoystick(void); // Called by D_DoomLoop, // returns current time in tics. @@ -86,8 +87,6 @@ void I_Quit (void); // killough 4/25/98: add gcc attributes void I_Error(const char *error, ...) PRINTF_ATTR(1, 2); -extern int mousepresent; // killough - extern int leds_always_off; // killough 10/98 void I_ResetLEDs(void); // killough 10/98 diff --git a/Source/i_video.c b/Source/i_video.c index b1dba5c9..da08de26 100644 --- a/Source/i_video.c +++ b/Source/i_video.c @@ -66,9 +66,6 @@ static int window_width, window_height; ///////////////////////////////////////////////////////////////////////////// extern int usejoystick; -extern int joystickpresent; -extern int joy_x,joy_y; -extern int joy_b1,joy_b2,joy_b3,joy_b4; // I_JoystickEvents() gathers joystick data and creates an event_t for // later processing by G_Responder(). @@ -78,79 +75,70 @@ int joystickSens_y; extern SDL_Joystick *sdlJoystick; -void I_JoystickEvents(void) +// Get a bitmask of all currently-pressed buttons + +static int GetButtonsState(void) { - // haleyjd 04/15/02: SDL joystick support + int i; + int result; - event_t event; - int joy_b1, joy_b2, joy_b3, joy_b4; - int joy_b5, joy_b6, joy_b7, joy_b8; - Sint16 joy_x, joy_y; - - if(!joystickpresent || !usejoystick || !sdlJoystick) - return; - - SDL_JoystickUpdate(); // read the current joystick settings - event.type = ev_joystick; - event.data1 = 0; - - // read the button settings - if((joy_b1 = SDL_JoystickGetButton(sdlJoystick, 0))) - event.data1 |= 1; - if((joy_b2 = SDL_JoystickGetButton(sdlJoystick, 1))) - event.data1 |= 2; - if((joy_b3 = SDL_JoystickGetButton(sdlJoystick, 2))) - event.data1 |= 4; - if((joy_b4 = SDL_JoystickGetButton(sdlJoystick, 3))) - event.data1 |= 8; - if((joy_b5 = SDL_JoystickGetButton(sdlJoystick, 4))) - event.data1 |= 16; - if((joy_b6 = SDL_JoystickGetButton(sdlJoystick, 5))) - event.data1 |= 32; - if((joy_b7 = SDL_JoystickGetButton(sdlJoystick, 6))) - event.data1 |= 64; - if((joy_b8 = SDL_JoystickGetButton(sdlJoystick, 7))) - event.data1 |= 128; - - // Read the x,y settings. Convert to -1 or 0 or +1. - joy_x = SDL_JoystickGetAxis(sdlJoystick, 0); - joy_y = SDL_JoystickGetAxis(sdlJoystick, 1); - - if(joy_x < -joystickSens_x) - event.data2 = -1; - else if(joy_x > joystickSens_x) - event.data2 = 1; - else - event.data2 = 0; + result = 0; - if(joy_y < -joystickSens_y) - event.data3 = -1; - else if(joy_y > joystickSens_y) - event.data3 = 1; - else - event.data3 = 0; - - // post what you found - - D_PostEvent(&event); + for (i = 0; i < 8; ++i) + { + if (SDL_JoystickGetButton(sdlJoystick, i)) + { + result |= 1 << i; + } + } + + return result; } +// Read the state of an axis + +static int GetAxisState(int axis, int sens) +{ + int result; + + result = SDL_JoystickGetAxis(sdlJoystick, axis); + + if (result < -sens) + { + return -1; + } + else if (result > sens) + { + return 1; + } + + return 0; +} + +void I_UpdateJoystick(void) +{ + if (sdlJoystick != NULL) + { + event_t ev; + + ev.type = ev_joystick; + ev.data1 = GetButtonsState(); + ev.data2 = GetAxisState(0, joystickSens_x); + ev.data3 = GetAxisState(1, joystickSens_y); + + D_PostEvent(&ev); + } +} // // I_StartFrame // void I_StartFrame(void) { - static boolean firstframe = true; - - // haleyjd 02/23/04: turn mouse event processing on - if(firstframe) - { - SDL_EventState(SDL_MOUSEMOTION, SDL_ENABLE); - firstframe = false; - } - - I_JoystickEvents(); // Obtain joystick data phares 4/3/98 + if (usejoystick) + { + I_UpdateJoystick(); + } } ///////////////////////////////////////////////////////////////////////////// @@ -672,12 +660,6 @@ void I_StartTic (void) { I_ReadMouse(); } -/* - if (joywait < I_GetTime()) - { - I_UpdateJoystick(); - } -*/ } // diff --git a/Source/m_menu.c b/Source/m_menu.c index c0d27959..c0374d2e 100644 --- a/Source/m_menu.c +++ b/Source/m_menu.c @@ -168,6 +168,9 @@ extern int joybstrafe; // [FG] strafe left/right joystick buttons extern int joybstrafeleft; extern int joybstraferight; +// [FG] prev/next weapon joystick buttons +extern int joybprevweapon; +extern int joybnextweapon; extern int joybuse; extern int joybspeed; extern int health_red; // health amount less than which status is red @@ -2353,8 +2356,8 @@ setup_menu_t keys_settings3[] = // Key Binding screen strings {"BEST" ,S_KEY ,m_scrn,KB_X,KB_Y+10*8,{&key_weapontoggle}}, {"FIRE" ,S_KEY ,m_scrn,KB_X,KB_Y+11*8,{&key_fire},&mousebfire,&joybfire}, // [FG] prev/next weapon keys and buttons - {"PREV" ,S_KEY ,m_scrn,KB_X,KB_Y+12*8,{&key_prevweapon},&mousebprevweapon,0}, - {"NEXT" ,S_KEY ,m_scrn,KB_X,KB_Y+13*8,{&key_nextweapon},&mousebnextweapon,0}, + {"PREV" ,S_KEY ,m_scrn,KB_X,KB_Y+11*8,{&key_prevweapon},&mousebprevweapon,&joybprevweapon}, + {"NEXT" ,S_KEY ,m_scrn,KB_X,KB_Y+12*8,{&key_nextweapon},&mousebnextweapon,&joybnextweapon}, {"<- PREV",S_SKIP|S_PREV,m_null,KB_PREV,KB_Y+20*8, {keys_settings2}}, {"NEXT ->",S_SKIP|S_NEXT,m_null,KB_NEXT,KB_Y+20*8, {keys_settings4}}, @@ -3063,7 +3066,7 @@ setup_menu_t gen_settings2[] = { // General Settings screen2 G_Y + general_mouse*8, {"use_mouse"}}, {"Enable Joystick", S_YESNO, m_null, G_X, - G_Y + general_joy*8, {"use_joystick"}}, + G_Y + general_joy*8, {"use_joystick"}, 0, 0, I_InitJoystick}, #if 0 {"Keyboard LEDs Always Off", S_YESNO, m_null, G_X, @@ -4172,12 +4175,7 @@ boolean M_Responder (event_t* ev) if (setup_active && set_keybnd_active) { - if (ev->data1&4) - { - ch = 0; // meaningless, just to get you past the check for -1 - joywait = I_GetTime() + 5; - } - if (ev->data1&8 || ev->data1&16 || ev->data1&32 || ev->data1&64 || ev->data1&128) + if (ev->data1&4 || ev->data1&8 || ev->data1&16 || ev->data1&32 || ev->data1&64 || ev->data1&128) { ch = 0; // meaningless, just to get you past the check for -1 joywait = I_GetTime() + 5; diff --git a/Source/m_misc.c b/Source/m_misc.c index c7a8a492..c768a370 100644 --- a/Source/m_misc.c +++ b/Source/m_misc.c @@ -69,6 +69,9 @@ extern int joybstrafe; // [FG] strafe left/right joystick buttons extern int joybstrafeleft; extern int joybstraferight; +// [FG] prev/next weapon joystick buttons +extern int joybprevweapon; +extern int joybnextweapon; extern int joybuse; extern int joybspeed; extern int realtic_clock_rate; // killough 4/13/98: adjustable timer @@ -1110,45 +1113,59 @@ default_t defaults[] = { { "joyb_fire", &joybfire, NULL, - {0}, {0,UL}, number, ss_keys, wad_no, + {3}, {-1,7}, number, ss_keys, wad_no, "joystick button number to use for fire" }, { "joyb_strafe", &joybstrafe, NULL, - {1}, {0,UL}, 0, ss_keys, wad_no, + {-1}, {-1,7}, 0, ss_keys, wad_no, "joystick button number to use for strafing" }, { "joyb_speed", &joybspeed, NULL, - {2}, {0,UL}, 0, ss_keys, wad_no, + {1}, {-1,7}, 0, ss_keys, wad_no, "joystick button number to use for running" }, { "joyb_use", &joybuse, NULL, - {3}, {0,UL}, 0, ss_keys, wad_no, + {0}, {-1,7}, 0, ss_keys, wad_no, "joystick button number to use for use/open" }, { // [FG] strafe left/right joystick buttons "joyb_strafeleft", &joybstrafeleft, NULL, - {4}, {0,UL}, 0, ss_keys, wad_no, + {4}, {-1,7}, 0, ss_keys, wad_no, "joystick button number to strafe left (sideways left)" }, { "joyb_straferight", &joybstraferight, NULL, - {5}, {0,UL}, 0, ss_keys, wad_no, + {5}, {-1,7}, 0, ss_keys, wad_no, "joystick button number to strafe right (sideways right)" }, + { // [FG] prev/next weapon joystick buttons + "joyb_prevweapon", + &joybprevweapon, NULL, + {2}, {-1,7}, 0, ss_keys, wad_no, + "joystick button number to cycle to the previous weapon" + }, + + { + "joyb_nextweapon", + &joybnextweapon, NULL, + {-1}, {-1,7}, 0, ss_keys, wad_no, + "joystick button number to cycle to the next weapon" + }, + { // killough "snd_channels", &default_numChannels, NULL,