7 #include "sdlv.h" // Dispatching video-related events
12 unsigned short x2, y2;
17 #define TOUCH_BUTTON_INITIALIZER(name, x, y, w, h) \
18 {SNES_##name##_MASK, 0, 0, 0, 0, x, y, w, h}
20 #define kCornerButtonWidth (0.375)
21 #define kCornerButtonHeight (0.0833333333334)
22 #define kBigButtonWidth (0.125)
23 #define kBigButtonHeight (0.2777777777778)
25 static TouchButton touchbuttons[] = {
26 TOUCH_BUTTON_INITIALIZER(TL, 0.0, 0.0, kCornerButtonWidth, kCornerButtonHeight),
27 TOUCH_BUTTON_INITIALIZER(TR, 0.625, 0.0, kCornerButtonWidth, kCornerButtonHeight),
28 TOUCH_BUTTON_INITIALIZER(UP, kBigButtonWidth, kCornerButtonHeight, kBigButtonWidth, kBigButtonHeight),
29 TOUCH_BUTTON_INITIALIZER(LEFT, 0.0, kCornerButtonHeight + kBigButtonHeight, kBigButtonWidth, kBigButtonHeight),
30 TOUCH_BUTTON_INITIALIZER(RIGHT, 2.0 * kBigButtonWidth, kCornerButtonHeight + kBigButtonHeight, kBigButtonWidth, kBigButtonHeight),
31 TOUCH_BUTTON_INITIALIZER(DOWN, kBigButtonWidth, 1.0 - (kCornerButtonHeight + kBigButtonHeight), kBigButtonWidth, kBigButtonHeight),
32 TOUCH_BUTTON_INITIALIZER(SELECT, 0.0, 1.0 - kCornerButtonHeight, kCornerButtonWidth, kCornerButtonHeight),
33 TOUCH_BUTTON_INITIALIZER(X, 1.0 - 2.0 * kBigButtonWidth, kCornerButtonHeight, kBigButtonWidth, kBigButtonHeight),
34 TOUCH_BUTTON_INITIALIZER(Y, 1.0 - 3.0 * kBigButtonWidth, kCornerButtonHeight + kBigButtonHeight, kBigButtonWidth, kBigButtonHeight),
35 TOUCH_BUTTON_INITIALIZER(A, 1.0 - kBigButtonWidth, kCornerButtonHeight + kBigButtonHeight, kBigButtonWidth, kBigButtonHeight),
36 TOUCH_BUTTON_INITIALIZER(B, 1.0 - 2.0 * kBigButtonWidth, 1.0 - (kCornerButtonHeight + kBigButtonHeight), kBigButtonWidth, kBigButtonHeight),
37 TOUCH_BUTTON_INITIALIZER(START, 1.0 - kCornerButtonWidth, 1.0 - kCornerButtonHeight, kCornerButtonWidth, kCornerButtonHeight),
40 static TouchButton* current = 0;
42 static uint32 joypads[2];
46 bool enabled, pressed;
49 static TouchButton* getButtonFor(unsigned int x, unsigned int y) {
52 for (i = 0; i < sizeof(touchbuttons)/sizeof(TouchButton); i++) {
53 if (x >= touchbuttons[i].x && x < touchbuttons[i].x2 &&
54 y >= touchbuttons[i].y && y < touchbuttons[i].y2) {
56 return &touchbuttons[i];
63 static inline void unpress(TouchButton* b) {
64 joypads[0] &= ~b->mask;
66 static inline void press(TouchButton* b) {
67 joypads[0] |= b->mask;
70 static void processMouse(unsigned int x, unsigned int y, int pressed = 0)
73 /* no fullscreen escape button, we have to simulate one! */
74 /* TODO: don't hardcode sizes */
75 if (Config.fullscreen && x > (800 - 100) && y < 50 && pressed > 0) {
76 S9xDoAction(kActionQuit);
79 if (Config.touchscreenInput) {
88 // Button down, or mouse motion.
89 TouchButton* b = getButtonFor(x, y);
90 if (current && b && current != b) {
91 // Moving from button to button
95 } else if (current && !b) {
99 } else if (!current && b) {
105 } else if (mouse.enabled) {
109 if (mouse.x < GUI.RenderX) mouse.x = 0;
111 mouse.x -= GUI.RenderX;
112 if (mouse.x > GUI.RenderW) mouse.x = GUI.RenderW;
115 if (mouse.y < GUI.RenderY) mouse.y = 0;
117 mouse.y -= GUI.RenderY;
118 if (mouse.y > GUI.RenderH) mouse.y = GUI.RenderH;
121 // mouse.{x,y} are system coordinates.
122 // Scale them to emulated screen coordinates.
123 mouse.x = static_cast<unsigned int>(mouse.x / GUI.ScaleX);
124 mouse.y = static_cast<unsigned int>(mouse.y / GUI.ScaleY);
127 mouse.pressed = true;
128 else if (pressed < 0)
129 mouse.pressed = false;
133 static void processEvent(const SDL_Event& event)
138 if (Config.action[event.key.keysym.scancode])
139 S9xDoAction(Config.action[event.key.keysym.scancode]);
140 joypads[0] |= Config.joypad1Mapping[event.key.keysym.scancode];
141 joypads[1] |= Config.joypad2Mapping[event.key.keysym.scancode];
144 joypads[0] &= ~Config.joypad1Mapping[event.key.keysym.scancode];
145 joypads[1] &= ~Config.joypad2Mapping[event.key.keysym.scancode];
147 case SDL_MOUSEBUTTONUP:
148 case SDL_MOUSEBUTTONDOWN:
149 processMouse(event.button.x, event.button.y,
150 (event.button.state == SDL_PRESSED) ? 1 : - 1);
152 case SDL_MOUSEMOTION:
153 processMouse(event.motion.x, event.motion.y);
156 Config.quitting = true;
158 case SDL_ACTIVEEVENT:
160 processVideoEvent(event);
165 /** This function is called to return a bit-wise mask of the state of one of the
166 five emulated SNES controllers.
168 @return 0 if you're not supporting controllers past a certain number or
169 return the mask representing the current state of the controller number
170 passed as a parameter or'ed with 0x80000000.
173 uint32 S9xReadJoypad (int which)
175 if (which < 0 || which >= 2) {
176 // More joypads that we currently handle (could happen if bad conf)
180 return joypads[which];
183 /** Get the current position of the host pointing device, usually a mouse,
184 used to emulated the SNES mouse.
186 @param buttons The buttons return value is a bit-wise mask of the two SNES
187 mouse buttons, bit 0 for button 1 (left) and bit 1 for button 2 (right).
189 bool8 S9xReadMousePosition(int which1, int& x, int& y, uint32& buttons)
191 if (which1 != 0) return FALSE;
195 buttons = mouse.pressed ? 1 : 0;
200 bool8 S9xReadSuperScopePosition(int& x, int& y, uint32& buttons)
204 buttons = mouse.pressed ? 8 : 0;
209 /** Get and process system/input events.
210 @param block true to block, false to poll until the queue is empty.
212 void S9xProcessEvents(bool block)
217 SDL_WaitEvent(&event);
220 while(SDL_PollEvent(&event)) {
226 void S9xInitInputDevices()
230 mouse.enabled = false;
231 mouse.pressed = false;
233 if (Config.joypad1Enabled) {
234 joypads[0] = 0x80000000UL;
236 if (Config.joypad2Enabled) {
237 joypads[1] = 0x80000000UL;
240 // Pretty print some information
242 if (Config.joypad1Enabled) {
243 printf("Player 1 (joypad)");
244 if (Config.joypad2Enabled) {
245 printf("+ player 2 (joypad)");
247 } else if (Config.joypad2Enabled) {
248 printf("Player 2 (joypad)");
254 // TODO Non-awful mouse support, Superscope
256 S9xInputScreenChanged();
259 void S9xDeinitInputDevices()
263 mouse.enabled = false;
264 mouse.pressed = false;
267 void S9xInputScreenChanged()
270 const unsigned int w = GUI.Width, h = GUI.Height;
271 for (i = 0; i < sizeof(touchbuttons)/sizeof(TouchButton); i++) {
272 touchbuttons[i].x = (unsigned int)(touchbuttons[i].fx * w);
273 touchbuttons[i].y = (unsigned int)(touchbuttons[i].fy * h);
274 touchbuttons[i].x2 = (unsigned int)(touchbuttons[i].x + touchbuttons[i].fw * w);
275 touchbuttons[i].y2 = (unsigned int)(touchbuttons[i].y + touchbuttons[i].fh * h);
279 template <typename T>
280 static void drawControls(T * buffer, const int pitch)
284 const T black = static_cast<T>(0xFFFFFFFFU);
287 for (i = 0; i < sizeof(touchbuttons)/sizeof(TouchButton); i++) {
288 temp = buffer + touchbuttons[i].y * pitch + touchbuttons[i].x;
289 for (x = touchbuttons[i].x; x < touchbuttons[i].x2; x++) {
293 temp = buffer + touchbuttons[i].y2 * pitch + touchbuttons[i].x;
294 for (x = touchbuttons[i].x; x < touchbuttons[i].x2; x++) {
298 temp = buffer + touchbuttons[i].y * pitch + touchbuttons[i].x;
299 for (y = touchbuttons[i].y; y < touchbuttons[i].y2; y++) {
303 temp = buffer + touchbuttons[i].y * pitch + touchbuttons[i].x2;
304 for (y = touchbuttons[i].y; y < touchbuttons[i].y2; y++) {
311 void S9xInputScreenDraw(int pixelSize, void * buffer, int pitch)
316 drawControls(reinterpret_cast<uint8*>(buffer), pitch);
319 drawControls(reinterpret_cast<uint16*>(buffer), pitch / 2);