Annotation of uae/src/svga.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.