OSDN Git Service

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