touchscreen controls
authorJavier S. Pedro <maemo@javispedro.com>
Fri, 28 Aug 2009 19:03:08 +0000 (21:03 +0200)
committerJavier S. Pedro <maemo@javispedro.com>
Fri, 28 Aug 2009 19:03:08 +0000 (21:03 +0200)
platform/platform.h
platform/sdl.cpp
platform/sdli.cpp
platform/sdlv.cpp

index 75ef7d2..f261bb6 100644 (file)
@@ -31,6 +31,7 @@ extern struct config {
 
 // Video
 void S9xVideoToggleFullscreen();
+void S9xVideoGetWindowSize(unsigned int * w, unsigned int * h);
 void S9xVideoOutputFocus(bool hasFocus);
 
 // Audio output
@@ -41,7 +42,7 @@ void S9xAudioOutputEnable(bool enable);
 // Input devices
 EXTERN_C void S9xInitInputDevices();
 void S9xDeinitInputDevices();
-void S9xInputFullscreenChanged();
+void S9xInputScreenChanged();
 
 // Input actions
 #define kActionNone                                            0
index 7da4fa7..4597ad3 100644 (file)
@@ -265,7 +265,7 @@ void S9xDoAction(unsigned char action)
 
        if (action & kActionToggleFullscreen) {
                S9xVideoToggleFullscreen();
-               S9xInputFullscreenChanged();
+               S9xInputScreenChanged();
        }
 }
 
index 3fb883f..d7ff176 100644 (file)
 #include <SDL.h>
+#include <math.h>
 
 #include "platform.h"
 #include "snes9x.h"
 #include "display.h"
 
