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

1.1.1.3   root        1:  /*
1.1       root        2:   * UAE - The Un*x Amiga Emulator
1.1.1.3   root        3:   *
1.1       root        4:   * SVGAlib interface.
1.1.1.3   root        5:   *
1.1       root        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 "options.h"
1.1.1.10  root       20: #include "threaddep/thread.h"
1.1.1.3   root       21: #include "uae.h"
1.1       root       22: #include "memory.h"
                     23: #include "keyboard.h"
                     24: #include "xwin.h"
1.1.1.7   root       25: #include "custom.h"
                     26: #include "drawing.h"
1.1       root       27: #include "keybuf.h"
1.1.1.7   root       28: #include "newcpu.h"
1.1.1.3   root       29: #include "tui.h"
1.1       root       30: #include "gui.h"
1.1.1.3   root       31: #include "picasso96.h"
1.1       root       32: 
1.1.1.3   root       33: #define SCODE_CB_UP    103     /* Cursor key block. */
                     34: #define SCODE_CB_LEFT  105
                     35: #define SCODE_CB_RIGHT 106
                     36: #define SCODE_CB_DOWN  108
                     37: 
                     38: #define SCODE_INSERT   110
                     39: #define SCODE_HOME     102
                     40: #define SCODE_PGUP     104
                     41: #define SCODE_DELETE   111
                     42: #define SCODE_END      107
                     43: #define SCODE_PGDN     109
                     44: 
                     45: #define SCODE_PRTSCR   99
                     46: #define SCODE_SLOCK    70
                     47: #define SCODE_BREAK    119
                     48: 
                     49: #define SCODE_NUMLOCK  69
1.1       root       50: 
                     51: #define SCODE_KEYPAD0  82
                     52: #define SCODE_KEYPAD1  79
                     53: #define SCODE_KEYPAD2  80
                     54: #define SCODE_KEYPAD3  81
                     55: #define SCODE_KEYPAD4  75
                     56: #define SCODE_KEYPAD5  76
                     57: #define SCODE_KEYPAD6  77
                     58: #define SCODE_KEYPAD7  71
                     59: #define SCODE_KEYPAD8  72
                     60: #define SCODE_KEYPAD9  73
1.1.1.3   root       61: #define SCODE_KEYPADRET        96
                     62: #define SCODE_KEYPADADD        78
                     63: #define SCODE_KEYPADSUB        74
                     64: #define SCODE_KEYPADMUL        55
                     65: #define SCODE_KEYPADDIV        98
                     66: #define SCODE_KEYPADDOT 83
1.1       root       67: 
                     68: #define SCODE_Q                16
                     69: #define SCODE_W                17
                     70: #define SCODE_E                18
                     71: #define SCODE_R                19
                     72: #define SCODE_T                20
                     73: #define SCODE_Y                21
                     74: #define SCODE_U                22
                     75: #define SCODE_I                23
                     76: #define SCODE_O                24
                     77: #define SCODE_P                25
                     78: 
                     79: #define SCODE_A                30
                     80: #define SCODE_S                31
                     81: #define SCODE_D                32
                     82: #define SCODE_F                33
                     83: #define SCODE_G                34
                     84: #define SCODE_H                35
                     85: #define SCODE_J                36
                     86: #define SCODE_K                37
                     87: #define SCODE_L                38
                     88: 
                     89: #define SCODE_Z                44
                     90: #define SCODE_X                45
                     91: #define SCODE_C                46
                     92: #define SCODE_V                47
                     93: #define SCODE_B                48
                     94: #define SCODE_N                49
                     95: #define SCODE_M                50
                     96: 
1.1.1.3   root       97: #define SCODE_ESCAPE   1
                     98: #define SCODE_ENTER    28
                     99: #define SCODE_RCONTROL 97
1.1       root      100: #define SCODE_CONTROL  97
1.1.1.3   root      101: #define SCODE_RALT     100
                    102: #define SCODE_LCONTROL 29
                    103: #define SCODE_LALT     56
                    104: #define SCODE_SPACE    57
                    105: 
                    106: #define SCODE_F1       59
                    107: #define SCODE_F2       60
                    108: #define SCODE_F3       61
                    109: #define SCODE_F4       62
                    110: #define SCODE_F5       63
                    111: #define SCODE_F6       64
                    112: #define SCODE_F7       65
                    113: #define SCODE_F8       66
                    114: #define SCODE_F9       67
                    115: #define SCODE_F10      68
                    116: #define SCODE_F11      87
                    117: #define SCODE_F12      88
                    118: 
                    119: #define SCODE_0                11
                    120: #define SCODE_1                2
                    121: #define SCODE_2                3
                    122: #define SCODE_3                4
                    123: #define SCODE_4                5
                    124: #define SCODE_5                6
                    125: #define SCODE_6                7
                    126: #define SCODE_7                8
                    127: #define SCODE_8                9
                    128: #define SCODE_9        10
                    129: 
                    130: #define SCODE_LSHIFT   42
                    131: #define SCODE_RSHIFT   54
                    132: #define SCODE_TAB      15
                    133: 
                    134: #define SCODE_BS       14
                    135: 
                    136: #define SCODE_asciicircum      41
                    137: 
                    138: #define SCODE_bracketleft      26
                    139: #define SCODE_bracketright     27
                    140: #define SCODE_comma    51
                    141: #define SCODE_period   52
                    142: #define SCODE_slash    53
                    143: #define SCODE_semicolon        39
                    144: #define SCODE_grave    40
                    145: #define SCODE_minus    12
                    146: #define SCODE_equal    13
                    147: #define SCODE_numbersign       43
                    148: #define SCODE_ltgt     86
