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