OSDN Git Service

GF_MAKE_TRAPで無駄な地形判定削除。place_trap()が全てやってくれる。
[hengband/hengband.git] / src / main-mac.c
1 /* File: main-mac.c */
2
3 /* Purpose: Simple support for MACINTOSH Angband */
4
5 /*
6  * This file should only be compiled with the "Macintosh" version
7  *
8  * This file written by "Ben Harrison (benh@phial.com)".
9  *
10  * Some code adapted from "MacAngband 2.6.1" by Keith Randall
11  *
12  * Maarten Hazewinkel (mmhazewi@cs.ruu.nl) provided some initial
13  * suggestions for the PowerMac port.
14  *
15  * Steve Linberg (slinberg@crocker.com) provided the code surrounded
16  * by "USE_SFL_CODE".
17  *
18  * The graphics code is adapted from an extremely minimal subset of
19  * the code from "Sprite World II", an amazing animation package.
20  *
21  * See "z-term.c" for info on the concept of the "generic terminal"
22  *
23  * The preference file is now a text file named "Angband preferences".
24  *
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).
28  *
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.
32  *
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".
36  *
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.
41  *
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.
47  *
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.
51  *
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.
55  */
56
57
58 /*
59  * Important Resources in the resource file:
60  *
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)
65  *
66  *   DLOG 128 = "About Angband..."
67  *
68  *   ALRT 128 = unused (?)
69  *   ALRT 129 = "Warning..."
70  *   ALRT 130 = "Are you sure you want to quit without saving?"
71  *
72  *   DITL 128 = body for DLOG 128
73  *   DITL 129 = body for ALRT 129
74  *   DITL 130 = body for ALRT 130
75  *
76  *   ICON 128 = "warning" icon
77  *
78  *   MENU 128 = apple (about, -, ...)
79  *   MENU 129 = File (new, open, close, save, -, exit, quit)
80  *   MENU 130 = Edit (undo, -, cut, copy, paste, clear)
81  *
82  *   PICT 1001 = Graphics tile set
83  */
84
85
86 /*
87  * File name patterns:
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:*" (?)
93  *
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
98  */
99
100
101 /*
102  * Reasons for each header file:
103  *
104  *   angband.h = Angband header file
105  *
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
128  *
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
132  */
133
134
135 #include "angband.h"
136
137 #include <Types.h>
138 #include <Gestalt.h>
139 #include <QuickDraw.h>
140 #include <Files.h>
141 #include <Fonts.h>
142 #include <Menus.h>
143 #include <Dialogs.h>
144 #include <Windows.h>
145 #include <Palettes.h>
146 #include <StandardFile.h>
147 #include <DiskInit.h>
148 #include <ToolUtils.h>
149 #include <Devices.h>
150 #include <Events.h>
151 #include <Resources.h>
152 #include <Controls.h>
153 #include <SegLoad.h>
154 #include <Memory.h>
155 #include <QDOffscreen.h>
156 #include <Sound.h>
157 #if TARGET_API_MAC_CARBON
158 #include <Navigation.h>
159 # ifdef MAC_MPW
160 # include <CarbonStdCLib.h>
161 # endif
162 #endif
163
164 #ifdef JP
165
166 #include <Script.h>
167
168 #endif
169
170 /*
171  * Cleaning up a couple of things to make these easier to change --AR
172  */
173 #ifdef JP
174 #define PREF_FILE_NAME "Hengband Preferences"
175 #else
176 #define PREF_FILE_NAME "Hengband-E Preferences"
177 #endif
178
179 /*
180  * Use "malloc()" instead of "NewPtr()"
181  */
182 /* #define USE_MALLOC */
183
184
185 #if defined(powerc) || defined(__powerc)
186
187 /*
188  * Disable "LITE" version
189  */
190 # undef ANGBAND_LITE_MAC
191
192 #endif
193
194
195 #ifdef ANGBAND_LITE_MAC
196
197 /*
198  * Maximum number of windows
199  */
200 # define MAX_TERM_DATA 1
201
202 #else /* ANGBAND_LITE_MAC */
203
204 /*
205  * Maximum number of windows
206  */
207 # define MAX_TERM_DATA 8
208
209 /*
210  * Activate some special code
211  */
212 # define USE_SFL_CODE
213
214 #endif /* ANGBAND_LITE_MAC */
215
216
217
218 #ifdef USE_SFL_CODE
219
220 /*
221  * Include the necessary header files
222  */
223 #include <AppleEvents.h>
224 #include <EPPC.h>
225 #include <Folders.h>
226
227 #endif
228
229
230 /*
231  * Globals for MPW compilation
232  */
233 #if defined(MACH_O_CARBON) || defined(MAC_MPW)
234        /* Globals needed */
235 #if !TARGET_API_MAC_CARBON
236        QDGlobals qd;
237 #endif
238        OSType _ftype;
239        OSType _fcreator;
240 #endif
241
242
243
244 #if 0
245
246 /*
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
250  *
251  * Colors 8 to 15 are basically "enhanced" versions of Colors 0 to 7.
252  *
253  * On the Macintosh, we use color quickdraw, and we use actual "RGB"
254  * values below to choose the 16 colors.
255  *
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).
259  */
260 static RGBColor foo[16] =
261 {
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 */
278 };
279
280 #endif
281
282
283 /*
284  * Forward declare
285  */
286 typedef struct term_data term_data;
287
288 /*
289  * Extra "term" data
290  */
291 struct term_data
292 {
293         term            *t;
294
295         Rect            r;
296
297         WindowPtr       w;
298
299 #ifdef ANGBAND_LITE_MAC
300
301         /* Nothing */
302
303 #else /* ANGBAND_LITE_MAC */
304
305         short padding;
306
307         short pixelDepth;
308
309         GWorldPtr theGWorld;
310
311         GDHandle theGDH;
312
313         GDHandle mainSWGDH;
314
315 #endif /* ANGBAND_LITE_MAC */
316
317         Str15           title;
318
319         s16b            oops;
320
321         s16b            keys;
322
323         s16b            last;
324
325         s16b            mapped;
326
327         s16b            rows;
328         s16b            cols;
329
330         s16b            font_id;
331         s16b            font_size;
332         s16b            font_face;
333         s16b            font_mono;
334
335         s16b            font_o_x;
336         s16b            font_o_y;
337         s16b            font_wid;
338         s16b            font_hgt;
339
340         s16b            tile_o_x;
341         s16b            tile_o_y;
342         s16b            tile_wid;
343         s16b            tile_hgt;
344
345         s16b            size_wid;
346         s16b            size_hgt;
347
348         s16b            size_ow1;
349         s16b            size_oh1;
350         s16b            size_ow2;
351         s16b            size_oh2;
352 };
353
354
355
356
357 /*
358  * Forward declare -- see below
359  */
360 static bool CheckEvents(bool wait);
361
362
363 /*
364  * Hack -- location of the main directory
365  */
366 static short app_vol;
367 static long  app_dir;
368
369
370 /*
371  * Delay handling of double-clicked savefiles
372  */
373 Boolean open_when_ready = FALSE;
374
375 /*
376  * Delay handling of pre-emptive "quit" event
377  */
378 Boolean quit_when_ready = FALSE;
379
380
381 /*
382  * Hack -- game in progress
383  */
384 static int game_in_progress = 0;
385
386
387 /*
388  * Only do "SetPort()" when needed
389  */
390 static WindowPtr active = NULL;
391
392
393
394 /*
395  * An array of term_data's
396  */
397 static term_data data[MAX_TERM_DATA];
398
399
400
401 /*
402  * Note when "open"/"new" become valid
403  */
404 static bool initialized = FALSE;
405
406 /*
407  * Version of Mac OS - for version specific bug workarounds (; ;)
408  */
409 static long mac_os_version;
410
411
412 /*
413  * CodeWarrior uses Universal Procedure Pointers
414  */
415 static ModalFilterUPP ynfilterUPP;
416
417 #ifdef USE_SFL_CODE
418
419 /*
420  * Apple Event Hooks
421  */
422 AEEventHandlerUPP AEH_Start_UPP;
423 AEEventHandlerUPP AEH_Quit_UPP;
424 AEEventHandlerUPP AEH_Print_UPP;
425 AEEventHandlerUPP AEH_Open_UPP;
426
427 #endif
428
429 /*
430         Extra Sound Mode
431 */
432
433 static int ext_sound = 0;
434
435 #define         SND_NON         0
436 #define         SND_ATTACK      1
437 #define         SND_MOVE                2
438 #define         SND_TRAP                3
439 #define         SND_SHOP                4
440 #define         SND_ME          5
441 #define         SND_CMD_ERROR   6
442
443 static int soundchoice[] = {
444         SND_NON,
445         SND_ATTACK,
446         SND_ATTACK,
447         SND_ATTACK,
448         SND_TRAP,
449         SND_ATTACK,
450         SND_ME,
451         SND_ME,
452         SND_ME,
453         SND_MOVE,
454         SND_ATTACK,
455         SND_ME,
456         SND_ATTACK,
457         SND_NON,
458         SND_MOVE,
459         SND_MOVE,
460         SND_ME,
461         SND_SHOP,
462         SND_SHOP,
463         SND_SHOP,
464         SND_SHOP,
465         SND_MOVE,
466         SND_MOVE,
467         SND_MOVE,
468         SND_MOVE,
469         SND_ATTACK,
470         SND_SHOP,
471         SND_SHOP,
472         SND_ME,
473         SND_NON,
474         SND_ATTACK,
475         SND_NON,
476         SND_NON,
477         SND_NON,
478         SND_NON,
479         SND_ATTACK,
480         SND_ATTACK,
481         SND_NON,
482         SND_NON,
483         SND_ATTACK,
484         SND_NON,
485         SND_NON,
486         SND_NON,
487         SND_TRAP,
488         SND_ATTACK,
489         SND_ATTACK,
490         SND_ATTACK,
491         SND_ATTACK,
492         SND_ATTACK,
493         SND_NON,
494         SND_NON,
495         SND_NON,
496         SND_NON,
497         SND_NON,
498         SND_CMD_ERROR,
499         SND_TRAP,
500         SND_NON,
501         SND_NON,
502         SND_TRAP,
503         SND_ATTACK,
504         SND_TRAP,
505         SND_ATTACK,
506         SND_ATTACK,
507         SND_NON,
508         SND_TRAP,
509 };
510
511 static int                      soundmode[8];
512
513 static int ext_graf = 0;
514
515
516
517 /*
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
521  */
522 #if TARGET_API_MAC_CARBON
523 static void refnum_to_name(char *buf, long refnum, short vrefnum, char *fname)
524 {
525         CInfoPBRec pb;
526         Str255 name;
527         int err;
528         int i, j;
529
530         char res[1000];
531         
532         FSSpec spec;
533         short   vref;
534     long        dirID;
535     
536         i=999;
537
538         res[i]=0; i--;
539         for (j=1; j<=fname[0]; j++)
540         {
541                 res[i-fname[0]+j] = fname[j];
542         }
543         i-=fname[0];
544
545         vref = vrefnum;
546         dirID = refnum;
547
548         while (1)
549         {
550                 pb.dirInfo.ioDrDirID=pb.dirInfo.ioDrParID;
551                 err = FSMakeFSSpec( vref, dirID, "\p", &spec );
552                 
553                 if( err != noErr )
554                     break;
555                 
556                 res[i] = ':'; i--;
557                 for (j=1; j<=spec.name[0]; j++)
558                 {
559                         res[i-spec.name[0]+j] = spec.name[j];
560                 }
561                 i -= spec.name[0];
562                 
563                 dirID = spec.parID;
564         }
565
566         /* Extract the result */
567         for (j = 0, i++; res[i]; j++, i++) buf[j] = res[i];
568         buf[j] = 0;
569 }
570 #else
571 static void refnum_to_name(char *buf, long refnum, short vrefnum, char *fname)
572 {
573         DirInfo pb;
574         Str255 name;
575         int err;
576         int i, j;
577
578         char res[1000];
579
580         i=999;
581
582         res[i]=0; i--;
583         for (j=1; j<=fname[0]; j++)
584         {
585                 res[i-fname[0]+j] = fname[j];
586         }
587         i-=fname[0];
588
589         pb.ioCompletion=NULL;
590         pb.ioNamePtr=name;
591         pb.ioVRefNum=vrefnum;
592         pb.ioDrParID=refnum;
593         pb.ioFDirIndex=-1;
594
595         while (1)
596         {
597                 pb.ioDrDirID=pb.ioDrParID;
598                 err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
599                 res[i] = ':'; i--;
600                 for (j=1; j<=name[0]; j++)
601                 {
602                         res[i-name[0]+j] = name[j];
603                 }
604                 i -= name[0];
605
606                 if (pb.ioDrDirID == fsRtDirID) break;
607         }
608
609         /* Extract the result */
610         for (j = 0, i++; res[i]; j++, i++) buf[j] = res[i];
611         buf[j] = 0;
612 }
613 #endif
614
615 #if TARGET_API_MAC_CARBON
616 pascal OSErr FSpLocationFromFullPath(short fullPathLength,
617                                                                          const void *fullPath,
618                                                                          FSSpec *spec)
619 {
620         AliasHandle     alias;
621         OSErr           result;
622         Boolean         wasChanged;
623         Str32           nullString;
624         
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 )
629         {
630                 /* Let the Alias Manager resolve the alias. */
631                 result = ResolveAlias(NULL, alias, spec, &wasChanged);
632                 
633                 /* work around Alias Mgr sloppy volume matching bug */
634                 if ( spec->vRefNum == 0 )
635                 {
636                         /* invalidate wrong FSSpec */
637                         spec->parID = 0;
638                         spec->name[0] =  0;
639                         result = nsvErr;
640                 }
641                 DisposeHandle((Handle)alias);   /* Free up memory used */
642         }
643         return ( result );
644 }
645 #endif
646
647 #if 0
648
649 /*
650  * XXX XXX XXX Allow the system to ask us for a filename
651  */
652 static bool askfor_file(char *buf, int len)
653 {
654         SFReply reply;
655         Str255 dflt;
656         Point topleft;
657         short vrefnum;
658         long drefnum, junk;
659
660         /* Default file name */
661         sprintf((char*)dflt + 1, "%s's description", buf);
662         dflt[0] = strlen((char*)dflt + 1);
663
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); */
669
670         /* Process */
671         if (reply.good)
672         {
673                 int fc;
674
675                 /* Get info */
676                 GetWDInfo(reply.vRefNum, &vrefnum, &drefnum, &junk);
677
678                 /* Extract the name */
679                 refnum_to_name(buf, drefnum, vrefnum, (char*)reply.fName);
680
681                 /* Success */
682                 return (TRUE);
683         }
684
685         /* Failure */
686         return (FALSE);
687 }
688
689 #endif
690
691 static void local_to_global( Rect *r )
692 {
693         Point           temp;
694         
695         temp.h = r->left;
696         temp.v = r->top;
697         
698         LocalToGlobal( &temp );
699         
700         r->left = temp.h;
701         r->top = temp.v;
702         
703         temp.h = r->right;
704         temp.v = r->bottom;
705         
706         LocalToGlobal( &temp );
707         
708         r->right = temp.h;
709         r->bottom = temp.v;
710 }
711
712 static void global_to_local( Rect *r )
713 {
714         Point           temp;
715         
716         temp.h = r->left;
717         temp.v = r->top;
718         
719         GlobalToLocal( &temp );
720         
721         r->left = temp.h;
722         r->top = temp.v;
723         
724         temp.h = r->right;
725         temp.v = r->bottom;
726         
727         GlobalToLocal( &temp );
728         
729         r->right = temp.h;
730         r->bottom = temp.v;
731 }
732
733
734 #ifdef MAC_MPW
735
736 /*
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
741  */
742 void convert_pathname(char* path)
743 {
744         char buf[1024];
745
746         /* Nothing has to be done for CarbonLib on Classic */
747         if (mac_os_version >= 0x1000)
748         {
749                 /* Convert to POSIX style */
750                 ConvertHFSPathToUnixPath(path, buf);
751
752                 /* Copy the result back */
753                 strcpy(path, buf);
754         }
755
756         /* Done. */
757         return;
758 }
759
760 # ifdef CHECK_MODIFICATION_TIME
761
762 /*
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.
765  */
766 static int get_modification_time(cptr path, u32b *mod_time)
767 {
768         CInfoPBRec pb;
769         Str255 pathname;
770         int i;
771
772         /* Paranoia - make sure the pathname fits in Str255 */
773         i = strlen(path);
774         if (i > 255) return (-1);
775
776         /* Convert pathname to a Pascal string */
777         strncpy((char *)pathname + 1, path, 255);
778         pathname[0] = i;
779
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;
785
786         /* Get catalog information of the file */
787         if (PBGetCatInfoSync(&pb) != noErr) return (-1);
788
789         /* Set modification date and time */
790         *mod_time = pb.hFileInfo.ioFlMdDat;
791
792         /* Success */
793         return (0);
794 }
795
796
797 /*
798  * A (non-Mach-O) Mac OS version of check_modification_time, for those
799  * compilers without good enough POSIX-compatibility libraries XXX XXX
800  */
801 errr check_modification_date(int fd, cptr template_file)
802 {
803 #pragma unused(fd)
804         u32b txt_stat, raw_stat;
805         char *p;
806         char fname[32];
807         char buf[1024];
808
809         /* Build the file name */
810         path_build(buf, sizeof(buf), ANGBAND_DIR_EDIT, template_file);
811
812         /* XXX XXX XXX */
813         convert_pathname(buf);
814
815         /* Obtain modification time */
816         if (get_modification_time(buf, &txt_stat)) return (-1);
817
818         /* XXX Build filename of the corresponding *.raw file */
819         strnfmt(fname, sizeof(fname), "%s", template_file);
820
821         /* Find last '.' */
822         p = strrchr(fname, '.');
823
824         /* Can't happen */
825         if (p == NULL) return (-1);
826
827         /* Substitute ".raw" for ".txt" */
828         strcpy(p, ".raw");
829
830         /* Build the file name of the raw file */
831         path_build(buf, sizeof(buf), ANGBAND_DIR_DATA, fname);
832
833         /* XXX XXX XXX */
834         convert_pathname(buf);
835
836         /* Obtain modification time */
837         if (get_modification_time(buf, &raw_stat)) return (-1);
838
839         /* Ensure the text file is not newer than the raw file */
840         if (txt_stat > raw_stat) return (-1);
841
842         /* Keep using the current .raw file */
843         return (0);
844 }
845
846 # endif /* CHECK_MODIFICATION_TIME */
847
848 #endif /* MAC_MPW */
849
850 /*
851  * Center a rectangle inside another rectangle
852  */
853 static void center_rect(Rect *r, Rect *s)
854 {
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;
859         r->left += dx;
860         r->right += dx;
861         r->top += dy;
862         r->bottom += dy;
863 }
864
865
866 /*
867  * Convert a pascal string in place
868  *
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.
872  */
873 static void ptocstr(StringPtr src)
874 {
875         int i;
876
877         /* Hack -- pointer */
878         char *s = (char*)(src);
879
880         /* Hack -- convert the string */
881         for (i = s[0]; i; i--, s++) s[0] = s[1];
882
883         /* Hack -- terminate the string */
884         s[0] = '\0';
885 }
886
887
888 #if defined(USE_SFL_CODE)
889
890
891 /*
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
896  * is.
897  *
898  * I had to hack PathNameFromDirID a little for MetroWerks, but it's awfully
899  * nice.
900  */
901 static void pstrcat(StringPtr dst, StringPtr src)
902 {
903         /* copy string in */
904         BlockMove(src + 1, dst + *dst + 1, *src);
905
906         /* adjust length byte */
907         *dst += *src;
908 }
909
910 /*
911  * pstrinsert - insert string 'src' at beginning of string 'dst'
912  */
913 static void pstrinsert(StringPtr dst, StringPtr src)
914 {
915         /* make room for new string */
916         BlockMove(dst + 1, dst + *src + 1, *dst);
917
918         /* copy new string in */
919         BlockMove(src + 1, dst + 1, *src);
920
921         /* adjust length byte */
922         *dst += *src;
923 }
924
925 static void PathNameFromDirID(long dirID, short vRefNum, StringPtr fullPathName)
926 {
927         CInfoPBRec      block;
928         Str255  directoryName;
929         OSErr   err;
930
931         fullPathName[0] = '\0';
932
933         block.dirInfo.ioDrParID = dirID;
934         block.dirInfo.ioNamePtr = directoryName;
935
936         while (1)
937         {
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;
945         }
946 }
947
948 #endif
949
950 #if TARGET_API_MAC_CARBON
951
952 static OSErr ChooseFile( StringPtr filename, FSSpec selfld )
953 {
954         NavReplyRecord          reply;
955         NavDialogOptions        dialogOptions;
956         NavTypeListHandle       navTypeList = NULL;
957         OSErr                           err;
958         AEDesc  deffld;
959         
960         AECreateDesc( typeFSS, &selfld, sizeof(FSSpec), &deffld );
961         
962         err = NavGetDefaultDialogOptions( &dialogOptions );
963         
964         if( err == noErr ){
965                 
966                 err = NavChooseFile( &deffld, &reply, &dialogOptions, NULL, NULL, NULL, navTypeList, NULL );
967                 
968                 if ( reply.validRecord && err == noErr ){
969                         // grab the target FSSpec from the AEDesc:
970                         FSSpec          finalFSSpec;
971                         AEKeyword       keyWord;
972                         DescType        typeCode;
973                         Size            actualSize = 0;
974
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 )
978                         {
979                                 refnum_to_name( (char *)filename, finalFSSpec.parID, finalFSSpec.vRefNum, (char *)finalFSSpec.name );
980                                 // 'finalFSSpec' is the chosen file¥Î
981                         }
982                         
983                         err = NavDisposeReply( &reply );
984                 }
985                 if( navTypeList != NULL )
986                 {
987                         DisposeHandle( (Handle)navTypeList );
988                         navTypeList = NULL;
989                 }
990         }
991         
992         AEDisposeDesc( &deffld );
993         
994         return err;
995 }
996
997 #endif
998
999 /*
1000  * Activate a given window, if necessary
1001  */
1002 static void activate(WindowPtr w)
1003 {
1004         /* Activate */
1005         if (active != w)
1006         {
1007                 /* Activate */
1008 #if TARGET_API_MAC_CARBON
1009                 if (w) SetPortWindowPort(w);
1010 #else
1011                 if (w) SetPort(w);
1012 #endif
1013
1014                 /* Remember */
1015                 active = w;
1016         }
1017 }
1018
1019
1020 /*
1021  * Display a warning message
1022  */
1023 static void mac_warning(cptr warning)
1024 {
1025         Str255 text;
1026         int len, i;
1027
1028         /* Limit of 250 chars */
1029         len = strlen(warning);
1030         if (len > 250) len = 250;
1031
1032         /* Make a "Pascal" string */
1033         text[0] = len;
1034         for (i=0; i<len; i++) text[i+1] = warning[i];
1035
1036         /* Prepare the dialog box values */
1037         ParamText(text, "\p", "\p", "\p");
1038
1039         /* Display the Alert, wait for Okay */
1040         Alert(129, 0L);
1041 }
1042
1043
1044
1045 /*** Some generic functions ***/
1046
1047
1048 #ifdef ANGBAND_LITE_MAC
1049
1050 /*
1051  * Hack -- activate a color (0 to 255)
1052  */
1053 #define term_data_color(TD,A) /* Nothing */
1054
1055 #else /* ANGBAND_LITE_MAC */
1056
1057 /*
1058  * Hack -- activate a color (0 to 255)
1059  */
1060 static void term_data_color(term_data *td, int a)
1061 {
1062         u16b rv, gv, bv;
1063
1064         RGBColor color;
1065
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];
1070
1071         /* Set the color */
1072         color.red = (rv | (rv << 8));
1073         color.green = (gv | (gv << 8));
1074         color.blue = (bv | (bv << 8));
1075
1076         /* Activate the color */
1077         RGBForeColor(&color);
1078
1079         /* Memorize color */
1080         td->last = a;
1081 }
1082
1083 #endif /* ANGBAND_LITE_MAC */
1084
1085
1086 /*
1087  * Hack -- Apply and Verify the "font" info
1088  *
1089  * This should usually be followed by "term_data_check_size()"
1090  */
1091 static void term_data_check_font(term_data *td)
1092 {
1093         int i;
1094
1095         FontInfo info;
1096
1097         WindowPtr old = active;
1098
1099
1100         /* Activate */
1101         activate(td->w);
1102
1103         /* Instantiate font */
1104         TextFont(td->font_id);
1105         TextSize(td->font_size);
1106         TextFace(td->font_face);
1107
1108         /* Extract the font info */
1109         GetFontInfo(&info);
1110
1111         /* Assume monospaced */
1112         td->font_mono = TRUE;
1113
1114         /* Extract the font sizing values XXX XXX XXX */
1115         td->font_wid = CharWidth('@'); /* info.widMax; */
1116         td->font_hgt = info.ascent + info.descent;
1117         td->font_o_x = 0;
1118         td->font_o_y = info.ascent;
1119
1120         /* Check important characters */
1121         for (i = 33; i < 127; i++)
1122         {
1123                 /* Hack -- notice non-mono-space */
1124                 if (td->font_wid != CharWidth(i)) td->font_mono = FALSE;
1125
1126                 /* Hack -- collect largest width */
1127                 if (td->font_wid < CharWidth(i)) td->font_wid = CharWidth(i);
1128         }
1129
1130         /* Set default offsets */
1131         td->tile_o_x = td->font_o_x;
1132         td->tile_o_y = td->font_o_y;
1133
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;
1138         }
1139
1140         /* Re-activate the old window */
1141         activate(old);
1142 }
1143
1144
1145 /*
1146  * Hack -- Apply and Verify the "size" info
1147  */
1148 static void term_data_check_size(term_data *td)
1149 {
1150         BitMap          screen;
1151         
1152 #if TARGET_API_MAC_CARBON
1153         GetQDGlobalsScreenBits( &screen );
1154 #else
1155         screen = qd.screenBits;
1156 #endif
1157         /* Minimal window size */
1158         if (td == &data[0])
1159         {
1160                 /* Enforce minimal size */
1161                 if (td->cols < 80) td->cols = 80;
1162                 if (td->rows < 24) td->rows = 24;
1163         }
1164
1165         /* Allow small windows for the rest */
1166         else
1167         {
1168                 if (td->cols < 1) td->cols = 1;
1169                 if (td->rows < 1) td->rows = 1;
1170         }
1171
1172         /* Minimal tile size */
1173         if (td->tile_wid < 4) td->tile_wid = 4;
1174         if (td->tile_hgt < 4) td->tile_hgt = 4;
1175
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;
1179
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;
1183
1184         /* Apply font offsets */
1185         td->tile_o_x += td->font_o_x;
1186         td->tile_o_y += td->font_o_y;
1187
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;
1191
1192         /* Verify the top */
1193         if (td->r.top > screen.bounds.bottom - td->size_hgt)
1194         {
1195                 td->r.top = screen.bounds.bottom - td->size_hgt;
1196         }
1197
1198         /* Verify the top */
1199         if (td->r.top < screen.bounds.top + 30)
1200         {
1201                 td->r.top = screen.bounds.top + 30;
1202         }
1203
1204         /* Verify the left */
1205         if (td->r.left > screen.bounds.right - td->size_wid)
1206         {
1207                 td->r.left = screen.bounds.right - td->size_wid;
1208         }
1209
1210         /* Verify the left */
1211         if (td->r.left < screen.bounds.left)
1212         {
1213                 td->r.left = screen.bounds.left;
1214         }
1215
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;
1219
1220         /* Assume no graphics */
1221         td->t->higher_pict = FALSE;
1222         td->t->always_pict = FALSE;
1223
1224 #ifdef ANGBAND_LITE_MAC
1225
1226         /* No graphics */
1227
1228 #else /* ANGBAND_LITE_MAC */
1229
1230         /* Handle graphics */
1231         if (use_graphics)
1232         {
1233                 /* Use higher_pict whenever possible */
1234                 if (td->font_mono) td->t->higher_pict = TRUE;
1235
1236                 /* Use always_pict only when necessary */
1237                 else td->t->always_pict = TRUE;
1238         }
1239
1240 #endif /* ANGBAND_LITE_MAC */
1241
1242         /* Fake mono-space */
1243         if (!td->font_mono ||
1244             (td->font_wid != td->tile_wid) ||
1245                 (td->font_hgt != td->tile_hgt))
1246         {
1247                 /* Handle fake monospace -- this is SLOW */
1248                 if (td->t->higher_pict) td->t->higher_pict = FALSE;
1249                 td->t->always_pict = TRUE;
1250         }
1251 }
1252
1253 /*
1254  * Hack -- resize a term_data
1255  *
1256  * This should normally be followed by "term_data_resize()"
1257  */
1258 static void term_data_resize(term_data *td)
1259 {
1260         /* Actually resize the window */
1261         SizeWindow(td->w, td->size_wid, td->size_hgt, 0);
1262 }
1263
1264
1265
1266 /*
1267  * Hack -- redraw a term_data
1268  *
1269  * Note that "Term_redraw()" calls "TERM_XTRA_CLEAR"
1270  */
1271 static void term_data_redraw(term_data *td)
1272 {
1273         term *old = Term;
1274
1275         /* Activate the term */
1276         Term_activate(td->t);
1277
1278         /* Redraw the contents */
1279         Term_redraw();
1280
1281         /* Flush the output */
1282         Term_fresh();
1283
1284         /* Restore the old term */
1285         Term_activate(old);
1286         
1287         /* No need to redraw */
1288 #if TARGET_API_MAC_CARBON
1289         {
1290                 RgnHandle               theRgn = NewRgn();
1291                 GetWindowRegion( td->w, kWindowContentRgn, theRgn );
1292                 ValidWindowRgn( (WindowRef)(td->w), theRgn );
1293                 DisposeRgn( theRgn );
1294         }
1295 #else
1296         ValidRect(&td->w->portRect);
1297 #endif
1298
1299 }
1300
1301
1302
1303
1304 #ifdef ANGBAND_LITE_MAC
1305
1306 /* No graphics */
1307
1308 #else /* ANGBAND_LITE_MAC */
1309
1310
1311 /*
1312  * Constants
1313  */
1314
1315 static int pictID = 1001;       /* 8x8 tiles; 16x16 tiles are 1002 */
1316
1317 static int grafWidth = 8;       /* Always equal to grafHeight */
1318 static int grafHeight = 8;      /* Either 8 or 16 */
1319
1320 static bool arg_newstyle_graphics;
1321 static bool use_newstyle_graphics;
1322
1323 /*
1324  * Forward Declare
1325  */
1326 typedef struct FrameRec FrameRec;
1327
1328 /*
1329  * Frame
1330  *
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)
1334  */
1335 struct FrameRec
1336 {
1337         GWorldPtr               framePort;
1338         PixMapHandle    framePixHndl;
1339         PixMapPtr               framePix;
1340         
1341 };
1342
1343
1344 /*
1345  * The global picture data
1346  */
1347 static FrameRec *frameP = NULL;
1348
1349
1350 /*
1351  * Lock a frame
1352  */
1353 static void BenSWLockFrame(FrameRec *srcFrameP)
1354 {
1355         PixMapHandle            pixMapH;
1356
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;
1363 #else
1364         srcFrameP->framePix = (PixMapPtr)StripAddress(*(Handle)pixMapH);
1365 #endif
1366         
1367 }
1368
1369
1370 /*
1371  * Unlock a frame
1372  */
1373 static void BenSWUnlockFrame(FrameRec *srcFrameP)
1374 {
1375         if (srcFrameP->framePort != NULL)
1376         {
1377                 HUnlock((Handle)srcFrameP->framePixHndl);
1378                 UnlockPixels(srcFrameP->framePixHndl);
1379         }
1380
1381         srcFrameP->framePix = NULL;
1382         
1383 }
1384
1385 static OSErr BenSWCreateGWorldFromPict(
1386         GWorldPtr *pictGWorld,
1387         PicHandle pictH)
1388 {
1389         OSErr err;
1390         GWorldPtr saveGWorld;
1391         GDHandle saveGDevice;
1392         GWorldPtr tempGWorld;
1393         Rect pictRect;
1394         short depth;
1395         GDHandle theGDH;
1396
1397         /* Reset */
1398         *pictGWorld = NULL;
1399
1400         /* Get depth */
1401         depth = data[0].pixelDepth;
1402
1403         /* Get GDH */
1404         theGDH = data[0].theGDH;
1405
1406         /* Obtain size rectangle */
1407         pictRect = (**pictH).picFrame;
1408         OffsetRect(&pictRect, -pictRect.left, -pictRect.top);
1409
1410         /* Create a GWorld */
1411         err = NewGWorld(&tempGWorld, depth, &pictRect, nil, 
1412                                         theGDH, noNewDevice);
1413
1414         /* Success */
1415         if (err != noErr)
1416         {
1417                 return (err);
1418         }
1419
1420         /* Save pointer */
1421         *pictGWorld = tempGWorld;
1422
1423         /* Save GWorld */
1424         GetGWorld(&saveGWorld, &saveGDevice);
1425
1426         /* Activate */
1427         SetGWorld(tempGWorld, nil);
1428
1429         /* Dump the pict into the GWorld */
1430         (void)LockPixels(GetGWorldPixMap(tempGWorld));
1431         EraseRect(&pictRect);
1432         DrawPicture(pictH, &pictRect);
1433         UnlockPixels(GetGWorldPixMap(tempGWorld));
1434
1435         /* Restore GWorld */
1436         SetGWorld(saveGWorld, saveGDevice);
1437         
1438         /* Success */
1439         return (0);
1440 }
1441
1442
1443
1444
1445 /*
1446  * Init the global "frameP"
1447  */
1448
1449 static errr globe_init(void)
1450 {
1451         OSErr err;
1452         
1453         GWorldPtr tempPictGWorldP;
1454
1455         PicHandle newPictH;
1456
1457         /* Use window XXX XXX XXX */
1458 #if TARGET_API_MAC_CARBON
1459         SetPortWindowPort(data[0].w);
1460 #else
1461         SetPort(data[0].w);
1462 #endif
1463
1464
1465         /* Get the pict resource */
1466         newPictH = GetPicture(pictID);
1467
1468         /* Analyze result */
1469         err = (newPictH ? 0 : -1);
1470
1471         /* Oops */
1472         if (err == noErr)
1473         {
1474
1475                 /* Create GWorld */
1476                 err = BenSWCreateGWorldFromPict(&tempPictGWorldP, newPictH);
1477                 
1478                 /* Release resource */
1479                 ReleaseResource((Handle)newPictH);
1480
1481                 /* Error */
1482                 if (err == noErr)
1483                 {
1484                         /* Create the frame */
1485                         frameP = (FrameRec*)NewPtrClear((Size)sizeof(FrameRec));
1486
1487                         /* Analyze result */
1488                         err = (frameP ? 0 : -1);
1489
1490                         /* Oops */
1491                         if (err == noErr)
1492                         {
1493                                 /* Save GWorld */
1494                                 frameP->framePort = tempPictGWorldP;
1495
1496                                 /* Lock it */
1497                                 BenSWLockFrame(frameP);
1498                         }
1499                 }
1500         }
1501
1502         /* Result */
1503         return (err);
1504 }
1505
1506
1507 /*
1508  * Nuke the global "frameP"
1509  */
1510 static errr globe_nuke(void)
1511 {
1512         /* Dispose */
1513         if (frameP)
1514         {
1515                 /* Unlock */
1516                 BenSWUnlockFrame(frameP);
1517
1518                 /* Dispose of the GWorld */
1519                 DisposeGWorld(frameP->framePort);
1520
1521                 /* Dispose of the memory */
1522                 DisposePtr((Ptr)frameP);
1523
1524                 /* Forget */
1525                 frameP = NULL;
1526         }
1527
1528         /* Flush events */      
1529         FlushEvents(everyEvent, 0);
1530
1531         /* Success */
1532         return (0);
1533 }
1534
1535
1536 #endif /* ANGBAND_LITE_MAC */
1537
1538
1539
1540 /*** Support for the "z-term.c" package ***/
1541
1542
1543 /*
1544  * Initialize a new Term
1545  *
1546  * Note also the "window type" called "noGrowDocProc", which might be more
1547  * appropriate for the main "screen" window.
1548  *
1549  * Note the use of "srcCopy" mode for optimized screen writes.
1550  */
1551 static void Term_init_mac(term *t)
1552 {
1553         term_data *td = (term_data*)(t->data);
1554
1555         static RGBColor black = {0x0000,0x0000,0x0000};
1556         static RGBColor white = {0xFFFF,0xFFFF,0xFFFF};
1557
1558 #ifdef ANGBAND_LITE_MAC
1559
1560         /* Make the window */
1561         td->w = NewWindow(0, &td->r, td->title, 0, noGrowDocProc, (WindowPtr)-1, 1, 0L);
1562
1563 #else /* ANGBAND_LITE_MAC */
1564
1565         /* Make the window */
1566         td->w = NewCWindow(0, &td->r, td->title, 0, documentProc, (WindowPtr)-1, 1, 0L);
1567
1568 #endif /* ANGBAND_LITE_MAC */
1569
1570         /* Activate the window */
1571         activate(td->w);
1572
1573         /* Erase behind words */
1574         TextMode(srcCopy);
1575
1576         /* Apply and Verify */
1577         term_data_check_font(td);
1578         term_data_check_size(td);
1579
1580         /* Resize the window */
1581         term_data_resize(td);
1582
1583 #ifdef ANGBAND_LITE_MAC
1584
1585         /* Prepare the colors (base colors) */
1586         BackColor(blackColor);
1587         ForeColor(whiteColor);
1588
1589 #else /* ANGBAND_LITE_MAC */
1590
1591         /* Prepare the colors (real colors) */
1592         RGBBackColor(&black);
1593         RGBForeColor(&white);
1594
1595         /* Block */
1596         {
1597                 Rect tempRect;
1598                 Rect globalRect;
1599                 GDHandle mainGDH;
1600                 GDHandle currentGDH;
1601                 GWorldPtr windowGWorld;
1602                 PixMapHandle basePixMap;
1603
1604                 /* Obtain the rect */
1605 #if TARGET_API_MAC_CARBON
1606                 GetWindowBounds( (WindowRef)td->w, kWindowContentRgn, &globalRect );
1607 #else
1608                 globalRect = td->w->portRect;
1609                 LocalToGlobal((Point*)&globalRect.top);
1610                 LocalToGlobal((Point*)&globalRect.bottom);
1611 #endif
1612
1613                 /* Obtain the proper GDH */
1614                 mainGDH = GetMaxDevice(&globalRect);
1615
1616                 /* Extract GWorld and GDH */
1617                 GetGWorld(&windowGWorld, &currentGDH);
1618
1619                 /* Obtain base pixmap */
1620                 basePixMap = (**mainGDH).gdPMap;
1621
1622                 /* Save pixel depth */
1623                 td->pixelDepth = (**basePixMap).pixelSize;
1624
1625                 /* Save Window GWorld */
1626                 td->theGWorld = windowGWorld;
1627
1628                 /* Save Window GDH */
1629                 td->theGDH = currentGDH;
1630
1631                 /* Save main GDH */
1632                 td->mainSWGDH = mainGDH;
1633         }
1634
1635 #endif /* ANGBAND_LITE_MAC */
1636
1637         {
1638                 Rect            portRect;
1639
1640 #if TARGET_API_MAC_CARBON
1641                 GetWindowBounds( (WindowRef)td->w, kWindowContentRgn, &portRect );
1642                 global_to_local( &portRect );
1643 #else
1644                 portRect = td->w->portRect;
1645 #endif
1646                 /* Clip to the window */
1647                 ClipRect(&portRect);
1648
1649                 /* Erase the window */
1650                 EraseRect(&portRect);
1651
1652                 /* Invalidate the window */
1653 #if TARGET_API_MAC_CARBON
1654                 InvalWindowRect((WindowRef)(td->w), (const Rect *)(&portRect));
1655 #else
1656                 InvalRect(&portRect);
1657 #endif
1658
1659                 /* Display the window if needed */
1660                 if (td->mapped) ShowWindow(td->w);
1661
1662                 /* Hack -- set "mapped" flag */
1663                 t->mapped_flag = td->mapped;
1664
1665                 /* Forget color */
1666                 td->last = -1;
1667         }
1668         /* Oops */
1669 /*      if (err == noErr)
1670         {
1671                 
1672         }*/
1673 }
1674
1675
1676
1677 /*
1678  * Nuke an old Term
1679  */
1680 static void Term_nuke_mac(term *t)
1681 {
1682
1683 #pragma unused (t)
1684
1685         /* XXX */
1686 }
1687
1688
1689
1690 /*
1691  * Unused
1692  */
1693 static errr Term_user_mac(int n)
1694 {
1695
1696 #pragma unused (n)
1697
1698         /* Success */
1699         return (0);
1700 }
1701
1702
1703
1704 /*
1705  * React to changes
1706  */
1707 static errr Term_xtra_mac_react(void)
1708 {
1709         term_data *td = (term_data*)(Term->data);
1710
1711
1712         /* Reset color */
1713         td->last = -1;
1714
1715 #ifdef ANGBAND_LITE_MAC
1716
1717         /* Nothing */
1718         
1719 #else /* ANGBAND_LITE_MAC */
1720
1721         /* Handle sound */
1722         if (use_sound != arg_sound)
1723         {
1724                 /* Apply request */
1725                 use_sound = arg_sound;
1726         }
1727
1728         
1729         /* Handle transparency */
1730         if (use_newstyle_graphics != arg_newstyle_graphics)
1731         {
1732                 globe_nuke();
1733
1734                 if (globe_init() != 0)
1735                 {
1736                         plog("Cannot initialize graphics!");
1737                         arg_graphics = FALSE;
1738                         arg_newstyle_graphics = FALSE;
1739                 }
1740
1741                 /* Apply request */
1742                 use_newstyle_graphics = arg_newstyle_graphics;
1743
1744                 /* Apply and Verify */
1745                 term_data_check_size(td);
1746
1747                 /* Resize the window */
1748                 term_data_resize(td);
1749  
1750                 /* Reset visuals */
1751                 reset_visuals();
1752         }
1753         
1754         /* Handle graphics */
1755         if (use_graphics != arg_graphics)
1756         {
1757                 /* Initialize graphics */
1758
1759                 if (!use_graphics && !frameP && (globe_init() != 0))
1760                 {
1761 #ifdef JP
1762                         plog("¥°¥é¥Õ¥£¥Ã¥¯¤Î½é´ü²½¤Ï½ÐÍè¤Þ¤»¤ó¤Ç¤·¤¿.");
1763 #else
1764                         plog("Cannot initialize graphics!");
1765 #endif
1766                         arg_graphics = FALSE;
1767                 }
1768
1769                 /* Apply request */
1770                 use_graphics = arg_graphics;
1771
1772                 /* Apply and Verify */
1773                 term_data_check_size(td);
1774
1775                 /* Resize the window */
1776                 term_data_resize(td);
1777
1778                 /* Reset visuals */
1779                 reset_visuals();
1780         }
1781
1782 #endif /* ANGBAND_LITE_MAC */
1783
1784         /* Success */
1785         return (0);
1786 }
1787
1788
1789 /*
1790  * Do a "special thing"
1791  */
1792 static errr Term_xtra_mac(int n, int v)
1793 {
1794         term_data *td = (term_data*)(Term->data);
1795
1796         Rect r;
1797
1798         /* Analyze */
1799         switch (n)
1800         {
1801                 /* Make a noise */
1802                 case TERM_XTRA_NOISE:
1803                 {
1804                         /* Make a noise */
1805                         SysBeep(1);
1806
1807                         /* Success */
1808                         return (0);
1809                 }
1810
1811 #ifdef ANGBAND_LITE_MAC
1812
1813                 /* Nothing */
1814
1815 #else /* ANGBAND_LITE_MAC */
1816
1817                 /* Make a sound */
1818                 case TERM_XTRA_SOUND:
1819                 {
1820                         Handle handle;
1821
1822                         Str255 sound;
1823
1824 #if 0
1825                         short oldResFile;
1826                         short newResFile;
1827
1828                         /* Open the resource file */
1829                         oldResFile = CurResFile();
1830                         newResFile = OpenResFile(sound);
1831
1832                         /* Close the resource file */
1833                         CloseResFile(newResFile);
1834                         UseResFile(oldResFile);
1835 #endif
1836
1837                         /* Get the proper sound name */
1838                         sprintf((char*)sound + 1, "%.16s.wav", angband_sound_name[v]);
1839                         sound[0] = strlen((char*)sound + 1);
1840
1841                         /* Obtain resource XXX XXX XXX */
1842                         handle = Get1NamedResource('snd ', sound);
1843                         if( handle == NULL || ext_sound )
1844                                 handle = GetNamedResource('snd ', sound);
1845                         
1846                         /* Oops */
1847                         if (handle && soundmode[soundchoice[v]] == true)
1848                         {
1849                                 /* Load and Lock */
1850                                 LoadResource(handle);
1851                                 HLock(handle);
1852
1853                                 /* Play sound (wait for completion) */
1854                                 SndPlay(nil, (SndListHandle)handle, true);
1855
1856                                 /* Unlock and release */
1857                                 HUnlock(handle);
1858                                 ReleaseResource(handle);
1859                         }
1860                         /* Success */
1861                         return (0);
1862                 }
1863
1864 #endif /* ANGBAND_LITE_MAC */
1865
1866                 /* Process random events */
1867                 case TERM_XTRA_BORED:
1868                 {
1869                         /* Process an event */
1870                         (void)CheckEvents(FALSE);
1871
1872                         /* Success */
1873                         return (0);
1874                 }
1875
1876                 /* Process pending events */
1877                 case TERM_XTRA_EVENT:
1878                 {
1879                         /* Process an event */
1880                         (void)CheckEvents(v);
1881
1882                         /* Success */
1883                         return (0);
1884                 }
1885
1886                 /* Flush all pending events (if any) */
1887                 case TERM_XTRA_FLUSH:
1888                 {
1889                         /* Hack -- flush all events */
1890                         while (CheckEvents(TRUE)) /* loop */;
1891
1892                         /* Success */
1893                         return (0);
1894                 }
1895
1896                 /* Hack -- Change the "soft level" */
1897                 case TERM_XTRA_LEVEL:
1898                 {
1899                         /* Activate if requested */
1900                         if (v) activate(td->w);
1901
1902                         /* Success */
1903                         return (0);
1904                 }
1905
1906                 /* Clear the screen */
1907                 case TERM_XTRA_CLEAR:
1908                 {
1909                         Rect            portRect;
1910                         
1911 #if TARGET_API_MAC_CARBON
1912                         GetWindowBounds( (WindowRef)td->w, kWindowContentRgn, &portRect );
1913                         global_to_local( &portRect );
1914 #else
1915                         portRect = td->w->portRect;
1916 #endif
1917
1918                         /* No clipping XXX XXX XXX */
1919                         ClipRect(&portRect);
1920
1921                         /* Erase the window */
1922                         EraseRect(&portRect);
1923
1924                         /* Set the color */
1925                         term_data_color(td, TERM_WHITE);
1926
1927                         /* Frame the window in white */
1928                         MoveTo(0, 0);
1929                         LineTo(0, td->size_hgt-1);
1930                         LineTo(td->size_wid-1, td->size_hgt-1);
1931                         LineTo(td->size_wid-1, 0);
1932
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;
1938                         ClipRect(&r);
1939
1940                         /* Success */
1941                         return (0);
1942                 }
1943
1944                 /* React to changes */
1945                 case TERM_XTRA_REACT:
1946                 {
1947                         /* React to changes */
1948                         return (Term_xtra_mac_react());
1949                 }
1950
1951                 /* Delay (milliseconds) */
1952                 case TERM_XTRA_DELAY:
1953                 {
1954                         /* If needed */
1955                         if (v > 0)
1956                         {
1957 #if TARGET_API_MAC_CARBON
1958                                 EventRecord tmp;
1959                                 UInt32 ticks;
1960
1961                                 /* Convert millisecs to ticks */
1962                                 ticks = (v * 60L) / 1000;
1963
1964                                 /*
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.
1970                                  */
1971                                 WaitNextEvent(~everyEvent, &tmp, ticks, nil);
1972 #else
1973                                 long m = TickCount() + (v * 60L) / 1000;
1974
1975                                 /* Wait for it */
1976                                 while (TickCount() < m) /* loop */;
1977 #endif
1978                         }
1979
1980                         /* Success */
1981                         return (0);
1982                 }
1983         }
1984
1985         /* Oops */
1986         return (1);
1987 }
1988
1989
1990
1991 /*
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).
1996  */
1997 static errr Term_curs_mac(int x, int y)
1998 {
1999         Rect r;
2000
2001         term_data *td = (term_data*)(Term->data);
2002
2003         /* Set the color */
2004         term_data_color(td, TERM_YELLOW);
2005
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;
2011
2012         FrameRect(&r);
2013
2014         /* Success */
2015         return (0);
2016 }
2017
2018
2019 /*
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).
2024  */
2025 static errr Term_bigcurs_mac(int x, int y)
2026 {
2027         Rect r;
2028
2029         term_data *td = (term_data*)(Term->data);
2030
2031         /* Set the color */
2032         term_data_color(td, TERM_YELLOW);
2033
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;
2039
2040         FrameRect(&r);
2041
2042         /* Success */
2043         return (0);
2044 }
2045
2046
2047 /*
2048  * Low level graphics (Assumes valid input)
2049  *
2050  * Erase "n" characters starting at (x,y)
2051  */
2052 static errr Term_wipe_mac(int x, int y, int n)
2053 {
2054         Rect r;
2055
2056         term_data *td = (term_data*)(Term->data);
2057
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;
2063         EraseRect(&r);
2064
2065         /* Success */
2066         return (0);
2067 }
2068
2069
2070 /*
2071  * Low level graphics.  Assumes valid input.
2072  *
2073  * Draw several ("n") chars, with an attr, at a given location.
2074  */
2075 static errr Term_text_mac(int x, int y, int n, byte a, const char *cp)
2076 {
2077         int xp, yp;
2078
2079         term_data *td = (term_data*)(Term->data);
2080
2081         /* Set the color */
2082         term_data_color(td, (a & 0x0F));
2083
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;
2087
2088         /* Move to the correct location */
2089         MoveTo(xp, yp);
2090
2091         /* Draw the character */
2092         if (n == 1) DrawChar(*cp);
2093
2094         /* Draw the string */
2095         else DrawText(cp, 0, n);
2096
2097         /* Success */
2098         return (0);
2099 }
2100
2101
2102 /*
2103  * Low level graphics (Assumes valid input)
2104  *
2105  * Erase "n" characters starting at (x,y)
2106  */
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)
2109 {
2110         int i;
2111         Rect r2;
2112         term_data *td = (term_data*)(Term->data);
2113         GDHandle saveGDevice;
2114         GWorldPtr saveGWorld;
2115         
2116         PixMapHandle PortPix;
2117         
2118         /* Save GWorld */
2119         GetGWorld(&saveGWorld, &saveGDevice);
2120         
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;
2125         
2126         if( n > 1 )
2127         {
2128                 /* Instantiate font */
2129                 TextFont(td->font_id);
2130                 TextSize(td->font_size);
2131                 TextFace(td->font_face);
2132                 
2133                 /* Restore colors */
2134                 BackColor(blackColor);
2135                 ForeColor(whiteColor);
2136         }
2137         else
2138         {
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;*/
2143                 
2144         }
2145                 
2146         /* Scan the input */
2147         for (i = 0; i < n; i++)
2148         {
2149                 bool done = FALSE;
2150
2151                 byte a = ap[i];
2152                 char c = cp[i];
2153
2154                 /* Second byte of bigtile */
2155                 if (use_bigtile && a == 255)
2156                 {
2157                         /* Advance */
2158                         r2.left += td->tile_wid;
2159
2160                         continue;
2161                 }
2162
2163                 /* Prepare right of rectangle now */
2164                 r2.right = r2.left + td->tile_wid;
2165
2166 #ifdef ANGBAND_LITE_MAC
2167
2168                 /* No graphics */
2169
2170 #else /* ANGBAND_LITE_MAC */
2171
2172                 /* Graphics -- if Available and Needed */
2173                 if (use_graphics && ((byte)a & 0x80) && ((byte)c & 0x80))
2174                 {
2175 #if TARGET_API_MAC_CARBON
2176                         PixMapHandle    srcBitMap = GetGWorldPixMap(frameP->framePort);
2177                         PixMapHandle    destBitMap;
2178 #else
2179                         BitMapPtr srcBitMap = (BitMapPtr)(frameP->framePix);
2180                         BitMapPtr destBitMap;
2181 #endif
2182                                 
2183                         int col, row;
2184                         Rect r1;
2185
2186                         Rect terrain_r;
2187                         bool terrain_flag = FALSE;
2188                         byte ta = tap[i];
2189                         char tc = tcp[i];
2190
2191                         if ((a != ta || c != tc) &&
2192                             ((byte)ta & 0x80) && ((byte)tc & 0x80))
2193                         {
2194                                 /* Row and Col */
2195                                 row = ((byte)ta & 0x7F);
2196                                 col = ((byte)tc & 0x7F);
2197
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;
2203
2204                                 terrain_flag = TRUE;
2205                         }
2206
2207                         /* Row and Col */
2208                         row = ((byte)a & 0x7F);
2209                         col = ((byte)c & 0x7F);
2210                         
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;
2216
2217                         /* Hardwire CopyBits */
2218                         BackColor(whiteColor);
2219                         ForeColor(blackColor);
2220
2221                         /* Draw the picture */
2222 #if TARGET_API_MAC_CARBON
2223                         destBitMap = GetPortPixMap(GetWindowPort( td->w ));
2224 #else
2225                         destBitMap = (BitMapPtr)&(td->w->portBits);
2226 #endif
2227                         if (use_bigtile) r2.right += td->tile_wid;
2228
2229                         if (terrain_flag)
2230                         {
2231                                 /*
2232                                  * Source mode const = srcCopy:
2233                                  *
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
2241                                  */
2242 #if TARGET_API_MAC_CARBON
2243                                 CopyBits( (BitMap *) *srcBitMap, (BitMap *) *destBitMap, &terrain_r, &r2, srcCopy, NULL);
2244 #else
2245                                 CopyBits( srcBitMap, destBitMap, &terrain_r, &r2, srcCopy, NULL );
2246 #endif
2247                                 /*
2248                                  * Draw transparent tile
2249                                  * BackColor is ignored and the destination is
2250                                  * left untouched
2251                                  */
2252                                 BackColor(blackColor);
2253 #if TARGET_API_MAC_CARBON
2254                                 CopyBits( (BitMap *) *srcBitMap, (BitMap *) *destBitMap, &r1, &r2, transparent, NULL);
2255 #else
2256                                 CopyBits( srcBitMap, destBitMap, &r1, &r2, transparent, NULL );
2257 #endif
2258                         }
2259                         else
2260                         {
2261 #if TARGET_API_MAC_CARBON
2262                                 CopyBits( (BitMap *) *srcBitMap, (BitMap *) *destBitMap, &r1, &r2, srcCopy, NULL);
2263 #else
2264                                 CopyBits( srcBitMap, destBitMap, &r1, &r2, srcCopy, NULL );
2265 #endif
2266                         }
2267
2268                         /* Restore colors */
2269                         BackColor(blackColor);
2270                         ForeColor(whiteColor);
2271
2272                         /* Forget color */
2273                         td->last = -1;
2274
2275                         /* Done */
2276                         done = TRUE;
2277                 }
2278
2279 #endif /* ANGBAND_LITE_MAC */
2280
2281                 /* Normal */
2282                 if (!done)
2283                 {
2284                         int xp, yp;
2285
2286                         /* Set the color */
2287                         term_data_color(td, (a & 0x0F));
2288                         
2289                         /* Starting pixel */
2290                         xp = r2.left + td->tile_o_x;
2291                         yp = r2.top + td->tile_o_y;
2292                         
2293                         /* Move to the correct location */
2294                         MoveTo(xp, yp);
2295
2296 #ifdef JP
2297                         if (iskanji(c))
2298                         {
2299                                 /* Double width rectangle */
2300                                 r2.right += td->tile_wid;
2301
2302                                 /* Erase */
2303                                 EraseRect(&r2);
2304
2305                                 /* Draw the character */
2306                                 DrawText(cp, i, 2);
2307                                 
2308                                 i++;
2309                                 
2310                                 r2.left += td->tile_wid;
2311                         }
2312                         else
2313 #endif
2314                         {
2315                                 /* Erase */
2316                                 EraseRect(&r2);
2317
2318                                 /* Draw the character */
2319                                 DrawChar(c);
2320                         }
2321                 }
2322
2323                 /* Advance */
2324                 r2.left += td->tile_wid;
2325         }
2326                 
2327         /* Success */
2328         return (0);
2329 }
2330
2331
2332 /*
2333  * Create and initialize window number "i"
2334  */
2335 static void term_data_link(int i)
2336 {
2337         term *old = Term;
2338
2339         term_data *td = &data[i];
2340
2341         /* Only once */
2342         if (td->t) return;
2343
2344         /* Require mapped */
2345         if (!td->mapped) return;
2346
2347         /* Allocate */
2348         MAKE(td->t, term);
2349
2350         /* Initialize the term */
2351         term_init(td->t, td->cols, td->rows, td->keys);
2352
2353         /* Use a "software" cursor */
2354         td->t->soft_cursor = TRUE;
2355
2356         /* Erase with "white space" */
2357         td->t->attr_blank = TERM_WHITE;
2358         td->t->char_blank = ' ';
2359
2360         /* Prepare the init/nuke hooks */
2361         td->t->init_hook = Term_init_mac;
2362         td->t->nuke_hook = Term_nuke_mac;
2363
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;
2372
2373         /* Link the local structure */
2374         td->t->data = (vptr)(td);
2375
2376         /* Activate it */
2377         Term_activate(td->t);
2378
2379         /* Global pointer */
2380         angband_term[i] = td->t;
2381
2382         /* Activate old */
2383         Term_activate(old);
2384 }
2385
2386
2387
2388
2389 /*
2390  * Set the "current working directory" (also known as the "default"
2391  * volume/directory) to the location of the current application.
2392  *
2393  * Code by: Maarten Hazewinkel (mmhazewi@cs.ruu.nl)
2394  *
2395  * This function does not appear to work correctly with System 6.
2396  */
2397 static void SetupAppDir(void)
2398 {
2399         FCBPBRec fcbBlock;
2400         OSErr err = noErr;
2401         char errString[100];
2402
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);
2410         if (err != noErr)
2411         {
2412 #ifdef JP
2413                 sprintf(errString, "PBGetFCBInfo ¥¨¥é¡¼ #%d.\r ½ªÎ»¤·¤Þ¤¹.", err);
2414 #else
2415                 sprintf(errString, "Fatal PBGetFCBInfo Error #%d.\r Exiting.", err);
2416 #endif
2417                 mac_warning(errString);
2418                 ExitToShell();
2419         }
2420
2421         /* Extract the Vol and Dir */
2422         app_vol = fcbBlock.ioFCBVRefNum;
2423         app_dir = fcbBlock.ioFCBParID;
2424
2425         /* Set the current working directory to that location */
2426         err = HSetVol(NULL, app_vol, app_dir);
2427         if (err != noErr)
2428         {
2429 #ifdef JP
2430                 sprintf(errString, "HSetVol ¥¨¥é¡¼ #%d.\r ½ªÎ»¤·¤Þ¤¹.", err);
2431 #else
2432                 sprintf(errString, "Fatal HSetVol Error #%d.\r Exiting.", err);
2433 #endif
2434                 mac_warning(errString);
2435                 ExitToShell();
2436         }
2437 }
2438
2439
2440
2441
2442 /*
2443  * Global "preference" file pointer
2444  */
2445 static FILE *fff;
2446
2447 /*
2448  * Read a "short" from the file
2449  */
2450 static int getshort(void)
2451 {
2452         int x = 0;
2453         char buf[256];
2454         if (0 == my_fgets(fff, buf, sizeof(buf))) x = atoi(buf);
2455         return (x);
2456 }
2457
2458 /*
2459  * Dump a "short" to the file
2460  */
2461 static void putshort(int x)
2462 {
2463         fprintf(fff, "%d\n", x);
2464 }
2465
2466
2467
2468 /*
2469  * Write the "preference" data to the current "file"
2470  */
2471 static void save_prefs(void)
2472 {
2473         int i;
2474
2475         term_data *td;
2476
2477
2478         /*** The current version ***/
2479
2480         putshort(FAKE_VERSION);
2481         putshort(FAKE_VER_MAJOR);
2482         putshort(FAKE_VER_MINOR);
2483         putshort(FAKE_VER_PATCH);
2484
2485         putshort(arg_sound);
2486         putshort(arg_graphics);
2487         putshort(arg_newstyle_graphics);
2488         putshort(arg_bigtile);
2489         
2490         /* SoundMode */
2491         for( i = 0 ; i < 7 ; i++ )
2492                 putshort(soundmode[i]);
2493         
2494         /* Dump */
2495         for (i = 0; i < MAX_TERM_DATA; i++)
2496         {
2497                 /* Access */
2498                 td = &data[i];
2499
2500                 putshort(td->mapped);
2501
2502                 putshort(td->font_id);
2503                 putshort(td->font_size);
2504                 putshort(td->font_face);
2505
2506                 putshort(td->tile_wid);
2507                 putshort(td->tile_hgt);
2508
2509                 putshort(td->cols);
2510                 putshort(td->rows);
2511
2512                 putshort(td->r.left);
2513                 putshort(td->r.top);
2514         }
2515 }
2516
2517
2518 /*
2519  * Load the preferences from the current "file"
2520  *
2521  * XXX XXX XXX Being able to undefine various windows is
2522  * slightly bizarre, and may cause problems.
2523  */
2524 static void load_prefs(void)
2525 {
2526         int i;
2527
2528         int old_version, old_major, old_minor, old_patch;
2529
2530         term_data *td;
2531         MenuHandle m;
2532
2533         /*** Version information ***/
2534
2535         /* Preferences version */
2536         old_version = getshort();
2537         old_major = getshort();
2538         old_minor = getshort();
2539         old_patch = getshort();
2540
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))
2546         {
2547                 /* Message */
2548                 #ifdef JP
2549                 mac_warning("¸Å¤¤½é´üÀßÄê¥Õ¥¡¥¤¥ë¤ò̵»ë¤·¤Þ¤¹.");
2550                 #else
2551                 mac_warning("Ignoring old preferences.");
2552                 #endif
2553                 /* Ignore */
2554                 return;
2555         }
2556
2557         arg_sound = getshort();
2558         arg_graphics = getshort();
2559         arg_newstyle_graphics = getshort();
2560         use_newstyle_graphics = arg_newstyle_graphics;
2561         
2562         if (use_newstyle_graphics == true)
2563         {
2564                 ANGBAND_GRAF = "new";
2565                 arg_newstyle_graphics = true;
2566                 grafWidth = grafHeight = 16;
2567                 pictID = 1002;
2568         }
2569         else
2570         {
2571                 ANGBAND_GRAF = "old";
2572                 arg_newstyle_graphics = false;
2573                 grafWidth = grafHeight = 8;
2574                 pictID = 1001;
2575         }
2576
2577         arg_bigtile = getshort();
2578         use_bigtile = arg_bigtile;
2579         
2580         /* SoundMode */
2581         for( i = 0 ; i < 7 ; i++ )
2582                 soundmode[i] = getshort();
2583         
2584         /* Special menu */
2585         m = GetMenuHandle(134);
2586
2587 #if TARGET_API_MAC_CARBON
2588         /* Item "arg_sound" */
2589         CheckMenuItem(m, 1, arg_sound);
2590
2591         /* Item "arg_graphics" */
2592         CheckMenuItem(m, 2, arg_graphics);
2593         
2594         /* Item "arg_newstyle_graphics"*/
2595         CheckMenuItem(m, 8, arg_newstyle_graphics);
2596 #else
2597         /* Item "arg_sound" */
2598         CheckItem(m, 1, arg_sound);
2599
2600         /* Item "arg_graphics" */
2601         CheckItem(m, 2, arg_graphics);
2602         
2603         /* Item "arg_newstyle_graphics"*/
2604         CheckItem(m, 8, arg_newstyle_graphics);
2605 #endif
2606
2607         /* Windows */
2608         for (i = 0; i < MAX_TERM_DATA; i++)
2609         {
2610                 /* Access */
2611                 td = &data[i];
2612
2613                 td->mapped = getshort();
2614
2615                 td->font_id = getshort();
2616                 td->font_size = getshort();
2617                 td->font_face = getshort();
2618
2619                 td->tile_wid = getshort();
2620                 td->tile_hgt = getshort();
2621
2622                 td->cols = getshort();
2623                 td->rows = getshort();
2624
2625                 td->r.left = getshort();
2626                 td->r.top = getshort();
2627
2628                 /* Done */
2629                 if (feof(fff)) break;
2630         }
2631 }
2632
2633
2634
2635
2636 /*
2637  * Hack -- default data for a window
2638  */
2639 static void term_data_hack(term_data *td)
2640 {
2641         short fid;
2642
2643 #ifdef JP
2644 #if TARGET_API_MAC_CARBON
2645         /* Default to Osaka font (Japanese) */
2646         fid = FMGetFontFamilyFromName( "\pOsaka¡ÝÅùÉý" );
2647 #else
2648         GetFNum( "\pÅùÉýÌÀÄ«", &fid);
2649         SetFScaleDisable( true );
2650 #endif
2651 #else
2652         /* Default to Monaco font */
2653         GetFNum("\pmonaco", &fid);
2654 #endif
2655
2656         /* Wipe it */
2657         WIPE(td, term_data);
2658
2659         /* No color */
2660         td->last = -1;
2661
2662         /* Default borders */
2663         td->size_ow1 = 2;
2664         td->size_ow2 = 2;
2665         td->size_oh2 = 2;
2666
2667         /* Start hidden */
2668         td->mapped = FALSE;
2669
2670         /* Default font */
2671         td->font_id = fid;
2672
2673         /* Default font size */
2674         td->font_size = 12;
2675
2676         /* Default font face */
2677         td->font_face = 0;
2678
2679         /* Default size */
2680         td->rows = 24;
2681         td->cols = 80;
2682
2683         /* Default position */
2684         td->r.left = 10;
2685         td->r.top = 40;
2686
2687         /* Minimal keys */
2688         td->keys = 16;
2689 }
2690
2691
2692 /*
2693  * Read the preference file, Create the windows.
2694  *
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.
2698  */
2699 static void init_windows(void)
2700 {
2701         int i, b = 0;
2702
2703         term_data *td;
2704
2705         SysEnvRec env;
2706         short savev;
2707         long saved;
2708
2709         bool oops;
2710
2711
2712         /*** Default values ***/
2713
2714         /* Initialize (backwards) */
2715         for (i = MAX_TERM_DATA - 1; i >= 0; i--)
2716         {
2717                 int n;
2718
2719                 cptr s;
2720
2721                 /* Obtain */
2722                 td = &data[i];
2723
2724                 /* Defaults */
2725                 term_data_hack(td);
2726
2727                 /* Obtain title */
2728                 s = angband_term_name[i];
2729
2730                 /* Get length */
2731                 n = strlen(s);
2732
2733                 /* Maximal length */
2734                 if (n > 15) n = 15;
2735
2736                 /* Copy the title */
2737                 strncpy((char*)(td->title) + 1, s, n);
2738
2739                 /* Save the length */
2740                 td->title[0] = n;
2741
2742                 /* Tile the windows */
2743                 td->r.left += (b * 30);
2744                 td->r.top += (b * 30);
2745
2746                 /* Tile */
2747                 b++;
2748         }
2749
2750
2751         /*** Load preferences ***/
2752
2753         /* Assume failure */
2754         oops = TRUE;
2755
2756         /* Assume failure */
2757         fff = NULL;
2758
2759 #ifdef USE_SFL_CODE
2760
2761         /* Block */
2762         if (TRUE)
2763         {
2764                 OSErr   err;
2765                 short   vref;
2766                 long    dirID;
2767                 char    foo[128];
2768
2769                 /* Find the folder */
2770                 err = FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder,
2771                                  &vref, &dirID);
2772
2773                 /* Success */
2774                 if (!err)
2775                 {
2776                         /* Extract a path name */
2777                         PathNameFromDirID(dirID, vref, (StringPtr)foo);
2778
2779                         /* Convert the string */
2780                         ptocstr((StringPtr)foo);
2781
2782                         /* Append the preference file name */
2783                         strcat(foo, PREF_FILE_NAME);
2784
2785                         /* Open the preference file */
2786                         fff = fopen(foo, "r");
2787
2788                         /* Success */
2789                         oops = FALSE;
2790                 }
2791         }
2792
2793 #endif /* USE_SFL_CODE */
2794
2795 #if TARGET_API_MAC_CARBON
2796 #else
2797         /* Oops */
2798         if (oops)
2799         {
2800                 /* Save */
2801                 HGetVol(0, &savev, &saved);
2802
2803                 /* Go to the "system" folder */
2804                 SysEnvirons(curSysEnvVers, &env);
2805                 SetVol(0, env.sysVRefNum);
2806
2807                 /* Open the file */
2808                 fff = fopen(PREF_FILE_NAME, "r");
2809
2810                 /* Restore */
2811                 HSetVol(0, savev, saved);
2812         }
2813 #endif
2814
2815         /* Load preferences */
2816         if (fff)
2817         {
2818                 /* Load a real preference file */
2819                 load_prefs();
2820
2821                 /* Close the file */
2822                 my_fclose(fff);
2823         }
2824
2825
2826         /*** Instantiate ***/
2827
2828         /* Main window */
2829         td = &data[0];
2830
2831         /* Many keys */
2832         td->keys = 1024;
2833
2834         /* Start visible */
2835         td->mapped = TRUE;
2836
2837         /* Link (backwards, for stacking order) */
2838         for (i = MAX_TERM_DATA - 1; i >= 0; i--)
2839         {
2840                 term_data_link(i);
2841         }
2842
2843         /* Main window */
2844         td = &data[0];
2845
2846         /* Main window */
2847         Term_activate(td->t);
2848 }
2849
2850 static void init_sound( void )
2851 {
2852         int err, i;
2853         CInfoPBRec pb;
2854         SignedByte              permission = fsRdPerm;
2855         pascal short    ret;
2856         
2857         Handle handle;
2858         Str255 sound;
2859
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;
2866
2867         /* Check for errors */
2868         err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
2869
2870         /* Success */
2871         if ((err == noErr) && (pb.dirInfo.ioFlAttrib & 0x10))
2872         {
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;
2879
2880                 /* Check for errors */
2881                 err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
2882                         
2883                         /* Success */
2884                 if ((err == noErr) && (pb.dirInfo.ioFlAttrib & 0x10))
2885                 {
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;
2892
2893                         /* Check for errors */
2894                         err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
2895
2896                         /* Success */
2897                         if ((err == noErr) && (pb.dirInfo.ioFlAttrib & 0x10))
2898                         {
2899                                 ret = HOpenResFile( app_vol , pb.dirInfo.ioDrDirID , "\psound.rsrc" , permission );
2900                                 if( ret != -1 ){
2901                                         ext_sound = 1;
2902                                         
2903                                         for( i = 0 ; i < 7 ; i++ )
2904                                                         soundmode[i] = false;
2905                                         
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);
2910
2911                                                 /* Obtain resource XXX XXX XXX */
2912                                                 handle = Get1NamedResource('snd ', sound);
2913                                                 if( handle == NULL || ext_sound )
2914                                                         handle = GetNamedResource('snd ', sound);
2915                                                 
2916                                                 if( handle )
2917                                                         soundmode[soundchoice[i]] = true;
2918                                                 
2919                                         }
2920                                 }
2921                         }
2922                 }
2923         }
2924 }
2925
2926 static void init_graf( void )
2927 {
2928         int err, i;
2929         CInfoPBRec pb;
2930         SignedByte              permission = fsRdPerm;
2931         pascal short    ret;
2932         
2933         Handle handle;
2934         Str255 graf;
2935
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;
2942
2943         /* Check for errors */
2944         err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
2945
2946         /* Success */
2947         if ((err == noErr) && (pb.dirInfo.ioFlAttrib & 0x10))
2948         {
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;
2955
2956                 /* Check for errors */
2957                 err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
2958                         
2959                 /* Success */
2960                 if ((err == noErr) && (pb.dirInfo.ioFlAttrib & 0x10))
2961                 {
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;
2968
2969                         /* Check for errors */
2970                         err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
2971
2972                         /* Success */
2973                         if ((err == noErr) && (pb.dirInfo.ioFlAttrib & 0x10))
2974                         {
2975                                 ret = HOpenResFile( app_vol , pb.dirInfo.ioDrDirID , "\pgraf.rsrc" , permission );
2976                                 if (ret != -1)
2977                                 {
2978                                         ext_graf = 1;
2979
2980                                         /* Obtain resource XXX XXX XXX */
2981                                         handle = Get1NamedResource('PICT', graf);
2982                                         if ( handle == NULL || ext_graf )
2983                                                 handle = GetNamedResource('PICT', "\pgraf.rsrc");
2984                                 }
2985                         }
2986                 }
2987         }
2988 }
2989
2990 #ifdef CHUUKEI
2991 /*
2992
2993 */
2994 static void init_chuukei( void )
2995 {
2996         char path[1024];
2997         char tmp[1024];
2998         FILE *fp;
2999         
3000         path_build(path, sizeof(path), ANGBAND_DIR_XTRA, "chuukei.txt");
3001
3002         fp = fopen(path, "r");
3003         if(!fp)
3004                 return;
3005         
3006         /* Read a line */
3007         if (fgets(tmp, 1024, fp)){
3008                 if(tmp[0] == '-'){
3009                         int n = strlen(tmp);
3010                         tmp[n-1] = 0;
3011                         switch(tmp[1]){
3012                         case 'p':
3013                         {
3014                                 if (!tmp[2]) break;
3015                                 chuukei_server = TRUE;
3016                                 if(connect_chuukei_server(&tmp[2])<0){
3017                                         msg_print("connect fail");
3018                                         return;
3019                                 }
3020                                 msg_print("connect");
3021                                 msg_print(NULL);
3022                                 break;
3023                         }
3024
3025                         case 'c':
3026                         {
3027                                 chuukei_client = TRUE;
3028                                 connect_chuukei_server(&tmp[2]);
3029                                 play_game(FALSE);
3030                                 quit(NULL);
3031                         }
3032                         }
3033                 }
3034                 
3035         }
3036         fclose(fp);
3037         
3038 }
3039 #endif
3040
3041 /*
3042
3043 */
3044 short InevrtCheck( DialogPtr targetDlg, short check )
3045 {
3046         Handle  checkH;
3047         short   itemType;
3048         long    result;
3049         Rect    box;
3050         
3051         GetDialogItem( targetDlg, check, &itemType, &checkH, &box );
3052         result = (GetControlValue( (ControlHandle)checkH ) + 1 ) % 2;
3053         SetControlValue( (ControlHandle)checkH , result );
3054         return result ;
3055
3056 }
3057
3058 /*
3059
3060 */
3061 short SetCheck( DialogPtr targetDlg, short check, long result )
3062 {
3063         Handle  checkH;
3064         short   itemType;
3065
3066         Rect    box;
3067         
3068         GetDialogItem( targetDlg, check, &itemType, &checkH, &box );
3069         SetControlValue( (ControlHandle)checkH , result );
3070         return result ;
3071
3072 }
3073
3074 /*
3075
3076 */
3077 short GetCheck( DialogPtr targetDlg, short check )
3078 {
3079         Handle  checkH;
3080         short   itemType;
3081         long    result;
3082         Rect    box;
3083         
3084         GetDialogItem( targetDlg, check, &itemType, &checkH, &box );
3085         result = GetControlValue( (ControlHandle)checkH );
3086         return result ;
3087
3088 }
3089 void SoundConfigDLog(void)
3090 {
3091         DialogPtr dialog;
3092         Rect r;
3093         short item_hit;
3094         int     i;
3095
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] );
3101         
3102         /* ShowWindow(dialog); */ 
3103         for( item_hit = 100 ; cancel < item_hit ; ){
3104                 ModalDialog(0, &item_hit);
3105                 
3106                 switch(item_hit){
3107                         case ok:
3108                                 for( i = 1 ; i < 7 ; i++ )
3109                                         soundmode[i] = GetCheck( dialog, i+2 );
3110                                 break;
3111                         case cancel:
3112                                 break;
3113                         default:
3114                                 InevrtCheck( dialog, item_hit );
3115                 }
3116         }
3117         DisposeDialog(dialog);
3118
3119 }
3120
3121
3122 /*
3123  * Exit the program
3124  */
3125 static void save_pref_file(void)
3126 {
3127         bool oops;
3128
3129         SysEnvRec env;
3130         short savev;
3131         long saved;
3132
3133
3134         /* Assume failure */
3135         oops = TRUE;
3136
3137         /* Assume failure */
3138         fff = NULL;
3139
3140         /* Text file */
3141         _ftype = 'TEXT';
3142
3143
3144 #ifdef USE_SFL_CODE
3145
3146         /* Block */
3147         if (TRUE)
3148         {
3149                 OSErr   err;
3150                 short   vref;
3151                 long    dirID;
3152                 char    foo[128];
3153
3154                 /* Find the folder */
3155                 err = FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder,
3156                                  &vref, &dirID);
3157
3158                 /* Success */
3159                 if (!err)
3160                 {
3161                         /* Extract a path name */
3162                         PathNameFromDirID(dirID, vref, (StringPtr)foo);
3163
3164                         /* Convert the string */
3165                         ptocstr((StringPtr)foo);
3166
3167                         /* Append the preference file name */
3168                         strcat(foo, PREF_FILE_NAME);
3169
3170                         /* Open the preference file */
3171                         /* my_fopen set file type and file creator for MPW */
3172                         fff = my_fopen(foo, "w");
3173
3174                         /* Success */
3175                         oops = FALSE;
3176                 }
3177         }
3178
3179 #endif /* USE_SFL_CODE */
3180
3181 #if TARGET_API_MAC_CARBON
3182 #else
3183         /* Oops */
3184         if (oops)
3185         {
3186                 /* Save */
3187                 HGetVol(0, &savev, &saved);
3188
3189                 /* Go to "system" folder */
3190                 SysEnvirons(curSysEnvVers, &env);
3191                 SetVol(0, env.sysVRefNum);
3192
3193                 /* Open the preference file */
3194                 /* my_fopen set file type and file creator for MPW */
3195                 fff = fopen(PREF_FILE_NAME, "w");
3196
3197                 /* Restore */
3198                 HSetVol(0, savev, saved);
3199         }
3200 #endif
3201
3202         /* Save preferences */
3203         if (fff)
3204         {
3205                 /* Write the preferences */
3206                 save_prefs();
3207
3208                 /* Close it */
3209                 my_fclose(fff);
3210         }
3211 }
3212
3213
3214
3215 /*
3216  * A simple "Yes/No" filter to parse "key press" events in dialog windows
3217  */
3218 static pascal Boolean ynfilter(DialogPtr dialog, EventRecord *event, short *ip)
3219 {
3220         /* Parse key press events */
3221         if (event->what == keyDown)
3222         {
3223                 int i = 0;
3224                 char c;
3225
3226                 /* Extract the pressed key */
3227                 c = (event->message & charCodeMask);
3228
3229                 /* Accept "no" and <return> and <enter> */
3230                 if ((c=='n') || (c=='N') || (c==13) || (c==3)) i = 1;
3231
3232                 /* Accept "yes" */
3233                 else if ((c=='y') || (c=='Y')) i = 2;
3234
3235                 /* Handle "yes" or "no" */
3236                 if (i)
3237                 {
3238                         short type;
3239                         ControlHandle control;
3240                         Rect r;
3241
3242                         /* Get the button */
3243                         GetDialogItem(dialog, i, &type, (Handle*)&control, &r);
3244
3245                         /* Blink button for 1/10 second */
3246                         HiliteControl(control, 1);
3247                         Term_xtra_mac(TERM_XTRA_DELAY, 100);
3248                         HiliteControl(control, 0);
3249
3250                         /* Result */
3251                         *ip = i;
3252                         return (1);
3253                 }
3254         }
3255
3256         /* Ignore */
3257         return (0);
3258 }
3259
3260
3261 /*
3262  * Handle menu: "File" + "New"
3263  */
3264 static void do_menu_file_new(void)
3265 {
3266         /* Hack */
3267         HiliteMenu(0);
3268
3269         /* Game is in progress */
3270         game_in_progress = 1;
3271
3272         /* Flush input */
3273         flush();
3274
3275         /* Play a game */
3276         play_game(TRUE);
3277
3278         /* Hack -- quit */
3279         quit(NULL);
3280 }
3281
3282
3283 /*
3284  * Handle menu: "File" + "Open"
3285  */
3286 #if TARGET_API_MAC_CARBON
3287 static void do_menu_file_open(bool all)
3288 {
3289         int err;
3290         short vrefnum;
3291         long drefnum;
3292         long junk;
3293         DirInfo pb;
3294         SFTypeList types;
3295         SFReply reply;
3296         Point topleft;
3297         BitMap screen;
3298         FSSpec  fsp;
3299         char path[1024];
3300         
3301         refnum_to_name(path, app_dir, app_vol, (char*)("\plib:save:"));
3302         
3303         FSpLocationFromFullPath( strlen(path), path, &fsp );
3304         
3305         /* Get any file */
3306         ChooseFile( (StringPtr)savefile, fsp );
3307         
3308         /* Allow cancel */
3309         if (err != noErr) return;
3310
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);
3314 */
3315         /* Hack */
3316         HiliteMenu(0);
3317
3318         /* Game is in progress */
3319         game_in_progress = 1;
3320
3321         /* Flush input */
3322         flush();
3323
3324         /* Play a game */
3325         play_game(FALSE);
3326
3327         /* Hack -- quit */
3328         quit(NULL);
3329 }
3330 #else
3331 static void do_menu_file_open(bool all)
3332 {
3333         int err;
3334         short vrefnum;
3335         long drefnum;
3336         long junk;
3337         DirInfo pb;
3338         SFTypeList types;
3339         SFReply reply;
3340         Point topleft;
3341
3342
3343         /* XXX XXX XXX */
3344
3345         /* vrefnum = GetSFCurVol(); */
3346         vrefnum = -*((short*)0x214);
3347
3348         /* drefnum = GetSFCurDir(); */
3349         drefnum = *((long*)0x398);
3350
3351         /* Descend into "lib" folder */
3352         pb.ioCompletion = NULL;
3353         pb.ioNamePtr = "\plib";
3354         pb.ioVRefNum = vrefnum;
3355         pb.ioDrDirID = drefnum;
3356         pb.ioFDirIndex = 0;
3357
3358         /* Check for errors */
3359         err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
3360
3361         /* Success */
3362         if ((err == noErr) && (pb.ioFlAttrib & 0x10))
3363         {
3364                 /* Descend into "lib/save" folder */
3365                 pb.ioCompletion = NULL;
3366                 pb.ioNamePtr = "\psave";
3367                 pb.ioVRefNum = vrefnum;
3368                 pb.ioDrDirID = pb.ioDrDirID;
3369                 pb.ioFDirIndex = 0;
3370
3371                 /* Check for errors */
3372                 err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
3373
3374                 /* Success */
3375                 if ((err == noErr) && (pb.ioFlAttrib & 0x10))
3376                 {
3377                         /* SetSFCurDir(pb.ioDrDirID); */
3378                         *((long*)0x398) = pb.ioDrDirID;
3379                 }
3380         }
3381
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;
3385
3386         /* Allow "all" files */
3387         if (all)
3388         {
3389                 /* Get any file */
3390                 SFGetFile(topleft, "\p", NULL, -1, types, NULL, &reply);
3391         }
3392
3393         /* Allow "save" files */
3394         else
3395         {
3396                 /* Legal types */
3397                 types[0] = 'SAVE';
3398
3399                 /* Get a file */
3400                 SFGetFile(topleft, "\p", NULL, 1, types, NULL, &reply);
3401         }
3402
3403         /* Allow cancel */
3404         if (!reply.good) return;
3405
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);
3409
3410         /* Hack */
3411         HiliteMenu(0);
3412
3413         /* Game is in progress */
3414         game_in_progress = 1;
3415
3416         /* Flush input */
3417         flush();
3418
3419         /* Play a game */
3420         play_game(FALSE);
3421
3422         /* Hack -- quit */
3423         quit(NULL);
3424 }
3425 #endif
3426
3427
3428 /*
3429  * Handle the "open_when_ready" flag
3430  */
3431 static void handle_open_when_ready(void)
3432 {
3433         /* Check the flag XXX XXX XXX make a function for this */
3434         if (open_when_ready && initialized && !game_in_progress)
3435         {
3436                 /* Forget */
3437                 open_when_ready = FALSE;
3438
3439                 /* Game is in progress */
3440                 game_in_progress = 1;
3441
3442                 /* Wait for it */
3443                 pause_line(23);
3444
3445                 /* Flush input */
3446                 flush();
3447
3448                 /* Play a game */
3449                 play_game(FALSE);
3450
3451                 /* Quit */
3452                 quit(NULL);
3453         }
3454 }
3455
3456
3457
3458 /*
3459  * Initialize the menus
3460  *
3461  * Verify menus 128, 129, 130
3462  * Create menus 131, 132, 133, 134
3463  *
3464  * The standard menus are:
3465  *
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 }
3475  */
3476 static void init_menubar(void)
3477 {
3478         int i, n;
3479
3480         Rect r;
3481
3482         WindowPtr tmpw;
3483
3484         MenuHandle m;
3485         OSErr           err;
3486         long            response;
3487
3488         /* Get the "apple" menu */
3489         m = GetMenu(128);
3490
3491         /* Insert the menu */
3492         InsertMenu(m, 0);
3493
3494         /* Add the DA's to the "apple" menu */
3495 #if TARGET_API_MAC_CARBON
3496 #else
3497         AppendResMenu   (m, 'DRVR');
3498 #endif
3499
3500         /* Get the "File" menu */
3501 #if TARGET_API_MAC_CARBON
3502         m = GetMenu(129);
3503         err = Gestalt( gestaltSystemVersion, &response );
3504         if ( (err == noErr) && (response >= 0x00000A00) )
3505         {
3506                 DeleteMenuItem( m, 7 );
3507         }
3508 #else
3509         m = GetMenu(129);
3510 #endif
3511
3512         /* Insert the menu */
3513         InsertMenu(m, 0);
3514
3515
3516         /* Get the "Edit" menu */
3517         m = GetMenu(130);
3518
3519         /* Insert the menu */
3520         InsertMenu(m, 0);
3521
3522
3523         /* Make the "Font" menu */
3524         #ifdef JP
3525         m = NewMenu(131, "\p¥Õ¥©¥ó¥È");
3526         #else
3527         m = NewMenu(131, "\pFont");
3528         #endif
3529         
3530         /* Insert the menu */
3531         InsertMenu(m, 0);
3532
3533         /* Add "bold" */
3534         AppendMenu(m, "\pBold");
3535
3536         /* Add "wide" */
3537         AppendMenu(m, "\pWide");
3538
3539         /* Add a separator */
3540         AppendMenu(m, "\p-");
3541
3542         /* Fake window */
3543         r.left = r.right = r.top = r.bottom = 0;
3544
3545         /* Make the fake window */
3546         tmpw = NewWindow(0, &r, "\p", false, documentProc, 0, 0, 0);
3547
3548         /* Activate the "fake" window */
3549 #if TARGET_API_MAC_CARBON
3550         SetPortWindowPort(tmpw);
3551 #else
3552         SetPort(tmpw);
3553 #endif
3554
3555         /* Default mode */
3556         TextMode(0);
3557
3558         /* Default size */
3559         TextSize(12);
3560
3561         /* Add the fonts to the menu */
3562         AppendResMenu(m, 'FONT');
3563
3564         /* Size of menu */
3565 #if TARGET_API_MAC_CARBON
3566         n = CountMenuItems(m);
3567 #else
3568         n = CountMItems(m);
3569 #endif
3570
3571         /* Scan the menu */
3572         for (i = n; i >= 4; i--)
3573         {
3574                 Str255 tmpName;
3575                 short fontNum;
3576
3577                 /* Acquire the font name */
3578                 GetMenuItemText(m, i, tmpName);
3579
3580                 /* Acquire the font index */
3581 #if TARGET_API_MAC_CARBON
3582                 fontNum = FMGetFontFamilyFromName( tmpName );
3583 #else
3584                 GetFNum(tmpName, &fontNum);
3585 #endif
3586
3587                 /* Apply the font index */
3588                 TextFont(fontNum);
3589
3590                 /* Remove non-mono-spaced fonts */
3591                 if ((CharWidth('i') != CharWidth('W')) || (CharWidth('W') == 0))
3592                 {
3593                         /* Delete the menu item XXX XXX XXX */
3594                         DeleteMenuItem  (m, i);
3595                 }
3596         }
3597
3598         /* Destroy the old window */
3599         DisposeWindow(tmpw);
3600
3601         /* Add a separator */
3602         AppendMenu(m, "\p-");
3603
3604         /* Add the fonts to the menu */
3605         AppendResMenu   (m, 'FONT');
3606
3607
3608         /* Make the "Size" menu */
3609         #ifdef JP
3610         m = NewMenu(132, "\p¥µ¥¤¥º");
3611         #else
3612         m = NewMenu(132, "\pSize");
3613         #endif
3614         
3615         /* Insert the menu */
3616         InsertMenu(m, 0);
3617
3618         /* Add some sizes (stagger choices) */
3619         for (i = 8; i <= 32; i += ((i / 16) + 1))
3620         {
3621                 Str15 buf;
3622                 
3623                 /* Textual size */
3624                 sprintf((char*)buf + 1, "%d", i);
3625                 buf[0] = strlen((char*)buf + 1);
3626
3627                 /* Add the item */
3628                 AppendMenu(m, buf);
3629         }
3630
3631
3632         /* Make the "Windows" menu */
3633         #ifdef JP
3634         m = NewMenu(133, "\p¥¦¥¤¥ó¥É¥¦");
3635         #else
3636         m = NewMenu(133, "\pWindows");
3637         #endif
3638         
3639         /* Insert the menu */
3640         InsertMenu(m, 0);
3641
3642         /* Default choices */
3643         for (i = 0; i < MAX_TERM_DATA; i++)
3644         {
3645                 Str15 buf;
3646                 
3647                 /* Describe the item */
3648                 sprintf((char*)buf + 1, "%.15s", angband_term_name[i]);
3649                 buf[0] = strlen((char*)buf + 1);
3650
3651                 /* Add the item */
3652                 AppendMenu(m, buf);
3653
3654                 /* Command-Key shortcuts */
3655                 if (i < 8) SetItemCmd(m, i + 1, '0' + i);
3656         }
3657
3658
3659         /* Make the "Special" menu */
3660         #ifdef JP
3661         m = NewMenu(134, "\pÆÃÊÌ");
3662         #else
3663         m = NewMenu(134, "\pSpecial");
3664         #endif
3665         
3666         /* Insert the menu */
3667         InsertMenu(m, 0);
3668
3669         /* Append the choices */
3670         #ifdef JP
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£²ÇÜÉý¥¿¥¤¥ëɽ¼¨");
3680         #else
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");
3690         #endif
3691
3692         /* Make the "TileWidth" menu */
3693         #ifdef JP
3694         m = NewMenu(135, "\p¥¿¥¤¥ëÉý");
3695         #else
3696         m = NewMenu(135, "\pTileWidth");
3697         #endif
3698
3699         /* Insert the menu */
3700         InsertMenu(m, 0);
3701
3702         /* Add some sizes */
3703         for (i = 4; i <= 32; i++)
3704         {
3705                 Str15 buf;
3706                 
3707                 /* Textual size */
3708                 sprintf((char*)buf + 1, "%d", i);
3709                 buf[0] = strlen((char*)buf + 1);
3710
3711                 /* Append item */
3712                 AppendMenu(m, buf);
3713         }
3714
3715
3716         /* Make the "TileHeight" menu */
3717         #ifdef JP
3718         m = NewMenu(136, "\p¥¿¥¤¥ë¹â");
3719         #else
3720         m = NewMenu(136, "\pTileHeight");
3721         #endif
3722
3723         /* Insert the menu */
3724         InsertMenu(m, 255);
3725
3726         /* Add some sizes */
3727         for (i = 4; i <= 32; i++)
3728         {
3729                 Str15 buf;
3730
3731                 /* Textual size */
3732                 sprintf((char*)buf + 1, "%d", i);
3733                 buf[0] = strlen((char*)buf + 1);
3734
3735                 /* Append item */
3736                 AppendMenu(m, buf);
3737         }
3738
3739
3740         /* Update the menu bar */
3741         DrawMenuBar();
3742 }
3743
3744
3745 /*
3746  * Prepare the menus
3747  */
3748 static void setup_menus(void)
3749 {
3750         int i, n;
3751
3752         short value;
3753
3754         Str255 s;
3755
3756         MenuHandle m;
3757
3758         term_data *td = NULL;
3759
3760
3761         /* Relevant "term_data" */
3762         for (i = 0; i < MAX_TERM_DATA; i++)
3763         {
3764                 /* Unused */
3765                 if (!data[i].t) continue;
3766
3767                 /* Notice the matching window */
3768                 if (data[i].w == FrontWindow()) td = &data[i];
3769         }
3770
3771
3772         /* File menu */
3773         m = GetMenuHandle(129);
3774
3775         /* Get menu size */
3776 #if TARGET_API_MAC_CARBON
3777         n = CountMenuItems(m);
3778 #else
3779         n = CountMItems(m);
3780 #endif
3781
3782         /* Reset menu */
3783         for (i = 1; i <= n; i++)
3784         {
3785                 /* Reset */
3786 #if TARGET_API_MAC_CARBON
3787                 DisableMenuItem(m, i);
3788                 CheckMenuItem(m, i, FALSE);
3789 #else
3790                 DisableItem(m, i);
3791                 CheckItem(m, i, FALSE);
3792 #endif
3793         }
3794
3795         /* Enable "new"/"open..."/"import..." */
3796         if (initialized && !game_in_progress)
3797         {
3798 #if TARGET_API_MAC_CARBON
3799                 EnableMenuItem(m, 1);
3800                 EnableMenuItem(m, 2);
3801                 EnableMenuItem(m, 3);
3802 #else
3803                 EnableItem(m, 1);
3804                 EnableItem(m, 2);
3805                 EnableItem(m, 3);
3806 #endif
3807         }
3808
3809         /* Enable "close" */
3810         if (initialized)
3811         {
3812 #if TARGET_API_MAC_CARBON
3813                 EnableMenuItem(m, 4);
3814 #else
3815                 EnableItem(m, 4);
3816 #endif
3817         }
3818
3819         /* Enable "save" */
3820         if (initialized && character_generated)
3821         {
3822 #if TARGET_API_MAC_CARBON
3823                 EnableMenuItem(m, 5);
3824 #else
3825                 EnableItem(m, 5);
3826 #endif
3827         }
3828
3829         /* Enable "quit" */
3830         if (TRUE)
3831         {
3832 #if TARGET_API_MAC_CARBON
3833                 EnableMenuItem(m, 7);
3834 #else
3835                 EnableItem(m, 7);
3836 #endif
3837         }
3838
3839
3840         /* Edit menu */
3841         m = GetMenuHandle(130);
3842
3843         /* Get menu size */
3844 #if TARGET_API_MAC_CARBON
3845         n = CountMenuItems(m);
3846 #else
3847         n = CountMItems(m);
3848 #endif
3849
3850         /* Reset menu */
3851         for (i = 1; i <= n; i++)
3852         {
3853                 /* Reset */
3854 #if TARGET_API_MAC_CARBON
3855                 DisableMenuItem(m, i);
3856                 CheckMenuItem(m, i, FALSE);
3857 #else
3858                 DisableItem(m, i);
3859                 CheckItem(m, i, FALSE);
3860 #endif
3861         }
3862
3863         /* Enable "edit" options if "needed" */
3864         if (!td)
3865         {
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);
3872 #else
3873                 EnableItem(m, 1);
3874                 EnableItem(m, 3);
3875                 EnableItem(m, 4);
3876                 EnableItem(m, 5);
3877                 EnableItem(m, 6);
3878 #endif
3879         }
3880
3881
3882         /* Font menu */
3883         m = GetMenuHandle(131);
3884
3885         /* Get menu size */
3886 #if TARGET_API_MAC_CARBON
3887         n = CountMenuItems(m);
3888 #else
3889         n = CountMItems(m);
3890 #endif
3891
3892         /* Reset menu */
3893         for (i = 1; i <= n; i++)
3894         {
3895                 /* Reset */
3896 #if TARGET_API_MAC_CARBON
3897                 DisableMenuItem(m, i);
3898                 CheckMenuItem(m, i, FALSE);
3899 #else
3900                 DisableItem(m, i);
3901                 CheckItem(m, i, FALSE);
3902 #endif
3903         }
3904
3905         /* Hack -- look cute XXX XXX */
3906         /* SetItemStyle(m, 1, bold); */
3907
3908         /* Hack -- look cute XXX XXX */
3909         /* SetItemStyle(m, 2, extend); */
3910
3911         /* Active window */
3912         if (td)
3913         {
3914 #if TARGET_API_MAC_CARBON
3915                 /* Enable "bold" */
3916                 EnableMenuItem(m, 1);
3917
3918                 /* Enable "extend" */
3919                 EnableMenuItem(m, 2);
3920
3921                 /* Check the appropriate "bold-ness" */
3922                 if (td->font_face & bold) CheckMenuItem(m, 1, TRUE);
3923
3924                 /* Check the appropriate "wide-ness" */
3925                 if (td->font_face & extend) CheckMenuItem(m, 2, TRUE);
3926
3927                 /* Analyze fonts */
3928                 for (i = 4; i <= n; i++)
3929                 {
3930                         /* Enable it */
3931                         EnableMenuItem(m, i);
3932
3933                         /* Analyze font */
3934                         GetMenuItemText(m, i, s);
3935                         GetFNum(s, &value);
3936
3937                         /* Check active font */
3938                         if (td->font_id == value) CheckMenuItem(m, i, TRUE);
3939                 }
3940 #else
3941                 /* Enable "bold" */
3942                 EnableItem(m, 1);
3943
3944                 /* Enable "extend" */
3945                 EnableItem(m, 2);
3946
3947                 /* Check the appropriate "bold-ness" */
3948                 if (td->font_face & bold) CheckItem(m, 1, TRUE);
3949
3950                 /* Check the appropriate "wide-ness" */
3951                 if (td->font_face & extend) CheckItem(m, 2, TRUE);
3952
3953                 /* Analyze fonts */
3954                 for (i = 4; i <= n; i++)
3955                 {
3956                         /* Enable it */
3957                         EnableItem(m, i);
3958
3959                         /* Analyze font */
3960                         GetMenuItemText(m, i, s);
3961                         GetFNum(s, &value);
3962
3963                         /* Check active font */
3964                         if (td->font_id == value) CheckItem(m, i, TRUE);
3965                 }
3966 #endif
3967         }
3968
3969
3970         /* Size menu */
3971         m = GetMenuHandle(132);
3972
3973         /* Get menu size */
3974 #if TARGET_API_MAC_CARBON
3975         n = CountMenuItems(m);
3976 #else
3977         n = CountMItems(m);
3978 #endif
3979
3980         /* Reset menu */
3981         for (i = 1; i <= n; i++)
3982         {
3983                 /* Reset */
3984 #if TARGET_API_MAC_CARBON
3985                 DisableMenuItem(m, i);
3986                 CheckMenuItem(m, i, FALSE);
3987 #else
3988                 DisableItem(m, i);
3989                 CheckItem(m, i, FALSE);
3990 #endif
3991         }
3992         
3993         /* Active window */
3994         if (td)
3995         {
3996                 /* Analyze sizes */
3997                 for (i = 1; i <= n; i++)
3998                 {
3999 #if TARGET_API_MAC_CARBON
4000                         /* Analyze size */
4001                         GetMenuItemText(m, i, s);
4002                         s[s[0]+1] = '\0';
4003                         value = atoi((char*)(s+1));
4004
4005                         /* Enable the "real" sizes */
4006                         if (RealFont(td->font_id, value)) EnableMenuItem(m, i);
4007
4008                         /* Check the current size */
4009                         if (td->font_size == value) CheckMenuItem(m, i, TRUE);
4010 #else
4011                         /* Analyze size */
4012                         GetMenuItemText(m, i, s);
4013                         s[s[0]+1] = '\0';
4014                         value = atoi((char*)(s+1));
4015
4016                         /* Enable the "real" sizes */
4017                         if (RealFont(td->font_id, value)) EnableItem(m, i);
4018
4019                         /* Check the current size */
4020                         if (td->font_size == value) CheckItem(m, i, TRUE);
4021 #endif
4022                 }
4023         }
4024
4025
4026         /* Windows menu */
4027         m = GetMenuHandle(133);
4028
4029         /* Get menu size */
4030 #if TARGET_API_MAC_CARBON
4031         n = CountMenuItems(m);
4032 #else
4033         n = CountMItems(m);
4034 #endif
4035
4036         /* Check active windows */
4037         for (i = 1; i <= n; i++)
4038         {
4039                 /* Check if needed */
4040 #if TARGET_API_MAC_CARBON
4041                 CheckMenuItem(m, i, data[i-1].mapped);
4042 #else
4043                 CheckItem(m, i, data[i-1].mapped);
4044 #endif
4045         }
4046
4047
4048         /* Special menu */
4049         m = GetMenuHandle(134);
4050
4051         /* Get menu size */
4052 #if TARGET_API_MAC_CARBON
4053         n = CountMenuItems(m);
4054 #else
4055         n = CountMItems(m);
4056 #endif
4057
4058         /* Reset menu */
4059         for (i = 1; i <= n; i++)
4060         {
4061                 /* Reset */
4062 #if TARGET_API_MAC_CARBON
4063                 DisableMenuItem(m, i);
4064                 CheckMenuItem(m, i, FALSE);
4065 #else
4066                 DisableItem(m, i);
4067                 CheckItem(m, i, FALSE);
4068 #endif
4069         }
4070
4071 #if TARGET_API_MAC_CARBON
4072         /* Item "arg_sound" */
4073         EnableMenuItem(m, 1);
4074         CheckMenuItem(m, 1, arg_sound);
4075
4076         /* Item "arg_graphics" */
4077         EnableMenuItem(m, 2);
4078         CheckMenuItem(m, 2, arg_graphics);
4079
4080         /* Item "arg_fiddle" */
4081         EnableMenuItem(m, 4);
4082         CheckMenuItem(m, 4, arg_fiddle);
4083
4084         /* Item "arg_wizard" */
4085         EnableMenuItem(m, 5);
4086         CheckMenuItem(m, 5, arg_wizard);
4087
4088         /* Item "SoundSetting" */
4089         EnableMenuItem(m, 7);
4090
4091         /* Item NewStyle Graphics */
4092         EnableMenuItem(m, 8);
4093         CheckMenuItem(m, 8, use_newstyle_graphics);
4094
4095         /* Item Bigtile Mode */
4096         EnableMenuItem(m, 9);
4097         CheckMenuItem(m, 9, arg_bigtile);
4098 #else
4099         /* Item "arg_sound" */
4100         EnableItem(m, 1);
4101         CheckItem(m, 1, arg_sound);
4102
4103         /* Item "arg_graphics" */
4104         EnableItem(m, 2);
4105         CheckItem(m, 2, arg_graphics);
4106
4107         /* Item "arg_fiddle" */
4108         EnableItem(m, 4);
4109         CheckItem(m, 4, arg_fiddle);
4110
4111         /* Item "arg_wizard" */
4112         EnableItem(m, 5);
4113         CheckItem(m, 5, arg_wizard);
4114
4115         /* Item "SoundSetting" */
4116         EnableItem(m, 7);
4117
4118         /* Item NewStyle Graphics */
4119         EnableItem(m, 8);
4120         CheckItem(m, 8, use_newstyle_graphics);
4121
4122         /* Item Bigtile Mode */
4123         EnableItem(m, 9);
4124         CheckItem(m, 9, arg_bigtile);
4125 #endif
4126
4127         /* TileWidth menu */
4128         m = GetMenuHandle(135);
4129
4130         /* Get menu size */
4131 #if TARGET_API_MAC_CARBON
4132         n = CountMenuItems(m);
4133 #else
4134         n = CountMItems(m);
4135 #endif
4136
4137         /* Reset menu */
4138         for (i = 1; i <= n; i++)
4139         {
4140                 /* Reset */
4141 #if TARGET_API_MAC_CARBON
4142                 DisableMenuItem(m, i);
4143                 CheckMenuItem(m, i, FALSE);
4144 #else
4145                 DisableItem(m, i);
4146                 CheckItem(m, i, FALSE);
4147 #endif
4148         }
4149
4150         /* Active window */
4151         if (td)
4152         {
4153                 /* Analyze sizes */
4154                 for (i = 1; i <= n; i++)
4155                 {
4156                         /* Analyze size */
4157                         /* GetMenuItemText(m,i,s); */
4158                         GetMenuItemText(m, i, s);
4159                         s[s[0]+1] = '\0';
4160                         value = atoi((char*)(s+1));
4161
4162 #if TARGET_API_MAC_CARBON
4163                         /* Enable */
4164                         EnableMenuItem(m, i);
4165
4166                         /* Check the current size */
4167                         if (td->tile_wid == value) CheckMenuItem(m, i, TRUE);
4168 #else
4169                         /* Enable */
4170                         EnableItem(m, i);
4171
4172                         /* Check the current size */
4173                         if (td->tile_wid == value) CheckItem(m, i, TRUE);
4174 #endif
4175                 }
4176         }
4177
4178
4179         /* TileHeight menu */
4180         m = GetMenuHandle(136);
4181
4182         /* Get menu size */
4183 #if TARGET_API_MAC_CARBON
4184         n = CountMenuItems(m);
4185 #else
4186         n = CountMItems(m);
4187 #endif
4188
4189         /* Reset menu */
4190         for (i = 1; i <= n; i++)
4191         {
4192                 /* Reset */
4193 #if TARGET_API_MAC_CARBON
4194                 DisableMenuItem(m, i);
4195                 CheckMenuItem(m, i, FALSE);
4196 #else
4197                 DisableItem(m, i);
4198                 CheckItem(m, i, FALSE);
4199 #endif
4200         }
4201
4202         /* Active window */
4203         if (td)
4204         {
4205                 /* Analyze sizes */
4206                 for (i = 1; i <= n; i++)
4207                 {
4208                         /* Analyze size */
4209                         GetMenuItemText(m, i, s);
4210                         s[s[0]+1] = '\0';
4211                         value = atoi((char*)(s+1));
4212
4213 #if TARGET_API_MAC_CARBON
4214                         /* Enable */
4215                         EnableMenuItem(m, i);
4216
4217                         /* Check the current size */
4218                         if (td->tile_hgt == value) CheckMenuItem(m, i, TRUE);
4219 #else
4220                         /* Enable */
4221                         EnableItem(m, i);
4222
4223                         /* Check the current size */
4224                         if (td->tile_hgt == value) CheckItem(m, i, TRUE);
4225 #endif
4226                 }
4227         }
4228 }
4229
4230
4231 /*
4232  * Process a menu selection (see above)
4233  *
4234  * Hack -- assume that invalid menu selections are disabled above,
4235  * which I have been informed may not be reliable.  XXX XXX XXX
4236  */
4237 static void menu(long mc)
4238 {
4239         int i;
4240
4241         int menuid, selection;
4242
4243         static unsigned char s[1000];
4244
4245         short fid;
4246
4247         term_data *td = NULL;
4248
4249         WindowPtr old_win;
4250
4251
4252         /* Analyze the menu command */
4253         menuid = HiWord(mc);
4254         selection = LoWord(mc);
4255
4256
4257         /* Find the window */
4258         for (i = 0; i < MAX_TERM_DATA; i++)
4259         {
4260                 /* Skip dead windows */
4261                 if (!data[i].t) continue;
4262
4263                 /* Notice matches */
4264                 if (data[i].w == FrontWindow()) td = &data[i];
4265         }
4266
4267
4268         /* Branch on the menu */
4269         switch (menuid)
4270         {
4271                 /* Apple Menu */
4272                 case 128:
4273                 {
4274                         /* About Angband... */
4275 #if TARGET_API_MAC_CARBON
4276                         if (selection == 1)
4277                         {
4278                                 DialogPtr dialog;
4279                                 short item_hit;
4280
4281                                 /* Get the about dialogue */
4282                                 dialog=GetNewDialog(128, 0, (WindowPtr)-1);
4283
4284                                 /* Move it to the middle of the screen */
4285                                 RepositionWindow(
4286                                         GetDialogWindow(dialog),
4287                                         NULL,
4288                                         kWindowCenterOnMainScreen);
4289
4290                                 /* Show the dialog */
4291                                 TransitionWindow(GetDialogWindow(dialog),
4292                                         kWindowZoomTransitionEffect,
4293                                         kWindowShowTransitionAction,
4294                                         NULL);
4295
4296                                 /* Wait for user to click on it */
4297                                 ModalDialog(0, &item_hit);
4298
4299                                 /* Free the dialogue */
4300                                 DisposeDialog(dialog);
4301                                 break;
4302                         }
4303 #else
4304                         if (selection == 1)
4305                         {
4306                                 DialogPtr dialog;
4307                                 Rect r;
4308                                 short item_hit;
4309
4310                                 dialog=GetNewDialog(128, 0, (WindowPtr)-1);
4311
4312                                 r=dialog->portRect;
4313                                 center_rect(&r, &qd.screenBits.bounds);
4314                                 MoveWindow(dialog, r.left, r.top, 1);
4315                                 ShowWindow(dialog);
4316                                 ModalDialog(0, &item_hit);
4317                                 DisposeDialog(dialog);
4318                                 break;
4319                         }
4320
4321                         /* Desk accessory */
4322                         /* GetMenuItemText(GetMHandle(128),selection,s); */
4323                         GetMenuItemText(GetMenuHandle(128), selection, s);
4324                         OpenDeskAcc(s);
4325                         break;
4326 #endif
4327                 }
4328
4329                 /* File Menu */
4330                 case 129:
4331                 {
4332                         switch (selection)
4333                         {
4334                                 /* New */
4335                                 case 1:
4336                                 {
4337                                         do_menu_file_new();
4338                                         break;
4339                                 }
4340
4341                                 /* Open... */
4342                                 case 2:
4343                                 {
4344                                         do_menu_file_open(FALSE);
4345                                         break;
4346                                 }
4347
4348                                 /* Import... */
4349                                 case 3:
4350                                 {
4351                                         do_menu_file_open(TRUE);
4352                                         break;
4353                                 }
4354
4355                                 /* Close */
4356                                 case 4:
4357                                 {
4358                                         /* No window */
4359                                         if (!td) break;
4360
4361                                         /* Not Mapped */
4362                                         td->mapped = FALSE;
4363
4364                                         /* Not Mapped */
4365                                         td->t->mapped_flag = FALSE;
4366
4367                                         /* Hide the window */
4368                                         HideWindow(td->w);
4369
4370                                         break;
4371                                 }
4372
4373                                 /* Save */
4374                                 case 5:
4375                                 {
4376                                         if (!can_save){
4377 #ifdef JP
4378                                                 plog("º£¤Ï¥»¡¼¥Ö¤¹¤ë¤³¤È¤Ï½ÐÍè¤Þ¤»¤ó¡£");
4379 #else
4380                                                 plog("You may not do that right now.");
4381 #endif
4382                                                 break;
4383                                         }
4384                                         
4385                                         /* Hack -- Forget messages */
4386                                         msg_flag = FALSE;
4387
4388                                         /* Hack -- Save the game */
4389                                         do_cmd_save_game(FALSE);
4390
4391                                         break;
4392                                 }
4393
4394                                 /* Quit (with save) */
4395                                 case 7:
4396                                 {
4397                                         /* Save the game (if necessary) */
4398                                         if (game_in_progress && character_generated)
4399                                         {
4400                                                 if (!can_save){
4401 #ifdef JP
4402                                                         plog("º£¤Ï¥»¡¼¥Ö¤¹¤ë¤³¤È¤Ï½ÐÍè¤Þ¤»¤ó¡£");
4403 #else
4404                                                         plog("You may not do that right now.");
4405 #endif
4406                                                         break;
4407                                                 }
4408                                                 /* Hack -- Forget messages */
4409                                                 msg_flag = FALSE;
4410
4411                                                 /* Save the game */
4412 #if 0
4413                                                 do_cmd_save_game(FALSE);
4414 #endif
4415                                                 Term_key_push(SPECIAL_KEY_QUIT);
4416                                                 break;
4417                                         }
4418
4419                                         /* Quit */
4420                                         quit(NULL);
4421                                         break;
4422                                 }
4423                         }
4424                         break;
4425                 }
4426
4427                 /* Edit menu */
4428                 case 130:
4429                 {
4430                         /* Unused */
4431                         break;
4432                 }
4433
4434                 /* Font menu */
4435                 case 131:
4436                 {
4437                         /* Require a window */
4438                         if (!td) break;
4439
4440                         /* Memorize old */
4441                         old_win = active;
4442
4443                         /* Activate */
4444                         activate(td->w);
4445
4446                         /* Toggle the "bold" setting */
4447                         if (selection == 1)
4448                         {
4449                                 /* Toggle the setting */
4450                                 if (td->font_face & bold)
4451                                 {
4452                                         td->font_face &= ~bold;
4453                                 }
4454                                 else
4455                                 {
4456                                         td->font_face |= bold;
4457                                 }
4458
4459                                 /* Tile Width Hight Init */
4460                                 td->tile_wid = td->tile_hgt = 0;
4461
4462                                 /* Apply and Verify */
4463                                 term_data_check_font(td);
4464                                 term_data_check_size(td);
4465
4466                                 /* Resize and Redraw */
4467                                 term_data_resize(td);
4468                                 term_data_redraw(td);
4469
4470                                 break;
4471                         }
4472
4473                         /* Toggle the "wide" setting */
4474                         if (selection == 2)
4475                         {
4476                                 /* Toggle the setting */
4477                                 if (td->font_face & extend)
4478                                 {
4479                                         td->font_face &= ~extend;
4480                                 }
4481                                 else
4482                                 {
4483                                         td->font_face |= extend;
4484                                 }
4485
4486                                 /* Tile Width Hight Init */
4487                                 td->tile_wid = td->tile_hgt = 0;
4488
4489                                 /* Apply and Verify */
4490                                 term_data_check_font(td);
4491                                 term_data_check_size(td);
4492
4493                                 /* Resize and Redraw */
4494                                 term_data_resize(td);
4495                                 term_data_redraw(td);
4496
4497                                 break;
4498                         }
4499
4500                         /* Get a new font name */
4501                         GetMenuItemText(GetMenuHandle(131), selection, s);
4502                         GetFNum(s, &fid);
4503
4504                         /* Save the new font id */
4505                         td->font_id = fid;
4506
4507                         /* Current size is bad for new font */
4508                         if (!RealFont(td->font_id, td->font_size))
4509                         {
4510                                 /* Find similar size */
4511                                 for (i = 1; i <= 32; i++)
4512                                 {
4513                                         /* Adjust smaller */
4514                                         if (td->font_size - i >= 8)
4515                                         {
4516                                                 if (RealFont(td->font_id, td->font_size - i))
4517                                                 {
4518                                                         td->font_size -= i;
4519                                                         break;
4520                                                 }
4521                                         }
4522
4523                                         /* Adjust larger */
4524                                         if (td->font_size + i <= 128)
4525                                         {
4526                                                 if (RealFont(td->font_id, td->font_size + i))
4527                                                 {
4528                                                         td->font_size += i;
4529                                                         break;
4530                                                 }
4531                                         }
4532                                 }
4533                         }
4534
4535                         /* Tile Width Hight Init */
4536                         td->tile_wid = td->tile_hgt = 0;
4537
4538                         /* Apply and Verify */
4539                         term_data_check_font(td);
4540                         term_data_check_size(td);
4541
4542                         /* Resize and Redraw */
4543                         term_data_resize(td);
4544                         term_data_redraw(td);
4545
4546                         /* Restore the window */
4547                         activate(old_win);
4548
4549                         break;
4550                 }
4551
4552                 /* Size menu */
4553                 case 132:
4554                 {
4555                         if (!td) break;
4556
4557                         /* Save old */
4558                         old_win = active;
4559
4560                         /* Activate */
4561                         activate(td->w);
4562
4563                         GetMenuItemText(GetMenuHandle(132), selection, s);
4564                         s[s[0]+1]=0;
4565                         td->font_size = atoi((char*)(s+1));
4566
4567                         /* Tile Width Hight Init */
4568                         td->tile_wid = td->tile_hgt = 0;
4569
4570                         /* Apply and Verify */
4571                         term_data_check_font(td);
4572                         term_data_check_size(td);
4573
4574                         /* Resize and Redraw */
4575                         term_data_resize(td);
4576                         term_data_redraw(td);
4577
4578                         /* Restore */
4579                         activate(old_win);
4580
4581                         break;
4582                 }
4583
4584                 /* Window menu */
4585                 case 133:
4586                 {
4587                         /* Parse */
4588                         i = selection - 1;
4589
4590                         /* Check legality of choice */
4591                         if ((i < 0) || (i >= MAX_TERM_DATA)) break;
4592
4593                         /* Obtain the window */
4594                         td = &data[i];
4595
4596                         /* Mapped */
4597                         td->mapped = TRUE;
4598
4599                         /* Link */      
4600                         term_data_link(i);
4601
4602                         /* Mapped (?) */
4603                         td->t->mapped_flag = TRUE;
4604
4605                         /* Show the window */
4606                         ShowWindow(td->w);
4607
4608                         /* Bring to the front */
4609                         SelectWindow(td->w);
4610
4611                         break;
4612                 }
4613
4614                 /* Special menu */
4615                 case 134:
4616                 {
4617                         switch (selection)
4618                         {
4619                                 case 1:
4620                                 {
4621                                         /* Toggle arg_sound */
4622                                         arg_sound = !arg_sound;
4623
4624                                         /* React to changes */
4625                                         Term_xtra(TERM_XTRA_REACT, 0);
4626
4627                                         break;
4628                                 }
4629
4630                                 case 2:
4631                                 {
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;
4638                                                 pictID = 1001;
4639                                         }
4640
4641                                         /* Hack -- Force redraw */
4642                                         Term_key_push(KTRL('R'));
4643
4644                                         break;
4645                                 }
4646
4647                                 case 4:
4648                                 {
4649                                         arg_fiddle = !arg_fiddle;
4650                                         break;
4651                                 }
4652
4653                                 case 5:
4654                                 {
4655                                         arg_wizard = !arg_wizard;
4656                                         break;
4657                                 }
4658
4659                                 case 7:
4660                                 {
4661                                         SoundConfigDLog();
4662                                         break;
4663                                 }
4664                                 case 8:
4665                                 {
4666                                         if (streq(ANGBAND_GRAF, "old"))
4667                                         {
4668                                                 ANGBAND_GRAF = "new";
4669                                                 arg_newstyle_graphics = true;
4670                                                 grafWidth = grafHeight = 16;
4671                                                 pictID = 1002;
4672                                         }
4673                                         else
4674                                         {
4675                                                 ANGBAND_GRAF = "old";
4676                                                 arg_newstyle_graphics = false;
4677                                                 grafWidth = grafHeight = 8;
4678                                                 pictID = 1001;
4679                                         }
4680
4681                                         /* Hack -- Force redraw */
4682                                         Term_key_push(KTRL('R'));
4683                                         break;
4684                                 }
4685
4686                                 case 9: /* bigtile mode */
4687                                 {
4688                                         term_data *td = &data[0];
4689
4690                                         if (!can_save){
4691 #ifdef JP
4692                                                 plog("º£¤ÏÊѹ¹½ÐÍè¤Þ¤»¤ó¡£");
4693 #else
4694                                                 plog("You may not do that right now.");
4695 #endif
4696                                                 break;
4697                                         }
4698
4699                                         /* Toggle "arg_bigtile" */
4700                                         arg_bigtile = !arg_bigtile;
4701
4702                                         /* Activate */
4703                                         Term_activate(td->t);
4704
4705                                         /* Resize the term */
4706                                         Term_resize(td->cols, td->rows);
4707
4708                                         break;
4709                                 }
4710
4711                         }
4712
4713                         break;
4714                 }
4715
4716                 /* TileWidth menu */
4717                 case 135:
4718                 {
4719                         if (!td) break;
4720
4721                         /* Save old */
4722                         old_win = active;
4723
4724                         /* Activate */
4725                         activate(td->w);
4726
4727                         GetMenuItemText(GetMenuHandle(135), selection, s);
4728                         s[s[0]+1]=0;
4729                         td->tile_wid = atoi((char*)(s+1));
4730
4731                         /* Apply and Verify */
4732                         term_data_check_size(td);
4733
4734                         /* Resize and Redraw */
4735                         term_data_resize(td);
4736                         term_data_redraw(td);
4737
4738                         /* Restore */
4739                         activate(old_win);
4740
4741                         break;
4742                 }
4743
4744                 /* TileHeight menu */
4745                 case 136:
4746                 {
4747                         if (!td) break;
4748
4749                         /* Save old */
4750                         old_win = active;
4751
4752                         /* Activate */
4753                         activate(td->w);
4754
4755                         GetMenuItemText(GetMenuHandle(136), selection, s);
4756                         s[s[0]+1]=0;
4757                         td->tile_hgt = atoi((char*)(s+1));
4758
4759                         /* Apply and Verify */
4760                         term_data_check_size(td);
4761
4762                         /* Resize and Redraw */
4763                         term_data_resize(td);
4764                         term_data_redraw(td);
4765
4766                         /* Restore */
4767                         activate(old_win);
4768
4769                         break;
4770                 }
4771         }
4772
4773
4774         /* Clean the menu */
4775         HiliteMenu(0);
4776 }
4777
4778
4779 #ifdef USE_SFL_CODE
4780
4781
4782 /*
4783  * Check for extra required parameters -- From "Maarten Hazewinkel"
4784  */
4785 static OSErr CheckRequiredAEParams(const AppleEvent *theAppleEvent)
4786 {
4787         OSErr   aeError;
4788         DescType        returnedType;
4789         Size    actualSize;
4790
4791         aeError = AEGetAttributePtr(theAppleEvent, keyMissedKeywordAttr, typeWildCard,
4792                                     &returnedType, NULL, 0, &actualSize);
4793
4794         if (aeError == errAEDescNotFound) return (noErr);
4795
4796         if (aeError == noErr) return (errAEParamMissed);
4797
4798         return (aeError);
4799 }
4800
4801
4802 /*
4803  * Apple Event Handler -- Open Application
4804  */
4805 static pascal OSErr AEH_Start(const AppleEvent *theAppleEvent,
4806                               AppleEvent *reply, long handlerRefCon)
4807 {
4808 #pragma unused(reply, handlerRefCon)
4809
4810         return (CheckRequiredAEParams(theAppleEvent));
4811 }
4812
4813
4814 /*
4815  * Apple Event Handler -- Quit Application
4816  */
4817 static pascal OSErr AEH_Quit(const AppleEvent *theAppleEvent,
4818                              AppleEvent *reply, long handlerRefCon)
4819 {
4820 #pragma unused(reply, handlerRefCon)
4821 #if TARGET_API_MAC_CARBON
4822
4823         /* Save the game (if necessary) */
4824         if (game_in_progress && character_generated)
4825         {
4826                         if (!can_save){
4827 #ifdef JP
4828                                 plog("º£¤Ï¥»¡¼¥Ö¤¹¤ë¤³¤È¤Ï½ÐÍè¤Þ¤»¤ó¡£");
4829 #else
4830                                 plog("You may not do that right now.");
4831 #endif
4832                                 return;
4833                         }
4834                         /* Hack -- Forget messages */
4835                         msg_flag = FALSE;
4836
4837                         /* Save the game */
4838 #if 0
4839                         do_cmd_save_game(FALSE);
4840 #endif
4841                         Term_key_push(SPECIAL_KEY_QUIT);
4842                         return;
4843                 }
4844
4845                 /* Quit */
4846                 quit(NULL);
4847 #else
4848         /* Quit later */
4849         quit_when_ready = TRUE;
4850
4851         /* Check arguments */
4852         return (CheckRequiredAEParams(theAppleEvent));
4853 #endif
4854 }
4855
4856
4857 /*
4858  * Apple Event Handler -- Print Documents
4859  */
4860 static pascal OSErr AEH_Print(const AppleEvent *theAppleEvent,
4861                               AppleEvent *reply, long handlerRefCon)
4862 {
4863 #pragma unused(theAppleEvent, reply, handlerRefCon)
4864
4865         return (errAEEventNotHandled);
4866 }
4867
4868
4869 /*
4870  * Apple Event Handler by Steve Linberg (slinberg@crocker.com).
4871  *
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.
4877  *
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")
4882  */
4883 static pascal OSErr AEH_Open(const AppleEvent *theAppleEvent,
4884                              AppleEvent* reply, long handlerRefCon)
4885 {
4886 #pragma unused(reply, handlerRefCon)
4887
4888         FSSpec          myFSS;
4889         AEDescList      docList;
4890         OSErr           err;
4891         Size            actualSize;
4892         AEKeyword       keywd;
4893         DescType        returnedType;
4894         char            foo[128];
4895         FInfo           myFileInfo;
4896
4897         /* Put the direct parameter (a descriptor list) into a docList */
4898         err = AEGetParamDesc(theAppleEvent, keyDirectObject, typeAEList, &docList);
4899         if (err) return err;
4900
4901         /*
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.
4904          */
4905
4906         err = AEGetNthPtr(&docList, 1L, typeFSS, &keywd,
4907                           &returnedType, (Ptr) &myFSS, sizeof(myFSS), &actualSize);
4908         if (err) return err;
4909
4910         /* Only needed to check savefile type below */
4911         err = FSpGetFInfo(&myFSS, &myFileInfo);
4912         if (err)
4913         {
4914                 sprintf(foo, "Arg!  FSpGetFInfo failed with code %d", err);
4915                 mac_warning (foo);
4916                 return err;
4917         }
4918
4919         /* Ignore non 'SAVE' files */
4920         if (myFileInfo.fdType != 'SAVE') return noErr;
4921
4922         /* XXX XXX XXX Extract a file name */
4923         PathNameFromDirID(myFSS.parID, myFSS.vRefNum, (StringPtr)savefile);
4924         pstrcat((StringPtr)savefile, (StringPtr)&myFSS.name);
4925
4926         /* Convert the string */
4927         ptocstr((StringPtr)savefile);
4928
4929         /* Delay actual open */
4930         open_when_ready = TRUE;
4931
4932         /* Dispose */
4933         err = AEDisposeDesc(&docList);
4934
4935         /* Success */
4936         return noErr;
4937 }
4938
4939
4940 #endif
4941
4942
4943
4944 /*
4945  * Macintosh modifiers (event.modifier & ccc):
4946  *   cmdKey, optionKey, shiftKey, alphaLock, controlKey
4947  *
4948  *
4949  * Macintosh Keycodes (0-63 normal, 64-95 keypad, 96-127 extra):
4950  *
4951  * Return:36
4952  * Delete:51
4953  *
4954  * Period:65
4955  * Star:67
4956  * Plus:69
4957  * Clear:71
4958  * Slash:75
4959  * Enter:76
4960  * Minus:78
4961  * Equal:81
4962  * 0-7:82-89
4963  * 8-9:91-92
4964  *
4965  * F5: 96
4966  * F6: 97
4967  * F7: 98
4968  * F3:99
4969  * F8:100
4970  * F10:109
4971  * F11:103
4972  * F13:105
4973  * F14:107
4974  * F9:101
4975  * F12:111
4976  * F15:113
4977  * Help:114
4978  * Home:115
4979  * PgUp:116
4980  * Del:117
4981  * F4: 118
4982  * End:119
4983  * F2:120
4984  * PgDn:121
4985  * F1:122
4986  * Lt:123
4987  * Rt:124
4988  * Dn:125
4989  * Up:126
4990  */
4991
4992
4993 /*
4994  * Optimize non-blocking calls to "CheckEvents()"
4995  * Idea from "Maarten Hazewinkel <mmhazewi@cs.ruu.nl>"
4996  */
4997 #define EVENT_TICKS 6
4998
4999
5000 /*
5001  * Check for Events, return TRUE if we process any
5002  *
5003  * Hack -- Handle AppleEvents if appropriate (ignore result code).
5004  */
5005 static bool CheckEvents(bool wait)
5006 {
5007         EventRecord event;
5008
5009         WindowPtr w;
5010
5011         Rect r;
5012
5013         long newsize;
5014
5015         int ch, ck;
5016
5017         int mc, ms, mo, mx;
5018
5019         int i;
5020
5021         term_data *td = NULL;
5022
5023         huge curTicks;
5024
5025         static huge lastTicks = 0L;
5026
5027
5028         /* Access the clock */
5029         curTicks = TickCount();
5030
5031         /* Hack -- Allow efficient checking for non-pending events */
5032         if (!wait && (curTicks < lastTicks + EVENT_TICKS)) return (FALSE);
5033
5034         /* Timestamp last check */
5035         lastTicks = curTicks;
5036
5037 #if TARGET_API_MAC_CARBON
5038         WaitNextEvent( everyEvent, &event, 1L, nil );
5039 #else
5040         /* Let the "system" run */
5041         SystemTask();
5042
5043         /* Get an event (or null) */
5044         GetNextEvent(everyEvent, &event);
5045 #endif
5046
5047         /* Hack -- Nothing is ready yet */
5048         if (event.what == nullEvent) return (FALSE);
5049
5050         /* Analyze the event */
5051         switch (event.what)
5052         {
5053
5054 #if 0
5055
5056                 case activateEvt:
5057                 {
5058                         w = (WindowPtr)event.message;
5059
5060                         activate(w);
5061
5062                         break;
5063                 }
5064
5065 #endif
5066
5067                 case updateEvt:
5068                 {
5069                         /* Extract the window */
5070                         w = (WindowPtr)event.message;
5071
5072                         /* Find the window */
5073                         for (i = 0; i < MAX_TERM_DATA; i++)
5074                         {
5075                                 /* Skip dead windows */
5076                                 if (!data[i].t) continue;
5077
5078                                 /* Notice matches */
5079                                 if (data[i].w == w) td = &data[i];
5080                         }
5081
5082                         /* Hack XXX XXX XXX */
5083                         BeginUpdate(w);
5084                         EndUpdate(w);
5085
5086                         /* Redraw the window */
5087                         if (td) term_data_redraw(td);
5088
5089                         break;
5090                 }
5091
5092                 case keyDown:
5093                 case autoKey:
5094                 {
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;
5100
5101                         /* Keypress: (only "valid" if ck < 96) */
5102                         ch = (event.message & charCodeMask) & 255;
5103
5104                         /* Keycode: see table above */
5105                         ck = ((event.message & keyCodeMask) >> 8) & 255;
5106
5107                         /* Command + "normal key" -> menu action */
5108                         if (mx && (ck < 64))
5109                         {
5110                                 /* Hack -- Prepare the menus */
5111                                 setup_menus();
5112
5113                                 /* Run the Menu-Handler */
5114                                 menu(MenuKey(ch));
5115
5116                                 /* Turn off the menus */
5117                                 HiliteMenu(0);
5118
5119                                 /* Done */
5120                                 break;
5121                         }
5122
5123
5124                         /* Hide the mouse pointer */
5125                         ObscureCursor();
5126
5127                         /* Normal key -> simple keypress */
5128                         if (ck < 64)
5129                         {
5130                                 /* Enqueue the keypress */
5131                                 Term_keypress(ch);
5132                         }
5133
5134                         /* Bizarre key -> encoded keypress */
5135                         else if (ck <= 127)
5136                         {
5137                                 /* Hack -- introduce with control-underscore */
5138                                 Term_keypress(31);
5139
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');
5145
5146                                 /* Hack -- Downshift and encode the keycode */
5147                                 Term_keypress('0' + (ck - 64) / 10);
5148                                 Term_keypress('0' + (ck - 64) % 10);
5149
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');
5154                         }
5155
5156                         break;
5157                 }
5158
5159                 case mouseDown:
5160                 {
5161                         int code;
5162
5163                         /* Analyze click location */
5164                         code = FindWindow(event.where, &w);
5165
5166                         /* Find the window */
5167                         for (i = 0; i < MAX_TERM_DATA; i++)
5168                         {
5169                                 /* Skip dead windows */
5170                                 if (!data[i].t) continue;
5171
5172                                 /* Notice matches */
5173                                 if (data[i].w == w) td = &data[i];
5174                         }
5175
5176                         /* Analyze */
5177                         switch (code)
5178                         {
5179                                 case inMenuBar:
5180                                 {
5181                                         setup_menus();
5182                                         menu(MenuSelect(event.where));
5183                                         HiliteMenu(0);
5184                                         break;
5185                                 }
5186 #if !TARGET_API_MAC_CARBON
5187                                 case inSysWindow:
5188                                 {
5189                                         SystemClick(&event, w);
5190                                         break;
5191                                 }
5192 #endif
5193
5194                                 case inDrag:
5195                                 {
5196                                         Point p;
5197
5198                                         WindowPtr old_win;
5199                                         BitMap screen;
5200                                         Rect portRect;
5201 #if TARGET_API_MAC_CARBON                                               
5202                                         GetQDGlobalsScreenBits( &screen );
5203 #else
5204                                         screen = qd.screenBits;
5205 #endif  
5206                                         r = screen.bounds;
5207                                         r.top += 20; /* GetMBarHeight() XXX XXX XXX */
5208                                         InsetRect(&r, 4, 4);
5209                                         DragWindow(w, event.where, &r);
5210
5211                                         /* Oops */
5212                                         if (!td) break;
5213
5214                                         /* Save */
5215                                         old_win = active;
5216
5217                                         /* Activate */
5218                                         activate(td->w);
5219
5220                                         /* Analyze */
5221 #if TARGET_API_MAC_CARBON
5222                                         GetWindowBounds( (WindowRef)td->w, kWindowContentRgn, &portRect );
5223 #else
5224                                         portRect = td->w->portRect;
5225                                         local_to_global( &portRect );
5226 #endif
5227                                         p.h = portRect.left;
5228                                         p.v = portRect.top;
5229 #if !TARGET_API_MAC_CARBON
5230                                         LocalToGlobal(&p);
5231 #endif
5232                                         td->r.left = p.h;
5233                                         td->r.top = p.v;
5234
5235                                         /* Restore */
5236                                         activate(old_win);
5237
5238                                         /* Apply and Verify */
5239                                         term_data_check_size(td);
5240
5241                                         break;
5242                                 }
5243
5244                                 case inGoAway:
5245                                 {
5246                                         /* Oops */
5247                                         if (!td) break;
5248
5249                                         /* Track the go-away box */
5250                                         if (TrackGoAway(w, event.where))
5251                                         {
5252                                                 /* Not Mapped */
5253                                                 td->mapped = FALSE;
5254
5255                                                 /* Not Mapped */
5256                                                 td->t->mapped_flag = FALSE;
5257
5258                                                 /* Hide the window */
5259                                                 HideWindow(td->w);
5260                                         }
5261
5262                                         break;
5263                                 }
5264
5265                                 case inGrow:
5266                                 {
5267                                         s16b x, y;
5268
5269                                         term *old = Term;
5270                                         BitMap          screen;
5271         
5272 #if TARGET_API_MAC_CARBON
5273                                         GetQDGlobalsScreenBits( &screen );
5274 #else
5275                                         screen = qd.screenBits;
5276 #endif
5277                                         /* Oops */
5278                                         if (!td) break;
5279
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;
5285
5286                                         /* Grow the rectangle */
5287                                         newsize = GrowWindow(w, event.where, &r);
5288
5289                                         /* Handle abort */
5290                                         if (!newsize) break;
5291
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;
5295
5296                                         /* Extract a "close" approximation */
5297                                         td->rows = y / td->tile_hgt;
5298                                         td->cols = x / td->tile_wid;
5299
5300                                         /* Apply and Verify */
5301                                         term_data_check_size(td);
5302                                         /* Activate */
5303                                         Term_activate(td->t);
5304
5305                                         /* Hack -- Resize the term */
5306                                         Term_resize(td->cols, td->rows);
5307
5308                                         /* Resize and Redraw */
5309                                         term_data_resize(td);
5310                                         term_data_redraw(td);
5311
5312                                         /* Restore */
5313                                         Term_activate(old);
5314
5315                                         break;
5316                                 }
5317
5318                                 case inContent:
5319                                 {
5320                                         SelectWindow(w);
5321
5322                                         break;
5323                                 }
5324                         }
5325
5326                         break;
5327                 }
5328
5329                 /* Disk Event -- From "Maarten Hazewinkel" */
5330                 case diskEvt:
5331                 {
5332
5333 #if TARGET_API_MAC_CARBON
5334 #else
5335                         /* check for error when mounting the disk */
5336                         if (HiWord(event.message) != noErr)
5337                         {
5338                                 Point p =
5339                                 {120, 120};
5340
5341                                 DILoad();
5342                                 DIBadMount(p, event.message);
5343                                 DIUnload();
5344                         }
5345 #endif
5346                         break;
5347                 }
5348
5349                 /* OS Event -- From "Maarten Hazewinkel" */
5350                 case osEvt:
5351                 {
5352                         switch ((event.message >> 24) & 0x000000FF)
5353                         {
5354                                 case suspendResumeMessage:
5355
5356                                 /* Resuming: activate the front window */
5357                                 if (event.message & resumeFlag)
5358                                 {
5359 #if TARGET_API_MAC_CARBON
5360                                         Cursor  arrow;
5361                                                 
5362                                         SetPortWindowPort( FrontWindow() );
5363                                         
5364                                         GetQDGlobalsArrow( &arrow );
5365                                         SetCursor(&arrow);
5366 #else
5367                                         SetPort(FrontWindow());
5368                                         SetCursor(&qd.arrow);
5369 #endif
5370                                 }
5371
5372                                 /* Suspend: deactivate the front window */
5373                                 else
5374                                 {
5375                                         /* Nothing */
5376                                 }
5377
5378                                 break;
5379                         }
5380
5381                         break;
5382                 }
5383
5384 #ifdef USE_SFL_CODE
5385
5386                 /* From "Steve Linberg" and "Maarten Hazewinkel" */
5387                 case kHighLevelEvent:
5388                 {
5389 #if TARGET_API_MAC_CARBON
5390                         AEProcessAppleEvent(&event);
5391 #else
5392                         /* Process apple events */
5393                         if (AEProcessAppleEvent(&event) != noErr)
5394                         {
5395                                 #ifdef JP
5396                                 plog("Apple Event Handler¤Î¥¨¥é¡¼¤Ç¤¹.");
5397                                 #else
5398                                 plog("Error in Apple Event Handler!");
5399                                 #endif
5400                         }
5401
5402                         /* Handle "quit_when_ready" */
5403                         if (quit_when_ready)
5404                         {
5405                                 /* Forget */
5406                                 quit_when_ready = FALSE;
5407
5408                                 /* Do the menu key */
5409                                 menu(MenuKey('q'));
5410
5411                                 /* Turn off the menus */
5412                                 HiliteMenu(0);
5413                         }
5414
5415                         /* Handle "open_when_ready" */
5416                         handle_open_when_ready();
5417 #endif
5418
5419                         break;
5420                 }
5421
5422 #endif
5423
5424         }
5425
5426
5427         /* Something happened */
5428         return (TRUE);
5429 }
5430
5431
5432
5433
5434 /*** Some Hooks for various routines ***/
5435
5436
5437 /*
5438  * Mega-Hack -- emergency lifeboat
5439  */
5440 static vptr lifeboat = NULL;
5441
5442
5443 /*
5444  * Hook to "release" memory
5445  */
5446 static vptr hook_rnfree(vptr v, huge size)
5447 {
5448
5449 #pragma unused (size)
5450
5451 #ifdef USE_MALLOC
5452
5453         /* Alternative method */
5454         free(v);
5455
5456 #else
5457
5458         /* Dispose */
5459         DisposePtr(v);
5460
5461 #endif
5462
5463         /* Success */
5464         return (NULL);
5465 }
5466
5467 /*
5468  * Hook to "allocate" memory
5469  */
5470 static vptr hook_ralloc(huge size)
5471 {
5472
5473 #ifdef USE_MALLOC
5474
5475         /* Make a new pointer */
5476         return (malloc(size));
5477
5478 #else
5479
5480         /* Make a new pointer */
5481         return (NewPtr(size));
5482
5483 #endif
5484
5485 }
5486
5487 /*
5488  * Hook to handle "out of memory" errors
5489  */
5490 static vptr hook_rpanic(huge size)
5491 {
5492
5493 #pragma unused (size)
5494
5495         vptr mem = NULL;
5496
5497         /* Free the lifeboat */
5498         if (lifeboat)
5499         {
5500                 /* Free the lifeboat */
5501                 DisposePtr(lifeboat);
5502
5503                 /* Forget the lifeboat */
5504                 lifeboat = NULL;
5505
5506                 /* Mega-Hack -- Warning */
5507                 #ifdef JP
5508                 mac_warning("¥á¥â¥ê¡¼¤¬Â­¤ê¤Þ¤»¤ó!\rº£¤¹¤°½ªÎ»¤·¤Æ²¼¤µ¤¤!");
5509                 #else
5510                 mac_warning("Running out of Memory!\rAbort this process now!");
5511                 #endif
5512
5513                 /* Mega-Hack -- Never leave this function */
5514                 while (TRUE) CheckEvents(TRUE);
5515         }
5516
5517         /* Mega-Hack -- Crash */
5518         return (NULL);
5519 }
5520
5521
5522 /*
5523  * Hook to tell the user something important
5524  */
5525 static void hook_plog(cptr str)
5526 {
5527         /* Warning message */
5528         mac_warning(str);
5529 }
5530
5531 /*
5532  * Hook to tell the user something, and then quit
5533  */
5534 static void hook_quit(cptr str)
5535 {
5536         /* Warning if needed */
5537         if (str) mac_warning(str);
5538
5539         /* Write a preference file */
5540         save_pref_file();
5541
5542         /* All done */
5543         ExitToShell();
5544 }
5545
5546 /*
5547  * Hook to tell the user something, and then crash
5548  */
5549 static void hook_core(cptr str)
5550 {
5551         /* XXX Use the debugger */
5552         /* DebugStr(str); */
5553
5554         /* Warning */
5555         if (str) mac_warning(str);
5556
5557         /* Warn, then save player */
5558         #ifdef JP
5559         mac_warning("Ã×̿Ū¤Ê¥¨¥é¡¼¤Ç¤¹.\r¶¯À©Åª¤Ë¥»¡¼¥Ö¤·¤Æ½ªÎ»¤·¤Þ¤¹.");
5560         #else
5561         mac_warning("Fatal error.\rI will now attempt to save and quit.");
5562         #endif
5563
5564         /* Attempt to save */
5565         #ifdef JP
5566         if (!save_player()) mac_warning("·Ù¹ð -- ¥»¡¼¥Ö¤Ë¼ºÇÔ¤·¤Þ¤·¤¿!");
5567         #else
5568         if (!save_player()) mac_warning("Warning -- save failed!");
5569         #endif
5570         
5571         /* Quit */
5572         quit(NULL);
5573 }
5574
5575
5576
5577 /*** Main program ***/
5578
5579
5580 /*
5581  * Init some stuff
5582  *
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...
5589  *
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...
5593  */
5594 static void init_stuff(void)
5595 {
5596         int i;
5597
5598         short vrefnum;
5599         long drefnum;
5600         long junk;
5601
5602         SFTypeList types;
5603         SFReply reply;
5604
5605         Rect r;
5606         Point topleft;
5607
5608         char path[1024];
5609
5610         BitMap screen;
5611         Rect screenRect;
5612
5613 #if TARGET_API_MAC_CARBON
5614         OSErr err = noErr;
5615         NavDialogOptions dialogOptions;
5616         FSSpec theFolderSpec;
5617         NavReplyRecord theReply;
5618 #endif
5619         /* Fake rectangle */
5620         r.left = 0;
5621         r.top = 0;
5622         r.right = 344;
5623         r.bottom = 188;
5624
5625         /* Center it */
5626 #if TARGET_API_MAC_CARBON
5627         screenRect = GetQDGlobalsScreenBits(&screen)->bounds;
5628 #else
5629         screenRect = qd.screenBits.bounds;
5630 #endif
5631         center_rect(&r, &screenRect);
5632
5633         /* Extract corner */
5634         topleft.v = r.top;
5635         topleft.h = r.left;
5636
5637
5638         /* Default to the "lib" folder with the application */
5639         refnum_to_name(path, app_dir, app_vol, (char*)("\plib:"));
5640
5641
5642         /* Check until done */
5643         while (1)
5644         {
5645                 /* Prepare the paths */
5646                 init_file_paths(path);
5647
5648                 /* Build the filename */
5649 #ifdef JP
5650                 path_build(path, sizeof(path), ANGBAND_DIR_FILE, "news_j.txt");
5651 #else
5652                 path_build(path, sizeof(path), ANGBAND_DIR_FILE, "news.txt");
5653 #endif
5654
5655                 /* Attempt to open and close that file */
5656                 if (0 == fd_close(fd_open(path, O_RDONLY))) break;
5657
5658                 /* Warning */
5659 #ifdef JP
5660                 plog_fmt("'%s' ¥Õ¥¡¥¤¥ë¤ò¥ª¡¼¥×¥ó½ÐÍè¤Þ¤»¤ó.", path);
5661 #else
5662                 plog_fmt("Unable to open the '%s' file.", path);
5663 #endif
5664
5665                 /* Warning */
5666 #ifdef JP
5667                 plog("Hengband¤Î'lib'¥Õ¥©¥ë¥À¤¬Â¸ºß¤·¤Ê¤¤¤«Àµ¤·¤¯Ìµ¤¤²ÄǽÀ­¤¬¤¢¤ê¤Þ¤¹.");
5668 #else
5669                 plog("The Angband 'lib' folder is probably missing or misplaced.");
5670 #endif
5671
5672                 /* Warning */
5673 #ifdef JP
5674                 plog("Please 'open' any file in any sub-folder of the 'lib' folder.");
5675 #else
5676                 plog("Please 'open' any file in any sub-folder of the 'lib' folder.");
5677 #endif
5678                 
5679 #if TARGET_API_MAC_CARBON
5680                 /* Ask the user to choose the lib folder */
5681                 err = NavGetDefaultDialogOptions(&dialogOptions);
5682
5683                 /* Paranoia */
5684                 if (err != noErr) quit(NULL);
5685
5686                 /* Set default location option */
5687                 dialogOptions.dialogOptionFlags |= kNavSelectDefaultLocation;
5688
5689                 /* Clear preview option */
5690                 dialogOptions.dialogOptionFlags &= ~(kNavAllowPreviews);
5691
5692                 /* Forbit selection of multiple files */
5693                 dialogOptions.dialogOptionFlags &= ~(kNavAllowMultipleFiles);
5694
5695                 /* Display location */
5696                 dialogOptions.location = topleft;
5697
5698                 /* Load the message for the missing folder from the resource fork */
5699                 GetIndString(dialogOptions.message, 128, 1);
5700
5701                 /* Wait for the user to choose a folder */
5702                 err = NavChooseFolder(
5703                         nil,
5704                         &theReply,
5705                         &dialogOptions,
5706                         nil,
5707                         nil,
5708                         nil);
5709
5710                 /* Assume the player doesn't want to go on */
5711                 if ((err != noErr) || !theReply.validRecord) quit(NULL);
5712
5713                 /* Retrieve FSSpec from the reply */
5714                 {
5715                         AEKeyword theKeyword;
5716                         DescType actualType;
5717                         Size actualSize;
5718
5719                         /* Get a pointer to selected folder */
5720                         err = AEGetNthPtr(
5721                                 &(theReply.selection),
5722                                 1,
5723                                 typeFSS,
5724                                 &theKeyword,
5725                                 &actualType,
5726                                 &theFolderSpec,
5727                                 sizeof(FSSpec),
5728                                 &actualSize);
5729
5730                         /* Paranoia */
5731                         if (err != noErr) quit(NULL);
5732                 }
5733
5734                 /* Free navitagor reply */
5735                 err = NavDisposeReply(&theReply);
5736
5737                 /* Paranoia */
5738                 if (err != noErr) quit(NULL);
5739
5740                 /* Extract textual file name for given file */
5741                 refnum_to_name(
5742                         path,
5743                         theFolderSpec.parID,
5744                         theFolderSpec.vRefNum,
5745                         (char *)theFolderSpec.name);
5746 #else
5747                 /* Allow "text" files */
5748                 types[0] = 'TEXT';
5749
5750                 /* Allow "save" files */
5751                 types[1] = 'SAVE';
5752
5753                 /* Allow "data" files */
5754                 types[2] = 'DATA';
5755
5756                 /* Get any file */
5757                 SFGetFile(topleft, "\p", NULL, 3, types, NULL, &reply);
5758
5759                 /* Allow cancel */
5760                 if (!reply.good) quit(NULL);
5761
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);
5765 #endif
5766
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';
5771
5772                 /* Hack -- allow "lib" folders */
5773                 if (suffix(path, "lib:")) continue;
5774
5775                 /* Hack -- Remove the "sub-folder" */
5776                 i = i - 1;
5777                 while ((i > 1) && (path[i] != ':')) i--;
5778                 if (path[i] == ':') path[i+1] = '\0';
5779         }
5780 }
5781
5782
5783 /*
5784  * Macintosh Main loop
5785  */
5786 void main(void)
5787 {
5788         EventRecord tempEvent;
5789         int numberOfMasters = 10;
5790
5791 #if !TARGET_API_MAC_CARBON
5792         /* Increase stack space by 64K */
5793         SetApplLimit(GetApplLimit() - 131072L);//65536L);
5794
5795         /* Stretch out the heap to full size */
5796         MaxApplZone();
5797 #endif
5798
5799         /* Get more Masters */
5800         while (numberOfMasters--) MoreMasters();
5801
5802 #if !TARGET_API_MAC_CARBON
5803         /* Set up the Macintosh */
5804         InitGraf(&qd.thePort);
5805         InitFonts();
5806         InitWindows();
5807         InitMenus();
5808         /* TEInit(); */
5809         InitDialogs(NULL);
5810 #endif
5811         InitCursor();
5812
5813 #ifdef JP
5814         KeyScript(smRoman);
5815 #endif
5816
5817         /* Flush events */
5818         FlushEvents(everyEvent, 0);
5819
5820         /* Flush events some more (?) */
5821         (void)EventAvail(everyEvent, &tempEvent);
5822         (void)EventAvail(everyEvent, &tempEvent);
5823         (void)EventAvail(everyEvent, &tempEvent);
5824
5825
5826 #ifdef ANGBAND_LITE_MAC
5827
5828         /* Nothing */
5829
5830 #else /* ANGBAND_LITE_MAC */
5831
5832 # if defined(powerc) || defined(__powerc)
5833
5834         /* Assume System 7 */
5835         
5836         /* Assume Color Quickdraw */
5837
5838 # else
5839
5840         /* Block */
5841         if (TRUE)
5842         {
5843                 OSErr err;
5844                 long versionNumber;
5845
5846                 /* Check the Gestalt */
5847                 err = Gestalt(gestaltSystemVersion, &versionNumber);
5848
5849                 /* Check the version */
5850                 if ((err != noErr) || (versionNumber < 0x0700))
5851                 {
5852                         #ifdef JP
5853                         quit("¤³¤Î¥×¥í¥°¥é¥à¤Ï´Á»úTalk7.x.x°Ê¹ß¤ÇÆ°ºî¤·¤Þ¤¹.");
5854                         #else
5855                         quit("You must have System 7 to use this program.");
5856                         #endif
5857                 }
5858         }
5859
5860         /* Block */
5861         if (TRUE)
5862         {
5863                 SysEnvRec env;
5864
5865                 /* Check the environs */
5866                 if (SysEnvirons(1, &env) != noErr)
5867                 {
5868                         #ifdef JP
5869                         quit("SysEnvirons ¥³¡¼¥ë¤Ï¼ºÇÔ¤·¤Þ¤·¤¿¡ª");
5870                         #else
5871                         quit("The SysEnvirons call failed!");
5872                         #endif
5873                 }
5874
5875                 /* Check for System Seven Stuff */
5876                 if (env.systemVersion < 0x0700)
5877                 {
5878                         #ifdef JP
5879                         quit("¤³¤Î¥×¥í¥°¥é¥à¤Ï´Á»úTalk7.x.x°Ê¹ß¤ÇÆ°ºî¤·¤Þ¤¹.");
5880                         #else
5881                         quit("You must have System 7 to use this program.");
5882                         #endif
5883                 }
5884
5885                 /* Check for Color Quickdraw */
5886                 if (!env.hasColorQD)
5887                 {
5888                         #ifdef JP
5889                         quit("¤³¤Î¥×¥í¥°¥é¥à¤ÏColor Quickdraw¤¬Ìµ¤¤¤ÈÆ°ºî¤·¤Þ¤»¤ó.");
5890                         #else
5891                         quit("You must have Color Quickdraw to use this program.");
5892                         #endif
5893                 }
5894         }
5895
5896 # endif
5897
5898 #endif /* ANGBAND_LITE_MAC */
5899
5900         /* 
5901          * Remember Mac OS version, in case we have to cope with version-specific
5902          * problems
5903          */
5904         (void)Gestalt(gestaltSystemVersion, &mac_os_version);
5905
5906 #ifdef USE_SFL_CODE
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,
5911                               0L, FALSE);
5912
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,
5917                               0L, FALSE);
5918
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,
5923                               0L, FALSE);
5924
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,
5929                               0L, FALSE);
5930 #endif
5931
5932         /* Find the current application */
5933         SetupAppDir();
5934
5935
5936         /* Mark ourself as the file creator */
5937         _fcreator = 'Heng';
5938
5939         /* Default to saving a "text" file */
5940         _ftype = 'TEXT';
5941
5942
5943 #if defined(__MWERKS__)
5944
5945         /* Obtian a "Universal Procedure Pointer" */
5946 #if TARGET_API_MAC_CARBON
5947         ynfilterUPP = NewModalFilterUPP(ynfilter);
5948 #else
5949         ynfilterUPP = NewModalFilterProc(ynfilter);
5950 #endif
5951
5952 #endif
5953
5954
5955         /* Hook in some "z-virt.c" hooks */
5956         rnfree_aux = hook_rnfree;
5957         ralloc_aux = hook_ralloc;
5958         rpanic_aux = hook_rpanic;
5959
5960         /* Hooks in some "z-util.c" hooks */
5961         plog_aux = hook_plog;
5962         quit_aux = hook_quit;
5963         core_aux = hook_core;
5964
5965         BackColor(blackColor);
5966         ForeColor(whiteColor);
5967
5968         /* Show the "watch" cursor */
5969         SetCursor(*(GetCursor(watchCursor)));
5970
5971         /* Prepare the menubar */
5972         init_menubar();
5973
5974         /* Prepare the windows */
5975         init_windows();
5976
5977         init_sound();
5978
5979         init_graf();
5980         
5981         /* Hack -- process all events */
5982         while (CheckEvents(TRUE)) /* loop */;
5983
5984         /* Reset the cursor */
5985 #if TARGET_API_MAC_CARBON
5986         {
5987                 Cursor  arrow;
5988                 GetQDGlobalsArrow( &arrow );
5989                 SetCursor(&arrow);
5990         }
5991 #else
5992         SetCursor( &qd.arrow );
5993 #endif
5994
5995
5996         /* Mega-Hack -- Allocate a "lifeboat" */
5997         lifeboat = NewPtr(16384);
5998
5999         /* Note the "system" */
6000         ANGBAND_SYS = "mac";
6001
6002         /* Initialize */
6003         init_stuff();
6004
6005         /* Initialize */
6006         init_angband();
6007
6008
6009         /* Hack -- process all events */
6010         while (CheckEvents(TRUE)) /* loop */;
6011
6012
6013         /* We are now initialized */
6014         initialized = TRUE;
6015
6016
6017         /* Handle "open_when_ready" */
6018         handle_open_when_ready();
6019
6020 #ifdef CHUUKEI
6021         init_chuukei();
6022 #endif
6023
6024         /* Prompt the user */
6025 #ifdef JP
6026         prt("'¥Õ¥¡¥¤¥ë'¥á¥Ë¥å¡¼¤è¤ê'¿·µ¬'¤Þ¤¿¤Ï'³«¤¯...'¤òÁªÂò¤·¤Æ¤¯¤À¤µ¤¤¡£", 23, 10);
6027 #else
6028         prt("[Choose 'New' or 'Open' from the 'File' menu]", 23, 15);
6029 #endif
6030
6031         /* Flush the prompt */
6032         Term_fresh();
6033
6034
6035         /* Hack -- Process Events Forever */
6036         while (TRUE) CheckEvents(TRUE);
6037 }
6038