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 * Cleaning up a couple of things to make these easier to change --AR
168 #define PREF_FILE_NAME "Hengband Preferences"
170 #define PREF_FILE_NAME "Hengband-E Preferences"
174 * Use "malloc()" instead of "NewPtr()"
176 /* #define USE_MALLOC */
179 #if defined(powerc) || defined(__powerc)
182 * Disable "LITE" version
184 # undef ANGBAND_LITE_MAC
189 #ifdef ANGBAND_LITE_MAC
192 * Maximum number of windows
194 # define MAX_TERM_DATA 1
196 #else /* ANGBAND_LITE_MAC */
199 * Maximum number of windows
201 # define MAX_TERM_DATA 8
204 * Activate some special code
206 # define USE_SFL_CODE
208 #endif /* ANGBAND_LITE_MAC */
215 * Include the necessary header files
217 #include <AppleEvents.h>
225 * Globals for MPW compilation
239 * The Angband Color Set (0 to 15):
240 * Black, White, Slate, Orange, Red, Blue, Green, Umber
241 * D-Gray, L-Gray, Violet, Yellow, L-Red, L-Blue, L-Green, L-Umber
243 * Colors 8 to 15 are basically "enhanced" versions of Colors 0 to 7.
245 * On the Macintosh, we use color quickdraw, and we use actual "RGB"
246 * values below to choose the 16 colors.
248 * If we are compiled for ancient machines, we bypass color and simply
249 * draw everything in white (letting "z-term.c" automatically convert
250 * "black" into "wipe" calls).
252 static RGBColor foo[16] =
254 {0x0000, 0x0000, 0x0000}, /* TERM_DARK */
255 {0xFFFF, 0xFFFF, 0xFFFF}, /* TERM_WHITE */
256 {0x8080, 0x8080, 0x8080}, /* TERM_SLATE */
257 {0xFFFF, 0x8080, 0x0000}, /* TERM_ORANGE */
258 {0xC0C0, 0x0000, 0x0000}, /* TERM_RED */
259 {0x0000, 0x8080, 0x4040}, /* TERM_GREEN */
260 {0x0000, 0x0000, 0xFFFF}, /* TERM_BLUE */
261 {0x8080, 0x4040, 0x0000}, /* TERM_UMBER */
262 {0x4040, 0x4040, 0x4040}, /* TERM_L_DARK */
263 {0xC0C0, 0xC0C0, 0xC0C0}, /* TERM_L_WHITE */
264 {0xFFFF, 0x0000, 0xFFFF}, /* TERM_VIOLET */
265 {0xFFFF, 0xFFFF, 0x0000}, /* TERM_YELLOW */
266 {0xFFFF, 0x0000, 0x0000}, /* TERM_L_RED */
267 {0x0000, 0xFFFF, 0x0000}, /* TERM_L_GREEN */
268 {0x0000, 0xFFFF, 0xFFFF}, /* TERM_L_BLUE */
269 {0xC0C0, 0x8080, 0x4040} /* TERM_L_UMBER */
278 typedef struct term_data term_data;
291 #ifdef ANGBAND_LITE_MAC
295 #else /* ANGBAND_LITE_MAC */
307 #endif /* ANGBAND_LITE_MAC */
309 GWorldPtr bufferPort;
310 PixMapHandle bufferPixHndl;
354 * Forward declare -- see below
356 static bool CheckEvents(bool wait);
360 * Hack -- location of the main directory
362 static short app_vol;
367 * Delay handling of double-clicked savefiles
369 Boolean open_when_ready = FALSE;
372 * Delay handling of pre-emptive "quit" event
374 Boolean quit_when_ready = FALSE;
378 * Hack -- game in progress
380 static int game_in_progress = 0;
384 * Only do "SetPort()" when needed
386 static WindowPtr active = NULL;
391 * An array of term_data's
393 static term_data data[MAX_TERM_DATA];
398 * Note when "open"/"new" become valid
400 static bool initialized = FALSE;
405 * CodeWarrior uses Universal Procedure Pointers
407 static ModalFilterUPP ynfilterUPP;
414 AEEventHandlerUPP AEH_Start_UPP;
415 AEEventHandlerUPP AEH_Quit_UPP;
416 AEEventHandlerUPP AEH_Print_UPP;
417 AEEventHandlerUPP AEH_Open_UPP;
425 static int ext_sound = 0;
433 #define SND_CMD_ERROR 6
435 static int soundchoice[] = {
503 static int soundmode[8];
509 * Convert refnum+vrefnum+fname into a full file name
510 * Store this filename in 'buf' (make sure it is long enough)
511 * Note that 'fname' looks to be a "pascal" string
513 static void refnum_to_name(char *buf, long refnum, short vrefnum, char *fname)
525 for (j=1; j<=fname[0]; j++)
527 res[i-fname[0]+j] = fname[j];
531 pb.ioCompletion=NULL;
533 pb.ioVRefNum=vrefnum;
539 pb.ioDrDirID=pb.ioDrParID;
540 err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
542 for (j=1; j<=name[0]; j++)
544 res[i-name[0]+j] = name[j];
548 if (pb.ioDrDirID == fsRtDirID) break;
551 /* Extract the result */
552 for (j = 0, i++; res[i]; j++, i++) buf[j] = res[i];
560 * XXX XXX XXX Allow the system to ask us for a filename
562 static bool askfor_file(char *buf, int len)
570 /* Default file name */
571 sprintf((char*)dflt + 1, "%s's description", buf);
572 dflt[0] = strlen((char*)dflt + 1);
574 /* Ask for a file name */
575 topleft.h=(qd.screenBits.bounds.left+qd.screenBits.bounds.right)/2-344/2;
576 topleft.v=(2*qd.screenBits.bounds.top+qd.screenBits.bounds.bottom)/3-188/2;
577 SFPutFile(topleft, "\pSelect a filename:", dflt, NULL, &reply);
578 /* StandardPutFile("\pSelect a filename:", dflt, &reply); */
586 GetWDInfo(reply.vRefNum, &vrefnum, &drefnum, &junk);
588 /* Extract the name */
589 refnum_to_name(buf, drefnum, vrefnum, (char*)reply.fName);
604 * Center a rectangle inside another rectangle
606 static void center_rect(Rect *r, Rect *s)
608 int centerx = (s->left + s->right)/2;
609 int centery = (2*s->top + s->bottom)/3;
610 int dx = centerx - (r->right - r->left)/2 - r->left;
611 int dy = centery - (r->bottom - r->top)/2 - r->top;
620 * Convert a pascal string in place
622 * This function may be defined elsewhere, but since it is so
623 * small, it is not worth finding the proper function name for
624 * all the different platforms.
626 static void ptocstr(StringPtr src)
630 /* Hack -- pointer */
631 char *s = (char*)(src);
633 /* Hack -- convert the string */
634 for (i = s[0]; i; i--, s++) s[0] = s[1];
636 /* Hack -- terminate the string */
641 #if defined(USE_SFL_CODE)
645 * The following three routines (pstrcat, pstrinsert, and PathNameFromDirID)
646 * were taken from the Think Reference section called "Getting a Full Pathname"
647 * (under the File Manager section). We need PathNameFromDirID to get the
648 * full pathname of the opened savefile, making no assumptions about where it
651 * I had to hack PathNameFromDirID a little for MetroWerks, but it's awfully
654 static void pstrcat(StringPtr dst, StringPtr src)
657 BlockMove(src + 1, dst + *dst + 1, *src);
659 /* adjust length byte */
664 * pstrinsert - insert string 'src' at beginning of string 'dst'
666 static void pstrinsert(StringPtr dst, StringPtr src)
668 /* make room for new string */
669 BlockMove(dst + 1, dst + *src + 1, *dst);
671 /* copy new string in */
672 BlockMove(src + 1, dst + 1, *src);
674 /* adjust length byte */
678 static void PathNameFromDirID(long dirID, short vRefNum, StringPtr fullPathName)
681 Str255 directoryName;
684 fullPathName[0] = '\0';
686 block.dirInfo.ioDrParID = dirID;
687 block.dirInfo.ioNamePtr = directoryName;
691 block.dirInfo.ioVRefNum = vRefNum;
692 block.dirInfo.ioFDirIndex = -1;
693 block.dirInfo.ioDrDirID = block.dirInfo.ioDrParID;
694 err = PBGetCatInfo(&block, FALSE);
695 pstrcat(directoryName, (StringPtr)"\p:");
696 pstrinsert(fullPathName, directoryName);
697 if (block.dirInfo.ioDrDirID == 2) break;
706 * Activate a given window, if necessary
708 static void activate(WindowPtr w)
723 * Display a warning message
725 static void mac_warning(cptr warning)
730 /* Limit of 250 chars */
731 len = strlen(warning);
732 if (len > 250) len = 250;
734 /* Make a "Pascal" string */
736 for (i=0; i<len; i++) text[i+1] = warning[i];
738 /* Prepare the dialog box values */
739 ParamText(text, "\p", "\p", "\p");
741 /* Display the Alert, wait for Okay */
747 /*** Some generic functions ***/
750 #ifdef ANGBAND_LITE_MAC
753 * Hack -- activate a color (0 to 255)
755 #define term_data_color(TD,A) /* Nothing */
757 #else /* ANGBAND_LITE_MAC */
760 * Hack -- activate a color (0 to 255)
762 static void term_data_color(term_data *td, int a)
768 /* Extract the R,G,B data */
769 rv = angband_color_table[a][1];
770 gv = angband_color_table[a][2];
771 bv = angband_color_table[a][3];
774 color.red = (rv | (rv << 8));
775 color.green = (gv | (gv << 8));
776 color.blue = (bv | (bv << 8));
778 /* Activate the color */
779 RGBForeColor(&color);
785 #endif /* ANGBAND_LITE_MAC */
789 * Hack -- Apply and Verify the "font" info
791 * This should usually be followed by "term_data_check_size()"
793 static void term_data_check_font(term_data *td)
799 WindowPtr old = active;
805 /* Instantiate font */
806 TextFont(td->font_id);
807 TextSize(td->font_size);
808 TextFace(td->font_face);
810 /* Extract the font info */
813 /* Assume monospaced */
814 td->font_mono = TRUE;
816 /* Extract the font sizing values XXX XXX XXX */
817 td->font_wid = CharWidth('@'); /* info.widMax; */
818 td->font_hgt = info.ascent + info.descent;
820 td->font_o_y = info.ascent;
822 /* Check important characters */
823 for (i = 33; i < 127; i++)
825 /* Hack -- notice non-mono-space */
826 if (td->font_wid != CharWidth(i)) td->font_mono = FALSE;
828 /* Hack -- collect largest width */
829 if (td->font_wid < CharWidth(i)) td->font_wid = CharWidth(i);
832 /* Set default offsets */
833 td->tile_o_x = td->font_o_x;
834 td->tile_o_y = td->font_o_y;
836 /* Set default tile size */
837 if( td->tile_wid == 0 && td->tile_hgt == 0 ){
838 td->tile_wid = td->font_wid;
839 td->tile_hgt = td->font_hgt;
842 /* Re-activate the old window */
848 * Hack -- Apply and Verify the "size" info
850 static void term_data_check_size(term_data *td)
852 /* Minimal window size */
853 if (td->cols < 1) td->cols = 1;
854 if (td->rows < 1) td->rows = 1;
856 /* Minimal tile size */
857 if (td->tile_wid < 4) td->tile_wid = 4;
858 if (td->tile_hgt < 4) td->tile_hgt = 4;
860 /* Default tile offsets */
861 td->tile_o_x = (td->tile_wid - td->font_wid) / 2;
862 td->tile_o_y = (td->tile_hgt - td->font_hgt) / 2;
864 /* Minimal tile offsets */
865 if (td->tile_o_x < 0) td->tile_o_x = 0;
866 if (td->tile_o_y < 0) td->tile_o_y = 0;
868 /* Apply font offsets */
869 td->tile_o_x += td->font_o_x;
870 td->tile_o_y += td->font_o_y;
872 /* Calculate full window size */
873 td->size_wid = td->cols * td->tile_wid + td->size_ow1 + td->size_ow2;
874 td->size_hgt = td->rows * td->tile_hgt + td->size_oh1 + td->size_oh2;
877 if (td->r.top > qd.screenBits.bounds.bottom - td->size_hgt)
879 td->r.top = qd.screenBits.bounds.bottom - td->size_hgt;
883 if (td->r.top < qd.screenBits.bounds.top + 30)
885 td->r.top = qd.screenBits.bounds.top + 30;
888 /* Verify the left */
889 if (td->r.left > qd.screenBits.bounds.right - td->size_wid)
891 td->r.left = qd.screenBits.bounds.right - td->size_wid;
894 /* Verify the left */
895 if (td->r.left < qd.screenBits.bounds.left)
897 td->r.left = qd.screenBits.bounds.left;
900 /* Calculate bottom right corner */
901 td->r.right = td->r.left + td->size_wid;
902 td->r.bottom = td->r.top + td->size_hgt;
904 /* Assume no graphics */
905 td->t->always_pict = FALSE;
907 #ifdef ANGBAND_LITE_MAC
911 #else /* ANGBAND_LITE_MAC */
913 /* Handle graphics */
914 if (use_graphics && (td == &data[0]))
916 td->t->always_pict = TRUE;
919 #endif /* ANGBAND_LITE_MAC */
921 /* Fake mono-space */
922 if (!td->font_mono ||
923 (td->font_wid != td->tile_wid) ||
924 (td->font_hgt != td->tile_hgt))
926 /* Handle fake monospace */
927 td->t->always_pict = TRUE;
931 static OSErr XDDSWUpDateGWorldFromPict( term_data *td );
933 * Hack -- resize a term_data
935 * This should normally be followed by "term_data_resize()"
937 static void term_data_resize(term_data *td)
939 /* Actually resize the window */
940 SizeWindow(td->w, td->size_wid, td->size_hgt, 0);
942 XDDSWUpDateGWorldFromPict( td );
948 * Hack -- redraw a term_data
950 * Note that "Term_redraw()" calls "TERM_XTRA_CLEAR"
952 static void term_data_redraw(term_data *td)
956 /* Activate the term */
957 Term_activate(td->t);
959 /* Redraw the contents */
962 /* Flush the output */
965 /* Restore the old term */
968 /* No need to redraw */
969 ValidRect(&td->w->portRect);
975 #ifdef ANGBAND_LITE_MAC
979 #else /* ANGBAND_LITE_MAC */
986 #define kPictID 1001 /* Graf 'pict' resource */
988 #define kGrafWidth 8 /* Graf Size (X) */
989 #define kGrafHeight 8 /* Graf Size (Y) */
996 typedef struct FrameRec FrameRec;
1001 * - GWorld for the frame image
1002 * - Handle to pix map (saved for unlocking/locking)
1003 * - Pointer to color pix map (valid only while locked)
1007 GWorldPtr framePort;
1008 PixMapHandle framePixHndl;
1015 * The global picture data
1017 static FrameRec *frameP = NULL;
1023 static void BenSWLockFrame(FrameRec *srcFrameP)
1025 PixMapHandle pixMapH;
1027 pixMapH = GetGWorldPixMap(srcFrameP->framePort);
1028 (void)LockPixels(pixMapH);
1029 HLockHi((Handle)pixMapH);
1030 srcFrameP->framePixHndl = pixMapH;
1031 srcFrameP->framePix = (PixMapPtr)StripAddress(*(Handle)pixMapH);
1038 static void XDDSWLockFrame( term_data *td )
1040 PixMapHandle pixMapH;
1042 pixMapH = GetGWorldPixMap(td->bufferPort);
1043 (void)LockPixels(pixMapH);
1044 HLockHi((Handle)pixMapH);
1045 td->bufferPixHndl = pixMapH;
1046 td->bufferPix = (PixMapPtr)*(Handle)pixMapH;
1053 static void BenSWUnlockFrame(FrameRec *srcFrameP)
1055 if (srcFrameP->framePort != NULL)
1057 HUnlock((Handle)srcFrameP->framePixHndl);
1058 UnlockPixels(srcFrameP->framePixHndl);
1061 srcFrameP->framePix = NULL;
1068 static void XDDSWUnlockFrame( term_data *td )
1070 if (td->bufferPort != NULL)
1072 HUnlock((Handle)td->bufferPixHndl);
1073 UnlockPixels(td->bufferPixHndl);
1076 td->bufferPix = NULL;
1079 static OSErr BenSWCreateGWorldFromPict(
1080 GWorldPtr *pictGWorld,
1084 GWorldPtr saveGWorld;
1085 GDHandle saveGDevice;
1086 GWorldPtr tempGWorld;
1095 depth = data[0].pixelDepth;
1098 theGDH = data[0].theGDH;
1100 /* Obtain size rectangle */
1101 pictRect = (**pictH).picFrame;
1102 OffsetRect(&pictRect, -pictRect.left, -pictRect.top);
1104 /* Create a GWorld */
1105 err = NewGWorld(&tempGWorld, depth, &pictRect, nil,
1106 theGDH, noNewDevice);
1115 *pictGWorld = tempGWorld;
1118 GetGWorld(&saveGWorld, &saveGDevice);
1121 SetGWorld(tempGWorld, nil);
1123 /* Dump the pict into the GWorld */
1124 (void)LockPixels(GetGWorldPixMap(tempGWorld));
1125 EraseRect(&pictRect);
1126 DrawPicture(pictH, &pictRect);
1127 UnlockPixels(GetGWorldPixMap(tempGWorld));
1129 /* Restore GWorld */
1130 SetGWorld(saveGWorld, saveGDevice);
1137 static OSErr XDDSWCreateGWorldFromPict(
1138 GWorldPtr *pictGWorld,
1142 /* GWorldPtr saveGWorld;
1143 GDHandle saveGDevice;*/
1144 GWorldPtr tempGWorld;
1147 /* GDHandle theGDH; */
1155 /* depth = td->pixelDepth; */
1158 /* theGDH = td->theGDH; */
1160 /* Obtain size rectangle */
1162 pictRect.right = td->size_wid;
1164 pictRect.bottom = td->tile_hgt;
1166 /* Create a GWorld */
1167 err = NewGWorld(&tempGWorld, 0, &pictRect, 0, 0, 0);
1176 *pictGWorld = tempGWorld;
1179 /* GetGWorld(&saveGWorld, &saveGDevice); */
1182 /* SetGWorld(tempGWorld, nil); */
1184 /* Dump the pict into the GWorld */
1185 /* (void)LockPixels(GetGWorldPixMap(tempGWorld)); */
1186 /* EraseRect(&pictRect); */
1187 /* DrawPicture(pictH, &pictRect); */
1188 /* UnlockPixels(GetGWorldPixMap(tempGWorld)); */
1190 /* Restore GWorld */
1191 /* SetGWorld(saveGWorld, saveGDevice); */
1197 static OSErr XDDSWUpDateGWorldFromPict( term_data *td )
1199 /* GWorldPtr saveGWorld; */
1200 /* GDHandle saveGDevice; */
1203 /* GDHandle theGDH; */
1205 GWorldFlags errflag;
1209 if( td->bufferPort == NULL )
1212 /* depth = td->pixelDepth; */
1215 /* theGDH = td->theGDH; */
1217 /* Obtain size rectangle */
1220 pictRect.right = td->size_wid;
1221 pictRect.bottom = td->tile_hgt;
1223 XDDSWUnlockFrame(td);
1225 errflag = UpdateGWorld( &td->bufferPort, 0, &pictRect, 0, 0, 0);
1227 if( errflag & gwFlagErr ){
1233 /* GetGWorld(&saveGWorld, &saveGDevice); */
1236 /* SetGWorld(td->bufferPort, nil); */
1238 /* Dump the pict into the GWorld */
1239 /* (void)LockPixels(GetGWorldPixMap(td->bufferPort)); */
1240 /* EraseRect(&td->bufferPort->portRect); */
1242 /* UnlockPixels(GetGWorldPixMap(td->bufferPort)); */
1244 /* Restore GWorld */
1245 /* SetGWorld(saveGWorld, saveGDevice); */
1250 * Init the global "frameP"
1253 static errr globe_init(void)
1257 GWorldPtr tempPictGWorldP;
1261 /* Use window XXX XXX XXX */
1265 /* Get the pict resource */
1266 newPictH = GetPicture(kPictID);
1268 /* Analyze result */
1269 err = (newPictH ? 0 : -1);
1276 err = BenSWCreateGWorldFromPict(&tempPictGWorldP, newPictH);
1278 /* Release resource */
1279 ReleaseResource((Handle)newPictH);
1284 /* Create the frame */
1285 frameP = (FrameRec*)NewPtrClear((Size)sizeof(FrameRec));
1287 /* Analyze result */
1288 err = (frameP ? 0 : -1);
1294 frameP->framePort = tempPictGWorldP;
1297 BenSWLockFrame(frameP);
1308 * Nuke the global "frameP"
1310 static errr globe_nuke(void)
1316 BenSWUnlockFrame(frameP);
1318 /* Dispose of the GWorld */
1319 DisposeGWorld(frameP->framePort);
1321 /* Dispose of the memory */
1322 DisposePtr((Ptr)frameP);
1329 FlushEvents(everyEvent, 0);
1336 #endif /* ANGBAND_LITE_MAC */
1340 /*** Support for the "z-term.c" package ***/
1344 * Initialize a new Term
1346 * Note also the "window type" called "noGrowDocProc", which might be more
1347 * appropriate for the main "screen" window.
1349 * Note the use of "srcCopy" mode for optimized screen writes.
1351 static void Term_init_mac(term *t)
1353 term_data *td = (term_data*)(t->data);
1355 static RGBColor black = {0x0000,0x0000,0x0000};
1356 static RGBColor white = {0xFFFF,0xFFFF,0xFFFF};
1358 #ifdef ANGBAND_LITE_MAC
1360 /* Make the window */
1361 td->w = NewWindow(0, &td->r, td->title, 0, noGrowDocProc, (WindowPtr)-1, 1, 0L);
1363 #else /* ANGBAND_LITE_MAC */
1365 /* Make the window */
1366 td->w = NewCWindow(0, &td->r, td->title, 0, documentProc, (WindowPtr)-1, 1, 0L);
1368 #endif /* ANGBAND_LITE_MAC */
1370 /* Activate the window */
1373 /* Erase behind words */
1376 /* Apply and Verify */
1377 term_data_check_font(td);
1378 term_data_check_size(td);
1380 /* Resize the window */
1381 term_data_resize(td);
1383 #ifdef ANGBAND_LITE_MAC
1385 /* Prepare the colors (base colors) */
1386 BackColor(blackColor);
1387 ForeColor(whiteColor);
1389 #else /* ANGBAND_LITE_MAC */
1391 /* Prepare the colors (real colors) */
1392 RGBBackColor(&black);
1393 RGBForeColor(&white);
1400 GDHandle currentGDH;
1401 GWorldPtr windowGWorld;
1402 PixMapHandle basePixMap;
1404 /* Obtain the rect */
1405 tempRect = td->w->portRect;
1407 /* Obtain the global rect */
1408 globalRect = tempRect;
1409 LocalToGlobal((Point*)&globalRect.top);
1410 LocalToGlobal((Point*)&globalRect.bottom);
1412 /* Obtain the proper GDH */
1413 mainGDH = GetMaxDevice(&globalRect);
1415 /* Extract GWorld and GDH */
1416 GetGWorld(&windowGWorld, ¤tGDH);
1418 /* Obtain base pixmap */
1419 basePixMap = (**mainGDH).gdPMap;
1421 /* Save pixel depth */
1422 td->pixelDepth = (**basePixMap).pixelSize;
1424 /* Save Window GWorld */
1425 td->theGWorld = windowGWorld;
1427 /* Save Window GDH */
1428 td->theGDH = currentGDH;
1431 td->mainSWGDH = mainGDH;
1434 #endif /* ANGBAND_LITE_MAC */
1436 /* Clip to the window */
1437 ClipRect(&td->w->portRect);
1439 /* Erase the window */
1440 EraseRect(&td->w->portRect);
1442 /* Invalidate the window */
1443 InvalRect(&td->w->portRect);
1445 /* Display the window if needed */
1446 if (td->mapped) ShowWindow(td->w);
1448 /* Hack -- set "mapped" flag */
1449 t->mapped_flag = td->mapped;
1453 XDDSWCreateGWorldFromPict( &td->bufferPort, td );
1455 XDDSWLockFrame( td );
1457 /* if (err == noErr)
1468 static void Term_nuke_mac(term *t)
1481 static errr Term_user_mac(int n)
1495 static errr Term_xtra_mac_react(void)
1497 term_data *td = (term_data*)(Term->data);
1503 #ifdef ANGBAND_LITE_MAC
1507 #else /* ANGBAND_LITE_MAC */
1510 if (use_sound != arg_sound)
1513 use_sound = arg_sound;
1516 /* Handle graphics */
1517 if ((td == &data[0]) && (use_graphics != arg_graphics))
1519 /* Initialize graphics */
1521 if (!use_graphics && !frameP && (globe_init() != 0))
1524 plog("¥°¥é¥Õ¥£¥Ã¥¯¤Î½é´ü²½¤Ï½ÐÍè¤Þ¤»¤ó¤Ç¤·¤¿.");
1526 plog("Cannot initialize graphics!");
1528 arg_graphics = FALSE;
1532 use_graphics = arg_graphics;
1534 /* Apply and Verify */
1535 term_data_check_size(td);
1537 /* Resize the window */
1538 term_data_resize(td);
1544 #endif /* ANGBAND_LITE_MAC */
1552 * Do a "special thing"
1554 static errr Term_xtra_mac(int n, int v)
1556 term_data *td = (term_data*)(Term->data);
1564 case TERM_XTRA_NOISE:
1573 #ifdef ANGBAND_LITE_MAC
1577 #else /* ANGBAND_LITE_MAC */
1580 case TERM_XTRA_SOUND:
1590 /* Open the resource file */
1591 oldResFile = CurResFile();
1592 newResFile = OpenResFile(sound);
1594 /* Close the resource file */
1595 CloseResFile(newResFile);
1596 UseResFile(oldResFile);
1599 /* Get the proper sound name */
1600 sprintf((char*)sound + 1, "%.16s.wav", angband_sound_name[v]);
1601 sound[0] = strlen((char*)sound + 1);
1603 /* Obtain resource XXX XXX XXX */
1604 handle = Get1NamedResource('snd ', sound);
1605 if( handle == NULL || ext_sound )
1606 handle = GetNamedResource('snd ', sound);
1609 if (handle && soundmode[soundchoice[v]] == true)
1612 LoadResource(handle);
1615 /* Play sound (wait for completion) */
1616 SndPlay(nil, (SndListHandle)handle, true);
1618 /* Unlock and release */
1620 ReleaseResource(handle);
1626 #endif /* ANGBAND_LITE_MAC */
1628 /* Process random events */
1629 case TERM_XTRA_BORED:
1631 /* Process an event */
1632 (void)CheckEvents(0);
1638 /* Process pending events */
1639 case TERM_XTRA_EVENT:
1641 /* Process an event */
1642 (void)CheckEvents(v);
1648 /* Flush all pending events (if any) */
1649 case TERM_XTRA_FLUSH:
1651 /* Hack -- flush all events */
1652 while (CheckEvents(TRUE)) /* loop */;
1658 /* Hack -- Change the "soft level" */
1659 case TERM_XTRA_LEVEL:
1661 /* Activate if requested */
1662 if (v) activate(td->w);
1668 /* Clear the screen */
1669 case TERM_XTRA_CLEAR:
1671 /* No clipping XXX XXX XXX */
1672 ClipRect(&td->w->portRect);
1674 /* Erase the window */
1675 EraseRect(&td->w->portRect);
1678 term_data_color(td, TERM_WHITE);
1680 /* Frame the window in white */
1682 LineTo(0, td->size_hgt-1);
1683 LineTo(td->size_wid-1, td->size_hgt-1);
1684 LineTo(td->size_wid-1, 0);
1686 /* Clip to the new size */
1687 r.left = td->w->portRect.left + td->size_ow1;
1688 r.top = td->w->portRect.top + td->size_oh1;
1689 r.right = td->w->portRect.right - td->size_ow2;
1690 r.bottom = td->w->portRect.bottom - td->size_oh2;
1697 /* React to changes */
1698 case TERM_XTRA_REACT:
1700 /* React to changes */
1701 return (Term_xtra_mac_react());
1704 /* Delay (milliseconds) */
1705 case TERM_XTRA_DELAY:
1710 long m = TickCount() + (v * 60L) / 1000;
1713 while (TickCount() < m) /* loop */;
1728 * Low level graphics (Assumes valid input).
1729 * Draw a "cursor" at (x,y), using a "yellow box".
1730 * We are allowed to use "Term_grab()" to determine
1731 * the current screen contents (for inverting, etc).
1733 static errr Term_curs_mac(int x, int y)
1737 term_data *td = (term_data*)(Term->data);
1740 term_data_color(td, TERM_YELLOW);
1742 /* Frame the grid */
1743 r.left = x * td->tile_wid + td->size_ow1;
1744 r.right = r.left + td->tile_wid;
1745 r.top = y * td->tile_hgt + td->size_oh1;
1746 r.bottom = r.top + td->tile_hgt;
1755 * Low level graphics (Assumes valid input)
1757 * Erase "n" characters starting at (x,y)
1759 static errr Term_wipe_mac(int x, int y, int n)
1763 term_data *td = (term_data*)(Term->data);
1765 /* Erase the block of characters */
1766 r.left = x * td->tile_wid + td->size_ow1;
1767 r.right = r.left + n * td->tile_wid;
1768 r.top = y * td->tile_hgt + td->size_oh1;
1769 r.bottom = r.top + td->tile_hgt;
1778 * Low level graphics. Assumes valid input.
1780 * Draw several ("n") chars, with an attr, at a given location.
1782 static errr Term_text_mac(int x, int y, int n, byte a, const char *cp)
1786 term_data *td = (term_data*)(Term->data);
1789 term_data_color(td, (a & 0x0F));
1791 /* Starting pixel */
1792 xp = x * td->tile_wid + td->tile_o_x + td->size_ow1;
1793 yp = y * td->tile_hgt + td->tile_o_y + td->size_oh1;
1795 /* Move to the correct location */
1798 /* Draw the character */
1799 if (n == 1) DrawChar(*cp);
1801 /* Draw the string */
1802 else DrawText(cp, 0, n);
1810 * Low level graphics (Assumes valid input)
1812 * Erase "n" characters starting at (x,y)
1814 static errr Term_pict_mac(int x, int y, int n, const byte *ap, const char *cp)
1818 bool use_buffer = false;
1819 term_data *td = (term_data*)(Term->data);
1820 GDHandle saveGDevice;
1821 GWorldPtr saveGWorld;
1823 PixMapHandle PortPix;
1827 GetGWorld(&saveGWorld, &saveGDevice);
1831 /* Destination rectangle */
1832 r2.left = x * td->tile_wid + td->size_ow1;
1833 r2.right = r2.left + td->tile_wid;
1835 r2.bottom = r2.top + td->tile_hgt;
1838 SetGWorld(td->bufferPort, nil);
1839 PortPix = GetGWorldPixMap(td->bufferPort );
1840 LockPixels( PortPix );
1842 /* Instantiate font */
1843 TextFont(td->font_id);
1844 TextSize(td->font_size);
1845 TextFace(td->font_face);
1847 /* Restore colors */
1848 BackColor(blackColor);
1849 ForeColor(whiteColor);
1852 EraseRect(&td->bufferPort->portRect);
1858 /* Destination rectangle */
1859 r2.left = x * td->tile_wid + td->size_ow1;
1860 r2.right = r2.left + td->tile_wid;
1861 r2.top = y * td->tile_hgt + td->size_oh1;
1862 r2.bottom = r2.top + td->tile_hgt;
1864 /* no buffering, so we use the normal current port */
1869 /* Scan the input */
1870 for (i = 0; i < n; i++)
1877 #ifdef ANGBAND_LITE_MAC
1881 #else /* ANGBAND_LITE_MAC */
1883 /* Graphics -- if Available and Needed */
1884 if (use_graphics && ((td == &data[0]) || (td == &data[6])) &&
1885 ((byte)a & 0x80) && ((byte)c & 0x80))
1891 row = ((byte)a & 0x7F);
1892 col = ((byte)c & 0x7F);
1894 /* Source rectangle */
1895 r1.left = col * kGrafWidth;
1896 r1.top = row * kGrafHeight;
1897 r1.right = r1.left + kGrafWidth;
1898 r1.bottom = r1.top + kGrafHeight;
1900 /* Hardwire CopyBits */
1901 BackColor(whiteColor);
1902 ForeColor(blackColor);
1904 /* Draw the picture */
1906 BitMapPtr srcBitMap = (BitMapPtr)(frameP->framePix);
1907 BitMapPtr destBitMap;
1911 destBitMap = (BitMapPtr)(td->bufferPix);
1915 destBitMap = (BitMapPtr)&(td->w->portBits);
1918 /* draw transparent tile */
1919 /* BackColor is ignored and the destination is left untouched */
1920 BackColor(blackColor);
1921 CopyBits( srcBitMap, destBitMap, &r1, &r2, transparent, NULL );
1923 /* Restore colors */
1924 BackColor(blackColor);
1925 ForeColor(whiteColor);
1934 #endif /* ANGBAND_LITE_MAC */
1945 term_data_color(td, (a & 0x0F));
1947 /* Starting pixel */
1948 xp = r2.left + td->tile_o_x;
1949 yp = r2.top + td->tile_o_y;
1951 /* Move to the correct location */
1954 /* Draw the character */
1958 term_data_color(td, (a & 0x0F));
1960 /* Starting pixel */
1961 xp = r2.left + td->tile_o_x;
1964 /* Move to the correct location */
1968 /* Draw the character */
1973 r2.left += td->tile_wid;
1974 r2.right += td->tile_wid;
1976 /* Draw the character */
1983 r2.left += td->tile_wid;
1984 r2.right += td->tile_wid;
1989 /* Now we blast the buffer pixmap onto the screen in the right place */
1990 BitMapPtr srcBitMap = (BitMapPtr)(td->bufferPix);
1992 BitMapPtr destBitMap = (BitMapPtr)&(td->w->portBits);
1998 srcRect.left = x * td->tile_wid + td->size_ow1;
2000 srcRect.right = srcRect.left + (td->tile_wid * n);
2001 srcRect.bottom = td->tile_hgt;
2003 destRect.left = x * td->tile_wid + td->size_ow1;
2004 destRect.right = destRect.left + (td->tile_wid * n);
2005 destRect.top = y * td->tile_hgt + td->size_oh1;
2006 destRect.bottom = destRect.top + td->tile_hgt;
2008 UnlockPixels( PortPix );
2010 /* Restore GWorld */
2011 SetGWorld(saveGWorld, saveGDevice);
2013 /* Hardwire CopyBits */
2014 BackColor(whiteColor);
2015 ForeColor(blackColor);
2017 //CopyBits( srcBitMap, destBitMap, &srcRect, &destRect, srcCopy, NULL );
2018 CopyBits( (BitMapPtr)(td->bufferPix)
2019 , &(td->w->portBits), &srcRect, &destRect, srcCopy, NULL );
2021 /* Restore colors */
2022 BackColor(blackColor);
2023 ForeColor(whiteColor);
2036 * Create and initialize window number "i"
2038 static void term_data_link(int i)
2042 term_data *td = &data[i];
2047 /* Require mapped */
2048 if (!td->mapped) return;
2053 /* Initialize the term */
2054 term_init(td->t, td->cols, td->rows, td->keys);
2056 /* Use a "software" cursor */
2057 td->t->soft_cursor = TRUE;
2059 /* Erase with "white space" */
2060 td->t->attr_blank = TERM_WHITE;
2061 td->t->char_blank = ' ';
2063 /* Prepare the init/nuke hooks */
2064 td->t->init_hook = Term_init_mac;
2065 td->t->nuke_hook = Term_nuke_mac;
2067 /* Prepare the function hooks */
2068 td->t->user_hook = Term_user_mac;
2069 td->t->xtra_hook = Term_xtra_mac;
2070 td->t->wipe_hook = Term_wipe_mac;
2071 td->t->curs_hook = Term_curs_mac;
2072 td->t->text_hook = Term_text_mac;
2073 td->t->pict_hook = Term_pict_mac;
2075 /* Link the local structure */
2076 td->t->data = (vptr)(td);
2079 Term_activate(td->t);
2081 /* Global pointer */
2082 angband_term[i] = td->t;
2092 * Set the "current working directory" (also known as the "default"
2093 * volume/directory) to the location of the current application.
2095 * Code by: Maarten Hazewinkel (mmhazewi@cs.ruu.nl)
2097 * This function does not appear to work correctly with System 6.
2099 static void SetupAppDir(void)
2103 char errString[100];
2105 /* Get the location of the Angband executable */
2106 fcbBlock.ioCompletion = NULL;
2107 fcbBlock.ioNamePtr = NULL;
2108 fcbBlock.ioVRefNum = 0;
2109 fcbBlock.ioRefNum = CurResFile();
2110 fcbBlock.ioFCBIndx = 0;
2111 err = PBGetFCBInfo(&fcbBlock, FALSE);
2115 sprintf(errString, "PBGetFCBInfo ¥¨¥é¡¼ #%d.\r ½ªÎ»¤·¤Þ¤¹.", err);
2117 sprintf(errString, "Fatal PBGetFCBInfo Error #%d.\r Exiting.", err);
2119 mac_warning(errString);
2123 /* Extract the Vol and Dir */
2124 app_vol = fcbBlock.ioFCBVRefNum;
2125 app_dir = fcbBlock.ioFCBParID;
2127 /* Set the current working directory to that location */
2128 err = HSetVol(NULL, app_vol, app_dir);
2132 sprintf(errString, "HSetVol ¥¨¥é¡¼ #%d.\r ½ªÎ»¤·¤Þ¤¹.", err);
2134 sprintf(errString, "Fatal HSetVol Error #%d.\r Exiting.", err);
2136 mac_warning(errString);
2145 * Global "preference" file pointer
2150 * Read a "short" from the file
2152 static int getshort(void)
2156 if (0 == my_fgets(fff, buf, 256)) x = atoi(buf);
2161 * Dump a "short" to the file
2163 static void putshort(int x)
2165 fprintf(fff, "%d\n", x);
2171 * Write the "preference" data to the current "file"
2173 static void save_prefs(void)
2180 /*** The current version ***/
2182 putshort(VERSION_MAJOR);
2183 putshort(VERSION_MINOR);
2184 putshort(VERSION_PATCH);
2185 putshort(VERSION_EXTRA);
2187 putshort(arg_sound);
2188 putshort(arg_graphics);
2191 for( i = 0 ; i < 7 ; i++ )
2192 putshort(soundmode[i]);
2195 for (i = 0; i < MAX_TERM_DATA; i++)
2200 putshort(td->mapped);
2202 putshort(td->font_id);
2203 putshort(td->font_size);
2204 putshort(td->font_face);
2206 putshort(td->tile_wid);
2207 putshort(td->tile_hgt);
2212 putshort(td->r.left);
2213 putshort(td->r.top);
2219 * Load the preferences from the current "file"
2221 * XXX XXX XXX Being able to undefine various windows is
2222 * slightly bizarre, and may cause problems.
2224 static void load_prefs(void)
2228 int old_major, old_minor, old_patch, old_extra;
2233 /*** Version information ***/
2235 /* Preferences version */
2236 old_major = getshort();
2237 old_minor = getshort();
2238 old_patch = getshort();
2239 old_extra = getshort();
2241 /* Hack -- Verify or ignore */
2242 if ((old_major != VERSION_MAJOR) ||
2243 (old_minor != VERSION_MINOR) ||
2244 (old_patch != VERSION_PATCH) ||
2245 (old_extra != VERSION_EXTRA))
2249 mac_warning("¸Å¤¤½é´üÀßÄê¥Õ¥¡¥¤¥ë¤ò̵»ë¤·¤Þ¤¹.");
2251 mac_warning("Ignoring old preferences.");
2257 arg_sound = getshort();
2258 arg_graphics = getshort();
2261 for( i = 0 ; i < 7 ; i++ )
2262 soundmode[i] = getshort();
2265 m = GetMenuHandle(134); //m = GetMHandle(134);
2267 /* Item "arg_sound" */
2268 CheckItem(m, 1, arg_sound);
2270 /* Item "arg_graphics" */
2271 CheckItem(m, 2, arg_graphics);
2274 for (i = 0; i < MAX_TERM_DATA; i++)
2279 td->mapped = getshort();
2281 td->font_id = getshort();
2282 td->font_size = getshort();
2283 td->font_face = getshort();
2285 td->tile_wid = getshort();
2286 td->tile_hgt = getshort();
2288 td->cols = getshort();
2289 td->rows = getshort();
2291 td->r.left = getshort();
2292 td->r.top = getshort();
2295 if (feof(fff)) break;
2303 * Hack -- default data for a window
2305 static void term_data_hack(term_data *td)
2310 GetFNum( "\pÅùÉýÌÀÄ«", &fid); /* ¥Õ¥©¥ó¥È̾¤«¤éIDÈÖ¹æ¤òÄ´¤Ù¤ë */
2311 SetFScaleDisable( true );
2313 /* Default to Monaco font */
2314 GetFNum("\pmonaco", &fid);
2317 WIPE(td, term_data);
2322 /* Default borders */
2333 /* Default font size */
2336 /* Default font face */
2343 /* Default position */
2353 * Read the preference file, Create the windows.
2355 * We attempt to use "FindFolder()" to track down the preference file,
2356 * but if this fails, for any reason, we will try the "SysEnvirons()"
2357 * method, which may work better with System 6.
2359 static void init_windows(void)
2372 /*** Default values ***/
2374 /* Initialize (backwards) */
2375 for (i = MAX_TERM_DATA - 1; i >= 0; i--)
2388 s = angband_term_name[i];
2393 /* Maximal length */
2396 /* Copy the title */
2397 strncpy((char*)(td->title) + 1, s, n);
2399 /* Save the length */
2402 /* Tile the windows */
2403 td->r.left += (b * 30);
2404 td->r.top += (b * 30);
2411 /*** Load preferences ***/
2413 /* Assume failure */
2416 /* Assume failure */
2429 /* Find the folder */
2430 err = FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder,
2436 /* Extract a path name */
2437 PathNameFromDirID(dirID, vref, (StringPtr)foo);
2439 /* Convert the string */
2440 ptocstr((StringPtr)foo);
2442 /* Append the preference file name */
2443 strcat(foo, PREF_FILE_NAME);
2445 /* Open the preference file */
2446 fff = fopen(foo, "r");
2453 #endif /* USE_SFL_CODE */
2459 HGetVol(0, &savev, &saved);
2461 /* Go to the "system" folder */
2462 SysEnvirons(curSysEnvVers, &env);
2463 SetVol(0, env.sysVRefNum);
2466 fff = fopen(PREF_FILE_NAME, "r");
2469 HSetVol(0, savev, saved);
2472 /* Load preferences */
2475 /* Load a real preference file */
2478 /* Close the file */
2483 /*** Instantiate ***/
2494 /* Link (backwards, for stacking order) */
2495 for (i = MAX_TERM_DATA - 1; i >= 0; i--)
2504 Term_activate(td->t);
2507 static void init_sound( void )
2511 SignedByte permission = fsRdPerm;
2517 /* Descend into "lib" folder */
2518 pb.ioCompletion = NULL;
2519 pb.ioNamePtr = "\plib";
2520 pb.ioVRefNum = app_vol;
2521 pb.ioDrDirID = app_dir;
2524 /* Check for errors */
2525 err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
2528 if ((err == noErr) && (pb.ioFlAttrib & 0x10))
2530 /* Descend into "lib/save" folder */
2531 pb.ioCompletion = NULL;
2532 pb.ioNamePtr = "\pxtra";
2533 pb.ioVRefNum = app_vol;
2534 pb.ioDrDirID = pb.ioDrDirID;
2537 /* Check for errors */
2538 err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
2541 if ((err == noErr) && (pb.ioFlAttrib & 0x10))
2543 /* Descend into "lib/save" folder */
2544 pb.ioCompletion = NULL;
2545 pb.ioNamePtr = "\psound";
2546 pb.ioVRefNum = app_vol;
2547 pb.ioDrDirID = pb.ioDrDirID;
2550 /* Check for errors */
2551 err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
2554 if ((err == noErr) && (pb.ioFlAttrib & 0x10))
2556 ret = HOpenResFile( app_vol , pb.ioDrDirID , "\psound.rsrc" , permission );
2560 for( i = 0 ; i < 7 ; i++ )
2561 soundmode[i] = false;
2563 for( i = 1 ; i < SOUND_MAX ; i++ ){
2564 /* Get the proper sound name */
2565 sprintf((char*)sound + 1, "%.16s.wav", angband_sound_name[i]);
2566 sound[0] = strlen((char*)sound + 1);
2568 /* Obtain resource XXX XXX XXX */
2569 handle = Get1NamedResource('snd ', sound);
2570 if( handle == NULL || ext_sound )
2571 handle = GetNamedResource('snd ', sound);
2574 soundmode[soundchoice[i]] = true;
2587 static void init_chuukei( void )
2593 path_build(path, 1024, ANGBAND_DIR_XTRA, "chuukei.txt");
2595 fp = fopen(path, "r");
2600 if (fgets(tmp, 1024, fp)){
2602 int n = strlen(tmp);
2608 chuukei_server = TRUE;
2609 if(connect_chuukei_server(&tmp[2])<0){
2610 msg_print("connect fail");
2613 msg_print("connect");
2620 chuukei_client = TRUE;
2621 connect_chuukei_server(&tmp[2]);
2637 short InevrtCheck( DialogPtr targetDlg, short check )
2644 GetDialogItem( targetDlg, check, &itemType, &checkH, &box );
2645 result = (GetControlValue( (ControlHandle)checkH ) + 1 ) % 2;
2646 SetControlValue( (ControlHandle)checkH , result );
2654 short SetCheck( DialogPtr targetDlg, short check, long result )
2661 GetDialogItem( targetDlg, check, &itemType, &checkH, &box );
2662 SetControlValue( (ControlHandle)checkH , result );
2670 short GetCheck( DialogPtr targetDlg, short check )
2677 GetDialogItem( targetDlg, check, &itemType, &checkH, &box );
2678 result = GetControlValue( (ControlHandle)checkH );
2682 void SoundConfigDLog(void)
2689 dialog=GetNewDialog(131, 0, (WindowPtr)-1);
2690 SetDialogDefaultItem( dialog, ok );
2691 SetDialogCancelItem( dialog, cancel );
2692 for( i = 1 ; i < 7 ; i++ )
2693 SetCheck( dialog, i+2 , soundmode[i] );
2696 for( item_hit = 100 ; cancel < item_hit ; ){
2697 ModalDialog(0, &item_hit);
2701 for( i = 1 ; i < 7 ; i++ )
2702 soundmode[i] = GetCheck( dialog, i+2 );
2707 InevrtCheck( dialog, item_hit );
2710 DisposeDialog(dialog);
2718 static void save_pref_file(void)
2727 /* Assume failure */
2730 /* Assume failure */
2747 /* Find the folder */
2748 err = FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder,
2754 /* Extract a path name */
2755 PathNameFromDirID(dirID, vref, (StringPtr)foo);
2757 /* Convert the string */
2758 ptocstr((StringPtr)foo);
2760 /* Append the preference file name */
2761 strcat(foo, PREF_FILE_NAME);
2763 /* Open the preference file */
2764 /* my_fopen set file type and file creator for MPW */
2765 fff = my_fopen(foo, "w");
2772 #endif /* USE_SFL_CODE */
2778 HGetVol(0, &savev, &saved);
2780 /* Go to "system" folder */
2781 SysEnvirons(curSysEnvVers, &env);
2782 SetVol(0, env.sysVRefNum);
2784 /* Open the preference file */
2785 /* my_fopen set file type and file creator for MPW */
2786 fff = fopen(PREF_FILE_NAME, "w");
2789 HSetVol(0, savev, saved);
2792 /* Save preferences */
2795 /* Write the preferences */
2806 * A simple "Yes/No" filter to parse "key press" events in dialog windows
2808 static pascal Boolean ynfilter(DialogPtr dialog, EventRecord *event, short *ip)
2810 /* Parse key press events */
2811 if (event->what == keyDown)
2816 /* Extract the pressed key */
2817 c = (event->message & charCodeMask);
2819 /* Accept "no" and <return> and <enter> */
2820 if ((c=='n') || (c=='N') || (c==13) || (c==3)) i = 1;
2823 else if ((c=='y') || (c=='Y')) i = 2;
2825 /* Handle "yes" or "no" */
2829 ControlHandle control;
2832 /* Get the button */
2833 GetDialogItem(dialog, i, &type, (Handle*)&control, &r); //GetDItem(dialog, i, &type, (Handle*)&control, &r);
2835 /* Blink button for 1/10 second */
2836 HiliteControl(control, 1);
2837 Term_xtra_mac(TERM_XTRA_DELAY, 100);
2838 HiliteControl(control, 0);
2852 * Handle menu: "File" + "New"
2854 static void do_menu_file_new(void)
2859 /* Game is in progress */
2860 game_in_progress = 1;
2874 * Handle menu: "File" + "Open"
2876 static void do_menu_file_open(bool all)
2890 /* vrefnum = GetSFCurVol(); */
2891 vrefnum = -*((short*)0x214);
2893 /* drefnum = GetSFCurDir(); */
2894 drefnum = *((long*)0x398);
2896 /* Descend into "lib" folder */
2897 pb.ioCompletion = NULL;
2898 pb.ioNamePtr = "\plib";
2899 pb.ioVRefNum = vrefnum;
2900 pb.ioDrDirID = drefnum;
2903 /* Check for errors */
2904 err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
2907 if ((err == noErr) && (pb.ioFlAttrib & 0x10))
2909 /* Descend into "lib/save" folder */
2910 pb.ioCompletion = NULL;
2911 pb.ioNamePtr = "\psave";
2912 pb.ioVRefNum = vrefnum;
2913 pb.ioDrDirID = pb.ioDrDirID;
2916 /* Check for errors */
2917 err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
2920 if ((err == noErr) && (pb.ioFlAttrib & 0x10))
2922 /* SetSFCurDir(pb.ioDrDirID); */
2923 *((long*)0x398) = pb.ioDrDirID;
2927 /* Window location */
2928 topleft.h = (qd.screenBits.bounds.left+qd.screenBits.bounds.right)/2-344/2;
2929 topleft.v = (2*qd.screenBits.bounds.top+qd.screenBits.bounds.bottom)/3-188/2;
2931 /* Allow "all" files */
2935 SFGetFile(topleft, "\p", NULL, -1, types, NULL, &reply);
2938 /* Allow "save" files */
2945 SFGetFile(topleft, "\p", NULL, 1, types, NULL, &reply);
2949 if (!reply.good) return;
2951 /* Extract textual file name for save file */
2952 GetWDInfo(reply.vRefNum, &vrefnum, &drefnum, &junk);
2953 refnum_to_name(savefile, drefnum, vrefnum, (char*)reply.fName);
2958 /* Game is in progress */
2959 game_in_progress = 1;
2973 * Handle the "open_when_ready" flag
2975 static void handle_open_when_ready(void)
2977 /* Check the flag XXX XXX XXX make a function for this */
2978 if (open_when_ready && initialized && !game_in_progress)
2981 open_when_ready = FALSE;
2983 /* Game is in progress */
2984 game_in_progress = 1;
3003 * Initialize the menus
3005 * Verify menus 128, 129, 130
3006 * Create menus 131, 132, 133, 134
3008 * The standard menus are:
3010 * Apple (128) = { About, -, ... }
3011 * File (129) = { New,Open,Import,Close,Save,-,Exit,Quit }
3012 * Edit (130) = { Cut, Copy, Paste, Clear } (?)
3013 * Font (131) = { Bold, Extend, -, Monaco, ..., -, ... }
3014 * Size (132) = { ... }
3015 * Window (133) = { Angband, Mirror, Recall, Choice,
3016 * Term-4, Term-5, Term-6, Term-7 }
3017 * Special (134) = { arg_sound, arg_graphics, -,
3018 * arg_fiddle, arg_wizard }
3020 static void init_menubar(void)
3031 /* Get the "apple" menu */
3034 /* Insert the menu */
3037 /* Add the DA's to the "apple" menu */
3038 AppendResMenu (m, 'DRVR'); //AddResMenu(m, 'DRVR');
3041 /* Get the "File" menu */
3044 /* Insert the menu */
3048 /* Get the "Edit" menu */
3051 /* Insert the menu */
3055 /* Make the "Font" menu */
3057 m = NewMenu(131, "\p¥Õ¥©¥ó¥È");
3059 m = NewMenu(131, "\pFont");
3062 /* Insert the menu */
3066 AppendMenu(m, "\pBold");
3069 AppendMenu(m, "\pWide");
3071 /* Add a separator */
3072 AppendMenu(m, "\p-");
3075 r.left = r.right = r.top = r.bottom = 0;
3077 /* Make the fake window */
3078 tmpw = NewWindow(0, &r, "\p", false, documentProc, 0, 0, 0);
3080 /* Activate the "fake" window */
3089 /* Add the fonts to the menu */
3090 AppendResMenu(m, 'FONT'); //AddResMenu(m, 'FONT');
3096 for (i = n; i >= 4; i--)
3101 /* Acquire the font name */
3102 /* GetMenuItemText(m, i, tmpName); */
3103 GetMenuItemText(m, i, tmpName); //GetItem(m, i, tmpName);
3105 /* Acquire the font index */
3106 GetFNum(tmpName, &fontNum);
3108 /* Apply the font index */
3111 /* Remove non-mono-spaced fonts */
3112 if ((CharWidth('i') != CharWidth('W')) || (CharWidth('W') == 0))
3114 /* Delete the menu item XXX XXX XXX */
3115 /* DeleteMenuItem(m, i); */
3116 DeleteMenuItem (m, i); //DelMenuItem(m, i);
3120 /* Destroy the old window */
3121 DisposeWindow(tmpw);
3123 /* Add a separator */
3124 AppendMenu(m, "\p-");
3126 /* Add the fonts to the menu */
3127 AppendResMenu (m, 'FONT'); //AddResMenu(m, 'FONT');
3130 /* Make the "Size" menu */
3132 m = NewMenu(132, "\p¥µ¥¤¥º");
3134 m = NewMenu(132, "\pSize");
3137 /* Insert the menu */
3140 /* Add some sizes (stagger choices) */
3141 for (i = 8; i <= 32; i += ((i / 16) + 1))
3146 sprintf((char*)buf + 1, "%d", i);
3147 buf[0] = strlen((char*)buf + 1);
3154 /* Make the "Windows" menu */
3156 m = NewMenu(133, "\p¥¦¥¤¥ó¥É¥¦");
3158 m = NewMenu(133, "\pWindows");
3161 /* Insert the menu */
3164 /* Default choices */
3165 for (i = 0; i < MAX_TERM_DATA; i++)
3169 /* Describe the item */
3170 sprintf((char*)buf + 1, "%.15s", angband_term_name[i]);
3171 buf[0] = strlen((char*)buf + 1);
3176 /* Command-Key shortcuts */
3177 if (i < 8) SetItemCmd(m, i + 1, '0' + i);
3181 /* Make the "Special" menu */
3183 m = NewMenu(134, "\pÆÃÊÌ");
3185 m = NewMenu(134, "\pSpecial");
3188 /* Insert the menu */
3191 /* Append the choices */
3193 AppendMenu(m, "\p¥µ¥¦¥ó¥É»ÈÍÑ");
3194 AppendMenu(m, "\p¥°¥é¥Õ¥£¥Ã¥¯»ÈÍÑ");
3195 AppendMenu(m, "\p-");
3196 AppendMenu(m, "\parg_fiddle");
3197 AppendMenu(m, "\parg_wizard");
3198 AppendMenu(m, "\p-");
3199 AppendMenu(m, "\p¥µ¥¦¥ó¥ÉÀßÄê...");
3201 AppendMenu(m, "\parg_sound");
3202 AppendMenu(m, "\parg_graphics");
3203 AppendMenu(m, "\p-");
3204 AppendMenu(m, "\parg_fiddle");
3205 AppendMenu(m, "\parg_wizard");
3206 AppendMenu(m, "\p-");
3207 AppendMenu(m, "\psnd_setting");
3210 /* Make the "TileWidth" menu */
3212 m = NewMenu(135, "\p¥¿¥¤¥ëÉý");
3214 m = NewMenu(135, "\pTileWidth");
3217 /* Insert the menu */
3220 /* Add some sizes */
3221 for (i = 4; i <= 32; i++)
3226 sprintf((char*)buf + 1, "%d", i);
3227 buf[0] = strlen((char*)buf + 1);
3234 /* Make the "TileHeight" menu */
3236 m = NewMenu(136, "\p¥¿¥¤¥ë¹â");
3238 m = NewMenu(136, "\pTileHeight");
3241 /* Insert the menu */
3244 /* Add some sizes */
3245 for (i = 4; i <= 32; i++)
3250 sprintf((char*)buf + 1, "%d", i);
3251 buf[0] = strlen((char*)buf + 1);
3258 /* Update the menu bar */
3266 static void setup_menus(void)
3276 term_data *td = NULL;
3279 /* Relevant "term_data" */
3280 for (i = 0; i < MAX_TERM_DATA; i++)
3283 if (!data[i].t) continue;
3285 /* Notice the matching window */
3286 if (data[i].w == FrontWindow()) td = &data[i];
3291 m = GetMenuHandle(129); //m = GetMHandle(129);
3297 for (i = 1; i <= n; i++)
3301 CheckItem(m, i, FALSE);
3304 /* Enable "new"/"open..."/"import..." */
3305 if (initialized && !game_in_progress)
3312 /* Enable "close" */
3319 if (initialized && character_generated)
3328 /* EnableItem(m, 8); */
3333 m = GetMenuHandle(130); //m = GetMHandle(130);
3339 for (i = 1; i <= n; i++)
3343 CheckItem(m, i, FALSE);
3346 /* Enable "edit" options if "needed" */
3358 m = GetMenuHandle(131); //m = GetMHandle(131);
3364 for (i = 1; i <= n; i++)
3368 CheckItem(m, i, FALSE);
3371 /* Hack -- look cute XXX XXX */
3372 /* SetItemStyle(m, 1, bold); */
3374 /* Hack -- look cute XXX XXX */
3375 /* SetItemStyle(m, 2, extend); */
3383 /* Enable "extend" */
3386 /* Check the appropriate "bold-ness" */
3387 if (td->font_face & bold) CheckItem(m, 1, TRUE);
3389 /* Check the appropriate "wide-ness" */
3390 if (td->font_face & extend) CheckItem(m, 2, TRUE);
3393 for (i = 4; i <= n; i++)
3399 /* GetMenuItemText(m,i,s); */
3400 GetMenuItemText(m, i, s); //GetItem(m, i, s);
3403 /* Check active font */
3404 if (td->font_id == value) CheckItem(m, i, TRUE);
3410 m = GetMenuHandle(132); //m = GetMHandle(132);
3416 for (i = 1; i <= n; i++)
3420 CheckItem(m, i, FALSE);
3427 for (i = 1; i <= n; i++)
3430 /* GetMenuItemText(m,i,s); */
3431 GetMenuItemText(m, i, s); //GetItem(m, i, s);
3433 value = atoi((char*)(s+1));
3435 /* Enable the "real" sizes */
3436 if (RealFont(td->font_id, value)) EnableItem(m, i);
3438 /* Check the current size */
3439 if (td->font_size == value) CheckItem(m, i, TRUE);
3445 m = GetMenuHandle(133); //m = GetMHandle(133);
3450 /* Check active windows */
3451 for (i = 1; i <= n; i++)
3453 /* Check if needed */
3454 CheckItem(m, i, data[i-1].mapped);
3459 m = GetMenuHandle(134); //m = GetMHandle(134);
3465 for (i = 1; i <= n; i++)
3469 CheckItem(m, i, FALSE);
3472 /* Item "arg_sound" */
3474 CheckItem(m, 1, arg_sound);
3476 /* Item "arg_graphics" */
3478 CheckItem(m, 2, arg_graphics);
3480 /* Item "arg_fiddle" */
3482 CheckItem(m, 4, arg_fiddle);
3484 /* Item "arg_wizard" */
3486 CheckItem(m, 5, arg_wizard);
3488 /* Item "SoundSetting" */
3492 /* EnableItem(m, 9); */
3495 /* TileWidth menu */
3496 m = GetMenuHandle(135); //m = GetMHandle(135);
3502 for (i = 1; i <= n; i++)
3506 CheckItem(m, i, FALSE);
3513 for (i = 1; i <= n; i++)
3516 /* GetMenuItemText(m,i,s); */
3517 GetMenuItemText(m, i, s); //GetItem(m, i, s);
3519 value = atoi((char*)(s+1));
3524 /* Check the current size */
3525 if (td->tile_wid == value) CheckItem(m, i, TRUE);
3530 /* TileHeight menu */
3531 m = GetMenuHandle(136); //m = GetMHandle(136);
3537 for (i = 1; i <= n; i++)
3541 CheckItem(m, i, FALSE);
3548 for (i = 1; i <= n; i++)
3551 /* GetMenuItemText(m,i,s); */
3552 GetMenuItemText(m, i, s); //GetItem(m, i, s);
3554 value = atoi((char*)(s+1));
3559 /* Check the current size */
3560 if (td->tile_hgt == value) CheckItem(m, i, TRUE);
3567 * Process a menu selection (see above)
3569 * Hack -- assume that invalid menu selections are disabled above,
3570 * which I have been informed may not be reliable. XXX XXX XXX
3572 static void menu(long mc)
3576 int menuid, selection;
3578 static unsigned char s[1000];
3582 term_data *td = NULL;
3587 /* Analyze the menu command */
3588 menuid = HiWord(mc);
3589 selection = LoWord(mc);
3592 /* Find the window */
3593 for (i = 0; i < MAX_TERM_DATA; i++)
3595 /* Skip dead windows */
3596 if (!data[i].t) continue;
3598 /* Notice matches */
3599 if (data[i].w == FrontWindow()) td = &data[i];
3603 /* Branch on the menu */
3609 /* About Angband... */
3616 dialog=GetNewDialog(128, 0, (WindowPtr)-1);
3618 /* r=dialog->portRect;
3619 center_rect(&r, &qd.screenBits.bounds);
3620 MoveWindow(dialog, r.left, r.top, 1);*/
3622 ModalDialog(0, &item_hit);
3623 DisposeDialog(dialog); //DisposDialog(dialog);
3627 /* Desk accessory */
3628 /* GetMenuItemText(GetMHandle(128),selection,s); */
3629 GetMenuItemText(GetMenuHandle(128), selection, s); //GetItem(GetMHandle(128), selection, s);
3649 do_menu_file_open(FALSE);
3656 do_menu_file_open(TRUE);
3670 td->t->mapped_flag = FALSE;
3672 /* Hide the window */
3683 plog("º£¤Ï¥»¡¼¥Ö¤¹¤ë¤³¤È¤Ï½ÐÍè¤Þ¤»¤ó¡£");
3685 plog("You may not do that right now.");
3690 /* Hack -- Forget messages */
3693 /* Hack -- Save the game */
3694 do_cmd_save_game(FALSE);
3699 /* Quit (with save) */
3702 /* Save the game (if necessary) */
3703 if (game_in_progress && character_generated)
3707 plog("º£¤Ï¥»¡¼¥Ö¤¹¤ë¤³¤È¤Ï½ÐÍè¤Þ¤»¤ó¡£");
3709 plog("You may not do that right now.");
3713 /* Hack -- Forget messages */
3717 do_cmd_save_game(FALSE);
3738 /* Require a window */
3747 /* Toggle the "bold" setting */
3750 /* Toggle the setting */
3751 if (td->font_face & bold)
3753 td->font_face &= ~bold;
3757 td->font_face |= bold;
3760 /* Tile Width Hight Init */
3761 td->tile_wid = td->tile_hgt = 0;
3763 /* Apply and Verify */
3764 term_data_check_font(td);
3765 term_data_check_size(td);
3767 /* Resize and Redraw */
3768 term_data_resize(td);
3769 term_data_redraw(td);
3774 /* Toggle the "wide" setting */
3777 /* Toggle the setting */
3778 if (td->font_face & extend)
3780 td->font_face &= ~extend;
3784 td->font_face |= extend;
3787 /* Tile Width Hight Init */
3788 td->tile_wid = td->tile_hgt = 0;
3790 /* Apply and Verify */
3791 term_data_check_font(td);
3792 term_data_check_size(td);
3794 /* Resize and Redraw */
3795 term_data_resize(td);
3796 term_data_redraw(td);
3801 /* Get a new font name */
3802 /* GetMenuItemText(GetMHandle(131), selection, s); */
3803 GetMenuItemText(GetMenuHandle(131), selection, s); //GetItem(GetMHandle(131), selection, s);
3806 /* Save the new font id */
3809 /* Current size is bad for new font */
3810 if (!RealFont(td->font_id, td->font_size))
3812 /* Find similar size */
3813 for (i = 1; i <= 32; i++)
3815 /* Adjust smaller */
3816 if (td->font_size - i >= 8)
3818 if (RealFont(td->font_id, td->font_size - i))
3826 if (td->font_size + i <= 128)
3828 if (RealFont(td->font_id, td->font_size + i))
3837 /* Tile Width Hight Init */
3838 td->tile_wid = td->tile_hgt = 0;
3840 /* Apply and Verify */
3841 term_data_check_font(td);
3842 term_data_check_size(td);
3844 /* Resize and Redraw */
3845 term_data_resize(td);
3846 term_data_redraw(td);
3848 /* Restore the window */
3865 /* GetMenuItemText(GetMHandle(132), selection, s); */
3866 GetMenuItemText(GetMenuHandle(132), selection, s); //GetItem(GetMHandle(132), selection, s);
3868 td->font_size = atoi((char*)(s+1));
3870 /* Tile Width Hight Init */
3871 td->tile_wid = td->tile_hgt = 0;
3873 /* Apply and Verify */
3874 term_data_check_font(td);
3875 term_data_check_size(td);
3877 /* Resize and Redraw */
3878 term_data_resize(td);
3879 term_data_redraw(td);
3893 /* Check legality of choice */
3894 if ((i < 0) || (i >= MAX_TERM_DATA)) break;
3896 /* Obtain the window */
3906 td->t->mapped_flag = TRUE;
3908 /* Show the window */
3911 /* Bring to the front */
3912 SelectWindow(td->w);
3924 /* Toggle arg_sound */
3925 arg_sound = !arg_sound;
3927 /* React to changes */
3928 Term_xtra(TERM_XTRA_REACT, 0);
3935 /* Toggle arg_graphics */
3936 arg_graphics = !arg_graphics;
3938 /* Hack -- Force redraw */
3939 Term_key_push(KTRL('R'));
3946 arg_fiddle = !arg_fiddle;
3952 arg_wizard = !arg_wizard;
3966 /* TileWidth menu */
3977 /* GetMenuItemText(GetMHandle(135), selection, s); */
3978 GetMenuItemText(GetMenuHandle(135), selection, s); //GetItem(GetMHandle(135), selection, s);
3980 td->tile_wid = atoi((char*)(s+1));
3982 /* Apply and Verify */
3983 term_data_check_size(td);
3985 /* Resize and Redraw */
3986 term_data_resize(td);
3987 term_data_redraw(td);
3995 /* TileHeight menu */
4006 /* GetMenuItemText(GetMHandle(136), selection, s); */
4007 GetMenuItemText(GetMenuHandle(136), selection, s); //GetItem(GetMHandle(136), selection, s);
4009 td->tile_hgt = atoi((char*)(s+1));
4011 /* Apply and Verify */
4012 term_data_check_size(td);
4014 /* Resize and Redraw */
4015 term_data_resize(td);
4016 term_data_redraw(td);
4026 /* Clean the menu */
4035 * Check for extra required parameters -- From "Maarten Hazewinkel"
4037 static OSErr CheckRequiredAEParams(const AppleEvent *theAppleEvent)
4040 DescType returnedType;
4043 aeError = AEGetAttributePtr(theAppleEvent, keyMissedKeywordAttr, typeWildCard,
4044 &returnedType, NULL, 0, &actualSize);
4046 if (aeError == errAEDescNotFound) return (noErr);
4048 if (aeError == noErr) return (errAEParamMissed);
4055 * Apple Event Handler -- Open Application
4057 static pascal OSErr AEH_Start(const AppleEvent *theAppleEvent,
4058 const AppleEvent *reply, long handlerRefCon)
4060 #pragma unused(reply, handlerRefCon)
4062 return (CheckRequiredAEParams(theAppleEvent));
4067 * Apple Event Handler -- Quit Application
4069 static pascal OSErr AEH_Quit(const AppleEvent *theAppleEvent,
4070 const AppleEvent *reply, long handlerRefCon)
4072 #pragma unused(reply, handlerRefCon)
4075 quit_when_ready = TRUE;
4077 /* Check arguments */
4078 return (CheckRequiredAEParams(theAppleEvent));
4083 * Apple Event Handler -- Print Documents
4085 static pascal OSErr AEH_Print(const AppleEvent *theAppleEvent,
4086 const AppleEvent *reply, long handlerRefCon)
4088 #pragma unused(theAppleEvent, reply, handlerRefCon)
4090 return (errAEEventNotHandled);
4095 * Apple Event Handler by Steve Linberg (slinberg@crocker.com).
4097 * The old method of opening savefiles from the finder does not work
4098 * on the Power Macintosh, because CountAppFiles and GetAppFiles,
4099 * used to return information about the selected document files when
4100 * an application is launched, are part of the Segment Loader, which
4101 * is not present in the RISC OS due to the new memory architecture.
4103 * The "correct" way to do this is with AppleEvents. The following
4104 * code is modeled on the "Getting Files Selected from the Finder"
4105 * snippet from Think Reference 2.0. (The prior sentence could read
4106 * "shamelessly swiped & hacked")
4108 static pascal OSErr AEH_Open(AppleEvent *theAppleEvent,
4109 AppleEvent* reply, long handlerRefCon)
4111 #pragma unused(reply, handlerRefCon)
4118 DescType returnedType;
4122 /* Put the direct parameter (a descriptor list) into a docList */
4123 err = AEGetParamDesc(theAppleEvent, keyDirectObject, typeAEList, &docList);
4124 if (err) return err;
4127 * We ignore the validity check, because we trust the FInder, and we only
4128 * allow one savefile to be opened, so we ignore the depth of the list.
4131 err = AEGetNthPtr(&docList, 1L, typeFSS, &keywd,
4132 &returnedType, (Ptr) &myFSS, sizeof(myFSS), &actualSize);
4133 if (err) return err;
4135 /* Only needed to check savefile type below */
4136 err = FSpGetFInfo(&myFSS, &myFileInfo);
4139 sprintf(foo, "Arg! FSpGetFInfo failed with code %d", err);
4144 /* Ignore non 'SAVE' files */
4145 if (myFileInfo.fdType != 'SAVE') return noErr;
4147 /* XXX XXX XXX Extract a file name */
4148 PathNameFromDirID(myFSS.parID, myFSS.vRefNum, (StringPtr)savefile);
4149 pstrcat((StringPtr)savefile, (StringPtr)&myFSS.name);
4151 /* Convert the string */
4152 ptocstr((StringPtr)savefile);
4154 /* Delay actual open */
4155 open_when_ready = TRUE;
4158 err = AEDisposeDesc(&docList);
4170 * Macintosh modifiers (event.modifier & ccc):
4171 * cmdKey, optionKey, shiftKey, alphaLock, controlKey
4174 * Macintosh Keycodes (0-63 normal, 64-95 keypad, 96-127 extra):
4219 * Optimize non-blocking calls to "CheckEvents()"
4220 * Idea from "Maarten Hazewinkel <mmhazewi@cs.ruu.nl>"
4222 #define EVENT_TICKS 6
4226 * Check for Events, return TRUE if we process any
4228 * Hack -- Handle AppleEvents if appropriate (ignore result code).
4230 static bool CheckEvents(bool wait)
4246 term_data *td = NULL;
4250 static huge lastTicks = 0L;
4253 /* Access the clock */
4254 curTicks = TickCount();
4256 /* Hack -- Allow efficient checking for non-pending events */
4257 if (!wait && (curTicks < lastTicks + EVENT_TICKS)) return (FALSE);
4259 /* Timestamp last check */
4260 lastTicks = curTicks;
4262 /* Let the "system" run */
4265 /* Get an event (or null) */
4266 GetNextEvent(everyEvent, &event);
4268 /* Hack -- Nothing is ready yet */
4269 if (event.what == nullEvent) return (FALSE);
4272 /* Analyze the event */
4280 w = (WindowPtr)event.message;
4291 /* Extract the window */
4292 w = (WindowPtr)event.message;
4294 /* Find the window */
4295 for (i = 0; i < MAX_TERM_DATA; i++)
4297 /* Skip dead windows */
4298 if (!data[i].t) continue;
4300 /* Notice matches */
4301 if (data[i].w == w) td = &data[i];
4304 /* Hack XXX XXX XXX */
4308 /* Redraw the window */
4309 if (td) term_data_redraw(td);
4317 /* Extract some modifiers */
4318 mc = (event.modifiers & controlKey) ? TRUE : FALSE;
4319 ms = (event.modifiers & shiftKey) ? TRUE : FALSE;
4320 mo = (event.modifiers & optionKey) ? TRUE : FALSE;
4321 mx = (event.modifiers & cmdKey) ? TRUE : FALSE;
4323 /* Keypress: (only "valid" if ck < 96) */
4324 ch = (event.message & charCodeMask) & 255;
4326 /* Keycode: see table above */
4327 ck = ((event.message & keyCodeMask) >> 8) & 255;
4329 /* Command + "normal key" -> menu action */
4330 if (mx && (ck < 64))
4332 /* Hack -- Prepare the menus */
4335 /* Mega-Hack -- allow easy exit if nothing to save */
4336 /* if (!character_generated && (ch=='Q' || ch=='q')) ch = 'e'; */
4338 /* Run the Menu-Handler */
4341 /* Turn off the menus */
4349 /* Hide the mouse pointer */
4352 /* Normal key -> simple keypress */
4355 /* Enqueue the keypress */
4359 /* Hack -- normal "keypad keys" -> special keypress */
4360 else if (!mc && !ms && !mo && !mx && (ck < 96))
4362 /* Hack -- "enter" is confused */
4363 if (ck == 76) ch = '\n';
4365 /* Send control-caret as a trigger */
4368 /* Send the "ascii" keypress */
4372 /* Bizarre key -> encoded keypress */
4375 /* Hack -- introduce with control-underscore */
4378 /* Send some modifier keys */
4379 if (mc) Term_keypress('C');
4380 if (ms) Term_keypress('S');
4381 if (mo) Term_keypress('O');
4382 if (mx) Term_keypress('X');
4384 /* Hack -- Downshift and encode the keycode */
4385 Term_keypress('0' + (ck - 64) / 10);
4386 Term_keypress('0' + (ck - 64) % 10);
4388 /* Hack -- Terminate the sequence */
4389 /* MPW can generate 10 or 13 for keycode of '\r' */
4390 /* -noMapCR option swaps '\r' and '\n' */
4391 Term_keypress('\r');
4401 /* Analyze click location */
4402 code = FindWindow(event.where, &w);
4404 /* Find the window */
4405 for (i = 0; i < MAX_TERM_DATA; i++)
4407 /* Skip dead windows */
4408 if (!data[i].t) continue;
4410 /* Notice matches */
4411 if (data[i].w == w) td = &data[i];
4420 menu(MenuSelect(event.where));
4427 SystemClick(&event, w);
4437 r = qd.screenBits.bounds;
4438 r.top += 20; /* GetMBarHeight() XXX XXX XXX */
4439 InsetRect(&r, 4, 4);
4440 DragWindow(w, event.where, &r);
4452 p.h = td->w->portRect.left;
4453 p.v = td->w->portRect.top;
4461 /* Apply and Verify */
4462 term_data_check_size(td);
4472 /* Track the go-away box */
4473 if (TrackGoAway(w, event.where))
4479 td->t->mapped_flag = FALSE;
4481 /* Hide the window */
4497 /* Fake rectangle */
4498 r.left = 20 * td->tile_wid + td->size_ow1;
4499 r.right = 80 * td->tile_wid + td->size_ow1 + td->size_ow2 + 1;
4500 r.top = 1 * td->tile_hgt + td->size_oh1;
4501 r.bottom = 24 * td->tile_hgt + td->size_oh1 + td->size_oh2 + 1;
4503 /* Grow the rectangle */
4504 newsize = GrowWindow(w, event.where, &r);
4507 if (!newsize) break;
4509 /* Extract the new size in pixels */
4510 y = HiWord(newsize) - td->size_oh1 - td->size_oh2;
4511 x = LoWord(newsize) - td->size_ow1 - td->size_ow2;
4513 /* Extract a "close" approximation */
4514 td->rows = y / td->tile_hgt;
4515 td->cols = x / td->tile_wid;
4517 /* Apply and Verify */
4518 term_data_check_size(td);
4521 Term_activate(td->t);
4523 /* Hack -- Resize the term */
4524 Term_resize(td->cols, td->rows);
4526 /* Resize and Redraw */
4527 term_data_resize(td);
4528 term_data_redraw(td);
4547 /* Disk Event -- From "Maarten Hazewinkel" */
4550 /* check for error when mounting the disk */
4551 if (HiWord(event.message) != noErr)
4557 DIBadMount(p, event.message);
4564 /* OS Event -- From "Maarten Hazewinkel" */
4567 switch ((event.message >> 24) & 0x000000FF)
4569 case suspendResumeMessage:
4571 /* Resuming: activate the front window */
4572 if (event.message & resumeFlag)
4574 SetPort(FrontWindow());
4575 SetCursor(&qd.arrow);
4578 /* Suspend: deactivate the front window */
4592 /* From "Steve Linberg" and "Maarten Hazewinkel" */
4593 case kHighLevelEvent:
4595 /* Process apple events */
4596 if (AEProcessAppleEvent(&event) != noErr)
4599 plog("Apple Event Handler¤Î¥¨¥é¡¼¤Ç¤¹.");
4601 plog("Error in Apple Event Handler!");
4605 /* Handle "quit_when_ready" */
4606 if (quit_when_ready)
4609 quit_when_ready = FALSE;
4611 /* Do the menu key */
4614 /* Turn off the menus */
4618 /* Handle "open_when_ready" */
4619 handle_open_when_ready();
4629 /* Something happened */
4636 /*** Some Hooks for various routines ***/
4640 * Mega-Hack -- emergency lifeboat
4642 static vptr lifeboat = NULL;
4646 * Hook to "release" memory
4648 static vptr hook_rnfree(vptr v, huge size)
4651 #pragma unused (size)
4655 /* Alternative method */
4670 * Hook to "allocate" memory
4672 static vptr hook_ralloc(huge size)
4677 /* Make a new pointer */
4678 return (malloc(size));
4682 /* Make a new pointer */
4683 return (NewPtr(size));
4690 * Hook to handle "out of memory" errors
4692 static vptr hook_rpanic(huge size)
4695 #pragma unused (size)
4699 /* Free the lifeboat */
4702 /* Free the lifeboat */
4703 DisposePtr(lifeboat);
4705 /* Forget the lifeboat */
4708 /* Mega-Hack -- Warning */
4710 mac_warning("¥á¥â¥ê¡¼¤¬Â¤ê¤Þ¤»¤ó!\rº£¤¹¤°½ªÎ»¤·¤Æ²¼¤µ¤¤!");
4712 mac_warning("Running out of Memory!\rAbort this process now!");
4715 /* Mega-Hack -- Never leave this function */
4716 while (TRUE) CheckEvents(TRUE);
4719 /* Mega-Hack -- Crash */
4725 * Hook to tell the user something important
4727 static void hook_plog(cptr str)
4729 /* Warning message */
4734 * Hook to tell the user something, and then quit
4736 static void hook_quit(cptr str)
4738 /* Warning if needed */
4739 if (str) mac_warning(str);
4741 /* Write a preference file */
4749 * Hook to tell the user something, and then crash
4751 static void hook_core(cptr str)
4753 /* XXX Use the debugger */
4754 /* DebugStr(str); */
4757 if (str) mac_warning(str);
4759 /* Warn, then save player */
4761 mac_warning("Ã×̿Ū¤Ê¥¨¥é¡¼¤Ç¤¹.\r¶¯À©Åª¤Ë¥»¡¼¥Ö¤·¤Æ½ªÎ»¤·¤Þ¤¹.");
4763 mac_warning("Fatal error.\rI will now attempt to save and quit.");
4766 /* Attempt to save */
4768 if (!save_player()) mac_warning("·Ù¹ð -- ¥»¡¼¥Ö¤Ë¼ºÇÔ¤·¤Þ¤·¤¿!");
4770 if (!save_player()) mac_warning("Warning -- save failed!");
4779 /*** Main program ***/
4785 * XXX XXX XXX Hack -- This function attempts to "fix" the nasty
4786 * "Macintosh Save Bug" by using "absolute" path names, since on
4787 * System 7 machines anyway, the "current working directory" often
4788 * "changes" due to background processes, invalidating any "relative"
4789 * path names. Note that the Macintosh is limited to 255 character
4790 * path names, so be careful about deeply embedded directories...
4792 * XXX XXX XXX Hack -- This function attempts to "fix" the nasty
4793 * "missing lib folder bug" by allowing the user to help find the
4794 * "lib" folder by hand if the "application folder" code fails...
4796 static void init_stuff(void)
4813 /* Fake rectangle */
4820 center_rect(&r, &qd.screenBits.bounds);
4822 /* Extract corner */
4827 /* Default to the "lib" folder with the application */
4828 refnum_to_name(path, app_dir, app_vol, (char*)("\plib:"));
4831 /* Check until done */
4834 /* Prepare the paths */
4835 init_file_paths(path);
4837 /* Build the filename */
4839 path_build(path, 1024, ANGBAND_DIR_FILE, "news_j.txt");
4841 path_build(path, 1024, ANGBAND_DIR_FILE, "news.txt");
4844 /* Attempt to open and close that file */
4845 if (0 == fd_close(fd_open(path, O_RDONLY))) break;
4849 plog_fmt("'%s' ¥Õ¥¡¥¤¥ë¤ò¥ª¡¼¥×¥ó½ÐÍè¤Þ¤»¤ó.", path);
4851 plog_fmt("Unable to open the '%s' file.", path);
4856 plog("Hengband¤Î'lib'¥Õ¥©¥ë¥À¤¬Â¸ºß¤·¤Ê¤¤¤«Àµ¤·¤¯Ìµ¤¤²ÄǽÀ¤¬¤¢¤ê¤Þ¤¹.");
4858 plog("The Angband 'lib' folder is probably missing or misplaced.");
4862 plog("Please 'open' any file in any sub-folder of the 'lib' folder.");
4864 /* Allow "text" files */
4867 /* Allow "save" files */
4870 /* Allow "data" files */
4874 SFGetFile(topleft, "\p", NULL, 3, types, NULL, &reply);
4877 if (!reply.good) quit(NULL);
4879 /* Extract textual file name for given file */
4880 GetWDInfo(reply.vRefNum, &vrefnum, &drefnum, &junk);
4881 refnum_to_name(path, drefnum, vrefnum, (char*)reply.fName);
4883 /* Hack -- Remove the "filename" */
4884 i = strlen(path) - 1;
4885 while ((i > 0) && (path[i] != ':')) i--;
4886 if (path[i] == ':') path[i+1] = '\0';
4888 /* Hack -- allow "lib" folders */
4889 if (suffix(path, "lib:")) continue;
4891 /* Hack -- Remove the "sub-folder" */
4893 while ((i > 1) && (path[i] != ':')) i--;
4894 if (path[i] == ':') path[i+1] = '\0';
4900 * Macintosh Main loop
4904 EventRecord tempEvent;
4905 int numberOfMasters = 10;
4907 /* Increase stack space by 64K */
4908 SetApplLimit(GetApplLimit() - 131072L);//65536L);
4910 /* Stretch out the heap to full size */
4913 /* Get more Masters */
4914 while (numberOfMasters--) MoreMasters();
4916 /* Set up the Macintosh */
4917 InitGraf(&qd.thePort);
4930 FlushEvents(everyEvent, 0);
4932 /* Flush events some more (?) */
4933 (void)EventAvail(everyEvent, &tempEvent);
4934 (void)EventAvail(everyEvent, &tempEvent);
4935 (void)EventAvail(everyEvent, &tempEvent);
4938 #ifdef ANGBAND_LITE_MAC
4942 #else /* ANGBAND_LITE_MAC */
4944 # if defined(powerc) || defined(__powerc)
4946 /* Assume System 7 */
4948 /* Assume Color Quickdraw */
4958 /* Check the Gestalt */
4959 err = Gestalt(gestaltSystemVersion, &versionNumber);
4961 /* Check the version */
4962 if ((err != noErr) || (versionNumber < 0x0700))
4965 quit("¤³¤Î¥×¥í¥°¥é¥à¤Ï´Á»úTalk7.x.x°Ê¹ß¤ÇÆ°ºî¤·¤Þ¤¹.");
4967 quit("You must have System 7 to use this program.");
4977 /* Check the environs */
4978 if (SysEnvirons(1, &env) != noErr)
4981 quit("SysEnvirons ¥³¡¼¥ë¤Ï¼ºÇÔ¤·¤Þ¤·¤¿¡ª");
4983 quit("The SysEnvirons call failed!");
4987 /* Check for System Seven Stuff */
4988 if (env.systemVersion < 0x0700)
4991 quit("¤³¤Î¥×¥í¥°¥é¥à¤Ï´Á»úTalk7.x.x°Ê¹ß¤ÇÆ°ºî¤·¤Þ¤¹.");
4993 quit("You must have System 7 to use this program.");
4997 /* Check for Color Quickdraw */
4998 if (!env.hasColorQD)
5001 quit("¤³¤Î¥×¥í¥°¥é¥à¤ÏColor Quickdraw¤¬Ìµ¤¤¤ÈÆ°ºî¤·¤Þ¤»¤ó.");
5003 quit("You must have Color Quickdraw to use this program.");
5010 #endif /* ANGBAND_LITE_MAC */
5015 /* Obtain a "Universal Procedure Pointer" */
5016 AEH_Start_UPP = NewAEEventHandlerProc(AEH_Start);
5018 /* Install the hook (ignore error codes) */
5019 AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, AEH_Start_UPP,
5022 /* Obtain a "Universal Procedure Pointer" */
5023 AEH_Quit_UPP = NewAEEventHandlerProc(AEH_Quit);
5025 /* Install the hook (ignore error codes) */
5026 AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, AEH_Quit_UPP,
5029 /* Obtain a "Universal Procedure Pointer" */
5030 AEH_Print_UPP = NewAEEventHandlerProc(AEH_Print);
5032 /* Install the hook (ignore error codes) */
5033 AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments, AEH_Print_UPP,
5036 /* Obtain a "Universal Procedure Pointer" */
5037 AEH_Open_UPP = NewAEEventHandlerProc(AEH_Open);
5039 /* Install the hook (ignore error codes) */
5040 AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, AEH_Open_UPP,
5046 /* Find the current application */
5050 /* Mark ourself as the file creator */
5053 /* Default to saving a "text" file */
5057 #if defined(__MWERKS__)
5059 /* Obtian a "Universal Procedure Pointer" */
5060 ynfilterUPP = NewModalFilterProc(ynfilter);
5065 /* Hook in some "z-virt.c" hooks */
5066 rnfree_aux = hook_rnfree;
5067 ralloc_aux = hook_ralloc;
5068 rpanic_aux = hook_rpanic;
5070 /* Hooks in some "z-util.c" hooks */
5071 plog_aux = hook_plog;
5072 quit_aux = hook_quit;
5073 core_aux = hook_core;
5075 BackColor(blackColor);
5076 ForeColor(whiteColor);
5078 /* Show the "watch" cursor */
5079 SetCursor(*(GetCursor(watchCursor)));
5081 /* Prepare the menubar */
5084 /* Prepare the windows */
5089 /* Hack -- process all events */
5090 while (CheckEvents(TRUE)) /* loop */;
5092 /* Reset the cursor */
5093 SetCursor(&qd.arrow);
5096 /* Mega-Hack -- Allocate a "lifeboat" */
5097 lifeboat = NewPtr(16384);
5099 /* Note the "system" */
5100 ANGBAND_SYS = "mac";
5102 ANGBAND_GRAF = "new";
5104 ANGBAND_GRAF = "old";
5114 /* Hack -- process all events */
5115 while (CheckEvents(TRUE)) /* loop */;
5118 /* We are now initialized */
5122 /* Handle "open_when_ready" */
5123 handle_open_when_ready();
5129 /* Prompt the user */
5131 prt("'¥Õ¥¡¥¤¥ë'¥á¥Ë¥å¡¼¤è¤ê'¿·µ¬'¤Þ¤¿¤Ï'³«¤¯...'¤òÁªÂò¤·¤Æ¤¯¤À¤µ¤¤¡£", 23, 10);
5133 prt("[Choose 'New' or 'Open' from the 'File' menu]", 23, 15);
5136 /* Flush the prompt */
5140 /* Hack -- Process Events Forever */
5141 while (TRUE) CheckEvents(TRUE);