Skip to content

Repository files navigation

SFA3 MAX — Native 16:9 Widescreen Patch (PSP)

🌐 English · 日本語 · Français · Español · Português (BR)

Native 16:9 (480×272) widescreen patch for Street Fighter Alpha 3 MAX / Street Fighter Zero 3 Double Upper on PSP.

The game's internal display option must be set to "Normal" (un-stretched 4:3). This patch makes the engine render the background natively in 16:9: the viewport is opened to the full 480 px and the background tile layers are extended with real stage tiles on the left and right, kept centered — no stretching, no triple-render duplication.

Before / after

Stock (4:3, pillarbox) Patched (native 16:9)
before after
Version 1.1
Supported dumps EU ULES-00235 (v1.01) · US ULUS-10062 · JP ULJM-05082 (v1.01, Zero 3 Double Upper)
Tested on PPSSPP
Input a decrypted EBOOT.BIN (ELF)
Method pure-Python binary patcher, pattern-scan (no hard-coded offsets)

What it does

  • Viewport opener — render window 384 → 480 px, side pillarbox removed.
  • Background widescreen — the three background tile drawers (16 px and 32 px layers) get extra columns + a left shift, so the background fills the whole 480 px centered.

New in v1.1

  • Painted-decor / object layers (temples, trees, foreground props, and the title/menu/character-select art — a separate render path the v1.0 patch never touched) are now extended to 480 px instead of being clipped at the old 4:3 bounds.
  • Wrap-seam vertical-shift fix — v1.0 shifted the tile layers left to fill the widened side, but the wrap-around trigger wasn't adjusted, so the last column / scroll seam read one tile-row too low (a ~16 px downward shift). All three tile drawers now compensate the trigger, so seams line up exactly.
  • Third tile drawer (FUN_177c8) — the one tilemap routine v1.0 left in 4:3 now gets the full widescreen treatment (count + left shift + seam fix).

The character sprites, HUD and gameplay are untouched and stay centered.

Known limitation

At the extreme edges of a stage (where the tilemap simply contains no more tiles) a small margin can remain in those rare camera positions. This is a data limit of the original stage, not a code limit. Mid-stage the background is full 16:9.


Quick start (PPSSPP, decrypted EBOOT)

python sfa3_ws_patternpatcher.py  EBOOT.BIN  EBOOT_WS.BIN

Then run EBOOT_WS.BIN (or repack it into the ISO — see below) and set the game's internal display option to Normal.

The patcher refuses to write if anything looks wrong (missing/duplicate signature), so it never produces a half-patched file, and it recognises an already-patched EBOOT or ISO up front and leaves it alone.


Easiest install — PPSSPP cheat (no decrypt, no repack)

Ready-made cheats are in cheats/, one per region. They apply the exact same memory edits as the patcher, continuously at runtime, so you don't need to decrypt or repack anything — just drop the file in and enable it.

  1. Copy cheats/<DISC-ID>.ini into memstick/PSP/Cheats/ (e.g. ULES00235.ini).
  2. PPSSPP: Settings → System → Enable cheats.
  3. Launch the game → Pause → Cheats → tick "16:9 Widescreen (native, v1.1)".
  4. Set the game's internal display option to Normal.

⚠️ Version-specific. Cheat addresses are fixed for the dumps listed above (EU/JP v1.01). A different revision shifts the addresses — in that case use the Python patcher instead, which locates everything by pattern and adapts to any revision. (Your dump's revision shows in PPSSPP's game info, or as _1.0x in save-state filenames.)



Patch an ISO directly (no extraction, no UMDGen)

The same script takes the disc image and does the whole job:

python sfa3_ws_patternpatcher.py  GAME.iso  GAME_WS.iso

It walks the ISO9660 filesystem (no hard-coded LBA), finds PSP_GAME/SYSDIR/EBOOT.BIN, patches it and writes a new ISO — then re-opens that ISO and verifies it: the EBOOT reads back exactly as patched and every other file is byte-identical (sha1 per file).

  • ISO holding a decrypted EBOOT (a "DECRYPTED" ISO, or one you repacked once already): patched in place — the patch never changes the file size, so not a single LBA moves.

  • Retail ISO (encrypted ~PSP EBOOT): nothing to decrypt either. A retail UMD keeps the unencrypted ELF right beside the signed one, as PSP_GAME/SYSDIR/BOOT.BIN — byte-for-byte the same program as PPSSPP's decrypted dump (verified on EU, US and JP). The script falls back to it automatically, patches it and writes it into the EBOOT.BIN slot; both slots end up patched (--no-boot leaves BOOT.BIN alone). On this game the patched ELF is smaller than the encrypted EBOOT, so it fits the existing extent and no LBA moves.

    For an ISO without a plain BOOT.BIN, supply a decrypted EBOOT instead:

    python sfa3_ws_patternpatcher.py GAME.iso GAME_WS.iso --eboot ULES00235_EBOOT.BIN
    

    (or --decrypter "<cmd>", called as <cmd> <in> <out>, for a PRXDecrypter-style tool). If the result then needs more room than the original, the image is resized the way UMDGen would: following sectors shifted, every directory-record LBA, both path tables and the volume space size fixed.

  • CSO input is read directly (GAME.cso → patched .iso); use maxcso if you want a CSO back. ZSO/DAX are not supported.

  • --list prints the ISO tree · --dry-run writes nothing · re-running on an already-patched ISO just says so.

