This comprehensive guide covers creating new homebrew games for Nintendo DS, Sega Saturn, Sega Dreamcast, and PlayStation (PS1) that run on emulators. It includes hardware specs, SDKs, build formats, emulator notes (BIOS, settings, compatibilities), debugging, asset pipelines, performance tips, common pitfalls, templates, libraries, licensing, and packaging. We also cover additional retro consoles and provide comparison tables. Citations are included for authoritative hardware and devkit info. Let’s dive deep into the retro console architectures and workflows.
Cross-Console Foundations
The following sections break down each console by hardware and development ecosystem. We also compare toolchains and emulator targets across consoles. The build-and-test workflow for all systems roughly follows:
graph LR; Code[Source Code & Assets] --> Convert[Asset Conversion] Convert --> Compile[Compile & Link] Compile --> Package[Create ROM/ISO Image] Package --> Emulator1[Run in Dev Emulator
(logging, GDB)] Emulator1 --> Debug[Debugging (breakpoints, etc.)] Debug --> Emulator2[Run in Accuracy Emulator] Emulator2 --> Test[Testing & Save States] Test --> Code
This loop is powered by emulators and SDK tools. Popular emulator features used include save states, debug menus, GDB stubs, and memory viewers【17†L0-L4】【6†L3-L11】. Primary sources such as official docs and community guides are cited throughout.
Comparison Tables
| Console | SDK/Toolchain | Output Format | Recommended Emulator(s) | BIOS/Firmware Needs |
|---|---|---|---|---|
| Nintendo DS | devkitARM/libnds, BlocksDS | .nds (ARM9/ARM7 bundles) | melonDS, DeSmuME | BIOS & firmware dumps required for melonDS【17†L0-L4】; no BIOS needed for DeSmuME+ |
| Sega Saturn | yaul/libyaul, Jo Engine | .iso/.cue (Mode2), .bin/.cue | Mednafen (Beetle Saturn), Kronos | BIOS files required (specified names in Mednafen SAT doc)【6†L3-L11】 |
| Sega Dreamcast | KallistiOS (KOS), kos-ports | .cdi, .gdi, .chd, .iso | Flycast, Redream, Demul | Redream uses internal BIOS by default (optional boot.bin for real BIOS)【19†L39-L47】; Flycast supports HLE or real BIOS. |
| PlayStation (PS1) | PSn00bSDK (GCC), Psy-Q (legacy) | .bin/.cue (Mode1/2 ISO); .pbp (PSP format) | DuckStation, PCSX-Redux | BIOS required (e.g. scph5501); not provided by emulators【19†L39-L47】 |
| Additional | see notes | see notes | see notes | varies |
Nintendo DS Homebrew
Hardware Specs & Constraints
The DS has two CPUs: an ARM946E-S at ~67 MHz and an ARM7TDMI at ~33 MHz【15†L0-L2】【21†L3-L9】. It includes 4 MB RAM, 656 KB video RAM (divided into banks A–I), and dual 256×192 screens (top LCD has 4:3 and bottom is touch). The 2D engines handle tilemaps & sprites; 3D is fixed-function via OpenGL-like PSGPU. Audio uses ARM7 and Wolfson codec【15†L0-L2】.
Memory is tightly banked: VRAM is split into 128KB banks A–D, etc., and must be assigned carefully to backgrounds, sprites, textures or framebuffers【15†L0-L2】【21†L3-L9】. The ARM7 has 256KB WRAM. Shared WRAM (32KB) can be switched between CPUs【21†L3-L9】. ARM9 can access the cartridge and much of the hardware; ARM7 handles audio, touch, Wi-Fi, etc【15†L0-L2】【21†L3-L9】.
SDKs & Toolchains
Official SDKs are proprietary, so community toolchains are used:
- devkitPro / devkitARM: GCC-based, libnds library for graphics, libfat/ndslib for file systems, Maxmod for audio【9†L1-L3】【15†L0-L2】. CMake support and example templates exist.
- BlocksDS: An alternative SDK with templates, built on devkitPro. Includes a build system and support for custom ARM7 cores. Documentation covers build process and GDB debugging【13†L1-L9】【17†L0-L4】.
Build Targets & Formats
DS homebrew is distributed as a .nds ROM. Tools like ndstool package two ELF binaries (ARM9 and ARM7) plus data into one NDS file【13†L1-L9】. The header, filenames, icon, and NitroFS (built-in filesystem) are included. On Windows, makerom.exe (devkitPro) or BlocksDS scripts handle this.
Emulator Compatibility
Popular emulators: melonDS and DeSmuME. melonDS aims for accuracy (requires BIOS/firmware dumps). Its FAQ states it needs the DS BIOS and ARM7/ARM9 firmware images from a console for full accuracy【17†L0-L4】. DeSmuME (especially the “dev+” build) is developer-friendly: it can be run with GDB stubs for ARM7/ARM9【17†L0-L4】【25†L1-L4】. No$GBA is another option (but less known for dev).
In melonDS 0.9/0.10, user data placement is identical to hardware, so homebrew works same as on console. Use NTSC or PAL DS BIOS accordingly. melonDS settings allow enabling GDB (break-on-start) and disable speed limiting for debugging【17†L0-L4】.
Debug & Test Workflows
DeSmuME exposes a GDB server for ARM9/ARM7. BlocksDS docs instruct using desmume --arm9gdb 3333 --arm7gdb 3334 and attaching gdb-multiarch【17†L0-L4】. melonDS has an “Enable GDB stub” checkbox (ports configurable) and can break on startup. You load the corresponding ELF symbol files into GDB. Emulators support save states (F1–F8 keys) and input recording for regression tests (record movies).
Asset Pipeline
- Graphics: 2D work is tile-based. Tools like
grit(devkitPro) convert images to tile/palette data. Backgrounds use indexed palettes (4bpp or 8bpp). Sprites (OBJ) also use palettes (or 16-bit direct color). The DS has 9 VRAM banks; allocate banks A-D for BG/OBJ, E–I for textures, etc【15†L0-L2】【21†L3-L9】. Copetti’s DS architecture doc details VRAM mapping【21†L3-L9】. For 3D, textures are 256² or 512² with palettes or 16-bit, loaded into texture memory (banks A-D). DMA should be used for fast transfers. - Audio: ARM7 controls sound hardware. You can stream ADPCM WAVs via ARM7 I2S or use Maxmod to play tracker formats (MOD/XM). Samples are 8/16-bit PCM (32kHz) for background audio. NitinWrites DS audio samples or Nitro Composer FM can be used.
- Other: Sprites support affine rotation/scaling. Palette reuse and tile compression (RLE) optimize VRAM use.
Input Handling
The DS has two D-pads, face buttons, L/R triggers, Start/Select, and touchscreen. ARM7 often handles touchscreen and RTC. libnds provides scanKeys() for digital inputs; keysHeld() to get buttons. Use touchRead() via ARM7 for touch. Be mindful that code on ARM9 must request touch state from ARM7 FIFO. Disable repeated fast polling in debug (DeSmuME can freeze on heavy logging).
Optimization & Memory Management
Focus on minimizing VRAM contention: avoid mapping two engines to same bank. Use DMA for bulk transfers. Precompute math or use hardware div/sqrt on ARM9. Run heavy logic on ARM9 and I/O on ARM7. Consider ITCM (fast CPU RAM) for time-critical loops on ARM9. Keep ARM7 code light (max 96KB WRAM). BlocksDS warns that overloading ARM7 can break Wi-Fi/music if RAM runs out【21†L3-L9】.
Common Pitfalls
- Unallocated VRAM: forgetting to assign banks for textures can cause “nothing appears.”
- Dual-CPU sync: missing memory fences between ARM9/ARM7 (cached writes) can corrupt data.
- BIOS mismatch: using PAL BIOS with NTSC code or vice versa can cause timing issues.
- DSi mode: melonDS requires a full DSi firmware+NAND to emulate DSi; homebrew generally sticks to DS mode.【8†L0-L4】
Sample Template & Libraries
An example devkitPro project has source and include dirs, with a Makefile invoking devkitARM. BlocksDS provides templates with ARM7 cores (e.g. dswifi). Key libraries: libnds for graphics, Maxmod for audio, and libfat for FAT filesystem. Sample projects: the examples folder in libnds repo; BlocksDS GitHub.
Licensing & Distribution
devkitPro libraries are open source (MIT/GPL). Maxmod is MIT. The Nintendo firmware (BIOS/firmware) is copyrighted – DO NOT distribute it. Recommend users dump their own (e.g. using Caetla)【19†L39-L47】. Homebrew games on DS typically distribute the .nds (legal as fanworks, but note any copyrighted media). Trademark “Nintendo” usage should comply with fan-art rules.
Emulator Installation & Setup
melonDS: Download, unzip, configure BIOS/firmware (place bios7.bin, bios9.bin, firmware.bin in config dir)【17†L0-L4】. Enable “GDB stub” under Config > Emu Settings for debugging. Use 2x/3x scaling for crisp visuals.
DeSmuME: Get the latest dev build (e.g. from GitHub). Ensure “DSi mode” is off unless you have DSi files. It auto-scales to 2x by default. Under Debug > Options, enable console log and GDB port.
Community Links
- devkitPro DS Wiki
- libnds (Nintendo DS library) documentation
- GRIT image converter
- GBAdev (active DS forums)
- GBATemp DS Homebrew
Sega Saturn Homebrew
Hardware Specs & Constraints
The Saturn has dual Hitachi SH-2 CPUs at 28.63MHz each【19†L132-L140】【19†L148-L156】, plus a custom SCU DMA/DSP coprocessor. It includes 2MB main DRAM (split as 1MB @WRAM-H fast, 1MB @WRAM-L), 1.5MB video RAM, 512KB sound RAM. Graphics: VDP1 (sprite/quads to framebuffer, 2D) and VDP2 (background planes, hardware scrolling/rotation) operate concurrently【19†L198-L207】【19†L217-L225】. The SCU DSP aids 3D geometry (matrix multiplies) and has 32KB SRAM. Saturn is an “octopus” architecture of subsystems (CPU, Video, Audio, CD) on separate buses【19†L150-L158】.
Memory access is complex: the two SH-2s share an external bus, prone to contention【19†L132-L140】. VDP1 VRAM (1MB) is split for frame buffers, textures, and CLUTs. VDP2 has its own 1MB VRAM for tilemaps and planes【19†L215-L224】. No hardware depth-buffer (developers must sort polygons). Sequential page-flipping is common due to VRAM.
SDKs & Toolchains
- yaul/libyaul: Open-source Saturn SDK (MIT). Uses modern GCC (sh-elf) via crosstool-ng; provides C libs for VDP1/VDP2 control, MIDI, etc. Offers build scripts (Windows/Linux)【7†L0-L3】. Example:
examples/yaulshows drawing sprites. (GitHub: yaul-org/libyaul) - Jo Engine: C library/engine (MIT) simplifying Saturn development. Includes scene graph, image loading, map editors【7†L5-L8】. Its GitHub includes templates and documentation for asset pipelines (BIN, TEX). Jo downloads include SSF & Yabause for testing【7†L7-L11】.
- Saturn SDK (retro): Official Sega SDK is proprietary. Older SGL (Sega Graphics Library) etc. Homebrewers avoid these due to NDAs.
Build Targets & Formats
Saturn homebrew is typically built into a CD-ROM image. Yaul’s makefiles generate a .cue with Mode 2 Form 1 data track containing the binary. For example, running make cd might produce project.cue and 0.bin. Mednafen can load this .cue directly. Multidisc games use an .m3u playlist (Mednafen doc on multi-CD support【18†L167-L174】). Redump-compatible .BIN/.CUE or .CCD/.IMG are safest per community norms【1†L6-L9】.
Emulator Notes
Key Saturn emulators: Mednafen (Beetle Saturn core), Yabause/Kronos, SSF. Mednafen’s Saturn doc lists required BIOS: saturn_bios_US.bin, etc.【6†L3-L11】. Without proper BIOS dump, games won’t boot. Kronos (RetroArch) notes limitations: CUE sheets cannot reference compressed audio tracks【17†L0-L4】. Use Redump-format images to avoid quirks【17†L0-L4】. Set emulator region to match your BIOS (NTSC/PAL). Save states and rewinds are available in Mednafen.
Debugging & Testing
Saturn devs often rely on logging (print text via VDP1) and timing checks. Mednafen’s debugger (Alt+D) offers memory view and breakpoints at any address【18†L167-L174】【18†L169-L177】. Core-specific debugging is limited; Yabause/Kronos lack built-in debuggers. Workaround: simulate on PC by instrumenting code with semihosting or scpc headers for output.
Asset Pipeline
- Graphics: VDP1 uses 4-vertex sprites/quads. All textures are *tiles* of up to 1024x1024, usually 4bpp (16-color) or 8bpp. Color lookup tables (256 colors) are in VDP2. VDP2 uses tilemap layers up to 2048×2048 with 15-bit palettes【19†L198-L207】. Popular formats: 4bpp/8bpp BMP/TGA converted to raw tiles; Jo Engine documentation shows using BIN files for sprites and TEX (texture) for backgrounds.
- Audio: SCSP sound chip: 8 channels of ADPCM. Samples are 8-bit or 16-bit PCM (16kHz-44kHz), stored as VN (PCM) or AV (ADPCM) in VGM/SCSP formats. Tools:
vgmtoolsto convert to VAG format, or libyaul’s sound libs for streaming. - Tools: SAM2 updates (Jo example) can convert maps/sprites; SAGOLib for image packing. Some use
crunchfor Run-Length Encoding of tile data.
Input Handling
Saturn controllers: typically digital pad. Jo Engine provides input via its API (jo_pad_read()). Mednafen’s Saturn core allows keyboard/joypad mapping in config. For analog Saturn pads (Saturn Virtua Pad), custom code is needed. Multi-tap adapters are supported by some emus; ensure port and device settings in emulator menus.
Optimization & Memory
Minimize CPU bus contention: split workloads carefully between SH2s. Use DMA (SCU) for big data moves. Use frame buffering to avoid stuttering. Copetti notes that drawing to screen is expensive on VDP1; use double-buffering and hide drawing behind layers【19†L206-L215】. Exploit VDP2 for backgrounds to offload VDP1. Jo Engine examples draw simple backgrounds in VDP2 and moving sprites in VDP1 to maximize throughput.
Common Pitfalls
- Forgetting VDP2 scroll windows: missing panoramas.
- Not handling palette banks: incorrect colors if CLUT offset is wrong.
- Running out of command list (VDP1 list size 5120 bytes limit).
- BIOS mismatch: Saturn expects
IP.BINin sector 0; if manually making ISO, ensureIP.BINis included as first file【7†L7-L11】. - Multi-CD: forgetting
.m3ufor Panzer Dragoon Saga. (RetroArch Kronos requires .cue in folder with .bin per disc【27†L7-L15】.)
Sample Template & Libraries
Use yaul’s sample project structure: put source in src/, use provided Makefiles. You can copy and modify examples/yaul from the libyaul GitHub. Libraries: libyaul API, libm (math), jo_controllers (for Jo Engine). Jo Engine repo includes sprite and image loading utilities. Community code: libyaul on GitHub, Jo Engine site with downloads and docs.
Licensing & Distribution
yaul and Jo Engine are MIT-licensed. Saturn BIOS is copyrighted – only use dumps from your console. Homebrew games can be distributed freely, but beware Sega’s trademark on console name/images. Avoid including arcade ROM content due to IP. Many Saturn homebrew are shared via SegaXtreme forums and GitHub.
Emulator Packaging & Setup
Place BIOS files (bios_CD_E.bin etc.) in Mednafen’s firmware directory (or same folder as EXE)【6†L3-L11】. To load, drag the .cue onto mednafen or use “Load” menu. For multi-disc, create an .m3u with each .cue file on a new line【18†L167-L174】. In Kronos/RetroArch, enable “Force HLE BIOS: Disabled” and supply real BIOS for accuracy, unless using HLE mode. Save-state hotkeys (F5–F7) work for Saturn games as in other Mednafen modules.
Sega Dreamcast Homebrew
Hardware Specs & Constraints
Dreamcast’s CPU is a 32-bit Hitachi SH-4 at 200MHz【21†L11-L13】 (1.4 GFLOPS). Graphics are powered by a PowerVR2 “Tile Accelerator” GPU (VGA output, 640×480)【21†L1-L4】. RAM: 16MB 100MHz main, 8MB video, 2MB sound. Sound: 67MHz SH-4 DSP (AICA with 10MB sample RAM). Input: 4 Maple ports, VMUs.
Key feature: tile-based deferred rendering. The GPU divides the screen into 32×32 tiles, bins geometry into these, then renders tiles with hidden-surface removal in hardware【21†L1-L4】. No Z-buffer is exposed to the developer; think in quads and reduce overdraw. Textures: best in PVRTC (PVR) format with VQ compression to save VRAM (textures > 32×32 are compressed by hardware). Use 16-bit RGB or ARGB for textures.【21†L1-L4】【17†L55-L60】
SDKs & Toolchains
- KallistiOS (KOS): Primary community OS/SDK (GPLish license with commercial clause). Includes libdcl, math, input, graphics, audio, file I/O. Comes with gcc toolchain builder for Windows/Linux. KOS Wiki is main reference【14†L11-L15】. Many homebrew games use KOS.
- kos-ports: Additional libraries (SDL, OpenGL ES2, libpng/jpg, Ogg Vorbis, etc.) ready for KOS【14†L9-L17】. Useful for richer assets.
- Alternative: Phantasy Star Online engine leaked docs (public domain?), but rarely used due to complexity.
Build Targets & Formats
Dreamcast homebrew typically uses .cdi (DiscJuggler), .gdi (GDI format descriptor), or .chd. KOS projects often produce an ELF or BIN and include ip.bin/1st_read.bin in a CD image. Standard method: create a CD-ISO with KOS Makefile, then use cdi4dc to scramble and produce a .cdi (self-boot)*. Alternatively, run dcload-server to load the ELF directly over network for testing.
*Dreamcast uses a proprietary “MICRO” address scrambling; cdi4dc from KOS handles it automatically. Dreamcast GD-ROM is 1GB; CDI shrinks it to 700MB by recompressing – however, CDI compression can alter code/data, so some homebrew builds skip CDI for safety【19†L55-L60】.
Emulator Compatibility
Leading emulators: Flycast (libretro), Redream, Demul, Reicast. Redream official FAQ says it runs GDI, BIN/CUE, CHD or CDI, but strongly advises against CDI due to compression issues【19†L55-L60】. CHD (MAME format) is lossless and recommended for archival. Flycast and Redream have built-in HLE BIOS but can use real BIOS (boot.bin) if placed in app dir【19†L39-L47】. Emulation is good, but some KOS-specific quirks may exist (e.g. vector units timing).
Debugging & Testing
KOS and dcload provide robust debugging: use dc-tool or dcload-ip to boot game and start GDB stub【12†L0-L8】【12†L9-L13】. Connect with sh-elf-gdb to port 20000 (or default) and set breakpoints in your code. The console prints (via kprint()) appear in dcload logs. Emulators: Flycast has a console for logging. Save states are supported (F3/F4 in Flycast). Demul also supports breakpoints via the DC-TM. KOS performance counters can profile hot code on real hardware.
Asset Pipeline
- Textures: Dreamcast’s GPU expects
.pvrformat. UsePVRTexToolor KOS’svqencto compress 24-bit images to 16-bit + VQ blocks. E.g. PNG→PVR. KOS utilities page mentions using VQPNG for lossless. Avoid NPOT textures by padding; max size 1024×1024. - Audio: AICA sound uses ADPCM. Tools:
wav2adpcmfrom KOS (converts WAV to NVA14 format), or use Ogg Vorbis streamed via kos-portslibvortice. KOS supports playing .raw PCM too. - Other: KOS has PNG/JPG loaders (kos-ports), helpful for UI assets. For maps/sprites, developers port PC tools or use homebrew editors.
Input Handling
Dreamcast controllers are recognized by KOS via maple_button_status(). Standard mapping: arrows + A/B/C/X/Y/Z, with analog triggers. Emulators map to keyboard/gamepads; Redream default keys are WASD + others. Ensure correct controller port selection. VMU use requires emulator support; devs often ignore VMU in homebrew.
Optimization & Memory
Minimize video RAM transfers: update only changed textures/polys. Use pvr_mem_malloc() to manage VRAM. Align geometry to 32×32 tiles. Optimize by using hardware edge antialias (PVR supports it) but turn off if not needed (it costs cycles). CPU: use SH-4 FPU and SIMD carefully (precise data alignment). KOS supports threading on SH-4’s four SIMD units via SIMD intrinsics. Avoid heavy divisions in main loop.
Common Pitfalls
- CD scrambler: forgetting
ip.binor using wrong1st_read.binwill fail to boot on emu/hardware. KOS Makefile handlesIP.BINgeneration【7†L7-L11】. - Using CDI: as Redream warns, CDI altering code can crash. Use GDI+CHD instead for pure accuracy.
- Non-optimized textures: 32bpp PNGs will perform badly. Always convert to 16bpp PVR with VQ.
- Video timing: complex fill rates. Use
pvr_wait_ready()to sync before uploading textures.
Sample Template & Libraries
KOS has a dreamcast-kos-template on GitHub. It includes a Makefile and example code that draws a triangle. Libraries: kos core (math, dc), kos-ports for image/audio, SDL_DC for SDL apps. Check KallistiOS GitHub and dreamcast.wiki for samples and documentation. KOS forums and DCEmulation are rich community hubs.
Licensing & Distribution
KOS is BSD/GPL (check version). kos-ports libs carry their own licenses (e.g. SDL is zlib-like). Dreamcast BIOS is copyrighted; do NOT distribute it. Homebrew can distribute CDI/GDI files (game code) freely. Many homebrew use the term “Homebrew.” Commercial releases (like indie Dreamcast games) have occurred under disclaimers (no Sega license) but are rare.
Emulator Packaging & Setup
Flycast: Zip-download, no install. Place BIOS (if used) as boot.bin in working dir for boot menu. Redream: also self-contained, uses internal BIOS by default【19†L39-L47】. To run: add game folders in UI or launch via command line flycast.exe /path/to/game.cdi. CHD files: Redream and Flycast support them; M3U playlists work for multi-disc.
dcload: For development, run dcload -g -x game.elf to send code to DC (physical or emulator). Set GDB to port 2159 for Flycast in libretro.
Key emulator settings: Use "Skip BIOS" to load directly into game, enable rounding of upscaling (integer scale) for pixel art.
PlayStation (PS1) Homebrew
Hardware Specs & Constraints
The PS1 uses a 33.8688MHz MIPS R3000A CPU and a GPU with 1MB VRAM【21†L3-L10】. Sound: 24-channel SPU with 512KB RAM. Memory: 2MB main, 1MB VRAM, 512KB SPU. No hardware Z-buffer – uses a manual ordering table for 3D render order【21†L3-L10】. Textures are tiles (MT 256×256 max). The geometry engine (GTE) does fixed-point transforms and lighting. Model vertices must fit transformed 16-bit range; large models often break.
Development must manage small RAM: code+data must fit 2MB. Typical pipeline uses CD streaming; less code/data must remain in RAM. CLUTs: 256-color palettes may be uploaded (16 or 256 entries). VRAM also holds 64-bit frame buffer and possibly double-buffering.
SDKs & Toolchains
- PSn00bSDK: Main open-source SDK (ISC license). Includes
psx-gcc(MIPS32 gcc), libraries for GPU, GTE, CD, SPU, controllers. Also includesmkpsxisofor ISO and asset converters (TIM, ADPCM)【15†L0-L2】. - PsyQ: Sony's old dev kit (Proprietary); out-of-scope for open homebrew.
- PSXSDK: Another open kit based on GNU tools (older).
- Popular example codes: „Hello world“ consoles, insect dance demos in PSn00b repo.
Build Targets & Formats
PS1 homebrew is usually distributed as .bin/.cue files for the disc (Mode 2 Form 2 with XA ADPCM audio optional). The mkpsxiso tool from PSn00bSDK creates a .bin data track and .cue sheet. For CD-DA tracks, cues reference .wav files. PS1 executables can be in PS-EXE format (PS1 EXE header) or raw .EXE with relocation; mkpsxiso can wrap either.
Emulator Notes
Key emulators: DuckStation, PCSX-Redux, Mednafen PSX, ePSXe (for completeness). DuckStation (GPLv2) is recommended for accuracy; it requires a BIOS (e.g. scph5501.bin) and will not boot games without it (legal reasons)【19†L39-L47】. PCSX-Redux has integrated cheat/debug support. Mednafen’s PSX core is good for input logging. Warmup tip: disable frame limit in emus to test speed. If issues appear, test in multiple emulators to isolate emulator bugs.
Debugging & Testing
PCSX-Redux supports a GDB stub and on-screen logging【17†L0-L4】. One can compile PSX code with -g, then in PCSX-Redux enable the debugger (in core options) and attach GDB. Alternatively, psx-gdb target (deprecated) can be used. DuckStation has a built-in debugger in newer builds (enable in settings). Mednafen PSX supports stepping through code (see Mednafen docs). Save states and movie recording exist (F1-F5). For tile/sprite issues, use memory viewers.
Asset Pipeline
- Textures: The TIM format is standard. Tools like
tim2rgbaand GIMP plugin (file>export as TIM) exist. PSXSPX docs detail TIM structure (palette + tiles). TIMs support 4bpp (16 color) with optional CLUT, 8bpp (256 color), or 15-bit RGB with no CLUT【15†L0-L2】. Typically we use 4bpp for sprites to save VRAM. - Audio: SPU uses ADPCM. Commonly use .XA (ADPCM) for CD streaming music; toolchain has
xa_adpcmconverters. For sound FX, use SPUADPCM (each sample looped or one-shot). PSn00bSDK includes example loaders for XA and SPU. - Others: PlayStation uses pattern tables (like old SNES char sets). Sprites and tiles are 4bpp with CLUT. You pack sprite sheets (4-bit plane) via
img2sifor similar, then useVSyncFIFOto blit.
Input Handling
PS1 controllers: digital (D-pad, buttons) plus analog sticks (DualShock). Devkits provide pollController() or BIOS syscalls. Homebrew often uses BIOS int 0x1B/0x1C for pad. Two players on separate ports. Emulators map keys by default (DuckStation: arrow keys = left pad, etc.). Allow customizing in game options. Analog values range -128 to 127.
Optimization & Memory
PS1 is limited by memory and no Z-buffer. To avoid “polygon jitter,” implement painter’s algorithm well (sort by depth, possibly split polygons). Keep polygon count low. Use fixed-point for all math (GTE helps), avoid division. Double-buffering the frame (swap VRAM) reduces tearing. Streaming from CD: use the CD sector read interrupt (async) or use CDDA tracks carefully. Most textures should be ≤256×256 due to VRAM constraints (1MB total).
Common Pitfalls
- Forgetting
gsu.ordering-table: causing flicker (lack of depth sort)【21†L3-L10】. - Using Mode1 sectors for audio tracks (PX1); use Mode2 XA for ADPCM and Mode1 for CD-DA.
- Not including
#includefor BIOS calls. - Library confusion: many PSX libs assume PS-EXE format; mixups can cause boot failures.
Sample Template & Libraries
PSn00bSDK provides a CMake-based template. Basic steps: create CMakeLists.txt, place code in src/, run make. The SDK also provides bin2cue to pack raw BIN to cue. Key libraries: libgte, libgpu (for drawing), libcd, libspu. Example repo: PSn00bSDK on GitHub with “template” and examples.
Licensing & Distribution
PSn00bSDK is ISC-licensed. GTE/GPU libs often use MIT. The PSX BIOS (SCPH-7000 series) is copyrighted (owned by Sony) – do not distribute it. Game code (homebrew) can be freely shared. Some homebrew developers use the #homebrew label. Music and assets must be original or cleared (CD-quality audio is possible).
Emulator Packaging & Setup
Put BIOS (e.g. scph5501.bin) in emulator BIOS folder. For DuckStation, set BIOS in system settings (it expects "USA" or region-named file)【19†L39-L47】. Load the .cue file via “Load Content.” In RetroArch Kronos, “Force HLE BIOS” should be disabled to use real BIOS. Multi-disc games: use .m3u lists (DuckStation supports .m3u for multi-ISO). Recommended settings: 2x resolution, disable smoothing for pixel art, enable compiler recompiler for speed.
Other Retro Consoles (Summary)
We briefly cover additional consoles and their emulator homebrew scenes:
- Nintendo Entertainment System (NES): NESASM or cc65 toolchains; output
.nes(iNES format). Emulators: FCEUX, Nestopia. Community: NESDev Wiki. - Super Nintendo (SNES): PVSnesLib (C compiler); output
.sfc(LoROM/HiROM). Emulators: bsnes, Snes9X. Community: SuperFamicom.org. - Sega Genesis: SGDK (C, GCC m68k); output
.bin. Emulators: Genesis Plus GX, Kega Fusion. Community: Sega Retro, SGDK docs. - Game Boy/Game Boy Color: GBDK-2020 (SDCC, C); output
.gb/.gbc. Emulators: BGB, mGBA. Community: GBDev. - Game Boy Advance: devkitARM (C, gcc-arm); output
.gba. Emulators: mGBA, NO$GBA. Community: GBAdev forums. - Nintendo 64: libdragon (C, gcc-mips); output
.z64/.n64. Emulators: Project64, Mupen. Community: libdragon. - PlayStation 2: PS2SDK/ps2toolchain (C/C++, GCC); output
.elfor DVD ISO. Emulators: PCSX2. Community: PS2DEV GitHub. - GameCube/Wii: devkitPPC (C/C++); output
.dol/ISO. Emulators: Dolphin. Community: devkitPro Wii line, libOGC. - PlayStation Portable (PSP): PSPSDK (C/C++); output
.pbp. Emulators: PPSSPP. Community: PSPDev.
Resources and Links
- RetrogamePrices.com (retro dev blog)
- ROMHacking.net (homebrew tools wiki)
- AssemblerGames (homebrew community)
- RGBDS/NES Dev
- Console Modding Wiki
- Mednafen Documentation
- PlayStation Homebrew