No description
  • Pascal 70.8%
  • Python 18%
  • C 5%
  • JavaScript 3.3%
  • Nix 1.4%
  • Other 1.4%
Find a file
Eric 09647dbf70 port_smoke.py: the screen checked against the frame presented
Each session runs with HOLIDAY_GL_CHECK and HOLIDAY_PRESENT_CHECK -- the
build's own path, OpenGL where the X server has GLX, SDL's renderer
without or with HOLIDAY_GL=0 -- and fails on a frame that differs: a part
not uploaded, which a build leaving one out had passed in every session.
The report counts the frames on the screen checked.  Both paths, all six
sessions: none differ; the broken build fails at once.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015JsUgeyk9CsEXERdwUGTuD
2026-10-25 19:01:38 -04:00
docs port_smoke.py: the screen checked against the frame presented 2026-10-25 19:01:38 -04:00
game Touch: a pan flings on, its fingers' moves merged, its diagonal steps two 2026-10-24 21:10:18 -04:00
port web: played in WebKit; the 2D canvas puts only the parts that changed 2026-10-25 18:17:04 -04:00
recon The widgets' Checked and the options it sets are Booleans 2026-10-24 03:38:41 -04:00
tools port_smoke.py: the screen checked against the frame presented 2026-10-25 19:01:38 -04:00
.editorconfig build: store recon/ as UTF-8, transcode to cp1252 when assembling the build tree 2026-09-29 14:08:42 -04:00
.envrc tools: a justfile for unpack, build, run and smoke -- versions en, fr, de, de10; the game directories named after them; lite the default shell 2026-10-06 00:23:39 -04:00
.gitignore docs: current state only -- findings, unit sheets and the old catalogue retired 2026-10-03 22:31:09 -04:00
flake.lock Mac OS 9: the game as a PowerPC application, played in QEMU's mac99 2026-10-23 20:51:28 -04:00
flake.nix web: played in WebKit; the 2D canvas puts only the parts that changed 2026-10-25 18:17:04 -04:00
justfile Android without the SDK: game controllers, and in just release 2026-10-25 13:48:20 -04:00
PLAN.md docs, tools: what a scroll step copies, and profile_scroll.py to count it 2026-10-22 18:10:20 -04:00
README.md Android without the SDK: game controllers, and in just release 2026-10-25 13:48:20 -04:00

Holiday Island

Reviving Holiday Island (1996, Sunflowers / Bomico), a 16-bit Windows isometric resort-tycoon game, as a native, improvable program.

  • recon/: the original's Delphi 1 source, reconstructed. Borland's compiler turns it into the shipped executables, the German 1.0 byte for byte (recon/README.md).
  • The port: the same tree builds with Free Pascal and the Lazarus LCL into a native program that plays the game, on Linux, Windows, a Nintendo Switch (homebrew, on a console), a Steam Deck, Android (a phone so far), in a browser (WebAssembly: Firefox and Chromium) and on MS-DOS (a 32-bit DPMI program: DOSBox-X and a Pentium II laptop), and agrees with the original tick for tick (docs/port.md). It can keep its bitmaps as a 256-colour display did, a quarter of the memory (docs/port.md).
  • game/: the port's improvement tree, where the game changes: a resizable view and overview map, the whole screen on a Switch or a Steam Deck so far (game/README.md).

PLAN.md has the goals, the rules and what is open.

Everything works from the user's own copy of the game, kept in iso/ with the Delphi 1 archives the reconstruction builds with. No CD image, and nothing extracted from one, is committed or redistributed.

Quick start

nix develop                                     # FPC, Lazarus, just, tools (or: direnv allow)
just unpack iso/Holiday_Island_Win_ROM_EN.zip   # -> extracted/en
just run                                        # build game/ for English 1.1 and play it

The justfile holds the everyday steps over tools/; just lists them. build, run and smoke take a version, en (the default), fr, de or de10, and optionally a tree, game (the default, but for de10) or recon. game/ builds the three 1.1s with --language; recon/ builds the originals, the German ones with --variant: just run de builds game/ with --language de into build/game-de/ and plays it in extracted/de, just run de recon builds recon/ with --variant v11de into build/recon-de/. Outside the dev shells the recipes run the tools in them.

