|
|
1.1 root 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 "config.h"
20: #include "options.h"
21: #include "memory.h"
22: #include "custom.h"
23: #include "newcpu.h"
24: #include "keyboard.h"
25: #include "xwin.h"
26: #include "keybuf.h"
27: #include "gui.h"
28:
29: #define SCODE_CURSORBLOCKUP 103 /* Cursor key block. */
30: #define SCODE_CURSORBLOCKLEFT 105
31: #define SCODE_CURSORBLOCKRIGHT 106
32: #define SCODE_CURSORBLOCKDOWN 108
33:
34: #define SCODE_INSERT 110
35: #define SCODE_HOME 102
36: #define SCODE_PGUP 104
37: #define SCODE_DELETE 111
38: #define SCODE_END 107
39: #define SCODE_PGDN 109
40:
41: #define SCODE_KEYPAD0 82
42: #define SCODE_KEYPAD1 79
43: #define SCODE_KEYPAD2 80
44: #define SCODE_KEYPAD3 81
45: #define SCODE_KEYPAD4 75
46: #define SCODE_KEYPAD5 76
47: #define SCODE_KEYPAD6 77
48: #define SCODE_KEYPAD7 71
49: #define SCODE_KEYPAD8 72
50: #define SCODE_KEYPAD9 73
51: #define SCODE_KEYPADENTER 96
52: #define SCODE_KEYPADPLUS 78
53: #define SCODE_KEYPADMINUS 74
54:
55: #define SCODE_Q 16
56: #define SCODE_W 17
57: #define SCODE_E 18
58: #define SCODE_R 19
59: #define SCODE_T 20
60: #define SCODE_Y 21
61: #define SCODE_U 22
62: #define SCODE_I 23
63: #define SCODE_O 24
64: #define SCODE_P 25
65:
66: #define SCODE_A 30
67: #define SCODE_S 31
68: #define SCODE_D 32
69: #define SCODE_F 33
70: #define SCODE_G 34
71: #define SCODE_H 35
72: #define SCODE_J 36
73: #define SCODE_K 37
74: #define SCODE_L 38
75:
76: #define SCODE_Z 44
77: #define SCODE_X 45
78: #define SCODE_C 46
79: #define SCODE_V 47
80: #define SCODE_B 48
81: #define SCODE_N 49
82: #define SCODE_M 50
83:
84: #define SCODE_ESCAPE 1
85: #define SCODE_ENTER 28
86: #define SCODE_RIGHTCONTROL 97
87: #define SCODE_CONTROL 97
88: #define SCODE_RIGHTALT 100
89: #define SCODE_LEFTCONTROL 29
90: #define SCODE_LEFTALT 56
91: #define SCODE_SPACE 57
92:
93: #define SCODE_F1 59
94: #define SCODE_F2 60
95: #define SCODE_F3 61
96: #define SCODE_F4 62
97: #define SCODE_F5 63
98: #define SCODE_F6 64
99: #define SCODE_F7 65
100: #define SCODE_F8 66
101: #define SCODE_F9 67
102: #define SCODE_F10 68
103:
104: #define SCODE_0 11
105: #define SCODE_1 2
106: #define SCODE_2 3
107: #define SCODE_3 4
108: #define SCODE_4 5
109: #define SCODE_5 6
110: #define SCODE_6 7
111: #define SCODE_7 8
112: #define SCODE_8 9
113: #define SCODE_9 10
114:
115: #define SCODE_LEFTSHIFT 42
116: #define SCODE_RIGHTSHIFT 54
117: #define SCODE_TAB 15
118:
119: #define SCODE_F11 87
120: #define SCODE_F12 88
121: #define SCODE_NEXT 81
122: #define SCODE_PRIOR 73
123: #define SCODE_BS 14
124: /*
125: #define SCODE_asciicircum 1
126: */
127: #define SCODE_bracketleft 26
128: #define SCODE_bracketright 27
129: #define SCODE_comma 51
130: #define SCODE_period 52
131: #define SCODE_slash 53
132: #define SCODE_semicolon 39
133: #define SCODE_grave 40
134: #define SCODE_minus 12
135: #define SCODE_equal 13
136: #define SCODE_numbersign 43
137: #define SCODE_ltgt 86
138: #define SCODE_scrolllock 70
139:
140: #define SCODE_LWIN95 125
141: #define SCODE_RWIN95 126
142: #define SCODE_MWIN95 127
143:
144: void setup_brkhandler(void)
145: {
146: }
147:
148: static int vsize, bitdepth, bit_unit, using_linear;
149: static vga_modeinfo modeinfo;
150: static char *linear_mem = NULL;
151: static int need_dither;
152: static int x_size = 0, vidmode_linewidth;
153:
154: static UBYTE dither_buf[1000]; /* I hate having to think about array bounds */
155:
156: xcolnr xcolors[4096];
157:
158: struct vidbuf_description gfxvidinfo;
159:
160: static int x_size_table[MAX_SCREEN_MODES+1] = { 320, 320, 320, 640, 800 };
161:
162: static int vga_mode_table[MAX_SCREEN_MODES+1][MAX_COLOR_MODES+1] =
163: { { G320x200x256, G320x200x32K, G320x200x64K, G320x200x256, G320x200x16, G320x200x16M32 },
164: { G320x240x256, -1, -1, G320x240x256, -1, -1 },
165: { G320x400x256, -1, -1, G320x400x256, -1, -1 },
166: { G640x480x256, G640x480x32K, G640x480x64K, G640x480x256, G640x480x16, G640x480x16M32 },
167: { G800x600x256, G800x600x32K, G800x600x64K, G800x600x256, G800x600x16, G800x600x16M32 } };
168:
169: static int mode_bitdepth[MAX_COLOR_MODES+1][3] =
170: { { 8, 8, 0 }, { 15, 16, 0 }, { 16, 16, 0 }, { 8, 8, 1 }, { 4, 8, 1 }, { 24, 32, 0 } };
171:
172: void flush_line(int y)
173: {
174: int target_y = y;
175:
176: if (screen_res < 2)
177: target_y -= 8;
178: if (linear_mem == NULL) {
179: char *addr = gfxvidinfo.bufmem + y*gfxvidinfo.rowbytes;
180: if (target_y < modeinfo.height && target_y >= 0) {
181: if (need_dither) {
182: DitherLine(dither_buf, (UWORD *)addr, 0, y, x_size, bit_unit);
183: addr = dither_buf;
184: }
185: vga_drawscanline(target_y, addr);
186: }
187: } else {
188: if (need_dither && target_y >= 0) {
189: char *addr = gfxvidinfo.bufmem + y*gfxvidinfo.rowbytes;
190: DitherLine(linear_mem + vidmode_linewidth * target_y, (UWORD *)addr, 0, y, x_size, bit_unit);
191: }
192: }
193: }
194:
195: void flush_block(int a, int b)
196: {
197: abort();
198: }
199:
200: void flush_screen(int a, int b)
201: {
202: }
203:
204: void calc_adjustment(void)
205: {
206: switch (screen_res) {
207: case 0: case 1: case 2: /* LoRes, 320xfoo */
208: gfxvidinfo.x_adjust = prev_max_diwstop - 320;
209: break;
210:
211: case 3: /* 640xbar */
212: gfxvidinfo.x_adjust = prev_max_diwstop - 640;
213: break;
214: default:
215: gfxvidinfo.x_adjust = 0;
216: break;
217: }
218: }
219:
220: static int colors_allocated;
221:
222: static int get_color(int r, int g, int b, xcolnr *cnp)
223: {
224: if (colors_allocated == 256)
225: return -1;
226: *cnp = colors_allocated;
227: vga_setpalette(colors_allocated, doMask(r, 6, 0), doMask(g, 6, 0), doMask(b, 6, 0));
228: colors_allocated++;
229: return 1;
230: }
231:
232: static void init_colors(void)
233: {
234: if (need_dither) {
235: setup_dither(bitdepth, get_color);
236: } else {
237: int rw = 5, gw = 5, bw = 5;
238: colors_allocated = 0;
239: if (color_mode == 2) gw = 6;
240:
241: switch (gfxvidinfo.pixbytes) {
242: case 4:
243: alloc_colors64k(8, 8, 8, 16, 8, 0);
244: break;
245: case 2:
246: alloc_colors64k(rw, gw, bw, gw+bw, bw, 0);
247: break;
248: case 1:
249: alloc_colors256(get_color);
250: break;
251: default:
252: abort();
253: }
254: }
255: }
256:
257: int buttonstate[3] = { 0, 0, 0 };
258: int lastmx, lastmy;
259: int newmousecounters = 0;
260:
261: static int keystate[256];
262:
263: static int scancode2amiga(int scancode)
264: {
265: switch(scancode) {
266: case SCODE_A: return AK_A;
267: case SCODE_B: return AK_B;
268: case SCODE_C: return AK_C;
269: case SCODE_D: return AK_D;
270: case SCODE_E: return AK_E;
271: case SCODE_F: return AK_F;
272: case SCODE_G: return AK_G;
273: case SCODE_H: return AK_H;
274: case SCODE_I: return AK_I;
275: case SCODE_J: return AK_J;
276: case SCODE_K: return AK_K;
277: case SCODE_L: return AK_L;
278: case SCODE_M: return AK_M;
279: case SCODE_N: return AK_N;
280: case SCODE_O: return AK_O;
281: case SCODE_P: return AK_P;
282: case SCODE_Q: return AK_Q;
283: case SCODE_R: return AK_R;
284: case SCODE_S: return AK_S;
285: case SCODE_T: return AK_T;
286: case SCODE_U: return AK_U;
287: case SCODE_V: return AK_V;
288: case SCODE_W: return AK_W;
289: case SCODE_X: return AK_X;
290: case SCODE_Y: return AK_Y;
291: case SCODE_Z: return AK_Z;
292:
293: case SCODE_0: return AK_0;
294: case SCODE_1: return AK_1;
295: case SCODE_2: return AK_2;
296: case SCODE_3: return AK_3;
297: case SCODE_4: return AK_4;
298: case SCODE_5: return AK_5;
299: case SCODE_6: return AK_6;
300: case SCODE_7: return AK_7;
301: case SCODE_8: return AK_8;
302: case SCODE_9: return AK_9;
303:
304: case SCODE_KEYPAD0: return AK_NP0;
305: case SCODE_KEYPAD1: return AK_NP1;
306: case SCODE_KEYPAD2: return AK_NP2;
307: case SCODE_KEYPAD3: return AK_NP3;
308: case SCODE_KEYPAD4: return AK_NP4;
309: case SCODE_KEYPAD5: return AK_NP5;
310: case SCODE_KEYPAD6: return AK_NP6;
311: case SCODE_KEYPAD7: return AK_NP7;
312: case SCODE_KEYPAD8: return AK_NP8;
313: case SCODE_KEYPAD9: return AK_NP9;
314:
315: case SCODE_F1: return AK_F1;
316: case SCODE_F2: return AK_F2;
317: case SCODE_F3: return AK_F3;
318: case SCODE_F4: return AK_F4;
319: case SCODE_F5: return AK_F5;
320: case SCODE_F6: return AK_F6;
321: case SCODE_F7: return AK_F7;
322: case SCODE_F8: return AK_F8;
323: case SCODE_F9: return AK_F9;
324: case SCODE_F10: return AK_F10;
325:
326: case SCODE_BS: return AK_BS;
327: case SCODE_LEFTCONTROL: return AK_CTRL;
328: case SCODE_RIGHTCONTROL: return AK_CTRL;
329: case SCODE_TAB: return AK_TAB;
330: case SCODE_LEFTALT: return AK_LALT;
331: case SCODE_RIGHTALT: return AK_RALT;
332: case SCODE_ENTER: return AK_RET;
333: case SCODE_SPACE: return AK_SPC;
334: case SCODE_LEFTSHIFT: return AK_LSH;
335: case SCODE_RIGHTSHIFT: return AK_RSH;
336: case SCODE_ESCAPE: return AK_ESC;
337:
338: case SCODE_INSERT:
339: case SCODE_END:
340: case SCODE_HOME: break;
341:
342: case SCODE_DELETE: return AK_DEL;
343: case SCODE_CURSORBLOCKUP: return AK_UP;
344: case SCODE_CURSORBLOCKDOWN: return AK_DN;
345: case SCODE_CURSORBLOCKLEFT: return AK_LF;
346: case SCODE_CURSORBLOCKRIGHT: return AK_RT;
347:
348: case SCODE_F11: return AK_BACKSLASH;
349: /*
350: case SCODE_asciicircum: return AK_00;
351: */
352: case SCODE_bracketleft: return AK_LBRACKET;
353: case SCODE_bracketright: return AK_RBRACKET;
354: case SCODE_comma: return AK_COMMA;
355: case SCODE_period: return AK_PERIOD;
356: case SCODE_slash: return AK_SLASH;
357: case SCODE_semicolon: return AK_SEMICOLON;
358: case SCODE_grave: return AK_QUOTE;
359: case SCODE_minus: return AK_MINUS;
360: case SCODE_equal: return AK_EQUAL;
361:
362: /* This one turns off screen updates. */
363: case SCODE_scrolllock: return AK_inhibit;
364:
365: case SCODE_PGUP: case SCODE_RWIN95: return AK_RAMI;
366: case SCODE_PGDN: case SCODE_LWIN95: return AK_LAMI;
367:
368: /*#ifdef KBD_LANG_DE*/
369: case SCODE_numbersign: return AK_NUMBERSIGN;
370: case SCODE_ltgt: return AK_LTGT;
371: /*#endif*/
372: }
373: return -1;
374: }
375:
376: static void my_kbd_handler(int scancode, int newstate)
377: {
378: int akey = scancode2amiga(scancode);
379:
380: assert(scancode >= 0 && scancode < 0x100);
381: if (scancode == SCODE_F12) {
382: regs.spcflags |= SPCFLAG_BRK;
383: quit_program = 1;
384: }
385: if (keystate[scancode] == newstate)
386: return;
387: keystate[scancode] = newstate;
388:
389: if (akey == -1) {
390: return;
391: }
392:
393: if (newstate == KEY_EVENTPRESS) {
394: if (akey == AK_inhibit)
395: inhibit_frame ^= 1;
396: else
397: record_key (akey << 1);
398: } else
399: record_key ((akey << 1) | 1);
400:
401: /* "Affengriff" */
402: if(keystate[AK_CTRL] && keystate[AK_LAMI] && keystate[AK_RAMI])
403: m68k_reset();
404: }
405:
406: int graphics_init(void)
407: {
408: int i;
409: int vgamode;
410:
411: need_dither = 0;
412: using_linear = 0;
413:
414: if (screen_res < 3)
415: correct_aspect = 0;
416:
417: vgamode = vga_mode_table[screen_res][color_mode];
418: if (vgamode == -1) {
419: fprintf(stderr, "Sorry, this combination of color and video mode is not supported.\n");
420: return 0;
421: }
422:
423: bitdepth = mode_bitdepth[color_mode][0];
424: bit_unit = mode_bitdepth[color_mode][1];
425: need_dither = mode_bitdepth[color_mode][2];
426: x_size = x_size_table[screen_res];
427:
428: vga_init();
429: modeinfo = *vga_getmodeinfo (vgamode);
430:
431: vidmode_linewidth = modeinfo.linewidth;
432: gfxvidinfo.pixbytes = modeinfo.bytesperpixel;
433: if (!need_dither) {
434: if (modeinfo.bytesperpixel == 0) {
435: printf("Got a bogus value from SVGAlib... %s.\n",
436: screen_res == 1 || screen_res == 2 ? "trying to fix it" : "giving up");
437: if (screen_res != 1 && screen_res != 2)
438: return 0;
439: gfxvidinfo.pixbytes = 1;
440: }
441: } else {
442: gfxvidinfo.pixbytes = 2;
443: }
444:
445: if (vga_setmode(vgamode) < 0) {
446: sleep(1);
447: vga_setmode(TEXT);
448: fprintf(stderr, "SVGAlib doesn't like my video mode. Giving up.\n");
449: return 0;
450: }
451:
452: if ((modeinfo.flags & CAPABLE_LINEAR) && !no_xhair) {
453: if (vga_setlinearaddressing() != -1) {
454: linear_mem = (char *)vga_getgraphmem();
455: printf("Using linear addressing: %p.\n", linear_mem);
456: using_linear = !need_dither;
457: }
458: }
459:
460: vsize = correct_aspect ? 2*numscrlines : numscrlines;
461: gfxvidinfo.maxblocklines = 0;
462:
463: if (using_linear) {
464: gfxvidinfo.bufmem = linear_mem;
465: gfxvidinfo.rowbytes = modeinfo.linewidth;
466: } else {
467: gfxvidinfo.rowbytes = x_size * gfxvidinfo.pixbytes;
468: gfxvidinfo.bufmem = malloc(gfxvidinfo.rowbytes * vsize);
469: memset(gfxvidinfo.bufmem, 0, gfxvidinfo.rowbytes * vsize);
470: }
471:
472: gfxvidinfo.maxlinetoscr = x_size < 800 ? x_size : 0;
473: gfxvidinfo.x_adjust = 0;
474: gfxvidinfo.maxline = modeinfo.height;
475:
476: init_colors();
477: vga_setmousesupport(1);
478: mouse_init("/dev/mouse",vga_getmousetype(),10);
479: if (keyboard_init() != 0)
480: abort();
481: keyboard_seteventhandler(my_kbd_handler);
482: keyboard_translatekeys(DONT_CATCH_CTRLC);
483:
484: buttonstate[0] = buttonstate[1] = buttonstate[2] = 0;
485: for(i = 0; i < 256; i++)
486: keystate[i] = 0;
487:
488: lastmx = lastmy = 0;
489: newmousecounters = 0;
490:
491: mouse_setxrange(-1000,1000);
492: mouse_setyrange(-1000,1000);
493: mouse_setposition(0,0);
494:
495: return 1;
496: }
497:
498: void graphics_leave(void)
499: {
500: sleep(1); /* Maybe this will fix the "screen full of garbage" problem */
501: vga_setmode(TEXT);
502: keyboard_close();
503: dumpcustom();
504: }
505:
506: void handle_events(void)
507: {
508: int button = mouse_getbutton();
509:
510: keyboard_update();
511: mouse_update();
512: lastmx += mouse_getx();
513: lastmy += mouse_gety();
514: mouse_setposition(0,0);
515:
516: buttonstate[0] = button & 4;
517: buttonstate[1] = button & 2;
518: buttonstate[2] = button & 1;
519: }
520:
521: int debuggable(void)
522: {
523: return 0;
524: }
525:
526: int needmousehack(void)
527: {
528: return 0;
529: }
530:
531: void LED(int on)
532: {
533: }
534:
535: void target_specific_usage(void)
536: {
537: printf(" -S n : Sound emulation accuracy (n = 0, 1, 2 or 3)\n"
538: " For sound emulation, n = 2 is recommended\n");
539: printf(" -b n : Use n bits for sound output (8 or 16)\n");
540: printf(" -R n : Use n Hz to output sound. Common values are\n"
541: " 22050 Hz or 44100 Hz\n");
542: printf(" -B n : Use a sound buffer of n bytes (use small\n"
543: " values on fast machines)\n");
544: printf(" -x : Don't use SVGAlib linear framebuffer, even if available.\n");
545: printf(" -p command : Use command to pipe printer output to.\n");
546: printf(" -I device : Name of the used serial device (i.e. /dev/ttyS1\n");
547: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.