Modify data structures to include palette data per tile
parent
f7b9216680
commit
ff08ee4e46
|
@ -67,7 +67,7 @@ pub fn run_command() -> Result<(), Box<dyn Error>> {
|
|||
}
|
||||
Tools::Level { input_file, output_directory, console, tile_size } => {
|
||||
let tiled_file = get_tiled_tilemap( &input_file )?;
|
||||
print_info( &format!( "{:#?}", tiled_file ) );
|
||||
//print_info( &format!( "{:#?}", tiled_file ) );
|
||||
print_good( "file opened without errors" );
|
||||
print_error( "unimplemented" );
|
||||
}
|
||||
|
|
|
@ -10,14 +10,13 @@ pub struct TiledTilemap {
|
|||
pub layers: Vec<Layer>,
|
||||
ecs: Vec<ecs::Entity>,
|
||||
pub width: usize,
|
||||
pub height: usize,
|
||||
pub tile_width: usize,
|
||||
pub tile_height: usize
|
||||
pub height: usize
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TiledTileset {
|
||||
pub image: DynamicImage
|
||||
pub image: DynamicImage,
|
||||
pub palettes: Vec<Option<u8>>
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -103,6 +102,42 @@ fn get_layer( layer: Node, map_width: usize, map_height: usize ) -> Result<Optio
|
|||
}
|
||||
}
|
||||
|
||||
fn get_tiles( tileset: Node ) -> Result<TiledTileset, Box<dyn Error>> {
|
||||
// Get the image for the tileset
|
||||
let image = tileset.descendants().find( | node | node.tag_name() == "image".into() ).ok_or( "invalid file: no image object" )?;
|
||||
let image = image::open( image.attribute( "source" ).ok_or( "invalid file: no source attribute on image" )? )?;
|
||||
|
||||
// Image must be a multiple of 8 (--system md)
|
||||
if image.width() % 8 != 0 { return Err( "invalid file: tileset width not multiple of 8" )? }
|
||||
if image.height() % 8 != 0 { return Err( "invalid file: tileset height not multiple of 8" )? }
|
||||
|
||||
let tile_count: usize = tileset.attribute( "tilecount" ).ok_or( "invalid file: no tilecount attribute on tileset" )?.parse()?;
|
||||
let mut palettes: Vec<Option<u8>> = vec![ None; tile_count ];
|
||||
|
||||
let defined_tiles = tileset.descendants().filter( | node | node.tag_name() == "tile".into() );
|
||||
for defined_tile in defined_tiles {
|
||||
let tile_id: usize = defined_tile.attribute( "id" ).ok_or( "invalid file: id attribute not defined on a tile" )?.parse()?;
|
||||
let properties = defined_tile.descendants().find( | node | node.tag_name() == "properties".into() ).ok_or( "invalid file: no properties descendant in tileset" )?;
|
||||
let property = properties.descendants().find( | node | node.tag_name() == "property".into() && node.attribute( "reskit-palette" ).is_some() );
|
||||
if let Some( property ) = property {
|
||||
let property_type = property.attribute( "type" ).unwrap_or( "string" );
|
||||
if property_type == "int" {
|
||||
let palette_value: u8 = property.attribute( "value" ).ok_or( "invalid file: reskit-palette property has no value" )?.parse()?;
|
||||
// --system md
|
||||
if palette_value > 3 {
|
||||
print_warning( &format!( "reskit-palette property on tile {} is not valid palette (0 to 3) - leaving palette unset, this is probably not what you want...", tile_id ) );
|
||||
} else {
|
||||
palettes[ tile_id ] = Some( palette_value );
|
||||
}
|
||||
} else {
|
||||
print_warning( &format!( "reskit-palette property on tile {} is not int type - leaving palette unset, this is probably not what you want...", tile_id ) )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok( TiledTileset { image, palettes } )
|
||||
}
|
||||
|
||||
pub fn get_tiled_tilemap( path: &str ) -> Result<TiledTilemap, Box<dyn Error>> {
|
||||
let file = read_to_string( path )?;
|
||||
let document = roxmltree::Document::parse( &file )?;
|
||||
|
@ -135,6 +170,14 @@ pub fn get_tiled_tilemap( path: &str ) -> Result<TiledTilemap, Box<dyn Error>> {
|
|||
map.attribute( "tileheight" ).ok_or( "invalid file: no tileheight attribute" )?.parse()?
|
||||
);
|
||||
|
||||
// --system md is 8x8
|
||||
if tile_width != 8 {
|
||||
return Err( "invalid file: tile width is not 8 for --system md" )?
|
||||
}
|
||||
if tile_height != 8 {
|
||||
return Err( "invalid file: tile height is not 8 for --system md" )?
|
||||
}
|
||||
|
||||
// Build tileset (current version assumes one tileset per level)
|
||||
let tileset = map.descendants().find( | node | node.tag_name() == "tileset".into() ).ok_or( "invalid file: no tileset" )?;
|
||||
let tileset_source_path = tileset.attribute( "source" ).ok_or( "invalid file: no tileset source" )?;
|
||||
|
@ -152,13 +195,7 @@ pub fn get_tiled_tilemap( path: &str ) -> Result<TiledTilemap, Box<dyn Error>> {
|
|||
return Err( "invalid file: referenced tilemap doesn't have same per-tile width and height of parent tilemap" )?
|
||||
}
|
||||
|
||||
// Get the image for the tileset
|
||||
let image = tileset.descendants().find( | node | node.tag_name() == "image".into() ).ok_or( "invalid file: no image object" )?;
|
||||
let image = image::open( image.attribute( "source" ).ok_or( "invalid file: no source attribute on image" )? )?;
|
||||
|
||||
// Image must be a multiple of 8 (md system)
|
||||
if image.width() % 8 != 0 { return Err( "invalid file: tileset width not multiple of 8" )? }
|
||||
if image.height() % 8 != 0 { return Err( "invalid file: tileset height not multiple of 8" )? }
|
||||
let tileset = get_tiles( tileset )?;
|
||||
|
||||
// Get the layers
|
||||
let layers: Vec<Layer> = map.descendants()
|
||||
|
@ -184,13 +221,11 @@ pub fn get_tiled_tilemap( path: &str ) -> Result<TiledTilemap, Box<dyn Error>> {
|
|||
|
||||
Ok(
|
||||
TiledTilemap {
|
||||
tileset: TiledTileset { image },
|
||||
tileset,
|
||||
layers,
|
||||
ecs,
|
||||
width,
|
||||
height,
|
||||
tile_width,
|
||||
tile_height
|
||||
height
|
||||
}
|
||||
)
|
||||
} else {
|
||||
|
|
|
@ -10,13 +10,13 @@ pub fn get_tiles( tilemap: &TiledTilemap ) -> Result<Vec<u8>, Box<dyn Error>> {
|
|||
let mut palette: [u16; 16] = [ 0; 16 ];
|
||||
let mut all_tiles: Vec<u8> = Vec::new();
|
||||
|
||||
for tile_y in 0..tilemap.tile_height {
|
||||
for tile_x in 0..tilemap.tile_width {
|
||||
for tile_y in 0..tilemap.height {
|
||||
for tile_x in 0..tilemap.width {
|
||||
let tile = tilemap.tileset.image.clone().crop(
|
||||
tile_x as u32,
|
||||
tile_y as u32,
|
||||
tilemap.tile_width as u32,
|
||||
tilemap.tile_height as u32
|
||||
8, // --system md
|
||||
8 // --system md
|
||||
);
|
||||
|
||||
let tile_bin = image_to_tiles(
|
||||
|
@ -52,8 +52,8 @@ pub fn get_tilemap( tilemap: &TiledTilemap ) -> Result<Vec<u8>, Box<dyn Error>>
|
|||
let layer_b: Option<&Layer> = tilemap.layers.iter().find( | layer | matches!( layer, Layer::Tile { system_plane: SystemPlane::MdPlaneB, tiles: _ } ) );
|
||||
let layer_a: Option<&Layer> = tilemap.layers.iter().find( | layer | matches!( layer, Layer::Tile { system_plane: SystemPlane::MdPlaneA, tiles: _ } ) );
|
||||
|
||||
let md_height_per_tile = tilemap.tile_height / 8;
|
||||
let md_width_per_tile = tilemap.tile_width / 8;
|
||||
let md_height_per_tile = 1; // --system md
|
||||
let md_width_per_tile = 1; // --system md
|
||||
|
||||
// Each entry in a `--system md` tilemap is 16 bits
|
||||
let mut nametable: Vec<u16> = vec![ 0; ( tilemap.width * md_width_per_tile ) * ( tilemap.height * md_height_per_tile ) ];
|
||||
|
|
Loading…
Reference in New Issue