diff --git a/Libretro/LibretroRenderer.h b/Libretro/LibretroRenderer.h index 57c226ba..dfbccff6 100644 --- a/Libretro/LibretroRenderer.h +++ b/Libretro/LibretroRenderer.h @@ -2,13 +2,19 @@ #include "stdafx.h" #include "../Core/IRenderingDevice.h" #include "../Core/VideoRenderer.h" +#include "../Core/EmulationSettings.h" +#include "../Core/Console.h" +#include "../Utilities/nes_ntsc.h" #include "libretro.h" class LibretroRenderer : public IRenderingDevice { private: retro_video_refresh_t _sendFrame = nullptr; + retro_environment_t _retroEnv = nullptr; bool _skipMode = false; + int32_t _previousHeight = -1; + int32_t _previousWidth = -1; public: LibretroRenderer() @@ -25,13 +31,51 @@ public: virtual void UpdateFrame(void *frameBuffer, uint32_t width, uint32_t height) override { if(!_skipMode && _sendFrame) { + //Use Blargg's NTSC filter's max size as a minimum resolution, to prevent changing resolution too often + int32_t newWidth = std::max(width, NES_NTSC_OUT_WIDTH(256)); + int32_t newHeight = std::max(height, 480); + if(_previousWidth != newWidth || _previousHeight != newHeight) { + //Resolution change is needed + retro_system_av_info avInfo = {}; + GetSystemAudioVideoInfo(avInfo, newWidth, newHeight); + _retroEnv(RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO, &avInfo); + + _previousWidth = newWidth; + _previousHeight = newHeight; + } + _sendFrame(frameBuffer, width, height, sizeof(uint32_t) * width); } } + + static void GetSystemAudioVideoInfo(retro_system_av_info &info, int32_t newHeight, int32_t newWidth) + { + info.timing.fps = Console::GetModel() == NesModel::NTSC ? 60.098811862348404716732985230828 : 50.006977968268290848936010226333; + info.timing.sample_rate = 48000; - void SetSendFrame(retro_video_refresh_t sendFrame) + float ratio = (float)EmulationSettings::GetAspectRatio(); + if(ratio == 0.0f) { + ratio = 1.0f; + } + ratio *= (float)EmulationSettings::GetOverscanDimensions().GetScreenWidth() / EmulationSettings::GetOverscanDimensions().GetScreenHeight() / 256 * 240; + + if(EmulationSettings::GetScreenRotation() % 180) { + info.geometry.aspect_ratio = ratio == 0.0f ? 0.0f : 1.0f / ratio; + } else { + info.geometry.aspect_ratio = ratio; + } + + info.geometry.base_width = EmulationSettings::GetOverscanDimensions().GetScreenWidth(); + info.geometry.base_height = EmulationSettings::GetOverscanDimensions().GetScreenHeight(); + + info.geometry.max_width = newHeight; + info.geometry.max_height = newWidth; + } + + void SetCallbacks(retro_video_refresh_t sendFrame, retro_environment_t retroEnv) { _sendFrame = sendFrame; + _retroEnv = retroEnv; } void SetSkipMode(bool skip) diff --git a/Libretro/libretro.cpp b/Libretro/libretro.cpp index 69981237..8c2fa9a5 100644 --- a/Libretro/libretro.cpp +++ b/Libretro/libretro.cpp @@ -147,7 +147,7 @@ extern "C" { RETRO_API void retro_set_video_refresh(retro_video_refresh_t sendFrame) { - _renderer->SetSendFrame(sendFrame); + _renderer->SetCallbacks(sendFrame, retroEnv); } RETRO_API void retro_set_audio_sample(retro_audio_sample_t sendAudioSample) @@ -178,31 +178,6 @@ extern "C" { Console::Reset(true); } - void setup_av_info(struct retro_system_av_info *info) - { - info->timing.fps = Console::GetModel() == NesModel::NTSC ? 60.098811862348404716732985230828 : 50.006977968268290848936010226333; - info->timing.sample_rate = 48000; - - float ratio = (float)EmulationSettings::GetAspectRatio(); - if(ratio == 0.0f) { - ratio = 1.0f; - } - ratio *= (float)EmulationSettings::GetOverscanDimensions().GetScreenWidth() / EmulationSettings::GetOverscanDimensions().GetScreenHeight() / 256 * 240; - - if(EmulationSettings::GetScreenRotation() % 180) { - info->geometry.aspect_ratio = ratio == 0.0f ? 0.0f : 1.0f / ratio; - } else { - info->geometry.aspect_ratio = ratio; - } - - info->geometry.base_width = EmulationSettings::GetOverscanDimensions().GetScreenWidth(); - info->geometry.base_height = EmulationSettings::GetOverscanDimensions().GetScreenHeight(); - - //For HD packs: - info->geometry.max_width = 256 * 10; - info->geometry.max_height = 240 * 10; - } - void set_flag(const char* flagName, uint64_t flagValue) { struct retro_variable var = {}; @@ -464,10 +439,6 @@ extern "C" { EmulationSettings::SetControllerKeys(1, getKeyBindings(1)); EmulationSettings::SetControllerKeys(2, getKeyBindings(2)); EmulationSettings::SetControllerKeys(3, getKeyBindings(3)); - - retro_system_av_info avInfo = {}; - setup_av_info(&avInfo); - retroEnv(RETRO_ENVIRONMENT_SET_GEOMETRY, &avInfo); } RETRO_API void retro_run() @@ -492,12 +463,8 @@ extern "C" { bool hdPacksEnabled = EmulationSettings::CheckFlag(EmulationFlags::UseHdPacks); if(hdPacksEnabled != _hdPacksEnabled) { - if(_hdPacksEnabled != hdPacksEnabled) { - //Try to load/unload HD pack when the flag is toggled - if(Console::GetInstance()->UpdateHdPackMode()) { - update_settings(); - } - } + //Try to load/unload HD pack when the flag is toggled + Console::GetInstance()->UpdateHdPackMode(); _hdPacksEnabled = hdPacksEnabled; } } @@ -685,7 +652,7 @@ extern "C" { RETRO_API void retro_get_system_av_info(struct retro_system_av_info *info) { - setup_av_info(info); + _renderer->GetSystemAudioVideoInfo(*info, 256, 240); } RETRO_API void *retro_get_memory_data(unsigned id)