rust/mapgen/src/theme.rs
changeset 14710 946df0bb3b28
parent 14175 76a52e8149e3
child 15120 febccab419b1
equal deleted inserted replaced
14709:65c971417780 14710:946df0bb3b28
       
     1 use png::{ColorType, Decoder, DecodingError};
     1 use std::{
     2 use std::{
     2     slice::{
     3     fs::{read_dir, File},
     3         from_raw_parts,
       
     4         from_raw_parts_mut
       
     5     },
       
     6     io,
     4     io,
     7     io::BufReader,
     5     io::BufReader,
     8     fs::{File, read_dir},
     6     path::Path,
     9     path::Path
     7     slice::{from_raw_parts, from_raw_parts_mut},
    10 };
       
    11 use png::{
       
    12     ColorType,
       
    13     Decoder,
       
    14     DecodingError
       
    15 };
     8 };
    16 
     9 
    17 use integral_geometry::Size;
    10 use integral_geometry::Size;
    18 use vec2d::Vec2D;
    11 use vec2d::Vec2D;
    19 
    12 
    20 pub struct ThemeSprite {
    13 pub struct ThemeSprite {
    21     pixels: Vec2D<u32>
    14     pixels: Vec2D<u32>,
    22 }
    15 }
    23 
    16 
    24 impl ThemeSprite {
    17 impl ThemeSprite {
    25     #[inline]
    18     #[inline]
    26     pub fn size(&self) -> Size {
    19     pub fn size(&self) -> Size {
    73             for (x, v) in row.iter().enumerate() {
    66             for (x, v) in row.iter().enumerate() {
    74                 pixels[get_tiled_index(x, y, tile_width_shift)] = *v;
    67                 pixels[get_tiled_index(x, y, tile_width_shift)] = *v;
    75             }
    68             }
    76         }
    69         }
    77 
    70 
    78         TiledSprite { tile_width_shift, size, pixels }
    71         TiledSprite {
       
    72             tile_width_shift,
       
    73             size,
       
    74             pixels,
       
    75         }
    79     }
    76     }
    80 }
    77 }
    81 
    78 
    82 #[inline]
    79 #[inline]
    83 fn get_tiled_index(x: usize, y: usize, tile_width_shift: usize) -> usize {
    80 fn get_tiled_index(x: usize, y: usize, tile_width_shift: usize) -> usize {
    85 }
    82 }
    86 
    83 
    87 pub struct TiledSprite {
    84 pub struct TiledSprite {
    88     tile_width_shift: usize,
    85     tile_width_shift: usize,
    89     size: Size,
    86     size: Size,
    90     pixels: Vec<u32>
    87     pixels: Vec<u32>,
    91 }
    88 }
    92 
    89 
    93 impl TiledSprite {
    90 impl TiledSprite {
    94     #[inline]
    91     #[inline]
    95     pub fn size(&self) -> Size {
    92     pub fn size(&self) -> Size {
   112     }
   109     }
   113 }
   110 }
   114 
   111 
   115 pub struct Theme {
   112 pub struct Theme {
   116     land_texture: Option<ThemeSprite>,
   113     land_texture: Option<ThemeSprite>,
   117     border_texture: Option<ThemeSprite>
   114     border_texture: Option<ThemeSprite>,
   118 }
   115 }
   119 
   116 
   120 impl Theme {
   117 impl Theme {
   121     pub fn land_texture(&self) -> Option<&ThemeSprite> {
   118     pub fn land_texture(&self) -> Option<&ThemeSprite> {
   122         self.land_texture.as_ref()
   119         self.land_texture.as_ref()
   129 
   126 
   130 #[derive(Debug)]
   127 #[derive(Debug)]
   131 pub enum ThemeLoadError {
   128 pub enum ThemeLoadError {
   132     File(io::Error),
   129     File(io::Error),
   133     Decoding(DecodingError),
   130     Decoding(DecodingError),
   134     Format(String)
   131     Format(String),
   135 }
   132 }
   136 
   133 
   137 impl From<io::Error> for ThemeLoadError {
   134 impl From<io::Error> for ThemeLoadError {
   138     fn from(e: io::Error) -> Self {
   135     fn from(e: io::Error) -> Self {
   139         ThemeLoadError::File(e)
   136         ThemeLoadError::File(e)
   169         Ok(theme)
   166         Ok(theme)
   170     }
   167     }
   171 }
   168 }
   172 
   169 
   173 fn load_sprite(path: &Path) -> Result<ThemeSprite, ThemeLoadError> {
   170 fn load_sprite(path: &Path) -> Result<ThemeSprite, ThemeLoadError> {
   174     let decoder = Decoder::new(
   171     let decoder = Decoder::new(BufReader::new(File::open(path)?));
   175         BufReader::new(File::open(path)?));
       
   176     let (info, mut reader) = decoder.read_info()?;
   172     let (info, mut reader) = decoder.read_info()?;
   177 
   173 
   178     if info.color_type != ColorType::RGBA {
   174     if info.color_type != ColorType::RGBA {
   179         return Err(ThemeLoadError::Format(
   175         return Err(ThemeLoadError::Format(format!(
   180             format!("Unexpected format: {:?}", info.color_type)));
   176             "Unexpected format: {:?}",
       
   177             info.color_type
       
   178         )));
   181     }
   179     }
   182     let size = Size::new(info.width as usize, info.height as usize);
   180     let size = Size::new(info.width as usize, info.height as usize);
   183 
   181 
   184     let mut pixels: Vec2D<u32> = Vec2D::new(size, 0);
   182     let mut pixels: Vec2D<u32> = Vec2D::new(size, 0);
   185     reader.next_frame(slice_u32_to_u8_mut(pixels.as_mut_slice()))?;
   183     reader.next_frame(slice_u32_to_u8_mut(pixels.as_mut_slice()))?;
   186 
   184 
   187     Ok(ThemeSprite { pixels })
   185     Ok(ThemeSprite { pixels })
   188 }
   186 }
   189 
   187 
   190 pub fn slice_u32_to_u8(slice_u32: &[u32]) -> &[u8] {
   188 pub fn slice_u32_to_u8(slice_u32: &[u32]) -> &[u8] {
   191     unsafe {
   189     unsafe { from_raw_parts::<u8>(slice_u32.as_ptr() as *const u8, slice_u32.len() * 4) }
   192         from_raw_parts::<u8>(
       
   193             slice_u32.as_ptr() as *const u8,
       
   194             slice_u32.len() * 4
       
   195         )
       
   196     }
       
   197 }
   190 }
   198 
   191 
   199 pub fn slice_u32_to_u8_mut(slice_u32: &mut [u32]) -> &mut [u8] {
   192 pub fn slice_u32_to_u8_mut(slice_u32: &mut [u32]) -> &mut [u8] {
   200     unsafe {
   193     unsafe { from_raw_parts_mut::<u8>(slice_u32.as_mut_ptr() as *mut u8, slice_u32.len() * 4) }
   201         from_raw_parts_mut::<u8>(
       
   202             slice_u32.as_mut_ptr() as *mut u8,
       
   203             slice_u32.len() * 4
       
   204         )
       
   205     }
       
   206 }
   194 }
   207