diff --git a/README.md b/README.md index 17cb9e4..d5c06d5 100644 --- a/README.md +++ b/README.md @@ -41,19 +41,36 @@ build with nightly features cargo +nightly build --bin kubi -r --features nightly ``` -build for android +build for android -please note that android support is purely experimental! -gamepad, keyboard and mouse input is currently borked, and touch controls are not available. +please note that android support is purely experimental! +gamepad, keyboard and mouse input is currently borked, and touch controls are not available. srgb and blending are broken too, which leads to many rendering issues prerequisites: Android SDK, NDK, platform-tools, latest JDK (all should be in $PATH) +Setup: + ```bash -cargo install cargo-apk -cargo target add aarch64-linux-android -cargo apk build -p kubi -cargo apk run -p kubi +cargo install cargo-apk +cargo target add aarch64-linux-android +``` + +Build: +`--no-default-features` is required for keyboard input! + +```bash +cargo apk build -p kubi --no-default-features +# or, with nighly optimizations: +cargo +nightly apk build -p kubi --no-default-features --features nightly +``` + +Run: + +```bash +cargo apk run -p kubi --features nightly +# or, with nighly optimizations: +cargo +nightly apk run -p kubi --no-default-features --features nightly ```

mutiplayer

diff --git a/kubi-server/src/auth.rs b/kubi-server/src/auth.rs index 9673619..5a40946 100644 --- a/kubi-server/src/auth.rs +++ b/kubi-server/src/auth.rs @@ -81,7 +81,7 @@ pub fn authenticate_players( //Find the player ID let max_clients = config.server.max_clients as ClientId; - let Some(client_id) = (0..max_clients).into_iter().find(|id| { + let Some(client_id) = (0..max_clients).find(|id| { !client_entity_map.0.contains_key(id) }) else { client.borrow_mut().send( diff --git a/kubi-server/src/server.rs b/kubi-server/src/server.rs index cb996b2..0c0cb31 100644 --- a/kubi-server/src/server.rs +++ b/kubi-server/src/server.rs @@ -38,7 +38,6 @@ pub fn bind_server( keepalive_interval_ms: 5000, ..Default::default() }, - ..Default::default() } ).expect("Failed to create the server"); storages.add_unique_non_send_sync(UdpServer(server)); diff --git a/kubi-server/src/util.rs b/kubi-server/src/util.rs index 74f2f98..c33d2f1 100644 --- a/kubi-server/src/util.rs +++ b/kubi-server/src/util.rs @@ -54,7 +54,7 @@ pub fn check_message_auth<'a, const C_MSG: u8>( log::error!("Client not authenticated"); return None }; - let Ok(&Client(client_id)) = (&clients).get(entity_id) else { + let Ok(&Client(client_id)) = clients.get(entity_id) else { log::error!("Entity ID is invalid"); return None }; diff --git a/kubi-server/src/world.rs b/kubi-server/src/world.rs index c253a8d..43bdc5c 100644 --- a/kubi-server/src/world.rs +++ b/kubi-server/src/world.rs @@ -71,7 +71,7 @@ fn process_chunk_requests( //TODO Start task here if status is "Nothing" if let Some(blocks) = &chunk.blocks { send_chunk_compressed( - &message.client, + message.client, &ServerToClientMessage::ChunkResponse { chunk: chunk_position, data: blocks.clone(), diff --git a/kubi-shared/src/worldgen.rs b/kubi-shared/src/worldgen.rs index a5e4a4c..5d6cc59 100644 --- a/kubi-shared/src/worldgen.rs +++ b/kubi-shared/src/worldgen.rs @@ -9,7 +9,7 @@ use crate::{ }; fn mountain_ramp(mut x: f32) -> f32 { - x = x * 2.0; + x *= 2.0; if x < 0.4 { 0.5 * x } else if x < 0.55 { @@ -94,7 +94,7 @@ pub fn generate_world(chunk_position: IVec3, seed: u64) -> (BlockData, Vec (BlockData, Vec 0.4 { - let raw_ravine_value = ravine_nose_line.get_noise(noise_x, noise_y); - if (-0.0125..0.0125).contains(&(raw_ravine_value.powi(2))) { - is_surface = false; - height -= (100. * (0.0125 - raw_ravine_value.powi(2)) * (1. / 0.0125)).round() as i32; - } + if height < 0 && raw_ravine_location_value > 0.4 { + let raw_ravine_value = ravine_nose_line.get_noise(noise_x, noise_y); + if (-0.0125..0.0125).contains(&(raw_ravine_value.powi(2))) { + is_surface = false; + height -= (100. * (0.0125 - raw_ravine_value.powi(2)) * (1. / 0.0125)).round() as i32; } } height }; //add to heightmap if is_surface { - deco_heightmap[x as usize][z as usize] = Some(height); + deco_heightmap[x][z] = Some(height); //place dirt for y in 0..local_height(height, chunk_position) { blocks[x][y][z] = Block::Dirt; @@ -162,29 +160,27 @@ pub fn generate_world(chunk_position: IVec3, seed: u64) -> (BlockData, Vec) { #[allow(clippy::collapsible_match, clippy::single_match)] match event { Event::WindowEvent { window_id: _, event } => match event { + WindowEvent::Resized(size) => { world.add_entity(( EventComponent, WindowResizedEvent(UVec2::new(size.width as _, size.height as _)) )); }, + + #[cfg(not(feature = "raw-evt"))] + WindowEvent::KeyboardInput { device_id, input, is_synthetic } => { + world.add_entity(( + EventComponent, + InputDeviceEvent { + device_id: *device_id, + event: DeviceEvent::Key(*input) + } + )); + } + _ => () }, + + #[cfg(feature = "raw-evt")] Event::DeviceEvent { device_id, event } => { world.add_entity(( - EventComponent, - InputDeviceEvent { - device_id: *device_id, - event: event.clone() + EventComponent, + InputDeviceEvent { + device_id: *device_id, + event: event.clone() } )); }, + Event::LoopDestroyed => { world.add_entity(( - EventComponent, + EventComponent, OnBeforeExitEvent )); }, + _ => (), } } diff --git a/kubi/src/filesystem.rs b/kubi/src/filesystem.rs index 33757f6..be2104f 100644 --- a/kubi/src/filesystem.rs +++ b/kubi/src/filesystem.rs @@ -4,7 +4,6 @@ use anyhow::Result; pub trait ReadOnly: Read + Seek {} impl ReadOnly for T {} -#[allow(unreachable_code)] pub fn open_asset(path: &Path) -> Result> { #[cfg(target_os = "android")] { use anyhow::Context; @@ -13,8 +12,10 @@ pub fn open_asset(path: &Path) -> Result> { let asset_manager = ndk_glue::native_activity().asset_manager(); let path_cstr = CString::new(path.to_string_lossy().as_bytes())?; let handle = asset_manager.open(&path_cstr).context("Asset doesn't exist")?; - return Ok(Box::new(handle)); + Ok(Box::new(handle)) + } + #[cfg(not(target_os = "android"))] { + let asset_path = Path::new("./assets/").join(path); + Ok(Box::new(File::open(asset_path)?)) } - let asset_path = Path::new("./assets/").join(path); - return Ok(Box::new(File::open(asset_path)?)) } diff --git a/kubi/src/networking/world.rs b/kubi/src/networking/world.rs index c04755c..a5e0410 100644 --- a/kubi/src/networking/world.rs +++ b/kubi/src/networking/world.rs @@ -14,15 +14,15 @@ use crate::{ world::{ tasks::{ChunkTaskResponse, ChunkTaskManager}, queue::BlockUpdateQueue - }, + }, }; use super::{NetworkEvent, UdpClient}; //TODO multithreaded decompression -fn decompress_chunk_packet(data: &Box<[u8]>) -> Result { +fn decompress_chunk_packet(data: &[u8]) -> Result { let mut decompressed = decompress_size_prepended(&data[1..])?; decompressed.insert(0, data[0]); - Ok(postcard::from_bytes(&decompressed).ok().context("Deserialization failed")?) + postcard::from_bytes(&decompressed).ok().context("Deserialization failed") } //TODO get rid of this, this is awfulll @@ -38,7 +38,7 @@ pub fn inject_network_responses_into_manager_queue( chunk, data, queued } = packet else { unreachable!() }; manager.add_sussy_response(ChunkTaskResponse::LoadedChunk { - position: chunk, + position: chunk, chunk_data: data, queued }); diff --git a/kubi/src/rendering.rs b/kubi/src/rendering.rs index 1f52c21..8b620c4 100644 --- a/kubi/src/rendering.rs +++ b/kubi/src/rendering.rs @@ -41,6 +41,11 @@ impl Renderer { .with_maximized(true) .with_min_inner_size(PhysicalSize::new(640, 480)) .with_fullscreen({ + //this has no effect on android, so skip this pointless stuff + #[cfg(target_os = "android")] { + None + } + #[cfg(not(target_os = "android"))] if let Some(fs_settings) = &settings.fullscreen { let monitor = event_loop.primary_monitor().or_else(|| { event_loop.available_monitors().next() @@ -104,7 +109,7 @@ impl Renderer { } pub fn clear_background( - mut target: NonSendSync>, + mut target: NonSendSync>, color: UniqueView, ) { target.0.clear_color_srgb_and_depth((color.0.x, color.0.y, color.0.z, 1.), 1.); diff --git a/kubi/src/world/mesh/builder.rs b/kubi/src/world/mesh/builder.rs index fb5949e..561342c 100644 --- a/kubi/src/world/mesh/builder.rs +++ b/kubi/src/world/mesh/builder.rs @@ -1,9 +1,8 @@ use strum::EnumIter; use glam::{Vec3, vec3, IVec3, ivec3}; +use std::f32::consts::FRAC_1_SQRT_2; use crate::rendering::world::ChunkVertex; -const INV_SQRT_2: f32 = 0.70710678118655; // 1 / 2.sqrt() - #[repr(usize)] #[derive(Clone, Copy, Debug, EnumIter)] pub enum CubeFace { @@ -28,7 +27,7 @@ const CUBE_FACE_VERTICES: [[Vec3; 4]; 6] = [ [vec3(1., 0., 1.), vec3(1., 1., 1.), vec3(0., 0., 1.), vec3(0., 1., 1.)], [vec3(0., 0., 1.), vec3(0., 0., 0.), vec3(1., 0., 1.), vec3(1., 0., 0.)], ]; -const CUBE_FACE_NORMALS_IVEC3: [IVec3; 6] = [ +const CUBE_FACE_NORMALS_IVEC3: [IVec3; 6] = [ ivec3( 0, 1, 0), ivec3( 0, 0, -1), ivec3(-1, 0, 0), @@ -36,7 +35,7 @@ const CUBE_FACE_NORMALS_IVEC3: [IVec3; 6] = [ ivec3( 0, 0, 1), ivec3( 0, -1, 0) ]; -const CUBE_FACE_NORMALS: [Vec3; 6] = [ +const CUBE_FACE_NORMALS: [Vec3; 6] = [ vec3(0., 1., 0.), vec3(0., 0., -1.), vec3(-1.,0., 0.), @@ -53,25 +52,25 @@ pub enum DiagonalFace { } const CROSS_FACES: [[Vec3; 4]; 2] = [ [ - vec3(0., 0., 0.), - vec3(0., 1., 0.), - vec3(1., 0., 1.), + vec3(0., 0., 0.), + vec3(0., 1., 0.), + vec3(1., 0., 1.), vec3(1., 1., 1.), ], [ - vec3(0., 0., 1.), - vec3(0., 1., 1.), - vec3(1., 0., 0.), + vec3(0., 0., 1.), + vec3(0., 1., 1.), + vec3(1., 0., 0.), vec3(1., 1., 0.), ] ]; const CROSS_FACE_NORMALS: [Vec3; 2] = [ - vec3(-INV_SQRT_2, 0., INV_SQRT_2), - vec3(INV_SQRT_2, 0., INV_SQRT_2), + vec3(-FRAC_1_SQRT_2, 0., FRAC_1_SQRT_2), + vec3( FRAC_1_SQRT_2, 0., FRAC_1_SQRT_2), ]; const CROSS_FACE_NORMALS_BACK: [Vec3; 2] = [ - vec3(INV_SQRT_2, 0., -INV_SQRT_2), - vec3(-INV_SQRT_2, 0., -INV_SQRT_2), + vec3( FRAC_1_SQRT_2, 0., -FRAC_1_SQRT_2), + vec3(-FRAC_1_SQRT_2, 0., -FRAC_1_SQRT_2), ]; const CROSS_FACE_INDICES: [u32; 12] = [ 0, 1, 2, 2, 1, 3, //Front side @@ -109,7 +108,7 @@ impl MeshBuilder { self.vertex_buffer.push(ChunkVertex { position: (coord + vert[i]).to_array(), normal: norm.to_array(), - uv: UV_COORDS[i], + uv: UV_COORDS[i], tex_index: texture }); } @@ -149,7 +148,7 @@ impl MeshBuilder { self.index_buffer.extend_from_slice(&CROSS_FACE_INDICES.map(|x| x + self.idx_counter)); //Increment idx counter - self.idx_counter += 8; + self.idx_counter += 8; } pub fn add_model(&mut self, position: Vec3, vertices: &[ChunkVertex], indices: Option<&[u32]>) {