|
|
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 <stdlib.h>
10: #include <string.h>
11: #include <stdio.h>
12: #include <assert.h>
13: #include <signal.h>
14: #include <unistd.h>
15: #include <vga.h>
16: #include <vgamouse.h>
17: #include <vgakeyboard.h>
18:
19: #include "config.h"
20: #include "amiga.h"
21: #include "options.h"
22: #include "memory.h"
23: #include "custom.h"
24: #include "newcpu.h"
25: #include "keyboard.h"
26: #include "xwin.h"
27: #include "keybuf.h"
28:
29: #ifndef LINUX_SVGALIB
30: #error Compiling svga.c, but LINUX_SVGALIB unset. Re-edit "config.h".
31: #endif
32:
33: /* Why doesn't SVGAlib define these !??? */
34:
35: #define SCANCODE_0 11
36: #define SCANCODE_1 2
37: #define SCANCODE_2 3
38: #define SCANCODE_3 4
39: #define SCANCODE_4 5
40: #define SCANCODE_5 6
41: #define SCANCODE_6 7
42: #define SCANCODE_7 8
43: #define SCANCODE_8 9
44: #define SCANCODE_9 10
45:
46: #define SCANCODE_LEFTSHIFT 42
47: #define SCANCODE_RIGHTSHIFT 54
48: #define SCANCODE_TAB 15
49:
50: #define SCANCODE_F11 87
51: #define SCANCODE_F12 88
52: #define SCANCODE_NEXT 81
53: #define SCANCODE_PRIOR 73
54: #define SCANCODE_BS 14
55: /*
56: #define SCANCODE_asciicircum 1
57: */
58: #define SCANCODE_bracketleft 26
59: #define SCANCODE_bracketright 27
60: #define SCANCODE_comma 51
61: #define SCANCODE_period 52
62: #define SCANCODE_slash 53
63: #define SCANCODE_semicolon 39
64: #define SCANCODE_grave 40
65: #define SCANCODE_minus 12
66: #define SCANCODE_equal 13
67: #define SCANCODE_numbersign 41
68: #define SCANCODE_ltgt 43
69: #define SCANCODE_scrolllock 70
70:
71: static char pixel_buffer[3200];
72: char *xlinebuffer;
73:
74: long int xcolors[4096];
75:
76: static int next_pos;
77: static bool next_double;
78:
79: void prepare_line(int y, bool need_double)
80: {
81: next_pos = y;
82: next_double = need_double;
83: xlinebuffer = pixel_buffer;
84: }
85:
86: void flush_line(void)
87: {
88: vga_drawscanline(next_pos, pixel_buffer);
89: if (next_double)
90: vga_drawscanline(next_pos+1, pixel_buffer);
91: }
92:
93: void flush_screen(void)
94: {
95: }
96:
97: static __inline__ unsigned long doMask(int p, int bits, int shift)
98: {
99: /* p is a value from 0 to 15 (Amiga color value)
100: * scale to 0..255, shift to align msb with mask, and apply mask */
101:
102: unsigned long val = p * 0x11111111UL;
103: val >>= (32 - bits);
104: val <<= shift;
105:
106: return val;
107: }
108:
109: static void init_colors(void)
110: {
111: #ifdef SVGALIB_16BIT_SCREEN
112: int i;
113: for(i=0; i<4096; i++) {
114: int r = i >> 8;
115: int g = (i >> 4) & 0xF;
116: int b = i & 0xF;
117: xcolors[i] = (doMask(r, SVGALIB_R_WEIGHT, SVGALIB_G_WEIGHT + SVGALIB_B_WEIGHT)
118: | doMask(g, SVGALIB_G_WEIGHT, SVGALIB_B_WEIGHT)
119: | doMask(b, SVGALIB_B_WEIGHT, 0));
120: }
121: #endif
122: #ifdef SVGALIB_8BIT_SCREEN
123: /* This is kind of kludgy...
124: * Try to allocate as many different colors as possible. */
125: int step = 16, count = 0, col;
126: int allocated[4096];
127: memset(allocated,0,sizeof allocated);
128:
129: while ((step/=2) > 0) {
130: int r, g, b;
131: for(r = 0; r < 16; r += step) {
132: for(g = 0; g < 16; g += step) {
133: for(b = 0; b < 16; b += step) {
134: int cnr = (r << 8) + (g << 4) + b;
135: if (++count == 256)
136: goto finished;
137: if (!allocated[cnr]) {
138: allocated[cnr] = true;
139: xcolors[cnr] = count-1;
140: vga_setpalette(count-1,(r*63+7)/15,(g*63+7)/15,(b*63+7)/15);
141: }
142: }
143: }
144: }
145: }
146: finished:
147: for(col = 0; col < 4096; col++) {
148: int cnr = col;
149: if (!allocated[cnr]) {
150: int r = cnr >> 8;
151: int g = (cnr >> 4) & 0xF;
152: int b = cnr & 0xF;
153: int maxd = 4096,best = 0;
154: int c2;
155: for(c2 = 0; c2 < 4096; c2++)
156: if (allocated[c2]) {
157: int r2 = c2 >> 8;
158: int g2 = (c2 >> 4) & 0xF;
159: int b2 = c2 & 0xF;
160: int dist = abs(r2-r)*2 + abs(g2-g)*3 + abs(b2-b);
161: if (dist < maxd) {
162: maxd = dist;
163: best = c2;
164: }
165: }
166: cnr = best;
167: }
168: xcolors[col] = xcolors[cnr];
169: }
170: #endif
171: }
172:
173: bool buttonstate[3] = { false, false, false };
174: int lastmx, lastmy;
175: bool newmousecounters = false;
176:
177: static bool keystate[256];
178:
179: static int scancode2amiga(int scancode)
180: {
181: switch(scancode) {
182: case SCANCODE_A: return AK_A;
183: case SCANCODE_B: return AK_B;
184: case SCANCODE_C: return AK_C;
185: case SCANCODE_D: return AK_D;
186: case SCANCODE_E: return AK_E;
187: case SCANCODE_F: return AK_F;
188: case SCANCODE_G: return AK_G;
189: case SCANCODE_H: return AK_H;
190: case SCANCODE_I: return AK_I;
191: case SCANCODE_J: return AK_J;
192: case SCANCODE_K: return AK_K;
193: case SCANCODE_L: return AK_L;
194: case SCANCODE_M: return AK_M;
195: case SCANCODE_N: return AK_N;
196: case SCANCODE_O: return AK_O;
197: case SCANCODE_P: return AK_P;
198: case SCANCODE_Q: return AK_Q;
199: case SCANCODE_R: return AK_R;
200: case SCANCODE_S: return AK_S;
201: case SCANCODE_T: return AK_T;
202: case SCANCODE_U: return AK_U;
203: case SCANCODE_V: return AK_V;
204: case SCANCODE_W: return AK_W;
205: case SCANCODE_X: return AK_X;
206: case SCANCODE_Y: return AK_Y;
207: case SCANCODE_Z: return AK_Z;
208:
209: case SCANCODE_0: return AK_0;
210: case SCANCODE_1: return AK_1;
211: case SCANCODE_2: return AK_2;
212: case SCANCODE_3: return AK_3;
213: case SCANCODE_4: return AK_4;
214: case SCANCODE_5: return AK_5;
215: case SCANCODE_6: return AK_6;
216: case SCANCODE_7: return AK_7;
217: case SCANCODE_8: return AK_8;
218: case SCANCODE_9: return AK_9;
219:
220: case SCANCODE_KEYPAD0: return AK_NP0;
221: case SCANCODE_KEYPAD1: return AK_NP1;
222: case SCANCODE_KEYPAD2: return AK_NP2;
223: case SCANCODE_KEYPAD3: return AK_NP3;
224: case SCANCODE_KEYPAD4: return AK_NP4;
225: case SCANCODE_KEYPAD5: return AK_NP5;
226: case SCANCODE_KEYPAD6: return AK_NP6;
227: case SCANCODE_KEYPAD7: return AK_NP7;
228: case SCANCODE_KEYPAD8: return AK_NP8;
229: case SCANCODE_KEYPAD9: return AK_NP9;
230:
231: case SCANCODE_F1: return AK_F1;
232: case SCANCODE_F2: return AK_F2;
233: case SCANCODE_F3: return AK_F3;
234: case SCANCODE_F4: return AK_F4;
235: case SCANCODE_F5: return AK_F5;
236: case SCANCODE_F6: return AK_F6;
237: case SCANCODE_F7: return AK_F7;
238: case SCANCODE_F8: return AK_F8;
239: case SCANCODE_F9: return AK_F9;
240: case SCANCODE_F10: return AK_F10;
241:
242: case SCANCODE_BS: return AK_BS;
243: case SCANCODE_CONTROL: return AK_CTRL;
244: case SCANCODE_TAB: return AK_TAB;
245: case SCANCODE_LEFTALT: return AK_LALT;
246: case SCANCODE_RIGHTALT: return AK_RALT;
247: case SCANCODE_ENTER: return AK_RET;
248: case SCANCODE_SPACE: return AK_SPC;
249: case SCANCODE_LEFTSHIFT: return AK_LSH;
250: case SCANCODE_RIGHTSHIFT: return AK_RSH;
251: case SCANCODE_ESCAPE: return AK_ESC;
252:
253: case SCANCODE_CURSORBLOCKUP: return AK_UP;
254: case SCANCODE_CURSORBLOCKDOWN: return AK_DN;
255: case SCANCODE_CURSORBLOCKLEFT: return AK_LF;
256: case SCANCODE_CURSORBLOCKRIGHT: return AK_RT;
257:
258: case SCANCODE_F11: return AK_BACKSLASH;
259: /*
260: case SCANCODE_asciicircum: return AK_00;
261: */
262: case SCANCODE_bracketleft: return AK_LBRACKET;
263: case SCANCODE_bracketright: return AK_RBRACKET;
264: case SCANCODE_comma: return AK_COMMA;
265: case SCANCODE_period: return AK_PERIOD;
266: case SCANCODE_slash: return AK_SLASH;
267: case SCANCODE_semicolon: return AK_SEMICOLON;
268: case SCANCODE_grave: return AK_QUOTE;
269: case SCANCODE_minus: return AK_MINUS;
270: case SCANCODE_equal: return AK_EQUAL;
271:
272: /* This one turns off screen updates. */
273: case SCANCODE_scrolllock: return AK_inhibit;
274:
275: #if 0 /* No unique scancode for these yet. I need a Win95 keyboard :-( */
276: case SCANCODE_NEXT: return AK_RAMI; /* PgUp mapped to right amiga */
277: case SCANCODE_PRIOR: return AK_LAMI; /* PgDn mapped to left amiga */
278: #endif
279:
280: /*#ifdef KBD_LANG_DE*/
281: case SCANCODE_numbersign: return AK_NUMBERSIGN;
282: case SCANCODE_ltgt: return AK_LTGT;
283: /*#endif*/
284: }
285: return -1;
286: }
287:
288: static void my_kbd_handler(int scancode, int newstate)
289: {
290: int akey = scancode2amiga(scancode);
291:
292: assert(scancode >= 0 && scancode < 0x100);
293: if (scancode == SCANCODE_F12)
294: specialflags |= SPCFLAG_BRK;
295: if (keystate[scancode] == newstate)
296: return;
297: keystate[scancode] = newstate;
298:
299: if (akey == -1)
300: return;
301:
302: if (newstate == KEY_EVENTPRESS) {
303: if (akey == AK_inhibit)
304: inhibit_frame ^= 1;
305: else
306: record_key (akey << 1);
307: } else
308: record_key ((akey << 1) | 1);
309:
310: /* "Affengriff" */
311: if(keystate[AK_CTRL] && keystate[AK_LAMI] && keystate[AK_RAMI])
312: MC68000_reset();
313: }
314:
315: void graphics_init(void)
316: {
317: int i;
318:
319: vga_init();
320: vga_setmousesupport(1);
321: mouse_init("/dev/mouse",vga_getmousetype(),10);
322: #ifdef SVGALIB_8BIT_SCREEN
323: vga_setmode(SVGALIB_MODE_8);
324: #endif
325: #ifdef SVGALIB_16BIT_SCREEN
326: vga_setmode(SVGALIB_MODE_16);
327: #endif
328: if (keyboard_init() != 0)
329: abort();
330: keyboard_seteventhandler(my_kbd_handler);
331:
332: init_colors();
333:
334: buttonstate[0] = buttonstate[1] = buttonstate[2] = false;
335: for(i = 0; i < 256; i++)
336: keystate[i] = false;
337:
338: lastmx = lastmy = 0; newmousecounters = false;
339:
340: mouse_setxrange(-1000,1000);
341: mouse_setyrange(-1000,1000);
342: mouse_setposition(0,0);
343: }
344:
345: void graphics_leave(void)
346: {
347: sleep(1); /* Maybe this will fix the "screen full of garbage" problem */
348: vga_setmode(TEXT);
349: keyboard_close();
350: }
351:
352: void handle_events(void)
353: {
354: int button = mouse_getbutton();
355:
356: keyboard_update();
357: mouse_update();
358: lastmx += mouse_getx();
359: lastmy += mouse_gety();
360: mouse_setposition(0,0);
361:
362: buttonstate[0] = button & 4;
363: buttonstate[1] = button & 2;
364: buttonstate[2] = button & 1;
365: }
366:
367: bool debuggable(void)
368: {
369: return false;
370: }
371:
372: bool needmousehack(void)
373: {
374: return false;
375: }
376:
377: void LED(int on)
378: {
379: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.