Description
Play your PS2 games on iPhone and iPad.
You need your own PS2 BIOS and game files, and JIT for full speed. None of it is included.
ARMSX2 is a native ARM64 build of PCSX2. The recompilers run on your device instead of translating x86 code, which is what makes PS2 emulation workable on a phone. They are the shared ARM64 recompilers, checked by comparing what they execute against other emulators, and they apply the game database's own patches as a game runs.
What you get
• On-screen controls you can move and resize, with separate portrait and landscape layouts
• Controller skins, browsed and installed inside the app with a preview and the author on every row, or brought in yourself as .armsx2skin, Delta or ManicEMU. Each game can keep its own
• Per-game settings, so a fix for one game does not follow you into the next
• RetroAchievements, with your account, your progress and the achievement list in the app, and unlocks arriving as ordinary iOS notifications. Hardcore Mode still allows trusted widescreen and 60 FPS patches, and still blocks cheats
• Save states and virtual memory cards
• Save states from AetherSX2 and NetherSX2 builds load directly, once you copy them in through Files
• A frame rate cap that limits presentation only, to cut heat and battery drain
• An on-screen performance overlay
• External controllers, plus adjustable phone haptics
• Live backgrounds behind the menus: twelve built in, including a PS2 menu and an XMB recreation, or your own image or video, set separately for portrait and landscape
• Ten alternate app icons
Requirements
iPhone or iPad on iOS 17 or later. JIT is what gets you full speed. Without it ARMSX2 falls back to an interpreter rather than refusing to start, flags it with a No JIT badge while you play, and most games are too slow to enjoy. Disc images open straight from Files: .iso, .bin, .img, .chd and .rom.
How well a game runs depends on your device, your iOS version and the game itself. Some are perfect, some are slow, some do not boot. Check the compatibility list before you start.
Links
Website: https://armsx2.net
Compatibility: https://armsx2.net/compatibility
Docs and FAQ: https://armsx2.net/docs
Discord: https://discord.gg/S7VxwfS8w9
Source code: https://github.com/ARMSX2/ARMSX2
Support development
Patreon: https://www.patreon.com/cw/ARMSX2
Ko-fi: https://ko-fi.com/armsx2
Credits
ARMSX2 is open source under GPL-3.0 and builds on PCSX2. Started by MoonPower with support from jpolo1224, forked from PCSX2_ARM64 by Pontos.
App icon by fffathur, logo by Vivimagic. The icon artwork is MIT licensed: https://github.com/ARMSX2/Save-Tower
ARMSX2 does not include games or BIOS files. Donations are voluntary and the project seeks no commercial return. It is not officially associated with PCSX2 or with any other fork of it, and not affiliated with Sony Interactive Entertainment or PlayStation.
Change Log
https://github.com/ARMSX2/ARMSX2/releases/tag/iOSv2.5.2
Frame rate cap
@Henyckma added an FPS cap that limits presentation only. The game and the audio keep running at full speed, so it costs nothing in emulation and gives back battery and heat instead. Targets are 15, 23.976, 29.94, 30, 45, 59.97, 60, 90 and 120, set globally or per game. The gain is biggest at 2x and 3x internal resolution, where the passes it skips cover the most pixels. Selecting 30 FPS used to halve emulation and audio speed, which is fixed, and FPS profiles from earlier builds carry over without losing the cadence you picked.
Crashes and freezes
Fixed a crash in games like Namco Museum 50th Anniversary, which turned out to be an out of bounds write in the virtual memory page protection table. Fixed a freeze in readback heavy scenes with Hardware Download Mode set to Unsynchronized. Rogue Galaxy no longer stalls the graphics thread around 7.5 ms every frame on a depth probe readback, about a fifth of the frame on an M2. The last two are bmdhacks. Saving per game settings could also leave the game frozen a second or two later, which is covered below.
Sprite hacks
Align Sprite and Merge Sprite apply when you switch them off. This was the third report of that bug and the fifth attempt at it, and the earlier ones all fixed the global screen while leaving everything around it alone. Per game, those rows greyed out whenever GameDB Graphics Fixes was on, kept showing their old value, and got written back on every save. Align Sprite, Merge Sprite and Wild Arms Offset are one Use Global / Off / On picker each now, and they no longer need manual hacks mode. Setting one claims that fix, so the game database stops overriding it while keeping every other fix for the game. Texture Inside RT, Native Scaling, Bilinear Upscale, Unscaled Palette Draw, Preload Frame Data and Disable Partial Invalidation had the same bug and were fixed with it. None of these do anything at 1x internal resolution, which is by design.
Per-game settings
Turning on Use Per-Game Overrides used to soften text and edges: enabling it copied six graphics keys into the per game file, and one of those forced a blend deinterlace that also suppressed the game's own database fix. Only the settings you change are written now. Saving in that panel could also leave the game frozen a second or two later while the emulator carried on at full speed, because metadata scans share one disc image with the running game and a scan during play left it holding a closed disc.
The Renderer picker never saved a change made while a game was running, so it never applied either. It saves now, and it moved from Fixes & Compatibility to the Graphics tab where people kept looking for it. It still applies at the next boot of that game. Saving the panel is quicker too: it used to fire one full settings reload per field written, 71 of them for a single Save.
Settings
Every slider, stepper and typed number is one control now, and each setting is described once instead of once per screen. The FPS target had three different sets of bounds across three screens. Sliders stop on values people actually pick, every stop list holds the default so reset lands on one, and typing still reaches anything in between. Per game numbers can inherit the global value instead of choosing from a short list. The dynamic background sliders stay continuous, since every value there is a legitimate one, but they snap to the precision they print: a row could read 50% while storing 0.4973, which also left the reset arrow comparing against the hidden value.
Applying the Default preset asks first and then resets every setting, with the Default row showing as active afterwards, and Reset Graphics and Reset Emulator no longer reach into settings they do not show or drag Frame Pacing to Custom on the way. Buffer Size and Output Latency are sliders on Frame Pacing now, matching the Audio screen, and GS Back Thread says it needs a restart instead of looking broken. The preset fixes are @Henyckma's.
Rumble
Phone Rumble Strength runs on a scale that means something: off at 0%, the previous strength at 25%, and roughly three times that at 100%, with a separate Increase Duration of Rumble and Interpolation toggle that stretches how long an effect is felt without changing how strong it is. That changes what the stored value means, so existing settings are rescaled once on first launch rather than getting louder on update. Controller rumble is unchanged. Also @Henyckma.
Interface
The interface is dark everywhere now, whatever the device is set to. The library, the BIOS list and the settings screens used to follow the system while gameplay and the pause menu were already dark. There is a new App Icon screen under Interface with ten alternate icons.
Hide Menu Button stays hidden until you bring it back, and the choice survives restarting the app. Any controller press used to restore the button and switch the setting off with it. Tapping the game area shows it for about four seconds instead.
Booting without JIT shows a two stage warning now, and a red No JIT badge sits beside the Pause control while you play. Stop is on the Quick Menu and leaves the game straight away. The keyboard no longer flips the per game panel to the wrong layout, rotating no longer throws away unsaved edits, and Change Disc and Controller Skin line up with the rest of the pause menu. The no JIT warning and Quick Menu Stop are @Henyckma's.
Emulation accuracy
@bmdhacks and @pstef landed 26 EE and vector unit correctness fixes covering square root, min and max, the arctangent series, the multiplier's rounding and several flag paths. 23 of them cite hardware or console behaviour.
Save states
Save states written by AetherSX2 v1.5-era builds and NetherSX2 v2.1 load directly, and saving over one writes a current format state. Voice, streaming and DMA state come back with them, so audio carries on instead of resetting. Pad, USB and achievement blocks in those older states predate the format ARMSX2 reads today and get skipped, so controllers keep whatever type and mode they booted with. There is no import button yet. Copy the file into the sstates folder in the ARMSX2 documents directory using the Files app, named the way ARMSX2 names its own: SERIAL (CRC).01.p2s
Thanks
Thanks to @bmdhacks for the save state loading, the accuracy work, the GS fixes and the Rogue Galaxy tuning, to @henyckma for the frame rate cap, the haptics, Quick Menu Stop, the preset resets and the no JIT warning, and to pstef for the EE multiplier work. Thanks as well to the testers who tracked down the per game text softening, the Namco Museum crash, and three separate rounds of Align Sprite.
Full commit list: https://github.com/ARMSX2/ARMSX2/compare/iOSv2.5.1...iOSv2.5.2
Version
2.5.2 (252)
Last Updated
August 6, 2026