Compare commits

...

3 commits

Author SHA1 Message Date
griffi-gh bd327c86f3 change stuff :3 (will break android builds) 2023-11-20 23:21:50 +01:00
griffi-gh 43ca458896 wip data 2023-11-20 20:59:34 +01:00
griffi-gh e2bec4bf2e . 2023-11-20 19:51:16 +01:00
14 changed files with 132 additions and 39 deletions

View file

@ -1,5 +1,3 @@
#link crt statically on msvc
[target.x86_64-pc-windows-msvc]
rustflags = ["-Ctarget-feature=+crt-static"]
@ -9,12 +7,5 @@ rustflags = ["-Ctarget-feature=+crt-static"]
[target.i586-pc-windows-msvc]
rustflags = ["-Ctarget-feature=+crt-static"]
# enable sse,sse2,avx
[target.'cfg(target_arch = "x86_64")']
rustflags = "-Ctarget-feature=+sse,+sse2,+avx"
# use sparse crates.io protocol
[registries.crates-io]
protocol = "sparse"

2
.gitignore vendored
View file

@ -13,3 +13,5 @@ target/
_src
_visualizer.json
*.kubi

27
Cargo.lock generated
View file

@ -1033,11 +1033,13 @@ dependencies = [
"glam",
"hashbrown 0.14.0",
"nohash-hasher",
"num_enum 0.7.1",
"postcard",
"rand",
"rand_xoshiro",
"serde",
"shipyard",
"static_assertions",
"strum",
]
@ -1223,7 +1225,7 @@ dependencies = [
"bitflags 1.3.2",
"jni-sys",
"ndk-sys",
"num_enum",
"num_enum 0.5.11",
"raw-window-handle 0.5.2",
"thiserror",
]
@ -1371,7 +1373,16 @@ version = "0.5.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9"
dependencies = [
"num_enum_derive",
"num_enum_derive 0.5.11",
]
[[package]]
name = "num_enum"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "683751d591e6d81200c39fb0d1032608b77724f34114db54f571ff1317b337c0"
dependencies = [
"num_enum_derive 0.7.1",
]
[[package]]
@ -1386,6 +1397,18 @@ dependencies = [
"syn 1.0.109",
]
[[package]]
name = "num_enum_derive"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c11e44798ad209ccdd91fc192f0526a369a01234f7373e1b141c96d7cee4f0e"
dependencies = [
"proc-macro-crate",
"proc-macro2",
"quote",
"syn 2.0.23",
]
[[package]]
name = "objc"
version = "0.2.7"

View file