1.1       root      149: 
                    150: #define SCODE_LWIN95 125
                    151: #define SCODE_RWIN95 126
                    152: #define SCODE_MWIN95 127
                    153: 
                    154: void setup_brkhandler(void)
                    155: {
                    156: }
                    157: 
1.1.1.3   root      158: static int bitdepth, bit_unit, using_linear, vgamode, current_vgamode, gui_requested;
1.1       root      159: static vga_modeinfo modeinfo;
                    160: static char *linear_mem = NULL;
                    161: static int need_dither;
1.1.1.3   root      162: static int screen_is_picasso;
                    163: static int picasso_vgamode = -1;
                    164: static char picasso_invalid_lines[1200];
1.1       root      165: 
1.1.1.3   root      166: static uae_u8 dither_buf[1000]; /* I hate having to think about array bounds */
1.1       root      167: 
1.1.1.3   root      168: #define MAX_SCREEN_MODES 9
1.1       root      169: 
1.1.1.3   root      170: static int x_size_table[MAX_SCREEN_MODES] = { 320, 320, 320, 640, 640, 800, 1024, 1152, 1280 };
                    171: static int y_size_table[MAX_SCREEN_MODES] = { 200, 240, 400, 350, 480, 600, 768, 864, 1024 };
1.1       root      172: 
1.1.1.2   root      173: static int vga_mode_table[MAX_SCREEN_MODES][MAX_COLOR_MODES+1] =
1.1       root      174:  { { G320x200x256, G320x200x32K, G320x200x64K, G320x200x256, G320x200x16, G320x200x16M32 },
                    175:    { G320x240x256, -1, -1, G320x240x256, -1, -1 },
                    176:    { G320x400x256, -1, -1, G320x400x256, -1, -1 },
1.1.1.2   root      177:    { -1, -1, -1, -1, G640x350x16, -1 },
1.1       root      178:    { G640x480x256, G640x480x32K, G640x480x64K, G640x480x256, G640x480x16, G640x480x16M32 },
1.1.1.3   root      179:    { G800x600x256, G800x600x32K, G800x600x64K, G800x600x256, G800x600x16, G800x600x16M32 },
                    180:    { G1024x768x256, G1024x768x32K, G1024x768x64K, G1024x768x256, G1024x768x16, G1024x768x16M32 },
                    181:    { G1152x864x256, G1152x864x32K, G1152x864x64K, G1152x864x256, G1152x864x16, G1152x864x16M32 },
                    182:    { G1280x1024x256, G1280x1024x32K, G1280x1024x64K, G1280x1024x256, G1280x1024x16, G1280x1024x16M32 }
                    183:  };
1.1       root      184: 
                    185: static int mode_bitdepth[MAX_COLOR_MODES+1][3] =
                    186:   { { 8, 8, 0 }, { 15, 16, 0 }, { 16, 16, 0 }, { 8, 8, 1 }, { 4, 8, 1 }, { 24, 32, 0 } };
                    187: 
1.1.1.3   root      188: struct bstring *video_mode_menu = NULL;
                    189: 
1.1       root      190: void flush_line(int y)
                    191: {
                    192:     int target_y = y;
1.1.1.3   root      193:     char *addr;
                    194: 
                    195:     if (linear_mem != NULL && !need_dither)
                    196:        return;
                    197: 
                    198:     addr = gfxvidinfo.linemem;
                    199:     if (addr == NULL)
                    200:        addr = gfxvidinfo.bufmem + y*gfxvidinfo.rowbytes;
1.1       root      201: 
                    202:     if (linear_mem == NULL) {
                    203:        if (target_y < modeinfo.height && target_y >= 0) {
                    204:            if (need_dither) {
1.1.1.4   root      205:                DitherLine (dither_buf, (uae_u16 *)addr, 0, y, gfxvidinfo.width, bit_unit);
1.1       root      206:                addr = dither_buf;
1.1.1.3   root      207:            }
1.1       root      208:            vga_drawscanline(target_y, addr);
                    209:        }
                    210:     } else {
                    211:        if (need_dither && target_y >= 0) {
1.1.1.4   root      212:            DitherLine (linear_mem + modeinfo.linewidth * target_y, (uae_u16 *)addr, 0, y,
                    213:                        gfxvidinfo.width, bit_unit);
1.1       root      214:        }
                    215:     }
                    216: }
                    217: 
1.1.1.4   root      218: void flush_block (int a, int b)
1.1       root      219: {
                    220:     abort();
                    221: }
                    222: 
1.1.1.4   root      223: void flush_screen (int a, int b)
1.1       root      224: {
                    225: }
                    226: 
                    227: static int colors_allocated;
1.1.1.3   root      228: static long palette_entries[256][3];
                    229: 
                    230: static void restore_vga_colors (void)
                    231: {
                    232:     int i;
                    233:     if (gfxvidinfo.pixbytes != 1)
                    234:        return;
                    235:     for (i = 0; i < 256; i++)
                    236:        vga_setpalette (i, palette_entries[i][0], palette_entries[i][1], palette_entries[i][2]);
                    237: }
1.1       root      238: 
1.1.1.4   root      239: static int get_color (int r, int g, int b, xcolnr *cnp)
1.1       root      240: {
                    241:     if (colors_allocated == 256)
                    242:        return -1;
                    243:     *cnp = colors_allocated;
1.1.1.4   root      244:     palette_entries[colors_allocated][0] = doMask (r, 6, 0);
                    245:     palette_entries[colors_allocated][1] = doMask (g, 6, 0);
                    246:     palette_entries[colors_allocated][2] = doMask (b, 6, 0);
                    247:     vga_setpalette(colors_allocated, doMask (r, 6, 0), doMask (g, 6, 0), doMask (b, 6, 0));
1.1       root      248:     colors_allocated++;
                    249:     return 1;
                    250: }
                    251: 
