From c9b10b5bdcbf830e8bc9c76c0c6103ed6267833b Mon Sep 17 00:00:00 2001 From: "Javier S. Pedro" Date: Fri, 28 Aug 2009 21:03:08 +0200 Subject: [PATCH] touchscreen controls --- platform/platform.h | 3 +- platform/sdl.cpp | 2 +- platform/sdli.cpp | 127 ++++++++++++++++++++++++++++++++++++++++++++------- platform/sdlv.cpp | 11 +++++ 4 files changed, 124 insertions(+), 19 deletions(-) diff --git a/platform/platform.h b/platform/platform.h index 75ef7d2..f261bb6 100644 --- a/platform/platform.h +++ b/platform/platform.h @@ -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 diff --git a/platform/sdl.cpp b/platform/sdl.cpp index 7da4fa7..4597ad3 100644 --- a/platform/sdl.cpp +++ b/platform/sdl.cpp @@ -265,7 +265,7 @@ void S9xDoAction(unsigned char action) if (action & kActionToggleFullscreen) { S9xVideoToggleFullscreen(); - S9xInputFullscreenChanged(); + S9xInputScreenChanged(); } } diff --git a/platform/sdli.cpp b/platform/sdli.cpp index 3fb883f..d7ff176 100644 --- a/platform/sdli.cpp +++ b/platform/sdli.cpp @@ -1,18 +1,109 @@ #include +#include #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); + } } diff --git a/platform/sdlv.cpp b/platform/sdlv.cpp index 3d1a29c..641e92e 100644 --- a/platform/sdlv.cpp +++ b/platform/sdlv.cpp @@ -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 () { -- 1.7.9.5