diff options
Diffstat (limited to 'renderer/src/map.rs')
-rw-r--r-- | renderer/src/map.rs | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/renderer/src/map.rs b/renderer/src/map.rs new file mode 100644 index 0000000..0ea3a6b --- /dev/null +++ b/renderer/src/map.rs @@ -0,0 +1,163 @@ +use std::collections::HashMap; + +use log::{info, warn}; +use skia_safe::{ + canvas::SrcRectConstraint, Canvas, Color4f, ColorSpace, ISize, Image, Paint, Rect, +}; +use twclient::world::{ + map::{format, TILE_NUM}, + World, +}; + +pub struct MapRenderer { + tileset: HashMap<Option<usize>, Image>, +} + +impl MapRenderer { + pub fn new() -> Self { + Self { + tileset: HashMap::new(), + } + } + + pub fn tick(&mut self) {} + pub fn map_changed(&mut self, world: &World) { + self.tileset.clear(); + for (key, t) in &world.map.tilesets { + let mut bytes: Vec<u8> = Vec::with_capacity(t.dim().0 * t.dim().1 * 4); + info!("loading tileset: {:?} => {:?}", key, t.dim()); + for ((_x, _y), c) in t.indexed_iter() { + bytes.push(c.red); + bytes.push(c.green); + bytes.push(c.blue); + bytes.push(c.alpha); + } + let d = skia_safe::Data::new_copy(&bytes); + let v = skia_safe::Image::from_raster_data( + &skia_safe::ImageInfo::new( + ISize::new(t.dim().0 as i32, t.dim().1 as i32), + skia_safe::ColorType::RGBA8888, + skia_safe::AlphaType::Opaque, + None, + ), + d, + t.dim().0 * 4, + ) + .unwrap(); + self.tileset.insert(*key, v); + } + } + + pub fn draw(&mut self, world: &World, canvas: &mut Canvas) { + let mut grid_paint = Paint::new( + Color4f { + a: 1.0, + r: 1.0, + g: 1.0, + b: 1.0, + }, + &ColorSpace::new_srgb(), + ); + grid_paint.set_style(skia_safe::PaintStyle::Stroke); + grid_paint.set_anti_alias(true); + + let center = world + .local_tee() + .map(|t| (t.x / 16, t.y / 16)) + .unwrap_or((0, 0)); + + let tile_rect = Rect { + top: center.1 as f32 * 16.0, + left: center.0 as f32 * 16.0, + bottom: center.1 as f32 * 16.0 + 16.0, + right: center.0 as f32 * 16.0 + 16.0, + }; + canvas.draw_rect(tile_rect, &grid_paint); + + for l in &world.map.layers { + let tileset = match world.map.tilesets.get(&l.image) { + Some(t) => t, + None => { + warn!("missing tileset for {:?}, skipping layer", l.image); + continue; + } + }; + if tileset.dim() == (1, 1) { + continue; + } + + for layer_y in (center.1 - 30)..(center.1 + 30) { + for layer_x in (center.0 - 30)..(center.0 + 30) { + let layer_x = layer_x.try_into().unwrap_or(0); + let layer_y = layer_y.try_into().unwrap_or(0); + + if layer_x >= l.tiles.dim().1 || layer_y >= l.tiles.dim().0 { + continue; + } + let tile = l.tiles[(layer_y, layer_x)]; + + let _rotate = tile.flags & format::TILEFLAG_ROTATE != 0; + let _vflip = tile.flags & format::TILEFLAG_VFLIP != 0; + let _hflip = tile.flags & format::TILEFLAG_HFLIP != 0; + let tile_x = tile.index as u32 % TILE_NUM; + let tile_y = tile.index as u32 / TILE_NUM; + + if tile_x == 0 && tile_y == 0 { + continue; + } + + let tile_rect = Rect { + top: layer_y as f32 * 16.0, + left: layer_x as f32 * 16.0, + bottom: layer_y as f32 * 16.0 + 16.0, + right: layer_x as f32 * 16.0 + 16.0, + }; + canvas.draw_rect(tile_rect, &grid_paint); + + const TL: u32 = 16; + canvas.draw_image_rect( + self.tileset.get(&l.image).unwrap(), + Some(( + &Rect { + top: (tile_y * TL) as f32, + left: (tile_x * TL) as f32, + bottom: ((tile_y + 1) * TL) as f32, + right: ((tile_x + 1) * TL) as f32, + }, + SrcRectConstraint::Strict, + )), + tile_rect, + &Paint::default(), + ); + // for iy in 0..TL { + // for ix in 0..TL { + // let (x, y) = ((layer_x as u32 * TL + iy), (layer_y as u32 * TL + ix)); + // let p_tile = + // tileset[((tile_y * TL + iy) as usize, (tile_x * TL + ix) as usize)]; + // let mut p = Paint::new( + // Color4f { + // a: 0.0, + // b: 0.0, + // g: 0.0, + // r: 0.0, + // }, + // &ColorSpace::new_srgb(), + // ); + // p.set_argb(p_tile.alpha, p_tile.red, p_tile.green, p_tile.green); + // p.set_style(PaintStyle::Fill); + // canvas.draw_rect( + // Rect { + // left: x as f32, + // top: y as f32, + // right: x as f32 + 1.0, + // bottom: y as f32 + 1.0, + // }, + // &p, + // ); + // } + // } + } + } + } + } +} |