|
|
1.1 root 1: /*
2: * UAE - The Un*x Amiga Emulator
3: *
4: * GGI - Interface
5: *
6: * Always remember: "GGI - The right thing to do[tm]"
7: *
8: * Copyright 1997 Christian Schmitt <[email protected]>,
9: * Stefan Reinauer <[email protected]>
10: */
11:
12: #include "sysconfig.h"
13: #include "sysdeps.h"
14:
15: #include <stdio.h>
16: #include <stdlib.h>
17: #include <time.h>
18: #include <unistd.h>
19: #include <ggi/libggi.h>
20: #include <ggi/libggi_db.h>
21: #include <ggi/events.h>
22: #include <string.h>
23:
24: #include "config.h"
25: #include "options.h"
26: #include "threaddep/penguin.h"
27: #include "uae.h"
28: #include "memory.h"
29: #include "custom.h"
30: #include "readcpu.h"
31: #include "newcpu.h"
32: #include "keyboard.h"
33: #include "xwin.h"
34: #include "keybuf.h"
35: #include "gui.h"
36: #include "picasso96.h"
37:
38: static ggi_visual_t vis;
39: static ggi_graphtype amiga_modetype;
40: static unsigned char pack[256];
41: static uae_u8 dither_buf[1000];
42: int buttonstate[3] = {0, 0, 0};
43: int lastmx,lastmy,newmousecounters=0;
44: static int keystate[256];
45:
46: int need_dither,bpp;
47: void *linear=NULL;
48:
49: static int screen_is_picasso;
50: static char picasso_invalid_lines[1200];
51: static ggi_graphtype picasso_modetype;
52:
53: struct bstring *video_mode_menu = NULL;
54:
55: /* We don't need a brkhandler with GGI */
56: void setup_brkhandler(void)
57: {
58: }
59:
60: #define MAX_SCREEN_MODES 6
61: #define MAX_GGI_COLOR_MODES 4
62:
63: int x_size_table[MAX_SCREEN_MODES]={320,640,640,800,1024,1152};
64: int y_size_table[MAX_SCREEN_MODES]={200,400,480,600,768,864};
65: ggi_graphtype color_table[MAX_GGI_COLOR_MODES]=
66: {GT_4BIT,GT_8BIT,GT_16BIT,GT_32BIT};
67:
68: static struct ggi_graphmodes{
69: int x;
70: int y;
71: int col;
72: struct ggi_graphmodes *next;
73: } got_modes;
74:
75:
76: int graphics_setup(void)
77: {
78: struct ggi_graphmodes *dummy;
79: int count=0;
80: char buf[80];
81: int i,j,c=0;
82:
83: ggiInit();
84:
85: if((vis=ggiOpen(NULL))==NULL) {
86: fprintf(stderr,"Can't open Visual\n");
87: return 0;
88: }
89:
90: for(i=0;i<MAX_SCREEN_MODES;i++) {
91: for(j=0;j<MAX_GGI_COLOR_MODES;j++) {
92: if (ggiCheckGraphMode(vis, x_size_table[i], y_size_table[i],
93: x_size_table[i], y_size_table[i],
1.1.1.2 ! root 94: color_table[j],NULL,NULL) != 0)
1.1 root 95: continue;
96:
97: dummy=(struct ggi_graphmodes *)malloc(sizeof(struct ggi_graphmodes));
98: dummy->x=x_size_table[i];
99: dummy->y=y_size_table[i];
100: switch(color_table[j]) {
101: case GT_4BIT : c=4;break;
102: case GT_8BIT : c=8;break;
103: case GT_16BIT : c=16;break;
104: case GT_32BIT : c=32;break;
105: default : break; /* Ups */
106: }
107: dummy->col=c;
108: dummy->next=got_modes.next;
109: got_modes.next=dummy;
110: count++;
111: }
112: }
113: count++;
114: video_mode_menu = (struct bstring *)malloc(sizeof (struct bstring)*count);
115: memset(video_mode_menu, 0, sizeof (struct bstring)*count);
116: dummy=got_modes.next;
117: for (i = 0; i < count - 1; i++) {
118: sprintf(buf, "%3dx%d, %2d Bit", dummy->x, dummy->y,dummy->col);
119: video_mode_menu[i].val = -1;
120: video_mode_menu[i].data = strdup(buf);
121: dummy = dummy->next;
122: }
123: video_mode_menu[count-1].val = -3;
124: video_mode_menu[count-1].data = NULL;
125: return 1;
126: }
127:
128: void vidmode_menu_selected(int m)
129: {
130: int i;
131: struct ggi_graphmodes *dummy=got_modes.next;
132: for(i=1;i<=m;i++) dummy=dummy->next;
133: currprefs.gfx_width = dummy->x;
134: currprefs.gfx_height = dummy->y;
135: currprefs.color_mode = dummy->col == 32 ? 5 : dummy->col == 16 ? 2 : 0;
136: }
137:
138: static int colors_allocated;
139: static ggi_color map[256];
140: static ggi_color vga_map[256];
141:
142: static void restore_vga_colors (void)
143: {
144: int i;
145: if (gfxvidinfo.pixbytes != 1)
146: return;
147: memcpy (map, vga_map, sizeof map);
148: ggiSetPaletteVec(vis, 0, colors_allocated, map);
149: }
150:
151: static int get_color(int r, int g, int b, xcolnr *cnp)
152: {
153: if(colors_allocated == 255)
154: return -1;
155: *cnp = colors_allocated;
156: map[colors_allocated].r = doMask (r,16,0);
157: map[colors_allocated].g = doMask (g,16,0);
158: map[colors_allocated].b = doMask (b,16,0);
159:
160: colors_allocated++;
161: return 1;
162: }
163:
164: static void init_colors(void)
165: {
166: if (need_dither) {
167: setup_dither (8, get_color);
168: } else {
169: int i;
170: colors_allocated = 0;
171: gfxvidinfo.can_double = 0;
172: switch (bpp){
173: case 8:
174: alloc_colors256 (get_color);
175: ggiSetPaletteVec (vis, 0, colors_allocated, map);
176: memcpy (vga_map, map, sizeof vga_map);
177: for (i = 0; i < 4096;i++)
178: xcolors[i] *= 0x01010101;
179: gfxvidinfo.can_double=1;
180: break;
181: case 16:
182: alloc_colors64k (5, 6, 5, 11, 5, 0);
183: for(i = 0; i < 4096; i++)
184: xcolors[i] *= 0x00010001;
185: gfxvidinfo.can_double=1;
186: break;
187: case 32:
188: alloc_colors64k(8, 8, 8, 16, 8, 0);
189: break;
190: default:
191: break;
192: }
193: }
194: }
195:
196: static int set_amiga_mode (void)
197: {
198: int sx = gfxvidinfo.width;
199: int sy = gfxvidinfo.height;
200: ggi_directbuffer_t gbuf=NULL;
201: ggi_pixellinearbuffer *plb;
202:
203: if (ggiSetGraphMode (vis, sx, sy, sx, sy, amiga_modetype) != 0) {
204: fprintf(stderr,"Can't set graphics mode\n");
205: return 0;
206: }
207: ggiDBGetBuffer(vis,&gbuf);
208: plb=ggiDBGetPLB(gbuf);
209: linear = plb->write;
210: return 1;
211: }
212:
213: int graphics_init (void) /* See how simple it is? :-> */
214: {
215: int err,i;
216:
217: switch(currprefs.color_mode) {
218: case 0:
219: amiga_modetype = GT_8BIT;
220: need_dither = 0;
221: break;
222: case 1:
223: case 2:
224: amiga_modetype = GT_16BIT;
225: need_dither = 0;
226: break;
227: case 3:
228: amiga_modetype = GT_8BIT;
229: need_dither = 1;
230: break;
231: case 4:
232: amiga_modetype = GT_4BIT;
233: need_dither = 1;
234: break;
235: default:
236: fprintf(stderr, "Bad color mode selected. Using default.\n");
237: currprefs.color_mode = 0;
238: amiga_modetype = GT_8BIT;
239: break;
240: }
241:
242: gfxvidinfo.width = currprefs.gfx_width;
243: gfxvidinfo.height = currprefs.gfx_height;
244:
245: if (! set_amiga_mode ())
246: return 0;
247:
248: bpp = ggiGetBPP (vis);
249:
250: gfxvidinfo.pixbytes = bpp >> 3;
251: gfxvidinfo.rowbytes = gfxvidinfo.pixbytes * currprefs.gfx_width;
252: if (linear != NULL)
253: gfxvidinfo.bufmem = linear;
254: else
255: gfxvidinfo.bufmem = (char *)malloc (gfxvidinfo.rowbytes * currprefs.gfx_height);
256: gfxvidinfo.maxblocklines = 0;
257: memset (gfxvidinfo.bufmem, 0, gfxvidinfo.rowbytes * currprefs.gfx_height);
258:
259: screen_is_picasso = 0;
260:
261: for (i = 0; i < 256; i++) {
262: map[i].r=i;
263: map[i].g=i;
264: map[i].b=i;
265: }
266: ggiPackColors(vis, pack, map, 256);
267: init_colors ();
268:
269: buttonstate[0] = buttonstate[1] = buttonstate[2] = 0;
270: for (i = 0; i < 256; i++)
271: keystate[i] = 0;
272: lastmx = lastmy = 0;
273: return 1;
274: }
275:
276: void graphics_leave(void)
277: {
278: ggiClose (vis);
279: ggiExit ();
280: }
281:
282: void flush_line(int y)
283: {
284: int target_y = y;
285: int bit_unit=8;
286: int i=0;
287: char *addr;
288:
289: if (linear != NULL && !need_dither)
290: return;
291:
292: addr = gfxvidinfo.bufmem + y*gfxvidinfo.rowbytes;
293: if (target_y < 400 && target_y >= 0) {
294: if (need_dither) {
295: if (linear == NULL){
296: DitherLine (dither_buf, (uae_u16 *)addr, 0, y,
297: gfxvidinfo.width, bit_unit);
298: addr = dither_buf;
299: ggiPutHLine (vis, 0, target_y, gfxvidinfo.width, addr);
300: } else {
301: DitherLine (linear + gfxvidinfo.rowbytes*y, (uae_u16 *)addr, 0, y,
302: gfxvidinfo.width, bit_unit);
303: }
304: return;
305: }
306: if(linear==NULL)
307: ggiPutHLine(vis, 0, target_y, gfxvidinfo.width, addr);
308: }
309: }
310:
311: void flush_block(int a, int b){};
312: void flush_screen(int a, int b){};
313:
314: #define KEY_NOTHING 0x00
315: #define AK_QUIT 0xf00
316:
317: /* We should not need to have different versions for different keyboard */
318: static short decodekey[128]={
319: KEY_NOTHING, /* 0 */
320: AK_ESC,
321: AK_1, AK_2, AK_3, AK_4, AK_5, AK_6, AK_7, AK_8, AK_9, AK_0,
322: AK_MINUS, /* 12 */
323: AK_EQUAL,
324: AK_BS,
325: AK_TAB, /* 0x0f */
326: AK_Q, AK_W, AK_E, AK_R, AK_T,
327: AK_Y, /* 0x15 Attention: language specific !!!! */
328: AK_U, AK_I, AK_O, AK_P, AK_LBRACKET,
329: AK_RBRACKET, /* 0x1b */
330: AK_RET,
331: AK_CTRL,
332: AK_A, AK_S, AK_D, AK_F, AK_G, AK_H, AK_J, AK_K, AK_L,
333: AK_SEMICOLON, /* 0x27 */
334: AK_QUOTE, /* ä 0x28 */
335: KEY_NOTHING,
336: AK_LSH, /* 0x2a */
337: AK_LTGT, /* < 0x2b Attention: language specific !!!! */
338: AK_Z, /* 0x2c Attention: language specific !!!! */
339: AK_X, AK_C, AK_V, AK_B, AK_N, AK_M, AK_COMMA, AK_PERIOD,
340: AK_SLASH, /* 0x35 */
341: AK_RSH, /* 0x36 */
342: AK_NPMUL,
343: AK_LALT,
344: AK_SPC,
345: AK_CAPSLOCK, /* 0x3a */
346: AK_F1, AK_F2, AK_F3, AK_F4, AK_F5, AK_F6, AK_F7, AK_F8, AK_F9,
347: AK_F10, /* 0x44 */
348: KEY_NOTHING, /* NumLock */
349: KEY_NOTHING, /* "Rollen" */
350: AK_NP7, /* 0x47 */
351: AK_NP8,
352: AK_NP9,
353: AK_NPSUB, /* 0x4a */
354: AK_NP4,
355: AK_NP5,
356: AK_NP6,
357: AK_NPADD, /* 0x4e */
358: AK_NP1,
359: AK_NP2,
360: AK_NP3,
361: AK_NP0, /* 0x52 */
362: AK_NPDEL,
363: KEY_NOTHING, /* ??? */
364: KEY_NOTHING, /* ??? */
365: KEY_NOTHING, /* ??? */
366: AK_BS, /* 0x57 --> F11 */
367: AK_QUIT, /* 0x58 --> F12 */
368: KEY_NOTHING, /* ??? */
369: KEY_NOTHING, /* ??? */
370: KEY_NOTHING, /* ??? */
371: KEY_NOTHING, /* ??? */
372: KEY_NOTHING, /* ??? */
373: KEY_NOTHING, /* ??? */
374: KEY_NOTHING, /* ??? */
375: AK_ENT, /* 0x60 */
376: AK_RCTRL, /* 0x61 */
377: AK_NPDIV,
378: KEY_NOTHING,
379: AK_RALT, /* 0x64 */
380: KEY_NOTHING, /* ??? */
381: AK_NP7, /* Pos1 */
382: AK_UP, /* 0x67 */
383: AK_LAMI, /* 0x68 --> PgUp, */
384: AK_LF, /* 0x69 */
385: AK_RT, /* 0x6a */
386: AK_NP1, /* End */
387: AK_DN, /* 0x6c */
388: AK_RAMI, /* --> PgDown */
389: AK_HELP, /* 0x6e --> insert */
390: AK_DEL,
391: KEY_NOTHING,
392: KEY_NOTHING,
393: KEY_NOTHING,
394: KEY_NOTHING,
395: KEY_NOTHING,
396: KEY_NOTHING,
397: KEY_NOTHING,
398: KEY_NOTHING, /* 0x77 --> Pause */
399: KEY_NOTHING,
400: KEY_NOTHING,
401: KEY_NOTHING,
402: KEY_NOTHING,
403: KEY_NOTHING,
404: AK_LAMI, /* 0x7d --> WindOoze left */
405: AK_RAMI, /* --> WindOoze right */
406: AK_CTRL /* 0x7f --> WindOoze Menu */
407: };
408:
409: void handle_events (void)
410: {
411: struct timeval t={0,1};
412: ggi_event ev;
413: ggi_event_mask mask;
414: int akey;
415: uint32 state=0,button=0;
416: while(ggiEventPoll(vis,emPtrButton|emPtrRelative|emKey,&t)) {
417: ggiEventRead(vis,&ev,emPtrButton|emPtrRelative|emKey);
418: switch(ev.any.type){
419: case evPtrButtonPress:
420: case evPtrButtonRelease:
421: state=ev.pbutton.state;
422: button=ev.pbutton.button;
423: switch(button) {
1.1.1.2 ! root 424: case 1 : buttonstate[0]=state&button;break;
! 425: case 2 : buttonstate[2]=(state&button)>>1;break;
1.1 root 426: case 4 : buttonstate[1]=(state&button)>>2;break;
427: default: break;
428: }
429: break;
430: case evPtrRelative:
431: lastmx+=ev.pmove.x;
432: lastmy+=ev.pmove.y;
433: break;
434: case evKeyPress:
435: case evKeyRelease:
436: if(ev.key.sym==0) continue;
437: if(ev.key.code>128) return;
438: akey=decodekey[ev.key.code];
439: if(akey==0xf00) uae_quit();
440: if(keystate[AK_CTRL] && keystate[AK_LAMI] && keystate[AK_RAMI])
441: m68k_reset();
442: switch(ev.key.type) {
443: case 6 : keystate[akey]=0;
444: record_key((akey << 1) | 1);
445: break;
446: case 5 : if(akey==KEY_NOTHING) break;
447: if(!keystate[akey]) {
448: keystate[akey]=1;
449: record_key(akey << 1);
450: }
451: break;
452: default : break;
453: }
454: default:
1.1.1.2 ! root 455: /* printf("Ugh\n");*/
1.1 root 456: }
457: }
458:
459:
460:
461: #ifdef PICASSO96
462: if (screen_is_picasso && !picasso_vidinfo.extra_mem) {
463: int i;
464: char *addr = gfxmemory + (picasso96_state.Address - gfxmem_start);
465: for (i = 0; i < picasso_vidinfo.height; i++, addr += picasso96_state.BytesPerRow) {
466: if (!picasso_invalid_lines[i])
467: continue;
468: picasso_invalid_lines[i] = 0;
469: ggiPutHLine (vis, 0, i, gfxvidinfo.width, addr);
470: }
471: }
472: #endif
473:
474: return;
475: }
476:
1.1.1.2 ! root 477: int check_prefs_changed_gfx (void)
1.1 root 478: {
1.1.1.2 ! root 479: return 0;
1.1 root 480: }
481:
482: int debuggable(void)
483: {
1.1.1.2 ! root 484: return 0;
1.1 root 485: }
486:
487: int needmousehack(void)
488: {
1.1.1.2 ! root 489: return 0;
1.1 root 490: }
491:
492: /* This is not implemented yet as GGI is not that far */
493: void LED(int on)
494: {
495: }
496:
497: #ifdef PICASSO96
498:
499: void DX_Invalidate (int first, int last)
500: {
501: do {
502: picasso_invalid_lines[first] = 1;
503: first++;
504: } while (first <= last);
505: }
506:
507: int DX_BitsPerCannon (void)
508: {
509: return 8;
510: }
511:
512: void DX_SetPalette(int start, int count)
513: {
514: int i;
515:
516: if (!screen_is_picasso || picasso_vidinfo.pixbytes != 1)
517: return;
518:
519: fprintf (stderr, "DX_SetPalette\n");
520:
521: for (i = 0; i < count; i++) {
522: map[start + i].r = picasso96_state.CLUT[start + i].Red * 0x0101;
523: map[start + i].g = picasso96_state.CLUT[start + i].Green * 0x0101;
524: map[start + i].b = picasso96_state.CLUT[start + i].Blue * 0x0101;
525: }
526: ggiSetPaletteVec (vis, start, count, map + start);
527: }
528:
529: int DX_FillResolutions (uae_u16 *ppixel_format)
530: {
531: int i, count = 0;
532: uae_u16 format = 0;
533:
534: for (i = 0; i < MAX_SCREEN_MODES; i++) {
535: if (ggiCheckGraphMode (vis, x_size_table[i], y_size_table[i],
536: x_size_table[i], y_size_table[i],
1.1.1.2 ! root 537: GT_8BIT,NULL,NULL) == 0) {
1.1 root 538: DisplayModes[count].res.width = x_size_table[i];
539: DisplayModes[count].res.height = y_size_table[i];
540: DisplayModes[count].depth = 1;
541: DisplayModes[count].refresh = 75;
542: count++;
543: format |= RGBFF_CHUNKY;
544: }
545: if (ggiCheckGraphMode (vis, x_size_table[i], y_size_table[i],
546: x_size_table[i], y_size_table[i],
1.1.1.2 ! root 547: GT_16BIT,NULL,NULL) == 0) {
1.1 root 548: DisplayModes[count].res.width = x_size_table[i];
549: DisplayModes[count].res.height = y_size_table[i];
550: DisplayModes[count].depth = 2;
551: DisplayModes[count].refresh = 75;
552: count++;
553: format |= RGBFF_R5G6B5PC;
554: }
555: if (ggiCheckGraphMode (vis, x_size_table[i], y_size_table[i],
556: x_size_table[i], y_size_table[i],
1.1.1.2 ! root 557: GT_32BIT,NULL,NULL) == 0) {
1.1 root 558: DisplayModes[count].res.width = x_size_table[i];
559: DisplayModes[count].res.height = y_size_table[i];
560: DisplayModes[count].depth = 4;
561: DisplayModes[count].refresh = 75;
562: count++;
563: format |= RGBFF_B8G8R8A8;
564: }
565: }
566:
567: *ppixel_format = format;
568: return count;
569: }
570:
571: static void set_window_for_picasso (void)
572: {
573: int sx, sy;
574: ggi_directbuffer_t gbuf=NULL;
575: ggi_pixellinearbuffer *plb;
576:
577: sx = picasso_vidinfo.width;
578: sy = picasso_vidinfo.height;
579: fprintf (stderr, "picasso mode %d %d %d!\n", sx, sy, picasso_modetype);
580: if (ggiSetGraphMode (vis, sx, sy, sx, sy, picasso_modetype) != 0) {
581: fprintf (stderr,"Can't set graphics mode\n");
582: abort ();
583: }
584: fprintf (stderr, "picasso mode ok!\n");
585:
586: ggiDBGetBuffer(vis,&gbuf);
587: plb=ggiDBGetPLB(gbuf);
588: linear = plb->write;
589:
590: if (linear != NULL)
591: picasso_vidinfo.extra_mem = 1;
592: else
593: picasso_vidinfo.extra_mem = 0;
594: fprintf (stderr, "em: %d\n", picasso_vidinfo.extra_mem);
595: DX_SetPalette (0, 256);
596: }
597:
598: static void set_window_for_amiga (void)
599: {
600: set_amiga_mode ();
601: if (linear != NULL && !need_dither)
602: gfxvidinfo.bufmem = linear;
603:
604: restore_vga_colors ();
605: }
606:
607: void gfx_set_picasso_modeinfo (int w, int h, int depth)
608: {
609: fprintf (stderr, "set_picasso_modeinfo\n");
610: picasso_vidinfo.width = w;
611: picasso_vidinfo.height = h;
612: picasso_vidinfo.depth = depth;
613: picasso_vidinfo.pixbytes = depth >> 3;
1.1.1.2 ! root 614: picasso_vidinfo.rowbytes = w * picasso_vidinfo.pixbytes;
1.1 root 615: picasso_modetype = (depth == 8 ? GT_8BIT
616: : depth == 16 ? GT_16BIT
617: : GT_32BIT);
618: if (screen_is_picasso)
619: set_window_for_picasso ();
620: }
621:
622: void gfx_set_picasso_baseaddr (uaecptr a)
623: {
624: }
625:
626: void gfx_set_picasso_state (int on)
627: {
628: if (on == screen_is_picasso)
629: return;
630: fprintf (stderr, "set_picasso_state\n");
631: screen_is_picasso = on;
632: if (on)
633: set_window_for_picasso ();
634: else
635: set_window_for_amiga ();
636: }
637:
1.1.1.2 ! root 638: uae_u8 *gfx_lock_picasso (void)
1.1 root 639: {
640: return linear;
641: }
1.1.1.2 ! root 642: void gfx_unlock_picasso (void)
1.1 root 643: {
644: }
645: #endif
1.1.1.2 ! root 646:
! 647: int lockscr (void)
! 648: {
! 649: return 1;
! 650: }
! 651:
! 652: void unlockscr (void)
! 653: {
! 654: }
! 655:
! 656:
! 657:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.