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