Final docs
This commit is contained in:
@@ -43,8 +43,21 @@ typedef union shadermaterial_u {
|
|||||||
} shadermaterial_t;
|
} shadermaterial_t;
|
||||||
```
|
```
|
||||||
|
|
||||||
`shaderunlitmaterial_t` typically holds a `texture_t *` and a
|
`shaderunlitmaterial_t` fields:
|
||||||
tint colour. Check `shaderunlitmaterial.h` for the exact fields.
|
|
||||||
|
```c
|
||||||
|
typedef struct {
|
||||||
|
color_t color; // tint colour (multiplied with the texture sample)
|
||||||
|
texture_t *texture; // NULL uses TEXTURE_WHITE (solid colour draw)
|
||||||
|
} shaderunlitmaterial_t;
|
||||||
|
```
|
||||||
|
|
||||||
|
The shader exposes uniforms `u_Proj`, `u_View`, `u_Model` (mat4),
|
||||||
|
`u_Texture` (sampler), and `u_Color` (vec4). They are uploaded via
|
||||||
|
`shaderUnlitSetMaterial(shader, material)`.
|
||||||
|
|
||||||
|
A global singleton `SHADER_UNLIT` is the live shader object;
|
||||||
|
`SHADER_UNLIT_DEFINITION` is its platform definition descriptor.
|
||||||
|
|
||||||
To use a shader material on a renderable entity:
|
To use a shader material on a renderable entity:
|
||||||
|
|
||||||
|
|||||||
+10
-3
@@ -97,6 +97,13 @@ eventSubscribe(&state.onComplete, myHandler, myUserPtr);
|
|||||||
|
|
||||||
## Where events are used
|
## Where events are used
|
||||||
|
|
||||||
- `inputactiondata_t`: `onPressed`, `onReleased` per action
|
| Subsystem | Event | Fires when |
|
||||||
- Any engine subsystem that exposes hooks (network connect/disconnect,
|
|-----------|-------|-----------|
|
||||||
asset batch completion, etc.)
|
| `inputactiondata_t` | `onPressed`, `onReleased` | Action button state changes |
|
||||||
|
| `uitextbox_t` | `onPageComplete` | Typewriter scroll reveals the full page |
|
||||||
|
| `uitextbox_t` | `onLastPage` | Last page is fully scrolled |
|
||||||
|
| `uifullbox_t` | `onTransitionEnd` | Colour transition animation completes |
|
||||||
|
| `uiloading_t` | `onShow` / `onHide` | Loading indicator fade completes |
|
||||||
|
| Asset system | `assetbatch_t` callback | All entries in a batch reach LOADED/ERROR |
|
||||||
|
|
||||||
|
See `.claude/ui.md` for the UI event details.
|
||||||
|
|||||||
+70
-13
@@ -17,6 +17,26 @@ The platform layer implements two hooks:
|
|||||||
- `inputButtonGetValuePlatform()` -- return the analog value [0.0, 1.0]
|
- `inputButtonGetValuePlatform()` -- return the analog value [0.0, 1.0]
|
||||||
for a given button
|
for a given button
|
||||||
|
|
||||||
|
## Defined actions
|
||||||
|
|
||||||
|
Actions are defined in `src/dusk/input/input.csv` and code-generated
|
||||||
|
into the `inputaction_t` enum. Current values:
|
||||||
|
|
||||||
|
| Constant | Meaning |
|
||||||
|
|----------|---------|
|
||||||
|
| `INPUT_ACTION_NULL` | Invalid / sentinel (0) |
|
||||||
|
| `INPUT_ACTION_UP` | Up direction |
|
||||||
|
| `INPUT_ACTION_DOWN` | Down direction |
|
||||||
|
| `INPUT_ACTION_LEFT` | Left direction |
|
||||||
|
| `INPUT_ACTION_RIGHT` | Right direction |
|
||||||
|
| `INPUT_ACTION_ACCEPT` | Confirm / primary action |
|
||||||
|
| `INPUT_ACTION_CANCEL` | Back / secondary action |
|
||||||
|
| `INPUT_ACTION_RAGEQUIT` | Quit the application |
|
||||||
|
| `INPUT_ACTION_CONSOLE` | Toggle debug console |
|
||||||
|
| `INPUT_ACTION_POINTERX` | Mouse / pointer X axis |
|
||||||
|
| `INPUT_ACTION_POINTERY` | Mouse / pointer Y axis |
|
||||||
|
| `INPUT_ACTION_COUNT` | Total count (not a valid action) |
|
||||||
|
|
||||||
## Global state
|
## Global state
|
||||||
|
|
||||||
```c
|
```c
|
||||||
@@ -40,14 +60,22 @@ bool_t inputWasDown(inputaction_t action);
|
|||||||
bool_t inputPressed(inputaction_t action); // was up, now down
|
bool_t inputPressed(inputaction_t action); // was up, now down
|
||||||
bool_t inputReleased(inputaction_t action); // was down, now up
|
bool_t inputReleased(inputaction_t action); // was down, now up
|
||||||
|
|
||||||
// 2D axis helpers
|
// Single axis from a neg + pos pair of actions (returns [-1, 1]):
|
||||||
|
float_t inputAxis(inputaction_t neg, inputaction_t pos);
|
||||||
|
|
||||||
|
// 2D axis from four actions (negX/posX/negY/posY):
|
||||||
void inputAxis2D(
|
void inputAxis2D(
|
||||||
inputaction_t horiz,
|
inputaction_t negX, inputaction_t posX,
|
||||||
inputaction_t vert,
|
inputaction_t negY, inputaction_t posY,
|
||||||
vec2 out
|
vec2 result
|
||||||
|
);
|
||||||
|
|
||||||
|
// Same four-action axis, normalized to a unit vector via atan2:
|
||||||
|
void inputAngle2D(
|
||||||
|
inputaction_t negX, inputaction_t posX,
|
||||||
|
inputaction_t negY, inputaction_t posY,
|
||||||
|
vec2 result
|
||||||
);
|
);
|
||||||
float_t inputAngle2D(inputaction_t horiz, inputaction_t vert);
|
|
||||||
void inputAxis(inputaction_t action, float_t *out);
|
|
||||||
|
|
||||||
// Deadzone filter (applied to raw axis values)
|
// Deadzone filter (applied to raw axis values)
|
||||||
float_t inputDeadzone(float_t value, float_t deadzone);
|
float_t inputDeadzone(float_t value, float_t deadzone);
|
||||||
@@ -119,12 +147,41 @@ constants to PSP button names, then calls `inputBind` to wire them:
|
|||||||
| L / R | `SDL_CONTROLLER_BUTTON_LEFTSHOULDER` / `RIGHTSHOULDER` |
|
| L / R | `SDL_CONTROLLER_BUTTON_LEFTSHOULDER` / `RIGHTSHOULDER` |
|
||||||
| L-Stick | `SDL_CONTROLLER_AXIS_LEFTX/Y` |
|
| L-Stick | `SDL_CONTROLLER_AXIS_LEFTX/Y` |
|
||||||
|
|
||||||
|
### Vita (`src/duskvita/input/`)
|
||||||
|
|
||||||
|
Layered on top of SDL2 (via vitaSDL2). Behaviour is similar to PSP --
|
||||||
|
no keyboard, no pointer, gamepad only.
|
||||||
|
|
||||||
|
## JS module (`Input`)
|
||||||
|
|
||||||
|
The input system is exposed to JS as the global `Input` object with
|
||||||
|
static methods. Action constants are pre-defined as numeric properties
|
||||||
|
on the `Input` object (e.g. `Input.ACCEPT`, `Input.UP`):
|
||||||
|
|
||||||
|
```js
|
||||||
|
// Check if the accept button is held this frame:
|
||||||
|
if(Input.isDown(Input.ACCEPT)) { ... }
|
||||||
|
|
||||||
|
// Was the cancel button just pressed?
|
||||||
|
if(Input.pressed(Input.CANCEL)) { ... }
|
||||||
|
|
||||||
|
// Analog value for the right trigger:
|
||||||
|
var val = Input.getValue(Input.RIGHT);
|
||||||
|
|
||||||
|
// Single axis (-1 to 1) from a neg/pos pair:
|
||||||
|
var h = Input.axis(Input.LEFT, Input.RIGHT);
|
||||||
|
```
|
||||||
|
|
||||||
|
All `Input.*` action constants match the `INPUT_ACTION_*` enum values
|
||||||
|
from the C layer (UP, DOWN, LEFT, RIGHT, ACCEPT, CANCEL, RAGEQUIT,
|
||||||
|
CONSOLE, POINTERX, POINTERY).
|
||||||
|
|
||||||
## Platform capability notes
|
## Platform capability notes
|
||||||
|
|
||||||
| Feature | Linux/Knulli | PSP | GameCube/Wii |
|
| Feature | Linux/Knulli | PSP | Vita | GameCube/Wii |
|
||||||
|---------|-------------|-----|--------------|
|
|---------|-------------|-----|------|--------------|
|
||||||
| Keyboard | Yes (SDL2) | No | No |
|
| Keyboard | Yes (SDL2) | No | No | No |
|
||||||
| Pointer/Mouse | Yes (SDL2) | No | No |
|
| Pointer/Mouse | Yes (SDL2) | No | No | No |
|
||||||
| Gamepad | Yes (SDL2) | Yes (SDL2) | Yes (PAD) |
|
| Gamepad | Yes (SDL2) | Yes (SDL2) | Yes (SDL2) | Yes (PAD) |
|
||||||
| Analog axes | Yes | L-Stick only | L-Stick, C-Stick, Triggers |
|
| Analog axes | Yes | L-Stick only | L-Stick, R-Stick | L-Stick, C-Stick, Triggers |
|
||||||
| Touch | Defined, not implemented | -- | -- |
|
| Touch | Defined, not implemented | -- | -- | -- |
|
||||||
|
|||||||
+32
-4
@@ -86,10 +86,38 @@ The shader used for each renderable:
|
|||||||
|
|
||||||
## Transitioning between scenes
|
## Transitioning between scenes
|
||||||
|
|
||||||
To move to a new scene from JS, call the scene module's transition
|
Scene transitions are handled entirely in JS via the `Scene` global.
|
||||||
function (exact API in the `scene` JS module). The C side defers the
|
The `Scene` object is a singleton with:
|
||||||
actual switch to the start of the next `sceneUpdate` call so the
|
|
||||||
current tick completes cleanly before any dispose runs.
|
```js
|
||||||
|
// Switch to a new scene. Calls dispose() on the current scene, then
|
||||||
|
// init() on the new one. Both happen synchronously this tick.
|
||||||
|
Scene.set(newSceneObject);
|
||||||
|
|
||||||
|
// The current scene object (may be null):
|
||||||
|
Scene.current
|
||||||
|
```
|
||||||
|
|
||||||
|
Typical scene-switch pattern:
|
||||||
|
|
||||||
|
```js
|
||||||
|
// Inside a scene's update or event handler:
|
||||||
|
const nextScene = require("scenes/gameplay.js");
|
||||||
|
Scene.set(nextScene);
|
||||||
|
```
|
||||||
|
|
||||||
|
`Scene.set` is synchronous -- it calls `dispose` on the old scene and
|
||||||
|
`init` on the new scene before returning. If `init` needs async work
|
||||||
|
(loading assets), use an async function and `await` inside `init`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
nextScene.init = async function() {
|
||||||
|
await batch.load(); // wait for assets before proceeding
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
The C side does not defer the transition; the switch happens inside
|
||||||
|
the current `sceneUpdate` call.
|
||||||
|
|
||||||
## Relationship to the engine loop
|
## Relationship to the engine loop
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user