just switch, just switch-romfs, just deck, just appimage, just windows and just release (all of the ports, Android's the no-SDK build) make the version's game for a Nintendo Switch's SD card (a folder, or one .nro), a Steam Deck, one file on Linux (an AppImage) and Windows, in build/release-TREE-VERSION/: switch-sd.zip, switch-romfs/switch/holiday/holiday.nro, deck/holiday-deck.tar.gz, appimage/Holiday_Island-x86_64.AppImage and windows/holiday-windows.zip, from your install's files (about a minute each; docs/port.md, AppImage, Windows). The 1.1s from game/ fill the Switch's and the Deck's screens; recon/ keeps the original's 640x480. The Windows build has run only under Wine so far. just frame makes the Deck's folder for a Steam Frame (aarch64, SteamOS on ARM), frame/holiday-frame.tar.gz, untried on one (docs/port.md).

just web makes the version's game for a browser: build/release-TREE-VERSION/web/holiday-web/ and holiday-web.zip, with your install's files and the music's SoundFont in it. python3 serve.py in the folder serves it and opens the page, which starts the game at once (docs/port.md). It is part of just release.

The MS-DOS build is a Free Pascal i386-go32v2 program on its own platform (VESA 8-bit video, the mouse driver, IRQ 1, a Sound Blaster, an MPU-401 or an FM chip for the music), built in .#dos and tried under DOSBox-X in it and on a real PC, a Pentium II laptop: nix develop .#dos -c python3 tools/fpc_build.py game/holiday.dpr --target i386-go32v2 --dos --out /tmp/dos. just dos makes the version's game for a real PC: build/release-TREE-VERSION/dos/holiday-dos/ and holiday-dos.zip (HOLIDAY.EXE, CWSDPMI.EXE, a README and your install's files, 193 MB; type HOLIDAY in the folder), part of just release (docs/port.md).

just nt makes the version's game for Windows NT 3.51 and on, Windows 95, 98 and ME, and Windows 3.1 with Win32s: a 32-bit program on Win32 alone (GDI, waveOut, MCI's sequencer for the music), no DLL beside it, in build/release-TREE-VERSION/nt/holiday-nt/ and holiday-nt.zip (195 MB). just nt-mips makes the same for NT 3.51 on MIPS, with a Free Pascal target and a linker of the flake's own: build/release-TREE-VERSION/nt-mips/holiday-nt-mips/ and its .zip; just nt-ppc the same for NT 3.51 on PowerPC: build/release-TREE-VERSION/nt-ppc/holiday-nt-ppc/. All three played on NT 3.51 in QEMU so far (the first on Windows 95 in QEMU and on Windows 3.11 with Win32s in DOSBox-X too). just release makes all three (docs/port.md).

