better lighting
This commit is contained in:
parent
805a2713a3
commit
6ed4e17065
75 changed files with 6417 additions and 3667 deletions
|
|
@ -1,11 +1,21 @@
|
|||
#include "pxl8_net.h"
|
||||
#include "pxl8_chunk_cache.h"
|
||||
#include "pxl8_log.h"
|
||||
#include "pxl8_mem.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "pxl8_hal.h"
|
||||
|
||||
#ifdef PXL8_ASYNC_THREADS
|
||||
#include <stdatomic.h>
|
||||
#include "pxl8_queue.h"
|
||||
#endif
|
||||
|
||||
#include "pxl8_bytes.h"
|
||||
#include "pxl8_log.h"
|
||||
#include "pxl8_mem.h"
|
||||
#include "pxl8_world.h"
|
||||
#include "pxl8_world_chunk_cache.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <winsock2.h>
|
||||
|
|
@ -30,28 +40,42 @@
|
|||
|
||||
struct pxl8_net {
|
||||
char address[256];
|
||||
bool connected;
|
||||
u16 port;
|
||||
struct sockaddr_in server_addr;
|
||||
socket_t sock;
|
||||
|
||||
pxl8_world_chunk_cache* chunk_cache;
|
||||
u32 chunk_id;
|
||||
u8 chunk_type;
|
||||
pxl8_chunk_cache* chunk_cache;
|
||||
bool connected;
|
||||
pxl8_world* world;
|
||||
|
||||
f32 dt;
|
||||
u64 highest_tick;
|
||||
f32 interp_time;
|
||||
u32 sequence;
|
||||
|
||||
pxl8_entity_state entities[PXL8_MAX_SNAPSHOT_ENTITIES];
|
||||
pxl8_event_msg events[PXL8_MAX_SNAPSHOT_EVENTS];
|
||||
u64 highest_tick;
|
||||
pxl8_input_msg input_history[PXL8_NET_INPUT_HISTORY_SIZE];
|
||||
u64 input_head;
|
||||
u64 input_oldest_tick;
|
||||
f32 interp_time;
|
||||
u16 port;
|
||||
u8 predicted_state[PXL8_NET_USERDATA_SIZE];
|
||||
u64 predicted_tick;
|
||||
pxl8_entity_state prev_entities[PXL8_MAX_SNAPSHOT_ENTITIES];
|
||||
pxl8_snapshot_header prev_snapshot;
|
||||
pxl8_snapshot_header snapshot;
|
||||
|
||||
u64 input_head;
|
||||
pxl8_input_msg input_history[PXL8_NET_INPUT_HISTORY_SIZE];
|
||||
u64 input_oldest_tick;
|
||||
|
||||
u8 predicted_state[PXL8_NET_USERDATA_SIZE];
|
||||
u64 predicted_tick;
|
||||
|
||||
u8 recv_buf[4096];
|
||||
u8 send_buf[4096];
|
||||
u32 sequence;
|
||||
struct sockaddr_in server_addr;
|
||||
pxl8_snapshot_header snapshot;
|
||||
socket_t sock;
|
||||
|
||||
#ifdef PXL8_ASYNC_THREADS
|
||||
pxl8_thread* recv_thread;
|
||||
atomic_bool running;
|
||||
pxl8_queue recv_queue;
|
||||
#endif
|
||||
};
|
||||
|
||||
static const pxl8_entity_state* find_entity(const pxl8_entity_state* entities, u16 count, u64 id) {
|
||||
|
|
@ -225,7 +249,7 @@ bool pxl8_net_poll(pxl8_net* net) {
|
|||
payload_len = len - offset;
|
||||
}
|
||||
|
||||
pxl8_chunk_cache_receive(net->chunk_cache, &chunk_hdr, payload, payload_len);
|
||||
pxl8_world_chunk_cache_receive(net->chunk_cache, &chunk_hdr, payload, payload_len);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -238,6 +262,12 @@ bool pxl8_net_poll(pxl8_net* net) {
|
|||
return true;
|
||||
}
|
||||
|
||||
if (hdr.type == PXL8_MSG_CHUNK_EXIT) {
|
||||
net->chunk_id = 0;
|
||||
net->chunk_type = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (hdr.type != PXL8_MSG_SNAPSHOT) return false;
|
||||
|
||||
pxl8_snapshot_header snap;
|
||||
|
|
@ -260,6 +290,10 @@ bool pxl8_net_poll(pxl8_net* net) {
|
|||
net->recv_buf + offset, len - offset, &net->entities[i]);
|
||||
}
|
||||
|
||||
if (net->world) {
|
||||
pxl8_world_reconcile(net->world, net, 1.0f / 30.0f);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -312,6 +346,8 @@ pxl8_result pxl8_net_send_command(pxl8_net* net, const pxl8_command_msg* cmd) {
|
|||
pxl8_result pxl8_net_send_input(pxl8_net* net, const pxl8_input_msg* input) {
|
||||
if (!net || !net->connected) return PXL8_ERROR_INVALID_ARGUMENT;
|
||||
|
||||
pxl8_net_input_push(net, input);
|
||||
|
||||
u8 buf[sizeof(pxl8_msg_header) + sizeof(pxl8_input_msg)];
|
||||
pxl8_msg_header hdr = {
|
||||
.type = PXL8_MSG_INPUT,
|
||||
|
|
@ -338,19 +374,25 @@ u64 pxl8_net_tick(const pxl8_net* net) {
|
|||
|
||||
void pxl8_net_update(pxl8_net* net, f32 dt) {
|
||||
if (!net) return;
|
||||
net->dt = dt;
|
||||
net->interp_time += dt;
|
||||
}
|
||||
|
||||
void pxl8_net_set_chunk_cache(pxl8_net* net, pxl8_chunk_cache* cache) {
|
||||
void pxl8_net_set_chunk_cache(pxl8_net* net, pxl8_world_chunk_cache* cache) {
|
||||
if (!net) return;
|
||||
net->chunk_cache = cache;
|
||||
}
|
||||
|
||||
pxl8_chunk_cache* pxl8_net_chunk_cache(pxl8_net* net) {
|
||||
pxl8_world_chunk_cache* pxl8_net_chunk_cache(pxl8_net* net) {
|
||||
if (!net) return NULL;
|
||||
return net->chunk_cache;
|
||||
}
|
||||
|
||||
void pxl8_net_set_world(pxl8_net* net, pxl8_world* world) {
|
||||
if (!net) return;
|
||||
net->world = world;
|
||||
}
|
||||
|
||||
u32 pxl8_net_chunk_id(const pxl8_net* net) {
|
||||
if (!net) return 0;
|
||||
return net->chunk_id;
|
||||
|
|
@ -360,3 +402,186 @@ u8 pxl8_net_chunk_type(const pxl8_net* net) {
|
|||
if (!net) return PXL8_CHUNK_TYPE_VXL;
|
||||
return net->chunk_type;
|
||||
}
|
||||
|
||||
pxl8_result pxl8_net_send_chunk_settings(pxl8_net* net, i32 render_distance, i32 sim_distance) {
|
||||
if (!net) return PXL8_ERROR_NULL_POINTER;
|
||||
if (!net->connected) return PXL8_ERROR_NOT_CONNECTED;
|
||||
|
||||
pxl8_command_msg cmd = {0};
|
||||
cmd.cmd_type = PXL8_CMD_SET_CHUNK_SETTINGS;
|
||||
pxl8_pack_i32_be(cmd.payload, 0, render_distance);
|
||||
pxl8_pack_i32_be(cmd.payload, 4, sim_distance);
|
||||
cmd.payload_size = 8;
|
||||
|
||||
return pxl8_net_send_command(net, &cmd);
|
||||
}
|
||||
|
||||
pxl8_result pxl8_net_spawn(pxl8_net* net, f32 x, f32 y, f32 z, f32 yaw, f32 pitch) {
|
||||
if (!net) return PXL8_ERROR_NULL_POINTER;
|
||||
if (!net->connected) return PXL8_ERROR_NOT_CONNECTED;
|
||||
|
||||
pxl8_command_msg cmd = {0};
|
||||
cmd.cmd_type = PXL8_CMD_SPAWN_ENTITY;
|
||||
pxl8_pack_f32_be(cmd.payload, 0, x);
|
||||
pxl8_pack_f32_be(cmd.payload, 4, y);
|
||||
pxl8_pack_f32_be(cmd.payload, 8, z);
|
||||
pxl8_pack_f32_be(cmd.payload, 12, yaw);
|
||||
pxl8_pack_f32_be(cmd.payload, 16, pitch);
|
||||
cmd.payload_size = 20;
|
||||
|
||||
return pxl8_net_send_command(net, &cmd);
|
||||
}
|
||||
|
||||
pxl8_result pxl8_net_exit_chunk(pxl8_net* net, f32 x, f32 y, f32 z) {
|
||||
if (!net) return PXL8_ERROR_NULL_POINTER;
|
||||
if (!net->connected) return PXL8_ERROR_NOT_CONNECTED;
|
||||
|
||||
pxl8_command_msg cmd = {0};
|
||||
cmd.cmd_type = PXL8_CMD_EXIT_CHUNK;
|
||||
pxl8_pack_f32_be(cmd.payload, 0, x);
|
||||
pxl8_pack_f32_be(cmd.payload, 4, y);
|
||||
pxl8_pack_f32_be(cmd.payload, 8, z);
|
||||
cmd.payload_size = 12;
|
||||
|
||||
return pxl8_net_send_command(net, &cmd);
|
||||
}
|
||||
|
||||
pxl8_result pxl8_net_enter_chunk(pxl8_net* net, u32 chunk_id) {
|
||||
if (!net) return PXL8_ERROR_NULL_POINTER;
|
||||
if (!net->connected) return PXL8_ERROR_NOT_CONNECTED;
|
||||
|
||||
pxl8_command_msg cmd = {0};
|
||||
cmd.cmd_type = PXL8_CMD_ENTER_CHUNK;
|
||||
pxl8_pack_u32_be(cmd.payload, 0, chunk_id);
|
||||
cmd.payload_size = 4;
|
||||
|
||||
return pxl8_net_send_command(net, &cmd);
|
||||
}
|
||||
|
||||
#ifdef PXL8_ASYNC_THREADS
|
||||
|
||||
static int pxl8_net_recv_thread(void* data) {
|
||||
pxl8_net* net = (pxl8_net*)data;
|
||||
u8 buf[PXL8_NET_PACKET_MAX_SIZE];
|
||||
|
||||
while (atomic_load(&net->running)) {
|
||||
if (!net->connected) {
|
||||
pxl8_sleep_ms(10);
|
||||
continue;
|
||||
}
|
||||
|
||||
struct sockaddr_in from;
|
||||
socklen_t from_len = sizeof(from);
|
||||
ssize_t received = recvfrom(net->sock, (char*)buf, sizeof(buf), 0,
|
||||
(struct sockaddr*)&from, &from_len);
|
||||
|
||||
if (received > 0) {
|
||||
pxl8_packet* pkt = pxl8_malloc(sizeof(pxl8_packet));
|
||||
if (pkt) {
|
||||
memcpy(pkt->data, buf, (usize)received);
|
||||
pkt->len = (usize)received;
|
||||
|
||||
if (!pxl8_queue_push(&net->recv_queue, pkt)) {
|
||||
pxl8_free(pkt);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
pxl8_sleep_ms(1);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pxl8_net_start_thread(pxl8_net* net) {
|
||||
if (!net || net->recv_thread) return;
|
||||
|
||||
pxl8_queue_init(&net->recv_queue);
|
||||
atomic_store(&net->running, true);
|
||||
net->recv_thread = pxl8_thread_create(pxl8_net_recv_thread, "pxl8_net_recv", net);
|
||||
}
|
||||
|
||||
void pxl8_net_stop_thread(pxl8_net* net) {
|
||||
if (!net || !net->recv_thread) return;
|
||||
|
||||
atomic_store(&net->running, false);
|
||||
pxl8_thread_wait(net->recv_thread, NULL);
|
||||
net->recv_thread = NULL;
|
||||
|
||||
pxl8_packet* pkt;
|
||||
while ((pkt = pxl8_queue_pop(&net->recv_queue))) {
|
||||
pxl8_free(pkt);
|
||||
}
|
||||
}
|
||||
|
||||
pxl8_packet* pxl8_net_pop_packet(pxl8_net* net) {
|
||||
if (!net) return NULL;
|
||||
return (pxl8_packet*)pxl8_queue_pop(&net->recv_queue);
|
||||
}
|
||||
|
||||
void pxl8_net_packet_free(pxl8_packet* pkt) {
|
||||
pxl8_free(pkt);
|
||||
}
|
||||
|
||||
bool pxl8_net_process_packet(pxl8_net* net, const pxl8_packet* pkt) {
|
||||
if (!net || !pkt || pkt->len < sizeof(pxl8_msg_header)) return false;
|
||||
|
||||
pxl8_msg_header hdr;
|
||||
usize offset = pxl8_protocol_deserialize_header(pkt->data, pkt->len, &hdr);
|
||||
|
||||
if (hdr.type == PXL8_MSG_CHUNK) {
|
||||
if (!net->chunk_cache) return false;
|
||||
|
||||
pxl8_chunk_msg_header chunk_hdr;
|
||||
offset += pxl8_protocol_deserialize_chunk_msg_header(pkt->data + offset, pkt->len - offset, &chunk_hdr);
|
||||
|
||||
const u8* payload = pkt->data + offset;
|
||||
usize payload_len = chunk_hdr.payload_size;
|
||||
if (payload_len > pkt->len - offset) {
|
||||
payload_len = pkt->len - offset;
|
||||
}
|
||||
|
||||
pxl8_world_chunk_cache_receive(net->chunk_cache, &chunk_hdr, payload, payload_len);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (hdr.type == PXL8_MSG_CHUNK_ENTER) {
|
||||
pxl8_chunk_enter_msg chunk_msg;
|
||||
pxl8_protocol_deserialize_chunk_enter(pkt->data + offset, pkt->len - offset, &chunk_msg);
|
||||
net->chunk_id = chunk_msg.chunk_id;
|
||||
net->chunk_type = chunk_msg.chunk_type;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (hdr.type == PXL8_MSG_CHUNK_EXIT) {
|
||||
net->chunk_id = 0;
|
||||
net->chunk_type = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (hdr.type != PXL8_MSG_SNAPSHOT) return false;
|
||||
|
||||
pxl8_snapshot_header snap;
|
||||
offset += pxl8_protocol_deserialize_snapshot_header(pkt->data + offset, pkt->len - offset, &snap);
|
||||
|
||||
if (snap.tick <= net->highest_tick) return false;
|
||||
|
||||
memcpy(net->prev_entities, net->entities, sizeof(net->entities));
|
||||
net->prev_snapshot = net->snapshot;
|
||||
|
||||
net->highest_tick = snap.tick;
|
||||
net->snapshot = snap;
|
||||
net->interp_time = 0.0f;
|
||||
|
||||
u16 count = snap.entity_count;
|
||||
if (count > PXL8_MAX_SNAPSHOT_ENTITIES) count = PXL8_MAX_SNAPSHOT_ENTITIES;
|
||||
|
||||
for (u16 i = 0; i < count; i++) {
|
||||
offset += pxl8_protocol_deserialize_entity_state(
|
||||
pkt->data + offset, pkt->len - offset, &net->entities[i]);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -9,9 +9,16 @@ extern "C" {
|
|||
|
||||
#define PXL8_NET_INPUT_HISTORY_SIZE 64
|
||||
#define PXL8_NET_USERDATA_SIZE 56
|
||||
#define PXL8_NET_PACKET_MAX_SIZE 2048
|
||||
|
||||
typedef struct pxl8_net pxl8_net;
|
||||
typedef struct pxl8_chunk_cache pxl8_chunk_cache;
|
||||
typedef struct pxl8_world pxl8_world;
|
||||
typedef struct pxl8_world_chunk_cache pxl8_world_chunk_cache;
|
||||
|
||||
typedef struct pxl8_packet {
|
||||
u8 data[PXL8_NET_PACKET_MAX_SIZE];
|
||||
usize len;
|
||||
} pxl8_packet;
|
||||
|
||||
typedef struct pxl8_net_config {
|
||||
const char* address;
|
||||
|
|
@ -43,12 +50,27 @@ pxl8_result pxl8_net_send_input(pxl8_net* net, const pxl8_input_msg* input);
|
|||
const pxl8_snapshot_header* pxl8_net_snapshot(const pxl8_net* net);
|
||||
u64 pxl8_net_tick(const pxl8_net* net);
|
||||
void pxl8_net_update(pxl8_net* net, f32 dt);
|
||||
void pxl8_net_set_chunk_cache(pxl8_net* net, pxl8_chunk_cache* cache);
|
||||
pxl8_chunk_cache* pxl8_net_chunk_cache(pxl8_net* net);
|
||||
void pxl8_net_set_chunk_cache(pxl8_net* net, pxl8_world_chunk_cache* cache);
|
||||
pxl8_world_chunk_cache* pxl8_net_chunk_cache(pxl8_net* net);
|
||||
void pxl8_net_set_world(pxl8_net* net, pxl8_world* world);
|
||||
|
||||
u32 pxl8_net_chunk_id(const pxl8_net* net);
|
||||
u8 pxl8_net_chunk_type(const pxl8_net* net);
|
||||
|
||||
pxl8_result pxl8_net_send_chunk_settings(pxl8_net* net, i32 render_distance, i32 sim_distance);
|
||||
|
||||
pxl8_result pxl8_net_spawn(pxl8_net* net, f32 x, f32 y, f32 z, f32 yaw, f32 pitch);
|
||||
pxl8_result pxl8_net_exit_chunk(pxl8_net* net, f32 x, f32 y, f32 z);
|
||||
pxl8_result pxl8_net_enter_chunk(pxl8_net* net, u32 chunk_id);
|
||||
|
||||
#ifdef PXL8_ASYNC_THREADS
|
||||
void pxl8_net_start_thread(pxl8_net* net);
|
||||
void pxl8_net_stop_thread(pxl8_net* net);
|
||||
pxl8_packet* pxl8_net_pop_packet(pxl8_net* net);
|
||||
void pxl8_net_packet_free(pxl8_packet* pkt);
|
||||
bool pxl8_net_process_packet(pxl8_net* net, const pxl8_packet* pkt);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ typedef enum pxl8_msg_type {
|
|||
PXL8_MSG_NONE = 0,
|
||||
PXL8_MSG_CHUNK,
|
||||
PXL8_MSG_CHUNK_ENTER,
|
||||
PXL8_MSG_CHUNK_EXIT,
|
||||
PXL8_MSG_COMMAND,
|
||||
PXL8_MSG_CONNECT,
|
||||
PXL8_MSG_DISCONNECT,
|
||||
|
|
@ -34,6 +35,9 @@ typedef struct pxl8_msg_header {
|
|||
typedef enum pxl8_cmd_type {
|
||||
PXL8_CMD_NONE = 0,
|
||||
PXL8_CMD_SPAWN_ENTITY,
|
||||
PXL8_CMD_EXIT_CHUNK,
|
||||
PXL8_CMD_ENTER_CHUNK,
|
||||
PXL8_CMD_SET_CHUNK_SETTINGS,
|
||||
} pxl8_cmd_type;
|
||||
|
||||
typedef struct pxl8_input_msg {
|
||||
|
|
@ -92,17 +96,17 @@ typedef struct pxl8_chunk_msg_header {
|
|||
} pxl8_chunk_msg_header;
|
||||
|
||||
typedef struct pxl8_bsp_wire_header {
|
||||
u32 num_vertices;
|
||||
u32 num_cell_portals;
|
||||
u32 num_edges;
|
||||
u32 num_faces;
|
||||
u32 num_planes;
|
||||
u32 num_nodes;
|
||||
u32 num_leafs;
|
||||
u32 num_surfedges;
|
||||
u32 num_marksurfaces;
|
||||
u32 num_cell_portals;
|
||||
u32 visdata_size;
|
||||
u32 num_nodes;
|
||||
u32 num_planes;
|
||||
u32 num_surfedges;
|
||||
u32 num_vertex_lights;
|
||||
u32 num_vertices;
|
||||
u32 visdata_size;
|
||||
} pxl8_bsp_wire_header;
|
||||
|
||||
usize pxl8_protocol_serialize_header(const pxl8_msg_header* msg, u8* buf, usize len);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue