foxygit / doom Log in
commit 0cd984759aa3d21b74c596cf930b6002dd425618
Author:     Simon Howard <fraggle@gmail.com>
AuthorDate: Sun Mar 3 02:01:04 2013 +0000
Commit:     Simon Howard <fraggle@gmail.com>
CommitDate: Sun Mar 3 02:01:04 2013 +0000

    Add configuration file variable to specify path to a Timidity config
    file.

    Subversion-branch: /branches/v2-branch
    Subversion-revision: 2564
---
 src/i_sdlmusic.c  | 95 ++++++++++++++++++++++++++++++++++++++++++++++++-------
 src/i_sound.c     | 17 ++++++++++
 src/m_config.c    |  9 ++++++
 src/setup/sound.c |  3 ++
 4 files changed, 112 insertions(+), 12 deletions(-)

diff --git a/src/i_sdlmusic.c b/src/i_sdlmusic.c
index 0418e025..12167665 100644
--- a/src/i_sdlmusic.c
+++ b/src/i_sdlmusic.c
@@ -53,10 +53,73 @@ static boolean sdl_was_initialized = false;
 static boolean musicpaused = false;
 static int current_music_volume;

+char *timidity_cfg_path = "";
+static char *temp_timidity_cfg = NULL;
+
+// If the temp_timidity_cfg config variable is set, generate a "wrapper"
+// config file for Timidity to point to the actual config file. This
+// is needed to inject a "dir" command so that the patches are read
+// relative to the actual config file.
+
+void I_InitTimidityConfig(void)
+{
+    char *env_string;
+    char *p, *path;
+    FILE *fstream;
+
+    temp_timidity_cfg = NULL;
+
+    if (!strcmp(timidity_cfg_path, ""))
+    {
+        return;
+    }
+
+    temp_timidity_cfg = M_TempFile("timidity.cfg");
+    fstream = fopen(temp_timidity_cfg, "w");
+
+    if (fstream == NULL)
+    {
+        free(temp_timidity_cfg);
+        temp_timidity_cfg = NULL;
+        return;
+    }
+
+    p = strrchr(timidity_cfg_path, DIR_SEPARATOR);
+    if (p != NULL)
+    {
+        path = strdup(timidity_cfg_path);
+        path[p - timidity_cfg_path] = '\0';
+        fprintf(fstream, "dir %s\n", path);
+        free(path);
+    }
+
+    fprintf(fstream, "source %s\n", timidity_cfg_path);
+    fclose(fstream);
+
+    // Set the TIMIDITY_CFG environment variable to point to the temporary
+    // config file.
+
+    env_string = malloc(strlen(temp_timidity_cfg) + 15);
+    sprintf(env_string, "TIMIDITY_CFG=%s", temp_timidity_cfg);
+    putenv(env_string);
+    free(env_string);
+}
+
+// Remove the temporary config file generated by I_InitTimidityConfig().
+
+static void RemoveTimidityConfig(void)
+{
+    if (temp_timidity_cfg != NULL)
+    {
+        remove(temp_timidity_cfg);
+        free(temp_timidity_cfg);
+    }
+}
+
 // Shutdown music

 static void I_SDL_ShutdownMusic(void)
