Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 10 additions & 28 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,15 @@ set(PSXRECOMP_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/psxrecomp-v4" CACHE PATH

include("${PSXRECOMP_ROOT}/runtime/runtime.cmake")

set(GAME_GENERATED_FULL
"${CMAKE_CURRENT_SOURCE_DIR}/generated/SCUS_944.23_full.c")
# Current psxrecomp emits the large game translation unit as numbered shards.
# Keep the monolithic fallback for older/generated source drops.
file(GLOB GAME_GENERATED_FULL CONFIGURE_DEPENDS
"${CMAKE_CURRENT_SOURCE_DIR}/generated/SCUS_944.23_full_[0-9][0-9].c")
list(SORT GAME_GENERATED_FULL)
if(NOT GAME_GENERATED_FULL)
set(GAME_GENERATED_FULL
"${CMAKE_CURRENT_SOURCE_DIR}/generated/SCUS_944.23_full.c")
endif()
set(GAME_GENERATED_DISPATCH
"${CMAKE_CURRENT_SOURCE_DIR}/generated/SCUS_944.23_dispatch.c")

Expand All @@ -21,33 +28,8 @@ psxrecomp_add_runtime_target(psx-runtime
WINDOW_TITLE "ApeEscapeRecomp"
DEFAULT_BIOS_PATH "${PSXRECOMP_ROOT}/bios/SCPH1001.BIN"
DEFAULT_GAME_CONFIG_PATH "game.toml"
LAUNCHER_BOXART "${CMAKE_SOURCE_DIR}/recomp/launcher/boxart.tga"
# Per-game executable name so each title's process is distinct (killing/
# launching one title by name never hits another's running instance).
EXE_NAME "ApeEscapeRecomp"
)

# Shared recomp-ui Dear ImGui launcher. Wires in the PSX-themed launcher UI
# (see main.cpp RECOMP_LAUNCHER gate) instead of the framework's default RmlUi
# launcher. recomp-ui is a real git submodule (github.com/mstan/recomp-ui,
# pinned via the recomp-ui gitlink); locally it is a directory junction to the
# working checkout so builds stay offline and reproducible like everything else.
include("${CMAKE_SOURCE_DIR}/recomp-ui/recomp_ui.cmake")
recomp_target_launcher_ui(psx-runtime
BOXART "${CMAKE_SOURCE_DIR}/recomp/launcher/boxart.tga"
PAD "${CMAKE_SOURCE_DIR}/recomp/launcher/pad.tga"
BRAND "${CMAKE_SOURCE_DIR}/recomp/launcher/brand.tga" # PlayStation shapes, not the SNES mark
)

# Per-game launcher art override. The framework copies its shared launcher assets
# (img/disc.png etc. — the default is Tomba's disc) next to the exe inside
# psxrecomp_add_runtime_target above; this copies this repo's launcher_art/ on top
# AFTERWARD (POST_BUILD commands run in add order) so the launcher shows Ape
# Escape's disc. img/disc.png is a generated PLACEHOLDER — drop official box/disc
# art into launcher_art/img/ to replace it.
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/launcher_art")
add_custom_command(TARGET psx-runtime POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
"${CMAKE_CURRENT_SOURCE_DIR}/launcher_art"
"$<TARGET_FILE_DIR:psx-runtime>"
COMMENT "Overriding launcher art with ApeEscapeRecomp/launcher_art")
endif()
19 changes: 7 additions & 12 deletions ISSUES.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ and Tomba (1).

---

## #5 — Widescreen: HUD / UI elements are stretched — OPEN (root-caused)
## #5 — Widescreen: HUD / UI elements are stretched — OPEN

On the projection-and-stretch widescreen path, 3D geometry is squashed at GTE
projection time so the final frame stretch restores its proportions. Screen-space
Expand Down Expand Up @@ -112,17 +112,12 @@ widescreen build.
`0x8001A3xx` store loops) are **shared with world object rendering** — the
HUD/world discrimination point is the orchestrator subtree, not the builders.

