OSDN Git Service

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