Tested on retail and decrypted ISOs of all three regions (EU ULES-00235, US ULUS-10062, JP ULJM-05082): in each case the patched EBOOT read back out of the ISO carries exactly the 62 word edits of that region's cheat file, and every other file on the disc is byte-identical.

A decrypted EBOOT inside an ISO runs fine in PPSSPP; real hardware/CFW still needs a re-signed EBOOT (sign_np). Should an ISO carry no plain BOOT.BIN, the decryption step becomes unavoidable — UMDGen cannot do it either; it only performs the filesystem surgery, which is exactly what this script replaces.

Full workflow: ISO → decrypt → patch → repack

The EBOOT inside a retail ISO is encrypted (~PSP / PSAR header). You must decrypt it first. Re-encryption is not required for PPSSPP.

1. Extract & decrypt the EBOOT (PPSSPP)

PPSSPP can dump the decrypted EBOOT for you:

  1. Settings → Tools → Developer tools → enable "Dump Decrypted EBOOT.BIN on game boot".
  2. Boot the game once.
  3. The decrypted file appears in memstick/PSP/SYSTEM/DUMP/<DISC-ID>_EBOOT.BIN (e.g. ULES00235_EBOOT.BIN). Copy it out.

Alternatively use PRXDecrypter on a real/emulated PSP, which writes a decrypted BOOT.BIN.

2. Patch it

python sfa3_ws_patternpatcher.py  ULES00235_EBOOT.BIN  EBOOT_WS.BIN

3. Repack into the ISO (UMDGen)

  1. Open the original ISO in UMDGen.
  2. Navigate to PSP_GAME/SYSDIR/EBOOT.BIN.
  3. Right-click → Import / Replace file and select EBOOT_WS.BIN.
    • PPSSPP runs a decrypted EBOOT placed in the ISO directly; no signing needed for emulator use.
  4. File → Save As a new ISO.

Real-hardware use needs a signed EBOOT (e.g. sign_np) and CFW; this guide targets PPSSPP.

4. Set display to Normal

In-game: Options → Display → Normal (not "Wide"/stretched). The widescreen now comes from real rendered tiles, not stretching.


Files

File Purpose
sfa3_ws_patternpatcher.py the patcher — one file, takes an ISO/CSO or a decrypted EBOOT
cheats/<DISC-ID>.ini ready-made PPSSPP cheats (per region, no repack needed)
README.md this file — user guide
TECHNICAL.md full reverse-engineering write-up: every patch explained
LICENSE MIT (patcher code only); game © Capcom

Tools used

Tool Role Where
Python 3 runs the patcher (stdlib only — no pip install) python.org
PPSSPP EBOOT decryption dump · GE/CPU debuggers used for the reverse-engineering ppsspp.org
UMDGen repack the patched EBOOT into the ISO — optional, sfa3_ws_patternpatcher.py does it (Windows ISO tool)
PRXDecrypter alternative EBOOT decryption on real/CFW PSP (PSP homebrew)
sign_np re-sign EBOOT for real-hardware use (not needed for PPSSPP) (PSP homebrew)

Requirements: Python 3.8+. No third-party packages — the patcher imports only os, sys, struct from the standard library.


Credits / notes

Reverse-engineered from the decrypted EBOOT via static MIPS disassembly and PPSSPP's GE/CPU debuggers. The patch is a set of in-place instruction edits plus two small code-caves placed in existing executable padding — no file size change.

Original game © Capcom.


Credits & license

Original patcher under MIT. Acknowledgments (PPSSPP for testing) and legal notes in CREDITS.md. No game/EBOOT is distributed — provide your own.

About

Native 16:9 widescreen patch for Street Fighter Alpha 3 MAX (PSP) — EU/US/JP

Topics

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages