From 01afd4500797ed4df4a6904126735e3abf94caaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Madar=C3=A1sz?= Date: Thu, 29 Sep 2022 13:59:51 +0200 Subject: [PATCH] merge glue code between games --- code/foundation/src/gui/build_mode.c | 2 +- code/foundation/src/platform/arch.h | 133 ++++++++++++++++ code/foundation/src/world/worldgen_utils.h | 134 ++++++++++++++++ code/games/minimal/src/main.c | 42 +---- code/games/minimal/src/platform.c | 82 +--------- code/games/minimal/src/worldgen.c | 135 +--------------- code/games/sandbox/src/main.c | 42 +---- code/games/sandbox/src/platform.c | 83 +--------- code/games/sandbox/src/worldgen.c | 176 +++------------------ 9 files changed, 309 insertions(+), 520 deletions(-) create mode 100644 code/foundation/src/platform/arch.h create mode 100644 code/foundation/src/world/worldgen_utils.h diff --git a/code/foundation/src/gui/build_mode.c b/code/foundation/src/gui/build_mode.c index 138c4d1..935cbc3 100644 --- a/code/foundation/src/gui/build_mode.c +++ b/code/foundation/src/gui/build_mode.c @@ -28,7 +28,7 @@ void buildmode_draw(void) { cam.x = (double)mx; cam.y = (double)my; - renderer_draw_single(cam.x, cam.y, ASSET_BLOCK_FRAME, WHITE); + renderer_draw_single((float)cam.x, (float)cam.y, ASSET_BLOCK_FRAME, WHITE); // NOTE(zaklaus): Check distance double dx = old_cam.x - cam.x; diff --git a/code/foundation/src/platform/arch.h b/code/foundation/src/platform/arch.h new file mode 100644 index 0000000..5166b32 --- /dev/null +++ b/code/foundation/src/platform/arch.h @@ -0,0 +1,133 @@ +#pragma once +#include "platform/system.h" + +#if defined(PLATFORM_WEB) +#include +#ifdef ARCH_IMPL +EM_JS(int, canvas_get_width, (), { + return canvas.width; +}); + +EM_JS(int, canvas_get_height, (), { + return canvas.height; +}); + +void UpdateDrawFrame(void) { + reset_cached_time(); + profile (PROF_MAIN_LOOP) { + game_input(); + game_update(); + game_render(); + } + + profiler_collate(); +} +#else +void UpdateDrawFrame(void); +#endif +#endif + +#ifdef ARCH_IMPL +static uint16_t screenWidth = 1024; +static uint16_t screenHeight = 768; +static float target_zoom = 0.6f; +static bool request_shutdown; + +static float temp_time = 0.0f; + +float get_cached_time(void) { + return temp_time; +} +void reset_cached_time(void) { + temp_time = (float)zpl_time_rel(); +} + +void game_run(void) { + #if !defined(PLATFORM_WEB) + while (game_is_running()) { + reset_cached_time(); + profile (PROF_MAIN_LOOP) { + game_input(); + game_update(); + game_render(); + } + + profiler_collate(); + } + #else + emscripten_set_main_loop(UpdateDrawFrame, 0, 1); + #endif +} +void platform_create_window(const char *title) { + SetTraceLogLevel(LOG_ERROR); + + #if defined(PLATFORM_WEB) + screenWidth = (uint16_t)canvas_get_width(); + screenHeight = (uint16_t)canvas_get_height(); + #endif + + InitWindow(screenWidth, screenHeight, title); + SetWindowState(/*FLAG_WINDOW_UNDECORATED|*/FLAG_WINDOW_MAXIMIZED|FLAG_WINDOW_RESIZABLE|FLAG_MSAA_4X_HINT|FLAG_VSYNC_HINT); + + #if !defined(PLATFORM_WEB) + screenWidth = (uint16_t)GetScreenWidth(); + screenHeight = (uint16_t)GetScreenHeight(); + #endif + // ToggleFullscreen(); + // SetTargetFPS(60.0); +} + +void platform_resize_window() { +#if !defined(PLATFORM_WEB) + screenWidth = (uint16_t)GetScreenWidth(); + screenHeight = (uint16_t)GetScreenHeight(); +#else + uint16_t newScreenWidth = (uint16_t)canvas_get_width(); + uint16_t newScreenHeight = (uint16_t)canvas_get_height(); + if (newScreenWidth != screenWidth || newScreenHeight != screenHeight) { + screenWidth = newScreenWidth; + screenHeight = newScreenHeight; + SetWindowSize(screenWidth, screenHeight); + } +#endif +} + +void platform_get_block_realpos(float *x, float *y){ + camera cam = camera_get(); + Vector2 mpos = GetMousePosition(); + entity_view *e = game_world_view_active_get_entity(cam.ent_id); + if (!e) return; + float zoom = renderer_zoom_get(); + mpos.x -= screenWidth/2.0f; + mpos.y -= screenHeight/2.0f; + cam.x += mpos.x*(1.0f/zoom); + cam.y += mpos.y*(1.0f/zoom); + cam.x = ((int32_t)cam.x / (int32_t)(WORLD_BLOCK_SIZE)) * WORLD_BLOCK_SIZE; + cam.y = ((int32_t)cam.y / (int32_t)(WORLD_BLOCK_SIZE)) * WORLD_BLOCK_SIZE; + cam.x += WORLD_BLOCK_SIZE/2.0f; + cam.y += WORLD_BLOCK_SIZE/2.0f; + if (x) *x = (float)cam.x; + if (y) *y = (float)cam.y; +} + + +float platform_frametime() { + return GetFrameTime(); +} + +float platform_zoom_get(void) { + return target_zoom; +} + +void platform_request_close(void) { + request_shutdown = true; +} + + +uint8_t platform_is_running() { + return !WindowShouldClose(); +} + +#else +void game_run(void); +#endif diff --git a/code/foundation/src/world/worldgen_utils.h b/code/foundation/src/world/worldgen_utils.h new file mode 100644 index 0000000..4ba0d38 --- /dev/null +++ b/code/foundation/src/world/worldgen_utils.h @@ -0,0 +1,134 @@ +#pragma once +#include "platform/system.h" +#include "world/blocks.h" +#include "world/world.h" +#include "world/perlin.h" + +static world_data *world; + +#define WORLD_BLOCK_OBSERVER(name) block_id name(block_id *data, block_id id, uint32_t block_idx) +typedef WORLD_BLOCK_OBSERVER(world_block_observer_proc); + +#ifndef WORLD_CUSTOM_PERLIN +#define WORLD_PERLIN_FREQ 100 +#define WORLD_PERLIN_OCTAVES 1 +#endif + +#define BLOCK_INVALID 0xF + +// ensure it is set in worldgen_build + +int worldgen_in_circle(int x, int y, int radius) { + return (zpl_pow(x, 2) + zpl_pow(y, 2)) < zpl_pow(radius, 2); +} + +static void world_fill_rect(block_id *data, block_id id, uint32_t x, uint32_t y, uint32_t w, uint32_t h, world_block_observer_proc *proc) { + for (uint32_t cy=y; cy= world->dim) continue; + if (cy < 0 || cy >= world->dim) continue; + uint32_t i = (cy*world->dim) + cx; + + if (proc) { + block_id new_id = (*proc)(data, id, i); + if (new_id != BLOCK_INVALID) { + id = new_id; + } + else continue; + } + + data[i] = id; + } + } +} + +static void world_fill_circle(block_id *data, block_id id, uint32_t cx, uint32_t cy, uint32_t radius, world_block_observer_proc *proc) { + for (int x = -(int32_t)(radius); x < (int32_t)radius; ++x) { + for (int y = -(int32_t)(radius); y < (int32_t)radius; ++y) { + if (worldgen_in_circle(x, y, radius)) { + int fx = x + cx; + int fy = y + cy; + + uint32_t i = (fy*world->dim) + fx; + + if (proc) { + block_id new_id = (*proc)(data, id, i); + if (new_id != BLOCK_INVALID) { + id = new_id; + } + else continue; + } + + data[i] = id; + } + } + } +} + +static void world_fill_rect_anchor(block_id *data, block_id id, uint32_t x, uint32_t y, uint32_t w, uint32_t h, float ax, float ay, world_block_observer_proc *proc) { + uint32_t w2 = (uint32_t)floorf(w*ax); + uint32_t h2 = (uint32_t)floorf(h*ay); + world_fill_rect(data, id, x-w2, y-h2, w, h, proc); +} + + +static block_id world_perlin_cond_offset(uint32_t block_idx, double chance, uint32_t ofx, uint32_t ofy) { + uint32_t x = block_idx % world->dim + ofx; + uint32_t y = block_idx / world->dim + ofy; + + return perlin_fbm(world->seed, x, y, WORLD_PERLIN_FREQ, WORLD_PERLIN_OCTAVES) < chance; +} + +#ifndef WORLD_CUSTOM_SHAPER +static WORLD_BLOCK_OBSERVER(shaper) { + uint32_t kind = id; + + return id; +} +#endif + +static block_id world_perlin_cond(uint32_t block_idx, double chance) { + return world_perlin_cond_offset(block_idx, chance, 0, 0); +} + +#if 1 +static WORLD_BLOCK_OBSERVER(shaper_noise80) { + return world_perlin_cond(block_idx, 0.80) ? shaper(data, id, block_idx) : BLOCK_INVALID; +} + +static WORLD_BLOCK_OBSERVER(shaper_noise50) { + return world_perlin_cond(block_idx, 0.50) ? shaper(data, id, block_idx) : BLOCK_INVALID; +} + +static WORLD_BLOCK_OBSERVER(shaper_noise33) { + return world_perlin_cond(block_idx, 0.33) ? shaper(data, id, block_idx) : BLOCK_INVALID; +} + +static WORLD_BLOCK_OBSERVER(shaper_noise05) { + return world_perlin_cond(block_idx, 0.05) ? shaper(data, id, block_idx) : BLOCK_INVALID; +} + +static WORLD_BLOCK_OBSERVER(shaper_noise05b) { + return world_perlin_cond_offset(block_idx, 0.05, 32, 0) ? shaper(data, id, block_idx) : BLOCK_INVALID; +} + +static WORLD_BLOCK_OBSERVER(shaper_noise01b) { + return world_perlin_cond_offset(block_idx, 0.01, 32, 0) ? shaper(data, id, block_idx) : BLOCK_INVALID; +} +#else +static WORLD_BLOCK_OBSERVER(shaper_noise80) { + return rand()%10 < 8 ? shaper(id, block_idx) : BLOCK_INVALID; +} + +static WORLD_BLOCK_OBSERVER(shaper_noise50) { + return rand()%10 < 5 ? shaper(id, block_idx) : BLOCK_INVALID; +} + +static WORLD_BLOCK_OBSERVER(shaper_noise33) { + return rand()%10 < 3 ? shaper(id, block_idx) : BLOCK_INVALID; +} +#endif + + +#define RAND_RANGE(x,y) (x + (int)rand()%(y-(x))) +#define RAND_RANGEF(x,y) ((float)RAND_RANGE(x,y)) diff --git a/code/games/minimal/src/main.c b/code/games/minimal/src/main.c index 9d9456a..73a9dc6 100644 --- a/code/games/minimal/src/main.c +++ b/code/games/minimal/src/main.c @@ -14,10 +14,7 @@ #include "ecs/components.h" #include "ecs/systems.h" -#if defined(PLATFORM_WEB) - #include - void UpdateDrawFrame(void); -#endif +#include "platform/arch.h" #define DEFAULT_WORLD_SEED 302097 #define DEFAULT_CHUNK_SIZE 16 /* amount of blocks within a chunk (single axis) */ @@ -74,20 +71,7 @@ int main(int argc, char** argv) { sighandler_register(); game_init(host, port, play_mode, 1, seed, chunk_size, world_size, 0); -#if !defined(PLATFORM_WEB) - while (game_is_running()) { - reset_cached_time(); - profile (PROF_MAIN_LOOP) { - game_input(); - game_update(); - game_render(); - } - - profiler_collate(); - } -#else - emscripten_set_main_loop(UpdateDrawFrame, 0, 1); -#endif + game_run(); game_shutdown(); sighandler_unregister(); @@ -96,25 +80,3 @@ int main(int argc, char** argv) { zpl_opts_free(&opts); return 0; } - -#if defined(PLATFORM_WEB) -void UpdateDrawFrame(void) { - reset_cached_time(); - profile (PROF_MAIN_LOOP) { - game_input(); - game_update(); - game_render(); - } - - profiler_collate(); -} -#endif - -static float temp_time = 0.0f; - -float get_cached_time(void) { - return temp_time; -} -void reset_cached_time(void) { - temp_time = zpl_time_rel(); -} diff --git a/code/games/minimal/src/platform.c b/code/games/minimal/src/platform.c index 514bb76..97c9185 100644 --- a/code/games/minimal/src/platform.c +++ b/code/games/minimal/src/platform.c @@ -12,42 +12,17 @@ #include "platform/profiler.h" #include "debug/debug_ui.h" #include "utils/raylib_helpers.h" +#include "platform/renderer.h" -#if defined(PLATFORM_WEB) -#include -EM_JS(int, canvas_get_width, (), { - return canvas.width; -}); - -EM_JS(int, canvas_get_height, (), { - return canvas.height; -}); -#endif - -static uint16_t screenWidth = 1024; -static uint16_t screenHeight = 768; -static float target_zoom = 0.6f; -static bool request_shutdown; +#define ARCH_IMPL +#include "platform/arch.h" #include "renderer.c" bool inv_is_open = false; void platform_init() { - SetTraceLogLevel(LOG_ERROR); - -#if defined(PLATFORM_WEB) - screenWidth = (uint16_t)canvas_get_width(); - screenHeight = (uint16_t)canvas_get_height(); -#endif - - InitWindow(screenWidth, screenHeight, "eco2d"); - SetWindowState(/*FLAG_WINDOW_UNDECORATED|*/FLAG_WINDOW_MAXIMIZED|FLAG_WINDOW_RESIZABLE|FLAG_MSAA_4X_HINT); - -#if !defined(PLATFORM_WEB) - screenWidth = (uint16_t)GetScreenWidth(); - screenHeight = (uint16_t)GetScreenHeight(); -#endif + platform_create_window("minimal-demo"); renderer_init(); } @@ -56,10 +31,6 @@ void platform_shutdown() { CloseWindow(); } -uint8_t platform_is_running() { - return !WindowShouldClose(); -} - static game_keystate_data last_input_data = {0}; inline static @@ -89,7 +60,7 @@ void platform_input() { // NOTE(zaklaus): keystate handling { float x=0.0f, y=0.0f; - uint8_t use, sprint, drop, ctrl, pick; + uint8_t use, sprint, ctrl; if (IsKeyDown(KEY_RIGHT) || IsKeyDown(KEY_D)) x += 1.0f; if (IsKeyDown(KEY_LEFT) || IsKeyDown(KEY_A)) x -= 1.0f; if (IsKeyDown(KEY_UP) || IsKeyDown(KEY_W)) y += 1.0f; @@ -127,18 +98,7 @@ void platform_input() { } void platform_render() { -#if !defined(PLATFORM_WEB) - screenWidth = (uint16_t)GetScreenWidth(); - screenHeight = (uint16_t)GetScreenHeight(); -#else - uint16_t newScreenWidth = (uint16_t)canvas_get_width(); - uint16_t newScreenHeight = (uint16_t)canvas_get_height(); - if (newScreenWidth != screenWidth || newScreenHeight != screenHeight) { - screenWidth = newScreenWidth; - screenHeight = newScreenHeight; - SetWindowSize(screenWidth, screenHeight); - } -#endif + platform_resize_window(); profile(PROF_ENTITY_LERP) { game_world_view_active_entity_map(lerp_entity_positions); @@ -159,33 +119,3 @@ void platform_render() { CloseWindow(); } } - -float platform_frametime() { - return GetFrameTime(); -} - -float platform_zoom_get(void) { - return target_zoom; -} - -void platform_request_close(void) { - request_shutdown = true; -} - -void platform_get_block_realpos(float *x, float *y){ - camera cam = camera_get(); - Vector2 mpos = GetMousePosition(); - entity_view *e = game_world_view_active_get_entity(cam.ent_id); - if (!e) return; - float zoom = renderer_zoom_get(); - mpos.x -= screenWidth/2.0f; - mpos.y -= screenHeight/2.0f; - cam.x += mpos.x*(1.0f/zoom); - cam.y += mpos.y*(1.0f/zoom); - cam.x = ((int32_t)cam.x / (int32_t)(WORLD_BLOCK_SIZE)) * WORLD_BLOCK_SIZE; - cam.y = ((int32_t)cam.y / (int32_t)(WORLD_BLOCK_SIZE)) * WORLD_BLOCK_SIZE; - cam.x += WORLD_BLOCK_SIZE/2.0f; - cam.y += WORLD_BLOCK_SIZE/2.0f; - if (x) *x = (float)cam.x; - if (y) *y = (float)cam.y; -} diff --git a/code/games/minimal/src/worldgen.c b/code/games/minimal/src/worldgen.c index 9165a43..802b914 100644 --- a/code/games/minimal/src/worldgen.c +++ b/code/games/minimal/src/worldgen.c @@ -13,17 +13,7 @@ #include "ents/items.h" #include "world/blocks_info.h" -#define WORLD_BLOCK_OBSERVER(name) block_id name(block_id *data, block_id id, uint32_t block_idx) -typedef WORLD_BLOCK_OBSERVER(world_block_observer_proc); - -#define WORLD_PERLIN_FREQ 100 -#define WORLD_PERLIN_OCTAVES 1 - -#define BLOCK_INVALID 0xF - -int eco_incircle(int x, int y, int radius) { - return (zpl_pow(x, 2) + zpl_pow(y, 2)) < zpl_pow(radius, 2); -} +#include "world/worldgen_utils.h" block_id worldgen_biome_find(uint32_t biome, uint32_t kind) { asset_id asset = ASSET_INVALID; @@ -44,129 +34,6 @@ block_id worldgen_biome_find(uint32_t biome, uint32_t kind) { return blocks_find(asset); } -static world_data *world; - -static void world_fill_rect(block_id *data, block_id id, uint32_t x, uint32_t y, uint32_t w, uint32_t h, world_block_observer_proc *proc) { - for (uint32_t cy=y; cy= world->dim) continue; - if (cy < 0 || cy >= world->dim) continue; - uint32_t i = (cy*world->dim) + cx; - - if (proc) { - block_id new_id = (*proc)(data, id, i); - if (new_id != BLOCK_INVALID) { - id = new_id; - } - else continue; - } - - data[i] = id; - } - } -} - -static void world_fill_circle(block_id *data, block_id id, uint32_t cx, uint32_t cy, uint32_t radius, world_block_observer_proc *proc) { - for (int x = -(int32_t)(radius); x < (int32_t)radius; ++x) { - for (int y = -(int32_t)(radius); y < (int32_t)radius; ++y) { - if (eco_incircle(x, y, radius)) { - int fx = x + cx; - int fy = y + cy; - - uint32_t i = (fy*world->dim) + fx; - - if (proc) { - block_id new_id = (*proc)(data, id, i); - if (new_id != BLOCK_INVALID) { - id = new_id; - } - else continue; - } - - data[i] = id; - } - } - } -} - -static void world_fill_rect_anchor(block_id *data, block_id id, uint32_t x, uint32_t y, uint32_t w, uint32_t h, float ax, float ay, world_block_observer_proc *proc) { - uint32_t w2 = (uint32_t)floorf(w*ax); - uint32_t h2 = (uint32_t)floorf(h*ay); - world_fill_rect(data, id, x-w2, y-h2, w, h, proc); -} - -static WORLD_BLOCK_OBSERVER(shaper) { - uint32_t kind = id; - uint32_t old_kind = data[block_idx]; - - if (kind == BLOCK_KIND_WALL && kind == old_kind) { - return worldgen_biome_find(BLOCK_BIOME_DEV, BLOCK_KIND_HILL); - } - if (kind == BLOCK_KIND_HILL && kind == old_kind) { - return worldgen_biome_find(BLOCK_BIOME_DEV, BLOCK_KIND_HILL_SNOW); - } - - return id; -} - -static block_id world_perlin_cond_offset(uint32_t block_idx, double chance, uint32_t ofx, uint32_t ofy) { - uint32_t x = block_idx % world->dim + ofx; - uint32_t y = block_idx / world->dim + ofy; - - return perlin_fbm(world->seed, x, y, WORLD_PERLIN_FREQ, WORLD_PERLIN_OCTAVES) < chance; -} - -static block_id world_perlin_cond(uint32_t block_idx, double chance) { - return world_perlin_cond_offset(block_idx, chance, 0, 0); -} - -#if 1 -static WORLD_BLOCK_OBSERVER(shaper_noise80) { - return world_perlin_cond(block_idx, 0.80) ? shaper(data, id, block_idx) : BLOCK_INVALID; -} - -static WORLD_BLOCK_OBSERVER(shaper_noise50) { - return world_perlin_cond(block_idx, 0.50) ? shaper(data, id, block_idx) : BLOCK_INVALID; -} - -static WORLD_BLOCK_OBSERVER(shaper_noise33) { - return world_perlin_cond(block_idx, 0.33) ? shaper(data, id, block_idx) : BLOCK_INVALID; -} - -static WORLD_BLOCK_OBSERVER(shaper_noise05) { - return world_perlin_cond(block_idx, 0.05) ? shaper(data, id, block_idx) : BLOCK_INVALID; -} - -static WORLD_BLOCK_OBSERVER(shaper_noise05b) { - return world_perlin_cond_offset(block_idx, 0.05, 32, 0) ? shaper(data, id, block_idx) : BLOCK_INVALID; -} - -static WORLD_BLOCK_OBSERVER(shaper_noise01b) { - return world_perlin_cond_offset(block_idx, 0.01, 32, 0) ? shaper(data, id, block_idx) : BLOCK_INVALID; -} -#else -static WORLD_BLOCK_OBSERVER(shaper_noise80) { - return rand()%10 < 8 ? shaper(id, block_idx) : BLOCK_INVALID; -} - -static WORLD_BLOCK_OBSERVER(shaper_noise50) { - return rand()%10 < 5 ? shaper(id, block_idx) : BLOCK_INVALID; -} - -static WORLD_BLOCK_OBSERVER(shaper_noise33) { - return rand()%10 < 3 ? shaper(id, block_idx) : BLOCK_INVALID; -} -#endif - -#if 0 -static void world_fill_mountain(uint32_t x, uint32_t y) { - -} -#endif - -#define RAND_RANGE(x,y) (x + (int)rand()%(y-(x))) -#define RAND_RANGEF(x,y) ((float)RAND_RANGE(x,y)) - int32_t worldgen_build(world_data *wld) { // TODO(zaklaus): pass world as an arg instead world = wld; diff --git a/code/games/sandbox/src/main.c b/code/games/sandbox/src/main.c index 1c50c15..941ebd9 100644 --- a/code/games/sandbox/src/main.c +++ b/code/games/sandbox/src/main.c @@ -14,10 +14,7 @@ #include "ecs/components.h" #include "ecs/systems.h" -#if defined(PLATFORM_WEB) - #include - void UpdateDrawFrame(void); -#endif +#include "platform/arch.h" #define DEFAULT_WORLD_SEED 302097 #define DEFAULT_CHUNK_SIZE 16 /* amount of blocks within a chunk (single axis) */ @@ -78,20 +75,7 @@ int main(int argc, char** argv) { sighandler_register(); game_init(host, port, play_mode, num_viewers, seed, chunk_size, world_size, is_dash_enabled); -#if !defined(PLATFORM_WEB) - while (game_is_running()) { - reset_cached_time(); - profile (PROF_MAIN_LOOP) { - game_input(); - game_update(); - game_render(); - } - - profiler_collate(); - } -#else - emscripten_set_main_loop(UpdateDrawFrame, 0, 1); -#endif + game_run(); game_shutdown(); sighandler_unregister(); @@ -100,25 +84,3 @@ int main(int argc, char** argv) { zpl_opts_free(&opts); return 0; } - -#if defined(PLATFORM_WEB) -void UpdateDrawFrame(void) { - reset_cached_time(); - profile (PROF_MAIN_LOOP) { - game_input(); - game_update(); - game_render(); - } - - profiler_collate(); -} -#endif - -static float temp_time = 0.0f; - -float get_cached_time(void) { - return temp_time; -} -void reset_cached_time(void) { - temp_time = zpl_time_rel(); -} diff --git a/code/games/sandbox/src/platform.c b/code/games/sandbox/src/platform.c index f5795f2..aa7e30f 100644 --- a/code/games/sandbox/src/platform.c +++ b/code/games/sandbox/src/platform.c @@ -13,22 +13,10 @@ #include "debug/debug_ui.h" #include "debug/debug_draw.h" #include "utils/raylib_helpers.h" +#include "platform/renderer.h" -#if defined(PLATFORM_WEB) -#include -EM_JS(int, canvas_get_width, (), { - return canvas.width; -}); - -EM_JS(int, canvas_get_height, (), { - return canvas.height; -}); -#endif - -static uint16_t screenWidth = 1024; -static uint16_t screenHeight = 768; -static float target_zoom = 0.6f; -static bool request_shutdown; +#define ARCH_IMPL +#include "platform/arch.h" #include "renderer.c" @@ -37,23 +25,7 @@ static bool request_shutdown; #include "gui/inventory.c" void platform_init() { - SetTraceLogLevel(LOG_ERROR); - -#if defined(PLATFORM_WEB) - screenWidth = (uint16_t)canvas_get_width(); - screenHeight = (uint16_t)canvas_get_height(); -#endif - - InitWindow(screenWidth, screenHeight, "eco2d"); - SetWindowState(/*FLAG_WINDOW_UNDECORATED|*/FLAG_WINDOW_MAXIMIZED|FLAG_WINDOW_RESIZABLE|FLAG_MSAA_4X_HINT); - -#if !defined(PLATFORM_WEB) - screenWidth = (uint16_t)GetScreenWidth(); - screenHeight = (uint16_t)GetScreenHeight(); -#endif - // ToggleFullscreen(); - // SetTargetFPS(60.0); - + platform_create_window("eco2d"); renderer_init(); } @@ -75,28 +47,6 @@ void platform_shutdown() { CloseWindow(); } -uint8_t platform_is_running() { - return !WindowShouldClose(); -} - -void platform_get_block_realpos(float *x, float *y){ - camera cam = camera_get(); - Vector2 mpos = GetMousePosition(); - entity_view *e = game_world_view_active_get_entity(cam.ent_id); - if (!e) return; - float zoom = renderer_zoom_get(); - mpos.x -= screenWidth/2.0f; - mpos.y -= screenHeight/2.0f; - cam.x += mpos.x*(1.0f/zoom); - cam.y += mpos.y*(1.0f/zoom); - cam.x = ((int32_t)cam.x / (int32_t)(WORLD_BLOCK_SIZE)) * WORLD_BLOCK_SIZE; - cam.y = ((int32_t)cam.y / (int32_t)(WORLD_BLOCK_SIZE)) * WORLD_BLOCK_SIZE; - cam.x += WORLD_BLOCK_SIZE/2.0f; - cam.y += WORLD_BLOCK_SIZE/2.0f; - if (x) *x = (float)cam.x; - if (y) *y = (float)cam.y; -} - static game_keystate_data last_input_data = {0}; static pkt_send_blockpos last_blockpos_data = {0}; @@ -246,18 +196,7 @@ void draw_selected_item() { } void platform_render() { -#if !defined(PLATFORM_WEB) - screenWidth = (uint16_t)GetScreenWidth(); - screenHeight = (uint16_t)GetScreenHeight(); -#else - uint16_t newScreenWidth = (uint16_t)canvas_get_width(); - uint16_t newScreenHeight = (uint16_t)canvas_get_height(); - if (newScreenWidth != screenWidth || newScreenHeight != screenHeight) { - screenWidth = newScreenWidth; - screenHeight = newScreenHeight; - SetWindowSize(screenWidth, screenHeight); - } -#endif + platform_resize_window(); profile(PROF_ENTITY_LERP) { game_world_view_active_entity_map(lerp_entity_positions); @@ -287,15 +226,3 @@ void platform_render() { CloseWindow(); } } - -float platform_frametime() { - return GetFrameTime(); -} - -float platform_zoom_get(void) { - return target_zoom; -} - -void platform_request_close(void) { - request_shutdown = true; -} diff --git a/code/games/sandbox/src/worldgen.c b/code/games/sandbox/src/worldgen.c index f26cbd8..4b94bbd 100644 --- a/code/games/sandbox/src/worldgen.c +++ b/code/games/sandbox/src/worldgen.c @@ -13,13 +13,7 @@ #include "ents/items.h" #include "world/blocks_info.h" -#define WORLD_BLOCK_OBSERVER(name) block_id name(block_id *data, block_id id, uint32_t block_idx) -typedef WORLD_BLOCK_OBSERVER(world_block_observer_proc); - -#define WORLD_PERLIN_FREQ 100 -#define WORLD_PERLIN_OCTAVES 1 - -#define BLOCK_INVALID 0xF +#include "world/worldgen_utils.h" block_id worldgen_biome_find(uint32_t biome, uint32_t kind) { asset_id asset = ASSET_INVALID; @@ -36,134 +30,14 @@ block_id worldgen_biome_find(uint32_t biome, uint32_t kind) { } } } - + return blocks_find(asset); } -static world_data *world; - -static void world_fill_rect(block_id *data, block_id id, uint32_t x, uint32_t y, uint32_t w, uint32_t h, world_block_observer_proc *proc) { - for (uint32_t cy=y; cy= world->dim) continue; - if (cy < 0 || cy >= world->dim) continue; - uint32_t i = (cy*world->dim) + cx; - - if (proc) { - block_id new_id = (*proc)(data, id, i); - if (new_id != BLOCK_INVALID) { - id = new_id; - } - else continue; - } - - data[i] = id; - } - } -} - -static void world_fill_circle(block_id *data, block_id id, uint32_t x, uint32_t y, uint32_t w, uint32_t h, world_block_observer_proc *proc) { - for (uint32_t cy=y; cy= world->dim) continue; - if (cy < 0 || cy >= world->dim) continue; - uint32_t i = (cy*world->dim) + cx; - - if (proc) { - block_id new_id = (*proc)(data, id, i); - if (new_id != BLOCK_INVALID) { - id = new_id; - } - else continue; - } - - data[i] = id; - } - } -} - -static void world_fill_rect_anchor(block_id *data, block_id id, uint32_t x, uint32_t y, uint32_t w, uint32_t h, float ax, float ay, world_block_observer_proc *proc) { - uint32_t w2 = (uint32_t)floorf(w*ax); - uint32_t h2 = (uint32_t)floorf(h*ay); - world_fill_rect(data, id, x-w2, y-h2, w, h, proc); -} - -static WORLD_BLOCK_OBSERVER(shaper) { - uint32_t kind = id; - uint32_t old_kind = data[block_idx]; - - if (kind == BLOCK_KIND_WALL && kind == old_kind) { - return worldgen_biome_find(BLOCK_BIOME_DEV, BLOCK_KIND_HILL); - } - if (kind == BLOCK_KIND_HILL && kind == old_kind) { - return worldgen_biome_find(BLOCK_BIOME_DEV, BLOCK_KIND_HILL_SNOW); - } - - return id; -} - -static block_id world_perlin_cond_offset(uint32_t block_idx, double chance, uint32_t ofx, uint32_t ofy) { - uint32_t x = block_idx % world->dim + ofx; - uint32_t y = block_idx / world->dim + ofy; - - return perlin_fbm(world->seed, x, y, WORLD_PERLIN_FREQ, WORLD_PERLIN_OCTAVES) < chance; -} - -static block_id world_perlin_cond(uint32_t block_idx, double chance) { - return world_perlin_cond_offset(block_idx, chance, 0, 0); -} - -#if 1 -static WORLD_BLOCK_OBSERVER(shaper_noise80) { - return world_perlin_cond(block_idx, 0.80) ? shaper(data, id, block_idx) : BLOCK_INVALID; -} - -static WORLD_BLOCK_OBSERVER(shaper_noise50) { - return world_perlin_cond(block_idx, 0.50) ? shaper(data, id, block_idx) : BLOCK_INVALID; -} - -static WORLD_BLOCK_OBSERVER(shaper_noise33) { - return world_perlin_cond(block_idx, 0.33) ? shaper(data, id, block_idx) : BLOCK_INVALID; -} - -static WORLD_BLOCK_OBSERVER(shaper_noise05) { - return world_perlin_cond(block_idx, 0.05) ? shaper(data, id, block_idx) : BLOCK_INVALID; -} - -static WORLD_BLOCK_OBSERVER(shaper_noise05b) { - return world_perlin_cond_offset(block_idx, 0.05, 32, 0) ? shaper(data, id, block_idx) : BLOCK_INVALID; -} - -static WORLD_BLOCK_OBSERVER(shaper_noise01b) { - return world_perlin_cond_offset(block_idx, 0.01, 32, 0) ? shaper(data, id, block_idx) : BLOCK_INVALID; -} -#else -static WORLD_BLOCK_OBSERVER(shaper_noise80) { - return rand()%10 < 8 ? shaper(id, block_idx) : BLOCK_INVALID; -} - -static WORLD_BLOCK_OBSERVER(shaper_noise50) { - return rand()%10 < 5 ? shaper(id, block_idx) : BLOCK_INVALID; -} - -static WORLD_BLOCK_OBSERVER(shaper_noise33) { - return rand()%10 < 3 ? shaper(id, block_idx) : BLOCK_INVALID; -} -#endif - -#if 0 -static void world_fill_mountain(uint32_t x, uint32_t y) { - -} -#endif - -#define RAND_RANGE(x,y) (x + (int)rand()%(y-(x))) -#define RAND_RANGEF(x,y) ((float)RAND_RANGE(x,y)) - int32_t worldgen_build(world_data *wld) { // TODO(zaklaus): pass world as an arg instead world = wld; - + // TODO: perform world gen // atm, we will fill the world with ground and surround it by walls block_id wall_id = worldgen_biome_find(BLOCK_BIOME_DEV, BLOCK_KIND_WALL); @@ -172,37 +46,37 @@ int32_t worldgen_build(world_data *wld) { block_id watr_id = worldgen_biome_find(BLOCK_BIOME_DEV, BLOCK_KIND_WATER); block_id lava_id = worldgen_biome_find(BLOCK_BIOME_DEV, BLOCK_KIND_LAVA); block_id tree_id = blocks_find(ASSET_TREE); - + srand(world->seed); - + // walls world_fill_rect(world->data, wall_id, 0, 0, world->dim, world->dim, NULL); - + // ground world_fill_rect(world->data, grnd_id, 1, 1, world->dim-2, world->dim-2, NULL); world_fill_rect(world->data, dirt_id, 1, 1, world->dim-2, world->dim-2, shaper_noise05); world_fill_rect(world->outer_data, tree_id, 1, 1, world->dim-2, world->dim-2, shaper_noise01b); - + // water #if 1 for (int i=0; idata, watr_id, RAND_RANGE(0, world->dim), RAND_RANGE(0, world->dim), 4+RAND_RANGE(0,3), 4+RAND_RANGE(0,3), 0.5f, 0.5f, shaper_noise80); } #endif - + // ice rink #if 0 world_fill_rect_anchor(world->data, watr_id, 450, 125, 10, 10, 0.0f, 0.0f, NULL); #endif - + // lava #if 1 for (int i=0; idata, lava_id, RAND_RANGE(0, world->dim), RAND_RANGE(0, world->dim), 4+RAND_RANGE(0,3), 4+RAND_RANGE(0,3), 0.5f, 0.5f, shaper_noise80); } #endif - - + + // hills #if 1 const uint32_t HILLS_SIZE = 21; @@ -210,67 +84,67 @@ int32_t worldgen_build(world_data *wld) { world_fill_rect_anchor(world->data, wall_id, RAND_RANGE(0, world->dim), RAND_RANGE(0, world->dim), RAND_RANGE(0,HILLS_SIZE), RAND_RANGE(0,HILLS_SIZE), 0.5f, 0.5f, shaper_noise50); } #endif - + // vehicles #if 1 for (int i=0; ix = RAND_RANGEF(0, world->dim*WORLD_BLOCK_SIZE); dest->y = RAND_RANGEF(0, world->dim*WORLD_BLOCK_SIZE); entity_set_position(e, dest->x, dest->y); } #endif - + // items #if 1 for (int i=0; ix = RAND_RANGEF(0, world->dim*WORLD_BLOCK_SIZE); dest->y = RAND_RANGEF(0, world->dim*WORLD_BLOCK_SIZE); entity_set_position(e, dest->x, dest->y); } - + for (int i=0; ix = RAND_RANGEF(0, world->dim*WORLD_BLOCK_SIZE); dest->y = RAND_RANGEF(0, world->dim*WORLD_BLOCK_SIZE); entity_set_position(e, dest->x, dest->y); } - + for (int i=0; ix = RAND_RANGEF(0, world->dim*WORLD_BLOCK_SIZE); dest->y = RAND_RANGEF(0, world->dim*WORLD_BLOCK_SIZE); entity_set_position(e, dest->x, dest->y); } - + for (int i=0; ix = RAND_RANGEF(0, world->dim*WORLD_BLOCK_SIZE); dest->y = RAND_RANGEF(0, world->dim*WORLD_BLOCK_SIZE); entity_set_position(e, dest->x, dest->y); } - + for (int i=0; ix = RAND_RANGEF(0, world->dim*WORLD_BLOCK_SIZE); dest->y = RAND_RANGEF(0, world->dim*WORLD_BLOCK_SIZE); entity_set_position(e, dest->x, dest->y); } - + #endif - + return WORLD_ERROR_NONE; }