(fix) issues regarding tilemap cache and render
All checks were successful
Intrepid/Prometeu/Runtime/pipeline/head This commit looks good
Intrepid/Prometeu/Runtime/pipeline/pr-master This commit looks good

This commit is contained in:
bQUARKz 2026-05-01 05:54:23 +01:00
parent 983e4cfc29
commit 29d531f622
Signed by: bquarkz
SSH Key Fingerprint: SHA256:Z7dgqoglWwoK6j6u4QC87OveEq74WOhFN+gitsxtkf8

View File

@ -4,7 +4,9 @@ use prometeu_hal::GfxBridge;
use prometeu_hal::glyph::Glyph; use prometeu_hal::glyph::Glyph;
use prometeu_hal::scene_bank::SceneBank; use prometeu_hal::scene_bank::SceneBank;
use prometeu_hal::scene_viewport_cache::SceneViewportCache; use prometeu_hal::scene_viewport_cache::SceneViewportCache;
use prometeu_hal::scene_viewport_resolver::{CacheRefreshRequest, SceneViewportResolver}; use prometeu_hal::scene_viewport_resolver::{
CacheRefreshRequest, ResolverUpdate, SceneViewportResolver,
};
use prometeu_hal::sprite::Sprite; use prometeu_hal::sprite::Sprite;
use std::sync::Arc; use std::sync::Arc;
@ -257,6 +259,7 @@ impl FrameComposer {
panic!("SCENE runtime invariant broken: active scene without cache/resolver"); panic!("SCENE runtime invariant broken: active scene without cache/resolver");
}; };
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::sync_cache_windows(cache, &update);
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. // `FrameComposer` owns only canonical game-frame composition.
// Deferred `gfx.*` primitives are drained later by a separate // Deferred `gfx.*` primitives are drained later by a separate
@ -334,6 +337,16 @@ impl FrameComposer {
} }
} }
} }
fn sync_cache_windows(cache: &mut SceneViewportCache, update: &ResolverUpdate) {
for request in &update.copy_requests {
cache.move_layer_window_to(
request.layer_index,
request.cache_origin_tile_x,
request.cache_origin_tile_y,
);
}
}
} }
#[cfg(test)] #[cfg(test)]
@ -360,6 +373,16 @@ mod tests {
glyph_asset_id: AssetId, glyph_asset_id: AssetId,
palette_id: u8, palette_id: u8,
tile_size: TileSize, tile_size: TileSize,
) -> SceneBank {
make_scene_grid(glyph_asset_id, palette_id, tile_size, 2, 2)
}
fn make_scene_grid(
glyph_asset_id: AssetId,
palette_id: u8,
tile_size: TileSize,
width: usize,
height: usize,
) -> SceneBank { ) -> SceneBank {
let layer = SceneLayer { let layer = SceneLayer {
active: true, active: true,
@ -367,8 +390,8 @@ mod tests {
tile_size, tile_size,
parallax_factor: ParallaxFactor { x: 1.0, y: 0.5 }, parallax_factor: ParallaxFactor { x: 1.0, y: 0.5 },
tilemap: TileMap { tilemap: TileMap {
width: 2, width,
height: 2, height,
tiles: vec![ tiles: vec![
Tile { Tile {
active: true, active: true,
@ -376,7 +399,7 @@ mod tests {
flip_x: false, flip_x: false,
flip_y: false, flip_y: false,
}; };
4 width * height
], ],
}, },
}; };
@ -768,6 +791,43 @@ mod tests {
assert_eq!(gfx.front_buffer()[0], Color::BLUE.raw()); assert_eq!(gfx.front_buffer()[0], Color::BLUE.raw());
} }
#[test]
fn render_frame_realigns_cache_window_before_refresh_when_camera_moves() {
let banks = Arc::new(MemoryBanks::new());
let scene = Arc::new(make_scene_grid(0, 2, TileSize::Size8, 16, 16));
banks.install_glyph_bank(0, Arc::new(make_glyph_bank(TileSize::Size8, 2, Color::BLUE)));
banks.install_scene_bank(0, Arc::clone(&scene));
let mut frame_composer = FrameComposer::new(
16,
16,
Arc::clone(&banks) as Arc<dyn SceneBankPoolAccess>,
make_glyph_slot_index(&[(0, 0)]),
);
assert!(frame_composer.bind_scene(0));
let mut expected_resolver = FrameComposer::build_scene_runtime(16, 16, &scene).1;
expected_resolver.update(&scene, 0, 0);
let expected_update = expected_resolver.update(&scene, 40, 0);
let mut gfx = Gfx::new(16, 16, Arc::clone(&banks) as Arc<dyn GlyphBankPoolAccess>);
gfx.scene_fade_level = 31;
gfx.hud_fade_level = 31;
frame_composer.render_frame(&mut gfx);
frame_composer.set_camera(40, 0);
frame_composer.render_frame(&mut gfx);
let cache = frame_composer.cache().expect("cache should exist");
assert_eq!(
cache.layers[0].logical_origin(),
(
expected_update.copy_requests[0].cache_origin_tile_x,
expected_update.copy_requests[0].cache_origin_tile_y,
)
);
}
#[test] #[test]
fn render_frame_survives_scene_transition_through_unbind_and_rebind() { fn render_frame_survives_scene_transition_through_unbind_and_rebind() {
let banks = Arc::new(MemoryBanks::new()); let banks = Arc::new(MemoryBanks::new());