Move to core options V2 style

This commit is contained in:
Craig Carnell authored and Eric Warmenhoven committed 2025-10-30 14:02:54 -04:00
1 parent bb6559e51d
commit 7189a75497
15 files changed
+1815 -541

No files matched your search

+28 -3
View File
@@ -3,6 +3,7 @@
#include "Common/Logging/Log.h"
#include "Common/Thread.h"
#include "AudioCommon/AudioCommon.h"
#include "VideoCommon/Present.h"
#include "DolphinLibretro/Common/Globals.h"
namespace Libretro
@@ -21,13 +22,14 @@ unsigned int GetSampleRate()
{
// when called from retro_run
SoundStream* sound_stream = Core::System::GetInstance().GetSoundStream();
double sampleRate = Libretro::Options::GetCached<int>(Libretro::Options::audio::MIXER_RATE);
if (sound_stream && sound_stream->GetMixer() &&
sound_stream->GetMixer()->GetSampleRate() != 0)
return sound_stream->GetMixer()->GetSampleRate();
// used in Stream constructor
if (Core::System::GetInstance().IsWii())
return Options::audioMixerRate;
else if (Options::audioMixerRate == 32000u)
return sampleRate;
else if (sampleRate == 32000u)
return 32029;
return 48043;
@@ -42,7 +44,7 @@ void Init()
{
Reset();
call_back_audio = Options::callBackAudio.Get();
call_back_audio = Libretro::Options::GetCached<bool>(Libretro::Options::audio::CALL_BACK_AUDIO);
if (!call_back_audio)
return;
@@ -256,6 +258,29 @@ namespace FrameTiming
return use_frame_time_cb;
}
bool IsFastForwarding()
{
return VideoCommon::g_is_fast_forwarding;
}
void CheckForFastForwarding()
{
if (!Libretro::environ_cb)
return;
bool is_fast_forwarding = false;
// Query the fast-forward state from RetroArch
if (Libretro::environ_cb(RETRO_ENVIRONMENT_GET_FASTFORWARDING, &is_fast_forwarding))
{
VideoCommon::g_is_fast_forwarding = is_fast_forwarding;
return;
}
// Environment call not supported
VideoCommon::g_is_fast_forwarding = false;
}
void ThrottleFrame()
{
if (!use_frame_time_cb)
+3 -1
View File
@@ -50,7 +50,9 @@ namespace FrameTiming
void Init();
void Reset();
bool IsEnabled();
void ThrottleFrame(); // Call this at end of retro_run()
void CheckForFastForwarding();
bool IsFastForwarding();
void ThrottleFrame();
} // namespace FrameTiming
} // namespace Libretro
+178 -74
View File
@@ -107,111 +107,200 @@ bool retro_load_game(const struct retro_game_info* game)
INFO_LOG_FMT(COMMON, "User Directory set to '{}'", user_dir);
INFO_LOG_FMT(COMMON, "System Directory set to '{}'", sys_dir);
using namespace Libretro::Options;
Libretro::Options::Init();
// Main.Core
Config::SetCurrent(Config::MAIN_CPU_CORE, Libretro::Options::cpu_core);
// Disabled due to current upstream bug causing fastmem disabled to segfault
//#if defined(_DEBUG)
// Config::SetCurrent(Config::MAIN_FASTMEM, false);
//#else
Config::SetCurrent(Config::MAIN_FASTMEM, Libretro::Options::fastmem);
//#endif
Config::SetCurrent(Config::MAIN_DSP_HLE, Libretro::Options::DSPHLE);
Config::SetCurrent(Config::MAIN_CPU_THREAD, true);
Config::SetCurrent(Config::MAIN_ENABLE_CHEATS, Libretro::Options::cheatsEnabled);
Config::SetCurrent(Config::MAIN_GC_LANGUAGE, (int)(DiscIO::Language)Libretro::Options::Language - 1);
Config::SetCurrent(Config::MAIN_CPU_CORE,
static_cast<PowerPC::CPUCore>(
Libretro::GetOption<int>(
core::CPU_CORE,
static_cast<int>(PowerPC::DefaultCPUCore()))));
#if defined(_DEBUG)
Config::SetCurrent(Config::MAIN_FASTMEM, false);
Config::SetCurrent(Config::MAIN_FASTMEM_ARENA, false);
#else
Config::SetCurrent(Config::MAIN_FASTMEM,
Libretro::GetOption<bool>(core::FASTMEM, /*def=*/true));
Config::SetCurrent(Config::MAIN_FASTMEM_ARENA,
Libretro::GetOption<bool>(core::FASTMEM_ARENA, /*def=*/true));
#endif
Config::SetCurrent(Config::MAIN_DSP_HLE,
Libretro::GetOption<bool>(audio::DSP_HLE, /*def=*/true));
// dual core (true) or single core (false)
Config::SetCurrent(Config::MAIN_CPU_THREAD,
Libretro::GetOption<bool>(core::MAIN_CPU_THREAD, /*def=*/true));
Config::SetCurrent(Config::MAIN_ENABLE_CHEATS,
Libretro::GetOption<bool>(core::CHEATS_ENABLED, /*def=*/false));
Config::SetCurrent(Config::MAIN_GC_LANGUAGE,
Libretro::GetOption<int>(core::LANGUAGE, static_cast<int>(DiscIO::Language::English)));
Config::SetCurrent(Config::MAIN_DPL2_DECODER, false);
Config::SetCurrent(Config::MAIN_AUDIO_LATENCY, 0);
Config::SetCurrent(Config::MAIN_AUDIO_FILL_GAPS, false);
Config::SetCurrent(Config::MAIN_EMULATION_SPEED, Libretro::Options::EmulationSpeed);
Config::SetCurrent(Config::MAIN_OVERCLOCK, Libretro::Options::cpuClockRate);
Config::SetCurrent(Config::MAIN_OVERCLOCK_ENABLE, Libretro::Options::cpuClockRate != 1.0);
Config::SetCurrent(Config::MAIN_WIIMOTE_CONTINUOUS_SCANNING,
static_cast<bool>(Libretro::Options::WiimoteContinuousScanning));
Config::SetCurrent(Config::MAIN_FAST_DISC_SPEED, Libretro::Options::fastDiscSpeed);
#ifdef IPHONEOS
//Libretro::Options::cpu_core.FilterForJitCapability();
bool can_jit = false;
if (!Libretro::environ_cb(RETRO_ENVIRONMENT_GET_JIT_CAPABLE, &can_jit) || !can_jit)
{
auto current = Config::Get(Config::MAIN_CPU_CORE);
if (current == PowerPC::CPUCore::JIT64 ||
current == PowerPC::CPUCore::JITARM64)
{
Config::SetCurrent(Config::MAIN_CPU_CORE, PowerPC::CPUCore::CachedInterpreter);
}
Config::SetCurrent(Config::GFX_VERTEX_LOADER_TYPE, VertexLoaderType::Software);
Config::SetCurrent(Config::MAIN_EMULATION_SPEED,
Libretro::GetOption<double>(core::EMULATION_SPEED, /*def=*/0.0));
{
// Overclock (cpu clock rate) — option values in option_defs used strings like "100%" etc.
double multiplier = Libretro::GetOption<double>(core::CPU_CLOCK_RATE, 1.0);
Config::SetCurrent(Config::MAIN_OVERCLOCK, multiplier);
Config::SetCurrent(Config::MAIN_OVERCLOCK_ENABLE, multiplier != 1.0);
}
#endif
Config::SetCurrent(Config::MAIN_PRECISION_FRAME_TIMING,
Libretro::GetOption<bool>(core::MAIN_PRECISION_FRAME_TIMING,
/*def=*/false)); // true is the standalone default
Config::SetCurrent(Config::MAIN_WIIMOTE_CONTINUOUS_SCANNING,
Libretro::GetOption<bool>(sysconf::WIIMOTE_CONTINUOUS_SCANNING,
/*def=*/false));
Config::SetCurrent(Config::MAIN_MMU,
Libretro::GetOption<bool>(core::MAIN_MMU, /*def=*/false));
Config::SetCurrent(Config::MAIN_FAST_DISC_SPEED,
Libretro::GetOption<bool>(core::FAST_DISC_SPEED, /*def=*/false));
// Main.Interface
Config::SetCurrent(Config::MAIN_OSD_MESSAGES, Libretro::Options::osdEnabled);
Config::SetCurrent(Config::MAIN_OSD_MESSAGES,
Libretro::GetOption<bool>(main_interface::OSD_ENABLED, /*def=*/true));
Config::SetCurrent(Config::MAIN_ENABLE_DEBUGGING,
Libretro::GetOption<bool>(main_interface::ENABLE_DEBUGGING, /*def=*/false));
// Main.General
Config::SetCurrent(Config::MAIN_TIME_TRACKING, false);
// Main.DSP
Config::SetCurrent(Config::MAIN_DSP_JIT, Libretro::Options::DSPEnableJIT);
Config::SetCurrent(Config::MAIN_DSP_JIT,
Libretro::GetOption<bool>(audio::DSP_JIT, /*def=*/true));
Config::SetCurrent(Config::MAIN_DUMP_AUDIO, false);
Config::SetCurrent(Config::MAIN_AUDIO_BACKEND, BACKEND_NULLSOUND);
// SYSCONF.IPL
Config::SetBase(Config::SYSCONF_LANGUAGE, (u32)(DiscIO::Language)Libretro::Options::Language);
Config::SetBase(Config::SYSCONF_WIDESCREEN, Libretro::Options::Widescreen);
Config::SetBase(Config::SYSCONF_PROGRESSIVE_SCAN, Libretro::Options::progressiveScan);
Config::SetBase(Config::SYSCONF_PAL60, Libretro::Options::pal60);
Config::SetBase(Config::SYSCONF_WIDESCREEN,
Libretro::GetOption<bool>(sysconf::WIDESCREEN, /*def=*/true));
Config::SetBase(Config::SYSCONF_PROGRESSIVE_SCAN,
Libretro::GetOption<bool>(sysconf::PROGRESSIVE_SCAN, /*def=*/true));
Config::SetBase(Config::SYSCONF_PAL60,
Libretro::GetOption<bool>(sysconf::PAL60, /*def=*/true));
// SYSCONF.BT
Config::SetBase(Config::SYSCONF_SENSOR_BAR_POSITION, Libretro::Options::sensorBarPosition);
Config::SetBase(Config::SYSCONF_WIIMOTE_MOTOR, Libretro::Options::enableRumble);
Config::SetBase(Config::SYSCONF_SENSOR_BAR_POSITION,
Libretro::GetOption<int>(sysconf::SENSOR_BAR_POSITION, 0));
Config::SetBase(Config::SYSCONF_WIIMOTE_MOTOR,
Libretro::GetOption<bool>(sysconf::ENABLE_RUMBLE, /*def=*/true));
// Graphics.Hardware
Config::SetBase(Config::GFX_VSYNC, Libretro::Options::vSync);
//Config::SetBase(Config::GFX_VSYNC,
// Libretro::GetOption<bool>(gfx_hardware::VSYNC, /*def=*/false));
// Graphics.Settings
Config::SetBase(Config::GFX_WIDESCREEN_HACK, Libretro::Options::WidescreenHack);
Config::SetBase(Config::GFX_WIDESCREEN_HACK,
Libretro::GetOption<bool>(gfx_settings::WIDESCREEN_HACK, /*def=*/false));
Config::SetBase(Config::GFX_ASPECT_RATIO, AspectMode::Stretch);
Config::SetBase(Config::GFX_SAFE_TEXTURE_CACHE_COLOR_SAMPLES, Libretro::Options::textureCacheAccuracy);
Config::SetBase(Config::GFX_HIRES_TEXTURES, Libretro::Options::loadCustomTextures);
Config::SetBase(Config::GFX_CACHE_HIRES_TEXTURES, Libretro::Options::cacheCustomTextures);
Config::SetBase(Config::GFX_ENABLE_GPU_TEXTURE_DECODING, Libretro::Options::gpuTextureDecoding);
Config::SetBase(Config::GFX_FAST_DEPTH_CALC, Libretro::Options::fastDepthCalc);
Config::SetBase(Config::GFX_EFB_SCALE, Libretro::Options::efbScale);
Config::SetBase(Config::GFX_SAFE_TEXTURE_CACHE_COLOR_SAMPLES,
Libretro::GetOption<int>(gfx_settings::TEXTURE_CACHE_ACCURACY, 128));
Config::SetBase(Config::GFX_HIRES_TEXTURES,
Libretro::GetOption<bool>(gfx_enhancements::LOAD_CUSTOM_TEXTURES, /*def=*/false));
Config::SetBase(Config::GFX_CACHE_HIRES_TEXTURES,
Libretro::GetOption<bool>(gfx_enhancements::CACHE_CUSTOM_TEXTURES, /*def=*/false));
Config::SetBase(Config::GFX_ENABLE_GPU_TEXTURE_DECODING,
Libretro::GetOption<bool>(gfx_settings::GPU_TEXTURE_DECODING, /*def=*/false));
Config::SetBase(Config::GFX_ENABLE_PIXEL_LIGHTING,
Libretro::GetOption<bool>(gfx_settings::ENABLE_PIXEL_LIGHTING, /*def=*/false));
Config::SetBase(Config::GFX_FAST_DEPTH_CALC,
Libretro::GetOption<bool>(gfx_settings::FAST_DEPTH_CALCULATION, /*def=*/true));
Config::SetBase(Config::GFX_DISABLE_FOG,
Libretro::GetOption<bool>(gfx_settings::DISABLE_FOG, /*def=*/false));
Config::SetBase(Config::GFX_EFB_SCALE,
Libretro::GetOption<int>(gfx_settings::EFB_SCALE, /*def=*/1));
Config::SetBase(Config::GFX_BACKEND_MULTITHREADING, false);
Config::SetBase(Config::GFX_SHADER_COMPILATION_MODE, Libretro::Options::shaderCompilationMode);
Config::SetBase(Config::GFX_WAIT_FOR_SHADERS_BEFORE_STARTING, Libretro::Options::waitForShaders);
#if 0
Config::SetBase(Config::GFX_SHADER_COMPILER_THREADS, 1);
Config::SetBase(Config::GFX_SHADER_PRECOMPILER_THREADS, 1);
#endif
Config::SetBase(Config::GFX_SHADER_COMPILATION_MODE,
static_cast<ShaderCompilationMode>(
Libretro::GetOption<int>(
gfx_settings::SHADER_COMPILATION_MODE,
static_cast<int>(ShaderCompilationMode::Synchronous))));
Config::SetBase(Config::GFX_WAIT_FOR_SHADERS_BEFORE_STARTING,
Libretro::GetOption<bool>(gfx_settings::WAIT_FOR_SHADERS, /*def=*/false));
// Graphics.Enhancements
Config::SetBase(Config::GFX_ENHANCE_FORCE_TEXTURE_FILTERING, Libretro::Options::forceTextureFilteringMode);
Config::SetBase(Config::GFX_ENHANCE_MAX_ANISOTROPY, Libretro::Options::maxAnisotropy);
Config::SetBase(Config::GFX_ENHANCE_FORCE_TEXTURE_FILTERING,
static_cast<TextureFilteringMode>(
Libretro::GetOption<int>(
gfx_enhancements::FORCE_TEXTURE_FILTERING_MODE,
static_cast<int>(TextureFilteringMode::Default))));
Config::SetBase(Config::GFX_ENHANCE_MAX_ANISOTROPY,
static_cast<AnisotropicFilteringMode>(
Libretro::GetOption<int>(
gfx_enhancements::MAX_ANISOTROPY,
static_cast<int>(AnisotropicFilteringMode::Force1x))));
Config::SetBase(Config::GFX_ENHANCE_OUTPUT_RESAMPLING,
static_cast<OutputResamplingMode>(
Libretro::GetOption<int>(
gfx_enhancements::GFX_ENHANCE_OUTPUT_RESAMPLING,
static_cast<int>(OutputResamplingMode::Default))));
Config::SetBase(Config::GFX_ENHANCE_FORCE_TRUE_COLOR,
Libretro::GetOption<bool>(gfx_enhancements::FORCE_TRUE_COLOR,
/*def=*/true));
Config::SetBase(Config::GFX_ENHANCE_DISABLE_COPY_FILTER,
Libretro::GetOption<bool>(gfx_enhancements::GFX_ENHANCE_DISABLE_COPY_FILTER,
/*def=*/true));
Config::SetBase(Config::GFX_ENHANCE_HDR_OUTPUT,
Libretro::GetOption<bool>(gfx_enhancements::GFX_ENHANCE_HDR_OUTPUT,
/*def=*/false));
Config::SetBase(Config::GFX_ENHANCE_ARBITRARY_MIPMAP_DETECTION,
Libretro::GetOption<bool>(gfx_enhancements::GFX_ARBITRARY_MIPMAP_DETECTION, /*def=*/false));
// Graphics.Hacks
Config::SetBase(Config::GFX_HACK_EFB_ACCESS_ENABLE, Libretro::Options::efbAccessEnable);
Config::SetBase(Config::GFX_HACK_EFB_DEFER_INVALIDATION, Libretro::Options::efbAccessDeferInvalidation);
Config::SetBase(Config::GFX_HACK_EFB_ACCESS_TILE_SIZE, Libretro::Options::efbAccessTileSize);
Config::SetBase(Config::GFX_HACK_BBOX_ENABLE, Libretro::Options::bboxEnabled);
Config::SetBase(Config::GFX_HACK_FORCE_PROGRESSIVE, Libretro::Options::forceProgressive);
Config::SetBase(Config::GFX_HACK_SKIP_EFB_COPY_TO_RAM, Libretro::Options::efbToTexture);
Config::SetBase(Config::GFX_HACK_SKIP_XFB_COPY_TO_RAM, Libretro::Options::xfbToTextureEnable);
Config::SetBase(Config::GFX_HACK_DISABLE_COPY_TO_VRAM, Libretro::Options::efbToVram);
Config::SetBase(Config::GFX_HACK_DEFER_EFB_COPIES, Libretro::Options::deferEfbCopies);
Config::SetBase(Config::GFX_HACK_IMMEDIATE_XFB, Libretro::Options::immediatexfb);
Config::SetBase(Config::GFX_HACK_SKIP_DUPLICATE_XFBS, Libretro::Options::skipDupeFrames);
Config::SetBase(Config::GFX_HACK_EARLY_XFB_OUTPUT, Libretro::Options::earlyXFBOutput);
Config::SetBase(Config::GFX_HACK_COPY_EFB_SCALED, Libretro::Options::efbScaledCopy);
Config::SetBase(Config::GFX_HACK_EFB_EMULATE_FORMAT_CHANGES, Libretro::Options::efbEmulateFormatChanges);
Config::SetBase(Config::GFX_HACK_VERTEX_ROUNDING, Libretro::Options::vertexRounding);
Config::SetBase(Config::GFX_HACK_VI_SKIP, Libretro::Options::viSkip);
//Config::SetBase(Config::GFX_HACK_MISSING_COLOR_VALUE, Libretro::Options::missingColorValue);
Config::SetBase(Config::GFX_HACK_FAST_TEXTURE_SAMPLING, Libretro::Options::fastTextureSampling);
Config::SetBase(Config::GFX_HACK_EFB_ACCESS_ENABLE,
Libretro::GetOption<bool>(gfx_hacks::EFB_ACCESS_ENABLE, /*def=*/false));
Config::SetBase(Config::GFX_HACK_EFB_DEFER_INVALIDATION,
Libretro::GetOption<bool>(gfx_hacks::EFB_ACCESS_DEFER_INVALIDATION, /*def=*/false));
Config::SetBase(Config::GFX_HACK_EFB_ACCESS_TILE_SIZE,
Libretro::GetOption<int>(gfx_hacks::EFB_ACCESS_TILE_SIZE, /*def=*/64));
Config::SetBase(Config::GFX_HACK_BBOX_ENABLE,
Libretro::GetOption<bool>(gfx_hacks::BBOX_ENABLED, /*def=*/false));
Config::SetBase(Config::GFX_HACK_FORCE_PROGRESSIVE,
Libretro::GetOption<bool>(gfx_hacks::FORCE_PROGRESSIVE, /*def=*/true));
Config::SetBase(Config::GFX_HACK_SKIP_EFB_COPY_TO_RAM,
Libretro::GetOption<bool>(gfx_hacks::EFB_TO_TEXTURE, /*def=*/true));
Config::SetBase(Config::GFX_HACK_SKIP_XFB_COPY_TO_RAM,
Libretro::GetOption<bool>(gfx_hacks::XFB_TO_TEXTURE_ENABLE, /*def=*/true));
Config::SetBase(Config::GFX_HACK_DISABLE_COPY_TO_VRAM,
Libretro::GetOption<bool>(gfx_hacks::EFB_TO_VRAM, /*def=*/false));
Config::SetBase(Config::GFX_HACK_DEFER_EFB_COPIES,
Libretro::GetOption<bool>(gfx_hacks::DEFER_EFB_COPIES, /*def=*/true));
Config::SetBase(Config::GFX_HACK_IMMEDIATE_XFB,
Libretro::GetOption<bool>(gfx_hacks::IMMEDIATE_XFB, /*def=*/false));
Config::SetBase(Config::GFX_HACK_SKIP_DUPLICATE_XFBS,
Libretro::GetOption<bool>(gfx_hacks::SKIP_DUPE_FRAMES, /*def=*/true));
Config::SetBase(Config::GFX_HACK_EARLY_XFB_OUTPUT,
Libretro::GetOption<bool>(gfx_hacks::EARLY_XFB_OUTPUT, /*def=*/true));
Config::SetBase(Config::GFX_HACK_COPY_EFB_SCALED,
Libretro::GetOption<bool>(gfx_hacks::EFB_SCALED_COPY, /*def=*/true));
Config::SetBase(Config::GFX_HACK_EFB_EMULATE_FORMAT_CHANGES,
Libretro::GetOption<bool>(gfx_hacks::EFB_EMULATE_FORMAT_CHANGES, /*def=*/false));
Config::SetBase(Config::GFX_HACK_VERTEX_ROUNDING,
Libretro::GetOption<bool>(gfx_hacks::VERTEX_ROUNDING, /*def=*/false));
Config::SetBase(Config::GFX_HACK_VI_SKIP,
Libretro::GetOption<bool>(gfx_hacks::VI_SKIP, /*def=*/false));
Config::SetBase(Config::GFX_HACK_FAST_TEXTURE_SAMPLING,
Libretro::GetOption<bool>(gfx_hacks::FAST_TEXTURE_SAMPLING, /*def=*/true));
#ifdef __APPLE__
Config::SetBase(Config::GFX_HACK_NO_MIPMAPPING, Libretro::Options::noMipmapping);
Config::SetBase(Config::GFX_HACK_NO_MIPMAPPING,
Libretro::GetOption<bool>(gfx_hacks::NO_MIPMAPPING, /*def=*/false));
#endif
switch (Libretro::Options::antiAliasing)
switch (Libretro::GetOption<int>(gfx_settings::ANTI_ALIASING, 0))
{
case 1: // 2x MSAA
Config::SetBase(Config::GFX_MSAA, 2);
@@ -247,6 +336,21 @@ bool retro_load_game(const struct retro_game_info* game)
Core::SetIsThrottlerTempDisabled(true);
SConfig::GetInstance().bBootToPause = true;
#ifdef IPHONEOS
bool can_jit = false;
if (!Libretro::environ_cb(RETRO_ENVIRONMENT_GET_JIT_CAPABLE, &can_jit) || !can_jit)
{
auto current = Config::Get(Config::MAIN_CPU_CORE);
if (current == PowerPC::CPUCore::JIT64 ||
current == PowerPC::CPUCore::JITARM64)
{
Config::SetCurrent(Config::MAIN_CPU_CORE, PowerPC::CPUCore::CachedInterpreter);
}
Config::SetCurrent(Config::GFX_VERTEX_LOADER_TYPE, VertexLoaderType::Software);
}
#endif
INFO_LOG_FMT(BOOT, "Fastmem enabled = {}", (Config::Get(Config::MAIN_FASTMEM)) ? "Yes" : "No");
INFO_LOG_FMT(BOOT, "JIT debug enabled = {}", Config::IsDebuggingEnabled() ? "Yes" : "No");
File diff suppressed because it is too large. Load diff
+122 -117
View File
@@ -5,7 +5,6 @@
#include <string>
#include <vector>
#include <libretro.h>
#include "Common/Logging/Log.h"
#include "Core/PowerPC/PowerPC.h"
#include "DiscIO/Enums.h"
@@ -15,24 +14,25 @@ namespace Libretro
{
extern retro_environment_t environ_cb;
bool GetVariable(const char* key, const char*& out_value);
template <typename T>
T GetOption(const char* key, T def);
namespace Options
{
void Init();
void SetVariables();
void CheckVariables();
void RegisterCache();
void CheckForUpdatedVariables();
template <typename T>
T GetCached(const char* key, T def = T{});
bool IsUpdated(const char* key);
template <typename T>
class Option
{
public:
Option(const char* id, const char* name, std::initializer_list<std::pair<const char*, T>> list);
Option(const char* id, const char* name, std::initializer_list<const char*> list);
Option(const char* id, const char* name, T first, std::initializer_list<const char*> list);
Option(const char* id, const char* name, T first, int count, int step = 1);
Option(const char* id, const char* name, bool initial);
Option(const char* id, const char* name,
const std::vector<std::pair<std::string, T>>& list);
Option(const char* id, const char* name, int initial);
bool Updated()
{
if (m_dirty)
@@ -81,28 +81,7 @@ public:
return (T)(*this) != value;
}
void Rebuild()
{
m_options = m_name;
m_options.push_back(';');
bool first = true;
for (auto& option : m_list)
{
if (first) {
m_options += " " + option.first;
first = false;
} else {
m_options += "|" + option.first;
}
}
}
T Get() const;
void FilterForJitCapability();
private:
void Register();
const char* m_id;
const char* m_name;
T m_value;
@@ -111,102 +90,128 @@ private:
std::vector<std::pair<std::string, T>> m_list;
};
// ======================================================
// Core
extern Option<PowerPC::CPUCore> cpu_core;
extern Option<float> cpuClockRate;
extern Option<float> EmulationSpeed;
extern Option<bool> fastmem;
extern Option<bool> DSPHLE;
extern Option<bool> cheatsEnabled;
extern Option<DiscIO::Language> Language;
extern Option<bool> fastDiscSpeed;
extern Option<bool> WiimoteContinuousScanning;
extern Option<bool> altGCPorts;
extern Option<unsigned int> audioMixerRate;
// ======================================================
namespace core {
constexpr const char CPU_CORE[] = "dolphin_cpu_core";
constexpr const char CPU_CLOCK_RATE[] = "dolphin_cpu_clock_rate";
constexpr const char EMULATION_SPEED[] = "dolphin_emulation_speed";
constexpr const char MAIN_CPU_THREAD[] = "dolphin_main_cpu_thread";
constexpr const char MAIN_PRECISION_FRAME_TIMING[] = "dolphin_precision_frame_timing";
constexpr const char FASTMEM[] = "dolphin_fastmem";
constexpr const char FASTMEM_ARENA[] = "dolphin_fastmem_arena";
constexpr const char CHEATS_ENABLED[] = "dolphin_cheats_enabled";
constexpr const char LANGUAGE[] = "dolphin_language";
constexpr const char FAST_DISC_SPEED[] = "dolphin_fast_disc_speed";
constexpr const char MAIN_MMU[] = "dolphin_main_mmu";
} // namespace core
// Main.Interface
extern Option<bool> osdEnabled;
// ======================================================
// Audio / DSP
// ======================================================
namespace audio {
constexpr const char DSP_HLE[] = "dolphin_dsp_hle";
constexpr const char DSP_JIT[] = "dolphin_dsp_jit";
constexpr const char MIXER_RATE[] = "dolphin_mixer_rate";
constexpr const char CALL_BACK_AUDIO[] = "dolphin_call_back_audio";
} // namespace audio
// Main.DSP
extern Option<bool> DSPEnableJIT;
// ======================================================
// Interface
// ======================================================
namespace main_interface {
constexpr const char OSD_ENABLED[] = "dolphin_osd_enabled";
constexpr const char LOG_LEVEL[] = "dolphin_log_level";
constexpr const char ENABLE_DEBUGGING[] = "dolphin_debug_mode_enabled";
} // namespace main_interface
// SYSCONF.IPL
extern Option<bool> Widescreen;
extern Option<bool> progressiveScan;
extern Option<bool> pal60;
// ======================================================
// System Configuration (SYSCONF)
// ======================================================
namespace sysconf {
constexpr const char WIDESCREEN[] = "dolphin_widescreen";
constexpr const char PROGRESSIVE_SCAN[] = "dolphin_progressive_scan";
constexpr const char PAL60[] = "dolphin_pal60";
constexpr const char SENSOR_BAR_POSITION[] = "dolphin_sensor_bar_position";
constexpr const char ENABLE_RUMBLE[] = "dolphin_enable_rumble";
constexpr const char WIIMOTE_CONTINUOUS_SCANNING[] = "dolphin_wiimote_continuous_scanning";
constexpr const char ALT_GC_PORTS_ON_WII[] = "dolphin_alt_gc_ports_on_wii";
} // namespace sysconf
// SYSCONF.BT
extern Option<u32> sensorBarPosition;
extern Option<bool> enableRumble;
// ======================================================
// Graphics > Hardware
// ======================================================
namespace gfx_hardware {
// constexpr const char VSYNC[] = "dolphin_vysnc";
} // namespace gfx_hardware
// Graphics.Hardware
extern Option<bool> vSync;
// ======================================================
// Graphics > Settings
// ======================================================
namespace gfx_settings {
constexpr const char RENDERER[] = "dolphin_renderer";
constexpr const char WIDESCREEN_HACK[] = "dolphin_widescreen_hack";
constexpr const char EFB_SCALE[] = "dolphin_efb_scale";
constexpr const char SHADER_COMPILATION_MODE[] = "dolphin_shader_compilation_mode";
constexpr const char WAIT_FOR_SHADERS[] = "dolphin_wait_for_shaders";
constexpr const char ANTI_ALIASING[] = "dolphin_anti_aliasing";
constexpr const char TEXTURE_CACHE_ACCURACY[] = "dolphin_texture_cache_accuracy";
constexpr const char GPU_TEXTURE_DECODING[] = "dolphin_gpu_texture_decoding";
constexpr const char ENABLE_PIXEL_LIGHTING[] = "dolphin_pixel_lighting";
constexpr const char FAST_DEPTH_CALCULATION[] = "dolphin_fast_depth_calculation";
constexpr const char DISABLE_FOG[] = "dolphin_disable_fog";
} // namespace gfx_settings
// Graphics.Settings
extern Option<std::string> renderer;
extern Option<bool> WidescreenHack;
extern Option<int> efbScale;
extern Option<ShaderCompilationMode> shaderCompilationMode;
extern Option<bool> waitForShaders;
extern Option<int> antiAliasing;
extern Option<int> textureCacheAccuracy;
extern Option<bool> loadCustomTextures;
extern Option<bool> cacheCustomTextures;
extern Option<bool> gpuTextureDecoding;
extern Option<bool> fastDepthCalc;
// ======================================================
// Graphics > Enhancements
// ======================================================
namespace gfx_enhancements {
constexpr const char MAX_ANISOTROPY[] = "dolphin_max_anisotropy";
constexpr const char FORCE_TEXTURE_FILTERING_MODE[] = "dolphin_force_texture_filtering_mode";
constexpr const char LOAD_CUSTOM_TEXTURES[] = "dolphin_load_custom_textures";
constexpr const char CACHE_CUSTOM_TEXTURES[] = "dolphin_cache_custom_textures";
constexpr const char GFX_ENHANCE_OUTPUT_RESAMPLING[] = "dolphin_enhance_output_resampling";
constexpr const char FORCE_TRUE_COLOR[] = "dolphin_force_true_color";
constexpr const char GFX_ENHANCE_DISABLE_COPY_FILTER[] = "dolphin_disable_copy_filter";
constexpr const char GFX_ENHANCE_HDR_OUTPUT[] = "dolphin_enhance_hdr_output";
constexpr const char GFX_ARBITRARY_MIPMAP_DETECTION[] = "dolphin_mipmap_detection";
} // namespace gfx_enhancements
// Graphics.Enhancements
extern Option<TextureFilteringMode> forceTextureFilteringMode;
extern Option<AnisotropicFilteringMode> maxAnisotropy;
// Graphics.Hacks
extern Option<bool> efbAccessEnable;
extern Option<bool> efbAccessDeferInvalidation;
extern Option<int> efbAccessTileSize;
extern Option<bool> bboxEnabled;
extern Option<bool> forceProgressive;
extern Option<bool> efbToTexture;
extern Option<bool> xfbToTextureEnable;
extern Option<bool> efbToVram;
extern Option<bool> deferEfbCopies;
extern Option<bool> immediatexfb;
extern Option<bool> skipDupeFrames;
extern Option<bool> earlyXFBOutput;
extern Option<bool> efbScaledCopy;
extern Option<bool> efbEmulateFormatChanges;
extern Option<bool> vertexRounding;
extern Option<bool> viSkip;
//extern Option<u32> missingColorValue;
extern Option<bool> fastTextureSampling;
// ======================================================
// Graphics > Hacks
// ======================================================
namespace gfx_hacks {
constexpr const char EFB_ACCESS_ENABLE[] = "dolphin_efb_access_enable";
constexpr const char EFB_ACCESS_DEFER_INVALIDATION[] = "dolphin_efb_access_defer_invalidation";
constexpr const char EFB_ACCESS_TILE_SIZE[] = "dolphin_efb_access_tile_size";
constexpr const char BBOX_ENABLED[] = "dolphin_bbox_enabled";
constexpr const char FORCE_PROGRESSIVE[] = "dolphin_force_progressive";
constexpr const char EFB_TO_TEXTURE[] = "dolphin_efb_to_texture";
constexpr const char XFB_TO_TEXTURE_ENABLE[] = "dolphin_xfb_to_texture_enable";
constexpr const char EFB_TO_VRAM[] = "dolphin_efb_to_vram";
constexpr const char DEFER_EFB_COPIES[] = "dolphin_defer_efb_copies";
constexpr const char IMMEDIATE_XFB[] = "dolphin_immediate_xfb";
constexpr const char SKIP_DUPE_FRAMES[] = "dolphin_skip_dupe_frames";
constexpr const char EARLY_XFB_OUTPUT[] = "dolphin_early_xfb_output";
constexpr const char EFB_SCALED_COPY[] = "dolphin_efb_scaled_copy";
constexpr const char EFB_EMULATE_FORMAT_CHANGES[] = "dolphin_efb_emulate_format_changes";
constexpr const char VERTEX_ROUNDING[] = "dolphin_vertex_rounding";
constexpr const char VI_SKIP[] = "dolphin_vi_skip";
constexpr const char FAST_TEXTURE_SAMPLING[] = "dolphin_fast_texture_sampling";
#ifdef __APPLE__
extern Option<bool> noMipmapping;
constexpr const char NO_MIPMAPPING[] = "dolphin_no_mipmapping";
#endif
} // namespace gfx_hacks
// ======================================================
// Wiimote IR
extern Option<int> irMode;
extern Option<int> irCenter;
extern Option<int> irWidth;
extern Option<int> irHeight;
// Other
extern Option<Common::Log::LogLevel> logLevel;
extern Option<bool> callBackAudio;
template <typename T>
T Libretro::Options::Option<T>::Get() const
{
struct retro_variable var = {m_id, nullptr};
if (environ_cb && environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
{
std::string selected = var.value;
for (const auto& pair : m_list)
{
if (pair.first == selected)
return pair.second;
}
}
return m_list.empty() ? T{} : m_list.front().second;
}
// ======================================================
namespace wiimote {
constexpr const char IR_MODE[] = "dolphin_ir_mode";
constexpr const char IR_OFFSET[] = "dolphin_ir_offset";
constexpr const char IR_YAW[] = "dolphin_ir_yaw";
constexpr const char IR_PITCH[] = "dolphin_ir_pitch";
} // namespace wiimote
} // namespace Options
} // namespace Libretro
+26 -14
View File
@@ -450,7 +450,8 @@ void Init(const WindowSystemInfo& wsi)
Keyboard::Initialize();
FreeLook::Initialize();
int port_max = (Core::System::GetInstance().IsWii() && Libretro::Options::altGCPorts) ? 8 : 4;
int port_max = (Core::System::GetInstance().IsWii() &&
Libretro::Options::GetCached<int>(Libretro::Options::sysconf::ALT_GC_PORTS_ON_WII)) ? 8 : 4;
for (int i = 0; i < port_max; i++)
Libretro::Input::AddDevicesForPort(i);
@@ -466,7 +467,8 @@ void InitStage2()
if (Core::System::GetInstance().IsWii() && !Config::Get(Config::MAIN_BLUETOOTH_PASSTHROUGH_ENABLED))
{
if (Libretro::Options::altGCPorts) // Wii devices listed in ports 1-4, GC controllers in ports 5-8
// Wii devices listed in ports 1-4, GC controllers in ports 5-8
if (Libretro::Options::GetCached<int>(Libretro::Options::sysconf::ALT_GC_PORTS_ON_WII))
{
static const struct retro_controller_description wiimote_desc[] = {
{"WiiMote", RETRO_DEVICE_WIIMOTE},
@@ -594,8 +596,9 @@ void retro_set_input_state(retro_input_state_t cb)
void retro_set_controller_port_device(unsigned port, unsigned device)
{
auto& system = Core::System::GetInstance();
bool altGCPorts = Libretro::Options::GetCached<bool>(Libretro::Options::sysconf::ALT_GC_PORTS_ON_WII);
if (((!system.IsWii() || !Libretro::Options::altGCPorts) && port > 3) || port > 7)
if (((!system.IsWii() || !altGCPorts) && port > 3) || port > 7)
return;
Libretro::Input::input_types[port] = device;
@@ -606,7 +609,7 @@ void retro_set_controller_port_device(unsigned port, unsigned device)
if (system.IsWii() && port < 4)
WiimoteCommon::OnSourceChanged(port, WiimoteSource::None);
if (!system.IsWii() || !Libretro::Options::altGCPorts)
if (!system.IsWii() || !altGCPorts)
{
Config::SetBaseOrCurrent(Config::GetInfoForSIDevice(port), SerialInterface::SIDEVICE_NONE);
si.ChangeDevice(Config::Get(Config::GetInfoForSIDevice(port)), port);
@@ -628,7 +631,7 @@ void retro_set_controller_port_device(unsigned port, unsigned device)
std::vector<retro_input_descriptor> all_descs;
int port_max = (system.IsWii() && Libretro::Options::altGCPorts) ? 8 : 4;
int port_max = (system.IsWii() && altGCPorts) ? 8 : 4;
for (int i = 0; i < port_max; i++)
{
@@ -748,7 +751,8 @@ void retro_set_controller_port_device_gc(unsigned port, unsigned device)
"`" + devAnalog + ":Trigger0+`|L3"); // L-trigger Soft Press
gcTriggers->SetControlExpression(3,
"`" + devAnalog + ":Trigger1+`|R3"); // R-trigger Soft Press
if (Libretro::Options::enableRumble)
bool enableRumble = Libretro::Options::GetCached<bool>(Libretro::Options::sysconf::ENABLE_RUMBLE);
if (enableRumble)
gcRumble->SetControlExpression(0, "Rumble");
static_cast<ControllerEmu::NumericSetting<bool>*>(gcOptions->numeric_settings[0].get())
->SetValue(true); // Always Connected
@@ -775,7 +779,8 @@ void retro_set_controller_port_device_wii(unsigned port, unsigned device)
return;
}
if (!Libretro::Options::altGCPorts) // Disconnect GC controller to avoid conflict with Wii device
bool altGCPorts = Libretro::Options::GetCached<bool>(Libretro::Options::sysconf::ALT_GC_PORTS_ON_WII);
if (!altGCPorts) // Disconnect GC controller to avoid conflict with Wii device
{
Config::SetBaseOrCurrent(Config::GetInfoForSIDevice(port), SerialInterface::SIDEVICE_NONE);
si.ChangeDevice(Config::Get(Config::GetInfoForSIDevice(port)), port);
@@ -844,12 +849,17 @@ void retro_set_controller_port_device_wii(unsigned port, unsigned device)
ControllerEmu::ControlGroup* wmHotkeys = wm->GetWiimoteGroup(WiimoteGroup::Hotkeys);
#endif
const int irMode = Libretro::Options::GetCached<int>(Libretro::Options::wiimote::IR_MODE);
const int irCenter = Libretro::Options::GetCached<int>(Libretro::Options::wiimote::IR_OFFSET);
const int irWidth = Libretro::Options::GetCached<int>(Libretro::Options::wiimote::IR_YAW);
const int irHeight = Libretro::Options::GetCached<int>(Libretro::Options::wiimote::IR_PITCH);
static_cast<ControllerEmu::NumericSetting<double>*>(wmIR->numeric_settings[1].get())
->SetValue(Libretro::Options::irCenter); // IR Vertical Offset
->SetValue(irCenter); // IR Vertical Offset
static_cast<ControllerEmu::NumericSetting<double>*>(wmIR->numeric_settings[2].get())
->SetValue(Libretro::Options::irWidth); // IR Total Yaw
->SetValue(irWidth); // IR Total Yaw
static_cast<ControllerEmu::NumericSetting<double>*>(wmIR->numeric_settings[3].get())
->SetValue(Libretro::Options::irHeight); // IR Total Pitch
->SetValue(irHeight); // IR Total Pitch
if (device == RETRO_DEVICE_WIIMOTE_NC)
{
@@ -877,7 +887,7 @@ void retro_set_controller_port_device_wii(unsigned port, unsigned device)
wmButtons->SetControlExpression(4, "L"); // -
wmButtons->SetControlExpression(5, "R"); // +
if (Libretro::Options::irMode != 1 && Libretro::Options::irMode != 2)
if (irMode != 1 && irMode != 2)
{
wmTilt->SetControlExpression(0, "`" + devAnalog + ":Y1-`"); // Forward
wmTilt->SetControlExpression(1, "`" + devAnalog + ":Y1+`"); // Backward
@@ -915,7 +925,7 @@ void retro_set_controller_port_device_wii(unsigned port, unsigned device)
wmDPad->SetControlExpression(2, "Left"); // Left
wmDPad->SetControlExpression(3, "Right"); // Right
if (Libretro::Options::irMode == 1 || Libretro::Options::irMode == 2)
if (irMode == 1 || irMode == 2)
{
// Set right stick to control the IR
wmIR->SetControlExpression(0, "`" + devAnalog + ":Y1-`"); // Up
@@ -923,7 +933,7 @@ void retro_set_controller_port_device_wii(unsigned port, unsigned device)
wmIR->SetControlExpression(2, "`" + devAnalog + ":X1-`"); // Left
wmIR->SetControlExpression(3, "`" + devAnalog + ":X1+`"); // Right
static_cast<ControllerEmu::NumericSetting<bool>*>(wmIR->numeric_settings[4].get())
->SetValue(Libretro::Options::irMode == 1); // Relative input
->SetValue(irMode == 1); // Relative input
static_cast<ControllerEmu::NumericSetting<bool>*>(wmIR->numeric_settings[5].get())
->SetValue(true); // Auto hide
}
@@ -964,7 +974,9 @@ void retro_set_controller_port_device_wii(unsigned port, unsigned device)
->SetValue(false); // Upright Wiimote
static_cast<ControllerEmu::NumericSetting<bool>*>(wmOptions->numeric_settings[3].get())
->SetValue(false); // Sideways Wiimote
if (Libretro::Options::enableRumble)
bool enableRumble = Libretro::Options::GetCached<bool>(Libretro::Options::sysconf::ENABLE_RUMBLE);
if (enableRumble)
wmRumble->SetControlExpression(0, "Rumble");
switch (device)
+4 -1
View File
@@ -49,7 +49,10 @@ void Shutdown()
LogListener::LogListener(retro_log_printf_t log) : m_log(log)
{
Common::Log::LogManager::GetInstance()->SetLogLevel(Libretro::Options::logLevel);
Common::Log::LogManager::GetInstance()->SetLogLevel(
static_cast<Common::Log::LogLevel>(
Libretro::Options::GetCached<int>(
Libretro::Options::main_interface::LOG_LEVEL, static_cast<int>(Common::Log::LogLevel::LINFO))));
Common::Log::LogManager::GetInstance()->SetEnable(Common::Log::LogType::BOOT, true);
Common::Log::LogManager::GetInstance()->SetEnable(Common::Log::LogType::CORE, true);
Common::Log::LogManager::GetInstance()->SetEnable(Common::Log::LogType::VIDEO, true);
+28 -27
View File
@@ -69,7 +69,6 @@ extern "C" {
void retro_set_environment(retro_environment_t cb)
{
Libretro::environ_cb = cb;
Libretro::Options::SetVariables();
#ifdef PERF_TEST
environ_cb(RETRO_ENVIRONMENT_GET_PERF_INTERFACE, &perf_cb);
#endif
@@ -100,8 +99,11 @@ void retro_get_system_info(retro_system_info* info)
void retro_get_system_av_info(retro_system_av_info* info)
{
info->geometry.base_width = EFB_WIDTH * Libretro::Options::efbScale;
info->geometry.base_height = EFB_HEIGHT * Libretro::Options::efbScale;
int efbScale = Libretro::Options::GetCached<int>(
Libretro::Options::gfx_settings::EFB_SCALE);
info->geometry.base_width = EFB_WIDTH * efbScale;
info->geometry.base_height = EFB_HEIGHT * efbScale;
info->geometry.max_width = info->geometry.base_width;
info->geometry.max_height = info->geometry.base_height;
@@ -123,15 +125,22 @@ void retro_reset(void)
void retro_run(void)
{
Libretro::Options::CheckVariables();
Libretro::Options::CheckForUpdatedVariables();
Libretro::FrameTiming::CheckForFastForwarding();
#if defined(_DEBUG)
Common::Log::LogManager::GetInstance()->SetLogLevel(Common::Log::LogLevel::LDEBUG);
#else
Common::Log::LogManager::GetInstance()->SetLogLevel(Libretro::Options::logLevel);
Common::Log::LogManager::GetInstance()->SetLogLevel(
static_cast<Common::Log::LogLevel>(
Libretro::Options::GetCached<int>(
Libretro::Options::main_interface::LOG_LEVEL, static_cast<int>(Common::Log::LogLevel::LINFO))));
#endif
Config::SetCurrent(Config::MAIN_OVERCLOCK, Libretro::Options::cpuClockRate);
Config::SetCurrent(Config::MAIN_OVERCLOCK_ENABLE, Libretro::Options::cpuClockRate != 1.0);
g_Config.bWidescreenHack = Libretro::Options::WidescreenHack;
double cpuClock = Libretro::Options::GetCached<double>(
Libretro::Options::core::CPU_CLOCK_RATE);
Config::SetCurrent(Config::MAIN_OVERCLOCK, cpuClock);
Config::SetCurrent(Config::MAIN_OVERCLOCK_ENABLE, cpuClock != 1.0);
g_Config.bWidescreenHack = Libretro::Options::GetCached<bool>(
Libretro::Options::gfx_settings::WIDESCREEN_HACK);
Libretro::Input::Update();
@@ -171,14 +180,14 @@ void retro_run(void)
->SetSystemFrameBuffer((GLuint)Libretro::Video::hw_render.get_current_framebuffer());
}
if (Libretro::Options::efbScale.Updated())
if (Libretro::Options::IsUpdated(Libretro::Options::gfx_settings::EFB_SCALE))
{
g_Config.iEFBScale = Libretro::Options::efbScale;
g_Config.iEFBScale = Libretro::Options::GetCached<int>(
Libretro::Options::gfx_settings::EFB_SCALE);
unsigned cmd = RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO;
if (Libretro::Video::hw_render.context_type == RETRO_HW_CONTEXT_D3D11)
cmd = RETRO_ENVIRONMENT_SET_GEOMETRY;
retro_system_av_info info;
retro_get_system_av_info(&info);
Libretro::environ_cb(cmd, &info);
@@ -192,16 +201,19 @@ void retro_run(void)
Libretro::environ_cb(RETRO_ENVIRONMENT_SET_GEOMETRY, &info);
}
if (Libretro::Options::irMode.Updated() || Libretro::Options::irCenter.Updated()
|| Libretro::Options::irWidth.Updated() || Libretro::Options::irHeight.Updated()
|| Libretro::Options::enableRumble.Updated())
if (Libretro::Options::IsUpdated(Libretro::Options::wiimote::IR_MODE) ||
Libretro::Options::IsUpdated(Libretro::Options::wiimote::IR_OFFSET) ||
Libretro::Options::IsUpdated(Libretro::Options::wiimote::IR_YAW) ||
Libretro::Options::IsUpdated(Libretro::Options::wiimote::IR_PITCH) ||
Libretro::Options::IsUpdated(Libretro::Options::sysconf::ENABLE_RUMBLE))
{
Libretro::Input::ResetControllers();
}
if (Libretro::Options::WiimoteContinuousScanning.Updated())
if (Libretro::Options::IsUpdated(Libretro::Options::sysconf::WIIMOTE_CONTINUOUS_SCANNING))
{
Config::SetCurrent(Config::MAIN_WIIMOTE_CONTINUOUS_SCANNING, Libretro::Options::WiimoteContinuousScanning.Get());
Config::SetCurrent(Config::MAIN_WIIMOTE_CONTINUOUS_SCANNING,
Libretro::Options::GetCached<bool>(Libretro::Options::sysconf::WIIMOTE_CONTINUOUS_SCANNING));
WiimoteReal::Initialize(Wiimote::InitializeMode::DO_NOT_WAIT_FOR_WIIMOTES);
}
@@ -212,17 +224,6 @@ void retro_run(void)
Core::DoFrameStep(system);
system.GetFifo().RunGpuLoop();
// ensures frame advance with OpenGL backend
// without this, frames may only advance with input!
#ifdef __linux__
if (g_gfx && Config::Get(Config::MAIN_GFX_BACKEND) == "OGL")
{
u32 backbuffer_width = EFB_WIDTH * Libretro::Options::efbScale;
u32 backbuffer_height = EFB_HEIGHT * Libretro::Options::efbScale;
Libretro::Video::video_cb(RETRO_HW_FRAME_BUFFER_VALID, backbuffer_width, backbuffer_height, 0);
}
#endif
RETRO_PERFORMANCE_STOP(dolphin_main_func);
}
+34 -15
View File
@@ -67,7 +67,10 @@ void Init()
{
DEBUG_LOG_FMT(VIDEO, "Video - Init");
if (Options::renderer == "Hardware")
std::string renderer = Libretro::Options::GetCached<std::string>(
Libretro::Options::gfx_settings::RENDERER);
if (renderer == "Hardware")
{
retro_hw_context_type preferred = RETRO_HW_CONTEXT_NONE;
if (environ_cb(RETRO_ENVIRONMENT_GET_PREFERRED_HW_RENDER, &preferred) && SetHWRender(preferred))
@@ -88,7 +91,7 @@ void Init()
#endif
}
hw_render.context_type = RETRO_HW_CONTEXT_NONE;
if (Options::renderer == "Software")
if (renderer == "Software")
Config::SetBase(Config::MAIN_GFX_BACKEND, "Software Renderer");
else
Config::SetBase(Config::MAIN_GFX_BACKEND, "Null");
@@ -102,6 +105,7 @@ bool SetHWRender(retro_hw_context_type type)
hw_render.context_reset = ContextReset;
hw_render.context_destroy = ContextDestroy;
hw_render.bottom_left_origin = true;
bool success = false;
switch (type)
{
@@ -112,29 +116,38 @@ bool SetHWRender(retro_hw_context_type type)
if (environ_cb(RETRO_ENVIRONMENT_SET_HW_RENDER, &hw_render))
{
Config::SetBase(Config::MAIN_GFX_BACKEND, "OGL");
return true;
success = true;
} else {
WARN_LOG_FMT(VIDEO, "Video - SetHWRender - failed to set hw renderer for OpenGL Core");
}
break;
case RETRO_HW_CONTEXT_OPENGLES3:
case RETRO_HW_CONTEXT_OPENGL:
{
// when using RETRO_HW_CONTEXT_OPENGL you can't set version above 3.0 (RA will try to use highest version available anyway)
// dolphin support OpenGL ES 3.0 too (no support for 2.0) so we are good
hw_render.version_major = 3;
hw_render.version_minor = 0;
const char* api_name = (type == RETRO_HW_CONTEXT_OPENGLES3)
? "OpenGL ES 3.0+" : "OpenGL 3.0+";
if (environ_cb(RETRO_ENVIRONMENT_SET_HW_RENDER, &hw_render))
{
// Shared context is required with "gl" video driver
if(!environ_cb(RETRO_ENVIRONMENT_SET_HW_SHARED_CONTEXT, nullptr)) {
WARN_LOG_FMT(VIDEO, "Video - SetHWRender - unable to set shared context for OpenGL/GLES");
if (!environ_cb(RETRO_ENVIRONMENT_SET_HW_SHARED_CONTEXT, nullptr)) {
WARN_LOG_FMT(VIDEO, "Video - SetHWRender - unable to set shared context for {}", api_name);
}
INFO_LOG_FMT(VIDEO, "Video - SetHWRender - using {}", api_name);
Config::SetBase(Config::MAIN_GFX_BACKEND, "OGL");
return true;
} else {
WARN_LOG_FMT(VIDEO, "Video - SetHWRender - failed to set hw renderer for OpenGL/GLES");
success = true;
}
else
{
WARN_LOG_FMT(VIDEO, "Video - SetHWRender - failed to set hw renderer for {}", api_name);
}
break;
}
#ifdef _WIN32
case RETRO_HW_CONTEXT_D3D11:
hw_render.version_major = 11;
@@ -142,7 +155,7 @@ bool SetHWRender(retro_hw_context_type type)
if (environ_cb(RETRO_ENVIRONMENT_SET_HW_RENDER, &hw_render))
{
Config::SetBase(Config::MAIN_GFX_BACKEND, "D3D");
return true;
success = true;
}
break;
#endif
@@ -166,14 +179,15 @@ bool SetHWRender(retro_hw_context_type type)
environ_cb(RETRO_ENVIRONMENT_SET_HW_RENDER_CONTEXT_NEGOTIATION_INTERFACE, (void*)&iface);
Config::SetBase(Config::MAIN_GFX_BACKEND, "Vulkan");
return true;
success = true;
}
break;
#endif
default:
break;
}
return false;
return success;
}
void ContextReset(void)
@@ -199,8 +213,11 @@ void ContextReset(void)
return;
}
Vk::SetHWRenderInterface(vulkan);
Vk::SetSurfaceSize(EFB_WIDTH * Libretro::Options::efbScale,
EFB_HEIGHT * Libretro::Options::efbScale);
int efbScale = Libretro::Options::GetCached<int>(
Libretro::Options::gfx_settings::EFB_SCALE, 1);
Vk::SetSurfaceSize(EFB_WIDTH * efbScale,
EFB_HEIGHT * efbScale);
}
#endif
@@ -208,7 +225,9 @@ void ContextReset(void)
if (hw_render.context_type == RETRO_HW_CONTEXT_D3D11)
{
WindowSystemInfo wsi(WindowSystemType::Libretro, nullptr, nullptr, nullptr);
wsi.render_surface_scale = Libretro::Options::efbScale;
int efbScale = Libretro::Options::GetCached<int>(
Libretro::Options::gfx_settings::EFB_SCALE, 1);
wsi.render_surface_scale = efbScale;
g_video_backend->PrepareWindow(wsi);
retro_hw_render_interface_d3d11* d3d;
@@ -255,7 +274,7 @@ void ContextReset(void)
UpdateActiveConfig();
std::unique_ptr<DX11SwapChain> swap_chain = std::make_unique<DX11SwapChain>(
wsi, EFB_WIDTH * Libretro::Options::efbScale, EFB_HEIGHT * Libretro::Options::efbScale,
wsi, EFB_WIDTH * efbScale, EFB_HEIGHT * efbScale,
nullptr, nullptr);
auto gfx = std::make_unique<DX11::Gfx>(std::move(swap_chain), wsi.render_surface_scale);
@@ -2,6 +2,7 @@
#include "Common/Logging/Log.h"
#include "Core/Config/MainSettings.h"
#include "VideoCommon/VideoCommon.h"
#include "VideoCommon/Present.h"
#include "DolphinLibretro/Common/Options.h"
#include "DolphinLibretro/VideoContexts/ContextStatus.h"
#include "DolphinLibretro/Video.h"
@@ -19,8 +20,8 @@ void* GLContextLR::GetFuncAddress(const std::string& name)
bool GLContextLR::Initialize(const WindowSystemInfo& wsi, bool stereo, bool core)
{
m_backbuffer_width = EFB_WIDTH * Libretro::Options::efbScale;
m_backbuffer_height = EFB_HEIGHT * Libretro::Options::efbScale;
m_backbuffer_width = EFB_WIDTH * Libretro::Options::GetCached<int>(Libretro::Options::gfx_settings::EFB_SCALE, 1);
m_backbuffer_height = EFB_HEIGHT * Libretro::Options::GetCached<int>(Libretro::Options::gfx_settings::EFB_SCALE, 1);
switch (Libretro::Video::hw_render.context_type)
{
@@ -47,8 +48,8 @@ bool GLContextLR::Initialize(const WindowSystemInfo& wsi, bool stereo, bool core
void GLContextLR::Swap()
{
Libretro::Video::video_cb(RETRO_HW_FRAME_BUFFER_VALID, m_backbuffer_width, m_backbuffer_height,
0);
Libretro::Video::video_cb(VideoCommon::g_is_duplicate_frame ? nullptr : RETRO_HW_FRAME_BUFFER_VALID,
m_backbuffer_width, m_backbuffer_height, 0);
}
void GLContextLR::Shutdown()
+33 -6
View File
@@ -222,6 +222,24 @@ bool VKGfx::BindBackbuffer(const ClearColor& clear_color)
g_command_buffer_mgr->WaitForWorkerThreadIdle();
#ifdef __LIBRETRO__
// During fast-forward, skip most frame presentations to reduce swap chain load
// this is a temp HACK until we can properly implement frame skipping
if (VideoCommon::g_is_fast_forwarding)
{
static int frame_skip_counter = 0;
frame_skip_counter++;
// Only present every x frame during fast-forward
if (frame_skip_counter < 12)
{
return false;
}
frame_skip_counter = 0;
}
#endif
// Handle host window resizes.
CheckForSurfaceChange();
CheckForSurfaceResize();
@@ -297,11 +315,17 @@ bool VKGfx::BindBackbuffer(const ClearColor& clear_color)
// Transition from undefined (or present src, but it can be substituted) to
// color attachment ready for writing. These transitions must occur outside
// a render pass, unless the render pass declares a self-dependency.
m_swap_chain->GetCurrentTexture()->OverrideImageLayout(VK_IMAGE_LAYOUT_UNDEFINED);
m_swap_chain->GetCurrentTexture()->TransitionToLayout(
g_command_buffer_mgr->GetCurrentCommandBuffer(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
SetAndClearFramebuffer(m_swap_chain->GetCurrentFramebuffer(),
ClearColor{{0.0f, 0.0f, 0.0f, 1.0f}});
if (auto* tex = m_swap_chain->GetCurrentTexture())
{
tex->OverrideImageLayout(VK_IMAGE_LAYOUT_UNDEFINED);
tex->TransitionToLayout(
g_command_buffer_mgr->GetCurrentCommandBuffer(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
}
if(auto* chain = m_swap_chain->GetCurrentFramebuffer())
{
SetAndClearFramebuffer(chain,
ClearColor{{0.0f, 0.0f, 0.0f, 1.0f}});
}
return true;
}
@@ -314,8 +338,11 @@ void VKGfx::PresentBackbuffer()
{
// Transition the backbuffer to PRESENT_SRC to ensure all commands drawing
// to it have finished before present.
m_swap_chain->GetCurrentTexture()->TransitionToLayout(
if (auto* tex = m_swap_chain->GetCurrentTexture())
{
tex->TransitionToLayout(
g_command_buffer_mgr->GetCurrentCommandBuffer(), VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
}
// Submit the current command buffer, signaling rendering finished semaphore when it's done
// Because this final command buffer is rendering to the swap chain, we need to wait for
@@ -46,10 +46,17 @@ public:
}
VKTexture* GetCurrentTexture() const
{
const size_t idx = static_cast<size_t>(m_current_swap_chain_image_index);
if (idx >= m_swap_chain_images.size() || m_swap_chain_images.empty())
return nullptr;
return m_swap_chain_images[m_current_swap_chain_image_index].texture.get();
}
VKFramebuffer* GetCurrentFramebuffer() const
{
const size_t idx = static_cast<size_t>(m_current_swap_chain_image_index);
const size_t count = m_swap_chain_images.size();
if (count == 0 || idx >= count)
return nullptr;
return m_swap_chain_images[m_current_swap_chain_image_index].framebuffer.get();
}
VkResult AcquireNextImage();
@@ -22,6 +22,7 @@
#endif
#include "vulkan/vulkan.h"
#undef Success
#ifdef ANDROID
#include <unistd.h>
+20
View File
@@ -23,6 +23,7 @@
#include "VideoCommon/VideoEvents.h"
#include "VideoCommon/Widescreen.h"
#ifdef __LIBRETRO__
#include "Core/Config/MainSettings.h"
#include "VideoCommon/VideoBackendBase.h"
#endif
@@ -30,6 +31,10 @@ std::unique_ptr<VideoCommon::Presenter> g_presenter;
namespace VideoCommon
{
#ifdef __LIBRETRO__
bool g_is_fast_forwarding{false};
bool g_is_duplicate_frame{false};
#endif
// Stretches the native/internal analog resolution aspect ratio from ~4:3 to ~16:9
static float SourceAspectRatioToWidescreen(float source_aspect)
{
@@ -198,6 +203,14 @@ void Presenter::ViSwap(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height,
}
}
#ifdef __LIBRETRO__
g_is_duplicate_frame = is_duplicate;
// allow presentation logic to proceed to always generate a frame with OGL
if(Config::Get(Config::MAIN_GFX_BACKEND) == "OGL")
is_duplicate = false;
#endif
BeforePresentEvent::Trigger(present_info);
if (!is_duplicate || !g_ActiveConfig.bSkipPresentingDuplicateXFBs)
@@ -872,10 +885,17 @@ void Presenter::Present(std::optional<TimePoint> presentation_time)
{
std::lock_guard<std::mutex> guard(m_swap_mutex);
#ifndef __LIBRETRO__
if (presentation_time.has_value())
Core::System::GetInstance().GetCoreTiming().SleepUntil(*presentation_time);
#endif
#ifdef __LIBRETRO__
if ((!g_is_fast_forwarding) || (g_is_fast_forwarding && backbuffer_bound))
g_gfx->PresentBackbuffer();
#else
g_gfx->PresentBackbuffer();
#endif
}
if (m_xfb_entry)
+4 -1
View File
@@ -24,7 +24,10 @@ namespace VideoCommon
{
class OnScreenUI;
class PostProcessing;
#ifdef __LIBRETRO__
extern bool g_is_fast_forwarding;
extern bool g_is_duplicate_frame;
#endif
// Presenter is a class that deals with putting the final XFB on the screen.
// It also handles the ImGui UI and post-processing.
class Presenter