shithub: choc

Download patch

ref: 2435f5bb4de3a31c38748a0cab70d654c3bd4a8f
parent: ec90c9fa062440dd25e4e7fe9a3df58db7c55081
author: Jonathan Dowland <jon+github@alcopop.org>
date: Sat Jul 2 18:22:25 EDT 2016

Fix mousewheel for SDL2 by synthesising buttons

SDL2 treats mouse wheel events as different from buttons.

Assuming we want the wheel to emulate buttons as per SDL1,
map the mouse wheel events to buttons. Use the mappings in
textscreen (down = 3, up = 4).

Fixes #722.

--- a/src/i_input.c
+++ b/src/i_input.c
@@ -355,6 +355,47 @@
     D_PostEvent(&event);
 }
 
+static void MapMouseWheelToButtons(SDL_MouseWheelEvent *wheel)
+{
+    // SDL2 distinguishes button events from mouse wheel events.
+    // We want to treat the mouse wheel as two buttons, as per
+    // SDL1
+    event_t event1, event2;
+    int y = wheel->y;
+    int button;
+
+#if !(SDL_MAJOR_VERSION == 2 && SDL_MINOR_VERSION == 0 && SDL_PATCHLEVEL < 4)
+    // Ignore OS axis inversion (so up is always up)
+    if (wheel->direction == SDL_MOUSEWHEEL_FLIPPED)
+    {
+        y *= -1;
+    }
+#endif
+
+    if (y <= 0)
+    {   // scroll down
+        button = 3;
+    }
+    else
+    {   // scroll up
+        button = 4;
+    }
+
+    // post a button down event
+    mouse_button_state |= (1 << button);
+    event1.type = ev_mouse;
+    event1.data1 = mouse_button_state;
+    event1.data2 = event1.data3 = 0;
+    D_PostEvent(&event1);
+
+    // post a button up event
+    mouse_button_state &= ~(1 << button);
+    event2.type = ev_mouse;
+    event2.data1 = mouse_button_state;
+    event2.data2 = event2.data3 = 0;
+    D_PostEvent(&event2);
+}
+
 void I_HandleMouseEvent(SDL_Event *sdlevent)
 {
     switch (sdlevent->type)
@@ -365,6 +406,10 @@
 
         case SDL_MOUSEBUTTONUP:
             UpdateMouseButtonState(sdlevent->button.button, false);
+            break;
+
+        case SDL_MOUSEWHEEL:
+            MapMouseWheelToButtons(&(sdlevent->wheel));
             break;
 
         default:
--- a/src/i_video.c
+++ b/src/i_video.c
@@ -418,6 +418,7 @@
 
             case SDL_MOUSEBUTTONDOWN:
             case SDL_MOUSEBUTTONUP:
+            case SDL_MOUSEWHEEL:
                 if (usemouse && !nomouse && window_focused)
                 {
                     I_HandleMouseEvent(&sdlevent);
--- a/textscreen/txt_sdl.c
+++ b/textscreen/txt_sdl.c
@@ -531,6 +531,30 @@
     }
 }
 
+// Convert an SDL wheel motion to a textscreen button index.
+
+static int SDLWheelToTXTButton(SDL_MouseWheelEvent *wheel)
+{
+    int y = wheel->y;
+
+#if !(SDL_MAJOR_VERSION == 2 && SDL_MINOR_VERSION == 0 && SDL_PATCHLEVEL < 4)
+    // Ignore OS axis inversion (so up is always up)
+    if (wheel->direction == SDL_MOUSEWHEEL_FLIPPED)
+    {
+        y *= -1;
+    }
+#endif
+
+    if (y <= 0)
+    {
+        return TXT_MOUSE_SCROLLDOWN;
+    }
+    else
+    {
+        return TXT_MOUSE_SCROLLUP;
+    }
+}
+
 static int MouseHasMoved(void)
 {
     static int last_x = 0, last_y = 0;
@@ -614,6 +638,9 @@
                     return SDLButtonToTXTButton(ev.button.button);
                 }
                 break;
+
+            case SDL_MOUSEWHEEL:
+                return SDLWheelToTXTButton(&ev.wheel);
 
             case SDL_KEYDOWN:
                 UpdateModifierState(&ev.key.keysym, 1);