@ -13,7 +13,7 @@ struct Task<T> {
fn task_loop<T, R>() {
let tasks = VecDeque::<Task<T>>::new();
loop {
//todo
};
}
@ -22,7 +22,7 @@ impl<T: 'static, R: 'static> KubiPool<T, R> {
Self {
callback,
threads: (0..threads).map(|_| {
std::thread::spawn(task_loop::<T, R>)
std::thread::spawn(move || task_loop::<T, R>())
}).collect(),
}
}

View file

@ -8,6 +8,7 @@ publish = false
glam = { version = "0.24", features = ["debug-glam-assert", "fast-math", "serde"] }
shipyard = { git = "https://github.com/leudz/shipyard", rev = "0934b426eb9a8", default-features = false, features = ["std"] }
strum = { version = "0.25", features = ["derive"] }
num_enum = "0.7"
postcard = { version = "1.0", features = ["alloc"] }
serde = { version = "1.0", default-features = false, features = ["alloc", "derive"] }
bincode = "1.3"
@ -17,9 +18,8 @@ rand = { version = "0.8", default_features = false, features = ["std", "min_cons
rand_xoshiro = "0.6"
hashbrown = { version = "0.14", features = ["serde"] }
nohash-hasher = "0.2"
#bytemuck = { version = "1.14", features = ["derive"] }
#static_assertions = "1.1"
static_assertions = "1.1"
[features]
default = []

View file

@ -1,5 +1,6 @@
use serde::{Serialize, Deserialize};
use strum::EnumIter;
use num_enum::TryFromPrimitive;
#[derive(Serialize, Deserialize, Clone, Copy, Debug, EnumIter)]
#[repr(u8)]
@ -22,7 +23,7 @@ pub enum BlockTexture {
WaterSolid,
}
#[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Eq, EnumIter)]
#[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Eq, EnumIter, TryFromPrimitive)]
#[repr(u8)]
pub enum Block {
Air,

View file

@ -2,13 +2,20 @@ use std::{
fs::File,
mem::size_of,
io::{Read, Seek, SeekFrom, Write},
borrow::Cow
borrow::Cow,
sync::{Arc, RwLock}
};
use num_enum::TryFromPrimitive;
use serde::{Serialize, Deserialize};
use glam::IVec2;
use glam::IVec3;
use hashbrown::HashMap;
use anyhow::Result;
use crate::{block::Block, chunk::{CHUNK_SIZE, BlockDataRef}};
use shipyard::Unique;
use static_assertions::const_assert_eq;
use crate::{
block::Block,
chunk::{CHUNK_SIZE, BlockDataRef, BlockData}
};
const SECTOR_SIZE: usize = CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE * size_of::<Block>();
const RESERVED_SIZE: usize = 1048576; //~1mb (16 sectors assuming 32x32x32 world of 1byte blocks)
@ -20,13 +27,13 @@ const HEADER_MAGIC_STR: [u8; 4] = *b"KUBI";
const HEADER_MAGIC_IDENTITY: u32 = 1;
// #[repr(transparent)]
// struct IVec2Hash(IVec2);
// struct IVec3Hash(IVec3);
#[derive(Serialize, Deserialize)]
struct WorldSaveDataHeader {
pub struct WorldSaveDataHeader {
pub name: Cow<'static, str>,
pub seed: u64,
sector_count: u32,
chunk_map: HashMap<IVec2, u32>,
chunk_map: HashMap<IVec3, u32>,
}
impl Default for WorldSaveDataHeader {
@ -40,11 +47,14 @@ impl Default for WorldSaveDataHeader {
}
}
struct WorldSaveFile {
#[derive(Unique)]
pub struct WorldSaveFile {
pub file: File,
pub header: WorldSaveDataHeader,
}
pub type SharedSaveFile = Arc<RwLock<WorldSaveFile>>;
impl WorldSaveFile {
pub fn new(file: File) -> Self {
WorldSaveFile {
@ -82,13 +92,23 @@ impl WorldSaveFile {
Ok(())
}
pub fn initialize(&mut self) -> Result<()> {
self.write_header()?;
Ok(())
}
pub fn load_data(&mut self) -> Result<()> {
self.read_header()?;
Ok(())
}
fn allocate_sector(&mut self) -> u32 {
let value = self.header.sector_count + 1;
self.header.sector_count += 1;
value
}
pub fn save_chunk(&mut self, position: IVec2, data: &BlockDataRef) -> Result<()> {
pub fn save_chunk(&mut self, position: IVec3, data: &BlockDataRef) -> Result<()> {
let mut header_modified = false;
let sector = self.header.chunk_map.get(&position).copied().unwrap_or_else(|| {
header_modified = true;
@ -96,7 +116,8 @@ impl WorldSaveFile {
});
let offset = sector as u64 * SECTOR_SIZE as u64;
//SAFETY: *nuzzles* t-t-twust me pwease OwO
const_assert_eq!(size_of::<Block>(), 1);
let data: &[u8; SECTOR_SIZE] = unsafe { std::mem::transmute(data) };
self.file.seek(SeekFrom::Start(offset))?;
@ -108,4 +129,41 @@ impl WorldSaveFile {
self.file.sync_data()?;
Ok(())
}
///TODO partial chunk commit (No need to write whole 32kb for a single block change!)
pub fn chunk_set_block() {
todo!()
}
pub fn chunk_exists(&self, position: IVec3) -> bool {
self.header.chunk_map.contains_key(&position)
}
pub fn load_chunk(&mut self, position: IVec3) -> Result<Option<BlockData>> {
let Some(&sector) = self.header.chunk_map.get(&position) else {
return Ok(None);
};
let mut buffer = Box::new([0u8; CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE * size_of::<Block>()]);
let offset = sector as u64 * SECTOR_SIZE as u64;
self.file.seek(SeekFrom::Start(offset))?;
self.file.read_exact(&mut buffer[..])?;
//should be safe under these conditions:
//Block is a single byte
//All block data bytes are in valid range
const_assert_eq!(size_of::<Block>(), 1);
for &byte in &buffer[..] {
let block = Block::try_from_primitive(byte);
match block {
//Sanity check, not actually required: (should NEVER happen)
Ok(block) => debug_assert_eq!(byte, block as u8),
Err(_) => anyhow::bail!("invalid block data"),
}
}
let data: BlockData = unsafe { std::mem::transmute(buffer) };
Ok(Some(data))
}
}

View file

@ -5,6 +5,7 @@ edition = "2021"
publish = false
[lib]
name = "kubilib"
crate-type = ["lib", "cdylib"]
[dependencies]

View file

@ -6,7 +6,7 @@ use kubi_shared::{
player::PlayerHolding,
};
use crate::{
player::MainPlayer,
player::MainPlayer,
world::{raycast::{LookingAtBlock, RAYCAST_STEP}, queue::BlockUpdateQueue},
input::{Inputs, PrevInputs, RawKbmInputState},
events::{EventComponent, player_actions::PlayerActionEvent},

View file

@ -1,9 +1,26 @@
use shipyard::{AllStoragesView, UniqueViewMut};
use std::{env, net::SocketAddr};
use std::{env, net::SocketAddr, fs::OpenOptions, path::{Path, PathBuf}, str::FromStr, sync::{Arc, RwLock}};
use anyhow::Result;
use crate::{
networking::{GameType, ServerAddress},
state::{GameState, NextState}
};
use kubi_shared::data::{WorldSaveFile, SharedSaveFile};
fn open_local_save_file(path: &Path) -> Result<WorldSaveFile> {
let mut save_file = WorldSaveFile::new({
OpenOptions::new()
.read(true)
.write(true)
.open("world.kbi")?
});
if save_file.file.metadata().unwrap().len() == 0 {
save_file.initialize()?;
} else {
save_file.load_data()?;
}
Ok(save_file)
}
pub fn initialize_from_args(
all_storages: AllStoragesView,

View file

@ -1,16 +1,14 @@
#![allow(clippy::too_many_arguments)] // allowed because systems often need a lot of arguments
use shipyard::{
World, Workload, IntoWorkload,
UniqueView, UniqueViewMut,
NonSendSync, WorkloadModificator,
World, Workload, IntoWorkload,
UniqueView, UniqueViewMut,
NonSendSync, WorkloadModificator,
SystemModificator
};
use glium::{
glutin::{
event_loop::{EventLoop, ControlFlow},
event::{Event, WindowEvent}
}
use glium::glutin::{
event_loop::{EventLoop, ControlFlow},
event::{Event, WindowEvent}
};
use glam::vec3;
use std::time::Instant;

View file

@ -4,5 +4,5 @@
)]
fn main() {
kubi::kubi_main();
kubilib::kubi_main();
}

View file

@ -2,7 +2,8 @@ use glam::Mat4;
use shipyard::{Component, AllStoragesViewMut, UniqueViewMut};
use kubi_shared::{
entity::{Entity, Health},
player::{PLAYER_HEALTH, PlayerHolding},
player::{Player, PLAYER_HEALTH, PlayerHolding},
block::Block,
networking::{
client::{Username, Client, ClientIdMap},
messages::ClientInitData
@ -14,7 +15,6 @@ use crate::{
fly_controller::FlyController,
world::raycast::LookingAtBlock,
};
pub use kubi_shared::player::Player;
#[derive(Component)]
pub struct MainPlayer;
@ -32,7 +32,7 @@ pub fn spawn_player (
Camera::default(),
FlyController,
LookingAtBlock::default(),
PlayerHolding::default(),
PlayerHolding(Some(Block::Cobblestone)),
Username("LocalPlayer".into())
));
}

2
rust-toolchain.toml Normal file
View file

@ -0,0 +1,2 @@
[toolchain]
channel = "nightly"