From 2c4da6fefeb13e40be3948dd24524b82adcac3df Mon Sep 17 00:00:00 2001 From: LLLL Colonq Date: Sun, 16 Feb 2025 04:46:35 -0500 Subject: Fix saves --- .gitmodules | 3 ++ Cargo.lock | 92 ++++++++++++++++++++++++++++++++++++++++++++++------- Cargo.toml | 12 ++++--- deps/directories-rs | 1 + src/font.rs | 2 +- src/lib.rs | 64 ++++++++++++++++++++----------------- src/main.rs | 2 +- src/save.rs | 40 +++++++++++++++++++++++ src/state.rs | 3 -- 9 files changed, 167 insertions(+), 52 deletions(-) create mode 160000 deps/directories-rs create mode 100644 src/save.rs diff --git a/.gitmodules b/.gitmodules index 3ddd468..2317b8f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "deps/glfw-rs"] path = deps/glfw-rs url = git@github.com:lcolonq/glfw-rs.git +[submodule "deps/directories-rs"] + path = deps/directories-rs + url = git@github.com:lcolonq/directories-rs.git diff --git a/Cargo.lock b/Cargo.lock index f1ca1fb..d2c408f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -101,7 +101,7 @@ dependencies = [ "ndk-context", "ndk-sys", "num_enum", - "thiserror", + "thiserror 1.0.57", ] [[package]] @@ -318,7 +318,7 @@ dependencies = [ "polling", "rustix", "slab", - "thiserror", + "thiserror 1.0.57", ] [[package]] @@ -571,6 +571,25 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c87e182de0887fd5361989c677c4e8f5000cd9491d6d563161a8f3a5519fc7f" +[[package]] +name = "directories" +version = "6.0.0" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.59.0", +] + [[package]] name = "dispatch" version = "0.2.0" @@ -1208,7 +1227,7 @@ dependencies = [ "combine", "jni-sys", "log", - "thiserror", + "thiserror 1.0.57", "walkdir", "windows-sys 0.45.0", ] @@ -1301,6 +1320,16 @@ dependencies = [ "redox_syscall 0.4.1", ] +[[package]] +name = "libredox" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags 2.6.0", + "libc", +] + [[package]] name = "linux-raw-sys" version = "0.4.13" @@ -1416,7 +1445,7 @@ dependencies = [ "ndk-sys", "num_enum", "raw-window-handle", - "thiserror", + "thiserror 1.0.57", ] [[package]] @@ -1605,13 +1634,19 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + [[package]] name = "orbclient" version = "0.3.47" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52f0d54bde9774d3a51dcf281a5def240c71996bc6ca05d2c847ec8b2b216166" dependencies = [ - "libredox", + "libredox 0.0.2", ] [[package]] @@ -1720,9 +1755,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" dependencies = [ "unicode-ident", ] @@ -1837,6 +1872,17 @@ dependencies = [ "bitflags 2.6.0", ] +[[package]] +name = "redox_users" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b" +dependencies = [ + "getrandom", + "libredox 0.1.3", + "thiserror 2.0.11", +] + [[package]] name = "regex" version = "1.11.1" @@ -2187,7 +2233,7 @@ dependencies = [ "log", "memmap2", "rustix", - "thiserror", + "thiserror 1.0.57", "wayland-backend", "wayland-client", "wayland-csd-frame", @@ -2361,9 +2407,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.52" +version = "2.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07" +checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1" dependencies = [ "proc-macro2", "quote", @@ -2405,10 +2451,11 @@ name = "teleia" version = "0.1.0" dependencies = [ "bimap", - "bitflags 1.3.2", + "bitflags 2.6.0", "bytes", "console_error_panic_hook", "console_log", + "directories", "enum-map", "env_logger", "fontdue", @@ -2424,6 +2471,7 @@ dependencies = [ "rand", "reqwest", "serde", + "serde_json", "tobj", "tokio", "tracing-wasm", @@ -2452,7 +2500,16 @@ version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b" dependencies = [ - "thiserror-impl", + "thiserror-impl 1.0.57", +] + +[[package]] +name = "thiserror" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc" +dependencies = [ + "thiserror-impl 2.0.11", ] [[package]] @@ -2466,6 +2523,17 @@ dependencies = [ "syn", ] +[[package]] +name = "thiserror-impl" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "thread_local" version = "1.1.8" diff --git a/Cargo.toml b/Cargo.toml index 23dd274..55627e3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,6 +29,7 @@ glam = "*" # linear algebra log = "*" # logging rand = {version = "*", features = ["small_rng"]} # rng serde = {version = "*", features = ["derive"]} # serialization +serde_json = "*" # serialize JSON enum-map = "*" # fast maps with enums as keys bimap = "*" # bijective maps reqwest = "*" # http requests @@ -44,10 +45,11 @@ tracing-wasm = "*" # trace performance in browser wasm-bindgen = "*" # interface with javascript wasm-bindgen-futures = "*" # interface with async javascript js-sys = "*" # browser APIs to interact with JS runtime (e.g. run WASM) -web-sys = { version = "*", features = ["Document", "Window", "Element", "HtmlCanvasElement", "WebGl2RenderingContext", "Headers", "Request", "RequestInit", "RequestMode", "Response", "Performance", "PerformanceTiming", "AudioContext", "AudioNode", "AudioDestinationNode", "AudioBuffer", "AudioBufferSourceNode", "BinaryType", "Blob", "CloseEvent", "ErrorEvent", "FileReader", "MessageEvent", "ProgressEvent", "WebSocket"] } +web-sys = { version = "*", features = ["Document", "Window", "Element", "HtmlCanvasElement", "WebGl2RenderingContext", "Headers", "Request", "RequestInit", "RequestMode", "Response", "Performance", "PerformanceTiming", "AudioContext", "AudioNode", "AudioDestinationNode", "AudioBuffer", "AudioBufferSourceNode", "BinaryType", "Blob", "CloseEvent", "ErrorEvent", "FileReader", "MessageEvent", "ProgressEvent", "WebSocket", "Storage"] } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] -env_logger = "*" -glfw = { path = "deps/glfw-rs", features = ["serde"] } -kira = "0.9.6" -tokio = { version = "*", features = ["full"] } +env_logger = "*" # configurable logging to stdout +tokio = { version = "*", features = ["full"] } # async runtime +glfw = { path = "deps/glfw-rs", features = ["serde"] } # window management +kira = "0.9.6" # audio +directories = { path = "deps/directories-rs" } # standard system directories \ No newline at end of file diff --git a/deps/directories-rs b/deps/directories-rs new file mode 160000 index 0000000..164536d --- /dev/null +++ b/deps/directories-rs @@ -0,0 +1 @@ +Subproject commit 164536daab2c07265167715934081cb1942387b0 diff --git a/src/font.rs b/src/font.rs index 3074dff..e431896 100644 --- a/src/font.rs +++ b/src/font.rs @@ -92,7 +92,7 @@ impl Bitmap { texcoords.push(tcbase + glam::Vec2::new(cwidth, cheight)); texcoords.push(tcbase + glam::Vec2::new(cwidth, 0.0)); texcoords.push(tcbase); - let c = if let Some(c) = color.get(i) { + let c = if let Some(c) = color.get(if color.len() == 0 { 0 } else { i % color.len() }) { *c } else { glam::Vec3::new(1.0, 1.0, 1.0) diff --git a/src/lib.rs b/src/lib.rs index 6d6fc9d..d0ee6d9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,6 +11,7 @@ pub mod font; pub mod shadow; pub mod audio; pub mod net; +pub mod save; use std::ops::Rem; @@ -29,6 +30,14 @@ use glfw::Context; #[cfg(not(target_arch = "wasm32"))] use bitflags::bitflags; +#[cfg(not(target_arch = "wasm32"))] +bitflags! { + pub struct Options: u32 { + const OVERLAY = 0b00000001; + const HIDDEN = 0b00000010; + } +} + static mut CTX: Option<*const context::Context> = None; static mut ST: Option<*mut state::State> = None; static mut G: Option<*mut std::ffi::c_void> = None; @@ -45,13 +54,6 @@ where } } -bitflags! { - pub struct Options: u32 { - const OVERLAY = 0b00000001; - const HIDDEN = 0b00000010; - } -} - #[cfg(not(target_arch = "wasm32"))] pub async fn run<'a, F, G, Fut>(title: &str, w: u32, h: u32, options: Options, gnew: F) where @@ -100,6 +102,10 @@ where }); window.make_current(); window.set_key_polling(true); + window.set_mouse_button_polling(true); + window.set_size_polling(true); + window.set_focus_polling(true); + window.set_cursor_pos_polling(true); let gl = unsafe { glow::Context::from_loader_function(|s| window.get_proc_address(s) as *const _) }; @@ -126,27 +132,25 @@ where ctx.glfw.borrow_mut().poll_events(); for (_, event) in glfw::flush_messages(&events) { match event { - // sdl2::event::Event::Window { win_event: sdl2::event::WindowEvent::Resized(_, _), .. } => { - // st.handle_resize(&ctx); - // }, - // sdl2::event::Event::Window { win_event: sdl2::event::WindowEvent::FocusLost, .. } => { - // st.keys = state::Keys::new(); - // }, - // sdl2::event::Event::MouseMotion { x, y, .. } => { - // st.mouse_moved(&ctx, x as f32, y as f32, game); - // }, - // sdl2::event::Event::MouseButtonDown {..} => { - // st.mouse_pressed(&ctx, game) - // }, - // sdl2::event::Event::MouseButtonUp {..} => { - // st.mouse_released(&ctx) - // }, - // sdl2::event::Event::KeyDown { keycode: Some(key), repeat: false, .. } => { - // st.key_pressed(&ctx, state::Keycode::new(key)) - // }, - // sdl2::event::Event::KeyUp { keycode: Some(key), repeat: false, .. } => { - // st.key_released(&ctx, state::Keycode::new(key)) - // }, + glfw::WindowEvent::Size(_, _) => st.handle_resize(&ctx), + glfw::WindowEvent::Focus(false) => { + st.keys = state::Keys::new(); + }, + glfw::WindowEvent::CursorPos(x, y) => { + st.mouse_moved(&ctx, x as f32, y as f32, game); + } + glfw::WindowEvent::MouseButton(_, glfw::Action::Press, _) => { + st.mouse_pressed(&ctx, game) + }, + glfw::WindowEvent::MouseButton(_, glfw::Action::Release, _) => { + st.mouse_released(&ctx) + }, + glfw::WindowEvent::Key(key, _, glfw::Action::Press, _) => { + st.key_pressed(&ctx, state::Keycode::new(key)) + }, + glfw::WindowEvent::Key(key, _, glfw::Action::Release, _) => { + st.key_released(&ctx, state::Keycode::new(key)) + }, _ => {}, } } @@ -312,7 +316,7 @@ use wasm_bindgen::prelude::*; pub struct TestGame { font: font::Bitmap, tt: font::TrueType, - cube: mesh::Mesh, + // cube: mesh::Mesh, fox: scene::Scene, tex: texture::Texture, shader: shader::Shader, @@ -323,7 +327,7 @@ impl TestGame { Self { font: font::Bitmap::new(ctx), tt: font::TrueType::new(ctx, 12.0, include_bytes!("assets/fonts/ComicNeue-Regular.ttf")), - cube: mesh::Mesh::from_obj(ctx, include_bytes!("assets/meshes/cube.obj")), + // cube: mesh::Mesh::from_obj(ctx, include_bytes!("assets/meshes/cube.obj")), fox: scene::Scene::from_gltf(ctx, include_bytes!("assets/scenes/fox.glb")), // fox: scene::Scene::from_gltf(ctx, include_bytes!("/home/llll/src/colonq/assets/lcolonq_flat.vrm")), tex: texture::Texture::new(ctx, include_bytes!("assets/textures/test.png")), diff --git a/src/main.rs b/src/main.rs index 5bbebd1..f7c2a88 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,5 +4,5 @@ pub fn main() {} #[cfg(not(target_arch = "wasm32"))] #[tokio::main] pub async fn main() { - teleia::run("teleia test", 240, 160, teleia::TestGame::new).await; + teleia::run("teleia test", 240, 160, teleia::Options::empty(), teleia::TestGame::new).await; } diff --git a/src/save.rs b/src/save.rs new file mode 100644 index 0000000..0f0d20b --- /dev/null +++ b/src/save.rs @@ -0,0 +1,40 @@ +#[cfg(target_arch = "wasm32")] +pub fn save(id: &str, data: &W) where W: serde::Serialize { + let window = web_sys::window().expect("failed to get window object"); + let storage = window.local_storage() + .expect("failed to get local storage") + .expect("local storage not present"); + let key = format!("{}_save", id); + let val = serde_json::to_string(data).expect("failed to serialize save"); + storage.set_item(&key, &val).expect("failed to set save"); +} + +#[cfg(target_arch = "wasm32")] +pub fn load(id: &str) -> Option where W: serde::de::DeserializeOwned { + let window = web_sys::window().expect("failed to get window object"); + let storage = window.local_storage() + .expect("failed to get local storage") + .expect("local storage not present"); + let key = format!("{}_save", id); + let s = storage.get_item(&key).expect("failed to get save").expect("save not present"); + let mut cur = std::io::Cursor::new(s); + serde_json::from_reader(&mut cur).ok() +} + +#[cfg(not(target_arch = "wasm32"))] +pub fn save(id: &str, data: &W) where W: serde::Serialize { + let pd = directories::ProjectDirs::from("", "milkfat", id).expect("failed to get save directory"); + let _ = std::fs::create_dir_all(pd.data_dir()); + let path = pd.data_dir().join("teleia.save"); + let file = std::fs::File::create(&path).expect("failed to open save file"); + serde_json::to_writer(file, data).expect("failed to write save file"); +} + +#[cfg(not(target_arch = "wasm32"))] +pub fn load(id: &str) -> Option where W: serde::de::DeserializeOwned { + let pd = directories::ProjectDirs::from("", "milkfat", id).expect("failed to get save directory"); + let _ = std::fs::create_dir_all(pd.data_dir()); + let path = pd.data_dir().join("teleia.save"); + let file = std::fs::File::open(&path).ok()?; + serde_json::from_reader(file).ok() +} diff --git a/src/state.rs b/src/state.rs index 2ac6d4b..4d23af6 100644 --- a/src/state.rs +++ b/src/state.rs @@ -504,9 +504,6 @@ impl State { pub fn run_render(&mut self, ctx: &context::Context, game: &mut G) where G: Game { self.render_framebuffer.bind(&ctx); - ctx.clear_color(glam::Vec4::new(0.1, 0.1, 0.1, 0.0)); - ctx.clear(); - game.render(ctx, self); self.screen.bind(&ctx); -- cgit v1.2.3