Repository navigation
Dual present filters: a set for 2D scenes and one for 3D (dw2003recomp #122) - #111
Merged
Merged
Conversation
…_scene() A game may opt in to one present-filter set for its 2D scenes and one for its 3D scenes (dw2003recomp #122). This is the contract part alone, so the launcher and the game can start from it: game.json's video.scenes (the labels and the 2D set's default filter) in the schema and the generator, which writes PSXSTACK_GAME_SCENES and the labels and filter as macros; the adapter's new probe game_state_scene() (PORT_SCENE_3D / PORT_SCENE_2D) with its weak default, 3D; the settings' video.scene_2d in settings.c's key list; the first game's copy of its scenes block. Additive, so PSXSTACK_API stays 1. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e menu's getter For a game with video.scenes (dw2003recomp #122): the settings read video.scene_2d member by member over its default (game.json's 2d.filter with the default crt values, else a copy of the 3D set) and --print-settings writes it; --filter sets both sets and the new --filter-2d the 2D set alone. video.c holds both sets and reads game_state_scene() once per vsync, before the present, only when the description declares scenes; a change is logged and picks the other slot. render_gpu_present.c keeps two slots built (pipelines per kind, so equal kinds share them; smooth's edges texture when either slot is smooth): a scene change binds another pipeline and creates or frees nothing. Live apply builds both again. port_video_scene() is the scene in use, for the in-game menu. A game without scenes has one set: f[1] copies f[0], the probe is never called, scene_2d is an unknown key, the log line is the old "renderer: gpu: filter NAME". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
docs/RUNTIME.md (video.scene_2d, --filter-2d, the log lines), docs/PORT.md "Rendering" (two slots, both built), docs/DECISIONS.md (the game names its scene rather than the runtime detecting it, and both pipelines stay built so a switch builds nothing), README.md's feature line. The scene change's log line gets ", vsync N", so a test can tell where a scene began. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A game can now opt in to two present-filter sets, one for its 2D scenes and one for its 3D scenes, and the runtime switches between them as the game moves between scenes (dw2003recomp #122). A game that doesn't opt in keeps one set and sees no change. This PR is the contract and the runtime. The launcher and the in-game menu are a separate PR stacked on this one.
What
video.scenes(2d.label,2d.filter,3d.label), in the schema and intools/game_gen.py.PSXSTACK_GAME_SCENES,PSXSTACK_GAME_SCENE_2D_LABEL,PSXSTACK_GAME_SCENE_3D_LABELandPSXSTACK_GAME_SCENE_2D_FILTER.game_state_scene()returnsPORT_SCENE_3D(0) orPORT_SCENE_2D(1). Its weak default is 3D.examples/dw2003.game.jsonhas the scenes block.PSXSTACK_APIstays 1.video.filterandvideo.crtare now the 3D set.video.scene_2d { filter, crt }is the 2D set. It is read member by member over its default: game.json's2d.filterwith the default crt values, or a copy of the 3D set when game.json names no 2D filter. A bad member exits 64 and names the key.scene_2das unknown and ignores it.--print-settingswritesscene_2dfor a game that opts in, and its output loads back to the same output.--filtersets both sets. The new--filter-2d NAME[:KEY=V,...]sets the 2D set alone, on top of--filter. A game without scenes refuses--filter-2d(exit 64).video.cholds both sets and readsgame_state_scene()once per vsync, before the present, only when the description declares scenes. A game without scenes never calls the probe.renderer: gpu: scene 2d (filter smooth), vsync N.port_video_apply()/port_live_apply()path takes both sets.render_gpu_present.ckeeps two slots, both built at start and at live apply.int32_t port_video_scene(void)inport_harness.hreturns the scene in use, for the in-game menu.Why
DW2003 wants smooth on the field's pixel art and something else in battles. The runtime can't detect the scene from what is drawn: the game draws rotated 2D sprites with the GTE, and counting polygons flickers. So the game names its scene through a pull probe, the same way it reports
game_state_stage. A switch must not stall a frame, so both pipelines stay built. The scene is read fresh each vsync, so replays, checkpoint hashes and save states don't hold it.Gates that ran
python3 tests/game_gen_test.py, with and without jsonschema (with and without scenes, and the bad shapes)tests/hello_test.py,--menu,--menu --gputests/shim_test.pytests/tasks_test.py --sanitizepsyq/check.sh --compilepython3 -m py_compileon the Python I touched-DPSXSTACK_DIR= this branch, with the disc):tests/port/settings.pypass andtests/port/render_filters.pypass.game_state_scene()(3D while the tier-1 overlay is FIGHTSTG),tests/port/run.pypasses (first_battle_save, new_game).--gpu-screenshot@960x720 readbacks:--filter crt --filter-2d smoothgives the same pictures.tests/port/settings.pyfails exactly 2 exact-dict checks, because--print-settingsnow writesscene_2d. The round trip passes. Updating those expectations is the game PR's job (worker C).These did not run here: the Windows cross-build and Wine (CI covers them), and a windowed present on a real display. The window path uses the same draw call as the readback.
Owner play-test
video.filter: battles should keep that filter and the field should show smooth.--filter crtalone (both sets crt), then add--filter-2d sharp.🤖 Generated with Claude Code