--- uae/src/svga.c 2018/04/24 16:38:39 1.1 +++ uae/src/svga.c 2018/04/24 16:42:10 1.1.1.4 @@ -1,8 +1,8 @@ - /* + /* * UAE - The Un*x Amiga Emulator - * + * * SVGAlib interface. - * + * * (c) 1995 Bernd Schmidt */ @@ -18,25 +18,36 @@ #include "config.h" #include "options.h" +#include "threaddep/penguin.h" +#include "uae.h" #include "memory.h" #include "custom.h" +#include "readcpu.h" #include "newcpu.h" #include "keyboard.h" #include "xwin.h" #include "keybuf.h" +#include "tui.h" #include "gui.h" +#include "picasso96.h" -#define SCODE_CURSORBLOCKUP 103 /* Cursor key block. */ -#define SCODE_CURSORBLOCKLEFT 105 -#define SCODE_CURSORBLOCKRIGHT 106 -#define SCODE_CURSORBLOCKDOWN 108 - -#define SCODE_INSERT 110 -#define SCODE_HOME 102 -#define SCODE_PGUP 104 -#define SCODE_DELETE 111 -#define SCODE_END 107 -#define SCODE_PGDN 109 +#define SCODE_CB_UP 103 /* Cursor key block. */ +#define SCODE_CB_LEFT 105 +#define SCODE_CB_RIGHT 106 +#define SCODE_CB_DOWN 108 + +#define SCODE_INSERT 110 +#define SCODE_HOME 102 +#define SCODE_PGUP 104 +#define SCODE_DELETE 111 +#define SCODE_END 107 +#define SCODE_PGDN 109 + +#define SCODE_PRTSCR 99 +#define SCODE_SLOCK 70 +#define SCODE_BREAK 119 + +#define SCODE_NUMLOCK 69 #define SCODE_KEYPAD0 82 #define SCODE_KEYPAD1 79 @@ -48,9 +59,12 @@ #define SCODE_KEYPAD7 71 #define SCODE_KEYPAD8 72 #define SCODE_KEYPAD9 73 -#define SCODE_KEYPADENTER 96 -#define SCODE_KEYPADPLUS 78 -#define SCODE_KEYPADMINUS 74 +#define SCODE_KEYPADRET 96 +#define SCODE_KEYPADADD 78 +#define SCODE_KEYPADSUB 74 +#define SCODE_KEYPADMUL 55 +#define SCODE_KEYPADDIV 98 +#define SCODE_KEYPADDOT 83 #define SCODE_Q 16 #define SCODE_W 17 @@ -81,61 +95,58 @@ #define SCODE_N 49 #define SCODE_M 50 -#define SCODE_ESCAPE 1 -#define SCODE_ENTER 28 -#define SCODE_RIGHTCONTROL 97 +#define SCODE_ESCAPE 1 +#define SCODE_ENTER 28 +#define SCODE_RCONTROL 97 #define SCODE_CONTROL 97 -#define SCODE_RIGHTALT 100 -#define SCODE_LEFTCONTROL 29 -#define SCODE_LEFTALT 56 -#define SCODE_SPACE 57 - -#define SCODE_F1 59 -#define SCODE_F2 60 -#define SCODE_F3 61 -#define SCODE_F4 62 -#define SCODE_F5 63 -#define SCODE_F6 64 -#define SCODE_F7 65 -#define SCODE_F8 66 -#define SCODE_F9 67 -#define SCODE_F10 68 - -#define SCODE_0 11 -#define SCODE_1 2 -#define SCODE_2 3 -#define SCODE_3 4 -#define SCODE_4 5 -#define SCODE_5 6 -#define SCODE_6 7 -#define SCODE_7 8 -#define SCODE_8 9 -#define SCODE_9 10 - -#define SCODE_LEFTSHIFT 42 -#define SCODE_RIGHTSHIFT 54 -#define SCODE_TAB 15 - -#define SCODE_F11 87 -#define SCODE_F12 88 -#define SCODE_NEXT 81 -#define SCODE_PRIOR 73 -#define SCODE_BS 14 -/* -#define SCODE_asciicircum 1 -*/ -#define SCODE_bracketleft 26 -#define SCODE_bracketright 27 -#define SCODE_comma 51 -#define SCODE_period 52 -#define SCODE_slash 53 -#define SCODE_semicolon 39 -#define SCODE_grave 40 -#define SCODE_minus 12 -#define SCODE_equal 13 -#define SCODE_numbersign 43 -#define SCODE_ltgt 86 -#define SCODE_scrolllock 70 +#define SCODE_RALT 100 +#define SCODE_LCONTROL 29 +#define SCODE_LALT 56 +#define SCODE_SPACE 57 + +#define SCODE_F1 59 +#define SCODE_F2 60 +#define SCODE_F3 61 +#define SCODE_F4 62 +#define SCODE_F5 63 +#define SCODE_F6 64 +#define SCODE_F7 65 +#define SCODE_F8 66 +#define SCODE_F9 67 +#define SCODE_F10 68 +#define SCODE_F11 87 +#define SCODE_F12 88 + +#define SCODE_0 11 +#define SCODE_1 2 +#define SCODE_2 3 +#define SCODE_3 4 +#define SCODE_4 5 +#define SCODE_5 6 +#define SCODE_6 7 +#define SCODE_7 8 +#define SCODE_8 9 +#define SCODE_9 10 + +#define SCODE_LSHIFT 42 +#define SCODE_RSHIFT 54 +#define SCODE_TAB 15 + +#define SCODE_BS 14 + +#define SCODE_asciicircum 41 + +#define SCODE_bracketleft 26 +#define SCODE_bracketright 27 +#define SCODE_comma 51 +#define SCODE_period 52 +#define SCODE_slash 53 +#define SCODE_semicolon 39 +#define SCODE_grave 40 +#define SCODE_minus 12 +#define SCODE_equal 13 +#define SCODE_numbersign 43 +#define SCODE_ltgt 86 #define SCODE_LWIN95 125 #define SCODE_RWIN95 126 @@ -145,124 +156,146 @@ void setup_brkhandler(void) { } -static int vsize, bitdepth, bit_unit, using_linear; +static int bitdepth, bit_unit, using_linear, vgamode, current_vgamode, gui_requested; static vga_modeinfo modeinfo; static char *linear_mem = NULL; static int need_dither; -static int x_size = 0, vidmode_linewidth; - -static UBYTE dither_buf[1000]; /* I hate having to think about array bounds */ +static int screen_is_picasso; +static int picasso_vgamode = -1; +static char picasso_invalid_lines[1200]; -xcolnr xcolors[4096]; +static uae_u8 dither_buf[1000]; /* I hate having to think about array bounds */ -struct vidbuf_description gfxvidinfo; +#define MAX_SCREEN_MODES 9 -static int x_size_table[MAX_SCREEN_MODES+1] = { 320, 320, 320, 640, 800 }; +static int x_size_table[MAX_SCREEN_MODES] = { 320, 320, 320, 640, 640, 800, 1024, 1152, 1280 }; +static int y_size_table[MAX_SCREEN_MODES] = { 200, 240, 400, 350, 480, 600, 768, 864, 1024 }; -static int vga_mode_table[MAX_SCREEN_MODES+1][MAX_COLOR_MODES+1] = +static int vga_mode_table[MAX_SCREEN_MODES][MAX_COLOR_MODES+1] = { { G320x200x256, G320x200x32K, G320x200x64K, G320x200x256, G320x200x16, G320x200x16M32 }, { G320x240x256, -1, -1, G320x240x256, -1, -1 }, { G320x400x256, -1, -1, G320x400x256, -1, -1 }, + { -1, -1, -1, -1, G640x350x16, -1 }, { G640x480x256, G640x480x32K, G640x480x64K, G640x480x256, G640x480x16, G640x480x16M32 }, - { G800x600x256, G800x600x32K, G800x600x64K, G800x600x256, G800x600x16, G800x600x16M32 } }; + { G800x600x256, G800x600x32K, G800x600x64K, G800x600x256, G800x600x16, G800x600x16M32 }, + { G1024x768x256, G1024x768x32K, G1024x768x64K, G1024x768x256, G1024x768x16, G1024x768x16M32 }, + { G1152x864x256, G1152x864x32K, G1152x864x64K, G1152x864x256, G1152x864x16, G1152x864x16M32 }, + { G1280x1024x256, G1280x1024x32K, G1280x1024x64K, G1280x1024x256, G1280x1024x16, G1280x1024x16M32 } + }; static int mode_bitdepth[MAX_COLOR_MODES+1][3] = { { 8, 8, 0 }, { 15, 16, 0 }, { 16, 16, 0 }, { 8, 8, 1 }, { 4, 8, 1 }, { 24, 32, 0 } }; +struct bstring *video_mode_menu = NULL; + void flush_line(int y) { int target_y = y; + char *addr; + + if (linear_mem != NULL && !need_dither) + return; + + addr = gfxvidinfo.linemem; + if (addr == NULL) + addr = gfxvidinfo.bufmem + y*gfxvidinfo.rowbytes; - if (screen_res < 2) - target_y -= 8; if (linear_mem == NULL) { - char *addr = gfxvidinfo.bufmem + y*gfxvidinfo.rowbytes; if (target_y < modeinfo.height && target_y >= 0) { if (need_dither) { - DitherLine(dither_buf, (UWORD *)addr, 0, y, x_size, bit_unit); + DitherLine (dither_buf, (uae_u16 *)addr, 0, y, gfxvidinfo.width, bit_unit); addr = dither_buf; - } + } vga_drawscanline(target_y, addr); } } else { if (need_dither && target_y >= 0) { - char *addr = gfxvidinfo.bufmem + y*gfxvidinfo.rowbytes; - DitherLine(linear_mem + vidmode_linewidth * target_y, (UWORD *)addr, 0, y, x_size, bit_unit); + DitherLine (linear_mem + modeinfo.linewidth * target_y, (uae_u16 *)addr, 0, y, + gfxvidinfo.width, bit_unit); } } } -void flush_block(int a, int b) +void flush_block (int a, int b) { abort(); } -void flush_screen(int a, int b) +void flush_screen (int a, int b) { } -void calc_adjustment(void) -{ - switch (screen_res) { - case 0: case 1: case 2: /* LoRes, 320xfoo */ - gfxvidinfo.x_adjust = prev_max_diwstop - 320; - break; +static int colors_allocated; +static long palette_entries[256][3]; - case 3: /* 640xbar */ - gfxvidinfo.x_adjust = prev_max_diwstop - 640; - break; - default: - gfxvidinfo.x_adjust = 0; - break; - } +static void restore_vga_colors (void) +{ + int i; + if (gfxvidinfo.pixbytes != 1) + return; + for (i = 0; i < 256; i++) + vga_setpalette (i, palette_entries[i][0], palette_entries[i][1], palette_entries[i][2]); } -static int colors_allocated; - -static int get_color(int r, int g, int b, xcolnr *cnp) +static int get_color (int r, int g, int b, xcolnr *cnp) { if (colors_allocated == 256) return -1; *cnp = colors_allocated; - vga_setpalette(colors_allocated, doMask(r, 6, 0), doMask(g, 6, 0), doMask(b, 6, 0)); + palette_entries[colors_allocated][0] = doMask (r, 6, 0); + palette_entries[colors_allocated][1] = doMask (g, 6, 0); + palette_entries[colors_allocated][2] = doMask (b, 6, 0); + vga_setpalette(colors_allocated, doMask (r, 6, 0), doMask (g, 6, 0), doMask (b, 6, 0)); colors_allocated++; return 1; } -static void init_colors(void) +static void init_colors (void) { + int i; if (need_dither) { - setup_dither(bitdepth, get_color); + setup_dither (bitdepth, get_color); } else { int rw = 5, gw = 5, bw = 5; colors_allocated = 0; - if (color_mode == 2) gw = 6; + if (currprefs.color_mode == 2) gw = 6; switch (gfxvidinfo.pixbytes) { case 4: - alloc_colors64k(8, 8, 8, 16, 8, 0); + alloc_colors64k (8, 8, 8, 16, 8, 0); break; case 2: - alloc_colors64k(rw, gw, bw, gw+bw, bw, 0); + alloc_colors64k (rw, gw, bw, gw+bw, bw, 0); break; case 1: - alloc_colors256(get_color); + alloc_colors256 (get_color); break; default: abort(); } } + switch (gfxvidinfo.pixbytes) { + case 2: + for (i = 0; i < 4096; i++) + xcolors[i] = xcolors[i] * 0x00010001; + gfxvidinfo.can_double = 1; + break; + case 1: + for (i = 0; i < 4096; i++) + xcolors[i] = xcolors[i] * 0x01010101; + gfxvidinfo.can_double = 1; + break; + default: + gfxvidinfo.can_double = 0; + break; + } } -int buttonstate[3] = { 0, 0, 0 }; -int lastmx, lastmy; -int newmousecounters = 0; - static int keystate[256]; -static int scancode2amiga(int scancode) +static int scancode2amiga (int scancode) { - switch(scancode) { + switch (scancode) { case SCODE_A: return AK_A; case SCODE_B: return AK_B; case SCODE_C: return AK_C; @@ -289,7 +322,7 @@ static int scancode2amiga(int scancode) case SCODE_X: return AK_X; case SCODE_Y: return AK_Y; case SCODE_Z: return AK_Z; - + case SCODE_0: return AK_0; case SCODE_1: return AK_1; case SCODE_2: return AK_2; @@ -300,7 +333,7 @@ static int scancode2amiga(int scancode) case SCODE_7: return AK_7; case SCODE_8: return AK_8; case SCODE_9: return AK_9; - + case SCODE_KEYPAD0: return AK_NP0; case SCODE_KEYPAD1: return AK_NP1; case SCODE_KEYPAD2: return AK_NP2; @@ -311,7 +344,14 @@ static int scancode2amiga(int scancode) case SCODE_KEYPAD7: return AK_NP7; case SCODE_KEYPAD8: return AK_NP8; case SCODE_KEYPAD9: return AK_NP9; - + + case SCODE_KEYPADADD: return AK_NPADD; + case SCODE_KEYPADSUB: return AK_NPSUB; + case SCODE_KEYPADMUL: return AK_NPMUL; + case SCODE_KEYPADDIV: return AK_NPDIV; + case SCODE_KEYPADRET: return AK_ENT; + case SCODE_KEYPADDOT: return AK_NPDEL; + case SCODE_F1: return AK_F1; case SCODE_F2: return AK_F2; case SCODE_F3: return AK_F3; @@ -322,33 +362,31 @@ static int scancode2amiga(int scancode) case SCODE_F8: return AK_F8; case SCODE_F9: return AK_F9; case SCODE_F10: return AK_F10; - + case SCODE_BS: return AK_BS; - case SCODE_LEFTCONTROL: return AK_CTRL; - case SCODE_RIGHTCONTROL: return AK_CTRL; + case SCODE_LCONTROL: return AK_CTRL; + case SCODE_RCONTROL: return AK_RCTRL; case SCODE_TAB: return AK_TAB; - case SCODE_LEFTALT: return AK_LALT; - case SCODE_RIGHTALT: return AK_RALT; + case SCODE_LALT: return AK_LALT; + case SCODE_RALT: return AK_RALT; case SCODE_ENTER: return AK_RET; case SCODE_SPACE: return AK_SPC; - case SCODE_LEFTSHIFT: return AK_LSH; - case SCODE_RIGHTSHIFT: return AK_RSH; + case SCODE_LSHIFT: return AK_LSH; + case SCODE_RSHIFT: return AK_RSH; case SCODE_ESCAPE: return AK_ESC; - - case SCODE_INSERT: - case SCODE_END: - case SCODE_HOME: break; + + case SCODE_INSERT: return AK_HELP; + case SCODE_END: return AK_NPRPAREN; + case SCODE_HOME: return AK_NPLPAREN; case SCODE_DELETE: return AK_DEL; - case SCODE_CURSORBLOCKUP: return AK_UP; - case SCODE_CURSORBLOCKDOWN: return AK_DN; - case SCODE_CURSORBLOCKLEFT: return AK_LF; - case SCODE_CURSORBLOCKRIGHT: return AK_RT; - - case SCODE_F11: return AK_BACKSLASH; -/* - case SCODE_asciicircum: return AK_00; - */ + case SCODE_CB_UP: return AK_UP; + case SCODE_CB_DOWN: return AK_DN; + case SCODE_CB_LEFT: return AK_LF; + case SCODE_CB_RIGHT: return AK_RT; + + case SCODE_PRTSCR: return AK_BACKSLASH; + case SCODE_asciicircum: return AK_BACKQUOTE; case SCODE_bracketleft: return AK_LBRACKET; case SCODE_bracketright: return AK_RBRACKET; case SCODE_comma: return AK_COMMA; @@ -358,13 +396,13 @@ static int scancode2amiga(int scancode) case SCODE_grave: return AK_QUOTE; case SCODE_minus: return AK_MINUS; case SCODE_equal: return AK_EQUAL; - + /* This one turns off screen updates. */ - case SCODE_scrolllock: return AK_inhibit; + case SCODE_SLOCK: return AK_inhibit; case SCODE_PGUP: case SCODE_RWIN95: return AK_RAMI; - case SCODE_PGDN: case SCODE_LWIN95: return AK_LAMI; - + case SCODE_PGDN: case SCODE_LWIN95: return AK_LAMI; + /*#ifdef KBD_LANG_DE*/ case SCODE_numbersign: return AK_NUMBERSIGN; case SCODE_ltgt: return AK_LTGT; @@ -373,175 +411,527 @@ static int scancode2amiga(int scancode) return -1; } -static void my_kbd_handler(int scancode, int newstate) +static void my_kbd_handler (int scancode, int newstate) { - int akey = scancode2amiga(scancode); - - assert(scancode >= 0 && scancode < 0x100); + int akey = scancode2amiga (scancode); + + assert (scancode >= 0 && scancode < 0x100); if (scancode == SCODE_F12) { - regs.spcflags |= SPCFLAG_BRK; - quit_program = 1; + uae_quit (); + } else if (scancode == SCODE_F11) { + gui_requested = 1; } if (keystate[scancode] == newstate) - return; + return; + keystate[scancode] = newstate; - if (akey == -1) { - return; - } + if (akey == -1) + return; if (newstate == KEY_EVENTPRESS) { if (akey == AK_inhibit) - inhibit_frame ^= 1; + toggle_inhibit_frame (0); else record_key (akey << 1); } else - record_key ((akey << 1) | 1); - + record_key ((akey << 1) | 1); + /* "Affengriff" */ if(keystate[AK_CTRL] && keystate[AK_LAMI] && keystate[AK_RAMI]) - m68k_reset(); + uae_reset (); } -int graphics_init(void) +static void leave_graphics_mode (void) { - int i; - int vgamode; - - need_dither = 0; - using_linear = 0; + keyboard_close (); + mouse_close (); + sleep (1); /* Maybe this will fix the "screen full of garbage" problem */ + current_vgamode = TEXT; + vga_setmode (TEXT); +} - if (screen_res < 3) - correct_aspect = 0; - - vgamode = vga_mode_table[screen_res][color_mode]; - if (vgamode == -1) { - fprintf(stderr, "Sorry, this combination of color and video mode is not supported.\n"); +static int post_enter_graphics (void) +{ + vga_setmousesupport (1); + mouse_init("/dev/mouse", vga_getmousetype (), 10); + if (keyboard_init() != 0) { + leave_graphics_mode (); + fprintf (stderr, "Are you sure you have a keyboard??\n"); + return 0; + } + keyboard_seteventhandler (my_kbd_handler); + keyboard_translatekeys (DONT_CATCH_CTRLC); + + mouse_setxrange (-1000, 1000); + mouse_setyrange (-1000, 1000); + mouse_setposition (0, 0); + + return 1; +} + +static int enter_graphics_mode (int which) +{ + int oldmode = current_vgamode; + if (vga_setmode (which) < 0) { + sleep(1); + vga_setmode (TEXT); + fprintf (stderr, "SVGAlib doesn't like my video mode. Giving up.\n"); return 0; } - - bitdepth = mode_bitdepth[color_mode][0]; - bit_unit = mode_bitdepth[color_mode][1]; - need_dither = mode_bitdepth[color_mode][2]; - x_size = x_size_table[screen_res]; - + current_vgamode = which; + + linear_mem = 0; + if ((modeinfo.flags & CAPABLE_LINEAR) && !currprefs.no_xhair) { + int val = vga_setlinearaddressing (); + int new_ul = val != -1 ? !need_dither : 0; + if (using_linear == -1) + using_linear = new_ul; + else + if (using_linear != new_ul) { + leave_graphics_mode (); + fprintf (stderr, "SVGAlib feeling not sure about linear modes???\n"); + abort (); + } + if (val != -1) { + linear_mem = (char *)vga_getgraphmem (); + fprintf (stderr, "Using linear addressing: %p.\n", linear_mem); + } + } + + return post_enter_graphics (); +} + +static int enter_graphics_mode_picasso (int which) +{ + int oldmode = current_vgamode; + if (which == oldmode) + return 1; + + if (vga_setmode (which) < 0) { + sleep (1); + vga_setmode (TEXT); + fprintf (stderr, "SVGAlib doesn't like my video mode. Giving up.\n"); + exit (1); + } + current_vgamode = which; + + linear_mem = 0; + if ((modeinfo.flags & CAPABLE_LINEAR) && !currprefs.no_xhair) { + int val = vga_setlinearaddressing (); + if (val != -1) { + linear_mem = (char *)vga_getgraphmem (); + fprintf (stderr, "Using linear addressing: %p.\n", linear_mem); + } + } + + keyboard_close (); + mouse_close (); + return post_enter_graphics (); +} + +int graphics_setup (void) +{ + int i,j, count = 1; + vga_init(); + + current_vgamode = TEXT; + + for (i = 0; i < MAX_SCREEN_MODES; i++) { + /* Ignore the larger modes which only make sense for Picasso screens. */ + if (x_size_table[i] > 800 || y_size_table[i] > 600) + continue; + + for (j = 0; j < MAX_COLOR_MODES+1; j++) { + /* Delete modes which are not available on this card. */ + if (!vga_hasmode (vga_mode_table[i][j])) { + vga_mode_table[i][j] = -1; + } + + if (vga_mode_table[i][j] != -1) + count++; + } + } + + video_mode_menu = (struct bstring *)malloc (sizeof (struct bstring)*count); + memset (video_mode_menu, 0, sizeof (struct bstring)*count); + count = 0; + + for (i = 0; i < MAX_SCREEN_MODES; i++) { + /* Ignore the larger modes which only make sense for Picasso screens. */ + if (x_size_table[i] > 800 || y_size_table[i] > 600) + continue; + + for (j = 0; j < MAX_COLOR_MODES+1; j++) { + char buf[80]; + if (vga_mode_table[i][j] == -1) + continue; + + sprintf (buf, "%3dx%d, %s", x_size_table[i], y_size_table[i], + colormodes[j]); + video_mode_menu[count].val = -1; + video_mode_menu[count++].data = strdup(buf); + } + } + video_mode_menu[count].val = -3; + video_mode_menu[count++].data = NULL; + return 1; +} + +void vidmode_menu_selected(int m) +{ + int i, j; + for (i = 0; i < MAX_SCREEN_MODES; i++) { + /* Ignore the larger modes which only make sense for Picasso screens. */ + if (x_size_table[i] > 800 || y_size_table[i] > 600) + continue; + for (j = 0; j < MAX_COLOR_MODES+1; j++) { + if (vga_mode_table[i][j] != -1) + if (!m--) + goto found; + + } + } + abort(); + + found: + currprefs.gfx_width = x_size_table[i]; + currprefs.gfx_height = y_size_table[i]; + currprefs.color_mode = j; +} + +static int select_mode_from_prefs (void) +{ + int mode_nr0, mode_nr; + int i; + + if (currprefs.color_mode > 5) + fprintf (stderr, "Bad color mode selected. Using default.\n"), currprefs.color_mode = 0; + + mode_nr0 = 0; + for (i = 1; i < MAX_SCREEN_MODES; i++) { + if (x_size_table[mode_nr0] >= currprefs.gfx_width) + break; + if (x_size_table[i-1] != x_size_table[i]) + mode_nr0 = i; + } + mode_nr = -1; + for (i = mode_nr0; i < MAX_SCREEN_MODES && x_size_table[i] == x_size_table[mode_nr0]; i++) { + if ((y_size_table[i] >= currprefs.gfx_height + || i + 1 == MAX_SCREEN_MODES + || x_size_table[i+1] != x_size_table[mode_nr0]) + && vga_mode_table[i][currprefs.color_mode] != -1) + { + mode_nr = i; + break; + } + } + if (mode_nr == -1) { + fprintf (stderr, "Sorry, this combination of color and video mode is not supported.\n"); + return 0; + } + vgamode = vga_mode_table[mode_nr][currprefs.color_mode]; + if (vgamode == -1) { + fprintf (stderr, "Bug!\n"); + abort (); + } + fprintf (stderr, "Desired resolution: %dx%d, using: %dx%d\n", + currprefs.gfx_width, currprefs.gfx_height, + x_size_table[mode_nr], y_size_table[mode_nr]); + + currprefs.gfx_width = x_size_table[mode_nr]; + currprefs.gfx_height = y_size_table[mode_nr]; + + return 1; +} + +int graphics_init (void) +{ + int i; + need_dither = 0; + screen_is_picasso = 0; + + if (!select_mode_from_prefs ()) + return 0; + + bitdepth = mode_bitdepth[currprefs.color_mode][0]; + bit_unit = mode_bitdepth[currprefs.color_mode][1]; + need_dither = mode_bitdepth[currprefs.color_mode][2]; + modeinfo = *vga_getmodeinfo (vgamode); - - vidmode_linewidth = modeinfo.linewidth; + gfxvidinfo.pixbytes = modeinfo.bytesperpixel; if (!need_dither) { if (modeinfo.bytesperpixel == 0) { - printf("Got a bogus value from SVGAlib... %s.\n", - screen_res == 1 || screen_res == 2 ? "trying to fix it" : "giving up"); - if (screen_res != 1 && screen_res != 2) - return 0; + printf("Got a bogus value from SVGAlib...\n"); gfxvidinfo.pixbytes = 1; } } else { gfxvidinfo.pixbytes = 2; } - - if (vga_setmode(vgamode) < 0) { - sleep(1); - vga_setmode(TEXT); - fprintf(stderr, "SVGAlib doesn't like my video mode. Giving up.\n"); + + using_linear = -1; + + if (!enter_graphics_mode (vgamode)) return 0; - } - if ((modeinfo.flags & CAPABLE_LINEAR) && !no_xhair) { - if (vga_setlinearaddressing() != -1) { - linear_mem = (char *)vga_getgraphmem(); - printf("Using linear addressing: %p.\n", linear_mem); - using_linear = !need_dither; - } - } - - vsize = correct_aspect ? 2*numscrlines : numscrlines; + sleep(2); gfxvidinfo.maxblocklines = 0; - if (using_linear) { + gfxvidinfo.width = modeinfo.width; + gfxvidinfo.height = modeinfo.height; + + if (linear_mem != NULL && !need_dither) { gfxvidinfo.bufmem = linear_mem; gfxvidinfo.rowbytes = modeinfo.linewidth; } else { - gfxvidinfo.rowbytes = x_size * gfxvidinfo.pixbytes; - gfxvidinfo.bufmem = malloc(gfxvidinfo.rowbytes * vsize); - memset(gfxvidinfo.bufmem, 0, gfxvidinfo.rowbytes * vsize); - } - - gfxvidinfo.maxlinetoscr = x_size < 800 ? x_size : 0; - gfxvidinfo.x_adjust = 0; - gfxvidinfo.maxline = modeinfo.height; - - init_colors(); - vga_setmousesupport(1); - mouse_init("/dev/mouse",vga_getmousetype(),10); - if (keyboard_init() != 0) - abort(); - keyboard_seteventhandler(my_kbd_handler); - keyboard_translatekeys(DONT_CATCH_CTRLC); - + gfxvidinfo.rowbytes = (modeinfo.width * gfxvidinfo.pixbytes + 3) & ~3; +#if 1 + gfxvidinfo.bufmem = malloc (gfxvidinfo.rowbytes); + gfxvidinfo.linemem = gfxvidinfo.bufmem; + memset (gfxvidinfo.bufmem, 0, gfxvidinfo.rowbytes); +#else + gfxvidinfo.bufmem = malloc(gfxvidinfo.rowbytes * modeinfo.height); + memset (gfxvidinfo.bufmem, 0, gfxvidinfo.rowbytes * modeinfo.height); +#endif + gfxvidinfo.emergmem = 0; + } + + init_colors (); buttonstate[0] = buttonstate[1] = buttonstate[2] = 0; - for(i = 0; i < 256; i++) + for(i = 0; i < 256; i++) keystate[i] = 0; lastmx = lastmy = 0; newmousecounters = 0; - mouse_setxrange(-1000,1000); - mouse_setyrange(-1000,1000); - mouse_setposition(0,0); - return 1; } -void graphics_leave(void) +void graphics_leave (void) { - sleep(1); /* Maybe this will fix the "screen full of garbage" problem */ - vga_setmode(TEXT); - keyboard_close(); + leave_graphics_mode (); dumpcustom(); } -void handle_events(void) +void handle_events (void) { - int button = mouse_getbutton(); - - keyboard_update(); - mouse_update(); - lastmx += mouse_getx(); - lastmy += mouse_gety(); - mouse_setposition(0,0); + int button = mouse_getbutton (); + + gui_requested = 0; + keyboard_update (); + mouse_update (); + lastmx += mouse_getx (); + lastmy += mouse_gety (); + mouse_setposition (0, 0); buttonstate[0] = button & 4; buttonstate[1] = button & 2; buttonstate[2] = button & 1; + +#ifdef PICASSO96 + if (screen_is_picasso && !picasso_vidinfo.extra_mem) { + int i; + char *addr = gfxmemory + (picasso96_state.Address - gfxmem_start); + for (i = 0; i < picasso_vidinfo.height; i++, addr += picasso96_state.BytesPerRow) { + if (!picasso_invalid_lines[i]) + continue; + picasso_invalid_lines[i] = 0; + vga_drawscanline (i, addr); + } + } +#endif + + if (!screen_is_picasso && gui_requested) { + leave_graphics_mode (); + gui_changesettings (); + enter_graphics_mode (vgamode); + if (linear_mem != NULL && !need_dither) + gfxvidinfo.bufmem = linear_mem; + restore_vga_colors (); + notice_screen_contents_lost (); + } } -int debuggable(void) +int check_prefs_changed_gfx (void) { return 0; } -int needmousehack(void) +int debuggable (void) { return 0; } -void LED(int on) +int needmousehack (void) +{ + return 0; +} + +void LED (int on) +{ +} + +#ifdef PICASSO96 + +void DX_Invalidate (int first, int last) +{ + do { + picasso_invalid_lines[first] = 1; + first++; + } while (first <= last); +} + +int DX_BitsPerCannon (void) +{ + return 8; +} + +void DX_SetPalette(int start, int count) +{ + if (!screen_is_picasso || picasso_vidinfo.pixbytes != 1) + return; + + while (count-- > 0) { + vga_setpalette(start, picasso96_state.CLUT[start].Red * 63 / 255, + picasso96_state.CLUT[start].Green * 63 / 255, + picasso96_state.CLUT[start].Blue * 63 / 255); + start++; + } +} + +int DX_FillResolutions (uae_u16 *ppixel_format) +{ + int i, count = 0; + uae_u16 format = 0; + + for (i = 0; i < MAX_SCREEN_MODES; i++) { + int mode = vga_mode_table[i][0]; + if (mode != -1) { + DisplayModes[count].res.width = x_size_table[i]; + DisplayModes[count].res.height = y_size_table[i]; + DisplayModes[count].depth = 1; + DisplayModes[count].refresh = 75; + count++; + format |= RGBFF_CHUNKY; + } + mode = vga_mode_table[i][2]; + if (mode != -1) { + DisplayModes[count].res.width = x_size_table[i]; + DisplayModes[count].res.height = y_size_table[i]; + DisplayModes[count].depth = 2; + DisplayModes[count].refresh = 75; + count++; + format |= RGBFF_R5G6B5PC; + } + mode = vga_mode_table[i][5]; + if (mode != -1) { + DisplayModes[count].res.width = x_size_table[i]; + DisplayModes[count].res.height = y_size_table[i]; + DisplayModes[count].depth = 4; + DisplayModes[count].refresh = 75; + count++; + format |= RGBFF_B8G8R8A8; + } + } + + *ppixel_format = format; + return count; +} + +static void set_window_for_picasso (void) +{ + enter_graphics_mode_picasso (picasso_vgamode); + if (linear_mem != NULL) + picasso_vidinfo.extra_mem = 1; + else + picasso_vidinfo.extra_mem = 0; + printf ("em: %d\n", picasso_vidinfo.extra_mem); + DX_SetPalette (0, 256); +} + +static void set_window_for_amiga (void) { + leave_graphics_mode (); + enter_graphics_mode (vgamode); + if (linear_mem != NULL && !need_dither) + gfxvidinfo.bufmem = linear_mem; + + restore_vga_colors (); +} + +void gfx_set_picasso_modeinfo (int w, int h, int depth) +{ + vga_modeinfo *info; + int i, mode; + + for (i = 0; i < MAX_SCREEN_MODES; i++) + if (x_size_table[i] == w && y_size_table[i] == h) + break; + printf ("::: %d %d %d, %d\n", w, h, depth, i); + if (i == MAX_SCREEN_MODES) + abort (); + mode = (depth == 8 ? vga_mode_table[i][0] + : depth == 16 ? vga_mode_table[i][2] + : depth == 32 ? vga_mode_table[i][5] + : -1); + printf ("::: %d\n", mode); + if (mode == -1) + abort (); + + info = vga_getmodeinfo (mode); + printf ("::: %d\n", info->linewidth); + picasso_vgamode = mode; + picasso_vidinfo.width = w; + picasso_vidinfo.height = h; + picasso_vidinfo.depth = depth; + picasso_vidinfo.pixbytes = depth>>3; + picasso_vidinfo.rowbytes = info->linewidth; + picasso_vidinfo.rgbformat = (depth == 8 ? RGBFB_CHUNKY + : depth == 16 ? RGBFB_R5G6B5PC + : RGBFB_B8G8R8A8); + if (screen_is_picasso) + set_window_for_picasso (); +} + +void gfx_set_picasso_baseaddr (uaecptr a) +{ +} + +void gfx_set_picasso_state (int on) +{ + if (on == screen_is_picasso) + return; + screen_is_picasso = on; + if (on) + set_window_for_picasso (); + else + set_window_for_amiga (); +} + +void begindrawing (void) +{ +} + +void enddrawing (void) +{ +} + +uae_u8 *gfx_lock_picasso (void) +{ + return linear_mem; +} +void gfx_unlock_picasso (void) +{ +} +#endif + +int lockscr (void) +{ + return 1; } -void target_specific_usage(void) +void unlockscr (void) { - printf(" -S n : Sound emulation accuracy (n = 0, 1, 2 or 3)\n" - " For sound emulation, n = 2 is recommended\n"); - printf(" -b n : Use n bits for sound output (8 or 16)\n"); - printf(" -R n : Use n Hz to output sound. Common values are\n" - " 22050 Hz or 44100 Hz\n"); - printf(" -B n : Use a sound buffer of n bytes (use small\n" - " values on fast machines)\n"); - printf(" -x : Don't use SVGAlib linear framebuffer, even if available.\n"); - printf(" -p command : Use command to pipe printer output to.\n"); - printf(" -I device : Name of the used serial device (i.e. /dev/ttyS1\n"); }