/[pearpc]/src/system/ui/sdl/syssdl.cc
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /src/system/ui/sdl/syssdl.cc

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (hide annotations)
Wed Sep 5 17:11:21 2007 UTC (16 years, 8 months ago) by dpavlin
File size: 13214 byte(s)
import upstream CVS
1 dpavlin 1 /*
2     * PearPC
3     * syssdl.cc
4     *
5     * Copyright (C) 2004 Jens v.d. Heydt (mailme@vdh-webservice.de)
6     * Copyright (C) 1999-2002 Stefan Weyergraf
7     * Copyright (C) 1999-2004 Sebastian Biallas (sb@biallas.net)
8     *
9     * This program is free software; you can redistribute it and/or modify
10     * it under the terms of the GNU General Public License version 2 as
11     * published by the Free Software Foundation.
12     *
13     * This program is distributed in the hope that it will be useful,
14     * but WITHOUT ANY WARRANTY; without even the implied warranty of
15     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16     * GNU General Public License for more details.
17     *
18     * You should have received a copy of the GNU General Public License
19     * along with this program; if not, write to the Free Software
20     * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21     */
22    
23     #include <SDL.h>
24     #include <SDL_thread.h>
25    
26     #include <csignal>
27     #include <cstdlib>
28     #include <cstdio>
29     #include <unistd.h>
30     #include <cstring>
31    
32     // for stopping the CPU
33     #include "cpu/cpu.h"
34    
35     #include "system/sysclk.h"
36     #include "system/display.h"
37     #include "system/keyboard.h"
38     #include "system/mouse.h"
39     #include "system/systhread.h"
40     #include "system/systimer.h"
41    
42     #include "tools/snprintf.h"
43    
44     #include "syssdl.h"
45    
46     SDL_Surface * gSDLScreen;
47     static bool gSDLVideoExposePending = false;
48     SDL_TimerID SDL_RedrawTimerID;
49    
50     SDLSystemDisplay *sd;
51    
52     #if 0
53    
54     // Argl, this doesn't work, stupid SDL
55    
56     static uint8 sdl_key_to_adb_key[512];
57    
58     static struct {
59     SDLKey sdlkey;
60     uint8 adbkey;
61     } sdladbkeys[] = {
62     {SDLK_BACKSPACE, KEY_DELETE},
63     {SDLK_TAB, KEY_TAB},
64     {SDLK_RETURN, KEY_RETURN},
65     {SDLK_PAUSE, KEY_PAUSE},
66     {SDLK_ESCAPE, KEY_ESCAPE},
67     {SDLK_SPACE, KEY_SPACE},
68     {SDLK_COMMA, KEY_COMMA},
69     {SDLK_MINUS, KEY_MINUS},
70     {SDLK_PERIOD, KEY_PERIOD},
71     {SDLK_0, KEY_0},
72     {SDLK_1, KEY_1},
73     {SDLK_2, KEY_2},
74     {SDLK_3, KEY_3},
75     {SDLK_4, KEY_4},
76     {SDLK_5, KEY_5},
77     {SDLK_6, KEY_6},
78     {SDLK_7, KEY_7},
79     {SDLK_8, KEY_8},
80     {SDLK_9, KEY_9},
81     {SDLK_SEMICOLON, KEY_SEMICOLON},
82     {SDLK_LEFTBRACKET, KEY_BRACKET_R},
83     {SDLK_BACKSLASH, KEY_BACKSLASH},
84     {SDLK_RIGHTBRACKET, KEY_BRACKET_L},
85     {SDLK_BACKQUOTE, KEY_GRAVE},
86     {SDLK_a, KEY_a},
87     {SDLK_b, KEY_b},
88     {SDLK_c, KEY_c},
89     {SDLK_d, KEY_d},
90     {SDLK_e, KEY_e},
91     {SDLK_f, KEY_f},
92     {SDLK_g, KEY_g},
93     {SDLK_h, KEY_h},
94     {SDLK_i, KEY_i},
95     {SDLK_j, KEY_j},
96     {SDLK_k, KEY_k},
97     {SDLK_l, KEY_l},
98     {SDLK_m, KEY_m},
99     {SDLK_n, KEY_n},
100     {SDLK_o, KEY_o},
101     {SDLK_p, KEY_p},
102     {SDLK_q, KEY_q},
103     {SDLK_r, KEY_r},
104     {SDLK_s, KEY_s},
105     {SDLK_t, KEY_t},
106     {SDLK_u, KEY_u},
107     {SDLK_v, KEY_v},
108     {SDLK_w, KEY_w},
109     {SDLK_x, KEY_x},
110     {SDLK_y, KEY_y},
111     {SDLK_z, KEY_z},
112     {SDLK_DELETE, KEY_REMOVE},
113     {SDLK_KP0, KEY_KP_0},
114     {SDLK_KP1, KEY_KP_1},
115     {SDLK_KP2, KEY_KP_2},
116     {SDLK_KP3, KEY_KP_3},
117     {SDLK_KP4, KEY_KP_4},
118     {SDLK_KP5, KEY_KP_5},
119     {SDLK_KP6, KEY_KP_6},
120     {SDLK_KP7, KEY_KP_7},
121     {SDLK_KP8, KEY_KP_8},
122     {SDLK_KP9, KEY_KP_9},
123     {SDLK_KP_PERIOD, KEY_KP_PERIOD},
124     {SDLK_KP_DIVIDE, KEY_KP_DIVIDE},
125     {SDLK_KP_MULTIPLY, KEY_KP_MULTIPLY},
126     {SDLK_KP_MINUS, KEY_KP_SUBTRACT},
127     {SDLK_KP_PLUS, KEY_KP_ADD},
128     {SDLK_KP_ENTER, KEY_KP_ENTER},
129     {SDLK_UP, KEY_UP},
130     {SDLK_DOWN, KEY_DOWN},
131     {SDLK_RIGHT, KEY_RIGHT},
132     {SDLK_LEFT, KEY_LEFT},
133     {SDLK_INSERT, KEY_INSERT},
134     {SDLK_HOME, KEY_HOME},
135     {SDLK_END, KEY_END},
136     {SDLK_PAGEUP, KEY_PRIOR},
137     {SDLK_PAGEDOWN, KEY_NEXT},
138     {SDLK_F1, KEY_F1},
139     {SDLK_F2, KEY_F2},
140     {SDLK_F3, KEY_F3},
141     {SDLK_F4, KEY_F4},
142     {SDLK_F5, KEY_F5},
143     {SDLK_F6, KEY_F6},
144     {SDLK_F7, KEY_F7},
145     {SDLK_F8, KEY_F8},
146     {SDLK_F9, KEY_F9},
147     {SDLK_F10, KEY_F10},
148     {SDLK_F11, KEY_F11},
149     {SDLK_F12, KEY_F12},
150     {SDLK_F13, KEY_F13},
151     {SDLK_NUMLOCK, KEY_NUM_LOCK},
152     {SDLK_CAPSLOCK, KEY_CAPS_LOCK},
153     {SDLK_SCROLLOCK, KEY_SCROLL_LOCK},
154     {SDLK_RSHIFT, KEY_SHIFT},
155     {SDLK_LSHIFT, KEY_SHIFT},
156     {SDLK_RCTRL, KEY_CONTROL},
157     {SDLK_LCTRL, KEY_CONTROL},
158     {SDLK_RALT, KEY_ALTGR},
159     {SDLK_LALT, KEY_ALT},
160     };
161    
162     static void createSDLToADBKeytable()
163     {
164     memset(sdl_key_to_adb_key, 0xff, sizeof sdl_key_to_adb_key);
165     for (uint i=0; i < (sizeof sdladbkeys / sizeof sdladbkeys[0]); i++) {
166     if (sdladbkeys[i].sdlkey > sizeof sdl_key_to_adb_key) {
167     ht_printf("%d > 256 for key %d\n", sdladbkeys[i].sdlkey, sdladbkeys[i].adbkey);
168     }
169     sdl_key_to_adb_key[sdladbkeys[i].sdlkey] = sdladbkeys[i].adbkey;
170     }
171     }
172    
173     #else
174    
175     #ifdef __WIN32__
176     static byte scancode_to_adb_key[] = {
177     //00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
178     0xff,0x35,0x12,0x13,0x14,0x15,0x17,0x16,0x1a,0x1c,0x19,0x1d,0x1b,0x18,0x33,0x30,
179     0x0c,0x0d,0x0e,0x0f,0x11,0x10,0x20,0x22,0x1f,0x23,0x21,0x1e,0x24,0x36,0x00,0x01,
180     0x02,0x03,0x05,0x04,0x26,0x28,0x25,0x29,0x27,0xff,0x38,0x2a,0x06,0x07,0x08,0x09,
181     0x0b,0x2d,0x2e,0x2b,0x2f,0x2c,0x38,0x43,0x37,0x31,0x39,0x7a,0x78,0x63,0x76,0x60,
182     0x61,0x62,0x64,0x65,0x6d,0xff,0xff,0x59,0x5b,0x5c,0x4e,0x56,0x57,0x58,0x45,0x53,
183     0x54,0x55,0x52,0x41,0xff,0xff,0x0a,0x67,0x6f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
184     0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
185     0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
186     0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
187     0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x36,0xff,0xff,
188     0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
189     0xff,0xff,0xff,0xff,0xff,0x4b,0xff,0xff,0x3a,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
190     0xff,0xff,0xff,0xff,0xff,0x71,0xff,0x73,0x3e,0x74,0xff,0x3b,0xff,0x3c,0xff,0x77,
191     0x3d,0x79,0x72,0x75,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
192     0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
193     0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
194     };
195    
196     #else
197    
198     static uint8 scancode_to_adb_key[256] = {
199     // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
200     0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x35,0x12,0x13,0x14,0x15,0x17,0x16,
201     0x1a,0x1c,0x19,0x1d,0x1b,0x18,0x33,0x30,0x0c,0x0d,0x0e,0x0f,0x11,0x10,0x20,0x22,
202     0x1f,0x23,0x21,0x1e,0x24,0x36,0x00,0x01,0x02,0x03,0x05,0x04,0x26,0x28,0x25,0x29,
203     0x27,0x32,0x38,0x2a,0x06,0x07,0x08,0x09,0x0b,0x2d,0x2e,0x2b,0x2f,0x2c,0x38,0x43,
204     0x37,0x31,0xff,0x7a,0x78,0x63,0x76,0x60,0x61,0x62,0x64,0x65,0x6d,0x47,0xff,0x59,
205     0x5b,0x5c,0x4e,0x56,0x57,0x58,0x45,0x53,0x54,0x55,0x52,0x41,0xff,0xff,0x0a,0x67,
206     0x6f,0x73,0x3e,0x74,0x3b,0xff,0x3c,0x77,0x3d,0x79,0x72,0x75,0x4c,0x36,0xff,0xff,
207     0x4b,0x3a,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
208     0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
209     0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
210     0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
211     0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
212     0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
213     0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
214     0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
215     0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
216     };
217    
218     #endif
219    
220     #endif
221    
222     static bool handleSDLEvent(const SDL_Event &event)
223     {
224     static bool mouseButton[3] = {false, false, false};
225     bool tmpMouseButton[3];
226    
227     SystemEvent ev;
228     switch (event.type) {
229     case SDL_USEREVENT:
230     if (event.user.code == 1) { // helper for changeResolution
231     //ht_printf("got forward event\n");
232     sd->mChangeResRet = sd->changeResolutionREAL(sd->mSDLChartemp);
233     SDL_CondSignal(sd->mWaitcondition); // Signal, that condition is over.
234     }
235     return true;
236     case SDL_VIDEOEXPOSE:
237     gDisplay->displayShow();
238     gSDLVideoExposePending = false;
239     return true;
240     case SDL_KEYUP:
241     ev.key.keycode = scancode_to_adb_key[event.key.keysym.scancode];
242     // ht_printf("%x %x up ", event.key.keysym.scancode, ev.key.keycode);
243     if ((ev.key.keycode & 0xff) == 0xff) break;
244     ev.type = sysevKey;
245     ev.key.pressed = false;
246     gKeyboard->handleEvent(ev);
247     return true;
248     case SDL_KEYDOWN:
249     ev.key.keycode = scancode_to_adb_key[event.key.keysym.scancode];
250     // ht_printf("%x %x %x dn \n", event.key.keysym.sym, event.key.keysym.scancode, ev.key.keycode);
251     if ((ev.key.keycode & 0xff) == 0xff) break;
252     ev.type = sysevKey;
253     ev.key.pressed = true;
254     gKeyboard->handleEvent(ev);
255     return true;
256     case SDL_MOUSEBUTTONDOWN:
257     ev.type = sysevMouse;
258     ev.mouse.type = sme_buttonPressed;
259     memcpy(tmpMouseButton, mouseButton, sizeof (tmpMouseButton));
260     mouseButton[0] = SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(1);
261     mouseButton[1] = SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(2);
262     mouseButton[2] = SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(3);
263     ev.mouse.button1 = mouseButton[0];
264     ev.mouse.button2 = mouseButton[1];
265     ev.mouse.button3 = mouseButton[2];
266     if (mouseButton[0] != tmpMouseButton[0]) {
267     ev.mouse.dbutton = 1;
268     } else if (mouseButton[1] != tmpMouseButton[1]) {
269     ev.mouse.dbutton = 2;
270     } else if (mouseButton[2] != tmpMouseButton[2]) {
271     ev.mouse.dbutton = 3;
272     } else {
273     ev.mouse.dbutton = 0;
274     }
275     ev.mouse.x = gDisplay->mCurMouseX;
276     ev.mouse.y = gDisplay->mCurMouseY;
277     ev.mouse.relx = 0;
278     ev.mouse.rely = 0;
279     gMouse->handleEvent(ev);
280     return true;
281     case SDL_MOUSEBUTTONUP:
282     ev.type = sysevMouse;
283     ev.mouse.type = sme_buttonReleased;
284     memcpy(tmpMouseButton, mouseButton, sizeof (tmpMouseButton));
285     mouseButton[0] = SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(1);
286     mouseButton[1] = SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(2);
287     mouseButton[2] = SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(3);
288     ev.mouse.button1 = mouseButton[0];
289     ev.mouse.button2 = mouseButton[1];
290     ev.mouse.button3 = mouseButton[2];
291     if (mouseButton[0] != tmpMouseButton[0]) {
292     ev.mouse.dbutton = 1;
293     } else if (mouseButton[1] != tmpMouseButton[1]) {
294     ev.mouse.dbutton = 2;
295     } else if (mouseButton[2] != tmpMouseButton[2]) {
296     ev.mouse.dbutton = 3;
297     } else {
298     ev.mouse.dbutton = 0;
299     }
300     ev.mouse.x = gDisplay->mCurMouseX;
301     ev.mouse.y = gDisplay->mCurMouseY;
302     ev.mouse.relx = 0;
303     ev.mouse.rely = 0;
304     gMouse->handleEvent(ev);
305     return true;
306     case SDL_MOUSEMOTION:
307     ev.type = sysevMouse;
308     ev.mouse.type = sme_motionNotify;
309     ev.mouse.button1 = mouseButton[0];
310     ev.mouse.button2 = mouseButton[1];
311     ev.mouse.button3 = mouseButton[2];
312     ev.mouse.dbutton = 0;
313     ev.mouse.x = event.motion.y;
314     ev.mouse.y = event.motion.x;
315     ev.mouse.relx = event.motion.xrel;
316     ev.mouse.rely = event.motion.yrel;
317     gMouse->handleEvent(ev);
318     return true;
319     case SDL_ACTIVEEVENT:
320     if (event.active.state & SDL_APPACTIVE) {
321     gDisplay->setExposed(event.active.gain);
322     }
323     if (event.active.state & SDL_APPINPUTFOCUS) {
324     if (!event.active.gain) {
325     gDisplay->setMouseGrab(false);
326     }
327     }
328     return true;
329     case SDL_QUIT:
330     gDisplay->setFullscreenMode(false);
331     return false;
332     }
333     return true;
334     }
335    
336     static Uint32 SDL_redrawCallback(Uint32 interval, void *param)
337     {
338     SDL_Event event;
339    
340     if (!gSDLVideoExposePending) {
341     event.type = SDL_VIDEOEXPOSE;
342     // according to the docs, "You may always call SDL_PushEvent" in an SDL
343     // timer callback function
344     SDL_PushEvent(&event);
345     gSDLVideoExposePending = true;
346     }
347     return interval;
348     }
349    
350     sys_timer gSDLRedrawTimer;
351     static bool eventThreadAlive;
352    
353     static void *SDLeventLoop(void *p)
354     {
355     eventThreadAlive = true;
356     #ifdef __WIN32__
357     if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_NOPARACHUTE) < 0) {
358     #else
359     if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_EVENTTHREAD | SDL_INIT_NOPARACHUTE) < 0) {
360     #endif
361     ht_printf("SDL: Unable to init: %s\n", SDL_GetError());
362     exit(1);
363     }
364    
365     atexit(SDL_Quit); // give SDl a chance to clean up before exit!
366     sd = (SDLSystemDisplay*)gDisplay;
367    
368     sd->initCursor();
369    
370     sd->updateTitle();
371     sd->mEventThreadID = SDL_ThreadID();
372    
373     SDL_WM_GrabInput(SDL_GRAB_OFF);
374    
375     sd->changeResolution(sd->mClientChar);
376     sd->setExposed(true);
377    
378     gSDLVideoExposePending = false;
379     SDL_RedrawTimerID = SDL_AddTimer(gDisplay->mRedraw_ms, SDL_redrawCallback, NULL);
380    
381     sd->setFullscreenMode(sd->mFullscreen);
382    
383     SDL_Event event;
384     do {
385     SDL_WaitEvent(&event);
386     } while (handleSDLEvent(event));
387    
388     gDisplay->setMouseGrab(false);
389    
390     if (SDL_RedrawTimerID)
391     SDL_RemoveTimer(SDL_RedrawTimerID);
392    
393     ppc_cpu_stop();
394    
395     eventThreadAlive = false;
396    
397     return NULL;
398     }
399    
400     SystemDisplay *allocSystemDisplay(const char *title, const DisplayCharacteristics &chr, int redraw_ms);
401     SystemKeyboard *allocSystemKeyboard();
402     SystemMouse *allocSystemMouse();
403    
404     void initUI(const char *title, const DisplayCharacteristics &aCharacteristics, int redraw_ms, const KeyboardCharacteristics &keyConfig, bool fullscreen)
405     {
406     #if 0
407     createSDLToADBKeytable();
408     #endif
409    
410     sys_thread SDLeventLoopThread;
411    
412     gDisplay = allocSystemDisplay(title, aCharacteristics, redraw_ms);
413     gMouse = allocSystemMouse();
414     gKeyboard = allocSystemKeyboard();
415     if (!gKeyboard->setKeyConfig(keyConfig)) {
416     ht_printf("no keyConfig, or is empty");
417     exit(1);
418     }
419    
420     gDisplay->mFullscreen = fullscreen;
421    
422     if (sys_create_thread(&SDLeventLoopThread, 0, SDLeventLoop, NULL)) {
423     ht_printf("SDL: can't create event thread!\n");
424     exit(1);
425     }
426     }
427    
428     void doneUI()
429     {
430     if (eventThreadAlive) {
431     SDL_Event event;
432     event.type = SDL_QUIT;
433     SDL_PushEvent(&event);
434     while (eventThreadAlive) SDL_Delay(10); // FIXME: UGLY!
435     }
436     SDL_Quit();
437     }

  ViewVC Help
Powered by ViewVC 1.1.26