- cleanup of mouse input code and removal of all magic factors.

Sensitivity scaling of both axes is now exposed as a raw factor to the user instead of obscuring it behind an unclear 'prescale' boolean.
This also consolidates the coordinate processing code to prevent such discrepancies as were present here from happening again.
Migration code for old config settings is present so that this change does not affect existing configurations.
This commit is contained in:
Christoph Oelckers 2020-09-28 21:13:34 +02:00
parent cd6ef67209
commit 51518d63a4
13 changed files with 139 additions and 187 deletions

View file

@ -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;

View file

@ -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
{

View file

@ -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;

View file

@ -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);
}

View file

@ -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 ()

View file

@ -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();

View file

@ -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.
}
//==========================================================================

View file

@ -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;

View file

@ -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;
}

View file

@ -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;
}
}

View file

@ -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.

View file

@ -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,Скорость обзора,Брзина гледања мишем

Can't render this file because it is too large.

View file

@ -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"