OSDN Git Service

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