all storage systems are dynamic now

isolation_bkp/dynres
Dominik Madarász 2022-09-27 13:55:24 +00:00 committed by GitHub
parent b3589bac81
commit b6b632899d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 272 additions and 180 deletions

View File

@ -4,7 +4,6 @@ add_library(eco2d-foundation STATIC
src/core/game.c src/core/game.c
src/core/camera.c src/core/camera.c
src/platform/platform_raylib.c
src/platform/signal_handling.c src/platform/signal_handling.c
src/platform/profiler.c src/platform/profiler.c

View File

@ -6,6 +6,7 @@
#include "platform/signal_handling.h" #include "platform/signal_handling.h"
#include "net/network.h" #include "net/network.h"
#include "ents/entity.h" #include "ents/entity.h"
#include "ents/items.h"
#include "world/world_view.h" #include "world/world_view.h"
#include "world/entity_view.h" #include "world/entity_view.h"
#include "core/camera.h" #include "core/camera.h"
@ -31,7 +32,7 @@ static WORLD_PKT_READER(pkt_reader) {
pkt_header header = {0}; pkt_header header = {0};
uint32_t ok = pkt_header_decode(&header, data, datalen); uint32_t ok = pkt_header_decode(&header, data, datalen);
header.udata = udata; header.udata = udata;
if (ok && header.ok) { if (ok && header.ok) {
return pkt_handlers[header.id].handler(&header) >= 0; return pkt_handlers[header.id].handler(&header) >= 0;
} else { } else {
@ -66,7 +67,7 @@ static WORLD_PKT_WRITER(mp_cli_pkt_writer) {
void world_viewers_init(uint32_t num_viewers) { void world_viewers_init(uint32_t num_viewers) {
zpl_buffer_init(world_viewers, zpl_heap(), num_viewers); zpl_buffer_init(world_viewers, zpl_heap(), num_viewers);
for (uint32_t i = 0; i < num_viewers; i++) { for (uint32_t i = 0; i < num_viewers; i++) {
zpl_buffer_append(world_viewers, world_view_create(i)); zpl_buffer_append(world_viewers, world_view_create(i));
} }
@ -128,31 +129,39 @@ float game_time() {
void game_init(const char *ip, uint16_t port, game_kind play_mode, uint32_t num_viewers, int32_t seed, uint16_t chunk_size, uint16_t chunk_amount, int8_t is_dash_enabled) { void game_init(const char *ip, uint16_t port, game_kind play_mode, uint32_t num_viewers, int32_t seed, uint16_t chunk_size, uint16_t chunk_amount, int8_t is_dash_enabled) {
game_mode = play_mode; game_mode = play_mode;
game_should_close = false; game_should_close = false;
#ifndef _DEBUG #ifndef _DEBUG
const char *host_ip = "lab.zakto.pw"; const char *host_ip = "lab.zakto.pw";
#else #else
const char *host_ip = "127.0.0.1"; const char *host_ip = "127.0.0.1";
#endif #endif
uint16_t host_port = (port > 0) ? port : 27000; uint16_t host_port = (port > 0) ? port : 27000;
if (ip != NULL) { if (ip != NULL) {
host_ip = ip; host_ip = ip;
} }
// NOTE: initialise subsystems
{
assets_setup();
blocks_setup();
item_setup();
entity_spawndef_setup();
}
if (game_mode != GAMEKIND_HEADLESS) { if (game_mode != GAMEKIND_HEADLESS) {
platform_init(); platform_init();
world_viewers_init(num_viewers); world_viewers_init(num_viewers);
active_viewer = &world_viewers[0]; active_viewer = &world_viewers[0];
camera_reset(); camera_reset();
} }
if (game_mode != GAMEKIND_SINGLE) { if (game_mode != GAMEKIND_SINGLE) {
network_init(); network_init();
} }
if (game_mode == GAMEKIND_CLIENT) { if (game_mode == GAMEKIND_CLIENT) {
world_setup_pkt_handlers(pkt_reader, mp_cli_pkt_writer); world_setup_pkt_handlers(pkt_reader, mp_cli_pkt_writer);
network_client_connect(host_ip, host_port); network_client_connect(host_ip, host_port);
@ -161,13 +170,13 @@ void game_init(const char *ip, uint16_t port, game_kind play_mode, uint32_t num_
world_setup_pkt_handlers(pkt_reader, game_mode == GAMEKIND_SINGLE ? sp_pkt_writer : mp_pkt_writer); world_setup_pkt_handlers(pkt_reader, game_mode == GAMEKIND_SINGLE ? sp_pkt_writer : mp_pkt_writer);
world_init(seed, chunk_size, chunk_amount); world_init(seed, chunk_size, chunk_amount);
if (is_dash_enabled) flecs_dash_init(); if (is_dash_enabled) flecs_dash_init();
if (game_mode == GAMEKIND_HEADLESS) { if (game_mode == GAMEKIND_HEADLESS) {
network_server_start(0, 27000); network_server_start(0, 27000);
//ecs_set_target_fps(world_ecs(), 60); //ecs_set_target_fps(world_ecs(), 60);
} }
} }
if (game_mode == GAMEKIND_SINGLE) { if (game_mode == GAMEKIND_SINGLE) {
for (uint32_t i = 0; i < num_viewers; i++) { for (uint32_t i = 0; i < num_viewers; i++) {
pkt_00_init_send(i); pkt_00_init_send(i);
@ -180,27 +189,35 @@ int8_t game_is_networked() {
} }
void game_shutdown() { void game_shutdown() {
if (game_mode == GAMEKIND_CLIENT) { if (game_mode == GAMEKIND_CLIENT) {
network_client_disconnect(); network_client_disconnect();
} else { } else {
world_destroy(); world_destroy();
if (game_mode == GAMEKIND_HEADLESS) { if (game_mode == GAMEKIND_HEADLESS) {
network_server_stop(); network_server_stop();
} }
} }
if (game_mode != GAMEKIND_SINGLE) { if (game_mode != GAMEKIND_SINGLE) {
network_destroy(); network_destroy();
} }
if (game_mode != GAMEKIND_HEADLESS) { if (game_mode != GAMEKIND_HEADLESS) {
world_viewers_destroy(); world_viewers_destroy();
// TODO(zaklaus): crashes on exit // TODO(zaklaus): crashes on exit
//platform_shutdown(); //platform_shutdown();
} }
// NOTE: shutdown subsystems
{
item_cleanup();
entity_spawndef_cleanup();
blocks_cleanup();
assets_cleanup();
}
} }
uint8_t game_is_running() { uint8_t game_is_running() {
@ -228,10 +245,10 @@ void game_update() {
} }
else { else {
world_update(); world_update();
if (game_mode == GAMEKIND_HEADLESS) { if (game_mode == GAMEKIND_HEADLESS) {
network_server_tick(); network_server_tick();
static float ms_report = 2.5f; static float ms_report = 2.5f;
if (ms_report < get_cached_time()) { if (ms_report < get_cached_time()) {
ms_report = get_cached_time() + 5.f; ms_report = get_cached_time() + 5.f;
@ -239,7 +256,7 @@ void game_update() {
} }
} }
} }
last_update = get_cached_time(); last_update = get_cached_time();
} }

View File

@ -11,6 +11,17 @@
// NOTE(zaklaus): bring in entity spawnlist // NOTE(zaklaus): bring in entity spawnlist
#include "entity_spawnlist.c" #include "entity_spawnlist.c"
void entity_spawndef_cleanup() {
zpl_array_free(entity_spawnlist); entity_spawnlist = NULL;
}
void entity_spawndef_register(spawndef def) {
if (!entity_spawnlist) {
zpl_array_init(entity_spawnlist, zpl_heap());
}
zpl_array_append(entity_spawnlist, def);
}
uint64_t entity_spawn(uint16_t class_id) { uint64_t entity_spawn(uint16_t class_id) {
ecs_entity_t e = ecs_new(world_ecs(), 0); ecs_entity_t e = ecs_new(world_ecs(), 0);
@ -38,7 +49,7 @@ uint64_t entity_spawn(uint16_t class_id) {
} }
uint64_t entity_spawn_id(uint16_t id){ uint64_t entity_spawn_id(uint16_t id){
for (size_t i = 0; i < MAX_ENTITY_SPAWNDEFS; ++i){ for (zpl_isize i = 0; i < zpl_array_count(entity_spawnlist); ++i){
if (entity_spawnlist[i].id == id){ if (entity_spawnlist[i].id == id){
ZPL_ASSERT(entity_spawnlist[i].proc); ZPL_ASSERT(entity_spawnlist[i].proc);
return entity_spawnlist[i].proc(); return entity_spawnlist[i].proc();

View File

@ -1,8 +1,18 @@
#pragma once #pragma once
#include "platform/system.h" #include "platform/system.h"
#include "gen/assets.h"
#define ENTITY_ACTION_VELOCITY_THRESHOLD 0.05f #define ENTITY_ACTION_VELOCITY_THRESHOLD 0.05f
typedef struct {
asset_id id;
uint64_t (*proc)();
} spawndef;
void entity_spawndef_setup();
void entity_spawndef_cleanup();
void entity_spawndef_register(spawndef def);
uint64_t entity_spawn(uint16_t class_id /* 0 = no streaming */); uint64_t entity_spawn(uint16_t class_id /* 0 = no streaming */);
uint64_t entity_spawn_id(uint16_t id); uint64_t entity_spawn_id(uint16_t id);
void entity_batch_despawn(uint64_t *ids, size_t num_ids); void entity_batch_despawn(uint64_t *ids, size_t num_ids);

View File

@ -1,11 +1,8 @@
// NOTE(zaklaus): access to spawners // NOTE(zaklaus): access to spawners
#include "ents/storage.h" #include "ents/storage.h"
static struct { static spawndef *entity_spawnlist = 0;
asset_id id;
uint64_t (*proc)();
} entity_spawnlist[] = {
{ .id = ASSET_CHEST, .proc = storage_spawn }
};
#define MAX_ENTITY_SPAWNDEFS ((sizeof(entity_spawnlist))/(sizeof(entity_spawnlist[0]))) void entity_spawndef_setup(void) {
entity_spawndef_register((spawndef){ .id = ASSET_CHEST, .proc = storage_spawn });
}

View File

@ -9,10 +9,21 @@
#include "zpl.h" #include "zpl.h"
#include "items_list.c" #include "items_list.c"
#define ITEMS_COUNT (sizeof(items)/sizeof(item_desc))
void item_cleanup() {
zpl_array_free(items); items = NULL;
}
void item_register(item_desc desc) {
if (!items) {
zpl_array_init(items, zpl_heap());
}
zpl_array_append(items, desc);
}
static inline item_id item_resolve_proxy(item_id id) { static inline item_id item_resolve_proxy(item_id id) {
ZPL_ASSERT(id >= 0 && id < ITEMS_COUNT); ZPL_ASSERT(id >= 0 && id < zpl_array_count(items));
item_usage usage = items[id].usage; item_usage usage = items[id].usage;
if (usage == UKIND_PROXY) { if (usage == UKIND_PROXY) {
return item_find(items[id].proxy.id); return item_find(items[id].proxy.id);
@ -38,7 +49,7 @@ uint64_t item_spawn(asset_id kind, uint32_t qty) {
} }
item_id item_find(asset_id kind) { item_id item_find(asset_id kind) {
for (item_id i=0; i<ITEMS_COUNT; i++) { for (item_id i=0; i<zpl_array_count(items); i++) {
if (items[i].kind == kind) if (items[i].kind == kind)
return item_resolve_proxy(i); return item_resolve_proxy(i);
} }
@ -104,16 +115,16 @@ void item_despawn(uint64_t id) {
} }
uint32_t item_max_quantity(item_id id) { uint32_t item_max_quantity(item_id id) {
ZPL_ASSERT(id >= 0 && id < ITEMS_COUNT); ZPL_ASSERT(id >= 0 && id < zpl_array_count(items));
return items[id].max_quantity; return items[id].max_quantity;
} }
item_usage item_get_usage(item_id id) { item_usage item_get_usage(item_id id) {
ZPL_ASSERT(id >= 0 && id < ITEMS_COUNT); ZPL_ASSERT(id >= 0 && id < zpl_array_count(items));
return items[id].usage; return items[id].usage;
} }
bool item_get_place_directional(item_id id) { bool item_get_place_directional(item_id id) {
ZPL_ASSERT(id >= 0 && id < ITEMS_COUNT); ZPL_ASSERT(id >= 0 && id < zpl_array_count(items));
return items[id].place.directional; return items[id].place.directional;
} }

View File

@ -41,6 +41,10 @@ typedef struct {
typedef uint16_t item_id; typedef uint16_t item_id;
void item_setup();
void item_cleanup();
void item_register(item_desc desc);
// NOTE(zaklaus): item drops // NOTE(zaklaus): item drops
uint64_t item_spawn(asset_id kind, uint32_t qty); uint64_t item_spawn(asset_id kind, uint32_t qty);
void item_despawn(uint64_t id); void item_despawn(uint64_t id);

View File

@ -2,18 +2,20 @@
#include "world/entity_view.h" #include "world/entity_view.h"
#include "items_list_helpers.h" #include "items_list_helpers.h"
static item_desc items[] = { static item_desc *items = 0;
{ .kind = 0, .max_quantity = 0, },
ITEM_BLOCK(ASSET_DEMO_ICEMAKER, 64, ASSET_WATER), void item_setup() {
ITEM_SELF(ASSET_FENCE, 64), item_register((item_desc){ .kind = 0, .max_quantity = 0, });
ITEM_SELF(ASSET_WOOD, 64), item_register(ITEM_BLOCK(ASSET_DEMO_ICEMAKER, 64, ASSET_WATER));
ITEM_HOLD(ASSET_TREE, 64), item_register(ITEM_SELF(ASSET_FENCE, 64));
item_register(ITEM_SELF(ASSET_WOOD, 64));
ITEM_SELF_DIR(ASSET_BELT, 999), item_register(ITEM_HOLD(ASSET_TREE, 64));
ITEM_PROXY(ASSET_BELT_LEFT, ASSET_BELT),
ITEM_PROXY(ASSET_BELT_RIGHT, ASSET_BELT), item_register(ITEM_SELF_DIR(ASSET_BELT, 999));
ITEM_PROXY(ASSET_BELT_UP, ASSET_BELT), item_register(ITEM_PROXY(ASSET_BELT_LEFT, ASSET_BELT));
ITEM_PROXY(ASSET_BELT_DOWN, ASSET_BELT), item_register(ITEM_PROXY(ASSET_BELT_RIGHT, ASSET_BELT));
item_register(ITEM_PROXY(ASSET_BELT_UP, ASSET_BELT));
ITEM_ENT(ASSET_CHEST, 32, ASSET_CHEST), item_register(ITEM_PROXY(ASSET_BELT_DOWN, ASSET_BELT));
};
item_register(ITEM_ENT(ASSET_CHEST, 32, ASSET_CHEST));
}

View File

@ -1,14 +1,14 @@
#pragma once #pragma once
#define ITEM_HOLD(asset, qty)\ #define ITEM_HOLD(asset, qty)\
{\ (item_desc){\
.kind = asset,\ .kind = asset,\
.usage = UKIND_HOLD,\ .usage = UKIND_HOLD,\
.max_quantity = qty,\ .max_quantity = qty,\
} }
#define ITEM_BLOCK(asset, qty, build_asset)\ #define ITEM_BLOCK(asset, qty, build_asset)\
{\ (item_desc){\
.kind = asset,\ .kind = asset,\
.usage = UKIND_PLACE,\ .usage = UKIND_PLACE,\
.max_quantity = qty,\ .max_quantity = qty,\
@ -18,7 +18,7 @@
} }
#define ITEM_BLOCK_DIR(asset, qty, build_asset)\ #define ITEM_BLOCK_DIR(asset, qty, build_asset)\
{\ (item_desc){\
.kind = asset,\ .kind = asset,\
.usage = UKIND_PLACE,\ .usage = UKIND_PLACE,\
.max_quantity = qty,\ .max_quantity = qty,\
@ -29,7 +29,7 @@
} }
#define ITEM_PROXY(asset, proxy_id)\ #define ITEM_PROXY(asset, proxy_id)\
{\ (item_desc){\
.kind = asset,\ .kind = asset,\
.usage = UKIND_PROXY,\ .usage = UKIND_PROXY,\
.proxy = {\ .proxy = {\
@ -38,7 +38,7 @@
} }
#define ITEM_ENT(asset, qty, eid)\ #define ITEM_ENT(asset, qty, eid)\
{\ (item_desc){\
.kind = asset,\ .kind = asset,\
.usage = UKIND_PLACE_ITEM,\ .usage = UKIND_PLACE_ITEM,\
.max_quantity = qty,\ .max_quantity = qty,\

View File

@ -2,17 +2,15 @@
#include "raylib.h" #include "raylib.h"
#include "gen/texgen.h" #include "gen/texgen.h"
#define ASSETS_COUNT (sizeof(assets)/sizeof(asset))
typedef struct { typedef struct {
asset_id id; asset_id id;
asset_kind kind; asset_kind kind;
union { union {
Texture2D tex; Texture2D tex;
Sound snd; Sound snd;
}; };
// NOTE(zaklaus): metadata // NOTE(zaklaus): metadata
} asset; } asset;
@ -20,80 +18,92 @@ typedef struct {
#define ASSET_FRAME_RENDER_MS (1.0/5.0) #define ASSET_FRAME_RENDER_MS (1.0/5.0)
#define ASSET_FRAME_SKIP 4 #define ASSET_FRAME_SKIP 4
static int64_t assets_frame_counter = 1; static int64_t assets_resources_frame_counter = 1;
static double assets_frame_next_draw = 0.0; static double assets_resources_frame_next_draw = 0.0;
#include <time.h> #include <time.h>
int32_t assets_setup(void) { void assets_register(asset_desc a) {
for (uint32_t i=0; i<ASSETS_COUNT; i++) { if (!assets) {
zpl_array_init(assets, zpl_heap());
}
zpl_array_append(assets, ((asset){ .id = a.id, .kind = a.kind }));
}
void assets_cleanup(void) {
zpl_array_free(assets); assets = NULL;
}
int32_t assets_resources_setup(void) {
for (zpl_isize i=0; i<zpl_array_count(assets); i++) {
asset *b = &assets[i]; asset *b = &assets[i];
switch (b->kind) { switch (b->kind) {
case AKIND_TEXTURE: { case AKIND_TEXTURE: {
b->tex = texgen_build_sprite(b->id); b->tex = texgen_build_sprite(b->id);
}break; }break;
case AKIND_ANIM: { case AKIND_ANIM: {
b->tex = texgen_build_anim(b->id, 0); b->tex = texgen_build_anim(b->id, 0);
}break; }break;
case AKIND_SOUND: { case AKIND_SOUND: {
// TODO(zaklaus): soundgen // TODO(zaklaus): soundgen
}break; }break;
default: break; default: break;
} }
} }
assets_frame_next_draw = get_cached_time() + ASSET_FRAME_RENDER_MS; assets_resources_frame_next_draw = get_cached_time() + ASSET_FRAME_RENDER_MS;
return 0; return 0;
} }
int32_t assets_frame(void) { int32_t assets_resources_frame(void) {
if (assets_frame_next_draw < get_cached_time()) { if (assets_resources_frame_next_draw < get_cached_time()) {
for (uint32_t i=0; i<ASSETS_COUNT; i++) { for (zpl_isize i=0; i<zpl_array_count(assets); i++) {
asset *b = &assets[i]; asset *b = &assets[i];
switch (b->kind) { switch (b->kind) {
case AKIND_ANIM: { case AKIND_ANIM: {
UnloadTexture(b->tex); UnloadTexture(b->tex);
b->tex = texgen_build_anim(b->id, assets_frame_counter); b->tex = texgen_build_anim(b->id, assets_resources_frame_counter);
}break; }break;
default: break; default: break;
} }
} }
assets_frame_next_draw = get_cached_time() + ASSET_FRAME_RENDER_MS; assets_resources_frame_next_draw = get_cached_time() + ASSET_FRAME_RENDER_MS;
assets_frame_counter += ASSET_FRAME_SKIP; assets_resources_frame_counter += ASSET_FRAME_SKIP;
} }
return 0; return 0;
} }
void assets_destroy(void) { void assets_resources_destroy(void) {
for (uint32_t i=0; i<ASSETS_COUNT; i++) { for (zpl_isize i=0; i<zpl_array_count(assets); i++) {
switch (assets[i].kind) { switch (assets[i].kind) {
case AKIND_ANIM: case AKIND_ANIM:
case AKIND_TEXTURE: { case AKIND_TEXTURE: {
UnloadTexture(assets[i].tex); UnloadTexture(assets[i].tex);
}break; }break;
case AKIND_SOUND: { case AKIND_SOUND: {
// TODO(zaklaus): soundgen // TODO(zaklaus): soundgen
}break; }break;
default: break; default: break;
} }
} }
} }
uint16_t assets_find(asset_id id) { uint16_t assets_find(asset_id id) {
for (uint16_t i=0; i<ASSETS_COUNT; i++) { for (zpl_isize i=0; i<zpl_array_count(assets); i++) {
if (assets[i].id == id) if (assets[i].id == id)
return i; return i;
} }
ZPL_PANIC("Unknown asset id: %d\n", id); ZPL_PANIC("Unknown asset id: %d\n", id);
return ASSET_INVALID; return ASSET_INVALID;
} }

View File

@ -3,20 +3,30 @@
#define ASSET_INVALID 0xFF #define ASSET_INVALID 0xFF
#define ASSET_ENTRY(asset, asset_kind)\
(asset_desc){\
.id = asset,\
.kind = asset_kind,\
}
#define ASSET_SND(asset) ASSET_ENTRY(asset, AKIND_SOUND)
#define ASSET_TEX(asset) ASSET_ENTRY(asset, AKIND_TEXTURE)
#define ASSET_ANI(asset) ASSET_ENTRY(asset, AKIND_ANIM)
typedef enum { typedef enum {
// NOTE(zaklaus): Debug // NOTE(zaklaus): Debug
ASSET_EMPTY, ASSET_EMPTY,
ASSET_BLANK, ASSET_BLANK,
ASSET_BUILDMODE_HIGHLIGHT, ASSET_BUILDMODE_HIGHLIGHT,
// NOTE(zaklaus): entities // NOTE(zaklaus): entities
ASSET_PLAYER, ASSET_PLAYER,
ASSET_THING, ASSET_THING,
ASSET_CHEST, ASSET_CHEST,
// NOTE(zaklaus): items // NOTE(zaklaus): items
ASSET_DEMO_ICEMAKER, ASSET_DEMO_ICEMAKER,
// NOTE(zaklaus): blocks // NOTE(zaklaus): blocks
ASSET_FENCE, ASSET_FENCE,
ASSET_DEV, ASSET_DEV,
@ -30,13 +40,15 @@ typedef enum {
ASSET_HOLE, ASSET_HOLE,
ASSET_WOOD, ASSET_WOOD,
ASSET_TREE, ASSET_TREE,
ASSET_BELT, ASSET_BELT,
ASSET_BELT_LEFT, ASSET_BELT_LEFT,
ASSET_BELT_RIGHT, ASSET_BELT_RIGHT,
ASSET_BELT_UP, ASSET_BELT_UP,
ASSET_BELT_DOWN, ASSET_BELT_DOWN,
ASSET_NEXT_FREE,
MAX_ASSETS = 1024, MAX_ASSETS = 1024,
} asset_id; } asset_id;
@ -44,13 +56,23 @@ typedef enum {
AKIND_TEXTURE, AKIND_TEXTURE,
AKIND_ANIM, AKIND_ANIM,
AKIND_SOUND, AKIND_SOUND,
FORCE_AKIND_UINT8 = UINT8_MAX FORCE_AKIND_UINT8 = UINT8_MAX
} asset_kind; } asset_kind;
int32_t assets_setup(void); typedef struct {
int32_t assets_frame(void); asset_id id;
void assets_destroy(void); asset_kind kind;
} asset_desc;
void assets_setup(void);
void assets_cleanup(void);
void assets_register(asset_desc desc);
// resources
int32_t assets_resources_setup(void);
void assets_resources_destroy(void);
int32_t assets_resources_frame(void);
uint16_t assets_find(asset_id id); uint16_t assets_find(asset_id id);

View File

@ -1,39 +1,31 @@
#include "gen/assets.h" #include "gen/assets.h"
#define ASSET_ENTRY(asset, asset_kind)\ static asset *assets = 0;
{\
.id = asset,\
.kind = asset_kind,\
}
#define ASSET_SND(asset) ASSET_ENTRY(asset, AKIND_SOUND) void assets_setup() {
#define ASSET_TEX(asset) ASSET_ENTRY(asset, AKIND_TEXTURE) assets_register(ASSET_TEX(ASSET_EMPTY));
#define ASSET_ANI(asset) ASSET_ENTRY(asset, AKIND_ANIM) assets_register(ASSET_TEX(ASSET_BLANK));
assets_register(ASSET_TEX(ASSET_BUILDMODE_HIGHLIGHT));
assets_register(ASSET_TEX(ASSET_DEMO_ICEMAKER));
assets_register(ASSET_TEX(ASSET_CHEST));
static asset assets[] = { // NOTE: blocks
ASSET_TEX(ASSET_EMPTY), assets_register(ASSET_TEX(ASSET_FENCE));
ASSET_TEX(ASSET_BLANK), assets_register(ASSET_TEX(ASSET_DEV));
ASSET_TEX(ASSET_BUILDMODE_HIGHLIGHT), assets_register(ASSET_TEX(ASSET_GROUND));
ASSET_TEX(ASSET_DEMO_ICEMAKER), assets_register(ASSET_TEX(ASSET_DIRT));
ASSET_TEX(ASSET_CHEST), assets_register(ASSET_ANI(ASSET_WATER));
assets_register(ASSET_TEX(ASSET_LAVA));
// NOTE(zaklaus): blocks assets_register(ASSET_TEX(ASSET_WALL));
ASSET_TEX(ASSET_FENCE), assets_register(ASSET_TEX(ASSET_HILL));
ASSET_TEX(ASSET_DEV), assets_register(ASSET_TEX(ASSET_HILL_SNOW));
ASSET_TEX(ASSET_GROUND), assets_register(ASSET_TEX(ASSET_HOLE));
ASSET_TEX(ASSET_DIRT), assets_register(ASSET_TEX(ASSET_WOOD));
ASSET_ANI(ASSET_WATER), assets_register(ASSET_TEX(ASSET_TREE));
ASSET_TEX(ASSET_LAVA),
ASSET_TEX(ASSET_WALL), assets_register(ASSET_TEX(ASSET_BELT));
ASSET_TEX(ASSET_HILL), assets_register(ASSET_TEX(ASSET_BELT_LEFT));
ASSET_TEX(ASSET_HILL_SNOW), assets_register(ASSET_TEX(ASSET_BELT_RIGHT));
ASSET_TEX(ASSET_HOLE), assets_register(ASSET_TEX(ASSET_BELT_UP));
ASSET_TEX(ASSET_WOOD), assets_register(ASSET_TEX(ASSET_BELT_DOWN));
ASSET_TEX(ASSET_TREE),
ASSET_TEX(ASSET_BELT),
ASSET_TEX(ASSET_BELT_LEFT),
ASSET_TEX(ASSET_BELT_RIGHT),
ASSET_TEX(ASSET_BELT_UP),
ASSET_TEX(ASSET_BELT_DOWN),
}; };

View File

@ -127,13 +127,13 @@ void renderer_init_3d(void) {
DrawText(loading_text, GetScreenWidth()-text_w-15, GetScreenHeight()-135, 120, RAYWHITE); DrawText(loading_text, GetScreenWidth()-text_w-15, GetScreenHeight()-135, 120, RAYWHITE);
EndDrawing(); EndDrawing();
blocks_setup(); assets_resources_setup();
assets_setup(); blocks_resources_setup();
} }
void renderer_shutdown_3d(void) { void renderer_shutdown_3d(void) {
blocks_destroy(); blocks_resources_destroy();
assets_destroy(); assets_resources_destroy();
} }

View File

@ -179,13 +179,13 @@ void renderer_init_v0(void) {
DrawText(loading_text, GetScreenWidth()-text_w-15, GetScreenHeight()-135, 120, RAYWHITE); DrawText(loading_text, GetScreenWidth()-text_w-15, GetScreenHeight()-135, 120, RAYWHITE);
EndDrawing(); EndDrawing();
blocks_setup(); assets_resources_setup();
assets_setup(); blocks_resources_setup();
} }
void renderer_shutdown_v0(void) { void renderer_shutdown_v0(void) {
blocks_destroy(); blocks_resources_destroy();
assets_destroy(); assets_resources_destroy();
} }
void renderer_debug_draw_v0(void) { void renderer_debug_draw_v0(void) {

View File

@ -7,7 +7,6 @@
#include "world/world_view.h" #include "world/world_view.h"
#include "perlin.h" #include "perlin.h"
#define BLOCKS_COUNT (sizeof(blocks)/sizeof(block))
#define WORLD_TEXTURE_BLOCK_SCALE 0.5f #define WORLD_TEXTURE_BLOCK_SCALE 0.5f
ZPL_TABLE(static, blocks__chunk_tbl, blocks__chunk_tbl_, RenderTexture2D); ZPL_TABLE(static, blocks__chunk_tbl, blocks__chunk_tbl_, RenderTexture2D);
@ -19,38 +18,35 @@ static void chunks_unload_textures(uint64_t key, RenderTexture2D *value) {
UnloadRenderTexture(*value); UnloadRenderTexture(*value);
} }
typedef struct {
asset_id kind;
uint32_t flags;
char symbol;
float drag;
float friction;
float bounce;
float velx;
float vely;
// NOTE(zaklaus): viewer data
block_id slot;
} block;
#include "blocks_list.c" #include "blocks_list.c"
int32_t blocks_setup(void) { void blocks_register(block desc) {
for (block_id i=0; i<BLOCKS_COUNT; i++) { if (!blocks) {
zpl_array_init(blocks, zpl_heap());
}
zpl_array_append(blocks, desc);
}
void blocks_cleanup(void) {
zpl_array_free(blocks); blocks = NULL;
}
int32_t blocks_resources_setup(void) {
for (block_id i=0; i<zpl_array_count(blocks); i++) {
blocks[i].slot = assets_find(blocks[i].kind); blocks[i].slot = assets_find(blocks[i].kind);
} }
blocks__chunk_tbl_init(&baked_chunks, zpl_heap()); blocks__chunk_tbl_init(&baked_chunks, zpl_heap());
return 0; return 0;
} }
void blocks_destroy(void) { void blocks_resources_destroy(void) {
blocks__chunk_tbl_map_mut(&baked_chunks, chunks_unload_textures); blocks__chunk_tbl_map_mut(&baked_chunks, chunks_unload_textures);
blocks__chunk_tbl_destroy(&baked_chunks); blocks__chunk_tbl_destroy(&baked_chunks);
} }
block_id blocks_find(asset_id kind) { block_id blocks_find(asset_id kind) {
for (block_id i=0; i<BLOCKS_COUNT; i++) { for (block_id i=0; i<zpl_array_count(blocks); i++) {
if (blocks[i].kind == kind) if (blocks[i].kind == kind)
return i; return i;
} }

View File

@ -2,6 +2,11 @@
#include "platform/system.h" #include "platform/system.h"
#include "gen/assets.h" #include "gen/assets.h"
#define BLOCK(a, f, s, ...)\
(block){\
.kind = a, .flags = f, .symbol = s, __VA_ARGS__\
}
typedef enum { typedef enum {
BLOCK_FLAG_COLLISION = (1 << 1), BLOCK_FLAG_COLLISION = (1 << 1),
BLOCK_FLAG_HAZARD = (1 << 2), BLOCK_FLAG_HAZARD = (1 << 2),
@ -11,8 +16,28 @@ typedef enum {
typedef uint16_t block_id; typedef uint16_t block_id;
int32_t blocks_setup(void); typedef struct {
void blocks_destroy(void); asset_id kind;
uint32_t flags;
char symbol;
float drag;
float friction;
float bounce;
float velx;
float vely;
// NOTE(zaklaus): viewer data
block_id slot;
} block;
void blocks_setup(void);
void blocks_register(block desc);
void blocks_cleanup(void);
// resources
int32_t blocks_resources_setup(void);
void blocks_resources_destroy(void);
block_id blocks_find(asset_id kind); block_id blocks_find(asset_id kind);

View File

@ -1,27 +1,22 @@
#include "world/blocks.h" #include "world/blocks.h"
#define BLOCK(a, f, s, ...)\ static block *blocks = 0;
{\
.kind = a, .flags = f, .symbol = s, __VA_ARGS__\
}
static block blocks[] = { void blocks_setup() {
BLOCK(ASSET_EMPTY, 0, 'E'), blocks_register(BLOCK(ASSET_EMPTY, 0, 'E'));
BLOCK(ASSET_GROUND, 0, '.', .drag = 1.0f, .friction = 1.0f), blocks_register(BLOCK(ASSET_GROUND, 0, '.', .drag = 1.0f, .friction = 1.0f));
BLOCK(ASSET_DIRT, 0, ',', .drag = 2.1f , .friction = 1.0f), blocks_register(BLOCK(ASSET_DIRT, 0, ',', .drag = 2.1f , .friction = 1.0f));
BLOCK(ASSET_WALL, BLOCK_FLAG_COLLISION, '#', .drag = 1.0f , .friction = 1.0f, .bounce = 1.0f), blocks_register(BLOCK(ASSET_WALL, BLOCK_FLAG_COLLISION, '#', .drag = 1.0f , .friction = 1.0f, .bounce = 1.0f));
BLOCK(ASSET_HILL, BLOCK_FLAG_COLLISION, '^', .drag = 1.0f , .friction = 1.0f), blocks_register(BLOCK(ASSET_HILL, BLOCK_FLAG_COLLISION, '^', .drag = 1.0f , .friction = 1.0f));
BLOCK(ASSET_HILL_SNOW, BLOCK_FLAG_COLLISION, '*', .drag = 1.0f , .friction = 1.0f), blocks_register(BLOCK(ASSET_HILL_SNOW, BLOCK_FLAG_COLLISION, '*', .drag = 1.0f , .friction = 1.0f));
BLOCK(ASSET_WATER, 0, '~', .drag = 0.11f , .friction = 1.0f), blocks_register(BLOCK(ASSET_WATER, 0, '~', .drag = 0.11f , .friction = 1.0f));
BLOCK(ASSET_LAVA, BLOCK_FLAG_HAZARD, '!', .drag = 6.2f , .friction = 4.0f), blocks_register(BLOCK(ASSET_LAVA, BLOCK_FLAG_HAZARD, '!', .drag = 6.2f , .friction = 4.0f));
BLOCK(ASSET_FENCE, BLOCK_FLAG_COLLISION, '#', .drag = 1.0f , .friction = 1.0f, .bounce = 1.0f), blocks_register(BLOCK(ASSET_FENCE, BLOCK_FLAG_COLLISION, '#', .drag = 1.0f , .friction = 1.0f, .bounce = 1.0f));
BLOCK(ASSET_WOOD, BLOCK_FLAG_COLLISION, '#', .drag = 1.0f , .friction = 1.0f, .bounce = 0.0f), blocks_register(BLOCK(ASSET_WOOD, BLOCK_FLAG_COLLISION, '#', .drag = 1.0f , .friction = 1.0f, .bounce = 0.0f));
BLOCK(ASSET_TREE, BLOCK_FLAG_COLLISION|BLOCK_FLAG_DESTROY_ON_COLLISION, '@', .drag = 1.0f , .friction = 1.0f, .bounce = 0.0f), blocks_register(BLOCK(ASSET_TREE, BLOCK_FLAG_COLLISION|BLOCK_FLAG_DESTROY_ON_COLLISION, '@', .drag = 1.0f , .friction = 1.0f, .bounce = 0.0f));
BLOCK(ASSET_BELT_LEFT, 0, '@', .drag = 1.0f , .friction = 1.0f, .velx = -150.0f), blocks_register(BLOCK(ASSET_BELT_LEFT, 0, '@', .drag = 1.0f , .friction = 1.0f, .velx = -150.0f));
BLOCK(ASSET_BELT_RIGHT, 0, '@', .drag = 1.0f , .friction = 1.0f, .velx = 150.0f), blocks_register(BLOCK(ASSET_BELT_RIGHT, 0, '@', .drag = 1.0f , .friction = 1.0f, .velx = 150.0f));
BLOCK(ASSET_BELT_UP, 0, '@', .drag = 1.0f , .friction = 1.0f, .vely = -150.0f), blocks_register(BLOCK(ASSET_BELT_UP, 0, '@', .drag = 1.0f , .friction = 1.0f, .vely = -150.0f));
BLOCK(ASSET_BELT_DOWN, 0, '@', .drag = 1.0f , .friction = 1.0f, .vely = 150.0f), blocks_register(BLOCK(ASSET_BELT_DOWN, 0, '@', .drag = 1.0f , .friction = 1.0f, .vely = 150.0f));
}; };
ZPL_STATIC_ASSERT(sizeof(blocks)/sizeof(block) < ZPL_U16_MAX, "too many registered blocks! (max. 65536)");

View File

@ -16,7 +16,7 @@ typedef enum {
EKIND_MONSTER, EKIND_MONSTER,
EKIND_MACRO_BOT, EKIND_MACRO_BOT,
EKIND_CHUNK, EKIND_CHUNK,
FORCE_EKIND_UINT16 = UINT16_MAX EKIND_NEXT_FREE
} entity_kind; } entity_kind;
typedef enum { typedef enum {

View File

@ -1,5 +1,6 @@
add_executable(eco2d add_executable(eco2d
src/main.c src/main.c
src/platform.c
) )
target_compile_definitions(eco2d PRIVATE CLIENT) target_compile_definitions(eco2d PRIVATE CLIENT)

View File

@ -270,7 +270,7 @@ void platform_render() {
game_world_view_active_entity_map(do_entity_fadeinout); game_world_view_active_entity_map(do_entity_fadeinout);
} }
assets_frame(); assets_resources_frame();
BeginDrawing(); BeginDrawing();
{ {