1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
//! Sprite loading functions.

use anyhow::Context;
use png::{BitDepth, ColorType};
use sdl2::pixels::PixelFormatEnum;
use sdl2::render::{Texture, TextureCreator};
use sdl2::surface::Surface;

use crate::SdlError;

/// The tile index for the player sprite.
pub const TILE_INDEX_PLAYER: u32 = 74;

/// Loads [tileset.png](../../../../client/src/graphics/tileset.png) and creates
/// a texture out of it.
///
/// ### The image
///
/// ![tileset.png](../../../../client/src/graphics/tileset.png)
pub fn load_tileset<T>(texture_creator: &TextureCreator<T>) -> anyhow::Result<Texture> {
    let decoder = png::Decoder::new(&include_bytes!("../../graphics/tileset.png")[..]);
    let mut reader = decoder.read_info().unwrap();
    let mut buf = vec![0; reader.output_buffer_size()];
    let info = reader.next_frame(&mut buf).unwrap();
    if info.bit_depth != BitDepth::Eight || info.color_type != ColorType::Rgba {
        return Err(anyhow::format_err!(
            "Tileset is not an 8-bit RGBA image! Bit depth: {:?}, color type: {:?}",
            info.bit_depth,
            info.color_type,
        ));
    }
    let (w, h) = (info.width, info.height);
    let pixels = &mut buf[..info.buffer_size()];
    let tileset_surf = Surface::from_data(pixels, w, h, w * 4, PixelFormatEnum::RGBA32)
        .map_err(SdlError)
        .context("Failed to create the tileset surface.")?;
    Texture::from_surface(&tileset_surf, texture_creator)
        .context("Failed to create the tileset texture.")
}