Skip to content
Closed
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
593 changes: 130 additions & 463 deletions CMakeLists.txt

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Before submitting a change:

- Run the relevant tests and review both the working diff and staged paths.
- Keep experimental visual features optional.
- Update [STATUS.md](STATUS.md) when behavior, verified coverage, or a known
- Update [STATUS.md](docs/STATUS.md) when behavior, verified coverage, or a known
limitation changes. Keep it focused on the current build.

For bug reports, include the level, steps to reproduce, render scale/aspect,
Expand Down
2 changes: 2 additions & 0 deletions PSXRECOMP_OVERLAY_FILES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ runtime/include/gpu_sw_renderer.h
+runtime/include/iso_overlay.h
runtime/include/mod_memory.h
runtime/include/psx_cyc.h
+runtime/include/save_point.h
runtime/include/overlay_dispatch_preamble.c.inc
runtime/include/ws_aspect_cone_math.h
runtime/src/boot_state.c
Expand All @@ -40,6 +41,7 @@ runtime/src/gpu_gl_renderer.c
+runtime/src/gpu_gl_temporal.c.inc
runtime/src/gpu_render.c
runtime/src/gte.cpp
runtime/src/interrupts.c
runtime/src/iso_reader_c.cpp
runtime/src/main.cpp
runtime/src/memory.c
Expand Down
13 changes: 9 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,18 @@ disc revision; the redistributable OpenBIOS backend is used for booting.
the screen too, movies stay at 4:3, and the HUD retains its proportions. A
HUD size setting shrinks it toward the screen edges.
- Optional geometry and perspective-texture correction.
- Optional gap filling, a depth-sorted world, and experimental ambient
occlusion on top of geometry correction.
- Optional 60 FPS gameplay and in-between frames.
- Keyboard/controller input and optional modern WASD/mouse controls.
- Optional smooth mouse turning between the game's 256 turn steps.
- Experimental vertical mouse look and weapon aim.
- In-game settings for controls, display, fullscreen, VSync, volume, and mute.
- Diagnostic views and a screen recorder for reports of a fault in the picture.
- Memory-card saves and twelve save-state slots.
- Windows launcher with disc-image browsing, automatic copy/CUE setup,
full-disc SHA-256 verification, the game's settings, and game launch.
full-disc SHA-256 verification, the game's settings with a hint for each,
and game launch.
- Optional French, German, and Japanese game content from an additional disc
image you own; the supported USA disc remains required.
- Optional intro skipping and a key to skip a logo or movie.
Expand Down Expand Up @@ -56,7 +61,7 @@ Place these files from your own supported disc in `input/`:
- `SLUS_002.24`
- `Disruptor (USA).cue` and the `.bin` track it references

Check the required hashes and disc format in [DISC.md](DISC.md). Then run from
Check the required hashes and disc format in [DISC.md](docs/DISC.md). Then run from
an x64 developer PowerShell:

