Skip to content

Repository files navigation

Dungeons of Noudar 3D — Sega 32X port

A port of Daniel Monteiro's MS-DOS dungeon crawler Dungeons of Noudar 3D (BSD 2-Clause) to the Sega 32X, built with Chilly Willy's Sega devkit (the toolchain shipped by viciious/32XDK, the same one Doom 32X Resurrection uses).

The compiled ROM is rom/noudar32x.32x — 512 KB, ready to run in any 32X emulator (PicoDrive, Ares, BlastEm-nightly, Gens/GS...) or on real hardware from a flash cart. A gameplay capture recorded from the automated test harness sits at the workspace root as noudar32x-gameplay.mp4.

gameplay

What it is

The full original game, reimplemented in C on the 32X:

  • all 8 maps, parsed from the original 40×40 ASCII level files, with the original tile property sheets driving wall/floor/ceiling/masked textures
  • the original turn-based rules: damage = attack − defense, monsters act once per player turn and chase along the dominant axis, monks drop the Holy Health when wounded, cocoons hatch into the invulnerable premature Master Demon, spirit generators, ropes and reenforced doors that flood-fill sections of the level open ("You hear mechanisms in action")
  • the original items: Sword of sorrow, Crossbow of damnation (3 bolts a shot, hitscan), Shield of restoration (supercharges the crossbow for +10 damage at 5 power), the Quiver, the Holy Health — and holy soil * that recharges holy items
  • level exits (9 doorways), chapter interstitials, the game-over epilogue and the ending — hero faith and inventory carry across levels
  • all original art: the 32×32 textures and monster sprites, the logo, the Valdés Leal paintings, the 8×8 font, chapter texts

How it renders

A raycaster written for the 32X rather than a translation of the original's polygon rasterizer (see src/render.c):

  • 128×80 internal 8bpp buffer in SDRAM, expanded 2×2 with 32-bit writes to a 256×160 viewport — 30 fps sustained on the master SH-2
  • one DDA per column with the SH-2 hardware divider (39-cycle divides); textured floors and ceilings per cell, animated lava, scrolling cloud sky where the map has no ceiling
  • bars / arches / magic seals / slots are masked billboards collected during the ray walk; monsters, items and blood splats are depth-sorted billboards clipped against the column z-buffer
  • one global 64-colour palette replicated as 4 CRAM shade banks — a pixel is (shade << 6) | colour, so distance fog costs zero per-pixel work — plus full-palette swaps for the damage/heal flashes
  • grid movement is interpolated (⅛ cell, 1/32 turn per frame) so the turn-based game scrolls smoothly like a 90s "free look" crawler

Controls (3-button pad)

Button Action
D-pad ↑ / ↓ step forward / backward (a turn)
D-pad ← / → turn 90° (free)
C + ← / → strafe (a turn)
B use selected item: swing sword / fire crossbow / drink (a turn)
A cycle inventory
Start pick up item underfoot / advance menus

Walking into an enemy also swings the sword.

Build it

./setup.sh      # toolchain -> /opt/toolchains/sega, PicoDrive test core
make            # -> rom/noudar32x.32x
make test       # host rule tests + 12 point-to-point tests on the real ROM

Regenerate src/assets.c from the original assets in res/ with make assets (needs python3 + Pillow).

Layout

Path Role
src/game.c/.h the game rules, a C reimplementation of noudar-core
src/render.c raycaster: walls, flats, sky, billboards, 2× blit
src/hud.c, src/menu.c status panel, log, title/chapter/ending screens
src/main.c state machine, input, test beacon (COMM2 + SDRAM struct)
src/hw_32x.c, src/32x.h VDP init, line tables, flip, pads
src/fixed.c/.h 16.16 fixed point, SH-2 hardware-divider divides
src/sh2_crt0.s, md/ devkit boot code: ROM header, SH-2/68000 startup
src/assets.c/.h generated — palette, textures, font, maps, texts
tools/gen_assets.py asset pipeline (quantize, shade banks, prp parser)
tools/romfix.py pads the ROM, writes the MD header checksum
tests/game_host.c 32 host-side assertions on the game rules
tests/host_render.c desktop oracle: renders the real game off-console
tests/harness.c, tests/run_tests.py headless PicoDrive point-to-point suite

Testing

make test runs two layers:

  1. Host testsgame.c compiled natively with ASan/UBSan; asserts spawns, blocking, rope/door flood-fills, monk drops, cocoon hatching, crossbow ammo math, supercharged shots, pickups, level completion, state carry-over and hero death (32 checks).
  2. ROM tests — the real .32x inside headless PicoDrive; asserts the header/checksum, boot, no-black-screen on three different screens, the title→chapter→play state machine, movement/turn/strafe/turn-economy, a scripted fight that kills the Fallen Hero, smooth-scroll animation, ≥20 fps in the dungeon and HUD chrome — via both framebuffer pixels and a live game-state beacon in SDRAM (12 tests).

Licence

The original game — code and assets — is © 2016 Daniel Monteiro, BSD 2-Clause (see LICENSE-noudar.md); this port keeps that licence for the reimplemented rules and the converted assets in res//src/assets.c. Boot code (sh2_crt0.s, md/*.s) comes from Chilly Willy's freely distributed 32X devkit samples.

About

A W.I.P. vibe-port of Daniel Monteiro's MS-DOS dungeon crawler Dungeons of Noudar 3D (BSD 2-Clause) to the Sega 32X, built with Chilly Willy's Sega devkit (the toolchain shipped by viciious/32XDK, the same one Doom 32X Resurrection uses). Made using Arena.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages