|
|
1.1 root 1: /*
2: * UAE - The Un*x Amiga Emulator
3: *
1.1.1.4 ! root 4: * SDL graphics support
1.1 root 5: *
6: * Copyright 2001 Bernd Lachner (EMail: [email protected])
1.1.1.4 ! root 7: * Copyright 2003-2006 Richard Drummond
1.1 root 8: *
9: * Partialy based on the UAE X interface (xwin.c)
10: *
11: * Copyright 1995, 1996 Bernd Schmidt
12: * Copyright 1996 Ed Hanway, Andre Beck, Samuel Devulder, Bruno Coste
13: * Copyright 1998 Marcus Sundberg
14: * DGA support by Kai Kollmorgen
15: * X11/DGA merge, hotkeys and grabmouse by Marcus Sundberg
16: */
17:
18: #include "sysconfig.h"
19: #include "sysdeps.h"
20:
21: #include <signal.h>
1.1.1.4 ! root 22: #include <SDL.h>
! 23: #include <SDL_endian.h>
1.1 root 24:
25: #include "options.h"
26: #include "uae.h"
27: #include "xwin.h"
28: #include "custom.h"
29: #include "drawing.h"
30: #include "keyboard.h"
31: #include "keybuf.h"
32: #include "gui.h"
33: #include "debug.h"
34: #include "picasso96.h"
1.1.1.4 ! root 35: #include "inputdevice.h"
! 36: #include "hotkeys.h"
! 37: #include "sdlgfx.h"
1.1 root 38:
39: /* Uncomment for debugging output */
1.1.1.4 ! root 40: //#define DEBUG
! 41: #ifdef DEBUG
! 42: #define DEBUG_LOG write_log
1.1 root 43: #else
1.1.1.4 ! root 44: #define DEBUG_LOG(...) do ; while(0)
1.1 root 45: #endif
46:
1.1.1.4 ! root 47: static SDL_Surface *display;
! 48: static SDL_Surface *screen;
1.1 root 49:
1.1.1.4 ! root 50: /* Standard P96 screen modes */
! 51: #define MAX_SCREEN_MODES 12
1.1 root 52: static int x_size_table[MAX_SCREEN_MODES] = { 320, 320, 320, 320, 640, 640, 640, 800, 1024, 1152, 1280 };
1.1.1.4 ! root 53: static int y_size_table[MAX_SCREEN_MODES] = { 200, 240, 256, 400, 350, 480, 512, 600, 768, 864, 1024 };
! 54:
! 55: /* Supported SDL screen modes */
! 56: #define MAX_SDL_SCREENMODE 32
! 57: SDL_Rect screenmode[MAX_SDL_SCREENMODE];
! 58: int mode_count;
! 59:
! 60: static int sdlgfx_init_ok;
1.1 root 61:
62: static int red_bits, green_bits, blue_bits;
63: static int red_shift, green_shift, blue_shift;
64:
1.1.1.4 ! root 65: #ifdef PICASSO96
1.1 root 66: static int screen_is_picasso;
67: static char picasso_invalid_lines[1201];
68: static int picasso_has_invalid_lines;
69: static int picasso_invalid_start, picasso_invalid_stop;
70: static int picasso_maxw = 0, picasso_maxh = 0;
1.1.1.4 ! root 71: #endif
1.1 root 72:
73: static int bitdepth, bit_unit;
74: static int current_width, current_height;
75:
1.1.1.4 ! root 76: /* If we have to lock the SDL surface, then we remember the address
! 77: * of its pixel data - and recalculate the row maps only when this
! 78: * address changes */
! 79: static void *old_pixels;
1.1 root 80:
1.1.1.4 ! root 81: static SDL_Color arSDLColors[256];
! 82: #ifdef PICASSO96
! 83: static SDL_Color p96Colors[256];
! 84: #endif
! 85: static int ncolors;
1.1 root 86:
1.1.1.4 ! root 87: static int fullscreen;
! 88: static int mousegrab;
1.1 root 89:
1.1.1.4 ! root 90: static int is_hwsurface;
1.1 root 91:
1.1.1.4 ! root 92: static int have_rawkeys;
1.1 root 93:
1.1.1.4 ! root 94: /* This isn't supported yet.
! 95: * gui_handle_events() needs to be reworked fist
! 96: */
! 97: int pause_emulation;
1.1 root 98:
1.1.1.4 ! root 99: #ifdef __cplusplus
! 100: static RETSIGTYPE sigbrkhandler(...)
! 101: #else
! 102: static RETSIGTYPE sigbrkhandler (int foo)
! 103: #endif
1.1 root 104: {
1.1.1.4 ! root 105: activate_debugger();
! 106: #if !defined(__unix) || defined(__NeXT__)
! 107: signal (SIGINT, sigbrkhandler);
1.1 root 108: #endif
109: }
110:
1.1.1.4 ! root 111: void setup_brkhandler (void)
1.1 root 112: {
1.1.1.4 ! root 113: #if defined(__unix) && !defined(__NeXT__)
! 114: struct sigaction sa;
! 115: sa.sa_handler = sigbrkhandler;
! 116: sa.sa_flags = 0;
! 117: #ifdef SA_RESTART
! 118: sa.sa_flags = SA_RESTART;
! 119: #endif
! 120: sigemptyset (&sa.sa_mask);
! 121: sigaction (SIGINT, &sa, NULL);
! 122: #else
! 123: signal (SIGINT, sigbrkhandler);
1.1 root 124: #endif
125: }
126:
1.1.1.4 ! root 127: /*
! 128: * What graphics platform are we running on . . .?
! 129: *
! 130: * Yes, SDL is supposed to abstract away from the underlying
! 131: * platform, but we need to know this to be able to map raw keys
! 132: * and to work around any platform-specific quirks . . .
! 133: */
! 134: int get_sdlgfx_type (void)
! 135: {
! 136: char name[16] = "";
! 137: static int driver = SDLGFX_DRIVER_UNKNOWN;
! 138: static int search_done = 0;
! 139:
! 140: if (!search_done) {
! 141: if (SDL_VideoDriverName (name, sizeof name)) {
! 142: if (strcmp (name, "x11")==0)
! 143: driver = SDLGFX_DRIVER_X11;
! 144: else if (strcmp (name, "dga") == 0)
! 145: driver = SDLGFX_DRIVER_DGA;
! 146: else if (strcmp (name, "svgalib") == 0)
! 147: driver = SDLGFX_DRIVER_SVGALIB;
! 148: else if (strcmp (name, "fbcon") == 0)
! 149: driver = SDLGFX_DRIVER_FBCON;
! 150: else if (strcmp (name, "directfb") == 0)
! 151: driver = SDLGFX_DRIVER_DIRECTFB;
! 152: else if (strcmp (name, "Quartz") == 0)
! 153: driver = SDLGFX_DRIVER_QUARTZ;
! 154: else if (strcmp (name, "bwindow") == 0)
! 155: driver = SDLGFX_DRIVER_BWINDOW;
! 156: else if (strcmp (name, "CGX") == 0)
! 157: driver = SDLGFX_DRIVER_CYBERGFX;
! 158: else if (strcmp (name, "OS4") == 0)
! 159: driver = SDLGFX_DRIVER_AMIGAOS4;
! 160: }
! 161: search_done = 1;
1.1 root 162:
1.1.1.4 ! root 163: DEBUG_LOG ("SDL video driver: %s\n", name);
! 164: }
! 165: return driver;
1.1 root 166: }
167:
1.1.1.4 ! root 168: STATIC_INLINE unsigned long bitsInMask (unsigned long mask)
1.1 root 169: {
1.1.1.4 ! root 170: /* count bits in mask */
! 171: unsigned long n = 0;
! 172: while (mask) {
! 173: n += mask & 1;
! 174: mask >>= 1;
! 175: }
! 176: return n;
1.1 root 177: }
178:
1.1.1.4 ! root 179: STATIC_INLINE unsigned long maskShift (unsigned long mask)
1.1 root 180: {
1.1.1.4 ! root 181: /* determine how far mask is shifted */
! 182: unsigned long n = 0;
! 183: while (!(mask & 1)) {
! 184: n++;
! 185: mask >>= 1;
! 186: }
! 187: return n;
1.1 root 188: }
189:
190: static int get_color (int r, int g, int b, xcolnr *cnp)
191: {
1.1.1.4 ! root 192: DEBUG_LOG ("Function: get_color\n");
1.1 root 193:
1.1.1.4 ! root 194: arSDLColors[ncolors].r = r << 4;
! 195: arSDLColors[ncolors].g = g << 4;
! 196: arSDLColors[ncolors].b = b << 4;
! 197: *cnp = ncolors++;
! 198: return 1;
1.1 root 199: }
200:
201: static int init_colors (void)
202: {
1.1.1.4 ! root 203: int i;
1.1 root 204:
1.1.1.4 ! root 205: DEBUG_LOG ("Function: init_colors\n");
1.1 root 206:
1.1.1.4 ! root 207: if (bitdepth > 8) {
! 208: red_bits = bitsInMask (display->format->Rmask);
! 209: green_bits = bitsInMask (display->format->Gmask);
! 210: blue_bits = bitsInMask (display->format->Bmask);
! 211: red_shift = maskShift (display->format->Rmask);
! 212: green_shift = maskShift (display->format->Gmask);
! 213: blue_shift = maskShift (display->format->Bmask);
! 214:
! 215: alloc_colors64k (red_bits, green_bits, blue_bits, red_shift, green_shift, blue_shift);
! 216: } else {
! 217: alloc_colors256 (get_color);
! 218: SDL_SetColors (screen, arSDLColors, 0, 256);
! 219: }
1.1 root 220:
1.1.1.4 ! root 221: return 1;
! 222: }
! 223:
! 224:
! 225: /*
! 226: * Test whether the screen mode <width>x<height>x<depth> is
! 227: * available. If not, find a supported screen mode which best
! 228: * matches.
! 229: */
! 230: static int find_best_mode (int *width, int *height, int depth, int *try_fs)
! 231: {
! 232: int found = 0;
! 233:
! 234: DEBUG_LOG ("Function: find_best_mode(%d,%d,%d)\n", *width, *height, depth);
! 235:
! 236: restart:
! 237: /* First test whether the specified mode is supported */
! 238: found = SDL_VideoModeOK (*width, *height, depth, *try_fs ? SDL_FULLSCREEN : 0);
! 239:
! 240: if (!found && mode_count > 0) {
! 241: /* The specified mode wasn't available, so we'll try and find
! 242: * a supported resolution which best matches it.
! 243: */
! 244: int i;
! 245: write_log ("SDLGFX: Requested mode (%dx%d%d) not available.\n", *width, *height, depth);
! 246:
! 247: /* Note: the screenmode array should already be sorted from largest to smallest, since
! 248: * that's the order SDL gives us the screenmodes. */
! 249: for (i = mode_count - 1; i >= 0; i--) {
! 250: if (screenmode[i].w >= *width && screenmode[i].h >= *height)
1.1 root 251: break;
252: }
1.1.1.4 ! root 253:
! 254: /* If we didn't find a mode, use the largest supported mode */
! 255: if (i < 0)
! 256: i = 0;
! 257:
! 258: *width = screenmode[i].w;
! 259: *height = screenmode[i].h;
! 260: found = 1;
! 261:
! 262: write_log ("SDLGFX: Using mode (%dx%d)\n", *width, *height);
! 263: }
! 264: if (!found && *try_fs) {
! 265: *try_fs = 0;
! 266: goto restart;
! 267: }
! 268: return found;
! 269: }
! 270:
! 271: #ifdef PICASSO96
! 272: /*
! 273: * Map an SDL pixel format to a P96 pixel format
! 274: */
! 275: static int get_p96_pixel_format (const struct SDL_PixelFormat *fmt)
! 276: {
! 277: if (fmt->BitsPerPixel == 8)
! 278: return RGBFB_CLUT;
! 279:
! 280: #ifdef WORDS_BIGENDIAN
! 281: if (fmt->BitsPerPixel == 24) {
! 282: if (fmt->Rmask == 0x00FF0000 && fmt->Gmask == 0x0000FF00 && fmt->Bmask == 0x000000FF)
! 283: return RGBFB_R8G8B8;
! 284: if (fmt->Rmask == 0x000000FF && fmt->Gmask == 0x0000FF00 && fmt->Bmask == 0x00FF0000)
! 285: return RGBFB_B8G8R8;
! 286: } else if (fmt->BitsPerPixel == 32) {
! 287: if (fmt->Rmask == 0xFF000000 && fmt->Gmask == 0x00FF0000 && fmt->Bmask == 0x0000FF00)
! 288: return RGBFB_R8G8B8A8;
! 289: if (fmt->Rmask == 0x00FF0000 && fmt->Gmask == 0x0000FF00 && fmt->Bmask == 0x000000FF)
! 290: return RGBFB_A8R8G8B8;
! 291: if (fmt->Bmask == 0x00FF0000 && fmt->Gmask == 0x0000FF00 && fmt->Rmask == 0x000000FF)
! 292: return RGBFB_A8B8G8R8;
! 293: if (fmt->Bmask == 0xFF000000 && fmt->Gmask == 0x00FF0000 && fmt->Rmask == 0x0000FF00)
! 294: return RGBFB_B8G8R8A8;
! 295: } else if (fmt->BitsPerPixel == 16) {
! 296: if (get_sdlgfx_type () == SDLGFX_DRIVER_QUARTZ) {
! 297: /* The MacOS X port of SDL lies about it's default pixel format
! 298: * for high-colour display. It's always R5G5B5. */
! 299: return RGBFB_R5G5B5;
! 300: } else {
! 301: if (fmt->Rmask == 0xf800 && fmt->Gmask == 0x07e0 && fmt->Bmask == 0x001f)
! 302: return RGBFB_R5G6B5;
! 303: if (fmt->Rmask == 0x7C00 && fmt->Gmask == 0x03e0 && fmt->Bmask == 0x001f)
! 304: return RGBFB_R5G5B5;
1.1 root 305: }
1.1.1.4 ! root 306: } else if (fmt->BitsPerPixel == 15) {
! 307: if (fmt->Rmask == 0x7C00 && fmt->Gmask == 0x03e0 && fmt->Bmask == 0x001f)
! 308: return RGBFB_R5G5B5;
! 309: }
! 310: #else
! 311: if (fmt->BitsPerPixel == 24) {
! 312: if (fmt->Rmask == 0x00FF0000 && fmt->Gmask == 0x0000FF00 && fmt->Bmask == 0x000000FF)
! 313: return RGBFB_B8G8R8;
! 314: if (fmt->Rmask == 0x000000FF && fmt->Gmask == 0x0000FF00 && fmt->Bmask == 0x00FF0000)
! 315: return RGBFB_R8G8B8;
! 316: } else if (fmt->BitsPerPixel == 32) {
! 317: if (fmt->Rmask == 0xFF000000 && fmt->Gmask == 0x00FF0000 && fmt->Bmask == 0x0000FF00)
! 318: return RGBFB_A8B8G8R8;
! 319: if (fmt->Rmask == 0x00FF0000 && fmt->Gmask == 0x0000FF00 && fmt->Bmask == 0x000000FF)
! 320: return RGBFB_B8G8R8A8;
! 321: if (fmt->Bmask == 0x00FF0000 && fmt->Gmask == 0x0000FF00 && fmt->Rmask == 0x000000FF)
! 322: return RGBFB_R8G8B8A8;
! 323: if (fmt->Bmask == 0xFF000000 && fmt->Gmask == 0x00FF0000 && fmt->Rmask == 0x0000FF00)
! 324: return RGBFB_A8R8G8B8;
! 325: } else if (fmt->BitsPerPixel == 16) {
! 326: if (fmt->Rmask == 0xf800 && fmt->Gmask == 0x07e0 && fmt->Bmask == 0x001f)
! 327: return RGBFB_R5G6B5PC;
! 328: if (fmt->Rmask == 0x7C00 && fmt->Gmask == 0x03e0 && fmt->Bmask == 0x001f)
! 329: return RGBFB_R5G5B5PC;
! 330: } else if (fmt->BitsPerPixel == 15) {
! 331: if (fmt->Rmask == 0x7C00 && fmt->Gmask == 0x03e0 && fmt->Bmask == 0x001f)
! 332: return RGBFB_R5G5B5PC;
! 333: }
! 334: #endif
! 335:
! 336: return RGBFB_NONE;
1.1 root 337: }
1.1.1.4 ! root 338: #endif
1.1 root 339:
1.1.1.4 ! root 340: /*
! 341: * Build list of full-screen screen-modes supported by SDL
! 342: * with the specified pixel format.
! 343: *
! 344: * Returns a count of the number of supported modes, -1 if any mode is supported,
! 345: * or 0 if there are no modes with this pixel format.
! 346: */
! 347: static long find_screen_modes (struct SDL_PixelFormat *vfmt, SDL_Rect *mode_list, int mode_list_size)
! 348: {
! 349: long count = 0;
! 350: SDL_Rect **modes = SDL_ListModes (vfmt, SDL_FULLSCREEN | SDL_HWSURFACE);
! 351:
! 352: if (modes != 0 && modes != (SDL_Rect**)-1) {
! 353: unsigned int i;
! 354: int w = -1;
! 355: int h = -1;
! 356:
! 357: /* Filter list of modes SDL gave us and ignore duplicates */
! 358: for (i = 0; modes[i] && count < mode_list_size; i++) {
! 359: if (modes[i]->w != w || modes[i]->h != h) {
! 360: mode_list[count].w = w = modes[i]->w;
! 361: mode_list[count].h = h = modes[i]->h;
! 362: count++;
! 363:
! 364: write_log ("SDLGFX: Found screenmode: %dx%d.\n", w, h);
! 365: }
! 366: }
! 367: } else
! 368: count = (long) modes;
! 369:
! 370: return count;
! 371: }
! 372:
! 373: /**
! 374: ** Buffer methods for SDL surfaces that must be locked
! 375: **/
! 376:
! 377: int lockscr (void)
1.1 root 378: {
1.1.1.4 ! root 379: int success = 0;
1.1 root 380:
1.1.1.4 ! root 381: if (!SDL_MUSTLOCK (screen))
! 382: return 1;
! 383:
! 384: if (SDL_LockSurface (display) == 0) {
! 385: gfxvidinfo.bufmem = display->pixels;
! 386: gfxvidinfo.rowbytes = display->pitch;
! 387:
! 388: if (display->pixels != old_pixels) {
! 389: /* If the address of the pixel data has
! 390: * changed, recalculate the row maps
! 391: */
! 392: init_row_map ();
! 393: old_pixels = display->pixels;
! 394: }
! 395: success = 1;
1.1 root 396: }
1.1.1.4 ! root 397: return success;
! 398: }
1.1 root 399:
1.1.1.4 ! root 400: void unlockscr (void)
! 401: {
! 402: if (SDL_MUSTLOCK (screen))
! 403: SDL_UnlockSurface (display);
1.1 root 404: }
405:
1.1.1.4 ! root 406: void flush_block (int first_line, int last_line)
! 407: {
! 408: // DEBUG_LOG ("Function: flush_block %d %d\n", first_line, last_line);
! 409:
! 410: SDL_UpdateRect (display, 0, first_line, current_width, last_line - first_line + 1);
! 411: }
1.1 root 412:
1.1.1.4 ! root 413: void flush_screen (int first_line, int last_line)
1.1 root 414: {
1.1.1.4 ! root 415: if (! (screen->flags & SDL_DOUBLEBUF))
! 416: return;
1.1 root 417:
1.1.1.4 ! root 418: SDL_BlitSurface (display,0,screen,0);
1.1 root 419:
1.1.1.4 ! root 420: SDL_Flip (screen);
! 421: }
1.1 root 422:
1.1.1.4 ! root 423: void flush_line (int line)
! 424: {
1.1 root 425: }
426:
1.1.1.4 ! root 427: int graphics_setup (void)
! 428: {
! 429: int result = 0;
1.1 root 430:
1.1.1.4 ! root 431: if (SDL_InitSubSystem (SDL_INIT_VIDEO) == 0) {
! 432:
! 433: const SDL_version *version = SDL_Linked_Version ();
! 434: const SDL_VideoInfo *info = SDL_GetVideoInfo ();
! 435:
! 436: write_log ("SDLGFX: Initialized.\n");
! 437: write_log ("SDLGFX: Using SDL version %d.%d.%d.\n", version->major, version->minor, version->patch);
! 438:
! 439: /* Find default display depth */
! 440: bitdepth = info->vfmt->BitsPerPixel;
! 441: bit_unit = info->vfmt->BytesPerPixel * 8;
! 442:
! 443: write_log ("SDLGFX: Display is %d bits deep.\n", bitdepth);
! 444:
! 445: /* Build list of screenmodes */
! 446: mode_count = find_screen_modes (info->vfmt, &screenmode[0], MAX_SDL_SCREENMODE);
! 447:
! 448: result = 1;
! 449: sdlgfx_init_ok = 1;
! 450: } else
! 451: write_log ("SDLGFX: initialization failed - %s\n", SDL_GetError());
! 452:
! 453: return result;
! 454: }
! 455:
! 456: static int graphics_subinit (void)
1.1 root 457: {
1.1.1.4 ! root 458: Uint32 uiSDLVidModFlags = 0;
1.1 root 459:
1.1.1.4 ! root 460: DEBUG_LOG ("Function: graphics_subinit\n");
1.1 root 461:
1.1.1.4 ! root 462: if (screen_is_picasso) {
! 463: // Set height, width for Picasso gfx
! 464: current_width = picasso_vidinfo.width;
! 465: current_height = picasso_vidinfo.height;
! 466: fullscreen = currprefs.gfx_pfullscreen;
! 467: curr_gfx = 0;
! 468: } else {
! 469: // Set height, width for Amiga gfx
! 470: fullscreen = currprefs.gfx_afullscreen;
! 471: if (fullscreen)
! 472: curr_gfx = &currprefs.gfx_f;
! 473: else
! 474: curr_gfx = &currprefs.gfx_w;
! 475:
! 476: current_width = curr_gfx->width;
! 477: current_height = curr_gfx->height;
! 478: }
! 479: find_best_mode (¤t_width, ¤t_height, bitdepth, &fullscreen);
! 480: if (!screen_is_picasso) {
! 481: gfxvidinfo.width = current_width;
! 482: gfxvidinfo.height = current_height;
! 483: }
1.1 root 484:
1.1.1.4 ! root 485: if (bitdepth == 8)
! 486: uiSDLVidModFlags |= SDL_HWPALETTE;
! 487: if (fullscreen) {
! 488: uiSDLVidModFlags |= SDL_FULLSCREEN | SDL_HWSURFACE;
! 489: if(!screen_is_picasso && 0 /*currprefs.gfx_vsync */)
! 490: uiSDLVidModFlags |= SDL_DOUBLEBUF;
! 491: }
1.1 root 492:
1.1.1.4 ! root 493: DEBUG_LOG ("Resolution: %d x %d x %d (FS: %d)\n", current_width, current_height, bitdepth, fullscreen);
1.1 root 494:
1.1.1.4 ! root 495: screen = SDL_SetVideoMode (current_width, current_height, bitdepth, uiSDLVidModFlags);
1.1 root 496:
1.1.1.4 ! root 497: if (screen == NULL) {
! 498: #if 0
! 499: gui_message ("Unable to set video mode: %s\n", SDL_GetError ());
! 500: #endif
! 501: return 0;
! 502: } else {
! 503: /* Just in case we didn't get exactly what we asked for . . . */
! 504: fullscreen = ((screen->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN);
! 505: is_hwsurface = ((screen->flags & SDL_HWSURFACE) == SDL_HWSURFACE);
! 506:
! 507: /* Are these values what we expected? */
! 508: # ifdef PICASSO96
! 509: DEBUG_LOG ("P96 screen? : %d\n", screen_is_picasso);
! 510: # endif
! 511: DEBUG_LOG ("Fullscreen? : %d\n", fullscreen);
! 512: DEBUG_LOG ("Mouse grabbed? : %d\n", mousegrab);
! 513: DEBUG_LOG ("HW surface? : %d\n", is_hwsurface);
! 514: DEBUG_LOG ("Must lock? : %d\n", SDL_MUSTLOCK (screen));
! 515: DEBUG_LOG ("Bytes per Pixel: %d\n", screen->format->BytesPerPixel);
! 516: DEBUG_LOG ("Bytes per Line : %d\n", screen->pitch);
! 517:
! 518: /* Set up buffer methods */
! 519:
! 520: if (screen->flags & SDL_DOUBLEBUF) {
! 521: display = SDL_CreateRGBSurface(SDL_HWSURFACE, screen->w, screen->h, screen->format->BitsPerPixel,
! 522: screen->format->Rmask, screen->format->Gmask, screen->format->Bmask, 0);
1.1 root 523:
1.1.1.4 ! root 524: } else {
! 525: display = screen;
1.1 root 526: }
527:
1.1.1.4 ! root 528: /* Set UAE window title and icon name */
! 529: SDL_WM_SetCaption (PACKAGE_NAME, PACKAGE_NAME);
! 530:
! 531: /* Mouse is now always grabbed when full-screen - to work around
! 532: * problems with full-screen mouse input in some SDL implementations */
! 533: if (fullscreen)
! 534: SDL_WM_GrabInput (SDL_GRAB_ON);
! 535: else
! 536: SDL_WM_GrabInput (mousegrab ? SDL_GRAB_ON : SDL_GRAB_OFF);
! 537:
! 538: /* Hide mouse cursor */
! 539: SDL_ShowCursor (/*currprefs.hide_cursor || */fullscreen || mousegrab ? SDL_DISABLE : SDL_ENABLE);
! 540:
! 541: inputdevice_release_all_keys ();
! 542: reset_hotkeys ();
! 543:
! 544: #ifdef PICASSO96
! 545: if (!screen_is_picasso) {
! 546: #endif
! 547: /* Initialize structure for Amiga video modes */
! 548: if (is_hwsurface) {
! 549: SDL_LockSurface (display);
! 550: gfxvidinfo.bufmem = 0;
! 551: gfxvidinfo.emergmem = malloc (display->pitch);
! 552: gfxvidinfo.maxblocklines = 0;
! 553: SDL_UnlockSurface (display);
! 554: }
! 555:
! 556: if (!is_hwsurface) {
! 557: gfxvidinfo.bufmem = display->pixels;
! 558: gfxvidinfo.emergmem = 0;
! 559: gfxvidinfo.maxblocklines = gfxvidinfo.height;
! 560: }
! 561: gfxvidinfo.linemem = 0;
! 562: gfxvidinfo.pixbytes = display->format->BytesPerPixel;
! 563: bit_unit = display->format->BytesPerPixel * 8;
! 564: gfxvidinfo.rowbytes = display->pitch;
! 565:
1.1 root 566:
1.1.1.4 ! root 567: SDL_SetColors (display, arSDLColors, 0, 256);
1.1 root 568:
1.1.1.4 ! root 569: reset_drawing ();
1.1 root 570:
1.1.1.4 ! root 571: /* Force recalculation of row maps - if we're locking */
! 572: old_pixels = (void *)-1;
! 573: #ifdef PICASSO96
! 574: } else {
! 575: /* Initialize structure for Picasso96 video modes */
! 576: picasso_vidinfo.rowbytes = display->pitch;
! 577: picasso_vidinfo.extra_mem = 1;
! 578: picasso_vidinfo.depth = bitdepth;
! 579: picasso_has_invalid_lines = 0;
! 580: picasso_invalid_start = picasso_vidinfo.height + 1;
! 581: picasso_invalid_stop = -1;
! 582:
! 583: memset (picasso_invalid_lines, 0, sizeof picasso_invalid_lines);
! 584: }
! 585: #endif
! 586: }
1.1 root 587:
588: return 1;
589: }
590:
1.1.1.4 ! root 591: int graphics_init (void)
1.1 root 592: {
1.1.1.4 ! root 593: int success = 0;
! 594:
! 595: DEBUG_LOG ("Function: graphics_init\n");
! 596:
! 597: if (currprefs.color_mode > 5) {
! 598: write_log ("Bad color mode selected. Using default.\n");
! 599: currprefs.color_mode = 0;
! 600: }
! 601:
! 602: #ifdef PICASSO96
! 603: screen_is_picasso = 0;
1.1 root 604: #endif
1.1.1.4 ! root 605: mousegrab = 0;
! 606:
! 607: fixup_prefs_dimensions (&currprefs.gfx_w);
! 608: fixup_prefs_dimensions (&currprefs.gfx_f);
1.1 root 609:
1.1.1.4 ! root 610: if (graphics_subinit ()) {
! 611: if (init_colors ()) {
! 612: success = 1;
! 613: }
! 614: }
! 615: return success;
1.1 root 616: }
617:
1.1.1.4 ! root 618: static void graphics_subshutdown (int final)
1.1 root 619: {
1.1.1.4 ! root 620: DEBUG_LOG ("Function: graphics_subshutdown\n");
1.1 root 621:
1.1.1.4 ! root 622: if (display && display != screen)
! 623: SDL_FreeSurface (display);
1.1 root 624:
1.1.1.4 ! root 625: /* XRandR requires that clients sometimes have to retry a request for
! 626: changing screen size, which SDL doesn't do. Work around the problem
! 627: by reinitializing SDL. */
! 628: SDL_QuitSubSystem (SDL_INIT_VIDEO);
! 629: SDL_InitSubSystem (SDL_INIT_VIDEO);
! 630: if (fullscreen)
! 631: /* Try switching back to the previous screenmode. */
! 632: SDL_SetVideoMode (screenmode[0].w, screenmode[0].h, bitdepth, SDL_FULLSCREEN);
1.1 root 633:
1.1.1.4 ! root 634: display = screen = 0;
1.1 root 635:
1.1.1.4 ! root 636: if (gfxvidinfo.emergmem) {
! 637: free (gfxvidinfo.emergmem);
! 638: gfxvidinfo.emergmem = 0;
1.1 root 639: }
1.1.1.4 ! root 640: }
! 641:
! 642: void graphics_leave (void)
! 643: {
! 644: DEBUG_LOG ("Function: graphics_leave\n");
! 645:
! 646: graphics_subshutdown (1);
! 647: SDL_QuitSubSystem (SDL_INIT_VIDEO);
! 648: dumpcustom ();
1.1 root 649: }
650:
651: static int refresh_necessary = 0;
652:
653: void handle_events (void)
654: {
655: SDL_Event rEvent;
656:
657: gui_handle_events ();
658:
1.1.1.4 ! root 659: while (SDL_PollEvent (&rEvent)) {
! 660: switch (rEvent.type) {
! 661: case SDL_QUIT:
! 662: DEBUG_LOG ("Event: quit\n");
! 663: uae_quit();
! 664: break;
! 665:
! 666: case SDL_MOUSEBUTTONDOWN:
! 667: case SDL_MOUSEBUTTONUP: {
! 668: int state = (rEvent.type == SDL_MOUSEBUTTONDOWN);
! 669: int buttonno = -1;
! 670:
! 671: DEBUG_LOG ("Event: mouse button %d %s\n", rEvent.button.button, state ? "down" : "up");
! 672:
! 673: switch (rEvent.button.button) {
! 674: case SDL_BUTTON_LEFT: buttonno = 0; break;
! 675: case SDL_BUTTON_MIDDLE: buttonno = 2; break;
! 676: case SDL_BUTTON_RIGHT: buttonno = 1; break;
! 677: #ifdef SDL_BUTTON_WHEELUP
! 678: case SDL_BUTTON_WHEELUP: if (state) record_key (0x7a << 1); break;
! 679: case SDL_BUTTON_WHEELDOWN: if (state) record_key (0x7b << 1); break;
1.1 root 680: #endif
681: }
1.1.1.4 ! root 682: if (buttonno >= 0)
! 683: setmousebuttonstate (0, buttonno, rEvent.type == SDL_MOUSEBUTTONDOWN ? 1:0);
! 684: break;
1.1 root 685: }
1.1.1.4 ! root 686:
! 687: case SDL_KEYUP:
! 688: case SDL_KEYDOWN: {
! 689: int state = (rEvent.type == SDL_KEYDOWN);
! 690: int keycode;
! 691: int ievent;
! 692:
! 693: keycode = rEvent.key.keysym.sym;
! 694:
! 695: DEBUG_LOG ("Event: key %d %s\n", keycode, state ? "down" : "up");
! 696:
! 697: if ((ievent = match_hotkey_sequence (keycode, state))) {
! 698: DEBUG_LOG ("Hotkey event: %d\n", ievent);
! 699: handle_hotkey_event (ievent, state);
! 700: } else {
! 701: inputdevice_do_keyboard (keysym2amiga (keycode), state);
1.1 root 702: }
1.1.1.4 ! root 703: break;
1.1 root 704: }
1.1.1.4 ! root 705:
! 706: case SDL_MOUSEMOTION:
! 707: //DEBUG_LOG ("Event: mouse motion\n");
! 708:
! 709: if (!fullscreen && !mousegrab) {
! 710: setmousestate (0, 0,rEvent.motion.x, 1);
! 711: setmousestate (0, 1,rEvent.motion.y, 1);
! 712: } else {
! 713: setmousestate (0, 0, rEvent.motion.xrel, 0);
! 714: setmousestate (0, 1, rEvent.motion.yrel, 0);
1.1 root 715: }
1.1.1.4 ! root 716: break;
! 717:
! 718: case SDL_ACTIVEEVENT:
! 719: if (rEvent.active.state & SDL_APPINPUTFOCUS && !rEvent.active.gain) {
! 720: DEBUG_LOG ("Lost input focus\n");
! 721: inputdevice_release_all_keys ();
! 722: reset_hotkeys ();
1.1 root 723: }
1.1.1.4 ! root 724: break;
! 725: } /* end switch() */
! 726: } /* end while() */
! 727:
! 728: #ifdef PICASSO96
! 729: if (screen_is_picasso && refresh_necessary) {
! 730: SDL_UpdateRect (screen, 0, 0, picasso_vidinfo.width, picasso_vidinfo.height);
1.1 root 731: refresh_necessary = 0;
732: memset (picasso_invalid_lines, 0, sizeof picasso_invalid_lines);
1.1.1.4 ! root 733: } else if (screen_is_picasso && picasso_has_invalid_lines) {
1.1 root 734: int i;
735: int strt = -1;
736: picasso_invalid_lines[picasso_vidinfo.height] = 0;
1.1.1.4 ! root 737: for (i = picasso_invalid_start; i < picasso_invalid_stop + 2; i++) {
! 738: if (picasso_invalid_lines[i]) {
1.1 root 739: picasso_invalid_lines[i] = 0;
740: if (strt != -1)
741: continue;
742: strt = i;
1.1.1.4 ! root 743: } else {
1.1 root 744: if (strt == -1)
745: continue;
1.1.1.4 ! root 746: SDL_UpdateRect (screen, 0, strt, picasso_vidinfo.width, i - strt);
1.1 root 747: strt = -1;
748: }
749: }
750: if (strt != -1)
751: abort ();
752: }
753: picasso_has_invalid_lines = 0;
754: picasso_invalid_start = picasso_vidinfo.height + 1;
755: picasso_invalid_stop = -1;
756: #endif
1.1.1.4 ! root 757: }
1.1 root 758:
1.1.1.4 ! root 759: static void switch_keymaps (void)
! 760: {
! 761: set_default_hotkeys (get_default_cooked_hotkeys ());
1.1 root 762: }
763:
764: int check_prefs_changed_gfx (void)
765: {
1.1.1.4 ! root 766: int a_changed = 0, p_changed = 0;
1.1 root 767:
1.1.1.4 ! root 768: if (!screen_is_picasso) {
! 769: if (!fullscreen
! 770: && memcmp (&changed_prefs.gfx_w, &currprefs.gfx_w, sizeof (struct gfx_params)) != 0)
! 771: {
! 772: a_changed = 1;
! 773: fixup_prefs_dimensions (&changed_prefs.gfx_w);
! 774: currprefs.gfx_w = changed_prefs.gfx_w;
! 775: } else if (fullscreen
! 776: && memcmp (&changed_prefs.gfx_f, &currprefs.gfx_f, sizeof (struct gfx_params)) != 0)
! 777: {
! 778: a_changed = 1;
! 779: fixup_prefs_dimensions (&changed_prefs.gfx_f);
! 780: currprefs.gfx_f = changed_prefs.gfx_f;
! 781: }
! 782: if (changed_prefs.gfx_afullscreen != currprefs.gfx_afullscreen) {
! 783: a_changed = 1;
! 784: }
! 785: } else if (changed_prefs.gfx_pfullscreen != currprefs.gfx_pfullscreen) {
! 786: p_changed = 1;
1.1 root 787: }
1.1.1.4 ! root 788:
1.1 root 789: currprefs.gfx_afullscreen = changed_prefs.gfx_afullscreen;
790: currprefs.gfx_pfullscreen = changed_prefs.gfx_pfullscreen;
791:
1.1.1.4 ! root 792: if (!a_changed && !p_changed)
! 793: return 0;
! 794:
! 795: DEBUG_LOG ("Function: check_prefs_changed_gfx\n");
! 796:
! 797: graphics_subshutdown (0);
! 798:
1.1 root 799: gui_update_gfx ();
800:
801: graphics_subinit ();
802:
803: notice_screen_contents_lost ();
804: init_row_map ();
805: if (screen_is_picasso)
806: picasso_enablescreen (1);
1.1.1.4 ! root 807:
1.1 root 808: return 0;
809: }
810:
811: int debuggable (void)
812: {
813: return 1;
814: }
815:
816: int needmousehack (void)
817: {
818: return 1;
819: }
820:
1.1.1.4 ! root 821: int mousehack_allowed (void)
1.1 root 822: {
1.1.1.4 ! root 823: return 1;
! 824: }
1.1 root 825:
1.1.1.4 ! root 826: void LED (int on)
! 827: {
1.1 root 828: }
829:
830: #ifdef PICASSO96
831:
832: void DX_Invalidate (int first, int last)
833: {
1.1.1.4 ! root 834: DEBUG_LOG ("Function: DX_Invalidate %i - %i\n", first, last);
! 835:
! 836: if (is_hwsurface)
! 837: return;
1.1 root 838:
839: if (first > last)
840: return;
841:
842: picasso_has_invalid_lines = 1;
843: if (first < picasso_invalid_start)
844: picasso_invalid_start = first;
845: if (last > picasso_invalid_stop)
846: picasso_invalid_stop = last;
847:
1.1.1.4 ! root 848: while (first <= last) {
1.1 root 849: picasso_invalid_lines[first] = 1;
850: first++;
851: }
852: }
853:
854: int DX_BitsPerCannon (void)
855: {
856: return 8;
857: }
858:
1.1.1.4 ! root 859: static int palette_update_start = 256;
! 860: static int palette_update_end = 0;
1.1 root 861:
862: void DX_SetPalette (int start, int count)
863: {
1.1.1.4 ! root 864: DEBUG_LOG ("Function: DX_SetPalette_real\n");
1.1 root 865:
866: if (! screen_is_picasso || picasso96_state.RGBFormat != RGBFB_CHUNKY)
867: return;
868:
1.1.1.4 ! root 869: if (picasso_vidinfo.pixbytes != 1) {
! 870: /* This is the case when we're emulating a 256 color display. */
! 871: while (count-- > 0) {
1.1 root 872: int r = picasso96_state.CLUT[start].Red;
873: int g = picasso96_state.CLUT[start].Green;
874: int b = picasso96_state.CLUT[start].Blue;
1.1.1.4 ! root 875: picasso_vidinfo.clut[start++] =
! 876: (doMask256 (r, red_bits, red_shift)
! 877: | doMask256 (g, green_bits, green_shift)
! 878: | doMask256 (b, blue_bits, blue_shift));
1.1 root 879: }
1.1.1.4 ! root 880: } else {
! 881: int i;
! 882: for (i = start; i < start+count && i < 256; i++) {
! 883: p96Colors[i].r = picasso96_state.CLUT[i].Red;
! 884: p96Colors[i].g = picasso96_state.CLUT[i].Green;
! 885: p96Colors[i].b = picasso96_state.CLUT[i].Blue;
! 886: }
! 887: SDL_SetColors (screen, &p96Colors[start], start, count);
1.1 root 888: }
1.1.1.4 ! root 889: }
1.1 root 890:
891: #if 0
1.1.1.4 ! root 892: void DX_SetPalette_vsync(void)
! 893: {
! 894: if (palette_update_end > palette_update_start) {
! 895: DX_SetPalette (palette_update_start,
! 896: palette_update_end - palette_update_start);
! 897: palette_update_end = 0;
! 898: palette_update_start = 0;
! 899: }
! 900: }
! 901:
! 902: int DX_Fill (int dstx, int dsty, int width, int height, uae_u32 color, RGBFTYPE rgbtype)
! 903: {
! 904: int result = 0;
! 905: SDL_Rect rect = {dstx, dsty, width, height};
! 906:
! 907: DEBUG_LOG ("DX_Fill (x:%d y:%d w:%d h:%d color=%08x)\n", dstx, dsty, width, height, color);
! 908:
! 909: if (SDL_FillRect (screen, &rect, color) == 0) {
! 910: DX_Invalidate (dsty, dsty + height - 1);
! 911: result = 1;
1.1 root 912: }
1.1.1.4 ! root 913: return result;
1.1 root 914: }
915:
1.1.1.4 ! root 916: int DX_Blit (int srcx, int srcy, int dstx, int dsty, int width, int height, BLIT_OPCODE opcode)
1.1 root 917: {
1.1.1.4 ! root 918: int result = 0;
! 919: SDL_Rect src_rect = {srcx, srcy, width, height};
! 920: SDL_Rect dest_rect = {dstx, dsty, 0, 0};
1.1 root 921:
1.1.1.4 ! root 922: DEBUG_LOG ("DX_Blit (sx:%d sy:%d dx:%d dy:%d w:%d h:%d op:%d)\n",
! 923: srcx, srcy, dstx, dsty, width, height, opcode);
! 924:
! 925: if (opcode == BLIT_SRC && SDL_BlitSurface (screen, &src_rect, screen, &dest_rect) == 0) {
! 926: DX_Invalidate (dsty, dsty + height - 1);
! 927: result = 1;
! 928: }
! 929: return result;
! 930: }
1.1 root 931: #endif
932:
1.1.1.4 ! root 933: /*
! 934: * Add a screenmode to the emulated P96 display database
! 935: */
! 936: static void add_p96_mode (int width, int height, int emulate_chunky, int *count)
! 937: {
! 938: unsigned int i;
! 939:
! 940: for (i = 0; i <= (emulate_chunky ? 1 : 0); i++) {
! 941: if (*count < MAX_PICASSO_MODES) {
! 942: DisplayModes[*count].res.width = width;
! 943: DisplayModes[*count].res.height = height;
! 944: DisplayModes[*count].depth = (i == 1) ? 1 : bit_unit >> 3;
! 945: DisplayModes[*count].refresh = 75;
! 946: (*count)++;
! 947:
! 948: write_log ("SDLGFX: Added P96 mode: %dx%dx%d\n", width, height, (i == 1) ? 8 : bitdepth);
1.1 root 949: }
950: }
1.1.1.4 ! root 951: return;
! 952: }
1.1 root 953:
1.1.1.4 ! root 954: int DX_FillResolutions (uae_u16 *ppixel_format)
! 955: {
! 956: int i;
! 957: int count = 0;
! 958: int emulate_chunky = 0;
! 959:
! 960: DEBUG_LOG ("Function: DX_FillResolutions\n");
1.1 root 961:
1.1.1.4 ! root 962: /* Find supported pixel formats */
! 963: picasso_vidinfo.rgbformat = get_p96_pixel_format (SDL_GetVideoInfo()->vfmt);
1.1 root 964:
965: *ppixel_format = 1 << picasso_vidinfo.rgbformat;
1.1.1.4 ! root 966: if (bit_unit == 16 || bit_unit == 32) {
1.1 root 967: *ppixel_format |= RGBFF_CHUNKY;
968: emulate_chunky = 1;
969: }
970:
1.1.1.4 ! root 971: /* Check list of standard P96 screenmodes */
! 972: for (i = 0; i < MAX_SCREEN_MODES; i++) {
! 973: if (SDL_VideoModeOK (x_size_table[i], y_size_table[i], bitdepth,
! 974: SDL_HWSURFACE | SDL_FULLSCREEN)) {
! 975: add_p96_mode (x_size_table[i], y_size_table[i], emulate_chunky, &count);
! 976: }
! 977: }
! 978:
! 979: /* Check list of supported SDL screenmodes */
! 980: for (i = 0; i < mode_count; i++) {
1.1 root 981: int j;
1.1.1.4 ! root 982: int found = 0;
! 983: for (j = 0; j < MAX_SCREEN_MODES - 1; j++) {
! 984: if (screenmode[i].w == x_size_table[j] &&
! 985: screenmode[i].h == y_size_table[j])
1.1 root 986: {
1.1.1.4 ! root 987: found = 1;
! 988: break;
1.1 root 989: }
990: }
1.1.1.4 ! root 991:
! 992: /* If SDL mode is not a standard P96 mode (and thus already added to the
! 993: * list, above) then add it */
! 994: if (!found)
! 995: add_p96_mode (screenmode[i].w, screenmode[i].h, emulate_chunky, &count);
1.1 root 996: }
1.1.1.4 ! root 997:
1.1 root 998: return count;
999: }
1000:
1001: static void set_window_for_picasso (void)
1002: {
1.1.1.4 ! root 1003: DEBUG_LOG ("Function: set_window_for_picasso\n");
! 1004: #if 0
1.1 root 1005: if (current_width == picasso_vidinfo.width && current_height == picasso_vidinfo.height)
1.1.1.4 ! root 1006: return;
! 1007: #endif
1.1 root 1008:
1.1.1.4 ! root 1009: graphics_subshutdown(0);
! 1010: graphics_subinit();
1.1 root 1011: }
1012:
1013: void gfx_set_picasso_modeinfo (int w, int h, int depth, int rgbfmt)
1014: {
1.1.1.4 ! root 1015: DEBUG_LOG ("Function: gfx_set_picasso_modeinfo w: %i h: %i depth: %i rgbfmt: %i\n", w, h, depth, rgbfmt);
! 1016:
! 1017: if (screen_is_picasso
! 1018: && picasso_vidinfo.width == w
! 1019: && picasso_vidinfo.height == h)
! 1020: return;
1.1 root 1021:
1022: picasso_vidinfo.width = w;
1023: picasso_vidinfo.height = h;
1024: picasso_vidinfo.depth = depth;
1025: picasso_vidinfo.pixbytes = bit_unit >> 3;
1026: if (screen_is_picasso)
1027: set_window_for_picasso();
1028: }
1029:
1030: void gfx_set_picasso_baseaddr (uaecptr a)
1031: {
1032: }
1033:
1034: void gfx_set_picasso_state (int on)
1035: {
1.1.1.4 ! root 1036: DEBUG_LOG ("Function: gfx_set_picasso_state: %d\n", on);
1.1 root 1037:
1038: if (on == screen_is_picasso)
1039: return;
1.1.1.4 ! root 1040:
! 1041: graphics_subshutdown (0);
1.1 root 1042: screen_is_picasso = on;
1.1.1.4 ! root 1043:
1.1 root 1044: graphics_subinit ();
1.1.1.4 ! root 1045:
1.1 root 1046: if (on)
1047: DX_SetPalette (0, 256);
1048: }
1049:
1050: uae_u8 *gfx_lock_picasso (void)
1051: {
1.1.1.4 ! root 1052: DEBUG_LOG ("Function: gfx_lock_picasso\n");
! 1053:
! 1054: if (SDL_MUSTLOCK (screen))
! 1055: SDL_LockSurface (screen);
! 1056: picasso_vidinfo.rowbytes = screen->pitch;
! 1057: return screen->pixels;
1.1 root 1058: }
1059:
1060: void gfx_unlock_picasso (void)
1061: {
1.1.1.4 ! root 1062: DEBUG_LOG ("Function: gfx_unlock_picasso\n");
! 1063:
! 1064: if (SDL_MUSTLOCK (screen))
! 1065: SDL_UnlockSurface (screen);
1.1 root 1066: }
1.1.1.4 ! root 1067: #endif /* PICASSO96 */
1.1 root 1068:
1.1.1.4 ! root 1069: void toggle_fullscreen (void)
! 1070: {
! 1071: changed_prefs.gfx_afullscreen = changed_prefs.gfx_pfullscreen = !fullscreen;
! 1072:
! 1073: DEBUG_LOG ("ToggleFullScreen: %d\n", fullscreen );
! 1074: };
! 1075:
! 1076: void toggle_mousegrab (void)
! 1077: {
! 1078: if (!fullscreen) {
! 1079: if (SDL_WM_GrabInput (SDL_GRAB_QUERY) == SDL_GRAB_OFF) {
! 1080: if (SDL_WM_GrabInput (SDL_GRAB_ON) == SDL_GRAB_ON) {
! 1081: SDL_WarpMouse (0, 0);
! 1082: mousegrab = 1;
! 1083: SDL_ShowCursor (SDL_DISABLE);
! 1084: }
! 1085: } else {
! 1086: if (SDL_WM_GrabInput (SDL_GRAB_OFF) == SDL_GRAB_OFF) {
! 1087: mousegrab = 0;
! 1088: SDL_ShowCursor (SDL_DISABLE);
! 1089: }
! 1090: }
! 1091: }
! 1092: }
! 1093:
! 1094: void screenshot (int mode)
! 1095: {
! 1096: write_log ("Screenshot not supported yet\n");
! 1097: }
! 1098:
! 1099: /*
! 1100: * Mouse inputdevice functions
! 1101: */
! 1102:
! 1103: /* Hardwire for 3 axes and 3 buttons - although SDL doesn't
! 1104: * currently support a Z-axis as such. Mousewheel events are supplied
! 1105: * as buttons 4 and 5
! 1106: */
! 1107: #define MAX_BUTTONS 3
! 1108: #define MAX_AXES 3
! 1109: #define FIRST_AXIS 0
! 1110: #define FIRST_BUTTON MAX_AXES
! 1111:
! 1112: static int init_mouse (void)
! 1113: {
! 1114: return 1;
! 1115: }
! 1116:
! 1117: static void close_mouse (void)
! 1118: {
! 1119: return;
! 1120: }
! 1121:
! 1122: static int acquire_mouse (unsigned int num, int flags)
! 1123: {
! 1124: /* SDL supports only one mouse */
! 1125: return 1;
! 1126: }
! 1127:
! 1128: static void unacquire_mouse (unsigned int num)
! 1129: {
! 1130: return;
! 1131: }
! 1132:
! 1133: static unsigned int get_mouse_num (void)
1.1 root 1134: {
1135: return 1;
1136: }
1137:
1.1.1.4 ! root 1138: static const char *get_mouse_name (unsigned int mouse)
1.1 root 1139: {
1.1.1.4 ! root 1140: return "Default mouse";
1.1 root 1141: }
1142:
1.1.1.4 ! root 1143: static unsigned int get_mouse_widget_num (unsigned int mouse)
1.1 root 1144: {
1.1.1.4 ! root 1145: return MAX_AXES + MAX_BUTTONS;
! 1146: }
! 1147:
! 1148: static int get_mouse_widget_first (unsigned int mouse, int type)
! 1149: {
! 1150: switch (type) {
! 1151: case IDEV_WIDGET_BUTTON:
! 1152: return FIRST_BUTTON;
! 1153: case IDEV_WIDGET_AXIS:
! 1154: return FIRST_AXIS;
1.1 root 1155: }
1.1.1.4 ! root 1156: return -1;
! 1157: }
! 1158:
! 1159: static int get_mouse_widget_type (unsigned int mouse, unsigned int num, char *name, uae_u32 *code)
! 1160: {
! 1161: if (num >= MAX_AXES && num < MAX_AXES + MAX_BUTTONS) {
! 1162: if (name)
! 1163: sprintf (name, "Button %d", num + 1 + MAX_AXES);
! 1164: return IDEV_WIDGET_BUTTON;
! 1165: } else if (num < MAX_AXES) {
! 1166: if (name)
! 1167: sprintf (name, "Axis %d", num + 1);
! 1168: return IDEV_WIDGET_AXIS;
1.1 root 1169: }
1.1.1.4 ! root 1170: return IDEV_WIDGET_NONE;
1.1 root 1171: }
1172:
1.1.1.4 ! root 1173: static void read_mouse (void)
1.1 root 1174: {
1.1.1.4 ! root 1175: /* We handle mouse input in handle_events() */
1.1 root 1176: }
1177:
1.1.1.4 ! root 1178: struct inputdevice_functions inputdevicefunc_mouse = {
! 1179: init_mouse,
! 1180: close_mouse,
! 1181: acquire_mouse,
! 1182: unacquire_mouse,
! 1183: read_mouse,
! 1184: get_mouse_num,
! 1185: get_mouse_name,
! 1186: get_mouse_widget_num,
! 1187: get_mouse_widget_type,
! 1188: get_mouse_widget_first
! 1189: };
! 1190:
! 1191: /*
! 1192: * Keyboard inputdevice functions
! 1193: */
! 1194: static unsigned int get_kb_num (void)
! 1195: {
! 1196: /* SDL supports only one keyboard */
! 1197: return 1;
! 1198: }
1.1 root 1199:
1.1.1.4 ! root 1200: static const char *get_kb_name (unsigned int kb)
1.1 root 1201: {
1.1.1.4 ! root 1202: return "Default keyboard";
! 1203: }
! 1204:
! 1205: static unsigned int get_kb_widget_num (unsigned int kb)
! 1206: {
! 1207: return 255; // fix me
! 1208: }
! 1209:
! 1210: static int get_kb_widget_first (unsigned int kb, int type)
! 1211: {
! 1212: return 0;
! 1213: }
! 1214:
! 1215: static int get_kb_widget_type (unsigned int kb, unsigned int num, char *name, uae_u32 *code)
! 1216: {
! 1217: // fix me
! 1218: *code = num;
! 1219: return IDEV_WIDGET_KEY;
! 1220: }
! 1221:
! 1222: static int init_kb (void)
! 1223: {
! 1224: struct uae_input_device_kbr_default *keymap = 0;
! 1225:
! 1226: /* See if we support raw keys on this platform */
! 1227: if ((keymap = get_default_raw_keymap (get_sdlgfx_type ())) != 0) {
! 1228: inputdevice_setkeytranslation (keymap);
! 1229: have_rawkeys = 1;
1.1 root 1230: }
1.1.1.4 ! root 1231: switch_keymaps ();
! 1232:
! 1233: return 1;
! 1234: }
! 1235:
! 1236: static void close_kb (void)
! 1237: {
! 1238: }
! 1239:
! 1240: static int keyhack (int scancode, int pressed, int num)
! 1241: {
! 1242: return scancode;
1.1 root 1243: }
1244:
1.1.1.4 ! root 1245: static void read_kb (void)
1.1 root 1246: {
1247: }
1248:
1.1.1.4 ! root 1249: static int acquire_kb (unsigned int num, int flags)
1.1 root 1250: {
1.1.1.4 ! root 1251: return 1;
1.1 root 1252: }
1253:
1.1.1.4 ! root 1254: static void unacquire_kb (unsigned int num)
! 1255: {
! 1256: }
! 1257:
! 1258: struct inputdevice_functions inputdevicefunc_keyboard =
! 1259: {
! 1260: init_kb,
! 1261: close_kb,
! 1262: acquire_kb,
! 1263: unacquire_kb,
! 1264: read_kb,
! 1265: get_kb_num,
! 1266: get_kb_name,
! 1267: get_kb_widget_num,
! 1268: get_kb_widget_type,
! 1269: get_kb_widget_first
! 1270: };
! 1271:
! 1272: //static int capslockstate;
! 1273:
! 1274: int getcapslockstate (void)
! 1275: {
! 1276: // TODO
! 1277: // return capslockstate;
! 1278: return 0;
! 1279: }
! 1280: void setcapslockstate (int state)
! 1281: {
! 1282: // TODO
! 1283: // capslockstate = state;
! 1284: }
! 1285:
! 1286:
! 1287: /*
! 1288: * Default inputdevice config for SDL mouse
! 1289: */
! 1290: void input_get_default_mouse (struct uae_input_device *uid)
! 1291: {
! 1292: /* SDL supports only one mouse */
! 1293: uid[0].eventid[ID_AXIS_OFFSET + 0][0] = INPUTEVENT_MOUSE1_HORIZ;
! 1294: uid[0].eventid[ID_AXIS_OFFSET + 1][0] = INPUTEVENT_MOUSE1_VERT;
! 1295: uid[0].eventid[ID_AXIS_OFFSET + 2][0] = INPUTEVENT_MOUSE1_WHEEL;
! 1296: uid[0].eventid[ID_BUTTON_OFFSET + 0][0] = INPUTEVENT_JOY1_FIRE_BUTTON;
! 1297: uid[0].eventid[ID_BUTTON_OFFSET + 1][0] = INPUTEVENT_JOY1_2ND_BUTTON;
! 1298: uid[0].eventid[ID_BUTTON_OFFSET + 2][0] = INPUTEVENT_JOY1_3RD_BUTTON;
! 1299: uid[0].enabled = 1;
! 1300: }
! 1301:
! 1302: /*
! 1303: * Handle gfx specific cfgfile options
! 1304: */
! 1305:
1.1 root 1306: void target_save_options (FILE *f, struct uae_prefs *p)
1307: {
1308: }
1309:
1310: int target_parse_option (struct uae_prefs *p, char *option, char *value)
1311: {
1312: return 0;
1313: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.