add raw-evt feature, fix clippy warnings

`raw-evt` is enable by default
forcing it off is required for kb input on android
mouse input is not supported without it yet though
This commit is contained in:
griffi-gh 2023-06-04 15:16:25 +02:00
parent c919aeb81b
commit 601e55fb9f
12 changed files with 109 additions and 74 deletions

View file

@ -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
```
<h2>mutiplayer</h2>

View file

@ -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(

View file

@ -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));

View file

@ -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
};

View file

@ -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(),

View file

@ -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<Queue
let mut rng = Xoshiro256StarStar::seed_from_u64(
seed
^ ((chunk_position.x as u32 as u64) << 0)
^ (chunk_position.x as u32 as u64)
^ ((chunk_position.z as u32 as u64) << 32)
);
let rng_map_a: [[f32; CHUNK_SIZE]; CHUNK_SIZE] = rng.gen();
@ -133,20 +133,18 @@ pub fn generate_world(chunk_position: IVec3, seed: u64) -> (BlockData, Vec<Queue
}
}
//Generate ravines
if height < 0 {
if 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;
}
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<Queue
blocks[x][y][z] = Block::Grass;
within_heightmap = true;
}
} else if let Some(river_fill_height) = river_fill_height {
//Place water
for y in 0..local_height(river_fill_height, chunk_position) {
blocks[x][y][z] = Block::Water;
within_heightmap = true;
}
//Place stone
for y in 0..local_height(height, chunk_position) {
blocks[x][y][z] = Block::Stone;
within_heightmap = true;
}
//Place dirt
if let Some(y) = local_y_position(height, chunk_position) {
blocks[x][y][z] = Block::Dirt;
within_heightmap = true;
}
} else {
if let Some(river_fill_height) = river_fill_height {
//Place water
for y in 0..local_height(river_fill_height, chunk_position) {
blocks[x][y][z] = Block::Water;
within_heightmap = true;
}
//Place stone
for y in 0..local_height(height, chunk_position) {
blocks[x][y][z] = Block::Stone;
within_heightmap = true;
}
//Place dirt
if let Some(y) = local_y_position(height, chunk_position) {
blocks[x][y][z] = Block::Dirt;
within_heightmap = true;
}
} else {
//Place stone
for y in 0..local_height(height, chunk_position) {
blocks[x][y][z] = Block::Stone;
within_heightmap = true;
}
//Place stone
for y in 0..local_height(height, chunk_position) {
blocks[x][y][z] = Block::Stone;
within_heightmap = true;
}
}
}

View file

@ -37,7 +37,8 @@ ndk-glue = "0.7"
winapi = { version = "0.3" }
[features]
default = []
default = ["raw-evt"]
raw-evt = []
generate_visualizer_data = ["serde_json", "shipyard/serde1"]
safe_lz4 = ["lz4_flex/safe-encode", "lz4_flex/safe-decode"]
parallel = ["shipyard/parallel"]

View file

@ -24,29 +24,46 @@ pub fn process_glutin_events(world: &mut World, event: &Event<'_, ()>) {
#[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
));
},
_ => (),
}
}

View file

@ -4,7 +4,6 @@ use anyhow::Result;
pub trait ReadOnly: Read + Seek {}
impl<T: Read + Seek> ReadOnly for T {}
#[allow(unreachable_code)]
pub fn open_asset(path: &Path) -> Result<Box<dyn ReadOnly>> {
#[cfg(target_os = "android")] {
use anyhow::Context;
@ -13,8 +12,10 @@ pub fn open_asset(path: &Path) -> Result<Box<dyn ReadOnly>> {
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)?))
}

View file

@ -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<ServerToClientMessage> {
fn decompress_chunk_packet(data: &[u8]) -> Result<ServerToClientMessage> {
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
});

View file

@ -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<UniqueViewMut<RenderTarget>>,
mut target: NonSendSync<UniqueViewMut<RenderTarget>>,
color: UniqueView<BackgroundColor>,
) {
target.0.clear_color_srgb_and_depth((color.0.x, color.0.y, color.0.z, 1.), 1.);

View file

@ -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]>) {