|
|
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>
1.1.1.2 ! root 15: #include <Sound.h>
! 16: #include <errno.h>
1.1 root 17:
18: #include "mackbd.h"
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 "xwin.h"
26: #include "keyboard.h"
27: #include "keybuf.h"
28:
1.1.1.2 ! root 29: #define kAppleMenuID 128
! 30: #define kFileMenuID 129
! 31: #define kEditMenuID 130
! 32: #define kDrivesMenuID 131
! 33: #define kMemoryMenuID 132
! 34: #define kResMenuID 135
! 35: #define kRateMenuID 134
! 36: #define kVideoMenuID 133
! 37:
! 38: #define kAboutDialogID 128
! 39: #define kHardfileDialogID 129
! 40: #define kQuitError 130
! 41:
! 42: #define mTopLeft(r) (((Point *)&(r))[0])
! 43: #define mBotRight(r) (((Point *)&(r))[1])
! 44:
! 45: #define qd_CenterScreen 144
! 46:
! 47: extern int quit_program;
! 48:
! 49: static GDHandle curDevice;
! 50: static int oldDepth=0;
! 51: static Boolean macCursorState=true;
! 52: int use_quickdraw=true;
! 53: short filesys_vRefNum=0;
! 54: static KeyMap keys;
! 55: static Boolean redraw=true,diskInit=true;
! 56: static int mBarState=1;
! 57: static int RM=0;
! 58: static int my_use_gfxlib=0;
! 59: static int my_automount_uaedev=1;
! 60: static int my_screen_res=3;
! 61: static int my_use_quickdraw=1;
! 62: static WindowPtr mywin;
! 63: static RgnHandle gOldVisRgn;
! 64: static short gOldMBarHeight;
! 65: static Boolean macDiskStatus[4];
! 66: static GWorldPtr gOffscreenBuffer;
! 67: static PixMapHandle gOffscreenPixels;
! 68: static Rect gOffscreenRect,gDrawRect;
! 69: static unsigned char *gOffscreenBaseAddr;
! 70: static unsigned long gOffscreenRowBytes;
! 71: static PaletteHandle mypal;
! 72: static int CenterScreen=0;
! 73: static CTabHandle myCTAB;
! 74: static long screenH=0,screenV=0;
! 75: static GrafPtr dummyPort;
! 76: extern SndChannelPtr newChannel;
! 77: static unsigned long refresh;
! 78: extern char *xlinebuffer;
1.1 root 79: long int xcolors[4096];
80:
1.1.1.2 ! root 81: struct vidbuf_description gfxvidinfo;
! 82:
1.1 root 83: /* Keyboard and mouse */
84:
1.1.1.2 ! root 85: static int keystate[256];
1.1 root 86:
1.1.1.2 ! root 87: int buttonstate[3];
1.1 root 88: int lastmx, lastmy;
1.1.1.2 ! root 89: int newmousecounters;
1.1 root 90:
1.1.1.2 ! root 91: static int colors_allocated;
1.1 root 92:
1.1.1.2 ! root 93: // Prototypes
! 94: static void HandleMenu (long mSelect);
! 95: static void macHandleCursors(void);
! 96: static Boolean CheckForSetup (void);
! 97: static void ParamAString( ConstStr255Param theStr);
! 98: static void printStatusLine (void);
! 99: static void Share_main(void);
! 100: static void Share_ResolvePath (FSSpec *fSpec, char *path);
! 101: // end Prototypes
1.1 root 102:
1.1.1.2 ! root 103: static void my_setpalette(int count, int r, int g, int b)
! 104: { RGBColor mycolor;
! 105:
! 106: mycolor.red=r*1024;
! 107: mycolor.green=g*1024;
! 108: mycolor.blue=b*1024;
! 109:
! 110: if (count == 0 || count == 255) SetEntryColor(mypal, count, &mycolor);
! 111: else SetEntryColor(mypal, (~count & 0x000000ff), &mycolor);
1.1 root 112: }
113:
1.1.1.2 ! root 114: static int get_color(int r, int g, int b, xcolnr *cnp)
1.1 root 115: {
1.1.1.2 ! root 116: if (colors_allocated == 256) return -1;
! 117: *cnp = colors_allocated;
! 118: my_setpalette(colors_allocated, doMask(r, 6, 0), doMask(g, 6, 0), doMask(b, 6, 0));
! 119: colors_allocated++;
! 120: return 1;
1.1 root 121: }
122:
1.1.1.2 ! root 123: static void init_colors(void)
1.1 root 124: {
1.1.1.2 ! root 125: int rw = 5, gw = 5, bw = 5;
! 126: colors_allocated = 0;
! 127:
! 128: if (gfxvidinfo.pixbytes == 1)
! 129: alloc_colors256(get_color);
! 130: else
! 131: { if (gfxvidinfo.pixbytes == 4) rw=gw=bw=8;
! 132: alloc_colors64k(rw, gw, bw, gw+bw, bw, 0);
! 133: }
1.1 root 134: }
135:
1.1.1.2 ! root 136: static void HideMenuBar(GrafPtr grafPort)
! 137: { Rect menuRect={0,0,20,640};
! 138: RgnHandle newVisRgn;
! 139: GrafPtr savePort;
! 140:
! 141: GetPort(&savePort);
! 142: SetPort(grafPort);
1.1 root 143:
1.1.1.2 ! root 144: // save off vis region
! 145: gOldVisRgn = NewRgn();
! 146: CopyRgn(grafPort->visRgn, gOldVisRgn);
! 147:
! 148: // expand the vis region to the port rect
! 149: newVisRgn = NewRgn();
! 150: RectRgn(newVisRgn, &grafPort->portRect);
! 151: CopyRgn(newVisRgn, grafPort->visRgn);
! 152: DisposeRgn(newVisRgn);
1.1 root 153:
1.1.1.2 ! root 154: PaintRect(&menuRect);
! 155:
! 156: gOldMBarHeight = GetMBarHeight();
! 157: LMSetMBarHeight(0);
! 158:
! 159: SetPort(savePort);
1.1 root 160: }
161:
1.1.1.2 ! root 162: static void ShowMenuBar(GrafPtr grafPort)
1.1 root 163: {
1.1.1.2 ! root 164: GrafPtr savePort;
! 165: RgnHandle junkRgn;
1.1 root 166:
1.1.1.2 ! root 167: GetPort(&savePort);
! 168: SetPort(grafPort);
1.1 root 169:
1.1.1.2 ! root 170: // fill the rounded corners of the screen with black again
! 171: junkRgn = NewRgn();
! 172: CopyRgn(gOldVisRgn, junkRgn);
! 173: DiffRgn(grafPort->visRgn, junkRgn, junkRgn);
! 174:
! 175: #ifdef dangerousPattern
! 176: FillRgn(junkRgn, qd.black);
! 177: #else
! 178: FillRgn(junkRgn, &qd.black);
! 179: #endif
! 180:
! 181: DisposeRgn(junkRgn);
! 182:
! 183: // restore the old vis region
! 184: CopyRgn(gOldVisRgn, grafPort->visRgn);
! 185: DisposeRgn(gOldVisRgn);
! 186: gOldVisRgn = NULL;
! 187:
! 188: LMSetMBarHeight(gOldMBarHeight);
! 189:
! 190: DrawMenuBar();
! 191: }
! 192:
! 193: int graphics_init()
! 194: {
! 195: int i;
! 196: char p1;
! 197: long tmp;
! 198: long memtop=0;
! 199: Rect windowRectangle,osRect={0,0,600,800};
! 200: char *dst;
! 201: CGrafPtr oldPort;
! 202: GDHandle oldDevice;
! 203:
! 204: my_use_gfxlib=use_gfxlib;
! 205: my_automount_uaedev=automount_uaedev;
! 206: my_screen_res=screen_res;
! 207: my_use_quickdraw=use_quickdraw;
1.1 root 208:
209: if (CheckForSetup()) ExitToShell();
210:
1.1.1.2 ! root 211: gfxvidinfo.maxblocklines=600; // Whatever...
! 212:
! 213: if (gfxvidinfo.pixbytes == 1)
! 214: { myCTAB=GetCTable(128);
! 215: mypal=NewPalette(256, myCTAB, pmTolerant + pmExplicit, 0x0000);
! 216: }
! 217:
! 218: windowRectangle.left=0;
! 219: if (screen_res > 4 || screen_res < 0) screen_res=3;
! 220: if (screen_res == 4 || screen_res == 2) dont_want_aspect = 0;
! 221: else dont_want_aspect = 1;
! 222: switch (screen_res)
! 223: { case 0:
! 224: case 1:
! 225: case 2:
! 226: CenterScreen=(36*gfxvidinfo.pixbytes)/2;
! 227: windowRectangle.right=320;
! 228: use_lores = 1;
! 229: windowRectangle.top=40;
! 230: if (screen_res == 0) windowRectangle.bottom=200+windowRectangle.top+38;
! 231: else if (screen_res == 1) windowRectangle.bottom=256+windowRectangle.top+38;
! 232: else windowRectangle.bottom=400+windowRectangle.top+38;
! 233: break;
! 234:
! 235: case 3:
! 236: case 4:
! 237: CenterScreen=36*gfxvidinfo.pixbytes;
! 238: use_lores = 0;
! 239: windowRectangle.right=640;
! 240: if (dont_want_aspect == 0)
! 241: { windowRectangle.top=0;
! 242: windowRectangle.bottom=480;
! 243: }
! 244: else
! 245: { windowRectangle.top=40;
! 246: windowRectangle.bottom=256+windowRectangle.top+38;
! 247: }
! 248: break;
! 249: }
! 250:
! 251: screenV=windowRectangle.bottom-windowRectangle.top;
! 252: if (dont_want_aspect == 1 || screen_res == 2) screenV -= 12;
! 253: screenH=windowRectangle.right-windowRectangle.left;
! 254:
! 255: mywin = NewCWindow(nil, &windowRectangle, "\pThe Un*x Amiga Emulator", 1, 4, (WindowPtr)-1L, 0, 0);
1.1 root 256: SetPort(mywin);
257:
1.1.1.2 ! root 258: gui_prepare_leds(screenV);
1.1 root 259:
1.1.1.2 ! root 260: init_colors();
1.1 root 261:
1.1.1.2 ! root 262: if (use_quickdraw)
! 263: { GetGWorld(&oldPort, &oldDevice);
! 264: NewGWorld( &gOffscreenBuffer, (gfxvidinfo.pixbytes*8), &osRect, 0L, oldDevice, 0);
! 265: SetGWorld(oldPort, oldDevice);
! 266: gOffscreenPixels = GetGWorldPixMap( gOffscreenBuffer );
! 267: LockPixels(gOffscreenPixels);
! 268: gDrawRect.top=(mywin->portRect).top;
! 269: gDrawRect.left=(mywin->portRect).left;
! 270: gDrawRect.right=(mywin->portRect).right;
! 271: gDrawRect.bottom=(mywin->portRect).bottom;
! 272: gDrawRect.bottom -= 12;
! 273: gOffscreenRect.top=(mywin->portRect).top;
! 274: gOffscreenRect.left=(mywin->portRect).left;
! 275: gOffscreenRect.right=(mywin->portRect).right;
! 276: gOffscreenRect.bottom=(mywin->portRect).bottom;
! 277: gOffscreenRect.bottom -= 12;
! 278: OffsetRect(&gOffscreenRect,(use_lores == 1) ? qd_CenterScreen/2 : qd_CenterScreen,0);
! 279: gOffscreenBaseAddr = (unsigned char *)GetPixBaseAddr(gOffscreenPixels);
! 280: gOffscreenRowBytes = (*gOffscreenPixels)->rowBytes & 0x3fff;
! 281: gfxvidinfo.bufmem=(char *)gOffscreenBaseAddr;
! 282: gfxvidinfo.rowbytes=gOffscreenRowBytes;
! 283: SetGWorld(gOffscreenBuffer, NULL);
! 284: PaintRect(&gOffscreenRect);
! 285: SetGWorld(oldPort, oldDevice);
! 286: }
! 287: else
! 288: { gfxvidinfo.bufmem=NewPtrClear(600*(800*gfxvidinfo.pixbytes));
! 289: if (gfxvidinfo.bufmem == 0) SysBeep(0);
! 290: gfxvidinfo.rowbytes=800*gfxvidinfo.pixbytes;
1.1 root 291: }
1.1.1.2 ! root 292:
! 293: if (dont_want_aspect || screen_res == 2) printStatusLine();
! 294:
! 295: if (gfxvidinfo.pixbytes == 1)
! 296: { SetPalette((WindowPtr) -1L, mypal, false);
! 297: }
! 298:
! 299: buttonstate[0] = buttonstate[1] = buttonstate[2] = 0;
! 300: for(i=0; i<256; i++) keystate[i] = 0;
! 301:
! 302: lastmx = lastmy = 0; newmousecounters=0;
1.1 root 303:
304: refresh=TickCount();
305:
1.1.1.2 ! root 306: // tmp=ProfilerInit(collectDetailed,bestTimeBase,200,10);
! 307: return 1;
1.1 root 308: }
309:
310: void graphics_leave()
311: {
1.1.1.2 ! root 312: // ProfilerDump((unsigned char *)"\pmyProf");
! 313: // ProfilerTerm();
! 314:
1.1 root 315: ShowCursor();
1.1.1.2 ! root 316: if (dont_want_aspect == 0) if (!mBarState) ShowMenuBar(mywin);
1.1 root 317: if (oldDepth != 0) SetDepth(curDevice,oldDepth,0,0);
318: FlushEvents (everyEvent,0);
1.1.1.2 ! root 319: SndDisposeChannel(newChannel,true);
! 320: if (gfxvidinfo.pixbytes == 1)
! 321: { DisposePalette(mypal);
! 322: DisposeCTable(myCTAB);
! 323: }
! 324: DisposeWindow(mywin);
! 325: if (use_quickdraw)
! 326: { DisposeGWorld(gOffscreenBuffer);
! 327: }
! 328: else DisposePtr((Ptr)(gfxvidinfo.bufmem));
1.1 root 329: }
330:
1.1.1.2 ! root 331: static int next_line_double;
1.1 root 332: static int next_line_pos = 0;
333:
334: void flush_screen ()
1.1.1.2 ! root 335: { short y,x,y1=0;
1.1 root 336: unsigned char *winbaseaddr;
1.1.1.2 ! root 337: long *src,*dest;
1.1 root 338: unsigned long winrowbytes;
339: PixMapHandle ph;
1.1.1.2 ! root 340: CGrafPtr oldPort;
! 341: GDHandle oldDevice;
1.1 root 342:
1.1.1.2 ! root 343: if (TickCount() < refresh + 4) return;
! 344: if (!redraw) return;
! 345: if (FrontWindow() != mywin) return;
! 346: if (inhibit_frame) return;
! 347:
! 348: GetGWorld(&oldPort,&oldDevice);
! 349: SetGWorld((CWindowPtr) mywin, oldDevice);
! 350: if (use_quickdraw)
! 351: { ForeColor(blackColor); /* Prevents colorizing mode */
! 352: BackColor(whiteColor); /* Prevents colorizing mode */
! 353: (*((*gOffscreenPixels)->pmTable))->ctSeed = (*((*((*(GetGDevice()))->gdPMap))->pmTable))->ctSeed;
! 354: CopyBits((BitMap *)(*gOffscreenPixels), &(mywin->portBits), &gOffscreenRect, &gDrawRect, srcCopy, (RgnHandle) 0L);
! 355: }
! 356: else
! 357: { ph=GetGWorldPixMap((CGrafPort *) mywin);
! 358: winbaseaddr=( unsigned char *) GetPixBaseAddr(ph);
! 359: winrowbytes=(*ph)->rowBytes & 0x3FFF;
! 360: winbaseaddr-=((**ph).bounds.left);
! 361: winbaseaddr-=(((**ph).bounds.top)*winrowbytes);
! 362: dest=(long *)winbaseaddr;
! 363: src=(long *)(gfxvidinfo.bufmem)+CenterScreen;
! 364:
! 365: y=0;
! 366: if ((dont_want_aspect == 0 && mBarState == true && y < 20)) y=20;
! 367: dest=(long *)(winbaseaddr+(y*winrowbytes));
! 368: src=(long *)(gfxvidinfo.bufmem+(y*gfxvidinfo.rowbytes))+CenterScreen;
! 369: for (; y< screenV; y++)
! 370: { for (x=0;x < ((screenH*gfxvidinfo.pixbytes)/sizeof(long));x++) *dest++ = *src++;
! 371: dest=(long *)(winbaseaddr+(y*winrowbytes));
! 372: src=(long *)(gfxvidinfo.bufmem+(y*gfxvidinfo.rowbytes))+CenterScreen;
! 373: }
! 374: }
! 375: SetGWorld(oldPort, oldDevice);
1.1 root 376: }
377:
1.1.1.2 ! root 378: void flush_block (int start_y, int end_y)
! 379: { short y,x,y1=0;
! 380: unsigned char *winbaseaddr;
! 381: long *src,*dest;
! 382: unsigned long winrowbytes;
! 383: PixMapHandle ph;
! 384: Rect srcRect,dstRect;
! 385: CGrafPtr oldPort;
! 386: GDHandle oldDevice;
! 387:
! 388: if (TickCount() < refresh + 4) return;
! 389: if (!redraw) return;
! 390: if (FrontWindow() != mywin) return;
! 391: if (inhibit_frame) return;
! 392:
! 393: if (end_y > screenV) end_y=screenV;
! 394: GetGWorld(&oldPort,&oldDevice);
! 395: SetGWorld((CWindowPtr) mywin, oldDevice);
! 396: if (use_quickdraw)
! 397: {
! 398: srcRect.top=start_y;
! 399: srcRect.bottom=end_y;
! 400: srcRect.left=gOffscreenRect.left;
! 401: srcRect.right=gOffscreenRect.right;
! 402: dstRect.top=start_y;
! 403: dstRect.bottom=end_y;
! 404: dstRect.left=gDrawRect.left;
! 405: dstRect.right=gDrawRect.right;
! 406:
! 407: /* Taken from my favorite book:
! 408: "It is significant, if not surprising, that the Mac and PC cannot come
! 409: to an agreement over the most fundamental issue in the universe: the
! 410: distinction between black and white. On the PC, the pixel value 0
! 411: indicates a pixel of zero intensity, or black. On the Mac, 0 indicates
! 412: a page wich has not been written on, wich leaves it white."
! 413:
! 414: Eric Johnston.
! 415: Tricks of the Mac Game Programming Gurus.
! 416:
! 417: Check set_palette and line_to_scr8() on how i fixed that.
! 418: If you know a better way let me know.
! 419: */
! 420:
! 421: ForeColor(blackColor); /* Prevents colorizing mode */
! 422: BackColor(whiteColor); /* Prevents colorizing mode */
! 423: (*((*gOffscreenPixels)->pmTable))->ctSeed = (*((*((*(GetGDevice()))->gdPMap))->pmTable))->ctSeed;
! 424: CopyBits((BitMap *)(*gOffscreenPixels), &(mywin->portBits), &srcRect, &dstRect, srcCopy, (RgnHandle) 0L);
! 425: }
! 426: else
! 427: { ph=GetGWorldPixMap((CGrafPort *) mywin);
! 428: winbaseaddr=( unsigned char *) GetPixBaseAddr(ph);
! 429: winrowbytes=(*ph)->rowBytes & 0x3FFF;
! 430: winbaseaddr-=((**ph).bounds.left);
! 431: winbaseaddr-=(((**ph).bounds.top)*winrowbytes);
! 432: dest=(long *)winbaseaddr;
! 433: src=(long *)(gfxvidinfo.bufmem)+CenterScreen;
! 434:
! 435: y=start_y;
! 436: if ((dont_want_aspect == 0 && mBarState == true && y < 20)) y=20;
! 437: dest=(long *)(winbaseaddr+(y*winrowbytes));
! 438: src=(long *)(gfxvidinfo.bufmem+(y*gfxvidinfo.rowbytes))+CenterScreen;
! 439: for (; y <= end_y; y++)
! 440: { for (x=0;x < ((screenH*gfxvidinfo.pixbytes)/sizeof(long));x++) *dest++ = *src++;
! 441: dest=(long *)(winbaseaddr+(y*winrowbytes));
! 442: src=(long *)(gfxvidinfo.bufmem+(y*gfxvidinfo.rowbytes))+CenterScreen;
! 443: }
! 444: }
! 445: SetGWorld(oldPort, oldDevice);
1.1 root 446: }
447:
1.1.1.2 ! root 448: void flush_line(int line_num)
1.1 root 449: {
1.1.1.2 ! root 450: long i;
1.1 root 451: char *dst,*src;
1.1.1.2 ! root 452: CGrafPtr oldPort;
! 453: GDHandle oldDevice;
1.1 root 454:
1.1.1.2 ! root 455: if (use_quickdraw)
! 456: { GetGWorld(&oldPort, &oldDevice);
! 457: SetGWorld(gOffscreenBuffer, NULL);
! 458: dst=(char *)gOffscreenBaseAddr;
! 459: dst+=(char *)((line_num)*gOffscreenRowBytes);
! 460: src=(char *)xlinebuffer;
! 461: BlockMove(src,dst,gOffscreenRowBytes);
! 462: if (next_line_double)
! 463: { dst=(char *)gOffscreenBaseAddr;
! 464: dst+=(char *)((line_num+1)*gOffscreenRowBytes);
! 465: src=(char *)xlinebuffer;
! 466: BlockMove(src,dst,gOffscreenRowBytes);
! 467: }
! 468: SetGWorld(oldPort, oldDevice);
1.1 root 469: }
1.1.1.2 ! root 470: else
! 471: { if (line_num < 481)
! 472: { dst=(char *)gfxvidinfo.bufmem+((line_num)*gfxvidinfo.rowbytes);
! 473: src=(char *)xlinebuffer;
! 474: BlockMove(src,dst,gfxvidinfo.rowbytes);
! 475: }
! 476: if (next_line_double)
! 477: {
! 478: if (line_num < 481)
! 479: { dst=(char *)gfxvidinfo.bufmem+((line_num+1)*gfxvidinfo.rowbytes);
! 480: src=(char *)xlinebuffer;
! 481: BlockMove(src,dst,gfxvidinfo.rowbytes);
! 482: }
! 483: }
1.1 root 484: }
485: }
486:
487: /* Decode KeySyms. This function knows about all keys that are common
488: * between different keyboard languages.
489: */
490: static int kc_decode (long ks)
491: {
492: switch (ks)
493: {
494: case kAKeyMap: return AK_A;
495: case kBKeyMap: return AK_B;
496: case kCKeyMap: return AK_C;
497: case kDKeyMap: return AK_D;
498: case kEKeyMap: return AK_E;
499: case kFKeyMap: return AK_F;
500: case kGKeyMap: return AK_G;
501: case kHKeyMap: return AK_H;
502: case kIKeyMap: return AK_I;
503: case kJKeyMap: return AK_J;
504: case kKKeyMap: return AK_K;
505: case kLKeyMap: return AK_L;
506: case kMKeyMap: return AK_M;
507: case kNKeyMap: return AK_N;
508: case kOKeyMap: return AK_O;
509: case kPKeyMap: return AK_P;
510: case kQKeyMap: return AK_Q;
511: case kRKeyMap: return AK_R;
512: case kSKeyMap: return AK_S;
513: case kTKeyMap: return AK_T;
514: case kUKeyMap: return AK_U;
515: case kVKeyMap: return AK_V;
516: case kWKeyMap: return AK_W;
517: case kXKeyMap: return AK_X;
518:
519: case k0KeyMap: return AK_0;
520: case k1KeyMap: return AK_1;
521: case k2KeyMap: return AK_2;
522: case k3KeyMap: return AK_3;
523: case k4KeyMap: return AK_4;
524: case k5KeyMap: return AK_5;
525: case k6KeyMap: return AK_6;
526: case k7KeyMap: return AK_7;
527: case k8KeyMap: return AK_8;
528: case k9KeyMap: return AK_9;
529:
530: case kKP0KeyMap: return AK_NP0;
531: case kKP1KeyMap: return AK_NP1;
532: case kKP2KeyMap: return AK_NP2;
533: case kKP3KeyMap: return AK_NP3;
534: case kKP4KeyMap: return AK_NP4;
535: case kKP5KeyMap: return AK_NP5;
536: case kKP6KeyMap: return AK_NP6;
537: case kKP7KeyMap: return AK_NP7;
538: case kKP8KeyMap: return AK_NP8;
539: case kKP9KeyMap: return AK_NP9;
540:
541: case kF1KeyMap: return AK_F1;
542: case kF2KeyMap: return AK_F2;
543: case kF3KeyMap: return AK_F3;
544: case kF4KeyMap: return AK_F4;
545: case kF5KeyMap: return AK_F5;
546: case kF6KeyMap: return AK_F6;
547: case kF7KeyMap: return AK_F7;
548: case kF8KeyMap: return AK_F8;
549: case kF9KeyMap: return AK_F9;
550: case kF10KeyMap: return AK_F10;
551:
552: case kBackSpaceKeyMap: return AK_BS;
553: case kTabKeyMap: return AK_TAB;
554: case kReturnKeyMap: return AK_RET;
555: case kEscapeKeyMap: return AK_ESC;
556:
1.1.1.2 ! root 557: case kSpaceBarMap: return AK_SPC;
1.1 root 558:
1.1.1.2 ! root 559: case kUpArrowKeyMap: return AK_UP;
! 560: case kDownArrowKeyMap: return AK_DN;
! 561: case kLeftArrowKeyMap: return AK_LF;
! 562: case kRightArrowKeyMap: return AK_RT;
1.1 root 563:
1.1.1.2 ! root 564: case kF11KeyMap: return AK_inhibit;
! 565:
! 566: case kF12KeyMap: return AK_mousestuff;
1.1 root 567:
568: case kPgUpKeyMap: return AK_RAMI;
569: case kPgDnKeyMap: return AK_LAMI;
570: case kBackSlash: return AK_BACKSLASH;
571: }
572: return -1;
573: }
574:
575: static int decode_us(long ks)
576: {
577: switch(ks) {
578: /* US specific */
579:
580: case kYKeyMap: return AK_Y;
581: case kZKeyMap: return AK_Z;
582: case kLBracketKeyMap: return AK_LBRACKET;
583: case kRBracketKeyMap: return AK_RBRACKET;
584: case kCommaKeyMap: return AK_COMMA;
585: case kPeriodKeyMap: return AK_PERIOD;
586: case kSlashKeyMap: return AK_SLASH;
587: case kSemiColonKeyMap: return AK_SEMICOLON;
588: case kMinusKeyMap: return AK_MINUS;
589: case kEqualKeyMap: return AK_EQUAL;
590: case kQuoteKeyMap: return AK_QUOTE;
591: }
592:
593: return -1;
594: }
595:
596: static int decode_de(long ks)
597: {
598: switch(ks) {
599: /* DE specific
600: case XK_Y: case XK_y: return AK_Z;
601: case XK_Z: case XK_z: return AK_Y;
602: case XK_Odiaeresis: case XK_odiaeresis: return AK_SEMICOLON;
603: case XK_Adiaeresis: case XK_adiaeresis: return AK_QUOTE;
604: case XK_Udiaeresis: case XK_udiaeresis: return AK_LBRACKET;
605: case XK_plus: case XK_asterisk: return AK_RBRACKET;
606: case XK_comma: return AK_COMMA;
607: case XK_period: return AK_PERIOD;
608: case XK_less: case XK_greater: return AK_LTGT;
609: case XK_numbersign: return AK_NUMBERSIGN;
610: case XK_ssharp: return AK_MINUS;
611: case XK_apostrophe: return AK_EQUAL;
612: case XK_asciicircum: return AK_00;
613: case XK_minus: return AK_SLASH;
614: */
615: }
616:
617: return -1;
618: }
619:
620: static int keycode2amiga(long code)
621: {
622: long ks;
623: int as;
624:
625: ks = (code & keyCodeMask) >> 8;
626: as = kc_decode (ks);
627:
628: if (as == -1) {
629: switch(keyboard_lang) {
630: case KBD_LANG_US:
631: as = decode_us(ks);
632: break;
633:
634: case KBD_LANG_DE:
635: as = decode_de(ks);
636: break;
637:
638: default:
639: as = -1;
640: break;
641: }
642: }
643: if(-1 != as)
644: return as;
645: return -1;
646: }
647:
648: void handle_events()
1.1.1.2 ! root 649: { WindowPeek wp;
! 650: short windowPart;
! 651: Boolean repeat;
1.1 root 652: Boolean itHappened;
653: Point mpos;
654: EventRecord event;
655: int kc,i,count;
1.1.1.2 ! root 656: char osKind;
! 657: GrafPtr oldSave;
1.1 root 658:
1.1.1.2 ! root 659: GetPort(&oldSave);
! 660: if ((redraw) && mywin != FrontWindow()) SelectWindow(mywin);
! 661:
1.1 root 662: SetEventMask(-1);
1.1.1.2 ! root 663:
! 664: if (diskInit)
! 665: { macDiskStatus[0]=!disk_empty(0);
! 666: SetMenuItemText(GetMenuHandle(kDrivesMenuID), 1, macDiskStatus[0] ? "\pEject Disk in DF0:" : "\pInsert Disk in DF0:");
! 667: macDiskStatus[1]=!disk_empty(1);
! 668: SetMenuItemText(GetMenuHandle(kDrivesMenuID), 2, macDiskStatus[1] ? "\pEject Disk in DF1:" : "\pInsert Disk in DF1:");
! 669: macDiskStatus[2]=!disk_empty(2);
! 670: SetMenuItemText(GetMenuHandle(kDrivesMenuID), 3, macDiskStatus[2] ? "\pEject Disk in DF2:" : "\pInsert Disk in DF2:");
! 671: macDiskStatus[3]=!disk_empty(3);
! 672: SetMenuItemText(GetMenuHandle(kDrivesMenuID), 4, macDiskStatus[3] ? "\pEject Disk in DF3:" : "\pInsert Disk in DF3:");
! 673: diskInit=false;
! 674: }
! 675:
! 676: if (redraw)
! 677: { gui_update_leds();
! 678: macHandleCursors();
! 679: }
! 680:
1.1 root 681: GetKeys(keys);
682: if (BitTst(&keys, kCommandRawKey))
1.1.1.2 ! root 683: buttonstate[2] = 1;
1.1 root 684: else
1.1.1.2 ! root 685: buttonstate[2] = 0;
1.1 root 686:
687: if (BitTst(&keys, kShiftRawKey))
688: {
689: if (!keystate[AK_LSH]) {
1.1.1.2 ! root 690: keystate[AK_LSH] = 1;
1.1 root 691: record_key (AK_LSH << 1);
692: goto label1;
693: }
694: } else {
695: if (keystate[AK_LSH]) {
1.1.1.2 ! root 696: keystate[AK_LSH] = 0;
1.1 root 697: record_key ((AK_LSH << 1) | 1);
698: goto label1;
699: }
700: }
701: if (BitTst(&keys, kControlRawKey))
702: {
703: if (!keystate[AK_CTRL]) {
1.1.1.2 ! root 704: keystate[AK_CTRL] = 1;
1.1 root 705: record_key (AK_CTRL << 1);
706: goto label1;
707: }
708: } else {
709: if (keystate[AK_CTRL]) {
1.1.1.2 ! root 710: keystate[AK_CTRL] = 0;
1.1 root 711: record_key ((AK_CTRL << 1) | 1);
712: goto label1;
713: }
714: }
1.1.1.2 ! root 715: if (BitTst(&keys, kCapsRawKey))
! 716: {
! 717: if (!keystate[AK_CAPSLOCK]) {
! 718: keystate[AK_CAPSLOCK] = 1;
! 719: record_key (AK_CAPSLOCK << 1);
! 720: goto label1;
! 721: }
! 722: } else {
! 723: if (keystate[AK_CAPSLOCK]) {
! 724: keystate[AK_CAPSLOCK] = 0;
! 725: record_key ((AK_CAPSLOCK << 1) | 1);
! 726: goto label1;
! 727: }
! 728: }
1.1 root 729: if (BitTst(&keys, kOptionRawKey))
730: {
731: if (!keystate[AK_LALT]) {
1.1.1.2 ! root 732: keystate[AK_LALT] = 1;
1.1 root 733: record_key (AK_LALT << 1);
734: goto label1;
735: }
736: } else {
737: if (keystate[AK_LALT]) {
1.1.1.2 ! root 738: keystate[AK_LALT] = 0;
1.1 root 739: record_key ((AK_LALT << 1) | 1);
740: goto label1;
741: }
742: }
743: do {
1.1.1.2 ! root 744: repeat = 0;
! 745: newmousecounters=0;
! 746: itHappened=WaitNextEvent(-1,&event,0L,(*mywin).visRgn);
1.1 root 747:
748: switch(event.what) {
749: case keyDown:
1.1.1.2 ! root 750: case autoKey: {
! 751: if ((event.modifiers & cmdKey) != 0)
! 752: { HandleMenu(MenuKey((char) (event.message & charCodeMask)));
! 753: }
! 754: else
! 755: { int kc = keycode2amiga(event.message);
! 756: if (kc == -1) break;
! 757: switch (kc)
! 758: { case AK_mousestuff:
! 759: togglemouse();
! 760: break;
! 761:
! 762: case AK_inhibit:
! 763: inhibit_frame ^= 1;
! 764: break;
! 765:
! 766: default:
! 767: if (!keystate[kc])
! 768: { keystate[kc] = 1;
! 769: record_key (kc << 1);
! 770: }
! 771: break;
! 772: }
! 773: }
! 774: break;
1.1 root 775: }
1.1.1.2 ! root 776: case keyUp: {
1.1 root 777: kc = keycode2amiga(event.message);
778: if (kc == -1) break;
1.1.1.2 ! root 779: keystate[kc] = 0;
1.1 root 780: record_key ((kc << 1) | 1);
781: break;
782: }
783: case mouseDown:
1.1.1.2 ! root 784: windowPart = FindWindow (event.where, (WindowPtr*) &wp);
! 785: if (windowPart == inMenuBar) HandleMenu(MenuSelect(event.where));
! 786: else
! 787: if (windowPart == inSysWindow) SystemClick (&event, (WindowPtr) wp);
! 788: else buttonstate[0] = 1;
1.1 root 789: break;
1.1.1.2 ! root 790:
! 791: case osEvt:
! 792: osKind=(event.message) >> 24;
! 793: if (osKind == suspendResumeMessage)
! 794: { osKind=(event.message)&1;
! 795: if (osKind)
! 796: { redraw=true; // Resume
! 797: flush_screen();
! 798: if (dont_want_aspect || screen_res == 2)
! 799: { SelectWindow(mywin);
! 800: printStatusLine();
! 801: }
! 802: }
! 803: else redraw=false; // Suspend
! 804: }
! 805: break;
1.1 root 806: case mouseUp:
1.1.1.2 ! root 807: buttonstate[0] = 0;
! 808: buttonstate[2] = 0;
1.1 root 809: break;
810: }
1.1.1.2 ! root 811: if (redraw)
! 812: { GetMouse(&mpos);
! 813: if (mpos.h != lastmx) { lastmx=mpos.h; /* repeat = 1;*/ }
! 814: if (mpos.v != lastmy) { lastmy=mpos.v; /*repeat = 1;*/ }
! 815: }
1.1 root 816: } while (repeat);
817:
818: label1:
819: /* "Affengriff" */
820: if(keystate[AK_CTRL] && keystate[AK_LAMI] && keystate[AK_RAMI])
821: MC68000_reset();
1.1.1.2 ! root 822: SetPort(oldSave);
1.1 root 823: }
824:
1.1.1.2 ! root 825: int debuggable()
1.1 root 826: {
1.1.1.2 ! root 827: return 1;
1.1 root 828: }
829:
1.1.1.2 ! root 830: int needmousehack()
1.1 root 831: {
1.1.1.2 ! root 832: return 1;
1.1 root 833: }
834:
835: void LED(int on)
836: {
837: }
838:
839: void parse_cmdline ()
840: {
1.1.1.2 ! root 841: /* No commandline on the Mac. */
! 842: }
! 843:
! 844: static void PStrCat ( StringPtr p1, StringPtr p2)
! 845: {
! 846: register int len;
! 847: register int total;
! 848: StringPtr p3;
! 849:
! 850: len = *p1++;
! 851: total = len +*p2;
! 852:
! 853: p3=p2;
! 854: p2=p2+ (*p2 + 1);
! 855:
! 856: while (--len>=0) *p2++=*p1++;
! 857: *p3=total;
! 858: }
! 859:
! 860: static void PStrCopy ( StringPtr p1, StringPtr p2)
! 861: {
! 862: register int len;
! 863:
! 864: len = *p2++ = *p1++;
! 865: while (--len>=0) *p2++=*p1++;
! 866: }
! 867:
! 868: short vRefNum=0;
! 869: long dirID=0;
! 870:
! 871: static void HandleMenu (long mSelect)
! 872: { short menuID;
! 873: short menuItem;
! 874: Str32 name;
! 875: GrafPtr savePort;
! 876: WindowPtr batchWin;
! 877: Str255 batchStr,batchStr2;
! 878: StandardFileReply inputReply;
! 879: char strSize,i;
! 880: long count;
! 881: FILE *outFile;
! 882: char fileBuf[512];
! 883: int backup=0;
! 884:
! 885: menuID = HiWord(mSelect);
! 886: menuItem = LoWord(mSelect);
! 887:
! 888: if (menuID == 0) return;
! 889: switch (menuID)
! 890: { case kAppleMenuID:
! 891: if (menuItem == 1)
! 892: { if (!macCursorState) ShowCursor();
! 893: macCursorState=true;
! 894: Alert(kAboutDialogID,0); // About Box
! 895: if (dont_want_aspect || screen_res == 2) printStatusLine();
! 896: }
! 897: else
! 898: { GetPort(&savePort);
! 899: GetItem(GetMenuHandle(kAppleMenuID), menuItem, name);
! 900: OpenDeskAcc(name);
! 901: SystemTask();
! 902: SetPort(savePort);
! 903: }
! 904: break;
! 905:
! 906: case kFileMenuID:
! 907: switch (menuItem)
! 908: { case 1:
! 909: MC68000_reset();
! 910: break;
! 911:
! 912: case 3:
! 913: if (dont_want_aspect == 0)
! 914: { if (mBarState) HideMenuBar(mywin);
! 915: else ShowMenuBar(mywin);
! 916: mBarState=!mBarState;
! 917: }
! 918: break;
! 919:
! 920: case 5:
! 921: broken_in = 1;
! 922: specialflags |= SPCFLAG_BRK;
! 923: break;
! 924:
! 925: case 7:
! 926: inhibit_frame ^= 1;
! 927: if (inhibit_frame) SetMenuItemText(GetMenuHandle(kFileMenuID), 7, "\pTurn Screen Update On");
! 928: else SetMenuItemText(GetMenuHandle(kFileMenuID), 7, "\pTurn Screen Update Off");
! 929: break;
! 930:
! 931: case 9:
! 932: produce_sound= !produce_sound;
! 933: if (produce_sound) SetMenuItemText(GetMenuHandle(kFileMenuID), 9, "\pTurn Sound Off");
! 934: else SetMenuItemText(GetMenuHandle(kFileMenuID), 9, "\pTurn Sound On");
! 935: WritePrefs(0);
! 936: break;
! 937:
! 938: case 11:
! 939: fake_joystick= !fake_joystick;
! 940: if (fake_joystick) SetMenuItemText(GetMenuHandle(kFileMenuID), 11, "\pTurn Joystick Off");
! 941: else SetMenuItemText(GetMenuHandle(kFileMenuID), 11, "\pTurn Joystick On");
! 942: WritePrefs(0);
! 943: break;
! 944:
! 945: case 13:
! 946: broken_in = 1;
! 947: specialflags |= SPCFLAG_BRK;
! 948: quit_program=1;
! 949: break;
! 950: }
! 951: break;
! 952:
! 953: case kDrivesMenuID:
! 954: if (menuItem >= 1 && menuItem <= 4)
! 955: { if (macDiskStatus[menuItem-1]) disk_eject(menuItem-1);
! 956: else
! 957: { if (!macCursorState) ShowCursor();
! 958: if (!mBarState) ShowMenuBar(mywin);
! 959: macCursorState=true;
! 960: StandardGetFile(nil,-1L,nil,&inputReply);
! 961: if (inputReply.sfGood)
! 962: { vRefNum=inputReply.sfFile.vRefNum;
! 963: dirID=inputReply.sfFile.parID;
! 964: disk_insert (menuItem-1, p2cstr(inputReply.sfFile.name));
! 965: }
! 966: else macDiskStatus[menuItem-1] = !macDiskStatus[menuItem-1];
! 967: if (!mBarState) HideMenuBar(mywin);
! 968: }
! 969: macDiskStatus[menuItem-1] = !macDiskStatus[menuItem-1];
! 970: if (macDiskStatus[menuItem-1]) PStrCopy("\pEject Disk in DF",batchStr);
! 971: else PStrCopy("\pInsert Disk in DF",batchStr);
! 972: NumToString((long)(menuItem-1),batchStr2);
! 973: PStrCat(batchStr2,batchStr);
! 974: PStrCat("\p:",batchStr);
! 975: SetMenuItemText(GetMenuHandle(kDrivesMenuID), menuItem, batchStr);
! 976:
! 977: }
! 978: if (menuItem == 6)
! 979: { if (!macCursorState) ShowCursor();
! 980: macCursorState=true;
! 981: for (count=0;count<512;count++) fileBuf[count]=0;
! 982: errno=0;
! 983: outFile=fopen("hardfile","wb");
! 984: if (outFile != 0)
! 985: { for (count=0;count<16384;count++)
! 986: { fwrite(fileBuf, sizeof(char), 512, outFile);
! 987: if (errno != 0)
! 988: { ParamAString("\pError generating the hardfile!.\n Make sure you have at least 8Mb of free storage on your Harddrive.");
! 989: DisplayError(kQuitError);
! 990: }
! 991: }
! 992: fclose(outFile);
! 993: Alert(kHardfileDialogID,0);
! 994: }
! 995: else
! 996: { ParamAString("\pCan't create the hardfile!.\n Make sure your Harddrive isnt either software or hardware locked.");
! 997: DisplayError(kQuitError);
! 998: }
! 999: }
! 1000: if (menuItem == 7)
! 1001: { my_automount_uaedev=!my_automount_uaedev;
! 1002: WritePrefs(0);
! 1003: ParamAString("\pChanges will take effect the next time you run UAE.");
! 1004: DisplayError(kQuitError);
! 1005: CheckItem(GetMenuHandle(kDrivesMenuID),7,my_automount_uaedev ? false : true);
! 1006: }
! 1007: if (menuItem == 9)
! 1008: { if (!macCursorState) ShowCursor();
! 1009: macCursorState=true;
! 1010: Share_main();
! 1011: }
! 1012: break;
! 1013:
! 1014: case kMemoryMenuID:
! 1015: if (menuItem == 1) use_slow_mem = !use_slow_mem;
! 1016: WritePrefs(0);
! 1017: ParamAString("\pChanges will take effect the next time you run UAE.");
! 1018: DisplayError(kQuitError);
! 1019: if (use_slow_mem) SetMenuItemText(GetMenuHandle(kMemoryMenuID), 1, "\pDisable 1 Mb (SlowMem)");
! 1020: else SetMenuItemText(GetMenuHandle(kMemoryMenuID), 1, "\pEnable 1 Mb (SlowMem)");
! 1021: break;
! 1022:
! 1023: case kResMenuID:
! 1024: my_screen_res=(int)menuItem-1;
! 1025: WritePrefs(0);
! 1026: CheckItem(GetMenuHandle(kResMenuID),screen_res+1,false);
! 1027: CheckItem(GetMenuHandle(kResMenuID),my_screen_res+1,true);
! 1028: ParamAString("\pChanges will take effect the next time you run UAE.");
! 1029: DisplayError(kQuitError);
! 1030: break;
! 1031:
! 1032: case kRateMenuID:
! 1033: for (count=1;count<5;count++) CheckItem(GetMenuHandle(kRateMenuID),count,false);
! 1034: if (menuItem == 1) framerate=1;
! 1035: if (menuItem == 2) framerate=3;
! 1036: if (menuItem == 3) framerate=5;
! 1037: if (menuItem == 4) framerate=7;
! 1038: CheckItem(GetMenuHandle(kRateMenuID),menuItem,true);
! 1039: WritePrefs(0);
! 1040: break;
! 1041:
! 1042: case kVideoMenuID:
! 1043: if (menuItem == 5)
! 1044: { my_use_quickdraw = !my_use_quickdraw;
! 1045: WritePrefs(0);
! 1046: CheckItem(GetMenuHandle(kVideoMenuID),5,my_use_quickdraw ? true : false);
! 1047: ParamAString("\pChanges will take effect the next time you run UAE.");
! 1048: DisplayError(kQuitError);
! 1049: }
! 1050: if (menuItem == 7)
! 1051: { my_use_gfxlib = !my_use_gfxlib;
! 1052: WritePrefs(0);
! 1053: CheckItem(GetMenuHandle(kVideoMenuID),7,my_use_gfxlib ? true : false);
! 1054: ParamAString("\pChanges will take effect the next time you run UAE.");
! 1055: DisplayError(kQuitError);
! 1056: }
! 1057: break;
! 1058:
! 1059: default:
! 1060: break;
! 1061: }
! 1062: HiliteMenu(0);
! 1063: flush_screen();
! 1064: if (dont_want_aspect || screen_res == 2) printStatusLine();
! 1065: }
! 1066:
! 1067: static void macHandleCursors(void)
! 1068: { Point mpos;
! 1069:
! 1070: if (redraw)
! 1071: { GetMouse(&mpos);
! 1072: if (!dont_want_aspect && mBarState && screen_res == 4)
! 1073: { if (mpos.v < 20)
! 1074: { ShowCursor();
! 1075: macCursorState=true;
! 1076: }
! 1077: else
! 1078: { if (macCursorState)
! 1079: { HideCursor();
! 1080: macCursorState=false;
! 1081: }
! 1082: }
! 1083: }
! 1084: else
! 1085: if (PtInRect(mpos,&(mywin->portRect)))
! 1086: { if (macCursorState)
! 1087: { HideCursor();
! 1088: macCursorState=false;
! 1089: }
! 1090: }
! 1091: else
! 1092: { if (!macCursorState)
! 1093: { ShowCursor();
! 1094: macCursorState=true;
! 1095: }
! 1096: }
! 1097: }
1.1 root 1098: }
1099:
1100: // Check Minimal System Configuration and Setup
1101: static Boolean CheckForSetup (void)
1.1.1.2 ! root 1102: { Boolean retvalue=false;
1.1 root 1103: SysEnvRec env;
1104:
1.1.1.2 ! root 1105: oldDepth=0;
1.1 root 1106: SysEnvirons( 2, &env );
1107:
1108: if ( env.systemVersion < 0x0700 )
1.1.1.2 ! root 1109: { ParamAString("\pUAE requires System 7 or later!\n Press Ok to Quit...");
1.1 root 1110: DisplayError(kQuitError);
1.1.1.2 ! root 1111: retvalue=true;
1.1 root 1112: }
1113: if ( !env.hasColorQD)
1.1.1.2 ! root 1114: { ParamAString("\pUAE requires Color QuickDraw!\n Press Ok to Quit...");
1.1 root 1115: DisplayError(kQuitError);
1.1.1.2 ! root 1116: retvalue=true;
1.1 root 1117: }
1118: curDevice = GetMainDevice();
1.1.1.2 ! root 1119: gfxvidinfo.pixbytes=((*(*curDevice)->gdPMap)->pixelSize)/8;
1.1 root 1120: return(retvalue);
1121: }
1122:
1123: // Shows up the standard error alert;
1.1.1.2 ! root 1124: static int DisplayError(int ID)
1.1 root 1125: { int ret=0;
1126:
1127: InitCursor();
1128: ret=Alert(ID,0);
1129:
1130: return (ret);
1131: }
1132:
1133: // Parses a Pascal string for error display
1.1.1.2 ! root 1134: static void ParamAString( ConstStr255Param theStr )
1.1 root 1135: {
1136: ParamText(theStr, "\p", "\p", "\p");
1137: }
1.1.1.2 ! root 1138:
! 1139: static void printStatusLine (void)
! 1140: { GrafPtr savePort;
! 1141: Rect updateRect;
! 1142:
! 1143: updateRect.top=screenV;
! 1144: updateRect.bottom=screenV+38;
! 1145: updateRect.left=0;
! 1146: updateRect.right=screenH;
! 1147: GetPort(&savePort);
! 1148: SetPort(mywin);
! 1149: EraseRect(&updateRect);
! 1150: MoveTo(10,screenV+10);
! 1151: TextFont(monaco);
! 1152: TextSize(9);
! 1153: if (screen_res >= 3)
! 1154: DrawString("\pPower LED: Drive LEDs: DF0: DF1: DF2: DF3:");
! 1155: else DrawString("\pPower: DF0: DF1: DF2: DF3:");
! 1156: TextFont(0);
! 1157: TextSize(0);
! 1158: SetPort(savePort);
! 1159: }
! 1160:
! 1161: typedef struct {
! 1162: StandardFileReply *replyPtr;
! 1163: FSSpec oldSelection;
! 1164: } SFData, *SFDataPtr;
! 1165:
! 1166: /* constants */
! 1167:
! 1168: #define kSelectItem 10
! 1169: #define kSFDlg 128
! 1170: #define kCanSelectDesktop true
! 1171: #define kSelectStrRsrc 128
! 1172: #define kDefaultSelectString "\pSelect"
! 1173: #define kDeskStrRsrc 129
! 1174: #define kDefaultDeskString "\pDesktop"
! 1175: #define kSelectKey 's'
! 1176:
! 1177: /* globals */
! 1178:
! 1179: Boolean gHasFindFolder;
! 1180: FSSpec gDeskFolderSpec;
! 1181: Str255 gSelectString;
! 1182: Str255 gDesktopFName;
! 1183:
! 1184: FileFilterYDUPP Share_FilterAllFiles_UPP;
! 1185: DlgHookYDUPP Share_MyDlgHook_UPP;
! 1186: ModalFilterYDUPP Share_MyModalFilter_UPP;
! 1187:
! 1188: /* prototypes */
! 1189:
! 1190: static void Share_Init(void);
! 1191: static Boolean Share_CustomGet(FSSpec *fSpec);
! 1192: static pascal short Share_MyDlgHook(short item,DialogPtr theDlg,Ptr userData);
! 1193: static pascal Boolean Share_MyModalFilter(DialogPtr theDlg,EventRecord *ev,short *itemHit,Ptr myData);
! 1194: static void Share_HitButton(DialogPtr theDlg,short item);
! 1195: static pascal Boolean Share_FilterAllFiles(CInfoPBPtr pb, Ptr myDataPtr);
! 1196: static void Share_SetSelectButtonName(StringPtr selName,Boolean hilited,DialogPtr theDlg);
! 1197: static Boolean Share_SameFile(FSSpec *file1,FSSpec *file2);
! 1198: static Boolean Share_GetFSSpecPartialName(FSSpec *file,StringPtr fName);
! 1199: static OSErr Share_GetDeskFolderSpec(FSSpec *fSpec,short vRefNum);
! 1200: static OSErr Share_MakeCanonFSSpec(FSSpec *fSpec);
! 1201: static Boolean Share_ShouldHiliteSelect(FSSpec *fSpec);
! 1202:
! 1203:
! 1204: static void Share_main(void)
! 1205: { FSSpec fSpec;
! 1206: Boolean good;
! 1207: GrafPtr oldPort;
! 1208: char share_path[1024];
! 1209: Handle share_handle;
! 1210: short backup;
! 1211:
! 1212: GetPort(&oldPort);
! 1213: Share_Init();
! 1214:
! 1215: good = Share_CustomGet(&fSpec);
! 1216:
! 1217: if (good)
! 1218: { Share_ResolvePath(&fSpec,share_path);
! 1219: backup=filesys_vRefNum;
! 1220: filesys_vRefNum=fSpec.vRefNum;
! 1221: WritePrefs(share_path);
! 1222: filesys_vRefNum=backup;
! 1223: }
! 1224: SetPort(oldPort);
! 1225: }
! 1226:
! 1227: static void Share_Init(void)
! 1228: {
! 1229: Handle strHndl;
! 1230:
! 1231: gHasFindFolder = true;
! 1232:
! 1233: Share_FilterAllFiles_UPP=NewFileFilterYDProc(Share_FilterAllFiles);
! 1234: Share_MyDlgHook_UPP=NewDlgHookYDProc(Share_MyDlgHook);
! 1235: Share_MyModalFilter_UPP=NewModalFilterYDProc(Share_MyModalFilter);
! 1236:
! 1237: strHndl = Get1Resource('STR ',kSelectStrRsrc);
! 1238: if (ResError()!=noErr || !strHndl || !*strHndl)
! 1239: BlockMove(kDefaultSelectString,gSelectString,kDefaultSelectString[0]+1);
! 1240: else {
! 1241: BlockMove(*strHndl,&gSelectString,(long)((unsigned char *)(*strHndl)[0]+1));
! 1242: ReleaseResource(strHndl);
! 1243: }
! 1244:
! 1245: strHndl = Get1Resource('STR ',kDeskStrRsrc);
! 1246: if (ResError()!=noErr || !strHndl || !*strHndl)
! 1247: BlockMove(kDefaultDeskString,gDesktopFName,kDefaultSelectString[0]+1);
! 1248: else {
! 1249: BlockMove(*strHndl,&gDesktopFName,(long)((unsigned char *)(*strHndl)[0]+1));
! 1250: ReleaseResource(strHndl);
! 1251: }
! 1252: }
! 1253:
! 1254:
! 1255: /* do getfile */
! 1256:
! 1257: static Boolean Share_CustomGet(FSSpec *fSpec)
! 1258: {
! 1259: Point where = {-1,-1};
! 1260: SFReply reply;
! 1261: DialogPtr theDialog;
! 1262: short item;
! 1263: StandardFileReply sfReply;
! 1264: SFData sfUserData;
! 1265: OSErr err;
! 1266: Boolean targetIsFolder,wasAliased;
! 1267:
! 1268: /* initialize user data area */
! 1269:
! 1270: sfUserData.replyPtr = &sfReply;
! 1271: sfUserData.oldSelection.vRefNum = -9999; /* init to ridiculous value */
! 1272:
! 1273: CustomGetFile(Share_FilterAllFiles_UPP,-1,nil,&sfReply,kSFDlg,where,Share_MyDlgHook_UPP,
! 1274: Share_MyModalFilter_UPP,nil,nil,&sfUserData);
! 1275:
! 1276: if (sfReply.sfGood) {
! 1277: err = ResolveAliasFile(&sfReply.sfFile,true,&targetIsFolder,&wasAliased);
! 1278: if (err!=noErr)
! 1279: return false;
! 1280: }
! 1281:
! 1282: err = FSMakeFSSpec(sfReply.sfFile.vRefNum,sfReply.sfFile.parID,sfReply.sfFile.name,fSpec);
! 1283: if (err!=noErr)
! 1284: return false;
! 1285:
! 1286: return sfReply.sfGood;
! 1287: }
! 1288:
! 1289: static pascal short Share_MyDlgHook(short item,DialogPtr theDlg,Ptr userData)
! 1290: {
! 1291: SFDataPtr sfUserData;
! 1292: Boolean hiliteButton;
! 1293: FSSpec curSpec;
! 1294: OSType refCon;
! 1295:
! 1296: refCon = GetWRefCon(theDlg);
! 1297: if (refCon!=sfMainDialogRefCon)
! 1298: return item;
! 1299:
! 1300: sfUserData = (SFDataPtr) userData;
! 1301:
! 1302: if (item==sfHookFirstCall || item==sfHookLastCall)
! 1303: return item;
! 1304:
! 1305: if (item==sfItemVolumeUser) {
! 1306: sfUserData->replyPtr->sfFile.name[0] = '\0';
! 1307: sfUserData->replyPtr->sfFile.parID = 2;
! 1308: sfUserData->replyPtr->sfIsFolder = false;
! 1309: sfUserData->replyPtr->sfIsVolume = false;
! 1310: sfUserData->replyPtr->sfFlags = 0;
! 1311: item = sfHookChangeSelection;
! 1312: }
! 1313:
! 1314: if (!Share_SameFile(&sfUserData->replyPtr->sfFile,&sfUserData->oldSelection)) {
! 1315: BlockMove(&sfUserData->replyPtr->sfFile,&curSpec,sizeof(FSSpec));
! 1316: Share_MakeCanonFSSpec(&curSpec);
! 1317:
! 1318: if (curSpec.vRefNum!=sfUserData->oldSelection.vRefNum)
! 1319: Share_GetDeskFolderSpec(&gDeskFolderSpec,curSpec.vRefNum);
! 1320: Share_SetSelectButtonName(curSpec.name,Share_ShouldHiliteSelect(&curSpec),theDlg);
! 1321:
! 1322: BlockMove(&sfUserData->replyPtr->sfFile,&sfUserData->oldSelection,sizeof(FSSpec));
! 1323: }
! 1324:
! 1325: if (item==kSelectItem)
! 1326: item = sfItemOpenButton;
! 1327:
! 1328: return item;
! 1329: }
! 1330:
! 1331:
! 1332: static pascal Boolean Share_MyModalFilter(DialogPtr theDlg,EventRecord *ev,short *itemHit,Ptr myData)
! 1333: {
! 1334: Boolean evHandled;
! 1335: char keyPressed;
! 1336: OSType refCon;
! 1337:
! 1338: refCon = GetWRefCon(theDlg);
! 1339: if (refCon!=sfMainDialogRefCon)
! 1340: return false;
! 1341:
! 1342: evHandled = false;
! 1343:
! 1344: switch (ev->what) {
! 1345: case keyDown:
! 1346: case autoKey:
! 1347: keyPressed = ev->message & charCodeMask;
! 1348: if ((ev->modifiers & cmdKey) != 0) {
! 1349: switch (keyPressed) {
! 1350: case kSelectKey:
! 1351: Share_HitButton(theDlg,kSelectItem);
! 1352: *itemHit = kSelectItem;
! 1353: evHandled = true;
! 1354: break;
! 1355: }
! 1356: }
! 1357: break;
! 1358: }
! 1359:
! 1360: return evHandled;
! 1361: }
! 1362:
! 1363:
! 1364: static void Share_HitButton(DialogPtr theDlg,short item)
! 1365: {
! 1366: short iType;
! 1367: Handle iHndl;
! 1368: Rect iRect;
! 1369: long fTicks;
! 1370:
! 1371: GetDItem(theDlg,item,&iType,&iHndl,&iRect);
! 1372: HiliteControl((ControlHandle)iHndl,inButton);
! 1373: Delay(5,&fTicks);
! 1374: HiliteControl((ControlHandle)iHndl,0);
! 1375: }
! 1376:
! 1377:
! 1378: static pascal Boolean Share_FilterAllFiles(CInfoPBPtr pb, Ptr myDataPtr)
! 1379: {
! 1380: if (pb->hFileInfo.ioFlAttrib & (1<<4)) /* file is a directory */
! 1381: return false;
! 1382:
! 1383: return true;
! 1384: }
! 1385:
! 1386:
! 1387: static void Share_SetSelectButtonName(StringPtr selName,Boolean hilited,DialogPtr theDlg)
! 1388: {
! 1389: ControlHandle selectButton;
! 1390: short iType;
! 1391: Handle iHndl;
! 1392: Rect iRect;
! 1393: Str255 storeName,tempLenStr,tempSelName;
! 1394: short btnWidth;
! 1395:
! 1396: BlockMove(selName,tempSelName,selName[0]+1);
! 1397: GetDItem(theDlg,kSelectItem,&iType,&iHndl,&iRect);
! 1398:
! 1399: /* truncate select name to fit in button */
! 1400:
! 1401: btnWidth = iRect.right - iRect.left;
! 1402: BlockMove(gSelectString,tempLenStr,gSelectString[0]+1);
! 1403: p2cstr(tempLenStr);
! 1404: strcat((char *)tempLenStr," �� ");
! 1405: c2pstr((char *)tempLenStr);
! 1406: btnWidth -= StringWidth(tempLenStr);
! 1407: TruncString(btnWidth,tempSelName,smTruncMiddle);
! 1408:
! 1409: BlockMove(gSelectString,storeName,gSelectString[0]+1);
! 1410: p2cstr(storeName);
! 1411: p2cstr(tempSelName);
! 1412: strcat((char *)storeName," �");
! 1413: strcat((char *)storeName,(char *)tempSelName);
! 1414: strcat((char *)storeName,"�");
! 1415:
! 1416: c2pstr((char *)storeName);
! 1417: c2pstr((char *)tempSelName);
! 1418: SetCTitle((ControlHandle)iHndl,storeName);
! 1419:
! 1420: SetDItem(theDlg,kSelectItem,iType,iHndl,&iRect);
! 1421:
! 1422: if (hilited)
! 1423: HiliteControl((ControlHandle)iHndl,0);
! 1424: else
! 1425: HiliteControl((ControlHandle)iHndl,255);
! 1426: }
! 1427:
! 1428:
! 1429: static Boolean Share_SameFile(FSSpec *file1,FSSpec *file2)
! 1430: {
! 1431: if (file1->vRefNum != file2->vRefNum)
! 1432: return false;
! 1433: if (file1->parID != file2->parID)
! 1434: return false;
! 1435: if (!EqualString(file1->name,file2->name,false,true))
! 1436: return false;
! 1437:
! 1438: return true;
! 1439: }
! 1440:
! 1441:
! 1442: static OSErr Share_GetDeskFolderSpec(FSSpec *fSpec,short vRefNum)
! 1443: {
! 1444: DirInfo infoPB;
! 1445: OSErr err;
! 1446:
! 1447: if (!gHasFindFolder) {
! 1448: fSpec->vRefNum = -9999;
! 1449: return -1;
! 1450: }
! 1451:
! 1452: fSpec->name[0] = '\0';
! 1453: err = FindFolder(vRefNum,kDesktopFolderType,kDontCreateFolder,
! 1454: &fSpec->vRefNum,&fSpec->parID);
! 1455: if (err!=noErr)
! 1456: return err;
! 1457:
! 1458: return Share_MakeCanonFSSpec(fSpec);
! 1459: }
! 1460:
! 1461:
! 1462: static Boolean Share_ShouldHiliteSelect(FSSpec *fSpec)
! 1463: {
! 1464: if (Share_SameFile(fSpec,&gDeskFolderSpec)) {
! 1465: BlockMove(gDesktopFName,fSpec->name,gDesktopFName[0]+1);
! 1466: return kCanSelectDesktop;
! 1467: }
! 1468: else
! 1469: return true;
! 1470: }
! 1471:
! 1472: static OSErr Share_MakeCanonFSSpec(FSSpec *fSpec)
! 1473: {
! 1474: CInfoPBRec infoPB;
! 1475: OSErr err;
! 1476:
! 1477: if (fSpec->name[0] != '\0')
! 1478: return;
! 1479:
! 1480: infoPB.dirInfo.ioNamePtr = fSpec->name;
! 1481: infoPB.dirInfo.ioVRefNum = fSpec->vRefNum;
! 1482: infoPB.dirInfo.ioDrDirID = fSpec->parID;
! 1483: infoPB.dirInfo.ioFDirIndex = -1;
! 1484: err = PBGetCatInfo(&infoPB,false);
! 1485: fSpec->parID = infoPB.dirInfo.ioDrParID;
! 1486:
! 1487: return err;
! 1488: }
! 1489:
! 1490: static void Share_ResolvePath (FSSpec *fSpec, char *path)
! 1491: { char volname[128];
! 1492: char dirname[128];
! 1493: char path_copy[1024];
! 1494: short the_vRefNum;
! 1495: long the_parID;
! 1496: CInfoPBRec infoPB;
! 1497:
! 1498: volname[0]=0;
! 1499: strcpy(dirname,(char *)fSpec->name);
! 1500: p2cstr((unsigned char *)dirname);
! 1501:
! 1502: strcpy(path,dirname);
! 1503:
! 1504: the_vRefNum=(fSpec->vRefNum);
! 1505: the_parID=(fSpec->parID);
! 1506:
! 1507: infoPB.dirInfo.ioNamePtr = (unsigned char *)volname;
! 1508: infoPB.dirInfo.ioVRefNum = the_vRefNum;
! 1509: infoPB.dirInfo.ioDrDirID = fsRtDirID;
! 1510: infoPB.dirInfo.ioFDirIndex = -1;
! 1511: PBGetCatInfo(&infoPB,false);
! 1512:
! 1513: p2cstr((unsigned char *)volname);
! 1514:
! 1515: while (strcmp(volname,dirname) != 0)
! 1516: {
! 1517: infoPB.dirInfo.ioNamePtr = (unsigned char *)dirname;
! 1518: infoPB.dirInfo.ioVRefNum = the_vRefNum;
! 1519: infoPB.dirInfo.ioDrDirID = the_parID;
! 1520: infoPB.dirInfo.ioFDirIndex = -1;
! 1521: PBGetCatInfo(&infoPB,false);
! 1522: the_parID = infoPB.dirInfo.ioDrParID;
! 1523:
! 1524: p2cstr((unsigned char *)dirname);
! 1525: strcpy(path_copy,dirname);
! 1526: strcat(path_copy,":");
! 1527: strcat(path_copy,path);
! 1528: strcpy(path,path_copy);
! 1529: }
! 1530: }
! 1531:
! 1532: Boolean ReadPrefs (char *share_path)
! 1533: { OSErr err=noErr;
! 1534: short prefsFolder;
! 1535: Str255 prefsName="\pUAE Preferences";
! 1536: long prefDirID;
! 1537: short prefvRefNum;
! 1538: FSSpec spec;
! 1539: short home,preffile;
! 1540: Handle share_handle;
! 1541: Handle config_handle;
! 1542: int config_sets[128],count;
! 1543:
! 1544: home = CurResFile();
! 1545: preffile=0;
! 1546: *share_path=0;
! 1547:
! 1548: err=FindFolder(kOnSystemDisk, kPreferencesFolderType, true, &prefvRefNum, &prefDirID);
! 1549: if (err != noErr) return false;
! 1550: FSMakeFSSpec(prefvRefNum, prefDirID, prefsName, &spec);
! 1551:
! 1552: preffile=FSpOpenResFile(&spec, fsRdWrPerm);
! 1553: if (ResError() != noErr) return false;
! 1554:
! 1555: UseResFile(preffile);
! 1556:
! 1557: if (share_path != 0)
! 1558: { share_handle = Get1Resource('STR ',128);
! 1559: if (ResError() == noErr && share_handle !=0 && *share_handle !=0)
! 1560: { strcpy(share_path,*share_handle);
! 1561: ReleaseResource(share_handle);
! 1562: }
! 1563: }
! 1564:
! 1565: config_handle = Get1Resource('PREF',128);
! 1566: if (ResError() == noErr && config_handle !=0)
! 1567: { BlockMove((Ptr) *config_handle,(Ptr) config_sets,128);
! 1568: ReleaseResource(config_handle);
! 1569:
! 1570: framerate=config_sets[0];
! 1571: use_slow_mem=config_sets[1];
! 1572: use_gfxlib=config_sets[2];
! 1573: automount_uaedev=config_sets[3];
! 1574: produce_sound=config_sets[4];
! 1575: fake_joystick=config_sets[5];
! 1576: screen_res=config_sets[6];
! 1577: use_quickdraw=config_sets[7];
! 1578: filesys_vRefNum=config_sets[8];
! 1579: }
! 1580:
! 1581: UseResFile(home);
! 1582: CloseResFile(preffile);
! 1583: return true;
! 1584: }
! 1585:
! 1586: void CreatePrefs (void)
! 1587: { OSErr err=noErr;
! 1588: short prefsFolder;
! 1589: Str255 prefsName="\pUAE Preferences";
! 1590: long prefDirID;
! 1591: short prefvRefNum;
! 1592: FSSpec spec;
! 1593: short home,preffile;
! 1594:
! 1595: home = CurResFile();
! 1596: preffile=0;
! 1597:
! 1598: err=FindFolder(kOnSystemDisk, kPreferencesFolderType, true, &prefvRefNum, &prefDirID);
! 1599: if (err != noErr) return;
! 1600: FSMakeFSSpec(prefvRefNum, prefDirID, prefsName, &spec);
! 1601:
! 1602: err=FSpCreate(&spec, 'mUAE', 'pref', 0);
! 1603: if (err != noErr) return;
! 1604:
! 1605: FSpCreateResFile(&spec, 'mUAE', 'pref', 0);
! 1606: }
! 1607:
! 1608: void WritePrefs (char *share_path)
! 1609: { OSErr err=noErr;
! 1610: short prefsFolder;
! 1611: Str255 prefsName="\pUAE Preferences";
! 1612: long prefDirID;
! 1613: short prefvRefNum;
! 1614: FSSpec spec;
! 1615: short home,preffile;
! 1616: Handle share_handle;
! 1617: Handle config_handle;
! 1618: int config_sets[128],count;
! 1619:
! 1620: home = CurResFile();
! 1621: preffile=0;
! 1622:
! 1623: err=FindFolder(kOnSystemDisk, kPreferencesFolderType, true, &prefvRefNum, &prefDirID);
! 1624: if (err != noErr) return;
! 1625: FSMakeFSSpec(prefvRefNum, prefDirID, prefsName, &spec);
! 1626:
! 1627: preffile=FSpOpenResFile(&spec, fsRdWrPerm);
! 1628: if (ResError() != noErr) return;
! 1629:
! 1630: for (count=0;count < 64;count++) config_sets[count]=0;
! 1631:
! 1632: config_sets[0]=framerate;
! 1633: config_sets[1]=use_slow_mem;
! 1634: config_sets[2]=my_use_gfxlib;
! 1635: config_sets[3]=my_automount_uaedev;
! 1636: config_sets[4]=produce_sound;
! 1637: config_sets[5]=fake_joystick;
! 1638: config_sets[6]=my_screen_res;
! 1639: config_sets[7]=my_use_quickdraw;
! 1640: config_sets[8]=filesys_vRefNum;
! 1641:
! 1642: UseResFile(preffile);
! 1643:
! 1644:
! 1645: if (share_path != 0)
! 1646: { share_handle=Get1Resource('STR ',128);
! 1647: if (ResError() != noErr || share_handle == 0)
! 1648: { share_handle=NewHandleClear(1024);
! 1649: strcpy(*share_handle,share_path);
! 1650: AddResource(share_handle,'STR ',128, "\pMac/Amiga sharing path");
! 1651: WriteResource(share_handle);
! 1652: DetachResource(share_handle);
! 1653: }
! 1654: else
! 1655: { strcpy(*share_handle,share_path);
! 1656: ChangedResource(share_handle);
! 1657: WriteResource(share_handle);
! 1658: ReleaseResource(share_handle);
! 1659: }
! 1660: }
! 1661:
! 1662: config_handle=Get1Resource('PREF',128);
! 1663: if (ResError() != noErr || config_handle == 0)
! 1664: { config_handle=NewHandleClear(1024);
! 1665: BlockMove((Ptr) config_sets,(Ptr) *config_handle,128);
! 1666: AddResource(config_handle,'PREF',128, "\pUAE Preferences");
! 1667: WriteResource(config_handle);
! 1668: DetachResource(config_handle);
! 1669: }
! 1670: else
! 1671: { BlockMove((Ptr) config_sets,(Ptr) *config_handle,128);
! 1672: ChangedResource(config_handle);
! 1673: WriteResource(config_handle);
! 1674: ReleaseResource(config_handle);
! 1675: }
! 1676:
! 1677: UseResFile(home);
! 1678: CloseResFile(preffile);
! 1679: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.