Skip to content

Jedi Knight cutscenes on the Tab5 - #3

Merged
finger563 merged 4 commits into
mainfrom
feat/jk-movies
Oct 15, 2026
Merged

finger563 merged 4 commits into
mainfrom
feat/jk-movies

Conversation

@finger563

Copy link
Copy Markdown
Contributor

Summary

Jedi Knight's full-motion cutscenes now play on the Tab5: the intro and the story movies between levels, with their audio, at the movies' full 15 fps. Start (Esc) skips a movie. Until now the ESP32 port skipped them.

All of the changes are in the OpenJKDF2 fork (esp32p4 branch, edc4b33..c3a5816); this PR moves the submodule pointer and updates the README.

Playback

  • jkCutscene.c uses OpenJKDF2's software cutscene path (JKCUTSCENE_SOFT, the same path the SDL and homebrew ports use) on TARGET_ESP32. It draws the 8-bit frames through the menu buffer the port already presents.
  • Skipped frames are still decoded. When decoding falls behind, the original code turned video decoding off for non-keyframes, but Smacker frames are deltas on the previous frame, so the picture stayed corrupted ("sparkly" patches) until the next keyframe. Now only the presentation of a skipped frame is skipped.

Opening a movie: ~11 s → ~1 s

  • Huffman tree nodes come from 8192-node chunks. Building a movie's trees used about 300k callocs from PSRAM, which took 9.8 s; chunked allocation takes 0.9 s.
  • Frame offsets are computed in one pass. Disk mode used to seek once per frame (3,446 seeks for the intro); it now sums the frame sizes after a single seek (~1.4 s saved).

Decode speed: full frame rate in the heavy scenes

  • The 16-bit trees are decoded through multi-level lookup tables (12-bit root, 3-bit subtables) built when the file opens. This replaces a recursive walk one bit at a time down ~300k nodes in PSRAM.
  • The 8-bit (audio) trees walk iteratively on peeked bits.
  • The trees' node pools are freed once the tables exist, so memory use drops too: 1.5 MB of tables for the intro vs 2.4 MB of nodes.
  • In the heaviest scenes, smk_next took ~53 ms of the 66 ms frame budget.
  • Host decode of the intro went from 1.97 s to 0.72 s.

Audio

  • Gapless queueing. stdSound_BufferQueueAfterAnother on the ESP32 mixer used to start each buffer as soon as it was filled, so consecutive buffers overlapped or left gaps. Queued buffers now form a stream the mixer plays back to back, continuing mid-chunk.
  • The audio queue is drained every pass. The cutscene moved at most one decoded audio packet per engine loop into the sound buffers, so audio backed up whenever decoding was slow; it now drains the queue.
  • Result: 0 underruns over 90 s, down from up to ~10 per 5 s.

Testing

  • Decoder equivalence: a host harness hashes every frame's video, palette and audio from the modified libsmacker and the original. They are identical for all 25 JK movies, and ASan/UBSan runs are clean.
  • On the Tab5: the intro (01-02a.smk, 640x300, 3,446 frames) plays to the end. Telemetry shows 0 stream underruns, 15 fps decoded throughout, and the display presenting 20–43 fps. Reviewed by eye and ear on hardware.
  • Cutscenes between levels play through the same path but haven't been tried on hardware yet.

🤖 Generated with Claude Code

finger563 and others added 4 commits October 15, 2026 00:33
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…KDF2 f53922a)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…F2 c3a5816)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

ESP-IDF Size Report for 'Tab5 Emu'

Metric Base PR Delta
FLASH 0 bytes (0.00%) 0 bytes (0.00%) 0 bytes (0.00%)
DRAM 266,374 bytes (60.36%) 266,374 bytes (60.36%) 0 bytes (0.00%)
IRAM 0 bytes 0 bytes 0 bytes
RAM (DRAM+IRAM) 266,374 bytes 266,374 bytes 0 bytes (0.00%)

FLASH uses app .bin size or json2 flash sum. RAM sums DRAM+IRAM via idf_size. Percentages shown when totals are available.
DRAM/IRAM usage does not include memory used by the heap allocator at runtime.
This report was generated by esp-idf-size-delta.

@finger563
finger563 merged commit b2312bb into main Oct 15, 2026
1 check passed
@finger563
finger563 deleted the feat/jk-movies branch October 15, 2026 20:24
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.

1 participant