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