1.1.1.4   root      252: static void init_colors (void)
1.1       root      253: {
1.1.1.3   root      254:     int i;
1.1       root      255:     if (need_dither) {
1.1.1.4   root      256:        setup_dither (bitdepth, get_color);
1.1       root      257:     } else {
                    258:        int rw = 5, gw = 5, bw = 5;
                    259:        colors_allocated = 0;
1.1.1.3   root      260:        if (currprefs.color_mode == 2) gw = 6;
1.1       root      261: 
                    262:        switch (gfxvidinfo.pixbytes) {
                    263:         case 4:
1.1.1.4   root      264:            alloc_colors64k (8, 8, 8, 16, 8, 0);
1.1       root      265:            break;
                    266:         case 2:
1.1.1.4   root      267:            alloc_colors64k (rw, gw, bw, gw+bw, bw, 0);
1.1       root      268:            break;
                    269:         case 1:
1.1.1.4   root      270:            alloc_colors256 (get_color);
1.1       root      271:            break;
                    272:         default:
                    273:            abort();
                    274:        }
                    275:     }
1.1.1.3   root      276:     switch (gfxvidinfo.pixbytes) {
                    277:      case 2:
                    278:        for (i = 0; i < 4096; i++)
                    279:            xcolors[i] = xcolors[i] * 0x00010001;
                    280:        gfxvidinfo.can_double = 1;
                    281:        break;
                    282:      case 1:
                    283:        for (i = 0; i < 4096; i++)
                    284:            xcolors[i] = xcolors[i] * 0x01010101;
                    285:        gfxvidinfo.can_double = 1;
                    286:        break;
                    287:      default:
                    288:        gfxvidinfo.can_double = 0;
                    289:        break;
                    290:     }
1.1       root      291: }
                    292: 
                    293: static int keystate[256];
                    294: 
