|
|
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 "newcpu.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.8 root 476: vga_setmode (TEXT);
1.1.1.4 root 477: if (vga_setmode (which) < 0) {
1.1.1.3 root 478: sleep(1);
1.1.1.4 root 479: vga_setmode (TEXT);
1.1.1.8 root 480: fprintf (stderr, "SVGAlib doesn't like my video mode (%d). Giving up.\n", which);
1.1.1.3 root 481: return 0;
482: }
483: current_vgamode = which;
484:
485: linear_mem = 0;
1.1.1.6 root 486: if ((modeinfo.flags & CAPABLE_LINEAR) && ! currprefs.svga_no_linear) {
1.1.1.4 root 487: int val = vga_setlinearaddressing ();
1.1.1.3 root 488: int new_ul = val != -1 ? !need_dither : 0;
489: if (using_linear == -1)
490: using_linear = new_ul;
491: else
492: if (using_linear != new_ul) {
493: leave_graphics_mode ();
494: fprintf (stderr, "SVGAlib feeling not sure about linear modes???\n");
495: abort ();
496: }
497: if (val != -1) {
1.1.1.4 root 498: linear_mem = (char *)vga_getgraphmem ();
499: fprintf (stderr, "Using linear addressing: %p.\n", linear_mem);
1.1.1.3 root 500: }
501: }
502:
503: return post_enter_graphics ();
504: }
505:
506: static int enter_graphics_mode_picasso (int which)
507: {
508: int oldmode = current_vgamode;
509: if (which == oldmode)
510: return 1;
511:
1.1.1.8 root 512: vga_setmode (TEXT);
1.1.1.4 root 513: if (vga_setmode (which) < 0) {
514: sleep (1);
515: vga_setmode (TEXT);
1.1.1.8 root 516: fprintf (stderr, "SVGAlib doesn't like my video mode (%d). Giving up.\n", which);
1.1.1.3 root 517: exit (1);
518: }
519: current_vgamode = which;
520:
521: linear_mem = 0;
1.1.1.6 root 522: if ((modeinfo.flags & CAPABLE_LINEAR) && ! currprefs.svga_no_linear) {
1.1.1.4 root 523: int val = vga_setlinearaddressing ();
1.1.1.3 root 524: if (val != -1) {
1.1.1.4 root 525: linear_mem = (char *)vga_getgraphmem ();
526: fprintf (stderr, "Using linear addressing: %p.\n", linear_mem);
1.1.1.3 root 527: }
528: }
529:
530: keyboard_close ();
531: mouse_close ();
532: return post_enter_graphics ();
533: }
534:
1.1.1.4 root 535: int graphics_setup (void)
1.1.1.3 root 536: {
537: int i,j, count = 1;
538:
539: vga_init();
540:
541: current_vgamode = TEXT;
542:
543: for (i = 0; i < MAX_SCREEN_MODES; i++) {
544: /* Ignore the larger modes which only make sense for Picasso screens. */
545: if (x_size_table[i] > 800 || y_size_table[i] > 600)
546: continue;
547:
548: for (j = 0; j < MAX_COLOR_MODES+1; j++) {
549: /* Delete modes which are not available on this card. */
550: if (!vga_hasmode (vga_mode_table[i][j])) {
551: vga_mode_table[i][j] = -1;
552: }
553:
554: if (vga_mode_table[i][j] != -1)
555: count++;
556: }
557: }
558:
1.1.1.4 root 559: video_mode_menu = (struct bstring *)malloc (sizeof (struct bstring)*count);
560: memset (video_mode_menu, 0, sizeof (struct bstring)*count);
561: count = 0;
1.1.1.3 root 562:
563: for (i = 0; i < MAX_SCREEN_MODES; i++) {
564: /* Ignore the larger modes which only make sense for Picasso screens. */
565: if (x_size_table[i] > 800 || y_size_table[i] > 600)
566: continue;
567:
568: for (j = 0; j < MAX_COLOR_MODES+1; j++) {
569: char buf[80];
570: if (vga_mode_table[i][j] == -1)
571: continue;
572:
1.1.1.4 root 573: sprintf (buf, "%3dx%d, %s", x_size_table[i], y_size_table[i],
574: colormodes[j]);
1.1.1.3 root 575: video_mode_menu[count].val = -1;
576: video_mode_menu[count++].data = strdup(buf);
577: }
578: }
579: video_mode_menu[count].val = -3;
580: video_mode_menu[count++].data = NULL;
581: return 1;
582: }
583:
584: void vidmode_menu_selected(int m)
585: {
586: int i, j;
587: for (i = 0; i < MAX_SCREEN_MODES; i++) {
588: /* Ignore the larger modes which only make sense for Picasso screens. */
589: if (x_size_table[i] > 800 || y_size_table[i] > 600)
590: continue;
591: for (j = 0; j < MAX_COLOR_MODES+1; j++) {
592: if (vga_mode_table[i][j] != -1)
593: if (!m--)
594: goto found;
595:
596: }
597: }
598: abort();
599:
600: found:
601: currprefs.gfx_width = x_size_table[i];
602: currprefs.gfx_height = y_size_table[i];
603: currprefs.color_mode = j;
604: }
605:
606: static int select_mode_from_prefs (void)
1.1 root 607: {
1.1.1.2 root 608: int mode_nr0, mode_nr;
1.1.1.3 root 609: int i;
610:
611: if (currprefs.color_mode > 5)
1.1.1.4 root 612: fprintf (stderr, "Bad color mode selected. Using default.\n"), currprefs.color_mode = 0;
1.1 root 613:
1.1.1.2 root 614: mode_nr0 = 0;
615: for (i = 1; i < MAX_SCREEN_MODES; i++) {
1.1.1.3 root 616: if (x_size_table[mode_nr0] >= currprefs.gfx_width)
1.1.1.2 root 617: break;
618: if (x_size_table[i-1] != x_size_table[i])
619: mode_nr0 = i;
620: }
621: mode_nr = -1;
622: for (i = mode_nr0; i < MAX_SCREEN_MODES && x_size_table[i] == x_size_table[mode_nr0]; i++) {
1.1.1.3 root 623: if ((y_size_table[i] >= currprefs.gfx_height
624: || i + 1 == MAX_SCREEN_MODES
1.1.1.2 root 625: || x_size_table[i+1] != x_size_table[mode_nr0])
1.1.1.3 root 626: && vga_mode_table[i][currprefs.color_mode] != -1)
1.1.1.2 root 627: {
628: mode_nr = i;
629: break;
630: }
631: }
632: if (mode_nr == -1) {
1.1.1.4 root 633: fprintf (stderr, "Sorry, this combination of color and video mode is not supported.\n");
1.1 root 634: return 0;
635: }
1.1.1.3 root 636: vgamode = vga_mode_table[mode_nr][currprefs.color_mode];
1.1.1.2 root 637: if (vgamode == -1) {
1.1.1.4 root 638: fprintf (stderr, "Bug!\n");
639: abort ();
1.1.1.2 root 640: }
1.1.1.4 root 641: fprintf (stderr, "Desired resolution: %dx%d, using: %dx%d\n",
642: currprefs.gfx_width, currprefs.gfx_height,
643: x_size_table[mode_nr], y_size_table[mode_nr]);
1.1.1.3 root 644:
645: currprefs.gfx_width = x_size_table[mode_nr];
646: currprefs.gfx_height = y_size_table[mode_nr];
647:
648: return 1;
649: }
650:
1.1.1.4 root 651: int graphics_init (void)
1.1.1.3 root 652: {
653: int i;
654: need_dither = 0;
655: screen_is_picasso = 0;
656:
657: if (!select_mode_from_prefs ())
658: return 0;
659:
660: bitdepth = mode_bitdepth[currprefs.color_mode][0];
661: bit_unit = mode_bitdepth[currprefs.color_mode][1];
662: need_dither = mode_bitdepth[currprefs.color_mode][2];
663:
1.1 root 664: modeinfo = *vga_getmodeinfo (vgamode);
1.1.1.3 root 665:
1.1 root 666: gfxvidinfo.pixbytes = modeinfo.bytesperpixel;
667: if (!need_dither) {
668: if (modeinfo.bytesperpixel == 0) {
1.1.1.2 root 669: printf("Got a bogus value from SVGAlib...\n");
1.1 root 670: gfxvidinfo.pixbytes = 1;
671: }
672: } else {
673: gfxvidinfo.pixbytes = 2;
674: }
675:
1.1.1.3 root 676: using_linear = -1;
677:
678: if (!enter_graphics_mode (vgamode))
679: return 0;
1.1.1.2 root 680:
1.1.1.3 root 681: sleep(2);
1.1 root 682: gfxvidinfo.maxblocklines = 0;
683:
1.1.1.3 root 684: gfxvidinfo.width = modeinfo.width;
685: gfxvidinfo.height = modeinfo.height;
1.1.1.2 root 686:
1.1.1.3 root 687: if (linear_mem != NULL && !need_dither) {
1.1 root 688: gfxvidinfo.bufmem = linear_mem;
689: gfxvidinfo.rowbytes = modeinfo.linewidth;
690: } else {
1.1.1.2 root 691: gfxvidinfo.rowbytes = (modeinfo.width * gfxvidinfo.pixbytes + 3) & ~3;
1.1.1.3 root 692: #if 1
1.1.1.4 root 693: gfxvidinfo.bufmem = malloc (gfxvidinfo.rowbytes);
1.1.1.3 root 694: gfxvidinfo.linemem = gfxvidinfo.bufmem;
1.1.1.4 root 695: memset (gfxvidinfo.bufmem, 0, gfxvidinfo.rowbytes);
1.1.1.3 root 696: #else
1.1.1.2 root 697: gfxvidinfo.bufmem = malloc(gfxvidinfo.rowbytes * modeinfo.height);
1.1.1.4 root 698: memset (gfxvidinfo.bufmem, 0, gfxvidinfo.rowbytes * modeinfo.height);
1.1.1.3 root 699: #endif
1.1.1.4 root 700: gfxvidinfo.emergmem = 0;
1.1 root 701: }
1.1.1.7 root 702: printf ("rowbytes %d\n", gfxvidinfo.rowbytes);
1.1.1.4 root 703: init_colors ();
1.1 root 704: buttonstate[0] = buttonstate[1] = buttonstate[2] = 0;
1.1.1.3 root 705: for(i = 0; i < 256; i++)
1.1 root 706: keystate[i] = 0;
707:
708: lastmx = lastmy = 0;
709: newmousecounters = 0;
710:
711: return 1;
712: }
713:
1.1.1.4 root 714: void graphics_leave (void)
1.1 root 715: {
1.1.1.3 root 716: leave_graphics_mode ();
1.1 root 717: dumpcustom();
718: }
719:
1.1.1.4 root 720: void handle_events (void)
1.1 root 721: {
1.1.1.4 root 722: int button = mouse_getbutton ();
1.1.1.3 root 723:
724: gui_requested = 0;
1.1.1.4 root 725: keyboard_update ();
726: mouse_update ();
727: lastmx += mouse_getx ();
728: lastmy += mouse_gety ();
729: mouse_setposition (0, 0);
1.1 root 730:
731: buttonstate[0] = button & 4;
732: buttonstate[1] = button & 2;
733: buttonstate[2] = button & 1;
1.1.1.3 root 734:
735: #ifdef PICASSO96
736: if (screen_is_picasso && !picasso_vidinfo.extra_mem) {
737: int i;
738: char *addr = gfxmemory + (picasso96_state.Address - gfxmem_start);
739: for (i = 0; i < picasso_vidinfo.height; i++, addr += picasso96_state.BytesPerRow) {
740: if (!picasso_invalid_lines[i])
741: continue;
742: picasso_invalid_lines[i] = 0;
1.1.1.4 root 743: vga_drawscanline (i, addr);
1.1.1.3 root 744: }
745: }
746: #endif
747:
748: if (!screen_is_picasso && gui_requested) {
749: leave_graphics_mode ();
750: gui_changesettings ();
751: enter_graphics_mode (vgamode);
752: if (linear_mem != NULL && !need_dither)
753: gfxvidinfo.bufmem = linear_mem;
754: restore_vga_colors ();
755: notice_screen_contents_lost ();
756: }
1.1 root 757: }
758:
1.1.1.4 root 759: int check_prefs_changed_gfx (void)
1.1 root 760: {
761: return 0;
762: }
763:
1.1.1.4 root 764: int debuggable (void)
1.1 root 765: {
766: return 0;
767: }
768:
1.1.1.4 root 769: int needmousehack (void)
1.1 root 770: {
1.1.1.4 root 771: return 0;
1.1 root 772: }
773:
1.1.1.4 root 774: void LED (int on)
1.1.1.3 root 775: {
776: }
777:
778: #ifdef PICASSO96
779:
780: void DX_Invalidate (int first, int last)
781: {
782: do {
783: picasso_invalid_lines[first] = 1;
784: first++;
785: } while (first <= last);
786: }
787:
788: int DX_BitsPerCannon (void)
789: {
790: return 8;
791: }
792:
793: void DX_SetPalette(int start, int count)
794: {
795: if (!screen_is_picasso || picasso_vidinfo.pixbytes != 1)
796: return;
797:
798: while (count-- > 0) {
799: vga_setpalette(start, picasso96_state.CLUT[start].Red * 63 / 255,
800: picasso96_state.CLUT[start].Green * 63 / 255,
801: picasso96_state.CLUT[start].Blue * 63 / 255);
802: start++;
803: }
804: }
805:
806: int DX_FillResolutions (uae_u16 *ppixel_format)
807: {
808: int i, count = 0;
809: uae_u16 format = 0;
810:
811: for (i = 0; i < MAX_SCREEN_MODES; i++) {
812: int mode = vga_mode_table[i][0];
813: if (mode != -1) {
814: DisplayModes[count].res.width = x_size_table[i];
815: DisplayModes[count].res.height = y_size_table[i];
816: DisplayModes[count].depth = 1;
817: DisplayModes[count].refresh = 75;
818: count++;
819: format |= RGBFF_CHUNKY;
820: }
821: mode = vga_mode_table[i][2];
822: if (mode != -1) {
823: DisplayModes[count].res.width = x_size_table[i];
824: DisplayModes[count].res.height = y_size_table[i];
825: DisplayModes[count].depth = 2;
826: DisplayModes[count].refresh = 75;
827: count++;
828: format |= RGBFF_R5G6B5PC;
829: }
830: mode = vga_mode_table[i][5];
831: if (mode != -1) {
832: DisplayModes[count].res.width = x_size_table[i];
833: DisplayModes[count].res.height = y_size_table[i];
834: DisplayModes[count].depth = 4;
835: DisplayModes[count].refresh = 75;
836: count++;
837: format |= RGBFF_B8G8R8A8;
838: }
839: }
840:
841: *ppixel_format = format;
842: return count;
843: }
844:
845: static void set_window_for_picasso (void)
846: {
847: enter_graphics_mode_picasso (picasso_vgamode);
848: if (linear_mem != NULL)
849: picasso_vidinfo.extra_mem = 1;
850: else
851: picasso_vidinfo.extra_mem = 0;
852: printf ("em: %d\n", picasso_vidinfo.extra_mem);
853: DX_SetPalette (0, 256);
854: }
855:
856: static void set_window_for_amiga (void)
857: {
858: leave_graphics_mode ();
859: enter_graphics_mode (vgamode);
860: if (linear_mem != NULL && !need_dither)
861: gfxvidinfo.bufmem = linear_mem;
862:
863: restore_vga_colors ();
864: }
865:
1.1.1.5 root 866: void gfx_set_picasso_modeinfo (int w, int h, int depth, int rgbfmt)
1.1.1.3 root 867: {
868: vga_modeinfo *info;
869: int i, mode;
870:
871: for (i = 0; i < MAX_SCREEN_MODES; i++)
872: if (x_size_table[i] == w && y_size_table[i] == h)
873: break;
874: printf ("::: %d %d %d, %d\n", w, h, depth, i);
875: if (i == MAX_SCREEN_MODES)
876: abort ();
877: mode = (depth == 8 ? vga_mode_table[i][0]
878: : depth == 16 ? vga_mode_table[i][2]
879: : depth == 32 ? vga_mode_table[i][5]
880: : -1);
881: printf ("::: %d\n", mode);
882: if (mode == -1)
883: abort ();
884:
885: info = vga_getmodeinfo (mode);
886: printf ("::: %d\n", info->linewidth);
887: picasso_vgamode = mode;
888: picasso_vidinfo.width = w;
889: picasso_vidinfo.height = h;
890: picasso_vidinfo.depth = depth;
891: picasso_vidinfo.pixbytes = depth>>3;
892: picasso_vidinfo.rowbytes = info->linewidth;
1.1.1.4 root 893: picasso_vidinfo.rgbformat = (depth == 8 ? RGBFB_CHUNKY
894: : depth == 16 ? RGBFB_R5G6B5PC
895: : RGBFB_B8G8R8A8);
1.1.1.3 root 896: if (screen_is_picasso)
897: set_window_for_picasso ();
898: }
899:
900: void gfx_set_picasso_baseaddr (uaecptr a)
901: {
902: }
903:
904: void gfx_set_picasso_state (int on)
905: {
906: if (on == screen_is_picasso)
907: return;
908: screen_is_picasso = on;
909: if (on)
910: set_window_for_picasso ();
911: else
912: set_window_for_amiga ();
913: }
914:
1.1.1.4 root 915: uae_u8 *gfx_lock_picasso (void)
1.1.1.3 root 916: {
917: return linear_mem;
918: }
1.1.1.4 root 919: void gfx_unlock_picasso (void)
1.1 root 920: {
921: }
1.1.1.3 root 922: #endif
1.1.1.4 root 923:
924: int lockscr (void)
925: {
926: return 1;
927: }
928:
929: void unlockscr (void)
930: {
931: }
1.1.1.6 root 932:
933: void target_save_options (FILE *f, struct uae_prefs *p)
934: {
935: fprintf (f, "svga.no_linear=%s\n", p->svga_no_linear ? "true" : "false");
936: }
937:
938: int target_parse_option (struct uae_prefs *p, char *option, char *value)
939: {
940: return (cfgfile_yesno (option, value, "no_linear", &p->svga_no_linear));
941: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.