OSDN Git Service

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