|
|
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.