Skip to content

GameFrame 1.2.0

Choose a tag to compare

@tanepiper tanepiper released this 25 Oct 00:30
· 120 commits to main since this release

[1.2.0] - 2026-10-25

GameFrame 1.2.0 expands the late-1990s replacement libraries, adds a clean-room Indeo 4.1
decoder and a runtime harness, and improves input capture and project safety. Know-how now has
broad starting entries for major topics alongside its specific failure notes.

Added

  • Know-how now has broad starting entries for sound cards, CPU behavior, display output,
    CD-ROMs, input, networking, game files, and timing. The entries link to detailed guides, with
    case notes where available. Know-how guidance now calls for an overview when a major topic has
    only narrow entries.

  • sgl.dll draws the immediate mode's shadow and light volumes (sgltri_shadow), which it
    only counted before. Each call's faces become the planes of one convex volume, oriented as
    PowerVR's driver orients them, and every pixel is tested against them: a shadow multiplies
    by its brightness, a light volume adds its colour. Texture wrapping now moves a vertex by one
    turn at most, as measured in the driver. In shadow mode a Gouraud face with a translucent map
    is drawn flat, as the driver does. The fog constant is 1.0, a person's choice until a PCX2
    picture settles it. Free texture memory and the sglhw.ini the library writes follow the
    driver's installer (TSPParamSize 256). sgltritest.c draws one volume of each kind.

  • gameframe-msvc-crt adds safe byte memory operations, C byte-string functions, integer parsing
    and integer formatting. It models Windows long as 32 bits and documents its C-locale limits.
    The 2008, 2010, 2012 and 2013 x86 CRT exports and selected decompiles informed the new routines.
    Their runtime parity is still open.

  • glide2x.dll draws under Wine on macOS. There Wine gives OpenGL 2.1, which cannot compile
    the library's shaders. The library now asks for a forward-compatible 3.2 core context when the
    first one is older than OpenGL 3. glidetest.exe passes all 27 checks under Wine on an Apple
    M3 Max (docs/knowhow/wine-macos-opengl-2-1.md).

  • glide2x.dll now implements all 156 Glide 2 calls. The last 25 are in. The PCI library
    (pci*) shows one Voodoo Graphics. guMPDrawTriangle draws two textures in two passes, as
    Glide 2.43 does. The guMovie* calls record each frame shown as a TGA file. That is a
    Deviation, as Glide 2.43 cannot record. guEncodeRLE16 gives the same bytes as the
    original on 2009 test images, faults included. ConvertAndDownloadRle downloads zeros, as
    the original does, since its line decoder is empty. grSstConfigPipeline and
    grSstVidMode do nothing, as the window is the library's. glidetest.c checks the PCI
    library, the encoder, the two passes and a recorded frame.

  • A project's target/, the user's own copy of the game, is now hard to delete by mistake. A
    disk cleanup took it for Cargo build output and lost three projects' game copies and an
    original save (docs/knowhow/game-folder-deleted-as-build-output.md).
    new-project.sh writes target/GAME-FILES-NOT-BUILD-OUTPUT.txt, and update-project.sh
    adds it and .cargo/config.toml (target-dir = "build") to older projects. A new delete
    gate (scripts/hooks/gates/deletes.py) blocks an agent's rm, move to the Trash,
    find -delete, git clean -x, cargo clean into target/ and build-folder cleaners on a
    game folder; GAMEFRAME_DELETE_GAME=1 on the command lets it through. ./gameframe doctor
    reports a missing or empty target/. templates/project/AGENTS.md says target/ is the
    only copy and build/ is Cargo's.

  • glide2x.dll implements 131 of the 156 Glide calls, up from 55, so it runs more Glide 2
    games than POD. It now draws points, polygons, and the antialiased and clipping draws. It
    handles culling, the alpha test, colour and depth masks, depth bias, drawing to the front
    buffer, the lower left origin and the colour formats. It saves and restores state
    (grGlideGetState, grGlideSetState). Textures gain mipmaps, LOD bias, NCC tables,
    multibase, partial downloads, the gu texture manager and 3DF files. The frame buffer gains
    region reads and colour formats. The queries, statistics and gu fog tables are in. The
    fog tables match the original byte for byte. wrappers/glide/test/glidetest.c draws and
    checks a known scene through the DLL, and tests/run.sh builds it. The host tests cover
    clipping, culling, mip level layout, fog tables, 3DF files and NCC tables.

  • sgl.dll now has SGL's immediate mode, which Hardwar's PowerVR mode uses. It has the
    sgltri_* calls for triangles, quads and rendering. It has SGL's DirectDraw mode with its 2D
    callback. It also has the end-of-render callback, the error, version and texture-memory
    calls and sgl_delete_all_textures. That is 14 more calls, so SGL has 61 of 134. The faces
    go through the scene graph's renderer. The header leaves facing, flat shading, translucency
    levels, the order of translucent passes and the fog register open. They were read from
    PowerVR's own SGLMID4.dll, partly by unattended re-tracer runs.
    wrappers/sgl/test/sgltritest.c draws a known scene with them. The plain-Rust part has
    host tests.

  • Every wrapper DLL now exports every call of the original library, so any game that uses one
    loads. Calls implemented of calls exported: Glide 55 of 156 (Glide 2.43 and 2.1.1), SGL 47
    of 134, ATI3DCIF 6 of 17, S3D Toolkit 6 of 6, DirectDraw 2 of 9. Each crate's api.tsv
    holds the original's API table. wrappers/stubgen.py writes the crate's .def and
    src/stubs.rs from it. It stubs each call not written yet. It fails on a call written with
    the wrong convention. The originals stay outside the repository.

  • tools/pe/apitable.py writes the API table of a 32-bit DLL or of an SDK's import library.
    For a DLL, each export's convention and argument bytes come from the ret N its code ends
    with. A header gives the parameter counts and return kinds. The tool is tested on a DLL
    built from our own C.

  • The wrappers log what they lack in one way. shim::stub! and shim::gap! log the first call
    of each stub and unhandled mode with its arguments. They count the later calls. When the game
    exits, they list them all with their counts. ddraw.dll names each COM method that is a stub. sgl.dll now logs the
    convex objects it skips.

  • Debug and release builds of the wrappers. cargo build gives symbols, debug assertions, the
    first 50 calls of each stub logged and OpenGL errors checked after each frame. cargo build --release gives link-time optimisation and stripped DLLs. Each log names its build.

  • S3DTK_ExitLib and S3DTK_PhysicalToLinear, from the original's code. With them the S3D
    Toolkit is complete.

  • wrappers/, a Cargo workspace of replacement libraries for the 3D cards of 1997, moved from
    the POD project: glide2x.dll (Glide 2.x on OpenGL), ddraw.dll (DirectDraw in memory,
    scaled), ati3dcif.dll and s3dtkw.dll (the chips' faces drawn in software), and sgl.dll
    (PowerVR SGL's scene-graph half on OpenGL). The shared crates are shim, raster,
    scalers and pixels. The game-specific parts became settings: WRAPPER_WINDOW_CLASS,
    WRAPPER_MARKER and a patch file named by WRAPPER_PATCHES. tests/run.sh runs the host
    tests, builds the DLLs, checks their export tables against the .def files and builds
    sgltest.c.

  • Thirty-seven know-how entries: thirteen from POD (POD Gold, the PowerVR build, the emulated
    PC, ptrace under Wine, the FPU control word in the game's own thread and more) and
    twenty-four from Hardwar, among them running the original on a whole-process snapshot,
    registers left by callees, fake worlds and Ghidra function recovery. The taxonomy gains the
    API sgl (PowerVR).

  • A guide to the replacement libraries, docs/hardware/wrappers.md:
    why games had a build per card, what each DLL draws and lacks, how to build and use them,
    patch files, logs, adding a game or a call, tests, and POD as the worked example with
    screenshots of its runs. The home page has a section on them.

  • gameframe-indeo, a clean-room Indeo 4.1 decoder that matches Intel's IR41_32.DLL byte
    for byte, and ir41_32.dll, a Video for Windows codec built on it. The decoder's empty-band
    path now uses the same fill words as Intel's Pentium path.

  • wrappers/maxi94 supplies a silent 94DLL32.dll so POD Gold's Maxi Sound 64 build starts,
    then maps its opened wave outputs and mixer lines to host audio. A full race measured the
    output. The sound-card API guide distinguishes measured behavior from unverified descriptions.

  • tools/live/emupc.py gives each game's emulated PC a project-specific name and refuses to
    start a second copy for the same project.

  • The runtime harness inspects a game folder, names its runtime needs and writes setup steps.
    Its initial modules cover Wine, emulated PCs, DOSBox-X, Steam, audio, disc drives and Glide
    wrappers. tools/live/align.py maps a known screen to a capture so scripts can place clicks;
    tools/llm/locate.py can locate a changed screen, and tools/formats/pngio.py reads and writes
    PNG. re-observe now plans the harness before the first run and maps click points before
    driving it.

  • The repository now backs up its Codex Cloud environment settings, install script and start
    instructions under docs/working/ and scripts/.

Changed

  • scripts/zcc.sh also finds a DLL's .def file one folder down, in ZCC_DEF_DIR/*/NAME.def,
    for a workspace with one .def in each crate.
  • The replacement-libraries guide points at wrappers/ and says how a game uses them.
  • Three know-how entries take POD's newer findings: the game races with the x87 word 0x027f,
    and CD audio and PulseAudio in the emulated PC.
  • re-randomiser lists chance taken from the frame clock; the recording guide records the
    FPU's control word and measures sequences; re-start gives the order for moving to a newer
    version; the object-model guide says a probe client takes any JSON answer.
  • tools/llm/name_functions.py submits functions in batches, reports each batch's status,
    fetches every result, and can cancel the run.

Fixed

  • memrec --name takes the game's own process, never the shell or launcher that started it,
    whose command line names the game too.
  • client.py keeps reading a project .env file after a key is absent, so later settings are
    still available.
  • new-project.sh --copy removes generated Python caches from copied scripts/ as well as
    tools/, so they do not keep GameFrame's scripts behind when a project moves to the plugin.