diff --git a/CMakeLists.txt b/CMakeLists.txt index e61f2fce0..e80bc3171 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -197,9 +197,9 @@ if( MSVC ) # Function-level linking # Disable run-time type information if ( HAVE_VULKAN ) - set( ALL_C_FLAGS "/GF /Gy /GR- /permissive- /DHAVE_VULKAN" ) + set( ALL_C_FLAGS "/GF /Gy /permissive- /DHAVE_VULKAN" ) else() - set( ALL_C_FLAGS "/GF /Gy /GR- /permissive-" ) + set( ALL_C_FLAGS "/GF /Gy /permissive-" ) endif() # Use SSE 2 as minimum always as the true color drawers needs it for __vectorcall diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index a1e5ba2ed..d1b734c3f 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -614,8 +614,6 @@ file( GLOB HEADER_FILES libsmackerdec/include/*.h libxmp-lite/include/libxmp-lite/*.h libxmp-lite/src/*.h - mact/include/*.h - mact/src/*.h common/*.h common/2d/*.h common/fonts/*.h @@ -624,6 +622,7 @@ file( GLOB HEADER_FILES common/filesystem/*.h common/music/*.h common/menu/*.h + common/input/*.h build/src/*.h thirdparty/include/*.h @@ -638,7 +637,6 @@ file( GLOB HEADER_FILES # without being compiled. set( NOT_COMPILED_SOURCE_FILES ${OTHER_SYSTEM_SOURCES} - build/src/sdlkeytrans.cpp sc_man_scanner.h common/utility/sc_man_scanner.re ) @@ -691,11 +689,6 @@ set (PCH_SOURCES glbackend/gl_buffers.cpp glbackend/hw_draw2d.cpp - mact/src/animlib.cpp - mact/src/control.cpp - mact/src/joystick.cpp - mact/src/input.cpp - thirdparty/src/base64.cpp thirdparty/src/sjson.cpp thirdparty/src/fix16.cpp @@ -739,6 +732,7 @@ set (PCH_SOURCES build/src/timer.cpp build/src/voxmodel.cpp + common/animlib.cpp common/rts.cpp common/gameconfigfile.cpp common/gamecvars.cpp @@ -840,6 +834,12 @@ set (PCH_SOURCES common/menu/menuinput.cpp common/menu/messagebox.cpp common/menu/optionmenu.cpp + + common/input/i_gui.cpp + common/input/i_joystick.cpp + common/input/i_input.cpp + common/input/m_joy.cpp + common/input/input.cpp ) if( MSVC ) @@ -886,7 +886,6 @@ target_link_libraries( demolition ${DEMOLITION_LIBS} gdtoa lzma duke3d blood rr include_directories( ${CMAKE_CURRENT_SOURCE_DIR} build/include - mact/include audiolib/include glad/include libxmp-lite/include @@ -905,6 +904,7 @@ include_directories( common/sound common/dobject common/menu + common/input platform ${CMAKE_BINARY_DIR}/libraries/gdtoa @@ -1030,9 +1030,6 @@ source_group("Utility\\Smackerdec\\Sources" REGULAR_EXPRESSION "^${CMAKE_CURRENT source_group("Utility\\XMP-Lite" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/libxmp-lite/.+") source_group("Utility\\XMP-Lite Headers" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/libxmp-lite/include/libxmp-lite/.+") source_group("Utility\\XMP-Lite Sources" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/libxmp-lite/src/.+") -source_group("Utility\\Mact" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/mact/.+") -source_group("Utility\\Mact Headers" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/mact/include/.+") -source_group("Utility\\Mact Sources" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/mact/src/.+") source_group("Utility\\Third Party" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/.+") source_group("Utility\\Third Party Headers" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/include/.+") source_group("Utility\\Third Party Sources" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/src/.+") diff --git a/source/blood/CMakeLists.txt b/source/blood/CMakeLists.txt index 564c2a255..595335204 100644 --- a/source/blood/CMakeLists.txt +++ b/source/blood/CMakeLists.txt @@ -14,7 +14,6 @@ endif() include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/../build/include - ${CMAKE_CURRENT_SOURCE_DIR}/../mact/include ${CMAKE_CURRENT_SOURCE_DIR}/../audiolib/include ${CMAKE_CURRENT_SOURCE_DIR}/../libsmackerdec/include ${CMAKE_CURRENT_SOURCE_DIR}/../thirdparty/include @@ -25,6 +24,7 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/../common/fonts ${CMAKE_CURRENT_SOURCE_DIR}/../common/2d ${CMAKE_CURRENT_SOURCE_DIR}/../common/music + ${CMAKE_CURRENT_SOURCE_DIR}/../common/input ${CMAKE_CURRENT_SOURCE_DIR}/../platform ) diff --git a/source/blood/src/blood.cpp b/source/blood/src/blood.cpp index 2bb26e7c9..86a115d73 100644 --- a/source/blood/src/blood.cpp +++ b/source/blood/src/blood.cpp @@ -175,7 +175,6 @@ void ShutDown(void) sndTerm(); sfxTerm(); scrUnInit(); - CONTROL_Shutdown(); // PORT_TODO: Check argument if (syncstate) printf("A packet was lost! (syncstate)\n"); diff --git a/source/blood/src/config.h b/source/blood/src/config.h index da8cf0efd..41758f109 100644 --- a/source/blood/src/config.h +++ b/source/blood/src/config.h @@ -24,9 +24,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #ifndef config_public_h_ #define config_public_h_ -#include "keyboard.h" -#include "control.h" -#include "_control.h" #include "hash.h" #include "gamecvars.h" #include "gamecontrol.h" diff --git a/source/blood/src/controls.cpp b/source/blood/src/controls.cpp index 4a85b6afe..558404b4b 100644 --- a/source/blood/src/controls.cpp +++ b/source/blood/src/controls.cpp @@ -25,10 +25,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "compat.h" #include "baselayer.h" -#include "keyboard.h" -#include "mouse.h" -#include "joystick.h" -#include "control.h" #include "gamecontrol.h" #include "common_game.h" #include "blood.h" @@ -46,8 +42,8 @@ int32_t ctrlCheckAllInput(void) { return ( inputState.keyBufferWaiting() || - inputState.MouseGetButtons() || - JOYSTICK_GetButtons() + inputState.MouseGetButtons() + //JOYSTICK_GetButtons() ); } @@ -56,7 +52,8 @@ void ctrlClearAllInput(void) inputState.keyFlushChars(); inputState.ClearKeysDown(); inputState.MouseClearAllButtonss(); - JOYSTICK_ClearAllButtons(); + //JOYSTICK_ClearAllButtons() + ; } GINPUT gInput; @@ -75,7 +72,6 @@ void ctrlInit(void) void ctrlTerm(void) { - CONTROL_Shutdown(); } int32_t mouseyaxismode = -1; diff --git a/source/blood/src/credits.cpp b/source/blood/src/credits.cpp index 45c2157a2..1ca8799e6 100644 --- a/source/blood/src/credits.cpp +++ b/source/blood/src/credits.cpp @@ -27,7 +27,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "compat.h" #include "SmackerDecoder.h" #include "fx_man.h" -#include "keyboard.h" #include "common_game.h" #include "blood.h" #include "config.h" diff --git a/source/blood/src/d_menu.cpp b/source/blood/src/d_menu.cpp index 2b81b6317..579f83293 100644 --- a/source/blood/src/d_menu.cpp +++ b/source/blood/src/d_menu.cpp @@ -25,7 +25,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "build.h" #include "compat.h" -#include "mouse.h" #include "common_game.h" #include "blood.h" #include "config.h" diff --git a/source/blood/src/demo.cpp b/source/blood/src/demo.cpp index 596ac9bc9..2d50af750 100644 --- a/source/blood/src/demo.cpp +++ b/source/blood/src/demo.cpp @@ -27,8 +27,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include #include "common.h" #include "common_game.h" -#include "keyboard.h" -#include "control.h" #include "osd.h" #include "mmulti.h" diff --git a/source/blood/src/gamemenu.cpp b/source/blood/src/gamemenu.cpp index 4ce789220..31bf46c39 100644 --- a/source/blood/src/gamemenu.cpp +++ b/source/blood/src/gamemenu.cpp @@ -25,7 +25,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "build.h" #include "compat.h" -#include "mouse.h" #include "common_game.h" #include "blood.h" #include "config.h" diff --git a/source/blood/src/messages.cpp b/source/blood/src/messages.cpp index c93c0f13a..2c2ac7a2f 100644 --- a/source/blood/src/messages.cpp +++ b/source/blood/src/messages.cpp @@ -25,8 +25,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "build.h" #include "mmulti.h" #include "compat.h" -#include "keyboard.h" -#include "control.h" #include "gamecontrol.h" #include "common_game.h" #include "blood.h" diff --git a/source/blood/src/osdcmd.cpp b/source/blood/src/osdcmd.cpp index b8d38f114..f7fa34ca6 100644 --- a/source/blood/src/osdcmd.cpp +++ b/source/blood/src/osdcmd.cpp @@ -24,8 +24,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "build.h" #include "baselayer.h" -#include "keyboard.h" -#include "control.h" #include "osd.h" #include "compat.h" #include "mmulti.h" diff --git a/source/build/src/engine.cpp b/source/build/src/engine.cpp index 2a2e87603..81cdea343 100644 --- a/source/build/src/engine.cpp +++ b/source/build/src/engine.cpp @@ -7316,6 +7316,7 @@ static void dosetaspect(void) { oxyaspect = xyaspect; j = xyaspect*320; + horizycent = (ydim*4)>>1; horizlookup2[horizycent-1] = divscale32(131072,j); for (i=0; i < horizycent-1; i++) diff --git a/source/build/src/sdlayer.cpp b/source/build/src/sdlayer.cpp index 9cc9992d9..16f27e654 100644 --- a/source/build/src/sdlayer.cpp +++ b/source/build/src/sdlayer.cpp @@ -78,6 +78,8 @@ double g_beforeSwapTime; GameInterface* gi; FArgs* Args; +void buildkeytranslationtable();; + #if !defined STARTUP_SETUP_WINDOW int32_t startwin_open(void) { return 0; } int32_t startwin_close(void) { return 0; } @@ -143,7 +145,6 @@ static int32_t vsync_renderlayer; //#define KEY_PRINT_DEBUG -#include "sdlkeytrans.cpp" static SDL_Surface *appicon = NULL; #if !defined __APPLE__ && !defined EDUKE32_TOUCH_DEVICES @@ -377,7 +378,7 @@ void wm_setapptitle(const char *name) # include #endif -static inline char grabmouse_low(char a); +char grabmouse_low(char a); #ifndef __ANDROID__ static void attach_debugger_here(void) {} @@ -924,57 +925,6 @@ const char *joyGetName(int32_t what, int32_t num) } -// -// initmouse() -- init mouse input -// -void mouseInit(void) -{ - mouseGrabInput(g_mouseEnabled = g_mouseLockedToWindow); // FIXME - SA -} - -// -// uninitmouse() -- uninit mouse input -// -void mouseUninit(void) -{ - mouseGrabInput(0); - g_mouseEnabled = 0; -} - - -// -// grabmouse_low() -- show/hide mouse cursor, lower level (doesn't check state). -// furthermore return 0 if successful. -// - -static inline char grabmouse_low(char a) -{ - /* FIXME: Maybe it's better to make sure that grabmouse_low - is called only when a window is ready? */ - if (sdl_window) - SDL_SetWindowGrab(sdl_window, a ? SDL_TRUE : SDL_FALSE); - return SDL_SetRelativeMouseMode(a ? SDL_TRUE : SDL_FALSE); -} - -// -// grabmouse() -- show/hide mouse cursor -// -void mouseGrabInput(bool grab) -{ - if (appactive && g_mouseEnabled) - { - if ((grab != g_mouseGrabbed) && !grabmouse_low(grab)) - g_mouseGrabbed = grab; - } - else - g_mouseGrabbed = grab; - - inputState.MouseSetPos(0, 0); - SDL_ShowCursor(!grab ? SDL_ENABLE : SDL_DISABLE); - if (grab) GUICapture &= ~1; - else GUICapture |= 1; -} - // // setjoydeadzone() -- sets the dead and saturation zones for the joystick // @@ -1026,6 +976,20 @@ static int sortmodes(const void *a_, const void *b_) static char modeschecked=0; +void WindowMoved(int x, int y) +{ + if (windowpos) + { + windowx = x; + windowy = y; + } + + r_displayindex = SDL_GetWindowDisplayIndex(sdl_window); + modeschecked = 0; + videoGetModes(); +} + + #if SDL_MAJOR_VERSION != 1 void videoGetModes(void) { @@ -1606,493 +1570,6 @@ static inline SDL_Surface *loadappicon(void) // // -int32_t handleevents_peekkeys(void) -{ - SDL_PumpEvents(); - - return SDL_PeepEvents(NULL, 1, SDL_PEEKEVENT, SDL_KEYDOWN, SDL_KEYDOWN); -} - -static void PostMouseMove(int x, int y) -{ - static int lastx = 0, lasty = 0; - event_t ev = { 0,0,0,0,0,0,0 }; - - ev.x = x; - ev.y = y; - lastx = x; - lasty = y; - if (ev.x | ev.y) - { - ev.type = EV_Mouse; - D_PostEvent(&ev); - } -} - -CVAR(Bool, m_noprescale, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) - -static void MouseRead() -{ - int x, y; - -#if 0 - if (NativeMouse) - { - return; - } -#endif - - SDL_GetRelativeMouseState(&x, &y); - if (!m_noprescale) - { - x *= 3; - y *= 2; - } - if (x | y) - { - PostMouseMove(x, -y); - } -} - - -// -// handleevents() -- process the SDL message queue -// returns !0 if there was an important event worth checking (like quitting) -// - -int32_t handleevents_sdlcommon(SDL_Event *ev) -{ - switch (ev->type) - { - case SDL_MOUSEMOTION: - //case SDL_JOYBALLMOTION: - { - // The menus need this, even in non GUI-capture mode - event_t event; - event.data1 = ev->motion.x; - event.data2 = ev->motion.y; - - //screen->ScaleCoordsFromWindow(event.data1, event.data2); - - event.type = EV_GUI_Event; - event.subtype = EV_GUI_MouseMove; - - SDL_Keymod kmod = SDL_GetModState(); - event.data3 = ((kmod & KMOD_SHIFT) ? GKM_SHIFT : 0) | - ((kmod & KMOD_CTRL) ? GKM_CTRL : 0) | - ((kmod & KMOD_ALT) ? GKM_ALT : 0); - - D_PostEvent(&event); - break; - } - - case SDL_MOUSEBUTTONDOWN: - case SDL_MOUSEBUTTONUP: - { - int32_t j; - - // some of these get reordered to match winlayer - switch (ev->button.button) - { - default: j = -1; break; - case SDL_BUTTON_LEFT: j = KEY_MOUSE1; break; - case SDL_BUTTON_RIGHT: j = KEY_MOUSE2; break; - case SDL_BUTTON_MIDDLE: j = KEY_MOUSE3; break; - - /* Thumb buttons. */ - // On SDL2/Windows and SDL >= 2.0.?/Linux, everything is as it should be. - // If anyone cares about old versions of SDL2 on Linux, patches welcome. - case SDL_BUTTON_X1: j = KEY_MOUSE4; break; - case SDL_BUTTON_X2: j = KEY_MOUSE5; break; - } - - if (j < 0) - break; - - if (!(GUICapture & 1)) - { - event_t evt = { uint8_t((ev->button.state == SDL_PRESSED) ? EV_KeyDown : EV_KeyUp), 0, (int16_t)j }; - D_PostEvent(&evt); - } - else - { - event_t evt; - evt.type = EV_GUI_Event; - evt.subtype = uint8_t((ev->button.state == SDL_PRESSED) ? EV_GUI_LButtonDown : EV_GUI_LButtonUp); - evt.data1 = ev->motion.x; - evt.data2 = ev->motion.y; - - SDL_Keymod kmod = SDL_GetModState(); - evt.data3 = ((kmod & KMOD_SHIFT) ? GKM_SHIFT : 0) | - ((kmod & KMOD_CTRL) ? GKM_CTRL : 0) | - ((kmod & KMOD_ALT) ? GKM_ALT : 0); - - D_PostEvent(&evt); - - } - break; - } - - case SDL_JOYAXISMOTION: -#if SDL_MAJOR_VERSION >= 2 - if (joystick.isGameController) - break; - fallthrough__; - case SDL_CONTROLLERAXISMOTION: -#endif - if (appactive && ev->jaxis.axis < joystick.numAxes) - { - joystick.pAxis[ev->jaxis.axis] = ev->jaxis.value; - int32_t const scaledValue = ev->jaxis.value * 10000 / 32767; - if ((scaledValue < joydead[ev->jaxis.axis]) && - (scaledValue > -joydead[ev->jaxis.axis])) - joystick.pAxis[ev->jaxis.axis] = 0; - else if (scaledValue >= joysatur[ev->jaxis.axis]) - joystick.pAxis[ev->jaxis.axis] = 32767; - else if (scaledValue <= -joysatur[ev->jaxis.axis]) - joystick.pAxis[ev->jaxis.axis] = -32767; - else - joystick.pAxis[ev->jaxis.axis] = joystick.pAxis[ev->jaxis.axis] * 10000 / joysatur[ev->jaxis.axis]; - } - break; - - case SDL_JOYHATMOTION: - { - int32_t hatvals[16] = { - -1, // centre - 0, // up 1 - 9000, // right 2 - 4500, // up+right 3 - 18000, // down 4 - -1, // down+up!! 5 - 13500, // down+right 6 - -1, // down+right+up!! 7 - 27000, // left 8 - 27500, // left+up 9 - -1, // left+right!! 10 - -1, // left+right+up!! 11 - 22500, // left+down 12 - -1, // left+down+up!! 13 - -1, // left+down+right!! 14 - -1, // left+down+right+up!! 15 - }; - if (appactive && ev->jhat.hat < joystick.numHats) - joystick.pHat[ev->jhat.hat] = hatvals[ev->jhat.value & 15]; - break; - } - - case SDL_JOYBUTTONDOWN: - case SDL_JOYBUTTONUP: -#if SDL_MAJOR_VERSION >= 2 - if (joystick.isGameController) - break; - fallthrough__; - case SDL_CONTROLLERBUTTONDOWN: - case SDL_CONTROLLERBUTTONUP: -#endif - if (appactive && ev->jbutton.button < joystick.numButtons) - { - if (ev->jbutton.state == SDL_PRESSED) - joystick.bits |= 1 << ev->jbutton.button; - else - joystick.bits &= ~(1 << ev->jbutton.button); - - } - break; - - case SDL_QUIT: - throw ExitEvent(0); // completely bypass the hackery in the games to block Alt-F4. - return -1; - } - - return 0; -} - -// So this is how the engine handles text input? -// Argh. This is just gross. -int scancodetoasciihack(SDL_Event &ev) -{ - int sc = ev.key.keysym.scancode; - SDL_Keycode keyvalue = ev.key.keysym.sym; - int code = keytranslation[sc]; - // Modifiers that have to be held down to be effective - // (excludes KMOD_NUM, for example). - static const int MODIFIERS = - KMOD_LSHIFT|KMOD_RSHIFT|KMOD_LCTRL|KMOD_RCTRL| - KMOD_LALT|KMOD_RALT|KMOD_LGUI|KMOD_RGUI; - - // XXX: see osd.c, OSD_HandleChar(), there are more... - if ( - (sc == SDL_SCANCODE_RETURN || sc == SDL_SCANCODE_KP_ENTER || - sc == SDL_SCANCODE_ESCAPE || - sc == SDL_SCANCODE_BACKSPACE || - sc == SDL_SCANCODE_TAB || - (((ev.key.keysym.mod) & MODIFIERS) == KMOD_LCTRL && - (sc >= SDL_SCANCODE_A && sc <= SDL_SCANCODE_Z)))) - { - char keyvalue; - switch (sc) - { - case SDL_SCANCODE_RETURN: case SDL_SCANCODE_KP_ENTER: keyvalue = '\r'; break; - case SDL_SCANCODE_ESCAPE: keyvalue = 27; break; - case SDL_SCANCODE_BACKSPACE: keyvalue = '\b'; break; - case SDL_SCANCODE_TAB: keyvalue = '\t'; break; - default: keyvalue = sc - SDL_SCANCODE_A + 1; break; // Ctrl+A --> 1, etc. - } - } - else - { - /* - Necessary for Duke 3D's method of entering cheats to work without showing IMEs. - SDL_TEXTINPUT is preferable overall, but with bitmap fonts it has no advantage. - */ - // Note that this is not how text input is supposed to be handled! - - if ('a' <= keyvalue && keyvalue <= 'z') - { - if (!!(ev.key.keysym.mod & KMOD_SHIFT) ^ !!(ev.key.keysym.mod & KMOD_CAPS)) - keyvalue -= 'a'-'A'; - } - else if (ev.key.keysym.mod & KMOD_SHIFT) - { - keyvalue = g_keyAsciiTableShift[code]; - } - else if (ev.key.keysym.mod & KMOD_NUM) // && !(ev.key.keysym.mod & KMOD_SHIFT) - { - switch (keyvalue) - { - case SDLK_KP_1: keyvalue = '1'; break; - case SDLK_KP_2: keyvalue = '2'; break; - case SDLK_KP_3: keyvalue = '3'; break; - case SDLK_KP_4: keyvalue = '4'; break; - case SDLK_KP_5: keyvalue = '5'; break; - case SDLK_KP_6: keyvalue = '6'; break; - case SDLK_KP_7: keyvalue = '7'; break; - case SDLK_KP_8: keyvalue = '8'; break; - case SDLK_KP_9: keyvalue = '9'; break; - case SDLK_KP_0: keyvalue = '0'; break; - case SDLK_KP_PERIOD: keyvalue = '.'; break; - case SDLK_KP_COMMA: keyvalue = ','; break; - } - } - - switch (keyvalue) - { - case SDLK_KP_DIVIDE: keyvalue = '/'; break; - case SDLK_KP_MULTIPLY: keyvalue = '*'; break; - case SDLK_KP_MINUS: keyvalue = '-'; break; - case SDLK_KP_PLUS: keyvalue = '+'; break; - } - } - if (keyvalue >= 0x80) keyvalue = 0; // Sadly ASCII only... - return keyvalue; -} - -int32_t handleevents_pollsdl(void); -#if SDL_MAJOR_VERSION != 1 -// SDL 2.0 specific event handling -int32_t handleevents_pollsdl(void) -{ - int32_t code, rv=0, j; - SDL_Event ev; - - while (SDL_PollEvent(&ev)) - { - if ((GUICapture & 10) == 2) - { - if (ImGui_ImplSDL2_ProcessEvent(&ev)) return 0; - } - switch (ev.type) - { - case SDL_TEXTINPUT: - { - j = 0; - const uint8_t* text = (uint8_t*)ev.text.text; - while ((j = GetCharFromString(text))) - { - code = ev.text.text[j]; - // Fixme: Send an EV_GUI_Event instead and properly deal with Unicode. - if ((GUICapture & 1) && menuactive != MENU_WaitKey) - { - event_t ev = { EV_GUI_Event, EV_GUI_Char, int16_t(j), !!(SDL_GetModState() & KMOD_ALT) }; - D_PostEvent(&ev); - } - } - break; - } - - case SDL_KEYDOWN: - case SDL_KEYUP: - { - if ((GUICapture & 1) && menuactive != MENU_WaitKey) - { - event_t event = {}; - event.type = EV_GUI_Event; - event.subtype = ev.type == SDL_KEYDOWN ? EV_GUI_KeyDown : EV_GUI_KeyUp; - SDL_Keymod kmod = SDL_GetModState(); - event.data3 = ((kmod & KMOD_SHIFT) ? GKM_SHIFT : 0) | - ((kmod & KMOD_CTRL) ? GKM_CTRL : 0) | - ((kmod & KMOD_ALT) ? GKM_ALT : 0); - - if (event.subtype == EV_GUI_KeyDown && ev.key.repeat) - { - event.subtype = EV_GUI_KeyRepeat; - } - - switch (ev.key.keysym.sym) - { - case SDLK_KP_ENTER: event.data1 = GK_RETURN; break; - case SDLK_PAGEUP: event.data1 = GK_PGUP; break; - case SDLK_PAGEDOWN: event.data1 = GK_PGDN; break; - case SDLK_END: event.data1 = GK_END; break; - case SDLK_HOME: event.data1 = GK_HOME; break; - case SDLK_LEFT: event.data1 = GK_LEFT; break; - case SDLK_RIGHT: event.data1 = GK_RIGHT; break; - case SDLK_UP: event.data1 = GK_UP; break; - case SDLK_DOWN: event.data1 = GK_DOWN; break; - case SDLK_DELETE: event.data1 = GK_DEL; break; - case SDLK_ESCAPE: event.data1 = GK_ESCAPE; break; - case SDLK_F1: event.data1 = GK_F1; break; - case SDLK_F2: event.data1 = GK_F2; break; - case SDLK_F3: event.data1 = GK_F3; break; - case SDLK_F4: event.data1 = GK_F4; break; - case SDLK_F5: event.data1 = GK_F5; break; - case SDLK_F6: event.data1 = GK_F6; break; - case SDLK_F7: event.data1 = GK_F7; break; - case SDLK_F8: event.data1 = GK_F8; break; - case SDLK_F9: event.data1 = GK_F9; break; - case SDLK_F10: event.data1 = GK_F10; break; - case SDLK_F11: event.data1 = GK_F11; break; - case SDLK_F12: event.data1 = GK_F12; break; - default: - if (ev.key.keysym.sym < 256) - { - event.data1 = ev.key.keysym.sym; - } - break; - } - if (event.data1 < 128) - { - event.data1 = toupper(event.data1); - D_PostEvent(&event); - } - } - else - { - auto const& sc = ev.key.keysym.scancode; - code = keytranslation[sc]; - - // The pause key generates a release event right after - // the pressing one. As a result, it gets unseen - // by the game most of the time. - if (code == 0x59 && ev.type == SDL_KEYUP) // pause - break; - - int keyvalue = ev.type == SDL_KEYDOWN ? scancodetoasciihack(ev) : 0; - event_t evt = { (uint8_t)(ev.type == SDL_KEYUP ? EV_KeyUp : EV_KeyDown), 0, (int16_t)code, (int16_t)keyvalue }; - D_PostEvent(&evt); - } - - break; - } - - case SDL_MOUSEWHEEL: - // initprintf("wheel y %d\n",ev.wheel.y); - - // This never sends keyup events. For the current code that should suffice - if (ev.wheel.y > 0) - { - event_t evt = { EV_KeyDown, 0, (int16_t)KEY_MWHEELUP }; - D_PostEvent(&evt); - } - if (ev.wheel.y < 0) - { - event_t evt = { EV_KeyDown, 0, (int16_t)KEY_MWHEELDOWN }; - D_PostEvent(&evt); - } - break; - - case SDL_WINDOWEVENT: - switch (ev.window.event) - { - case SDL_WINDOWEVENT_FOCUS_GAINED: - case SDL_WINDOWEVENT_FOCUS_LOST: - appactive = (ev.window.event == SDL_WINDOWEVENT_FOCUS_GAINED); - if (g_mouseGrabbed && g_mouseEnabled) - grabmouse_low(appactive); - break; - - case SDL_WINDOWEVENT_MOVED: - { - if (windowpos) - { - windowx = ev.window.data1; - windowy = ev.window.data2; - } - - r_displayindex = SDL_GetWindowDisplayIndex(sdl_window); - modeschecked = 0; - videoGetModes(); - break; - } - case SDL_WINDOWEVENT_ENTER: - g_mouseInsideWindow = 1; - break; - case SDL_WINDOWEVENT_LEAVE: - g_mouseInsideWindow = 0; - break; - } - - break; - - default: - rv = handleevents_sdlcommon(&ev); - break; - } - } - MouseRead(); - - return rv; -} -#endif - -int32_t handleevents(void) -{ - int32_t rv; - - if (inputchecked && g_mouseEnabled) - { - // This is a horrible crutch - if (inputState.mouseReadButtons() & WHEELUP_MOUSE) - { - event_t ev = { EV_KeyUp, 0, (int16_t)KEY_MWHEELUP }; - D_PostEvent(&ev); - } - if (inputState.mouseReadButtons() & WHEELDOWN_MOUSE) - { - event_t ev = { EV_KeyUp, 0, (int16_t)KEY_MWHEELDOWN }; - D_PostEvent(&ev); - } - } - - rv = handleevents_pollsdl(); - - inputchecked = 0; - timerUpdateClock(); - return rv; -} - -void I_SetMouseCapture() -{ - // Clear out any mouse movement. - SDL_CaptureMouse(SDL_TRUE); -} - -void I_ReleaseMouseCapture() -{ - SDL_CaptureMouse(SDL_FALSE); -} - auto vsnprintfptr = vsnprintf; // This is an inline in Visual Studio but we need an address for it to satisfy the MinGW compiled libraries. // diff --git a/source/build/src/sdlkeytrans.cpp b/source/build/src/sdlkeytrans.cpp deleted file mode 100644 index 9cdd18ce7..000000000 --- a/source/build/src/sdlkeytrans.cpp +++ /dev/null @@ -1,263 +0,0 @@ - -#if (SDL_MAJOR_VERSION == 1 && SDL_MINOR_VERSION < 3) -static uint8_t keytranslation[SDLK_LAST]; -#else -static uint8_t keytranslation[SDL_NUM_SCANCODES]; -#endif -static int32_t buildkeytranslationtable(void); - -#if (SDL_MAJOR_VERSION == 1 && SDL_MINOR_VERSION < 3) // SDL 1.2 -static int32_t buildkeytranslationtable(void) -{ - memset(keytranslation,0,sizeof(keytranslation)); - -#define MAP(x,y) keytranslation[x] = y - MAP(SDLK_BACKSPACE, 0xe); - MAP(SDLK_TAB, 0xf); - MAP(SDLK_RETURN, 0x1c); - MAP(SDLK_PAUSE, 0x59); // 0x1d + 0x45 + 0x9d + 0xc5 - MAP(SDLK_ESCAPE, 0x1); - MAP(SDLK_SPACE, 0x39); - MAP(SDLK_EXCLAIM, 0x2); // '1' - MAP(SDLK_QUOTEDBL, 0x28); // ''' - MAP(SDLK_HASH, 0x4); // '3' - MAP(SDLK_DOLLAR, 0x5); // '4' - MAP(37, 0x6); // '5' <-- where's the keysym SDL guys? - MAP(SDLK_AMPERSAND, 0x8); // '7' - MAP(SDLK_QUOTE, 0x28); // ''' - MAP(SDLK_LEFTPAREN, 0xa); // '9' - MAP(SDLK_RIGHTPAREN, 0xb); // '0' - MAP(SDLK_ASTERISK, 0x9); // '8' - MAP(SDLK_PLUS, 0xd); // '=' - MAP(SDLK_COMMA, 0x33); - MAP(SDLK_MINUS, 0xc); - MAP(SDLK_PERIOD, 0x34); - MAP(SDLK_SLASH, 0x35); - MAP(SDLK_0, 0xb); - MAP(SDLK_1, 0x2); - MAP(SDLK_2, 0x3); - MAP(SDLK_3, 0x4); - MAP(SDLK_4, 0x5); - MAP(SDLK_5, 0x6); - MAP(SDLK_6, 0x7); - MAP(SDLK_7, 0x8); - MAP(SDLK_8, 0x9); - MAP(SDLK_9, 0xa); - MAP(SDLK_COLON, 0x27); - MAP(SDLK_SEMICOLON, 0x27); - MAP(SDLK_LESS, 0x56); - MAP(SDLK_EQUALS, 0xd); - MAP(SDLK_GREATER, 0x34); - MAP(SDLK_QUESTION, 0x35); - MAP(SDLK_AT, 0x3); // '2' - MAP(SDLK_LEFTBRACKET, 0x1a); - MAP(SDLK_BACKSLASH, 0x2b); - MAP(SDLK_RIGHTBRACKET, 0x1b); - MAP(SDLK_CARET, 0x7); // '7' - MAP(SDLK_UNDERSCORE, 0xc); - MAP(SDLK_BACKQUOTE, 0x29); - MAP(SDLK_a, 0x1e); - MAP(SDLK_b, 0x30); - MAP(SDLK_c, 0x2e); - MAP(SDLK_d, 0x20); - MAP(SDLK_e, 0x12); - MAP(SDLK_f, 0x21); - MAP(SDLK_g, 0x22); - MAP(SDLK_h, 0x23); - MAP(SDLK_i, 0x17); - MAP(SDLK_j, 0x24); - MAP(SDLK_k, 0x25); - MAP(SDLK_l, 0x26); - MAP(SDLK_m, 0x32); - MAP(SDLK_n, 0x31); - MAP(SDLK_o, 0x18); - MAP(SDLK_p, 0x19); - MAP(SDLK_q, 0x10); - MAP(SDLK_r, 0x13); - MAP(SDLK_s, 0x1f); - MAP(SDLK_t, 0x14); - MAP(SDLK_u, 0x16); - MAP(SDLK_v, 0x2f); - MAP(SDLK_w, 0x11); - MAP(SDLK_x, 0x2d); - MAP(SDLK_y, 0x15); - MAP(SDLK_z, 0x2c); - MAP(SDLK_DELETE, 0xd3); - MAP(SDLK_KP0, 0x52); - MAP(SDLK_KP1, 0x4f); - MAP(SDLK_KP2, 0x50); - MAP(SDLK_KP3, 0x51); - MAP(SDLK_KP4, 0x4b); - MAP(SDLK_KP5, 0x4c); - MAP(SDLK_KP6, 0x4d); - MAP(SDLK_KP7, 0x47); - MAP(SDLK_KP8, 0x48); - MAP(SDLK_KP9, 0x49); - MAP(SDLK_KP_PERIOD, 0x53); - MAP(SDLK_KP_DIVIDE, 0xb5); - MAP(SDLK_KP_MULTIPLY, 0x37); - MAP(SDLK_KP_MINUS, 0x4a); - MAP(SDLK_KP_PLUS, 0x4e); - MAP(SDLK_KP_ENTER, 0x9c); - //MAP(SDLK_KP_EQUALS, ); - MAP(SDLK_UP, 0xc8); - MAP(SDLK_DOWN, 0xd0); - MAP(SDLK_RIGHT, 0xcd); - MAP(SDLK_LEFT, 0xcb); - MAP(SDLK_INSERT, 0xd2); - MAP(SDLK_HOME, 0xc7); - MAP(SDLK_END, 0xcf); - MAP(SDLK_PAGEUP, 0xc9); - MAP(SDLK_PAGEDOWN, 0xd1); - MAP(SDLK_F1, 0x3b); - MAP(SDLK_F2, 0x3c); - MAP(SDLK_F3, 0x3d); - MAP(SDLK_F4, 0x3e); - MAP(SDLK_F5, 0x3f); - MAP(SDLK_F6, 0x40); - MAP(SDLK_F7, 0x41); - MAP(SDLK_F8, 0x42); - MAP(SDLK_F9, 0x43); - MAP(SDLK_F10, 0x44); - MAP(SDLK_F11, 0x57); - MAP(SDLK_F12, 0x58); - MAP(SDLK_NUMLOCK, 0x45); - MAP(SDLK_CAPSLOCK, 0x3a); - MAP(SDLK_SCROLLOCK, 0x46); - MAP(SDLK_RSHIFT, 0x36); - MAP(SDLK_LSHIFT, 0x2a); - MAP(SDLK_RCTRL, 0x9d); - MAP(SDLK_LCTRL, 0x1d); - MAP(SDLK_RALT, 0xb8); - MAP(SDLK_LALT, 0x38); - MAP(SDLK_LSUPER, 0xdb); // win l - MAP(SDLK_RSUPER, 0xdc); // win r - MAP(SDLK_PRINT, -2); // 0xaa + 0xb7 - MAP(SDLK_SYSREQ, 0x54); // alt+printscr - MAP(SDLK_BREAK, 0xb7); // ctrl+pause - MAP(SDLK_MENU, 0xdd); // win menu? -#undef MAP - - return 0; -} -#else // if SDL 1.3+ -static int32_t buildkeytranslationtable(void) -{ - memset(keytranslation,0,sizeof(keytranslation)); - -#define MAP(x,y) keytranslation[x] = y - MAP(SDL_SCANCODE_BACKSPACE, 0xe); - MAP(SDL_SCANCODE_TAB, 0xf); - MAP(SDL_SCANCODE_RETURN, 0x1c); - MAP(SDL_SCANCODE_PAUSE, 0x59); // 0x1d + 0x45 + 0x9d + 0xc5 - MAP(SDL_SCANCODE_ESCAPE, 0x1); - MAP(SDL_SCANCODE_SPACE, 0x39); - MAP(SDL_SCANCODE_COMMA, 0x33); - MAP(SDL_SCANCODE_NONUSBACKSLASH, 0x56); - MAP(SDL_SCANCODE_MINUS, 0xc); - MAP(SDL_SCANCODE_PERIOD, 0x34); - MAP(SDL_SCANCODE_SLASH, 0x35); - MAP(SDL_SCANCODE_0, 0xb); - MAP(SDL_SCANCODE_1, 0x2); - MAP(SDL_SCANCODE_2, 0x3); - MAP(SDL_SCANCODE_3, 0x4); - MAP(SDL_SCANCODE_4, 0x5); - MAP(SDL_SCANCODE_5, 0x6); - MAP(SDL_SCANCODE_6, 0x7); - MAP(SDL_SCANCODE_7, 0x8); - MAP(SDL_SCANCODE_8, 0x9); - MAP(SDL_SCANCODE_9, 0xa); - MAP(SDL_SCANCODE_SEMICOLON, 0x27); - MAP(SDL_SCANCODE_APOSTROPHE, 0x28); - MAP(SDL_SCANCODE_EQUALS, 0xd); - MAP(SDL_SCANCODE_LEFTBRACKET, 0x1a); - MAP(SDL_SCANCODE_BACKSLASH, 0x2b); - MAP(SDL_SCANCODE_RIGHTBRACKET, 0x1b); - MAP(SDL_SCANCODE_A, 0x1e); - MAP(SDL_SCANCODE_B, 0x30); - MAP(SDL_SCANCODE_C, 0x2e); - MAP(SDL_SCANCODE_D, 0x20); - MAP(SDL_SCANCODE_E, 0x12); - MAP(SDL_SCANCODE_F, 0x21); - MAP(SDL_SCANCODE_G, 0x22); - MAP(SDL_SCANCODE_H, 0x23); - MAP(SDL_SCANCODE_I, 0x17); - MAP(SDL_SCANCODE_J, 0x24); - MAP(SDL_SCANCODE_K, 0x25); - MAP(SDL_SCANCODE_L, 0x26); - MAP(SDL_SCANCODE_M, 0x32); - MAP(SDL_SCANCODE_N, 0x31); - MAP(SDL_SCANCODE_O, 0x18); - MAP(SDL_SCANCODE_P, 0x19); - MAP(SDL_SCANCODE_Q, 0x10); - MAP(SDL_SCANCODE_R, 0x13); - MAP(SDL_SCANCODE_S, 0x1f); - MAP(SDL_SCANCODE_T, 0x14); - MAP(SDL_SCANCODE_U, 0x16); - MAP(SDL_SCANCODE_V, 0x2f); - MAP(SDL_SCANCODE_W, 0x11); - MAP(SDL_SCANCODE_X, 0x2d); - MAP(SDL_SCANCODE_Y, 0x15); - MAP(SDL_SCANCODE_Z, 0x2c); - MAP(SDL_SCANCODE_DELETE, 0xd3); - MAP(SDL_SCANCODE_KP_0, 0x52); - MAP(SDL_SCANCODE_KP_1, 0x4f); - MAP(SDL_SCANCODE_KP_2, 0x50); - MAP(SDL_SCANCODE_KP_3, 0x51); - MAP(SDL_SCANCODE_KP_4, 0x4b); - MAP(SDL_SCANCODE_KP_5, 0x4c); - MAP(SDL_SCANCODE_KP_CLEAR, 0x4c); - MAP(SDL_SCANCODE_CLEAR, 0x4c); - MAP(SDL_SCANCODE_KP_6, 0x4d); - MAP(SDL_SCANCODE_KP_7, 0x47); - MAP(SDL_SCANCODE_KP_8, 0x48); - MAP(SDL_SCANCODE_KP_9, 0x49); - MAP(SDL_SCANCODE_KP_PERIOD, 0x53); - MAP(SDL_SCANCODE_KP_DIVIDE, 0xb5); - MAP(SDL_SCANCODE_KP_MULTIPLY, 0x37); - MAP(SDL_SCANCODE_KP_MINUS, 0x4a); - MAP(SDL_SCANCODE_KP_PLUS, 0x4e); - MAP(SDL_SCANCODE_KP_ENTER, 0x9c); - //MAP(SDL_SCANCODE_KP_EQUALS, ); - MAP(SDL_SCANCODE_UP, 0xc8); - MAP(SDL_SCANCODE_DOWN, 0xd0); - MAP(SDL_SCANCODE_RIGHT, 0xcd); - MAP(SDL_SCANCODE_LEFT, 0xcb); - MAP(SDL_SCANCODE_INSERT, 0xd2); - MAP(SDL_SCANCODE_HOME, 0xc7); - MAP(SDL_SCANCODE_END, 0xcf); - MAP(SDL_SCANCODE_PAGEUP, 0xc9); - MAP(SDL_SCANCODE_PAGEDOWN, 0xd1); - MAP(SDL_SCANCODE_F1, 0x3b); - MAP(SDL_SCANCODE_F2, 0x3c); - MAP(SDL_SCANCODE_F3, 0x3d); - MAP(SDL_SCANCODE_F4, 0x3e); - MAP(SDL_SCANCODE_F5, 0x3f); - MAP(SDL_SCANCODE_F6, 0x40); - MAP(SDL_SCANCODE_F7, 0x41); - MAP(SDL_SCANCODE_F8, 0x42); - MAP(SDL_SCANCODE_F9, 0x43); - MAP(SDL_SCANCODE_F10, 0x44); - MAP(SDL_SCANCODE_F11, 0x57); - MAP(SDL_SCANCODE_F12, 0x58); - MAP(SDL_SCANCODE_NUMLOCKCLEAR, 0x45); - MAP(SDL_SCANCODE_CAPSLOCK, 0x3a); - MAP(SDL_SCANCODE_SCROLLLOCK, 0x46); - MAP(SDL_SCANCODE_RSHIFT, 0x36); - MAP(SDL_SCANCODE_LSHIFT, 0x2a); - MAP(SDL_SCANCODE_RCTRL, 0x9d); - MAP(SDL_SCANCODE_LCTRL, 0x1d); - MAP(SDL_SCANCODE_RALT, 0xb8); - MAP(SDL_SCANCODE_LALT, 0x38); - MAP(SDL_SCANCODE_LGUI, 0xdb); // win l - MAP(SDL_SCANCODE_RGUI, 0xdc); // win r -// MAP(SDL_SCANCODE_PRINTSCREEN, -2); // 0xaa + 0xb7 - MAP(SDL_SCANCODE_SYSREQ, 0x54); // alt+printscr -// MAP(SDL_SCANCODE_PAUSE, 0xb7); // ctrl+pause - MAP(SDL_SCANCODE_MENU, 0xdd); // win menu? - MAP(SDL_SCANCODE_GRAVE, 0x29); // tilde -#undef MAP - - return 0; -} -#endif diff --git a/source/mact/src/animlib.cpp b/source/common/animlib.cpp similarity index 100% rename from source/mact/src/animlib.cpp rename to source/common/animlib.cpp diff --git a/source/mact/include/animlib.h b/source/common/animlib.h similarity index 100% rename from source/mact/include/animlib.h rename to source/common/animlib.h diff --git a/source/common/console/c_con.cpp b/source/common/console/c_con.cpp index df40bde31..a7db2650a 100644 --- a/source/common/console/c_con.cpp +++ b/source/common/console/c_con.cpp @@ -37,7 +37,6 @@ #include "basics.h" #include "zstring.h" #include "c_bind.h" -#include "control.h" #include "gamecontrol.h" //============================================================================= @@ -198,7 +197,7 @@ char const* C_CON_GetGameFuncOnJoystick(int gameFunc) FString C_CON_GetBoundKeyForLastInput(int gameFunc) { - if (CONTROL_LastSeenInput == LastSeenInput::Joystick) + if (inputState.gamePadActive()) { FString name = C_CON_GetGameFuncOnJoystick(gameFunc); if (name.IsNotEmpty()) diff --git a/source/common/console/d_event.cpp b/source/common/console/d_event.cpp index 03b424c8e..aa1772d18 100644 --- a/source/common/console/d_event.cpp +++ b/source/common/console/d_event.cpp @@ -105,8 +105,8 @@ void D_ProcessEvents (void) ev = &events[eventtail]; if (ev->type == EV_None) continue; - if (ev->type == EV_DeviceChange) - (void)0;//UpdateJoystickMenu(I_UpdateDeviceList()); + /*if (ev->type == EV_DeviceChange) + UpdateJoystickMenu(I_UpdateDeviceList());*/ if (C_Responder (ev)) continue; // console ate the event if (M_Responder (ev)) diff --git a/source/common/filesystem/resourcefile.cpp b/source/common/filesystem/resourcefile.cpp index 446db0deb..2773a34c0 100644 --- a/source/common/filesystem/resourcefile.cpp +++ b/source/common/filesystem/resourcefile.cpp @@ -299,7 +299,6 @@ void FResourceFile::PostProcessArchive(void *lumps, size_t lumpsize) // each one so that we don't risk refiltering already filtered lumps. uint32_t max = NumLumps; - long len; int lastpos = -1; FString file; diff --git a/source/common/gameconfigfile.cpp b/source/common/gameconfigfile.cpp index e045c2645..e8c360aae 100644 --- a/source/common/gameconfigfile.cpp +++ b/source/common/gameconfigfile.cpp @@ -40,14 +40,7 @@ #include "c_bind.h" #include "m_argv.h" #include "cmdlib.h" -//#include "version.h" #include "i_specialpaths.h" -//#include "v_font.h" -//#include "doomstat.h" -//#include "gi.h" -//#include "d_main.h" -#include "keyboard.h" -#include "control.h" #include "printf.h" #include "gamecontrol.h" #include "version.h" @@ -531,7 +524,6 @@ void G_SaveConfig() { GameConfig->ArchiveGlobalData(); GameConfig->ArchiveGameData(GameName); - CONFIG_WriteControllerSettings(); GameConfig->WriteConfigFile(); delete GameConfig; GameConfig = nullptr; diff --git a/source/common/gamecontrol.cpp b/source/common/gamecontrol.cpp index 5164b3aea..7fb1eed14 100644 --- a/source/common/gamecontrol.cpp +++ b/source/common/gamecontrol.cpp @@ -1,18 +1,36 @@ +//------------------------------------------------------------------------- +/* +Copyright (C) 2019 Christoph Oelckers + +This is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ +//------------------------------------------------------------------------- + #include #include "gamecontrol.h" #include "tarray.h" #include "zstring.h" #include "name.h" -#include "control.h" -#include "keyboard.h" #include "sc_man.h" #include "c_cvars.h" #include "gameconfigfile.h" #include "gamecvars.h" #include "build.h" #include "inputstate.h" -#include "_control.h" -#include "control.h" #include "m_argv.h" #include "rts.h" #include "printf.h" @@ -250,6 +268,9 @@ void CheckFrontend(int flags) } } +void I_StartupJoysticks(); +void I_ShutdownInput(); +int RunGame(); int GameMain() { @@ -257,6 +278,8 @@ int GameMain() C_InitConsole(1024, 768, true); FStringf logpath("logfile %sdemolition.log", M_GetDocumentsPath().GetChars()); C_DoCommand(logpath); + I_StartupJoysticks(); + mouseInit(); #ifndef NETCODE_DISABLE gHaveNetworking = !enet_initialize(); @@ -267,7 +290,7 @@ int GameMain() int r; try { - r = CONFIG_Init(); + r = RunGame(); } catch (const std::runtime_error & err) { @@ -279,6 +302,7 @@ int GameMain() // Just let the rest of the function execute. r = exit.Reason(); } + I_ShutdownInput(); G_SaveConfig(); #ifndef NETCODE_DISABLE if (gHaveNetworking) enet_deinitialize(); @@ -313,13 +337,6 @@ void SetDefaultStrings() quoteMgr.InitializeQuote(84, "$FOLLOW MODE ON"); quoteMgr.InitializeQuote(85, "$AUTORUNOFF"); quoteMgr.InitializeQuote(86, "$AUTORUNON"); - #if 0 // todo: print a message - if (gAutoRun) - viewSetMessage("Auto run ON"); - else - viewSetMessage("Auto run OFF"); - - #endif } //========================================================================== @@ -328,16 +345,10 @@ void SetDefaultStrings() // //========================================================================== -int CONFIG_Init() +int RunGame() { SetClipshapes(); - // This must be done before initializing any data, so doing it late in the startup process won't work. - if (CONTROL_Startup(controltype_keyboardandmouse, BGetTime, 120)) - { - return 1; - } - userConfig.ProcessOptions(); G_LoadConfig(); @@ -436,7 +447,6 @@ int CONFIG_Init() } TileFiles.AddArt(addArt); - CONTROL_ClearAssignments(); CONFIG_InitMouseAndController(); CONFIG_SetDefaultKeys(cl_defaultconfiguration == 1 ? "demolition/origbinds.txt" : cl_defaultconfiguration == 2 ? "demolition/leftbinds.txt" : "demolition/defbinds.txt"); @@ -526,288 +536,12 @@ int CONFIG_SetMapBestTime(uint8_t const* const mapmd4, int32_t tm) } return 0; } -//========================================================================== -// -// -// -//========================================================================== - -int32_t MouseAnalogueAxes[MAXMOUSEAXES]; -int32_t JoystickFunctions[MAXJOYBUTTONSANDHATS][2]; -int32_t JoystickDigitalFunctions[MAXJOYAXES][2]; -int32_t JoystickAnalogueAxes[MAXJOYAXES]; -int32_t JoystickAnalogueScale[MAXJOYAXES]; -int32_t JoystickAnalogueDead[MAXJOYAXES]; -int32_t JoystickAnalogueSaturate[MAXJOYAXES]; -int32_t JoystickAnalogueInvert[MAXJOYAXES]; - -static const char* mouseanalogdefaults[MAXMOUSEAXES] = -{ -"analog_turning", -"analog_moving", -}; - - -static const char* joystickclickeddefaults[MAXJOYBUTTONSANDHATS] = -{ -"", -"Inventory", -"Jump", -"Crouch", -}; - - -static const char* joystickanalogdefaults[MAXJOYAXES] = -{ -"analog_turning", -"analog_moving", -"analog_strafing", -}; - - -//========================================================================== -// -// -// -//========================================================================== - -int32_t CONFIG_AnalogNameToNum(const char* func) -{ - if (!func) - return -1; - - if (!Bstrcasecmp(func, "analog_turning")) - { - return analog_turning; - } - if (!Bstrcasecmp(func, "analog_strafing")) - { - return analog_strafing; - } - if (!Bstrcasecmp(func, "analog_moving")) - { - return analog_moving; - } - if (!Bstrcasecmp(func, "analog_lookingupanddown")) - { - return analog_lookingupanddown; - } - - return -1; -} - - -//========================================================================== -// -// -// -//========================================================================== - -const char* CONFIG_AnalogNumToName(int32_t func) -{ - switch (func) - { - case analog_turning: - return "analog_turning"; - case analog_strafing: - return "analog_strafing"; - case analog_moving: - return "analog_moving"; - case analog_lookingupanddown: - return "analog_lookingupanddown"; - } - - return NULL; -} - -void CONFIG_SetupMouse(void) -{ - CONTROL_MouseEnabled = (in_mouse && CONTROL_MousePresent); -} - - -void CONFIG_SetupJoystick(void) -{ - for (int i = 0; i < MAXJOYAXES; i++) - { - CONTROL_MapAnalogAxis(i, JoystickAnalogueAxes[i], controldevice_joystick); - CONTROL_MapDigitalAxis(i, JoystickDigitalFunctions[i][0], 0, controldevice_joystick); - CONTROL_MapDigitalAxis(i, JoystickDigitalFunctions[i][1], 1, controldevice_joystick); - CONTROL_SetAnalogAxisScale(i, JoystickAnalogueScale[i], controldevice_joystick); - CONTROL_SetAnalogAxisInvert(i, JoystickAnalogueInvert[i], controldevice_joystick); - } - - CONTROL_JoystickEnabled = (in_joystick && CONTROL_JoyPresent); - - // JBF 20040215: evil and nasty place to do this, but joysticks are evil and nasty too - for (int i=0; iSetValueForKey(key, str); -} - -void CONFIG_WriteControllerSettings() -{ - FString buf; - - - if (in_joystick) - { - FString section = currentGame + ".ControllerSettings"; - GameConfig->SetSection(section); - for (int dummy = 0; dummy < MAXJOYAXES; dummy++) - { - if (CONFIG_AnalogNumToName(JoystickAnalogueAxes[dummy])) - { - buf.Format("ControllerAnalogAxes%d", dummy); - GameConfig->SetValueForKey(buf, CONFIG_AnalogNumToName(JoystickAnalogueAxes[dummy])); - } - - if (buttonMap.GetButtonName(JoystickDigitalFunctions[dummy][1])) - { - buf.Format("ControllerDigitalAxes%d_1", dummy); - GameConfig->SetValueForKey(buf, buttonMap.GetButtonName(JoystickDigitalFunctions[dummy][1])); - } - - buf.Format("ControllerAnalogScale%d", dummy); - CONFIG_PutNumber(buf, JoystickAnalogueScale[dummy]); - - buf.Format("ControllerAnalogInvert%d", dummy); - CONFIG_PutNumber(buf, JoystickAnalogueInvert[dummy]); - - buf.Format("ControllerAnalogDead%d", dummy); - CONFIG_PutNumber(buf, JoystickAnalogueDead[dummy]); - - buf.Format("ControllerAnalogSaturate%d", dummy); - CONFIG_PutNumber(buf, JoystickAnalogueSaturate[dummy]); - } - } -} diff --git a/source/common/gamecontrol.h b/source/common/gamecontrol.h index b699693d8..5899375a6 100644 --- a/source/common/gamecontrol.h +++ b/source/common/gamecontrol.h @@ -1,8 +1,5 @@ #pragma once -#include "keyboard.h" -#include "control.h" -#include "_control.h" #include "c_cvars.h" #include "zstring.h" #include "inputstate.h" @@ -39,7 +36,6 @@ void CONFIG_SetDefaultKeys(const char *defbinds); void CONFIG_SetupJoystick(void); -void CONFIG_WriteControllerSettings(); void CONFIG_InitMouseAndController(); void CONFIG_SetGameControllerDefaultsClear(); diff --git a/source/common/gamecvars.cpp b/source/common/gamecvars.cpp index 5a4674b13..65c8be757 100644 --- a/source/common/gamecvars.cpp +++ b/source/common/gamecvars.cpp @@ -39,9 +39,6 @@ #include "fx_man.h" #include "baselayer.h" #include "gameconfigfile.h" -#include "keyboard.h" -#include "control.h" -#include "_control.h" #include "gamecontrol.h" #include "m_argv.h" #include "rts.h" @@ -292,16 +289,8 @@ CUSTOM_CVARD(Int, r_fov, 90, CVAR_ARCHIVE|CVAR_GLOBALCONFIG, "change the field o CVARD(Bool, r_horizcenter, false, CVAR_ARCHIVE|CVAR_FRONTEND_BLOOD, "enable/disable centered horizon line") // only present in Blood, maybe add to others? -CUSTOM_CVARD(Bool, in_joystick, false, CVAR_ARCHIVE||CVAR_GLOBALCONFIG|CVAR_NOINITCALL, "enables input from the joystick if it is present") -{ - CONTROL_JoystickEnabled = (self && CONTROL_JoyPresent); -} - -CUSTOM_CVARD(Bool, in_mouse, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL, "enables input from the mouse if it is present") -{ - CONTROL_MouseEnabled = (self && CONTROL_MousePresent); -} - +CVARD(Bool, in_joystick, false, CVAR_ARCHIVE||CVAR_GLOBALCONFIG|CVAR_NOINITCALL, "enables input from the joystick if it is present") +CVARD(Bool, in_mouse, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL, "enables input from the mouse if it is present") CVARD(Bool, in_mousemode, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG, "toggles vertical mouse view") CVAR(Bool, silentmouseaimtoggle, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) diff --git a/source/common/input/i_gui.cpp b/source/common/input/i_gui.cpp new file mode 100644 index 000000000..01a2362ca --- /dev/null +++ b/source/common/input/i_gui.cpp @@ -0,0 +1,87 @@ +/* +** i_gui.cpp +** +**--------------------------------------------------------------------------- +** Copyright 2008 Randy Heit +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +#include + +#include + +#include "bitmap.h" +//#include "v_palette.h" +#include "textures.h" + +bool I_SetCursor(FTexture *cursorpic) +{ + static SDL_Cursor *cursor; + static SDL_Surface *cursorSurface; + + if (cursorpic != NULL) + { + auto src = cursorpic->GetBgraBitmap(nullptr); + // Must be no larger than 32x32. + if (src.GetWidth() > 32 || src.GetHeight() > 32) + { + return false; + } + + if (cursorSurface == NULL) + cursorSurface = SDL_CreateRGBSurface (0, 32, 32, 32, MAKEARGB(0,255,0,0), MAKEARGB(0,0,255,0), MAKEARGB(0,0,0,255), MAKEARGB(255,0,0,0)); + + SDL_LockSurface(cursorSurface); + uint8_t buffer[32*32*4]; + memset(buffer, 0, 32*32*4); + FBitmap bmp(buffer, 32*4, 32, 32); + bmp.Blit(0, 0, src); // expand to 32*32 + memcpy(cursorSurface->pixels, bmp.GetPixels(), 32*32*4); + SDL_UnlockSurface(cursorSurface); + + if (cursor) + SDL_FreeCursor (cursor); + cursor = SDL_CreateColorCursor (cursorSurface, 0, 0); + SDL_SetCursor (cursor); + } + else + { + if (cursor) + { + SDL_SetCursor (NULL); + SDL_FreeCursor (cursor); + cursor = NULL; + } + if (cursorSurface != NULL) + { + SDL_FreeSurface(cursorSurface); + cursorSurface = NULL; + } + } + return true; +} diff --git a/source/common/input/i_input.cpp b/source/common/input/i_input.cpp new file mode 100644 index 000000000..ef30d1bcc --- /dev/null +++ b/source/common/input/i_input.cpp @@ -0,0 +1,748 @@ +/* +** This code is partially original EDuke32 code, partially taken from ZDoom +** +** For the portions taken from ZDoom the following applies: +** +**--------------------------------------------------------------------------- +** Copyright 2005-2016 Randy Heit +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +#include + +#include "m_argv.h" + +#include "c_buttons.h" +#include "d_event.h" +#include "d_gui.h" +#include "c_console.h" +#include "c_dispatch.h" +#include "c_cvars.h" +#include "keydef.h" +#include "utf8.h" +#include "menu/menu.h" + + +char grabmouse_low(char a); +void WindowMoved(int x, int y); +extern SDL_Window* sdl_window; + + +static uint8_t keytranslation[SDL_NUM_SCANCODES]; + +void buildkeytranslationtable(void) +{ + memset(keytranslation, 0, sizeof(keytranslation)); + +#define MAP(x,y) keytranslation[x] = y + MAP(SDL_SCANCODE_BACKSPACE, 0xe); + MAP(SDL_SCANCODE_TAB, 0xf); + MAP(SDL_SCANCODE_RETURN, 0x1c); + MAP(SDL_SCANCODE_PAUSE, 0x59); // 0x1d + 0x45 + 0x9d + 0xc5 + MAP(SDL_SCANCODE_ESCAPE, 0x1); + MAP(SDL_SCANCODE_SPACE, 0x39); + MAP(SDL_SCANCODE_COMMA, 0x33); + MAP(SDL_SCANCODE_NONUSBACKSLASH, 0x56); + MAP(SDL_SCANCODE_MINUS, 0xc); + MAP(SDL_SCANCODE_PERIOD, 0x34); + MAP(SDL_SCANCODE_SLASH, 0x35); + MAP(SDL_SCANCODE_0, 0xb); + MAP(SDL_SCANCODE_1, 0x2); + MAP(SDL_SCANCODE_2, 0x3); + MAP(SDL_SCANCODE_3, 0x4); + MAP(SDL_SCANCODE_4, 0x5); + MAP(SDL_SCANCODE_5, 0x6); + MAP(SDL_SCANCODE_6, 0x7); + MAP(SDL_SCANCODE_7, 0x8); + MAP(SDL_SCANCODE_8, 0x9); + MAP(SDL_SCANCODE_9, 0xa); + MAP(SDL_SCANCODE_SEMICOLON, 0x27); + MAP(SDL_SCANCODE_APOSTROPHE, 0x28); + MAP(SDL_SCANCODE_EQUALS, 0xd); + MAP(SDL_SCANCODE_LEFTBRACKET, 0x1a); + MAP(SDL_SCANCODE_BACKSLASH, 0x2b); + MAP(SDL_SCANCODE_RIGHTBRACKET, 0x1b); + MAP(SDL_SCANCODE_A, 0x1e); + MAP(SDL_SCANCODE_B, 0x30); + MAP(SDL_SCANCODE_C, 0x2e); + MAP(SDL_SCANCODE_D, 0x20); + MAP(SDL_SCANCODE_E, 0x12); + MAP(SDL_SCANCODE_F, 0x21); + MAP(SDL_SCANCODE_G, 0x22); + MAP(SDL_SCANCODE_H, 0x23); + MAP(SDL_SCANCODE_I, 0x17); + MAP(SDL_SCANCODE_J, 0x24); + MAP(SDL_SCANCODE_K, 0x25); + MAP(SDL_SCANCODE_L, 0x26); + MAP(SDL_SCANCODE_M, 0x32); + MAP(SDL_SCANCODE_N, 0x31); + MAP(SDL_SCANCODE_O, 0x18); + MAP(SDL_SCANCODE_P, 0x19); + MAP(SDL_SCANCODE_Q, 0x10); + MAP(SDL_SCANCODE_R, 0x13); + MAP(SDL_SCANCODE_S, 0x1f); + MAP(SDL_SCANCODE_T, 0x14); + MAP(SDL_SCANCODE_U, 0x16); + MAP(SDL_SCANCODE_V, 0x2f); + MAP(SDL_SCANCODE_W, 0x11); + MAP(SDL_SCANCODE_X, 0x2d); + MAP(SDL_SCANCODE_Y, 0x15); + MAP(SDL_SCANCODE_Z, 0x2c); + MAP(SDL_SCANCODE_DELETE, 0xd3); + MAP(SDL_SCANCODE_KP_0, 0x52); + MAP(SDL_SCANCODE_KP_1, 0x4f); + MAP(SDL_SCANCODE_KP_2, 0x50); + MAP(SDL_SCANCODE_KP_3, 0x51); + MAP(SDL_SCANCODE_KP_4, 0x4b); + MAP(SDL_SCANCODE_KP_5, 0x4c); + MAP(SDL_SCANCODE_KP_CLEAR, 0x4c); + MAP(SDL_SCANCODE_CLEAR, 0x4c); + MAP(SDL_SCANCODE_KP_6, 0x4d); + MAP(SDL_SCANCODE_KP_7, 0x47); + MAP(SDL_SCANCODE_KP_8, 0x48); + MAP(SDL_SCANCODE_KP_9, 0x49); + MAP(SDL_SCANCODE_KP_PERIOD, 0x53); + MAP(SDL_SCANCODE_KP_DIVIDE, 0xb5); + MAP(SDL_SCANCODE_KP_MULTIPLY, 0x37); + MAP(SDL_SCANCODE_KP_MINUS, 0x4a); + MAP(SDL_SCANCODE_KP_PLUS, 0x4e); + MAP(SDL_SCANCODE_KP_ENTER, 0x9c); + //MAP(SDL_SCANCODE_KP_EQUALS, ); + MAP(SDL_SCANCODE_UP, 0xc8); + MAP(SDL_SCANCODE_DOWN, 0xd0); + MAP(SDL_SCANCODE_RIGHT, 0xcd); + MAP(SDL_SCANCODE_LEFT, 0xcb); + MAP(SDL_SCANCODE_INSERT, 0xd2); + MAP(SDL_SCANCODE_HOME, 0xc7); + MAP(SDL_SCANCODE_END, 0xcf); + MAP(SDL_SCANCODE_PAGEUP, 0xc9); + MAP(SDL_SCANCODE_PAGEDOWN, 0xd1); + MAP(SDL_SCANCODE_F1, 0x3b); + MAP(SDL_SCANCODE_F2, 0x3c); + MAP(SDL_SCANCODE_F3, 0x3d); + MAP(SDL_SCANCODE_F4, 0x3e); + MAP(SDL_SCANCODE_F5, 0x3f); + MAP(SDL_SCANCODE_F6, 0x40); + MAP(SDL_SCANCODE_F7, 0x41); + MAP(SDL_SCANCODE_F8, 0x42); + MAP(SDL_SCANCODE_F9, 0x43); + MAP(SDL_SCANCODE_F10, 0x44); + MAP(SDL_SCANCODE_F11, 0x57); + MAP(SDL_SCANCODE_F12, 0x58); + MAP(SDL_SCANCODE_NUMLOCKCLEAR, 0x45); + MAP(SDL_SCANCODE_CAPSLOCK, 0x3a); + MAP(SDL_SCANCODE_SCROLLLOCK, 0x46); + MAP(SDL_SCANCODE_RSHIFT, 0x36); + MAP(SDL_SCANCODE_LSHIFT, 0x2a); + MAP(SDL_SCANCODE_RCTRL, 0x9d); + MAP(SDL_SCANCODE_LCTRL, 0x1d); + MAP(SDL_SCANCODE_RALT, 0xb8); + MAP(SDL_SCANCODE_LALT, 0x38); + MAP(SDL_SCANCODE_LGUI, 0xdb); // win l + MAP(SDL_SCANCODE_RGUI, 0xdc); // win r +// MAP(SDL_SCANCODE_PRINTSCREEN, -2); // 0xaa + 0xb7 + MAP(SDL_SCANCODE_SYSREQ, 0x54); // alt+printscr +// MAP(SDL_SCANCODE_PAUSE, 0xb7); // ctrl+pause + MAP(SDL_SCANCODE_MENU, 0xdd); // win menu? + MAP(SDL_SCANCODE_GRAVE, 0x29); // tilde +#undef MAP +} + + + +// +// initmouse() -- init mouse input +// +void mouseInit(void) +{ + mouseGrabInput(g_mouseEnabled = g_mouseLockedToWindow); // FIXME - SA +} + +// +// uninitmouse() -- uninit mouse input +// +void mouseUninit(void) +{ + mouseGrabInput(0); + g_mouseEnabled = 0; +} + + +// +// grabmouse_low() -- show/hide mouse cursor, lower level (doesn't check state). +// furthermore return 0 if successful. +// + +char grabmouse_low(char a) +{ + /* FIXME: Maybe it's better to make sure that grabmouse_low + is called only when a window is ready? */ + if (sdl_window) + SDL_SetWindowGrab(sdl_window, a ? SDL_TRUE : SDL_FALSE); + return SDL_SetRelativeMouseMode(a ? SDL_TRUE : SDL_FALSE); +} + +// +// grabmouse() -- show/hide mouse cursor +// +void mouseGrabInput(bool grab) +{ + if (appactive && g_mouseEnabled) + { + if ((grab != g_mouseGrabbed) && !grabmouse_low(grab)) + g_mouseGrabbed = grab; + } + else + g_mouseGrabbed = grab; + + inputState.MouseSetPos(0, 0); + SDL_ShowCursor(!grab ? SDL_ENABLE : SDL_DISABLE); + if (grab) GUICapture &= ~1; + else GUICapture |= 1; +} + + +// So this is how the engine handles text input? +// Argh. This is just gross. +int scancodetoasciihack(SDL_Event& ev) +{ + int sc = ev.key.keysym.scancode; + SDL_Keycode keyvalue = ev.key.keysym.sym; + int code = keytranslation[sc]; + // Modifiers that have to be held down to be effective + // (excludes KMOD_NUM, for example). + static const int MODIFIERS = + KMOD_LSHIFT | KMOD_RSHIFT | KMOD_LCTRL | KMOD_RCTRL | + KMOD_LALT | KMOD_RALT | KMOD_LGUI | KMOD_RGUI; + + // XXX: see osd.c, OSD_HandleChar(), there are more... + if ( + (sc == SDL_SCANCODE_RETURN || sc == SDL_SCANCODE_KP_ENTER || + sc == SDL_SCANCODE_ESCAPE || + sc == SDL_SCANCODE_BACKSPACE || + sc == SDL_SCANCODE_TAB || + (((ev.key.keysym.mod) & MODIFIERS) == KMOD_LCTRL && + (sc >= SDL_SCANCODE_A && sc <= SDL_SCANCODE_Z)))) + { + char keyvalue; + switch (sc) + { + case SDL_SCANCODE_RETURN: case SDL_SCANCODE_KP_ENTER: keyvalue = '\r'; break; + case SDL_SCANCODE_ESCAPE: keyvalue = 27; break; + case SDL_SCANCODE_BACKSPACE: keyvalue = '\b'; break; + case SDL_SCANCODE_TAB: keyvalue = '\t'; break; + default: keyvalue = sc - SDL_SCANCODE_A + 1; break; // Ctrl+A --> 1, etc. + } + } + else + { + /* + Necessary for Duke 3D's method of entering cheats to work without showing IMEs. + SDL_TEXTINPUT is preferable overall, but with bitmap fonts it has no advantage. + */ + // Note that this is not how text input is supposed to be handled! + + if ('a' <= keyvalue && keyvalue <= 'z') + { + if (!!(ev.key.keysym.mod & KMOD_SHIFT) ^ !!(ev.key.keysym.mod & KMOD_CAPS)) + keyvalue -= 'a' - 'A'; + } + else if (ev.key.keysym.mod & KMOD_SHIFT) + { + keyvalue = g_keyAsciiTableShift[code]; + } + else if (ev.key.keysym.mod & KMOD_NUM) // && !(ev.key.keysym.mod & KMOD_SHIFT) + { + switch (keyvalue) + { + case SDLK_KP_1: keyvalue = '1'; break; + case SDLK_KP_2: keyvalue = '2'; break; + case SDLK_KP_3: keyvalue = '3'; break; + case SDLK_KP_4: keyvalue = '4'; break; + case SDLK_KP_5: keyvalue = '5'; break; + case SDLK_KP_6: keyvalue = '6'; break; + case SDLK_KP_7: keyvalue = '7'; break; + case SDLK_KP_8: keyvalue = '8'; break; + case SDLK_KP_9: keyvalue = '9'; break; + case SDLK_KP_0: keyvalue = '0'; break; + case SDLK_KP_PERIOD: keyvalue = '.'; break; + case SDLK_KP_COMMA: keyvalue = ','; break; + } + } + + switch (keyvalue) + { + case SDLK_KP_DIVIDE: keyvalue = '/'; break; + case SDLK_KP_MULTIPLY: keyvalue = '*'; break; + case SDLK_KP_MINUS: keyvalue = '-'; break; + case SDLK_KP_PLUS: keyvalue = '+'; break; + } + } + if (keyvalue >= 0x80) keyvalue = 0; // Sadly ASCII only... + return keyvalue; +} + +static void PostMouseMove(int x, int y) +{ + static int lastx = 0, lasty = 0; + event_t ev = { 0,0,0,0,0,0,0 }; + + ev.x = x; + ev.y = y; + lastx = x; + lasty = y; + if (ev.x | ev.y) + { + ev.type = EV_Mouse; + D_PostEvent(&ev); + } +} + +CVAR(Bool, m_noprescale, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) + +static void MouseRead() +{ + int x, y; + +#if 0 + if (NativeMouse) + { + return; + } +#endif + + SDL_GetRelativeMouseState(&x, &y); + if (!m_noprescale) + { + x *= 3; + y *= 2; + } + if (x | y) + { + PostMouseMove(x, -y); + } +} + +int32_t handleevents_pollsdl(void) +{ + int32_t code, rv = 0, j; + SDL_Event ev; + event_t evt; + + while (SDL_PollEvent(&ev)) + { + switch (ev.type) + { + case SDL_TEXTINPUT: + { + j = 0; + const uint8_t* text = (uint8_t*)ev.text.text; + while ((j = GetCharFromString(text))) + { + code = ev.text.text[j]; + // Fixme: Send an EV_GUI_Event instead and properly deal with Unicode. + if ((GUICapture & 1) && menuactive != MENU_WaitKey) + { + evt = { EV_GUI_Event, EV_GUI_Char, int16_t(j), !!(SDL_GetModState() & KMOD_ALT) }; + D_PostEvent(&evt); + } + } + break; + } + + case SDL_KEYDOWN: + case SDL_KEYUP: + { + if ((GUICapture & 1) && menuactive != MENU_WaitKey) + { + evt = {}; + evt.type = EV_GUI_Event; + evt.subtype = ev.type == SDL_KEYDOWN ? EV_GUI_KeyDown : EV_GUI_KeyUp; + SDL_Keymod kmod = SDL_GetModState(); + evt.data3 = ((kmod & KMOD_SHIFT) ? GKM_SHIFT : 0) | + ((kmod & KMOD_CTRL) ? GKM_CTRL : 0) | + ((kmod & KMOD_ALT) ? GKM_ALT : 0); + + if (evt.subtype == EV_GUI_KeyDown && ev.key.repeat) + { + evt.subtype = EV_GUI_KeyRepeat; + } + + switch (ev.key.keysym.sym) + { + case SDLK_KP_ENTER: evt.data1 = GK_RETURN; break; + case SDLK_PAGEUP: evt.data1 = GK_PGUP; break; + case SDLK_PAGEDOWN: evt.data1 = GK_PGDN; break; + case SDLK_END: evt.data1 = GK_END; break; + case SDLK_HOME: evt.data1 = GK_HOME; break; + case SDLK_LEFT: evt.data1 = GK_LEFT; break; + case SDLK_RIGHT: evt.data1 = GK_RIGHT; break; + case SDLK_UP: evt.data1 = GK_UP; break; + case SDLK_DOWN: evt.data1 = GK_DOWN; break; + case SDLK_DELETE: evt.data1 = GK_DEL; break; + case SDLK_ESCAPE: evt.data1 = GK_ESCAPE; break; + case SDLK_F1: evt.data1 = GK_F1; break; + case SDLK_F2: evt.data1 = GK_F2; break; + case SDLK_F3: evt.data1 = GK_F3; break; + case SDLK_F4: evt.data1 = GK_F4; break; + case SDLK_F5: evt.data1 = GK_F5; break; + case SDLK_F6: evt.data1 = GK_F6; break; + case SDLK_F7: evt.data1 = GK_F7; break; + case SDLK_F8: evt.data1 = GK_F8; break; + case SDLK_F9: evt.data1 = GK_F9; break; + case SDLK_F10: evt.data1 = GK_F10; break; + case SDLK_F11: evt.data1 = GK_F11; break; + case SDLK_F12: evt.data1 = GK_F12; break; + default: + if (ev.key.keysym.sym < 256) + { + evt.data1 = ev.key.keysym.sym; + } + break; + } + if (evt.data1 < 128) + { + evt.data1 = toupper(evt.data1); + D_PostEvent(&evt); + } + } + else + { + auto const& sc = ev.key.keysym.scancode; + code = keytranslation[sc]; + + // The pause key generates a release event right after + // the pressing one. As a result, it gets unseen + // by the game most of the time. + if (code == 0x59 && ev.type == SDL_KEYUP) // pause + break; + + int keyvalue = ev.type == SDL_KEYDOWN ? scancodetoasciihack(ev) : 0; + event_t evt = { (uint8_t)(ev.type == SDL_KEYUP ? EV_KeyUp : EV_KeyDown), 0, (int16_t)code, (int16_t)keyvalue }; + D_PostEvent(&evt); + } + + break; + } + + case SDL_MOUSEWHEEL: + if (GUICapture) + { + evt.type = EV_GUI_Event; + + if (ev.wheel.y == 0) + evt.subtype = ev.wheel.x > 0 ? EV_GUI_WheelRight : EV_GUI_WheelLeft; + else + evt.subtype = ev.wheel.y > 0 ? EV_GUI_WheelUp : EV_GUI_WheelDown; + + SDL_Keymod kmod = SDL_GetModState(); + evt.data3 = ((kmod & KMOD_SHIFT) ? GKM_SHIFT : 0) | + ((kmod & KMOD_CTRL) ? GKM_CTRL : 0) | + ((kmod & KMOD_ALT) ? GKM_ALT : 0); + + D_PostEvent(&evt); + } + else + { + // This never sends keyup events. They must be delayed for this to work with game buttons. + if (ev.wheel.y > 0) + { + evt = { EV_KeyDown, 0, (int16_t)KEY_MWHEELUP }; + D_PostEvent(&evt); + } + if (ev.wheel.y < 0) + { + evt = { EV_KeyDown, 0, (int16_t)KEY_MWHEELDOWN }; + D_PostEvent(&evt); + } + if (ev.wheel.x > 0) + { + evt = { EV_KeyDown, 0, (int16_t)KEY_MWHEELRIGHT }; + D_PostEvent(&evt); + } + if (ev.wheel.y < 0) + { + evt = { EV_KeyDown, 0, (int16_t)KEY_MWHEELLEFT }; + D_PostEvent(&evt); + } + } + break; + + case SDL_WINDOWEVENT: + switch (ev.window.event) + { + case SDL_WINDOWEVENT_FOCUS_GAINED: + case SDL_WINDOWEVENT_FOCUS_LOST: + appactive = (ev.window.event == SDL_WINDOWEVENT_FOCUS_GAINED); + if (g_mouseGrabbed && g_mouseEnabled) + grabmouse_low(appactive); + break; + + case SDL_WINDOWEVENT_MOVED: + { + WindowMoved(ev.window.data1, ev.window.data2); + break; + } + case SDL_WINDOWEVENT_ENTER: + g_mouseInsideWindow = 1; + break; + case SDL_WINDOWEVENT_LEAVE: + g_mouseInsideWindow = 0; + break; + } + + break; + + case SDL_MOUSEMOTION: + //case SDL_JOYBALLMOTION: + { + // The menus need this, even in non GUI-capture mode + event_t event; + event.data1 = ev.motion.x; + event.data2 = ev.motion.y; + + //screen->ScaleCoordsFromWindow(event.data1, event.data2); + + event.type = EV_GUI_Event; + event.subtype = EV_GUI_MouseMove; + + SDL_Keymod kmod = SDL_GetModState(); + event.data3 = ((kmod & KMOD_SHIFT) ? GKM_SHIFT : 0) | + ((kmod & KMOD_CTRL) ? GKM_CTRL : 0) | + ((kmod & KMOD_ALT) ? GKM_ALT : 0); + + D_PostEvent(&event); + break; + } + + case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONUP: + + if (!GUICapture) + { + evt.type = ev.type == SDL_MOUSEBUTTONDOWN ? EV_KeyDown : EV_KeyUp; + + switch (ev.button.button) + { + case SDL_BUTTON_LEFT: evt.data1 = KEY_MOUSE1; break; + case SDL_BUTTON_MIDDLE: evt.data1 = KEY_MOUSE3; break; + case SDL_BUTTON_RIGHT: evt.data1 = KEY_MOUSE2; break; + case SDL_BUTTON_X1: evt.data1 = KEY_MOUSE4; break; + case SDL_BUTTON_X2: evt.data1 = KEY_MOUSE5; break; + case 6: evt.data1 = KEY_MOUSE6; break; + case 7: evt.data1 = KEY_MOUSE7; break; + case 8: evt.data1 = KEY_MOUSE8; break; + //default: printf("SDL mouse button %s %d\n", sev.type == SDL_MOUSEBUTTONDOWN ? "down" : "up", sev.button.button); break; + } + + if (evt.data1 != 0) + { + D_PostEvent(&evt); + } + } + else if ((ev.button.button >= SDL_BUTTON_LEFT && ev.button.button <= SDL_BUTTON_X2)) + { + int x, y; + SDL_GetMouseState(&x, &y); + + evt.type = EV_GUI_Event; + evt.data1 = x; + evt.data2 = y; + + //screen->ScaleCoordsFromWindow(event.data1, event.data2); + + if (ev.type == SDL_MOUSEBUTTONDOWN) + { + switch (ev.button.button) + { + case SDL_BUTTON_LEFT: evt.subtype = EV_GUI_LButtonDown; break; + case SDL_BUTTON_MIDDLE: evt.subtype = EV_GUI_MButtonDown; break; + case SDL_BUTTON_RIGHT: evt.subtype = EV_GUI_RButtonDown; break; + case SDL_BUTTON_X1: evt.subtype = EV_GUI_BackButtonDown; break; + case SDL_BUTTON_X2: evt.subtype = EV_GUI_FwdButtonDown; break; + default: assert(false); evt.subtype = EV_GUI_None; break; + } + } + else + { + switch (ev.button.button) + { + case SDL_BUTTON_LEFT: evt.subtype = EV_GUI_LButtonUp; break; + case SDL_BUTTON_MIDDLE: evt.subtype = EV_GUI_MButtonUp; break; + case SDL_BUTTON_RIGHT: evt.subtype = EV_GUI_RButtonUp; break; + case SDL_BUTTON_X1: evt.subtype = EV_GUI_BackButtonUp; break; + case SDL_BUTTON_X2: evt.subtype = EV_GUI_FwdButtonUp; break; + default: assert(false); evt.subtype = EV_GUI_None; break; + } + } + + SDL_Keymod kmod = SDL_GetModState(); + evt.data3 = ((kmod & KMOD_SHIFT) ? GKM_SHIFT : 0) | + ((kmod & KMOD_CTRL) ? GKM_CTRL : 0) | + ((kmod & KMOD_ALT) ? GKM_ALT : 0); + + D_PostEvent(&evt); + } + break; + +#if 0 + case SDL_JOYAXISMOTION: +#if SDL_MAJOR_VERSION >= 2 + if (joystick.isGameController) + break; + fallthrough__; + case SDL_CONTROLLERAXISMOTION: +#endif + if (appactive && ev.jaxis.axis < joystick.numAxes) + { + joystick.pAxis[ev.jaxis.axis] = ev.jaxis.value; + int32_t const scaledValue = ev.jaxis.value * 10000 / 32767; + if ((scaledValue < joydead[ev.jaxis.axis]) && + (scaledValue > -joydead[ev.jaxis.axis])) + joystick.pAxis[ev.jaxis.axis] = 0; + else if (scaledValue >= joysatur[ev.jaxis.axis]) + joystick.pAxis[ev.jaxis.axis] = 32767; + else if (scaledValue <= -joysatur[ev.jaxis.axis]) + joystick.pAxis[ev.jaxis.axis] = -32767; + else + joystick.pAxis[ev.jaxis.axis] = joystick.pAxis[ev.jaxis.axis] * 10000 / joysatur[ev.jaxis.axis]; + } + break; +#endif + + case SDL_JOYHATMOTION: + { + int32_t hatvals[16] = { + -1, // centre + 0, // up 1 + 9000, // right 2 + 4500, // up+right 3 + 18000, // down 4 + -1, // down+up!! 5 + 13500, // down+right 6 + -1, // down+right+up!! 7 + 27000, // left 8 + 27500, // left+up 9 + -1, // left+right!! 10 + -1, // left+right+up!! 11 + 22500, // left+down 12 + -1, // left+down+up!! 13 + -1, // left+down+right!! 14 + -1, // left+down+right+up!! 15 + }; + if (appactive && ev.jhat.hat < joystick.numHats) + joystick.pHat[ev.jhat.hat] = hatvals[ev.jhat.value & 15]; + break; + } + + case SDL_JOYBUTTONDOWN: + case SDL_JOYBUTTONUP: +#if 0 // SDL_MAJOR_VERSION >= 2 + if (joystick.isGameController) + break; + fallthrough__; + case SDL_CONTROLLERBUTTONDOWN: + case SDL_CONTROLLERBUTTONUP: +#endif + if (!GUICapture) + { + evt.type = ev.type == SDL_JOYBUTTONDOWN ? EV_KeyDown : EV_KeyUp; + evt.data1 = KEY_FIRSTJOYBUTTON + ev.jbutton.button; + if (evt.data1 != 0) + D_PostEvent(&evt); + } + break; + + case SDL_QUIT: + throw ExitEvent(0); // completely bypass the hackery in the games to block Alt-F4. + return -1; + + default: + break; + } + } + MouseRead(); + + return rv; +} + +int32_t handleevents(void) +{ + int32_t rv; + + if (inputchecked && g_mouseEnabled) + { + // This is a horrible crutch + if (inputState.mouseReadButtons() & WHEELUP_MOUSE) + { + event_t ev = { EV_KeyUp, 0, (int16_t)KEY_MWHEELUP }; + D_PostEvent(&ev); + } + if (inputState.mouseReadButtons() & WHEELDOWN_MOUSE) + { + event_t ev = { EV_KeyUp, 0, (int16_t)KEY_MWHEELDOWN }; + D_PostEvent(&ev); + } + if (inputState.mouseReadButtons() & WHEELLEFT_MOUSE) + { + event_t ev = { EV_KeyUp, 0, (int16_t)KEY_MWHEELLEFT }; + D_PostEvent(&ev); + } + if (inputState.mouseReadButtons() & WHEELRIGHT_MOUSE) + { + event_t ev = { EV_KeyUp, 0, (int16_t)KEY_MWHEELRIGHT }; + D_PostEvent(&ev); + } + } + + rv = handleevents_pollsdl(); + + inputchecked = 0; + timerUpdateClock(); + //I_ProcessJoysticks(); + return rv; +} + + +int32_t handleevents_peekkeys(void) +{ + SDL_PumpEvents(); + + return SDL_PeepEvents(NULL, 1, SDL_PEEKEVENT, SDL_KEYDOWN, SDL_KEYDOWN); +} + +void I_SetMouseCapture() +{ + // Clear out any mouse movement. + SDL_CaptureMouse(SDL_TRUE); +} + +void I_ReleaseMouseCapture() +{ + SDL_CaptureMouse(SDL_FALSE); +} diff --git a/source/common/input/i_joystick.cpp b/source/common/input/i_joystick.cpp new file mode 100644 index 000000000..695a44686 --- /dev/null +++ b/source/common/input/i_joystick.cpp @@ -0,0 +1,342 @@ +/* +** i_joystick.cpp +** +**--------------------------------------------------------------------------- +** Copyright 2005-2016 Randy Heit +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ +#include + +#include "basics.h" +#include "templates.h" +#include "m_joy.h" +#include "keydef.h" + +// Very small deadzone so that floating point magic doesn't happen +#define MIN_DEADZONE 0.000001f + +class SDLInputJoystick: public IJoystickConfig +{ +public: + SDLInputJoystick(int DeviceIndex) : DeviceIndex(DeviceIndex), Multiplier(1.0f) + { + Device = SDL_JoystickOpen(DeviceIndex); + if(Device != NULL) + { + NumAxes = SDL_JoystickNumAxes(Device); + NumHats = SDL_JoystickNumHats(Device); + + SetDefaultConfig(); + } + } + ~SDLInputJoystick() + { + if(Device != NULL) + M_SaveJoystickConfig(this); + SDL_JoystickClose(Device); + } + + bool IsValid() const + { + return Device != NULL; + } + + FString GetName() + { + return SDL_JoystickName(Device); + } + float GetSensitivity() + { + return Multiplier; + } + void SetSensitivity(float scale) + { + Multiplier = scale; + } + + int GetNumAxes() + { + return NumAxes + NumHats*2; + } + float GetAxisDeadZone(int axis) + { + return Axes[axis].DeadZone; + } + EJoyAxis GetAxisMap(int axis) + { + return Axes[axis].GameAxis; + } + const char *GetAxisName(int axis) + { + return Axes[axis].Name.GetChars(); + } + float GetAxisScale(int axis) + { + return Axes[axis].Multiplier; + } + + void SetAxisDeadZone(int axis, float zone) + { + Axes[axis].DeadZone = clamp(zone, MIN_DEADZONE, 1.f); + } + void SetAxisMap(int axis, EJoyAxis gameaxis) + { + Axes[axis].GameAxis = gameaxis; + } + void SetAxisScale(int axis, float scale) + { + Axes[axis].Multiplier = scale; + } + + // Used by the saver to not save properties that are at their defaults. + bool IsSensitivityDefault() + { + return Multiplier == 1.0f; + } + bool IsAxisDeadZoneDefault(int axis) + { + return Axes[axis].DeadZone <= MIN_DEADZONE; + } + bool IsAxisMapDefault(int axis) + { + if(axis >= 5) + return Axes[axis].GameAxis == JOYAXIS_None; + return Axes[axis].GameAxis == DefaultAxes[axis]; + } + bool IsAxisScaleDefault(int axis) + { + return Axes[axis].Multiplier == 1.0f; + } + + void SetDefaultConfig() + { + for(int i = 0;i < GetNumAxes();i++) + { + AxisInfo info; + if(i < NumAxes) + info.Name.Format("Axis %d", i+1); + else + info.Name.Format("Hat %d (%c)", (i-NumAxes)/2 + 1, (i-NumAxes)%2 == 0 ? 'x' : 'y'); + info.DeadZone = MIN_DEADZONE; + info.Multiplier = 1.0f; + info.Value = 0.0; + info.ButtonValue = 0; + if(i >= 5) + info.GameAxis = JOYAXIS_None; + else + info.GameAxis = DefaultAxes[i]; + Axes.Push(info); + } + } + FString GetIdentifier() + { + char id[16]; + snprintf(id, countof(id), "JS:%d", DeviceIndex); + return id; + } + + void AddAxes(float axes[NUM_JOYAXIS]) + { + // Add to game axes. + for (int i = 0; i < GetNumAxes(); ++i) + { + if(Axes[i].GameAxis != JOYAXIS_None) + axes[Axes[i].GameAxis] -= float(Axes[i].Value * Multiplier * Axes[i].Multiplier); + } + } + + void ProcessInput() + { + uint8_t buttonstate; + + for (int i = 0; i < NumAxes; ++i) + { + buttonstate = 0; + + Axes[i].Value = SDL_JoystickGetAxis(Device, i)/32767.0; + Axes[i].Value = Joy_RemoveDeadZone(Axes[i].Value, Axes[i].DeadZone, &buttonstate); + + // Map button to axis + // X and Y are handled differently so if we have 2 or more axes then we'll use that code instead. + if (NumAxes == 1 || (i >= 2 && i < NUM_JOYAXISBUTTONS)) + { + Joy_GenerateButtonEvents(Axes[i].ButtonValue, buttonstate, 2, KEY_JOYAXIS1PLUS + i*2); + Axes[i].ButtonValue = buttonstate; + } + } + + if(NumAxes > 1) + { + buttonstate = Joy_XYAxesToButtons(Axes[0].Value, Axes[1].Value); + Joy_GenerateButtonEvents(Axes[0].ButtonValue, buttonstate, 4, KEY_JOYAXIS1PLUS); + Axes[0].ButtonValue = buttonstate; + } + + // Map POV hats to buttons and axes. Why axes? Well apparently I have + // a gamepad where the left control stick is a POV hat (instead of the + // d-pad like you would expect, no that's pressure sensitive). Also + // KDE's joystick dialog maps them to axes as well. + for (int i = 0; i < NumHats; ++i) + { + AxisInfo &x = Axes[NumAxes + i*2]; + AxisInfo &y = Axes[NumAxes + i*2 + 1]; + + buttonstate = SDL_JoystickGetHat(Device, i); + + // If we're going to assume that we can pass SDL's value into + // Joy_GenerateButtonEvents then we might as well assume the format here. + if(buttonstate & 0x1) // Up + y.Value = -1.0; + else if(buttonstate & 0x4) // Down + y.Value = 1.0; + else + y.Value = 0.0; + if(buttonstate & 0x2) // Left + x.Value = 1.0; + else if(buttonstate & 0x8) // Right + x.Value = -1.0; + else + x.Value = 0.0; + + if(i < 4) + { + Joy_GenerateButtonEvents(x.ButtonValue, buttonstate, 4, KEY_JOYPOV1_UP + i*4); + x.ButtonValue = buttonstate; + } + } + } + +protected: + struct AxisInfo + { + FString Name; + float DeadZone; + float Multiplier; + EJoyAxis GameAxis; + double Value; + uint8_t ButtonValue; + }; + static const EJoyAxis DefaultAxes[5]; + + int DeviceIndex; + SDL_Joystick *Device; + + float Multiplier; + TArray Axes; + int NumAxes; + int NumHats; +}; +const EJoyAxis SDLInputJoystick::DefaultAxes[5] = {JOYAXIS_Side, JOYAXIS_Forward, JOYAXIS_Pitch, JOYAXIS_Yaw, JOYAXIS_Up}; + +class SDLInputJoystickManager +{ +public: + SDLInputJoystickManager() + { + for(int i = 0;i < SDL_NumJoysticks();i++) + { + SDLInputJoystick *device = new SDLInputJoystick(i); + if(device->IsValid()) + Joysticks.Push(device); + else + delete device; + } + } + ~SDLInputJoystickManager() + { + for(unsigned int i = 0;i < Joysticks.Size();i++) + delete Joysticks[i]; + } + + void AddAxes(float axes[NUM_JOYAXIS]) + { + for(unsigned int i = 0;i < Joysticks.Size();i++) + Joysticks[i]->AddAxes(axes); + } + void GetDevices(TArray &sticks) + { + for(unsigned int i = 0;i < Joysticks.Size();i++) + { + M_LoadJoystickConfig(Joysticks[i]); + sticks.Push(Joysticks[i]); + } + } + + void ProcessInput() const + { + for(unsigned int i = 0;i < Joysticks.Size();++i) + Joysticks[i]->ProcessInput(); + } +protected: + TArray Joysticks; +}; +static SDLInputJoystickManager *JoystickManager; + +void I_StartupJoysticks() +{ + if(SDL_InitSubSystem(SDL_INIT_JOYSTICK) >= 0) + JoystickManager = new SDLInputJoystickManager(); +} +void I_ShutdownInput() +{ + if(JoystickManager) + { + delete JoystickManager; + SDL_QuitSubSystem(SDL_INIT_JOYSTICK); + } +} + +void I_GetJoysticks(TArray &sticks) +{ + sticks.Clear(); + + JoystickManager->GetDevices(sticks); +} + +void I_GetAxes(float axes[NUM_JOYAXIS]) +{ + for (int i = 0; i < NUM_JOYAXIS; ++i) + { + axes[i] = 0; + } + if (use_joystick) + { + JoystickManager->AddAxes(axes); + } +} + +void I_ProcessJoysticks() +{ + if (use_joystick && JoystickManager) + JoystickManager->ProcessInput(); +} + +IJoystickConfig *I_UpdateDeviceList() +{ + return NULL; +} diff --git a/source/mact/src/input.cpp b/source/common/input/input.cpp similarity index 84% rename from source/mact/src/input.cpp rename to source/common/input/input.cpp index 3687637a7..0b7f25939 100644 --- a/source/mact/src/input.cpp +++ b/source/common/input/input.cpp @@ -21,10 +21,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //------------------------------------------------------------------------- #include "gamecontrol.h" -#include "keyboard.h" -#include "mouse.h" -#include "joystick.h" -#include "control.h" #include "input.h" #include "inputstate.h" @@ -41,14 +37,15 @@ int32_t I_CheckAllInput(void) return inputState.keyBufferWaiting() || inputState.MouseGetButtons() - || JOYSTICK_GetButtons(); + //|| JOYSTICK_GetButtons() + ; } void I_ClearAllInput(void) { inputState.keyFlushChars(); inputState.ClearKeysDown(); inputState.MouseClearAllButtonss(); - JOYSTICK_ClearAllButtons(); + //JOYSTICK_ClearAllButtons(); buttonMap.ResetButtonStates(); } @@ -59,7 +56,7 @@ int32_t I_TextSubmit(void) inputState.GetKeyStatus(sc_Enter) || inputState.GetKeyStatus(sc_kpad_Enter) || mouseInactiveConditional(inputState.MouseGetButtons()&LEFT_MOUSE) - || (JOYSTICK_GetGameControllerButtons()&(1< +#include "vectors.h" +#include "m_joy.h" +#include "gameconfigfile.h" +#include "d_event.h" + +// MACROS ------------------------------------------------------------------ + +// TYPES ------------------------------------------------------------------- + +// EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- + +// PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- + +// PRIVATE FUNCTION PROTOTYPES --------------------------------------------- + +// EXTERNAL DATA DECLARATIONS ---------------------------------------------- + +#if 0 +EXTERN_CVAR(Bool, joy_ps2raw) +EXTERN_CVAR(Bool, joy_dinput) +EXTERN_CVAR(Bool, joy_xinput) +#endif + +// PUBLIC DATA DEFINITIONS ------------------------------------------------- + +CUSTOM_CVAR(Bool, use_joystick, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL) +{ +#if 0//def _WIN32 + joy_ps2raw.Callback(); + joy_dinput.Callback(); + joy_xinput.Callback(); +#endif +} + +// PRIVATE DATA DEFINITIONS ------------------------------------------------ + +// Bits 0 is X+, 1 is X-, 2 is Y+, and 3 is Y-. +static uint8_t JoyAngleButtons[8] = { 1, 1+4, 4, 2+4, 2, 2+8, 8, 1+8 }; + +// CODE -------------------------------------------------------------------- + +//========================================================================== +// +// IJoystickConfig - Virtual Destructor +// +//========================================================================== + +IJoystickConfig::~IJoystickConfig() +{ +} + +//========================================================================== +// +// M_SetJoystickConfigSection +// +// Sets up the config for reading or writing this controller's axis config. +// +//========================================================================== + +static bool M_SetJoystickConfigSection(IJoystickConfig *joy, bool create) +{ + FString id = "Joy:"; + id += joy->GetIdentifier(); + return GameConfig->SetSection(id, create); +} + +//========================================================================== +// +// M_LoadJoystickConfig +// +//========================================================================== + +bool M_LoadJoystickConfig(IJoystickConfig *joy) +{ + char key[32]; + const char *value; + int axislen; + int numaxes; + + joy->SetDefaultConfig(); + if (!M_SetJoystickConfigSection(joy, false)) + { + return false; + } + value = GameConfig->GetValueForKey("Sensitivity"); + if (value != NULL) + { + joy->SetSensitivity((float)atof(value)); + } + numaxes = joy->GetNumAxes(); + for (int i = 0; i < numaxes; ++i) + { + axislen = snprintf(key, countof(key), "Axis%u", i); + + snprintf(key + axislen, countof(key) - axislen, "deadzone"); + value = GameConfig->GetValueForKey(key); + if (value != NULL) + { + joy->SetAxisDeadZone(i, (float)atof(value)); + } + + snprintf(key + axislen, countof(key) - axislen, "scale"); + value = GameConfig->GetValueForKey(key); + if (value != NULL) + { + joy->SetAxisScale(i, (float)atof(value)); + } + + snprintf(key + axislen, countof(key) - axislen, "map"); + value = GameConfig->GetValueForKey(key); + if (value != NULL) + { + EJoyAxis gameaxis = (EJoyAxis)atoi(value); + if (gameaxis < JOYAXIS_None || gameaxis >= NUM_JOYAXIS) + { + gameaxis = JOYAXIS_None; + } + joy->SetAxisMap(i, gameaxis); + } + } + return true; +} + +//========================================================================== +// +// M_SaveJoystickConfig +// +// Only saves settings that are not at their defaults. +// +//========================================================================== + +void M_SaveJoystickConfig(IJoystickConfig *joy) +{ + char key[32], value[32]; + int axislen, numaxes; + + if (M_SetJoystickConfigSection(joy, true)) + { + GameConfig->ClearCurrentSection(); + if (!joy->IsSensitivityDefault()) + { + snprintf(value, countof(value), "%g", joy->GetSensitivity()); + GameConfig->SetValueForKey("Sensitivity", value); + } + numaxes = joy->GetNumAxes(); + for (int i = 0; i < numaxes; ++i) + { + axislen = snprintf(key, countof(key), "Axis%u", i); + + if (!joy->IsAxisDeadZoneDefault(i)) + { + snprintf(key + axislen, countof(key) - axislen, "deadzone"); + snprintf(value, countof(value), "%g", joy->GetAxisDeadZone(i)); + GameConfig->SetValueForKey(key, value); + } + if (!joy->IsAxisScaleDefault(i)) + { + snprintf(key + axislen, countof(key) - axislen, "scale"); + snprintf(value, countof(value), "%g", joy->GetAxisScale(i)); + GameConfig->SetValueForKey(key, value); + } + if (!joy->IsAxisMapDefault(i)) + { + snprintf(key + axislen, countof(key) - axislen, "map"); + snprintf(value, countof(value), "%d", joy->GetAxisMap(i)); + GameConfig->SetValueForKey(key, value); + } + } + // If the joystick is entirely at its defaults, delete this section + // so that we don't write out a lone section header. + if (GameConfig->SectionIsEmpty()) + { + GameConfig->DeleteCurrentSection(); + } + } +} + + +//=========================================================================== +// +// Joy_RemoveDeadZone +// +//=========================================================================== + +double Joy_RemoveDeadZone(double axisval, double deadzone, uint8_t *buttons) +{ + uint8_t butt; + + // Cancel out deadzone. + if (fabs(axisval) < deadzone) + { + axisval = 0; + butt = 0; + } + // Make the dead zone the new 0. + else if (axisval < 0) + { + axisval = (axisval + deadzone) / (1.0 - deadzone); + butt = 2; // button minus + } + else + { + axisval = (axisval - deadzone) / (1.0 - deadzone); + butt = 1; // button plus + } + if (buttons != NULL) + { + *buttons = butt; + } + return axisval; +} + +//=========================================================================== +// +// Joy_XYAxesToButtons +// +// Given two axes, returns a button set for them. They should have already +// been sent through Joy_RemoveDeadZone. For axes that share the same +// physical stick, the angle the stick forms should determine whether or +// not the four component buttons are present. Going by deadzone alone gives +// you huge areas where you have to buttons pressed and thin strips where +// you only have one button pressed. For DirectInput gamepads, there is +// not much standard for how the right stick is presented, so we can only +// do this for the left stick for those, since X and Y axes are pretty +// standard. For XInput and Raw PS2 controllers, both sticks are processed +// through here. +// +//=========================================================================== + +int Joy_XYAxesToButtons(double x, double y) +{ + if (x == 0 && y == 0) + { + return 0; + } + double rad = atan2(y, x); + if (rad < 0) + { + rad += 2*pi::pi(); + } + // The circle is divided into eight segments for corresponding + // button combinations. Each segment is pi/4 radians wide. We offset + // by half this so that the segments are centered around the ideal lines + // their buttons represent instead of being right on the lines. + rad += pi::pi()/8; // Offset + rad *= 4/pi::pi(); // Convert range from [0,2pi) to [0,8) + return JoyAngleButtons[int(rad) & 7]; +} + +//=========================================================================== +// +// Joy_GenerateButtonEvents +// +// Provided two bitmasks for a set of buttons, generates events to reflect +// any changes from the old to new set, where base is the key for bit 0, +// base+1 is the key for bit 1, etc. +// +//=========================================================================== + +void Joy_GenerateButtonEvents(int oldbuttons, int newbuttons, int numbuttons, int base) +{ + int changed = oldbuttons ^ newbuttons; + if (changed != 0) + { + event_t ev = { 0, 0, 0, 0, 0, 0, 0 }; + int mask = 1; + for (int j = 0; j < numbuttons; mask <<= 1, ++j) + { + if (changed & mask) + { + ev.data1 = base + j; + ev.type = (newbuttons & mask) ? EV_KeyDown : EV_KeyUp; + D_PostEvent(&ev); + } + } + } +} + +void Joy_GenerateButtonEvents(int oldbuttons, int newbuttons, int numbuttons, const int *keys) +{ + int changed = oldbuttons ^ newbuttons; + if (changed != 0) + { + event_t ev = { 0, 0, 0, 0, 0, 0, 0 }; + int mask = 1; + for (int j = 0; j < numbuttons; mask <<= 1, ++j) + { + if (changed & mask) + { + ev.data1 = keys[j]; + ev.type = (newbuttons & mask) ? EV_KeyDown : EV_KeyUp; + D_PostEvent(&ev); + } + } + } +} diff --git a/source/common/input/m_joy.h b/source/common/input/m_joy.h new file mode 100644 index 000000000..90cea3e14 --- /dev/null +++ b/source/common/input/m_joy.h @@ -0,0 +1,65 @@ +#ifndef M_JOY_H +#define M_JOY_H + +#include +#include "tarray.h" +#include "c_cvars.h" + +enum EJoyAxis +{ + JOYAXIS_None = -1, + JOYAXIS_Yaw, + JOYAXIS_Pitch, + JOYAXIS_Forward, + JOYAXIS_Side, + JOYAXIS_Up, +// JOYAXIS_Roll, // Ha ha. No roll for you. + NUM_JOYAXIS, +}; + +// Generic configuration interface for a controller. +struct IJoystickConfig +{ + virtual ~IJoystickConfig() = 0; + + virtual FString GetName() = 0; + virtual float GetSensitivity() = 0; + virtual void SetSensitivity(float scale) = 0; + + virtual int GetNumAxes() = 0; + virtual float GetAxisDeadZone(int axis) = 0; + virtual EJoyAxis GetAxisMap(int axis) = 0; + virtual const char *GetAxisName(int axis) = 0; + virtual float GetAxisScale(int axis) = 0; + + virtual void SetAxisDeadZone(int axis, float zone) = 0; + virtual void SetAxisMap(int axis, EJoyAxis gameaxis) = 0; + virtual void SetAxisScale(int axis, float scale) = 0; + + // Used by the saver to not save properties that are at their defaults. + virtual bool IsSensitivityDefault() = 0; + virtual bool IsAxisDeadZoneDefault(int axis) = 0; + virtual bool IsAxisMapDefault(int axis) = 0; + virtual bool IsAxisScaleDefault(int axis) = 0; + + virtual void SetDefaultConfig() = 0; + virtual FString GetIdentifier() = 0; +}; + +EXTERN_CVAR(Bool, use_joystick); + +bool M_LoadJoystickConfig(IJoystickConfig *joy); +void M_SaveJoystickConfig(IJoystickConfig *joy); + +void Joy_GenerateButtonEvents(int oldbuttons, int newbuttons, int numbuttons, int base); +void Joy_GenerateButtonEvents(int oldbuttons, int newbuttons, int numbuttons, const int *keys); +int Joy_XYAxesToButtons(double x, double y); +double Joy_RemoveDeadZone(double axisval, double deadzone, uint8_t *buttons); + +// These ought to be provided by a system-specific i_input.cpp. +void I_GetAxes(float axes[NUM_JOYAXIS]); +void I_GetJoysticks(TArray &sticks); +IJoystickConfig *I_UpdateDeviceList(); +extern void UpdateJoystickMenu(IJoystickConfig *); + +#endif diff --git a/source/common/inputstate.cpp b/source/common/inputstate.cpp index f5a3e6ced..ef7c45452 100644 --- a/source/common/inputstate.cpp +++ b/source/common/inputstate.cpp @@ -83,6 +83,8 @@ void InputState::AddEvent(const event_t *ev) case KEY_MOUSE4 : mouseSetBit(THUMB_MOUSE, ev->type == EV_KeyDown); break; case KEY_MWHEELUP: mouseSetBit(WHEELUP_MOUSE, ev->type == EV_KeyDown); break; case KEY_MWHEELDOWN: mouseSetBit(WHEELDOWN_MOUSE, ev->type == EV_KeyDown); break; + case KEY_MWHEELLEFT: mouseSetBit(WHEELLEFT_MOUSE, ev->type == EV_KeyDown); break; + case KEY_MWHEELRIGHT: mouseSetBit(WHEELRIGHT_MOUSE, ev->type == EV_KeyDown); break; case KEY_MOUSE5: mouseSetBit(THUMB2_MOUSE, ev->type == EV_KeyDown); break; default: break; } diff --git a/source/common/inputstate.h b/source/common/inputstate.h index 12b973ca3..ab977dd0c 100644 --- a/source/common/inputstate.h +++ b/source/common/inputstate.h @@ -7,6 +7,8 @@ #include "c_buttons.h" #include "d_event.h" #include "osd.h" +#include "m_joy.h" +#include "gamecvars.h" extern char appactive; @@ -21,8 +23,6 @@ enum MAXMOUSEBUTTONS = 10, }; -extern bool CONTROL_BindsEnabled; - extern bool g_mouseGrabbed; extern bool g_mouseEnabled; extern bool g_mouseInsideWindow; @@ -39,6 +39,8 @@ enum EMouseBits WHEELUP_MOUSE = 16, WHEELDOWN_MOUSE= 32, THUMB2_MOUSE = 64, + WHEELLEFT_MOUSE = 128, + WHEELRIGHT_MOUSE = 256, }; enum @@ -135,8 +137,6 @@ public: void SetBindsEnabled(bool on) { - // This just forwards the setting - CONTROL_BindsEnabled = on; } bool keyBufferWaiting() @@ -296,6 +296,12 @@ public: { g_mouseAbs = { x, y }; } + + bool gamePadActive() + { + // fixme: This needs to be tracked. + return false; + } int32_t MouseGetButtons(void) { return mouseReadButtons(); } inline void MouseClearButton(int32_t b) { g_mouseBits &= ~b; } inline void MouseClearAllButtonss(void) { g_mouseBits = 0; } @@ -311,7 +317,28 @@ public: }; - - extern InputState inputState; +inline void CONTROL_GetInput(ControlInfo* info) +{ + memset(info, 0, sizeof(ControlInfo)); + + if (in_mouse) + inputState.GetMouseDelta(info); + + if (in_joystick) + { + // Handle joysticks/game controllers. + float joyaxes[NUM_JOYAXIS]; + + I_GetAxes(joyaxes); + + info->dyaw += joyaxes[JOYAXIS_Yaw]; + info->dx += joyaxes[JOYAXIS_Side]; + info->dz += joyaxes[JOYAXIS_Forward]; + info->dpitch += joyaxes[JOYAXIS_Pitch]; + } +} + + + diff --git a/source/common/menu/joystickmenu.cpp b/source/common/menu/joystickmenu.cpp index 18a1e5af6..40b0a4136 100644 --- a/source/common/menu/joystickmenu.cpp +++ b/source/common/menu/joystickmenu.cpp @@ -42,11 +42,11 @@ #include "c_bind.h" #include "d_event.h" #include "d_gui.h" +#include "input/m_joy.h" #define NO_IMP #include "optionmenuitems.h" -#if 0 // This requires the entire ZDoom backend to work. static TArray Joysticks; IJoystickConfig *SELECTED_JOYSTICK; @@ -245,10 +245,10 @@ public: mJoy = joy; } - bool Activate() + bool Activate(FName caller) override { UpdateJoystickConfigMenu(mJoy); - return FOptionMenuItemSubmenu::Activate(); + return FOptionMenuItemSubmenu::Activate(caller); } }; @@ -273,51 +273,50 @@ FOptionMenuDescriptor *UpdateJoystickConfigMenu(IJoystickConfig *joy) } if (joy == NULL) { - opt->mTitle = "Configure Controller"; - it = new FOptionMenuItemStaticText("Invalid controller specified for menu", false); + opt->mTitle = "$JOYMNU_TITLE"; + it = new FOptionMenuItemStaticText("$JOYMNU_INVALID"); opt->mItems.Push(it); } else { - opt->mTitle.Format("Configure %s", joy->GetName().GetChars()); + opt->mTitle.Format("%s", joy->GetName().GetChars()); SELECTED_JOYSTICK = joy; - it = new FOptionMenuSliderJoySensitivity("Overall sensitivity", 0, 2, 0.1, 3); + it = new FOptionMenuSliderJoySensitivity("$JOYMNU_OVRSENS", 0, 2, 0.1, 3); opt->mItems.Push(it); - it = new FOptionMenuItemStaticText(" ", false); + it = new FOptionMenuItemStaticText(" "); opt->mItems.Push(it); if (joy->GetNumAxes() > 0) { - it = new FOptionMenuItemStaticText("Axis Configuration", true); + it = new FOptionMenuItemStaticText("$JOYMNU_AXIS"); opt->mItems.Push(it); for (int i = 0; i < joy->GetNumAxes(); ++i) { - it = new FOptionMenuItemStaticText(" ", false); + it = new FOptionMenuItemStaticText(" "); opt->mItems.Push(it); it = new FOptionMenuItemJoyMap(joy->GetAxisName(i), i, "JoyAxisMapNames", false); opt->mItems.Push(it); - it = new FOptionMenuSliderJoyScale("Overall sensitivity", i, 0, 4, 0.1, 3); + it = new FOptionMenuSliderJoyScale("$JOYMNU_OVRSENS", i, 0, 4, 0.1, 3); opt->mItems.Push(it); - it = new FOptionMenuItemInverter("Invert", i, false); + it = new FOptionMenuItemInverter("$JOYMNU_INVERT", i, false); opt->mItems.Push(it); - it = new FOptionMenuSliderJoyDeadZone("Dead Zone", i, 0, 0.9, 0.05, 3); + it = new FOptionMenuSliderJoyDeadZone("$JOYMNU_DEADZONE", i, 0, 0.9, 0.05, 3); opt->mItems.Push(it); } } else { - it = new FOptionMenuItemStaticText("No configurable axes", false); + it = new FOptionMenuItemStaticText("$JOYMNU_NOAXES"); opt->mItems.Push(it); } } opt->mScrollPos = 0; opt->mSelectedItem = -1; opt->mIndent = 0; - opt->mPosition = -25; opt->CalcIndent(); return opt; } @@ -333,6 +332,7 @@ void UpdateJoystickMenu(IJoystickConfig *selected) { FOptionMenuDescriptor *opt = (FOptionMenuDescriptor *)*desc; FOptionMenuItem *it; + for(unsigned i=0;imItems.Size();i++) { delete opt->mItems[i]; @@ -360,9 +360,9 @@ void UpdateJoystickMenu(IJoystickConfig *selected) } // Todo: Block joystick for changing this one. - it = new FOptionMenuItemOption("Enable controller support", "use_joystick", "YesNo", NULL, false); + it = new FOptionMenuItemOption("$JOYMNU_ENABLE", "use_joystick", "YesNo", NULL, false); opt->mItems.Push(it); - #ifdef _WIN32 + #if 0//def _WIN32 it = new FOptionMenuItemOption("Enable DirectInput controllers", "joy_dinput", "YesNo", NULL, false); opt->mItems.Push(it); it = new FOptionMenuItemOption("Enable XInput controllers", "joy_xinput", "YesNo", NULL, false); @@ -371,24 +371,24 @@ void UpdateJoystickMenu(IJoystickConfig *selected) opt->mItems.Push(it); #endif - it = new FOptionMenuItemStaticText(" ", false); + it = new FOptionMenuItemStaticText(" "); opt->mItems.Push(it); if (Joysticks.Size() == 0) { - it = new FOptionMenuItemStaticText("No controllers detected", false); + it = new FOptionMenuItemStaticText("$JOYMNU_NOCON"); opt->mItems.Push(it); if (!use_joystick) { - it = new FOptionMenuItemStaticText("Controller support must be", false); + it = new FOptionMenuItemStaticText("$JOYMNU_DISABLED1"); opt->mItems.Push(it); - it = new FOptionMenuItemStaticText("enabled to detect any", false); + it = new FOptionMenuItemStaticText("$JOYMNU_DISABLED1"); opt->mItems.Push(it); } } else { - it = new FOptionMenuItemStaticText("Configure controllers:", false); + it = new FOptionMenuItemStaticText("$JOYMNU_CONFIG"); opt->mItems.Push(it); for (int i = 0; i < (int)Joysticks.Size(); ++i) @@ -417,7 +417,7 @@ void UpdateJoystickMenu(IJoystickConfig *selected) if (i == (int)Joysticks.Size()) { SELECTED_JOYSTICK = NULL; - if (DMenu::CurrentMenu != NULL && DMenu::CurrentMenu->IsKindOf(RUNTIME_CLASS(DJoystickConfigMenu))) + if (DMenu::CurrentMenu != NULL && dynamic_cast(DMenu::CurrentMenu)) { DMenu::CurrentMenu->Close(); } @@ -425,4 +425,9 @@ void UpdateJoystickMenu(IJoystickConfig *selected) } } -#endif \ No newline at end of file +static TMenuClassDescriptor _im("JoystickConfigMenu"); + +void RegisterJoystickMenus() +{ + menuClasses.Push(&_im); +} diff --git a/source/common/menu/menu.cpp b/source/common/menu/menu.cpp index e1265fd2c..1d893c972 100644 --- a/source/common/menu/menu.cpp +++ b/source/common/menu/menu.cpp @@ -53,6 +53,7 @@ #include "build.h" #include "baselayer.h" #include "statistics.h" +#include "input/m_joy.h" void RegisterDukeMenus(); void RegisterRedneckMenus(); @@ -60,6 +61,8 @@ void RegisterBloodMenus(); void RegisterSWMenus(); void RegisterLoadsaveMenus(); void RegisterOptionMenus(); +void RegisterJoystickMenus(); +void UpdateJoystickMenu(IJoystickConfig* joy); extern bool rotatesprite_2doverride; bool help_disabled, credits_disabled; int g_currentMenu; // accessible by CON scripts - contains the current menu's script ID if defined or INT_MAX if none given. @@ -953,8 +956,10 @@ void M_Init (void) RegisterSWMenus(); RegisterLoadsaveMenus(); RegisterOptionMenus(); + RegisterJoystickMenus(); timerSetCallback(M_Ticker); M_ParseMenuDefs(); + UpdateJoystickMenu(nullptr); } diff --git a/source/common/utility/namedef.h b/source/common/utility/namedef.h index 3fdb641b3..643d1378a 100644 --- a/source/common/utility/namedef.h +++ b/source/common/utility/namedef.h @@ -43,4 +43,7 @@ xx(EndgameMenu) xx(Mididevices) xx(Aldevices) xx(Alresamplers) -xx(AdvSoundOptions) \ No newline at end of file +xx(AdvSoundOptions) +xx(JoystickConfigMenu) +xx(JoystickOptions) + diff --git a/source/duke3d/CMakeLists.txt b/source/duke3d/CMakeLists.txt index b3169684e..2a969f8b6 100644 --- a/source/duke3d/CMakeLists.txt +++ b/source/duke3d/CMakeLists.txt @@ -14,7 +14,6 @@ endif() include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/../build/include - ${CMAKE_CURRENT_SOURCE_DIR}/../mact/include ${CMAKE_CURRENT_SOURCE_DIR}/../audiolib/include ${CMAKE_CURRENT_SOURCE_DIR}/../libsmackerdec/include ${CMAKE_CURRENT_SOURCE_DIR}/../thirdparty/include @@ -25,6 +24,7 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/../common/fonts ${CMAKE_CURRENT_SOURCE_DIR}/../common/2d ${CMAKE_CURRENT_SOURCE_DIR}/../common/music + ${CMAKE_CURRENT_SOURCE_DIR}/../common/input ${CMAKE_CURRENT_SOURCE_DIR}/../platform ) diff --git a/source/duke3d/src/anim.cpp b/source/duke3d/src/anim.cpp index 3af7e8d8d..081f85777 100644 --- a/source/duke3d/src/anim.cpp +++ b/source/duke3d/src/anim.cpp @@ -26,7 +26,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "renderlayer.h" #include "duke3d.h" #include "animlib.h" -#include "mouse.h" #include "compat.h" #include "input.h" diff --git a/source/duke3d/src/duke3d.h b/source/duke3d/src/duke3d.h index 21e187a22..5153b823e 100644 --- a/source/duke3d/src/duke3d.h +++ b/source/duke3d/src/duke3d.h @@ -30,7 +30,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "cache1d.h" #include "compat.h" #include "fx_man.h" -#include "keyboard.h" #include "pragmas.h" #include "polymost.h" #include "gamecvars.h" @@ -112,7 +111,6 @@ EDUKE32_STATIC_ASSERT(7 <= MAXTILES-MAXUSERTILES); #include "actors.h" #include "common_game.h" #include "config.h" -#include "control.h" #include "gamecontrol.h" #include "game.h" #include "gamedef.h" diff --git a/source/duke3d/src/game.cpp b/source/duke3d/src/game.cpp index 644425f06..7101a1fff 100644 --- a/source/duke3d/src/game.cpp +++ b/source/duke3d/src/game.cpp @@ -5434,7 +5434,6 @@ static void G_Cleanup(void) void G_Shutdown(void) { S_SoundShutdown(); - CONTROL_Shutdown(); engineUnInit(); G_Cleanup(); } diff --git a/source/duke3d/src/gamestructures.cpp b/source/duke3d/src/gamestructures.cpp index 9ea044ae4..f698b7912 100644 --- a/source/duke3d/src/gamestructures.cpp +++ b/source/duke3d/src/gamestructures.cpp @@ -1548,7 +1548,7 @@ int32_t __fastcall VM_GetUserdef(int32_t labelNum, int const lParm2) case USERDEFS_DRAW_Y: labelNum = rotatesprite_y_offset; break; case USERDEFS_DRAW_YXASPECT: labelNum = rotatesprite_yxaspect; break; case USERDEFS_FOV: labelNum = r_fov; break; - case USERDEFS_GAMEPADACTIVE: labelNum = (CONTROL_LastSeenInput == LastSeenInput::Joystick); break; + case USERDEFS_GAMEPADACTIVE: labelNum = inputState.gamePadActive(); break; default: EDUKE32_UNREACHABLE_SECTION(labelNum = -1; break); } diff --git a/source/mact/gpl-2.0.txt b/source/mact/gpl-2.0.txt deleted file mode 100644 index d159169d1..000000000 --- a/source/mact/gpl-2.0.txt +++ /dev/null @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. diff --git a/source/mact/include/_control.h b/source/mact/include/_control.h deleted file mode 100644 index b3198bf09..000000000 --- a/source/mact/include/_control.h +++ /dev/null @@ -1,173 +0,0 @@ -//------------------------------------------------------------------------- -/* -Copyright (C) 1996, 2003 - 3D Realms Entertainment - -This file is NOT part of Duke Nukem 3D version 1.5 - Atomic Edition -However, it is either an older version of a file that is, or is -some test code written during the development of Duke Nukem 3D. -This file is provided purely for educational interest. - -Duke Nukem 3D is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms -*/ -//------------------------------------------------------------------------- - -//**************************************************************************** -// -// Private header for CONTROL.C -// -//**************************************************************************** - -#pragma once - -#ifndef control_private_h_ -#define control_private_h_ - -#include "compat.h" -#include "keyboard.h" - - -//**************************************************************************** -// -// DEFINES -// -//**************************************************************************** - -#define AXISUNDEFINED 0x7f -#define BUTTONUNDEFINED 0x7f -#define KEYUNDEFINED 0x7f - -#define THRESHOLD (0x200 * 32767 / 10000) -#define MINTHRESHOLD (0x80 * 32767 / 10000) - -#define DEFAULTMOUSESENSITIVITY 4 // 0x7000+MINIMUMMOUSESENSITIVITY - -#define INSTANT_ONOFF 0 -#define TOGGLE_ONOFF 1 - -#define MAXCONTROLVALUE 0x7fff - -// Number of Mouse buttons - -//#define MAXMOUSEBUTTONS 10 - -// Number of JOY buttons -// KEEPINSYNC duke3d/src/gamedefs.h, build/src/sdlayer.cpp -#define MAXJOYBUTTONS 32 -#define MAXJOYBUTTONSANDHATS (MAXJOYBUTTONS+4) - -// Number of JOY axes -// KEEPINSYNC duke3d/src/gamedefs.h, build/src/sdlayer.cpp -#define MAXJOYAXES 9 -#define MAXJOYDIGITAL (MAXJOYAXES*2) - -// NORMAL axis scale -#define NORMALAXISSCALE 65536 - -#define LIMITCONTROL(x) (*x = clamp(*x, -MAXCONTROLVALUE, MAXCONTROLVALUE)) - -//**************************************************************************** -// -// TYPEDEFS -// -//**************************************************************************** - -typedef enum -{ - motion_Left = -1, - motion_Up = -1, - motion_None = 0, - motion_Right = 1, - motion_Down = 1 -} motion; - - -typedef struct -{ - int32_t joyMinX; - int32_t joyMinY; - int32_t threshMinX; - int32_t threshMinY; - int32_t threshMaxX; - int32_t threshMaxY; - int32_t joyMaxX; - int32_t joyMaxY; - int32_t joyMultXL; - int32_t joyMultYL; - int32_t joyMultXH; - int32_t joyMultYH; -} JoystickDef; - -// int32_t ThrottleMin; -// int32_t RudderMin; -// int32_t ThrottlethreshMin; -// int32_t RudderthreshMin; -// int32_t ThrottlethreshMax; -// int32_t RudderthreshMax; -// int32_t ThrottleMax; -// int32_t RudderMax; -// int32_t ThrottleMultL; -// int32_t RudderMultL; -// int32_t ThrottleMultH; -// int32_t RudderMultH; - - -typedef struct -{ - uint8_t active; - uint8_t used; - uint8_t toggle; - uint8_t buttonheld; - int32_t cleared; -} controlflags; - -typedef struct -{ - kb_scancode key1; - kb_scancode key2; -} controlkeymaptype; - -typedef struct -{ - uint8_t singleclicked; - uint8_t doubleclicked; - uint16_t extra; -} controlbuttontype; - -typedef struct -{ - uint8_t analogmap; - uint8_t minmap; - uint8_t maxmap; - uint8_t extra; -} controlaxismaptype; - -typedef struct -{ - int32_t analog; - int8_t digital; - int8_t digitalClearedN, digitalClearedP; -} controlaxistype; - - -//*************************************************************************** -// -// PROTOTYPES -// -//*************************************************************************** - -#endif diff --git a/source/mact/include/control.h b/source/mact/include/control.h deleted file mode 100644 index 9756bed4c..000000000 --- a/source/mact/include/control.h +++ /dev/null @@ -1,169 +0,0 @@ -//------------------------------------------------------------------------- -/* -Copyright (C) 1996, 2003 - 3D Realms Entertainment - -This file is part of Duke Nukem 3D version 1.5 - Atomic Edition - -Duke Nukem 3D is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -Original Source: 1996 - Todd Replogle -Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms -Modifications for JonoF's port by Jonathon Fowler (jf@jonof.id.au) -*/ -//------------------------------------------------------------------------- - -//*************************************************************************** -// -// Public header for CONTROL.C. -// -//*************************************************************************** - -#pragma once - -#ifndef control_public_h_ -#define control_public_h_ - -#include "tarray.h" -#include "inputstate.h" - -//*************************************************************************** -// -// DEFINES -// -//*************************************************************************** - -//*************************************************************************** -// -// TYPEDEFS -// -//*************************************************************************** -typedef enum - { - axis_up, - axis_down, - axis_left, - axis_right - } axisdirection; - -typedef enum - { - analog_turning=0, - analog_strafing=1, - analog_lookingupanddown=2, - analog_elevation=3, - analog_rolling=4, - analog_moving=5, - analog_maxtype - } analogcontrol; - -typedef enum - { - controltype_keyboard, - controltype_keyboardandmouse, - controltype_keyboardandjoystick - } controltype; - -typedef enum - { - controldevice_keyboard, - controldevice_mouse, - controldevice_joystick - } controldevice; - -enum GameControllerButton : int -{ - GAMECONTROLLER_BUTTON_INVALID = -1, - GAMECONTROLLER_BUTTON_A, - GAMECONTROLLER_BUTTON_B, - GAMECONTROLLER_BUTTON_X, - GAMECONTROLLER_BUTTON_Y, - GAMECONTROLLER_BUTTON_BACK, - GAMECONTROLLER_BUTTON_GUIDE, - GAMECONTROLLER_BUTTON_START, - GAMECONTROLLER_BUTTON_LEFTSTICK, - GAMECONTROLLER_BUTTON_RIGHTSTICK, - GAMECONTROLLER_BUTTON_LEFTSHOULDER, - GAMECONTROLLER_BUTTON_RIGHTSHOULDER, - GAMECONTROLLER_BUTTON_DPAD_UP, - GAMECONTROLLER_BUTTON_DPAD_DOWN, - GAMECONTROLLER_BUTTON_DPAD_LEFT, - GAMECONTROLLER_BUTTON_DPAD_RIGHT, - GAMECONTROLLER_BUTTON_MAX -}; - -enum GameControllerAxis : int -{ - GAMECONTROLLER_AXIS_INVALID = -1, - GAMECONTROLLER_AXIS_LEFTX, - GAMECONTROLLER_AXIS_LEFTY, - GAMECONTROLLER_AXIS_RIGHTX, - GAMECONTROLLER_AXIS_RIGHTY, - GAMECONTROLLER_AXIS_TRIGGERLEFT, - GAMECONTROLLER_AXIS_TRIGGERRIGHT, - GAMECONTROLLER_AXIS_MAX -}; - -enum class LastSeenInput : unsigned char -{ - Keyboard, - Joystick, -}; - -//*************************************************************************** -// -// GLOBALS -// -//*************************************************************************** - -extern bool CONTROL_Started; -extern bool CONTROL_MousePresent; -extern bool CONTROL_JoyPresent; -extern bool CONTROL_MouseEnabled; -extern bool CONTROL_JoystickEnabled; - -extern LastSeenInput CONTROL_LastSeenInput; - - -//*************************************************************************** -// -// PROTOTYPES -// -//*************************************************************************** -void CONTROL_ClearAssignments( void ); -void CONTROL_GetInput( ControlInfo *info ); - -bool CONTROL_Startup(controltype which, int32_t ( *TimeFunction )( void ), int32_t ticspersecond); -void CONTROL_Shutdown( void ); - -void CONTROL_MapAnalogAxis(int whichaxis, int whichanalog, controldevice device); -void CONTROL_MapDigitalAxis(int32_t whichaxis, int32_t whichfunction, int32_t direction, controldevice device); -void CONTROL_SetAnalogAxisScale(int32_t whichaxis, int32_t axisscale, controldevice device); -void CONTROL_SetAnalogAxisInvert(int32_t whichaxis, int32_t invert, controldevice device); - -void CONTROL_ScanForControllers(void); - -int32_t CONTROL_GetGameControllerDigitalAxisPos(int32_t axis); -int32_t CONTROL_GetGameControllerDigitalAxisNeg(int32_t axis); -void CONTROL_ClearGameControllerDigitalAxisPos(int32_t axis); -void CONTROL_ClearGameControllerDigitalAxisNeg(int32_t axis); - - -////////// KEY/MOUSE BIND STUFF ////////// - - -//////////////////// - -#endif diff --git a/source/mact/include/joystick.h b/source/mact/include/joystick.h deleted file mode 100644 index 5696ae52e..000000000 --- a/source/mact/include/joystick.h +++ /dev/null @@ -1,31 +0,0 @@ - -#ifndef __joystick_h -#define __joystick_h - - - -#define HAT_CENTERED 0x00 -#define HAT_UP 0x01 -#define HAT_RIGHT 0x02 -#define HAT_DOWN 0x04 -#define HAT_LEFT 0x08 -#define HAT_RIGHTUP (HAT_RIGHT|HAT_UP) -#define HAT_RIGHTDOWN (HAT_RIGHT|HAT_DOWN) -#define HAT_LEFTUP (HAT_LEFT|HAT_UP) -#define HAT_LEFTDOWN (HAT_LEFT|HAT_DOWN) - -int32_t JOYSTICK_GetButtons( void ); -int32_t JOYSTICK_GetGameControllerButtons( void ); -int32_t JOYSTICK_ClearButton( int32_t b ); -void JOYSTICK_ClearGameControllerButton( int32_t b ); -void JOYSTICK_ClearAllButtons( void ); - -int32_t JOYSTICK_GetHat( int32_t h ); -void JOYSTICK_ClearHat( int32_t h ); -void JOYSTICK_ClearAllHats( void ); - -int32_t JOYSTICK_GetAxis( int32_t a ); -void JOYSTICK_ClearAxis( int32_t a ); -void JOYSTICK_ClearAllAxes( void ); - -#endif /* __joystick_h */ diff --git a/source/mact/include/mouse.h b/source/mact/include/mouse.h deleted file mode 100644 index e69de29bb..000000000 diff --git a/source/mact/src/control.cpp b/source/mact/src/control.cpp deleted file mode 100644 index 6eb85ce87..000000000 --- a/source/mact/src/control.cpp +++ /dev/null @@ -1,554 +0,0 @@ -/* - * control.c - * MACT library controller handling - * - * Derived from MACT386.LIB disassembly by Jonathon Fowler - * - */ - -#include "_control.h" -#include "baselayer.h" -#include "compat.h" -#include "control.h" -#include "joystick.h" -#include "keyboard.h" -#include "mouse.h" -#include "osd.h" -#include "gamecvars.h" -#include "pragmas.h" - -bool CONTROL_Started = false; -bool CONTROL_MouseEnabled = false; -bool CONTROL_MousePresent = false; -bool CONTROL_JoyPresent = false; -bool CONTROL_JoystickEnabled = false; - -LastSeenInput CONTROL_LastSeenInput; - -static int32_t CONTROL_NumMouseButtons = 0; -static int32_t CONTROL_NumJoyButtons = 0; -static int32_t CONTROL_NumJoyAxes = 0; - -// static controlkeymaptype CONTROL_KeyMapping[CONTROL_NUM_FLAGS]; - -static controlaxismaptype CONTROL_JoyAxesMap[MAXJOYAXES]; -static controlaxistype CONTROL_JoyAxes[MAXJOYAXES]; -static controlaxistype CONTROL_LastJoyAxes[MAXJOYAXES]; -static int32_t CONTROL_JoyAxesScale[MAXJOYAXES]; -static int8_t CONTROL_JoyAxesInvert[MAXJOYAXES]; - -static controlbuttontype CONTROL_JoyButtonMapping[MAXJOYBUTTONS]; - -static int32_t CONTROL_JoyButtonClicked[MAXJOYBUTTONS]; -static int32_t CONTROL_JoyButtonClickedState[MAXJOYBUTTONS]; -static int32_t CONTROL_JoyButtonClickedTime[MAXJOYBUTTONS]; -static int32_t CONTROL_JoyButtonState[MAXJOYBUTTONS]; -static uint8_t CONTROL_JoyButtonClickedCount[MAXJOYBUTTONS]; - -static int32_t(*ExtGetTime)(void); -//static int32_t ticrate; -static uint8_t CONTROL_DoubleClickSpeed; - -int32_t CONTROL_ButtonFlags[NUMKEYS]; -bool CONTROL_BindsEnabled = 0; - -#define CONTROL_CheckRange(which) ((unsigned)which >= (unsigned)NUMKEYS) - -static int32_t CONTROL_GetTime(void) -{ - static int32_t t = 0; - t += 5; - return t; -} - -void CONTROL_MapAnalogAxis(int whichaxis, int whichanalog, controldevice device) -{ - controlaxismaptype *set; - - if ((unsigned)whichanalog >= (unsigned)analog_maxtype && whichanalog != -1) - { - //Error("CONTROL_MapAnalogAxis: analog function %d out of valid range for %d analog functions.", - // whichanalog, analog_maxtype); - return; - } - - switch (device) - { - case controldevice_joystick: - if ((unsigned)whichaxis >= (unsigned)MAXJOYAXES) - { - //Error("CONTROL_MapAnalogAxis: axis %d out of valid range for %d joystick axes.", - // whichaxis, MAXJOYAXES); - return; - } - - set = CONTROL_JoyAxesMap; - break; - - default: - //Error("CONTROL_MapAnalogAxis: invalid controller device type"); - return; - } - - set[whichaxis].analogmap = whichanalog; -} - -void CONTROL_SetAnalogAxisScale(int32_t whichaxis, int32_t axisscale, controldevice device) -{ - int32_t *set; - - switch (device) - { - case controldevice_joystick: - if ((unsigned) whichaxis >= (unsigned) MAXJOYAXES) - { - //Error("CONTROL_SetAnalogAxisScale: axis %d out of valid range for %d joystick axes.", - // whichaxis, MAXJOYAXES); - return; - } - - set = CONTROL_JoyAxesScale; - break; - - default: - //Error("CONTROL_SetAnalogAxisScale: invalid controller device type"); - return; - } - - set[whichaxis] = axisscale; -} - -void CONTROL_SetAnalogAxisInvert(int32_t whichaxis, int32_t invert, controldevice device) -{ - int8_t * set; - - switch (device) - { - case controldevice_joystick: - if ((unsigned) whichaxis >= (unsigned) MAXJOYAXES) - { - //Error("CONTROL_SetAnalogAxisInvert: axis %d out of valid range for %d joystick axes.", - // whichaxis, MAXJOYAXES); - return; - } - - set = CONTROL_JoyAxesInvert; - break; - - default: - //Error("CONTROL_SetAnalogAxisInvert: invalid controller device type"); - return; - } - - set[whichaxis] = invert; -} - -void CONTROL_MapDigitalAxis(int32_t whichaxis, int32_t whichfunction, int32_t direction, controldevice device) -{ - controlaxismaptype *set; - - if (CONTROL_CheckRange(whichfunction)) whichfunction = AXISUNDEFINED; - - switch (device) - { - case controldevice_joystick: - if ((unsigned) whichaxis >= (unsigned) MAXJOYAXES) - { - //Error("CONTROL_MapDigitalAxis: axis %d out of valid range for %d joystick axes.", - // whichaxis, MAXJOYAXES); - return; - } - - set = CONTROL_JoyAxesMap; - break; - - default: - //Error("CONTROL_MapDigitalAxis: invalid controller device type"); - return; - } - - switch (direction) // JBF: this is all very much a guess. The ASM puzzles me. - { - case axis_up: - case axis_left: - set[whichaxis].minmap = whichfunction; - break; - case axis_down: - case axis_right: - set[whichaxis].maxmap = whichfunction; - break; - default: - break; - } -} - -void CONTROL_ClearAssignments(void) -{ - memset(CONTROL_JoyAxes, 0, sizeof(CONTROL_JoyAxes)); - memset(CONTROL_JoyAxesInvert, 0, sizeof(CONTROL_JoyAxesInvert)); - memset(CONTROL_JoyAxesMap, AXISUNDEFINED, sizeof(CONTROL_JoyAxesMap)); - memset(CONTROL_JoyButtonMapping, BUTTONUNDEFINED, sizeof(CONTROL_JoyButtonMapping)); - memset(CONTROL_LastJoyAxes, 0, sizeof(CONTROL_LastJoyAxes)); -} - -static int DoGetDeviceButtons( - int32_t buttons, int32_t tm, - int32_t NumButtons, - int32_t *DeviceButtonState, - int32_t *ButtonClickedTime, - int32_t *ButtonClickedState, - int32_t *ButtonClicked, - uint8_t *ButtonClickedCount -) -{ - int32_t i=NumButtons-1; - int retval = 0; - - for (; i>=0; i--) - { - int const bs = (buttons >> i) & 1; - - DeviceButtonState[i] = bs; - ButtonClickedState[i] = FALSE; - - if (bs) - { - retval = 1; - - if (ButtonClicked[i] == FALSE) - { - ButtonClicked[i] = TRUE; - - if (ButtonClickedCount[i] == 0 || tm > ButtonClickedTime[i]) - { - ButtonClickedTime[i] = tm + CONTROL_DoubleClickSpeed; - ButtonClickedCount[i] = 1; - } - else if (tm < ButtonClickedTime[i]) - { - ButtonClickedState[i] = TRUE; - ButtonClickedTime[i] = 0; - ButtonClickedCount[i] = 2; - } - } - else if (ButtonClickedCount[i] == 2) - { - ButtonClickedState[i] = TRUE; - } - - continue; - } - - if (ButtonClickedCount[i] == 2) - ButtonClickedCount[i] = 0; - - ButtonClicked[i] = FALSE; - } - - return retval; -} - -static void CONTROL_GetDeviceButtons(void) -{ - int32_t const t = ExtGetTime(); - - if (CONTROL_JoystickEnabled) - { - int retval = DoGetDeviceButtons( - JOYSTICK_GetButtons(), t, - CONTROL_NumJoyButtons, - CONTROL_JoyButtonState, - CONTROL_JoyButtonClickedTime, - CONTROL_JoyButtonClickedState, - CONTROL_JoyButtonClicked, - CONTROL_JoyButtonClickedCount - ); - if (retval) - CONTROL_LastSeenInput = LastSeenInput::Joystick; - } -} - -static int CONTROL_DigitizeAxis(int axis, controldevice device) -{ - controlaxistype *set, *lastset; - - switch (device) - { - case controldevice_joystick: - set = CONTROL_JoyAxes; - lastset = CONTROL_LastJoyAxes; - break; - - default: return 0; - } - - set[axis].digitalClearedN = lastset[axis].digitalClearedN; - set[axis].digitalClearedP = lastset[axis].digitalClearedP; - - if (set[axis].analog > 0) - { - set[axis].digitalClearedN = 0; - - if (set[axis].analog > THRESHOLD || (set[axis].analog > MINTHRESHOLD && lastset[axis].digital == 1)) - set[axis].digital = 1; - else - set[axis].digitalClearedP = 0; - - return 1; - } - else if (set[axis].analog < 0) - { - set[axis].digitalClearedP = 0; - - if (set[axis].analog < -THRESHOLD || (set[axis].analog < -MINTHRESHOLD && lastset[axis].digital == -1)) - set[axis].digital = -1; - else - set[axis].digitalClearedN = 0; - - return 1; - } - else - { - set[axis].digitalClearedN = 0; - set[axis].digitalClearedP = 0; - } - - return 0; -} - -static void CONTROL_ScaleAxis(int axis, controldevice device) -{ - controlaxistype *set; - int32_t *scale; - int8_t * invert; - - switch (device) - { - case controldevice_joystick: - set = CONTROL_JoyAxes; - scale = CONTROL_JoyAxesScale; - invert = CONTROL_JoyAxesInvert; - break; - - default: return; - } - - int const invertResult = !!invert[axis]; - set[axis].analog = (mulscale16(set[axis].analog, scale[axis]) ^ -invertResult) + invertResult; -} - -static void CONTROL_ApplyAxis(int axis, ControlInfo *info, controldevice device) -{ - controlaxistype *set; - controlaxismaptype *map; - - switch (device) - { - case controldevice_joystick: - set = CONTROL_JoyAxes; - map = CONTROL_JoyAxesMap; - break; - - default: return; - } - - switch (map[axis].analogmap) - { - case analog_turning: info->dyaw += set[axis].analog; break; - case analog_strafing: info->dx += set[axis].analog; break; - case analog_lookingupanddown: info->dpitch += set[axis].analog; break; - case analog_elevation: info->dy += set[axis].analog; break; - case analog_rolling: info->droll += set[axis].analog; break; - case analog_moving: info->dz += set[axis].analog; break; - default: break; - } -} - -static void CONTROL_PollDevices(ControlInfo *info) -{ - memset(info, 0, sizeof(ControlInfo)); - - if (CONTROL_MouseEnabled) - inputState.GetMouseDelta(info); - - if (CONTROL_JoystickEnabled) - { - Bmemcpy(CONTROL_LastJoyAxes, CONTROL_JoyAxes, sizeof(CONTROL_JoyAxes)); - memset(CONTROL_JoyAxes, 0, sizeof(CONTROL_JoyAxes)); - - for (int i=joystick.numAxes-1; i>=0; i--) - { - CONTROL_JoyAxes[i].analog = joystick.pAxis[i]; - - if (CONTROL_DigitizeAxis(i, controldevice_joystick)) - CONTROL_LastSeenInput = LastSeenInput::Joystick; - CONTROL_ScaleAxis(i, controldevice_joystick); - LIMITCONTROL(&CONTROL_JoyAxes[i].analog); - CONTROL_ApplyAxis(i, info, controldevice_joystick); - } - } - - CONTROL_GetDeviceButtons(); -} - -static int CONTROL_HandleAxisFunction(int32_t *p1, controlaxistype *axes, controlaxismaptype *axismap, int numAxes) -{ - int axis = numAxes - 1; - int retval = 0; - - do - { - if (!axes[axis].digital) - continue; - - int const j = (axes[axis].digital < 0) ? axismap[axis].minmap : axismap[axis].maxmap; - - if (j != AXISUNDEFINED) - { - p1[j] = 1; - retval = 1; - } - } - while (axis--); - - return retval; -} - -static void CONTROL_AxisFunctionState(int32_t *p1) -{ - if (CONTROL_NumJoyAxes) - { - if (CONTROL_HandleAxisFunction(p1, CONTROL_JoyAxes, CONTROL_JoyAxesMap, CONTROL_NumJoyAxes)) - CONTROL_LastSeenInput = LastSeenInput::Joystick; - } -} - -static void CONTROL_ButtonFunctionState(int32_t *p1) -{ - if (CONTROL_NumJoyButtons) - { - int i=CONTROL_NumJoyButtons-1, j; - int retval = 0; - - do - { - j = CONTROL_JoyButtonMapping[i].doubleclicked; - if (j != KEYUNDEFINED) - { - auto const state = CONTROL_JoyButtonClickedState[i]; - p1[j] |= state; - retval |= state; - } - - j = CONTROL_JoyButtonMapping[i].singleclicked; - if (j != KEYUNDEFINED) - { - auto const state = CONTROL_JoyButtonState[i]; - p1[j] |= state; - retval |= state; - } - } - while (i--); - - if (retval) - CONTROL_LastSeenInput = LastSeenInput::Joystick; - } -} - -int32_t CONTROL_GetGameControllerDigitalAxisPos(int32_t axis) -{ - if (!joystick.isGameController) - return 0; - - return CONTROL_JoyAxes[axis].digital > 0 && !CONTROL_JoyAxes[axis].digitalClearedP; -} -int32_t CONTROL_GetGameControllerDigitalAxisNeg(int32_t axis) -{ - if (!joystick.isGameController) - return 0; - - return CONTROL_JoyAxes[axis].digital < 0 && !CONTROL_JoyAxes[axis].digitalClearedN; -} - -void CONTROL_ClearGameControllerDigitalAxisPos(int32_t axis) -{ - if (!joystick.isGameController) - return; - - CONTROL_JoyAxes[axis].digitalClearedP = 1; -} -void CONTROL_ClearGameControllerDigitalAxisNeg(int32_t axis) -{ - if (!joystick.isGameController) - return; - - CONTROL_JoyAxes[axis].digitalClearedN = 1; -} - - -static void CONTROL_GetFunctionInput(void) -{ - CONTROL_ButtonFunctionState(CONTROL_ButtonFlags); - CONTROL_AxisFunctionState(CONTROL_ButtonFlags); -} - -void CONTROL_GetInput(ControlInfo *info) -{ - CONTROL_PollDevices(info); - CONTROL_GetFunctionInput(); - inputchecked = 1; -} - -static void CONTROL_ResetJoystickValues() -{ - CONTROL_NumJoyAxes = min(MAXJOYAXES, joystick.numAxes); - CONTROL_NumJoyButtons = min(MAXJOYBUTTONS, joystick.numButtons + 4 * (joystick.numHats > 0)); - CONTROL_JoystickEnabled = CONTROL_JoyPresent = !!((inputdevices & 4) >> 2); -} - -void CONTROL_ScanForControllers() -{ - joyScanDevices(); - CONTROL_ResetJoystickValues(); -} - -bool CONTROL_Startup(controltype which, int32_t(*TimeFunction)(void), int32_t ticspersecond) -{ - UNREFERENCED_PARAMETER(which); - - if (CONTROL_Started) return false; - - ExtGetTime = TimeFunction ? TimeFunction : CONTROL_GetTime; - - // what the fuck??? - CONTROL_DoubleClickSpeed = (ticspersecond * 57) / 100; - - if (CONTROL_DoubleClickSpeed <= 0) - CONTROL_DoubleClickSpeed = 1; - - if (initinput()) - return true; - - CONTROL_NumMouseButtons = MAXMOUSEBUTTONS; - mouseInit(); - CONTROL_MousePresent = ((inputdevices & 2) == 2); - CONTROL_MouseEnabled = CONTROL_MousePresent; - - CONTROL_ResetJoystickValues(); - - CONTROL_Started = TRUE; - - return false; -} - -void CONTROL_Shutdown(void) -{ - if (!CONTROL_Started) - return; - - mouseUninit(); - uninitinput(); - - CONTROL_Started = FALSE; -} - diff --git a/source/mact/src/joystick.cpp b/source/mact/src/joystick.cpp deleted file mode 100644 index 4f2da88f3..000000000 --- a/source/mact/src/joystick.cpp +++ /dev/null @@ -1,128 +0,0 @@ -/* - * joystick.c - * MACT library -to- Build Port Joystick Glue - * - * by Hendricks266 - * - * We needed raw joystick access for the Wii port. - * We only had raw mouse and keyboard access. - * I made raw joystick access. - * - */ -//------------------------------------------------------------------------- -/* -Duke Nukem Copyright (C) 1996, 2003 3D Realms Entertainment - -This file is part of Duke Nukem 3D version 1.5 - Atomic Edition - -Duke Nukem 3D is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ -//------------------------------------------------------------------------- - -#include "compat.h" - -#include "joystick.h" -#include "baselayer.h" - -#include "keyboard.h" -#include "_control.h" - -int32_t JOYSTICK_GetButtons(void) -{ - int32_t buttons; - - joyReadButtons(&buttons); - - if (joystick.numHats > 0) - { - int32_t hat = JOYSTICK_GetHat(0); - if (hat != 0) - buttons |= hat << min(MAXJOYBUTTONS, joystick.numButtons); - } - - return buttons; -} -int32_t JOYSTICK_GetGameControllerButtons(void) -{ - if (!joystick.isGameController) - return 0; - - int32_t buttons; - joyReadButtons(&buttons); - return buttons; -} -int32_t JOYSTICK_ClearButton(int32_t b) -{ - return (joystick.bits &= ~b); -} -void JOYSTICK_ClearGameControllerButton(int32_t b) -{ - if (!joystick.isGameController) - return; - - joystick.bits &= ~b; -} -void JOYSTICK_ClearAllButtons(void) -{ - joystick.bits = 0; -} - -int32_t JOYSTICK_GetHat(int32_t h) -{ - if (h>=0 && h=0 && h=0 && a=0 && agm & (MODE_MENU|MODE_DEMO))) && totalclock >= ototalclock+TICSPERFRAME) { - //if (g_networkMode != NET_DEDICATED_SERVER) - //{ - // if (RRRA && g_player[myconnectindex].ps->on_motorcycle) - // P_GetInputMotorcycle(myconnectindex); - // else if (RRRA && g_player[myconnectindex].ps->on_boat) - // P_GetInputBoat(myconnectindex); - // else - // P_GetInput(myconnectindex); - //} - - //Bmemcpy(&inputfifo[0][myconnectindex], &localInput, sizeof(input_t)); - - S_Update(); - do { - if (ready2send == 0) break; - Net_GetInput(); + //if (g_networkMode != NET_DEDICATED_SERVER) + //{ + // if (RRRA && g_player[myconnectindex].ps->on_motorcycle) + // P_GetInputMotorcycle(myconnectindex); + // else if (RRRA && g_player[myconnectindex].ps->on_boat) + // P_GetInputBoat(myconnectindex); + // else + // P_GetInput(myconnectindex); + //} - ototalclock += TICSPERFRAME; + //Bmemcpy(&inputfifo[0][myconnectindex], &localInput, sizeof(input_t)); - int const moveClock = (int) totalclock; + if (!frameJustDrawn) + break; - if (((ud.show_help == 0 && !GUICapture && (g_player[myconnectindex].ps->gm&MODE_MENU) != MODE_MENU) || ud.recstat == 2 || (g_netServer || ud.multimode > 1)) && - (g_player[myconnectindex].ps->gm&MODE_GAME)) - { - G_MoveLoop(); - } + frameJustDrawn = false; - if (totalclock - moveClock >= TICSPERFRAME) - { - // computing a tic takes longer than a tic, so we're slowing - // the game down. rather than tightly spinning here, go draw - // a frame since we're fucked anyway - break; - } - } - while (((g_netClient || g_netServer) || !(g_player[myconnectindex].ps->gm & (MODE_MENU|MODE_DEMO))) && totalclock >= ototalclock+TICSPERFRAME); + do + { + if (ready2send == 0) break; + Net_GetInput(); - gameUpdate = true; - g_gameUpdateTime = timerGetHiTicks()-gameUpdateStartTime; - if (g_gameUpdateAvgTime < 0.f) - g_gameUpdateAvgTime = g_gameUpdateTime; - g_gameUpdateAvgTime = ((GAMEUPDATEAVGTIMENUMSAMPLES-1.f)*g_gameUpdateAvgTime+g_gameUpdateTime)/((float) GAMEUPDATEAVGTIMENUMSAMPLES); + ototalclock += TICSPERFRAME; + + int const moveClock = (int) totalclock; + + if (((ud.show_help == 0 && !GUICapture && (g_player[myconnectindex].ps->gm&MODE_MENU) != MODE_MENU) || ud.recstat == 2 || (g_netServer || ud.multimode > 1)) && + (g_player[myconnectindex].ps->gm&MODE_GAME)) + { + G_MoveLoop(); + S_Update(); + } + + if (totalclock - moveClock >= TICSPERFRAME) + { + // computing a tic takes longer than a tic, so we're slowing + // the game down. rather than tightly spinning here, go draw + // a frame since we're fucked anyway + break; + } + } + while (((g_netClient || g_netServer) || !(g_player[myconnectindex].ps->gm & (MODE_MENU|MODE_DEMO))) && totalclock >= ototalclock+TICSPERFRAME); + + gameUpdate = true; + g_gameUpdateTime = timerGetHiTicks()-gameUpdateStartTime; + if (g_gameUpdateAvgTime < 0.f) + g_gameUpdateAvgTime = g_gameUpdateTime; + g_gameUpdateAvgTime = ((GAMEUPDATEAVGTIMENUMSAMPLES-1.f)*g_gameUpdateAvgTime+g_gameUpdateTime)/((float) GAMEUPDATEAVGTIMENUMSAMPLES); + } while(0); } G_DoCheats(); @@ -7690,6 +7706,8 @@ MAIN_LOOP_RESTART: { g_gameUpdateAndDrawTime = g_beforeSwapTime/* timerGetHiTicks()*/ - gameUpdateStartTime; } + + frameJustDrawn = true; } if (g_player[myconnectindex].ps->gm&MODE_DEMO) diff --git a/source/rr/src/net.cpp b/source/rr/src/net.cpp index 993283e75..9d5838e43 100644 --- a/source/rr/src/net.cpp +++ b/source/rr/src/net.cpp @@ -2531,10 +2531,6 @@ void Net_ReceiveDisconnect(ENetEvent *event) void Net_GetPackets(void) { - MUSIC_Update(); - - G_HandleSpecialKeys(); - if (g_netDisconnect) { Net_Disconnect(); diff --git a/source/rr/src/sector.cpp b/source/rr/src/sector.cpp index a75f5f9e6..84d2046f5 100644 --- a/source/rr/src/sector.cpp +++ b/source/rr/src/sector.cpp @@ -3495,9 +3495,12 @@ default_case: SA(spriteNum) = (sprite[dmgSrc].ang + 1024) & 2047; sprite[spriteNum].xvel = -(sprite[dmgSrc].extra << 2); int16_t sectNum = SECT(spriteNum); - pushmove((vec3_t *)&sprite[spriteNum], §Num, 128L, (4L << 8), (4L << 8), CLIPMASK0); - if (sectNum != SECT(spriteNum) && (unsigned)sectNum < MAXSECTORS) - changespritesect(spriteNum, sectNum); + if ((unsigned)sectNum < MAXSECTORS) + { + pushmove((vec3_t *)&sprite[spriteNum], §Num, 128L, (4L << 8), (4L << 8), CLIPMASK0); + if (sectNum != SECT(spriteNum) && (unsigned)sectNum < MAXSECTORS) + changespritesect(spriteNum, sectNum); + } } if (sprite[spriteNum].statnum == STAT_ZOMBIEACTOR) diff --git a/source/sw/CMakeLists.txt b/source/sw/CMakeLists.txt index 6de3ea9b1..5209c43f3 100644 --- a/source/sw/CMakeLists.txt +++ b/source/sw/CMakeLists.txt @@ -14,7 +14,6 @@ endif() include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/../build/include - ${CMAKE_CURRENT_SOURCE_DIR}/../mact/include ${CMAKE_CURRENT_SOURCE_DIR}/../audiolib/include ${CMAKE_CURRENT_SOURCE_DIR}/../libsmackerdec/include ${CMAKE_CURRENT_SOURCE_DIR}/../thirdparty/include @@ -25,6 +24,7 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/../common/fonts ${CMAKE_CURRENT_SOURCE_DIR}/../common/2d ${CMAKE_CURRENT_SOURCE_DIR}/../common/music + ${CMAKE_CURRENT_SOURCE_DIR}/../common/input ${CMAKE_CURRENT_SOURCE_DIR}/../platform ) diff --git a/source/sw/src/anim.cpp b/source/sw/src/anim.cpp index de3e0e216..7e892296f 100644 --- a/source/sw/src/anim.cpp +++ b/source/sw/src/anim.cpp @@ -33,9 +33,7 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #include "fx_man.h" #include "music.h" #include "gamedefs.h" -#include "keyboard.h" -#include "control.h" #include "config.h" #include "sounds.h" #include "gamecontrol.h" diff --git a/source/sw/src/cheats.cpp b/source/sw/src/cheats.cpp index 529d38fd1..be1eb4df5 100644 --- a/source/sw/src/cheats.cpp +++ b/source/sw/src/cheats.cpp @@ -43,7 +43,6 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #include "mytypes.h" #include "text.h" -#include "control.h" #include "gamecontrol.h" #include "gstrings.h" //#include "inv.h" diff --git a/source/sw/src/config.cpp b/source/sw/src/config.cpp index c354c3994..db5f9d82a 100644 --- a/source/sw/src/config.cpp +++ b/source/sw/src/config.cpp @@ -33,9 +33,7 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #include "settings.h" #include "mytypes.h" #include "gamedefs.h" -#include "keyboard.h" #include "gamecontrol.h" -#include "control.h" #include "fx_man.h" #include "sounds.h" #include "config.h" diff --git a/source/sw/src/config.h b/source/sw/src/config.h index d36c187c3..73f934848 100644 --- a/source/sw/src/config.h +++ b/source/sw/src/config.h @@ -30,8 +30,6 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #include "compat.h" #include "gamecontrol.h" -#include "keyboard.h" -#include "control.h" BEGIN_SW_NS diff --git a/source/sw/src/console.cpp b/source/sw/src/console.cpp index b6afca650..0689f0140 100644 --- a/source/sw/src/console.cpp +++ b/source/sw/src/console.cpp @@ -45,7 +45,6 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #include "common_game.h" #include "gamecontrol.h" -#include "control.h" #include "trigger.h" #include "savedef.h" diff --git a/source/sw/src/d_menu.cpp b/source/sw/src/d_menu.cpp index 3c431eabc..4291464ba 100644 --- a/source/sw/src/d_menu.cpp +++ b/source/sw/src/d_menu.cpp @@ -33,12 +33,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "weapon.h" #include "player.h" #include "jsector.h" -#include "control.h" #include "menus.h" #include "sw_strs.h" #include "pal.h" #include "demo.h" -#include "input.h" #include "keydef.h" #include "gamecontrol.h" diff --git a/source/sw/src/demo.cpp b/source/sw/src/demo.cpp index 863214725..37afdfaee 100644 --- a/source/sw/src/demo.cpp +++ b/source/sw/src/demo.cpp @@ -37,7 +37,6 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #include "network.h" #include "mytypes.h" -#include "control.h" #include "gamecontrol.h" #include "demo.h" diff --git a/source/sw/src/draw.cpp b/source/sw/src/draw.cpp index 930165ce2..edec0f361 100644 --- a/source/sw/src/draw.cpp +++ b/source/sw/src/draw.cpp @@ -40,7 +40,6 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #include "jsector.h" #include "mytypes.h" -#include "control.h" #include "gamecontrol.h" #include "network.h" #include "pal.h" diff --git a/source/sw/src/game.cpp b/source/sw/src/game.cpp index 896fe2e55..0b4f48db7 100644 --- a/source/sw/src/game.cpp +++ b/source/sw/src/game.cpp @@ -68,7 +68,6 @@ Things required to make savegames work: #include "menus.h" -#include "control.h" #include "gamecontrol.h" #include "gamedefs.h" #include "config.h" @@ -85,7 +84,6 @@ Things required to make savegames work: #include "light.h" #include "track.h" #include "jsector.h" -#include "keyboard.h" #include "text.h" #include "music.h" diff --git a/source/sw/src/game.h b/source/sw/src/game.h index e27bffb0d..5d9de1bdb 100644 --- a/source/sw/src/game.h +++ b/source/sw/src/game.h @@ -41,7 +41,6 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #include "mmulti.h" #include "mytypes.h" -#include "keyboard.h" #include "sounds.h" #include "settings.h" #include "pragmas.h" diff --git a/source/sw/src/jplayer.cpp b/source/sw/src/jplayer.cpp index 04a9aac35..de7da172b 100644 --- a/source/sw/src/jplayer.cpp +++ b/source/sw/src/jplayer.cpp @@ -43,7 +43,6 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #include "common_game.h" #include "gamecontrol.h" -#include "control.h" #include "trigger.h" #include "savedef.h" diff --git a/source/sw/src/menus.cpp b/source/sw/src/menus.cpp index a834eafa6..bdc4e160f 100644 --- a/source/sw/src/menus.cpp +++ b/source/sw/src/menus.cpp @@ -38,7 +38,6 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #include "weapon.h" #include "player.h" #include "jsector.h" -#include "control.h" #include "menus.h" #include "sw_strs.h" #include "pal.h" diff --git a/source/sw/src/player.cpp b/source/sw/src/player.cpp index f320a223a..286e088f9 100644 --- a/source/sw/src/player.cpp +++ b/source/sw/src/player.cpp @@ -42,7 +42,6 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #include "common_game.h" #include "gamecontrol.h" -#include "control.h" #include "trigger.h" #include "savedef.h" diff --git a/source/sw/src/predict.cpp b/source/sw/src/predict.cpp index 3d4481ab0..0b2865cbf 100644 --- a/source/sw/src/predict.cpp +++ b/source/sw/src/predict.cpp @@ -33,14 +33,7 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #include "names2.h" #include "panel.h" #include "game.h" -//#include "quake.h" -//#include "jsector.h" - -//#include "mytypes.h" -//#include "control.h" -//#include "gamecontrol.h" #include "network.h" -//#include "symutil.h" BEGIN_SW_NS diff --git a/source/sw/src/setup.cpp b/source/sw/src/setup.cpp index 8177426ba..d28ce3af5 100644 --- a/source/sw/src/setup.cpp +++ b/source/sw/src/setup.cpp @@ -33,9 +33,7 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #include "fx_man.h" #include "music.h" #include "gamedefs.h" -#include "keyboard.h" -#include "control.h" #include "config.h" #include "sounds.h" #include "gamecontrol.h" diff --git a/wadsrc/static/demolition/menudef.txt b/wadsrc/static/demolition/menudef.txt index c2a6a68dd..944b77c4e 100644 --- a/wadsrc/static/demolition/menudef.txt +++ b/wadsrc/static/demolition/menudef.txt @@ -945,29 +945,12 @@ OptionMenu "MouseOptions" //protected // //------------------------------------------------------------------------------------------- -OptionMenu "JoystickOptions"//Defaults" //protected +OptionMenu "JoystickOptions" //protected { Title "$JOYMNU_OPTIONS" - Option "$JOYMNU_ENABLE", "use_joystick", "YesNo" - Option "$JOYMNU_NOMENU", "m_blockcontrollers", "YesNo" - /*IfOption(Windows) - { - Option "$JOYMNU_DINPUT", "joy_dinput", "YesNo" - Option "$JOYMNU_XINPUT", "joy_xinput", "YesNo" - Option "$JOYMNU_PS2", "joy_ps2raw", "YesNo" - }*/ - StaticText "" - StaticTextSwitchable "$JOYMNU_NOCON", "$JOYMNU_CONFIG", "ConfigureMessage" - StaticTextSwitchable " ", "$JOYMNU_DISABLED1", "ConnectMessage1" - StaticTextSwitchable " ", "$JOYMNU_DISABLED2", "ConnectMessage2" - - // The rest will be filled in by joystick code if devices get connected or disconnected + // This will be filled in by joystick code if devices get connected or disconnected } -OptionMenu "JoystickOptions1" //protected -{ - Title "$JOYMNU_OPTIONS" -} OptionValue "JoyAxisMapNames" {