Files
dusk/.claude/platform-linux.md
T
2026-06-16 10:15:59 -05:00

4.1 KiB

Platform -- Linux and Knulli

DUSK_TARGET_SYSTEM: linux / knulli
Source layer: src/dusklinux/
Renderer: OpenGL (Linux) / OpenGL ES via EGL (Knulli)


Overview

Linux is the primary development target. Knulli is a Linux-based handheld OS (e.g. Anbernic devices); it shares the src/dusklinux/ layer entirely and differs only in the CMake target (OpenGL ES instead of desktop OpenGL, EGL instead of GLX, and no backtrace support).

Both targets use SDL2 for windowing and input. The window is resizable on both (DUSK_DISPLAY_SIZE_DYNAMIC).


Compile-time macros

Macro Linux Knulli
DUSK_LINUX yes yes
DUSK_KNULLI no yes
DUSK_SDL2 yes yes
DUSK_OPENGL yes yes
DUSK_OPENGL_ES no yes
DUSK_DISPLAY_SIZE_DYNAMIC yes yes
DUSK_INPUT_KEYBOARD yes yes
DUSK_INPUT_POINTER yes yes
DUSK_INPUT_GAMEPAD yes yes
DUSK_TIME_DYNAMIC yes yes
DUSK_NETWORK_IPV6 yes no
DUSK_THREAD_PTHREAD yes yes
DUSK_CONSOLE_POSIX yes no

Display

  • Default logical resolution: 640x480 (DUSK_DISPLAY_WIDTH_DEFAULT / DUSK_DISPLAY_HEIGHT_DEFAULT); game content renders at DUSK_DISPLAY_SCREEN_HEIGHT=240.
  • Dynamic resize: the window can be resized at any time; the engine letterboxes/scales the logical framebuffer to fit.
  • Screen mode is configurable via SCREEN.mode (see .claude/display-core.md).
  • Knulli uses OpenGL ES (GLES2) linked via EGL. Avoid any desktop OpenGL extensions that are not in the ES2 core.

Asset loading

dusk.dsk is located by searching a list of paths relative to the current working directory:

static const char_t *ASSET_LINUX_SEARCH_PATHS[] = {
  "%s",
  "../%s",
  "../../%s",
  "data/%s",
  "../data/%s",
  NULL
};

The first path where dusk.dsk is found wins. No packaging step is required on Linux -- run from the build directory or the project root.


Input

All three input types are supported:

  • Keyboard -- SDL scancode array via SDL_GetKeyboardState().
  • Pointer -- mouse position normalized to [0, 1], scroll axes.
  • Gamepad -- first available SDL_GameController; axes normalized to [-1, 1] with a 0.2 deadzone.

See .claude/input.md for the full action/button API.


Save system

Save files are plain files written to disk.

  • Path: ./saves/save_N.dat (override SAVE_LINUX_PATH to change the directory at CMake configure time).
  • Format: SAVE_LINUX_FILE_FORMAT = "%s/save_%u.dat" where %u is the slot index.
  • No OS-level dialog blocking -- saves are synchronous filesystem calls.
  • Endian: host byte order (little-endian on x86/ARM).

Network

  • Connection is detected automatically via getifaddrs(). No explicit connect step is needed.
  • networkRequestConnection immediately calls onConnected if any non-loopback interface is up, onFailed otherwise.
  • IPv4 and IPv6 supported (DUSK_NETWORK_IPV6).

Time

  • Tick source: SDL_GetTicks64().
  • Real time: clock_gettime(CLOCK_REALTIME).
  • Dynamic timestep enabled (DUSK_TIME_DYNAMIC).

Threading

pthreads (DUSK_THREAD_PTHREAD). Thread-local storage via __thread.


Build and toolchain

No cross-compiler needed -- use the host GCC/Clang.

# Debug build
cmake -B build -DDUSK_TARGET_SYSTEM=linux -DCMAKE_BUILD_TYPE=Debug
cmake --build build

# Knulli (cross-compile to aarch64)
cmake -B build \
      -DDUSK_TARGET_SYSTEM=knulli \
      -DCMAKE_TOOLCHAIN_FILE=cmake/toolchains/aarch64-linux-gnu.cmake \
      -DCMAKE_BUILD_TYPE=Release
cmake --build build

Dependencies: SDL2, OpenGL (Linux) or GLES2 + EGL (Knulli), pthread, m.


Endianness

Little-endian. Detected at CMake configure time via TestBigEndian and set as DUSK_PLATFORM_ENDIAN_LITTLE or DUSK_PLATFORM_ENDIAN_BIG.


Gotchas

  • DUSK_CONSOLE_POSIX enables POSIX-specific assert backtracing (Linux only; Knulli does not set it).
  • Knulli does not set DUSK_NETWORK_IPV6 -- IPv6 may not be available on handheld devices.
  • DUSK_TIME_DYNAMIC is set, so physics/networking skip dynamic sub-steps by checking if(TIME.dynamicUpdate) return;.