docs: write README
This commit is contained in:
@@ -1,4 +1,201 @@
|
|||||||
# skele
|
# skele
|
||||||
|
|
||||||
Generic game framework written in C99.
|
[](https://opensource.org/licenses/MPL-2.0)
|
||||||
|
|
||||||
|
`skele` is a lightweight, generic game framework written in C99. It provides a **platform-agnostic core** (clock, video, input) split cleanly from OS/backend-specific implementations, so games and engines built on it stay portable without fighting the framework's opinions.
|
||||||
|
|
||||||
|
It pairs naturally with [`stk`](https://git.forlornoutpost.ca/anth64/stk) for hot-reloadable game modules, but has no hard dependency on it beyond the optional `skele_stk_setup`/`skele_stk_teardown` glue.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Key Features
|
||||||
|
|
||||||
|
- **Platform-agnostic core** (`include/`) with OS/backend-specific implementations swapped in at build time (`src/platform/`)
|
||||||
|
- **Two video backends** behind one API: software/SDL3 blit (`libskele`) and OpenGL (`libglskele`)
|
||||||
|
- **Headless server builds**, linking only the engine core, no client/video/input code pulled in
|
||||||
|
- **Fixed-timestep clock** with monotonic time and signal-aware sleep (POSIX and Win32)
|
||||||
|
- **SDL3-backed input**: keyboard, gamepad (up to 4 pads), mouse, with held/pressed-this-frame state and analog axes
|
||||||
|
- **256-color palette + software blit path** for indexed-color renderers (Doom-era style pipelines)
|
||||||
|
- **Optional `stk` hot-reload integration** via `skele_stk_setup`/`skele_stk_teardown`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
### Building
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Unix (Linux/BSD/macOS)
|
||||||
|
./build.sh debug release
|
||||||
|
|
||||||
|
# Windows
|
||||||
|
build.bat debug release
|
||||||
|
```
|
||||||
|
|
||||||
|
Builds three static libraries into `bin/{debug,release}`:
|
||||||
|
- `libskele.a` - software/SDL3 client backend
|
||||||
|
- `libglskele.a` - OpenGL client backend
|
||||||
|
- `libskeleserver.a` - headless engine core only
|
||||||
|
|
||||||
|
Raspberry Pi 5 is auto-detected and builds against GL 3.1 instead of the default 3.3.
|
||||||
|
|
||||||
|
### Installation
|
||||||
|
|
||||||
|
#### Unix (Linux/BSD/macOS)
|
||||||
|
```bash
|
||||||
|
./build.sh install
|
||||||
|
```
|
||||||
|
|
||||||
|
Installs to `/usr` on Linux, `/usr/local` on BSD/macOS by default. Use `PREFIX` to customize:
|
||||||
|
```bash
|
||||||
|
./build.sh PREFIX=$HOME/.local install
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Windows
|
||||||
|
```
|
||||||
|
build.bat release
|
||||||
|
```
|
||||||
|
* Once finished building, copy the headers from `include/` to `your_project/include/skele/` and copy the built `.lib`/`.dll` files to your project's `lib` directory.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### Basic Example (software client)
|
||||||
|
|
||||||
|
```c
|
||||||
|
#include "client/blit.h"
|
||||||
|
#include "client/input.h"
|
||||||
|
#include "client/video.h"
|
||||||
|
#include "clock.h"
|
||||||
|
#include "skele.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stk/stk.h>
|
||||||
|
|
||||||
|
static uint8_t running = 1;
|
||||||
|
|
||||||
|
static void on_signal(void) { running = 0; }
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
skele_video_config_t video_cfg;
|
||||||
|
uint64_t last, now, elapsed, accum = 0;
|
||||||
|
uint8_t *pixels;
|
||||||
|
|
||||||
|
skele_clock_init(on_signal);
|
||||||
|
|
||||||
|
if (skele_stk_setup() != SKELE_INIT_SUCCESS)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (skele_init() != SKELE_INIT_SUCCESS) {
|
||||||
|
skele_stk_teardown();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
video_cfg.render_width = SKELE_DEFAULT_RENDER_WIDTH;
|
||||||
|
video_cfg.render_height = SKELE_DEFAULT_RENDER_HEIGHT;
|
||||||
|
video_cfg.window_width = 0;
|
||||||
|
video_cfg.window_height = 0;
|
||||||
|
video_cfg.flags = 0;
|
||||||
|
|
||||||
|
if (skele_video_init(video_cfg) != SKELE_INIT_SUCCESS) {
|
||||||
|
skele_stk_teardown();
|
||||||
|
skele_shutdown();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pixels = calloc(video_cfg.render_width * video_cfg.render_height,
|
||||||
|
sizeof(uint8_t));
|
||||||
|
|
||||||
|
last = skele_time_ns();
|
||||||
|
|
||||||
|
while (running) {
|
||||||
|
stk_poll();
|
||||||
|
if (!skele_input_poll())
|
||||||
|
break;
|
||||||
|
|
||||||
|
now = skele_time_ns();
|
||||||
|
elapsed = now - last;
|
||||||
|
accum += elapsed;
|
||||||
|
last = now;
|
||||||
|
|
||||||
|
while (accum >= skele_tick_ns) {
|
||||||
|
skele_tick();
|
||||||
|
accum -= skele_tick_ns;
|
||||||
|
}
|
||||||
|
|
||||||
|
skele_video_blit(pixels);
|
||||||
|
skele_video_present();
|
||||||
|
}
|
||||||
|
|
||||||
|
free(pixels);
|
||||||
|
skele_video_shutdown();
|
||||||
|
skele_stk_teardown();
|
||||||
|
skele_shutdown();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
See `example/client`, `example/gl_client`, and `example/server` for the full reference loops, including a fixed-timestep accumulator suitable for interpolated rendering.
|
||||||
|
|
||||||
|
### Headless / Server Builds
|
||||||
|
|
||||||
|
Link `libskeleserver.a` instead of `libskele.a`/`libglskele.a` to get the engine core (clock, tick, `stk` glue) without pulling in any video/input/SDL3 dependency:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cc -o my_server main.c -lskeleserver -lstk
|
||||||
|
```
|
||||||
|
|
||||||
|
### API Reference
|
||||||
|
|
||||||
|
#### Core (`skele.h`)
|
||||||
|
- `uint8_t skele_init(void)` / `void skele_shutdown(void)` - engine lifecycle
|
||||||
|
- `void skele_tick(void)` - advance one simulation tick
|
||||||
|
- `void skele_set_tick_rate(uint8_t rate)` - configure ticks/sec (default `SKELE_DEFAULT_TICK_RATE`)
|
||||||
|
- `uint64_t skele_tick_ns` - nanoseconds per tick, for accumulator loops
|
||||||
|
- `uint8_t skele_stk_setup(void)` / `void skele_stk_teardown(void)` - wire up `stk` hot-reload
|
||||||
|
|
||||||
|
#### Clock (`clock.h`)
|
||||||
|
- `void skele_clock_init(void (*on_signal)(void))` - monotonic clock + signal handling
|
||||||
|
- `uint64_t skele_time_ns(void)` - current monotonic time
|
||||||
|
- `void skele_sleep_ns(uint64_t ns)` - sleep for a duration
|
||||||
|
|
||||||
|
#### Video (`client/video.h`)
|
||||||
|
- `uint8_t skele_video_init(skele_video_config_t cfg)` / `void skele_video_shutdown(void)`
|
||||||
|
- `void skele_video_present(void)` - present the current frame
|
||||||
|
- `void skele_video_set_title(const char *title)`
|
||||||
|
- `void skele_video_toggle_fullscreen(void)` / `skele_video_set_fullscreen_kind(...)`
|
||||||
|
- `void skele_video_cycle_scale(void)` - cycle integer window scale
|
||||||
|
- `void skele_video_set_mouse_grab(uint8_t grab)`
|
||||||
|
|
||||||
|
#### Blit / Palette (`client/blit.h`, `client/palette.h`)
|
||||||
|
- `void skele_video_blit(uint8_t *pixels)` - blit an indexed-color framebuffer through the active palette
|
||||||
|
- `void skele_palette_set(skele_palette_t pal)` / `skele_palette_set_index(uint8_t index, uint32_t color)`
|
||||||
|
|
||||||
|
#### Input (`client/input.h`)
|
||||||
|
- `uint8_t skele_input_poll(void)` - pump platform events, returns `0` on quit
|
||||||
|
- `uint8_t skele_key_down(skele_key_t key)` / `skele_key_held(skele_key_t key)` - pressed-this-frame vs. currently-held
|
||||||
|
- `uint8_t skele_pad_connected(uint8_t pad)`, `skele_pad_button_down/held(...)`, `float skele_pad_axis(...)` - up to `SKELE_MAX_PADS` gamepads
|
||||||
|
- `void skele_mouse_delta(int32_t *dx, int32_t *dy)`, `skele_mouse_button_down/held(...)`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Project Status
|
||||||
|
|
||||||
|
**Current Version:** 0.0.0
|
||||||
|
|
||||||
|
Early/active development. Platform backends (clock, video, input) are functional and exercised by real client applications, but the engine core (`skele_init`/`skele_tick`) is still minimal. API is not yet stable; expect breaking changes until the core lifecycle is fleshed out.
|
||||||
|
|
||||||
|
No test suite yet.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
Mozilla Public License 2.0 (MPL-2.0)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
Contributions welcome! Please ensure code follows C99 standard and works across all supported platforms.
|
||||||
|
|||||||
Reference in New Issue
Block a user