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>
160 # include <CarbonStdCLib.h>
171 * Cleaning up a couple of things to make these easier to change --AR
174 #define PREF_FILE_NAME "Hengband Preferences"
176 #define PREF_FILE_NAME "Hengband-E Preferences"
180 * Use "malloc()" instead of "NewPtr()"
182 /* #define USE_MALLOC */
185 #if defined(powerc) || defined(__powerc)
188 * Disable "LITE" version
190 # undef ANGBAND_LITE_MAC
195 #ifdef ANGBAND_LITE_MAC
198 * Maximum number of windows
200 # define MAX_TERM_DATA 1
202 #else /* ANGBAND_LITE_MAC */
205 * Maximum number of windows
207 # define MAX_TERM_DATA 8
210 * Activate some special code
212 # define USE_SFL_CODE
214 #endif /* ANGBAND_LITE_MAC */
221 * Include the necessary header files
223 #include <AppleEvents.h>
231 * Globals for MPW compilation
233 #if defined(MACH_O_CARBON) || defined(MAC_MPW)
235 #if !TARGET_API_MAC_CARBON
247 * The Angband Color Set (0 to 15):
248 * Black, White, Slate, Orange, Red, Blue, Green, Umber
249 * D-Gray, L-Gray, Violet, Yellow, L-Red, L-Blue, L-Green, L-Umber
251 * Colors 8 to 15 are basically "enhanced" versions of Colors 0 to 7.
253 * On the Macintosh, we use color quickdraw, and we use actual "RGB"
254 * values below to choose the 16 colors.
256 * If we are compiled for ancient machines, we bypass color and simply
257 * draw everything in white (letting "z-term.c" automatically convert
258 * "black" into "wipe" calls).
260 static RGBColor foo[16] =
262 {0x0000, 0x0000, 0x0000}, /* TERM_DARK */
263 {0xFFFF, 0xFFFF, 0xFFFF}, /* TERM_WHITE */
264 {0x8080, 0x8080, 0x8080}, /* TERM_SLATE */
265 {0xFFFF, 0x8080, 0x0000}, /* TERM_ORANGE */
266 {0xC0C0, 0x0000, 0x0000}, /* TERM_RED */
267 {0x0000, 0x8080, 0x4040}, /* TERM_GREEN */
268 {0x0000, 0x0000, 0xFFFF}, /* TERM_BLUE */
269 {0x8080, 0x4040, 0x0000}, /* TERM_UMBER */
270 {0x4040, 0x4040, 0x4040}, /* TERM_L_DARK */
271 {0xC0C0, 0xC0C0, 0xC0C0}, /* TERM_L_WHITE */
272 {0xFFFF, 0x0000, 0xFFFF}, /* TERM_VIOLET */
273 {0xFFFF, 0xFFFF, 0x0000}, /* TERM_YELLOW */
274 {0xFFFF, 0x0000, 0x0000}, /* TERM_L_RED */
275 {0x0000, 0xFFFF, 0x0000}, /* TERM_L_GREEN */
276 {0x0000, 0xFFFF, 0xFFFF}, /* TERM_L_BLUE */
277 {0xC0C0, 0x8080, 0x4040} /* TERM_L_UMBER */
286 typedef struct term_data term_data;
299 #ifdef ANGBAND_LITE_MAC
303 #else /* ANGBAND_LITE_MAC */
315 #endif /* ANGBAND_LITE_MAC */
358 * Forward declare -- see below
360 static bool CheckEvents(bool wait);
364 * Hack -- location of the main directory
366 static short app_vol;
371 * Delay handling of double-clicked savefiles
373 Boolean open_when_ready = FALSE;
376 * Delay handling of pre-emptive "quit" event
378 Boolean quit_when_ready = FALSE;
382 * Hack -- game in progress
384 static int game_in_progress = 0;
388 * Only do "SetPort()" when needed
390 static WindowPtr active = NULL;
395 * An array of term_data's
397 static term_data data[MAX_TERM_DATA];
402 * Note when "open"/"new" become valid
404 static bool initialized = FALSE;
407 * Version of Mac OS - for version specific bug workarounds (; ;)
409 static long mac_os_version;
413 * CodeWarrior uses Universal Procedure Pointers
415 static ModalFilterUPP ynfilterUPP;
422 AEEventHandlerUPP AEH_Start_UPP;
423 AEEventHandlerUPP AEH_Quit_UPP;
424 AEEventHandlerUPP AEH_Print_UPP;
425 AEEventHandlerUPP AEH_Open_UPP;
433 static int ext_sound = 0;
441 #define SND_CMD_ERROR 6
443 static int soundchoice[] = {
511 static int soundmode[8];
513 static int ext_graf = 0;
518 * Convert refnum+vrefnum+fname into a full file name
519 * Store this filename in 'buf' (make sure it is long enough)
520 * Note that 'fname' looks to be a "pascal" string
522 #if TARGET_API_MAC_CARBON
523 static void refnum_to_name(char *buf, long refnum, short vrefnum, char *fname)
539 for (j=1; j<=fname[0]; j++)
541 res[i-fname[0]+j] = fname[j];
550 pb.dirInfo.ioDrDirID=pb.dirInfo.ioDrParID;
551 err = FSMakeFSSpec( vref, dirID, "\p", &spec );
557 for (j=1; j<=spec.name[0]; j++)
559 res[i-spec.name[0]+j] = spec.name[j];
566 /* Extract the result */
567 for (j = 0, i++; res[i]; j++, i++) buf[j] = res[i];
571 static void refnum_to_name(char *buf, long refnum, short vrefnum, char *fname)
583 for (j=1; j<=fname[0]; j++)
585 res[i-fname[0]+j] = fname[j];
589 pb.ioCompletion=NULL;
591 pb.ioVRefNum=vrefnum;
597 pb.ioDrDirID=pb.ioDrParID;
598 err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
600 for (j=1; j<=name[0]; j++)
602 res[i-name[0]+j] = name[j];
606 if (pb.ioDrDirID == fsRtDirID) break;
609 /* Extract the result */
610 for (j = 0, i++; res[i]; j++, i++) buf[j] = res[i];
615 #if TARGET_API_MAC_CARBON
616 pascal OSErr FSpLocationFromFullPath(short fullPathLength,
617 const void *fullPath,
625 /* Create a minimal alias from the full pathname */
626 nullString[0] = 0; /* null string to indicate no zone or server name */
627 result = NewAliasMinimalFromFullPath(fullPathLength, fullPath, nullString, nullString, &alias);
628 if ( result == noErr )
630 /* Let the Alias Manager resolve the alias. */
631 result = ResolveAlias(NULL, alias, spec, &wasChanged);
633 /* work around Alias Mgr sloppy volume matching bug */
634 if ( spec->vRefNum == 0 )
636 /* invalidate wrong FSSpec */
641 DisposeHandle((Handle)alias); /* Free up memory used */
650 * XXX XXX XXX Allow the system to ask us for a filename
652 static bool askfor_file(char *buf, int len)
660 /* Default file name */
661 sprintf((char*)dflt + 1, "%s's description", buf);
662 dflt[0] = strlen((char*)dflt + 1);
664 /* Ask for a file name */
665 topleft.h=(qd.screenBits.bounds.left+qd.screenBits.bounds.right)/2-344/2;
666 topleft.v=(2*qd.screenBits.bounds.top+qd.screenBits.bounds.bottom)/3-188/2;
667 SFPutFile(topleft, "\pSelect a filename:", dflt, NULL, &reply);
668 /* StandardPutFile("\pSelect a filename:", dflt, &reply); */
676 GetWDInfo(reply.vRefNum, &vrefnum, &drefnum, &junk);
678 /* Extract the name */
679 refnum_to_name(buf, drefnum, vrefnum, (char*)reply.fName);
691 static void local_to_global( Rect *r )
698 LocalToGlobal( &temp );
706 LocalToGlobal( &temp );
712 static void global_to_local( Rect *r )
719 GlobalToLocal( &temp );
727 GlobalToLocal( &temp );
737 * Convert pathname to an appropriate format, because MPW's
738 * CarbonStdCLib chose to use system's native path format,
739 * making our lives harder to create binaries that run on
740 * OS 8/9 and OS X :( -- pelpel
742 void convert_pathname(char* path)
746 /* Nothing has to be done for CarbonLib on Classic */
747 if (mac_os_version >= 0x1000)
749 /* Convert to POSIX style */
750 ConvertHFSPathToUnixPath(path, buf);
752 /* Copy the result back */
760 # ifdef CHECK_MODIFICATION_TIME
763 * Although there is no easy way to emulate fstat in the old interface,
764 * we still can do stat-like things, because Mac OS is an OS.
766 static int get_modification_time(cptr path, u32b *mod_time)
772 /* Paranoia - make sure the pathname fits in Str255 */
774 if (i > 255) return (-1);
776 /* Convert pathname to a Pascal string */
777 strncpy((char *)pathname + 1, path, 255);
780 /* Set up parameter block */
781 pb.hFileInfo.ioNamePtr = pathname;
782 pb.hFileInfo.ioFDirIndex = 0;
783 pb.hFileInfo.ioVRefNum = app_vol;
784 pb.hFileInfo.ioDirID = 0;
786 /* Get catalog information of the file */
787 if (PBGetCatInfoSync(&pb) != noErr) return (-1);
789 /* Set modification date and time */
790 *mod_time = pb.hFileInfo.ioFlMdDat;
798 * A (non-Mach-O) Mac OS version of check_modification_time, for those
799 * compilers without good enough POSIX-compatibility libraries XXX XXX
801 errr check_modification_date(int fd, cptr template_file)
804 u32b txt_stat, raw_stat;
809 /* Build the file name */
810 path_build(buf, sizeof(buf), ANGBAND_DIR_EDIT, template_file);
813 convert_pathname(buf);
815 /* Obtain modification time */
816 if (get_modification_time(buf, &txt_stat)) return (-1);
818 /* XXX Build filename of the corresponding *.raw file */
819 strnfmt(fname, sizeof(fname), "%s", template_file);
822 p = strrchr(fname, '.');
825 if (p == NULL) return (-1);
827 /* Substitute ".raw" for ".txt" */
830 /* Build the file name of the raw file */
831 path_build(buf, sizeof(buf), ANGBAND_DIR_DATA, fname);
834 convert_pathname(buf);
836 /* Obtain modification time */
837 if (get_modification_time(buf, &raw_stat)) return (-1);
839 /* Ensure the text file is not newer than the raw file */
840 if (txt_stat > raw_stat) return (-1);
842 /* Keep using the current .raw file */
846 # endif /* CHECK_MODIFICATION_TIME */
851 * Center a rectangle inside another rectangle
853 static void center_rect(Rect *r, Rect *s)
855 int centerx = (s->left + s->right)/2;
856 int centery = (2*s->top + s->bottom)/3;
857 int dx = centerx - (r->right - r->left)/2 - r->left;
858 int dy = centery - (r->bottom - r->top)/2 - r->top;
867 * Convert a pascal string in place
869 * This function may be defined elsewhere, but since it is so
870 * small, it is not worth finding the proper function name for
871 * all the different platforms.
873 static void ptocstr(StringPtr src)
877 /* Hack -- pointer */
878 char *s = (char*)(src);
880 /* Hack -- convert the string */
881 for (i = s[0]; i; i--, s++) s[0] = s[1];
883 /* Hack -- terminate the string */
888 #if defined(USE_SFL_CODE)
892 * The following three routines (pstrcat, pstrinsert, and PathNameFromDirID)
893 * were taken from the Think Reference section called "Getting a Full Pathname"
894 * (under the File Manager section). We need PathNameFromDirID to get the
895 * full pathname of the opened savefile, making no assumptions about where it
898 * I had to hack PathNameFromDirID a little for MetroWerks, but it's awfully
901 static void pstrcat(StringPtr dst, StringPtr src)
904 BlockMove(src + 1, dst + *dst + 1, *src);
906 /* adjust length byte */
911 * pstrinsert - insert string 'src' at beginning of string 'dst'
913 static void pstrinsert(StringPtr dst, StringPtr src)
915 /* make room for new string */
916 BlockMove(dst + 1, dst + *src + 1, *dst);
918 /* copy new string in */
919 BlockMove(src + 1, dst + 1, *src);
921 /* adjust length byte */
925 static void PathNameFromDirID(long dirID, short vRefNum, StringPtr fullPathName)
928 Str255 directoryName;
931 fullPathName[0] = '\0';
933 block.dirInfo.ioDrParID = dirID;
934 block.dirInfo.ioNamePtr = directoryName;
938 block.dirInfo.ioVRefNum = vRefNum;
939 block.dirInfo.ioFDirIndex = -1;
940 block.dirInfo.ioDrDirID = block.dirInfo.ioDrParID;
941 err = PBGetCatInfo(&block, FALSE);
942 pstrcat(directoryName, (StringPtr)"\p:");
943 pstrinsert(fullPathName, directoryName);
944 if (block.dirInfo.ioDrDirID == 2) break;
950 #if TARGET_API_MAC_CARBON
952 static OSErr ChooseFile( StringPtr filename, FSSpec selfld )
954 NavReplyRecord reply;
955 NavDialogOptions dialogOptions;
956 NavTypeListHandle navTypeList = NULL;
960 AECreateDesc( typeFSS, &selfld, sizeof(FSSpec), &deffld );
962 err = NavGetDefaultDialogOptions( &dialogOptions );
966 err = NavChooseFile( &deffld, &reply, &dialogOptions, NULL, NULL, NULL, navTypeList, NULL );
968 if ( reply.validRecord && err == noErr ){
969 // grab the target FSSpec from the AEDesc:
975 // retrieve the returned selection:
976 // there is only one selection here we get only the first AEDescList:
977 if (( err = AEGetNthPtr( &(reply.selection), 1, typeFSS, &keyWord, &typeCode, &finalFSSpec, sizeof( FSSpec ), &actualSize )) == noErr )
979 refnum_to_name( (char *)filename, finalFSSpec.parID, finalFSSpec.vRefNum, (char *)finalFSSpec.name );
980 // 'finalFSSpec' is the chosen file¥Î
983 err = NavDisposeReply( &reply );
985 if( navTypeList != NULL )
987 DisposeHandle( (Handle)navTypeList );
992 AEDisposeDesc( &deffld );
1000 * Activate a given window, if necessary
1002 static void activate(WindowPtr w)
1008 #if TARGET_API_MAC_CARBON
1009 if (w) SetPortWindowPort(w);
1021 * Display a warning message
1023 static void mac_warning(cptr warning)
1028 /* Limit of 250 chars */
1029 len = strlen(warning);
1030 if (len > 250) len = 250;
1032 /* Make a "Pascal" string */
1034 for (i=0; i<len; i++) text[i+1] = warning[i];
1036 /* Prepare the dialog box values */
1037 ParamText(text, "\p", "\p", "\p");
1039 /* Display the Alert, wait for Okay */
1045 /*** Some generic functions ***/
1048 #ifdef ANGBAND_LITE_MAC
1051 * Hack -- activate a color (0 to 255)
1053 #define term_data_color(TD,A) /* Nothing */
1055 #else /* ANGBAND_LITE_MAC */
1058 * Hack -- activate a color (0 to 255)
1060 static void term_data_color(term_data *td, int a)
1066 /* Extract the R,G,B data */
1067 rv = angband_color_table[a][1];
1068 gv = angband_color_table[a][2];
1069 bv = angband_color_table[a][3];
1072 color.red = (rv | (rv << 8));
1073 color.green = (gv | (gv << 8));
1074 color.blue = (bv | (bv << 8));
1076 /* Activate the color */
1077 RGBForeColor(&color);
1079 /* Memorize color */
1083 #endif /* ANGBAND_LITE_MAC */
1087 * Hack -- Apply and Verify the "font" info
1089 * This should usually be followed by "term_data_check_size()"
1091 static void term_data_check_font(term_data *td)
1097 WindowPtr old = active;
1103 /* Instantiate font */
1104 TextFont(td->font_id);
1105 TextSize(td->font_size);
1106 TextFace(td->font_face);
1108 /* Extract the font info */
1111 /* Assume monospaced */
1112 td->font_mono = TRUE;
1114 /* Extract the font sizing values XXX XXX XXX */
1115 td->font_wid = CharWidth('@'); /* info.widMax; */
1116 td->font_hgt = info.ascent + info.descent;
1118 td->font_o_y = info.ascent;
1120 /* Check important characters */
1121 for (i = 33; i < 127; i++)
1123 /* Hack -- notice non-mono-space */
1124 if (td->font_wid != CharWidth(i)) td->font_mono = FALSE;
1126 /* Hack -- collect largest width */
1127 if (td->font_wid < CharWidth(i)) td->font_wid = CharWidth(i);
1130 /* Set default offsets */
1131 td->tile_o_x = td->font_o_x;
1132 td->tile_o_y = td->font_o_y;
1134 /* Set default tile size */
1135 if( td->tile_wid == 0 && td->tile_hgt == 0 ){
1136 td->tile_wid = td->font_wid;
1137 td->tile_hgt = td->font_hgt;
1140 /* Re-activate the old window */
1146 * Hack -- Apply and Verify the "size" info
1148 static void term_data_check_size(term_data *td)
1152 #if TARGET_API_MAC_CARBON
1153 GetQDGlobalsScreenBits( &screen );
1155 screen = qd.screenBits;
1157 /* Minimal window size */
1160 /* Enforce minimal size */
1161 if (td->cols < 80) td->cols = 80;
1162 if (td->rows < 24) td->rows = 24;
1165 /* Allow small windows for the rest */
1168 if (td->cols < 1) td->cols = 1;
1169 if (td->rows < 1) td->rows = 1;
1172 /* Minimal tile size */
1173 if (td->tile_wid < 4) td->tile_wid = 4;
1174 if (td->tile_hgt < 4) td->tile_hgt = 4;
1176 /* Default tile offsets */
1177 td->tile_o_x = (td->tile_wid - td->font_wid) / 2;
1178 td->tile_o_y = (td->tile_hgt - td->font_hgt) / 2;
1180 /* Minimal tile offsets */
1181 if (td->tile_o_x < 0) td->tile_o_x = 0;
1182 if (td->tile_o_y < 0) td->tile_o_y = 0;
1184 /* Apply font offsets */
1185 td->tile_o_x += td->font_o_x;
1186 td->tile_o_y += td->font_o_y;
1188 /* Calculate full window size */
1189 td->size_wid = td->cols * td->tile_wid + td->size_ow1 + td->size_ow2;
1190 td->size_hgt = td->rows * td->tile_hgt + td->size_oh1 + td->size_oh2;
1192 /* Verify the top */
1193 if (td->r.top > screen.bounds.bottom - td->size_hgt)
1195 td->r.top = screen.bounds.bottom - td->size_hgt;
1198 /* Verify the top */
1199 if (td->r.top < screen.bounds.top + 30)
1201 td->r.top = screen.bounds.top + 30;
1204 /* Verify the left */
1205 if (td->r.left > screen.bounds.right - td->size_wid)
1207 td->r.left = screen.bounds.right - td->size_wid;
1210 /* Verify the left */
1211 if (td->r.left < screen.bounds.left)
1213 td->r.left = screen.bounds.left;
1216 /* Calculate bottom right corner */
1217 td->r.right = td->r.left + td->size_wid;
1218 td->r.bottom = td->r.top + td->size_hgt;
1220 /* Assume no graphics */
1221 td->t->higher_pict = FALSE;
1222 td->t->always_pict = FALSE;
1224 #ifdef ANGBAND_LITE_MAC
1228 #else /* ANGBAND_LITE_MAC */
1230 /* Handle graphics */
1233 /* Use higher_pict whenever possible */
1234 if (td->font_mono) td->t->higher_pict = TRUE;
1236 /* Use always_pict only when necessary */
1237 else td->t->always_pict = TRUE;
1240 #endif /* ANGBAND_LITE_MAC */
1242 /* Fake mono-space */
1243 if (!td->font_mono ||
1244 (td->font_wid != td->tile_wid) ||
1245 (td->font_hgt != td->tile_hgt))
1247 /* Handle fake monospace -- this is SLOW */
1248 if (td->t->higher_pict) td->t->higher_pict = FALSE;
1249 td->t->always_pict = TRUE;
1254 * Hack -- resize a term_data
1256 * This should normally be followed by "term_data_resize()"
1258 static void term_data_resize(term_data *td)
1260 /* Actually resize the window */
1261 SizeWindow(td->w, td->size_wid, td->size_hgt, 0);
1267 * Hack -- redraw a term_data
1269 * Note that "Term_redraw()" calls "TERM_XTRA_CLEAR"
1271 static void term_data_redraw(term_data *td)
1275 /* Activate the term */
1276 Term_activate(td->t);
1278 /* Redraw the contents */
1281 /* Flush the output */
1284 /* Restore the old term */
1287 /* No need to redraw */
1288 #if TARGET_API_MAC_CARBON
1290 RgnHandle theRgn = NewRgn();
1291 GetWindowRegion( td->w, kWindowContentRgn, theRgn );
1292 ValidWindowRgn( (WindowRef)(td->w), theRgn );
1293 DisposeRgn( theRgn );
1296 ValidRect(&td->w->portRect);
1304 #ifdef ANGBAND_LITE_MAC
1308 #else /* ANGBAND_LITE_MAC */
1315 static int pictID = 1001; /* 8x8 tiles; 16x16 tiles are 1002 */
1317 static int grafWidth = 8; /* Always equal to grafHeight */
1318 static int grafHeight = 8; /* Either 8 or 16 */
1320 static bool arg_newstyle_graphics;
1321 static bool use_newstyle_graphics;
1326 typedef struct FrameRec FrameRec;
1331 * - GWorld for the frame image
1332 * - Handle to pix map (saved for unlocking/locking)
1333 * - Pointer to color pix map (valid only while locked)
1337 GWorldPtr framePort;
1338 PixMapHandle framePixHndl;
1345 * The global picture data
1347 static FrameRec *frameP = NULL;
1353 static void BenSWLockFrame(FrameRec *srcFrameP)
1355 PixMapHandle pixMapH;
1357 pixMapH = GetGWorldPixMap(srcFrameP->framePort);
1358 (void)LockPixels(pixMapH);
1359 HLockHi((Handle)pixMapH);
1360 srcFrameP->framePixHndl = pixMapH;
1361 #if TARGET_API_MAC_CARBON
1362 srcFrameP->framePix = (PixMapPtr)*(Handle)pixMapH;
1364 srcFrameP->framePix = (PixMapPtr)StripAddress(*(Handle)pixMapH);
1373 static void BenSWUnlockFrame(FrameRec *srcFrameP)
1375 if (srcFrameP->framePort != NULL)
1377 HUnlock((Handle)srcFrameP->framePixHndl);
1378 UnlockPixels(srcFrameP->framePixHndl);
1381 srcFrameP->framePix = NULL;
1385 static OSErr BenSWCreateGWorldFromPict(
1386 GWorldPtr *pictGWorld,
1390 GWorldPtr saveGWorld;
1391 GDHandle saveGDevice;
1392 GWorldPtr tempGWorld;
1401 depth = data[0].pixelDepth;
1404 theGDH = data[0].theGDH;
1406 /* Obtain size rectangle */
1407 pictRect = (**pictH).picFrame;
1408 OffsetRect(&pictRect, -pictRect.left, -pictRect.top);
1410 /* Create a GWorld */
1411 err = NewGWorld(&tempGWorld, depth, &pictRect, nil,
1412 theGDH, noNewDevice);
1421 *pictGWorld = tempGWorld;
1424 GetGWorld(&saveGWorld, &saveGDevice);
1427 SetGWorld(tempGWorld, nil);
1429 /* Dump the pict into the GWorld */
1430 (void)LockPixels(GetGWorldPixMap(tempGWorld));
1431 EraseRect(&pictRect);
1432 DrawPicture(pictH, &pictRect);
1433 UnlockPixels(GetGWorldPixMap(tempGWorld));
1435 /* Restore GWorld */
1436 SetGWorld(saveGWorld, saveGDevice);
1446 * Init the global "frameP"
1449 static errr globe_init(void)
1453 GWorldPtr tempPictGWorldP;
1457 /* Use window XXX XXX XXX */
1458 #if TARGET_API_MAC_CARBON
1459 SetPortWindowPort(data[0].w);
1465 /* Get the pict resource */
1466 newPictH = GetPicture(pictID);
1468 /* Analyze result */
1469 err = (newPictH ? 0 : -1);
1476 err = BenSWCreateGWorldFromPict(&tempPictGWorldP, newPictH);
1478 /* Release resource */
1479 ReleaseResource((Handle)newPictH);
1484 /* Create the frame */
1485 frameP = (FrameRec*)NewPtrClear((Size)sizeof(FrameRec));
1487 /* Analyze result */
1488 err = (frameP ? 0 : -1);
1494 frameP->framePort = tempPictGWorldP;
1497 BenSWLockFrame(frameP);
1508 * Nuke the global "frameP"
1510 static errr globe_nuke(void)
1516 BenSWUnlockFrame(frameP);
1518 /* Dispose of the GWorld */
1519 DisposeGWorld(frameP->framePort);
1521 /* Dispose of the memory */
1522 DisposePtr((Ptr)frameP);
1529 FlushEvents(everyEvent, 0);
1536 #endif /* ANGBAND_LITE_MAC */
1540 /*** Support for the "z-term.c" package ***/
1544 * Initialize a new Term
1546 * Note also the "window type" called "noGrowDocProc", which might be more
1547 * appropriate for the main "screen" window.
1549 * Note the use of "srcCopy" mode for optimized screen writes.
1551 static void Term_init_mac(term *t)
1553 term_data *td = (term_data*)(t->data);
1555 static RGBColor black = {0x0000,0x0000,0x0000};
1556 static RGBColor white = {0xFFFF,0xFFFF,0xFFFF};
1558 #ifdef ANGBAND_LITE_MAC
1560 /* Make the window */
1561 td->w = NewWindow(0, &td->r, td->title, 0, noGrowDocProc, (WindowPtr)-1, 1, 0L);
1563 #else /* ANGBAND_LITE_MAC */
1565 /* Make the window */
1566 td->w = NewCWindow(0, &td->r, td->title, 0, documentProc, (WindowPtr)-1, 1, 0L);
1568 #endif /* ANGBAND_LITE_MAC */
1570 /* Activate the window */
1573 /* Erase behind words */
1576 /* Apply and Verify */
1577 term_data_check_font(td);
1578 term_data_check_size(td);
1580 /* Resize the window */
1581 term_data_resize(td);
1583 #ifdef ANGBAND_LITE_MAC
1585 /* Prepare the colors (base colors) */
1586 BackColor(blackColor);
1587 ForeColor(whiteColor);
1589 #else /* ANGBAND_LITE_MAC */
1591 /* Prepare the colors (real colors) */
1592 RGBBackColor(&black);
1593 RGBForeColor(&white);
1600 GDHandle currentGDH;
1601 GWorldPtr windowGWorld;
1602 PixMapHandle basePixMap;
1604 /* Obtain the rect */
1605 #if TARGET_API_MAC_CARBON
1606 GetWindowBounds( (WindowRef)td->w, kWindowContentRgn, &globalRect );
1608 globalRect = td->w->portRect;
1609 LocalToGlobal((Point*)&globalRect.top);
1610 LocalToGlobal((Point*)&globalRect.bottom);
1613 /* Obtain the proper GDH */
1614 mainGDH = GetMaxDevice(&globalRect);
1616 /* Extract GWorld and GDH */
1617 GetGWorld(&windowGWorld, ¤tGDH);
1619 /* Obtain base pixmap */
1620 basePixMap = (**mainGDH).gdPMap;
1622 /* Save pixel depth */
1623 td->pixelDepth = (**basePixMap).pixelSize;
1625 /* Save Window GWorld */
1626 td->theGWorld = windowGWorld;
1628 /* Save Window GDH */
1629 td->theGDH = currentGDH;
1632 td->mainSWGDH = mainGDH;
1635 #endif /* ANGBAND_LITE_MAC */
1640 #if TARGET_API_MAC_CARBON
1641 GetWindowBounds( (WindowRef)td->w, kWindowContentRgn, &portRect );
1642 global_to_local( &portRect );
1644 portRect = td->w->portRect;
1646 /* Clip to the window */
1647 ClipRect(&portRect);
1649 /* Erase the window */
1650 EraseRect(&portRect);
1652 /* Invalidate the window */
1653 #if TARGET_API_MAC_CARBON
1654 InvalWindowRect((WindowRef)(td->w), (const Rect *)(&portRect));
1656 InvalRect(&portRect);
1659 /* Display the window if needed */
1660 if (td->mapped) ShowWindow(td->w);
1662 /* Hack -- set "mapped" flag */
1663 t->mapped_flag = td->mapped;
1669 /* if (err == noErr)
1680 static void Term_nuke_mac(term *t)
1693 static errr Term_user_mac(int n)
1707 static errr Term_xtra_mac_react(void)
1709 term_data *td = (term_data*)(Term->data);
1715 #ifdef ANGBAND_LITE_MAC
1719 #else /* ANGBAND_LITE_MAC */
1722 if (use_sound != arg_sound)
1725 use_sound = arg_sound;
1729 /* Handle transparency */
1730 if (use_newstyle_graphics != arg_newstyle_graphics)
1734 if (globe_init() != 0)
1736 plog("Cannot initialize graphics!");
1737 arg_graphics = FALSE;
1738 arg_newstyle_graphics = FALSE;
1742 use_newstyle_graphics = arg_newstyle_graphics;
1744 /* Apply and Verify */
1745 term_data_check_size(td);
1747 /* Resize the window */
1748 term_data_resize(td);
1754 /* Handle graphics */
1755 if (use_graphics != arg_graphics)
1757 /* Initialize graphics */
1759 if (!use_graphics && !frameP && (globe_init() != 0))
1762 plog("¥°¥é¥Õ¥£¥Ã¥¯¤Î½é´ü²½¤Ï½ÐÍè¤Þ¤»¤ó¤Ç¤·¤¿.");
1764 plog("Cannot initialize graphics!");
1766 arg_graphics = FALSE;
1770 use_graphics = arg_graphics;
1772 /* Apply and Verify */
1773 term_data_check_size(td);
1775 /* Resize the window */
1776 term_data_resize(td);
1782 #endif /* ANGBAND_LITE_MAC */
1790 * Do a "special thing"
1792 static errr Term_xtra_mac(int n, int v)
1794 term_data *td = (term_data*)(Term->data);
1802 case TERM_XTRA_NOISE:
1811 #ifdef ANGBAND_LITE_MAC
1815 #else /* ANGBAND_LITE_MAC */
1818 case TERM_XTRA_SOUND:
1828 /* Open the resource file */
1829 oldResFile = CurResFile();
1830 newResFile = OpenResFile(sound);
1832 /* Close the resource file */
1833 CloseResFile(newResFile);
1834 UseResFile(oldResFile);
1837 /* Get the proper sound name */
1838 sprintf((char*)sound + 1, "%.16s.wav", angband_sound_name[v]);
1839 sound[0] = strlen((char*)sound + 1);
1841 /* Obtain resource XXX XXX XXX */
1842 handle = Get1NamedResource('snd ', sound);
1843 if( handle == NULL || ext_sound )
1844 handle = GetNamedResource('snd ', sound);
1847 if (handle && soundmode[soundchoice[v]] == true)
1850 LoadResource(handle);
1853 /* Play sound (wait for completion) */
1854 SndPlay(nil, (SndListHandle)handle, true);
1856 /* Unlock and release */
1858 ReleaseResource(handle);
1864 #endif /* ANGBAND_LITE_MAC */
1866 /* Process random events */
1867 case TERM_XTRA_BORED:
1869 /* Process an event */
1870 (void)CheckEvents(FALSE);
1876 /* Process pending events */
1877 case TERM_XTRA_EVENT:
1879 /* Process an event */
1880 (void)CheckEvents(v);
1886 /* Flush all pending events (if any) */
1887 case TERM_XTRA_FLUSH:
1889 /* Hack -- flush all events */
1890 while (CheckEvents(TRUE)) /* loop */;
1896 /* Hack -- Change the "soft level" */
1897 case TERM_XTRA_LEVEL:
1899 /* Activate if requested */
1900 if (v) activate(td->w);
1906 /* Clear the screen */
1907 case TERM_XTRA_CLEAR:
1911 #if TARGET_API_MAC_CARBON
1912 GetWindowBounds( (WindowRef)td->w, kWindowContentRgn, &portRect );
1913 global_to_local( &portRect );
1915 portRect = td->w->portRect;
1918 /* No clipping XXX XXX XXX */
1919 ClipRect(&portRect);
1921 /* Erase the window */
1922 EraseRect(&portRect);
1925 term_data_color(td, TERM_WHITE);
1927 /* Frame the window in white */
1929 LineTo(0, td->size_hgt-1);
1930 LineTo(td->size_wid-1, td->size_hgt-1);
1931 LineTo(td->size_wid-1, 0);
1933 /* Clip to the new size */
1934 r.left = portRect.left + td->size_ow1;
1935 r.top = portRect.top + td->size_oh1;
1936 r.right = portRect.right - td->size_ow2;
1937 r.bottom = portRect.bottom - td->size_oh2;
1944 /* React to changes */
1945 case TERM_XTRA_REACT:
1947 /* React to changes */
1948 return (Term_xtra_mac_react());
1951 /* Delay (milliseconds) */
1952 case TERM_XTRA_DELAY:
1957 #if TARGET_API_MAC_CARBON
1961 /* Convert millisecs to ticks */
1962 ticks = (v * 60L) / 1000;
1965 * Hack? - Put the programme into sleep.
1966 * No events match ~everyEvent, so nothing
1967 * should be lost in Angband's event queue.
1968 * Even if ticks are 0, it's worth calling for
1969 * the above mentioned reasons.
1971 WaitNextEvent(~everyEvent, &tmp, ticks, nil);
1973 long m = TickCount() + (v * 60L) / 1000;
1976 while (TickCount() < m) /* loop */;
1992 * Low level graphics (Assumes valid input).
1993 * Draw a "cursor" at (x,y), using a "yellow box".
1994 * We are allowed to use "Term_grab()" to determine
1995 * the current screen contents (for inverting, etc).
1997 static errr Term_curs_mac(int x, int y)
2001 term_data *td = (term_data*)(Term->data);
2004 term_data_color(td, TERM_YELLOW);
2006 /* Frame the grid */
2007 r.left = x * td->tile_wid + td->size_ow1;
2008 r.right = r.left + td->tile_wid;
2009 r.top = y * td->tile_hgt + td->size_oh1;
2010 r.bottom = r.top + td->tile_hgt;
2020 * Low level graphics (Assumes valid input).
2021 * Draw a "big cursor" at (x,y), using a "yellow box".
2022 * We are allowed to use "Term_grab()" to determine
2023 * the current screen contents (for inverting, etc).
2025 static errr Term_bigcurs_mac(int x, int y)
2029 term_data *td = (term_data*)(Term->data);
2032 term_data_color(td, TERM_YELLOW);
2034 /* Frame the grid */
2035 r.left = x * td->tile_wid + td->size_ow1;
2036 r.right = r.left + 2 * td->tile_wid;
2037 r.top = y * td->tile_hgt + td->size_oh1;
2038 r.bottom = r.top + td->tile_hgt;
2048 * Low level graphics (Assumes valid input)
2050 * Erase "n" characters starting at (x,y)
2052 static errr Term_wipe_mac(int x, int y, int n)
2056 term_data *td = (term_data*)(Term->data);
2058 /* Erase the block of characters */
2059 r.left = x * td->tile_wid + td->size_ow1;
2060 r.right = r.left + n * td->tile_wid;
2061 r.top = y * td->tile_hgt + td->size_oh1;
2062 r.bottom = r.top + td->tile_hgt;
2071 * Low level graphics. Assumes valid input.
2073 * Draw several ("n") chars, with an attr, at a given location.
2075 static errr Term_text_mac(int x, int y, int n, byte a, const char *cp)
2079 term_data *td = (term_data*)(Term->data);
2082 term_data_color(td, (a & 0x0F));
2084 /* Starting pixel */
2085 xp = x * td->tile_wid + td->tile_o_x + td->size_ow1;
2086 yp = y * td->tile_hgt + td->tile_o_y + td->size_oh1;
2088 /* Move to the correct location */
2091 /* Draw the character */
2092 if (n == 1) DrawChar(*cp);
2094 /* Draw the string */
2095 else DrawText(cp, 0, n);
2103 * Low level graphics (Assumes valid input)
2105 * Erase "n" characters starting at (x,y)
2107 static errr Term_pict_mac(int x, int y, int n, const byte *ap, const char *cp,
2108 const byte *tap, const char *tcp)
2112 term_data *td = (term_data*)(Term->data);
2113 GDHandle saveGDevice;
2114 GWorldPtr saveGWorld;
2116 PixMapHandle PortPix;
2119 GetGWorld(&saveGWorld, &saveGDevice);
2121 r2.left = x * td->tile_wid + td->size_ow1;
2122 r2.right = r2.left + td->tile_wid;
2123 r2.top = y * td->tile_hgt + td->size_oh1;
2124 r2.bottom = r2.top + td->tile_hgt;
2128 /* Instantiate font */
2129 TextFont(td->font_id);
2130 TextSize(td->font_size);
2131 TextFace(td->font_face);
2133 /* Restore colors */
2134 BackColor(blackColor);
2135 ForeColor(whiteColor);
2139 /* Destination rectangle */
2140 /* r2.left = x * td->tile_wid + td->size_ow1;
2141 r2.top = y * td->tile_hgt + td->size_oh1;
2142 r2.bottom = r2.top + td->tile_hgt;*/
2146 /* Scan the input */
2147 for (i = 0; i < n; i++)
2154 /* Second byte of bigtile */
2155 if (use_bigtile && a == 255)
2158 r2.left += td->tile_wid;
2163 /* Prepare right of rectangle now */
2164 r2.right = r2.left + td->tile_wid;
2166 #ifdef ANGBAND_LITE_MAC
2170 #else /* ANGBAND_LITE_MAC */
2172 /* Graphics -- if Available and Needed */
2173 if (use_graphics && ((byte)a & 0x80) && ((byte)c & 0x80))
2175 #if TARGET_API_MAC_CARBON
2176 PixMapHandle srcBitMap = GetGWorldPixMap(frameP->framePort);
2177 PixMapHandle destBitMap;
2179 BitMapPtr srcBitMap = (BitMapPtr)(frameP->framePix);
2180 BitMapPtr destBitMap;
2187 bool terrain_flag = FALSE;
2191 if ((a != ta || c != tc) &&
2192 ((byte)ta & 0x80) && ((byte)tc & 0x80))
2195 row = ((byte)ta & 0x7F);
2196 col = ((byte)tc & 0x7F);
2198 /* Terrain Source rectangle */
2199 terrain_r.left = col * grafWidth;
2200 terrain_r.top = row * grafHeight;
2201 terrain_r.right = terrain_r.left + grafWidth;
2202 terrain_r.bottom = terrain_r.top + grafHeight;
2204 terrain_flag = TRUE;
2208 row = ((byte)a & 0x7F);
2209 col = ((byte)c & 0x7F);
2211 /* Source rectangle */
2212 r1.left = col * grafWidth;
2213 r1.top = row * grafHeight;
2214 r1.right = r1.left + grafWidth;
2215 r1.bottom = r1.top + grafHeight;
2217 /* Hardwire CopyBits */
2218 BackColor(whiteColor);
2219 ForeColor(blackColor);
2221 /* Draw the picture */
2222 #if TARGET_API_MAC_CARBON
2223 destBitMap = GetPortPixMap(GetWindowPort( td->w ));
2225 destBitMap = (BitMapPtr)&(td->w->portBits);
2227 if (use_bigtile) r2.right += td->tile_wid;
2232 * Source mode const = srcCopy:
2234 * determine how close the color of the source
2235 * pixel is to black, and assign this relative
2236 * amount of foreground color to the
2237 * destination pixel; determine how close the
2238 * color of the source pixel is to white, and
2239 * assign this relative amount of background
2240 * color to the destination pixel
2242 #if TARGET_API_MAC_CARBON
2243 CopyBits( (BitMap *) *srcBitMap, (BitMap *) *destBitMap, &terrain_r, &r2, srcCopy, NULL);
2245 CopyBits( srcBitMap, destBitMap, &terrain_r, &r2, srcCopy, NULL );
2248 * Draw transparent tile
2249 * BackColor is ignored and the destination is
2252 BackColor(blackColor);
2253 #if TARGET_API_MAC_CARBON
2254 CopyBits( (BitMap *) *srcBitMap, (BitMap *) *destBitMap, &r1, &r2, transparent, NULL);
2256 CopyBits( srcBitMap, destBitMap, &r1, &r2, transparent, NULL );
2261 #if TARGET_API_MAC_CARBON
2262 CopyBits( (BitMap *) *srcBitMap, (BitMap *) *destBitMap, &r1, &r2, srcCopy, NULL);
2264 CopyBits( srcBitMap, destBitMap, &r1, &r2, srcCopy, NULL );
2268 /* Restore colors */
2269 BackColor(blackColor);
2270 ForeColor(whiteColor);
2279 #endif /* ANGBAND_LITE_MAC */
2287 term_data_color(td, (a & 0x0F));
2289 /* Starting pixel */
2290 xp = r2.left + td->tile_o_x;
2291 yp = r2.top + td->tile_o_y;
2293 /* Move to the correct location */
2299 /* Double width rectangle */
2300 r2.right += td->tile_wid;
2305 /* Draw the character */
2310 r2.left += td->tile_wid;
2318 /* Draw the character */
2324 r2.left += td->tile_wid;
2333 * Create and initialize window number "i"
2335 static void term_data_link(int i)
2339 term_data *td = &data[i];
2344 /* Require mapped */
2345 if (!td->mapped) return;
2350 /* Initialize the term */
2351 term_init(td->t, td->cols, td->rows, td->keys);
2353 /* Use a "software" cursor */
2354 td->t->soft_cursor = TRUE;
2356 /* Erase with "white space" */
2357 td->t->attr_blank = TERM_WHITE;
2358 td->t->char_blank = ' ';
2360 /* Prepare the init/nuke hooks */
2361 td->t->init_hook = Term_init_mac;
2362 td->t->nuke_hook = Term_nuke_mac;
2364 /* Prepare the function hooks */
2365 td->t->user_hook = Term_user_mac;
2366 td->t->xtra_hook = Term_xtra_mac;
2367 td->t->wipe_hook = Term_wipe_mac;
2368 td->t->curs_hook = Term_curs_mac;
2369 td->t->bigcurs_hook = Term_bigcurs_mac;
2370 td->t->text_hook = Term_text_mac;
2371 td->t->pict_hook = Term_pict_mac;
2373 /* Link the local structure */
2374 td->t->data = (vptr)(td);
2377 Term_activate(td->t);
2379 /* Global pointer */
2380 angband_term[i] = td->t;
2390 * Set the "current working directory" (also known as the "default"
2391 * volume/directory) to the location of the current application.
2393 * Code by: Maarten Hazewinkel (mmhazewi@cs.ruu.nl)
2395 * This function does not appear to work correctly with System 6.
2397 static void SetupAppDir(void)
2401 char errString[100];
2403 /* Get the location of the Angband executable */
2404 fcbBlock.ioCompletion = NULL;
2405 fcbBlock.ioNamePtr = NULL;
2406 fcbBlock.ioVRefNum = 0;
2407 fcbBlock.ioRefNum = CurResFile();
2408 fcbBlock.ioFCBIndx = 0;
2409 err = PBGetFCBInfo(&fcbBlock, FALSE);
2413 sprintf(errString, "PBGetFCBInfo ¥¨¥é¡¼ #%d.\r ½ªÎ»¤·¤Þ¤¹.", err);
2415 sprintf(errString, "Fatal PBGetFCBInfo Error #%d.\r Exiting.", err);
2417 mac_warning(errString);
2421 /* Extract the Vol and Dir */
2422 app_vol = fcbBlock.ioFCBVRefNum;
2423 app_dir = fcbBlock.ioFCBParID;
2425 /* Set the current working directory to that location */
2426 err = HSetVol(NULL, app_vol, app_dir);
2430 sprintf(errString, "HSetVol ¥¨¥é¡¼ #%d.\r ½ªÎ»¤·¤Þ¤¹.", err);
2432 sprintf(errString, "Fatal HSetVol Error #%d.\r Exiting.", err);
2434 mac_warning(errString);
2443 * Global "preference" file pointer
2448 * Read a "short" from the file
2450 static int getshort(void)
2454 if (0 == my_fgets(fff, buf, sizeof(buf))) x = atoi(buf);
2459 * Dump a "short" to the file
2461 static void putshort(int x)
2463 fprintf(fff, "%d\n", x);
2469 * Write the "preference" data to the current "file"
2471 static void save_prefs(void)
2478 /*** The current version ***/
2480 putshort(FAKE_VERSION);
2481 putshort(FAKE_VER_MAJOR);
2482 putshort(FAKE_VER_MINOR);
2483 putshort(FAKE_VER_PATCH);
2485 putshort(arg_sound);
2486 putshort(arg_graphics);
2487 putshort(arg_newstyle_graphics);
2488 putshort(arg_bigtile);
2491 for( i = 0 ; i < 7 ; i++ )
2492 putshort(soundmode[i]);
2495 for (i = 0; i < MAX_TERM_DATA; i++)
2500 putshort(td->mapped);
2502 putshort(td->font_id);
2503 putshort(td->font_size);
2504 putshort(td->font_face);
2506 putshort(td->tile_wid);
2507 putshort(td->tile_hgt);
2512 putshort(td->r.left);
2513 putshort(td->r.top);
2519 * Load the preferences from the current "file"
2521 * XXX XXX XXX Being able to undefine various windows is
2522 * slightly bizarre, and may cause problems.
2524 static void load_prefs(void)
2528 int old_version, old_major, old_minor, old_patch;
2533 /*** Version information ***/
2535 /* Preferences version */
2536 old_version = getshort();
2537 old_major = getshort();
2538 old_minor = getshort();
2539 old_patch = getshort();
2541 /* Hack -- Verify or ignore */
2542 if ((old_version != FAKE_VERSION) ||
2543 (old_major != FAKE_VER_MAJOR) ||
2544 (old_minor != FAKE_VER_MINOR) ||
2545 (old_patch != FAKE_VER_PATCH))
2549 mac_warning("¸Å¤¤½é´üÀßÄê¥Õ¥¡¥¤¥ë¤ò̵»ë¤·¤Þ¤¹.");
2551 mac_warning("Ignoring old preferences.");
2557 arg_sound = getshort();
2558 arg_graphics = getshort();
2559 arg_newstyle_graphics = getshort();
2560 use_newstyle_graphics = arg_newstyle_graphics;
2562 if (use_newstyle_graphics == true)
2564 ANGBAND_GRAF = "new";
2565 arg_newstyle_graphics = true;
2566 grafWidth = grafHeight = 16;
2571 ANGBAND_GRAF = "old";
2572 arg_newstyle_graphics = false;
2573 grafWidth = grafHeight = 8;
2577 arg_bigtile = getshort();
2578 use_bigtile = arg_bigtile;
2581 for( i = 0 ; i < 7 ; i++ )
2582 soundmode[i] = getshort();
2585 m = GetMenuHandle(134);
2587 #if TARGET_API_MAC_CARBON
2588 /* Item "arg_sound" */
2589 CheckMenuItem(m, 1, arg_sound);
2591 /* Item "arg_graphics" */
2592 CheckMenuItem(m, 2, arg_graphics);
2594 /* Item "arg_newstyle_graphics"*/
2595 CheckMenuItem(m, 8, arg_newstyle_graphics);
2597 /* Item "arg_sound" */
2598 CheckItem(m, 1, arg_sound);
2600 /* Item "arg_graphics" */
2601 CheckItem(m, 2, arg_graphics);
2603 /* Item "arg_newstyle_graphics"*/
2604 CheckItem(m, 8, arg_newstyle_graphics);
2608 for (i = 0; i < MAX_TERM_DATA; i++)
2613 td->mapped = getshort();
2615 td->font_id = getshort();
2616 td->font_size = getshort();
2617 td->font_face = getshort();
2619 td->tile_wid = getshort();
2620 td->tile_hgt = getshort();
2622 td->cols = getshort();
2623 td->rows = getshort();
2625 td->r.left = getshort();
2626 td->r.top = getshort();
2629 if (feof(fff)) break;
2637 * Hack -- default data for a window
2639 static void term_data_hack(term_data *td)
2644 #if TARGET_API_MAC_CARBON
2645 /* Default to Osaka font (Japanese) */
2646 fid = FMGetFontFamilyFromName( "\pOsaka¡ÝÅùÉý" );
2648 GetFNum( "\pÅùÉýÌÀÄ«", &fid);
2649 SetFScaleDisable( true );
2652 /* Default to Monaco font */
2653 GetFNum("\pmonaco", &fid);
2657 WIPE(td, term_data);
2662 /* Default borders */
2673 /* Default font size */
2676 /* Default font face */
2683 /* Default position */
2693 * Read the preference file, Create the windows.
2695 * We attempt to use "FindFolder()" to track down the preference file,
2696 * but if this fails, for any reason, we will try the "SysEnvirons()"
2697 * method, which may work better with System 6.
2699 static void init_windows(void)
2712 /*** Default values ***/
2714 /* Initialize (backwards) */
2715 for (i = MAX_TERM_DATA - 1; i >= 0; i--)
2728 s = angband_term_name[i];
2733 /* Maximal length */
2736 /* Copy the title */
2737 strncpy((char*)(td->title) + 1, s, n);
2739 /* Save the length */
2742 /* Tile the windows */
2743 td->r.left += (b * 30);
2744 td->r.top += (b * 30);
2751 /*** Load preferences ***/
2753 /* Assume failure */
2756 /* Assume failure */
2769 /* Find the folder */
2770 err = FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder,
2776 /* Extract a path name */
2777 PathNameFromDirID(dirID, vref, (StringPtr)foo);
2779 /* Convert the string */
2780 ptocstr((StringPtr)foo);
2782 /* Append the preference file name */
2783 strcat(foo, PREF_FILE_NAME);
2785 /* Open the preference file */
2786 fff = fopen(foo, "r");
2793 #endif /* USE_SFL_CODE */
2795 #if TARGET_API_MAC_CARBON
2801 HGetVol(0, &savev, &saved);
2803 /* Go to the "system" folder */
2804 SysEnvirons(curSysEnvVers, &env);
2805 SetVol(0, env.sysVRefNum);
2808 fff = fopen(PREF_FILE_NAME, "r");
2811 HSetVol(0, savev, saved);
2815 /* Load preferences */
2818 /* Load a real preference file */
2821 /* Close the file */
2826 /*** Instantiate ***/
2837 /* Link (backwards, for stacking order) */
2838 for (i = MAX_TERM_DATA - 1; i >= 0; i--)
2847 Term_activate(td->t);
2850 static void init_sound( void )
2854 SignedByte permission = fsRdPerm;
2860 /* Descend into "lib" folder */
2861 pb.dirInfo.ioCompletion = NULL;
2862 pb.dirInfo.ioNamePtr = "\plib";
2863 pb.dirInfo.ioVRefNum = app_vol;
2864 pb.dirInfo.ioDrDirID = app_dir;
2865 pb.dirInfo.ioFDirIndex = 0;
2867 /* Check for errors */
2868 err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
2871 if ((err == noErr) && (pb.dirInfo.ioFlAttrib & 0x10))
2873 /* Descend into "lib/save" folder */
2874 pb.dirInfo.ioCompletion = NULL;
2875 pb.dirInfo.ioNamePtr = "\pxtra";
2876 pb.dirInfo.ioVRefNum = app_vol;
2877 pb.dirInfo.ioDrDirID = pb.dirInfo.ioDrDirID;
2878 pb.dirInfo.ioFDirIndex = 0;
2880 /* Check for errors */
2881 err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
2884 if ((err == noErr) && (pb.dirInfo.ioFlAttrib & 0x10))
2886 /* Descend into "lib/save" folder */
2887 pb.dirInfo.ioCompletion = NULL;
2888 pb.dirInfo.ioNamePtr = "\psound";
2889 pb.dirInfo.ioVRefNum = app_vol;
2890 pb.dirInfo.ioDrDirID = pb.dirInfo.ioDrDirID;
2891 pb.dirInfo.ioFDirIndex = 0;
2893 /* Check for errors */
2894 err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
2897 if ((err == noErr) && (pb.dirInfo.ioFlAttrib & 0x10))
2899 ret = HOpenResFile( app_vol , pb.dirInfo.ioDrDirID , "\psound.rsrc" , permission );
2903 for( i = 0 ; i < 7 ; i++ )
2904 soundmode[i] = false;
2906 for( i = 1 ; i < SOUND_MAX ; i++ ){
2907 /* Get the proper sound name */
2908 sprintf((char*)sound + 1, "%.16s.wav", angband_sound_name[i]);
2909 sound[0] = strlen((char*)sound + 1);
2911 /* Obtain resource XXX XXX XXX */
2912 handle = Get1NamedResource('snd ', sound);
2913 if( handle == NULL || ext_sound )
2914 handle = GetNamedResource('snd ', sound);
2917 soundmode[soundchoice[i]] = true;
2926 static void init_graf( void )
2930 SignedByte permission = fsRdPerm;
2936 /* Descend into "lib" folder */
2937 pb.dirInfo.ioCompletion = NULL;
2938 pb.dirInfo.ioNamePtr = "\plib";
2939 pb.dirInfo.ioVRefNum = app_vol;
2940 pb.dirInfo.ioDrDirID = app_dir;
2941 pb.dirInfo.ioFDirIndex = 0;
2943 /* Check for errors */
2944 err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
2947 if ((err == noErr) && (pb.dirInfo.ioFlAttrib & 0x10))
2949 /* Descend into "lib/xtra" folder */
2950 pb.dirInfo.ioCompletion = NULL;
2951 pb.dirInfo.ioNamePtr = "\pxtra";
2952 pb.dirInfo.ioVRefNum = app_vol;
2953 pb.dirInfo.ioDrDirID = pb.dirInfo.ioDrDirID;
2954 pb.dirInfo.ioFDirIndex = 0;
2956 /* Check for errors */
2957 err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
2960 if ((err == noErr) && (pb.dirInfo.ioFlAttrib & 0x10))
2962 /* Descend into "lib/xtra/graf" folder */
2963 pb.dirInfo.ioCompletion = NULL;
2964 pb.dirInfo.ioNamePtr = "\pgraf";
2965 pb.dirInfo.ioVRefNum = app_vol;
2966 pb.dirInfo.ioDrDirID = pb.dirInfo.ioDrDirID;
2967 pb.dirInfo.ioFDirIndex = 0;
2969 /* Check for errors */
2970 err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
2973 if ((err == noErr) && (pb.dirInfo.ioFlAttrib & 0x10))
2975 ret = HOpenResFile( app_vol , pb.dirInfo.ioDrDirID , "\pgraf.rsrc" , permission );
2980 /* Obtain resource XXX XXX XXX */
2981 handle = Get1NamedResource('PICT', graf);
2982 if ( handle == NULL || ext_graf )
2983 handle = GetNamedResource('PICT', "\pgraf.rsrc");
2994 static void init_chuukei( void )
3000 path_build(path, sizeof(path), ANGBAND_DIR_XTRA, "chuukei.txt");
3002 fp = fopen(path, "r");
3007 if (fgets(tmp, 1024, fp)){
3009 int n = strlen(tmp);
3015 chuukei_server = TRUE;
3016 if(connect_chuukei_server(&tmp[2])<0){
3017 msg_print("connect fail");
3020 msg_print("connect");
3027 chuukei_client = TRUE;
3028 connect_chuukei_server(&tmp[2]);
3044 short InevrtCheck( DialogPtr targetDlg, short check )
3051 GetDialogItem( targetDlg, check, &itemType, &checkH, &box );
3052 result = (GetControlValue( (ControlHandle)checkH ) + 1 ) % 2;
3053 SetControlValue( (ControlHandle)checkH , result );
3061 short SetCheck( DialogPtr targetDlg, short check, long result )
3068 GetDialogItem( targetDlg, check, &itemType, &checkH, &box );
3069 SetControlValue( (ControlHandle)checkH , result );
3077 short GetCheck( DialogPtr targetDlg, short check )
3084 GetDialogItem( targetDlg, check, &itemType, &checkH, &box );
3085 result = GetControlValue( (ControlHandle)checkH );
3089 void SoundConfigDLog(void)
3096 dialog=GetNewDialog(131, 0, (WindowPtr)-1);
3097 SetDialogDefaultItem( dialog, ok );
3098 SetDialogCancelItem( dialog, cancel );
3099 for( i = 1 ; i < 7 ; i++ )
3100 SetCheck( dialog, i+2 , soundmode[i] );
3102 /* ShowWindow(dialog); */
3103 for( item_hit = 100 ; cancel < item_hit ; ){
3104 ModalDialog(0, &item_hit);
3108 for( i = 1 ; i < 7 ; i++ )
3109 soundmode[i] = GetCheck( dialog, i+2 );
3114 InevrtCheck( dialog, item_hit );
3117 DisposeDialog(dialog);
3125 static void save_pref_file(void)
3134 /* Assume failure */
3137 /* Assume failure */
3154 /* Find the folder */
3155 err = FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder,
3161 /* Extract a path name */
3162 PathNameFromDirID(dirID, vref, (StringPtr)foo);
3164 /* Convert the string */
3165 ptocstr((StringPtr)foo);
3167 /* Append the preference file name */
3168 strcat(foo, PREF_FILE_NAME);
3170 /* Open the preference file */
3171 /* my_fopen set file type and file creator for MPW */
3172 fff = my_fopen(foo, "w");
3179 #endif /* USE_SFL_CODE */
3181 #if TARGET_API_MAC_CARBON
3187 HGetVol(0, &savev, &saved);
3189 /* Go to "system" folder */
3190 SysEnvirons(curSysEnvVers, &env);
3191 SetVol(0, env.sysVRefNum);
3193 /* Open the preference file */
3194 /* my_fopen set file type and file creator for MPW */
3195 fff = fopen(PREF_FILE_NAME, "w");
3198 HSetVol(0, savev, saved);
3202 /* Save preferences */
3205 /* Write the preferences */
3216 * A simple "Yes/No" filter to parse "key press" events in dialog windows
3218 static pascal Boolean ynfilter(DialogPtr dialog, EventRecord *event, short *ip)
3220 /* Parse key press events */
3221 if (event->what == keyDown)
3226 /* Extract the pressed key */
3227 c = (event->message & charCodeMask);
3229 /* Accept "no" and <return> and <enter> */
3230 if ((c=='n') || (c=='N') || (c==13) || (c==3)) i = 1;
3233 else if ((c=='y') || (c=='Y')) i = 2;
3235 /* Handle "yes" or "no" */
3239 ControlHandle control;
3242 /* Get the button */
3243 GetDialogItem(dialog, i, &type, (Handle*)&control, &r);
3245 /* Blink button for 1/10 second */
3246 HiliteControl(control, 1);
3247 Term_xtra_mac(TERM_XTRA_DELAY, 100);
3248 HiliteControl(control, 0);
3262 * Handle menu: "File" + "New"
3264 static void do_menu_file_new(void)
3269 /* Game is in progress */
3270 game_in_progress = 1;
3284 * Handle menu: "File" + "Open"
3286 #if TARGET_API_MAC_CARBON
3287 static void do_menu_file_open(bool all)
3301 refnum_to_name(path, app_dir, app_vol, (char*)("\plib:save:"));
3303 FSpLocationFromFullPath( strlen(path), path, &fsp );
3306 ChooseFile( (StringPtr)savefile, fsp );
3309 if (err != noErr) return;
3311 /* Extract textual file name for save file */
3312 /* GetWDInfo(reply.vRefNum, &vrefnum, &drefnum, &junk);
3313 refnum_to_name(savefile, drefnum, vrefnum, (char*)reply.fName);
3318 /* Game is in progress */
3319 game_in_progress = 1;
3331 static void do_menu_file_open(bool all)
3345 /* vrefnum = GetSFCurVol(); */
3346 vrefnum = -*((short*)0x214);
3348 /* drefnum = GetSFCurDir(); */
3349 drefnum = *((long*)0x398);
3351 /* Descend into "lib" folder */
3352 pb.ioCompletion = NULL;
3353 pb.ioNamePtr = "\plib";
3354 pb.ioVRefNum = vrefnum;
3355 pb.ioDrDirID = drefnum;
3358 /* Check for errors */
3359 err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
3362 if ((err == noErr) && (pb.ioFlAttrib & 0x10))
3364 /* Descend into "lib/save" folder */
3365 pb.ioCompletion = NULL;
3366 pb.ioNamePtr = "\psave";
3367 pb.ioVRefNum = vrefnum;
3368 pb.ioDrDirID = pb.ioDrDirID;
3371 /* Check for errors */
3372 err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
3375 if ((err == noErr) && (pb.ioFlAttrib & 0x10))
3377 /* SetSFCurDir(pb.ioDrDirID); */
3378 *((long*)0x398) = pb.ioDrDirID;
3382 /* Window location */
3383 topleft.h = (qd.screenBits.bounds.left+qd.screenBits.bounds.right)/2-344/2;
3384 topleft.v = (2*qd.screenBits.bounds.top+qd.screenBits.bounds.bottom)/3-188/2;
3386 /* Allow "all" files */
3390 SFGetFile(topleft, "\p", NULL, -1, types, NULL, &reply);
3393 /* Allow "save" files */
3400 SFGetFile(topleft, "\p", NULL, 1, types, NULL, &reply);
3404 if (!reply.good) return;
3406 /* Extract textual file name for save file */
3407 GetWDInfo(reply.vRefNum, &vrefnum, &drefnum, &junk);
3408 refnum_to_name(savefile, drefnum, vrefnum, (char*)reply.fName);
3413 /* Game is in progress */
3414 game_in_progress = 1;
3429 * Handle the "open_when_ready" flag
3431 static void handle_open_when_ready(void)
3433 /* Check the flag XXX XXX XXX make a function for this */
3434 if (open_when_ready && initialized && !game_in_progress)
3437 open_when_ready = FALSE;
3439 /* Game is in progress */
3440 game_in_progress = 1;
3459 * Initialize the menus
3461 * Verify menus 128, 129, 130
3462 * Create menus 131, 132, 133, 134
3464 * The standard menus are:
3466 * Apple (128) = { About, -, ... }
3467 * File (129) = { New,Open,Import,Close,Save,-,Exit,Quit }
3468 * Edit (130) = { Cut, Copy, Paste, Clear } (?)
3469 * Font (131) = { Bold, Extend, -, Monaco, ..., -, ... }
3470 * Size (132) = { ... }
3471 * Window (133) = { Angband, Mirror, Recall, Choice,
3472 * Term-4, Term-5, Term-6, Term-7 }
3473 * Special (134) = { arg_sound, arg_graphics, -,
3474 * arg_fiddle, arg_wizard }
3476 static void init_menubar(void)
3488 /* Get the "apple" menu */
3491 /* Insert the menu */
3494 /* Add the DA's to the "apple" menu */
3495 #if TARGET_API_MAC_CARBON
3497 AppendResMenu (m, 'DRVR');
3500 /* Get the "File" menu */
3501 #if TARGET_API_MAC_CARBON
3503 err = Gestalt( gestaltSystemVersion, &response );
3504 if ( (err == noErr) && (response >= 0x00000A00) )
3506 DeleteMenuItem( m, 7 );
3512 /* Insert the menu */
3516 /* Get the "Edit" menu */
3519 /* Insert the menu */
3523 /* Make the "Font" menu */
3525 m = NewMenu(131, "\p¥Õ¥©¥ó¥È");
3527 m = NewMenu(131, "\pFont");
3530 /* Insert the menu */
3534 AppendMenu(m, "\pBold");
3537 AppendMenu(m, "\pWide");
3539 /* Add a separator */
3540 AppendMenu(m, "\p-");
3543 r.left = r.right = r.top = r.bottom = 0;
3545 /* Make the fake window */
3546 tmpw = NewWindow(0, &r, "\p", false, documentProc, 0, 0, 0);
3548 /* Activate the "fake" window */
3549 #if TARGET_API_MAC_CARBON
3550 SetPortWindowPort(tmpw);
3561 /* Add the fonts to the menu */
3562 AppendResMenu(m, 'FONT');
3565 #if TARGET_API_MAC_CARBON
3566 n = CountMenuItems(m);
3572 for (i = n; i >= 4; i--)
3577 /* Acquire the font name */
3578 GetMenuItemText(m, i, tmpName);
3580 /* Acquire the font index */
3581 #if TARGET_API_MAC_CARBON
3582 fontNum = FMGetFontFamilyFromName( tmpName );
3584 GetFNum(tmpName, &fontNum);
3587 /* Apply the font index */
3590 /* Remove non-mono-spaced fonts */
3591 if ((CharWidth('i') != CharWidth('W')) || (CharWidth('W') == 0))
3593 /* Delete the menu item XXX XXX XXX */
3594 DeleteMenuItem (m, i);
3598 /* Destroy the old window */
3599 DisposeWindow(tmpw);
3601 /* Add a separator */
3602 AppendMenu(m, "\p-");
3604 /* Add the fonts to the menu */
3605 AppendResMenu (m, 'FONT');
3608 /* Make the "Size" menu */
3610 m = NewMenu(132, "\p¥µ¥¤¥º");
3612 m = NewMenu(132, "\pSize");
3615 /* Insert the menu */
3618 /* Add some sizes (stagger choices) */
3619 for (i = 8; i <= 32; i += ((i / 16) + 1))
3624 sprintf((char*)buf + 1, "%d", i);
3625 buf[0] = strlen((char*)buf + 1);
3632 /* Make the "Windows" menu */
3634 m = NewMenu(133, "\p¥¦¥¤¥ó¥É¥¦");
3636 m = NewMenu(133, "\pWindows");
3639 /* Insert the menu */
3642 /* Default choices */
3643 for (i = 0; i < MAX_TERM_DATA; i++)
3647 /* Describe the item */
3648 sprintf((char*)buf + 1, "%.15s", angband_term_name[i]);
3649 buf[0] = strlen((char*)buf + 1);
3654 /* Command-Key shortcuts */
3655 if (i < 8) SetItemCmd(m, i + 1, '0' + i);
3659 /* Make the "Special" menu */
3661 m = NewMenu(134, "\pÆÃÊÌ");
3663 m = NewMenu(134, "\pSpecial");
3666 /* Insert the menu */
3669 /* Append the choices */
3671 AppendMenu(m, "\p¥µ¥¦¥ó¥É»ÈÍÑ");
3672 AppendMenu(m, "\p¥°¥é¥Õ¥£¥Ã¥¯»ÈÍÑ");
3673 AppendMenu(m, "\p-");
3674 AppendMenu(m, "\parg_fiddle");
3675 AppendMenu(m, "\parg_wizard");
3676 AppendMenu(m, "\p-");
3677 AppendMenu(m, "\p¥µ¥¦¥ó¥ÉÀßÄê...");
3678 AppendMenu(m, "\p16X16¥°¥é¥Õ¥£¥Ã¥¯");
3679 AppendMenu(m, "\p£²ÇÜÉý¥¿¥¤¥ëɽ¼¨");
3681 AppendMenu(m, "\parg_sound");
3682 AppendMenu(m, "\parg_graphics");
3683 AppendMenu(m, "\p-");
3684 AppendMenu(m, "\parg_fiddle");
3685 AppendMenu(m, "\parg_wizard");
3686 AppendMenu(m, "\p-");
3687 AppendMenu(m, "\pSound config");
3688 AppendMenu(m, "\pAdam Bolt tile");
3689 AppendMenu(m, "\pBigtile Mode");
3692 /* Make the "TileWidth" menu */
3694 m = NewMenu(135, "\p¥¿¥¤¥ëÉý");
3696 m = NewMenu(135, "\pTileWidth");
3699 /* Insert the menu */
3702 /* Add some sizes */
3703 for (i = 4; i <= 32; i++)
3708 sprintf((char*)buf + 1, "%d", i);
3709 buf[0] = strlen((char*)buf + 1);
3716 /* Make the "TileHeight" menu */
3718 m = NewMenu(136, "\p¥¿¥¤¥ë¹â");
3720 m = NewMenu(136, "\pTileHeight");
3723 /* Insert the menu */
3726 /* Add some sizes */
3727 for (i = 4; i <= 32; i++)
3732 sprintf((char*)buf + 1, "%d", i);
3733 buf[0] = strlen((char*)buf + 1);
3740 /* Update the menu bar */
3748 static void setup_menus(void)
3758 term_data *td = NULL;
3761 /* Relevant "term_data" */
3762 for (i = 0; i < MAX_TERM_DATA; i++)
3765 if (!data[i].t) continue;
3767 /* Notice the matching window */
3768 if (data[i].w == FrontWindow()) td = &data[i];
3773 m = GetMenuHandle(129);
3776 #if TARGET_API_MAC_CARBON
3777 n = CountMenuItems(m);
3783 for (i = 1; i <= n; i++)
3786 #if TARGET_API_MAC_CARBON
3787 DisableMenuItem(m, i);
3788 CheckMenuItem(m, i, FALSE);
3791 CheckItem(m, i, FALSE);
3795 /* Enable "new"/"open..."/"import..." */
3796 if (initialized && !game_in_progress)
3798 #if TARGET_API_MAC_CARBON
3799 EnableMenuItem(m, 1);
3800 EnableMenuItem(m, 2);
3801 EnableMenuItem(m, 3);
3809 /* Enable "close" */
3812 #if TARGET_API_MAC_CARBON
3813 EnableMenuItem(m, 4);
3820 if (initialized && character_generated)
3822 #if TARGET_API_MAC_CARBON
3823 EnableMenuItem(m, 5);
3832 #if TARGET_API_MAC_CARBON
3833 EnableMenuItem(m, 7);
3841 m = GetMenuHandle(130);
3844 #if TARGET_API_MAC_CARBON
3845 n = CountMenuItems(m);
3851 for (i = 1; i <= n; i++)
3854 #if TARGET_API_MAC_CARBON
3855 DisableMenuItem(m, i);
3856 CheckMenuItem(m, i, FALSE);
3859 CheckItem(m, i, FALSE);
3863 /* Enable "edit" options if "needed" */
3866 #if TARGET_API_MAC_CARBON
3867 EnableMenuItem(m, 1);
3868 EnableMenuItem(m, 3);
3869 EnableMenuItem(m, 4);
3870 EnableMenuItem(m, 5);
3871 EnableMenuItem(m, 6);
3883 m = GetMenuHandle(131);
3886 #if TARGET_API_MAC_CARBON
3887 n = CountMenuItems(m);
3893 for (i = 1; i <= n; i++)
3896 #if TARGET_API_MAC_CARBON
3897 DisableMenuItem(m, i);
3898 CheckMenuItem(m, i, FALSE);
3901 CheckItem(m, i, FALSE);
3905 /* Hack -- look cute XXX XXX */
3906 /* SetItemStyle(m, 1, bold); */
3908 /* Hack -- look cute XXX XXX */
3909 /* SetItemStyle(m, 2, extend); */
3914 #if TARGET_API_MAC_CARBON
3916 EnableMenuItem(m, 1);
3918 /* Enable "extend" */
3919 EnableMenuItem(m, 2);
3921 /* Check the appropriate "bold-ness" */
3922 if (td->font_face & bold) CheckMenuItem(m, 1, TRUE);
3924 /* Check the appropriate "wide-ness" */
3925 if (td->font_face & extend) CheckMenuItem(m, 2, TRUE);
3928 for (i = 4; i <= n; i++)
3931 EnableMenuItem(m, i);
3934 GetMenuItemText(m, i, s);
3937 /* Check active font */
3938 if (td->font_id == value) CheckMenuItem(m, i, TRUE);
3944 /* Enable "extend" */
3947 /* Check the appropriate "bold-ness" */
3948 if (td->font_face & bold) CheckItem(m, 1, TRUE);
3950 /* Check the appropriate "wide-ness" */
3951 if (td->font_face & extend) CheckItem(m, 2, TRUE);
3954 for (i = 4; i <= n; i++)
3960 GetMenuItemText(m, i, s);
3963 /* Check active font */
3964 if (td->font_id == value) CheckItem(m, i, TRUE);
3971 m = GetMenuHandle(132);
3974 #if TARGET_API_MAC_CARBON
3975 n = CountMenuItems(m);
3981 for (i = 1; i <= n; i++)
3984 #if TARGET_API_MAC_CARBON
3985 DisableMenuItem(m, i);
3986 CheckMenuItem(m, i, FALSE);
3989 CheckItem(m, i, FALSE);
3997 for (i = 1; i <= n; i++)
3999 #if TARGET_API_MAC_CARBON
4001 GetMenuItemText(m, i, s);
4003 value = atoi((char*)(s+1));
4005 /* Enable the "real" sizes */
4006 if (RealFont(td->font_id, value)) EnableMenuItem(m, i);
4008 /* Check the current size */
4009 if (td->font_size == value) CheckMenuItem(m, i, TRUE);
4012 GetMenuItemText(m, i, s);
4014 value = atoi((char*)(s+1));
4016 /* Enable the "real" sizes */
4017 if (RealFont(td->font_id, value)) EnableItem(m, i);
4019 /* Check the current size */
4020 if (td->font_size == value) CheckItem(m, i, TRUE);
4027 m = GetMenuHandle(133);
4030 #if TARGET_API_MAC_CARBON
4031 n = CountMenuItems(m);
4036 /* Check active windows */
4037 for (i = 1; i <= n; i++)
4039 /* Check if needed */
4040 #if TARGET_API_MAC_CARBON
4041 CheckMenuItem(m, i, data[i-1].mapped);
4043 CheckItem(m, i, data[i-1].mapped);
4049 m = GetMenuHandle(134);
4052 #if TARGET_API_MAC_CARBON
4053 n = CountMenuItems(m);
4059 for (i = 1; i <= n; i++)
4062 #if TARGET_API_MAC_CARBON
4063 DisableMenuItem(m, i);
4064 CheckMenuItem(m, i, FALSE);
4067 CheckItem(m, i, FALSE);
4071 #if TARGET_API_MAC_CARBON
4072 /* Item "arg_sound" */
4073 EnableMenuItem(m, 1);
4074 CheckMenuItem(m, 1, arg_sound);
4076 /* Item "arg_graphics" */
4077 EnableMenuItem(m, 2);
4078 CheckMenuItem(m, 2, arg_graphics);
4080 /* Item "arg_fiddle" */
4081 EnableMenuItem(m, 4);
4082 CheckMenuItem(m, 4, arg_fiddle);
4084 /* Item "arg_wizard" */
4085 EnableMenuItem(m, 5);
4086 CheckMenuItem(m, 5, arg_wizard);
4088 /* Item "SoundSetting" */
4089 EnableMenuItem(m, 7);
4091 /* Item NewStyle Graphics */
4092 EnableMenuItem(m, 8);
4093 CheckMenuItem(m, 8, use_newstyle_graphics);
4095 /* Item Bigtile Mode */
4096 EnableMenuItem(m, 9);
4097 CheckMenuItem(m, 9, arg_bigtile);
4099 /* Item "arg_sound" */
4101 CheckItem(m, 1, arg_sound);
4103 /* Item "arg_graphics" */
4105 CheckItem(m, 2, arg_graphics);
4107 /* Item "arg_fiddle" */
4109 CheckItem(m, 4, arg_fiddle);
4111 /* Item "arg_wizard" */
4113 CheckItem(m, 5, arg_wizard);
4115 /* Item "SoundSetting" */
4118 /* Item NewStyle Graphics */
4120 CheckItem(m, 8, use_newstyle_graphics);
4122 /* Item Bigtile Mode */
4124 CheckItem(m, 9, arg_bigtile);
4127 /* TileWidth menu */
4128 m = GetMenuHandle(135);
4131 #if TARGET_API_MAC_CARBON
4132 n = CountMenuItems(m);
4138 for (i = 1; i <= n; i++)
4141 #if TARGET_API_MAC_CARBON
4142 DisableMenuItem(m, i);
4143 CheckMenuItem(m, i, FALSE);
4146 CheckItem(m, i, FALSE);
4154 for (i = 1; i <= n; i++)
4157 /* GetMenuItemText(m,i,s); */
4158 GetMenuItemText(m, i, s);
4160 value = atoi((char*)(s+1));
4162 #if TARGET_API_MAC_CARBON
4164 EnableMenuItem(m, i);
4166 /* Check the current size */
4167 if (td->tile_wid == value) CheckMenuItem(m, i, TRUE);
4172 /* Check the current size */
4173 if (td->tile_wid == value) CheckItem(m, i, TRUE);
4179 /* TileHeight menu */
4180 m = GetMenuHandle(136);
4183 #if TARGET_API_MAC_CARBON
4184 n = CountMenuItems(m);
4190 for (i = 1; i <= n; i++)
4193 #if TARGET_API_MAC_CARBON
4194 DisableMenuItem(m, i);
4195 CheckMenuItem(m, i, FALSE);
4198 CheckItem(m, i, FALSE);
4206 for (i = 1; i <= n; i++)
4209 GetMenuItemText(m, i, s);
4211 value = atoi((char*)(s+1));
4213 #if TARGET_API_MAC_CARBON
4215 EnableMenuItem(m, i);
4217 /* Check the current size */
4218 if (td->tile_hgt == value) CheckMenuItem(m, i, TRUE);
4223 /* Check the current size */
4224 if (td->tile_hgt == value) CheckItem(m, i, TRUE);
4232 * Process a menu selection (see above)
4234 * Hack -- assume that invalid menu selections are disabled above,
4235 * which I have been informed may not be reliable. XXX XXX XXX
4237 static void menu(long mc)
4241 int menuid, selection;
4243 static unsigned char s[1000];
4247 term_data *td = NULL;
4252 /* Analyze the menu command */
4253 menuid = HiWord(mc);
4254 selection = LoWord(mc);
4257 /* Find the window */
4258 for (i = 0; i < MAX_TERM_DATA; i++)
4260 /* Skip dead windows */
4261 if (!data[i].t) continue;
4263 /* Notice matches */
4264 if (data[i].w == FrontWindow()) td = &data[i];
4268 /* Branch on the menu */
4274 /* About Angband... */
4275 #if TARGET_API_MAC_CARBON
4281 /* Get the about dialogue */
4282 dialog=GetNewDialog(128, 0, (WindowPtr)-1);
4284 /* Move it to the middle of the screen */
4286 GetDialogWindow(dialog),
4288 kWindowCenterOnMainScreen);
4290 /* Show the dialog */
4291 TransitionWindow(GetDialogWindow(dialog),
4292 kWindowZoomTransitionEffect,
4293 kWindowShowTransitionAction,
4296 /* Wait for user to click on it */
4297 ModalDialog(0, &item_hit);
4299 /* Free the dialogue */
4300 DisposeDialog(dialog);
4310 dialog=GetNewDialog(128, 0, (WindowPtr)-1);
4313 center_rect(&r, &qd.screenBits.bounds);
4314 MoveWindow(dialog, r.left, r.top, 1);
4316 ModalDialog(0, &item_hit);
4317 DisposeDialog(dialog);
4321 /* Desk accessory */
4322 /* GetMenuItemText(GetMHandle(128),selection,s); */
4323 GetMenuItemText(GetMenuHandle(128), selection, s);
4344 do_menu_file_open(FALSE);
4351 do_menu_file_open(TRUE);
4365 td->t->mapped_flag = FALSE;
4367 /* Hide the window */
4378 plog("º£¤Ï¥»¡¼¥Ö¤¹¤ë¤³¤È¤Ï½ÐÍè¤Þ¤»¤ó¡£");
4380 plog("You may not do that right now.");
4385 /* Hack -- Forget messages */
4388 /* Hack -- Save the game */
4389 do_cmd_save_game(FALSE);
4394 /* Quit (with save) */
4397 /* Save the game (if necessary) */
4398 if (game_in_progress && character_generated)
4402 plog("º£¤Ï¥»¡¼¥Ö¤¹¤ë¤³¤È¤Ï½ÐÍè¤Þ¤»¤ó¡£");
4404 plog("You may not do that right now.");
4408 /* Hack -- Forget messages */
4413 do_cmd_save_game(FALSE);
4415 Term_key_push(SPECIAL_KEY_QUIT);
4437 /* Require a window */
4446 /* Toggle the "bold" setting */
4449 /* Toggle the setting */
4450 if (td->font_face & bold)
4452 td->font_face &= ~bold;
4456 td->font_face |= bold;
4459 /* Tile Width Hight Init */
4460 td->tile_wid = td->tile_hgt = 0;
4462 /* Apply and Verify */
4463 term_data_check_font(td);
4464 term_data_check_size(td);
4466 /* Resize and Redraw */
4467 term_data_resize(td);
4468 term_data_redraw(td);
4473 /* Toggle the "wide" setting */
4476 /* Toggle the setting */
4477 if (td->font_face & extend)
4479 td->font_face &= ~extend;
4483 td->font_face |= extend;
4486 /* Tile Width Hight Init */
4487 td->tile_wid = td->tile_hgt = 0;
4489 /* Apply and Verify */
4490 term_data_check_font(td);
4491 term_data_check_size(td);
4493 /* Resize and Redraw */
4494 term_data_resize(td);
4495 term_data_redraw(td);
4500 /* Get a new font name */
4501 GetMenuItemText(GetMenuHandle(131), selection, s);
4504 /* Save the new font id */
4507 /* Current size is bad for new font */
4508 if (!RealFont(td->font_id, td->font_size))
4510 /* Find similar size */
4511 for (i = 1; i <= 32; i++)
4513 /* Adjust smaller */
4514 if (td->font_size - i >= 8)
4516 if (RealFont(td->font_id, td->font_size - i))
4524 if (td->font_size + i <= 128)
4526 if (RealFont(td->font_id, td->font_size + i))
4535 /* Tile Width Hight Init */
4536 td->tile_wid = td->tile_hgt = 0;
4538 /* Apply and Verify */
4539 term_data_check_font(td);
4540 term_data_check_size(td);
4542 /* Resize and Redraw */
4543 term_data_resize(td);
4544 term_data_redraw(td);
4546 /* Restore the window */
4563 GetMenuItemText(GetMenuHandle(132), selection, s);
4565 td->font_size = atoi((char*)(s+1));
4567 /* Tile Width Hight Init */
4568 td->tile_wid = td->tile_hgt = 0;
4570 /* Apply and Verify */
4571 term_data_check_font(td);
4572 term_data_check_size(td);
4574 /* Resize and Redraw */
4575 term_data_resize(td);
4576 term_data_redraw(td);
4590 /* Check legality of choice */
4591 if ((i < 0) || (i >= MAX_TERM_DATA)) break;
4593 /* Obtain the window */
4603 td->t->mapped_flag = TRUE;
4605 /* Show the window */
4608 /* Bring to the front */
4609 SelectWindow(td->w);
4621 /* Toggle arg_sound */
4622 arg_sound = !arg_sound;
4624 /* React to changes */
4625 Term_xtra(TERM_XTRA_REACT, 0);
4632 /* Toggle arg_graphics */
4633 arg_graphics = !arg_graphics;
4634 if( arg_graphics == true ){
4635 ANGBAND_GRAF = "old";
4636 arg_newstyle_graphics = false;
4637 grafWidth = grafHeight = 8;
4641 /* Hack -- Force redraw */
4642 Term_key_push(KTRL('R'));
4649 arg_fiddle = !arg_fiddle;
4655 arg_wizard = !arg_wizard;
4666 if (streq(ANGBAND_GRAF, "old"))
4668 ANGBAND_GRAF = "new";
4669 arg_newstyle_graphics = true;
4670 grafWidth = grafHeight = 16;
4675 ANGBAND_GRAF = "old";
4676 arg_newstyle_graphics = false;
4677 grafWidth = grafHeight = 8;
4681 /* Hack -- Force redraw */
4682 Term_key_push(KTRL('R'));
4686 case 9: /* bigtile mode */
4688 term_data *td = &data[0];
4692 plog("º£¤ÏÊѹ¹½ÐÍè¤Þ¤»¤ó¡£");
4694 plog("You may not do that right now.");
4699 /* Toggle "arg_bigtile" */
4700 arg_bigtile = !arg_bigtile;
4703 Term_activate(td->t);
4705 /* Resize the term */
4706 Term_resize(td->cols, td->rows);
4716 /* TileWidth menu */
4727 GetMenuItemText(GetMenuHandle(135), selection, s);
4729 td->tile_wid = atoi((char*)(s+1));
4731 /* Apply and Verify */
4732 term_data_check_size(td);
4734 /* Resize and Redraw */
4735 term_data_resize(td);
4736 term_data_redraw(td);
4744 /* TileHeight menu */
4755 GetMenuItemText(GetMenuHandle(136), selection, s);
4757 td->tile_hgt = atoi((char*)(s+1));
4759 /* Apply and Verify */
4760 term_data_check_size(td);
4762 /* Resize and Redraw */
4763 term_data_resize(td);
4764 term_data_redraw(td);
4774 /* Clean the menu */
4783 * Check for extra required parameters -- From "Maarten Hazewinkel"
4785 static OSErr CheckRequiredAEParams(const AppleEvent *theAppleEvent)
4788 DescType returnedType;
4791 aeError = AEGetAttributePtr(theAppleEvent, keyMissedKeywordAttr, typeWildCard,
4792 &returnedType, NULL, 0, &actualSize);
4794 if (aeError == errAEDescNotFound) return (noErr);
4796 if (aeError == noErr) return (errAEParamMissed);
4803 * Apple Event Handler -- Open Application
4805 static pascal OSErr AEH_Start(const AppleEvent *theAppleEvent,
4806 AppleEvent *reply, long handlerRefCon)
4808 #pragma unused(reply, handlerRefCon)
4810 return (CheckRequiredAEParams(theAppleEvent));
4815 * Apple Event Handler -- Quit Application
4817 static pascal OSErr AEH_Quit(const AppleEvent *theAppleEvent,
4818 AppleEvent *reply, long handlerRefCon)
4820 #pragma unused(reply, handlerRefCon)
4821 #if TARGET_API_MAC_CARBON
4823 /* Save the game (if necessary) */
4824 if (game_in_progress && character_generated)
4828 plog("º£¤Ï¥»¡¼¥Ö¤¹¤ë¤³¤È¤Ï½ÐÍè¤Þ¤»¤ó¡£");
4830 plog("You may not do that right now.");
4834 /* Hack -- Forget messages */
4839 do_cmd_save_game(FALSE);
4841 Term_key_push(SPECIAL_KEY_QUIT);
4849 quit_when_ready = TRUE;
4851 /* Check arguments */
4852 return (CheckRequiredAEParams(theAppleEvent));
4858 * Apple Event Handler -- Print Documents
4860 static pascal OSErr AEH_Print(const AppleEvent *theAppleEvent,
4861 AppleEvent *reply, long handlerRefCon)
4863 #pragma unused(theAppleEvent, reply, handlerRefCon)
4865 return (errAEEventNotHandled);
4870 * Apple Event Handler by Steve Linberg (slinberg@crocker.com).
4872 * The old method of opening savefiles from the finder does not work
4873 * on the Power Macintosh, because CountAppFiles and GetAppFiles,
4874 * used to return information about the selected document files when
4875 * an application is launched, are part of the Segment Loader, which
4876 * is not present in the RISC OS due to the new memory architecture.
4878 * The "correct" way to do this is with AppleEvents. The following
4879 * code is modeled on the "Getting Files Selected from the Finder"
4880 * snippet from Think Reference 2.0. (The prior sentence could read
4881 * "shamelessly swiped & hacked")
4883 static pascal OSErr AEH_Open(const AppleEvent *theAppleEvent,
4884 AppleEvent* reply, long handlerRefCon)
4886 #pragma unused(reply, handlerRefCon)
4893 DescType returnedType;
4897 /* Put the direct parameter (a descriptor list) into a docList */
4898 err = AEGetParamDesc(theAppleEvent, keyDirectObject, typeAEList, &docList);
4899 if (err) return err;
4902 * We ignore the validity check, because we trust the FInder, and we only
4903 * allow one savefile to be opened, so we ignore the depth of the list.
4906 err = AEGetNthPtr(&docList, 1L, typeFSS, &keywd,
4907 &returnedType, (Ptr) &myFSS, sizeof(myFSS), &actualSize);
4908 if (err) return err;
4910 /* Only needed to check savefile type below */
4911 err = FSpGetFInfo(&myFSS, &myFileInfo);
4914 sprintf(foo, "Arg! FSpGetFInfo failed with code %d", err);
4919 /* Ignore non 'SAVE' files */
4920 if (myFileInfo.fdType != 'SAVE') return noErr;
4922 /* XXX XXX XXX Extract a file name */
4923 PathNameFromDirID(myFSS.parID, myFSS.vRefNum, (StringPtr)savefile);
4924 pstrcat((StringPtr)savefile, (StringPtr)&myFSS.name);
4926 /* Convert the string */
4927 ptocstr((StringPtr)savefile);
4929 /* Delay actual open */
4930 open_when_ready = TRUE;
4933 err = AEDisposeDesc(&docList);
4945 * Macintosh modifiers (event.modifier & ccc):
4946 * cmdKey, optionKey, shiftKey, alphaLock, controlKey
4949 * Macintosh Keycodes (0-63 normal, 64-95 keypad, 96-127 extra):
4994 * Optimize non-blocking calls to "CheckEvents()"
4995 * Idea from "Maarten Hazewinkel <mmhazewi@cs.ruu.nl>"
4997 #define EVENT_TICKS 6
5001 * Check for Events, return TRUE if we process any
5003 * Hack -- Handle AppleEvents if appropriate (ignore result code).
5005 static bool CheckEvents(bool wait)
5021 term_data *td = NULL;
5025 static huge lastTicks = 0L;
5028 /* Access the clock */
5029 curTicks = TickCount();
5031 /* Hack -- Allow efficient checking for non-pending events */
5032 if (!wait && (curTicks < lastTicks + EVENT_TICKS)) return (FALSE);
5034 /* Timestamp last check */
5035 lastTicks = curTicks;
5037 #if TARGET_API_MAC_CARBON
5038 WaitNextEvent( everyEvent, &event, 1L, nil );
5040 /* Let the "system" run */
5043 /* Get an event (or null) */
5044 GetNextEvent(everyEvent, &event);
5047 /* Hack -- Nothing is ready yet */
5048 if (event.what == nullEvent) return (FALSE);
5050 /* Analyze the event */
5058 w = (WindowPtr)event.message;
5069 /* Extract the window */
5070 w = (WindowPtr)event.message;
5072 /* Find the window */
5073 for (i = 0; i < MAX_TERM_DATA; i++)
5075 /* Skip dead windows */
5076 if (!data[i].t) continue;
5078 /* Notice matches */
5079 if (data[i].w == w) td = &data[i];
5082 /* Hack XXX XXX XXX */
5086 /* Redraw the window */
5087 if (td) term_data_redraw(td);
5095 /* Extract some modifiers */
5096 mc = (event.modifiers & controlKey) ? TRUE : FALSE;
5097 ms = (event.modifiers & shiftKey) ? TRUE : FALSE;
5098 mo = (event.modifiers & optionKey) ? TRUE : FALSE;
5099 mx = (event.modifiers & cmdKey) ? TRUE : FALSE;
5101 /* Keypress: (only "valid" if ck < 96) */
5102 ch = (event.message & charCodeMask) & 255;
5104 /* Keycode: see table above */
5105 ck = ((event.message & keyCodeMask) >> 8) & 255;
5107 /* Command + "normal key" -> menu action */
5108 if (mx && (ck < 64))
5110 /* Hack -- Prepare the menus */
5113 /* Run the Menu-Handler */
5116 /* Turn off the menus */
5124 /* Hide the mouse pointer */
5127 /* Normal key -> simple keypress */
5130 /* Enqueue the keypress */
5134 /* Bizarre key -> encoded keypress */
5137 /* Hack -- introduce with control-underscore */
5140 /* Send some modifier keys */
5141 if (mc) Term_keypress('C');
5142 if (ms) Term_keypress('S');
5143 if (mo) Term_keypress('O');
5144 if (mx) Term_keypress('X');
5146 /* Hack -- Downshift and encode the keycode */
5147 Term_keypress('0' + (ck - 64) / 10);
5148 Term_keypress('0' + (ck - 64) % 10);
5150 /* Hack -- Terminate the sequence */
5151 /* MPW can generate 10 or 13 for keycode of '\r' */
5152 /* -noMapCR option swaps '\r' and '\n' */
5153 Term_keypress('\r');
5163 /* Analyze click location */
5164 code = FindWindow(event.where, &w);
5166 /* Find the window */
5167 for (i = 0; i < MAX_TERM_DATA; i++)
5169 /* Skip dead windows */
5170 if (!data[i].t) continue;
5172 /* Notice matches */
5173 if (data[i].w == w) td = &data[i];
5182 menu(MenuSelect(event.where));
5186 #if !TARGET_API_MAC_CARBON
5189 SystemClick(&event, w);
5201 #if TARGET_API_MAC_CARBON
5202 GetQDGlobalsScreenBits( &screen );
5204 screen = qd.screenBits;
5207 r.top += 20; /* GetMBarHeight() XXX XXX XXX */
5208 InsetRect(&r, 4, 4);
5209 DragWindow(w, event.where, &r);
5221 #if TARGET_API_MAC_CARBON
5222 GetWindowBounds( (WindowRef)td->w, kWindowContentRgn, &portRect );
5224 portRect = td->w->portRect;
5225 local_to_global( &portRect );
5227 p.h = portRect.left;
5229 #if !TARGET_API_MAC_CARBON
5238 /* Apply and Verify */
5239 term_data_check_size(td);
5249 /* Track the go-away box */
5250 if (TrackGoAway(w, event.where))
5256 td->t->mapped_flag = FALSE;
5258 /* Hide the window */
5272 #if TARGET_API_MAC_CARBON
5273 GetQDGlobalsScreenBits( &screen );
5275 screen = qd.screenBits;
5280 /* Fake rectangle */
5281 r.left = 20 * td->tile_wid + td->size_ow1;
5282 r.right = screen.bounds.right;
5283 r.top = 1 * td->tile_hgt + td->size_oh1;
5284 r.bottom = screen.bounds.bottom;
5286 /* Grow the rectangle */
5287 newsize = GrowWindow(w, event.where, &r);
5290 if (!newsize) break;
5292 /* Extract the new size in pixels */
5293 y = HiWord(newsize) - td->size_oh1 - td->size_oh2;
5294 x = LoWord(newsize) - td->size_ow1 - td->size_ow2;
5296 /* Extract a "close" approximation */
5297 td->rows = y / td->tile_hgt;
5298 td->cols = x / td->tile_wid;
5300 /* Apply and Verify */
5301 term_data_check_size(td);
5303 Term_activate(td->t);
5305 /* Hack -- Resize the term */
5306 Term_resize(td->cols, td->rows);
5308 /* Resize and Redraw */
5309 term_data_resize(td);
5310 term_data_redraw(td);
5329 /* Disk Event -- From "Maarten Hazewinkel" */
5333 #if TARGET_API_MAC_CARBON
5335 /* check for error when mounting the disk */
5336 if (HiWord(event.message) != noErr)
5342 DIBadMount(p, event.message);
5349 /* OS Event -- From "Maarten Hazewinkel" */
5352 switch ((event.message >> 24) & 0x000000FF)
5354 case suspendResumeMessage:
5356 /* Resuming: activate the front window */
5357 if (event.message & resumeFlag)
5359 #if TARGET_API_MAC_CARBON
5362 SetPortWindowPort( FrontWindow() );
5364 GetQDGlobalsArrow( &arrow );
5367 SetPort(FrontWindow());
5368 SetCursor(&qd.arrow);
5372 /* Suspend: deactivate the front window */
5386 /* From "Steve Linberg" and "Maarten Hazewinkel" */
5387 case kHighLevelEvent:
5389 #if TARGET_API_MAC_CARBON
5390 AEProcessAppleEvent(&event);
5392 /* Process apple events */
5393 if (AEProcessAppleEvent(&event) != noErr)
5396 plog("Apple Event Handler¤Î¥¨¥é¡¼¤Ç¤¹.");
5398 plog("Error in Apple Event Handler!");
5402 /* Handle "quit_when_ready" */
5403 if (quit_when_ready)
5406 quit_when_ready = FALSE;
5408 /* Do the menu key */
5411 /* Turn off the menus */
5415 /* Handle "open_when_ready" */
5416 handle_open_when_ready();
5427 /* Something happened */
5434 /*** Some Hooks for various routines ***/
5438 * Mega-Hack -- emergency lifeboat
5440 static vptr lifeboat = NULL;
5444 * Hook to "release" memory
5446 static vptr hook_rnfree(vptr v, huge size)
5449 #pragma unused (size)
5453 /* Alternative method */
5468 * Hook to "allocate" memory
5470 static vptr hook_ralloc(huge size)
5475 /* Make a new pointer */
5476 return (malloc(size));
5480 /* Make a new pointer */
5481 return (NewPtr(size));
5488 * Hook to handle "out of memory" errors
5490 static vptr hook_rpanic(huge size)
5493 #pragma unused (size)
5497 /* Free the lifeboat */
5500 /* Free the lifeboat */
5501 DisposePtr(lifeboat);
5503 /* Forget the lifeboat */
5506 /* Mega-Hack -- Warning */
5508 mac_warning("¥á¥â¥ê¡¼¤¬Â¤ê¤Þ¤»¤ó!\rº£¤¹¤°½ªÎ»¤·¤Æ²¼¤µ¤¤!");
5510 mac_warning("Running out of Memory!\rAbort this process now!");
5513 /* Mega-Hack -- Never leave this function */
5514 while (TRUE) CheckEvents(TRUE);
5517 /* Mega-Hack -- Crash */
5523 * Hook to tell the user something important
5525 static void hook_plog(cptr str)
5527 /* Warning message */
5532 * Hook to tell the user something, and then quit
5534 static void hook_quit(cptr str)
5536 /* Warning if needed */
5537 if (str) mac_warning(str);
5539 /* Write a preference file */
5547 * Hook to tell the user something, and then crash
5549 static void hook_core(cptr str)
5551 /* XXX Use the debugger */
5552 /* DebugStr(str); */
5555 if (str) mac_warning(str);
5557 /* Warn, then save player */
5559 mac_warning("Ã×̿Ū¤Ê¥¨¥é¡¼¤Ç¤¹.\r¶¯À©Åª¤Ë¥»¡¼¥Ö¤·¤Æ½ªÎ»¤·¤Þ¤¹.");
5561 mac_warning("Fatal error.\rI will now attempt to save and quit.");
5564 /* Attempt to save */
5566 if (!save_player()) mac_warning("·Ù¹ð -- ¥»¡¼¥Ö¤Ë¼ºÇÔ¤·¤Þ¤·¤¿!");
5568 if (!save_player()) mac_warning("Warning -- save failed!");
5577 /*** Main program ***/
5583 * XXX XXX XXX Hack -- This function attempts to "fix" the nasty
5584 * "Macintosh Save Bug" by using "absolute" path names, since on
5585 * System 7 machines anyway, the "current working directory" often
5586 * "changes" due to background processes, invalidating any "relative"
5587 * path names. Note that the Macintosh is limited to 255 character
5588 * path names, so be careful about deeply embedded directories...
5590 * XXX XXX XXX Hack -- This function attempts to "fix" the nasty
5591 * "missing lib folder bug" by allowing the user to help find the
5592 * "lib" folder by hand if the "application folder" code fails...
5594 static void init_stuff(void)
5613 #if TARGET_API_MAC_CARBON
5615 NavDialogOptions dialogOptions;
5616 FSSpec theFolderSpec;
5617 NavReplyRecord theReply;
5619 /* Fake rectangle */
5626 #if TARGET_API_MAC_CARBON
5627 screenRect = GetQDGlobalsScreenBits(&screen)->bounds;
5629 screenRect = qd.screenBits.bounds;
5631 center_rect(&r, &screenRect);
5633 /* Extract corner */
5638 /* Default to the "lib" folder with the application */
5639 refnum_to_name(path, app_dir, app_vol, (char*)("\plib:"));
5642 /* Check until done */
5645 /* Prepare the paths */
5646 init_file_paths(path);
5648 /* Build the filename */
5650 path_build(path, sizeof(path), ANGBAND_DIR_FILE, "news_j.txt");
5652 path_build(path, sizeof(path), ANGBAND_DIR_FILE, "news.txt");
5655 /* Attempt to open and close that file */
5656 if (0 == fd_close(fd_open(path, O_RDONLY))) break;
5660 plog_fmt("'%s' ¥Õ¥¡¥¤¥ë¤ò¥ª¡¼¥×¥ó½ÐÍè¤Þ¤»¤ó.", path);
5662 plog_fmt("Unable to open the '%s' file.", path);
5667 plog("Hengband¤Î'lib'¥Õ¥©¥ë¥À¤¬Â¸ºß¤·¤Ê¤¤¤«Àµ¤·¤¯Ìµ¤¤²ÄǽÀ¤¬¤¢¤ê¤Þ¤¹.");
5669 plog("The Angband 'lib' folder is probably missing or misplaced.");
5674 plog("Please 'open' any file in any sub-folder of the 'lib' folder.");
5676 plog("Please 'open' any file in any sub-folder of the 'lib' folder.");
5679 #if TARGET_API_MAC_CARBON
5680 /* Ask the user to choose the lib folder */
5681 err = NavGetDefaultDialogOptions(&dialogOptions);
5684 if (err != noErr) quit(NULL);
5686 /* Set default location option */
5687 dialogOptions.dialogOptionFlags |= kNavSelectDefaultLocation;
5689 /* Clear preview option */
5690 dialogOptions.dialogOptionFlags &= ~(kNavAllowPreviews);
5692 /* Forbit selection of multiple files */
5693 dialogOptions.dialogOptionFlags &= ~(kNavAllowMultipleFiles);
5695 /* Display location */
5696 dialogOptions.location = topleft;
5698 /* Load the message for the missing folder from the resource fork */
5699 GetIndString(dialogOptions.message, 128, 1);
5701 /* Wait for the user to choose a folder */
5702 err = NavChooseFolder(
5710 /* Assume the player doesn't want to go on */
5711 if ((err != noErr) || !theReply.validRecord) quit(NULL);
5713 /* Retrieve FSSpec from the reply */
5715 AEKeyword theKeyword;
5716 DescType actualType;
5719 /* Get a pointer to selected folder */
5721 &(theReply.selection),
5731 if (err != noErr) quit(NULL);
5734 /* Free navitagor reply */
5735 err = NavDisposeReply(&theReply);
5738 if (err != noErr) quit(NULL);
5740 /* Extract textual file name for given file */
5743 theFolderSpec.parID,
5744 theFolderSpec.vRefNum,
5745 (char *)theFolderSpec.name);
5747 /* Allow "text" files */
5750 /* Allow "save" files */
5753 /* Allow "data" files */
5757 SFGetFile(topleft, "\p", NULL, 3, types, NULL, &reply);
5760 if (!reply.good) quit(NULL);
5762 /* Extract textual file name for given file */
5763 GetWDInfo(reply.vRefNum, &vrefnum, &drefnum, &junk);
5764 refnum_to_name(path, drefnum, vrefnum, (char*)reply.fName);
5767 /* Hack -- Remove the "filename" */
5768 i = strlen(path) - 1;
5769 while ((i > 0) && (path[i] != ':')) i--;
5770 if (path[i] == ':') path[i+1] = '\0';
5772 /* Hack -- allow "lib" folders */
5773 if (suffix(path, "lib:")) continue;
5775 /* Hack -- Remove the "sub-folder" */
5777 while ((i > 1) && (path[i] != ':')) i--;
5778 if (path[i] == ':') path[i+1] = '\0';
5784 * Macintosh Main loop
5788 EventRecord tempEvent;
5789 int numberOfMasters = 10;
5791 #if !TARGET_API_MAC_CARBON
5792 /* Increase stack space by 64K */
5793 SetApplLimit(GetApplLimit() - 131072L);//65536L);
5795 /* Stretch out the heap to full size */
5799 /* Get more Masters */
5800 while (numberOfMasters--) MoreMasters();
5802 #if !TARGET_API_MAC_CARBON
5803 /* Set up the Macintosh */
5804 InitGraf(&qd.thePort);
5818 FlushEvents(everyEvent, 0);
5820 /* Flush events some more (?) */
5821 (void)EventAvail(everyEvent, &tempEvent);
5822 (void)EventAvail(everyEvent, &tempEvent);
5823 (void)EventAvail(everyEvent, &tempEvent);
5826 #ifdef ANGBAND_LITE_MAC
5830 #else /* ANGBAND_LITE_MAC */
5832 # if defined(powerc) || defined(__powerc)
5834 /* Assume System 7 */
5836 /* Assume Color Quickdraw */
5846 /* Check the Gestalt */
5847 err = Gestalt(gestaltSystemVersion, &versionNumber);
5849 /* Check the version */
5850 if ((err != noErr) || (versionNumber < 0x0700))
5853 quit("¤³¤Î¥×¥í¥°¥é¥à¤Ï´Á»úTalk7.x.x°Ê¹ß¤ÇÆ°ºî¤·¤Þ¤¹.");
5855 quit("You must have System 7 to use this program.");
5865 /* Check the environs */
5866 if (SysEnvirons(1, &env) != noErr)
5869 quit("SysEnvirons ¥³¡¼¥ë¤Ï¼ºÇÔ¤·¤Þ¤·¤¿¡ª");
5871 quit("The SysEnvirons call failed!");
5875 /* Check for System Seven Stuff */
5876 if (env.systemVersion < 0x0700)
5879 quit("¤³¤Î¥×¥í¥°¥é¥à¤Ï´Á»úTalk7.x.x°Ê¹ß¤ÇÆ°ºî¤·¤Þ¤¹.");
5881 quit("You must have System 7 to use this program.");
5885 /* Check for Color Quickdraw */
5886 if (!env.hasColorQD)
5889 quit("¤³¤Î¥×¥í¥°¥é¥à¤ÏColor Quickdraw¤¬Ìµ¤¤¤ÈÆ°ºî¤·¤Þ¤»¤ó.");
5891 quit("You must have Color Quickdraw to use this program.");
5898 #endif /* ANGBAND_LITE_MAC */
5901 * Remember Mac OS version, in case we have to cope with version-specific
5904 (void)Gestalt(gestaltSystemVersion, &mac_os_version);
5907 /* Obtain a "Universal Procedure Pointer" */
5908 AEH_Start_UPP = NewAEEventHandlerUPP(AEH_Start);
5909 /* Install the hook (ignore error codes) */
5910 AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, AEH_Start_UPP,
5913 /* Obtain a "Universal Procedure Pointer" */
5914 AEH_Quit_UPP = NewAEEventHandlerUPP(AEH_Quit);
5915 /* Install the hook (ignore error codes) */
5916 AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, AEH_Quit_UPP,
5919 /* Obtain a "Universal Procedure Pointer" */
5920 AEH_Print_UPP = NewAEEventHandlerUPP(AEH_Print);
5921 /* Install the hook (ignore error codes) */
5922 AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments, AEH_Print_UPP,
5925 /* Obtain a "Universal Procedure Pointer" */
5926 AEH_Open_UPP = NewAEEventHandlerUPP(AEH_Open);
5927 /* Install the hook (ignore error codes) */
5928 AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, AEH_Open_UPP,
5932 /* Find the current application */
5936 /* Mark ourself as the file creator */
5939 /* Default to saving a "text" file */
5943 #if defined(__MWERKS__)
5945 /* Obtian a "Universal Procedure Pointer" */
5946 #if TARGET_API_MAC_CARBON
5947 ynfilterUPP = NewModalFilterUPP(ynfilter);
5949 ynfilterUPP = NewModalFilterProc(ynfilter);
5955 /* Hook in some "z-virt.c" hooks */
5956 rnfree_aux = hook_rnfree;
5957 ralloc_aux = hook_ralloc;
5958 rpanic_aux = hook_rpanic;
5960 /* Hooks in some "z-util.c" hooks */
5961 plog_aux = hook_plog;
5962 quit_aux = hook_quit;
5963 core_aux = hook_core;
5965 BackColor(blackColor);
5966 ForeColor(whiteColor);
5968 /* Show the "watch" cursor */
5969 SetCursor(*(GetCursor(watchCursor)));
5971 /* Prepare the menubar */
5974 /* Prepare the windows */
5981 /* Hack -- process all events */
5982 while (CheckEvents(TRUE)) /* loop */;
5984 /* Reset the cursor */
5985 #if TARGET_API_MAC_CARBON
5988 GetQDGlobalsArrow( &arrow );
5992 SetCursor( &qd.arrow );
5996 /* Mega-Hack -- Allocate a "lifeboat" */
5997 lifeboat = NewPtr(16384);
5999 /* Note the "system" */
6000 ANGBAND_SYS = "mac";
6009 /* Hack -- process all events */
6010 while (CheckEvents(TRUE)) /* loop */;
6013 /* We are now initialized */
6017 /* Handle "open_when_ready" */
6018 handle_open_when_ready();
6024 /* Prompt the user */
6026 prt("'¥Õ¥¡¥¤¥ë'¥á¥Ë¥å¡¼¤è¤ê'¿·µ¬'¤Þ¤¿¤Ï'³«¤¯...'¤òÁªÂò¤·¤Æ¤¯¤À¤µ¤¤¡£", 23, 10);
6028 prt("[Choose 'New' or 'Open' from the 'File' menu]", 23, 15);
6031 /* Flush the prompt */
6035 /* Hack -- Process Events Forever */
6036 while (TRUE) CheckEvents(TRUE);