mirror of
https://github.com/ARMSX2/ARMSX2.git
synced 2026-08-24 16:50:16 -07:00
refactor: move iOS frontend to platforms/ios on single shared core
Snapshot the iOS-refresh app (React Native shell + Objective-C/Swift iOS
runtime: AppDelegate, SceneDelegate, GamepadHaptics, ARMSX2Bridge) into
platforms/ios/. Delete its vendored PCSX2 core (794 pcsx2 + 150 common files)
and its vendored 3rdparty (~11.8k files); the repo-root core is the single
source of truth.
Relocate the genuine iOS-only core additions (MacOSStubs, QAProbe, TestHarness,
SifRingBuffer.h, common/PNGStub.cpp) into the root core, guarded by an
ARMSX2_IOS (CMAKE_SYSTEM_NAME==iOS) branch in pcsx2/CMakeLists.txt. The
NEON SPU2 sources are now shared by both arm64 mobile targets (ANDROID OR iOS).
Dropped cruft: *.try/*.ref backups, stray x86/microVU_impl.cpp, leaked
common/Android/* JNI files, and the adrenotools submodule (android-only).
Rewire the iOS native CMake to source the root {common,pcsx2,3rdparty} via an
ARMSX2_ROOT var, preserving all iOS-SDK/bundle/JIT-entitlement/Metal config.
NOT yet compiled against Xcode -- build validation is CI's job.
See REFACTOR_STATUS.md.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
2eb9ec659c
commit
f17460df0d
@@ -0,0 +1,11 @@
|
||||
// [P63] PNG stubs for macOS build (libpng not linked)
|
||||
#include <TargetConditionals.h>
|
||||
#if !TARGET_OS_IPHONE
|
||||
#include "Image.h"
|
||||
#include <cstdio>
|
||||
#include <vector>
|
||||
bool PNGFileLoader(RGBA8Image* img, const char* fn, FILE* fp) { return false; }
|
||||
bool PNGFileSaver(const RGBA8Image& img, const char* fn, FILE* fp, u8 q) { return false; }
|
||||
bool PNGBufferLoader(RGBA8Image* img, const void* buf, size_t len) { return false; }
|
||||
bool PNGBufferSaver(const RGBA8Image& img, std::vector<u8>* buf, u8 q) { return false; }
|
||||
#endif
|
||||
+26
-6
@@ -1085,12 +1085,16 @@ set(pcsx2arm64Headers
|
||||
arm64/aVU_Compile.inl
|
||||
)
|
||||
|
||||
# Android platform sources, relocated from the former android core fork
|
||||
# (refresh-experimental). Source wiring only: a real NDK build is required to
|
||||
# validate include paths and link deps. See REFACTOR_STATUS.md.
|
||||
if(ANDROID)
|
||||
list(APPEND pcsx2HostSources
|
||||
Host/OboeAudioStream.cpp)
|
||||
# Mobile (arm64) platform sources, relocated from the former android/iOS core
|
||||
# forks (refresh-experimental / iOS-refresh). Source wiring only: real NDK /
|
||||
# Xcode builds are required to validate include paths and link deps.
|
||||
# See REFACTOR_STATUS.md.
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "iOS")
|
||||
set(ARMSX2_IOS TRUE)
|
||||
endif()
|
||||
|
||||
# NEON-optimised SPU2 mixer/reverb: shared by all arm64 mobile targets.
|
||||
if(ANDROID OR ARMSX2_IOS)
|
||||
list(APPEND pcsx2SPU2Sources
|
||||
SPU2/spu2_neon.cpp)
|
||||
list(APPEND pcsx2SPU2Headers
|
||||
@@ -1101,6 +1105,11 @@ if(ANDROID)
|
||||
SPU2/spu2_optimize.h
|
||||
SPU2/spu2_sve2_fir.h
|
||||
SPU2/spu2_mt6899_tuning.h)
|
||||
endif()
|
||||
|
||||
if(ANDROID)
|
||||
list(APPEND pcsx2HostSources
|
||||
Host/OboeAudioStream.cpp)
|
||||
list(APPEND pcsx2GSSources
|
||||
GS/Renderers/OpenGL/GLContextEGLAndroid.cpp
|
||||
GS/Renderers/Common/GSGPUProfile.cpp)
|
||||
@@ -1120,6 +1129,17 @@ if(ANDROID)
|
||||
PS1DrvTrace.h)
|
||||
endif()
|
||||
|
||||
if(ARMSX2_IOS)
|
||||
list(APPEND pcsx2Sources
|
||||
MacOSStubs.cpp
|
||||
QAProbe.cpp
|
||||
TestHarness.cpp)
|
||||
list(APPEND pcsx2Headers
|
||||
QAProbe.h
|
||||
TestHarness.h
|
||||
SifRingBuffer.h)
|
||||
endif()
|
||||
|
||||
# These ones benefit a lot from LTO
|
||||
set(pcsx2LTOSources
|
||||
${pcsx2Sources}
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
// [P63] Stubs for macOS native build — symbols not available without full UI
|
||||
#include <TargetConditionals.h>
|
||||
#if !TARGET_OS_IPHONE
|
||||
|
||||
#include "Host.h"
|
||||
#include "VMManager.h"
|
||||
#include "Input/InputManager.h"
|
||||
#include "DEV9/pcap_io.h"
|
||||
#include "Achievements.h"
|
||||
#include "common/HTTPDownloader.h"
|
||||
#include "common/ProgressCallback.h"
|
||||
#include "common/FileSystem.h"
|
||||
#include "Host/AudioStream.h"
|
||||
#include "INISettingsInterface.h"
|
||||
|
||||
// --- PNG (already in common/PNGStub.cpp) ---
|
||||
|
||||
// --- FileSystem ---
|
||||
int FileSystem::OpenFDFileContent(const char* path) { return -1; }
|
||||
|
||||
// --- x86 emitter symbols (never called on ARM64, but referenced by JIT stubs) ---
|
||||
// Non-const → external linkage; Itanium ABI mangles by name only, type doesn't matter
|
||||
namespace x86Emitter {
|
||||
char xmm0[16]={}, xmm1[16]={}, xmm2[16]={}, xmm3[16]={}, xmm4[16]={}, xmm5[16]={};
|
||||
char xmm6[16]={}, xmm7[16]={}, xmm8[16]={}, xmm9[16]={}, xmm10[16]={};
|
||||
char xmm11[16]={}, xmm12[16]={}, xmm13[16]={}, xmm14[16]={}, xmm15[16]={};
|
||||
}
|
||||
|
||||
// --- g_xmmtypes (thread-local, referenced by iCore.o) ---
|
||||
enum { _XMMT_INT = 0 };
|
||||
thread_local int g_xmmtypes[16] = {_XMMT_INT};
|
||||
|
||||
// --- Audio: Oboe is Android-only ---
|
||||
std::unique_ptr<AudioStream> AudioStream::CreateOboeAudioStream(u32 sr, const AudioStreamParameters& p, bool s, Error* e) { return nullptr; }
|
||||
|
||||
// --- Network: PCAP not available ---
|
||||
PCAPAdapter::PCAPAdapter() : NetAdapter() {}
|
||||
|
||||
// --- HTTP: curl not linked ---
|
||||
std::unique_ptr<HTTPDownloader> HTTPDownloader::Create(std::string ua) { return nullptr; }
|
||||
|
||||
// --- Input: keyboard mapping ---
|
||||
std::optional<std::string> InputManager::ConvertHostKeyboardCodeToString(u32 c) { return std::nullopt; }
|
||||
const char* InputManager::ConvertHostKeyboardCodeToIcon(u32 c) { return nullptr; }
|
||||
std::optional<u32> InputManager::ConvertHostKeyboardStringToCode(std::string_view s) { return std::nullopt; }
|
||||
|
||||
// --- Settings ---
|
||||
INISettingsInterface* g_p44_settings_interface = nullptr;
|
||||
|
||||
// --- Host functions (declared in Host.h) ---
|
||||
bool Host::InNoGUIMode() { return true; }
|
||||
void Host::RunOnCPUThread(std::function<void()> f, bool b) { if (f) f(); }
|
||||
void Host::RequestVMShutdown(bool a, bool b, bool c) {}
|
||||
bool Host::RequestResetSettings(bool a, bool b, bool c, bool d, bool e) { return false; }
|
||||
void Host::CancelGameListRefresh() {}
|
||||
void Host::RefreshGameListAsync(bool i) {}
|
||||
void Host::CommitBaseSettingChanges() {}
|
||||
bool Host::ConfirmMessage(std::string_view t, std::string_view m) { return true; }
|
||||
void Host::ReportErrorAsync(std::string_view t, std::string_view m) { fprintf(stderr, "[Error] %.*s: %.*s\n", (int)t.size(), t.data(), (int)m.size(), m.data()); }
|
||||
void Host::ReportInfoAsync(std::string_view t, std::string_view m) {}
|
||||
void Host::OpenURL(std::string_view u) {}
|
||||
bool Host::CopyTextToClipboard(std::string_view t) { return false; }
|
||||
std::unique_ptr<ProgressCallback> Host::CreateHostProgressCallback() { return nullptr; }
|
||||
std::string Host::TranslatePluralToString(const char* ctx, const char* msg, const char* mpl, int n) { return msg; }
|
||||
s32 Host::Internal::GetTranslatedStringImpl(std::string_view ctx, std::string_view msg, char* buf, size_t sz) {
|
||||
s32 len = std::min((s32)msg.size(), (s32)(sz - 1));
|
||||
std::memcpy(buf, msg.data(), len);
|
||||
buf[len] = 0;
|
||||
return len;
|
||||
}
|
||||
|
||||
// --- Host functions (declared in VMManager.h / other headers) ---
|
||||
namespace Host {
|
||||
void BeginPresentFrame() {}
|
||||
// AcquireRenderWindow is in ios_main.mm (macOS section) with correct return type
|
||||
void ReleaseRenderWindow() {}
|
||||
void BeginTextInput() {}
|
||||
void EndTextInput() {}
|
||||
bool IsFullscreen() { return false; }
|
||||
void SetFullscreen(bool f) {}
|
||||
void SetMouseMode(bool r, bool h) {}
|
||||
void OnVMStarting() {}
|
||||
void OnVMStarted() {}
|
||||
void OnVMDestroyed() {}
|
||||
void OnVMPaused() {}
|
||||
void OnVMResumed() {}
|
||||
void OnGameChanged(const std::string& d, const std::string& e, const std::string& t, const std::string& s, u32 c, u32 r) {}
|
||||
void OnPerformanceMetricsUpdated() {}
|
||||
void OnSaveStateLoading(std::string_view f) {}
|
||||
void OnSaveStateLoaded(std::string_view f, bool w) {}
|
||||
void OnSaveStateSaved(std::string_view f) {}
|
||||
void OnAchievementsHardcoreModeChanged(bool e) {}
|
||||
void OnAchievementsLoginRequested(Achievements::LoginRequestReason r) {}
|
||||
void OnAchievementsLoginSuccess(const char* u, u32 p, u32 sc, u32 us) {}
|
||||
void OnAchievementsRefreshed() {}
|
||||
void OnCoverDownloaderOpenRequested() {}
|
||||
void OnCreateMemoryCardOpenRequested() {}
|
||||
void OnInputDeviceConnected(std::string_view i, std::string_view d) {}
|
||||
void OnInputDeviceDisconnected(InputBindingKey k, std::string_view i) {}
|
||||
void PumpMessagesOnCPUThread() {}
|
||||
void RequestExitApplication(bool a) {}
|
||||
void RequestExitBigPicture() {}
|
||||
void CheckForSettingsChanges(const Pcsx2Config& c) {}
|
||||
void LoadSettings(SettingsInterface& si, std::unique_lock<std::mutex>& lock) {}
|
||||
bool ShouldPreferHostFileSelector() { return false; }
|
||||
void OpenHostFileSelectorAsync(std::string_view t, bool d, std::function<void(const std::string&)> cb, std::vector<std::string> f, std::string_view i) {}
|
||||
bool LocaleCircleConfirm() { return false; }
|
||||
}
|
||||
|
||||
// iOS-specific globals (referenced by iPSX2Bridge.mm)
|
||||
#include <map>
|
||||
#include <string>
|
||||
int g_touchPadState = 0;
|
||||
bool s_captureMode = false;
|
||||
int s_capturedButton = -1;
|
||||
bool s_requestVMStop = false;
|
||||
extern "C" void iPSX2_SetSDLFullscreen(bool) {}
|
||||
std::map<std::string, int> s_buttonMap;
|
||||
|
||||
// PCAPAdapter vtable
|
||||
PCAPAdapter::~PCAPAdapter() {}
|
||||
bool PCAPAdapter::blocks() { return false; }
|
||||
bool PCAPAdapter::isInitialised() { return false; }
|
||||
bool PCAPAdapter::recv(NetPacket* p) { return false; }
|
||||
bool PCAPAdapter::send(NetPacket* p) { return false; }
|
||||
void PCAPAdapter::reloadSettings() {}
|
||||
|
||||
#endif // !TARGET_OS_IPHONE
|
||||
|
||||
@@ -0,0 +1,175 @@
|
||||
// QAProbe — implementation. See QAProbe.h for design.
|
||||
|
||||
#include "QAProbe.h"
|
||||
#include "common/Console.h"
|
||||
#include "MTGS.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
extern uint32_t getVif1CmdUnpack(); // Vif_Transfer.cpp
|
||||
|
||||
namespace
|
||||
{
|
||||
// -------- env-driven config (parsed once, on first vsync) --------
|
||||
// All defaults OFF: release ship 構成では QA probe を全 dormant 化、
|
||||
// env で明示的に opt-in した場合のみ counter / log / SS が動作する。
|
||||
bool s_inited = false;
|
||||
std::set<u32> s_ss_vs;
|
||||
std::string s_tag = "run";
|
||||
bool s_gif_dump = false;
|
||||
u64 s_gif_dump_quota = 2000000;
|
||||
bool s_qa_log = false;
|
||||
|
||||
// -------- cumulative counters --------
|
||||
std::atomic<u64> s_cum_gif_pkt{0};
|
||||
std::atomic<u64> s_cum_d_prim{0};
|
||||
std::atomic<u64> s_cum_d_unp{0};
|
||||
std::atomic<u64> s_cum_d_bytes{0};
|
||||
std::atomic<u64> s_gif_dump_emitted{0};
|
||||
|
||||
// per-vsync deltas (reset each VSyncEnd)
|
||||
std::atomic<u64> s_vs_gif_pkt{0};
|
||||
std::atomic<u64> s_vs_d_prim{0};
|
||||
std::atomic<u64> s_vs_d_unp{0};
|
||||
std::atomic<u64> s_vs_d_bytes{0};
|
||||
|
||||
void parse_csv_u32(const char* env, std::set<u32>& out)
|
||||
{
|
||||
if (!env || !*env) return;
|
||||
const char* p = env;
|
||||
while (*p)
|
||||
{
|
||||
char* end = nullptr;
|
||||
unsigned long v = std::strtoul(p, &end, 10);
|
||||
if (end == p) break;
|
||||
out.insert(static_cast<u32>(v));
|
||||
p = end;
|
||||
while (*p == ',' || *p == ' ') ++p;
|
||||
}
|
||||
}
|
||||
|
||||
void init_once()
|
||||
{
|
||||
if (s_inited) return;
|
||||
s_inited = true;
|
||||
|
||||
if (const char* e = std::getenv("iPSX2_QA_TAG"); e && *e) s_tag = e;
|
||||
if (const char* e = std::getenv("iPSX2_SS_AT_VS"); e && *e) parse_csv_u32(e, s_ss_vs);
|
||||
if (const char* e = std::getenv("iPSX2_GIF_DUMP"); e && *e == '1') s_gif_dump = true;
|
||||
if (const char* e = std::getenv("iPSX2_GIF_DUMP_QUOTA"); e && *e)
|
||||
s_gif_dump_quota = std::strtoull(e, nullptr, 10);
|
||||
if (const char* e = std::getenv("iPSX2_QA_LOG"); e && *e == '1') s_qa_log = true;
|
||||
|
||||
// Init log only emitted when any QA feature is active (= one-time, never spams).
|
||||
if (s_qa_log || s_gif_dump || !s_ss_vs.empty())
|
||||
{
|
||||
Console.WriteLn("@@QA_INIT@@ tag=%s ss_vs_count=%zu gif_dump=%d quota=%llu qa_log=%d",
|
||||
s_tag.c_str(), s_ss_vs.size(), (int)s_gif_dump,
|
||||
(unsigned long long)s_gif_dump_quota, (int)s_qa_log);
|
||||
}
|
||||
}
|
||||
|
||||
// FNV1a-32 over packet bytes (fast, deterministic)
|
||||
u32 fnv1a32(const u8* p, u32 n)
|
||||
{
|
||||
u32 h = 0x811c9dc5u;
|
||||
for (u32 i = 0; i < n; ++i) { h ^= p[i]; h *= 0x01000193u; }
|
||||
return h;
|
||||
}
|
||||
|
||||
// Best-effort RGBA dump: 8-byte header [w,h u32 LE] + W*H*4 bytes.
|
||||
void dump_ss(u32 vs)
|
||||
{
|
||||
u32 w = 0, h = 0;
|
||||
std::vector<u32> pixels;
|
||||
if (!MTGS::SaveMemorySnapshot(640, 480, true, false, &w, &h, &pixels))
|
||||
{
|
||||
Console.WriteLn("@@QA_SS@@ vs=%u snapshot FAILED", vs);
|
||||
return;
|
||||
}
|
||||
char path[256];
|
||||
std::snprintf(path, sizeof(path), "/tmp/qa_ss_%s_vs%u.rgba", s_tag.c_str(), vs);
|
||||
FILE* f = std::fopen(path, "wb");
|
||||
if (!f) { Console.WriteLn("@@QA_SS@@ vs=%u fopen failed: %s", vs, path); return; }
|
||||
u32 hdr[2] = {w, h};
|
||||
std::fwrite(hdr, sizeof(u32), 2, f);
|
||||
std::fwrite(pixels.data(), 4, (size_t)w * h, f);
|
||||
std::fclose(f);
|
||||
Console.WriteLn("@@QA_SS@@ vs=%u path=%s size=%ux%u", vs, path, w, h);
|
||||
}
|
||||
}
|
||||
|
||||
namespace QAProbe
|
||||
{
|
||||
void on_vsync_end(u32 frame_count)
|
||||
{
|
||||
init_once();
|
||||
|
||||
// Fast path: when QA log + SS dump 両方 OFF なら全 skip。
|
||||
// release ship default ではこの path で常時 early return (= per-vsync ゼロ cost)。
|
||||
if (!s_qa_log && s_ss_vs.empty()) return;
|
||||
|
||||
const u32 vs = frame_count + 1; // VSyncEnd increments g_FrameCount; align to "vs about to start"
|
||||
|
||||
if (s_qa_log)
|
||||
{
|
||||
const u64 cum_pkt = s_cum_gif_pkt.load(std::memory_order_relaxed);
|
||||
const u64 cum_prim = s_cum_d_prim.load(std::memory_order_relaxed);
|
||||
const u64 d_pkt = s_vs_gif_pkt.exchange(0, std::memory_order_relaxed);
|
||||
const u64 d_prim = s_vs_d_prim.exchange(0, std::memory_order_relaxed);
|
||||
const u64 d_unp = s_vs_d_unp.exchange(0, std::memory_order_relaxed);
|
||||
const u64 d_bytes = s_vs_d_bytes.exchange(0, std::memory_order_relaxed);
|
||||
const u32 vif1_unp = getVif1CmdUnpack();
|
||||
(void)cum_prim;
|
||||
|
||||
Console.WriteLn(
|
||||
"@@BL_FRAME@@ vs=%u gif_pkt=%llu d_pkt=%llu d_prim=%llu d_unp=%llu d_bytes=%llu vif1_unpack=%u",
|
||||
vs,
|
||||
(unsigned long long)cum_pkt,
|
||||
(unsigned long long)d_pkt,
|
||||
(unsigned long long)d_prim,
|
||||
(unsigned long long)d_unp,
|
||||
(unsigned long long)d_bytes,
|
||||
vif1_unp);
|
||||
}
|
||||
|
||||
if (!s_ss_vs.empty() && s_ss_vs.count(vs)) dump_ss(vs);
|
||||
}
|
||||
|
||||
void on_gif_transfer(u32 tran_type, u32 path, const u8* pMem, u32 size)
|
||||
{
|
||||
// Fast path: env で QA log も GIF dump も off の場合は全 skip。
|
||||
// release ship default ではこの path で常時 early return (= per-transfer ゼロ cost)。
|
||||
if (!s_qa_log && !s_gif_dump) return;
|
||||
|
||||
if (s_qa_log)
|
||||
{
|
||||
// Cumulative + per-vsync counters (only when @@BL_FRAME@@ log consumer exists)
|
||||
s_cum_gif_pkt.fetch_add(1, std::memory_order_relaxed);
|
||||
s_vs_gif_pkt.fetch_add(1, std::memory_order_relaxed);
|
||||
s_cum_d_bytes.fetch_add(size, std::memory_order_relaxed);
|
||||
s_vs_d_bytes.fetch_add(size, std::memory_order_relaxed);
|
||||
s_cum_d_prim.fetch_add(1, std::memory_order_relaxed);
|
||||
s_vs_d_prim.fetch_add(1, std::memory_order_relaxed);
|
||||
if (path == 1)
|
||||
{
|
||||
s_cum_d_unp.fetch_add(size, std::memory_order_relaxed);
|
||||
s_vs_d_unp.fetch_add(size, std::memory_order_relaxed);
|
||||
}
|
||||
}
|
||||
|
||||
// Optional verbose GIF packet dump (env-gated).
|
||||
if (!s_gif_dump || !pMem || !size) return;
|
||||
const u64 emitted = s_gif_dump_emitted.fetch_add(1, std::memory_order_relaxed);
|
||||
if (emitted >= s_gif_dump_quota) return;
|
||||
const u32 crc = fnv1a32(pMem, size);
|
||||
Console.WriteLn("@@GIF_PKT@@ seq=%llu path=%u tran=%u size=%u crc=%08x",
|
||||
(unsigned long long)emitted, path, tran_type, size, crc);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
// QAProbe — Quality Assurance probe module for iPSX2 (V34 baseline, 2026-05-25)
|
||||
//
|
||||
// Purpose: thin hook-based probe infrastructure for automated JIT vs Interpreter
|
||||
// regression gates. All probes are env-gated; when env vars unset, hooks are 1-line
|
||||
// no-op early-returns with negligible cost.
|
||||
//
|
||||
// Hook points (3 total, all 1-line calls into this module):
|
||||
// 1. Counters.cpp VSyncEnd -> QAProbe::on_vsync_end()
|
||||
// 2. Gif_Unit.h TransferGSPacketData entry -> QAProbe::on_gif_transfer()
|
||||
// 3. (optional) QAProbe::on_gif_primitive() called per-PRIM emit
|
||||
//
|
||||
// Env vars consumed:
|
||||
// iPSX2_SS_AT_VS=N1,N2,... : at each listed vs, dump 640x480 RGBA framebuffer
|
||||
// to /tmp/qa_ss_<TAG>_vs<N>.rgba
|
||||
// iPSX2_QA_TAG=<tag> : tag prefix for output filenames (default: "run")
|
||||
// iPSX2_GIF_DUMP=1 : emit @@GIF_PKT@@ per transfer with CRC
|
||||
// iPSX2_GIF_DUMP_QUOTA=N : cap @@GIF_PKT@@ count (default 2000000)
|
||||
// iPSX2_QA_LOG=1 : emit @@BL_FRAME@@ line per vsync end (default ON)
|
||||
//
|
||||
// Output (consumed by Scripts/eval_bench.py, gif_diff.py, ss_compare.py):
|
||||
// @@BL_FRAME@@ vs=N gif_pkt=N d_pkt=N d_prim=N d_unp=N d_bytes=N vif1_unpack=N
|
||||
// @@GIF_PKT@@ vs=N seq=N path=N tran=N size=N crc=HEX
|
||||
// @@QA_SS@@ vs=N path=/tmp/qa_ss_<tag>_vs<N>.rgba size=WxH
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/Pcsx2Types.h"
|
||||
|
||||
namespace QAProbe
|
||||
{
|
||||
// Called from Counters.cpp::VSyncEnd. frame_count = pre-increment g_FrameCount.
|
||||
void on_vsync_end(u32 frame_count);
|
||||
|
||||
// Called from Gif_Unit.h::TransferGSPacketData on every transfer.
|
||||
// path: 0-2 (GIF_PATH_1/2/3 = 0/1/2). pMem may be null when size==0.
|
||||
void on_gif_transfer(u32 tran_type, u32 path, const u8* pMem, u32 size);
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
// SPDX-FileCopyrightText: 2002-2025 PCSX2 Dev Team
|
||||
// SPDX-License-Identifier: GPL-3.0+
|
||||
#pragma once
|
||||
|
||||
// [P34] SIF/RPC イベント ring buffer — タイムアウト診断用
|
||||
// iPSX2_SIF_RING=1 でenabled化。デフォルト OFF。
|
||||
|
||||
#include "common/Pcsx2Types.h"
|
||||
#include <cstdlib>
|
||||
#include <atomic>
|
||||
|
||||
namespace SifRing {
|
||||
|
||||
enum EventType : u8 {
|
||||
BIND_REQ = 1, // EE sceSifBindRpc
|
||||
CALL_REQ = 2, // EE sceSifCallRpc
|
||||
RPC_REGISTER = 3, // IOP sceSifRegisterRpc
|
||||
ICTRL_CHANGE = 4, // 0x1078 change
|
||||
ISTAT_SET = 5, // iopIntcIrq
|
||||
ISTAT_CONSUME = 6, // iopEventTest consume
|
||||
PSXDMA9 = 7, // IOP→EE SIF0
|
||||
PSXDMA10 = 8, // EE→IOP SIF1 (IOP side)
|
||||
IOP_TAG = 9, // ProcessIOPTag
|
||||
EE_XFER = 10, // HandleEETransfer
|
||||
GAME_EXIT = 11, // EE → EELOAD idle
|
||||
};
|
||||
|
||||
struct Event {
|
||||
u8 type;
|
||||
u8 pad;
|
||||
u16 pad2;
|
||||
u32 ee_cyc;
|
||||
u32 iop_cyc;
|
||||
u32 d0;
|
||||
u32 d1;
|
||||
};
|
||||
|
||||
static constexpr int RING_SIZE = 256;
|
||||
static constexpr int RING_MASK = RING_SIZE - 1;
|
||||
|
||||
inline Event g_ring[RING_SIZE];
|
||||
inline u32 g_idx = 0;
|
||||
inline bool g_enabled = false;
|
||||
inline bool g_initialized = false;
|
||||
|
||||
inline bool IsEnabled() {
|
||||
if (!g_initialized) {
|
||||
g_initialized = true;
|
||||
const char* v = getenv("iPSX2_SIF_RING");
|
||||
g_enabled = (v && v[0] == '1');
|
||||
}
|
||||
return g_enabled;
|
||||
}
|
||||
|
||||
// 外部から ee_cyc / iop_cyc を渡す (ヘッダ依存を避けるため)
|
||||
inline void Record(u8 type, u32 ee_cyc, u32 iop_cyc, u32 d0, u32 d1) {
|
||||
if (!IsEnabled()) return;
|
||||
u32 i = g_idx++ & RING_MASK;
|
||||
g_ring[i] = {type, 0, 0, ee_cyc, iop_cyc, d0, d1};
|
||||
}
|
||||
|
||||
// ダンプ (Console.WriteLn はcall側で行う)
|
||||
inline void DumpTo(void (*emit)(const char*, u32, u32, u32, u32, u32, u32)) {
|
||||
if (!IsEnabled()) return;
|
||||
u32 start = (g_idx > RING_SIZE) ? (g_idx - RING_SIZE) : 0;
|
||||
u32 end = g_idx;
|
||||
for (u32 i = start; i < end; i++) {
|
||||
const Event& e = g_ring[i & RING_MASK];
|
||||
emit("@@SIF_RING@@ type=%u ee=%u iop=%u d0=%08x d1=%08x seq=%u",
|
||||
(u32)e.type, e.ee_cyc, e.iop_cyc, e.d0, e.d1, i);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace SifRing
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,64 @@
|
||||
// SPDX-FileCopyrightText: 2002-2025 PCSX2 Dev Team
|
||||
// SPDX-License-Identifier: GPL-3.0+
|
||||
|
||||
#pragma once
|
||||
|
||||
// [P30] iOS Native EE Test Harness
|
||||
// BIOS/SIF/IOP 非依存で EE JIT 命令精度を検証する。
|
||||
// iPSX2_TEST_HARNESS=1 でenabled化。デフォルト OFF。
|
||||
//
|
||||
// テストコード (MIPS R5900 マシンコード) を eeMem に直接書き込み、
|
||||
// cpuRegs.pc をconfigして実行。resultは EE memoryに書き込まれ、
|
||||
// vsync handlerがログ出力する。
|
||||
|
||||
#include "common/Pcsx2Types.h"
|
||||
#include <string>
|
||||
|
||||
namespace TestHarness
|
||||
{
|
||||
// テストresultmemoryレイアウト
|
||||
// kseg0 address (TLB not needed、物理addressに直接mapping)
|
||||
// 0x01F00000 (31MB) は BIOS/OSDSYS ワークエリア外
|
||||
static constexpr u32 PHYS_CODE = 0x01F00000u; // eeMem 書き込み先 (物理)
|
||||
static constexpr u32 PHYS_RESULT = 0x01FF0000u;
|
||||
static constexpr u32 CODE_BASE = 0x81F00000u; // EE PC 用 kseg0 address
|
||||
static constexpr u32 RESULT_BASE = 0x81FF0000u;
|
||||
static constexpr u32 STACK_TOP = 0x81FE0000u;
|
||||
|
||||
// ヘッダ (CODE_BASE に配置)
|
||||
struct Header {
|
||||
u32 magic; // 0x54455354 ("TEST")
|
||||
u32 test_count;
|
||||
u32 pass_count;
|
||||
u32 fail_count;
|
||||
u32 current_test;
|
||||
u32 status; // 0=running, 1=complete, 2=error
|
||||
};
|
||||
|
||||
// 個別テストresult (RESULT_BASE + n*16)
|
||||
struct Result {
|
||||
u32 test_id;
|
||||
u32 expected;
|
||||
u32 actual;
|
||||
u32 pass; // 1=pass, 0=fail
|
||||
};
|
||||
|
||||
// テストハーネスがenabledかどうか
|
||||
bool IsEnabled();
|
||||
|
||||
// テストコードを eeMem に注入し cpuRegs.pc をconfig
|
||||
// eeloadHook n=1 のタイミングで呼ばれる
|
||||
void InjectTests();
|
||||
|
||||
// vsync でresultを読み取りログ出力
|
||||
// 戻り値: true=テスト完了 (status==1)
|
||||
bool CheckResults(u32 vsync_count);
|
||||
|
||||
// Force inject (sets flag, actual inject happens at next vsync on CPU thread)
|
||||
void ForceInject();
|
||||
void ForceInjectMini(); // Mini stress test for hang investigation
|
||||
bool CheckForceInject();
|
||||
|
||||
// Get last results as string
|
||||
std::string GetResultsString();
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
name: Game Emulation Bug Report
|
||||
description: Problem in a game. (ie. graphical artifacts, crashes, etc.)
|
||||
title: '[GAME BUG]: '
|
||||
labels:
|
||||
- bug
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
## Important: Read First
|
||||
|
||||
Please do not make support requests on GitHub. Our issue tracker is for tracking bugs and feature requests only.
|
||||
If you have a support request or are unsure about the nature of your issue please contact us on [discord](https://discord.gg/KwAChKDctz).
|
||||
|
||||
Do not create issues involving software piracy of BIOS or ISO files, our rules specifically prohibit this and your issue will be closed.
|
||||
|
||||
- type: checkboxes
|
||||
id: checklist
|
||||
attributes:
|
||||
label: Checklist
|
||||
options:
|
||||
- label: I have searched for a similar issue in this repository and did not find one.
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: game
|
||||
attributes:
|
||||
label: Game Title
|
||||
placeholder: 'e.g. Dragon Ball Z: Budokai 2'
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: emu-ver
|
||||
attributes:
|
||||
label: ARMSX2 Version
|
||||
description: Please ensure you are on the latest version before making an issue.
|
||||
placeholder: e.g. v1.0.4
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: dropdown
|
||||
id: renderer
|
||||
attributes:
|
||||
label: Renderer (Graphics Backend)
|
||||
options:
|
||||
- Vulkan
|
||||
- OpenGL
|
||||
- Software
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: device
|
||||
attributes:
|
||||
label: Device Model
|
||||
placeholder: e.g. Google Pixel 4
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: os-ver
|
||||
attributes:
|
||||
label: OS Version
|
||||
placeholder: e.g. Android 12
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: textarea
|
||||
id: desc
|
||||
attributes:
|
||||
label: Describe the Bug
|
||||
description: A clear and concise description of what the bug is.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: repro
|
||||
attributes:
|
||||
label: Reproduction Steps
|
||||
description: Steps to reproduce the behavior.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: expect
|
||||
attributes:
|
||||
label: Expected Behavior
|
||||
description: A clear and concise description of what you expected to happen.
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: textarea
|
||||
id: log
|
||||
attributes:
|
||||
label: Log File
|
||||
description: A log file will help our developers to better diagnose and fix the issue.
|
||||
validations:
|
||||
required: false
|
||||
@@ -0,0 +1,81 @@
|
||||
name: Application Bug Report
|
||||
description: Problem with the application itself. (ie. bad file path handling, UX issue)
|
||||
title: '[APP BUG]: '
|
||||
labels:
|
||||
- bug
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
## Important: Read First
|
||||
|
||||
Please do not make support requests on GitHub. Our issue tracker is for tracking bugs and feature requests only.
|
||||
If you have a support request or are unsure about the nature of your issue please contact us on [discord](https://discord.gg/KwAChKDctz).
|
||||
|
||||
Do not create issues involving software piracy of BIOS or ISO files, our rules specifically prohibit this and your issue will be closed.
|
||||
|
||||
- type: checkboxes
|
||||
id: checklist
|
||||
attributes:
|
||||
label: Checklist
|
||||
options:
|
||||
- label: I have searched for a similar issue in this repository and did not find one.
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: emu-ver
|
||||
attributes:
|
||||
label: ARMSX2 Version
|
||||
description: Please ensure you are on the latest version before making an issue.
|
||||
placeholder: e.g. v1.0.4
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: device
|
||||
attributes:
|
||||
label: Device Model
|
||||
placeholder: e.g. Google Pixel 4
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: os-ver
|
||||
attributes:
|
||||
label: OS Version
|
||||
placeholder: e.g. Android 12
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: desc
|
||||
attributes:
|
||||
label: Describe the Bug
|
||||
description: A clear and concise description of what the bug is.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: repro
|
||||
attributes:
|
||||
label: Reproduction Steps
|
||||
description: Steps to reproduce the behavior.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: expect
|
||||
attributes:
|
||||
label: Expected Behavior
|
||||
description: A clear and concise description of what you expected to happen.
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: textarea
|
||||
id: log
|
||||
attributes:
|
||||
label: Log File
|
||||
description: A log file will help our developers to better diagnose and fix the issue.
|
||||
validations:
|
||||
required: false
|
||||
@@ -0,0 +1,57 @@
|
||||
name: Feature Request
|
||||
description: Suggest a new feature or improve an existing one.
|
||||
title: '[Feature Request]: '
|
||||
labels:
|
||||
- enhancement
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
## Important: Read First
|
||||
|
||||
Please make an effort to make sure your issue isn't already reported.
|
||||
|
||||
Do not create issues involving software piracy of BIOS or ISO files, our rules specifically prohibit this and your issue will be closed.
|
||||
|
||||
- type: checkboxes
|
||||
id: checklist
|
||||
attributes:
|
||||
label: Checklist
|
||||
options:
|
||||
- label: I have searched for a similar issue in this repository and did not find one.
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: desc
|
||||
attributes:
|
||||
label: Description
|
||||
description: |
|
||||
A concise description of the feature you want.
|
||||
|
||||
Include step by step examples of how the feature should work under various circumstances.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: reason
|
||||
attributes:
|
||||
label: Reason
|
||||
description: |
|
||||
Give a reason why you want this feature.
|
||||
- How will it make things easier for you?
|
||||
- How does this feature help your enjoyment of the emulator?
|
||||
- What does it provide that isn't being provided currently?
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: examples
|
||||
attributes:
|
||||
label: Examples
|
||||
description: |
|
||||
Provide examples of the feature as implemented by other software.
|
||||
|
||||
Include screenshots or video if you like to help demonstrate how you'd like this feature to work.
|
||||
validations:
|
||||
required: true
|
||||
@@ -0,0 +1,5 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Discord
|
||||
url: https://discord.gg/KwAChKDctz
|
||||
about: Get direct support and hang out with us.
|
||||
@@ -0,0 +1,124 @@
|
||||
name: Android Nightly Debug Build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
paths-ignore:
|
||||
- '**/*.md'
|
||||
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
paths-ignore:
|
||||
- '**/*.md'
|
||||
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
outputs:
|
||||
package_name: ${{ steps.package_info.outputs.PACKAGE_NAME }}
|
||||
version_name: ${{ steps.package_info.outputs.VERSION_NAME }}
|
||||
release_tag: ${{ steps.release_vars.outputs.RELEASE_TAG }}
|
||||
release_title: ${{ steps.release_vars.outputs.RELEASE_TITLE }}
|
||||
|
||||
steps:
|
||||
- name: Checkout of code
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Java and Android SDK Setup
|
||||
uses: actions/setup-java@v5
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '17'
|
||||
cache: 'gradle'
|
||||
|
||||
# --- Build Phase ---
|
||||
- name: Running the Debug Build (only Nightly)
|
||||
run: ./gradlew assembleUnrestrictedDebug
|
||||
|
||||
- name: Get Package Name and Version
|
||||
id: package_info
|
||||
run: |
|
||||
PACKAGE_NAME=$(grep 'applicationId' app/build.gradle | head -n 1 | awk '{print $2}' | tr -d '"')
|
||||
VERSION_NAME=$(grep 'versionName' app/build.gradle | head -n 1 | awk '{print $2}' | tr -d '"')
|
||||
echo "PACKAGE_NAME=$PACKAGE_NAME" >> $GITHUB_OUTPUT
|
||||
echo "VERSION_NAME=$VERSION_NAME" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Defining the Release Tag and Title
|
||||
id: release_vars
|
||||
run: |
|
||||
# The release tag will be in the format: come.nanodata.armsx2-nightly-1.0.4-20251104-1411
|
||||
DATE_TIME=$(date +%Y%m%d-%H%M)
|
||||
FULL_TAG="${{ steps.package_info.outputs.PACKAGE_NAME }}-nightly-${{ steps.package_info.outputs.VERSION_NAME }}-${DATE_TIME}"
|
||||
TITLE="Nightly Build (DEBUG - ${{ steps.package_info.outputs.VERSION_NAME }}) - ${DATE_TIME}"
|
||||
|
||||
echo "RELEASE_TAG=$FULL_TAG" >> $GITHUB_OUTPUT
|
||||
echo "RELEASE_TITLE=$TITLE" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Find and Rename APK to Nightly
|
||||
id: rename_apk
|
||||
run: |
|
||||
ORIGINAL_PATH=$(find ${{ github.workspace }}/app/build -type f -name "*debug.apk" -print -quit)
|
||||
if [ -z "$ORIGINAL_PATH" ]; then
|
||||
echo "CRITICAL ERROR: Debug APK non found."
|
||||
exit 1
|
||||
fi
|
||||
NEW_FILE_PATH=$(echo "$ORIGINAL_PATH" | sed 's/-debug.apk/-nightly.apk/')
|
||||
mv "$ORIGINAL_PATH" "$NEW_FILE_PATH"
|
||||
echo "APK_FILE_NIGHTLY=$NEW_FILE_PATH" >> $GITHUB_OUTPUT
|
||||
echo "APK renamed and saved in: $NEW_FILE_PATH"
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v5
|
||||
with:
|
||||
name: ${{ steps.package_info.outputs.PACKAGE_NAME }}
|
||||
path: ${{ steps.rename_apk.outputs.APK_FILE_NIGHTLY }}
|
||||
|
||||
release:
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
needs: [ build ]
|
||||
|
||||
if: >
|
||||
github.repository == 'ARMSX2/ARMSX2' &&
|
||||
github.ref == 'refs/heads/master'
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
concurrency:
|
||||
group: release
|
||||
cancel-in-progress: false
|
||||
|
||||
steps:
|
||||
- name: Download artifact
|
||||
uses: actions/download-artifact@v5
|
||||
with:
|
||||
name: ${{ needs.build.outputs.package_name }}
|
||||
path: artifact
|
||||
|
||||
- name: Create the Release on GitHub
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
tag_name: ${{ needs.build.outputs.release_tag }}
|
||||
name: ${{ needs.build.outputs.release_title }}
|
||||
body: |
|
||||
## Automatic Night Release (DEBUG)
|
||||
|
||||
Automated build for community testing. This is an **unsigned** build for public distribution.
|
||||
|
||||
* **Version:** ${{ needs.build.outputs.version_name }}
|
||||
* **Package Name:** ${{ needs.build.outputs.package_name }}
|
||||
* **Branch:** ${{ github.ref_name }}
|
||||
* **Commit:** ${{ github.sha }}
|
||||
|
||||
**Check the attached assets for the NIGHTLY APK.**
|
||||
draft: false
|
||||
prerelease: true
|
||||
files: artifact/*.apk
|
||||
@@ -0,0 +1,43 @@
|
||||
# Build system and IDE files
|
||||
build/
|
||||
.gradle
|
||||
.vscode/
|
||||
.idea/
|
||||
.project
|
||||
.settings/
|
||||
local.properties
|
||||
node_modules/
|
||||
bun.lockb
|
||||
package-lock.json
|
||||
/build-ios*/
|
||||
/build-maccatalyst/
|
||||
/ipa-package/
|
||||
*.ipa
|
||||
|
||||
# OS junk & editor/files
|
||||
.DS_Store
|
||||
app/.DS_Store
|
||||
app/src/.DS_Store
|
||||
app/src/main/.DS_Store
|
||||
|
||||
# Android/NDK/intermediate output
|
||||
app/.cxx/
|
||||
app/src/main/jniLibs/
|
||||
app/src/main/cpp/bin
|
||||
|
||||
# Sensitive or key material
|
||||
armsx2_release.jks
|
||||
armsx2_keystore.properties
|
||||
app/src/main/assets/discord_creds.env
|
||||
|
||||
# Temporary/log/output files
|
||||
log.txt
|
||||
|
||||
# Third-party (vendored) native or generated sources
|
||||
app/src/main/cpp/3rdparty/rcheevos/.build
|
||||
app/src/main/cpp/3rdparty/discord_social_sdk/cdiscord.h
|
||||
app/src/main/cpp/3rdparty/discord_social_sdk/discordpp.h
|
||||
|
||||
# External libs
|
||||
app/libs/discord_partner_sdk.aar
|
||||
macos
|
||||
@@ -0,0 +1,3 @@
|
||||
[submodule "extras/Save-Tower_Adaptive"]
|
||||
path = extras/Save-Tower_Adaptive
|
||||
url = https://github.com/Vivimagic/Save-Tower_Adaptive.git
|
||||
@@ -0,0 +1,11 @@
|
||||
import React from 'react';
|
||||
import Router from './app_ui/Router.jsx';
|
||||
import { ThemeProvider } from './app_ui/theme.jsx';
|
||||
|
||||
export default function App() {
|
||||
return (
|
||||
<ThemeProvider>
|
||||
<Router />
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
Windows:
|
||||
git clone https://github.com/ARMSX2/ARMSX2.git
|
||||
git submodule init
|
||||
git submodule update
|
||||
|
||||
cd app\src\main\cpp\3rdparty\libadrenotools
|
||||
git submodule init
|
||||
git submodule update
|
||||
|
||||
NPM Packages:
|
||||
npm install --legacy-peer-deps
|
||||
|
||||
Build: react-native-gradle-plugin
|
||||
cd node_modules/@react-native/gradle-plugin
|
||||
npm install
|
||||
gradlew.bat build
|
||||
|
||||
Change: node_modules\@assembless\react-native-material-you\android\build.gradle
|
||||
android {
|
||||
compileSdkVersion 36
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 34
|
||||
targetSdkVersion 34
|
||||
}
|
||||
}
|
||||
|
||||
gradlew.bat assembleDebug -PenableRN=true
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,76 @@
|
||||
<div align="center">
|
||||
|
||||

|
||||
|
||||
# ARMSX2
|
||||
|
||||
[](https://www.gnu.org/licenses/gpl-3.0.html)
|
||||
[](https://discord.gg/6yyawTtCnX)
|
||||
(https://patreon.com/ARMSX2)
|
||||
[](https://github.com/ARMSX2/ARMSX2/actions/workflows/android_nightly_build.yml)
|
||||
|
||||
</div>
|
||||
|
||||
ARMSX2 is a free and open-source PlayStation 2 emulator for ARM devices, based on PCSX2, PCSX2_ARM64 for our OG versions that used x86 translation, and our own arm64jit with the new ARMSX2 refresh versions.
|
||||
|
||||
Its goal is to bring modern PS2 emulation to ARM platforms while staying aligned with upstream PCSX2 improvements. ARMSX2 now supports native ARM64 JIT/recompiler work alongside legacy x86-to-ARM64 translation paths, meaning it is no longer solely dependent on x86 translation. Development is ongoing, and the project continues to move toward deeper native ARM64 support as more of the emulator core is modernized.
|
||||
|
||||
ARMSX2 allows you to play PS2 games on Android, iOS, Linux, macOS, and Windows devices, with a focus on ARM-based mobile and desktop hardware.
|
||||
|
||||
## Project Details
|
||||
|
||||
ARMSX2 began after years of there being no open source PS2 emulator for ARM systems, and so developer [@MoonPower](https://github.com/momo-AUX1) with the support of [@jpolo1224](https://github.com/jpolo1224) decided to try their hand at porting a new PS2 emulator for Android, forking from the repository PCSX2_ARM64 by developer Pontos. Moon has and will continue doing his best to fill in the gaps and make this into a complete emulator, with the goal to have version parity with PCSX2. This project is not officially associated with PCSX2, and we are not associated with any other forks made from the original repository. This is our own attempt at continuing PS2 emulation on Android, iOS, and MacOS. The emulator no longer operates as just x86 -> arm64, we now have native arm64 support in our refresh/2.0 builds.
|
||||
## System Requirements
|
||||
|
||||
ARMSX2 supports any ARM capable device, including Android, iOS, Linux, and Windows platforms (eventually, should work as well). Please note that performance will also depend on your devices hardware capabilities, we have done our best to optimize for low end devices and will continue to do so.
|
||||
|
||||
Please note that a BIOS dump from a legitimately-owned PS2 console is required to use the emulator.
|
||||
|
||||
## Website
|
||||
|
||||
→ <https://armsx2.net/>
|
||||
|
||||
Any other website is not affiliated with ARMSX2.
|
||||
|
||||
## Translation
|
||||
|
||||
[Help translate ARMSX2](https://crowdin.com/project/armsx2-translations/invite?h=940eaf6355b31b5fdb1771183c694ca32710218)
|
||||
|
||||
## Download
|
||||
|
||||
ARMSX2 is available on the Google Play Store once released.
|
||||
|
||||
[<img src="https://play.google.com/intl/en_us/badges/static/images/badges/en_badge_web_generic.png" alt="Get it on Google Play" height="80"/>](https://play.google.com/store/apps/details?id=come.nanodata.armsx2)
|
||||
|
||||
## Affiliation
|
||||
|
||||
We are NOT affiliated with ARM Holding LTD in any way shape or form. We chose the name ARMSX2 since it runs on ARM devices, and seek no commercial incentive from the emulator. The most we accept is voluntary donations. Thank you.
|
||||
|
||||
## Additional Credits
|
||||
|
||||
[PCSX2](https://github.com/PCSX2/pcsx2) - ARMSX2 would not be possible without the legendary work from the PCSX2 team and their patience and understanding regarding this project!
|
||||
|
||||
[PCSX2_ARM64](https://github.com/pontos2024/PCSX2_ARM64) - ARMSX2 originally started off as a fork of developer Pontos work.
|
||||
|
||||
Thank you to [@Vivimagic](https://github.com/Vivimagic) for creating and working on the logo!
|
||||
|
||||
Thank you to developers [@tanosshi](https://github.com/tanosshi) [@jpolo1224](https://github.com/jpolo1224) [@MoonPower](https://github.com/momo-AUX1) for working on the ARMSX2 website!
|
||||
|
||||
## Why are there .js and .jsx files?
|
||||
|
||||
Originally as a curious idea the react native screens were just an experiment i decided to keep they are extremely barebones and will either be finalized in a seperate branch (armsx2-rn) or removed altogether They do not affect performance as they are hidden by default and not executed. Any PR to them is welcome!
|
||||
|
||||
### To start developing with ARMSX2 RN do the following:
|
||||
|
||||
1. First install the deps:
|
||||
```sh
|
||||
(npm/pnpm/bun) install
|
||||
```
|
||||
|
||||
|
||||
2. Compile ARMSX2 With the react native core:
|
||||
```sh
|
||||
./gradlew assembleDebug -PenableRN=true
|
||||
```
|
||||
|
||||
And now you will have a new button appear on the top right of the game selector screen click it and start developing with hot reload and see your changes without recompiling (note: compiling RN switches the emucore from static to shared).
|
||||
@@ -0,0 +1,89 @@
|
||||
|
||||
<div align="center">
|
||||
|
||||

|
||||
|
||||
# ARMSX2
|
||||
|
||||
[](https://www.gnu.org/licenses/gpl-3.0.html)
|
||||
[](https://discord.gg/6yyawTtCnX)
|
||||
(https://patreon.com/ARMSX2)
|
||||
[](https://github.com/ARMSX2/ARMSX2/actions/workflows/android_nightly_build.yml)
|
||||
|
||||
</div>
|
||||
|
||||
ARMSX2 é um emulador gratuito e de código aberto de PlayStation 2 (PS2) para dispositivos ARM baseado no PCSX2 e PCSX2_ARM64. O propósito é emular o hardware do PS2 para dispositivos ARM, usando um recompilador que opera de x86 para arm64, não arm64 nativo, isso está sujeito a alterações assim que o desenvolvimento continuar. ARMSX2 permite que você jogue jogos de PS2 no seu dispositivo móvel Android, assim como iOS, Linux, e dispositivos Windows.
|
||||
|
||||
## Detalhes do Projeto
|
||||
|
||||
ARMSX2 começou após anos pela falta de um emulador de código aberto para os sistemas ARM, e então o desenvolvedor [@MoonPower](https://github.com/momo-AUX1) com o suporte de [@jpolo1224](https://github.com/jpolo1224) decidiu tentar fazer um port de um novo emulador de PS2 para Android, fazendo um fork do repositório PCSX2_ARM64 do desenvolvedor Pontos. Moon tem feito e continuará fazendo o seu melhor para preencher as lacunas e fazer do ARMSX2 um emulador completo, com o objetivo de manter uma versão de paridade com a do PCSX2. Esse projeto não é oficialmente associado com PCSX2, e nós não somos associados com nenhum outro fork feito a partir do repositório original. Esta é a nossa própria tentativa de continuar a emulação de PS2 para Android, iOS, e MacOS. O emulador atualmente opera de x86 para arm64, não nativamente arm64, então muito provavelmente a performance não vai ser tão boa como AetherSX2 no momento, porém as coisas estão sujeitas a mudanças no decorrer do desenvolvimento.
|
||||
|
||||
## Requisitos do Sistema
|
||||
|
||||
ARMSX2 suporta qualquer dispositivo ARM capaz, incluindo as plataformas Android, iOS, Linux, e Windows (futuramente, também deve funcionar). Por gentileza, saiba que a performance também irá depender das capacidades de hardware do seu dispositivo, Temos feito o nosso melhor para otimizar para dispositivos low end e vamos continuar fazendo isso.
|
||||
|
||||
Por gentileza, saiba que uma imagem da BIOS vinda do seu console PS2 legítimo é necessária para usar o emulador.
|
||||
|
||||
## Website
|
||||
|
||||
→ <https://armsx2.net/>
|
||||
|
||||
Qualquer outro website não é afiliado com ARMSX2.
|
||||
|
||||
## Traduções
|
||||
|
||||
[Ajude a traduzir o ARMSX2](https://crowdin.com/project/armsx2-translations/invite?h=940eaf6355b31b5fdb1771183c694ca32710218)
|
||||
|
||||
## Baixar
|
||||
|
||||
ARMSX2 está disponível na [Google Play Store](https://play.google.com/store/apps/details?id=come.nanodata.armsx2)
|
||||
|
||||
[<img src="https://play.google.com/intl/en_us/badges/static/images/badges/en_badge_web_generic.png" alt="Baixe pela Google Play" height="80"/>](https://play.google.com/store/apps/details?id=come.nanodata.armsx2)
|
||||
|
||||
## Afiliação
|
||||
|
||||
Nós NÃO somos afiliados de forma/maneira nenhuma com ARM Holding LTD. Nós escolhemos o nome ARMSX2 já que executa em dispositivos ARM, e não queremos nenhum incentivo comercial com o emulador. O máximo que aceitamos é doações voluntárias. Obrigado.
|
||||
|
||||
## Créditos Adicionais
|
||||
|
||||
[PCSX2](https://github.com/PCSX2/pcsx2) - ARMSX2 não seria possível sem o trabalho, paciência e compreensão lendários da equipe do PCSX2 com relação ao projeto.
|
||||
|
||||
[PCSX2_ARM64](https://github.com/pontos2024/PCSX2_ARM64) - ARMSX2 originalmente começou como um fork do trabalho de pontos.
|
||||
|
||||
Obrigado [@Vivimagic](https://github.com/Vivimagic) por criar e trabalhar na logo!
|
||||
|
||||
Obrigado aos desenvolvedores [@tanosshi](https://github.com/tanosshi) [@jpolo1224](https://github.com/jpolo1224) [@MoonPower](https://github.com/momo-AUX1) por trabalharem no website do ARMSX2!
|
||||
|
||||
## Roadmap
|
||||
|
||||
Aqui está o roadmap de coisas que você pode esperar do ARMSX2 no futuro:
|
||||
|
||||
| Tarefa | Prioridade |
|
||||
| --- | --- |
|
||||
| Arrumar GPUs xclipse | Alta |
|
||||
| Arrumar os crashes em GPUs Mali | Alta |
|
||||
| Suporte para Nintendo Switch | Média |
|
||||
| Atualizar para o núcleo mais recente | Alta |
|
||||
| Atualizar o design para Material expressive | Baixa |
|
||||
| Migrar para Kotlin | Média |
|
||||
|
||||
|
||||
## Por que existem arquivos .js e .jsx?
|
||||
|
||||
Originalmente como uma ideia curiosa, na verdade, as telas do React Native eram apenas um experimento, eu decidi manter extremamente básicos, serão finalizados em uma branch separada (armsx2-rn) ou removidos completamente, Não afetam a performance já que são escondidos por padrão e não executados. Qualquer PR para os mesmos são bem-vindas!
|
||||
|
||||
### Para começar a desenvolver com ARMSX2 agora faça o seguinte:
|
||||
|
||||
1. Primeiro instale as deps:
|
||||
```sh
|
||||
(npm/pnpm/bun) install
|
||||
```
|
||||
|
||||
|
||||
2. Compilar ARMSX2 com o react native core:
|
||||
```sh
|
||||
./gradlew assembleDebug -PenableRN=true
|
||||
```
|
||||
|
||||
E agora você terá um novo botão aparecendo no canto superior direito da tela de carregamento de jogos, clique e comece a desenvolver com hot reload e veja suas mudanças sem recompilação(nota: compilar agora muda o emucore de static para shared).
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user