diff options
Diffstat (limited to 'light-client/src')
-rw-r--r-- | light-client/src/bin/bunnymark.rs | 104 | ||||
-rw-r--r-- | light-client/src/game.rs | 4 | ||||
-rw-r--r-- | light-client/src/main.rs | 81 | ||||
-rw-r--r-- | light-client/src/network.rs | 52 |
4 files changed, 241 insertions, 0 deletions
diff --git a/light-client/src/bin/bunnymark.rs b/light-client/src/bin/bunnymark.rs new file mode 100644 index 00000000..12c18d66 --- /dev/null +++ b/light-client/src/bin/bunnymark.rs @@ -0,0 +1,104 @@ +/* + Hurry Curry! - a game about cooking + Copyright 2024 metamuffin + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, version 3 of the License only. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. + +*/ +use hurrycurry_protocol::glam::IVec2; +use sdl2::{ + event::Event, + image::{InitFlag, LoadTexture}, + keyboard::Keycode, + pixels::Color, + rect::Rect, +}; +use std::time::Instant; + +const WIDTH: i32 = 1920; +const HEIGHT: i32 = 1080; + +pub fn main() { + let amount = std::env::args().skip(1).next().unwrap().parse().unwrap(); + + let sdl_context = sdl2::init().unwrap(); + let video_subsystem = sdl_context.video().unwrap(); + let _image_context = sdl2::image::init(InitFlag::WEBP | InitFlag::PNG).unwrap(); + let window = video_subsystem + .window("Hurry Curry! Light Client", WIDTH as u32, HEIGHT as u32) + .position_centered() + .build() + .map_err(|e| e.to_string()) + .unwrap(); + + let mut canvas = window + .into_canvas() + .accelerated() + .build() + .map_err(|e| e.to_string()) + .unwrap(); + let texture_creator = canvas.texture_creator(); + let texture = texture_creator.load_texture("client/icon.png").unwrap(); + + let mut bunnies = vec![(IVec2::ZERO, IVec2::ONE); amount]; + + for (i, (pos, vel)) in bunnies.iter_mut().enumerate() { + let mut r = xorshift(i as i32); + pos.x = r % WIDTH; + r = xorshift(r); + pos.y = r % HEIGHT; + r = xorshift(r); + vel.x = r % 7 - 3; + r = xorshift(r); + vel.y = r % 7 - 3; + } + + let mut last = Instant::now(); + 'mainloop: loop { + canvas.set_draw_color(Color::BLACK); + canvas.clear(); + for (pos, vel) in &mut bunnies { + *pos += *vel; + if pos.x < 0 || pos.x > WIDTH { + vel.x *= -1 + } + if pos.y < 0 || pos.y > HEIGHT { + vel.y *= -1 + } + canvas + .copy(&texture, None, Some(Rect::new(pos.x, pos.y, 30, 30))) + .unwrap(); + } + canvas.present(); + + for event in sdl_context.event_pump().unwrap().poll_iter() { + match event { + Event::Quit { .. } + | Event::KeyDown { + keycode: Option::Some(Keycode::Escape), + .. + } => break 'mainloop, + _ => {} + } + } + println!("frame time: {:?}", last.elapsed()); + last = Instant::now(); + } +} + +fn xorshift(mut x: i32) -> i32 { + x ^= x << 13; + x ^= x >> 17; + x ^= x << 5; + x +} diff --git a/light-client/src/game.rs b/light-client/src/game.rs new file mode 100644 index 00000000..fd045f53 --- /dev/null +++ b/light-client/src/game.rs @@ -0,0 +1,4 @@ + +pub struct Game { + +} diff --git a/light-client/src/main.rs b/light-client/src/main.rs new file mode 100644 index 00000000..85254ef4 --- /dev/null +++ b/light-client/src/main.rs @@ -0,0 +1,81 @@ +use network::Network; +/* + Hurry Curry! - a game about cooking + Copyright 2024 metamuffin + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, version 3 of the License only. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. + +*/ +use sdl2::{ + event::Event, + image::InitFlag, + keyboard::Keycode, + pixels::{Color, PixelFormatEnum}, + render::TextureAccess, +}; + +pub mod network; +pub mod game; + +fn main() { + let net = Network::connect("ws://127.0.0.1:27032/"); + + let sdl_context = sdl2::init().unwrap(); + let video_subsystem = sdl_context.video().unwrap(); + let _image_context = sdl2::image::init(InitFlag::WEBP).unwrap(); + let window = video_subsystem + .window("Hurry Curry! Light Client", 1280, 720) + .position_centered() + .resizable() + .build() + .map_err(|e| e.to_string()) + .unwrap(); + + let mut canvas = window + .into_canvas() + .accelerated() + .build() + .map_err(|e| e.to_string()) + .unwrap(); + let texture_creator = canvas.texture_creator(); + let mut texture = texture_creator + .create_texture( + Some(PixelFormatEnum::RGBA8888), + TextureAccess::Streaming, + 1024, + 1024, + ) + .unwrap(); + + texture.update(None, &vec![128; 1024 * 1024], 1024).unwrap(); + + 'mainloop: loop { + canvas.set_draw_color(Color::BLACK); + canvas.clear(); + + canvas.copy(&texture, None, None).unwrap(); + + canvas.present(); + + for event in sdl_context.event_pump().unwrap().poll_iter() { + match event { + Event::Quit { .. } + | Event::KeyDown { + keycode: Option::Some(Keycode::Escape), + .. + } => break 'mainloop, + _ => {} + } + } + } +} diff --git a/light-client/src/network.rs b/light-client/src/network.rs new file mode 100644 index 00000000..dc6e894f --- /dev/null +++ b/light-client/src/network.rs @@ -0,0 +1,52 @@ +use hurrycurry_protocol::{PacketC, PacketS, BINCODE_CONFIG}; +use log::warn; +use std::{collections::VecDeque, net::TcpStream}; +use tungstenite::{stream::MaybeTlsStream, Message, WebSocket}; + +pub struct Network { + sock: WebSocket<MaybeTlsStream<TcpStream>>, + queue_in: VecDeque<PacketC>, + queue_out: VecDeque<PacketS>, +} + +impl Network { + pub fn connect(addr: &str) -> Self { + let (sock, _resp) = tungstenite::connect(addr).unwrap(); + Self { + sock, + queue_in: VecDeque::new(), + queue_out: VecDeque::new(), + } + } + pub fn poll(&mut self) { + self.queue_in.extend(match self.sock.read() { + Ok(Message::Text(packet)) => match serde_json::from_str(&packet) { + Ok(p) => Some(p), + Err(e) => { + warn!("invalid json packet: {e:?}"); + None + } + }, + Ok(Message::Binary(packet)) => { + match bincode::decode_from_slice(&packet, BINCODE_CONFIG) { + Ok((p, _)) => Some(p), + Err(e) => { + warn!("invalid bincode packet: {e:?}"); + None + } + } + } + Ok(_) => None, + Err(e) => { + warn!("{e:?}"); + None + } + }); + + for packet in self.queue_out.drain(..) { + self.sock + .write(Message::Text(serde_json::to_string(&packet).unwrap())) + .unwrap(); + } + } +} |