OSDN Git Service

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