OSDN Git Service

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