From f453201fa149d3e2a85f0b466b1c67c6c90d54e0 Mon Sep 17 00:00:00 2001 From: Dwedit Date: Fri, 30 Mar 2018 22:35:35 -0500 Subject: Add support for Audio/Video Disable flags Add support for Hard Disable Audio Fix frame discarding causing infinite loops Fix MSVC building --- libretro.c | 20 ++++++++++++++++++++ libretro.h | 41 +++++++++++++++++++++++++++++++++++++++++ source/apu_blargg.c | 8 +++++++- source/gfx.c | 4 ++-- source/memmap.c | 5 +++++ source/snes9x.h | 1 + 6 files changed, 76 insertions(+), 3 deletions(-) diff --git a/libretro.c b/libretro.c index 47729b0..43dad13 100644 --- a/libretro.c +++ b/libretro.c @@ -428,6 +428,8 @@ static int32_t samples_to_play = 0; void retro_run(void) { bool updated = false; + int result; + bool okay; #ifndef USE_BLARGG_APU static int16_t audio_buf[2048]; #endif @@ -440,6 +442,24 @@ void retro_run(void) IPPU.RenderThisFrame = false; #endif + result = -1; + okay = environ_cb(RETRO_ENVIRONMENT_GET_AUDIO_VIDEO_ENABLE, &result); + if (okay) + { + bool audioEnabled = 0 != (result & 2); + bool videoEnabled = 0 != (result & 1); + bool hardDisableAudio = 0 != (result & 8); + IPPU.RenderThisFrame = videoEnabled; + S9xSetSoundMute(!audioEnabled || hardDisableAudio); + Settings.HardDisableAudio = hardDisableAudio; + } + else + { + IPPU.RenderThisFrame = true;; + S9xSetSoundMute(false); + Settings.HardDisableAudio = false; + } + poll_cb(); RETRO_PERFORMANCE_INIT(S9xMainLoop_func); diff --git a/libretro.h b/libretro.h index 469b86a..ed1902b 100644 --- a/libretro.h +++ b/libretro.h @@ -901,6 +901,47 @@ enum retro_mod * writeable (and readable). */ +#define RETRO_ENVIRONMENT_GET_AUDIO_VIDEO_ENABLE (47 | RETRO_ENVIRONMENT_EXPERIMENTAL) + /* int * -- + * Tells the core if the frontend wants audio or video. + * If disabled, the frontend will discard the audio or video, + * so the core may decide to skip generating a frame or generating audio. + * This is mainly used for increasing performance. + * Bit 0 (value 1): Enable Video + * Bit 1 (value 2): Enable Audio + * Bit 2 (value 4): Use Fast Savestates. + * Bit 3 (value 8): Hard Disable Audio + * Other bits are reserved for future use and will default to zero. + * If video is disabled: + * * The frontend wants the core to not generate any video, + * including presenting frames via hardware acceleration. + * * The frontend's video frame callback will do nothing. + * * After running the frame, the video output of the next frame should be + * no different than if video was enabled, and saving and loading state + * should have no issues. + * If audio is disabled: + * * The frontend wants the core to not generate any audio. + * * The frontend's audio callbacks will do nothing. + * * After running the frame, the audio output of the next frame should be + * no different than if audio was enabled, and saving and loading state + * should have no issues. + * Fast Savestates: + * * Guaranteed to be created by the same binary that will load them. + * * Will not be written to or read from the disk. + * * Suggest that the core assumes loading state will succeed. + * * Suggest that the core updates its memory buffers in-place if possible. + * * Suggest that the core skips clearing memory. + * * Suggest that the core skips resetting the system. + * * Suggest that the core may skip validation steps. + * Hard Disable Audio: + * * Used for a secondary core when running ahead. + * * Indicates that the frontend will never need audio from the core. + * * Suggests that the core may stop synthesizing audio, but this should not + * compromise emulation accuracy. + * * Audio output for the next frame does not matter, and the frontend will + * never need an accurate audio state in the future. + * * State will never be saved when using Hard Disable Audio. + */ enum retro_hw_render_interface_type { RETRO_HW_RENDER_INTERFACE_VULKAN = 0, diff --git a/source/apu_blargg.c b/source/apu_blargg.c index 49f5491..2976580 100644 --- a/source/apu_blargg.c +++ b/source/apu_blargg.c @@ -761,7 +761,8 @@ V(V9_V6_V3,2) -> V(V9,2) V(V6,3) V(V3,4) */ static void dsp_run( int32_t clocks_remain ) { int32_t phase; - + if (Settings.HardDisableAudio) + return; phase = dsp_m.phase; dsp_m.phase = (phase + clocks_remain) & 31; @@ -3259,6 +3260,11 @@ static int8_t const reg_times_ [256] = 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, }; +void S9xSetSoundMute(bool mute) +{ + Settings.Mute = mute; +} + bool S9xInitAPU() { int32_t i; diff --git a/source/gfx.c b/source/gfx.c index 1b9928d..a43ef35 100644 --- a/source/gfx.c +++ b/source/gfx.c @@ -478,10 +478,10 @@ void S9xEndScreenRefresh(void) GFX.Pitch = GFX.Pitch2 = GFX.RealPitch; GFX.PPL = GFX.PPLx2 >> 1; + } #ifdef LAGFIX - finishedFrame = true; + finishedFrame = true; #endif - } S9xApplyCheats(); diff --git a/source/memmap.c b/source/memmap.c index d5c29b1..4f76fc8 100644 --- a/source/memmap.c +++ b/source/memmap.c @@ -24,6 +24,11 @@ #include #endif +#ifdef _MSC_VER +/* Necessary to build on MSVC */ +#define strnicmp _strnicmp +#endif + #define MAP_HIROM_SRAM_OR_NONE (Memory.SRAMSize == 0 ? (uint8_t*) MAP_NONE : (uint8_t*) MAP_HIROM_SRAM) #define MAP_LOROM_SRAM_OR_NONE (Memory.SRAMSize == 0 ? (uint8_t*) MAP_NONE : (uint8_t*) MAP_LOROM_SRAM) #define MAP_RONLY_SRAM_OR_NONE (Memory.SRAMSize == 0 ? (uint8_t*) MAP_NONE : (uint8_t*) MAP_RONLY_SRAM) diff --git a/source/snes9x.h b/source/snes9x.h index 11dc1ff..ad410e1 100644 --- a/source/snes9x.h +++ b/source/snes9x.h @@ -214,6 +214,7 @@ typedef struct bool Justifier; bool SecondJustifier; int8_t SETA; + bool HardDisableAudio; } SSettings; extern SSettings Settings; -- cgit v1.2.3