shithub: zelda3

Download patch

ref: ac2d1210a30b8302c48a675124cc0c6b606f7f75
parent: 95e3a919dd9490101b9f2b708ce63225c7420845
author: Keaton Greve <keatongreve@google.com>
date: Mon Oct 3 03:43:28 EDT 2022

add basic support for in-application volume adjustment (OS mixer or SDL mixer, depending on platform) (#131)


--- a/config.c
+++ b/config.c
@@ -56,7 +56,7 @@
   M(Controls), M(Load), M(Save), M(Replay), M(LoadRef), M(ReplayRef),
   S(CheatLife), S(CheatKeys), S(CheatEquipment), S(CheatWalkThroughWalls),
   S(ClearKeyLog), S(StopReplay), S(Fullscreen), S(Reset),
-  S(Pause), S(PauseDimmed), S(Turbo), S(ReplayTurbo), S(WindowBigger), S(WindowSmaller), S(DisplayPerf), S(ToggleRenderer),
+  S(Pause), S(PauseDimmed), S(Turbo), S(ReplayTurbo), S(WindowBigger), S(WindowSmaller), S(VolumeUp), S(VolumeDown), S(DisplayPerf), S(ToggleRenderer),
 };
 #undef S
 #undef M
--- a/config.h
+++ b/config.h
@@ -31,6 +31,8 @@
   kKeys_WindowSmaller,
   kKeys_DisplayPerf,
   kKeys_ToggleRenderer,
+  kKeys_VolumeUp,
+  kKeys_VolumeDown,
   kKeys_Total,
 };
 
--- a/main.c
+++ b/main.c
@@ -6,6 +6,7 @@
 #include <SDL.h>
 #ifdef _WIN32
 #include <direct.h>
+#define SYSTEM_VOLUME_MIXER_AVAILABLE
 #else
 #include <sys/stat.h>
 #include <sys/types.h>
@@ -12,6 +13,13 @@
 #include <unistd.h>
 #endif
 
+#ifdef SYSTEM_VOLUME_MIXER_AVAILABLE
+#define VOLUME_INCREMENT 5
+#include "platform/win32/volume_control.h"
+#else
+#define VOLUME_INCREMENT (SDL_MIX_MAXVOLUME >> 4)
+#endif
+
 #include "snes/ppu.h"
 
 #include "types.h"
@@ -35,6 +43,7 @@
 static void HandleGamepadInput(int button, bool pressed);
 static void HandleGamepadAxisInput(int gamepad_id, int axis, int value);
 static void OpenOneGamepad(int i);
+static void HandleVolumeAdjustment(int volume_adjustment);
 static void LoadAssets();
 
 enum {
@@ -60,6 +69,7 @@
 static int g_ppu_render_flags = 0;
 static bool g_run_without_emu = false;
 static int g_snes_width, g_snes_height;
+static int g_sdl_audio_mixer_volume = SDL_MIX_MAXVOLUME;
 
 void NORETURN Die(const char *error) {
   fprintf(stderr, "Error: %s\n", error);
@@ -178,7 +188,13 @@
       g_audiobuffer_end = g_audiobuffer + g_frames_per_block * g_audio_channels * sizeof(int16);
     }
     int n = IntMin(len, g_audiobuffer_end - g_audiobuffer_cur);
+#ifdef SYSTEM_VOLUME_MIXER_AVAILABLE
     memcpy(stream, g_audiobuffer_cur, n);
+#else
+    // Ensure destination audio stream is empty/silence.
+    SDL_memset(stream, 0, n);
+    SDL_MixAudioFormat(stream, g_audiobuffer_cur, AUDIO_S16, n, g_sdl_audio_mixer_volume);
+#endif
     g_audiobuffer_cur += n;
     stream += n;
     len -= n;
@@ -577,6 +593,12 @@
     case kKeys_WindowSmaller: ChangeWindowScale(-1); break;
     case kKeys_DisplayPerf: g_display_perf ^= 1; break;
     case kKeys_ToggleRenderer: g_ppu_render_flags ^= kPpuRenderFlags_NewRenderer; break;
+    case kKeys_VolumeUp:
+      HandleVolumeAdjustment(VOLUME_INCREMENT);
+      break;
+    case kKeys_VolumeDown:
+      HandleVolumeAdjustment(-VOLUME_INCREMENT);
+      break;
     default: assert(0);
     }
   }
@@ -611,6 +633,18 @@
   case SDL_CONTROLLER_BUTTON_LEFTSHOULDER: SetButtonState(10, pressed); break;
   case SDL_CONTROLLER_BUTTON_RIGHTSHOULDER: SetButtonState(11, pressed); break;
   }
+}
+
+static void HandleVolumeAdjustment(int volume_adjustment) {
+#ifdef SYSTEM_VOLUME_MIXER_AVAILABLE
+  int current_volume = GetApplicationVolume();
+  int new_volume = IntMin(IntMax(0, current_volume + volume_adjustment), 100);
+  SetApplicationVolume(new_volume);
+  printf("[System Volume]=%i\n", new_volume);
+#else
+  g_sdl_audio_mixer_volume = IntMin(IntMax(0, g_sdl_audio_mixer_volume + volume_adjustment), SDL_MIX_MAXVOLUME);
+  printf("[SDL mixer volume]=%i\n", g_sdl_audio_mixer_volume);
+#endif
 }
 
 // Approximates atan2(y, x) normalized to the [0,4) range
--- a/platform/win32/volume_control.c
+++ b/platform/win32/volume_control.c
@@ -22,6 +22,16 @@
     com_initialized = SUCCEEDED(CoInitialize(NULL));
 }
 
+int GetApplicationVolume() {
+  ISimpleAudioVolume *simple_audio_volume = GetSimpleAudioVolume();
+  if (!simple_audio_volume)
+    return false;
+  float volume_level = -1;
+  HRESULT result = ISimpleAudioVolume_GetMasterVolume(simple_audio_volume, &volume_level);
+  ISimpleAudioVolume_Release(simple_audio_volume);
+  return (int)(volume_level * 100);
+}
+
 bool SetApplicationVolume(int volume_level) {
   ISimpleAudioVolume *simple_audio_volume = GetSimpleAudioVolume();
   if (!simple_audio_volume)
--- a/platform/win32/volume_control.h
+++ b/platform/win32/volume_control.h
@@ -3,6 +3,7 @@
 
 #include <stdbool.h>
 
+int GetApplicationVolume();
 bool SetApplicationVolume(int volume_level);
 bool SetApplicationMuted(bool muted);
 
--- a/zelda3.ini
+++ b/zelda3.ini
@@ -118,6 +118,9 @@
 WindowBigger = Ctrl+Up
 WindowSmaller = Ctrl+Down
 
+VolumeUp = Shift+=
+VolumeDown = Shift+-
+
 Load =      F1,     F2,     F3,     F4,     F5,     F6,     F7,     F8,     F9,     F10
 Save = Shift+F1,Shift+F2,Shift+F3,Shift+F4,Shift+F5,Shift+F6,Shift+F7,Shift+F8,Shift+F9,Shift+F10
 Replay= Ctrl+F1,Ctrl+F2,Ctrl+F3,Ctrl+F4,Ctrl+F5,Ctrl+F6,Ctrl+F7,Ctrl+F8,Ctrl+F9,Ctrl+F10