mirror of
https://github.com/griffi-gh/kubi.git
synced 2024-11-21 14:28:43 -06:00
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:
parent
340a140ec9
commit
d5e8b4c6b7
31
README.md
31
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
|
||||
```
|
||||
|
||||
<h2>mutiplayer</h2>
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"]
|
||||
|
|
|
@ -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
|
||||
));
|
||||
},
|
||||
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)?))
|
||||
}
|
||||
|
|
|
@ -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
|
||||
});
|
||||
|
|
|
@ -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.);
|
||||
|
|
|
@ -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]>) {
|
||||
|
|
Loading…
Reference in a new issue