allow finding sprites
authoralfadur
Thu, 12 Nov 2020 00:24:58 +0300
changeset 15759 c929e25a7da2
parent 15758 6c939e6de981
child 15760 ff1432e873bd
allow finding sprites
rust/lib-hedgewars-engine/src/lib.rs
rust/lib-hedgewars-engine/src/render/atlas.rs
rust/lib-hedgewars-engine/src/render/gear.rs
rust/lib-hedgewars-engine/src/world.rs
--- a/rust/lib-hedgewars-engine/src/lib.rs	Wed Nov 11 22:41:31 2020 +0300
+++ b/rust/lib-hedgewars-engine/src/lib.rs	Thu Nov 12 00:24:58 2020 +0300
@@ -78,7 +78,6 @@
     x: i32,
     y: i32,
 ) {
-
 }
 
 #[no_mangle]
--- a/rust/lib-hedgewars-engine/src/render/atlas.rs	Wed Nov 11 22:41:31 2020 +0300
+++ b/rust/lib-hedgewars-engine/src/render/atlas.rs	Thu Nov 12 00:24:58 2020 +0300
@@ -335,7 +335,7 @@
                 buffer,
                 &mut buffer_size,
                 free_rect.with_margins(0, 0, 0, -trim),
-            );;
+            );
         }
         if rect.bottom() < free_rect.bottom() {
             let trim = rect.bottom() - free_rect.top() + 1;
@@ -344,7 +344,7 @@
                 buffer,
                 &mut buffer_size,
                 free_rect.with_margins(0, 0, -trim, 0),
-            );;
+            );
         }
     }
     if split {
--- a/rust/lib-hedgewars-engine/src/render/gear.rs	Wed Nov 11 22:41:31 2020 +0300
+++ b/rust/lib-hedgewars-engine/src/render/gear.rs	Thu Nov 12 00:24:58 2020 +0300
@@ -1,22 +1,46 @@
-use super::{atlas::AtlasCollection, gl::Texture2D};
-use crate::render::camera::Camera;
+use crate::render::{
+    atlas::{AtlasCollection, SpriteIndex, SpriteLocation},
+    camera::Camera,
+    gl::Texture2D,
+};
 
 use integral_geometry::{Rect, Size};
 
-use crate::render::atlas::SpriteIndex;
 use png::{ColorType, Decoder, DecodingError};
-use std::path::PathBuf;
+
 use std::{
     collections::HashMap,
     ffi::OsString,
     fs::{read_dir, File},
     io,
     io::BufReader,
-    path::Path,
+    path::{Path, PathBuf},
 };
 
+#[derive(PartialEq, Debug, Clone, Copy)]
+enum SpriteId {
+    Mine = 0,
+    Grenade,
+
+    MaxSprite,
+}
+
+const SPRITE_LOAD_LIST: &[(SpriteId, &str)] = &[
+    (
+        SpriteId::Mine,
+        "../../share/hedgewars/Data/Graphics/MineOn.png",
+    ),
+    (
+        SpriteId::Grenade,
+        "../../share/hedgewars/Data/Graphics/Bomb.png",
+    ),
+];
+
+const MAX_SPRITES: usize = SpriteId::MaxSprite as usize + 1;
+
 pub struct GearRenderer {
     atlas: AtlasCollection,
+    allocation: Box<[SpriteLocation; MAX_SPRITES]>,
 }
 
 struct SpriteData {
@@ -28,49 +52,36 @@
 
 impl GearRenderer {
     pub fn new() -> Self {
-        let mut lookup = Vec::with_capacity(2048);
-
         let mut atlas = AtlasCollection::new(ATLAS_SIZE);
-        let mut sprites = load_sprites(Path::new("../../share/hedgewars/Data/Graphics/"))
-            .expect("Unable to load Graphics");
-        let max_size = sprites
-            .iter()
-            .fold(Size::EMPTY, |size, sprite| size.join(sprite.size));
-        for sprite in sprites.drain(..) {
-            lookup.push((sprite.filename, atlas.insert_sprite(sprite.size).unwrap()));
-        }
-
-        println!(
-            "Filled atlas with {} sprites:\n{}",
-            sprites.len(),
-            atlas.used_space()
-        );
 
         let texture = Texture2D::new(ATLAS_SIZE, gl::RGBA8, gl::LINEAR);
 
-        let mut pixels = vec![0; max_size.area()].into_boxed_slice();
-        let mut pixels_transposed = vec![0; max_size.area()].into_boxed_slice();
+        let mut allocation = Box::new([(0, Rect::at_origin(Size::EMPTY)); MAX_SPRITES]);
 
-        for (path, sprite_index) in lookup.drain(..) {
-            if let Some((atlas_index, rect)) = atlas.get_rect(sprite_index) {
-                let size = load_sprite_pixels(&path, mapgen::theme::slice_u32_to_u8_mut(&mut pixels[..])).expect("Unable to load Graphics");
+        for (sprite, file) in SPRITE_LOAD_LIST {
+            let path = Path::new(file);
+            let size = load_sprite_size(path).expect(&format!("Unable to open {}", file));
+            let index = atlas
+                .insert_sprite(size)
+                .expect(&format!("Could not store sprite {:?}", sprite));
+            let (texture_index, rect) = atlas.get_rect(index).unwrap();
 
-                let used_pixels = if size.width != rect.width() {
-                    for y in 0..rect.height() {
-                        for x in 0..rect.width() {
-                            pixels_transposed[y * rect.width() + x] = pixels[x * rect.height() + y];
-                        }
-                    }
-                    &mut pixels_transposed[..]
-                } else {
-                    &mut pixels[..]
-                };
+            let mut pixels = vec![0; size.area()].into_boxed_slice();
+            load_sprite_pixels(path, mapgen::theme::slice_u32_to_u8_mut(&mut pixels[..]))
+                .expect("Unable to load Graphics");
 
-                texture.update(rect, mapgen::theme::slice_u32_to_u8_mut(used_pixels), 0, gl::RGBA, gl::UNSIGNED_BYTE);
-            }
+            texture.update(
+                rect,
+                mapgen::theme::slice_u32_to_u8_mut(&mut pixels[..]),
+                0,
+                gl::RGBA,
+                gl::UNSIGNED_BYTE,
+            );
+
+            allocation[*sprite as usize] = (texture_index, rect);
         }
 
-        Self { atlas }
+        Self { atlas, allocation }
     }
 
     pub fn render(&mut self, camera: &Camera) {
--- a/rust/lib-hedgewars-engine/src/world.rs	Wed Nov 11 22:41:31 2020 +0300
+++ b/rust/lib-hedgewars-engine/src/world.rs	Thu Nov 12 00:24:58 2020 +0300
@@ -134,14 +134,10 @@
         if let Some(ref mut state) = self.game_state {
             let id = state.physics.new_gear().unwrap();
             let fp_position = FPPoint::new(position.x.into(), position.y.into());
-            state.physics.add_gear_data(
-                id,
-                &PositionData(fp_position)
-            );
-            state.physics.add_gear_data(
-                id,
-                &VelocityData(FPPoint::zero())
-            )
+            state.physics.add_gear_data(id, &PositionData(fp_position));
+            state
+                .physics
+                .add_gear_data(id, &VelocityData(FPPoint::zero()))
         }
     }