Skip to content

Commit 89d8b59

Browse files
committed
Actually check the mouse position when clicking, instead of just assuming people clicked wherever the mouse moves to later.
In theory, this should make the UI usable, even on machines that don't consistently get 10000 FPS. Because WZ widgets are weird, just make the widgets pretend that the mouse stopped moving after clicking or releasing in a given frame. If you click twice in the same frame, the second widget will still greedily steal the mouse click from the first widget. Changelog: Try to improve UI responsiveness under low framerates.
1 parent b25bc87 commit 89d8b59

File tree

4 files changed

+48
-3
lines changed

4 files changed

+48
-3
lines changed

lib/framework/input.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ typedef enum _key_state
5050
typedef struct _input_state {
5151
KEY_STATE state; /// Last key/mouse state
5252
UDWORD lastdown; /// last key/mouse button down timestamp
53+
Vector2i pressPos; ///< Location of last mouse press event.
54+
Vector2i releasePos; ///< Location of last mouse release event.
5355
} INPUT_STATE;
5456

5557
/// constant for the interval between 2 singleclicks for doubleclick event in ms
@@ -317,9 +319,14 @@ void inputHandleKeyEvent(SDL_KeyboardEvent * keyEvent)
317319
*/
318320
void inputHandleMouseButtonEvent(SDL_MouseButtonEvent * buttonEvent)
319321
{
322+
mouseXPos = buttonEvent->x;
323+
mouseYPos = buttonEvent->y;
324+
320325
switch (buttonEvent->type)
321326
{
322327
case SDL_MOUSEBUTTONDOWN:
328+
aMouseState[buttonEvent->button].pressPos.x = mouseXPos;
329+
aMouseState[buttonEvent->button].pressPos.y = mouseYPos;
323330
if ( aMouseState[buttonEvent->button].state == KEY_UP
324331
|| aMouseState[buttonEvent->button].state == KEY_RELEASED
325332
|| aMouseState[buttonEvent->button].state == KEY_PRESSRELEASE )
@@ -355,6 +362,8 @@ void inputHandleMouseButtonEvent(SDL_MouseButtonEvent * buttonEvent)
355362
}
356363
break;
357364
case SDL_MOUSEBUTTONUP:
365+
aMouseState[buttonEvent->button].releasePos.x = mouseXPos;
366+
aMouseState[buttonEvent->button].releasePos.y = mouseYPos;
358367
if (aMouseState[buttonEvent->button].state == KEY_PRESSED)
359368
{
360369
aMouseState[buttonEvent->button].state = KEY_PRESSRELEASE;
@@ -489,6 +498,16 @@ Uint16 mouseY(void)
489498
return mouseYPos;
490499
}
491500

501+
Vector2i mousePressPos(MOUSE_KEY_CODE code)
502+
{
503+
return aMouseState[code].pressPos;
504+
}
505+
506+
Vector2i mouseReleasePos(MOUSE_KEY_CODE code)
507+
{
508+
return aMouseState[code].releasePos;
509+
}
510+
492511
/* This returns true if the mouse key is currently depressed */
493512
bool mouseDown(MOUSE_KEY_CODE code)
494513
{

lib/framework/input.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include <SDL.h>
3434
#include "types.h"
3535
#include "lib/framework/utf.h"
36+
#include "vector.h"
3637

3738
/** Defines for all the key codes used. */
3839
typedef enum _key_code
@@ -184,6 +185,11 @@ extern Uint16 mouseX(void) WZ_DECL_PURE;
184185
/** Return the current Y position of the mouse. */
185186
extern Uint16 mouseY(void) WZ_DECL_PURE;
186187

188+
/// Return the position of the mouse where it was clicked last.
189+
Vector2i mousePressPos(MOUSE_KEY_CODE code) WZ_DECL_PURE;
190+
/// Return the position of the mouse where it was released last.
191+
Vector2i mouseReleasePos(MOUSE_KEY_CODE code) WZ_DECL_PURE;
192+
187193
/** This returns true if the mouse key is currently depressed. */
188194
extern bool mouseDown(MOUSE_KEY_CODE code);
189195

lib/widget/widget.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1451,34 +1451,41 @@ UDWORD widgRunScreen(W_SCREEN *psScreen)
14511451

14521452
// Note which keys have been pressed
14531453
pressed = WKEY_NONE;
1454+
sContext.mx = mouseX();
1455+
sContext.my = mouseY();
14541456
if(getWidgetsStatus())
14551457
{
1456-
14571458
if (mousePressed(MOUSE_LMB))
14581459
{
14591460
pressed = WKEY_PRIMARY;
1461+
sContext.mx = mousePressPos(MOUSE_LMB).x;
1462+
sContext.my = mousePressPos(MOUSE_LMB).y;
14601463
}
14611464
else if (mousePressed(MOUSE_RMB))
14621465
{
14631466
pressed = WKEY_SECONDARY;
1467+
sContext.mx = mousePressPos(MOUSE_RMB).x;
1468+
sContext.my = mousePressPos(MOUSE_RMB).y;
14641469
}
14651470
released = WKEY_NONE;
14661471
if (mouseReleased(MOUSE_LMB))
14671472
{
14681473
released = WKEY_PRIMARY;
1474+
sContext.mx = mouseReleasePos(MOUSE_LMB).x;
1475+
sContext.my = mouseReleasePos(MOUSE_LMB).y;
14691476
}
14701477
else if (mouseReleased(MOUSE_RMB))
14711478
{
14721479
released = WKEY_SECONDARY;
1480+
sContext.mx = mouseReleasePos(MOUSE_RMB).x;
1481+
sContext.my = mouseReleasePos(MOUSE_RMB).y;
14731482
}
14741483
}
14751484
/* Initialise the context */
14761485
sContext.psScreen = psScreen;
14771486
sContext.psForm = (W_FORM *)psScreen->psForm;
14781487
sContext.xOffset = 0;
14791488
sContext.yOffset = 0;
1480-
sContext.mx = mouseX();
1481-
sContext.my = mouseY();
14821489
psMouseOverWidget = NULL;
14831490

14841491
/* Process the screen's widgets */

src/display.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,16 @@ void ProcessRadarInput(void)
392392

393393
if (mousePressed(MOUSE_ORDER) || (mousePressed(MOUSE_MMB) && keyDown(KEY_LALT)))
394394
{
395+
if (mousePressed(MOUSE_ORDER))
396+
{
397+
x = mousePressPos(MOUSE_ORDER).x;
398+
y = mousePressPos(MOUSE_ORDER).y;
399+
}
400+
else
401+
{
402+
x = mousePressPos(MOUSE_MMB).x;
403+
y = mousePressPos(MOUSE_MMB).y;
404+
}
395405
if(driveModeActive()) {
396406
driveProcessRadarInput(x,y);
397407
} else {
@@ -431,6 +441,9 @@ void ProcessRadarInput(void)
431441
}
432442
else if (mousePressed(MOUSE_SELECT))
433443
{
444+
x = mousePressPos(MOUSE_SELECT).x;
445+
y = mousePressPos(MOUSE_SELECT).y;
446+
434447
CalcRadarPosition(x, y, &PosX, &PosY);
435448

436449
if(bInstantRadarJump)

0 commit comments

Comments
 (0)