From 5cd4d7bf4cc093ed02c70941eb4ea2a798bac866 Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Sat, 9 Sep 2023 03:11:17 +0300 Subject: [PATCH] client: reimplement input with SDL2, link client.dll with SDL2. * Leave a way to use Windows input --- cl_dll/in_camera.cpp | 39 +++++++++++- cl_dll/inputw32.cpp | 143 +++++++++++++++++++++++++++++++++++++++---- cl_dll/wscript | 8 ++- 3 files changed, 176 insertions(+), 14 deletions(-) diff --git a/cl_dll/in_camera.cpp b/cl_dll/in_camera.cpp index ec146f0..1e644a8 100644 --- a/cl_dll/in_camera.cpp +++ b/cl_dll/in_camera.cpp @@ -15,7 +15,13 @@ #include "camera.h" #include "in_defs.h" +#define USE_SDL +#ifndef USE_SDL #include "windows.h" +#else +#include "SDL2/SDL_mouse.h" +#endif +#include "port.h" float CL_KeyState (kbutton_t *key); @@ -146,6 +152,17 @@ typedef struct extern trace_t SV_ClipMoveToEntity (edict_t *ent, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end); +#ifdef USE_SDL +void SDL_GetCursorPos( POINT *p ) +{ + gEngfuncs.GetMousePosition( (int *)&p->x, (int *)&p->y ); +// SDL_GetMouseState( (int *)&p->x, (int *)&p->y ); +} + +void SDL_SetCursorPos( const int x, const int y ) +{ +} +#endif void DLLEXPORT CAM_Think( void ) { vec3_t origin; @@ -194,7 +211,11 @@ void DLLEXPORT CAM_Think( void ) if (cam_mousemove) { //get windows cursor position +#ifndef USE_SDL GetCursorPos (&cam_mouse); +#else + SDL_GetCursorPos (&cam_mouse); +#endif //check for X delta values and adjust accordingly //eventually adjust YAW based on amount of movement //don't do any movement of the cam using YAW/PITCH if we are zooming in/out the camera @@ -269,7 +290,11 @@ void DLLEXPORT CAM_Think( void ) cam_old_mouse_x=cam_mouse.x; cam_old_mouse_y=cam_mouse.y; } +#ifndef USE_SDL SetCursorPos (gEngfuncs.GetWindowCenterX(), gEngfuncs.GetWindowCenterY()); +#else + SDL_SetCursorPos (gEngfuncs.GetWindowCenterX(), gEngfuncs.GetWindowCenterY()); +#endif } } @@ -327,7 +352,11 @@ void DLLEXPORT CAM_Think( void ) //since we are done with the mouse cam_old_mouse_x=cam_mouse.x*gHUD.GetSensitivity(); cam_old_mouse_y=cam_mouse.y*gHUD.GetSensitivity(); +#ifndef USE_SDL SetCursorPos (gEngfuncs.GetWindowCenterX(), gEngfuncs.GetWindowCenterY()); +#else + SDL_SetCursorPos (gEngfuncs.GetWindowCenterX(), gEngfuncs.GetWindowCenterY()); +#endif } #ifdef LATER if( cam_contain->value ) @@ -540,7 +569,11 @@ void CAM_StartMouseMove(void) { cam_mousemove=1; iMouseInUse=1; +#ifndef USE_SDL GetCursorPos (&cam_mouse); +#else + SDL_GetCursorPos (&cam_mouse); +#endif if ( ( flSensitivity = gHUD.GetSensitivity() ) != 0 ) { @@ -587,7 +620,11 @@ void CAM_StartDistance(void) cam_distancemove=1; cam_mousemove=1; iMouseInUse=1; +#ifndef USE_SDL GetCursorPos (&cam_mouse); +#else + SDL_GetCursorPos (&cam_mouse); +#endif cam_old_mouse_x=cam_mouse.x*gHUD.GetSensitivity(); cam_old_mouse_y=cam_mouse.y*gHUD.GetSensitivity(); } @@ -618,4 +655,4 @@ int DLLEXPORT CL_IsThirdPerson( void ) void DLLEXPORT CL_CameraOffset( float *ofs ) { VectorCopy( cam_ofs, ofs ); -} \ No newline at end of file +} diff --git a/cl_dll/inputw32.cpp b/cl_dll/inputw32.cpp index 5e73f43..d209a96 100644 --- a/cl_dll/inputw32.cpp +++ b/cl_dll/inputw32.cpp @@ -19,7 +19,16 @@ #include "in_defs.h" #include "../engine/keydefs.h" #include "view.h" -#include "windows.h" +#include "port.h" + +#define USE_SDL + +#ifndef USE_SDL +#include +#else +#include +#include +#endif #define MOUSE_BUTTON_COUNT 5 @@ -65,7 +74,9 @@ cvar_t *sensitivity; int mouse_buttons; int mouse_oldbuttonstate; +#ifndef USE_SDL POINT current_pos; +#endif int mouse_x, mouse_y, old_mouse_x, old_mouse_y, mx_accum, my_accum; static int restore_spi; @@ -96,6 +107,7 @@ enum _ControlList AxisTurn }; +#ifndef USE_SDL DWORD dwAxisFlags[JOY_MAX_AXES] = { JOY_RETURNX, @@ -105,10 +117,15 @@ DWORD dwAxisFlags[JOY_MAX_AXES] = JOY_RETURNU, JOY_RETURNV }; +#endif DWORD dwAxisMap[ JOY_MAX_AXES ]; DWORD dwControlMap[ JOY_MAX_AXES ]; +#ifdef USE_SDL +int pdwRawValue[ JOY_MAX_AXES ]; +#else PDWORD pdwRawValue[ JOY_MAX_AXES ]; +#endif // none of these cvars are saved over a session // this means that advanced controller configuration needs to be executed @@ -142,7 +159,11 @@ int joy_id; DWORD joy_flags; DWORD joy_numbuttons; +#ifdef USE_SDL +static SDL_GameController *s_pJoystick = NULL; +#else static JOYINFOEX ji; +#endif /* =========== @@ -170,8 +191,10 @@ void DLLEXPORT IN_ActivateMouse (void) { if (mouseinitialized) { +#ifdef _WIN32 if (mouseparmsvalid) restore_spi = SystemParametersInfo (SPI_SETMOUSE, 0, newmouseparms, 0); +#endif mouseactive = 1; } } @@ -185,9 +208,10 @@ void DLLEXPORT IN_DeactivateMouse (void) { if (mouseinitialized) { +#ifdef _WIN32 if (restore_spi) SystemParametersInfo (SPI_SETMOUSE, 0, originalmouseparms, 0); - +#endif mouseactive = 0; } } @@ -203,6 +227,7 @@ void IN_StartupMouse (void) return; mouseinitialized = 1; +#ifdef _WIN32 mouseparmsvalid = SystemParametersInfo (SPI_GETMOUSE, 0, originalmouseparms, 0); if (mouseparmsvalid) @@ -223,7 +248,7 @@ void IN_StartupMouse (void) newmouseparms[2] = originalmouseparms[2]; } } - +#endif mouse_buttons = MOUSE_BUTTON_COUNT; } @@ -258,7 +283,9 @@ FIXME: Call through to engine? */ void IN_ResetMouse( void ) { - SetCursorPos ( gEngfuncs.GetWindowCenterX(), gEngfuncs.GetWindowCenterY() ); +#ifndef USE_SDL + SetCursorPos ( gEngfuncs.GetWindowCenterX(), gEngfuncs.GetWindowCenterY() ); +#endif } /* @@ -314,10 +341,17 @@ void IN_MouseMove ( float frametime, usercmd_t *cmd) // GAGE -> if your dead you cant move your head dumbass :) if ( !iMouseInUse && !g_iVisibleMouse && !gHUD.m_iIntermission) { +#ifdef USE_SDL + int deltaX, deltaY; + SDL_GetRelativeMouseState( &deltaX, &deltaY ); + mx = deltaX + mx_accum; + my = deltaY + my_accum; +#else GetCursorPos (¤t_pos); - mx = current_pos.x - gEngfuncs.GetWindowCenterX() + mx_accum; my = current_pos.y - gEngfuncs.GetWindowCenterY() + my_accum; +#endif + mx_accum = 0; my_accum = 0; @@ -410,10 +444,17 @@ void DLLEXPORT IN_Accumulate (void) { if (mouseactive) { +#ifdef USE_SDL + int x = 0, y = 0; + SDL_GetRelativeMouseState( &x, &y ); + mx_accum += x; + my_accum += y; +#else GetCursorPos (¤t_pos); - mx_accum += current_pos.x - gEngfuncs.GetWindowCenterX(); my_accum += current_pos.y - gEngfuncs.GetWindowCenterY(); +#endif + // force the mouse to the center, so there's room to move IN_ResetMouse(); @@ -445,16 +486,52 @@ IN_StartupJoystick void IN_StartupJoystick (void) { int numdevs; +#ifndef USE_SDL JOYCAPS jc; MMRESULT mmr; - +#endif // assume no joystick joy_avail = 0; // abort startup if user requests no joystick if ( gEngfuncs.CheckParm ("-nojoy", NULL ) ) return; - + +#ifdef USE_SDL + int nJoysticks = SDL_NumJoysticks(); + if( nJoysticks > 0 ) + { + for( int i = 0; i < nJoysticks; i++ ) + { + if( SDL_IsGameController( i )) + { + s_pJoystick = SDL_GameControllerOpen( i ); + if( s_pJoystick ) + { + //save the joystick's number of buttons and POV status + joy_numbuttons = SDL_CONTROLLER_BUTTON_MAX; + joy_haspov = 0; + + // old button and POV states default to no buttons pressed + joy_oldbuttonstate = joy_oldpovstate = 0; + + // mark the joystick as available and advanced initialization not completed + // this is needed as cvars are not available during initialization + gEngfuncs.Con_Printf ("joystick found\n\n", SDL_GameControllerName(s_pJoystick)); + joy_avail = 1; + joy_advancedinit = 0; + break; + } + } + } + } + else + { + gEngfuncs.Con_DPrintf ("joystick not found -- driver not present\n\n"); + return; + } + +#else // verify joystick driver is present if ((numdevs = joyGetNumDevs ()) == 0) { @@ -501,6 +578,7 @@ void IN_StartupJoystick (void) gEngfuncs.Con_Printf ("joystick found\n\n", mmr); joy_avail = 1; joy_advancedinit = 0; +#endif } @@ -509,8 +587,27 @@ void IN_StartupJoystick (void) RawValuePointer =========== */ +#ifdef USE_SDL +int RawValuePointer (int axis) +#else PDWORD RawValuePointer (int axis) +#endif { +#ifdef USE_SDL + switch (axis) + { + default: + case JOY_AXIS_X: + return SDL_GameControllerGetAxis( s_pJoystick, SDL_CONTROLLER_AXIS_LEFTX ); + case JOY_AXIS_Y: + return SDL_GameControllerGetAxis( s_pJoystick, SDL_CONTROLLER_AXIS_LEFTY ); + case JOY_AXIS_Z: + return SDL_GameControllerGetAxis( s_pJoystick, SDL_CONTROLLER_AXIS_RIGHTX ); + case JOY_AXIS_R: + return SDL_GameControllerGetAxis( s_pJoystick, SDL_CONTROLLER_AXIS_RIGHTY ); + } + return 0; +#else switch (axis) { case JOY_AXIS_X: @@ -528,6 +625,7 @@ PDWORD RawValuePointer (int axis) } // FIX: need to do some kind of error return &ji.dwXpos; +#endif } @@ -591,6 +689,7 @@ void Joy_AdvancedUpdate_f (void) dwControlMap[JOY_AXIS_V] = dwTemp & JOY_RELATIVE_AXIS; } +#ifndef USE_SDL // compute the axes to collect from DirectInput joy_flags = JOY_RETURNCENTERED | JOY_RETURNBUTTONS | JOY_RETURNPOV; for (i = 0; i < JOY_MAX_AXES; i++) @@ -600,6 +699,7 @@ void Joy_AdvancedUpdate_f (void) joy_flags |= dwAxisFlags[i]; } } +#endif } @@ -621,7 +721,19 @@ void IN_Commands (void) // loop through the joystick buttons // key a joystick event or auxillary event for higher number buttons for each state change +#ifdef USE_SDL + buttonstate = 0; + for( i = 0; i < SDL_CONTROLLER_BUTTON_MAX; i++ ) + { + if( SDL_GameControllerGetButton( s_pJoystick, (SDL_GameControllerButton)i )) + buttonstate |= i; + } + + for (i = 0; i < JOY_MAX_AXES; i++) + pdwRawValue[i] = RawValuePointer(i); +#else buttonstate = ji.dwButtons; +#endif for (i=0 ; i < (int)joy_numbuttons ; i++) { if ( (buttonstate & (1<value != 0.0) { if (dwAxisMap[i] == AxisTurn) @@ -948,4 +1069,4 @@ void IN_Init (void) IN_StartupMouse (); IN_StartupJoystick (); -} \ No newline at end of file +} diff --git a/cl_dll/wscript b/cl_dll/wscript index 499ef3b..6452618 100644 --- a/cl_dll/wscript +++ b/cl_dll/wscript @@ -9,12 +9,15 @@ def options(opt): opt.load('vgui') def configure(conf): + conf.env.INCLUDES_SDL = ['../external/SDL2'] + conf.env.LIBPATH_SDL = ['../linux'] + conf.env.LIB_SDL = ['SDL2'] conf.load('vgui') if not conf.check_vgui(): conf.fatal('VGUI was enabled but VGUI cannot be used') def build(bld): - libs = ['VGUI'] + libs = ['VGUI', 'SDL'] defines = ['CLIENT_DLL'] includes = ['.', '../dlls', @@ -22,7 +25,8 @@ def build(bld): '../engine', '../pm_shared', '../game_shared', - '../public'] + '../public', + '../external/SDL2'] source = [ './ev_thewastes.cpp', './thewastes/hl_baseentity.cpp',