OSDN Git Service

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