From b7973b289de49d579cfbda5449e25a614b4a3170 Mon Sep 17 00:00:00 2001 From: Gabriel Perez Date: Mon, 8 Jun 2026 16:47:59 -0400 Subject: [PATCH] docs: update API documentation for scene transitions and camera effects - Add detailed descriptions and usage examples for the new TransitionEffect and CameraEffectsSystem classes. - Document new methods for scene transitions in Engine and SceneManager. - Update configuration options in config.md to reflect changes in transition and camera effect features. - Enhance core and graphics documentation to include new functionalities and performance considerations. --- api/config.md | 37 ++- api/core.md | 18 +- api/generated/audio/AudioConfig.md | 11 - api/generated/audio/DefaultAudioScheduler.md | 36 ++- api/generated/core/Actor.md | 48 +++- api/generated/core/Engine.md | 34 +++ api/generated/core/Entity.md | 28 -- api/generated/core/LimitRect.md | 11 - api/generated/core/PhysicsActor.md | 74 +++++- api/generated/core/Scene.md | 24 +- api/generated/core/SceneManager.md | 63 +++++ api/generated/core/TransitionState.md | 14 + api/generated/drivers/ESP32AudioScheduler.md | 10 + .../drivers/ESP32_DAC_AudioBackend.md | 2 + .../drivers/ESP32_I2S_AudioBackend.md | 2 + api/generated/drivers/NativeAudioScheduler.md | 10 + api/generated/drivers/SDL2_AudioBackend.md | 2 + api/generated/drivers/SDL2_Drawer.md | 44 ++++ api/generated/drivers/TFT_eSPI_Drawer.md | 72 ++++++ api/generated/drivers/U8G2_Drawer.md | 32 +++ api/generated/graphics/Camera2D.md | 12 + api/generated/graphics/CameraEffectsSystem.md | 116 +++++++++ api/generated/graphics/DrawSurface.md | 8 + api/generated/graphics/EffectSlot.md | 16 ++ api/generated/graphics/LayerAttributes.md | 142 ++++++++++ api/generated/graphics/ParticleEmitter.md | 21 ++ api/generated/graphics/Renderer.md | 24 +- api/generated/graphics/ResolutionPresets.md | 27 ++ api/generated/graphics/Sprite2bpp.md | 10 + api/generated/graphics/Sprite4bpp.md | 10 + .../graphics/TileAnimationManager.md | 2 - api/generated/graphics/TileMapGeneric.md | 9 + api/generated/graphics/TransitionDirection.md | 32 +++ api/generated/graphics/TransitionEffect.md | 242 ++++++++++++++++++ api/generated/graphics/TransitionType.md | 9 + api/generated/graphics/UIAnchorLayout.md | 56 ++++ api/generated/graphics/UIButton.md | 4 + api/generated/graphics/UICheckBox.md | 4 + api/generated/graphics/UIGridLayout.md | 82 ++++++ api/generated/graphics/UIHitTest.md | 16 ++ api/generated/graphics/UIHorizontalLayout.md | 69 +++++ api/generated/graphics/UILabel.md | 4 + api/generated/graphics/UILayout.md | 21 -- api/generated/graphics/UIPaddingContainer.md | 32 +++ api/generated/graphics/UIPanel.md | 32 +++ api/generated/graphics/UITouchButton.md | 22 ++ api/generated/graphics/UITouchCheckbox.md | 22 ++ api/generated/graphics/UITouchElement.md | 20 ++ api/generated/graphics/UITouchSlider.md | 22 ++ api/generated/graphics/UITouchWidget.md | 8 +- api/generated/graphics/UIVerticalLayout.md | 69 +++++ api/generated/graphics/WipeDirection.md | 12 + api/generated/index.md | 8 + api/generated/input/TouchEvent.md | 17 -- api/generated/input/TouchEventDispatcher.md | 28 ++ api/generated/input/TouchPoint.md | 16 -- api/generated/input/TouchStateMachine.md | 33 +++ api/generated/math/Vector2.md | 34 +-- api/generated/physics/CollisionSystem.md | 44 ++++ api/generated/physics/KinematicActor.md | 60 ++++- api/generated/physics/RigidActor.md | 30 +++ api/generated/physics/Segment.md | 15 ++ api/generated/physics/SensorActor.md | 4 + api/generated/physics/SnapPolicy.md | 13 + api/generated/physics/StaticActor.md | 12 + api/generated/physics/TileCollisionBuilder.md | 16 ++ .../physics/TileConsumptionHelper.md | 18 +- api/generated/test/StressTestScene.md | 6 + api/graphics.md | 122 +++++++++ architecture/layer-scene.md | 60 ++++- architecture/physics-subsystem.md | 2 - examples/camera-effect-demo.md | 74 ++++++ examples/camera.md | 55 +++- examples/demos.md | 1 + examples/metroidvania.md | 4 + guide/scenes.md | 80 +++++- 76 files changed, 2320 insertions(+), 179 deletions(-) create mode 100644 api/generated/core/TransitionState.md create mode 100644 api/generated/graphics/CameraEffectsSystem.md create mode 100644 api/generated/graphics/EffectSlot.md create mode 100644 api/generated/graphics/TransitionDirection.md create mode 100644 api/generated/graphics/TransitionEffect.md create mode 100644 api/generated/graphics/TransitionType.md create mode 100644 api/generated/graphics/WipeDirection.md create mode 100644 api/generated/physics/SnapPolicy.md create mode 100644 examples/camera-effect-demo.md diff --git a/api/config.md b/api/config.md index e6a2558..5c1c9ea 100644 --- a/api/config.md +++ b/api/config.md @@ -14,10 +14,10 @@ This document covers global configuration options, build flags, and compile-time |-------|-------------|-----------------| | `PR32_DEFAULT_AUDIO_CORE` | CPU core assigned to audio tasks. | `0` | | `PR32_DEFAULT_MAIN_CORE` | CPU core assigned to the main game loop. | `1` | -| `PIXELROOT32_NO_DAC_AUDIO` | Disable Internal DAC support on classic ESP32. | Enabled | -| `PIXELROOT32_NO_I2S_AUDIO` | Disable I2S audio support. | Enabled | +| `PIXELROOT32_NO_DAC_AUDIO` | Disable Internal DAC support on classic ESP32. | Not defined (opt-in) | +| `PIXELROOT32_NO_I2S_AUDIO` | Disable I2S audio support. | Not defined (opt-in) | | `PIXELROOT32_USE_U8G2_DRIVER` | Enable U8G2 display driver support for monochromatic OLEDs. | Disabled | -| `PIXELROOT32_NO_TFT_ESPI` | Disable default TFT_eSPI driver support. | Enabled | +| `PIXELROOT32_NO_TFT_ESPI` | Disable default TFT_eSPI driver support. | Not defined (opt-in) | ## Modular Compilation Flags @@ -27,8 +27,10 @@ This document covers global configuration options, build flags, and compile-time | `PIXELROOT32_ENABLE_PHYSICS` | Enable physics system. | `1` | | `PIXELROOT32_ENABLE_UI_SYSTEM` | Enable UI system. | `1` | | `PIXELROOT32_ENABLE_PARTICLES` | Enable particle system. | `1` | +| `PIXELROOT32_ENABLE_CAMERA_EFFECTS` | Enable camera effects (shake, punch, offset). | `1` | +| `PIXELROOT32_ENABLE_SCENE_TRANSITIONS` | Enable scene transition effects (fade, iris). | `1` | | `PIXELROOT32_ENABLE_DEBUG_OVERLAY` | Enable FPS/RAM/CPU debug overlay. | Disabled | -| `PIXELROOT32_ENABLE_TILE_ANIMATIONS` | Enable tile animation system. | `1` | +| `PIXELROOT32_ENABLE_TILE_ANIMATIONS` | Enable tile animation system. | `0` | | `PIXELROOT32_ENABLE_2BPP_SPRITES` | Enable 2bpp sprite support. | Disabled | | `PIXELROOT32_ENABLE_4BPP_SPRITES` | Enable 4bpp sprite support. | Disabled | | `PIXELROOT32_ENABLE_SCENE_ARENA` | Enable scene memory arena. | Disabled | @@ -40,10 +42,8 @@ This document covers global configuration options, build flags, and compile-time | `PIXELROOT32_TFT_ESPI_LINES_PER_BLOCK` | TFT_eSPI DMA line batch size. | `60` | | `PIXELROOT32_TFT_ESPI_LINES_PER_BLOCK_FALLBACK` | Fallback DMA batch size if memory fails. | `30` | | `PIXELROOT32_DEBUG_MODE` | Enable unified logging system. | Disabled | -| `PIXELROOT32_ENABLE_PHYSICS_FIXED_TIMESTEP` | Enable PhysicsScheduler for consistent physics. | `1` | | `PIXELROOT32_VELOCITY_DAMPING` | Per-frame velocity damping factor (0.0-1.0). | `0.999` | | `PIXELROOT32_MAX_VELOCITY` | Maximum velocity cap in units/s. | `500` | -| `PIXELROOT32_HAS_FAST_RSQRT` | Enable fast reciprocal square root. | `1` | ## Memory Savings by Subsystem @@ -104,20 +104,35 @@ build_flags = | Constant | Default | Description | |----------|---------|-------------| -| `DISPLAY_WIDTH` | `240` | The logical width of the display in pixels. | -| `DISPLAY_HEIGHT` | `240` | The logical height of the display in pixels. | -| `xOffset` / `yOffset` | `0` | Coordinate offsets for hardware alignment. | +| `DISPLAY_WIDTH` | `LOGICAL_WIDTH` | Deprecated alias for `LOGICAL_WIDTH`. | +| `DISPLAY_HEIGHT` | `LOGICAL_HEIGHT` | Deprecated alias for `LOGICAL_HEIGHT`. | +| `PHYSICAL_DISPLAY_WIDTH` | `240` | Actual hardware display width in pixels. | +| `PHYSICAL_DISPLAY_HEIGHT` | `240` | Actual hardware display height in pixels. | +| `LOGICAL_WIDTH` | `PHYSICAL_DISPLAY_WIDTH` | Internal rendering width. Engine scales to physical. | +| `LOGICAL_HEIGHT` | `PHYSICAL_DISPLAY_HEIGHT` | Internal rendering height. Engine scales to physical. | +| `DISPLAY_ROTATION` | `0` | Display rotation (0, 90, 180, 270). | +| `X_OFF_SET` | `0` | Horizontal coordinate offset for hardware alignment. | +| `Y_OFF_SET` | `0` | Vertical coordinate offset for hardware alignment. | +| `MAX_SCENES` | `8` | Maximum number of scenes in the scene stack. | +| `MAX_LAYERS` | `4` | Maximum number of layers per scene. | +| `MAX_ENTITIES` | `64` | Maximum entities per scene. | +| `MAX_TILESET_SIZE` | `256` | Maximum number of tiles in a tileset. | +| `MAX_BACKGROUND_PALETTE_SLOTS` | `8` | Background palette slots for multi-palette tilemaps (2bpp/4bpp). | +| `MAX_SPRITE_PALETTE_SLOTS` | `8` | Sprite palette slots for multi-palette sprites (2bpp/4bpp). | +| `PHYSICS_MAX_ENTITIES` | `64` | Maximum entities in the physics system. | | `PHYSICS_MAX_PAIRS` | `128` | Maximum collision pairs considered in broadphase. | | `PHYSICS_MAX_CONTACTS` | `128` | Maximum simultaneous contacts in the physics solver. | -| `VELOCITY_ITERATIONS` | `2` | Number of impulse solver passes per frame. | +| `PIXELROOT32_VELOCITY_ITERATIONS` | `2` | Number of impulse solver passes per frame. | | `SPATIAL_GRID_CELL_SIZE` | `32` | Size of each cell in the broadphase grid (pixels). | | `SPATIAL_GRID_MAX_ENTITIES_PER_CELL` | `24` | (Legacy) max entities per cell. | | `SPATIAL_GRID_MAX_STATIC_PER_CELL` | `12` | Max static actors per grid cell. | | `SPATIAL_GRID_MAX_DYNAMIC_PER_CELL` | `12` | Max dynamic actors per grid cell. | +| `PR32_HAS_FPU_MACRO` | Auto-detected | Set to `1` if target has hardware FPU (ESP32, ESP32-S3, ESP32-P4, native). Undefined for C-series. | +| `PR32_FORCE_FIXED` | Undefined | User override: undefines `PR32_HAS_FPU_MACRO` to force Fixed16 math. | ## Custom Scene Limits -The engine defines default limits in `platforms/EngineConfig.h`: `MAX_LAYERS` (default 3) and `MAX_ENTITIES` (default 32). These are guarded with `#ifndef`, so you can override them from your project without modifying the engine. +The engine defines default limits in `platforms/EngineConfig.h`: `MAX_LAYERS` (default 4) and `MAX_ENTITIES` (default 64). These are guarded with `#ifndef`, so you can override them from your project without modifying the engine. **Compiler flags (recommended)** diff --git a/api/core.md b/api/core.md index 53ad23f..ed4251e 100644 --- a/api/core.md +++ b/api/core.md @@ -5,6 +5,7 @@ > - `include/core/Entity.h` > - `include/core/Scene.h` > - `include/core/SceneManager.h` +> - `include/graphics/TransitionEffect.h` > - `include/platforms/PlatformCapabilities.h` > - `include/graphics/DisplayConfig.h` @@ -16,7 +17,13 @@ This document covers the core engine classes, entity system, and scene managemen ### Engine -The main engine class that manages the game loop and core subsystems. Each iteration calls **`update()`**; **`draw()`** and **`present()`** run only when **`SceneManager::aggregateShouldRedrawFramebuffer()`** is `true` (any stacked scene may request a pass). +The main engine class that manages the game loop and core subsystems. Each iteration calls **`update()`**; **`draw()`** and **`present()`** run only when **`SceneManager::aggregateShouldRedrawFramebuffer()`** is `true` (any stacked scene may request a pass). + +**Scene Transitions** (`PIXELROOT32_ENABLE_SCENE_TRANSITIONS=1`): +- `triggerTransition(type, durationMs, dir)`: Initiate Fade or Iris transition +- `isTransitioning()`: Check if transition is active +- Transition effects are managed by `TransitionEffect` class (see Graphics Module) +- Input is blocked during transitions to prevent ghost inputs ### Entity @@ -50,6 +57,14 @@ build_flags = Manages the stack of active scenes. Allows for scene transitions (replacing) and stacking (push/pop), useful for pausing or menus. `aggregateShouldRedrawFramebuffer()` ensures that menus don't suppress background scenes that still need drawing. +**Transition Support** (`PIXELROOT32_ENABLE_SCENE_TRANSITIONS=1`): +- `transitionToScene(scene, type, durationMs, dir)`: Begin transition to new scene +- `isTransitioning()`: Check if transition is active +- `updateTransitions(deltaTime)`: Update transition state machine +- `drawTransitionOverlay(renderer)`: Render transition effect overlay +- State machine: `Idle → FadingOut → SceneSwap → FadingIn → Idle` +- Input blocked during `FadingOut` and `FadingIn` states + ### SceneArena (Memory Management) An optional memory arena for zero-allocation scenes (enabled via `PIXELROOT32_ENABLE_SCENE_ARENA`). Pre-allocates a fixed memory block for temporary data or entity storage, avoiding heap fragmentation on embedded devices. @@ -100,6 +115,7 @@ The metrics are drawn in the top-right area of the screen, fixed and independent - `Scene` → `include/core/Scene.h` - `SceneManager` → `include/core/SceneManager.h` - `SceneArena` → `include/core/Scene.h` +- `TransitionEffect` → `include/graphics/TransitionEffect.h` - `PlatformCapabilities` → `include/platforms/PlatformCapabilities.h` - `DisplayConfig` → `include/graphics/DisplayConfig.h` diff --git a/api/generated/audio/AudioConfig.md b/api/generated/audio/AudioConfig.md index e328596..993e626 100644 --- a/api/generated/audio/AudioConfig.md +++ b/api/generated/audio/AudioConfig.md @@ -19,14 +19,3 @@ Configuration for the Audio subsystem. ## Methods ### `: backend(backend), sampleRate(sampleRate), blockSize(blockSize)` - -**Description:** - -Constructs an AudioConfig with platform-adaptive block size. - -**Parameters:** - -- `backend`: Pointer to the audio backend implementation. May be nullptr for headless configs. -- `sampleRate`: Desired sample rate in Hz (default 22050 for retro feel). -- `blockSize`: Audio block size in samples. Defaults to 256 on FPU platforms, 128 on no-FPU platforms. - Must be a multiple of 128 for I2S DMA alignment. diff --git a/api/generated/audio/DefaultAudioScheduler.md b/api/generated/audio/DefaultAudioScheduler.md index 8cc515f..bfcb940 100644 --- a/api/generated/audio/DefaultAudioScheduler.md +++ b/api/generated/audio/DefaultAudioScheduler.md @@ -28,7 +28,39 @@ For platforms with a dedicated audio task (e.g., FreeRTOS on ESP32), ## Methods -### `bool isMusicPlaying() const` +### `void init(AudioBackend* backend, int sampleRate, const pixelroot32::platforms::PlatformCapabilities& caps, int blockSize = 256)` + +### `void submitCommand(const AudioCommand& cmd)` + +**Description:** + +Enqueues a command to the ApuCore. @param cmd The command to submit. + +**Parameters:** + +- `cmd`: The command to submit. + +### `void start()` + +**Description:** + +Marks scheduler as running. Starts audio generation context. + +### `void stop()` + +**Description:** + +Marks scheduler as stopped. Silences all voices. + +### `bool isIndependent() const` + +**Description:** + +Returns false (no dedicated audio thread). @return false. + +**Returns:** false. + +### `void generateSamples(int16_t* stream, int length)` **Description:** @@ -38,6 +70,8 @@ Generates samples via ApuCore. @param stream Output buffer. @param length Sample - `stream`: Output buffer. +### `bool isMusicPlaying() const` + ### `bool isMusicPaused() const` ### `ApuCore& getApuCore()` diff --git a/api/generated/core/Actor.md b/api/generated/core/Actor.md index 4ce2ece..ff082c0 100644 --- a/api/generated/core/Actor.md +++ b/api/generated/core/Actor.md @@ -31,28 +31,66 @@ enemies, and projectiles. ### `: Entity(x, y, w, h, EntityType::ACTOR)` +### `: Entity(pos, w, h, EntityType::ACTOR)` + +### `void setCollisionLayer(pixelroot32::physics::CollisionLayer l)` + **Description:** -Constructor using Scalar coordinates. +Sets the collision layer this actor belongs to. -### `: Entity(pos, w, h, EntityType::ACTOR)` +**Parameters:** + +- `l`: The collision layer. + +### `void setCollisionMask(pixelroot32::physics::CollisionLayer m)` **Description:** -Constructor using Vector2 position. +Sets the collision mask defining which layers this actor interacts with. -### `void setCollisionLayer(pixelroot32::physics::CollisionLayer l)` +**Parameters:** -### `void setCollisionMask(pixelroot32::physics::CollisionLayer m)` +- `m`: The collision mask. ### `void update(unsigned long deltaTime)` +**Description:** + +Updates the actor's state. + +**Parameters:** + +- `deltaTime`: Time elapsed since last update in milliseconds. + ### `bool isInLayer(uint16_t targetLayer) const` +**Description:** + +Checks if the actor belongs to a specific collision layer. + +**Parameters:** + +- `targetLayer`: The layer bitmask to check. + +**Returns:** true if the actor is in the specified layer. + ### `virtual Rect getHitBox()` +**Description:** + +Gets the axis-aligned bounding box (hitbox) for this actor. + +**Returns:** The Rect representing the hitbox. + ### `virtual bool isPhysicsBody() const` +**Description:** + +Checks if this actor is a physics-driven body (e.g., RigidActor). + +**Returns:** true if it is a physics body, false otherwise. + ### `virtual void onCollision(Actor* other)` **Description:** diff --git a/api/generated/core/Engine.md b/api/generated/core/Engine.md index 393e554..a3750d6 100644 --- a/api/generated/core/Engine.md +++ b/api/generated/core/Engine.md @@ -65,6 +65,40 @@ Sets the current active scene. - `newScene`: Pointer to the new Scene to become active. +### `void triggerTransition(Scene* newScene, pixelroot32::graphics::TransitionType type, unsigned long durationMs)` + +**Description:** + +Start a visual scene transition (Fade, Iris, or DiagonalWipe). + +**Parameters:** + +- `newScene`: The target scene to transition to. +- `type`: TransitionType::Fade, TransitionType::Iris, or TransitionType::DiagonalWipe. +- `durationMs`: Duration of each phase (Out and In) in ms. + +Delegates to SceneManager::transitionToScene(). Ignored if a +transition is already in progress. + +### `void triggerTransition(Scene* newScene, pixelroot32::graphics::TransitionType type, unsigned long durationMs, int irisOutCx, int irisOutCy, int irisInCx, int irisInCy)` + +**Description:** + +Start a visual scene transition with direction-specific iris centers. + +**Parameters:** + +- `newScene`: The target scene to transition to. +- `type`: TransitionType::Fade, TransitionType::Iris, or TransitionType::DiagonalWipe. +- `durationMs`: Duration of each phase (Out and In) in ms. +- `irisOutCx`: Iris center X for Out (closing) phase. +- `irisOutCy`: Iris center Y for Out (closing) phase. +- `irisInCx`: Iris center X for In (opening) phase. +- `irisInCy`: Iris center Y for In (opening) phase. + +Delegates to SceneManager::transitionToScene() with centers. +Only meaningful for Iris transitions — Fade ignores centers. + ### `std::optional getCurrentScene() const` **Description:** diff --git a/api/generated/core/Entity.md b/api/generated/core/Entity.md index 6c9f6e4..d9f66bd 100644 --- a/api/generated/core/Entity.md +++ b/api/generated/core/Entity.md @@ -65,38 +65,10 @@ Sets the render layer. ### `: position(pos), width(w), height(h), type(t)` -**Description:** - -Constructor. - -**Parameters:** - -- `position`: Initial position. -- `w`: Width. -- `h`: Height. -- `t`: EntityType. - ### `: position(x, y), width(w), height(h), type(t)` -**Description:** - -Constructor. - -**Parameters:** - -- `x`: Initial X position. -- `y`: Initial Y position. -- `w`: Width. -- `h`: Height. -- `t`: EntityType. - ### `: position(pixelroot32::math::toScalar(x), pixelroot32::math::toScalar(y)), width(w), height(h), type(t)` -**Description:** - -Constructor with float coordinates for convenience. -Only enabled if Scalar is NOT float to avoid ambiguity. - ### `virtual void update(unsigned long deltaTime)` **Description:** diff --git a/api/generated/core/LimitRect.md b/api/generated/core/LimitRect.md index 2c5bf4e..59e1664 100644 --- a/api/generated/core/LimitRect.md +++ b/api/generated/core/LimitRect.md @@ -15,15 +15,4 @@ Values of -1 indicate no limit on that side. ### `int width() const` -**Description:** - -Constructs a new LimitRect. - -**Parameters:** - -- `l`: Left limit. -- `t`: Top limit. -- `r`: Right limit. -- `b`: Bottom limit. - ### `int height() const` diff --git a/api/generated/core/PhysicsActor.md b/api/generated/core/PhysicsActor.md index d5aa502..0f7c76d 100644 --- a/api/generated/core/PhysicsActor.md +++ b/api/generated/core/PhysicsActor.md @@ -19,6 +19,16 @@ Automatically adapts to use float or Fixed16 based on the platform configuration ## Methods +### `void update(unsigned long deltaTime)` + +**Description:** + +Updates the actor state. + +**Parameters:** + +- `deltaTime`: Time elapsed since the last frame in milliseconds. + ### `void setLimits(const LimitRect& limitRect)` **Description:** @@ -156,16 +166,15 @@ Integrates velocity to update position. Resolves collisions with the defined world or custom bounds. -### `void setVelocity(T x, T y)` +### `pixelroot32::core::Rect getHitBox()` **Description:** -Sets the linear velocity of the actor using floats. +Gets the axis-aligned bounding box (AABB) hitbox of the actor. -**Parameters:** +**Returns:** Rect representing the hitbox. -- `x`: Horizontal velocity. -- `y`: Vertical velocity. +### `void setVelocity(T x, T y)` ### `void setVelocity(pixelroot32::math::Scalar x, pixelroot32::math::Scalar y)` @@ -294,6 +303,51 @@ Get user data pointer. **Returns:** Pointer set via setUserData, or nullptr if never set. +### `void setHitboxOffset(pixelroot32::math::Vector2 offset)` + +**Description:** + +Sets the hitbox offset relative to position. + +**Parameters:** + +- `offset`: Offset vector (e.g., {4, 8} shifts hitbox right and down). + +### `pixelroot32::math::Vector2 getHitboxOffset() const` + +**Description:** + +Gets the current hitbox offset. + +**Returns:** Offset vector. + +### `void setHitboxDimensions(pixelroot32::math::Scalar w, pixelroot32::math::Scalar h)` + +**Description:** + +Sets custom hitbox dimensions separate from entity dimensions. + +**Parameters:** + +- `w`: Custom hitbox width (0 = use entity width). +- `h`: Custom hitbox height (0 = use entity height). + +### `pixelroot32::math::Scalar getHitboxWidth() const` + +**Description:** + +Gets the custom hitbox width. + +**Returns:** Custom hitbox width as Scalar (0 means entity width is used). + +### `pixelroot32::math::Scalar getHitboxHeight() const` + +**Description:** + +Gets the custom hitbox height. + +**Returns:** Custom hitbox height as Scalar (0 means entity height is used). + ### `void setSensor(bool s)` **Description:** @@ -366,6 +420,16 @@ Sets the position and syncs previous position. - `pos`: The new position. +### `void onCollision(Actor* other)` + +**Description:** + +Callback triggered when this actor collides with another actor. + +**Parameters:** + +- `other`: Pointer to the actor involved in the collision. + ### `virtual void onWorldCollision()` **Description:** diff --git a/api/generated/core/Scene.md b/api/generated/core/Scene.md index 33f6c6c..602fa50 100644 --- a/api/generated/core/Scene.md +++ b/api/generated/core/Scene.md @@ -8,13 +8,21 @@ Represents a game level or screen containing entities. +init() is idempotent — may be called any number of times, each call + leaves the state equivalent to a fresh init. + +::: tip +init() is idempotent — may be called any number of times, each call + leaves the state equivalent to a fresh init. +::: + ## Methods ### `virtual void init()` **Description:** -Initializes the scene. Called when entering the scene. +Initialises the scene. Called when entering the scene. ### `virtual void initUI()` @@ -102,6 +110,14 @@ layers/camera sampling as StaticTilemapLayerCache::draw so dirty-region clears a When false, Engine may skip `draw()` and `present()` for this iteration (after `update()`). +### `inline pixelroot32::math::Vector2 getCameraEffectOffset() const` + +**Description:** + +Get the current summed offset from CameraEffectsSystem. + +**Returns:** math::Vector2 offset (ZERO when no effects active or feature disabled). + ### `void addEntity(Entity* entity)` **Description:** @@ -127,3 +143,9 @@ Removes an entity from the scene. **Description:** Removes all entities from the scene. + +### `virtual void resetState() noexcept; Entity* entities[pixelroot32::platforms::config::MaxEntities]; ///< Array of entities in the scene. int entityCount; ///< Current number of entities. bool needsSorting = false; ///< Flag to trigger sorting by layer. void sortEntities(); ///< Sorts entities by render layer. bool isVisibleInViewport(Entity* entity, pixelroot32::graphics::Renderer& renderer)` + +**Description:** + +Resets the scene to a clean initial state. diff --git a/api/generated/core/SceneManager.md b/api/generated/core/SceneManager.md index 3170d09..56fc01b 100644 --- a/api/generated/core/SceneManager.md +++ b/api/generated/core/SceneManager.md @@ -94,3 +94,66 @@ Gets the number of scenes in the stack. Checks if the scene stack is empty. **Returns:** True if there are no scenes. + +### `void transitionToScene(Scene* newScene, pixelroot32::graphics::TransitionType type, unsigned long durationMs)` + +**Description:** + +Start a transition from the current scene to a new one. + +**Parameters:** + +- `newScene`: The target scene to transition to. +- `type`: Fade, Iris, or DiagonalWipe transition effect. +- `durationMs`: Duration of each phase (Out and In) in ms. + +Ignored if a transition is already running (state != Idle). +The full cycle is: FadingOut (durationMs) → SceneSwap → FadingIn (durationMs) → Idle. + +### `void transitionToScene(Scene* newScene, pixelroot32::graphics::TransitionType type, unsigned long durationMs, int irisOutCx, int irisOutCy, int irisInCx, int irisInCy)` + +**Description:** + +Start a transition with direction-specific iris centers. + +**Parameters:** + +- `newScene`: The target scene to transition to. +- `type`: Fade, Iris, or DiagonalWipe transition effect. +- `durationMs`: Duration of each phase (Out and In) in ms. +- `irisOutCx`: Iris center X for Out (closing) phase. +- `irisOutCy`: Iris center Y for Out (closing) phase. +- `irisInCx`: Iris center X for In (opening) phase. +- `irisInCy`: Iris center Y for In (opening) phase. + +Stores the centers and re-applies them after each effect.init() +(which resets centers to -1). Only meaningful for Iris transitions. + +### `bool isTransitioning() const` + +**Description:** + +Whether a scene transition is currently active. + +**Returns:** true when TransitionState != Idle. + +### `TransitionState getTransitionState() const` + +**Description:** + +Get the current transition state. + +**Returns:** The active TransitionState. + +### `void setTransitionEffect(pixelroot32::graphics::TransitionEffect* effect)` + +**Description:** + +Provide a pointer to the Engine-owned TransitionEffect instance. + +**Parameters:** + +- `effect`: Non-owning pointer to the TransitionEffect. + +Called by Engine::init(). The Engine owns the TransitionEffect; +SceneManager only drives it (init, update) during transitions. diff --git a/api/generated/core/TransitionState.md b/api/generated/core/TransitionState.md new file mode 100644 index 0000000..b135696 --- /dev/null +++ b/api/generated/core/TransitionState.md @@ -0,0 +1,14 @@ +# TransitionState + + + +**Source:** `SceneManager.h` + +## Description + +State machine for scene transitions. + +Idle → FadingOut → SceneSwap → FadingIn → Idle. +During FadingOut/FadingIn the current scene's update() is skipped +(input blocking). Draw() still runs so the framebuffer has content +for the transition effect to post-process. diff --git a/api/generated/drivers/ESP32AudioScheduler.md b/api/generated/drivers/ESP32AudioScheduler.md index 1c0409b..2552e36 100644 --- a/api/generated/drivers/ESP32AudioScheduler.md +++ b/api/generated/drivers/ESP32AudioScheduler.md @@ -21,8 +21,18 @@ Constructor arguments are reserved for API stability. ## Methods +### `void init(AudioBackend* backend, int sampleRate, const pixelroot32::platforms::PlatformCapabilities& caps, int blockSize = 256)` + +### `void submitCommand(const AudioCommand& cmd)` + +### `void start()` + +### `void stop()` + ### `bool isIndependent() const` +### `void generateSamples(int16_t* stream, int length)` + ### `bool isMusicPlaying() const` ### `bool isMusicPaused() const` diff --git a/api/generated/drivers/ESP32_DAC_AudioBackend.md b/api/generated/drivers/ESP32_DAC_AudioBackend.md index 18d928c..0f152c2 100644 --- a/api/generated/drivers/ESP32_DAC_AudioBackend.md +++ b/api/generated/drivers/ESP32_DAC_AudioBackend.md @@ -23,6 +23,8 @@ Target: ESP32 (original), ESP32-S2. The DAC does not exist on S3/C3. ## Methods +### `void init(pixelroot32::audio::AudioEngine* engine, const pixelroot32::platforms::PlatformCapabilities& caps)` + ### `int getSampleRate() const` ### `void audioTaskLoop()` diff --git a/api/generated/drivers/ESP32_I2S_AudioBackend.md b/api/generated/drivers/ESP32_I2S_AudioBackend.md index d47063a..20b68e5 100644 --- a/api/generated/drivers/ESP32_I2S_AudioBackend.md +++ b/api/generated/drivers/ESP32_I2S_AudioBackend.md @@ -19,6 +19,8 @@ to ensure smooth playback independent of the game loop frame rate. ## Methods +### `void init(pixelroot32::audio::AudioEngine* engine, const pixelroot32::platforms::PlatformCapabilities& caps)` + ### `int getSampleRate() const` ### `void audioTaskLoop()` diff --git a/api/generated/drivers/NativeAudioScheduler.md b/api/generated/drivers/NativeAudioScheduler.md index 73c5e67..2122b43 100644 --- a/api/generated/drivers/NativeAudioScheduler.md +++ b/api/generated/drivers/NativeAudioScheduler.md @@ -23,8 +23,18 @@ threading and the ring buffer. ### `explicit NativeAudioScheduler(size_t ringBufferSize = 4096)` +### `void init(AudioBackend* backend, int sampleRate, const pixelroot32::platforms::PlatformCapabilities& caps, int blockSize = 256)` + +### `void submitCommand(const AudioCommand& cmd)` + +### `void start()` + +### `void stop()` + ### `bool isIndependent() const` +### `void generateSamples(int16_t* stream, int length)` + ### `bool isMusicPlaying() const` ### `bool isMusicPaused() const` diff --git a/api/generated/drivers/SDL2_AudioBackend.md b/api/generated/drivers/SDL2_AudioBackend.md index 52fce6b..c8d2fca 100644 --- a/api/generated/drivers/SDL2_AudioBackend.md +++ b/api/generated/drivers/SDL2_AudioBackend.md @@ -16,6 +16,8 @@ Audio backend implementation for SDL2 (Windows/Linux/Mac). ## Methods +### `void init(pixelroot32::audio::AudioEngine* engine, const pixelroot32::platforms::PlatformCapabilities& caps)` + ### `int getSampleRate() const` ### `void audioCallback(uint8_t* stream, int len)` diff --git a/api/generated/drivers/SDL2_Drawer.md b/api/generated/drivers/SDL2_Drawer.md index 522d05d..6705580 100644 --- a/api/generated/drivers/SDL2_Drawer.md +++ b/api/generated/drivers/SDL2_Drawer.md @@ -16,12 +16,56 @@ SDL2-backed draw surface for native desktop builds. ## Methods +### `void init()` + +### `void setRotation(uint16_t rotation)` + +**Description:** + +Sets the screen rotation. + +**Parameters:** + +- `rotation`: 0-3 corresponding to 0, 90, 180, 270 degrees. + +### `void clearBuffer()` + +### `void sendBuffer()` + +### `void drawFilledCircle(int x, int y, int radius, uint16_t color)` + +### `void drawCircle(int x, int y, int radius, uint16_t color)` + +### `void drawRectangle(int x, int y, int width, int height, uint16_t color)` + +### `void drawFilledRectangle(int x, int y, int width, int height, uint16_t color)` + +### `void drawLine(int x1, int y1, int x2, int y2, uint16_t color)` + +### `void drawBitmap(int x, int y, int width, int height, const uint8_t *bitmap, uint16_t color)` + +### `void drawPixel(int x, int y, uint16_t color)` + +### `void drawTileDirect(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint8_t* data)` + +**Description:** + +Direct tile write (not optimized for SDL2 - uses fallback). + ### `uint8_t* getSpriteBuffer()` **Description:** Get pointer to sprite buffer (not supported in SDL2). +### `uint16_t* getPixelBuffer()` + +**Description:** + +Get pointer to the RGB565 pixel buffer for transition effects. + +### `bool processEvents()` + ### `void setTouchDispatcher(pixelroot32::input::TouchEventDispatcher* touchDispatcher)` **Description:** diff --git a/api/generated/drivers/TFT_eSPI_Drawer.md b/api/generated/drivers/TFT_eSPI_Drawer.md index fcf095b..2b50736 100644 --- a/api/generated/drivers/TFT_eSPI_Drawer.md +++ b/api/generated/drivers/TFT_eSPI_Drawer.md @@ -19,6 +19,78 @@ It uses a sprite (framebuffer) to minimize flickering and tearing. ## Methods +### `void init()` + +**Description:** + +Initializes the TFT_eSPI library and the sprite buffer. +Sets up the SPI communication and allocates memory for the framebuffer. + +### `void setRotation(uint16_t rotation)` + +**Description:** + +Sets the screen rotation. + +**Parameters:** + +- `rotation`: 0-3 corresponding to 0, 90, 180, 270 degrees. + +### `void clearBuffer()` + +**Description:** + +Fills the sprite buffer with black color. + +### `void sendBuffer()` + +**Description:** + +Pushes the sprite buffer to the physical display. +This is the "flip" operation in double buffering. + +### `void drawFilledCircle(int x, int y, int radius, uint16_t color)` + +### `void drawCircle(int x, int y, int radius, uint16_t color)` + +### `void drawRectangle(int x, int y, int width, int height, uint16_t color)` + +### `void drawFilledRectangle(int x, int y, int width, int height, uint16_t color)` + +### `void drawLine(int x1, int y1, int x2, int y2, uint16_t color)` + +### `void drawBitmap(int x, int y, int width, int height, const uint8_t *bitmap, uint16_t color)` + +### `void drawPixel(int x, int y, uint16_t color)` + +### `void drawTileDirect(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint8_t* data)` + +**Description:** + +Direct tile write to sprite buffer (optimized for tilemap rendering). + +**Parameters:** + +- `x`: Tile X position in sprite coordinates +- `y`: Tile Y position in sprite coordinates +- `width`: Tile width in pixels +- `height`: Tile height in pixels +- `data`: Pointer to 8bpp tile data (one byte per pixel, index into palette) + +### `uint8_t* getSpriteBuffer()` + +**Description:** + +Get pointer to sprite buffer for direct manipulation. + +**Returns:** Pointer to 8bpp sprite buffer, or nullptr if sprite not created + +### `bool processEvents()` + +**Description:** + +Processes system events. Always true for embedded. + ### `bool needsScaling() const` **Description:** diff --git a/api/generated/drivers/U8G2_Drawer.md b/api/generated/drivers/U8G2_Drawer.md index 7c7c68b..349cef9 100644 --- a/api/generated/drivers/U8G2_Drawer.md +++ b/api/generated/drivers/U8G2_Drawer.md @@ -16,6 +16,38 @@ Implementation of DrawSurface using the U8G2 library for monochromatic OLED disp ## Methods +### `void init()` + +### `void setRotation(uint16_t rotation)` + +### `void drawPixel(int x, int y, uint16_t color)` + +### `void clearBuffer()` + +### `void sendBuffer()` + +### `void drawLine(int x1, int y1, int x2, int y2, uint16_t color)` + +### `void drawRectangle(int x, int y, int w, int h, uint16_t color)` + +### `void drawFilledRectangle(int x, int y, int w, int h, uint16_t color)` + +### `void drawCircle(int x0, int y0, int r, uint16_t color)` + +### `void drawFilledCircle(int x0, int y0, int r, uint16_t color)` + +### `void drawBitmap(int x, int y, int w, int h, const uint8_t *bitmap, uint16_t color)` + +**Description:** + +Support for U8G2 native XBM bitmaps. +Note: This assumes the bitmap is in XBM format if color is 1, +otherwise it uses the base implementation. + +### `void setDisplaySize(int w, int h)` + +### `void setPhysicalSize(int w, int h)` + ### `U8G2* getU8g2() const` ### `void drawTileDirect(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint8_t* data)` diff --git a/api/generated/graphics/Camera2D.md b/api/generated/graphics/Camera2D.md index dd3e6a3..43abe6a 100644 --- a/api/generated/graphics/Camera2D.md +++ b/api/generated/graphics/Camera2D.md @@ -49,4 +49,16 @@ Camera2D does not own a Renderer. Call apply(renderer) to push the Pushes the camera transform into the renderer (sets display offset). +### `void apply(Renderer& renderer, const pixelroot32::math::Vector2& effectOffset) const` + +**Description:** + +Pushes camera transform + effect offset into the renderer. + +**Parameters:** + +- `renderer`: The renderer to push the transform into. +- `effectOffset`: Additional offset from CameraEffectsSystem + (added to camera position before negation). + ### `void setViewportSize(int width, int height)` diff --git a/api/generated/graphics/CameraEffectsSystem.md b/api/generated/graphics/CameraEffectsSystem.md new file mode 100644 index 0000000..c4a9736 --- /dev/null +++ b/api/generated/graphics/CameraEffectsSystem.md @@ -0,0 +1,116 @@ +# CameraEffectsSystem + + + +**Source:** `CameraEffects.h` + +## Description + +Manages up to 4 simultaneous camera effects with round-robin insertion. + +Effects are updated with a delta time and the resulting summed offset +can be fetched for application to a Camera2D. Provides a fast no-op path +via hasActiveEffects(). + +## Methods + +### `void update(unsigned long deltaTimeMs)` + +**Description:** + +Advance all active effect timers. + +**Parameters:** + +- `deltaTimeMs`: Time elapsed since last frame in ms. + +### `math::Vector2 getOffset() const` + +**Description:** + +Get the summed offset from all active effects. + +**Returns:** Summed math::Vector2 offset. ZERO if no effects are active. + +Early-outs when hasActiveEffects() is false — zero loop iteration. + +### `bool hasActiveEffects() const` + +**Description:** + +Fast check for any active effects. + +**Returns:** true if at least one slot is active. + +### `void triggerShake(math::Scalar amp, unsigned long dur)` + +**Description:** + +Trigger a shake effect (random oscillation). + +**Parameters:** + +- `amp`: Maximum amplitude of the shake. +- `dur`: Duration in ms. + +### `void triggerPunch(math::Scalar amp, unsigned long dur, const math::Vector2& dir)` + +**Description:** + +Trigger a punch effect (directional impulse with decay). + +**Parameters:** + +- `amp`: Initial amplitude. +- `dur`: Duration in ms. +- `dir`: Normalized direction of the punch. + +### `void triggerOffset(math::Scalar amp, unsigned long dur)` + +**Description:** + +Trigger a constant offset effect. + +**Parameters:** + +- `amp`: Amplitude/displacement amount. +- `dur`: Duration in ms. + +The offset direction defaults to RIGHT (1, 0). +Displacement stays constant for the full duration, then snaps to zero. + +### `void cancelAll()` + +**Description:** + +Cancel all active effects immediately. + +### `math::Vector2 computeShakeOffset(const EffectSlot& s) const` + +**Description:** + +Compute a single frame's shake offset using Xorshift32. + +**Parameters:** + +- `s`: The shake effect slot. + +**Returns:** Random offset vector bounded by slot amplitude. + +### `math::Vector2 computeDecayOffset(const EffectSlot& s) const` + +**Description:** + +Compute offset with linear decay (Punch) or constant (Offset). + +**Parameters:** + +- `s`: The effect slot (Punch or Offset type). + +**Returns:** Decayed or constant offset vector. + +### `uint8_t allocSlot()` + +**Description:** + +Find the next available slot index (round-robin). diff --git a/api/generated/graphics/DrawSurface.md b/api/generated/graphics/DrawSurface.md index ff7534f..75feafb 100644 --- a/api/generated/graphics/DrawSurface.md +++ b/api/generated/graphics/DrawSurface.md @@ -159,6 +159,14 @@ Get pointer to sprite buffer for direct manipulation. **Returns:** Pointer to 8bpp sprite buffer, or nullptr if not supported +### `virtual uint16_t* getPixelBuffer()` + +**Description:** + +Get pointer to the native pixel buffer (RGB565 on SDL2). + +**Returns:** Pointer to RGB565 pixel array, or nullptr if not supported. + ### `virtual void setContrast(uint8_t level)` **Description:** diff --git a/api/generated/graphics/EffectSlot.md b/api/generated/graphics/EffectSlot.md new file mode 100644 index 0000000..12c5824 --- /dev/null +++ b/api/generated/graphics/EffectSlot.md @@ -0,0 +1,16 @@ +# EffectSlot + + + +**Source:** `CameraEffects.h` + +## Description + +Per-slot state for a single camera effect (20 bytes). + +## Properties + +| Name | Type | Description | +|------|------|-------------| +| `long` | `unsigned` | Total duration in ms. | +| `direction` | `math::Vector2` | Normalized direction (Punch/Offset only). | diff --git a/api/generated/graphics/LayerAttributes.md b/api/generated/graphics/LayerAttributes.md index 205b686..5996a91 100644 --- a/api/generated/graphics/LayerAttributes.md +++ b/api/generated/graphics/LayerAttributes.md @@ -65,3 +65,145 @@ Maximum 65535 tiles with attributes per layer (uint16_t limit) | `char` | `const` | Layer name (PROGMEM string, e.g., "Background") | | `num_tiles_with_attributes` | `uint16_t` | Number of tiles with attributes in this layer | | `TileAttributeEntry` | `const` | PROGMEM array of tiles with attributes (sparse) | + +## Methods + +### `inline const char* get_tile_attribute( const LayerAttributes* layer_attributes, uint8_t num_layers, uint8_t layer_idx, uint16_t x, uint16_t y, const char* key )` + +**Description:** + +Query a tile attribute value by position and key. + +**Parameters:** + +- `layer_attributes`: Pointer to PROGMEM array of LayerAttributes +- `num_layers`: Number of layers in the array +- `layer_idx`: Index of the layer to query (0-based) +- `x`: Tile X coordinate +- `y`: Tile Y coordinate +- `key`: Attribute key to search for (may be RAM or PROGMEM string) + +**Returns:** Pointer to PROGMEM attribute value string, or nullptr if not found + +::: tip +Returns nullptr if: + - layer_idx >= num_layers (out of bounds) + - Layer is empty (num_tiles_with_attributes == 0) + - Tile at (x, y) does not exist + - Tile exists but does not have the specified key +::: + +::: tip +The returned pointer references PROGMEM. Use strcmp_P() or similar + functions to compare values. + +Example usage: +```cpp +// Query "solid" attribute for tile at (10, 5) in layer 0 +const char* value = pixelroot32::graphics::get_tile_attribute( + layer_attributes, NUM_LAYERS_WITH_ATTRIBUTES, 0, 10, 5, "solid" +); +if (value && strcmp_P(value, "true") == 0) { + // Tile is solid +} +``` +::: + +### `inline bool tile_has_attributes( const LayerAttributes* layer_attributes, uint8_t num_layers, uint8_t layer_idx, uint16_t x, uint16_t y )` + +**Description:** + +Check if a tile at the given position has any attributes. + +**Parameters:** + +- `layer_attributes`: Pointer to PROGMEM array of LayerAttributes +- `num_layers`: Number of layers in the array +- `layer_idx`: Index of the layer to query (0-based) +- `x`: Tile X coordinate +- `y`: Tile Y coordinate + +**Returns:** true if tile has attributes, false otherwise + +::: tip +Returns false if: + - layer_idx >= num_layers (out of bounds) + - Layer is empty (num_tiles_with_attributes == 0) + - Tile at (x, y) does not exist in the layer +::: + +::: tip +This function only checks for tile existence. To query specific + attribute values, use get_tile_attribute(). + +Example usage: +```cpp +// Check if tile at (10, 5) in layer 0 has any attributes +if (pixelroot32::graphics::tile_has_attributes( + layer_attributes, NUM_LAYERS_WITH_ATTRIBUTES, 0, 10, 5 +)) { + // Tile has attributes, query specific values + const char* solid = pixelroot32::graphics::get_tile_attribute( + layer_attributes, NUM_LAYERS_WITH_ATTRIBUTES, 0, 10, 5, "solid" + ); +} +``` +::: + +### `inline const TileAttributeEntry* get_tile_entry( const LayerAttributes* layer_attributes, uint8_t num_layers, uint8_t layer_idx, uint16_t x, uint16_t y )` + +**Description:** + +Get the TileAttributeEntry for a tile at the given position. + +**Parameters:** + +- `layer_attributes`: Pointer to PROGMEM array of LayerAttributes +- `num_layers`: Number of layers in the array +- `layer_idx`: Index of the layer to query (0-based) +- `x`: Tile X coordinate +- `y`: Tile Y coordinate + +**Returns:** Pointer to TileAttributeEntry in PROGMEM, or nullptr if not found + +::: tip +Returns nullptr if: + - layer_idx >= num_layers (out of bounds) + - Layer is empty (num_tiles_with_attributes == 0) + - Tile at (x, y) does not exist in the layer +::: + +::: tip +The returned pointer references PROGMEM. Use PIXELROOT32_MEMCPY_P + to read the entry into RAM before accessing its fields. +::: + +::: tip +This function is more efficient than calling get_tile_attribute() + multiple times for the same tile, as it performs the position lookup + only once. + +Example usage: +```cpp +// Query multiple attributes from tile at (10, 5) in layer 0 +const TileAttributeEntry* entry_ptr = pixelroot32::graphics::get_tile_entry( + layer_attributes, NUM_LAYERS_WITH_ATTRIBUTES, 0, 10, 5 +); + +if (entry_ptr) { + // Read entry from PROGMEM into RAM + TileAttributeEntry entry; + PIXELROOT32_MEMCPY_P(&entry, entry_ptr, sizeof(TileAttributeEntry)); + + // Iterate through all attributes + for (uint8_t i = 0; i < entry.num_attributes; i++) { + TileAttribute attr; + PIXELROOT32_MEMCPY_P(&attr, &entry.attributes[i], sizeof(TileAttribute)); + + // Process attribute key and value + // attr.key and attr.value are PROGMEM pointers + // Use strcmp_P() or similar functions to compare + } +} +``` +::: diff --git a/api/generated/graphics/ParticleEmitter.md b/api/generated/graphics/ParticleEmitter.md index 72e6eaa..d4bbc79 100644 --- a/api/generated/graphics/ParticleEmitter.md +++ b/api/generated/graphics/ParticleEmitter.md @@ -19,6 +19,27 @@ Uses a fixed-size array for particles to avoid dynamic allocation during runtime ## Methods +### `void update(unsigned long deltaTime)` + +**Description:** + +Updates all active particles. +Applies physics (gravity, friction) and updates lifetime. + +**Parameters:** + +- `deltaTime`: Time elapsed since last frame. + +### `void draw(pixelroot32::graphics::Renderer& renderer)` + +**Description:** + +Renders all active particles. + +**Parameters:** + +- `renderer`: The renderer instance. + ### `void burst(pixelroot32::math::Vector2 position, int count)` **Description:** diff --git a/api/generated/graphics/Renderer.md b/api/generated/graphics/Renderer.md index e3c3e6d..67a0404 100644 --- a/api/generated/graphics/Renderer.md +++ b/api/generated/graphics/Renderer.md @@ -408,8 +408,6 @@ Draws a 4bpp sprite (legacy). - `y`: Top-left Y coordinate. - `flipX`: True to mirror horizontally. -### `* Each layer is rendered in array order using the existing drawSprite()` - ### `void drawMultiSprite(const MultiSprite& sprite, int x, int y)` **Description:** @@ -436,6 +434,28 @@ Draws a scaled multi-layer sprite. - `scaleX`: Horizontal scaling factor. - `scaleY`: Vertical scaling factor. +### `void drawTileMap(const TileMap& map, int originX, int originY, Color color = Color::White, LayerType layerType = LayerType::Dynamic)` + +**Description:** + +Draws a tilemap of 1bpp sprites. + +**Parameters:** + +- `layerType`: Static layers assume full coverage (no dirty marks); Dynamic marks dirt (animated maps mark only tiles whose frame changed vs last step snapshot when possible). + +### `void drawTileMap(const TileMap2bpp& map, int originX, int originY, LayerType layerType = LayerType::Dynamic)` + +**Description:** + +Draws a tilemap of 2bpp sprites. + +### `void drawTileMap(const TileMap4bpp& map, int originX, int originY, LayerType layerType = LayerType::Dynamic)` + +**Description:** + +Draws a tilemap of 4bpp sprites. + ### `void setOffsetBypass(bool bypass)` **Description:** diff --git a/api/generated/graphics/ResolutionPresets.md b/api/generated/graphics/ResolutionPresets.md index 0b0097b..bf7583b 100644 --- a/api/generated/graphics/ResolutionPresets.md +++ b/api/generated/graphics/ResolutionPresets.md @@ -11,3 +11,30 @@ Factory for creating DisplayConfig from resolution presets. Simplifies display setup on memory-constrained targets by providing a single create() call that sets logical dimensions, physical dimensions, and rotation together. + +## Methods + +### `static DisplayConfig create(ResolutionPreset preset, DisplayType type = ST7789, uint16_t physicalW = 240, uint16_t physicalH = 240)` + +**Description:** + +Creates a DisplayConfig from a preset and hardware target. + +**Parameters:** + +- `preset`: Desired resolution preset. +- `type`: Physical display type (default ST7789). +- `physicalW`: Physical width in pixels (default 240). +- `physicalH`: Physical height in pixels (default 240). + +**Returns:** Configured DisplayConfig with correct logical/physical dimensions. + +### `case RES_240x240: return DisplayConfig(type, 0, physicalW, physicalH, physicalW, physicalH)` + +### `case RES_160x160: return DisplayConfig(type, 0, physicalW, physicalH, 160, 160)` + +### `case RES_128x128: return DisplayConfig(type, 0, physicalW, physicalH, 128, 128)` + +### `case RES_96x96: return DisplayConfig(type, 0, physicalW, physicalH, 96, 96)` + +### `default: return DisplayConfig(type, 0, physicalW, physicalH, physicalW, physicalH)` diff --git a/api/generated/graphics/Sprite2bpp.md b/api/generated/graphics/Sprite2bpp.md index 3b93758..36884d6 100644 --- a/api/generated/graphics/Sprite2bpp.md +++ b/api/generated/graphics/Sprite2bpp.md @@ -7,3 +7,13 @@ ## Description Sprite descriptor for 2bpp (4-color) multi-color sprites. + +## Properties + +| Name | Type | Description | +|------|------|-------------| +| `uint8_t` | `const` | Pointer to 2bpp bitmap data. | +| `Color` | `const` | Pointer to color palette (max 4 colors). | +| `width` | `uint8_t` | Sprite width in pixels. | +| `height` | `uint8_t` | Sprite height in pixels. | +| `paletteSize` | `uint8_t` | Number of colors in the palette. | diff --git a/api/generated/graphics/Sprite4bpp.md b/api/generated/graphics/Sprite4bpp.md index 84e6ea8..2a1c4d6 100644 --- a/api/generated/graphics/Sprite4bpp.md +++ b/api/generated/graphics/Sprite4bpp.md @@ -7,3 +7,13 @@ ## Description Sprite descriptor for 4bpp (16-color) multi-color sprites. + +## Properties + +| Name | Type | Description | +|------|------|-------------| +| `uint8_t` | `const` | Pointer to 4bpp bitmap data. | +| `Color` | `const` | Pointer to color palette (max 16 colors). | +| `width` | `uint8_t` | Sprite width in pixels. | +| `height` | `uint8_t` | Sprite height in pixels. | +| `paletteSize` | `uint8_t` | Number of colors in the palette. | diff --git a/api/generated/graphics/TileAnimationManager.md b/api/generated/graphics/TileAnimationManager.md index e9ee273..367c23e 100644 --- a/api/generated/graphics/TileAnimationManager.md +++ b/api/generated/graphics/TileAnimationManager.md @@ -30,8 +30,6 @@ Resolve tile index to current animated frame. PERFORMANCE: O(1) array lookup, IRAM-friendly, no branches in hot path -### `* Complexity: O(animations × frameCount) when at least one tick elapses; else O(1)` - ### `void step(unsigned long deltaTimeMs)` **Description:** diff --git a/api/generated/graphics/TileMapGeneric.md b/api/generated/graphics/TileMapGeneric.md index c425c03..0852a7c 100644 --- a/api/generated/graphics/TileMapGeneric.md +++ b/api/generated/graphics/TileMapGeneric.md @@ -8,10 +8,19 @@ Generic tilemap structure supporting 1bpp, 2bpp, or 4bpp tile graphics. +T The sprite type used for tiles (Sprite, Sprite2bpp, or Sprite4bpp). + ## Properties | Name | Type | Description | |------|------|-------------| +| `indices` | `uint8_t*` | Pointer to tile indices array (size = width * height). | +| `width` | `uint8_t` | Map width in tiles. | +| `height` | `uint8_t` | Map height in tiles. | +| `T` | `const` | Pointer to tileset array. | +| `tileWidth` | `uint8_t` | Width of each tile in pixels. | +| `tileHeight` | `uint8_t` | Height of each tile in pixels. | +| `tileCount` | `uint16_t` | Number of unique tiles in the tileset. | | `runtimeMask` | `uint8_t*` | Bitmask for runtime tile activation (1 bit per tile, nullptr = all active) | | `animManager` | `TileAnimationManager*` | Optional animation manager for tile animations | diff --git a/api/generated/graphics/TransitionDirection.md b/api/generated/graphics/TransitionDirection.md new file mode 100644 index 0000000..d4e0fbc --- /dev/null +++ b/api/generated/graphics/TransitionDirection.md @@ -0,0 +1,32 @@ +# TransitionDirection + + + +**Source:** `TransitionEffect.h` + +## Description + +Direction of the transition effect. + +Out: starts fully visible and transitions to black/invisible. +In: starts black/invisible and transitions to fully visible. + +## Methods + +### `uint16_t smoothstepQ8(uint16_t t)` + +**Description:** + +Q8.8 smoothstep easing function for transition progress. + +**Parameters:** + +- `t`: Q8.8 input in [0, 256] (0.0 to 1.0 in fixed point). + +**Returns:** Q8.8 eased value in [0, 256]. + +Implements smoothstep(t) = t^2 * (3 - 2t) using fixed-point Q8.8 math: +result = (t^2 * (768 - 2t)) / 65536, clamped to [0, 256]. + +Provides smoother acceleration/deceleration than linear interpolation, +used by DiagonalWipe to avoid harsh pixel boundaries during the wipe. diff --git a/api/generated/graphics/TransitionEffect.md b/api/generated/graphics/TransitionEffect.md new file mode 100644 index 0000000..0b82d3f --- /dev/null +++ b/api/generated/graphics/TransitionEffect.md @@ -0,0 +1,242 @@ +# TransitionEffect + + + +**Source:** `TransitionEffect.h` + +## Description + +Manages a single scene transition with zero runtime allocation. + +Supports three transition types: Fade (palette LUT), Iris (circular wipe), +and DiagonalWipe (corner-to-corner sweep). All state is fixed-size — no +heap allocation in update() or apply(). + +Typical lifecycle: + effect.init(Fade, Out, 500); + while (effect.isActive()) { + effect.update(dt); + effect.apply(buffer, width, height); + } + +## Methods + +### `void init(TransitionType type, TransitionDirection direction, unsigned long durationMs)` + +**Description:** + +Initialise the effect with type, direction and duration. + +**Parameters:** + +- `type`: Fade, Iris or DiagonalWipe transition. +- `direction`: Out (visible→hidden) or In (hidden→visible). +- `durationMs`: Total duration of the transition in milliseconds. + +### `void update(unsigned long deltaTimeMs)` + +**Description:** + +Advance the effect timer. + +**Parameters:** + +- `deltaTimeMs`: Time elapsed since last frame in ms. + +Clamps elapsed to duration — isActive() returns false once elapsed ≥ duration. + +### `void apply(uint8_t* buffer, int width, int height)` + +**Description:** + +Apply the transition effect to an 8bpp framebuffer. + +**Parameters:** + +- `buffer`: Pointer to the 8bpp pixel data (can be nullptr — safe no-op). +- `width`: Buffer width in pixels. +- `height`: Buffer height in pixels. + +Fade: pre-computes LUT from current progress, then maps each pixel through it. +Iris: zeroes pixels whose (x-cx)²+(y-cy)² exceeds current radius² (no sqrt). + +Safe to call when not active — returns immediately with no side effects. + +### `void applyRGB565(uint16_t* buffer, int width, int height)` + +**Description:** + +Apply the transition effect to an RGB565 framebuffer. + +**Parameters:** + +- `buffer`: Pointer to RGB565 pixel data (can be nullptr — safe no-op). +- `width`: Buffer width in pixels. +- `height`: Buffer height in pixels. + +Used on native/SDL2 path where no 8bpp sprite buffer exists. +Iris zeroes pixels outside the circle. Fade darkens/brightens via channel scaling. + +Safe to call when not active — returns immediately with no side effects. + +### `bool isActive() const` + +**Description:** + +Check whether the transition is still running. + +**Returns:** true while elapsed < duration or while hold frames remain. + +After elapsed reaches duration, isActive() stays true for +holdFrames_ additional update ticks. This provides a safety +window for systems that read isActive() before the final +apply() call in the same frame. + +### `float getProgress() const` + +**Description:** + +Get normalised progress of the transition. + +**Returns:** 0.0 at start, 1.0 at completion. + +### `void setIrisCenter(int cx, int cy)` + +**Description:** + +Override the iris center for both Out and In phases (backward compat). + +**Parameters:** + +- `cx`: X-coordinate of the iris center. +- `cy`: Y-coordinate of the iris center. + +Sets both Out and In phases to the same center. Equivalent to calling +both setIrisOutCenter() and setIrisInCenter(). +Only relevant for Iris transitions. Default is buffer center. +Call after init() and before apply(). + +### `void setIrisOutCenter(int cx, int cy)` + +**Description:** + +Override the iris center for the Out (closing) phase. + +**Parameters:** + +- `cx`: X-coordinate of the iris center. +- `cy`: Y-coordinate of the iris center. + +Sets the center used when the iris closes (Out direction). +Only relevant for Iris transitions. Default is buffer center. +Call after init() and before apply(). + +### `void setIrisInCenter(int cx, int cy)` + +**Description:** + +Override the iris center for the In (opening) phase. + +**Parameters:** + +- `cx`: X-coordinate of the iris center. +- `cy`: Y-coordinate of the iris center. + +Sets the center used when the iris opens (In direction). +Only relevant for Iris transitions. Default is buffer center. +Call after init() and before apply(). + +### `void setWipeDirection(WipeDirection dir)` + +**Description:** + +Set the wipe direction for DiagonalWipe transitions. + +**Parameters:** + +- `dir`: Corner-to-corner direction (default: NE_SW). + +Only relevant for DiagonalWipe transitions. Call after init(). + +### `void setHoldFrames(uint8_t frames)` + +**Description:** + +Set the number of hold frames after duration expires. + +**Parameters:** + +- `frames`: Number of update ticks the effect stays active + after reaching the duration boundary (default: 1). + +Provides a safety window for systems that read isActive() before +the final apply() call. Use 0 to disable hold entirely. + +### `void setSubStepMs(uint16_t ms)` + +**Description:** + +Set the sub-step time for DiagonalWipe transitions. + +**Parameters:** + +- `ms`: Sub-step duration in milliseconds (0 disables, default: 0). + +DiagonalWipe can use a sub-step accumulator to quantise elapsed time +into fixed increments, preventing visual flicker from fractional pixel +boundary positions. Set to 16 (≈60 fps frame time) for smooth stepping. +Only affects DiagonalWipe transitions. Fade and Iris are unaffected. + +::: tip +Default is 0 (disabled). Enable explicitly for DiagonalWipe when + you observe boundary flicker during the wipe animation. +::: + +### `void computeFadeLut(uint8_t* lut, uint16_t scaledProgress) const` + +**Description:** + +Fill a 256-byte LUT for the current fade direction and progress. + +**Parameters:** + +- `scaledProgress`: Progress in Q8.8 format (0..256, where 256 = 1.0). + +Out: lut[i] = i * (256-p) / 256 — dims to black. +In: lut[i] = i * p / 256 — brightens from black. + +### `void applyFade(uint8_t* buffer, int width, int height)` + +**Description:** + +Apply the fade LUT to the entire 8bpp buffer. + +### `void applyIris(uint8_t* buffer, int width, int height)` + +**Description:** + +Apply the iris wipe to the entire 8bpp buffer. + +### `void applyIrisRGB565(uint16_t* buffer, int width, int height)` + +**Description:** + +Apply the iris wipe to an RGB565 buffer. + +### `void applyFadeRGB565(uint16_t* buffer, int width, int height)` + +**Description:** + +Apply the fade to an RGB565 buffer via channel scaling. + +### `void applyDiagonalWipe(uint8_t* buffer, int width, int height)` + +**Description:** + +Apply the diagonal wipe to an 8bpp buffer. + +### `void applyDiagonalWipeRGB565(uint16_t* buffer, int width, int height)` + +**Description:** + +Apply the diagonal wipe to an RGB565 buffer. diff --git a/api/generated/graphics/TransitionType.md b/api/generated/graphics/TransitionType.md new file mode 100644 index 0000000..1a5b726 --- /dev/null +++ b/api/generated/graphics/TransitionType.md @@ -0,0 +1,9 @@ +# TransitionType + + + +**Source:** `TransitionEffect.h` + +## Description + +Types of scene transitions. diff --git a/api/generated/graphics/UIAnchorLayout.md b/api/generated/graphics/UIAnchorLayout.md index 91bfa28..0569f0b 100644 --- a/api/generated/graphics/UIAnchorLayout.md +++ b/api/generated/graphics/UIAnchorLayout.md @@ -31,6 +31,62 @@ Adds a UI element with a specific anchor point. - `element`: Pointer to the element to add. - `anchor`: Anchor point for positioning. +### `void addElement(UIElement* element)` + +**Description:** + +Adds a UI element to the layout (defaults to TOP_LEFT anchor). + +**Parameters:** + +- `element`: Pointer to the element to add. + +### `void removeElement(UIElement* element)` + +**Description:** + +Removes a UI element from the layout. + +**Parameters:** + +- `element`: Pointer to the element to remove. + +### `void updateLayout()` + +**Description:** + +Recalculates positions of all elements based on anchors. + +### `void handleInput(const pixelroot32::input::InputManager& input)` + +**Description:** + +Handles input (no-op for anchor layout, elements handle their own input). + +**Parameters:** + +- `input`: Reference to the InputManager. + +### `void update(unsigned long deltaTime)` + +**Description:** + +Updates the layout and child elements. + +**Parameters:** + +- `deltaTime`: Time elapsed since last frame in milliseconds. + +### `void draw(pixelroot32::graphics::Renderer& renderer)` + +**Description:** + +Draws all elements. + +**Parameters:** + +- `renderer`: Reference to the renderer. + ### `void setScreenSize(int screenWidth, int screenHeight)` **Description:** diff --git a/api/generated/graphics/UIButton.md b/api/generated/graphics/UIButton.md index de48508..0838f43 100644 --- a/api/generated/graphics/UIButton.md +++ b/api/generated/graphics/UIButton.md @@ -68,6 +68,10 @@ Checks for touch events within bounds or confirmation buttons if selected. - `input`: The input manager instance. +### `void update(unsigned long deltaTime)` + +### `void draw(pixelroot32::graphics::Renderer& renderer)` + ### `void press()` **Description:** diff --git a/api/generated/graphics/UICheckBox.md b/api/generated/graphics/UICheckBox.md index dc82468..f66f1fe 100644 --- a/api/generated/graphics/UICheckBox.md +++ b/api/generated/graphics/UICheckBox.md @@ -99,6 +99,10 @@ Checks for touch events within bounds or confirmation buttons if selected. - `input`: The input manager instance. +### `void update(unsigned long deltaTime)` + +### `void draw(pixelroot32::graphics::Renderer& renderer)` + ### `void toggle()` **Description:** diff --git a/api/generated/graphics/UIGridLayout.md b/api/generated/graphics/UIGridLayout.md index e5c3b3a..80994d1 100644 --- a/api/generated/graphics/UIGridLayout.md +++ b/api/generated/graphics/UIGridLayout.md @@ -20,6 +20,62 @@ positioning based on grid coordinates. ## Methods +### `void addElement(UIElement* element)` + +**Description:** + +Adds a UI element to the layout. + +**Parameters:** + +- `element`: Pointer to the element to add. + +### `void removeElement(UIElement* element)` + +**Description:** + +Removes a UI element from the layout. + +**Parameters:** + +- `element`: Pointer to the element to remove. + +### `void updateLayout()` + +**Description:** + +Recalculates positions of all elements. + +### `void handleInput(const pixelroot32::input::InputManager& input)` + +**Description:** + +Handles input for navigation and selection. + +**Parameters:** + +- `input`: Reference to the InputManager. + +### `void update(unsigned long deltaTime)` + +**Description:** + +Updates the layout (for child elements). + +**Parameters:** + +- `deltaTime`: Time elapsed since last frame in milliseconds. + +### `void draw(pixelroot32::graphics::Renderer& renderer)` + +**Description:** + +Draws the layout and its visible elements. + +**Parameters:** + +- `renderer`: Reference to the renderer. + ### `void setColumns(uint8_t cols)` **Description:** @@ -72,6 +128,32 @@ Gets the selected element. **Returns:** Pointer to selected element, or nullptr if none selected. +### `void setNavigationButtons(uint8_t upButton, uint8_t downButton, uint8_t leftButton, uint8_t rightButton)` + +**Description:** + +Sets the navigation button indices. + +**Parameters:** + +- `upButton`: Button index for UP navigation. +- `downButton`: Button index for DOWN navigation. +- `leftButton`: Button index for LEFT navigation. +- `rightButton`: Button index for RIGHT navigation. + +### `void setButtonStyle(pixelroot32::graphics::Color selectedTextCol, pixelroot32::graphics::Color selectedBgCol, pixelroot32::graphics::Color unselectedTextCol, pixelroot32::graphics::Color unselectedBgCol)` + +**Description:** + +Sets the style colors for selected and unselected buttons. + +**Parameters:** + +- `selectedTextCol`: Text color when selected. +- `selectedBgCol`: Background color when selected. +- `unselectedTextCol`: Text color when not selected. +- `unselectedBgCol`: Background color when not selected. + ### `void calculateRows()` **Description:** diff --git a/api/generated/graphics/UIHitTest.md b/api/generated/graphics/UIHitTest.md index 7400781..c625b93 100644 --- a/api/generated/graphics/UIHitTest.md +++ b/api/generated/graphics/UIHitTest.md @@ -103,3 +103,19 @@ Find the top-most element that contains the point (const UITouchElement version) - `py`: Y coordinate **Returns:** Pointer to hit element, or nullptr if no hit + +### `static bool intersects(const UITouchWidget& widget, int16_t rx, int16_t ry, uint16_t rw, uint16_t rh)` + +**Description:** + +Check if a rectangle intersects with a widget (AABB) + +**Parameters:** + +- `widget`: The widget to test +- `rx`: Rectangle X (top-left) +- `ry`: Rectangle Y (top-left) +- `rw`: Rectangle width +- `rh`: Rectangle height + +**Returns:** true if rectangles intersect diff --git a/api/generated/graphics/UIHorizontalLayout.md b/api/generated/graphics/UIHorizontalLayout.md index 2a0435c..0726ca4 100644 --- a/api/generated/graphics/UIHorizontalLayout.md +++ b/api/generated/graphics/UIHorizontalLayout.md @@ -20,6 +20,62 @@ navigation automatically. ## Methods +### `void addElement(UIElement* element)` + +**Description:** + +Adds a UI element to the layout. + +**Parameters:** + +- `element`: Pointer to the element to add. + +### `void removeElement(UIElement* element)` + +**Description:** + +Removes a UI element from the layout. + +**Parameters:** + +- `element`: Pointer to the element to remove. + +### `void updateLayout()` + +**Description:** + +Recalculates positions of all elements. + +### `void handleInput(const pixelroot32::input::InputManager& input)` + +**Description:** + +Handles input for navigation and scrolling. + +**Parameters:** + +- `input`: Reference to the InputManager. + +### `void update(unsigned long deltaTime)` + +**Description:** + +Updates the layout (handles smooth scrolling). + +**Parameters:** + +- `deltaTime`: Time elapsed since last frame in milliseconds. + +### `void draw(pixelroot32::graphics::Renderer& renderer)` + +**Description:** + +Draws the layout and its visible elements. + +**Parameters:** + +- `renderer`: Reference to the renderer. + ### `void setScrollEnabled(bool enable)` **Description:** @@ -123,6 +179,19 @@ Sets the navigation button indices. - `leftButton`: Button index for LEFT navigation. - `rightButton`: Button index for RIGHT navigation. +### `void setButtonStyle(pixelroot32::graphics::Color selectedTextCol, pixelroot32::graphics::Color selectedBgCol, pixelroot32::graphics::Color unselectedTextCol, pixelroot32::graphics::Color unselectedBgCol)` + +**Description:** + +Sets the style colors for selected and unselected buttons. + +**Parameters:** + +- `selectedTextCol`: Text color when selected. +- `selectedBgCol`: Background color when selected. +- `unselectedTextCol`: Text color when not selected. +- `unselectedBgCol`: Background color when not selected. + ### `void calculateContentWidth()` **Description:** diff --git a/api/generated/graphics/UILabel.md b/api/generated/graphics/UILabel.md index ec6d004..86ea38e 100644 --- a/api/generated/graphics/UILabel.md +++ b/api/generated/graphics/UILabel.md @@ -49,6 +49,10 @@ Centers the label horizontally on the screen. - `screenWidth`: Width of the screen/container. +### `void update(unsigned long deltaTime)` + +### `void draw(pixelroot32::graphics::Renderer& renderer)` + ### `void recalcSize()` **Description:** diff --git a/api/generated/graphics/UILayout.md b/api/generated/graphics/UILayout.md index 9b23bda..a10056e 100644 --- a/api/generated/graphics/UILayout.md +++ b/api/generated/graphics/UILayout.md @@ -22,29 +22,8 @@ that can be added to scenes. ### `: UIElement(x, y, w, h, UIElementType::LAYOUT)` -**Description:** - -Constructs a new UILayout. - -**Parameters:** - -- `x`: X position of the layout container. -- `y`: Y position of the layout container. -- `w`: Width of the layout container. -- `h`: Height of the layout container. - ### `: UIElement(position, w, h, UIElementType::LAYOUT)` -**Description:** - -Constructs a new UILayout. - -**Parameters:** - -- `position`: Position of the layout container. -- `w`: Width of the layout container. -- `h`: Height of the layout container. - ### `virtual void addElement(UIElement* element)` **Description:** diff --git a/api/generated/graphics/UIPaddingContainer.md b/api/generated/graphics/UIPaddingContainer.md index d2607e8..e6d870b 100644 --- a/api/generated/graphics/UIPaddingContainer.md +++ b/api/generated/graphics/UIPaddingContainer.md @@ -93,6 +93,38 @@ Gets the bottom padding. **Returns:** Bottom padding in pixels. +### `void setPosition(pixelroot32::math::Scalar newX, pixelroot32::math::Scalar newY)` + +**Description:** + +Sets the position of the container. +Also updates the child element's position. + +**Parameters:** + +- `newX`: New X coordinate. +- `newY`: New Y coordinate. + +### `void update(unsigned long deltaTime)` + +**Description:** + +Updates the container and child element. + +**Parameters:** + +- `deltaTime`: Time elapsed since last frame in milliseconds. + +### `void draw(pixelroot32::graphics::Renderer& renderer)` + +**Description:** + +Draws the child element. + +**Parameters:** + +- `renderer`: Reference to the renderer. + ### `void updateChildPosition()` **Description:** diff --git a/api/generated/graphics/UIPanel.md b/api/generated/graphics/UIPanel.md index e5ad321..a31fbb0 100644 --- a/api/generated/graphics/UIPanel.md +++ b/api/generated/graphics/UIPanel.md @@ -92,6 +92,38 @@ Gets the border width. **Returns:** Border width in pixels. +### `void setPosition(pixelroot32::math::Scalar newX, pixelroot32::math::Scalar newY)` + +**Description:** + +Sets the position of the panel. +Also updates the child element's position. + +**Parameters:** + +- `newX`: New X coordinate. +- `newY`: New Y coordinate. + +### `void update(unsigned long deltaTime)` + +**Description:** + +Updates the panel and child element. + +**Parameters:** + +- `deltaTime`: Time elapsed since last frame in milliseconds. + +### `void draw(pixelroot32::graphics::Renderer& renderer)` + +**Description:** + +Draws the panel (background, border) and child element. + +**Parameters:** + +- `renderer`: Reference to the renderer. + ### `void updateChildPosition()` **Description:** diff --git a/api/generated/graphics/UITouchButton.md b/api/generated/graphics/UITouchButton.md index 703736f..0f6a33e 100644 --- a/api/generated/graphics/UITouchButton.md +++ b/api/generated/graphics/UITouchButton.md @@ -181,6 +181,28 @@ Get the OnClick callback **Returns:** The current OnClick callback +### `bool processEvent(const pixelroot32::input::TouchEvent& event)` + +**Description:** + +Process a touch event + +**Parameters:** + +- `event`: The touch event to process + +**Returns:** true if event was consumed by this button + +### `void draw(pixelroot32::graphics::Renderer& renderer)` + +**Description:** + +Render the button + +**Parameters:** + +- `renderer`: Reference to the renderer + ### `void reset()` **Description:** diff --git a/api/generated/graphics/UITouchCheckbox.md b/api/generated/graphics/UITouchCheckbox.md index 6571af3..541c8ef 100644 --- a/api/generated/graphics/UITouchCheckbox.md +++ b/api/generated/graphics/UITouchCheckbox.md @@ -151,6 +151,28 @@ Get the OnChanged callback **Returns:** The current OnChanged callback +### `bool processEvent(const pixelroot32::input::TouchEvent& event)` + +**Description:** + +Process a touch event + +**Parameters:** + +- `event`: The touch event to process + +**Returns:** true if event was consumed by this checkbox + +### `void draw(pixelroot32::graphics::Renderer& renderer)` + +**Description:** + +Render the checkbox + +**Parameters:** + +- `renderer`: Reference to the renderer + ### `void reset()` **Description:** diff --git a/api/generated/graphics/UITouchElement.md b/api/generated/graphics/UITouchElement.md index fe13f39..8bc995c 100644 --- a/api/generated/graphics/UITouchElement.md +++ b/api/generated/graphics/UITouchElement.md @@ -22,6 +22,26 @@ Memory: Owns widget data inline - no external allocation needed. ## Methods +### `void update(unsigned long deltaTime)` + +**Description:** + +Update widget logic + +**Parameters:** + +- `deltaTime`: Time since last frame in ms + +### `void draw(pixelroot32::graphics::Renderer& renderer)` + +**Description:** + +Render the widget + +**Parameters:** + +- `renderer`: Reference to renderer + ### `virtual bool processEvent(const pixelroot32::input::TouchEvent& event)` **Description:** diff --git a/api/generated/graphics/UITouchSlider.md b/api/generated/graphics/UITouchSlider.md index 827696b..d5b3d88 100644 --- a/api/generated/graphics/UITouchSlider.md +++ b/api/generated/graphics/UITouchSlider.md @@ -159,6 +159,28 @@ Check if value changed since last frame **Returns:** true if value changed +### `bool processEvent(const pixelroot32::input::TouchEvent& event)` + +**Description:** + +Process a touch event + +**Parameters:** + +- `event`: The touch event to process + +**Returns:** true if event was consumed by this slider + +### `void draw(pixelroot32::graphics::Renderer& renderer)` + +**Description:** + +Render the slider + +**Parameters:** + +- `renderer`: Reference to the renderer + ### `void reset()` **Description:** diff --git a/api/generated/graphics/UITouchWidget.md b/api/generated/graphics/UITouchWidget.md index c52c9ee..4154a2f 100644 --- a/api/generated/graphics/UITouchWidget.md +++ b/api/generated/graphics/UITouchWidget.md @@ -25,10 +25,6 @@ Base touch widget structure ### `: type(UIWidgetType::Generic)` -**Description:** - -Default constructor - creates empty widget - ### `, state(UIWidgetState::Idle)` ### `, flags(UIWidgetFlags::None)` @@ -45,9 +41,7 @@ Default constructor - creates empty widget ### `: type(widgetType)` -**Description:** - -Construct touch widget with all fields +### `, flags(static_cast(static_cast(UIWidgetFlags::Enabled) | static_cast(UIWidgetFlags::Visible)))` ### `, id(widgetId)` diff --git a/api/generated/graphics/UIVerticalLayout.md b/api/generated/graphics/UIVerticalLayout.md index 1d2c663..476c58a 100644 --- a/api/generated/graphics/UIVerticalLayout.md +++ b/api/generated/graphics/UIVerticalLayout.md @@ -20,6 +20,62 @@ navigation automatically. ## Methods +### `void addElement(UIElement* element)` + +**Description:** + +Adds a UI element to the layout. + +**Parameters:** + +- `element`: Pointer to the element to add. + +### `void removeElement(UIElement* element)` + +**Description:** + +Removes a UI element from the layout. + +**Parameters:** + +- `element`: Pointer to the element to remove. + +### `void updateLayout()` + +**Description:** + +Recalculates positions of all elements. + +### `void handleInput(const pixelroot32::input::InputManager& input)` + +**Description:** + +Handles input for navigation and scrolling. + +**Parameters:** + +- `input`: Reference to the InputManager. + +### `void update(unsigned long deltaTime)` + +**Description:** + +Updates the layout (handles smooth scrolling). + +**Parameters:** + +- `deltaTime`: Time elapsed since last frame in milliseconds. + +### `void draw(pixelroot32::graphics::Renderer& renderer)` + +**Description:** + +Draws the layout and its visible elements. + +**Parameters:** + +- `renderer`: Reference to the renderer. + ### `void setScrollEnabled(bool enable)` **Description:** @@ -123,6 +179,19 @@ Sets the navigation button indices. - `upButton`: Button index for UP navigation. - `downButton`: Button index for DOWN navigation. +### `void setButtonStyle(pixelroot32::graphics::Color selectedTextCol, pixelroot32::graphics::Color selectedBgCol, pixelroot32::graphics::Color unselectedTextCol, pixelroot32::graphics::Color unselectedBgCol)` + +**Description:** + +Sets the style colors for selected and unselected buttons. + +**Parameters:** + +- `selectedTextCol`: Text color when selected. +- `selectedBgCol`: Background color when selected. +- `unselectedTextCol`: Text color when not selected. +- `unselectedBgCol`: Background color when not selected. + ### `void calculateContentHeight()` **Description:** diff --git a/api/generated/graphics/WipeDirection.md b/api/generated/graphics/WipeDirection.md new file mode 100644 index 0000000..6db4b7d --- /dev/null +++ b/api/generated/graphics/WipeDirection.md @@ -0,0 +1,12 @@ +# WipeDirection + + + +**Source:** `TransitionEffect.h` + +## Description + +Corner-to-corner directions for DiagonalWipe transitions. + +Values name the source and target corners: NW_SE starts from top-left +(north-west) and sweeps toward bottom-right (south-east). diff --git a/api/generated/index.md b/api/generated/index.md index d1ae12a..2c86347 100644 --- a/api/generated/index.md +++ b/api/generated/index.md @@ -34,6 +34,7 @@ Auto-generated API documentation from C++ header files. - [Rect](./core/Rect.md) — Represents a 2D rectangle, typically used for hitboxes or bounds. - [Scene](./core/Scene.md) — Represents a game level or screen containing entities. - [SceneManager](./core/SceneManager.md) — Manages the stack of active scenes. +- [TransitionState](./core/TransitionState.md) — State machine for scene transitions. - [WorldCollisionInfo](./core/WorldCollisionInfo.md) — Stores flags indicating which world boundaries were hit in the current frame. ## Drivers @@ -52,9 +53,11 @@ Auto-generated API documentation from C++ header files. - [Anchor](./graphics/Anchor.md) — Defines anchor points for positioning UI elements. - [BaseDrawSurface](./graphics/BaseDrawSurface.md) — Optional base class for DrawSurface implementations providing default primitive rendering. - [Camera2D](./graphics/Camera2D.md) — 2D camera for viewport management and smooth scrolling. +- [CameraEffectsSystem](./graphics/CameraEffectsSystem.md) — Manages up to 4 simultaneous camera effects with round-robin insertion. - [DirtyGrid](./graphics/DirtyGrid.md) — Two-buffer dirty cell grid (8×8 px cells) for selective framebuffer clears. - [DisplayType](./graphics/DisplayType.md) — Identifies the type of display driver to use. - [DrawSurface](./graphics/DrawSurface.md) — Abstract interface for platform-specific drawing operations. +- [EffectSlot](./graphics/EffectSlot.md) — Per-slot state for a single camera effect (20 bytes). - [Font](./graphics/Font.md) — Descriptor for a bitmap font using 1bpp sprites. - [FontManager](./graphics/FontManager.md) — Static utility class for managing bitmap fonts. - [LayerAttributes](./graphics/LayerAttributes.md) — All tiles with attributes in a single tilemap layer. @@ -81,6 +84,9 @@ Auto-generated API documentation from C++ header files. - [TilemapSpriteDirtyMode](./graphics/TilemapSpriteDirtyMode.md) — Suppress per-sprite dirty marks while drawing tilemaps (static layer or selective animated marking). - [TouchConfig](./graphics/TouchConfig.md) — Configuration for a touch controller (XPT2046 or GT911). - [TouchController](./graphics/TouchController.md) — Supported touch controller types. +- [TransitionDirection](./graphics/TransitionDirection.md) — Direction of the transition effect. +- [TransitionEffect](./graphics/TransitionEffect.md) — Manages a single scene transition with zero runtime allocation. +- [TransitionType](./graphics/TransitionType.md) — Types of scene transitions. - [UIAnchorLayout](./graphics/UIAnchorLayout.md) — Layout that positions elements at fixed anchor points on the screen. - [UIButton](./graphics/UIButton.md) — A clickable button UI element. - [UICheckBox](./graphics/UICheckBox.md) — A clickable checkbox UI element. @@ -102,6 +108,7 @@ Auto-generated API documentation from C++ header files. - [UIWidgetFlags](./graphics/UIWidgetFlags.md) — Flags for widget behavior - [UIWidgetState](./graphics/UIWidgetState.md) — Current state of a touch widget - [UIWidgetType](./graphics/UIWidgetType.md) — Types of touch UI widgets +- [WipeDirection](./graphics/WipeDirection.md) — Corner-to-corner directions for DiagonalWipe transitions. ## Input @@ -144,6 +151,7 @@ Auto-generated API documentation from C++ header files. - [RigidActor](./physics/RigidActor.md) — A physics body fully simulated by the engine. - [Segment](./physics/Segment.md) — Represents a 2D line segment for collision detection. - [SensorActor](./physics/SensorActor.md) — A static body that acts as a trigger: detects overlap but produces no physical response. +- [SnapPolicy](./physics/SnapPolicy.md) — Controls floor snap behavior after slide resolution. - [SpatialGrid](./physics/SpatialGrid.md) — Optimized spatial partitioning with separate static/dynamic layers. - [StaticActor](./physics/StaticActor.md) — A physics body that does not move. - [TileBehaviorLayer](./physics/TileBehaviorLayer.md) — Runtime representation of exported behavior layer for O(1) flag lookup. diff --git a/api/generated/input/TouchEvent.md b/api/generated/input/TouchEvent.md index 9cf8833..8738241 100644 --- a/api/generated/input/TouchEvent.md +++ b/api/generated/input/TouchEvent.md @@ -39,10 +39,6 @@ Invariants: ### `: timestamp(0)` -**Description:** - -Default constructor - creates empty event - ### `, x(0)` ### `, y(0)` @@ -57,19 +53,6 @@ Default constructor - creates empty event ### `: timestamp(ts)` -**Description:** - -Construct touch event with all fields - -**Parameters:** - -- `eventType`: Type of event -- `touchId`: Touch identifier -- `xPos`: X coordinate -- `yPos`: Y coordinate -- `ts`: Timestamp in ms -- `eventFlags`: Event flags - ### `, x(xPos)` ### `, y(yPos)` diff --git a/api/generated/input/TouchEventDispatcher.md b/api/generated/input/TouchEventDispatcher.md index fa9986d..bad567f 100644 --- a/api/generated/input/TouchEventDispatcher.md +++ b/api/generated/input/TouchEventDispatcher.md @@ -27,6 +27,34 @@ if (dispatcher.hasEvents()) { ## Methods +### `void processTouch(uint8_t touchId, bool pressed, int16_t x, int16_t y, uint32_t timestamp)` + +**Description:** + +Process raw touch input + +**Parameters:** + +- `touchId`: Touch identifier (0-4) +- `pressed`: True if touch is pressed +- `x`: X position +- `y`: Y position +- `timestamp`: Current timestamp in ms + +Call this every frame with the current touch state. + +### `void processTouchPoints(const TouchPoint* points, uint8_t count, uint32_t timestamp)` + +**Description:** + +Process multiple touch points + +**Parameters:** + +- `points`: Array of touch points +- `count`: Number of touch points +- `timestamp`: Current timestamp in ms + ### `uint8_t getEvents(TouchEvent* events, uint8_t maxCount)` **Description:** diff --git a/api/generated/input/TouchPoint.md b/api/generated/input/TouchPoint.md index ba4f792..a243a51 100644 --- a/api/generated/input/TouchPoint.md +++ b/api/generated/input/TouchPoint.md @@ -31,24 +31,8 @@ Invariants: ### `: x(0), y(0), pressed(false), id(0), ts(0)` -**Description:** - -Default constructor - creates empty/invalid touch point - ### `: x(xPos), y(yPos), pressed(isPressed), id(touchId), ts(timestamp)` -**Description:** - -Construct a touch point with all fields - -**Parameters:** - -- `xPos`: X coordinate -- `yPos`: Y coordinate -- `isPressed`: Touch state -- `touchId`: Touch identifier -- `timestamp`: Timestamp in ms - ### `bool isValid(int16_t maxX, int16_t maxY) const` **Description:** diff --git a/api/generated/input/TouchStateMachine.md b/api/generated/input/TouchStateMachine.md index e23d952..4ed5946 100644 --- a/api/generated/input/TouchStateMachine.md +++ b/api/generated/input/TouchStateMachine.md @@ -20,6 +20,21 @@ O(1) update - deterministic timing ## Methods +### `void update(uint8_t touchId, bool pressed, int16_t x, int16_t y, uint32_t timestamp, TouchEventQueue& outputQueue)` + +**Description:** + +Process a touch input update + +**Parameters:** + +- `touchId`: Touch identifier (0-4) +- `pressed`: True if touch is currently pressed +- `x`: Current X position +- `y`: Current Y position +- `timestamp`: Current timestamp in ms +- `outputQueue`: Queue to enqueue generated events + ### `void reset(uint8_t touchId)` **Description:** @@ -75,6 +90,24 @@ Get time since press for a touch Calculate Manhattan distance between two points +### `void handleTouchDown(uint8_t touchId, int16_t x, int16_t y, uint32_t timestamp, TouchEventQueue& queue)` + +**Description:** + +Handle touch down event + +### `void handleTouchUp(uint8_t touchId, int16_t x, int16_t y, uint32_t timestamp, TouchEventQueue& queue)` + +**Description:** + +Handle touch up event + +### `void handleTouchMove(uint8_t touchId, int16_t x, int16_t y, uint32_t timestamp, TouchEventQueue& queue)` + +**Description:** + +Handle touch move while pressed + ### `void checkLongPress(uint8_t touchId, uint32_t timestamp, TouchEventQueue& queue)` **Description:** diff --git a/api/generated/math/Vector2.md b/api/generated/math/Vector2.md index 6525f49..e1c14ec 100644 --- a/api/generated/math/Vector2.md +++ b/api/generated/math/Vector2.md @@ -98,47 +98,47 @@ Returns vector (1, 0). @return (1, 0) vector. **Returns:** (1, 0) vector. -### `constexpr Scalar lengthSquared() const` +### `constexpr Scalar dot(const Vector2& other) const` **Description:** -Computes squared length. @return Squared length of the vector. +Computes the dot product of two vectors. + +**Parameters:** + +- `other`: The other vector. -**Returns:** Squared length of the vector. +**Returns:** The dot product. -### `inline Scalar length() const` +### `constexpr Scalar lengthSquared() const` **Description:** -Computes length (magnitude). @return Length of the vector. +Computes the squared length of the vector. -**Returns:** Length of the vector. +**Returns:** The squared length. -### `inline void normalize()` +### `void normalize()` **Description:** -Normalizes the vector in place. +Normalizes the vector in-place. -### `inline Vector2 normalized() const` +### `Vector2 normalized() const` **Description:** -Returns a normalized copy. @return Normalized vector. +Returns a normalized copy of the vector. **Returns:** Normalized vector. -### `inline Scalar dot(const Vector2& other) const` +### `Scalar length() const` **Description:** -Dot product with another vector. @param other Vector to compute dot product with. @return Dot product result. - -**Parameters:** - -- `other`: Vector to compute dot product with. +Computes the length of the vector. -**Returns:** Dot product result. +**Returns:** The length. ### `inline Scalar cross(const Vector2& other) const` diff --git a/api/generated/physics/CollisionSystem.md b/api/generated/physics/CollisionSystem.md index ce9c935..4038c1b 100644 --- a/api/generated/physics/CollisionSystem.md +++ b/api/generated/physics/CollisionSystem.md @@ -80,6 +80,21 @@ Gets the total number of registered entities. Clears the collision system state. +### `bool checkCollision(pixelroot32::core::Actor* actor, pixelroot32::core::Actor** outArray, int& count, int maxCount)` + +**Description:** + +Checks for collisions with a specific actor. + +**Parameters:** + +- `actor`: The actor to check. +- `outArray`: Array to store colliding actors. +- `count`: Reference to store the number of collisions found. +- `maxCount`: Maximum number of collisions to return. + +**Returns:** True if any collisions were found. + ### `bool needsCCD(pixelroot32::core::PhysicsActor* body) const` **Description:** @@ -91,3 +106,32 @@ Checks if a body requires continuous collision detection (CCD). - `body`: The physics actor to check. **Returns:** True if CCD is required. + +### `bool sweptCircleVsAABB(pixelroot32::core::PhysicsActor* circle, pixelroot32::core::PhysicsActor* box, pixelroot32::math::Scalar& outTime, pixelroot32::math::Vector2& outNormal)` + +**Description:** + +Performs a swept collision test between a circle and an AABB. + +**Parameters:** + +- `circle`: The moving circle. +- `box`: The static AABB. +- `outTime`: Reference to store the time of impact [0, 1]. +- `outNormal`: Reference to store the collision normal. + +**Returns:** True if a collision occurs. + +### `bool validateOneWayPlatform( pixelroot32::core::PhysicsActor* actor, pixelroot32::core::PhysicsActor* platform, const pixelroot32::math::Vector2& collisionNormal )` + +**Description:** + +Validates if a collision with a one-way platform should occur. + +**Parameters:** + +- `actor`: The moving actor. +- `platform`: The one-way platform. +- `collisionNormal`: The contact normal. + +**Returns:** True if the collision is valid and should be resolved. diff --git a/api/generated/physics/KinematicActor.md b/api/generated/physics/KinematicActor.md index 324f865..4b70b78 100644 --- a/api/generated/physics/KinematicActor.md +++ b/api/generated/physics/KinematicActor.md @@ -18,8 +18,30 @@ moveAndSlide for complex character movement. [PhysicsActor](../core/PhysicsActor.md) → `KinematicActor` +## Properties + +| Name | Type | Description | +|------|------|-------------| +| `constexpr` | `static` | Minimum snap magnitude for SnapPolicy::Step. | + ## Methods +### `bool moveAndCollide(pixelroot32::math::Vector2 motion, KinematicCollision* outCollision = nullptr, bool testOnly = false, pixelroot32::math::Scalar safeMargin = pixelroot32::math::Scalar(0.08f), bool recoveryAsCollision = false)` + +**Description:** + +Moves the body along a vector and stops at the first collision. + +**Parameters:** + +- `motion`: The relative movement vector. +- `outCollision`: Pointer to store collision data if a hit occurs. +- `testOnly`: If true, checks for collision without moving. +- `safeMargin`: Extra margin for collision recovery. +- `recoveryAsCollision`: If true, depenetration is reported as collision. + +**Returns:** true if a collision occurred. + ### `inline bool is_on_ceiling() const` **Description:** @@ -30,10 +52,46 @@ Returns true if the body collided with the ceiling. **Description:** -Returns true if the body collided with the floor. +Returns true if the body collided with the floor this frame. + +### `const pixelroot32::math::Vector2& getFloorVelocity() const` + +**Description:** + +Gets the persisted floor velocity from the last KINEMATIC floor contact. + +**Returns:** Reference to the floor velocity vector. + +### `void clearFloorVelocity()` + +**Description:** + +Clears floor velocity and state. ### `inline bool is_on_wall() const` **Description:** Returns true if the body collided with a wall. + +### `void draw(pixelroot32::graphics::Renderer& renderer)` + +**Description:** + +Draws the actor. + +**Parameters:** + +- `renderer`: Reference to the renderer. + +### `void slide(pixelroot32::math::Vector2& currentMotion, pixelroot32::math::Vector2 upDirection, pixelroot32::core::PhysicsActor*& localFloorBody)` + +**Description:** + +Internal slide loop. Iterates moveAndCollide to slide along surfaces. + +**Parameters:** + +- `currentMotion`: In/out: the motion vector to process (modified by slides). +- `upDirection`: Up vector for floor/ceiling/wall classification. +- `localFloorBody`: Out: set if floor collision is on a KINEMATIC body. diff --git a/api/generated/physics/RigidActor.md b/api/generated/physics/RigidActor.md index 51c94f2..a2177a2 100644 --- a/api/generated/physics/RigidActor.md +++ b/api/generated/physics/RigidActor.md @@ -38,3 +38,33 @@ Applies an instantaneous impulse (velocity change). **Parameters:** - `j`: Impulse vector. + +### `void integrate(pixelroot32::math::Scalar dt)` + +**Description:** + +Integrates forces and velocity to update position. + +**Parameters:** + +- `dt`: Delta time as Scalar. + +### `void update(unsigned long deltaTime)` + +**Description:** + +Logic update called every frame. + +**Parameters:** + +- `deltaTime`: Elapsed time in ms. + +### `void draw(pixelroot32::graphics::Renderer& renderer)` + +**Description:** + +Draws the actor. + +**Parameters:** + +- `renderer`: Reference to the renderer. diff --git a/api/generated/physics/Segment.md b/api/generated/physics/Segment.md index 4bdeac0..f7df29f 100644 --- a/api/generated/physics/Segment.md +++ b/api/generated/physics/Segment.md @@ -57,3 +57,18 @@ Checks intersection between a line segment and a rectangle. - `r`: The rectangle. **Returns:** True if they intersect. + +### `bool sweepCircleVsRect(const Circle& start, const Circle& end, const pixelroot32::core::Rect& rect, pixelroot32::math::Scalar& tHit)` + +**Description:** + +Sweeps a circle against a rectangle to find time of impact. + +**Parameters:** + +- `start`: Circle start position. +- `end`: Circle end position. +- `rect`: The static rectangle. +- `tHit`: Reference to store the time of impact. + +**Returns:** True if a hit occurs along the sweep path. diff --git a/api/generated/physics/SensorActor.md b/api/generated/physics/SensorActor.md index cde2299..575a094 100644 --- a/api/generated/physics/SensorActor.md +++ b/api/generated/physics/SensorActor.md @@ -16,3 +16,7 @@ onCollision() without pushing or blocking the other body. ## Inheritance [StaticActor](./StaticActor.md) → `SensorActor` + +## Methods + +### `void draw(pixelroot32::graphics::Renderer& renderer)` diff --git a/api/generated/physics/SnapPolicy.md b/api/generated/physics/SnapPolicy.md new file mode 100644 index 0000000..89bacb3 --- /dev/null +++ b/api/generated/physics/SnapPolicy.md @@ -0,0 +1,13 @@ +# SnapPolicy + + + +**Source:** `KinematicActor.h` + +## Description + +Controls floor snap behavior after slide resolution. + +- None: slide only (default). +- Step: guarded snap post-step when wasSnapFloor was true at entry. +- Continuous: reserved for future continuous floor adhesion; currently no-op. diff --git a/api/generated/physics/StaticActor.md b/api/generated/physics/StaticActor.md index 2fce15f..2b0ff87 100644 --- a/api/generated/physics/StaticActor.md +++ b/api/generated/physics/StaticActor.md @@ -17,3 +17,15 @@ They are optimized to skip integration and world bound resolution. ## Inheritance [PhysicsActor](../core/PhysicsActor.md) → `StaticActor` + +## Methods + +### `void draw(pixelroot32::graphics::Renderer& renderer)` + +**Description:** + +Draws the actor. + +**Parameters:** + +- `renderer`: Reference to the renderer. diff --git a/api/generated/physics/TileCollisionBuilder.md b/api/generated/physics/TileCollisionBuilder.md index 6ea869e..01c30d7 100644 --- a/api/generated/physics/TileCollisionBuilder.md +++ b/api/generated/physics/TileCollisionBuilder.md @@ -88,3 +88,19 @@ Converts tile coordinates to world position. - `y`: Tile Y coordinate **Returns:** World position vector + +### `inline int buildTileCollisions( pixelroot32::core::Scene& scene, const TileBehaviorLayer& layer, uint8_t tileWidth = 16, uint8_t tileHeight = 16, uint8_t layerIndex = 0 )` + +**Description:** + +Convenience function for building collision bodies from behavior layers. + +**Parameters:** + +- `scene`: Scene to add entities to +- `layer`: Behavior layer to process +- `tileWidth`: Width of tiles in world units +- `tileHeight`: Height of tiles in world units +- `layerIndex`: Layer index for debugging + +**Returns:** Number of entities created, or -1 if entity limit exceeded diff --git a/api/generated/physics/TileConsumptionHelper.md b/api/generated/physics/TileConsumptionHelper.md index 8ce4a8e..8a7430d 100644 --- a/api/generated/physics/TileConsumptionHelper.md +++ b/api/generated/physics/TileConsumptionHelper.md @@ -98,7 +98,7 @@ Template method to check tilemap runtimeMask state. Validate tile coordinates against tilemap dimensions. -### `TileConsumptionHelper helper(scene, tilemap, config)` +### `inline bool consumeTileFromCollision(pixelroot32::core::Actor* tileActor, uintptr_t packedUserData, pixelroot32::core::Scene& scene, void* tilemap, const TileConsumptionConfig& config = TileConsumptionConfig())` **Description:** @@ -113,3 +113,19 @@ Convenience function for consuming tiles from collision callbacks. - `config`: Optional consumption configuration **Returns:** true if tile was consumed, false otherwise + +### `inline int consumeTilesBatch(pixelroot32::core::Scene& scene, void* tilemap, const uint16_t tiles[][2], int count, const TileConsumptionConfig& config = TileConsumptionConfig())` + +**Description:** + +Batch consumption helper for multiple tiles. + +**Parameters:** + +- `scene`: Reference to the scene +- `tilemap`: Pointer to the tilemap +- `tiles`: Array of tile coordinates to consume +- `count`: Number of tiles in the array +- `config`: Optional consumption configuration + +**Returns:** Number of tiles successfully consumed diff --git a/api/generated/test/StressTestScene.md b/api/generated/test/StressTestScene.md index d52f4b7..ed44146 100644 --- a/api/generated/test/StressTestScene.md +++ b/api/generated/test/StressTestScene.md @@ -16,6 +16,12 @@ Scene for stress testing physics performance. ## Methods +### `void init()` + +### `void update(unsigned long deltaTime)` + +### `void draw(pixelroot32::graphics::Renderer& renderer)` + ### `const Metrics& getMetrics() const` ### `void resetMetrics()` diff --git a/api/graphics.md b/api/graphics.md index ee2afe4..1d36b1c 100644 --- a/api/graphics.md +++ b/api/graphics.md @@ -3,12 +3,14 @@ > **Source of truth:** > - `include/graphics/Renderer.h` > - `include/graphics/Camera2D.h` +> - `include/graphics/CameraEffects.h` > - `include/graphics/Color.h` > - `include/graphics/Font.h`, `include/graphics/FontManager.h` > - `include/graphics/StaticTilemapLayerCache.h` > - `include/graphics/DirtyGrid.h` > - `include/graphics/TileAnimation.h` > - `include/graphics/DrawSurface.h`, `include/graphics/BaseDrawSurface.h` +> - `include/graphics/TransitionEffect.h` > - `include/graphics/particles/*.h` ## Overview @@ -38,6 +40,63 @@ Avoids redrawing "static" **4bpp** tilemaps every frame. It caches the static gr Manages the viewport and scrolling of the game world. Handles coordinate transformations and target following with configurable dead zones. +### CameraEffectsSystem + +*(Requires `PIXELROOT32_ENABLE_CAMERA_EFFECTS=1`)* + +Manages up to 4 simultaneous camera effects with round-robin insertion. Effects are updated each frame and the summed offset is retrieved via `getOffset()` for application to a Camera2D. + +**Effect Types**: + +| Type | Description | Use Case | +|------|-------------|----------| +| `Shake` | Random oscillation with amplitude | Explosions, impacts, earthquakes | +| `Punch` | Directional impulse with linear decay | Hits, kicks, knockback | +| `Offset` | Constant displacement for duration | Camera lerp, recoil | + +**API**: + +```cpp +#include + +using namespace pixelroot32::graphics; + +// Initialize +CameraEffectsSystem effects; + +// Trigger effects +effects.triggerShake(2.0f, 200); // amplitude, duration (ms) +effects.triggerPunch(3.0f, 150, Vector2(-1, 0)); // amp, dur, direction +effects.triggerOffset(4.0f, 100); // amplitude, duration + +// Update (call each frame) +effects.update(deltaTime); + +// Get offset (apply to Camera2D) +if (effects.hasActiveEffects()) { + math::Vector2 offset = effects.getOffset(); + camera.applyWithEffect(renderer, offset); +} + +// Cancel all effects +effects.cancelAll(); +``` + +**Performance**: +- Zero heap allocation (`std::array`) +- Fast early-out via `hasActiveEffects()` +- Shake uses Xorshift32 random (pure integer math, no floats) +- Stub implementation when disabled (zero overhead) + +**Feature Gate**: +```ini +; platformio.ini +build_flags = + -DPIXELROOT32_ENABLE_CAMERA_EFFECTS=1 +``` + +When disabled, `CameraEffectsSystem` becomes a no-op stub — all methods return zero/empty, no RAM or CPU cost. + ### Color and Palettes The engine supports indexed colors via the `Color` enumeration. @@ -107,10 +166,73 @@ Lightweight, step-based animation controller for advancing through an array of ` Abstract interfaces for platform-specific drawing operations (e.g., `SDL2_Drawer`, `TFT_eSPI_Drawer`). +### TransitionEffect + +*(Requires `PIXELROOT32_ENABLE_SCENE_TRANSITIONS=1`)* + +Provides scene transition effects (Fade and Iris) for smooth visual transitions between scenes. Uses direct 8bpp buffer access for zero-allocation, ESP32-friendly implementation. + +**Transition Types**: + +| Type | Method | Description | +|------|--------|-------------| +| `Fade` | Palette manipulation | Smooth global dimming via 256-byte LUT | +| `Iris` | Buffer circle | Circular wipe using squared-distance test | + +**API**: + +```cpp +#include + +using namespace pixelroot32::graphics; + +// Create effect +TransitionEffect effect; + +// Start transition +effect.begin(TransitionType::Fade, 500, TransitionDirection::Out); + +// Update (call each frame) +effect.update(deltaTime); + +// Apply to buffer +if (effect.isActive()) { + uint8_t* buffer = surface->getSpriteBuffer(); + effect.apply(buffer, logicalWidth, logicalHeight); +} + +// Check completion +if (effect.isComplete()) { + // Transition finished +} + +// Iris customization +effect.setIrisCenter(64, 64); // Set circle center +``` + +**Performance**: +- Fade: ~2-4% frame budget (LUT lookup per pixel) +- Iris: ~2.8% frame budget (squared-distance test, no sqrt) +- Zero heap allocation (256-byte LUT on stack) +- Direct buffer access via `getSpriteBuffer()` + +**Feature Gate**: +```ini +; platformio.ini +build_flags = + -DPIXELROOT32_ENABLE_SCENE_TRANSITIONS=1 +``` + +When disabled, `TransitionEffect` becomes a no-op stub — all methods are safe to call but do nothing. + +See [Scene Management Guide](../guide/scenes.md#level-transitions-built-in) for usage examples. + ## Related Types - `Renderer` → `include/graphics/Renderer.h` - `Camera2D` → `include/graphics/Camera2D.h` +- `CameraEffectsSystem` → `include/graphics/CameraEffects.h` +- `TransitionEffect` → `include/graphics/TransitionEffect.h` - `Color`, `PaletteType` → `include/graphics/Color.h` - `Font`, `FontManager` → `include/graphics/FontManager.h` - `Sprite`, `TileMap` → `include/graphics/Renderer.h` diff --git a/architecture/layer-scene.md b/architecture/layer-scene.md index a94f408..d35c7e5 100644 --- a/architecture/layer-scene.md +++ b/architecture/layer-scene.md @@ -19,6 +19,7 @@ Central class that orchestrates all subsystems. - Manages Renderer, SceneManager, InputManager, AudioEngine, MusicPlayer - Runs the main game loop - Provides automatic touch processing (when enabled) +- Manages scene transitions (Fade, Iris) via `TransitionEffect` **Game Loop**: @@ -45,10 +46,41 @@ void Engine::update() { void Engine::draw() { renderer.beginFrame(); sceneManager.draw(renderer); + + // Apply transition overlay (after scene draw, before present) + if (sceneManager.isTransitioning()) { + sceneManager.drawTransitionOverlay(renderer); + } + renderer.endFrame(); } ``` +**Scene Transitions** (`PIXELROOT32_ENABLE_SCENE_TRANSITIONS=1`): + +```cpp +// Trigger a transition +void Engine::triggerTransition( + graphics::TransitionType type, // Fade or Iris + unsigned long durationMs, // Duration per phase (ms) + graphics::TransitionDirection dir // Out (hide) or In (reveal) +); + +// Check if transitioning +bool isTransitioning() const; +``` + +**Transition State Machine**: + +```mermaid +stateDiagram-v2 + [*] --> Idle + Idle --> FadingOut: triggerTransition() + FadingOut --> SceneSwap: fade complete + SceneSwap --> FadingIn: scene swapped + FadingIn --> Idle: fade complete +``` + **Touch Integration** (`PIXELROOT32_ENABLE_TOUCH=1`): - `getTouchDispatcher()`: Access touch event dispatcher @@ -70,15 +102,19 @@ See [Touch Input Architecture](touch-input.md) for details. **Files**: `include/core/SceneManager.h`, `src/core/SceneManager.cpp` -Scene stack management (push/pop operations). +Scene stack management (push/pop operations) and transition orchestration. **Operations**: | Method | Description | |--------|-------------| -| `setCurrentScene()` | Replace current scene | +| `setCurrentScene()` | Replace current scene (immediate) | | `pushScene()` | Push new scene (pauses previous) | | `popScene()` | Pop scene (resumes previous) | +| `transitionToScene()` | Begin transition to new scene (Fade/Iris) | +| `isTransitioning()` | Check if transition is active | +| `updateTransitions()` | Update transition state machine | +| `drawTransitionOverlay()` | Render transition effect overlay | **Scene Stack**: @@ -93,6 +129,26 @@ Useful for: - Settings screens - Dialog overlays +**Transition Support** (`PIXELROOT32_ENABLE_SCENE_TRANSITIONS=1`): + +```cpp +// Internal state machine +enum class TransitionState : uint8_t { + Idle, // No transition active + FadingOut, // Applying effect to hide current scene + SceneSwap, // Swapping scene pointer (atomic) + FadingIn // Applying effect to reveal new scene +}; + +// Transition is orchestrated by SceneManager but effect is owned by Engine +void SceneManager::updateTransitions(unsigned long deltaTime); +void SceneManager::drawTransitionOverlay(graphics::Renderer& renderer); +``` + +::: info Input Blocking +During transitions (`FadingOut` or `FadingIn`), `SceneManager::update()` skips scene updates and input processing. This ensures clean transitions without ghost inputs. +::: + --- ### Scene diff --git a/architecture/physics-subsystem.md b/architecture/physics-subsystem.md index 5d1208c..c330e11 100644 --- a/architecture/physics-subsystem.md +++ b/architecture/physics-subsystem.md @@ -154,10 +154,8 @@ void Scene::update(unsigned long deltaTime) { ```ini # platformio.ini --D PIXELROOT32_ENABLE_PHYSICS_FIXED_TIMESTEP=1 ; Enable scheduler (profile_full/arcade) -D PIXELROOT32_VELOCITY_DAMPING=0.999 ; Per-frame damping (default) -D PIXELROOT32_MAX_VELOCITY=500 ; Max velocity (units/s, default) --D PIXELROOT32_HAS_FAST_RSQRT=1 ; Enable fast reciprocal sqrt ``` --- diff --git a/examples/camera-effect-demo.md b/examples/camera-effect-demo.md new file mode 100644 index 0000000..2fb4662 --- /dev/null +++ b/examples/camera-effect-demo.md @@ -0,0 +1,74 @@ +# Camera Effect Demo Example + +Interactive menu-based demo that showcases all **`CameraEffectsSystem`** effects: **shake**, **punch** (4 directions), **offset**, and **cancel all**. Select an effect from the menu, watch it activate for a few seconds, then return to the menu. Built as a visual reference for developers integrating camera effects into their own games. + +## Requirements (build flags) + +- **`PIXELROOT32_ENABLE_CAMERA_EFFECTS`** +- **`PIXELROOT32_ENABLE_UI_SYSTEM`** + +Both are enabled by default in [`PlatformDefaults.h`](../../include/platforms/PlatformDefaults.h). See **`platformio.ini`** in this folder for `native` and **`esp32dev`** presets. + +The scene expects **`extern pixelroot32::core::Engine engine`** (see `src/platforms/native.h` / `esp32_dev.h` and `main.cpp`). + +## Platforms + +| Environment | Notes | +|-------------|--------| +| **`native`** | SDL2 window, 240×240 logical size (paths to SDL on Windows may need adjustment in `platformio.ini`). | +| **`esp32dev`** | **ST7789** TFT 240×240, TFT_eSPI-style pin defines in `platformio.ini`. | + +The engine version or Git branch is set in **`lib_deps`** in `platformio.ini`. + +## Controls + +- **UP / DOWN** — navigate effect list (buttons **0** and **1** in `InputManager` order). +- **SELECT** — trigger the selected effect (button **5**). +- **BACK** — return to menu from active effect (button **4**). + +## Features + +- **`CameraEffectsSystem`**: shake, punch (up/down/left/right), offset, cancel all +- **`Camera2D`** integration via `apply(renderer, getCameraEffectOffset())` +- **`UIVerticalLayout`** menu with `UIButton` navigation (same pattern as `music_demo`) +- Auto-cancel after 2 seconds, instant cancel via "Cancel All" +- Static vs dynamic draw ordering to visualize effect displacement + +## Effects + +| Effect | Preset | Description | +|--------|--------|-------------| +| **Shake** | amp=8, dur=2000ms | Random oscillation with linear decay | +| **Punch Up** | amp=6, dur=1500ms | Directional impulse upward | +| **Punch Down** | amp=6, dur=1500ms | Directional impulse downward | +| **Punch Left** | amp=6, dur=1500ms | Directional impulse leftward | +| **Punch Right** | amp=6, dur=1500ms | Directional impulse rightward | +| **Offset** | amp=4, dur=2000ms | Constant displacement (default RIGHT) | +| **Cancel All** | — | Immediately clears all active effects | + +## Documentation links + +- [Graphics — CameraEffectsSystem](../../docs/api/graphics.md#cameraeffects) +- [Graphics — Camera2D](../../docs/api/graphics.md#camera2d) +- [Core — Scene / entities](../../docs/api/core.md) +- [Architecture](../../docs/architecture/architecture-index.md) + +## Build + +Run from **`examples/camera-effect-demo`**: + +```bash +pio run -e native +pio run -e esp32dev +``` + +## Upload (ESP32) + +```bash +pio run -e esp32dev --target upload +``` + + +--- + +**Source code:** https://github.com/PixelRoot32-Game-Engine/PixelRoot32-Game-Engine/tree/main/examples/camera_effect_demo diff --git a/examples/camera.md b/examples/camera.md index c813f7c..96cfd3e 100644 --- a/examples/camera.md +++ b/examples/camera.md @@ -1,10 +1,11 @@ # Camera Demo Example -Side-scrolling platformer-style demo that showcases **`Camera2D`** (smoothing and horizontal bounds), **parallax background layers**, and **`KinematicActor`** movement with tile-based ground and one-way platforms (`StaticActor`, collision layers). The world is wider than the screen so the camera follows the player. +Side-scrolling platformer-style demo that showcases **`Camera2D`** (smoothing and horizontal bounds), **parallax background layers**, **`KinematicActor`** movement with tile-based ground and one-way platforms (`StaticActor`, collision layers), and **directional iris scene transitions** between two scenes. The world is wider than the screen so the camera follows the player. ## Requirements (build flags) - **`PIXELROOT32_ENABLE_SCENE_ARENA`** +- **`PIXELROOT32_ENABLE_SCENE_TRANSITIONS`** (enabled by default in `PlatformDefaults.h`) Additional engine features (physics actors, tilemaps) follow defaults from [`PlatformDefaults.h`](../../include/platforms/PlatformDefaults.h). See **`platformio.ini`** in this folder for `native` and **`esp32dev`** presets. @@ -14,8 +15,8 @@ The scene expects **`extern pixelroot32::core::Engine engine`** (see `src/platfo | Environment | Notes | |-------------|--------| -| **`native`** | SDL2 window, 240×240 logical size (paths to SDL on Windows may need adjustment in `platformio.ini`). | -| **`esp32dev`** | **ST7789** TFT 240×240, TFT_eSPI-style pin defines in `platformio.ini`. | +| **`native`** | SDL2 window, 240×240 logical size. Transitions work via RGB565 pixel buffer path. | +| **`esp32dev`** | **ST7789** TFT 240×240, TFT_eSPI-style pin defines in `platformio.ini`. Transitions work via 8bpp sprite buffer path. | The engine version or Git branch is set in **`lib_deps`** in `platformio.ini`. @@ -24,17 +25,61 @@ The engine version or Git branch is set in **`lib_deps`** in `platformio.ini`. - **Left / Right** — move (buttons **2** and **3** in `InputManager` order). - **Jump** — button **4** (edge-triggered after release so hold does not spam jump). +## Scenes + +The demo contains two scenes with identical gameplay but different color palettes: + +| | CameraDemoScene (Scene 1) | CameraDemoScene2 (Scene 2) | +|---|---|---| +| Parallax far | DarkBlue | Teal | +| Parallax mid | DarkGreen | Orange | +| Tilemap color | Brown | Gold | + +Both scenes share the same tilemap layout (ground + 3 platforms), player physics, and camera follow. + +### Scene Transitions + +- **Scene 1 → Scene 2**: Iris transition closes from the **right edge**, opens from the **left edge**. Triggered when the player reaches the rightmost end of the level. +- **Scene 2 → Scene 1**: Iris transition closes from the **left edge**, opens from the **right edge**. Triggered when the player reaches the leftmost edge (position ≤ 0). + +The iris effect uses directional centers (`irisOutCx/Cy`, `irisInCx/Cy`) stored in `SceneManager` and re-applied after each `TransitionEffect::init()` call. + +### Transition Rendering Paths + +The engine automatically selects the correct rendering path: + +- **ESP32 (8bpp)**: `TransitionEffect::apply()` operates on the TFT_eSPI sprite buffer (palette-indexed). +- **Native/SDL2 (RGB565)**: `TransitionEffect::applyRGB565()` operates directly on the SDL2 pixel buffer when `getSpriteBuffer()` returns `nullptr`. + ## Features - **`Camera2D`**: follow target, bounds, locked vertical scroll in this demo -- **Parallax** layers (`GameLayers`) + tilemap strip for ground/platforms +- **Parallax** layers + tilemap strip for ground/platforms - **`KinematicActor`** player cube (`PlayerCube`), gravity and one-way platform collision masks -- **Scene arena** for stable entity storage +- **Scene arena** for stable entity storage (fixed-size array, no heap allocation) +- **Directional iris transitions** between two scenes with opposite center directions +- **`TransitionEffect`**: Fade (palette LUT) and Iris (circle wipe), zero-allocation + +## File Structure + +``` +src/ +├── CameraDemoScene.h/.cpp — Scene 1 (platformer, transitions to Scene 2) +├── CameraDemoScene2.h/.cpp — Scene 2 (identical gameplay, different colors, back to Scene 1) +├── PlayerCube.h/.cpp — KinematicActor with gravity/jump/movement +├── GameConstants.h — Tile size, player dimensions, physics constants +├── GameLayers.h — Collision layer bitmasks +└── platforms/ + ├── native.h — SDL2 engine wiring + └── esp32_dev.h — ESP32 engine wiring +``` ## Documentation links - [Graphics — Camera2D](../../docs/api/graphics.md#camera2d) +- [Graphics — TransitionEffect](../../docs/api/generated/graphics/TransitionEffect.md) - [Core — Scene / entities](../../docs/api/core.md) +- [Core — SceneManager transitions](../../docs/api/generated/core/SceneManager.md) - [Physics — kinematic & static actors](../../docs/api/physics.md) - [Architecture](../../docs/architecture/architecture-index.md) diff --git a/examples/demos.md b/examples/demos.md index f2e5d3e..d42d56a 100644 --- a/examples/demos.md +++ b/examples/demos.md @@ -21,6 +21,7 @@ The engine revision for each example is defined in `**lib_deps**` inside that ex - [animated_tilemap](./animated_tilemap) — [source code](https://github.com/PixelRoot32-Game-Engine/PixelRoot32-Game-Engine/tree/main/examples/animated_tilemap) - [brick_breaker](./brick_breaker) — [source code](https://github.com/PixelRoot32-Game-Engine/PixelRoot32-Game-Engine/tree/main/examples/brick_breaker) - [camera](./camera) — [source code](https://github.com/PixelRoot32-Game-Engine/PixelRoot32-Game-Engine/tree/main/examples/camera) +- [camera-effect-demo](./camera-effect-demo) — [source code](https://github.com/PixelRoot32-Game-Engine/PixelRoot32-Game-Engine/tree/main/examples/camera-effect-demo) - [dual_palette](./dual_palette) — [source code](https://github.com/PixelRoot32-Game-Engine/PixelRoot32-Game-Engine/tree/main/examples/dual_palette) - [flappy_bird](./flappy_bird) — [source code](https://github.com/PixelRoot32-Game-Engine/PixelRoot32-Game-Engine/tree/main/examples/flappy_bird) - [hello_world](./hello_world) — [source code](https://github.com/PixelRoot32-Game-Engine/PixelRoot32-Game-Engine/tree/main/examples/hello_world) diff --git a/examples/metroidvania.md b/examples/metroidvania.md index e817246..1b793a0 100644 --- a/examples/metroidvania.md +++ b/examples/metroidvania.md @@ -10,6 +10,7 @@ A compact **platformer** sample with **4bpp tilemap layers**, **`StaticTilemapLa - **`PIXELROOT32_ENABLE_2BPP_SPRITES`** (enabled alongside 4bpp in this example's `platformio.ini`) - **`PIXELROOT32_ENABLE_SCENE_ARENA`** - **`PIXELROOT32_ENABLE_DIRTY_REGIONS`** +- **`PIXELROOT32_ENABLE_CAMERA_EFFECTS`** — camera shake when player falls into void See **`platformio.ini`** for **`native`** and **`esp32dev`** presets (no `esp32cyd` environment in this project). @@ -39,6 +40,8 @@ The **`PlayerActor`** extends **`KinematicActor`** and implements: Drawing goes through **`StaticTilemapLayerCache`**: allocate for the renderer when layers are ready, draw static groups with camera offsets, and **`invalidate()`** when static tile data or relevant animators change. See [Animated Tilemap README](../animated_tilemap/README.md) for the detailed invalidation table and [Architecture — static tilemap cache](../../docs/architecture/architecture-index.md#static-tilemap-layer-cache-engine--scenes). +**Note**: During camera shake, the `StaticTilemapLayerCache` auto-invalidates each frame because the renderer offset changes. This ensures tilemaps shake along with entities. After the shake ends, the cache resumes its fast memcpy path. + ## Dirty Regions This example enables **`PIXELROOT32_ENABLE_DIRTY_REGIONS`** for targeted clearing on ESP32. The rendering pipeline uses a dirty-grid approach to selectively clear only the regions that changed between frames, reducing SPI transfer overhead on the display. @@ -52,6 +55,7 @@ This example enables **`PIXELROOT32_ENABLE_DIRTY_REGIONS`** for targeted clearin - **Stairs mask cache** — bitmask RAM cache built once from tile indices for fast overlap checks - **State-driven sprite animation** — `IDLE`, `RUN`, `JUMP`, `CLIMBING` states - **Scene arena** + owned layer entities +- **Camera shake on void fall** — when the player falls below the world boundary, the entire screen (tilemaps + entities) shakes for 200ms before respawning ## Documentation links diff --git a/guide/scenes.md b/guide/scenes.md index 5dada42..bedb0fb 100644 --- a/guide/scenes.md +++ b/guide/scenes.md @@ -330,22 +330,74 @@ public: }; ``` -### Level Transitions +### Level Transitions (Built-in) + +The engine provides a built-in scene transition system with Fade and Iris effects. Transitions are triggered via the `Engine::triggerTransition()` API and are feature-gated via `PIXELROOT32_ENABLE_SCENE_TRANSITIONS`. ```cpp -class TransitionScene : public Scene { +#include +#include + +using namespace pixelroot32; + +// Fade transition (smooth black dimming) +void GameLevel::completeLevel() { + // Trigger fade-out → scene swap → fade-in (500ms each phase) + engine->triggerTransition( + graphics::TransitionType::Fade, + 500, // duration in ms per phase + graphics::TransitionDirection::Out // fade out first + ); + + // Scene is swapped automatically after fade-out completes + engine->setScene(new NextLevel()); +} + +// Iris transition (circular wipe) +void GameLevel::enterBossRoom() { + engine->triggerTransition( + graphics::TransitionType::Iris, + 400, + graphics::TransitionDirection::Out + ); + + engine->setScene(new BossScene()); +} + +// Iris with custom center (offset iris) +void GameLevel::teleportPlayer() { + graphics::TransitionEffect effect; + effect.setIrisCenter(128, 64); // Right side of screen + + engine->triggerTransition( + graphics::TransitionType::Iris, + 300, + graphics::TransitionDirection::Out + ); + + engine->setScene(new TeleportScene()); +} +``` + +::: tip Feature Gate +Scene transitions require `PIXELROOT32_ENABLE_SCENE_TRANSITIONS=1` in your build flags. When disabled, `triggerTransition()` becomes a no-op with zero overhead. +::: + +::: warning Transition State +During a transition, input is blocked and scenes cannot be changed. Wait for the transition to complete before triggering another one. Check `isTransitioning()` if needed. +::: + +### Manual Transitions (Legacy) + +For custom transition effects not covered by the built-in system, you can implement manual transitions: + +```cpp +class CustomTransitionScene : public Scene { Scene* nextScene; unsigned long elapsed = 0; public: - TransitionScene(Scene* next) : nextScene(next) {} - - void draw(Renderer& r) override { - // Fade effect based on elapsed time - int alpha = (elapsed * 255) / 1000; - r.drawFilledRectangleW(0, 0, 240, 240, - (alpha << 8) | alpha); // Fade to black - } + CustomTransitionScene(Scene* next) : nextScene(next) {} void update(unsigned long deltaTime) override { elapsed += deltaTime; @@ -354,11 +406,15 @@ public: engine->setScene(nextScene); } } + + void draw(Renderer& r) override { + // Custom effect here + } }; // Usage -void GameLevel::completeLevel() { - engine->setScene(new TransitionScene(new NextLevel())); +void GameLevel::customTransition() { + engine->setScene(new CustomTransitionScene(new NextLevel())); } ```