OSDN Git Service

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