1.1.1.4   root      295: static int scancode2amiga (int scancode)
1.1       root      296: {
1.1.1.4   root      297:     switch (scancode) {
1.1       root      298:      case SCODE_A: return AK_A;
                    299:      case SCODE_B: return AK_B;
                    300:      case SCODE_C: return AK_C;
                    301:      case SCODE_D: return AK_D;
                    302:      case SCODE_E: return AK_E;
                    303:      case SCODE_F: return AK_F;
                    304:      case SCODE_G: return AK_G;
                    305:      case SCODE_H: return AK_H;
                    306:      case SCODE_I: return AK_I;
                    307:      case SCODE_J: return AK_J;
                    308:      case SCODE_K: return AK_K;
                    309:      case SCODE_L: return AK_L;
                    310:      case SCODE_M: return AK_M;
                    311:      case SCODE_N: return AK_N;
                    312:      case SCODE_O: return AK_O;
                    313:      case SCODE_P: return AK_P;
                    314:      case SCODE_Q: return AK_Q;
                    315:      case SCODE_R: return AK_R;
                    316:      case SCODE_S: return AK_S;
                    317:      case SCODE_T: return AK_T;
                    318:      case SCODE_U: return AK_U;
                    319:      case SCODE_V: return AK_V;
                    320:      case SCODE_W: return AK_W;
                    321:      case SCODE_X: return AK_X;
                    322:      case SCODE_Y: return AK_Y;
                    323:      case SCODE_Z: return AK_Z;
1.1.1.3   root      324: 
1.1       root      325:      case SCODE_0: return AK_0;
                    326:      case SCODE_1: return AK_1;
                    327:      case SCODE_2: return AK_2;
                    328:      case SCODE_3: return AK_3;
                    329:      case SCODE_4: return AK_4;
                    330:      case SCODE_5: return AK_5;
                    331:      case SCODE_6: return AK_6;
                    332:      case SCODE_7: return AK_7;
                    333:      case SCODE_8: return AK_8;
                    334:      case SCODE_9: return AK_9;
1.1.1.3   root      335: 
1.1       root      336:      case SCODE_KEYPAD0: return AK_NP0;
                    337:      case SCODE_KEYPAD1: return AK_NP1;
                    338:      case SCODE_KEYPAD2: return AK_NP2;
                    339:      case SCODE_KEYPAD3: return AK_NP3;
                    340:      case SCODE_KEYPAD4: return AK_NP4;
                    341:      case SCODE_KEYPAD5: return AK_NP5;
                    342:      case SCODE_KEYPAD6: return AK_NP6;
                    343:      case SCODE_KEYPAD7: return AK_NP7;
                    344:      case SCODE_KEYPAD8: return AK_NP8;
                    345:      case SCODE_KEYPAD9: return AK_NP9;
1.1.1.3   root      346: 
                    347:      case SCODE_KEYPADADD: return AK_NPADD;
                    348:      case SCODE_KEYPADSUB: return AK_NPSUB;
                    349:      case SCODE_KEYPADMUL: return AK_NPMUL;
                    350:      case SCODE_KEYPADDIV: return AK_NPDIV;
                    351:      case SCODE_KEYPADRET: return AK_ENT;
                    352:      case SCODE_KEYPADDOT: return AK_NPDEL;
                    353: 
1.1       root      354:      case SCODE_F1: return AK_F1;
                    355:      case SCODE_F2: return AK_F2;
                    356:      case SCODE_F3: return AK_F3;
                    357:      case SCODE_F4: return AK_F4;
                    358:      case SCODE_F5: return AK_F5;
                    359:      case SCODE_F6: return AK_F6;
                    360:      case SCODE_F7: return AK_F7;
                    361:      case SCODE_F8: return AK_F8;
                    362:      case SCODE_F9: return AK_F9;
                    363:      case SCODE_F10: return AK_F10;
1.1.1.3   root      364: 
1.1       root      365:      case SCODE_BS: return AK_BS;
1.1.1.3   root      366:      case SCODE_LCONTROL: return AK_CTRL;
                    367:      case SCODE_RCONTROL: return AK_RCTRL;
1.1       root      368:      case SCODE_TAB: return AK_TAB;
1.1.1.3   root      369:      case SCODE_LALT: return AK_LALT;
                    370:      case SCODE_RALT: return AK_RALT;
1.1       root      371:      case SCODE_ENTER: return AK_RET;
                    372:      case SCODE_SPACE: return AK_SPC;
1.1.1.3   root      373:      case SCODE_LSHIFT: return AK_LSH;
                    374:      case SCODE_RSHIFT: return AK_RSH;
1.1       root      375:      case SCODE_ESCAPE: return AK_ESC;
1.1.1.3   root      376: 
                    377:      case SCODE_INSERT: return AK_HELP;
                    378:      case SCODE_END: return AK_NPRPAREN;
                    379:      case SCODE_HOME: return AK_NPLPAREN;
1.1       root      380: 
                    381:      case SCODE_DELETE: return AK_DEL;
1.1.1.3   root      382:      case SCODE_CB_UP: return AK_UP;
                    383:      case SCODE_CB_DOWN: return AK_DN;
                    384:      case SCODE_CB_LEFT: return AK_LF;
                    385:      case SCODE_CB_RIGHT: return AK_RT;
                    386: 
                    387:      case SCODE_PRTSCR: return AK_BACKSLASH;
                    388:      case SCODE_asciicircum: return AK_BACKQUOTE;
1.1       root      389:      case SCODE_bracketleft: return AK_LBRACKET;
                    390:      case SCODE_bracketright: return AK_RBRACKET;
                    391:      case SCODE_comma: return AK_COMMA;
                    392:      case SCODE_period: return AK_PERIOD;
                    393:      case SCODE_slash: return AK_SLASH;
                    394:      case SCODE_semicolon: return AK_SEMICOLON;
                    395:      case SCODE_grave: return AK_QUOTE;
                    396:      case SCODE_minus: return AK_MINUS;
                    397:      case SCODE_equal: return AK_EQUAL;
1.1.1.3   root      398: 
1.1       root      399:        /* This one turns off screen updates. */
1.1.1.3   root      400:      case SCODE_SLOCK: return AK_inhibit;
1.1       root      401: 
                    402:      case SCODE_PGUP: case SCODE_RWIN95: return AK_RAMI;
1.1.1.3   root      403:      case SCODE_PGDN: case SCODE_LWIN95: return AK_LAMI;
                    404: 
1.1       root      405: /*#ifdef KBD_LANG_DE*/
                    406:      case SCODE_numbersign: return AK_NUMBERSIGN;
                    407:      case SCODE_ltgt: return AK_LTGT;
                    408: /*#endif*/
                    409:     }
                    410:     return -1;
                    411: }
                    412: 
1.1.1.4   root      413: static void my_kbd_handler (int scancode, int newstate)
1.1       root      414: {
1.1.1.4   root      415:     int akey = scancode2amiga (scancode);
1.1.1.3   root      416: 
1.1.1.4   root      417:     assert (scancode >= 0 && scancode < 0x100);
1.1       root      418:     if (scancode == SCODE_F12) {
1.1.1.3   root      419:        uae_quit ();
                    420:     } else if (scancode == SCODE_F11) {
                    421:        gui_requested = 1;
1.1       root      422:     }
                    423:     if (keystate[scancode] == newstate)
1.1.1.3   root      424:        return;
1.1.1.4   root      425: 
1.1       root      426:     keystate[scancode] = newstate;
                    427: 
1.1.1.4   root      428:     if (akey == -1)
1.1.1.3   root      429:        return;
1.1       root      430: 
                    431:     if (newstate == KEY_EVENTPRESS) {
                    432:        if (akey == AK_inhibit)
1.1.1.3   root      433:            toggle_inhibit_frame (0);
1.1       root      434:        else
                    435:            record_key (akey << 1);
                    436:     } else
1.1.1.3   root      437:        record_key ((akey << 1) | 1);
                    438: 
1.1       root      439:     /* "Affengriff" */
1.1.1.6   root      440:     if ((keystate[AK_CTRL] || keystate[AK_RCTRL]) && keystate[AK_LAMI] && keystate[AK_RAMI])
1.1.1.4   root      441:        uae_reset ();
1.1       root      442: }
                    443: 
