shithub: zelda3

Download patch

ref: b1b1871fb7888dbe050e4a120b82f9f6b701547c
parent: ca656497b4a8b27ff3d766b966e834b39cfc9078
author: Snesrev <snesrev@protonmail.com>
date: Mon Oct 17 12:19:28 EDT 2022

Add MSUVolume (fixes #153)

--- a/audio.c
+++ b/audio.c
@@ -128,9 +128,11 @@
   return rv;
 }
 
-static const uint8 kVolumeTransitionTarget[3] = { 0, 64, 255};
-static const uint8 kVolumeTransitionStep[3] = { 7, 3, 3};
-static float kVolumeTransitionStepFloat;
+static const uint8 kVolumeTransitionTarget[4] = { 0, 64, 255, 255};
+static const uint8 kVolumeTransitionStep[4] = { 7, 3, 3, 24};
+// These are precomputed in the config parse
+static float kVolumeTransitionStepFloat[4];
+static float kVolumeTransitionTargetFloat[4];
 
 void ZeldaPlayMsuAudioTrack(uint8 music_ctrl) {
   MsuPlayer *mp = &g_msu_player;
@@ -143,8 +145,8 @@
   if ((music_ctrl & 0xf0) != 0xf0)
     MsuPlayer_Open(mp, music_ctrl, false);
   else if (music_ctrl >= 0xf1 && music_ctrl <= 0xf3) {
-    mp->volume_target = kVolumeTransitionTarget[music_ctrl - 0xf1] * (1.0f / 255);
-    mp->volume_step = kVolumeTransitionStepFloat * kVolumeTransitionStep[music_ctrl - 0xf1];
+    mp->volume_target = kVolumeTransitionTargetFloat[music_ctrl - 0xf1];
+    mp->volume_step = kVolumeTransitionStepFloat[music_ctrl - 0xf1];
   }
 
   if (mp->state == 0) {
@@ -183,8 +185,8 @@
     memcpy(&resume, msu_resume_info, sizeof(mp->resume_info));
   }
 
-  mp->volume_target = 1.0f;
-  mp->volume_step = kVolumeTransitionStepFloat * 16;
+  mp->volume_target = kVolumeTransitionTargetFloat[3];
+  mp->volume_step = kVolumeTransitionStepFloat[3];
 
   mp->state = kMsuState_Idle;
   MsuPlayer_CloseFile(mp);
@@ -192,6 +194,7 @@
     return;
   char fname[256], buf[8];
   snprintf(fname, sizeof(fname), "%s%d.%s", g_config.msu_path ? g_config.msu_path : "", actual_track, mp->enabled & kMsuEnabled_Opuz ? "opuz" : "pcm");
+  printf("Loading MSU %s\n", fname);
   mp->f = fopen(fname, "rb");
   if (mp->f == NULL)
     goto READ_ERROR;
@@ -480,7 +483,8 @@
   MsuPlayer *mp = &g_msu_player;
   if (mp->enabled) {
     mp->volume = 0.0;
-    MsuPlayer_Open(mp, (music_unk1 == 0xf1) ? mp->resume_info.orig_track : music_unk1, true);
+    MsuPlayer_Open(mp, (music_unk1 == 0xf1) ? ((MsuPlayerResumeInfo*)msu_resume_info)->orig_track : 
+                   music_unk1, true);
 
     // If resuming in the middle of a transition, then override
     // the volume with that of the transition.
@@ -487,9 +491,10 @@
     if (last_music_control >= 0xf1 && last_music_control <= 0xf3) {
       uint8 target = kVolumeTransitionTarget[last_music_control - 0xf1];
       if (target != msu_volume) {
-        mp->volume = msu_volume * (1.0f / 255);
-        mp->volume_target = target * (1.0f / 255);
-        mp->volume_step = kVolumeTransitionStepFloat * kVolumeTransitionStep[last_music_control - 0xf1];
+        float f = kVolumeTransitionTargetFloat[3] * (1.0f / 255);
+        mp->volume = msu_volume * f;
+        mp->volume_target = target * f;
+        mp->volume_step = kVolumeTransitionStepFloat[last_music_control - 0xf1];
       }
     }
 
@@ -522,7 +527,12 @@
       fprintf(stderr, "Warning: MSU requires: AudioFreq = 44100\n");
   }
 
-  kVolumeTransitionStepFloat = (60 / 256.0f) / g_config.audio_freq;
+  float volscale = g_config.msuvolume * (1.0f / 255 / 100);
+  float stepscale = g_config.msuvolume * (60.0f / 256 / 100) / g_config.audio_freq;
+  for (size_t i = 0; i != countof(kVolumeTransitionStepFloat); i++) {
+    kVolumeTransitionStepFloat[i] = kVolumeTransitionStep[i] * stepscale;
+    kVolumeTransitionTargetFloat[i] = kVolumeTransitionTarget[i] * volscale;
+  }
 }
 
 void LoadSongBank(const uint8 *p) {  // 808888
--- a/config.c
+++ b/config.c
@@ -273,6 +273,9 @@
     } else if (StringEqualsNoCase(key, "MSUPath")) {
       g_config.msu_path = value;
       return true;
+    } else if (StringEqualsNoCase(key, "MSUVolume")) {
+      g_config.msuvolume = atoi(value);
+      return true;
     } else if (StringEqualsNoCase(key, "ResumeMSU")) {
       return ParseBool(value, &g_config.resume_msu);
     }
@@ -382,6 +385,8 @@
 }
 
 void ParseConfigFile(const char *filename) {
+  g_config.msuvolume = 100;  // default msu volume, 100%
+
   if (filename != NULL || !ParseOneConfigFile("zelda3.user.ini", 0)) {
     if (filename == NULL)
       filename = "zelda3.ini";
--- a/config.h
+++ b/config.h
@@ -64,6 +64,7 @@
   uint8 enable_msu;
   bool resume_msu;
   bool disable_frame_delay;
+  uint8 msuvolume;
   uint32 features0;
 
   const char *link_graphics;
--- a/zelda3.ini
+++ b/zelda3.ini
@@ -80,6 +80,8 @@
 # an overworld area. (Only remembers one area)
 ResumeMSU = 1
 
+# Change the volume of the MSU playback, a value between 0-100
+MSUVolume = 100%
 
 [Features]
 # Item switch on L/R. Also allows reordering of items in inventory by pressing Y+direction