fix stress render packet scene composition
This commit is contained in:
parent
8cd218dc04
commit
df0d7949c8
@ -327,6 +327,55 @@ impl FrameComposer {
|
||||
gfx.render_no_scene_frame();
|
||||
}
|
||||
|
||||
pub fn render_game2d_frame_packet(
|
||||
&mut self,
|
||||
packet: &Game2DFramePacket,
|
||||
gfx: &mut dyn GfxBridge,
|
||||
) {
|
||||
let sprites: Vec<Sprite> =
|
||||
packet.composer.sprites.iter().map(Self::sprite_from_packet).collect();
|
||||
gfx.load_frame_sprites(&sprites);
|
||||
|
||||
let Some(bound_scene) = packet.composer.bound_scene else {
|
||||
gfx.render_no_scene_frame();
|
||||
return;
|
||||
};
|
||||
|
||||
let scene_bank_id = bound_scene.bank_id as usize;
|
||||
if self.active_scene_id != Some(scene_bank_id) && !self.bind_scene(scene_bank_id) {
|
||||
gfx.render_no_scene_frame();
|
||||
return;
|
||||
}
|
||||
|
||||
self.camera_x_px = packet.composer.camera.x;
|
||||
self.camera_y_px = packet.composer.camera.y;
|
||||
|
||||
let scene =
|
||||
self.active_scene.as_deref().expect("active scene should exist after packet bind");
|
||||
let resolved_glyph_slots = self.resolve_glyph_slots(scene, scene_bank_id, "render_packet");
|
||||
let (Some(cache), Some(resolver)) = (self.cache.as_mut(), self.resolver.as_mut()) else {
|
||||
panic!("SCENE runtime invariant broken: packet scene without cache/resolver");
|
||||
};
|
||||
let update = resolver.update(scene, self.camera_x_px, self.camera_y_px);
|
||||
Self::sync_cache_windows(cache, &update);
|
||||
Self::apply_refresh_requests(cache, scene, &update.refresh_requests);
|
||||
gfx.render_scene_from_cache(cache, &update, &resolved_glyph_slots);
|
||||
}
|
||||
|
||||
fn sprite_from_packet(sprite: &GameSpritePacket) -> 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,
|
||||
}
|
||||
}
|
||||
|
||||
fn build_scene_runtime(
|
||||
viewport_width_px: usize,
|
||||
viewport_height_px: usize,
|
||||
|
||||
@ -75,10 +75,10 @@ impl HardwareBridge for Hardware {
|
||||
fn publish_render_submission(&mut self, submission: &RenderSubmission) {
|
||||
match &submission.packet {
|
||||
RenderSubmissionPacket::Game2D(packet) => {
|
||||
if self.frame_composer.active_scene_id().is_none() {
|
||||
if packet.composer.bound_scene.is_none() {
|
||||
self.gfx.render_game2d_frame_packet(packet);
|
||||
} else {
|
||||
self.frame_composer.render_frame(&mut self.gfx);
|
||||
self.frame_composer.render_game2d_frame_packet(packet, &mut self.gfx);
|
||||
self.gfx.apply_gfx2d_commands(&packet.gfx2d);
|
||||
}
|
||||
}
|
||||
@ -195,7 +195,9 @@ mod tests {
|
||||
use prometeu_hal::scene_viewport_resolver::SceneViewportResolver;
|
||||
use prometeu_hal::tile::Tile;
|
||||
use prometeu_hal::tilemap::TileMap;
|
||||
use prometeu_hal::{FrameId, Gfx2dCommand};
|
||||
use prometeu_hal::{
|
||||
BoundScenePacket, Camera2D, ComposerFramePacket, FrameId, GameSpritePacket, Gfx2dCommand,
|
||||
};
|
||||
|
||||
fn make_glyph_bank() -> GlyphBank {
|
||||
let mut bank = GlyphBank::new(TileSize::Size8, 8, 8);
|
||||
@ -292,4 +294,42 @@ mod tests {
|
||||
|
||||
assert_eq!(hardware.gfx.front_buffer()[0], Color::BLUE.raw());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn publish_game2d_submission_uses_packet_scene_and_sprites_not_live_frame_state() {
|
||||
let banks = Arc::new(MemoryBanks::new());
|
||||
banks.install_glyph_bank(0, Arc::new(make_glyph_bank()));
|
||||
banks.install_scene_bank(0, Arc::new(make_scene_with_glyph_asset_id(0)));
|
||||
|
||||
let mut hardware = Hardware::new_with_memory_banks(banks);
|
||||
let mut glyph_slots = [None; 16];
|
||||
glyph_slots[0] = Some(0);
|
||||
hardware.assets.glyph_asset_slot_index().rebuild_from_slots(&glyph_slots);
|
||||
assert!(hardware.bind_scene(0));
|
||||
|
||||
let packet = Game2DFramePacket::new(
|
||||
ComposerFramePacket {
|
||||
bound_scene: Some(BoundScenePacket { bank_id: 0 }),
|
||||
camera: Camera2D::default(),
|
||||
sprites: vec![GameSpritePacket {
|
||||
glyph_id: 0,
|
||||
palette_id: 0,
|
||||
x: 0,
|
||||
y: 0,
|
||||
layer: 0,
|
||||
bank_id: 0,
|
||||
flip_x: false,
|
||||
flip_y: false,
|
||||
priority: 0,
|
||||
}],
|
||||
hud: Default::default(),
|
||||
},
|
||||
Vec::new(),
|
||||
);
|
||||
|
||||
hardware.begin_frame();
|
||||
hardware.publish_render_submission(&RenderSubmission::game2d(FrameId::ZERO, packet));
|
||||
|
||||
assert_eq!(hardware.gfx.front_buffer()[0], Color::RED.raw());
|
||||
}
|
||||
}
|
||||
|
||||
@ -41,13 +41,6 @@ fn asm(s: &str) -> Vec<u8> {
|
||||
pub fn generate() -> Result<()> {
|
||||
let mut rom: Vec<u8> = Vec::new();
|
||||
let syscalls = vec![
|
||||
SyscallDecl {
|
||||
module: "gfx2d".into(),
|
||||
name: "clear".into(),
|
||||
version: 1,
|
||||
arg_slots: 1,
|
||||
ret_slots: 0,
|
||||
},
|
||||
SyscallDecl {
|
||||
module: "gfx2d".into(),
|
||||
name: "draw_text".into(),
|
||||
@ -143,17 +136,15 @@ fn heavy_load(rom: &mut Vec<u8>) {
|
||||
let jif_bind_done_offset = rom.len() + 2;
|
||||
rom.extend(asm("JMP_IF_FALSE 0"));
|
||||
|
||||
rom.extend(asm("PUSH_I32 0\nHOSTCALL 3\nPOP_N 1\nPUSH_I32 1\nSET_GLOBAL 1"));
|
||||
rom.extend(asm("PUSH_I32 0\nHOSTCALL 2\nPOP_N 1\nPUSH_I32 1\nSET_GLOBAL 1"));
|
||||
let bind_done_target = rom.len() as u32;
|
||||
|
||||
rom.extend(asm("PUSH_I32 0\nHOSTCALL 0"));
|
||||
|
||||
let scene_width_px = (STRESS_SCENE_TILE_W * 8) as i32;
|
||||
let scene_height_px = (STRESS_SCENE_TILE_H * 8) as i32;
|
||||
let camera_x_span = scene_width_px - STRESS_VIEWPORT_W;
|
||||
let camera_y_span = scene_height_px - STRESS_VIEWPORT_H;
|
||||
rom.extend(asm(&format!(
|
||||
"GET_GLOBAL 0\nPUSH_I32 2\nMUL\nPUSH_I32 {camera_x_span}\nMOD\nGET_GLOBAL 0\nPUSH_I32 {camera_y_span}\nMOD\nHOSTCALL 4"
|
||||
"GET_GLOBAL 0\nPUSH_I32 2\nMUL\nPUSH_I32 {camera_x_span}\nMOD\nGET_GLOBAL 0\nPUSH_I32 {camera_y_span}\nMOD\nHOSTCALL 3"
|
||||
)));
|
||||
|
||||
rom.extend(asm("PUSH_I32 0\nSET_LOCAL 0"));
|
||||
@ -178,7 +169,7 @@ fn heavy_load(rom: &mut Vec<u8>) {
|
||||
GET_LOCAL 1\nGET_GLOBAL 0\nADD\nPUSH_I32 1\nBIT_AND\nPUSH_I32 0\nNEQ\n\
|
||||
GET_LOCAL 0\nGET_GLOBAL 0\nADD\nPUSH_I32 1\nBIT_AND\nPUSH_I32 0\nNEQ\n\
|
||||
GET_LOCAL 0\nGET_LOCAL 1\nADD\nPUSH_I32 4\nMOD\n\
|
||||
HOSTCALL 5\nPOP_N 1"
|
||||
HOSTCALL 4\nPOP_N 1"
|
||||
)));
|
||||
|
||||
rom.extend(asm("GET_LOCAL 1\nPUSH_I32 1\nADD\nSET_LOCAL 1"));
|
||||
@ -195,27 +186,27 @@ fn heavy_load(rom: &mut Vec<u8>) {
|
||||
PUSH_I32 8\n\
|
||||
PUSH_CONST 0\n\
|
||||
GET_GLOBAL 0\nPUSH_I32 2047\nMUL\nPUSH_I32 65535\nBIT_AND\n\
|
||||
HOSTCALL 1"));
|
||||
HOSTCALL 0"));
|
||||
rom.extend(asm("PUSH_I32 16\n\
|
||||
GET_GLOBAL 0\nPUSH_I32 2\nMUL\nPUSH_I32 186\nMOD\nPUSH_I32 32\nADD\n\
|
||||
PUSH_CONST 1\n\
|
||||
GET_GLOBAL 0\nPUSH_I32 4093\nMUL\nPUSH_I32 65535\nBIT_AND\n\
|
||||
HOSTCALL 1"));
|
||||
HOSTCALL 0"));
|
||||
rom.extend(asm("PUSH_I32 336\n\
|
||||
GET_GLOBAL 0\nPUSH_I32 5\nMUL\nPUSH_I32 194\nMOD\n\
|
||||
PUSH_CONST 2\n\
|
||||
GET_GLOBAL 0\nPUSH_I32 1237\nMUL\nPUSH_I32 65535\nBIT_AND\n\
|
||||
HOSTCALL 1"));
|
||||
HOSTCALL 0"));
|
||||
rom.extend(asm("GET_GLOBAL 0\nPUSH_I32 4\nMUL\nPUSH_I32 240\nMOD\nPUSH_I32 112\nADD\n\
|
||||
GET_GLOBAL 0\nPUSH_I32 3\nMUL\nPUSH_I32 120\nMOD\nPUSH_I32 88\nADD\n\
|
||||
PUSH_CONST 3\n\
|
||||
GET_GLOBAL 0\nPUSH_I32 3001\nMUL\nPUSH_I32 65535\nBIT_AND\n\
|
||||
HOSTCALL 1"));
|
||||
HOSTCALL 0"));
|
||||
|
||||
rom.extend(asm("GET_GLOBAL 0\nPUSH_I32 60\nMOD\nPUSH_I32 0\nEQ"));
|
||||
let jif_log_offset = rom.len() + 2;
|
||||
rom.extend(asm("JMP_IF_FALSE 0"));
|
||||
rom.extend(asm("PUSH_I32 2\nPUSH_CONST 0\nHOSTCALL 2"));
|
||||
rom.extend(asm("PUSH_I32 2\nPUSH_CONST 0\nHOSTCALL 1"));
|
||||
let after_log = rom.len() as u32;
|
||||
|
||||
rom.extend(asm("FRAME_SYNC\nRET"));
|
||||
|
||||
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user