Work log
Short notes as bigger pieces of work finish, newest first. The diary tells the story of each session; the reference documents are under Formats.
2026-10-26
- Un-POD dispatches both measured textured face paths. Source visibility, keyed and two-sided flags now reach the scene renderer; the app chooses the affine fan or clipped row-span path. A matched POD frame is still needed to confirm the roof gaps. Diary
- POD's affine textured fan drawers measured and ported. Both ordinary and keyed span paths match 240 complete POD 2.8 frames; face dispatch and the roof gaps remain open. Diary
2026-10-25
- Un-POD draws the measured horizon panorama. The race background now sends the measured
build_horizonblock throughdraw_horizonandspan_horizon; the affine sampler is no longer used for race frames. The release probe and horizon tests pass; same-camera parity and roof gaps remain open. Diary - POD's sun flare now draws after the world. The cloud pass places the marker before the horizon, and
pod-renderdraws the dither-off RGB565 flare after world faces when it remains visible. Native tests, the release probe and the WebAssembly check pass; same-camera parity remains open. Diary - POD clouds now render in Un-POD. Both Rust race renderers draw the measured indexed cloud layer under the horizon and world; flat and Gouraud faces also use the measured color drawers. The release probe and focused tests pass; whole-frame comparison and the sun remain open. Diary
- POD's cloud renderer traced. The 16-bit path from track settings through sky clipping and spans is documented; byte-level measurement and the Rust port remain next. Diary
- Rust worktrees audited and formatted. The old worktree changes are reconciled and stale checkouts removed; the release workspace tests and site build pass. Galleria's live AI lane panic and the unverified roof gaps remain open. Diary
- The race screech traced to missing POD events. Car sound slots 8 and 10 still reference absent events 21 and 22; their zero-filled entries start the looped tyre squeal. Un-POD now skips absent car events, with a fresh mix and original-race comparison still to check. Diary
- POD race HUD and CD audio. The default DATA path selects the local POD CUE, and a live one-lap run produces both effects and CD streams. The lower-left damage bars and lower-right radar draw in a fresh frame; the reported sound loop and approximate HUD values still need comparison with POD captures. Diary
- POD renderer stages in pod-render. The clipper, affine fan filler, transform/projection, horizon lists and horizon spans are integrated and pass their measured POD fixtures; the complete frame path remains open. Diary
- Best times, ghost files, team pages. pod-ui reads, updates and writes
RECORDS\*.BRTas POD does (its insertion measured equal under Unicorn), imports and exports.ghtghosts, draws the mirrored track map, menu 21 and menu 60's team pages, and the time-attack pages' pictures. - Ghosts, end pages and the mirror. Time attack's Top 5 ghost panel and
.ghtreader, every time-attack end page drawn, the racer table between runs, and the track screen's mirror withmenu_back. - Time attack in pod-ui. Menu 18's three types (three laps, one lap, ghost race), the race set-up's laps and the time-attack race ends; the ghosts' Top 5 panel is still to come.
- Championships in pod-ui. POD's championship saves, its race-end standings pages and next-track screen, and the custom and random championships, written by unattended API agents and merged into one model. Diary
2026-10-24
- The front end end to end. pod-ui now runs the whole path: the start-up videos, the menus, a single race and its end pages, and a championship from its first race to the ending videos and back to the main menu.
- pod-render in Un-POD.
UNPOD_RENDERER=golddraws the race with Gold's software renderer (filler, spans, shade bands, coverage mask) behind the app's seam. Diary - The videos decode. A clean-room Indeo 4.1 decoder from Intel's own
IR41_32.DLLgives all 13,663 pictures of Gold's six videos byte-identical to Intel's codec under the emulator (pod_video::indeo); GameFrame'sir41_32.dllplays them through Video for Windows, andWINPOD.EXEand the Direct3D builds play the intro with it in the emulated PC (diary, Videos). - A fifth Gold race in the replay.
gold-beltane-full(Beltane, three laps): 23,509 samples, 23,407 order pairs and the final records all match; the player's car stuck again, so still no results screen. - The videos: the player traced, the sound read. WINPOD's Indeo check and AVI player traced, and the six videos' sound decoded (
pod-video); a first Indeo decoder was withdrawn for the clean-room rule, and the format is being specified from Intel's own codec (diary, Videos). - Every build of Gold. All 14 of POD Gold's builds run through the wrappers in the emulated PC: 12 race (software, 3dfx, ATI, S3, PowerVR and their MMX and Maxi Sound 64 variants); the two Direct3D builds draw through Wine's Direct3D but stop when a video plays, for want of Indeo (diary, 3D cards).
- A fourth Gold race in the replay.
gold-factory-full(FACTORY, five laps): all 14,450 samples and 14,285 order pairs match; it was stopped before the player finished, so no results screen yet. - FACTORY races without music. A Gold recording with the CD on its own stream: silence for all 1,596 s, as the track data predicts (diary).
- Gold's 3dfx build on our Glide.
WPOD3DFX.EXEfrom POD Gold races on Beltane throughglide2x.dll(the later Glide 2 calls) at 1280 × 960, with two in-memory patches: the CPU check and a 16-bit-desktop check Wine cannot pass (diary). - PowerVR's own driver read.
SGLMID4.dllfrom Gold's disc settles the SGL stand-in's fog, shading and light-volume placement; the race runs with them. - Gold's race end. The ranking and the all-time best races pages, with the player's tinted bar, match Gold's captures of the Azthec race pixel for pixel; choosing a key in the controls works and is saved to Ubi.ini. 19 Gold captures are now checked.
- The human on the race paths. Gold's per-frame path follower for the player (
FUN_004c688c) ported in pod-ai with the fold search (FUN_004c6854); 20,000 + 5,000 cases match the game under Unicorn, wrong-way bit included. - Props, beacons and the racing line in the editor. Props added and removed (add then remove gives the original on all 44 Gold files with props), beacons and race paths moved; in Un-POD a lifted lap line counts no lap and a moved racing line moves the computer's cars by as much (diary).
- A live race to the results. One lap of Beltane on
--autopilotruns from the disc to the results screen; a stuck-timer bug that kept computer cars reversing is fixed; damage sets and moving props reach the renderer through the seam. - A new car beside the sixteen. The vehicle creator writes a new car as an extras package (
pod-extrasinstalls it, Un-POD races it), edits single vertices, faces and pages from PNG files, and has a panel in the viewer (diary). - Props against walls and each other, and the damage record. The props' last cases match Gold's own code, and the race display's damage record is ported (car physics).
- Controls and graphics options. Gold's device choice, the keyboard's key names and the graphics options match their captures; 17 Gold menu captures are now checked pixel for pixel.
- The polygon filler. pod-render ports Gold's
FUN_004931ec, polygons into span records with perspective edges; 1,500 random polygons match the original byte for byte. Diary - The PowerVR build races. Gold's
WPODPVR.EXEruns a race on Beltane throughwrappers/sglat 1280 × 960 in the emulated PC: light volumes tested per pixel, cars lit by the camera's lamp, the render queue bounded. - The wrappers live in GameFrame. Glide, DirectDraw, ATI3DCIF, S3D Toolkit and SGL, with
mmxandgpu-1997, moved to GameFrame'swrappers/; POD stages them withrun/wrappers/stage.shand keeps only its patch file. - PowerVR's SGL stand-in.
wrapper/sglkeeps the PowerVR build's scene graph and draws it with OpenGL at any size; the build's main menu shows through it; a race waits on the emulated PC. - Props from the disc. The
.env's collidable props are laid out as Gold builds them; Canyon's 20 match the running game; the live race runs the prop collisions. - Canyon's jumps and the track's props. A second Gold race (Canyon, damage on) matches every car step and is followed whole by the port; the props cars knock about are ported and checked in Gold's own code (car physics).
- Gold's garage. The five car settings with their 300-point budget, the hatched star chart, typed values, and the five saved set-ups of
Params\<car>.prbin Gold's encoded format, read and written; the race gets the garage's set-up; it matches Gold's capture (diary). - Three odd fan tracks explained; a gamepad. Tron and Arcade were our
.BL4bug (fixed); Arcade's sunken grid, Beach's start and the empty opponent lists are in the files. A gamepad drives Un-POD natively and in the browser. - The vehicle creator.
pod-viewer caredits a Gold car's parameters, garage settings, torque curve, colours and shape, and writes its.BV3and.BV4byte for byte; an edited GAMMA raced in Un-POD lapped 15 seconds faster (vehicle creator). - The race rules on Gold. Every
pod-racecheck runs on POD Gold 2.8: its functions measured under the game's control word0x027f(the dot product's model corrected), three Gold races replayed, and the order between gates checked against the game's own path state: every change the samples can decide (diary). - Gold's options buttons. Difficulty, damage, volumes, Dolby, intro, stereo and the opponent count work as in Gold, with their Ubi.ini writes (diary).
- Back on the track. The race paths are in Un-POD's disc world as Gold keeps them; a car put back heads along the path, and the cars' trackers start where the original's do.
- Every Gold menu capture matches. All ten captures of the ported menus (main menu, one player, options, both track pages, car, pause, quit warning, records) now match pod-ui pixel for pixel, pointer included. The last differences were the captures' own row 478 and right columns, and Gold's own track-page states.
- A Gold frame replayed. pod-render replays a recorded Beltane frame's 55 span calls: 271,467 of 272,446 pixels match Gold's; the rest are drawn over later by the game. Gold draws at 53-bit FPU precision. Diary
- Gold's car swap screen. The car screen offers only
VOITURES.BIN's eight cars; its "Load new car" button opens menu 25, which trades one for a car ofVOITURE2.BINand writes both lists. pod-ui ports it, so the added cars ofpod-extrasreach the race. - The track editor on Gold. All 66 of POD Gold's track files, the 15 new tracks included, save back byte for byte;
--installputs an edited track (or a new one, with its list row) in a game folder, Un-POD races it with--content, and its physics rides a raised road as the original did (diary). - Cars touch in Un-POD. Each car's drawn object (parts, hulls, health, damaged versions) is built from its car file and matches Gold's running game; the live race runs the collisions and the damage.
- The extra cars and tracks. All 482 files of the download's 101 extra zips now read as the game reads them and write back unchanged; eight are broken and listed.
pod-extrasinstalls them as Ubi Soft's CD Patcher did. POD Gold lists and races them (Beach with the fan car LORIS, in the emulated PC), and so does Un-POD with--content(the extras). - The CD music's start and stop found. The tracks' loudspeakers (
.hp) hold event 20; the "Depart" macro plays them and "FinCourse" stops them, on 29 of Gold's 32 tracks. Un-POD runs both (diary). - Un-POD's cars in colour. The cars drew nearly white: their
.BV3textures are 8-bit with no palette of their own. Un-POD now takes them from the.BV4, a marked deviation until the software build's car palette is traced. - A live race from the disc. Un-POD builds the track world and every race car from the game's files, puts them on the grid and settles them; all eight cars match the original's first step word for word.
--livedrives on any track, natively and in the browser. - Cars touch, and take damage. pod-physics ports Gold's car-to-car collisions and damage; the port follows the whole Gold race by itself, all eight cars, word for word (car physics).
- The renderer's bottom layer.
crates/pod-renderports Gold's renderer tables, shade table, coverage mask and both textured span kinds; under the emulator every byte matches the original (4,000 span lists each). Diary - Gold's options and track pages.
pod-uiports POD Gold's options screen (traced in its executable; matches Gold's capture) and the track screen's page arrows for its 32 circuits. - The menus on POD Gold.
pod-uiruns on Gold in English; its main menu, one-player menu, pause menu and quit warning match Gold's captures exactly. - The race's sound in Un-POD. The engines follow each car's revs and the car code's sounds (brakes, crashes, landings, scrapes) play, through
PoseandGame::take_sounds, as soon as the physics drives the cars; with the replay the engines idle. - A car put back on the track. pod-physics ports Gold's put-back (
FUN_00415730); every one of the Gold race's 8,328 car steps now matches, the player's car followed through the whole race (car physics). - Car physics, Gold only. pod-physics follows POD Gold 2.8 alone; its per-function tests re-captured from Gold's code on the Gold race, 39 functions, every call matching (car physics).
- Gold only. POD Gold 2.8 is the final release and the only version worked on; every Un-POD session moved its defaults, tests and checks to it (diary).
- Moving to POD Gold. Gold's programs exported and matched to the first edition's (273 of 309 names carried), Gold running in English in the emulated PC with its own patches, every reader on Gold's files, and three Gold reference races: Beltane EASY and MEDIUM, and Azthec.
- Car physics on POD Gold. A Gold race recorded from inside the game; with Gold's four differences in the port, all 8,327 car steps match word for word, apart from one step where the game put a car back on the track (car physics).
- pod-sound on POD Gold. Every sound measurement repeated on Gold's EXE: the mixer, the 3D model and the events unchanged; Gold picks the ten mixed channels differently and starts with stereo swapped. pod-sound follows Gold.
- The CD plays in the emulated PC. CDEmu gives the VM a drive with the disc's audio track; the original starts track 2 with a race's countdown, never in the menus.
- The race display from HABI.BIN. Its ten fields and the handlers of each kind traced (
docs/systems/hud.md); Un-POD's HUD drawn from the game's own layout, glyphs and words. - Car physics ported. The physics step and all its callees in
crates/pod-physics; every one of 20,488 car steps of a race recorded from inside the game matches word for word (car physics). - A race heard. The countdown and the engines of a Beltane race, recorded in the emulated PC and replayed through pod-sound from the same race's step log: the six voices at one delay and their own level, the engines changing when the log says.
- POD Gold is the reference. The last version released is the one to match (the user's rule); everything moves to POD Gold 2.8, the first edition kept as documented differences.
- Track, car and pause screens.
pod-uidraws the track screen (title, length, laps, map) and the car screen (picture, garage figures, names) as the original does, with the pause menu's confirmation; 97 captures match.Ui::race_overopens the race's end screen. - POD Gold found. A second disc, POD Gold 2.8 (September 1997): English, 32 tracks, 16 cars, new Direct3D and PowerVR builds, plus updates, fan cars and tracks, and era tools (versions).
- The original heard. PulseAudio in the emulated PC records WINPOD's sound; the menu sound matches pod-sound's with a gain of 1.00006 and 94% of samples within ±1.
- From the menus to a race.
pod-uifollows the single race from "Un joueur" through the race mode, track and car screens toEffect::StartRace, writing the default circuit and car toUbi.ini; the race-mode menu matches its 13 captures (61 in all), and the pause menu opens over the race. - The sound engine in Rust.
crates/pod-sound: WINPOD's mixer, channel calls, 3D sound, events and the Monza engine group, each measured against the original under the emulator and equal sample for sample; CD track 2 from the player's disc image; cpal playback. - The menus, pixel for pixel.
crates/pod-uiports POD's menu engine (keys, mouse, selection, animated outline, fonts, the game's own pointer); the main menu, quit box, help and records pages match 46 frames captured from the original. - The car controllers. The computer's controller and the player's controls are in
crates/pod-ai, matching the original under Unicorn on random states, eight-car races and states read from the running game. The opponents' only chance is the summed frame time (diary). - Un-POD plays a race.
apps/unpodruns the reference race from the countdown to the results screen through the core (crates/pod-game), with a chase camera, a HUD in the game's own font and a probe for agents, natively and in the browser; the results are the original's. - The road to 1:1.
docs/PORT.mddefines a 1:1 Un-POD and lists its subsystems; five sessions started on physics, controllers, the game app, the front end and sound. - The diary dressed like the game. Rust-metal panels with bolts, bevelled plate buttons, stencil headings and the menus' green selection; dark by default (
site/.vitepress/theme). - The order between gates. The computer cars' path tracker and the order update it calls are in
crates/pod-race, matching the original under Unicorn on 20,000 cases each. The replayed reference race shows the game's order in 99.4% of samples (diary). - Sharper scaling for the DirectDraw builds.
wrapper/ddrawshows the frame at the largest whole multiple by default, withDDRAW_FILTER=scale2x(Scale2x) orcrt(scanlines and a column mask) as options (wrapper/scalers, diary). - Diary filled in. Three entries written up from the night: the wall under Rosetta, teaching GameFrame its know-how layer, and how the five overnight sessions built the frame around POD.
- The track editor. The viewer edits tracks behind the
editorfeature: props, a sector's or face's texture, vertices, whole sectors, a smooth raise, lights, undo, save. The window andpod-viewer editmake the same edits; an unedited save is the original on all 36 tracks. A changed texture, a raised road and moved props show in the original game, and the cars ride the new road (diary). - The ATI and S3 builds. Our own
ddraw.dll,ati3dcif.dllandS3DTKW.dll(wrapper/) runWPODATI.EXEandWPODS3D.EXEunchanged to a race, shown at 1280 × 960. Both chips draw only the cars' shadows and light beams; the textured scene is the game's software renderer (3D cards). - The race rules in Rust.
crates/pod-race, Un-POD's first core piece: the clock, the countdown, the gate test, laps, checkpoints, the order at gates, the end and the results. The gate test, order update and time printing match the original under Unicorn on 20,000 inputs each. Replayed from the reference race's positions, it ends with the same records, order and results. A second order update, by progress along the race paths, was found and is next (the race).
2026-10-23
Our own Glide.
wrapper/glide: aglide.dllfor the 3dfx build, on OpenGL at any size.WPOD3DFX.EXEruns unchanged in the emulated PC and reaches a race on Beltane at 1280 × 960; all 47 Glide calls it makes are in 3D cards.The first mods. Every format writes back byte for byte, the whole track included, and four changed files load in the original game from
C:\POD\Data: a string, a menu image, a track texture and a car's grip setting (modding).How a race runs. The race loop, its clock (ms × 65), the countdown, laps and checkpoints run by the tracks' beacon macros, the order, the end and every random draw traced (
docs/systems/race.md); a race of the original recorded from memory, with a reader whose times match the results screen digit for digit.A whole race. POD plays from the menu to the results screen in an emulated x86 PC (QEMU, Debian, Wine 10), driven by a script that reads the cars from memory. Under Wine on the Mac the menu freezes (a WOW64 fault under Rosetta). Next: a wrapper for every build and a mod layer (plan).
North star: play POD. The goal now leads to playing: first the original under Wine made complete, then a playable port in Rust grown from the viewer. Work merges into
mainearly. New target list in the plan.Tracks decoded to the end. All 36 track files read to the end of every entry: animations, sky (horizon, clouds, light sprites), texture animations, race paths per difficulty, the reverse track and the opponents. The viewer shows the sky and plays the animations (diary).
Sound banks and fonts to the last byte. The bank loader
FUN_004c1e48is found; all 28.MEGand 4.BP3files decode and round-trip, with glyph boxes in the viewer. The catalogue reads 230 of 289 files to the last byte: only track and car data are left.Best times and lists.
RECORDS/*.BRT,CIRCUITS.BIN,BETAMNU.BIN,HABI.BINand the music tables decode and round-trip byte for byte; the viewer shows them as tables. All.BI2files decode. The catalogue reads 198 of 289 files to the last byte.The original runs.
WINPOD.EXEplays its demo race in a 640 × 480 window under Wine 11 on macOS, after six patches to a copy (Cyrix port probe, display-mode table overflow, 16-bit desktop, RGB565 back surface).run/wine/run.sh,docs/running.md.Car parameters. Not scrambled: the block follows the car's name. Every field of the
0x558bytes is named from the physics code that reads it (grip, springs, gears, torque curve, steering, brakes, mass), the whole car file decodes to the game's last read, the car lists (VOITURES.BIN, XOR0x68) round-trip, and the viewer shows the table beside the car.Disc images read in place. New crates
disc-image(CUE, BIN, ISO 9660, Joliet) andgame-source(folder, image, a URL with resume and MD5, browser ranges cached in OPFS). All 781 files read fromPOD2_0.BINmatch the extracted copy;pod-viewer --image,?image=and a dropped.cue+.binwork. archive.org downloads send no CORS header.MMX and the 3D cards. The MMX build's 25 routines are traced and matched to the Pentium build; the coverage mask is measured identical. The
.BL4track flags halve texture pages for the 3dfx card, and the extra word per face is a mirror group. New crates:mmx,gpu-1997.Track props, lighting and visibility. All 36 tracks decode past their sectors: which sectors to draw from each, the placed props (cones, drums, signs, a bus) and the lights. The viewer places the props;
rendergains--zoomand--focus.Tracks in 3D. All 36 track files decode to their sectors (1 to 167 per track, up to 6,821 faces); the viewer and
pod-viewer renderdraw them textured. The site now publishes only when started by hand.Cars in 3D. All 18 car files decode to 26 objects each; the viewer draws them textured, on their wheels where the positions decode (2 of 9 cars). The viewer has a command line (
list,info,export,render), and the diary now shows screenshots.Rust libraries and the viewer.
pod-container,pixelsandpod-formatsread every asset kind, tested on all files of the disc; the egui viewer runs on the desktop and in the browser. The diary now groups entries by day, newest first.Sounds and fonts in the viewer. All 28 sound banks decode to 82 sounds (16-bit PCM, with rates, loops and French descriptions) that play in the viewer. The fonts and the menu skin are texture pages; the smoke is a 32-bit BGRA picture.
Plan written. A native and wasm viewer in Rust, reusable format libraries, and a view for every format, including a 3D track viewer: see the plan.
Stills and text decode completely. All 6 video stills (Windows bitmaps behind a small header) and all 12 text tables (four languages, sections of keyed strings). The viewer now shows textures, menu images, stills and text.
Menu images decode completely. All 146
MIMG/*.IMGfiles read to the last byte: a header, 16-byte entries (size, slot, offset, palette), 16-bit palettes and pixels. Reader in the game:FUN_0047a454.345 texture pages in the viewer. Every track, car and chrome file's textures decode for viewing (
viewer/build.py). The 8-bit car palette is still missing.Track layout mapped. Every track has the same ten entries; names use a small XOR cipher of their own.
Block container decoded. 98 files decode and encode back byte-identical.