summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitmodules3
-rw-r--r--Cargo.lock92
-rw-r--r--Cargo.toml12
m---------deps/directories-rs0
-rw-r--r--src/font.rs2
-rw-r--r--src/lib.rs64
-rw-r--r--src/main.rs2
-rw-r--r--src/save.rs40
-rw-r--r--src/state.rs3
9 files changed, 166 insertions, 52 deletions
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]]
@@ -572,6 +572,25 @@ 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"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1208,7 +1227,7 @@ dependencies = [
"combine",
"jni-sys",
"log",
- "thiserror",
+ "thiserror 1.0.57",
"walkdir",
"windows-sys 0.45.0",
]
@@ -1302,6 +1321,16 @@ dependencies = [
]
[[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"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1416,7 +1445,7 @@ dependencies = [
"ndk-sys",
"num_enum",
"raw-window-handle",
- "thiserror",
+ "thiserror 1.0.57",
]
[[package]]
@@ -1606,12 +1635,18 @@ dependencies = [
]
[[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",
]
@@ -1838,6 +1873,17 @@ dependencies = [
]
[[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"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -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]]
@@ -2467,6 +2524,17 @@ dependencies = [
]
[[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"
source = "registry+https://github.com/rust-lang/crates.io-index"
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
+Subproject 164536daab2c07265167715934081cb1942387b
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<W>(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<W>(id: &str) -> Option<W> 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<W>(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<W>(id: &str) -> Option<W> 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<G>(&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);