3 /* Purpose: Simple support for MACINTOSH Angband */
6 * This file should only be compiled with the "Macintosh" version
8 * This file written by "Ben Harrison (benh@phial.com)".
10 * Some code adapted from "MacAngband 2.6.1" by Keith Randall
12 * Maarten Hazewinkel (mmhazewi@cs.ruu.nl) provided some initial
13 * suggestions for the PowerMac port.
15 * Steve Linberg (slinberg@crocker.com) provided the code surrounded
18 * The graphics code is adapted from an extremely minimal subset of
19 * the code from "Sprite World II", an amazing animation package.
21 * See "z-term.c" for info on the concept of the "generic terminal"
23 * The preference file is now a text file named "Angband preferences".
25 * Note that the "preference" file is now a simple text file called
26 * "Angband preferences", which contains the versions information, so
27 * that obsolete preference files can be ignored (this may be bad).
29 * Note that "init1.c", "init2.c", "load1.c", "load2.c", and "birth.c"
30 * should probably be "unloaded" as soon as they are no longer needed,
31 * to save space, but I do not know how to do this.
33 * Stange bug -- The first "ClipRect()" call crashes if the user closes
34 * all the windows, switches to another application, switches back, and
35 * then re-opens the main window, for example, using "command-a".
37 * By default, this file assumes that you will be using a 68020 or better
38 * machine, running System 7 and Color Quickdraw. In fact, the game will
39 * refuse to run unless these features are available. This allows the use
40 * of a variety of interesting features such as graphics and sound.
42 * To create a version which can be used on 68000 machines, or on machines
43 * which are not running System 7 or Color Quickdraw, simply activate the
44 * "ANGBAND_LITE_MAC" compilation flag in the proper header file. This
45 * will disable all "modern" features used in this file, including support
46 * for multiple sub-windows, color, graphics, and sound.
48 * When compiling with the "ANGBAND_LITE_MAC" flag, the "ANGBAND_LITE"
49 * flag will be automatically defined, which will disable many of the
50 * advanced features of the game itself, reducing the total memory usage.
52 * If you are never going to use "graphics" (especially if you are not
53 * compiling support for graphics anyway) then you can delete the "pict"
54 * resource with id "1001" with no dangerous side effects.
59 * Important Resources in the resource file:
61 * FREF 130 = 'A271' / 'APPL' (application)
62 * FREF 129 = 'A271' / 'SAVE' (save file)
63 * FREF 130 = 'A271' / 'TEXT' (bone file, generic text file)
64 * FREF 131 = 'A271' / 'DATA' (binary image file, score file)
66 * DLOG 128 = "About Angband..."
68 * ALRT 128 = unused (?)
69 * ALRT 129 = "Warning..."
70 * ALRT 130 = "Are you sure you want to quit without saving?"
72 * DITL 128 = body for DLOG 128
73 * DITL 129 = body for ALRT 129
74 * DITL 130 = body for ALRT 130
76 * ICON 128 = "warning" icon
78 * MENU 128 = apple (about, -, ...)
79 * MENU 129 = File (new, open, close, save, -, exit, quit)
80 * MENU 130 = Edit (undo, -, cut, copy, paste, clear)
82 * PICT 1001 = Graphics tile set
88 * all 'APEX' files have a filename of the form "*:apex:*" (?)
89 * all 'BONE' files have a filename of the form "*:bone:*" (?)
90 * all 'DATA' files have a filename of the form "*:data:*"
91 * all 'SAVE' files have a filename of the form "*:save:*"
92 * all 'USER' files have a filename of the form "*:user:*" (?)
94 * Perhaps we should attempt to set the "_ftype" flag inside this file,
95 * to avoid nasty file type information being spread all through the
96 * rest of the code. (?) This might require adding hooks into the
97 * "fd_open()" and "my_fopen()" functions in "util.c". XXX XXX XXX
102 * Reasons for each header file:
104 * angband.h = Angband header file
106 * Types.h = (included anyway)
107 * Gestalt.h = gestalt code
108 * QuickDraw.h = (included anyway)
109 * OSUtils.h = (included anyway)
110 * Files.h = file code
111 * Fonts.h = font code
112 * Menus.h = menu code
113 * Dialogs.h = dialog code
114 * Windows.h = (included anyway)
115 * Palettes.h = palette code
116 * StandardFile.h = file dialog box
117 * DiskInit.h = disk initialization
118 * ToolUtils.h = HiWord() / LoWord()
119 * Desk.h = OpenDeskAcc()
120 * Devices.h = OpenDeskAcc()
121 * Events.h = event code
122 * Resources.h = resource code
123 * Controls.h = button code
124 * SegLoad.h = ExitToShell(), AppFile, etc
125 * Memory.h = SetApplLimit(), NewPtr(), etc
126 * QDOffscreen.h = GWorld code
127 * Sound.h = Sound code
129 * For backwards compatibility:
130 * Use GestaltEqu.h instead of Gestalt.h
131 * Add Desk.h to include simply includes Menus.h, Devices.h, Events.h
139 #include <QuickDraw.h>
145 #include <Palettes.h>
146 #include <StandardFile.h>
147 #include <DiskInit.h>
148 #include <ToolUtils.h>
151 #include <Resources.h>
152 #include <Controls.h>
155 #include <QDOffscreen.h>
157 #if TARGET_API_MAC_CARBON
158 #include <Navigation.h>
168 * Cleaning up a couple of things to make these easier to change --AR
171 #define PREF_FILE_NAME "Hengband Preferences"
173 #define PREF_FILE_NAME "Hengband-E Preferences"
177 * Use "malloc()" instead of "NewPtr()"
179 /* #define USE_MALLOC */
182 #if defined(powerc) || defined(__powerc)
185 * Disable "LITE" version
187 # undef ANGBAND_LITE_MAC
192 #ifdef ANGBAND_LITE_MAC
195 * Maximum number of windows
197 # define MAX_TERM_DATA 1
199 #else /* ANGBAND_LITE_MAC */
202 * Maximum number of windows
204 # define MAX_TERM_DATA 8
207 * Activate some special code
209 # define USE_SFL_CODE
211 #endif /* ANGBAND_LITE_MAC */
218 * Include the necessary header files
220 #include <AppleEvents.h>
228 * Globals for MPW compilation
242 * The Angband Color Set (0 to 15):
243 * Black, White, Slate, Orange, Red, Blue, Green, Umber
244 * D-Gray, L-Gray, Violet, Yellow, L-Red, L-Blue, L-Green, L-Umber
246 * Colors 8 to 15 are basically "enhanced" versions of Colors 0 to 7.
248 * On the Macintosh, we use color quickdraw, and we use actual "RGB"
249 * values below to choose the 16 colors.
251 * If we are compiled for ancient machines, we bypass color and simply
252 * draw everything in white (letting "z-term.c" automatically convert
253 * "black" into "wipe" calls).
255 static RGBColor foo[16] =
257 {0x0000, 0x0000, 0x0000}, /* TERM_DARK */
258 {0xFFFF, 0xFFFF, 0xFFFF}, /* TERM_WHITE */
259 {0x8080, 0x8080, 0x8080}, /* TERM_SLATE */
260 {0xFFFF, 0x8080, 0x0000}, /* TERM_ORANGE */
261 {0xC0C0, 0x0000, 0x0000}, /* TERM_RED */
262 {0x0000, 0x8080, 0x4040}, /* TERM_GREEN */
263 {0x0000, 0x0000, 0xFFFF}, /* TERM_BLUE */
264 {0x8080, 0x4040, 0x0000}, /* TERM_UMBER */
265 {0x4040, 0x4040, 0x4040}, /* TERM_L_DARK */
266 {0xC0C0, 0xC0C0, 0xC0C0}, /* TERM_L_WHITE */
267 {0xFFFF, 0x0000, 0xFFFF}, /* TERM_VIOLET */
268 {0xFFFF, 0xFFFF, 0x0000}, /* TERM_YELLOW */
269 {0xFFFF, 0x0000, 0x0000}, /* TERM_L_RED */
270 {0x0000, 0xFFFF, 0x0000}, /* TERM_L_GREEN */
271 {0x0000, 0xFFFF, 0xFFFF}, /* TERM_L_BLUE */
272 {0xC0C0, 0x8080, 0x4040} /* TERM_L_UMBER */
281 typedef struct term_data term_data;
294 #ifdef ANGBAND_LITE_MAC
298 #else /* ANGBAND_LITE_MAC */
310 #endif /* ANGBAND_LITE_MAC */
353 * Forward declare -- see below
355 static bool CheckEvents(bool wait);
359 * Hack -- location of the main directory
361 static short app_vol;
366 * Delay handling of double-clicked savefiles
368 Boolean open_when_ready = FALSE;
371 * Delay handling of pre-emptive "quit" event
373 Boolean quit_when_ready = FALSE;
377 * Hack -- game in progress
379 static int game_in_progress = 0;
383 * Only do "SetPort()" when needed
385 static WindowPtr active = NULL;
390 * An array of term_data's
392 static term_data data[MAX_TERM_DATA];
397 * Note when "open"/"new" become valid
399 static bool initialized = FALSE;
404 * CodeWarrior uses Universal Procedure Pointers
406 static ModalFilterUPP ynfilterUPP;
413 AEEventHandlerUPP AEH_Start_UPP;
414 AEEventHandlerUPP AEH_Quit_UPP;
415 AEEventHandlerUPP AEH_Print_UPP;
416 AEEventHandlerUPP AEH_Open_UPP;
424 static int ext_sound = 0;
432 #define SND_CMD_ERROR 6
434 static int soundchoice[] = {
502 static int soundmode[8];
504 static int ext_graf = 0;
509 * Convert refnum+vrefnum+fname into a full file name
510 * Store this filename in 'buf' (make sure it is long enough)
511 * Note that 'fname' looks to be a "pascal" string
513 #if TARGET_API_MAC_CARBON
514 static void refnum_to_name(char *buf, long refnum, short vrefnum, char *fname)
530 for (j=1; j<=fname[0]; j++)
532 res[i-fname[0]+j] = fname[j];
541 pb.ioDrDirID=pb.ioDrParID;
542 err = FSMakeFSSpec( vref, dirID, "\p", &spec );
548 for (j=1; j<=spec.name[0]; j++)
550 res[i-spec.name[0]+j] = spec.name[j];
557 /* Extract the result */
558 for (j = 0, i++; res[i]; j++, i++) buf[j] = res[i];
562 static void refnum_to_name(char *buf, long refnum, short vrefnum, char *fname)
574 for (j=1; j<=fname[0]; j++)
576 res[i-fname[0]+j] = fname[j];
580 pb.ioCompletion=NULL;
582 pb.ioVRefNum=vrefnum;
588 pb.ioDrDirID=pb.ioDrParID;
589 err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
591 for (j=1; j<=name[0]; j++)
593 res[i-name[0]+j] = name[j];
597 if (pb.ioDrDirID == fsRtDirID) break;
600 /* Extract the result */
601 for (j = 0, i++; res[i]; j++, i++) buf[j] = res[i];
606 #if TARGET_API_MAC_CARBON
607 pascal OSErr FSpLocationFromFullPath(short fullPathLength,
608 const void *fullPath,
616 /* Create a minimal alias from the full pathname */
617 nullString[0] = 0; /* null string to indicate no zone or server name */
618 result = NewAliasMinimalFromFullPath(fullPathLength, fullPath, nullString, nullString, &alias);
619 if ( result == noErr )
621 /* Let the Alias Manager resolve the alias. */
622 result = ResolveAlias(NULL, alias, spec, &wasChanged);
624 /* work around Alias Mgr sloppy volume matching bug */
625 if ( spec->vRefNum == 0 )
627 /* invalidate wrong FSSpec */
632 DisposeHandle((Handle)alias); /* Free up memory used */
641 * XXX XXX XXX Allow the system to ask us for a filename
643 static bool askfor_file(char *buf, int len)
651 /* Default file name */
652 sprintf((char*)dflt + 1, "%s's description", buf);
653 dflt[0] = strlen((char*)dflt + 1);
655 /* Ask for a file name */
656 topleft.h=(qd.screenBits.bounds.left+qd.screenBits.bounds.right)/2-344/2;
657 topleft.v=(2*qd.screenBits.bounds.top+qd.screenBits.bounds.bottom)/3-188/2;
658 SFPutFile(topleft, "\pSelect a filename:", dflt, NULL, &reply);
659 /* StandardPutFile("\pSelect a filename:", dflt, &reply); */
667 GetWDInfo(reply.vRefNum, &vrefnum, &drefnum, &junk);
669 /* Extract the name */
670 refnum_to_name(buf, drefnum, vrefnum, (char*)reply.fName);
682 static void local_to_global( Rect *r )
689 LocalToGlobal( &temp );
697 LocalToGlobal( &temp );
703 static void global_to_local( Rect *r )
710 GlobalToLocal( &temp );
718 GlobalToLocal( &temp );
726 * Center a rectangle inside another rectangle
728 static void center_rect(Rect *r, Rect *s)
730 int centerx = (s->left + s->right)/2;
731 int centery = (2*s->top + s->bottom)/3;
732 int dx = centerx - (r->right - r->left)/2 - r->left;
733 int dy = centery - (r->bottom - r->top)/2 - r->top;
742 * Convert a pascal string in place
744 * This function may be defined elsewhere, but since it is so
745 * small, it is not worth finding the proper function name for
746 * all the different platforms.
748 static void ptocstr(StringPtr src)
752 /* Hack -- pointer */
753 char *s = (char*)(src);
755 /* Hack -- convert the string */
756 for (i = s[0]; i; i--, s++) s[0] = s[1];
758 /* Hack -- terminate the string */
763 #if defined(USE_SFL_CODE)
767 * The following three routines (pstrcat, pstrinsert, and PathNameFromDirID)
768 * were taken from the Think Reference section called "Getting a Full Pathname"
769 * (under the File Manager section). We need PathNameFromDirID to get the
770 * full pathname of the opened savefile, making no assumptions about where it
773 * I had to hack PathNameFromDirID a little for MetroWerks, but it's awfully
776 static void pstrcat(StringPtr dst, StringPtr src)
779 BlockMove(src + 1, dst + *dst + 1, *src);
781 /* adjust length byte */
786 * pstrinsert - insert string 'src' at beginning of string 'dst'
788 static void pstrinsert(StringPtr dst, StringPtr src)
790 /* make room for new string */
791 BlockMove(dst + 1, dst + *src + 1, *dst);
793 /* copy new string in */
794 BlockMove(src + 1, dst + 1, *src);
796 /* adjust length byte */
800 static void PathNameFromDirID(long dirID, short vRefNum, StringPtr fullPathName)
803 Str255 directoryName;
806 fullPathName[0] = '\0';
808 block.dirInfo.ioDrParID = dirID;
809 block.dirInfo.ioNamePtr = directoryName;
813 block.dirInfo.ioVRefNum = vRefNum;
814 block.dirInfo.ioFDirIndex = -1;
815 block.dirInfo.ioDrDirID = block.dirInfo.ioDrParID;
816 err = PBGetCatInfo(&block, FALSE);
817 pstrcat(directoryName, (StringPtr)"\p:");
818 pstrinsert(fullPathName, directoryName);
819 if (block.dirInfo.ioDrDirID == 2) break;
825 #if TARGET_API_MAC_CARBON
827 static OSErr ChooseFile( StringPtr filename, FSSpec selfld )
829 NavReplyRecord reply;
830 NavDialogOptions dialogOptions;
831 NavTypeListHandle navTypeList = NULL;
835 AECreateDesc( typeFSS, &selfld, sizeof(FSSpec), &deffld );
837 err = NavGetDefaultDialogOptions( &dialogOptions );
841 err = NavChooseFile( &deffld, &reply, &dialogOptions, NULL, NULL, NULL, navTypeList, NULL );
843 if ( reply.validRecord && err == noErr ){
844 // grab the target FSSpec from the AEDesc:
850 // retrieve the returned selection:
851 // there is only one selection here we get only the first AEDescList:
852 if (( err = AEGetNthPtr( &(reply.selection), 1, typeFSS, &keyWord, &typeCode, &finalFSSpec, sizeof( FSSpec ), &actualSize )) == noErr )
854 refnum_to_name( filename, finalFSSpec.parID, finalFSSpec.vRefNum, finalFSSpec.name );
855 // 'finalFSSpec' is the chosen file¥Î
858 err = NavDisposeReply( &reply );
860 if( navTypeList != NULL )
862 DisposeHandle( (Handle)navTypeList );
867 AEDisposeDesc( &deffld );
875 * Activate a given window, if necessary
877 static void activate(WindowPtr w)
883 #if TARGET_API_MAC_CARBON
884 if (w) SetPortWindowPort(w);
896 * Display a warning message
898 static void mac_warning(cptr warning)
903 /* Limit of 250 chars */
904 len = strlen(warning);
905 if (len > 250) len = 250;
907 /* Make a "Pascal" string */
909 for (i=0; i<len; i++) text[i+1] = warning[i];
911 /* Prepare the dialog box values */
912 ParamText(text, "\p", "\p", "\p");
914 /* Display the Alert, wait for Okay */
920 /*** Some generic functions ***/
923 #ifdef ANGBAND_LITE_MAC
926 * Hack -- activate a color (0 to 255)
928 #define term_data_color(TD,A) /* Nothing */
930 #else /* ANGBAND_LITE_MAC */
933 * Hack -- activate a color (0 to 255)
935 static void term_data_color(term_data *td, int a)
941 /* Extract the R,G,B data */
942 rv = angband_color_table[a][1];
943 gv = angband_color_table[a][2];
944 bv = angband_color_table[a][3];
947 color.red = (rv | (rv << 8));
948 color.green = (gv | (gv << 8));
949 color.blue = (bv | (bv << 8));
951 /* Activate the color */
952 RGBForeColor(&color);
958 #endif /* ANGBAND_LITE_MAC */
962 * Hack -- Apply and Verify the "font" info
964 * This should usually be followed by "term_data_check_size()"
966 static void term_data_check_font(term_data *td)
972 WindowPtr old = active;
978 /* Instantiate font */
979 TextFont(td->font_id);
980 TextSize(td->font_size);
981 TextFace(td->font_face);
983 /* Extract the font info */
986 /* Assume monospaced */
987 td->font_mono = TRUE;
989 /* Extract the font sizing values XXX XXX XXX */
990 td->font_wid = CharWidth('@'); /* info.widMax; */
991 td->font_hgt = info.ascent + info.descent;
993 td->font_o_y = info.ascent;
995 /* Check important characters */
996 for (i = 33; i < 127; i++)
998 /* Hack -- notice non-mono-space */
999 if (td->font_wid != CharWidth(i)) td->font_mono = FALSE;
1001 /* Hack -- collect largest width */
1002 if (td->font_wid < CharWidth(i)) td->font_wid = CharWidth(i);
1005 /* Set default offsets */
1006 td->tile_o_x = td->font_o_x;
1007 td->tile_o_y = td->font_o_y;
1009 /* Set default tile size */
1010 if( td->tile_wid == 0 && td->tile_hgt == 0 ){
1011 td->tile_wid = td->font_wid;
1012 td->tile_hgt = td->font_hgt;
1015 /* Re-activate the old window */
1021 * Hack -- Apply and Verify the "size" info
1023 static void term_data_check_size(term_data *td)
1027 #if TARGET_API_MAC_CARBON
1028 GetQDGlobalsScreenBits( &screen );
1030 screen = qd.screenBits;
1032 /* Minimal window size */
1035 /* Enforce minimal size */
1036 if (td->cols < 80) td->cols = 80;
1037 if (td->rows < 24) td->rows = 24;
1040 /* Allow small windows for the rest */
1043 if (td->cols < 1) td->cols = 1;
1044 if (td->rows < 1) td->rows = 1;
1047 /* Minimal tile size */
1048 if (td->tile_wid < 4) td->tile_wid = 4;
1049 if (td->tile_hgt < 4) td->tile_hgt = 4;
1051 /* Default tile offsets */
1052 td->tile_o_x = (td->tile_wid - td->font_wid) / 2;
1053 td->tile_o_y = (td->tile_hgt - td->font_hgt) / 2;
1055 /* Minimal tile offsets */
1056 if (td->tile_o_x < 0) td->tile_o_x = 0;
1057 if (td->tile_o_y < 0) td->tile_o_y = 0;
1059 /* Apply font offsets */
1060 td->tile_o_x += td->font_o_x;
1061 td->tile_o_y += td->font_o_y;
1063 /* Calculate full window size */
1064 td->size_wid = td->cols * td->tile_wid + td->size_ow1 + td->size_ow2;
1065 td->size_hgt = td->rows * td->tile_hgt + td->size_oh1 + td->size_oh2;
1067 /* Verify the top */
1068 if (td->r.top > screen.bounds.bottom - td->size_hgt)
1070 td->r.top = screen.bounds.bottom - td->size_hgt;
1073 /* Verify the top */
1074 if (td->r.top < screen.bounds.top + 30)
1076 td->r.top = screen.bounds.top + 30;
1079 /* Verify the left */
1080 if (td->r.left > screen.bounds.right - td->size_wid)
1082 td->r.left = screen.bounds.right - td->size_wid;
1085 /* Verify the left */
1086 if (td->r.left < screen.bounds.left)
1088 td->r.left = screen.bounds.left;
1091 /* Calculate bottom right corner */
1092 td->r.right = td->r.left + td->size_wid;
1093 td->r.bottom = td->r.top + td->size_hgt;
1095 /* Assume no graphics */
1096 td->t->higher_pict = FALSE;
1097 td->t->always_pict = FALSE;
1099 #ifdef ANGBAND_LITE_MAC
1103 #else /* ANGBAND_LITE_MAC */
1105 /* Handle graphics */
1108 /* Use higher_pict whenever possible */
1109 if (td->font_mono) td->t->higher_pict = TRUE;
1111 /* Use always_pict only when necessary */
1112 else td->t->always_pict = TRUE;
1115 #endif /* ANGBAND_LITE_MAC */
1117 /* Fake mono-space */
1118 if (!td->font_mono ||
1119 (td->font_wid != td->tile_wid) ||
1120 (td->font_hgt != td->tile_hgt))
1122 /* Handle fake monospace -- this is SLOW */
1123 if (td->t->higher_pict) td->t->higher_pict = FALSE;
1124 td->t->always_pict = TRUE;
1129 * Hack -- resize a term_data
1131 * This should normally be followed by "term_data_resize()"
1133 static void term_data_resize(term_data *td)
1135 /* Actually resize the window */
1136 SizeWindow(td->w, td->size_wid, td->size_hgt, 0);
1142 * Hack -- redraw a term_data
1144 * Note that "Term_redraw()" calls "TERM_XTRA_CLEAR"
1146 static void term_data_redraw(term_data *td)
1150 /* Activate the term */
1151 Term_activate(td->t);
1153 /* Redraw the contents */
1156 /* Flush the output */
1159 /* Restore the old term */
1162 /* No need to redraw */
1163 #if TARGET_API_MAC_CARBON
1165 RgnHandle theRgn = NewRgn();
1166 GetWindowRegion( td->w, kWindowContentRgn, theRgn );
1167 ValidWindowRgn( (WindowRef)(td->w), theRgn );
1168 DisposeRgn( theRgn );
1171 ValidRect(&td->w->portRect);
1179 #ifdef ANGBAND_LITE_MAC
1183 #else /* ANGBAND_LITE_MAC */
1190 static int pictID = 1001; /* 8x8 tiles; 16x16 tiles are 1002 */
1192 static int grafWidth = 8; /* Always equal to grafHeight */
1193 static int grafHeight = 8; /* Either 8 or 16 */
1195 static bool arg_newstyle_graphics;
1196 static bool use_newstyle_graphics;
1201 typedef struct FrameRec FrameRec;
1206 * - GWorld for the frame image
1207 * - Handle to pix map (saved for unlocking/locking)
1208 * - Pointer to color pix map (valid only while locked)
1212 GWorldPtr framePort;
1213 PixMapHandle framePixHndl;
1220 * The global picture data
1222 static FrameRec *frameP = NULL;
1228 static void BenSWLockFrame(FrameRec *srcFrameP)
1230 PixMapHandle pixMapH;
1232 pixMapH = GetGWorldPixMap(srcFrameP->framePort);
1233 (void)LockPixels(pixMapH);
1234 HLockHi((Handle)pixMapH);
1235 srcFrameP->framePixHndl = pixMapH;
1236 #if TARGET_API_MAC_CARBON
1237 srcFrameP->framePix = (PixMapPtr)*(Handle)pixMapH;
1239 srcFrameP->framePix = (PixMapPtr)StripAddress(*(Handle)pixMapH);
1248 static void BenSWUnlockFrame(FrameRec *srcFrameP)
1250 if (srcFrameP->framePort != NULL)
1252 HUnlock((Handle)srcFrameP->framePixHndl);
1253 UnlockPixels(srcFrameP->framePixHndl);
1256 srcFrameP->framePix = NULL;
1260 static OSErr BenSWCreateGWorldFromPict(
1261 GWorldPtr *pictGWorld,
1265 GWorldPtr saveGWorld;
1266 GDHandle saveGDevice;
1267 GWorldPtr tempGWorld;
1276 depth = data[0].pixelDepth;
1279 theGDH = data[0].theGDH;
1281 /* Obtain size rectangle */
1282 pictRect = (**pictH).picFrame;
1283 OffsetRect(&pictRect, -pictRect.left, -pictRect.top);
1285 /* Create a GWorld */
1286 err = NewGWorld(&tempGWorld, depth, &pictRect, nil,
1287 theGDH, noNewDevice);
1296 *pictGWorld = tempGWorld;
1299 GetGWorld(&saveGWorld, &saveGDevice);
1302 SetGWorld(tempGWorld, nil);
1304 /* Dump the pict into the GWorld */
1305 (void)LockPixels(GetGWorldPixMap(tempGWorld));
1306 EraseRect(&pictRect);
1307 DrawPicture(pictH, &pictRect);
1308 UnlockPixels(GetGWorldPixMap(tempGWorld));
1310 /* Restore GWorld */
1311 SetGWorld(saveGWorld, saveGDevice);
1321 * Init the global "frameP"
1324 static errr globe_init(void)
1328 GWorldPtr tempPictGWorldP;
1332 /* Use window XXX XXX XXX */
1333 #if TARGET_API_MAC_CARBON
1334 SetPortWindowPort(data[0].w);
1340 /* Get the pict resource */
1341 newPictH = GetPicture(pictID);
1343 /* Analyze result */
1344 err = (newPictH ? 0 : -1);
1351 err = BenSWCreateGWorldFromPict(&tempPictGWorldP, newPictH);
1353 /* Release resource */
1354 ReleaseResource((Handle)newPictH);
1359 /* Create the frame */
1360 frameP = (FrameRec*)NewPtrClear((Size)sizeof(FrameRec));
1362 /* Analyze result */
1363 err = (frameP ? 0 : -1);
1369 frameP->framePort = tempPictGWorldP;
1372 BenSWLockFrame(frameP);
1383 * Nuke the global "frameP"
1385 static errr globe_nuke(void)
1391 BenSWUnlockFrame(frameP);
1393 /* Dispose of the GWorld */
1394 DisposeGWorld(frameP->framePort);
1396 /* Dispose of the memory */
1397 DisposePtr((Ptr)frameP);
1404 FlushEvents(everyEvent, 0);
1411 #endif /* ANGBAND_LITE_MAC */
1415 /*** Support for the "z-term.c" package ***/
1419 * Initialize a new Term
1421 * Note also the "window type" called "noGrowDocProc", which might be more
1422 * appropriate for the main "screen" window.
1424 * Note the use of "srcCopy" mode for optimized screen writes.
1426 static void Term_init_mac(term *t)
1428 term_data *td = (term_data*)(t->data);
1430 static RGBColor black = {0x0000,0x0000,0x0000};
1431 static RGBColor white = {0xFFFF,0xFFFF,0xFFFF};
1433 #ifdef ANGBAND_LITE_MAC
1435 /* Make the window */
1436 td->w = NewWindow(0, &td->r, td->title, 0, noGrowDocProc, (WindowPtr)-1, 1, 0L);
1438 #else /* ANGBAND_LITE_MAC */
1440 /* Make the window */
1441 td->w = NewCWindow(0, &td->r, td->title, 0, documentProc, (WindowPtr)-1, 1, 0L);
1443 #endif /* ANGBAND_LITE_MAC */
1445 /* Activate the window */
1448 /* Erase behind words */
1451 /* Apply and Verify */
1452 term_data_check_font(td);
1453 term_data_check_size(td);
1455 /* Resize the window */
1456 term_data_resize(td);
1458 #ifdef ANGBAND_LITE_MAC
1460 /* Prepare the colors (base colors) */
1461 BackColor(blackColor);
1462 ForeColor(whiteColor);
1464 #else /* ANGBAND_LITE_MAC */
1466 /* Prepare the colors (real colors) */
1467 RGBBackColor(&black);
1468 RGBForeColor(&white);
1475 GDHandle currentGDH;
1476 GWorldPtr windowGWorld;
1477 PixMapHandle basePixMap;
1479 /* Obtain the rect */
1480 #if TARGET_API_MAC_CARBON
1481 GetWindowBounds( (WindowRef)td->w, kWindowContentRgn, &globalRect );
1483 globalRect = td->w->portRect;
1484 LocalToGlobal((Point*)&globalRect.top);
1485 LocalToGlobal((Point*)&globalRect.bottom);
1488 /* Obtain the proper GDH */
1489 mainGDH = GetMaxDevice(&globalRect);
1491 /* Extract GWorld and GDH */
1492 GetGWorld(&windowGWorld, ¤tGDH);
1494 /* Obtain base pixmap */
1495 basePixMap = (**mainGDH).gdPMap;
1497 /* Save pixel depth */
1498 td->pixelDepth = (**basePixMap).pixelSize;
1500 /* Save Window GWorld */
1501 td->theGWorld = windowGWorld;
1503 /* Save Window GDH */
1504 td->theGDH = currentGDH;
1507 td->mainSWGDH = mainGDH;
1510 #endif /* ANGBAND_LITE_MAC */
1515 #if TARGET_API_MAC_CARBON
1516 GetWindowBounds( (WindowRef)td->w, kWindowContentRgn, &portRect );
1517 global_to_local( &portRect );
1519 portRect = td->w->portRect;
1521 /* Clip to the window */
1522 ClipRect(&portRect);
1524 /* Erase the window */
1525 EraseRect(&portRect);
1527 /* Invalidate the window */
1528 #if TARGET_API_MAC_CARBON
1529 InvalWindowRect((WindowRef)(td->w), (const Rect *)(&portRect));
1531 InvalRect(&portRect);
1534 /* Display the window if needed */
1535 if (td->mapped) ShowWindow(td->w);
1537 /* Hack -- set "mapped" flag */
1538 t->mapped_flag = td->mapped;
1544 /* if (err == noErr)
1555 static void Term_nuke_mac(term *t)
1568 static errr Term_user_mac(int n)
1582 static errr Term_xtra_mac_react(void)
1584 term_data *td = (term_data*)(Term->data);
1590 #ifdef ANGBAND_LITE_MAC
1594 #else /* ANGBAND_LITE_MAC */
1597 if (use_sound != arg_sound)
1600 use_sound = arg_sound;
1604 /* Handle transparency */
1605 if (use_newstyle_graphics != arg_newstyle_graphics)
1609 if (globe_init() != 0)
1611 plog("Cannot initialize graphics!");
1612 arg_graphics = FALSE;
1613 arg_newstyle_graphics = FALSE;
1617 use_newstyle_graphics = arg_newstyle_graphics;
1619 /* Apply and Verify */
1620 term_data_check_size(td);
1622 /* Resize the window */
1623 term_data_resize(td);
1629 /* Handle graphics */
1630 if (use_graphics != arg_graphics)
1632 /* Initialize graphics */
1634 if (!use_graphics && !frameP && (globe_init() != 0))
1637 plog("¥°¥é¥Õ¥£¥Ã¥¯¤Î½é´ü²½¤Ï½ÐÍè¤Þ¤»¤ó¤Ç¤·¤¿.");
1639 plog("Cannot initialize graphics!");
1641 arg_graphics = FALSE;
1645 use_graphics = arg_graphics;
1647 /* Apply and Verify */
1648 term_data_check_size(td);
1650 /* Resize the window */
1651 term_data_resize(td);
1657 #endif /* ANGBAND_LITE_MAC */
1665 * Do a "special thing"
1667 static errr Term_xtra_mac(int n, int v)
1669 term_data *td = (term_data*)(Term->data);
1677 case TERM_XTRA_NOISE:
1686 #ifdef ANGBAND_LITE_MAC
1690 #else /* ANGBAND_LITE_MAC */
1693 case TERM_XTRA_SOUND:
1703 /* Open the resource file */
1704 oldResFile = CurResFile();
1705 newResFile = OpenResFile(sound);
1707 /* Close the resource file */
1708 CloseResFile(newResFile);
1709 UseResFile(oldResFile);
1712 /* Get the proper sound name */
1713 sprintf((char*)sound + 1, "%.16s.wav", angband_sound_name[v]);
1714 sound[0] = strlen((char*)sound + 1);
1716 /* Obtain resource XXX XXX XXX */
1717 handle = Get1NamedResource('snd ', sound);
1718 if( handle == NULL || ext_sound )
1719 handle = GetNamedResource('snd ', sound);
1722 if (handle && soundmode[soundchoice[v]] == true)
1725 LoadResource(handle);
1728 /* Play sound (wait for completion) */
1729 SndPlay(nil, (SndListHandle)handle, true);
1731 /* Unlock and release */
1733 ReleaseResource(handle);
1739 #endif /* ANGBAND_LITE_MAC */
1741 /* Process random events */
1742 case TERM_XTRA_BORED:
1744 /* Process an event */
1745 (void)CheckEvents(FALSE);
1751 /* Process pending events */
1752 case TERM_XTRA_EVENT:
1754 /* Process an event */
1755 (void)CheckEvents(v);
1761 /* Flush all pending events (if any) */
1762 case TERM_XTRA_FLUSH:
1764 /* Hack -- flush all events */
1765 while (CheckEvents(TRUE)) /* loop */;
1771 /* Hack -- Change the "soft level" */
1772 case TERM_XTRA_LEVEL:
1774 /* Activate if requested */
1775 if (v) activate(td->w);
1781 /* Clear the screen */
1782 case TERM_XTRA_CLEAR:
1786 #if TARGET_API_MAC_CARBON
1787 GetWindowBounds( (WindowRef)td->w, kWindowContentRgn, &portRect );
1788 global_to_local( &portRect );
1790 portRect = td->w->portRect;
1793 /* No clipping XXX XXX XXX */
1794 ClipRect(&portRect);
1796 /* Erase the window */
1797 EraseRect(&portRect);
1800 term_data_color(td, TERM_WHITE);
1802 /* Frame the window in white */
1804 LineTo(0, td->size_hgt-1);
1805 LineTo(td->size_wid-1, td->size_hgt-1);
1806 LineTo(td->size_wid-1, 0);
1808 /* Clip to the new size */
1809 r.left = portRect.left + td->size_ow1;
1810 r.top = portRect.top + td->size_oh1;
1811 r.right = portRect.right - td->size_ow2;
1812 r.bottom = portRect.bottom - td->size_oh2;
1819 /* React to changes */
1820 case TERM_XTRA_REACT:
1822 /* React to changes */
1823 return (Term_xtra_mac_react());
1826 /* Delay (milliseconds) */
1827 case TERM_XTRA_DELAY:
1832 #if TARGET_API_MAC_CARBON
1836 /* Convert millisecs to ticks */
1837 ticks = (v * 60L) / 1000;
1840 * Hack? - Put the programme into sleep.
1841 * No events match ~everyEvent, so nothing
1842 * should be lost in Angband's event queue.
1843 * Even if ticks are 0, it's worth calling for
1844 * the above mentioned reasons.
1846 WaitNextEvent(~everyEvent, &tmp, ticks, nil);
1848 long m = TickCount() + (v * 60L) / 1000;
1851 while (TickCount() < m) /* loop */;
1867 * Low level graphics (Assumes valid input).
1868 * Draw a "cursor" at (x,y), using a "yellow box".
1869 * We are allowed to use "Term_grab()" to determine
1870 * the current screen contents (for inverting, etc).
1872 static errr Term_curs_mac(int x, int y)
1876 term_data *td = (term_data*)(Term->data);
1879 term_data_color(td, TERM_YELLOW);
1881 /* Frame the grid */
1882 r.left = x * td->tile_wid + td->size_ow1;
1883 r.right = r.left + td->tile_wid;
1884 r.top = y * td->tile_hgt + td->size_oh1;
1885 r.bottom = r.top + td->tile_hgt;
1888 if (x + 1 < Term->wid &&
1889 ((use_bigtile && Term->old->a[y][x+1] == 255)
1890 || (iskanji(Term->old->c[y][x]) && !(Term->old->a[y][x] & 0x80))))
1892 if (use_bigtile && x + 1 < Term->wid && Term->old->a[y][x+1] == 255)
1894 r.right += td->tile_wid;
1904 * Low level graphics (Assumes valid input)
1906 * Erase "n" characters starting at (x,y)
1908 static errr Term_wipe_mac(int x, int y, int n)
1912 term_data *td = (term_data*)(Term->data);
1914 /* Erase the block of characters */
1915 r.left = x * td->tile_wid + td->size_ow1;
1916 r.right = r.left + n * td->tile_wid;
1917 r.top = y * td->tile_hgt + td->size_oh1;
1918 r.bottom = r.top + td->tile_hgt;
1927 * Low level graphics. Assumes valid input.
1929 * Draw several ("n") chars, with an attr, at a given location.
1931 static errr Term_text_mac(int x, int y, int n, byte a, const char *cp)
1935 term_data *td = (term_data*)(Term->data);
1938 term_data_color(td, (a & 0x0F));
1940 /* Starting pixel */
1941 xp = x * td->tile_wid + td->tile_o_x + td->size_ow1;
1942 yp = y * td->tile_hgt + td->tile_o_y + td->size_oh1;
1944 /* Move to the correct location */
1947 /* Draw the character */
1948 if (n == 1) DrawChar(*cp);
1950 /* Draw the string */
1951 else DrawText(cp, 0, n);
1959 * Low level graphics (Assumes valid input)
1961 * Erase "n" characters starting at (x,y)
1963 #ifdef USE_TRANSPARENCY
1964 static errr Term_pict_mac(int x, int y, int n, const byte *ap, const char *cp,
1965 const byte *tap, const char *tcp)
1967 static errr Term_pict_mac(int x, int y, int n, const byte *ap, const char *cp)
1972 term_data *td = (term_data*)(Term->data);
1973 GDHandle saveGDevice;
1974 GWorldPtr saveGWorld;
1976 PixMapHandle PortPix;
1979 GetGWorld(&saveGWorld, &saveGDevice);
1981 r2.left = x * td->tile_wid + td->size_ow1;
1982 r2.right = r2.left + td->tile_wid;
1983 r2.top = y * td->tile_hgt + td->size_oh1;
1984 r2.bottom = r2.top + td->tile_hgt;
1988 /* Instantiate font */
1989 TextFont(td->font_id);
1990 TextSize(td->font_size);
1991 TextFace(td->font_face);
1993 /* Restore colors */
1994 BackColor(blackColor);
1995 ForeColor(whiteColor);
1999 /* Destination rectangle */
2000 /* r2.left = x * td->tile_wid + td->size_ow1;
2001 r2.top = y * td->tile_hgt + td->size_oh1;
2002 r2.bottom = r2.top + td->tile_hgt;*/
2006 /* Scan the input */
2007 for (i = 0; i < n; i++)
2014 /* Second byte of bigtile */
2015 if (use_bigtile && a == 255)
2018 r2.left += td->tile_wid;
2023 /* Prepare right of rectangle now */
2024 r2.right = r2.left + td->tile_wid;
2026 #ifdef ANGBAND_LITE_MAC
2030 #else /* ANGBAND_LITE_MAC */
2032 /* Graphics -- if Available and Needed */
2033 if (use_graphics && ((byte)a & 0x80) && ((byte)c & 0x80))
2035 #if TARGET_API_MAC_CARBON
2036 PixMapHandle srcBitMap = GetGWorldPixMap(frameP->framePort);
2037 PixMapHandle destBitMap;
2039 BitMapPtr srcBitMap = (BitMapPtr)(frameP->framePix);
2040 BitMapPtr destBitMap;
2046 #ifdef USE_TRANSPARENCY
2048 bool terrain_flag = FALSE;
2052 if ((a != ta || c != tc) &&
2053 ((byte)ta & 0x80) && ((byte)tc & 0x80))
2056 row = ((byte)ta & 0x7F);
2057 col = ((byte)tc & 0x7F);
2059 /* Terrain Source rectangle */
2060 terrain_r.left = col * grafWidth;
2061 terrain_r.top = row * grafHeight;
2062 terrain_r.right = terrain_r.left + grafWidth;
2063 terrain_r.bottom = terrain_r.top + grafHeight;
2065 terrain_flag = TRUE;
2070 row = ((byte)a & 0x7F);
2071 col = ((byte)c & 0x7F);
2073 /* Source rectangle */
2074 r1.left = col * grafWidth;
2075 r1.top = row * grafHeight;
2076 r1.right = r1.left + grafWidth;
2077 r1.bottom = r1.top + grafHeight;
2079 /* Hardwire CopyBits */
2080 BackColor(whiteColor);
2081 ForeColor(blackColor);
2083 /* Draw the picture */
2084 #if TARGET_API_MAC_CARBON
2085 destBitMap = GetPortPixMap(GetWindowPort( td->w ));
2087 destBitMap = (BitMapPtr)&(td->w->portBits);
2089 if (use_bigtile) r2.right += td->tile_wid;
2091 #ifdef USE_TRANSPARENCY
2095 * Source mode const = srcCopy:
2097 * determine how close the color of the source
2098 * pixel is to black, and assign this relative
2099 * amount of foreground color to the
2100 * destination pixel; determine how close the
2101 * color of the source pixel is to white, and
2102 * assign this relative amount of background
2103 * color to the destination pixel
2105 #if TARGET_API_MAC_CARBON
2106 CopyBits( (BitMap *) *srcBitMap, (BitMap *) *destBitMap, &terrain_r, &r2, srcCopy, NULL);
2108 CopyBits( srcBitMap, destBitMap, &terrain_r, &r2, srcCopy, NULL );
2111 * Draw transparent tile
2112 * BackColor is ignored and the destination is
2115 BackColor(blackColor);
2116 #if TARGET_API_MAC_CARBON
2117 CopyBits( (BitMap *) *srcBitMap, (BitMap *) *destBitMap, &r1, &r2, transparent, NULL);
2119 CopyBits( srcBitMap, destBitMap, &r1, &r2, transparent, NULL );
2123 #endif /* USE_TRANSPARENCY */
2125 #if TARGET_API_MAC_CARBON
2126 CopyBits( (BitMap *) *srcBitMap, (BitMap *) *destBitMap, &r1, &r2, srcCopy, NULL);
2128 CopyBits( srcBitMap, destBitMap, &r1, &r2, srcCopy, NULL );
2132 /* Restore colors */
2133 BackColor(blackColor);
2134 ForeColor(whiteColor);
2143 #endif /* ANGBAND_LITE_MAC */
2151 term_data_color(td, (a & 0x0F));
2153 /* Starting pixel */
2154 xp = r2.left + td->tile_o_x;
2155 yp = r2.top + td->tile_o_y;
2157 /* Move to the correct location */
2163 /* Double width rectangle */
2164 r2.right += td->tile_wid;
2169 /* Draw the character */
2174 r2.left += td->tile_wid;
2182 /* Draw the character */
2188 r2.left += td->tile_wid;
2197 * Create and initialize window number "i"
2199 static void term_data_link(int i)
2203 term_data *td = &data[i];
2208 /* Require mapped */
2209 if (!td->mapped) return;
2214 /* Initialize the term */
2215 term_init(td->t, td->cols, td->rows, td->keys);
2217 /* Use a "software" cursor */
2218 td->t->soft_cursor = TRUE;
2220 /* Erase with "white space" */
2221 td->t->attr_blank = TERM_WHITE;
2222 td->t->char_blank = ' ';
2224 /* Prepare the init/nuke hooks */
2225 td->t->init_hook = Term_init_mac;
2226 td->t->nuke_hook = Term_nuke_mac;
2228 /* Prepare the function hooks */
2229 td->t->user_hook = Term_user_mac;
2230 td->t->xtra_hook = Term_xtra_mac;
2231 td->t->wipe_hook = Term_wipe_mac;
2232 td->t->curs_hook = Term_curs_mac;
2233 td->t->text_hook = Term_text_mac;
2234 td->t->pict_hook = Term_pict_mac;
2236 /* Link the local structure */
2237 td->t->data = (vptr)(td);
2240 Term_activate(td->t);
2242 /* Global pointer */
2243 angband_term[i] = td->t;
2253 * Set the "current working directory" (also known as the "default"
2254 * volume/directory) to the location of the current application.
2256 * Code by: Maarten Hazewinkel (mmhazewi@cs.ruu.nl)
2258 * This function does not appear to work correctly with System 6.
2260 static void SetupAppDir(void)
2264 char errString[100];
2266 /* Get the location of the Angband executable */
2267 fcbBlock.ioCompletion = NULL;
2268 fcbBlock.ioNamePtr = NULL;
2269 fcbBlock.ioVRefNum = 0;
2270 fcbBlock.ioRefNum = CurResFile();
2271 fcbBlock.ioFCBIndx = 0;
2272 err = PBGetFCBInfo(&fcbBlock, FALSE);
2276 sprintf(errString, "PBGetFCBInfo ¥¨¥é¡¼ #%d.\r ½ªÎ»¤·¤Þ¤¹.", err);
2278 sprintf(errString, "Fatal PBGetFCBInfo Error #%d.\r Exiting.", err);
2280 mac_warning(errString);
2284 /* Extract the Vol and Dir */
2285 app_vol = fcbBlock.ioFCBVRefNum;
2286 app_dir = fcbBlock.ioFCBParID;
2288 /* Set the current working directory to that location */
2289 err = HSetVol(NULL, app_vol, app_dir);
2293 sprintf(errString, "HSetVol ¥¨¥é¡¼ #%d.\r ½ªÎ»¤·¤Þ¤¹.", err);
2295 sprintf(errString, "Fatal HSetVol Error #%d.\r Exiting.", err);
2297 mac_warning(errString);
2306 * Global "preference" file pointer
2311 * Read a "short" from the file
2313 static int getshort(void)
2317 if (0 == my_fgets(fff, buf, sizeof(buf))) x = atoi(buf);
2322 * Dump a "short" to the file
2324 static void putshort(int x)
2326 fprintf(fff, "%d\n", x);
2332 * Write the "preference" data to the current "file"
2334 static void save_prefs(void)
2341 /*** The current version ***/
2343 putshort(FAKE_VERSION);
2344 putshort(FAKE_VER_MAJOR);
2345 putshort(FAKE_VER_MINOR);
2346 putshort(FAKE_VER_PATCH);
2348 putshort(arg_sound);
2349 putshort(arg_graphics);
2350 putshort(arg_newstyle_graphics);
2351 putshort(arg_bigtile);
2354 for( i = 0 ; i < 7 ; i++ )
2355 putshort(soundmode[i]);
2358 for (i = 0; i < MAX_TERM_DATA; i++)
2363 putshort(td->mapped);
2365 putshort(td->font_id);
2366 putshort(td->font_size);
2367 putshort(td->font_face);
2369 putshort(td->tile_wid);
2370 putshort(td->tile_hgt);
2375 putshort(td->r.left);
2376 putshort(td->r.top);
2382 * Load the preferences from the current "file"
2384 * XXX XXX XXX Being able to undefine various windows is
2385 * slightly bizarre, and may cause problems.
2387 static void load_prefs(void)
2391 int old_version, old_major, old_minor, old_patch;
2396 /*** Version information ***/
2398 /* Preferences version */
2399 old_version = getshort();
2400 old_major = getshort();
2401 old_minor = getshort();
2402 old_patch = getshort();
2404 /* Hack -- Verify or ignore */
2405 if ((old_version != FAKE_VERSION) ||
2406 (old_major != FAKE_VER_MAJOR) ||
2407 (old_minor != FAKE_VER_MINOR) ||
2408 (old_patch != FAKE_VER_PATCH))
2412 mac_warning("¸Å¤¤½é´üÀßÄê¥Õ¥¡¥¤¥ë¤ò̵»ë¤·¤Þ¤¹.");
2414 mac_warning("Ignoring old preferences.");
2420 arg_sound = getshort();
2421 arg_graphics = getshort();
2422 arg_newstyle_graphics = getshort();
2423 use_newstyle_graphics = arg_newstyle_graphics;
2425 if (use_newstyle_graphics == true)
2427 ANGBAND_GRAF = "new";
2428 arg_newstyle_graphics = true;
2429 grafWidth = grafHeight = 16;
2434 ANGBAND_GRAF = "old";
2435 arg_newstyle_graphics = false;
2436 grafWidth = grafHeight = 8;
2440 arg_bigtile = getshort();
2441 use_bigtile = arg_bigtile;
2444 for( i = 0 ; i < 7 ; i++ )
2445 soundmode[i] = getshort();
2448 m = GetMenuHandle(134);
2450 #if TARGET_API_MAC_CARBON
2451 /* Item "arg_sound" */
2452 CheckMenuItem(m, 1, arg_sound);
2454 /* Item "arg_graphics" */
2455 CheckMenuItem(m, 2, arg_graphics);
2457 /* Item "arg_newstyle_graphics"*/
2458 CheckMenuItem(m, 8, arg_newstyle_graphics);
2460 /* Item "arg_sound" */
2461 CheckItem(m, 1, arg_sound);
2463 /* Item "arg_graphics" */
2464 CheckItem(m, 2, arg_graphics);
2466 /* Item "arg_newstyle_graphics"*/
2467 CheckItem(m, 8, arg_newstyle_graphics);
2471 for (i = 0; i < MAX_TERM_DATA; i++)
2476 td->mapped = getshort();
2478 td->font_id = getshort();
2479 td->font_size = getshort();
2480 td->font_face = getshort();
2482 td->tile_wid = getshort();
2483 td->tile_hgt = getshort();
2485 td->cols = getshort();
2486 td->rows = getshort();
2488 td->r.left = getshort();
2489 td->r.top = getshort();
2492 if (feof(fff)) break;
2500 * Hack -- default data for a window
2502 static void term_data_hack(term_data *td)
2507 #if TARGET_API_MAC_CARBON
2508 /* Default to Osaka font (Japanese) */
2509 fid = FMGetFontFamilyFromName( "\pOsaka¡ÝÅùÉý" );
2511 GetFNum( "\pÅùÉýÌÀÄ«", &fid);
2512 SetFScaleDisable( true );
2515 /* Default to Monaco font */
2516 GetFNum("\pmonaco", &fid);
2520 WIPE(td, term_data);
2525 /* Default borders */
2536 /* Default font size */
2539 /* Default font face */
2546 /* Default position */
2556 * Read the preference file, Create the windows.
2558 * We attempt to use "FindFolder()" to track down the preference file,
2559 * but if this fails, for any reason, we will try the "SysEnvirons()"
2560 * method, which may work better with System 6.
2562 static void init_windows(void)
2575 /*** Default values ***/
2577 /* Initialize (backwards) */
2578 for (i = MAX_TERM_DATA - 1; i >= 0; i--)
2591 s = angband_term_name[i];
2596 /* Maximal length */
2599 /* Copy the title */
2600 strncpy((char*)(td->title) + 1, s, n);
2602 /* Save the length */
2605 /* Tile the windows */
2606 td->r.left += (b * 30);
2607 td->r.top += (b * 30);
2614 /*** Load preferences ***/
2616 /* Assume failure */
2619 /* Assume failure */
2632 /* Find the folder */
2633 err = FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder,
2639 /* Extract a path name */
2640 PathNameFromDirID(dirID, vref, (StringPtr)foo);
2642 /* Convert the string */
2643 ptocstr((StringPtr)foo);
2645 /* Append the preference file name */
2646 strcat(foo, PREF_FILE_NAME);
2648 /* Open the preference file */
2649 fff = fopen(foo, "r");
2656 #endif /* USE_SFL_CODE */
2658 #if TARGET_API_MAC_CARBON
2664 HGetVol(0, &savev, &saved);
2666 /* Go to the "system" folder */
2667 SysEnvirons(curSysEnvVers, &env);
2668 SetVol(0, env.sysVRefNum);
2671 fff = fopen(PREF_FILE_NAME, "r");
2674 HSetVol(0, savev, saved);
2678 /* Load preferences */
2681 /* Load a real preference file */
2684 /* Close the file */
2689 /*** Instantiate ***/
2700 /* Link (backwards, for stacking order) */
2701 for (i = MAX_TERM_DATA - 1; i >= 0; i--)
2710 Term_activate(td->t);
2713 static void init_sound( void )
2717 SignedByte permission = fsRdPerm;
2723 /* Descend into "lib" folder */
2724 pb.ioCompletion = NULL;
2725 pb.ioNamePtr = "\plib";
2726 pb.ioVRefNum = app_vol;
2727 pb.ioDrDirID = app_dir;
2730 /* Check for errors */
2731 err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
2734 if ((err == noErr) && (pb.ioFlAttrib & 0x10))
2736 /* Descend into "lib/save" folder */
2737 pb.ioCompletion = NULL;
2738 pb.ioNamePtr = "\pxtra";
2739 pb.ioVRefNum = app_vol;
2740 pb.ioDrDirID = pb.ioDrDirID;
2743 /* Check for errors */
2744 err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
2747 if ((err == noErr) && (pb.ioFlAttrib & 0x10))
2749 /* Descend into "lib/save" folder */
2750 pb.ioCompletion = NULL;
2751 pb.ioNamePtr = "\psound";
2752 pb.ioVRefNum = app_vol;
2753 pb.ioDrDirID = pb.ioDrDirID;
2756 /* Check for errors */
2757 err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
2760 if ((err == noErr) && (pb.ioFlAttrib & 0x10))
2762 ret = HOpenResFile( app_vol , pb.ioDrDirID , "\psound.rsrc" , permission );
2766 for( i = 0 ; i < 7 ; i++ )
2767 soundmode[i] = false;
2769 for( i = 1 ; i < SOUND_MAX ; i++ ){
2770 /* Get the proper sound name */
2771 sprintf((char*)sound + 1, "%.16s.wav", angband_sound_name[i]);
2772 sound[0] = strlen((char*)sound + 1);
2774 /* Obtain resource XXX XXX XXX */
2775 handle = Get1NamedResource('snd ', sound);
2776 if( handle == NULL || ext_sound )
2777 handle = GetNamedResource('snd ', sound);
2780 soundmode[soundchoice[i]] = true;
2789 static void init_graf( void )
2793 SignedByte permission = fsRdPerm;
2799 /* Descend into "lib" folder */
2800 pb.ioCompletion = NULL;
2801 pb.ioNamePtr = "\plib";
2802 pb.ioVRefNum = app_vol;
2803 pb.ioDrDirID = app_dir;
2806 /* Check for errors */
2807 err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
2810 if ((err == noErr) && (pb.ioFlAttrib & 0x10))
2812 /* Descend into "lib/xtra" folder */
2813 pb.ioCompletion = NULL;
2814 pb.ioNamePtr = "\pxtra";
2815 pb.ioVRefNum = app_vol;
2816 pb.ioDrDirID = pb.ioDrDirID;
2819 /* Check for errors */
2820 err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
2823 if ((err == noErr) && (pb.ioFlAttrib & 0x10))
2825 /* Descend into "lib/xtra/graf" folder */
2826 pb.ioCompletion = NULL;
2827 pb.ioNamePtr = "\pgraf";
2828 pb.ioVRefNum = app_vol;
2829 pb.ioDrDirID = pb.ioDrDirID;
2832 /* Check for errors */
2833 err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
2836 if ((err == noErr) && (pb.ioFlAttrib & 0x10))
2838 ret = HOpenResFile( app_vol , pb.ioDrDirID , "\pgraf.rsrc" , permission );
2843 /* Obtain resource XXX XXX XXX */
2844 handle = Get1NamedResource('PICT', graf);
2845 if ( handle == NULL || ext_graf )
2846 handle = GetNamedResource('PICT', "\pgraf.rsrc");
2857 static void init_chuukei( void )
2863 path_build(path, sizeof(path), ANGBAND_DIR_XTRA, "chuukei.txt");
2865 fp = fopen(path, "r");
2870 if (fgets(tmp, 1024, fp)){
2872 int n = strlen(tmp);
2878 chuukei_server = TRUE;
2879 if(connect_chuukei_server(&tmp[2])<0){
2880 msg_print("connect fail");
2883 msg_print("connect");
2890 chuukei_client = TRUE;
2891 connect_chuukei_server(&tmp[2]);
2907 short InevrtCheck( DialogPtr targetDlg, short check )
2914 GetDialogItem( targetDlg, check, &itemType, &checkH, &box );
2915 result = (GetControlValue( (ControlHandle)checkH ) + 1 ) % 2;
2916 SetControlValue( (ControlHandle)checkH , result );
2924 short SetCheck( DialogPtr targetDlg, short check, long result )
2931 GetDialogItem( targetDlg, check, &itemType, &checkH, &box );
2932 SetControlValue( (ControlHandle)checkH , result );
2940 short GetCheck( DialogPtr targetDlg, short check )
2947 GetDialogItem( targetDlg, check, &itemType, &checkH, &box );
2948 result = GetControlValue( (ControlHandle)checkH );
2952 void SoundConfigDLog(void)
2959 dialog=GetNewDialog(131, 0, (WindowPtr)-1);
2960 SetDialogDefaultItem( dialog, ok );
2961 SetDialogCancelItem( dialog, cancel );
2962 for( i = 1 ; i < 7 ; i++ )
2963 SetCheck( dialog, i+2 , soundmode[i] );
2966 for( item_hit = 100 ; cancel < item_hit ; ){
2967 ModalDialog(0, &item_hit);
2971 for( i = 1 ; i < 7 ; i++ )
2972 soundmode[i] = GetCheck( dialog, i+2 );
2977 InevrtCheck( dialog, item_hit );
2980 DisposeDialog(dialog);
2988 static void save_pref_file(void)
2997 /* Assume failure */
3000 /* Assume failure */
3017 /* Find the folder */
3018 err = FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder,
3024 /* Extract a path name */
3025 PathNameFromDirID(dirID, vref, (StringPtr)foo);
3027 /* Convert the string */
3028 ptocstr((StringPtr)foo);
3030 /* Append the preference file name */
3031 strcat(foo, PREF_FILE_NAME);
3033 /* Open the preference file */
3034 /* my_fopen set file type and file creator for MPW */
3035 fff = my_fopen(foo, "w");
3042 #endif /* USE_SFL_CODE */
3044 #if TARGET_API_MAC_CARBON
3050 HGetVol(0, &savev, &saved);
3052 /* Go to "system" folder */
3053 SysEnvirons(curSysEnvVers, &env);
3054 SetVol(0, env.sysVRefNum);
3056 /* Open the preference file */
3057 /* my_fopen set file type and file creator for MPW */
3058 fff = fopen(PREF_FILE_NAME, "w");
3061 HSetVol(0, savev, saved);
3065 /* Save preferences */
3068 /* Write the preferences */
3079 * A simple "Yes/No" filter to parse "key press" events in dialog windows
3081 static pascal Boolean ynfilter(DialogPtr dialog, EventRecord *event, short *ip)
3083 /* Parse key press events */
3084 if (event->what == keyDown)
3089 /* Extract the pressed key */
3090 c = (event->message & charCodeMask);
3092 /* Accept "no" and <return> and <enter> */
3093 if ((c=='n') || (c=='N') || (c==13) || (c==3)) i = 1;
3096 else if ((c=='y') || (c=='Y')) i = 2;
3098 /* Handle "yes" or "no" */
3102 ControlHandle control;
3105 /* Get the button */
3106 GetDialogItem(dialog, i, &type, (Handle*)&control, &r);
3108 /* Blink button for 1/10 second */
3109 HiliteControl(control, 1);
3110 Term_xtra_mac(TERM_XTRA_DELAY, 100);
3111 HiliteControl(control, 0);
3125 * Handle menu: "File" + "New"
3127 static void do_menu_file_new(void)
3132 /* Game is in progress */
3133 game_in_progress = 1;
3147 * Handle menu: "File" + "Open"
3149 #if TARGET_API_MAC_CARBON
3150 static void do_menu_file_open(bool all)
3164 refnum_to_name(path, app_dir, app_vol, (char*)("\plib:save:"));
3166 FSpLocationFromFullPath( strlen(path), path, &fsp );
3169 err = ChooseFile( savefile, fsp );
3172 if (err != noErr) return;
3174 /* Extract textual file name for save file */
3175 /* GetWDInfo(reply.vRefNum, &vrefnum, &drefnum, &junk);
3176 refnum_to_name(savefile, drefnum, vrefnum, (char*)reply.fName);
3181 /* Game is in progress */
3182 game_in_progress = 1;
3194 static void do_menu_file_open(bool all)
3208 /* vrefnum = GetSFCurVol(); */
3209 vrefnum = -*((short*)0x214);
3211 /* drefnum = GetSFCurDir(); */
3212 drefnum = *((long*)0x398);
3214 /* Descend into "lib" folder */
3215 pb.ioCompletion = NULL;
3216 pb.ioNamePtr = "\plib";
3217 pb.ioVRefNum = vrefnum;
3218 pb.ioDrDirID = drefnum;
3221 /* Check for errors */
3222 err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
3225 if ((err == noErr) && (pb.ioFlAttrib & 0x10))
3227 /* Descend into "lib/save" folder */
3228 pb.ioCompletion = NULL;
3229 pb.ioNamePtr = "\psave";
3230 pb.ioVRefNum = vrefnum;
3231 pb.ioDrDirID = pb.ioDrDirID;
3234 /* Check for errors */
3235 err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
3238 if ((err == noErr) && (pb.ioFlAttrib & 0x10))
3240 /* SetSFCurDir(pb.ioDrDirID); */
3241 *((long*)0x398) = pb.ioDrDirID;
3245 /* Window location */
3246 topleft.h = (qd.screenBits.bounds.left+qd.screenBits.bounds.right)/2-344/2;
3247 topleft.v = (2*qd.screenBits.bounds.top+qd.screenBits.bounds.bottom)/3-188/2;
3249 /* Allow "all" files */
3253 SFGetFile(topleft, "\p", NULL, -1, types, NULL, &reply);
3256 /* Allow "save" files */
3263 SFGetFile(topleft, "\p", NULL, 1, types, NULL, &reply);
3267 if (!reply.good) return;
3269 /* Extract textual file name for save file */
3270 GetWDInfo(reply.vRefNum, &vrefnum, &drefnum, &junk);
3271 refnum_to_name(savefile, drefnum, vrefnum, (char*)reply.fName);
3276 /* Game is in progress */
3277 game_in_progress = 1;
3292 * Handle the "open_when_ready" flag
3294 static void handle_open_when_ready(void)
3296 /* Check the flag XXX XXX XXX make a function for this */
3297 if (open_when_ready && initialized && !game_in_progress)
3300 open_when_ready = FALSE;
3302 /* Game is in progress */
3303 game_in_progress = 1;
3322 * Initialize the menus
3324 * Verify menus 128, 129, 130
3325 * Create menus 131, 132, 133, 134
3327 * The standard menus are:
3329 * Apple (128) = { About, -, ... }
3330 * File (129) = { New,Open,Import,Close,Save,-,Exit,Quit }
3331 * Edit (130) = { Cut, Copy, Paste, Clear } (?)
3332 * Font (131) = { Bold, Extend, -, Monaco, ..., -, ... }
3333 * Size (132) = { ... }
3334 * Window (133) = { Angband, Mirror, Recall, Choice,
3335 * Term-4, Term-5, Term-6, Term-7 }
3336 * Special (134) = { arg_sound, arg_graphics, -,
3337 * arg_fiddle, arg_wizard }
3339 static void init_menubar(void)
3351 /* Get the "apple" menu */
3354 /* Insert the menu */
3357 /* Add the DA's to the "apple" menu */
3358 #if TARGET_API_MAC_CARBON
3360 AppendResMenu (m, 'DRVR');
3363 /* Get the "File" menu */
3364 #if TARGET_API_MAC_CARBON
3366 err = Gestalt( gestaltSystemVersion, &response );
3367 if ( (err == noErr) && (response >= 0x00000A00) )
3369 DeleteMenuItem( m, 7 );
3375 /* Insert the menu */
3379 /* Get the "Edit" menu */
3382 /* Insert the menu */
3386 /* Make the "Font" menu */
3388 m = NewMenu(131, "\p¥Õ¥©¥ó¥È");
3390 m = NewMenu(131, "\pFont");
3393 /* Insert the menu */
3397 AppendMenu(m, "\pBold");
3400 AppendMenu(m, "\pWide");
3402 /* Add a separator */
3403 AppendMenu(m, "\p-");
3406 r.left = r.right = r.top = r.bottom = 0;
3408 /* Make the fake window */
3409 tmpw = NewWindow(0, &r, "\p", false, documentProc, 0, 0, 0);
3411 /* Activate the "fake" window */
3412 #if TARGET_API_MAC_CARBON
3413 SetPortWindowPort(tmpw);
3424 /* Add the fonts to the menu */
3425 AppendResMenu(m, 'FONT');
3428 #if TARGET_API_MAC_CARBON
3429 n = CountMenuItems(m);
3435 for (i = n; i >= 4; i--)
3440 /* Acquire the font name */
3441 GetMenuItemText(m, i, tmpName);
3443 /* Acquire the font index */
3444 #if TARGET_API_MAC_CARBON
3445 fontNum = FMGetFontFamilyFromName( tmpName );
3447 GetFNum(tmpName, &fontNum);
3450 /* Apply the font index */
3453 /* Remove non-mono-spaced fonts */
3454 if ((CharWidth('i') != CharWidth('W')) || (CharWidth('W') == 0))
3456 /* Delete the menu item XXX XXX XXX */
3457 DeleteMenuItem (m, i);
3461 /* Destroy the old window */
3462 DisposeWindow(tmpw);
3464 /* Add a separator */
3465 AppendMenu(m, "\p-");
3467 /* Add the fonts to the menu */
3468 AppendResMenu (m, 'FONT');
3471 /* Make the "Size" menu */
3473 m = NewMenu(132, "\p¥µ¥¤¥º");
3475 m = NewMenu(132, "\pSize");
3478 /* Insert the menu */
3481 /* Add some sizes (stagger choices) */
3482 for (i = 8; i <= 32; i += ((i / 16) + 1))
3487 sprintf((char*)buf + 1, "%d", i);
3488 buf[0] = strlen((char*)buf + 1);
3495 /* Make the "Windows" menu */
3497 m = NewMenu(133, "\p¥¦¥¤¥ó¥É¥¦");
3499 m = NewMenu(133, "\pWindows");
3502 /* Insert the menu */
3505 /* Default choices */
3506 for (i = 0; i < MAX_TERM_DATA; i++)
3510 /* Describe the item */
3511 sprintf((char*)buf + 1, "%.15s", angband_term_name[i]);
3512 buf[0] = strlen((char*)buf + 1);
3517 /* Command-Key shortcuts */
3518 if (i < 8) SetItemCmd(m, i + 1, '0' + i);
3522 /* Make the "Special" menu */
3524 m = NewMenu(134, "\pÆÃÊÌ");
3526 m = NewMenu(134, "\pSpecial");
3529 /* Insert the menu */
3532 /* Append the choices */
3534 AppendMenu(m, "\p¥µ¥¦¥ó¥É»ÈÍÑ");
3535 AppendMenu(m, "\p¥°¥é¥Õ¥£¥Ã¥¯»ÈÍÑ");
3536 AppendMenu(m, "\p-");
3537 AppendMenu(m, "\parg_fiddle");
3538 AppendMenu(m, "\parg_wizard");
3539 AppendMenu(m, "\p-");
3540 AppendMenu(m, "\p¥µ¥¦¥ó¥ÉÀßÄê...");
3541 AppendMenu(m, "\p16X16¥°¥é¥Õ¥£¥Ã¥¯");
3542 AppendMenu(m, "\p£²ÇÜÉý¥¿¥¤¥ëɽ¼¨");
3544 AppendMenu(m, "\parg_sound");
3545 AppendMenu(m, "\parg_graphics");
3546 AppendMenu(m, "\p-");
3547 AppendMenu(m, "\parg_fiddle");
3548 AppendMenu(m, "\parg_wizard");
3549 AppendMenu(m, "\p-");
3550 AppendMenu(m, "\pSound config");
3551 AppendMenu(m, "\pAdam Bolt tile");
3552 AppendMenu(m, "\pBigtile Mode");
3555 /* Make the "TileWidth" menu */
3557 m = NewMenu(135, "\p¥¿¥¤¥ëÉý");
3559 m = NewMenu(135, "\pTileWidth");
3562 /* Insert the menu */
3565 /* Add some sizes */
3566 for (i = 4; i <= 32; i++)
3571 sprintf((char*)buf + 1, "%d", i);
3572 buf[0] = strlen((char*)buf + 1);
3579 /* Make the "TileHeight" menu */
3581 m = NewMenu(136, "\p¥¿¥¤¥ë¹â");
3583 m = NewMenu(136, "\pTileHeight");
3586 /* Insert the menu */
3589 /* Add some sizes */
3590 for (i = 4; i <= 32; i++)
3595 sprintf((char*)buf + 1, "%d", i);
3596 buf[0] = strlen((char*)buf + 1);
3603 /* Update the menu bar */
3611 static void setup_menus(void)
3621 term_data *td = NULL;
3624 /* Relevant "term_data" */
3625 for (i = 0; i < MAX_TERM_DATA; i++)
3628 if (!data[i].t) continue;
3630 /* Notice the matching window */
3631 if (data[i].w == FrontWindow()) td = &data[i];
3636 m = GetMenuHandle(129);
3639 #if TARGET_API_MAC_CARBON
3640 n = CountMenuItems(m);
3646 for (i = 1; i <= n; i++)
3649 #if TARGET_API_MAC_CARBON
3650 DisableMenuItem(m, i);
3651 CheckMenuItem(m, i, FALSE);
3654 CheckItem(m, i, FALSE);
3658 /* Enable "new"/"open..."/"import..." */
3659 if (initialized && !game_in_progress)
3661 #if TARGET_API_MAC_CARBON
3662 EnableMenuItem(m, 1);
3663 EnableMenuItem(m, 2);
3664 EnableMenuItem(m, 3);
3672 /* Enable "close" */
3675 #if TARGET_API_MAC_CARBON
3676 EnableMenuItem(m, 4);
3683 if (initialized && character_generated)
3685 #if TARGET_API_MAC_CARBON
3686 EnableMenuItem(m, 5);
3695 #if TARGET_API_MAC_CARBON
3696 EnableMenuItem(m, 7);
3704 m = GetMenuHandle(130);
3707 #if TARGET_API_MAC_CARBON
3708 n = CountMenuItems(m);
3714 for (i = 1; i <= n; i++)
3717 #if TARGET_API_MAC_CARBON
3718 DisableMenuItem(m, i);
3719 CheckMenuItem(m, i, FALSE);
3722 CheckItem(m, i, FALSE);
3726 /* Enable "edit" options if "needed" */
3729 #if TARGET_API_MAC_CARBON
3730 EnableMenuItem(m, 1);
3731 EnableMenuItem(m, 3);
3732 EnableMenuItem(m, 4);
3733 EnableMenuItem(m, 5);
3734 EnableMenuItem(m, 6);
3746 m = GetMenuHandle(131);
3749 #if TARGET_API_MAC_CARBON
3750 n = CountMenuItems(m);
3756 for (i = 1; i <= n; i++)
3759 #if TARGET_API_MAC_CARBON
3760 DisableMenuItem(m, i);
3761 CheckMenuItem(m, i, FALSE);
3764 CheckItem(m, i, FALSE);
3768 /* Hack -- look cute XXX XXX */
3769 /* SetItemStyle(m, 1, bold); */
3771 /* Hack -- look cute XXX XXX */
3772 /* SetItemStyle(m, 2, extend); */
3777 #if TARGET_API_MAC_CARBON
3779 EnableMenuItem(m, 1);
3781 /* Enable "extend" */
3782 EnableMenuItem(m, 2);
3784 /* Check the appropriate "bold-ness" */
3785 if (td->font_face & bold) CheckMenuItem(m, 1, TRUE);
3787 /* Check the appropriate "wide-ness" */
3788 if (td->font_face & extend) CheckMenuItem(m, 2, TRUE);
3791 for (i = 4; i <= n; i++)
3794 EnableMenuItem(m, i);
3797 GetMenuItemText(m, i, s);
3800 /* Check active font */
3801 if (td->font_id == value) CheckMenuItem(m, i, TRUE);
3807 /* Enable "extend" */
3810 /* Check the appropriate "bold-ness" */
3811 if (td->font_face & bold) CheckItem(m, 1, TRUE);
3813 /* Check the appropriate "wide-ness" */
3814 if (td->font_face & extend) CheckItem(m, 2, TRUE);
3817 for (i = 4; i <= n; i++)
3823 GetMenuItemText(m, i, s);
3826 /* Check active font */
3827 if (td->font_id == value) CheckItem(m, i, TRUE);
3834 m = GetMenuHandle(132);
3837 #if TARGET_API_MAC_CARBON
3838 n = CountMenuItems(m);
3844 for (i = 1; i <= n; i++)
3847 #if TARGET_API_MAC_CARBON
3848 DisableMenuItem(m, i);
3849 CheckMenuItem(m, i, FALSE);
3852 CheckItem(m, i, FALSE);
3860 for (i = 1; i <= n; i++)
3862 #if TARGET_API_MAC_CARBON
3864 GetMenuItemText(m, i, s);
3866 value = atoi((char*)(s+1));
3868 /* Enable the "real" sizes */
3869 if (RealFont(td->font_id, value)) EnableMenuItem(m, i);
3871 /* Check the current size */
3872 if (td->font_size == value) CheckMenuItem(m, i, TRUE);
3875 GetMenuItemText(m, i, s);
3877 value = atoi((char*)(s+1));
3879 /* Enable the "real" sizes */
3880 if (RealFont(td->font_id, value)) EnableItem(m, i);
3882 /* Check the current size */
3883 if (td->font_size == value) CheckItem(m, i, TRUE);
3890 m = GetMenuHandle(133);
3893 #if TARGET_API_MAC_CARBON
3894 n = CountMenuItems(m);
3899 /* Check active windows */
3900 for (i = 1; i <= n; i++)
3902 /* Check if needed */
3903 #if TARGET_API_MAC_CARBON
3904 CheckMenuItem(m, i, data[i-1].mapped);
3906 CheckItem(m, i, data[i-1].mapped);
3912 m = GetMenuHandle(134);
3915 #if TARGET_API_MAC_CARBON
3916 n = CountMenuItems(m);
3922 for (i = 1; i <= n; i++)
3925 #if TARGET_API_MAC_CARBON
3926 DisableMenuItem(m, i);
3927 CheckMenuItem(m, i, FALSE);
3930 CheckItem(m, i, FALSE);
3934 #if TARGET_API_MAC_CARBON
3935 /* Item "arg_sound" */
3936 EnableMenuItem(m, 1);
3937 CheckMenuItem(m, 1, arg_sound);
3939 /* Item "arg_graphics" */
3940 EnableMenuItem(m, 2);
3941 CheckMenuItem(m, 2, arg_graphics);
3943 /* Item "arg_fiddle" */
3944 EnableMenuItem(m, 4);
3945 CheckMenuItem(m, 4, arg_fiddle);
3947 /* Item "arg_wizard" */
3948 EnableMenuItem(m, 5);
3949 CheckMenuItem(m, 5, arg_wizard);
3951 /* Item "SoundSetting" */
3952 EnableMenuItem(m, 7);
3954 /* Item NewStyle Graphics */
3955 EnableMenuItem(m, 8);
3956 CheckMenuItem(m, 8, use_newstyle_graphics);
3958 /* Item Bigtile Mode */
3959 EnableMenuItem(m, 9);
3960 CheckMenuItem(m, 9, arg_bigtile);
3962 /* Item "arg_sound" */
3964 CheckItem(m, 1, arg_sound);
3966 /* Item "arg_graphics" */
3968 CheckItem(m, 2, arg_graphics);
3970 /* Item "arg_fiddle" */
3972 CheckItem(m, 4, arg_fiddle);
3974 /* Item "arg_wizard" */
3976 CheckItem(m, 5, arg_wizard);
3978 /* Item "SoundSetting" */
3981 /* Item NewStyle Graphics */
3983 CheckItem(m, 8, use_newstyle_graphics);
3985 /* Item Bigtile Mode */
3987 CheckItem(m, 9, arg_bigtile);
3990 /* TileWidth menu */
3991 m = GetMenuHandle(135);
3994 #if TARGET_API_MAC_CARBON
3995 n = CountMenuItems(m);
4001 for (i = 1; i <= n; i++)
4004 #if TARGET_API_MAC_CARBON
4005 DisableMenuItem(m, i);
4006 CheckMenuItem(m, i, FALSE);
4009 CheckItem(m, i, FALSE);
4017 for (i = 1; i <= n; i++)
4020 /* GetMenuItemText(m,i,s); */
4021 GetMenuItemText(m, i, s);
4023 value = atoi((char*)(s+1));
4025 #if TARGET_API_MAC_CARBON
4027 EnableMenuItem(m, i);
4029 /* Check the current size */
4030 if (td->tile_wid == value) CheckMenuItem(m, i, TRUE);
4035 /* Check the current size */
4036 if (td->tile_wid == value) CheckItem(m, i, TRUE);
4042 /* TileHeight menu */
4043 m = GetMenuHandle(136);
4046 #if TARGET_API_MAC_CARBON
4047 n = CountMenuItems(m);
4053 for (i = 1; i <= n; i++)
4056 #if TARGET_API_MAC_CARBON
4057 DisableMenuItem(m, i);
4058 CheckMenuItem(m, i, FALSE);
4061 CheckItem(m, i, FALSE);
4069 for (i = 1; i <= n; i++)
4072 GetMenuItemText(m, i, s);
4074 value = atoi((char*)(s+1));
4076 #if TARGET_API_MAC_CARBON
4078 EnableMenuItem(m, i);
4080 /* Check the current size */
4081 if (td->tile_hgt == value) CheckMenuItem(m, i, TRUE);
4086 /* Check the current size */
4087 if (td->tile_hgt == value) CheckItem(m, i, TRUE);
4095 * Process a menu selection (see above)
4097 * Hack -- assume that invalid menu selections are disabled above,
4098 * which I have been informed may not be reliable. XXX XXX XXX
4100 static void menu(long mc)
4104 int menuid, selection;
4106 static unsigned char s[1000];
4110 term_data *td = NULL;
4115 /* Analyze the menu command */
4116 menuid = HiWord(mc);
4117 selection = LoWord(mc);
4120 /* Find the window */
4121 for (i = 0; i < MAX_TERM_DATA; i++)
4123 /* Skip dead windows */
4124 if (!data[i].t) continue;
4126 /* Notice matches */
4127 if (data[i].w == FrontWindow()) td = &data[i];
4131 /* Branch on the menu */
4137 /* About Angband... */
4138 #if TARGET_API_MAC_CARBON
4144 /* Get the about dialogue */
4145 dialog=GetNewDialog(128, 0, (WindowPtr)-1);
4147 /* Move it to the middle of the screen */
4149 GetDialogWindow(dialog),
4151 kWindowCenterOnMainScreen);
4153 /* Show the dialog */
4154 TransitionWindow(GetDialogWindow(dialog),
4155 kWindowZoomTransitionEffect,
4156 kWindowShowTransitionAction,
4159 /* Wait for user to click on it */
4160 ModalDialog(0, &item_hit);
4162 /* Free the dialogue */
4163 DisposeDialog(dialog);
4173 dialog=GetNewDialog(128, 0, (WindowPtr)-1);
4176 center_rect(&r, &qd.screenBits.bounds);
4177 MoveWindow(dialog, r.left, r.top, 1);
4179 ModalDialog(0, &item_hit);
4180 DisposeDialog(dialog);
4184 /* Desk accessory */
4185 /* GetMenuItemText(GetMHandle(128),selection,s); */
4186 GetMenuItemText(GetMenuHandle(128), selection, s);
4207 do_menu_file_open(FALSE);
4214 do_menu_file_open(TRUE);
4228 td->t->mapped_flag = FALSE;
4230 /* Hide the window */
4241 plog("º£¤Ï¥»¡¼¥Ö¤¹¤ë¤³¤È¤Ï½ÐÍè¤Þ¤»¤ó¡£");
4243 plog("You may not do that right now.");
4248 /* Hack -- Forget messages */
4251 /* Hack -- Save the game */
4252 do_cmd_save_game(FALSE);
4257 /* Quit (with save) */
4260 /* Save the game (if necessary) */
4261 if (game_in_progress && character_generated)
4265 plog("º£¤Ï¥»¡¼¥Ö¤¹¤ë¤³¤È¤Ï½ÐÍè¤Þ¤»¤ó¡£");
4267 plog("You may not do that right now.");
4271 /* Hack -- Forget messages */
4276 do_cmd_save_game(FALSE);
4278 Term_key_push(SPECIAL_KEY_QUIT);
4300 /* Require a window */
4309 /* Toggle the "bold" setting */
4312 /* Toggle the setting */
4313 if (td->font_face & bold)
4315 td->font_face &= ~bold;
4319 td->font_face |= bold;
4322 /* Tile Width Hight Init */
4323 td->tile_wid = td->tile_hgt = 0;
4325 /* Apply and Verify */
4326 term_data_check_font(td);
4327 term_data_check_size(td);
4329 /* Resize and Redraw */
4330 term_data_resize(td);
4331 term_data_redraw(td);
4336 /* Toggle the "wide" setting */
4339 /* Toggle the setting */
4340 if (td->font_face & extend)
4342 td->font_face &= ~extend;
4346 td->font_face |= extend;
4349 /* Tile Width Hight Init */
4350 td->tile_wid = td->tile_hgt = 0;
4352 /* Apply and Verify */
4353 term_data_check_font(td);
4354 term_data_check_size(td);
4356 /* Resize and Redraw */
4357 term_data_resize(td);
4358 term_data_redraw(td);
4363 /* Get a new font name */
4364 GetMenuItemText(GetMenuHandle(131), selection, s);
4367 /* Save the new font id */
4370 /* Current size is bad for new font */
4371 if (!RealFont(td->font_id, td->font_size))
4373 /* Find similar size */
4374 for (i = 1; i <= 32; i++)
4376 /* Adjust smaller */
4377 if (td->font_size - i >= 8)
4379 if (RealFont(td->font_id, td->font_size - i))
4387 if (td->font_size + i <= 128)
4389 if (RealFont(td->font_id, td->font_size + i))
4398 /* Tile Width Hight Init */
4399 td->tile_wid = td->tile_hgt = 0;
4401 /* Apply and Verify */
4402 term_data_check_font(td);
4403 term_data_check_size(td);
4405 /* Resize and Redraw */
4406 term_data_resize(td);
4407 term_data_redraw(td);
4409 /* Restore the window */
4426 GetMenuItemText(GetMenuHandle(132), selection, s);
4428 td->font_size = atoi((char*)(s+1));
4430 /* Tile Width Hight Init */
4431 td->tile_wid = td->tile_hgt = 0;
4433 /* Apply and Verify */
4434 term_data_check_font(td);
4435 term_data_check_size(td);
4437 /* Resize and Redraw */
4438 term_data_resize(td);
4439 term_data_redraw(td);
4453 /* Check legality of choice */
4454 if ((i < 0) || (i >= MAX_TERM_DATA)) break;
4456 /* Obtain the window */
4466 td->t->mapped_flag = TRUE;
4468 /* Show the window */
4471 /* Bring to the front */
4472 SelectWindow(td->w);
4484 /* Toggle arg_sound */
4485 arg_sound = !arg_sound;
4487 /* React to changes */
4488 Term_xtra(TERM_XTRA_REACT, 0);
4495 /* Toggle arg_graphics */
4496 arg_graphics = !arg_graphics;
4497 if( arg_graphics == true ){
4498 ANGBAND_GRAF = "old";
4499 arg_newstyle_graphics = false;
4500 grafWidth = grafHeight = 8;
4504 /* Hack -- Force redraw */
4505 Term_key_push(KTRL('R'));
4512 arg_fiddle = !arg_fiddle;
4518 arg_wizard = !arg_wizard;
4529 if (streq(ANGBAND_GRAF, "old"))
4531 ANGBAND_GRAF = "new";
4532 arg_newstyle_graphics = true;
4533 grafWidth = grafHeight = 16;
4538 ANGBAND_GRAF = "old";
4539 arg_newstyle_graphics = false;
4540 grafWidth = grafHeight = 8;
4544 /* Hack -- Force redraw */
4545 Term_key_push(KTRL('R'));
4549 case 9: /* bigtile mode */
4551 term_data *td = &data[0];
4555 plog("º£¤ÏÊѹ¹½ÐÍè¤Þ¤»¤ó¡£");
4557 plog("You may not do that right now.");
4562 /* Toggle "arg_bigtile" */
4563 arg_bigtile = !arg_bigtile;
4566 Term_activate(td->t);
4568 /* Resize the term */
4569 Term_resize(td->cols, td->rows);
4579 /* TileWidth menu */
4590 GetMenuItemText(GetMenuHandle(135), selection, s);
4592 td->tile_wid = atoi((char*)(s+1));
4594 /* Apply and Verify */
4595 term_data_check_size(td);
4597 /* Resize and Redraw */
4598 term_data_resize(td);
4599 term_data_redraw(td);
4607 /* TileHeight menu */
4618 GetMenuItemText(GetMenuHandle(136), selection, s);
4620 td->tile_hgt = atoi((char*)(s+1));
4622 /* Apply and Verify */
4623 term_data_check_size(td);
4625 /* Resize and Redraw */
4626 term_data_resize(td);
4627 term_data_redraw(td);
4637 /* Clean the menu */
4646 * Check for extra required parameters -- From "Maarten Hazewinkel"
4648 static OSErr CheckRequiredAEParams(const AppleEvent *theAppleEvent)
4651 DescType returnedType;
4654 aeError = AEGetAttributePtr(theAppleEvent, keyMissedKeywordAttr, typeWildCard,
4655 &returnedType, NULL, 0, &actualSize);
4657 if (aeError == errAEDescNotFound) return (noErr);
4659 if (aeError == noErr) return (errAEParamMissed);
4666 * Apple Event Handler -- Open Application
4668 static pascal OSErr AEH_Start(const AppleEvent *theAppleEvent,
4669 const AppleEvent *reply, long handlerRefCon)
4671 #pragma unused(reply, handlerRefCon)
4673 return (CheckRequiredAEParams(theAppleEvent));
4678 * Apple Event Handler -- Quit Application
4680 static pascal OSErr AEH_Quit(const AppleEvent *theAppleEvent,
4681 const AppleEvent *reply, long handlerRefCon)
4683 #pragma unused(reply, handlerRefCon)
4684 #if TARGET_API_MAC_CARBON
4686 /* Save the game (if necessary) */
4687 if (game_in_progress && character_generated)
4691 plog("º£¤Ï¥»¡¼¥Ö¤¹¤ë¤³¤È¤Ï½ÐÍè¤Þ¤»¤ó¡£");
4693 plog("You may not do that right now.");
4697 /* Hack -- Forget messages */
4702 do_cmd_save_game(FALSE);
4704 Term_key_push(SPECIAL_KEY_QUIT);
4712 quit_when_ready = TRUE;
4714 /* Check arguments */
4715 return (CheckRequiredAEParams(theAppleEvent));
4721 * Apple Event Handler -- Print Documents
4723 static pascal OSErr AEH_Print(const AppleEvent *theAppleEvent,
4724 const AppleEvent *reply, long handlerRefCon)
4726 #pragma unused(theAppleEvent, reply, handlerRefCon)
4728 return (errAEEventNotHandled);
4733 * Apple Event Handler by Steve Linberg (slinberg@crocker.com).
4735 * The old method of opening savefiles from the finder does not work
4736 * on the Power Macintosh, because CountAppFiles and GetAppFiles,
4737 * used to return information about the selected document files when
4738 * an application is launched, are part of the Segment Loader, which
4739 * is not present in the RISC OS due to the new memory architecture.
4741 * The "correct" way to do this is with AppleEvents. The following
4742 * code is modeled on the "Getting Files Selected from the Finder"
4743 * snippet from Think Reference 2.0. (The prior sentence could read
4744 * "shamelessly swiped & hacked")
4746 static pascal OSErr AEH_Open(AppleEvent *theAppleEvent,
4747 AppleEvent* reply, long handlerRefCon)
4749 #pragma unused(reply, handlerRefCon)
4756 DescType returnedType;
4760 /* Put the direct parameter (a descriptor list) into a docList */
4761 err = AEGetParamDesc(theAppleEvent, keyDirectObject, typeAEList, &docList);
4762 if (err) return err;
4765 * We ignore the validity check, because we trust the FInder, and we only
4766 * allow one savefile to be opened, so we ignore the depth of the list.
4769 err = AEGetNthPtr(&docList, 1L, typeFSS, &keywd,
4770 &returnedType, (Ptr) &myFSS, sizeof(myFSS), &actualSize);
4771 if (err) return err;
4773 /* Only needed to check savefile type below */
4774 err = FSpGetFInfo(&myFSS, &myFileInfo);
4777 sprintf(foo, "Arg! FSpGetFInfo failed with code %d", err);
4782 /* Ignore non 'SAVE' files */
4783 if (myFileInfo.fdType != 'SAVE') return noErr;
4785 /* XXX XXX XXX Extract a file name */
4786 PathNameFromDirID(myFSS.parID, myFSS.vRefNum, (StringPtr)savefile);
4787 pstrcat((StringPtr)savefile, (StringPtr)&myFSS.name);
4789 /* Convert the string */
4790 ptocstr((StringPtr)savefile);
4792 /* Delay actual open */
4793 open_when_ready = TRUE;
4796 err = AEDisposeDesc(&docList);
4808 * Macintosh modifiers (event.modifier & ccc):
4809 * cmdKey, optionKey, shiftKey, alphaLock, controlKey
4812 * Macintosh Keycodes (0-63 normal, 64-95 keypad, 96-127 extra):
4857 * Optimize non-blocking calls to "CheckEvents()"
4858 * Idea from "Maarten Hazewinkel <mmhazewi@cs.ruu.nl>"
4860 #define EVENT_TICKS 6
4864 * Check for Events, return TRUE if we process any
4866 * Hack -- Handle AppleEvents if appropriate (ignore result code).
4868 static bool CheckEvents(bool wait)
4884 term_data *td = NULL;
4888 static huge lastTicks = 0L;
4891 /* Access the clock */
4892 curTicks = TickCount();
4894 /* Hack -- Allow efficient checking for non-pending events */
4895 if (!wait && (curTicks < lastTicks + EVENT_TICKS)) return (FALSE);
4897 /* Timestamp last check */
4898 lastTicks = curTicks;
4900 #if TARGET_API_MAC_CARBON
4901 WaitNextEvent( everyEvent, &event, 1L, nil );
4903 /* Let the "system" run */
4906 /* Get an event (or null) */
4907 GetNextEvent(everyEvent, &event);
4910 /* Hack -- Nothing is ready yet */
4911 if (event.what == nullEvent) return (FALSE);
4913 /* Analyze the event */
4921 w = (WindowPtr)event.message;
4932 /* Extract the window */
4933 w = (WindowPtr)event.message;
4935 /* Find the window */
4936 for (i = 0; i < MAX_TERM_DATA; i++)
4938 /* Skip dead windows */
4939 if (!data[i].t) continue;
4941 /* Notice matches */
4942 if (data[i].w == w) td = &data[i];
4945 /* Hack XXX XXX XXX */
4949 /* Redraw the window */
4950 if (td) term_data_redraw(td);
4958 /* Extract some modifiers */
4959 mc = (event.modifiers & controlKey) ? TRUE : FALSE;
4960 ms = (event.modifiers & shiftKey) ? TRUE : FALSE;
4961 mo = (event.modifiers & optionKey) ? TRUE : FALSE;
4962 mx = (event.modifiers & cmdKey) ? TRUE : FALSE;
4964 /* Keypress: (only "valid" if ck < 96) */
4965 ch = (event.message & charCodeMask) & 255;
4967 /* Keycode: see table above */
4968 ck = ((event.message & keyCodeMask) >> 8) & 255;
4970 /* Command + "normal key" -> menu action */
4971 if (mx && (ck < 64))
4973 /* Hack -- Prepare the menus */
4976 /* Run the Menu-Handler */
4979 /* Turn off the menus */
4987 /* Hide the mouse pointer */
4990 /* Normal key -> simple keypress */
4993 /* Enqueue the keypress */
4997 /* Hack -- normal "keypad keys" -> special keypress */
4998 else if (!mc && !ms && !mo && !mx && (ck < 96))
5000 /* Hack -- "enter" is confused */
5001 if (ck == 76) ch = '\n';
5003 /* Send control-caret as a trigger */
5006 /* Send the "ascii" keypress */
5010 /* Bizarre key -> encoded keypress */
5013 /* Hack -- introduce with control-underscore */
5016 /* Send some modifier keys */
5017 if (mc) Term_keypress('C');
5018 if (ms) Term_keypress('S');
5019 if (mo) Term_keypress('O');
5020 if (mx) Term_keypress('X');
5022 /* Hack -- Downshift and encode the keycode */
5023 Term_keypress('0' + (ck - 64) / 10);
5024 Term_keypress('0' + (ck - 64) % 10);
5026 /* Hack -- Terminate the sequence */
5027 /* MPW can generate 10 or 13 for keycode of '\r' */
5028 /* -noMapCR option swaps '\r' and '\n' */
5029 Term_keypress('\r');
5039 /* Analyze click location */
5040 code = FindWindow(event.where, &w);
5042 /* Find the window */
5043 for (i = 0; i < MAX_TERM_DATA; i++)
5045 /* Skip dead windows */
5046 if (!data[i].t) continue;
5048 /* Notice matches */
5049 if (data[i].w == w) td = &data[i];
5058 menu(MenuSelect(event.where));
5062 #if !TARGET_API_MAC_CARBON
5065 SystemClick(&event, w);
5077 #if TARGET_API_MAC_CARBON
5078 GetQDGlobalsScreenBits( &screen );
5080 screen = qd.screenBits;
5083 r.top += 20; /* GetMBarHeight() XXX XXX XXX */
5084 InsetRect(&r, 4, 4);
5085 DragWindow(w, event.where, &r);
5097 #if TARGET_API_MAC_CARBON
5098 GetWindowBounds( (WindowRef)td->w, kWindowContentRgn, &portRect );
5100 portRect = td->w->portRect;
5101 local_to_global( &portRect );
5103 p.h = portRect.left;
5105 #if !TARGET_API_MAC_CARBON
5114 /* Apply and Verify */
5115 term_data_check_size(td);
5125 /* Track the go-away box */
5126 if (TrackGoAway(w, event.where))
5132 td->t->mapped_flag = FALSE;
5134 /* Hide the window */
5148 #if TARGET_API_MAC_CARBON
5149 GetQDGlobalsScreenBits( &screen );
5151 screen = qd.screenBits;
5156 /* Fake rectangle */
5157 r.left = 20 * td->tile_wid + td->size_ow1;
5158 r.right = screen.bounds.right;
5159 r.top = 1 * td->tile_hgt + td->size_oh1;
5160 r.bottom = screen.bounds.bottom;
5162 /* Grow the rectangle */
5163 newsize = GrowWindow(w, event.where, &r);
5166 if (!newsize) break;
5168 /* Extract the new size in pixels */
5169 y = HiWord(newsize) - td->size_oh1 - td->size_oh2;
5170 x = LoWord(newsize) - td->size_ow1 - td->size_ow2;
5172 /* Extract a "close" approximation */
5173 td->rows = y / td->tile_hgt;
5174 td->cols = x / td->tile_wid;
5176 /* Apply and Verify */
5177 term_data_check_size(td);
5179 Term_activate(td->t);
5181 /* Hack -- Resize the term */
5182 Term_resize(td->cols, td->rows);
5184 /* Resize and Redraw */
5185 term_data_resize(td);
5186 term_data_redraw(td);
5205 /* Disk Event -- From "Maarten Hazewinkel" */
5209 #if TARGET_API_MAC_CARBON
5211 /* check for error when mounting the disk */
5212 if (HiWord(event.message) != noErr)
5218 DIBadMount(p, event.message);
5225 /* OS Event -- From "Maarten Hazewinkel" */
5228 switch ((event.message >> 24) & 0x000000FF)
5230 case suspendResumeMessage:
5232 /* Resuming: activate the front window */
5233 if (event.message & resumeFlag)
5235 #if TARGET_API_MAC_CARBON
5238 SetPortWindowPort( FrontWindow() );
5240 GetQDGlobalsArrow( &arrow );
5243 SetPort(FrontWindow());
5244 SetCursor(&qd.arrow);
5248 /* Suspend: deactivate the front window */
5262 /* From "Steve Linberg" and "Maarten Hazewinkel" */
5263 case kHighLevelEvent:
5265 #if TARGET_API_MAC_CARBON
5266 AEProcessAppleEvent(&event);
5268 /* Process apple events */
5269 if (AEProcessAppleEvent(&event) != noErr)
5272 plog("Apple Event Handler¤Î¥¨¥é¡¼¤Ç¤¹.");
5274 plog("Error in Apple Event Handler!");
5278 /* Handle "quit_when_ready" */
5279 if (quit_when_ready)
5282 quit_when_ready = FALSE;
5284 /* Do the menu key */
5287 /* Turn off the menus */
5291 /* Handle "open_when_ready" */
5292 handle_open_when_ready();
5303 /* Something happened */
5310 /*** Some Hooks for various routines ***/
5314 * Mega-Hack -- emergency lifeboat
5316 static vptr lifeboat = NULL;
5320 * Hook to "release" memory
5322 static vptr hook_rnfree(vptr v, huge size)
5325 #pragma unused (size)
5329 /* Alternative method */
5344 * Hook to "allocate" memory
5346 static vptr hook_ralloc(huge size)
5351 /* Make a new pointer */
5352 return (malloc(size));
5356 /* Make a new pointer */
5357 return (NewPtr(size));
5364 * Hook to handle "out of memory" errors
5366 static vptr hook_rpanic(huge size)
5369 #pragma unused (size)
5373 /* Free the lifeboat */
5376 /* Free the lifeboat */
5377 DisposePtr(lifeboat);
5379 /* Forget the lifeboat */
5382 /* Mega-Hack -- Warning */
5384 mac_warning("¥á¥â¥ê¡¼¤¬Â¤ê¤Þ¤»¤ó!\rº£¤¹¤°½ªÎ»¤·¤Æ²¼¤µ¤¤!");
5386 mac_warning("Running out of Memory!\rAbort this process now!");
5389 /* Mega-Hack -- Never leave this function */
5390 while (TRUE) CheckEvents(TRUE);
5393 /* Mega-Hack -- Crash */
5399 * Hook to tell the user something important
5401 static void hook_plog(cptr str)
5403 /* Warning message */
5408 * Hook to tell the user something, and then quit
5410 static void hook_quit(cptr str)
5412 /* Warning if needed */
5413 if (str) mac_warning(str);
5415 /* Write a preference file */
5423 * Hook to tell the user something, and then crash
5425 static void hook_core(cptr str)
5427 /* XXX Use the debugger */
5428 /* DebugStr(str); */
5431 if (str) mac_warning(str);
5433 /* Warn, then save player */
5435 mac_warning("Ã×̿Ū¤Ê¥¨¥é¡¼¤Ç¤¹.\r¶¯À©Åª¤Ë¥»¡¼¥Ö¤·¤Æ½ªÎ»¤·¤Þ¤¹.");
5437 mac_warning("Fatal error.\rI will now attempt to save and quit.");
5440 /* Attempt to save */
5442 if (!save_player()) mac_warning("·Ù¹ð -- ¥»¡¼¥Ö¤Ë¼ºÇÔ¤·¤Þ¤·¤¿!");
5444 if (!save_player()) mac_warning("Warning -- save failed!");
5453 /*** Main program ***/
5459 * XXX XXX XXX Hack -- This function attempts to "fix" the nasty
5460 * "Macintosh Save Bug" by using "absolute" path names, since on
5461 * System 7 machines anyway, the "current working directory" often
5462 * "changes" due to background processes, invalidating any "relative"
5463 * path names. Note that the Macintosh is limited to 255 character
5464 * path names, so be careful about deeply embedded directories...
5466 * XXX XXX XXX Hack -- This function attempts to "fix" the nasty
5467 * "missing lib folder bug" by allowing the user to help find the
5468 * "lib" folder by hand if the "application folder" code fails...
5470 static void init_stuff(void)
5489 #if TARGET_API_MAC_CARBON
5491 NavDialogOptions dialogOptions;
5492 FSSpec theFolderSpec;
5493 NavReplyRecord theReply;
5495 /* Fake rectangle */
5502 #if TARGET_API_MAC_CARBON
5503 screenRect = GetQDGlobalsScreenBits(&screen)->bounds;
5505 screenRect = qd.screenBits.bounds;
5507 center_rect(&r, &screenRect);
5509 /* Extract corner */
5514 /* Default to the "lib" folder with the application */
5515 refnum_to_name(path, app_dir, app_vol, (char*)("\plib:"));
5518 /* Check until done */
5521 /* Prepare the paths */
5522 init_file_paths(path);
5524 /* Build the filename */
5526 path_build(path, sizeof(path), ANGBAND_DIR_FILE, "news_j.txt");
5528 path_build(path, sizeof(path), ANGBAND_DIR_FILE, "news.txt");
5531 /* Attempt to open and close that file */
5532 if (0 == fd_close(fd_open(path, O_RDONLY))) break;
5536 plog_fmt("'%s' ¥Õ¥¡¥¤¥ë¤ò¥ª¡¼¥×¥ó½ÐÍè¤Þ¤»¤ó.", path);
5538 plog_fmt("Unable to open the '%s' file.", path);
5543 plog("Hengband¤Î'lib'¥Õ¥©¥ë¥À¤¬Â¸ºß¤·¤Ê¤¤¤«Àµ¤·¤¯Ìµ¤¤²ÄǽÀ¤¬¤¢¤ê¤Þ¤¹.");
5545 plog("The Angband 'lib' folder is probably missing or misplaced.");
5550 plog("Please 'open' any file in any sub-folder of the 'lib' folder.");
5552 plog("Please 'open' any file in any sub-folder of the 'lib' folder.");
5555 #if TARGET_API_MAC_CARBON
5556 /* Ask the user to choose the lib folder */
5557 err = NavGetDefaultDialogOptions(&dialogOptions);
5560 if (err != noErr) quit(NULL);
5562 /* Set default location option */
5563 dialogOptions.dialogOptionFlags |= kNavSelectDefaultLocation;
5565 /* Clear preview option */
5566 dialogOptions.dialogOptionFlags &= ~(kNavAllowPreviews);
5568 /* Forbit selection of multiple files */
5569 dialogOptions.dialogOptionFlags &= ~(kNavAllowMultipleFiles);
5571 /* Display location */
5572 dialogOptions.location = topleft;
5574 /* Load the message for the missing folder from the resource fork */
5575 GetIndString(dialogOptions.message, 128, 1);
5577 /* Wait for the user to choose a folder */
5578 err = NavChooseFolder(
5586 /* Assume the player doesn't want to go on */
5587 if ((err != noErr) || !theReply.validRecord) quit(NULL);
5589 /* Retrieve FSSpec from the reply */
5591 AEKeyword theKeyword;
5592 DescType actualType;
5595 /* Get a pointer to selected folder */
5597 &(theReply.selection),
5607 if (err != noErr) quit(NULL);
5610 /* Free navitagor reply */
5611 err = NavDisposeReply(&theReply);
5614 if (err != noErr) quit(NULL);
5616 /* Extract textual file name for given file */
5619 theFolderSpec.parID,
5620 theFolderSpec.vRefNum,
5621 (char *)theFolderSpec.name);
5623 /* Allow "text" files */
5626 /* Allow "save" files */
5629 /* Allow "data" files */
5633 SFGetFile(topleft, "\p", NULL, 3, types, NULL, &reply);
5636 if (!reply.good) quit(NULL);
5638 /* Extract textual file name for given file */
5639 GetWDInfo(reply.vRefNum, &vrefnum, &drefnum, &junk);
5640 refnum_to_name(path, drefnum, vrefnum, (char*)reply.fName);
5643 /* Hack -- Remove the "filename" */
5644 i = strlen(path) - 1;
5645 while ((i > 0) && (path[i] != ':')) i--;
5646 if (path[i] == ':') path[i+1] = '\0';
5648 /* Hack -- allow "lib" folders */
5649 if (suffix(path, "lib:")) continue;
5651 /* Hack -- Remove the "sub-folder" */
5653 while ((i > 1) && (path[i] != ':')) i--;
5654 if (path[i] == ':') path[i+1] = '\0';
5660 * Macintosh Main loop
5664 EventRecord tempEvent;
5665 int numberOfMasters = 10;
5667 #if !TARGET_API_MAC_CARBON
5668 /* Increase stack space by 64K */
5669 SetApplLimit(GetApplLimit() - 131072L);//65536L);
5671 /* Stretch out the heap to full size */
5675 /* Get more Masters */
5676 while (numberOfMasters--) MoreMasters();
5678 #if !TARGET_API_MAC_CARBON
5679 /* Set up the Macintosh */
5680 InitGraf(&qd.thePort);
5694 FlushEvents(everyEvent, 0);
5696 /* Flush events some more (?) */
5697 (void)EventAvail(everyEvent, &tempEvent);
5698 (void)EventAvail(everyEvent, &tempEvent);
5699 (void)EventAvail(everyEvent, &tempEvent);
5702 #ifdef ANGBAND_LITE_MAC
5706 #else /* ANGBAND_LITE_MAC */
5708 # if defined(powerc) || defined(__powerc)
5710 /* Assume System 7 */
5712 /* Assume Color Quickdraw */
5722 /* Check the Gestalt */
5723 err = Gestalt(gestaltSystemVersion, &versionNumber);
5725 /* Check the version */
5726 if ((err != noErr) || (versionNumber < 0x0700))
5729 quit("¤³¤Î¥×¥í¥°¥é¥à¤Ï´Á»úTalk7.x.x°Ê¹ß¤ÇÆ°ºî¤·¤Þ¤¹.");
5731 quit("You must have System 7 to use this program.");
5741 /* Check the environs */
5742 if (SysEnvirons(1, &env) != noErr)
5745 quit("SysEnvirons ¥³¡¼¥ë¤Ï¼ºÇÔ¤·¤Þ¤·¤¿¡ª");
5747 quit("The SysEnvirons call failed!");
5751 /* Check for System Seven Stuff */
5752 if (env.systemVersion < 0x0700)
5755 quit("¤³¤Î¥×¥í¥°¥é¥à¤Ï´Á»úTalk7.x.x°Ê¹ß¤ÇÆ°ºî¤·¤Þ¤¹.");
5757 quit("You must have System 7 to use this program.");
5761 /* Check for Color Quickdraw */
5762 if (!env.hasColorQD)
5765 quit("¤³¤Î¥×¥í¥°¥é¥à¤ÏColor Quickdraw¤¬Ìµ¤¤¤ÈÆ°ºî¤·¤Þ¤»¤ó.");
5767 quit("You must have Color Quickdraw to use this program.");
5774 #endif /* ANGBAND_LITE_MAC */
5778 /* Obtain a "Universal Procedure Pointer" */
5779 AEH_Start_UPP = NewAEEventHandlerUPP(AEH_Start);
5780 /* Install the hook (ignore error codes) */
5781 AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, AEH_Start_UPP,
5784 /* Obtain a "Universal Procedure Pointer" */
5785 AEH_Quit_UPP = NewAEEventHandlerUPP(AEH_Quit);
5786 /* Install the hook (ignore error codes) */
5787 AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, AEH_Quit_UPP,
5790 /* Obtain a "Universal Procedure Pointer" */
5791 AEH_Print_UPP = NewAEEventHandlerUPP(AEH_Print);
5792 /* Install the hook (ignore error codes) */
5793 AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments, AEH_Print_UPP,
5796 /* Obtain a "Universal Procedure Pointer" */
5797 AEH_Open_UPP = NewAEEventHandlerUPP(AEH_Open);
5798 /* Install the hook (ignore error codes) */
5799 AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, AEH_Open_UPP,
5803 /* Find the current application */
5807 /* Mark ourself as the file creator */
5810 /* Default to saving a "text" file */
5814 #if defined(__MWERKS__)
5816 /* Obtian a "Universal Procedure Pointer" */
5817 #if TARGET_API_MAC_CARBON
5818 ynfilterUPP = NewModalFilterUPP(ynfilter);
5820 ynfilterUPP = NewModalFilterProc(ynfilter);
5826 /* Hook in some "z-virt.c" hooks */
5827 rnfree_aux = hook_rnfree;
5828 ralloc_aux = hook_ralloc;
5829 rpanic_aux = hook_rpanic;
5831 /* Hooks in some "z-util.c" hooks */
5832 plog_aux = hook_plog;
5833 quit_aux = hook_quit;
5834 core_aux = hook_core;
5836 BackColor(blackColor);
5837 ForeColor(whiteColor);
5839 /* Show the "watch" cursor */
5840 SetCursor(*(GetCursor(watchCursor)));
5842 /* Prepare the menubar */
5845 /* Prepare the windows */
5852 /* Hack -- process all events */
5853 while (CheckEvents(TRUE)) /* loop */;
5855 /* Reset the cursor */
5856 #if TARGET_API_MAC_CARBON
5859 GetQDGlobalsArrow( &arrow );
5863 SetCursor( &qd.arrow );
5867 /* Mega-Hack -- Allocate a "lifeboat" */
5868 lifeboat = NewPtr(16384);
5870 /* Note the "system" */
5871 ANGBAND_SYS = "mac";
5880 /* Hack -- process all events */
5881 while (CheckEvents(TRUE)) /* loop */;
5884 /* We are now initialized */
5888 /* Handle "open_when_ready" */
5889 handle_open_when_ready();
5895 /* Prompt the user */
5897 prt("'¥Õ¥¡¥¤¥ë'¥á¥Ë¥å¡¼¤è¤ê'¿·µ¬'¤Þ¤¿¤Ï'³«¤¯...'¤òÁªÂò¤·¤Æ¤¯¤À¤µ¤¤¡£", 23, 10);
5899 prt("[Choose 'New' or 'Open' from the 'File' menu]", 23, 15);
5902 /* Flush the prompt */
5906 /* Hack -- Process Events Forever */
5907 while (TRUE) CheckEvents(TRUE);