1.1.1.3   root      444: static void leave_graphics_mode (void)
                    445: {
                    446:     keyboard_close ();
                    447:     mouse_close ();
1.1.1.4   root      448:     sleep (1); /* Maybe this will fix the "screen full of garbage" problem */
1.1.1.3   root      449:     current_vgamode = TEXT;
1.1.1.4   root      450:     vga_setmode (TEXT);
1.1.1.3   root      451: }
                    452: 
                    453: static int post_enter_graphics (void)
                    454: {
1.1.1.4   root      455:     vga_setmousesupport (1);
                    456:     mouse_init("/dev/mouse", vga_getmousetype (), 10);
1.1.1.3   root      457:     if (keyboard_init() != 0) {
                    458:        leave_graphics_mode ();
1.1.1.11  root      459:        write_log ("Are you sure you have a keyboard??\n");
1.1.1.3   root      460:        return 0;
                    461:     }
                    462:     keyboard_seteventhandler (my_kbd_handler);
                    463:     keyboard_translatekeys (DONT_CATCH_CTRLC);
                    464: 
1.1.1.4   root      465:     mouse_setxrange (-1000, 1000);
                    466:     mouse_setyrange (-1000, 1000);
                    467:     mouse_setposition (0, 0);
1.1.1.3   root      468: 
                    469:     return 1;
                    470: }
                    471: 
                    472: static int enter_graphics_mode (int which)
                    473: {
                    474:     int oldmode = current_vgamode;
1.1.1.8   root      475:     vga_setmode (TEXT);
1.1.1.4   root      476:     if (vga_setmode (which) < 0) {
1.1.1.3   root      477:        sleep(1);
1.1.1.4   root      478:        vga_setmode (TEXT);
1.1.1.11  root      479:        write_log ("SVGAlib doesn't like my video mode (%d). Giving up.\n", which);
1.1.1.3   root      480:        return 0;
                    481:     }
                    482:     current_vgamode = which;
                    483: 
                    484:     linear_mem = 0;
1.1.1.6   root      485:     if ((modeinfo.flags & CAPABLE_LINEAR) && ! currprefs.svga_no_linear) {
1.1.1.4   root      486:        int val = vga_setlinearaddressing ();
1.1.1.3   root      487:        int new_ul = val != -1 ? !need_dither : 0;
                    488:        if (using_linear == -1)
                    489:            using_linear = new_ul;
                    490:        else
                    491:            if (using_linear != new_ul) {
                    492:                leave_graphics_mode ();
1.1.1.11  root      493:                write_log ("SVGAlib feeling not sure about linear modes???\n");
1.1.1.3   root      494:                abort ();
                    495:            }
                    496:        if (val != -1) {
1.1.1.4   root      497:            linear_mem = (char *)vga_getgraphmem ();
1.1.1.11  root      498:            write_log ("Using linear addressing: %p.\n", linear_mem);
1.1.1.3   root      499:        }
                    500:     }
                    501: 
                    502:     return post_enter_graphics ();
                    503: }
                    504: 
                    505: static int enter_graphics_mode_picasso (int which)
                    506: {
                    507:     int oldmode = current_vgamode;
                    508:     if (which == oldmode)
                    509:        return 1;
                    510: 
1.1.1.8   root      511:     vga_setmode (TEXT);
1.1.1.4   root      512:     if (vga_setmode (which) < 0) {
                    513:        sleep (1);
                    514:        vga_setmode (TEXT);
1.1.1.11  root      515:        write_log ("SVGAlib doesn't like my video mode (%d). Giving up.\n", which);
1.1.1.3   root      516:        exit (1);
                    517:     }
                    518:     current_vgamode = which;
                    519: 
                    520:     linear_mem = 0;
1.1.1.6   root      521:     if ((modeinfo.flags & CAPABLE_LINEAR) && ! currprefs.svga_no_linear) {
1.1.1.4   root      522:        int val = vga_setlinearaddressing ();
1.1.1.3   root      523:        if (val != -1) {
1.1.1.4   root      524:            linear_mem = (char *)vga_getgraphmem ();
1.1.1.11  root      525:            write_log ("Using linear addressing: %p.\n", linear_mem);
1.1.1.3   root      526:        }
                    527:     }
                    528: 
                    529:     keyboard_close ();
                    530:     mouse_close ();
                    531:     return post_enter_graphics ();
                    532: }
                    533: 
1.1.1.4   root      534: int graphics_setup (void)
1.1.1.3   root      535: {
                    536:     int i,j, count = 1;
                    537: 
                    538:     vga_init();
                    539: 
                    540:     current_vgamode = TEXT;
                    541: 
                    542:     for (i = 0; i < MAX_SCREEN_MODES; i++) {
                    543:        /* Ignore the larger modes which only make sense for Picasso screens.  */
                    544:        if (x_size_table[i] > 800 || y_size_table[i] > 600)
                    545:            continue;
                    546: 
                    547:        for (j = 0; j < MAX_COLOR_MODES+1; j++) {
                    548:            /* Delete modes which are not available on this card.  */
                    549:            if (!vga_hasmode (vga_mode_table[i][j])) {
                    550:                vga_mode_table[i][j] = -1;
                    551:            }
                    552: 
                    553:            if (vga_mode_table[i][j] != -1)
                    554:                count++;
                    555:        }
                    556:     }
                    557: 
1.1.1.4   root      558:     video_mode_menu = (struct bstring *)malloc (sizeof (struct bstring)*count);
                    559:     memset (video_mode_menu, 0, sizeof (struct bstring)*count);
                    560:     count = 0;
1.1.1.3   root      561: 
                    562:     for (i = 0; i < MAX_SCREEN_MODES; i++) {
                    563:        /* Ignore the larger modes which only make sense for Picasso screens.  */
                    564:        if (x_size_table[i] > 800 || y_size_table[i] > 600)
                    565:            continue;
                    566: 
                    567:        for (j = 0; j < MAX_COLOR_MODES+1; j++) {
                    568:            char buf[80];
                    569:            if (vga_mode_table[i][j] == -1)
                    570:                continue;
                    571: 
1.1.1.4   root      572:            sprintf (buf, "%3dx%d, %s", x_size_table[i], y_size_table[i],
                    573:                     colormodes[j]);
1.1.1.3   root      574:            video_mode_menu[count].val = -1;
                    575:            video_mode_menu[count++].data = strdup(buf);
                    576:        }
                    577:     }
                    578:     video_mode_menu[count].val = -3;
                    579:     video_mode_menu[count++].data = NULL;
                    580:     return 1;
                    581: }
                    582: 
                    583: void vidmode_menu_selected(int m)
                    584: {
                    585:     int i, j;
                    586:     for (i = 0; i < MAX_SCREEN_MODES; i++) {
                    587:        /* Ignore the larger modes which only make sense for Picasso screens.  */
                    588:        if (x_size_table[i] > 800 || y_size_table[i] > 600)
                    589:            continue;
                    590:        for (j = 0; j < MAX_COLOR_MODES+1; j++) {
                    591:            if (vga_mode_table[i][j] != -1)
                    592:                if (!m--)
                    593:                    goto found;
                    594: 
                    595:        }
                    596:     }
                    597:     abort();
                    598: 
                    599:     found:
                    600:     currprefs.gfx_width = x_size_table[i];
                    601:     currprefs.gfx_height = y_size_table[i];
                    602:     currprefs.color_mode = j;
                    603: }
                    604: 
                    605: static int select_mode_from_prefs (void)
