142 lines
4.4 KiB
Rust
142 lines
4.4 KiB
Rust
#![no_std]
|
|
#![no_main]
|
|
|
|
extern crate alloc;
|
|
|
|
mod allocator;
|
|
|
|
use core::panic::PanicInfo;
|
|
use pxl8_server::*;
|
|
|
|
#[global_allocator]
|
|
static ALLOCATOR: allocator::Allocator = allocator::Allocator;
|
|
|
|
#[panic_handler]
|
|
fn panic(_info: &PanicInfo) -> ! {
|
|
loop {}
|
|
}
|
|
|
|
const TICK_RATE: u64 = 30;
|
|
const TICK_NS: u64 = 1_000_000_000 / TICK_RATE;
|
|
|
|
#[cfg(unix)]
|
|
fn get_time_ns() -> u64 {
|
|
let mut ts = libc::timespec { tv_sec: 0, tv_nsec: 0 };
|
|
unsafe { libc::clock_gettime(libc::CLOCK_MONOTONIC, &mut ts) };
|
|
(ts.tv_sec as u64) * 1_000_000_000 + (ts.tv_nsec as u64)
|
|
}
|
|
|
|
#[cfg(windows)]
|
|
fn get_time_ns() -> u64 {
|
|
use windows_sys::Win32::System::Performance::*;
|
|
static mut FREQ: i64 = 0;
|
|
unsafe {
|
|
if FREQ == 0 {
|
|
QueryPerformanceFrequency(&mut FREQ);
|
|
}
|
|
let mut count: i64 = 0;
|
|
QueryPerformanceCounter(&mut count);
|
|
((count as u128 * 1_000_000_000) / FREQ as u128) as u64
|
|
}
|
|
}
|
|
|
|
#[cfg(unix)]
|
|
fn sleep_ms(ms: u64) {
|
|
let ts = libc::timespec {
|
|
tv_sec: (ms / 1000) as i64,
|
|
tv_nsec: ((ms % 1000) * 1_000_000) as i64,
|
|
};
|
|
unsafe { libc::nanosleep(&ts, core::ptr::null_mut()) };
|
|
}
|
|
|
|
#[cfg(windows)]
|
|
fn sleep_ms(ms: u64) {
|
|
use windows_sys::Win32::System::Threading::Sleep;
|
|
unsafe { Sleep(ms as u32) };
|
|
}
|
|
|
|
fn extract_spawn_position(payload: &[u8]) -> (f32, f32, f32, f32, f32) {
|
|
let x = f32::from_be_bytes([payload[0], payload[1], payload[2], payload[3]]);
|
|
let y = f32::from_be_bytes([payload[4], payload[5], payload[6], payload[7]]);
|
|
let z = f32::from_be_bytes([payload[8], payload[9], payload[10], payload[11]]);
|
|
let yaw = f32::from_be_bytes([payload[12], payload[13], payload[14], payload[15]]);
|
|
let pitch = f32::from_be_bytes([payload[16], payload[17], payload[18], payload[19]]);
|
|
(x, y, z, yaw, pitch)
|
|
}
|
|
|
|
#[unsafe(no_mangle)]
|
|
pub extern "C" fn main(_argc: i32, _argv: *const *const u8) -> i32 {
|
|
let mut transport = match transport::Transport::bind(transport::DEFAULT_PORT) {
|
|
Some(t) => t,
|
|
None => return 1,
|
|
};
|
|
|
|
let mut sim = Simulation::new();
|
|
let mut player_id: u64 = 0;
|
|
let mut last_client_tick: u64 = 0;
|
|
|
|
let mut sequence: u32 = 0;
|
|
let mut last_tick = get_time_ns();
|
|
let mut entities_buf = [protocol::pxl8_entity_state {
|
|
entity_id: 0,
|
|
userdata: [0u8; 56],
|
|
}; 64];
|
|
let mut inputs_buf: [protocol::pxl8_input_msg; 16] = unsafe { core::mem::zeroed() };
|
|
|
|
loop {
|
|
let now = get_time_ns();
|
|
let elapsed = now.saturating_sub(last_tick);
|
|
|
|
if elapsed >= TICK_NS {
|
|
last_tick = now;
|
|
let dt = (elapsed as f32) / 1_000_000_000.0;
|
|
|
|
let mut latest_input: Option<protocol::pxl8_input_msg> = None;
|
|
while let Some(msg_type) = transport.recv() {
|
|
match msg_type {
|
|
x if x == protocol::pxl8_msg_type::PXL8_MSG_INPUT as u8 => {
|
|
latest_input = Some(transport.get_input());
|
|
}
|
|
x if x == protocol::pxl8_msg_type::PXL8_MSG_COMMAND as u8 => {
|
|
let cmd = transport.get_command();
|
|
if cmd.cmd_type == protocol::pxl8_cmd_type::PXL8_CMD_SPAWN_ENTITY as u16 {
|
|
let (x, y, z, _yaw, _pitch) = extract_spawn_position(&cmd.payload);
|
|
let player = sim.spawn_player(x, y, z);
|
|
player_id = player.to_bits();
|
|
}
|
|
}
|
|
_ => {}
|
|
}
|
|
}
|
|
|
|
if let Some(input) = latest_input {
|
|
last_client_tick = input.tick;
|
|
inputs_buf[0] = input;
|
|
sim.step(&inputs_buf[..1], dt);
|
|
} else {
|
|
sim.step(&[], dt);
|
|
}
|
|
|
|
let mut count = 0;
|
|
sim.generate_snapshot(player_id, |state| {
|
|
if count < entities_buf.len() {
|
|
entities_buf[count] = *state;
|
|
count += 1;
|
|
}
|
|
});
|
|
|
|
let header = protocol::pxl8_snapshot_header {
|
|
entity_count: count as u16,
|
|
event_count: 0,
|
|
player_id,
|
|
tick: last_client_tick,
|
|
time: sim.time,
|
|
};
|
|
|
|
transport.send_snapshot(&header, &entities_buf[..count], sequence);
|
|
sequence = sequence.wrapping_add(1);
|
|
}
|
|
|
|
sleep_ms(1);
|
|
}
|
|
}
|