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