From: nhmall Date: Wed, 1 Feb 2023 03:19:29 +0000 (-0500) Subject: further work on soundlib support code X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8ee42f564441e6cd23dcaf47810416ea5f6c71a7;p=nethack further work on soundlib support code move some inline code into functions replace some magic numbers The mingw code is not tested yet. --- diff --git a/include/extern.h b/include/extern.h index 33c8da31a..e91424b5d 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2615,6 +2615,8 @@ extern void get_soundlib_name(char *dest, int maxlen); #ifdef SND_SOUNDEFFECTS_AUTOMAP extern char *get_sound_effect_filename(int32_t seidint, char *buf, size_t bufsz, int32_t); +extern char *base_soundname_to_filename(char *basename, char *buf, + size_t bufsz, int32_t baseflag); #endif /* ### sp_lev.c ### */ diff --git a/include/sndprocs.h b/include/sndprocs.h index ce644f88a..69f3ee49a 100755 --- a/include/sndprocs.h +++ b/include/sndprocs.h @@ -414,4 +414,16 @@ SoundAchievement(0, sa2_xpleveldown, level); #define SOUNDLIBONLY UNUSED #endif +enum findsound_approaches { + findsound_embedded, + findsound_soundfile +}; + +enum sound_file_flags { + sff_default, /* add dir prefix + '/' + sound + suffix */ + sff_base_only, /* base sound name only, no dir, no suffix */ + sff_havedir_append_rest, /* dir provided, append base sound name + suffix */ + sff_baseknown_add_rest /* base is already known, add dir and suffix */ +}; + #endif /* SNDPROCS_H */ diff --git a/include/windconf.h b/include/windconf.h index 691a7359e..9557cedea 100644 --- a/include/windconf.h +++ b/include/windconf.h @@ -92,6 +92,7 @@ #define INTERJECTION_TYPES (INTERJECT_PANIC + 1) extern void interject_assistance(int, int, genericptr_t, genericptr_t); extern void interject(int); +extern char *windows_exepath(void); /* *=============================================== @@ -119,7 +120,6 @@ extern errno_t tmpfile_s(FILE * restrict * restrict streamptr); #define __USE_MINGW_ANSI_STDIO 1 #endif /* extern int getlock(void); */ -extern char *mingw_exepath(void); #endif /* __MINGW32__ */ #ifdef _MSC_VER diff --git a/sound/macsound/macsound.m b/sound/macsound/macsound.m index 4eb91d99e..dd98f0477 100644 --- a/sound/macsound/macsound.m +++ b/sound/macsound/macsound.m @@ -93,7 +93,8 @@ macsound_soundeffect(char *desc UNUSED, int32_t seid, int volume UNUSED) if (seid <= se_zero_invalid || seid >= number_of_se_entries) return; if (!affiliation[seid]) { - soundname = get_sound_effect_filename(seid, buf, sizeof buf, 1); + soundname = get_sound_effect_filename(seid, buf, sizeof buf, + sff_base_only); if (soundname) { affiliate(seid, soundname); } @@ -231,4 +232,3 @@ affiliate(int32_t seid, const char *soundname) return 1; } /* end of macsound.m */ - diff --git a/sound/windsound/windsound.c b/sound/windsound/windsound.c index 580e21235..b39680e63 100644 --- a/sound/windsound/windsound.c +++ b/sound/windsound/windsound.c @@ -16,6 +16,7 @@ #ifdef SND_LIB_WINDSOUND +/* sound interface routines */ static void windsound_init_nhsound(void); static void windsound_exit_nhsound(const char *); static void windsound_achievement(schar, schar, int32_t); @@ -23,6 +24,10 @@ static void windsound_soundeffect(char *, int32_t, int32_t); static void windsound_hero_playnotes(int32_t instrument, const char *str, int32_t volume); static void windsound_play_usersound(char *, int32_t, int32_t); +/* supporting routines */ +static void adjust_soundargs_for_compiler(int32_t *, DWORD *, char **); +static void maybe_preinsert_directory(int32_t, char *, char *, size_t); + struct sound_procs windsound_procs = { SOUNDID(windsound), SOUND_TRIGGER_USERSOUNDS | SOUND_TRIGGER_SOUNDEFFECTS @@ -56,48 +61,25 @@ windsound_soundeffect(char *desc, int32_t seid, int32_t volume) { #ifdef SND_SOUNDEFFECTS_AUTOMAP int reslt = 0; - int32_t sefnflag = 0; + int32_t findsound_approach = sff_base_only; char buf[PATHLEN]; const char *filename; - DWORD fdwsound; + DWORD fdwsound = SND_NODEFAULT; + char *exedir = 0; + adjust_soundargs_for_compiler(&findsound_approach, &fdwsound, &exedir); + maybe_preinsert_directory(findsound_approach, exedir, buf, sizeof buf); + fdwsound |= SND_ASYNC; if (seid >= se_squeak_C || seid <= se_squeak_B) { -#if defined(__MINGW32__) - /* The mingw32 resources don't seem to be able to be retrieved by the - * API PlaySound function with the SND_RESOURCE flag. Use files from - * the file system instead. */ - extern char *sounddir; /* in sounds.c, set in files.c */ - char *mingw_exedir; - - if (!sounddir) { - mingw_exedir = mingw_exepath(); - if (mingw_exedir) - if (strlen(mingw_exedir) < sizeof buf - 30) { - Strcpy(buf, mingw_exedir); - sefnflag = 2; /* 2 = use the directory name already in buf */ - } - } - filename = get_sound_effect_filename(seid, buf, sizeof buf, sefnflag); - fdwsound = SND_ASYNC | SND_NODEFAULT; -#else - sefnflag = 1; - /* sefnflag = 1 means just obtain the soundeffect base name with - * no directory name and no file extension. That's because we're - * going to use the base soundeffect name as the name of a resource - * that's embedded into the .exe file, passing SND_RESOURCE flag to - * Windows API PlaySound(). - */ - filename = get_sound_effect_filename(seid, buf, sizeof buf, sefnflag); - fdwsound = SND_ASYNC | SND_RESOURCE; -#endif + filename = get_sound_effect_filename(seid, buf, sizeof buf, findsound_approach); } else { - filename = get_sound_effect_filename(seid, buf, sizeof buf, sefnflag); - fdwsound = SND_ASYNC | SND_NODEFAULT; + filename = get_sound_effect_filename(seid, buf, sizeof buf, findsound_approach); + fdwsound &= ~(SND_RESOURCE); + fdwsound |= SND_FILENAME; } if (filename) { reslt = PlaySound(filename, NULL, fdwsound); -// (void) sndPlaySound(filename, fdwsound); } #endif } @@ -110,8 +92,12 @@ windsound_hero_playnotes(int32_t instrument, const char *str, int32_t volume) #ifdef WAVEMUSIC_SOUNDS int reslt = 0; boolean has_note_variations = FALSE; - char resourcename[120], *end_of_res = 0; + const char *filename; + char resourcename[120], buf[PATHLEN], *end_of_res = 0; const char *c = 0; + int findsound_approach = sff_base_only; + DWORD fdwsound = SND_NODEFAULT; + char *exedir = (char *) 0; if (!str) return; @@ -130,17 +116,17 @@ windsound_hero_playnotes(int32_t instrument, const char *str, int32_t volume) has_note_variations = TRUE; break; case ins_french_horn: /* FROST_HORN */ - Strcpy(resourcename, "sound_Frost_Horn"); + Strcpy(resourcename, "sound_Frost_Horn"); break; case ins_baritone_sax: /* FIRE_HORN */ - Strcpy(resourcename, "sound_Fire_Horn"); + Strcpy(resourcename, "sound_Fire_Horn"); break; case ins_trumpet: /* BUGLE */ - Strcpy(resourcename, "sound_Bugle"); + Strcpy(resourcename, "sound_Bugle"); has_note_variations = TRUE; break; case ins_orchestral_harp: /* WOODEN_HARP */ - Strcpy(resourcename, "sound_Wooden_Harp"); + Strcpy(resourcename, "sound_Wooden_Harp"); has_note_variations = TRUE; break; case ins_cello: /* MAGIC_HARP */ @@ -157,6 +143,7 @@ windsound_hero_playnotes(int32_t instrument, const char *str, int32_t volume) Strcpy(resourcename, "sound_Leather_Drum"); break; } + adjust_soundargs_for_compiler(&findsound_approach, &fdwsound, &exedir); if (has_note_variations) { int i, idx = 0, notecount = strlen(str); static const char *const note_suffixes[] @@ -164,20 +151,26 @@ windsound_hero_playnotes(int32_t instrument, const char *str, int32_t volume) end_of_res = eos(resourcename); c = str; + fdwsound |= SND_SYNC; for (i = 0; i < notecount; ++i) { if (*c >= 'A' && *c <= 'G') { idx = (*c) - 'A'; Strcpy(end_of_res, note_suffixes[idx]); + maybe_preinsert_directory(findsound_approach, exedir, buf, sizeof buf); + filename = base_soundname_to_filename(resourcename, + buf, sizeof buf, findsound_approach); if (i == (notecount - 1)) break; /* drop out of for-loop and play it async below */ - reslt = PlaySound(resourcename, NULL, - SND_SYNC | SND_RESOURCE); + reslt = PlaySound(buf, NULL, fdwsound); } c++; } + fdwsound &= ~(SND_SYNC); } + fdwsound |= SND_ASYNC; /* the final, or only, one is played ASYNC */ - reslt = PlaySound(resourcename, NULL, SND_ASYNC | SND_RESOURCE); + maybe_preinsert_directory(findsound_approach, exedir, buf, sizeof buf); + reslt = PlaySound(buf, NULL, fdwsound); #endif } @@ -185,7 +178,73 @@ void windsound_play_usersound(char *filename, int32_t volume UNUSED, int32_t idx UNUSED) { /* pline("play_usersound: %s (%d).", filename, volume); */ - (void) sndPlaySound(filename, SND_ASYNC | SND_NODEFAULT); + (void) sndPlaySound(filename, SND_ASYNC | SND_NODEFAULT | SND_FILENAME); } +static void adjust_soundargs_for_compiler( + int32_t *sefilename_flags, + DWORD *fdwsound, + char **dirbuf) +{ + /* The mingw32 resources don't seem to be able to be retrieved by the + * API PlaySound function with the SND_RESOURCE flag. Use files from + * the file system instead. */ + + enum findsound_approaches approach = +#if !defined(__MINGW32__) + findsound_embedded; +#else + findsound_soundfile; +#endif + + if (approach == findsound_soundfile) { + char *exe_dir; + + if (*sefilename_flags == sff_base_only + || *sefilename_flags == sff_baseknown_add_rest) { + exe_dir = windows_exepath(); + if (exe_dir) { + *dirbuf = exe_dir; + /* switch the sff_base_only to a sff_havedir_append_rest */ + *sefilename_flags = sff_havedir_append_rest; + *fdwsound |= SND_FILENAME; + } + } + } else { + if (*sefilename_flags == sff_base_only + || *sefilename_flags == sff_baseknown_add_rest) { + /* *sefilename_flags = sff_base_only means just obtain the + * soundeffect base name with no directory name and no file + * extension. That's because we're going to use the base + * soundeffect name as the name of a resource that's embedded + * into the .exe file, passing SND_RESOURCE flag to + * Windows API PlaySound(). + */ + *sefilename_flags = sff_base_only; + *fdwsound |= SND_RESOURCE; + } + } +} + +static void +maybe_preinsert_directory(int32_t findsound_approach, char *exedir, char *buf, size_t sz) +{ + int largest_se_basename = 35; + + /* findsound_approach = sff_havdir_append_rest means a directory name will be + * inserted into the begining of buf and the remaining parts of the + * resource/file name will be appended by + * get_sound_effect_filename(seid, buf, sizeof buf, findsound_approach) + * when it sees the sff_havedir_append_rest indicator. + */ + + if (findsound_approach == sff_havedir_append_rest) { + if (exedir) { + if (strlen(exedir) < (sz - largest_se_basename)) + Strcpy(buf, exedir); + else + *buf = '\0'; + } + } +} #endif /* SND_LIB_WINDSOUND */ diff --git a/src/sounds.c b/src/sounds.c index 2bdd97fb2..f5069d811 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -810,7 +810,7 @@ domonnoise(register struct monst* mtmp) } else { Soundeffect(se_feline_mew, 60); pline_msg = "mews."; - } + } break; } /*FALLTHRU*/ @@ -874,7 +874,7 @@ domonnoise(register struct monst* mtmp) if (!rn2(3)) { Soundeffect(se_groan, 60); pline_msg = "groans."; - } + } break; case MS_GURGLE: Soundeffect(se_gurgle, 60); @@ -2071,11 +2071,7 @@ get_sound_effect_filename( int32_t seidint, char *buf, size_t bufsz, - int32_t baseflag) /* 0 = soundir + '/' + sound + '.wav' - * 1 = sound only (no dir, no extension) ' - * 2 = dir is already in buf incl '/', - * add sound + ".wav" - */ + int32_t approach) { static const char prefix[] = "se_", suffix[] = ".wav"; size_t consumes = 0, baselen = 0, existinglen = 0; @@ -2084,7 +2080,7 @@ get_sound_effect_filename( char *cp = buf; boolean needslash = TRUE; - if (!buf || (!ourdir && baseflag == 0)) + if (!buf || (!ourdir && approach == sff_default)) return (char *) 0; if (!basenames_initialized) { @@ -2096,11 +2092,10 @@ get_sound_effect_filename( baselen = strlen(semap_basenames[seidint]); consumes = (sizeof prefix - 1) + baselen; - if (baseflag == 0) { + if (approach == sff_default) { consumes += (sizeof suffix - 1) + strlen(ourdir) + 1; /* 1 for '/' */ - } else if (baseflag == 2) { - - consumes += (sizeof suffix - 1); + } else if (approach == sff_havedir_append_rest) { + /* consumes += (sizeof suffix - 1); */ existinglen = strlen(buf); if (existinglen > 0) { cp = buf + existinglen; /* points at trailing NUL */ @@ -2108,11 +2103,11 @@ get_sound_effect_filename( if (*cp == '/' || *cp == '\\') needslash = FALSE; cp++; /* points back at trailing NUL */ - } - if (needslash) + } + if (needslash) consumes++; /* for '/' */ + consumes += existinglen; consumes += (sizeof suffix - 1); - consumes += existinglen; } consumes += 1; /* for trailing NUL */ /* existinglen could be >= bufsz if caller didn't initialize buf @@ -2121,35 +2116,37 @@ get_sound_effect_filename( return (char *) 0; #if 0 - if (baseflag == 0) { + if (approach == sff_default) { Strcpy(buf, ourdir); Strcat(buf, "/"); - } else if (baseflag == 2) { + } else if (approach == sff_havdir_append_rest) { if (needslash) Strcat(buf, "/"); - } else if (baseflag == 1) { + } else if (approach == sff_base_only) { buf[0] = '\0'; + } else { + return (char *) 0; } Strcat(buf, prefix); Strcat(buf, semap_basenames[seidint]); - if (baseflag == 0 || baseflag == 2) { + if (approach != sff_base_only) { Strcat(buf, suffix); } #else - if (baseflag == 0) { + if (approach == sff_default) { Snprintf(buf, bufsz , "%s/%s%s%s", ourdir, prefix, semap_basenames[seidint], suffix); - } else if (baseflag == 2) { - if (needslash) { + } else if (approach == sff_havedir_append_rest) { + if (needslash) { *cp = '/'; - cp++; - *cp = '\0'; - existinglen++; + cp++; + *cp = '\0'; + existinglen++; } Snprintf(cp, bufsz - (existinglen + 1) , "%s%s%s", prefix, semap_basenames[seidint], suffix); - } else if (baseflag == 1) { - Snprintf(buf, bufsz, "%s%s", prefix, semap_basenames[seidint]); + } else if (approach == sff_base_only) { + Snprintf(buf, bufsz, "%s%s", prefix, semap_basenames[seidint]); } else { return (char *) 0; } @@ -2158,4 +2155,75 @@ get_sound_effect_filename( } #endif /* SND_SOUNDEFFECTS_AUTOMAP */ +char * +base_soundname_to_filename( + char *basename, + char *buf, + size_t bufsz, + int32_t approach) +{ + static const char suffix[] = ".wav"; + size_t consumes = 0, baselen = 0, existinglen = 0; + char *cp = buf; + boolean needslash = TRUE; + + if (!buf) + return (char *) 0; + + baselen = strlen(basename); + consumes = baselen; + + if (approach == sff_havedir_append_rest) { + /* consumes += (sizeof suffix - 1); */ + existinglen = strlen(buf); + if (existinglen > 0) { + cp = buf + existinglen; /* points at trailing NUL */ + cp--; /* points at last character */ + if (*cp == '/' || *cp == '\\') + needslash = FALSE; + cp++; /* points back at trailing NUL */ + } + if (needslash) + consumes++; /* for '/' */ + consumes += existinglen; + consumes += (sizeof suffix - 1); + } + consumes += 1; /* for trailing NUL */ + /* existinglen could be >= bufsz if caller didn't initialize buf + * to properly include a trailing NUL */ + if (baselen <= 0 || consumes > bufsz || existinglen >= bufsz) + return (char *) 0; + +#if 0 + if (approach == sff_havedir_append_rest) { + if (needslash) + Strcat(buf, "/"); + } else if (approach == sff_base_only) { + buf[0] = '\0'; + } else { + return (char *) 0; + } + Strcat(buf, basename); + if (approach != sff_base_only) { + Strcat(buf, suffix); + } +#else + if (approach == sff_havedir_append_rest) { + if (needslash) { + *cp = '/'; + cp++; + *cp = '\0'; + existinglen++; + } + Snprintf(cp, bufsz - (existinglen + 1) , "%s%s", + basename, suffix); + } else if (approach == sff_base_only) { + Snprintf(buf, bufsz, "%s", basename); + } else { + return (char *) 0; + } +#endif + return buf; +} + /*sounds.c*/ diff --git a/sys/windows/windmain.c b/sys/windows/windmain.c index 1b1e3b76b..93f9a54b4 100644 --- a/sys/windows/windmain.c +++ b/sys/windows/windmain.c @@ -1083,9 +1083,8 @@ get_executable_path(void) return path_buffer; } -#ifdef __MINGW32__ char * -mingw_exepath(void) +windows_exepath(void) { char *p = (char *) 0; @@ -1093,7 +1092,6 @@ mingw_exepath(void) p = path_buffer; return p; } -#endif char * translate_path_variables(const char* str, char* buf)