diff options
Diffstat (limited to 'src/main.rs')
| -rw-r--r-- | src/main.rs | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..717599d --- /dev/null +++ b/src/main.rs @@ -0,0 +1,160 @@ +use std::collections::HashMap; +use std::fs::File; +use std::io::Read; +use std::num::NonZeroU32; +use std::path::Path; + +use alligator_scripts::ScriptManager; +use alligator_sprites::SpriteManager; +use alligator_sys::{Renderer, RendererConfig, Window, WindowConfig, WindowEvent}; +use alligator_textures::TextureManager; + +use serde::Deserialize; +use sha3::{Digest, Sha3_256}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize)] +enum ScriptType { + Wasm, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize)] +enum ConfigWindowMode { + Windowed, + BorderlessFullscreen, +} + +#[derive(Debug, Clone, Deserialize)] +struct ConfigScript { + path: Box<Path>, + script_type: ScriptType, + hash: Option<String>, +} + +#[derive(Debug, Clone, Deserialize)] +struct ConfigSprite { + texture: String, + x: f32, + y: f32, + z: f32, +} + +#[derive(Debug, Clone, Deserialize)] +struct ConfigTexture { + size: usize, + path: Box<Path>, +} + +#[derive(Debug, Clone, Deserialize)] +struct Scene { + initial_sprites: HashMap<String, ConfigSprite>, + initial_scripts: Vec<String>, +} + +#[derive(Debug, Clone, Deserialize)] +pub struct Config { + alligator_version: usize, + scenes: HashMap<String, Scene>, + textures: HashMap<String, ConfigTexture>, + scripts: HashMap<String, ConfigScript>, + default_scene: String, + sprite_manager_capacity: u32, + default_window_width: NonZeroU32, + default_window_height: NonZeroU32, + default_window_mode: ConfigWindowMode, + window_title: String, + vsync: bool, +} + +fn texture_manager(config: &Config) -> TextureManager { + let mut textures = TextureManager::new(config.default_textures_size_target); + for (key, texture) in config.textures.iter() { + textures.add_texture( + key.clone().into(), + texture.path.clone().into(), + texture.size, + ); + } + + textures +} + +fn sprite_manager(config: &Config) -> SpriteManager { + SpriteManager::with_capacity(config.sprite_manager_capacity as usize) +} + +fn script_manager(config: &Config) -> ScriptManager { + let mut scripts = ScriptManager::new(); + for (key, script) in config.scripts.iter() { + let path = script.path.clone(); + let trusted = if let Some(hash) = &script.hash { + let mut bytes = Vec::new(); + let mut msg = File::open(&path).unwrap(); + msg.read_to_end(&mut bytes).unwrap(); + let mut hasher = Sha3_256::new(); + hasher.update(bytes); + let result = hasher.finalize(); + hash.as_bytes() == &result[..] + } else { + false + }; + + scripts + .add_wasm_script(key.clone().into_boxed_str(), path, trusted) + .unwrap(); + } + + scripts +} + +fn window(config: &Config) -> Window { + let config = WindowConfig { + title: config.window_title.clone(), + default_width: config.default_window_width.get(), + default_height: config.default_window_height.get(), + default_x: 100, + default_y: 100, + borderless_fullscreen: config.default_window_mode == ConfigWindowMode::BorderlessFullscreen, + visible: false, + }; + + Window::new(config) +} + +fn renderer(config: &Config, window: &Window) -> Renderer { + let config = RendererConfig { + width: config.default_window_width.get(), + height: config.default_window_height.get(), + instance_capacity: config.sprite_manager_capacity, + fullscreen: false, + vsync: config.vsync, + }; + + Renderer::new(window, config) +} + +fn main() { + std::env::set_current_dir(std::env::current_exe().unwrap().parent().unwrap()).unwrap(); + let config = File::open("game.json").unwrap(); + let config: Config = serde_json::from_reader(config).unwrap(); + + let textures = texture_manager(&config); + let sprites = sprite_manager(&config); + let scripts = script_manager(&config); + let mut window = window(&config); + + window.wait_for_resume(); + + let mut renderer = renderer(&config, &window); + window.set_visible(true); + + window.run(move |window, event| match event { + Some(WindowEvent::RedrawRequest) => { + renderer.render_frame(); + } + Some(WindowEvent::CloseRequest) => { + std::process::exit(0); + } + Some(_) => (), + None => window.request_redraw(), + }) +} |
