From b240f0ad9f600aee9011f0734fc0d9db20303fb2 Mon Sep 17 00:00:00 2001 From: jblanked <82678820+jblanked@users.noreply.github.com> Date: Thu, 12 Dec 2024 14:37:52 -0500 Subject: [PATCH] Add game engine example to Run view --- alloc/alloc.c | 2 + application.fam | 9 +++- callback/callback.c | 97 ++++++++++++++++++++++++++++++++++++++++- callback/callback.h | 9 ++++ engine/main.c | 104 ++++++++++++++++++++++---------------------- flip_world.h | 7 ++- 6 files changed, 173 insertions(+), 55 deletions(-) diff --git a/alloc/alloc.c b/alloc/alloc.c index eb60dda5ab0..6ae381486af 100644 --- a/alloc/alloc.c +++ b/alloc/alloc.c @@ -25,6 +25,8 @@ FlipWorldApp *flip_world_app_alloc() return NULL; } + view_dispatcher_set_custom_event_callback(app->view_dispatcher, flip_world_custom_event_callback); + // Submenu if (!easy_flipper_set_submenu(&app->submenu, FlipWorldViewSubmenu, VERSION_TAG, callback_exit_app, &app->view_dispatcher)) { diff --git a/application.fam b/application.fam index 45bdcb12220..564a2ff785f 100644 --- a/application.fam +++ b/application.fam @@ -6,6 +6,13 @@ App( stack_size=4 * 1024, fap_icon="app.png", fap_category="GPIO", - fap_icon_assets="assets", fap_description="Open World Multiplayer game, best played with the VGM." + fap_icon_assets="assets", + fap_file_assets="assets", # Do not touch this and the next line, it is needed to generate sprites + fap_extbuild=( + ExtFile( + path="${FAP_SRC_DIR}/assets", + command="${PYTHON3} ${FAP_SRC_DIR}/engine/scripts/sprite_builder.py ${FAP_SRC_DIR.abspath}/sprites ${TARGET.abspath}/sprites", + ), + ), ) diff --git a/callback/callback.c b/callback/callback.c index b20315cd7a7..721a0ba09df 100644 --- a/callback/callback.c +++ b/callback/callback.c @@ -1,5 +1,68 @@ #include +static void frame_cb(GameEngine *engine, Canvas *canvas, InputState input, void *context) +{ + UNUSED(engine); + GameManager *game_manager = context; + game_manager_input_set(game_manager, input); + game_manager_update(game_manager); + game_manager_render(game_manager, canvas); +} + +int32_t game_app(void *p) +{ + UNUSED(p); + GameManager *game_manager = game_manager_alloc(); + if (!game_manager) + { + FURI_LOG_E("Game", "Failed to allocate game manager"); + return -1; + } + GameEngineSettings settings = game_engine_settings_init(); + settings.target_fps = game.target_fps; + settings.show_fps = game.show_fps; + settings.always_backlight = game.always_backlight; + settings.frame_callback = frame_cb; + settings.context = game_manager; + + GameEngine *engine = game_engine_alloc(settings); + if (!engine) + { + FURI_LOG_E("Game", "Failed to allocate game engine"); + game_manager_free(game_manager); + return -1; + } + game_manager_engine_set(game_manager, engine); + + void *game_context = NULL; + if (game.context_size > 0) + { + game_context = malloc(game.context_size); + game_manager_game_context_set(game_manager, game_context); + } + game.start(game_manager, game_context); + + game_engine_run(engine); + game_engine_free(engine); + + game_manager_free(game_manager); + + game.stop(game_context); + if (game_context) + { + free(game_context); + } + + int32_t entities = entities_get_count(); + if (entities != 0) + { + FURI_LOG_E("Game", "Memory leak detected: %ld entities still allocated", entities); + return -1; + } + + return 0; +} + static bool alloc_about_view(void *context); static bool alloc_main_view(void *context); static bool alloc_text_input_view(void *context, char *title); @@ -271,6 +334,37 @@ void free_all_views(void *context, bool should_free_variable_item_list) free_text_input_view(app); } +static void flip_world_loader_process_callback(void *context) +{ + FlipWorldApp *app = (FlipWorldApp *)context; + if (!app) + { + FURI_LOG_E(TAG, "FlipWorldApp is NULL"); + return; + } + + // load game + game_app(NULL); +} + +bool flip_world_custom_event_callback(void *context, uint32_t index) +{ + if (!context) + { + FURI_LOG_E(TAG, "context is NULL"); + return false; + } + switch (index) + { + case FlipWorldCustomEventPlay: + // free_all_views(app, true); + flip_world_loader_process_callback(context); + return true; + default: + return false; + } +} + void callback_submenu_choices(void *context, uint32_t index) { FlipWorldApp *app = (FlipWorldApp *)context; @@ -288,7 +382,8 @@ void callback_submenu_choices(void *context, uint32_t index) FURI_LOG_E(TAG, "Failed to allocate main view"); return; } - view_dispatcher_switch_to_view(app->view_dispatcher, FlipWorldViewMain); + // view_dispatcher_switch_to_view(app->view_dispatcher, FlipWorldViewMain); + view_dispatcher_send_custom_event(app->view_dispatcher, FlipWorldCustomEventPlay); break; case FlipWorldSubmenuIndexAbout: free_all_views(app, true); diff --git a/callback/callback.h b/callback/callback.h index 790b0009477..023f2a08243 100644 --- a/callback/callback.h +++ b/callback/callback.h @@ -2,5 +2,14 @@ #include #include +// +#include +#include "engine/engine.h" +#include "engine/game_engine.h" +#include "engine/game_manager_i.h" +#include "engine/level_i.h" +#include "engine/entity_i.h" + void free_all_views(void *context, bool free_variable_item_list); +bool flip_world_custom_event_callback(void *context, uint32_t index); void callback_submenu_choices(void *context, uint32_t index); \ No newline at end of file diff --git a/engine/main.c b/engine/main.c index 8fdf5b4a27f..b423e812c2d 100644 --- a/engine/main.c +++ b/engine/main.c @@ -5,55 +5,55 @@ #include "level_i.h" #include "entity_i.h" -static void frame_cb(GameEngine *engine, Canvas *canvas, InputState input, void *context) -{ - UNUSED(engine); - GameManager *game_manager = context; - game_manager_input_set(game_manager, input); - game_manager_update(game_manager); - game_manager_render(game_manager, canvas); -} - -int32_t game_app(void *p) -{ - UNUSED(p); - GameManager *game_manager = game_manager_alloc(); - - GameEngineSettings settings = game_engine_settings_init(); - settings.target_fps = game.target_fps; - settings.show_fps = game.show_fps; - settings.always_backlight = game.always_backlight; - settings.frame_callback = frame_cb; - settings.context = game_manager; - - GameEngine *engine = game_engine_alloc(settings); - game_manager_engine_set(game_manager, engine); - - void *game_context = NULL; - if (game.context_size > 0) - { - game_context = malloc(game.context_size); - game_manager_game_context_set(game_manager, game_context); - } - game.start(game_manager, game_context); - - game_engine_run(engine); - game_engine_free(engine); - - game_manager_free(game_manager); - - game.stop(game_context); - if (game_context) - { - free(game_context); - } - - int32_t entities = entities_get_count(); - if (entities != 0) - { - FURI_LOG_E("Game", "Memory leak detected: %ld entities still allocated", entities); - return -1; - } - - return 0; -} \ No newline at end of file +// static void frame_cb(GameEngine *engine, Canvas *canvas, InputState input, void *context) +// { +// UNUSED(engine); +// GameManager *game_manager = context; +// game_manager_input_set(game_manager, input); +// game_manager_update(game_manager); +// game_manager_render(game_manager, canvas); +// } + +// int32_t game_app(void *p) +// { +// UNUSED(p); +// GameManager *game_manager = game_manager_alloc(); + +// GameEngineSettings settings = game_engine_settings_init(); +// settings.target_fps = game.target_fps; +// settings.show_fps = game.show_fps; +// settings.always_backlight = game.always_backlight; +// settings.frame_callback = frame_cb; +// settings.context = game_manager; + +// GameEngine *engine = game_engine_alloc(settings); +// game_manager_engine_set(game_manager, engine); + +// void *game_context = NULL; +// if (game.context_size > 0) +// { +// game_context = malloc(game.context_size); +// game_manager_game_context_set(game_manager, game_context); +// } +// game.start(game_manager, game_context); + +// game_engine_run(engine); +// game_engine_free(engine); + +// game_manager_free(game_manager); + +// game.stop(game_context); +// if (game_context) +// { +// free(game_context); +// } + +// int32_t entities = entities_get_count(); +// if (entities != 0) +// { +// FURI_LOG_E("Game", "Memory leak detected: %ld entities still allocated", entities); +// return -1; +// } + +// return 0; +// } \ No newline at end of file diff --git a/flip_world.h b/flip_world.h index 8837e0c948d..3995f4fa624 100644 --- a/flip_world.h +++ b/flip_world.h @@ -30,9 +30,14 @@ typedef enum FlipWorldViewAbout, // The about screen FlipWorldViewSettings, // The settings screen FlipWorldViewTextInput, // The text input screen - FlipWorldlViewDialog, // The dialog screen } FlipWorldView; +// Define a custom event for our FlipWorld application +typedef enum +{ + FlipWorldCustomEventPlay, // Play the game +} FlipWorldCustomEvent; + // Each screen will have its own view typedef struct {