diff --git a/src/common/engine/d_event.cpp b/src/common/engine/d_event.cpp index bb0ef5dae..1e705c67f 100644 --- a/src/common/engine/d_event.cpp +++ b/src/common/engine/d_event.cpp @@ -42,6 +42,7 @@ #include "m_joy.h" #include "vm.h" #include "gamestate.h" +#include "i_interface.h" bool G_Responder(event_t* ev); @@ -49,6 +50,11 @@ int eventhead; int eventtail; event_t events[MAXEVENTS]; +CVAR(Float, m_sensitivity_x, 2, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +CVAR(Float, m_sensitivity_y, 2, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +CVAR(Bool, m_filter, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) + + //========================================================================== // // D_ProcessEvents @@ -116,6 +122,57 @@ void D_RemoveNextCharEvent() } +//========================================================================== +// +// D_PostEvent +// +// Called by the I/O functions when input is detected. +// +//========================================================================== + +void D_PostEvent(event_t* ev) +{ + // Do not post duplicate consecutive EV_DeviceChange events. + if (ev->type == EV_DeviceChange && events[eventhead].type == EV_DeviceChange) + { + return; + } + if (sysCallbacks && sysCallbacks->DispatchEvent && sysCallbacks->DispatchEvent(ev)) + return; + + events[eventhead] = *ev; + eventhead = (eventhead + 1) & (MAXEVENTS - 1); +} + + +void PostMouseMove(int xx, int yy) +{ + static float lastx = 0, lasty = 0; + event_t ev{}; + + float x = float(xx) * m_sensitivity_x; + float y = -float(yy) * m_sensitivity_y; + + if (m_filter) + { + ev.x = xs_CRoundToInt((x + lastx) / 2); + ev.y = xs_CRoundToInt((y + lasty) / 2); + } + else + { + ev.x = xs_CRoundToInt(x); + ev.y = xs_CRoundToInt(y); + } + lastx = x; + lasty = y; + if (ev.x | ev.y) + { + ev.type = EV_Mouse; + D_PostEvent(&ev); + } +} + + FInputEvent::FInputEvent(const event_t *ev) { Type = (EGenericEvent)ev->type; diff --git a/src/common/engine/d_eventbase.h b/src/common/engine/d_eventbase.h index 6ae14b4a3..c2b994ae7 100644 --- a/src/common/engine/d_eventbase.h +++ b/src/common/engine/d_eventbase.h @@ -29,9 +29,10 @@ struct event_t // Called by IO functions when input is detected. -void D_PostEvent (const event_t* ev); +void D_PostEvent (event_t* ev); void D_RemoveNextCharEvent(); void D_ProcessEvents(void); +void PostMouseMove(int x, int y); enum { diff --git a/src/common/engine/i_interface.h b/src/common/engine/i_interface.h index cf77c743e..7207df14f 100644 --- a/src/common/engine/i_interface.h +++ b/src/common/engine/i_interface.h @@ -3,6 +3,8 @@ #include "zstring.h" #include "intrect.h" +struct event_t; + struct SystemCallbacks { bool (*WantGuiCapture)(); @@ -19,6 +21,7 @@ struct SystemCallbacks FString(*GetLocationDescription)(); void (*MenuDim)(); FString(*GetPlayerName)(int i); + bool (*DispatchEvent)(event_t* ev); }; extern SystemCallbacks *sysCallbacks; diff --git a/src/common/platform/posix/cocoa/i_input.mm b/src/common/platform/posix/cocoa/i_input.mm index 3b562bcb8..a9b9443a0 100644 --- a/src/common/platform/posix/cocoa/i_input.mm +++ b/src/common/platform/posix/cocoa/i_input.mm @@ -52,8 +52,6 @@ EXTERN_CVAR(Int, m_use_mouse) CVAR(Bool, use_mouse, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) -CVAR(Bool, m_noprescale, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) -CVAR(Bool, m_filter, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR(Bool, k_allowfullscreentoggle, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) @@ -488,43 +486,9 @@ void ProcessMouseMoveInMenu(NSEvent* theEvent) void ProcessMouseMoveInGame(NSEvent* theEvent) { int x([theEvent deltaX]); - int y(-[theEvent deltaY]); + int y([theEvent deltaY]); - if (0 == x && 0 == y) - { - return; - } - - if (!m_noprescale) - { - x *= 3; - y *= 2; - } - - event_t event = {}; - - static int lastX = 0, lastY = 0; - - if (m_filter) - { - event.x = (x + lastX) / 2; - event.y = (y + lastY) / 2; - } - else - { - event.x = x; - event.y = y; - } - - lastX = x; - lastY = y; - - if (0 != event.x || 0 != event.y) - { - event.type = EV_Mouse; - - D_PostEvent(&event); - } + PostMouseMove(x, y); } diff --git a/src/common/platform/posix/sdl/i_input.cpp b/src/common/platform/posix/sdl/i_input.cpp index 4bd576ef4..1ad9fa65d 100644 --- a/src/common/platform/posix/sdl/i_input.cpp +++ b/src/common/platform/posix/sdl/i_input.cpp @@ -54,8 +54,6 @@ bool GUICapture; static bool NativeMouse = true; CVAR (Bool, use_mouse, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) -CVAR (Bool, m_noprescale, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) -CVAR (Bool, m_filter, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) extern int WaitingForKey, chatmodeon; @@ -191,30 +189,6 @@ void I_ReleaseMouseCapture() SDL_SetRelativeMouseMode (SDL_FALSE); } -static void PostMouseMove (int x, int y) -{ - static int lastx = 0, lasty = 0; - event_t ev = { 0,0,0,0,0,0,0 }; - - if (m_filter) - { - ev.x = (x + lastx) / 2; - ev.y = (y + lasty) / 2; - } - else - { - ev.x = x; - ev.y = y; - } - lastx = x; - lasty = y; - if (ev.x | ev.y) - { - ev.type = EV_Mouse; - D_PostEvent (&ev); - } -} - static void MouseRead () { int x, y; @@ -225,15 +199,7 @@ static void MouseRead () } SDL_GetRelativeMouseState (&x, &y); - if (!m_noprescale) - { - x *= 3; - y *= 2; - } - if (x | y) - { - PostMouseMove (x, -y); - } + PostMouseMove (x, y); } static void I_CheckNativeMouse () diff --git a/src/common/platform/win32/i_input.h b/src/common/platform/win32/i_input.h index 5e5204212..433c1f2c6 100644 --- a/src/common/platform/win32/i_input.h +++ b/src/common/platform/win32/i_input.h @@ -77,7 +77,6 @@ public: virtual void Ungrab() = 0; protected: - void PostMouseMove(int x, int y); void WheelMoved(int axis, int wheelmove); void PostButtonEvent(int button, bool down); void ClearButtonState(); diff --git a/src/common/platform/win32/i_mouse.cpp b/src/common/platform/win32/i_mouse.cpp index ddcdc7816..b4a15a494 100644 --- a/src/common/platform/win32/i_mouse.cpp +++ b/src/common/platform/win32/i_mouse.cpp @@ -162,8 +162,6 @@ bool NativeMouse; bool CursorState; CVAR (Bool, use_mouse, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) -CVAR (Bool, m_noprescale, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) -CVAR (Bool, m_filter, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR (Bool, m_hidepointer, true, 0) CUSTOM_CVAR (Int, in_mouse, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL) @@ -314,38 +312,6 @@ FMouse::FMouse() WheelMove[1] = 0; } -//========================================================================== -// -// FMouse :: PostMouseMove -// -// Posts a mouse movement event, potentially averaging it with the previous -// movement. If there is no movement to post, then no event is generated. -// -//========================================================================== - -void FMouse::PostMouseMove(int x, int y) -{ - event_t ev = { 0 }; - - if (m_filter) - { - ev.x = (x + LastX) / 2; - ev.y = (y + LastY) / 2; - } - else - { - ev.x = x; - ev.y = y; - } - LastX = x; - LastY = y; - if (ev.x | ev.y) - { - ev.type = EV_Mouse; - D_PostEvent(&ev); - } -} - //========================================================================== // // FMouse :: WheelMoved @@ -620,8 +586,8 @@ bool FRawMouse::ProcessRawInput(RAWINPUT *raw, int code) { WheelMoved(1, (SHORT)raw->data.mouse.usButtonData); } - int x = m_noprescale ? raw->data.mouse.lLastX : raw->data.mouse.lLastX << 2; - int y = -raw->data.mouse.lLastY; + int x = raw->data.mouse.lLastX; + int y = raw->data.mouse.lLastY; PostMouseMove(x, y); if (x | y) { @@ -847,7 +813,7 @@ void FDInputMouse::ProcessInput() } } } - PostMouseMove(m_noprescale ? dx : dx<<2, -dy); + PostMouseMove(dx, dy); } //========================================================================== @@ -952,18 +918,13 @@ void FWin32Mouse::ProcessInput() } x = pt.x - PrevX; - y = PrevY - pt.y; + y = pt.y - PrevY; - if (!m_noprescale) - { - x *= 3; - y *= 2; - } if (x | y) { CenterMouse(pt.x, pt.y, &PrevX, &PrevY); } - PostMouseMove(x, y); + PostMouseMove(2* x, 2* y); // The factor of 2 is needed to match this with raw mouse input. } //========================================================================== diff --git a/src/d_main.cpp b/src/d_main.cpp index d168c829b..7b82ee775 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -447,47 +447,8 @@ CCMD(togglehud) D_ToggleHud(); } -//========================================================================== -// -// D_PostEvent -// -// Called by the I/O functions when input is detected. -// -//========================================================================== - -void D_PostEvent (const event_t *ev) -{ - // Do not post duplicate consecutive EV_DeviceChange events. - if (ev->type == EV_DeviceChange && events[eventhead].type == EV_DeviceChange) - { - return; - } - events[eventhead] = *ev; - if (ev->type == EV_Mouse && menuactive == MENU_Off && ConsoleState != c_down && ConsoleState != c_falling && !primaryLevel->localEventManager->Responder(ev) && !paused) - { - if (buttonMap.ButtonDown(Button_Mlook) || freelook) - { - int look = int(ev->y * m_pitch * mouse_sensitivity * 16.0); - if (invertmouse) - look = -look; - G_AddViewPitch (look, true); - events[eventhead].y = 0; - } - if (!buttonMap.ButtonDown(Button_Strafe) && !lookstrafe) - { - int turn = int(ev->x * m_yaw * mouse_sensitivity * 8.0); - if (invertmousex) - turn = -turn; - G_AddViewAngle (turn, true); - events[eventhead].x = 0; - } - if ((events[eventhead].x | events[eventhead].y) == 0) - { - return; - } - } - eventhead = (eventhead+1)&(MAXEVENTS-1); -} +CVAR(Float, m_pitch, 1.f, CVAR_GLOBALCONFIG | CVAR_ARCHIVE) // Mouse speeds +CVAR(Float, m_yaw, 1.f, CVAR_GLOBALCONFIG | CVAR_ARCHIVE) //========================================================================== // @@ -2744,6 +2705,33 @@ bool System_WantLeftButton() return (gamestate == GS_DEMOSCREEN || gamestate == GS_TITLELEVEL); } +static bool System_DispatchEvent(event_t* ev) +{ + if (ev->type == EV_Mouse && menuactive == MENU_Off && ConsoleState != c_down && ConsoleState != c_falling && !primaryLevel->localEventManager->Responder(ev) && !paused) + { + if (buttonMap.ButtonDown(Button_Mlook) || freelook) + { + int look = int(ev->y * m_pitch * 16.0); + if (invertmouse) look = -look; + G_AddViewPitch(look, true); + ev->y = 0; + } + if (!buttonMap.ButtonDown(Button_Strafe) && !lookstrafe) + { + int turn = int(ev->x * m_yaw * 8.0); + if (invertmousex) + turn = -turn; + G_AddViewAngle(turn, true); + ev->x = 0; + } + if ((ev->x | ev->y) == 0) + { + return true; + } + } + return false; +} + bool System_NetGame() { return netgame; @@ -3076,6 +3064,7 @@ static int D_DoomMain_Internal (void) System_GetLocationDescription, System_M_Dim, System_GetPlayerName, + System_DispatchEvent, }; sysCallbacks = &syscb; diff --git a/src/g_game.cpp b/src/g_game.cpp index 515686cdb..7d247d28c 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -206,8 +206,6 @@ CVAR (Bool, invertmouse, false, CVAR_GLOBALCONFIG|CVAR_ARCHIVE) // Invert mous CVAR (Bool, invertmousex, false, CVAR_GLOBALCONFIG|CVAR_ARCHIVE) // Invert mouse look left/right? CVAR (Bool, freelook, true, CVAR_GLOBALCONFIG|CVAR_ARCHIVE) // Always mlook? CVAR (Bool, lookstrafe, false, CVAR_GLOBALCONFIG|CVAR_ARCHIVE) // Always strafe with mouse? -CVAR (Float, m_pitch, 1.f, CVAR_GLOBALCONFIG|CVAR_ARCHIVE) // Mouse speeds -CVAR (Float, m_yaw, 1.f, CVAR_GLOBALCONFIG|CVAR_ARCHIVE) CVAR (Float, m_forward, 1.f, CVAR_GLOBALCONFIG|CVAR_ARCHIVE) CVAR (Float, m_side, 2.f, CVAR_GLOBALCONFIG|CVAR_ARCHIVE) @@ -1037,8 +1035,8 @@ bool G_Responder (event_t *ev) // [RH] mouse buttons are sent as key up/down events case EV_Mouse: - mousex = (int)(ev->x * mouse_sensitivity); - mousey = (int)(ev->y * mouse_sensitivity); + mousex = ev->x; + mousey = ev->y; break; } diff --git a/src/gameconfigfile.cpp b/src/gameconfigfile.cpp index 7f7e55a21..dedbcb464 100644 --- a/src/gameconfigfile.cpp +++ b/src/gameconfigfile.cpp @@ -68,6 +68,12 @@ EXTERN_CVAR (Int, gl_texture_hqresizemult) EXTERN_CVAR (Int, vid_preferbackend) EXTERN_CVAR (Float, vid_scale_custompixelaspect) EXTERN_CVAR (Bool, vid_scale_linear) +EXTERN_CVAR(Float, m_sensitivity_x) +EXTERN_CVAR(Float, m_sensitivity_y) + +#ifdef _WIN32 +EXTERN_CVAR(Int, in_mouse) +#endif FGameConfigFile::FGameConfigFile () { @@ -295,14 +301,6 @@ void FGameConfigFile::DoGlobalSetup () if (lastver != NULL) { double last = atof (lastver); - if (last < 123.1) - { - FBaseCVar *noblitter = FindCVar ("vid_noblitter", NULL); - if (noblitter != NULL) - { - noblitter->ResetToDefault (); - } - } if (last < 202) { // Make sure the Hexen hotkeys are accessible by default. @@ -327,15 +325,6 @@ void FGameConfigFile::DoGlobalSetup () vsync->ResetToDefault (); } } - /* spc_amp no longer exists - if (last < 206) - { // spc_amp is now a float, not an int. - if (spc_amp > 16) - { - spc_amp = spc_amp / 16.f; - } - } - */ if (last < 207) { // Now that snd_midiprecache works again, you probably don't want it on. FBaseCVar *precache = FindCVar ("snd_midiprecache", NULL); @@ -575,6 +564,31 @@ void FGameConfigFile::DoGlobalSetup () UCVarValue v = var->GetGenericRep(CVAR_Bool); vid_fullscreen = v.Float; } + } + if (last < 221) + { + // Transfer the messed up mouse scaling config to something sane and consistent. +#ifndef _WIN32 + double xfact = 3, yfact = 2; +#else + double xfact = in_mouse == 1? 1.5 : 4, yfact = 1; +#endif + auto var = FindCVar("m_noprescale", NULL); + if (var != NULL) + { + UCVarValue v = var->GetGenericRep(CVAR_Bool); + if (v.Bool) xfact = yfact = 1; + } + + var = FindCVar("mouse_sensitivity", NULL); + if (var != NULL) + { + UCVarValue v = var->GetGenericRep(CVAR_Float); + xfact *= v.Float; + yfact *= v.Float; + } + m_sensitivity_x = (float)xfact; + m_sensitivity_y = (float)yfact; } } diff --git a/src/version.h b/src/version.h index 0cc4b8af7..2f72000ef 100644 --- a/src/version.h +++ b/src/version.h @@ -65,7 +65,7 @@ const char *GetVersionString(); // Version stored in the ini's [LastRun] section. // Bump it if you made some configuration change that you want to // be able to migrate in FGameConfigFile::DoGlobalSetup(). -#define LASTRUNVERSION "220" +#define LASTRUNVERSION "221" // Protocol version used in demos. // Bump it if you change existing DEM_ commands or add new ones. diff --git a/wadsrc/static/language.csv b/wadsrc/static/language.csv index 73fc1b374..cb89519d1 100644 --- a/wadsrc/static/language.csv +++ b/wadsrc/static/language.csv @@ -2815,8 +2815,8 @@ Enable mouse,MOUSEMNU_ENABLEMOUSE,,,,Povolit myš,Maus aktiv,Ενεργοποί Enable mouse in menus,MOUSEMNU_MOUSEINMENU,,,,Povolit myš v nabídkách,Maus aktiv in Menüs,Ενεργοποίηση Ποντικιού στα Μενού ,Aktivigi muson en menuoj,Usa ratón en los menús,,Ota hiiri käyttöön valikoissa,Activer Souris dans les Menus,Egér engedélyezése a menüben.,Abilita il mouse nei menu,メニューでのマウスの使用,메뉴에서 마우스 사용,Muis in menu's inschakelen,Włącz myszkę w menu,Habilitar mouse nos menus,Permitir rato nos menus,Permite navigarea cu mouse în meniuri,Использовать мышь в меню,Укључи миш у менијима Show back button,MOUSEMNU_SHOWBACKBUTTON,,,,Zobrazit tlačítko zpět,Zeige Zurück-Knopf,,Montri antaŭklavon,Botón de retroceso,,Näytä taaksenäppäin,Afficher le bouton retour,Vissza gomb mutatása,Mostra il bottone per tornare indietro,戻るボタンを表示,뒤로가기 버튼 보이기,Toon terugknop,Pokaż przycisk powrotu,Mostrar botão de voltar,,"Afișează butonul ""Înapoi""",Расположение кнопки «назад»,Прикажи тастер за назад Cursor,MOUSEMNU_CURSOR,,,,Kurzor,,,Musmontrilo,,,Osoitin,Curseur,Egérmutató,Cursore,カーソル,커서,,Kursor,,,Cursor,Курсор,Курсор -Overall sensitivity,MOUSEMNU_SENSITIVITY,,,,Celková citlivost,Allgemeine Empfindlichkeit,,Tutsentemo,Sensibilidad promedio,,Yleinen herkkyys,Sensibilité générale,Teljes érzékenység,Sensibilità complessiva,全体的な感度,전체 민감도,Algemene gevoeligheid,Ogólna wrażliwość,Sensibilidade geral,,Sensibilitate mouse per ansamblu,Общая чувствительность,Осетљивост -Prescale mouse movement,MOUSEMNU_NOPRESCALE,,,,Akcelerace myši,Mausbewegung skalieren,,Antaŭpesilo musmovo,Pre-escalar movimiento,,Esiskaalaa hiiren liike,Prescaling mouvement souris,,Prescala il movimento del mouse,マウス操作の精密化,속도 높인 움직임,Muisbewegingen vooraf inschalen,Przeskaluj ruch myszki,Movimento pré-escalar do mouse,Movimento pré-escalar do rato,Sensibilitate mărită,Увеличенная чувствительность,Убрзање миша +Horizontal sensitivity,MOUSEMNU_SENSITIVITY_X,,,,Horizontální citlivost,Horizontale Empfindlichkeit,Οριζόντια ευαισθησία,Horizontala sentemo,Sensibilidad horizontal,,Vaakasuuntainen herkkyys,Sensibilité horizontale,Vízszintes érzékenység,Sensibilità orizzontale,水平感度,수평 감도,Horizontale gevoeligheid,Czułość pozioma,Sensibilidade horizontal,,Sensibilitate orizontală,Горизонтальная чувствительность,Хоризонтална осетљивост +Vertical sensitivity,MOUSEMNU_SENSITIVITY_Y,,,,Vertikální citlivost,Vertikale Empfindlichkeit,Κάθετη ευαισθησία,Vertikala sentemo,Sensibilidad vertical,,Pystysuuntainen herkkyys,Sensibilité verticale,Függőleges érzékenység,Sensibilità verticale,垂直感度,수직 감도,Verticale gevoeligheid,Czułość pionowa,Sensibilidade vertical,,Sensibilitate verticală,Вертикальная чувствительность,Вертикална осетљивост Smooth mouse movement,MOUSEMNU_SMOOTHMOUSE,,,,Vyhladit pohyb myši,Mausbewegung glätten,,Glata musmovo,Mov. fluido del ratón,,Sulava hiiren liike,Lissage Souris,Egyenletes egérmozdulatok,Movimento del mouse liscio,マウス操作を滑らかにする,부드러운 움직임,Vloeiende muisbeweging,Gładki ruch myszki,Movimento fluído do mouse,Movimento fluído do rato,Mișcare fină mouse,Плавное перемещение,Глатки окрет Turning speed,MOUSEMNU_TURNSPEED,,,,Rychlost otáčení,Umdrehgeschwindigkeit,,Turnorapido,Velocidad de giro,,Kääntymisnopeus,Vitesse pour tourner,Fordulási sebesség,Velocità di rotazione,旋回速度,회전 속도,Draaisnelheid,Szybkość obracania się,Velocidade de giro,,Viteză rotire,Скорость поворота,Брзина окрета Mouselook speed,MOUSEMNU_MOUSELOOKSPEED,,,,Rychlost pohledu nahoru/dolů,Mausblick-Geschwindigkeit,,Musrigarda rapido.,Veloc. de vista con ratón,,Katselunopeus,Vitesse Vue Souris,Egérrel való nézés sebessége,Velocità di rotazione della vista,上下視点速度,마우스룩 속도,Mouseaanzichtssnelheid,Szybkość rozglądania się myszką,Velocidade de vista com mouse,Velocidade de vista com rato,Viteză Privire în Jur cu mouse,Скорость обзора,Брзина гледања мишем diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index b20948960..5d8d7ce74 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -734,8 +734,8 @@ OptionMenu "MouseOptions" protected Option "$MOUSEMNU_SHOWBACKBUTTON", "m_show_backbutton", "Corners", "use_mouse" Option "$MOUSEMNU_CURSOR", "vid_cursor", "Cursors" StaticText "" - Slider "$MOUSEMNU_SENSITIVITY", "mouse_sensitivity", 0.5, 2.5, 0.1 - Option "$MOUSEMNU_NOPRESCALE", "m_noprescale", "NoYes" + Slider "$MOUSEMNU_SENSITIVITY_X", "m_sensitivity_x", 0.5, 8, 0.25 + Slider "$MOUSEMNU_SENSITIVITY_Y", "m_sensitivity_y", 0.5, 8, 0.25 Option "$MOUSEMNU_SMOOTHMOUSE", "m_filter", "YesNo" StaticText "" Slider "$MOUSEMNU_TURNSPEED", "m_yaw", 0, 2.5, 0.1 @@ -744,7 +744,7 @@ OptionMenu "MouseOptions" protected Slider "$MOUSEMNU_STRAFESPEED", "m_side", 0, 2.5, 0.1 StaticText "" Option "$MOUSEMNU_ALWAYSMOUSELOOK", "freelook", "OnOff" - Option "$MOUSEMNU_INVERTMOUSEX", "invertmousex", "OnOff" + Option "$MOUSEMNU_INVERTMOUSEX", "invertmousex", "OnOff" Option "$MOUSEMNU_INVERTMOUSE", "invertmouse", "OnOff" Option "$MOUSEMNU_LOOKSPRING", "lookspring", "OnOff" Option "$MOUSEMNU_LOOKSTRAFE", "lookstrafe", "OnOff"