From d02439b0332f1ed7361893bf9dc6f796d7abf5cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Madar=C3=A1sz?= Date: Tue, 27 Sep 2022 14:19:57 +0000 Subject: [PATCH] wip minimal demo --- code/games/CMakeLists.txt | 1 + code/games/minimal/CMakeLists.txt | 11 ++ code/games/minimal/src/main.c | 120 +++++++++++++++++++++ code/games/minimal/src/platform.c | 173 ++++++++++++++++++++++++++++++ web/build.sh | 6 +- web/deploy.sh | 6 +- 6 files changed, 313 insertions(+), 4 deletions(-) create mode 100644 code/games/minimal/CMakeLists.txt create mode 100644 code/games/minimal/src/main.c create mode 100644 code/games/minimal/src/platform.c diff --git a/code/games/CMakeLists.txt b/code/games/CMakeLists.txt index 72d3810..9cb9dcb 100644 --- a/code/games/CMakeLists.txt +++ b/code/games/CMakeLists.txt @@ -1 +1,2 @@ add_subdirectory(sandbox) +add_subdirectory(minimal) diff --git a/code/games/minimal/CMakeLists.txt b/code/games/minimal/CMakeLists.txt new file mode 100644 index 0000000..3ce8101 --- /dev/null +++ b/code/games/minimal/CMakeLists.txt @@ -0,0 +1,11 @@ +add_executable(minimal + src/main.c + src/platform.c +) + +target_compile_definitions(minimal PRIVATE CLIENT) +include_directories(src ../../foundation/src ../../../art/gen) +target_link_libraries(minimal eco2d-foundation) +target_compile_options(minimal PRIVATE -Werror -Wall -Wextra -Wno-unused-function -Wno-unknown-pragmas -Wno-unused-variable -Wno-unused-parameter) + +link_system_libs(minimal) diff --git a/code/games/minimal/src/main.c b/code/games/minimal/src/main.c new file mode 100644 index 0000000..02628dc --- /dev/null +++ b/code/games/minimal/src/main.c @@ -0,0 +1,120 @@ +#define ZPL_IMPL +#include "zpl.h" +#include "platform/system.h" +#include "core/game.h" +#include "ents/entity.h" +#include "world/entity_view.h" +#include "utils/options.h" +#include "platform/signal_handling.h" +#include "platform/profiler.h" + +#include "flecs/flecs.h" +#include "flecs/flecs_os_api_stdcpp.h" + +#include "ecs/components.h" +#include "ecs/systems.h" + +#if defined(PLATFORM_WEB) + #include + void UpdateDrawFrame(void); +#endif + +#define DEFAULT_WORLD_SEED 302097 +#define DEFAULT_CHUNK_SIZE 16 /* amount of blocks within a chunk (single axis) */ +#define DEFAULT_WORLD_SIZE 32 /* amount of chunks within a world (single axis) */ + +int main(int argc, char** argv) { + zpl_opts opts={0}; + zpl_opts_init(&opts, zpl_heap(), argv[0]); + + zpl_opts_add(&opts, "?", "help", "the HELP section", ZPL_OPTS_FLAG); + zpl_opts_add(&opts, "v", "viewer-only", "run viewer-only client", ZPL_OPTS_FLAG); + zpl_opts_add(&opts, "d", "server-only", "run dedicated server", ZPL_OPTS_FLAG); + zpl_opts_add(&opts, "p", "preview-map", "draw world preview", ZPL_OPTS_FLAG); + zpl_opts_add(&opts, "s", "seed", "world seed", ZPL_OPTS_INT); + zpl_opts_add(&opts, "r", "random-seed", "generate random world seed", ZPL_OPTS_FLAG); + //zpl_opts_add(&opts, "cs", "chunk-size", "amount of blocks within a chunk (single axis)", ZPL_OPTS_INT); + zpl_opts_add(&opts, "ws", "world-size", "amount of chunks within a world (single axis)", ZPL_OPTS_INT); + zpl_opts_add(&opts, "ip", "host", "host IP address", ZPL_OPTS_STRING); + zpl_opts_add(&opts, "port", "port", "port number", ZPL_OPTS_INT); + + uint32_t ok = zpl_opts_compile(&opts, argc, argv); + + if (!ok) { + zpl_opts_print_errors(&opts); + zpl_opts_print_help(&opts); + return -1; + } + + int8_t is_viewer_only = zpl_opts_has_arg(&opts, "viewer-only"); + int8_t is_server_only = zpl_opts_has_arg(&opts, "server-only"); + int32_t seed = (int32_t)zpl_opts_integer(&opts, "seed", DEFAULT_WORLD_SEED); + uint16_t world_size = (uint16_t)zpl_opts_integer(&opts, "world-size", DEFAULT_WORLD_SIZE); + uint16_t chunk_size = DEFAULT_CHUNK_SIZE; //zpl_opts_integer(&opts, "chunk-size", DEFAULT_CHUNK_SIZE); + zpl_string host = zpl_opts_string(&opts, "host", NULL); + uint16_t port = (uint16_t)zpl_opts_integer(&opts, "port", 0); + + game_kind play_mode = GAMEKIND_SINGLE; + + if (is_viewer_only) play_mode = GAMEKIND_CLIENT; + if (is_server_only) play_mode = GAMEKIND_HEADLESS; + + if (zpl_opts_has_arg(&opts, "random-seed")) { + zpl_random rnd={0}; + zpl_random_init(&rnd); + seed = zpl_random_gen_u32(&rnd); + zpl_printf("Seed: %u\n", seed); + } + + if (zpl_opts_has_arg(&opts, "preview-map")) { + generate_minimap(seed, WORLD_BLOCK_SIZE, chunk_size, world_size); + return 0; + } + + 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_shutdown(); + sighandler_unregister(); + + zpl_string_free(host); + 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 new file mode 100644 index 0000000..34b7c1c --- /dev/null +++ b/code/games/minimal/src/platform.c @@ -0,0 +1,173 @@ +#include "platform/platform.h" +#include "raylib.h" +#include "raymath.h" +#include "net/network.h" +#include "core/game.h" +#include "world/entity_view.h" +#include "world/prediction.h" +#include "core/camera.h" +#include "math.h" +#include "world/blocks.h" +#include "gen/assets.h" +#include "platform/profiler.h" +#include "debug/debug_ui.h" +#include "utils/raylib_helpers.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 + +//temp +bool inv_is_open = false; + +static uint16_t screenWidth = 1024; +static uint16_t screenHeight = 768; +static float target_zoom = 0.6f; +static bool request_shutdown; + +#define GFX_KIND 2 +#include "renderers/renderer_bridge.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, "minimal"); + 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 + renderer_init(); +} + +void platform_shutdown() { + renderer_shutdown(); + CloseWindow(); +} + +uint8_t platform_is_running() { + return !WindowShouldClose(); +} + +static game_keystate_data last_input_data = {0}; + +inline static +void platform_input_update_input_frame(game_keystate_data data) { + // NOTE(zaklaus): Test if there are any changes + if (data.x != last_input_data.x) goto send_data; + if (data.y != last_input_data.y) goto send_data; + if (data.use != last_input_data.use) goto send_data; + if (data.sprint != last_input_data.sprint) goto send_data; + if (data.ctrl != last_input_data.ctrl) goto send_data; + return; + + send_data: + last_input_data = data; + game_action_send_keystate(&data); +} + +void platform_input() { + float mouse_z = (GetMouseWheelMove()*0.5f); + + if (mouse_z != 0.0f) { + target_zoom = zpl_clamp(target_zoom+mouse_z, 0.1f, 11.0f); + } + + // NOTE(zaklaus): keystate handling + { + float x=0.0f, y=0.0f; + uint8_t use, sprint, drop, 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; + if (IsKeyDown(KEY_DOWN) || IsKeyDown(KEY_S)) y -= 1.0f; + + use = IsKeyPressed(KEY_SPACE); + sprint = IsKeyDown(KEY_LEFT_SHIFT) || IsKeyDown(KEY_RIGHT_SHIFT); + ctrl = IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(KEY_RIGHT_CONTROL); + + // NOTE(zaklaus): NEW! mouse movement + Vector2 mouse_pos = GetMousePosition(); + mouse_pos.x /= screenWidth; + mouse_pos.y /= screenHeight; + mouse_pos.x -= 0.5f; + mouse_pos.y -= 0.5f; + mouse_pos = Vector2Normalize(mouse_pos); + + if (game_get_kind() == GAMEKIND_SINGLE && IsMouseButtonDown(MOUSE_MIDDLE_BUTTON)) { + x = mouse_pos.x; + y = -mouse_pos.y; + } + + game_keystate_data in_data = { + .x = x, + .y = y, + .mx = mouse_pos.x, + .my = mouse_pos.y, + .use = use, + .sprint = sprint, + .ctrl = ctrl, + }; + + platform_input_update_input_frame(in_data); + } +} + +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 + + profile(PROF_ENTITY_LERP) { + game_world_view_active_entity_map(lerp_entity_positions); + game_world_view_active_entity_map(do_entity_fadeinout); + } + + assets_resources_frame(); + + BeginDrawing(); + { + profile (PROF_RENDER) { + renderer_draw(); + } + } + EndDrawing(); + + if (request_shutdown) { + 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/web/build.sh b/web/build.sh index 04c3aee..c89a58a 100755 --- a/web/build.sh +++ b/web/build.sh @@ -7,8 +7,10 @@ if [ -f "index.html" ]; then rm -rf index.html fi +APP=${1:-eco2d} + cmake --build . --parallel -if [ -f "eco2d.html" ]; then - mv eco2d.html index.html +if [ -f "$APP.html" ]; then + mv $APP.html index.html fi popd diff --git a/web/deploy.sh b/web/deploy.sh index 17f135f..4c0ca39 100755 --- a/web/deploy.sh +++ b/web/deploy.sh @@ -28,12 +28,14 @@ if [ ! -f "build_web/index.html" ]; then exit 1 fi +APP=${1:-eco2d} + mkdir -p deploy_web -cp build_web/eco2d.* deploy_web/ +cp build_web/$APP.* deploy_web/ cp build_web/index.html deploy_web/ # Deploy to itch.io -./butler/butler push deploy_web/ zaklaus/eco2d:html-latest +./butler/butler push deploy_web/ zaklaus/$APP:html-latest # Teardown rm -rf deploy_web