implements PLN-0026
This commit is contained in:
parent
b0b8bb9028
commit
4f52a65169
@ -247,10 +247,15 @@ impl FrameComposer {
|
|||||||
{
|
{
|
||||||
let update = resolver.update(scene, self.camera_x_px, self.camera_y_px);
|
let update = resolver.update(scene, self.camera_x_px, self.camera_y_px);
|
||||||
Self::apply_refresh_requests(cache, scene, &update.refresh_requests);
|
Self::apply_refresh_requests(cache, scene, &update.refresh_requests);
|
||||||
|
// `FrameComposer` owns only canonical game-frame composition.
|
||||||
|
// Deferred `gfx.*` primitives are drained later by a separate
|
||||||
|
// overlay/debug stage outside this service boundary.
|
||||||
gfx.render_scene_from_cache(cache, &update);
|
gfx.render_scene_from_cache(cache, &update);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// No-scene frames still stop at canonical game composition. Final
|
||||||
|
// overlay/debug work remains outside `FrameComposer`.
|
||||||
gfx.render_no_scene_frame();
|
gfx.render_no_scene_frame();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -31,22 +31,11 @@ pub enum BlendMode {
|
|||||||
|
|
||||||
/// PROMETEU Graphics Subsystem (GFX).
|
/// PROMETEU Graphics Subsystem (GFX).
|
||||||
///
|
///
|
||||||
/// Models a specialized graphics chip with a fixed resolution, double buffering,
|
/// `Gfx` owns the framebuffer backend and the canonical game-frame raster path
|
||||||
/// and a multi-layered tile/sprite architecture.
|
/// consumed by `FrameComposer`. That canonical path covers scene composition,
|
||||||
///
|
/// sprite composition, and fades. Public `gfx.*` primitives remain valid, but
|
||||||
/// The GFX system works by composing several "layers" into a single 16-bit
|
/// they do not define the canonical game composition contract; they belong to a
|
||||||
/// RGB565 framebuffer. It supports hardware-accelerated primitives (lines, rects)
|
/// separate final overlay/debug stage.
|
||||||
/// and specialized console features like background scrolling and sprite sorting.
|
|
||||||
///
|
|
||||||
/// ### Layer Composition Order (back to front):
|
|
||||||
/// 1. **Priority 0 Sprites**: Objects behind everything else.
|
|
||||||
/// 2. **Tile Layer 0 + Priority 1 Sprites**: Background 0.
|
|
||||||
/// 3. **Tile Layer 1 + Priority 2 Sprites**: Background 1.
|
|
||||||
/// 4. **Tile Layer 2 + Priority 3 Sprites**: Background 2.
|
|
||||||
/// 5. **Tile Layer 3 + Priority 4 Sprites**: Foreground.
|
|
||||||
/// 6. **Scene Fade**: Global brightness/color filter.
|
|
||||||
/// 7. **HUD Layer**: Fixed UI elements (always on top).
|
|
||||||
/// 8. **HUD Fade**: Independent fade for the UI.
|
|
||||||
pub struct Gfx {
|
pub struct Gfx {
|
||||||
/// Width of the internal framebuffer in pixels.
|
/// Width of the internal framebuffer in pixels.
|
||||||
w: usize,
|
w: usize,
|
||||||
@ -54,7 +43,8 @@ pub struct Gfx {
|
|||||||
h: usize,
|
h: usize,
|
||||||
/// Front buffer: the "VRAM" currently being displayed by the Host window.
|
/// Front buffer: the "VRAM" currently being displayed by the Host window.
|
||||||
front: Vec<u16>,
|
front: Vec<u16>,
|
||||||
/// Back buffer: the "Work RAM" where new frames are composed.
|
/// Back buffer: the working buffer where canonical game frames are composed
|
||||||
|
/// before any final overlay/debug drain.
|
||||||
back: Vec<u16>,
|
back: Vec<u16>,
|
||||||
|
|
||||||
/// Shared access to graphical memory banks (tiles and palettes).
|
/// Shared access to graphical memory banks (tiles and palettes).
|
||||||
|
|||||||
@ -48,9 +48,21 @@ pub trait GfxBridge {
|
|||||||
fn draw_horizontal_line(&mut self, x0: i32, x1: i32, y: i32, color: Color);
|
fn draw_horizontal_line(&mut self, x0: i32, x1: i32, y: i32, color: Color);
|
||||||
fn draw_vertical_line(&mut self, x: i32, y0: i32, y1: i32, color: Color);
|
fn draw_vertical_line(&mut self, x: i32, y0: i32, y1: i32, color: Color);
|
||||||
fn present(&mut self);
|
fn present(&mut self);
|
||||||
|
/// Render the canonical game frame with no bound scene.
|
||||||
|
///
|
||||||
|
/// Deferred `gfx.*` overlay/debug primitives are intentionally outside this
|
||||||
|
/// contract and are drained by a separate final overlay stage.
|
||||||
fn render_no_scene_frame(&mut self);
|
fn render_no_scene_frame(&mut self);
|
||||||
|
/// Render the canonical scene-backed game frame from cache/resolver state.
|
||||||
|
///
|
||||||
|
/// Deferred `gfx.*` overlay/debug primitives are intentionally outside this
|
||||||
|
/// contract and are drained by a separate final overlay stage.
|
||||||
fn render_scene_from_cache(&mut self, cache: &SceneViewportCache, update: &ResolverUpdate);
|
fn render_scene_from_cache(&mut self, cache: &SceneViewportCache, update: &ResolverUpdate);
|
||||||
fn load_frame_sprites(&mut self, sprites: &[Sprite]);
|
fn load_frame_sprites(&mut self, sprites: &[Sprite]);
|
||||||
|
/// Submit text into the `gfx.*` primitive path.
|
||||||
|
///
|
||||||
|
/// Under the accepted runtime contract this is not the canonical game
|
||||||
|
/// composition path; it belongs to the deferred final overlay/debug family.
|
||||||
fn draw_text(&mut self, x: i32, y: i32, text: &str, color: Color);
|
fn draw_text(&mut self, x: i32, y: i32, text: &str, color: Color);
|
||||||
fn draw_char(&mut self, x: i32, y: i32, c: char, color: Color);
|
fn draw_char(&mut self, x: i32, y: i32, c: char, color: Color);
|
||||||
|
|
||||||
|
|||||||
@ -48,10 +48,12 @@ The GFX maintains two buffers:
|
|||||||
|
|
||||||
Per-frame flow:
|
Per-frame flow:
|
||||||
|
|
||||||
1. The system draws to the back buffer
|
1. The system prepares the logical frame
|
||||||
2. Calls `present()`
|
2. Canonical game composition is rendered into the back buffer
|
||||||
3. Buffers are swapped
|
3. Deferred final overlay/debug primitives are drained on top of the completed game frame
|
||||||
4. The host displays the front buffer
|
4. Calls `present()`
|
||||||
|
5. Buffers are swapped
|
||||||
|
6. The host displays the front buffer
|
||||||
|
|
||||||
This guarantees:
|
This guarantees:
|
||||||
|
|
||||||
@ -183,7 +185,7 @@ Access:
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 10. Projection to the Back Buffer
|
## 10. Canonical Game Projection to the Back Buffer
|
||||||
|
|
||||||
For each frame:
|
For each frame:
|
||||||
|
|
||||||
@ -198,6 +200,10 @@ For each frame:
|
|||||||
|
|
||||||
3. Draw HUD layer last
|
3. Draw HUD layer last
|
||||||
|
|
||||||
|
This section describes only the canonical game composition path.
|
||||||
|
|
||||||
|
`gfx.*` primitives such as `draw_text`, `draw_line`, and `draw_disc` are not part of this canonical game projection order. In v1 they belong to a deferred final overlay/debug stage that is drained after canonical game composition is complete.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 11. Drawing Order and Priority
|
## 11. Drawing Order and Priority
|
||||||
@ -214,6 +220,15 @@ Base order:
|
|||||||
4. Tile Layer 3
|
4. Tile Layer 3
|
||||||
5. Sprites (by priority between layers)
|
5. Sprites (by priority between layers)
|
||||||
6. HUD Layer
|
6. HUD Layer
|
||||||
|
7. Scene Fade
|
||||||
|
8. HUD Fade
|
||||||
|
9. Deferred `gfx.*` overlay/debug primitives
|
||||||
|
|
||||||
|
Normative boundary:
|
||||||
|
|
||||||
|
- Items 1 through 8 belong to canonical game-frame composition.
|
||||||
|
- Item 9 is a separate overlay/debug stage.
|
||||||
|
- Deferred `gfx.*` primitives MUST NOT be interpreted as scene, sprite, or canonical HUD content.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -258,8 +273,9 @@ Everything is:
|
|||||||
## 14. Where Blend is Applied
|
## 14. Where Blend is Applied
|
||||||
|
|
||||||
- Blending occurs during drawing
|
- Blending occurs during drawing
|
||||||
- The result goes directly to the back buffer
|
- For canonical game composition, the result goes to the back buffer during composition
|
||||||
- There is no automatic post-composition
|
- For deferred `gfx.*` overlay/debug primitives, the result is applied during the final overlay/debug drain stage
|
||||||
|
- There is no automatic GPU-style post-processing pipeline
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -296,6 +312,8 @@ controls:
|
|||||||
- **Scene Fade**: affects the entire scene (Tile Layers 0–3 + Sprites)
|
- **Scene Fade**: affects the entire scene (Tile Layers 0–3 + Sprites)
|
||||||
- **HUD Fade**: affects only the HUD Layer (always composed last)
|
- **HUD Fade**: affects only the HUD Layer (always composed last)
|
||||||
|
|
||||||
|
In v1, deferred `gfx.*` overlay/debug primitives are drained after both fades and therefore are not themselves part of scene or HUD fade application.
|
||||||
|
|
||||||
The fade is implemented without continuous per-pixel alpha and without floats.
|
The fade is implemented without continuous per-pixel alpha and without floats.
|
||||||
It uses a **discrete integer level** (0..31), which in practice produces an
|
It uses a **discrete integer level** (0..31), which in practice produces an
|
||||||
"almost continuous" visual result in 320×180 pixel art.
|
"almost continuous" visual result in 320×180 pixel art.
|
||||||
@ -566,6 +584,18 @@ Fault boundary:
|
|||||||
| `composer.set_camera` | `void` | no real operational failure path in v1 |
|
| `composer.set_camera` | `void` | no real operational failure path in v1 |
|
||||||
| `composer.emit_sprite` | `status:int` | explicit orchestration-domain operational rejection |
|
| `composer.emit_sprite` | `status:int` | explicit orchestration-domain operational rejection |
|
||||||
|
|
||||||
|
### 19.1.a Deferred overlay/debug semantics for `gfx.*`
|
||||||
|
|
||||||
|
The public `gfx.*` primitive family remains valid in v1, but its stable operational meaning is:
|
||||||
|
|
||||||
|
- deferred final overlay/debug composition;
|
||||||
|
- screen-space and pipeline-agnostic relative to `composer.*`;
|
||||||
|
- outside `FrameComposer`;
|
||||||
|
- above scene, sprites, and canonical HUD;
|
||||||
|
- drained after `hud_fade`.
|
||||||
|
|
||||||
|
This means callers MUST NOT rely on stable immediate writes to the working back buffer as the public contract for `gfx.draw_text(...)` or sibling primitives.
|
||||||
|
|
||||||
### 19.2 `composer.emit_sprite`
|
### 19.2 `composer.emit_sprite`
|
||||||
|
|
||||||
`composer.emit_sprite` returns `status:int`.
|
`composer.emit_sprite` returns `status:int`.
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user