1.1       root      606: {
1.1.1.2   root      607:     int mode_nr0, mode_nr;
1.1.1.3   root      608:     int i;
                    609: 
                    610:     if (currprefs.color_mode > 5)
1.1.1.11  root      611:        write_log ("Bad color mode selected. Using default.\n"), currprefs.color_mode = 0;
1.1       root      612: 
1.1.1.2   root      613:     mode_nr0 = 0;
                    614:     for (i = 1; i < MAX_SCREEN_MODES; i++) {
1.1.1.3   root      615:        if (x_size_table[mode_nr0] >= currprefs.gfx_width)
1.1.1.2   root      616:            break;
                    617:        if (x_size_table[i-1] != x_size_table[i])
                    618:            mode_nr0 = i;
                    619:     }
                    620:     mode_nr = -1;
                    621:     for (i = mode_nr0; i < MAX_SCREEN_MODES && x_size_table[i] == x_size_table[mode_nr0]; i++) {
1.1.1.3   root      622:        if ((y_size_table[i] >= currprefs.gfx_height
                    623:             || i + 1 == MAX_SCREEN_MODES
1.1.1.2   root      624:             || x_size_table[i+1] != x_size_table[mode_nr0])
1.1.1.3   root      625:            && vga_mode_table[i][currprefs.color_mode] != -1)
1.1.1.2   root      626:        {
                    627:            mode_nr = i;
                    628:            break;
                    629:        }
                    630:     }
                    631:     if (mode_nr == -1) {
1.1.1.11  root      632:        write_log ("Sorry, this combination of color and video mode is not supported.\n");
1.1       root      633:        return 0;
                    634:     }
1.1.1.3   root      635:     vgamode = vga_mode_table[mode_nr][currprefs.color_mode];
1.1.1.2   root      636:     if (vgamode == -1) {
1.1.1.11  root      637:        write_log ("Bug!\n");
1.1.1.4   root      638:        abort ();
1.1.1.2   root      639:     }
1.1.1.11  root      640:     write_log ("Desired resolution: %dx%d, using: %dx%d\n",
1.1.1.4   root      641:             currprefs.gfx_width, currprefs.gfx_height,
                    642:             x_size_table[mode_nr], y_size_table[mode_nr]);
1.1.1.3   root      643: 
                    644:     currprefs.gfx_width = x_size_table[mode_nr];
                    645:     currprefs.gfx_height = y_size_table[mode_nr];
                    646: 
                    647:     return 1;
                    648: }
                    649: 
