OSDN Git Service

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