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