|
|
1.1 ! root 1: /* ! 2: * UAE - The Un*x Amiga Emulator ! 3: * ! 4: * SVGAlib interface. ! 5: * ! 6: * (c) 1995 Bernd Schmidt ! 7: */ ! 8: ! 9: #include "sysconfig.h" ! 10: #include "sysdeps.h" ! 11: ! 12: #include <assert.h> ! 13: #include <ctype.h> ! 14: #include <signal.h> ! 15: #include <vga.h> ! 16: #include <vgamouse.h> ! 17: #include <vgakeyboard.h> ! 18: ! 19: #include "config.h" ! 20: #include "options.h" ! 21: #include "memory.h" ! 22: #include "custom.h" ! 23: #include "newcpu.h" ! 24: #include "keyboard.h" ! 25: #include "xwin.h" ! 26: #include "keybuf.h" ! 27: #include "gui.h" ! 28: ! 29: #define SCODE_CURSORBLOCKUP 103 /* Cursor key block. */ ! 30: #define SCODE_CURSORBLOCKLEFT 105 ! 31: #define SCODE_CURSORBLOCKRIGHT 106 ! 32: #define SCODE_CURSORBLOCKDOWN 108 ! 33: ! 34: #define SCODE_INSERT 110 ! 35: #define SCODE_HOME 102 ! 36: #define SCODE_PGUP 104 ! 37: #define SCODE_DELETE 111 ! 38: #define SCODE_END 107 ! 39: #define SCODE_PGDN 109 ! 40: ! 41: #define SCODE_KEYPAD0 82 ! 42: #define SCODE_KEYPAD1 79 ! 43: #define SCODE_KEYPAD2 80 ! 44: #define SCODE_KEYPAD3 81 ! 45: #define SCODE_KEYPAD4 75 ! 46: #define SCODE_KEYPAD5 76 ! 47: #define SCODE_KEYPAD6 77 ! 48: #define SCODE_KEYPAD7 71 ! 49: #define SCODE_KEYPAD8 72 ! 50: #define SCODE_KEYPAD9 73 ! 51: #define SCODE_KEYPADENTER 96 ! 52: #define SCODE_KEYPADPLUS 78 ! 53: #define SCODE_KEYPADMINUS 74 ! 54: ! 55: #define SCODE_Q 16 ! 56: #define SCODE_W 17 ! 57: #define SCODE_E 18 ! 58: #define SCODE_R 19 ! 59: #define SCODE_T 20 ! 60: #define SCODE_Y 21 ! 61: #define SCODE_U 22 ! 62: #define SCODE_I 23 ! 63: #define SCODE_O 24 ! 64: #define SCODE_P 25 ! 65: ! 66: #define SCODE_A 30 ! 67: #define SCODE_S 31 ! 68: #define SCODE_D 32 ! 69: #define SCODE_F 33 ! 70: #define SCODE_G 34 ! 71: #define SCODE_H 35 ! 72: #define SCODE_J 36 ! 73: #define SCODE_K 37 ! 74: #define SCODE_L 38 ! 75: ! 76: #define SCODE_Z 44 ! 77: #define SCODE_X 45 ! 78: #define SCODE_C 46 ! 79: #define SCODE_V 47 ! 80: #define SCODE_B 48 ! 81: #define SCODE_N 49 ! 82: #define SCODE_M 50 ! 83: ! 84: #define SCODE_ESCAPE 1 ! 85: #define SCODE_ENTER 28 ! 86: #define SCODE_RIGHTCONTROL 97 ! 87: #define SCODE_CONTROL 97 ! 88: #define SCODE_RIGHTALT 100 ! 89: #define SCODE_LEFTCONTROL 29 ! 90: #define SCODE_LEFTALT 56 ! 91: #define SCODE_SPACE 57 ! 92: ! 93: #define SCODE_F1 59 ! 94: #define SCODE_F2 60 ! 95: #define SCODE_F3 61 ! 96: #define SCODE_F4 62 ! 97: #define SCODE_F5 63 ! 98: #define SCODE_F6 64 ! 99: #define SCODE_F7 65 ! 100: #define SCODE_F8 66 ! 101: #define SCODE_F9 67 ! 102: #define SCODE_F10 68 ! 103: ! 104: #define SCODE_0 11 ! 105: #define SCODE_1 2 ! 106: #define SCODE_2 3 ! 107: #define SCODE_3 4 ! 108: #define SCODE_4 5 ! 109: #define SCODE_5 6 ! 110: #define SCODE_6 7 ! 111: #define SCODE_7 8 ! 112: #define SCODE_8 9 ! 113: #define SCODE_9 10 ! 114: ! 115: #define SCODE_LEFTSHIFT 42 ! 116: #define SCODE_RIGHTSHIFT 54 ! 117: #define SCODE_TAB 15 ! 118: ! 119: #define SCODE_F11 87 ! 120: #define SCODE_F12 88 ! 121: #define SCODE_NEXT 81 ! 122: #define SCODE_PRIOR 73 ! 123: #define SCODE_BS 14 ! 124: /* ! 125: #define SCODE_asciicircum 1 ! 126: */ ! 127: #define SCODE_bracketleft 26 ! 128: #define SCODE_bracketright 27 ! 129: #define SCODE_comma 51 ! 130: #define SCODE_period 52 ! 131: #define SCODE_slash 53 ! 132: #define SCODE_semicolon 39 ! 133: #define SCODE_grave 40 ! 134: #define SCODE_minus 12 ! 135: #define SCODE_equal 13 ! 136: #define SCODE_numbersign 43 ! 137: #define SCODE_ltgt 86 ! 138: #define SCODE_scrolllock 70 ! 139: ! 140: #define SCODE_LWIN95 125 ! 141: #define SCODE_RWIN95 126 ! 142: #define SCODE_MWIN95 127 ! 143: ! 144: void setup_brkhandler(void) ! 145: { ! 146: } ! 147: ! 148: static int vsize, bitdepth, bit_unit, using_linear; ! 149: static vga_modeinfo modeinfo; ! 150: static char *linear_mem = NULL; ! 151: static int need_dither; ! 152: static int x_size = 0, vidmode_linewidth; ! 153: ! 154: static UBYTE dither_buf[1000]; /* I hate having to think about array bounds */ ! 155: ! 156: xcolnr xcolors[4096]; ! 157: ! 158: struct vidbuf_description gfxvidinfo; ! 159: ! 160: static int x_size_table[MAX_SCREEN_MODES+1] = { 320, 320, 320, 640, 800 }; ! 161: ! 162: static int vga_mode_table[MAX_SCREEN_MODES+1][MAX_COLOR_MODES+1] = ! 163: { { G320x200x256, G320x200x32K, G320x200x64K, G320x200x256, G320x200x16, G320x200x16M32 }, ! 164: { G320x240x256, -1, -1, G320x240x256, -1, -1 }, ! 165: { G320x400x256, -1, -1, G320x400x256, -1, -1 }, ! 166: { G640x480x256, G640x480x32K, G640x480x64K, G640x480x256, G640x480x16, G640x480x16M32 }, ! 167: { G800x600x256, G800x600x32K, G800x600x64K, G800x600x256, G800x600x16, G800x600x16M32 } }; ! 168: ! 169: static int mode_bitdepth[MAX_COLOR_MODES+1][3] = ! 170: { { 8, 8, 0 }, { 15, 16, 0 }, { 16, 16, 0 }, { 8, 8, 1 }, { 4, 8, 1 }, { 24, 32, 0 } }; ! 171: ! 172: void flush_line(int y) ! 173: { ! 174: int target_y = y; ! 175: ! 176: if (screen_res < 2) ! 177: target_y -= 8; ! 178: if (linear_mem == NULL) { ! 179: char *addr = gfxvidinfo.bufmem + y*gfxvidinfo.rowbytes; ! 180: if (target_y < modeinfo.height && target_y >= 0) { ! 181: if (need_dither) { ! 182: DitherLine(dither_buf, (UWORD *)addr, 0, y, x_size, bit_unit); ! 183: addr = dither_buf; ! 184: } ! 185: vga_drawscanline(target_y, addr); ! 186: } ! 187: } else { ! 188: if (need_dither && target_y >= 0) { ! 189: char *addr = gfxvidinfo.bufmem + y*gfxvidinfo.rowbytes; ! 190: DitherLine(linear_mem + vidmode_linewidth * target_y, (UWORD *)addr, 0, y, x_size, bit_unit); ! 191: } ! 192: } ! 193: } ! 194: ! 195: void flush_block(int a, int b) ! 196: { ! 197: abort(); ! 198: } ! 199: ! 200: void flush_screen(int a, int b) ! 201: { ! 202: } ! 203: ! 204: void calc_adjustment(void) ! 205: { ! 206: switch (screen_res) { ! 207: case 0: case 1: case 2: /* LoRes, 320xfoo */ ! 208: gfxvidinfo.x_adjust = prev_max_diwstop - 320; ! 209: break; ! 210: ! 211: case 3: /* 640xbar */ ! 212: gfxvidinfo.x_adjust = prev_max_diwstop - 640; ! 213: break; ! 214: default: ! 215: gfxvidinfo.x_adjust = 0; ! 216: break; ! 217: } ! 218: } ! 219: ! 220: static int colors_allocated; ! 221: ! 222: static int get_color(int r, int g, int b, xcolnr *cnp) ! 223: { ! 224: if (colors_allocated == 256) ! 225: return -1; ! 226: *cnp = colors_allocated; ! 227: vga_setpalette(colors_allocated, doMask(r, 6, 0), doMask(g, 6, 0), doMask(b, 6, 0)); ! 228: colors_allocated++; ! 229: return 1; ! 230: } ! 231: ! 232: static void init_colors(void) ! 233: { ! 234: if (need_dither) { ! 235: setup_dither(bitdepth, get_color); ! 236: } else { ! 237: int rw = 5, gw = 5, bw = 5; ! 238: colors_allocated = 0; ! 239: if (color_mode == 2) gw = 6; ! 240: ! 241: switch (gfxvidinfo.pixbytes) { ! 242: case 4: ! 243: alloc_colors64k(8, 8, 8, 16, 8, 0); ! 244: break; ! 245: case 2: ! 246: alloc_colors64k(rw, gw, bw, gw+bw, bw, 0); ! 247: break; ! 248: case 1: ! 249: alloc_colors256(get_color); ! 250: break; ! 251: default: ! 252: abort(); ! 253: } ! 254: } ! 255: } ! 256: ! 257: int buttonstate[3] = { 0, 0, 0 }; ! 258: int lastmx, lastmy; ! 259: int newmousecounters = 0; ! 260: ! 261: static int keystate[256]; ! 262: ! 263: static int scancode2amiga(int scancode) ! 264: { ! 265: switch(scancode) { ! 266: case SCODE_A: return AK_A; ! 267: case SCODE_B: return AK_B; ! 268: case SCODE_C: return AK_C; ! 269: case SCODE_D: return AK_D; ! 270: case SCODE_E: return AK_E; ! 271: case SCODE_F: return AK_F; ! 272: case SCODE_G: return AK_G; ! 273: case SCODE_H: return AK_H; ! 274: case SCODE_I: return AK_I; ! 275: case SCODE_J: return AK_J; ! 276: case SCODE_K: return AK_K; ! 277: case SCODE_L: return AK_L; ! 278: case SCODE_M: return AK_M; ! 279: case SCODE_N: return AK_N; ! 280: case SCODE_O: return AK_O; ! 281: case SCODE_P: return AK_P; ! 282: case SCODE_Q: return AK_Q; ! 283: case SCODE_R: return AK_R; ! 284: case SCODE_S: return AK_S; ! 285: case SCODE_T: return AK_T; ! 286: case SCODE_U: return AK_U; ! 287: case SCODE_V: return AK_V; ! 288: case SCODE_W: return AK_W; ! 289: case SCODE_X: return AK_X; ! 290: case SCODE_Y: return AK_Y; ! 291: case SCODE_Z: return AK_Z; ! 292: ! 293: case SCODE_0: return AK_0; ! 294: case SCODE_1: return AK_1; ! 295: case SCODE_2: return AK_2; ! 296: case SCODE_3: return AK_3; ! 297: case SCODE_4: return AK_4; ! 298: case SCODE_5: return AK_5; ! 299: case SCODE_6: return AK_6; ! 300: case SCODE_7: return AK_7; ! 301: case SCODE_8: return AK_8; ! 302: case SCODE_9: return AK_9; ! 303: ! 304: case SCODE_KEYPAD0: return AK_NP0; ! 305: case SCODE_KEYPAD1: return AK_NP1; ! 306: case SCODE_KEYPAD2: return AK_NP2; ! 307: case SCODE_KEYPAD3: return AK_NP3; ! 308: case SCODE_KEYPAD4: return AK_NP4; ! 309: case SCODE_KEYPAD5: return AK_NP5; ! 310: case SCODE_KEYPAD6: return AK_NP6; ! 311: case SCODE_KEYPAD7: return AK_NP7; ! 312: case SCODE_KEYPAD8: return AK_NP8; ! 313: case SCODE_KEYPAD9: return AK_NP9; ! 314: ! 315: case SCODE_F1: return AK_F1; ! 316: case SCODE_F2: return AK_F2; ! 317: case SCODE_F3: return AK_F3; ! 318: case SCODE_F4: return AK_F4; ! 319: case SCODE_F5: return AK_F5; ! 320: case SCODE_F6: return AK_F6; ! 321: case SCODE_F7: return AK_F7; ! 322: case SCODE_F8: return AK_F8; ! 323: case SCODE_F9: return AK_F9; ! 324: case SCODE_F10: return AK_F10; ! 325: ! 326: case SCODE_BS: return AK_BS; ! 327: case SCODE_LEFTCONTROL: return AK_CTRL; ! 328: case SCODE_RIGHTCONTROL: return AK_CTRL; ! 329: case SCODE_TAB: return AK_TAB; ! 330: case SCODE_LEFTALT: return AK_LALT; ! 331: case SCODE_RIGHTALT: return AK_RALT; ! 332: case SCODE_ENTER: return AK_RET; ! 333: case SCODE_SPACE: return AK_SPC; ! 334: case SCODE_LEFTSHIFT: return AK_LSH; ! 335: case SCODE_RIGHTSHIFT: return AK_RSH; ! 336: case SCODE_ESCAPE: return AK_ESC; ! 337: ! 338: case SCODE_INSERT: ! 339: case SCODE_END: ! 340: case SCODE_HOME: break; ! 341: ! 342: case SCODE_DELETE: return AK_DEL; ! 343: case SCODE_CURSORBLOCKUP: return AK_UP; ! 344: case SCODE_CURSORBLOCKDOWN: return AK_DN; ! 345: case SCODE_CURSORBLOCKLEFT: return AK_LF; ! 346: case SCODE_CURSORBLOCKRIGHT: return AK_RT; ! 347: ! 348: case SCODE_F11: return AK_BACKSLASH; ! 349: /* ! 350: case SCODE_asciicircum: return AK_00; ! 351: */ ! 352: case SCODE_bracketleft: return AK_LBRACKET; ! 353: case SCODE_bracketright: return AK_RBRACKET; ! 354: case SCODE_comma: return AK_COMMA; ! 355: case SCODE_period: return AK_PERIOD; ! 356: case SCODE_slash: return AK_SLASH; ! 357: case SCODE_semicolon: return AK_SEMICOLON; ! 358: case SCODE_grave: return AK_QUOTE; ! 359: case SCODE_minus: return AK_MINUS; ! 360: case SCODE_equal: return AK_EQUAL; ! 361: ! 362: /* This one turns off screen updates. */ ! 363: case SCODE_scrolllock: return AK_inhibit; ! 364: ! 365: case SCODE_PGUP: case SCODE_RWIN95: return AK_RAMI; ! 366: case SCODE_PGDN: case SCODE_LWIN95: return AK_LAMI; ! 367: ! 368: /*#ifdef KBD_LANG_DE*/ ! 369: case SCODE_numbersign: return AK_NUMBERSIGN; ! 370: case SCODE_ltgt: return AK_LTGT; ! 371: /*#endif*/ ! 372: } ! 373: return -1; ! 374: } ! 375: ! 376: static void my_kbd_handler(int scancode, int newstate) ! 377: { ! 378: int akey = scancode2amiga(scancode); ! 379: ! 380: assert(scancode >= 0 && scancode < 0x100); ! 381: if (scancode == SCODE_F12) { ! 382: regs.spcflags |= SPCFLAG_BRK; ! 383: quit_program = 1; ! 384: } ! 385: if (keystate[scancode] == newstate) ! 386: return; ! 387: keystate[scancode] = newstate; ! 388: ! 389: if (akey == -1) { ! 390: return; ! 391: } ! 392: ! 393: if (newstate == KEY_EVENTPRESS) { ! 394: if (akey == AK_inhibit) ! 395: inhibit_frame ^= 1; ! 396: else ! 397: record_key (akey << 1); ! 398: } else ! 399: record_key ((akey << 1) | 1); ! 400: ! 401: /* "Affengriff" */ ! 402: if(keystate[AK_CTRL] && keystate[AK_LAMI] && keystate[AK_RAMI]) ! 403: m68k_reset(); ! 404: } ! 405: ! 406: int graphics_init(void) ! 407: { ! 408: int i; ! 409: int vgamode; ! 410: ! 411: need_dither = 0; ! 412: using_linear = 0; ! 413: ! 414: if (screen_res < 3) ! 415: correct_aspect = 0; ! 416: ! 417: vgamode = vga_mode_table[screen_res][color_mode]; ! 418: if (vgamode == -1) { ! 419: fprintf(stderr, "Sorry, this combination of color and video mode is not supported.\n"); ! 420: return 0; ! 421: } ! 422: ! 423: bitdepth = mode_bitdepth[color_mode][0]; ! 424: bit_unit = mode_bitdepth[color_mode][1]; ! 425: need_dither = mode_bitdepth[color_mode][2]; ! 426: x_size = x_size_table[screen_res]; ! 427: ! 428: vga_init(); ! 429: modeinfo = *vga_getmodeinfo (vgamode); ! 430: ! 431: vidmode_linewidth = modeinfo.linewidth; ! 432: gfxvidinfo.pixbytes = modeinfo.bytesperpixel; ! 433: if (!need_dither) { ! 434: if (modeinfo.bytesperpixel == 0) { ! 435: printf("Got a bogus value from SVGAlib... %s.\n", ! 436: screen_res == 1 || screen_res == 2 ? "trying to fix it" : "giving up"); ! 437: if (screen_res != 1 && screen_res != 2) ! 438: return 0; ! 439: gfxvidinfo.pixbytes = 1; ! 440: } ! 441: } else { ! 442: gfxvidinfo.pixbytes = 2; ! 443: } ! 444: ! 445: if (vga_setmode(vgamode) < 0) { ! 446: sleep(1); ! 447: vga_setmode(TEXT); ! 448: fprintf(stderr, "SVGAlib doesn't like my video mode. Giving up.\n"); ! 449: return 0; ! 450: } ! 451: ! 452: if ((modeinfo.flags & CAPABLE_LINEAR) && !no_xhair) { ! 453: if (vga_setlinearaddressing() != -1) { ! 454: linear_mem = (char *)vga_getgraphmem(); ! 455: printf("Using linear addressing: %p.\n", linear_mem); ! 456: using_linear = !need_dither; ! 457: } ! 458: } ! 459: ! 460: vsize = correct_aspect ? 2*numscrlines : numscrlines; ! 461: gfxvidinfo.maxblocklines = 0; ! 462: ! 463: if (using_linear) { ! 464: gfxvidinfo.bufmem = linear_mem; ! 465: gfxvidinfo.rowbytes = modeinfo.linewidth; ! 466: } else { ! 467: gfxvidinfo.rowbytes = x_size * gfxvidinfo.pixbytes; ! 468: gfxvidinfo.bufmem = malloc(gfxvidinfo.rowbytes * vsize); ! 469: memset(gfxvidinfo.bufmem, 0, gfxvidinfo.rowbytes * vsize); ! 470: } ! 471: ! 472: gfxvidinfo.maxlinetoscr = x_size < 800 ? x_size : 0; ! 473: gfxvidinfo.x_adjust = 0; ! 474: gfxvidinfo.maxline = modeinfo.height; ! 475: ! 476: init_colors(); ! 477: vga_setmousesupport(1); ! 478: mouse_init("/dev/mouse",vga_getmousetype(),10); ! 479: if (keyboard_init() != 0) ! 480: abort(); ! 481: keyboard_seteventhandler(my_kbd_handler); ! 482: keyboard_translatekeys(DONT_CATCH_CTRLC); ! 483: ! 484: buttonstate[0] = buttonstate[1] = buttonstate[2] = 0; ! 485: for(i = 0; i < 256; i++) ! 486: keystate[i] = 0; ! 487: ! 488: lastmx = lastmy = 0; ! 489: newmousecounters = 0; ! 490: ! 491: mouse_setxrange(-1000,1000); ! 492: mouse_setyrange(-1000,1000); ! 493: mouse_setposition(0,0); ! 494: ! 495: return 1; ! 496: } ! 497: ! 498: void graphics_leave(void) ! 499: { ! 500: sleep(1); /* Maybe this will fix the "screen full of garbage" problem */ ! 501: vga_setmode(TEXT); ! 502: keyboard_close(); ! 503: dumpcustom(); ! 504: } ! 505: ! 506: void handle_events(void) ! 507: { ! 508: int button = mouse_getbutton(); ! 509: ! 510: keyboard_update(); ! 511: mouse_update(); ! 512: lastmx += mouse_getx(); ! 513: lastmy += mouse_gety(); ! 514: mouse_setposition(0,0); ! 515: ! 516: buttonstate[0] = button & 4; ! 517: buttonstate[1] = button & 2; ! 518: buttonstate[2] = button & 1; ! 519: } ! 520: ! 521: int debuggable(void) ! 522: { ! 523: return 0; ! 524: } ! 525: ! 526: int needmousehack(void) ! 527: { ! 528: return 0; ! 529: } ! 530: ! 531: void LED(int on) ! 532: { ! 533: } ! 534: ! 535: void target_specific_usage(void) ! 536: { ! 537: printf(" -S n : Sound emulation accuracy (n = 0, 1, 2 or 3)\n" ! 538: " For sound emulation, n = 2 is recommended\n"); ! 539: printf(" -b n : Use n bits for sound output (8 or 16)\n"); ! 540: printf(" -R n : Use n Hz to output sound. Common values are\n" ! 541: " 22050 Hz or 44100 Hz\n"); ! 542: printf(" -B n : Use a sound buffer of n bytes (use small\n" ! 543: " values on fast machines)\n"); ! 544: printf(" -x : Don't use SVGAlib linear framebuffer, even if available.\n"); ! 545: printf(" -p command : Use command to pipe printer output to.\n"); ! 546: printf(" -I device : Name of the used serial device (i.e. /dev/ttyS1\n"); ! 547: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.