1.1.1.4   root      650: int graphics_init (void)
1.1.1.3   root      651: {
                    652:     int i;
                    653:     need_dither = 0;
                    654:     screen_is_picasso = 0;
                    655: 
                    656:     if (!select_mode_from_prefs ())
                    657:        return 0;
                    658: 
                    659:     bitdepth = mode_bitdepth[currprefs.color_mode][0];
                    660:     bit_unit = mode_bitdepth[currprefs.color_mode][1];
                    661:     need_dither = mode_bitdepth[currprefs.color_mode][2];
                    662: 
1.1       root      663:     modeinfo = *vga_getmodeinfo (vgamode);
1.1.1.3   root      664: 
1.1       root      665:     gfxvidinfo.pixbytes = modeinfo.bytesperpixel;
                    666:     if (!need_dither) {
                    667:        if (modeinfo.bytesperpixel == 0) {
1.1.1.2   root      668:            printf("Got a bogus value from SVGAlib...\n");
1.1       root      669:            gfxvidinfo.pixbytes = 1;
                    670:        }
                    671:     } else {
                    672:        gfxvidinfo.pixbytes = 2;
                    673:     }
                    674: 
1.1.1.3   root      675:     using_linear = -1;
                    676: 
                    677:     if (!enter_graphics_mode (vgamode))
                    678:        return 0;
1.1.1.2   root      679: 
1.1.1.3   root      680:     sleep(2);
1.1       root      681:     gfxvidinfo.maxblocklines = 0;
                    682: 
1.1.1.3   root      683:     gfxvidinfo.width = modeinfo.width;
                    684:     gfxvidinfo.height = modeinfo.height;
1.1.1.2   root      685: 
1.1.1.3   root      686:     if (linear_mem != NULL && !need_dither) {
1.1       root      687:        gfxvidinfo.bufmem = linear_mem;
                    688:        gfxvidinfo.rowbytes = modeinfo.linewidth;
                    689:     } else {
1.1.1.2   root      690:        gfxvidinfo.rowbytes = (modeinfo.width * gfxvidinfo.pixbytes + 3) & ~3;
1.1.1.3   root      691: #if 1
1.1.1.4   root      692:        gfxvidinfo.bufmem = malloc (gfxvidinfo.rowbytes);
1.1.1.3   root      693:        gfxvidinfo.linemem = gfxvidinfo.bufmem;
1.1.1.4   root      694:        memset (gfxvidinfo.bufmem, 0, gfxvidinfo.rowbytes);
1.1.1.3   root      695: #else
1.1.1.2   root      696:        gfxvidinfo.bufmem = malloc(gfxvidinfo.rowbytes * modeinfo.height);
1.1.1.4   root      697:        memset (gfxvidinfo.bufmem, 0, gfxvidinfo.rowbytes * modeinfo.height);
1.1.1.3   root      698: #endif
1.1.1.4   root      699:        gfxvidinfo.emergmem = 0;
1.1       root      700:     }
1.1.1.7   root      701:     printf ("rowbytes %d\n", gfxvidinfo.rowbytes);
1.1.1.4   root      702:     init_colors ();
1.1       root      703:     buttonstate[0] = buttonstate[1] = buttonstate[2] = 0;
1.1.1.3   root      704:     for(i = 0; i < 256; i++)
1.1       root      705:        keystate[i] = 0;
                    706: 
                    707:     lastmx = lastmy = 0;
                    708:     newmousecounters = 0;
                    709: 
                    710:     return 1;
                    711: }
                    712: 
1.1.1.4   root      713: void graphics_leave (void)
1.1       root      714: {
1.1.1.3   root      715:     leave_graphics_mode ();
1.1       root      716:     dumpcustom();
                    717: }
                    718: 
1.1.1.4   root      719: void handle_events (void)
1.1       root      720: {
1.1.1.4   root      721:     int button = mouse_getbutton ();
1.1.1.3   root      722: 
                    723:     gui_requested = 0;
1.1.1.4   root      724:     keyboard_update ();
                    725:     mouse_update ();
                    726:     lastmx += mouse_getx ();
                    727:     lastmy += mouse_gety ();
                    728:     mouse_setposition (0, 0);
1.1       root      729: 
                    730:     buttonstate[0] = button & 4;
                    731:     buttonstate[1] = button & 2;
                    732:     buttonstate[2] = button & 1;
1.1.1.3   root      733: 
                    734: #ifdef PICASSO96
                    735:     if (screen_is_picasso && !picasso_vidinfo.extra_mem) {
                    736:        int i;
                    737:        char *addr = gfxmemory + (picasso96_state.Address - gfxmem_start);
                    738:        for (i = 0; i < picasso_vidinfo.height; i++, addr += picasso96_state.BytesPerRow) {
                    739:            if (!picasso_invalid_lines[i])
                    740:                continue;
                    741:            picasso_invalid_lines[i] = 0;
1.1.1.4   root      742:            vga_drawscanline (i, addr);
1.1.1.3   root      743:        }
                    744:     }
                    745: #endif
                    746: 
                    747:     if (!screen_is_picasso && gui_requested) {
                    748:        leave_graphics_mode ();
                    749:        gui_changesettings ();
                    750:        enter_graphics_mode (vgamode);
                    751:        if (linear_mem != NULL && !need_dither)
                    752:            gfxvidinfo.bufmem = linear_mem;
                    753:        restore_vga_colors ();
                    754:        notice_screen_contents_lost ();
                    755:     }
1.1       root      756: }
                    757: 
1.1.1.4   root      758: int check_prefs_changed_gfx (void)
1.1       root      759: {
                    760:     return 0;
                    761: }
                    762: 
1.1.1.4   root      763: int debuggable (void)
1.1       root      764: {
                    765:     return 0;
                    766: }
                    767: 
1.1.1.4   root      768: int needmousehack (void)
1.1       root      769: {
1.1.1.4   root      770:     return 0;
1.1       root      771: }
                    772: 
