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