OSDN Git Service

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