Skip to content

Add STEINS;GATE 0 (Steam) support - #564

Closed
owenisas wants to merge 5 commits into
CommitteeOfZero:masterfrom
owenisas:sg0-support
Closed

owenisas wants to merge 5 commits into
CommitteeOfZero:masterfrom
owenisas:sg0-support

Conversation

@owenisas

Copy link
Copy Markdown

Adds support for STEINS;GATE 0 (Steam) as a new sg0 profile, plus a few engine fixes it needed. Opened as a draft: it is large, and I am happy to split it (for example the Bink 2 port on its own) if that is easier to review.

Commits

  1. Build the Bink 2 decoder into the FFmpeg overlay port. SG0 Steam ships its movies as Bink 2. The overlay port builds FFmpeg 7.1.2 with the binkvideo2 decoder from SharpEmu's FFmpeg fork (sharpemu/ffmpeg-core@3b502d4, LGPL-2.1-or-later). It also normalises the alpha flag to a boolean: the raw value (0x100000) made the decoder walk past the fourth plane and crash on alpha movies.
  2. Serialize DDS texture loads. The DDS decoder keeps file-global state while spritesheets load concurrently, so loads could interleave.
  3. Allow backlog entries without glyphs. AddMessage used Glyphs.back() on the previous entry. SG0 adds empty lines through SetRevMes, which crashed intermittently.
  4. Play full-range and alpha Bink 2 frames. Bink 2 decodes to full-range YUV, and to YUVA420P for alpha movies. The video shader expects limited range, and alpha in the bottom half of the frame. As a result, movies showed crushed blacks and clipped whites, and alpha overlays did not show at all. Frames are now repacked on upload; there are no shader changes.
  5. Add STEINS;GATE 0 (Steam) support.
    • Instruction set: an SG0 instruction set, CC's table corrected against SG0's scripts. All 178 scripts decode without desyncs; operand layouts agree with sc3ntist.
    • Profile:
      • mounts, movie order, the font atlas with per-glyph metrics, and the charset;
      • the save layout, with the script message table and CG album;
      • TIPS and key bindings, the bindings taken from the game's own help page.
    • Phone (PhoneSG0): the triggers that select the routes, and RINE threads with replies.
    • Screens:
      • save, load and quick load;
      • system message boxes;
      • the system menu, backlog, TIPS, config, help and title menu;
      • the EXTRA library (CG viewer, sound player, movies) and the clear list.
    • Engine changes, all scoped to SG0:
      • SG0 rendering paths and cut-ins (SetCutin);
      • movies on priorities above the scene layers;
      • the looping title movie;
      • the title menu ignoring input while another screen is focused.

Testing

On macOS arm64 with the Steam version:

  • Routes: all six endings were reached by force-skip playthroughs with the phone decisions that select them: Promised Rinascimento, Twin Automata, Recursive Mother Goose, Gehenna's Stigma, Vega and Altair, and Milky-way Crossing on a second playthrough.
  • No hangs or crashes after the backlog fix.
  • Movies: frames match the source decode in colour range, and the alpha overlays (IMV005-007) show.
  • CGs: they match the source images.
  • Not covered: other platforms or renderers; audio was not compared by ear.

Known gaps

  • No name box, and no AUTO/SKIP icons.
  • The PC build ships no system sound effects, so menus are silent; the original most likely is too.
  • IMV006's first frame uses a frame flag the decoder does not handle, so each loop starts one frame late.

STEINS;GATE 0 (Steam) ships its movies as Bink 2 (.bk2). The overlay port
builds FFmpeg 7.1.2 with the binkvideo2 decoder from SharpEmu's FFmpeg fork
(github.com/sharpemu/ffmpeg-core at 3b502d4, LGPL-2.1-or-later), plus a fix
that normalises the alpha flag to a boolean: the raw flag value (0x100000)
made the decoder walk past the fourth plane and crash on alpha movies.
The DDS decoder keeps its state in file-global variables while spritesheets
are loaded concurrently, so two loads could interleave and corrupt each
other.
AddMessage placed the new entry under the previous one using
Glyphs.back(), which is undefined for an entry with no text. STEINS;GATE 0
adds such lines with SetRevMes and crashed intermittently (SIGBUS) in
SG0_01_04. Use the entry's bounds when it has no glyphs.
Bink 2 movies decode to full-range YUV (AVCOL_RANGE_JPEG) and, with an
alpha plane, to YUVA420P. The video shader converts limited-range YUV and
reads alpha from the bottom half of the frame, so full-range movies showed
crushed blacks and clipped whites and alpha movies did not display at all.
Repack such frames on upload: scale full-range values to video range and
lay the alpha plane out as luma below the picture.
Adds the sg0 profile and an SG0 instruction set: CC's opcode table with
the slots corrected against SG0's scripts (all 178 scripts decode without
desyncs), plus the game-specific instructions and UI the game needs to be
played through.

- Profile: Steam USRDIR mounts, Bink 2 movie order, the 64x125 font atlas
  (font_a/font_b stacked) with per-glyph advances and bearings, CCLCC
  charset and save layout with SG0's script message table and CG album,
  TIPS through the CCLCC tips system, keyboard bindings from the game's own
  help page.
- Phone (PhoneSG0): the slide, sessions, call/power-off/RINE triggers that
  decide the routes, and RINE threads with reply menus run as branch
  threads.
- Screens: save/load/quick load, system message boxes, the system menu
  ring, backlog, TIPS, config, help, title menu, the EXTRA library
  (CG viewer, sound player, movie list) and the clear list.
- Engine: SG0 paths for rendering, capture, save checks and ClickOnJump;
  cut-ins (SetCutin); movies on priorities above the scene layers; the
  title movie keeps looping while the title is shown; the title menu
  ignores input while another screen has focus.

Tested on macOS (arm64) with the Steam version: all six endings are
reached with the phone decisions that select them, and the menus and
EXTRA screens work.
@owenisas
owenisas marked this pull request as ready for review October 23, 2026 04:43
Copilot AI balanced review requested due to automatic review settings October 23, 2026 04:43

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.

@Gunoshozo

Copy link
Copy Markdown
Contributor

Nobody gonna read that vibe slop buddy

@Gunoshozo Gunoshozo closed this Oct 23, 2026
@owenisas

Copy link
Copy Markdown
Author

Fair enough, that was way too much to review in one go. I've split it up: #565 to #568 are small standalone fixes, and #569 is the first STEINS;GATE 0 step (startup through the title into the story text). I'll open the rest one at a time after that's in. Thanks for the heads-up.

@Emberind

Copy link
Copy Markdown
Member

You misunderstand. We don't accept vibe-coded PRs

@owenisas
owenisas deleted the sg0-support branch October 23, 2026 23:05
@owenisas

Copy link
Copy Markdown
Author

You misunderstand. We don't accept vibe-coded PRs

Ok, got it. Although it's tested and played, but the agent probably didn't consider human maintainablilty and edge cases. Thanks for letting me know though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants