diff options
| author | metamuffin <metamuffin@disroot.org> | 2024-07-16 17:51:59 +0200 | 
|---|---|---|
| committer | metamuffin <metamuffin@disroot.org> | 2024-07-16 17:51:59 +0200 | 
| commit | 9dfc5afb299ed74b277735bcf06f47b52f68caee (patch) | |
| tree | 2a6cd5f5197e4d616c8907482698bfa781aab466 /light-client/src/render/mod.rs | |
| parent | 14a4379a68f5e514ddeed82ef8f385d4acc9b4d1 (diff) | |
| download | hurrycurry-9dfc5afb299ed74b277735bcf06f47b52f68caee.tar hurrycurry-9dfc5afb299ed74b277735bcf06f47b52f68caee.tar.bz2 hurrycurry-9dfc5afb299ed74b277735bcf06f47b52f68caee.tar.zst  | |
a
Diffstat (limited to 'light-client/src/render/mod.rs')
| -rw-r--r-- | light-client/src/render/mod.rs | 158 | 
1 files changed, 158 insertions, 0 deletions
diff --git a/light-client/src/render/mod.rs b/light-client/src/render/mod.rs new file mode 100644 index 00000000..fbf3d7a5 --- /dev/null +++ b/light-client/src/render/mod.rs @@ -0,0 +1,158 @@ +/* +    Hurry Curry! - a game about cooking +    Copyright 2024 metamuffin + +    This program is free software: you can redistribute it and/or modify +    it under the terms of the GNU Affero General Public License as published by +    the Free Software Foundation, version 3 of the License only. + +    This program is distributed in the hope that it will be useful, +    but WITHOUT ANY WARRANTY; without even the implied warranty of +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +    GNU Affero General Public License for more details. + +    You should have received a copy of the GNU Affero General Public License +    along with this program.  If not, see <https://www.gnu.org/licenses/>. + +*/ +pub mod sprite; + +use hurrycurry_protocol::glam::Vec2; +use sdl2::{ +    pixels::PixelFormatEnum, +    rect::{FRect, Rect}, +    render::{BlendMode, Canvas, Texture, TextureAccess, TextureCreator}, +    video::{Window, WindowContext}, +}; +use sprite::{Sprite, SpriteDraw}; +use std::collections::HashMap; + +pub struct SpriteRenderer<'a> { +    metadata: HashMap<String, Rect>, + +    texture: Texture<'a>, + +    view_scale: Vec2, +    view_offset: Vec2, + +    sprites: Vec<SpriteDraw>, +} + +impl<'a> SpriteRenderer<'a> { +    pub fn init(texture_creator: &'a TextureCreator<WindowContext>) -> Self { +        let palette = include_str!("../../assets/palette.csv") +            .split('\n') +            .filter(|l| !l.is_empty()) +            .map(|s| { +                let mut toks = s.split(","); +                ( +                    toks.next().unwrap().chars().next().unwrap(), +                    [ +                        toks.next().unwrap().parse::<u8>().unwrap(), +                        toks.next().unwrap().parse::<u8>().unwrap(), +                        toks.next().unwrap().parse::<u8>().unwrap(), +                        toks.next().unwrap().parse::<u8>().unwrap(), +                    ], +                ) +            }) +            .collect::<HashMap<_, _>>(); + +        let mut texels = vec![255; 1024 * 1024 * 4]; + +        for (y, line) in include_str!("../../assets/atlas.ta").lines().enumerate() { +            if line.is_empty() { +                continue; +            } +            for (x, char) in line.chars().enumerate() { +                let color = palette.get(&char).unwrap(); +                texels[(y * 1024 + x) * 4 + 0] = color[3]; +                texels[(y * 1024 + x) * 4 + 1] = color[2]; +                texels[(y * 1024 + x) * 4 + 2] = color[1]; +                texels[(y * 1024 + x) * 4 + 3] = color[0]; +            } +        } + +        let mut texture = texture_creator +            .create_texture( +                Some(PixelFormatEnum::RGBA8888), +                TextureAccess::Streaming, +                1024, +                1024, +            ) +            .unwrap(); + +        texture.update(None, &texels, 1024 * 4).unwrap(); +        texture.set_blend_mode(BlendMode::Blend); + +        let metadata = include_str!("../../assets/atlas.meta.csv") +            .lines() +            .filter(|l| !l.is_empty()) +            .map(|l| { +                let mut toks = l.split(","); +                let x: i32 = toks.next().unwrap().parse().unwrap(); +                let y: i32 = toks.next().unwrap().parse().unwrap(); +                let w: u32 = toks.next().unwrap().parse().unwrap(); +                let h: u32 = toks.next().unwrap().parse().unwrap(); +                let name = toks.next().unwrap().to_string(); +                (name, Rect::new(x, y, w, h)) +            }) +            .collect::<HashMap<_, _>>(); + +        Self { +            texture, +            metadata, +            sprites: vec![], +            view_offset: Vec2::ZERO, +            view_scale: Vec2::splat(3.), +        } +    } + +    #[inline] +    pub fn metadata(&self) -> &HashMap<String, Rect> { +        &self.metadata +    } + +    pub fn set_modulation(&mut self, r: u8, g: u8, b: u8, a: u8) { +        self.texture.set_alpha_mod(a); +        self.texture.set_color_mod(r, g, b); +    } +    pub fn reset_modulation(&mut self) { +        self.set_modulation(255, 255, 255, 255) +    } + +    pub fn draw_world(&mut self, sprite: SpriteDraw) { +        self.sprites.push(SpriteDraw { +            z_order: sprite.z_order, +            src: sprite.src, +            dst: FRect::new( +                ((sprite.dst.x + self.view_offset.x) * 32.).round() * self.view_scale.x, +                ((sprite.dst.y + self.view_offset.y) * 24.).round() * self.view_scale.y, +                (sprite.dst.w * 32.).round() * self.view_scale.x, +                (sprite.dst.h * 24.).round() * self.view_scale.y, +            ), +        }) +    } + +    pub fn submit(&mut self, canvas: &mut Canvas<Window>) { +        self.sprites.sort(); +        for SpriteDraw { src, dst, .. } in self.sprites.drain(..) { +            canvas.copy_f(&self.texture, src, dst).unwrap(); +        } +    } +} + +pub struct MiscTextures { +    pub player: Sprite, +} + +impl MiscTextures { +    pub fn init(renderer: &SpriteRenderer) -> Self { +        MiscTextures { +            player: Sprite::new( +                *renderer.metadata().get("player+a").unwrap(), +                Vec2::Y * 0.3, +                0., +            ), +        } +    } +}  |