Skip to main content

mireforge_game_assets/
lib.rs

1/*
2 * Copyright (c) Peter Bjorklund. All rights reserved. https://github.com/mireforge/mireforge
3 * Licensed under the MIT License. See LICENSE in the project root for license information.
4 */
5use int_math::UVec2;
6
7use limnus_asset_id::{AssetName, Id};
8use limnus_asset_registry::AssetRegistry;
9use limnus_audio_mixer::{StereoSample, StereoSampleRef};
10use limnus_resource::ResourceStorage;
11use mireforge_font::{Font, GlyphDraw};
12use mireforge_render_wgpu::{
13    FixedAtlas, FontAndMaterial, Material, MaterialBase, MaterialKind, MaterialRef,
14    NineSliceAndMaterial, Slices, Texture, TextureRef,
15};
16use monotonic_time_rs::Millis;
17use std::fmt::Debug;
18use std::sync::Arc;
19
20pub trait Assets {
21    #[must_use]
22    fn now(&self) -> Millis;
23
24    #[must_use]
25    fn texture_png(&mut self, name: impl Into<AssetName>) -> TextureRef;
26
27    #[must_use]
28    fn material_png(&mut self, name: impl Into<AssetName>) -> MaterialRef;
29
30    #[must_use]
31    fn material_alpha_mask(
32        &mut self,
33        name: impl Into<AssetName>,
34        mask: impl Into<AssetName>,
35    ) -> MaterialRef;
36
37    #[must_use]
38    fn light_material_png(&mut self, name: impl Into<AssetName>) -> MaterialRef;
39
40    #[must_use]
41    fn frame_fixed_grid_material_png(
42        &mut self,
43        name: impl Into<AssetName>,
44        grid_size: UVec2,
45        texture_size: UVec2,
46    ) -> FixedAtlas;
47
48    #[must_use]
49    fn nine_slice_material_png(
50        &mut self,
51        name: impl Into<AssetName>,
52        slices: Slices,
53    ) -> NineSliceAndMaterial;
54
55    #[must_use]
56    fn bm_font(&mut self, name: impl Into<AssetName>) -> FontAndMaterial;
57
58    #[must_use]
59    fn bm_font_txt(&mut self, name: impl Into<AssetName>) -> FontAndMaterial;
60
61    #[must_use]
62    fn text_glyphs(&self, text: &str, font_and_mat: &FontAndMaterial) -> Option<GlyphDraw>;
63
64    #[must_use]
65    fn font(&self, font_ref: &Id<Font>) -> Option<&Font>;
66    #[must_use]
67    fn audio_sample_wav(&mut self, name: impl Into<AssetName>) -> StereoSampleRef;
68}
69
70pub struct GameAssets<'a> {
71    now: Millis,
72    resource_storage: &'a mut ResourceStorage,
73}
74
75impl Debug for GameAssets<'_> {
76    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
77        write!(f, "assets")
78    }
79}
80
81impl<'a> GameAssets<'a> {
82    pub const fn new(resource_storage: &'a mut ResourceStorage, now: Millis) -> Self {
83        Self {
84            now,
85            resource_storage,
86        }
87    }
88}
89
90impl Assets for GameAssets<'_> {
91    fn now(&self) -> Millis {
92        self.now
93    }
94
95    fn texture_png(&mut self, name: impl Into<AssetName>) -> TextureRef {
96        let asset_loader = self
97            .resource_storage
98            .get_mut::<AssetRegistry>()
99            .expect("should exist registry");
100
101        let texture_id = asset_loader.load::<Texture>(name.into().with_extension("png"));
102
103        TextureRef::from(texture_id)
104    }
105
106    fn material_png(&mut self, name: impl Into<AssetName>) -> MaterialRef {
107        let asset_loader = self
108            .resource_storage
109            .get_mut::<AssetRegistry>()
110            .expect("should exist registry");
111
112        let texture_ref = asset_loader.load::<Texture>(name.into().with_extension("png"));
113
114        let material = Material {
115            base: MaterialBase {
116                //pipeline: self.renderer().normal_sprite_pipeline.clone(),
117            },
118            kind: MaterialKind::NormalSprite {
119                primary_texture: texture_ref,
120            },
121        };
122
123        Arc::new(material)
124    }
125
126    fn material_alpha_mask(
127        &mut self,
128        name: impl Into<AssetName>,
129        mask: impl Into<AssetName>,
130    ) -> MaterialRef {
131        let asset_loader = self
132            .resource_storage
133            .get_mut::<AssetRegistry>()
134            .expect("should exist registry");
135        let diffuse_texture_id = asset_loader.load::<Texture>(name.into().with_extension("png"));
136        let alpha_mask_texture_id = asset_loader.load::<Texture>(mask.into().with_extension("png"));
137        let material = Material {
138            base: MaterialBase {},
139            kind: MaterialKind::AlphaMasker {
140                primary_texture: diffuse_texture_id,
141                alpha_texture: alpha_mask_texture_id,
142            },
143        };
144
145        Arc::new(material)
146    }
147
148    fn light_material_png(&mut self, name: impl Into<AssetName>) -> MaterialRef {
149        let asset_loader = self
150            .resource_storage
151            .get_mut::<AssetRegistry>()
152            .expect("should exist registry");
153
154        let texture_ref = asset_loader.load::<Texture>(name.into().with_extension("png"));
155
156        let material = Material {
157            base: MaterialBase {
158                //pipeline: self.renderer().normal_sprite_pipeline.clone(),
159            },
160            kind: MaterialKind::LightAdd {
161                primary_texture: texture_ref,
162            },
163        };
164
165        Arc::new(material)
166    }
167
168    fn frame_fixed_grid_material_png(
169        &mut self,
170        name: impl Into<AssetName>,
171        grid_size: UVec2,
172        texture_size: UVec2,
173    ) -> FixedAtlas {
174        let material_ref = self.material_png(name);
175
176        FixedAtlas::new(grid_size, texture_size, material_ref)
177    }
178
179    fn nine_slice_material_png(
180        &mut self,
181        name: impl Into<AssetName>,
182        slices: Slices,
183    ) -> NineSliceAndMaterial {
184        let material_ref = self.material_png(name);
185
186        NineSliceAndMaterial {
187            slices,
188            material_ref,
189        }
190    }
191
192    fn bm_font(&mut self, name: impl Into<AssetName>) -> FontAndMaterial {
193        let asset_name = name.into();
194        let asset_loader = self
195            .resource_storage
196            .get_mut::<AssetRegistry>()
197            .expect("should exist registry");
198        let font_ref = asset_loader.load::<Font>(asset_name.clone().with_extension("fnt"));
199        let texture_id = asset_loader.load::<Texture>(asset_name.clone().with_extension("png"));
200
201        let material = Material {
202            base: MaterialBase {
203                //pipeline: self.renderer().normal_sprite_pipeline.clone(),
204            },
205            kind: MaterialKind::NormalSprite {
206                primary_texture: texture_id,
207            },
208        };
209
210        FontAndMaterial {
211            font_ref,
212            material_ref: Arc::new(material),
213        }
214    }
215
216    fn bm_font_txt(&mut self, name: impl Into<AssetName>) -> FontAndMaterial {
217        let asset_name = name.into();
218        let asset_loader = self
219            .resource_storage
220            .get_mut::<AssetRegistry>()
221            .expect("should exist registry");
222        let font_ref = asset_loader.load::<Font>(asset_name.clone().with_extension("txt.fnt"));
223        let texture_id = asset_loader.load::<Texture>(asset_name.clone().with_extension("png"));
224
225        let material = Material {
226            base: MaterialBase {
227                //pipeline: self.renderer().normal_sprite_pipeline.clone(),
228            },
229            kind: MaterialKind::NormalSprite {
230                primary_texture: texture_id,
231            },
232        };
233
234        FontAndMaterial {
235            font_ref,
236            material_ref: Arc::new(material),
237        }
238    }
239
240    fn text_glyphs(&self, text: &str, font_and_mat: &FontAndMaterial) -> Option<GlyphDraw> {
241        match self.font(&font_and_mat.font_ref) {
242            Some(font) => {
243                let glyphs = font.draw(text);
244                Some(glyphs)
245            }
246            _ => None,
247        }
248    }
249
250    fn font(&self, font_ref: &Id<Font>) -> Option<&Font> {
251        let font_assets = self
252            .resource_storage
253            .get::<limnus_assets::Assets<Font>>()
254            .expect("font assets should be a thing");
255
256        font_assets.get(font_ref)
257    }
258
259    fn audio_sample_wav(&mut self, name: impl Into<AssetName>) -> StereoSampleRef {
260        let asset_loader = self
261            .resource_storage
262            .get_mut::<AssetRegistry>()
263            .expect("should exist registry");
264        asset_loader.load::<StereoSample>(name.into().with_extension("wav"))
265    }
266}