]> granicus.if.org Git - nethack/commitdiff
further work on soundlib support code
authornhmall <nhmall@nethack.org>
Wed, 1 Feb 2023 03:19:29 +0000 (22:19 -0500)
committernhmall <nhmall@nethack.org>
Wed, 1 Feb 2023 03:19:29 +0000 (22:19 -0500)
move some inline code into functions
replace some magic numbers

The mingw code is not tested yet.

include/extern.h
include/sndprocs.h
include/windconf.h
sound/macsound/macsound.m
sound/windsound/windsound.c
src/sounds.c
sys/windows/windmain.c

index 33c8da31adf069032dd28f6e23e4bec610dc9b43..e91424b5da67995fd019b9c17ea6d99a07b07aee 100644 (file)
@@ -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 ### */
index ce644f88ad200abcbf4d513feb311d2cdb8ce2ae..69f3ee49a7e9fd96f3ddb8ecc0d7d9b73effffc8 100755 (executable)
@@ -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 */
index 691a7359ea2c7d7a9196c762d34a099600c225d7..9557cedeac42c9b3840cac77db3547f4ad11e22c 100644 (file)
@@ -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
index 4eb91d99e634cf53b6fc66c87ef2574f992504c5..dd98f04776ba285d5c37a92c49b7fa8666dbbde8 100644 (file)
@@ -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 */
-
index 580e21235b829f0f2c3b1330fbbe548f8caca9f6..b39680e633426ff9e414034331120aacbea378f8 100644 (file)
@@ -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 */
index 2bdd97fb29868905663a759a419368ebc5a4b8e9..f5069d8117471d2ae6454a25ccd2586fb0809d0a 100644 (file)
@@ -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*/
index 1b1e3b76bc158fc9b05c0c521a9082c2532f0b35..93f9a54b4b5da5a44b157f82774cce45a5a7c148 100644 (file)
@@ -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)