**Fix design (framework class mechanism + per-game config, enhancement tier):**
`[widescreen] hud_bracket_funcs` — (1) recompiler emits `psx_ws_hud_enter(cpu)`
at entry of listed funcs (same emission pattern as `sprite_tag_funcs` /
`unsquash_funcs`; regen required); (2) runtime bracket records guest (sp, ra)
and the dispatcher closes it when pc==ra with sp restored (the existing
(ra,sp)-contract pattern); (3) while bracketed, guest RAM stores mark a
frame-stamped HUD packet-address hash (same table shape as the sprite tag);
(4) gpu.c squashes tagged prims — polys and rects — around the existing
`ws_hud_pivot` thirds-anchor; identity at 4:3 / unconfigured. Ape config:
bracket `0x8005BF70` (verify pause-menu coverage at implementation time; add
`0x80060780` if its screens need it).
**Failed validation 2026-07-19.** Function-bracketing and packet-writer guesses
did not cover the title screen, the four-button gadget UI, or all character
draw paths. A 21:9 gameplay capture also showed squashed Spike and unacceptable
scene gaps. Those per-game hooks are disabled. The replacement must distinguish
GTE-projected geometry from screen-space UI at the submitted packet itself and
must pass paired 4:3 / 16:9 / 21:9 image checks before this issue is closed.

---

Expand Down
15 changes: 12 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,20 @@ so treat it as a very playable preview rather than a certified full playthrough.

An **experimental 16:9 / 21:9 mode** is available in the launcher (off by
default; the game ships authentic 4:3). It uses the stable GTE
projection-and-stretch path for a wider 3D field of view. The title sky and
ferris-wheel cabin regressions are fixed; the remaining very-wide draw-distance
limitation is tracked in [`ISSUES.md`](ISSUES.md). Regular 4:3 play is
projection-and-stretch path for a wider 3D field of view. UI proportion,
character projection, and scene-culling regressions are still under active
validation and are tracked in [`ISSUES.md`](ISSUES.md). Regular 4:3 play is
byte-for-byte the original presentation and is unaffected.

The launcher's Video page exposes **Supersampling (1x-4x)**,
**Antialiasing**, and **Texture filtering**. On OpenGL, supersampling is true
ordered-grid SSAA: geometry and shading are rasterized at a higher internal
resolution and resolved to the window, while native PSX VRAM remains the
authoritative game-visible buffer. Antialiasing controls the linear SSAA resolve
and final presentation filtering; it is not RT64-style MSAA. Try **2x** first on
a discrete GPU, keep texture filtering at **Nearest** for the authored PSX look,
and return to 1x if a demanding scene misses full speed.

## Playing

1. Run `ApeEscapeRecomp.exe`. A launcher window opens.
Expand Down
5 changes: 3 additions & 2 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ behind TombaRecomp and MegaManX6Recomp.
interpolation, and more.
- **Controllers** — analog / digital / hybrid pad modes and full keyboard
rebinding (all 24 inputs, including the analog-stick directions).
- **Widescreen fixes.** The 16:9 / 21:9 path is back on Ape's stable projection
and the title-screen sky no longer tears. Widescreen remains experimental.
- **Widescreen remains experimental.** UI proportion, character projection,
and scene-culling regressions are being image-validated before this work is
promoted as a fix.

## 🕹️ New in v0.0.5 — controls fix (phantom camera rotation)

Expand Down
33 changes: 33 additions & 0 deletions game.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ strict = true
debug_port = 4480
window_title = "ApeEscapeRecomp"
controller = "dualshock"
# Ship the play-free AOT overlay cache beside the executable and keep runtime
# capture/compilation enabled as a fail-safe for any producer the cache misses.
overlay_cache = true
memcard_dir = "saves"
# HLE kernel-service tier + boot shell-skip (skip the BIOS boot animation and
# jump straight into the game). LLE stays linked as the fallback/oracle for any
Expand All @@ -36,6 +39,15 @@ auto_skip_fmv = true
# GL compositor perf fix). The launcher's Renderer setting still offers Software.
renderer = "opengl"

# Ship 2x SSAA with present antialiasing enabled. Aligned RTX/OpenGL testing
# found 2x and 4x stayed within the 59.94 Hz budget in the sampled attract
# scene, but that is not yet a full-playthrough guarantee. 3x/4x SSAA and
# bilinear texture filtering (which changes the authored PSX texture look)
# remain opt-in.
supersampling = 2
antialiasing = true
texture_filtering = "nearest"

