OSDN Git Service

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