|
|
1.1 root 1: /*
2: * UAE - The Un*x Amiga Emulator
3: *
4: * SDL interface
5: *
6: * Copyright 2001 Bernd Lachner (EMail: [email protected])
7: *
8: * Partialy based on the UAE X interface (xwin.c)
9: *
10: * Copyright 1995, 1996 Bernd Schmidt
11: * Copyright 1996 Ed Hanway, Andre Beck, Samuel Devulder, Bruno Coste
12: * Copyright 1998 Marcus Sundberg
13: * DGA support by Kai Kollmorgen
14: * X11/DGA merge, hotkeys and grabmouse by Marcus Sundberg
15: */
16:
17: #include "sysconfig.h"
18: #include "sysdeps.h"
19:
20: #include <unistd.h>
21: #include <signal.h>
22:
23: #include <SDL/SDL.h>
24: #include <SDL/SDL_endian.h>
25:
26: #include "config.h"
27: #include "options.h"
28: #include "uae.h"
29: #include "memory.h"
30: #include "xwin.h"
31: #include "custom.h"
32: #include "drawing.h"
33: #include "newcpu.h"
34: #include "keyboard.h"
35: #include "keybuf.h"
36: #include "gui.h"
37: #include "debug.h"
38: #include "picasso96.h"
39:
40: #define DEBUG
41: /* Uncomment for debugging output */
42: /* #define DEBUG */
43:
44: #ifdef __cplusplus
45: static RETSIGTYPE sigbrkhandler(...)
46: #else
47: static RETSIGTYPE sigbrkhandler (int foo)
48: #endif
49: {
50: activate_debugger();
51: #if !defined(__unix) || defined(__NeXT__)
52: signal (SIGINT, sigbrkhandler);
53: #endif
54: }
55:
56: void setup_brkhandler (void)
57: {
58: #if defined(__unix) && !defined(__NeXT__)
59: struct sigaction sa;
60: sa.sa_handler = sigbrkhandler;
61: sa.sa_flags = 0;
62: #ifdef SA_RESTART
63: sa.sa_flags = SA_RESTART;
64: #endif
65: sigemptyset (&sa.sa_mask);
66: sigaction (SIGINT, &sa, NULL);
67: #else
68: signal (SIGINT, sigbrkhandler);
69: #endif
70: }
71:
72: /* SDL variable for output surface */
73: static SDL_Surface *prSDLScreen = NULL;
74: /* Possible screen modes (x and y resolutions) */
75: #define MAX_SCREEN_MODES 11
76: static int x_size_table[MAX_SCREEN_MODES] = { 320, 320, 320, 320, 640, 640, 640, 800, 1024, 1152, 1280 };
77: static int y_size_table[MAX_SCREEN_MODES] = { 200, 240, 256, 400, 350, 480, 512, 600, 768, 864, 1024 };
78: /* Possible screen depth (0 terminated) */
79: static int aScreenDepth[] = {16, 15, 12, 0};
80:
81: static int red_bits, green_bits, blue_bits;
82: static int red_shift, green_shift, blue_shift;
83:
84: static int screen_is_picasso;
85: static char picasso_invalid_lines[1201];
86: static int picasso_has_invalid_lines;
87: static int picasso_invalid_start, picasso_invalid_stop;
88: static int picasso_maxw = 0, picasso_maxh = 0;
89:
90: static int bitdepth, bit_unit;
91:
92: static int current_width, current_height;
93: static SDL_Color arSDLColors[256];
94: static int ncolors = 0;
95:
96: /* Keyboard and mouse */
97: static int keystate[256];
98:
99: static void handle_mousegrab(void);
100: static void handle_inhibit(void);
101: static void framerate_up(void);
102: static void framerate_down(void);
103: static void togglefullscreen(void)
104: {
105: SDL_WM_ToggleFullScreen(prSDLScreen);
106: };
107:
108: static void handle_interpol (void);
109:
110: struct SDLHotKey
111: {
112: SDLKey aHotKeys[2];
113: void (*pfHandler)(void);
114: long aPressedKeys[2];
115: };
116:
117:
118: static struct SDLHotKey arHotKeys[] =
119: {
120: {{ SDLK_F12, SDLK_s}, togglefullscreen, {0, 0} },
121: {{ SDLK_F12, SDLK_q}, uae_quit, {0, 0} },
122: {{ SDLK_F12, SDLK_m}, togglemouse, {0, 0} },
123: {{ SDLK_F12, SDLK_g}, handle_mousegrab, {0, 0} },
124: {{ SDLK_F12, SDLK_i}, handle_inhibit, {0, 0} },
125: {{ SDLK_F12, SDLK_p}, handle_interpol, {0, 0} },
126: {{ SDLK_F12, SDLK_KP_PLUS}, framerate_up, {0, 0} },
127: {{ SDLK_F12, SDLK_KP_MINUS}, framerate_down, {0, 0} },
128: {{ 0, 0 }, NULL, {0, 0} } /* List must be terminated */
129: };
130:
131: void flush_line (int y)
132: {
133: /* Not implemented for SDL output */
134: #ifdef DEBUG
135: fprintf(stderr, "Function: flush_line\n");
136: #endif
137: }
138:
139: void flush_block (int ystart, int ystop)
140: {
141: #ifdef DEBUG
142: fprintf(stderr, "Function: flush_block %d %d\n", ystart, ystop);
143: #endif
144: SDL_UnlockSurface (prSDLScreen);
145: SDL_UpdateRect(prSDLScreen, 0, ystart, current_width, ystop-ystart+1);
146: SDL_LockSurface (prSDLScreen);
147: }
148:
149: void flush_screen (int ystart, int ystop)
150: {
151: #ifdef DEBUG
152: fprintf(stderr, "Function: flush_screen\n");
153: #endif
154:
155: #if 0
156: SDL_UpdateRect(prSDLScreen, 0, 0, current_width, current_height);
157: #endif
158: }
159:
160: STATIC_INLINE int bitsInMask (unsigned long mask)
161: {
162: /* count bits in mask */
163: int n = 0;
164: while (mask)
165: {
166: n += mask & 1;
167: mask >>= 1;
168: }
169: return n;
170: }
171:
172: STATIC_INLINE int maskShift (unsigned long mask)
173: {
174: /* determine how far mask is shifted */
175: int n = 0;
176: while (!(mask & 1))
177: {
178: n++;
179: mask >>= 1;
180: }
181: return n;
182: }
183:
184: static int get_color (int r, int g, int b, xcolnr *cnp)
185: {
186: #ifdef DEBUG
187: fprintf(stderr, "Function: get_color\n");
188: #endif
189:
190: *cnp = SDL_MapRGB(prSDLScreen->format, r, g, b);
191: arSDLColors[ncolors].r = r;
192: arSDLColors[ncolors].g = g;
193: arSDLColors[ncolors].b = b;
194:
195: ncolors++;
196: return 1;
197: }
198:
199: static int init_colors (void)
200: {
201: int i;
202:
203: #ifdef DEBUG
204: fprintf(stderr, "Function: init_colors\n");
205: #endif
206:
207: if (bitdepth > 8)
208: {
209: /* Truecolor: */
210: red_bits = bitsInMask(prSDLScreen->format->Rmask);
211: green_bits = bitsInMask(prSDLScreen->format->Gmask);
212: blue_bits = bitsInMask(prSDLScreen->format->Bmask);
213: red_shift = maskShift(prSDLScreen->format->Rmask);
214: green_shift = maskShift(prSDLScreen->format->Gmask);
215: blue_shift = maskShift(prSDLScreen->format->Bmask);
216: alloc_colors64k (red_bits, green_bits, blue_bits, red_shift, green_shift, blue_shift);
217: }
218: else
219: {
220: alloc_colors256 (get_color);
221: SDL_SetColors(prSDLScreen, arSDLColors, 0, 256);
222: }
223:
224: switch (gfxvidinfo.pixbytes)
225: {
226: case 2:
227: for (i = 0; i < 4096; i++)
228: xcolors[i] = xcolors[i] * 0x00010001;
229: gfxvidinfo.can_double = 1;
230: break;
231: case 1:
232: for (i = 0; i < 4096; i++)
233: xcolors[i] = xcolors[i] * 0x01010101;
234: gfxvidinfo.can_double = 1;
235: break;
236: default:
237: gfxvidinfo.can_double = 0;
238: break;
239: }
240: if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
241: {
242: switch (gfxvidinfo.pixbytes)
243: {
244: case 4:
245: for(i = 0; i < 4096; i++)
246: SDL_Swap32(xcolors[i]);
247: break;
248: case 2:
249: for (i = 0; i < 4096; i++)
250: SDL_Swap16(xcolors[i]);
251: break;
252: }
253: }
254: return 1;
255: }
256:
257: int graphics_setup (void)
258: {
259: #ifdef DEBUG
260: fprintf(stderr, "Function: graphics_setup\n");
261: #endif
262:
263: /* Initialize the SDL library */
264: if ( SDL_Init(SDL_INIT_VIDEO) < 0 )
265: {
266: fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError());
267: return 0;
268: }
269:
270: return 1;
271: }
272:
273:
274: static void graphics_subinit (void)
275: {
276: int i, j;
277: Uint32 uiSDLVidModFlags;
278:
279: #ifdef DEBUG
280: fprintf(stderr, "Function: graphics_subinit\n");
281: #endif
282:
283: /* Open SDL Window in current mode */
284: uiSDLVidModFlags = SDL_SWSURFACE;
285: if (bitdepth == 8)
286: {
287: uiSDLVidModFlags |= SDL_HWPALETTE;
288: }
289: if (currprefs.gfx_afullscreen || currprefs.gfx_pfullscreen)
290: {
291: uiSDLVidModFlags |= SDL_FULLSCREEN;
292: }
293: fprintf(stderr, "Resolution: %d x %d x %d\n", current_width, current_height, bitdepth);
294:
295: prSDLScreen = SDL_SetVideoMode(current_width, current_height, bitdepth, uiSDLVidModFlags);
296: if (prSDLScreen == NULL)
297: {
298: fprintf(stderr, "Unable to set video mode: %s\n", SDL_GetError());
299: return;
300: }
301: else
302: {
303: #ifdef DEBUG
304: fprintf(stderr, "Bytes per Pixel: %d\n", prSDLScreen->format->BytesPerPixel);
305: fprintf(stderr, "Bytes per Line: %d\n", prSDLScreen->pitch);
306: #endif
307: SDL_LockSurface(prSDLScreen);
308: memset(prSDLScreen->pixels, 0xff, current_width * current_height * prSDLScreen->format->BytesPerPixel);
309: SDL_UnlockSurface(prSDLScreen);
310: SDL_UpdateRect(prSDLScreen, 0, 0, current_width, current_height);
311: /* Set UAE window title and icon name */
312: SDL_WM_SetCaption("UAE","UAE");
313: /* Hide mouse cursor */
314: SDL_ShowCursor(SDL_DISABLE);
315: /* Initialize structure for Amiga video modes */
316: gfxvidinfo.bufmem = prSDLScreen->pixels;
317: gfxvidinfo.linemem = 0;
318: gfxvidinfo.emergmem = 0;
319: gfxvidinfo.pixbytes = prSDLScreen->format->BytesPerPixel;
320: bit_unit = prSDLScreen->format->BytesPerPixel * 8;
321: gfxvidinfo.rowbytes = prSDLScreen->pitch;
322: gfxvidinfo.maxblocklines = 100;
323: gfxvidinfo.can_double = 0;
324: /* Initialize structure for Picasso96 video modes */
325: picasso_vidinfo.rowbytes = current_width * gfxvidinfo.pixbytes;
326: picasso_vidinfo.extra_mem = 1;
327: picasso_vidinfo.depth = bitdepth;
328: picasso_has_invalid_lines = 0;
329: picasso_invalid_start = picasso_vidinfo.height + 1;
330: picasso_invalid_stop = -1;
331: memset (picasso_invalid_lines, 0, sizeof picasso_invalid_lines);
332: }
333: lastmx = lastmy = 0;
334: newmousecounters = 0;
335: }
336:
337:
338: int graphics_init (void)
339: {
340: int i,j;
341:
342: #ifdef DEBUG
343: fprintf(stderr, "Function: graphics_init\n");
344: #endif
345:
346: if (currprefs.color_mode > 5)
347: fprintf (stderr, "Bad color mode selected. Using default.\n"), currprefs.color_mode = 0;
348:
349: screen_is_picasso = 0;
350:
351: fixup_prefs_dimensions (&currprefs);
352:
353:
354: gfxvidinfo.width = currprefs.gfx_width;
355: gfxvidinfo.height = currprefs.gfx_height;
356: current_width = currprefs.gfx_width;
357: current_height = currprefs.gfx_height;
358:
359: /* Find a SDL video mode with exact width and height */
360: for (i = 0; aScreenDepth[i] != 0; i++)
361: {
362: bitdepth = SDL_VideoModeOK(current_width, current_height, aScreenDepth[i], SDL_SWSURFACE);
363: if (bitdepth)
364: {
365: #ifdef DEBUG
366: fprintf(stderr, "Bit depth: %d\n", bitdepth);
367: #endif
368: break;
369: }
370: else
371: {
372: fprintf(stderr, "Video mode %dx%d@%d not available\n", current_width, current_height, aScreenDepth[i]);
373: }
374: }
375: if (bitdepth == 0)
376: {
377: /* Find a SDL video mode from standard resolutions */
378: for (j = 0; j < MAX_SCREEN_MODES && !bitdepth; j++)
379: {
380: if (x_size_table[j] < current_width || y_size_table[j] < current_height)
381: continue;
382: for (i = 0; aScreenDepth[i] != 0 && !bitdepth; i++)
383: {
384: bitdepth = SDL_VideoModeOK(x_size_table[j], y_size_table[j], aScreenDepth[i], SDL_SWSURFACE);
385: if (bitdepth)
386: {
387: #ifdef DEBUG
388: fprintf(stderr, "Bit depth: %d\n", bitdepth);
389: #endif
390: gfxvidinfo.width = current_width = x_size_table[j];
391: gfxvidinfo.height = current_height = y_size_table[j];
392: break;
393: }
394: else
395: {
396: fprintf(stderr, "Video mode %dx%d@%d not available\n", current_width, current_height, aScreenDepth[i]);
397: }
398: }
399: }
400: if (bitdepth == 0)
401: {
402: fprintf(stderr, "No video mode found!\n");
403: return 0;
404: }
405: }
406:
407: graphics_subinit ();
408:
409:
410: if (!init_colors ())
411: return 0;
412:
413: buttonstate[0] = buttonstate[1] = buttonstate[2] = 0;
414: for (i = 0; i < 256; i++)
415: keystate[i] = 0;
416:
417: return 1;
418: }
419:
420: static void graphics_subshutdown (void)
421: {
422: #ifdef DEBUG
423: fprintf(stderr, "Function: graphics_subshutdown\n");
424: #endif
425:
426: SDL_FreeSurface(prSDLScreen);
427: }
428:
429: void graphics_leave (void)
430: {
431: #ifdef DEBUG
432: fprintf(stderr, "Function: graphics_leave\n");
433: #endif
434:
435: graphics_subshutdown ();
436:
437: SDL_Quit();
438:
439: dumpcustom ();
440: }
441:
442: /* Decode KeySyms. This function knows about all keys that are common
443: * between different keyboard languages. */
444: static int kc_decode (SDL_keysym *prKeySym)
445: {
446: switch (prKeySym->sym)
447: {
448: case SDLK_b: return AK_B;
449: case SDLK_c: return AK_C;
450: case SDLK_d: return AK_D;
451: case SDLK_e: return AK_E;
452: case SDLK_f: return AK_F;
453: case SDLK_g: return AK_G;
454: case SDLK_h: return AK_H;
455: case SDLK_i: return AK_I;
456: case SDLK_j: return AK_J;
457: case SDLK_k: return AK_K;
458: case SDLK_l: return AK_L;
459: case SDLK_n: return AK_N;
460: case SDLK_o: return AK_O;
461: case SDLK_p: return AK_P;
462: case SDLK_r: return AK_R;
463: case SDLK_s: return AK_S;
464: case SDLK_t: return AK_T;
465: case SDLK_u: return AK_U;
466: case SDLK_v: return AK_V;
467: case SDLK_x: return AK_X;
468:
469: case SDLK_0: return AK_0;
470: case SDLK_1: return AK_1;
471: case SDLK_2: return AK_2;
472: case SDLK_3: return AK_3;
473: case SDLK_4: return AK_4;
474: case SDLK_5: return AK_5;
475: case SDLK_6: return AK_6;
476: case SDLK_7: return AK_7;
477: case SDLK_8: return AK_8;
478: case SDLK_9: return AK_9;
479:
480: case SDLK_KP0: return AK_NP0;
481: case SDLK_KP1: return AK_NP1;
482: case SDLK_KP2: return AK_NP2;
483: case SDLK_KP3: return AK_NP3;
484: case SDLK_KP4: return AK_NP4;
485: case SDLK_KP5: return AK_NP5;
486: case SDLK_KP6: return AK_NP6;
487: case SDLK_KP7: return AK_NP7;
488: case SDLK_KP8: return AK_NP8;
489: case SDLK_KP9: return AK_NP9;
490: case SDLK_KP_DIVIDE: return AK_NPDIV;
491: case SDLK_KP_MULTIPLY: return AK_NPMUL;
492: case SDLK_KP_MINUS: return AK_NPSUB;
493: case SDLK_KP_PLUS: return AK_NPADD;
494: case SDLK_KP_PERIOD: return AK_NPDEL;
495: case SDLK_KP_ENTER: return AK_ENT;
496:
497: case SDLK_F1: return AK_F1;
498: case SDLK_F2: return AK_F2;
499: case SDLK_F3: return AK_F3;
500: case SDLK_F4: return AK_F4;
501: case SDLK_F5: return AK_F5;
502: case SDLK_F6: return AK_F6;
503: case SDLK_F7: return AK_F7;
504: case SDLK_F8: return AK_F8;
505: case SDLK_F9: return AK_F9;
506: case SDLK_F10: return AK_F10;
507:
508: case SDLK_BACKSPACE: return AK_BS;
509: case SDLK_DELETE: return AK_DEL;
510: case SDLK_LCTRL: return AK_CTRL;
511: case SDLK_RCTRL: return AK_RCTRL;
512: case SDLK_TAB: return AK_TAB;
513: case SDLK_LALT: return AK_LALT;
514: case SDLK_RALT: return AK_RALT;
515: case SDLK_RMETA: return AK_RAMI;
516: case SDLK_LMETA: return AK_LAMI;
517: case SDLK_RETURN: return AK_RET;
518: case SDLK_SPACE: return AK_SPC;
519: case SDLK_LSHIFT: return AK_LSH;
520: case SDLK_RSHIFT: return AK_RSH;
521: case SDLK_ESCAPE: return AK_ESC;
522:
523: case SDLK_INSERT: return AK_HELP;
524: case SDLK_HOME: return AK_NPLPAREN;
525: case SDLK_END: return AK_NPRPAREN;
526: case SDLK_CAPSLOCK: return AK_CAPSLOCK;
527:
528: case SDLK_UP: return AK_UP;
529: case SDLK_DOWN: return AK_DN;
530: case SDLK_LEFT: return AK_LF;
531: case SDLK_RIGHT: return AK_RT;
532:
533: case SDLK_PAGEUP: return AK_RAMI; /* PgUp mapped to right amiga */
534: case SDLK_PAGEDOWN: return AK_LAMI; /* PgDn mapped to left amiga */
535:
536: default: return -1;
537: }
538: }
539:
540: static int decode_fr (SDL_keysym *prKeySym)
541: {
542: switch(prKeySym->sym)
543: {
544: /* FR specific */
545: case SDLK_a: return AK_Q;
546: case SDLK_m: return AK_SEMICOLON;
547: case SDLK_q: return AK_A;
548: case SDLK_y: return AK_Y;
549: case SDLK_w: return AK_Z;
550: case SDLK_z: return AK_W;
551: case SDLK_LEFTBRACKET: return AK_LBRACKET;
552: case SDLK_RIGHTBRACKET: return AK_RBRACKET;
553: case SDLK_COMMA: return AK_M;
554: case SDLK_LESS: case SDLK_GREATER: return AK_LTGT;
555: case SDLK_PERIOD: case SDLK_SEMICOLON: return AK_COMMA;
556: case SDLK_RIGHTPAREN: return AK_MINUS;
557: case SDLK_EQUALS: return AK_SLASH;
558: case SDLK_HASH: return AK_NUMBERSIGN;
559: case SDLK_SLASH: return AK_PERIOD;
560: case SDLK_MINUS: return AK_EQUAL;
561: case SDLK_BACKSLASH: return AK_BACKSLASH;
562: default: return -1;
563: }
564: }
565:
566: static int decode_us (SDL_keysym *prKeySym)
567: {
568: switch(prKeySym->sym)
569: {
570: /* US specific */
571: case SDLK_a: return AK_A;
572: case SDLK_m: return AK_M;
573: case SDLK_q: return AK_Q;
574: case SDLK_y: return AK_Y;
575: case SDLK_w: return AK_W;
576: case SDLK_z: return AK_Z;
577: case SDLK_LEFTBRACKET: return AK_LBRACKET;
578: case SDLK_RIGHTBRACKET: return AK_RBRACKET;
579: case SDLK_COMMA: return AK_COMMA;
580: case SDLK_PERIOD: return AK_PERIOD;
581: case SDLK_SLASH: return AK_SLASH;
582: case SDLK_SEMICOLON: return AK_SEMICOLON;
583: case SDLK_MINUS: return AK_MINUS;
584: case SDLK_EQUALS: return AK_EQUAL;
585: /* this doesn't work: */
586: case SDLK_BACKQUOTE: return AK_QUOTE;
587: case SDLK_QUOTE: return AK_BACKQUOTE;
588: case SDLK_BACKSLASH: return AK_BACKSLASH;
589: default: return -1;
590: }
591: }
592:
593: static int decode_de (SDL_keysym *prKeySym)
594: {
595: switch(prKeySym->sym)
596: {
597: /* DE specific */
598: case SDLK_a: return AK_A;
599: case SDLK_m: return AK_M;
600: case SDLK_q: return AK_Q;
601: case SDLK_w: return AK_W;
602: case SDLK_y: return AK_Z;
603: case SDLK_z: return AK_Y;
604: /* German umlaut oe */
605: case SDLK_WORLD_86: return AK_SEMICOLON;
606: /* German umlaut ae */
607: case SDLK_WORLD_68: return AK_QUOTE;
608: /* German umlaut ue */
609: case SDLK_WORLD_92: return AK_LBRACKET;
610: case SDLK_PLUS: case SDLK_ASTERISK: return AK_RBRACKET;
611: case SDLK_COMMA: return AK_COMMA;
612: case SDLK_PERIOD: return AK_PERIOD;
613: case SDLK_LESS: case SDLK_GREATER: return AK_LTGT;
614: case SDLK_HASH: return AK_NUMBERSIGN;
615: /* German sharp s */
616: case SDLK_WORLD_63: return AK_MINUS;
617: case SDLK_QUOTE: return AK_EQUAL;
618: case SDLK_CARET: return AK_BACKQUOTE;
619: case SDLK_MINUS: return AK_SLASH;
620: default: return -1;
621: }
622: }
623:
624: static int decode_se (SDL_keysym *prKeySym)
625: {
626: switch(prKeySym->sym)
627: {
628: /* SE specific */
629: case SDLK_a: return AK_A;
630: case SDLK_m: return AK_M;
631: case SDLK_q: return AK_Q;
632: case SDLK_w: return AK_W;
633: case SDLK_y: return AK_Y;
634: case SDLK_z: return AK_Z;
635: case SDLK_WORLD_86: return AK_SEMICOLON;
636: case SDLK_WORLD_68: return AK_QUOTE;
637: case SDLK_WORLD_69: return AK_LBRACKET;
638: case SDLK_COMMA: return AK_COMMA;
639: case SDLK_PERIOD: return AK_PERIOD;
640: case SDLK_MINUS: return AK_SLASH;
641: case SDLK_LESS: case SDLK_GREATER: return AK_LTGT;
642: case SDLK_PLUS: case SDLK_QUESTION: return AK_EQUAL;
643: case SDLK_AT: case SDLK_WORLD_29: return AK_BACKQUOTE;
644: case SDLK_CARET: return AK_RBRACKET;
645: case SDLK_BACKSLASH: return AK_MINUS;
646: case SDLK_HASH: return AK_NUMBERSIGN;
647: default: return -1;
648: }
649: }
650:
651: static int decode_it (SDL_keysym *prKeySym)
652: {
653: switch(prKeySym->sym)
654: {
655: /* IT specific */
656: case SDLK_a: return AK_A;
657: case SDLK_m: return AK_M;
658: case SDLK_q: return AK_Q;
659: case SDLK_w: return AK_W;
660: case SDLK_y: return AK_Y;
661: case SDLK_z: return AK_Z;
662: case SDLK_WORLD_82: return AK_SEMICOLON;
663: case SDLK_WORLD_64: return AK_QUOTE;
664: case SDLK_WORLD_72: return AK_LBRACKET;
665: case SDLK_PLUS: case SDLK_ASTERISK: return AK_RBRACKET;
666: case SDLK_COMMA: return AK_COMMA;
667: case SDLK_PERIOD: return AK_PERIOD;
668: case SDLK_LESS: case SDLK_GREATER: return AK_LTGT;
669: case SDLK_BACKSLASH: return AK_BACKQUOTE;
670: case SDLK_QUOTE: return AK_MINUS;
671: case SDLK_WORLD_76: return AK_EQUAL;
672: case SDLK_MINUS: return AK_SLASH;
673: case SDLK_HASH: return AK_NUMBERSIGN;
674: default: return -1;
675: }
676: }
677:
678: static int decode_es (SDL_keysym *prKeySym)
679: {
680: switch(prKeySym->sym)
681: {
682: /* ES specific */
683: case SDLK_a: return AK_A;
684: case SDLK_m: return AK_M;
685: case SDLK_q: return AK_Q;
686: case SDLK_w: return AK_W;
687: case SDLK_y: return AK_Y;
688: case SDLK_z: return AK_Z;
689: case SDLK_WORLD_81: return AK_SEMICOLON;
690: case SDLK_PLUS: case SDLK_ASTERISK: return AK_RBRACKET;
691: case SDLK_COMMA: return AK_COMMA;
692: case SDLK_PERIOD: return AK_PERIOD;
693: case SDLK_LESS: case SDLK_GREATER: return AK_LTGT;
694: case SDLK_BACKSLASH: return AK_BACKQUOTE;
695: case SDLK_QUOTE: return AK_MINUS;
696: case SDLK_WORLD_76: return AK_EQUAL;
697: case SDLK_MINUS: return AK_SLASH;
698: case SDLK_HASH: return AK_NUMBERSIGN;
699: default: return -1;
700: }
701: }
702:
703: static int keycode2amiga(SDL_keysym *prKeySym)
704: {
705: int iAmigaKeycode = kc_decode(prKeySym);
706: if (iAmigaKeycode == -1)
707: {
708: switch (currprefs.keyboard_lang)
709: {
710: case KBD_LANG_FR:
711: return decode_fr(prKeySym);
712: case KBD_LANG_US:
713: return decode_us(prKeySym);
714: case KBD_LANG_DE:
715: return decode_de(prKeySym);
716: case KBD_LANG_SE:
717: return decode_se (prKeySym);
718: case KBD_LANG_IT:
719: return decode_it (prKeySym);
720: case KBD_LANG_ES:
721: return decode_es (prKeySym);
722: default:
723: return -1;
724: }
725: }
726: return iAmigaKeycode;
727: }
728:
729: static int refresh_necessary = 0;
730:
731: void handle_events (void)
732: {
733: SDL_Event rEvent;
734: int iAmigaKeyCode;
735: int i, j;
736: int iIsHotKey = 0;
737: #ifdef DEBUG
738: fprintf(stderr, "Function: handle_events\n");
739: #endif
740:
741: /* Handle GUI events */
742: gui_handle_events ();
743:
744: while (SDL_PollEvent(&rEvent))
745: {
746: switch (rEvent.type)
747: {
748: case SDL_QUIT:
749: #ifdef DEBUG
750: fprintf(stderr, "Event: quit\n");
751: #endif
752: uae_quit();
753: break;
754: case SDL_KEYDOWN:
755: #ifdef DEBUG
756: fprintf(stderr, "Event: key down\n");
757: #endif
758: /* Check for hotkey sequence */
759: i = 0;
760: while (arHotKeys[i].pfHandler != NULL)
761: {
762: if (rEvent.key.keysym.sym == arHotKeys[i].aHotKeys[0])
763: {
764: arHotKeys[i].aPressedKeys[0] = 1;
765: iIsHotKey = 1;
766: }
767: if (arHotKeys[i].aPressedKeys[0] == 1 &&
768: rEvent.key.keysym.sym == arHotKeys[i].aHotKeys[1])
769: {
770: arHotKeys[i].aPressedKeys[1] = 1;
771: arHotKeys[i].pfHandler();
772: iIsHotKey = 1;
773: }
774: i++;
775: }
776: if (iIsHotKey == 0)
777: {
778: /* No hotkey sequence */
779: iAmigaKeyCode = keycode2amiga(&(rEvent.key.keysym));
780: if (iAmigaKeyCode >= 0)
781: {
782: if (!keystate[iAmigaKeyCode])
783: {
784: keystate[iAmigaKeyCode] = 1;
785: record_key(iAmigaKeyCode << 1);
786: }
787: }
788: }
789: break;
790: case SDL_KEYUP:
791: #ifdef DEBUG
792: fprintf(stderr, "Event: key up\n");
793: #endif
794: /* Check for hotkey sequence */
795: i = 0;
796: while (arHotKeys[i].pfHandler != NULL)
797: {
798: for (j = 0; j < 2; j++)
799: {
800: if (rEvent.key.keysym.sym == arHotKeys[i].aHotKeys[j] &&
801: arHotKeys[i].aPressedKeys[j] == 1)
802: {
803: arHotKeys[i].aPressedKeys[j] = 0;
804: iIsHotKey = 1;
805: }
806: }
807: i++;
808: }
809: if (iIsHotKey == 0)
810: {
811: iAmigaKeyCode = keycode2amiga(&(rEvent.key.keysym));
812: if (iAmigaKeyCode >= 0)
813: {
814: keystate[iAmigaKeyCode] = 0;
815: record_key((iAmigaKeyCode << 1) | 1);
816: }
817: }
818: break;
819: case SDL_MOUSEBUTTONDOWN:
820: #ifdef DEBUG
821: fprintf(stderr, "Event: mouse button down\n");
822: #endif
823: buttonstate[rEvent.button.button-1] = 1;
824: break;
825: case SDL_MOUSEBUTTONUP:
826: #ifdef DEBUG
827: fprintf(stderr, "Event: mouse button up\n");
828: #endif
829: buttonstate[rEvent.button.button-1] = 0;
830: break;
831: case SDL_MOUSEMOTION:
832: #ifdef DEBUG
833: fprintf(stderr, "Event: mouse motion\n");
834: #endif
835: newmousecounters = 1;
836: lastmx += rEvent.motion.xrel;
837: lastmy += rEvent.motion.yrel;
838: break;
839: }
840: }
841: #if defined PICASSO96
842: if (screen_is_picasso && refresh_necessary)
843: {
844: SDL_UpdateRect(prSDLScreen, 0, 0, picasso_vidinfo.width, picasso_vidinfo.height);
845: refresh_necessary = 0;
846: memset (picasso_invalid_lines, 0, sizeof picasso_invalid_lines);
847: }
848: else if (screen_is_picasso && picasso_has_invalid_lines)
849: {
850: int i;
851: int strt = -1;
852: picasso_invalid_lines[picasso_vidinfo.height] = 0;
853: for (i = picasso_invalid_start; i < picasso_invalid_stop + 2; i++)
854: {
855: if (picasso_invalid_lines[i])
856: {
857: picasso_invalid_lines[i] = 0;
858: if (strt != -1)
859: continue;
860: strt = i;
861: }
862: else
863: {
864: if (strt == -1)
865: continue;
866: SDL_UpdateRect(prSDLScreen, 0, strt, picasso_vidinfo.width, i-strt);
867: strt = -1;
868: }
869: }
870: if (strt != -1)
871: abort ();
872: }
873: picasso_has_invalid_lines = 0;
874: picasso_invalid_start = picasso_vidinfo.height + 1;
875: picasso_invalid_stop = -1;
876: #endif
877:
878: /* Handle UAE reset */
879: if ((keystate[AK_CTRL] || keystate[AK_RCTRL]) && keystate[AK_LAMI] && keystate[AK_RAMI])
880: uae_reset ();
881: }
882:
883: int check_prefs_changed_gfx (void)
884: {
885:
886: if (changed_prefs.gfx_width != currprefs.gfx_width
887: || changed_prefs.gfx_height != currprefs.gfx_height)
888: {
889: fixup_prefs_dimensions (&changed_prefs);
890: }
891:
892: if (changed_prefs.gfx_width == currprefs.gfx_width
893: && changed_prefs.gfx_height == currprefs.gfx_height
894: && changed_prefs.gfx_lores == currprefs.gfx_lores
895: && changed_prefs.gfx_linedbl == currprefs.gfx_linedbl
896: && changed_prefs.gfx_correct_aspect == currprefs.gfx_correct_aspect
897: && changed_prefs.gfx_xcenter == currprefs.gfx_xcenter
898: && changed_prefs.gfx_ycenter == currprefs.gfx_ycenter
899: && changed_prefs.gfx_afullscreen == currprefs.gfx_afullscreen
900: && changed_prefs.gfx_pfullscreen == currprefs.gfx_pfullscreen)
901: {
902: return 0;
903: }
904: #ifdef DEBUG
905: fprintf(stderr, "Function: check_prefs_changed_gfx\n");
906: #endif
907: graphics_subshutdown ();
908: currprefs.gfx_width = changed_prefs.gfx_width;
909: currprefs.gfx_height = changed_prefs.gfx_height;
910: currprefs.gfx_lores = changed_prefs.gfx_lores;
911: currprefs.gfx_linedbl = changed_prefs.gfx_linedbl;
912: currprefs.gfx_correct_aspect = changed_prefs.gfx_correct_aspect;
913: currprefs.gfx_xcenter = changed_prefs.gfx_xcenter;
914: currprefs.gfx_ycenter = changed_prefs.gfx_ycenter;
915: currprefs.gfx_afullscreen = changed_prefs.gfx_afullscreen;
916: currprefs.gfx_pfullscreen = changed_prefs.gfx_pfullscreen;
917:
918: gui_update_gfx ();
919:
920: graphics_subinit ();
921:
922: /* if (! inwindow)
923: XWarpPointer (display, None, mywin, 0, 0, 0, 0,
924: current_width / 2, current_height / 2);
925: */
926: notice_screen_contents_lost ();
927: init_row_map ();
928: if (screen_is_picasso)
929: picasso_enablescreen (1);
930: return 0;
931: }
932:
933: int debuggable (void)
934: {
935: return 1;
936: }
937:
938: int needmousehack (void)
939: {
940: return 1;
941: }
942:
943: void LED (int on)
944: {
945: #if 0 /* Maybe that is responsible for the joystick emulation problems on SunOS? */
946: static int last_on = -1;
947: XKeyboardControl control;
948:
949: if (last_on == on)
950: return;
951: last_on = on;
952: control.led = 1; /* implementation defined */
953: control.led_mode = on ? LedModeOn : LedModeOff;
954: XChangeKeyboardControl(display, KBLed | KBLedMode, &control);
955: #endif
956: }
957:
958: #ifdef PICASSO96
959:
960: void DX_Invalidate (int first, int last)
961: {
962: #ifdef DEBUG
963: fprintf(stderr, "Function: DX_Invalidate %i - %i\n", first, last);
964: #endif
965:
966: if (first > last)
967: return;
968:
969: picasso_has_invalid_lines = 1;
970: if (first < picasso_invalid_start)
971: picasso_invalid_start = first;
972: if (last > picasso_invalid_stop)
973: picasso_invalid_stop = last;
974:
975: while (first <= last)
976: {
977: picasso_invalid_lines[first] = 1;
978: first++;
979: }
980: }
981:
982: int DX_BitsPerCannon (void)
983: {
984: return 8;
985: }
986:
987: static int palette_update_start=256;
988: static int palette_update_end=0;
989:
990: void DX_SetPalette (int start, int count)
991: {
992: #ifdef DEBUG
993: fprintf(stderr, "Function: DX_SetPalette_real\n");
994: #endif
995:
996: if (! screen_is_picasso || picasso96_state.RGBFormat != RGBFB_CHUNKY)
997: return;
998:
999: if (picasso_vidinfo.pixbytes != 1)
1000: {
1001: /* This is the case when we're emulating a 256 color display. */
1002: while (count-- > 0)
1003: {
1004: int r = picasso96_state.CLUT[start].Red;
1005: int g = picasso96_state.CLUT[start].Green;
1006: int b = picasso96_state.CLUT[start].Blue;
1007: picasso_vidinfo.clut[start++] = (doMask256 (r, red_bits, red_shift)
1008: | doMask256 (g, green_bits, green_shift)
1009: | doMask256 (b, blue_bits, blue_shift));
1010: }
1011: return;
1012: }
1013:
1014: while (count-- > 0)
1015: {
1016: #if 0
1017: XColor col = parsed_xcolors[start];
1018: col.red = picasso96_state.CLUT[start].Red * 0x0101;
1019: col.green = picasso96_state.CLUT[start].Green * 0x0101;
1020: col.blue = picasso96_state.CLUT[start].Blue * 0x0101;
1021: XStoreColor (display, cmap, &col);
1022: #endif
1023: start++;
1024: }
1025: }
1026:
1027: int DX_FillResolutions (uae_u16 *ppixel_format)
1028: {
1029: int i, count = 0;
1030: int w = 0;
1031: int h = 0;
1032: int emulate_chunky = 0;
1033:
1034: #ifdef DEBUG
1035: fprintf(stderr, "Function: DX_FillResolutions\n");
1036: #endif
1037:
1038: /* Find out, which is the highest resolution the SDL can offer */
1039: for (i = MAX_SCREEN_MODES-1; i>=0; i--)
1040: {
1041: if (bitdepth == SDL_VideoModeOK(x_size_table[i], y_size_table[i], bitdepth, SDL_SWSURFACE))
1042: {
1043: w = x_size_table[i];
1044: h = y_size_table[i];
1045: break;
1046: }
1047: }
1048:
1049: #ifdef DEBUG
1050: fprintf(stderr, "Max. Picasso screen size: %d x %d\n", w, h);
1051: #endif
1052:
1053: picasso_vidinfo.rgbformat = (bit_unit == 8 ? RGBFB_CHUNKY
1054: : bitdepth == 15 && bit_unit == 16 ? RGBFB_R5G5B5PC
1055: : bitdepth == 16 && bit_unit == 16 ? RGBFB_R5G6B5PC
1056: : bit_unit == 24 ? RGBFB_B8G8R8
1057: : bit_unit == 32 ? RGBFB_B8G8R8A8
1058: : RGBFB_NONE);
1059:
1060: *ppixel_format = 1 << picasso_vidinfo.rgbformat;
1061: if (bit_unit == 16 || bit_unit == 32)
1062: {
1063: *ppixel_format |= RGBFF_CHUNKY;
1064: emulate_chunky = 1;
1065: }
1066:
1067: for (i = 0; i < MAX_SCREEN_MODES && count < MAX_PICASSO_MODES; i++)
1068: {
1069: int j;
1070: for (j = 0; j <= emulate_chunky && count < MAX_PICASSO_MODES; j++)
1071: {
1072: if (x_size_table[i] <= w && y_size_table[i] <= h)
1073: {
1074: if (x_size_table[i] > picasso_maxw)
1075: picasso_maxw = x_size_table[i];
1076: if (y_size_table[i] > picasso_maxh)
1077: picasso_maxh = y_size_table[i];
1078: DisplayModes[count].res.width = x_size_table[i];
1079: DisplayModes[count].res.height = y_size_table[i];
1080: DisplayModes[count].depth = j == 1 ? 1 : bit_unit >> 3;
1081: DisplayModes[count].refresh = 75;
1082: #ifdef DEBUG
1083: fprintf(stderr, "Picasso resolution %d x %d @ %d allowed\n", DisplayModes[count].res.width, DisplayModes[count].res.height, DisplayModes[count].depth);
1084: #endif
1085:
1086: count++;
1087: }
1088: }
1089: }
1090: #ifdef DEBUG
1091: fprintf(stderr, "Max. Picasso screen size: %d x %d\n", picasso_maxw, picasso_maxh);
1092: #endif
1093: return count;
1094: }
1095:
1096: static void set_window_for_picasso (void)
1097: {
1098: #ifdef DEBUG
1099: fprintf(stderr, "Function: set_window_for_picasso\n");
1100: #endif
1101:
1102: if (current_width == picasso_vidinfo.width && current_height == picasso_vidinfo.height)
1103: return;
1104:
1105: current_width = picasso_vidinfo.width;
1106: current_height = picasso_vidinfo.height;
1107: // XResizeWindow (display, mywin, current_width, current_height);
1108: }
1109:
1110: void gfx_set_picasso_modeinfo (int w, int h, int depth, int rgbfmt)
1111: {
1112: #ifdef DEBUG
1113: fprintf(stderr, "Function: gfx_set_picasso_modeinfo w: %i h: %i depth: %i rgbfmt: %i\n",w, h, depth, rgbfmt);
1114: #endif
1115:
1116: picasso_vidinfo.width = w;
1117: picasso_vidinfo.height = h;
1118: picasso_vidinfo.depth = depth;
1119: picasso_vidinfo.pixbytes = bit_unit >> 3;
1120: if (screen_is_picasso)
1121: set_window_for_picasso();
1122: }
1123:
1124: void gfx_set_picasso_baseaddr (uaecptr a)
1125: {
1126: }
1127:
1128: void gfx_set_picasso_state (int on)
1129: {
1130: #ifdef DEBUG
1131: fprintf(stderr, "Function: gfx_set_picasso_state\n");
1132: #endif
1133:
1134: if (on == screen_is_picasso)
1135: return;
1136: graphics_subshutdown ();
1137: screen_is_picasso = on;
1138: if (on)
1139: {
1140: // Set height, width for Picasso gfx
1141: current_width = picasso_vidinfo.width;
1142: current_height = picasso_vidinfo.height;
1143: }
1144: else
1145: {
1146: // Set height, width for Amiga gfx
1147: current_width = gfxvidinfo.width;
1148: current_height = gfxvidinfo.height;
1149: }
1150: graphics_subinit ();
1151: if (on)
1152: DX_SetPalette (0, 256);
1153: }
1154:
1155: uae_u8 *gfx_lock_picasso (void)
1156: {
1157: #ifdef DEBUG
1158: fprintf(stderr, "Function: gfx_lock_picasso\n");
1159: #endif
1160: SDL_LockSurface(prSDLScreen);
1161: return prSDLScreen->pixels;
1162: }
1163:
1164: void gfx_unlock_picasso (void)
1165: {
1166: #ifdef DEBUG
1167: fprintf(stderr, "Function: gfx_unlock_picasso\n");
1168: #endif
1169: SDL_UnlockSurface(prSDLScreen);
1170: }
1171: #endif
1172:
1173: int lockscr (void)
1174: {
1175: #ifdef DEBUG
1176: fprintf(stderr, "Function: lockscr\n");
1177: #endif
1178: SDL_LockSurface(prSDLScreen);
1179: return 1;
1180: }
1181:
1182: void unlockscr (void)
1183: {
1184: #ifdef DEBUG
1185: fprintf(stderr, "Function: unlockscr\n");
1186: #endif
1187: SDL_UnlockSurface(prSDLScreen);
1188: }
1189:
1190: static void handle_mousegrab (void)
1191: {
1192: if (SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_OFF)
1193: {
1194: SDL_WM_GrabInput(SDL_GRAB_ON);
1195: SDL_WarpMouse(0, 0);
1196: }
1197: else
1198: {
1199: SDL_WM_GrabInput(SDL_GRAB_OFF);
1200: }
1201: }
1202:
1203: static void handle_inhibit (void)
1204: {
1205: toggle_inhibit_frame (IHF_SCROLLLOCK);
1206: }
1207:
1208:
1209: static void handle_interpol (void)
1210: {
1211: if (currprefs.sound_interpol == 0)
1212: {
1213: currprefs.sound_interpol = 1;
1214: printf ("Interpol on: rh\n");
1215: }
1216: else if (currprefs.sound_interpol == 1)
1217: {
1218: currprefs.sound_interpol = 2;
1219: printf ("Interpol on: crux\n");
1220: }
1221: else
1222: {
1223: currprefs.sound_interpol = 0;
1224: printf ("Interpol off\n");
1225: }
1226: }
1227:
1228: static void framerate_up (void)
1229: {
1230: if (currprefs.gfx_framerate < 20)
1231: changed_prefs.gfx_framerate = currprefs.gfx_framerate + 1;
1232: }
1233:
1234: static void framerate_down (void)
1235: {
1236: if (currprefs.gfx_framerate > 1)
1237: changed_prefs.gfx_framerate = currprefs.gfx_framerate - 1;
1238: }
1239:
1240: void target_save_options (FILE *f, struct uae_prefs *p)
1241: {
1242: }
1243:
1244: int target_parse_option (struct uae_prefs *p, char *option, char *value)
1245: {
1246: return 0;
1247: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.