From a84137b5ffc196f2aad6aa229870f285c71cd518 Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Tue, 4 Aug 2026 06:58:03 -0500 Subject: [PATCH] del md --- CLAUDE.md | 455 ------------------------------------------------------ 1 file changed, 455 deletions(-) delete mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md deleted file mode 100644 index 451c4d16..00000000 --- a/CLAUDE.md +++ /dev/null @@ -1,455 +0,0 @@ -# Dusk — Claude Code rules - -## File headers -Every C, H, and JS file starts with: - -```c -/** - * Copyright (c) 2026 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ -``` - -JS files use `//` comment style instead. - ---- - -## C conventions - -### Types -Always use the project-defined aliases instead of bare C primitives: - -| Use | Not | -|-----------|--------------| -| `bool_t` | `bool` | -| `int_t` | `int` | -| `float_t` | `float` | -| `char_t` | `char` | - -Use `uint8_t`, `uint16_t`, `int32_t`, etc. for fixed-width integers. -All struct and enum types end in `_t` (`animation_t`, `errorret_t`, …). - -### Naming -- **Functions** — snake_case, prefixed with their module: - `assetLock()`, `entityPositionInit()`, `moduleAssetBatchCtor()` -- **Struct fields** — camelCase: `keyframeCount`, `localPosition` -- **Macros / constants** — UPPER_SNAKE_CASE: - `ENTITY_ID_INVALID`, `ERROR_OK`, `COMPONENT_TYPE_COUNT` -- **Files** — snake_case matching the primary type: `entityposition.c`, - `moduleassetbatch.c` - -### Header files (`.h`) -- Use `#pragma once` — no include guards. -- Declare every public function, `#define`, and `extern` global. -- Write a JSDoc block (`/** … */`) above every declaration explaining - purpose, `@param`s, and `@returns`. -- Only include headers that the `.h` file itself strictly requires for - the types it exposes. Move everything else to the `.c` file. - Do not use forward declarations as a workaround — use the real - include in the `.c` file instead. - -### Implementation files (`.c`) -- Contain function bodies only; no declarations. -- Pull in whatever additional includes the implementation needs. -- Do not use `static` or `inline` on **functions**. Every function, - including internal helpers, must be declared in the matching `.h` and - defined in the `.c` file. Internal helpers belong near the bottom of - the `.c` file, not at the top with a `static` qualifier. - `static` and `inline` on functions are only appropriate when the - function body is written directly inside a `.h` file. - `static` on **variables** (file-scope state) is fine and expected. - -### Formatting -- Hard-wrap all lines at **80 characters**. - -### Error handling -Return `errorret_t` from fallible functions. Use these macros: - -```c -errorOk(); // return success -errorThrow("msg %d", val); // return failure with message -errorChain(someCall()); // propagate failure, continue on success -errorIsOk(ret) / errorIsNotOk(ret) // test a result -errorCatch(ret); // handle + free an error -``` - -Never return raw error codes or use `errno` for in-engine errors. - -### Memory -Use the project allocator — never raw `malloc`/`free`: - -```c -memoryAllocate(size) // allocate -memoryFree(ptr) // free -memoryZero(dest, size) // zero a block -memoryCopy(dest, src, size) // copy -``` - -### Asserts -Prefer specific assert macros over bare `assert()`: - -```c -assertNotNull(ptr, "msg"); -assertTrue(cond, "msg"); -assertFalse(cond, "msg"); -assertUnreachable("msg"); -assertIsMainThread("msg"); -``` - ---- - -## Build system -Each subdirectory has its own `CMakeLists.txt` that adds sources with: - -```cmake -target_sources(${DUSK_LIBRARY_TARGET_NAME} - PUBLIC - myfile.c -) -``` - -Never add source files to the root `CMakeLists.txt` directly. - ---- - -## Platform support - -### Targets -Set `DUSK_TARGET_SYSTEM` at CMake configure time to select a platform: - -| `DUSK_TARGET_SYSTEM` | Macro defined | Platform | -|----------------------|-------------------|------------------| -| `linux` | `DUSK_LINUX` | Linux desktop | -| `knulli` | `DUSK_KNULLI` | Knulli (handheld)| -| `psp` | `DUSK_PSP` | Sony PSP | -| `vita` | `DUSK_VITA` | PlayStation Vita | -| `gamecube` | `DUSK_GAMECUBE` | Nintendo GameCube| -| `wii` | `DUSK_WII` | Nintendo Wii | - -### Layer structure -``` -src/dusk/ core, platform-agnostic game logic -src/duskgl/ OpenGL abstraction (Linux, Knulli, PSP, Vita) -src/dusksdl2/ SDL2 window + input (Linux, Knulli, PSP, Vita) -src/dusklinux/ Linux + Knulli platform impl -src/duskpsp/ PSP platform impl -src/duskvita/ Vita platform impl -src/duskdolphin/ GameCube / Wii platform impl (no SDL2/OpenGL) -``` - -Dolphin is the only target that bypasses SDL2 and OpenGL entirely — -it uses native GameCube/Wii rendering and input APIs. - -### Platform guards -Use the compile-time macros for platform-specific code: - -```c -#ifdef DUSK_PSP - // PSP-only path -#elif defined(DUSK_GAMECUBE) || defined(DUSK_WII) - // GameCube / Wii path -#else - // Generic / Linux fallback -#endif -``` - -Additional capability macros set per-target: -`DUSK_SDL2`, `DUSK_OPENGL`, `DUSK_OPENGL_ES`, `DUSK_OPENGL_LEGACY`, -`DUSK_INPUT_GAMEPAD`, `DUSK_INPUT_KEYBOARD`, `DUSK_INPUT_POINTER`, -`DUSK_PLATFORM_ENDIAN_BIG` / `DUSK_PLATFORM_ENDIAN_LITTLE`. - -### Abstraction pattern -Platform-specific implementations are wired in via `#define` macros in -each platform's `displayplatform.h` / `inputplatform.h` etc., which -the core calls through. Functions that a platform does not support are -simply left undefined — the core guards calls with `#ifdef`. - -### Adding platform-specific code -- Put it under `src/dusk/` in the matching subsystem folder. -- Gate any core call-site with the appropriate `#ifdef DUSK_` - or capability macro. -- Keep the `src/dusk/` core free of platform ifdefs — delegate through - the platform header macros instead. - ---- - -## Adding a new asset loader type -1. Add an enum value to `assetloadertype_t` (before `_COUNT`) in - `src/dusk/asset/loader/assetloader.h`. -2. Add fields to the input/loading/output unions in `assetloader.h`. -3. Implement `assetXxxLoaderSync`, `assetXxxLoaderAsync`, and - `assetXxxDispose` in a new `src/dusk/asset/loader/xxx/` directory. -4. Register the three callbacks in `ASSET_LOADER_CALLBACKS[]` in - `src/dusk/asset/loader/assetloader.c`. -5. If user-facing, create a JS module (see below) and a `.d.ts` file. - ---- - -## Adding a new entity component -1. Create `src/dusk/entity/component//entityMyComp.h/.c` with - struct `entityMyComp_t`, `entityMyCompInit()`, and optionally - `entityMyCompDispose()`. -2. Add the include to `src/dusk/entity/componentlist.h` header block. -3. Add a row to `src/dusk/entity/componentlist.h`: - ```c - X(MYCOMP, entityMyComp_t, myComp, entityMyCompInit, NULL, NULL) - ``` - This auto-generates the enum, union field, and definition entry. -4. If JS-facing, create the script module and `.d.ts` (see below). - ---- - -## Adding a new script (JS) module -1. Create `src/dusk/script/module//moduleMyMod.h/.c`. - - Declare `extern scriptproto_t MODULE_MYMOD_PROTO;` in the header. - - Use `moduleBaseFunction(name)` to define JS-callable functions. - - Register props/funcs in `moduleMyModInit()` with - `scriptProtoDefineProp` / `scriptProtoDefineFunc` / - `scriptProtoDefineStaticFunc`. -2. `#include` the header in - `src/dusk/script/module/modulelist.c` and call - `moduleMyModInit()` in `moduleListInit()` (and `Dispose` in - `moduleListDispose()`). -3. For component modules also register in - `src/dusk/script/module/entity/component/modulecomponentlist.c` - so `entity.add()` returns the typed wrapper. -4. Create `types//mymod.d.ts` and add a - `/// ` line to `types/index.d.ts`. - ---- - -## Script module type declarations -Whenever a `src/dusk/script/module/**/*.c` file is created or modified, -check whether the corresponding `types/**/*.d.ts` needs updating and -apply any changes before finishing the task. - ---- - -## JavaScript (asset scripts) -- Use `var` for module-level state; `const` for values that never - change. -- Always use semicolons. -- Scene objects are plain objects (`var scene = {}`) with assigned - methods. -- Export via `module.exports = scene`. -- Async scene init should use `async function` and `await`. - ---- - -## Coding style - -### ASCII only -Source files (`.c`, `.h`, `.js`) must contain only ASCII characters (U+0000–U+007F). -Non-ASCII characters are banned even in comments and string literals. -Use ASCII-only substitutes instead: -- `--` or `-` instead of `—` (em dash) -- `->` instead of `→` (arrow) -- `x` or `*` instead of `×` (multiplication) - -Only non-script asset files (e.g. `.po` locale files) may contain non-ASCII text. - -### Indentation -2 spaces. No tabs. - -### Keyword and operator spacing -No space between a keyword or function name and its opening parenthesis: - -```c -if(!ptr) return; -for(uint8_t i = 0; i < count; i++) { -while(entry->state != DONE) { -switch(type) { -sizeof(assetbatch_t) -memoryZero(ptr, size) -``` - -Spaces around all binary operators and after every comma: - -```c -pos->flags |= ENTITY_POSITION_FLAG_WORLD_DIRTY; -(size_t)end - (size_t)start -foo(a, b, c) -``` - -### Braces -Opening brace on the **same line** as the statement (K&R style) for all -constructs — functions, `if`, `else`, `for`, `while`, `switch`: - -```c -void assetEntryLock(assetentry_t *entry) { - ... -} - -if(dirty) { - ... -} else { - ... -} -``` - -### Guard returns -Short guards go on one line with no braces: - -```c -if(!ptr) return; -if(!b || !b->batch) return jerry_undefined(); -if(!(flags & DIRTY)) return; -``` - -### Blank lines -- One blank line between functions; no blank line at the start or end of - a function body. -- One blank line between logical blocks inside a function body. -- No trailing blank lines at the end of a file. - -### Pointer placement -`*` is attached to the variable name, not the type: - -```c -assetentry_t *entry -const char_t *name -void *ptr -uint8_t *d = (uint8_t *)dest; -``` - -### Casts -Space between cast and operand: - -```c -(assetbatch_t *)user -(uint8_t *)dest -(textureformat_t)v -``` - -### Return -No parentheses around the return value: - -```c -return ptr; -return MEMORY_POINTERS_IN_USE; -``` - -### switch / case -`case` indented 2 spaces from `switch`; body indented 2 more from `case`: - -```c -switch(type) { - case ASSET_LOADER_TYPE_TEXTURE: - descs[i].input.texture = (textureformat_t)v; - break; - default: - break; -} -``` - -### Multi-line function signatures -When parameters don't fit on one line, put each on its own line indented -2 spaces; the closing `) {` (definition) or `);` (declaration) goes on -its own line at column 0: - -```c -void assetEntryInit( - assetentry_t *entry, - const char_t *name, - const assetloadertype_t type, - assetloaderinput_t *input -) { - -errorret_t memoryCompare( - const void *a, - const void *b, - const size_t size -); -``` - -### Structs and enums -Anonymous inner struct or enum with a `typedef`, `_t` suffix, closing -brace and name on the same line: - -```c -typedef struct { - errorcode_t code; - char_t *message; -} errorstate_t; - -typedef enum { - ASSET_LOADER_TYPE_NULL, - ASSET_LOADER_TYPE_COUNT -} assetloadertype_t; -``` - -### Designated initialisers -Spaces inside braces; `.field = value`: - -```c -jsassetentry_t e = { .entry = entry }; -assetbatchloadedpend_t init = { .batch = batch }; -``` - -### Ternary operator -Spaces around `?` and `:`: - -```c -const float val = psx > 0.0f ? pt[0][0] / psx : 0.0f; -``` - -### const placement -`const` before the type, `*` attached to the variable: - -```c -const char_t *name -const void *src -const size_t size -``` - -### Comments in `.c` files -- Do not use section dividers (`/* ---- ... ---- */`). Just let the - functions follow one another with a single blank line between them. -- Multi-line explanatory comments inside function bodies use `//` lines: - ```c - // Script modules are freed; orphaned JS wrapper objects now get GC'd - // so their finalizers fire before assetDispose() checks ref counts. - jerry_heap_gc(JERRY_GC_PRESSURE_HIGH); - ``` -- Do not use `/* */` for inline or inline-block comments inside `.c` - function bodies. - -### Comments in `.h` files -Every public declaration gets a Javadoc block (`/** … */`) with -`@param` and `@returns` where relevant. Keep it on the lines immediately -above the declaration with no blank line in between. - ---- - -## Color system - -Colors are defined in `src/dusk/display/color.csv` and code-generated -into a `color.h` header by `tools/color/csv/__main__.py`. - -Each row in the CSV has `name,r,g,b,a` with channel values in `[0.0, 1.0]`. -The script emits four `#define` variants per color plus a bare alias: - -``` -COLOR__4B color4b(r8, g8, b8, a8) // default alias target -COLOR__3B color3b(r8, g8, b8) -COLOR__3F color3f(rf, gf, bf) -COLOR__4F color4f(rf, gf, bf, af) -COLOR_ COLOR__4B -``` - -`color_t` is `color4b_t` (four `uint8_t` channels). - -To add a new color, append a row to `color.csv` and rebuild — do not -hand-edit the generated header. - ---- - -## Tests -- Tests live in `test/` mirroring `src/dusk/` structure. -- Use cmocka; include `dusktest.h`. -- Test functions: `static void test_something(void **state)`. -- After each test, assert `memoryGetAllocatedCount() == 0` to catch - leaks. -- Build with `-DDUSK_BUILD_TESTS=ON`.