mirror of
https://github.com/ARMSX2/ARMSX2.git
synced 2026-08-24 16:50:16 -07:00
1345 lines
69 KiB
Diff
1345 lines
69 KiB
Diff
diff --git a/app/src/main/cpp/ARMSX2Bridge.h b/app/src/main/cpp/ARMSX2Bridge.h
|
|
index 10d02ab9a..2b8edaf5e 100644
|
|
--- a/app/src/main/cpp/ARMSX2Bridge.h
|
|
+++ b/app/src/main/cpp/ARMSX2Bridge.h
|
|
@@ -13,8 +13,10 @@ typedef NS_ENUM(NSInteger, ARMSX2EmulatorState) {
|
|
};
|
|
|
|
typedef NS_ENUM(NSInteger, ARMSX2CoreType) {
|
|
- ARMSX2CoreTypeJIT = 0,
|
|
+ ARMSX2CoreTypeLegacyRecompiler = 0,
|
|
ARMSX2CoreTypeInterpreter = 1,
|
|
+ ARMSX2CoreTypeARM64JIT = 2,
|
|
+ ARMSX2CoreTypeJIT = ARMSX2CoreTypeARM64JIT,
|
|
};
|
|
|
|
typedef NS_ENUM(NSInteger, ARMSX2PadButton) {
|
|
diff --git a/app/src/main/cpp/ARMSX2Bridge.mm b/app/src/main/cpp/ARMSX2Bridge.mm
|
|
index 4001e2531..ad35fd478 100644
|
|
--- a/app/src/main/cpp/ARMSX2Bridge.mm
|
|
+++ b/app/src/main/cpp/ARMSX2Bridge.mm
|
|
@@ -18,7 +18,9 @@
|
|
#include "common/Path.h"
|
|
#include "common/ZipHelpers.h"
|
|
|
|
+#include <algorithm>
|
|
#include <cstdio>
|
|
+#include <cstring>
|
|
#include <future>
|
|
#include <optional>
|
|
#include <string_view>
|
|
@@ -89,6 +91,49 @@ static BOOL ARMSX2GetCurrentSaveStateIdentity(std::string* serial, u32* crc)
|
|
return [NSData dataWithBytes:data->data() length:data->size()];
|
|
}
|
|
|
|
+static void ARMSX2ApplyLiveGSBoolSetting(const char* section, const char* key, bool value)
|
|
+{
|
|
+ if (std::strcmp(section, "EmuCore/GS") != 0)
|
|
+ return;
|
|
+
|
|
+#define APPLY_OSD_BOOL(name) \
|
|
+ do { \
|
|
+ if (std::strcmp(key, #name) == 0) { \
|
|
+ EmuConfig.GS.name = value; \
|
|
+ GSConfig.name = value; \
|
|
+ return; \
|
|
+ } \
|
|
+ } while (0)
|
|
+
|
|
+ APPLY_OSD_BOOL(OsdShowFPS);
|
|
+ APPLY_OSD_BOOL(OsdShowVPS);
|
|
+ APPLY_OSD_BOOL(OsdShowSpeed);
|
|
+ APPLY_OSD_BOOL(OsdShowCPU);
|
|
+ APPLY_OSD_BOOL(OsdShowGPU);
|
|
+ APPLY_OSD_BOOL(OsdShowResolution);
|
|
+ APPLY_OSD_BOOL(OsdShowGSStats);
|
|
+ APPLY_OSD_BOOL(OsdShowIndicators);
|
|
+ APPLY_OSD_BOOL(OsdShowSettings);
|
|
+ APPLY_OSD_BOOL(OsdShowInputs);
|
|
+ APPLY_OSD_BOOL(OsdShowFrameTimes);
|
|
+ APPLY_OSD_BOOL(OsdShowVersion);
|
|
+ APPLY_OSD_BOOL(OsdShowHardwareInfo);
|
|
+ APPLY_OSD_BOOL(OsdShowVideoCapture);
|
|
+ APPLY_OSD_BOOL(OsdShowInputRec);
|
|
+
|
|
+#undef APPLY_OSD_BOOL
|
|
+}
|
|
+
|
|
+static void ARMSX2ApplyLiveGSIntSetting(const char* section, const char* key, int value)
|
|
+{
|
|
+ if (std::strcmp(section, "EmuCore/GS") != 0 || std::strcmp(key, "OsdPerformancePos") != 0)
|
|
+ return;
|
|
+
|
|
+ const int clamped = std::clamp(value, static_cast<int>(OsdOverlayPos::None), static_cast<int>(OsdOverlayPos::TopRight));
|
|
+ EmuConfig.GS.OsdPerformancePos = static_cast<OsdOverlayPos>(clamped);
|
|
+ GSConfig.OsdPerformancePos = static_cast<OsdOverlayPos>(clamped);
|
|
+}
|
|
+
|
|
@implementation ARMSX2Bridge
|
|
|
|
+ (UIView *)gameRenderView {
|
|
@@ -195,7 +240,7 @@ + (nonnull NSString *)biosName {
|
|
+ (void)requestVMStop {
|
|
extern std::atomic<bool> s_requestVMStop;
|
|
s_requestVMStop.store(true);
|
|
- [[NSNotificationCenter defaultCenter] postNotificationName:@"ARMSX2iOSVMDidShutdown" object:nil];
|
|
+ NSLog(@"[ARMSX2Bridge] VM stop requested");
|
|
}
|
|
|
|
+ (void)setFullScreen:(BOOL)enabled {
|
|
@@ -209,7 +254,9 @@ + (nonnull NSString *)buildVersion {
|
|
|
|
+ (nullable NSString *)currentISOPath {
|
|
NSString *docsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
|
|
- NSString *iniPath = [docsPath stringByAppendingPathComponent:@"PCSX2-iOS.ini"];
|
|
+ NSString *iniPath = [docsPath stringByAppendingPathComponent:@"ARMSX2-iOS.ini"];
|
|
+ if (![[NSFileManager defaultManager] fileExistsAtPath:iniPath])
|
|
+ iniPath = [docsPath stringByAppendingPathComponent:@"PCSX2-iOS.ini"];
|
|
// Read BootISO from INI
|
|
FILE *f = fopen(iniPath.UTF8String, "r");
|
|
if (!f) return nil;
|
|
@@ -310,28 +357,60 @@ + (void)applyOsdPreset:(int)preset {
|
|
GSConfig.OsdShowFrameTimes = false;
|
|
GSConfig.OsdShowVersion = false;
|
|
GSConfig.OsdShowHardwareInfo = false;
|
|
+ GSConfig.OsdShowIndicators = false;
|
|
+ GSConfig.OsdShowSettings = false;
|
|
+ GSConfig.OsdShowInputs = false;
|
|
+ GSConfig.OsdShowVideoCapture = false;
|
|
+ GSConfig.OsdShowInputRec = false;
|
|
|
|
switch (preset) {
|
|
- case 1: // simple: FPS + CPU usage
|
|
+ case 1: // simple: Android-style quick readout
|
|
GSConfig.OsdShowFPS = true;
|
|
+ GSConfig.OsdShowSpeed = true;
|
|
GSConfig.OsdShowCPU = true;
|
|
+ GSConfig.OsdShowIndicators = true;
|
|
break;
|
|
- case 2: // detail: simple + speed + resolution
|
|
+ case 2: // detail: performance and renderer diagnostics
|
|
GSConfig.OsdShowFPS = true;
|
|
+ GSConfig.OsdShowVPS = true;
|
|
GSConfig.OsdShowSpeed = true;
|
|
GSConfig.OsdShowCPU = true;
|
|
+ GSConfig.OsdShowGPU = true;
|
|
GSConfig.OsdShowResolution = true;
|
|
+ GSConfig.OsdShowIndicators = true;
|
|
break;
|
|
- case 3: // full: detail + frame times
|
|
+ case 3: // full: closest to Android's full stats section
|
|
GSConfig.OsdShowFPS = true;
|
|
+ GSConfig.OsdShowVPS = true;
|
|
GSConfig.OsdShowSpeed = true;
|
|
GSConfig.OsdShowCPU = true;
|
|
+ GSConfig.OsdShowGPU = true;
|
|
GSConfig.OsdShowResolution = true;
|
|
+ GSConfig.OsdShowGSStats = true;
|
|
GSConfig.OsdShowFrameTimes = true;
|
|
+ GSConfig.OsdShowVersion = true;
|
|
+ GSConfig.OsdShowHardwareInfo = true;
|
|
+ GSConfig.OsdShowIndicators = true;
|
|
+ GSConfig.OsdShowSettings = true;
|
|
+ GSConfig.OsdShowInputs = true;
|
|
break;
|
|
default: // 0 = off
|
|
break;
|
|
}
|
|
+
|
|
+ EmuConfig.GS.OsdShowFPS = GSConfig.OsdShowFPS;
|
|
+ EmuConfig.GS.OsdShowVPS = GSConfig.OsdShowVPS;
|
|
+ EmuConfig.GS.OsdShowSpeed = GSConfig.OsdShowSpeed;
|
|
+ EmuConfig.GS.OsdShowCPU = GSConfig.OsdShowCPU;
|
|
+ EmuConfig.GS.OsdShowGPU = GSConfig.OsdShowGPU;
|
|
+ EmuConfig.GS.OsdShowResolution = GSConfig.OsdShowResolution;
|
|
+ EmuConfig.GS.OsdShowGSStats = GSConfig.OsdShowGSStats;
|
|
+ EmuConfig.GS.OsdShowFrameTimes = GSConfig.OsdShowFrameTimes;
|
|
+ EmuConfig.GS.OsdShowVersion = GSConfig.OsdShowVersion;
|
|
+ EmuConfig.GS.OsdShowHardwareInfo = GSConfig.OsdShowHardwareInfo;
|
|
+ EmuConfig.GS.OsdShowIndicators = GSConfig.OsdShowIndicators;
|
|
+ EmuConfig.GS.OsdShowSettings = GSConfig.OsdShowSettings;
|
|
+ EmuConfig.GS.OsdShowInputs = GSConfig.OsdShowInputs;
|
|
}
|
|
|
|
// ============================================================
|
|
@@ -438,12 +517,14 @@ + (void)setINIInt:(nonnull NSString *)section key:(nonnull NSString *)key value:
|
|
if (!g_p44_settings_interface) return;
|
|
g_p44_settings_interface->SetIntValue(section.UTF8String, key.UTF8String, value);
|
|
g_p44_settings_interface->Save();
|
|
+ ARMSX2ApplyLiveGSIntSetting(section.UTF8String, key.UTF8String, value);
|
|
}
|
|
|
|
+ (void)setINIBool:(nonnull NSString *)section key:(nonnull NSString *)key value:(BOOL)value {
|
|
if (!g_p44_settings_interface) return;
|
|
g_p44_settings_interface->SetBoolValue(section.UTF8String, key.UTF8String, value);
|
|
g_p44_settings_interface->Save();
|
|
+ ARMSX2ApplyLiveGSBoolSetting(section.UTF8String, key.UTF8String, value);
|
|
}
|
|
|
|
+ (void)setINIFloat:(nonnull NSString *)section key:(nonnull NSString *)key value:(float)value {
|
|
diff --git a/app/src/main/cpp/CMakeLists.txt b/app/src/main/cpp/CMakeLists.txt
|
|
index 8e72c0431..76e8ab8c5 100644
|
|
--- a/app/src/main/cpp/CMakeLists.txt
|
|
+++ b/app/src/main/cpp/CMakeLists.txt
|
|
@@ -228,7 +228,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "iOS")
|
|
XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS "@executable_path/Frameworks /usr/lib/swift"
|
|
XCODE_ATTRIBUTE_LIBRARY_SEARCH_PATHS "$(inherited) $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) /usr/lib/swift"
|
|
XCODE_ATTRIBUTE_OTHER_SWIFT_FLAGS ""
|
|
- XCODE_ATTRIBUTE_MTL_HEADER_SEARCH_PATHS "${CMAKE_SOURCE_DIR}/pcsx2/GS/Renderers/Metal ${CMAKE_SOURCE_DIR}/../assets"
|
|
+ XCODE_ATTRIBUTE_MTL_HEADER_SEARCH_PATHS "${CMAKE_SOURCE_DIR}/pcsx2/GS/Renderers/Metal ${CMAKE_SOURCE_DIR}/3rdparty/include ${CMAKE_SOURCE_DIR}/../assets ${CMAKE_SOURCE_DIR}/../assets/resources"
|
|
XCODE_ATTRIBUTE_MTL_ENABLE_DEBUG_INFO "$<IF:$<CONFIG:Debug>,INCLUDE_SOURCE,>"
|
|
)
|
|
|
|
diff --git a/app/src/main/cpp/cmake/BuildParameters.cmake b/app/src/main/cpp/cmake/BuildParameters.cmake
|
|
index 88bacfb79..7420144b2 100644
|
|
--- a/app/src/main/cpp/cmake/BuildParameters.cmake
|
|
+++ b/app/src/main/cpp/cmake/BuildParameters.cmake
|
|
@@ -119,7 +119,7 @@ elseif("${CMAKE_HOST_SYSTEM_PROCESSOR}" STREQUAL "arm64" OR "${CMAKE_HOST_SYSTEM
|
|
# add_compile_options("-march=armv8.4-a" "-mcpu=apple-m1")
|
|
|
|
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
|
- add_definitions("-march=armv8-a+crc")
|
|
+ add_compile_options("$<$<COMPILE_LANGUAGE:C,CXX,OBJC,OBJCXX>:-march=armv8-a+crc>")
|
|
|
|
# If we're running on Linux, we need to detect the page/cache line size.
|
|
# It could be a virtual machine with 4K pages, or 16K with Asahi.
|
|
@@ -159,7 +159,11 @@ if(MSVC)
|
|
# Disable Exceptions
|
|
string(REPLACE "/EHsc" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
|
|
else()
|
|
- add_compile_options(-pipe -fvisibility=hidden -pthread)
|
|
+ add_compile_options(
|
|
+ "$<$<COMPILE_LANGUAGE:C,CXX,OBJC,OBJCXX>:-pipe>"
|
|
+ "$<$<COMPILE_LANGUAGE:C,CXX,OBJC,OBJCXX>:-fvisibility=hidden>"
|
|
+ "$<$<COMPILE_LANGUAGE:C,CXX,OBJC,OBJCXX>:-pthread>"
|
|
+ )
|
|
add_compile_options(
|
|
"$<$<COMPILE_LANGUAGE:CXX>:-fno-exceptions>"
|
|
)
|
|
diff --git a/app/src/main/cpp/common/Darwin/DarwinMisc.cpp b/app/src/main/cpp/common/Darwin/DarwinMisc.cpp
|
|
index 624bf70f5..3c2fd9056 100644
|
|
--- a/app/src/main/cpp/common/Darwin/DarwinMisc.cpp
|
|
+++ b/app/src/main/cpp/common/Darwin/DarwinMisc.cpp
|
|
@@ -832,6 +832,10 @@ void DarwinMisc::MunmapCodeDualMap(void* rx_ptr, size_t size)
|
|
|
|
bool DarwinMisc::IsJITAvailable()
|
|
{
|
|
+ static std::optional<bool> s_cached_jit_available;
|
|
+ if (s_cached_jit_available.has_value())
|
|
+ return *s_cached_jit_available;
|
|
+
|
|
#if ARMSX2_APPLE_IOS_DEVICE
|
|
uint32_t cs_flags = 0;
|
|
int rv = csops(getpid(), 0, &cs_flags, sizeof(cs_flags));
|
|
@@ -844,11 +848,13 @@ bool DarwinMisc::IsJITAvailable()
|
|
fprintf(stderr, "@@JIT_DETECT@@ result=UNAVAILABLE (no CS_DEBUGGED — launch via StikDebug)\n");
|
|
s_jit_mode = JitMode::Legacy;
|
|
s_jit_mode_detected = true;
|
|
- return false;
|
|
+ s_cached_jit_available = false;
|
|
+ return *s_cached_jit_available;
|
|
}
|
|
|
|
fprintf(stderr, "@@JIT_DETECT@@ result=AVAILABLE (CS_DEBUGGED set)\n");
|
|
- return true;
|
|
+ s_cached_jit_available = true;
|
|
+ return *s_cached_jit_available;
|
|
#else
|
|
const size_t probe_size = static_cast<size_t>(getpagesize());
|
|
void* probe = mmap(nullptr, probe_size, PROT_READ | PROT_WRITE | PROT_EXEC,
|
|
@@ -856,12 +862,14 @@ bool DarwinMisc::IsJITAvailable()
|
|
if (probe == MAP_FAILED)
|
|
{
|
|
fprintf(stderr, "@@JIT_DETECT@@ MAP_JIT probe failed errno=%d\n", errno);
|
|
- return false;
|
|
+ s_cached_jit_available = false;
|
|
+ return *s_cached_jit_available;
|
|
}
|
|
|
|
munmap(probe, probe_size);
|
|
fprintf(stderr, "@@JIT_DETECT@@ MAP_JIT probe result=AVAILABLE\n");
|
|
- return true;
|
|
+ s_cached_jit_available = true;
|
|
+ return *s_cached_jit_available;
|
|
#endif
|
|
}
|
|
|
|
@@ -1088,8 +1096,21 @@ void HostSys::BeginCodeWrite()
|
|
}
|
|
} else {
|
|
static auto func = reinterpret_cast<void(*)(int)>(dlsym(RTLD_DEFAULT, "pthread_jit_write_protect_np"));
|
|
+ static bool s_logged_pthread_jit_begin = false;
|
|
if (func)
|
|
+ {
|
|
+ if (!s_logged_pthread_jit_begin)
|
|
+ {
|
|
+ fprintf(stderr, "@@JIT_WRITE_PROTECT@@ pthread_jit_write_protect_np available=1 action=begin_write protect=0\n");
|
|
+ s_logged_pthread_jit_begin = true;
|
|
+ }
|
|
func(0);
|
|
+ }
|
|
+ else if (!s_logged_pthread_jit_begin)
|
|
+ {
|
|
+ fprintf(stderr, "@@JIT_WRITE_PROTECT@@ pthread_jit_write_protect_np available=0 action=begin_write\n");
|
|
+ s_logged_pthread_jit_begin = true;
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
@@ -1120,8 +1141,21 @@ void HostSys::EndCodeWrite()
|
|
}
|
|
} else {
|
|
static auto func = reinterpret_cast<void(*)(int)>(dlsym(RTLD_DEFAULT, "pthread_jit_write_protect_np"));
|
|
+ static bool s_logged_pthread_jit_end = false;
|
|
if (func)
|
|
+ {
|
|
+ if (!s_logged_pthread_jit_end)
|
|
+ {
|
|
+ fprintf(stderr, "@@JIT_WRITE_PROTECT@@ pthread_jit_write_protect_np available=1 action=end_write protect=1\n");
|
|
+ s_logged_pthread_jit_end = true;
|
|
+ }
|
|
func(1);
|
|
+ }
|
|
+ else if (!s_logged_pthread_jit_end)
|
|
+ {
|
|
+ fprintf(stderr, "@@JIT_WRITE_PROTECT@@ pthread_jit_write_protect_np available=0 action=end_write\n");
|
|
+ s_logged_pthread_jit_end = true;
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
diff --git a/app/src/main/cpp/ios_main.mm b/app/src/main/cpp/ios_main.mm
|
|
index e688872dc..431562f55 100644
|
|
--- a/app/src/main/cpp/ios_main.mm
|
|
+++ b/app/src/main/cpp/ios_main.mm
|
|
@@ -22,6 +22,7 @@
|
|
#include <cstdio>
|
|
#include <cstring>
|
|
#include <string>
|
|
+#include <string_view>
|
|
#include <iostream>
|
|
#include <algorithm>
|
|
#include <deque>
|
|
@@ -729,6 +730,7 @@ void DestroyMetalLayer(WindowInfo* wi) {
|
|
#include "pcsx2/INISettingsInterface.h"
|
|
|
|
static INISettingsInterface* s_settings_interface = nullptr;
|
|
+static std::string s_iosSettingsPath;
|
|
// Expose to ARMSX2Bridge.mm via extern
|
|
INISettingsInterface* g_p44_settings_interface = nullptr;
|
|
|
|
@@ -826,22 +828,36 @@ static void ARMSX2LogIOSSettingsSnapshot(const char* tag, INISettingsInterface*
|
|
const bool recVU0 = si->GetBoolValue("EmuCore/CPU/Recompiler", "EnableVU0", false);
|
|
const bool recVU1 = si->GetBoolValue("EmuCore/CPU/Recompiler", "EnableVU1", false);
|
|
const bool extraMemory = si->GetBoolValue("EmuCore/CPU", "ExtraMemory", false);
|
|
+ const bool fastmem = si->GetBoolValue("EmuCore/CPU/Recompiler", "EnableFastmem", false);
|
|
const int gsRenderer = si->GetIntValue("EmuCore/GS", "Renderer", -999);
|
|
const int vsyncQueue = si->GetIntValue("EmuCore/GS", "VsyncQueueSize", -999);
|
|
const bool mtvu = si->GetBoolValue("EmuCore/Speedhacks", "MTVU", false);
|
|
const bool vuThread = si->GetBoolValue("EmuCore/Speedhacks", "vuThread", false);
|
|
+ const std::string bootISO = si->GetStringValue("GameISO", "BootISO", "");
|
|
+ const std::string biosName = si->GetStringValue("Filenames", "BIOS", "");
|
|
+#if ARMSX2_APPLE_MAC_RUNTIME
|
|
+ const bool jitAvailable = true;
|
|
+ const bool noJitActive = false;
|
|
+#else
|
|
+ const bool forceEEInterp = (DarwinMisc::ARMSX2_FORCE_EE_INTERP != 0);
|
|
+ const bool forceJit = (DarwinMisc::ARMSX2_FORCE_JIT != 0);
|
|
+ const bool jitAvailable = forceJit || (!forceEEInterp && DarwinMisc::IsJITAvailable());
|
|
+ const bool noJitActive = forceEEInterp || (!forceJit && !jitAvailable) || cpuCore == 1;
|
|
+#endif
|
|
|
|
fprintf(stderr,
|
|
- "@@IOS_SETTINGS@@ tag=%s si=%p spu2_backend=%s cpu_core=%d arm64_dynarec=%d rec_ee=%d rec_iop=%d rec_vu0=%d rec_vu1=%d extra_memory=%d gs_renderer=%d vsync_queue=%d mtvu=%d vu_thread=%d\n",
|
|
- tag, si, spu2Backend.c_str(), cpuCore, arm64Dynarec ? 1 : 0, recEE ? 1 : 0, recIOP ? 1 : 0,
|
|
- recVU0 ? 1 : 0, recVU1 ? 1 : 0, extraMemory ? 1 : 0, gsRenderer, vsyncQueue, mtvu ? 1 : 0,
|
|
- vuThread ? 1 : 0);
|
|
+ "@@IOS_SETTINGS@@ tag=%s si=%p config_path=%s data_root=%s bios_dir=%s boot_iso=\"%s\" bios_name=\"%s\" spu2_backend=%s cpu_core=%d arm64_dynarec=%d rec_ee=%d rec_iop=%d rec_vu0=%d rec_vu1=%d fastmem=%d extra_memory=%d gs_renderer=%d vsync_queue=%d mtvu=%d vu_thread=%d jit_available=%d no_jit_active=%d\n",
|
|
+ tag, si, s_iosSettingsPath.c_str(), EmuFolders::DataRoot.c_str(), EmuFolders::Bios.c_str(), bootISO.c_str(),
|
|
+ biosName.c_str(), spu2Backend.c_str(), cpuCore, arm64Dynarec ? 1 : 0, recEE ? 1 : 0, recIOP ? 1 : 0,
|
|
+ recVU0 ? 1 : 0, recVU1 ? 1 : 0, fastmem ? 1 : 0, extraMemory ? 1 : 0, gsRenderer, vsyncQueue,
|
|
+ mtvu ? 1 : 0, vuThread ? 1 : 0, jitAvailable ? 1 : 0, noJitActive ? 1 : 0);
|
|
fflush(stderr);
|
|
Console.WriteLn(
|
|
- "@@IOS_SETTINGS@@ tag=%s si=%p spu2_backend=%s cpu_core=%d arm64_dynarec=%d rec_ee=%d rec_iop=%d rec_vu0=%d rec_vu1=%d extra_memory=%d gs_renderer=%d vsync_queue=%d mtvu=%d vu_thread=%d",
|
|
- tag, si, spu2Backend.c_str(), cpuCore, arm64Dynarec ? 1 : 0, recEE ? 1 : 0, recIOP ? 1 : 0,
|
|
- recVU0 ? 1 : 0, recVU1 ? 1 : 0, extraMemory ? 1 : 0, gsRenderer, vsyncQueue, mtvu ? 1 : 0,
|
|
- vuThread ? 1 : 0);
|
|
+ "@@IOS_SETTINGS@@ tag=%s si=%p config_path=%s data_root=%s bios_dir=%s boot_iso=\"%s\" bios_name=\"%s\" spu2_backend=%s cpu_core=%d arm64_dynarec=%d rec_ee=%d rec_iop=%d rec_vu0=%d rec_vu1=%d fastmem=%d extra_memory=%d gs_renderer=%d vsync_queue=%d mtvu=%d vu_thread=%d jit_available=%d no_jit_active=%d",
|
|
+ tag, si, s_iosSettingsPath.c_str(), EmuFolders::DataRoot.c_str(), EmuFolders::Bios.c_str(), bootISO.c_str(),
|
|
+ biosName.c_str(), spu2Backend.c_str(), cpuCore, arm64Dynarec ? 1 : 0, recEE ? 1 : 0, recIOP ? 1 : 0,
|
|
+ recVU0 ? 1 : 0, recVU1 ? 1 : 0, fastmem ? 1 : 0, extraMemory ? 1 : 0, gsRenderer, vsyncQueue,
|
|
+ mtvu ? 1 : 0, vuThread ? 1 : 0, jitAvailable ? 1 : 0, noJitActive ? 1 : 0);
|
|
}
|
|
|
|
static constexpr const char* ARMSX2_IOS_JIT_SECTION = "ARMSX2iOS/JIT";
|
|
@@ -894,6 +910,36 @@ static void ARMSX2RestoreIOSJitDefaults(INISettingsInterface* si)
|
|
si->SetBoolValue("EmuCore/CPU/Recompiler", "EnableFastmem", true);
|
|
}
|
|
|
|
+static const char* ARMSX2NormalizeGSAspectRatio(std::string_view value)
|
|
+{
|
|
+ if (value == "Stretch" || value == "0")
|
|
+ return "Stretch";
|
|
+ if (value == "Auto 4:3/3:2" || value == "1")
|
|
+ return "Auto 4:3/3:2";
|
|
+ if (value == "4:3" || value == "2")
|
|
+ return "4:3";
|
|
+ if (value == "16:9" || value == "3")
|
|
+ return "16:9";
|
|
+ if (value == "10:7" || value == "4")
|
|
+ return "10:7";
|
|
+ return nullptr;
|
|
+}
|
|
+
|
|
+static const char* ARMSX2NormalizeGSFMVAspectRatioSwitch(std::string_view value)
|
|
+{
|
|
+ if (value == "Off" || value == "0")
|
|
+ return "Off";
|
|
+ if (value == "Auto 4:3/3:2" || value == "1")
|
|
+ return "Auto 4:3/3:2";
|
|
+ if (value == "4:3" || value == "2")
|
|
+ return "4:3";
|
|
+ if (value == "16:9" || value == "3")
|
|
+ return "16:9";
|
|
+ if (value == "10:7" || value == "4")
|
|
+ return "10:7";
|
|
+ return nullptr;
|
|
+}
|
|
+
|
|
static void ARMSX2ApplyIOSRuntimeDefaults(INISettingsInterface* si)
|
|
{
|
|
if (!si)
|
|
@@ -948,9 +994,10 @@ static void ARMSX2ApplyIOSRuntimeDefaults(INISettingsInterface* si)
|
|
si->SetBoolValue("EmuCore/CPU/Recompiler", "EnableVU1", true);
|
|
si->SetBoolValue("EmuCore/CPU/Recompiler", "EnableFastmem", true);
|
|
#else
|
|
+ const int configured_core_type = si->GetIntValue("EmuCore/CPU", "CoreType", 2);
|
|
if (!si->ContainsValue("EmuCore/CPU", "CoreType"))
|
|
si->SetIntValue("EmuCore/CPU", "CoreType", 2);
|
|
- if (!si->ContainsValue("EmuCore/CPU", "UseArm64Dynarec"))
|
|
+ if (configured_core_type == 2 || !si->ContainsValue("EmuCore/CPU", "UseArm64Dynarec"))
|
|
si->SetBoolValue("EmuCore/CPU", "UseArm64Dynarec", true);
|
|
if (!si->ContainsValue("EmuCore/CPU/Recompiler", "EnableEE"))
|
|
si->SetBoolValue("EmuCore/CPU/Recompiler", "EnableEE", true);
|
|
@@ -984,8 +1031,25 @@ static void ARMSX2ApplyIOSRuntimeDefaults(INISettingsInterface* si)
|
|
break;
|
|
}
|
|
#endif
|
|
- si->SetStringValue("EmuCore/GS", "AspectRatio", "Auto 4:3/3:2");
|
|
- si->SetStringValue("EmuCore/GS", "FMVAspectRatioSwitch", "Off");
|
|
+ const std::string configured_aspect_ratio = si->GetStringValue("EmuCore/GS", "AspectRatio", "");
|
|
+ const char* normalized_aspect_ratio = ARMSX2NormalizeGSAspectRatio(configured_aspect_ratio);
|
|
+ if (!normalized_aspect_ratio) {
|
|
+ Console.Warning("@@IOS_SETTINGS@@ invalid AspectRatio=\"%s\" fallback=\"Auto 4:3/3:2\"",
|
|
+ configured_aspect_ratio.c_str());
|
|
+ normalized_aspect_ratio = "Auto 4:3/3:2";
|
|
+ }
|
|
+ if (configured_aspect_ratio != normalized_aspect_ratio)
|
|
+ si->SetStringValue("EmuCore/GS", "AspectRatio", normalized_aspect_ratio);
|
|
+
|
|
+ const std::string configured_fmv_aspect = si->GetStringValue("EmuCore/GS", "FMVAspectRatioSwitch", "");
|
|
+ const char* normalized_fmv_aspect = ARMSX2NormalizeGSFMVAspectRatioSwitch(configured_fmv_aspect);
|
|
+ if (!normalized_fmv_aspect) {
|
|
+ Console.Warning("@@IOS_SETTINGS@@ invalid FMVAspectRatioSwitch=\"%s\" fallback=\"Off\"",
|
|
+ configured_fmv_aspect.c_str());
|
|
+ normalized_fmv_aspect = "Off";
|
|
+ }
|
|
+ if (configured_fmv_aspect != normalized_fmv_aspect)
|
|
+ si->SetStringValue("EmuCore/GS", "FMVAspectRatioSwitch", normalized_fmv_aspect);
|
|
ARMSX2ClampINIInt(si, "EmuCore/GS", "VsyncQueueSize", 2, 0, 8);
|
|
ARMSX2ClampINIInt(si, "EmuCore/GS", "deinterlace_mode", static_cast<int>(GSInterlaceMode::Automatic), 0, static_cast<int>(GSInterlaceMode::Count) - 1);
|
|
ARMSX2ClampINIInt(si, "EmuCore/GS", "accurate_blending_unit", static_cast<int>(AccBlendLevel::Basic), 0, static_cast<int>(AccBlendLevel::Maximum));
|
|
@@ -1026,12 +1090,12 @@ - (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session op
|
|
|
|
// --- SDL Initialization ---
|
|
static bool s_initialized = false;
|
|
- if (!s_initialized) {
|
|
- SDL_SetMainReady();
|
|
- if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_GAMEPAD) < 0) {
|
|
- NSLog(@"SDL_Init failed: %s", SDL_GetError());
|
|
- return;
|
|
- }
|
|
+ if (!s_initialized) {
|
|
+ SDL_SetMainReady();
|
|
+ if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_GAMEPAD)) {
|
|
+ NSLog(@"SDL_Init failed: %s", SDL_GetError());
|
|
+ return;
|
|
+ }
|
|
s_initialized = true;
|
|
}
|
|
|
|
@@ -1059,6 +1123,7 @@ - (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session op
|
|
}
|
|
|
|
std::string iniPath = [iniPathString UTF8String];
|
|
+ s_iosSettingsPath = iniPath;
|
|
s_settings_interface = new INISettingsInterface(iniPath);
|
|
if (!static_cast<INISettingsInterface*>(s_settings_interface)->Load()) {
|
|
Console.WriteLn("Creating new config at %s", iniPath.c_str());
|
|
@@ -1509,8 +1574,17 @@ - (void)checkJITAndStartVM {
|
|
const bool force_jit = (DarwinMisc::ARMSX2_FORCE_JIT != 0);
|
|
const bool jit_available = force_jit || (!force_ee_interp && DarwinMisc::IsJITAvailable());
|
|
const bool jit_unavailable = !force_ee_interp && !force_jit && !jit_available;
|
|
+ const bool config_interpreter = ARMSX2IOSConfigRequestsInterpreter(s_settings_interface);
|
|
+ const char* fallback_reason =
|
|
+ force_ee_interp ? "env_force_ee_interp" :
|
|
+ (config_interpreter ? "config_interpreter" :
|
|
+ (jit_unavailable ? "jit_unavailable" : "none"));
|
|
|
|
- if (!jit_available || force_ee_interp || ARMSX2IOSConfigRequestsInterpreter(s_settings_interface)) {
|
|
+ Console.WriteLn("@@JIT_GATE@@ force_ee_interp=%d force_jit=%d jit_available=%d config_interpreter=%d fallback_reason=%s",
|
|
+ force_ee_interp ? 1 : 0, force_jit ? 1 : 0, jit_available ? 1 : 0, config_interpreter ? 1 : 0,
|
|
+ fallback_reason);
|
|
+
|
|
+ if (!jit_available || force_ee_interp || config_interpreter) {
|
|
if (s_settings_interface) {
|
|
if (jit_unavailable)
|
|
ARMSX2SetAutoNoJitFallback(s_settings_interface);
|
|
@@ -1727,6 +1801,35 @@ - (void)startVMThread {
|
|
}
|
|
|
|
const std::string bios_path = Path::Combine(EmuFolders::Bios, EmuConfig.BaseFilenames.Bios);
|
|
+ const std::string selected_game_path =
|
|
+ !boot_params.elf_override.empty() ? boot_params.elf_override :
|
|
+ (!boot_params.filename.empty() ? boot_params.filename : std::string());
|
|
+ const bool boot_arm64_dynarec =
|
|
+ s_settings_interface ? s_settings_interface->GetBoolValue("EmuCore/CPU", "UseArm64Dynarec", EmuConfig.Cpu.CoreType == 2) :
|
|
+ (EmuConfig.Cpu.CoreType == 2);
|
|
+#if ARMSX2_APPLE_MAC_RUNTIME
|
|
+ const bool boot_jit_available = true;
|
|
+ const bool boot_no_jit_active = false;
|
|
+ const char* boot_fallback_reason = "none";
|
|
+#else
|
|
+ const bool boot_force_ee_interp = (DarwinMisc::ARMSX2_FORCE_EE_INTERP != 0);
|
|
+ const bool boot_force_jit = (DarwinMisc::ARMSX2_FORCE_JIT != 0);
|
|
+ const bool boot_jit_available = boot_force_jit || (!boot_force_ee_interp && DarwinMisc::IsJITAvailable());
|
|
+ const bool boot_no_jit_active = boot_force_ee_interp || (!boot_force_jit && !boot_jit_available) || EmuConfig.Cpu.CoreType == 1;
|
|
+ const char* boot_fallback_reason =
|
|
+ boot_force_ee_interp ? "env_force_ee_interp" :
|
|
+ (EmuConfig.Cpu.CoreType == 1 ? "config_interpreter" :
|
|
+ (!boot_jit_available ? "jit_unavailable" : "none"));
|
|
+#endif
|
|
+ Console.WriteLn(
|
|
+ "@@IOS_BOOT_DIAG@@ config_path=%s data_root=%s bios_dir=%s bios_name=\"%s\" bios_path=%s bios_exists=%d game_path=%s renderer=%d core_type=%d arm64_dynarec=%d ee_rec=%d iop_rec=%d vu0_rec=%d vu1_rec=%d fastmem=%d jit_available=%d no_jit_active=%d fallback_reason=%s",
|
|
+ s_iosSettingsPath.c_str(), EmuFolders::DataRoot.c_str(), EmuFolders::Bios.c_str(),
|
|
+ EmuConfig.BaseFilenames.Bios.c_str(), bios_path.c_str(), FileSystem::FileExists(bios_path.c_str()) ? 1 : 0,
|
|
+ selected_game_path.c_str(), static_cast<int>(EmuConfig.GS.Renderer), EmuConfig.Cpu.CoreType,
|
|
+ boot_arm64_dynarec ? 1 : 0, EmuConfig.Cpu.Recompiler.EnableEE ? 1 : 0,
|
|
+ EmuConfig.Cpu.Recompiler.EnableIOP ? 1 : 0, EmuConfig.Cpu.Recompiler.EnableVU0 ? 1 : 0,
|
|
+ EmuConfig.Cpu.Recompiler.EnableVU1 ? 1 : 0, EmuConfig.Cpu.Recompiler.EnableFastmem ? 1 : 0,
|
|
+ boot_jit_available ? 1 : 0, boot_no_jit_active ? 1 : 0, boot_fallback_reason);
|
|
#if ARMSX2_APPLE_MAC_RUNTIME
|
|
const bool mac_fast_boot_value = boot_params.fast_boot.value_or(false);
|
|
LogUnified("@@MAC_VM_BOOT_PARAMS@@ filename=%s elf=%s source_type=%d fast_boot=%d bios_name=%s bios_path=%s bios_exists=%d renderer=%d cpu_core=%d rec_ee=%d rec_iop=%d rec_vu0=%d rec_vu1=%d\n",
|
|
@@ -1842,18 +1945,26 @@ - (void)startVMThread {
|
|
}
|
|
|
|
- (void)sceneDidDisconnect:(UIScene *)scene {
|
|
+ Console.WriteLn("@@IOS_LIFECYCLE@@ sceneDidDisconnect vm_state=%d active=%d",
|
|
+ static_cast<int>(VMManager::GetState()), s_vmThreadActive.load() ? 1 : 0);
|
|
}
|
|
|
|
- (void)sceneDidBecomeActive:(UIScene *)scene {
|
|
+ Console.WriteLn("@@IOS_LIFECYCLE@@ sceneDidBecomeActive vm_state=%d active=%d",
|
|
+ static_cast<int>(VMManager::GetState()), s_vmThreadActive.load() ? 1 : 0);
|
|
}
|
|
|
|
- (void)sceneWillResignActive:(UIScene *)scene {
|
|
// NVM save when app loses focus
|
|
extern void cdvdSaveNVRAM();
|
|
cdvdSaveNVRAM();
|
|
+ Console.WriteLn("@@IOS_LIFECYCLE@@ sceneWillResignActive vm_state=%d active=%d saved_nvram=1",
|
|
+ static_cast<int>(VMManager::GetState()), s_vmThreadActive.load() ? 1 : 0);
|
|
}
|
|
|
|
- (void)sceneWillEnterForeground:(UIScene *)scene {
|
|
+ Console.WriteLn("@@IOS_LIFECYCLE@@ sceneWillEnterForeground vm_state=%d active=%d",
|
|
+ static_cast<int>(VMManager::GetState()), s_vmThreadActive.load() ? 1 : 0);
|
|
}
|
|
|
|
- (void)sceneDidEnterBackground:(UIScene *)scene {
|
|
@@ -1863,7 +1974,8 @@ - (void)sceneDidEnterBackground:(UIScene *)scene {
|
|
// happens when iOS terminates the app via SIGTERM.
|
|
extern void cdvdSaveNVRAM();
|
|
cdvdSaveNVRAM();
|
|
- Console.WriteLn("[NVM] NVM saved on sceneDidEnterBackground");
|
|
+ Console.WriteLn("@@IOS_LIFECYCLE@@ sceneDidEnterBackground vm_state=%d active=%d saved_nvram=1",
|
|
+ static_cast<int>(VMManager::GetState()), s_vmThreadActive.load() ? 1 : 0);
|
|
}
|
|
|
|
@end
|
|
diff --git a/app/src/main/cpp/pcsx2/GS/Renderers/Metal/cas.metal b/app/src/main/cpp/pcsx2/GS/Renderers/Metal/cas.metal
|
|
index 523ba1194..56cf3094a 100644
|
|
--- a/app/src/main/cpp/pcsx2/GS/Renderers/Metal/cas.metal
|
|
+++ b/app/src/main/cpp/pcsx2/GS/Renderers/Metal/cas.metal
|
|
@@ -5,7 +5,7 @@
|
|
#define A_MSL 1
|
|
#define A_HALF 1
|
|
|
|
-#include "../../../../bin/resources/shaders/common/ffx_a.h"
|
|
+#include "shaders/common/ffx_a.h"
|
|
|
|
struct CASTextureF
|
|
{
|
|
@@ -35,7 +35,7 @@ A_STATIC AH3 CasLoadH(CASTextureH tex, ASW2 coord)
|
|
|
|
A_STATIC void CasInputH(inoutAH2 r, inoutAH2 g, inoutAH2 b){}
|
|
|
|
-#include "../../../../bin/resources/shaders/common/ffx_cas.h"
|
|
+#include "shaders/common/ffx_cas.h"
|
|
|
|
#include "GSMTLShaderCommon.h"
|
|
|
|
diff --git a/app/src/main/cpp/pcsx2/GS/Renderers/Metal/fxaa.metal b/app/src/main/cpp/pcsx2/GS/Renderers/Metal/fxaa.metal
|
|
index 68c9a249f..bf09eef48 100644
|
|
--- a/app/src/main/cpp/pcsx2/GS/Renderers/Metal/fxaa.metal
|
|
+++ b/app/src/main/cpp/pcsx2/GS/Renderers/Metal/fxaa.metal
|
|
@@ -2,7 +2,7 @@
|
|
// SPDX-License-Identifier: GPL-3.0+
|
|
|
|
#include "GSMTLShaderCommon.h"
|
|
-#include "../../../../bin/resources/shaders/common/fxaa.fx"
|
|
+#include "shaders/common/fxaa.fx"
|
|
|
|
fragment float4 ps_fxaa(ConvertShaderData data [[stage_in]], texture2d<float> tex [[texture(GSMTLTextureIndexNonHW)]])
|
|
{
|
|
diff --git a/app/src/main/cpp/pcsx2/ImGui/FullscreenUI.cpp b/app/src/main/cpp/pcsx2/ImGui/FullscreenUI.cpp
|
|
index 83e3f6387..704fb2c17 100644
|
|
--- a/app/src/main/cpp/pcsx2/ImGui/FullscreenUI.cpp
|
|
+++ b/app/src/main/cpp/pcsx2/ImGui/FullscreenUI.cpp
|
|
@@ -1404,7 +1404,7 @@ void FullscreenUI::DrawLandingTemplate(ImVec2* menu_pos, ImVec2* menu_size)
|
|
logo_pos, logo_pos + logo_size);
|
|
dl->AddText(heading_font, heading_font->FontSize,
|
|
ImVec2(logo_pos.x + logo_size.x + LayoutScale(LAYOUT_MENU_BUTTON_X_PADDING), logo_pos.y),
|
|
- ImGui::GetColorU32(ImGuiCol_Text), "PCSX2");
|
|
+ ImGui::GetColorU32(ImGuiCol_Text), "ARMSX2");
|
|
}
|
|
|
|
// draw time
|
|
@@ -1620,7 +1620,7 @@ void FullscreenUI::DrawExitWindow()
|
|
QueueResetFocus(FocusResetType::WindowChanged);
|
|
}
|
|
|
|
- if (HorizontalMenuItem(GetCachedTexture("fullscreenui/exit.png"), FSUI_CSTR("Exit PCSX2"),
|
|
+ if (HorizontalMenuItem(GetCachedTexture("fullscreenui/exit.png"), FSUI_CSTR("Exit ARMSX2"),
|
|
FSUI_CSTR("Completely exits the application, returning you to your desktop.")))
|
|
{
|
|
DoRequestExit();
|
|
@@ -3430,7 +3430,7 @@ void FullscreenUI::DrawInterfaceSettingsPage()
|
|
FSUI_NSTR("Untouched Lagoon"),
|
|
FSUI_NSTR("Baby Pastel"),
|
|
FSUI_NSTR("Pizza Time!"),
|
|
- FSUI_NSTR("PCSX2 Blue"),
|
|
+ FSUI_NSTR("ARMSX2 Blue"),
|
|
FSUI_NSTR("Scarlet Devil"),
|
|
FSUI_NSTR("Violet Angel"),
|
|
FSUI_NSTR("Cobalt Sky"),
|
|
@@ -3585,8 +3585,8 @@ void FullscreenUI::DrawInterfaceSettingsPage()
|
|
FSUI_CSTR(
|
|
"Shows on-screen-display messages when events occur such as save states being created/loaded, screenshots being taken, etc."),
|
|
"EmuCore/GS", "OsdShowMessages", true);
|
|
- DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_INFO, "Show PCSX2 Version"),
|
|
- FSUI_CSTR("Shows the current PCSX2 version on the top-right corner of the display."), "EmuCore/GS",
|
|
+ DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_INFO, "Show ARMSX2 Version"),
|
|
+ FSUI_CSTR("Shows the current ARMSX2 version on the top-right corner of the display."), "EmuCore/GS",
|
|
"OsdShowVersion", false);
|
|
DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_TACHOMETER_ALT, "Show Speed"),
|
|
FSUI_CSTR("Shows the current emulation speed of the system in the top-right corner of the display as a percentage."), "EmuCore/GS",
|
|
@@ -3817,7 +3817,7 @@ void FullscreenUI::DrawEmulationSettingsPage()
|
|
FSUI_CSTR("Speeds up emulation so that the guest refresh rate matches the host."), "EmuCore/GS", "SyncToHostRefreshRate", false);
|
|
|
|
DrawToggleSetting(bsi, FSUI_CSTR("Use Host VSync Timing"),
|
|
- FSUI_CSTR("Disables PCSX2's internal frame timing, and uses host vsync instead."), "EmuCore/GS", "UseVSyncForTiming", false,
|
|
+ FSUI_CSTR("Disables the emulator's internal frame timing, and uses host vsync instead."), "EmuCore/GS", "UseVSyncForTiming", false,
|
|
GetEffectiveBoolSetting(bsi, "EmuCore/GS", "VsyncEnable", false) && GetEffectiveBoolSetting(bsi, "EmuCore/GS", "SyncToHostRefreshRate", false));
|
|
|
|
EndMenuButtons();
|
|
@@ -5148,8 +5148,8 @@ void FullscreenUI::DrawAdvancedSettingsPage()
|
|
if (!IsEditingGameSettings(bsi))
|
|
{
|
|
DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_BIOHAZARD, "Show Advanced Settings"),
|
|
- FSUI_CSTR("Changing these options may cause games to become non-functional. Modify at your own risk, the PCSX2 team will not "
|
|
- "provide support for configurations with these settings changed."),
|
|
+ FSUI_CSTR("Changing these options may cause games to become non-functional. Modify at your own risk; support is not "
|
|
+ "guaranteed for configurations with these settings changed."),
|
|
"UI", "ShowAdvancedSettings", false);
|
|
}
|
|
|
|
@@ -5337,7 +5337,7 @@ void FullscreenUI::DrawPatchesOrCheatsSettingsPage(bool cheats)
|
|
FSUI_CSTR("Activating game patches can cause unpredictable behavior, crashing, soft-locks, or broken saved games."),
|
|
false, false, ImGuiFullscreen::LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY);
|
|
ActiveButton(
|
|
- FSUI_CSTR("Use patches at your own risk, the PCSX2 team will provide no support for users who have enabled game patches."),
|
|
+ FSUI_CSTR("Use patches at your own risk; support is not guaranteed for users who have enabled game patches."),
|
|
false, false, ImGuiFullscreen::LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY);
|
|
}
|
|
|
|
@@ -7223,7 +7223,7 @@ void FullscreenUI::DrawAchievementsSettingsPage(std::unique_lock<std::mutex>& se
|
|
|
|
MenuHeading(FSUI_CSTR("Settings"));
|
|
check_challenge_state = DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_TROPHY, "Enable Achievements"),
|
|
- FSUI_CSTR("When enabled and logged in, PCSX2 will scan for achievements on startup."), "Achievements", "Enabled", false);
|
|
+ FSUI_CSTR("When enabled and logged in, ARMSX2 will scan for achievements on startup."), "Achievements", "Enabled", false);
|
|
|
|
const bool enabled = bsi->GetBoolValue("Achievements", "Enabled", false);
|
|
|
|
@@ -7247,11 +7247,11 @@ void FullscreenUI::DrawAchievementsSettingsPage(std::unique_lock<std::mutex>& se
|
|
FSUI_CSTR("When enabled, each session will behave as if no achievements have been unlocked."), "Achievements", "EncoreMode", false,
|
|
enabled);
|
|
DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_EYE, "Spectator Mode"),
|
|
- FSUI_CSTR("When enabled, PCSX2 will assume all achievements are locked and not send any unlock notifications to the server."),
|
|
+ FSUI_CSTR("When enabled, ARMSX2 will assume all achievements are locked and not send any unlock notifications to the server."),
|
|
"Achievements", "SpectatorMode", false, enabled);
|
|
DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_MEDAL, "Test Unofficial Achievements"),
|
|
FSUI_CSTR(
|
|
- "When enabled, PCSX2 will list achievements from unofficial sets. These achievements are not tracked by RetroAchievements."),
|
|
+ "When enabled, ARMSX2 will list achievements from unofficial sets. These achievements are not tracked by RetroAchievements."),
|
|
"Achievements", "UnofficialTestMode", false, enabled);
|
|
|
|
// Check for challenge mode just being enabled.
|
|
@@ -7426,7 +7426,7 @@ TRANSLATE_NOOP("FullscreenUI", "Start BIOS");
|
|
TRANSLATE_NOOP("FullscreenUI", "Start the console without any disc inserted.");
|
|
TRANSLATE_NOOP("FullscreenUI", "Back");
|
|
TRANSLATE_NOOP("FullscreenUI", "Return to the previous menu.");
|
|
-TRANSLATE_NOOP("FullscreenUI", "Exit PCSX2");
|
|
+ TRANSLATE_NOOP("FullscreenUI", "Exit ARMSX2");
|
|
TRANSLATE_NOOP("FullscreenUI", "Completely exits the application, returning you to your desktop.");
|
|
TRANSLATE_NOOP("FullscreenUI", "Desktop Mode");
|
|
TRANSLATE_NOOP("FullscreenUI", "Exits Big Picture mode, returning to the desktop interface.");
|
|
@@ -7467,7 +7467,7 @@ TRANSLATE_NOOP("FullscreenUI", "On-Screen Display");
|
|
TRANSLATE_NOOP("FullscreenUI", "Determines how large the on-screen messages and monitor are.");
|
|
TRANSLATE_NOOP("FullscreenUI", "%d%%");
|
|
TRANSLATE_NOOP("FullscreenUI", "Shows on-screen-display messages when events occur such as save states being created/loaded, screenshots being taken, etc.");
|
|
-TRANSLATE_NOOP("FullscreenUI", "Shows the current PCSX2 version on the top-right corner of the display.");
|
|
+TRANSLATE_NOOP("FullscreenUI", "Shows the current ARMSX2 version on the top-right corner of the display.");
|
|
TRANSLATE_NOOP("FullscreenUI", "Shows the current emulation speed of the system in the top-right corner of the display as a percentage.");
|
|
TRANSLATE_NOOP("FullscreenUI", "Shows the number of video frames (or v-syncs) displayed per second by the system in the top-right corner of the display.");
|
|
TRANSLATE_NOOP("FullscreenUI", "Shows the CPU usage based on threads in the top-right corner of the display.");
|
|
@@ -7520,7 +7520,7 @@ TRANSLATE_NOOP("FullscreenUI", "Synchronizes frame presentation with host refres
|
|
TRANSLATE_NOOP("FullscreenUI", "Sync to Host Refresh Rate");
|
|
TRANSLATE_NOOP("FullscreenUI", "Speeds up emulation so that the guest refresh rate matches the host.");
|
|
TRANSLATE_NOOP("FullscreenUI", "Use Host VSync Timing");
|
|
-TRANSLATE_NOOP("FullscreenUI", "Disables PCSX2's internal frame timing, and uses host vsync instead.");
|
|
+TRANSLATE_NOOP("FullscreenUI", "Disables the emulator's internal frame timing, and uses host vsync instead.");
|
|
TRANSLATE_NOOP("FullscreenUI", "Renderer");
|
|
TRANSLATE_NOOP("FullscreenUI", "Selects the API used to render the emulated GS.");
|
|
TRANSLATE_NOOP("FullscreenUI", "Display");
|
|
@@ -7727,7 +7727,7 @@ TRANSLATE_NOOP("FullscreenUI", "Determines the pressure required to activate the
|
|
TRANSLATE_NOOP("FullscreenUI", "Toggle every %d frames");
|
|
TRANSLATE_NOOP("FullscreenUI", "Clears all bindings for this USB controller.");
|
|
TRANSLATE_NOOP("FullscreenUI", "Data Save Locations");
|
|
-TRANSLATE_NOOP("FullscreenUI", "Changing these options may cause games to become non-functional. Modify at your own risk, the PCSX2 team will not provide support for configurations with these settings changed.");
|
|
+TRANSLATE_NOOP("FullscreenUI", "Changing these options may cause games to become non-functional. Modify at your own risk; support is not guaranteed for configurations with these settings changed.");
|
|
TRANSLATE_NOOP("FullscreenUI", "Logging");
|
|
TRANSLATE_NOOP("FullscreenUI", "Writes log messages to the system console (console window/standard output).");
|
|
TRANSLATE_NOOP("FullscreenUI", "Writes log messages to emulog.txt.");
|
|
@@ -7782,7 +7782,7 @@ TRANSLATE_NOOP("FullscreenUI", "No patches are available for this game.");
|
|
TRANSLATE_NOOP("FullscreenUI", "Game Patches");
|
|
TRANSLATE_NOOP("FullscreenUI", "Activating cheats can cause unpredictable behavior, crashing, soft-locks, or broken saved games.");
|
|
TRANSLATE_NOOP("FullscreenUI", "Activating game patches can cause unpredictable behavior, crashing, soft-locks, or broken saved games.");
|
|
-TRANSLATE_NOOP("FullscreenUI", "Use patches at your own risk, the PCSX2 team will provide no support for users who have enabled game patches.");
|
|
+TRANSLATE_NOOP("FullscreenUI", "Use patches at your own risk; support is not guaranteed for users who have enabled game patches.");
|
|
TRANSLATE_NOOP("FullscreenUI", "Game Fixes");
|
|
TRANSLATE_NOOP("FullscreenUI", "Game fixes should not be modified unless you are aware of what each option does and the implications of doing so.");
|
|
TRANSLATE_NOOP("FullscreenUI", "FPU Multiply Hack");
|
|
@@ -7845,15 +7845,15 @@ TRANSLATE_NOOP("FullscreenUI", "About PCSX2");
|
|
TRANSLATE_NOOP("FullscreenUI", "PCSX2 is a free and open-source PlayStation 2 (PS2) emulator. Its purpose is to emulate the PS2's hardware, using a combination of MIPS CPU Interpreters, Recompilers and a Virtual Machine which manages hardware states and PS2 system memory. This allows you to play PS2 games on your PC, with many additional features and benefits.");
|
|
TRANSLATE_NOOP("FullscreenUI", "PlayStation 2 and PS2 are registered trademarks of Sony Interactive Entertainment. This application is not affiliated in any way with Sony Interactive Entertainment.");
|
|
TRANSLATE_NOOP("FullscreenUI", "Version: %s");
|
|
-TRANSLATE_NOOP("FullscreenUI", "When enabled and logged in, PCSX2 will scan for achievements on startup.");
|
|
+TRANSLATE_NOOP("FullscreenUI", "When enabled and logged in, ARMSX2 will scan for achievements on startup.");
|
|
TRANSLATE_NOOP("FullscreenUI", "\"Challenge\" mode for achievements, including leaderboard tracking. Disables save state, cheats, and slowdown functions.");
|
|
TRANSLATE_NOOP("FullscreenUI", "Displays popup messages on events such as achievement unlocks and leaderboard submissions.");
|
|
TRANSLATE_NOOP("FullscreenUI", "Displays popup messages when starting, submitting, or failing a leaderboard challenge.");
|
|
TRANSLATE_NOOP("FullscreenUI", "Plays sound effects for events such as achievement unlocks and leaderboard submissions.");
|
|
TRANSLATE_NOOP("FullscreenUI", "Shows icons in the lower-right corner of the screen when a challenge/primed achievement is active.");
|
|
TRANSLATE_NOOP("FullscreenUI", "When enabled, each session will behave as if no achievements have been unlocked.");
|
|
-TRANSLATE_NOOP("FullscreenUI", "When enabled, PCSX2 will assume all achievements are locked and not send any unlock notifications to the server.");
|
|
-TRANSLATE_NOOP("FullscreenUI", "When enabled, PCSX2 will list achievements from unofficial sets. These achievements are not tracked by RetroAchievements.");
|
|
+TRANSLATE_NOOP("FullscreenUI", "When enabled, ARMSX2 will assume all achievements are locked and not send any unlock notifications to the server.");
|
|
+TRANSLATE_NOOP("FullscreenUI", "When enabled, ARMSX2 will list achievements from unofficial sets. These achievements are not tracked by RetroAchievements.");
|
|
TRANSLATE_NOOP("FullscreenUI", "Sound Effects");
|
|
TRANSLATE_NOOP("FullscreenUI", "Account");
|
|
TRANSLATE_NOOP("FullscreenUI", "Logs out of RetroAchievements.");
|
|
@@ -7921,7 +7921,7 @@ TRANSLATE_NOOP("FullscreenUI", "Grey Matter");
|
|
TRANSLATE_NOOP("FullscreenUI", "Untouched Lagoon");
|
|
TRANSLATE_NOOP("FullscreenUI", "Baby Pastel");
|
|
TRANSLATE_NOOP("FullscreenUI", "Pizza Time!");
|
|
-TRANSLATE_NOOP("FullscreenUI", "PCSX2 Blue");
|
|
+TRANSLATE_NOOP("FullscreenUI", "ARMSX2 Blue");
|
|
TRANSLATE_NOOP("FullscreenUI", "Scarlet Devil");
|
|
TRANSLATE_NOOP("FullscreenUI", "Violet Angel");
|
|
TRANSLATE_NOOP("FullscreenUI", "Cobalt Sky");
|
|
@@ -8145,7 +8145,7 @@ TRANSLATE_NOOP("FullscreenUI", "Double-Click Toggles Fullscreen");
|
|
TRANSLATE_NOOP("FullscreenUI", "Hide Cursor In Fullscreen");
|
|
TRANSLATE_NOOP("FullscreenUI", "OSD Scale");
|
|
TRANSLATE_NOOP("FullscreenUI", "Show Messages");
|
|
-TRANSLATE_NOOP("FullscreenUI", "Show PCSX2 Version");
|
|
+TRANSLATE_NOOP("FullscreenUI", "Show ARMSX2 Version");
|
|
TRANSLATE_NOOP("FullscreenUI", "Show Speed");
|
|
TRANSLATE_NOOP("FullscreenUI", "Show FPS");
|
|
TRANSLATE_NOOP("FullscreenUI", "Show CPU Usage");
|
|
diff --git a/app/src/main/cpp/pcsx2/ImGui/ImGuiOverlays.cpp b/app/src/main/cpp/pcsx2/ImGui/ImGuiOverlays.cpp
|
|
index 39d091c67..2bef10643 100644
|
|
--- a/app/src/main/cpp/pcsx2/ImGui/ImGuiOverlays.cpp
|
|
+++ b/app/src/main/cpp/pcsx2/ImGui/ImGuiOverlays.cpp
|
|
@@ -37,6 +37,10 @@
|
|
#include "fmt/format.h"
|
|
#include "imgui.h"
|
|
|
|
+#if defined(__APPLE__)
|
|
+#include <TargetConditionals.h>
|
|
+#endif
|
|
+
|
|
#include <array>
|
|
#include <chrono>
|
|
#include <cmath>
|
|
@@ -137,13 +141,11 @@ __ri void ImGuiManager::DrawPerformanceOverlay(float& position_y, float scale, f
|
|
switch (PerformanceMetrics::GetInternalFPSMethod())
|
|
{
|
|
case PerformanceMetrics::InternalFPSMethod::GSPrivilegedRegister:
|
|
- text.append_format("FPS: {:.2f} [P]", PerformanceMetrics::GetInternalFPS(),
|
|
- PerformanceMetrics::GetFPS());
|
|
+ text.append_format("FPS: {:.2f} [P]", PerformanceMetrics::GetInternalFPS());
|
|
break;
|
|
|
|
case PerformanceMetrics::InternalFPSMethod::DISPFBBlit:
|
|
- text.append_format("FPS: {:.2f} [B]", PerformanceMetrics::GetInternalFPS(),
|
|
- PerformanceMetrics::GetFPS());
|
|
+ text.append_format("FPS: {:.2f} [B]", PerformanceMetrics::GetInternalFPS());
|
|
break;
|
|
|
|
case PerformanceMetrics::InternalFPSMethod::None:
|
|
@@ -156,8 +158,7 @@ __ri void ImGuiManager::DrawPerformanceOverlay(float& position_y, float scale, f
|
|
|
|
if (GSConfig.OsdShowVPS)
|
|
{
|
|
- text.append_format("{}VPS: {:.2f}", first ? "" : " | ", PerformanceMetrics::GetFPS(),
|
|
- PerformanceMetrics::GetFPS());
|
|
+ text.append_format("{}VPS: {:.2f}", first ? "" : " | ", PerformanceMetrics::GetFPS());
|
|
first = false;
|
|
}
|
|
|
|
@@ -175,8 +176,11 @@ __ri void ImGuiManager::DrawPerformanceOverlay(float& position_y, float scale, f
|
|
|
|
if (GSConfig.OsdShowVersion)
|
|
{
|
|
-// text.append_format("{}PCSX2 {}", first ? "" : " | ", BuildVersion::GitRev);
|
|
- text.append_format("{}ARMSX2 {}", first ? "" : " | ", "v2.3.430");
|
|
+#if defined(__APPLE__) && TARGET_OS_IPHONE
|
|
+ text.append_format("{}ARMSX2 iOS", first ? "" : " | ");
|
|
+#else
|
|
+ text.append_format("{}ARMSX2 {}", first ? "" : " | ", BuildVersion::GitRev);
|
|
+#endif
|
|
}
|
|
|
|
if (!text.empty())
|
|
diff --git a/app/src/main/swift/Models/FileImportHandler.swift b/app/src/main/swift/Models/FileImportHandler.swift
|
|
index 26480f32e..8af61a734 100644
|
|
--- a/app/src/main/swift/Models/FileImportHandler.swift
|
|
+++ b/app/src/main/swift/Models/FileImportHandler.swift
|
|
@@ -2,6 +2,7 @@
|
|
// SPDX-License-Identifier: GPL-3.0+
|
|
|
|
import SwiftUI
|
|
+import Foundation
|
|
import UniformTypeIdentifiers
|
|
|
|
@Observable
|
|
@@ -83,12 +84,14 @@ final class FileImportHandler: @unchecked Sendable {
|
|
|
|
if preferredDestination == .game {
|
|
guard Self.gameExtensions.contains(ext) else {
|
|
+ NSLog("[ARMSX2 iOS Import] unsupported game file: %@", fileName)
|
|
return .unsupported(fileName)
|
|
}
|
|
destDir = (docsPath as NSString).appendingPathComponent("iso")
|
|
category = "Game"
|
|
} else if preferredDestination == .bios {
|
|
guard Self.biosExtensions.contains(ext) else {
|
|
+ NSLog("[ARMSX2 iOS Import] unsupported BIOS file: %@", fileName)
|
|
return .unsupported(fileName)
|
|
}
|
|
destDir = (docsPath as NSString).appendingPathComponent("bios")
|
|
@@ -108,6 +111,7 @@ final class FileImportHandler: @unchecked Sendable {
|
|
category = "BIOS"
|
|
}
|
|
} else {
|
|
+ NSLog("[ARMSX2 iOS Import] unsupported file: %@", fileName)
|
|
return .unsupported(fileName)
|
|
}
|
|
|
|
@@ -122,8 +126,10 @@ final class FileImportHandler: @unchecked Sendable {
|
|
try FileManager.default.removeItem(atPath: destPath)
|
|
}
|
|
try FileManager.default.copyItem(at: url, to: URL(fileURLWithPath: destPath))
|
|
+ NSLog("[ARMSX2 iOS Import] %@ imported: %@ -> %@", category, fileName, destPath)
|
|
return .success("\(category) imported: \(fileName)")
|
|
} catch {
|
|
+ NSLog("[ARMSX2 iOS Import] failed: %@ -> %@ error=%@", fileName, destPath, error.localizedDescription)
|
|
return .failure("\(fileName): \(error.localizedDescription)")
|
|
}
|
|
}
|
|
diff --git a/app/src/main/swift/Models/SettingsStore.swift b/app/src/main/swift/Models/SettingsStore.swift
|
|
index d76d21c35..c98e94796 100644
|
|
--- a/app/src/main/swift/Models/SettingsStore.swift
|
|
+++ b/app/src/main/swift/Models/SettingsStore.swift
|
|
@@ -26,7 +26,10 @@ final class SettingsStore: @unchecked Sendable {
|
|
|
|
// ── Emulator / CPU ──
|
|
var eeCoreType: Int {
|
|
- didSet { ARMSX2Bridge.setINIInt("EmuCore/CPU", key: "CoreType", value: Int32(eeCoreType)) }
|
|
+ didSet {
|
|
+ ARMSX2Bridge.setINIInt("EmuCore/CPU", key: "CoreType", value: Int32(eeCoreType))
|
|
+ ARMSX2Bridge.setINIBool("EmuCore/CPU", key: "UseArm64Dynarec", value: eeCoreType == 2)
|
|
+ }
|
|
}
|
|
var iopRecompiler: Bool {
|
|
didSet { ARMSX2Bridge.setINIBool("EmuCore/CPU/Recompiler", key: "EnableIOP", value: iopRecompiler) }
|
|
@@ -89,7 +92,7 @@ final class SettingsStore: @unchecked Sendable {
|
|
didSet { ARMSX2Bridge.setINIInt("EmuCore/GS", key: "deinterlace_mode", value: Int32(interlaceMode)) }
|
|
}
|
|
var aspectRatio: Int {
|
|
- didSet { ARMSX2Bridge.setINIInt("EmuCore/GS", key: "AspectRatio", value: Int32(aspectRatio)) }
|
|
+ didSet { ARMSX2Bridge.setINIString("EmuCore/GS", key: "AspectRatio", value: Self.aspectRatioName(for: aspectRatio)) }
|
|
}
|
|
var blendingAccuracy: Int {
|
|
didSet { ARMSX2Bridge.setINIInt("EmuCore/GS", key: "accurate_blending_unit", value: Int32(blendingAccuracy)) }
|
|
@@ -105,21 +108,48 @@ final class SettingsStore: @unchecked Sendable {
|
|
applyOsdPreset(osdPreset)
|
|
}
|
|
}
|
|
+ var osdPerformancePosition: Int {
|
|
+ didSet { ARMSX2Bridge.setINIInt("EmuCore/GS", key: "OsdPerformancePos", value: Int32(osdPerformancePosition)) }
|
|
+ }
|
|
var osdShowFPS: Bool {
|
|
didSet { ARMSX2Bridge.setINIBool("EmuCore/GS", key: "OsdShowFPS", value: osdShowFPS) }
|
|
}
|
|
+ var osdShowVPS: Bool {
|
|
+ didSet { ARMSX2Bridge.setINIBool("EmuCore/GS", key: "OsdShowVPS", value: osdShowVPS) }
|
|
+ }
|
|
var osdShowSpeed: Bool {
|
|
didSet { ARMSX2Bridge.setINIBool("EmuCore/GS", key: "OsdShowSpeed", value: osdShowSpeed) }
|
|
}
|
|
var osdShowCPU: Bool {
|
|
didSet { ARMSX2Bridge.setINIBool("EmuCore/GS", key: "OsdShowCPU", value: osdShowCPU) }
|
|
}
|
|
+ var osdShowGPU: Bool {
|
|
+ didSet { ARMSX2Bridge.setINIBool("EmuCore/GS", key: "OsdShowGPU", value: osdShowGPU) }
|
|
+ }
|
|
var osdShowResolution: Bool {
|
|
didSet { ARMSX2Bridge.setINIBool("EmuCore/GS", key: "OsdShowResolution", value: osdShowResolution) }
|
|
}
|
|
+ var osdShowGSStats: Bool {
|
|
+ didSet { ARMSX2Bridge.setINIBool("EmuCore/GS", key: "OsdShowGSStats", value: osdShowGSStats) }
|
|
+ }
|
|
+ var osdShowIndicators: Bool {
|
|
+ didSet { ARMSX2Bridge.setINIBool("EmuCore/GS", key: "OsdShowIndicators", value: osdShowIndicators) }
|
|
+ }
|
|
+ var osdShowSettings: Bool {
|
|
+ didSet { ARMSX2Bridge.setINIBool("EmuCore/GS", key: "OsdShowSettings", value: osdShowSettings) }
|
|
+ }
|
|
+ var osdShowInputs: Bool {
|
|
+ didSet { ARMSX2Bridge.setINIBool("EmuCore/GS", key: "OsdShowInputs", value: osdShowInputs) }
|
|
+ }
|
|
var osdShowFrameTimes: Bool {
|
|
didSet { ARMSX2Bridge.setINIBool("EmuCore/GS", key: "OsdShowFrameTimes", value: osdShowFrameTimes) }
|
|
}
|
|
+ var osdShowVersion: Bool {
|
|
+ didSet { ARMSX2Bridge.setINIBool("EmuCore/GS", key: "OsdShowVersion", value: osdShowVersion) }
|
|
+ }
|
|
+ var osdShowHardwareInfo: Bool {
|
|
+ didSet { ARMSX2Bridge.setINIBool("EmuCore/GS", key: "OsdShowHardwareInfo", value: osdShowHardwareInfo) }
|
|
+ }
|
|
|
|
// ── Gamepad / UI ──
|
|
var padOpacity: Float {
|
|
@@ -129,6 +159,28 @@ final class SettingsStore: @unchecked Sendable {
|
|
didSet { ARMSX2Bridge.setINIBool("ARMSX2iOS/UI", key: "HapticFeedback", value: hapticFeedback) }
|
|
}
|
|
|
|
+ private static func aspectRatioName(for value: Int) -> String {
|
|
+ switch value {
|
|
+ case 0: return "Stretch"
|
|
+ case 1: return "Auto 4:3/3:2"
|
|
+ case 2: return "4:3"
|
|
+ case 3: return "16:9"
|
|
+ case 4: return "10:7"
|
|
+ default: return "Auto 4:3/3:2"
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private static func aspectRatioValue(from name: String) -> Int {
|
|
+ switch name {
|
|
+ case "Stretch", "0": return 0
|
|
+ case "Auto 4:3/3:2", "1": return 1
|
|
+ case "4:3", "2": return 2
|
|
+ case "16:9", "3": return 3
|
|
+ case "10:7", "4": return 4
|
|
+ default: return 1
|
|
+ }
|
|
+ }
|
|
+
|
|
// ── Init from INI ──
|
|
private init() {
|
|
// CPU
|
|
@@ -159,19 +211,29 @@ final class SettingsStore: @unchecked Sendable {
|
|
casMode = Int(ARMSX2Bridge.getINIInt("EmuCore/GS", key: "CASMode", defaultValue: 0))
|
|
casSharpness = Int(ARMSX2Bridge.getINIInt("EmuCore/GS", key: "CASSharpness", defaultValue: 50))
|
|
interlaceMode = Int(ARMSX2Bridge.getINIInt("EmuCore/GS", key: "deinterlace_mode", defaultValue: 7))
|
|
- aspectRatio = Int(ARMSX2Bridge.getINIInt("EmuCore/GS", key: "AspectRatio", defaultValue: 0))
|
|
+ aspectRatio = Self.aspectRatioValue(from: ARMSX2Bridge.getINIString("EmuCore/GS", key: "AspectRatio", defaultValue: "Auto 4:3/3:2"))
|
|
blendingAccuracy = Int(ARMSX2Bridge.getINIInt("EmuCore/GS", key: "accurate_blending_unit", defaultValue: 1))
|
|
dithering = Int(ARMSX2Bridge.getINIInt("EmuCore/GS", key: "dithering_ps2", defaultValue: 2))
|
|
// OSD
|
|
osdPreset = OsdPreset(rawValue: Int(ARMSX2Bridge.getINIInt("ARMSX2iOS/UI", key: "OsdPreset", defaultValue: 0))) ?? .off
|
|
+ osdPerformancePosition = Int(ARMSX2Bridge.getINIInt("EmuCore/GS", key: "OsdPerformancePos", defaultValue: 2))
|
|
osdShowFPS = ARMSX2Bridge.getINIBool("EmuCore/GS", key: "OsdShowFPS", defaultValue: false)
|
|
+ osdShowVPS = ARMSX2Bridge.getINIBool("EmuCore/GS", key: "OsdShowVPS", defaultValue: false)
|
|
osdShowSpeed = ARMSX2Bridge.getINIBool("EmuCore/GS", key: "OsdShowSpeed", defaultValue: false)
|
|
osdShowCPU = ARMSX2Bridge.getINIBool("EmuCore/GS", key: "OsdShowCPU", defaultValue: false)
|
|
+ osdShowGPU = ARMSX2Bridge.getINIBool("EmuCore/GS", key: "OsdShowGPU", defaultValue: false)
|
|
osdShowResolution = ARMSX2Bridge.getINIBool("EmuCore/GS", key: "OsdShowResolution", defaultValue: false)
|
|
+ osdShowGSStats = ARMSX2Bridge.getINIBool("EmuCore/GS", key: "OsdShowGSStats", defaultValue: false)
|
|
+ osdShowIndicators = ARMSX2Bridge.getINIBool("EmuCore/GS", key: "OsdShowIndicators", defaultValue: false)
|
|
+ osdShowSettings = ARMSX2Bridge.getINIBool("EmuCore/GS", key: "OsdShowSettings", defaultValue: false)
|
|
+ osdShowInputs = ARMSX2Bridge.getINIBool("EmuCore/GS", key: "OsdShowInputs", defaultValue: false)
|
|
osdShowFrameTimes = ARMSX2Bridge.getINIBool("EmuCore/GS", key: "OsdShowFrameTimes", defaultValue: false)
|
|
+ osdShowVersion = ARMSX2Bridge.getINIBool("EmuCore/GS", key: "OsdShowVersion", defaultValue: false)
|
|
+ osdShowHardwareInfo = ARMSX2Bridge.getINIBool("EmuCore/GS", key: "OsdShowHardwareInfo", defaultValue: false)
|
|
// UI
|
|
padOpacity = ARMSX2Bridge.getINIFloat("ARMSX2iOS/UI", key: "PadOpacity", defaultValue: 0.6)
|
|
hapticFeedback = ARMSX2Bridge.getINIBool("ARMSX2iOS/UI", key: "HapticFeedback", defaultValue: true)
|
|
+ ARMSX2Bridge.setINIString("EmuCore/GS", key: "AspectRatio", value: Self.aspectRatioName(for: aspectRatio))
|
|
// [P60] Force MTVU off (known buggy)
|
|
ARMSX2Bridge.setINIBool("EmuCore/Speedhacks", key: "vuThread", value: false)
|
|
// Apply OSD preset
|
|
@@ -204,15 +266,24 @@ final class SettingsStore: @unchecked Sendable {
|
|
casMode = Int(ARMSX2Bridge.getINIInt("EmuCore/GS", key: "CASMode", defaultValue: 0))
|
|
casSharpness = Int(ARMSX2Bridge.getINIInt("EmuCore/GS", key: "CASSharpness", defaultValue: 50))
|
|
interlaceMode = Int(ARMSX2Bridge.getINIInt("EmuCore/GS", key: "deinterlace_mode", defaultValue: 7))
|
|
- aspectRatio = Int(ARMSX2Bridge.getINIInt("EmuCore/GS", key: "AspectRatio", defaultValue: 0))
|
|
+ aspectRatio = Self.aspectRatioValue(from: ARMSX2Bridge.getINIString("EmuCore/GS", key: "AspectRatio", defaultValue: "Auto 4:3/3:2"))
|
|
blendingAccuracy = Int(ARMSX2Bridge.getINIInt("EmuCore/GS", key: "accurate_blending_unit", defaultValue: 1))
|
|
dithering = Int(ARMSX2Bridge.getINIInt("EmuCore/GS", key: "dithering_ps2", defaultValue: 2))
|
|
osdPreset = OsdPreset(rawValue: Int(ARMSX2Bridge.getINIInt("ARMSX2iOS/UI", key: "OsdPreset", defaultValue: 0))) ?? .off
|
|
+ osdPerformancePosition = Int(ARMSX2Bridge.getINIInt("EmuCore/GS", key: "OsdPerformancePos", defaultValue: 2))
|
|
osdShowFPS = ARMSX2Bridge.getINIBool("EmuCore/GS", key: "OsdShowFPS", defaultValue: false)
|
|
+ osdShowVPS = ARMSX2Bridge.getINIBool("EmuCore/GS", key: "OsdShowVPS", defaultValue: false)
|
|
osdShowSpeed = ARMSX2Bridge.getINIBool("EmuCore/GS", key: "OsdShowSpeed", defaultValue: false)
|
|
osdShowCPU = ARMSX2Bridge.getINIBool("EmuCore/GS", key: "OsdShowCPU", defaultValue: false)
|
|
+ osdShowGPU = ARMSX2Bridge.getINIBool("EmuCore/GS", key: "OsdShowGPU", defaultValue: false)
|
|
osdShowResolution = ARMSX2Bridge.getINIBool("EmuCore/GS", key: "OsdShowResolution", defaultValue: false)
|
|
+ osdShowGSStats = ARMSX2Bridge.getINIBool("EmuCore/GS", key: "OsdShowGSStats", defaultValue: false)
|
|
+ osdShowIndicators = ARMSX2Bridge.getINIBool("EmuCore/GS", key: "OsdShowIndicators", defaultValue: false)
|
|
+ osdShowSettings = ARMSX2Bridge.getINIBool("EmuCore/GS", key: "OsdShowSettings", defaultValue: false)
|
|
+ osdShowInputs = ARMSX2Bridge.getINIBool("EmuCore/GS", key: "OsdShowInputs", defaultValue: false)
|
|
osdShowFrameTimes = ARMSX2Bridge.getINIBool("EmuCore/GS", key: "OsdShowFrameTimes", defaultValue: false)
|
|
+ osdShowVersion = ARMSX2Bridge.getINIBool("EmuCore/GS", key: "OsdShowVersion", defaultValue: false)
|
|
+ osdShowHardwareInfo = ARMSX2Bridge.getINIBool("EmuCore/GS", key: "OsdShowHardwareInfo", defaultValue: false)
|
|
padOpacity = ARMSX2Bridge.getINIFloat("ARMSX2iOS/UI", key: "PadOpacity", defaultValue: 0.6)
|
|
hapticFeedback = ARMSX2Bridge.getINIBool("ARMSX2iOS/UI", key: "HapticFeedback", defaultValue: true)
|
|
}
|
|
@@ -220,37 +291,65 @@ final class SettingsStore: @unchecked Sendable {
|
|
/// Apply OSD preset — writes ALL OSD flags to INI + GSConfig
|
|
private func applyOsdPreset(_ preset: OsdPreset) {
|
|
ARMSX2Bridge.applyOsdPreset(Int32(preset.rawValue))
|
|
+ if preset == .off {
|
|
+ osdPerformancePosition = 0
|
|
+ } else if osdPerformancePosition == 0 {
|
|
+ osdPerformancePosition = 2
|
|
+ }
|
|
let isSimple = preset == .simple
|
|
let isDetail = preset == .detail
|
|
let isFull = preset == .full
|
|
osdShowFPS = isSimple || isDetail || isFull
|
|
- osdShowSpeed = isDetail || isFull
|
|
+ osdShowVPS = isDetail || isFull
|
|
+ osdShowSpeed = isSimple || isDetail || isFull
|
|
osdShowCPU = isSimple || isDetail || isFull
|
|
+ osdShowGPU = isDetail || isFull
|
|
osdShowResolution = isDetail || isFull
|
|
+ osdShowGSStats = isFull
|
|
+ osdShowIndicators = isSimple || isDetail || isFull
|
|
+ osdShowSettings = isFull
|
|
+ osdShowInputs = isFull
|
|
osdShowFrameTimes = isFull
|
|
- ARMSX2Bridge.setINIBool("EmuCore/GS", key: "OsdShowVPS", value: false)
|
|
- ARMSX2Bridge.setINIBool("EmuCore/GS", key: "OsdShowVersion", value: false)
|
|
- ARMSX2Bridge.setINIBool("EmuCore/GS", key: "OsdShowHardwareInfo", value: false)
|
|
- ARMSX2Bridge.setINIBool("EmuCore/GS", key: "OsdShowGPU", value: false)
|
|
- ARMSX2Bridge.setINIBool("EmuCore/GS", key: "OsdShowGSStats", value: false)
|
|
+ osdShowVersion = isFull
|
|
+ osdShowHardwareInfo = isFull
|
|
}
|
|
|
|
- /// Reset emulator settings to PC PCSX2 defaults
|
|
+ /// Reset emulator settings to ARMSX2 iOS defaults
|
|
func resetEmulatorDefaults() {
|
|
eeCoreType = 2 // ARM64 JIT
|
|
iopRecompiler = true
|
|
- vu0Recompiler = true // PC PCSX2 default: microVU JIT
|
|
- vu1Recompiler = true // PC PCSX2 default: microVU JIT
|
|
+ vu0Recompiler = true
|
|
+ vu1Recompiler = true
|
|
fastBoot = false
|
|
fastmem = true
|
|
fastCDVD = false
|
|
eeCycleRate = 0
|
|
- vu1Instant = true // PC PCSX2 recommended default
|
|
- waitLoop = true // PC PCSX2 recommended default
|
|
- intcStat = true // PC PCSX2 recommended default
|
|
+ vu1Instant = true
|
|
+ waitLoop = true
|
|
+ intcStat = true
|
|
+ }
|
|
+
|
|
+ /// Keep EE/IOP/VU0 fast while isolating suspected VU1 JIT regressions.
|
|
+ func applyVU1CompatibilityPreset() {
|
|
+ eeCoreType = 2
|
|
+ iopRecompiler = true
|
|
+ vu0Recompiler = true
|
|
+ vu1Recompiler = false
|
|
+ vu1Instant = false
|
|
+ fastmem = false
|
|
+ }
|
|
+
|
|
+ /// Slow diagnostic preset for crash isolation when dynarec state is suspect.
|
|
+ func applyFullInterpreterPreset() {
|
|
+ eeCoreType = 1
|
|
+ iopRecompiler = false
|
|
+ vu0Recompiler = false
|
|
+ vu1Recompiler = false
|
|
+ vu1Instant = false
|
|
+ fastmem = false
|
|
}
|
|
|
|
- /// Reset graphics settings to PC PCSX2 defaults
|
|
+ /// Reset graphics settings to ARMSX2 iOS defaults
|
|
func resetGraphicsDefaults() {
|
|
renderer = 17 // Metal
|
|
upscaleMultiplier = 1.0 // Native PS2
|
|
@@ -260,7 +359,7 @@ final class SettingsStore: @unchecked Sendable {
|
|
casMode = 0 // Disabled
|
|
casSharpness = 50
|
|
interlaceMode = 7 // Adaptive
|
|
- aspectRatio = 0 // Auto 4:3/3:2
|
|
+ aspectRatio = 1 // Auto 4:3/3:2
|
|
blendingAccuracy = 1 // Basic
|
|
dithering = 2 // Scaled
|
|
}
|
|
diff --git a/app/src/main/swift/Views/BootSplashView.swift b/app/src/main/swift/Views/BootSplashView.swift
|
|
index bee9674f2..4991612f1 100644
|
|
--- a/app/src/main/swift/Views/BootSplashView.swift
|
|
+++ b/app/src/main/swift/Views/BootSplashView.swift
|
|
@@ -25,7 +25,7 @@ struct BootSplashView: View {
|
|
}
|
|
.task {
|
|
try? await Task.sleep(nanoseconds: Self.hardTimeout)
|
|
- await finish()
|
|
+ finish()
|
|
}
|
|
}
|
|
|
|
@@ -79,7 +79,7 @@ private struct BootSplashPlayerView: UIViewRepresentable {
|
|
coordinator.stopObserving()
|
|
}
|
|
|
|
- final class Coordinator {
|
|
+ final class Coordinator: @unchecked Sendable {
|
|
var player: AVPlayer?
|
|
private let onFinished: () -> Void
|
|
private var endToken: NSObjectProtocol?
|
|
diff --git a/app/src/main/swift/Views/GameScreenView.swift b/app/src/main/swift/Views/GameScreenView.swift
|
|
index bfb9fc229..1159c8a78 100644
|
|
--- a/app/src/main/swift/Views/GameScreenView.swift
|
|
+++ b/app/src/main/swift/Views/GameScreenView.swift
|
|
@@ -205,22 +205,28 @@ private struct SaveStatesPanel: View {
|
|
}
|
|
|
|
private func save(_ slot: ARMSX2SaveStateSlotInfo) {
|
|
- busySlot = slot.slot
|
|
- ARMSX2Bridge.saveState(toSlot: slot.slot) { success in
|
|
- busySlot = nil
|
|
- refresh()
|
|
- statusHandler(success ? "State saved to slot \(slot.slot)" : "Failed to save slot \(slot.slot)")
|
|
+ let slotNumber = slot.slot
|
|
+ busySlot = slotNumber
|
|
+ ARMSX2Bridge.saveState(toSlot: slotNumber) { success in
|
|
+ Task { @MainActor in
|
|
+ busySlot = nil
|
|
+ refresh()
|
|
+ statusHandler(success ? "State saved to slot \(slotNumber)" : "Failed to save slot \(slotNumber)")
|
|
+ }
|
|
}
|
|
}
|
|
|
|
private func load(_ slot: ARMSX2SaveStateSlotInfo) {
|
|
- busySlot = slot.slot
|
|
- ARMSX2Bridge.loadState(fromSlot: slot.slot) { success in
|
|
- busySlot = nil
|
|
- refresh()
|
|
- statusHandler(success ? "State loaded from slot \(slot.slot)" : "Failed to load slot \(slot.slot)")
|
|
- if success {
|
|
- dismiss()
|
|
+ let slotNumber = slot.slot
|
|
+ busySlot = slotNumber
|
|
+ ARMSX2Bridge.loadState(fromSlot: slotNumber) { success in
|
|
+ Task { @MainActor in
|
|
+ busySlot = nil
|
|
+ refresh()
|
|
+ statusHandler(success ? "State loaded from slot \(slotNumber)" : "Failed to load slot \(slotNumber)")
|
|
+ if success {
|
|
+ dismiss()
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
diff --git a/app/src/main/swift/Views/HelpView.swift b/app/src/main/swift/Views/HelpView.swift
|
|
index 8193b2fc1..19c6d78b0 100644
|
|
--- a/app/src/main/swift/Views/HelpView.swift
|
|
+++ b/app/src/main/swift/Views/HelpView.swift
|
|
@@ -60,7 +60,7 @@ private let helpData: [HelpSection] = [
|
|
HelpSection(title: "Overlay", icon: "speedometer", items: [
|
|
HelpItem(
|
|
question: "Overlay presets",
|
|
- answer: "OFF: No overlay. Simple: FPS + CPU usage. Detail: FPS, Speed, CPU, Resolution. Full: Everything including Frame Times graph. Configure in Settings > Overlay."
|
|
+ answer: "OFF hides the overlay. Simple shows FPS, speed, CPU, and indicators. Detail adds VPS, GPU, and resolution. Full enables the Android-style diagnostic set including GS stats, settings, inputs, frame times, version, and hardware info."
|
|
),
|
|
HelpItem(
|
|
question: "In-game toggle",
|
|
diff --git a/app/src/main/swift/Views/Settings/EmulatorSettingsView.swift b/app/src/main/swift/Views/Settings/EmulatorSettingsView.swift
|
|
index d96a8deb4..6196f08c1 100644
|
|
--- a/app/src/main/swift/Views/Settings/EmulatorSettingsView.swift
|
|
+++ b/app/src/main/swift/Views/Settings/EmulatorSettingsView.swift
|
|
@@ -69,6 +69,22 @@ struct EmulatorSettingsView: View {
|
|
.foregroundStyle(.secondary)
|
|
}
|
|
|
|
+ Section {
|
|
+ Button("Use VU1 Interpreter Preset") {
|
|
+ settings.applyVU1CompatibilityPreset()
|
|
+ }
|
|
+ Button("Use Full Interpreter Preset") {
|
|
+ settings.applyFullInterpreterPreset()
|
|
+ }
|
|
+ Text("Use the VU1 preset first for boot crashes or VU1-related texture/rendering glitches. Full Interpreter is much slower, but helps isolate dynarec/JIT issues.")
|
|
+ .font(.caption)
|
|
+ .foregroundStyle(.secondary)
|
|
+ } header: {
|
|
+ Text("Compatibility")
|
|
+ } footer: {
|
|
+ Text("Changes take effect on next VM boot.")
|
|
+ }
|
|
+
|
|
Section {
|
|
Stepper("EE Cycle Rate: \(settings.eeCycleRate)", value: $settings.eeCycleRate, in: -3...3)
|
|
Text("0 = Default. Negative = underclock (stable). Positive = overclock (fast but risky).")
|
|
@@ -80,7 +96,7 @@ struct EmulatorSettingsView: View {
|
|
Toggle("Wait Loop Detection", isOn: $settings.waitLoop)
|
|
Toggle("INTC Stat Hack", isOn: $settings.intcStat)
|
|
|
|
- Text("These are recommended defaults from PCSX2. Disable only if a specific game has issues.")
|
|
+ Text("These are recommended compatibility defaults. Disable only if a specific game has issues.")
|
|
.font(.caption)
|
|
.foregroundStyle(.secondary)
|
|
} header: {
|
|
diff --git a/app/src/main/swift/Views/Settings/GamepadSettingsView.swift b/app/src/main/swift/Views/Settings/GamepadSettingsView.swift
|
|
index 4cac1494f..481811906 100644
|
|
--- a/app/src/main/swift/Views/Settings/GamepadSettingsView.swift
|
|
+++ b/app/src/main/swift/Views/Settings/GamepadSettingsView.swift
|
|
@@ -126,8 +126,10 @@ struct GamepadSettingsView: View {
|
|
let captured = ARMSX2Bridge.capturedButton()
|
|
if captured >= 0 {
|
|
ARMSX2Bridge.setButtonMapping(Int32(ps2Index), toSDLButton: captured)
|
|
- stopCapture()
|
|
- mappingVersion += 1
|
|
+ Task { @MainActor in
|
|
+ stopCapture()
|
|
+ mappingVersion += 1
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
diff --git a/app/src/main/swift/Views/Settings/GraphicsSettingsView.swift b/app/src/main/swift/Views/Settings/GraphicsSettingsView.swift
|
|
index 58c3380d6..e292b7cfb 100644
|
|
--- a/app/src/main/swift/Views/Settings/GraphicsSettingsView.swift
|
|
+++ b/app/src/main/swift/Views/Settings/GraphicsSettingsView.swift
|
|
@@ -90,10 +90,11 @@ struct GraphicsSettingsView: View {
|
|
}
|
|
|
|
Picker("Aspect Ratio", selection: $settings.aspectRatio) {
|
|
- Text("Auto 4:3 / 3:2 (Default)").tag(0)
|
|
- Text("4:3").tag(1)
|
|
- Text("16:9 (Widescreen)").tag(2)
|
|
- Text("Stretch to Window").tag(3)
|
|
+ Text("Auto 4:3 / 3:2 (Default)").tag(1)
|
|
+ Text("4:3").tag(2)
|
|
+ Text("16:9 (Widescreen)").tag(3)
|
|
+ Text("10:7").tag(4)
|
|
+ Text("Stretch to Window").tag(0)
|
|
}
|
|
}
|
|
|
|
diff --git a/app/src/main/swift/Views/Settings/OverlaySettingsView.swift b/app/src/main/swift/Views/Settings/OverlaySettingsView.swift
|
|
index 7e4bc8189..ae9970687 100644
|
|
--- a/app/src/main/swift/Views/Settings/OverlaySettingsView.swift
|
|
+++ b/app/src/main/swift/Views/Settings/OverlaySettingsView.swift
|
|
@@ -15,30 +15,33 @@ struct OverlaySettingsView: View {
|
|
}
|
|
}
|
|
.pickerStyle(.segmented)
|
|
- }
|
|
|
|
- Section {
|
|
- switch settings.osdPreset {
|
|
- case .off:
|
|
- Text("Overlay is hidden.")
|
|
- .foregroundStyle(.secondary)
|
|
- case .simple:
|
|
- Label("FPS", systemImage: "checkmark")
|
|
- Label("CPU Usage (EE/GS)", systemImage: "checkmark")
|
|
- case .detail:
|
|
- Label("FPS", systemImage: "checkmark")
|
|
- Label("Speed %", systemImage: "checkmark")
|
|
- Label("CPU Usage (EE/GS)", systemImage: "checkmark")
|
|
- Label("Resolution", systemImage: "checkmark")
|
|
- case .full:
|
|
- Label("FPS", systemImage: "checkmark")
|
|
- Label("Speed %", systemImage: "checkmark")
|
|
- Label("CPU Usage (EE/GS)", systemImage: "checkmark")
|
|
- Label("Resolution", systemImage: "checkmark")
|
|
- Label("Frame Times Graph", systemImage: "checkmark")
|
|
+ Picker("Position", selection: $settings.osdPerformancePosition) {
|
|
+ Text("Hidden").tag(0)
|
|
+ Text("Top Left").tag(1)
|
|
+ Text("Top Right").tag(2)
|
|
}
|
|
- } header: {
|
|
- Text("Displayed Items")
|
|
+ }
|
|
+
|
|
+ Section("Displayed Items") {
|
|
+ Toggle("Show FPS", isOn: $settings.osdShowFPS)
|
|
+ Toggle("Show VPS", isOn: $settings.osdShowVPS)
|
|
+ Toggle("Show Speed", isOn: $settings.osdShowSpeed)
|
|
+ Toggle("Show CPU", isOn: $settings.osdShowCPU)
|
|
+ Toggle("Show GPU", isOn: $settings.osdShowGPU)
|
|
+ Toggle("Show Resolution", isOn: $settings.osdShowResolution)
|
|
+ Toggle("Show GS Stats", isOn: $settings.osdShowGSStats)
|
|
+ Toggle("Show Indicators", isOn: $settings.osdShowIndicators)
|
|
+ Toggle("Show Settings", isOn: $settings.osdShowSettings)
|
|
+ Toggle("Show Inputs", isOn: $settings.osdShowInputs)
|
|
+ Toggle("Show Frame Times", isOn: $settings.osdShowFrameTimes)
|
|
+ Toggle("Show Version", isOn: $settings.osdShowVersion)
|
|
+ Toggle("Show Hardware Info", isOn: $settings.osdShowHardwareInfo)
|
|
+ }
|
|
+
|
|
+ Section("Notes") {
|
|
+ Text("These match ARMSX2 Android's OSD/stat controls where practical. When Show Version is enabled, the overlay label displays ARMSX2 iOS.")
|
|
+ .foregroundStyle(.secondary)
|
|
}
|
|
}
|
|
.navigationTitle("Overlay")
|