Skip to content

v3.4.0

Latest

Choose a tag to compare

@github-actions github-actions released this 20 Aug 02:56
0d503bf

Virtual Jaguar v3.4.0 — Peripherals, texture dump, BIOS selection

The peripheral release. Every controller the Jaguar ever had — plus the one
that let you phone your opponent — now works, alongside a texture-dump
pipeline for HD pack authors and user-selectable boot ROMs.

Highlights

Ultra Vortek netplay, over the emulated Jaguar Voice Modem (#481)

The JVM was Atari's voice-and-data modem, and Ultra Vortek was the only
retail title that spoke to it. Both sides of that conversation now work:
the modem's command protocol is emulated on JERRY's UART, and the "phone
call" is carried over the existing netlink transport (TCP or RetroArch
netplay).

Type 911 on the numpad at the Ultra Vortek title screen, one player
dials any number, the other answers.

The protocol was reverse-engineered from the retail ROM rather than
guessed: a custom Phylon command set (not AT), 16-bit words console→modem,
3-byte replies back, and a mutual DTMF probe as the line-quality check. The
full decode is in docs/voice-modem.md.

Verified on two real iOS devices, not only headlessly.

Network link setup that explains itself (#502)

Linking two consoles used to mean typing an IP address — which libretro
core options cannot do. They are strictly enumerated: the frontend stores a
value index, and no core on any platform can present a text field. The
only routes were a .local preset, a file, or localhost, and on iOS those
were the only options at all.

So the link now finds its own peers:

  • Automatic mode, the new default: if a frontend netplay session is
    running, the link rides it with nothing to configure. That path already
    worked and nothing said so — it was buried in a blurb on the TCP client
    option, findable only once you had already committed to typing an address.
  • LAN discovery — hosts beacon over UDP and appear in the host picker by
    name. Chosen over Bonjour because RetroArch's iOS/tvOS property lists
    enumerate only their own service types, so a core advertising its own is
    blocked, while the iOS entitlements do permit broadcast. UDP is not the
    fallback here; it is the only mechanism that works on the platform this
    was reported from.
  • On-screen narration — what mode resolved, when the link comes up or
    drops, how many hosts were found, and a warning when the peer is running a
    different device than you (JagLink and Voice Modem cannot interoperate,
    and that used to fail silently).
  • vj_netlink.txt is finally documented: one line, the address only, no
    port.

Automatic mode deliberately never opens a listener and never dials a
discovered peer by itself — with the Voice Modem that would place a call the
user did not initiate.

The input-device epic, complete (#428)

Device Notes
ST/Amiga mouse Port 2
Tempest rotary Both ports
Analog / driving TR10 bank-switching protocol
Lightgun Balloons homebrew verified playable
Per-axis tuning Dead zone, offset, response exponent on every analog source

Two of these needed hardware archaeology. The analog controller has no
console-side ADC
— Atari deleted it from production silicon, so the
controller carries its own microcontroller and answers the ordinary
$F14000 row scan. The lightgun latches TOM's LPH/LPV light-pen
registers
continuously, not on the trigger, which means software cannot
detect a shot from those registers at all — the trigger is an ordinary pad
button.

Texture dump mode (#369)

Every unique blit source a game uses is written out as a PNG with a stable
content hash, ready for pack authors to redraw. The identity contract is
frozen and documented in docs/texture-dump.md:
FNV-1a 64 over format, dimensions and raw source bytes — deliberately not
the palette, because the Jaguar blitter never sees one, and a key the
replacement pipeline cannot discriminate would strand every pack drawn
against it.

Default off. Enable virtualjaguar_texture_dump, play, and find the tiles
under <system>/vj_texdump/<CRC32>/.

Texture replacement, tier 1 (#369)

The other half of the pipeline also ships: drop redrawn art into
<system>/vj_texpacks/<CRC32>/<hash>.png — the same hashes dump mode
writes — and it presents in place of the title's own tiles. Authoring is
"dump, redraw, move one directory over".

Packs are true colour; nothing in the path quantises RGB back to CRY,
and a pack pixel with alpha below 128 keeps the stock pixel instead.

The pipeline never writes the emulated machine. Replacement rides the
existing true-colour shadow framebuffer, gated on a per-pixel
straight-copy witness, so savestates, rewind, run-ahead and netplay stay
bit-identical with or without a pack — a pack cannot desync a link
game or invalidate a state.

Tier 1 covers 16bpp source tiles at 1x through straight-copy blits, which
is the sprite and UI blit class dump mode was built around. Indexed
sources (tier 2) and >1x Stage 2 surfaces (tier 3) are designed but not
implemented; entries of those kinds are skipped and the stock pixel
presents.

Default off, and the option only appears when a pack directory exists for
the loaded cartridge.

Boot ROM selection (#469, #473, #477)

Cartridges can now boot the Series K or Model M console boot ROM
(both embedded), or a custom image from the system directory. External
images are identified by checksum and named in the log — Series K, Model M,
Stubulator '93, Stubulator '94 — with unrecognised images loaded anyway and
flagged, so homebrew and modified ROMs work.

Fixes

  • Voice Modem corrupted video (#500) — activating the modem tore the
    picture apart: scanlines out of order, content stamped repeatedly down the
    screen, alternating garbage and clean at 60 Hz. It needed no connection —
    starting to dial was enough. UARTRaiseIRQ() asserted a 68000 level-2
    interrupt after checking only JERRY's own mask, but JERRY's interrupt
    output reaches the 68000 solely through TOM's C_JERENA gate, which both
    PIT callbacks apply and the UART did not. Ultra Vortek never enables that
    gate (measured: 2598 of 2600 frames), because its DSP polls the serial
    status and the 68000 never uses the receive interrupt — so on real silicon
    those bytes raise nothing, while here each one re-entered the display
    handler at an arbitrary raster position. Measured 3.26 spurious interrupts
    per frame before the gate, 0.999 after.
  • Blitter cross-load state leak (#479) — the B_CMD decode statics were
    never reset, so a session that used the fast blitter contaminated the
    next session's savestate. Invisible on desktop (a fresh dlopen
    re-zeroes statics) and live on iOS, where the core stays resident. Broke
    run-ahead and netplay determinism after an engine switch.
  • CHD session attribution and boot-header search (#476) — two
    independent parser bugs. Session metadata was indexed by track number
    rather than among itself, mis-attributing session 2 on discs whose first
    session has more than one track; and the ATARI boot header was assumed at
    a fixed offset when it is really variable mastering filler (2 bytes on one
    disc, 378 on another). The second reproduces from CUE and is unrelated to
    CHD.
  • Idle analog offset manufactured input (#439) — a non-zero offset fed
    phantom motion every frame from an untouched device, the exact failure the
    option exists to prevent.
  • JaguarDemos BootIntros (#469, #470, #473) — GPU-only jagcrypt carts
    crashed the frontend; they now auto-enable the real boot ROM. 46 of 49
    demos boot, gated in CI.

Accuracy groundwork

A real-hardware Doom capture was measured against our output: hardware
presents the attract demo at 4.0 fields/flip (15.01 flips/s); we present
2.00. That number now anchors the timing campaign, whose full plan ships in
docs/timing-campaign-plan.md — including
the finding that Doom's own code gates flips on a two-field software floor,
which is why processor-clock scaling never moved the cadence.

The campaign itself lands in v4.0.0.

Known issues

  • Ultra Vortek netplay is verified over both transports: the direct TCP
    link by an automated two-instance test through the in-game lockstep
    exchange, and RetroArch netplay by play-testing on two devices. There is
    still no automated test for the netplay transport (#494) — RetroArch
    netplay cannot be driven by scripted input — so regressions there would
    not be caught by CI.

  • The device-mismatch warning does not fire when the host was selected as
    jaghub.local, from vj_netlink.txt, or via VJ_NETLINK_HOST (#501). It
    compares against the raw option value rather than the resolved address, so
    the warning degrades to silence — connections themselves are unaffected.

  • Link input latency is authentic rather than good: the modem's DTE rate is
    permanently 19200 (proven from Atari's own JVM manual and the retail ROM,
    where the connect-speed byte turns out to be cosmetic), which is ~5.8 ms of
    wire time each way per frame against a strictly lockstep exchange. An
    opt-in enhancement to compress it is tracked as #498 for v3.5.0.

  • Voice audio over the modem is not emulated (#485) — the real JVM carried
    voice modem-to-modem, bypassing the console entirely.

  • The analog/driving controller implements the TR10 bank-switching protocol
    on the $F14000 joystick matrix. No released title is known to read that
    protocol, so its verification is the synthetic register-level suite in
    test/tools/analog_decode_test.c.

    Analog-capable software does exist, but it targets different hardware:
    BattleSphere and BattleSphere Gold sample the motherboard 8-bit
    ADC at $F17C00 — JERRY GPIO5, the "Paddle Interface", an ADC0844 fitted
    only to early Jaguar boards and deleted from production silicon. They round-
    robin four channels from a JERRY Timer 1 handler and consume two of them in
    an "Analog Joystick Calibrator" screen and in GPU code, gated behind
    Gameplay Options → 2nd Controller: Analog Stick. Club Drive writes the
    same channel-select without ever reading it back. That interface is not
    emulated
    — we return 0x0000 where an ADC-less console returns 0xFF
    and is tracked separately.

Downloads

Cores for 16 platforms are attached below. No BIOS files are required.

Stats

git diff --shortstat v3.3.0..v3.4.0 — 219 files changed, 98,856
insertions, 761 deletions, across 176 commits.

Maintainers

Joseph Mattiello, with the Virtual Jaguar libretro contributors.
Original Virtual Jaguar by David Raingeard (Potato Emulation) and
James Hammons.


Artifacts in this release

SHA256SUMS.txt
cue2cdi-linux-x86_64
cue2cdi-macos-universal
cue2cdi-windows-x86_64.exe
jagcd-tools-linux-x64.zip
jagcd-tools-macos.zip
jagcd-tools-windows-x64.zip
virtualjaguar_libretro-android-arm64-v8a-debug.tar.gz
virtualjaguar_libretro-android-arm64-v8a.so
virtualjaguar_libretro-android-armeabi-v7a-debug.tar.gz
virtualjaguar_libretro-android-armeabi-v7a.so
virtualjaguar_libretro-android-x86-debug.tar.gz
virtualjaguar_libretro-android-x86.so
virtualjaguar_libretro-android-x86_64-debug.tar.gz
virtualjaguar_libretro-android-x86_64.so
virtualjaguar_libretro-emscripten-wasm-debug.tar.gz
virtualjaguar_libretro-emscripten-wasm.bc
virtualjaguar_libretro-ios-arm64-debug.tar.gz
virtualjaguar_libretro-ios-arm64.dylib
virtualjaguar_libretro-linux-aarch64-debug.tar.gz
virtualjaguar_libretro-linux-aarch64.so
virtualjaguar_libretro-linux-i686-debug.tar.gz
virtualjaguar_libretro-linux-i686.so
virtualjaguar_libretro-linux-x86_64-debug.tar.gz
virtualjaguar_libretro-linux-x86_64.so
virtualjaguar_libretro-macos-arm64-debug.tar.gz
virtualjaguar_libretro-macos-arm64.dylib
virtualjaguar_libretro-macos-x86_64-debug.tar.gz
virtualjaguar_libretro-macos-x86_64.dylib
virtualjaguar_libretro-switch-debug.tar.gz
virtualjaguar_libretro-switch.a
virtualjaguar_libretro-tvos-arm64-debug.tar.gz
virtualjaguar_libretro-tvos-arm64.dylib
virtualjaguar_libretro-vita-debug.tar.gz
virtualjaguar_libretro-vita.a
virtualjaguar_libretro-windows-i686-debug.tar.gz
virtualjaguar_libretro-windows-i686.dll
virtualjaguar_libretro-windows-x86_64-debug.tar.gz
virtualjaguar_libretro-windows-x86_64.dll
virtualjaguar_libretro.info

SHA-256 checksums

Verify with sha256sum --check SHA256SUMS.txt (Linux) or
shasum -a 256 --check SHA256SUMS.txt (macOS).
See SECURITY.md
for full verification instructions and antivirus false-positive guidance.

b926e41185057ee9204aaa0aaafff53ceec2cbb6d4f37e478edf7a7ddb353332  cue2cdi-linux-x86_64
c19f65c1be0eab40e58f0a4d619704dcfc4632858d00eef78a737d0f26e7a134  cue2cdi-macos-universal
cfb56befb74e324f5a02575fe93299bd80ece7d6b371269c1aeb5b69255c1536  cue2cdi-windows-x86_64.exe
f5299c526b779e04880998bb5978f538bcf14aefad6749c7539ed9098aec8e5c  jagcd-tools-linux-x64.zip
9c994c37e73092bc3c740824305f84d0dbce7dc1ee197c51f0beb704e7446966  jagcd-tools-macos.zip
5170ae1320ff96aba8b14198569ee9ab74bd231a4aa566a43045395217d08712  jagcd-tools-windows-x64.zip
1f94f40f934790868d745abd6a93eabd28706e599aea845b36ae7accf5f53f47  virtualjaguar_libretro-android-arm64-v8a-debug.tar.gz
5899694ca9c8507109ca2344ae5647dbc49ee9faf1d74377006746f7f7d066e9  virtualjaguar_libretro-android-arm64-v8a.so
396214fd300ce5e7afbb7c586c19f7c1388953a23c7550cc6061b9d2b04fa30b  virtualjaguar_libretro-android-armeabi-v7a-debug.tar.gz
973e7344ceb35cb73a10bcfd38c7aaa1fa9d0cd67f5f5c984b88836ad3a83d66  virtualjaguar_libretro-android-armeabi-v7a.so
7d0ba3633ab151f457f6189af3a9debd6a51ed753045c60706c2e7b721825ed1  virtualjaguar_libretro-android-x86-debug.tar.gz
3a47486d54e4db17ff03b09ec54095b74ca5635e164f4c8e74ffb5570a6ab984  virtualjaguar_libretro-android-x86.so
3719512cecce9a4c4ae8a09863b82fa69101338980a9dd473089cbe40e616535  virtualjaguar_libretro-android-x86_64-debug.tar.gz
068b3a327e5b6eea97b13bdbb628e515a54a33a95e1fa7b379fba15c3f4588b2  virtualjaguar_libretro-android-x86_64.so
480dd7a2b9d1fe1feee8856256f608aa74e0a2819894e0d99cdc766cf3aac3ce  virtualjaguar_libretro-emscripten-wasm-debug.tar.gz
84d1de02e0f9e6a6d73a1d36be7eefe2494bb1e9d48ca1ce0c3ad9c2560a6a95  virtualjaguar_libretro-emscripten-wasm.bc
6f5ab2f712261eb5cc9452345a4dd4e21d1cb025777f704d88af1108aff036b8  virtualjaguar_libretro-ios-arm64-debug.tar.gz
e0bdd44fd893cba1dfc93d33d34febdcf61154ecf36782e96e19132466815a51  virtualjaguar_libretro-ios-arm64.dylib
a74f662fad8083c304ab0a89fce16e4a48c7c563d16285a5bc63ac06483df884  virtualjaguar_libretro-linux-aarch64-debug.tar.gz
f63f1aaa0060f84a321e56e97f82e652f5fb213c09e29f5a4a2276b9270013cc  virtualjaguar_libretro-linux-aarch64.so
4dcfde68e420e0e07d075afc4c0b2cca071186d503aa8f3b9ab846e0955fbdd5  virtualjaguar_libretro-linux-i686-debug.tar.gz
47faa6c8760e549855cd8b82fa89a0e0c2898164e49f07cc29ee148156f54420  virtualjaguar_libretro-linux-i686.so
cbf2c65fd5eef8cc591a9876988ac04ab0726b4209cdc4c3a067f3b6aa19ee59  virtualjaguar_libretro-linux-x86_64-debug.tar.gz
e6e7736057ffe1e7186a2f5c867aa4a070574a1a297b443d39b1545fb2b06da0  virtualjaguar_libretro-linux-x86_64.so
bacb161d34f1c06eb3d34ad361a1b56695e01536e708cd8a05573ae882c6a92b  virtualjaguar_libretro-macos-arm64-debug.tar.gz
61d8e5baf0b99ea12bff0f9fc488bffad67d6831d8dc6839fe22cc01c28c4921  virtualjaguar_libretro-macos-arm64.dylib
fe791ee04c3e5abccc7f8c02e27cdb800414852b57427011819aaff544a88de4  virtualjaguar_libretro-macos-x86_64-debug.tar.gz
ce046a0081c04c9c48729cec0543c3921296015f7534403472ae08e2bc7f08ee  virtualjaguar_libretro-macos-x86_64.dylib
aa457847e7717a86fda7e6bf767b01bf4bc18958eb1cb6874073c1dfcc65d8f8  virtualjaguar_libretro-switch-debug.tar.gz
dc0bf73de83b9a085136533586496922d351d8ea9e9b86f04f23cecb68253d82  virtualjaguar_libretro-switch.a
b42a9f41aded12b0bbeee60be62282526643d6a20d149499dc764c213d630a16  virtualjaguar_libretro-tvos-arm64-debug.tar.gz
332226cf181113edac7da4cf7a9369351b58ea7a982fd4fe6d72ea895227e347  virtualjaguar_libretro-tvos-arm64.dylib
95fa9d087c2df0379babe05cf75ac6253d5bfbac8903b9f78e726db18625216c  virtualjaguar_libretro-vita-debug.tar.gz
3a90448661e61b7b4bd98638c12d0dbca28a2c4dc69ecd35e02b62cfc68cf99a  virtualjaguar_libretro-vita.a
8eff83a33fb8c20795701f993e015efff698d2a81ad21b4a4c4fb7757a92cb6f  virtualjaguar_libretro-windows-i686-debug.tar.gz
10614a2d02ffd917607d1de36bc2e5da9b1f026672a34d4aac1fbf2008b6e96c  virtualjaguar_libretro-windows-i686.dll
a35b19e1a4739472130216546731e139917f697277f6cff16ee11752d8d23c2d  virtualjaguar_libretro-windows-x86_64-debug.tar.gz
049bdbb72e8dc0db6f6b04099cde5d94bca68617ee61c7f226147ba19caa16ae  virtualjaguar_libretro-windows-x86_64.dll
f507cdffedb37d68777f56db70992e1e56fcd90d0056ebf4988379cfa54e4fc7  virtualjaguar_libretro.info