ENGINES: Add support for Ripper - #7839
Draft
alexbevi wants to merge 414 commits into
Draft
Conversation
References: - RIPPER.LE: RunTubeSwitchScene at 0x25e18 - RIPPER.LE: RunFrontEndActionMenu at 0x18b3a - RIPPER.LE: RunUnlockGatedSelectionMenu at 0x360ae - RIPPER.LE: ExecuteUnlockSelectionChoice at 0x364be Assisted-by: Codex:gpt-5
References: - RIPPER.LE: RunKaDialogueScene at 0x2aef5 Assisted-by: Codex:gpt-5
References: - RIPPER.LE: RunTubeSwitchScene at 0x25e18 - RIPPER.LE: RunKaDialogueScene at 0x2aef5 - RIPPER.LE: RunCainDialogueScene at 0x2c160 - RIPPER.LE: RunCrystalPiecePlacementPuzzleScene at 0x2710c - RIPPER.LE: RunRolodexSequencePuzzleScene at 0x280ae - RIPPER.LE: RunShockLeverPuzzleScene at 0x3affb Assisted-by: Codex:gpt-5
The powered switch loop must reuse one Smacker decoder because later frames depend on its delta-coded surface and palette. References: - RIPPER.LE: RunTubeSwitchScene at 0x25e18 - RIPPER.LE: retained-decoder seek path at 0x263ae Assisted-by: Codex:gpt-5
References: - RIPPER.LE: RunCombatEncounterScene at 0x31436 - RIPPER.LE: LoadCombatEncounterResourceSet at 0x34d6e - RIPPER.LE: LoadPresentationFrameRegionTable at 0x35615 - RIPPER.LE: LoadPresentationFrameAudioCueMap at 0x3574a Assisted-by: Codex:gpt-5
References: - RIPPER.LE: RunGcCshFourChoiceSequencePuzzleScene at 0x38871 - RIPPER.LE: DispatchSceneEntryAction at 0x36892 - RIPPER.LE: PreparePacketizedMediaPlaybackBranchSetup at 0x5b237 Assisted-by: Codex:gpt-5
Player depletion follows the Escape cleanup path and must not set the completion flag. References: - RIPPER.LE: RunCombatEncounterScene at 0x31436 Assisted-by: Codex:gpt-5
References: - RIPPER.LE: RunGcCshFourChoiceSequencePuzzleScene at 0x38871 Assisted-by: Codex:gpt-5
The cursor frame and palette must be reinstalled after puzzle media even when the requested cursor row is unchanged. References: - RIPPER.LE: RunGcCshFourChoiceSequencePuzzleScene at 0x3868b - RIPPER.LE: cursor reinstallation paths at 0x38986 through 0x389a2 and 0x38e98 through 0x38ea1 Assisted-by: Codex:gpt-5
References: - RIPPER.LE: RunGcCshFourChoiceSequencePuzzleScene at 0x38871 - RIPPER.LE: ServiceUiControlStateSelection at 0x4a912 Assisted-by: Codex:gpt-5
Save version 4 adds the toolbar mask. Older supported saves restore the original full mask. References: - RIPPER.LE: DispatchSceneEntryAction at 0x36892 - RIPPER.LE: PollInteractionAndResolveSelection at 0x13c8d Assisted-by: Codex:gpt-5
A scene action unlocks the new item and clears its consumed partner before opening the chooser. The toolbar opens the same chooser without mutating inventory. References: - RIPPER.LE: DispatchSceneEntryAction at 0x36892 - RIPPER.LE: RunUnlockGatedSelectionMenu at 0x360ae - RIPPER.LE: ExecuteUnlockSelectionChoice at 0x364be Assisted-by: Codex:gpt-5
References: - RIPPER.LE: RunUnlockGatedSelectionMenu at 0x360ae - RIPPER.LE: ExecuteUnlockSelectionChoice at 0x364be - RIPPER.LE: InitializeSharedPresentationTemplates at 0x1196f Assisted-by: Codex:gpt-5
References: - RIPPER.LE: DrawPromptChooserTemplateLabelCallback at 0x16d0f Assisted-by: Codex:gpt-5
References: - RIPPER.LE: RunTableGateLeverPuzzleScene at 0x3912a Assisted-by: Codex:gpt-5
References: - RIPPER.LE: RunClockPuzzleScene at 0x374c5 - RIPPER.LE: PlayClockSmackerOverlayAnimation at 0x38316 - RIPPER.LE: DispatchSceneEntryAction at 0x36892 Assisted-by: Codex:gpt-5
CLOCK_TMP.MCG is one custom bitmap, not a bitmap-set container. References: - RIPPER.LE: RunClockPuzzleScene at 0x374c5 - RIPPER.LE: DecodeCustomBitmapAsset at 0x53fdf Assisted-by: Codex:gpt-5
Assisted-by: Codex:gpt-5
References: - RIPPER.LE: DecodeCustomBitmapAsset at 0x53f60 Assisted-by: Codex:gpt-5
Assisted-by: Codex:gpt-5
Assisted-by: Codex:gpt-5
Assisted-by: Codex:gpt-5
Assisted-by: Codex:gpt-5
Assisted-by: Codex:gpt-5
The first registered overlapping control wins the hit test. References: - RIPPER.LE: FindUiControlStateAtPoint at 0x4aae8 Assisted-by: Codex:gpt-5
Save data retains the existing selected and first-visible fields. The model validates them before rebuilding layout. Assisted-by: Codex:gpt-5
The index accelerates exact lookup without changing directory order used by member sizing and prefix enumeration. References: - RIPPER.LE: OpenIndexedContainerEntryReadOnly at 0x55a4c - RIPPER.LE: LoadAssetLibraryDirectoryFromOpenHandle at 0x6ad80 Assisted-by: Codex:gpt-5
Assisted-by: Codex:gpt-5
References: - RIPPER.LE: CreateSceneRuntime at 0x12be7 Assisted-by: Codex:gpt-5
References: - RIPPER.LE: RunSceneCallbackCommandStream at 0x14080 - RIPPER.LE: DispatchSceneEntryAction at 0x36892 Assisted-by: Codex:gpt-5
Assisted-by: Codex:gpt-5.6-sol
The template byte previously used as a color is a row metric. The foreground is the active movie palette entry nearest pure white. References: - RIPPER.LE: ServiceMediaPresentationTextControl at 0x17014 - RIPPER.LE: FindNearestPaletteColorIndex at 0x56af1 - RIPPER.LE: normal glyph-template color byte at 0x94338 Assisted-by: Codex:gpt-5.6-sol
Only controlled AVI entries replace the replay buffer. WAV and direct type-1 presentations replay the preceding interaction scene. References: - RIPPER.LE: PollInteractionAndResolveSelection at 0x13fc7 - RIPPER.LE: ExecutePresentationEntry at 0x1754b - RIPPER.LE: process-wide replay buffer at 0x9b0e0 Assisted-by: Codex:gpt-5.6-sol
The menu teardown leaves a blank logical return page. Otherwise controlled intro media can restore the final RIP_OPEN.SMK frame. References: - RIPPER.LE: RunStartupFrontEndLoop at 0x10778 Assisted-by: Codex:gpt-5.6-sol
Assisted-by: Codex:gpt-5.6-sol
Assisted-by: Codex:gpt-5.6-sol
References: - RIPPER.LE: InitializeDefaultSettingsBlob at 0x1eea2 - RIPPER.LE: ResolveFrontEndActionIdFromInput at 0x1442d - RIPPER.LE: RunOptionsKeyCaptureLoop at 0x1eae7 - RIPPER.LE: PollKeyboardCommand at 0x4d364 Assisted-by: Codex:gpt-5.6-sol
MemoryReadStream releases owned buffers with free(), so reconstructed Smacker buffers must use a compatible allocator. References: - RIPPER.LE: RunPacketizedMediaPlaybackCore at 0x5b592 Assisted-by: Codex:gpt-5.6-sol
References: - RIPPER.LE: RunPacketizedMediaPlaybackCore at 0x5b592 Assisted-by: Codex:gpt-5.6-sol
Parsing is transactional: caller-owned outputs remain unchanged until every field and signed stream bound has been validated. References: - RIPPER.LE: DecodeCustomBitmapAsset at 0x53f60 Assisted-by: Codex:gpt-5.6-sol
Assisted-by: Codex:gpt-5.6-sol
Assisted-by: Codex:gpt-5.6-sol
Assisted-by: Codex:gpt-5.6-sol
Assisted-by: Codex:gpt-5.6-sol
Assisted-by: Codex:gpt-5.6-sol
The Ka book-code and KI skull-maze results include failure states outside the standard puzzle contract, so those classes remain independent. Assisted-by: Codex:gpt-5.6-sol
Assisted-by: Codex:gpt-5.6-sol
Assisted-by: Codex:gpt-5.6-sol
Intermediate date and navigation flags and KI skull-maze completion remain outside the standard puzzle completion contract. Assisted-by: Codex:gpt-5.6-sol
Assisted-by: Codex:gpt-5.6-sol
Assisted-by: Codex:gpt-5.6-sol
The prebuffer command requires every Smacker branch to be reconstructed before the external PCM timeline starts. References: - RIPPER.LE: RunPacketizedMediaPlaybackCore at 0x5b592 Assisted-by: Codex:gpt-5.6-sol
Remove RIPPER-ARCHITECTURE.md from the branch while retaining it as a checkout-local analysis document. The existing .git/info/exclude pattern keeps the local copy out of future status and add operations. Assisted-by: Codex:gpt-5.6-sol
Remove AGENTS.md from the branch while retaining it as checkout-local guidance. The existing .git/info/exclude entry keeps the local copy out of future status and add operations. Assisted-by: Codex:gpt-5.6-sol
RIPER.BAT invokes PLAYER.EXE with SCENES.AVI. It is not an alternate RIPPER.EXE mode, and the demo did not ship this route. Assisted-by: Codex:gpt-5.6-sol
Assisted-by: Codex:gpt-5.6-sol
Assisted-by: Codex:gpt-5.6-sol
Assisted-by: Codex:gpt-5.6-sol
alexbevi
marked this pull request as draft
August 25, 2026 22:00
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.
This PR adds an initial, Ghidra-backed implementation of the DOS game Ripper.
As with the previous re-implementation of Harvester, this PR uses Ghidra and Codex (notes available in this gist).
AI-GUIDELINES.mdwas followed, and to make validation easier, commit messages include the binary disassembly notes and function addresses as references.The original work was done against the v1.0 game, but I eventually introduced v1.05 functionality such as interaction subtitles. I documented the IAVF format in greater detail in this blog post, and will look to add more content over time.
Shared code changes
Only two shared runtime areas are changed, so I wanted to call them out directly.
IMAGEIFF decoder (8d706d7dd82,a42c63d6c5f)4a93237885f)ListWidget::scrollTo()clamps the logical row before calculating its fluid-scroll position. This prevents a remembered save-chooser position from clipping or moving the first entries when every slot fits onscreen.6d6f5d76fef)test/module.mkincludes the Ripper test suites and static engine library when Ripper is configured as a static plugin.No common media, audio, event, savefile or serializer code is modified.
Run with
./scummvm -d 3 --debugflags=general,resources,scripts,scene,input,audio,cursor,video,dialogue,wac,saveload,milestones,puzzles,cyber,combat ripperfor full debug output.Screenshots