X-Git-Url: http://vcs.maemo.org/git/?a=blobdiff_plain;f=platform%2Fsdli.cpp;h=3e0a118ea6b4ef42ee659615cfe7197ac60400b8;hb=2b158b830ecb8011d5b4d955ee0e42e28f1ceff5;hp=86b3223254496376a5011263763297d72e89eec3;hpb=96b93ff5f9e7aef51e96b218ddb2c7a7f658b7da;p=drnoksnes diff --git a/platform/sdli.cpp b/platform/sdli.cpp index 86b3223..3e0a118 100644 --- a/platform/sdli.cpp +++ b/platform/sdli.cpp @@ -3,7 +3,15 @@ #include "platform.h" #include "snes9x.h" -#include "display.h" +#include "sdlv.h" // Dispatching video-related events + +#if CONF_ZEEMOTE +#include "zeemote.h" +#endif + +#if !defined(SDL_MAXMOUSE) +#define SDL_MAXMOUSE 1 +#endif struct TouchButton { unsigned short mask; @@ -13,30 +21,36 @@ struct TouchButton { double fw, fh; }; -#define TOUCH_BUTTON_INITIALIZER(name, x, y, w, h) \ - {SNES_##name##_MASK, 0, 0, 0, 0, x, y, w, h} - #define kCornerButtonWidth (0.375) #define kCornerButtonHeight (0.0833333333334) #define kBigButtonWidth (0.125) #define kBigButtonHeight (0.2777777777778) static TouchButton touchbuttons[] = { - TOUCH_BUTTON_INITIALIZER(TL, 0.0, 0.0, kCornerButtonWidth, kCornerButtonHeight), - TOUCH_BUTTON_INITIALIZER(TR, 0.625, 0.0, kCornerButtonWidth, kCornerButtonHeight), - TOUCH_BUTTON_INITIALIZER(UP, kBigButtonWidth, kCornerButtonHeight, kBigButtonWidth, kBigButtonHeight), - TOUCH_BUTTON_INITIALIZER(LEFT, 0.0, kCornerButtonHeight + kBigButtonHeight, kBigButtonWidth, kBigButtonHeight), - TOUCH_BUTTON_INITIALIZER(RIGHT, 2.0 * kBigButtonWidth, kCornerButtonHeight + kBigButtonHeight, kBigButtonWidth, kBigButtonHeight), - TOUCH_BUTTON_INITIALIZER(DOWN, kBigButtonWidth, 1.0 - (kCornerButtonHeight + kBigButtonHeight), kBigButtonWidth, kBigButtonHeight), - TOUCH_BUTTON_INITIALIZER(SELECT, 0.0, 1.0 - kCornerButtonHeight, kCornerButtonWidth, kCornerButtonHeight), - TOUCH_BUTTON_INITIALIZER(X, 1.0 - 2.0 * kBigButtonWidth, kCornerButtonHeight, kBigButtonWidth, kBigButtonHeight), - TOUCH_BUTTON_INITIALIZER(Y, 1.0 - 3.0 * kBigButtonWidth, kCornerButtonHeight + kBigButtonHeight, kBigButtonWidth, kBigButtonHeight), - TOUCH_BUTTON_INITIALIZER(A, 1.0 - kBigButtonWidth, kCornerButtonHeight + kBigButtonHeight, kBigButtonWidth, kBigButtonHeight), - TOUCH_BUTTON_INITIALIZER(B, 1.0 - 2.0 * kBigButtonWidth, 1.0 - (kCornerButtonHeight + kBigButtonHeight), kBigButtonWidth, kBigButtonHeight), - TOUCH_BUTTON_INITIALIZER(START, 1.0 - kCornerButtonWidth, 1.0 - kCornerButtonHeight, kCornerButtonWidth, kCornerButtonHeight), +#define TB(actions, x, y, w, h) \ + {actions, 0, 0, 0, 0, x, y, w, h} +#define P(x) SNES_##x##_MASK + TB(P(TL), 0.0, 0.0, kCornerButtonWidth, kCornerButtonHeight), + TB(P(TR), 0.625, 0.0, kCornerButtonWidth, kCornerButtonHeight), + TB(P(LEFT) | P(UP), 0.0, kCornerButtonHeight, kBigButtonWidth, kBigButtonHeight), + TB(P(UP), kBigButtonWidth, kCornerButtonHeight, kBigButtonWidth, kBigButtonHeight), + TB(P(RIGHT) | P(UP), 2.0 * kBigButtonWidth, kCornerButtonHeight, kBigButtonWidth, kBigButtonHeight), + TB(P(LEFT), 0.0, kCornerButtonHeight + kBigButtonHeight, kBigButtonWidth, kBigButtonHeight), + TB(P(RIGHT), 2.0 * kBigButtonWidth, kCornerButtonHeight + kBigButtonHeight, kBigButtonWidth, kBigButtonHeight), + TB(P(LEFT) | P(DOWN), 0, 1.0 - (kCornerButtonHeight + kBigButtonHeight), kBigButtonWidth, kBigButtonHeight), + TB(P(DOWN), kBigButtonWidth, 1.0 - (kCornerButtonHeight + kBigButtonHeight), kBigButtonWidth, kBigButtonHeight), + TB(P(RIGHT) | P(DOWN), 2.0 * kBigButtonWidth, 1.0 - (kCornerButtonHeight + kBigButtonHeight), kBigButtonWidth, kBigButtonHeight), + TB(P(SELECT), 0.0, 1.0 - kCornerButtonHeight, kCornerButtonWidth, kCornerButtonHeight), + TB(P(X), 1.0 - 2.0 * kBigButtonWidth, kCornerButtonHeight, kBigButtonWidth, kBigButtonHeight), + TB(P(Y), 1.0 - 3.0 * kBigButtonWidth, kCornerButtonHeight + kBigButtonHeight, kBigButtonWidth, kBigButtonHeight), + TB(P(A), 1.0 - kBigButtonWidth, kCornerButtonHeight + kBigButtonHeight, kBigButtonWidth, kBigButtonHeight), + TB(P(B), 1.0 - 2.0 * kBigButtonWidth, 1.0 - (kCornerButtonHeight + kBigButtonHeight), kBigButtonWidth, kBigButtonHeight), + TB(P(START), 1.0 - kCornerButtonWidth, 1.0 - kCornerButtonHeight, kCornerButtonWidth, kCornerButtonHeight), +#undef P +#undef TB }; -static TouchButton* current = 0; +static TouchButton* current[SDL_MAXMOUSE] = { 0 }; static uint32 joypads[2]; static struct { @@ -60,38 +74,45 @@ static TouchButton* getButtonFor(unsigned int x, unsigned int y) { } static inline void unpress(TouchButton* b) { - joypads[0] &= ~b->mask; + joypads[Config.touchscreenInput - 1] &= ~b->mask; } static inline void press(TouchButton* b) { - joypads[0] |= b->mask; + joypads[Config.touchscreenInput - 1] |= b->mask; } -static void processMouse(unsigned int x, unsigned int y, int pressed = 0) +static void processMouse(int which, unsigned int x, unsigned int y, int pressed = 0) { +#if CONF_EXIT_BUTTON + /* no fullscreen escape button, we have to simulate one! */ + /* TODO: don't hardcode sizes */ + if (Config.fullscreen && x > (800 - 100) && y < 50 && pressed > 0) { + S9xDoAction(kActionQuit); + } +#endif if (Config.touchscreenInput) { if (pressed < 0) { // Button up. - if (current) { + if (current[which]) { // Leaving button - unpress(current); - current = 0; + unpress(current[which]); + current[which] = 0; } } else { // Button down, or mouse motion. TouchButton* b = getButtonFor(x, y); - if (current && b && current != b) { + if (current[which] && b && current[which] != b) { // Moving from button to button - unpress(current); - current = b; - press(current); - } else if (current && !b) { + unpress(current[which]); + current[which] = b; + press(current[which]); + } else if (current[which] && !b) { // Leaving button - unpress(current); - current = 0; - } else if (!current && b) { + unpress(current[which]); + current[which] = 0; + } else if (!current[which] && b) { // Entering button - current = b; - press(current); + current[which] = b; + press(current[which]); } } } else if (mouse.enabled) { @@ -110,9 +131,10 @@ static void processMouse(unsigned int x, unsigned int y, int pressed = 0) if (mouse.y > GUI.RenderH) mouse.y = GUI.RenderH; } - // Take care of scaling - mouse.x /= GUI.ScaleX; - mouse.y /= GUI.ScaleY; + // mouse.{x,y} are system coordinates. + // Scale them to emulated screen coordinates. + mouse.x = static_cast(mouse.x / GUI.ScaleX); + mouse.y = static_cast(mouse.y / GUI.ScaleY); if (pressed > 0) mouse.pressed = true; @@ -123,68 +145,90 @@ static void processMouse(unsigned int x, unsigned int y, int pressed = 0) static void processEvent(const SDL_Event& event) { + if (videoEventFilter(event)) return; + switch (event.type) { - case SDL_KEYDOWN: - if (Config.action[event.key.keysym.scancode]) - S9xDoAction(Config.action[event.key.keysym.scancode]); - joypads[0] |= Config.joypad1Mapping[event.key.keysym.scancode]; - break; - case SDL_KEYUP: - joypads[0] &= ~Config.joypad1Mapping[event.key.keysym.scancode]; - break; - case SDL_MOUSEBUTTONUP: - case SDL_MOUSEBUTTONDOWN: - processMouse(event.button.x, event.button.y, - (event.button.state == SDL_PRESSED) ? 1 : - 1); - break; - case SDL_MOUSEMOTION: - processMouse(event.motion.x, event.motion.y); - break; - case SDL_ACTIVEEVENT: - if (event.active.state & SDL_APPINPUTFOCUS) { - S9xVideoOutputFocus(event.active.gain); - } - break; - case SDL_QUIT: - Config.quitting = true; - break; + case SDL_KEYDOWN: + if (Config.action[event.key.keysym.scancode]) + S9xDoAction(Config.action[event.key.keysym.scancode]); + joypads[0] |= Config.joypad1Mapping[event.key.keysym.scancode]; + joypads[1] |= Config.joypad2Mapping[event.key.keysym.scancode]; + break; + case SDL_KEYUP: + joypads[0] &= ~Config.joypad1Mapping[event.key.keysym.scancode]; + joypads[1] &= ~Config.joypad2Mapping[event.key.keysym.scancode]; + break; + case SDL_MOUSEBUTTONUP: + case SDL_MOUSEBUTTONDOWN: + processMouse(event.button.which, event.button.x, event.button.y, + (event.button.state == SDL_PRESSED) ? 1 : - 1); + break; + case SDL_MOUSEMOTION: + processMouse(event.button.which, event.motion.x, event.motion.y); + break; + case SDL_QUIT: + Config.quitting = true; + break; } } +/** This function is called to return a bit-wise mask of the state of one of the + five emulated SNES controllers. + + @return 0 if you're not supporting controllers past a certain number or + return the mask representing the current state of the controller number + passed as a parameter or'ed with 0x80000000. +*/ + uint32 S9xReadJoypad (int which) { - if (which < 0 || which > 2) { + if (which < 0 || which >= 2) { + // More joypads that we currently handle (could happen if bad conf) return 0; } return joypads[which]; } -bool8 S9xReadMousePosition(int which1, int& x, int& y, uint32& buttons) +/** Get the current position of the host pointing device, usually a mouse, + used to emulated the SNES mouse. + + @param buttons The buttons return value is a bit-wise mask of the two SNES + mouse buttons, bit 0 for button 1 (left) and bit 1 for button 2 (right). +*/ +bool8 S9xReadMousePosition(int which, int *x, int *y, uint32 *buttons) { - if (which1 != 0) return FALSE; + if (which != 0) return FALSE; - x = mouse.x; - y = mouse.y; - buttons = mouse.pressed ? 1 : 0; + *x = mouse.x; + *y = mouse.y; + *buttons = mouse.pressed ? 1 : 0; return TRUE; } -bool8 S9xReadSuperScopePosition(int& x, int& y, uint32& buttons) +bool8 S9xReadSuperScopePosition(int *x, int *y, uint32 *buttons) { - x = mouse.x; - y = mouse.y; - buttons = mouse.pressed ? 8 : 0; + *x = mouse.x; + *y = mouse.y; + *buttons = mouse.pressed ? 8 : 0; return TRUE; } -void S9xProcessEvents(bool8_32 block) +/** Get and process system/input events. + @param block true to block, false to poll until the queue is empty. +*/ +void S9xProcessEvents(bool block) { SDL_Event event; +#if CONF_ZEEMOTE + // Wheter blocking or non blocking, poll zeemotes now. + ZeeRead(joypads); +#endif + if (block) { SDL_WaitEvent(&event); processEvent(event); @@ -199,37 +243,48 @@ void S9xInitInputDevices() { joypads[0] = 0; joypads[1] = 0; + mouse.enabled = false; + mouse.pressed = false; - switch (Settings.ControllerOption) { - case SNES_JOYPAD: - joypads[0] = 0x80000000UL; - printf("Input: 1 joypad, keyboard only\n"); - 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; +#if CONF_ZEEMOTE + ZeeInit(); +#endif + + if (Config.joypad1Enabled) { + joypads[0] = 0x80000000UL; + } + if (Config.joypad2Enabled) { + joypads[1] = 0x80000000UL; + } + + // Pretty print some information + printf("Input: "); + if (Config.joypad1Enabled) { + printf("Player 1 (joypad)"); + if (Config.joypad2Enabled) { + printf("+ player 2 (joypad)"); + } + } else if (Config.joypad2Enabled) { + printf("Player 2 (joypad)"); + } else { + printf("Nothing"); } + printf("\n"); + + // TODO Non-awful mouse & superscope support S9xInputScreenChanged(); } void S9xDeinitInputDevices() { - +#if CONF_ZEEMOTE + ZeeQuit(); +#endif + joypads[0] = 0; + joypads[1] = 0; + mouse.enabled = false; + mouse.pressed = false; } void S9xInputScreenChanged() @@ -276,16 +331,8 @@ static void drawControls(T * buffer, const int pitch) } } -void S9xInputScreenDraw(int pixelSize, void * buffer, int pitch) +void S9xInputScreenDraw(void * buffer, int pitch) { - switch (pixelSize) - { - case 1: - drawControls(reinterpret_cast(buffer), pitch); - break; - case 2: - drawControls(reinterpret_cast(buffer), pitch / 2); - break; - } + drawControls(reinterpret_cast(buffer), pitch / 2); }