1.1.1.4   root      773: void LED (int on)
1.1.1.3   root      774: {
                    775: }
                    776: 
                    777: #ifdef PICASSO96
                    778: 
                    779: void DX_Invalidate (int first, int last)
                    780: {
                    781:     do {
                    782:        picasso_invalid_lines[first] = 1;
                    783:        first++;
                    784:     } while (first <= last);
                    785: }
                    786: 
                    787: int DX_BitsPerCannon (void)
                    788: {
                    789:     return 8;
                    790: }
                    791: 
                    792: void DX_SetPalette(int start, int count)
                    793: {
                    794:     if (!screen_is_picasso || picasso_vidinfo.pixbytes != 1)
                    795:        return;
                    796: 
                    797:     while (count-- > 0) {
                    798:        vga_setpalette(start, picasso96_state.CLUT[start].Red * 63 / 255,
                    799:                       picasso96_state.CLUT[start].Green * 63 / 255,
                    800:                       picasso96_state.CLUT[start].Blue * 63 / 255);
                    801:        start++;
                    802:     }
                    803: }
                    804: 
                    805: int DX_FillResolutions (uae_u16 *ppixel_format)
                    806: {
                    807:     int i, count = 0;
                    808:     uae_u16 format = 0;
                    809: 
                    810:     for (i = 0; i < MAX_SCREEN_MODES; i++) {
                    811:        int mode = vga_mode_table[i][0];
                    812:        if (mode != -1) {
                    813:            DisplayModes[count].res.width = x_size_table[i];
                    814:            DisplayModes[count].res.height = y_size_table[i];
                    815:            DisplayModes[count].depth = 1;
                    816:            DisplayModes[count].refresh = 75;
                    817:            count++;
                    818:            format |= RGBFF_CHUNKY;
                    819:        }
                    820:        mode = vga_mode_table[i][2];
                    821:        if (mode != -1) {
                    822:            DisplayModes[count].res.width = x_size_table[i];
                    823:            DisplayModes[count].res.height = y_size_table[i];
                    824:            DisplayModes[count].depth = 2;
                    825:            DisplayModes[count].refresh = 75;
                    826:            count++;
                    827:            format |= RGBFF_R5G6B5PC;
                    828:        }
                    829:        mode = vga_mode_table[i][5];
                    830:        if (mode != -1) {
                    831:            DisplayModes[count].res.width = x_size_table[i];
                    832:            DisplayModes[count].res.height = y_size_table[i];
                    833:            DisplayModes[count].depth = 4;
                    834:            DisplayModes[count].refresh = 75;
                    835:            count++;
                    836:            format |= RGBFF_B8G8R8A8;
                    837:        }
                    838:     }
                    839: 
                    840:     *ppixel_format = format;
                    841:     return count;
                    842: }
                    843: 
                    844: static void set_window_for_picasso (void)
                    845: {
                    846:     enter_graphics_mode_picasso (picasso_vgamode);
                    847:     if (linear_mem != NULL)
                    848:        picasso_vidinfo.extra_mem = 1;
                    849:     else
                    850:        picasso_vidinfo.extra_mem = 0;
                    851:     printf ("em: %d\n", picasso_vidinfo.extra_mem);
                    852:     DX_SetPalette (0, 256);
                    853: }
                    854: 
                    855: static void set_window_for_amiga (void)
                    856: {
                    857:     leave_graphics_mode ();
                    858:     enter_graphics_mode (vgamode);
                    859:     if (linear_mem != NULL && !need_dither)
                    860:        gfxvidinfo.bufmem = linear_mem;
                    861: 
                    862:     restore_vga_colors ();
                    863: }
                    864: 
1.1.1.5   root      865: void gfx_set_picasso_modeinfo (int w, int h, int depth, int rgbfmt)
1.1.1.3   root      866: {
                    867:     vga_modeinfo *info;
                    868:     int i, mode;
                    869: 
                    870:     for (i = 0; i < MAX_SCREEN_MODES; i++)
                    871:        if (x_size_table[i] == w && y_size_table[i] == h)
                    872:            break;
                    873:     printf ("::: %d %d %d, %d\n", w, h, depth, i);
                    874:     if (i == MAX_SCREEN_MODES)
                    875:        abort ();
                    876:     mode = (depth == 8 ? vga_mode_table[i][0]
                    877:            : depth == 16 ? vga_mode_table[i][2]
                    878:            : depth == 32 ? vga_mode_table[i][5]
                    879:            : -1);
                    880:     printf ("::: %d\n", mode);
                    881:     if (mode == -1)
                    882:        abort ();
                    883: 
                    884:     info = vga_getmodeinfo (mode);
                    885:     printf ("::: %d\n", info->linewidth);
                    886:     picasso_vgamode = mode;
                    887:     picasso_vidinfo.width = w;
                    888:     picasso_vidinfo.height = h;
                    889:     picasso_vidinfo.depth = depth;
                    890:     picasso_vidinfo.pixbytes = depth>>3;
                    891:     picasso_vidinfo.rowbytes = info->linewidth;
1.1.1.4   root      892:     picasso_vidinfo.rgbformat = (depth == 8 ? RGBFB_CHUNKY
                    893:                                 : depth == 16 ? RGBFB_R5G6B5PC
                    894:                                 : RGBFB_B8G8R8A8);
1.1.1.3   root      895:     if (screen_is_picasso)
                    896:        set_window_for_picasso ();
                    897: }
                    898: 
                    899: void gfx_set_picasso_baseaddr (uaecptr a)
                    900: {
                    901: }
                    902: 
                    903: void gfx_set_picasso_state (int on)
                    904: {
                    905:     if (on == screen_is_picasso)
                    906:        return;
                    907:     screen_is_picasso = on;
                    908:     if (on)
                    909:        set_window_for_picasso ();
                    910:     else
                    911:        set_window_for_amiga ();
                    912: }
                    913: 
1.1.1.4   root      914: uae_u8 *gfx_lock_picasso (void)
1.1.1.3   root      915: {
                    916:     return linear_mem;
                    917: }
1.1.1.4   root      918: void gfx_unlock_picasso (void)
1.1       root      919: {
                    920: }
1.1.1.3   root      921: #endif
1.1.1.4   root      922: 
                    923: int lockscr (void)
                    924: {
                    925:     return 1;
                    926: }
                    927: 
                    928: void unlockscr (void)
                    929: {
                    930: }
1.1.1.6   root      931: 
                    932: void target_save_options (FILE *f, struct uae_prefs *p)
                    933: {
                    934:     fprintf (f, "svga.no_linear=%s\n", p->svga_no_linear ? "true" : "false");
                    935: }
                    936: 
                    937: int target_parse_option (struct uae_prefs *p, char *option, char *value)
                    938: {
                    939:     return (cfgfile_yesno (option, value, "no_linear", &p->svga_no_linear));
                    940: }

unix.superglobalmegacorp.com

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