Skip to content

v0.10.0

Choose a tag to compare

@github-actions github-actions released this 17 May 17:39

Second tagged release of the fork. ~30 merged PRs since v0.9.0: first-launch folder picker, gamepad-friendly saves, console give/slide, macOS DMG + Linux tarball joining the AppImage and Windows ZIP, a UB hardening pass from new clang-tidy CI, restored ScaleSprite distance scaling (most visible: the magic ball receding properly in exteriors), and a refactor laying the foundation for the widescreen work.

Welcomes @b-tuma as a new contributor (gamepad D-pad navigation, #79).

Binaries for Linux (AppImage + tarball, x86_64 + aarch64), macOS (Apple Silicon DMG), and Windows (x64 ZIP) attached below. Smoke-tested against a clean debian:stable-slim container with no SDL3 / X11 / audio deps preinstalled. macOS DMG still needs the right-click → Open Gatekeeper bypass on first launch (Developer ID + notarization deferred); see the README inside the DMG.


New features (opt-in)

  • Cross-platform first-launch folder picker: when no retail game data is found via the usual discovery paths (./data, ../LBA2, LBA2_GAME_DIR, --game-dir), the engine now prompts for the install folder via the native system file dialog instead of exiting with an error. Picked path is persisted to a user-config file for next run; pass --pick-game-dir to force the picker again. Works on Windows, macOS, and Linux (zenity / xdg-desktop-portal-* on Linux, with explanatory fallback text when no backend is installed) (#107, #111).
  • Save/load list now navigable with gamepad D-pad (#79).
  • Auto-named saves for gamepad users: gamepad input on the save-name prompt skips text entry and writes a scene-aware default name in the form <scene> - YYYY-MM-DD HH-MM-SS (e.g. Citadel Island - 2026-05-17 14-30-00). The scene portion is localised across the six menu languages (sourced from the retail TEXT.HQR file 2); the date/time portion is fixed %Y-%m-%d %H-%M-%S. Long names clip with a marquee in the save list; post-save success chime + "Game saved" overlay (#151).
  • Console give command now actually grants inventory items instead of only playing the found-object cinematic. It takes an item name (give conch), with the numeric index still accepted as a fallback; run give with no arguments to list every item name. Countable items accept an optional count (give gem 5, give money 5000, give clover 3) (#143) — see docs/CONSOLE.md.
  • Console slide command jumps directly to a distributor/bumper slide (Adeline, EA, etc.); companion distrib command lists the available slide IDs (#116).

Stability & fixes

  • ScaleSprite scaled path restored. A 2024 ASM→CPP port had stripped the scaled-output branches, leaving the function effectively unscaled for months. The most visible symptom in-game: world-space sprites that should shrink with distance no longer did — the magic ball, for example, stayed the same size as it flew away from Twinsen in exterior scenes instead of receding with distance. The regression went unnoticed because the existing test only varied numerator/x/y, not the scale factor. Mirrored back from SCALESPT ASM, and the test matrix extended to cover factor sweeps (#148).
  • TempoRealAngle extern conflict in savegame load: DEBUG_TOOLS=ON builds failed to compile because PR #62's stride-retry refactor introduced a wrong-typed extern S32 TempoRealAngle next to the existing file-scope T_REAL_VALUE_HR definition. Default builds were unaffected (the block is #if-gated out). Fix removes the redundant extern (#146).
  • GereExtras no longer reads uninitialised old-position memory (#142).
  • Undefined-behaviour hardening pass from the static-analysis sweep: shift-by-32 UB in the POLYGOUR dither rotate, signed-overflow in I_WEAPON_7 / A_FLIP bit masks, and TheEndCheckFile marked noreturn to close null-deref paths flagged downstream (#140).
  • deffile config parser: signed-char EOL desync and self-aliasing strcpy cleaned up. Bug A was user-reported: a lba2.cfg containing Language: Français (or any other Latin-1 high-bit byte) corrupted on successive rewrites — 21 stray çais lines spliced in and all 144 keyboard + gamepad bindings reset to zero. Bug B was an overlapping strcpy(FileName, file) caught by ASan against the GOG TLBA2 Classic package on shutdown. Both were old, both UB. Host-only regression test added under host_quick (#115, #132).
  • Terrain vertex projection: dropped the no-op / off-by-one +0.5 rounding bias that desynced terrain vertex positions from the rest of the scene (#145).

Refactoring

  • Framebuffer dimensions extracted to RESOLUTION_X / RESOLUTION_Y in a new LIB386/H/SYSTEM/RESOLUTION.H. Cinema bars and sort-tree preclip now route through ModeDesiredX/Y instead of hardcoded 640/480. Foundation for the widescreen / higher-resolution rendering work (#134).

Game data, config, and UX

  • lba2.cfg defaults modernised for the open-source era: fullscreen on by default (DisplayFullScreen=1), Version row defaults tightened to match the shipping engine (#117).

Tools

  • scripts/dev/extract_lba2_gog_media.py extracts the retail media tree from the GOG Original Edition LBA2.GOG bin/cue image (ISO9660 reader with no external mount/isoinfo dependency). Lets users with the GOG install seed ./data without owning the original CDs (#119, #123).

Cross-platform & build

  • macOS native release artifact: a portable DMG with the .app bundle inside, drag-to-Applications layout, native multi-resolution .icns icon, and an Info.plist populated from the same LBA2_* cache vars that drive the runtime window title, .desktop entry, AppImage labels, and Windows resource. Built for arm64 (Apple Silicon) on tag push; static-linked SDL3, no .dylib dependencies, ad-hoc codesigned to satisfy Apple Silicon's mandatory bundle integrity check. First launch still needs the right-click → Open Gatekeeper bypass (Developer ID + notarization deferred); documented in the README inside the DMG, and the Sequoia (15+) xattr -dr com.apple.quarantine recovery flow is spelled out in docs/RELEASING.md. Intel-Mac users can produce a local DMG via scripts/dev/build-macos-release.sh --preset macos_x86_64 while hosted Intel runners are unreliable (#102, #103, #105, #106, #149).
  • Linux binary tarball release artifact alongside the AppImage: same static-linked single-binary layout, drop-in for distros where AppImage FUSE is a hassle. libxtst-dev added to the tarball build deps after the first CI run surfaced the missing X11 link (#124, #125).
  • Post-release smoke-test script (scripts/dev/verify-release.sh) downloads each published Linux artifact, runs the discovery self-tests, and reports per-asset pass/fail. Pointers added to the releasing recipe and announcement steps (#126, #127).
  • Rolling latest pre-release: every push to main triggers a CI build of all three platforms (Linux AppImages, Windows ZIP, macOS DMG) and force-updates a latest-tagged GitHub Release. Marked pre-release; the most recent stable tag keeps GitHub's "Latest" promotion. Lets community testers grab bleeding-edge main builds without cloning + building (#108) — see docs/RELEASING.md "Rolling latest pre-release".
  • Release workflow hardening: low-friction release-target additions, CI path filters so doc-only pushes skip the heavy matrix, pinned setup-sdl SHA + per-arch cache discriminator after a stale-cache drift incident (#129, #130).

CI & developer workflow

  • clang-tidy static-analysis pass wired into CI, with a tuned check-list that silences bulk-noise categories (Watcom-era idioms, C-style casts in ported code) while keeping the high-signal UB / memory-safety / portability checks. The first analysis pass produced the UB-hardening fixes listed above (#139, #141).
  • Docs-only gate for the required build/test checks so README/CHANGELOG edits don't block on the full matrix (#136).
  • Optional pre-commit hook running check-format.sh for contributors who'd rather catch clang-format mismatches locally than in CI (#133).

Documentation

  • docs/WIDESCREEN.md — phased plan (A–E) for the widescreen / higher-resolution work, with the framebuffer-extraction refactor above as its first landed phase (#135).
  • docs/CI.md — map of the CI workflow surface (matrix builds, gates, release flow) so contributors can reason about a failing job without spelunking the YAML (#137).
  • docs/SPRITES.md — sprite/blit pipeline reference, including the ScaleSprite path layout and the test gap that hid the scaled-path regression for months.
  • docs/AUDIO.md extended with the retail audio asset inventory: what's ADPCM-WAV, what's MIDI, and which backend owns which path.

Contributors

Welcome to a new contributor since v0.9.0: @b-tuma — gamepad D-pad navigation for the save/load list (#79).


Full Changelog: v0.9.0...v0.10.0