-{
+{
     if (music_initialized)
     {
         Mix_HaltMusic();
@@ -107,29 +170,37 @@ static boolean I_SDL_InitMusic(void)
     // If SDL_mixer is not initialized, we have to initialize it
     // and have the responsibility to shut it down later on.

-    if (!SDLIsInitialized())
+    if (SDLIsInitialized())
+    {
+        music_initialized = true;
+    }
+    else
     {
         if (SDL_Init(SDL_INIT_AUDIO) < 0)
         {
             fprintf(stderr, "Unable to set up sound.\n");
-            return false;
         }
-
-        if (Mix_OpenAudio(snd_samplerate, AUDIO_S16SYS, 2, 1024) < 0)
+        else if (Mix_OpenAudio(snd_samplerate, AUDIO_S16SYS, 2, 1024) < 0)
         {
-            fprintf(stderr, "Error initializing SDL_mixer: %s\n", Mix_GetError());
+            fprintf(stderr, "Error initializing SDL_mixer: %s\n",
+                    Mix_GetError());
             SDL_QuitSubSystem(SDL_INIT_AUDIO);
-            return false;
         }
+        else
+        {
+            SDL_PauseAudio(0);

-        SDL_PauseAudio(0);
-
-        sdl_was_initialized = true;
+            sdl_was_initialized = true;
+            music_initialized = true;
+        }
     }

-    music_initialized = true;
+    // Once initialization is complete, the temporary Timidity config
+    // file can be removed.
+
+    RemoveTimidityConfig();

-    return true;
+    return music_initialized;
 }

 //
diff --git a/src/i_sound.c b/src/i_sound.c
index 2e9e71db..198b233e 100644
--- a/src/i_sound.c
+++ b/src/i_sound.c
@@ -56,6 +56,7 @@ int snd_sfxdevice = SNDDEVICE_SB;

 // Sound modules

+extern void I_InitTimidityConfig(void);
 extern sound_module_t sound_sdl_module;
 extern sound_module_t sound_pcsound_module;
 extern music_module_t music_sdl_module;
@@ -65,6 +66,10 @@ extern music_module_t music_opl_module;

 extern int opl_io_port;

+// For native music module:
+
+extern char *timidity_cfg_path;
+
 // DOS-specific options: These are unused but should be maintained
 // so that the config file can be shared between chocolate
 // doom and doom.exe
@@ -209,6 +214,15 @@ void I_InitSound(boolean use_sfx_prefix)

     if (!nosound && !screensaver_mode)
     {
+        // This is kind of a hack. If native MIDI is enabled, set up
+        // the TIMIDITY_CFG environment variable here before SDL_mixer
+        // is opened.
+
+        if (!nomusic && snd_musicdevice == SNDDEVICE_GENMIDI)
+        {
+            I_InitTimidityConfig();
+        }
+
         if (!nosfx)
         {
             InitSfxModule(use_sfx_prefix);
@@ -419,6 +433,9 @@ void I_BindSoundVariables(void)
     M_BindVariable("snd_samplerate",    &snd_samplerate);
     M_BindVariable("snd_cachesize",     &snd_cachesize);
     M_BindVariable("opl_io_port",       &opl_io_port);
+
+    M_BindVariable("timidity_cfg_path", &timidity_cfg_path);
+
 #ifdef FEATURE_SOUND
     M_BindVariable("use_libsamplerate", &use_libsamplerate);
 #endif
diff --git a/src/m_config.c b/src/m_config.c
index 3ebc3812..e2afe6cc 100644
--- a/src/m_config.c
+++ b/src/m_config.c
@@ -906,6 +906,15 @@ static default_t extra_defaults_list[] =

     CONFIG_VARIABLE_INT(use_libsamplerate),

+    //!
+    // Full path to a Timidity configuration file to use for MIDI
+    // playback. The file will be evaluated from the directory where
+    // it is evaluated, so there is no need to add "dir" commands
+    // into it.
+    //
+
+    CONFIG_VARIABLE_STRING(timidity_cfg_path),
+
 #endif

     //!
diff --git a/src/setup/sound.c b/src/setup/sound.c
index 1ed73cc6..4a9b80b3 100644
--- a/src/setup/sound.c
+++ b/src/setup/sound.c
@@ -78,6 +78,8 @@ static int voiceVolume = 15;
 static int show_talk = 0;
 static int use_libsamplerate = 0;

+static char *timidity_cfg_path = "";
+
 // DOS specific variables: these are unused but should be maintained
 // so that the config file can be shared between chocolate
 // doom and doom.exe
@@ -251,6 +253,7 @@ void BindSoundVariables(void)
     M_BindVariable("music_volume",        &musicVolume);
     M_BindVariable("snd_samplerate",      &snd_samplerate);
     M_BindVariable("use_libsamplerate",   &use_libsamplerate);
+    M_BindVariable("timidity_cfg_path",   &timidity_cfg_path);

     M_BindVariable("snd_sbport",          &snd_sbport);
     M_BindVariable("snd_sbirq",           &snd_sbirq);