#endif /* MACH_O_CARBON */
/*
- * Use rewritten asynchronous sound player
- */
-#define USE_ASYNC_SOUND
-
-/*
* Cleaning up a couple of things to make these easier to change --AR
*/
#ifdef JP
*/
# define USE_SFL_CODE
+/*
+ * Use rewritten asynchronous sound player
+ */
+#define USE_ASYNC_SOUND
+
+
+#ifdef MACH_O_CARBON
+
+#define USE_QT_SOUND
+
+#endif /* MACH_O_CARBON */
#endif /* ANGBAND_LITE_MAC */
#endif
-# ifdef USE_ASYNC_SOUND
-
-/*
- * Asynchronous sound player revised
- */
-#if defined(USE_QT_SOUND) && !defined(MACH_O_CARBON)
-# undef USE_QT_SOUND
-#endif /* USE_QT_SOUND && !MACH_O_CARBON */
-
-
/*
- * Number of channels in the channel pool
+ * 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
*/
#if TARGET_API_MAC_CARBON
-#define MAX_CHANNELS 8
-#else
-#define MAX_CHANNELS 4
-#endif
-
-/*
- * A pool of sound channels
- */
-static SndChannelPtr channels[MAX_CHANNELS];
-
-/*
- * Status of the channel pool
- */
-static Boolean channel_initialised = FALSE;
+static void refnum_to_name(char *buf, long refnum, short vrefnum, char *fname)
+{
+ CInfoPBRec pb;
+ int err;
+ int i, j;
-/*
- * Data handles containing sound samples
- */
-static SndListHandle samples[SOUND_MAX];
+ char res[1000];
+
+ FSSpec spec;
+ short vref;
+ long dirID;
+
+ i=999;
-/*
- * Reference counts of sound samples
- */
-static SInt16 sample_refs[SOUND_MAX];
+ res[i]=0; i--;
+ for (j=1; j<=fname[0]; j++)
+ {
+ res[i-fname[0]+j] = fname[j];
+ }
+ i-=fname[0];
+ vref = vrefnum;
+ dirID = refnum;
-/*
- * Sound effects
- *
- * These constants aren't used by the program at the moment.
- */
-#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 % */
+ while (1)
+ {
+ pb.dirInfo.ioDrDirID=pb.dirInfo.ioDrParID;
+ err = FSMakeFSSpec( vref, dirID, "\p", &spec );
+
+ if( err != noErr )
+ break;
+
+ res[i] = ':'; i--;
+ for (j=1; j<=spec.name[0]; j++)
+ {
+ res[i-spec.name[0]+j] = spec.name[j];
+ }
+ i -= spec.name[0];
+
+ dirID = spec.parID;
+ }
-/* I'm just too lazy to write a panel for this XXX XXX */
-static SInt16 sound_volume = SOUND_VOLUME_MAX;
+ /* Extract the result */
+ for (j = 0, i++; res[i]; j++, i++) buf[j] = res[i];
+ buf[j] = 0;
+}
+#else
+static void refnum_to_name(char *buf, long refnum, short vrefnum, char *fname)
+{
+ DirInfo pb;
+ Str255 name;
+ int err;
+ int i, j;
-#ifdef USE_QT_SOUND
+ char res[1000];
-/*
- * 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;
+ i=999;
- /* Find resource (=file) in the current bundle */
- res_url = CFBundleCopyResourceURL(
- CFBundleGetMainBundle(), base_name, type_name, NULL);
+ res[i]=0; i--;
+ for (j=1; j<=fname[0]; j++)
+ {
+ res[i-fname[0]+j] = fname[j];
+ }
+ i-=fname[0];
- /* Oops */
- if (res_url == NULL) return (false);
+ pb.ioCompletion=NULL;
+ pb.ioNamePtr=name;
+ pb.ioVRefNum=vrefnum;
+ pb.ioDrParID=refnum;
+ pb.ioFDirIndex=-1;
- /* Convert CFURL to FSRef */
- (void)CFURLGetFSRef(res_url, &ref);
+ while (1)
+ {
+ pb.ioDrDirID=pb.ioDrParID;
+ err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
+ res[i] = ':'; i--;
+ for (j=1; j<=name[0]; j++)
+ {
+ res[i-name[0]+j] = name[j];
+ }
+ i -= name[0];
- /* Convert FSRef to FSSpec */
- (void)FSGetCatalogInfo(&ref, kFSCatInfoNone, NULL, NULL, spec, NULL);
+ if (pb.ioDrDirID == fsRtDirID) break;
+ }
- /* Free allocated CF data */
- CFRelease(res_url);
+ /* Extract the result */
+ for (j = 0, i++; res[i]; j++, i++) buf[j] = res[i];
+ buf[j] = 0;
+}
+#endif
- /* Success */
- return (true);
+#if TARGET_API_MAC_CARBON
+pascal OSErr FSpLocationFromFullPath(short fullPathLength,
+ const void *fullPath,
+ FSSpec *spec)
+{
+ AliasHandle alias;
+ OSErr result;
+ Boolean wasChanged;
+ Str32 nullString;
+
+ /* Create a minimal alias from the full pathname */
+ nullString[0] = 0; /* null string to indicate no zone or server name */
+ result = NewAliasMinimalFromFullPath(fullPathLength, fullPath, nullString, nullString, &alias);
+ if ( result == noErr )
+ {
+ /* Let the Alias Manager resolve the alias. */
+ result = ResolveAlias(NULL, alias, spec, &wasChanged);
+
+ /* work around Alias Mgr sloppy volume matching bug */
+ if ( spec->vRefNum == 0 )
+ {
+ /* invalidate wrong FSSpec */
+ spec->parID = 0;
+ spec->name[0] = 0;
+ result = nsvErr;
+ }
+ DisposeHandle((Handle)alias); /* Free up memory used */
+ }
+ return ( result );
}
+#endif
-/*
- * 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
- */
+#if 0
/*
- * (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*)
+ * XXX XXX XXX Allow the system to ask us for a filename
*/
-static void load_sounds(void)
+static bool askfor_file(char *buf, int len)
{
- OSErr err;
- int i;
+ SFReply reply;
+ Str255 dflt;
+ Point topleft;
+ short vrefnum;
+ long drefnum, junk;
- /* Start QuickTime */
- err = EnterMovies();
+ /* Default file name */
+ sprintf((char*)dflt + 1, "%s's description", buf);
+ dflt[0] = strlen((char*)dflt + 1);
- /* Error */
- if (err != noErr) return;
+ /* Ask for a file name */
+ topleft.h=(qd.screenBits.bounds.left+qd.screenBits.bounds.right)/2-344/2;
+ topleft.v=(2*qd.screenBits.bounds.top+qd.screenBits.bounds.bottom)/3-188/2;
+ SFPutFile(topleft, "\pSelect a filename:", dflt, NULL, &reply);
+ /* StandardPutFile("\pSelect a filename:", dflt, &reply); */
- /*
- * 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++)
+ /* Process */
+ if (reply.good)
{
- /* 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;
+ int fc;
- /* Allocate CFString with the name of sound event to be processed */
- name = CFStringCreateWithCString(NULL, angband_sound_name[i],
- kTextEncodingUS_ASCII);
+ /* Get info */
+ GetWDInfo(reply.vRefNum, &vrefnum, &drefnum, &junk);
- /* Error */
- if (name == NULL) continue;
+ /* Extract the name */
+ refnum_to_name(buf, drefnum, vrefnum, (char*)reply.fName);
- /* Find sound sample resource with the same name */
- res = get_resource_spec(name, CFSTR("wav"), &spec);
+ /* Success */
+ return (TRUE);
+ }
- /* Free the reference to CFString */
- CFRelease(name);
+ /* Failure */
+ return (FALSE);
+}
- /* Error */
- if (!res) continue;
+#endif
- /* Open the sound file */
- err = OpenMovieFile(&spec, &file_id, fsRdPerm);
+#if !TARGET_API_MAC_CARBON
+static void local_to_global( Rect *r )
+{
+ Point temp;
+
+ temp.h = r->left;
+ temp.v = r->top;
+
+ LocalToGlobal( &temp );
+
+ r->left = temp.h;
+ r->top = temp.v;
+
+ temp.h = r->right;
+ temp.v = r->bottom;
+
+ LocalToGlobal( &temp );
+
+ r->right = temp.h;
+ r->bottom = temp.v;
+}
+#endif /* !TARGET_API_MAC_CARBON */
- /* Error */
- if (err != noErr) continue;
+static void global_to_local( Rect *r )
+{
+ Point temp;
+
+ temp.h = r->left;
+ temp.v = r->top;
+
+ GlobalToLocal( &temp );
+
+ r->left = temp.h;
+ r->top = temp.v;
+
+ temp.h = r->right;
+ temp.v = r->bottom;
+
+ GlobalToLocal( &temp );
+
+ r->right = temp.h;
+ r->bottom = temp.v;
+}
- /* Create Movie from the file */
- err = NewMovieFromFile(&movie, file_id, &res_id, movie_name,
- newMovieActive, NULL);
- /* Error */
- if (err != noErr) goto close_file;
+#ifdef MAC_MPW
- /* Get the first track of the movie */
- track = GetMovieIndTrackType(movie, 1, AudioMediaCharacteristic,
- movieTrackCharacteristic | movieTrackEnabledOnly );
+/*
+ * Convert pathname to an appropriate format, because MPW's
+ * CarbonStdCLib chose to use system's native path format,
+ * making our lives harder to create binaries that run on
+ * OS 8/9 and OS X :( -- pelpel
+ */
+void convert_pathname(char* path)
+{
+ char buf[1024];
- /* Error */
- if (track == NULL) goto close_movie;
+ /* Nothing has to be done for CarbonLib on Classic */
+ if (mac_os_version >= 0x1000)
+ {
+ /* Convert to POSIX style */
+ ConvertHFSPathToUnixPath(path, buf);
- /* Allocate a handle to store sample */
- h = NewHandle(0);
+ /* Copy the result back */
+ strcpy(path, buf);
+ }
- /* Error */
- if (h == NULL) goto close_track;
+ /* Done. */
+ return;
+}
- /* Dump the sample into the handle */
- err = PutMovieIntoTypedHandle(movie, track, soundListRsrc, h, 0,
- GetTrackDuration(track), 0L, NULL);
+# ifdef CHECK_MODIFICATION_TIME
- /* Success */
- if (err == noErr)
- {
- /* Store the handle in the sample list */
- samples[i] = (SndListHandle)h;
- }
+/*
+ * Although there is no easy way to emulate fstat in the old interface,
+ * we still can do stat-like things, because Mac OS is an OS.
+ */
+static int get_modification_time(cptr path, u32b *mod_time)
+{
+ CInfoPBRec pb;
+ Str255 pathname;
+ int i;
- /* Failure */
- else
- {
- /* Free unused handle */
- DisposeHandle(h);
- }
+ /* Paranoia - make sure the pathname fits in Str255 */
+ i = strlen(path);
+ if (i > 255) return (-1);
- /* Free the track */
- close_track: DisposeMovieTrack(track);
+ /* Convert pathname to a Pascal string */
+ strncpy((char *)pathname + 1, path, 255);
+ pathname[0] = i;
- /* Free the movie */
- close_movie: DisposeMovie(movie);
+ /* Set up parameter block */
+ pb.hFileInfo.ioNamePtr = pathname;
+ pb.hFileInfo.ioFDirIndex = 0;
+ pb.hFileInfo.ioVRefNum = app_vol;
+ pb.hFileInfo.ioDirID = 0;
- /* Close the movie file */
- close_file: CloseMovieFile(file_id);
- }
+ /* Get catalog information of the file */
+ if (PBGetCatInfoSync(&pb) != noErr) return (-1);
- /* Stop QuickTime */
- ExitMovies();
+ /* Set modification date and time */
+ *mod_time = pb.hFileInfo.ioFlMdDat;
+
+ /* Success */
+ return (0);
}
-#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)
+ * A (non-Mach-O) Mac OS version of check_modification_time, for those
+ * compilers without good enough POSIX-compatibility libraries XXX XXX
*/
-static SndListHandle find_sound(int num)
+errr check_modification_date(int fd, cptr template_file)
{
- Str255 sound;
+#pragma unused(fd)
+ u32b txt_stat, raw_stat;
+ char *p;
+ char fname[32];
+ char buf[1024];
- /* Get the proper sound name */
- strnfmt((char*)sound + 1, 255, "%.16s.wav", angband_sound_name[num]);
- sound[0] = strlen((char*)sound + 1);
+ /* Build the file name */
+ path_build(buf, sizeof(buf), ANGBAND_DIR_EDIT, template_file);
- /* Obtain resource XXX XXX XXX */
- return ((SndListHandle)GetNamedResource('snd ', sound));
-}
+ /* XXX XXX XXX */
+ convert_pathname(buf);
-#endif /* USE_QT_SOUND */
+ /* Obtain modification time */
+ if (get_modification_time(buf, &txt_stat)) return (-1);
+ /* XXX Build filename of the corresponding *.raw file */
+ strnfmt(fname, sizeof(fname), "%s", template_file);
-/*
- * Clean up sound support - to be called when the game exits.
- *
- * Globals referenced: channels[], samples[], sample_refs[].
- */
-static void cleanup_sound(void)
-{
- int i;
+ /* Find last '.' */
+ p = strrchr(fname, '.');
- /* No need to clean it up */
- if (!channel_initialised) return;
+ /* Can't happen */
+ if (p == NULL) return (-1);
- /* Dispose channels */
- for (i = 0; i < MAX_CHANNELS; i++)
- {
- /* Drain sound commands and free the channel */
- SndDisposeChannel(channels[i], TRUE);
- }
+ /* Substitute ".raw" for ".txt" */
+ strcpy(p, ".raw");
- /* 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]);
- }
+ /* Build the file name of the raw file */
+ path_build(buf, sizeof(buf), ANGBAND_DIR_DATA, fname);
-#ifndef USE_QT_SOUND
+ /* XXX XXX XXX */
+ convert_pathname(buf);
- /* Release it */
- if (samples[i]) ReleaseResource((Handle)samples[i]);
-#else
+ /* Obtain modification time */
+ if (get_modification_time(buf, &raw_stat)) return (-1);
- /* Free handle */
- if (samples[i]) DisposeHandle((Handle)samples[i]);
-#endif /* !USE_QT_SOUND */
- }
+ /* Ensure the text file is not newer than the raw file */
+ if (txt_stat > raw_stat) return (-1);
+
+ /* Keep using the current .raw file */
+ return (0);
}
+# endif /* CHECK_MODIFICATION_TIME */
+
+#endif /* MAC_MPW */
/*
- * 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: ditto.
+ * Center a rectangle inside another rectangle
*/
-static void play_sound(int num, SInt16 vol)
+static void center_rect(Rect *r, Rect *s)
{
- OSErr err;
- int i;
- int prev_num;
- SndListHandle h;
- SndChannelPtr chan;
- SCStatus status;
+ 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;
+}
- static int next_chan;
- static SInt16 channel_occupants[MAX_CHANNELS];
- static SndCommand volume_cmd, quiet_cmd;
+#ifdef MACH_O_CARBON
- /* Initialise sound channels */
- if (!channel_initialised)
- {
- for (i = 0; i < MAX_CHANNELS; i++)
- {
- /* Paranoia - Clear occupant table */
- /* channel_occupants[i] = 0; */
+/* Carbon File Manager utilities by pelpel */
- /* Create sound channel for all sounds to play from */
- err = SndNewChannel(&channels[i], sampledSynth, initMono, 0L);
+/*
+ * (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;
- /* Error */
- if (err != noErr)
- {
- /* Free channels */
- while (--i >= 0)
- {
- SndDisposeChannel(channels[i], TRUE);
- }
+ /* Convert pathname to FSRef ... */
+ err = FSPathMakeRef(path, &ref, NULL);
+ if (err != noErr) return (err);
- /* Notify error */
-#ifdef JP
- plog("¥µ¥¦¥ó¥É¥Á¥ã¥ó¥Í¥ë¤ò½é´ü²½½ÐÍè¤Þ¤»¤ó!");
-#else
- plog("Cannot initialise sound channels!");
-#endif
+ /* ... then FSRef to FSSpec */
+ err = FSGetCatalogInfo(&ref, kFSCatInfoNone, NULL, NULL, spec, NULL);
+
+ /* Inform caller of success or failure */
+ return (err);
+}
- /* Cancel request */
- use_sound = arg_sound = FALSE;
- /* Failure */
- return;
- }
- }
+/*
+ * (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;
- /* First channel to use */
- next_chan = 0;
+ /* Convert FSSpec to FSRef ... */
+ err = FSpMakeFSRef(spec, &ref);
+ if (err != noErr) return (err);
- /* Prepare volume command */
- volume_cmd.cmd = volumeCmd;
- volume_cmd.param1 = 0;
- volume_cmd.param2 = 0;
+ /* ... then FSRef to pathname */
+ err = FSRefMakePath(&ref, buf, size);
- /* Prepare quiet command */
- quiet_cmd.cmd = quietCmd;
- quiet_cmd.param1 = 0;
- quiet_cmd.param2 = 0;
+ /* Inform caller of success or failure */
+ return (err);
+}
- /* Initialisation complete */
- channel_initialised = TRUE;
- }
- /* Paranoia */
- if ((num <= 0) || (num >= SOUND_MAX)) return;
+/*
+ * (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.
+ */
+void fsetfileinfo(cptr pathname, OSType fcreator, OSType ftype)
+{
+ OSErr err;
+ FSSpec spec;
+ FInfo info;
- /* Prepare volume command */
- volume_cmd.param2 = ((SInt32)vol << 16) | vol;
+ /* Convert pathname to FSSpec */
+ if (path_to_spec(pathname, &spec) != noErr) return;
- /* Channel to use (round robin) */
- chan = channels[next_chan];
+ /* Obtain current finder info of the file */
+ if (FSpGetFInfo(&spec, &info) != noErr) return;
- /* See if the resource is already in use */
- if (sample_refs[num] > 0)
- {
- /* Resource in use */
- h = samples[num];
+ /* Overwrite creator and type */
+ info.fdCreator = fcreator;
+ info.fdType = ftype;
+ err = FSpSetFInfo(&spec, &info);
- /* Increase the refcount */
- sample_refs[num]++;
- }
+ /* Done */
+ return;
+}
- /* 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;
+#else /* MACH_O_CARBON */
-#ifndef USE_QT_SOUND
- /* Load resource */
- LoadResource((Handle)h);
+/*
+ * 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;
- /* Remember it */
- samples[num] = h;
+ /* Hack -- pointer */
+ char *s = (char*)(src);
-#endif /* !USE_QT_SOUND */
+ /* Hack -- convert the string */
+ for (i = s[0]; i; i--, s++) s[0] = s[1];
- /* Lock the handle */
- HLockHi((Handle)h);
+ /* Hack -- terminate the string */
+ s[0] = '\0';
+}
- /* Initialise refcount */
- sample_refs[num] = 1;
- }
- /* Poll the channel */
- err = SndChannelStatus(chan, sizeof(SCStatus), &status);
+#if defined(USE_SFL_CODE)
- /* 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];
+/*
+ * 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);
- /* Process previously played sound */
- if (prev_num != 0)
- {
- /* Decrease refcount */
- sample_refs[prev_num]--;
+ /* adjust length byte */
+ *dst += *src;
+}
- /* We can free it now */
- if (sample_refs[prev_num] <= 0)
- {
- /* Unlock */
- HUnlock((Handle)samples[prev_num]);
+/*
+ * 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);
-#ifndef USE_QT_SOUND
+ /* copy new string in */
+ BlockMove(src + 1, dst + 1, *src);
- /* Release */
- ReleaseResource((Handle)samples[prev_num]);
+ /* adjust length byte */
+ *dst += *src;
+}
- /* Forget handle */
- samples[prev_num] = NULL;
+static void PathNameFromDirID(long dirID, short vRefNum, StringPtr fullPathName)
+{
+ CInfoPBRec block;
+ Str255 directoryName;
+ OSErr err;
-#endif /* !USE_QT_SOUND */
+ fullPathName[0] = '\0';
- /* Paranoia */
- sample_refs[prev_num] = 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 = PBGetCatInfo(&block, FALSE);
+ pstrcat(directoryName, (StringPtr)"\p:");
+ pstrinsert(fullPathName, directoryName);
+ if (block.dirInfo.ioDrDirID == 2) break;
}
+}
- /* Remember this sound as the current occupant of the channel */
- channel_occupants[next_chan] = num;
+#endif
+#endif /* MACH_O_CARBON */
- /* Set up volume for channel */
- SndDoImmediate(chan, &volume_cmd);
-
- /* Play new sound asynchronously */
- SndPlay(chan, h, TRUE);
+/*
+ * Activate a given window, if necessary
+ */
+static void activate(WindowPtr w)
+{
+ /* Activate */
+ if (active != w)
+ {
+ /* Activate */
+#if TARGET_API_MAC_CARBON
+ if (w) SetPortWindowPort(w);
+#else
+ if (w) SetPort(w);
+#endif
- /* Schedule next channel (round robin) */
- next_chan++;
- if (next_chan >= MAX_CHANNELS) next_chan = 0;
+ /* Remember */
+ active = w;
+ }
}
-# else /* USE_ASYNC_SOUND */
/*
- * Play sound synchronously
- *
- * This may not be your choice, but much safer and much less resource hungry.
+ * Display a warning message
*/
-static void play_sound(int num, SInt16 vol)
+static void mac_warning(cptr warning)
{
- Handle handle;
- Str255 sound;
+ Str255 text;
+ int len, i;
- /* Get the proper sound name */
- strnfmt((char*)sound + 1, 255, "%.16s.wav", angband_sound_name[num]);
- sound[0] = strlen((char*)sound + 1);
+ /* Limit of 250 chars */
+ len = strlen(warning);
+ if (len > 250) len = 250;
- /* Obtain resource XXX XXX XXX */
- handle = GetNamedResource('snd ', sound);
+ /* Make a "Pascal" string */
+ text[0] = len;
+ for (i=0; i<len; i++) text[i+1] = warning[i];
- /* Oops */
- if (handle == NULL) return;
+ /* Prepare the dialog box values */
+ ParamText(text, "\p", "\p", "\p");
- /* Load and Lock */
- LoadResource(handle);
- HLockHi(handle);
+ /* Display the Alert, wait for Okay */
+ Alert(129, 0L);
+}
- /* Play sound (wait for completion) */
- SndPlay(NULL, (SndListHandle)handle, FALSE);
- /* Unlock and release */
- HUnlock(handle);
- ReleaseResource(handle);
-}
-# endif /* USE_ASYNC_SOUND */
+/*** Some generic functions ***/
-#ifndef MACH_O_CARBON
+
+#ifdef ANGBAND_LITE_MAC
/*
- Extra Sound Mode
-*/
+ * Hack -- activate a color (0 to 255)
+ */
+#define term_data_color(TD,A) /* Nothing */
-static int ext_sound = 0;
+#else /* ANGBAND_LITE_MAC */
-#define SND_NON 0
-#define SND_ATTACK 1
-#define SND_MOVE 2
-#define SND_TRAP 3
-#define SND_SHOP 4
-#define SND_ME 5
-#define SND_CMD_ERROR 6
+/*
+ * Hack -- activate a color (0 to 255)
+ */
+static void term_data_color(term_data *td, int a)
+{
+ u16b rv, gv, bv;
-static int soundchoice[] = {
- SND_NON,
- SND_ATTACK,
- SND_ATTACK,
- SND_ATTACK,
- SND_TRAP,
- SND_ATTACK,
- SND_ME,
- SND_ME,
- SND_ME,
- SND_MOVE,
- SND_ATTACK,
- SND_ME,
- SND_ATTACK,
- SND_NON,
- SND_MOVE,
- SND_MOVE,
- SND_ME,
- SND_SHOP,
- SND_SHOP,
- SND_SHOP,
- SND_SHOP,
- SND_MOVE,
- SND_MOVE,
- SND_MOVE,
- SND_MOVE,
- SND_ATTACK,
- SND_SHOP,
- SND_SHOP,
- SND_ME,
- SND_NON,
- SND_ATTACK,
- SND_NON,
- SND_NON,
- SND_NON,
- SND_NON,
- SND_ATTACK,
- SND_ATTACK,
- SND_NON,
- SND_NON,
- SND_ATTACK,
- SND_NON,
- SND_NON,
- SND_NON,
- SND_TRAP,
- SND_ATTACK,
- SND_ATTACK,
- SND_ATTACK,
- SND_ATTACK,
- SND_ATTACK,
- SND_NON,
- SND_NON,
- SND_NON,
- SND_NON,
- SND_NON,
- SND_CMD_ERROR,
- SND_TRAP,
- SND_NON,
- SND_NON,
- SND_TRAP,
- SND_ATTACK,
- SND_TRAP,
- SND_ATTACK,
- SND_ATTACK,
- SND_NON,
- SND_TRAP,
-};
+ RGBColor color;
-static int ext_graf = 0;
+ /* Extract the R,G,B data */
+ rv = angband_color_table[a][1];
+ gv = angband_color_table[a][2];
+ bv = angband_color_table[a][3];
-#endif /* !MACH_O_CARBON */
+ /* Set the color */
+ color.red = (rv | (rv << 8));
+ color.green = (gv | (gv << 8));
+ color.blue = (bv | (bv << 8));
-static short soundmode[8];
+ /* Activate the color */
+ RGBForeColor(&color);
+
+ /* Memorize color */
+ td->last = a;
+}
+
+#endif /* ANGBAND_LITE_MAC */
/*
- * 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
+ * Hack -- Apply and Verify the "font" info
+ *
+ * This should usually be followed by "term_data_check_size()"
*/
-#if TARGET_API_MAC_CARBON
-static void refnum_to_name(char *buf, long refnum, short vrefnum, char *fname)
+static void term_data_check_font(term_data *td)
{
- CInfoPBRec pb;
- int err;
- int i, j;
+ int i;
- char res[1000];
-
- FSSpec spec;
- short vref;
- long dirID;
-
- i=999;
+ FontInfo info;
- res[i]=0; i--;
- for (j=1; j<=fname[0]; j++)
+ 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++)
{
- res[i-fname[0]+j] = fname[j];
+ /* 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);
}
- i-=fname[0];
- vref = vrefnum;
- dirID = refnum;
+ /* Set default offsets */
+ td->tile_o_x = td->font_o_x;
+ td->tile_o_y = td->font_o_y;
- while (1)
- {
- pb.dirInfo.ioDrDirID=pb.dirInfo.ioDrParID;
- err = FSMakeFSSpec( vref, dirID, "\p", &spec );
-
- if( err != noErr )
- break;
-
- res[i] = ':'; i--;
- for (j=1; j<=spec.name[0]; j++)
- {
- res[i-spec.name[0]+j] = spec.name[j];
- }
- i -= spec.name[0];
-
- dirID = spec.parID;
+ /* Set default tile size */
+ if( td->tile_wid == 0 && td->tile_hgt == 0 ){
+ td->tile_wid = td->font_wid;
+ td->tile_hgt = td->font_hgt;
}
- /* Extract the result */
- for (j = 0, i++; res[i]; j++, i++) buf[j] = res[i];
- buf[j] = 0;
+ /* Re-activate the old window */
+ activate(old);
}
-#else
-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;
+/*
+ * Hack -- Apply and Verify the "size" info
+ */
+static void term_data_check_size(term_data *td)
+{
+ BitMap screen;
+
+#if TARGET_API_MAC_CARBON
+ GetQDGlobalsScreenBits( &screen );
+#else
+ screen = qd.screenBits;
+#endif
+ /* Minimal window size */
+ if (td == &data[0])
+ {
+ /* Enforce minimal size */
+ if (td->cols < 80) td->cols = 80;
+ if (td->rows < 24) td->rows = 24;
+ }
- res[i]=0; i--;
- for (j=1; j<=fname[0]; j++)
+ /* Allow small windows for the rest */
+ else
{
- res[i-fname[0]+j] = fname[j];
+ if (td->cols < 1) td->cols = 1;
+ if (td->rows < 1) td->rows = 1;
}
- i-=fname[0];
- pb.ioCompletion=NULL;
- pb.ioNamePtr=name;
- pb.ioVRefNum=vrefnum;
- pb.ioDrParID=refnum;
- pb.ioFDirIndex=-1;
+ /* Minimal tile size */
+ if (td->tile_wid < 4) td->tile_wid = 4;
+ if (td->tile_hgt < 4) td->tile_hgt = 4;
- while (1)
- {
- pb.ioDrDirID=pb.ioDrParID;
- err = PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
- res[i] = ':'; i--;
- for (j=1; j<=name[0]; j++)
- {
- res[i-name[0]+j] = name[j];
- }
- i -= name[0];
+ /* 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;
- if (pb.ioDrDirID == fsRtDirID) break;
+ /* 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;
+
+ /* Verify the top */
+ if (td->r.top > screen.bounds.bottom - td->size_hgt)
+ {
+ td->r.top = screen.bounds.bottom - td->size_hgt;
}
- /* Extract the result */
- for (j = 0, i++; res[i]; j++, i++) buf[j] = res[i];
- buf[j] = 0;
-}
-#endif
+ /* Verify the top */
+ if (td->r.top < screen.bounds.top + 30)
+ {
+ td->r.top = screen.bounds.top + 30;
+ }
-#if TARGET_API_MAC_CARBON
-pascal OSErr FSpLocationFromFullPath(short fullPathLength,
- const void *fullPath,
- FSSpec *spec)
-{
- AliasHandle alias;
- OSErr result;
- Boolean wasChanged;
- Str32 nullString;
-
- /* Create a minimal alias from the full pathname */
- nullString[0] = 0; /* null string to indicate no zone or server name */
- result = NewAliasMinimalFromFullPath(fullPathLength, fullPath, nullString, nullString, &alias);
- if ( result == noErr )
+ /* Verify the left */
+ if (td->r.left > screen.bounds.right - td->size_wid)
{
- /* Let the Alias Manager resolve the alias. */
- result = ResolveAlias(NULL, alias, spec, &wasChanged);
-
- /* work around Alias Mgr sloppy volume matching bug */
- if ( spec->vRefNum == 0 )
- {
- /* invalidate wrong FSSpec */
- spec->parID = 0;
- spec->name[0] = 0;
- result = nsvErr;
- }
- DisposeHandle((Handle)alias); /* Free up memory used */
+ td->r.left = screen.bounds.right - td->size_wid;
}
- return ( result );
-}
-#endif
-#if 0
+ /* Verify the left */
+ if (td->r.left < screen.bounds.left)
+ {
+ td->r.left = screen.bounds.left;
+ }
-/*
- * XXX XXX XXX Allow the system to ask us for a filename
- */
-static bool askfor_file(char *buf, int len)
-{
- SFReply reply;
- Str255 dflt;
- Point topleft;
- short vrefnum;
- long drefnum, junk;
+ /* Calculate bottom right corner */
+ td->r.right = td->r.left + td->size_wid;
+ td->r.bottom = td->r.top + td->size_hgt;
- /* Default file name */
- sprintf((char*)dflt + 1, "%s's description", buf);
- dflt[0] = strlen((char*)dflt + 1);
+ /* Assume no graphics */
+ td->t->higher_pict = FALSE;
+ td->t->always_pict = FALSE;
- /* Ask for a file name */
- topleft.h=(qd.screenBits.bounds.left+qd.screenBits.bounds.right)/2-344/2;
- topleft.v=(2*qd.screenBits.bounds.top+qd.screenBits.bounds.bottom)/3-188/2;
- SFPutFile(topleft, "\pSelect a filename:", dflt, NULL, &reply);
- /* StandardPutFile("\pSelect a filename:", dflt, &reply); */
+#ifdef ANGBAND_LITE_MAC
- /* Process */
- if (reply.good)
- {
- int fc;
+ /* No graphics */
- /* Get info */
- GetWDInfo(reply.vRefNum, &vrefnum, &drefnum, &junk);
+#else /* ANGBAND_LITE_MAC */
- /* Extract the name */
- refnum_to_name(buf, drefnum, vrefnum, (char*)reply.fName);
+ /* Handle graphics */
+ if (use_graphics)
+ {
+ /* Use higher_pict whenever possible */
+ if (td->font_mono) td->t->higher_pict = TRUE;
- /* Success */
- return (TRUE);
+ /* Use always_pict only when necessary */
+ else td->t->always_pict = TRUE;
}
- /* Failure */
- return (FALSE);
-}
-
-#endif
+#endif /* ANGBAND_LITE_MAC */
-#if !TARGET_API_MAC_CARBON
-static void local_to_global( Rect *r )
-{
- Point temp;
-
- temp.h = r->left;
- temp.v = r->top;
-
- LocalToGlobal( &temp );
-
- r->left = temp.h;
- r->top = temp.v;
-
- temp.h = r->right;
- temp.v = r->bottom;
-
- LocalToGlobal( &temp );
-
- r->right = temp.h;
- r->bottom = temp.v;
+ /* Fake mono-space */
+ if (!td->font_mono ||
+ (td->font_wid != td->tile_wid) ||
+ (td->font_hgt != td->tile_hgt))
+ {
+ /* Handle fake monospace -- this is SLOW */
+ if (td->t->higher_pict) td->t->higher_pict = FALSE;
+ td->t->always_pict = TRUE;
+ }
}
-#endif /* !TARGET_API_MAC_CARBON */
-static void global_to_local( Rect *r )
+/*
+ * Hack -- resize a term_data
+ *
+ * This should normally be followed by "term_data_resize()"
+ */
+static void term_data_resize(term_data *td)
{
- Point temp;
-
- temp.h = r->left;
- temp.v = r->top;
-
- GlobalToLocal( &temp );
-
- r->left = temp.h;
- r->top = temp.v;
-
- temp.h = r->right;
- temp.v = r->bottom;
-
- GlobalToLocal( &temp );
-
- r->right = temp.h;
- r->bottom = temp.v;
+ /* Actually resize the window */
+ SizeWindow(td->w, td->size_wid, td->size_hgt, 0);
}
-#ifdef MAC_MPW
/*
- * Convert pathname to an appropriate format, because MPW's
- * CarbonStdCLib chose to use system's native path format,
- * making our lives harder to create binaries that run on
- * OS 8/9 and OS X :( -- pelpel
+ * Hack -- redraw a term_data
+ *
+ * Note that "Term_redraw()" calls "TERM_XTRA_CLEAR"
*/
-void convert_pathname(char* path)
+static void term_data_redraw(term_data *td)
{
- char buf[1024];
+ term *old = Term;
- /* Nothing has to be done for CarbonLib on Classic */
- if (mac_os_version >= 0x1000)
- {
- /* Convert to POSIX style */
- ConvertHFSPathToUnixPath(path, buf);
+ /* Activate the term */
+ Term_activate(td->t);
- /* Copy the result back */
- strcpy(path, buf);
- }
+ /* Redraw the contents */
+ Term_redraw();
- /* Done. */
- return;
-}
+ /* Flush the output */
+ Term_fresh();
-# ifdef CHECK_MODIFICATION_TIME
+ /* Restore the old term */
+ Term_activate(old);
+
+ /* No need to redraw */
+#if TARGET_API_MAC_CARBON
+ {
+ RgnHandle theRgn = NewRgn();
+ GetWindowRegion( td->w, kWindowContentRgn, theRgn );
+ ValidWindowRgn( (WindowRef)(td->w), theRgn );
+ DisposeRgn( theRgn );
+ }
+#else
+ ValidRect(&td->w->portRect);
+#endif
-/*
- * Although there is no easy way to emulate fstat in the old interface,
- * we still can do stat-like things, because Mac OS is an OS.
- */
-static int get_modification_time(cptr path, u32b *mod_time)
-{
- CInfoPBRec pb;
- Str255 pathname;
- int i;
+}
- /* Paranoia - make sure the pathname fits in Str255 */
- i = strlen(path);
- if (i > 255) return (-1);
- /* Convert pathname to a Pascal string */
- strncpy((char *)pathname + 1, path, 255);
- pathname[0] = i;
- /* Set up parameter block */
- pb.hFileInfo.ioNamePtr = pathname;
- pb.hFileInfo.ioFDirIndex = 0;
- pb.hFileInfo.ioVRefNum = app_vol;
- pb.hFileInfo.ioDirID = 0;
- /* Get catalog information of the file */
- if (PBGetCatInfoSync(&pb) != noErr) return (-1);
+#ifdef ANGBAND_LITE_MAC
- /* Set modification date and time */
- *mod_time = pb.hFileInfo.ioFlMdDat;
+/* No graphics */
- /* Success */
- return (0);
-}
+#else /* ANGBAND_LITE_MAC */
/*
- * A (non-Mach-O) Mac OS version of check_modification_time, for those
- * compilers without good enough POSIX-compatibility libraries XXX XXX
+ * Graphics support
*/
-errr check_modification_date(int fd, cptr template_file)
-{
-#pragma unused(fd)
- u32b txt_stat, raw_stat;
- char *p;
- char fname[32];
- char buf[1024];
-
- /* Build the file name */
- path_build(buf, sizeof(buf), ANGBAND_DIR_EDIT, template_file);
- /* XXX XXX XXX */
- convert_pathname(buf);
-
- /* Obtain modification time */
- if (get_modification_time(buf, &txt_stat)) return (-1);
-
- /* XXX Build filename of the corresponding *.raw file */
- strnfmt(fname, sizeof(fname), "%s", template_file);
+/*
+ * PICT id of image tiles, set by Term_xtra_mac_react
+ */
+#ifdef MACH_O_CARBON
+static CFStringRef pictID = NULL;
+#else
+static int pictID = 0;
+#endif /* MACH_O_CARBON */
- /* Find last '.' */
- p = strrchr(fname, '.');
+/*
+ * Width and height of a tile in pixels
+ */
+static int grafWidth = 0;
+static int grafHeight = 0;
- /* Can't happen */
- if (p == NULL) return (-1);
+/*
+ * Numbers of rows and columns in tiles, calculated by
+ * the PICT loading code
+ */
+static int pictCols = 0;
+static int pictRows = 0;
- /* Substitute ".raw" for ".txt" */
- strcpy(p, ".raw");
+/*
+ * Available graphics modes - 32x32 tiles don't work on Classic
+ */
+#define GRAF_MODE_NONE 0
+#define GRAF_MODE_8X8 1
+#define GRAF_MODE_16X16 2
+#define GRAF_MODE_32X32 3
- /* Build the file name of the raw file */
- path_build(buf, sizeof(buf), ANGBAND_DIR_DATA, fname);
+/*
+ * Current and requested graphics modes
+ */
+static int graf_mode = GRAF_MODE_NONE;
+static int graf_mode_req = GRAF_MODE_NONE;
- /* XXX XXX XXX */
- convert_pathname(buf);
- /* Obtain modification time */
- if (get_modification_time(buf, &raw_stat)) return (-1);
+/*
+ * Forward Declare
+ */
+typedef struct FrameRec FrameRec;
- /* Ensure the text file is not newer than the raw file */
- if (txt_stat > raw_stat) return (-1);
+/*
+ * 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;
+
+};
- /* Keep using the current .raw file */
- return (0);
-}
-# endif /* CHECK_MODIFICATION_TIME */
+/*
+ * The global picture data
+ */
+static FrameRec *frameP = NULL;
-#endif /* MAC_MPW */
/*
- * Center a rectangle inside another rectangle
+ * Lock a frame
*/
-static void center_rect(Rect *r, Rect *s)
+static void BenSWLockFrame(FrameRec *srcFrameP)
{
- 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;
-}
-
+ PixMapHandle pixMapH;
-#ifdef MACH_O_CARBON
+ pixMapH = GetGWorldPixMap(srcFrameP->framePort);
+ (void)LockPixels(pixMapH);
+ HLockHi((Handle)pixMapH);
+ srcFrameP->framePixHndl = pixMapH;
+#if TARGET_API_MAC_CARBON
+ srcFrameP->framePix = (PixMapPtr)*(Handle)pixMapH;
+#else
+ srcFrameP->framePix = (PixMapPtr)StripAddress(*(Handle)pixMapH);
+#endif
+
+}
-/* Carbon File Manager utilities by pelpel */
/*
- * (Carbon)
- * Convert a pathname to a corresponding FSSpec.
- * Returns noErr on success.
+ * Unlock a frame
*/
-static OSErr path_to_spec(const char *path, FSSpec *spec)
+static void BenSWUnlockFrame(FrameRec *srcFrameP)
{
- OSErr err;
- FSRef ref;
-
- /* Convert pathname to FSRef ... */
- err = FSPathMakeRef(path, &ref, NULL);
- if (err != noErr) return (err);
+ if (srcFrameP->framePort != NULL)
+ {
+ HUnlock((Handle)srcFrameP->framePixHndl);
+ UnlockPixels(srcFrameP->framePixHndl);
+ }
- /* ... then FSRef to FSSpec */
- err = FSGetCatalogInfo(&ref, kFSCatInfoNone, NULL, NULL, spec, NULL);
+ srcFrameP->framePix = NULL;
- /* Inform caller of success or failure */
- return (err);
}
+#ifdef MACH_O_CARBON
/*
- * (Carbon)
- * Convert a FSSpec to a corresponding pathname.
- * Returns noErr on success.
+ * 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 OSErr spec_to_path(const FSSpec *spec, char *buf, size_t size)
+static Boolean get_resource_spec(
+ CFStringRef base_name, CFStringRef type_name, FSSpec *spec)
{
- OSErr err;
+ CFURLRef res_url;
FSRef ref;
- /* Convert FSSpec to FSRef ... */
- err = FSpMakeFSRef(spec, &ref);
- if (err != noErr) return (err);
+ /* Find resource (=file) in the current bundle */
+ res_url = CFBundleCopyResourceURL(
+ CFBundleGetMainBundle(), base_name, type_name, NULL);
- /* ... then FSRef to pathname */
- err = FSRefMakePath(&ref, buf, size);
+ /* Oops */
+ if (res_url == NULL) return (false);
- /* Inform caller of success or failure */
- return (err);
+ /* 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);
}
/*
- * (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.
+ * (QuickTime)
+ * Create a off-screen GWorld from contents of a file specified by a FSSpec.
+ * Based on BenSWCreateGWorldFromPict.
+ *
+ * Globals referenced: data[0], graf_height, graf_width
+ * Globals updated: pict_rows, pict_cols.
*/
-void fsetfileinfo(cptr pathname, OSType fcreator, OSType ftype)
+static OSErr create_gworld_from_spec(
+ GWorldPtr *tile_gw, FSSpec *tile_spec)
{
OSErr err;
- FSSpec spec;
- FInfo info;
+ GraphicsImportComponent gi;
+ GWorldPtr gw, tmp_gw;
+ GDHandle gdh, tmp_gdh;
+ Rect r;
+ SInt16 depth;
- /* Convert pathname to FSSpec */
- if (path_to_spec(pathname, &spec) != noErr) return;
+ /* See if QuickTime understands the file format */
+ err = GetGraphicsImporterForFile(tile_spec, &gi);
- /* Obtain current finder info of the file */
- if (FSpGetFInfo(&spec, &info) != noErr) return;
+ /* Oops */
+ if (err != noErr) return (err);
- /* Overwrite creator and type */
- info.fdCreator = fcreator;
- info.fdType = ftype;
- err = FSpSetFInfo(&spec, &info);
+ /* Get depth */
+ depth = data[0].pixelDepth;
- /* Done */
- return;
-}
+ /* Get GDH */
+ gdh = data[0].theGDH;
+ /* Retrieve the rect of the image */
+ err = GraphicsImportGetNaturalBounds(gi, &r);
-#else /* MACH_O_CARBON */
+ /* 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 */
+ pictRows = r.bottom / grafHeight;
+ pictCols = r.right / grafWidth;
-/*
- * 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;
+ /* Create a GWorld */
+ err = NewGWorld(&gw, depth, &r, NULL, gdh, noNewDevice);
- /* Hack -- pointer */
- char *s = (char*)(src);
+ /* Oops */
+ if (err != noErr) return (err);
- /* Hack -- convert the string */
- for (i = s[0]; i; i--, s++) s[0] = s[1];
+ /* Save the pointer to the GWorld */
+ *tile_gw = gw;
- /* Hack -- terminate the string */
- s[0] = '\0';
-}
+ /* Save the current GWorld */
+ GetGWorld(&tmp_gw, &tmp_gdh);
+ /* Activate the newly created GWorld */
+ (void)GraphicsImportSetGWorld(gi, gw, NULL);
-#if defined(USE_SFL_CODE)
+ /* Prevent pixmap from moving while drawing */
+ (void)LockPixels(GetGWorldPixMap(gw));
+ /* Clear the pixels */
+ EraseRect(&r);
-/*
- * 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);
+ /* Draw the image into it */
+ (void)GraphicsImportDraw(gi);
- /* adjust length byte */
- *dst += *src;
-}
+ /* Release the lock*/
+ UnlockPixels(GetGWorldPixMap(gw));
-/*
- * 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);
+ /* Restore GWorld */
+ SetGWorld(tmp_gw, tmp_gdh);
- /* copy new string in */
- BlockMove(src + 1, dst + 1, *src);
+ /* Close the image importer */
+ CloseComponent(gi);
- /* adjust length byte */
- *dst += *src;
+ /* Success */
+ return (noErr);
}
-static void PathNameFromDirID(long dirID, short vRefNum, StringPtr fullPathName)
+#else /* MACH_O_CARBON */
+
+static OSErr BenSWCreateGWorldFromPict(
+ GWorldPtr *pictGWorld,
+ PicHandle pictH)
{
- CInfoPBRec block;
- Str255 directoryName;
- OSErr err;
+ OSErr err;
+ GWorldPtr saveGWorld;
+ GDHandle saveGDevice;
+ GWorldPtr tempGWorld;
+ Rect pictRect;
+ short depth;
+ GDHandle theGDH;
- fullPathName[0] = '\0';
+ /* Reset */
+ *pictGWorld = NULL;
- block.dirInfo.ioDrParID = dirID;
- block.dirInfo.ioNamePtr = directoryName;
+ /* Get depth */
+ depth = data[0].pixelDepth;
- while (1)
+ /* Get GDH */
+ theGDH = data[0].theGDH;
+
+ /* Obtain size rectangle */
+ pictRect = (**pictH).picFrame;
+ OffsetRect(&pictRect, -pictRect.left, -pictRect.top);
+
+ /* Create a GWorld */
+ err = NewGWorld(&tempGWorld, depth, &pictRect, nil,
+ theGDH, noNewDevice);
+
+ /* Success */
+ if (err != noErr)
{
- block.dirInfo.ioVRefNum = vRefNum;
- block.dirInfo.ioFDirIndex = -1;
- block.dirInfo.ioDrDirID = block.dirInfo.ioDrParID;
- err = PBGetCatInfo(&block, FALSE);
- pstrcat(directoryName, (StringPtr)"\p:");
- pstrinsert(fullPathName, directoryName);
- if (block.dirInfo.ioDrDirID == 2) break;
+ 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
#endif /* MACH_O_CARBON */
+
/*
- * Activate a given window, if necessary
+ * Init the global "frameP"
*/
-static void activate(WindowPtr w)
+
+static errr globe_init(void)
{
- /* Activate */
- if (active != w)
- {
- /* Activate */
+ OSErr err;
+
+ GWorldPtr tempPictGWorldP;
+
+#ifdef MACH_O_CARBON
+ FSSpec pict_spec;
+#else
+ PicHandle newPictH;
+#endif /* MACH_O_CARBON */
+
+ /* Use window XXX XXX XXX */
#if TARGET_API_MAC_CARBON
- if (w) SetPortWindowPort(w);
+ SetPortWindowPort(data[0].w);
#else
- if (w) SetPort(w);
+ SetPort(data[0].w);
#endif
- /* Remember */
- active = w;
- }
-}
+#ifdef MACH_O_CARBON
-/*
- * Display a warning message
- */
-static void mac_warning(cptr warning)
-{
- Str255 text;
- int len, i;
+ /* Get the tile resources */
+ if (!get_resource_spec(pictID, CFSTR("png"), &pict_spec)) return (-1);
+
+ /* Create GWorld */
+ err = create_gworld_from_spec(&tempPictGWorldP, &pict_spec);
+
+ /* Error */
+ if (err != noErr) return (err);
+
+ /* Create the frame */
+ frameP = (FrameRec*)NewPtrClear((Size)sizeof(FrameRec));
+
+ /* Analyze result */
+ if (frameP == NULL)
+ {
+ /* Dispose of image GWorld */
+ DisposeGWorld(tempPictGWorldP);
+
+ /* Fake error code */
+ return (-1);
+ }
+
+ /* Save GWorld */
+ frameP->framePort = tempPictGWorldP;
- /* Limit of 250 chars */
- len = strlen(warning);
- if (len > 250) len = 250;
+ /* Lock it */
+ BenSWLockFrame(frameP);
- /* Make a "Pascal" string */
- text[0] = len;
- for (i=0; i<len; i++) text[i+1] = warning[i];
+#else /* MACH_O_CARBON */
- /* Prepare the dialog box values */
- ParamText(text, "\p", "\p", "\p");
+ /* Get the pict resource */
+ newPictH = GetPicture(pictID);
- /* Display the Alert, wait for Okay */
- Alert(129, 0L);
-}
+ /* Analyze result */
+ err = (newPictH ? 0 : -1);
+ /* Oops */
+ if (err == noErr)
+ {
+
+ /* Create GWorld */
+ err = BenSWCreateGWorldFromPict(&tempPictGWorldP, newPictH);
+
+ /* Release resource */
+ ReleaseResource((Handle)newPictH);
+ /* Error */
+ if (err == noErr)
+ {
+ /* Create the frame */
+ frameP = (FrameRec*)NewPtrClear((Size)sizeof(FrameRec));
-/*** Some generic functions ***/
+ /* Analyze result */
+ err = (frameP ? 0 : -1);
+ /* Oops */
+ if (err == noErr)
+ {
+ /* Save GWorld */
+ frameP->framePort = tempPictGWorldP;
-#ifdef ANGBAND_LITE_MAC
+ /* Lock it */
+ BenSWLockFrame(frameP);
+ }
+ }
+ }
+#endif /* MACH_O_CARBON */
-/*
- * Hack -- activate a color (0 to 255)
- */
-#define term_data_color(TD,A) /* Nothing */
-#else /* ANGBAND_LITE_MAC */
+ /* Result */
+ return (err);
+}
+
/*
- * Hack -- activate a color (0 to 255)
+ * Nuke the global "frameP"
*/
-static void term_data_color(term_data *td, int a)
+static errr globe_nuke(void)
{
- u16b rv, gv, bv;
+ /* Dispose */
+ if (frameP)
+ {
+ /* Unlock */
+ BenSWUnlockFrame(frameP);
- RGBColor color;
+ /* Dispose of the GWorld */
+ DisposeGWorld(frameP->framePort);
- /* Extract the R,G,B data */
- rv = angband_color_table[a][1];
- gv = angband_color_table[a][2];
- bv = angband_color_table[a][3];
+ /* Dispose of the memory */
+ DisposePtr((Ptr)frameP);
- /* Set the color */
- color.red = (rv | (rv << 8));
- color.green = (gv | (gv << 8));
- color.blue = (bv | (bv << 8));
+ /* Forget */
+ frameP = NULL;
+ }
- /* Activate the color */
- RGBForeColor(&color);
+ /* Flush events */
+ FlushEvents(everyEvent, 0);
- /* Memorize color */
- td->last = a;
+ /* Success */
+ return (0);
}
-#endif /* ANGBAND_LITE_MAC */
+# ifdef USE_ASYNC_SOUND
/*
- * Hack -- Apply and Verify the "font" info
- *
- * This should usually be followed by "term_data_check_size()"
+ * Asynchronous sound player revised
*/
-static void term_data_check_font(term_data *td)
-{
- int i;
-
- FontInfo info;
-
- WindowPtr old = active;
-
+#if defined(USE_QT_SOUND) && !defined(MACH_O_CARBON)
+# undef USE_QT_SOUND
+#endif /* USE_QT_SOUND && !MACH_O_CARBON */
- /* Activate */
- activate(td->w);
- /* Instantiate font */
- TextFont(td->font_id);
- TextSize(td->font_size);
- TextFace(td->font_face);
+/*
+ * Number of channels in the channel pool
+ */
+#if TARGET_API_MAC_CARBON
+#define MAX_CHANNELS 8
+#else
+#define MAX_CHANNELS 4
+#endif
- /* Extract the font info */
- GetFontInfo(&info);
+/*
+ * A pool of sound channels
+ */
+static SndChannelPtr channels[MAX_CHANNELS];
- /* Assume monospaced */
- td->font_mono = TRUE;
+/*
+ * Status of the channel pool
+ */
+static Boolean channel_initialised = FALSE;
- /* 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;
+/*
+ * Data handles containing sound samples
+ */
+static SndListHandle samples[SOUND_MAX];
- /* Check important characters */
- for (i = 33; i < 127; i++)
- {
- /* Hack -- notice non-mono-space */
- if (td->font_wid != CharWidth(i)) td->font_mono = FALSE;
+/*
+ * Reference counts of sound samples
+ */
+static SInt16 sample_refs[SOUND_MAX];
- /* 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;
+/*
+ * Sound effects
+ *
+ * These constants aren't used by the program at the moment.
+ */
+#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 % */
- /* Set default tile size */
- if( td->tile_wid == 0 && td->tile_hgt == 0 ){
- td->tile_wid = td->font_wid;
- td->tile_hgt = td->font_hgt;
- }
+/* I'm just too lazy to write a panel for this XXX XXX */
+static SInt16 sound_volume = SOUND_VOLUME_MAX;
- /* Re-activate the old window */
- activate(old);
-}
+#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
+ */
/*
- * Hack -- Apply and Verify the "size" info
+ * (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 term_data_check_size(term_data *td)
+static void load_sounds(void)
{
- BitMap screen;
-
-#if TARGET_API_MAC_CARBON
- GetQDGlobalsScreenBits( &screen );
-#else
- screen = qd.screenBits;
-#endif
- /* Minimal window size */
- if (td == &data[0])
- {
- /* Enforce minimal size */
- if (td->cols < 80) td->cols = 80;
- if (td->rows < 24) td->rows = 24;
- }
+ OSErr err;
+ int i;
- /* Allow small windows for the rest */
- else
+ /* 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++)
{
- if (td->cols < 1) td->cols = 1;
- if (td->rows < 1) td->rows = 1;
- }
+ /* 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;
- /* Minimal tile size */
- if (td->tile_wid < 4) td->tile_wid = 4;
- if (td->tile_hgt < 4) td->tile_hgt = 4;
+ /* Allocate CFString with the name of sound event to be processed */
+ name = CFStringCreateWithCString(NULL, angband_sound_name[i],
+ kTextEncodingUS_ASCII);
- /* 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;
+ /* Error */
+ if (name == NULL) continue;
- /* 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;
+ /* Find sound sample resource with the same name */
+ res = get_resource_spec(name, CFSTR("wav"), &spec);
- /* Apply font offsets */
- td->tile_o_x += td->font_o_x;
- td->tile_o_y += td->font_o_y;
+ /* Free the reference to CFString */
+ CFRelease(name);
- /* 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;
+ /* Error */
+ if (!res) continue;
- /* Verify the top */
- if (td->r.top > screen.bounds.bottom - td->size_hgt)
- {
- td->r.top = screen.bounds.bottom - td->size_hgt;
- }
+ /* Open the sound file */
+ err = OpenMovieFile(&spec, &file_id, fsRdPerm);
- /* Verify the top */
- if (td->r.top < screen.bounds.top + 30)
- {
- td->r.top = screen.bounds.top + 30;
- }
+ /* Error */
+ if (err != noErr) continue;
- /* Verify the left */
- if (td->r.left > screen.bounds.right - td->size_wid)
- {
- td->r.left = screen.bounds.right - td->size_wid;
- }
+ /* Create Movie from the file */
+ err = NewMovieFromFile(&movie, file_id, &res_id, movie_name,
+ newMovieActive, NULL);
- /* Verify the left */
- if (td->r.left < screen.bounds.left)
- {
- td->r.left = screen.bounds.left;
- }
+ /* Error */
+ if (err != noErr) goto close_file;
- /* Calculate bottom right corner */
- td->r.right = td->r.left + td->size_wid;
- td->r.bottom = td->r.top + td->size_hgt;
+ /* Get the first track of the movie */
+ track = GetMovieIndTrackType(movie, 1, AudioMediaCharacteristic,
+ movieTrackCharacteristic | movieTrackEnabledOnly );
- /* Assume no graphics */
- td->t->higher_pict = FALSE;
- td->t->always_pict = FALSE;
+ /* Error */
+ if (track == NULL) goto close_movie;
-#ifdef ANGBAND_LITE_MAC
+ /* Allocate a handle to store sample */
+ h = NewHandle(0);
- /* No graphics */
+ /* Error */
+ if (h == NULL) goto close_track;
-#else /* ANGBAND_LITE_MAC */
+ /* Dump the sample into the handle */
+ err = PutMovieIntoTypedHandle(movie, track, soundListRsrc, h, 0,
+ GetTrackDuration(track), 0L, NULL);
- /* Handle graphics */
- if (use_graphics)
- {
- /* Use higher_pict whenever possible */
- if (td->font_mono) td->t->higher_pict = TRUE;
+ /* Success */
+ if (err == noErr)
+ {
+ /* Store the handle in the sample list */
+ samples[i] = (SndListHandle)h;
+ }
- /* Use always_pict only when necessary */
- else td->t->always_pict = TRUE;
- }
+ /* Failure */
+ else
+ {
+ /* Free unused handle */
+ DisposeHandle(h);
+ }
-#endif /* ANGBAND_LITE_MAC */
+ /* Free the track */
+ close_track: DisposeMovieTrack(track);
- /* Fake mono-space */
- if (!td->font_mono ||
- (td->font_wid != td->tile_wid) ||
- (td->font_hgt != td->tile_hgt))
- {
- /* Handle fake monospace -- this is SLOW */
- if (td->t->higher_pict) td->t->higher_pict = FALSE;
- td->t->always_pict = TRUE;
+ /* Free the movie */
+ close_movie: DisposeMovie(movie);
+
+ /* Close the movie file */
+ close_file: CloseMovieFile(file_id);
}
+
+ /* Stop QuickTime */
+ ExitMovies();
}
+#else /* USE_QT_SOUND */
+
/*
- * Hack -- resize a term_data
+ * Return a handle of 'snd ' resource given Angband sound event number,
+ * or NULL if it isn't found.
*
- * This should normally be followed by "term_data_resize()"
+ * Globals referenced: angband_sound_name[] (variable.c)
*/
-static void term_data_resize(term_data *td)
+static SndListHandle find_sound(int num)
{
- /* Actually resize the window */
- SizeWindow(td->w, td->size_wid, td->size_hgt, 0);
+ 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 */
/*
- * Hack -- redraw a term_data
+ * Clean up sound support - to be called when the game exits.
*
- * Note that "Term_redraw()" calls "TERM_XTRA_CLEAR"
+ * Globals referenced: channels[], samples[], sample_refs[].
*/
-static void term_data_redraw(term_data *td)
+static void cleanup_sound(void)
{
- term *old = Term;
-
- /* Activate the term */
- Term_activate(td->t);
-
- /* Redraw the contents */
- Term_redraw();
+ int i;
- /* Flush the output */
- Term_fresh();
+ /* No need to clean it up */
+ if (!channel_initialised) return;
- /* Restore the old term */
- Term_activate(old);
-
- /* No need to redraw */
-#if TARGET_API_MAC_CARBON
+ /* Dispose channels */
+ for (i = 0; i < MAX_CHANNELS; i++)
{
- RgnHandle theRgn = NewRgn();
- GetWindowRegion( td->w, kWindowContentRgn, theRgn );
- ValidWindowRgn( (WindowRef)(td->w), theRgn );
- DisposeRgn( theRgn );
+ /* Drain sound commands and free the channel */
+ SndDisposeChannel(channels[i], TRUE);
}
-#else
- ValidRect(&td->w->portRect);
-#endif
-}
+ /* 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 */
+ }
+}
-#ifdef ANGBAND_LITE_MAC
-/* No graphics */
+/*
+ * 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: ditto.
+ */
+static void play_sound(int num, SInt16 vol)
+{
+ OSErr err;
+ int i;
+ int prev_num;
+ SndListHandle h;
+ SndChannelPtr chan;
+ SCStatus status;
-#else /* ANGBAND_LITE_MAC */
+ static int next_chan;
+ static SInt16 channel_occupants[MAX_CHANNELS];
+ static SndCommand volume_cmd, quiet_cmd;
-/*
- * Constants
- */
+ /* 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, 0L);
-static int pictID = 1001; /* 8x8 tiles; 16x16 tiles are 1002 */
+ /* Error */
+ if (err != noErr)
+ {
+ /* Free channels */
+ while (--i >= 0)
+ {
+ SndDisposeChannel(channels[i], TRUE);
+ }
-static int grafWidth = 8; /* Always equal to grafHeight */
-static int grafHeight = 8; /* Either 8 or 16 */
+ /* Notify error */
+#ifdef JP
+ plog("¥µ¥¦¥ó¥É¥Á¥ã¥ó¥Í¥ë¤ò½é´ü²½½ÐÍè¤Þ¤»¤ó!");
+#else
+ plog("Cannot initialise sound channels!");
+#endif
-static bool arg_newstyle_graphics;
-static bool use_newstyle_graphics;
+ /* Cancel request */
+ use_sound = arg_sound = FALSE;
-/*
- * Forward Declare
- */
-typedef struct FrameRec FrameRec;
+ /* Failure */
+ return;
+ }
+ }
-/*
- * 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;
-
-};
+ /* First channel to use */
+ next_chan = 0;
+ /* Prepare volume command */
+ volume_cmd.cmd = volumeCmd;
+ volume_cmd.param1 = 0;
+ volume_cmd.param2 = 0;
-/*
- * The global picture data
- */
-static FrameRec *frameP = NULL;
+ /* Prepare quiet command */
+ quiet_cmd.cmd = quietCmd;
+ quiet_cmd.param1 = 0;
+ quiet_cmd.param2 = 0;
+ /* Initialisation complete */
+ channel_initialised = TRUE;
+ }
-/*
- * Lock a frame
- */
-static void BenSWLockFrame(FrameRec *srcFrameP)
-{
- PixMapHandle pixMapH;
+ /* Paranoia */
+ if ((num <= 0) || (num >= SOUND_MAX)) return;
- pixMapH = GetGWorldPixMap(srcFrameP->framePort);
- (void)LockPixels(pixMapH);
- HLockHi((Handle)pixMapH);
- srcFrameP->framePixHndl = pixMapH;
-#if TARGET_API_MAC_CARBON
- srcFrameP->framePix = (PixMapPtr)*(Handle)pixMapH;
-#else
- srcFrameP->framePix = (PixMapPtr)StripAddress(*(Handle)pixMapH);
-#endif
-
-}
+ /* Prepare volume command */
+ volume_cmd.param2 = ((SInt32)vol << 16) | vol;
+ /* Channel to use (round robin) */
+ chan = channels[next_chan];
-/*
- * Unlock a frame
- */
-static void BenSWUnlockFrame(FrameRec *srcFrameP)
-{
- if (srcFrameP->framePort != NULL)
+ /* See if the resource is already in use */
+ if (sample_refs[num] > 0)
{
- HUnlock((Handle)srcFrameP->framePixHndl);
- UnlockPixels(srcFrameP->framePixHndl);
+ /* Resource in use */
+ h = samples[num];
+
+ /* Increase the refcount */
+ sample_refs[num]++;
}
- srcFrameP->framePix = NULL;
-
-}
+ /* 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 */
-static OSErr BenSWCreateGWorldFromPict(
- GWorldPtr *pictGWorld,
- PicHandle pictH)
-{
- OSErr err;
- GWorldPtr saveGWorld;
- GDHandle saveGDevice;
- GWorldPtr tempGWorld;
- Rect pictRect;
- short depth;
- GDHandle theGDH;
+ /* Sample not available */
+ if (h == NULL) return;
- /* Reset */
- *pictGWorld = NULL;
+#ifndef USE_QT_SOUND
- /* Get depth */
- depth = data[0].pixelDepth;
+ /* Load resource */
+ LoadResource((Handle)h);
- /* Get GDH */
- theGDH = data[0].theGDH;
+ /* Remember it */
+ samples[num] = h;
- /* Obtain size rectangle */
- pictRect = (**pictH).picFrame;
- OffsetRect(&pictRect, -pictRect.left, -pictRect.top);
+#endif /* !USE_QT_SOUND */
- /* Create a GWorld */
- err = NewGWorld(&tempGWorld, depth, &pictRect, nil,
- theGDH, noNewDevice);
+ /* Lock the handle */
+ HLockHi((Handle)h);
- /* Success */
- if (err != noErr)
- {
- return (err);
+ /* Initialise refcount */
+ sample_refs[num] = 1;
}
- /* Save pointer */
- *pictGWorld = tempGWorld;
+ /* Poll the channel */
+ err = SndChannelStatus(chan, sizeof(SCStatus), &status);
- /* Save GWorld */
- GetGWorld(&saveGWorld, &saveGDevice);
+ /* It isn't available */
+ if ((err != noErr) || status.scChannelBusy)
+ {
+ /* Shut it down */
+ SndDoImmediate(chan, &quiet_cmd);
+ }
- /* Activate */
- SetGWorld(tempGWorld, nil);
+ /* Previously played sound on this channel */
+ prev_num = channel_occupants[next_chan];
- /* Dump the pict into the GWorld */
- (void)LockPixels(GetGWorldPixMap(tempGWorld));
- EraseRect(&pictRect);
- DrawPicture(pictH, &pictRect);
- UnlockPixels(GetGWorldPixMap(tempGWorld));
+ /* Process previously played sound */
+ if (prev_num != 0)
+ {
+ /* Decrease refcount */
+ sample_refs[prev_num]--;
- /* Restore GWorld */
- SetGWorld(saveGWorld, saveGDevice);
-
- /* Success */
- return (0);
-}
+ /* 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;
-/*
- * Init the global "frameP"
- */
+#endif /* !USE_QT_SOUND */
-static errr globe_init(void)
-{
- OSErr err;
-
- GWorldPtr tempPictGWorldP;
+ /* Paranoia */
+ sample_refs[prev_num] = 0;
+ }
+ }
- PicHandle newPictH;
+ /* Remember this sound as the current occupant of the channel */
+ channel_occupants[next_chan] = num;
- /* Use window XXX XXX XXX */
-#if TARGET_API_MAC_CARBON
- SetPortWindowPort(data[0].w);
-#else
- SetPort(data[0].w);
-#endif
+ /* Set up volume for channel */
+ SndDoImmediate(chan, &volume_cmd);
+ /* Play new sound asynchronously */
+ SndPlay(chan, h, TRUE);
- /* Get the pict resource */
- newPictH = GetPicture(pictID);
+ /* Schedule next channel (round robin) */
+ next_chan++;
+ if (next_chan >= MAX_CHANNELS) next_chan = 0;
+}
- /* Analyze result */
- err = (newPictH ? 0 : -1);
+# else /* USE_ASYNC_SOUND */
- /* Oops */
- if (err == noErr)
- {
+/*
+ * Play sound synchronously
+ *
+ * This may not be your choice, but much safer and much less resource hungry.
+ */
+static void play_sound(int num, SInt16 vol)
+{
+ Handle handle;
+ Str255 sound;
- /* Create GWorld */
- err = BenSWCreateGWorldFromPict(&tempPictGWorldP, newPictH);
-
- /* Release resource */
- ReleaseResource((Handle)newPictH);
+ /* Get the proper sound name */
+ strnfmt((char*)sound + 1, 255, "%.16s.wav", angband_sound_name[num]);
+ sound[0] = strlen((char*)sound + 1);
- /* Error */
- if (err == noErr)
- {
- /* Create the frame */
- frameP = (FrameRec*)NewPtrClear((Size)sizeof(FrameRec));
+ /* Obtain resource XXX XXX XXX */
+ handle = GetNamedResource('snd ', sound);
- /* Analyze result */
- err = (frameP ? 0 : -1);
+ /* Oops */
+ if (handle == NULL) return;
- /* Oops */
- if (err == noErr)
- {
- /* Save GWorld */
- frameP->framePort = tempPictGWorldP;
+ /* Load and Lock */
+ LoadResource(handle);
+ HLockHi(handle);
- /* Lock it */
- BenSWLockFrame(frameP);
- }
- }
- }
+ /* Play sound (wait for completion) */
+ SndPlay(NULL, (SndListHandle)handle, FALSE);
- /* Result */
- return (err);
+ /* Unlock and release */
+ HUnlock(handle);
+ ReleaseResource(handle);
}
+# endif /* USE_ASYNC_SOUND */
/*
- * Nuke the global "frameP"
- */
-static errr globe_nuke(void)
-{
- /* Dispose */
- if (frameP)
- {
- /* Unlock */
- BenSWUnlockFrame(frameP);
+ Extra Sound Mode
+*/
- /* Dispose of the GWorld */
- DisposeGWorld(frameP->framePort);
- /* Dispose of the memory */
- DisposePtr((Ptr)frameP);
+static short soundmode[8];
- /* Forget */
- frameP = NULL;
- }
+#define SND_NON 0
+#define SND_ATTACK 1
+#define SND_MOVE 2
+#define SND_TRAP 3
+#define SND_SHOP 4
+#define SND_ME 5
+#define SND_CMD_ERROR 6
+
+#ifndef MACH_O_CARBON
- /* Flush events */
- FlushEvents(everyEvent, 0);
+static int soundchoice[] = {
+ SND_NON,
+ SND_ATTACK,
+ SND_ATTACK,
+ SND_ATTACK,
+ SND_TRAP,
+ SND_ATTACK,
+ SND_ME,
+ SND_ME,
+ SND_ME,
+ SND_MOVE,
+ SND_ATTACK,
+ SND_ME,
+ SND_ATTACK,
+ SND_NON,
+ SND_MOVE,
+ SND_MOVE,
+ SND_ME,
+ SND_SHOP,
+ SND_SHOP,
+ SND_SHOP,
+ SND_SHOP,
+ SND_MOVE,
+ SND_MOVE,
+ SND_MOVE,
+ SND_MOVE,
+ SND_ATTACK,
+ SND_SHOP,
+ SND_SHOP,
+ SND_ME,
+ SND_NON,
+ SND_ATTACK,
+ SND_NON,
+ SND_NON,
+ SND_NON,
+ SND_NON,
+ SND_ATTACK,
+ SND_ATTACK,
+ SND_NON,
+ SND_NON,
+ SND_ATTACK,
+ SND_NON,
+ SND_NON,
+ SND_NON,
+ SND_TRAP,
+ SND_ATTACK,
+ SND_ATTACK,
+ SND_ATTACK,
+ SND_ATTACK,
+ SND_ATTACK,
+ SND_NON,
+ SND_NON,
+ SND_NON,
+ SND_NON,
+ SND_NON,
+ SND_CMD_ERROR,
+ SND_TRAP,
+ SND_NON,
+ SND_NON,
+ SND_TRAP,
+ SND_ATTACK,
+ SND_TRAP,
+ SND_ATTACK,
+ SND_ATTACK,
+ SND_NON,
+ SND_TRAP,
+};
- /* Success */
- return (0);
-}
+static int ext_sound = 0;
+static int ext_graf = 0;
+#endif /* !MACH_O_CARBON */
#endif /* ANGBAND_LITE_MAC */
}
- /* Handle transparency */
- if (use_newstyle_graphics != arg_newstyle_graphics)
+ /* Handle graphics */
+ if (graf_mode_req != graf_mode)
{
+ /* dispose old GWorld's if present */
globe_nuke();
- if (globe_init() != 0)
+ /* Setup parameters according to request */
+ switch (graf_mode_req)
{
- plog("Cannot initialize graphics!");
- arg_graphics = FALSE;
- arg_newstyle_graphics = FALSE;
- }
-
- /* Apply request */
- use_newstyle_graphics = arg_newstyle_graphics;
+ /* ASCII - no graphics whatsoever */
+ case GRAF_MODE_NONE:
+ {
+ use_graphics = arg_graphics = GRAPHICS_NONE;
+ break;
+ }
- /* Apply and Verify */
- term_data_check_size(td);
+ /*
+ * 8x8 tiles (PICT id 1001)
+ * no transparency effect
+ * "old" graphics definitions
+ */
+ case GRAF_MODE_8X8:
+ {
+ use_graphics = arg_graphics = GRAPHICS_ORIGINAL;
+ ANGBAND_GRAF = "old";
+#ifdef MACH_O_CARBON
+ pictID = CFSTR("8x8");
+#else
+ pictID = 1001;
+#endif /* MACH_O_CARBON */
+ grafWidth = grafHeight = 8;
+ break;
+ }
- /* Resize the window */
- term_data_resize(td);
-
- /* Reset visuals */
- reset_visuals();
- }
-
- /* Handle graphics */
- if (use_graphics != arg_graphics)
- {
- /* Initialize graphics */
+ /*
+ * 16x16 tiles (images: PICT id 1002)
+ * with transparency effect
+ * "new" graphics definitions
+ */
+ case GRAF_MODE_16X16:
+ {
+ use_graphics = arg_graphics = GRAPHICS_ADAM_BOLT;
+ ANGBAND_GRAF = "new";
+#ifdef MACH_O_CARBON
+ pictID = CFSTR("16x16");
+#else
+ pictID = 1002;
+#endif /* MACH_O_CARBON */
+ grafWidth = grafHeight = 16;
+ break;
+ }
+ }
- if (!use_graphics && !frameP && (globe_init() != 0))
+ if ((graf_mode_req != GRAF_MODE_NONE) && !frameP && (globe_init() != 0))
{
#ifdef JP
plog("¥°¥é¥Õ¥£¥Ã¥¯¤Î½é´ü²½¤Ï½ÐÍè¤Þ¤»¤ó¤Ç¤·¤¿.");
#else
plog("Cannot initialize graphics!");
#endif
- arg_graphics = FALSE;
+
+ /* reject request */
+ graf_mode_req = GRAF_MODE_NONE;
+
+ /* reset graphics flags */
+ use_graphics = arg_graphics = FALSE;
+
}
- /* Apply request */
- use_graphics = arg_graphics;
+ /* update current graphics mode */
+ graf_mode = graf_mode_req;
/* Apply and Verify */
term_data_check_size(td);
/* Gfx settings */
save_pref_short("arg.arg_sound", arg_sound);
- save_pref_short("arg.arg_graphics", arg_graphics);
- save_pref_short("arg.arg_newstyle_graphics", arg_newstyle_graphics);
- save_pref_short("arg.arg_bigtile", arg_bigtile);
-
-#ifndef MACH_O_CARBON
+ save_pref_short("arg.graf_mode", graf_mode);
+ save_pref_short("arg.arg_bigtile", use_bigtile);
/* SoundMode */
for( i = 0 ; i < 7 ; i++ )
save_pref_short(format("sound%d.on", i), soundmode[i]);
-#endif /* MACH_O_CARBON */
-
/* Windows */
for (i = 0; i < MAX_TERM_DATA; i++)
{
short pref_major, pref_minor, pref_patch, pref_extra;
int i;
- MenuHandle m;
-
/* Assume nothing is wrong, yet */
ok = TRUE;
return;
}
-#if 0
-
- /* Check version */
- if ((pref_major != PREF_VER_MAJOR) ||
- (pref_minor != PREF_VER_MINOR) ||
- (pref_patch != PREF_VER_PATCH) ||
- (pref_extra != PREF_VER_EXTRA))
- {
- /* Message */
- mac_warning(
- format("Ignoring %d.%d.%d.%d preferences.",
- pref_major, pref_minor, pref_patch, pref_extra));
-
- /* Ignore */
- return;
- }
-
-#endif
-
/* Gfx settings */
{
short pref_tmp;
arg_sound = pref_tmp;
/* graphics */
- if (query_load_pref_short("arg.arg_graphics", &pref_tmp))
- arg_graphics = pref_tmp;
-
- /*newstyle graphics*/
- if (query_load_pref_short("arg.arg_newstyle_graphics", &pref_tmp))
- {
- use_newstyle_graphics = pref_tmp;
- }
-
- if (use_newstyle_graphics == true)
- {
- ANGBAND_GRAF = "new";
- arg_newstyle_graphics = true;
- grafWidth = grafHeight = 16;
- pictID = 1002;
- }
- else
- {
- ANGBAND_GRAF = "old";
- arg_newstyle_graphics = false;
- grafWidth = grafHeight = 8;
- pictID = 1001;
- }
+ if (query_load_pref_short("arg.graf_mode", &pref_tmp))
+ graf_mode_req = pref_tmp;
/* double-width tiles */
if (query_load_pref_short("arg.arg_bigtile", &pref_tmp))
}
-#ifndef MACH_O_CARBON
-
/* SoundMode */
for( i = 0 ; i < 7 ; i++ )
{
query_load_pref_short(format("sound%d.on", i), &soundmode[i]);
}
-#endif /* MACH_O_CARBON */
-
- /* Special menu */
- m = GetMenuHandle(134);
-
- /* Item "arg_sound" */
- CheckMenuItem(m, 1, arg_sound);
-
- /* Item "arg_graphics" */
- CheckMenuItem(m, 2, arg_graphics);
-
- /* Item "arg_newstyle_graphics"*/
- CheckMenuItem(m, 8, arg_newstyle_graphics);
-
- /* Item "arg_bigtile"*/
- CheckMenuItem(m, 9, arg_bigtile);
-
/* Windows */
for (i = 0; i < MAX_TERM_DATA; i++)
{
putshort(FAKE_VER_PATCH);
putshort(arg_sound);
- putshort(arg_graphics);
- putshort(arg_newstyle_graphics);
+ putshort(graf_mode);
putshort(arg_bigtile);
/* SoundMode */
}
arg_sound = getshort();
- arg_graphics = getshort();
- arg_newstyle_graphics = getshort();
- use_newstyle_graphics = arg_newstyle_graphics;
-
- if (use_newstyle_graphics == true)
- {
- ANGBAND_GRAF = "new";
- arg_newstyle_graphics = true;
- grafWidth = grafHeight = 16;
- pictID = 1002;
- }
- else
- {
- ANGBAND_GRAF = "old";
- arg_newstyle_graphics = false;
- grafWidth = grafHeight = 8;
- pictID = 1001;
- }
-
+ graf_mode_req = getshort();
arg_bigtile = getshort();
use_bigtile = arg_bigtile;
for( i = 0 ; i < 7 ; i++ )
soundmode[i] = getshort();
- /* Special menu */
- m = GetMenuHandle(134);
-
- /* Item "arg_sound" */
- CheckItem(m, 1, arg_sound);
-
- /* Item "arg_graphics" */
- CheckItem(m, 2, arg_graphics);
-
- /* Item "arg_newstyle_graphics"*/
- CheckItem(m, 8, arg_newstyle_graphics);
-
- /* Item "arg_bigtile"*/
- CheckItem(m, 9, arg_bigtile);
-
/* Windows */
for (i = 0; i < MAX_TERM_DATA; i++)
{
/*
* Initialize the menus
*
- * Verify menus 128, 129, 130
- * Create menus 131, 132, 133, 134
- *
- * The standard menus are:
- *
* Apple (128) = { About, -, ... }
* File (129) = { New,Open,Import,Close,Save,-,Exit,Quit }
* Edit (130) = { Cut, Copy, Paste, Clear } (?)
* Size (132) = { ... }
* Window (133) = { Angband, Mirror, Recall, Choice,
* Term-4, Term-5, Term-6, Term-7 }
- * Special (134) = { arg_sound, arg_graphics, -,
- * arg_fiddle, arg_wizard }
+ * 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_NEW 1
+# define ITEM_OPEN 2
+# define ITEM_IMPORT 3
+# define ITEM_CLOSE 4
+# define ITEM_SAVE 5
+# define ITEM_QUIT 7
+
+/* 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 ITEM_TILEWIDTH 3
+# define ITEM_TILEHEIGHT 4
+# define ITEM_FIDDLE 6
+# define ITEM_WIZARD 7
+
+/* Sounds submenu */
+#define SUBMENU_SOUND 143
+# define ITEM_USE_SOUND 1
+# define ITEM_SOUND_SETTING 2
+
+/* Graphics submenu */
+#define SUBMENU_GRAPH 144
+# define ITEM_NONE 1
+# define ITEM_8X8 2
+# define ITEM_16X16 3
+# define ITEM_BIGTILE 5
+
+/* TileWidth submenu */
+#define SUBMENU_TILEWIDTH 145
+
+/* TileHeight submenu */
+#define SUBMENU_TILEHEIGHT 146
+
+
static void init_menubar(void)
{
int i, n;
WindowPtr tmpw;
MenuHandle m;
- OSErr err;
- long response;
+
+ Handle mbar;
+
+#if TARGET_API_MAC_CARBON
+ OSErr err;
+ long response;
+#endif
/* Get the "apple" menu */
- m = GetMenu(128);
+ mbar = GetNewMBar(128);
- /* Insert the menu */
- InsertMenu(m, 0);
+ /* Whoops! */
+#ifdef JP
+ if (mbar == nil) quit("¥á¥Ë¥å¡¼¥Ð¡¼ ID 128¤ò¸«¤Ä¤±¤ë»ö¤¬¤Ç¤¤Þ¤»¤ó!");
+#else
+ if (mbar == nil) quit("Cannot find menubar('MBAR') id 128!");
+#endif
+
+ /* Insert them into the current menu list */
+ SetMenuBar(mbar);
+
+ /* Free handle */
+ DisposeHandle(mbar);
+
+#if !TARGET_API_MAC_CARBON
+ /* Apple menu (id 128) */
+ m = GetMenuHandle(MENU_APPLE);
/* Add the DA's to the "apple" menu */
-#if TARGET_API_MAC_CARBON
-#else
AppendResMenu (m, 'DRVR');
#endif
/* Get the "File" menu */
#if TARGET_API_MAC_CARBON
- m = GetMenu(129);
+ m = GetMenu(MENU_FILE);
err = Gestalt( gestaltSystemVersion, &response );
if ( (err == noErr) && (response >= 0x00000A00) )
{
- DeleteMenuItem( m, 7 );
+ DeleteMenuItem(m, ITEM_QUIT);
}
-#else
- m = GetMenu(129);
#endif
- /* Insert the menu */
- InsertMenu(m, 0);
-
-
- /* Get the "Edit" menu */
- m = GetMenu(130);
-
- /* Insert the menu */
- InsertMenu(m, 0);
-
-
- /* Make the "Font" menu */
- #ifdef JP
- m = NewMenu(131, "\p¥Õ¥©¥ó¥È");
- #else
- m = NewMenu(131, "\pFont");
- #endif
-
- /* Insert the menu */
- InsertMenu(m, 0);
-
- /* Add "bold" */
- AppendMenu(m, "\pBold");
+ /* Edit menu (id 130) - we don't have to do anything */
- /* Add "wide" */
- AppendMenu(m, "\pWide");
-
- /* Add a separator */
- AppendMenu(m, "\p-");
+ /*
+ * 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;
AppendResMenu (m, 'FONT');
- /* Make the "Size" menu */
- #ifdef JP
- m = NewMenu(132, "\p¥µ¥¤¥º");
- #else
- m = NewMenu(132, "\pSize");
- #endif
-
- /* Insert the menu */
- InsertMenu(m, 0);
+ /* Size menu (id 132) */
+ m = GetMenuHandle(MENU_SIZE);
/* Add some sizes (stagger choices) */
for (i = 8; i <= 32; i += ((i / 16) + 1))
}
- /* Make the "Windows" menu */
- #ifdef JP
- m = NewMenu(133, "\p¥¦¥¤¥ó¥É¥¦");
- #else
- m = NewMenu(133, "\pWindows");
- #endif
-
- /* Insert the menu */
- InsertMenu(m, 0);
+ /* Windows menu (id 133) */
+ m = GetMenuHandle(MENU_WINDOWS);
/* Default choices */
for (i = 0; i < MAX_TERM_DATA; i++)
/* Add the item */
AppendMenu(m, buf);
- /* Command-Key shortcuts */
- if (i < 8) SetItemCmd(m, i + 1, '0' + i);
- }
+ /* Command-Key shortcuts */
+ if (i < 8) SetItemCmd(m, i + 1, '0' + i);
+ }
+
+
+#if TARGET_API_MAC_CARBON && !defined(MAC_MPW)
+
+ /* CW or gcc -- Use recommended interface for hierarchical menus */
+
+ /* Special menu (id 134) */
+ m = GetMenuHandle(MENU_SPECIAL);
+
+ /* Insert Graphics submenu (id 143) */
+ {
+ MenuHandle submenu;
+
+ /* Get the submenu */
+ submenu = GetMenu(SUBMENU_SOUND);
+
+ /* Insert it */
+ SetMenuItemHierarchicalMenu(m, ITEM_SOUND, submenu);
+ }
+
+ /* 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);
+ }
+
+ /* 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);
+ }
+
+ /* Insert it */
+ SetMenuItemHierarchicalMenu(m, ITEM_TILEHEIGHT, submenu);
+ }
+
+#else
+
+ /* Special menu (id 134) */
+
+ /* Get graphics (sub)menu (id 143) */
+ m = GetMenu(SUBMENU_SOUND);
+
+ /* Insert it as a submenu */
+ InsertMenu(m, hierMenu);
- /* Make the "Special" menu */
- #ifdef JP
- m = NewMenu(134, "\pÆÃÊÌ");
- #else
- m = NewMenu(134, "\pSpecial");
- #endif
-
- /* Insert the menu */
- InsertMenu(m, 0);
+ /* Get graphics (sub)menu (id 144) */
+ m = GetMenu(SUBMENU_GRAPH);
- /* Append the choices */
- #ifdef JP
- AppendMenu(m, "\p¥µ¥¦¥ó¥É»ÈÍÑ");
- AppendMenu(m, "\p¥°¥é¥Õ¥£¥Ã¥¯»ÈÍÑ");
- AppendMenu(m, "\p-");
- AppendMenu(m, "\parg_fiddle");
- AppendMenu(m, "\parg_wizard");
- AppendMenu(m, "\p-");
- AppendMenu(m, "\p¥µ¥¦¥ó¥ÉÀßÄê...");
- AppendMenu(m, "\p16X16¥°¥é¥Õ¥£¥Ã¥¯");
- AppendMenu(m, "\p£²ÇÜÉý¥¿¥¤¥ëɽ¼¨");
- #else
- AppendMenu(m, "\parg_sound");
- AppendMenu(m, "\parg_graphics");
- AppendMenu(m, "\p-");
- AppendMenu(m, "\parg_fiddle");
- AppendMenu(m, "\parg_wizard");
- AppendMenu(m, "\p-");
- AppendMenu(m, "\pSound config");
- AppendMenu(m, "\pAdam Bolt tile");
- AppendMenu(m, "\pBigtile Mode");
- #endif
+ /* Insert it as a submenu */
+ InsertMenu(m, hierMenu);
- /* Make the "TileWidth" menu */
- #ifdef JP
- m = NewMenu(135, "\p¥¿¥¤¥ëÉý");
- #else
- m = NewMenu(135, "\pTileWidth");
- #endif
- /* Insert the menu */
- InsertMenu(m, 0);
+ /* Get TileWidth (sub)menu (id 145) */
+ m = GetMenu(SUBMENU_TILEWIDTH);
/* Add some sizes */
for (i = 4; i <= 32; i++)
}
- /* Make the "TileHeight" menu */
- #ifdef JP
- m = NewMenu(136, "\p¥¿¥¤¥ë¹â");
- #else
- m = NewMenu(136, "\pTileHeight");
- #endif
+ /* Insert it as a submenu */
+ InsertMenu(m, hierMenu);
- /* Insert the menu */
- InsertMenu(m, 255);
+ /* Get TileHeight (sub)menu (id 146) */
+ m = GetMenu(SUBMENU_TILEHEIGHT);
/* Add some sizes */
for (i = 4; i <= 32; i++)
}
+ /* Insert the menu */
+ InsertMenu(m, hierMenu);
+
+#endif
/* Update the menu bar */
DrawMenuBar();
}
/* File menu */
- m = GetMenuHandle(129);
+ m = GetMenuHandle(MENU_FILE);
/* Get menu size */
#if TARGET_API_MAC_CARBON
if (initialized && !game_in_progress)
{
#if TARGET_API_MAC_CARBON
- EnableMenuItem(m, 1);
- EnableMenuItem(m, 2);
- EnableMenuItem(m, 3);
+ EnableMenuItem(m, ITEM_NEW);
+ EnableMenuItem(m, ITEM_OPEN);
+ EnableMenuItem(m, ITEM_IMPORT);
#else
- EnableItem(m, 1);
- EnableItem(m, 2);
- EnableItem(m, 3);
+ EnableItem(m, ITEM_NEW);
+ EnableItem(m, ITEM_OPEN);
+ EnableItem(m, ITEM_IMPORT);
#endif
}
if (initialized)
{
#if TARGET_API_MAC_CARBON
- EnableMenuItem(m, 4);
+ EnableMenuItem(m, ITEM_CLOSE);
#else
- EnableItem(m, 4);
+ EnableItem(m, ITEM_CLOSE);
#endif
}
if (initialized && character_generated)
{
#if TARGET_API_MAC_CARBON
- EnableMenuItem(m, 5);
+ EnableMenuItem(m, ITEM_SAVE);
#else
- EnableItem(m, 5);
+ EnableItem(m, ITEM_SAVE);
#endif
}
if (TRUE)
{
#if TARGET_API_MAC_CARBON
- EnableMenuItem(m, 7);
+ EnableMenuItem(m, ITEM_QUIT);
#else
- EnableItem(m, 7);
+ EnableItem(m, ITEM_QUIT);
#endif
}
/* Edit menu */
- m = GetMenuHandle(130);
+ m = GetMenuHandle(MENU_EDIT);
/* Get menu size */
#if TARGET_API_MAC_CARBON
if (!td)
{
#if TARGET_API_MAC_CARBON
- EnableMenuItem(m, 1);
- EnableMenuItem(m, 3);
- EnableMenuItem(m, 4);
- EnableMenuItem(m, 5);
- EnableMenuItem(m, 6);
+ EnableMenuItem(m, ITEM_UNDO);
+ EnableMenuItem(m, ITEM_CUT);
+ EnableMenuItem(m, ITEM_COPY);
+ EnableMenuItem(m, ITEM_PASTE);
+ EnableMenuItem(m, ITEM_CLEAR);
#else
- EnableItem(m, 1);
- EnableItem(m, 3);
- EnableItem(m, 4);
- EnableItem(m, 5);
- EnableItem(m, 6);
+ EnableItem(m, ITEM_UNDO);
+ EnableItem(m, ITEM_CUT);
+ EnableItem(m, ITEM_COPY);
+ EnableItem(m, ITEM_PASTE);
+ EnableItem(m, ITEM_CLEAR);
#endif
}
/* Font menu */
- m = GetMenuHandle(131);
+ m = GetMenuHandle(MENU_FONT);
/* Get menu size */
#if TARGET_API_MAC_CARBON
{
#if TARGET_API_MAC_CARBON
/* Enable "bold" */
- EnableMenuItem(m, 1);
+ EnableMenuItem(m, ITEM_BOLD);
/* Enable "extend" */
- EnableMenuItem(m, 2);
+ EnableMenuItem(m, ITEM_WIDE);
/* Check the appropriate "bold-ness" */
- if (td->font_face & bold) CheckMenuItem(m, 1, TRUE);
+ if (td->font_face & bold) CheckMenuItem(m, ITEM_BOLD, TRUE);
/* Check the appropriate "wide-ness" */
- if (td->font_face & extend) CheckMenuItem(m, 2, TRUE);
+ if (td->font_face & extend) CheckMenuItem(m, ITEM_WIDE, TRUE);
/* Analyze fonts */
for (i = 4; i <= n; i++)
}
#else
/* Enable "bold" */
- EnableItem(m, 1);
+ EnableItem(m, ITEM_BOLD);
/* Enable "extend" */
- EnableItem(m, 2);
+ EnableItem(m, ITEM_WIDE);
/* Check the appropriate "bold-ness" */
- if (td->font_face & bold) CheckItem(m, 1, TRUE);
+ if (td->font_face & bold) CheckItem(m, ITEM_BOLD, TRUE);
/* Check the appropriate "wide-ness" */
- if (td->font_face & extend) CheckItem(m, 2, TRUE);
+ if (td->font_face & extend) CheckItem(m, ITEM_WIDE, TRUE);
/* Analyze fonts */
for (i = 4; i <= n; i++)
/* Size menu */
- m = GetMenuHandle(132);
+ m = GetMenuHandle(MENU_SIZE);
/* Get menu size */
#if TARGET_API_MAC_CARBON
/* Analyze sizes */
for (i = 1; i <= n; i++)
{
-#if TARGET_API_MAC_CARBON
/* Analyze size */
GetMenuItemText(m, i, s);
s[s[0]+1] = '\0';
value = atoi((char*)(s+1));
+#if TARGET_API_MAC_CARBON
/* 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);
#else
- /* Analyze size */
- GetMenuItemText(m, i, s);
- s[s[0]+1] = '\0';
- value = atoi((char*)(s+1));
-
/* Enable the "real" sizes */
if (RealFont(td->font_id, value)) EnableItem(m, i);
/* Windows menu */
- m = GetMenuHandle(133);
+ m = GetMenuHandle(MENU_WINDOWS);
/* Get menu size */
#if TARGET_API_MAC_CARBON
/* Special menu */
- m = GetMenuHandle(134);
+ m = GetMenuHandle(MENU_SPECIAL);
/* Get menu size */
#if TARGET_API_MAC_CARBON
/* Reset */
#if TARGET_API_MAC_CARBON
DisableMenuItem(m, i);
+
+#ifdef MAC_MPW
+ /* XXX Oh no, this removes submenu... */
+ if ((i != ITEM_SOUND) &&
+ (i != ITEM_GRAPH) &&
+ (i != ITEM_TILEWIDTH) &&
+ (i != ITEM_TILEHEIGHT)) CheckMenuItem(m, i, FALSE);
+#else
+
CheckMenuItem(m, i, FALSE);
+#endif
+
#else
DisableItem(m, i);
- CheckItem(m, i, FALSE);
+
+ /* XXX Oh no, this removes submenu... */
+ if ((i != ITEM_SOUND) &&
+ (i != ITEM_GRAPH) &&
+ (i != ITEM_TILEWIDTH) &&
+ (i != ITEM_TILEHEIGHT)) CheckItem(m, i, FALSE);
#endif
}
#if TARGET_API_MAC_CARBON
/* Item "arg_sound" */
- EnableMenuItem(m, 1);
- CheckMenuItem(m, 1, arg_sound);
+ EnableMenuItem(m, ITEM_SOUND);
+ {
+ MenuRef submenu;
- /* Item "arg_graphics" */
- EnableMenuItem(m, 2);
- CheckMenuItem(m, 2, arg_graphics);
+#ifdef MAC_MPW
- /* Item "arg_fiddle" */
- EnableMenuItem(m, 4);
- CheckMenuItem(m, 4, arg_fiddle);
+ /* MPW's Universal Interface is a bit out of date */
- /* Item "arg_wizard" */
- EnableMenuItem(m, 5);
- CheckMenuItem(m, 5, arg_wizard);
+ /* Graphics submenu */
+ submenu = GetMenuHandle(SUBMENU_SOUND);
+
+#else
+
+ /* Graphics submenu */
+ (void)GetMenuItemHierarchicalMenu(m, ITEM_SOUND, &submenu);
+
+#endif
+
+ /* Get menu size */
+ n = CountMenuItems(submenu);
+
+ /* Reset menu */
+ for (i = 1; i <= n; i++)
+ {
+ /* Reset */
+ DisableMenuItem(submenu, i);
+ CheckMenuItem(submenu, i, FALSE);
+ }
+
+ /* Item "Sound On/Off" */
+ EnableMenuItem(submenu, ITEM_USE_SOUND);
+ CheckMenuItem(submenu, ITEM_USE_SOUND, arg_sound);
+
+ /* Item "Sounf Config" */
+#ifndef MACH_O_CARBON
+ EnableMenuItem(submenu, ITEM_SOUND_SETTING);
+#endif
+ }
+
+ /* Item "Graphics" */
+ EnableMenuItem(m, ITEM_GRAPH);
+ {
+ MenuRef submenu;
+
+#ifdef MAC_MPW
+
+ /* MPW's Universal Interface is a bit out of date */
+
+ /* Graphics submenu */
+ submenu = GetMenuHandle(SUBMENU_GRAPH);
+
+#else
+
+ /* Graphics submenu */
+ (void)GetMenuItemHierarchicalMenu(m, ITEM_GRAPH, &submenu);
+
+#endif
+
+ /* 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 "Big tiles" */
+ EnableMenuItem(submenu, ITEM_BIGTILE);
+ CheckMenuItem(submenu, ITEM_BIGTILE, arg_bigtile);
+ }
+
+ /* Item "TileWidth" */
+ EnableMenuItem(m, ITEM_TILEWIDTH);
+ {
+ MenuRef submenu;
+
+#ifdef MAC_MPW
+
+ /* MPW's Universal Interface is a bit out of date */
+
+ /* TIleWidth submenu */
+ submenu = GetMenuHandle(SUBMENU_TILEWIDTH);
+
+#else
+
+ /* TileWidth submenu */
+ (void)GetMenuItemHierarchicalMenu(m, ITEM_TILEWIDTH, &submenu);
+
+#endif
+
+ /* 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 (td)
+ {
+ /* Analyze sizes */
+ for (i = 1; i <= n; i++)
+ {
+ /* Analyze size */
+ /* GetMenuItemText(m,i,s); */
+ GetMenuItemText(submenu, i, s);
+ s[s[0]+1] = '\0';
+ value = atoi((char*)(s+1));
+
+ /* 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;
+
+#ifdef MAC_MPW
+
+ /* MPW's Universal Interface is a bit out of date */
+
+ /* TileHeight submenu */
+ submenu = GetMenuHandle(SUBMENU_TILEHEIGHT);
+
+#else
+
+ /* TileWidth submenu */
+ (void)GetMenuItemHierarchicalMenu(m, ITEM_TILEHEIGHT, &submenu);
+
+#endif
+
+ /* 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 (td)
+ {
+ /* Analyze sizes */
+ for (i = 1; i <= n; i++)
+ {
+ /* Analyze size */
+ /* GetMenuItemText(m,i,s); */
+ GetMenuItemText(submenu, i, s);
+ s[s[0]+1] = '\0';
+ value = atoi((char*)(s+1));
+
+ /* Enable */
+ if (value >= td->font_hgt) EnableMenuItem(submenu, i);
+
+ /* Check the current size */
+ if (td->tile_hgt == value) CheckMenuItem(submenu, i, TRUE);
+ }
+ }
+ }
- /* Item "SoundSetting" */
- EnableMenuItem(m, 7);
+ /* Item "arg_fiddle" */
+ EnableMenuItem(m, ITEM_FIDDLE);
+ CheckMenuItem(m, ITEM_FIDDLE, arg_fiddle);
- /* Item NewStyle Graphics */
- EnableMenuItem(m, 8);
- CheckMenuItem(m, 8, use_newstyle_graphics);
+ /* Item "arg_wizard" */
+ EnableMenuItem(m, ITEM_WIZARD);
+ CheckMenuItem(m, ITEM_WIZARD, arg_wizard);
- /* Item Bigtile Mode */
- EnableMenuItem(m, 9);
- CheckMenuItem(m, 9, arg_bigtile);
#else
/* Item "arg_sound" */
- EnableItem(m, 1);
- CheckItem(m, 1, arg_sound);
+ EnableItem(m, ITEM_SOUND);
/* Item "arg_graphics" */
- EnableItem(m, 2);
- CheckItem(m, 2, arg_graphics);
+ EnableItem(m, ITEM_GRAPH);
+
+ /* Item "TileWidth" */
+ EnableItem(m, ITEM_TILEWIDTH);
+
+ /* Item "TileHeight" */
+ EnableItem(m, ITEM_TILEHEIGHT);
/* Item "arg_fiddle" */
- EnableItem(m, 4);
- CheckItem(m, 4, arg_fiddle);
+ EnableItem(m, ITEM_FIDDLE);
+ CheckItem(m, ITEM_FIDDLE, arg_fiddle);
/* Item "arg_wizard" */
- EnableItem(m, 5);
- CheckItem(m, 5, arg_wizard);
+ EnableItem(m, ITEM_WIZARD);
+ CheckItem(m, ITEM_WIZARD, arg_wizard);
- /* Item "SoundSetting" */
- EnableItem(m, 7);
+ /* Sounds submenu */
+ m = GetMenuHandle(SUBMENU_SOUND);
- /* Item NewStyle Graphics */
- EnableItem(m, 8);
- CheckItem(m, 8, use_newstyle_graphics);
+ /* Get menu size */
+ n = CountMItems(m);
- /* Item Bigtile Mode */
- EnableItem(m, 9);
- CheckItem(m, 9, arg_bigtile);
-#endif
+ /* Reset menu */
+ for (i = 1; i <= n; i++)
+ {
+ /* Reset */
+ DisableItem(m, i);
+ CheckItem(m, i, FALSE);
+ }
+
+ /* Item "Sound On/Off" */
+ EnableItem(m, ITEM_USE_SOUND);
+ CheckItem(m, ITEM_USE_SOUND, arg_sound);
+
+ /* Item "Sound Config" */
+ EnableItem(m, ITEM_SOUND_SETTING);
- /* TileWidth menu */
- m = GetMenuHandle(135);
+ /* Graphics submenu */
+ m = GetMenuHandle(SUBMENU_GRAPH);
+
+ /* Get menu size */
+ n = CountMItems(m);
+
+ /* Reset menu */
+ for (i = 1; i <= n; i++)
+ {
+ /* Reset */
+ DisableItem(m, i);
+ CheckItem(m, i, FALSE);
+ }
+
+ /* Item "None" */
+ EnableItem(m, ITEM_NONE);
+ CheckItem(m, ITEM_NONE, (graf_mode == GRAF_MODE_NONE));
+
+ /* Item "8x8" */
+ EnableItem(m, ITEM_8X8);
+ CheckItem(m, ITEM_8X8, (graf_mode == GRAF_MODE_8X8));
+
+ /* Item "16x16" */
+ EnableItem(m, ITEM_16X16);
+ CheckItem(m, ITEM_16X16, (graf_mode == GRAF_MODE_16X16));
+
+ /* Item "Bigtile" */
+ EnableItem(m, ITEM_BIGTILE);
+ CheckItem(m, ITEM_BIGTILE, arg_bigtile);
+
+
+ /* TIleWidth submenu */
+ m = GetMenuHandle(SUBMENU_TILEWIDTH);
/* Get menu size */
-#if TARGET_API_MAC_CARBON
- n = CountMenuItems(m);
-#else
n = CountMItems(m);
-#endif
/* Reset menu */
for (i = 1; i <= n; i++)
{
/* Reset */
-#if TARGET_API_MAC_CARBON
- DisableMenuItem(m, i);
- CheckMenuItem(m, i, FALSE);
-#else
DisableItem(m, i);
CheckItem(m, i, FALSE);
-#endif
}
/* Active window */
s[s[0]+1] = '\0';
value = atoi((char*)(s+1));
-#if TARGET_API_MAC_CARBON
- /* Enable */
- EnableMenuItem(m, i);
-
- /* Check the current size */
- if (td->tile_wid == value) CheckMenuItem(m, i, TRUE);
-#else
/* Enable */
- EnableItem(m, i);
+ if (value >= td->font_wid) EnableItem(m, i);
/* Check the current size */
if (td->tile_wid == value) CheckItem(m, i, TRUE);
-#endif
}
}
- /* TileHeight menu */
- m = GetMenuHandle(136);
+ /* TileHeight submenu */
+ m = GetMenuHandle(SUBMENU_TILEHEIGHT);
/* Get menu size */
-#if TARGET_API_MAC_CARBON
- n = CountMenuItems(m);
-#else
n = CountMItems(m);
-#endif
/* Reset menu */
for (i = 1; i <= n; i++)
{
/* Reset */
-#if TARGET_API_MAC_CARBON
- DisableMenuItem(m, i);
- CheckMenuItem(m, i, FALSE);
-#else
DisableItem(m, i);
CheckItem(m, i, FALSE);
-#endif
}
/* Active window */
s[s[0]+1] = '\0';
value = atoi((char*)(s+1));
-#if TARGET_API_MAC_CARBON
- /* Enable */
- EnableMenuItem(m, i);
-
- /* Check the current size */
- if (td->tile_hgt == value) CheckMenuItem(m, i, TRUE);
-#else
/* Enable */
- EnableItem(m, i);
+ if (value >= td->font_hgt) EnableItem(m, i);
/* Check the current size */
if (td->tile_hgt == value) CheckItem(m, i, TRUE);
-#endif
}
}
+#endif
+
}
switch (menuid)
{
/* Apple Menu */
- case 128:
+ case MENU_APPLE:
{
/* About Angband... */
#if TARGET_API_MAC_CARBON
- if (selection == 1)
+ if (selection == ITEM_ABOUT)
{
DialogPtr dialog;
short item_hit;
break;
}
#else
- if (selection == 1)
+ if (selection == ITEM_ABOUT)
{
DialogPtr dialog;
Rect r;
}
/* Desk accessory */
- /* GetMenuItemText(GetMHandle(128),selection,s); */
- GetMenuItemText(GetMenuHandle(128), selection, s);
+ GetMenuItemText(GetMenuHandle(MENU_APPLE), selection, s);
OpenDeskAcc(s);
break;
#endif
}
/* File Menu */
- case 129:
+ case MENU_FILE:
{
switch (selection)
{
/* New */
- case 1:
+ case ITEM_NEW:
{
do_menu_file_new();
break;
}
/* Open... */
- case 2:
+ case ITEM_OPEN:
{
do_menu_file_open(FALSE);
break;
}
/* Import... */
- case 3:
+ case ITEM_IMPORT:
{
do_menu_file_open(TRUE);
break;
}
/* Close */
- case 4:
+ case ITEM_CLOSE:
{
/* No window */
if (!td) break;
}
/* Save */
- case 5:
+ case ITEM_SAVE:
{
if (!can_save){
#ifdef JP
}
/* Quit (with save) */
- case 7:
+ case ITEM_QUIT:
{
/* Save the game (if necessary) */
if (game_in_progress && character_generated)
}
/* Edit menu */
- case 130:
+ case MENU_EDIT:
{
/* Unused */
break;
}
/* Font menu */
- case 131:
+ case MENU_FONT:
{
/* Require a window */
if (!td) break;
activate(td->w);
/* Toggle the "bold" setting */
- if (selection == 1)
+ if (selection == ITEM_BOLD)
{
/* Toggle the setting */
if (td->font_face & bold)
}
/* Toggle the "wide" setting */
- if (selection == 2)
+ if (selection == ITEM_WIDE)
{
/* Toggle the setting */
if (td->font_face & extend)
}
/* Get a new font name */
- GetMenuItemText(GetMenuHandle(131), selection, s);
+ GetMenuItemText(GetMenuHandle(MENU_FONT), selection, s);
GetFNum(s, &fid);
/* Save the new font id */
}
/* Size menu */
- case 132:
+ case MENU_SIZE:
{
if (!td) break;
/* Activate */
activate(td->w);
- GetMenuItemText(GetMenuHandle(132), selection, s);
+ GetMenuItemText(GetMenuHandle(MENU_SIZE), selection, s);
s[s[0]+1]=0;
td->font_size = atoi((char*)(s+1));
}
/* Window menu */
- case 133:
+ case MENU_WINDOWS:
{
/* Parse */
i = selection - 1;
}
/* Special menu */
- case 134:
+ case MENU_SPECIAL:
+ {
+ switch (selection)
+ {
+ case ITEM_FIDDLE:
+ {
+ arg_fiddle = !arg_fiddle;
+ break;
+ }
+
+ case ITEM_WIZARD:
+ {
+ arg_wizard = !arg_wizard;
+ break;
+ }
+ }
+
+ break;
+ }
+
+ /* Sounds submenu */
+ case SUBMENU_SOUND:
{
switch (selection)
{
- case 1:
+ case ITEM_USE_SOUND:
{
/* Toggle arg_sound */
arg_sound = !arg_sound;
break;
}
- case 2:
+ case ITEM_SOUND_SETTING:
{
- /* Toggle arg_graphics */
- arg_graphics = !arg_graphics;
- if( arg_graphics == true ){
- ANGBAND_GRAF = "old";
- arg_newstyle_graphics = false;
- grafWidth = grafHeight = 8;
- pictID = 1001;
- }
-
- /* Hack -- Force redraw */
- Term_key_push(KTRL('R'));
+ SoundConfigDLog();
break;
}
+ }
- case 4:
- {
- arg_fiddle = !arg_fiddle;
- break;
- }
+ break;
+ }
- case 5:
+ /* Graphics submenu */
+ case SUBMENU_GRAPH:
+ {
+ switch (selection)
+ {
+ case ITEM_NONE:
{
- arg_wizard = !arg_wizard;
+ graf_mode_req = GRAF_MODE_NONE;
+
break;
}
- case 7:
+ case ITEM_8X8:
{
- SoundConfigDLog();
+ graf_mode_req = GRAF_MODE_8X8;
+
break;
}
- case 8:
+
+ case ITEM_16X16:
{
- if (streq(ANGBAND_GRAF, "old"))
- {
- ANGBAND_GRAF = "new";
- arg_newstyle_graphics = true;
- grafWidth = grafHeight = 16;
- pictID = 1002;
- }
- else
- {
- ANGBAND_GRAF = "old";
- arg_newstyle_graphics = false;
- grafWidth = grafHeight = 8;
- pictID = 1001;
- }
+ graf_mode_req = GRAF_MODE_16X16;
- /* Hack -- Force redraw */
- Term_key_push(KTRL('R'));
break;
}
- case 9: /* bigtile mode */
+ case ITEM_BIGTILE:
{
+ term *old = Term;
term_data *td = &data[0];
- if (!can_save){
-#ifdef JP
- plog("º£¤ÏÊѹ¹½ÐÍè¤Þ¤»¤ó¡£");
-#else
- plog("You may not do that right now.");
-#endif
- break;
- }
-
/* Toggle "arg_bigtile" */
arg_bigtile = !arg_bigtile;
/* Resize the term */
Term_resize(td->cols, td->rows);
+ /* Activate old */
+ Term_activate(old);
+
break;
}
-
}
+ /* Hack -- Force redraw */
+ Term_key_push(KTRL('R'));
+
break;
}
- /* TileWidth menu */
- case 135:
+ /* TileWidth submenu */
+ case SUBMENU_TILEWIDTH:
{
if (!td) break;
/* Activate */
activate(td->w);
- GetMenuItemText(GetMenuHandle(135), selection, s);
+ /* Analyse value */
+ GetMenuItemText(GetMenuHandle(SUBMENU_TILEWIDTH), selection, s);
s[s[0]+1]=0;
td->tile_wid = atoi((char*)(s+1));
break;
}
- /* TileHeight menu */
- case 136:
+ /* TileHeight submenu */
+ case SUBMENU_TILEHEIGHT:
{
if (!td) break;
/* Activate */
activate(td->w);
- GetMenuItemText(GetMenuHandle(136), selection, s);
+ /* Analyse value */
+ GetMenuItemText(GetMenuHandle(SUBMENU_TILEHEIGHT), selection, s);
s[s[0]+1]=0;
td->tile_hgt = atoi((char*)(s+1));
{
#pragma unused(reply, handlerRefCon)
#if TARGET_API_MAC_CARBON
+#pragma unused(theAppleEvent)
/* Save the game (if necessary) */
if (game_in_progress && character_generated)
/* 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";