# Widescreen ships OFF (authentic 4:3); the launcher's experimental Widescreen
# toggle / settings.toml opts into 16:9 native-wide at runtime.
aspect_ratio = "4:3"
Expand All @@ -53,13 +65,34 @@ gte_game_mode = true
# produces severe geometry wedges here, so do not opt Ape into that path.
native_wide = false

# Correct small textured screen-space quads/rectangles before the final wide
# presentation stretch. Large backdrop planes and projected/non-axis-aligned
# world geometry are excluded; repeating glyph/icon rows share one anchor.
auto_ui_squash = true

[widescreen.dome]
# The title sky is a finite 16x16 curved mesh. This is the exact JAL that
# projects its grid vertices in the title overlay (return address 0x80136614).
# Preserve only this producer's authored 4:3 projection before the final wide
# stretch, without touching Spike or any other attract-demo geometry.
call_sites = ["0x8013660C"]

[widescreen.cull]
# Ape's GTE render funnel uses 385x241 extent signatures. Widen only functions
# containing both the horizontal and vertical signature; isolated compares are
# left untouched.
auto_screen_x = true
screen_w_imms = ["0x181"]
screen_h_imms = ["0xF1"]
slti_sites = ["0x8004AB64"]

# Object-level screen bounds used after the shared vertex funnel. These exact
# guarded pairs were identified in the boot EXE; the hooks are identity at 4:3.
bias_sites = ["0x80059d28", "0x800699f4", "0x8006ae04", "0x8006d87c",
"0x8006de40", "0x8006f14c", "0x8006f538", "0x80084430"]
range_sites = ["0x80059d30", "0x800699fc", "0x8006ae0c", "0x8006d884",
"0x8006de44", "0x8006f150", "0x8006f540", "0x80084434"]

# Controller defaults. Ape Escape is a dual-analog title — the whole monkey-net /
# movement scheme is built around the DualShock's two analog sticks, so the game
# expects an analog-capable pad (id 0x73) to be present. Present a DualShock by
Expand Down
Binary file removed launcher_art/img/disc.png
Binary file not shown.
2 changes: 1 addition & 1 deletion psxrecomp-v4
Submodule psxrecomp-v4 updated 139 files
4 changes: 2 additions & 2 deletions tools/package_release.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ function Invoke-Native {

# Build: Release, debug tools OFF, launcher ON. PSX_STATIC_RUNTIME defaults ON
# for MinGW Release so the exe imports only system DLLs (self-contained).
Invoke-Native { cmake -S $Root -B $BuildPath -G Ninja -DCMAKE_BUILD_TYPE=Release -DPSX_DEBUG_TOOLS=OFF -DPSX_LAUNCHER=ON } "cmake configure"
Invoke-Native { cmake -S $Root -B $BuildPath -G Ninja -DCMAKE_BUILD_TYPE=Release -DPSX_DEBUG_TOOLS=OFF } "cmake configure"
Invoke-Native { cmake --build $BuildPath -j $env:NUMBER_OF_PROCESSORS } "cmake build"

if (Test-Path $StageRoot) { Remove-Item -Recurse -Force $StageRoot }
Expand All @@ -60,7 +60,7 @@ if (Test-Path (Join-Path $Root "RELEASE_NOTES.md")) { Copy-Item (Join-Path $Roo
# Launcher assets: this build ships the shared recomp-ui Dear ImGui launcher
# (RECOMP_LAUNCHER; see main.cpp + recomp-ui/recomp_ui.cmake), which loads from
# <exe>/assets/ (fonts + img TGAs) staged next to the exe by
# recomp_target_launcher_ui's POST_BUILD -- NOT the legacy RmlUi launcher.rml.
# recomp_target_launcher_ui's POST_BUILD.
$AssetsSrc = Join-Path $BuildPath "assets"
if (-not (Test-Path (Join-Path $AssetsSrc "img"))) {
throw "recomp-ui launcher assets missing at $AssetsSrc -- was the recomp-ui launcher built (recomp-ui junction present)?"
Expand Down