3 /* Purpose: Simple support for MACINTOSH Angband */
6 * This file should only be compiled with the "Macintosh" version
8 * This file written by "Ben Harrison (benh@phial.com)".
10 * Some code adapted from "MacAngband 2.6.1" by Keith Randall
12 * Maarten Hazewinkel (mmhazewi@cs.ruu.nl) provided some initial
13 * suggestions for the PowerMac port.
15 * Steve Linberg (slinberg@crocker.com) provided the code surrounded
18 * The graphics code is adapted from an extremely minimal subset of
19 * the code from "Sprite World II", an amazing animation package.
21 * See "z-term.c" for info on the concept of the "generic terminal"
23 * The preference file is now a text file named "Angband preferences".
25 * Note that the "preference" file is now a simple text file called
26 * "Angband preferences", which contains the versions information, so
27 * that obsolete preference files can be ignored (this may be bad).
29 * Note that "init1.c", "init2.c", "load1.c", "load2.c", and "birth.c"
30 * should probably be "unloaded" as soon as they are no longer needed,
31 * to save space, but I do not know how to do this.
33 * Stange bug -- The first "ClipRect()" call crashes if the user closes
34 * all the windows, switches to another application, switches back, and
35 * then re-opens the main window, for example, using "command-a".
37 * By default, this file assumes that you will be using a 68020 or better
38 * machine, running System 7 and Color Quickdraw. In fact, the game will
39 * refuse to run unless these features are available. This allows the use
40 * of a variety of interesting features such as graphics and sound.
42 * To create a version which can be used on 68000 machines, or on machines
43 * which are not running System 7 or Color Quickdraw, simply activate the
44 * "ANGBAND_LITE_MAC" compilation flag in the proper header file. This
45 * will disable all "modern" features used in this file, including support
46 * for multiple sub-windows, color, graphics, and sound.
48 * When compiling with the "ANGBAND_LITE_MAC" flag, the "ANGBAND_LITE"
49 * flag will be automatically defined, which will disable many of the
50 * advanced features of the game itself, reducing the total memory usage.
52 * If you are never going to use "graphics" (especially if you are not
53 * compiling support for graphics anyway) then you can delete the "pict"
54 * resource with id "1001" with no dangerous side effects.
59 * Important Resources in the resource file:
61 * FREF 130 = 'A271' / 'APPL' (application)
62 * FREF 129 = 'A271' / 'SAVE' (save file)
63 * FREF 130 = 'A271' / 'TEXT' (bone file, generic text file)
64 * FREF 131 = 'A271' / 'DATA' (binary image file, score file)
66 * DLOG 128 = "About Angband..."
68 * ALRT 128 = unused (?)
69 * ALRT 129 = "Warning..."
70 * ALRT 130 = "Are you sure you want to quit without saving?"
72 * DITL 128 = body for DLOG 128
73 * DITL 129 = body for ALRT 129
74 * DITL 130 = body for ALRT 130
76 * ICON 128 = "warning" icon
78 * MENU 128 = apple (about, -, ...)
79 * MENU 129 = File (new, open, close, save, -, exit, quit)
80 * MENU 130 = Edit (undo, -, cut, copy, paste, clear)
82 * PICT 1001 = Graphics tile set
88 * all 'APEX' files have a filename of the form "*:apex:*" (?)
89 * all 'BONE' files have a filename of the form "*:bone:*" (?)
90 * all 'DATA' files have a filename of the form "*:data:*"
91 * all 'SAVE' files have a filename of the form "*:save:*"
92 * all 'USER' files have a filename of the form "*:user:*" (?)
94 * Perhaps we should attempt to set the "_ftype" flag inside this file,
95 * to avoid nasty file type information being spread all through the
96 * rest of the code. (?) This might require adding hooks into the
97 * "fd_open()" and "my_fopen()" functions in "util.c". XXX XXX XXX
102 * Reasons for each header file:
104 * angband.h = Angband header file
106 * Types.h = (included anyway)
107 * Gestalt.h = gestalt code
108 * QuickDraw.h = (included anyway)
109 * OSUtils.h = (included anyway)
110 * Files.h = file code
111 * Fonts.h = font code
112 * Menus.h = menu code
113 * Dialogs.h = dialog code
114 * Windows.h = (included anyway)
115 * Palettes.h = palette code
116 * StandardFile.h = file dialog box
117 * DiskInit.h = disk initialization
118 * ToolUtils.h = HiWord() / LoWord()
119 * Desk.h = OpenDeskAcc()
120 * Devices.h = OpenDeskAcc()
121 * Events.h = event code
122 * Resources.h = resource code
123 * Controls.h = button code
124 * SegLoad.h = ExitToShell(), AppFile, etc
125 * Memory.h = SetApplLimit(), NewPtr(), etc
126 * QDOffscreen.h = GWorld code
127 * Sound.h = Sound code
129 * For backwards compatibility:
130 * Use GestaltEqu.h instead of Gestalt.h
131 * Add Desk.h to include simply includes Menus.h, Devices.h, Events.h
139 #include <QuickDraw.h>
145 #include <Palettes.h>
146 #include <StandardFile.h>
147 #include <DiskInit.h>
148 #include <ToolUtils.h>
151 #include <Resources.h>
152 #include <Controls.h>
155 #include <QDOffscreen.h>
165 * Use "malloc()" instead of "NewPtr()"
167 /* #define USE_MALLOC */
170 #if defined(powerc) || defined(__powerc)
173 * Disable "LITE" version
175 # undef ANGBAND_LITE_MAC
180 #ifdef ANGBAND_LITE_MAC
183 * Maximum number of windows
185 # define MAX_TERM_DATA 1
187 #else /* ANGBAND_LITE_MAC */
190 * Maximum number of windows
192 # define MAX_TERM_DATA 8
195 * Activate some special code
197 # define USE_SFL_CODE
199 #endif /* ANGBAND_LITE_MAC */
206 * Include the necessary header files
208 #include <AppleEvents.h>
216 * Globals for MPW compilation
230 * The Angband Color Set (0 to 15):
231 * Black, White, Slate, Orange, Red, Blue, Green, Umber
232 * D-Gray, L-Gray, Violet, Yellow, L-Red, L-Blue, L-Green, L-Umber
234 * Colors 8 to 15 are basically "enhanced" versions of Colors 0 to 7.
236 * On the Macintosh, we use color quickdraw, and we use actual "RGB"
237 * values below to choose the 16 colors.
239 * If we are compiled for ancient machines, we bypass color and simply
240 * draw everything in white (letting "z-term.c" automatically convert
241 * "black" into "wipe" calls).
243 static RGBColor foo[16] =
245 {0x0000, 0x0000, 0x0000}, /* TERM_DARK */
246 {0xFFFF, 0xFFFF, 0xFFFF}, /* TERM_WHITE */
247 {0x8080, 0x8080, 0x8080}, /* TERM_SLATE */
248 {0xFFFF, 0x8080, 0x0000}, /* TERM_ORANGE */
249 {0xC0C0, 0x0000, 0x0000}, /* TERM_RED */
250 {0x0000, 0x8080, 0x4040}, /* TERM_GREEN */
251 {0x0000, 0x0000, 0xFFFF}, /* TERM_BLUE */
252 {0x8080, 0x4040, 0x0000}, /* TERM_UMBER */
253 {0x4040, 0x4040, 0x4040}, /* TERM_L_DARK */
254 {0xC0C0, 0xC0C0, 0xC0C0}, /* TERM_L_WHITE */
255 {0xFFFF, 0x0000, 0xFFFF}, /* TERM_VIOLET */
256 {0xFFFF, 0xFFFF, 0x0000}, /* TERM_YELLOW */
257 {0xFFFF, 0x0000, 0x0000}, /* TERM_L_RED */
258 {0x0000, 0xFFFF, 0x0000}, /* TERM_L_GREEN */
259 {0x0000, 0xFFFF, 0xFFFF}, /* TERM_L_BLUE */
260 {0xC0C0, 0x8080, 0x4040} /* TERM_L_UMBER */
269 typedef struct term_data term_data;
282 #ifdef ANGBAND_LITE_MAC
286 #else /* ANGBAND_LITE_MAC */
298 #endif /* ANGBAND_LITE_MAC */
301 GWorldPtr bufferPort;
302 PixMapHandle bufferPixHndl;
347 * Forward declare -- see below
349 static bool CheckEvents(bool wait);
353 * Hack -- location of the main directory
355 static short app_vol;
360 * Delay handling of double-clicked savefiles
362 Boolean open_when_ready = FALSE;
365 * Delay handling of pre-emptive "quit" event
367 Boolean quit_when_ready = FALSE;
371 * Hack -- game in progress
373 static int game_in_progress = 0;
377 * Only do "SetPort()" when needed
379 static WindowPtr active = NULL;
384 * An array of term_data's
386 static term_data data[MAX_TERM_DATA];
391 * Note when "open"/"new" become valid
393 static bool initialized = FALSE;
398 * CodeWarrior uses Universal Procedure Pointers
400 static ModalFilterUPP ynfilterUPP;
407 AEEventHandlerUPP AEH_Start_UPP;
408 AEEventHandlerUPP AEH_Quit_UPP;
409 AEEventHandlerUPP AEH_Print_UPP;
410 AEEventHandlerUPP AEH_Open_UPP;
418 static int ext_sound = 0;
426 #define SND_CMD_ERROR 6
428 static int soundchoice[] = {
496 static int soundmode[8];
503 * Convert refnum+vrefnum+fname into a full file name
504 * Store this filename in 'buf' (make sure it is long enough)
505 * Note that 'fname' looks to be a "pascal" string
507 static void refnum_to_name(char *buf, long refnum, short vrefnum, char *fname)
519 for (j=1; j<=fname[0]; j++)
521 res[i-fname[0]+j] = fname[j];
525 pb.ioCompletion=NULL;
527 pb.ioVRefNum=vrefnum;
533 pb.ioDrDirID=pb.ioDrParID;
534 err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
536 for (j=1; j<=name[0]; j++)
538 res[i-name[0]+j] = name[j];
542 if (pb.ioDrDirID == fsRtDirID) break;
545 /* Extract the result */
546 for (j = 0, i++; res[i]; j++, i++) buf[j] = res[i];
554 * XXX XXX XXX Allow the system to ask us for a filename
556 static bool askfor_file(char *buf, int len)
564 /* Default file name */
565 sprintf((char*)dflt + 1, "%s's description", buf);
566 dflt[0] = strlen((char*)dflt + 1);
568 /* Ask for a file name */
569 topleft.h=(qd.screenBits.bounds.left+qd.screenBits.bounds.right)/2-344/2;
570 topleft.v=(2*qd.screenBits.bounds.top+qd.screenBits.bounds.bottom)/3-188/2;
571 SFPutFile(topleft, "\pSelect a filename:", dflt, NULL, &reply);
572 /* StandardPutFile("\pSelect a filename:", dflt, &reply); */
580 GetWDInfo(reply.vRefNum, &vrefnum, &drefnum, &junk);
582 /* Extract the name */
583 refnum_to_name(buf, drefnum, vrefnum, (char*)reply.fName);
598 * Center a rectangle inside another rectangle
600 static void center_rect(Rect *r, Rect *s)
602 int centerx = (s->left + s->right)/2;
603 int centery = (2*s->top + s->bottom)/3;
604 int dx = centerx - (r->right - r->left)/2 - r->left;
605 int dy = centery - (r->bottom - r->top)/2 - r->top;
614 * Convert a pascal string in place
616 * This function may be defined elsewhere, but since it is so
617 * small, it is not worth finding the proper function name for
618 * all the different platforms.
620 static void ptocstr(StringPtr src)
624 /* Hack -- pointer */
625 char *s = (char*)(src);
627 /* Hack -- convert the string */
628 for (i = s[0]; i; i--, s++) s[0] = s[1];
630 /* Hack -- terminate the string */
635 #if defined(USE_SFL_CODE)
639 * The following three routines (pstrcat, pstrinsert, and PathNameFromDirID)
640 * were taken from the Think Reference section called "Getting a Full Pathname"
641 * (under the File Manager section). We need PathNameFromDirID to get the
642 * full pathname of the opened savefile, making no assumptions about where it
645 * I had to hack PathNameFromDirID a little for MetroWerks, but it's awfully
648 static void pstrcat(StringPtr dst, StringPtr src)
651 BlockMove(src + 1, dst + *dst + 1, *src);
653 /* adjust length byte */
658 * pstrinsert - insert string 'src' at beginning of string 'dst'
660 static void pstrinsert(StringPtr dst, StringPtr src)
662 /* make room for new string */
663 BlockMove(dst + 1, dst + *src + 1, *dst);
665 /* copy new string in */
666 BlockMove(src + 1, dst + 1, *src);
668 /* adjust length byte */
672 static void PathNameFromDirID(long dirID, short vRefNum, StringPtr fullPathName)
675 Str255 directoryName;
678 fullPathName[0] = '\0';
680 block.dirInfo.ioDrParID = dirID;
681 block.dirInfo.ioNamePtr = directoryName;
685 block.dirInfo.ioVRefNum = vRefNum;
686 block.dirInfo.ioFDirIndex = -1;
687 block.dirInfo.ioDrDirID = block.dirInfo.ioDrParID;
688 err = PBGetCatInfo(&block, FALSE);
689 pstrcat(directoryName, (StringPtr)"\p:");
690 pstrinsert(fullPathName, directoryName);
691 if (block.dirInfo.ioDrDirID == 2) break;
700 * Activate a given window, if necessary
702 static void activate(WindowPtr w)
717 * Display a warning message
719 static void mac_warning(cptr warning)
724 /* Limit of 250 chars */
725 len = strlen(warning);
726 if (len > 250) len = 250;
728 /* Make a "Pascal" string */
730 for (i=0; i<len; i++) text[i+1] = warning[i];
732 /* Prepare the dialog box values */
733 ParamText(text, "\p", "\p", "\p");
735 /* Display the Alert, wait for Okay */
741 /*** Some generic functions ***/
744 #ifdef ANGBAND_LITE_MAC
747 * Hack -- activate a color (0 to 255)
749 #define term_data_color(TD,A) /* Nothing */
751 #else /* ANGBAND_LITE_MAC */
754 * Hack -- activate a color (0 to 255)
756 static void term_data_color(term_data *td, int a)
763 /* Extract the R,G,B data */
764 rv = angband_color_table[a][1];
765 gv = angband_color_table[a][2];
766 bv = angband_color_table[a][3];
769 color.red = (rv | (rv << 8));
770 color.green = (gv | (gv << 8));
771 color.blue = (bv | (bv << 8));
773 /* Activate the color */
774 RGBForeColor(&color);
779 /* Activate the color */
786 /* Extract the R,G,B data */
787 rv = angband_color_table[a][1];
788 gv = angband_color_table[a][2];
789 bv = angband_color_table[a][3];
792 color.red = (rv | (rv << 8));
793 color.green = (gv | (gv << 8));
794 color.blue = (bv | (bv << 8));
796 /* Activate the color */
797 RGBForeColor(&color);
805 #endif /* ANGBAND_LITE_MAC */
809 * Hack -- Apply and Verify the "font" info
811 * This should usually be followed by "term_data_check_size()"
813 static void term_data_check_font(term_data *td)
819 WindowPtr old = active;
825 /* Instantiate font */
826 TextFont(td->font_id);
827 TextSize(td->font_size);
828 TextFace(td->font_face);
830 /* Extract the font info */
833 /* Assume monospaced */
834 td->font_mono = TRUE;
836 /* Extract the font sizing values XXX XXX XXX */
837 td->font_wid = CharWidth('@'); /* info.widMax; */
838 td->font_hgt = info.ascent + info.descent;
840 td->font_o_y = info.ascent;
842 /* Check important characters */
843 for (i = 33; i < 127; i++)
845 /* Hack -- notice non-mono-space */
846 if (td->font_wid != CharWidth(i)) td->font_mono = FALSE;
848 /* Hack -- collect largest width */
849 if (td->font_wid < CharWidth(i)) td->font_wid = CharWidth(i);
852 /* Set default offsets */
853 td->tile_o_x = td->font_o_x;
854 td->tile_o_y = td->font_o_y;
856 /* Set default tile size */
858 if( td->tile_wid == 0 && td->tile_hgt == 0 ){
859 td->tile_wid = td->font_wid;
860 td->tile_hgt = td->font_hgt;
863 td->tile_wid = td->font_wid;
864 td->tile_hgt = td->font_hgt;
867 /* Re-activate the old window */
873 * Hack -- Apply and Verify the "size" info
875 static void term_data_check_size(term_data *td)
877 /* Minimal window size */
878 if (td->cols < 1) td->cols = 1;
879 if (td->rows < 1) td->rows = 1;
881 /* Minimal tile size */
882 if (td->tile_wid < 4) td->tile_wid = 4;
883 if (td->tile_hgt < 4) td->tile_hgt = 4;
885 /* Default tile offsets */
886 td->tile_o_x = (td->tile_wid - td->font_wid) / 2;
887 td->tile_o_y = (td->tile_hgt - td->font_hgt) / 2;
889 /* Minimal tile offsets */
890 if (td->tile_o_x < 0) td->tile_o_x = 0;
891 if (td->tile_o_y < 0) td->tile_o_y = 0;
893 /* Apply font offsets */
894 td->tile_o_x += td->font_o_x;
895 td->tile_o_y += td->font_o_y;
897 /* Calculate full window size */
898 td->size_wid = td->cols * td->tile_wid + td->size_ow1 + td->size_ow2;
899 td->size_hgt = td->rows * td->tile_hgt + td->size_oh1 + td->size_oh2;
902 if (td->r.top > qd.screenBits.bounds.bottom - td->size_hgt)
904 td->r.top = qd.screenBits.bounds.bottom - td->size_hgt;
908 if (td->r.top < qd.screenBits.bounds.top + 30)
910 td->r.top = qd.screenBits.bounds.top + 30;
913 /* Verify the left */
914 if (td->r.left > qd.screenBits.bounds.right - td->size_wid)
916 td->r.left = qd.screenBits.bounds.right - td->size_wid;
919 /* Verify the left */
920 if (td->r.left < qd.screenBits.bounds.left)
922 td->r.left = qd.screenBits.bounds.left;
925 /* Calculate bottom right corner */
926 td->r.right = td->r.left + td->size_wid;
927 td->r.bottom = td->r.top + td->size_hgt;
929 /* Assume no graphics */
930 td->t->always_pict = FALSE;
932 #ifdef ANGBAND_LITE_MAC
936 #else /* ANGBAND_LITE_MAC */
938 /* Handle graphics */
939 if (use_graphics && (td == &data[0]))
941 td->t->always_pict = TRUE;
944 #endif /* ANGBAND_LITE_MAC */
946 /* Fake mono-space */
947 if (!td->font_mono ||
948 (td->font_wid != td->tile_wid) ||
949 (td->font_hgt != td->tile_hgt))
951 /* Handle fake monospace */
952 td->t->always_pict = TRUE;
956 static OSErr XDDSWUpDateGWorldFromPict( term_data *td );
958 * Hack -- resize a term_data
960 * This should normally be followed by "term_data_resize()"
962 static void term_data_resize(term_data *td)
964 /* Actually resize the window */
965 SizeWindow(td->w, td->size_wid, td->size_hgt, 0);
968 XDDSWUpDateGWorldFromPict( td );
975 * Hack -- redraw a term_data
977 * Note that "Term_redraw()" calls "TERM_XTRA_CLEAR"
979 static void term_data_redraw(term_data *td)
983 /* Activate the term */
984 Term_activate(td->t);
986 /* Redraw the contents */
989 /* Flush the output */
992 /* Restore the old term */
995 /* No need to redraw */
996 ValidRect(&td->w->portRect);
1002 #ifdef ANGBAND_LITE_MAC
1006 #else /* ANGBAND_LITE_MAC */
1013 #define kPictID 1002 /* Graf 'pict' resource */
1015 #define kGrafWidth 16 /* Graf Size (X) */
1016 #define kGrafHeight 16 /* Graf Size (Y) */
1018 #define kPictCols 32 /* Number of Cols in Pict */
1019 #define kPictRows 60 /* Number of Rows in Pict */
1025 typedef struct FrameRec FrameRec;
1030 * - GWorld for the frame image
1031 * - Handle to pix map (saved for unlocking/locking)
1032 * - Pointer to color pix map (valid only while locked)
1036 GWorldPtr framePort;
1037 PixMapHandle framePixHndl;
1044 * The global picture data
1046 static FrameRec *frameP = NULL;
1052 static void BenSWLockFrame(FrameRec *srcFrameP)
1054 PixMapHandle pixMapH;
1056 pixMapH = GetGWorldPixMap(srcFrameP->framePort);
1057 (void)LockPixels(pixMapH);
1058 HLockHi((Handle)pixMapH);
1059 srcFrameP->framePixHndl = pixMapH;
1060 srcFrameP->framePix = (PixMapPtr)StripAddress(*(Handle)pixMapH);
1068 static void XDDSWLockFrame( term_data *td )
1070 PixMapHandle pixMapH;
1072 pixMapH = GetGWorldPixMap(td->bufferPort);
1073 (void)LockPixels(pixMapH);
1074 HLockHi((Handle)pixMapH);
1075 td->bufferPixHndl = pixMapH;
1076 td->bufferPix = (PixMapPtr)*(Handle)pixMapH;
1084 static void BenSWUnlockFrame(FrameRec *srcFrameP)
1086 if (srcFrameP->framePort != NULL)
1088 HUnlock((Handle)srcFrameP->framePixHndl);
1089 UnlockPixels(srcFrameP->framePixHndl);
1092 srcFrameP->framePix = NULL;
1100 static void XDDSWUnlockFrame( term_data *td )
1102 if (td->bufferPort != NULL)
1104 HUnlock((Handle)td->bufferPixHndl);
1105 UnlockPixels(td->bufferPixHndl);
1108 td->bufferPix = NULL;
1112 static OSErr BenSWCreateGWorldFromPict(
1113 GWorldPtr *pictGWorld,
1117 GWorldPtr saveGWorld;
1118 GDHandle saveGDevice;
1119 GWorldPtr tempGWorld;
1128 depth = data[0].pixelDepth;
1131 theGDH = data[0].theGDH;
1133 /* Obtain size rectangle */
1134 pictRect = (**pictH).picFrame;
1135 OffsetRect(&pictRect, -pictRect.left, -pictRect.top);
1137 /* Create a GWorld */
1138 err = NewGWorld(&tempGWorld, depth, &pictRect, nil,
1139 theGDH, noNewDevice);
1148 *pictGWorld = tempGWorld;
1151 GetGWorld(&saveGWorld, &saveGDevice);
1154 SetGWorld(tempGWorld, nil);
1156 /* Dump the pict into the GWorld */
1157 (void)LockPixels(GetGWorldPixMap(tempGWorld));
1158 EraseRect(&pictRect);
1159 DrawPicture(pictH, &pictRect);
1160 UnlockPixels(GetGWorldPixMap(tempGWorld));
1162 /* Restore GWorld */
1163 SetGWorld(saveGWorld, saveGDevice);
1171 static OSErr XDDSWCreateGWorldFromPict(
1172 GWorldPtr *pictGWorld,
1176 /* GWorldPtr saveGWorld;
1177 GDHandle saveGDevice;*/
1178 GWorldPtr tempGWorld;
1181 /* GDHandle theGDH; */
1189 /* depth = td->pixelDepth; */
1192 /* theGDH = td->theGDH; */
1194 /* Obtain size rectangle */
1196 pictRect.right = td->size_wid;
1198 pictRect.bottom = td->tile_hgt;
1200 /* Create a GWorld */
1201 err = NewGWorld(&tempGWorld, 0, &pictRect, 0, 0, 0);
1210 *pictGWorld = tempGWorld;
1213 /* GetGWorld(&saveGWorld, &saveGDevice); */
1216 /* SetGWorld(tempGWorld, nil); */
1218 /* Dump the pict into the GWorld */
1219 /* (void)LockPixels(GetGWorldPixMap(tempGWorld)); */
1220 /* EraseRect(&pictRect); */
1221 /* DrawPicture(pictH, &pictRect); */
1222 /* UnlockPixels(GetGWorldPixMap(tempGWorld)); */
1224 /* Restore GWorld */
1225 /* SetGWorld(saveGWorld, saveGDevice); */
1231 static OSErr XDDSWUpDateGWorldFromPict( term_data *td )
1233 /* GWorldPtr saveGWorld; */
1234 /* GDHandle saveGDevice; */
1237 /* GDHandle theGDH; */
1239 GWorldFlags errflag;
1243 if( td->bufferPort == NULL )
1246 /* depth = td->pixelDepth; */
1249 /* theGDH = td->theGDH; */
1251 /* Obtain size rectangle */
1254 pictRect.right = td->size_wid;
1255 pictRect.bottom = td->tile_hgt;
1257 XDDSWUnlockFrame(td);
1259 errflag = UpdateGWorld( &td->bufferPort, 0, &pictRect, 0, 0, 0);
1261 if( errflag & gwFlagErr ){
1267 /* GetGWorld(&saveGWorld, &saveGDevice); */
1270 /* SetGWorld(td->bufferPort, nil); */
1272 /* Dump the pict into the GWorld */
1273 /* (void)LockPixels(GetGWorldPixMap(td->bufferPort)); */
1274 /* EraseRect(&td->bufferPort->portRect); */
1276 /* UnlockPixels(GetGWorldPixMap(td->bufferPort)); */
1278 /* Restore GWorld */
1279 /* SetGWorld(saveGWorld, saveGDevice); */
1285 * Init the global "frameP"
1288 static errr globe_init(void)
1292 GWorldPtr tempPictGWorldP;
1296 /* Use window XXX XXX XXX */
1300 /* Get the pict resource */
1301 newPictH = GetPicture(kPictID);
1303 /* Analyze result */
1304 err = (newPictH ? 0 : -1);
1311 err = BenSWCreateGWorldFromPict(&tempPictGWorldP, newPictH);
1313 /* Release resource */
1314 ReleaseResource((Handle)newPictH);
1319 /* Create the frame */
1320 frameP = (FrameRec*)NewPtrClear((Size)sizeof(FrameRec));
1322 /* Analyze result */
1323 err = (frameP ? 0 : -1);
1329 frameP->framePort = tempPictGWorldP;
1332 BenSWLockFrame(frameP);
1343 * Nuke the global "frameP"
1345 static errr globe_nuke(void)
1351 BenSWUnlockFrame(frameP);
1353 /* Dispose of the GWorld */
1354 DisposeGWorld(frameP->framePort);
1356 /* Dispose of the memory */
1357 DisposePtr((Ptr)frameP);
1364 FlushEvents(everyEvent, 0);
1371 #endif /* ANGBAND_LITE_MAC */
1375 /*** Support for the "z-term.c" package ***/
1379 * Initialize a new Term
1381 * Note also the "window type" called "noGrowDocProc", which might be more
1382 * appropriate for the main "screen" window.
1384 * Note the use of "srcCopy" mode for optimized screen writes.
1386 static void Term_init_mac(term *t)
1388 term_data *td = (term_data*)(t->data);
1390 static RGBColor black = {0x0000,0x0000,0x0000};
1391 static RGBColor white = {0xFFFF,0xFFFF,0xFFFF};
1393 #ifdef ANGBAND_LITE_MAC
1395 /* Make the window */
1396 td->w = NewWindow(0, &td->r, td->title, 0, noGrowDocProc, (WindowPtr)-1, 1, 0L);
1398 #else /* ANGBAND_LITE_MAC */
1400 /* Make the window */
1401 td->w = NewCWindow(0, &td->r, td->title, 0, documentProc, (WindowPtr)-1, 1, 0L);
1403 #endif /* ANGBAND_LITE_MAC */
1405 /* Activate the window */
1408 /* Erase behind words */
1411 /* Apply and Verify */
1412 term_data_check_font(td);
1413 term_data_check_size(td);
1415 /* Resize the window */
1416 term_data_resize(td);
1418 #ifdef ANGBAND_LITE_MAC
1420 /* Prepare the colors (base colors) */
1421 BackColor(blackColor);
1422 ForeColor(whiteColor);
1424 #else /* ANGBAND_LITE_MAC */
1426 /* Prepare the colors (real colors) */
1427 RGBBackColor(&black);
1428 RGBForeColor(&white);
1435 GDHandle currentGDH;
1436 GWorldPtr windowGWorld;
1437 PixMapHandle basePixMap;
1439 /* Obtain the rect */
1440 tempRect = td->w->portRect;
1442 /* Obtain the global rect */
1443 globalRect = tempRect;
1444 LocalToGlobal((Point*)&globalRect.top);
1445 LocalToGlobal((Point*)&globalRect.bottom);
1447 /* Obtain the proper GDH */
1448 mainGDH = GetMaxDevice(&globalRect);
1450 /* Extract GWorld and GDH */
1451 GetGWorld(&windowGWorld, ¤tGDH);
1453 /* Obtain base pixmap */
1454 basePixMap = (**mainGDH).gdPMap;
1456 /* Save pixel depth */
1457 td->pixelDepth = (**basePixMap).pixelSize;
1459 /* Save Window GWorld */
1460 td->theGWorld = windowGWorld;
1462 /* Save Window GDH */
1463 td->theGDH = currentGDH;
1466 td->mainSWGDH = mainGDH;
1469 #endif /* ANGBAND_LITE_MAC */
1471 /* Clip to the window */
1472 ClipRect(&td->w->portRect);
1474 /* Erase the window */
1475 EraseRect(&td->w->portRect);
1477 /* Invalidate the window */
1478 InvalRect(&td->w->portRect);
1480 /* Display the window if needed */
1481 if (td->mapped) ShowWindow(td->w);
1483 /* Hack -- set "mapped" flag */
1484 t->mapped_flag = td->mapped;
1489 XDDSWCreateGWorldFromPict( &td->bufferPort, td );
1491 XDDSWLockFrame( td );
1493 /* if (err == noErr)
1505 static void Term_nuke_mac(term *t)
1518 static errr Term_user_mac(int n)
1532 static errr Term_xtra_mac_react(void)
1534 term_data *td = (term_data*)(Term->data);
1540 #ifdef ANGBAND_LITE_MAC
1544 #else /* ANGBAND_LITE_MAC */
1547 if (use_sound != arg_sound)
1550 use_sound = arg_sound;
1553 /* Handle graphics */
1554 if ((td == &data[0]) && (use_graphics != arg_graphics))
1556 /* Initialize graphics */
1558 if (!use_graphics && !frameP && (globe_init() != 0))
1561 plog("¥°¥é¥Õ¥£¥Ã¥¯¤Î½é´ü²½¤Ï½ÐÍè¤Þ¤»¤ó¤Ç¤·¤¿.");
1563 plog("Cannot initialize graphics!");
1565 arg_graphics = FALSE;
1569 use_graphics = arg_graphics;
1571 /* Apply and Verify */
1572 term_data_check_size(td);
1574 /* Resize the window */
1575 term_data_resize(td);
1581 #endif /* ANGBAND_LITE_MAC */
1589 * Do a "special thing"
1591 static errr Term_xtra_mac(int n, int v)
1593 term_data *td = (term_data*)(Term->data);
1601 case TERM_XTRA_NOISE:
1610 #ifdef ANGBAND_LITE_MAC
1614 #else /* ANGBAND_LITE_MAC */
1617 case TERM_XTRA_SOUND:
1627 /* Open the resource file */
1628 oldResFile = CurResFile();
1629 newResFile = OpenResFile(sound);
1631 /* Close the resource file */
1632 CloseResFile(newResFile);
1633 UseResFile(oldResFile);
1636 /* Get the proper sound name */
1637 sprintf((char*)sound + 1, "%.16s.wav", angband_sound_name[v]);
1638 sound[0] = strlen((char*)sound + 1);
1640 /* Obtain resource XXX XXX XXX */
1642 handle = Get1NamedResource('snd ', sound);
1643 if( handle == NULL || ext_sound )
1644 handle = GetNamedResource('snd ', sound);
1647 if (handle && soundmode[soundchoice[v]] == true)
1650 LoadResource(handle);
1653 /* Play sound (wait for completion) */
1654 SndPlay(nil, (SndListHandle)handle, true);
1656 /* Unlock and release */
1658 ReleaseResource(handle);
1661 handle = GetNamedResource('snd ', sound);
1667 LoadResource(handle);
1670 /* Play sound (wait for completion) */
1671 SndPlay(nil, (SndListHandle)handle, true);
1673 /* Unlock and release */
1675 ReleaseResource(handle);
1682 #endif /* ANGBAND_LITE_MAC */
1684 /* Process random events */
1685 case TERM_XTRA_BORED:
1687 /* Process an event */
1688 (void)CheckEvents(0);
1694 /* Process pending events */
1695 case TERM_XTRA_EVENT:
1697 /* Process an event */
1698 (void)CheckEvents(v);
1704 /* Flush all pending events (if any) */
1705 case TERM_XTRA_FLUSH:
1707 /* Hack -- flush all events */
1708 while (CheckEvents(TRUE)) /* loop */;
1714 /* Hack -- Change the "soft level" */
1715 case TERM_XTRA_LEVEL:
1717 /* Activate if requested */
1718 if (v) activate(td->w);
1724 /* Clear the screen */
1725 case TERM_XTRA_CLEAR:
1727 /* No clipping XXX XXX XXX */
1728 ClipRect(&td->w->portRect);
1730 /* Erase the window */
1731 EraseRect(&td->w->portRect);
1734 term_data_color(td, TERM_WHITE);
1736 /* Frame the window in white */
1738 LineTo(0, td->size_hgt-1);
1739 LineTo(td->size_wid-1, td->size_hgt-1);
1740 LineTo(td->size_wid-1, 0);
1742 /* Clip to the new size */
1743 r.left = td->w->portRect.left + td->size_ow1;
1744 r.top = td->w->portRect.top + td->size_oh1;
1745 r.right = td->w->portRect.right - td->size_ow2;
1746 r.bottom = td->w->portRect.bottom - td->size_oh2;
1753 /* React to changes */
1754 case TERM_XTRA_REACT:
1756 /* React to changes */
1757 return (Term_xtra_mac_react());
1760 /* Delay (milliseconds) */
1761 case TERM_XTRA_DELAY:
1766 long m = TickCount() + (v * 60L) / 1000;
1769 while (TickCount() < m) /* loop */;
1784 * Low level graphics (Assumes valid input).
1785 * Draw a "cursor" at (x,y), using a "yellow box".
1786 * We are allowed to use "Term_grab()" to determine
1787 * the current screen contents (for inverting, etc).
1789 static errr Term_curs_mac(int x, int y)
1793 term_data *td = (term_data*)(Term->data);
1796 term_data_color(td, TERM_YELLOW);
1798 /* Frame the grid */
1799 r.left = x * td->tile_wid + td->size_ow1;
1800 r.right = r.left + td->tile_wid;
1801 r.top = y * td->tile_hgt + td->size_oh1;
1802 r.bottom = r.top + td->tile_hgt;
1811 * Low level graphics (Assumes valid input)
1813 * Erase "n" characters starting at (x,y)
1815 static errr Term_wipe_mac(int x, int y, int n)
1819 term_data *td = (term_data*)(Term->data);
1821 /* Erase the block of characters */
1822 r.left = x * td->tile_wid + td->size_ow1;
1823 r.right = r.left + n * td->tile_wid;
1824 r.top = y * td->tile_hgt + td->size_oh1;
1825 r.bottom = r.top + td->tile_hgt;
1834 * Low level graphics. Assumes valid input.
1836 * Draw several ("n") chars, with an attr, at a given location.
1838 static errr Term_text_mac(int x, int y, int n, byte a, const char *cp)
1842 term_data *td = (term_data*)(Term->data);
1845 term_data_color(td, (a & 0x0F));
1847 /* Starting pixel */
1848 xp = x * td->tile_wid + td->tile_o_x + td->size_ow1;
1849 yp = y * td->tile_hgt + td->tile_o_y + td->size_oh1;
1851 /* Move to the correct location */
1854 /* Draw the character */
1855 if (n == 1) DrawChar(*cp);
1857 /* Draw the string */
1858 else DrawText(cp, 0, n);
1866 * Low level graphics (Assumes valid input)
1868 * Erase "n" characters starting at (x,y)
1870 static errr Term_pict_mac(int x, int y, int n, const byte *ap, const char *cp)
1874 bool use_buffer = false;
1875 term_data *td = (term_data*)(Term->data);
1876 GDHandle saveGDevice;
1877 GWorldPtr saveGWorld;
1880 PixMapHandle PortPix;
1885 GetGWorld(&saveGWorld, &saveGDevice);
1889 /* Destination rectangle */
1890 r2.left = x * td->tile_wid + td->size_ow1;
1891 r2.right = r2.left + td->tile_wid;
1893 r2.bottom = r2.top + td->tile_hgt;
1896 SetGWorld(td->bufferPort, nil);
1898 PortPix = GetGWorldPixMap(td->bufferPort );
1899 LockPixels( PortPix );
1901 /* Instantiate font */
1902 TextFont(td->font_id);
1903 TextSize(td->font_size);
1904 TextFace(td->font_face);
1906 /* Restore colors */
1907 BackColor(blackColor);
1908 ForeColor(whiteColor);
1912 EraseRect(&td->bufferPort->portRect);
1919 /* Destination rectangle */
1920 r2.left = x * td->tile_wid + td->size_ow1;
1921 r2.right = r2.left + td->tile_wid;
1922 r2.top = y * td->tile_hgt + td->size_oh1;
1923 r2.bottom = r2.top + td->tile_hgt;
1925 /* no buffering, so we use the normal current port */
1930 /* Scan the input */
1931 for (i = 0; i < n; i++)
1938 #ifdef ANGBAND_LITE_MAC
1942 #else /* ANGBAND_LITE_MAC */
1944 /* Graphics -- if Available and Needed */
1945 if (use_graphics && ((td == &data[0]) || (td == &data[6])) &&
1946 ((byte)a & 0x80) && ((byte)c & 0x80))
1952 row = ((byte)a & 0x7F);// % kPictRows;
1953 col = ((byte)c & 0x7F);// % kPictCols;
1955 /* Source rectangle */
1956 r1.left = col * kGrafWidth;
1957 r1.top = row * kGrafHeight;
1958 r1.right = r1.left + kGrafWidth;
1959 r1.bottom = r1.top + kGrafHeight;
1961 /* Hardwire CopyBits */
1962 BackColor(whiteColor);
1963 ForeColor(blackColor);
1965 /* Draw the picture */
1967 BitMapPtr srcBitMap = (BitMapPtr)(frameP->framePix);
1968 BitMapPtr destBitMap;
1972 destBitMap = (BitMapPtr)(td->bufferPix);
1976 destBitMap = (BitMapPtr)&(td->w->portBits);
1979 /* draw transparent tile */
1980 /* BackColor is ignored and the destination is left untouched */
1981 BackColor(blackColor);
1982 CopyBits( srcBitMap, destBitMap, &r1, &r2, transparent, NULL );
1984 /* Restore colors */
1985 BackColor(blackColor);
1986 ForeColor(whiteColor);
1995 #endif /* ANGBAND_LITE_MAC */
2006 term_data_color(td, (a & 0x0F));
2008 /* Starting pixel */
2009 xp = r2.left + td->tile_o_x;
2010 yp = r2.top + td->tile_o_y;
2012 /* Move to the correct location */
2015 /* Draw the character */
2019 term_data_color(td, (a & 0x0F));
2021 /* Starting pixel */
2022 xp = r2.left + td->tile_o_x;
2025 /* Move to the correct location */
2029 /* Draw the character */
2034 r2.left += td->tile_wid;
2035 r2.right += td->tile_wid;
2037 /* Draw the character */
2044 r2.left += td->tile_wid;
2045 r2.right += td->tile_wid;
2050 /* Now we blast the buffer pixmap onto the screen in the right place */
2051 BitMapPtr srcBitMap = (BitMapPtr)(td->bufferPix);
2053 BitMapPtr destBitMap = (BitMapPtr)&(td->w->portBits);
2059 srcRect.left = x * td->tile_wid + td->size_ow1;
2061 srcRect.right = srcRect.left + (td->tile_wid * n);
2062 srcRect.bottom = td->tile_hgt;
2064 destRect.left = x * td->tile_wid + td->size_ow1;
2065 destRect.right = destRect.left + (td->tile_wid * n);
2066 destRect.top = y * td->tile_hgt + td->size_oh1;
2067 destRect.bottom = destRect.top + td->tile_hgt;
2070 UnlockPixels( PortPix );
2072 /* Restore GWorld */
2073 SetGWorld(saveGWorld, saveGDevice);
2075 /* Hardwire CopyBits */
2076 BackColor(whiteColor);
2077 ForeColor(blackColor);
2079 //CopyBits( srcBitMap, destBitMap, &srcRect, &destRect, srcCopy, NULL );
2080 CopyBits( (BitMapPtr)(td->bufferPix)
2081 , &(td->w->portBits), &srcRect, &destRect, srcCopy, NULL );
2083 /* Restore colors */
2084 BackColor(blackColor);
2085 ForeColor(whiteColor);
2098 * Create and initialize window number "i"
2100 static void term_data_link(int i)
2104 term_data *td = &data[i];
2109 /* Require mapped */
2110 if (!td->mapped) return;
2115 /* Initialize the term */
2116 term_init(td->t, td->cols, td->rows, td->keys);
2118 /* Use a "software" cursor */
2119 td->t->soft_cursor = TRUE;
2121 /* Erase with "white space" */
2122 td->t->attr_blank = TERM_WHITE;
2123 td->t->char_blank = ' ';
2125 /* Prepare the init/nuke hooks */
2126 td->t->init_hook = Term_init_mac;
2127 td->t->nuke_hook = Term_nuke_mac;
2129 /* Prepare the function hooks */
2130 td->t->user_hook = Term_user_mac;
2131 td->t->xtra_hook = Term_xtra_mac;
2132 td->t->wipe_hook = Term_wipe_mac;
2133 td->t->curs_hook = Term_curs_mac;
2134 td->t->text_hook = Term_text_mac;
2135 td->t->pict_hook = Term_pict_mac;
2137 /* Link the local structure */
2138 td->t->data = (vptr)(td);
2141 Term_activate(td->t);
2143 /* Global pointer */
2144 angband_term[i] = td->t;
2154 * Set the "current working directory" (also known as the "default"
2155 * volume/directory) to the location of the current application.
2157 * Code by: Maarten Hazewinkel (mmhazewi@cs.ruu.nl)
2159 * This function does not appear to work correctly with System 6.
2161 static void SetupAppDir(void)
2165 char errString[100];
2167 /* Get the location of the Angband executable */
2168 fcbBlock.ioCompletion = NULL;
2169 fcbBlock.ioNamePtr = NULL;
2170 fcbBlock.ioVRefNum = 0;
2171 fcbBlock.ioRefNum = CurResFile();
2172 fcbBlock.ioFCBIndx = 0;
2173 err = PBGetFCBInfo(&fcbBlock, FALSE);
2177 sprintf(errString, "PBGetFCBInfo ¥¨¥é¡¼ #%d.\r ½ªÎ»¤·¤Þ¤¹.", err);
2179 sprintf(errString, "Fatal PBGetFCBInfo Error #%d.\r Exiting.", err);
2181 mac_warning(errString);
2185 /* Extract the Vol and Dir */
2186 app_vol = fcbBlock.ioFCBVRefNum;
2187 app_dir = fcbBlock.ioFCBParID;
2189 /* Set the current working directory to that location */
2190 err = HSetVol(NULL, app_vol, app_dir);
2194 sprintf(errString, "HSetVol ¥¨¥é¡¼ #%d.\r ½ªÎ»¤·¤Þ¤¹.", err);
2196 sprintf(errString, "Fatal HSetVol Error #%d.\r Exiting.", err);
2198 mac_warning(errString);
2207 * Global "preference" file pointer
2212 * Read a "short" from the file
2214 static int getshort(void)
2218 if (0 == my_fgets(fff, buf, 256)) x = atoi(buf);
2223 * Dump a "short" to the file
2225 static void putshort(int x)
2227 fprintf(fff, "%d\n", x);
2233 * Write the "preference" data to the current "file"
2235 static void save_prefs(void)
2242 /*** The current version ***/
2244 putshort(VERSION_MAJOR);
2245 putshort(VERSION_MINOR);
2246 putshort(VERSION_PATCH);
2247 putshort(VERSION_EXTRA);
2249 putshort(arg_sound);
2250 putshort(arg_graphics);
2253 for( i = 0 ; i < 7 ; i++ )
2254 putshort(soundmode[i]);
2257 for (i = 0; i < MAX_TERM_DATA; i++)
2262 putshort(td->mapped);
2264 putshort(td->font_id);
2265 putshort(td->font_size);
2266 putshort(td->font_face);
2269 putshort(td->tile_wid);
2270 putshort(td->tile_hgt);
2276 putshort(td->r.left);
2277 putshort(td->r.top);
2283 * Load the preferences from the current "file"
2285 * XXX XXX XXX Being able to undefine various windows is
2286 * slightly bizarre, and may cause problems.
2288 static void load_prefs(void)
2292 int old_major, old_minor, old_patch, old_extra;
2297 /*** Version information ***/
2299 /* Preferences version */
2300 old_major = getshort();
2301 old_minor = getshort();
2302 old_patch = getshort();
2303 old_extra = getshort();
2305 /* Hack -- Verify or ignore */
2306 if ((old_major != VERSION_MAJOR) ||
2307 (old_minor != VERSION_MINOR) ||
2308 (old_patch != VERSION_PATCH) ||
2309 (old_extra != VERSION_EXTRA))
2313 mac_warning("¸Å¤¤½é´üÀßÄê¥Õ¥¡¥¤¥ë¤ò̵»ë¤·¤Þ¤¹.");
2315 mac_warning("Ignoring old preferences.");
2321 arg_sound = getshort();
2322 arg_graphics = getshort();
2325 for( i = 0 ; i < 7 ; i++ )
2326 soundmode[i] = getshort();
2329 m = GetMenuHandle(134); //m = GetMHandle(134);
2331 /* Item "arg_sound" */
2332 CheckItem(m, 1, arg_sound);
2334 /* Item "arg_graphics" */
2335 CheckItem(m, 2, arg_graphics);
2338 for (i = 0; i < MAX_TERM_DATA; i++)
2343 td->mapped = getshort();
2345 td->font_id = getshort();
2346 td->font_size = getshort();
2347 td->font_face = getshort();
2350 td->tile_wid = getshort();
2351 td->tile_hgt = getshort();
2354 td->cols = getshort();
2355 td->rows = getshort();
2357 td->r.left = getshort();
2358 td->r.top = getshort();
2361 if (feof(fff)) break;
2369 * Hack -- default data for a window
2371 static void term_data_hack(term_data *td)
2376 GetFNum( "\pÅùÉýÌÀÄ«", &fid); /* ¥Õ¥©¥ó¥È̾¤«¤éIDÈÖ¹æ¤òÄ´¤Ù¤ë */
2377 SetFScaleDisable( true );
2379 /* Default to Monaco font */
2380 GetFNum("\pmonaco", &fid);
2383 WIPE(td, term_data);
2388 /* Default borders */
2399 /* Default font size */
2402 /* Default font face */
2409 /* Default position */
2419 * Read the preference file, Create the windows.
2421 * We attempt to use "FindFolder()" to track down the preference file,
2422 * but if this fails, for any reason, we will try the "SysEnvirons()"
2423 * method, which may work better with System 6.
2425 static void init_windows(void)
2438 /*** Default values ***/
2440 /* Initialize (backwards) */
2441 for (i = MAX_TERM_DATA - 1; i >= 0; i--)
2454 s = angband_term_name[i];
2459 /* Maximal length */
2462 /* Copy the title */
2463 strncpy((char*)(td->title) + 1, s, n);
2465 /* Save the length */
2468 /* Tile the windows */
2469 td->r.left += (b * 30);
2470 td->r.top += (b * 30);
2477 /*** Load preferences ***/
2479 /* Assume failure */
2482 /* Assume failure */
2495 /* Find the folder */
2496 err = FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder,
2502 /* Extract a path name */
2503 PathNameFromDirID(dirID, vref, (StringPtr)foo);
2505 /* Convert the string */
2506 ptocstr((StringPtr)foo);
2508 /* Append the preference file name */
2510 strcat(foo, "Hengband Preferences");
2512 strcat(foo, "Angband Preferences");
2514 /* Open the preference file */
2515 fff = fopen(foo, "r");
2522 #endif /* USE_SFL_CODE */
2528 HGetVol(0, &savev, &saved);
2530 /* Go to the "system" folder */
2531 SysEnvirons(curSysEnvVers, &env);
2532 SetVol(0, env.sysVRefNum);
2536 fff = fopen(":Preferences:Hengband Preferences", "r");
2537 if (!fff) fff = fopen(":Hengband Preferences", "r");
2539 fff = fopen(":Preferences:Angband Preferences", "r");
2540 if (!fff) fff = fopen(":Angband Preferences", "r");
2543 HSetVol(0, savev, saved);
2546 /* Load preferences */
2549 /* Load a real preference file */
2552 /* Close the file */
2557 /*** Instantiate ***/
2568 /* Link (backwards, for stacking order) */
2569 for (i = MAX_TERM_DATA - 1; i >= 0; i--)
2578 Term_activate(td->t);
2582 static void init_sound( void )
2586 SignedByte permission = fsRdPerm;
2592 /* Descend into "lib" folder */
2593 pb.ioCompletion = NULL;
2594 pb.ioNamePtr = "\plib";
2595 pb.ioVRefNum = app_vol;
2596 pb.ioDrDirID = app_dir;
2599 /* Check for errors */
2600 err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
2603 if ((err == noErr) && (pb.ioFlAttrib & 0x10))
2605 /* Descend into "lib/save" folder */
2606 pb.ioCompletion = NULL;
2607 pb.ioNamePtr = "\pxtra";
2608 pb.ioVRefNum = app_vol;
2609 pb.ioDrDirID = pb.ioDrDirID;
2612 /* Check for errors */
2613 err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
2616 if ((err == noErr) && (pb.ioFlAttrib & 0x10))
2618 /* Descend into "lib/save" folder */
2619 pb.ioCompletion = NULL;
2620 pb.ioNamePtr = "\psound";
2621 pb.ioVRefNum = app_vol;
2622 pb.ioDrDirID = pb.ioDrDirID;
2625 /* Check for errors */
2626 err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
2629 if ((err == noErr) && (pb.ioFlAttrib & 0x10))
2631 ret = HOpenResFile( app_vol , pb.ioDrDirID , "\psound.rsrc" , permission );
2635 for( i = 0 ; i < 7 ; i++ )
2636 soundmode[i] = false;
2638 for( i = 1 ; i < SOUND_MAX ; i++ ){
2639 /* Get the proper sound name */
2640 sprintf((char*)sound + 1, "%.16s.wav", angband_sound_name[i]);
2641 sound[0] = strlen((char*)sound + 1);
2643 /* Obtain resource XXX XXX XXX */
2644 handle = Get1NamedResource('snd ', sound);
2645 if( handle == NULL || ext_sound )
2646 handle = GetNamedResource('snd ', sound);
2649 soundmode[soundchoice[i]] = true;
2662 static void init_chuukei( void )
2668 path_build(path, 1024, ANGBAND_DIR_XTRA, "chuukei.txt");
2670 fp = fopen(path, "r");
2675 if (fgets(tmp, 1024, fp)){
2677 int n = strlen(tmp);
2683 chuukei_server = TRUE;
2684 if(connect_chuukei_server(&tmp[2])<0){
2685 msg_print("connect fail");
2688 msg_print("connect");
2695 chuukei_client = TRUE;
2696 connect_chuukei_server(&tmp[2]);
2712 short InevrtCheck( DialogPtr targetDlg, short check )
2719 GetDialogItem( targetDlg, check, &itemType, &checkH, &box );
2720 result = (GetControlValue( (ControlHandle)checkH ) + 1 ) % 2;
2721 SetControlValue( (ControlHandle)checkH , result );
2729 short SetCheck( DialogPtr targetDlg, short check, long result )
2736 GetDialogItem( targetDlg, check, &itemType, &checkH, &box );
2737 SetControlValue( (ControlHandle)checkH , result );
2745 short GetCheck( DialogPtr targetDlg, short check )
2752 GetDialogItem( targetDlg, check, &itemType, &checkH, &box );
2753 result = GetControlValue( (ControlHandle)checkH );
2757 void SoundConfigDLog(void)
2764 dialog=GetNewDialog(131, 0, (WindowPtr)-1);
2765 SetDialogDefaultItem( dialog, ok );
2766 SetDialogCancelItem( dialog, cancel );
2767 for( i = 1 ; i < 7 ; i++ )
2768 SetCheck( dialog, i+2 , soundmode[i] );
2771 for( item_hit = 100 ; cancel < item_hit ; ){
2772 ModalDialog(0, &item_hit);
2776 for( i = 1 ; i < 7 ; i++ )
2777 soundmode[i] = GetCheck( dialog, i+2 );
2782 InevrtCheck( dialog, item_hit );
2785 DisposeDialog(dialog);
2794 static void save_pref_file(void)
2803 /* Assume failure */
2806 /* Assume failure */
2823 /* Find the folder */
2824 err = FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder,
2830 /* Extract a path name */
2831 PathNameFromDirID(dirID, vref, (StringPtr)foo);
2833 /* Convert the string */
2834 ptocstr((StringPtr)foo);
2836 /* Append the preference file name */
2838 strcat(foo, "Hengband Preferences");
2840 strcat(foo, "Angband Preferences");
2842 /* Open the preference file */
2843 /* my_fopen set file type and file creator for MPW */
2844 fff = my_fopen(foo, "w");
2851 #endif /* USE_SFL_CODE */
2857 HGetVol(0, &savev, &saved);
2859 /* Go to "system" folder */
2860 SysEnvirons(curSysEnvVers, &env);
2861 SetVol(0, env.sysVRefNum);
2863 /* Open the preference file */
2864 /* my_fopen set file type and file creator for MPW */
2866 fff = my_fopen(":Preferences:Hengband Preferences", "w");
2867 if (!fff) fff = my_fopen(":Hengband Preferences", "w");
2870 fff = my_fopen(":Preferences:Angband Preferences", "w");
2871 if (!fff) fff = my_fopen(":Angband Preferences", "w");
2874 HSetVol(0, savev, saved);
2877 /* Save preferences */
2880 /* Write the preferences */
2891 * A simple "Yes/No" filter to parse "key press" events in dialog windows
2893 static pascal Boolean ynfilter(DialogPtr dialog, EventRecord *event, short *ip)
2895 /* Parse key press events */
2896 if (event->what == keyDown)
2901 /* Extract the pressed key */
2902 c = (event->message & charCodeMask);
2904 /* Accept "no" and <return> and <enter> */
2905 if ((c=='n') || (c=='N') || (c==13) || (c==3)) i = 1;
2908 else if ((c=='y') || (c=='Y')) i = 2;
2910 /* Handle "yes" or "no" */
2914 ControlHandle control;
2917 /* Get the button */
2918 GetDialogItem(dialog, i, &type, (Handle*)&control, &r); //GetDItem(dialog, i, &type, (Handle*)&control, &r);
2920 /* Blink button for 1/10 second */
2921 HiliteControl(control, 1);
2922 Term_xtra_mac(TERM_XTRA_DELAY, 100);
2923 HiliteControl(control, 0);
2937 * Handle menu: "File" + "New"
2939 static void do_menu_file_new(void)
2944 /* Game is in progress */
2945 game_in_progress = 1;
2959 * Handle menu: "File" + "Open"
2961 static void do_menu_file_open(bool all)
2975 /* vrefnum = GetSFCurVol(); */
2976 vrefnum = -*((short*)0x214);
2978 /* drefnum = GetSFCurDir(); */
2979 drefnum = *((long*)0x398);
2981 /* Descend into "lib" folder */
2982 pb.ioCompletion = NULL;
2983 pb.ioNamePtr = "\plib";
2984 pb.ioVRefNum = vrefnum;
2985 pb.ioDrDirID = drefnum;
2988 /* Check for errors */
2989 err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
2992 if ((err == noErr) && (pb.ioFlAttrib & 0x10))
2994 /* Descend into "lib/save" folder */
2995 pb.ioCompletion = NULL;
2996 pb.ioNamePtr = "\psave";
2997 pb.ioVRefNum = vrefnum;
2998 pb.ioDrDirID = pb.ioDrDirID;
3001 /* Check for errors */
3002 err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
3005 if ((err == noErr) && (pb.ioFlAttrib & 0x10))
3007 /* SetSFCurDir(pb.ioDrDirID); */
3008 *((long*)0x398) = pb.ioDrDirID;
3012 /* Window location */
3013 topleft.h = (qd.screenBits.bounds.left+qd.screenBits.bounds.right)/2-344/2;
3014 topleft.v = (2*qd.screenBits.bounds.top+qd.screenBits.bounds.bottom)/3-188/2;
3016 /* Allow "all" files */
3020 SFGetFile(topleft, "\p", NULL, -1, types, NULL, &reply);
3023 /* Allow "save" files */
3030 SFGetFile(topleft, "\p", NULL, 1, types, NULL, &reply);
3034 if (!reply.good) return;
3036 /* Extract textual file name for save file */
3037 GetWDInfo(reply.vRefNum, &vrefnum, &drefnum, &junk);
3038 refnum_to_name(savefile, drefnum, vrefnum, (char*)reply.fName);
3043 /* Game is in progress */
3044 game_in_progress = 1;
3058 * Handle the "open_when_ready" flag
3060 static void handle_open_when_ready(void)
3062 /* Check the flag XXX XXX XXX make a function for this */
3063 if (open_when_ready && initialized && !game_in_progress)
3066 open_when_ready = FALSE;
3068 /* Game is in progress */
3069 game_in_progress = 1;
3088 * Initialize the menus
3090 * Verify menus 128, 129, 130
3091 * Create menus 131, 132, 133, 134
3093 * The standard menus are:
3095 * Apple (128) = { About, -, ... }
3096 * File (129) = { New,Open,Import,Close,Save,-,Exit,Quit }
3097 * Edit (130) = { Cut, Copy, Paste, Clear } (?)
3098 * Font (131) = { Bold, Extend, -, Monaco, ..., -, ... }
3099 * Size (132) = { ... }
3100 * Window (133) = { Angband, Mirror, Recall, Choice,
3101 * Term-4, Term-5, Term-6, Term-7 }
3102 * Special (134) = { arg_sound, arg_graphics, -,
3103 * arg_fiddle, arg_wizard }
3105 static void init_menubar(void)
3116 /* Get the "apple" menu */
3119 /* Insert the menu */
3122 /* Add the DA's to the "apple" menu */
3123 AppendResMenu (m, 'DRVR'); //AddResMenu(m, 'DRVR');
3126 /* Get the "File" menu */
3129 /* Insert the menu */
3133 /* Get the "Edit" menu */
3136 /* Insert the menu */
3140 /* Make the "Font" menu */
3142 m = NewMenu(131, "\p¥Õ¥©¥ó¥È");
3144 m = NewMenu(131, "\pFont");
3147 /* Insert the menu */
3151 AppendMenu(m, "\pBold");
3154 AppendMenu(m, "\pWide");
3156 /* Add a separator */
3157 AppendMenu(m, "\p-");
3160 r.left = r.right = r.top = r.bottom = 0;
3162 /* Make the fake window */
3163 tmpw = NewWindow(0, &r, "\p", false, documentProc, 0, 0, 0);
3165 /* Activate the "fake" window */
3174 /* Add the fonts to the menu */
3175 AppendResMenu(m, 'FONT'); //AddResMenu(m, 'FONT');
3181 for (i = n; i >= 4; i--)
3186 /* Acquire the font name */
3187 /* GetMenuItemText(m, i, tmpName); */
3188 GetMenuItemText(m, i, tmpName); //GetItem(m, i, tmpName);
3190 /* Acquire the font index */
3191 GetFNum(tmpName, &fontNum);
3193 /* Apply the font index */
3196 /* Remove non-mono-spaced fonts */
3197 if ((CharWidth('i') != CharWidth('W')) || (CharWidth('W') == 0))
3199 /* Delete the menu item XXX XXX XXX */
3200 /* DeleteMenuItem(m, i); */
3201 DeleteMenuItem (m, i); //DelMenuItem(m, i);
3205 /* Destroy the old window */
3206 DisposeWindow(tmpw);
3208 /* Add a separator */
3209 AppendMenu(m, "\p-");
3211 /* Add the fonts to the menu */
3212 AppendResMenu (m, 'FONT'); //AddResMenu(m, 'FONT');
3215 /* Make the "Size" menu */
3217 m = NewMenu(132, "\p¥µ¥¤¥º");
3219 m = NewMenu(132, "\pSize");
3222 /* Insert the menu */
3225 /* Add some sizes (stagger choices) */
3226 for (i = 8; i <= 32; i += ((i / 16) + 1))
3231 sprintf((char*)buf + 1, "%d", i);
3232 buf[0] = strlen((char*)buf + 1);
3239 /* Make the "Windows" menu */
3241 m = NewMenu(133, "\p¥¦¥¤¥ó¥É¥¦");
3243 m = NewMenu(133, "\pWindows");
3246 /* Insert the menu */
3249 /* Default choices */
3250 for (i = 0; i < MAX_TERM_DATA; i++)
3254 /* Describe the item */
3255 sprintf((char*)buf + 1, "%.15s", angband_term_name[i]);
3256 buf[0] = strlen((char*)buf + 1);
3261 /* Command-Key shortcuts */
3262 if (i < 8) SetItemCmd(m, i + 1, '0' + i);
3266 /* Make the "Special" menu */
3268 m = NewMenu(134, "\pÆÃÊÌ");
3270 m = NewMenu(134, "\pSpecial");
3273 /* Insert the menu */
3276 /* Append the choices */
3278 AppendMenu(m, "\p¥µ¥¦¥ó¥É»ÈÍÑ");
3279 AppendMenu(m, "\p¥°¥é¥Õ¥£¥Ã¥¯»ÈÍÑ");
3280 AppendMenu(m, "\p-");
3281 AppendMenu(m, "\parg_fiddle");
3282 AppendMenu(m, "\parg_wizard");
3283 AppendMenu(m, "\p-");
3284 AppendMenu(m, "\p¥µ¥¦¥ó¥ÉÀßÄê...");
3286 AppendMenu(m, "\parg_sound");
3287 AppendMenu(m, "\parg_graphics");
3288 AppendMenu(m, "\p-");
3289 AppendMenu(m, "\parg_fiddle");
3290 AppendMenu(m, "\parg_wizard");
3293 /* Make the "TileWidth" menu */
3295 m = NewMenu(135, "\p¥¿¥¤¥ëÉý");
3297 m = NewMenu(135, "\pTileWidth");
3300 /* Insert the menu */
3303 /* Add some sizes */
3304 for (i = 4; i <= 32; i++)
3309 sprintf((char*)buf + 1, "%d", i);
3310 buf[0] = strlen((char*)buf + 1);
3317 /* Make the "TileHeight" menu */
3319 m = NewMenu(136, "\p¥¿¥¤¥ë¹â");
3321 m = NewMenu(136, "\pTileHeight");
3324 /* Insert the menu */
3327 /* Add some sizes */
3328 for (i = 4; i <= 32; i++)
3333 sprintf((char*)buf + 1, "%d", i);
3334 buf[0] = strlen((char*)buf + 1);
3341 /* Update the menu bar */
3349 static void setup_menus(void)
3359 term_data *td = NULL;
3362 /* Relevant "term_data" */
3363 for (i = 0; i < MAX_TERM_DATA; i++)
3366 if (!data[i].t) continue;
3368 /* Notice the matching window */
3369 if (data[i].w == FrontWindow()) td = &data[i];
3374 m = GetMenuHandle(129); //m = GetMHandle(129);
3380 for (i = 1; i <= n; i++)
3384 CheckItem(m, i, FALSE);
3387 /* Enable "new"/"open..."/"import..." */
3388 if (initialized && !game_in_progress)
3395 /* Enable "close" */
3402 if (initialized && character_generated)
3411 /* EnableItem(m, 8); */
3416 m = GetMenuHandle(130); //m = GetMHandle(130);
3422 for (i = 1; i <= n; i++)
3426 CheckItem(m, i, FALSE);
3429 /* Enable "edit" options if "needed" */
3441 m = GetMenuHandle(131); //m = GetMHandle(131);
3447 for (i = 1; i <= n; i++)
3451 CheckItem(m, i, FALSE);
3454 /* Hack -- look cute XXX XXX */
3455 /* SetItemStyle(m, 1, bold); */
3457 /* Hack -- look cute XXX XXX */
3458 /* SetItemStyle(m, 2, extend); */
3466 /* Enable "extend" */
3469 /* Check the appropriate "bold-ness" */
3470 if (td->font_face & bold) CheckItem(m, 1, TRUE);
3472 /* Check the appropriate "wide-ness" */
3473 if (td->font_face & extend) CheckItem(m, 2, TRUE);
3476 for (i = 4; i <= n; i++)
3482 /* GetMenuItemText(m,i,s); */
3483 GetMenuItemText(m, i, s); //GetItem(m, i, s);
3486 /* Check active font */
3487 if (td->font_id == value) CheckItem(m, i, TRUE);
3493 m = GetMenuHandle(132); //m = GetMHandle(132);
3499 for (i = 1; i <= n; i++)
3503 CheckItem(m, i, FALSE);
3510 for (i = 1; i <= n; i++)
3513 /* GetMenuItemText(m,i,s); */
3514 GetMenuItemText(m, i, s); //GetItem(m, i, s);
3516 value = atoi((char*)(s+1));
3518 /* Enable the "real" sizes */
3519 if (RealFont(td->font_id, value)) EnableItem(m, i);
3521 /* Check the current size */
3522 if (td->font_size == value) CheckItem(m, i, TRUE);
3528 m = GetMenuHandle(133); //m = GetMHandle(133);
3533 /* Check active windows */
3534 for (i = 1; i <= n; i++)
3536 /* Check if needed */
3537 CheckItem(m, i, data[i-1].mapped);
3542 m = GetMenuHandle(134); //m = GetMHandle(134);
3548 for (i = 1; i <= n; i++)
3552 CheckItem(m, i, FALSE);
3555 /* Item "arg_sound" */
3557 CheckItem(m, 1, arg_sound);
3559 /* Item "arg_graphics" */
3561 CheckItem(m, 2, arg_graphics);
3563 /* Item "arg_fiddle" */
3565 CheckItem(m, 4, arg_fiddle);
3567 /* Item "arg_wizard" */
3569 CheckItem(m, 5, arg_wizard);
3572 /* Item "SoundSetting" */
3576 /* EnableItem(m, 9); */
3579 /* TileWidth menu */
3580 m = GetMenuHandle(135); //m = GetMHandle(135);
3586 for (i = 1; i <= n; i++)
3590 CheckItem(m, i, FALSE);
3597 for (i = 1; i <= n; i++)
3600 /* GetMenuItemText(m,i,s); */
3601 GetMenuItemText(m, i, s); //GetItem(m, i, s);
3603 value = atoi((char*)(s+1));
3608 /* Check the current size */
3609 if (td->tile_wid == value) CheckItem(m, i, TRUE);
3614 /* TileHeight menu */
3615 m = GetMenuHandle(136); //m = GetMHandle(136);
3621 for (i = 1; i <= n; i++)
3625 CheckItem(m, i, FALSE);
3632 for (i = 1; i <= n; i++)
3635 /* GetMenuItemText(m,i,s); */
3636 GetMenuItemText(m, i, s); //GetItem(m, i, s);
3638 value = atoi((char*)(s+1));
3643 /* Check the current size */
3644 if (td->tile_hgt == value) CheckItem(m, i, TRUE);
3651 * Process a menu selection (see above)
3653 * Hack -- assume that invalid menu selections are disabled above,
3654 * which I have been informed may not be reliable. XXX XXX XXX
3656 static void menu(long mc)
3660 int menuid, selection;
3662 static unsigned char s[1000];
3666 term_data *td = NULL;
3671 /* Analyze the menu command */
3672 menuid = HiWord(mc);
3673 selection = LoWord(mc);
3676 /* Find the window */
3677 for (i = 0; i < MAX_TERM_DATA; i++)
3679 /* Skip dead windows */
3680 if (!data[i].t) continue;
3682 /* Notice matches */
3683 if (data[i].w == FrontWindow()) td = &data[i];
3687 /* Branch on the menu */
3693 /* About Angband... */
3700 dialog=GetNewDialog(128, 0, (WindowPtr)-1);
3702 /* r=dialog->portRect;
3703 center_rect(&r, &qd.screenBits.bounds);
3704 MoveWindow(dialog, r.left, r.top, 1);*/
3706 ModalDialog(0, &item_hit);
3707 DisposeDialog(dialog); //DisposDialog(dialog);
3711 /* Desk accessory */
3712 /* GetMenuItemText(GetMHandle(128),selection,s); */
3713 GetMenuItemText(GetMenuHandle(128), selection, s); //GetItem(GetMHandle(128), selection, s);
3733 do_menu_file_open(FALSE);
3740 do_menu_file_open(TRUE);
3754 td->t->mapped_flag = FALSE;
3756 /* Hide the window */
3767 plog("º£¤Ï¥»¡¼¥Ö¤¹¤ë¤³¤È¤Ï½ÐÍè¤Þ¤»¤ó¡£");
3769 plog("You may not do that right now.");
3774 /* Hack -- Forget messages */
3777 /* Hack -- Save the game */
3778 do_cmd_save_game(FALSE);
3783 /* Quit (with save) */
3786 /* Save the game (if necessary) */
3787 if (game_in_progress && character_generated)
3791 plog("º£¤Ï¥»¡¼¥Ö¤¹¤ë¤³¤È¤Ï½ÐÍè¤Þ¤»¤ó¡£");
3793 plog("You may not do that right now.");
3797 /* Hack -- Forget messages */
3801 do_cmd_save_game(FALSE);
3822 /* Require a window */
3831 /* Toggle the "bold" setting */
3834 /* Toggle the setting */
3835 if (td->font_face & bold)
3837 td->font_face &= ~bold;
3841 td->font_face |= bold;
3845 /* Tile Width Hight Init */
3846 td->tile_wid = td->tile_hgt = 0;
3848 /* Apply and Verify */
3849 term_data_check_font(td);
3850 term_data_check_size(td);
3852 /* Resize and Redraw */
3853 term_data_resize(td);
3854 term_data_redraw(td);
3859 /* Toggle the "wide" setting */
3862 /* Toggle the setting */
3863 if (td->font_face & extend)
3865 td->font_face &= ~extend;
3869 td->font_face |= extend;
3873 /* Tile Width Hight Init */
3874 td->tile_wid = td->tile_hgt = 0;
3876 /* Apply and Verify */
3877 term_data_check_font(td);
3878 term_data_check_size(td);
3880 /* Resize and Redraw */
3881 term_data_resize(td);
3882 term_data_redraw(td);
3887 /* Get a new font name */
3888 /* GetMenuItemText(GetMHandle(131), selection, s); */
3889 GetMenuItemText(GetMenuHandle(131), selection, s); //GetItem(GetMHandle(131), selection, s);
3892 /* Save the new font id */
3895 /* Current size is bad for new font */
3896 if (!RealFont(td->font_id, td->font_size))
3898 /* Find similar size */
3899 for (i = 1; i <= 32; i++)
3901 /* Adjust smaller */
3902 if (td->font_size - i >= 8)
3904 if (RealFont(td->font_id, td->font_size - i))
3912 if (td->font_size + i <= 128)
3914 if (RealFont(td->font_id, td->font_size + i))
3924 /* Tile Width Hight Init */
3925 td->tile_wid = td->tile_hgt = 0;
3927 /* Apply and Verify */
3928 term_data_check_font(td);
3929 term_data_check_size(td);
3931 /* Resize and Redraw */
3932 term_data_resize(td);
3933 term_data_redraw(td);
3935 /* Restore the window */
3952 /* GetMenuItemText(GetMHandle(132), selection, s); */
3953 GetMenuItemText(GetMenuHandle(132), selection, s); //GetItem(GetMHandle(132), selection, s);
3955 td->font_size = atoi((char*)(s+1));
3958 /* Tile Width Hight Init */
3959 td->tile_wid = td->tile_hgt = 0;
3961 /* Apply and Verify */
3962 term_data_check_font(td);
3963 term_data_check_size(td);
3965 /* Resize and Redraw */
3966 term_data_resize(td);
3967 term_data_redraw(td);
3981 /* Check legality of choice */
3982 if ((i < 0) || (i >= MAX_TERM_DATA)) break;
3984 /* Obtain the window */
3994 td->t->mapped_flag = TRUE;
3996 /* Show the window */
3999 /* Bring to the front */
4000 SelectWindow(td->w);
4012 /* Toggle arg_sound */
4013 arg_sound = !arg_sound;
4015 /* React to changes */
4016 Term_xtra(TERM_XTRA_REACT, 0);
4023 /* Toggle arg_graphics */
4024 arg_graphics = !arg_graphics;
4026 /* Hack -- Force redraw */
4027 Term_key_push(KTRL('R'));
4034 arg_fiddle = !arg_fiddle;
4040 arg_wizard = !arg_wizard;
4054 /* TileWidth menu */
4065 /* GetMenuItemText(GetMHandle(135), selection, s); */
4066 GetMenuItemText(GetMenuHandle(135), selection, s); //GetItem(GetMHandle(135), selection, s);
4068 td->tile_wid = atoi((char*)(s+1));
4070 /* Apply and Verify */
4071 term_data_check_size(td);
4073 /* Resize and Redraw */
4074 term_data_resize(td);
4075 term_data_redraw(td);
4083 /* TileHeight menu */
4094 /* GetMenuItemText(GetMHandle(136), selection, s); */
4095 GetMenuItemText(GetMenuHandle(136), selection, s); //GetItem(GetMHandle(136), selection, s);
4097 td->tile_hgt = atoi((char*)(s+1));
4099 /* Apply and Verify */
4100 term_data_check_size(td);
4102 /* Resize and Redraw */
4103 term_data_resize(td);
4104 term_data_redraw(td);
4114 /* Clean the menu */
4123 * Check for extra required parameters -- From "Maarten Hazewinkel"
4125 static OSErr CheckRequiredAEParams(const AppleEvent *theAppleEvent)
4128 DescType returnedType;
4131 aeError = AEGetAttributePtr(theAppleEvent, keyMissedKeywordAttr, typeWildCard,
4132 &returnedType, NULL, 0, &actualSize);
4134 if (aeError == errAEDescNotFound) return (noErr);
4136 if (aeError == noErr) return (errAEParamMissed);
4143 * Apple Event Handler -- Open Application
4145 static pascal OSErr AEH_Start(const AppleEvent *theAppleEvent,
4146 const AppleEvent *reply, long handlerRefCon)
4148 #pragma unused(reply, handlerRefCon)
4150 return (CheckRequiredAEParams(theAppleEvent));
4155 * Apple Event Handler -- Quit Application
4157 static pascal OSErr AEH_Quit(const AppleEvent *theAppleEvent,
4158 const AppleEvent *reply, long handlerRefCon)
4160 #pragma unused(reply, handlerRefCon)
4163 quit_when_ready = TRUE;
4165 /* Check arguments */
4166 return (CheckRequiredAEParams(theAppleEvent));
4171 * Apple Event Handler -- Print Documents
4173 static pascal OSErr AEH_Print(const AppleEvent *theAppleEvent,
4174 const AppleEvent *reply, long handlerRefCon)
4176 #pragma unused(theAppleEvent, reply, handlerRefCon)
4178 return (errAEEventNotHandled);
4183 * Apple Event Handler by Steve Linberg (slinberg@crocker.com).
4185 * The old method of opening savefiles from the finder does not work
4186 * on the Power Macintosh, because CountAppFiles and GetAppFiles,
4187 * used to return information about the selected document files when
4188 * an application is launched, are part of the Segment Loader, which
4189 * is not present in the RISC OS due to the new memory architecture.
4191 * The "correct" way to do this is with AppleEvents. The following
4192 * code is modeled on the "Getting Files Selected from the Finder"
4193 * snippet from Think Reference 2.0. (The prior sentence could read
4194 * "shamelessly swiped & hacked")
4196 static pascal OSErr AEH_Open(AppleEvent *theAppleEvent,
4197 AppleEvent* reply, long handlerRefCon)
4199 #pragma unused(reply, handlerRefCon)
4206 DescType returnedType;
4210 /* Put the direct parameter (a descriptor list) into a docList */
4211 err = AEGetParamDesc(theAppleEvent, keyDirectObject, typeAEList, &docList);
4212 if (err) return err;
4215 * We ignore the validity check, because we trust the FInder, and we only
4216 * allow one savefile to be opened, so we ignore the depth of the list.
4219 err = AEGetNthPtr(&docList, 1L, typeFSS, &keywd,
4220 &returnedType, (Ptr) &myFSS, sizeof(myFSS), &actualSize);
4221 if (err) return err;
4223 /* Only needed to check savefile type below */
4224 err = FSpGetFInfo(&myFSS, &myFileInfo);
4227 sprintf(foo, "Arg! FSpGetFInfo failed with code %d", err);
4232 /* Ignore non 'SAVE' files */
4233 if (myFileInfo.fdType != 'SAVE') return noErr;
4235 /* XXX XXX XXX Extract a file name */
4236 PathNameFromDirID(myFSS.parID, myFSS.vRefNum, (StringPtr)savefile);
4237 pstrcat((StringPtr)savefile, (StringPtr)&myFSS.name);
4239 /* Convert the string */
4240 ptocstr((StringPtr)savefile);
4242 /* Delay actual open */
4243 open_when_ready = TRUE;
4246 err = AEDisposeDesc(&docList);
4258 * Macintosh modifiers (event.modifier & ccc):
4259 * cmdKey, optionKey, shiftKey, alphaLock, controlKey
4262 * Macintosh Keycodes (0-63 normal, 64-95 keypad, 96-127 extra):
4307 * Optimize non-blocking calls to "CheckEvents()"
4308 * Idea from "Maarten Hazewinkel <mmhazewi@cs.ruu.nl>"
4310 #define EVENT_TICKS 6
4314 * Check for Events, return TRUE if we process any
4316 * Hack -- Handle AppleEvents if appropriate (ignore result code).
4318 static bool CheckEvents(bool wait)
4334 term_data *td = NULL;
4338 static huge lastTicks = 0L;
4341 /* Access the clock */
4342 curTicks = TickCount();
4344 /* Hack -- Allow efficient checking for non-pending events */
4345 if (!wait && (curTicks < lastTicks + EVENT_TICKS)) return (FALSE);
4347 /* Timestamp last check */
4348 lastTicks = curTicks;
4350 /* Let the "system" run */
4353 /* Get an event (or null) */
4354 GetNextEvent(everyEvent, &event);
4356 /* Hack -- Nothing is ready yet */
4357 if (event.what == nullEvent) return (FALSE);
4360 /* Analyze the event */
4368 w = (WindowPtr)event.message;
4379 /* Extract the window */
4380 w = (WindowPtr)event.message;
4382 /* Find the window */
4383 for (i = 0; i < MAX_TERM_DATA; i++)
4385 /* Skip dead windows */
4386 if (!data[i].t) continue;
4388 /* Notice matches */
4389 if (data[i].w == w) td = &data[i];
4392 /* Hack XXX XXX XXX */
4396 /* Redraw the window */
4397 if (td) term_data_redraw(td);
4405 /* Extract some modifiers */
4406 mc = (event.modifiers & controlKey) ? TRUE : FALSE;
4407 ms = (event.modifiers & shiftKey) ? TRUE : FALSE;
4408 mo = (event.modifiers & optionKey) ? TRUE : FALSE;
4409 mx = (event.modifiers & cmdKey) ? TRUE : FALSE;
4411 /* Keypress: (only "valid" if ck < 96) */
4412 ch = (event.message & charCodeMask) & 255;
4414 /* Keycode: see table above */
4415 ck = ((event.message & keyCodeMask) >> 8) & 255;
4417 /* Command + "normal key" -> menu action */
4418 if (mx && (ck < 64))
4420 /* Hack -- Prepare the menus */
4423 /* Mega-Hack -- allow easy exit if nothing to save */
4424 /* if (!character_generated && (ch=='Q' || ch=='q')) ch = 'e'; */
4426 /* Run the Menu-Handler */
4429 /* Turn off the menus */
4437 /* Hide the mouse pointer */
4440 /* Normal key -> simple keypress */
4443 /* Enqueue the keypress */
4447 /* Hack -- normal "keypad keys" -> special keypress */
4448 else if (!mc && !ms && !mo && !mx && (ck < 96))
4450 /* Hack -- "enter" is confused */
4451 if (ck == 76) ch = '\n';
4453 /* Send control-caret as a trigger */
4456 /* Send the "ascii" keypress */
4460 /* Bizarre key -> encoded keypress */
4463 /* Hack -- introduce with control-underscore */
4466 /* Send some modifier keys */
4467 if (mc) Term_keypress('C');
4468 if (ms) Term_keypress('S');
4469 if (mo) Term_keypress('O');
4470 if (mx) Term_keypress('X');
4472 /* Hack -- Downshift and encode the keycode */
4473 Term_keypress('0' + (ck - 64) / 10);
4474 Term_keypress('0' + (ck - 64) % 10);
4476 /* Hack -- Terminate the sequence */
4487 /* Analyze click location */
4488 code = FindWindow(event.where, &w);
4490 /* Find the window */
4491 for (i = 0; i < MAX_TERM_DATA; i++)
4493 /* Skip dead windows */
4494 if (!data[i].t) continue;
4496 /* Notice matches */
4497 if (data[i].w == w) td = &data[i];
4506 menu(MenuSelect(event.where));
4513 SystemClick(&event, w);
4523 r = qd.screenBits.bounds;
4524 r.top += 20; /* GetMBarHeight() XXX XXX XXX */
4525 InsetRect(&r, 4, 4);
4526 DragWindow(w, event.where, &r);
4538 p.h = td->w->portRect.left;
4539 p.v = td->w->portRect.top;
4547 /* Apply and Verify */
4548 term_data_check_size(td);
4558 /* Track the go-away box */
4559 if (TrackGoAway(w, event.where))
4565 td->t->mapped_flag = FALSE;
4567 /* Hide the window */
4583 /* Fake rectangle */
4584 r.left = 20 * td->tile_wid + td->size_ow1;
4585 r.right = 80 * td->tile_wid + td->size_ow1 + td->size_ow2 + 1;
4586 r.top = 1 * td->tile_hgt + td->size_oh1;
4587 r.bottom = 24 * td->tile_hgt + td->size_oh1 + td->size_oh2 + 1;
4589 /* Grow the rectangle */
4590 newsize = GrowWindow(w, event.where, &r);
4593 if (!newsize) break;
4595 /* Extract the new size in pixels */
4596 y = HiWord(newsize) - td->size_oh1 - td->size_oh2;
4597 x = LoWord(newsize) - td->size_ow1 - td->size_ow2;
4599 /* Extract a "close" approximation */
4600 td->rows = y / td->tile_hgt;
4601 td->cols = x / td->tile_wid;
4603 /* Apply and Verify */
4604 term_data_check_size(td);
4607 Term_activate(td->t);
4609 /* Hack -- Resize the term */
4610 Term_resize(td->cols, td->rows);
4612 /* Resize and Redraw */
4613 term_data_resize(td);
4614 term_data_redraw(td);
4633 /* Disk Event -- From "Maarten Hazewinkel" */
4636 /* check for error when mounting the disk */
4637 if (HiWord(event.message) != noErr)
4643 DIBadMount(p, event.message);
4650 /* OS Event -- From "Maarten Hazewinkel" */
4653 switch ((event.message >> 24) & 0x000000FF)
4655 case suspendResumeMessage:
4657 /* Resuming: activate the front window */
4658 if (event.message & resumeFlag)
4660 SetPort(FrontWindow());
4661 SetCursor(&qd.arrow);
4664 /* Suspend: deactivate the front window */
4678 /* From "Steve Linberg" and "Maarten Hazewinkel" */
4679 case kHighLevelEvent:
4681 /* Process apple events */
4682 if (AEProcessAppleEvent(&event) != noErr)
4685 plog("Apple Event Handler¤Î¥¨¥é¡¼¤Ç¤¹.");
4687 plog("Error in Apple Event Handler!");
4691 /* Handle "quit_when_ready" */
4692 if (quit_when_ready)
4695 quit_when_ready = FALSE;
4697 /* Do the menu key */
4700 /* Turn off the menus */
4704 /* Handle "open_when_ready" */
4705 handle_open_when_ready();
4715 /* Something happened */
4722 /*** Some Hooks for various routines ***/
4726 * Mega-Hack -- emergency lifeboat
4728 static vptr lifeboat = NULL;
4732 * Hook to "release" memory
4734 static vptr hook_rnfree(vptr v, huge size)
4737 #pragma unused (size)
4741 /* Alternative method */
4756 * Hook to "allocate" memory
4758 static vptr hook_ralloc(huge size)
4763 /* Make a new pointer */
4764 return (malloc(size));
4768 /* Make a new pointer */
4769 return (NewPtr(size));
4776 * Hook to handle "out of memory" errors
4778 static vptr hook_rpanic(huge size)
4781 #pragma unused (size)
4785 /* Free the lifeboat */
4788 /* Free the lifeboat */
4789 DisposePtr(lifeboat);
4791 /* Forget the lifeboat */
4794 /* Mega-Hack -- Warning */
4796 mac_warning("¥á¥â¥ê¡¼¤¬Â¤ê¤Þ¤»¤ó!\rº£¤¹¤°½ªÎ»¤·¤Æ²¼¤µ¤¤!");
4798 mac_warning("Running out of Memory!\rAbort this process now!");
4801 /* Mega-Hack -- Never leave this function */
4802 while (TRUE) CheckEvents(TRUE);
4805 /* Mega-Hack -- Crash */
4811 * Hook to tell the user something important
4813 static void hook_plog(cptr str)
4815 /* Warning message */
4820 * Hook to tell the user something, and then quit
4822 static void hook_quit(cptr str)
4824 /* Warning if needed */
4825 if (str) mac_warning(str);
4827 /* Write a preference file */
4835 * Hook to tell the user something, and then crash
4837 static void hook_core(cptr str)
4839 /* XXX Use the debugger */
4840 /* DebugStr(str); */
4843 if (str) mac_warning(str);
4845 /* Warn, then save player */
4847 mac_warning("Ã×̿Ū¤Ê¥¨¥é¡¼¤Ç¤¹.\r¶¯À©Åª¤Ë¥»¡¼¥Ö¤·¤Æ½ªÎ»¤·¤Þ¤¹.");
4849 mac_warning("Fatal error.\rI will now attempt to save and quit.");
4852 /* Attempt to save */
4854 if (!save_player()) mac_warning("·Ù¹ð -- ¥»¡¼¥Ö¤Ë¼ºÇÔ¤·¤Þ¤·¤¿!");
4856 if (!save_player()) mac_warning("Warning -- save failed!");
4865 /*** Main program ***/
4871 * XXX XXX XXX Hack -- This function attempts to "fix" the nasty
4872 * "Macintosh Save Bug" by using "absolute" path names, since on
4873 * System 7 machines anyway, the "current working directory" often
4874 * "changes" due to background processes, invalidating any "relative"
4875 * path names. Note that the Macintosh is limited to 255 character
4876 * path names, so be careful about deeply embedded directories...
4878 * XXX XXX XXX Hack -- This function attempts to "fix" the nasty
4879 * "missing lib folder bug" by allowing the user to help find the
4880 * "lib" folder by hand if the "application folder" code fails...
4882 static void init_stuff(void)
4899 /* Fake rectangle */
4906 center_rect(&r, &qd.screenBits.bounds);
4908 /* Extract corner */
4913 /* Default to the "lib" folder with the application */
4914 refnum_to_name(path, app_dir, app_vol, (char*)("\plib:"));
4917 /* Check until done */
4920 /* Prepare the paths */
4921 init_file_paths(path);
4923 /* Build the filename */
4925 path_build(path, 1024, ANGBAND_DIR_FILE, "news_j.txt");
4927 path_build(path, 1024, ANGBAND_DIR_FILE, "news.txt");
4930 /* Attempt to open and close that file */
4931 if (0 == fd_close(fd_open(path, O_RDONLY))) break;
4935 plog_fmt("'%s' ¥Õ¥¡¥¤¥ë¤ò¥ª¡¼¥×¥ó½ÐÍè¤Þ¤»¤ó.", path);
4937 plog_fmt("Unable to open the '%s' file.", path);
4942 plog("Hengband¤Î'lib'¥Õ¥©¥ë¥À¤¬Â¸ºß¤·¤Ê¤¤¤«Àµ¤·¤¯Ìµ¤¤²ÄǽÀ¤¬¤¢¤ê¤Þ¤¹.");
4944 plog("The Angband 'lib' folder is probably missing or misplaced.");
4948 plog("Please 'open' any file in any sub-folder of the 'lib' folder.");
4950 /* Allow "text" files */
4953 /* Allow "save" files */
4956 /* Allow "data" files */
4960 SFGetFile(topleft, "\p", NULL, 3, types, NULL, &reply);
4963 if (!reply.good) quit(NULL);
4965 /* Extract textual file name for given file */
4966 GetWDInfo(reply.vRefNum, &vrefnum, &drefnum, &junk);
4967 refnum_to_name(path, drefnum, vrefnum, (char*)reply.fName);
4969 /* Hack -- Remove the "filename" */
4970 i = strlen(path) - 1;
4971 while ((i > 0) && (path[i] != ':')) i--;
4972 if (path[i] == ':') path[i+1] = '\0';
4974 /* Hack -- allow "lib" folders */
4975 if (suffix(path, "lib:")) continue;
4977 /* Hack -- Remove the "sub-folder" */
4979 while ((i > 1) && (path[i] != ':')) i--;
4980 if (path[i] == ':') path[i+1] = '\0';
4986 * Macintosh Main loop
4990 EventRecord tempEvent;
4991 int numberOfMasters = 10;
4993 /* Increase stack space by 64K */
4994 SetApplLimit(GetApplLimit() - 131072L);//65536L);
4996 /* Stretch out the heap to full size */
4999 /* Get more Masters */
5000 while (numberOfMasters--) MoreMasters();
5002 /* Set up the Macintosh */
5003 InitGraf(&qd.thePort);
5016 FlushEvents(everyEvent, 0);
5018 /* Flush events some more (?) */
5019 (void)EventAvail(everyEvent, &tempEvent);
5020 (void)EventAvail(everyEvent, &tempEvent);
5021 (void)EventAvail(everyEvent, &tempEvent);
5024 #ifdef ANGBAND_LITE_MAC
5028 #else /* ANGBAND_LITE_MAC */
5030 # if defined(powerc) || defined(__powerc)
5032 /* Assume System 7 */
5034 /* Assume Color Quickdraw */
5044 /* Check the Gestalt */
5045 err = Gestalt(gestaltSystemVersion, &versionNumber);
5047 /* Check the version */
5048 if ((err != noErr) || (versionNumber < 0x0700))
5051 quit("¤³¤Î¥×¥í¥°¥é¥à¤Ï´Á»úTalk7.x.x°Ê¹ß¤ÇÆ°ºî¤·¤Þ¤¹.");
5053 quit("You must have System 7 to use this program.");
5063 /* Check the environs */
5064 if (SysEnvirons(1, &env) != noErr)
5067 quit("SysEnvirons ¥³¡¼¥ë¤Ï¼ºÇÔ¤·¤Þ¤·¤¿¡ª");
5069 quit("The SysEnvirons call failed!");
5073 /* Check for System Seven Stuff */
5074 if (env.systemVersion < 0x0700)
5077 quit("¤³¤Î¥×¥í¥°¥é¥à¤Ï´Á»úTalk7.x.x°Ê¹ß¤ÇÆ°ºî¤·¤Þ¤¹.");
5079 quit("You must have System 7 to use this program.");
5083 /* Check for Color Quickdraw */
5084 if (!env.hasColorQD)
5087 quit("¤³¤Î¥×¥í¥°¥é¥à¤ÏColor Quickdraw¤¬Ìµ¤¤¤ÈÆ°ºî¤·¤Þ¤»¤ó.");
5089 quit("You must have Color Quickdraw to use this program.");
5096 #endif /* ANGBAND_LITE_MAC */
5101 /* Obtain a "Universal Procedure Pointer" */
5102 AEH_Start_UPP = NewAEEventHandlerProc(AEH_Start);
5104 /* Install the hook (ignore error codes) */
5105 AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, AEH_Start_UPP,
5108 /* Obtain a "Universal Procedure Pointer" */
5109 AEH_Quit_UPP = NewAEEventHandlerProc(AEH_Quit);
5111 /* Install the hook (ignore error codes) */
5112 AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, AEH_Quit_UPP,
5115 /* Obtain a "Universal Procedure Pointer" */
5116 AEH_Print_UPP = NewAEEventHandlerProc(AEH_Print);
5118 /* Install the hook (ignore error codes) */
5119 AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments, AEH_Print_UPP,
5122 /* Obtain a "Universal Procedure Pointer" */
5123 AEH_Open_UPP = NewAEEventHandlerProc(AEH_Open);
5125 /* Install the hook (ignore error codes) */
5126 AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, AEH_Open_UPP,
5132 /* Find the current application */
5136 /* Mark ourself as the file creator */
5139 /* Default to saving a "text" file */
5143 #if defined(__MWERKS__)
5145 /* Obtian a "Universal Procedure Pointer" */
5146 ynfilterUPP = NewModalFilterProc(ynfilter);
5151 /* Hook in some "z-virt.c" hooks */
5152 rnfree_aux = hook_rnfree;
5153 ralloc_aux = hook_ralloc;
5154 rpanic_aux = hook_rpanic;
5156 /* Hooks in some "z-util.c" hooks */
5157 plog_aux = hook_plog;
5158 quit_aux = hook_quit;
5159 core_aux = hook_core;
5161 BackColor(blackColor);
5162 ForeColor(whiteColor);
5164 /* Show the "watch" cursor */
5165 SetCursor(*(GetCursor(watchCursor)));
5167 /* Prepare the menubar */
5170 /* Prepare the windows */
5177 /* Hack -- process all events */
5178 while (CheckEvents(TRUE)) /* loop */;
5180 /* Reset the cursor */
5181 SetCursor(&qd.arrow);
5184 /* Mega-Hack -- Allocate a "lifeboat" */
5185 lifeboat = NewPtr(16384);
5187 /* Note the "system" */
5188 ANGBAND_SYS = "mac";
5189 ANGBAND_GRAF = "new";
5198 /* Hack -- process all events */
5199 while (CheckEvents(TRUE)) /* loop */;
5202 /* We are now initialized */
5206 /* Handle "open_when_ready" */
5207 handle_open_when_ready();
5213 /* Prompt the user */
5215 prt("'¥Õ¥¡¥¤¥ë'¥á¥Ë¥å¡¼¤è¤ê'¿·µ¬'¤Þ¤¿¤Ï'³«¤¯...'¤òÁªÂò¤·¤Æ¤¯¤À¤µ¤¤¡£", 23, 10);
5217 prt("[Choose 'New' or 'Open' from the 'File' menu]", 23, 15);
5220 /* Flush the prompt */
5224 /* Hack -- Process Events Forever */
5225 while (TRUE) CheckEvents(TRUE);