diff options
-rw-r--r-- | src/config.h | 6 | ||||
-rw-r--r-- | src/externs.h | 6 | ||||
-rw-r--r-- | src/init2.cc | 11 | ||||
-rw-r--r-- | src/main-crb.c | 5963 | ||||
-rw-r--r-- | src/modules.cc | 6 | ||||
-rw-r--r-- | src/util.cc | 53 |
6 files changed, 0 insertions, 6045 deletions
diff --git a/src/config.h b/src/config.h index cb258925..bc7e3fc4 100644 --- a/src/config.h +++ b/src/config.h @@ -157,13 +157,7 @@ /* * Where to put the user's files. */ -#if defined(MACH_O_CARBON) -#define PRIVATE_USER_PATH "~/Library/Application Support/ToME" -#define PRIVATE_USER_PATH_DATA -#define PRIVATE_USER_PATH_MODULES -#else #define PRIVATE_USER_PATH "~/.tome" -#endif /* diff --git a/src/externs.h b/src/externs.h index 71054a59..116e4e28 100644 --- a/src/externs.h +++ b/src/externs.h @@ -2210,12 +2210,6 @@ extern int usleep(huge usecs); /* extern void main(void); */ #endif -#ifdef MACH_O_CARBON -/* main-crb.c */ -extern int fsetfileinfo(char *path, u32b fcreator, u32b ftype); -extern u32b _fcreator; -extern u32b _ftype; -#endif /* MACH_O_CARBON */ #ifdef WINDOWS /* main-win.c */ diff --git a/src/init2.cc b/src/init2.cc index d4378570..725e87ba 100644 --- a/src/init2.cc +++ b/src/init2.cc @@ -180,17 +180,6 @@ void init_file_paths(char *path) strcat(user_path, USER_PATH_VERSION); ANGBAND_DIR_USER = string_make(user_path); ANGBAND_DIR_NOTE = string_make(user_path); -#ifdef PRIVATE_USER_PATH_MODULES - ANGBAND_DIR_MODULES = string_make(user_path); -#endif -#ifdef PRIVATE_USER_PATH_DATA - { - char user_path_data[1024]; - strcpy(user_path_data, user_path); - strcat(user_path_data, "/data"); - ANGBAND_DIR_DATA = string_make(user_path_data); - } -#endif /* Savefiles are in user directory */ strcat(user_path, "/save"); diff --git a/src/main-crb.c b/src/main-crb.c deleted file mode 100644 index c6a3a412..00000000 --- a/src/main-crb.c +++ /dev/null @@ -1,5963 +0,0 @@ -/* File: main-crb.c */ - -/* - * Copyright (c) 1997 Ben Harrison, Keith Randall, Peter Ammon, Ron Anderson - * and others - * - * This software may be copied and distributed for educational, research, - * and not for profit purposes provided that this copyright and statement - * are included in all such copies. - */ - - -/* - * This file helps Angband work with Macintosh computers running OS X, - * or OS 8/9 with CarbonLib system extention. - * - * To use this file, use an appropriate "Makefile" or "Project File", which - * should define "MACINTOSH". - * - * The official compilation uses the CodeWarrior Pro compiler. - * - * If you are never going to use "graphics" (especially if you are not - * compiling support for graphics anyway) then you can delete the "pict" - * resources with id "1001", "1002", "1003" and "1004" with no dangerous - * side effects. - * - * - * This file assumes that you will be using a PPC Mac running OS X - * or OS 8/9 (8.6 or greater) with CarbonLib system extention enabled. - * In fact, the game will refuse to run unless these features are available. - * - * MACH_O_CARBON code pushes the system requirement a bit further, and - * I don't think it works on System 8, even with CarbonLib, because it uses - * the Bundle services, but I may be wrong. - * - * Note that the "preference" file is now a simple XML text file - * called "<program name>.plist" in case of PEF Carbon, and "<Java-style - * program id defined in Info.plist>.plist" for Mach-O Carbon, which contains - * key-value paris, so it no longer has to check version stamp to validate - * its contents. - * - * - * Note that "init1.c", "init2.c", "load1.c", "load2.c", and "birth.c" - * should probably be "unloaded" as soon as they are no longer needed, - * to save space, but I do not know how to do this. XXX XXX XXX - * - * Stange bug -- The first "ClipRect()" call crashes if the user closes - * all the windows, switches to another application, switches back, and - * re-opens the main window, for example, using "command-a". XXX XXX XXX - * - * - * Initial framework (and most code) by Ben Harrison (benh@phial.com). - * - * Some code adapted from "MacAngband 2.6.1" by Keith Randall - * - * Initial PowerMac port by Maarten Hazewinkel (mmhazewi@cs.ruu.nl). - * - * Most Apple Event code provided by Steve Linberg (slinberg@crocker.com). - * - * Most of the graphics code is adapted from an extremely minimal subset of - * the "Sprite World II" package, an amazing (and free) animation package. - * - * Carbon code adapted from works by Peter Ammon and Ron Anderson. - * - * (List of changes made by "pelpel" follow) - * Some API calls are updated to OS 8.x-- ones. - * - * Pixmap locking code in Term_pict_map() follows Carbon Porting Guide - * by Apple. - * - * The idle loop in TERM_XTRA_DELAY is rewritten to sleep on WaitNextEvent - * for a couple of reasons. - * - * CheckEvent now really blocks whenever asked to wait. - * - * The unused buffer GWorld is completely removed. It has long been pure waste - * of memory. - * - * The default font-size combination was changed because the old one, Monaco - * at 12 points causes the redraw artefact problem on OS X. - * - * Characters in the ASCII mode are clipped by their bounding rects to reduce - * redraw artefacts that were quite annoying in certain font-point combos. - * - * Transparency effect now avoids double bitblts whenever possible. - * - * Old tiles were drawn in a wrong fashion by the USE_TRANSPARENCY code. - * - * ASCII and the two graphics modes are now controlled by single graf_mode - * variable. arg_* and use_* variables are set when requested mode is - * successfully initialised. - * - * Most of the menus are now loaded from resources. - * - * Moved TileWidth and TileHeight menus into Special. There were too many menus. - * - * Added support for 32x32 tiles, now for [V] only. - * - * Related to the above, globe_init no longer loads tile images twice if - * a tileset doesn't have corresponding masks. - * - * Added support for POSIX-style pathnames, for Mach-O Carbon (gcc, CW >= 7). - * We can finally live without Pascal strings to handle files this way. - * - * (Mach-O Carbon) Graphics tiles are moved out of the resource fork into - * bundle-based data fork files. - * - * Changed size-related menu code, because they no longer function because - * some APIs have been changed to return Unicode in some cases. - * - * Changed the transparency code again, this time using Ron Anderson's code, - * which makes more sound assumption about background colour and is more - * efficient. - * - * The old asynchronous sound player could try to lock the same handle more - * than once, load same sound resource already in use, or unlock and release - * currently playing sound. - * - * hook_quit() now releases memory-related resources dynamically allocated by - * the graphics and sound code. - * - * Important Resources in the resource file: - * - * FREF 130 = ANGBAND_CREATOR / 'APPL' (application) - * FREF 129 = ANGBAND_CREATOR / 'SAVE' (save file) - * FREF 130 = ANGBAND_CREATOR / 'TEXT' (generic text file) - * FREF 131 = ANGBAND_CREATOR / 'DATA' (binary image file, score file) - * - * DLOG 128 = "About Angband..." - * - * ALRT 128 = unused (?) - * ALRT 129 = "Warning..." - * - * DITL 128 = body for DLOG 128 - * DITL 129 = body for ALRT 129 - * DITL 130 = body for ALRT 130 - * - * ICON 128 = "warning" icon - * - * MBAR 128 = array of MENU id's (128, 129, 130, 131, 132, 133, 134) - * MENU 128 = apple (about, -, ...) - * MENU 129 = File (close, save, -, score, quit) - * MENU 130 = Edit (undo, -, cut, copy, paste, clear) - * MENU 131 = Font (bold, wide, -) - * MENU 132 = Size () - * MENU 133 = Windows () - * MENU 134 = Special (Sound, Graphics, TileWidth, TileHeight, -, Fiddle, - * Wizard) - * Graphics have following submenu attached: - * MENU 144 = Graphics (None, 8x8, 16x16, 32x32, enlarge tiles) - * TileWidth and TileHeight submenus are filled in by this program. - * MENU 145 = TileWidth () - * MENU 146 = TileHeight () - * - * On CFM(PEF) Carbon only: - * PICT 1001 = Graphics tile set (8x8) - * PICT 1002 = Graphics tile set (16x16 images) - * PICT 1004 = Graphics tile set (32x32) - * - * Mach-O Carbon now uses data fork resources: - * 8x8.png = Graphics tile set (8x8) - * 16x16.png = Graphics tile set (16x16 images) - * 32x32.png = Graphics tile set (32x32) - * These files should go into the Resources subdirectory of an application - * bundle. - * - * STR# 128 = "Please select the "lib" folder" - * - * plst 0 can be empty, but required for single binary Carbon apps on OS X - * Isn't necessary for Mach-O Carbon. - * - * - * File name patterns: - * all 'APEX' files have a filename of the form "*:apex:*" (?) - * all 'DATA' files have a filename of the form "*:data:*" - * all 'SAVE' files have a filename of the form "*:save:*" - * all 'USER' files have a filename of the form "*:user:*" (?) - * - * Perhaps we should attempt to set the "_ftype" flag inside this file, - * to avoid nasty file type information being spread all through the - * rest of the code. (?) This might require adding hooks into the - * "fd_open()" and "my_fopen()" functions in "util.c". XXX XXX XXX - * - * - * Reasons for each header file: - * - * angband.h = Angband header file - * - * Types.h = (included anyway) - * Gestalt.h = gestalt code - * QuickDraw.h = (included anyway) - * OSUtils.h = (included anyway) - * Files.h = file code - * Fonts.h = font code - * Menus.h = menu code - * Dialogs.h = dialog code - * Windows.h = (included anyway) - * Palettes.h = palette code - * ToolUtils.h = HiWord() / LoWord() - * Events.h = event code - * Resources.h = resource code - * Controls.h = button code - * SegLoad.h = ExitToShell(), AppFile, etc - * Memory.h = NewPtr(), etc - * QDOffscreen.h = GWorld code - * Sound.h = Sound code - * Navigation.h = save file / lib locating dialogues - * CFPreferences.h = Preferences - * CFNumber.h = read/write short values from/to preferences - */ - -/* - * Yet another main-xxx.c for Carbon (pelpel) - revision 11d - * - * Since I'm using CodeWarrior, the traditional header files are - * #include'd below. - * - * I also compiled Angband 3.0.2 successfully with OS X's gcc. - * Please follow these instructions if you are interested. - * - * ---(developer CD gcc + makefile porting notes, for Angband 3.0.2)------- - * 1. Compiling the binary - * - * If you try this on OS X + gcc, please use makefile.std, replacing - * main.c and main.o with main-crb.c and main-crb.o, removing all main-xxx.c - * and main-xxx.o from SRCS and OBJS, and, and use these settings: - * - * COPTS = -Wall -O1 -g -fpascal-strings - * INCLUDES = - * DEFINES = -DMACH_O_CARBON -DANGBAND30X - * LIBS = -framework CoreFoundation -framework QuickTime -framework Carbon - * - * Never, ever #define MACINTOSH. It'll wreck havoc in system interface - * (mostly because of totally different pathname convention). - * - * You might wish to disable some SET_UID features for various reasons: - * to have user folder within the lib folder, savefile names etc. - * - * For the best compatibility with the Classic ports and my PEF Carbon - * ports, my_fopen, fd_make and fd_open [in util.c] should call - * (void)fsetfileinfo(buf, _fcreator, _ftype); - * when a file is successfully opened. Or you'll see odd icons for some files - * in the lib folder. In order to do so, extern.h should contain these lines, - * within #ifdef MACH_O_CARBON: - * extern int fsetfileinfo(char *path, u32b fcreator, u32b ftype); - * extern u32b _fcreator; - * extern u32b _ftype; - * And enable the four FILE_TYPE macros in h-config.h for defined(MACH_O_CARBON) - * in addition to defined(MACINTOSH) && !defined(applec), i.e. - * #if defined(MACINTOSH) && !defined(applec) || defined(MACH_O_CARBON) - * - * This is a very good way to spot bugs in use of these macros, btw. - * - * 2. Installation - * - * The "angband" binary must be arranged this way for it to work: - * - * lib/ <- the lib folder - * Angband (OS X).app/ - * Contents/ - * MacOS/ - * angband <- the binary you've just compiled - * Info.plist <- to be explained below - * Resources/ - * Angband.icns - * Data.icns - * Edit.icns - * Save.icns - * 8x8.png <- 8x8 tiles - * 16x16.png <- 16x16 tiles - * angband.rsrc <- see below - * - * 3. Preparing Info.plist - * - * Info.plist is an XML file describing some attributes of an application, - * and this is appropriate for Angband: - * - * <?xml version="1.0" encoding="UTF-8"?> - * <plist version="1.0"> - * <dict> - * <key>CFBundleName</key><string>Angband</string> - * <key>CFBundleDisplayName</key><string>Angband (OS X)</string> - * <key>CFBundleExecutable</key><string>angband</string> - * <key>CFBundlePackageType</key><string>APPL</string> - * <key>CFBundleSignature</key><string>A271</string> - * <key>CFBundleVersion</key><string>3.0.2</string> - * <key>CFBundleShortVersionString</key><string>3.0.2</string> - * <key>CFBundleIconFile</key><string>Angband</string> - * <key>CFBundleIdentifier</key><string>net.thangorodrim.Angband</string> - * <key>CFBundleInfoDictionaryVersion</key><string>6.0</string> - * <key>CFBundleDocumentTypes</key> - * <array> - * <dict> - * <key>CFBundleTypeExtentions</key><array><string>*</string></array> - * <key>CFBundleTypeIconFile</key><string>Save</string> - * <key>CFBundleTypeName</key><string>Angband saved game</string> - * <key>CFBundleTypeOSTypes</key><array><string>SAVE</string></array> - * <key>CFBundleTypeRole</key><string>Editor</string> - * </dict> - * <dict> - * <key>CFBundleTypeExtentions</key><array><string>*</string></array> - * <key>CFBundleTypeIconFile</key><string>Edit</string> - * <key>CFBundleTypeName</key><string>Angband game data</string> - * <key>CFBundleTypeOSTypes</key><array><string>TEXT</string></array> - * <key>CFBundleTypeRole</key><string>Editor</string> - * </dict> - * <dict> - * <key>CFBundleTypeExtentions</key><array><string>raw</string></array> - * <key>CFBundleTypeIconFile</key><string>Data</string> - * <key>CFBundleTypeName</key><string>Angband game data</string> - * <key>CFBundleTypeOSTypes</key><array><string>DATA</string></array> - * <key>CFBundleTypeRole</key><string>Editor</string> - * </dict> - * </array> - * </dict> - * </plist> - * - * 4. Menu, diaglogue and gfx resources - * - * The binary assumes angband.rsrc should be in the traditional resource - * mangager format. Please run this command to create it from its textual - * description: - * - * Rez -i /Developer/Headers/FlatCarbon -d MACH_O -o angband.rsrc Angband.r - * - * The command is in /Developer/Tools. You might wish to include it in your - * PATH. - * - * It's better to comment out the definitions of BNDL and plst resources - * before you do that. I think you can DeRez the resulting tome.rsrc and - * feed it to the Interface Builder to produce a set of compatible .nib files, - * but this file also needs to be updated to understand .nib... On the other - * hand, I really don't like to hardcode UI definitions in C. - * - * Graphics resources are moved out of the resource fork and become ordinary - * PNG files. Make sure to set its resolution to 72 dpi (<- VERY important) - * while keeping vertical and horizontal scaling factor to 100% (<- VERY - * important), when you convert tiles in any formats to PNG. This means - * that the real size of an image must shrink or grow when you change it's dpi. - * - * Sound resources are a bit more complicated. - * The easiest way is: - * 1) Grab recent Mac Angband binary. - * 2) Run this command: - * DeRez -only 'snd ' (Angband binary) > sound.r - * 3) And specify sound.r files in addition to Angband.r when you run Rez. - * - * ---(end of OS X + gcc porting note)-------------------------------------- - * - * Code adapted from Peter Ammon's work on 2.8.3 and some modifications - * are made when Apple's Carbon Porting Guide says they are absolutely - * necessary. Other arbirary changes are mostly because of my hatred - * of deep nestings and indentations. The code for controlling graphics modes - * have been thoroughly revised simply because I didn't like it (^ ^;). - * A bonus of this is that graphics settings can be loaded from Preferences - * quite easily. - * - * I also took Ron Anderson's (minimising the use of local-global coordinate - * conversions). Some might say his QuickTime multimedia is the most - * significant achievement... Play your favourite CD instead, if you really - * miss that (^ ^;) I might consider incorporating it if it makes use of - * event notification. - * - * I replaced some old API calls with new (OS 8.x--) ones, especially - * when I felt Apple is strongly against their continued usage. - * - * Similarly, USE_SFL_CODE should be always active, so I removed ifdef's - * just to prevent accidents, as well as to make the code a bit cleaner. - * - * On the contrary, I deliberately left traditional resource interfaces. - * Whatever Apple might say, I abhor file name extentions. And keeping two - * different sets of resources for Classic and Carbon is just too much for - * a personal project XXX - * - * Because Carbon forbids the use of 68K code, ANGBAND_LITE_MAC sections - * are removed. - * - * Because the default font-size combination causes redraw artefact problem - * (some characters, even in monospace fonts, have negative left bearings), - * I introduced rather crude hack to clip all character drawings within - * their bounding rects. If you don't like this, please comment out the line - * #define CLIP_HACK - * below. - * - * The check for return values of AEProcessAppleEvent is removed, - * because it results in annoying dialogues on OS X, also because - * Apple says it isn't usually necessary. - * - * Because the always_pict code is *so* slow, I changed the graphics - * mode selection a bit to use higher_pict when a user chooses a fixed - * width font and doesn't changes tile width / height. - * - * Added support for David Gervais' 32x32 tiles. - * - * Replaced transparency effect code by Ron Anderson's. - * - * Added support for gcc & make compilation. They come free with OS X - * (on the developer CD). This means that it can be compiled as a bundle. - * - * For Mach-O Carbon binary, moved graphics tiles out of the - * resource fork and made them plain PNG files, to be stored in the application - * bundle's "Resources" subdirectory. - * - * For Mach-O Carbon binary, provided a compile-time option (USE_QT_SOUND) to - * move sound effect samples out of the resource fork and use *.wav files in - * the bundle's "Resources" subdirectory. The "*" part must match the names in - * angband_sound_name (variable.c) exactly. This doesn't hurt performance - * a lot in [V] (it's got ~25 sound events), but problematic in [Z]-based - * ones (they have somewhere around 70 sound events). - * - * You still can use the resource file that comes with the ext-mac archive - * on the Angband FTP server, with these additions: - * - MENUs 131--134 and 144--146, as described above - * - MBAR 128: just a array of 128 through 134 - * - plst 0 : can be empty, although Apple recommends us to fill it in. - * - STR# 128 : something like "Please select your lib folder" - * - * Since this involves considerable amount of work, I attached - * a plain text resource definition (= Rez format) . - * I heavily commented on the file, hoping it could be easily adapted - * to future versions of Angband as well as variants. - * I omitted sound effects and graphic tiles to make it reasonably small. - * Please copy them from any recent Mac binaries - you can use, say ZAngband - * ones for Vanilla or [V]-based variants quite safely. T.o.M.E. uses fairly - * extended 16x16 tileset and it is maintained actively. IIRC Thangorodrim - * compile page has an intruction explaining how to convert tiles for - * use on the Mac... It can be tricky, depending on your choice of - * graphics utility. Remember setting resolution to 72 pixels per inch, - * while keeping vertical/horizontal scale factor to 100% and dump the - * result as a PICT from resource. - * - * To build Carbonised Angband with CodeWarrior, copy your PPC project - * and - * - replace main-mac.c in the project with this file (in the link order tab) - * - remove InterfaceLib and MathLib - * - add CarbonLib (found in Carbon SDK or CW's UniversalInterfaces) -- - * if you have compiler/linker errors, you'll need Carbon SDK 1.1 or greater - * - replace MSL C.PPC.Lib with MSL C.Carbon.Lib (both found in - * MSL:MSL_C:MSL_MacOS:Lib:PPC) - * - leave MSL RuntimePPC.Lib as it is - * - don't forget to update resource file, as described above - * - as in Classic targets, you may have to include <unistd.h> and - * <fcntl.h>. The most convinient place for them is the first - * #ifdef MACINTOSH in h-system.h - * - check variant dependent ifdef's explained below, and add - * appropriate one(s) in your A-mac-h.pch. - */ - - -/* - * Force Carbon-compatible APIs - */ -#ifndef MACH_O_CARBON - -/* Can be CodeWarrior or MPW */ -# define TARGET_API_MAC_CARBON 1 - -#else - -/* -* Must be Mach-O Carbon target with OS X gcc. -* No need to set TARGET_API_MAC_CARBON to 1 here, but I assume it should -* be able to make efficient use of BSD functions, hence: -*/ -# define USE_MALLOC -/* Not yet */ -/* # define USE_NIB */ - -#endif /* !MACH_O_CARBON */ - - -#include "angband.h" - -#if defined(MACINTOSH) || defined(MACH_O_CARBON) - -/* - * Check and create if needed the directory dirpath - */ -bool_ private_check_user_directory(cptr dirpath) -{ - /* Is this used anywhere else in *bands? */ - struct stat stat_buf; - - int ret; - - /* See if it already exists */ - ret = stat(dirpath, &stat_buf); - - /* It does */ - if (ret == 0) - { - /* Now we see if it's a directory */ - if ((stat_buf.st_mode & S_IFMT) == S_IFDIR) return (TRUE); - - /* - * Something prevents us from create a directory with - * the same pathname - */ - return (FALSE); - } - - /* No - this maybe the first time. Try to create a directory */ - else - { - /* Create the ~/.ToME directory */ - ret = mkdir(dirpath, 0700); - - /* An error occured */ - if (ret == -1) return (FALSE); - - /* Success */ - return (TRUE); - } -} - -/* - * Check existence of ".ToME/" directory in the user's - * home directory or try to create it if it doesn't exist. - * Returns FALSE if all the attempts fail. - */ -static bool_ check_create_user_dir(void) -{ - char dirpath[1024]; - char versionpath[1024]; - char savepath[1024]; -#ifdef PRIVATE_USER_PATH_DATA - char datapath[1024]; -#endif - - /* Get an absolute path from the filename */ - path_parse(dirpath, 1024, PRIVATE_USER_PATH); - strcpy(versionpath, dirpath); - strcat(versionpath, USER_PATH_VERSION); - strcpy(savepath, versionpath); - strcat(savepath, "/save"); -#ifdef PRIVATE_USER_PATH_DATA - strcpy(datapath, versionpath); - strcat(datapath, "/data"); -#endif - - return /* don't forget, the dirpath muts come first */ - private_check_user_directory(dirpath) && - private_check_user_directory(versionpath) && -#ifdef PRIVATE_USER_PATH_DATA - private_check_user_directory(datapath) && -#endif - private_check_user_directory(savepath); -} - - -/* - * Variant-dependent features: - * - * #define ALLOW_BIG_SCREEN (V, Ey, O, T.o.M.E., and Z. Dr's big screen needs - * more work. New S one is too idiosyncratic...) - * #define HAS_SCORE_MENU (V and T.o.M.E.) - * #define ANGBAND_CREATOR four letter code for your variant, if any. - * or use the default one. - * - * For [Z], you also have to say -- #define inkey_flag (p_ptr->inkey_flag) - * but before that, please, please consider using main-mac-carbon.c in [Z], - * that has some interesting features. - */ - -#define USE_DOUBLE_TILES -#define ALLOW_BIG_SCREEN -#define HAS_SCORE_MENU -#define ANGBAND_CREATOR 'PrnA' - -/* Default creator signature */ -#ifndef ANGBAND_CREATOR -# define ANGBAND_CREATOR 'A271' -#endif - - -/* - * Use rewritten asynchronous sound player - */ -#define USE_ASYNC_SOUND - - -/* - * A rather crude fix to reduce amount of redraw artefacts. - * Some fixed width fonts (i.e. Monaco) has characters with negative - * left bearings, so Term_wipe_mac or overwriting cannot completely - * erase them. This could be introduced to Classic Mac OS ports too, - * but since I've never heard any complaints and I don't like to - * make 68K ports even slower, I won't do so there. - */ -#define CLIP_HACK /* */ - -/* - * To cope with pref file related problems. It no longer has to be acculate, - * because preferences are stored in plist. - */ -#define PREF_VER_MAJOR VERSION_MAJOR -#define PREF_VER_MINOR VERSION_MINOR -#define PREF_VER_PATCH VERSION_PATCH -#define PREF_VER_EXTRA VERSION_EXTRA - - -/* - * In OS X + gcc, use <Carbon/Carbon.h>, <CoreServices/CoreServices.h> and - * <CoreFoundation/CoreFoundation.h> for ALL of these, including the Apple - * Event ones. <QuickTime/QuickTime.h> is used by the tile loading code. - */ -#ifdef MACH_O_CARBON - -#include <Carbon/Carbon.h> -#include <QuickTime/QuickTime.h> -#include <CoreServices/CoreServices.h> -#include <CoreFoundation/CoreFoundation.h> - -#else /* MACH_O_CARBON */ - -#include <Types.h> -#include <Gestalt.h> -#include <QuickDraw.h> -#include <Files.h> -#include <Fonts.h> -#include <Menus.h> -#include <Dialogs.h> -#include <Windows.h> -#include <Palettes.h> -#include <ToolUtils.h> -#include <Events.h> -#include <SegLoad.h> -#include <Resources.h> -#include <Controls.h> -#include <Memory.h> -#include <QDOffscreen.h> -#include <Sound.h> -#include <Navigation.h> -#include <CFPreferences.h> -#include <CFNumber.h> -#include <AppleEvents.h> -#include <EPPC.h> -#include <Folders.h> - -#endif /* MACH_O_CARBON */ - -/* MacOSX == Unix == Good */ -#ifdef USE_MACOSX -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> -#include <dirent.h> -#endif - - -/* - * Use "malloc()" instead of "NewPtr()" - */ -/* #define USE_MALLOC */ - - -/* - * Information about each of the 256 available colors - */ -static RGBColor color_info[256]; - - -#ifdef MACH_O_CARBON - -/* - * Creator signature and file type - Didn't I say that I abhor file name - * extentions? Names and metadata are entirely different set of notions. - */ -OSType _fcreator; -OSType _ftype; - -#endif /* MACH_O_CARBON */ - - -/* - * Forward declare - */ -typedef struct term_data term_data; - -/* - * Extra "term" data - */ -struct term_data -{ - term *t; - - Rect r; - - WindowPtr w; - - - short padding; - - short pixelDepth; - - GWorldPtr theGWorld; /* not used ... */ - - GDHandle theGDH; - - GDHandle mainSWGDH; /* not used ... */ - - Str15 title; - - s16b oops; - - s16b keys; - - s16b last; - - s16b mapped; - - s16b rows; - s16b cols; - - s16b font_id; - s16b font_size; - s16b font_face; - s16b font_mono; - - s16b font_o_x; - s16b font_o_y; - s16b font_wid; - s16b font_hgt; - - s16b tile_o_x; - s16b tile_o_y; - s16b tile_wid; - s16b tile_hgt; - - s16b size_wid; - s16b size_hgt; - - s16b size_ow1; - s16b size_oh1; - s16b size_ow2; - s16b size_oh2; -}; - - - - -/* - * Forward declare -- see below - */ -static bool_ CheckEvents(bool_ wait); - - -#ifndef MACH_O_CARBON - -/* - * Hack -- location of the main directory - */ -static short app_vol; -static long app_dir; - -#endif /* !MACH_O_CARBON */ - - -/* - * Delay handling of double-clicked savefiles - */ -Boolean open_when_ready = FALSE; - -/* - * Delay handling of pre-emptive "quit" event - */ -Boolean quit_when_ready = FALSE; - - -/* - * Aqua automatically supplies the Quit menu. - */ -static Boolean is_aqua = FALSE; - -/* - * Version of Mac OS - for version specific bug workarounds (; ;) - */ -static long mac_os_version; - - -/* - * Hack -- game in progress - */ -static int game_in_progress = 0; - - -/* - * Only do "SetPort()" when needed - */ -static WindowPtr active = NULL; - - -/* - * Maximum number of terms - */ -#define MAX_TERM_DATA 8 - - -/* - * An array of term_data's - */ -static term_data data[MAX_TERM_DATA]; - - -/* - * Note when "open"/"new" become valid - */ -static bool_ initialized = FALSE; - - - -/* - * Convert a C string to a pascal string in place - * - * This function may be defined elsewhere, but since it is so - * small, it is not worth finding the proper function name for - * all the different platforms. - */ -static void ctopstr(StringPtr src) -{ - int i; - byte len; - - /* Hack -- pointer */ - char *s = (char*)(src); - - len = strlen(s); - - /* Hack -- convert the string */ - for (i = len; i > 1; i--) s[i] = s[i - 1]; - - /* Hack -- terminate the string */ - s[0] = len; -} - - -#ifdef MACH_O_CARBON - -/* Carbon File Manager utilities by pelpel */ - -/* - * (Carbon) - * Convert a pathname to a corresponding FSSpec. - * Returns noErr on success. - */ -static OSErr path_to_spec(const char *path, FSSpec *spec) -{ - OSErr err; - FSRef ref; - - /* Convert pathname to FSRef ... */ - err = FSPathMakeRef(path, &ref, NULL); - if (err != noErr) return (err); - - /* ... then FSRef to FSSpec */ - err = FSGetCatalogInfo(&ref, kFSCatInfoNone, NULL, NULL, spec, NULL); - - /* Inform caller of success or failure */ - return (err); -} - - -/* - * (Carbon) - * Convert a FSSpec to a corresponding pathname. - * Returns noErr on success. - */ -static OSErr spec_to_path(const FSSpec *spec, char *buf, size_t size) -{ - OSErr err; - FSRef ref; - - /* Convert FSSpec to FSRef ... */ - err = FSpMakeFSRef(spec, &ref); - if (err != noErr) return (err); - - /* ... then FSRef to pathname */ - err = FSRefMakePath(&ref, buf, size); - - /* Inform caller of success or failure */ - return (err); -} - - -/* - * (Carbon) [via path_to_spec] - * Set creator and filetype of a file specified by POSIX-style pathname. - * Returns 0 on success, -1 in case of errors. - */ -int fsetfileinfo(char *pathname, OSType fcreator, OSType ftype) -{ - OSErr err; - FSSpec spec; - FInfo info; - - /* Convert pathname to FSSpec */ - if (path_to_spec(pathname, &spec) != noErr) return ( -1); - - /* Obtain current finder info of the file */ - if (FSpGetFInfo(&spec, &info) != noErr) return ( -1); - - /* Overwrite creator and type */ - info.fdCreator = fcreator; - info.fdType = ftype; - err = FSpSetFInfo(&spec, &info); - - /* Inform caller of success or failure */ - return ((err == noErr) ? 0 : -1); -} - - -#else /* MACH_O_CARBON */ - -/* -* Convert refnum+vrefnum+fname into a full file name -* Store this filename in 'buf' (make sure it is long enough) -* Note that 'fname' looks to be a "pascal" string -*/ -static void refnum_to_name(char *buf, long refnum, short vrefnum, char *fname) -{ - DirInfo pb; - Str255 name; - int err; - int i, j; - - char res[1000]; - - i = 999; - - res[i] = 0; - i--; - for (j = 1; j <= fname[0]; j++) - { - res[i - fname[0] + j] = fname[j]; - } - i -= fname[0]; - - pb.ioCompletion = NULL; - pb.ioNamePtr = name; - pb.ioVRefNum = vrefnum; - pb.ioDrParID = refnum; - pb.ioFDirIndex = -1; - - while (1) - { - pb.ioDrDirID = pb.ioDrParID; - err = PBGetCatInfoSync((CInfoPBPtr) & pb); - res[i] = ':'; - i--; - for (j = 1; j <= name[0]; j++) - { - res[i - name[0] + j] = name[j]; - } - i -= name[0]; - - if (pb.ioDrDirID == fsRtDirID) break; - } - - /* Extract the result */ - for (j = 0, i++; res[i]; j++, i++) buf[j] = res[i]; - buf[j] = 0; -} - - -/* -* Convert a pascal string in place -* -* This function may be defined elsewhere, but since it is so -* small, it is not worth finding the proper function name for -* all the different platforms. -*/ -static void ptocstr(StringPtr src) -{ - int i; - - /* Hack -- pointer */ - char *s = (char*)(src); - - /* Hack -- convert the string */ - for (i = s[0]; i; i--, s++) s[0] = s[1]; - - /* Hack -- terminate the string */ - s[0] = '\0'; -} - - -/* -* Utility routines by Steve Linberg -* -* The following three routines (pstrcat, pstrinsert, and PathNameFromDirID) -* were taken from the Think Reference section called "Getting a Full Pathname" -* (under the File Manager section). We need PathNameFromDirID to get the -* full pathname of the opened savefile, making no assumptions about where it -* is. -* -* I had to hack PathNameFromDirID a little for MetroWerks, but it's awfully -* nice. -*/ -static void pstrcat(StringPtr dst, StringPtr src) -{ - /* copy string in */ - BlockMove(src + 1, dst + *dst + 1, *src); - - /* adjust length byte */ - *dst += *src; -} - - -/* -* pstrinsert - insert string 'src' at beginning of string 'dst' -*/ -static void pstrinsert(StringPtr dst, StringPtr src) -{ - /* make room for new string */ - BlockMove(dst + 1, dst + *src + 1, *dst); - - /* copy new string in */ - BlockMove(src + 1, dst + 1, *src); - - /* adjust length byte */ - *dst += *src; -} - - -static void PathNameFromDirID(long dirID, short vRefNum, StringPtr fullPathName) -{ - CInfoPBRec block; - Str255 directoryName; - OSErr err; - - fullPathName[0] = '\0'; - - block.dirInfo.ioDrParID = dirID; - block.dirInfo.ioNamePtr = directoryName; - - while (1) - { - block.dirInfo.ioVRefNum = vRefNum; - block.dirInfo.ioFDirIndex = -1; - block.dirInfo.ioDrDirID = block.dirInfo.ioDrParID; - err = PBGetCatInfoSync(&block); - pstrcat(directoryName, (StringPtr)"\p:"); - pstrinsert(fullPathName, directoryName); - if (block.dirInfo.ioDrDirID == 2) break; - } -} - -#endif /* MACH_O_CARBON */ - - - - -/* - * Center a rectangle inside another rectangle - * - * Consider using RepositionWindow() whenever possible - */ -static void center_rect(Rect *r, Rect *s) -{ - int centerx = (s->left + s->right) / 2; - int centery = (2 * s->top + s->bottom) / 3; - int dx = centerx - (r->right - r->left) / 2 - r->left; - int dy = centery - (r->bottom - r->top) / 2 - r->top; - r->left += dx; - r->right += dx; - r->top += dy; - r->bottom += dy; -} - - -/* - * Activate a given window, if necessary - */ -static void activate(WindowPtr w) -{ - /* Activate */ - if (active != w) - { - /* Activate */ - if (w) SetPort(GetWindowPort(w)); - - /* Remember */ - active = w; - } -} - - -/* - * Display a warning message - */ -static void mac_warning(cptr warning) -{ - Str255 text; - int len, i; - - /* Limit of 250 chars */ - len = strlen(warning); - if (len > 250) len = 250; - - /* Make a "Pascal" string */ - text[0] = len; - for (i = 0; i < len; i++) text[i + 1] = warning[i]; - - /* Prepare the dialog box values */ - ParamText(text, "\p", "\p", "\p"); - - /* Display the Alert, wait for Okay */ - Alert(129, 0L); -} - - - -/*** Some generic functions ***/ - -/* - * Hack -- activate a color (0 to 255) - */ -static void term_data_color(term_data *td, int a) -{ - /* Activate the color */ - if (td->last != a) - { - /* Activate the color */ - RGBForeColor(&color_info[a]); - - /* Memorize color */ - td->last = a; - } -} - - -/* - * Hack -- Apply and Verify the "font" info - * - * This should usually be followed by "term_data_check_size()" - * - * XXX XXX To force (re)initialisation of td->tile_wid and td->tile_hgt - * you have to reset them to zero before this function is called. - * XXX XXX This is automatic when the program starts because the term_data - * array is WIPE'd by term_data_hack, but isn't in the other cases, i.e. - * font, font style and size changes. - */ -static void term_data_check_font(term_data *td) -{ - int i; - - FontInfo info; - - WindowPtr old = active; - - - /* Activate */ - activate(td->w); - - /* Instantiate font */ - TextFont(td->font_id); - TextSize(td->font_size); - TextFace(td->font_face); - - /* Extract the font info */ - GetFontInfo(&info); - - /* Assume monospaced */ - td->font_mono = TRUE; - - /* Extract the font sizing values XXX XXX XXX */ - td->font_wid = CharWidth('@'); /* info.widMax; */ - td->font_hgt = info.ascent + info.descent; - td->font_o_x = 0; - td->font_o_y = info.ascent; - - /* Check important characters */ - for (i = 33; i < 127; i++) - { - /* Hack -- notice non-mono-space */ - if (td->font_wid != CharWidth(i)) td->font_mono = FALSE; - - /* Hack -- collect largest width */ - if (td->font_wid < CharWidth(i)) td->font_wid = CharWidth(i); - } - - /* Set default offsets */ - td->tile_o_x = td->font_o_x; - td->tile_o_y = td->font_o_y; - - /* Set default tile size */ - if (td->tile_wid == 0) td->tile_wid = td->font_wid; - if (td->tile_hgt == 0) td->tile_hgt = td->font_hgt; - - /* Re-activate the old window */ - activate(old); -} - - -/* - * Hack -- Apply and Verify the "size" info - */ -static void term_data_check_size(term_data *td) -{ - if (td == &data[0]) - { -#ifndef ALLOW_BIG_SCREEN - - /* Forbid resizing of the Angband window */ - td->cols = 80; - td->rows = 24; - -#else - - /* Enforce minimal size */ - if (td->cols < 80) td->cols = 80; - if (td->rows < 24) td->rows = 24; - -#endif /* !ALLOW_BIG_SCREEN */ - } - - /* Information windows can be much smaller */ - else - { - if (td->cols < 1) td->cols = 1; - if (td->rows < 1) td->rows = 1; - } - - /* Enforce maximal sizes */ - if (td->cols > 255) td->cols = 255; - if (td->rows > 255) td->rows = 255; - - /* Minimal tile size */ - if (td->tile_wid < td->font_wid) td->tile_wid = td->font_wid; - if (td->tile_hgt < td->font_hgt) td->tile_hgt = td->font_hgt; - - /* Default tile offsets */ - td->tile_o_x = (td->tile_wid - td->font_wid) / 2; - td->tile_o_y = (td->tile_hgt - td->font_hgt) / 2; - - /* Minimal tile offsets */ - if (td->tile_o_x < 0) td->tile_o_x = 0; - if (td->tile_o_y < 0) td->tile_o_y = 0; - - /* Apply font offsets */ - td->tile_o_x += td->font_o_x; - td->tile_o_y += td->font_o_y; - - /* Calculate full window size */ - td->size_wid = td->cols * td->tile_wid + td->size_ow1 + td->size_ow2; - td->size_hgt = td->rows * td->tile_hgt + td->size_oh1 + td->size_oh2; - - { - BitMap tScreen; - - /* Get current screen */ - (void)GetQDGlobalsScreenBits(&tScreen); - - /* Verify the top */ - if (td->r.top > tScreen.bounds.bottom - td->size_hgt) - { - td->r.top = tScreen.bounds.bottom - td->size_hgt; - } - - /* Verify the top */ - if (td->r.top < tScreen.bounds.top + GetMBarHeight()) - { - td->r.top = tScreen.bounds.top + GetMBarHeight(); - } - - /* Verify the left */ - if (td->r.left > tScreen.bounds.right - td->size_wid) - { - td->r.left = tScreen.bounds.right - td->size_wid; - } - - /* Verify the left */ - if (td->r.left < tScreen.bounds.left) - { - td->r.left = tScreen.bounds.left; - } - } - - /* Calculate bottom right corner */ - td->r.right = td->r.left + td->size_wid; - td->r.bottom = td->r.top + td->size_hgt; - - /* Assume no graphics */ - td->t->higher_pict = FALSE; - td->t->always_pict = FALSE; - - - /* Handle graphics */ - if (use_graphics) - { - /* Use higher pict whenever possible */ - if (td->font_mono) td->t->higher_pict = TRUE; - - /* Use always_pict only when necessary */ - else td->t->always_pict = TRUE; - } - - /* Fake mono-space */ - if (!td->font_mono || - (td->font_wid != td->tile_wid) || - (td->font_hgt != td->tile_hgt)) - { - /* - * Handle fake monospace - * - * pelpel: This is SLOW. Couldn't we use CharExtra - * and SpaceExtra for monospaced fonts? - */ - if (td->t->higher_pict) td->t->higher_pict = FALSE; - td->t->always_pict = TRUE; - } -} - - -/* - * Hack -- resize a term_data - * - * This should normally be followed by "term_data_redraw()" - */ -static void term_data_resize(term_data *td) -{ - /* - * Actually resize the window - * - * ResizeWindow is the preferred API call, but it cannot - * be used here. - */ - SizeWindow(td->w, td->size_wid, td->size_hgt, 0); -} - - - -/* - * Hack -- redraw a term_data - * - * Note that "Term_redraw()" calls "TERM_XTRA_CLEAR" - */ -static void term_data_redraw(term_data *td) -{ - term *old = Term; - Rect tRect; - - /* Activate the term */ - Term_activate(td->t); - - /* Redraw the contents */ - Term_redraw(); - - /* Flush the output */ - Term_fresh(); - - /* Restore the old term */ - Term_activate(old); - - /* No need to redraw */ - ValidWindowRect(td->w, GetPortBounds(GetWindowPort(td->w), &tRect)); -} - - -/* - * Graphics support - */ - -/* Set by Term_xtra_mac_react */ -#ifdef MACH_O_CARBON -static CFStringRef pict_id; /* PICT id of image tiles */ -#else -static int pict_id; /* PICT id of image tiles */ -#endif /* MACH_O_CARBON */ - -static int graf_width; /* Width of a tile in pixels */ -static int graf_height; /* Height of a tile in pixels */ - -/* Calculated by PICT loading code */ -static int pict_cols; /* Number of columns in tiles */ -static int pict_rows; /* Number of rows in tiles */ - -/* Available graphics modes */ -#define GRAF_MODE_NONE 0 /* plain ASCII */ -#define GRAF_MODE_8X8 1 /* 8x8 tiles */ -#define GRAF_MODE_16X16 2 /* 16x16 tiles */ -#define GRAF_MODE_32X32 3 /* 32x32 tiles */ - -static int graf_mode = GRAF_MODE_NONE; /* current graphics mode */ -static int graf_mode_req = GRAF_MODE_NONE; /* requested graphics mode */ - -#define TR_NONE 0 /* No transparency */ -#define TR_OVER 1 /* Overwriting with transparent black pixels */ -static int transparency_mode = TR_NONE; /* types of transparency effect */ - - -/* - * Forward Declare - */ -typedef struct FrameRec FrameRec; - -/* - * Frame - * - * - GWorld for the frame image - * - Handle to pix map (saved for unlocking/locking) - * - Pointer to color pix map (valid only while locked) - */ -struct FrameRec -{ - GWorldPtr framePort; - PixMapHandle framePixHndl; - PixMapPtr framePix; -}; - - -/* - * The global picture data - */ -static FrameRec *frameP = NULL; - - -/* - * Lock a frame - */ -static void BenSWLockFrame(FrameRec *srcFrameP) -{ - PixMapHandle pixMapH; - - pixMapH = GetGWorldPixMap(srcFrameP->framePort); - (void)LockPixels(pixMapH); - HLockHi((Handle)pixMapH); - srcFrameP->framePixHndl = pixMapH; - srcFrameP->framePix = (PixMapPtr)(*(Handle)pixMapH); -} - - -/* - * Unlock a frame - */ -static void BenSWUnlockFrame(FrameRec *srcFrameP) -{ - if (srcFrameP->framePort != NULL) - { - HUnlock((Handle)srcFrameP->framePixHndl); - UnlockPixels(srcFrameP->framePixHndl); - } - - srcFrameP->framePix = NULL; -} - - - -#ifdef MACH_O_CARBON - -/* Moving graphics resources into data fork -- pelpel */ - -/* - * (Carbon, Bundle) - * Given base and type names of a resource, find a file in the - * current application bundle and return its FSSpec in the third argument. - * Returns true on success, false otherwise. - * e.g. get_resource_spec(CFSTR("8x8"), CFSTR("png"), &spec); - */ -static Boolean get_resource_spec( - CFStringRef base_name, CFStringRef type_name, FSSpec *spec) -{ - CFURLRef res_url; - FSRef ref; - - /* Find the tile resource specified in the current bundle */ - res_url = CFBundleCopyResourceURL( - CFBundleGetMainBundle(), base_name, type_name, NULL); - - /* Oops */ - if (res_url == NULL) return (false); - - /* Convert CFURL to FSRef */ - (void)CFURLGetFSRef(res_url, &ref); - - /* Convert FSRef to FSSpec */ - (void)FSGetCatalogInfo(&ref, kFSCatInfoNone, NULL, NULL, spec, NULL); - - /* Free allocated CF data */ - CFRelease(res_url); - - /* Success */ - return (true); -} - - -/* - * (QuickTime) - * Create a off-screen GWorld from contents of a file specified by a FSSpec. - * - * Globals referenced: data[0], graf_height, graf_width - * Globals updated: pict_rows, pict_cols. - */ -static OSErr create_gworld_from_spec( - GWorldPtr *tile_gw, FSSpec *tile_spec) -{ - OSErr err; - GraphicsImportComponent gi; - GWorldPtr gw, tmp_gw; - GDHandle gdh, tmp_gdh; - Rect r; - SInt16 depth; - - /* See if QuickTime understands the file format */ - err = GetGraphicsImporterForFile(tile_spec, &gi); - - /* Oops */ - if (err != noErr) return (err); - - /* Get depth */ - depth = data[0].pixelDepth; - - /* Get GDH */ - gdh = data[0].theGDH; - - /* Retrieve the rect of the image */ - err = GraphicsImportGetNaturalBounds(gi, &r); - - /* Adjust it, so that the upper left corner becomes (0, 0) */ - OffsetRect(&r, -r.left, -r.top); - - /* Calculate and set numbers of rows and columns */ - pict_rows = r.bottom / graf_height; - pict_cols = r.right / graf_width; - - /* Create a GWorld */ - err = NewGWorld(&gw, depth, &r, NULL, gdh, noNewDevice); - - /* Oops */ - if (err != noErr) return (err); - - /* Save the pointer to the GWorld */ - *tile_gw = gw; - - /* Save the current GWorld */ - GetGWorld(&tmp_gw, &tmp_gdh); - - /* Activate the newly created GWorld */ - (void)GraphicsImportSetGWorld(gi, gw, NULL); - - /* Prevent pixmap from moving while drawing */ - (void)LockPixels(GetGWorldPixMap(gw)); - - /* Clear the pixels */ - EraseRect(&r); - - /* Draw the image into it */ - (void)GraphicsImportDraw(gi); - - /* Release the lock*/ - UnlockPixels(GetGWorldPixMap(gw)); - - /* Restore GWorld */ - SetGWorld(tmp_gw, tmp_gdh); - - /* Close the image importer */ - CloseComponent(gi); - - /* Success */ - return (noErr); -} - -#else /* MACH_O_CARBON */ - -static OSErr BenSWCreateGWorldFromPict( - GWorldPtr *pictGWorld, PicHandle pictH) -{ - OSErr err; - GWorldPtr saveGWorld; - GDHandle saveGDevice; - GWorldPtr tempGWorld; - Rect pictRect; - short depth; - GDHandle theGDH; - - tempGWorld = NULL; - - /* Reset */ - *pictGWorld = NULL; - - /* Get depth */ - depth = data[0].pixelDepth; - - /* Get GDH */ - theGDH = data[0].theGDH; - - /* Obtain size rectangle */ - pictRect = (**pictH).picFrame; - OffsetRect(&pictRect, -pictRect.left, -pictRect.top); - - /* Calculate and set numbers of rows and columns */ - pict_rows = pictRect.bottom / graf_height; - pict_cols = pictRect.right / graf_width; - - /* Create a GWorld */ - err = NewGWorld(&tempGWorld, depth, &pictRect, nil, theGDH, noNewDevice); - - /* Oops */ - if (err != noErr) return (err); - - /* Save pointer */ - *pictGWorld = tempGWorld; - - /* Save GWorld */ - GetGWorld(&saveGWorld, &saveGDevice); - - /* Activate */ - SetGWorld(tempGWorld, nil); - - /* Dump the pict into the GWorld */ - (void)LockPixels(GetGWorldPixMap(tempGWorld)); - EraseRect(&pictRect); - DrawPicture(pictH, &pictRect); - UnlockPixels(GetGWorldPixMap(tempGWorld)); - - /* Restore GWorld */ - SetGWorld(saveGWorld, saveGDevice); - - /* Success */ - return (0); -} - -#endif /* MACH_O_CARBON */ - - -/* - * Init the global "frameP" - */ -static errr globe_init(void) -{ - OSErr err; - - GWorldPtr tempPictGWorldP; - -#ifdef MACH_O_CARBON - FSSpec pict_spec; -#else - PicHandle newPictH; -#endif /* MACH_O_CARBON */ - - - /* Use window XXX XXX XXX */ - SetPort(GetWindowPort(data[0].w)); - - -#ifdef MACH_O_CARBON - - /* Get the tile resources */ - if (!get_resource_spec(pict_id, CFSTR("png"), &pict_spec)) return ( -1); - - /* Create GWorld */ - err = create_gworld_from_spec(&tempPictGWorldP, &pict_spec); - -#else /* MACH_O_CARBON */ - - /* Get the pict resource */ - if ((newPictH = GetPicture(pict_id)) == 0) return ( -1); - - /* Create GWorld */ - err = BenSWCreateGWorldFromPict(&tempPictGWorldP, newPictH); - - /* Release resource */ - ReleaseResource((Handle)newPictH); - -#endif /* MACH_O_CARBON */ - - /* Error */ - if (err != noErr) return (err); - - /* Create the frame */ - frameP = (FrameRec*)NewPtrClear((Size)sizeof(FrameRec)); - - /* Analyze result */ - if (frameP == NULL) return ( -1); - - /* Save GWorld */ - frameP->framePort = tempPictGWorldP; - - /* Lock it */ - BenSWLockFrame(frameP); - - /* Success */ - return (noErr); -} - - -/* - * Nuke the global "frameP" - */ -static errr globe_nuke(void) -{ - /* Dispose */ - if (frameP) - { - /* Unlock */ - BenSWUnlockFrame(frameP); - - /* Dispose of the GWorld */ - DisposeGWorld(frameP->framePort); - - /* Dispose of the memory */ - DisposePtr((Ptr)frameP); - - /* Forget */ - frameP = NULL; - } - - /* Flush events */ - FlushEvents(everyEvent, 0); - - /* Success */ - return (0); -} - - -#ifdef USE_ASYNC_SOUND - -/* - * Asynchronous sound player - completely revised (beta) - */ -#if defined(USE_QT_SOUND) && !defined(MACH_O_CARBON) -# undef USE_QT_SOUND -#endif /* USE_QT_SOUND && !MACH_O_CARBON */ - -/* - * How many sound channels will be pooled - * - * Was: 20, but I don't think we need 20 sound effects playing - * simultaneously :) -- pelpel - */ -#define MAX_CHANNELS 8 - -/* - * A pool of sound channels - */ -static SndChannelPtr channels[MAX_CHANNELS]; - -/* - * Status of the channel pool - */ -static Boolean channel_initialised = FALSE; - -/* - * Data handles containing sound samples - */ -static SndListHandle samples[SOUND_MAX]; - -/* - * Reference counts of sound samples - */ -static SInt16 sample_refs[SOUND_MAX]; - -#define SOUND_VOLUME_MIN 0 /* Default minimum sound volume */ -#define SOUND_VOLUME_MAX 255 /* Default maximum sound volume */ -#define VOLUME_MIN 0 /* Minimum sound volume in % */ -#define VOLUME_MAX 100 /* Maximum sound volume in % */ -#define VOLUME_INC 5 /* Increment sound volume in % */ - -/* - * I'm just too lazy to write a panel for this XXX XXX - */ -static int sound_volume = SOUND_VOLUME_MAX; - - -#ifdef USE_QT_SOUND - -/* - * QuickTime sound, by Ron Anderson - * - * I didn't choose to use Windows-style .ini files (Ron wrote a parser - * for it, but...), nor did I use lib/xtra directory, hoping someone - * would code plist-based configuration code in the future -- pelpel - */ - -/* - * (QuickTime) - * Load sound effects from data-fork resources. They are wav files - * with the same names as angband_sound_name[] (variable.c) - * - * Globals referenced: angband_sound_name[] - * Globals updated: samples[] (they can be *huge*) - */ -static void load_sounds(void) -{ - OSErr err; - int i; - - /* Start QuickTime */ - err = EnterMovies(); - - /* Error */ - if (err != noErr) return; - - /* - * This loop may take a while depending on the count and size of samples - * to load. - * - * We should use a progress dialog for this. - */ - for (i = 1; i < SOUND_MAX; i++) - { - /* Apple APIs always give me headacke :( */ - CFStringRef name; - FSSpec spec; - SInt16 file_id; - SInt16 res_id; - Str255 movie_name; - Movie movie; - Track track; - Handle h; - Boolean res; - - /* Allocate CFString with the name of sound event to be processed */ - name = CFStringCreateWithCString(NULL, angband_sound_name[i], - kTextEncodingUS_ASCII); - - /* Error */ - if (name == NULL) continue; - - /* Find sound sample resource with the same name */ - res = get_resource_spec(name, CFSTR("wav"), &spec); - - /* Free the reference to CFString */ - CFRelease(name); - - /* Error */ - if (!res) continue; - - /* Open the sound file */ - err = OpenMovieFile(&spec, &file_id, fsRdPerm); - - /* Error */ - if (err != noErr) continue; - - /* Create Movie from the file */ - err = NewMovieFromFile(&movie, file_id, &res_id, movie_name, - newMovieActive, NULL); - - /* Error */ - if (err != noErr) goto close_file; - - /* Get the first track of the movie */ - track = GetMovieIndTrackType(movie, 1, AudioMediaCharacteristic, - movieTrackCharacteristic | movieTrackEnabledOnly ); - - /* Error */ - if (track == NULL) goto close_movie; - - /* Allocate a handle to store sample */ - h = NewHandle(0); - - /* Error */ - if (h == NULL) goto close_track; - - /* Dump the sample into the handle */ - err = PutMovieIntoTypedHandle(movie, track, soundListRsrc, h, 0, - GetTrackDuration(track), 0L, NULL); - - /* Success */ - if (err == noErr) - { - /* Store the handle in the sample list */ - samples[i] = (SndListHandle)h; - } - - /* Failure */ - else - { - /* Free unused handle */ - DisposeHandle(h); - } - - /* Free the track */ -close_track: - DisposeMovieTrack(track); - - /* Free the movie */ -close_movie: - DisposeMovie(movie); - - /* Close the movie file */ -close_file: - CloseMovieFile(file_id); - } - - /* Stop QuickTime */ - ExitMovies(); -} - -#else /* USE_QT_SOUND */ - -/* -* Return a handle of 'snd ' resource given Angband sound event number, -* or NULL if it isn't found. -* -* Globals referenced: angband_sound_name[] (variable.c) -*/ -static SndListHandle find_sound(int num) -{ -Str255 sound; - -/* Get the proper sound name */ -strnfmt((char*)sound + 1, 255, "%.16s.wav", angband_sound_name[num]); -sound[0] = strlen((char*)sound + 1); - -/* Obtain resource XXX XXX XXX */ -return ((SndListHandle)GetNamedResource('snd ', sound)); -} - -#endif /* USE_QT_SOUND */ - - -/* - * Clean up sound support - to be called when the game exits. - * - * Globals referenced: channels[], samples[], sample_refs[]. - */ -static void cleanup_sound(void) -{ - int i; - - /* No need to clean it up */ - if (!channel_initialised) return; - - /* Dispose channels */ - for (i = 0; i < MAX_CHANNELS; i++) - { - /* Drain sound commands and free the channel */ - SndDisposeChannel(channels[i], TRUE); - } - - /* Free sound data */ - for (i = 1; i < SOUND_MAX; i++) - { - /* Still locked */ - if ((sample_refs[i] > 0) && (samples[i] != NULL)) - { - /* Unlock it */ - HUnlock((Handle)samples[i]); - } - -#ifndef USE_QT_SOUND - - /* Release it */ - if (samples[i]) ReleaseResource((Handle)samples[i]); - -#else -/* Free handle */ - if (samples[i]) DisposeHandle((Handle)samples[i]); - -#endif /* !USE_QT_SOUND */ - } -} - - -/* - * Play sound effects asynchronously -- pelpel - * - * I don't believe those who first started using the previous implementations - * imagined this is *much* more complicated as it may seem. Anyway, - * introduced round-robin scheduling of channels and made it much more - * paranoid about HLock/HUnlock. - * - * XXX XXX de-refcounting, HUnlock and ReleaseResource should be done - * using channel's callback procedures, which set global flags, and - * a procedure hooked into CheckEvents does housekeeping. On the other - * hand, this lazy reclaiming strategy keeps things simple (no interrupt - * time code) and provides a sort of cache for sound data. - * - * Globals referenced: channel_initialised, channels[], samples[], - * sample_refs[]. - * Globals updated: channel_initialised, channels[], sample_refs[]. - * Only in !USE_QT_SOUND, samples[]. - */ -static void play_sound(int num, int vol) -{ - OSErr err; - int i; - int prev_num; - SndListHandle h; - SndChannelPtr chan; - SCStatus status; - - static int next_chan; - static SInt16 channel_occupants[MAX_CHANNELS]; - static SndCommand volume_cmd, quiet_cmd; - - - /* Initialise sound channels */ - if (!channel_initialised) - { - for (i = 0; i < MAX_CHANNELS; i++) - { - /* Paranoia - Clear occupant table */ - /* channel_occupants[i] = 0; */ - - /* Create sound channel for all sounds to play from */ - err = SndNewChannel(&channels[i], sampledSynth, initMono, NULL); - - /* Error */ - if (err != noErr) - { - /* Free channels */ - while (--i >= 0) - { - SndDisposeChannel(channels[i], TRUE); - } - - /* Notify error */ - plog("Cannot initialise sound channels!"); - - /* Cancel request */ - use_sound = arg_sound = FALSE; - - /* Failure */ - return; - } - } - - /* First channel to use */ - next_chan = 0; - - /* Prepare volume command */ - volume_cmd.cmd = volumeCmd; - volume_cmd.param1 = 0; - volume_cmd.param2 = 0; - - /* Prepare quiet command */ - quiet_cmd.cmd = quietCmd; - quiet_cmd.param1 = 0; - quiet_cmd.param2 = 0; - - /* Initialisation complete */ - channel_initialised = TRUE; - } - - /* Paranoia */ - if ((num <= 0) || (num >= SOUND_MAX)) return; - - /* Prepare volume command */ - volume_cmd.param2 = (SInt16)((vol << 4) | vol); - - /* Channel to use (round robin) */ - chan = channels[next_chan]; - - /* See if the resource is already in use */ - if (sample_refs[num] > 0) - { - /* Resource in use */ - h = samples[num]; - - /* Increase the refcount */ - sample_refs[num]++; - } - - /* Sound is not currently in use */ - else - { - /* Get handle for the sound */ -#ifdef USE_QT_SOUND - h = samples[num]; -#else - h = find_sound(num); -#endif /* USE_QT_SOUND */ - - /* Sample not available */ - if (h == NULL) return; - -#ifndef USE_QT_SOUND - - /* Load resource */ - LoadResource((Handle)h); - - /* Remember it */ - samples[num] = h; - -#endif /* !USE_QT_SOUND */ - - /* Lock the handle */ - HLock((Handle)h); - - /* Initialise refcount */ - sample_refs[num] = 1; - } - - /* Poll the channel */ - err = SndChannelStatus(chan, sizeof(SCStatus), &status); - - /* It isn't available */ - if ((err != noErr) || status.scChannelBusy) - { - /* Shut it down */ - SndDoImmediate(chan, &quiet_cmd); - } - - /* Previously played sound on this channel */ - prev_num = channel_occupants[next_chan]; - - /* Process previously played sound */ - if (prev_num != 0) - { - /* Decrease refcount */ - sample_refs[prev_num]--; - - /* We can free it now */ - if (sample_refs[prev_num] <= 0) - { - /* Unlock */ - HUnlock((Handle)samples[prev_num]); - -#ifndef USE_QT_SOUND - - /* Release */ - ReleaseResource((Handle)samples[prev_num]); - - /* Forget handle */ - samples[prev_num] = NULL; - -#endif /* !USE_QT_SOUND */ - - /* Paranoia */ - sample_refs[prev_num] = 0; - } - } - - /* Remember this sound as the current occupant of the channel */ - channel_occupants[next_chan] = num; - - /* Set up volume for channel */ - SndDoImmediate(chan, &volume_cmd); - - /* Play new sound asynchronously */ - SndPlay(chan, h, TRUE); - - /* Schedule next channel (round robin) */ - next_chan++; - if (next_chan >= MAX_CHANNELS) next_chan = 0; -} - -#endif /* USE_ASYNC_SOUND */ - - - - -/*** Support for the "z-term.c" package ***/ - - -/* - * Initialize a new Term - * - * Note also the "window type" called "noGrowDocProc", which might be more - * appropriate for the main "screen" window. - * - * Note the use of "srcCopy" mode for optimized screen writes. - */ -static void Term_init_mac(term *t) -{ - term_data *td = (term_data*)(t->data); - WindowAttributes wattrs; - OSStatus err; - - static RGBColor black = {0x0000, 0x0000, 0x0000}; - static RGBColor white = {0xFFFF, 0xFFFF, 0xFFFF}; - -#ifndef ALLOW_BIG_SCREEN - - /* Every window has close and collapse boxes */ - wattrs = kWindowCloseBoxAttribute | kWindowCollapseBoxAttribute; - - /* Information windows are resizable */ - if (td != &data[0]) wattrs |= kWindowResizableAttribute; - -#else - - /* Big screen - every window has close, collapse and resize boxes */ - wattrs = kWindowCloseBoxAttribute | - kWindowCollapseBoxAttribute | - kWindowResizableAttribute; - -#endif /* !ALLOW_BIG_SCREEN */ - - /* Make the window */ - err = CreateNewWindow( - kDocumentWindowClass, - wattrs, - &td->r, - &td->w); - - /* - * XXX XXX Although the original main-mac.c doesn't perform error - * checking, it should be done here. - */ - - /* Set window title */ - SetWTitle(td->w, td->title); - - /* Activate the window */ - activate(td->w); - - /* Erase behind words */ - TextMode(srcCopy); - - /* Apply and Verify */ - term_data_check_font(td); - term_data_check_size(td); - - /* Resize the window */ - term_data_resize(td); - - - /* Prepare the colors (real colors) */ - RGBBackColor(&black); - RGBForeColor(&white); - - /* Block */ - { - Rect globalRect; - GDHandle mainGDH; - GDHandle currentGDH; - GWorldPtr windowGWorld; - PixMapHandle basePixMap; - - /* Obtain the global rect */ - GetWindowBounds((WindowRef)td->w, kWindowContentRgn, &globalRect); - - /* Obtain the proper GDH */ - mainGDH = GetMaxDevice(&globalRect); - - /* Extract GWorld and GDH */ - GetGWorld(&windowGWorld, ¤tGDH); - - /* Obtain base pixmap */ - basePixMap = (**mainGDH).gdPMap; - - /* Save pixel depth */ - td->pixelDepth = (**basePixMap).pixelSize; - - /* Save Window GWorld - unused */ - td->theGWorld = windowGWorld; - - /* Save Window GDH */ - td->theGDH = currentGDH; - - /* Save main GDH - unused */ - td->mainSWGDH = mainGDH; - } - - { - Rect portRect; - - /* Get current Rect */ - GetPortBounds(GetWindowPort(td->w), &portRect); - - /* Clip to the window */ - ClipRect(&portRect); - - /* Erase the window */ - EraseRect(&portRect); - - /* Invalidate the window */ - InvalWindowRect(td->w, &portRect); - } - - /* - * A certain release of OS X fails to display windows at proper - * locations (_ _#) - */ - if ((mac_os_version >= 0x1000) && (mac_os_version < 0x1010)) - { - /* Hack - Make sure the window is displayed at (r.left,r.top) */ - MoveWindow(td->w, td->r.left, td->r.top, 1); - } - - /* Display the window if needed */ - if (td->mapped) - { - TransitionWindow(td->w, - kWindowZoomTransitionEffect, kWindowShowTransitionAction, NULL); - } - - /* Hack -- set "mapped" flag */ - t->mapped_flag = td->mapped; - - /* Forget color */ - td->last = -1; -} - - - -/* - * Nuke an old Term - */ -static void Term_nuke_mac(term *t) -{ - /* XXX */ -} - - - -/* - * Unused - */ -static errr Term_user_mac(int n) -{ - /* Success */ - return (0); -} - - - -/* - * React to changes - */ -static errr Term_xtra_mac_react(void) -{ - term_data *td = (term_data*)(Term->data); - - int i; - - - /* Reset color */ - td->last = -1; - - /* Update colors */ - for (i = 0; i < 256; i++) - { - u16b rv, gv, bv; - - /* Extract the R,G,B data */ - rv = angband_color_table[i][1]; - gv = angband_color_table[i][2]; - bv = angband_color_table[i][3]; - - /* Save the actual color */ - color_info[i].red = (rv | (rv << 8)); - color_info[i].green = (gv | (gv << 8)); - color_info[i].blue = (bv | (bv << 8)); - } - - - /* Handle sound */ - if (use_sound != arg_sound) - { - /* Apply request */ - use_sound = arg_sound; - } - - - /* Handle graphics */ - if (graf_mode_req != graf_mode) - { - /* dispose old GWorld's if present */ - globe_nuke(); - - /* - * Setup parameters according to request - * - * In [Z], you have to set use_graphics and arg_graphics to - * GRAPHICS_NONE, GRAPHICS_ORIGINAL or GRAPHICS_ADAM_BOLT, and - * comment ANGBAND_GRAF out. - */ - switch (graf_mode_req) - { - /* ASCII - no graphics whatsoever */ - case GRAF_MODE_NONE: - { - use_graphics = arg_graphics = FALSE; - transparency_mode = TR_NONE; - break; - } - - /* - * 8x8 tiles (PICT id 1001) - * no transparency effect - * "old" graphics definitions - */ - case GRAF_MODE_8X8: - { - use_graphics = arg_graphics = TRUE; - ANGBAND_GRAF = "old"; - transparency_mode = TR_NONE; -#ifdef MACH_O_CARBON - pict_id = CFSTR("8x8"); -#else - pict_id = 1001; -#endif /* MACH_O_CARBON */ - graf_width = graf_height = 8; - break; - } - - /* - * 16x16 tiles (images: PICT id 1002, masks: PICT id 1003) - * with transparency effect - * "new" graphics definitions - */ - case GRAF_MODE_16X16: - { - use_graphics = arg_graphics = TRUE; - ANGBAND_GRAF = "new"; - transparency_mode = TR_OVER; -#ifdef MACH_O_CARBON - pict_id = CFSTR("16x16"); -#else - pict_id = 1002; -#endif /* MACH_O_CARBON */ - graf_width = graf_height = 16; - break; - } - - /* - * 32x32 tiles (images: PICT id 1004) - * with transparency effect - * "david" graphics definitions - * Vanilla-specific - */ - case GRAF_MODE_32X32: - { - use_graphics = arg_graphics = TRUE; - ANGBAND_GRAF = "david"; - transparency_mode = TR_OVER; -#ifdef MACH_O_CARBON - pict_id = CFSTR("32x32"); -#else - pict_id = 1004; -#endif /* MACH_O_CARBON */ - graf_width = graf_height = 32; - break; - } - } - - /* load tiles and setup GWorlds if tiles are requested */ - if ((graf_mode_req != GRAF_MODE_NONE) && (globe_init() != 0)) - { - /* Oops */ - plog("Cannot initialize graphics!"); - - /* reject request */ - graf_mode_req = GRAF_MODE_NONE; - - /* reset graphics flags */ - use_graphics = arg_graphics = FALSE; - - /* reset transparency mode */ - transparency_mode = TR_NONE; - } - - /* update current graphics mode */ - graf_mode = graf_mode_req; - - /* Apply and Verify */ - term_data_check_size(td); - - /* Resize the window */ - term_data_resize(td); - - /* Reset visuals */ - reset_visuals(); - } - - /* Success */ - return (0); -} - - -/* - * Do a "special thing" - */ -static errr Term_xtra_mac(int n, int v) -{ - term_data *td = (term_data*)(Term->data); - - Rect r; - - /* Analyze */ - switch (n) - { - /* Make a noise */ - case TERM_XTRA_NOISE: - { - /* Make a noise */ - SysBeep(1); - - /* Success */ - return (0); - } - - /* Make a sound */ - case TERM_XTRA_SOUND: - { -#ifndef USE_ASYNC_SOUND - - /* - * This may not be your choice, but much safer and much less - * resource hungry. Existing implementations can quite easily - * crash, by starting asynchronous playing and immediately - * unlocking and releasing the sound data just started playing... - * -- pelpel - */ - Handle handle; - Str255 sound; - - /* Get the proper sound name */ - strnfmt((char*)sound + 1, 255, "%.16s.wav", angband_sound_name[v]); - sound[0] = strlen((char*)sound + 1); - - /* Obtain resource XXX XXX XXX */ - handle = GetNamedResource('snd ', sound); - - /* Oops -- it is a failure, but we return 0 anyway */ - if (handle == NULL) return (0); - - /* Load and Lock */ - LoadResource(handle); - HLock(handle); - - /* Play sound (wait for completion) */ - SndPlay(NULL, (SndListHandle)handle, FALSE); - - /* Unlock and release */ - HUnlock(handle); - ReleaseResource(handle); - -#else /* !USE_ASYNC_SOUND */ - - /* Play sound */ - play_sound(v, sound_volume); - -#endif /* !USE_ASYNC_SOUND */ - - /* Success */ - return (0); - } - - /* Process random events */ - case TERM_XTRA_BORED: - { - /* Process an event */ - (void)CheckEvents(FALSE); - - /* Success */ - return (0); - } - - /* Process pending events */ - case TERM_XTRA_EVENT: - { - /* Process an event */ - (void)CheckEvents(v); - - /* Success */ - return (0); - } - - /* Flush all pending events (if any) */ - case TERM_XTRA_FLUSH: - { - /* Hack -- flush all events */ - while (CheckEvents(FALSE)) /* loop */; - - /* Success */ - return (0); - } - - /* Hack -- Change the "soft level" */ - case TERM_XTRA_LEVEL: - { - /* Activate if requested */ - if (v) activate(td->w); - - /* Success */ - return (0); - } - - /* Clear the screen */ - case TERM_XTRA_CLEAR: - { - Rect portRect; - - /* Get current Rect */ - GetPortBounds(GetWindowPort(td->w), &portRect); - - /* No clipping XXX XXX XXX */ - ClipRect(&portRect); - - /* Erase the window */ - EraseRect(&portRect); - - /* Set the color */ - term_data_color(td, TERM_WHITE); - - /* Frame the window in white */ - MoveTo(0, 0); - LineTo(0, td->size_hgt - 1); - LineTo(td->size_wid - 1, td->size_hgt - 1); - LineTo(td->size_wid - 1, 0); - - /* Clip to the new size */ - r.left = portRect.left + td->size_ow1; - r.top = portRect.top + td->size_oh1; - r.right = portRect.right - td->size_ow2; - r.bottom = portRect.bottom - td->size_oh2; - ClipRect(&r); - - /* Success */ - return (0); - } - - /* React to changes */ - case TERM_XTRA_REACT: - { - /* React to changes */ - return (Term_xtra_mac_react()); - } - - /* Delay (milliseconds) */ - case TERM_XTRA_DELAY: - { - /* - * WaitNextEvent relinquishes CPU as well as - * induces a screen refresh on OS X - */ - - /* If needed */ - if (v > 0) - { - EventRecord tmp; - UInt32 ticks; - - /* Convert millisecs to ticks */ - ticks = (v * 60L) / 1000; - - /* - * Hack? - Put the programme into sleep. - * No events match ~everyEvent, so nothing - * should be lost in Angband's event queue. - * Even if ticks are 0, it's worth calling for - * the above mentioned reasons. - */ - WaitNextEvent((EventMask)~everyEvent, &tmp, ticks, nil); - } - - /* Success */ - return (0); - } - - /* Rename main window */ - case TERM_XTRA_RENAME_MAIN_WIN: - { - char *s = strdup(angband_term_name[0]); - - ctopstr((StringPtr)s); - SetWTitle(data[0].w, (StringPtr)s); - - free(s); - return (0); - } - -/* MacOSX == Unix == Good */ -#ifdef USE_MACOSX - /* Get Delay of some milliseconds */ - case TERM_XTRA_GET_DELAY: - { - int ret; - struct timeval tv; - - ret = gettimeofday(&tv, NULL); - Term_xtra_long = (tv.tv_sec * 1000) + (tv.tv_usec / 1000); - - return ret; - } - - /* Subdirectory scan */ - case TERM_XTRA_SCANSUBDIR: - { - DIR *directory; - struct dirent *entry; - - scansubdir_max = 0; - - directory = opendir(scansubdir_dir); - if (!directory) - return 1; - - while ((entry = readdir(directory))) - { - char file[PATH_MAX + NAME_MAX + 2]; - struct stat filedata; - - file[PATH_MAX + NAME_MAX] = 0; - strncpy(file, scansubdir_dir, PATH_MAX); - strncat(file, "/", 2); - strncat(file, entry->d_name, NAME_MAX); - if (!stat(file, &filedata) && S_ISDIR((filedata.st_mode))) - { - string_free(scansubdir_result[scansubdir_max]); - scansubdir_result[scansubdir_max] = string_make(entry->d_name); - ++scansubdir_max; - } - } - - closedir(directory); - return 0; - } -#endif - } - - /* Oops */ - return (1); -} - - - -/* - * Low level graphics (Assumes valid input). - * Draw a "cursor" at (x,y), using a "yellow box". - * We are allowed to use "Term_what()" to determine - * the current screen contents (for inverting, etc). - */ -static errr Term_curs_mac(int x, int y) -{ - Rect r; - - term_data *td = (term_data*)(Term->data); - - /* Set the color */ - term_data_color(td, TERM_YELLOW); - - /* Frame the grid */ - r.left = x * td->tile_wid + td->size_ow1; - r.right = r.left + td->tile_wid; - r.top = y * td->tile_hgt + td->size_oh1; - r.bottom = r.top + td->tile_hgt; - -#ifdef USE_DOUBLE_TILES - - /* Mogami's bigtile patch */ - - /* Adjust it if double width tiles are requested */ - if (use_bigtile && - (x + 1 < Term->wid) && - (Term->old->a[y][x + 1] == 255)) - { - r.right += td->tile_wid; - } - -#endif /* USE_DOUBLE_TILES */ - - FrameRect(&r); - - /* Success */ - return (0); -} - - -/* - * Low level graphics (Assumes valid input) - * - * Erase "n" characters starting at (x,y) - */ -static errr Term_wipe_mac(int x, int y, int n) -{ - Rect r; - - term_data *td = (term_data*)(Term->data); - - - /* Erase the block of characters */ - r.left = x * td->tile_wid + td->size_ow1; - r.right = r.left + n * td->tile_wid; - r.top = y * td->tile_hgt + td->size_oh1; - r.bottom = r.top + td->tile_hgt; - EraseRect(&r); - - /* Success */ - return (0); -} - - -/* - * Low level graphics. Assumes valid input. - * - * Draw several ("n") chars, with an attr, at a given location. - */ -static errr Term_text_mac(int x, int y, int n, byte a, const char *cp) -{ - int xp, yp; - -#ifdef CLIP_HACK - Rect r; -#endif /* CLIP_HACK */ - - term_data *td = (term_data*)(Term->data); - - - /* Set the color */ - term_data_color(td, a); - -#ifdef CLIP_HACK - /* Hack - only draw within the bounding rect */ - r.left = x * td->tile_wid + td->size_ow1; - r.right = r.left + n * td->tile_wid; - r.top = y * td->tile_hgt + td->size_oh1; - r.bottom = r.top + td->tile_hgt; - ClipRect(&r); - - /* Hack - clear the content of the bounding rect */ - EraseRect(&r); -#endif /* CLIP_HACK */ - - /* Starting pixel */ - xp = x * td->tile_wid + td->tile_o_x + td->size_ow1; - yp = y * td->tile_hgt + td->tile_o_y + td->size_oh1; - - /* Move to the correct location */ - MoveTo(xp, yp); - - /* Draw the character */ - if (n == 1) DrawChar(*cp); - - /* Draw the string */ - else DrawText(cp, 0, n); - -#ifdef CLIP_HACK - /* Obtain current window's rect */ - GetPortBounds(GetWindowPort(td->w), &r); - - /* Clip to the window again */ - ClipRect(&r); -#endif /* CLIP_HACK */ - - /* Success */ - return (0); -} - - -/* - * Low level graphics (Assumes valid input) - * - * Erase "n" characters starting at (x,y) - */ -static errr Term_pict_mac(int x, int y, int n, const byte *ap, const char *cp, - const byte *tap, const char *tcp, - const byte *eap, const char *ecp) -{ - int i; - Rect dst_r; - GrafPtr port; - PixMapHandle pixmap_h; - -#ifdef CLIP_HACK - Rect portRect; -#endif /* CLIP_HACK */ - - term_data *td = (term_data*)(Term->data); - - static RGBColor black = {0x0000, 0x0000, 0x0000}; - static RGBColor white = {0xFFFF, 0xFFFF, 0xFFFF}; - - -#ifdef CLIP_HACK - /* Remember current window's rect */ - GetPortBounds(GetWindowPort(td->w), &portRect); -#endif /* CLIP_HACK */ - - /* Destination rectangle */ - dst_r.left = x * td->tile_wid + td->size_ow1; -#ifndef USE_DOUBLE_TILES - dst_r.right = dst_r.left + td->tile_wid; -#endif /* !USE_DOUBLE_TILES */ - dst_r.top = y * td->tile_hgt + td->size_oh1; - dst_r.bottom = dst_r.top + td->tile_hgt; - - /* Scan the input */ - for (i = 0; i < n; i++) - { - bool_ done = FALSE; - - byte a = *ap++; - char c = *cp++; - - byte ta = *tap++; - char tc = *tcp++; - byte ea = *eap++; - char ec = *ecp++; - bool_ has_overlay = (ea && ec); - - -#ifdef USE_DOUBLE_TILES - - /* Hack -- a filler for double-width tile */ - if (use_bigtile && (a == 255)) - { - /* Advance */ - dst_r.left += td->tile_wid; - - /* Ignore */ - continue; - } - - /* Prepare right side of rectagle now */ - dst_r.right = dst_r.left + td->tile_wid; - -#endif /* USE_DOUBLE_TILES */ - - /* Graphics -- if Available and Needed */ - if (use_graphics && ((byte)a & 0x80) && ((byte)c & 0x80)) - { - int col, row; - Rect src_r; - int t_col, t_row; - Rect terrain_r; - int e_col, e_row; - Rect ego_r; - - /* Row and Col */ - row = ((byte)a & 0x7F) % pict_rows; - col = ((byte)c & 0x7F) % pict_cols; - - /* Source rectangle */ - src_r.left = col * graf_width; - src_r.top = row * graf_height; - src_r.right = src_r.left + graf_width; - src_r.bottom = src_r.top + graf_height; - - /* Row and Col */ - t_row = ((byte)ta & 0x7F) % pict_rows; - t_col = ((byte)tc & 0x7F) % pict_cols; - - /* Source rectangle */ - terrain_r.left = t_col * graf_width; - terrain_r.top = t_row * graf_height; - terrain_r.right = terrain_r.left + graf_width; - terrain_r.bottom = terrain_r.top + graf_height; - - /* If there's an overlay */ - if (has_overlay) - { - /* Row and Col */ - e_row = ((byte)ea & 0x7F) % pict_rows; - e_col = ((byte)ec & 0x7F) % pict_cols; - - /* Source rectangle */ - ego_r.left = e_col * graf_width; - ego_r.top = e_row * graf_height; - ego_r.right = ego_r.left + graf_width; - ego_r.bottom = ego_r.top + graf_height; - } - - /* Hardwire CopyBits */ - RGBBackColor(&white); - RGBForeColor(&black); - -#ifdef USE_DOUBLE_TILES - - /* Double width tiles */ - if (use_bigtile) dst_r.right += td->tile_wid; - -#endif /* USE_DOUBLE_TILES */ - - /* - * OS X requires locking and unlocking of window port - * when we draw directly to its pixmap. - * The Lock/Unlock protocol is described in the Carbon - * Porting Guide. - */ - - /* Obtain current window's graphic port */ - port = GetWindowPort(td->w); - - /* Lock pixels, so we can use handle safely */ - LockPortBits(port); - - /* Get Pixmap handle */ - pixmap_h = GetPortPixMap(port); - - /* Transparency effect */ - switch (transparency_mode) - { - /* No transparency effects */ - case TR_NONE: - default: - { - /* Draw the picture */ - CopyBits((BitMap*)frameP->framePix, - (BitMap*)*pixmap_h, - &src_r, &dst_r, srcCopy, NULL); - - break; - } - - /* Overwriting with transparent black pixels */ - case TR_OVER: - { - /* Draw the terrain */ - CopyBits((BitMap*)frameP->framePix, - (BitMap*)*pixmap_h, - &terrain_r, &dst_r, srcCopy, NULL); - - /* Make black pixels transparent */ - RGBBackColor(&black); - - /* Draw mon/obj if there's one */ - if ((row != t_row) || (col != t_col)) - CopyBits((BitMap*)frameP->framePix, - (BitMap*)*pixmap_h, - &src_r, &dst_r, transparent, NULL); - - /* Draw overlay if there's one */ - if (has_overlay) - { - CopyBits((BitMap*)frameP->framePix, - (BitMap*)*pixmap_h, - &ego_r, &dst_r, transparent, NULL); - } - - break; - } - } - - /* Release the lock and dispose the PixMap handle */ - UnlockPortBits(port); - - /* Restore colors */ - RGBBackColor(&black); - RGBForeColor(&white); - - /* Forget color */ - td->last = -1; - - /* Done */ - done = TRUE; - } - - /* Normal */ - if (!done) - { - int xp, yp; - -#ifdef CLIP_HACK - /* Hack - avoid writing outside of dst_r */ - ClipRect(&dst_r); - /* Some characters do not match dst_r, therefore we have to... */ -#endif /* CLIP_HACK */ - - /* Erase */ - EraseRect(&dst_r); - - /* Set the color */ - term_data_color(td, a); - - /* Starting pixel */ - xp = dst_r.left + td->tile_o_x; - yp = dst_r.top + td->tile_o_y; - - /* Move to the correct location */ - MoveTo(xp, yp); - - /* Draw the character */ - DrawChar(c); - -#ifdef CLIP_HACK - /* Clip to the window - inefficient (; ;) XXX XXX */ - ClipRect(&portRect); -#endif /* CLIP_HACK */ - } - - /* Advance */ - dst_r.left += td->tile_wid; -#ifndef USE_DOUBLE_TILES - dst_r.right += td->tile_wid; -#endif /* !USE_DOUBLE_TILES */ - } - - /* Success */ - return (0); -} - - - - - -/* - * Create and initialize window number "i" - */ -static void term_data_link(int i) -{ - term *old = Term; - - term_data *td = &data[i]; - - /* Only once */ - if (td->t) return; - - /* Require mapped */ - if (!td->mapped) return; - - /* Allocate */ - MAKE(td->t, term); - - /* Initialize the term */ - term_init(td->t, td->cols, td->rows, td->keys); - - /* Use a "software" cursor */ - td->t->soft_cursor = TRUE; - - /* Erase with "white space" */ - td->t->attr_blank = TERM_WHITE; - td->t->char_blank = ' '; - - /* Prepare the init/nuke hooks */ - td->t->init_hook = Term_init_mac; - td->t->nuke_hook = Term_nuke_mac; - - /* Prepare the function hooks */ - td->t->user_hook = Term_user_mac; - td->t->xtra_hook = Term_xtra_mac; - td->t->wipe_hook = Term_wipe_mac; - td->t->curs_hook = Term_curs_mac; - td->t->text_hook = Term_text_mac; - td->t->pict_hook = Term_pict_mac; - - /* Link the local structure */ - td->t->data = (void *)(td); - - /* Activate it */ - Term_activate(td->t); - - /* Global pointer */ - angband_term[i] = td->t; - - /* Activate old */ - Term_activate(old); -} - - - - -#ifdef MACH_O_CARBON - -/* - * (Carbon, Bundle) - * Return a POSIX pathname of the lib directory, or NULL if it can't be - * located. Caller must supply a buffer along with its size in bytes, - * where returned pathname will be stored. - * I prefer use of goto's to several nested if's, if they involve error - * handling. Sorry if you are offended by their presence. Modern - * languages have neater constructs for this kind of jobs -- pelpel - */ -static char *locate_lib(char *buf, size_t size) -{ - CFURLRef main_url = NULL; - CFStringRef main_str = NULL; - char *p; - char *res = NULL; - - /* Obtain the URL of the main bundle */ - main_url = CFBundleCopyBundleURL(CFBundleGetMainBundle()); - - /* Oops */ - if (main_url == NULL) goto ret; - - /* Convert it to POSIX pathname */ - main_str = CFURLCopyFileSystemPath(main_url, kCFURLPOSIXPathStyle); - - /* Oops */ - if (main_str == NULL) goto ret; - - /* Convert it again from darn unisomething encoding to ASCII */ - if (CFStringGetCString(main_str, buf, size, kTextEncodingUS_ASCII) == FALSE) - goto ret; - - /* - * Paranoia - bounds check - */ - if (strlen(buf) + 25 + 1 > size) goto ret; - - /* Location of the data */ - strcat(buf, "/Contents/Resources/"); - - /* Set result */ - res = buf; - -ret: - - /* Release objects allocated and implicitly retained by the program */ - if (main_str) CFRelease(main_str); - if (main_url) CFRelease(main_url); - - /* pathname of the lib folder or NULL */ - return (res); -} - - -#else /* MACH_O_CARBON */ - -/* -* Set the "current working directory" (also known as the "default" -* volume/directory) to the location of the current application. -* -* Original code by: Maarten Hazewinkel (mmhazewi@cs.ruu.nl) -* -* Completely rewritten to use Carbon Process Manager. It retrieves the -* volume and direcotry of the current application and simply stores it -* in the (static) global variables app_vol and app_dir, but doesn't -* mess with the "current working directory", because it has long been -* an obsolete (and arcane!) feature. -*/ -static void SetupAppDir(void) -{ - OSErr err; - ProcessSerialNumber curPSN; - ProcessInfoRec procInfo; - FSSpec cwdSpec; - - /* Initialise PSN info for the current process */ - curPSN.highLongOfPSN = 0; - curPSN.lowLongOfPSN = kCurrentProcess; - - /* Fill in mandatory fields */ - procInfo.processInfoLength = sizeof(ProcessInfoRec); - procInfo.processName = nil; - procInfo.processAppSpec = &cwdSpec; - - /* Obtain current process information */ - err = GetProcessInformation(&curPSN, &procInfo); - - /* Oops */ - if (err != noErr) - { - mac_warning("Unable to get process information"); - - /* Quit without writing anything */ - ExitToShell(); - } - - /* Extract and save the Vol and Dir */ - app_vol = cwdSpec.vRefNum; - app_dir = cwdSpec.parID; -} - -#endif /* MACH_O_CARBON */ - - - - -/* - * Using Core Foundation's Preferences services -- pelpel - * - * Requires OS 8.6 or greater with CarbonLib 1.1 or greater. Or OS X, - * of course. - * - * Without this, we can support older versions of OS 8 as well - * (with CarbonLib 1.0.4). - * - * Frequent allocation/deallocation of small chunks of data is - * far from my liking, but since this is only called at the - * beginning and the end of a session, I hope this hardly matters. - */ - - -/* - * Store "value" as the value for preferences item name - * pointed by key - */ -static void save_pref_short(const char *key, short value) -{ - CFStringRef cf_key; - CFNumberRef cf_value; - - /* allocate and initialise the key */ - cf_key = CFStringCreateWithCString(NULL, key, kTextEncodingUS_ASCII); - - /* allocate and initialise the value */ - cf_value = CFNumberCreate(NULL, kCFNumberShortType, &value); - - if ((cf_key != NULL) && (cf_value != NULL)) - { - /* Store the key-value pair in the applications preferences */ - CFPreferencesSetAppValue( - cf_key, - cf_value, - kCFPreferencesCurrentApplication); - } - - /* - * Free CF data - the reverse order is a vain attempt to - * minimise memory fragmentation. - */ - if (cf_value) CFRelease(cf_value); - if (cf_key) CFRelease(cf_key); -} - - -/* - * Load preference value for key, returns TRUE if it succeeds with - * vptr updated appropriately, FALSE otherwise. - */ -static bool_ query_load_pref_short(const char *key, short *vptr) -{ - CFStringRef cf_key; - CFNumberRef cf_value; - - /* allocate and initialise the key */ - cf_key = CFStringCreateWithCString(NULL, key, kTextEncodingUS_ASCII); - - /* Oops */ - if (cf_key == NULL) return (FALSE); - - /* Retrieve value for the key */ - cf_value = CFPreferencesCopyAppValue( - cf_key, - kCFPreferencesCurrentApplication); - - /* Value not found */ - if (cf_value == NULL) - { - CFRelease(cf_key); - return (FALSE); - } - - /* Convert the value to short */ - CFNumberGetValue( - cf_value, - kCFNumberShortType, - vptr); - - /* Free CF data */ - CFRelease(cf_value); - CFRelease(cf_key); - - /* Success */ - return (TRUE); -} - - -/* - * Update short data pointed by vptr only if preferences - * value for key is located. - */ -static void load_pref_short(const char *key, short *vptr) -{ - short tmp; - - if (query_load_pref_short(key, &tmp)) *vptr = tmp; - return; -} - - -/* - * Save preferences to preferences file for current host+current user+ - * current application. - */ -static void cf_save_prefs() -{ - int i; - - /* Version stamp */ - save_pref_short("version.major", PREF_VER_MAJOR); - save_pref_short("version.minor", PREF_VER_MINOR); - save_pref_short("version.patch", PREF_VER_PATCH); - save_pref_short("version.extra", PREF_VER_EXTRA); - - /* Gfx settings */ - save_pref_short("arg.arg_sound", arg_sound); - save_pref_short("arg.graf_mode", graf_mode); -#ifdef USE_DOUBLE_TILES - save_pref_short("arg.big_tile", use_bigtile); -#endif /* USE_DOUBLE_TILES */ - - /* Windows */ - for (i = 0; i < MAX_TERM_DATA; i++) - { - term_data *td = &data[i]; - - save_pref_short(format("term%d.font_mono", i), td->font_mono); - save_pref_short(format("term%d.font_o_x", i), td->font_o_x); - save_pref_short(format("term%d.font_o_y", i), td->font_o_y); - save_pref_short(format("term%d.font_wid", i), td->font_wid); - save_pref_short(format("term%d.font_hgt", i), td->font_hgt); - save_pref_short(format("term%d.tile_o_x", i), td->tile_o_x); - save_pref_short(format("term%d.tile_o_y", i), td->tile_o_y); - save_pref_short(format("term%d.right", i), td->r.right); - save_pref_short(format("term%d.bottom", i), td->r.bottom); - save_pref_short(format("term%d.ow1", i), td->size_ow1); - save_pref_short(format("term%d.oh1", i), td->size_oh1); - save_pref_short(format("term%d.ow2", i), td->size_ow2); - save_pref_short(format("term%d.oh2", i), td->size_oh2); - - save_pref_short(format("term%d.mapped", i), td->mapped); - - save_pref_short(format("term%d.font_id", i), td->font_id); - save_pref_short(format("term%d.font_size", i), td->font_size); - save_pref_short(format("term%d.font_face", i), td->font_face); - - save_pref_short(format("term%d.tile_wid", i), td->tile_wid); - save_pref_short(format("term%d.tile_hgt", i), td->tile_hgt); - - save_pref_short(format("term%d.cols", i), td->cols); - save_pref_short(format("term%d.rows", i), td->rows); - save_pref_short(format("term%d.left", i), td->r.left); - save_pref_short(format("term%d.top", i), td->r.top); - } - - /* - * Make sure preferences are persistent - */ - CFPreferencesAppSynchronize( - kCFPreferencesCurrentApplication); -} - - -/* - * Load preferences from preferences file for current host+current user+ - * current application. - */ -static void cf_load_prefs() -{ - bool_ ok; - short pref_major, pref_minor, pref_patch, pref_extra; - int i; - - /* Assume nothing is wrong, yet */ - ok = TRUE; - - /* Load version information */ - ok &= query_load_pref_short("version.major", &pref_major); - ok &= query_load_pref_short("version.minor", &pref_minor); - ok &= query_load_pref_short("version.patch", &pref_patch); - ok &= query_load_pref_short("version.extra", &pref_extra); - - /* Any of the above failed */ - if (!ok) - { - /* This may be the first run */ - mac_warning("Preferences are not found."); - - /* Ignore the rest */ - return; - } - - /* Gfx settings */ - { - short pref_tmp; - - /* sound */ - if (query_load_pref_short("arg.arg_sound", &pref_tmp)) - arg_sound = pref_tmp; - - /* graphics */ - if (query_load_pref_short("arg.graf_mode", &pref_tmp)) - graf_mode_req = pref_tmp; - -#ifdef USE_DOUBLE_TILES - - /* double-width tiles */ - if (query_load_pref_short("arg.big_tile", &pref_tmp)) - { - use_bigtile = pref_tmp; - } - -#endif /* USE_DOUBLE_TILES */ - - } - - /* Windows */ - for (i = 0; i < MAX_TERM_DATA; i++) - { - term_data *td = &data[i]; - - load_pref_short(format("term%d.mapped", i), &td->mapped); - - load_pref_short(format("term%d.font_id", i), &td->font_id); - load_pref_short(format("term%d.font_size", i), &td->font_size); - load_pref_short(format("term%d.font_face", i), &td->font_face); - - load_pref_short(format("term%d.tile_wid", i), &td->tile_wid); - load_pref_short(format("term%d.tile_hgt", i), &td->tile_hgt); - - load_pref_short(format("term%d.cols", i), &td->cols); - load_pref_short(format("term%d.rows", i), &td->rows); - load_pref_short(format("term%d.left", i), &td->r.left); - load_pref_short(format("term%d.top", i), &td->r.top); - - load_pref_short(format("term%d.font_mono", i), &td->font_mono); - load_pref_short(format("term%d.font_o_x", i), &td->font_o_x); - load_pref_short(format("term%d.font_o_y", i), &td->font_o_y); - load_pref_short(format("term%d.font_wid", i), &td->font_wid); - load_pref_short(format("term%d.font_hgt", i), &td->font_hgt); - load_pref_short(format("term%d.tile_o_x", i), &td->tile_o_x); - load_pref_short(format("term%d.tile_o_y", i), &td->tile_o_y); - load_pref_short(format("term%d.right", i), &td->r.right); - load_pref_short(format("term%d.bottom", i), &td->r.bottom); - load_pref_short(format("term%d.ow1", i), &td->size_ow1); - load_pref_short(format("term%d.oh1", i), &td->size_oh1); - load_pref_short(format("term%d.ow2", i), &td->size_ow2); - load_pref_short(format("term%d.oh2", i), &td->size_oh2); - } -} - - - - -/* - * Hack -- default data for a window - */ -static void term_data_hack(term_data *td) -{ - short fid; - - /* Default to Monaco font */ - GetFNum("\pmonaco", &fid); - - /* Wipe it */ - WIPE(td, term_data); - - /* No color */ - td->last = -1; - - /* Default borders */ - td->size_ow1 = 2; - td->size_ow2 = 2; - td->size_oh1 = 2; - td->size_oh2 = 2; - - /* Start hidden */ - td->mapped = FALSE; - - /* Default font */ - td->font_id = fid; - - /* Default font size - was 12 */ - td->font_size = 14; - - /* Default font face */ - td->font_face = 0; - - /* Default size */ - td->rows = 24; - td->cols = 80; - - /* Default position */ - td->r.left = 10; - td->r.top = 40; - - /* Minimal keys */ - td->keys = 16; -} - - -/* - * Read the preference file, Create the windows. - * - * We attempt to use "FindFolder()" to track down the preference file. - */ -static void init_windows(void) -{ - int i, b = 0; - - term_data *td; - - - /*** Default values ***/ - - /* Initialize (backwards) */ - for (i = MAX_TERM_DATA; i-- > 0; ) - { - int n; - - cptr s; - - /* Obtain */ - td = &data[i]; - - /* Defaults */ - term_data_hack(td); - - /* Obtain title */ - s = angband_term_name[i]; - - /* Get length */ - n = strlen(s); - - /* Maximal length */ - if (n > 15) n = 15; - - /* Copy the title */ - strncpy((char*)(td->title) + 1, s, n); - - /* Save the length */ - td->title[0] = n; - - /* Tile the windows */ - td->r.left += (b * 30); - td->r.top += (b * 30); - - /* Tile */ - b++; - } - - - /*** Load preferences ***/ - - cf_load_prefs(); - - - /*** Instantiate ***/ - - /* Main window */ - td = &data[0]; - - /* Many keys */ - td->keys = 1024; - - /* Start visible */ - td->mapped = TRUE; - - /* Link (backwards, for stacking order) */ - for (i = MAX_TERM_DATA; i-- > 0; ) - { - term_data_link(i); - } - - /* Main window */ - td = &data[0]; - - /* Main window */ - Term_activate(td->t); -} - - -/* - * Save preferences - */ -static void save_pref_file(void) -{ - cf_save_prefs(); -} - - -/* - * Handle the "open_when_ready" flag - */ -static void handle_open_when_ready(void) -{ - /* Check the flag XXX XXX XXX make a function for this */ - if (open_when_ready && initialized && !game_in_progress) - { - /* Forget */ - open_when_ready = FALSE; - - /* Game is in progress */ - game_in_progress = 1; - - /* Wait for it */ - pause_line(23); - - /* Flush input */ - flush(); - - /* User double-clicked savefile; no savefile screen */ - no_begin_screen = TRUE; - - /* Play a game */ - play_game(FALSE); - - /* Quit */ - quit(NULL); - } -} - - - - -/* - * Menus - * - * The standard menus are: - * - * Apple (128) = { About, -, ... } - * File (129) = { Close,Save,-,Score,Quit } - * Edit (130) = { Cut, Copy, Paste, Clear } (?) - * Font (131) = { Bold, Extend, -, Monaco, ..., -, ... } - * Size (132) = { ... } - * Window (133) = { Angband, Term-1/Mirror, Term-2/Recall, Term-3/Choice, - * Term-4, Term-5, Term-6, Term-7 } - * Special (134) = { Sound, Graphics, TileWidth, TileHeight, -, - * Fiddle, Wizard } - */ - -/* Apple menu */ -#define MENU_APPLE 128 -#define ITEM_ABOUT 1 - -/* File menu */ -#define MENU_FILE 129 -#define ITEM_CLOSE 1 -#define ITEM_SAVE 2 -#ifdef HAS_SCORE_MENU -#define ITEM_SCORE 4 -#define ITEM_QUIT 5 -#else -#define ITEM_QUIT 4 -#endif /* HAS_SCORE_MENU */ - -/* Edit menu */ -#define MENU_EDIT 130 -#define ITEM_UNDO 1 -#define ITEM_CUT 3 -#define ITEM_COPY 4 -#define ITEM_PASTE 5 -#define ITEM_CLEAR 6 - -/* Font menu */ -#define MENU_FONT 131 -#define ITEM_BOLD 1 -#define ITEM_WIDE 2 - -/* Size menu */ -#define MENU_SIZE 132 - -/* Windows menu */ -#define MENU_WINDOWS 133 - -/* Special menu */ -#define MENU_SPECIAL 134 -#define ITEM_SOUND 1 -#define ITEM_GRAPH 2 -# define SUBMENU_GRAPH 144 -# define ITEM_NONE 1 -# define ITEM_8X8 2 -# define ITEM_16X16 3 -# define ITEM_32X32 4 -# define ITEM_BIGTILE 6 -#define ITEM_TILEWIDTH 3 -# define SUBMENU_TILEWIDTH 145 -#define ITEM_TILEHEIGHT 4 -# define SUBMENU_TILEHEIGHT 146 -#define ITEM_WIZARD 7 - - -/* - * I HATE UNICODE! We've never wanted it. Some multi-national companies - * made it up as their internationalisation "solution". So I won't use - * any such API's -- pelpel - */ -#define NSIZES 32 -static byte menu_size_values[NSIZES]; -static byte menu_tilewidth_values[NSIZES]; -static byte menu_tileheight_values[NSIZES]; - -/* - * Initialize the menus - * - * Fixed top level menus are now loaded all at once by GetNewMBar(). - * Although this simplifies the function a bit, we have to make sure - * that resources have all the expected entries defined XXX XXX - */ -static void init_menubar(void) -{ - int i, n; - - Rect r; - - WindowPtr tmpw; - - MenuRef m; - -#ifdef USE_NIB - - /* The new way - loading main menu using Interface Builder services */ - { - IBNibRef nib; - OSStatus err; - - /* Create a nib reference to the main nib file */ - err = CreateNibReference(CFSTR("main"), &nib); - - /* Fatal error - missing Main.nib */ - if (err != noErr) quit("Cannot find Main.nib in the bundle!"); - - /* Unarchive the menu bar and make it ready to use */ - err = SetMenuBarFromNib(nib, CFSTR("MainMenu")); - - /* Fatal error - couldn't insert menu bar */ - if (err != noErr) quit("Cannot prepare menu bar!"); - - /* Dispose of the nib reference because we don't need it any longer */ - DisposeNibReference(nib); - } - -#else /* USE_NIB */ - - /* The old way - loading main menu from Resource Manager resource */ - { - Handle mbar; - - /* Load menubar from resources */ - mbar = GetNewMBar(128); - - /* Whoops! */ - if (mbar == nil) quit("Cannot find menubar('MBAR') id 128!"); - - /* Insert them into the current menu list */ - SetMenuBar(mbar); - - /* Free handle */ - DisposeHandle(mbar); - } - -#endif /* USE_NIB */ - - - /* Apple menu (id 128) - we don't have to do anything */ - -#ifndef USE_NIB - - /* File menu (id 129) - Aqua provides Quit menu for us */ - if (is_aqua) - { - /* Get a handle to the file menu */ - m = GetMenuHandle(MENU_FILE); - - /* Nuke the quit menu since Aqua does that for us */ - DeleteMenuItem(m, ITEM_QUIT); - -#ifndef HAS_SCORE_MENU - - /* Hack - because the above leaves a separator as the last item */ - DeleteMenuItem(m, ITEM_QUIT - 1); - -#endif /* !HAS_SCORE_MENU */ - } - -#endif /* !USE_NIB */ - - - /* Edit menu (id 130) - we don't have to do anything */ - - - /* - * Font menu (id 131) - append names of mono-spaced fonts - * followed by all available ones - */ - m = GetMenuHandle(MENU_FONT); - - /* Fake window */ - r.left = r.right = r.top = r.bottom = 0; - - /* Make the fake window so that we can retrieve font info */ - (void)CreateNewWindow( - kDocumentWindowClass, - kWindowNoAttributes, - &r, - &tmpw); - - /* Activate the "fake" window */ - SetPort(GetWindowPort(tmpw)); - - /* Default mode */ - TextMode(0); - - /* Default size */ - TextSize(12); - - /* Add the fonts to the menu */ - AppendResMenu(m, 'FONT'); - - /* Size of menu */ - n = CountMenuItems(m); - - /* Scan the menu */ - for (i = n; i >= 4; i--) - { - Str255 tmpName; - short fontNum; - - /* Acquire the font name */ - GetMenuItemText(m, i, tmpName); - - /* Acquire the font index */ - GetFNum(tmpName, &fontNum); - - /* Apply the font index */ - TextFont(fontNum); - - /* Remove non-mono-spaced fonts */ - if ((CharWidth('i') != CharWidth('W')) || (CharWidth('W') == 0)) - { - /* Delete the menu item */ - DeleteMenuItem(m, i); - } - } - - /* Destroy the fake window */ - DisposeWindow(tmpw); - - /* Add a separator */ - AppendMenu(m, "\p-"); - - /* Add the fonts to the menu */ - AppendResMenu(m, 'FONT'); - - -#ifndef USE_NIB - - /* Size menu (id 132) */ - m = GetMenuHandle(MENU_SIZE); - - /* Add some sizes (stagger choices) */ - for (i = 8, n = 1; i <= 32; i += ((i / 16) + 1), n++) - { - Str15 buf; - - /* Textual size */ - strnfmt((char*)buf + 1, 15, "%d", i); - buf[0] = strlen((char*)buf + 1); - - /* Add the item */ - AppendMenu(m, buf); - - /* Remember its value, for we can't be sure it's in ASCII */ - menu_size_values[n] = i; - } - -#endif /* !USE_NIB */ - - - /* Windows menu (id 133) */ - m = GetMenuHandle(MENU_WINDOWS); - - /* Default choices */ - for (i = 0; i < MAX_TERM_DATA; i++) - { - Str15 buf; - - /* Describe the item */ - strnfmt((char*)buf + 1, 15, "%.15s", angband_term_name[i]); - buf[0] = strlen((char*)buf + 1); - - /* Add the item */ - AppendMenu(m, buf); - - /* Command-Key shortcuts */ - if (i < 8) SetItemCmd(m, i + 1, I2D(i)); - } - - -#ifndef USE_NIB - - /* Special menu (id 134) */ - m = GetMenuHandle(MENU_SPECIAL); - - /* Insert Graphics submenu (id 144) */ - { - MenuHandle submenu; - - /* Get the submenu */ - submenu = GetMenu(SUBMENU_GRAPH); - - /* Insert it */ - SetMenuItemHierarchicalMenu(m, ITEM_GRAPH, submenu); - } - - /* Insert TileWidth submenu (id 145) */ - { - MenuHandle submenu; - - /* Get the submenu */ - submenu = GetMenu(SUBMENU_TILEWIDTH); - - /* Add some sizes */ - for (i = 4, n = 1; i <= 32; i++, n++) - { - Str15 buf; - - /* Textual size */ - strnfmt((char*)buf + 1, 15, "%d", i); - buf[0] = strlen((char*)buf + 1); - - /* Append item */ - AppendMenu(submenu, buf); - - /* Remember its value, for we can't be sure it's in ASCII */ - menu_tilewidth_values[n] = i; - } - - /* Insert it */ - SetMenuItemHierarchicalMenu(m, ITEM_TILEWIDTH, submenu); - } - - /* Insert TileHeight submenu (id 146) */ - { - MenuHandle submenu; - - /* Get the submenu */ - submenu = GetMenu(SUBMENU_TILEHEIGHT); - - - /* Add some sizes */ - for (i = 4, n = 1; i <= 32; i++, n++) - { - Str15 buf; - - /* Textual size */ - strnfmt((char*)buf + 1, 15, "%d", i); - buf[0] = strlen((char*)buf + 1); - - /* Append item */ - AppendMenu(submenu, buf); - - /* Remember its value, for we can't be sure it's in ASCII */ - menu_tileheight_values[n] = i; - } - - /* Insert it */ - SetMenuItemHierarchicalMenu(m, ITEM_TILEHEIGHT, submenu); - } - -#endif /* !USE_NIB */ - - /* Update the menu bar */ - DrawMenuBar(); -} - - -/* - * Prepare the menus - * - * It is very important that the player not be allowed to "save" the game - * unless the "inkey_flag" variable is set, indicating that the game is - * waiting for a new command. XXX XXX XXX - */ - -static void setup_menus(void) -{ - int i, n; - - short value; - - Str255 s; - - MenuHandle m; - - term_data *td = NULL; - - - /* Relevant "term_data" */ - for (i = 0; i < MAX_TERM_DATA; i++) - { - /* Unused */ - if (!data[i].t) continue; - - /* Notice the matching window */ - if (data[i].w == FrontWindow()) td = &data[i]; - } - - - /* File menu */ - m = GetMenuHandle(MENU_FILE); - - /* Get menu size */ - n = CountMenuItems(m); - - /* Reset menu */ - for (i = 1; i <= n; i++) - { - /* Reset */ - DisableMenuItem(m, i); - CheckMenuItem(m, i, FALSE); - } - - /* Enable "close" */ - if (initialized) - { - EnableMenuItem(m, ITEM_CLOSE); - } - - /* Enable "save" */ - if (initialized && character_generated && inkey_flag) - { - EnableMenuItem(m, ITEM_SAVE); - } - -#ifdef HAS_SCORE_MENU - - /* Enable "score" */ - if (initialized && character_generated && !character_icky) - { - EnableMenuItem(m, ITEM_SCORE); - } - -#endif /* HAS_SCORE_MENU */ - - /* Enable "quit" */ - if (!is_aqua) - { - if (!initialized || !character_generated || inkey_flag) - { - EnableMenuItem(m, ITEM_QUIT); - } - } - - - /* Edit menu */ - m = GetMenuHandle(MENU_EDIT); - - /* Get menu size */ - n = CountMenuItems(m); - - /* Reset menu */ - for (i = 1; i <= n; i++) - { - /* Reset */ - DisableMenuItem(m, i); - CheckMenuItem(m, i, FALSE); - } - - /* Enable "edit" options if "needed" */ - if (!td) - { - EnableMenuItem(m, ITEM_UNDO); - EnableMenuItem(m, ITEM_CUT); - EnableMenuItem(m, ITEM_COPY); - EnableMenuItem(m, ITEM_PASTE); - EnableMenuItem(m, ITEM_CLEAR); - } - - - /* Font menu */ - m = GetMenuHandle(MENU_FONT); - - /* Get menu size */ - n = CountMenuItems(m); - - /* Reset menu */ - for (i = 1; i <= n; i++) - { - /* Reset */ - DisableMenuItem(m, i); - CheckMenuItem(m, i, FALSE); - } - - /* Hack -- look cute XXX XXX */ - /* SetItemStyle(m, ITEM_BOLD, bold); */ - - /* Hack -- look cute XXX XXX */ - /* SetItemStyle(m, ITEM_WIDE, extend); */ - - /* Active window */ - if (initialized && td) - { - /* Enable "bold" */ - EnableMenuItem(m, ITEM_BOLD); - - /* Enable "extend" */ - EnableMenuItem(m, ITEM_WIDE); - - /* Check the appropriate "bold-ness" */ - if (td->font_face & bold) CheckMenuItem(m, ITEM_BOLD, TRUE); - - /* Check the appropriate "wide-ness" */ - if (td->font_face & extend) CheckMenuItem(m, ITEM_WIDE, TRUE); - - /* Analyze fonts */ - for (i = 4; i <= n; i++) - { - /* Enable it */ - EnableMenuItem(m, i); - - /* Analyze font */ - GetMenuItemText(m, i, s); - GetFNum(s, &value); - - /* Check active font */ - if (td->font_id == value) CheckMenuItem(m, i, TRUE); - } - } - - - /* Size menu */ - m = GetMenuHandle(MENU_SIZE); - - /* Get menu size */ - n = CountMenuItems(m); - - /* Reset menu */ - for (i = 1; i <= n; i++) - { - /* Reset */ - DisableMenuItem(m, i); - CheckMenuItem(m, i, FALSE); - } - - /* Active window */ - if (initialized && td) - { - /* Analyze sizes */ - for (i = 1; i <= n; i++) - { - /* Analyze size */ - value = menu_size_values[i]; - - /* Enable the "real" sizes */ - if (RealFont(td->font_id, value)) EnableMenuItem(m, i); - - /* Check the current size */ - if (td->font_size == value) CheckMenuItem(m, i, TRUE); - } - } - - - /* Windows menu */ - m = GetMenuHandle(MENU_WINDOWS); - - /* Get menu size */ - n = CountMenuItems(m); - - /* Check active windows */ - for (i = 1; i <= n; i++) - { - /* Check if needed */ - CheckMenuItem(m, i, data[i - 1].mapped); - } - - - /* Special menu */ - m = GetMenuHandle(MENU_SPECIAL); - - /* Get menu size */ - n = CountMenuItems(m); - - /* Reset menu */ - for (i = 1; i <= n; i++) - { - /* Reset */ - DisableMenuItem(m, i); - CheckMenuItem(m, i, FALSE); - } - - /* Item "arg_sound" */ - EnableMenuItem(m, ITEM_SOUND); - CheckMenuItem(m, ITEM_SOUND, arg_sound); - - /* Item "Graphics" */ - EnableMenuItem(m, ITEM_GRAPH); - { - MenuRef submenu; - - /* Graphics submenu */ - (void)GetMenuItemHierarchicalMenu(m, ITEM_GRAPH, &submenu); - - /* Get menu size */ - n = CountMenuItems(submenu); - - /* Reset menu */ - for (i = 1; i <= n; i++) - { - /* Reset */ - DisableMenuItem(submenu, i); - CheckMenuItem(submenu, i, FALSE); - } - - /* Item "None" */ - EnableMenuItem(submenu, ITEM_NONE); - CheckMenuItem(submenu, ITEM_NONE, (graf_mode == GRAF_MODE_NONE)); - - /* Item "8x8" */ - EnableMenuItem(submenu, ITEM_8X8); - CheckMenuItem(submenu, ITEM_8X8, (graf_mode == GRAF_MODE_8X8)); - - /* Item "16x16" */ - EnableMenuItem(submenu, ITEM_16X16); - CheckMenuItem(submenu, ITEM_16X16, (graf_mode == GRAF_MODE_16X16)); - - /* Item "32x32" */ - /*EnableMenuItem(submenu, ITEM_32X32); - CheckMenuItem(submenu, ITEM_32X32, (graf_mode == GRAF_MODE_32X32));*/ - -#ifdef USE_DOUBLE_TILES - - /* Item "Big tiles" */ - if (inkey_flag) EnableMenuItem(submenu, ITEM_BIGTILE); - CheckMenuItem(submenu, ITEM_BIGTILE, use_bigtile); - -#endif /* USE_DOUBLE_TILES */ - - } - - /* Item "TileWidth" */ - EnableMenuItem(m, ITEM_TILEWIDTH); - { - MenuRef submenu; - - /* TileWidth submenu */ - (void)GetMenuItemHierarchicalMenu(m, ITEM_TILEWIDTH, &submenu); - - /* Get menu size */ - n = CountMenuItems(submenu); - - /* Reset menu */ - for (i = 1; i <= n; i++) - { - /* Reset */ - DisableMenuItem(submenu, i); - CheckMenuItem(submenu, i, FALSE); - } - - /* Active window */ - if (initialized && td) - { - /* Analyze sizes */ - for (i = 1; i <= n; i++) - { - /* Analyze size */ - value = menu_tilewidth_values[i]; - - /* Enable */ - if (value >= td->font_wid) EnableMenuItem(submenu, i); - - /* Check the current size */ - if (td->tile_wid == value) CheckMenuItem(submenu, i, TRUE); - } - } - } - - /* Item "TileHeight" */ - EnableMenuItem(m, ITEM_TILEHEIGHT); - { - MenuRef submenu; - - /* TileWidth submenu */ - (void)GetMenuItemHierarchicalMenu(m, ITEM_TILEHEIGHT, &submenu); - - /* Get menu size */ - n = CountMenuItems(submenu); - - /* Reset menu */ - for (i = 1; i <= n; i++) - { - /* Reset */ - DisableMenuItem(submenu, i); - CheckMenuItem(submenu, i, FALSE); - } - - /* Active window */ - if (initialized && td) - { - /* Analyze sizes */ - for (i = 1; i <= n; i++) - { - /* Analyze size */ - value = menu_tileheight_values[i]; - - /* Enable */ - if (value >= td->font_hgt) EnableMenuItem(submenu, i); - - /* Check the current size */ - if (td->tile_hgt == value) CheckMenuItem(submenu, i, TRUE); - } - } - } - - /* Item "arg_wizard" */ - EnableMenuItem(m, ITEM_WIZARD); - CheckMenuItem(m, ITEM_WIZARD, arg_wizard); - - - /* TileHeight menu */ - m = GetMenuHandle(SUBMENU_TILEHEIGHT); - - /* Get menu size */ - n = CountMenuItems(m); - - /* Reset menu */ - for (i = 1; i <= n; i++) - { - /* Reset */ - DisableMenuItem(m, i); - CheckMenuItem(m, i, FALSE); - } -} - - -/* - * Process a menu selection (see above) - * - * Hack -- assume that invalid menu selections are disabled above, - * which I have been informed may not be reliable. XXX XXX XXX - */ -static void menu(long mc) -{ - int i; - - int menuid, selection; - - static unsigned char s[1000]; - - short fid; - - term_data *td = NULL; - - WindowPtr old_win; - - - /* Analyze the menu command */ - menuid = HiWord(mc); - selection = LoWord(mc); - - - /* Find the window */ - for (i = 0; i < MAX_TERM_DATA; i++) - { - /* Skip dead windows */ - if (!data[i].t) continue; - - /* Notice matches */ - if (data[i].w == FrontWindow()) td = &data[i]; - } - - - /* Branch on the menu */ - switch (menuid) - { - /* Apple Menu */ - case MENU_APPLE: - { - /* About Angband... */ - if (selection == ITEM_ABOUT) - { - DialogPtr dialog; - short item_hit; - - /* Get the about dialogue */ - dialog = GetNewDialog(128, 0, (WindowPtr) - 1); - - /* Move it to the middle of the screen */ - RepositionWindow( - GetDialogWindow(dialog), - NULL, - kWindowCenterOnMainScreen); - - /* Show the dialog */ - TransitionWindow(GetDialogWindow(dialog), - kWindowZoomTransitionEffect, - kWindowShowTransitionAction, - NULL); - - /* Wait for user to click on it */ - ModalDialog(0, &item_hit); - - /* Free the dialogue */ - DisposeDialog(dialog); - break; - } - - break; - } - - /* File Menu */ - case MENU_FILE: - { - switch (selection) - { - - /* Close */ - case ITEM_CLOSE: - { - /* No window */ - if (!td) break; - - /* Not Mapped */ - td->mapped = FALSE; - - /* Not Mapped */ - td->t->mapped_flag = FALSE; - - /* Hide the window */ - TransitionWindow(td->w, - kWindowZoomTransitionEffect, - kWindowHideTransitionAction, - NULL); - - break; - } - - /* Save */ - case ITEM_SAVE: - { - /* Hack -- Forget messages */ - msg_flag = FALSE; - - /* Hack -- Save the game */ - do_cmd_save_game(); - - break; - } - -#ifdef HAS_SCORE_MENU - - /* Show score */ - case ITEM_SCORE: - { - predict_score_gui(&initialized, &game_in_progress); - - /* Done */ - break; - } - -#endif /* HAS_SCORE_MENU */ - - /* Quit (with save) */ - case ITEM_QUIT: - { - /* Save the game (if necessary) */ - if (game_in_progress && character_generated) - { - /* Hack -- Forget messages */ - msg_flag = FALSE; - - /* Save the game */ - do_cmd_save_game(); - } - - /* Quit */ - quit(NULL); - break; - } - } - break; - } - - /* Edit menu */ - case MENU_EDIT: - { - /* Unused */ - break; - } - - /* Font menu */ - case MENU_FONT: - { - /* Require a window */ - if (!td) break; - - /* Memorize old */ - old_win = active; - - /* Activate */ - activate(td->w); - - /* Toggle the "bold" setting */ - if (selection == ITEM_BOLD) - { - /* Toggle the setting */ - if (td->font_face & bold) - { - td->font_face &= ~bold; - } - else - { - td->font_face |= bold; - } - - /* Hack - clear tile size info XXX XXX */ - td->tile_wid = td->tile_hgt = 0; - - /* Apply and Verify */ - term_data_check_font(td); - term_data_check_size(td); - - /* Resize and Redraw */ - term_data_resize(td); - term_data_redraw(td); - - break; - } - - /* Toggle the "wide" setting */ - if (selection == ITEM_WIDE) - { - /* Toggle the setting */ - if (td->font_face & extend) - { - td->font_face &= ~extend; - } - else - { - td->font_face |= extend; - } - - /* Hack - clear tile size info XXX XXX */ - td->tile_wid = td->tile_hgt = 0; - - /* Apply and Verify */ - term_data_check_font(td); - term_data_check_size(td); - - /* Resize and Redraw */ - term_data_resize(td); - term_data_redraw(td); - - break; - } - - /* Get a new font name */ - GetMenuItemText(GetMenuHandle(MENU_FONT), selection, s); - GetFNum(s, &fid); - - /* Save the new font id */ - td->font_id = fid; - - /* Current size is bad for new font */ - if (!RealFont(td->font_id, td->font_size)) - { - /* Find similar size */ - for (i = 1; i <= 32; i++) - { - /* Adjust smaller */ - if (td->font_size - i >= 8) - { - if (RealFont(td->font_id, td->font_size - i)) - { - td->font_size -= i; - break; - } - } - - /* Adjust larger */ - if (td->font_size + i <= 128) - { - if (RealFont(td->font_id, td->font_size + i)) - { - td->font_size += i; - break; - } - } - } - } - - /* Hack - clear tile size info XXX XXX */ - td->tile_wid = td->tile_hgt = 0; - - /* Apply and Verify */ - term_data_check_font(td); - term_data_check_size(td); - - /* Resize and Redraw */ - term_data_resize(td); - term_data_redraw(td); - - /* Restore the window */ - activate(old_win); - - break; - } - - /* Size menu */ - case MENU_SIZE: - { - if (!td) break; - - /* Save old */ - old_win = active; - - /* Activate */ - activate(td->w); - - td->font_size = menu_size_values[selection]; - - /* Hack - clear tile size info XXX XXX */ - td->tile_wid = td->tile_hgt = 0; - - /* Apply and Verify */ - term_data_check_font(td); - term_data_check_size(td); - - /* Resize and Redraw */ - term_data_resize(td); - term_data_redraw(td); - - /* Restore */ - activate(old_win); - - break; - } - - /* Window menu */ - case MENU_WINDOWS: - { - /* Parse */ - i = selection - 1; - - /* Check legality of choice */ - if ((i < 0) || (i >= MAX_TERM_DATA)) break; - - /* Obtain the window */ - td = &data[i]; - - /* Mapped */ - td->mapped = TRUE; - - /* Link */ - term_data_link(i); - - /* Mapped (?) */ - td->t->mapped_flag = TRUE; - - /* Show the window */ - TransitionWindow(td->w, - kWindowZoomTransitionEffect, - kWindowShowTransitionAction, - NULL); - - /* Bring to the front */ - SelectWindow(td->w); - - break; - } - - /* Special menu */ - case MENU_SPECIAL: - { - switch (selection) - { - case ITEM_SOUND: - { - /* Toggle arg_sound */ - arg_sound = !arg_sound; - - /* React to changes */ - Term_xtra(TERM_XTRA_REACT, 0); - - break; - } - - case ITEM_WIZARD: - { - arg_wizard = !arg_wizard; - - break; - } - } - - break; - } - - /* Graphics submenu */ - case SUBMENU_GRAPH: - { - switch (selection) - { - case ITEM_NONE: - { - graf_mode_req = GRAF_MODE_NONE; - - break; - } - - case ITEM_8X8: - { - graf_mode_req = GRAF_MODE_8X8; - - break; - } - - case ITEM_16X16: - { - graf_mode_req = GRAF_MODE_16X16; - - break; - } - - case ITEM_32X32: - { - graf_mode_req = GRAF_MODE_32X32; - - break; - } - -#ifdef USE_DOUBLE_TILES - - case ITEM_BIGTILE: - { - term *old = Term; - term_data *td = &data[0]; - - /* Toggle "use_bigtile" */ - use_bigtile = !use_bigtile; - arg_bigtile = use_bigtile; - - /* Activate */ - Term_activate(td->t); - - /* Resize the term */ - Term_resize(td->cols, td->rows); - - /* Activate old */ - Term_activate(old); - - break; - } - -#endif /* USE_DOUBLE_TILES */ - - } - - /* Hack -- Force redraw */ - Term_key_push(KTRL('R')); - - break; - } - - /* TileWidth menu */ - case SUBMENU_TILEWIDTH: - { - if (!td) break; - - /* Save old */ - old_win = active; - - /* Activate */ - activate(td->w); - - /* Analyse value */ - td->tile_wid = menu_tilewidth_values[selection]; - - /* Apply and Verify */ - term_data_check_size(td); - - /* Resize and Redraw */ - term_data_resize(td); - term_data_redraw(td); - - /* Restore */ - activate(old_win); - - break; - } - - /* TileHeight menu */ - case SUBMENU_TILEHEIGHT: - { - if (!td) break; - - /* Save old */ - old_win = active; - - /* Activate */ - activate(td->w); - - /* Analyse value */ - td->tile_hgt = menu_tileheight_values[selection]; - - /* Apply and Verify */ - term_data_check_size(td); - - /* Resize and Redraw */ - term_data_resize(td); - term_data_redraw(td); - - /* Restore */ - activate(old_win); - - break; - } - } - - - /* Clean the menu */ - HiliteMenu(0); -} - - -/* - * Check for extra required parameters -- From "Maarten Hazewinkel" - */ -static OSErr CheckRequiredAEParams(const AppleEvent *theAppleEvent) -{ - OSErr aeError; - DescType returnedType; - Size actualSize; - - aeError = AEGetAttributePtr( - theAppleEvent, keyMissedKeywordAttr, typeWildCard, - &returnedType, NULL, 0, &actualSize); - - if (aeError == errAEDescNotFound) return (noErr); - - if (aeError == noErr) return (errAEParamMissed); - - return (aeError); -} - - -/* - * Apple Event Handler -- Open Application - */ -static OSErr AEH_Start(const AppleEvent *theAppleEvent, AppleEvent *reply, - SInt32 handlerRefCon) -{ - return (CheckRequiredAEParams(theAppleEvent)); -} - - -/* - * Apple Event Handler -- Quit Application - */ -static OSErr AEH_Quit(const AppleEvent *theAppleEvent, AppleEvent *reply, - SInt32 handlerRefCon) -{ - /* Quit later */ - quit_when_ready = TRUE; - - /* Check arguments */ - return (CheckRequiredAEParams(theAppleEvent)); -} - - -/* - * Apple Event Handler -- Print Documents - */ -static OSErr AEH_Print(const AppleEvent *theAppleEvent, AppleEvent *reply, - SInt32 handlerRefCon) -{ - return (errAEEventNotHandled); -} - - -/* - * Apple Event Handler by Steve Linberg (slinberg@crocker.com). - * - * The old method of opening savefiles from the finder does not work - * on the Power Macintosh, because CountAppFiles and GetAppFiles, - * used to return information about the selected document files when - * an application is launched, are part of the Segment Loader, which - * is not present in the RISC OS due to the new memory architecture. - * - * The "correct" way to do this is with AppleEvents. The following - * code is modeled on the "Getting Files Selected from the Finder" - * snippet from Think Reference 2.0. (The prior sentence could read - * "shamelessly swiped & hacked") - */ -static OSErr AEH_Open(const AppleEvent *theAppleEvent, AppleEvent* reply, - SInt32 handlerRefCon) -{ - FSSpec myFSS; - AEDescList docList; - OSErr err; - Size actualSize; - AEKeyword keywd; - DescType returnedType; - char msg[128]; - FInfo myFileInfo; - - /* Put the direct parameter (a descriptor list) into a docList */ - err = AEGetParamDesc( - theAppleEvent, keyDirectObject, typeAEList, &docList); - if (err) return err; - - /* - * We ignore the validity check, because we trust the FInder, and we only - * allow one savefile to be opened, so we ignore the depth of the list. - */ - err = AEGetNthPtr( - &docList, 1L, typeFSS, &keywd, &returnedType, - (Ptr) & myFSS, sizeof(myFSS), &actualSize); - if (err) return err; - - /* Only needed to check savefile type below */ - err = FSpGetFInfo(&myFSS, &myFileInfo); - if (err) - { - strnfmt(msg, 128, "Argh! FSpGetFInfo failed with code %d", err); - mac_warning(msg); - return err; - } - - /* Ignore non 'SAVE' files */ - if (myFileInfo.fdType != 'SAVE') return noErr; - -#ifdef MACH_O_CARBON - - /* Extract a file name */ - (void)spec_to_path(&myFSS, savefile, sizeof(savefile)); - -#else - - /* XXX XXX XXX Extract a file name */ - PathNameFromDirID(myFSS.parID, myFSS.vRefNum, (StringPtr)savefile); - pstrcat((StringPtr)savefile, (StringPtr)&myFSS.name); - - /* Convert the string */ - ptocstr((StringPtr)savefile); - -#endif /* MACH_O_CARBON */ - - /* Delay actual open */ - open_when_ready = TRUE; - - /* Dispose */ - err = AEDisposeDesc(&docList); - - /* Success */ - return noErr; -} - - -/* - * Handle quit_when_ready, by Peter Ammon, - * slightly modified to check inkey_flag. - */ -static void quit_calmly(void) -{ - /* Quit immediately if game's not started */ - if (!game_in_progress || !character_generated) quit(NULL); - - /* Save the game and Quit (if it's safe) */ - if (inkey_flag) - { - /* Hack -- Forget messages */ - msg_flag = FALSE; - - /* Save the game */ - do_cmd_save_game(); - - /* Quit */ - quit(NULL); - } - - /* Wait until inkey_flag is set */ -} - - -/* - * Macintosh modifiers (event.modifier & ccc): - * cmdKey, optionKey, shiftKey, alphaLock, controlKey - * - * - * Macintosh Keycodes (0-63 normal, 64-95 keypad, 96-127 extra): - * - * Return:36 - * Delete:51 - * - * Period:65 - * Star:67 - * Plus:69 - * Clear:71 - * Slash:75 - * Enter:76 - * Minus:78 - * Equal:81 - * 0-7:82-89 - * 8-9:91-92 - * - * backslash/vertical bar (Japanese keyboard):93 - * - * F5: 96 - * F6: 97 - * F7: 98 - * F3:99 - * F8:100 - * F10:101 - * F11:103 - * F13:105 - * F14:107 - * F9:109 - * F12:111 - * F15:113 - * Help:114 - * Home:115 - * PgUp:116 - * Del:117 - * F4: 118 - * End:119 - * F2:120 - * PgDn:121 - * F1:122 - * Lt:123 - * Rt:124 - * Dn:125 - * Up:126 - */ - - -/* - * Check for Events, return TRUE if we process any - * - * Now it really waits for events if wait set to true, to prevent - * undesirable monopoly of CPU. The side-effect is that you cannot do - * while (CheckEvents(TRUE)); without discretion. - */ -static bool_ CheckEvents(bool_ wait) -{ - EventRecord event; - - WindowPtr w; - - Rect r; - - UInt32 sleep_ticks; - - int ch, ck; - - int mc, ms, mo, mx; - - int i; - - term_data *td = NULL; - - - /* - * With the wait mode blocking for available event / timeout, - * the non-wait mode should actually call WaitNextEvent, - * because of those event draining loops. Or we had to - * implement yet another mode. - */ - - /* Handles the quit_when_ready flag */ - if (quit_when_ready) quit_calmly(); - - /* Blocking call to WaitNextEvent - should use MAX_INT XXX XXX */ - if (wait) sleep_ticks = 0x7FFFFFFFL; - - /* Non-blocking */ - else sleep_ticks = 0L; - - /* Get an event (or null) */ - WaitNextEvent(everyEvent, &event, sleep_ticks, nil); - - /* Hack -- Nothing is ready yet */ - if (event.what == nullEvent) return (FALSE); - - - /* Analyze the event */ - switch (event.what) - { - - case updateEvt: - { - /* Extract the window */ - w = (WindowPtr)event.message; - - /* Find the window */ - for (i = 0; i < MAX_TERM_DATA; i++) - { - /* Skip dead windows */ - if (!data[i].t) continue; - - /* Notice matches */ - if (data[i].w == w) td = &data[i]; - } - - /* Hack XXX XXX XXX */ - BeginUpdate(w); - EndUpdate(w); - - /* Redraw the window */ - if (td) term_data_redraw(td); - - break; - } - - case keyDown: - case autoKey: - { - /* Extract some modifiers */ - mc = (event.modifiers & controlKey) ? TRUE : FALSE; - ms = (event.modifiers & shiftKey) ? TRUE : FALSE; - mo = (event.modifiers & optionKey) ? TRUE : FALSE; - mx = (event.modifiers & cmdKey) ? TRUE : FALSE; - - /* Keypress: (only "valid" if ck < 96) */ - ch = (event.message & charCodeMask) & 255; - - /* Keycode: see table above */ - ck = ((event.message & keyCodeMask) >> 8) & 255; - - /* Command + "normal key" -> menu action */ - if (mx && (ck < 64)) - { -#ifdef MENU_SHORTCUTS - /* Hack -- Prepare the menus */ - setup_menus(); - - /* Run the Menu-Handler */ - menu(MenuKey(ch)); - - /* Turn off the menus */ - HiliteMenu(0); - - /* Done */ - break; -#else - /* Begin special trigger */ - Term_keypress(31); - - /* Send some modifier keys */ - if (mc) Term_keypress('C'); - if (ms) Term_keypress('S'); - if (mo) Term_keypress('O'); - if (mx) Term_keypress('X'); - - /* Enqueue the keypress */ - Term_keypress(ch); - - /* Terminate the trigger */ - Term_keypress(13); -#endif - } - - /* Hide the mouse pointer */ - ObscureCursor(); - - /* Normal key -> simple keypress */ - if ((ck < 64) || (ck == 93)) - { - /* Enqueue the keypress */ - Term_keypress(ch); - } - - /* Keypad keys -> trigger plus simple keypress */ - else if (!mc && !ms && !mo && !mx && (ck < 96)) - { - /* Hack -- "enter" is confused */ - if (ck == 76) ch = '\n'; - - /* Begin special trigger */ - Term_keypress(31); - - /* Send the "keypad" modifier */ - Term_keypress('K'); - - /* Send the "ascii" keypress */ - Term_keypress(ch); - - /* Terminate the trigger */ - Term_keypress(13); - } - - /* Bizarre key -> encoded keypress */ - else if (ck <= 127) - { - /* Begin special trigger */ - Term_keypress(31); - - /* Send some modifier keys */ - if (mc) Term_keypress('C'); - if (ms) Term_keypress('S'); - if (mo) Term_keypress('O'); - if (mx) Term_keypress('X'); - - /* Downshift and encode the keycode */ - Term_keypress(I2D((ck - 64) / 10)); - Term_keypress(I2D((ck - 64) % 10)); - - /* Terminate the trigger */ - Term_keypress(13); - } - - break; - } - - case mouseDown: - { - int code; - - /* Analyze click location */ - code = FindWindow(event.where, &w); - - /* Find the window */ - for (i = 0; i < MAX_TERM_DATA; i++) - { - /* Skip dead windows */ - if (!data[i].t) continue; - - /* Notice matches */ - if (data[i].w == w) td = &data[i]; - } - - /* Analyze */ - switch (code) - { - case inMenuBar: - { - setup_menus(); - menu(MenuSelect(event.where)); - HiliteMenu(0); - break; - } - - case inDrag: - { - WindowPtr old_win; - BitMap tBitMap; - Rect pRect; - - r = GetQDGlobalsScreenBits(&tBitMap)->bounds; - r.top += 20; /* GetMBarHeight() XXX XXX XXX */ - InsetRect(&r, 4, 4); - DragWindow(w, event.where, &r); - - /* Oops */ - if (!td) break; - - /* Save */ - old_win = active; - - /* Activate */ - activate(td->w); - - /* Analyze */ - GetWindowBounds( - (WindowRef)td->w, - kWindowContentRgn, - &pRect); - td->r.left = pRect.left; - td->r.top = pRect.top; - - /* Apply and Verify */ - term_data_check_size(td); - - /* Restore */ - activate(old_win); - - break; - } - - case inGoAway: - { - /* Oops */ - if (!td) break; - - /* Track the go-away box */ - if (TrackGoAway(w, event.where)) - { - /* Not Mapped */ - td->mapped = FALSE; - - /* Not Mapped */ - td->t->mapped_flag = FALSE; - - /* Hide the window */ - TransitionWindow(td->w, - kWindowZoomTransitionEffect, - kWindowHideTransitionAction, - NULL); - } - - break; - } - - case inGrow: - { - int x, y; - - Rect nr; - - term *old = Term; - - /* Oops */ - if (!td) break; - -#ifndef ALLOW_BIG_SCREEN - - /* Minimum and maximum sizes */ - r.left = 20 * td->tile_wid + td->size_ow1; - r.right = 80 * td->tile_wid + td->size_ow1 + td->size_ow2 + 1; - r.top = 1 * td->tile_hgt + td->size_oh1; - r.bottom = 24 * td->tile_hgt + td->size_oh1 + td->size_oh2 + 1; - - /* Grow the rectangle */ - if (!ResizeWindow(w, event.where, &r, NULL)) break; -#else - - /* Grow the rectangle */ - if (!ResizeWindow(w, event.where, NULL, NULL)) break; - -#endif /* !ALLOW_BIG_SCREEN */ - - - /* Obtain geometry of resized window */ - GetWindowBounds(w, kWindowContentRgn, &nr); - - /* Extract the new size in pixels */ - y = nr.bottom - nr.top - td->size_oh1 - td->size_oh2; - x = nr.right - nr.left - td->size_ow1 - td->size_ow2; - - /* Extract a "close" approximation */ - td->rows = y / td->tile_hgt; - td->cols = x / td->tile_wid; - - /* Apply and Verify */ - term_data_check_size(td); - - /* Activate */ - Term_activate(td->t); - - /* Hack -- Resize the term */ - Term_resize(td->cols, td->rows); - - /* Resize and Redraw */ - term_data_resize(td); - term_data_redraw(td); - - /* Restore */ - Term_activate(old); - - break; - } - - case inContent: - { - SelectWindow(w); - - break; - } - } - - break; - } - - /* OS Event -- From "Maarten Hazewinkel" */ - case osEvt: - { - switch ((event.message >> 24) & 0x000000FF) - { - case suspendResumeMessage: - - /* Resuming: activate the front window */ - if (event.message & resumeFlag) - { - Cursor tempCursor; - SetPort(GetWindowPort(FrontWindow())); - SetCursor(GetQDGlobalsArrow(&tempCursor)); - } - - /* Suspend: deactivate the front window */ - else - { - /* Nothing */ - } - - break; - } - - break; - } - - /* From "Steve Linberg" and "Maarten Hazewinkel" */ - case kHighLevelEvent: - { - /* Process apple events */ - (void)AEProcessAppleEvent(&event); - - /* Handle "quit_when_ready" */ - if (quit_when_ready) - { - /* Turn off the menus */ - HiliteMenu(0); - } - - /* Handle "open_when_ready" */ - else if (open_when_ready) - { - handle_open_when_ready(); - } - - break; - } - - } - - - /* Something happened */ - return (TRUE); -} - - -/*** Some Hooks for various routines ***/ - - -/* - * Mega-Hack -- emergency lifeboat - */ -static void *lifeboat = NULL; - - -/* - * Hook to "release" memory - */ -static void *hook_rnfree(void *v, size_t size) -{ - -#ifdef USE_MALLOC - - /* Alternative method */ - free(v); - -#else - - /* Dispose */ - DisposePtr(v); - -#endif - - /* Success */ - return (NULL); -} - -/* - * Hook to "allocate" memory - */ -static void *hook_ralloc(size_t size) -{ - -#ifdef USE_MALLOC - - /* Make a new pointer */ - return (malloc(size)); - -#else - - /* Make a new pointer */ - return (NewPtr(size)); - -#endif - -} - -/* - * Hook to handle "out of memory" errors - */ -static void *hook_rpanic(size_t size) -{ - /* void *mem = NULL; */ - - /* Free the lifeboat */ - if (lifeboat) - { - /* Free the lifeboat */ - DisposePtr(lifeboat); - - /* Forget the lifeboat */ - lifeboat = NULL; - - /* Mega-Hack -- Warning */ - mac_warning("Running out of Memory!\rAbort this process now!"); - - /* Mega-Hack -- Never leave this function */ - while (TRUE) CheckEvents(TRUE); - } - - /* Mega-Hack -- Crash */ - return (NULL); -} - - -/* - * Hook to tell the user something important - */ -static void hook_plog(cptr str) -{ - /* Warning message */ - mac_warning(str); -} - - -/* - * Hook to tell the user something, and then quit - */ -static void hook_quit(cptr str) -{ - /* Warning if needed */ - if (str) mac_warning(str); - -#ifdef USE_ASYNC_SOUND - - /* Clean up sound support */ - cleanup_sound(); - -#endif /* USE_ASYNC_SOUND */ - - /* Dispose of graphic tiles */ - if (frameP) - { - /* Unlock */ - BenSWUnlockFrame(frameP); - - /* Dispose of the GWorld */ - DisposeGWorld(frameP->framePort); - - /* Dispose of the memory */ - DisposePtr((Ptr)frameP); - } - - /* Write a preference file */ - save_pref_file(); - - /* All done */ - ExitToShell(); -} - - -/* - * Hook to tell the user something, and then crash - */ -static void hook_core(cptr str) -{ - /* XXX Use the debugger */ - /* DebugStr(str); */ - - /* Warning */ - if (str) mac_warning(str); - - /* Warn, then save player */ - mac_warning("Fatal error.\rI will now attempt to save and quit."); - - /* Attempt to save */ - if (!save_player()) mac_warning("Warning -- save failed!"); - - /* Quit */ - quit(NULL); -} - - - -/*** Main program ***/ - - -/* - * Init some stuff - * - * XXX XXX XXX Hack -- This function attempts to "fix" the nasty - * "Macintosh Save Bug" by using "absolute" path names, since on - * System 7 machines anyway, the "current working directory" often - * "changes" due to background processes, invalidating any "relative" - * path names. Note that the Macintosh is limited to 255 character - * path names, so be careful about deeply embedded directories... - * - * XXX XXX XXX Hack -- This function attempts to "fix" the nasty - * "missing lib folder bug" by allowing the user to help find the - * "lib" folder by hand if the "application folder" code fails... - * - * - * The problem description above no longer applies, but I left it here, - * modified for Carbon, to allow the game proceeds when a user doesn't - * placed the Angband binary and the lib folder in the same place for - * whatever reasons. -- pelpel - */ -static void init_stuff(void) -{ - Rect r; - BitMap tBitMap; - Rect screenRect; - Point topleft; - - char path[1024]; - - OSErr err = noErr; - NavDialogOptions dialogOptions; - FSSpec theFolderSpec; - NavReplyRecord theReply; - - - /* Fake rectangle */ - r.left = 0; - r.top = 0; - r.right = 344; - r.bottom = 188; - - /* Center it */ - screenRect = GetQDGlobalsScreenBits(&tBitMap)->bounds; - center_rect(&r, &screenRect); - - /* Extract corner */ - topleft.v = r.top; - topleft.h = r.left; - - /* Default to the "lib" folder with the application */ -#ifdef MACH_O_CARBON - if (locate_lib(path, sizeof(path)) == NULL) quit(NULL); -#else - refnum_to_name(path, app_dir, app_vol, (char*)("\plib:")); -#endif - - - /* Check until done */ - while (1) - { - /* Prepare the paths */ - init_file_paths(path); - - /* Build the filename */ - path_build(path, 1024, ANGBAND_DIR_FILE, "news.txt"); - - /* Attempt to open and close that file */ - if (0 == fd_close(fd_open(path, O_RDONLY))) break; - - /* Warning */ - plog_fmt("Unable to open the '%s' file.", path); - - /* Warning */ - plog("The Angband 'lib' folder is probably missing or misplaced."); - - /* Ask the user to choose the lib folder */ - err = NavGetDefaultDialogOptions(&dialogOptions); - - /* Paranoia */ - if (err != noErr) quit(NULL); - - /* Set default location option */ - dialogOptions.dialogOptionFlags |= kNavSelectDefaultLocation; - - /* Clear preview option */ - dialogOptions.dialogOptionFlags &= ~(kNavAllowPreviews); - - /* Forbit selection of multiple files */ - dialogOptions.dialogOptionFlags &= ~(kNavAllowMultipleFiles); - - /* Display location */ - dialogOptions.location = topleft; - - /* Set the message for the missing folder XXX XXX */ - strcpy(dialogOptions.message + 1, "Please select the \"lib\" folder"); - dialogOptions.message[0] = strlen(dialogOptions.message + 1); - - /* Wait for the user to choose a folder */ - err = NavChooseFolder( - nil, &theReply, &dialogOptions, nil, nil, nil); - - /* Assume the player doesn't want to go on */ - if ((err != noErr) || !theReply.validRecord) quit(NULL); - - /* Retrieve FSSpec from the reply */ - { - AEKeyword theKeyword; - DescType actualType; - Size actualSize; - - /* Get a pointer to selected folder */ - err = AEGetNthPtr( - &(theReply.selection), 1, typeFSS, &theKeyword, - &actualType, &theFolderSpec, sizeof(FSSpec), &actualSize); - - /* Paranoia */ - if (err != noErr) quit(NULL); - } - - /* Free navitagor reply */ - err = NavDisposeReply(&theReply); - - /* Paranoia */ - if (err != noErr) quit(NULL); - - /* Extract textual file name for given file */ -#ifdef MACH_O_CARBON - if (spec_to_path(&theFolderSpec, path, sizeof(path)) != noErr) - { - quit(NULL); - } -#else /* MACH_O_CARBON */ -refnum_to_name( - path, - theFolderSpec.parID, - theFolderSpec.vRefNum, - (char *)theFolderSpec.name); -#endif /* MACH_O_CARBON */ - } -} - - -/* - * Macintosh Main loop - */ -int main(void) -{ - int i; - long response; - OSStatus err; - EventRecord tempEvent; - UInt32 numberOfMasters = 10; - - /* Get more Masters -- it is not recommended by Apple, should go away */ - MoreMasterPointers(numberOfMasters); - - /* Check for existence of Carbon */ - err = Gestalt(gestaltCarbonVersion, &response); - - if (err != noErr) quit("This program requires Carbon API"); - - /* See if we are running on Aqua */ - err = Gestalt(gestaltMenuMgrAttr, &response); - - /* Cache the result */ - if ((err == noErr) && - (response & gestaltMenuMgrAquaLayoutMask)) is_aqua = TRUE; - - /* - * Remember Mac OS version, in case we have to cope with version-specific - * problems - */ - (void)Gestalt(gestaltSystemVersion, &mac_os_version); - - - /* Set up the Macintosh */ - InitCursor(); - - /* Flush events */ - FlushEvents(everyEvent, 0); - - /* Flush events some more (?) */ - if (EventAvail(everyEvent, &tempEvent)) FlushEvents(everyEvent, 0); - - - /* Install the start event hook (ignore error codes) */ - AEInstallEventHandler( - kCoreEventClass, - kAEOpenApplication, - NewAEEventHandlerUPP(AEH_Start), - 0L, - FALSE); - - /* Install the quit event hook (ignore error codes) */ - AEInstallEventHandler( - kCoreEventClass, - kAEQuitApplication, - NewAEEventHandlerUPP(AEH_Quit), - 0L, - FALSE); - - /* Install the print event hook (ignore error codes) */ - AEInstallEventHandler( - kCoreEventClass, - kAEPrintDocuments, - NewAEEventHandlerUPP(AEH_Print), - 0L, - FALSE); - - /* Install the open event hook (ignore error codes) */ - AEInstallEventHandler( - kCoreEventClass, - kAEOpenDocuments, - NewAEEventHandlerUPP(AEH_Open), - 0L, - FALSE); - - -#ifndef MACH_O_CARBON - - /* Find the current application */ - SetupAppDir(); - -#endif /* !MACH_O_CARBON */ - - /* Mark ourself as the file creator */ - _fcreator = ANGBAND_CREATOR; - - /* Default to saving a "text" file */ - _ftype = 'TEXT'; - - - /* Hook in some "z-virt.c" hooks */ - rnfree_aux = hook_rnfree; - ralloc_aux = hook_ralloc; - rpanic_aux = hook_rpanic; - - /* Hooks in some "z-util.c" hooks */ - plog_aux = hook_plog; - quit_aux = hook_quit; - core_aux = hook_core; - - - /* Initialize colors */ - for (i = 0; i < 256; i++) - { - u16b rv, gv, bv; - - /* Extract the R,G,B data */ - rv = angband_color_table[i][1]; - gv = angband_color_table[i][2]; - bv = angband_color_table[i][3]; - - /* Save the actual color */ - color_info[i].red = (rv | (rv << 8)); - color_info[i].green = (gv | (gv << 8)); - color_info[i].blue = (bv | (bv << 8)); - } - - - /* Show the "watch" cursor */ - SetCursor(*(GetCursor(watchCursor))); - - /* Prepare the menubar */ - init_menubar(); - - /* Prepare the windows */ - init_windows(); - - /* Hack -- process all events */ - while (CheckEvents(FALSE)) /* loop */; - - /* Reset the cursor */ - { - Cursor tempCursor; - - SetCursor(GetQDGlobalsArrow(&tempCursor)); - } - - /* Mega-Hack -- Allocate a "lifeboat" */ - lifeboat = NewPtr(16384); - -#ifdef USE_QT_SOUND - - /* Load sound effect resources */ - load_sounds(); - -#endif /* USE_QT_SOUND */ - - /* Note the "system" */ - ANGBAND_SYS = "mac"; - - if (check_create_user_dir() == FALSE) - quit("Cannot create directory " PRIVATE_USER_PATH); - - /* Initialize */ - init_stuff(); - - /* Initialize */ - init_angband(); - - - /* Hack -- process all events */ - while (CheckEvents(FALSE)) /* loop */; - - - /* We are now initialized */ - initialized = TRUE; - - - /* Handle "open_when_ready" */ - handle_open_when_ready(); - - /* Game is in progress */ - game_in_progress = 1; - - /* Wait for keypress */ - pause_line(23); - - /* flush input - Warning: without this, _system_ would hang */ - flush(); - - /* Play the game - note the value of the argument */ - play_game(FALSE); - - /* Quit */ - quit(NULL); - - /* Since it's a int function */ - return (0); -} - -#endif /* MACINTOSH || MACH_O_CARBON */ - diff --git a/src/modules.cc b/src/modules.cc index 7d1f0acb..12cc7de0 100644 --- a/src/modules.cc +++ b/src/modules.cc @@ -60,12 +60,6 @@ void module_reset_dir(cptr dir, cptr new_path) quit(format("Unable to create module dir %s\n", *d)); } } -#ifdef PRIVATE_USER_PATH_DATA - else if (!strcmp(dir, "data")) - { - module_reset_dir_aux(&ANGBAND_DIR_DATA, new_path); - } -#endif else if (!strcmp(dir, "save")) { module_reset_dir_aux(&ANGBAND_DIR_SAVE, new_path); diff --git a/src/util.cc b/src/util.cc index 87cfde03..ee138625 100644 --- a/src/util.cc +++ b/src/util.cc @@ -334,7 +334,6 @@ errr path_build(char *buf, int max, cptr path, cptr file) */ FILE *my_fopen(cptr file, cptr mode) { -#ifndef MACH_O_CARBON char buf[1024]; @@ -344,24 +343,6 @@ FILE *my_fopen(cptr file, cptr mode) /* Attempt to fopen the file anyway */ return (fopen(buf, mode)); -#else /* MACH_O_CARBON */ - -char buf[1024]; -FILE *s; - -/* Hack -- Try to parse the path */ -if (path_parse(buf, 1024, file)) return (NULL); - -/* Attempt to fopen the file anyway */ -s = fopen(buf, mode); - -/* Set creator and type if the file is successfully opened */ -if (s) fsetfileinfo(buf, _fcreator, _ftype); - -/* Done */ -return (s); - -#endif /* MACH_O_CARBON */ } @@ -574,27 +555,10 @@ int fd_make(cptr file, int mode) /* Hack -- Try to parse the path */ if (path_parse(buf, 1024, file)) return ( -1); -#ifdef MACH_O_CARBON - -{ -int fdes; - -/* Create the file, fail if exists, write-only, binary */ -fdes = open(buf, O_CREAT | O_EXCL | O_WRONLY | O_BINARY, mode); - -/* Set creator and type if the file is successfully opened */ -if (fdes >= 0) fsetfileinfo(buf, _fcreator, _ftype); - -/* Return the descriptor */ -return (fdes); -} - -#else /* MACH_O_CARBON */ /* Create the file, fail if exists, write-only, binary */ return (open(buf, O_CREAT | O_EXCL | O_WRONLY | O_BINARY, mode)); -#endif /* MACH_O_CARBON */ } @@ -611,27 +575,10 @@ int fd_open(cptr file, int flags) /* Hack -- Try to parse the path */ if (path_parse(buf, 1024, file)) return ( -1); -#ifdef MACH_O_CARBON - - { - int fdes; - - /* Attempt to open the file */ - fdes = open(buf, flags | O_BINARY, 0); - - /* Set creator and type if the file is successfully opened */ - if (fdes >= 0) fsetfileinfo(buf, _fcreator, _ftype); - - /* Return the descriptor */ - return (fdes); - } - -#else /* MACH_O_CARBON */ /* Attempt to open the file */ return (open(buf, flags | O_BINARY, 0)); -#endif /* MACH_O_CARBON */ } |