implements PLN-0078 Classic2D packet consumer
This commit is contained in:
parent
5e3cb87b57
commit
57439846c5
@ -1,11 +1,11 @@
|
|||||||
use crate::memory_banks::GlyphBankPoolAccess;
|
use crate::memory_banks::GlyphBankPoolAccess;
|
||||||
use prometeu_hal::GfxBridge;
|
|
||||||
use prometeu_hal::color::Color;
|
use prometeu_hal::color::Color;
|
||||||
use prometeu_hal::glyph::Glyph;
|
use prometeu_hal::glyph::Glyph;
|
||||||
use prometeu_hal::glyph_bank::GlyphBank;
|
use prometeu_hal::glyph_bank::GlyphBank;
|
||||||
use prometeu_hal::scene_viewport_cache::{CachedTileEntry, SceneViewportCache};
|
use prometeu_hal::scene_viewport_cache::{CachedTileEntry, SceneViewportCache};
|
||||||
use prometeu_hal::scene_viewport_resolver::{LayerCopyRequest, ResolverUpdate};
|
use prometeu_hal::scene_viewport_resolver::{LayerCopyRequest, ResolverUpdate};
|
||||||
use prometeu_hal::sprite::Sprite;
|
use prometeu_hal::sprite::Sprite;
|
||||||
|
use prometeu_hal::{Game2DFramePacket, Gfx2dCommand, GfxBridge};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
/// Blending modes inspired by classic 16-bit hardware.
|
/// Blending modes inspired by classic 16-bit hardware.
|
||||||
@ -686,6 +686,58 @@ impl Gfx {
|
|||||||
Self::apply_fade_to_buffer(&mut self.back, self.hud_fade_level, self.hud_fade_color);
|
Self::apply_fade_to_buffer(&mut self.back, self.hud_fade_level, self.hud_fade_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn render_game2d_frame_packet(&mut self, packet: &Game2DFramePacket) {
|
||||||
|
let sprites: Vec<Sprite> = packet
|
||||||
|
.composer
|
||||||
|
.sprites
|
||||||
|
.iter()
|
||||||
|
.map(|sprite| Sprite {
|
||||||
|
glyph: Glyph {
|
||||||
|
glyph_id: sprite.glyph_id as u16,
|
||||||
|
palette_id: sprite.palette_id as u8,
|
||||||
|
},
|
||||||
|
x: sprite.x,
|
||||||
|
y: sprite.y,
|
||||||
|
layer: sprite.layer as u8,
|
||||||
|
bank_id: sprite.bank_id as u8,
|
||||||
|
active: true,
|
||||||
|
flip_x: sprite.flip_x,
|
||||||
|
flip_y: sprite.flip_y,
|
||||||
|
priority: sprite.priority as u8,
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
self.load_frame_sprites(&sprites);
|
||||||
|
self.render_no_scene_frame();
|
||||||
|
|
||||||
|
for command in &packet.gfx2d {
|
||||||
|
self.apply_gfx2d_command(command);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn apply_gfx2d_command(&mut self, command: &Gfx2dCommand) {
|
||||||
|
match command {
|
||||||
|
Gfx2dCommand::Clear { color } => self.clear(*color),
|
||||||
|
Gfx2dCommand::FillRect { rect, color } => {
|
||||||
|
self.fill_rect(rect.x, rect.y, rect.w, rect.h, *color);
|
||||||
|
}
|
||||||
|
Gfx2dCommand::DrawLine { x0, y0, x1, y1, color } => {
|
||||||
|
self.draw_line(*x0, *y0, *x1, *y1, *color);
|
||||||
|
}
|
||||||
|
Gfx2dCommand::DrawCircle { x, y, radius, color } => {
|
||||||
|
self.draw_circle(*x, *y, *radius, *color);
|
||||||
|
}
|
||||||
|
Gfx2dCommand::DrawDisc { x, y, radius, border_color, fill_color } => {
|
||||||
|
self.draw_disc(*x, *y, *radius, *border_color, *fill_color);
|
||||||
|
}
|
||||||
|
Gfx2dCommand::DrawSquare { rect, border_color, fill_color } => {
|
||||||
|
self.draw_square(rect.x, rect.y, rect.w, rect.h, *border_color, *fill_color);
|
||||||
|
}
|
||||||
|
Gfx2dCommand::DrawText { x, y, text, color } => {
|
||||||
|
self.draw_text(*x, *y, text, *color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn populate_layer_buckets(&mut self) {
|
fn populate_layer_buckets(&mut self) {
|
||||||
for bucket in self.layer_buckets.iter_mut() {
|
for bucket in self.layer_buckets.iter_mut() {
|
||||||
bucket.clear();
|
bucket.clear();
|
||||||
@ -1331,4 +1383,22 @@ mod tests {
|
|||||||
assert_eq!(gfx.sprites[0].layer, 1);
|
assert_eq!(gfx.sprites[0].layer, 1);
|
||||||
assert_eq!(gfx.sprites[1].glyph.glyph_id, 5);
|
assert_eq!(gfx.sprites[1].glyph.glyph_id, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn render_game2d_frame_packet_applies_primitive_commands() {
|
||||||
|
let mut gfx = Gfx::new(8, 8, Arc::new(MemoryBanks::default()));
|
||||||
|
let packet = Game2DFramePacket::new(
|
||||||
|
Default::default(),
|
||||||
|
vec![Gfx2dCommand::FillRect {
|
||||||
|
rect: prometeu_hal::primitives::Rect { x: 1, y: 1, w: 2, h: 2 },
|
||||||
|
color: Color::RED,
|
||||||
|
}],
|
||||||
|
);
|
||||||
|
|
||||||
|
gfx.render_game2d_frame_packet(&packet);
|
||||||
|
gfx.present();
|
||||||
|
|
||||||
|
assert_eq!(gfx.front_buffer()[1 + 8], Color::RED.raw());
|
||||||
|
assert_eq!(gfx.front_buffer()[2 + 2 * 8], Color::RED.raw());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -73,7 +73,12 @@ impl HardwareBridge for Hardware {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn render_frame(&mut self) {
|
fn render_frame(&mut self) {
|
||||||
self.frame_composer.render_frame(&mut self.gfx);
|
if self.frame_composer.active_scene_id().is_none() {
|
||||||
|
let packet = self.frame_composer.close_game2d_packet();
|
||||||
|
self.gfx.render_game2d_frame_packet(&packet);
|
||||||
|
} else {
|
||||||
|
self.frame_composer.render_frame(&mut self.gfx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn has_glyph_bank(&self, bank_id: usize) -> bool {
|
fn has_glyph_bank(&self, bank_id: usize) -> bool {
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
{"type":"meta","next_id":{"DSC":39,"AGD":39,"DEC":31,"PLN":87,"LSN":47,"CLSN":1}}
|
{"type":"meta","next_id":{"DSC":39,"AGD":39,"DEC":31,"PLN":87,"LSN":47,"CLSN":1}}
|
||||||
{"type":"discussion","id":"DSC-0038","status":"in_progress","ticket":"render-frame-packet-boundary","title":"Logical Render Pipelines and Command Packets","created_at":"2026-05-25","updated_at":"2026-05-25","tags":["gfx","renderer","runtime","frame-composer","architecture","ui","pipeline"],"agendas":[{"id":"AGD-0038","file":"AGD-0038-renderframepacket-boundary-for-classic-2d-renderer.md","status":"accepted","created_at":"2026-05-25","updated_at":"2026-05-25"}],"decisions":[{"id":"DEC-0030","file":"DEC-0030-logical-render-pipeline-command-boundary.md","status":"accepted","created_at":"2026-05-25","updated_at":"2026-05-25","ref_agenda":"AGD-0038"}],"plans":[{"id":"PLN-0073","file":"PLN-0073-render-contract-specs.md","status":"done","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0074","file":"PLN-0074-hal-render-submission-types.md","status":"done","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0075","file":"PLN-0075-rendermanager-core.md","status":"done","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0076","file":"PLN-0076-capabilities-and-abi-domain-split.md","status":"done","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0077","file":"PLN-0077-composer-buffer-and-game2d-packet.md","status":"done","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0078","file":"PLN-0078-classic2d-game-renderer-consumer.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0079","file":"PLN-0079-gfx2d-primitive-domain.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0080","file":"PLN-0080-shell-ui-packet-and-gfxui-domain.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0081","file":"PLN-0081-shell-hub-migration.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0082","file":"PLN-0082-frame-publication-and-present-boundary.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0083","file":"PLN-0083-fade-removal.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0084","file":"PLN-0084-host-debug-overlay-removal.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0085","file":"PLN-0085-pbs-stdlib-and-syscall-declarations.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0086","file":"PLN-0086-end-to-end-render-boundary-validation.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]}],"lessons":[]}
|
{"type":"discussion","id":"DSC-0038","status":"in_progress","ticket":"render-frame-packet-boundary","title":"Logical Render Pipelines and Command Packets","created_at":"2026-05-25","updated_at":"2026-05-25","tags":["gfx","renderer","runtime","frame-composer","architecture","ui","pipeline"],"agendas":[{"id":"AGD-0038","file":"AGD-0038-renderframepacket-boundary-for-classic-2d-renderer.md","status":"accepted","created_at":"2026-05-25","updated_at":"2026-05-25"}],"decisions":[{"id":"DEC-0030","file":"DEC-0030-logical-render-pipeline-command-boundary.md","status":"accepted","created_at":"2026-05-25","updated_at":"2026-05-25","ref_agenda":"AGD-0038"}],"plans":[{"id":"PLN-0073","file":"PLN-0073-render-contract-specs.md","status":"done","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0074","file":"PLN-0074-hal-render-submission-types.md","status":"done","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0075","file":"PLN-0075-rendermanager-core.md","status":"done","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0076","file":"PLN-0076-capabilities-and-abi-domain-split.md","status":"done","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0077","file":"PLN-0077-composer-buffer-and-game2d-packet.md","status":"done","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0078","file":"PLN-0078-classic2d-game-renderer-consumer.md","status":"done","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0079","file":"PLN-0079-gfx2d-primitive-domain.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0080","file":"PLN-0080-shell-ui-packet-and-gfxui-domain.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0081","file":"PLN-0081-shell-hub-migration.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0082","file":"PLN-0082-frame-publication-and-present-boundary.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0083","file":"PLN-0083-fade-removal.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0084","file":"PLN-0084-host-debug-overlay-removal.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0085","file":"PLN-0085-pbs-stdlib-and-syscall-declarations.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0086","file":"PLN-0086-end-to-end-render-boundary-validation.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]}],"lessons":[]}
|
||||||
{"type":"discussion","id":"DSC-0035","status":"done","ticket":"task-owned-shell-windows","title":"Agenda - Task-Owned Shell Windows","created_at":"2026-05-15","updated_at":"2026-05-15","tags":["runtime","os","task","window-manager","shell","lifecycle"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0044","file":"discussion/lessons/DSC-0035-task-owned-shell-windows/LSN-0044-task-window-liveness-belongs-to-the-task.md","status":"done","created_at":"2026-05-15","updated_at":"2026-05-15"}]}
|
{"type":"discussion","id":"DSC-0035","status":"done","ticket":"task-owned-shell-windows","title":"Agenda - Task-Owned Shell Windows","created_at":"2026-05-15","updated_at":"2026-05-15","tags":["runtime","os","task","window-manager","shell","lifecycle"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0044","file":"discussion/lessons/DSC-0035-task-owned-shell-windows/LSN-0044-task-window-liveness-belongs-to-the-task.md","status":"done","created_at":"2026-05-15","updated_at":"2026-05-15"}]}
|
||||||
{"type":"discussion","id":"DSC-0034","status":"done","ticket":"system-os-domain-facades","title":"Agenda - SystemOS Domain Facades","created_at":"2026-05-15","updated_at":"2026-05-15","tags":["runtime","os","services","api-surface","lifecycle","fs"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0043","file":"discussion/lessons/DSC-0034-system-os-domain-facades/LSN-0043-systemos-domain-facades.md","status":"done","created_at":"2026-05-15","updated_at":"2026-05-15"}]}
|
{"type":"discussion","id":"DSC-0034","status":"done","ticket":"system-os-domain-facades","title":"Agenda - SystemOS Domain Facades","created_at":"2026-05-15","updated_at":"2026-05-15","tags":["runtime","os","services","api-surface","lifecycle","fs"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0043","file":"discussion/lessons/DSC-0034-system-os-domain-facades/LSN-0043-systemos-domain-facades.md","status":"done","created_at":"2026-05-15","updated_at":"2026-05-15"}]}
|
||||||
{"type":"discussion","id":"DSC-0023","status":"done","ticket":"perf-full-migration-to-atomic-telemetry","title":"Agenda - [PERF] Full Migration to Atomic Telemetry","created_at":"2026-04-10","updated_at":"2026-04-10","tags":["perf","runtime","telemetry"],"agendas":[{"id":"AGD-0021","file":"AGD-0021-full-migration-to-atomic-telemetry.md","status":"done","created_at":"2026-04-10","updated_at":"2026-04-10"}],"decisions":[{"id":"DEC-0008","file":"DEC-0008-full-migration-to-atomic-telemetry.md","status":"accepted","created_at":"2026-04-10","updated_at":"2026-04-10"}],"plans":[{"id":"PLN-0007","file":"PLN-0007-full-migration-to-atomic-telemetry.md","status":"done","created_at":"2026-04-10","updated_at":"2026-04-10"}],"lessons":[{"id":"LSN-0028","file":"discussion/lessons/DSC-0023-perf-full-migration-to-atomic-telemetry/LSN-0028-converging-to-single-atomic-telemetry-source.md","status":"done","created_at":"2026-04-10","updated_at":"2026-04-10"}]}
|
{"type":"discussion","id":"DSC-0023","status":"done","ticket":"perf-full-migration-to-atomic-telemetry","title":"Agenda - [PERF] Full Migration to Atomic Telemetry","created_at":"2026-04-10","updated_at":"2026-04-10","tags":["perf","runtime","telemetry"],"agendas":[{"id":"AGD-0021","file":"AGD-0021-full-migration-to-atomic-telemetry.md","status":"done","created_at":"2026-04-10","updated_at":"2026-04-10"}],"decisions":[{"id":"DEC-0008","file":"DEC-0008-full-migration-to-atomic-telemetry.md","status":"accepted","created_at":"2026-04-10","updated_at":"2026-04-10"}],"plans":[{"id":"PLN-0007","file":"PLN-0007-full-migration-to-atomic-telemetry.md","status":"done","created_at":"2026-04-10","updated_at":"2026-04-10"}],"lessons":[{"id":"LSN-0028","file":"discussion/lessons/DSC-0023-perf-full-migration-to-atomic-telemetry/LSN-0028-converging-to-single-atomic-telemetry-source.md","status":"done","created_at":"2026-04-10","updated_at":"2026-04-10"}]}
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
id: PLN-0078
|
id: PLN-0078
|
||||||
ticket: render-frame-packet-boundary
|
ticket: render-frame-packet-boundary
|
||||||
title: Classic2D Game Renderer Consumer
|
title: Classic2D Game Renderer Consumer
|
||||||
status: open
|
status: done
|
||||||
created: 2026-05-25
|
created: 2026-05-25
|
||||||
ref_decisions: [DEC-0030]
|
ref_decisions: [DEC-0030]
|
||||||
tags: [gfx, renderer, runtime, frame-composer, architecture, ui, pipeline]
|
tags: [gfx, renderer, runtime, frame-composer, architecture, ui, pipeline]
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user