-#define kPollEveryNFrames      3
+struct TouchButton {
+       unsigned short mask;
+       unsigned short x, y;
+       unsigned short x2, y2;
+       float fx, fy;
+       float fw, fh;
+};
+
+#define TOUCH_BUTTON_INITIALIZER(name, x, y, w, h) \
+       {SNES_##name##_MASK, 0, 0, 0, 0, x, y, w, h}
+
+TouchButton touchbuttons[] = {
+       TOUCH_BUTTON_INITIALIZER(TL, 0, 0, 0.375, 0.0833),
+       TOUCH_BUTTON_INITIALIZER(TR, 0.625, 0, 0.375, 0.0833),
+       TOUCH_BUTTON_INITIALIZER(UP, 0.125, 0, 0.125, 0.2777), //2
+       TOUCH_BUTTON_INITIALIZER(LEFT, 0.0, 0.2777, 0.125, 0.2777), //3
+       TOUCH_BUTTON_INITIALIZER(RIGHT, 0.25, 0.2777, 0.125, 0.2777), //4
+       TOUCH_BUTTON_INITIALIZER(DOWN, 0.125, 0.5555, 0.125, 0.2777), //5
+       TOUCH_BUTTON_INITIALIZER(START, 0, 0.9166, 0.375, 0.0833),
+       TOUCH_BUTTON_INITIALIZER(Y, 0.75, 0, 0.125, 0.2777),
+       TOUCH_BUTTON_INITIALIZER(X, 0.625, 0.2777, 0.125, 0.2777),
+       TOUCH_BUTTON_INITIALIZER(A, 0.875, 0.2777, 0.125, 0.2777),
+       TOUCH_BUTTON_INITIALIZER(B, 0.75, 0.5555, 0.125, 0.2777),
+       TOUCH_BUTTON_INITIALIZER(SELECT, 0.625, 0.9166, 0.375, 0.0833),
+};
+
+static TouchButton* current = 0;
 
 static uint32 joypads[2];
 static struct {
        unsigned x;
        unsigned y;
-       bool pressed;
+       bool enabled, pressed;
 } mouse;
 
+static TouchButton* getButtonFor(unsigned int x, unsigned int y) {
+       unsigned int i;
+
+       for (i = 0; i < sizeof(touchbuttons)/sizeof(TouchButton); i++) {
+               if (x > touchbuttons[i].x && x < touchbuttons[i].x2 &&
+                       y > touchbuttons[i].y && y < touchbuttons[i].y2) {
+
+                       return &touchbuttons[i];
+               }
+       }
+
+       return 0;
+}
+
+static inline void unpress(TouchButton* b) {
+       joypads[0] &= ~b->mask;
+}
+static inline void press(TouchButton* b) {
+       joypads[0] |= b->mask;
+}
+
+static void processMouse(unsigned int x, unsigned int y, int pressed = 0)
+{
+       if (Config.touchscreenInput) {
+               if (pressed < 0) {
+                       // Button up.
+                       if (current) {
+                               // Leaving button
+                               unpress(current);
+                               current = 0;
+                       }
+               } else {
+                       // Button down, or mouse motion.
+                       TouchButton* b = getButtonFor(x, y);
+                       if (current && b && current != b) {
+                               // Moving from button to button
+                               unpress(current);
+                               current = b;
+                               press(current);
+                       } else if (current && !b) {
+                               // Leaving button
+                               unpress(current);
+                               current = 0;
+                       } else if (!current && b) {
+                               // Entering button
+                               current = b;
+                               press(current);
+                       }
+               }
+       } else if (mouse.enabled) {
+               // TODO Review this
+               mouse.x = x;
+               mouse.y = y;
+               if (Config.xsp) {
+                       mouse.x /= 2;
+                       mouse.y /= 2;
+               }
+               if (pressed > 0)
+                       mouse.pressed = true;
+               else if (pressed < 0)
+                       mouse.pressed = false;
+       }
+}
+
 static void processEvent(const SDL_Event& event)
 {
        switch (event.type) 
@@ -27,21 +118,11 @@ static void processEvent(const SDL_Event& event)
                break;
        case SDL_MOUSEBUTTONUP:
        case SDL_MOUSEBUTTONDOWN:
-               mouse.x = event.button.x;
-               mouse.y = event.button.y;
-               if (Config.xsp) {
-                       mouse.x /= 2;
-                       mouse.y /= 2;
-               }
-               mouse.pressed = event.button.state == SDL_PRESSED;
+               processMouse(event.button.x, event.button.y,
+                               (event.button.state == SDL_PRESSED) ? 1 : - 1);
                break;
        case SDL_MOUSEMOTION:
-               mouse.x = event.motion.x;
-               mouse.y = event.motion.y;
-               if (Config.xsp) {
-                       mouse.x /= 2;
-                       mouse.y /= 2;
-               }
+               processMouse(event.motion.x, event.motion.y);
                break;
        case SDL_QUIT:
                Config.quitting = true;
@@ -105,19 +186,24 @@ void S9xInitInputDevices()
                        break;
                case SNES_MOUSE:
                        joypads[0] = 0x80000000UL;
+                       mouse.enabled = true;
                        printf("Input: 1 joypad + mouse\n");
                        break;
                case SNES_MOUSE_SWAPPED:
                        printf("Input: mouse\n");
+                       mouse.enabled = true;
                        break;
                case SNES_SUPERSCOPE:
                        joypads[0] = 0x80000000UL;
+                       mouse.enabled = true;
                        printf("Input: 1 joypad + superscope\n");
                        break;
                default:
                        printf("Input: unknown\n");
                        break;
        }
+
+       S9xInputScreenChanged();
 }
 
 void S9xDeinitInputDevices()
@@ -125,8 +211,15 @@ void S9xDeinitInputDevices()
 
 }
 
-void S9xInputFullscreenChanged()
+void S9xInputScreenChanged()
 {
-
+       unsigned int i = 0, w = 0, h = 0;
+       S9xVideoGetWindowSize(&w, &h);
+       for (i = 0; i < sizeof(touchbuttons)/sizeof(TouchButton); i++) {
+               touchbuttons[i].x = (unsigned)round(touchbuttons[i].fx * w);
+               touchbuttons[i].y = (unsigned)round(touchbuttons[i].fy * h);
+               touchbuttons[i].x2 = (unsigned)round(touchbuttons[i].x + touchbuttons[i].fw * w);
+               touchbuttons[i].y2 = (unsigned)round(touchbuttons[i].y + touchbuttons[i].fh * h);
+       }
 }
 
index 3d1a29c..641e92e 100644 (file)
@@ -219,6 +219,17 @@ void S9xVideoOutputFocus(bool hasFocus)
        } 
 }
 
+void S9xVideoGetWindowSize(unsigned int* w, unsigned int* h)
+{
+       if (Config.fullscreen) {
+               *w = screenSize.w;
+               *h = screenSize.h;
+       } else {
+               *w = windowSize.w;
+               *h = windowSize.h;
+       }
+}
+
 // This is here for completeness, but palette mode is useless on N8x0
 void S9xSetPalette ()
 {