libretro / beetle-psx-libretro

Standalone port/fork of Mednafen PSX to the Libretro API.
GNU General Public License v2.0
310 stars 131 forks source link

[Feature Request] adjustable CDDA and PSG volumes core options #499

Open eadmaster opened 5 years ago

eadmaster commented 5 years ago

I'd like to suggest adding core options for configurable CDDA and PSG volumes, like the Beetle PCE fast core has.

Basically i'd like to boost the CDDA volume over the PSG, since the second it is often too high on most games.

AFAIK no PSX emulator currently has this feature including the vanilla Mednafen core.

rz5 commented 4 years ago

Because of the recent Mednafen changelog notes concerning a bug fix concerning SPU CD volume, I got some names of variables I could check out hack this feature request into beetle-psx.

I've arrived at something that seems to be working in Tony Hawk's Pro Skater 2. When in-game, the new core option can boost and reduce the song being played, much like the in-game music volume control.

Here's a diff against the current state of the master branch:

diff --git a/beetle_psx_globals.c b/beetle_psx_globals.c
index 873ef80..5a866a3 100644
--- a/beetle_psx_globals.c
+++ b/beetle_psx_globals.c
@@ -9,3 +9,4 @@ int filter_mode;
 bool opaque_check;
 bool semitrans_check;
 bool crop_overscan = false;
+float cd_volume = 1.0;
diff --git a/beetle_psx_globals.h b/beetle_psx_globals.h
index 78b2f7c..88b968c 100644
--- a/beetle_psx_globals.h
+++ b/beetle_psx_globals.h
@@ -22,6 +22,7 @@ extern int filter_mode;
 extern bool opaque_check;
 extern bool semitrans_check;
 extern bool crop_overscan;
+extern float cd_volume;

 #ifdef __cplusplus
 }
diff --git a/libretro.cpp b/libretro.cpp
index 955e872..4176435 100644
--- a/libretro.cpp
+++ b/libretro.cpp
@@ -2669,6 +2669,13 @@ static void check_variables(bool startup)

    extern void PSXDitherApply(bool);

+   var.key = BEETLE_OPT(cd_volume);
+   if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
+   {
+      float new_cd_volume = atof(var.value);
+      cd_volume = new_cd_volume;
+   }
+
 #ifndef EMSCRIPTEN
    var.key = BEETLE_OPT(cd_access_method);
    if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
diff --git a/libretro_core_options.h b/libretro_core_options.h
index d6240ea..6ad73d7 100644
--- a/libretro_core_options.h
+++ b/libretro_core_options.h
@@ -51,6 +51,29 @@ extern "C" {
  *   frontend language definition */

 struct retro_core_option_definition option_defs_us[] = {
+
+   {
+      BEETLE_OPT(cd_volume),
+      "CD Volume",
+      "Changes CD volume",
+      {
+         { "1.00", NULL },
+         { "1.15", NULL },
+         { "1.30", NULL },
+         { "1.45", NULL },
+         { "1.60", NULL },
+         { "1.75", NULL },
+         { "2.00", NULL },
+         { "0.00", NULL },
+         { "0.15", NULL },
+         { "0.30", NULL },
+         { "0.45", NULL },
+         { "0.60", NULL },
+         { "0.75", NULL },
+         { NULL, NULL },
+      },
+      "1.00"
+   },
 #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) || defined(HAVE_VULKAN)
    {
       BEETLE_OPT(renderer),
diff --git a/mednafen/psx/spu.cpp b/mednafen/psx/spu.cpp
index 6744fcb..ec239b1 100644
--- a/mednafen/psx/spu.cpp
+++ b/mednafen/psx/spu.cpp
@@ -69,8 +69,10 @@
 #include "psx.h"
 #include "cdc.h"
 #include "spu.h"
+#include "beetle_psx_globals.h"
 #include <libretro.h>

+
 #include "../state_helpers.h"

 uint32_t IntermediateBufferPos;
@@ -1008,7 +1010,7 @@ int32 PS_SPU::UpdateFromCDC(int32 clocks)
          WriteSPURAM(CWA | 0x200, cda_raw[1]);

          for(unsigned i = 0; i < 2; i++)
-            cdav[i] = (cda_raw[i] * CDVol[i]) >> 15;
+            cdav[i] = (cda_raw[i] * (int32_t)(CDVol[i] * cd_volume)) >> 15;

          if(SPUControl & 0x0001)
          {

And if you're on Windows, here's a x64 build to try the feature out: mednafen_psx_hw_libretro.zip