OSDN Git Service

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