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>
159 #include <CFPreferences.h>
160 #include <CFNumber.h>
162 # include <CarbonStdCLib.h>
173 * Cleaning up a couple of things to make these easier to change --AR
176 #define PREF_FILE_NAME "Hengband Preferences"
178 #define PREF_FILE_NAME "Hengband-E Preferences"
182 * Use "malloc()" instead of "NewPtr()"
184 /* #define USE_MALLOC */
187 /* Default creator signature */
188 #ifndef ANGBAND_CREATOR
189 # define ANGBAND_CREATOR 'Heng'
193 #if defined(powerc) || defined(__powerc)
196 * Disable "LITE" version
198 # undef ANGBAND_LITE_MAC
203 #ifdef ANGBAND_LITE_MAC
206 * Maximum number of windows
208 # define MAX_TERM_DATA 1
210 #else /* ANGBAND_LITE_MAC */
213 * Maximum number of windows
215 # define MAX_TERM_DATA 8
218 * Activate some special code
220 # define USE_SFL_CODE
222 #endif /* ANGBAND_LITE_MAC */
229 * Include the necessary header files
231 #include <AppleEvents.h>
239 * Globals for MPW compilation
241 #if defined(MACH_O_CARBON) || defined(MAC_MPW)
243 #if !TARGET_API_MAC_CARBON
255 * The Angband Color Set (0 to 15):
256 * Black, White, Slate, Orange, Red, Blue, Green, Umber
257 * D-Gray, L-Gray, Violet, Yellow, L-Red, L-Blue, L-Green, L-Umber
259 * Colors 8 to 15 are basically "enhanced" versions of Colors 0 to 7.
261 * On the Macintosh, we use color quickdraw, and we use actual "RGB"
262 * values below to choose the 16 colors.
264 * If we are compiled for ancient machines, we bypass color and simply
265 * draw everything in white (letting "z-term.c" automatically convert
266 * "black" into "wipe" calls).
268 static RGBColor foo[16] =
270 {0x0000, 0x0000, 0x0000}, /* TERM_DARK */
271 {0xFFFF, 0xFFFF, 0xFFFF}, /* TERM_WHITE */
272 {0x8080, 0x8080, 0x8080}, /* TERM_SLATE */
273 {0xFFFF, 0x8080, 0x0000}, /* TERM_ORANGE */
274 {0xC0C0, 0x0000, 0x0000}, /* TERM_RED */
275 {0x0000, 0x8080, 0x4040}, /* TERM_GREEN */
276 {0x0000, 0x0000, 0xFFFF}, /* TERM_BLUE */
277 {0x8080, 0x4040, 0x0000}, /* TERM_UMBER */
278 {0x4040, 0x4040, 0x4040}, /* TERM_L_DARK */
279 {0xC0C0, 0xC0C0, 0xC0C0}, /* TERM_L_WHITE */
280 {0xFFFF, 0x0000, 0xFFFF}, /* TERM_VIOLET */
281 {0xFFFF, 0xFFFF, 0x0000}, /* TERM_YELLOW */
282 {0xFFFF, 0x0000, 0x0000}, /* TERM_L_RED */
283 {0x0000, 0xFFFF, 0x0000}, /* TERM_L_GREEN */
284 {0x0000, 0xFFFF, 0xFFFF}, /* TERM_L_BLUE */
285 {0xC0C0, 0x8080, 0x4040} /* TERM_L_UMBER */
294 typedef struct term_data term_data;
307 #ifdef ANGBAND_LITE_MAC
311 #else /* ANGBAND_LITE_MAC */
323 #endif /* ANGBAND_LITE_MAC */
366 * Forward declare -- see below
368 static bool CheckEvents(bool wait);
372 * Hack -- location of the main directory
374 static short app_vol;
379 * Delay handling of double-clicked savefiles
381 Boolean open_when_ready = FALSE;
384 * Delay handling of pre-emptive "quit" event
386 Boolean quit_when_ready = FALSE;
390 * Hack -- game in progress
392 static int game_in_progress = 0;
396 * Only do "SetPort()" when needed
398 static WindowPtr active = NULL;
403 * An array of term_data's
405 static term_data data[MAX_TERM_DATA];
410 * Note when "open"/"new" become valid
412 static bool initialized = FALSE;
415 * Version of Mac OS - for version specific bug workarounds (; ;)
417 static long mac_os_version;
421 * CodeWarrior uses Universal Procedure Pointers
423 static ModalFilterUPP ynfilterUPP;
430 AEEventHandlerUPP AEH_Start_UPP;
431 AEEventHandlerUPP AEH_Quit_UPP;
432 AEEventHandlerUPP AEH_Print_UPP;
433 AEEventHandlerUPP AEH_Open_UPP;
441 static int ext_sound = 0;
449 #define SND_CMD_ERROR 6
451 static int soundchoice[] = {
519 static short soundmode[8];
521 static int ext_graf = 0;
526 * Convert refnum+vrefnum+fname into a full file name
527 * Store this filename in 'buf' (make sure it is long enough)
528 * Note that 'fname' looks to be a "pascal" string
530 #if TARGET_API_MAC_CARBON
531 static void refnum_to_name(char *buf, long refnum, short vrefnum, char *fname)
547 for (j=1; j<=fname[0]; j++)
549 res[i-fname[0]+j] = fname[j];
558 pb.dirInfo.ioDrDirID=pb.dirInfo.ioDrParID;
559 err = FSMakeFSSpec( vref, dirID, "\p", &spec );
565 for (j=1; j<=spec.name[0]; j++)
567 res[i-spec.name[0]+j] = spec.name[j];
574 /* Extract the result */
575 for (j = 0, i++; res[i]; j++, i++) buf[j] = res[i];
579 static void refnum_to_name(char *buf, long refnum, short vrefnum, char *fname)
591 for (j=1; j<=fname[0]; j++)
593 res[i-fname[0]+j] = fname[j];
597 pb.ioCompletion=NULL;
599 pb.ioVRefNum=vrefnum;
605 pb.ioDrDirID=pb.ioDrParID;
606 err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
608 for (j=1; j<=name[0]; j++)
610 res[i-name[0]+j] = name[j];
614 if (pb.ioDrDirID == fsRtDirID) break;
617 /* Extract the result */
618 for (j = 0, i++; res[i]; j++, i++) buf[j] = res[i];
623 #if TARGET_API_MAC_CARBON
624 pascal OSErr FSpLocationFromFullPath(short fullPathLength,
625 const void *fullPath,
633 /* Create a minimal alias from the full pathname */
634 nullString[0] = 0; /* null string to indicate no zone or server name */
635 result = NewAliasMinimalFromFullPath(fullPathLength, fullPath, nullString, nullString, &alias);
636 if ( result == noErr )
638 /* Let the Alias Manager resolve the alias. */
639 result = ResolveAlias(NULL, alias, spec, &wasChanged);
641 /* work around Alias Mgr sloppy volume matching bug */
642 if ( spec->vRefNum == 0 )
644 /* invalidate wrong FSSpec */
649 DisposeHandle((Handle)alias); /* Free up memory used */
658 * XXX XXX XXX Allow the system to ask us for a filename
660 static bool askfor_file(char *buf, int len)
668 /* Default file name */
669 sprintf((char*)dflt + 1, "%s's description", buf);
670 dflt[0] = strlen((char*)dflt + 1);
672 /* Ask for a file name */
673 topleft.h=(qd.screenBits.bounds.left+qd.screenBits.bounds.right)/2-344/2;
674 topleft.v=(2*qd.screenBits.bounds.top+qd.screenBits.bounds.bottom)/3-188/2;
675 SFPutFile(topleft, "\pSelect a filename:", dflt, NULL, &reply);
676 /* StandardPutFile("\pSelect a filename:", dflt, &reply); */
684 GetWDInfo(reply.vRefNum, &vrefnum, &drefnum, &junk);
686 /* Extract the name */
687 refnum_to_name(buf, drefnum, vrefnum, (char*)reply.fName);
699 static void local_to_global( Rect *r )
706 LocalToGlobal( &temp );
714 LocalToGlobal( &temp );
720 static void global_to_local( Rect *r )
727 GlobalToLocal( &temp );
735 GlobalToLocal( &temp );
745 * Convert pathname to an appropriate format, because MPW's
746 * CarbonStdCLib chose to use system's native path format,
747 * making our lives harder to create binaries that run on
748 * OS 8/9 and OS X :( -- pelpel
750 void convert_pathname(char* path)
754 /* Nothing has to be done for CarbonLib on Classic */
755 if (mac_os_version >= 0x1000)
757 /* Convert to POSIX style */
758 ConvertHFSPathToUnixPath(path, buf);
760 /* Copy the result back */
768 # ifdef CHECK_MODIFICATION_TIME
771 * Although there is no easy way to emulate fstat in the old interface,
772 * we still can do stat-like things, because Mac OS is an OS.
774 static int get_modification_time(cptr path, u32b *mod_time)
780 /* Paranoia - make sure the pathname fits in Str255 */
782 if (i > 255) return (-1);
784 /* Convert pathname to a Pascal string */
785 strncpy((char *)pathname + 1, path, 255);
788 /* Set up parameter block */
789 pb.hFileInfo.ioNamePtr = pathname;
790 pb.hFileInfo.ioFDirIndex = 0;
791 pb.hFileInfo.ioVRefNum = app_vol;
792 pb.hFileInfo.ioDirID = 0;
794 /* Get catalog information of the file */
795 if (PBGetCatInfoSync(&pb) != noErr) return (-1);
797 /* Set modification date and time */
798 *mod_time = pb.hFileInfo.ioFlMdDat;
806 * A (non-Mach-O) Mac OS version of check_modification_time, for those
807 * compilers without good enough POSIX-compatibility libraries XXX XXX
809 errr check_modification_date(int fd, cptr template_file)
812 u32b txt_stat, raw_stat;
817 /* Build the file name */
818 path_build(buf, sizeof(buf), ANGBAND_DIR_EDIT, template_file);
821 convert_pathname(buf);
823 /* Obtain modification time */
824 if (get_modification_time(buf, &txt_stat)) return (-1);
826 /* XXX Build filename of the corresponding *.raw file */
827 strnfmt(fname, sizeof(fname), "%s", template_file);
830 p = strrchr(fname, '.');
833 if (p == NULL) return (-1);
835 /* Substitute ".raw" for ".txt" */
838 /* Build the file name of the raw file */
839 path_build(buf, sizeof(buf), ANGBAND_DIR_DATA, fname);
842 convert_pathname(buf);
844 /* Obtain modification time */
845 if (get_modification_time(buf, &raw_stat)) return (-1);
847 /* Ensure the text file is not newer than the raw file */
848 if (txt_stat > raw_stat) return (-1);
850 /* Keep using the current .raw file */
854 # endif /* CHECK_MODIFICATION_TIME */
859 * Center a rectangle inside another rectangle
861 static void center_rect(Rect *r, Rect *s)
863 int centerx = (s->left + s->right)/2;
864 int centery = (2*s->top + s->bottom)/3;
865 int dx = centerx - (r->right - r->left)/2 - r->left;
866 int dy = centery - (r->bottom - r->top)/2 - r->top;
875 * Convert a pascal string in place
877 * This function may be defined elsewhere, but since it is so
878 * small, it is not worth finding the proper function name for
879 * all the different platforms.
881 static void ptocstr(StringPtr src)
885 /* Hack -- pointer */
886 char *s = (char*)(src);
888 /* Hack -- convert the string */
889 for (i = s[0]; i; i--, s++) s[0] = s[1];
891 /* Hack -- terminate the string */
896 #if defined(USE_SFL_CODE)
900 * The following three routines (pstrcat, pstrinsert, and PathNameFromDirID)
901 * were taken from the Think Reference section called "Getting a Full Pathname"
902 * (under the File Manager section). We need PathNameFromDirID to get the
903 * full pathname of the opened savefile, making no assumptions about where it
906 * I had to hack PathNameFromDirID a little for MetroWerks, but it's awfully
909 static void pstrcat(StringPtr dst, StringPtr src)
912 BlockMove(src + 1, dst + *dst + 1, *src);
914 /* adjust length byte */
919 * pstrinsert - insert string 'src' at beginning of string 'dst'
921 static void pstrinsert(StringPtr dst, StringPtr src)
923 /* make room for new string */
924 BlockMove(dst + 1, dst + *src + 1, *dst);
926 /* copy new string in */
927 BlockMove(src + 1, dst + 1, *src);
929 /* adjust length byte */
933 static void PathNameFromDirID(long dirID, short vRefNum, StringPtr fullPathName)
936 Str255 directoryName;
939 fullPathName[0] = '\0';
941 block.dirInfo.ioDrParID = dirID;
942 block.dirInfo.ioNamePtr = directoryName;
946 block.dirInfo.ioVRefNum = vRefNum;
947 block.dirInfo.ioFDirIndex = -1;
948 block.dirInfo.ioDrDirID = block.dirInfo.ioDrParID;
949 err = PBGetCatInfo(&block, FALSE);
950 pstrcat(directoryName, (StringPtr)"\p:");
951 pstrinsert(fullPathName, directoryName);
952 if (block.dirInfo.ioDrDirID == 2) break;
958 #if TARGET_API_MAC_CARBON
960 static OSErr ChooseFile( StringPtr filename, FSSpec selfld )
962 NavReplyRecord reply;
963 NavDialogOptions dialogOptions;
964 NavTypeListHandle navTypeList = NULL;
968 AECreateDesc( typeFSS, &selfld, sizeof(FSSpec), &deffld );
970 err = NavGetDefaultDialogOptions( &dialogOptions );
974 err = NavChooseFile( &deffld, &reply, &dialogOptions, NULL, NULL, NULL, navTypeList, NULL );
976 if ( reply.validRecord && err == noErr ){
977 // grab the target FSSpec from the AEDesc:
983 // retrieve the returned selection:
984 // there is only one selection here we get only the first AEDescList:
985 if (( err = AEGetNthPtr( &(reply.selection), 1, typeFSS, &keyWord, &typeCode, &finalFSSpec, sizeof( FSSpec ), &actualSize )) == noErr )
987 refnum_to_name( (char *)filename, finalFSSpec.parID, finalFSSpec.vRefNum, (char *)finalFSSpec.name );
988 // 'finalFSSpec' is the chosen file¥Î
991 err = NavDisposeReply( &reply );
993 if( navTypeList != NULL )
995 DisposeHandle( (Handle)navTypeList );
1000 AEDisposeDesc( &deffld );
1008 * Activate a given window, if necessary
1010 static void activate(WindowPtr w)
1016 #if TARGET_API_MAC_CARBON
1017 if (w) SetPortWindowPort(w);
1029 * Display a warning message
1031 static void mac_warning(cptr warning)
1036 /* Limit of 250 chars */
1037 len = strlen(warning);
1038 if (len > 250) len = 250;
1040 /* Make a "Pascal" string */
1042 for (i=0; i<len; i++) text[i+1] = warning[i];
1044 /* Prepare the dialog box values */
1045 ParamText(text, "\p", "\p", "\p");
1047 /* Display the Alert, wait for Okay */
1053 /*** Some generic functions ***/
1056 #ifdef ANGBAND_LITE_MAC
1059 * Hack -- activate a color (0 to 255)
1061 #define term_data_color(TD,A) /* Nothing */
1063 #else /* ANGBAND_LITE_MAC */
1066 * Hack -- activate a color (0 to 255)
1068 static void term_data_color(term_data *td, int a)
1074 /* Extract the R,G,B data */
1075 rv = angband_color_table[a][1];
1076 gv = angband_color_table[a][2];
1077 bv = angband_color_table[a][3];
1080 color.red = (rv | (rv << 8));
1081 color.green = (gv | (gv << 8));
1082 color.blue = (bv | (bv << 8));
1084 /* Activate the color */
1085 RGBForeColor(&color);
1087 /* Memorize color */
1091 #endif /* ANGBAND_LITE_MAC */
1095 * Hack -- Apply and Verify the "font" info
1097 * This should usually be followed by "term_data_check_size()"
1099 static void term_data_check_font(term_data *td)
1105 WindowPtr old = active;
1111 /* Instantiate font */
1112 TextFont(td->font_id);
1113 TextSize(td->font_size);
1114 TextFace(td->font_face);
1116 /* Extract the font info */
1119 /* Assume monospaced */
1120 td->font_mono = TRUE;
1122 /* Extract the font sizing values XXX XXX XXX */
1123 td->font_wid = CharWidth('@'); /* info.widMax; */
1124 td->font_hgt = info.ascent + info.descent;
1126 td->font_o_y = info.ascent;
1128 /* Check important characters */
1129 for (i = 33; i < 127; i++)
1131 /* Hack -- notice non-mono-space */
1132 if (td->font_wid != CharWidth(i)) td->font_mono = FALSE;
1134 /* Hack -- collect largest width */
1135 if (td->font_wid < CharWidth(i)) td->font_wid = CharWidth(i);
1138 /* Set default offsets */
1139 td->tile_o_x = td->font_o_x;
1140 td->tile_o_y = td->font_o_y;
1142 /* Set default tile size */
1143 if( td->tile_wid == 0 && td->tile_hgt == 0 ){
1144 td->tile_wid = td->font_wid;
1145 td->tile_hgt = td->font_hgt;
1148 /* Re-activate the old window */
1154 * Hack -- Apply and Verify the "size" info
1156 static void term_data_check_size(term_data *td)
1160 #if TARGET_API_MAC_CARBON
1161 GetQDGlobalsScreenBits( &screen );
1163 screen = qd.screenBits;
1165 /* Minimal window size */
1168 /* Enforce minimal size */
1169 if (td->cols < 80) td->cols = 80;
1170 if (td->rows < 24) td->rows = 24;
1173 /* Allow small windows for the rest */
1176 if (td->cols < 1) td->cols = 1;
1177 if (td->rows < 1) td->rows = 1;
1180 /* Minimal tile size */
1181 if (td->tile_wid < 4) td->tile_wid = 4;
1182 if (td->tile_hgt < 4) td->tile_hgt = 4;
1184 /* Default tile offsets */
1185 td->tile_o_x = (td->tile_wid - td->font_wid) / 2;
1186 td->tile_o_y = (td->tile_hgt - td->font_hgt) / 2;
1188 /* Minimal tile offsets */
1189 if (td->tile_o_x < 0) td->tile_o_x = 0;
1190 if (td->tile_o_y < 0) td->tile_o_y = 0;
1192 /* Apply font offsets */
1193 td->tile_o_x += td->font_o_x;
1194 td->tile_o_y += td->font_o_y;
1196 /* Calculate full window size */
1197 td->size_wid = td->cols * td->tile_wid + td->size_ow1 + td->size_ow2;
1198 td->size_hgt = td->rows * td->tile_hgt + td->size_oh1 + td->size_oh2;
1200 /* Verify the top */
1201 if (td->r.top > screen.bounds.bottom - td->size_hgt)
1203 td->r.top = screen.bounds.bottom - td->size_hgt;
1206 /* Verify the top */
1207 if (td->r.top < screen.bounds.top + 30)
1209 td->r.top = screen.bounds.top + 30;
1212 /* Verify the left */
1213 if (td->r.left > screen.bounds.right - td->size_wid)
1215 td->r.left = screen.bounds.right - td->size_wid;
1218 /* Verify the left */
1219 if (td->r.left < screen.bounds.left)
1221 td->r.left = screen.bounds.left;
1224 /* Calculate bottom right corner */
1225 td->r.right = td->r.left + td->size_wid;
1226 td->r.bottom = td->r.top + td->size_hgt;
1228 /* Assume no graphics */
1229 td->t->higher_pict = FALSE;
1230 td->t->always_pict = FALSE;
1232 #ifdef ANGBAND_LITE_MAC
1236 #else /* ANGBAND_LITE_MAC */
1238 /* Handle graphics */
1241 /* Use higher_pict whenever possible */
1242 if (td->font_mono) td->t->higher_pict = TRUE;
1244 /* Use always_pict only when necessary */
1245 else td->t->always_pict = TRUE;
1248 #endif /* ANGBAND_LITE_MAC */
1250 /* Fake mono-space */
1251 if (!td->font_mono ||
1252 (td->font_wid != td->tile_wid) ||
1253 (td->font_hgt != td->tile_hgt))
1255 /* Handle fake monospace -- this is SLOW */
1256 if (td->t->higher_pict) td->t->higher_pict = FALSE;
1257 td->t->always_pict = TRUE;
1262 * Hack -- resize a term_data
1264 * This should normally be followed by "term_data_resize()"
1266 static void term_data_resize(term_data *td)
1268 /* Actually resize the window */
1269 SizeWindow(td->w, td->size_wid, td->size_hgt, 0);
1275 * Hack -- redraw a term_data
1277 * Note that "Term_redraw()" calls "TERM_XTRA_CLEAR"
1279 static void term_data_redraw(term_data *td)
1283 /* Activate the term */
1284 Term_activate(td->t);
1286 /* Redraw the contents */
1289 /* Flush the output */
1292 /* Restore the old term */
1295 /* No need to redraw */
1296 #if TARGET_API_MAC_CARBON
1298 RgnHandle theRgn = NewRgn();
1299 GetWindowRegion( td->w, kWindowContentRgn, theRgn );
1300 ValidWindowRgn( (WindowRef)(td->w), theRgn );
1301 DisposeRgn( theRgn );
1304 ValidRect(&td->w->portRect);
1312 #ifdef ANGBAND_LITE_MAC
1316 #else /* ANGBAND_LITE_MAC */
1323 static int pictID = 1001; /* 8x8 tiles; 16x16 tiles are 1002 */
1325 static int grafWidth = 8; /* Always equal to grafHeight */
1326 static int grafHeight = 8; /* Either 8 or 16 */
1328 static bool arg_newstyle_graphics;
1329 static bool use_newstyle_graphics;
1334 typedef struct FrameRec FrameRec;
1339 * - GWorld for the frame image
1340 * - Handle to pix map (saved for unlocking/locking)
1341 * - Pointer to color pix map (valid only while locked)
1345 GWorldPtr framePort;
1346 PixMapHandle framePixHndl;
1353 * The global picture data
1355 static FrameRec *frameP = NULL;
1361 static void BenSWLockFrame(FrameRec *srcFrameP)
1363 PixMapHandle pixMapH;
1365 pixMapH = GetGWorldPixMap(srcFrameP->framePort);
1366 (void)LockPixels(pixMapH);
1367 HLockHi((Handle)pixMapH);
1368 srcFrameP->framePixHndl = pixMapH;
1369 #if TARGET_API_MAC_CARBON
1370 srcFrameP->framePix = (PixMapPtr)*(Handle)pixMapH;
1372 srcFrameP->framePix = (PixMapPtr)StripAddress(*(Handle)pixMapH);
1381 static void BenSWUnlockFrame(FrameRec *srcFrameP)
1383 if (srcFrameP->framePort != NULL)
1385 HUnlock((Handle)srcFrameP->framePixHndl);
1386 UnlockPixels(srcFrameP->framePixHndl);
1389 srcFrameP->framePix = NULL;
1393 static OSErr BenSWCreateGWorldFromPict(
1394 GWorldPtr *pictGWorld,
1398 GWorldPtr saveGWorld;
1399 GDHandle saveGDevice;
1400 GWorldPtr tempGWorld;
1409 depth = data[0].pixelDepth;
1412 theGDH = data[0].theGDH;
1414 /* Obtain size rectangle */
1415 pictRect = (**pictH).picFrame;
1416 OffsetRect(&pictRect, -pictRect.left, -pictRect.top);
1418 /* Create a GWorld */
1419 err = NewGWorld(&tempGWorld, depth, &pictRect, nil,
1420 theGDH, noNewDevice);
1429 *pictGWorld = tempGWorld;
1432 GetGWorld(&saveGWorld, &saveGDevice);
1435 SetGWorld(tempGWorld, nil);
1437 /* Dump the pict into the GWorld */
1438 (void)LockPixels(GetGWorldPixMap(tempGWorld));
1439 EraseRect(&pictRect);
1440 DrawPicture(pictH, &pictRect);
1441 UnlockPixels(GetGWorldPixMap(tempGWorld));
1443 /* Restore GWorld */
1444 SetGWorld(saveGWorld, saveGDevice);
1454 * Init the global "frameP"
1457 static errr globe_init(void)
1461 GWorldPtr tempPictGWorldP;
1465 /* Use window XXX XXX XXX */
1466 #if TARGET_API_MAC_CARBON
1467 SetPortWindowPort(data[0].w);
1473 /* Get the pict resource */
1474 newPictH = GetPicture(pictID);
1476 /* Analyze result */
1477 err = (newPictH ? 0 : -1);
1484 err = BenSWCreateGWorldFromPict(&tempPictGWorldP, newPictH);
1486 /* Release resource */
1487 ReleaseResource((Handle)newPictH);
1492 /* Create the frame */
1493 frameP = (FrameRec*)NewPtrClear((Size)sizeof(FrameRec));
1495 /* Analyze result */
1496 err = (frameP ? 0 : -1);
1502 frameP->framePort = tempPictGWorldP;
1505 BenSWLockFrame(frameP);
1516 * Nuke the global "frameP"
1518 static errr globe_nuke(void)
1524 BenSWUnlockFrame(frameP);
1526 /* Dispose of the GWorld */
1527 DisposeGWorld(frameP->framePort);
1529 /* Dispose of the memory */
1530 DisposePtr((Ptr)frameP);
1537 FlushEvents(everyEvent, 0);
1544 #endif /* ANGBAND_LITE_MAC */
1548 /*** Support for the "z-term.c" package ***/
1552 * Initialize a new Term
1554 * Note also the "window type" called "noGrowDocProc", which might be more
1555 * appropriate for the main "screen" window.
1557 * Note the use of "srcCopy" mode for optimized screen writes.
1559 static void Term_init_mac(term *t)
1561 term_data *td = (term_data*)(t->data);
1563 static RGBColor black = {0x0000,0x0000,0x0000};
1564 static RGBColor white = {0xFFFF,0xFFFF,0xFFFF};
1566 #ifdef ANGBAND_LITE_MAC
1568 /* Make the window */
1569 td->w = NewWindow(0, &td->r, td->title, 0, noGrowDocProc, (WindowPtr)-1, 1, 0L);
1571 #else /* ANGBAND_LITE_MAC */
1573 /* Make the window */
1574 td->w = NewCWindow(0, &td->r, td->title, 0, documentProc, (WindowPtr)-1, 1, 0L);
1576 #endif /* ANGBAND_LITE_MAC */
1578 /* Activate the window */
1581 /* Erase behind words */
1584 /* Apply and Verify */
1585 term_data_check_font(td);
1586 term_data_check_size(td);
1588 /* Resize the window */
1589 term_data_resize(td);
1591 #ifdef ANGBAND_LITE_MAC
1593 /* Prepare the colors (base colors) */
1594 BackColor(blackColor);
1595 ForeColor(whiteColor);
1597 #else /* ANGBAND_LITE_MAC */
1599 /* Prepare the colors (real colors) */
1600 RGBBackColor(&black);
1601 RGBForeColor(&white);
1608 GDHandle currentGDH;
1609 GWorldPtr windowGWorld;
1610 PixMapHandle basePixMap;
1612 /* Obtain the rect */
1613 #if TARGET_API_MAC_CARBON
1614 GetWindowBounds( (WindowRef)td->w, kWindowContentRgn, &globalRect );
1616 globalRect = td->w->portRect;
1617 LocalToGlobal((Point*)&globalRect.top);
1618 LocalToGlobal((Point*)&globalRect.bottom);
1621 /* Obtain the proper GDH */
1622 mainGDH = GetMaxDevice(&globalRect);
1624 /* Extract GWorld and GDH */
1625 GetGWorld(&windowGWorld, ¤tGDH);
1627 /* Obtain base pixmap */
1628 basePixMap = (**mainGDH).gdPMap;
1630 /* Save pixel depth */
1631 td->pixelDepth = (**basePixMap).pixelSize;
1633 /* Save Window GWorld */
1634 td->theGWorld = windowGWorld;
1636 /* Save Window GDH */
1637 td->theGDH = currentGDH;
1640 td->mainSWGDH = mainGDH;
1643 #endif /* ANGBAND_LITE_MAC */
1648 #if TARGET_API_MAC_CARBON
1649 GetWindowBounds( (WindowRef)td->w, kWindowContentRgn, &portRect );
1650 global_to_local( &portRect );
1652 portRect = td->w->portRect;
1654 /* Clip to the window */
1655 ClipRect(&portRect);
1657 /* Erase the window */
1658 EraseRect(&portRect);
1660 /* Invalidate the window */
1661 #if TARGET_API_MAC_CARBON
1662 InvalWindowRect((WindowRef)(td->w), (const Rect *)(&portRect));
1664 InvalRect(&portRect);
1667 /* Display the window if needed */
1668 if (td->mapped) ShowWindow(td->w);
1670 /* Hack -- set "mapped" flag */
1671 t->mapped_flag = td->mapped;
1677 /* if (err == noErr)
1688 static void Term_nuke_mac(term *t)
1701 static errr Term_user_mac(int n)
1715 static errr Term_xtra_mac_react(void)
1717 term_data *td = (term_data*)(Term->data);
1723 #ifdef ANGBAND_LITE_MAC
1727 #else /* ANGBAND_LITE_MAC */
1730 if (use_sound != arg_sound)
1733 use_sound = arg_sound;
1737 /* Handle transparency */
1738 if (use_newstyle_graphics != arg_newstyle_graphics)
1742 if (globe_init() != 0)
1744 plog("Cannot initialize graphics!");
1745 arg_graphics = FALSE;
1746 arg_newstyle_graphics = FALSE;
1750 use_newstyle_graphics = arg_newstyle_graphics;
1752 /* Apply and Verify */
1753 term_data_check_size(td);
1755 /* Resize the window */
1756 term_data_resize(td);
1762 /* Handle graphics */
1763 if (use_graphics != arg_graphics)
1765 /* Initialize graphics */
1767 if (!use_graphics && !frameP && (globe_init() != 0))
1770 plog("¥°¥é¥Õ¥£¥Ã¥¯¤Î½é´ü²½¤Ï½ÐÍè¤Þ¤»¤ó¤Ç¤·¤¿.");
1772 plog("Cannot initialize graphics!");
1774 arg_graphics = FALSE;
1778 use_graphics = arg_graphics;
1780 /* Apply and Verify */
1781 term_data_check_size(td);
1783 /* Resize the window */
1784 term_data_resize(td);
1790 #endif /* ANGBAND_LITE_MAC */
1798 * Do a "special thing"
1800 static errr Term_xtra_mac(int n, int v)
1802 term_data *td = (term_data*)(Term->data);
1810 case TERM_XTRA_NOISE:
1819 #ifdef ANGBAND_LITE_MAC
1823 #else /* ANGBAND_LITE_MAC */
1826 case TERM_XTRA_SOUND:
1836 /* Open the resource file */
1837 oldResFile = CurResFile();
1838 newResFile = OpenResFile(sound);
1840 /* Close the resource file */
1841 CloseResFile(newResFile);
1842 UseResFile(oldResFile);
1845 /* Get the proper sound name */
1846 sprintf((char*)sound + 1, "%.16s.wav", angband_sound_name[v]);
1847 sound[0] = strlen((char*)sound + 1);
1849 /* Obtain resource XXX XXX XXX */
1850 handle = Get1NamedResource('snd ', sound);
1851 if( handle == NULL || ext_sound )
1852 handle = GetNamedResource('snd ', sound);
1855 if (handle && soundmode[soundchoice[v]] == true)
1858 LoadResource(handle);
1861 /* Play sound (wait for completion) */
1862 SndPlay(nil, (SndListHandle)handle, true);
1864 /* Unlock and release */
1866 ReleaseResource(handle);
1872 #endif /* ANGBAND_LITE_MAC */
1874 /* Process random events */
1875 case TERM_XTRA_BORED:
1877 /* Process an event */
1878 (void)CheckEvents(FALSE);
1884 /* Process pending events */
1885 case TERM_XTRA_EVENT:
1887 /* Process an event */
1888 (void)CheckEvents(v);
1894 /* Flush all pending events (if any) */
1895 case TERM_XTRA_FLUSH:
1897 /* Hack -- flush all events */
1898 while (CheckEvents(TRUE)) /* loop */;
1904 /* Hack -- Change the "soft level" */
1905 case TERM_XTRA_LEVEL:
1907 /* Activate if requested */
1908 if (v) activate(td->w);
1914 /* Clear the screen */
1915 case TERM_XTRA_CLEAR:
1919 #if TARGET_API_MAC_CARBON
1920 GetWindowBounds( (WindowRef)td->w, kWindowContentRgn, &portRect );
1921 global_to_local( &portRect );
1923 portRect = td->w->portRect;
1926 /* No clipping XXX XXX XXX */
1927 ClipRect(&portRect);
1929 /* Erase the window */
1930 EraseRect(&portRect);
1933 term_data_color(td, TERM_WHITE);
1935 /* Frame the window in white */
1937 LineTo(0, td->size_hgt-1);
1938 LineTo(td->size_wid-1, td->size_hgt-1);
1939 LineTo(td->size_wid-1, 0);
1941 /* Clip to the new size */
1942 r.left = portRect.left + td->size_ow1;
1943 r.top = portRect.top + td->size_oh1;
1944 r.right = portRect.right - td->size_ow2;
1945 r.bottom = portRect.bottom - td->size_oh2;
1952 /* React to changes */
1953 case TERM_XTRA_REACT:
1955 /* React to changes */
1956 return (Term_xtra_mac_react());
1959 /* Delay (milliseconds) */
1960 case TERM_XTRA_DELAY:
1965 #if TARGET_API_MAC_CARBON
1969 /* Convert millisecs to ticks */
1970 ticks = (v * 60L) / 1000;
1973 * Hack? - Put the programme into sleep.
1974 * No events match ~everyEvent, so nothing
1975 * should be lost in Angband's event queue.
1976 * Even if ticks are 0, it's worth calling for
1977 * the above mentioned reasons.
1979 WaitNextEvent(~everyEvent, &tmp, ticks, nil);
1981 long m = TickCount() + (v * 60L) / 1000;
1984 while (TickCount() < m) /* loop */;
2000 * Low level graphics (Assumes valid input).
2001 * Draw a "cursor" at (x,y), using a "yellow box".
2002 * We are allowed to use "Term_grab()" to determine
2003 * the current screen contents (for inverting, etc).
2005 static errr Term_curs_mac(int x, int y)
2009 term_data *td = (term_data*)(Term->data);
2012 term_data_color(td, TERM_YELLOW);
2014 /* Frame the grid */
2015 r.left = x * td->tile_wid + td->size_ow1;
2016 r.right = r.left + td->tile_wid;
2017 r.top = y * td->tile_hgt + td->size_oh1;
2018 r.bottom = r.top + td->tile_hgt;
2028 * Low level graphics (Assumes valid input).
2029 * Draw a "big cursor" at (x,y), using a "yellow box".
2030 * We are allowed to use "Term_grab()" to determine
2031 * the current screen contents (for inverting, etc).
2033 static errr Term_bigcurs_mac(int x, int y)
2037 term_data *td = (term_data*)(Term->data);
2040 term_data_color(td, TERM_YELLOW);
2042 /* Frame the grid */
2043 r.left = x * td->tile_wid + td->size_ow1;
2044 r.right = r.left + 2 * td->tile_wid;
2045 r.top = y * td->tile_hgt + td->size_oh1;
2046 r.bottom = r.top + td->tile_hgt;
2056 * Low level graphics (Assumes valid input)
2058 * Erase "n" characters starting at (x,y)
2060 static errr Term_wipe_mac(int x, int y, int n)
2064 term_data *td = (term_data*)(Term->data);
2066 /* Erase the block of characters */
2067 r.left = x * td->tile_wid + td->size_ow1;
2068 r.right = r.left + n * td->tile_wid;
2069 r.top = y * td->tile_hgt + td->size_oh1;
2070 r.bottom = r.top + td->tile_hgt;
2079 * Low level graphics. Assumes valid input.
2081 * Draw several ("n") chars, with an attr, at a given location.
2083 static errr Term_text_mac(int x, int y, int n, byte a, const char *cp)
2087 term_data *td = (term_data*)(Term->data);
2090 term_data_color(td, (a & 0x0F));
2092 /* Starting pixel */
2093 xp = x * td->tile_wid + td->tile_o_x + td->size_ow1;
2094 yp = y * td->tile_hgt + td->tile_o_y + td->size_oh1;
2096 /* Move to the correct location */
2099 /* Draw the character */
2100 if (n == 1) DrawChar(*cp);
2102 /* Draw the string */
2103 else DrawText(cp, 0, n);
2111 * Low level graphics (Assumes valid input)
2113 * Erase "n" characters starting at (x,y)
2115 #ifdef USE_TRANSPARENCY
2116 static errr Term_pict_mac(int x, int y, int n, const byte *ap, const char *cp,
2117 const byte *tap, const char *tcp)
2119 static errr Term_pict_mac(int x, int y, int n, const byte *ap, const char *cp)
2124 term_data *td = (term_data*)(Term->data);
2125 GDHandle saveGDevice;
2126 GWorldPtr saveGWorld;
2128 PixMapHandle PortPix;
2131 GetGWorld(&saveGWorld, &saveGDevice);
2133 r2.left = x * td->tile_wid + td->size_ow1;
2134 r2.right = r2.left + td->tile_wid;
2135 r2.top = y * td->tile_hgt + td->size_oh1;
2136 r2.bottom = r2.top + td->tile_hgt;
2140 /* Instantiate font */
2141 TextFont(td->font_id);
2142 TextSize(td->font_size);
2143 TextFace(td->font_face);
2145 /* Restore colors */
2146 BackColor(blackColor);
2147 ForeColor(whiteColor);
2151 /* Destination rectangle */
2152 /* r2.left = x * td->tile_wid + td->size_ow1;
2153 r2.top = y * td->tile_hgt + td->size_oh1;
2154 r2.bottom = r2.top + td->tile_hgt;*/
2158 /* Scan the input */
2159 for (i = 0; i < n; i++)
2166 /* Second byte of bigtile */
2167 if (use_bigtile && a == 255)
2170 r2.left += td->tile_wid;
2175 /* Prepare right of rectangle now */
2176 r2.right = r2.left + td->tile_wid;
2178 #ifdef ANGBAND_LITE_MAC
2182 #else /* ANGBAND_LITE_MAC */
2184 /* Graphics -- if Available and Needed */
2185 if (use_graphics && ((byte)a & 0x80) && ((byte)c & 0x80))
2187 #if TARGET_API_MAC_CARBON
2188 PixMapHandle srcBitMap = GetGWorldPixMap(frameP->framePort);
2189 PixMapHandle destBitMap;
2191 BitMapPtr srcBitMap = (BitMapPtr)(frameP->framePix);
2192 BitMapPtr destBitMap;
2198 #ifdef USE_TRANSPARENCY
2200 bool terrain_flag = FALSE;
2204 if ((a != ta || c != tc) &&
2205 ((byte)ta & 0x80) && ((byte)tc & 0x80))
2208 row = ((byte)ta & 0x7F);
2209 col = ((byte)tc & 0x7F);
2211 /* Terrain Source rectangle */
2212 terrain_r.left = col * grafWidth;
2213 terrain_r.top = row * grafHeight;
2214 terrain_r.right = terrain_r.left + grafWidth;
2215 terrain_r.bottom = terrain_r.top + grafHeight;
2217 terrain_flag = TRUE;
2222 row = ((byte)a & 0x7F);
2223 col = ((byte)c & 0x7F);
2225 /* Source rectangle */
2226 r1.left = col * grafWidth;
2227 r1.top = row * grafHeight;
2228 r1.right = r1.left + grafWidth;
2229 r1.bottom = r1.top + grafHeight;
2231 /* Hardwire CopyBits */
2232 BackColor(whiteColor);
2233 ForeColor(blackColor);
2235 /* Draw the picture */
2236 #if TARGET_API_MAC_CARBON
2237 destBitMap = GetPortPixMap(GetWindowPort( td->w ));
2239 destBitMap = (BitMapPtr)&(td->w->portBits);
2241 if (use_bigtile) r2.right += td->tile_wid;
2243 #ifdef USE_TRANSPARENCY
2247 * Source mode const = srcCopy:
2249 * determine how close the color of the source
2250 * pixel is to black, and assign this relative
2251 * amount of foreground color to the
2252 * destination pixel; determine how close the
2253 * color of the source pixel is to white, and
2254 * assign this relative amount of background
2255 * color to the destination pixel
2257 #if TARGET_API_MAC_CARBON
2258 CopyBits( (BitMap *) *srcBitMap, (BitMap *) *destBitMap, &terrain_r, &r2, srcCopy, NULL);
2260 CopyBits( srcBitMap, destBitMap, &terrain_r, &r2, srcCopy, NULL );
2263 * Draw transparent tile
2264 * BackColor is ignored and the destination is
2267 BackColor(blackColor);
2268 #if TARGET_API_MAC_CARBON
2269 CopyBits( (BitMap *) *srcBitMap, (BitMap *) *destBitMap, &r1, &r2, transparent, NULL);
2271 CopyBits( srcBitMap, destBitMap, &r1, &r2, transparent, NULL );
2275 #endif /* USE_TRANSPARENCY */
2277 #if TARGET_API_MAC_CARBON
2278 CopyBits( (BitMap *) *srcBitMap, (BitMap *) *destBitMap, &r1, &r2, srcCopy, NULL);
2280 CopyBits( srcBitMap, destBitMap, &r1, &r2, srcCopy, NULL );
2284 /* Restore colors */
2285 BackColor(blackColor);
2286 ForeColor(whiteColor);
2295 #endif /* ANGBAND_LITE_MAC */
2303 term_data_color(td, (a & 0x0F));
2305 /* Starting pixel */
2306 xp = r2.left + td->tile_o_x;
2307 yp = r2.top + td->tile_o_y;
2309 /* Move to the correct location */
2315 /* Double width rectangle */
2316 r2.right += td->tile_wid;
2321 /* Draw the character */
2326 r2.left += td->tile_wid;
2334 /* Draw the character */
2340 r2.left += td->tile_wid;
2349 * Create and initialize window number "i"
2351 static void term_data_link(int i)
2355 term_data *td = &data[i];
2360 /* Require mapped */
2361 if (!td->mapped) return;
2366 /* Initialize the term */
2367 term_init(td->t, td->cols, td->rows, td->keys);
2369 /* Use a "software" cursor */
2370 td->t->soft_cursor = TRUE;
2372 /* Erase with "white space" */
2373 td->t->attr_blank = TERM_WHITE;
2374 td->t->char_blank = ' ';
2376 /* Prepare the init/nuke hooks */
2377 td->t->init_hook = Term_init_mac;
2378 td->t->nuke_hook = Term_nuke_mac;
2380 /* Prepare the function hooks */
2381 td->t->user_hook = Term_user_mac;
2382 td->t->xtra_hook = Term_xtra_mac;
2383 td->t->wipe_hook = Term_wipe_mac;
2384 td->t->curs_hook = Term_curs_mac;
2385 td->t->bigcurs_hook = Term_bigcurs_mac;
2386 td->t->text_hook = Term_text_mac;
2387 td->t->pict_hook = Term_pict_mac;
2389 /* Link the local structure */
2390 td->t->data = (vptr)(td);
2393 Term_activate(td->t);
2395 /* Global pointer */
2396 angband_term[i] = td->t;
2406 * Set the "current working directory" (also known as the "default"
2407 * volume/directory) to the location of the current application.
2409 * Code by: Maarten Hazewinkel (mmhazewi@cs.ruu.nl)
2411 * This function does not appear to work correctly with System 6.
2413 static void SetupAppDir(void)
2417 char errString[100];
2419 /* Get the location of the Angband executable */
2420 fcbBlock.ioCompletion = NULL;
2421 fcbBlock.ioNamePtr = NULL;
2422 fcbBlock.ioVRefNum = 0;
2423 fcbBlock.ioRefNum = CurResFile();
2424 fcbBlock.ioFCBIndx = 0;
2425 err = PBGetFCBInfo(&fcbBlock, FALSE);
2429 sprintf(errString, "PBGetFCBInfo ¥¨¥é¡¼ #%d.\r ½ªÎ»¤·¤Þ¤¹.", err);
2431 sprintf(errString, "Fatal PBGetFCBInfo Error #%d.\r Exiting.", err);
2433 mac_warning(errString);
2437 /* Extract the Vol and Dir */
2438 app_vol = fcbBlock.ioFCBVRefNum;
2439 app_dir = fcbBlock.ioFCBParID;
2441 /* Set the current working directory to that location */
2442 err = HSetVol(NULL, app_vol, app_dir);
2446 sprintf(errString, "HSetVol ¥¨¥é¡¼ #%d.\r ½ªÎ»¤·¤Þ¤¹.", err);
2448 sprintf(errString, "Fatal HSetVol Error #%d.\r Exiting.", err);
2450 mac_warning(errString);
2457 #if TARGET_API_MAC_CARBON
2459 * Using Core Foundation's Preferences services -- pelpel
2461 * Requires OS 8.6 or greater with CarbonLib 1.1 or greater. Or OS X,
2464 * Without this, we can support older versions of OS 8 as well
2465 * (with CarbonLib 1.0.4).
2467 * Frequent allocation/deallocation of small chunks of data is
2468 * far from my liking, but since this is only called at the
2469 * beginning and the end of a session, I hope this hardly matters.
2474 * Store "value" as the value for preferences item name
2477 static void save_pref_short(const char *key, short value)
2480 CFNumberRef cf_value;
2482 /* allocate and initialise the key */
2483 cf_key = CFStringCreateWithCString(NULL, key, kTextEncodingUS_ASCII);
2485 /* allocate and initialise the value */
2486 cf_value = CFNumberCreate(NULL, kCFNumberShortType, &value);
2488 if ((cf_key != NULL) && (cf_value != NULL))
2490 /* Store the key-value pair in the applications preferences */
2491 CFPreferencesSetAppValue(
2494 kCFPreferencesCurrentApplication);
2498 * Free CF data - the reverse order is a vain attempt to
2499 * minimise memory fragmentation.
2501 if (cf_value) CFRelease(cf_value);
2502 if (cf_key) CFRelease(cf_key);
2507 * Load preference value for key, returns TRUE if it succeeds with
2508 * vptr updated appropriately, FALSE otherwise.
2510 static bool query_load_pref_short(const char *key, short *vptr)
2513 CFNumberRef cf_value;
2515 /* allocate and initialise the key */
2516 cf_key = CFStringCreateWithCString(NULL, key, kTextEncodingUS_ASCII);
2519 if (cf_key == NULL) return (FALSE);
2521 /* Retrieve value for the key */
2522 cf_value = CFPreferencesCopyAppValue(
2524 kCFPreferencesCurrentApplication);
2526 /* Value not found */
2527 if (cf_value == NULL)
2533 /* Convert the value to short */
2540 CFRelease(cf_value);
2549 * Update short data pointed by vptr only if preferences
2550 * value for key is located.
2552 static void load_pref_short(const char *key, short *vptr)
2556 if (query_load_pref_short(key, &tmp)) *vptr = tmp;
2562 * Save preferences to preferences file for current host+current user+
2563 * current application.
2565 static void cf_save_prefs()
2570 save_pref_short("version.major", FAKE_VERSION);
2571 save_pref_short("version.minor", FAKE_VER_MAJOR);
2572 save_pref_short("version.patch", FAKE_VER_MINOR);
2573 save_pref_short("version.extra", FAKE_VER_PATCH);
2576 save_pref_short("arg.arg_sound", arg_sound);
2577 save_pref_short("arg.arg_graphics", arg_graphics);
2578 save_pref_short("arg.arg_newstyle_graphics", arg_newstyle_graphics);
2579 save_pref_short("arg.arg_bigtile", arg_bigtile);
2582 for( i = 0 ; i < 7 ; i++ )
2583 save_pref_short(format("sound%d.on", i), soundmode[i]);
2586 for (i = 0; i < MAX_TERM_DATA; i++)
2588 term_data *td = &data[i];
2590 save_pref_short(format("term%d.mapped", i), td->mapped);
2592 save_pref_short(format("term%d.font_id", i), td->font_id);
2593 save_pref_short(format("term%d.font_size", i), td->font_size);
2594 save_pref_short(format("term%d.font_face", i), td->font_face);
2596 save_pref_short(format("term%d.tile_wid", i), td->tile_wid);
2597 save_pref_short(format("term%d.tile_hgt", i), td->tile_hgt);
2599 save_pref_short(format("term%d.cols", i), td->cols);
2600 save_pref_short(format("term%d.rows", i), td->rows);
2601 save_pref_short(format("term%d.left", i), td->r.left);
2602 save_pref_short(format("term%d.top", i), td->r.top);
2606 * Make sure preferences are persistent
2608 CFPreferencesAppSynchronize(
2609 kCFPreferencesCurrentApplication);
2614 * Load preferences from preferences file for current host+current user+
2615 * current application.
2617 static void cf_load_prefs()
2620 short pref_major, pref_minor, pref_patch, pref_extra;
2625 /* Assume nothing is wrong, yet */
2628 /* Load version information */
2629 ok &= query_load_pref_short("version.major", &pref_major);
2630 ok &= query_load_pref_short("version.minor", &pref_minor);
2631 ok &= query_load_pref_short("version.patch", &pref_patch);
2632 ok &= query_load_pref_short("version.extra", &pref_extra);
2634 /* Any of the above failed */
2637 /* This may be the first run */
2639 mac_warning("½é´üÀßÄê¥Õ¥¡¥¤¥ë¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó¡£");
2641 mac_warning("Preferences are not found.");
2644 /* Ignore the rest */
2651 if ((pref_major != PREF_VER_MAJOR) ||
2652 (pref_minor != PREF_VER_MINOR) ||
2653 (pref_patch != PREF_VER_PATCH) ||
2654 (pref_extra != PREF_VER_EXTRA))
2658 format("Ignoring %d.%d.%d.%d preferences.",
2659 pref_major, pref_minor, pref_patch, pref_extra));
2672 if (query_load_pref_short("arg.arg_sound", &pref_tmp))
2673 arg_sound = pref_tmp;
2676 if (query_load_pref_short("arg.arg_graphics", &pref_tmp))
2677 arg_graphics = pref_tmp;
2679 /*newstyle graphics*/
2680 if (query_load_pref_short("arg.arg_newstyle_graphics", &pref_tmp))
2682 use_newstyle_graphics = pref_tmp;
2685 if (use_newstyle_graphics == true)
2687 ANGBAND_GRAF = "new";
2688 arg_newstyle_graphics = true;
2689 grafWidth = grafHeight = 16;
2694 ANGBAND_GRAF = "old";
2695 arg_newstyle_graphics = false;
2696 grafWidth = grafHeight = 8;
2700 /* double-width tiles */
2701 if (query_load_pref_short("arg.arg_bigtile", &pref_tmp))
2703 use_bigtile = pref_tmp;
2709 for( i = 0 ; i < 7 ; i++ )
2711 query_load_pref_short(format("sound%d.on", i), &soundmode[i]);
2715 m = GetMenuHandle(134);
2717 /* Item "arg_sound" */
2718 CheckMenuItem(m, 1, arg_sound);
2720 /* Item "arg_graphics" */
2721 CheckMenuItem(m, 2, arg_graphics);
2723 /* Item "arg_newstyle_graphics"*/
2724 CheckMenuItem(m, 8, arg_newstyle_graphics);
2726 /* Item "arg_bigtile"*/
2727 CheckMenuItem(m, 9, arg_bigtile);
2730 for (i = 0; i < MAX_TERM_DATA; i++)
2732 term_data *td = &data[i];
2734 load_pref_short(format("term%d.mapped", i), &td->mapped);
2736 load_pref_short(format("term%d.font_id", i), &td->font_id);
2737 load_pref_short(format("term%d.font_size", i), &td->font_size);
2738 load_pref_short(format("term%d.font_face", i), &td->font_face);
2740 load_pref_short(format("term%d.tile_wid", i), &td->tile_wid);
2741 load_pref_short(format("term%d.tile_hgt", i), &td->tile_hgt);
2743 load_pref_short(format("term%d.cols", i), &td->cols);
2744 load_pref_short(format("term%d.rows", i), &td->rows);
2745 load_pref_short(format("term%d.left", i), &td->r.left);
2746 load_pref_short(format("term%d.top", i), &td->r.top);
2752 * Global "preference" file pointer
2757 * Read a "short" from the file
2759 static int getshort(void)
2763 if (0 == my_fgets(fff, buf, sizeof(buf))) x = atoi(buf);
2768 * Dump a "short" to the file
2770 static void putshort(int x)
2772 fprintf(fff, "%d\n", x);
2778 * Write the "preference" data to the current "file"
2780 static void save_prefs(void)
2787 /*** The current version ***/
2789 putshort(FAKE_VERSION);
2790 putshort(FAKE_VER_MAJOR);
2791 putshort(FAKE_VER_MINOR);
2792 putshort(FAKE_VER_PATCH);
2794 putshort(arg_sound);
2795 putshort(arg_graphics);
2796 putshort(arg_newstyle_graphics);
2797 putshort(arg_bigtile);
2800 for( i = 0 ; i < 7 ; i++ )
2801 putshort(soundmode[i]);
2804 for (i = 0; i < MAX_TERM_DATA; i++)
2809 putshort(td->mapped);
2811 putshort(td->font_id);
2812 putshort(td->font_size);
2813 putshort(td->font_face);
2815 putshort(td->tile_wid);
2816 putshort(td->tile_hgt);
2821 putshort(td->r.left);
2822 putshort(td->r.top);
2828 * Load the preferences from the current "file"
2830 * XXX XXX XXX Being able to undefine various windows is
2831 * slightly bizarre, and may cause problems.
2833 static void load_prefs(void)
2837 int old_version, old_major, old_minor, old_patch;
2842 /*** Version information ***/
2844 /* Preferences version */
2845 old_version = getshort();
2846 old_major = getshort();
2847 old_minor = getshort();
2848 old_patch = getshort();
2850 /* Hack -- Verify or ignore */
2851 if ((old_version != FAKE_VERSION) ||
2852 (old_major != FAKE_VER_MAJOR) ||
2853 (old_minor != FAKE_VER_MINOR) ||
2854 (old_patch != FAKE_VER_PATCH))
2858 mac_warning("¸Å¤¤½é´üÀßÄê¥Õ¥¡¥¤¥ë¤ò̵»ë¤·¤Þ¤¹.");
2860 mac_warning("Ignoring old preferences.");
2866 arg_sound = getshort();
2867 arg_graphics = getshort();
2868 arg_newstyle_graphics = getshort();
2869 use_newstyle_graphics = arg_newstyle_graphics;
2871 if (use_newstyle_graphics == true)
2873 ANGBAND_GRAF = "new";
2874 arg_newstyle_graphics = true;
2875 grafWidth = grafHeight = 16;
2880 ANGBAND_GRAF = "old";
2881 arg_newstyle_graphics = false;
2882 grafWidth = grafHeight = 8;
2886 arg_bigtile = getshort();
2887 use_bigtile = arg_bigtile;
2890 for( i = 0 ; i < 7 ; i++ )
2891 soundmode[i] = getshort();
2894 m = GetMenuHandle(134);
2896 /* Item "arg_sound" */
2897 CheckItem(m, 1, arg_sound);
2899 /* Item "arg_graphics" */
2900 CheckItem(m, 2, arg_graphics);
2902 /* Item "arg_newstyle_graphics"*/
2903 CheckItem(m, 8, arg_newstyle_graphics);
2905 /* Item "arg_bigtile"*/
2906 CheckItem(m, 9, arg_bigtile);
2909 for (i = 0; i < MAX_TERM_DATA; i++)
2914 td->mapped = getshort();
2916 td->font_id = getshort();
2917 td->font_size = getshort();
2918 td->font_face = getshort();
2920 td->tile_wid = getshort();
2921 td->tile_hgt = getshort();
2923 td->cols = getshort();
2924 td->rows = getshort();
2926 td->r.left = getshort();
2927 td->r.top = getshort();
2930 if (feof(fff)) break;
2933 #endif /* TARGET_API_MAC_CARBON */
2938 * Hack -- default data for a window
2940 static void term_data_hack(term_data *td)
2944 #if TARGET_API_MAC_CARBON
2946 /* Default to Osaka font (Japanese) */
2947 fid = FMGetFontFamilyFromName( "\pOsaka¡ÝÅùÉý" );
2949 /* Default to Monaco font */
2950 fid = FMGetFontFamilyFromName("\pmonaco");
2954 /* Default to ÅùÉýÌÀÄ« font (Japanese) */
2955 GetFNum( "\pÅùÉýÌÀÄ«", &fid);
2956 SetFScaleDisable( true );
2958 /* Default to Monaco font */
2959 GetFNum("\pmonaco", &fid);
2964 WIPE(td, term_data);
2969 /* Default borders */
2980 /* Default font size */
2983 /* Default font face */
2990 /* Default position */
3000 * Read the preference file, Create the windows.
3002 * We attempt to use "FindFolder()" to track down the preference file,
3003 * but if this fails, for any reason, we will try the "SysEnvirons()"
3004 * method, which may work better with System 6.
3006 static void init_windows(void)
3019 /*** Default values ***/
3021 /* Initialize (backwards) */
3022 for (i = MAX_TERM_DATA - 1; i >= 0; i--)
3035 s = angband_term_name[i];
3040 /* Maximal length */
3043 /* Copy the title */
3044 strncpy((char*)(td->title) + 1, s, n);
3046 /* Save the length */
3049 /* Tile the windows */
3050 td->r.left += (b * 30);
3051 td->r.top += (b * 30);
3058 /*** Load preferences ***/
3060 #if TARGET_API_MAC_CARBON
3063 /* Assume failure */
3066 /* Assume failure */
3079 /* Find the folder */
3080 err = FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder,
3086 /* Extract a path name */
3087 PathNameFromDirID(dirID, vref, (StringPtr)foo);
3089 /* Convert the string */
3090 ptocstr((StringPtr)foo);
3092 /* Append the preference file name */
3093 strcat(foo, PREF_FILE_NAME);
3095 /* Open the preference file */
3096 fff = fopen(foo, "r");
3103 #endif /* USE_SFL_CODE */
3109 HGetVol(0, &savev, &saved);
3111 /* Go to the "system" folder */
3112 SysEnvirons(curSysEnvVers, &env);
3113 SetVol(0, env.sysVRefNum);
3116 fff = fopen(PREF_FILE_NAME, "r");
3119 HSetVol(0, savev, saved);
3122 /* Load preferences */
3125 /* Load a real preference file */
3128 /* Close the file */
3131 #endif /* TARGET_API_MAC_CARBON */
3134 /*** Instantiate ***/
3145 /* Link (backwards, for stacking order) */
3146 for (i = MAX_TERM_DATA - 1; i >= 0; i--)
3155 Term_activate(td->t);
3158 static void init_sound( void )
3162 SignedByte permission = fsRdPerm;
3168 /* Descend into "lib" folder */
3169 pb.dirInfo.ioCompletion = NULL;
3170 pb.dirInfo.ioNamePtr = "\plib";
3171 pb.dirInfo.ioVRefNum = app_vol;
3172 pb.dirInfo.ioDrDirID = app_dir;
3173 pb.dirInfo.ioFDirIndex = 0;
3175 /* Check for errors */
3176 err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
3179 if ((err == noErr) && (pb.dirInfo.ioFlAttrib & 0x10))
3181 /* Descend into "lib/save" folder */
3182 pb.dirInfo.ioCompletion = NULL;
3183 pb.dirInfo.ioNamePtr = "\pxtra";
3184 pb.dirInfo.ioVRefNum = app_vol;
3185 pb.dirInfo.ioDrDirID = pb.dirInfo.ioDrDirID;
3186 pb.dirInfo.ioFDirIndex = 0;
3188 /* Check for errors */
3189 err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
3192 if ((err == noErr) && (pb.dirInfo.ioFlAttrib & 0x10))
3194 /* Descend into "lib/save" folder */
3195 pb.dirInfo.ioCompletion = NULL;
3196 pb.dirInfo.ioNamePtr = "\psound";
3197 pb.dirInfo.ioVRefNum = app_vol;
3198 pb.dirInfo.ioDrDirID = pb.dirInfo.ioDrDirID;
3199 pb.dirInfo.ioFDirIndex = 0;
3201 /* Check for errors */
3202 err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
3205 if ((err == noErr) && (pb.dirInfo.ioFlAttrib & 0x10))
3207 ret = HOpenResFile( app_vol , pb.dirInfo.ioDrDirID , "\psound.rsrc" , permission );
3211 for( i = 0 ; i < 7 ; i++ )
3212 soundmode[i] = false;
3214 for( i = 1 ; i < SOUND_MAX ; i++ ){
3215 /* Get the proper sound name */
3216 sprintf((char*)sound + 1, "%.16s.wav", angband_sound_name[i]);
3217 sound[0] = strlen((char*)sound + 1);
3219 /* Obtain resource XXX XXX XXX */
3220 handle = Get1NamedResource('snd ', sound);
3221 if( handle == NULL || ext_sound )
3222 handle = GetNamedResource('snd ', sound);
3225 soundmode[soundchoice[i]] = true;
3234 static void init_graf( void )
3238 SignedByte permission = fsRdPerm;
3244 /* Descend into "lib" folder */
3245 pb.dirInfo.ioCompletion = NULL;
3246 pb.dirInfo.ioNamePtr = "\plib";
3247 pb.dirInfo.ioVRefNum = app_vol;
3248 pb.dirInfo.ioDrDirID = app_dir;
3249 pb.dirInfo.ioFDirIndex = 0;
3251 /* Check for errors */
3252 err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
3255 if ((err == noErr) && (pb.dirInfo.ioFlAttrib & 0x10))
3257 /* Descend into "lib/xtra" folder */
3258 pb.dirInfo.ioCompletion = NULL;
3259 pb.dirInfo.ioNamePtr = "\pxtra";
3260 pb.dirInfo.ioVRefNum = app_vol;
3261 pb.dirInfo.ioDrDirID = pb.dirInfo.ioDrDirID;
3262 pb.dirInfo.ioFDirIndex = 0;
3264 /* Check for errors */
3265 err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
3268 if ((err == noErr) && (pb.dirInfo.ioFlAttrib & 0x10))
3270 /* Descend into "lib/xtra/graf" folder */
3271 pb.dirInfo.ioCompletion = NULL;
3272 pb.dirInfo.ioNamePtr = "\pgraf";
3273 pb.dirInfo.ioVRefNum = app_vol;
3274 pb.dirInfo.ioDrDirID = pb.dirInfo.ioDrDirID;
3275 pb.dirInfo.ioFDirIndex = 0;
3277 /* Check for errors */
3278 err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
3281 if ((err == noErr) && (pb.dirInfo.ioFlAttrib & 0x10))
3283 ret = HOpenResFile( app_vol , pb.dirInfo.ioDrDirID , "\pgraf.rsrc" , permission );
3288 /* Obtain resource XXX XXX XXX */
3289 handle = Get1NamedResource('PICT', graf);
3290 if ( handle == NULL || ext_graf )
3291 handle = GetNamedResource('PICT', "\pgraf.rsrc");
3302 static void init_chuukei( void )
3308 path_build(path, sizeof(path), ANGBAND_DIR_XTRA, "chuukei.txt");
3310 fp = fopen(path, "r");
3315 if (fgets(tmp, 1024, fp)){
3317 int n = strlen(tmp);
3323 chuukei_server = TRUE;
3324 if(connect_chuukei_server(&tmp[2])<0){
3325 msg_print("connect fail");
3328 msg_print("connect");
3335 chuukei_client = TRUE;
3336 connect_chuukei_server(&tmp[2]);
3352 short InevrtCheck( DialogPtr targetDlg, short check )
3359 GetDialogItem( targetDlg, check, &itemType, &checkH, &box );
3360 result = (GetControlValue( (ControlHandle)checkH ) + 1 ) % 2;
3361 SetControlValue( (ControlHandle)checkH , result );
3369 short SetCheck( DialogPtr targetDlg, short check, long result )
3376 GetDialogItem( targetDlg, check, &itemType, &checkH, &box );
3377 SetControlValue( (ControlHandle)checkH , result );
3385 short GetCheck( DialogPtr targetDlg, short check )
3392 GetDialogItem( targetDlg, check, &itemType, &checkH, &box );
3393 result = GetControlValue( (ControlHandle)checkH );
3397 void SoundConfigDLog(void)
3404 dialog=GetNewDialog(131, 0, (WindowPtr)-1);
3405 SetDialogDefaultItem( dialog, ok );
3406 SetDialogCancelItem( dialog, cancel );
3407 for( i = 1 ; i < 7 ; i++ )
3408 SetCheck( dialog, i+2 , soundmode[i] );
3410 /* ShowWindow(dialog); */
3411 for( item_hit = 100 ; cancel < item_hit ; ){
3412 ModalDialog(0, &item_hit);
3416 for( i = 1 ; i < 7 ; i++ )
3417 soundmode[i] = GetCheck( dialog, i+2 );
3422 InevrtCheck( dialog, item_hit );
3425 DisposeDialog(dialog);
3433 #if TARGET_API_MAC_CARBON
3434 static void save_pref_file(void)
3439 static void save_pref_file(void)
3448 /* Assume failure */
3451 /* Assume failure */
3468 /* Find the folder */
3469 err = FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder,
3475 /* Extract a path name */
3476 PathNameFromDirID(dirID, vref, (StringPtr)foo);
3478 /* Convert the string */
3479 ptocstr((StringPtr)foo);
3481 /* Append the preference file name */
3482 strcat(foo, PREF_FILE_NAME);
3484 /* Open the preference file */
3485 /* my_fopen set file type and file creator for MPW */
3486 fff = my_fopen(foo, "w");
3493 #endif /* USE_SFL_CODE */
3499 HGetVol(0, &savev, &saved);
3501 /* Go to "system" folder */
3502 SysEnvirons(curSysEnvVers, &env);
3503 SetVol(0, env.sysVRefNum);
3505 /* Open the preference file */
3506 /* my_fopen set file type and file creator for MPW */
3507 fff = fopen(PREF_FILE_NAME, "w");
3510 HSetVol(0, savev, saved);
3513 /* Save preferences */
3516 /* Write the preferences */
3528 * A simple "Yes/No" filter to parse "key press" events in dialog windows
3530 static pascal Boolean ynfilter(DialogPtr dialog, EventRecord *event, short *ip)
3532 /* Parse key press events */
3533 if (event->what == keyDown)
3538 /* Extract the pressed key */
3539 c = (event->message & charCodeMask);
3541 /* Accept "no" and <return> and <enter> */
3542 if ((c=='n') || (c=='N') || (c==13) || (c==3)) i = 1;
3545 else if ((c=='y') || (c=='Y')) i = 2;
3547 /* Handle "yes" or "no" */
3551 ControlHandle control;
3554 /* Get the button */
3555 GetDialogItem(dialog, i, &type, (Handle*)&control, &r);
3557 /* Blink button for 1/10 second */
3558 HiliteControl(control, 1);
3559 Term_xtra_mac(TERM_XTRA_DELAY, 100);
3560 HiliteControl(control, 0);
3573 #if TARGET_API_MAC_CARBON
3576 #ifdef MACH_O_CARBON
3578 /* Carbon File Manager utilities by pelpel */
3582 * Convert a pathname to a corresponding FSSpec.
3583 * Returns noErr on success.
3585 static OSErr path_to_spec(const char *path, FSSpec *spec)
3590 /* Convert pathname to FSRef ... */
3591 err = FSPathMakeRef(path, &ref, NULL);
3592 if (err != noErr) return (err);
3594 /* ... then FSRef to FSSpec */
3595 err = FSGetCatalogInfo(&ref, kFSCatInfoNone, NULL, NULL, spec, NULL);
3597 /* Inform caller of success or failure */
3604 * Convert a FSSpec to a corresponding pathname.
3605 * Returns noErr on success.
3607 static OSErr spec_to_path(const FSSpec *spec, char *buf, size_t size)
3612 /* Convert FSSpec to FSRef ... */
3613 err = FSpMakeFSRef(spec, &ref);
3614 if (err != noErr) return (err);
3616 /* ... then FSRef to pathname */
3617 err = FSRefMakePath(&ref, buf, size);
3619 /* Inform caller of success or failure */
3624 #endif /* MACH_O_CARBON */
3628 * Prepare savefile dialogue and set the variable
3629 * savefile accordingly. Returns true if it succeeds, false (or
3630 * aborts) otherwise. If all is false, only allow files whose type
3632 * Originally written by Peter Ammon
3634 static bool select_savefile(bool all)
3637 FSSpec theFolderSpec;
3638 FSSpec savedGameSpec;
3639 NavDialogOptions dialogOptions;
3640 NavReplyRecord reply;
3641 /* Used only when 'all' is true */
3642 NavTypeList types = {ANGBAND_CREATOR, 1, 1, {'SAVE'}};
3643 NavTypeListHandle myTypeList;
3644 AEDesc defaultLocation;
3646 #ifdef MACH_O_CARBON
3648 /* Find the save folder */
3649 err = path_to_spec(ANGBAND_DIR_SAVE, &theFolderSpec);
3653 /* Find :lib:save: folder */
3654 err = FSMakeFSSpec(app_vol, app_dir, "\p:lib:save:", &theFolderSpec);
3659 if (err != noErr) quit("Unable to find the folder :lib:save:");
3661 /* Get default Navigator dialog options */
3662 err = NavGetDefaultDialogOptions(&dialogOptions);
3664 /* Clear preview option */
3665 dialogOptions.dialogOptionFlags &= ~kNavAllowPreviews;
3667 /* Disable multiple file selection */
3668 dialogOptions.dialogOptionFlags &= ~kNavAllowMultipleFiles;
3670 /* Make descriptor for default location */
3671 err = AECreateDesc(typeFSS, &theFolderSpec, sizeof(FSSpec),
3675 if (err != noErr) quit("Unable to allocate descriptor");
3677 /* We are indifferent to signature and file types */
3680 myTypeList = (NavTypeListHandle)nil;
3683 /* Set up type handle */
3686 err = PtrToHand(&types, (Handle *)&myTypeList, sizeof(NavTypeList));
3689 if (err != noErr) quit("Error in PtrToHand. Try enlarging heap");
3693 /* Call NavGetFile() with the types list */
3694 err = NavChooseFile(&defaultLocation, &reply, &dialogOptions, NULL,
3695 NULL, NULL, myTypeList, NULL);
3697 /* Free type list */
3698 if (!all) DisposeHandle((Handle)myTypeList);
3706 /* Invalid response -- allow the user to cancel */
3707 else if (!reply.validRecord)
3709 /* Hack -- Fake error */
3713 /* Retrieve FSSpec from the reply */
3716 AEKeyword theKeyword;
3717 DescType actualType;
3720 /* Get a pointer to selected file */
3721 (void)AEGetNthPtr(&reply.selection, 1, typeFSS, &theKeyword,
3722 &actualType, &savedGameSpec, sizeof(FSSpec), &actualSize);
3724 /* Dispose NavReplyRecord, resources and descriptors */
3725 (void)NavDisposeReply(&reply);
3728 /* Dispose location info */
3729 AEDisposeDesc(&defaultLocation);
3732 if (err != noErr) return (FALSE);
3734 #ifdef MACH_O_CARBON
3736 /* Convert FSSpec to pathname and store it in variable savefile */
3737 (void)spec_to_path(&savedGameSpec, savefile, sizeof(savefile));
3741 /* Convert FSSpec to pathname and store it in variable savefile */
3744 savedGameSpec.parID,
3745 savedGameSpec.vRefNum,
3746 (char *)savedGameSpec.name);
3757 * Handle menu: "File" + "New"
3759 static void do_menu_file_new(void)
3764 /* Game is in progress */
3765 game_in_progress = 1;
3779 * Handle menu: "File" + "Open"
3781 #if TARGET_API_MAC_CARBON
3782 static void do_menu_file_open(bool all)
3784 /* Let the player to choose savefile */
3785 if (!select_savefile(all)) return;
3790 /* Game is in progress */
3791 game_in_progress = TRUE;
3803 static void do_menu_file_open(bool all)
3817 /* vrefnum = GetSFCurVol(); */
3818 vrefnum = -*((short*)0x214);
3820 /* drefnum = GetSFCurDir(); */
3821 drefnum = *((long*)0x398);
3823 /* Descend into "lib" folder */
3824 pb.ioCompletion = NULL;
3825 pb.ioNamePtr = "\plib";
3826 pb.ioVRefNum = vrefnum;
3827 pb.ioDrDirID = drefnum;
3830 /* Check for errors */
3831 err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
3834 if ((err == noErr) && (pb.ioFlAttrib & 0x10))
3836 /* Descend into "lib/save" folder */
3837 pb.ioCompletion = NULL;
3838 pb.ioNamePtr = "\psave";
3839 pb.ioVRefNum = vrefnum;
3840 pb.ioDrDirID = pb.ioDrDirID;
3843 /* Check for errors */
3844 err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
3847 if ((err == noErr) && (pb.ioFlAttrib & 0x10))
3849 /* SetSFCurDir(pb.ioDrDirID); */
3850 *((long*)0x398) = pb.ioDrDirID;
3854 /* Window location */
3855 topleft.h = (qd.screenBits.bounds.left+qd.screenBits.bounds.right)/2-344/2;
3856 topleft.v = (2*qd.screenBits.bounds.top+qd.screenBits.bounds.bottom)/3-188/2;
3858 /* Allow "all" files */
3862 SFGetFile(topleft, "\p", NULL, -1, types, NULL, &reply);
3865 /* Allow "save" files */
3872 SFGetFile(topleft, "\p", NULL, 1, types, NULL, &reply);
3876 if (!reply.good) return;
3878 /* Extract textual file name for save file */
3879 GetWDInfo(reply.vRefNum, &vrefnum, &drefnum, &junk);
3880 refnum_to_name(savefile, drefnum, vrefnum, (char*)reply.fName);
3885 /* Game is in progress */
3886 game_in_progress = 1;
3901 * Handle the "open_when_ready" flag
3903 static void handle_open_when_ready(void)
3905 /* Check the flag XXX XXX XXX make a function for this */
3906 if (open_when_ready && initialized && !game_in_progress)
3909 open_when_ready = FALSE;
3911 /* Game is in progress */
3912 game_in_progress = 1;
3931 * Initialize the menus
3933 * Verify menus 128, 129, 130
3934 * Create menus 131, 132, 133, 134
3936 * The standard menus are:
3938 * Apple (128) = { About, -, ... }
3939 * File (129) = { New,Open,Import,Close,Save,-,Exit,Quit }
3940 * Edit (130) = { Cut, Copy, Paste, Clear } (?)
3941 * Font (131) = { Bold, Extend, -, Monaco, ..., -, ... }
3942 * Size (132) = { ... }
3943 * Window (133) = { Angband, Mirror, Recall, Choice,
3944 * Term-4, Term-5, Term-6, Term-7 }
3945 * Special (134) = { arg_sound, arg_graphics, -,
3946 * arg_fiddle, arg_wizard }
3948 static void init_menubar(void)
3960 /* Get the "apple" menu */
3963 /* Insert the menu */
3966 /* Add the DA's to the "apple" menu */
3967 #if TARGET_API_MAC_CARBON
3969 AppendResMenu (m, 'DRVR');
3972 /* Get the "File" menu */
3973 #if TARGET_API_MAC_CARBON
3975 err = Gestalt( gestaltSystemVersion, &response );
3976 if ( (err == noErr) && (response >= 0x00000A00) )
3978 DeleteMenuItem( m, 7 );
3984 /* Insert the menu */
3988 /* Get the "Edit" menu */
3991 /* Insert the menu */
3995 /* Make the "Font" menu */
3997 m = NewMenu(131, "\p¥Õ¥©¥ó¥È");
3999 m = NewMenu(131, "\pFont");
4002 /* Insert the menu */
4006 AppendMenu(m, "\pBold");
4009 AppendMenu(m, "\pWide");
4011 /* Add a separator */
4012 AppendMenu(m, "\p-");
4015 r.left = r.right = r.top = r.bottom = 0;
4017 /* Make the fake window */
4018 tmpw = NewWindow(0, &r, "\p", false, documentProc, 0, 0, 0);
4020 /* Activate the "fake" window */
4021 #if TARGET_API_MAC_CARBON
4022 SetPortWindowPort(tmpw);
4033 /* Add the fonts to the menu */
4034 AppendResMenu(m, 'FONT');
4037 #if TARGET_API_MAC_CARBON
4038 n = CountMenuItems(m);
4044 for (i = n; i >= 4; i--)
4049 /* Acquire the font name */
4050 GetMenuItemText(m, i, tmpName);
4052 /* Acquire the font index */
4053 #if TARGET_API_MAC_CARBON
4054 fontNum = FMGetFontFamilyFromName( tmpName );
4056 GetFNum(tmpName, &fontNum);
4059 /* Apply the font index */
4062 /* Remove non-mono-spaced fonts */
4063 if ((CharWidth('i') != CharWidth('W')) || (CharWidth('W') == 0))
4065 /* Delete the menu item XXX XXX XXX */
4066 DeleteMenuItem (m, i);
4070 /* Destroy the old window */
4071 DisposeWindow(tmpw);
4073 /* Add a separator */
4074 AppendMenu(m, "\p-");
4076 /* Add the fonts to the menu */
4077 AppendResMenu (m, 'FONT');
4080 /* Make the "Size" menu */
4082 m = NewMenu(132, "\p¥µ¥¤¥º");
4084 m = NewMenu(132, "\pSize");
4087 /* Insert the menu */
4090 /* Add some sizes (stagger choices) */
4091 for (i = 8; i <= 32; i += ((i / 16) + 1))
4096 sprintf((char*)buf + 1, "%d", i);
4097 buf[0] = strlen((char*)buf + 1);
4104 /* Make the "Windows" menu */
4106 m = NewMenu(133, "\p¥¦¥¤¥ó¥É¥¦");
4108 m = NewMenu(133, "\pWindows");
4111 /* Insert the menu */
4114 /* Default choices */
4115 for (i = 0; i < MAX_TERM_DATA; i++)
4119 /* Describe the item */
4120 sprintf((char*)buf + 1, "%.15s", angband_term_name[i]);
4121 buf[0] = strlen((char*)buf + 1);
4126 /* Command-Key shortcuts */
4127 if (i < 8) SetItemCmd(m, i + 1, '0' + i);
4131 /* Make the "Special" menu */
4133 m = NewMenu(134, "\pÆÃÊÌ");
4135 m = NewMenu(134, "\pSpecial");
4138 /* Insert the menu */
4141 /* Append the choices */
4143 AppendMenu(m, "\p¥µ¥¦¥ó¥É»ÈÍÑ");
4144 AppendMenu(m, "\p¥°¥é¥Õ¥£¥Ã¥¯»ÈÍÑ");
4145 AppendMenu(m, "\p-");
4146 AppendMenu(m, "\parg_fiddle");
4147 AppendMenu(m, "\parg_wizard");
4148 AppendMenu(m, "\p-");
4149 AppendMenu(m, "\p¥µ¥¦¥ó¥ÉÀßÄê...");
4150 AppendMenu(m, "\p16X16¥°¥é¥Õ¥£¥Ã¥¯");
4151 AppendMenu(m, "\p£²ÇÜÉý¥¿¥¤¥ëɽ¼¨");
4153 AppendMenu(m, "\parg_sound");
4154 AppendMenu(m, "\parg_graphics");
4155 AppendMenu(m, "\p-");
4156 AppendMenu(m, "\parg_fiddle");
4157 AppendMenu(m, "\parg_wizard");
4158 AppendMenu(m, "\p-");
4159 AppendMenu(m, "\pSound config");
4160 AppendMenu(m, "\pAdam Bolt tile");
4161 AppendMenu(m, "\pBigtile Mode");
4164 /* Make the "TileWidth" menu */
4166 m = NewMenu(135, "\p¥¿¥¤¥ëÉý");
4168 m = NewMenu(135, "\pTileWidth");
4171 /* Insert the menu */
4174 /* Add some sizes */
4175 for (i = 4; i <= 32; i++)
4180 sprintf((char*)buf + 1, "%d", i);
4181 buf[0] = strlen((char*)buf + 1);
4188 /* Make the "TileHeight" menu */
4190 m = NewMenu(136, "\p¥¿¥¤¥ë¹â");
4192 m = NewMenu(136, "\pTileHeight");
4195 /* Insert the menu */
4198 /* Add some sizes */
4199 for (i = 4; i <= 32; i++)
4204 sprintf((char*)buf + 1, "%d", i);
4205 buf[0] = strlen((char*)buf + 1);
4212 /* Update the menu bar */
4220 static void setup_menus(void)
4230 term_data *td = NULL;
4233 /* Relevant "term_data" */
4234 for (i = 0; i < MAX_TERM_DATA; i++)
4237 if (!data[i].t) continue;
4239 /* Notice the matching window */
4240 if (data[i].w == FrontWindow()) td = &data[i];
4245 m = GetMenuHandle(129);
4248 #if TARGET_API_MAC_CARBON
4249 n = CountMenuItems(m);
4255 for (i = 1; i <= n; i++)
4258 #if TARGET_API_MAC_CARBON
4259 DisableMenuItem(m, i);
4260 CheckMenuItem(m, i, FALSE);
4263 CheckItem(m, i, FALSE);
4267 /* Enable "new"/"open..."/"import..." */
4268 if (initialized && !game_in_progress)
4270 #if TARGET_API_MAC_CARBON
4271 EnableMenuItem(m, 1);
4272 EnableMenuItem(m, 2);
4273 EnableMenuItem(m, 3);
4281 /* Enable "close" */
4284 #if TARGET_API_MAC_CARBON
4285 EnableMenuItem(m, 4);
4292 if (initialized && character_generated)
4294 #if TARGET_API_MAC_CARBON
4295 EnableMenuItem(m, 5);
4304 #if TARGET_API_MAC_CARBON
4305 EnableMenuItem(m, 7);
4313 m = GetMenuHandle(130);
4316 #if TARGET_API_MAC_CARBON
4317 n = CountMenuItems(m);
4323 for (i = 1; i <= n; i++)
4326 #if TARGET_API_MAC_CARBON
4327 DisableMenuItem(m, i);
4328 CheckMenuItem(m, i, FALSE);
4331 CheckItem(m, i, FALSE);
4335 /* Enable "edit" options if "needed" */
4338 #if TARGET_API_MAC_CARBON
4339 EnableMenuItem(m, 1);
4340 EnableMenuItem(m, 3);
4341 EnableMenuItem(m, 4);
4342 EnableMenuItem(m, 5);
4343 EnableMenuItem(m, 6);
4355 m = GetMenuHandle(131);
4358 #if TARGET_API_MAC_CARBON
4359 n = CountMenuItems(m);
4365 for (i = 1; i <= n; i++)
4368 #if TARGET_API_MAC_CARBON
4369 DisableMenuItem(m, i);
4370 CheckMenuItem(m, i, FALSE);
4373 CheckItem(m, i, FALSE);
4377 /* Hack -- look cute XXX XXX */
4378 /* SetItemStyle(m, 1, bold); */
4380 /* Hack -- look cute XXX XXX */
4381 /* SetItemStyle(m, 2, extend); */
4386 #if TARGET_API_MAC_CARBON
4388 EnableMenuItem(m, 1);
4390 /* Enable "extend" */
4391 EnableMenuItem(m, 2);
4393 /* Check the appropriate "bold-ness" */
4394 if (td->font_face & bold) CheckMenuItem(m, 1, TRUE);
4396 /* Check the appropriate "wide-ness" */
4397 if (td->font_face & extend) CheckMenuItem(m, 2, TRUE);
4400 for (i = 4; i <= n; i++)
4403 EnableMenuItem(m, i);
4406 GetMenuItemText(m, i, s);
4409 /* Check active font */
4410 if (td->font_id == value) CheckMenuItem(m, i, TRUE);
4416 /* Enable "extend" */
4419 /* Check the appropriate "bold-ness" */
4420 if (td->font_face & bold) CheckItem(m, 1, TRUE);
4422 /* Check the appropriate "wide-ness" */
4423 if (td->font_face & extend) CheckItem(m, 2, TRUE);
4426 for (i = 4; i <= n; i++)
4432 GetMenuItemText(m, i, s);
4435 /* Check active font */
4436 if (td->font_id == value) CheckItem(m, i, TRUE);
4443 m = GetMenuHandle(132);
4446 #if TARGET_API_MAC_CARBON
4447 n = CountMenuItems(m);
4453 for (i = 1; i <= n; i++)
4456 #if TARGET_API_MAC_CARBON
4457 DisableMenuItem(m, i);
4458 CheckMenuItem(m, i, FALSE);
4461 CheckItem(m, i, FALSE);
4469 for (i = 1; i <= n; i++)
4471 #if TARGET_API_MAC_CARBON
4473 GetMenuItemText(m, i, s);
4475 value = atoi((char*)(s+1));
4477 /* Enable the "real" sizes */
4478 if (RealFont(td->font_id, value)) EnableMenuItem(m, i);
4480 /* Check the current size */
4481 if (td->font_size == value) CheckMenuItem(m, i, TRUE);
4484 GetMenuItemText(m, i, s);
4486 value = atoi((char*)(s+1));
4488 /* Enable the "real" sizes */
4489 if (RealFont(td->font_id, value)) EnableItem(m, i);
4491 /* Check the current size */
4492 if (td->font_size == value) CheckItem(m, i, TRUE);
4499 m = GetMenuHandle(133);
4502 #if TARGET_API_MAC_CARBON
4503 n = CountMenuItems(m);
4508 /* Check active windows */
4509 for (i = 1; i <= n; i++)
4511 /* Check if needed */
4512 #if TARGET_API_MAC_CARBON
4513 CheckMenuItem(m, i, data[i-1].mapped);
4515 CheckItem(m, i, data[i-1].mapped);
4521 m = GetMenuHandle(134);
4524 #if TARGET_API_MAC_CARBON
4525 n = CountMenuItems(m);
4531 for (i = 1; i <= n; i++)
4534 #if TARGET_API_MAC_CARBON
4535 DisableMenuItem(m, i);
4536 CheckMenuItem(m, i, FALSE);
4539 CheckItem(m, i, FALSE);
4543 #if TARGET_API_MAC_CARBON
4544 /* Item "arg_sound" */
4545 EnableMenuItem(m, 1);
4546 CheckMenuItem(m, 1, arg_sound);
4548 /* Item "arg_graphics" */
4549 EnableMenuItem(m, 2);
4550 CheckMenuItem(m, 2, arg_graphics);
4552 /* Item "arg_fiddle" */
4553 EnableMenuItem(m, 4);
4554 CheckMenuItem(m, 4, arg_fiddle);
4556 /* Item "arg_wizard" */
4557 EnableMenuItem(m, 5);
4558 CheckMenuItem(m, 5, arg_wizard);
4560 /* Item "SoundSetting" */
4561 EnableMenuItem(m, 7);
4563 /* Item NewStyle Graphics */
4564 EnableMenuItem(m, 8);
4565 CheckMenuItem(m, 8, use_newstyle_graphics);
4567 /* Item Bigtile Mode */
4568 EnableMenuItem(m, 9);
4569 CheckMenuItem(m, 9, arg_bigtile);
4571 /* Item "arg_sound" */
4573 CheckItem(m, 1, arg_sound);
4575 /* Item "arg_graphics" */
4577 CheckItem(m, 2, arg_graphics);
4579 /* Item "arg_fiddle" */
4581 CheckItem(m, 4, arg_fiddle);
4583 /* Item "arg_wizard" */
4585 CheckItem(m, 5, arg_wizard);
4587 /* Item "SoundSetting" */
4590 /* Item NewStyle Graphics */
4592 CheckItem(m, 8, use_newstyle_graphics);
4594 /* Item Bigtile Mode */
4596 CheckItem(m, 9, arg_bigtile);
4599 /* TileWidth menu */
4600 m = GetMenuHandle(135);
4603 #if TARGET_API_MAC_CARBON
4604 n = CountMenuItems(m);
4610 for (i = 1; i <= n; i++)
4613 #if TARGET_API_MAC_CARBON
4614 DisableMenuItem(m, i);
4615 CheckMenuItem(m, i, FALSE);
4618 CheckItem(m, i, FALSE);
4626 for (i = 1; i <= n; i++)
4629 /* GetMenuItemText(m,i,s); */
4630 GetMenuItemText(m, i, s);
4632 value = atoi((char*)(s+1));
4634 #if TARGET_API_MAC_CARBON
4636 EnableMenuItem(m, i);
4638 /* Check the current size */
4639 if (td->tile_wid == value) CheckMenuItem(m, i, TRUE);
4644 /* Check the current size */
4645 if (td->tile_wid == value) CheckItem(m, i, TRUE);
4651 /* TileHeight menu */
4652 m = GetMenuHandle(136);
4655 #if TARGET_API_MAC_CARBON
4656 n = CountMenuItems(m);
4662 for (i = 1; i <= n; i++)
4665 #if TARGET_API_MAC_CARBON
4666 DisableMenuItem(m, i);
4667 CheckMenuItem(m, i, FALSE);
4670 CheckItem(m, i, FALSE);
4678 for (i = 1; i <= n; i++)
4681 GetMenuItemText(m, i, s);
4683 value = atoi((char*)(s+1));
4685 #if TARGET_API_MAC_CARBON
4687 EnableMenuItem(m, i);
4689 /* Check the current size */
4690 if (td->tile_hgt == value) CheckMenuItem(m, i, TRUE);
4695 /* Check the current size */
4696 if (td->tile_hgt == value) CheckItem(m, i, TRUE);
4704 * Process a menu selection (see above)
4706 * Hack -- assume that invalid menu selections are disabled above,
4707 * which I have been informed may not be reliable. XXX XXX XXX
4709 static void menu(long mc)
4713 int menuid, selection;
4715 static unsigned char s[1000];
4719 term_data *td = NULL;
4724 /* Analyze the menu command */
4725 menuid = HiWord(mc);
4726 selection = LoWord(mc);
4729 /* Find the window */
4730 for (i = 0; i < MAX_TERM_DATA; i++)
4732 /* Skip dead windows */
4733 if (!data[i].t) continue;
4735 /* Notice matches */
4736 if (data[i].w == FrontWindow()) td = &data[i];
4740 /* Branch on the menu */
4746 /* About Angband... */
4747 #if TARGET_API_MAC_CARBON
4753 /* Get the about dialogue */
4754 dialog=GetNewDialog(128, 0, (WindowPtr)-1);
4756 /* Move it to the middle of the screen */
4758 GetDialogWindow(dialog),
4760 kWindowCenterOnMainScreen);
4762 /* Show the dialog */
4763 TransitionWindow(GetDialogWindow(dialog),
4764 kWindowZoomTransitionEffect,
4765 kWindowShowTransitionAction,
4768 /* Wait for user to click on it */
4769 ModalDialog(0, &item_hit);
4771 /* Free the dialogue */
4772 DisposeDialog(dialog);
4782 dialog=GetNewDialog(128, 0, (WindowPtr)-1);
4785 center_rect(&r, &qd.screenBits.bounds);
4786 MoveWindow(dialog, r.left, r.top, 1);
4788 ModalDialog(0, &item_hit);
4789 DisposeDialog(dialog);
4793 /* Desk accessory */
4794 /* GetMenuItemText(GetMHandle(128),selection,s); */
4795 GetMenuItemText(GetMenuHandle(128), selection, s);
4816 do_menu_file_open(FALSE);
4823 do_menu_file_open(TRUE);
4837 td->t->mapped_flag = FALSE;
4839 /* Hide the window */
4850 plog("º£¤Ï¥»¡¼¥Ö¤¹¤ë¤³¤È¤Ï½ÐÍè¤Þ¤»¤ó¡£");
4852 plog("You may not do that right now.");
4857 /* Hack -- Forget messages */
4860 /* Hack -- Save the game */
4861 do_cmd_save_game(FALSE);
4866 /* Quit (with save) */
4869 /* Save the game (if necessary) */
4870 if (game_in_progress && character_generated)
4874 plog("º£¤Ï¥»¡¼¥Ö¤¹¤ë¤³¤È¤Ï½ÐÍè¤Þ¤»¤ó¡£");
4876 plog("You may not do that right now.");
4880 /* Hack -- Forget messages */
4885 do_cmd_save_game(FALSE);
4887 Term_key_push(SPECIAL_KEY_QUIT);
4909 /* Require a window */
4918 /* Toggle the "bold" setting */
4921 /* Toggle the setting */
4922 if (td->font_face & bold)
4924 td->font_face &= ~bold;
4928 td->font_face |= bold;
4931 /* Tile Width Hight Init */
4932 td->tile_wid = td->tile_hgt = 0;
4934 /* Apply and Verify */
4935 term_data_check_font(td);
4936 term_data_check_size(td);
4938 /* Resize and Redraw */
4939 term_data_resize(td);
4940 term_data_redraw(td);
4945 /* Toggle the "wide" setting */
4948 /* Toggle the setting */
4949 if (td->font_face & extend)
4951 td->font_face &= ~extend;
4955 td->font_face |= extend;
4958 /* Tile Width Hight Init */
4959 td->tile_wid = td->tile_hgt = 0;
4961 /* Apply and Verify */
4962 term_data_check_font(td);
4963 term_data_check_size(td);
4965 /* Resize and Redraw */
4966 term_data_resize(td);
4967 term_data_redraw(td);
4972 /* Get a new font name */
4973 GetMenuItemText(GetMenuHandle(131), selection, s);
4976 /* Save the new font id */
4979 /* Current size is bad for new font */
4980 if (!RealFont(td->font_id, td->font_size))
4982 /* Find similar size */
4983 for (i = 1; i <= 32; i++)
4985 /* Adjust smaller */
4986 if (td->font_size - i >= 8)
4988 if (RealFont(td->font_id, td->font_size - i))
4996 if (td->font_size + i <= 128)
4998 if (RealFont(td->font_id, td->font_size + i))
5007 /* Tile Width Hight Init */
5008 td->tile_wid = td->tile_hgt = 0;
5010 /* Apply and Verify */
5011 term_data_check_font(td);
5012 term_data_check_size(td);
5014 /* Resize and Redraw */
5015 term_data_resize(td);
5016 term_data_redraw(td);
5018 /* Restore the window */
5035 GetMenuItemText(GetMenuHandle(132), selection, s);
5037 td->font_size = atoi((char*)(s+1));
5039 /* Tile Width Hight Init */
5040 td->tile_wid = td->tile_hgt = 0;
5042 /* Apply and Verify */
5043 term_data_check_font(td);
5044 term_data_check_size(td);
5046 /* Resize and Redraw */
5047 term_data_resize(td);
5048 term_data_redraw(td);
5062 /* Check legality of choice */
5063 if ((i < 0) || (i >= MAX_TERM_DATA)) break;
5065 /* Obtain the window */
5075 td->t->mapped_flag = TRUE;
5077 /* Show the window */
5080 /* Bring to the front */
5081 SelectWindow(td->w);
5093 /* Toggle arg_sound */
5094 arg_sound = !arg_sound;
5096 /* React to changes */
5097 Term_xtra(TERM_XTRA_REACT, 0);
5104 /* Toggle arg_graphics */
5105 arg_graphics = !arg_graphics;
5106 if( arg_graphics == true ){
5107 ANGBAND_GRAF = "old";
5108 arg_newstyle_graphics = false;
5109 grafWidth = grafHeight = 8;
5113 /* Hack -- Force redraw */
5114 Term_key_push(KTRL('R'));
5121 arg_fiddle = !arg_fiddle;
5127 arg_wizard = !arg_wizard;
5138 if (streq(ANGBAND_GRAF, "old"))
5140 ANGBAND_GRAF = "new";
5141 arg_newstyle_graphics = true;
5142 grafWidth = grafHeight = 16;
5147 ANGBAND_GRAF = "old";
5148 arg_newstyle_graphics = false;
5149 grafWidth = grafHeight = 8;
5153 /* Hack -- Force redraw */
5154 Term_key_push(KTRL('R'));
5158 case 9: /* bigtile mode */
5160 term_data *td = &data[0];
5164 plog("º£¤ÏÊѹ¹½ÐÍè¤Þ¤»¤ó¡£");
5166 plog("You may not do that right now.");
5171 /* Toggle "arg_bigtile" */
5172 arg_bigtile = !arg_bigtile;
5175 Term_activate(td->t);
5177 /* Resize the term */
5178 Term_resize(td->cols, td->rows);
5188 /* TileWidth menu */
5199 GetMenuItemText(GetMenuHandle(135), selection, s);
5201 td->tile_wid = atoi((char*)(s+1));
5203 /* Apply and Verify */
5204 term_data_check_size(td);
5206 /* Resize and Redraw */
5207 term_data_resize(td);
5208 term_data_redraw(td);
5216 /* TileHeight menu */
5227 GetMenuItemText(GetMenuHandle(136), selection, s);
5229 td->tile_hgt = atoi((char*)(s+1));
5231 /* Apply and Verify */
5232 term_data_check_size(td);
5234 /* Resize and Redraw */
5235 term_data_resize(td);
5236 term_data_redraw(td);
5246 /* Clean the menu */
5255 * Check for extra required parameters -- From "Maarten Hazewinkel"
5257 static OSErr CheckRequiredAEParams(const AppleEvent *theAppleEvent)
5260 DescType returnedType;
5263 aeError = AEGetAttributePtr(theAppleEvent, keyMissedKeywordAttr, typeWildCard,
5264 &returnedType, NULL, 0, &actualSize);
5266 if (aeError == errAEDescNotFound) return (noErr);
5268 if (aeError == noErr) return (errAEParamMissed);
5275 * Apple Event Handler -- Open Application
5277 static pascal OSErr AEH_Start(const AppleEvent *theAppleEvent,
5278 AppleEvent *reply, long handlerRefCon)
5280 #pragma unused(reply, handlerRefCon)
5282 return (CheckRequiredAEParams(theAppleEvent));
5287 * Apple Event Handler -- Quit Application
5289 static pascal OSErr AEH_Quit(const AppleEvent *theAppleEvent,
5290 AppleEvent *reply, long handlerRefCon)
5292 #pragma unused(reply, handlerRefCon)
5293 #if TARGET_API_MAC_CARBON
5295 /* Save the game (if necessary) */
5296 if (game_in_progress && character_generated)
5300 plog("º£¤Ï¥»¡¼¥Ö¤¹¤ë¤³¤È¤Ï½ÐÍè¤Þ¤»¤ó¡£");
5302 plog("You may not do that right now.");
5306 /* Hack -- Forget messages */
5311 do_cmd_save_game(FALSE);
5313 Term_key_push(SPECIAL_KEY_QUIT);
5321 quit_when_ready = TRUE;
5323 /* Check arguments */
5324 return (CheckRequiredAEParams(theAppleEvent));
5330 * Apple Event Handler -- Print Documents
5332 static pascal OSErr AEH_Print(const AppleEvent *theAppleEvent,
5333 AppleEvent *reply, long handlerRefCon)
5335 #pragma unused(theAppleEvent, reply, handlerRefCon)
5337 return (errAEEventNotHandled);
5342 * Apple Event Handler by Steve Linberg (slinberg@crocker.com).
5344 * The old method of opening savefiles from the finder does not work
5345 * on the Power Macintosh, because CountAppFiles and GetAppFiles,
5346 * used to return information about the selected document files when
5347 * an application is launched, are part of the Segment Loader, which
5348 * is not present in the RISC OS due to the new memory architecture.
5350 * The "correct" way to do this is with AppleEvents. The following
5351 * code is modeled on the "Getting Files Selected from the Finder"
5352 * snippet from Think Reference 2.0. (The prior sentence could read
5353 * "shamelessly swiped & hacked")
5355 static pascal OSErr AEH_Open(const AppleEvent *theAppleEvent,
5356 AppleEvent* reply, long handlerRefCon)
5358 #pragma unused(reply, handlerRefCon)
5365 DescType returnedType;
5369 /* Put the direct parameter (a descriptor list) into a docList */
5370 err = AEGetParamDesc(theAppleEvent, keyDirectObject, typeAEList, &docList);
5371 if (err) return err;
5374 * We ignore the validity check, because we trust the FInder, and we only
5375 * allow one savefile to be opened, so we ignore the depth of the list.
5378 err = AEGetNthPtr(&docList, 1L, typeFSS, &keywd,
5379 &returnedType, (Ptr) &myFSS, sizeof(myFSS), &actualSize);
5380 if (err) return err;
5382 /* Only needed to check savefile type below */
5383 err = FSpGetFInfo(&myFSS, &myFileInfo);
5386 sprintf(foo, "Arg! FSpGetFInfo failed with code %d", err);
5391 /* Ignore non 'SAVE' files */
5392 if (myFileInfo.fdType != 'SAVE') return noErr;
5394 /* XXX XXX XXX Extract a file name */
5395 PathNameFromDirID(myFSS.parID, myFSS.vRefNum, (StringPtr)savefile);
5396 pstrcat((StringPtr)savefile, (StringPtr)&myFSS.name);
5398 /* Convert the string */
5399 ptocstr((StringPtr)savefile);
5401 /* Delay actual open */
5402 open_when_ready = TRUE;
5405 err = AEDisposeDesc(&docList);
5417 * Macintosh modifiers (event.modifier & ccc):
5418 * cmdKey, optionKey, shiftKey, alphaLock, controlKey
5421 * Macintosh Keycodes (0-63 normal, 64-95 keypad, 96-127 extra):
5466 * Optimize non-blocking calls to "CheckEvents()"
5467 * Idea from "Maarten Hazewinkel <mmhazewi@cs.ruu.nl>"
5469 #define EVENT_TICKS 6
5473 * Check for Events, return TRUE if we process any
5475 * Hack -- Handle AppleEvents if appropriate (ignore result code).
5477 static bool CheckEvents(bool wait)
5493 term_data *td = NULL;
5497 static huge lastTicks = 0L;
5500 /* Access the clock */
5501 curTicks = TickCount();
5503 /* Hack -- Allow efficient checking for non-pending events */
5504 if (!wait && (curTicks < lastTicks + EVENT_TICKS)) return (FALSE);
5506 /* Timestamp last check */
5507 lastTicks = curTicks;
5509 #if TARGET_API_MAC_CARBON
5510 WaitNextEvent( everyEvent, &event, 1L, nil );
5512 /* Let the "system" run */
5515 /* Get an event (or null) */
5516 GetNextEvent(everyEvent, &event);
5519 /* Hack -- Nothing is ready yet */
5520 if (event.what == nullEvent) return (FALSE);
5522 /* Analyze the event */
5530 w = (WindowPtr)event.message;
5541 /* Extract the window */
5542 w = (WindowPtr)event.message;
5544 /* Find the window */
5545 for (i = 0; i < MAX_TERM_DATA; i++)
5547 /* Skip dead windows */
5548 if (!data[i].t) continue;
5550 /* Notice matches */
5551 if (data[i].w == w) td = &data[i];
5554 /* Hack XXX XXX XXX */
5558 /* Redraw the window */
5559 if (td) term_data_redraw(td);
5567 /* Extract some modifiers */
5568 mc = (event.modifiers & controlKey) ? TRUE : FALSE;
5569 ms = (event.modifiers & shiftKey) ? TRUE : FALSE;
5570 mo = (event.modifiers & optionKey) ? TRUE : FALSE;
5571 mx = (event.modifiers & cmdKey) ? TRUE : FALSE;
5573 /* Keypress: (only "valid" if ck < 96) */
5574 ch = (event.message & charCodeMask) & 255;
5576 /* Keycode: see table above */
5577 ck = ((event.message & keyCodeMask) >> 8) & 255;
5579 /* Command + "normal key" -> menu action */
5580 if (mx && (ck < 64))
5582 /* Hack -- Prepare the menus */
5585 /* Run the Menu-Handler */
5588 /* Turn off the menus */
5596 /* Hide the mouse pointer */
5599 /* Normal key -> simple keypress */
5602 /* Enqueue the keypress */
5606 /* Hack -- normal "keypad keys" -> special keypress */
5607 else if (!mc && !ms && !mo && !mx && (ck < 96))
5609 /* Hack -- "enter" is confused */
5610 if (ck == 76) ch = '\n';
5612 /* Send control-caret as a trigger */
5615 /* Send the "ascii" keypress */
5619 /* Bizarre key -> encoded keypress */
5622 /* Hack -- introduce with control-underscore */
5625 /* Send some modifier keys */
5626 if (mc) Term_keypress('C');
5627 if (ms) Term_keypress('S');
5628 if (mo) Term_keypress('O');
5629 if (mx) Term_keypress('X');
5631 /* Hack -- Downshift and encode the keycode */
5632 Term_keypress('0' + (ck - 64) / 10);
5633 Term_keypress('0' + (ck - 64) % 10);
5635 /* Hack -- Terminate the sequence */
5636 /* MPW can generate 10 or 13 for keycode of '\r' */
5637 /* -noMapCR option swaps '\r' and '\n' */
5638 Term_keypress('\r');
5648 /* Analyze click location */
5649 code = FindWindow(event.where, &w);
5651 /* Find the window */
5652 for (i = 0; i < MAX_TERM_DATA; i++)
5654 /* Skip dead windows */
5655 if (!data[i].t) continue;
5657 /* Notice matches */
5658 if (data[i].w == w) td = &data[i];
5667 menu(MenuSelect(event.where));
5671 #if !TARGET_API_MAC_CARBON
5674 SystemClick(&event, w);
5686 #if TARGET_API_MAC_CARBON
5687 GetQDGlobalsScreenBits( &screen );
5689 screen = qd.screenBits;
5692 r.top += 20; /* GetMBarHeight() XXX XXX XXX */
5693 InsetRect(&r, 4, 4);
5694 DragWindow(w, event.where, &r);
5706 #if TARGET_API_MAC_CARBON
5707 GetWindowBounds( (WindowRef)td->w, kWindowContentRgn, &portRect );
5709 portRect = td->w->portRect;
5710 local_to_global( &portRect );
5712 p.h = portRect.left;
5714 #if !TARGET_API_MAC_CARBON
5723 /* Apply and Verify */
5724 term_data_check_size(td);
5734 /* Track the go-away box */
5735 if (TrackGoAway(w, event.where))
5741 td->t->mapped_flag = FALSE;
5743 /* Hide the window */
5757 #if TARGET_API_MAC_CARBON
5758 GetQDGlobalsScreenBits( &screen );
5760 screen = qd.screenBits;
5765 /* Fake rectangle */
5766 r.left = 20 * td->tile_wid + td->size_ow1;
5767 r.right = screen.bounds.right;
5768 r.top = 1 * td->tile_hgt + td->size_oh1;
5769 r.bottom = screen.bounds.bottom;
5771 /* Grow the rectangle */
5772 newsize = GrowWindow(w, event.where, &r);
5775 if (!newsize) break;
5777 /* Extract the new size in pixels */
5778 y = HiWord(newsize) - td->size_oh1 - td->size_oh2;
5779 x = LoWord(newsize) - td->size_ow1 - td->size_ow2;
5781 /* Extract a "close" approximation */
5782 td->rows = y / td->tile_hgt;
5783 td->cols = x / td->tile_wid;
5785 /* Apply and Verify */
5786 term_data_check_size(td);
5788 Term_activate(td->t);
5790 /* Hack -- Resize the term */
5791 Term_resize(td->cols, td->rows);
5793 /* Resize and Redraw */
5794 term_data_resize(td);
5795 term_data_redraw(td);
5814 /* Disk Event -- From "Maarten Hazewinkel" */
5818 #if TARGET_API_MAC_CARBON
5820 /* check for error when mounting the disk */
5821 if (HiWord(event.message) != noErr)
5827 DIBadMount(p, event.message);
5834 /* OS Event -- From "Maarten Hazewinkel" */
5837 switch ((event.message >> 24) & 0x000000FF)
5839 case suspendResumeMessage:
5841 /* Resuming: activate the front window */
5842 if (event.message & resumeFlag)
5844 #if TARGET_API_MAC_CARBON
5847 SetPortWindowPort( FrontWindow() );
5849 GetQDGlobalsArrow( &arrow );
5852 SetPort(FrontWindow());
5853 SetCursor(&qd.arrow);
5857 /* Suspend: deactivate the front window */
5871 /* From "Steve Linberg" and "Maarten Hazewinkel" */
5872 case kHighLevelEvent:
5874 #if TARGET_API_MAC_CARBON
5875 AEProcessAppleEvent(&event);
5877 /* Process apple events */
5878 if (AEProcessAppleEvent(&event) != noErr)
5881 plog("Apple Event Handler¤Î¥¨¥é¡¼¤Ç¤¹.");
5883 plog("Error in Apple Event Handler!");
5887 /* Handle "quit_when_ready" */
5888 if (quit_when_ready)
5891 quit_when_ready = FALSE;
5893 /* Do the menu key */
5896 /* Turn off the menus */
5900 /* Handle "open_when_ready" */
5901 handle_open_when_ready();
5912 /* Something happened */
5919 /*** Some Hooks for various routines ***/
5923 * Mega-Hack -- emergency lifeboat
5925 static vptr lifeboat = NULL;
5929 * Hook to "release" memory
5931 static vptr hook_rnfree(vptr v, huge size)
5934 #pragma unused (size)
5938 /* Alternative method */
5953 * Hook to "allocate" memory
5955 static vptr hook_ralloc(huge size)
5960 /* Make a new pointer */
5961 return (malloc(size));
5965 /* Make a new pointer */
5966 return (NewPtr(size));
5973 * Hook to handle "out of memory" errors
5975 static vptr hook_rpanic(huge size)
5978 #pragma unused (size)
5982 /* Free the lifeboat */
5985 /* Free the lifeboat */
5986 DisposePtr(lifeboat);
5988 /* Forget the lifeboat */
5991 /* Mega-Hack -- Warning */
5993 mac_warning("¥á¥â¥ê¡¼¤¬Â¤ê¤Þ¤»¤ó!\rº£¤¹¤°½ªÎ»¤·¤Æ²¼¤µ¤¤!");
5995 mac_warning("Running out of Memory!\rAbort this process now!");
5998 /* Mega-Hack -- Never leave this function */
5999 while (TRUE) CheckEvents(TRUE);
6002 /* Mega-Hack -- Crash */
6008 * Hook to tell the user something important
6010 static void hook_plog(cptr str)
6012 /* Warning message */
6017 * Hook to tell the user something, and then quit
6019 static void hook_quit(cptr str)
6021 /* Warning if needed */
6022 if (str) mac_warning(str);
6024 /* Write a preference file */
6032 * Hook to tell the user something, and then crash
6034 static void hook_core(cptr str)
6036 /* XXX Use the debugger */
6037 /* DebugStr(str); */
6040 if (str) mac_warning(str);
6042 /* Warn, then save player */
6044 mac_warning("Ã×̿Ū¤Ê¥¨¥é¡¼¤Ç¤¹.\r¶¯À©Åª¤Ë¥»¡¼¥Ö¤·¤Æ½ªÎ»¤·¤Þ¤¹.");
6046 mac_warning("Fatal error.\rI will now attempt to save and quit.");
6049 /* Attempt to save */
6051 if (!save_player()) mac_warning("·Ù¹ð -- ¥»¡¼¥Ö¤Ë¼ºÇÔ¤·¤Þ¤·¤¿!");
6053 if (!save_player()) mac_warning("Warning -- save failed!");
6062 /*** Main program ***/
6068 * XXX XXX XXX Hack -- This function attempts to "fix" the nasty
6069 * "Macintosh Save Bug" by using "absolute" path names, since on
6070 * System 7 machines anyway, the "current working directory" often
6071 * "changes" due to background processes, invalidating any "relative"
6072 * path names. Note that the Macintosh is limited to 255 character
6073 * path names, so be careful about deeply embedded directories...
6075 * XXX XXX XXX Hack -- This function attempts to "fix" the nasty
6076 * "missing lib folder bug" by allowing the user to help find the
6077 * "lib" folder by hand if the "application folder" code fails...
6079 static void init_stuff(void)
6098 #if TARGET_API_MAC_CARBON
6100 NavDialogOptions dialogOptions;
6101 FSSpec theFolderSpec;
6102 NavReplyRecord theReply;
6104 /* Fake rectangle */
6111 #if TARGET_API_MAC_CARBON
6112 screenRect = GetQDGlobalsScreenBits(&screen)->bounds;
6114 screenRect = qd.screenBits.bounds;
6116 center_rect(&r, &screenRect);
6118 /* Extract corner */
6123 /* Default to the "lib" folder with the application */
6124 refnum_to_name(path, app_dir, app_vol, (char*)("\plib:"));
6127 /* Check until done */
6130 /* Prepare the paths */
6131 init_file_paths(path);
6133 /* Build the filename */
6135 path_build(path, sizeof(path), ANGBAND_DIR_FILE, "news_j.txt");
6137 path_build(path, sizeof(path), ANGBAND_DIR_FILE, "news.txt");
6140 /* Attempt to open and close that file */
6141 if (0 == fd_close(fd_open(path, O_RDONLY))) break;
6145 plog_fmt("'%s' ¥Õ¥¡¥¤¥ë¤ò¥ª¡¼¥×¥ó½ÐÍè¤Þ¤»¤ó.", path);
6147 plog_fmt("Unable to open the '%s' file.", path);
6152 plog("Hengband¤Î'lib'¥Õ¥©¥ë¥À¤¬Â¸ºß¤·¤Ê¤¤¤«Àµ¤·¤¯Ìµ¤¤²ÄǽÀ¤¬¤¢¤ê¤Þ¤¹.");
6154 plog("The Angband 'lib' folder is probably missing or misplaced.");
6159 plog("Please 'open' any file in any sub-folder of the 'lib' folder.");
6161 plog("Please 'open' any file in any sub-folder of the 'lib' folder.");
6164 #if TARGET_API_MAC_CARBON
6165 /* Ask the user to choose the lib folder */
6166 err = NavGetDefaultDialogOptions(&dialogOptions);
6169 if (err != noErr) quit(NULL);
6171 /* Set default location option */
6172 dialogOptions.dialogOptionFlags |= kNavSelectDefaultLocation;
6174 /* Clear preview option */
6175 dialogOptions.dialogOptionFlags &= ~(kNavAllowPreviews);
6177 /* Forbit selection of multiple files */
6178 dialogOptions.dialogOptionFlags &= ~(kNavAllowMultipleFiles);
6180 /* Display location */
6181 dialogOptions.location = topleft;
6183 /* Load the message for the missing folder from the resource fork */
6184 GetIndString(dialogOptions.message, 128, 1);
6186 /* Wait for the user to choose a folder */
6187 err = NavChooseFolder(
6195 /* Assume the player doesn't want to go on */
6196 if ((err != noErr) || !theReply.validRecord) quit(NULL);
6198 /* Retrieve FSSpec from the reply */
6200 AEKeyword theKeyword;
6201 DescType actualType;
6204 /* Get a pointer to selected folder */
6206 &(theReply.selection),
6216 if (err != noErr) quit(NULL);
6219 /* Free navitagor reply */
6220 err = NavDisposeReply(&theReply);
6223 if (err != noErr) quit(NULL);
6225 /* Extract textual file name for given file */
6228 theFolderSpec.parID,
6229 theFolderSpec.vRefNum,
6230 (char *)theFolderSpec.name);
6232 /* Allow "text" files */
6235 /* Allow "save" files */
6238 /* Allow "data" files */
6242 SFGetFile(topleft, "\p", NULL, 3, types, NULL, &reply);
6245 if (!reply.good) quit(NULL);
6247 /* Extract textual file name for given file */
6248 GetWDInfo(reply.vRefNum, &vrefnum, &drefnum, &junk);
6249 refnum_to_name(path, drefnum, vrefnum, (char*)reply.fName);
6252 /* Hack -- Remove the "filename" */
6253 i = strlen(path) - 1;
6254 while ((i > 0) && (path[i] != ':')) i--;
6255 if (path[i] == ':') path[i+1] = '\0';
6257 /* Hack -- allow "lib" folders */
6258 if (suffix(path, "lib:")) continue;
6260 /* Hack -- Remove the "sub-folder" */
6262 while ((i > 1) && (path[i] != ':')) i--;
6263 if (path[i] == ':') path[i+1] = '\0';
6269 * Macintosh Main loop
6273 EventRecord tempEvent;
6274 int numberOfMasters = 10;
6276 #if !TARGET_API_MAC_CARBON
6277 /* Increase stack space by 64K */
6278 SetApplLimit(GetApplLimit() - 131072L);//65536L);
6280 /* Stretch out the heap to full size */
6284 /* Get more Masters */
6285 while (numberOfMasters--) MoreMasters();
6287 #if !TARGET_API_MAC_CARBON
6288 /* Set up the Macintosh */
6289 InitGraf(&qd.thePort);
6303 FlushEvents(everyEvent, 0);
6305 /* Flush events some more (?) */
6306 (void)EventAvail(everyEvent, &tempEvent);
6307 (void)EventAvail(everyEvent, &tempEvent);
6308 (void)EventAvail(everyEvent, &tempEvent);
6311 #ifdef ANGBAND_LITE_MAC
6315 #else /* ANGBAND_LITE_MAC */
6317 # if defined(powerc) || defined(__powerc)
6319 /* Assume System 7 */
6321 /* Assume Color Quickdraw */
6331 /* Check the Gestalt */
6332 err = Gestalt(gestaltSystemVersion, &versionNumber);
6334 /* Check the version */
6335 if ((err != noErr) || (versionNumber < 0x0700))
6338 quit("¤³¤Î¥×¥í¥°¥é¥à¤Ï´Á»úTalk7.x.x°Ê¹ß¤ÇÆ°ºî¤·¤Þ¤¹.");
6340 quit("You must have System 7 to use this program.");
6350 /* Check the environs */
6351 if (SysEnvirons(1, &env) != noErr)
6354 quit("SysEnvirons ¥³¡¼¥ë¤Ï¼ºÇÔ¤·¤Þ¤·¤¿¡ª");
6356 quit("The SysEnvirons call failed!");
6360 /* Check for System Seven Stuff */
6361 if (env.systemVersion < 0x0700)
6364 quit("¤³¤Î¥×¥í¥°¥é¥à¤Ï´Á»úTalk7.x.x°Ê¹ß¤ÇÆ°ºî¤·¤Þ¤¹.");
6366 quit("You must have System 7 to use this program.");
6370 /* Check for Color Quickdraw */
6371 if (!env.hasColorQD)
6374 quit("¤³¤Î¥×¥í¥°¥é¥à¤ÏColor Quickdraw¤¬Ìµ¤¤¤ÈÆ°ºî¤·¤Þ¤»¤ó.");
6376 quit("You must have Color Quickdraw to use this program.");
6383 #endif /* ANGBAND_LITE_MAC */
6386 * Remember Mac OS version, in case we have to cope with version-specific
6389 (void)Gestalt(gestaltSystemVersion, &mac_os_version);
6392 /* Obtain a "Universal Procedure Pointer" */
6393 AEH_Start_UPP = NewAEEventHandlerUPP(AEH_Start);
6394 /* Install the hook (ignore error codes) */
6395 AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, AEH_Start_UPP,
6398 /* Obtain a "Universal Procedure Pointer" */
6399 AEH_Quit_UPP = NewAEEventHandlerUPP(AEH_Quit);
6400 /* Install the hook (ignore error codes) */
6401 AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, AEH_Quit_UPP,
6404 /* Obtain a "Universal Procedure Pointer" */
6405 AEH_Print_UPP = NewAEEventHandlerUPP(AEH_Print);
6406 /* Install the hook (ignore error codes) */
6407 AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments, AEH_Print_UPP,
6410 /* Obtain a "Universal Procedure Pointer" */
6411 AEH_Open_UPP = NewAEEventHandlerUPP(AEH_Open);
6412 /* Install the hook (ignore error codes) */
6413 AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, AEH_Open_UPP,
6417 /* Find the current application */
6421 /* Mark ourself as the file creator */
6422 _fcreator = ANGBAND_CREATOR;
6424 /* Default to saving a "text" file */
6428 #if defined(__MWERKS__)
6430 /* Obtian a "Universal Procedure Pointer" */
6431 #if TARGET_API_MAC_CARBON
6432 ynfilterUPP = NewModalFilterUPP(ynfilter);
6434 ynfilterUPP = NewModalFilterProc(ynfilter);
6440 /* Hook in some "z-virt.c" hooks */
6441 rnfree_aux = hook_rnfree;
6442 ralloc_aux = hook_ralloc;
6443 rpanic_aux = hook_rpanic;
6445 /* Hooks in some "z-util.c" hooks */
6446 plog_aux = hook_plog;
6447 quit_aux = hook_quit;
6448 core_aux = hook_core;
6450 BackColor(blackColor);
6451 ForeColor(whiteColor);
6453 /* Show the "watch" cursor */
6454 SetCursor(*(GetCursor(watchCursor)));
6456 /* Prepare the menubar */
6459 /* Prepare the windows */
6466 /* Hack -- process all events */
6467 while (CheckEvents(TRUE)) /* loop */;
6469 /* Reset the cursor */
6470 #if TARGET_API_MAC_CARBON
6473 GetQDGlobalsArrow( &arrow );
6477 SetCursor( &qd.arrow );
6481 /* Mega-Hack -- Allocate a "lifeboat" */
6482 lifeboat = NewPtr(16384);
6484 /* Note the "system" */
6485 ANGBAND_SYS = "mac";
6490 /* Catch nasty signals */
6497 /* Hack -- process all events */
6498 while (CheckEvents(TRUE)) /* loop */;
6501 /* We are now initialized */
6505 /* Handle "open_when_ready" */
6506 handle_open_when_ready();
6512 /* Prompt the user */
6514 prt("'¥Õ¥¡¥¤¥ë'¥á¥Ë¥å¡¼¤è¤ê'¿·µ¬'¤Þ¤¿¤Ï'³«¤¯...'¤òÁªÂò¤·¤Æ¤¯¤À¤µ¤¤¡£", 23, 10);
6516 prt("[Choose 'New' or 'Open' from the 'File' menu]", 23, 15);
6519 /* Flush the prompt */
6523 /* Hack -- Process Events Forever */
6524 while (TRUE) CheckEvents(TRUE);