|
|
1.1 root 1: /*
2: * UAE - The Un*x Amiga Emulator
3: *
4: * Mac port specific stuff
5: *
6: * (c) 1996 Ernesto Corvi
7: */
8:
9: #include <stdio.h>
10: #include <stdlib.h>
11: #include <string.h>
12: #include <QDOffscreen.h>
13: #include <Palettes.h>
14: #include <Profiler.h>
15:
16: #include "mackbd.h"
17: #include "config.h"
18: #include "amiga.h"
19: #include "options.h"
20: #include "memory.h"
21: #include "custom.h"
22: #include "newcpu.h"
23: #include "xwin.h"
24: #include "keyboard.h"
25: #include "keybuf.h"
26:
27: #define kQuitError 128
28:
29: extern bool left, right, top, bot, but;
30:
31: KeyMap keys,keysold;
32: GDHandle curDevice;
33: int oldDepth=0;
34: static int screen;
35: Boolean RM=false,Joy=false;
36: WindowPtr mywin;
37: short gOldMBarHeight;
38: RgnHandle gMBarRgn;
39: static int bitdepth;
40: KeyMap theKeys;
41:
42: unsigned long refresh;
43: char *xlinebuffer;
44: unsigned int *obuff;
45: long int xcolors[4096];
46:
47: /* Keyboard and mouse */
48:
49: static bool keystate[256];
50:
51: bool buttonstate[3];
52: int lastmx, lastmy;
53: bool newmousecounters;
54: static bool inwindow;
55:
56: int GetRawCode (long set0, long set1, long set2, long set3);
57:
58: static inline unsigned long doMask(int p, int bits, int shift)
59: {
60: /* p is a value from 0 to 15 (Amiga color value)
61: * scale to 0..255, shift to align msb with mask, and apply mask */
62:
63: unsigned long val = p * 0x11111111UL;
64: val >>= (32 - bits);
65: val <<= shift;
66:
67: return val;
68: }
69:
70: static void InitXColors(void)
71: {
72: int n=16;
73: int red_bits = 5;
74: int green_bits = 5;
75: int blue_bits = 5;
76: int red_shift = 10;
77: int green_shift = 5;
78: int blue_shift = 0;
79: int i=0;
80: int r,g,b;
81:
82: for(i = 0; i < 4096; i++) {
83: r = i >> 8;
84: g = (i >> 4) & 0xF;
85: b = i & 0xF;
86: xcolors[i] = (doMask(r, red_bits, red_shift)
87: | doMask(g, green_bits, green_shift)
88: | doMask(b, blue_bits, blue_shift));
89: }
90: }
91:
92: static void InitToolbox(void)
93: {
94: InitGraf (&qd.thePort);
95: InitFonts ();
96: FlushEvents (everyEvent,0);
97: InitWindows ();
98: InitMenus ();
99: TEInit ();
100: InitDialogs (nil);
101: InitCursor ();
102: }
103:
104: static void HideMenuBar(void)
105: {
106: Rect mBarRect;
107:
108: /* GET RID OF THE MENU BAR */
109:
110: gOldMBarHeight = GetMBarHeight();
111: /* make the Menu Bar's height zero */
112: LMSetMBarHeight(0);
113: SetRect(&mBarRect, qd.screenBits.bounds.left, qd.screenBits.bounds.top,
114: qd.screenBits.bounds.right, qd.screenBits.bounds.top + gOldMBarHeight);
115: gMBarRgn = NewRgn();
116: RectRgn(gMBarRgn, &mBarRect);
117: UnionRgn(LMGetGrayRgn(), gMBarRgn, LMGetGrayRgn()); /* tell the desktop it covers the menu bar */
118:
119: PaintOne(nil, gMBarRgn); /* redraw desktop */
120: }
121:
122: static void ShowMenuBar(void)
123: {
124: LMSetMBarHeight(gOldMBarHeight); /* make the menu bar's height normal */
125: DiffRgn(LMGetGrayRgn(), gMBarRgn, LMGetGrayRgn()); /* remove the menu bar from the desktop */
126: DisposeRgn(gMBarRgn);
127: }
128:
129: void graphics_init()
130: { int i;
131: long p1;
132: long tmp;
133:
134: Rect windowRectangle={0,0,480,640};
135: InitToolbox();
136:
137: if (CheckForSetup()) ExitToShell();
138:
139: HideMenuBar();
140: mywin = NewCWindow(nil, &windowRectangle, "\pUAE", true, 2, (WindowPtr)-1L, false, 0);
141: SetPort(mywin);
142:
143: PaintRect(&qd.screenBits.bounds);
144:
145: xlinebuffer = (char *)malloc (3200);
146: InitXColors();
147: buttonstate[0] = buttonstate[1] = buttonstate[2] = false;
148: for(i=0; i<256; i++) keystate[i] = false;
149:
150: lastmx = lastmy = 0; newmousecounters = false; inwindow = false;
151:
152: obuff=(unsigned int *)NewPtrClear(481*1280);
153: {
154: for(p1=0;p1 < (480*1280);p1++)
155: *obuff=-1;
156: }
157:
158: HideCursor();
159: refresh=TickCount();
160:
161: /* tmp=ProfilerInit(collectDetailed,bestTimeBase,200,10); */
162: }
163:
164: void graphics_leave()
165: {
166: /* ProfilerDump((unsigned char *)"\pmyProf");
167: ProfilerTerm();
168: */
169: DisposeWindow(mywin);
170: ShowCursor();
171: if (oldDepth != 0) SetDepth(curDevice,oldDepth,0,0);
172: ShowMenuBar();
173: FlushEvents (everyEvent,0);
174: ExitToShell();
175: }
176:
177: static bool next_line_double;
178: static int next_line_pos = 0;
179:
180: void flush_screen ()
181: {
182: GrafPtr oldPort;
183: short y,x,daColor=0;
184: RGBColor daColorRGB;
185: unsigned char *winbaseaddr;
186: double *src,*dest;
187: unsigned long winrowbytes;
188: PixMapHandle ph;
189:
190: if (TickCount() < refresh + 4) return;
191: GetPort(&oldPort);
192: SetPort(mywin);
193:
194: ph=GetGWorldPixMap((CGrafPort *) mywin);
195: LockPixels(ph);
196: winbaseaddr=( unsigned char *) GetPixBaseAddr(ph);
197: winrowbytes=(*ph)->rowBytes & 0x3FFF;
198: winbaseaddr-=((**ph).bounds.left);
199: winbaseaddr-=((**ph).bounds.top*winrowbytes);
200: dest=(double *)winbaseaddr;
201: src=(double *)obuff;
202:
203: for (y=1; y< 480; y++)
204: {
205: for (x=0;x < 160;x++)
206: {
207: *dest++ = *src++;
208: }
209: dest=(double *)(winbaseaddr+(y*winrowbytes));
210: }
211: UnlockPixels(ph);
212: SetPort(oldPort);
213:
214: }
215:
216: void prepare_line (int y, bool need_double)
217: {
218: next_line_double = need_double;
219: next_line_pos = y;
220: }
221:
222: void flush_line()
223: {
224: short i;
225: char *dst,*src;
226: double *dst1,*src1;
227:
228: if ((next_line_pos < 508) && (next_line_pos > 28))
229: {
230: dst=(char *)obuff+((next_line_pos-28)*1280);
231: src=(char *)xlinebuffer+292;
232: BlockMove(src,dst,1280);
233: }
234: if (next_line_double)
235: {
236: if ((next_line_pos+1 < 508) && (next_line_pos+1 > 28))
237: {
238: dst1=(double *)obuff+((next_line_pos+1-28)*160);
239: src1=(double *)obuff+((next_line_pos-28)*160);
240: for (i=0;i < 160;i++)
241: {
242: *dst1++=*src1++;
243: }
244: }
245: }
246: }
247:
248: /* Decode KeySyms. This function knows about all keys that are common
249: * between different keyboard languages.
250: */
251: static int kc_decode (long ks)
252: {
253: switch (ks)
254: {
255: case kAKeyMap: return AK_A;
256: case kBKeyMap: return AK_B;
257: case kCKeyMap: return AK_C;
258: case kDKeyMap: return AK_D;
259: case kEKeyMap: return AK_E;
260: case kFKeyMap: return AK_F;
261: case kGKeyMap: return AK_G;
262: case kHKeyMap: return AK_H;
263: case kIKeyMap: return AK_I;
264: case kJKeyMap: return AK_J;
265: case kKKeyMap: return AK_K;
266: case kLKeyMap: return AK_L;
267: case kMKeyMap: return AK_M;
268: case kNKeyMap: return AK_N;
269: case kOKeyMap: return AK_O;
270: case kPKeyMap: return AK_P;
271: case kQKeyMap: return AK_Q;
272: case kRKeyMap: return AK_R;
273: case kSKeyMap: return AK_S;
274: case kTKeyMap: return AK_T;
275: case kUKeyMap: return AK_U;
276: case kVKeyMap: return AK_V;
277: case kWKeyMap: return AK_W;
278: case kXKeyMap: return AK_X;
279:
280: case k0KeyMap: return AK_0;
281: case k1KeyMap: return AK_1;
282: case k2KeyMap: return AK_2;
283: case k3KeyMap: return AK_3;
284: case k4KeyMap: return AK_4;
285: case k5KeyMap: return AK_5;
286: case k6KeyMap: return AK_6;
287: case k7KeyMap: return AK_7;
288: case k8KeyMap: return AK_8;
289: case k9KeyMap: return AK_9;
290:
291: case kKP0KeyMap: return AK_NP0;
292: case kKP1KeyMap: return AK_NP1;
293: case kKP2KeyMap: return AK_NP2;
294: case kKP3KeyMap: return AK_NP3;
295: case kKP4KeyMap: return AK_NP4;
296: case kKP5KeyMap: return AK_NP5;
297: case kKP6KeyMap: return AK_NP6;
298: case kKP7KeyMap: return AK_NP7;
299: case kKP8KeyMap: return AK_NP8;
300: case kKP9KeyMap: return AK_NP9;
301:
302: case kF1KeyMap: return AK_F1;
303: case kF2KeyMap: return AK_F2;
304: case kF3KeyMap: return AK_F3;
305: case kF4KeyMap: return AK_F4;
306: case kF5KeyMap: return AK_F5;
307: case kF6KeyMap: return AK_F6;
308: case kF7KeyMap: return AK_F7;
309: case kF8KeyMap: return AK_F8;
310: case kF9KeyMap: return AK_F9;
311: case kF10KeyMap: return AK_F10;
312:
313: case kBackSpaceKeyMap: return AK_BS;
314: case kTabKeyMap: return AK_TAB;
315: case kReturnKeyMap: return AK_RET;
316: case kEscapeKeyMap: return AK_ESC;
317:
318: case kSpaceBarMap: if (Joy) return -1; else return AK_SPC;
319:
320: case kUpArrowKeyMap: if (Joy) return -1; else return AK_UP;
321: case kDownArrowKeyMap: if (Joy) return -1; else return AK_DN;
322: case kLeftArrowKeyMap: if (Joy) return -1; else return AK_LF;
323: case kRightArrowKeyMap: if (Joy) return -1; else return AK_RT;
324:
325: case kF11KeyMap: graphics_leave();
326: case kF12KeyMap: { Joy=!Joy; SysBeep(0); return -1; }
327:
328: case kPgUpKeyMap: return AK_RAMI;
329: case kPgDnKeyMap: return AK_LAMI;
330: case kBackSlash: return AK_BACKSLASH;
331: }
332: return -1;
333: }
334:
335: static int decode_us(long ks)
336: {
337: switch(ks) {
338: /* US specific */
339:
340: case kYKeyMap: return AK_Y;
341: case kZKeyMap: return AK_Z;
342: case kLBracketKeyMap: return AK_LBRACKET;
343: case kRBracketKeyMap: return AK_RBRACKET;
344: case kCommaKeyMap: return AK_COMMA;
345: case kPeriodKeyMap: return AK_PERIOD;
346: case kSlashKeyMap: return AK_SLASH;
347: case kSemiColonKeyMap: return AK_SEMICOLON;
348: case kMinusKeyMap: return AK_MINUS;
349: case kEqualKeyMap: return AK_EQUAL;
350: case kQuoteKeyMap: return AK_QUOTE;
351: }
352:
353: return -1;
354: }
355:
356: static int decode_de(long ks)
357: {
358: switch(ks) {
359: /* DE specific
360: case XK_Y: case XK_y: return AK_Z;
361: case XK_Z: case XK_z: return AK_Y;
362: case XK_Odiaeresis: case XK_odiaeresis: return AK_SEMICOLON;
363: case XK_Adiaeresis: case XK_adiaeresis: return AK_QUOTE;
364: case XK_Udiaeresis: case XK_udiaeresis: return AK_LBRACKET;
365: case XK_plus: case XK_asterisk: return AK_RBRACKET;
366: case XK_comma: return AK_COMMA;
367: case XK_period: return AK_PERIOD;
368: case XK_less: case XK_greater: return AK_LTGT;
369: case XK_numbersign: return AK_NUMBERSIGN;
370: case XK_ssharp: return AK_MINUS;
371: case XK_apostrophe: return AK_EQUAL;
372: case XK_asciicircum: return AK_00;
373: case XK_minus: return AK_SLASH;
374: */
375: }
376:
377: return -1;
378: }
379:
380: static int keycode2amiga(long code)
381: {
382: long ks;
383: int as;
384:
385: ks = (code & keyCodeMask) >> 8;
386: as = kc_decode (ks);
387:
388: if (as == -1) {
389: switch(keyboard_lang) {
390: case KBD_LANG_US:
391: as = decode_us(ks);
392: break;
393:
394: case KBD_LANG_DE:
395: as = decode_de(ks);
396: break;
397:
398: default:
399: as = -1;
400: break;
401: }
402: }
403: if(-1 != as)
404: return as;
405: return -1;
406: }
407:
408: void handle_events()
409: {
410: Boolean repeat;
411: Boolean itHappened;
412: Point mpos;
413: EventRecord event;
414: int kc,i,count;
415:
416: SetEventMask(-1);
417: SelectWindow(mywin);
418: HideCursor();
419:
420: GetKeys(keys);
421: if (BitTst(&keys, kCommandRawKey))
422: RM=true;
423: else
424: RM=false;
425:
426: if (BitTst(&keys, kShiftRawKey))
427: {
428: if (!keystate[AK_LSH]) {
429: keystate[AK_LSH] = true;
430: record_key (AK_LSH << 1);
431: goto label1;
432: }
433: } else {
434: if (keystate[AK_LSH]) {
435: keystate[AK_LSH] = false;
436: record_key ((AK_LSH << 1) | 1);
437: goto label1;
438: }
439: }
440: if (BitTst(&keys, kControlRawKey))
441: {
442: if (!keystate[AK_CTRL]) {
443: keystate[AK_CTRL] = true;
444: record_key (AK_CTRL << 1);
445: goto label1;
446: }
447: } else {
448: if (keystate[AK_CTRL]) {
449: keystate[AK_CTRL] = false;
450: record_key ((AK_CTRL << 1) | 1);
451: goto label1;
452: }
453: }
454: if (BitTst(&keys, kOptionRawKey))
455: {
456: if (!keystate[AK_LALT]) {
457: keystate[AK_LALT] = true;
458: record_key (AK_LALT << 1);
459: goto label1;
460: }
461: } else {
462: if (keystate[AK_LALT]) {
463: keystate[AK_LALT] = false;
464: record_key ((AK_LALT << 1) | 1);
465: goto label1;
466: }
467: }
468: do {
469: repeat = false;
470: newmousecounters = false;
471: itHappened=WaitNextEvent(-1,&event,0L,0L);
472:
473: switch(event.what) {
474: case keyDown:
475: case autoKey: {
476: int kc = keycode2amiga(event.message);
477: if (kc == -1) break;
478: if (RM == true && kc == AK_Q) graphics_leave();
479: switch (kc) {
480: case AK_mousestuff:
481: #if 0
482: if (keystate[AK_CTRL])
483: mousesetup();
484: else
485: #endif
486: togglemouse();
487: break;
488:
489: case AK_inhibit:
490: inhibit_frame ^= 1;
491: break;
492:
493: default:
494: if (!keystate[kc]) {
495: keystate[kc] = true;
496: record_key (kc << 1);
497: }
498: break;
499: }
500: break;
501: }
502: case keyUp: {
503: if (Joy) break;
504: kc = keycode2amiga(event.message);
505: if (kc == -1) break;
506: keystate[kc] = false;
507: record_key ((kc << 1) | 1);
508: break;
509: }
510: case mouseDown:
511: if (RM == true) buttonstate[2] = true;
512: else buttonstate[0] = true;
513: break;
514: case mouseUp:
515: buttonstate[0] = false;
516: buttonstate[2] = false;
517: break;
518: }
519: GetMouse(&mpos);
520: if (mpos.h != lastmx) { lastmx=mpos.h; repeat = true; }
521: if (mpos.v != lastmy) { lastmy=mpos.v; repeat = true; }
522: } while (repeat);
523:
524: label1:
525: /* "Affengriff" */
526: if(keystate[AK_CTRL] && keystate[AK_LAMI] && keystate[AK_RAMI])
527: MC68000_reset();
528: }
529:
530: bool debuggable()
531: {
532: return true;
533: }
534:
535: bool needmousehack()
536: {
537: return true;
538: }
539:
540: void LED(int on)
541: {
542: }
543:
544: void parse_cmdline ()
545: {
546: /* No commandline on the Mac. Implemented on Menus soon!*/
547: }
548:
549: // Check Minimal System Configuration and Setup
550: static Boolean CheckForSetup (void)
551: { Boolean retvalue=FALSE;
552: SysEnvRec env;
553:
554: SysEnvirons( 2, &env );
555:
556: if ( env.systemVersion < 0x0700 )
557: { ParamAString("\pUAE requires System 7 or later!");
558: DisplayError(kQuitError);
559: retvalue=TRUE;
560: }
561: if ( !env.hasColorQD)
562: { ParamAString("\pUAE requires Color QuickDraw!");
563: DisplayError(kQuitError);
564: retvalue=TRUE;
565: }
566: if ( env.processor < 3)
567: { ParamAString("\pUAE requires a 68020 or better processor to run!");
568: DisplayError(kQuitError);
569: retvalue=TRUE;
570: }
571: curDevice = GetMainDevice();
572: if ((*curDevice)->gdPMap == NULL || (*(*curDevice)->gdPMap)->pixelSize != 16)
573: { if (HasDepth(curDevice,16,0,0) == 0)
574: { ParamAString("\pUAE requires 16 bit color and your display doesn't support it!");
575: DisplayError(kQuitError);
576: retvalue=TRUE;
577: }
578: else
579: {
580: oldDepth=(*(*curDevice)->gdPMap)->pixelSize;
581: SetDepth(curDevice,16,0,0);
582: }
583: }
584: return(retvalue);
585: }
586:
587: // Shows up the standard error alert;
588: int DisplayError(int ID)
589: { int ret=0;
590:
591: InitCursor();
592: ret=Alert(ID,0);
593:
594: return (ret);
595: }
596:
597: // Parses a Pascal string for error display
598: void ParamAString( ConstStr255Param theStr )
599: {
600: ParamText(theStr, "\p", "\p", "\p");
601: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.