summaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/teleia/Cargo.toml2
-rw-r--r--crates/teleia/src/context.rs12
-rw-r--r--crates/teleia/src/lib.rs17
-rw-r--r--crates/teleia/src/scene.rs2
-rw-r--r--crates/teleia/src/state.rs31
-rw-r--r--crates/teleia/src/texture.rs28
6 files changed, 70 insertions, 22 deletions
diff --git a/crates/teleia/Cargo.toml b/crates/teleia/Cargo.toml
index 05ec74a..1704309 100644
--- a/crates/teleia/Cargo.toml
+++ b/crates/teleia/Cargo.toml
@@ -46,7 +46,7 @@ web-sys = { version = "*", features = ["Document", "Window", "Element", "HtmlCan
[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", "wav"] } # audio
+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/crates/teleia/src/context.rs b/crates/teleia/src/context.rs
index 8547d59..6346237 100644
--- a/crates/teleia/src/context.rs
+++ b/crates/teleia/src/context.rs
@@ -1,6 +1,7 @@
use crate::Options;
use glow::HasContext;
+use glfw::Context as _;
#[cfg(target_arch = "wasm32")]
use wasm_bindgen::prelude::*;
@@ -257,6 +258,17 @@ impl Context {
}
}
+ #[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();
diff --git a/crates/teleia/src/lib.rs b/crates/teleia/src/lib.rs
index 85a5f4e..21f3b24 100644
--- a/crates/teleia/src/lib.rs
+++ b/crates/teleia/src/lib.rs
@@ -38,10 +38,11 @@ use glfw::Context;
use bitflags::bitflags;
bitflags! {
pub struct Options: u32 {
- const OVERLAY = 0b00000001;
- const HIDDEN = 0b00000010;
- const NORESIZE = 0b00000100;
- const EGL = 0b00001000;
+ const OVERLAY = 0b00000001;
+ const HIDDEN = 0b00000010;
+ const NORESIZE = 0b00000100;
+ const EGL = 0b00001000;
+ const FULLSCREEN_MOUSE = 0b00010000;
}
}
@@ -161,10 +162,10 @@ where
st.keys = state::Keys::new();
},
glfw::WindowEvent::CursorPos(x, y) => {
- st.mouse_moved(&ctx, x as f32, y as f32, game);
+ st.mouse_moved(&ctx, x as f32, y as f32, game)?;
}
glfw::WindowEvent::MouseButton(_, glfw::Action::Press, _) => {
- st.mouse_pressed(&ctx, game)
+ st.mouse_pressed(&ctx, game)?;
},
glfw::WindowEvent::MouseButton(_, glfw::Action::Release, _) => {
st.mouse_released(&ctx)
@@ -272,14 +273,14 @@ where
st.keys = state::Keys::new();
},
winit::event::WindowEvent::CursorMoved { position, ..} => {
- st.mouse_moved(&ctx, position.x as f32, position.y as f32, game);
+ 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)
+ st.mouse_pressed(&ctx, game)?;
},
winit::event::ElementState::Released => {
st.mouse_released(&ctx)
diff --git a/crates/teleia/src/scene.rs b/crates/teleia/src/scene.rs
index ccef8f6..6c9ab9a 100644
--- a/crates/teleia/src/scene.rs
+++ b/crates/teleia/src/scene.rs
@@ -233,7 +233,7 @@ impl Scene {
Some(&i.as_bytes()),
);
ctx.gl.generate_mipmap(glow::TEXTURE_2D);
- texture::Texture { tex }
+ texture::Texture { tex, width: i.width() as i32, height: i.height() as i32 }
}
}).collect();
let materials: Vec<Material> = gltf.materials().map(|m| {
diff --git a/crates/teleia/src/state.rs b/crates/teleia/src/state.rs
index 8f4462a..2e50fbf 100644
--- a/crates/teleia/src/state.rs
+++ b/crates/teleia/src/state.rs
@@ -22,9 +22,9 @@ pub trait Game {
) -> HashMap<String, audio::Audio> {
HashMap::new()
}
- fn finish_title(&mut self, st: &mut State) {}
- fn mouse_move(&mut self, ctx: &context::Context, st: &mut State, x: i32, y: i32) {}
- fn mouse_press(&mut self, ctx: &context::Context, st: &mut State) {}
+ fn finish_title(&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 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(()) }
}
@@ -451,28 +451,37 @@ impl State {
ctx: &context::Context,
x: f32, y: f32,
game: &mut G
- ) where G: Game
+ ) -> utils::Erm<()> where G: Game
{
- 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);
+ 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<G>(
&mut self,
ctx: &context::Context,
game: &mut G
- ) where G: Game {
+ ) -> utils::Erm<()> where G: Game {
log::info!("click");
if self.audio.is_none() {
self.audio = Some(audio::Assets::new(|actx| {
game.initialize_audio(ctx, &self, actx)
}));
- game.finish_title(self);
+ game.finish_title(ctx, self)?;
}
- game.mouse_press(ctx, self);
+ game.mouse_press(ctx, self)?;
+ Ok(())
}
pub fn mouse_released(
diff --git a/crates/teleia/src/texture.rs b/crates/teleia/src/texture.rs
index f993c08..727eec2 100644
--- a/crates/teleia/src/texture.rs
+++ b/crates/teleia/src/texture.rs
@@ -5,6 +5,8 @@ use crate::context;
pub struct Texture {
pub tex: glow::Texture,
+ pub width: i32,
+ pub height: i32,
}
impl Texture {
@@ -18,6 +20,7 @@ impl Texture {
ctx.gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_MAG_FILTER, glow::NEAREST as i32);
Self {
tex,
+ width: 0, height: 0,
}
}
}
@@ -52,11 +55,24 @@ impl Texture {
Self {
tex,
+ width: rgba.width() as i32,
+ height: rgba.height() as i32,
}
}
}
- pub fn upload_rgba8(&self, ctx: &context::Context, width: i32, height: i32, data: &[u8]) {
+ 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);
@@ -76,6 +92,16 @@ impl Texture {
);
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) {