OSDN Git Service

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