OSDN Git Service

USE_TRANSPARENCYでASCII文字地形の上にタイルの敵等が乗ると、
[hengbandforosx/hengbandosx.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                             ((byte)ta & 0x80) && ((byte)tc & 0x80))
1972                         {
1973                                 /* Row and Col */
1974                                 row = ((byte)ta & 0x7F);
1975                                 col = ((byte)tc & 0x7F);
1976
1977                                 /* Terrain Source rectangle */
1978                                 terrain_r.left = col * grafWidth;
1979                                 terrain_r.top = row * grafHeight;
1980                                 terrain_r.right = terrain_r.left + grafWidth;
1981                                 terrain_r.bottom = terrain_r.top + grafHeight;
1982
1983                                 terrain_flag = TRUE;
1984                         }
1985 #endif
1986
1987                         /* Row and Col */
1988                         row = ((byte)a & 0x7F);
1989                         col = ((byte)c & 0x7F);
1990                         
1991                         /* Source rectangle */
1992                         r1.left = col * grafWidth;
1993                         r1.top = row * grafHeight;
1994                         r1.right = r1.left + grafWidth;
1995                         r1.bottom = r1.top + grafHeight;
1996
1997                         /* Hardwire CopyBits */
1998                         BackColor(whiteColor);
1999                         ForeColor(blackColor);
2000
2001                         /* Draw the picture */
2002
2003                         if (use_buffer)
2004                                 destBitMap = (BitMapPtr)(td->bufferPix);
2005                         else
2006                                 destBitMap = (BitMapPtr)&(td->w->portBits);
2007                                 
2008                         if (use_bigtile) r2.right += td->tile_wid;
2009
2010 #ifdef USE_TRANSPARENCY
2011                         if (terrain_flag)
2012                         {
2013                                 /*
2014                                  * Source mode const = srcCopy:
2015                                  *
2016                                  * determine how close the color of the source
2017                                  * pixel is to black, and assign this relative
2018                                  * amount of foreground color to the
2019                                  * destination pixel; determine how close the
2020                                  * color of the source pixel is to white, and
2021                                  * assign this relative amount of background
2022                                  * color to the destination pixel
2023                                  */
2024                                 CopyBits( srcBitMap, destBitMap, &terrain_r, &r2, srcCopy, NULL );
2025                                 
2026                                 /*
2027                                  * Draw transparent tile
2028                                  * BackColor is ignored and the destination is
2029                                  * left untouched
2030                                  */
2031                                 BackColor(blackColor);
2032                                 CopyBits( srcBitMap, destBitMap, &r1, &r2, transparent, NULL );
2033                         }
2034                         else
2035 #endif /* USE_TRANSPARENCY */
2036                         {
2037                                 CopyBits( srcBitMap, destBitMap, &r1, &r2, srcCopy, NULL );
2038                         }
2039
2040                         /* Restore colors */
2041                         BackColor(blackColor);
2042                         ForeColor(whiteColor);
2043
2044                         /* Forget color */
2045                         td->last = -1;
2046
2047                         /* Done */
2048                         done = TRUE;
2049                 }
2050
2051 #endif /* ANGBAND_LITE_MAC */
2052
2053                 /* Normal */
2054                 if (!done)
2055                 {
2056                         int xp, yp;
2057
2058                         /* Set the color */
2059                         term_data_color(td, (a & 0x0F));
2060                         
2061                         /* Starting pixel */
2062                         xp = r2.left + td->tile_o_x;
2063                         yp = r2.top + td->tile_o_y;
2064                         
2065                         /* Move to the correct location */
2066                         MoveTo(xp, yp);
2067
2068 #ifdef JP
2069                         if (iskanji(c))
2070                         {
2071                                 /* Double width rectangle */
2072                                 r2.right += td->tile_wid;
2073
2074                                 /* Erase */
2075                                 EraseRect(&r2);
2076
2077                                 /* Draw the character */
2078                                 DrawText(cp, i, 2);
2079                                 
2080                                 i++;
2081                                 
2082                                 r2.left += td->tile_wid;
2083                         }
2084                         else
2085 #endif
2086                         {
2087                                 /* Erase */
2088                                 EraseRect(&r2);
2089
2090                                 /* Draw the character */
2091                                 DrawChar(c);
2092                         }
2093                 }
2094
2095                 /* Advance */
2096                 r2.left += td->tile_wid;
2097         }
2098         
2099         if( use_buffer )
2100         {
2101                 /* Now we blast the buffer pixmap onto the screen in the right place */
2102                 BitMapPtr       srcBitMap = (BitMapPtr)(td->bufferPix);
2103
2104                 BitMapPtr       destBitMap = (BitMapPtr)&(td->w->portBits);
2105
2106                 Rect            srcRect;
2107                 Rect            destRect;
2108                 
2109                 
2110                 srcRect.left = x * td->tile_wid + td->size_ow1;
2111                 srcRect.top = 0;
2112                 srcRect.right = srcRect.left + (td->tile_wid * n);
2113                 srcRect.bottom = td->tile_hgt;
2114                 
2115                 destRect.left = x * td->tile_wid + td->size_ow1;
2116                 destRect.right = destRect.left + (td->tile_wid * n);
2117                 destRect.top = y * td->tile_hgt + td->size_oh1;
2118                 destRect.bottom = destRect.top + td->tile_hgt;
2119
2120                 /* Double width rectangle */
2121                 if (use_bigtile)
2122                 {
2123                         srcRect.right += td->tile_wid * n;
2124                         destRect.right += td->tile_wid * n;
2125                 }
2126
2127                 UnlockPixels( PortPix );
2128
2129                 /* Restore GWorld */
2130                 SetGWorld(saveGWorld, saveGDevice);
2131                 
2132                 /* Hardwire CopyBits */
2133                 BackColor(whiteColor);
2134                 ForeColor(blackColor);
2135                 
2136                 CopyBits( srcBitMap, destBitMap, &srcRect, &destRect, srcCopy, NULL );
2137                 
2138                 /* Restore colors */
2139                 BackColor(blackColor);
2140                 ForeColor(whiteColor);
2141         }
2142         
2143         /* Success */
2144         return (0);
2145 }
2146
2147
2148
2149
2150
2151
2152 /*
2153  * Create and initialize window number "i"
2154  */
2155 static void term_data_link(int i)
2156 {
2157         term *old = Term;
2158
2159         term_data *td = &data[i];
2160
2161         /* Only once */
2162         if (td->t) return;
2163
2164         /* Require mapped */
2165         if (!td->mapped) return;
2166
2167         /* Allocate */
2168         MAKE(td->t, term);
2169
2170         /* Initialize the term */
2171         term_init(td->t, td->cols, td->rows, td->keys);
2172
2173         /* Use a "software" cursor */
2174         td->t->soft_cursor = TRUE;
2175
2176         /* Erase with "white space" */
2177         td->t->attr_blank = TERM_WHITE;
2178         td->t->char_blank = ' ';
2179
2180         /* Prepare the init/nuke hooks */
2181         td->t->init_hook = Term_init_mac;
2182         td->t->nuke_hook = Term_nuke_mac;
2183
2184         /* Prepare the function hooks */
2185         td->t->user_hook = Term_user_mac;
2186         td->t->xtra_hook = Term_xtra_mac;
2187         td->t->wipe_hook = Term_wipe_mac;
2188         td->t->curs_hook = Term_curs_mac;
2189         td->t->text_hook = Term_text_mac;
2190         td->t->pict_hook = Term_pict_mac;
2191
2192         /* Link the local structure */
2193         td->t->data = (vptr)(td);
2194
2195         /* Activate it */
2196         Term_activate(td->t);
2197
2198         /* Global pointer */
2199         angband_term[i] = td->t;
2200
2201         /* Activate old */
2202         Term_activate(old);
2203 }
2204
2205
2206
2207
2208 /*
2209  * Set the "current working directory" (also known as the "default"
2210  * volume/directory) to the location of the current application.
2211  *
2212  * Code by: Maarten Hazewinkel (mmhazewi@cs.ruu.nl)
2213  *
2214  * This function does not appear to work correctly with System 6.
2215  */
2216 static void SetupAppDir(void)
2217 {
2218         FCBPBRec fcbBlock;
2219         OSErr err = noErr;
2220         char errString[100];
2221
2222         /* Get the location of the Angband executable */
2223         fcbBlock.ioCompletion = NULL;
2224         fcbBlock.ioNamePtr = NULL;
2225         fcbBlock.ioVRefNum = 0;
2226         fcbBlock.ioRefNum = CurResFile();
2227         fcbBlock.ioFCBIndx = 0;
2228         err = PBGetFCBInfo(&fcbBlock, FALSE);
2229         if (err != noErr)
2230         {
2231 #ifdef JP
2232                 sprintf(errString, "PBGetFCBInfo ¥¨¥é¡¼ #%d.\r ½ªÎ»¤·¤Þ¤¹.", err);
2233 #else
2234                 sprintf(errString, "Fatal PBGetFCBInfo Error #%d.\r Exiting.", err);
2235 #endif
2236                 mac_warning(errString);
2237                 ExitToShell();
2238         }
2239
2240         /* Extract the Vol and Dir */
2241         app_vol = fcbBlock.ioFCBVRefNum;
2242         app_dir = fcbBlock.ioFCBParID;
2243
2244         /* Set the current working directory to that location */
2245         err = HSetVol(NULL, app_vol, app_dir);
2246         if (err != noErr)
2247         {
2248 #ifdef JP
2249                 sprintf(errString, "HSetVol ¥¨¥é¡¼ #%d.\r ½ªÎ»¤·¤Þ¤¹.", err);
2250 #else
2251                 sprintf(errString, "Fatal HSetVol Error #%d.\r Exiting.", err);
2252 #endif
2253                 mac_warning(errString);
2254                 ExitToShell();
2255         }
2256 }
2257
2258
2259
2260
2261 /*
2262  * Global "preference" file pointer
2263  */
2264 static FILE *fff;
2265
2266 /*
2267  * Read a "short" from the file
2268  */
2269 static int getshort(void)
2270 {
2271         int x = 0;
2272         char buf[256];
2273         if (0 == my_fgets(fff, buf, 256)) x = atoi(buf);
2274         return (x);
2275 }
2276
2277 /*
2278  * Dump a "short" to the file
2279  */
2280 static void putshort(int x)
2281 {
2282         fprintf(fff, "%d\n", x);
2283 }
2284
2285
2286
2287 /*
2288  * Write the "preference" data to the current "file"
2289  */
2290 static void save_prefs(void)
2291 {
2292         int i;
2293
2294         term_data *td;
2295
2296
2297         /*** The current version ***/
2298
2299         putshort(FAKE_VERSION);
2300         putshort(FAKE_VER_MAJOR);
2301         putshort(FAKE_VER_MINOR);
2302         putshort(FAKE_VER_PATCH);
2303
2304         putshort(arg_sound);
2305         putshort(arg_graphics);
2306         putshort(arg_newstyle_graphics);
2307         putshort(arg_bigtile);
2308         
2309         /* SoundMode */
2310         for( i = 0 ; i < 7 ; i++ )
2311                 putshort(soundmode[i]);
2312         
2313         /* Dump */
2314         for (i = 0; i < MAX_TERM_DATA; i++)
2315         {
2316                 /* Access */
2317                 td = &data[i];
2318
2319                 putshort(td->mapped);
2320
2321                 putshort(td->font_id);
2322                 putshort(td->font_size);
2323                 putshort(td->font_face);
2324
2325                 putshort(td->tile_wid);
2326                 putshort(td->tile_hgt);
2327
2328                 putshort(td->cols);
2329                 putshort(td->rows);
2330
2331                 putshort(td->r.left);
2332                 putshort(td->r.top);
2333         }
2334 }
2335
2336
2337 /*
2338  * Load the preferences from the current "file"
2339  *
2340  * XXX XXX XXX Being able to undefine various windows is
2341  * slightly bizarre, and may cause problems.
2342  */
2343 static void load_prefs(void)
2344 {
2345         int i;
2346
2347         int old_version, old_major, old_minor, old_patch;
2348
2349         term_data *td;
2350         MenuHandle m;
2351
2352         /*** Version information ***/
2353
2354         /* Preferences version */
2355         old_version = getshort();
2356         old_major = getshort();
2357         old_minor = getshort();
2358         old_patch = getshort();
2359
2360         /* Hack -- Verify or ignore */
2361         if ((old_version != FAKE_VERSION) ||
2362             (old_major != FAKE_VER_MAJOR) ||
2363             (old_minor != FAKE_VER_MINOR) ||
2364             (old_patch != FAKE_VER_PATCH))
2365         {
2366                 /* Message */
2367                 #ifdef JP
2368                 mac_warning("¸Å¤¤½é´üÀßÄê¥Õ¥¡¥¤¥ë¤ò̵»ë¤·¤Þ¤¹.");
2369                 #else
2370                 mac_warning("Ignoring old preferences.");
2371                 #endif
2372                 /* Ignore */
2373                 return;
2374         }
2375
2376         arg_sound = getshort();
2377         arg_graphics = getshort();
2378         arg_newstyle_graphics = getshort();
2379         use_newstyle_graphics = arg_newstyle_graphics;
2380         
2381         if (use_newstyle_graphics == true)
2382         {
2383                 ANGBAND_GRAF = "new";
2384                 arg_newstyle_graphics = true;
2385                 grafWidth = grafHeight = 16;
2386                 pictID = 1002;
2387         }
2388         else
2389         {
2390                 ANGBAND_GRAF = "old";
2391                 arg_newstyle_graphics = false;
2392                 grafWidth = grafHeight = 8;
2393                 pictID = 1001;
2394         }
2395
2396         arg_bigtile = getshort();
2397         use_bigtile = arg_bigtile;
2398         
2399         /* SoundMode */
2400         for( i = 0 ; i < 7 ; i++ )
2401                 soundmode[i] = getshort();
2402         
2403         /* Special menu */
2404         m = GetMenuHandle(134); //m = GetMHandle(134);
2405         
2406         /* Item "arg_sound" */
2407         CheckItem(m, 1, arg_sound);
2408
2409         /* Item "arg_graphics" */
2410         CheckItem(m, 2, arg_graphics);
2411         
2412         /* Item "arg_newstyle_graphics"*/
2413         CheckItem(m, 8, arg_newstyle_graphics);
2414         
2415         /* Windows */
2416         for (i = 0; i < MAX_TERM_DATA; i++)
2417         {
2418                 /* Access */
2419                 td = &data[i];
2420
2421                 td->mapped = getshort();
2422
2423                 td->font_id = getshort();
2424                 td->font_size = getshort();
2425                 td->font_face = getshort();
2426
2427                 td->tile_wid = getshort();
2428                 td->tile_hgt = getshort();
2429
2430                 td->cols = getshort();
2431                 td->rows = getshort();
2432
2433                 td->r.left = getshort();
2434                 td->r.top = getshort();
2435
2436                 /* Done */
2437                 if (feof(fff)) break;
2438         }
2439 }
2440
2441
2442
2443
2444 /*
2445  * Hack -- default data for a window
2446  */
2447 static void term_data_hack(term_data *td)
2448 {
2449         short fid;
2450
2451         #ifdef JP
2452         GetFNum( "\pÅùÉýÌÀÄ«", &fid);     /* ¥Õ¥©¥ó¥È̾¤«¤éIDÈÖ¹æ¤òÄ´¤Ù¤ë  */
2453         SetFScaleDisable( true );
2454         #else
2455         /* Default to Monaco font */
2456         GetFNum("\pmonaco", &fid);
2457         #endif
2458         /* Wipe it */
2459         WIPE(td, term_data);
2460
2461         /* No color */
2462         td->last = -1;
2463
2464         /* Default borders */
2465         td->size_ow1 = 2;
2466         td->size_ow2 = 2;
2467         td->size_oh2 = 2;
2468
2469         /* Start hidden */
2470         td->mapped = FALSE;
2471
2472         /* Default font */
2473         td->font_id = fid;
2474
2475         /* Default font size */
2476         td->font_size = 12;
2477
2478         /* Default font face */
2479         td->font_face = 0;
2480
2481         /* Default size */
2482         td->rows = 24;
2483         td->cols = 80;
2484
2485         /* Default position */
2486         td->r.left = 10;
2487         td->r.top = 40;
2488
2489         /* Minimal keys */
2490         td->keys = 16;
2491 }
2492
2493
2494 /*
2495  * Read the preference file, Create the windows.
2496  *
2497  * We attempt to use "FindFolder()" to track down the preference file,
2498  * but if this fails, for any reason, we will try the "SysEnvirons()"
2499  * method, which may work better with System 6.
2500  */
2501 static void init_windows(void)
2502 {
2503         int i, b = 0;
2504
2505         term_data *td;
2506
2507         SysEnvRec env;
2508         short savev;
2509         long saved;
2510
2511         bool oops;
2512
2513
2514         /*** Default values ***/
2515
2516         /* Initialize (backwards) */
2517         for (i = MAX_TERM_DATA - 1; i >= 0; i--)
2518         {
2519                 int n;
2520
2521                 cptr s;
2522
2523                 /* Obtain */
2524                 td = &data[i];
2525
2526                 /* Defaults */
2527                 term_data_hack(td);
2528
2529                 /* Obtain title */
2530                 s = angband_term_name[i];
2531
2532                 /* Get length */
2533                 n = strlen(s);
2534
2535                 /* Maximal length */
2536                 if (n > 15) n = 15;
2537
2538                 /* Copy the title */
2539                 strncpy((char*)(td->title) + 1, s, n);
2540
2541                 /* Save the length */
2542                 td->title[0] = n;
2543
2544                 /* Tile the windows */
2545                 td->r.left += (b * 30);
2546                 td->r.top += (b * 30);
2547
2548                 /* Tile */
2549                 b++;
2550         }
2551
2552
2553         /*** Load preferences ***/
2554
2555         /* Assume failure */
2556         oops = TRUE;
2557
2558         /* Assume failure */
2559         fff = NULL;
2560
2561 #ifdef USE_SFL_CODE
2562
2563         /* Block */
2564         if (TRUE)
2565         {
2566                 OSErr   err;
2567                 short   vref;
2568                 long    dirID;
2569                 char    foo[128];
2570
2571                 /* Find the folder */
2572                 err = FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder,
2573                                  &vref, &dirID);
2574
2575                 /* Success */
2576                 if (!err)
2577                 {
2578                         /* Extract a path name */
2579                         PathNameFromDirID(dirID, vref, (StringPtr)foo);
2580
2581                         /* Convert the string */
2582                         ptocstr((StringPtr)foo);
2583
2584                         /* Append the preference file name */
2585                         strcat(foo, PREF_FILE_NAME);
2586
2587                         /* Open the preference file */
2588                         fff = fopen(foo, "r");
2589
2590                         /* Success */
2591                         oops = FALSE;
2592                 }
2593         }
2594
2595 #endif /* USE_SFL_CODE */
2596
2597         /* Oops */
2598         if (oops)
2599         {
2600                 /* Save */
2601                 HGetVol(0, &savev, &saved);
2602
2603                 /* Go to the "system" folder */
2604                 SysEnvirons(curSysEnvVers, &env);
2605                 SetVol(0, env.sysVRefNum);
2606
2607                 /* Open the file */
2608                 fff = fopen(PREF_FILE_NAME, "r");
2609
2610                 /* Restore */
2611                 HSetVol(0, savev, saved);
2612         }
2613
2614         /* Load preferences */
2615         if (fff)
2616         {
2617                 /* Load a real preference file */
2618                 load_prefs();
2619
2620                 /* Close the file */
2621                 my_fclose(fff);
2622         }
2623
2624
2625         /*** Instantiate ***/
2626
2627         /* Main window */
2628         td = &data[0];
2629
2630         /* Many keys */
2631         td->keys = 1024;
2632
2633         /* Start visible */
2634         td->mapped = TRUE;
2635
2636         /* Link (backwards, for stacking order) */
2637         for (i = MAX_TERM_DATA - 1; i >= 0; i--)
2638         {
2639                 term_data_link(i);
2640         }
2641
2642         /* Main window */
2643         td = &data[0];
2644
2645         /* Main window */
2646         Term_activate(td->t);
2647 }
2648
2649 static void init_sound( void )
2650 {
2651         int err, i;
2652         DirInfo pb;
2653         SignedByte              permission = fsRdPerm;
2654         pascal short    ret;
2655         
2656         Handle handle;
2657         Str255 sound;
2658
2659         /* Descend into "lib" folder */
2660         pb.ioCompletion = NULL;
2661         pb.ioNamePtr = "\plib";
2662         pb.ioVRefNum = app_vol;
2663         pb.ioDrDirID = app_dir;
2664         pb.ioFDirIndex = 0;
2665
2666         /* Check for errors */
2667         err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
2668
2669         /* Success */
2670         if ((err == noErr) && (pb.ioFlAttrib & 0x10))
2671         {
2672                 /* Descend into "lib/save" folder */
2673                 pb.ioCompletion = NULL;
2674                 pb.ioNamePtr = "\pxtra";
2675                 pb.ioVRefNum = app_vol;
2676                 pb.ioDrDirID = pb.ioDrDirID;
2677                 pb.ioFDirIndex = 0;
2678
2679                 /* Check for errors */
2680                 err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
2681                         
2682                         /* Success */
2683                 if ((err == noErr) && (pb.ioFlAttrib & 0x10))
2684                 {
2685                         /* Descend into "lib/save" folder */
2686                         pb.ioCompletion = NULL;
2687                         pb.ioNamePtr = "\psound";
2688                         pb.ioVRefNum = app_vol;
2689                         pb.ioDrDirID = pb.ioDrDirID;
2690                         pb.ioFDirIndex = 0;
2691
2692                         /* Check for errors */
2693                         err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
2694
2695                         /* Success */
2696                         if ((err == noErr) && (pb.ioFlAttrib & 0x10))
2697                         {
2698                                 ret = HOpenResFile( app_vol , pb.ioDrDirID , "\psound.rsrc" , permission );
2699                                 if( ret != -1 ){
2700                                         ext_sound = 1;
2701                                         
2702                                         for( i = 0 ; i < 7 ; i++ )
2703                                                         soundmode[i] = false;
2704                                         
2705                                         for( i = 1 ; i < SOUND_MAX ; i++ ){
2706                                                 /* Get the proper sound name */
2707                                                 sprintf((char*)sound + 1, "%.16s.wav", angband_sound_name[i]);
2708                                                 sound[0] = strlen((char*)sound + 1);
2709
2710                                                 /* Obtain resource XXX XXX XXX */
2711                                                 handle = Get1NamedResource('snd ', sound);
2712                                                 if( handle == NULL || ext_sound )
2713                                                         handle = GetNamedResource('snd ', sound);
2714                                                 
2715                                                 if( handle )
2716                                                         soundmode[soundchoice[i]] = true;
2717                                                 
2718                                         }
2719                                 }
2720                         }
2721                 }
2722         }
2723 }
2724
2725 #ifdef CHUUKEI
2726 /*
2727
2728 */
2729 static void init_chuukei( void )
2730 {
2731         char path[1024];
2732         char tmp[1024];
2733         FILE *fp;
2734         
2735         path_build(path, 1024, ANGBAND_DIR_XTRA, "chuukei.txt");
2736
2737         fp = fopen(path, "r");
2738         if(!fp)
2739                 return;
2740         
2741         /* Read a line */
2742         if (fgets(tmp, 1024, fp)){
2743                 if(tmp[0] == '-'){
2744                         int n = strlen(tmp);
2745                         tmp[n-1] = 0;
2746                         switch(tmp[1]){
2747                         case 'p':
2748                         {
2749                                 if (!tmp[2]) break;
2750                                 chuukei_server = TRUE;
2751                                 if(connect_chuukei_server(&tmp[2])<0){
2752                                         msg_print("connect fail");
2753                                         return;
2754                                 }
2755                                 msg_print("connect");
2756                                 msg_print(NULL);
2757                                 break;
2758                         }
2759
2760                         case 'c':
2761                         {
2762                                 chuukei_client = TRUE;
2763                                 connect_chuukei_server(&tmp[2]);
2764                                 play_game(FALSE);
2765                                 quit(NULL);
2766                         }
2767                         }
2768                 }
2769                 
2770         }
2771         fclose(fp);
2772         
2773 }
2774 #endif
2775
2776 /*
2777
2778 */
2779 short InevrtCheck( DialogPtr targetDlg, short check )
2780 {
2781         Handle  checkH;
2782         short   itemType;
2783         long    result;
2784         Rect    box;
2785         
2786         GetDialogItem( targetDlg, check, &itemType, &checkH, &box );
2787         result = (GetControlValue( (ControlHandle)checkH ) + 1 ) % 2;
2788         SetControlValue( (ControlHandle)checkH , result );
2789         return result ;
2790
2791 }
2792
2793 /*
2794
2795 */
2796 short SetCheck( DialogPtr targetDlg, short check, long result )
2797 {
2798         Handle  checkH;
2799         short   itemType;
2800
2801         Rect    box;
2802         
2803         GetDialogItem( targetDlg, check, &itemType, &checkH, &box );
2804         SetControlValue( (ControlHandle)checkH , result );
2805         return result ;
2806
2807 }
2808
2809 /*
2810
2811 */
2812 short GetCheck( DialogPtr targetDlg, short check )
2813 {
2814         Handle  checkH;
2815         short   itemType;
2816         long    result;
2817         Rect    box;
2818         
2819         GetDialogItem( targetDlg, check, &itemType, &checkH, &box );
2820         result = GetControlValue( (ControlHandle)checkH );
2821         return result ;
2822
2823 }
2824 void SoundConfigDLog(void)
2825 {
2826         DialogPtr dialog;
2827         Rect r;
2828         short item_hit;
2829         int     i;
2830
2831         dialog=GetNewDialog(131, 0, (WindowPtr)-1);
2832         SetDialogDefaultItem( dialog, ok );
2833         SetDialogCancelItem( dialog, cancel );
2834         for( i = 1 ; i < 7 ; i++ )
2835                 SetCheck( dialog, i+2 , soundmode[i] );
2836         
2837         ShowWindow(dialog);
2838         for( item_hit = 100 ; cancel < item_hit ; ){
2839                 ModalDialog(0, &item_hit);
2840                 
2841                 switch(item_hit){
2842                         case ok:
2843                                 for( i = 1 ; i < 7 ; i++ )
2844                                         soundmode[i] = GetCheck( dialog, i+2 );
2845                                 break;
2846                         case cancel:
2847                                 break;
2848                         default:
2849                                 InevrtCheck( dialog, item_hit );
2850                 }
2851         }
2852         DisposeDialog(dialog);
2853
2854 }
2855
2856
2857 /*
2858  * Exit the program
2859  */
2860 static void save_pref_file(void)
2861 {
2862         bool oops;
2863
2864         SysEnvRec env;
2865         short savev;
2866         long saved;
2867
2868
2869         /* Assume failure */
2870         oops = TRUE;
2871
2872         /* Assume failure */
2873         fff = NULL;
2874
2875         /* Text file */
2876         _ftype = 'TEXT';
2877
2878
2879 #ifdef USE_SFL_CODE
2880
2881         /* Block */
2882         if (TRUE)
2883         {
2884                 OSErr   err;
2885                 short   vref;
2886                 long    dirID;
2887                 char    foo[128];
2888
2889                 /* Find the folder */
2890                 err = FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder,
2891                                  &vref, &dirID);
2892
2893                 /* Success */
2894                 if (!err)
2895                 {
2896                         /* Extract a path name */
2897                         PathNameFromDirID(dirID, vref, (StringPtr)foo);
2898
2899                         /* Convert the string */
2900                         ptocstr((StringPtr)foo);
2901
2902                         /* Append the preference file name */
2903                         strcat(foo, PREF_FILE_NAME);
2904
2905                         /* Open the preference file */
2906                         /* my_fopen set file type and file creator for MPW */
2907                         fff = my_fopen(foo, "w");
2908
2909                         /* Success */
2910                         oops = FALSE;
2911                 }
2912         }
2913
2914 #endif /* USE_SFL_CODE */
2915
2916         /* Oops */
2917         if (oops)
2918         {
2919                 /* Save */
2920                 HGetVol(0, &savev, &saved);
2921
2922                 /* Go to "system" folder */
2923                 SysEnvirons(curSysEnvVers, &env);
2924                 SetVol(0, env.sysVRefNum);
2925
2926                 /* Open the preference file */
2927                 /* my_fopen set file type and file creator for MPW */
2928                 fff = fopen(PREF_FILE_NAME, "w");
2929
2930                 /* Restore */
2931                 HSetVol(0, savev, saved);
2932         }
2933
2934         /* Save preferences */
2935         if (fff)
2936         {
2937                 /* Write the preferences */
2938                 save_prefs();
2939
2940                 /* Close it */
2941                 my_fclose(fff);
2942         }
2943 }
2944
2945
2946
2947 /*
2948  * A simple "Yes/No" filter to parse "key press" events in dialog windows
2949  */
2950 static pascal Boolean ynfilter(DialogPtr dialog, EventRecord *event, short *ip)
2951 {
2952         /* Parse key press events */
2953         if (event->what == keyDown)
2954         {
2955                 int i = 0;
2956                 char c;
2957
2958                 /* Extract the pressed key */
2959                 c = (event->message & charCodeMask);
2960
2961                 /* Accept "no" and <return> and <enter> */
2962                 if ((c=='n') || (c=='N') || (c==13) || (c==3)) i = 1;
2963
2964                 /* Accept "yes" */
2965                 else if ((c=='y') || (c=='Y')) i = 2;
2966
2967                 /* Handle "yes" or "no" */
2968                 if (i)
2969                 {
2970                         short type;
2971                         ControlHandle control;
2972                         Rect r;
2973
2974                         /* Get the button */
2975                         GetDialogItem(dialog, i, &type, (Handle*)&control, &r); //GetDItem(dialog, i, &type, (Handle*)&control, &r);
2976
2977                         /* Blink button for 1/10 second */
2978                         HiliteControl(control, 1);
2979                         Term_xtra_mac(TERM_XTRA_DELAY, 100);
2980                         HiliteControl(control, 0);
2981
2982                         /* Result */
2983                         *ip = i;
2984                         return (1);
2985                 }
2986         }
2987
2988         /* Ignore */
2989         return (0);
2990 }
2991
2992
2993 /*
2994  * Handle menu: "File" + "New"
2995  */
2996 static void do_menu_file_new(void)
2997 {
2998         /* Hack */
2999         HiliteMenu(0);
3000
3001         /* Game is in progress */
3002         game_in_progress = 1;
3003
3004         /* Flush input */
3005         flush();
3006
3007         /* Play a game */
3008         play_game(TRUE);
3009
3010         /* Hack -- quit */
3011         quit(NULL);
3012 }
3013
3014
3015 /*
3016  * Handle menu: "File" + "Open"
3017  */
3018 static void do_menu_file_open(bool all)
3019 {
3020         int err;
3021         short vrefnum;
3022         long drefnum;
3023         long junk;
3024         DirInfo pb;
3025         SFTypeList types;
3026         SFReply reply;
3027         Point topleft;
3028
3029
3030         /* XXX XXX XXX */
3031
3032         /* vrefnum = GetSFCurVol(); */
3033         vrefnum = -*((short*)0x214);
3034
3035         /* drefnum = GetSFCurDir(); */
3036         drefnum = *((long*)0x398);
3037
3038         /* Descend into "lib" folder */
3039         pb.ioCompletion = NULL;
3040         pb.ioNamePtr = "\plib";
3041         pb.ioVRefNum = vrefnum;
3042         pb.ioDrDirID = drefnum;
3043         pb.ioFDirIndex = 0;
3044
3045         /* Check for errors */
3046         err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
3047
3048         /* Success */
3049         if ((err == noErr) && (pb.ioFlAttrib & 0x10))
3050         {
3051                 /* Descend into "lib/save" folder */
3052                 pb.ioCompletion = NULL;
3053                 pb.ioNamePtr = "\psave";
3054                 pb.ioVRefNum = vrefnum;
3055                 pb.ioDrDirID = pb.ioDrDirID;
3056                 pb.ioFDirIndex = 0;
3057
3058                 /* Check for errors */
3059                 err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
3060
3061                 /* Success */
3062                 if ((err == noErr) && (pb.ioFlAttrib & 0x10))
3063                 {
3064                         /* SetSFCurDir(pb.ioDrDirID); */
3065                         *((long*)0x398) = pb.ioDrDirID;
3066                 }
3067         }
3068
3069         /* Window location */
3070         topleft.h = (qd.screenBits.bounds.left+qd.screenBits.bounds.right)/2-344/2;
3071         topleft.v = (2*qd.screenBits.bounds.top+qd.screenBits.bounds.bottom)/3-188/2;
3072
3073         /* Allow "all" files */
3074         if (all)
3075         {
3076                 /* Get any file */
3077                 SFGetFile(topleft, "\p", NULL, -1, types, NULL, &reply);
3078         }
3079
3080         /* Allow "save" files */
3081         else
3082         {
3083                 /* Legal types */
3084                 types[0] = 'SAVE';
3085
3086                 /* Get a file */
3087                 SFGetFile(topleft, "\p", NULL, 1, types, NULL, &reply);
3088         }
3089
3090         /* Allow cancel */
3091         if (!reply.good) return;
3092
3093         /* Extract textual file name for save file */
3094         GetWDInfo(reply.vRefNum, &vrefnum, &drefnum, &junk);
3095         refnum_to_name(savefile, drefnum, vrefnum, (char*)reply.fName);
3096
3097         /* Hack */
3098         HiliteMenu(0);
3099
3100         /* Game is in progress */
3101         game_in_progress = 1;
3102
3103         /* Flush input */
3104         flush();
3105
3106         /* Play a game */
3107         play_game(FALSE);
3108
3109         /* Hack -- quit */
3110         quit(NULL);
3111 }
3112
3113
3114 /*
3115  * Handle the "open_when_ready" flag
3116  */
3117 static void handle_open_when_ready(void)
3118 {
3119         /* Check the flag XXX XXX XXX make a function for this */
3120         if (open_when_ready && initialized && !game_in_progress)
3121         {
3122                 /* Forget */
3123                 open_when_ready = FALSE;
3124
3125                 /* Game is in progress */
3126                 game_in_progress = 1;
3127
3128                 /* Wait for it */
3129                 pause_line(23);
3130
3131                 /* Flush input */
3132                 flush();
3133
3134                 /* Play a game */
3135                 play_game(FALSE);
3136
3137                 /* Quit */
3138                 quit(NULL);
3139         }
3140 }
3141
3142
3143
3144 /*
3145  * Initialize the menus
3146  *
3147  * Verify menus 128, 129, 130
3148  * Create menus 131, 132, 133, 134
3149  *
3150  * The standard menus are:
3151  *
3152  *   Apple (128) =   { About, -, ... }
3153  *   File (129) =    { New,Open,Import,Close,Save,-,Exit,Quit }
3154  *   Edit (130) =    { Cut, Copy, Paste, Clear }   (?)
3155  *   Font (131) =    { Bold, Extend, -, Monaco, ..., -, ... }
3156  *   Size (132) =    { ... }
3157  *   Window (133) =  { Angband, Mirror, Recall, Choice,
3158  *                     Term-4, Term-5, Term-6, Term-7 }
3159  *   Special (134) = { arg_sound, arg_graphics, -,
3160  *                     arg_fiddle, arg_wizard }
3161  */
3162 static void init_menubar(void)
3163 {
3164         int i, n;
3165
3166         Rect r;
3167
3168         WindowPtr tmpw;
3169
3170         MenuHandle m;
3171
3172
3173         /* Get the "apple" menu */
3174         m = GetMenu(128);
3175
3176         /* Insert the menu */
3177         InsertMenu(m, 0);
3178
3179         /* Add the DA's to the "apple" menu */
3180         AppendResMenu   (m, 'DRVR');    //AddResMenu(m, 'DRVR');
3181
3182
3183         /* Get the "File" menu */
3184         m = GetMenu(129);
3185
3186         /* Insert the menu */
3187         InsertMenu(m, 0);
3188
3189
3190         /* Get the "Edit" menu */
3191         m = GetMenu(130);
3192
3193         /* Insert the menu */
3194         InsertMenu(m, 0);
3195
3196
3197         /* Make the "Font" menu */
3198         #ifdef JP
3199         m = NewMenu(131, "\p¥Õ¥©¥ó¥È");
3200         #else
3201         m = NewMenu(131, "\pFont");
3202         #endif
3203         
3204         /* Insert the menu */
3205         InsertMenu(m, 0);
3206
3207         /* Add "bold" */
3208         AppendMenu(m, "\pBold");
3209
3210         /* Add "wide" */
3211         AppendMenu(m, "\pWide");
3212
3213         /* Add a separator */
3214         AppendMenu(m, "\p-");
3215
3216         /* Fake window */
3217         r.left = r.right = r.top = r.bottom = 0;
3218
3219         /* Make the fake window */
3220         tmpw = NewWindow(0, &r, "\p", false, documentProc, 0, 0, 0);
3221
3222         /* Activate the "fake" window */
3223         SetPort(tmpw);
3224
3225         /* Default mode */
3226         TextMode(0);
3227
3228         /* Default size */
3229         TextSize(12);
3230
3231         /* Add the fonts to the menu */
3232         AppendResMenu(m, 'FONT');       //AddResMenu(m, 'FONT');
3233
3234         /* Size of menu */
3235         n = CountMItems(m);
3236
3237         /* Scan the menu */
3238         for (i = n; i >= 4; i--)
3239         {
3240                 Str255 tmpName;
3241                 short fontNum;
3242
3243                 /* Acquire the font name */
3244                 /* GetMenuItemText(m, i, tmpName); */
3245                 GetMenuItemText(m, i, tmpName); //GetItem(m, i, tmpName);
3246
3247                 /* Acquire the font index */
3248                 GetFNum(tmpName, &fontNum);
3249
3250                 /* Apply the font index */
3251                 TextFont(fontNum);
3252
3253                 /* Remove non-mono-spaced fonts */
3254                 if ((CharWidth('i') != CharWidth('W')) || (CharWidth('W') == 0))
3255                 {
3256                         /* Delete the menu item XXX XXX XXX */
3257                         /* DeleteMenuItem(m, i); */
3258                         DeleteMenuItem  (m, i); //DelMenuItem(m, i);
3259                 }
3260         }
3261
3262         /* Destroy the old window */
3263         DisposeWindow(tmpw);
3264
3265         /* Add a separator */
3266         AppendMenu(m, "\p-");
3267
3268         /* Add the fonts to the menu */
3269         AppendResMenu   (m, 'FONT');    //AddResMenu(m, 'FONT');
3270
3271
3272         /* Make the "Size" menu */
3273         #ifdef JP
3274         m = NewMenu(132, "\p¥µ¥¤¥º");
3275         #else
3276         m = NewMenu(132, "\pSize");
3277         #endif
3278         
3279         /* Insert the menu */
3280         InsertMenu(m, 0);
3281
3282         /* Add some sizes (stagger choices) */
3283         for (i = 8; i <= 32; i += ((i / 16) + 1))
3284         {
3285                 Str15 buf;
3286                 
3287                 /* Textual size */
3288                 sprintf((char*)buf + 1, "%d", i);
3289                 buf[0] = strlen((char*)buf + 1);
3290
3291                 /* Add the item */
3292                 AppendMenu(m, buf);
3293         }
3294
3295
3296         /* Make the "Windows" menu */
3297         #ifdef JP
3298         m = NewMenu(133, "\p¥¦¥¤¥ó¥É¥¦");
3299         #else
3300         m = NewMenu(133, "\pWindows");
3301         #endif
3302         
3303         /* Insert the menu */
3304         InsertMenu(m, 0);
3305
3306         /* Default choices */
3307         for (i = 0; i < MAX_TERM_DATA; i++)
3308         {
3309                 Str15 buf;
3310                 
3311                 /* Describe the item */
3312                 sprintf((char*)buf + 1, "%.15s", angband_term_name[i]);
3313                 buf[0] = strlen((char*)buf + 1);
3314
3315                 /* Add the item */
3316                 AppendMenu(m, buf);
3317
3318                 /* Command-Key shortcuts */
3319                 if (i < 8) SetItemCmd(m, i + 1, '0' + i);
3320         }
3321
3322
3323         /* Make the "Special" menu */
3324         #ifdef JP
3325         m = NewMenu(134, "\pÆÃÊÌ");
3326         #else
3327         m = NewMenu(134, "\pSpecial");
3328         #endif
3329         
3330         /* Insert the menu */
3331         InsertMenu(m, 0);
3332
3333         /* Append the choices */
3334         #ifdef JP
3335         AppendMenu(m, "\p¥µ¥¦¥ó¥É»ÈÍÑ");
3336         AppendMenu(m, "\p¥°¥é¥Õ¥£¥Ã¥¯»ÈÍÑ");
3337         AppendMenu(m, "\p-");
3338         AppendMenu(m, "\parg_fiddle");
3339         AppendMenu(m, "\parg_wizard");
3340         AppendMenu(m, "\p-");
3341         AppendMenu(m, "\p¥µ¥¦¥ó¥ÉÀßÄê...");
3342         AppendMenu(m, "\p16X16¥°¥é¥Õ¥£¥Ã¥¯");
3343         AppendMenu(m, "\p£²ÇÜÉý¥¿¥¤¥ëɽ¼¨");
3344         #else
3345         AppendMenu(m, "\parg_sound");
3346         AppendMenu(m, "\parg_graphics");
3347         AppendMenu(m, "\p-");
3348         AppendMenu(m, "\parg_fiddle");
3349         AppendMenu(m, "\parg_wizard");
3350         AppendMenu(m, "\p-");
3351         AppendMenu(m, "\pSound config");
3352         AppendMenu(m, "\pAdam Bolt tile");
3353         AppendMenu(m, "\pBigtile Mode");
3354         #endif
3355
3356         /* Make the "TileWidth" menu */
3357         #ifdef JP
3358         m = NewMenu(135, "\p¥¿¥¤¥ëÉý");
3359         #else
3360         m = NewMenu(135, "\pTileWidth");
3361         #endif
3362
3363         /* Insert the menu */
3364         InsertMenu(m, 0);
3365
3366         /* Add some sizes */
3367         for (i = 4; i <= 32; i++)
3368         {
3369                 Str15 buf;
3370                 
3371                 /* Textual size */
3372                 sprintf((char*)buf + 1, "%d", i);
3373                 buf[0] = strlen((char*)buf + 1);
3374
3375                 /* Append item */
3376                 AppendMenu(m, buf);
3377         }
3378
3379
3380         /* Make the "TileHeight" menu */
3381         #ifdef JP
3382         m = NewMenu(136, "\p¥¿¥¤¥ë¹â");
3383         #else
3384         m = NewMenu(136, "\pTileHeight");
3385         #endif
3386
3387         /* Insert the menu */
3388         InsertMenu(m, 255);
3389
3390         /* Add some sizes */
3391         for (i = 4; i <= 32; i++)
3392         {
3393                 Str15 buf;
3394
3395                 /* Textual size */
3396                 sprintf((char*)buf + 1, "%d", i);
3397                 buf[0] = strlen((char*)buf + 1);
3398
3399                 /* Append item */
3400                 AppendMenu(m, buf);
3401         }
3402
3403
3404         /* Update the menu bar */
3405         DrawMenuBar();
3406 }
3407
3408
3409 /*
3410  * Prepare the menus
3411  */
3412 static void setup_menus(void)
3413 {
3414         int i, n;
3415
3416         short value;
3417
3418         Str255 s;
3419
3420         MenuHandle m;
3421
3422         term_data *td = NULL;
3423
3424
3425         /* Relevant "term_data" */
3426         for (i = 0; i < MAX_TERM_DATA; i++)
3427         {
3428                 /* Unused */
3429                 if (!data[i].t) continue;
3430
3431                 /* Notice the matching window */
3432                 if (data[i].w == FrontWindow()) td = &data[i];
3433         }
3434
3435
3436         /* File menu */
3437         m = GetMenuHandle(129); //m = GetMHandle(129);
3438
3439         /* Get menu size */
3440         n = CountMItems(m);
3441
3442         /* Reset menu */
3443         for (i = 1; i <= n; i++)
3444         {
3445                 /* Reset */
3446                 DisableItem(m, i);
3447                 CheckItem(m, i, FALSE);
3448         }
3449
3450         /* Enable "new"/"open..."/"import..." */
3451         if (initialized && !game_in_progress)
3452         {
3453                 EnableItem(m, 1);
3454                 EnableItem(m, 2);
3455                 EnableItem(m, 3);
3456         }
3457
3458         /* Enable "close" */
3459         if (initialized)
3460         {
3461                 EnableItem(m, 4);
3462         }
3463
3464         /* Enable "save" */
3465         if (initialized && character_generated)
3466         {
3467                 EnableItem(m, 5);
3468         }
3469
3470         /* Enable "quit" */
3471         if (TRUE)
3472         {
3473                 EnableItem(m, 7);
3474         }
3475
3476
3477         /* Edit menu */
3478         m = GetMenuHandle(130); //m = GetMHandle(130);
3479
3480         /* Get menu size */
3481         n = CountMItems(m);
3482
3483         /* Reset menu */
3484         for (i = 1; i <= n; i++)
3485         {
3486                 /* Reset */
3487                 DisableItem(m, i);
3488                 CheckItem(m, i, FALSE);
3489         }
3490
3491         /* Enable "edit" options if "needed" */
3492         if (!td)
3493         {
3494                 EnableItem(m, 1);
3495                 EnableItem(m, 3);
3496                 EnableItem(m, 4);
3497                 EnableItem(m, 5);
3498                 EnableItem(m, 6);
3499         }
3500
3501
3502         /* Font menu */
3503         m = GetMenuHandle(131); //m = GetMHandle(131);
3504
3505         /* Get menu size */
3506         n = CountMItems(m);
3507
3508         /* Reset menu */
3509         for (i = 1; i <= n; i++)
3510         {
3511                 /* Reset */
3512                 DisableItem(m, i);
3513                 CheckItem(m, i, FALSE);
3514         }
3515
3516         /* Hack -- look cute XXX XXX */
3517         /* SetItemStyle(m, 1, bold); */
3518
3519         /* Hack -- look cute XXX XXX */
3520         /* SetItemStyle(m, 2, extend); */
3521
3522         /* Active window */
3523         if (td)
3524         {
3525                 /* Enable "bold" */
3526                 EnableItem(m, 1);
3527
3528                 /* Enable "extend" */
3529                 EnableItem(m, 2);
3530
3531                 /* Check the appropriate "bold-ness" */
3532                 if (td->font_face & bold) CheckItem(m, 1, TRUE);
3533
3534                 /* Check the appropriate "wide-ness" */
3535                 if (td->font_face & extend) CheckItem(m, 2, TRUE);
3536
3537                 /* Analyze fonts */
3538                 for (i = 4; i <= n; i++)
3539                 {
3540                         /* Enable it */
3541                         EnableItem(m, i);
3542
3543                         /* Analyze font */
3544                         /* GetMenuItemText(m,i,s); */
3545                         GetMenuItemText(m, i, s);       //GetItem(m, i, s);
3546                         GetFNum(s, &value);
3547
3548                         /* Check active font */
3549                         if (td->font_id == value) CheckItem(m, i, TRUE);
3550                 }
3551         }
3552
3553
3554         /* Size menu */
3555         m = GetMenuHandle(132); //m = GetMHandle(132);
3556
3557         /* Get menu size */
3558         n = CountMItems(m);
3559
3560         /* Reset menu */
3561         for (i = 1; i <= n; i++)
3562         {
3563                 /* Reset */
3564                 DisableItem(m, i);
3565                 CheckItem(m, i, FALSE);
3566         }
3567         
3568         /* Active window */
3569         if (td)
3570         {
3571                 /* Analyze sizes */
3572                 for (i = 1; i <= n; i++)
3573                 {
3574                         /* Analyze size */
3575                         /* GetMenuItemText(m,i,s); */
3576                         GetMenuItemText(m, i, s);       //GetItem(m, i, s);
3577                         s[s[0]+1] = '\0';
3578                         value = atoi((char*)(s+1));
3579
3580                         /* Enable the "real" sizes */
3581                         if (RealFont(td->font_id, value)) EnableItem(m, i);
3582
3583                         /* Check the current size */
3584                         if (td->font_size == value) CheckItem(m, i, TRUE);
3585                 }
3586         }
3587
3588
3589         /* Windows menu */
3590         m = GetMenuHandle(133); //m = GetMHandle(133);
3591
3592         /* Get menu size */
3593         n = CountMItems(m);
3594
3595         /* Check active windows */
3596         for (i = 1; i <= n; i++)
3597         {
3598                 /* Check if needed */
3599                 CheckItem(m, i, data[i-1].mapped);
3600         }
3601
3602
3603         /* Special menu */
3604         m = GetMenuHandle(134); //m = GetMHandle(134);
3605
3606         /* Get menu size */
3607         n = CountMItems(m);
3608
3609         /* Reset menu */
3610         for (i = 1; i <= n; i++)
3611         {
3612                 /* Reset */
3613                 DisableItem(m, i);
3614                 CheckItem(m, i, FALSE);
3615         }
3616
3617         /* Item "arg_sound" */
3618         EnableItem(m, 1);
3619         CheckItem(m, 1, arg_sound);
3620
3621         /* Item "arg_graphics" */
3622         EnableItem(m, 2);
3623         CheckItem(m, 2, arg_graphics);
3624
3625         /* Item "arg_fiddle" */
3626         EnableItem(m, 4);
3627         CheckItem(m, 4, arg_fiddle);
3628
3629         /* Item "arg_wizard" */
3630         EnableItem(m, 5);
3631         CheckItem(m, 5, arg_wizard);
3632
3633         /* Item "SoundSetting" */
3634         EnableItem(m, 7);
3635
3636         /* Item NewStyle Graphics */
3637         EnableItem(m, 8);
3638         CheckItem(m, 8, use_newstyle_graphics);
3639
3640         /* Item Bigtile Mode */
3641         EnableItem(m, 9);
3642         CheckItem(m, 9, arg_bigtile);
3643
3644
3645         /* TileWidth menu */
3646         m = GetMenuHandle(135); //m = GetMHandle(135);
3647
3648         /* Get menu size */
3649         n = CountMItems(m);
3650
3651         /* Reset menu */
3652         for (i = 1; i <= n; i++)
3653         {
3654                 /* Reset */
3655                 DisableItem(m, i);
3656                 CheckItem(m, i, FALSE);
3657         }
3658
3659         /* Active window */
3660         if (td)
3661         {
3662                 /* Analyze sizes */
3663                 for (i = 1; i <= n; i++)
3664                 {
3665                         /* Analyze size */
3666                         /* GetMenuItemText(m,i,s); */
3667                         GetMenuItemText(m, i, s);       //GetItem(m, i, s);
3668                         s[s[0]+1] = '\0';
3669                         value = atoi((char*)(s+1));
3670
3671                         /* Enable */
3672                         EnableItem(m, i);
3673
3674                         /* Check the current size */
3675                         if (td->tile_wid == value) CheckItem(m, i, TRUE);
3676                 }
3677         }
3678
3679
3680         /* TileHeight menu */
3681         m = GetMenuHandle(136); //m = GetMHandle(136);
3682
3683         /* Get menu size */
3684         n = CountMItems(m);
3685
3686         /* Reset menu */
3687         for (i = 1; i <= n; i++)
3688         {
3689                 /* Reset */
3690                 DisableItem(m, i);
3691                 CheckItem(m, i, FALSE);
3692         }
3693
3694         /* Active window */
3695         if (td)
3696         {
3697                 /* Analyze sizes */
3698                 for (i = 1; i <= n; i++)
3699                 {
3700                         /* Analyze size */
3701                         /* GetMenuItemText(m,i,s); */
3702                         GetMenuItemText(m, i, s);       //GetItem(m, i, s);
3703                         s[s[0]+1] = '\0';
3704                         value = atoi((char*)(s+1));
3705
3706                         /* Enable */
3707                         EnableItem(m, i);
3708
3709                         /* Check the current size */
3710                         if (td->tile_hgt == value) CheckItem(m, i, TRUE);
3711                 }
3712         }
3713 }
3714
3715
3716 /*
3717  * Process a menu selection (see above)
3718  *
3719  * Hack -- assume that invalid menu selections are disabled above,
3720  * which I have been informed may not be reliable.  XXX XXX XXX
3721  */
3722 static void menu(long mc)
3723 {
3724         int i;
3725
3726         int menuid, selection;
3727
3728         static unsigned char s[1000];
3729
3730         short fid;
3731
3732         term_data *td = NULL;
3733
3734         WindowPtr old_win;
3735
3736
3737         /* Analyze the menu command */
3738         menuid = HiWord(mc);
3739         selection = LoWord(mc);
3740
3741
3742         /* Find the window */
3743         for (i = 0; i < MAX_TERM_DATA; i++)
3744         {
3745                 /* Skip dead windows */
3746                 if (!data[i].t) continue;
3747
3748                 /* Notice matches */
3749                 if (data[i].w == FrontWindow()) td = &data[i];
3750         }
3751
3752
3753         /* Branch on the menu */
3754         switch (menuid)
3755         {
3756                 /* Apple Menu */
3757                 case 128:
3758                 {
3759                         /* About Angband... */
3760                         if (selection == 1)
3761                         {
3762                                 DialogPtr dialog;
3763                                 Rect r;
3764                                 short item_hit;
3765
3766                                 dialog=GetNewDialog(128, 0, (WindowPtr)-1);
3767
3768                                 r=dialog->portRect;
3769                                 center_rect(&r, &qd.screenBits.bounds);
3770                                 MoveWindow(dialog, r.left, r.top, 1);
3771                                 ShowWindow(dialog);
3772                                 ModalDialog(0, &item_hit);
3773                                 DisposeDialog(dialog);          //DisposDialog(dialog);
3774                                 break;
3775                         }
3776
3777                         /* Desk accessory */
3778                         /* GetMenuItemText(GetMHandle(128),selection,s); */
3779                         GetMenuItemText(GetMenuHandle(128), selection, s);      //GetItem(GetMHandle(128), selection, s);
3780                         OpenDeskAcc(s);
3781                         break;
3782                 }
3783
3784                 /* File Menu */
3785                 case 129:
3786                 {
3787                         switch (selection)
3788                         {
3789                                 /* New */
3790                                 case 1:
3791                                 {
3792                                         do_menu_file_new();
3793                                         break;
3794                                 }
3795
3796                                 /* Open... */
3797                                 case 2:
3798                                 {
3799                                         do_menu_file_open(FALSE);
3800                                         break;
3801                                 }
3802
3803                                 /* Import... */
3804                                 case 3:
3805                                 {
3806                                         do_menu_file_open(TRUE);
3807                                         break;
3808                                 }
3809
3810                                 /* Close */
3811                                 case 4:
3812                                 {
3813                                         /* No window */
3814                                         if (!td) break;
3815
3816                                         /* Not Mapped */
3817                                         td->mapped = FALSE;
3818
3819                                         /* Not Mapped */
3820                                         td->t->mapped_flag = FALSE;
3821
3822                                         /* Hide the window */
3823                                         HideWindow(td->w);
3824
3825                                         break;
3826                                 }
3827
3828                                 /* Save */
3829                                 case 5:
3830                                 {
3831                                         if (!can_save){
3832 #ifdef JP
3833                                                 plog("º£¤Ï¥»¡¼¥Ö¤¹¤ë¤³¤È¤Ï½ÐÍè¤Þ¤»¤ó¡£");
3834 #else
3835                                                 plog("You may not do that right now.");
3836 #endif
3837                                                 break;
3838                                         }
3839                                         
3840                                         /* Hack -- Forget messages */
3841                                         msg_flag = FALSE;
3842
3843                                         /* Hack -- Save the game */
3844                                         do_cmd_save_game(FALSE);
3845
3846                                         break;
3847                                 }
3848
3849                                 /* Quit (with save) */
3850                                 case 7:
3851                                 {
3852                                         /* Save the game (if necessary) */
3853                                         if (game_in_progress && character_generated)
3854                                         {
3855                                                 if (!can_save){
3856 #ifdef JP
3857                                                         plog("º£¤Ï¥»¡¼¥Ö¤¹¤ë¤³¤È¤Ï½ÐÍè¤Þ¤»¤ó¡£");
3858 #else
3859                                                         plog("You may not do that right now.");
3860 #endif
3861                                                         break;
3862                                                 }
3863                                                 /* Hack -- Forget messages */
3864                                                 msg_flag = FALSE;
3865
3866                                                 /* Save the game */
3867 //                                              do_cmd_save_game(FALSE);
3868                                                 Term_key_push(KTRL('X'));
3869                                                 break;
3870                                         }
3871
3872                                         /* Quit */
3873                                         quit(NULL);
3874                                         break;
3875                                 }
3876                         }
3877                         break;
3878                 }
3879
3880                 /* Edit menu */
3881                 case 130:
3882                 {
3883                         /* Unused */
3884                         break;
3885                 }
3886
3887                 /* Font menu */
3888                 case 131:
3889                 {
3890                         /* Require a window */
3891                         if (!td) break;
3892
3893                         /* Memorize old */
3894                         old_win = active;
3895
3896                         /* Activate */
3897                         activate(td->w);
3898
3899                         /* Toggle the "bold" setting */
3900                         if (selection == 1)
3901                         {
3902                                 /* Toggle the setting */
3903                                 if (td->font_face & bold)
3904                                 {
3905                                         td->font_face &= ~bold;
3906                                 }
3907                                 else
3908                                 {
3909                                         td->font_face |= bold;
3910                                 }
3911
3912                                 /* Tile Width Hight Init */
3913                                 td->tile_wid = td->tile_hgt = 0;
3914
3915                                 /* Apply and Verify */
3916                                 term_data_check_font(td);
3917                                 term_data_check_size(td);
3918
3919                                 /* Resize and Redraw */
3920                                 term_data_resize(td);
3921                                 term_data_redraw(td);
3922
3923                                 break;
3924                         }
3925
3926                         /* Toggle the "wide" setting */
3927                         if (selection == 2)
3928                         {
3929                                 /* Toggle the setting */
3930                                 if (td->font_face & extend)
3931                                 {
3932                                         td->font_face &= ~extend;
3933                                 }
3934                                 else
3935                                 {
3936                                         td->font_face |= extend;
3937                                 }
3938
3939                                 /* Tile Width Hight Init */
3940                                 td->tile_wid = td->tile_hgt = 0;
3941
3942                                 /* Apply and Verify */
3943                                 term_data_check_font(td);
3944                                 term_data_check_size(td);
3945
3946                                 /* Resize and Redraw */
3947                                 term_data_resize(td);
3948                                 term_data_redraw(td);
3949
3950                                 break;
3951                         }
3952
3953                         /* Get a new font name */
3954                         /* GetMenuItemText(GetMHandle(131), selection, s); */
3955                         GetMenuItemText(GetMenuHandle(131), selection, s);              //GetItem(GetMHandle(131), selection, s);
3956                         GetFNum(s, &fid);
3957
3958                         /* Save the new font id */
3959                         td->font_id = fid;
3960
3961                         /* Current size is bad for new font */
3962                         if (!RealFont(td->font_id, td->font_size))
3963                         {
3964                                 /* Find similar size */
3965                                 for (i = 1; i <= 32; i++)
3966                                 {
3967                                         /* Adjust smaller */
3968                                         if (td->font_size - i >= 8)
3969                                         {
3970                                                 if (RealFont(td->font_id, td->font_size - i))
3971                                                 {
3972                                                         td->font_size -= i;
3973                                                         break;
3974                                                 }
3975                                         }
3976
3977                                         /* Adjust larger */
3978                                         if (td->font_size + i <= 128)
3979                                         {
3980                                                 if (RealFont(td->font_id, td->font_size + i))
3981                                                 {
3982                                                         td->font_size += i;
3983                                                         break;
3984                                                 }
3985                                         }
3986                                 }
3987                         }
3988
3989                         /* Tile Width Hight Init */
3990                         td->tile_wid = td->tile_hgt = 0;
3991
3992                         /* Apply and Verify */
3993                         term_data_check_font(td);
3994                         term_data_check_size(td);
3995
3996                         /* Resize and Redraw */
3997                         term_data_resize(td);
3998                         term_data_redraw(td);
3999
4000                         /* Restore the window */
4001                         activate(old_win);
4002
4003                         break;
4004                 }
4005
4006                 /* Size menu */
4007                 case 132:
4008                 {
4009                         if (!td) break;
4010
4011                         /* Save old */
4012                         old_win = active;
4013
4014                         /* Activate */
4015                         activate(td->w);
4016
4017                         /* GetMenuItemText(GetMHandle(132), selection, s); */
4018                         GetMenuItemText(GetMenuHandle(132), selection, s);      //GetItem(GetMHandle(132), selection, s);
4019                         s[s[0]+1]=0;
4020                         td->font_size = atoi((char*)(s+1));
4021
4022                         /* Tile Width Hight Init */
4023                         td->tile_wid = td->tile_hgt = 0;
4024
4025                         /* Apply and Verify */
4026                         term_data_check_font(td);
4027                         term_data_check_size(td);
4028
4029                         /* Resize and Redraw */
4030                         term_data_resize(td);
4031                         term_data_redraw(td);
4032
4033                         /* Restore */
4034                         activate(old_win);
4035
4036                         break;
4037                 }
4038
4039                 /* Window menu */
4040                 case 133:
4041                 {
4042                         /* Parse */
4043                         i = selection - 1;
4044
4045                         /* Check legality of choice */
4046                         if ((i < 0) || (i >= MAX_TERM_DATA)) break;
4047
4048                         /* Obtain the window */
4049                         td = &data[i];
4050
4051                         /* Mapped */
4052                         td->mapped = TRUE;
4053
4054                         /* Link */      
4055                         term_data_link(i);
4056
4057                         /* Mapped (?) */
4058                         td->t->mapped_flag = TRUE;
4059
4060                         /* Show the window */
4061                         ShowWindow(td->w);
4062
4063                         /* Bring to the front */
4064                         SelectWindow(td->w);
4065
4066                         break;
4067                 }
4068
4069                 /* Special menu */
4070                 case 134:
4071                 {
4072                         switch (selection)
4073                         {
4074                                 case 1:
4075                                 {
4076                                         /* Toggle arg_sound */
4077                                         arg_sound = !arg_sound;
4078
4079                                         /* React to changes */
4080                                         Term_xtra(TERM_XTRA_REACT, 0);
4081
4082                                         break;
4083                                 }
4084
4085                                 case 2:
4086                                 {
4087                                         /* Toggle arg_graphics */
4088                                         arg_graphics = !arg_graphics;
4089
4090                                         /* Hack -- Force redraw */
4091                                         Term_key_push(KTRL('R'));
4092
4093                                         break;
4094                                 }
4095
4096                                 case 4:
4097                                 {
4098                                         arg_fiddle = !arg_fiddle;
4099                                         break;
4100                                 }
4101
4102                                 case 5:
4103                                 {
4104                                         arg_wizard = !arg_wizard;
4105                                         break;
4106                                 }
4107
4108                                 case 7:
4109                                 {
4110                                         SoundConfigDLog();
4111                                         break;
4112                                 }
4113                                 case 8:
4114                                 {
4115                                         if (streq(ANGBAND_GRAF, "old"))
4116                                         {
4117                                                 ANGBAND_GRAF = "new";
4118                                                 arg_newstyle_graphics = true;
4119                                                 grafWidth = grafHeight = 16;
4120                                                 pictID = 1002;
4121                                         }
4122                                         else
4123                                         {
4124                                                 ANGBAND_GRAF = "old";
4125                                                 arg_newstyle_graphics = false;
4126                                                 grafWidth = grafHeight = 8;
4127                                                 pictID = 1001;
4128                                         }
4129
4130                                         /* Hack -- Force redraw */
4131                                         Term_key_push(KTRL('R'));
4132                                         break;
4133                                 }
4134
4135                                 case 9: /* bigtile mode */
4136                                 {
4137                                         term_data *td = &data[0];
4138
4139                                         if (!can_save){
4140 #ifdef JP
4141                                                 plog("º£¤ÏÊѹ¹½ÐÍè¤Þ¤»¤ó¡£");
4142 #else
4143                                                 plog("You may not do that right now.");
4144 #endif
4145                                                 break;
4146                                         }
4147
4148                                         /* Toggle "arg_bigtile" */
4149                                         arg_bigtile = !arg_bigtile;
4150
4151                                         /* Activate */
4152                                         Term_activate(td->t);
4153
4154                                         /* Resize the term */
4155                                         Term_resize(td->cols, td->rows);
4156
4157                                         break;
4158                                 }
4159
4160                         }
4161
4162                         break;
4163                 }
4164
4165                 /* TileWidth menu */
4166                 case 135:
4167                 {
4168                         if (!td) break;
4169
4170                         /* Save old */
4171                         old_win = active;
4172
4173                         /* Activate */
4174                         activate(td->w);
4175
4176                         /* GetMenuItemText(GetMHandle(135), selection, s); */
4177                         GetMenuItemText(GetMenuHandle(135), selection, s);      //GetItem(GetMHandle(135), selection, s);
4178                         s[s[0]+1]=0;
4179                         td->tile_wid = atoi((char*)(s+1));
4180
4181                         /* Apply and Verify */
4182                         term_data_check_size(td);
4183
4184                         /* Resize and Redraw */
4185                         term_data_resize(td);
4186                         term_data_redraw(td);
4187
4188                         /* Restore */
4189                         activate(old_win);
4190
4191                         break;
4192                 }
4193
4194                 /* TileHeight menu */
4195                 case 136:
4196                 {
4197                         if (!td) break;
4198
4199                         /* Save old */
4200                         old_win = active;
4201
4202                         /* Activate */
4203                         activate(td->w);
4204
4205                         /* GetMenuItemText(GetMHandle(136), selection, s); */
4206                         GetMenuItemText(GetMenuHandle(136), selection, s);      //GetItem(GetMHandle(136), selection, s);
4207                         s[s[0]+1]=0;
4208                         td->tile_hgt = atoi((char*)(s+1));
4209
4210                         /* Apply and Verify */
4211                         term_data_check_size(td);
4212
4213                         /* Resize and Redraw */
4214                         term_data_resize(td);
4215                         term_data_redraw(td);
4216
4217                         /* Restore */
4218                         activate(old_win);
4219
4220                         break;
4221                 }
4222         }
4223
4224
4225         /* Clean the menu */
4226         HiliteMenu(0);
4227 }
4228
4229
4230 #ifdef USE_SFL_CODE
4231
4232
4233 /*
4234  * Check for extra required parameters -- From "Maarten Hazewinkel"
4235  */
4236 static OSErr CheckRequiredAEParams(const AppleEvent *theAppleEvent)
4237 {
4238         OSErr   aeError;
4239         DescType        returnedType;
4240         Size    actualSize;
4241
4242         aeError = AEGetAttributePtr(theAppleEvent, keyMissedKeywordAttr, typeWildCard,
4243                                     &returnedType, NULL, 0, &actualSize);
4244
4245         if (aeError == errAEDescNotFound) return (noErr);
4246
4247         if (aeError == noErr) return (errAEParamMissed);
4248
4249         return (aeError);
4250 }
4251
4252
4253 /*
4254  * Apple Event Handler -- Open Application
4255  */
4256 static pascal OSErr AEH_Start(const AppleEvent *theAppleEvent,
4257                               const AppleEvent *reply, long handlerRefCon)
4258 {
4259 #pragma unused(reply, handlerRefCon)
4260
4261         return (CheckRequiredAEParams(theAppleEvent));
4262 }
4263
4264
4265 /*
4266  * Apple Event Handler -- Quit Application
4267  */
4268 static pascal OSErr AEH_Quit(const AppleEvent *theAppleEvent,
4269                              const AppleEvent *reply, long handlerRefCon)
4270 {
4271 #pragma unused(reply, handlerRefCon)
4272
4273         /* Quit later */
4274         quit_when_ready = TRUE;
4275
4276         /* Check arguments */
4277         return (CheckRequiredAEParams(theAppleEvent));
4278 }
4279
4280
4281 /*
4282  * Apple Event Handler -- Print Documents
4283  */
4284 static pascal OSErr AEH_Print(const AppleEvent *theAppleEvent,
4285                               const AppleEvent *reply, long handlerRefCon)
4286 {
4287 #pragma unused(theAppleEvent, reply, handlerRefCon)
4288
4289         return (errAEEventNotHandled);
4290 }
4291
4292
4293 /*
4294  * Apple Event Handler by Steve Linberg (slinberg@crocker.com).
4295  *
4296  * The old method of opening savefiles from the finder does not work
4297  * on the Power Macintosh, because CountAppFiles and GetAppFiles,
4298  * used to return information about the selected document files when
4299  * an application is launched, are part of the Segment Loader, which
4300  * is not present in the RISC OS due to the new memory architecture.
4301  *
4302  * The "correct" way to do this is with AppleEvents.  The following
4303  * code is modeled on the "Getting Files Selected from the Finder"
4304  * snippet from Think Reference 2.0.  (The prior sentence could read
4305  * "shamelessly swiped & hacked")
4306  */
4307 static pascal OSErr AEH_Open(AppleEvent *theAppleEvent,
4308                              AppleEvent* reply, long handlerRefCon)
4309 {
4310 #pragma unused(reply, handlerRefCon)
4311
4312         FSSpec          myFSS;
4313         AEDescList      docList;
4314         OSErr           err;
4315         Size            actualSize;
4316         AEKeyword       keywd;
4317         DescType        returnedType;
4318         char            foo[128];
4319         FInfo           myFileInfo;
4320
4321         /* Put the direct parameter (a descriptor list) into a docList */
4322         err = AEGetParamDesc(theAppleEvent, keyDirectObject, typeAEList, &docList);
4323         if (err) return err;
4324
4325         /*
4326          * We ignore the validity check, because we trust the FInder, and we only
4327          * allow one savefile to be opened, so we ignore the depth of the list.
4328          */
4329
4330         err = AEGetNthPtr(&docList, 1L, typeFSS, &keywd,
4331                           &returnedType, (Ptr) &myFSS, sizeof(myFSS), &actualSize);
4332         if (err) return err;
4333
4334         /* Only needed to check savefile type below */
4335         err = FSpGetFInfo(&myFSS, &myFileInfo);
4336         if (err)
4337         {
4338                 sprintf(foo, "Arg!  FSpGetFInfo failed with code %d", err);
4339                 mac_warning (foo);
4340                 return err;
4341         }
4342
4343         /* Ignore non 'SAVE' files */
4344         if (myFileInfo.fdType != 'SAVE') return noErr;
4345
4346         /* XXX XXX XXX Extract a file name */
4347         PathNameFromDirID(myFSS.parID, myFSS.vRefNum, (StringPtr)savefile);
4348         pstrcat((StringPtr)savefile, (StringPtr)&myFSS.name);
4349
4350         /* Convert the string */
4351         ptocstr((StringPtr)savefile);
4352
4353         /* Delay actual open */
4354         open_when_ready = TRUE;
4355
4356         /* Dispose */
4357         err = AEDisposeDesc(&docList);
4358
4359         /* Success */
4360         return noErr;
4361 }
4362
4363
4364 #endif
4365
4366
4367
4368 /*
4369  * Macintosh modifiers (event.modifier & ccc):
4370  *   cmdKey, optionKey, shiftKey, alphaLock, controlKey
4371  *
4372  *
4373  * Macintosh Keycodes (0-63 normal, 64-95 keypad, 96-127 extra):
4374  *
4375  * Return:36
4376  * Delete:51
4377  *
4378  * Period:65
4379  * Star:67
4380  * Plus:69
4381  * Clear:71
4382  * Slash:75
4383  * Enter:76
4384  * Minus:78
4385  * Equal:81
4386  * 0-7:82-89
4387  * 8-9:91-92
4388  *
4389  * F5: 96
4390  * F6: 97
4391  * F7: 98
4392  * F3:99
4393  * F8:100
4394  * F10:101
4395  * F11:103
4396  * F13:105
4397  * F14:107
4398  * F9:109
4399  * F12:111
4400  * F15:113
4401  * Help:114
4402  * Home:115
4403  * PgUp:116
4404  * Del:117
4405  * F4: 118
4406  * End:119
4407  * F2:120
4408  * PgDn:121
4409  * F1:122
4410  * Lt:123
4411  * Rt:124
4412  * Dn:125
4413  * Up:126
4414  */
4415
4416
4417 /*
4418  * Optimize non-blocking calls to "CheckEvents()"
4419  * Idea from "Maarten Hazewinkel <mmhazewi@cs.ruu.nl>"
4420  */
4421 #define EVENT_TICKS 6
4422
4423
4424 /*
4425  * Check for Events, return TRUE if we process any
4426  *
4427  * Hack -- Handle AppleEvents if appropriate (ignore result code).
4428  */
4429 static bool CheckEvents(bool wait)
4430 {
4431         EventRecord event;
4432
4433         WindowPtr w;
4434
4435         Rect r;
4436
4437         long newsize;
4438
4439         int ch, ck;
4440
4441         int mc, ms, mo, mx;
4442
4443         int i;
4444
4445         term_data *td = NULL;
4446
4447         huge curTicks;
4448
4449         static huge lastTicks = 0L;
4450
4451
4452         /* Access the clock */
4453         curTicks = TickCount();
4454
4455         /* Hack -- Allow efficient checking for non-pending events */
4456         if (!wait && (curTicks < lastTicks + EVENT_TICKS)) return (FALSE);
4457
4458         /* Timestamp last check */
4459         lastTicks = curTicks;
4460
4461         /* Let the "system" run */
4462         SystemTask();
4463
4464         /* Get an event (or null) */
4465         GetNextEvent(everyEvent, &event);
4466
4467         /* Hack -- Nothing is ready yet */
4468         if (event.what == nullEvent) return (FALSE);
4469
4470
4471         /* Analyze the event */
4472         switch (event.what)
4473         {
4474
4475 #if 0
4476
4477                 case activateEvt:
4478                 {
4479                         w = (WindowPtr)event.message;
4480
4481                         activate(w);
4482
4483                         break;
4484                 }
4485
4486 #endif
4487
4488                 case updateEvt:
4489                 {
4490                         /* Extract the window */
4491                         w = (WindowPtr)event.message;
4492
4493                         /* Find the window */
4494                         for (i = 0; i < MAX_TERM_DATA; i++)
4495                         {
4496                                 /* Skip dead windows */
4497                                 if (!data[i].t) continue;
4498
4499                                 /* Notice matches */
4500                                 if (data[i].w == w) td = &data[i];
4501                         }
4502
4503                         /* Hack XXX XXX XXX */
4504                         BeginUpdate(w);
4505                         EndUpdate(w);
4506
4507                         /* Redraw the window */
4508                         if (td) term_data_redraw(td);
4509
4510                         break;
4511                 }
4512
4513                 case keyDown:
4514                 case autoKey:
4515                 {
4516                         /* Extract some modifiers */
4517                         mc = (event.modifiers & controlKey) ? TRUE : FALSE;
4518                         ms = (event.modifiers & shiftKey) ? TRUE : FALSE;
4519                         mo = (event.modifiers & optionKey) ? TRUE : FALSE;
4520                         mx = (event.modifiers & cmdKey) ? TRUE : FALSE;
4521
4522                         /* Keypress: (only "valid" if ck < 96) */
4523                         ch = (event.message & charCodeMask) & 255;
4524
4525                         /* Keycode: see table above */
4526                         ck = ((event.message & keyCodeMask) >> 8) & 255;
4527
4528                         /* Command + "normal key" -> menu action */
4529                         if (mx && (ck < 64))
4530                         {
4531                                 /* Hack -- Prepare the menus */
4532                                 setup_menus();
4533
4534                                 /* Run the Menu-Handler */
4535                                 menu(MenuKey(ch));
4536
4537                                 /* Turn off the menus */
4538                                 HiliteMenu(0);
4539
4540                                 /* Done */
4541                                 break;
4542                         }
4543
4544
4545                         /* Hide the mouse pointer */
4546                         ObscureCursor();
4547
4548                         /* Normal key -> simple keypress */
4549                         if (ck < 64)
4550                         {
4551                                 /* Enqueue the keypress */
4552                                 Term_keypress(ch);
4553                         }
4554
4555                         /* Hack -- normal "keypad keys" -> special keypress */
4556                         else if (!mc && !ms && !mo && !mx && (ck < 96))
4557                         {
4558                                 /* Hack -- "enter" is confused */
4559                                 if (ck == 76) ch = '\n';
4560
4561                                 /* Send control-caret as a trigger */
4562                                 Term_keypress(30);
4563
4564                                 /* Send the "ascii" keypress */
4565                                 Term_keypress(ch);
4566                         }
4567
4568                         /* Bizarre key -> encoded keypress */
4569                         else if (ck <= 127)
4570                         {
4571                                 /* Hack -- introduce with control-underscore */
4572                                 Term_keypress(31);
4573
4574                                 /* Send some modifier keys */
4575                                 if (mc) Term_keypress('C');
4576                                 if (ms) Term_keypress('S');
4577                                 if (mo) Term_keypress('O');
4578                                 if (mx) Term_keypress('X');
4579
4580                                 /* Hack -- Downshift and encode the keycode */
4581                                 Term_keypress('0' + (ck - 64) / 10);
4582                                 Term_keypress('0' + (ck - 64) % 10);
4583
4584                                 /* Hack -- Terminate the sequence */
4585                                 /* MPW can generate 10 or 13 for keycode of '\r' */
4586                                 /* -noMapCR option swaps '\r' and '\n' */
4587                                 Term_keypress('\r');
4588                         }
4589
4590                         break;
4591                 }
4592
4593                 case mouseDown:
4594                 {
4595                         int code;
4596
4597                         /* Analyze click location */
4598                         code = FindWindow(event.where, &w);
4599
4600                         /* Find the window */
4601                         for (i = 0; i < MAX_TERM_DATA; i++)
4602                         {
4603                                 /* Skip dead windows */
4604                                 if (!data[i].t) continue;
4605
4606                                 /* Notice matches */
4607                                 if (data[i].w == w) td = &data[i];
4608                         }
4609
4610                         /* Analyze */
4611                         switch (code)
4612                         {
4613                                 case inMenuBar:
4614                                 {
4615                                         setup_menus();
4616                                         menu(MenuSelect(event.where));
4617                                         HiliteMenu(0);
4618                                         break;
4619                                 }
4620
4621                                 case inSysWindow:
4622                                 {
4623                                         SystemClick(&event, w);
4624                                         break;
4625                                 }
4626
4627                                 case inDrag:
4628                                 {
4629                                         Point p;
4630
4631                                         WindowPtr old_win;
4632
4633                                         r = qd.screenBits.bounds;
4634                                         r.top += 20; /* GetMBarHeight() XXX XXX XXX */
4635                                         InsetRect(&r, 4, 4);
4636                                         DragWindow(w, event.where, &r);
4637
4638                                         /* Oops */
4639                                         if (!td) break;
4640
4641                                         /* Save */
4642                                         old_win = active;
4643
4644                                         /* Activate */
4645                                         activate(td->w);
4646
4647                                         /* Analyze */
4648                                         p.h = td->w->portRect.left;
4649                                         p.v = td->w->portRect.top;
4650                                         LocalToGlobal(&p);
4651                                         td->r.left = p.h;
4652                                         td->r.top = p.v;
4653
4654                                         /* Restore */
4655                                         activate(old_win);
4656
4657                                         /* Apply and Verify */
4658                                         term_data_check_size(td);
4659
4660                                         break;
4661                                 }
4662
4663                                 case inGoAway:
4664                                 {
4665                                         /* Oops */
4666                                         if (!td) break;
4667
4668                                         /* Track the go-away box */
4669                                         if (TrackGoAway(w, event.where))
4670                                         {
4671                                                 /* Not Mapped */
4672                                                 td->mapped = FALSE;
4673
4674                                                 /* Not Mapped */
4675                                                 td->t->mapped_flag = FALSE;
4676
4677                                                 /* Hide the window */
4678                                                 HideWindow(td->w);
4679                                         }
4680
4681                                         break;
4682                                 }
4683
4684                                 case inGrow:
4685                                 {
4686                                         s16b x, y;
4687
4688                                         term *old = Term;
4689
4690                                         /* Oops */
4691                                         if (!td) break;
4692
4693                                         /* Fake rectangle */
4694                                         r.left = 20 * td->tile_wid + td->size_ow1;
4695                                         r.right = qd.screenBits.bounds.right;
4696                                         r.top = 1 * td->tile_hgt + td->size_oh1;
4697                                         r.bottom = qd.screenBits.bounds.bottom;
4698
4699                                         /* Grow the rectangle */
4700                                         newsize = GrowWindow(w, event.where, &r);
4701
4702                                         /* Handle abort */
4703                                         if (!newsize) break;
4704
4705                                         /* Extract the new size in pixels */
4706                                         y = HiWord(newsize) - td->size_oh1 - td->size_oh2;
4707                                         x = LoWord(newsize) - td->size_ow1 - td->size_ow2;
4708
4709                                         /* Extract a "close" approximation */
4710                                         td->rows = y / td->tile_hgt;
4711                                         td->cols = x / td->tile_wid;
4712
4713                                         /* Apply and Verify */
4714                                         term_data_check_size(td);
4715                                         /* Activate */
4716                                         Term_activate(td->t);
4717
4718                                         /* Hack -- Resize the term */
4719                                         Term_resize(td->cols, td->rows);
4720
4721                                         /* Resize and Redraw */
4722                                         term_data_resize(td);
4723                                         term_data_redraw(td);
4724
4725                                         /* Restore */
4726                                         Term_activate(old);
4727
4728                                         break;
4729                                 }
4730
4731                                 case inContent:
4732                                 {
4733                                         SelectWindow(w);
4734
4735                                         break;
4736                                 }
4737                         }
4738
4739                         break;
4740                 }
4741
4742                 /* Disk Event -- From "Maarten Hazewinkel" */
4743                 case diskEvt:
4744                 {
4745                         /* check for error when mounting the disk */
4746                         if (HiWord(event.message) != noErr)
4747                         {
4748                                 Point p =
4749                                 {120, 120};
4750
4751                                 DILoad();
4752                                 DIBadMount(p, event.message);
4753                                 DIUnload();
4754                         }
4755
4756                         break;
4757                 }
4758
4759                 /* OS Event -- From "Maarten Hazewinkel" */
4760                 case osEvt:
4761                 {
4762                         switch ((event.message >> 24) & 0x000000FF)
4763                         {
4764                                 case suspendResumeMessage:
4765
4766                                 /* Resuming: activate the front window */
4767                                 if (event.message & resumeFlag)
4768                                 {
4769                                         SetPort(FrontWindow());
4770                                         SetCursor(&qd.arrow);
4771                                 }
4772
4773                                 /* Suspend: deactivate the front window */
4774                                 else
4775                                 {
4776                                         /* Nothing */
4777                                 }
4778
4779                                 break;
4780                         }
4781
4782                         break;
4783                 }
4784
4785 #ifdef USE_SFL_CODE
4786
4787                 /* From "Steve Linberg" and "Maarten Hazewinkel" */
4788                 case kHighLevelEvent:
4789                 {
4790                         /* Process apple events */
4791                         if (AEProcessAppleEvent(&event) != noErr)
4792                         {
4793                                 #ifdef JP
4794                                 plog("Apple Event Handler¤Î¥¨¥é¡¼¤Ç¤¹.");
4795                                 #else
4796                                 plog("Error in Apple Event Handler!");
4797                                 #endif
4798                         }
4799
4800                         /* Handle "quit_when_ready" */
4801                         if (quit_when_ready)
4802                         {
4803                                 /* Forget */
4804                                 quit_when_ready = FALSE;
4805
4806                                 /* Do the menu key */
4807                                 menu(MenuKey('q'));
4808
4809                                 /* Turn off the menus */
4810                                 HiliteMenu(0);
4811                         }
4812
4813                         /* Handle "open_when_ready" */
4814                         handle_open_when_ready();
4815
4816                         break;
4817                 }
4818
4819 #endif
4820
4821         }
4822
4823
4824         /* Something happened */
4825         return (TRUE);
4826 }
4827
4828
4829
4830
4831 /*** Some Hooks for various routines ***/
4832
4833
4834 /*
4835  * Mega-Hack -- emergency lifeboat
4836  */
4837 static vptr lifeboat = NULL;
4838
4839
4840 /*
4841  * Hook to "release" memory
4842  */
4843 static vptr hook_rnfree(vptr v, huge size)
4844 {
4845
4846 #pragma unused (size)
4847
4848 #ifdef USE_MALLOC
4849
4850         /* Alternative method */
4851         free(v);
4852
4853 #else
4854
4855         /* Dispose */
4856         DisposePtr(v);
4857
4858 #endif
4859
4860         /* Success */
4861         return (NULL);
4862 }
4863
4864 /*
4865  * Hook to "allocate" memory
4866  */
4867 static vptr hook_ralloc(huge size)
4868 {
4869
4870 #ifdef USE_MALLOC
4871
4872         /* Make a new pointer */
4873         return (malloc(size));
4874
4875 #else
4876
4877         /* Make a new pointer */
4878         return (NewPtr(size));
4879
4880 #endif
4881
4882 }
4883
4884 /*
4885  * Hook to handle "out of memory" errors
4886  */
4887 static vptr hook_rpanic(huge size)
4888 {
4889
4890 #pragma unused (size)
4891
4892         vptr mem = NULL;
4893
4894         /* Free the lifeboat */
4895         if (lifeboat)
4896         {
4897                 /* Free the lifeboat */
4898                 DisposePtr(lifeboat);
4899
4900                 /* Forget the lifeboat */
4901                 lifeboat = NULL;
4902
4903                 /* Mega-Hack -- Warning */
4904                 #ifdef JP
4905                 mac_warning("¥á¥â¥ê¡¼¤¬Â­¤ê¤Þ¤»¤ó!\rº£¤¹¤°½ªÎ»¤·¤Æ²¼¤µ¤¤!");
4906                 #else
4907                 mac_warning("Running out of Memory!\rAbort this process now!");
4908                 #endif
4909
4910                 /* Mega-Hack -- Never leave this function */
4911                 while (TRUE) CheckEvents(TRUE);
4912         }
4913
4914         /* Mega-Hack -- Crash */
4915         return (NULL);
4916 }
4917
4918
4919 /*
4920  * Hook to tell the user something important
4921  */
4922 static void hook_plog(cptr str)
4923 {
4924         /* Warning message */
4925         mac_warning(str);
4926 }
4927
4928 /*
4929  * Hook to tell the user something, and then quit
4930  */
4931 static void hook_quit(cptr str)
4932 {
4933         /* Warning if needed */
4934         if (str) mac_warning(str);
4935
4936         /* Write a preference file */
4937         save_pref_file();
4938
4939         /* All done */
4940         ExitToShell();
4941 }
4942
4943 /*
4944  * Hook to tell the user something, and then crash
4945  */
4946 static void hook_core(cptr str)
4947 {
4948         /* XXX Use the debugger */
4949         /* DebugStr(str); */
4950
4951         /* Warning */
4952         if (str) mac_warning(str);
4953
4954         /* Warn, then save player */
4955         #ifdef JP
4956         mac_warning("Ã×̿Ū¤Ê¥¨¥é¡¼¤Ç¤¹.\r¶¯À©Åª¤Ë¥»¡¼¥Ö¤·¤Æ½ªÎ»¤·¤Þ¤¹.");
4957         #else
4958         mac_warning("Fatal error.\rI will now attempt to save and quit.");
4959         #endif
4960
4961         /* Attempt to save */
4962         #ifdef JP
4963         if (!save_player()) mac_warning("·Ù¹ð -- ¥»¡¼¥Ö¤Ë¼ºÇÔ¤·¤Þ¤·¤¿!");
4964         #else
4965         if (!save_player()) mac_warning("Warning -- save failed!");
4966         #endif
4967         
4968         /* Quit */
4969         quit(NULL);
4970 }
4971
4972
4973
4974 /*** Main program ***/
4975
4976
4977 /*
4978  * Init some stuff
4979  *
4980  * XXX XXX XXX Hack -- This function attempts to "fix" the nasty
4981  * "Macintosh Save Bug" by using "absolute" path names, since on
4982  * System 7 machines anyway, the "current working directory" often
4983  * "changes" due to background processes, invalidating any "relative"
4984  * path names.  Note that the Macintosh is limited to 255 character
4985  * path names, so be careful about deeply embedded directories...
4986  *
4987  * XXX XXX XXX Hack -- This function attempts to "fix" the nasty
4988  * "missing lib folder bug" by allowing the user to help find the
4989  * "lib" folder by hand if the "application folder" code fails...
4990  */
4991 static void init_stuff(void)
4992 {
4993         int i;
4994
4995         short vrefnum;
4996         long drefnum;
4997         long junk;
4998
4999         SFTypeList types;
5000         SFReply reply;
5001
5002         Rect r;
5003         Point topleft;
5004
5005         char path[1024];
5006
5007
5008         /* Fake rectangle */
5009         r.left = 0;
5010         r.top = 0;
5011         r.right = 344;
5012         r.bottom = 188;
5013
5014         /* Center it */
5015         center_rect(&r, &qd.screenBits.bounds);
5016
5017         /* Extract corner */
5018         topleft.v = r.top;
5019         topleft.h = r.left;
5020
5021
5022         /* Default to the "lib" folder with the application */
5023         refnum_to_name(path, app_dir, app_vol, (char*)("\plib:"));
5024
5025
5026         /* Check until done */
5027         while (1)
5028         {
5029                 /* Prepare the paths */
5030                 init_file_paths(path);
5031
5032                 /* Build the filename */
5033                 #ifdef JP
5034                         path_build(path, 1024, ANGBAND_DIR_FILE, "news_j.txt");
5035                 #else
5036                         path_build(path, 1024, ANGBAND_DIR_FILE, "news.txt");
5037                 #endif
5038
5039                 /* Attempt to open and close that file */
5040                 if (0 == fd_close(fd_open(path, O_RDONLY))) break;
5041
5042                 /* Warning */
5043                 #ifdef JP
5044                         plog_fmt("'%s' ¥Õ¥¡¥¤¥ë¤ò¥ª¡¼¥×¥ó½ÐÍè¤Þ¤»¤ó.", path);
5045                 #else
5046                         plog_fmt("Unable to open the '%s' file.", path);
5047                 #endif
5048
5049                 /* Warning */
5050                 #ifdef JP
5051                         plog("Hengband¤Î'lib'¥Õ¥©¥ë¥À¤¬Â¸ºß¤·¤Ê¤¤¤«Àµ¤·¤¯Ìµ¤¤²ÄǽÀ­¤¬¤¢¤ê¤Þ¤¹.");
5052                 #else
5053                         plog("The Angband 'lib' folder is probably missing or misplaced.");
5054                 #endif
5055
5056                 /* Warning */
5057                 plog("Please 'open' any file in any sub-folder of the 'lib' folder.");
5058
5059                 /* Allow "text" files */
5060                 types[0] = 'TEXT';
5061
5062                 /* Allow "save" files */
5063                 types[1] = 'SAVE';
5064
5065                 /* Allow "data" files */
5066                 types[2] = 'DATA';
5067
5068                 /* Get any file */
5069                 SFGetFile(topleft, "\p", NULL, 3, types, NULL, &reply);
5070
5071                 /* Allow cancel */
5072                 if (!reply.good) quit(NULL);
5073
5074                 /* Extract textual file name for given file */
5075                 GetWDInfo(reply.vRefNum, &vrefnum, &drefnum, &junk);
5076                 refnum_to_name(path, drefnum, vrefnum, (char*)reply.fName);
5077
5078                 /* Hack -- Remove the "filename" */
5079                 i = strlen(path) - 1;
5080                 while ((i > 0) && (path[i] != ':')) i--;
5081                 if (path[i] == ':') path[i+1] = '\0';
5082
5083                 /* Hack -- allow "lib" folders */
5084                 if (suffix(path, "lib:")) continue;
5085
5086                 /* Hack -- Remove the "sub-folder" */
5087                 i = i - 1;
5088                 while ((i > 1) && (path[i] != ':')) i--;
5089                 if (path[i] == ':') path[i+1] = '\0';
5090         }
5091 }
5092
5093
5094 /*
5095  * Macintosh Main loop
5096  */
5097 void main(void)
5098 {
5099         EventRecord tempEvent;
5100         int numberOfMasters = 10;
5101
5102         /* Increase stack space by 64K */
5103         SetApplLimit(GetApplLimit() - 131072L);//65536L);
5104
5105         /* Stretch out the heap to full size */
5106         MaxApplZone();
5107
5108         /* Get more Masters */
5109         while (numberOfMasters--) MoreMasters();
5110
5111         /* Set up the Macintosh */
5112         InitGraf(&qd.thePort);
5113         InitFonts();
5114         InitWindows();
5115         InitMenus();
5116         /* TEInit(); */
5117         InitDialogs(NULL);
5118         InitCursor();
5119
5120 #ifdef JP
5121         KeyScript(smRoman);
5122 #endif
5123
5124         /* Flush events */
5125         FlushEvents(everyEvent, 0);
5126
5127         /* Flush events some more (?) */
5128         (void)EventAvail(everyEvent, &tempEvent);
5129         (void)EventAvail(everyEvent, &tempEvent);
5130         (void)EventAvail(everyEvent, &tempEvent);
5131
5132
5133 #ifdef ANGBAND_LITE_MAC
5134
5135         /* Nothing */
5136
5137 #else /* ANGBAND_LITE_MAC */
5138
5139 # if defined(powerc) || defined(__powerc)
5140
5141         /* Assume System 7 */
5142         
5143         /* Assume Color Quickdraw */
5144
5145 # else
5146
5147         /* Block */
5148         if (TRUE)
5149         {
5150                 OSErr err;
5151                 long versionNumber;
5152
5153                 /* Check the Gestalt */
5154                 err = Gestalt(gestaltSystemVersion, &versionNumber);
5155
5156                 /* Check the version */
5157                 if ((err != noErr) || (versionNumber < 0x0700))
5158                 {
5159                         #ifdef JP
5160                         quit("¤³¤Î¥×¥í¥°¥é¥à¤Ï´Á»úTalk7.x.x°Ê¹ß¤ÇÆ°ºî¤·¤Þ¤¹.");
5161                         #else
5162                         quit("You must have System 7 to use this program.");
5163                         #endif
5164                 }
5165         }
5166
5167         /* Block */
5168         if (TRUE)
5169         {
5170                 SysEnvRec env;
5171
5172                 /* Check the environs */
5173                 if (SysEnvirons(1, &env) != noErr)
5174                 {
5175                         #ifdef JP
5176                         quit("SysEnvirons ¥³¡¼¥ë¤Ï¼ºÇÔ¤·¤Þ¤·¤¿¡ª");
5177                         #else
5178                         quit("The SysEnvirons call failed!");
5179                         #endif
5180                 }
5181
5182                 /* Check for System Seven Stuff */
5183                 if (env.systemVersion < 0x0700)
5184                 {
5185                         #ifdef JP
5186                         quit("¤³¤Î¥×¥í¥°¥é¥à¤Ï´Á»úTalk7.x.x°Ê¹ß¤ÇÆ°ºî¤·¤Þ¤¹.");
5187                         #else
5188                         quit("You must have System 7 to use this program.");
5189                         #endif
5190                 }
5191
5192                 /* Check for Color Quickdraw */
5193                 if (!env.hasColorQD)
5194                 {
5195                         #ifdef JP
5196                         quit("¤³¤Î¥×¥í¥°¥é¥à¤ÏColor Quickdraw¤¬Ìµ¤¤¤ÈÆ°ºî¤·¤Þ¤»¤ó.");
5197                         #else
5198                         quit("You must have Color Quickdraw to use this program.");
5199                         #endif
5200                 }
5201         }
5202
5203 # endif
5204
5205 #endif /* ANGBAND_LITE_MAC */
5206
5207
5208 #ifdef USE_SFL_CODE
5209
5210         /* Obtain a "Universal Procedure Pointer" */
5211         AEH_Start_UPP = NewAEEventHandlerProc(AEH_Start);
5212
5213         /* Install the hook (ignore error codes) */
5214         AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, AEH_Start_UPP,
5215                               0L, FALSE);
5216
5217         /* Obtain a "Universal Procedure Pointer" */
5218         AEH_Quit_UPP = NewAEEventHandlerProc(AEH_Quit);
5219
5220         /* Install the hook (ignore error codes) */
5221         AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, AEH_Quit_UPP,
5222                               0L, FALSE);
5223
5224         /* Obtain a "Universal Procedure Pointer" */
5225         AEH_Print_UPP = NewAEEventHandlerProc(AEH_Print);
5226
5227         /* Install the hook (ignore error codes) */
5228         AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments, AEH_Print_UPP,
5229                               0L, FALSE);
5230
5231         /* Obtain a "Universal Procedure Pointer" */
5232         AEH_Open_UPP = NewAEEventHandlerProc(AEH_Open);
5233
5234         /* Install the hook (ignore error codes) */
5235         AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, AEH_Open_UPP,
5236                               0L, FALSE);
5237
5238 #endif
5239
5240
5241         /* Find the current application */
5242         SetupAppDir();
5243
5244
5245         /* Mark ourself as the file creator */
5246         _fcreator = 'Heng';
5247
5248         /* Default to saving a "text" file */
5249         _ftype = 'TEXT';
5250
5251
5252 #if defined(__MWERKS__)
5253
5254         /* Obtian a "Universal Procedure Pointer" */
5255         ynfilterUPP = NewModalFilterProc(ynfilter);
5256
5257 #endif
5258
5259
5260         /* Hook in some "z-virt.c" hooks */
5261         rnfree_aux = hook_rnfree;
5262         ralloc_aux = hook_ralloc;
5263         rpanic_aux = hook_rpanic;
5264
5265         /* Hooks in some "z-util.c" hooks */
5266         plog_aux = hook_plog;
5267         quit_aux = hook_quit;
5268         core_aux = hook_core;
5269
5270 BackColor(blackColor);
5271                 ForeColor(whiteColor);
5272
5273         /* Show the "watch" cursor */
5274         SetCursor(*(GetCursor(watchCursor)));
5275
5276         /* Prepare the menubar */
5277         init_menubar();
5278
5279         /* Prepare the windows */
5280         init_windows();
5281
5282         init_sound();
5283
5284         /* Hack -- process all events */
5285         while (CheckEvents(TRUE)) /* loop */;
5286
5287         /* Reset the cursor */
5288         SetCursor(&qd.arrow);
5289
5290
5291         /* Mega-Hack -- Allocate a "lifeboat" */
5292         lifeboat = NewPtr(16384);
5293
5294         /* Note the "system" */
5295         ANGBAND_SYS = "mac";
5296
5297         /* Initialize */
5298         init_stuff();
5299
5300         /* Initialize */
5301         init_angband();
5302
5303
5304         /* Hack -- process all events */
5305         while (CheckEvents(TRUE)) /* loop */;
5306
5307
5308         /* We are now initialized */
5309         initialized = TRUE;
5310
5311
5312         /* Handle "open_when_ready" */
5313         handle_open_when_ready();
5314
5315 #ifdef CHUUKEI
5316         init_chuukei();
5317 #endif
5318
5319         /* Prompt the user */
5320         #ifdef JP
5321         prt("'¥Õ¥¡¥¤¥ë'¥á¥Ë¥å¡¼¤è¤ê'¿·µ¬'¤Þ¤¿¤Ï'³«¤¯...'¤òÁªÂò¤·¤Æ¤¯¤À¤µ¤¤¡£", 23, 10);
5322         #else
5323         prt("[Choose 'New' or 'Open' from the 'File' menu]", 23, 15);
5324         #endif
5325
5326         /* Flush the prompt */
5327         Term_fresh();
5328
5329
5330         /* Hack -- Process Events Forever */
5331         while (TRUE) CheckEvents(TRUE);
5332 }
5333