# Architecture ## Platform abstraction Every subsystem that differs across platforms (display, input, asset loading, save, time, network, log) follows the same pattern: 1. `src/dusk//platform.h` — included by the public header. Contains `#include "path/to/platform-specific-header.h"` resolved by the build system include path. 2. `src/dusk{platform}//platform.h` — the actual platform-specific header included above (e.g. `src/duskgl/display/framebuffer/framebufferplatform.h`). 3. The shared header (`src/dusk//.h`) `#error`s at compile time if the platform doesn't define the expected macros/types. The active platform backends are selected by `DUSK_TARGET_SYSTEM` in CMake, which includes `cmake/targets/.cmake`. That file sets compile definitions (`DUSK_LINUX`, `DUSK_SDL2`, `DUSK_OPENGL`, …) and links platform libraries. Platform source directories: - `src/duskgl/` — OpenGL rendering (used on Linux and as the GL layer for SDL2) - `src/dusksdl2/` — SDL2 window/input/time (Linux desktop) - `src/dusklinux/` — Linux filesystem/save/network - `src/duskdolphin/` — GameCube & Wii (GX renderer, libogc) - `src/duskpsp/` — PSP (GU renderer, PSPSDK) - `src/duskvita/` — PS Vita ## Subsystem lifecycle All subsystems follow `init → update (per frame) → dispose`. Engine initialization order matters and is centralized in `engine.c`: ``` systemInit → timeInit → consoleInit → inputInit → assetInit → localeManagerInit → displayInit → uiInit → uiTextboxInit → cutsceneInit → rpgInit → networkInit → sceneInit ``` Dispose runs in reverse. Each call uses `errorChain()` to propagate failures. ## Error handling Functions that can fail return `errorret_t` (a code + pointer to thread-local error state). Three core macros: ```c errorThrow("message %s", arg); // sets error, returns from current function errorChain(someCall()); // if someCall() fails, propagates and returns errorOk(); // returns success ``` Check with `errorIsOk(ret)` / `errorIsNotOk(ret)`. The error state carries file/function/line info for a stack-like trace. ## Fixed-point math `fixed_t` is `int32_t` with Q24.8 format (8 fractional bits, ~0.004 resolution). Use it for all world/game values: ```c fixed_t x = FIXED(1.5); // compile-time literal fixed_t y = fixedFromI32(3); // runtime conversion fixed_t z = fixedMul(x, y); // arithmetic float_t f = fixedToFloat(z); // only where float is needed (e.g. GL uniforms) ``` ## Code generation from CSV Several subsystems define their data in CSV files and have corresponding Python tools that generate C headers at build time (via CMake `add_custom_command`): | CSV | Tool | Output | |-----|------|--------| | `src/dusk/input/input.csv` | `tools/input/csv/` | input action enum + names | | `src/dusk/display/color.csv` | `tools/color/csv/` | color constants | | `src/dusk/rpg/item/item.csv` | `tools/item/csv/` | item enum + metadata | | `src/dusk/rpg/story/storyflag.csv` | `tools/story/csv/` | story flag enum + initial values | Generated headers are written to `build-/generated/` and included via `target_include_directories`. ## Asset system Assets are packed into `dusk.dsk` (a zip archive) at build time from the `assets/` directory. At runtime `asset.c` opens the archive and serves files from it. Loading is asynchronous: `assetLock()` registers a load request; the background thread calls the appropriate loader; call `assetRequireLoaded()` to block until ready. `assetUnlock()` / `assetUnlockEntry()` releases the entry so it can be reclaimed. Loaders are registered per type (`assetloadertype_t`) and live under `src/dusk/asset/loader/`. Platform-specific asset init (finding the .dsk file) is in `src/dusk{platform}/asset/`. ## Display subsystem The display system is currently organized around immediate GPU-style rendering: `mesh_t` (vertex buffers), `shader_t` (GLSL on GL / TEV state on Dolphin), `texture_t`, and `framebuffer_t`. See [display-refactor.md](display-refactor.md) for the planned move to a render-queue model (needed for a future Saturn port). The `spritebatch_t` (`display/spritebatch/`) accumulates 2D quads and flushes in batches — the primary 2D drawing primitive used by the RPG layer.