diff options
16 files changed, 125 insertions, 82 deletions
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.kt index ed8fe6c3f0..9ebd6c732a 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.kt @@ -252,7 +252,7 @@ object NativeLibrary { external fun reloadKeys(): Boolean - external fun initializeSystem() + external fun initializeSystem(reload: Boolean) external fun defaultCPUCore(): Int diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/YuzuApplication.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/YuzuApplication.kt index 8c053670c6..d114bd53d7 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/YuzuApplication.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/YuzuApplication.kt @@ -11,6 +11,7 @@ import java.io.File import org.yuzu.yuzu_emu.utils.DirectoryInitialization import org.yuzu.yuzu_emu.utils.DocumentsTree import org.yuzu.yuzu_emu.utils.GpuDriverHelper +import org.yuzu.yuzu_emu.utils.Log fun Context.getPublicFilesDir(): File = getExternalFilesDir(null) ?: filesDir @@ -49,6 +50,7 @@ class YuzuApplication : Application() { DirectoryInitialization.start() GpuDriverHelper.initializeDriverParameters() NativeLibrary.logDeviceInfo() + Log.logDeviceInfo() createNotificationChannels() } diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt index da98d4ef50..054e4b7558 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt @@ -107,7 +107,7 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener { val preferences = PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext) if (!preferences.getBoolean(Settings.PREF_MEMORY_WARNING_SHOWN, false)) { - if (MemoryUtil.isLessThan(MemoryUtil.REQUIRED_MEMORY, MemoryUtil.Gb)) { + if (MemoryUtil.isLessThan(MemoryUtil.REQUIRED_MEMORY, MemoryUtil.totalMemory)) { Toast.makeText( this, getString( diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt index 07bd78bf72..c456c05921 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt @@ -312,6 +312,8 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { ViewUtils.showView(binding.surfaceInputOverlay) ViewUtils.hideView(binding.loadingIndicator) + emulationState.updateSurface() + // Setup overlay updateShowFpsOverlay() } @@ -805,6 +807,13 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { } @Synchronized + fun updateSurface() { + if (surface != null) { + NativeLibrary.surfaceChanged(surface) + } + } + + @Synchronized fun clearSurface() { if (surface == null) { Log.warning("[EmulationFragment] clearSurface called, but surface already null.") diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt index ba1177426a..211b7cf69d 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt @@ -403,7 +403,7 @@ class MainActivity : AppCompatActivity(), ThemeProvider { } else { firmwarePath.deleteRecursively() cacheFirmwareDir.copyRecursively(firmwarePath, true) - NativeLibrary.initializeSystem() + NativeLibrary.initializeSystem(true) getString(R.string.save_file_imported_success) } } catch (e: Exception) { @@ -649,7 +649,7 @@ class MainActivity : AppCompatActivity(), ThemeProvider { } // Reinitialize relevant data - NativeLibrary.initializeSystem() + NativeLibrary.initializeSystem(true) gamesViewModel.reloadGames(false) return@newInstance getString(R.string.user_data_import_success) diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/DirectoryInitialization.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/DirectoryInitialization.kt index 79a07f7ef7..5e9a1176ad 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/DirectoryInitialization.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/DirectoryInitialization.kt @@ -15,7 +15,7 @@ object DirectoryInitialization { fun start() { if (!areDirectoriesReady) { initializeInternalStorage() - NativeLibrary.initializeSystem() + NativeLibrary.initializeSystem(false) areDirectoriesReady = true } } diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/Log.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/Log.kt index fb682c3446..aebe84b0f1 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/Log.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/Log.kt @@ -3,6 +3,8 @@ package org.yuzu.yuzu_emu.utils +import android.os.Build + object Log { // Tracks whether we should share the old log or the current log var gameLaunched = false @@ -16,4 +18,14 @@ object Log { external fun error(message: String) external fun critical(message: String) + + fun logDeviceInfo() { + info("Device Manufacturer - ${Build.MANUFACTURER}") + info("Device Model - ${Build.MODEL}") + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.R) { + info("SoC Manufacturer - ${Build.SOC_MANUFACTURER}") + info("SoC Model - ${Build.SOC_MODEL}") + } + info("Total System Memory - ${MemoryUtil.getDeviceRAM()}") + } } diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/MemoryUtil.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/MemoryUtil.kt index aa4a5539a6..9076a86c41 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/MemoryUtil.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/MemoryUtil.kt @@ -27,7 +27,7 @@ object MemoryUtil { const val Pb = Tb * 1024 const val Eb = Pb * 1024 - private fun bytesToSizeUnit(size: Float): String = + private fun bytesToSizeUnit(size: Float, roundUp: Boolean = false): String = when { size < Kb -> { context.getString( @@ -39,63 +39,59 @@ object MemoryUtil { size < Mb -> { context.getString( R.string.memory_formatted, - (size / Kb).hundredths, + if (roundUp) ceil(size / Kb) else (size / Kb).hundredths, context.getString(R.string.memory_kilobyte) ) } size < Gb -> { context.getString( R.string.memory_formatted, - (size / Mb).hundredths, + if (roundUp) ceil(size / Mb) else (size / Mb).hundredths, context.getString(R.string.memory_megabyte) ) } size < Tb -> { context.getString( R.string.memory_formatted, - (size / Gb).hundredths, + if (roundUp) ceil(size / Gb) else (size / Gb).hundredths, context.getString(R.string.memory_gigabyte) ) } size < Pb -> { context.getString( R.string.memory_formatted, - (size / Tb).hundredths, + if (roundUp) ceil(size / Tb) else (size / Tb).hundredths, context.getString(R.string.memory_terabyte) ) } size < Eb -> { context.getString( R.string.memory_formatted, - (size / Pb).hundredths, + if (roundUp) ceil(size / Pb) else (size / Pb).hundredths, context.getString(R.string.memory_petabyte) ) } else -> { context.getString( R.string.memory_formatted, - (size / Eb).hundredths, + if (roundUp) ceil(size / Eb) else (size / Eb).hundredths, context.getString(R.string.memory_exabyte) ) } } - // Devices are unlikely to have 0.5GB increments of memory so we'll just round up to account for - // the potential error created by memInfo.totalMem - private val totalMemory: Float + val totalMemory: Float get() { val memInfo = ActivityManager.MemoryInfo() with(context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager) { getMemoryInfo(memInfo) } - return ceil( - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { - memInfo.advertisedMem.toFloat() - } else { - memInfo.totalMem.toFloat() - } - ) + return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { + memInfo.advertisedMem.toFloat() + } else { + memInfo.totalMem.toFloat() + } } fun isLessThan(minimum: Int, size: Float): Boolean = @@ -109,5 +105,7 @@ object MemoryUtil { else -> totalMemory < Kb && totalMemory < minimum } - fun getDeviceRAM(): String = bytesToSizeUnit(totalMemory) + // Devices are unlikely to have 0.5GB increments of memory so we'll just round up to account for + // the potential error created by memInfo.totalMem + fun getDeviceRAM(): String = bytesToSizeUnit(totalMemory, true) } diff --git a/src/android/app/src/main/jni/native.cpp b/src/android/app/src/main/jni/native.cpp index 294e41045c..46438906e1 100644 --- a/src/android/app/src/main/jni/native.cpp +++ b/src/android/app/src/main/jni/native.cpp @@ -247,11 +247,13 @@ void EmulationSession::ConfigureFilesystemProvider(const std::string& filepath) } } -void EmulationSession::InitializeSystem() { - // Initialize logging system - Common::Log::Initialize(); - Common::Log::SetColorConsoleBackendEnabled(true); - Common::Log::Start(); +void EmulationSession::InitializeSystem(bool reload) { + if (!reload) { + // Initialize logging system + Common::Log::Initialize(); + Common::Log::SetColorConsoleBackendEnabled(true); + Common::Log::Start(); + } // Initialize filesystem. m_system.SetFilesystem(m_vfs); @@ -667,12 +669,15 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_onTouchReleased(JNIEnv* env, jclass c } } -void Java_org_yuzu_yuzu_1emu_NativeLibrary_initializeSystem(JNIEnv* env, jclass clazz) { +void Java_org_yuzu_yuzu_1emu_NativeLibrary_initializeSystem(JNIEnv* env, jclass clazz, + jboolean reload) { // Create the default config.ini. Config{}; // Initialize the emulated system. - EmulationSession::GetInstance().System().Initialize(); - EmulationSession::GetInstance().InitializeSystem(); + if (!reload) { + EmulationSession::GetInstance().System().Initialize(); + } + EmulationSession::GetInstance().InitializeSystem(reload); } jint Java_org_yuzu_yuzu_1emu_NativeLibrary_defaultCPUCore(JNIEnv* env, jclass clazz) { diff --git a/src/android/app/src/main/jni/native.h b/src/android/app/src/main/jni/native.h index 0aa2b085b5..3b9596459a 100644 --- a/src/android/app/src/main/jni/native.h +++ b/src/android/app/src/main/jni/native.h @@ -43,7 +43,7 @@ public: const Core::PerfStatsResults& PerfStats() const; void ConfigureFilesystemProvider(const std::string& filepath); - void InitializeSystem(); + void InitializeSystem(bool reload); Core::SystemResultStatus InitializeEmulation(const std::string& filepath); bool IsHandheldOnly(); diff --git a/src/common/arm64/native_clock.cpp b/src/common/arm64/native_clock.cpp index 88fdba5277..f437d71870 100644 --- a/src/common/arm64/native_clock.cpp +++ b/src/common/arm64/native_clock.cpp @@ -1,6 +1,9 @@ // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#ifdef ANDROID +#include <sys/system_properties.h> +#endif #include "common/arm64/native_clock.h" namespace Common::Arm64 { @@ -65,7 +68,23 @@ bool NativeClock::IsNative() const { u64 NativeClock::GetHostCNTFRQ() { u64 cntfrq_el0 = 0; - asm("mrs %[cntfrq_el0], cntfrq_el0" : [cntfrq_el0] "=r"(cntfrq_el0)); + std::string_view board{""}; +#ifdef ANDROID + char buffer[PROP_VALUE_MAX]; + int len{__system_property_get("ro.product.board", buffer)}; + board = std::string_view(buffer, static_cast<size_t>(len)); +#endif + if (board == "s5e9925") { // Exynos 2200 + cntfrq_el0 = 25600000; + } else if (board == "exynos2100") { // Exynos 2100 + cntfrq_el0 = 26000000; + } else if (board == "exynos9810") { // Exynos 9810 + cntfrq_el0 = 26000000; + } else if (board == "s5e8825") { // Exynos 1280 + cntfrq_el0 = 26000000; + } else { + asm("mrs %[cntfrq_el0], cntfrq_el0" : [cntfrq_el0] "=r"(cntfrq_el0)); + } return cntfrq_el0; } diff --git a/src/core/hle/service/sockets/bsd.cpp b/src/core/hle/service/sockets/bsd.cpp index 85849d5f37..dd652ca421 100644 --- a/src/core/hle/service/sockets/bsd.cpp +++ b/src/core/hle/service/sockets/bsd.cpp @@ -39,6 +39,18 @@ bool IsConnectionBased(Type type) { } } +template <typename T> +T GetValue(std::span<const u8> buffer) { + T t{}; + std::memcpy(&t, buffer.data(), std::min(sizeof(T), buffer.size())); + return t; +} + +template <typename T> +void PutValue(std::span<u8> buffer, const T& t) { + std::memcpy(buffer.data(), &t, std::min(sizeof(T), buffer.size())); +} + } // Anonymous namespace void BSD::PollWork::Execute(BSD* bsd) { @@ -316,22 +328,12 @@ void BSD::SetSockOpt(HLERequestContext& ctx) { const s32 fd = rp.Pop<s32>(); const u32 level = rp.Pop<u32>(); const OptName optname = static_cast<OptName>(rp.Pop<u32>()); - - const auto buffer = ctx.ReadBuffer(); - const u8* optval = buffer.empty() ? nullptr : buffer.data(); - size_t optlen = buffer.size(); - - std::array<u64, 2> values; - if ((optname == OptName::SNDTIMEO || optname == OptName::RCVTIMEO) && buffer.size() == 8) { - std::memcpy(values.data(), buffer.data(), sizeof(values)); - optlen = sizeof(values); - optval = reinterpret_cast<const u8*>(values.data()); - } + const auto optval = ctx.ReadBuffer(); LOG_DEBUG(Service, "called. fd={} level={} optname=0x{:x} optlen={}", fd, level, - static_cast<u32>(optname), optlen); + static_cast<u32>(optname), optval.size()); - BuildErrnoResponse(ctx, SetSockOptImpl(fd, level, optname, optlen, optval)); + BuildErrnoResponse(ctx, SetSockOptImpl(fd, level, optname, optval)); } void BSD::Shutdown(HLERequestContext& ctx) { @@ -521,18 +523,19 @@ std::pair<s32, Errno> BSD::SocketImpl(Domain domain, Type type, Protocol protoco std::pair<s32, Errno> BSD::PollImpl(std::vector<u8>& write_buffer, std::span<const u8> read_buffer, s32 nfds, s32 timeout) { - if (write_buffer.size() < nfds * sizeof(PollFD)) { - return {-1, Errno::INVAL}; - } - - if (nfds == 0) { + if (nfds <= 0) { // When no entries are provided, -1 is returned with errno zero return {-1, Errno::SUCCESS}; } + if (read_buffer.size() < nfds * sizeof(PollFD)) { + return {-1, Errno::INVAL}; + } + if (write_buffer.size() < nfds * sizeof(PollFD)) { + return {-1, Errno::INVAL}; + } - const size_t length = std::min(read_buffer.size(), write_buffer.size()); std::vector<PollFD> fds(nfds); - std::memcpy(fds.data(), read_buffer.data(), length); + std::memcpy(fds.data(), read_buffer.data(), nfds * sizeof(PollFD)); if (timeout >= 0) { const s64 seconds = timeout / 1000; @@ -580,7 +583,7 @@ std::pair<s32, Errno> BSD::PollImpl(std::vector<u8>& write_buffer, std::span<con for (size_t i = 0; i < num; ++i) { fds[i].revents = Translate(host_pollfds[i].revents); } - std::memcpy(write_buffer.data(), fds.data(), length); + std::memcpy(write_buffer.data(), fds.data(), nfds * sizeof(PollFD)); return Translate(result); } @@ -608,8 +611,7 @@ std::pair<s32, Errno> BSD::AcceptImpl(s32 fd, std::vector<u8>& write_buffer) { new_descriptor.is_connection_based = descriptor.is_connection_based; const SockAddrIn guest_addr_in = Translate(result.sockaddr_in); - const size_t length = std::min(sizeof(guest_addr_in), write_buffer.size()); - std::memcpy(write_buffer.data(), &guest_addr_in, length); + PutValue(write_buffer, guest_addr_in); return {new_fd, Errno::SUCCESS}; } @@ -619,8 +621,7 @@ Errno BSD::BindImpl(s32 fd, std::span<const u8> addr) { return Errno::BADF; } ASSERT(addr.size() == sizeof(SockAddrIn)); - SockAddrIn addr_in; - std::memcpy(&addr_in, addr.data(), sizeof(addr_in)); + auto addr_in = GetValue<SockAddrIn>(addr); return Translate(file_descriptors[fd]->socket->Bind(Translate(addr_in))); } @@ -631,8 +632,7 @@ Errno BSD::ConnectImpl(s32 fd, std::span<const u8> addr) { } UNIMPLEMENTED_IF(addr.size() != sizeof(SockAddrIn)); - SockAddrIn addr_in; - std::memcpy(&addr_in, addr.data(), sizeof(addr_in)); + auto addr_in = GetValue<SockAddrIn>(addr); return Translate(file_descriptors[fd]->socket->Connect(Translate(addr_in))); } @@ -650,7 +650,7 @@ Errno BSD::GetPeerNameImpl(s32 fd, std::vector<u8>& write_buffer) { ASSERT(write_buffer.size() >= sizeof(guest_addrin)); write_buffer.resize(sizeof(guest_addrin)); - std::memcpy(write_buffer.data(), &guest_addrin, sizeof(guest_addrin)); + PutValue(write_buffer, guest_addrin); return Translate(bsd_errno); } @@ -667,7 +667,7 @@ Errno BSD::GetSockNameImpl(s32 fd, std::vector<u8>& write_buffer) { ASSERT(write_buffer.size() >= sizeof(guest_addrin)); write_buffer.resize(sizeof(guest_addrin)); - std::memcpy(write_buffer.data(), &guest_addrin, sizeof(guest_addrin)); + PutValue(write_buffer, guest_addrin); return Translate(bsd_errno); } @@ -725,7 +725,7 @@ Errno BSD::GetSockOptImpl(s32 fd, u32 level, OptName optname, std::vector<u8>& o optval.size() == sizeof(Errno), { return Errno::INVAL; }, "Incorrect getsockopt option size"); optval.resize(sizeof(Errno)); - memcpy(optval.data(), &translated_pending_err, sizeof(Errno)); + PutValue(optval, translated_pending_err); } return Translate(getsockopt_err); } @@ -735,7 +735,7 @@ Errno BSD::GetSockOptImpl(s32 fd, u32 level, OptName optname, std::vector<u8>& o } } -Errno BSD::SetSockOptImpl(s32 fd, u32 level, OptName optname, size_t optlen, const void* optval) { +Errno BSD::SetSockOptImpl(s32 fd, u32 level, OptName optname, std::span<const u8> optval) { if (!IsFileDescriptorValid(fd)) { return Errno::BADF; } @@ -748,17 +748,15 @@ Errno BSD::SetSockOptImpl(s32 fd, u32 level, OptName optname, size_t optlen, con Network::SocketBase* const socket = file_descriptors[fd]->socket.get(); if (optname == OptName::LINGER) { - ASSERT(optlen == sizeof(Linger)); - Linger linger; - std::memcpy(&linger, optval, sizeof(linger)); + ASSERT(optval.size() == sizeof(Linger)); + auto linger = GetValue<Linger>(optval); ASSERT(linger.onoff == 0 || linger.onoff == 1); return Translate(socket->SetLinger(linger.onoff != 0, linger.linger)); } - ASSERT(optlen == sizeof(u32)); - u32 value; - std::memcpy(&value, optval, sizeof(value)); + ASSERT(optval.size() == sizeof(u32)); + auto value = GetValue<u32>(optval); switch (optname) { case OptName::REUSEADDR: @@ -862,7 +860,7 @@ std::pair<s32, Errno> BSD::RecvFromImpl(s32 fd, u32 flags, std::vector<u8>& mess } else { ASSERT(addr.size() == sizeof(SockAddrIn)); const SockAddrIn result = Translate(addr_in); - std::memcpy(addr.data(), &result, sizeof(result)); + PutValue(addr, result); } } @@ -886,8 +884,7 @@ std::pair<s32, Errno> BSD::SendToImpl(s32 fd, u32 flags, std::span<const u8> mes Network::SockAddrIn* p_addr_in = nullptr; if (!addr.empty()) { ASSERT(addr.size() == sizeof(SockAddrIn)); - SockAddrIn guest_addr_in; - std::memcpy(&guest_addr_in, addr.data(), sizeof(guest_addr_in)); + auto guest_addr_in = GetValue<SockAddrIn>(addr); addr_in = Translate(guest_addr_in); p_addr_in = &addr_in; } diff --git a/src/core/hle/service/sockets/bsd.h b/src/core/hle/service/sockets/bsd.h index 161f22b9b1..4f69d382c9 100644 --- a/src/core/hle/service/sockets/bsd.h +++ b/src/core/hle/service/sockets/bsd.h @@ -163,7 +163,7 @@ private: Errno ListenImpl(s32 fd, s32 backlog); std::pair<s32, Errno> FcntlImpl(s32 fd, FcntlCmd cmd, s32 arg); Errno GetSockOptImpl(s32 fd, u32 level, OptName optname, std::vector<u8>& optval); - Errno SetSockOptImpl(s32 fd, u32 level, OptName optname, size_t optlen, const void* optval); + Errno SetSockOptImpl(s32 fd, u32 level, OptName optname, std::span<const u8> optval); Errno ShutdownImpl(s32 fd, s32 how); std::pair<s32, Errno> RecvImpl(s32 fd, u32 flags, std::vector<u8>& message); std::pair<s32, Errno> RecvFromImpl(s32 fd, u32 flags, std::vector<u8>& message, diff --git a/src/yuzu/configuration/shared_translation.cpp b/src/yuzu/configuration/shared_translation.cpp index 3fe448f27d..1434b1a561 100644 --- a/src/yuzu/configuration/shared_translation.cpp +++ b/src/yuzu/configuration/shared_translation.cpp @@ -156,7 +156,6 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QWidget* parent) { // Ui General INSERT(UISettings, select_user_on_boot, "Prompt for user on game boot", ""); INSERT(UISettings, pause_when_in_background, "Pause emulation when in background", ""); - INSERT(UISettings, confirm_before_closing, "Confirm exit while emulation is running", ""); INSERT(UISettings, confirm_before_stopping, "Confirm before stopping emulation", ""); INSERT(UISettings, hide_mouse, "Hide mouse on inactivity", ""); INSERT(UISettings, controller_applet_disabled, "Disable controller applet", ""); diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index db9da6dc8d..91aba118a4 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -2174,6 +2174,7 @@ void GMainWindow::ShutdownGame() { return; } + play_time_manager->Stop(); OnShutdownBegin(); OnEmulationStopTimeExpired(); OnEmulationStopped(); @@ -3484,7 +3485,7 @@ void GMainWindow::OnExecuteProgram(std::size_t program_index) { } void GMainWindow::OnExit() { - OnStopGame(); + ShutdownGame(); } void GMainWindow::OnSaveConfig() { @@ -4847,7 +4848,12 @@ bool GMainWindow::SelectRomFSDumpTarget(const FileSys::ContentProvider& installe } bool GMainWindow::ConfirmClose() { - if (emu_thread == nullptr || !UISettings::values.confirm_before_closing) { + if (emu_thread == nullptr || + UISettings::values.confirm_before_stopping.GetValue() == ConfirmStop::Ask_Never) { + return true; + } + if (!system->GetExitLocked() && + UISettings::values.confirm_before_stopping.GetValue() == ConfirmStop::Ask_Based_On_Game) { return true; } const auto text = tr("Are you sure you want to close yuzu?"); @@ -4952,7 +4958,7 @@ bool GMainWindow::ConfirmChangeGame() { } bool GMainWindow::ConfirmForceLockedExit() { - if (emu_thread == nullptr || !UISettings::values.confirm_before_closing) { + if (emu_thread == nullptr) { return true; } const auto text = tr("The currently running application has requested yuzu to not exit.\n\n" diff --git a/src/yuzu/uisettings.h b/src/yuzu/uisettings.h index b62ff620ce..77d992c542 100644 --- a/src/yuzu/uisettings.h +++ b/src/yuzu/uisettings.h @@ -93,10 +93,6 @@ struct Values { Setting<bool> show_filter_bar{linkage, true, "showFilterBar", Category::Ui}; Setting<bool> show_status_bar{linkage, true, "showStatusBar", Category::Ui}; - Setting<bool> confirm_before_closing{ - linkage, true, "confirmClose", Category::UiGeneral, Settings::Specialization::Default, - true, true}; - SwitchableSetting<ConfirmStop> confirm_before_stopping{linkage, ConfirmStop::Ask_Always, "confirmStop", |