|
|
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 <stdlib.h> ! 10: #include <string.h> ! 11: #include <stdio.h> ! 12: #include <assert.h> ! 13: #include <signal.h> ! 14: #include <unistd.h> ! 15: #include <vga.h> ! 16: #include <vgamouse.h> ! 17: #include <vgakeyboard.h> ! 18: ! 19: #include "config.h" ! 20: #include "amiga.h" ! 21: #include "options.h" ! 22: #include "memory.h" ! 23: #include "custom.h" ! 24: #include "newcpu.h" ! 25: #include "keyboard.h" ! 26: #include "xwin.h" ! 27: #include "keybuf.h" ! 28: ! 29: #ifndef LINUX_SVGALIB ! 30: #error Compiling svga.c, but LINUX_SVGALIB unset. Re-edit "config.h". ! 31: #endif ! 32: ! 33: /* Why doesn't SVGAlib define these !??? */ ! 34: ! 35: #define SCANCODE_0 11 ! 36: #define SCANCODE_1 2 ! 37: #define SCANCODE_2 3 ! 38: #define SCANCODE_3 4 ! 39: #define SCANCODE_4 5 ! 40: #define SCANCODE_5 6 ! 41: #define SCANCODE_6 7 ! 42: #define SCANCODE_7 8 ! 43: #define SCANCODE_8 9 ! 44: #define SCANCODE_9 10 ! 45: ! 46: #define SCANCODE_LEFTSHIFT 42 ! 47: #define SCANCODE_RIGHTSHIFT 54 ! 48: #define SCANCODE_TAB 15 ! 49: ! 50: #define SCANCODE_F11 87 ! 51: #define SCANCODE_F12 88 ! 52: #define SCANCODE_NEXT 81 ! 53: #define SCANCODE_PRIOR 73 ! 54: #define SCANCODE_BS 14 ! 55: /* ! 56: #define SCANCODE_asciicircum 1 ! 57: */ ! 58: #define SCANCODE_bracketleft 26 ! 59: #define SCANCODE_bracketright 27 ! 60: #define SCANCODE_comma 51 ! 61: #define SCANCODE_period 52 ! 62: #define SCANCODE_slash 53 ! 63: #define SCANCODE_semicolon 39 ! 64: #define SCANCODE_grave 40 ! 65: #define SCANCODE_minus 12 ! 66: #define SCANCODE_equal 13 ! 67: #define SCANCODE_numbersign 41 ! 68: #define SCANCODE_ltgt 43 ! 69: #define SCANCODE_scrolllock 70 ! 70: ! 71: static char pixel_buffer[3200]; ! 72: char *xlinebuffer; ! 73: ! 74: long int xcolors[4096]; ! 75: ! 76: static int next_pos; ! 77: static bool next_double; ! 78: ! 79: void prepare_line(int y, bool need_double) ! 80: { ! 81: next_pos = y; ! 82: next_double = need_double; ! 83: xlinebuffer = pixel_buffer; ! 84: } ! 85: ! 86: void flush_line(void) ! 87: { ! 88: vga_drawscanline(next_pos, pixel_buffer); ! 89: if (next_double) ! 90: vga_drawscanline(next_pos+1, pixel_buffer); ! 91: } ! 92: ! 93: void flush_screen(void) ! 94: { ! 95: } ! 96: ! 97: static __inline__ unsigned long doMask(int p, int bits, int shift) ! 98: { ! 99: /* p is a value from 0 to 15 (Amiga color value) ! 100: * scale to 0..255, shift to align msb with mask, and apply mask */ ! 101: ! 102: unsigned long val = p * 0x11111111UL; ! 103: val >>= (32 - bits); ! 104: val <<= shift; ! 105: ! 106: return val; ! 107: } ! 108: ! 109: static void init_colors(void) ! 110: { ! 111: #ifdef SVGALIB_16BIT_SCREEN ! 112: int i; ! 113: for(i=0; i<4096; i++) { ! 114: int r = i >> 8; ! 115: int g = (i >> 4) & 0xF; ! 116: int b = i & 0xF; ! 117: xcolors[i] = (doMask(r, SVGALIB_R_WEIGHT, SVGALIB_G_WEIGHT + SVGALIB_B_WEIGHT) ! 118: | doMask(g, SVGALIB_G_WEIGHT, SVGALIB_B_WEIGHT) ! 119: | doMask(b, SVGALIB_B_WEIGHT, 0)); ! 120: } ! 121: #endif ! 122: #ifdef SVGALIB_8BIT_SCREEN ! 123: /* This is kind of kludgy... ! 124: * Try to allocate as many different colors as possible. */ ! 125: int step = 16, count = 0, col; ! 126: int allocated[4096]; ! 127: memset(allocated,0,sizeof allocated); ! 128: ! 129: while ((step/=2) > 0) { ! 130: int r, g, b; ! 131: for(r = 0; r < 16; r += step) { ! 132: for(g = 0; g < 16; g += step) { ! 133: for(b = 0; b < 16; b += step) { ! 134: int cnr = (r << 8) + (g << 4) + b; ! 135: if (++count == 256) ! 136: goto finished; ! 137: if (!allocated[cnr]) { ! 138: allocated[cnr] = true; ! 139: xcolors[cnr] = count-1; ! 140: vga_setpalette(count-1,(r*63+7)/15,(g*63+7)/15,(b*63+7)/15); ! 141: } ! 142: } ! 143: } ! 144: } ! 145: } ! 146: finished: ! 147: for(col = 0; col < 4096; col++) { ! 148: int cnr = col; ! 149: if (!allocated[cnr]) { ! 150: int r = cnr >> 8; ! 151: int g = (cnr >> 4) & 0xF; ! 152: int b = cnr & 0xF; ! 153: int maxd = 4096,best = 0; ! 154: int c2; ! 155: for(c2 = 0; c2 < 4096; c2++) ! 156: if (allocated[c2]) { ! 157: int r2 = c2 >> 8; ! 158: int g2 = (c2 >> 4) & 0xF; ! 159: int b2 = c2 & 0xF; ! 160: int dist = abs(r2-r)*2 + abs(g2-g)*3 + abs(b2-b); ! 161: if (dist < maxd) { ! 162: maxd = dist; ! 163: best = c2; ! 164: } ! 165: } ! 166: cnr = best; ! 167: } ! 168: xcolors[col] = xcolors[cnr]; ! 169: } ! 170: #endif ! 171: } ! 172: ! 173: bool buttonstate[3] = { false, false, false }; ! 174: int lastmx, lastmy; ! 175: bool newmousecounters = false; ! 176: ! 177: static bool keystate[256]; ! 178: ! 179: static int scancode2amiga(int scancode) ! 180: { ! 181: switch(scancode) { ! 182: case SCANCODE_A: return AK_A; ! 183: case SCANCODE_B: return AK_B; ! 184: case SCANCODE_C: return AK_C; ! 185: case SCANCODE_D: return AK_D; ! 186: case SCANCODE_E: return AK_E; ! 187: case SCANCODE_F: return AK_F; ! 188: case SCANCODE_G: return AK_G; ! 189: case SCANCODE_H: return AK_H; ! 190: case SCANCODE_I: return AK_I; ! 191: case SCANCODE_J: return AK_J; ! 192: case SCANCODE_K: return AK_K; ! 193: case SCANCODE_L: return AK_L; ! 194: case SCANCODE_M: return AK_M; ! 195: case SCANCODE_N: return AK_N; ! 196: case SCANCODE_O: return AK_O; ! 197: case SCANCODE_P: return AK_P; ! 198: case SCANCODE_Q: return AK_Q; ! 199: case SCANCODE_R: return AK_R; ! 200: case SCANCODE_S: return AK_S; ! 201: case SCANCODE_T: return AK_T; ! 202: case SCANCODE_U: return AK_U; ! 203: case SCANCODE_V: return AK_V; ! 204: case SCANCODE_W: return AK_W; ! 205: case SCANCODE_X: return AK_X; ! 206: case SCANCODE_Y: return AK_Y; ! 207: case SCANCODE_Z: return AK_Z; ! 208: ! 209: case SCANCODE_0: return AK_0; ! 210: case SCANCODE_1: return AK_1; ! 211: case SCANCODE_2: return AK_2; ! 212: case SCANCODE_3: return AK_3; ! 213: case SCANCODE_4: return AK_4; ! 214: case SCANCODE_5: return AK_5; ! 215: case SCANCODE_6: return AK_6; ! 216: case SCANCODE_7: return AK_7; ! 217: case SCANCODE_8: return AK_8; ! 218: case SCANCODE_9: return AK_9; ! 219: ! 220: case SCANCODE_KEYPAD0: return AK_NP0; ! 221: case SCANCODE_KEYPAD1: return AK_NP1; ! 222: case SCANCODE_KEYPAD2: return AK_NP2; ! 223: case SCANCODE_KEYPAD3: return AK_NP3; ! 224: case SCANCODE_KEYPAD4: return AK_NP4; ! 225: case SCANCODE_KEYPAD5: return AK_NP5; ! 226: case SCANCODE_KEYPAD6: return AK_NP6; ! 227: case SCANCODE_KEYPAD7: return AK_NP7; ! 228: case SCANCODE_KEYPAD8: return AK_NP8; ! 229: case SCANCODE_KEYPAD9: return AK_NP9; ! 230: ! 231: case SCANCODE_F1: return AK_F1; ! 232: case SCANCODE_F2: return AK_F2; ! 233: case SCANCODE_F3: return AK_F3; ! 234: case SCANCODE_F4: return AK_F4; ! 235: case SCANCODE_F5: return AK_F5; ! 236: case SCANCODE_F6: return AK_F6; ! 237: case SCANCODE_F7: return AK_F7; ! 238: case SCANCODE_F8: return AK_F8; ! 239: case SCANCODE_F9: return AK_F9; ! 240: case SCANCODE_F10: return AK_F10; ! 241: ! 242: case SCANCODE_BS: return AK_BS; ! 243: case SCANCODE_CONTROL: return AK_CTRL; ! 244: case SCANCODE_TAB: return AK_TAB; ! 245: case SCANCODE_LEFTALT: return AK_LALT; ! 246: case SCANCODE_RIGHTALT: return AK_RALT; ! 247: case SCANCODE_ENTER: return AK_RET; ! 248: case SCANCODE_SPACE: return AK_SPC; ! 249: case SCANCODE_LEFTSHIFT: return AK_LSH; ! 250: case SCANCODE_RIGHTSHIFT: return AK_RSH; ! 251: case SCANCODE_ESCAPE: return AK_ESC; ! 252: ! 253: case SCANCODE_CURSORBLOCKUP: return AK_UP; ! 254: case SCANCODE_CURSORBLOCKDOWN: return AK_DN; ! 255: case SCANCODE_CURSORBLOCKLEFT: return AK_LF; ! 256: case SCANCODE_CURSORBLOCKRIGHT: return AK_RT; ! 257: ! 258: case SCANCODE_F11: return AK_BACKSLASH; ! 259: /* ! 260: case SCANCODE_asciicircum: return AK_00; ! 261: */ ! 262: case SCANCODE_bracketleft: return AK_LBRACKET; ! 263: case SCANCODE_bracketright: return AK_RBRACKET; ! 264: case SCANCODE_comma: return AK_COMMA; ! 265: case SCANCODE_period: return AK_PERIOD; ! 266: case SCANCODE_slash: return AK_SLASH; ! 267: case SCANCODE_semicolon: return AK_SEMICOLON; ! 268: case SCANCODE_grave: return AK_QUOTE; ! 269: case SCANCODE_minus: return AK_MINUS; ! 270: case SCANCODE_equal: return AK_EQUAL; ! 271: ! 272: /* This one turns off screen updates. */ ! 273: case SCANCODE_scrolllock: return AK_inhibit; ! 274: ! 275: #if 0 /* No unique scancode for these yet. I need a Win95 keyboard :-( */ ! 276: case SCANCODE_NEXT: return AK_RAMI; /* PgUp mapped to right amiga */ ! 277: case SCANCODE_PRIOR: return AK_LAMI; /* PgDn mapped to left amiga */ ! 278: #endif ! 279: ! 280: /*#ifdef KBD_LANG_DE*/ ! 281: case SCANCODE_numbersign: return AK_NUMBERSIGN; ! 282: case SCANCODE_ltgt: return AK_LTGT; ! 283: /*#endif*/ ! 284: } ! 285: return -1; ! 286: } ! 287: ! 288: static void my_kbd_handler(int scancode, int newstate) ! 289: { ! 290: int akey = scancode2amiga(scancode); ! 291: ! 292: assert(scancode >= 0 && scancode < 0x100); ! 293: if (scancode == SCANCODE_F12) ! 294: specialflags |= SPCFLAG_BRK; ! 295: if (keystate[scancode] == newstate) ! 296: return; ! 297: keystate[scancode] = newstate; ! 298: ! 299: if (akey == -1) ! 300: return; ! 301: ! 302: if (newstate == KEY_EVENTPRESS) { ! 303: if (akey == AK_inhibit) ! 304: inhibit_frame ^= 1; ! 305: else ! 306: record_key (akey << 1); ! 307: } else ! 308: record_key ((akey << 1) | 1); ! 309: ! 310: /* "Affengriff" */ ! 311: if(keystate[AK_CTRL] && keystate[AK_LAMI] && keystate[AK_RAMI]) ! 312: MC68000_reset(); ! 313: } ! 314: ! 315: void graphics_init(void) ! 316: { ! 317: int i; ! 318: ! 319: vga_init(); ! 320: vga_setmousesupport(1); ! 321: mouse_init("/dev/mouse",vga_getmousetype(),10); ! 322: #ifdef SVGALIB_8BIT_SCREEN ! 323: vga_setmode(SVGALIB_MODE_8); ! 324: #endif ! 325: #ifdef SVGALIB_16BIT_SCREEN ! 326: vga_setmode(SVGALIB_MODE_16); ! 327: #endif ! 328: if (keyboard_init() != 0) ! 329: abort(); ! 330: keyboard_seteventhandler(my_kbd_handler); ! 331: ! 332: init_colors(); ! 333: ! 334: buttonstate[0] = buttonstate[1] = buttonstate[2] = false; ! 335: for(i = 0; i < 256; i++) ! 336: keystate[i] = false; ! 337: ! 338: lastmx = lastmy = 0; newmousecounters = false; ! 339: ! 340: mouse_setxrange(-1000,1000); ! 341: mouse_setyrange(-1000,1000); ! 342: mouse_setposition(0,0); ! 343: } ! 344: ! 345: void graphics_leave(void) ! 346: { ! 347: sleep(1); /* Maybe this will fix the "screen full of garbage" problem */ ! 348: vga_setmode(TEXT); ! 349: keyboard_close(); ! 350: } ! 351: ! 352: void handle_events(void) ! 353: { ! 354: int button = mouse_getbutton(); ! 355: ! 356: keyboard_update(); ! 357: mouse_update(); ! 358: lastmx += mouse_getx(); ! 359: lastmy += mouse_gety(); ! 360: mouse_setposition(0,0); ! 361: ! 362: buttonstate[0] = button & 4; ! 363: buttonstate[1] = button & 2; ! 364: buttonstate[2] = button & 1; ! 365: } ! 366: ! 367: bool debuggable(void) ! 368: { ! 369: return false; ! 370: } ! 371: ! 372: bool needmousehack(void) ! 373: { ! 374: return false; ! 375: } ! 376: ! 377: void LED(int on) ! 378: { ! 379: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.