```powershell
Expand Down Expand Up @@ -100,8 +105,8 @@ retest and save-state restart check passed after fixing an ultrawide rendering
buffer overflow. Full campaign and release validation remain incomplete; minor
geometry and texture artifacts can remain.

- [Current status and known limits](STATUS.md)
- [Current status and known limits](docs/STATUS.md)
- [Build details](docs/BUILD.md)
- [Supported disc revision](DISC.md)
- [Supported disc revision](docs/DISC.md)
- [Contributing](CONTRIBUTING.md)
- [Third-party notices](THIRD_PARTY_NOTICES.md)
2 changes: 1 addition & 1 deletion build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ if [ -n "$WITHOUT_GAME" ]; then
printf '%s\n' $OBJECTS $TESTS | xargs -n 100 ninja -C "$BUILD"
ctest --test-dir "$BUILD" --output-on-failure --no-tests=error -LE retail
# The retail contracts still check the sources when the image is not asked for.
for contract in tests/test_*_contract.py; do
for contract in tests/contracts/test_*_contract.py; do
python3 -B "$contract"
done
echo "Built and tested without the game: the runtime was compiled and not linked."
Expand Down
56 changes: 56 additions & 0 deletions cmake/DisruptorTests.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# disruptor_contract(<name> [RETAIL])
#
# Registers tests/contracts/test_<name>_contract.py as the test disruptor_<name>_contract.
# RETAIL: the contract needs the retail image or the translated code. It is passed
# --require-artifacts and labelled so that `ctest -LE retail` leaves it out.
function(disruptor_contract name)
cmake_parse_arguments(PARSE_ARGV 1 CONTRACT "RETAIL" "" "")
if(CONTRACT_UNPARSED_ARGUMENTS)
message(FATAL_ERROR "disruptor_contract(${name}): unknown arguments ${CONTRACT_UNPARSED_ARGUMENTS}")
endif()
set(script "${PROJECT_SOURCE_DIR}/tests/contracts/test_${name}_contract.py")
if(NOT EXISTS "${script}")
message(FATAL_ERROR "disruptor_contract(${name}): ${script} does not exist")
endif()
set(arguments "")
if(CONTRACT_RETAIL)
set(arguments --require-artifacts)
endif()
add_test(NAME disruptor_${name}_contract
COMMAND "${Python3_EXECUTABLE}" -B "${script}" ${arguments})
if(CONTRACT_RETAIL)
set_tests_properties(disruptor_${name}_contract PROPERTIES LABELS retail)
endif()
endfunction()

# disruptor_unit_test(<test> <source> [TARGET <target>] [RUNTIME_HEADERS]
# [SOURCES <file>...] [INCLUDES <folder>...] [DEFINITIONS <definition>...]
# [ARGUMENTS <argument>...])
#
# Builds one C++20 executable from <source>, a path from the project's root, and registers
# it as the test <test>. The executable is named after the test, disruptor_far_rendering
# giving disruptor-far-rendering-test, unless TARGET names it.
# RUNTIME_HEADERS puts the framework's runtime headers on its include path.
function(disruptor_unit_test test source)
cmake_parse_arguments(PARSE_ARGV 2 UNIT "RUNTIME_HEADERS" "TARGET"
"SOURCES;INCLUDES;DEFINITIONS;ARGUMENTS")
if(UNIT_UNPARSED_ARGUMENTS)
message(FATAL_ERROR "disruptor_unit_test(${test}): unknown arguments ${UNIT_UNPARSED_ARGUMENTS}")
endif()
set(target "${UNIT_TARGET}")
if(NOT target)
string(REPLACE "_" "-" target "${test}-test")
endif()
add_executable(${target} "${PROJECT_SOURCE_DIR}/${source}" ${UNIT_SOURCES})
if(UNIT_RUNTIME_HEADERS)
target_include_directories(${target} PRIVATE "${PSXRECOMP_ROOT}/runtime/include")
endif()
if(UNIT_INCLUDES)
target_include_directories(${target} PRIVATE ${UNIT_INCLUDES})
endif()
if(UNIT_DEFINITIONS)
target_compile_definitions(${target} PRIVATE ${UNIT_DEFINITIONS})
endif()
target_compile_features(${target} PRIVATE cxx_std_20)
add_test(NAME ${test} COMMAND ${target} ${UNIT_ARGUMENTS})
endfunction()
2 changes: 1 addition & 1 deletion tools/stage_launcher.cmake → cmake/stage_launcher.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
foreach(pair IN ITEMS "game.toml|game.toml" "mouse-aim.ini|mouse-aim.ini"
"docs/PLAYING.md|GETTING_STARTED.md"
"release/windows/Play Disruptor.cmd|Play Disruptor.cmd"
"keybinds-modern.ini|keybinds.ini"
"config/keybinds-modern.ini|keybinds.ini"
"release/windows/settings.toml|settings.toml")
string(REPLACE "|" ";" paths "${pair}")
list(GET paths 0 source)
Expand Down
File renamed without changes.
File renamed without changes.
23 changes: 22 additions & 1 deletion docs/BUILD.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
## Requirements

- The verified Disruptor USA executable and BIN/CUE files in `input/`; see
[DISC.md](../DISC.md).
[DISC.md](DISC.md).
- Git, Python 3, CMake 3.20+, and a C++20 toolchain.
- Windows x64: Visual Studio with **Desktop development with C++**, or
MSYS2 MinGW-w64. Ninja is recommended.
Expand Down Expand Up @@ -129,6 +129,27 @@ files are listed in `PSXRECOMP_OVERLAY_FILES.txt`. Runtime preferences live in
`settings.toml` beside the executable; game files, generated code, and build
directories are ignored by Git.

## Layout

| Folder | Holds |
| --- | --- |
| `src/game/` | The game's own module by area: `input`, `render`, `frame`, `language`, `session`, `settings`, `ui` |
| `src/launcher/` | The Windows launcher |
| `psxrecomp-overlay/` | The framework files this project replaces or adds |
| `tests/unit/` | Unit tests, one executable each |
| `tests/contracts/` | Source contracts, run by Python |
| `tests/support/` | Stubs and fakes the unit tests build against |
| `cmake/` | Build helpers: test registration, launcher staging |
| `config/` | Key presets |
| `tools/` | Regeneration, the overlay, packaging, capsule replay |

`game.toml`, `game-widescreen.toml` and `mouse-aim.ini` stay at the root: the
game is started from there and reads them by those names.

A unit test is registered in `CMakeLists.txt` with
`disruptor_unit_test(<test> tests/unit/<file>)` and a contract with
`disruptor_contract(<name>)` for `tests/contracts/test_<name>_contract.py`.

## Replay capsules

Ctrl+F12 in the game starts a recording and Ctrl+F12 again ends it. The game
Expand Down
File renamed without changes.
22 changes: 18 additions & 4 deletions docs/PLAYING.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,10 @@ and share feedback.
6. At the game menu, use the arrow keys and **Enter** to select **New Game**,
or choose **Practice Mode** to try a training mission.

The launcher's **Display**, **Enhancements**, **Controls** and **Audio** tabs
hold the settings of the in-game menu. A change is saved to `settings.toml`
at once and applies the next time the game starts. **Original** and
The launcher's **Display**, **Enhancements**, **Controls**, **Audio** and
**Experimental** tabs hold the settings of the in-game menu. A long page
scrolls, and a row shows a hint under the pointer. A change is saved to
`settings.toml` at once and applies the next time the game starts. **Original** and
**Enhanced** set a group of them in one step, and **Reset settings** returns
them to those of a new installation. The tabs are locked while the game runs.
If the game stops with an error, the launcher shows the end of `startup.log`.
Expand Down Expand Up @@ -71,7 +72,10 @@ folder; these backups can be removed manually once the repaired copy works.

Modern mouse/keyboard controls, geometry correction, and perspective textures
are enabled initially. Vertical mouse look is experimental and starts off;
enable it in **Settings → Controls** if desired.
enable it in **Settings → Controls** if desired. A setting shows its
description under the pointer, the same one as in the launcher. A setting that
needs another one stays greyed until that one is on. In-between frames that
are on can still be switched off.

**Settings → Enhancements** offers 1x–8x resolution, widescreen options,
HUD size for widescreen, and 60 FPS gameplay and in-between frames. Both
Expand All @@ -80,6 +84,16 @@ The **Shadows** setting offers Vanilla and Improved shapes when geometry
correction is enabled. HUD size ranges from 50% to 100% in widescreen and
leaves the weapon size unchanged.

With geometry correction, **Gap filling** closes hairline gaps between
polygons and starts on. **Depth-sorted world** draws the world by depth where
the game's own order puts a far polygon over a near one; it starts off.
**Settings → Experimental** has ambient occlusion, which shades corners and
the floor under things and starts off. **Smooth mouse turning** in
**Settings → Controls** turns the picture between the game's 256 turn steps
while the mouse is captured; it starts off too. **Settings → Debug** has
diagnostic views and a two-second screen recorder for a report of a fault in
the picture.

**Skip the logos and the title movie** in Enhancements skips the boot intro
automatically. It starts off; the other movies still play normally. Escape
can skip the logo or movie currently on screen when the settings menu is closed.
Expand Down
6 changes: 3 additions & 3 deletions STATUS.md → docs/STATUS.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ and public-release validation are incomplete.
| Gameplay | Boot, menus, FMVs, audio, and the first mission have been exercised on Windows. |
| Rendering | OpenGL supports 1x–8x resolution, widescreen, geometry correction, and perspective textures. Minor edge gaps and localized texture wobble can remain. |
| Controls | Modern keyboard/mouse controls are available. Vertical look and weapon aim remain experimental. |
| Settings | Controls, Enhancements, Cheats, and System tabs; supported preferences persist between runs. |
| Interpolation and diagnostics | In-between frames are experimental and off until switched on in Settings. The Diagnostics tab and experimental debug controls are removed. |
| Settings | Controls, Enhancements, Experimental, Language, System, Debug, and Cheats tabs; supported preferences persist between runs. |
| Interpolation and diagnostics | In-between frames are off until switched on in Settings. The Debug tab has diagnostic views and a screen recorder. |
| Ultrawide corruption | Fixed primitive-buffer overflow. The user's 8x / 32:9 training retest stayed correct through 8,934 frames and closed normally. |
| Save states | Save states require a matching build and language. The alpha.3 code-generation changes make alpha.1 and alpha.2 states incompatible; use memory-card saves for progress across releases. |
| Automated checks | Windows Release build, code-generation audit, and all 59 root CTests passed. |
Expand All @@ -35,5 +35,5 @@ and public-release validation are incomplete.
individually exercised live.
- Live volume adjustment and its relaunch persistence need user validation.

See [build details](docs/BUILD.md) and [disc requirements](DISC.md) before
See [build details](BUILD.md) and [disc requirements](DISC.md) before
building or reporting a problem.
Binary file modified docs/images/launcher.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion input/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Copy these files from your own **Disruptor (USA, SLUS-00224)** disc here:
- `SLUS_002.24`
- `Disruptor (USA).cue` and the `.bin` track named in its `FILE` entry

Check the hashes and MODE2/2352 format in [DISC.md](../DISC.md). Build and run
Check the hashes and MODE2/2352 format in [DISC.md](../docs/DISC.md). Build and run
instructions are in [docs/BUILD.md](../docs/BUILD.md).

This directory's game files and the generated `SLUS_002.24.code` analysis image
Expand Down
26 changes: 26 additions & 0 deletions psxrecomp-overlay/runtime/include/save_point.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/* When an interrupt check polls for a waiting save or load of a state. */
#ifndef PSXRECOMP_SAVE_POINT_H
#define PSXRECOMP_SAVE_POINT_H

#ifdef __cplusplus
extern "C" {
#endif

int savestate_pending(void);

/* 1 when this check must poll. A periodic poll that meets a request at a check with no address of its own is owed to the next that has one. */
static inline int psx_save_poll_due(int periodic, int save_point, int *owed) {
if (!save_point) {
if (periodic) *owed = savestate_pending();
return 0;
}
if (!periodic && !*owed) return 0;
*owed = 0;
return 1;
}

#ifdef __cplusplus
}
#endif

#endif
Loading
Loading