From de99c5f7636a952025ea13de02bafd25bcb6bdec Mon Sep 17 00:00:00 2001 From: LLLL Colonq Date: Mon, 17 Aug 2026 20:14:16 -0400 Subject: Fix broken --- .../vendor/teleia/crates/teleia/Cargo.toml | 53 -- .../rpc2dot0/vendor/teleia/crates/teleia/build.rs | 15 - .../crates/teleia/src/assets/fonts/default.png | Bin 1042 -> 0 bytes .../crates/teleia/src/assets/fonts/small.png | Bin 904 -> 0 bytes .../crates/teleia/src/assets/meshes/square.obj | 15 - .../teleia/src/assets/shaders/bitmap/frag.glsl | 15 - .../teleia/src/assets/shaders/bitmap/vert.glsl | 20 - .../teleia/src/assets/shaders/common/frag.glsl | 160 ----- .../teleia/src/assets/shaders/common/vert.glsl | 30 - .../teleia/src/assets/shaders/flat/frag.glsl | 12 - .../teleia/src/assets/shaders/flat/vert.glsl | 4 - .../teleia/src/assets/shaders/scale/frag.glsl | 12 - .../teleia/src/assets/shaders/scale/vert.glsl | 22 - .../teleia/src/assets/shaders/scene/frag.glsl | 11 - .../teleia/src/assets/shaders/scene/vert.glsl | 18 - .../teleia/src/assets/shaders/test/frag.glsl | 23 - .../teleia/src/assets/shaders/test/vert.glsl | 4 - .../teleia/src/assets/shaders/tiled/frag.glsl | 12 - .../teleia/src/assets/shaders/tiled/vert.glsl | 14 - .../teleia/src/assets/shaders/truetype/frag.glsl | 16 - .../teleia/src/assets/shaders/truetype/vert.glsl | 17 - .../teleia/src/assets/shaders/uber/frag.glsl | 193 ------ .../teleia/src/assets/shaders/uber/vert.glsl | 41 -- .../vendor/teleia/crates/teleia/src/audio.rs | 341 ---------- .../vendor/teleia/crates/teleia/src/context.rs | 302 --------- .../vendor/teleia/crates/teleia/src/font.rs | 194 ------ .../vendor/teleia/crates/teleia/src/framebuffer.rs | 158 ----- .../vendor/teleia/crates/teleia/src/helpers.js | 21 - .../vendor/teleia/crates/teleia/src/js/module.js | 7 - .../vendor/teleia/crates/teleia/src/level2d.rs | 1 - .../teleia/crates/teleia/src/level2d/tiled.rs | 301 --------- .../vendor/teleia/crates/teleia/src/lib.rs | 355 ---------- .../vendor/teleia/crates/teleia/src/mesh.rs | 197 ------ .../vendor/teleia/crates/teleia/src/net.rs | 4 - .../vendor/teleia/crates/teleia/src/net/fig.rs | 100 --- .../vendor/teleia/crates/teleia/src/net/ws.rs | 10 - .../teleia/crates/teleia/src/net/ws/client.rs | 9 - .../crates/teleia/src/net/ws/client/native.rs | 124 ---- .../teleia/crates/teleia/src/net/ws/client/wasm.rs | 73 -- .../teleia/crates/teleia/src/net/ws/server.rs | 140 ---- .../vendor/teleia/crates/teleia/src/physics.rs | 0 .../vendor/teleia/crates/teleia/src/renderer.rs | 337 ---------- .../vendor/teleia/crates/teleia/src/save.rs | 47 -- .../vendor/teleia/crates/teleia/src/scene.rs | 401 ----------- .../vendor/teleia/crates/teleia/src/shader.rs | 260 -------- .../vendor/teleia/crates/teleia/src/shadow.rs | 127 ---- .../vendor/teleia/crates/teleia/src/state.rs | 735 --------------------- .../vendor/teleia/crates/teleia/src/texture.rs | 156 ----- .../rpc2dot0/vendor/teleia/crates/teleia/src/ui.rs | 169 ----- .../vendor/teleia/crates/teleia/src/utils.rs | 147 ----- .../vendor/teleia/crates/teleia_macros/Cargo.toml | 14 - .../vendor/teleia/crates/teleia_macros/src/lib.rs | 231 ------- 52 files changed, 5668 deletions(-) delete mode 100644 2026/games/rpc2dot0/vendor/teleia/crates/teleia/Cargo.toml delete mode 100644 2026/games/rpc2dot0/vendor/teleia/crates/teleia/build.rs delete mode 100644 2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/fonts/default.png delete mode 100644 2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/fonts/small.png delete mode 100644 2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/meshes/square.obj delete mode 100644 2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/bitmap/frag.glsl delete mode 100644 2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/bitmap/vert.glsl delete mode 100644 2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/common/frag.glsl delete mode 100644 2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/common/vert.glsl delete mode 100644 2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/flat/frag.glsl delete mode 100644 2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/flat/vert.glsl delete mode 100644 2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/scale/frag.glsl delete mode 100644 2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/scale/vert.glsl delete mode 100644 2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/scene/frag.glsl delete mode 100644 2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/scene/vert.glsl delete mode 100644 2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/test/frag.glsl delete mode 100644 2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/test/vert.glsl delete mode 100644 2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/tiled/frag.glsl delete mode 100644 2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/tiled/vert.glsl delete mode 100644 2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/truetype/frag.glsl delete mode 100644 2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/truetype/vert.glsl delete mode 100644 2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/uber/frag.glsl delete mode 100644 2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/uber/vert.glsl delete mode 100644 2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/audio.rs delete mode 100644 2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/context.rs delete mode 100644 2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/font.rs delete mode 100644 2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/framebuffer.rs delete mode 100644 2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/helpers.js delete mode 100644 2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/js/module.js delete mode 100644 2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/level2d.rs delete mode 100644 2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/level2d/tiled.rs delete mode 100644 2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/lib.rs delete mode 100644 2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/mesh.rs delete mode 100644 2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/net.rs delete mode 100644 2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/net/fig.rs delete mode 100644 2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/net/ws.rs delete mode 100644 2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/net/ws/client.rs delete mode 100644 2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/net/ws/client/native.rs delete mode 100644 2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/net/ws/client/wasm.rs delete mode 100644 2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/net/ws/server.rs delete mode 100644 2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/physics.rs delete mode 100644 2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/renderer.rs delete mode 100644 2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/save.rs delete mode 100644 2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/scene.rs delete mode 100644 2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/shader.rs delete mode 100644 2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/shadow.rs delete mode 100644 2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/state.rs delete mode 100644 2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/texture.rs delete mode 100644 2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/ui.rs delete mode 100644 2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/utils.rs delete mode 100644 2026/games/rpc2dot0/vendor/teleia/crates/teleia_macros/Cargo.toml delete mode 100644 2026/games/rpc2dot0/vendor/teleia/crates/teleia_macros/src/lib.rs (limited to '2026/games/rpc2dot0/vendor/teleia/crates') diff --git a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/Cargo.toml b/2026/games/rpc2dot0/vendor/teleia/crates/teleia/Cargo.toml deleted file mode 100644 index 90a0cca..0000000 --- a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/Cargo.toml +++ /dev/null @@ -1,53 +0,0 @@ -[package] -name = "teleia" -version.workspace = true -edition.workspace = true -authors.workspace = true - -[lib] -crate-type = ["cdylib", "rlib"] - -[dependencies] -strum = { version = "0.27.1", features = ["derive"] } # utility macros for enums -glow = { version = "=0.13.1", features = [] } # rendering -tobj = "=4.0.1" # loader for .obj meshes loader -ahash = "=0.8.10" # dependency of tobj -gltf = { git = "https://github.com/lcolonq/gltf", features = ["extras", "import", "names", "utils"] } # loader for .gltf scenes -image = { version = "0.25.10", default-features = false, features = ["jpeg", "png"] } # texture loader -# cosmic-text = { version = "*", default-features = false, features = ["std", "swash"] } # advanced text rendering -glam = "0.29.2" # linear algebra -log = "0.4.21" # logging -rand = { version = "=0.8.5", features = ["small_rng"] } # rng -serde = { version = "1.0.228", features = ["derive"] } # serialization -serde_json = "1.0.128" # serialize JSON -bincode = { version = "2.0.1", features = ["serde"] } # binary serialization -enum-map = "2.7.3" # fast maps with enums as keys -bimap = "0.6.3" # bijective maps -# reqwest = "*" # http requests -bytes = "*" # bytes for http responses -bitflags = { version = "2.6.0", features = ["serde"] } # bitwise flags -simple-eyre = { version = "0.3.1", default-features = false } # error reporting and formatting -rapier3d = "0.23.1" # rigid-body physics -parry3d = "0.18.0" # collision detection -nalgebra = {version = "0.33.2", features = ["convert-glam029"]} # linear algebra library for rapier3d -byteorder = "1.5.0" # read numbers in particular endianness -base64 = "0.22.1" # encode/decode base64 - -[target.'cfg(target_arch = "wasm32")'.dependencies] -winit = {version = "=0.29.15", features = ["serde"]} # windowing and events -getrandom = {version = "*", features = ["js"]} # rng in the browser -console_log = "*" # log to browser console -console_error_panic_hook = "*" # log to browser console on panic -tracing-wasm = "*" # trace performance in browser -wasm-bindgen = "=0.2.100" # 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", "GainNode", "AudioParam", "AudioDestinationNode", "AudioBuffer", "AudioBufferSourceNode", "BinaryType", "Blob", "CloseEvent", "ErrorEvent", "FileReader", "MessageEvent", "ProgressEvent", "WebSocket", "Storage"] } - -[target.'cfg(not(target_arch = "wasm32"))'.dependencies] -env_logger = "0.11.5" # configurable logging to stdout -glfw = { git = "https://github.com/lcolonq/glfw-rs", features = ["serde"] } # window management -kira = { version = "=0.9.6", default-features = false, features = ["cpal", "ogg", "mp3", "wav"] } # audio -directories = { git = "https://github.com/lcolonq/directories-rs" } # standard system directories -polling = "3.11.0" # interface to epoll -tungstenite = { version = "0.24.0", features = ["native-tls"] } # websockets \ No newline at end of file diff --git a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/build.rs b/2026/games/rpc2dot0/vendor/teleia/crates/teleia/build.rs deleted file mode 100644 index 42743ce..0000000 --- a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/build.rs +++ /dev/null @@ -1,15 +0,0 @@ -fn main() { - /*println!("cargo::rerun-if-changed=../../flake.lock"); - match &*std::env::var("CARGO_CFG_TARGET_ARCH").unwrap() { - "x86_64" => if let Ok(p) = std::env::var("LIBCOLONQ_PIT_NATIVE") { - println!("cargo::rustc-link-search={}", p); - }, - "wasm32" => if let Ok(p) = std::env::var("LIBCOLONQ_PIT_WASM") { - - println!("cargo::rustc-link-search={}", p); - }, - _ => eprintln!("warning: building for unknown architecture!"), - } - println!("cargo::rustc-link-lib=static=colonq-pit");*/ - eprint!("we are not using pit at all, this is a fork of teleia where scripting is disabled"); -} diff --git a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/fonts/default.png b/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/fonts/default.png deleted file mode 100644 index 7b1d2a3..0000000 Binary files a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/fonts/default.png and /dev/null differ diff --git a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/fonts/small.png b/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/fonts/small.png deleted file mode 100644 index 1d020f7..0000000 Binary files a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/fonts/small.png and /dev/null differ diff --git a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/meshes/square.obj b/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/meshes/square.obj deleted file mode 100644 index 7acdef6..0000000 --- a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/meshes/square.obj +++ /dev/null @@ -1,15 +0,0 @@ -# Blender 3.6.2 -# www.blender.org -o Cube -v -1.000000 -1.000000 0.000000 -v 1.000000 -1.000000 0.000000 -v -1.000000 1.000000 0.000000 -v 1.000000 1.000000 0.000000 -vn -0.0000 -0.0000 -1.0000 -vt 0.0 1.0 -vt 1.0 0.0 -vt 0.0 0.0 -vt 1.0 1.0 -s 0 -f 3/1/1 2/2/1 1/3/1 -f 3/1/1 4/4/1 2/2/1 diff --git a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/bitmap/frag.glsl b/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/bitmap/frag.glsl deleted file mode 100644 index fbc8d71..0000000 --- a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/bitmap/frag.glsl +++ /dev/null @@ -1,15 +0,0 @@ -#version 300 es -precision highp float; - -uniform sampler2D texture_data; - -in vec2 vertex_texcoord; -in vec3 vertex_color; -out vec4 frag_color; - -void main() { - vec4 texel = texture(texture_data, vertex_texcoord); - if (texel.rgb == vec3(0.0, 0.0, 0.0)) discard; - texel.rgb = vertex_color; - frag_color = texel; -} diff --git a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/bitmap/vert.glsl b/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/bitmap/vert.glsl deleted file mode 100644 index eee22fc..0000000 --- a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/bitmap/vert.glsl +++ /dev/null @@ -1,20 +0,0 @@ -#version 300 es -precision highp float; - -in vec3 vertex; -in vec2 texcoord; -in vec3 color; - -uniform mat4 view; -uniform mat4 position; -uniform mat4 projection; - -out vec2 vertex_texcoord; -out vec3 vertex_color; - -void main() { - vertex_texcoord = texcoord; - vertex_color = color; - vec3 pos = (position * vec4(vertex, 1.0)).xyz; - gl_Position = projection * view * vec4(pos, 1.0); -} diff --git a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/common/frag.glsl b/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/common/frag.glsl deleted file mode 100644 index fee9b80..0000000 --- a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/common/frag.glsl +++ /dev/null @@ -1,160 +0,0 @@ -#version 300 es -precision highp float; - -uniform vec3 camera_pos; -uniform float time; - -uniform vec3 light_ambient_color; -uniform vec3 light_dir; -uniform vec3 light_dir_color; -uniform int light_count; -uniform vec3 light_pos[5]; -uniform vec3 light_color[5]; -uniform vec2 light_attenuation[5]; -uniform highp sampler2DShadow light_shadowbuffer_dir; -uniform samplerCube light_shadowbuffer_point[5]; - -uniform int has_point_shadows; - -in vec2 vertex_texcoord; -in vec3 vertex_normal; -in vec3 vertex_fragpos; -in vec4 vertex_fragpos_shadow_dir; -in vec3 vertex_view_vector; - -out vec4 frag_color; - -mat3 compute_tbn() { - vec3 p = -vertex_view_vector; - vec3 normal = normalize(vertex_normal); - vec3 dpx = dFdx(p); - vec3 dpy = dFdy(p); - vec2 duvx = dFdx(vertex_texcoord); - vec2 duvy = dFdy(vertex_texcoord); - vec3 dpyperp = cross(dpy, normal); - vec3 dpxperp = cross(normal, dpx); - vec3 tangent = dpyperp * duvx.x + dpxperp * duvy.x; - vec3 bitangent = dpyperp * duvx.y + dpxperp * duvy.y; - float invmax = inversesqrt(max(dot(bitangent, bitangent), dot(bitangent, bitangent))); - return mat3(-tangent * invmax, -bitangent * invmax, normal); -} - -vec4 normal_as_color(vec3 n) { - float r = (128.0 + 127.0 * n.r) / 255.0; - float g = (128.0 + 127.0 * n.g) / 255.0; - float b = (128.0 + 127.0 * n.b) / 255.0; - return vec4(r, g, b, 1.0); -} - -vec3 dir_light(vec3 normal) { - return max(dot(normal, -normalize(light_dir)), 0.0) * light_dir_color; -} - -float dir_shadow(vec3 normal) { - vec3 proj = vertex_fragpos_shadow_dir.xyz / vertex_fragpos_shadow_dir.w; - float bias = 0.002; - // float current_depth = proj.z; - // float bias = max(0.05 * (1.0 - dot(normal, -normalize(light_dir))), 0.005); - proj.z -= bias; - proj *= 0.5; proj += 0.5; - if (proj.z > 1.0) return 0.0; - return 1.0 - texture(light_shadowbuffer_dir, proj.xyz); -} - -float point_shadow(vec3 normal, vec3 shadow_vector, float closest_depth) { - closest_depth *= 25.0; - float current_depth = length(shadow_vector); - float bias = max(0.1 * (1.0 - dot(normal, normalize(shadow_vector))), 0.005); - bias = min(bias + current_depth * 0.01, 0.2); - float shadow = current_depth - bias > closest_depth ? 1.0 : 0.0; - return shadow; -} - -vec3 point_light(vec3 normal, const int idx) { - vec3 pos = light_pos[idx]; - vec3 color = light_color[idx]; - float linear = light_attenuation[idx].x; - float quadratic = light_attenuation[idx].y; - vec3 light_vector = pos - vertex_fragpos; - float distance = length(light_vector); - float attenuation = 1.0 / (1.0 + distance * linear + distance * distance * quadratic); - - float directional = max(dot(normal.xyz, normalize(light_vector)), 0.0); - vec3 directional_light = color * directional; - - vec3 view_dir = normalize(camera_pos - vertex_fragpos); - vec3 reflect_dir = reflect(-normalize(light_vector), normalize(normal.xyz)); - float specular = pow(max(dot(view_dir, reflect_dir), 0.0), 32.0); - vec3 specular_light = 0.5 * specular * color; - // return (directional_light + specular_light) * attenuation; - return directional_light * attenuation; -} - -vec3 point_light_billboard(const int idx) { - vec3 pos = light_pos[idx]; - vec3 color = light_color[idx]; - float linear = light_attenuation[idx].x; - float quadratic = light_attenuation[idx].y; - vec3 light_vector = pos - vertex_fragpos; - float distance = length(light_vector); - float attenuation = 1.0 / (1.0 + distance * linear + distance * distance * quadratic); - - return color * attenuation; -} - -vec3 compute_lighting(vec3 normal) { - vec3 ambient_light = light_ambient_color; - - vec3 from_dir = dir_light(normal) * (1.0 - dir_shadow(normal)); - - vec3 shadow_vector[5]; - for (int i = 0; i < light_count; ++i) { - shadow_vector[i] = vertex_fragpos - light_pos[i]; - shadow_vector[i].x *= -1.0; - } - - // can only index array of samplers with a constant, hence the weird setup - #define SAMPLE_SHADOW(n) n < light_count ? texture(light_shadowbuffer_point[n], shadow_vector[n]).r : 1.0 - float shadow_depth[5]; - shadow_depth[0] = SAMPLE_SHADOW(0); - shadow_depth[1] = SAMPLE_SHADOW(1); - shadow_depth[2] = SAMPLE_SHADOW(2); - shadow_depth[3] = SAMPLE_SHADOW(3); - shadow_depth[4] = SAMPLE_SHADOW(4); - - vec3 from_points = vec3(0.0, 0.0, 0.0); - for (int i = 0; i < light_count; ++i) { - from_points += has_point_shadows != 0 - ? point_light(normal, i) * (1.0 - point_shadow(normal, shadow_vector[i], shadow_depth[i])) - : point_light(normal, i); - } - - return (ambient_light + from_dir + from_points); -} - -vec3 compute_lighting_noshadow(vec3 normal) { - vec3 ambient_light = light_ambient_color; - - vec3 from_dir = dir_light(normal); - - vec3 from_points = vec3(0.0, 0.0, 0.0); - for (int i = 0; i < light_count; ++i) { - from_points += point_light(normal, i); - } - - return (ambient_light + from_dir + from_points); -} - -vec3 compute_lighting_billboard(vec3 normal) { - vec3 ambient_light = light_ambient_color; - - vec3 from_dir = light_dir_color / 2.0; - - vec3 from_points = vec3(0.0, 0.0, 0.0); - for (int i = 0; i < light_count; ++i) { - from_points += point_light_billboard(i); - } - - return (ambient_light + from_dir + from_points); -} -#line 0 diff --git a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/common/vert.glsl b/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/common/vert.glsl deleted file mode 100644 index 06f7e30..0000000 --- a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/common/vert.glsl +++ /dev/null @@ -1,30 +0,0 @@ -#version 300 es -precision highp float; - -in vec3 vertex; -in vec3 normal; -in vec2 texcoord; - -uniform mat4 view; -uniform mat4 position; -uniform mat4 projection; -uniform mat4 normal_matrix; -uniform mat4 lightspace_matrix; -uniform vec3 camera_pos; - -out vec2 vertex_texcoord; -out vec3 vertex_normal; -out vec3 vertex_fragpos; -out vec4 vertex_fragpos_shadow_dir; -out vec3 vertex_view_vector; - -void default_main() -{ - vertex_texcoord = texcoord; - vertex_normal = (normal_matrix * vec4(normal, 1.0)).xyz; - vec3 pos = (position * vec4(vertex, 1.0)).xyz; - vertex_fragpos = pos; - vertex_fragpos_shadow_dir = lightspace_matrix * vec4(pos, 1.0); - vertex_view_vector = camera_pos - pos; - gl_Position = projection * view * vec4(pos, 1.0); -} diff --git a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/flat/frag.glsl b/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/flat/frag.glsl deleted file mode 100644 index fa305e6..0000000 --- a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/flat/frag.glsl +++ /dev/null @@ -1,12 +0,0 @@ -uniform sampler2D texture_data; - -uniform float transparency; - -void main() -{ - float opacity = 1.0 - clamp(transparency, 0.0, 1.0); - vec2 tcfull = vec2(vertex_texcoord.x, 1.0 - vertex_texcoord.y); - vec4 texel = texture(texture_data, tcfull); - texel.a *= opacity; - frag_color = texel; -} diff --git a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/flat/vert.glsl b/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/flat/vert.glsl deleted file mode 100644 index 6e796cc..0000000 --- a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/flat/vert.glsl +++ /dev/null @@ -1,4 +0,0 @@ -void main() -{ - default_main(); -} \ No newline at end of file diff --git a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/scale/frag.glsl b/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/scale/frag.glsl deleted file mode 100644 index 257c1b7..0000000 --- a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/scale/frag.glsl +++ /dev/null @@ -1,12 +0,0 @@ -#version 300 es -precision highp float; - -uniform sampler2D texture_data; - -in vec2 vertex_texcoord; -out vec4 frag_color; - -void main() { - vec4 texel = texture(texture_data, vertex_texcoord); - frag_color = texel; -} diff --git a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/scale/vert.glsl b/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/scale/vert.glsl deleted file mode 100644 index d48f78d..0000000 --- a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/scale/vert.glsl +++ /dev/null @@ -1,22 +0,0 @@ -#version 300 es -precision highp float; - -out vec2 vertex_texcoord; - -void main() { - const vec2 positions[4] = vec2[]( - vec2(-1, -1), - vec2(+1, -1), - vec2(-1, +1), - vec2(+1, +1) - ); - const vec2 coords[4] = vec2[]( - vec2(0, 0), - vec2(1, 0), - vec2(0, 1), - vec2(1, 1) - ); - - vertex_texcoord = coords[gl_VertexID]; - gl_Position = vec4(positions[gl_VertexID], 0.0, 1.0); -} diff --git a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/scene/frag.glsl b/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/scene/frag.glsl deleted file mode 100644 index 554c25d..0000000 --- a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/scene/frag.glsl +++ /dev/null @@ -1,11 +0,0 @@ -uniform sampler2D texture_data; - -void main() -{ - vec4 texel = texture(texture_data, vertex_texcoord); - if (texel.a != 1.0) { - discard; - } - - frag_color = vec4(texel.rgb, texel.a); -} diff --git a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/scene/vert.glsl b/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/scene/vert.glsl deleted file mode 100644 index c66a816..0000000 --- a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/scene/vert.glsl +++ /dev/null @@ -1,18 +0,0 @@ -in vec4 joint; -in vec4 weight; - -uniform mat4 joint_matrices[128]; - -void main() -{ - vertex_texcoord = texcoord; - vertex_normal = (normal_matrix * vec4(normal, 1.0)).xyz; - mat4 skin - = weight.x * joint_matrices[int(joint.x)] - + weight.y * joint_matrices[int(joint.y)] - + weight.z * joint_matrices[int(joint.z)] - + weight.w * joint_matrices[int(joint.w)]; - vec3 pos = (position * skin * vec4(vertex, 1.0)).xyz; - vertex_view_vector = camera_pos - pos; - gl_Position = projection * view * vec4(pos, 1.0); -} diff --git a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/test/frag.glsl b/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/test/frag.glsl deleted file mode 100644 index 954a9d2..0000000 --- a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/test/frag.glsl +++ /dev/null @@ -1,23 +0,0 @@ -// uniform int has_normal_map; -// uniform sampler2D normal_map; - -uniform sampler2D texture_data; - -void main() -{ - vec2 inverted_texcoord = vec2(vertex_texcoord.x, 1.0 - vertex_texcoord.y); - vec4 texel = texture(texture_data, inverted_texcoord); - if (texel.a != 1.0) { - discard; - } - - // mat3 tbn = compute_tbn(); - // vec3 normal = has_normal_map != 0 - // ? normalize(tbn * (texture(normal_map, inverted_texcoord).xyz * 2.0 - 1.0)) - // : normalize(vertex_normal); - vec3 normal = normalize(vertex_normal); - - vec3 lighting = compute_lighting_noshadow(normal); - - frag_color = vec4(texel.rgb * lighting, texel.a); -} diff --git a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/test/vert.glsl b/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/test/vert.glsl deleted file mode 100644 index 6e796cc..0000000 --- a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/test/vert.glsl +++ /dev/null @@ -1,4 +0,0 @@ -void main() -{ - default_main(); -} \ No newline at end of file diff --git a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/tiled/frag.glsl b/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/tiled/frag.glsl deleted file mode 100644 index 257c1b7..0000000 --- a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/tiled/frag.glsl +++ /dev/null @@ -1,12 +0,0 @@ -#version 300 es -precision highp float; - -uniform sampler2D texture_data; - -in vec2 vertex_texcoord; -out vec4 frag_color; - -void main() { - vec4 texel = texture(texture_data, vertex_texcoord); - frag_color = texel; -} diff --git a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/tiled/vert.glsl b/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/tiled/vert.glsl deleted file mode 100644 index a7567f4..0000000 --- a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/tiled/vert.glsl +++ /dev/null @@ -1,14 +0,0 @@ -#version 300 es -precision highp float; - -in vec2 vertex; -in vec2 texcoord; - -uniform mat4 transform; - -out vec2 vertex_texcoord; - -void main() { - vertex_texcoord = texcoord; - gl_Position = transform * vec4(vertex, 0.0, 1.0); -} diff --git a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/truetype/frag.glsl b/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/truetype/frag.glsl deleted file mode 100644 index d472c09..0000000 --- a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/truetype/frag.glsl +++ /dev/null @@ -1,16 +0,0 @@ -#version 300 es -precision highp float; - -uniform sampler2D texture_data; - -in vec2 vertex_texcoord; -in vec3 vertex_color; -out vec4 frag_color; - -void main() -{ - float val = texture(texture_data, vertex_texcoord).r; - if (val == 0.0) discard; - vec4 texel = vec4(vertex_color, val); - frag_color = texel; -} diff --git a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/truetype/vert.glsl b/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/truetype/vert.glsl deleted file mode 100644 index a501e0a..0000000 --- a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/truetype/vert.glsl +++ /dev/null @@ -1,17 +0,0 @@ -#version 300 es -precision highp float; - -in vec2 vertex; -in vec2 texcoord; -in vec3 color; - -uniform mat4 transform; - -out vec2 vertex_texcoord; -out vec3 vertex_color; - -void main() { - vertex_texcoord = texcoord; - vertex_color = color; - gl_Position = transform * vec4(vertex, 0.0, 1.0); -} diff --git a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/uber/frag.glsl b/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/uber/frag.glsl deleted file mode 100644 index 8e7b752..0000000 --- a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/uber/frag.glsl +++ /dev/null @@ -1,193 +0,0 @@ -uniform highp int flags; - -uniform vec3 camera_pos; -uniform float time; - -uniform vec2 sprite_offset; -uniform vec2 sprite_dims; - -uniform vec4 color; -uniform sampler2D texture_color; -uniform sampler2D texture_normal; -uniform vec3 light_ambient_color; -uniform vec3 light_dir; -uniform vec3 light_dir_color; -uniform int light_count; -uniform vec3 light_pos[5]; -uniform vec3 light_color[5]; -uniform vec2 light_attenuation[5]; - -uniform int effect_flip; -uniform float effect_flash; -uniform float effect_hueshift; -uniform float effect_huescale; - -in vec2 vertex_texcoord; -in vec3 vertex_color; -in vec3 vertex_normal; -in vec3 vertex_fragpos; -in vec4 vertex_fragpos_shadow_dir; -in vec3 vertex_view_vector; - -out vec4 frag_color; - -bool flag(int mask) { - return (flags & mask) != 0; -} - -mat3 compute_tbn() { - vec3 p = -vertex_view_vector; - vec3 normal = normalize(vertex_normal); - vec3 dpx = dFdx(p); - vec3 dpy = dFdy(p); - vec2 duvx = dFdx(vertex_texcoord); - vec2 duvy = dFdy(vertex_texcoord); - vec3 dpyperp = cross(dpy, normal); - vec3 dpxperp = cross(normal, dpx); - vec3 tangent = dpyperp * duvx.x + dpxperp * duvy.x; - vec3 bitangent = dpyperp * duvx.y + dpxperp * duvy.y; - float invmax = inversesqrt(max(dot(bitangent, bitangent), dot(bitangent, bitangent))); - float flip = flag(FLIP_TEXTURE) ? 1.0 : -1.0; - return mat3(-tangent * invmax, flip * bitangent * invmax, normal); - -} - -vec4 normal_as_color(vec3 n) { - float r = (128.0 + 127.0 * n.r) / 255.0; - float g = (128.0 + 127.0 * n.g) / 255.0; - float b = (128.0 + 127.0 * n.b) / 255.0; - return vec4(r, g, b, 1.0); -} - -vec3 dir_light(vec3 normal) { - return max(dot(normal, -normalize(light_dir)), 0.0) * light_dir_color; -} - -vec3 point_light(vec3 normal, const int idx) { - vec3 pos = light_pos[idx]; - vec3 color = light_color[idx]; - float linear = light_attenuation[idx].x; - float quadratic = light_attenuation[idx].y; - vec3 light_vector = pos - vertex_fragpos; - float distance = length(light_vector); - float attenuation = 1.0 / (1.0 + distance * linear + distance * distance * quadratic); - - float directional = max(dot(normal.xyz, normalize(light_vector)), 0.0); - vec3 directional_light = color * directional; - - vec3 view_dir = normalize(camera_pos - vertex_fragpos); - vec3 reflect_dir = reflect(-normalize(light_vector), normalize(normal.xyz)); - float specular = pow(max(dot(view_dir, reflect_dir), 0.0), 32.0); - vec3 specular_light = 0.5 * specular * color; - // return (directional_light + specular_light) * attenuation; - return directional_light * attenuation; -} - -vec3 point_light_billboard(const int idx) { - vec3 pos = light_pos[idx]; - vec3 color = light_color[idx]; - float linear = light_attenuation[idx].x; - float quadratic = light_attenuation[idx].y; - vec3 light_vector = pos - vertex_fragpos; - float distance = length(light_vector); - float attenuation = 1.0 / (1.0 + distance * linear + distance * distance * quadratic); - - return color * attenuation; -} - -vec3 rgb_to_hsl(vec3 rgb) { - vec3 ret; - float min = min(min(rgb.r, rgb.g), rgb.b); - float max = max(max(rgb.r, rgb.g), rgb.b); - float lum = (max + min) / 2.0; - ret.z = lum; - if (max == min) { - ret.x = ret.y = 0.0; - } else { - float chroma = max - min; - ret.y = chroma / (1.0 - abs(2.0 * lum - 1.0)); - if (max == rgb.r) { - ret.x = (rgb.g - rgb.b) / chroma + (rgb.g < rgb.b ? 6.0 : 0.0); - } else if (max == rgb.g) { - ret.x = (rgb.b - rgb.r) / chroma + 2.0; - } else { - ret.x = (rgb.r - rgb.g) / chroma + 4.0; - } - ret.x /= 6.0; - } - return ret; -} - -float hue_to_rgb(float p, float q, float t) { - if (t < 0.0) t += 1.0; - if (t > 1.0) t -= 1.0; - if (t < 1.0/6.0) return p + (q - p) * 6.0 * t; - if (t < 1.0/2.0) return q; - if (t < 2.0/3.0) return p + (q - p) * (2.0/3.0 - t) * 6.0; - return p; -} - -vec3 hsl_to_rgb(vec3 hsl) { - vec3 ret; - if (hsl.y == 0.0) { - ret.r = ret.g = ret.b = hsl.z; - } else { - float q = hsl.z < 0.5 ? hsl.z * (1.0 + hsl.y) : hsl.z + hsl.y - hsl.z * hsl.y; - float p = 2.0 * hsl.z - q; - ret.r = hue_to_rgb(p, q, hsl.x + 1.0/3.0); - ret.g = hue_to_rgb(p, q, hsl.x); - ret.b = hue_to_rgb(p, q, hsl.x - 1.0/3.0); - } - return ret; -} - -void main() { - float tcy = flag(FLIP_TEXTURE) ? vertex_texcoord.y : 1.0 - vertex_texcoord.y; - vec2 tc = vec2(vertex_texcoord.x, tcy); - mat3 tbn = compute_tbn(); - if (flag(EFFECTS)) { - float fbase = float(effect_flip); - float fmul = 1.0 - 2.0 * fbase; - tc = vec2(fbase + fmul * vertex_texcoord.x, tcy); - } - if (flag(SPRITE)) { - tc *= sprite_dims; - tc += sprite_offset; - } - frag_color = color; - if (flag(TEXTURE_COLOR)) { - frag_color = texture(texture_color, tc); - } - if (flag(EFFECTS)) { - vec3 hsl = rgb_to_hsl(frag_color.rgb); - hsl.x = mod(hsl.x * effect_huescale + effect_hueshift, 1.0); - vec3 p = hsl_to_rgb(hsl); - frag_color.rgb = vec3(p.r + effect_flash, p.g + effect_flash, p.b + effect_flash); - } - vec3 normal = vertex_normal; - if (flag(TEXTURE_NORMAL)) { - normal = normalize(tbn * (texture(texture_normal, tc).xyz * 2.0 - 1.0)); - } - vec3 from_ambient = vec3(1.0, 1.0, 1.0); - if (flag(LIGHT_AMBIENT)) { - from_ambient = light_ambient_color; - } - vec3 from_dir = vec3(0.0, 0.0, 0.0); - if (flag(LIGHT_DIR)) { - from_dir = dir_light(normal); - } - vec3 from_points = vec3(0.0, 0.0, 0.0); - if (flag(LIGHT_POINT)) { - for (int i = 0; i < light_count; ++i) { - vec3 pl = point_light(normal, i); - from_points += pl; - } - } - frag_color.rgb *= (from_ambient + from_dir + from_points); - if (frag_color.a == 0.0) { - discard; - } - if (flag(VERTEX_COLOR)) { - frag_color.rgb = vertex_color; - } -} diff --git a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/uber/vert.glsl b/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/uber/vert.glsl deleted file mode 100644 index bd5ac60..0000000 --- a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/assets/shaders/uber/vert.glsl +++ /dev/null @@ -1,41 +0,0 @@ -uniform highp int flags; - -in vec3 vertex; -in vec3 normal; -in vec2 texcoord; -in vec3 color; - -uniform mat4 view; -uniform mat4 position; -uniform mat4 projection; -uniform mat4 normal_matrix; -uniform mat4 lightspace_matrix; -uniform vec3 camera_pos; -uniform vec3 offset; -uniform float yskew; - -out vec2 vertex_texcoord; -out vec3 vertex_color; -out vec3 vertex_normal; -out vec3 vertex_fragpos; -out vec4 vertex_fragpos_shadow_dir; -out vec3 vertex_view_vector; - -bool flag(int mask) { - return (flags & mask) != 0; -} - -void main() { - vertex_texcoord = texcoord; - vertex_color = color; - vertex_normal = (normal_matrix * vec4(normal, 1.0)).xyz; - vec3 pos = (position * vec4(vertex, 1.0)).xyz; - vertex_fragpos = pos; - vertex_fragpos_shadow_dir = lightspace_matrix * vec4(pos, 1.0); - vertex_view_vector = camera_pos - pos; - gl_Position = projection * view * vec4(pos, 1.0); - gl_Position.xyz += offset; - if (flag(YSKEW)) { - gl_Position.y += yskew * pos.z; - } -} diff --git a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/audio.rs b/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/audio.rs deleted file mode 100644 index 431b010..0000000 --- a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/audio.rs +++ /dev/null @@ -1,341 +0,0 @@ -use std::collections::HashMap; - -use std::sync::{Arc, Mutex}; - -#[cfg(target_arch = "wasm32")] -pub struct Context { - pub audio: web_sys::AudioContext, -} - -#[cfg(target_arch = "wasm32")] -impl Context { - pub fn new() -> Self { - let audio = web_sys::AudioContext::new().expect("failed to create audio context"); - Self { audio } - } -} - -#[cfg(target_arch = "wasm32")] -pub struct AudioPlayingHandle { - node: web_sys::AudioBufferSourceNode, - gain: web_sys::GainNode, -} - -#[cfg(target_arch = "wasm32")] -impl AudioPlayingHandle { - pub fn stop(&self, _ctx: &Context) { - self.node.stop().expect("failed to stop audio"); - } - pub fn fade_out(&self, ctx: &Context, time: f32) { - self.gain - .gain() - .set_target_at_time(0.0, ctx.audio.current_time(), time as f64) - .expect("failed to fade out audio"); - self.node - .stop_with_when(ctx.audio.current_time() + time as f64 + 1.0) - .expect("failed to stop audio while fading out"); - } -} - -#[cfg(target_arch = "wasm32")] -pub struct Audio { - pub buffer: Arc>>, -} - -#[cfg(target_arch = "wasm32")] -impl Audio { - pub fn new(ctx: &Context, bytes: &[u8]) -> Self { - let sbuffer = Arc::new(Mutex::new(None)); - let sclone = sbuffer.clone(); - let ret = Audio { buffer: sclone }; - let jsp = ctx - .audio - .decode_audio_data(&js_sys::Uint8Array::from(bytes).buffer()) - .expect("failed to decode audio"); - let promise = wasm_bindgen_futures::JsFuture::from(jsp); - wasm_bindgen_futures::spawn_local(async move { - if let Some(data) = promise.await.ok() { - *sbuffer.lock().unwrap() = Some(web_sys::AudioBuffer::from(data)); - } - () - }); - ret - } - - pub fn from_samples(ctx: &Context, sample_rate: f32, samples: &[f32]) -> Self { - let buf = ctx - .audio - .create_buffer(1, samples.len() as u32, sample_rate) - .expect("failed to create audio buffer"); - buf.copy_to_channel(samples, 0) - .expect("failed to populate audio samples"); - Audio { - buffer: Arc::new(Mutex::new(Some(buf))), - } - } - - pub fn play( - &self, - ctx: &mut Context, - looping: Option<(Option, Option)>, - ) -> Option { - let source = ctx.audio.create_buffer_source().ok()?; - if let Some(ab) = &*self.buffer.lock().unwrap() { - source.set_buffer(Some(&ab)); - } else { - return None; - }; - if let Some((ms, me)) = looping { - source.set_loop(true); - if let Some(s) = ms { - source.set_loop_start(s) - } - if let Some(e) = me { - source.set_loop_end(e) - } - } - let gain = ctx.audio.create_gain().ok()?; - gain.gain() - .set_value_at_time(0.5, ctx.audio.current_time()) - .ok()?; - gain.connect_with_audio_node(&ctx.audio.destination()) - .ok()?; - source.connect_with_audio_node(&gain).ok()?; - source.start().ok()?; - Some(AudioPlayingHandle { node: source, gain }) - } -} - -#[cfg(target_arch = "wasm32")] -pub struct Assets { - pub ctx: Context, - pub audio: HashMap, - pub music_node: Option, -} - -#[cfg(target_arch = "wasm32")] -impl Assets { - pub fn new(f: F) -> Self - where - F: Fn(&Context) -> HashMap, - { - let ctx = Context::new(); - - let audio = f(&ctx); - - Self { - ctx, - audio, - music_node: None, - } - } - - pub fn play_sfx(&mut self, name: &str) { - if let Some(a) = self.audio.get(name) { - a.play(&mut self.ctx, None); - } - } - - pub fn is_music_playing(&self) -> bool { - if let Some(ms) = &self.music_node { - ms.node.buffer().is_some() - } else { - false - } - } - - pub fn play_music(&mut self, name: &str, start: Option, end: Option) { - if let Some(s) = &self.music_node { - let _ = s.stop(&self.ctx); - } - if let Some(a) = self.audio.get(name) { - self.music_node = a.play(&mut self.ctx, Some((start, end))); - } - } - - pub fn stop_music(&mut self) { - if let Some(node) = &self.music_node { - let _ = node.stop(&self.ctx); - } - self.music_node = None; - } -} - -#[cfg(not(target_arch = "wasm32"))] -pub struct Context { - manager: kira::manager::AudioManager, -} - -#[cfg(not(target_arch = "wasm32"))] -impl Context { - #[allow(clippy::new_without_default)] - pub fn new() -> Self { - Self { - manager: kira::manager::AudioManager::new( - kira::manager::AudioManagerSettings::default(), - ) - .expect("failed to create audio manager"), - } - } -} - -#[cfg(not(target_arch = "wasm32"))] -pub struct AudioPlayingHandle { - handle: Arc>, -} - -#[cfg(not(target_arch = "wasm32"))] -impl AudioPlayingHandle { - pub fn stop(&self, _ctx: &Context) { - self.handle - .lock() - .unwrap() - .stop(kira::tween::Tween::default()); - } - pub fn fade_out(&self, _ctx: &Context, time: f32) { - self.handle.lock().unwrap().stop(kira::tween::Tween { - duration: std::time::Duration::from_secs_f32(time + 0.5), - ..Default::default() - }); - } -} - -#[cfg(not(target_arch = "wasm32"))] -pub struct Audio { - data: kira::sound::static_sound::StaticSoundData, -} - -#[cfg(not(target_arch = "wasm32"))] -impl Audio { - pub fn new(_ctx: &Context, bytes: &[u8]) -> Self { - Self { - data: kira::sound::static_sound::StaticSoundData::from_cursor(std::io::Cursor::new( - bytes.to_owned(), - )) - .expect("failed to decode audio"), - } - } - - pub fn from_samples(_ctx: &Context, sample_rate: f32, samples: &[f32]) -> Self { - let frames: Vec = samples - .iter() - .map(|f| kira::Frame { - left: *f, - right: *f, - }) - .collect(); - Self { - data: kira::sound::static_sound::StaticSoundData { - sample_rate: sample_rate as u32, - frames: frames.into(), - settings: kira::sound::static_sound::StaticSoundSettings::default(), - slice: None, - }, - } - } - - pub fn play( - &self, - ctx: &mut Context, - looping: Option<(Option, Option)>, - ) -> Option { - let sd = if let Some((ss, se)) = looping { - let start = ss.unwrap_or(0.0); - if let Some(e) = se { - self.data.loop_region(start..e) - } else { - self.data.loop_region(start..) - } - } else { - self.data.clone() - }; - ctx.manager.play(sd).ok().map(|h| AudioPlayingHandle { - handle: Arc::new(Mutex::new(h)), - }) - } -} - -#[cfg(not(target_arch = "wasm32"))] -pub struct Assets { - pub ctx: Context, - pub audio: HashMap, - pub music_handle: Option, -} - -#[cfg(not(target_arch = "wasm32"))] -impl Assets { - pub fn new(f: F) -> Self - where - F: Fn(&Context) -> HashMap, - { - let ctx = Context::new(); - let audio = f(&ctx); - Self { - ctx, - audio, - music_handle: None, - } - } - - pub fn play_sfx(&mut self, name: &str) { - if let Some(a) = self.audio.get(name) { - if a.play(&mut self.ctx, None).is_none() { - log::warn!("failed to play sound {}", name); - } - } - } - - pub fn is_music_playing(&self) -> bool { - if let Some(mh) = &self.music_handle { - mh.handle.lock().unwrap().state() == kira::sound::PlaybackState::Playing - } else { - false - } - } - - pub fn play_music(&mut self, name: &str, start: Option, end: Option) { - if let Some(s) = &mut self.music_handle { - s.stop(&self.ctx); - } - if let Some(a) = self.audio.get(name) { - match a.play(&mut self.ctx, Some((start, end))) { - Some(h) => { - self.music_handle = Some(h); - } - _ => { - log::warn!("failed to play music {}", name); - } - } - } - } - - pub fn stop_music(&mut self) { - if let Some(h) = &mut self.music_handle { - h.stop(&self.ctx); - } - self.music_handle = None; - } -} - -pub trait AudioPlayback { - fn play_sfx(&mut self, name: &str); - fn play_music(&mut self, name: &str, start: Option, end: Option); - fn stop_music(&mut self); -} -impl AudioPlayback for Option { - fn play_sfx(&mut self, name: &str) { - if let Some(a) = self { - a.play_sfx(name); - } - } - fn play_music(&mut self, name: &str, start: Option, end: Option) { - if let Some(a) = self { - a.play_music(name, start, end); - } - } - fn stop_music(&mut self) { - if let Some(a) = self { - a.stop_music(); - } - } -} diff --git a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/context.rs b/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/context.rs deleted file mode 100644 index 34e0ad3..0000000 --- a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/context.rs +++ /dev/null @@ -1,302 +0,0 @@ -use crate::Options; - -use glow::HasContext; - -#[cfg(not(target_arch = "wasm32"))] -use glfw::Context as _; - -#[cfg(target_arch = "wasm32")] -use wasm_bindgen::prelude::*; - -#[cfg(target_arch = "wasm32")] -use winit::platform::web::WindowExtWebSys; - -#[cfg(target_arch = "wasm32")] -#[wasm_bindgen(module = "/src/helpers.js")] -extern { - fn js_track_resized_setup(); - fn js_poll_resized() -> bool; - fn js_bundt_api_server() -> String; - fn js_bundt_secure_api_server() -> String; -} - -#[cfg(not(target_arch = "wasm32"))] -pub struct Context { - pub render_width: f32, - pub render_height: f32, - pub options: Options, - pub glfw: std::cell::RefCell, - pub window: std::cell::RefCell, - pub gl: glow::Context, - pub emptyvao: glow::VertexArray, - pub start_instant: std::time::Instant, -} - - -#[cfg(target_arch = "wasm32")] -pub struct Context { - pub render_width: f32, - pub render_height: f32, - pub options: Options, - pub window: winit::window::Window, - pub gl: glow::Context, - pub emptyvao: glow::VertexArray, - pub performance: web_sys::Performance, -} - -impl Context { - pub fn compute_upscale(&self, windoww: u32, windowh: u32) -> u32 { - let mut ratio = 1; - loop { - if (self.render_width as u32) * ratio > windoww - || (self.render_height as u32) * ratio > windowh - { - break; - } - ratio += 1; - } - (ratio - 1).max(1) - } - - #[cfg(not(target_arch = "wasm32"))] - pub fn new(glfw: std::cell::RefCell, window: std::cell::RefCell, gl: glow::Context, render_width: f32, render_height: f32, options: Options) -> Self { - let emptyvao = unsafe { - gl.create_vertex_array().expect("failed to initialize vao") - }; - let ret = Self { - render_width, render_height, - options, - glfw, window, - gl, - emptyvao, - start_instant: std::time::Instant::now(), - }; - ret.init(); - ret - } - - #[cfg(target_arch = "wasm32")] - pub fn new(window: winit::window::Window, gl: glow::Context, render_width: f32, render_height: f32, options: Options) -> Self { - let emptyvao = unsafe { - gl.create_vertex_array().expect("failed to initialize vao") - }; - - #[cfg(target_arch = "wasm32")] - js_track_resized_setup(); - - let ret = Self { - render_width, render_height, - options, - window, - gl, - emptyvao, - - #[cfg(target_arch = "wasm32")] - performance: web_sys::window().expect("failed to find window") - .performance().expect("failed to get performance"), - }; - ret.init(); - ret - } - - pub fn init(&self) { - unsafe { - self.gl.clear_color(0.1, 0.1, 0.1, 1.0); - self.gl.clear_depth_f32(1.0); - - #[cfg(all(debug_assertions, not(target_arch = "wasm32")))] - self.gl.enable(glow::DEBUG_OUTPUT); - - self.gl.enable(glow::DEPTH_TEST); - self.gl.depth_func(glow::LEQUAL); - - self.gl.enable(glow::BLEND); - self.gl.blend_func(glow::SRC_ALPHA, glow::ONE_MINUS_SRC_ALPHA); - - self.gl.enable(glow::STENCIL_TEST); - - self.gl.cull_face(glow::FRONT); - } - } - - #[cfg(target_arch = "wasm32")] - pub fn maximize_canvas(&self) { - if !self.options.contains(Options::NORESIZE) { - web_sys::window() - .and_then(|win| win.document()) - .and_then(|doc| { - let inner_size = { - let browser_window = doc.default_view() - .or_else(web_sys::window) - .unwrap(); - winit::dpi::PhysicalSize::new( - browser_window.inner_width().unwrap().as_f64().unwrap(), - browser_window.inner_height().unwrap().as_f64().unwrap(), - ) - }; - self.window.canvas().unwrap().set_width(inner_size.width as _); - self.window.canvas().unwrap().set_height(inner_size.height as _); - let _ = self.window.request_inner_size(inner_size); - Some(()) - }) - .expect("failed to resize canvas"); - } - } - - #[cfg(target_arch = "wasm32")] - pub fn resize_necessary(&self) -> bool { js_poll_resized() } - #[cfg(not(target_arch = "wasm32"))] - pub fn resize_necessary(&self) -> bool { false } - - #[cfg(target_arch = "wasm32")] - pub fn bundt_api_server(&self) -> String { js_bundt_api_server() } - #[cfg(all(not(target_arch = "wasm32"), debug_assertions))] - pub fn bundt_api_server(&self) -> String { "http://localhost:8000/api".to_owned() } - #[cfg(all(not(target_arch = "wasm32"), not(debug_assertions)))] - pub fn bundt_api_server(&self) -> String { "https://api.colonq.computer/api".to_owned() } - - #[cfg(target_arch = "wasm32")] - pub fn bundt_secure_api_server(&self) -> String { js_bundt_secure_api_server() } - #[cfg(all(not(target_arch = "wasm32"), debug_assertions))] - pub fn bundt_secure_api_server(&self) -> String { "http://localhost:8000/api".to_owned() } - #[cfg(all(not(target_arch = "wasm32"), not(debug_assertions)))] - pub fn bundt_secure_api_server(&self) -> String { "https://secure.colonq.computer/api".to_owned() } - - pub fn clear_color(&self, color: glam::Vec4) { - unsafe { - self.gl.clear_color(color.x, color.y, color.z, color.w); - } - } - - pub fn clear_depth(&self) { - unsafe { - self.gl.clear(glow::DEPTH_BUFFER_BIT); - } - } - - pub fn clear(&self) { - unsafe { - self.gl.stencil_mask(0xff); - self.gl.clear(glow::COLOR_BUFFER_BIT | glow::DEPTH_BUFFER_BIT | glow::STENCIL_BUFFER_BIT); - } - } - - pub fn depth_mask(&self, m: bool) { - unsafe { - self.gl.depth_mask(m); - } - } - - pub fn begin_stencil(&self) { - unsafe { - self.gl.stencil_func(glow::ALWAYS, 1, 0xff); - self.gl.stencil_op(glow::KEEP, glow::KEEP, glow::REPLACE); - } - } - - pub fn use_stencil(&self) { - unsafe { - self.gl.stencil_func(glow::EQUAL, 1, 0xff); - self.gl.stencil_op(glow::KEEP, glow::KEEP, glow::KEEP); - } - } - - pub fn write_and_use_stencil(&self) { - unsafe { - self.gl.stencil_func(glow::EQUAL, 1, 0xff); - self.gl.stencil_op(glow::KEEP, glow::KEEP, glow::REPLACE); - } - } - - pub fn use_inverse_stencil(&self) { - unsafe { - self.gl.stencil_func(glow::NOTEQUAL, 1, 0xff); - self.gl.stencil_op(glow::KEEP, glow::KEEP, glow::KEEP); - } - } - - pub fn write_and_use_inverse_stencil(&self) { - unsafe { - self.gl.stencil_func(glow::NOTEQUAL, 1, 0xff); - self.gl.stencil_op(glow::KEEP, glow::KEEP, glow::REPLACE); - } - } - - pub fn end_stencil(&self) { - unsafe { - self.gl.stencil_func(glow::ALWAYS, 1, 0xff); - self.gl.stencil_op(glow::KEEP, glow::KEEP, glow::KEEP); - } - } - - pub fn render_no_geometry(&self) { - unsafe { - self.gl.bind_vertex_array(Some(self.emptyvao)); - self.gl.draw_arrays(glow::TRIANGLE_STRIP, 0, 4); - } - } - - pub fn reset_blend(&self) { - unsafe { - self.gl.blend_func(glow::SRC_ALPHA, glow::ONE_MINUS_SRC_ALPHA); - } - } - - pub fn inverse_blend(&self) { - unsafe { - self.gl.blend_func( - glow::ONE_MINUS_DST_COLOR, - glow::ZERO, - ); - } - } - - pub fn flip_colors_blend(&self) { - unsafe { - self.gl.blend_func_separate( - glow::ONE_MINUS_DST_COLOR, - glow::ZERO, - glow::ZERO, - glow::ONE, - ); - } - } - - pub fn enable_culling(&self) { - unsafe { - self.gl.enable(glow::CULL_FACE); - } - } - - pub fn disable_culling(&self) { - unsafe { - self.gl.disable(glow::CULL_FACE); - } - } - - #[cfg(target_arch = "wasm32")] - pub fn lock_mouse(&self) { - let _ = self.window.set_cursor_grab(winit::window::CursorGrabMode::Locked); - self.window.set_cursor_visible(false); - } - - #[cfg(not(target_arch = "wasm32"))] - pub fn lock_mouse(&self) { - unsafe { - glfw::ffi::glfwSetInputMode( - self.window.borrow_mut().window_ptr(), - glfw::ffi::CURSOR, - glfw::ffi::CURSOR_DISABLED, - ); - } - } - - pub fn check_error(&self) { - unsafe { - let err = self.gl.get_error(); - if err != 0 { - log::warn!("gl error: {}", err); - } - } - } -} diff --git a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/font.rs b/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/font.rs deleted file mode 100644 index 648bb47..0000000 --- a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/font.rs +++ /dev/null @@ -1,194 +0,0 @@ -use crate::{context, mesh, state, texture}; -use glow::HasContext; - -pub struct BitmapParams<'color> { - pub color: &'color [glam::Vec3], - pub scale: glam::Vec2, - pub offset: glam::Vec2, -} -impl<'color> Default for BitmapParams<'color> { - fn default() -> Self { - Self { - color: &[], - scale: glam::Vec2::ONE, - offset: glam::Vec2::ZERO, - } - } -} -pub struct Bitmap { - pub char_width: i32, - pub char_height: i32, - pub font_width: i32, - pub font_height: i32, - pub font: texture::Texture, - pub vao: glow::VertexArray, - pub vertex_buf: glow::Buffer, - pub texcoords_buf: glow::Buffer, - pub colors_buf: glow::Buffer, - pub index_buf: glow::Buffer, -} - -impl Bitmap { - pub fn from_image( - ctx: &context::Context, - char_width: i32, char_height: i32, - font_width: i32, font_height: i32, - data: &[u8], - ) -> Self { - let font = texture::Texture::new(ctx, data); - unsafe { - let vao = ctx.gl.create_vertex_array().expect("failed to initialize vao"); - ctx.gl.bind_vertex_array(Some(vao)); - let vertex_buf = ctx.gl.create_buffer().expect("failed to create buffer object"); - ctx.gl.bind_buffer(glow::ARRAY_BUFFER, Some(vertex_buf)); - ctx.gl.vertex_attrib_pointer_f32(mesh::ATTRIB_VERTEX, 2, glow::FLOAT, false, 0, 0); - ctx.gl.enable_vertex_attrib_array(mesh::ATTRIB_VERTEX); - let texcoords_buf = ctx.gl.create_buffer().expect("failed to create buffer object"); - ctx.gl.bind_buffer(glow::ARRAY_BUFFER, Some(texcoords_buf)); - ctx.gl.vertex_attrib_pointer_f32(mesh::ATTRIB_TEXCOORD, 2, glow::FLOAT, false, 0, 0); - ctx.gl.enable_vertex_attrib_array(mesh::ATTRIB_TEXCOORD); - let colors_buf = ctx.gl.create_buffer().expect("failed to create buffer object"); - ctx.gl.bind_buffer(glow::ARRAY_BUFFER, Some(colors_buf)); - ctx.gl.vertex_attrib_pointer_f32(mesh::ATTRIB_COLOR, 3, glow::FLOAT, false, 0, 0); - ctx.gl.enable_vertex_attrib_array(mesh::ATTRIB_COLOR); - let index_buf = ctx.gl.create_buffer().expect("failed to create buffer object"); - ctx.gl.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, Some(index_buf)); - Self { - char_width, char_height, - font_width, font_height, - font, - vao, - vertex_buf, - texcoords_buf, - colors_buf, - index_buf, - } - } - } - - pub fn default(ctx: &context::Context) -> Self { - Self::from_image(ctx, 7, 9, 112, 54, include_bytes!("assets/fonts/default.png")) - } - - pub fn small(ctx: &context::Context) -> Self { - Self::from_image(ctx, 6, 7, 96, 42, include_bytes!("assets/fonts/small.png")) - } - - pub fn render_text_parameterized(&self, - ctx: &context::Context, _st: &state::State, - text: &str, - params: BitmapParams, - ) { - let mut cur = params.offset; - let mut vertices = Vec::new(); - let mut texcoords = Vec::new(); - let mut colors = Vec::new(); - let mut indices = Vec::new(); - let cwidth = self.char_width as f32 / self.font_width as f32; - let cheight = self.char_height as f32 / self.font_height as f32; - let sdims = glam::Vec2::new(2.0, 2.0) * params.scale; - let row_len = self.font_width as u32 / self.char_width as u32; - for (i, c) in text.chars().enumerate() { - if c == '\n' { - cur.x = 0.0; - cur.y -= sdims.y; - } else { - let idx = vertices.len() as u32; - vertices.push(cur); - vertices.push(cur + glam::Vec2::new(sdims.x, 0.0)); - vertices.push(cur + glam::Vec2::new(sdims.x, sdims.y)); - vertices.push(cur + glam::Vec2::new(0.0, sdims.y)); - let cidx = c as u32 - ' ' as u32; - let col = cidx % row_len; - let row = cidx / row_len; - let tcbase = glam::Vec2::new(col as f32 * cwidth, row as f32 * cheight); - texcoords.push(tcbase + glam::Vec2::new(0.0, cheight)); - 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) = params.color.get(if params.color.is_empty() { 0 } else { i % params.color.len() }) { - *c - } else { - glam::Vec3::new(1.0, 1.0, 1.0) - }; - colors.push(c); colors.push(c); colors.push(c); colors.push(c); - indices.push(idx); indices.push(idx + 1); indices.push(idx + 2); - indices.push(idx); indices.push(idx + 3); indices.push(idx + 2); - cur.x += sdims.x; - } - } - let index_bytes: Vec = indices.iter().flat_map(|x| x.to_ne_bytes()).collect(); - self.font.bind(ctx); - unsafe { - ctx.gl.bind_vertex_array(Some(self.vao)); - ctx.gl.bind_buffer(glow::ARRAY_BUFFER, Some(self.vertex_buf)); - ctx.gl.buffer_data_u8_slice( - glow::ARRAY_BUFFER, - std::slice::from_raw_parts( - vertices.as_ptr() as _, - vertices.len() * std::mem::size_of::() * 2, - ), - glow::STATIC_DRAW, - ); - ctx.gl.bind_buffer(glow::ARRAY_BUFFER, Some(self.texcoords_buf)); - ctx.gl.buffer_data_u8_slice( - glow::ARRAY_BUFFER, - std::slice::from_raw_parts( - texcoords.as_ptr() as _, - texcoords.len() * std::mem::size_of::() * 2, - ), - glow::STATIC_DRAW, - ); - ctx.gl.bind_buffer(glow::ARRAY_BUFFER, Some(self.colors_buf)); - ctx.gl.buffer_data_u8_slice( - glow::ARRAY_BUFFER, - std::slice::from_raw_parts( - colors.as_ptr() as _, - colors.len() * std::mem::size_of::() * 3, - ), - glow::STATIC_DRAW, - ); - ctx.gl.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, Some(self.index_buf)); - ctx.gl.buffer_data_u8_slice( - glow::ELEMENT_ARRAY_BUFFER, - &index_bytes, - glow::STATIC_DRAW, - ); - ctx.gl.draw_elements(glow::TRIANGLES, indices.len() as _, glow::UNSIGNED_INT, 0); - } - } - - pub fn render_text_helper(&self, - ctx: &context::Context, st: &state::State, - text: &str, color: &[glam::Vec3] - ) { - self.render_text_parameterized( - ctx, st, - text, - BitmapParams { - color, - scale: glam::Vec2::ONE, - offset: glam::Vec2::ZERO, - } - ) - } - - pub fn render_text(&self, - ctx: &context::Context, st: &state::State, - text: &str - ) { - self.render_text_helper(ctx, st, text, &[]); - } - - pub fn render_text_at(&self, - ctx: &context::Context, st: &mut state::State, - pos: glam::Vec2, text: &str, - params: BitmapParams, - ) { - st.bind_2d(ctx, &st.shader_text_bitmap); - let dims = glam::Vec2::new(self.char_width as f32, self.char_height as f32); - let fpos = pos + glam::Vec2::new(-dims.x / 2.0, dims.y / 2.0); - st.shader_text_bitmap.set_position_text_bitmap(ctx, st, self, &fpos); - self.render_text_parameterized(ctx, st, text, params); - } -} diff --git a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/framebuffer.rs b/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/framebuffer.rs deleted file mode 100644 index 606fd6a..0000000 --- a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/framebuffer.rs +++ /dev/null @@ -1,158 +0,0 @@ -use glow::HasContext; - -use crate::context; - -#[cfg(target_arch = "wasm32")] -use crate::Options; - -pub struct Framebuffer { - pub tex: Option, - pub fbo: Option, - pub dims: glam::Vec2, - pub offsets: glam::Vec2, -} - -impl Framebuffer { - pub fn screen(ctx: &context::Context) -> Self { - #[cfg(target_arch = "wasm32")] - let (windoww, windowh): (f32, f32) = if !ctx.options.contains(Options::NORESIZE) { - ctx.window.inner_size().into() - } else { - (ctx.render_width, ctx.render_height) - }; - #[cfg(not(target_arch = "wasm32"))] - let (windoww, windowh) = { - let (w, h) = ctx.window.borrow().get_size(); - (w as f32, h as f32) - }; - let ratio = ctx.compute_upscale(windoww as _, windowh as _) as f32; - let upscalew = ctx.render_width * ratio; - let upscaleh = ctx.render_height * ratio; - let offsetx = (windoww - upscalew) / 2.0; - let offsety = (windowh - upscaleh) / 2.0; - log::info!("resize window: {:?}, upscale: {:?}, offset: {:?}", (windoww, windowh), (upscalew, upscaleh), (offsetx, offsety)); - Self { - tex: None, - fbo: None, - dims: glam::Vec2::new(upscalew, upscaleh), - offsets: glam::Vec2::new(offsetx, offsety), - } - } - - pub fn new(ctx: &context::Context, dims: &glam::Vec2, offsets: &glam::Vec2) -> Self { - unsafe { - let fbo = ctx.gl.create_framebuffer() - .expect("failed to create framebuffer"); - ctx.gl.bind_framebuffer(glow::FRAMEBUFFER, Some(fbo)); - - let depth_buffer = ctx.gl.create_renderbuffer() - .expect("failed to create depth buffer"); - ctx.gl.bind_renderbuffer(glow::RENDERBUFFER, Some(depth_buffer)); - ctx.gl.renderbuffer_storage(glow::RENDERBUFFER, glow::DEPTH_COMPONENT32F, dims.x as _, dims.y as _); - ctx.gl.framebuffer_renderbuffer(glow::FRAMEBUFFER, glow::DEPTH_ATTACHMENT, glow::RENDERBUFFER, Some(depth_buffer)); - - let stencil_buffer = ctx.gl.create_renderbuffer() - .expect("failed to create stencil buffer"); - ctx.gl.bind_renderbuffer(glow::RENDERBUFFER, Some(stencil_buffer)); - ctx.gl.renderbuffer_storage(glow::RENDERBUFFER, glow::DEPTH_STENCIL, dims.x as _, dims.y as _); - ctx.gl.framebuffer_renderbuffer(glow::FRAMEBUFFER, glow::DEPTH_STENCIL_ATTACHMENT, glow::RENDERBUFFER, Some(stencil_buffer)); - - let tex = ctx.gl.create_texture() - .expect("failed to create framebuffer texture"); - ctx.gl.bind_texture(glow::TEXTURE_2D, Some(tex)); - ctx.gl.tex_image_2d( - glow::TEXTURE_2D, - 0, - glow::RGBA as _, - dims.x as _, - dims.y as _, - 0, - glow::RGBA, - glow::UNSIGNED_BYTE, - None, - ); - ctx.gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_WRAP_S, glow::CLAMP_TO_EDGE as _); - ctx.gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_WRAP_T, glow::CLAMP_TO_EDGE as _); - ctx.gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_MIN_FILTER, glow::NEAREST as _); - ctx.gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_MAG_FILTER, glow::NEAREST as _); - ctx.gl.framebuffer_texture_2d(glow::FRAMEBUFFER, glow::COLOR_ATTACHMENT0, glow::TEXTURE_2D, Some(tex), 0); - ctx.gl.draw_buffer(glow::COLOR_ATTACHMENT0); - - let status = ctx.gl.check_framebuffer_status(glow::FRAMEBUFFER); - if status != glow::FRAMEBUFFER_COMPLETE { - panic!("error initializing framebuffer:\n{}", status); - } - - Self { - tex: Some(tex), - fbo: Some(fbo), - dims: *dims, - offsets: *offsets, - } - } - } - - pub fn bind_texture(&self, ctx: &context::Context) { - unsafe { - ctx.gl.active_texture(glow::TEXTURE0); - ctx.gl.bind_texture(glow::TEXTURE_2D, self.tex); - } - } - - pub fn bind(&self, ctx: &context::Context) { - unsafe { - ctx.gl.bind_framebuffer(glow::FRAMEBUFFER, self.fbo); - ctx.gl.viewport( - self.offsets.x as _, - self.offsets.y as _, - self.dims.x as _, - self.dims.y as _, - ); - } - } - - pub fn blit(&self, ctx: &context::Context, dest: &Self, pos: &glam::Vec2, scale: &glam::Vec2) { - unsafe { - ctx.gl.bind_framebuffer(glow::READ_FRAMEBUFFER, self.fbo); - ctx.gl.bind_framebuffer(glow::DRAW_FRAMEBUFFER, dest.fbo); - ctx.gl.blit_framebuffer( - 0, 0, self.dims.x as _, self.dims.y as _, - pos.x as _, pos.y as _, (pos.x + scale.x) as _, (pos.y + scale.y) as _, - glow::COLOR_BUFFER_BIT, glow::NEAREST - ); - } - } - - pub fn get_pixels(&self, ctx: &context::Context, buf: &mut [glam::Vec3]) { - let w = self.dims.x as usize; - let h = self.dims.y as usize; - let tmp = vec![glam::Vec3::default(); w * h]; - unsafe { - ctx.gl.bind_texture(glow::TEXTURE_2D, self.tex); - ctx.gl.get_tex_image( - glow::TEXTURE_2D, 0, glow::RGB, glow::FLOAT, - glow::PixelPackData::Slice( - std::slice::from_raw_parts_mut( - tmp.as_ptr() as *mut u8, - tmp.len() * std::mem::size_of::() - ) - ), - ); - } - for y in 0..h { - for x in 0..w { - buf[x + (h - 1 - y) * w] = tmp[x + y * w]; - } - } - } - - pub fn get_pixels_raw(&self, ctx: &context::Context, buf: &mut [u8]) { - unsafe { - ctx.gl.bind_texture(glow::TEXTURE_2D, self.tex); - ctx.gl.get_tex_image( - glow::TEXTURE_2D, 0, glow::RGBA, glow::UNSIGNED_BYTE, - glow::PixelPackData::Slice(buf), - ); - } - } -} diff --git a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/helpers.js b/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/helpers.js deleted file mode 100644 index d1b74b6..0000000 --- a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/helpers.js +++ /dev/null @@ -1,21 +0,0 @@ -let resized = false; - -export async function js_track_resized_setup() { - window.addEventListener("resize", () => { - resized = true; - }); -} - -export function js_poll_resized() { - let ret = resized; - resized = false; - return ret; -} - -export function js_bundt_api_server() { - return globalThis.apiServer || "http://localhost:8000/api"; -} - -export function js_bundt_secure_api_server() { - return globalThis.secureApiServer || "http://localhost:8000/api"; -} diff --git a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/js/module.js b/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/js/module.js deleted file mode 100644 index 03d0047..0000000 --- a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/js/module.js +++ /dev/null @@ -1,7 +0,0 @@ -export function js_build_interface() { - return { - env: { - log_info: window.wasmBindings.log_info, - }, - }; -} diff --git a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/level2d.rs b/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/level2d.rs deleted file mode 100644 index b64213a..0000000 --- a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/level2d.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod tiled; diff --git a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/level2d/tiled.rs b/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/level2d/tiled.rs deleted file mode 100644 index 2e8141e..0000000 --- a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/level2d/tiled.rs +++ /dev/null @@ -1,301 +0,0 @@ -#![allow(dead_code)] - -use std::collections::HashMap; -use serde::Deserialize; -use glow::HasContext; - -use crate::{context, erm, mesh, shader, texture, Erm}; - -#[derive(Debug)] -pub enum Err { - LayerIndexOutOfBounds, - LayerDataTooSmall, - GIDNotFound(u32), - AssetNotFound(String), - GL(String), -} -impl std::error::Error for Err {} -impl std::fmt::Display for Err { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - Self::LayerIndexOutOfBounds => write!(f, "layer index out of bounds"), - Self::LayerDataTooSmall => write!(f, "layer data too small for dimensions"), - Self::GIDNotFound(gid) => write!(f, "GID not found: {}", gid), - Self::AssetNotFound(ass) => write!(f, "asset not found: {}", ass), - Self::GL(msg) => write!(f, "GL error: {msg:}"), - } - } -} - -#[derive(Debug, Deserialize)] -pub enum LayerType { - #[serde(rename = "tilelayer")] - Tile, - #[serde(rename = "imagelayer")] - Image, - #[serde(rename = "objectgroup")] - ObjectGroup, - #[serde(rename = "group")] - Group, -} - -#[derive(Debug, Deserialize)] -pub struct Layer { - name: String, - id: i32, - #[serde(rename = "type")] ty: LayerType, - width: i32, height: i32, - x: i32, y: i32, - opacity: f32, - visible: bool, - data: Vec, -} - -#[derive(Debug, Deserialize)] -pub struct LevelTileset { - firstgid: i32, - source: String, -} - -#[derive(Debug, Deserialize)] -pub struct Level { - width: i32, height: i32, - tilewidth: i32, tileheight: i32, - layers: Vec, - tilesets: Vec, -} -impl Level { - pub fn new(bytes: &str) -> Erm { - Ok(serde_json::from_str(bytes)?) - } -} - -#[derive(Debug, Deserialize)] -pub struct Tileset { - name: String, - imagewidth: i32, imageheight: i32, - tilewidth: i32, tileheight: i32, - margin: i32, spacing: i32, -} -impl Tileset { - pub fn new(bytes: &str) -> Erm { - Ok(serde_json::from_str(bytes)?) - } -} - -// TODO -pub enum Flip { - None, -} - -pub struct Asset { - tileset: Tileset, - texture: texture::Texture, -} -#[derive(Default)] -pub struct Assets { - entries: HashMap, -} -impl Assets { - pub fn new() -> Self { Self::default() } - pub fn load(&mut self, ctx: &context::Context, nm: &str, ts: &str, img: &[u8]) -> Erm<()> { - let ass = Asset { - tileset: Tileset::new(ts)?, - texture: texture::Texture::new(ctx, img), - }; - if self.entries.insert(nm.to_string(), ass).is_some() { - log::warn!("duplicate tileset entry named: {}", nm); - } - Ok(()) - } - pub fn lookup_gid(&self, level: &Level, gid: u32) -> Erm<(i32, &Asset, Flip)> { - let offset = (gid & 0x0fffffff) as i32; - for lts in level.tilesets.iter().rev() { - if lts.firstgid <= offset { - return Ok(( - offset - lts.firstgid, - self.entries.get(<s.source).ok_or(Err::AssetNotFound(lts.source.clone()))?, - Flip::None - )) - } - } - erm(Err::GIDNotFound(gid)) - } -} - -pub struct LayerRenderer { - pub vao: glow::VertexArray, - pub vertex_buf: glow::Buffer, - pub texcoords_buf: glow::Buffer, - pub index_buf: glow::Buffer, - pub index_count: usize, -} -impl LayerRenderer { - pub fn new(ctx: &context::Context) -> Erm { - unsafe { - let vao = ctx.gl.create_vertex_array().map_err(Err::GL)?; - ctx.gl.bind_vertex_array(Some(vao)); - let vertex_buf = ctx.gl.create_buffer().map_err(Err::GL)?; - ctx.gl.bind_buffer(glow::ARRAY_BUFFER, Some(vertex_buf)); - ctx.gl.vertex_attrib_pointer_f32(mesh::ATTRIB_VERTEX, 2, glow::FLOAT, false, 0, 0); - ctx.gl.enable_vertex_attrib_array(mesh::ATTRIB_VERTEX); - let texcoords_buf = ctx.gl.create_buffer().map_err(Err::GL)?; - ctx.gl.bind_buffer(glow::ARRAY_BUFFER, Some(texcoords_buf)); - ctx.gl.vertex_attrib_pointer_f32(mesh::ATTRIB_TEXCOORD, 2, glow::FLOAT, false, 0, 0); - ctx.gl.enable_vertex_attrib_array(mesh::ATTRIB_TEXCOORD); - let index_buf = ctx.gl.create_buffer().map_err(Err::GL)?; - ctx.gl.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, Some(index_buf)); - Ok(Self { - vao, - vertex_buf, - texcoords_buf, - index_buf, - index_count: 0, - }) - } - } -} -pub struct LevelRenderer { - pub layers: Vec, - pub shader: shader::Shader, -} -impl LevelRenderer { - pub fn new(ctx: &context::Context, level: &Level) -> Erm { - let mut layers = Vec::new(); - for _ in level.layers.iter() { - layers.push(LayerRenderer::new(ctx)?); - } - let shader = shader::Shader::new_nolib( - ctx, - include_str!("../assets/shaders/tiled/vert.glsl"), - include_str!("../assets/shaders/tiled/frag.glsl"), - ); - Ok(Self { - layers, - shader, - }) - } - pub fn populate_layer( - &mut self, - ctx: &context::Context, - assets: &Assets, - level: &Level, - lidx: usize - ) -> Erm<()> { - let lr = self.layers.get_mut(lidx).ok_or(Err::LayerIndexOutOfBounds)?; - let layer = level.layers.get(lidx).ok_or(Err::LayerIndexOutOfBounds)?; - let mut vertices = Vec::new(); - let mut texcoords = Vec::new(); - let mut indices = Vec::new(); - for y in 0..layer.height { - for x in 0..layer.width { - let idx = x as usize + (y * layer.width) as usize; - let gid = *layer.data.get(idx).ok_or(Err::LayerDataTooSmall)?; - if gid == 0 { continue; } - let (lid, ass, _) = assets.lookup_gid(level, gid)?; - let cols = ass.tileset.imagewidth / ass.tileset.tilewidth; - let rows = ass.tileset.imageheight / ass.tileset.tileheight; - let col = lid % cols; - let row = lid / cols; - let twidth = 1.0 / cols as f32; - let theight = 1.0 / rows as f32; - - let i = vertices.len() as u32; - let v = glam::Vec2::new(x as _, y as _); - vertices.push(v); - vertices.push(v + glam::Vec2::new(1.0, 0.0)); - vertices.push(v + glam::Vec2::new(1.0, 1.0)); - vertices.push(v + glam::Vec2::new(0.0, 1.0)); - let uvbase = glam::Vec2::new(col as f32 / cols as f32, row as f32 / rows as f32); - texcoords.push(uvbase + glam::Vec2::new(0.0, theight)); - texcoords.push(uvbase + glam::Vec2::new(twidth, theight)); - texcoords.push(uvbase + glam::Vec2::new(twidth, 0.0)); - texcoords.push(uvbase); - indices.push(i); indices.push(i + 1); indices.push(i + 2); - indices.push(i); indices.push(i + 3); indices.push(i + 2); - } - } - let index_bytes: Vec = indices.iter().flat_map(|x| x.to_ne_bytes()).collect(); - unsafe { - ctx.gl.bind_vertex_array(Some(lr.vao)); - ctx.gl.bind_buffer(glow::ARRAY_BUFFER, Some(lr.vertex_buf)); - ctx.gl.buffer_data_u8_slice( - glow::ARRAY_BUFFER, - std::slice::from_raw_parts( - vertices.as_ptr() as _, - vertices.len() * std::mem::size_of::() * 2, - ), - glow::STATIC_DRAW, - ); - ctx.gl.bind_buffer(glow::ARRAY_BUFFER, Some(lr.texcoords_buf)); - ctx.gl.buffer_data_u8_slice( - glow::ARRAY_BUFFER, - std::slice::from_raw_parts( - texcoords.as_ptr() as _, - texcoords.len() * std::mem::size_of::() * 2, - ), - glow::STATIC_DRAW, - ); - ctx.gl.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, Some(lr.index_buf)); - ctx.gl.buffer_data_u8_slice( - glow::ELEMENT_ARRAY_BUFFER, - &index_bytes, - glow::STATIC_DRAW, - ); - lr.index_count = indices.len(); - } - Ok(()) - } - pub fn render_layer( - &self, - ctx: &context::Context, - assets: &Assets, - level: &Level, - lidx: usize, - ) -> Erm<()> { - let layer = level.layers.get(lidx).ok_or(Err::LayerIndexOutOfBounds)?; - let lr = self.layers.get(lidx).ok_or(Err::LayerIndexOutOfBounds)?; - // TODO: handle layers with multiple textures - let gid = *layer.data.iter().find(|g| **g > 0).unwrap(); - let (_, ass, _) = assets.lookup_gid(level, gid)?; - ass.texture.bind(ctx); - unsafe { - ctx.gl.bind_vertex_array(Some(lr.vao)); - ctx.gl.draw_elements(glow::TRIANGLES, lr.index_count as _, glow::UNSIGNED_INT, 0); - } - Ok(()) - } - pub fn populate( - &mut self, - ctx: &context::Context, - assets: &Assets, - level: &Level, - ) -> Erm<()> { - for lidx in 0..level.layers.len() { - self.populate_layer(ctx, assets, level, lidx)?; - } - Ok(()) - } - pub fn render( - &self, - ctx: &context::Context, - assets: &Assets, - level: &Level, - ) -> Erm<()> { - self.shader.bind(ctx); - let sx = 2.0 * level.tilewidth as f32 / ctx.render_width; - let sy = 2.0 * level.tileheight as f32 / ctx.render_height; - self.shader.set_mat4( - ctx, "transform", - &glam::Mat4::from_scale_rotation_translation( - glam::Vec3::new(sx, -sy, 1.0), - glam::Quat::IDENTITY, - glam::Vec3::new(0.0, 0.0, 0.0), - ), - ); - for lidx in 0..level.layers.len() { - self.render_layer(ctx, assets, level, lidx)?; - } - Ok(()) - } -} diff --git a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/lib.rs b/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/lib.rs deleted file mode 100644 index 6b1564e..0000000 --- a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/lib.rs +++ /dev/null @@ -1,355 +0,0 @@ -#![feature(try_blocks)] - -pub mod audio; -pub mod context; -pub mod font; -pub mod framebuffer; -pub mod level2d; -pub mod mesh; -pub mod net; -pub mod physics; -pub mod renderer; -pub mod save; -pub mod scene; -pub mod shader; -pub mod shadow; -pub mod state; -pub mod texture; -pub mod ui; -pub mod utils; - -pub use audio::AudioPlayback; -pub use simple_eyre::eyre::WrapErr; -pub use state::Tick; -pub use utils::{Erm, erm, install_error_handler}; - -#[cfg(target_arch = "wasm32")] -use winit::platform::web::EventLoopExtWebSys; - -#[cfg(target_arch = "wasm32")] -use winit::platform::web::WindowExtWebSys; - -#[cfg(target_arch = "wasm32")] -use wasm_bindgen::JsCast; - -#[cfg(not(target_arch = "wasm32"))] -use glfw::Context; - -use bitflags::bitflags; -bitflags! { - pub struct Options: u32 { - const OVERLAY = 0b00000001; - const HIDDEN = 0b00000010; - const NORESIZE = 0b00000100; - const EGL = 0b00001000; - const FULLSCREEN_MOUSE = 0b00010000; - } -} - -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; - -pub fn contextualize(mut f: F) -> X -where - G: state::Game + 'static, - F: FnMut(&context::Context, &mut state::State, &mut G) -> X, -{ - unsafe { - match (CTX, ST, G) { - (Some(c), Some(s), Some(g)) => f(&*c, &mut *s, &mut *(g as *mut G)), - _ => panic!("context not set"), - } - } -} - -#[cfg(not(target_arch = "wasm32"))] -pub fn run<'a, F, G>(title: &str, w: u32, h: u32, options: Options, gnew: F) -> Erm<()> -where - G: state::Game + 'static, - F: (FnOnce(&'a context::Context) -> G), -{ - env_logger::Builder::new() - .filter(None, log::LevelFilter::Info) - .init(); - install_error_handler(); - - log::info!("hello computer, starting up..."); - - let (rglfw, rwindow, gl, events) = { - use glfw::fail_on_errors; - let mut glfw = glfw::init(glfw::fail_on_errors!()).expect("failed to initialize GLFW"); - - if options.contains(Options::EGL) { - glfw.window_hint(glfw::WindowHint::ContextCreationApi( - glfw::ContextCreationApi::Egl, - )); - } - // let gl_attr = video.gl_attr(); - // gl_attr.set_context_profile(sdl2::video::GLProfile::Core); - // gl_attr.set_context_version(3, 0); - let (mut window, events) = glfw.with_primary_monitor(|glfw, primary| { - if options.contains(Options::HIDDEN) { - glfw.window_hint(glfw::WindowHint::Visible(false)); - glfw.create_window(w as _, h as _, title, glfw::WindowMode::Windowed) - .expect("failed to create window") - } else if options.contains(Options::OVERLAY) { - let mon = primary.expect("failed to get monitor"); - let mode = mon.get_video_mode().expect("failed to get video mode"); - glfw.window_hint(glfw::WindowHint::RedBits(Some(mode.red_bits))); - glfw.window_hint(glfw::WindowHint::GreenBits(Some(mode.green_bits))); - glfw.window_hint(glfw::WindowHint::BlueBits(Some(mode.blue_bits))); - glfw.window_hint(glfw::WindowHint::RefreshRate(Some(mode.refresh_rate))); - glfw.window_hint(glfw::WindowHint::Resizable(false)); - glfw.window_hint(glfw::WindowHint::Decorated(false)); - glfw.window_hint(glfw::WindowHint::Floating(true)); - glfw.window_hint(glfw::WindowHint::TransparentFramebuffer(true)); - unsafe { - // glfw.window_hint(glfw::WindowHint::MousePassthrough(true)); - glfw::ffi::glfwWindowHint(0x0002000D, 1); // mouse passthrough - } - glfw.create_window( - mode.width, - mode.height, - title, - glfw::WindowMode::FullScreen(mon), - ) - .expect("failed to create window") - } else { - glfw.create_window(w as _, h as _, title, glfw::WindowMode::Windowed) - .expect("failed to create window") - } - }); - 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 _) - }; - glfw.set_swap_interval(glfw::SwapInterval::Sync(1)); - (glfw, window, gl, events) - }; - let glfw = std::cell::RefCell::new(rglfw); - let window = std::cell::RefCell::new(rwindow); - - let ctx = Box::leak(Box::new(context::Context::new( - glfw, window, gl, w as f32, h as f32, options, - ))); - let game = Box::leak(Box::new(gnew(ctx))); - let st = Box::leak(Box::new(state::State::new(ctx))); - - unsafe { - CTX = Some(ctx as _); - ST = Some(st as _); - G = Some(game as *mut G as *mut std::ffi::c_void); - } - - game.initialize(ctx, st)?; - st.initialize_audio(ctx, game)?; - 'running: loop { - if ctx.window.borrow().should_close() { - game.finalize(ctx, st)?; - log::info!("bye!"); - break 'running; - } - ctx.glfw.borrow_mut().poll_events(); - for (_, event) in glfw::flush_messages(&events) { - match event { - 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, game)?; - } - glfw::WindowEvent::Key(key, _, glfw::Action::Press, _) => { - st.key_pressed(ctx, game, state::Keycode::new(key))?; - } - glfw::WindowEvent::Key(key, _, glfw::Action::Release, _) => { - st.key_released(ctx, game, state::Keycode::new(key))?; - } - _ => {} - } - } - if ctx.resize_necessary() { - st.handle_resize(ctx); - } - // if let Some(f) = &mut st.request { - // match std::future::Future::poll(f.as_mut(), &mut st.waker_ctx) { - // std::task::Poll::Pending => {}, - // std::task::Poll::Ready(res) => { - // st.request = None; - // match res { - // Ok(r) => st.request_returned(&ctx, game, r), - // Err(e) => log::warn!("error during HTTP request: {}", e), - // } - // }, - // } - // } - st.run_update(ctx, game)?; - st.run_render(ctx, game)?; - ctx.window.borrow_mut().swap_buffers(); - } - Ok(()) -} - -#[cfg(target_arch = "wasm32")] -pub fn run<'a, F, G>(w: u32, h: u32, options: Options, gnew: F) -where - G: state::Game + 'static, - F: (Fn(&'a context::Context) -> G), -{ - console_log::init_with_level(log::Level::Debug).unwrap(); - console_error_panic_hook::set_once(); - tracing_wasm::set_as_global_default(); - // install_error_handler(); - - log::info!("hello computer, starting up..."); - - let event_loop = winit::event_loop::EventLoop::new().expect("failed to initialize event loop"); - - let resize = !options.contains(Options::NORESIZE); - let (window, gl) = { - let mut builder = winit::window::WindowBuilder::new() - .with_maximized(resize) - .with_decorations(false); - if options.contains(Options::OVERLAY) { - builder = builder.with_transparent(true); - } - let window = builder - .build(&event_loop) - .expect("failed to initialize window"); - let gl = web_sys::window() - .and_then(|win| win.document()) - .and_then(|doc| { - let dst = doc.get_element_by_id("teleia-parent")?; - let canvas = - web_sys::Element::from(window.canvas().expect("failed to find canvas")); - dst.append_child(&canvas).ok()?; - let c = canvas.dyn_into::().ok()?; - let webgl2_context = c - .get_context("webgl2") - .ok()?? - .dyn_into::() - .ok()?; - Some(glow::Context::from_webgl2_context(webgl2_context)) - }) - .expect("couldn't add canvas to document"); - (window, gl) - }; - - let ctx = Box::leak(Box::new(context::Context::new( - window, gl, w as f32, h as f32, options, - ))); - ctx.maximize_canvas(); - let game = Box::leak(Box::new(gnew(ctx))); - let st = Box::leak(Box::new(state::State::new(&ctx))); - - unsafe { - CTX = Some(ctx as _); - ST = Some(st as _); - G = Some(game as *mut G as *mut std::ffi::c_void); - } - - let _ = game.initialize(ctx, st); - let _ = st.initialize_audio(ctx, game); - let res = std::rc::Rc::new(std::cell::RefCell::new(Ok(()))); - let result = res.clone(); - event_loop.set_control_flow(winit::event_loop::ControlFlow::Wait); - event_loop.spawn(move |event, elwt| { - let res: Erm<()> = contextualize(|ctx, st, game: &mut G| { - match &event { - winit::event::Event::WindowEvent { - event: wev, - window_id, - .. - } => match wev { - winit::event::WindowEvent::CloseRequested if *window_id == ctx.window.id() => { - elwt.exit() - } - winit::event::WindowEvent::Resized { .. } => { - #[cfg(target_arch = "wasm32")] - ctx.maximize_canvas(); - st.handle_resize(&ctx); - } - winit::event::WindowEvent::Focused(false) => { - st.keys = state::Keys::new(); - } - winit::event::WindowEvent::CursorMoved { position, .. } => { - st.mouse_moved(&ctx, position.x as f32, position.y as f32, game)?; - } - winit::event::WindowEvent::MouseInput { state, .. } => match state { - winit::event::ElementState::Pressed => { - st.mouse_pressed(&ctx, game)?; - } - winit::event::ElementState::Released => { - st.mouse_released(&ctx, game)?; - } - }, - winit::event::WindowEvent::KeyboardInput { - event: - winit::event::KeyEvent { - physical_key: winit::keyboard::PhysicalKey::Code(key), - state, - repeat: false, - .. - }, - .. - } => match state { - winit::event::ElementState::Pressed => { - st.key_pressed(&ctx, game, state::Keycode { kc: *key })?; - } - winit::event::ElementState::Released => { - st.key_released(&ctx, game, state::Keycode { kc: *key })?; - } - }, - _ => {} - }, - - winit::event::Event::AboutToWait => { - if ctx.resize_necessary() { - #[cfg(target_arch = "wasm32")] - ctx.maximize_canvas(); - st.handle_resize(&ctx); - } - // if let Some(f) = &mut st.request { - // match std::future::Future::poll(f.as_mut(), &mut st.waker_ctx) { - // std::task::Poll::Pending => {}, - // std::task::Poll::Ready(res) => { - // st.request = None; - // match res { - // Ok(r) => st.request_returned(&ctx, game, r), - // Err(e) => log::warn!("error during HTTP request: {}", e), - // } - // }, - // } - // // f.poll(); - // } - st.run_update(&ctx, game)?; - st.run_render(&ctx, game)?; - ctx.window.request_redraw(); - } - - _ => {} - } - Ok(()) - }); - if let Err(e) = res { - *result.borrow_mut() = Err(e); - elwt.exit(); - } - }); - let _ = game.finalize(ctx, st); - if let Err(e) = res.replace(Ok(())) { - panic!("{}", e); - } -} diff --git a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/mesh.rs b/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/mesh.rs deleted file mode 100644 index ce34de4..0000000 --- a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/mesh.rs +++ /dev/null @@ -1,197 +0,0 @@ -use glow::HasContext; - -use crate::context; - -pub const ATTRIB_VERTEX: u32 = 0; -pub const ATTRIB_NORMAL: u32 = 1; -pub const ATTRIB_TEXCOORD: u32 = 2; -pub const ATTRIB_JOINT: u32 = 3; -pub const ATTRIB_WEIGHT: u32 = 4; -pub const ATTRIB_COLOR: u32 = 5; - -type Buffer = ::Buffer; - -pub struct Mesh { - pub vao: glow::VertexArray, - pub vbo_vertex: Buffer, - pub vbo_index: Buffer, - pub vbo_normal: Option, - pub vbo_texcoord: Option, - pub mode: u32, // glow::TRIANGLES, etc. - pub index_count: usize, - pub index_type: u32, // glow::BYTE, glow::FLOAT, etc. - pub index_offset: i32, -} - -impl Mesh { - pub fn new_empty(ctx: &context::Context, normals: bool, texcoords: bool) -> Self { - unsafe { - let vao = ctx.gl.create_vertex_array().expect("failed to initialize vao"); - ctx.gl.bind_vertex_array(Some(vao)); - - let vbo_vertex = ctx.gl.create_buffer().expect("failed to create buffer object"); - ctx.gl.bind_buffer(glow::ARRAY_BUFFER, Some(vbo_vertex)); - ctx.gl.vertex_attrib_pointer_f32(ATTRIB_VERTEX, 3, glow::FLOAT, false, 0, 0); - ctx.gl.enable_vertex_attrib_array(ATTRIB_VERTEX); - - let vbo_index = ctx.gl.create_buffer().expect("failed to create buffer object"); - ctx.gl.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, Some(vbo_index)); - - let vbo_normal = if normals { - let vbo_normal = ctx.gl.create_buffer().expect("failed to create buffer object"); - ctx.gl.bind_buffer(glow::ARRAY_BUFFER, Some(vbo_normal)); - ctx.gl.vertex_attrib_pointer_f32(ATTRIB_NORMAL, 3, glow::FLOAT, false, 0, 0); - ctx.gl.enable_vertex_attrib_array(ATTRIB_NORMAL); - Some(vbo_normal) - } else { None }; - - let vbo_texcoord = if texcoords { - let vbo_texcoord = ctx.gl.create_buffer().expect("failed to create buffer object"); - ctx.gl.bind_buffer(glow::ARRAY_BUFFER, Some(vbo_texcoord)); - ctx.gl.vertex_attrib_pointer_f32(ATTRIB_TEXCOORD, 2, glow::FLOAT, false, 0, 0); - ctx.gl.enable_vertex_attrib_array(ATTRIB_TEXCOORD); - Some(vbo_texcoord) - } else { None }; - - Self { - vao, - vbo_vertex, - vbo_index, - vbo_normal, - vbo_texcoord, - mode: glow::TRIANGLES, - index_count: 0, - index_type: glow::UNSIGNED_INT, - index_offset: 0, - } - } - } - pub fn upload( - &mut self, - ctx: &context::Context, - vertices: &[f32], - indices: &[u32], - snormals: Option<&[f32]>, - stexcoords: Option<&[f32]>, - ) { - unsafe { - ctx.gl.bind_buffer(glow::ARRAY_BUFFER, Some(self.vbo_vertex)); - ctx.gl.buffer_data_u8_slice( - glow::ARRAY_BUFFER, - std::slice::from_raw_parts( - vertices.as_ptr() as _, - std::mem::size_of_val(vertices), - ), - glow::STATIC_DRAW, - ); - ctx.gl.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, Some(self.vbo_index)); - ctx.gl.buffer_data_u8_slice( - glow::ELEMENT_ARRAY_BUFFER, - std::slice::from_raw_parts( - indices.as_ptr() as _, - std::mem::size_of_val(indices), - ), - glow::STATIC_DRAW, - ); - - if let Some(vbo_normal) = self.vbo_normal && let Some(normals) = snormals { - ctx.gl.bind_buffer(glow::ARRAY_BUFFER, Some(vbo_normal)); - ctx.gl.buffer_data_u8_slice( - glow::ARRAY_BUFFER, - std::slice::from_raw_parts( - normals.as_ptr() as _, - std::mem::size_of_val(normals), - ), - glow::STATIC_DRAW, - ); - Some(vbo_normal) - } else { None }; - - if let Some(vbo_texcoord) = self.vbo_texcoord && let Some(texcoords) = stexcoords { - ctx.gl.bind_buffer(glow::ARRAY_BUFFER, Some(vbo_texcoord)); - ctx.gl.buffer_data_u8_slice( - glow::ARRAY_BUFFER, - std::slice::from_raw_parts( - texcoords.as_ptr() as _, - std::mem::size_of_val(texcoords), - ), - glow::STATIC_DRAW, - ); - Some(vbo_texcoord) - } else { None }; - self.index_count = indices.len(); - } - } - - pub fn build( - ctx: &context::Context, - vertices: &[f32], - indices: &[u32], - snormals: Option<&[f32]>, - stexcoords: Option<&[f32]>, - ) -> Self { - let mut ret = Self::new_empty(ctx, snormals.is_some(), stexcoords.is_some()); - ret.upload(ctx, vertices, indices, snormals, stexcoords); - ret - } - - pub fn upload_obj(&mut self, ctx: &context::Context, mut bytes: &[u8]) { - let lopts = tobj::LoadOptions { - triangulate: true, - single_index: true, - ..Default::default() - }; - let (meshes, _materials) = tobj::load_obj_buf( - &mut bytes, - &lopts, - |_| Err(tobj::LoadError::GenericFailure) - ).expect("failed to load mesh"); - let mesh = meshes.into_iter().next() - .expect("failed to load mesh") - .mesh; - self.upload( - ctx, - &mesh.positions, - &mesh.indices, - Some(&mesh.normals), - Some(&mesh.texcoords), - ) - } - - pub fn from_obj(ctx: &context::Context, mut bytes: &[u8]) -> Self { - let lopts = tobj::LoadOptions { - triangulate: true, - single_index: true, - ..Default::default() - }; - let (meshes, _materials) = tobj::load_obj_buf( - &mut bytes, - &lopts, - |_| Err(tobj::LoadError::GenericFailure) - ).expect("failed to load mesh"); - let mesh = meshes.into_iter().next() - .expect("failed to load mesh") - .mesh; - Self::build( - ctx, - &mesh.positions, - &mesh.indices, - Some(&mesh.normals), - Some(&mesh.texcoords), - ) - } - - pub fn render(&self, ctx: &context::Context) { - unsafe { - ctx.gl.bind_vertex_array(Some(self.vao)); - ctx.gl.draw_elements(self.mode, self.index_count as _, self.index_type, self.index_offset); - } - } - - pub fn render_instanced(&self, ctx: &context::Context, count: u64) { - unsafe { - ctx.gl.bind_vertex_array(Some(self.vao)); - ctx.gl.draw_elements_instanced(self.mode, self.index_count as _, self.index_type, self.index_offset, count as _); - } - } -} diff --git a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/net.rs b/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/net.rs deleted file mode 100644 index 8758968..0000000 --- a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/net.rs +++ /dev/null @@ -1,4 +0,0 @@ -pub mod ws; - -#[cfg(not(target_arch = "wasm32"))] -pub mod fig; diff --git a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/net/fig.rs b/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/net/fig.rs deleted file mode 100644 index 916cdc1..0000000 --- a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/net/fig.rs +++ /dev/null @@ -1,100 +0,0 @@ -use std::io::{Read, Write}; -use byteorder::{LE, ReadBytesExt, WriteBytesExt}; - -use crate::{Erm, WrapErr}; - -const KEY: usize = 42; - -pub fn read_length_prefixed_utf8(r: &mut R) -> Erm where R: std::io::Read { - let len = r.read_u32::()?; - let mut bs = vec![0; len as usize]; - r.read_exact(&mut bs)?; - Ok(String::from_utf8(bs)?) -} - -#[derive(Debug, Clone)] -pub struct BinaryMessage { - pub event: Vec, - pub data: Vec -} - -pub struct BinaryClient { - in_buf: Vec, - out_buf: Vec, - socket: std::net::TcpStream, - poller: polling::Poller, -} -impl BinaryClient { - pub fn new(addr: &str, subs: &[&[u8]]) -> Erm { - let mut socket = std::net::TcpStream::connect(addr).wrap_err("failed to connect to message bus")?; - for s in subs { - write!(socket, "s").wrap_err("failed to send subscribe message to bus")?; - socket.write_u32::(s.len() as u32).wrap_err("failed to send subscribe message length to bus")?; - socket.write_all(s).wrap_err("failed to send subscribe message to bus")?; - } - socket.set_nonblocking(true).wrap_err("failed to set message bus socket nonblocking")?; - socket.flush().wrap_err("failed to flush bus connection")?; - let in_buf = Vec::new(); - let out_buf = Vec::new(); - let poller = polling::Poller::new()?; - unsafe { - poller.add(&socket, polling::Event::all(KEY)).wrap_err("failed to add event to poll")?; - } - Ok(Self { - in_buf, out_buf, - socket, - poller, - }) - } - fn write_length_prefixed(&mut self, buf: &[u8]) -> Erm<()> { - self.out_buf.write_u32::(buf.len() as u32).wrap_err("failed to send message")?; - self.out_buf.write_all(buf).wrap_err("failed to send message")?; - Ok(()) - - } - pub fn publish(&mut self, ev: &[u8], data: &[u8]) -> Erm<()> { - write!(self.out_buf, "p").wrap_err("failed to send publish message to bus")?; - self.write_length_prefixed(ev)?; - self.write_length_prefixed(data)?; - Ok(()) - } - fn pop_incoming_message(&mut self) -> Option { - let mut reader = std::io::Cursor::new(&self.in_buf); - let event_len = reader.read_u32::().ok()?; - let mut event = vec![0; event_len as usize]; - reader.read_exact(&mut event).ok()?; - let data_len = reader.read_u32::().ok()?; - let mut data = vec![0; data_len as usize]; - reader.read_exact(&mut data).ok()?; - let len = reader.position() as usize; - self.in_buf.drain(..len); - Some(BinaryMessage { event, data }) - } - pub fn pump(&mut self) -> Erm> { - let mut events = polling::Events::new(); - events.clear(); - self.poller.wait(&mut events, Some(std::time::Duration::from_secs(0))) - .wrap_err("failed to poll message bus")?; - for ev in events.iter() { - if ev.key == KEY { - if ev.readable { - let mut buf = [0; 1024]; - match self.socket.read(&mut buf) { - Ok(sz) => self.in_buf.extend_from_slice(&buf[..sz]), - Err(e) if e.kind() == std::io::ErrorKind::WouldBlock => {}, - e => { e.wrap_err("failed to read from bus socket")?; }, - } - } - if ev.writable && !self.out_buf.is_empty() { - match self.socket.write(&self.out_buf) { - Ok(sz) => { self.out_buf.drain(..sz); }, - Err(e) if e.kind() == std::io::ErrorKind::WouldBlock => {}, - e => { e.wrap_err("failed to write to bus socket")?; }, - } - } - self.poller.modify(&self.socket, polling::Event::all(KEY)).wrap_err("failed to update event to poll")?; - } - } - Ok(self.pop_incoming_message()) - } -} diff --git a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/net/ws.rs b/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/net/ws.rs deleted file mode 100644 index b11df40..0000000 --- a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/net/ws.rs +++ /dev/null @@ -1,10 +0,0 @@ -pub mod client; - -#[cfg(not(target_arch = "wasm32"))] -pub mod server; - -#[derive(Debug, Clone)] -pub enum Message { - Binary(Vec), - Text(String), -} diff --git a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/net/ws/client.rs b/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/net/ws/client.rs deleted file mode 100644 index fe9f957..0000000 --- a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/net/ws/client.rs +++ /dev/null @@ -1,9 +0,0 @@ -#[cfg(target_arch = "wasm32")] -pub mod wasm; -#[cfg(target_arch = "wasm32")] -pub use wasm::*; - -#[cfg(not(target_arch = "wasm32"))] -pub mod native; -#[cfg(not(target_arch = "wasm32"))] -pub use native::*; diff --git a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/net/ws/client/native.rs b/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/net/ws/client/native.rs deleted file mode 100644 index eb94093..0000000 --- a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/net/ws/client/native.rs +++ /dev/null @@ -1,124 +0,0 @@ -use std::sync::mpsc::{Sender, Receiver, channel}; -use std::sync::{Arc, Mutex}; -use std::thread::spawn; - -use crate::net::ws::Message; -use crate::{utils, Erm, WrapErr}; - -const KEY: usize = 42; - -type ClientChannels = (Sender, Receiver); -#[derive(Default)] -pub struct Client { - channels: Arc>>, -} - -impl Client { - pub fn new() -> Self { Self::default() } - pub fn connect(&mut self, url: &str) { - let (mut socket, _resp) = if let Ok(v) = tungstenite::connect(url) { v } else { - log::warn!("failed to connect to websocket: {}", url); - return; - }; - let poller = match polling::Poller::new() { - Ok(v) => v, - Err(e) => { log::warn!("failed to create poller: {}", e); return; } - }; - let res: Erm<()> = try { match socket.get_ref() { - tungstenite::stream::MaybeTlsStream::Plain(s) => unsafe { - s.set_nonblocking(true).wrap_err("failed to set socket nonblocking")?; - poller.add(s, polling::Event::readable(KEY)).wrap_err("failed to add event to poll")?; - }, - tungstenite::stream::MaybeTlsStream::NativeTls(s) => unsafe { - s.get_ref().set_nonblocking(true).wrap_err("failed to set socket nonblocking")?; - poller.add(s.get_ref(), polling::Event::readable(KEY)).wrap_err("failed to add event to poll")?; - }, - _ => utils::erm_msg("unknown socket type; cannot poll!")?, - }}; - if let Err(e) = res { - log::warn!("failed to add event to poll: {}", e); - let _ = socket.close(None); - return; - }; - let (outgoing_sender, outgoing_receiver) = channel(); - let (incoming_sender, incoming_receiver) = channel(); - *self.channels.lock().unwrap() = Some((outgoing_sender, incoming_receiver)); - let send_channels_ref = self.channels.clone(); - let recv_channels_ref = self.channels.clone(); - let send_socket_ref = Arc::new(Mutex::new(socket)); - let recv_socket_ref = send_socket_ref.clone(); - let mut events = polling::Events::new(); - spawn(move || loop { - // write all outgoing messages - let res: Erm<()> = try { - while let Ok(msg) = outgoing_receiver.recv() { - match msg { - Message::Text(txt) => send_socket_ref.lock().unwrap() - .send(tungstenite::Message::Text(txt)) - .wrap_err("failed to send websocket text")?, - Message::Binary(bytes) => send_socket_ref.lock().unwrap() - .send(tungstenite::Message::Binary(bytes)) - .wrap_err("failed to send websocket bytes")?, - } - } - }; - if let Err(e) = res { - log::warn!("error in websocket send thread: {}", e); - *send_channels_ref.lock().unwrap() = None; - return; - } - }); - spawn(move || loop { - // wait for and receive all incoming messages - let res: Erm<()> = try { - events.clear(); - poller.wait(&mut events, None).wrap_err("failed to wait on websocket poller")?; - for ev in events.iter() { - if ev.key == KEY { - if ev.readable { match recv_socket_ref.lock().unwrap().read().wrap_err("failed to recv on websocket")? { - tungstenite::Message::Text(txt) => incoming_sender.send(Message::Text(txt)) - .wrap_err("failed to send incoming websocket message on channel")?, - tungstenite::Message::Binary(bytes) => incoming_sender.send(Message::Binary(bytes)) - .wrap_err("failed to send incoming websocket message on channel")?, - tungstenite::Message::Ping(bs) => recv_socket_ref.lock().unwrap() - .send(tungstenite::Message::Pong(bs)) - .wrap_err("failed to send websocket pong")?, - m => log::warn!("unhandled incoming websocket message: {}", m), - }} - match recv_socket_ref.lock().unwrap().get_ref() { - tungstenite::stream::MaybeTlsStream::Plain(s) => - poller.modify(s, polling::Event::readable(KEY)) - .wrap_err("failed to modify event to poll")?, - tungstenite::stream::MaybeTlsStream::NativeTls(s) => - poller.modify(s.get_ref(), polling::Event::readable(KEY)) - .wrap_err("failed to modify event to poll")?, - _ => log::warn!("unknown socket type; cannot modify polling!"), - } - } - } - }; - if let Err(e) = res { - log::warn!("error in websocket recv thread: {}", e); - *recv_channels_ref.lock().unwrap() = None; - return; - } - }); - } - pub fn is_connected(&self) -> bool { - self.channels.lock().unwrap().is_some() - } - pub fn poll(&mut self) -> Option { - if let Some((_, incoming)) = &*self.channels.lock().unwrap() { - incoming.try_recv().ok() - } else { None } - } - pub fn send(&self, msg: Message) { - if let Some((outgoing, _)) = &mut *self.channels.lock().unwrap() { - if let Err(e) = outgoing.send(msg) { - log::warn!("failed to send websocket message on channel: {}", e); - } - } else { - log::warn!("tried to send message, but websocket is not connected"); - } - } -} diff --git a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/net/ws/client/wasm.rs b/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/net/ws/client/wasm.rs deleted file mode 100644 index f4faff7..0000000 --- a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/net/ws/client/wasm.rs +++ /dev/null @@ -1,73 +0,0 @@ -use std::{collections::VecDeque, sync::{Arc, Mutex}}; - -use wasm_bindgen::prelude::*; - -use crate::net::ws::Message; - -impl Message { - fn from_messageevent(e: web_sys::MessageEvent) -> Self { - if let Ok(abuf) = e.data().dyn_into::() { - let array = js_sys::Uint8Array::new(&abuf).to_vec(); - Message::Binary(array) - } else if let Ok(txt) = e.data().dyn_into::() { - Message::Text(txt.into()) - } else { - panic!("received weird websocket message: {:?}", e); - } - } -} - -pub struct Client { - ws: Arc>>, - messages: Arc>>, -} - -impl Client { - pub fn new() -> Self { - Self { - ws: Arc::new(Mutex::new(None)), - messages: Arc::new(Mutex::new(VecDeque::new())), - } - } - pub fn connect(&mut self, url: &str) { - let ws_ref = self.ws.clone(); - let messages_ref = self.messages.clone(); - let cb: Closure = Closure::new(move |e: web_sys::MessageEvent| { - let msg = Message::from_messageevent(e); - log::info!("incoming: {:?}", msg); - messages_ref.lock().unwrap().push_back(msg); - }); - let close_cb: Closure = Closure::new(move |_: web_sys::MessageEvent| { - log::info!("closed!"); - *ws_ref.lock().unwrap() = None; - }); - let ws = web_sys::WebSocket::new(url).expect("failed to open websocket"); - ws.set_onmessage(Some(cb.as_ref().unchecked_ref())); - ws.set_onclose(Some(close_cb.as_ref().unchecked_ref())); - cb.forget(); - close_cb.forget(); - *self.ws.lock().unwrap() = Some(ws); - } - pub fn is_connected(&self) -> bool { - self.ws.lock().unwrap().is_some() - } - pub fn poll(&mut self) -> Option { - self.messages.lock().unwrap().pop_front() - } - pub fn send(&self, msg: Message) { - if let Some(ws) = &*self.ws.lock().unwrap() { - match msg { - Message::Text(txt) => { - if let Err(e) = ws.send_with_str(&txt) { - log::warn!("failed to send string: {:?}", e); - } - }, - Message::Binary(bytes) => { - if let Err(e) = ws.send_with_u8_array(&bytes) { - log::warn!("failed to send bytes: {:?}", e); - } - }, - } - } - } -} diff --git a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/net/ws/server.rs b/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/net/ws/server.rs deleted file mode 100644 index 9422aec..0000000 --- a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/net/ws/server.rs +++ /dev/null @@ -1,140 +0,0 @@ -use std::collections::HashMap; -use std::net::{TcpListener, TcpStream}; -use std::sync::mpsc::{Sender, Receiver, channel}; -use std::sync::{Arc, Mutex}; -use std::thread::spawn; - -use crate::net::ws::Message; -use crate::{utils, Erm, WrapErr}; - -const ACCEPT_KEY: usize = 1; - -type ClientId = usize; -type ClientMessage = (ClientId, Message); - -type ServerChannels = (Sender, Receiver); -#[derive(Default)] -pub struct Server { - clients: Arc>>>, - channels: Arc>>, -} - -impl Server { - pub fn new() -> Self { Self::default() } - pub fn start(&mut self, addr: &str) { - let recv_clients_ref = self.clients.clone(); - let send_clients_ref = self.clients.clone(); - let (outgoing_sender, outgoing_receiver) = channel(); - let (incoming_sender, incoming_receiver) = channel(); - *self.channels.lock().unwrap() = Some((outgoing_sender, incoming_receiver)); - let channels_ref = self.channels.clone(); - let listener = TcpListener::bind(addr).expect("failed to bind server socket"); - let poller = polling::Poller::new().expect("failed to create poller for websocket server"); - unsafe { - poller.add(&listener, polling::Event::readable(ACCEPT_KEY)) - .expect("failed to add poll server socket"); - } - let mut events = polling::Events::new(); - let mut next_id = ACCEPT_KEY + 1; - spawn(move || loop { - // write all outgoing messages - while let Ok((cid, msg)) = outgoing_receiver.recv() { - let res: Erm<()> = try { - if let Some(sock) = send_clients_ref.lock().unwrap().get_mut(&cid) { - let res = match msg { - Message::Text(txt) => sock.send(tungstenite::Message::Text(txt)), - Message::Binary(bytes) => sock.send(tungstenite::Message::Binary(bytes)) - }; - match res { - Ok(_) => {}, - Err(tungstenite::Error::Io(e)) if e.kind() == std::io::ErrorKind::WouldBlock => { - log::info!("client {} receive send block", cid); - }, - Err(e) => utils::erm(e)?, - } - } - }; - if let Err(e) = res { - log::warn!("error when sending to client {}, disconnecting: {}", cid, e); - send_clients_ref.lock().unwrap().remove(&cid); - } - } - }); - spawn(move || loop { - // wait for and receive all new connections and incoming messages - let res: Erm<()> = try { - events.clear(); - poller.wait(&mut events, None).wrap_err("failed to wait on websocket server poller")?; - for ev in events.iter() { - if ev.key == ACCEPT_KEY { - let (sock, client_addr) = listener.accept().wrap_err("failed to accept on socket")?; - let id = next_id; next_id += 1; - let res: Erm<()> = try { - unsafe { poller.add(&sock, polling::Event::readable(id)) - .wrap_err("failed to add socket to poller")?; } - let conn = tungstenite::accept(sock).wrap_err("failed to upgrade to websocket")?; - recv_clients_ref.lock().unwrap().insert(id, conn); - log::info!("new connected client! {}", id); - }; - if let Err(e) = res { - log::warn!("error during connection from {}: {}", client_addr, e); - }; - poller.modify(&listener, polling::Event::readable(ACCEPT_KEY)) - .wrap_err("failed to modify event to poll")?; - } else { - let res: Erm<()> = try { - if let Some(sock) = recv_clients_ref.lock().unwrap().get_mut(&ev.key) { - match sock.read() { - Ok(tungstenite::Message::Text(t)) => - incoming_sender.send((ev.key, Message::Text(t))) - .wrap_err("failed to send incoming message on channel")?, - Ok(tungstenite::Message::Binary(b)) => - incoming_sender.send((ev.key, Message::Binary(b))) - .wrap_err("failed to send incoming message on channel")?, - Ok(tungstenite::Message::Ping(x)) => - sock.write(tungstenite::Message::Pong(x)) - .wrap_err("failed to reply with pong")?, - Ok(m) => log::info!("received unhandled websocket message: {}", m), - Err(tungstenite::Error::Io(e)) if e.kind() == std::io::ErrorKind::WouldBlock => { - log::info!("client {} receive would block", ev.key); - }, - Err(e) => utils::erm(e)?, - } - poller.modify(sock.get_ref(), polling::Event::readable(ev.key)) - .wrap_err("failed to modify event to poll")?; - } else { - log::warn!("poller indicated event for unknown client: {}", ev.key); - } - }; - if let Err(e) = res { - log::warn!("error on client {} connection, disconnecting: {}", ev.key, e); - recv_clients_ref.lock().unwrap().remove(&ev.key); - } - } - } - }; - if let Err(e) = res { - log::warn!("unhandled error in websocket thread, stopping server: {}", e); - *channels_ref.lock().unwrap() = None; - return; - } - }); - } - pub fn clients(&self) -> Vec { - self.clients.lock().unwrap().keys().copied().collect() - } - pub fn poll(&mut self) -> Option<(ClientId, Message)> { - if let Some((_, incoming)) = &*self.channels.lock().unwrap() { - incoming.try_recv().ok() - } else { None } - } - pub fn send(&self, client: ClientId, msg: Message) { - if let Some((outgoing, _)) = &mut *self.channels.lock().unwrap() { - if let Err(e) = outgoing.send((client, msg)) { - log::warn!("failed to send websocket message to client {} on channel: {}", client, e); - } - } else { - log::warn!("tried to send message to client {}, but websocket is not connected", client); - } - } -} diff --git a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/physics.rs b/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/physics.rs deleted file mode 100644 index e69de29..0000000 diff --git a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/renderer.rs b/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/renderer.rs deleted file mode 100644 index c22c973..0000000 --- a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/renderer.rs +++ /dev/null @@ -1,337 +0,0 @@ -use crate::{context, state, shader, texture, mesh}; - -use bitflags::bitflags; - -bitflags! { - #[derive(Clone, Copy, Debug, PartialEq, Eq)] - pub struct UberFlags: u32 { - const TEXTURE_COLOR = 0b0000000001; - const TEXTURE_NORMAL = 0b0000000010; - const FLIP_TEXTURE = 0b0000000100; - const LIGHT_AMBIENT = 0b0000001000; - const LIGHT_DIR = 0b0000010000; - const LIGHT_POINT = 0b0000100000; - const SPRITE = 0b0001000000; - const EFFECTS = 0b0010000000; - const YSKEW = 0b0100000000; - const VERTEX_COLOR = 0b1000000000; - } -} -impl UberFlags { - fn prelude() -> String { - let mut s = String::new(); - s += "#version 300 es\nprecision highp float;"; - for (nm, f) in Self::all().iter_names() { - s += &format!("const int {} = {};\n", nm, f.bits()); - } - s - } - fn set_flags(self, ctx: &context::Context, shader: &shader::Shader) { - shader.set_i32(ctx, "flags", self.bits() as i32); - } -} - -pub trait Assets { - type Shader: PartialEq + Eq + Clone + Copy; - fn shader(&self, i: Self::Shader) -> &shader::Shader; - type Texture: PartialEq + Eq + Clone + Copy; - fn texture(&self, i: Self::Texture) -> &texture::Texture; - type Mesh: PartialEq + Eq + Clone + Copy; - fn mesh(&self, i: Self::Mesh) -> &mesh::Mesh; - type Material: PartialEq + Eq + Clone + Copy; - fn material(&self, i: Self::Material) -> &texture::Material; -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -enum ShaderMode { TwoDimension, ThreeDimension, ThreeDimensionOrth } -#[derive(Debug, Clone, Copy)] -enum BoundShader { None, Uber(UberFlags, ShaderMode), Shader(A::Shader, ShaderMode) } -impl PartialEq for BoundShader { - fn eq(&self, other: &Self) -> bool { - match (self, other) { - (Self::None, Self::None) => true, - (Self::Uber(sf, sm), Self::Uber(of, om)) => sf == of && sm == om, - (Self::Shader(ss, sm), Self::Shader(os, om)) => ss == os && sm == om, - _ => false, - } - } -} -#[derive(Debug, Clone, Copy)] -enum BoundTexture { None, Texture(A::Texture), Material(A::Material) } -impl PartialEq for BoundTexture { - fn eq(&self, other: &Self) -> bool { - match (self, other) { - (Self::None, Self::None) => true, - (Self::Texture(s), Self::Texture(o)) => s == o, - (Self::Material(s), Self::Material(o)) => s == o, - _ => false, - } - } -} -pub struct Renderer { - pub assets: A, - shader_uber: shader::Shader, - shader: BoundShader, - texture: BoundTexture, -} -impl Renderer { - pub fn new(ctx: &context::Context, f: F) -> Self - where F: FnOnce(&context::Context) -> A { - let shader_uber = shader::Shader::new_nolib(ctx, - &format!("{}{}", UberFlags::prelude(), include_str!("assets/shaders/uber/vert.glsl")), - &format!("{}{}", UberFlags::prelude(), include_str!("assets/shaders/uber/frag.glsl")), - ); - shader_uber.bind(ctx); - shader_uber.set_i32(ctx, "texture_normal", 1); - Self { - assets: f(ctx), - shader_uber, - shader: BoundShader::None, - texture: BoundTexture::None, - } - } - pub fn font_char_width(&self, st: &state::State) -> f32 { st.font_default.char_width as f32 } - pub fn font_char_height(&self, st: &state::State) -> f32 { st.font_default.char_height as f32 } - pub fn unbind_texture(&mut self, _ctx: &context::Context, _st: &mut state::State) { - self.texture = BoundTexture::None; - } - pub fn bind_texture(&mut self, ctx: &context::Context, _st: &mut state::State, texture: A::Texture) { - if self.texture != BoundTexture::Texture(texture) { - self.assets.texture(texture).bind(ctx); - self.texture = BoundTexture::Texture(texture); - } - } - pub fn bind_material(&mut self, ctx: &context::Context, _st: &mut state::State, mat: A::Material) { - if self.texture != BoundTexture::Material(mat) { - self.assets.material(mat).bind(ctx); - self.texture = BoundTexture::Material(mat); - } - } - fn shader(&self) -> Option<(&shader::Shader, ShaderMode)> { - match self.shader { - BoundShader::Uber(_, sm) => Some((&self.shader_uber, sm)), - BoundShader::Shader(s, sm) => Some((self.assets.shader(s), sm)), - _ => None, - } - } - fn bind_uber(&mut self, - ctx: &context::Context, st: &mut state::State, - flags: UberFlags, mode: ShaderMode, - ) { - if let BoundShader::Uber(f, sm) = self.shader && f == flags && sm == mode { return } - match mode { - ShaderMode::TwoDimension => st.bind_2d(ctx, &self.shader_uber), - ShaderMode::ThreeDimension => st.bind_3d(ctx, &self.shader_uber), - ShaderMode::ThreeDimensionOrth => st.bind_3d_orth(ctx, &self.shader_uber), - } - flags.set_flags(ctx, &self.shader_uber); - self.shader = BoundShader::Uber(flags, mode) - } - fn bind_shader(&mut self, - ctx: &context::Context, st: &mut state::State, - shader: A::Shader, mode: ShaderMode, - ) { - if let BoundShader::Shader(s, sm) = self.shader && s == shader && sm == mode { return } - match mode { - ShaderMode::TwoDimension => st.bind_2d(ctx, self.assets.shader(shader)), - ShaderMode::ThreeDimension => st.bind_3d(ctx, self.assets.shader(shader)), - ShaderMode::ThreeDimensionOrth => st.bind_3d_orth(ctx, self.assets.shader(shader)), - } - self.shader = BoundShader::Shader(shader, mode) - } - pub fn bind_uber_2d(&mut self, ctx: &context::Context, st: &mut state::State, flags: UberFlags) { - self.bind_uber(ctx, st, flags, ShaderMode::TwoDimension); - } - pub fn bind_uber_3d(&mut self, ctx: &context::Context, st: &mut state::State, flags: UberFlags) { - self.bind_uber(ctx, st, flags, ShaderMode::ThreeDimension); - } - pub fn bind_uber_3d_orth(&mut self, ctx: &context::Context, st: &mut state::State, flags: UberFlags) { - self.bind_uber(ctx, st, flags, ShaderMode::ThreeDimensionOrth); - } - pub fn bind_shader_2d(&mut self, ctx: &context::Context, st: &mut state::State, shader: A::Shader) { - self.bind_shader(ctx, st, shader, ShaderMode::TwoDimension); - } - pub fn bind_shader_3d(&mut self, ctx: &context::Context, st: &mut state::State, shader: A::Shader) { - self.bind_shader(ctx, st, shader, ShaderMode::ThreeDimension); - } - pub fn render(&self, ctx: &context::Context, _st: &state::State, mesh: A::Mesh) { - self.assets.mesh(mesh).render(ctx) - } - pub fn render_square(&self, ctx: &context::Context, st: &state::State) { - st.mesh_square.render(ctx) - } - pub fn set_position_2d_mat(&self, ctx: &context::Context, st: &state::State, pos: glam::Mat4) { - if let Some((s, sm)) = self.shader() { - debug_assert!(sm == ShaderMode::TwoDimension, "attempted to set_position_2d in wrong mode"); - s.set_position_2d_mat(ctx, st, &pos); - } - } - pub fn set_position_2d_rotate(&self, ctx: &context::Context, st: &state::State, pos: glam::Vec2, dims: glam::Vec2, rot: glam::Quat) { - if let Some((s, sm)) = self.shader() { - debug_assert!(sm == ShaderMode::TwoDimension, "attempted to set_position_2d in wrong mode"); - s.set_position_2d_helper(ctx, st, &pos, &dims, &rot) - } - } - pub fn set_position_2d(&self, ctx: &context::Context, st: &state::State, pos: glam::Vec2, dims: glam::Vec2) { - if let Some((s, sm)) = self.shader() { - debug_assert!(sm == ShaderMode::TwoDimension, "attempted to set_position_2d in wrong mode"); - s.set_position_2d(ctx, st, &pos, &dims) - } - } - pub fn set_position_3d(&self, ctx: &context::Context, st: &state::State, pos: glam::Mat4) { - if let Some((s, sm)) = self.shader() { - debug_assert!(sm == ShaderMode::ThreeDimension || sm == ShaderMode::ThreeDimensionOrth, - "attempted to set_position_3d in wrong mode" - ); - s.set_position_3d(ctx, st, &pos) - } - } - pub fn set_i32(&self, ctx: &context::Context, _st: &state::State, nm: &str, val: i32) { - if let Some((s, _)) = self.shader() { s.set_i32(ctx, nm, val) } - } - pub fn set_f32(&self, ctx: &context::Context, _st: &state::State, nm: &str, val: f32) { - if let Some((s, _)) = self.shader() { s.set_f32(ctx, nm, val) } - } - pub fn set_vec2(&self, ctx: &context::Context, _st: &state::State, nm: &str, val: glam::Vec2) { - if let Some((s, _)) = self.shader() { s.set_vec2(ctx, nm, &val) } - } - pub fn set_vec3(&self, ctx: &context::Context, _st: &state::State, nm: &str, val: glam::Vec3) { - if let Some((s, _)) = self.shader() { s.set_vec3(ctx, nm, &val) } - } - pub fn set_vec4(&self, ctx: &context::Context, _st: &state::State, nm: &str, val: glam::Vec4) { - if let Some((s, _)) = self.shader() { s.set_vec4(ctx, nm, &val) } - } - pub fn set_mat4(&self, ctx: &context::Context, _st: &state::State, nm: &str, val: glam::Mat4) { - if let Some((s, _)) = self.shader() { s.set_mat4(ctx, nm, &val) } - } - pub fn set_texture_offset(&self, - ctx: &context::Context, st: &state::State, - xinc: i32, yinc: i32, - x: i32, y: i32 - ) { - let xcount = xinc as f32; let xratio = 1.0 / xcount; - let ycount = yinc as f32; let yratio = 1.0 / ycount; - self.set_vec2( - ctx, st, "sprite_dims", - glam::Vec2::new(xratio, yratio), - ); - self.set_vec2( - ctx, st, "sprite_offset", - glam::Vec2::new((x % xinc) as f32 * xratio, (y % yinc) as f32 * yratio), - ); - } - - /// Common case: draw the given textured mesh in the world (units are world tiles) - pub fn textured_mesh_world(&mut self, - ctx: &context::Context, st: &mut state::State, - shader: A::Shader, - texture: A::Texture, - mesh: A::Mesh, - pos: glam::Mat4, - ) { - self.bind_shader_3d(ctx, st, shader); - self.bind_texture(ctx, st, texture); - self.set_position_3d(ctx, st, pos); - self.render(ctx, st, mesh); - } - - /// Common case: draw the given color in a rectangle on the screen (units are pixels, pos is top left) - pub fn color_screen(&mut self, - ctx: &context::Context, st: &mut state::State, - color: glam::Vec4, - pos: glam::Vec2, - dims: glam::Vec2, - ) { - self.bind_uber_2d(ctx, st, UberFlags::empty()); - self.set_vec4(ctx, st, "color", color); - self.set_position_2d(ctx, st, pos, dims); - self.render_square(ctx, st); - } - - /// Common case: draw the given texture on the screen (units are pixels, pos is top left) - pub fn texture_screen(&mut self, - ctx: &context::Context, st: &mut state::State, - texture: A::Texture, - pos: glam::Vec2, - dims: glam::Vec2, - ) { - self.bind_uber_2d(ctx, st, UberFlags::TEXTURE_COLOR); - self.bind_texture(ctx, st, texture); - self.set_position_2d(ctx, st, pos, dims); - self.render_square(ctx, st); - } - - pub fn texture_screen_rotate(&mut self, - ctx: &context::Context, st: &mut state::State, - texture: A::Texture, - pos: glam::Vec2, - dims: glam::Vec2, - rot: glam::Quat, - ) { - self.bind_uber_2d(ctx, st, UberFlags::TEXTURE_COLOR); - self.bind_texture(ctx, st, texture); - self.set_position_2d_rotate(ctx, st, pos, dims, rot); - self.render_square(ctx, st); - } - - pub fn texture_screen_recolor(&mut self, - ctx: &context::Context, st: &mut state::State, - texture: A::Texture, hue: f32, - pos: glam::Vec2, - dims: glam::Vec2, - ) { - self.bind_uber_2d(ctx, st, UberFlags::TEXTURE_COLOR | UberFlags::EFFECTS); - self.bind_texture(ctx, st, texture); - self.set_f32(ctx, st, "effect_huescale", 0.0); - self.set_f32(ctx, st, "effect_hueshift", hue); - self.set_position_2d(ctx, st, pos, dims); - self.render_square(ctx, st); - self.set_f32(ctx, st, "effect_huescale", 1.0); - self.set_f32(ctx, st, "effect_hueshift", 0.0); - } - - /// Common case: text in the default font (units are pixels, pos is top left) - pub fn text_screen(&mut self, - ctx: &context::Context, st: &mut state::State, - pos: glam::Vec2, - s: &str, - ) { - // drawing text might bind the texture - self.texture = BoundTexture::None; - self.bind_uber_2d(ctx, st, UberFlags::TEXTURE_COLOR | UberFlags::VERTEX_COLOR | UberFlags::FLIP_TEXTURE); - let dims = glam::Vec2::new(st.font_default.char_width as f32, st.font_default.char_height as f32); - let fpos = pos + glam::Vec2::new(-dims.x / 2.0, dims.y / 2.0); - self.set_position_2d(ctx, st, fpos, dims); - st.font_default.render_text(ctx, st, s); - } - - /// Common case: text in the default font, with a color (units are pixels, pos is top left) - pub fn text_colored_screen(&mut self, - ctx: &context::Context, st: &mut state::State, - pos: glam::Vec2, - col: glam::Vec3, - s: &str, - ) { - self.texture = BoundTexture::None; - self.bind_uber_2d(ctx, st, UberFlags::TEXTURE_COLOR | UberFlags::VERTEX_COLOR | UberFlags::FLIP_TEXTURE); - let dims = glam::Vec2::new(st.font_default.char_width as f32, st.font_default.char_height as f32); - let fpos = pos + glam::Vec2::new(-dims.x / 2.0, st.font_default.char_height as f32 / 2.0); - self.set_position_2d(ctx, st, fpos, dims); - st.font_default.render_text_helper(ctx, st, s, &[col]); - } - - /// Common case: text in the default font (units are pixels, pos is center) - pub fn text_centered_screen(&mut self, - ctx: &context::Context, st: &mut state::State, - pos: glam::Vec2, - s: &str, - ) { - self.texture = BoundTexture::None; - self.bind_uber_2d(ctx, st, UberFlags::TEXTURE_COLOR | UberFlags::VERTEX_COLOR | UberFlags::FLIP_TEXTURE); - let width = s.len() as f32 * st.font_default.char_width as f32; - let dims = glam::Vec2::new(st.font_default.char_width as f32, st.font_default.char_height as f32); - let fpos = pos + glam::Vec2::new(-dims.x / 2.0 - (width / 2.0).round(), st.font_default.char_height as f32 / 2.0); - self.set_position_2d(ctx, st, fpos, dims); - st.font_default.render_text(ctx, st, s); - } -} diff --git a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/save.rs b/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/save.rs deleted file mode 100644 index 1297a1b..0000000 --- a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/save.rs +++ /dev/null @@ -1,47 +0,0 @@ -#[cfg(target_arch = "wasm32")] -use base64::prelude::*; - -#[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 = bincode::serde::encode_to_vec(data, bincode::config::standard()).expect("failed to serialize save"); - let str = BASE64_STANDARD.encode(&val); - storage.set_item(&key, &str).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 bytes = BASE64_STANDARD.decode(&s).expect("failed to decode base64 for save"); - let (ret, _) = bincode::serde::decode_from_slice(&bytes, bincode::config::standard()) - .expect("failed to deserialize save"); - Some(ret) -} - -#[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 mut file = std::fs::File::create(&path).expect("failed to open save file"); - bincode::serde::encode_into_std_write(data, &mut file, bincode::config::standard()) - .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 mut file = std::fs::File::open(&path).ok()?; - bincode::serde::decode_from_std_read(&mut file, bincode::config::standard()).ok() -} diff --git a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/scene.rs b/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/scene.rs deleted file mode 100644 index a904bf1..0000000 --- a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/scene.rs +++ /dev/null @@ -1,401 +0,0 @@ -use std::{collections::{HashMap, VecDeque}, mem::offset_of}; - -use glow::HasContext; -use image::EncodableLayout; - -use crate::{context, mesh, shader, texture}; - -pub type Index = usize; - -pub struct Primitive { - pub mesh: mesh::Mesh, - pub material: Index, -} - -pub struct Object { - pub primitives: Vec, -} - -pub struct Material { - pub base_color_factor: glam::Vec4, - pub base_color_texture: Option, - - pub metallic_factor: f32, - pub roughness_factor: f32, - pub metallic_roughness_texture: Option, - - pub normal_texture: Option, - - pub occlusion_texture: Option, - - pub emissive_factor: glam::Vec3, - pub emissive_texture: Option, -} - -pub struct Skin { - pub inverse_bind_matrices: Vec, - pub joints: Vec, -} - -pub enum ChannelValues { - Translation(Vec), - Rotation(Vec), - Scale(Vec), -} - -pub enum Interpolation { - Linear, - Step, - CubicSpline, -} - -pub struct Channel { - pub target: Index, - pub interpolation: Interpolation, - pub keyframes: Vec, - pub values: ChannelValues, -} - -pub struct Animation { - pub channels: Vec, -} - -pub struct Node { - pub children: Vec, - pub object: Option, - pub skin: Option, - pub transform: glam::Mat4, -} - -pub struct Scene { - pub objects: Vec, - pub textures: Vec, - pub materials: Vec, - pub skins: Vec, - pub animations: HashMap, - pub nodes: Vec, - pub nodes_by_name: HashMap, - pub scene_nodes: Vec, -} - -impl Scene { - pub fn load_default_shader(ctx: &context::Context) -> shader::Shader { - shader::Shader::new( - ctx, - include_str!("assets/shaders/scene/vert.glsl"), - include_str!("assets/shaders/scene/frag.glsl") - ) - } - pub fn from_gltf(ctx: &context::Context, bytes: &[u8]) -> Self { - let (gltf, buffers, images) = gltf::import_slice(bytes).expect("failed to parse GLTF"); - let get_buffer_data = |b: gltf::Buffer| { - buffers.get(b.index()).map(|gltf::buffer::Data(bytes)| bytes.as_slice()) - }; - let objects = gltf.meshes().map(|m| { - let primitives = m.primitives().map(|p| { - let mode = match p.mode() { - gltf::mesh::Mode::Points => glow::POINTS, - gltf::mesh::Mode::Lines => glow::LINES, - gltf::mesh::Mode::LineLoop => glow::LINE_LOOP, - gltf::mesh::Mode::LineStrip => glow::LINE_STRIP, - gltf::mesh::Mode::Triangles => glow::TRIANGLES, - gltf::mesh::Mode::TriangleStrip => glow::TRIANGLE_STRIP, - gltf::mesh::Mode::TriangleFan => glow::TRIANGLE_FAN, - }; - unsafe { - let vao = ctx.gl.create_vertex_array().expect("failed to initialize vao"); - ctx.gl.bind_vertex_array(Some(vao)); - - // in the past, I've been lazy and just uploaded whole buffers to the GPU. - // this is certainly not the right thing to do in general. - // perhaps I am misunderstanding, but it feels like GLTF makes it pretty difficult to do - // that in general, on account of things like sparse accessors. - // instead, we'll use the gltf crate's handy "reader" abstraction to iterate over all of the - // data in the buffers, assemble it ourselves, and then upload that. - let reader = p.reader(get_buffer_data); - - // on to the actual vertex data. - // this is the layout of a single vertex in the buffer we send to the GPU. - struct Vertex { - pos: glam::Vec3, - normal: glam::Vec3, - texcoord: glam::Vec2, - joints: glam::Vec4, - weights: glam::Vec4, - } - - // vertices always have positions - let mut vertices = Vec::new(); - for pos in reader.read_positions().expect("primitive has no positions") { - vertices.push(Vertex { - pos: glam::Vec3::from_array(pos), - normal: glam::Vec3::default(), - texcoord: glam::Vec2::default(), - joints: glam::Vec4::default(), - weights: glam::Vec4::default(), - }); - } - - // if we find indices, use those. otherwise generate indices - let indices: Vec = if let Some(ri) = reader.read_indices() { - ri.into_u32().collect() - } else { - vertices.iter().enumerate().map(|(i, _)| i as u32).collect() - }; - let indices_bytes: Vec = indices.iter().flat_map(|x| x.to_ne_bytes()).collect(); - let indices_buf = ctx.gl.create_buffer().expect("failed to create index buffer object"); - ctx.gl.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, Some(indices_buf)); - ctx.gl.buffer_data_u8_slice( - glow::ELEMENT_ARRAY_BUFFER, - &indices_bytes, - glow::STATIC_DRAW, - ); - - // optionally, we might have some other vertex attributes too - if let Some(iter) = reader.read_normals() { - for (i, n) in iter.enumerate() { - vertices[i].normal = glam::Vec3::from_array(n) - } - } - if let Some(iter) = reader.read_tex_coords(0) { - for (i, uv) in iter.into_f32().enumerate() { - vertices[i].texcoord = glam::Vec2::from_array(uv) - } - } - if let Some(iter) = reader.read_joints(0) { - for (i, j) in iter.into_u16().enumerate() { - vertices[i].joints = glam::Vec4::from_slice(&j.into_iter().map(|x| x as f32).collect::>()) - } - } - if let Some(iter) = reader.read_weights(0) { - for (i, w) in iter.into_f32().enumerate() { - vertices[i].weights = glam::Vec4::from_array(w) - } - } - - let vertex_size = std::mem::size_of::() as i32; - let vertices_buf = ctx.gl.create_buffer().expect("failed to create buffer object"); - ctx.gl.bind_buffer(glow::ARRAY_BUFFER, Some(vertices_buf)); - ctx.gl.buffer_data_u8_slice( - glow::ARRAY_BUFFER, - std::slice::from_raw_parts( - vertices.as_ptr() as _, - vertices.len() * (vertex_size as usize), - ), - glow::STATIC_DRAW, - ); - ctx.gl.enable_vertex_attrib_array(mesh::ATTRIB_VERTEX); - ctx.gl.vertex_attrib_pointer_f32(mesh::ATTRIB_VERTEX, 3, glow::FLOAT, false, vertex_size, offset_of!(Vertex, pos) as _); - ctx.gl.enable_vertex_attrib_array(mesh::ATTRIB_NORMAL); - ctx.gl.vertex_attrib_pointer_f32(mesh::ATTRIB_NORMAL, 3, glow::FLOAT, false, vertex_size, offset_of!(Vertex, normal) as _); - ctx.gl.enable_vertex_attrib_array(mesh::ATTRIB_TEXCOORD); - ctx.gl.vertex_attrib_pointer_f32(mesh::ATTRIB_TEXCOORD, 2, glow::FLOAT, false, vertex_size, offset_of!(Vertex, texcoord) as _); - ctx.gl.enable_vertex_attrib_array(mesh::ATTRIB_JOINT); - ctx.gl.vertex_attrib_pointer_f32(mesh::ATTRIB_JOINT, 4, glow::FLOAT, false, vertex_size, offset_of!(Vertex, joints) as _); - ctx.gl.enable_vertex_attrib_array(mesh::ATTRIB_WEIGHT); - ctx.gl.vertex_attrib_pointer_f32(mesh::ATTRIB_WEIGHT, 4, glow::FLOAT, false, vertex_size, offset_of!(Vertex, weights) as _); - - - Primitive { - mesh: mesh::Mesh { - vao, - vbo_vertex: vertices_buf, - vbo_index: indices_buf, - vbo_normal: None, - vbo_texcoord: None, - mode, - index_count: indices.len(), - index_type: glow::UNSIGNED_INT, - index_offset: 0, - }, - material: p.material().index().unwrap(), - } - } - }).collect(); - Object { - primitives, - } - }).collect(); - let textures: Vec = images.into_iter().map(|bi| { - unsafe { - let i = bi.image.into_rgba8(); - let tex = ctx.gl.create_texture().expect("failed to create texture"); - ctx.gl.bind_texture(glow::TEXTURE_2D, Some(tex)); - ctx.gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_WRAP_S, glow::CLAMP_TO_EDGE as i32); - ctx.gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_WRAP_T, glow::CLAMP_TO_EDGE as i32); - ctx.gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_MIN_FILTER, glow::NEAREST as i32); - ctx.gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_MAG_FILTER, glow::NEAREST as i32); - ctx.gl.tex_image_2d( - glow::TEXTURE_2D, - 0, - glow::RGBA as i32, - i.width() as i32, - i.height() as i32, - 0, - glow::RGBA, - glow::UNSIGNED_BYTE, - Some(i.as_bytes()), - ); - ctx.gl.generate_mipmap(glow::TEXTURE_2D); - texture::Texture { tex, width: i.width() as i32, height: i.height() as i32 } - } - }).collect(); - let materials: Vec = gltf.materials().map(|m| { - let pbr = m.pbr_metallic_roughness(); - let [bcr, bcg, bcb, bca] = pbr.base_color_factor(); - let [emx, emy, emz] = m.emissive_factor(); - Material { - base_color_factor: glam::Vec4::new(bcr, bcg, bcb, bca), - base_color_texture: pbr.base_color_texture().map(|tex| tex.texture().source().index()), - metallic_factor: pbr.metallic_factor(), - roughness_factor: pbr.roughness_factor(), - metallic_roughness_texture: pbr.metallic_roughness_texture().map(|tex| tex.texture().source().index()), - normal_texture: m.normal_texture().map(|tex| tex.texture().source().index()), - occlusion_texture: m.occlusion_texture().map(|tex| tex.texture().source().index()), - emissive_factor: glam::Vec3::new(emx, emy, emz), - emissive_texture: m.emissive_texture().map(|tex| tex.texture().source().index()), - } - }).collect(); - - let skins = gltf.skins().map(|s| { - let ibm = s.reader(get_buffer_data).read_inverse_bind_matrices() - .expect("missing read inverse bind matrices") - .map(|m| glam::Mat4::from_cols_array_2d(&m)).collect(); - Skin { - inverse_bind_matrices: ibm, - joints: s.joints().map(|j| j.index()).collect(), - } - }).collect(); - - let animations = HashMap::from_iter(gltf.animations().filter_map(|a| { - let channels = a.channels().map(|c| { - let read = c.reader(get_buffer_data); - Channel { - target: c.target().node().index(), - interpolation: match c.sampler().interpolation() { - gltf::animation::Interpolation::Linear => Interpolation::Linear, - gltf::animation::Interpolation::Step => Interpolation::Step, - gltf::animation::Interpolation::CubicSpline => Interpolation::CubicSpline, - }, - keyframes: read.read_inputs().expect("channel has no inputs").collect(), - values: match read.read_outputs().expect("channel has no outputs") { - gltf::animation::util::ReadOutputs::Translations(ts) => - ChannelValues::Translation(ts.map(glam::Vec3::from_array).collect()), - gltf::animation::util::ReadOutputs::Rotations(ts) => - ChannelValues::Rotation(ts.into_f32().map(glam::Quat::from_array).collect()), - gltf::animation::util::ReadOutputs::Scales(ts) => - ChannelValues::Scale(ts.map(glam::Vec3::from_array).collect()), - _ => panic!("unsupport channel outputs"), - }, - } - }).collect(); - a.name().map(|nm| (nm.to_owned(), Animation { channels })) - })); - - let nodes = gltf.nodes().map(|n| { - Node { - children: n.children().map(|c| c.index()).collect(), - object: n.mesh().map(|m| m.index()), - skin: n.skin().map(|s| s.index()), - transform: glam::Mat4::from_cols_array_2d(&n.transform().matrix()), - } - }).collect(); - - let mut nodes_by_name = HashMap::new(); - for n in gltf.nodes() { - if let Some(nm) = n.name() { - nodes_by_name.insert(nm.to_owned(), n.index()); - } - } - - let scene_nodes = gltf.default_scene().unwrap().nodes().map(|n| n.index()).collect(); - - Self { - objects, - textures, - materials, - skins, - animations, - nodes, - nodes_by_name, - scene_nodes, - } - } - - pub fn compute_joint_matrices(&self, skin: &Skin) -> Vec { - let mut q: VecDeque<(Index, glam::Mat4)> = VecDeque::new(); - q.push_back((skin.joints[0], glam::Mat4::IDENTITY)); - let mut transforms = vec![glam::Mat4::IDENTITY; self.nodes.len()]; - while let Some((ni, m)) = q.pop_front() { - let n = &self.nodes[ni]; - transforms[ni] = m.mul_mat4(&n.transform); - for ci in &n.children { - q.push_back((*ci, transforms[ni])); - } - } - let mut ret = vec![glam::Mat4::IDENTITY; skin.joints.len()]; - for (idx, ni) in skin.joints.iter().enumerate() { - ret[idx] = transforms[*ni].mul_mat4(&skin.inverse_bind_matrices[idx]); - } - ret - } - - fn render_node(&self, ctx: &context::Context, shader: &shader::Shader, n: &Node) { - if let Some(o) = n.object.and_then(|i| self.objects.get(i)) { - if let Some(s) = n.skin.and_then(|i| self.skins.get(i)) { - let jms = self.compute_joint_matrices(s); - shader.set_mat4_array(ctx, "joint_matrices[0]", &jms); - } - for p in &o.primitives { - if let Some(tex) = self.materials.get(p.material) - .and_then(|m| m.base_color_texture) - .and_then(|t| self.textures.get(t)) { - tex.bind(ctx); - } else { - texture::Texture::bind_initial(ctx); - } - p.mesh.render(ctx); - } - } - } - - pub fn render(&self, ctx: &context::Context, shader: &shader::Shader) { - let mut q: VecDeque = VecDeque::new(); - for sn in &self.scene_nodes { - q.push_back(*sn); - } - while let Some(ni) = q.pop_front() { - let n = &self.nodes[ni]; - self.render_node(ctx, shader, n); - for ci in &n.children { - q.push_back(*ci); - } - } - } - - pub fn reflect_animation(&mut self, nm: &str, time: f32) { - if let Some(anim) = self.animations.get(nm) { - for c in &anim.channels { - let (previ, nexti) = if let Some(nexti) = c.keyframes.iter().position(|x| *x > time) { - let previ = if nexti > 0 { nexti - 1 } else { c.keyframes.len() - 1 }; - (previ, nexti) - } else { - (c.keyframes.len() - 1, 0) - }; - if let ChannelValues::Rotation(vs) = &c.values { - let prevt = c.keyframes[previ]; - let nextt = c.keyframes[nexti]; - let prev = vs[previ]; - let next = vs[nexti]; - let new = prev.slerp(next, (time - prevt) / (nextt - prevt)); - let (scale, _, trans) = self.nodes[c.target].transform.to_scale_rotation_translation(); - self.nodes[c.target].transform = glam::Mat4::from_scale_rotation_translation( - scale, - new, - trans, - ); - } - } - } - } -} diff --git a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/shader.rs b/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/shader.rs deleted file mode 100644 index d18ba27..0000000 --- a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/shader.rs +++ /dev/null @@ -1,260 +0,0 @@ -use std::collections::HashMap; - -use glow::HasContext; - -use crate::{context, font, mesh, state}; - -const COMMON_VERT: &str = include_str!("assets/shaders/common/vert.glsl"); -const COMMON_FRAG: &str = include_str!("assets/shaders/common/frag.glsl"); - -#[derive(Clone)] -pub struct Shader { - pub program: glow::Program, - pub uniforms: std::rc::Rc> -} - -impl Shader { - pub fn new_helper(ctx: &context::Context, vsrc: &str, fsrc: &str) -> Result { - unsafe { - let program = ctx.gl.create_program()?; - - let vert = ctx.gl.create_shader(glow::VERTEX_SHADER)?; - ctx.gl.shader_source(vert, vsrc); - ctx.gl.compile_shader(vert); - if !ctx.gl.get_shader_compile_status(vert) { - return Err(format!( - "failed to compile vertex shader:\n{}", - ctx.gl.get_shader_info_log(vert) - )); - } - ctx.gl.attach_shader(program, vert); - - let frag = ctx.gl.create_shader(glow::FRAGMENT_SHADER)?; - ctx.gl.shader_source(frag, fsrc); - ctx.gl.compile_shader(frag); - if !ctx.gl.get_shader_compile_status(frag) { - return Err(format!( - "failed to compile fragment shader:\n{}", - ctx.gl.get_shader_info_log(frag) - )); - } - ctx.gl.attach_shader(program, frag); - - ctx.gl.bind_attrib_location(program, mesh::ATTRIB_VERTEX, "vertex"); - ctx.gl.bind_attrib_location(program, mesh::ATTRIB_NORMAL, "normal"); - ctx.gl.bind_attrib_location(program, mesh::ATTRIB_TEXCOORD, "texcoord"); - ctx.gl.bind_attrib_location(program, mesh::ATTRIB_JOINT, "joint"); - ctx.gl.bind_attrib_location(program, mesh::ATTRIB_WEIGHT, "weight"); - ctx.gl.bind_attrib_location(program, mesh::ATTRIB_COLOR, "color"); - - ctx.gl.link_program(program); - if !ctx.gl.get_program_link_status(program) { - return Err(format!( - "failed to link shader program:\n{}", - ctx.gl.get_program_info_log(program), - )); - } - - ctx.gl.detach_shader(program, vert); - ctx.gl.delete_shader(vert); - ctx.gl.detach_shader(program, frag); - ctx.gl.delete_shader(frag); - - ctx.gl.use_program(Some(program)); - - let mut uniforms = HashMap::new(); - for index in 0..ctx.gl.get_active_uniforms(program) { - if let Some(active) = ctx.gl.get_active_uniform(program, index) { - if let Some(loc) = ctx.gl.get_uniform_location(program, &active.name) { - uniforms.insert(active.name, loc); - } else { - log::warn!("failed to get location for uniform: {}", active.name); - } - } else { - log::warn!("failed to get active uniform for index: {}", index); - } - } - - Ok(Self { - program, - uniforms: std::rc::Rc::new(uniforms), - }) - } - } - - pub fn new_nolib(ctx: &context::Context, vsrc: &str, fsrc: &str) -> Self { - match Self::new_helper(ctx, vsrc, fsrc) { - Ok(x) => x, - Err(e) => panic!("failed to load no-library shader: {}", e) - } - } - - pub fn new(ctx: &context::Context, vsrcstr: &str, fsrcstr: &str) -> Self { - let vsrc = format!("{}\n{}\n", COMMON_VERT, vsrcstr); - let fsrc = format!("{}\n{}\n", COMMON_FRAG, fsrcstr); - Self::new_nolib(ctx, &vsrc, &fsrc) - } - - pub fn delete(&mut self, ctx: &context::Context) { - unsafe { ctx.gl.delete_program(self.program); } - } - - pub fn replace(&mut self, ctx: &context::Context, vsrc: &str, fsrc: &str) -> Result<(), String> { - self.delete(ctx); - *self = Self::new_helper(ctx, vsrc, fsrc)?; - Ok(()) - } - - pub fn set_i32(&self, ctx: &context::Context, name: &str, val: i32) { - if let Some(loc) = self.uniforms.get(name) { - unsafe { ctx.gl.uniform_1_i32(Some(loc), val) } - } - } - - pub fn set_i32_array(&self, ctx: &context::Context, name: &str, val: &[i32]) { - if let Some(loc) = self.uniforms.get(name) { - unsafe { - ctx.gl.uniform_1_i32_slice(Some(loc), val) - } - } - } - - pub fn set_f32(&self, ctx: &context::Context, name: &str, val: f32) { - if let Some(loc) = self.uniforms.get(name) { - unsafe { ctx.gl.uniform_1_f32(Some(loc), val) } - } - } - - pub fn set_vec2(&self, ctx: &context::Context, name: &str, val: &glam::Vec2) { - if let Some(loc) = self.uniforms.get(name) { - unsafe { - ctx.gl.uniform_2_f32( - Some(loc), - val.x, - val.y, - ); - } - } - } - - pub fn set_vec2_array(&self, ctx: &context::Context, name: &str, val: &[glam::Vec2]) { - if let Some(loc) = self.uniforms.get(name) { - let vs: Vec = val.iter().flat_map(|v| [v.x, v.y]).collect(); - unsafe { - ctx.gl.uniform_2_f32_slice( - Some(loc), - &vs, - ); - } - } - } - - pub fn set_vec3(&self, ctx: &context::Context, name: &str, val: &glam::Vec3) { - if let Some(loc) = self.uniforms.get(name) { - unsafe { - ctx.gl.uniform_3_f32( - Some(loc), - val.x, - val.y, - val.z, - ); - } - } - } - - pub fn set_vec3_array(&self, ctx: &context::Context, name: &str, val: &[glam::Vec3]) { - if let Some(loc) = self.uniforms.get(name) { - let vs: Vec = val.iter().flat_map(|v| [v.x, v.y, v.z]).collect(); - unsafe { - ctx.gl.uniform_3_f32_slice( - Some(loc), - &vs, - ); - } - } - } - - pub fn set_vec4(&self, ctx: &context::Context, name: &str, val: &glam::Vec4) { - if let Some(loc) = self.uniforms.get(name) { - unsafe { - ctx.gl.uniform_4_f32( - Some(loc), - val.x, - val.y, - val.z, - val.w, - ); - } - } - } - - pub fn set_mat4(&self, ctx: &context::Context, name: &str, val: &glam::Mat4) { - if let Some(loc) = self.uniforms.get(name) { - unsafe { - ctx.gl.uniform_matrix_4_f32_slice( - Some(loc), - false, - &val.to_cols_array(), - ); - } - } - } - - pub fn set_mat4_array(&self, ctx: &context::Context, name: &str, val: &[glam::Mat4]) { - if let Some(loc) = self.uniforms.get(name) { - let vs: Vec = val.iter().flat_map(|m| m.to_cols_array()).collect(); - unsafe { - ctx.gl.uniform_matrix_4_f32_slice( - Some(loc), - false, - &vs, - ); - } - } - } - - pub fn set_position_3d(&self, ctx: &context::Context, _st: &state::State, position: &glam::Mat4) { - self.set_mat4(ctx, "position", position); - self.set_mat4(ctx, "normal_matrix", &position.inverse().transpose()); - } - - pub fn set_position_2d_mat(&self, ctx: &context::Context, st: &state::State, position: &glam::Mat4) { - self.set_mat4(ctx, "position", position); - } - - pub fn set_position_2d_helper(&self, ctx: &context::Context, st: &state::State, pos: &glam::Vec2, dims: &glam::Vec2, rot: &glam::Quat) { - let halfwidth = dims.x / 2.0; - let halfheight = dims.y / 2.0; - self.set_mat4( - ctx, "position", - &glam::Mat4::from_scale_rotation_translation( - glam::Vec3::new(halfwidth, halfheight, 1.0), - *rot, - glam::Vec3::new( - -st.render_dims.x / 2.0 + pos.x + halfwidth, - st.render_dims.y / 2.0 - pos.y - halfheight, - 0.0, - ), - ) - ); - } - - pub fn set_position_2d(&self, ctx: &context::Context, st: &state::State, pos: &glam::Vec2, dims: &glam::Vec2) { - self.set_position_2d_helper(ctx, st, pos, dims, &glam::Quat::IDENTITY) - } - - pub fn set_position_text_bitmap(&self, - ctx: &context::Context, st: &state::State, - font: &font::Bitmap, - pos: &glam::Vec2 - ) { - let dims = glam::Vec2::new(font.char_width as f32, font.char_height as f32); - self.set_position_2d_helper(ctx, st, pos, &dims, &glam::Quat::IDENTITY) - } - - pub fn bind(&self, ctx: &context::Context) { - unsafe { - ctx.gl.use_program(Some(self.program)); - } - } -} diff --git a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/shadow.rs b/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/shadow.rs deleted file mode 100644 index 8482179..0000000 --- a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/shadow.rs +++ /dev/null @@ -1,127 +0,0 @@ -use glow::HasContext; - -use crate::context; - -pub struct ShadowBuffer { - pub fbo: glow::Framebuffer, - pub depth_tex: glow::Texture, - pub width: i32, - pub height: i32, -} - -impl ShadowBuffer { - pub fn new(ctx: &context::Context, w: i32, h: i32) -> Self { - unsafe { - // generate and bind FBO - let fbo = ctx.gl.create_framebuffer().expect("failed to create framebuffer"); - ctx.gl.bind_framebuffer(glow::FRAMEBUFFER, Some(fbo)); - - // generate and attach depth buffer - let depth_tex = ctx.gl.create_texture().expect("failed to create texture"); - ctx.gl.bind_texture(glow::TEXTURE_2D, Some(depth_tex)); - ctx.gl.tex_image_2d( - glow::TEXTURE_2D, - 0, - glow::DEPTH_COMPONENT as i32, - w, - h, - 0, - glow::DEPTH_COMPONENT, - glow::FLOAT, - None, - ); - ctx.gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_MIN_FILTER, glow::LINEAR as i32); - ctx.gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_MAG_FILTER, glow::LINEAR as i32); - ctx.gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_WRAP_S, glow::CLAMP_TO_BORDER as i32); - ctx.gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_WRAP_T, glow::CLAMP_TO_BORDER as i32); - ctx.gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_COMPARE_MODE, glow::COMPARE_REF_TO_TEXTURE as i32); - ctx.gl.tex_parameter_f32_slice(glow::TEXTURE_2D, glow::TEXTURE_BORDER_COLOR, &[1.0, 1.0, 1.0, 1.0]); - ctx.gl.framebuffer_texture_2d(glow::FRAMEBUFFER, glow::DEPTH_ATTACHMENT, glow::TEXTURE_2D, Some(depth_tex), 0); - ctx.gl.draw_buffer(glow::NONE); - ctx.gl.read_buffer(glow::NONE); - - let status = ctx.gl.check_framebuffer_status(glow::FRAMEBUFFER); - if status != glow::FRAMEBUFFER_COMPLETE { - panic!("error initializing framebuffer: {}", status); - } - Self { - fbo, - depth_tex, - width: w, - height: h, - } - } - } - - pub fn bind(&self, ctx: &context::Context) { - unsafe { - ctx.gl.bind_framebuffer(glow::FRAMEBUFFER, Some(self.fbo)); - ctx.gl.viewport(0, 0, self.width as _, self.height as _); - ctx.gl.clear(glow::DEPTH_BUFFER_BIT); - - } - } -} - -pub struct ShadowBuffer3D { - pub fbo: glow::Framebuffer, - pub depth_cubemap: glow::Texture, - pub width: i32, - pub height: i32, -} - -impl ShadowBuffer3D { - pub fn new(ctx: &context::Context, w: i32, h: i32) -> Self { - unsafe { - // generate and bind FBO - let fbo = ctx.gl.create_framebuffer().expect("failed to create framebuffer"); - ctx.gl.bind_framebuffer(glow::FRAMEBUFFER, Some(fbo)); - - // generate and attach depth buffer - let depth_cubemap = ctx.gl.create_texture().expect("failed to create texture"); - ctx.gl.bind_texture(glow::TEXTURE_CUBE_MAP, Some(depth_cubemap)); - for i in 0..6 { - ctx.gl.tex_image_2d( - glow::TEXTURE_CUBE_MAP_POSITIVE_X + i, - 0, - glow::DEPTH_COMPONENT as i32, - w, - h, - 0, - glow::DEPTH_COMPONENT, - glow::FLOAT, - None, - ); - ctx.gl.tex_parameter_i32(glow::TEXTURE_CUBE_MAP, glow::TEXTURE_MIN_FILTER, glow::LINEAR as i32); - ctx.gl.tex_parameter_i32(glow::TEXTURE_CUBE_MAP, glow::TEXTURE_MAG_FILTER, glow::LINEAR as i32); - ctx.gl.tex_parameter_i32(glow::TEXTURE_CUBE_MAP, glow::TEXTURE_WRAP_S, glow::CLAMP_TO_EDGE as i32); - ctx.gl.tex_parameter_i32(glow::TEXTURE_CUBE_MAP, glow::TEXTURE_WRAP_T, glow::CLAMP_TO_EDGE as i32); - ctx.gl.tex_parameter_i32(glow::TEXTURE_CUBE_MAP, glow::TEXTURE_WRAP_R, glow::CLAMP_TO_EDGE as i32); - } - - ctx.gl.framebuffer_texture(glow::FRAMEBUFFER, glow::DEPTH_ATTACHMENT, Some(depth_cubemap), 0); - ctx.gl.draw_buffer(glow::NONE); - ctx.gl.read_buffer(glow::NONE); - - let status = ctx.gl.check_framebuffer_status(glow::FRAMEBUFFER); - if status != glow::FRAMEBUFFER_COMPLETE { - panic!("error initializing framebuffer: {}", status); - } - Self { - fbo, - depth_cubemap, - width: w, - height: h, - } - } - } - - pub fn bind(&self, ctx: &context::Context) { - unsafe { - ctx.gl.bind_framebuffer(glow::FRAMEBUFFER, Some(self.fbo)); - ctx.gl.viewport(0, 0, self.width as _, self.height as _); - ctx.gl.clear(glow::DEPTH_BUFFER_BIT); - - } - } -} diff --git a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/state.rs b/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/state.rs deleted file mode 100644 index 3353f33..0000000 --- a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/state.rs +++ /dev/null @@ -1,735 +0,0 @@ -#![allow(dead_code, unused_variables)] -use bimap::BiHashMap; -use enum_map::{Enum, EnumMap, enum_map}; -use serde::{Deserialize, Serialize}; -use std::{collections::HashMap, fmt::Display}; -use strum::EnumIter; - -#[cfg(not(target_arch = "wasm32"))] -use glow::HasContext; - -use crate::{audio, context, font, framebuffer, mesh, shader, utils}; - -pub type Tick = u64; - -const DELTA_TIME: f64 = 0.016; // todo - -pub const ORTH_WIDTH: f32 = 7.55869; -pub const ORTH_HEIGHT: f32 = 5.03913; - -pub trait Game { - fn initialize(&mut self, ctx: &context::Context, st: &mut State) -> utils::Erm<()> { - Ok(()) - } - fn finalize(&mut self, ctx: &context::Context, st: &mut State) -> utils::Erm<()> { - Ok(()) - } - fn initialize_audio( - &self, - ctx: &context::Context, - st: &State, - actx: &audio::Context, - ) -> HashMap { - HashMap::new() - } - fn keybindings_were_reset(&mut self, ctx: &context::Context, st: &mut State) -> utils::Erm<()> { - Ok(()) - } - fn mouse_move( - &mut self, - ctx: &context::Context, - st: &mut State, - x: i32, - y: i32, - ) -> utils::Erm<()> { - Ok(()) - } - fn mouse_press(&mut self, ctx: &context::Context, st: &mut State) -> utils::Erm<()> { - Ok(()) - } - fn mouse_released(&mut self, ctx: &context::Context, st: &mut State) -> utils::Erm<()> { - Ok(()) - } - fn update(&mut self, ctx: &context::Context, st: &mut State) -> utils::Erm<()> { - Ok(()) - } - fn render(&mut self, ctx: &context::Context, st: &mut State) -> utils::Erm<()> { - Ok(()) - } -} - -#[derive(Debug, Enum, EnumIter, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] -pub enum Key { - Up, - Down, - Left, - Right, - A, - B, - X, - Y, - L, - R, - Start, - Select, - Debug, -} -#[derive(Default)] -pub struct Keys { - pub pressed: EnumMap, - pub new: EnumMap, -} -impl Keys { - pub fn new() -> Self { - Self::default() - } - pub fn up(&self) -> bool { - self.pressed[Key::Up] - } - pub fn down(&self) -> bool { - self.pressed[Key::Down] - } - pub fn left(&self) -> bool { - self.pressed[Key::Left] - } - pub fn right(&self) -> bool { - self.pressed[Key::Right] - } - pub fn a(&self) -> bool { - self.pressed[Key::A] - } - pub fn b(&self) -> bool { - self.pressed[Key::B] - } - pub fn x(&self) -> bool { - self.pressed[Key::X] - } - pub fn y(&self) -> bool { - self.pressed[Key::Y] - } - pub fn l(&self) -> bool { - self.pressed[Key::L] - } - pub fn r(&self) -> bool { - self.pressed[Key::R] - } - pub fn start(&self) -> bool { - self.pressed[Key::Start] - } - pub fn select(&self) -> bool { - self.pressed[Key::Select] - } - pub fn debug(&self) -> bool { - self.pressed[Key::Debug] - } - pub fn new_up(&mut self) -> bool { - let ret = self.new[Key::Up]; - self.new[Key::Up] = false; - ret - } - pub fn new_down(&mut self) -> bool { - let ret = self.new[Key::Down]; - self.new[Key::Down] = false; - ret - } - pub fn new_left(&mut self) -> bool { - let ret = self.new[Key::Left]; - self.new[Key::Left] = false; - ret - } - pub fn new_right(&mut self) -> bool { - let ret = self.new[Key::Right]; - self.new[Key::Right] = false; - ret - } - pub fn new_a(&mut self) -> bool { - let ret = self.new[Key::A]; - self.new[Key::A] = false; - ret - } - pub fn new_b(&mut self) -> bool { - let ret = self.new[Key::B]; - self.new[Key::B] = false; - ret - } - pub fn new_x(&mut self) -> bool { - let ret = self.new[Key::X]; - self.new[Key::X] = false; - ret - } - pub fn new_y(&mut self) -> bool { - let ret = self.new[Key::Y]; - self.new[Key::Y] = false; - ret - } - pub fn new_l(&mut self) -> bool { - let ret = self.new[Key::L]; - self.new[Key::L] = false; - ret - } - pub fn new_r(&mut self) -> bool { - let ret = self.new[Key::R]; - self.new[Key::R] = false; - ret - } - pub fn new_start(&mut self) -> bool { - let ret = self.new[Key::Start]; - self.new[Key::Start] = false; - ret - } - pub fn new_select(&mut self) -> bool { - let ret = self.new[Key::Select]; - self.new[Key::Select] = false; - ret - } - pub fn new_debug(&mut self) -> bool { - let ret = self.new[Key::Debug]; - self.new[Key::Debug] = false; - ret - } -} - -pub struct PointLight { - pub pos: glam::Vec3, - pub color: glam::Vec3, - pub attenuation: glam::Vec2, -} - -type Timestamp = f64; - -#[cfg(target_arch = "wasm32")] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct Keycode { - pub kc: winit::keyboard::KeyCode, -} -#[cfg(target_arch = "wasm32")] -impl Keycode { - pub fn new(kc: winit::keyboard::KeyCode) -> Self { - Self { kc } - } -} -#[cfg(target_arch = "wasm32")] -impl Display for Keycode { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{:?}", self.kc) - } -} -#[cfg(target_arch = "wasm32")] -impl Serialize for Keycode { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - self.kc.serialize(serializer) - } -} -#[cfg(target_arch = "wasm32")] -impl<'de> Deserialize<'de> for Keycode { - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - let kc = winit::keyboard::KeyCode::deserialize(deserializer)?; - Ok(Self { kc }) - } -} - -#[cfg(not(target_arch = "wasm32"))] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct Keycode { - pub kc: glfw::Key, -} -#[cfg(not(target_arch = "wasm32"))] -impl Keycode { - pub fn new(kc: glfw::Key) -> Self { - Self { kc } - } -} -#[cfg(not(target_arch = "wasm32"))] -impl Display for Keycode { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{:?}", self.kc) - } -} -#[cfg(not(target_arch = "wasm32"))] -impl Serialize for Keycode { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - (self.kc as i32).serialize(serializer) - } -} -#[cfg(not(target_arch = "wasm32"))] -impl<'de> Deserialize<'de> for Keycode { - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - i32::deserialize(deserializer).map(|x| unsafe { std::mem::transmute(x) }) - } -} - -pub struct State { - pub tick: Tick, - pub nextframe: Timestamp, - pub fps: u32, - pub frames_this_second: u32, - pub start_this_second: Timestamp, - - pub rebinding: Option, - pub keybindings: BiHashMap, - pub keys: Keys, - - pub screen: framebuffer::Framebuffer, - pub render_framebuffer: framebuffer::Framebuffer, - pub render_dims: glam::Vec2, - pub shader_upscale: shader::Shader, - pub shader_text_bitmap: shader::Shader, - pub mesh_square: mesh::Mesh, - pub font_default: font::Bitmap, - pub font_small: font::Bitmap, - pub audio: Option, - - pub projection: glam::Mat4, - pub projection_orth: glam::Mat4, - pub camera: (glam::Vec3, glam::Vec3, glam::Vec3), - pub lighting: (glam::Vec3, glam::Vec3, glam::Vec3), - pub point_lights: Vec, -} - -#[cfg(target_arch = "wasm32")] -pub fn now(ctx: &context::Context) -> Timestamp { - ctx.performance.now() / 1000.0 -} - -#[cfg(not(target_arch = "wasm32"))] -pub fn now(ctx: &context::Context) -> Timestamp { - let elapsed = ctx.start_instant.elapsed(); - let ms = elapsed.as_millis(); - (ms as f64) / 1000.0 -} - -#[cfg(target_arch = "wasm32")] -pub fn default_keybindings() -> BiHashMap { - BiHashMap::from_iter(vec![ - (Keycode::new(winit::keyboard::KeyCode::KeyW), Key::Up), - (Keycode::new(winit::keyboard::KeyCode::KeyS), Key::Down), - (Keycode::new(winit::keyboard::KeyCode::KeyA), Key::Left), - (Keycode::new(winit::keyboard::KeyCode::KeyD), Key::Right), - (Keycode::new(winit::keyboard::KeyCode::Digit1), Key::A), - (Keycode::new(winit::keyboard::KeyCode::Digit2), Key::B), - (Keycode::new(winit::keyboard::KeyCode::Digit3), Key::X), - (Keycode::new(winit::keyboard::KeyCode::Digit4), Key::Y), - (Keycode::new(winit::keyboard::KeyCode::KeyQ), Key::L), - (Keycode::new(winit::keyboard::KeyCode::KeyE), Key::R), - (Keycode::new(winit::keyboard::KeyCode::Tab), Key::Start), - (Keycode::new(winit::keyboard::KeyCode::Space), Key::Select), - ( - Keycode::new(winit::keyboard::KeyCode::Backquote), - Key::Debug, - ), - ]) -} - -#[cfg(not(target_arch = "wasm32"))] -pub fn default_keybindings() -> BiHashMap { - BiHashMap::from_iter(vec![ - (Keycode::new(glfw::Key::W), Key::Up), - (Keycode::new(glfw::Key::S), Key::Down), - (Keycode::new(glfw::Key::A), Key::Left), - (Keycode::new(glfw::Key::D), Key::Right), - (Keycode::new(glfw::Key::Num1), Key::A), - (Keycode::new(glfw::Key::Num2), Key::B), - (Keycode::new(glfw::Key::Num3), Key::X), - (Keycode::new(glfw::Key::Num4), Key::Y), - (Keycode::new(glfw::Key::Q), Key::L), - (Keycode::new(glfw::Key::E), Key::R), - (Keycode::new(glfw::Key::Tab), Key::Start), - (Keycode::new(glfw::Key::Space), Key::Select), - (Keycode::new(glfw::Key::GraveAccent), Key::Debug), - ]) -} - -impl State { - pub fn new(ctx: &context::Context) -> Self { - let screen = framebuffer::Framebuffer::screen(ctx); - let render_framebuffer = framebuffer::Framebuffer::new( - ctx, - &glam::Vec2::new(ctx.render_width, ctx.render_height), - &glam::Vec2::new(0.0, 0.0), - ); - let shader_upscale = shader::Shader::new_nolib( - ctx, - include_str!("assets/shaders/scale/vert.glsl"), - include_str!("assets/shaders/scale/frag.glsl"), - ); - let shader_text_bitmap = shader::Shader::new_nolib( - ctx, - include_str!("assets/shaders/bitmap/vert.glsl"), - include_str!("assets/shaders/bitmap/frag.glsl"), - ); - let mesh_square = mesh::Mesh::from_obj(ctx, include_bytes!("assets/meshes/square.obj")); - - let nextframe = now(ctx); - - Self { - // we initialize the tick to 1000, which allows us to use "0" as the default time for - // various animation starts on entities without having them all play at game start - tick: 1000, - - nextframe, - fps: 0, - frames_this_second: 0, - start_this_second: nextframe, - - rebinding: None, - keybindings: default_keybindings(), - keys: Keys::new(), - - screen, - render_framebuffer, - render_dims: glam::Vec2::new(ctx.render_width, ctx.render_height), - shader_upscale, - shader_text_bitmap, - mesh_square, - font_default: font::Bitmap::default(ctx), - font_small: font::Bitmap::small(ctx), - audio: None, - - projection: glam::Mat4::perspective_lh( - std::f32::consts::PI / 4.0, - ctx.render_width / ctx.render_height, - // 0.1, - 0.5, - 50.0, - ), - projection_orth: glam::Mat4::orthographic_lh( - -ORTH_WIDTH, - ORTH_WIDTH, - -ORTH_HEIGHT, - ORTH_HEIGHT, - 0.5, - 50.0, - ), - camera: ( - glam::Vec3::new(0.0, 0.0, 0.0), - glam::Vec3::new(0.0, 0.0, 1.0), - glam::Vec3::new(0.0, 1.0, 0.0), - ), - lighting: ( - glam::Vec3::new(1.0, 1.0, 1.0), - glam::Vec3::new(1.0, 1.0, 1.0), - glam::Vec3::new(1.0, -1.0, 1.0), - ), - point_lights: Vec::new(), - // waker_ctx, - // http_client: reqwest::Client::new(), - // request: None, - } - } - - pub fn handle_resize(&mut self, ctx: &context::Context) { - self.screen = framebuffer::Framebuffer::screen(ctx); - } - - pub fn move_camera( - &mut self, - _ctx: &context::Context, - pos: &glam::Vec3, - dir: &glam::Vec3, - up: &glam::Vec3, - ) { - self.camera = (*pos, *dir, *up); - } - - pub fn bind_framebuffer(&mut self, ctx: &context::Context, fb: &framebuffer::Framebuffer) { - fb.bind(ctx); - self.render_dims = fb.dims; - } - - pub fn bind_render_framebuffer(&mut self, ctx: &context::Context) { - self.render_framebuffer.bind(ctx); - self.render_dims = self.render_framebuffer.dims; - } - - pub fn bind_screen(&mut self, ctx: &context::Context) { - self.screen.bind(ctx); - self.render_dims = self.screen.dims; - } - - pub fn set_lighting( - &mut self, - _ctx: &context::Context, - ambient: &glam::Vec3, - color: &glam::Vec3, - dir: &glam::Vec3, - ) { - self.lighting = (*ambient, *color, *dir); - } - - pub fn add_point_light( - &mut self, - _ctx: &context::Context, - pos: &glam::Vec3, - color: &glam::Vec3, - attenuation: &glam::Vec2, - ) { - self.point_lights.push(PointLight { - pos: *pos, - color: *color, - attenuation: *attenuation, - }); - } - - pub fn clear_point_lights(&mut self, _ctx: &context::Context) { - self.point_lights.clear(); - } - - pub fn view(&self) -> glam::Mat4 { - glam::Mat4::look_to_lh(self.camera.0, self.camera.1, self.camera.2) - } - - pub fn bind_3d_helper( - &self, - ctx: &context::Context, - shader: &shader::Shader, - plc: usize, - orth: bool, - ) { - shader.bind(ctx); - shader.set_mat4( - ctx, - "projection", - if orth { - &self.projection_orth - } else { - &self.projection - }, - ); - shader.set_mat4(ctx, "view", &self.view()); - shader.set_vec3(ctx, "light_ambient_color", &self.lighting.0); - shader.set_vec3(ctx, "light_dir_color", &self.lighting.1); - shader.set_vec3(ctx, "light_dir", &self.lighting.2.normalize()); - shader.set_i32(ctx, "light_count", plc as _); - } - - pub fn bind_3d_no_point_lights(&self, ctx: &context::Context, shader: &shader::Shader) { - self.bind_3d_helper(ctx, shader, 0, false); - } - - pub fn bind_3d_with_point_lights( - &self, - ctx: &context::Context, - shader: &shader::Shader, - orth: bool, - ) { - let plc = self.point_lights.len().min(5); - self.bind_3d_helper(ctx, shader, plc, orth); - if plc > 0 { - let lpos: Vec<_> = self.point_lights.iter().take(plc).map(|l| l.pos).collect(); - shader.set_vec3_array(ctx, "light_pos[0]", &lpos); - let lcolor: Vec<_> = self - .point_lights - .iter() - .take(plc) - .map(|l| l.color) - .collect(); - shader.set_vec3_array(ctx, "light_color[0]", &lcolor); - let lattenuation: Vec<_> = self - .point_lights - .iter() - .take(plc) - .map(|l| l.attenuation) - .collect(); - shader.set_vec2_array(ctx, "light_attenuation[0]", &lattenuation); - } - } - - pub fn bind_3d(&self, ctx: &context::Context, shader: &shader::Shader) { - self.bind_3d_with_point_lights(ctx, shader, false) - } - - pub fn bind_3d_orth(&self, ctx: &context::Context, shader: &shader::Shader) { - self.bind_3d_with_point_lights(ctx, shader, true) - } - - pub fn bind_2d(&self, ctx: &context::Context, shader: &shader::Shader) { - shader.bind(ctx); - shader.set_mat4(ctx, "projection", &glam::Mat4::IDENTITY); - shader.set_mat4( - ctx, - "view", - &glam::Mat4::from_scale(glam::Vec3::new( - 2.0 / ctx.render_width, - 2.0 / ctx.render_height, - 1.0, - )), - ); - } - - pub fn initialize_audio(&mut self, ctx: &context::Context, game: &mut G) -> utils::Erm<()> - where - G: Game, - { - if self.audio.is_none() { - self.audio = Some(audio::Assets::new(|actx| { - game.initialize_audio(ctx, self, actx) - })); - } - Ok(()) - } - - pub fn mouse_moved( - &mut self, - ctx: &context::Context, - x: f32, - y: f32, - game: &mut G, - ) -> utils::Erm<()> - where - G: Game, - { - if ctx.options.contains(crate::Options::FULLSCREEN_MOUSE) { - game.mouse_move( - ctx, - self, - (x * ctx.render_width / self.screen.dims.x) as i32, - (y * ctx.render_height / self.screen.dims.y) as i32, - )?; - } else { - let rx = ((x - self.screen.offsets.x) * ctx.render_width / self.screen.dims.x) as i32; - let ry = ((y - self.screen.offsets.y) * ctx.render_height / self.screen.dims.y) as i32; - if !(rx < 0 - || rx >= ctx.render_width as i32 - || ry < 0 - || ry >= ctx.render_height as i32) - { - game.mouse_move(ctx, self, rx, ry)?; - } - } - Ok(()) - } - - pub fn mouse_pressed(&mut self, ctx: &context::Context, game: &mut G) -> utils::Erm<()> - where - G: Game, - { - self.initialize_audio(ctx, game)?; - game.mouse_press(ctx, self)?; - Ok(()) - } - - pub fn mouse_released(&mut self, ctx: &context::Context, game: &mut G) -> utils::Erm<()> - where - G: Game, - { - game.mouse_released(ctx, self)?; - Ok(()) - } - - pub fn key_pressed( - &mut self, - ctx: &context::Context, - game: &mut G, - key: Keycode, - ) -> utils::Erm<()> - where - G: Game, - { - #[cfg(target_arch = "wasm32")] - let rebind = key.kc == winit::keyboard::KeyCode::F12; - #[cfg(not(target_arch = "wasm32"))] - let rebind = key.kc == glfw::Key::F12; - if rebind { - self.keybindings = default_keybindings(); - self.rebinding = None; - game.keybindings_were_reset(ctx, self)?; - } else if let Some(k) = self.rebinding { - self.keybindings.insert(key, k); - self.rebinding = None; - } else if let Some(k) = self.keybindings.get_by_left(&key) { - self.keys.pressed[*k] = true; - self.keys.new[*k] = true; - } - Ok(()) - } - - pub fn key_released( - &mut self, - _ctx: &context::Context, - _game: &mut G, - key: Keycode, - ) -> utils::Erm<()> - where - G: Game, - { - if let Some(k) = self.keybindings.get_by_left(&key) { - self.keys.pressed[*k] = false; - } - Ok(()) - } - - /// Return the first keybinding for the given virtual key - pub fn keybinding_for(&self, k: Key) -> Option { - self.keybindings - .get_by_right(&k) - .map(|kc| format!("{}", kc)) - } - - pub fn rebind_key(&mut self, k: Key) { - self.rebinding = Some(k); - } - - pub fn run_update(&mut self, ctx: &context::Context, game: &mut G) -> utils::Erm<()> - where - G: Game, - { - let now = now(ctx); - if now > self.nextframe { - while self.nextframe < now { - // find the next target frame that isn't in the past - self.nextframe += DELTA_TIME; - } - self.tick += 1; - self.frames_this_second += 1; - game.update(ctx, self)?; - self.keys.new = enum_map! { _ => false }; - } - if now - self.start_this_second > 1.0 { - // track FPS - self.start_this_second = now; - self.fps = self.frames_this_second; - self.frames_this_second = 0; - } - Ok(()) - } - - pub fn run_render(&mut self, ctx: &context::Context, game: &mut G) -> utils::Erm<()> - where - G: Game, - { - self.bind_screen(ctx); - ctx.clear_color(if ctx.options.contains(crate::Options::OVERLAY) { - glam::Vec4::new(0.0, 0.0, 0.0, 0.0) - } else { - glam::Vec4::new(0.0, 0.0, 0.0, 1.0) - }); - ctx.clear(); - - game.render(ctx, self)?; - - #[cfg(all(debug_assertions, not(target_arch = "wasm32")))] - { - let err = unsafe { ctx.gl.get_error() }; - if err != glow::NO_ERROR { - log::warn!("opengl error: {}", err); - } - // let log = unsafe { ctx.gl.get_debug_message_log(5) }; - // for m in log { - // log::warn!("opengl debug message: {:?}", m); - // } - } - Ok(()) - } -} diff --git a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/texture.rs b/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/texture.rs deleted file mode 100644 index b9749a2..0000000 --- a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/texture.rs +++ /dev/null @@ -1,156 +0,0 @@ -use glow::HasContext; -use image::EncodableLayout; - -use crate::context; - -pub struct Texture { - pub tex: glow::Texture, - pub width: i32, - pub height: i32, -} - -impl Texture { - pub fn new_empty(ctx: &context::Context) -> Self { - unsafe { - let tex = ctx.gl.create_texture().expect("failed to create texture"); - ctx.gl.bind_texture(glow::TEXTURE_2D, Some(tex)); - ctx.gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_WRAP_S, glow::CLAMP_TO_EDGE as i32); - ctx.gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_WRAP_T, glow::CLAMP_TO_EDGE as i32); - ctx.gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_MIN_FILTER, glow::NEAREST as i32); - ctx.gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_MAG_FILTER, glow::NEAREST as i32); - Self { - tex, - width: 0, height: 0, - } - } - } - - pub fn new(ctx: &context::Context, bytes: &[u8]) -> Self { - let rgba = image::ImageReader::new(std::io::Cursor::new(bytes)) - .with_guessed_format() - .expect("failed to guess image format") - .decode() - .expect("failed to decode image") - .into_rgba8(); - let pixels = rgba.as_bytes(); - unsafe { - let tex = ctx.gl.create_texture().expect("failed to create texture"); - ctx.gl.bind_texture(glow::TEXTURE_2D, Some(tex)); - ctx.gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_WRAP_S, glow::CLAMP_TO_EDGE as i32); - ctx.gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_WRAP_T, glow::CLAMP_TO_EDGE as i32); - ctx.gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_MIN_FILTER, glow::NEAREST as i32); - ctx.gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_MAG_FILTER, glow::NEAREST as i32); - ctx.gl.tex_image_2d( - glow::TEXTURE_2D, - 0, - glow::RGBA as i32, - rgba.width() as i32, - rgba.height() as i32, - 0, - glow::RGBA, - glow::UNSIGNED_BYTE, - Some(pixels), - ); - ctx.gl.generate_mipmap(glow::TEXTURE_2D); - - Self { - tex, - width: rgba.width() as i32, - height: rgba.height() as i32, - } - } - } - - pub fn upload(&mut self, ctx: &context::Context, bytes: &[u8]) { - let rgba = image::ImageReader::new(std::io::Cursor::new(bytes)) - .with_guessed_format() - .expect("failed to guess image format") - .decode() - .expect("failed to decode image") - .into_rgba8(); - let pixels = rgba.as_bytes(); - self.upload_rgba8(ctx, rgba.width() as i32, rgba.height() as i32, pixels); - } - - pub fn upload_rgba8(&mut self, ctx: &context::Context, width: i32, height: i32, data: &[u8]) { - unsafe { - ctx.gl.bind_texture(glow::TEXTURE_2D, Some(self.tex)); - ctx.gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_WRAP_S, glow::CLAMP_TO_EDGE as i32); - ctx.gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_WRAP_T, glow::CLAMP_TO_EDGE as i32); - ctx.gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_MIN_FILTER, glow::NEAREST as i32); - ctx.gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_MAG_FILTER, glow::NEAREST as i32); - ctx.gl.tex_image_2d( - glow::TEXTURE_2D, - 0, - glow::RGBA as i32, - width, - height, - 0, - glow::RGBA, - glow::UNSIGNED_BYTE, - Some(data), - ); - ctx.gl.generate_mipmap(glow::TEXTURE_2D); - } - self.width = width; - self.height = height; - } - - pub fn set_repeat(&self, ctx: &context::Context) { - unsafe { - ctx.gl.bind_texture(glow::TEXTURE_2D, Some(self.tex)); - ctx.gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_WRAP_S, glow::REPEAT as i32); - ctx.gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_WRAP_T, glow::REPEAT as i32); - } - } - - pub fn set_anisotropic_filtering(&self, ctx: &context::Context) { - unsafe { - ctx.gl.bind_texture(glow::TEXTURE_2D, Some(self.tex)); - ctx.gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_WRAP_S, glow::REPEAT as i32); - ctx.gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_WRAP_T, glow::REPEAT as i32); - ctx.gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_MIN_FILTER, glow::LINEAR_MIPMAP_LINEAR as i32); - ctx.gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_MAG_FILTER, glow::LINEAR as i32); - ctx.gl.tex_parameter_f32(glow::TEXTURE_2D, glow::TEXTURE_MAX_ANISOTROPY_EXT, 4.0); - } - } - - pub fn bind(&self, ctx: &context::Context) { - unsafe { - ctx.gl.active_texture(glow::TEXTURE0); - ctx.gl.bind_texture(glow::TEXTURE_2D, Some(self.tex)); - } - } - - pub fn bind_initial(ctx: &context::Context) { - unsafe { - ctx.gl.active_texture(glow::TEXTURE0); - ctx.gl.bind_texture(glow::TEXTURE_2D, None); - } - } - - pub fn bind_index(&self, ctx: &context::Context, idx: u32) { - unsafe { - ctx.gl.active_texture(glow::TEXTURE0 + idx); - ctx.gl.bind_texture(glow::TEXTURE_2D, Some(self.tex)); - } - } -} - -pub struct Material { - pub color: Texture, - pub normal: Texture, -} -impl Material { - pub fn new(ctx: &context::Context, color_bytes: &[u8], normal_bytes: &[u8]) -> Self { - let color = Texture::new(ctx, color_bytes); - let normal = Texture::new(ctx, normal_bytes); - color.set_anisotropic_filtering(ctx); - normal.set_anisotropic_filtering(ctx); - Self { color, normal } - } - pub fn bind(&self, ctx: &context::Context) { - self.color.bind(ctx); - self.normal.bind_index(ctx, 1); - } -} diff --git a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/ui.rs b/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/ui.rs deleted file mode 100644 index 8607fb6..0000000 --- a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/ui.rs +++ /dev/null @@ -1,169 +0,0 @@ -use crate::{state, utils}; -use crate::state::Tick; - -fn compute_reverse(frames: Tick, tick: Tick, start: Tick) -> Tick { - let leftover = frames - (tick - start) - .clamp(0, frames); - tick - leftover -} - -pub enum ModeToggle { - Inactive { start: Tick }, - Active { start: Tick }, -} - -pub struct Mode { - frames: Tick, - toggle: ModeToggle, -} - -impl Mode { - pub fn new(frames: Tick) -> Self { - Self { - frames, - toggle: ModeToggle::Inactive { start: 0 }, - } - } - - /// Is the current state active? - pub fn is_active(&self) -> bool { - match self.toggle { - ModeToggle::Inactive {..} => false, - ModeToggle::Active {..} => true, - } - } - - /// Has the current transition finished? - pub fn is_ready(&self, tick: Tick) -> bool { - let started = match self.toggle { - ModeToggle::Inactive { start } => start, - ModeToggle::Active { start } => start, - }; - tick - started > self.frames - } - - pub fn progress(&self, tick: Tick) -> f32 { - match self.toggle { - ModeToggle::Inactive { start } => { - 1.0 - (((tick - start) as f32) / self.frames as f32) - .clamp(0.0, 1.0) - }, - ModeToggle::Active { start } => { - (((tick - start) as f32) / self.frames as f32) - .clamp(0.0, 1.0) - } - } - } - - pub fn reset(&mut self) { - self.toggle = ModeToggle::Inactive { start: 0 }; - } - - pub fn toggle(&mut self, tick: Tick) { - match self.toggle { - ModeToggle::Inactive { start } => { - self.toggle = ModeToggle::Active { - start: compute_reverse(self.frames, tick, start) - }; - }, - ModeToggle::Active { start } => { - self.toggle = ModeToggle::Inactive { - start: compute_reverse(self.frames, tick, start) - }; - }, - } - } -} - -pub struct Cursor { - pub index: i32, - pub prev_index: i32, - pub change_started: Tick, - pub bound: i32, - pub frames: Tick, -} - -impl Cursor { - pub fn new(bound: i32, frames: Tick) -> Self { - Self { - index: 0, - prev_index: 0, - change_started: 0, - bound, - frames, - } - } - - pub fn animation_index(&self, tick: Tick) -> f32 { - let progress = ((tick - self.change_started) as f32) - / (self.frames as f32 / 2.0); - utils::lerp( - self.prev_index as f32, - self.index as f32, - progress - ) - } - - pub fn is_ready(&self, tick: Tick) -> bool { - tick - self.change_started > self.frames - } - - pub fn set(&mut self, val: i32, tick: Tick) -> bool { - if self.is_ready(tick) { - self.change_started = tick; - self.prev_index = self.index; - self.index = val; - self.index %= self.bound; - true - } else { false } - } - pub fn increment(&mut self, tick: Tick) -> bool { self.set(self.index + 1, tick) } - pub fn decrement(&mut self, tick: Tick) -> bool { self.set(self.index + self.bound - 1, tick) } - - pub fn set_unlocked(&mut self, val: i32, tick: Tick) { - self.change_started = tick; - self.prev_index = self.index; - self.index = val; - self.index %= self.bound; - } - pub fn increment_unlocked(&mut self, tick: Tick) -> bool { self.set_unlocked(self.index + 1, tick); true } - pub fn decrement_unlocked(&mut self, tick: Tick) -> bool { self.set_unlocked(self.index + self.bound - 1, tick); true } - - /// Read keypresses to update this cursor (assuming that the left/right keys decrement/increment) - /// Returns true if an update was performed (e.g. to determine whether to play a sound). - pub fn update_horizontal(&mut self, st: &mut state::State) -> bool { - if st.keys.new_left() { - self.decrement_unlocked(st.tick) - } else if st.keys.new_right() { - self.increment_unlocked(st.tick) - } else if st.keys.left() { - self.decrement(st.tick) - } else if st.keys.right() { - self.increment(st.tick) - } else { false } - } - - pub fn update_vertical(&mut self, st: &mut state::State) -> bool { - if st.keys.new_up() { - self.decrement_unlocked(st.tick) - } else if st.keys.new_down() { - self.increment_unlocked(st.tick) - } else if st.keys.up() { - self.decrement(st.tick) - } else if st.keys.down() { - self.increment(st.tick) - } else { false } - } - - pub fn update_lr(&mut self, st: &mut state::State) -> bool { - if st.keys.new_l() { - self.decrement_unlocked(st.tick) - } else if st.keys.new_r() { - self.increment_unlocked(st.tick) - } else if st.keys.l() { - self.decrement(st.tick) - } else if st.keys.r() { - self.increment(st.tick) - } else { false } - } -} diff --git a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/utils.rs b/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/utils.rs deleted file mode 100644 index 14a7fdf..0000000 --- a/2026/games/rpc2dot0/vendor/teleia/crates/teleia/src/utils.rs +++ /dev/null @@ -1,147 +0,0 @@ -use std::f32::consts::PI; - -use enum_map::Enum; -use serde::{Serialize, Deserialize}; -use strum::EnumIter; - -pub type Erm = simple_eyre::Result; - -pub fn erm(e: E) -> Erm where E: std::error::Error + std::marker::Send + std::marker::Sync + 'static { - Err(e.into()) -} - -#[derive(Debug)] -pub struct Error { - pub msg: String -} -impl std::fmt::Display for Error { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "teleia error: {}", self.msg) - } -} -impl std::error::Error for Error {} - -pub fn erm_msg(msg: &str) -> Erm { - Err(Error { - msg: msg.to_owned(), - }.into()) -} - -pub struct ErrorHandler; -impl simple_eyre::eyre::EyreHandler for ErrorHandler { - fn debug( - &self, - error: &(dyn std::error::Error + 'static), - f: &mut core::fmt::Formatter<'_>, - ) -> core::fmt::Result { - if f.alternate() { - return core::fmt::Debug::fmt(error, f); - } - let mut first = true; - if let Some(s) = error.source() { - let errors: Vec<_> = std::iter::successors(Some(s), |e| (*e).source()).collect(); - for err in errors.iter().rev() { - writeln!(f)?; write!(f, "{}{}", if first {""} else {" - "}, err)?; - first = false; - } - } - writeln!(f)?; write!(f, "{}{}", if first {""} else {" - "}, error)?; - Ok(()) - } -} - -pub fn install_error_handler() { - simple_eyre::eyre::set_hook(Box::new(move |_| Box::new(ErrorHandler))).expect("failed to install error handler"); -} - -#[derive(Clone, Copy, Debug, Enum, EnumIter, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)] -pub enum Cardinal { - North, - South, - West, - East, -} - -impl Cardinal { - pub fn to_string(&self) -> &'static str { - match self { - Self::North => "north", - Self::South => "south", - Self::West => "west", - Self::East => "east", - } - } - - pub fn turn_cw(&self) -> Self { - match self { - Self::North => Self::East, - Self::South => Self::West, - Self::West => Self::North, - Self::East => Self::South, - } - } - - pub fn turn_ccw(&self) -> Self { - match self { - Self::North => Self::West, - Self::South => Self::East, - Self::West => Self::South, - Self::East => Self::North, - } - } - - pub fn dir(&self) -> glam::Vec3 { - match self { - Self::North => glam::Vec3::new(0.0, 1.0, 0.0), - Self::South => glam::Vec3::new(0.0, -1.0, 0.0), - Self::West => glam::Vec3::new(-1.0, 0.0, 0.0), - Self::East => glam::Vec3::new(1.0, 0.0, 0.0), - } - } - - pub fn offsets(&self) -> (i32, i32) { - match self { - Self::North => (0, 1), - Self::South => (0, -1), - Self::West => (-1, 0), - Self::East => (1, 0), - } - } - - pub fn angle(&self) -> f32 { - match self { - Self::North => 0.0, - Self::South => PI, - Self::West => PI / 2.0, - Self::East => 3.0 * PI / 2.0, - } - } - - pub fn turn_by(&self, o: Self) -> Self { - match o { - Self::North => *self, - Self::South => self.turn_cw().turn_cw(), - Self::West => self.turn_cw(), - Self::East => self.turn_ccw(), - } - } - - pub fn angle_between(&self, o: &Self) -> f32 { - if o == &self.turn_cw() { -PI / 2.0 } - else if o == &self.turn_ccw() { PI / 2.0 } - else if o == &self.turn_cw().turn_cw() { PI } - else { 0.0 } - } -} - -pub fn lerp(a: f32, b: f32, t: f32) -> f32 { - a + t.clamp(0.0, 1.0) * (b - a) -} - -pub fn dir_lerp(a: glam::Vec3, b: glam::Vec3, t: f32) -> glam::Vec3 { - let dirrotaxis = a.cross(b).normalize(); - let dirrotangle = a.angle_between(b); - let dirrotfull = glam::Quat::from_axis_angle(dirrotaxis, dirrotangle); - let dirrot = glam::Quat::IDENTITY.slerp(dirrotfull, t); - dirrot.mul_vec3(a) -} diff --git a/2026/games/rpc2dot0/vendor/teleia/crates/teleia_macros/Cargo.toml b/2026/games/rpc2dot0/vendor/teleia/crates/teleia_macros/Cargo.toml deleted file mode 100644 index 3ef969e..0000000 --- a/2026/games/rpc2dot0/vendor/teleia/crates/teleia_macros/Cargo.toml +++ /dev/null @@ -1,14 +0,0 @@ -[package] -name = "teleia_macros" -version.workspace = true -edition.workspace = true -authors.workspace = true - -[lib] -proc-macro = true - -[dependencies] -env = "1.0.1" -walkdir = "2.5.0" -heck = "0.5.0" -litrs = "1.0.0" \ No newline at end of file diff --git a/2026/games/rpc2dot0/vendor/teleia/crates/teleia_macros/src/lib.rs b/2026/games/rpc2dot0/vendor/teleia/crates/teleia_macros/src/lib.rs deleted file mode 100644 index 5b6c0b9..0000000 --- a/2026/games/rpc2dot0/vendor/teleia/crates/teleia_macros/src/lib.rs +++ /dev/null @@ -1,231 +0,0 @@ -use heck::ToUpperCamelCase; -use proc_macro::TokenStream; -use std::collections::HashSet; -use std::path::Path; -use walkdir::WalkDir; - -#[derive(Debug, Hash, PartialEq, Eq)] -struct Designator { - path: String, - parts: Vec, -} -impl Designator { - fn new(fbase: &str, mut path: &Path, shorten: bool) -> Self { - let mut parts: Vec<_> = path - .strip_prefix(fbase) - .unwrap() - .with_extension("") - .components() - .filter_map(|c| match c { - std::path::Component::Normal(o) => Some(o.to_str().unwrap().to_owned()), - _ => None, - }) - .collect(); - if shorten { - parts.pop(); - path = path.parent().expect("path has no parent"); - } - Self { - path: path - .to_str() - .expect("path is not a string") - .replace("\\", "/"), - parts, - } - } - fn enum_entry(&self, fnm: &str) -> String { - let singular = match fnm { - "meshes" => "mesh", - "textures" => "texture", - "materials" => "material", - "shaders" => "shader", - _ => fnm, - }; - let mut ret = format!("\n#[doc=\"newton-{}: {}\"]\n", singular, self.path); - ret += &self.parts.join(" ").to_upper_camel_case(); - ret - } - fn enum_element(&self, _fnm: &str) -> String { - self.parts.join(" ").to_upper_camel_case() - } - fn load_expr(&self, fnm: &str) -> Option { - let i = format!("assets/{}/{}", fnm, self.parts.join("/")); - match fnm { - "meshes" => Some(format!( - "teleia::mesh::Mesh::from_obj(ctx, include_bytes!(\"{}.obj\"))", - i - )), - "textures" => Some(format!( - "teleia::texture::Texture::new(ctx, include_bytes!(\"{}.png\"))", - i - )), - "materials" => Some(format!( - "teleia::texture::Material::new(ctx, include_bytes!(\"{}/color.jpg\"), include_bytes!(\"{}/normal.jpg\"))", - i, i - )), - "shaders" => { - if self.parts.contains(&"nolib".to_owned()) { - Some(format!( - "teleia::shader::Shader::new_nolib(ctx, include_str!(\"{}/vert.glsl\"), include_str!(\"{}/frag.glsl\"))", - i, i - )) - } else { - Some(format!( - "teleia::shader::Shader::new(ctx, include_str!(\"{}/vert.glsl\"), include_str!(\"{}/frag.glsl\"))", - i, i - )) - } - } - _ => None, - } - } -} - -#[derive(Debug)] -struct Field { - nm: String, - entries: HashSet, -} -impl Field { - fn new(base: &str, nm: &str) -> Self { - let mut entries = HashSet::new(); - let fbase = format!("{}{}", base, nm); - for f in WalkDir::new(&fbase).into_iter().flatten() { - if f.file_type().is_file() { - entries.insert(Designator::new( - &fbase, - f.path(), - nm == "shaders" || nm == "materials", - )); - } - } - Self { - nm: nm.to_owned(), - entries, - } - } - fn generate(&self) -> Option<(String, String, String)> { - let mut ents = Vec::new(); - for d in self.entries.iter() { - if let Some(exp) = d.load_expr(&self.nm) { - ents.push((d.enum_entry(&self.nm), d.enum_element(&self.nm), exp)); - } - } - let (enm, ty) = match self.nm.as_str() { - "meshes" => ("Mesh", "teleia::mesh::Mesh"), - "textures" => ("Texture", "teleia::texture::Texture"), - "materials" => ("Material", "teleia::texture::Material"), - "shaders" => ("Shader", "teleia::shader::Shader"), - _ => return None, - }; - let enums: Vec<_> = ents.iter().map(|(e, _, _)| e.clone()).collect(); - let edecl = format!("#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize, enum_map::Enum)] -pub enum {} {{ {} }}", enm, enums.join(", ")); - let decl = format!("pub {}: enum_map::EnumMap<{}, {}>", self.nm, enm, ty); - let inits: Vec<_> = ents - .into_iter() - .map(|(_, e, exp)| format!("{}::{} => {}", enm, e, exp)) - .collect(); - let init = format!("{}: enum_map::enum_map!({})", self.nm, inits.join(", ")); - Some((edecl, decl, init)) - } -} - -#[derive(Debug)] -struct AssetData { - fields: Vec, -} -impl AssetData { - fn new(base: &str) -> Self { - let mut fields = Vec::new(); - let dirs = std::fs::read_dir(base) - .unwrap_or_else(|_| panic!("failed to read assets directory: {}", base)); - let (mut has_meshes, mut has_textures, mut has_materials, mut has_shaders) = - (false, false, false, false); - for d in dirs.flatten() { - let nm = d.file_name().into_string().unwrap(); - fields.push(Field::new(base, &nm)); - match &*nm { - "meshes" => has_meshes = true, - "textures" => has_textures = true, - "materials" => has_materials = true, - "shaders" => has_shaders = true, - _ => {} - }; - } - if !has_meshes { - fields.push(Field { - nm: "meshes".to_owned(), - entries: HashSet::new(), - }); - } - if !has_textures { - fields.push(Field { - nm: "textures".to_owned(), - entries: HashSet::new(), - }); - } - if !has_materials { - fields.push(Field { - nm: "materials".to_owned(), - entries: HashSet::new(), - }); - } - if !has_shaders { - fields.push(Field { - nm: "shaders".to_owned(), - entries: HashSet::new(), - }); - } - Self { fields } - } - fn generate(&self) -> String { - let mut res = String::new(); - let fdata: Vec<_> = self.fields.iter().filter_map(|f| f.generate()).collect(); - for (edecl, _, _) in fdata.iter() { - res += edecl; - res += "\n"; - } - res += "pub struct Assets {\n"; - for (_, decl, _) in fdata.iter() { - res += decl; - res += ",\n"; - } - res += "}\nimpl Assets {\npub fn new(ctx: &teleia::context::Context) -> Self {\nSelf {\n"; - for (_, _, init) in fdata.iter() { - res += init; - res += ",\n"; - } - res += "}\n}\n}\n"; - res += "impl teleia::renderer::Assets for Assets {\n"; - res += "type Shader = Shader;\n"; - res += - "fn shader(&self, i: Self::Shader) -> &teleia::shader::Shader { &self.shaders[i] }\n"; - res += "type Texture = Texture;\n"; - res += "fn texture(&self, i: Self::Texture) -> &teleia::texture::Texture { &self.textures[i] }\n"; - res += "type Material = Material;\n"; - res += "fn material(&self, i: Self::Material) -> &teleia::texture::Material { &self.materials[i] }\n"; - res += "type Mesh = Mesh;\n"; - res += "fn mesh(&self, i: Self::Mesh) -> &teleia::mesh::Mesh { &self.meshes[i] }\n"; - res += "}\n"; - res - } -} - -#[proc_macro] -pub fn generate_assets(s: TokenStream) -> TokenStream { - let token = s - .into_iter() - .next() - .expect("must pass asset base path as a string literal"); - let lit = litrs::StringLit::try_from(token).expect("argument was not a string literal"); - let base = lit.value(); - let manifest = env::var("CARGO_MANIFEST_DIR").expect("failed to get manifest path"); - let assets = AssetData::new(&format!("{}/{}", manifest, base)); - // println!("{}", assets.generate()); - assets - .generate() - .to_string() - .parse() - .expect("failed to parse generate_assets result") -} -- cgit v1.3.1