mirror of
https://github.com/dolphin-emu/dolphin
synced 2024-07-01 07:54:33 +00:00
Compare commits
33 Commits
d38f9d67d9
...
ad5d6fcce1
Author | SHA1 | Date | |
---|---|---|---|
|
ad5d6fcce1 | ||
|
f49659fbfc | ||
|
c46c010ae3 | ||
|
233ea58446 | ||
|
2f30ff6970 | ||
|
134c079ad2 | ||
|
bc67fc97c3 | ||
|
3dbaf38eae | ||
|
e58d6f4f1f | ||
|
1a33e28452 | ||
|
10a95a4d5b | ||
|
04b0ceedcd | ||
|
9c432e960b | ||
|
f8f117e599 | ||
|
c536754ffe | ||
|
e9e29daca4 | ||
|
2aec195ec8 | ||
|
c337ab6473 | ||
|
a75c65bde2 | ||
|
28692681ad | ||
|
bf230a9909 | ||
|
883195f171 | ||
|
ce2f4101f3 | ||
|
8e7d11d1a1 | ||
|
5c46716d28 | ||
|
0f659508ea | ||
|
aa393dfb6e | ||
|
e1a8dc65ce | ||
|
9b9e6c4582 | ||
|
29f1b82f5e | ||
|
75c2360aea | ||
|
55ba014fed | ||
|
e0d588e375 |
16
Data/Sys/GameSettings/GIT.ini
Normal file
16
Data/Sys/GameSettings/GIT.ini
Normal file
|
@ -0,0 +1,16 @@
|
|||
# GITP01, GITE01 - Geist
|
||||
|
||||
[Core]
|
||||
# Values set here will override the main Dolphin settings.
|
||||
# The game has random crashes and tons of unknown opcodes
|
||||
# when using Dualcore.
|
||||
CPUThread = False
|
||||
|
||||
[OnLoad]
|
||||
# Add memory patches to be loaded once on boot here.
|
||||
|
||||
[OnFrame]
|
||||
# Add memory patches to be applied every frame here.
|
||||
|
||||
[ActionReplay]
|
||||
# Add action replay cheats here.
|
2912
Languages/po/ar.po
2912
Languages/po/ar.po
File diff suppressed because it is too large
Load Diff
2868
Languages/po/ca.po
2868
Languages/po/ca.po
File diff suppressed because it is too large
Load Diff
2868
Languages/po/cs.po
2868
Languages/po/cs.po
File diff suppressed because it is too large
Load Diff
2870
Languages/po/da.po
2870
Languages/po/da.po
File diff suppressed because it is too large
Load Diff
2870
Languages/po/de.po
2870
Languages/po/de.po
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
2871
Languages/po/el.po
2871
Languages/po/el.po
File diff suppressed because it is too large
Load Diff
2868
Languages/po/en.po
2868
Languages/po/en.po
File diff suppressed because it is too large
Load Diff
3325
Languages/po/es.po
3325
Languages/po/es.po
File diff suppressed because it is too large
Load Diff
2868
Languages/po/fa.po
2868
Languages/po/fa.po
File diff suppressed because it is too large
Load Diff
3371
Languages/po/fi.po
3371
Languages/po/fi.po
File diff suppressed because it is too large
Load Diff
2973
Languages/po/fr.po
2973
Languages/po/fr.po
File diff suppressed because it is too large
Load Diff
2868
Languages/po/hr.po
2868
Languages/po/hr.po
File diff suppressed because it is too large
Load Diff
3489
Languages/po/hu.po
3489
Languages/po/hu.po
File diff suppressed because it is too large
Load Diff
2970
Languages/po/it.po
2970
Languages/po/it.po
File diff suppressed because it is too large
Load Diff
2943
Languages/po/ja.po
2943
Languages/po/ja.po
File diff suppressed because it is too large
Load Diff
2937
Languages/po/ko.po
2937
Languages/po/ko.po
File diff suppressed because it is too large
Load Diff
2871
Languages/po/ms.po
2871
Languages/po/ms.po
File diff suppressed because it is too large
Load Diff
2870
Languages/po/nb.po
2870
Languages/po/nb.po
File diff suppressed because it is too large
Load Diff
2934
Languages/po/nl.po
2934
Languages/po/nl.po
File diff suppressed because it is too large
Load Diff
2871
Languages/po/pl.po
2871
Languages/po/pl.po
File diff suppressed because it is too large
Load Diff
2868
Languages/po/pt.po
2868
Languages/po/pt.po
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
2868
Languages/po/ro.po
2868
Languages/po/ro.po
File diff suppressed because it is too large
Load Diff
3498
Languages/po/ru.po
3498
Languages/po/ru.po
File diff suppressed because it is too large
Load Diff
2868
Languages/po/sr.po
2868
Languages/po/sr.po
File diff suppressed because it is too large
Load Diff
2884
Languages/po/sv.po
2884
Languages/po/sv.po
File diff suppressed because it is too large
Load Diff
2937
Languages/po/tr.po
2937
Languages/po/tr.po
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -381,15 +381,9 @@ public final class NativeLibrary
|
|||
*/
|
||||
public static native boolean IsRunning();
|
||||
|
||||
/**
|
||||
* Returns true if emulation is running and not paused.
|
||||
*/
|
||||
public static native boolean IsRunningAndUnpaused();
|
||||
public static native boolean IsRunningAndStarted();
|
||||
|
||||
/**
|
||||
* Returns true if emulation is fully shut down.
|
||||
*/
|
||||
public static native boolean IsUninitialized();
|
||||
public static native boolean IsRunningAndUnpaused();
|
||||
|
||||
/**
|
||||
* Writes out the JitBlock Cache log dump
|
||||
|
|
|
@ -36,7 +36,7 @@ class Settings : Closeable {
|
|||
|
||||
if (isGameSpecific) {
|
||||
// Loading game INIs while the core is running will mess with the game INIs loaded by the core
|
||||
check(NativeLibrary.IsUninitialized()) { "Attempted to load game INI while emulating" }
|
||||
check(!NativeLibrary.IsRunning()) { "Attempted to load game INI while emulating" }
|
||||
NativeConfig.loadGameInis(gameId, revision)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,5 +20,5 @@ class RunRunnable(
|
|||
override val setting: AbstractSetting? = null
|
||||
|
||||
override val isEditable: Boolean
|
||||
get() = worksDuringEmulation || NativeLibrary.IsUninitialized()
|
||||
get() = worksDuringEmulation || !NativeLibrary.IsRunning()
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ abstract class SettingsItem {
|
|||
|
||||
open val isEditable: Boolean
|
||||
get() {
|
||||
if (NativeLibrary.IsUninitialized()) return true
|
||||
if (!NativeLibrary.IsRunning()) return true
|
||||
val setting = setting
|
||||
return setting != null && setting.isRuntimeEditable
|
||||
}
|
||||
|
|
|
@ -69,7 +69,7 @@ class SettingsFragmentPresenter(
|
|||
} else if (
|
||||
menuTag == MenuTag.GRAPHICS
|
||||
&& this.gameId.isNullOrEmpty()
|
||||
&& NativeLibrary.IsUninitialized()
|
||||
&& !NativeLibrary.IsRunning()
|
||||
&& GpuDriverHelper.supportsCustomDriverLoading()
|
||||
) {
|
||||
this.gpuDriver =
|
||||
|
@ -1303,7 +1303,7 @@ class SettingsFragmentPresenter(
|
|||
|
||||
if (
|
||||
this.gpuDriver != null && this.gameId.isNullOrEmpty()
|
||||
&& NativeLibrary.IsUninitialized()
|
||||
&& !NativeLibrary.IsRunning()
|
||||
&& GpuDriverHelper.supportsCustomDriverLoading()
|
||||
) {
|
||||
sl.add(
|
||||
|
|
|
@ -180,11 +180,11 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
|||
|
||||
private fun run(isActivityRecreated: Boolean) {
|
||||
if (isActivityRecreated) {
|
||||
if (NativeLibrary.IsUninitialized()) {
|
||||
loadPreviousTemporaryState = true
|
||||
} else {
|
||||
if (NativeLibrary.IsRunning()) {
|
||||
loadPreviousTemporaryState = false
|
||||
deleteFile(temporaryStateFilePath)
|
||||
} else {
|
||||
loadPreviousTemporaryState = true
|
||||
}
|
||||
} else {
|
||||
Log.debug("[EmulationFragment] activity resumed or fresh start")
|
||||
|
@ -203,7 +203,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
|||
|
||||
private fun runWithValidSurface() {
|
||||
runWhenSurfaceIsValid = false
|
||||
if (NativeLibrary.IsUninitialized()) {
|
||||
if (!NativeLibrary.IsRunning()) {
|
||||
NativeLibrary.SetIsBooting()
|
||||
val emulationThread = Thread({
|
||||
if (loadPreviousTemporaryState) {
|
||||
|
|
|
@ -83,7 +83,7 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex
|
|||
|
||||
fun initTouchPointer() {
|
||||
// Check if we have all the data we need yet
|
||||
val aspectRatioAvailable = NativeLibrary.IsRunning()
|
||||
val aspectRatioAvailable = NativeLibrary.IsRunningAndStarted()
|
||||
if (!aspectRatioAvailable || surfacePosition == null)
|
||||
return
|
||||
|
||||
|
|
|
@ -874,7 +874,7 @@ It can efficiently compress both junk data and encrypted Wii data.
|
|||
<string name="about_website"><a href="https://dolphin-emu.org/">Website</a></string>
|
||||
<string name="about_github"><a href="https://github.com/dolphin-emu/dolphin">GitHub</a></string>
|
||||
<string name="about_support"><a href="https://forums.dolphin-emu.org/">Support</a></string>
|
||||
<string name="about_copyright_warning">\u00A9 2003–2015+ Dolphin Team. \u201cGameCube\u201d and \u201cWii\u201d are trademarks of Nintendo. Dolphin is not affiliated with Nintendo in any way.</string>
|
||||
<string name="about_copyright_warning">\u00A9 2003–2024+ Dolphin Team. \u201cGameCube\u201d and \u201cWii\u201d are trademarks of Nintendo. Dolphin is not affiliated with Nintendo in any way.</string>
|
||||
<string name="system_driver">System driver</string>
|
||||
<string name="system_driver_desc">The GPU driver that is part of the OS.</string>
|
||||
|
||||
|
|
|
@ -118,7 +118,8 @@ void Host_Message(HostMessageID id)
|
|||
}
|
||||
else if (id == HostMessageID::WMUserStop)
|
||||
{
|
||||
Core::QueueHostJob(&Core::Stop);
|
||||
if (Core::IsRunning(Core::System::GetInstance()))
|
||||
Core::QueueHostJob(&Core::Stop);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -275,6 +276,13 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SetIsBooting
|
|||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_IsRunning(JNIEnv*, jclass)
|
||||
{
|
||||
return s_is_booting.IsSet() ||
|
||||
static_cast<jboolean>(Core::IsRunning(Core::System::GetInstance()));
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_IsRunningAndStarted(JNIEnv*,
|
||||
jclass)
|
||||
{
|
||||
return static_cast<jboolean>(Core::IsRunning(Core::System::GetInstance()));
|
||||
}
|
||||
|
@ -285,13 +293,6 @@ Java_org_dolphinemu_dolphinemu_NativeLibrary_IsRunningAndUnpaused(JNIEnv*, jclas
|
|||
return static_cast<jboolean>(Core::GetState(Core::System::GetInstance()) == Core::State::Running);
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_IsUninitialized(JNIEnv*,
|
||||
jclass)
|
||||
{
|
||||
return static_cast<jboolean>(Core::IsUninitialized(Core::System::GetInstance()) &&
|
||||
!s_is_booting.IsSet());
|
||||
}
|
||||
|
||||
JNIEXPORT jstring JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_GetVersionString(JNIEnv* env,
|
||||
jclass)
|
||||
{
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <rcheevos/include/rc_api_info.h>
|
||||
#include <rcheevos/include/rc_hash.h>
|
||||
|
||||
#include "Common/Assert.h"
|
||||
#include "Common/CommonPaths.h"
|
||||
#include "Common/FileUtil.h"
|
||||
#include "Common/Image.h"
|
||||
|
@ -22,6 +23,7 @@
|
|||
#include "Common/WorkQueueThread.h"
|
||||
#include "Core/Config/AchievementSettings.h"
|
||||
#include "Core/Core.h"
|
||||
#include "Core/HW/Memmap.h"
|
||||
#include "Core/PowerPC/MMU.h"
|
||||
#include "Core/System.h"
|
||||
#include "DiscIO/Blob.h"
|
||||
|
@ -44,7 +46,7 @@ void AchievementManager::Init()
|
|||
LoadDefaultBadges();
|
||||
if (!m_client && Config::Get(Config::RA_ENABLED))
|
||||
{
|
||||
m_client = rc_client_create(MemoryPeeker, Request);
|
||||
m_client = rc_client_create(MemoryVerifier, Request);
|
||||
std::string host_url = Config::Get(Config::RA_HOST_URL);
|
||||
if (!host_url.empty())
|
||||
rc_client_set_host(m_client, host_url.c_str());
|
||||
|
@ -120,6 +122,7 @@ void AchievementManager::LoadGame(const std::string& file_path, const DiscIO::Vo
|
|||
rc_client_set_unofficial_enabled(m_client, Config::Get(Config::RA_UNOFFICIAL_ENABLED));
|
||||
rc_client_set_encore_mode_enabled(m_client, Config::Get(Config::RA_ENCORE_ENABLED));
|
||||
rc_client_set_spectator_mode_enabled(m_client, Config::Get(Config::RA_SPECTATOR_ENABLED));
|
||||
rc_client_set_read_memory_function(m_client, MemoryVerifier);
|
||||
if (volume)
|
||||
{
|
||||
std::lock_guard lg{m_lock};
|
||||
|
@ -338,7 +341,7 @@ AchievementManager::RichPresence AchievementManager::GetRichPresence() const
|
|||
return m_rich_presence;
|
||||
}
|
||||
|
||||
const bool AchievementManager::AreChallengesUpdated() const
|
||||
bool AchievementManager::AreChallengesUpdated() const
|
||||
{
|
||||
return m_challenges_updated;
|
||||
}
|
||||
|
@ -679,13 +682,14 @@ void AchievementManager::LoadGameCallback(int result, const char* error_message,
|
|||
}
|
||||
INFO_LOG_FMT(ACHIEVEMENTS, "Loaded data for game ID {}.", game->id);
|
||||
|
||||
AchievementManager::GetInstance().m_display_welcome_message = true;
|
||||
AchievementManager::GetInstance().FetchGameBadges();
|
||||
AchievementManager::GetInstance().m_system = &Core::System::GetInstance();
|
||||
AchievementManager::GetInstance().m_update_callback({.all = true});
|
||||
auto& instance = AchievementManager::GetInstance();
|
||||
rc_client_set_read_memory_function(instance.m_client, MemoryPeeker);
|
||||
instance.m_display_welcome_message = true;
|
||||
instance.FetchGameBadges();
|
||||
instance.m_system = &Core::System::GetInstance();
|
||||
instance.m_update_callback({.all = true});
|
||||
// Set this to a value that will immediately trigger RP
|
||||
AchievementManager::GetInstance().m_last_rp_time =
|
||||
std::chrono::steady_clock::now() - std::chrono::minutes{2};
|
||||
instance.m_last_rp_time = std::chrono::steady_clock::now() - std::chrono::minutes{2};
|
||||
}
|
||||
|
||||
void AchievementManager::ChangeMediaCallback(int result, const char* error_message,
|
||||
|
@ -706,6 +710,7 @@ void AchievementManager::ChangeMediaCallback(int result, const char* error_messa
|
|||
|
||||
ERROR_LOG_FMT(ACHIEVEMENTS, "RetroAchievements media change failed: {}", error_message);
|
||||
}
|
||||
rc_client_set_read_memory_function(AchievementManager::GetInstance().m_client, MemoryPeeker);
|
||||
}
|
||||
|
||||
void AchievementManager::DisplayWelcomeMessage()
|
||||
|
@ -914,11 +919,36 @@ void AchievementManager::Request(const rc_api_request_t* request,
|
|||
});
|
||||
}
|
||||
|
||||
// Currently, when rc_client calls the memory peek method provided in its constructor (or in
|
||||
// rc_client_set_read_memory_function) it will do so on the thread that calls DoFrame, which is
|
||||
// currently the host thread, with one exception: an asynchronous callback in the load game process.
|
||||
// This is done to validate/invalidate each memory reference in the downloaded assets, mark assets
|
||||
// as unsupported, and notify the player upon startup that there are unsupported assets and how
|
||||
// many. As such, all that call needs to do is return the number of bytes that can be read with this
|
||||
// call. As only the CPU and host threads are allowed to read from memory, I provide a separate
|
||||
// method for this verification. In lieu of a more convenient set of steps, I provide MemoryVerifier
|
||||
// to rc_client at construction, and in the Load Game callback, after the verification has been
|
||||
// complete, I call rc_client_set_read_memory_function to switch to the usual MemoryPeeker for all
|
||||
// future synchronous calls.
|
||||
u32 AchievementManager::MemoryVerifier(u32 address, u8* buffer, u32 num_bytes, rc_client_t* client)
|
||||
{
|
||||
auto& system = Core::System::GetInstance();
|
||||
u32 ram_size = system.GetMemory().GetRamSizeReal();
|
||||
if (address >= ram_size)
|
||||
return 0;
|
||||
return std::min(ram_size - address, num_bytes);
|
||||
}
|
||||
|
||||
u32 AchievementManager::MemoryPeeker(u32 address, u8* buffer, u32 num_bytes, rc_client_t* client)
|
||||
{
|
||||
if (buffer == nullptr)
|
||||
return 0u;
|
||||
auto& system = Core::System::GetInstance();
|
||||
if (!(Core::IsHostThread() || Core::IsCPUThread()))
|
||||
{
|
||||
ASSERT_MSG(ACHIEVEMENTS, false, "MemoryPeeker called from wrong thread");
|
||||
return 0;
|
||||
}
|
||||
Core::CPUThreadGuard threadguard(system);
|
||||
for (u32 num_read = 0; num_read < num_bytes; num_read++)
|
||||
{
|
||||
|
|
|
@ -116,7 +116,7 @@ public:
|
|||
const Badge& GetAchievementBadge(AchievementId id, bool locked) const;
|
||||
const LeaderboardStatus* GetLeaderboardInfo(AchievementId leaderboard_id);
|
||||
RichPresence GetRichPresence() const;
|
||||
const bool AreChallengesUpdated() const;
|
||||
bool AreChallengesUpdated() const;
|
||||
void ResetChallengesUpdated();
|
||||
const std::unordered_set<AchievementId>& GetActiveChallenges() const;
|
||||
std::vector<std::string> GetActiveLeaderboards() const;
|
||||
|
@ -177,6 +177,7 @@ private:
|
|||
|
||||
static void Request(const rc_api_request_t* request, rc_client_server_callback_t callback,
|
||||
void* callback_data, rc_client_t* client);
|
||||
static u32 MemoryVerifier(u32 address, u8* buffer, u32 num_bytes, rc_client_t* client);
|
||||
static u32 MemoryPeeker(u32 address, u8* buffer, u32 num_bytes, rc_client_t* client);
|
||||
void FetchBadge(Badge* badge, u32 badge_type, const BadgeNameFunction function,
|
||||
const UpdatedItems callback_data);
|
||||
|
|
|
@ -33,7 +33,7 @@ namespace ConfigLoaders
|
|||
{
|
||||
void SaveToSYSCONF(Config::LayerType layer, std::function<bool(const Config::Location&)> predicate)
|
||||
{
|
||||
if (!Core::IsUninitialized(Core::System::GetInstance()))
|
||||
if (Core::IsRunning(Core::System::GetInstance()))
|
||||
return;
|
||||
|
||||
IOS::HLE::Kernel ios;
|
||||
|
@ -183,7 +183,7 @@ public:
|
|||
private:
|
||||
void LoadFromSYSCONF(Config::Layer* layer)
|
||||
{
|
||||
if (!Core::IsUninitialized(Core::System::GetInstance()))
|
||||
if (Core::IsRunning(Core::System::GetInstance()))
|
||||
return;
|
||||
|
||||
IOS::HLE::Kernel ios;
|
||||
|
|
|
@ -211,11 +211,6 @@ bool IsRunningOrStarting(Core::System& system)
|
|||
return state == State::Running || state == State::Starting;
|
||||
}
|
||||
|
||||
bool IsUninitialized(Core::System& system)
|
||||
{
|
||||
return s_state.load() == State::Uninitialized;
|
||||
}
|
||||
|
||||
bool IsCPUThread()
|
||||
{
|
||||
return tls_is_cpu_thread;
|
||||
|
@ -242,7 +237,7 @@ bool Init(Core::System& system, std::unique_ptr<BootParameters> boot, const Wind
|
|||
{
|
||||
if (s_emu_thread.joinable())
|
||||
{
|
||||
if (!IsUninitialized(system))
|
||||
if (IsRunning(system))
|
||||
{
|
||||
PanicAlertFmtT("Emu Thread already running");
|
||||
return false;
|
||||
|
|
|
@ -134,13 +134,8 @@ void UndeclareAsHostThread();
|
|||
|
||||
std::string StopMessage(bool main_thread, std::string_view message);
|
||||
|
||||
// Returns true when GetState returns Running or Paused.
|
||||
bool IsRunning(Core::System& system);
|
||||
// Returns true when GetState returns Starting, Running or Paused.
|
||||
bool IsRunningOrStarting(Core::System& system);
|
||||
// Returns true when GetState returns Uninitialized.
|
||||
bool IsUninitialized(Core::System& system);
|
||||
|
||||
bool IsCPUThread(); // this tells us whether we are the CPU thread.
|
||||
bool IsGPUThread();
|
||||
bool IsHostThread();
|
||||
|
|
|
@ -89,7 +89,7 @@ AboutDialog::AboutDialog(QWidget* parent) : QDialog(parent)
|
|||
// in your translation, please use the type of curly quotes that's appropriate for
|
||||
// your language. If you aren't sure which type is appropriate, see
|
||||
// https://en.wikipedia.org/wiki/Quotation_mark#Specific_language_features
|
||||
tr("\u00A9 2003-2015+ Dolphin Team. \u201cGameCube\u201d and \u201cWii\u201d are "
|
||||
tr("\u00A9 2003-2024+ Dolphin Team. \u201cGameCube\u201d and \u201cWii\u201d are "
|
||||
"trademarks of Nintendo. Dolphin is not affiliated with Nintendo in any way.")));
|
||||
|
||||
QLabel* logo = new QLabel();
|
||||
|
|
|
@ -4,10 +4,12 @@
|
|||
#ifdef USE_RETRO_ACHIEVEMENTS
|
||||
#include "DolphinQt/Achievements/AchievementBox.h"
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QDateTime>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QProgressBar>
|
||||
#include <QSizePolicy>
|
||||
#include <QVBoxLayout>
|
||||
#include <QWidget>
|
||||
|
||||
|
@ -30,9 +32,11 @@ AchievementBox::AchievementBox(QWidget* parent, rc_client_achievement_t* achieve
|
|||
m_badge = new QLabel();
|
||||
QLabel* title = new QLabel(QString::fromUtf8(achievement->title, strlen(achievement->title)));
|
||||
title->setWordWrap(true);
|
||||
title->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||
QLabel* description =
|
||||
new QLabel(QString::fromUtf8(achievement->description, strlen(achievement->description)));
|
||||
description->setWordWrap(true);
|
||||
description->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||
QLabel* points = new QLabel(tr("%1 points").arg(achievement->points));
|
||||
m_status = new QLabel();
|
||||
m_progress_bar = new QProgressBar();
|
||||
|
@ -61,39 +65,57 @@ AchievementBox::AchievementBox(QWidget* parent, rc_client_achievement_t* achieve
|
|||
}
|
||||
|
||||
void AchievementBox::UpdateData()
|
||||
{
|
||||
{
|
||||
std::lock_guard lg{AchievementManager::GetInstance().GetLock()};
|
||||
// rc_client guarantees m_achievement will be valid as long as the game is loaded
|
||||
if (!AchievementManager::GetInstance().IsGameLoaded())
|
||||
return;
|
||||
|
||||
const auto& badge = AchievementManager::GetInstance().GetAchievementBadge(
|
||||
m_achievement->id, m_achievement->state != RC_CLIENT_ACHIEVEMENT_STATE_UNLOCKED);
|
||||
std::string_view color = AchievementManager::GRAY;
|
||||
if (m_achievement->unlocked & RC_CLIENT_ACHIEVEMENT_UNLOCKED_HARDCORE)
|
||||
color = AchievementManager::GOLD;
|
||||
else if (m_achievement->unlocked & RC_CLIENT_ACHIEVEMENT_UNLOCKED_SOFTCORE)
|
||||
color = AchievementManager::BLUE;
|
||||
QImage i_badge(&badge.data.front(), badge.width, badge.height, QImage::Format_RGBA8888);
|
||||
m_badge->setPixmap(
|
||||
QPixmap::fromImage(i_badge).scaled(64, 64, Qt::KeepAspectRatio, Qt::SmoothTransformation));
|
||||
m_badge->adjustSize();
|
||||
m_badge->setStyleSheet(
|
||||
QStringLiteral("border: 4px solid %1").arg(QtUtils::FromStdString(color)));
|
||||
|
||||
if (m_achievement->state == RC_CLIENT_ACHIEVEMENT_STATE_UNLOCKED)
|
||||
{
|
||||
m_status->setText(
|
||||
tr("Unlocked at %1")
|
||||
.arg(QDateTime::fromSecsSinceEpoch(m_achievement->unlock_time).toString()));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_status->setText(tr("Locked"));
|
||||
}
|
||||
}
|
||||
|
||||
UpdateProgress();
|
||||
}
|
||||
|
||||
void AchievementBox::UpdateProgress()
|
||||
{
|
||||
std::lock_guard lg{AchievementManager::GetInstance().GetLock()};
|
||||
|
||||
const auto& badge = AchievementManager::GetInstance().GetAchievementBadge(
|
||||
m_achievement->id, m_achievement->state != RC_CLIENT_ACHIEVEMENT_STATE_UNLOCKED);
|
||||
std::string_view color = AchievementManager::GRAY;
|
||||
if (m_achievement->unlocked & RC_CLIENT_ACHIEVEMENT_UNLOCKED_HARDCORE)
|
||||
color = AchievementManager::GOLD;
|
||||
else if (m_achievement->unlocked & RC_CLIENT_ACHIEVEMENT_UNLOCKED_SOFTCORE)
|
||||
color = AchievementManager::BLUE;
|
||||
QImage i_badge(&badge.data.front(), badge.width, badge.height, QImage::Format_RGBA8888);
|
||||
m_badge->setPixmap(
|
||||
QPixmap::fromImage(i_badge).scaled(64, 64, Qt::KeepAspectRatio, Qt::SmoothTransformation));
|
||||
m_badge->adjustSize();
|
||||
m_badge->setStyleSheet(QStringLiteral("border: 4px solid %1").arg(QtUtils::FromStdString(color)));
|
||||
|
||||
if (m_achievement->state == RC_CLIENT_ACHIEVEMENT_STATE_UNLOCKED)
|
||||
{
|
||||
m_status->setText(
|
||||
tr("Unlocked at %1")
|
||||
.arg(QDateTime::fromSecsSinceEpoch(m_achievement->unlock_time).toString()));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_status->setText(tr("Locked"));
|
||||
}
|
||||
// rc_client guarantees m_achievement will be valid as long as the game is loaded
|
||||
if (!AchievementManager::GetInstance().IsGameLoaded())
|
||||
return;
|
||||
|
||||
if (m_achievement->measured_percent > 0.000)
|
||||
{
|
||||
m_progress_bar->setRange(0, 100);
|
||||
m_progress_bar->setValue(m_achievement->measured_percent);
|
||||
m_progress_bar->setTextVisible(false);
|
||||
m_progress_label->setText(QString::fromUtf8(m_achievement->measured_progress, PROGRESS_LENGTH));
|
||||
m_progress_label->setText(
|
||||
QString::fromUtf8(m_achievement->measured_progress,
|
||||
qstrnlen(m_achievement->measured_progress, PROGRESS_LENGTH)));
|
||||
m_progress_bar->setVisible(true);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -20,6 +20,7 @@ class AchievementBox final : public QGroupBox
|
|||
public:
|
||||
explicit AchievementBox(QWidget* parent, rc_client_achievement_t* achievement);
|
||||
void UpdateData();
|
||||
void UpdateProgress();
|
||||
|
||||
private:
|
||||
QLabel* m_badge;
|
||||
|
|
|
@ -57,8 +57,10 @@ void AchievementLeaderboardWidget::UpdateData(bool clean_all)
|
|||
m_leaderboard_order[leaderboard->id] = row;
|
||||
QLabel* a_title = new QLabel(QString::fromUtf8(leaderboard->title));
|
||||
a_title->setWordWrap(true);
|
||||
a_title->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||
QLabel* a_description = new QLabel(QString::fromUtf8(leaderboard->description));
|
||||
a_description->setWordWrap(true);
|
||||
a_description->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||
QVBoxLayout* a_col_left = new QVBoxLayout();
|
||||
a_col_left->addWidget(a_title);
|
||||
a_col_left->addWidget(a_description);
|
||||
|
|
|
@ -42,33 +42,51 @@ void AchievementProgressWidget::UpdateData(bool clean_all)
|
|||
{
|
||||
m_achievement_boxes.clear();
|
||||
ClearLayoutRecursively(m_common_layout);
|
||||
|
||||
auto& instance = AchievementManager::GetInstance();
|
||||
if (!instance.IsGameLoaded())
|
||||
return;
|
||||
auto* client = instance.GetClient();
|
||||
auto* achievement_list = rc_client_create_achievement_list(
|
||||
client, RC_CLIENT_ACHIEVEMENT_CATEGORY_CORE_AND_UNOFFICIAL,
|
||||
RC_CLIENT_ACHIEVEMENT_LIST_GROUPING_PROGRESS);
|
||||
for (u32 ix = 0; ix < achievement_list->num_buckets; ix++)
|
||||
{
|
||||
m_common_layout->addWidget(new QLabel(tr(achievement_list->buckets[ix].label)));
|
||||
for (u32 jx = 0; jx < achievement_list->buckets[ix].num_achievements; jx++)
|
||||
{
|
||||
auto* achievement = achievement_list->buckets[ix].achievements[jx];
|
||||
m_achievement_boxes[achievement->id] = std::make_shared<AchievementBox>(this, achievement);
|
||||
m_common_layout->addWidget(m_achievement_boxes[achievement->id].get());
|
||||
}
|
||||
}
|
||||
rc_client_destroy_achievement_list(achievement_list);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (auto box : m_achievement_boxes)
|
||||
while (auto* item = m_common_layout->takeAt(0))
|
||||
{
|
||||
box.second->UpdateData();
|
||||
auto* widget = item->widget();
|
||||
m_common_layout->removeWidget(widget);
|
||||
if (std::strcmp(widget->metaObject()->className(), "QLabel") == 0)
|
||||
{
|
||||
widget->deleteLater();
|
||||
delete item;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto& instance = AchievementManager::GetInstance();
|
||||
if (!instance.IsGameLoaded())
|
||||
return;
|
||||
auto* client = instance.GetClient();
|
||||
auto* achievement_list =
|
||||
rc_client_create_achievement_list(client, RC_CLIENT_ACHIEVEMENT_CATEGORY_CORE_AND_UNOFFICIAL,
|
||||
RC_CLIENT_ACHIEVEMENT_LIST_GROUPING_PROGRESS);
|
||||
if (!achievement_list)
|
||||
return;
|
||||
for (u32 ix = 0; ix < achievement_list->num_buckets; ix++)
|
||||
{
|
||||
m_common_layout->addWidget(new QLabel(tr(achievement_list->buckets[ix].label)));
|
||||
for (u32 jx = 0; jx < achievement_list->buckets[ix].num_achievements; jx++)
|
||||
{
|
||||
auto* achievement = achievement_list->buckets[ix].achievements[jx];
|
||||
auto box_itr = m_achievement_boxes.lower_bound(achievement->id);
|
||||
if (box_itr != m_achievement_boxes.end() && box_itr->first == achievement->id)
|
||||
{
|
||||
box_itr->second->UpdateProgress();
|
||||
m_common_layout->addWidget(box_itr->second.get());
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto new_box_itr = m_achievement_boxes.try_emplace(
|
||||
box_itr, achievement->id, std::make_shared<AchievementBox>(this, achievement));
|
||||
m_common_layout->addWidget(new_box_itr->second.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
rc_client_destroy_achievement_list(achievement_list);
|
||||
}
|
||||
|
||||
void AchievementProgressWidget::UpdateData(
|
||||
|
|
|
@ -159,8 +159,6 @@ void AchievementSettingsWidget::OnControllerInterfaceConfigure()
|
|||
|
||||
void AchievementSettingsWidget::LoadSettings()
|
||||
{
|
||||
Core::System& system = Core::System::GetInstance();
|
||||
|
||||
bool enabled = Config::Get(Config::RA_ENABLED);
|
||||
bool hardcore_enabled = Config::Get(Config::RA_HARDCORE_ENABLED);
|
||||
bool logged_out = Config::Get(Config::RA_API_TOKEN).empty();
|
||||
|
@ -176,15 +174,18 @@ void AchievementSettingsWidget::LoadSettings()
|
|||
SignalBlocking(m_common_password_input)->setVisible(logged_out);
|
||||
SignalBlocking(m_common_password_input)->setEnabled(enabled);
|
||||
SignalBlocking(m_common_login_button)->setVisible(logged_out);
|
||||
SignalBlocking(m_common_login_button)->setEnabled(enabled && Core::IsUninitialized(system));
|
||||
SignalBlocking(m_common_login_button)
|
||||
->setEnabled(enabled && !Core::IsRunning(Core::System::GetInstance()));
|
||||
SignalBlocking(m_common_logout_button)->setVisible(!logged_out);
|
||||
SignalBlocking(m_common_logout_button)->setEnabled(enabled);
|
||||
|
||||
SignalBlocking(m_common_hardcore_enabled_input)
|
||||
->setChecked(Config::Get(Config::RA_HARDCORE_ENABLED));
|
||||
auto& system = Core::System::GetInstance();
|
||||
SignalBlocking(m_common_hardcore_enabled_input)
|
||||
->setEnabled(enabled && (hardcore_enabled || (Core::IsUninitialized(system) &&
|
||||
!system.GetMovie().IsPlayingInput())));
|
||||
->setEnabled(enabled &&
|
||||
(hardcore_enabled || (Core::GetState(system) == Core::State::Uninitialized &&
|
||||
!system.GetMovie().IsPlayingInput())));
|
||||
|
||||
SignalBlocking(m_common_unofficial_enabled_input)
|
||||
->setChecked(Config::Get(Config::RA_UNOFFICIAL_ENABLED));
|
||||
|
@ -236,7 +237,10 @@ void AchievementSettingsWidget::ToggleRAIntegration()
|
|||
else
|
||||
instance.Shutdown();
|
||||
if (Config::Get(Config::RA_HARDCORE_ENABLED))
|
||||
{
|
||||
emit Settings::Instance().EmulationStateChanged(Core::GetState(Core::System::GetInstance()));
|
||||
emit Settings::Instance().HardcoreStateChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void AchievementSettingsWidget::Login()
|
||||
|
@ -266,6 +270,7 @@ void AchievementSettingsWidget::ToggleHardcore()
|
|||
Settings::Instance().SetDebugModeEnabled(false);
|
||||
}
|
||||
emit Settings::Instance().EmulationStateChanged(Core::GetState(Core::System::GetInstance()));
|
||||
emit Settings::Instance().HardcoreStateChanged();
|
||||
}
|
||||
|
||||
void AchievementSettingsWidget::ToggleUnofficial()
|
||||
|
|
|
@ -34,6 +34,8 @@ AchievementsWindow::AchievementsWindow(QWidget* parent) : QDialog(parent)
|
|||
});
|
||||
});
|
||||
connect(&Settings::Instance(), &Settings::EmulationStateChanged, this,
|
||||
[this] { m_settings_widget->UpdateData(); });
|
||||
connect(&Settings::Instance(), &Settings::HardcoreStateChanged, this,
|
||||
[this] { AchievementsWindow::UpdateData({.all = true}); });
|
||||
}
|
||||
|
||||
|
@ -89,7 +91,7 @@ void AchievementsWindow::UpdateData(AchievementManager::UpdatedItems updated_ite
|
|||
{
|
||||
m_header_widget->UpdateData();
|
||||
}
|
||||
if (updated_items.all_achievements)
|
||||
if (updated_items.all_achievements || updated_items.rich_presence)
|
||||
m_progress_widget->UpdateData(false);
|
||||
else if (updated_items.achievements.size() > 0)
|
||||
m_progress_widget->UpdateData(updated_items.achievements);
|
||||
|
|
|
@ -348,6 +348,8 @@ add_executable(dolphin-emu
|
|||
Settings/GeneralPane.h
|
||||
Settings/InterfacePane.cpp
|
||||
Settings/InterfacePane.h
|
||||
Settings/MiscPane.cpp
|
||||
Settings/MiscPane.h
|
||||
Settings/PathPane.cpp
|
||||
Settings/PathPane.h
|
||||
Settings/USBDeviceAddToWhitelistDialog.cpp
|
||||
|
|
|
@ -159,7 +159,8 @@ void CheatSearchFactoryWidget::OnNewSearchClicked()
|
|||
if (m_standard_address_space->isChecked())
|
||||
{
|
||||
auto& system = Core::System::GetInstance();
|
||||
if (!Core::IsRunning(system))
|
||||
const Core::State core_state = Core::GetState(system);
|
||||
if (core_state != Core::State::Running && core_state != Core::State::Paused)
|
||||
{
|
||||
ModalMessageBox::warning(
|
||||
this, tr("No game running."),
|
||||
|
|
|
@ -104,9 +104,8 @@ void CheatsManager::RefreshCodeTabs(Core::State state, bool force)
|
|||
if (!force && (state == Core::State::Starting || state == Core::State::Stopping))
|
||||
return;
|
||||
|
||||
const auto& game_id = state == Core::State::Running || state == Core::State::Paused ?
|
||||
SConfig::GetInstance().GetGameID() :
|
||||
std::string();
|
||||
const auto& game_id =
|
||||
state != Core::State::Uninitialized ? SConfig::GetInstance().GetGameID() : std::string();
|
||||
const auto& game_tdb_id = SConfig::GetInstance().GetGameTDBID();
|
||||
const u16 revision = SConfig::GetInstance().GetRevision();
|
||||
|
||||
|
|
|
@ -24,9 +24,8 @@ CheatWarningWidget::CheatWarningWidget(const std::string& game_id, bool restart_
|
|||
|
||||
connect(&Settings::Instance(), &Settings::EnableCheatsChanged, this,
|
||||
[this] { Update(Core::IsRunning(Core::System::GetInstance())); });
|
||||
connect(&Settings::Instance(), &Settings::EmulationStateChanged, this, [this](Core::State state) {
|
||||
Update(state == Core::State::Running || state == Core::State::Paused);
|
||||
});
|
||||
connect(&Settings::Instance(), &Settings::EmulationStateChanged, this,
|
||||
[this](Core::State state) { Update(state == Core::State::Running); });
|
||||
|
||||
Update(Core::IsRunning(Core::System::GetInstance()));
|
||||
}
|
||||
|
|
|
@ -43,7 +43,8 @@ AdvancedWidget::AdvancedWidget(GraphicsWindow* parent)
|
|||
});
|
||||
|
||||
OnBackendChanged();
|
||||
OnEmulationStateChanged(!Core::IsUninitialized(Core::System::GetInstance()));
|
||||
OnEmulationStateChanged(Core::GetState(Core::System::GetInstance()) !=
|
||||
Core::State::Uninitialized);
|
||||
}
|
||||
|
||||
void AdvancedWidget::CreateWidgets()
|
||||
|
|
|
@ -44,7 +44,8 @@ GeneralWidget::GeneralWidget(GraphicsWindow* parent)
|
|||
connect(&Settings::Instance(), &Settings::EmulationStateChanged, this, [this](Core::State state) {
|
||||
OnEmulationStateChanged(state != Core::State::Uninitialized);
|
||||
});
|
||||
OnEmulationStateChanged(!Core::IsUninitialized(Core::System::GetInstance()));
|
||||
OnEmulationStateChanged(Core::GetState(Core::System::GetInstance()) !=
|
||||
Core::State::Uninitialized);
|
||||
}
|
||||
|
||||
void GeneralWidget::CreateWidgets()
|
||||
|
@ -360,8 +361,7 @@ void GeneralWidget::OnBackendChanged(const QString& backend_name)
|
|||
const bool supports_adapters = !adapters.empty();
|
||||
|
||||
m_adapter_combo->setCurrentIndex(g_Config.iAdapter);
|
||||
m_adapter_combo->setEnabled(supports_adapters &&
|
||||
Core::IsUninitialized(Core::System::GetInstance()));
|
||||
m_adapter_combo->setEnabled(supports_adapters && !Core::IsRunning(Core::System::GetInstance()));
|
||||
|
||||
static constexpr char TR_ADAPTER_AVAILABLE_DESCRIPTION[] =
|
||||
QT_TR_NOOP("Selects a hardware adapter to use.<br><br>"
|
||||
|
|
|
@ -59,8 +59,6 @@
|
|||
#include "InputCommon/ControllerInterface/CoreDevice.h"
|
||||
#include "InputCommon/InputConfig.h"
|
||||
|
||||
constexpr const char* PROFILES_DIR = "Profiles/";
|
||||
|
||||
MappingWindow::MappingWindow(QWidget* parent, Type type, int port_num)
|
||||
: QDialog(parent), m_port(port_num)
|
||||
{
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "DolphinQt/Settings/GameCubePane.h"
|
||||
#include "DolphinQt/Settings/GeneralPane.h"
|
||||
#include "DolphinQt/Settings/InterfacePane.h"
|
||||
#include "DolphinQt/Settings/MiscPane.h"
|
||||
#include "DolphinQt/Settings/PathPane.h"
|
||||
#include "DolphinQt/Settings/WiiPane.h"
|
||||
|
||||
|
@ -40,6 +41,7 @@ SettingsWindow::SettingsWindow(QWidget* parent) : QDialog(parent)
|
|||
m_tab_widget->addTab(GetWrappedWidget(new PathPane, this, 125, 100), tr("Paths"));
|
||||
m_tab_widget->addTab(GetWrappedWidget(new GameCubePane, this, 125, 100), tr("GameCube"));
|
||||
m_tab_widget->addTab(GetWrappedWidget(new WiiPane, this, 125, 100), tr("Wii"));
|
||||
m_tab_widget->addTab(GetWrappedWidget(new MiscPane, this, 125, 200), tr("Misc"));
|
||||
m_tab_widget->addTab(GetWrappedWidget(new AdvancedPane, this, 125, 200), tr("Advanced"));
|
||||
|
||||
// Dialog box buttons
|
||||
|
|
|
@ -791,7 +791,7 @@ bool AssemblerWidget::SaveEditor(AsmEditor* editor)
|
|||
|
||||
void AssemblerWidget::OnEmulationStateChanged(Core::State state)
|
||||
{
|
||||
m_inject->setEnabled(state == Core::State::Running || state == Core::State::Paused);
|
||||
m_inject->setEnabled(state != Core::State::Uninitialized);
|
||||
}
|
||||
|
||||
void AssemblerWidget::OnTabClose(int index)
|
||||
|
|
|
@ -251,7 +251,7 @@ void BreakpointWidget::UpdateButtonsEnabled()
|
|||
if (!isVisible())
|
||||
return;
|
||||
|
||||
const bool is_initialised = Core::IsRunning(m_system);
|
||||
const bool is_initialised = Core::GetState(m_system) != Core::State::Uninitialized;
|
||||
m_new->setEnabled(is_initialised);
|
||||
m_load->setEnabled(is_initialised);
|
||||
m_save->setEnabled(is_initialised);
|
||||
|
|
|
@ -560,7 +560,7 @@ void CodeViewWidget::OnContextMenu()
|
|||
QMenu* menu = new QMenu(this);
|
||||
menu->setAttribute(Qt::WA_DeleteOnClose, true);
|
||||
|
||||
const bool running = Core::IsRunning(m_system);
|
||||
const bool running = Core::GetState(m_system) != Core::State::Uninitialized;
|
||||
const bool paused = Core::GetState(m_system) == Core::State::Paused;
|
||||
|
||||
const u32 addr = GetContextAddress();
|
||||
|
|
|
@ -258,7 +258,7 @@ void ThreadWidget::Update()
|
|||
|
||||
auto& system = Core::System::GetInstance();
|
||||
const auto emu_state = Core::GetState(system);
|
||||
if (emu_state == Core::State::Stopping || emu_state == Core::State::Uninitialized)
|
||||
if (emu_state == Core::State::Stopping)
|
||||
{
|
||||
m_thread_table->setRowCount(0);
|
||||
UpdateThreadContext({});
|
||||
|
|
|
@ -195,11 +195,10 @@ void WatchWidget::Update()
|
|||
|
||||
QBrush brush = QPalette().brush(QPalette::Text);
|
||||
|
||||
const bool core_is_running = Core::IsRunning(m_system);
|
||||
if (!core_is_running || !PowerPC::MMU::HostIsRAMAddress(guard, entry.address))
|
||||
if (!Core::IsRunning(m_system) || !PowerPC::MMU::HostIsRAMAddress(guard, entry.address))
|
||||
brush.setColor(Qt::red);
|
||||
|
||||
if (core_is_running)
|
||||
if (Core::IsRunning(m_system))
|
||||
{
|
||||
if (PowerPC::MMU::HostIsRAMAddress(guard, entry.address))
|
||||
{
|
||||
|
|
|
@ -212,6 +212,7 @@
|
|||
<ClCompile Include="Settings\GameCubePane.cpp" />
|
||||
<ClCompile Include="Settings\GeneralPane.cpp" />
|
||||
<ClCompile Include="Settings\InterfacePane.cpp" />
|
||||
<ClCompile Include="Settings\MiscPane.cpp" />
|
||||
<ClCompile Include="Settings\PathPane.cpp" />
|
||||
<ClCompile Include="Settings\USBDeviceAddToWhitelistDialog.cpp" />
|
||||
<ClCompile Include="Settings\WiiPane.cpp" />
|
||||
|
@ -414,6 +415,7 @@
|
|||
<QtMoc Include="Settings\GameCubePane.h" />
|
||||
<QtMoc Include="Settings\GeneralPane.h" />
|
||||
<QtMoc Include="Settings\InterfacePane.h" />
|
||||
<QtMoc Include="Settings\MiscPane.h" />
|
||||
<QtMoc Include="Settings\PathPane.h" />
|
||||
<QtMoc Include="Settings\USBDeviceAddToWhitelistDialog.h" />
|
||||
<QtMoc Include="Settings\WiiPane.h" />
|
||||
|
|
|
@ -59,14 +59,11 @@ FIFOPlayerWindow::FIFOPlayerWindow(FifoPlayer& fifo_player, FifoRecorder& fifo_r
|
|||
});
|
||||
|
||||
connect(&Settings::Instance(), &Settings::EmulationStateChanged, this, [this](Core::State state) {
|
||||
if (state != m_emu_state)
|
||||
{
|
||||
if (state == Core::State::Running && m_emu_state != Core::State::Paused)
|
||||
OnEmulationStarted();
|
||||
else if (state == Core::State::Uninitialized)
|
||||
OnEmulationStopped();
|
||||
m_emu_state = state;
|
||||
}
|
||||
if (state == Core::State::Running && m_emu_state != Core::State::Paused)
|
||||
OnEmulationStarted();
|
||||
else if (state == Core::State::Uninitialized)
|
||||
OnEmulationStopped();
|
||||
m_emu_state = state;
|
||||
});
|
||||
|
||||
installEventFilter(this);
|
||||
|
@ -379,11 +376,9 @@ void FIFOPlayerWindow::UpdateLimits()
|
|||
|
||||
void FIFOPlayerWindow::UpdateControls()
|
||||
{
|
||||
Core::System& system = Core::System::GetInstance();
|
||||
const bool core_is_uninitialized = Core::IsUninitialized(system);
|
||||
const bool core_is_running = Core::IsRunning(system);
|
||||
const bool is_recording = m_fifo_recorder.IsRecording();
|
||||
const bool is_playing = m_fifo_player.IsPlaying();
|
||||
bool running = Core::IsRunning(Core::System::GetInstance());
|
||||
bool is_recording = m_fifo_recorder.IsRecording();
|
||||
bool is_playing = m_fifo_player.IsPlaying();
|
||||
|
||||
m_frame_range_from->setEnabled(is_playing);
|
||||
m_frame_range_from_label->setEnabled(is_playing);
|
||||
|
@ -399,10 +394,10 @@ void FIFOPlayerWindow::UpdateControls()
|
|||
m_frame_record_count_label->setEnabled(enable_frame_record_count);
|
||||
m_frame_record_count->setEnabled(enable_frame_record_count);
|
||||
|
||||
m_load->setEnabled(core_is_uninitialized);
|
||||
m_record->setEnabled(core_is_running && !is_playing);
|
||||
m_load->setEnabled(!running);
|
||||
m_record->setEnabled(running && !is_playing);
|
||||
|
||||
m_stop->setVisible(core_is_running && is_recording);
|
||||
m_stop->setVisible(running && is_recording);
|
||||
m_record->setVisible(!m_stop->isVisible());
|
||||
|
||||
m_save->setEnabled(m_fifo_recorder.IsRecordingDone());
|
||||
|
|
|
@ -299,16 +299,14 @@ void GameList::MakeEmptyView()
|
|||
size_policy.setRetainSizeWhenHidden(true);
|
||||
m_empty->setSizePolicy(size_policy);
|
||||
|
||||
connect(&Settings::Instance(), &Settings::GameListRefreshRequested, this,
|
||||
[this, refreshing_msg = refreshing_msg] {
|
||||
m_empty->setText(refreshing_msg);
|
||||
m_empty->setEnabled(false);
|
||||
});
|
||||
connect(&Settings::Instance(), &Settings::GameListRefreshCompleted, this,
|
||||
[this, empty_msg = empty_msg] {
|
||||
m_empty->setText(empty_msg);
|
||||
m_empty->setEnabled(true);
|
||||
});
|
||||
connect(&Settings::Instance(), &Settings::GameListRefreshRequested, this, [this, refreshing_msg] {
|
||||
m_empty->setText(refreshing_msg);
|
||||
m_empty->setEnabled(false);
|
||||
});
|
||||
connect(&Settings::Instance(), &Settings::GameListRefreshCompleted, this, [this, empty_msg] {
|
||||
m_empty->setText(empty_msg);
|
||||
m_empty->setEnabled(true);
|
||||
});
|
||||
}
|
||||
|
||||
void GameList::resizeEvent(QResizeEvent* event)
|
||||
|
@ -438,7 +436,7 @@ void GameList::ShowContextMenu(const QPoint&)
|
|||
// system menu, trigger a refresh.
|
||||
Settings::Instance().NANDRefresh();
|
||||
});
|
||||
perform_disc_update->setEnabled(Core::IsUninitialized(system) || !system.IsWii());
|
||||
perform_disc_update->setEnabled(!Core::IsRunning(system) || !system.IsWii());
|
||||
}
|
||||
|
||||
if (!is_mod_descriptor && platform == DiscIO::Platform::WiiWAD)
|
||||
|
@ -451,10 +449,10 @@ void GameList::ShowContextMenu(const QPoint&)
|
|||
|
||||
for (QAction* a : {wad_install_action, wad_uninstall_action})
|
||||
{
|
||||
a->setEnabled(Core::IsUninitialized(system));
|
||||
a->setEnabled(!Core::IsRunning(system));
|
||||
menu->addAction(a);
|
||||
}
|
||||
if (Core::IsUninitialized(system))
|
||||
if (!Core::IsRunning(system))
|
||||
wad_uninstall_action->setEnabled(WiiUtils::IsTitleInstalled(game->GetTitleID()));
|
||||
|
||||
connect(&Settings::Instance(), &Settings::EmulationStateChanged, menu,
|
||||
|
@ -475,8 +473,8 @@ void GameList::ShowContextMenu(const QPoint&)
|
|||
QAction* export_wii_save =
|
||||
menu->addAction(tr("Export Wii Save"), this, &GameList::ExportWiiSave);
|
||||
|
||||
open_wii_save_folder->setEnabled(Core::IsUninitialized(system));
|
||||
export_wii_save->setEnabled(Core::IsUninitialized(system));
|
||||
open_wii_save_folder->setEnabled(!Core::IsRunning(system));
|
||||
export_wii_save->setEnabled(!Core::IsRunning(system));
|
||||
|
||||
menu->addSeparator();
|
||||
}
|
||||
|
@ -533,7 +531,7 @@ void GameList::ShowContextMenu(const QPoint&)
|
|||
connect(&Settings::Instance(), &Settings::EmulationStateChanged, menu, [=](Core::State state) {
|
||||
netplay_host->setEnabled(state == Core::State::Uninitialized);
|
||||
});
|
||||
netplay_host->setEnabled(Core::IsUninitialized(system));
|
||||
netplay_host->setEnabled(!Core::IsRunning(system));
|
||||
|
||||
menu->addAction(netplay_host);
|
||||
}
|
||||
|
|
|
@ -188,7 +188,7 @@ void HotkeyScheduler::Run()
|
|||
if (IsHotkey(HK_EXIT))
|
||||
emit ExitHotkey();
|
||||
|
||||
if (Core::IsUninitialized(system))
|
||||
if (!Core::IsRunning(system))
|
||||
{
|
||||
// Only check for Play Recording hotkey when no game is running
|
||||
if (IsHotkey(HK_PLAY_RECORDING))
|
||||
|
|
|
@ -905,7 +905,7 @@ void MainWindow::OnStopComplete()
|
|||
|
||||
bool MainWindow::RequestStop()
|
||||
{
|
||||
if (Core::IsUninitialized(Core::System::GetInstance()))
|
||||
if (!Core::IsRunning(Core::System::GetInstance()))
|
||||
{
|
||||
Core::QueueHostJob([this](Core::System&) { OnStopComplete(); }, true);
|
||||
return true;
|
||||
|
@ -1112,7 +1112,7 @@ void MainWindow::StartGame(std::unique_ptr<BootParameters>&& parameters)
|
|||
}
|
||||
|
||||
// If we're running, only start a new game once we've stopped the last.
|
||||
if (!Core::IsUninitialized(Core::System::GetInstance()))
|
||||
if (Core::GetState(Core::System::GetInstance()) != Core::State::Uninitialized)
|
||||
{
|
||||
if (!RequestStop())
|
||||
return;
|
||||
|
@ -1536,7 +1536,7 @@ void MainWindow::NetPlayInit()
|
|||
|
||||
bool MainWindow::NetPlayJoin()
|
||||
{
|
||||
if (!Core::IsUninitialized(Core::System::GetInstance()))
|
||||
if (Core::IsRunning(Core::System::GetInstance()))
|
||||
{
|
||||
ModalMessageBox::critical(nullptr, tr("Error"),
|
||||
tr("Can't start a NetPlay Session while a game is still running!"));
|
||||
|
@ -1603,7 +1603,7 @@ bool MainWindow::NetPlayJoin()
|
|||
|
||||
bool MainWindow::NetPlayHost(const UICommon::GameFile& game)
|
||||
{
|
||||
if (!Core::IsUninitialized(Core::System::GetInstance()))
|
||||
if (Core::IsRunning(Core::System::GetInstance()))
|
||||
{
|
||||
ModalMessageBox::critical(nullptr, tr("Error"),
|
||||
tr("Can't start a NetPlay Session while a game is still running!"));
|
||||
|
@ -1850,7 +1850,7 @@ void MainWindow::OnImportNANDBackup()
|
|||
|
||||
result.wait();
|
||||
|
||||
m_menu_bar->UpdateToolsMenu(Core::State::Uninitialized);
|
||||
m_menu_bar->UpdateToolsMenu(Core::IsRunning(Core::System::GetInstance()));
|
||||
}
|
||||
|
||||
void MainWindow::OnPlayRecording()
|
||||
|
@ -1882,8 +1882,7 @@ void MainWindow::OnStartRecording()
|
|||
{
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& movie = system.GetMovie();
|
||||
if (Core::GetState(system) == Core::State::Starting ||
|
||||
Core::GetState(system) == Core::State::Stopping || movie.IsRecordingInput() ||
|
||||
if (Core::GetState(system) == Core::State::Starting || movie.IsRecordingInput() ||
|
||||
movie.IsPlayingInput())
|
||||
{
|
||||
return;
|
||||
|
@ -1915,7 +1914,7 @@ void MainWindow::OnStartRecording()
|
|||
{
|
||||
emit RecordingStatusChanged(true);
|
||||
|
||||
if (Core::IsUninitialized(system))
|
||||
if (!Core::IsRunning(system))
|
||||
Play();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -138,11 +138,9 @@ void MenuBar::OnEmulationStateChanged(Core::State state)
|
|||
m_recording_stop->setEnabled(false);
|
||||
m_recording_export->setEnabled(false);
|
||||
}
|
||||
const bool can_start_from_boot = m_game_selected && state == Core::State::Uninitialized;
|
||||
const bool can_start_from_savestate =
|
||||
state == Core::State::Running || state == Core::State::Paused;
|
||||
m_recording_play->setEnabled(can_start_from_boot && !hardcore);
|
||||
m_recording_start->setEnabled((can_start_from_boot || can_start_from_savestate) &&
|
||||
m_recording_play->setEnabled(m_game_selected && !running);
|
||||
m_recording_play->setEnabled(m_game_selected && !running && !hardcore);
|
||||
m_recording_start->setEnabled((m_game_selected || running) &&
|
||||
!Core::System::GetInstance().GetMovie().IsPlayingInput());
|
||||
|
||||
// JIT
|
||||
|
@ -161,7 +159,7 @@ void MenuBar::OnEmulationStateChanged(Core::State state)
|
|||
m_symbols->setEnabled(running);
|
||||
|
||||
UpdateStateSlotMenu();
|
||||
UpdateToolsMenu(state);
|
||||
UpdateToolsMenu(running);
|
||||
|
||||
OnDebugModeToggled(Settings::Instance().IsDebugModeEnabled());
|
||||
}
|
||||
|
@ -302,8 +300,7 @@ void MenuBar::AddToolsMenu()
|
|||
|
||||
m_boot_sysmenu->setEnabled(false);
|
||||
|
||||
connect(&Settings::Instance(), &Settings::NANDRefresh, this,
|
||||
[this] { UpdateToolsMenu(Core::State::Uninitialized); });
|
||||
connect(&Settings::Instance(), &Settings::NANDRefresh, this, [this] { UpdateToolsMenu(false); });
|
||||
|
||||
m_perform_online_update_menu = tools_menu->addMenu(tr("Perform Online System Update"));
|
||||
m_perform_online_update_for_current_region = m_perform_online_update_menu->addAction(
|
||||
|
@ -1053,23 +1050,20 @@ void MenuBar::AddSymbolsMenu()
|
|||
m_symbols->addAction(tr("&Patch HLE Functions"), this, &MenuBar::PatchHLEFunctions);
|
||||
}
|
||||
|
||||
void MenuBar::UpdateToolsMenu(Core::State state)
|
||||
void MenuBar::UpdateToolsMenu(bool emulation_started)
|
||||
{
|
||||
const bool is_uninitialized = state == Core::State::Uninitialized;
|
||||
const bool is_running = state == Core::State::Running || state == Core::State::Paused;
|
||||
m_boot_sysmenu->setEnabled(!emulation_started);
|
||||
m_perform_online_update_menu->setEnabled(!emulation_started);
|
||||
m_ntscj_ipl->setEnabled(!emulation_started && File::Exists(Config::GetBootROMPath(JAP_DIR)));
|
||||
m_ntscu_ipl->setEnabled(!emulation_started && File::Exists(Config::GetBootROMPath(USA_DIR)));
|
||||
m_pal_ipl->setEnabled(!emulation_started && File::Exists(Config::GetBootROMPath(EUR_DIR)));
|
||||
m_wad_install_action->setEnabled(!emulation_started);
|
||||
m_import_backup->setEnabled(!emulation_started);
|
||||
m_check_nand->setEnabled(!emulation_started);
|
||||
m_import_wii_save->setEnabled(!emulation_started);
|
||||
m_export_wii_saves->setEnabled(!emulation_started);
|
||||
|
||||
m_boot_sysmenu->setEnabled(is_uninitialized);
|
||||
m_perform_online_update_menu->setEnabled(is_uninitialized);
|
||||
m_ntscj_ipl->setEnabled(is_uninitialized && File::Exists(Config::GetBootROMPath(JAP_DIR)));
|
||||
m_ntscu_ipl->setEnabled(is_uninitialized && File::Exists(Config::GetBootROMPath(USA_DIR)));
|
||||
m_pal_ipl->setEnabled(is_uninitialized && File::Exists(Config::GetBootROMPath(EUR_DIR)));
|
||||
m_wad_install_action->setEnabled(is_uninitialized);
|
||||
m_import_backup->setEnabled(is_uninitialized);
|
||||
m_check_nand->setEnabled(is_uninitialized);
|
||||
m_import_wii_save->setEnabled(is_uninitialized);
|
||||
m_export_wii_saves->setEnabled(is_uninitialized);
|
||||
|
||||
if (is_uninitialized)
|
||||
if (!emulation_started)
|
||||
{
|
||||
IOS::HLE::Kernel ios;
|
||||
const auto tmd = ios.GetESCore().FindInstalledTMD(Titles::SYSTEM_MENU);
|
||||
|
@ -1092,7 +1086,7 @@ void MenuBar::UpdateToolsMenu(Core::State state)
|
|||
}
|
||||
|
||||
const auto bt = WiiUtils::GetBluetoothEmuDevice();
|
||||
const bool enable_wiimotes = is_running && bt != nullptr;
|
||||
const bool enable_wiimotes = emulation_started && bt != nullptr;
|
||||
|
||||
for (std::size_t i = 0; i < m_wii_remotes.size(); i++)
|
||||
{
|
||||
|
@ -1263,20 +1257,16 @@ void MenuBar::OnSelectionChanged(std::shared_ptr<const UICommon::GameFile> game_
|
|||
m_game_selected = !!game_file;
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
const bool can_start_from_boot = m_game_selected && Core::IsUninitialized(system);
|
||||
const bool can_start_from_savestate = Core::IsRunning(system);
|
||||
m_recording_play->setEnabled(can_start_from_boot);
|
||||
m_recording_start->setEnabled((can_start_from_boot || can_start_from_savestate) &&
|
||||
const bool core_is_running = Core::IsRunning(system);
|
||||
m_recording_play->setEnabled(m_game_selected && !core_is_running);
|
||||
m_recording_start->setEnabled((m_game_selected || core_is_running) &&
|
||||
!system.GetMovie().IsPlayingInput());
|
||||
}
|
||||
|
||||
void MenuBar::OnRecordingStatusChanged(bool recording)
|
||||
{
|
||||
auto& system = Core::System::GetInstance();
|
||||
const bool can_start_from_boot = m_game_selected && Core::IsUninitialized(system);
|
||||
const bool can_start_from_savestate = Core::IsRunning(system);
|
||||
|
||||
m_recording_start->setEnabled(!recording && (can_start_from_boot || can_start_from_savestate));
|
||||
m_recording_start->setEnabled(!recording && (m_game_selected || Core::IsRunning(system)));
|
||||
m_recording_stop->setEnabled(recording);
|
||||
m_recording_export->setEnabled(recording);
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ public:
|
|||
|
||||
explicit MenuBar(QWidget* parent = nullptr);
|
||||
|
||||
void UpdateToolsMenu(Core::State state);
|
||||
void UpdateToolsMenu(bool emulation_started);
|
||||
|
||||
QMenu* GetListColumnsMenu() const { return m_cols_menu; }
|
||||
|
||||
|
|
|
@ -804,11 +804,9 @@ void NetPlayDialog::DisplayMessage(const QString& msg, const std::string& color,
|
|||
QColor c(color.empty() ? QStringLiteral("white") : QString::fromStdString(color));
|
||||
|
||||
if (g_ActiveConfig.bShowNetPlayMessages && Core::IsRunning(Core::System::GetInstance()))
|
||||
{
|
||||
g_netplay_chat_ui->AppendChat(msg.toStdString(),
|
||||
{static_cast<float>(c.redF()), static_cast<float>(c.greenF()),
|
||||
static_cast<float>(c.blueF())});
|
||||
}
|
||||
}
|
||||
|
||||
void NetPlayDialog::AppendChat(const std::string& msg)
|
||||
|
|
|
@ -354,11 +354,6 @@ void Settings::NotifyRefreshGameListComplete()
|
|||
emit GameListRefreshCompleted();
|
||||
}
|
||||
|
||||
void Settings::RefreshMetadata()
|
||||
{
|
||||
emit MetadataRefreshRequested();
|
||||
}
|
||||
|
||||
void Settings::NotifyMetadataRefreshComplete()
|
||||
{
|
||||
emit MetadataRefreshCompleted();
|
||||
|
|
|
@ -104,7 +104,6 @@ public:
|
|||
void RefreshGameList();
|
||||
void NotifyRefreshGameListStarted();
|
||||
void NotifyRefreshGameListComplete();
|
||||
void RefreshMetadata();
|
||||
void NotifyMetadataRefreshComplete();
|
||||
void ReloadTitleDB();
|
||||
bool IsAutoRefreshEnabled() const;
|
||||
|
@ -224,6 +223,7 @@ signals:
|
|||
void SDCardInsertionChanged(bool inserted);
|
||||
void USBKeyboardConnectionChanged(bool connected);
|
||||
void EnableGfxModsChanged(bool enabled);
|
||||
void HardcoreStateChanged();
|
||||
|
||||
private:
|
||||
Settings();
|
||||
|
|
|
@ -4,9 +4,6 @@
|
|||
#include "DolphinQt/Settings/AdvancedPane.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QComboBox>
|
||||
#include <QDateTimeEdit>
|
||||
#include <QFormLayout>
|
||||
#include <QGroupBox>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
|
@ -17,23 +14,14 @@
|
|||
#include <cmath>
|
||||
|
||||
#include "Core/Config/MainSettings.h"
|
||||
#include "Core/ConfigManager.h"
|
||||
#include "Core/Core.h"
|
||||
#include "Core/HW/SystemTimers.h"
|
||||
#include "Core/PowerPC/PowerPC.h"
|
||||
#include "Core/System.h"
|
||||
|
||||
#include "DolphinQt/Config/ConfigControls/ConfigBool.h"
|
||||
#include "DolphinQt/QtUtils/SignalBlocking.h"
|
||||
#include "DolphinQt/Settings.h"
|
||||
|
||||
static const std::map<PowerPC::CPUCore, const char*> CPU_CORE_NAMES = {
|
||||
{PowerPC::CPUCore::Interpreter, QT_TR_NOOP("Interpreter (slowest)")},
|
||||
{PowerPC::CPUCore::CachedInterpreter, QT_TR_NOOP("Cached Interpreter (slower)")},
|
||||
{PowerPC::CPUCore::JIT64, QT_TR_NOOP("JIT Recompiler for x86-64 (recommended)")},
|
||||
{PowerPC::CPUCore::JITARM64, QT_TR_NOOP("JIT Recompiler for ARM64 (recommended)")},
|
||||
};
|
||||
|
||||
AdvancedPane::AdvancedPane(QWidget* parent) : QWidget(parent)
|
||||
{
|
||||
CreateLayout();
|
||||
|
@ -49,44 +37,6 @@ void AdvancedPane::CreateLayout()
|
|||
auto* main_layout = new QVBoxLayout();
|
||||
setLayout(main_layout);
|
||||
|
||||
auto* cpu_options_group = new QGroupBox(tr("CPU Options"));
|
||||
auto* cpu_options_group_layout = new QVBoxLayout();
|
||||
cpu_options_group->setLayout(cpu_options_group_layout);
|
||||
main_layout->addWidget(cpu_options_group);
|
||||
|
||||
auto* cpu_emulation_engine_layout = new QFormLayout;
|
||||
cpu_emulation_engine_layout->setFormAlignment(Qt::AlignLeft | Qt::AlignTop);
|
||||
cpu_emulation_engine_layout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow);
|
||||
cpu_options_group_layout->addLayout(cpu_emulation_engine_layout);
|
||||
|
||||
m_cpu_emulation_engine_combobox = new QComboBox(this);
|
||||
cpu_emulation_engine_layout->addRow(tr("CPU Emulation Engine:"), m_cpu_emulation_engine_combobox);
|
||||
for (PowerPC::CPUCore cpu_core : PowerPC::AvailableCPUCores())
|
||||
{
|
||||
m_cpu_emulation_engine_combobox->addItem(tr(CPU_CORE_NAMES.at(cpu_core)));
|
||||
}
|
||||
|
||||
m_enable_mmu_checkbox = new ConfigBool(tr("Enable MMU"), Config::MAIN_MMU);
|
||||
m_enable_mmu_checkbox->SetDescription(
|
||||
tr("Enables the Memory Management Unit, needed for some games. (ON = Compatible, OFF = "
|
||||
"Fast)<br><br><dolphin_emphasis>If unsure, leave this unchecked.</dolphin_emphasis>"));
|
||||
cpu_options_group_layout->addWidget(m_enable_mmu_checkbox);
|
||||
|
||||
m_pause_on_panic_checkbox = new ConfigBool(tr("Pause on Panic"), Config::MAIN_PAUSE_ON_PANIC);
|
||||
m_pause_on_panic_checkbox->SetDescription(
|
||||
tr("Pauses the emulation if a Read/Write or Unknown Instruction panic occurs.<br>Enabling "
|
||||
"will affect performance.<br>The performance impact is the same as having Enable MMU "
|
||||
"on.<br><br><dolphin_emphasis>If unsure, leave this unchecked.</dolphin_emphasis>"));
|
||||
cpu_options_group_layout->addWidget(m_pause_on_panic_checkbox);
|
||||
|
||||
m_accurate_cpu_cache_checkbox =
|
||||
new ConfigBool(tr("Enable Write-Back Cache (slow)"), Config::MAIN_ACCURATE_CPU_CACHE);
|
||||
m_accurate_cpu_cache_checkbox->SetDescription(
|
||||
tr("Enables emulation of the CPU write-back cache.<br>Enabling will have a significant "
|
||||
"impact on performance.<br>This should be left disabled unless absolutely "
|
||||
"needed.<br><br><dolphin_emphasis>If unsure, leave this unchecked.</dolphin_emphasis>"));
|
||||
cpu_options_group_layout->addWidget(m_accurate_cpu_cache_checkbox);
|
||||
|
||||
auto* clock_override = new QGroupBox(tr("Clock Override"));
|
||||
auto* clock_override_layout = new QVBoxLayout();
|
||||
clock_override->setLayout(clock_override_layout);
|
||||
|
@ -100,7 +50,7 @@ void AdvancedPane::CreateLayout()
|
|||
clock_override_layout->addLayout(cpu_clock_override_slider_layout);
|
||||
|
||||
m_cpu_clock_override_slider = new QSlider(Qt::Horizontal);
|
||||
m_cpu_clock_override_slider->setRange(0, 150);
|
||||
m_cpu_clock_override_slider->setRange(1, 400);
|
||||
cpu_clock_override_slider_layout->addWidget(m_cpu_clock_override_slider);
|
||||
|
||||
m_cpu_clock_override_slider_label = new QLabel();
|
||||
|
@ -155,56 +105,18 @@ void AdvancedPane::CreateLayout()
|
|||
ram_override_description->setWordWrap(true);
|
||||
ram_override_layout->addWidget(ram_override_description);
|
||||
|
||||
auto* rtc_options = new QGroupBox(tr("Custom RTC Options"));
|
||||
rtc_options->setLayout(new QVBoxLayout());
|
||||
main_layout->addWidget(rtc_options);
|
||||
|
||||
m_custom_rtc_checkbox = new QCheckBox(tr("Enable Custom RTC"));
|
||||
rtc_options->layout()->addWidget(m_custom_rtc_checkbox);
|
||||
|
||||
m_custom_rtc_datetime = new QDateTimeEdit();
|
||||
|
||||
// Show seconds
|
||||
m_custom_rtc_datetime->setDisplayFormat(m_custom_rtc_datetime->displayFormat().replace(
|
||||
QStringLiteral("mm"), QStringLiteral("mm:ss")));
|
||||
|
||||
if (!m_custom_rtc_datetime->displayFormat().contains(QStringLiteral("yyyy")))
|
||||
{
|
||||
// Always show the full year, no matter what the locale specifies. Otherwise, two-digit years
|
||||
// will always be interpreted as in the 21st century.
|
||||
m_custom_rtc_datetime->setDisplayFormat(m_custom_rtc_datetime->displayFormat().replace(
|
||||
QStringLiteral("yy"), QStringLiteral("yyyy")));
|
||||
}
|
||||
m_custom_rtc_datetime->setDateTimeRange(QDateTime({2000, 1, 1}, {0, 0, 0}, Qt::UTC),
|
||||
QDateTime({2099, 12, 31}, {23, 59, 59}, Qt::UTC));
|
||||
m_custom_rtc_datetime->setTimeSpec(Qt::UTC);
|
||||
rtc_options->layout()->addWidget(m_custom_rtc_datetime);
|
||||
|
||||
auto* custom_rtc_description =
|
||||
new QLabel(tr("This setting allows you to set a custom real time clock (RTC) separate from "
|
||||
"your current system time.\n\nIf unsure, leave this unchecked."));
|
||||
custom_rtc_description->setWordWrap(true);
|
||||
rtc_options->layout()->addWidget(custom_rtc_description);
|
||||
|
||||
main_layout->addStretch(1);
|
||||
}
|
||||
|
||||
void AdvancedPane::ConnectLayout()
|
||||
{
|
||||
connect(m_cpu_emulation_engine_combobox, &QComboBox::currentIndexChanged, [](int index) {
|
||||
const auto cpu_cores = PowerPC::AvailableCPUCores();
|
||||
if (index >= 0 && static_cast<size_t>(index) < cpu_cores.size())
|
||||
Config::SetBaseOrCurrent(Config::MAIN_CPU_CORE, cpu_cores[index]);
|
||||
});
|
||||
|
||||
connect(m_cpu_clock_override_checkbox, &QCheckBox::toggled, [this](bool enable_clock_override) {
|
||||
Config::SetBaseOrCurrent(Config::MAIN_OVERCLOCK_ENABLE, enable_clock_override);
|
||||
Update();
|
||||
});
|
||||
|
||||
connect(m_cpu_clock_override_slider, &QSlider::valueChanged, [this](int oc_factor) {
|
||||
// Vaguely exponential scaling?
|
||||
const float factor = std::exp2f((m_cpu_clock_override_slider->value() - 100.f) / 25.f);
|
||||
const float factor = m_cpu_clock_override_slider->value() / 100.f;
|
||||
Config::SetBaseOrCurrent(Config::MAIN_OVERCLOCK, factor);
|
||||
Update();
|
||||
});
|
||||
|
@ -225,36 +137,13 @@ void AdvancedPane::ConnectLayout()
|
|||
Config::SetBaseOrCurrent(Config::MAIN_MEM2_SIZE, mem2_size);
|
||||
Update();
|
||||
});
|
||||
|
||||
connect(m_custom_rtc_checkbox, &QCheckBox::toggled, [this](bool enable_custom_rtc) {
|
||||
Config::SetBaseOrCurrent(Config::MAIN_CUSTOM_RTC_ENABLE, enable_custom_rtc);
|
||||
Update();
|
||||
});
|
||||
|
||||
connect(m_custom_rtc_datetime, &QDateTimeEdit::dateTimeChanged, [this](QDateTime date_time) {
|
||||
Config::SetBaseOrCurrent(Config::MAIN_CUSTOM_RTC_VALUE,
|
||||
static_cast<u32>(date_time.toSecsSinceEpoch()));
|
||||
Update();
|
||||
});
|
||||
}
|
||||
|
||||
void AdvancedPane::Update()
|
||||
{
|
||||
const bool running = !Core::IsUninitialized(Core::System::GetInstance());
|
||||
const bool running = Core::GetState(Core::System::GetInstance()) != Core::State::Uninitialized;
|
||||
const bool enable_cpu_clock_override_widgets = Config::Get(Config::MAIN_OVERCLOCK_ENABLE);
|
||||
const bool enable_ram_override_widgets = Config::Get(Config::MAIN_RAM_OVERRIDE_ENABLE);
|
||||
const bool enable_custom_rtc_widgets = Config::Get(Config::MAIN_CUSTOM_RTC_ENABLE) && !running;
|
||||
|
||||
const auto available_cpu_cores = PowerPC::AvailableCPUCores();
|
||||
const auto cpu_core = Config::Get(Config::MAIN_CPU_CORE);
|
||||
for (size_t i = 0; i < available_cpu_cores.size(); ++i)
|
||||
{
|
||||
if (available_cpu_cores[i] == cpu_core)
|
||||
m_cpu_emulation_engine_combobox->setCurrentIndex(int(i));
|
||||
}
|
||||
m_cpu_emulation_engine_combobox->setEnabled(!running);
|
||||
m_enable_mmu_checkbox->setEnabled(!running);
|
||||
m_pause_on_panic_checkbox->setEnabled(!running);
|
||||
|
||||
{
|
||||
QFont bf = font();
|
||||
|
@ -271,8 +160,8 @@ void AdvancedPane::Update()
|
|||
|
||||
{
|
||||
const QSignalBlocker blocker(m_cpu_clock_override_slider);
|
||||
m_cpu_clock_override_slider->setValue(static_cast<int>(
|
||||
std::round(std::log2f(Config::Get(Config::MAIN_OVERCLOCK)) * 25.f + 100.f)));
|
||||
m_cpu_clock_override_slider->setValue(
|
||||
static_cast<int>(std::round(Config::Get(Config::MAIN_OVERCLOCK) * 100.f)));
|
||||
}
|
||||
|
||||
m_cpu_clock_override_slider_label->setText([] {
|
||||
|
@ -313,12 +202,4 @@ void AdvancedPane::Update()
|
|||
const u32 mem2_size = Config::Get(Config::MAIN_MEM2_SIZE) / 0x100000;
|
||||
return tr("%1 MB (MEM2)").arg(QString::number(mem2_size));
|
||||
}());
|
||||
|
||||
m_custom_rtc_checkbox->setEnabled(!running);
|
||||
SignalBlocking(m_custom_rtc_checkbox)->setChecked(Config::Get(Config::MAIN_CUSTOM_RTC_ENABLE));
|
||||
|
||||
QDateTime initial_date_time;
|
||||
initial_date_time.setSecsSinceEpoch(Config::Get(Config::MAIN_CUSTOM_RTC_VALUE));
|
||||
m_custom_rtc_datetime->setEnabled(enable_custom_rtc_widgets);
|
||||
SignalBlocking(m_custom_rtc_datetime)->setDateTime(initial_date_time);
|
||||
}
|
||||
|
|
|
@ -3,22 +3,13 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class ConfigBool;
|
||||
class QCheckBox;
|
||||
class QComboBox;
|
||||
class QLabel;
|
||||
class QRadioButton;
|
||||
class QSlider;
|
||||
class QDateTimeEdit;
|
||||
|
||||
namespace Core
|
||||
{
|
||||
enum class State;
|
||||
}
|
||||
|
||||
class AdvancedPane final : public QWidget
|
||||
{
|
||||
|
@ -31,18 +22,11 @@ private:
|
|||
void ConnectLayout();
|
||||
void Update();
|
||||
|
||||
QComboBox* m_cpu_emulation_engine_combobox;
|
||||
ConfigBool* m_enable_mmu_checkbox;
|
||||
ConfigBool* m_pause_on_panic_checkbox;
|
||||
ConfigBool* m_accurate_cpu_cache_checkbox;
|
||||
QCheckBox* m_cpu_clock_override_checkbox;
|
||||
QSlider* m_cpu_clock_override_slider;
|
||||
QLabel* m_cpu_clock_override_slider_label;
|
||||
QLabel* m_cpu_clock_override_description;
|
||||
|
||||
QCheckBox* m_custom_rtc_checkbox;
|
||||
QDateTimeEdit* m_custom_rtc_datetime;
|
||||
|
||||
QCheckBox* m_ram_override_checkbox;
|
||||
QSlider* m_mem1_override_slider;
|
||||
QLabel* m_mem1_override_slider_label;
|
||||
|
|
|
@ -40,7 +40,8 @@ AudioPane::AudioPane()
|
|||
OnEmulationStateChanged(state != Core::State::Uninitialized);
|
||||
});
|
||||
|
||||
OnEmulationStateChanged(!Core::IsUninitialized(Core::System::GetInstance()));
|
||||
OnEmulationStateChanged(Core::GetState(Core::System::GetInstance()) !=
|
||||
Core::State::Uninitialized);
|
||||
}
|
||||
|
||||
void AudioPane::CreateWidgets()
|
||||
|
|
|
@ -194,7 +194,7 @@ void GeneralPane::CreateAutoUpdate()
|
|||
auto_update_group_layout->addRow(tr("&Auto Update:"), m_combobox_update_track);
|
||||
|
||||
for (const QString& option :
|
||||
{tr("Don't Update"), tr("Beta (once a month)"), tr("Dev (multiple times a day)")})
|
||||
{tr("Don't Update"), tr("Releases (every few months)"), tr("Dev (multiple times a day)")})
|
||||
m_combobox_update_track->addItem(option);
|
||||
}
|
||||
|
||||
|
|
|
@ -235,15 +235,15 @@ void InterfacePane::ConnectLayout()
|
|||
connect(m_checkbox_use_builtin_title_database, &QCheckBox::toggled, &Settings::Instance(),
|
||||
&Settings::GameListRefreshRequested);
|
||||
connect(m_checkbox_use_covers, &QCheckBox::toggled, &Settings::Instance(),
|
||||
&Settings::RefreshMetadata);
|
||||
&Settings::MetadataRefreshRequested);
|
||||
connect(m_checkbox_show_debugging_ui, &QCheckBox::toggled, &Settings::Instance(),
|
||||
&Settings::SetDebugModeEnabled);
|
||||
connect(m_combobox_theme, &QComboBox::currentIndexChanged, this,
|
||||
[this](int index) { Settings::Instance().TriggerThemeChanged(); });
|
||||
connect(m_combobox_theme, &QComboBox::currentIndexChanged, &Settings::Instance(),
|
||||
&Settings::ThemeChanged);
|
||||
connect(m_combobox_userstyle, &QComboBox::currentIndexChanged, this,
|
||||
&InterfacePane::OnUserStyleChanged);
|
||||
connect(m_combobox_language, &QComboBox::currentIndexChanged, this,
|
||||
[this]() { OnLanguageChanged(); });
|
||||
&InterfacePane::OnLanguageChanged);
|
||||
connect(m_checkbox_top_window, &QCheckBox::toggled, &Settings::Instance(),
|
||||
&Settings::KeepWindowOnTopChanged);
|
||||
connect(m_radio_cursor_visible_movement, &ConfigRadioInt::OnSelected, &Settings::Instance(),
|
||||
|
@ -253,7 +253,7 @@ void InterfacePane::ConnectLayout()
|
|||
connect(m_radio_cursor_visible_always, &ConfigRadioInt::OnSelected, &Settings::Instance(),
|
||||
&Settings::CursorVisibilityChanged);
|
||||
connect(m_checkbox_lock_mouse, &QCheckBox::toggled, &Settings::Instance(),
|
||||
[this]() { Settings::Instance().LockCursorChanged(); });
|
||||
&Settings::LockCursorChanged);
|
||||
}
|
||||
|
||||
void InterfacePane::UpdateShowDebuggingCheckbox()
|
||||
|
|
159
Source/Core/DolphinQt/Settings/MiscPane.cpp
Normal file
159
Source/Core/DolphinQt/Settings/MiscPane.cpp
Normal file
|
@ -0,0 +1,159 @@
|
|||
// Copyright 2020 Dolphin Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "DolphinQt/Settings/MiscPane.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QComboBox>
|
||||
#include <QDateTimeEdit>
|
||||
#include <QFormLayout>
|
||||
#include <QGroupBox>
|
||||
#include <QLabel>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include "Core/Config/MainSettings.h"
|
||||
#include "Core/ConfigManager.h"
|
||||
#include "Core/Core.h"
|
||||
#include "Core/PowerPC/PowerPC.h"
|
||||
|
||||
#include "DolphinQt/QtUtils/SignalBlocking.h"
|
||||
#include "DolphinQt/Settings.h"
|
||||
|
||||
static const std::map<PowerPC::CPUCore, const char*> CPU_CORE_NAMES = {
|
||||
{PowerPC::CPUCore::Interpreter, QT_TR_NOOP("Interpreter (slowest)")},
|
||||
{PowerPC::CPUCore::CachedInterpreter, QT_TR_NOOP("Cached Interpreter (slower)")},
|
||||
{PowerPC::CPUCore::JIT64, QT_TR_NOOP("JIT Recompiler for x86-64 (recommended)")},
|
||||
{PowerPC::CPUCore::JITARM64, QT_TR_NOOP("JIT Recompiler for ARM64 (recommended)")},
|
||||
};
|
||||
|
||||
MiscPane::MiscPane(QWidget* parent) : QWidget(parent)
|
||||
{
|
||||
CreateLayout();
|
||||
Update();
|
||||
|
||||
ConnectLayout();
|
||||
|
||||
connect(&Settings::Instance(), &Settings::EmulationStateChanged, this, &MiscPane::Update);
|
||||
}
|
||||
|
||||
void MiscPane::CreateLayout()
|
||||
{
|
||||
auto* main_layout = new QVBoxLayout();
|
||||
setLayout(main_layout);
|
||||
|
||||
auto* cpu_options_group = new QGroupBox(tr("CPU Options"));
|
||||
auto* cpu_options_group_layout = new QVBoxLayout();
|
||||
cpu_options_group->setLayout(cpu_options_group_layout);
|
||||
main_layout->addWidget(cpu_options_group);
|
||||
|
||||
auto* cpu_emulation_engine_layout = new QFormLayout;
|
||||
cpu_emulation_engine_layout->setFormAlignment(Qt::AlignLeft | Qt::AlignTop);
|
||||
cpu_emulation_engine_layout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow);
|
||||
cpu_options_group_layout->addLayout(cpu_emulation_engine_layout);
|
||||
|
||||
m_cpu_emulation_engine_combobox = new QComboBox(this);
|
||||
cpu_emulation_engine_layout->addRow(tr("CPU Emulation Engine:"), m_cpu_emulation_engine_combobox);
|
||||
for (PowerPC::CPUCore cpu_core : PowerPC::AvailableCPUCores())
|
||||
{
|
||||
m_cpu_emulation_engine_combobox->addItem(tr(CPU_CORE_NAMES.at(cpu_core)));
|
||||
}
|
||||
|
||||
m_enable_mmu_checkbox = new ConfigBool(tr("Enable MMU"), Config::MAIN_MMU);
|
||||
m_enable_mmu_checkbox->SetDescription(
|
||||
tr("Enables the Memory Management Unit, needed for some games. (ON = Compatible, OFF = "
|
||||
"Fast)<br><br><dolphin_emphasis>If unsure, leave this unchecked.</dolphin_emphasis>"));
|
||||
cpu_options_group_layout->addWidget(m_enable_mmu_checkbox);
|
||||
|
||||
m_pause_on_panic_checkbox = new ConfigBool(tr("Pause on Panic"), Config::MAIN_PAUSE_ON_PANIC);
|
||||
m_pause_on_panic_checkbox->SetDescription(
|
||||
tr("Pauses the emulation if a Read/Write or Unknown Instruction panic occurs.<br>Enabling "
|
||||
"will affect performance.<br>The performance impact is the same as having Enable MMU "
|
||||
"on.<br><br><dolphin_emphasis>If unsure, leave this unchecked.</dolphin_emphasis>"));
|
||||
cpu_options_group_layout->addWidget(m_pause_on_panic_checkbox);
|
||||
|
||||
m_accurate_cpu_cache_checkbox =
|
||||
new ConfigBool(tr("Enable Write-Back Cache (slow)"), Config::MAIN_ACCURATE_CPU_CACHE);
|
||||
m_accurate_cpu_cache_checkbox->SetDescription(
|
||||
tr("Enables emulation of the CPU write-back cache.<br>Enabling will have a significant "
|
||||
"impact on performance.<br>This should be left disabled unless absolutely "
|
||||
"needed.<br><br><dolphin_emphasis>If unsure, leave this unchecked.</dolphin_emphasis>"));
|
||||
cpu_options_group_layout->addWidget(m_accurate_cpu_cache_checkbox);
|
||||
|
||||
auto* rtc_options = new QGroupBox(tr("Custom RTC Options"));
|
||||
rtc_options->setLayout(new QVBoxLayout());
|
||||
main_layout->addWidget(rtc_options);
|
||||
|
||||
m_custom_rtc_checkbox = new QCheckBox(tr("Enable Custom RTC"));
|
||||
rtc_options->layout()->addWidget(m_custom_rtc_checkbox);
|
||||
|
||||
m_custom_rtc_datetime = new QDateTimeEdit();
|
||||
|
||||
// Show seconds
|
||||
m_custom_rtc_datetime->setDisplayFormat(m_custom_rtc_datetime->displayFormat().replace(
|
||||
QStringLiteral("mm"), QStringLiteral("mm:ss")));
|
||||
|
||||
if (!m_custom_rtc_datetime->displayFormat().contains(QStringLiteral("yyyy")))
|
||||
{
|
||||
// Always show the full year, no matter what the locale specifies. Otherwise, two-digit years
|
||||
// will always be interpreted as in the 21st century.
|
||||
m_custom_rtc_datetime->setDisplayFormat(m_custom_rtc_datetime->displayFormat().replace(
|
||||
QStringLiteral("yy"), QStringLiteral("yyyy")));
|
||||
}
|
||||
m_custom_rtc_datetime->setDateTimeRange(QDateTime({2000, 1, 1}, {0, 0, 0}, Qt::UTC),
|
||||
QDateTime({2099, 12, 31}, {23, 59, 59}, Qt::UTC));
|
||||
m_custom_rtc_datetime->setTimeSpec(Qt::UTC);
|
||||
rtc_options->layout()->addWidget(m_custom_rtc_datetime);
|
||||
|
||||
auto* custom_rtc_description =
|
||||
new QLabel(tr("This setting allows you to set a custom real time clock (RTC) separate from "
|
||||
"your current system time.\n\nIf unsure, leave this unchecked."));
|
||||
custom_rtc_description->setWordWrap(true);
|
||||
rtc_options->layout()->addWidget(custom_rtc_description);
|
||||
|
||||
main_layout->addStretch(1);
|
||||
}
|
||||
|
||||
void MiscPane::ConnectLayout()
|
||||
{
|
||||
connect(m_cpu_emulation_engine_combobox, &QComboBox::currentIndexChanged, [](int index) {
|
||||
const auto cpu_cores = PowerPC::AvailableCPUCores();
|
||||
if (index >= 0 && static_cast<size_t>(index) < cpu_cores.size())
|
||||
Config::SetBaseOrCurrent(Config::MAIN_CPU_CORE, cpu_cores[index]);
|
||||
});
|
||||
|
||||
connect(m_custom_rtc_checkbox, &QCheckBox::toggled, [this](bool enable_custom_rtc) {
|
||||
Config::SetBaseOrCurrent(Config::MAIN_CUSTOM_RTC_ENABLE, enable_custom_rtc);
|
||||
Update();
|
||||
});
|
||||
|
||||
connect(m_custom_rtc_datetime, &QDateTimeEdit::dateTimeChanged, [this](QDateTime date_time) {
|
||||
Config::SetBaseOrCurrent(Config::MAIN_CUSTOM_RTC_VALUE,
|
||||
static_cast<u32>(date_time.toSecsSinceEpoch()));
|
||||
Update();
|
||||
});
|
||||
}
|
||||
|
||||
void MiscPane::Update()
|
||||
{
|
||||
const bool running = Core::GetState() != Core::State::Uninitialized;
|
||||
const bool enable_custom_rtc_widgets = Config::Get(Config::MAIN_CUSTOM_RTC_ENABLE) && !running;
|
||||
|
||||
const auto available_cpu_cores = PowerPC::AvailableCPUCores();
|
||||
const auto cpu_core = Config::Get(Config::MAIN_CPU_CORE);
|
||||
for (size_t i = 0; i < available_cpu_cores.size(); ++i)
|
||||
{
|
||||
if (available_cpu_cores[i] == cpu_core)
|
||||
m_cpu_emulation_engine_combobox->setCurrentIndex(int(i));
|
||||
}
|
||||
m_cpu_emulation_engine_combobox->setEnabled(!running);
|
||||
m_enable_mmu_checkbox->setEnabled(!running);
|
||||
m_pause_on_panic_checkbox->setEnabled(!running);
|
||||
|
||||
m_custom_rtc_checkbox->setEnabled(!running);
|
||||
SignalBlocking(m_custom_rtc_checkbox)->setChecked(Config::Get(Config::MAIN_CUSTOM_RTC_ENABLE));
|
||||
|
||||
QDateTime initial_date_time;
|
||||
initial_date_time.setSecsSinceEpoch(Config::Get(Config::MAIN_CUSTOM_RTC_VALUE));
|
||||
m_custom_rtc_datetime->setEnabled(enable_custom_rtc_widgets);
|
||||
SignalBlocking(m_custom_rtc_datetime)->setDateTime(initial_date_time);
|
||||
}
|
33
Source/Core/DolphinQt/Settings/MiscPane.h
Normal file
33
Source/Core/DolphinQt/Settings/MiscPane.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
// Copyright 2020 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include "DolphinQt/Config/ConfigControls/ConfigBool.h"
|
||||
|
||||
class QCheckBox;
|
||||
class QComboBox;
|
||||
class QDateTimeEdit;
|
||||
|
||||
class MiscPane final : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MiscPane(QWidget* parent = nullptr);
|
||||
|
||||
private:
|
||||
void CreateLayout();
|
||||
void ConnectLayout();
|
||||
void Update();
|
||||
|
||||
QComboBox* m_cpu_emulation_engine_combobox;
|
||||
ConfigBool* m_enable_mmu_checkbox;
|
||||
ConfigBool* m_pause_on_panic_checkbox;
|
||||
ConfigBool* m_accurate_cpu_cache_checkbox;
|
||||
|
||||
QCheckBox* m_custom_rtc_checkbox;
|
||||
QDateTimeEdit* m_custom_rtc_datetime;
|
||||
};
|
|
@ -93,7 +93,8 @@ WiiPane::WiiPane(QWidget* parent) : QWidget(parent)
|
|||
LoadConfig();
|
||||
ConnectLayout();
|
||||
ValidateSelectionState();
|
||||
OnEmulationStateChanged(!Core::IsUninitialized(Core::System::GetInstance()));
|
||||
OnEmulationStateChanged(Core::GetState(Core::System::GetInstance()) !=
|
||||
Core::State::Uninitialized);
|
||||
}
|
||||
|
||||
void WiiPane::CreateLayout()
|
||||
|
|
|
@ -66,12 +66,15 @@ void VideoConfig::Refresh()
|
|||
CPUThreadConfigCallback::AddConfigChangedCallback([]() {
|
||||
auto& system = Core::System::GetInstance();
|
||||
|
||||
system.GetFifo().PauseAndLock(true, false);
|
||||
const bool lock_gpu_thread = Core::IsRunning(system);
|
||||
if (lock_gpu_thread)
|
||||
system.GetFifo().PauseAndLock(true, false);
|
||||
|
||||
g_Config.Refresh();
|
||||
g_Config.VerifyValidity();
|
||||
|
||||
system.GetFifo().PauseAndLock(false, true);
|
||||
if (lock_gpu_thread)
|
||||
system.GetFifo().PauseAndLock(false, true);
|
||||
});
|
||||
s_has_registered_callback = true;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user