Annotation of uae/src/svga.c, revision 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.