[AI] HexGL for Sega 32X
- physical : no
- rom : yes
- licensing : unlicensed
- code : hexglforsega32xbyharoldook
- Date(s) : 2026
- Tag(s) : 3D, Sci-fi, sega-32x, Generative AI used
- By(s) : haroldo-ok
Data retrieved from haroldo-ok.itch.io
HexGL for Sega 32X by haroldo-ok
- title : HexGL for Sega 32X by haroldo-ok
- status : Released
- tags : 3D,
Sci-fi,
sega-32x
- ai : AI Assisted, Code
- last updated : 2026
- by : haroldo-ok
- code : hexglforsega32xbyharoldook
Github repo: https://github.com/haroldo-ok/hexgl-32x
HexGL 32X
A SEGA 32X port of the anti-gravity racing game HexGL (BKcore's WebGL/three.js racer), rebuilt from scratch in C for the 32X's SH2 processors. This is real 3D, not pseudo-3D: the renderer runs a full polygon pipeline — world → view transform with an orthonormal camera basis, near-plane clipping, perspective projection and scanline polygon rasterisation — into the 32X VDP's 8bpp packed-pixel framebuffer.
The 32X boot architecture (ROM header layout, Mars module header, master/slave SH2 startup, 68000-side program) follows the approach used by the Doom 32X Resurrection project (viciious/d32xr) and Chilly Willy's 32X devkit (viciious/32XDK); the toolchain is the one from the 32XDK releases.
Original source: https://github.com/BKcore/HexGL
Game
Anti-gravity ship with thrust (B/C), manual boost (A, costs shield), air-brake style steering (D-pad), banking camera
Three circuits, compiled from section lists like real racing tracks (straights / sweepers / chicanes / hairpins / climbs), with banked corners and per-track themes and backdrops:
NEON CITY - dusk skyline, stars, lit tower windows, chicane + harbor hairpin (patterned after the feel of the original's city circuit)
SKYBRIDGE - bright high-altitude speedway, wide and fast, big bridge climb
RED CANYON - narrow technical desert run between sunset mesas, linked S-curves and two hairpins
Circuit select on the title screen (D-pad left/right)
Textured in the style of the original: hex-tiled track surface with glowing cyan edge strips and lane dashes, animated boost-pad chevrons that crawl toward the ship, tech-panel walls with light strips and hazard chevrons, checkered start/finish line. (HexGL's own art assets are licensed non-commercial, so all textures here are original, generated procedurally by tools/gen_textures.py in the original's visual style.)
3 timed laps, per-lap and total times, lap board on the finish screen
Wall scraping drains the shield; empty shield destroys the ship (START to retry)
Full game flow: title → countdown → race → results
PWM sound effects synthesized on the slave SH2: speed-tracking engine (two detuned oscillators), boost layer, wall-scrape noise, countdown beeps + GO, lap chime, explosion, menu click
Renderer notes
Polygons are rasterised scanline-by-scanline into the 32X packed-pixel framebuffer. Textured quads use affine UV interpolation per span (the track is finely segmented, so the affine error stays negligible - the classic 32X-era approach). Distance shading is baked into the palette layout: each texture ramp occupies a 16-colour block, and the fill loop scales the low nibble by the shade factor, so texel lookups and fog come out of the same table. Beyond ~16 segments ahead, quads fall back to flat shading (they're only a few pixels tall there), keeping the frame rate up.
Layout
src/ SH2 (master CPU) side: crt0 + the game in C crt0.s ROM header, Mars header, SH2 entries and vector tables sega_startup.inc mandatory SEGA 32X boot/security block (from the official devkit; required by the adapter on every cartridge) mars.h 32X hardware registers fixed.h 16.16 fixed-point math, vectors, sine LUT render.c/h true-3D software renderer + 2D HUD overlay track.c/h circuit compiler: section lists -> banked 3D loops, 3 tracks with per-track visual themes game.c/h ship physics, laps, shield, game flow scene.c track/ship/HUD/title drawing main.c master SH2 main loop (60Hz ticks clocked by 68000 vblank) sound.c/h PWM sound synthesizer (runs on the slave SH2, ~22 kHz) src-md/ 68000 side: MD VDP init, pad reading, vblank heartbeat tools/ table/texture generators, ROM padding/checksum fixer ldscripts/ SH2 linker script (ROM @ 0x02000000, SDRAM @ 0x06000000) tests/ automated emulator test harness (PicoDrive libretro core) build32x/ build output hexgl32x.32x the compiled ROM (also at build32x/hexgl32x.32x)
Building
Requires Chilly Willy's Sega devkit (sh-elf + m68k-elf GCC 12.1) in /opt/toolchains/sega — from the viciious/32XDK release chillys-sega-devkit-20220418-opt.tar.zst — plus python3.
make # produces hexgl32x.32x make test # builds + runs the automated emulator tests
Automated tests
tests/test_rom.c loads the PicoDrive libretro core (cycle-accurate-ish 32X emulation with both SH2s, the 68000, and the 32X VDP), boots the ROM headlessly, scripts pad input and asserts:
T1
SH2 C code entered (COMM0 magic handshake)
T2
32X VDP left blank mode — display actually enabled
T3
T4a/b
SH2 game loop and 68000 loop heartbeats advance at ~60Hz
T5
title screen state reached
T5b
circuit selector cycles tracks (COMM14 telemetry)
T5c
each circuit renders a distinct scene
T6a/b
START → countdown → race transitions
T7
holding thrust moves the ship along the track (segment telemetry)
T8
steering changes the rendered image
T8b
texture detail visible on the track (colour-transition density in the road area)
T6c
countdown beeps audible (peak amplitude of emulated PWM output)
T10a
engine audible while driving (audio RMS over 2s of PWM output)
T10b
engine volume tracks speed (idle RMS vs full-throttle RMS)
T9a
60 seconds of scripted play with zero black frames
T9b
continuous track progress the whole time (multiple laps)
T9c
game still in a valid running state at the end
What it proves
no black screen: rendered frame has ≥8 distinct colours and >5% lit pixels
The game exposes telemetry to the tests through the 32X COMM registers: COMM0 boot magic, COMM2 SH2 tick counter, COMM8 pad state (68000→SH2), COMM10 68000 vblank counter, COMM12 game state/lap, COMM14 track segment.
tests/test_tracks.c additionally boots a fresh emulator per circuit, selects it on the title screen, and races it for 20 seconds asserting race state, continuous progress and zero black frames - so every shipped track is proven playable end-to-end.
Screenshots of the emulator output are saved to tests/screenshots/ during the test run. A 14-second capture of the emulated PWM audio (countdown, engine spool-up, wall scrape, boost) is in tests/audio_sample.wav.
Sound architecture
The slave SH2 - idle until now - runs slave_main() (src/sound.c): it polls a sound-state word the master publishes in COMM4 each tick (engine speed, boost flag, scrape flag, one-shot event + sequence number) and renders ~22 kHz audio into the 32X PWM FIFOs. The synth uses only stack locals and const ROM tables, so it is immune to the master clearing .bss during startup. One-shots are edge-triggered via a 3-bit sequence counter, so repeated events (e.g. three countdown beeps) are never missed or double-fired.
Controls
B / C
thrust
A
boost (uses shield)
Left/Right
steer
Down
brake
Start
start / restart
Action
Credits & licenses
Game concept: HexGL by Thibaut Despoulain (BKcore), MIT license. All 32X code here is an original reimplementation.
Boot architecture reference: d32xr / 32XDK (Chilly Willy, viciious).
sega_startup.inc is the standard SEGA-mandated 32X cartridge boot block distributed with the official development kit.
Test emulator: PicoDrive (notaz, irixxxx), MAME license.
Screenshots