tile chunk testing
This commit is contained in:
parent
fa4f750beb
commit
478f077030
@ -174,7 +174,7 @@ struct asset *font_load_asset(struct string path, f32 point_size, b32 help)
|
|||||||
struct string key = string_format(scratch.arena,
|
struct string key = string_format(scratch.arena,
|
||||||
LIT("%F%F_font"),
|
LIT("%F%F_font"),
|
||||||
FMT_STR(path),
|
FMT_STR(path),
|
||||||
FMT_FLOAT_P((f64)point_size, 3));
|
FMT_FLOAT_P((f64)point_size, 1));
|
||||||
u64 hash = asset_cache_hash(key);
|
u64 hash = asset_cache_hash(key);
|
||||||
b32 is_first_touch;
|
b32 is_first_touch;
|
||||||
struct asset *asset = asset_cache_touch(key, hash, &is_first_touch);
|
struct asset *asset = asset_cache_touch(key, hash, &is_first_touch);
|
||||||
|
|||||||
15
src/math.h
15
src/math.h
@ -839,6 +839,21 @@ INLINE b32 v2i32_eq(struct v2i32 a, struct v2i32 b)
|
|||||||
return a.x == b.x && a.y == b.y;
|
return a.x == b.x && a.y == b.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
INLINE struct v2i32 v2i32_neg(struct v2i32 a)
|
||||||
|
{
|
||||||
|
return V2I32(-a.x, -a.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE struct v2i32 v2i32_add(struct v2i32 a, struct v2i32 b)
|
||||||
|
{
|
||||||
|
return V2I32(a.x + b.x, a.y + b.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE struct v2i32 v2i32_sub(struct v2i32 a, struct v2i32 b)
|
||||||
|
{
|
||||||
|
return V2I32(a.x - b.x, a.y - b.y);
|
||||||
|
}
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Mat4x4
|
* Mat4x4
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|||||||
@ -2,7 +2,6 @@
|
|||||||
#define RENDERER_H
|
#define RENDERER_H
|
||||||
|
|
||||||
struct sys_window;
|
struct sys_window;
|
||||||
struct sprite_scope;
|
|
||||||
|
|
||||||
#define RENDERER_TEXTURE_MAX_WIDTH 16384
|
#define RENDERER_TEXTURE_MAX_WIDTH 16384
|
||||||
#define RENDERER_TEXTURE_MAX_HEIGHT 16384
|
#define RENDERER_TEXTURE_MAX_HEIGHT 16384
|
||||||
@ -81,7 +80,7 @@ struct renderer_texture renderer_texture_alloc(enum renderer_texture_format form
|
|||||||
void renderer_texture_release(struct renderer_texture t);
|
void renderer_texture_release(struct renderer_texture t);
|
||||||
|
|
||||||
void renderer_texture_clear(struct renderer_texture target_texture, u32 clear_color);
|
void renderer_texture_clear(struct renderer_texture target_texture, u32 clear_color);
|
||||||
void renderer_texture_render(struct renderer_texture texture, struct renderer_cmd_buffer *cmdbuff, struct xform view, struct rect viewport, struct sprite_scope *sprite_scope);
|
void renderer_texture_render(struct renderer_texture texture, struct renderer_cmd_buffer *cmdbuff, struct xform view, struct rect viewport);
|
||||||
struct v2i32 renderer_texture_get_size(struct renderer_texture texture);
|
struct v2i32 renderer_texture_get_size(struct renderer_texture texture);
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
|
|||||||
@ -638,10 +638,12 @@ struct renderer_startup_receipt renderer_startup(struct sys_window *window)
|
|||||||
* Another option is to store a separate device on each cmdbuff?
|
* Another option is to store a separate device on each cmdbuff?
|
||||||
*
|
*
|
||||||
* I'm thinking we may also just need to lock texture modification access while presenting */
|
* I'm thinking we may also just need to lock texture modification access while presenting */
|
||||||
INTERNAL void dx11_render(ID3D11RenderTargetView *target, struct renderer_cmd_buffer *cmdbuff, struct xform view, struct rect viewport, struct sprite_scope *sprite_scope)
|
INTERNAL void dx11_render(ID3D11RenderTargetView *target, struct renderer_cmd_buffer *cmdbuff, struct xform view, struct rect viewport)
|
||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
__profscope_d3d11(G.profiling_ctx, Render);
|
__profscope_d3d11(G.profiling_ctx, Render);
|
||||||
|
struct sprite_scope *sprite_scope = sprite_scope_begin();
|
||||||
|
|
||||||
ID3D11DeviceContext_OMSetRenderTargets(G.devcon, 1, &target, NULL);
|
ID3D11DeviceContext_OMSetRenderTargets(G.devcon, 1, &target, NULL);
|
||||||
|
|
||||||
D3D11_VIEWPORT d3d11_viewport = ZI;
|
D3D11_VIEWPORT d3d11_viewport = ZI;
|
||||||
@ -754,6 +756,8 @@ INTERNAL void dx11_render(ID3D11RenderTargetView *target, struct renderer_cmd_bu
|
|||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sprite_scope_end(sprite_scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
@ -900,7 +904,7 @@ void renderer_texture_clear(struct renderer_texture target_texture, u32 clear_co
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderer_texture_render(struct renderer_texture texture, struct renderer_cmd_buffer *cmdbuff, struct xform view, struct rect viewport, struct sprite_scope *sprite_scope)
|
void renderer_texture_render(struct renderer_texture texture, struct renderer_cmd_buffer *cmdbuff, struct xform view, struct rect viewport)
|
||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
|
|
||||||
@ -909,7 +913,7 @@ void renderer_texture_render(struct renderer_texture texture, struct renderer_cm
|
|||||||
ID3D11RenderTargetView *target_view = NULL;
|
ID3D11RenderTargetView *target_view = NULL;
|
||||||
ID3D11Device_CreateRenderTargetView(G.dev, (ID3D11Resource *)t->texture, NULL, &target_view);
|
ID3D11Device_CreateRenderTargetView(G.dev, (ID3D11Resource *)t->texture, NULL, &target_view);
|
||||||
if (target_view) {
|
if (target_view) {
|
||||||
dx11_render(target_view, cmdbuff, view, viewport, sprite_scope);
|
dx11_render(target_view, cmdbuff, view, viewport);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target_view) {
|
if (target_view) {
|
||||||
|
|||||||
76
src/sim.c
76
src/sim.c
@ -543,6 +543,82 @@ struct sim_snapshot *sim_snapshot_from_closest_tick_gte(struct sim_client *clien
|
|||||||
return ss;
|
return ss;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ========================== *
|
||||||
|
* Tile
|
||||||
|
* ========================== */
|
||||||
|
|
||||||
|
struct v2i32 sim_world_tile_index_from_pos(struct v2 pos)
|
||||||
|
{
|
||||||
|
struct v2i32 res = V2I32(pos.x * SIM_TILES_PER_UNIT_SQRT, pos.y * SIM_TILES_PER_UNIT_SQRT);
|
||||||
|
res.x -= pos.x < 0;
|
||||||
|
res.y -= pos.y < 0;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct v2 sim_pos_from_world_tile_index(struct v2i32 world_tile_index)
|
||||||
|
{
|
||||||
|
struct v2 res = ZI;
|
||||||
|
f32 tile_size = 1.f / SIM_TILES_PER_UNIT_SQRT;
|
||||||
|
res.x = (f32)world_tile_index.x * tile_size;
|
||||||
|
res.y = (f32)world_tile_index.y * tile_size;
|
||||||
|
if (world_tile_index.x < 0) {
|
||||||
|
res.x += tile_size;
|
||||||
|
}
|
||||||
|
if (world_tile_index.y < 0) {
|
||||||
|
res.y += tile_size;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct v2i32 sim_local_tile_index_from_world_tile_index(struct v2i32 world_tile_index)
|
||||||
|
{
|
||||||
|
struct v2i32 res = ZI;
|
||||||
|
res.x = world_tile_index.x % SIM_TILES_PER_CHUNK_SQRT;
|
||||||
|
res.y = world_tile_index.y % SIM_TILES_PER_CHUNK_SQRT;
|
||||||
|
if (world_tile_index.x < 0) {
|
||||||
|
res.x = SIM_TILES_PER_CHUNK_SQRT + res.x - 1;
|
||||||
|
}
|
||||||
|
if (world_tile_index.y < 0) {
|
||||||
|
res.y = SIM_TILES_PER_CHUNK_SQRT + res.y - 1;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct v2i32 sim_world_tile_index_from_local_tile_index(struct v2i32 tile_chunk_index, struct v2i32 local_tile_index)
|
||||||
|
{
|
||||||
|
struct v2i32 res = ZI;
|
||||||
|
res.x = (tile_chunk_index.x * SIM_TILES_PER_CHUNK_SQRT) + local_tile_index.x;
|
||||||
|
res.y = (tile_chunk_index.y * SIM_TILES_PER_CHUNK_SQRT) + local_tile_index.y;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct v2i32 sim_tile_chunk_index_from_world_tile_index(struct v2i32 world_tile_index)
|
||||||
|
{
|
||||||
|
struct v2i32 res = ZI;
|
||||||
|
res.x = world_tile_index.x / SIM_TILES_PER_CHUNK_SQRT;
|
||||||
|
res.y = world_tile_index.y / SIM_TILES_PER_CHUNK_SQRT;
|
||||||
|
res.x -= world_tile_index.x < 0;
|
||||||
|
res.y -= world_tile_index.y < 0;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sim_snapshot_set_tile(struct sim_snapshot *ss, struct v2i32 world_tile_index, enum sim_tile_kind tile_kind)
|
||||||
|
{
|
||||||
|
struct v2i32 chunk_index = sim_tile_chunk_index_from_world_tile_index(world_tile_index);
|
||||||
|
|
||||||
|
struct sim_ent_id chunk_id = sim_ent_tile_chunk_id_from_tile_chunk_index(chunk_index);
|
||||||
|
struct sim_ent *chunk_ent = sim_ent_from_id(ss, chunk_id);
|
||||||
|
if (!chunk_ent->valid) {
|
||||||
|
struct sim_ent *root = sim_ent_from_id(ss, SIM_ENT_ROOT_ID);
|
||||||
|
chunk_ent = sim_ent_alloc_sync_src_with_id(root, chunk_id);
|
||||||
|
sim_ent_enable_prop(chunk_ent, SEPROP_TILE_CHUNK);
|
||||||
|
chunk_ent->tile_chunk_index = chunk_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct v2i32 local_index = sim_local_tile_index_from_world_tile_index(world_tile_index);
|
||||||
|
chunk_ent->tile_chunk_tiles[local_index.x + (local_index.y * SIM_TILES_PER_CHUNK_SQRT)] = tile_kind;
|
||||||
|
}
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Snapshot lerp
|
* Snapshot lerp
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|||||||
13
src/sim.h
13
src/sim.h
@ -167,8 +167,11 @@ enum sim_cmd_kind {
|
|||||||
|
|
||||||
enum sim_tile_kind {
|
enum sim_tile_kind {
|
||||||
SIM_TILE_KIND_NONE,
|
SIM_TILE_KIND_NONE,
|
||||||
SIM_TILE_KIND_TEST
|
SIM_TILE_KIND_WALL,
|
||||||
|
|
||||||
|
NUM_SIM_TILE_KINDS
|
||||||
};
|
};
|
||||||
|
CT_ASSERT(NUM_SIM_TILE_KINDS < 256); /* Tile kind must fit in 8 bits */
|
||||||
|
|
||||||
struct sim_ent_bin;
|
struct sim_ent_bin;
|
||||||
|
|
||||||
@ -228,6 +231,14 @@ struct sim_snapshot *sim_snapshot_from_tick(struct sim_client *client, u64 tick)
|
|||||||
struct sim_snapshot *sim_snapshot_from_closest_tick_lte(struct sim_client *client, u64 tick);
|
struct sim_snapshot *sim_snapshot_from_closest_tick_lte(struct sim_client *client, u64 tick);
|
||||||
struct sim_snapshot *sim_snapshot_from_closest_tick_gte(struct sim_client *client, u64 tick);
|
struct sim_snapshot *sim_snapshot_from_closest_tick_gte(struct sim_client *client, u64 tick);
|
||||||
|
|
||||||
|
/* Tile */
|
||||||
|
struct v2i32 sim_world_tile_index_from_pos(struct v2 pos);
|
||||||
|
struct v2 sim_pos_from_world_tile_index(struct v2i32 world_tile_index);
|
||||||
|
struct v2i32 sim_local_tile_index_from_world_tile_index(struct v2i32 world_tile_index);
|
||||||
|
struct v2i32 sim_world_tile_index_from_local_tile_index(struct v2i32 tile_chunk_index, struct v2i32 local_tile_index);
|
||||||
|
struct v2i32 sim_tile_chunk_index_from_world_tile_index(struct v2i32 world_tile_index);
|
||||||
|
void sim_snapshot_set_tile(struct sim_snapshot *ss, struct v2i32 world_tile_index, enum sim_tile_kind tile_kind);
|
||||||
|
|
||||||
/* Lerp */
|
/* Lerp */
|
||||||
struct sim_snapshot *sim_snapshot_alloc_from_lerp(struct sim_client *client, struct sim_snapshot *ss0, struct sim_snapshot *ss1, f64 blend);
|
struct sim_snapshot *sim_snapshot_alloc_from_lerp(struct sim_client *client, struct sim_snapshot *ss0, struct sim_snapshot *ss1, f64 blend);
|
||||||
|
|
||||||
|
|||||||
@ -296,12 +296,11 @@ struct sim_ent_id sim_ent_collision_debug_id_from_ids(struct sim_ent_id player_i
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Returns the deterministic id of the tile chunk that should be produced at chunk pos */
|
/* Returns the deterministic id of the tile chunk that should be produced at chunk pos */
|
||||||
struct sim_ent_id sim_ent_chunk_id_from_chunk_pos(struct sim_ent_id player_id, struct v2i32 chunk_pos)
|
struct sim_ent_id sim_ent_tile_chunk_id_from_tile_chunk_index(struct v2i32 chunk_index)
|
||||||
{
|
{
|
||||||
struct sim_ent_id res = ZI;
|
struct sim_ent_id res = ZI;
|
||||||
res.uid = SIM_ENT_TILE_CHUNK_BASIS_UID;
|
res.uid = SIM_ENT_TILE_CHUNK_BASIS_UID;
|
||||||
res.uid = uid_combine(res.uid, player_id.uid);
|
res.uid = uid_combine(res.uid, UID(rand_u64_from_seed(chunk_index.x), rand_u64_from_seed(chunk_index.y)));
|
||||||
res.uid = uid_combine(res.uid, UID(rand_u64_from_seed(chunk_pos.x), rand_u64_from_seed(chunk_pos.y)));
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -564,20 +563,21 @@ void sim_ent_apply_torque(struct sim_ent *ent, f32 torque)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Tile chunk
|
* Tile
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
struct string sim_ent_get_tile_chunk_data(struct sim_ent *ent)
|
struct sim_ent *sim_tile_chunk_from_world_tile_index(struct sim_snapshot *ss, struct v2i32 world_tile_index)
|
||||||
{
|
{
|
||||||
(UNUSED)ent;
|
struct v2i32 chunk_index = sim_tile_chunk_index_from_world_tile_index(world_tile_index);
|
||||||
struct string res = ZI;
|
struct sim_ent_id chunk_id = sim_ent_tile_chunk_id_from_tile_chunk_index(chunk_index);
|
||||||
return res;
|
struct sim_ent *chunk_ent = sim_ent_from_id(ss, chunk_id);
|
||||||
|
return chunk_ent;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sim_ent_set_tile_chunk_data(struct sim_ent *ent, struct string data)
|
enum sim_tile_kind sim_get_chunk_tile(struct sim_ent *chunk_ent, struct v2i32 local_tile_index)
|
||||||
{
|
{
|
||||||
(UNUSED)ent;
|
enum sim_tile_kind res = chunk_ent->tile_chunk_tiles[local_tile_index.x + (local_tile_index.y * SIM_TILES_PER_CHUNK_SQRT)];
|
||||||
(UNUSED)data;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
|
|||||||
@ -25,6 +25,7 @@ enum sim_ent_prop {
|
|||||||
SEPROP_CMD,
|
SEPROP_CMD,
|
||||||
|
|
||||||
SEPROP_TILE_CHUNK,
|
SEPROP_TILE_CHUNK,
|
||||||
|
SEPROP_WALL,
|
||||||
|
|
||||||
/* Physics collision */
|
/* Physics collision */
|
||||||
SEPROP_SENSOR, /* This entity's collisions generate contacts */
|
SEPROP_SENSOR, /* This entity's collisions generate contacts */
|
||||||
@ -158,6 +159,17 @@ struct sim_ent {
|
|||||||
struct sim_ent_id chat_player;
|
struct sim_ent_id chat_player;
|
||||||
//struct string chat_msg;
|
//struct string chat_msg;
|
||||||
|
|
||||||
|
|
||||||
|
/* ====================================================================== */
|
||||||
|
/* Tile */
|
||||||
|
|
||||||
|
/* SEPROP_TILE_CHUNK */
|
||||||
|
|
||||||
|
/* FIXME: Move out of here */
|
||||||
|
u8 tile_chunk_tiles[SIM_TILES_PER_CHUNK_SQRT * SIM_TILES_PER_CHUNK_SQRT];
|
||||||
|
struct v2i32 tile_chunk_index;
|
||||||
|
|
||||||
|
|
||||||
/* ====================================================================== */
|
/* ====================================================================== */
|
||||||
/* Client */
|
/* Client */
|
||||||
|
|
||||||
@ -505,7 +517,7 @@ struct sim_ent *sim_ent_from_id(struct sim_snapshot *ss, struct sim_ent_id id);
|
|||||||
struct sim_ent_id sim_ent_random_id(void);
|
struct sim_ent_id sim_ent_random_id(void);
|
||||||
struct sim_ent_id sim_ent_contact_constraint_id_from_contacting_ids(struct sim_ent_id player_id, struct sim_ent_id id0, struct sim_ent_id id1);
|
struct sim_ent_id sim_ent_contact_constraint_id_from_contacting_ids(struct sim_ent_id player_id, struct sim_ent_id id0, struct sim_ent_id id1);
|
||||||
struct sim_ent_id sim_ent_collision_debug_id_from_ids(struct sim_ent_id player_id, struct sim_ent_id id0, struct sim_ent_id id1);
|
struct sim_ent_id sim_ent_collision_debug_id_from_ids(struct sim_ent_id player_id, struct sim_ent_id id0, struct sim_ent_id id1);
|
||||||
struct sim_ent_id sim_ent_chunk_id_from_chunk_pos(struct sim_ent_id player_id, struct v2i32 chunk_pos);
|
struct sim_ent_id sim_ent_tile_chunk_id_from_tile_chunk_index(struct v2i32 chunk_start);
|
||||||
|
|
||||||
/* Query */
|
/* Query */
|
||||||
struct sim_ent *sim_ent_find_first_match_one(struct sim_snapshot *ss, enum sim_ent_prop prop);
|
struct sim_ent *sim_ent_find_first_match_one(struct sim_snapshot *ss, enum sim_ent_prop prop);
|
||||||
@ -530,9 +542,9 @@ void sim_ent_apply_force_to_center(struct sim_ent *ent, struct v2 force);
|
|||||||
void sim_ent_apply_angular_impulse(struct sim_ent *ent, f32 impulse);
|
void sim_ent_apply_angular_impulse(struct sim_ent *ent, f32 impulse);
|
||||||
void sim_ent_apply_torque(struct sim_ent *ent, f32 torque);
|
void sim_ent_apply_torque(struct sim_ent *ent, f32 torque);
|
||||||
|
|
||||||
/* Tile chunk */
|
/* Tile */
|
||||||
struct string sim_ent_get_tile_chunk_data(struct sim_ent *ent);
|
struct sim_ent *sim_tile_chunk_from_world_tile_index(struct sim_snapshot *ss, struct v2i32 world_tile_index);
|
||||||
void sim_ent_set_tile_chunk_data(struct sim_ent *ent, struct string data);
|
enum sim_tile_kind sim_get_chunk_tile(struct sim_ent *chunk_ent, struct v2i32 local_tile_index);
|
||||||
|
|
||||||
/* Lerp */
|
/* Lerp */
|
||||||
void sim_ent_lerp(struct sim_ent *e, struct sim_ent *e0, struct sim_ent *e1, f64 blend);
|
void sim_ent_lerp(struct sim_ent *e, struct sim_ent *e0, struct sim_ent *e1, f64 blend);
|
||||||
|
|||||||
142
src/sim_step.c
142
src/sim_step.c
@ -327,15 +327,16 @@ INTERNAL void test_spawn_entities3(struct sim_ent *parent, struct v2 pos)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
INTERNAL void test_spawn_tile(struct sim_ent *parent, struct v2 cursor_pos)
|
INTERNAL void test_spawn_tile(struct sim_snapshot *world, struct v2 world_pos)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
struct sim_ent *e = sim_ent_alloc_sync_src(parent);
|
struct sim_ent *e = sim_ent_alloc_sync_src(parent);
|
||||||
|
|
||||||
i32 sign_x = (cursor_pos.x >= 0) - (cursor_pos.x < 0);
|
i32 sign_x = (world_pos.x >= 0) - (world_pos.x < 0);
|
||||||
i32 sign_y = (cursor_pos.y >= 0) - (cursor_pos.y < 0);
|
i32 sign_y = (world_pos.y >= 0) - (world_pos.y < 0);
|
||||||
struct v2i32 tile_index = V2I32(cursor_pos.x * SIM_TILES_PER_UNIT_SQRT, cursor_pos.y * SIM_TILES_PER_UNIT_SQRT);
|
struct v2i32 tile_index = V2I32(world_pos.x * SIM_TILES_PER_UNIT_SQRT, world_pos.y * SIM_TILES_PER_UNIT_SQRT);
|
||||||
cursor_pos.x -= sign_x < 0;
|
world_pos.x -= sign_x < 0;
|
||||||
cursor_pos.y -= sign_y < 0;
|
world_pos.y -= sign_y < 0;
|
||||||
|
|
||||||
struct v2 tile_size = V2(1.f / SIM_TILES_PER_UNIT_SQRT, 1.f / SIM_TILES_PER_UNIT_SQRT);
|
struct v2 tile_size = V2(1.f / SIM_TILES_PER_UNIT_SQRT, 1.f / SIM_TILES_PER_UNIT_SQRT);
|
||||||
|
|
||||||
@ -359,6 +360,10 @@ INTERNAL void test_spawn_tile(struct sim_ent *parent, struct v2 cursor_pos)
|
|||||||
sim_ent_enable_prop(e, SEPROP_SOLID);
|
sim_ent_enable_prop(e, SEPROP_SOLID);
|
||||||
struct quad collider_quad = quad_from_rect(RECT(-tile_size.x / 2, -tile_size.y / 2, tile_size.y, tile_size.y));
|
struct quad collider_quad = quad_from_rect(RECT(-tile_size.x / 2, -tile_size.y / 2, tile_size.y, tile_size.y));
|
||||||
e->local_collider = collider_from_quad(collider_quad);
|
e->local_collider = collider_from_quad(collider_quad);
|
||||||
|
#else
|
||||||
|
struct v2i32 tile_index = sim_world_tile_index_from_pos(world_pos);
|
||||||
|
sim_snapshot_set_tile(world, tile_index, SIM_TILE_KIND_WALL);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -369,19 +374,22 @@ INTERNAL void test_spawn_tile(struct sim_ent *parent, struct v2 cursor_pos)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
INTERNAL SORT_COMPARE_FUNC_DEF(tile_chunk_sort, arg_a, arg_b, udata)
|
||||||
|
{
|
||||||
|
(UNUSED)udata;
|
||||||
|
struct sim_ent *a = (struct sim_ent *)arg_a;
|
||||||
|
struct sim_ent *b = (struct sim_ent *)arg_b;
|
||||||
|
struct v2i32 index_a = a->tile_chunk_index;
|
||||||
|
struct v2i32 index_b = b->tile_chunk_index;
|
||||||
|
|
||||||
|
i32 res = 0;
|
||||||
|
res = 2 * ((index_a.y > index_b.y) - (index_a.y < index_b.y)) + ((index_a.x > index_b.x) - (index_a.x < index_b.x));
|
||||||
/* TODO: Move this */
|
return res;
|
||||||
enum tile_kind {
|
}
|
||||||
TILE_KIND_NONE,
|
|
||||||
TILE_KIND_WALL
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
INTERNAL void test_generate_walls(struct sim_ent *parent)
|
INTERNAL void test_generate_walls(struct sim_ent *parent)
|
||||||
{
|
{
|
||||||
#if 0
|
#if 1
|
||||||
struct temp_arena scratch = scratch_begin_no_conflict();
|
struct temp_arena scratch = scratch_begin_no_conflict();
|
||||||
struct sim_snapshot *world = parent->ss;
|
struct sim_snapshot *world = parent->ss;
|
||||||
|
|
||||||
@ -395,31 +403,101 @@ INTERNAL void test_generate_walls(struct sim_ent *parent)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Sort tile chunks */
|
/* Sort tile chunks */
|
||||||
|
struct sim_ent **tile_chunks = arena_dry_push(scratch.arena, struct sim_ent *);
|
||||||
|
u64 tile_chunks_count = 0;
|
||||||
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
|
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
|
||||||
struct sim_ent *ent = &world->ents[ent_index];
|
struct sim_ent *ent = &world->ents[ent_index];
|
||||||
if (!ent->valid) continue;
|
if (!ent->valid) continue;
|
||||||
if (sim_ent_has_prop(ent, SEPROP_TILE_CHUNK)) {
|
if (sim_ent_has_prop(ent, SEPROP_TILE_CHUNK)) {
|
||||||
|
*arena_push_no_zero(scratch.arena, struct sim_ent *) = ent;
|
||||||
|
++tile_chunks_count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
merge_sort(tile_chunks, tile_chunks_count, sizeof(*tile_chunks), tile_chunk_sort, NULL);
|
||||||
|
|
||||||
/* Generate horizontal walls */
|
struct wall_node {
|
||||||
|
struct v2i32 start;
|
||||||
|
struct v2i32 end;
|
||||||
|
struct wall_node *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct wall_node *first_wall = NULL;
|
||||||
|
|
||||||
|
/* Generate horizontal wall nodes */
|
||||||
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
|
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
|
||||||
struct sim_ent *ent = &world->ents[ent_index];
|
struct sim_ent *chunk = &world->ents[ent_index];
|
||||||
if (!ent->valid) continue;
|
if (!chunk->valid) continue;
|
||||||
if (sim_ent_has_prop(ent, SEPROP_TILE_CHUNK)) {
|
if (sim_ent_has_prop(chunk, SEPROP_TILE_CHUNK)) {
|
||||||
//struct v2i32 chunk_start = ent->tile_chunk_start;
|
struct v2i32 chunk_index = chunk->tile_chunk_index;
|
||||||
//struct v2i32 chunk_end = v2_add(chunk_start, V2(SIM_TILES_PER_CHUNK_SQRT, SIM_TILES_PER_CHUNK_SQRT));
|
struct sim_ent *top_chunk = sim_tile_chunk_from_world_tile_index(world, V2I32(chunk_index.x, chunk_index.y - 1));
|
||||||
//struct sim_ent *left_chunk = sim_chunk_from_index(world, v2i32(chunk_start.x - 1, chunk_start.y));
|
struct sim_ent *bottom_chunk = sim_tile_chunk_from_world_tile_index(world, V2I32(chunk_index.x, chunk_index.y + 1));
|
||||||
//struct sim_ent *right_chunk = sim_chunk_from_index(world, v2i32(chunk_end.x, chunk_start.y));
|
/* If there's no chunk below this one, then do an extra iteration (since walls are created at the top of each tile) */
|
||||||
//struct sim_ent *top_chunk = sim_chunk_from_index(world, v2i32(chunk_start.x, chunk_start.y - 1);
|
i32 y_iterations = SIM_TILES_PER_CHUNK_SQRT + !bottom_chunk->valid;
|
||||||
//struct sim_ent *bottom_chunk = sim_chunk_from_index(world, v2i32(chunk_start.x, chunk_start.y));
|
i32 x_iterations = SIM_TILES_PER_CHUNK_SQRT + 1;
|
||||||
for (i64 tile_y = 0; tile_y < SIM_TILES_PER_CHUNK_SQRT; ++tile_y) {
|
for (i32 tile_y = 0; tile_y < y_iterations; ++tile_y) {
|
||||||
i64 tile_x = 0;
|
i32 wall_start = -1;
|
||||||
while (true) {
|
i32 wall_end = -1;
|
||||||
|
for (i32 tile_x = 0; tile_x < x_iterations; ++tile_x) {
|
||||||
|
enum sim_tile_kind tile = SIM_TILE_KIND_NONE;
|
||||||
|
enum sim_tile_kind top_tile = SIM_TILE_KIND_NONE;
|
||||||
|
if (tile_x < SIM_TILES_PER_CHUNK_SQRT && tile_y < SIM_TILES_PER_CHUNK_SQRT) {
|
||||||
|
tile = sim_get_chunk_tile(chunk, V2I32(tile_x, tile_y));
|
||||||
|
}
|
||||||
|
if (tile == SIM_TILE_KIND_NONE && tile_x < SIM_TILES_PER_CHUNK_SQRT) {
|
||||||
|
if (tile_y == 0) {
|
||||||
|
if (top_chunk->valid) {
|
||||||
|
top_tile = sim_get_chunk_tile(top_chunk, V2I32(tile_x, SIM_TILES_PER_CHUNK_SQRT - 1));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
top_tile = sim_get_chunk_tile(chunk, V2I32(tile_x, tile_y - 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (top_tile == SIM_TILE_KIND_WALL && tile != SIM_TILE_KIND_WALL) {
|
||||||
|
if (wall_start < 0) {
|
||||||
|
/* Start wall */
|
||||||
|
wall_start = tile_x;
|
||||||
|
}
|
||||||
|
/* Extend wall */
|
||||||
|
wall_end = tile_x + 1;
|
||||||
|
} else if (wall_end >= 0) {
|
||||||
|
/* Stop wall */
|
||||||
|
struct v2i32 start = sim_world_tile_index_from_local_tile_index(chunk_index, V2I32(wall_start, tile_y));
|
||||||
|
struct v2i32 end = sim_world_tile_index_from_local_tile_index(chunk_index, V2I32(wall_end, tile_y));
|
||||||
|
struct wall_node *node = arena_push(scratch.arena, struct wall_node);
|
||||||
|
node->start = start;
|
||||||
|
node->end = end;
|
||||||
|
node->next = first_wall;
|
||||||
|
first_wall = node;
|
||||||
|
wall_start = -1;
|
||||||
|
wall_end = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
/* Create wall entities */
|
||||||
}
|
for (struct wall_node *node = first_wall; node; node = node->next) {
|
||||||
}
|
struct sim_ent *wall_ent = sim_ent_alloc_sync_src(parent);
|
||||||
|
sim_ent_enable_prop(wall_ent, SEPROP_WALL);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
struct v2i32 node_start = node->start;
|
||||||
|
struct v2i32 node_end = node->end;
|
||||||
|
|
||||||
|
struct v2 start = V2(node_start.x / SIM_TILES_PER_UNIT_SQRT, node_start.y / SIM_TILES_PER_UNIT_SQRT);
|
||||||
|
struct v2 end = V2(node_end.x / SIM_TILES_PER_UNIT_SQRT, node_end.y / SIM_TILES_PER_UNIT_SQRT);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct v2 start = sim_pos_from_world_tile_index(node->start);
|
||||||
|
struct v2 end = sim_pos_from_world_tile_index(node->end);
|
||||||
|
|
||||||
|
struct xform xf = XFORM_POS(start);
|
||||||
|
sim_ent_set_xform(wall_ent, xf);
|
||||||
|
|
||||||
|
sim_ent_enable_prop(wall_ent, SEPROP_SOLID);
|
||||||
|
wall_ent->local_collider.count = 2;
|
||||||
|
wall_ent->local_collider.points[1] = v2_sub(end, start);
|
||||||
}
|
}
|
||||||
|
|
||||||
scratch_end(scratch);
|
scratch_end(scratch);
|
||||||
@ -840,7 +918,7 @@ void sim_step(struct sim_step_ctx *ctx)
|
|||||||
sim_ent_set_tile_chunk_data(chunk_ent, new_data);
|
sim_ent_set_tile_chunk_data(chunk_ent, new_data);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
test_spawn_tile(root, player->player_cursor_pos);
|
test_spawn_tile(world, player->player_cursor_pos);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -39,7 +39,7 @@ b32 string_ends_with(struct string str, struct string substring);
|
|||||||
* Format
|
* Format
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
#define DEFAULT_FMT_PRECISION 6
|
#define DEFAULT_FMT_PRECISION 3
|
||||||
|
|
||||||
enum fmt_type {
|
enum fmt_type {
|
||||||
FMT_TYPE_NONE,
|
FMT_TYPE_NONE,
|
||||||
|
|||||||
83
src/user.c
83
src/user.c
@ -408,9 +408,9 @@ INTERNAL struct string get_ent_debug_text(struct arena *arena, struct sim_ent *e
|
|||||||
struct xform xf = sim_ent_get_xform(ent);
|
struct xform xf = sim_ent_get_xform(ent);
|
||||||
struct v2 linear_velocity = ent->linear_velocity;
|
struct v2 linear_velocity = ent->linear_velocity;
|
||||||
f32 angular_velocity = ent->angular_velocity;
|
f32 angular_velocity = ent->angular_velocity;
|
||||||
res.len += string_format(arena, LIT("pos: (%F, %F)\n"), FMT_FLOAT_P(xf.og.x, 3), FMT_FLOAT_P(xf.og.y, 3)).len;
|
res.len += string_format(arena, LIT("pos: (%F, %F)\n"), FMT_FLOAT(xf.og.x), FMT_FLOAT(xf.og.y)).len;
|
||||||
res.len += string_format(arena, LIT("linear velocity: (%F, %F)\n"), FMT_FLOAT_P(linear_velocity.x, 3), FMT_FLOAT_P(linear_velocity.y, 3)).len;
|
res.len += string_format(arena, LIT("linear velocity: (%F, %F)\n"), FMT_FLOAT(linear_velocity.x), FMT_FLOAT(linear_velocity.y)).len;
|
||||||
res.len += string_format(arena, LIT("angular velocity: %F\n"), FMT_FLOAT_P(angular_velocity, 3)).len;
|
res.len += string_format(arena, LIT("angular velocity: %F\n"), FMT_FLOAT(angular_velocity)).len;
|
||||||
|
|
||||||
/* Children */
|
/* Children */
|
||||||
if (!sim_ent_id_is_nil(ent->first) || !sim_ent_id_is_nil(ent->last)) {
|
if (!sim_ent_id_is_nil(ent->first) || !sim_ent_id_is_nil(ent->last)) {
|
||||||
@ -1103,6 +1103,30 @@ INTERNAL void user_update(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Draw tiles */
|
||||||
|
/* TODO: Something better */
|
||||||
|
if (sim_ent_has_prop(ent, SEPROP_TILE_CHUNK)) {
|
||||||
|
struct v2i32 chunk_index = ent->tile_chunk_index;
|
||||||
|
struct sprite_tag tile_sprite = sprite_tag_from_path(LIT("res/graphics/tile.ase"));
|
||||||
|
f32 tile_size = 1.f / SIM_TILES_PER_UNIT_SQRT;
|
||||||
|
for (i32 tile_y = 0; tile_y < SIM_TILES_PER_CHUNK_SQRT; ++tile_y) {
|
||||||
|
for (i32 tile_x = 0; tile_x < SIM_TILES_PER_CHUNK_SQRT; ++tile_x) {
|
||||||
|
struct v2i32 local_tile_index = V2I32(tile_x, tile_y);
|
||||||
|
enum sim_tile_kind tile = ent->tile_chunk_tiles[local_tile_index.x + (local_tile_index.y * SIM_TILES_PER_CHUNK_SQRT)];
|
||||||
|
//if (tile > -1) {
|
||||||
|
if (tile == SIM_TILE_KIND_WALL) {
|
||||||
|
struct v2i32 world_tile_index = sim_world_tile_index_from_local_tile_index(chunk_index, local_tile_index);
|
||||||
|
|
||||||
|
struct v2 pos = sim_pos_from_world_tile_index(world_tile_index);
|
||||||
|
|
||||||
|
struct quad quad = quad_from_rect(RECT(pos.x, pos.y, tile_size, tile_size));
|
||||||
|
struct draw_texture_params params = DRAW_TEXTURE_PARAMS(.sprite = tile_sprite);
|
||||||
|
draw_quad_texture(G.world_cmd_buffer, params, quad);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Debug draw entity info */
|
/* Debug draw entity info */
|
||||||
if (G.debug_draw && !skip_debug_draw) {
|
if (G.debug_draw && !skip_debug_draw) {
|
||||||
struct temp_arena temp = arena_temp_begin(scratch.arena);
|
struct temp_arena temp = arena_temp_begin(scratch.arena);
|
||||||
@ -1298,8 +1322,8 @@ INTERNAL void user_update(void)
|
|||||||
FMT_UINT(e0->handle.idx),
|
FMT_UINT(e0->handle.idx),
|
||||||
FMT_UINT(e1->handle.idx),
|
FMT_UINT(e1->handle.idx),
|
||||||
FMT_HEX(point.id),
|
FMT_HEX(point.id),
|
||||||
FMT_FLOAT_P(point.normal_impulse, 3),
|
FMT_FLOAT(point.normal_impulse),
|
||||||
FMT_FLOAT_P(point.tangent_impulse, 3),
|
FMT_FLOAT(point.tangent_impulse),
|
||||||
FMT_FLOAT_P(point.starting_separation, 6),
|
FMT_FLOAT_P(point.starting_separation, 6),
|
||||||
FMT_FLOAT_P(data->normal.x, 6), FMT_FLOAT_P(data->normal.y, 6),
|
FMT_FLOAT_P(data->normal.x, 6), FMT_FLOAT_P(data->normal.y, 6),
|
||||||
FMT_UINT(data->num_points));
|
FMT_UINT(data->num_points));
|
||||||
@ -1768,26 +1792,26 @@ INTERNAL void user_update(void)
|
|||||||
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("blended world tick: %F"), FMT_UINT(G.ss_blended->tick)));
|
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("blended world tick: %F"), FMT_UINT(G.ss_blended->tick)));
|
||||||
pos.y += spacing;
|
pos.y += spacing;
|
||||||
|
|
||||||
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("blended world time: %F"), FMT_FLOAT_P(SECONDS_FROM_NS(G.ss_blended->sim_time_ns), 3)));
|
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("blended world time: %F"), FMT_FLOAT(SECONDS_FROM_NS(G.ss_blended->sim_time_ns))));
|
||||||
pos.y += spacing;
|
pos.y += spacing;
|
||||||
pos.y += spacing;
|
pos.y += spacing;
|
||||||
|
|
||||||
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("average local sim publish dt: %F"), FMT_FLOAT_P(SECONDS_FROM_NS(G.average_local_to_user_snapshot_publish_dt_ns), 3)));
|
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("average local sim publish dt: %F"), FMT_FLOAT(SECONDS_FROM_NS(G.average_local_to_user_snapshot_publish_dt_ns))));
|
||||||
pos.y += spacing;
|
pos.y += spacing;
|
||||||
|
|
||||||
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("local sim last known tick: %F"), FMT_UINT(G.local_sim_last_known_tick)));
|
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("local sim last known tick: %F"), FMT_UINT(G.local_sim_last_known_tick)));
|
||||||
pos.y += spacing;
|
pos.y += spacing;
|
||||||
|
|
||||||
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("local sim last known time: %F"), FMT_FLOAT_P(SECONDS_FROM_NS(G.local_sim_last_known_time_ns), 3)));
|
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("local sim last known time: %F"), FMT_FLOAT(SECONDS_FROM_NS(G.local_sim_last_known_time_ns))));
|
||||||
pos.y += spacing;
|
pos.y += spacing;
|
||||||
|
|
||||||
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("local sim predicted time: %F"), FMT_FLOAT_P(SECONDS_FROM_NS(G.local_sim_predicted_time_ns), 3)));
|
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("local sim predicted time: %F"), FMT_FLOAT(SECONDS_FROM_NS(G.local_sim_predicted_time_ns))));
|
||||||
pos.y += spacing;
|
pos.y += spacing;
|
||||||
|
|
||||||
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("render time target: %F"), FMT_FLOAT_P(SECONDS_FROM_NS(G.render_time_target_ns), 3)));
|
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("render time target: %F"), FMT_FLOAT(SECONDS_FROM_NS(G.render_time_target_ns))));
|
||||||
pos.y += spacing;
|
pos.y += spacing;
|
||||||
|
|
||||||
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("render time: %F"), FMT_FLOAT_P(SECONDS_FROM_NS(G.render_time_ns), 3)));
|
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("render time: %F"), FMT_FLOAT(SECONDS_FROM_NS(G.render_time_ns))));
|
||||||
pos.y += spacing;
|
pos.y += spacing;
|
||||||
pos.y += spacing;
|
pos.y += spacing;
|
||||||
|
|
||||||
@ -1795,23 +1819,40 @@ INTERNAL void user_update(void)
|
|||||||
pos.y += spacing;
|
pos.y += spacing;
|
||||||
pos.y += spacing;
|
pos.y += spacing;
|
||||||
|
|
||||||
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("Network read: %F mbit/s"), FMT_FLOAT_P((f64)G.net_bytes_read.last_second * 8 / 1000 / 1000, 3)));
|
struct v2 world_cursor = G.world_cursor;
|
||||||
|
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("cursor world: %F, %F"), FMT_FLOAT(world_cursor.x), FMT_FLOAT(world_cursor.y)));
|
||||||
pos.y += spacing;
|
pos.y += spacing;
|
||||||
|
|
||||||
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("Network write: %F mbit/s"), FMT_FLOAT_P((f64)G.net_bytes_sent.last_second * 8 / 1000 / 1000, 3)));
|
struct v2i32 world_tile_cursor = sim_world_tile_index_from_pos(world_cursor);
|
||||||
|
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("cursor world tile: %F, %F"), FMT_SINT(world_tile_cursor.x), FMT_SINT(world_tile_cursor.y)));
|
||||||
pos.y += spacing;
|
pos.y += spacing;
|
||||||
|
|
||||||
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("Ping (real): %F ms"), FMT_FLOAT_P(SECONDS_FROM_NS(local_player->player_last_rtt_ns) * 1000, 3)));
|
struct v2i32 local_tile_cursor = sim_local_tile_index_from_world_tile_index(world_tile_cursor);
|
||||||
|
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("cursor local tile: %F, %F"), FMT_SINT(local_tile_cursor.x), FMT_SINT(local_tile_cursor.y)));
|
||||||
pos.y += spacing;
|
pos.y += spacing;
|
||||||
|
|
||||||
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("Ping (average): %F ms"), FMT_FLOAT_P(local_player->player_average_rtt_seconds * 1000, 3)));
|
struct v2i32 tile_chunk_cursor = sim_tile_chunk_index_from_world_tile_index(world_tile_cursor);
|
||||||
|
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("cursor tile chunk: %F, %F"), FMT_SINT(tile_chunk_cursor.x), FMT_SINT(tile_chunk_cursor.y)));
|
||||||
pos.y += spacing;
|
pos.y += spacing;
|
||||||
pos.y += spacing;
|
pos.y += spacing;
|
||||||
|
|
||||||
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("Memory usage: %F MiB"), FMT_FLOAT_P((f64)gstat_get(GSTAT_MEMORY_COMMITTED) / 1024 / 1024, 3)));
|
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("Network read: %F mbit/s"), FMT_FLOAT((f64)G.net_bytes_read.last_second * 8 / 1000 / 1000)));
|
||||||
pos.y += spacing;
|
pos.y += spacing;
|
||||||
|
|
||||||
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("Virtual memory usage: %F TiB"), FMT_FLOAT_P((f64)gstat_get(GSTAT_MEMORY_RESERVED) / 1024 / 1024 / 1024 / 1024, 3)));
|
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("Network write: %F mbit/s"), FMT_FLOAT((f64)G.net_bytes_sent.last_second * 8 / 1000 / 1000)));
|
||||||
|
pos.y += spacing;
|
||||||
|
|
||||||
|
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("Ping (real): %F ms"), FMT_FLOAT(SECONDS_FROM_NS(local_player->player_last_rtt_ns) * 1000)));
|
||||||
|
pos.y += spacing;
|
||||||
|
|
||||||
|
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("Ping (average): %F ms"), FMT_FLOAT(local_player->player_average_rtt_seconds * 1000)));
|
||||||
|
pos.y += spacing;
|
||||||
|
pos.y += spacing;
|
||||||
|
|
||||||
|
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("Memory usage: %F MiB"), FMT_FLOAT((f64)gstat_get(GSTAT_MEMORY_COMMITTED) / 1024 / 1024)));
|
||||||
|
pos.y += spacing;
|
||||||
|
|
||||||
|
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("Virtual memory usage: %F TiB"), FMT_FLOAT((f64)gstat_get(GSTAT_MEMORY_RESERVED) / 1024 / 1024 / 1024 / 1024)));
|
||||||
pos.y += spacing;
|
pos.y += spacing;
|
||||||
|
|
||||||
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("Arenas allocated: %F"), FMT_UINT(gstat_get(GSTAT_NUM_ARENAS))));
|
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("Arenas allocated: %F"), FMT_UINT(gstat_get(GSTAT_NUM_ARENAS))));
|
||||||
@ -1956,16 +1997,16 @@ INTERNAL void user_update(void)
|
|||||||
renderer_texture_clear(G.backbuffer_texture, RGBA_F(0, 0, 0, 1));
|
renderer_texture_clear(G.backbuffer_texture, RGBA_F(0, 0, 0, 1));
|
||||||
|
|
||||||
/* Render to world texture */
|
/* Render to world texture */
|
||||||
renderer_texture_render(G.world_texture, G.world_cmd_buffer, G.world_to_ui_xf, ui_viewport, sprite_frame_scope);
|
renderer_texture_render(G.world_texture, G.world_cmd_buffer, G.world_to_ui_xf, ui_viewport);
|
||||||
|
|
||||||
/* Render to UI texture */
|
/* Render to UI texture */
|
||||||
renderer_texture_render(G.ui_texture, G.ui_cmd_buffer, XFORM_IDENT, ui_viewport, sprite_frame_scope);
|
renderer_texture_render(G.ui_texture, G.ui_cmd_buffer, XFORM_IDENT, ui_viewport);
|
||||||
|
|
||||||
/* Render to final texture */
|
/* Render to final texture */
|
||||||
renderer_texture_render(G.final_texture, G.final_cmd_buffer, XFORM_IDENT, ui_viewport, sprite_frame_scope);
|
renderer_texture_render(G.final_texture, G.final_cmd_buffer, XFORM_IDENT, ui_viewport);
|
||||||
|
|
||||||
/* Render to backbuffer */
|
/* Render to backbuffer */
|
||||||
renderer_texture_render(G.backbuffer_texture, G.backbuffer_cmd_buffer, XFORM_IDENT, backbuffer_viewport, sprite_frame_scope);
|
renderer_texture_render(G.backbuffer_texture, G.backbuffer_cmd_buffer, XFORM_IDENT, backbuffer_viewport);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Present */
|
/* Present */
|
||||||
|
|||||||
34
src/util.h
34
src/util.h
@ -108,25 +108,26 @@ INLINE void merge_sort(void *items, u64 item_count, u64 item_size, sort_compare_
|
|||||||
struct dict_entry {
|
struct dict_entry {
|
||||||
u64 hash;
|
u64 hash;
|
||||||
u64 value;
|
u64 value;
|
||||||
|
struct dict_entry *next_in_bin;
|
||||||
struct dict_entry *next;
|
struct dict_entry *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dict_bin {
|
struct dict_bin {
|
||||||
struct dict_entry *entry_head;
|
struct dict_entry *first;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dict {
|
struct dict {
|
||||||
u64 bins_count;
|
u64 bins_count;
|
||||||
struct dict_bin *bins;
|
struct dict_bin *bins;
|
||||||
|
struct dict_entry *first;
|
||||||
};
|
};
|
||||||
|
|
||||||
INLINE struct dict dict_init(struct arena *arena, u64 bins_count)
|
INLINE struct dict dict_init(struct arena *arena, u64 bins_count)
|
||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
struct dict dict = ZI;
|
struct dict dict = ZI;
|
||||||
bins_count = max_u64(bins_count, 1); /* Ensure at least 1 bin */
|
dict.bins_count = max_u64(bins_count, 1); /* Ensure at least 1 bin */
|
||||||
dict.bins_count = bins_count;
|
dict.bins = arena_push_array(arena, struct dict_bin, dict.bins_count);
|
||||||
dict.bins = arena_push_array(arena, struct dict_bin, bins_count);
|
|
||||||
return dict;
|
return dict;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,13 +137,13 @@ INLINE void dict_set(struct arena *arena, struct dict *dict, u64 hash, u64 value
|
|||||||
|
|
||||||
struct dict_bin *bin = &dict->bins[hash % dict->bins_count];
|
struct dict_bin *bin = &dict->bins[hash % dict->bins_count];
|
||||||
|
|
||||||
struct dict_entry *entry = bin->entry_head;
|
struct dict_entry *entry = bin->first;
|
||||||
while (entry) {
|
while (entry) {
|
||||||
if (hash == entry->hash) {
|
if (hash == entry->hash) {
|
||||||
/* Existing match found */
|
/* Existing match found */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
entry = entry->next;
|
entry = entry->next_in_bin;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* No match found, create new entry */
|
/* No match found, create new entry */
|
||||||
@ -150,28 +151,37 @@ INLINE void dict_set(struct arena *arena, struct dict *dict, u64 hash, u64 value
|
|||||||
entry = arena_push(arena, struct dict_entry);
|
entry = arena_push(arena, struct dict_entry);
|
||||||
entry->value = value;
|
entry->value = value;
|
||||||
entry->hash = hash;
|
entry->hash = hash;
|
||||||
entry->next = bin->entry_head;
|
entry->next_in_bin = bin->first;
|
||||||
bin->entry_head = entry;
|
entry->next = dict->first;
|
||||||
|
dict->first = entry;
|
||||||
|
bin->first = entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
entry->value = value;
|
entry->value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
INLINE u64 dict_get(const struct dict *dict, u64 hash)
|
INLINE struct dict_entry *dict_get_entry(const struct dict *dict, u64 hash)
|
||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
u64 result = 0;
|
struct dict_entry *result = NULL;
|
||||||
struct dict_bin *bin = &dict->bins[hash % dict->bins_count];
|
struct dict_bin *bin = &dict->bins[hash % dict->bins_count];
|
||||||
for (struct dict_entry *entry = bin->entry_head; entry; entry = entry->next) {
|
for (struct dict_entry *entry = bin->first; entry; entry = entry->next_in_bin) {
|
||||||
if (hash == entry->hash) {
|
if (hash == entry->hash) {
|
||||||
/* Match found */
|
/* Match found */
|
||||||
result = entry->value;
|
result = entry;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
INLINE u64 dict_get(const struct dict *dict, u64 hash)
|
||||||
|
{
|
||||||
|
__prof;
|
||||||
|
struct dict_entry *entry = dict_get_entry(dict, hash);
|
||||||
|
return entry ? entry->value : 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Sync flag
|
* Sync flag
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user