just wii makes the version's game for a Wii's SD card, for the Homebrew Channel: build/release-TREE-VERSION/wii-sd/ (its apps/ to the card) and wii-sd.zip (227 MB: the game as a .dol built with Free Pascal and devkitPPC, your install's files and the music's SoundFont cut down for the console's memory). It plays in Dolphin with its sound and music, the Wiimote pointing; it has not run on a console yet. Its files are a PC's, though the Wii is big-endian: the CD's tutorial and scenarios and a PC's saves load (not yet tried in Dolphin), and its saves load on a PC. Part of just release (docs/port.md).

just android makes an Android APK of the version's game, with your install's files in it, to sideload: build/release-TREE-VERSION/android/holiday.apk (docs/port.md). It is not part of just release: it fetches the Android SDK and NDK (about 1 GB, under their licence) and has run on one phone so far. just android-nosdk makes the same game on Android's own NativeActivity with nothing of Google's SDK or NDK (AOSP's headers, nixpkgs' clang and lld), an app of its own beside the other: build/release-TREE-VERSION/android-nosdk/holiday.apk, which plays on the same phone, controllers too, and is the one just release makes (docs/port.md).

just unpack (unpack_game.py) turns any of the CDs (ISO, .bin/.mdf/.cue, a directory, or a .zip/.7z holding one) into a directory the game plays from, with no installer and no Wine. Unless told otherwise it picks the directory the tools expect for the version it finds:

directory from used for
extracted/de10 the German CD (iso/Holiday Island (1996)(Bomico)(DE).iso) 1.0: the Delphi check, the original under Wine, fpc_run.py's default
extracted/en the English CD 1.1: running and smoke-testing the port
extracted/fr the French CD the French 1.1
extracted/nsis nsis_extract.py iso/Holiday_Island.exe the 1.1 executable recon/ reproduces
extracted/de the German "Erweiterte Version" CD the German 1.1 check

The checks

just smoke             # fresh builds of game/ and recon/, both through port_smoke.py side by side (~1.5 min)
just check-versions    # recon/ still compiles to the originals
just check-docs        # links and tables in the Markdown

just smoke after any change to port/. check_versions.py after any change to recon/; it needs the German retail Delphi 1 and the French Delphi 1 Client/Server CD in iso/ (recon/README.md), which it unpacks itself the first time.

Documentation

PLAN.md goals, rules, status and open work
recon/README.md the reconstruction: versions, building and checking, the rules for editing, why the source looks as it does, the units
docs/port.md the Free Pascal port: build, run, test; the compat layer; the guards; Delphi 1 vs FPC hazards; environment variables
game/README.md the improvement tree
docs/game.md the copies of the game, its files, the save format, timing and randomness
docs/original.md running the original under Wine, reading its state, comparing it with the port

The code is documented in place: the units' comments in recon/ and port/compat/ say what each routine and global is, and every tool's docstring says what it does (python3 tools/X.py --help).

Dev shells

shell contents download unpacked
nix develop (.#lite) disc and media tools, Free Pascal + Lazarus (qt6), SDL3, SDL2, FluidSynth ~1.3 GB ~4.6 GB
nix develop .#emu lite + Wine (with Win16), DOSBox-X for Borland's tools, Xvfb ~2.0 GB ~6.5 GB
nix develop .#re lite + Ghidra, gdb ~2.3 GB ~6.1 GB
nix develop .#full everything ~3.0 GB ~8.0 GB
nix develop .#win lite + the Windows cross toolchains (i386-win32, x86_64-win64; built locally) + a 64-bit Wine and Xvfb (docs/port.md)
nix develop .#arm lite + the aarch64-linux cross toolchain (built locally) + qemu-user and Xvfb (docs/port.md)
nix develop .#be lite + the powerpc-linux cross compiler (built locally, a big-endian CPU) + qemu-user (docs/port.md)
nix develop .#wasm lite + Free Pascal trunk's wasm32 cross compiler (built locally), wasmtime, Node, and .#be's PowerPC compiler and qemu-user (docs/port.md)
nix develop .#web .#wasm and a headless Chromium, for tools/web_test.mjs (docs/port.md)
nix develop .#dos lite + Free Pascal's i386-go32v2 compiler and RTL (built locally, with DJGPP's binutils for the start-up file), DOSBox-X and Xvfb (docs/port.md)
nix develop .#switch lite + devkitPro's Switch toolchain, the aarch64 cross compiler (built locally) + Ryujinx and Xvfb (docs/port.md)
nix develop .#wii lite + devkitPro's Wii toolchain, a PowerPC cross compiler (built locally) + Dolphin, gdb and Xvfb (docs/port.md)
nix develop .#android lite + the Android SDK and NDK (fetched, under their licence), JDK 17, CMake, the aarch64 cross compiler and its Android run time library (built locally) (docs/port.md)

The shells export what the port needs to build and run (FPC_LIBRARY_PATH, QT_PLUGIN_PATH, SOUNDFONT, TINYSOUNDFONT); .#emu and .#full also set up Wine (WINEPREFIX in extracted/wine/prefix, a 32-bit prefix, quiet, no Mono or Gecko installers). .#win sets up its own Wine prefix, a 64-bit one in extracted/wine/port, which runs both Windows builds of the port. Each shell names itself in HOLIDAY_SHELL. The Python tools are stdlib-only and also run without nix.

Layout

recon/         the reconstructed Delphi 1 source: 1.1, and 1.0 / German 1.1 as patches (v10/, v11de/)
game/          the improvement tree: recon/ as Free Pascal reads it, free to change
port/          fpc.inc and the compat units both trees build with; tests/
tools/         stdlib-only Python tools; ghidra_scripts/
docs/          the reference documents above
extracted/     working area (gitignored): unpacked games, run directories, traces
flake.nix      the toolchain
justfile       the everyday steps: unpack, build, run, smoke, the checks
build/         the justfile's builds (gitignored)