diff options
author | its your bedtime <23366927+itsyourbedtime@users.noreply.github.com> | 2021-08-05 23:49:04 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-05 23:49:04 +0300 |
commit | 9c38efd4ef229c7497c892c700c894264733a596 (patch) | |
tree | b8817c0cf13bc6003c1376690f04378615070555 /applications/dolphin | |
parent | 5741ed2bd5ef9b8c9cdb07459df034625c624d33 (diff) |
[FL-1427] Dolphin: new assets and engine rework (#546)
Diffstat (limited to 'applications/dolphin')
-rw-r--r-- | applications/dolphin/scenes/assets/emotes.h | 21 | ||||
-rw-r--r-- | applications/dolphin/scenes/assets/items.c | 240 | ||||
-rw-r--r-- | applications/dolphin/scenes/assets/items.h | 8 | ||||
-rw-r--r-- | applications/dolphin/scenes/assets/items_i.h | 10 | ||||
-rw-r--r-- | applications/dolphin/scenes/assets/meta.h | 276 | ||||
-rw-r--r-- | applications/dolphin/scenes/scene.c | 16 | ||||
-rw-r--r-- | applications/dolphin/scenes/scene.h | 73 | ||||
-rw-r--r-- | applications/dolphin/scenes/scene_controls.c | 59 | ||||
-rw-r--r-- | applications/dolphin/scenes/scene_dolphin_state.c | 69 | ||||
-rw-r--r-- | applications/dolphin/scenes/scene_gfx.c | 200 |
10 files changed, 604 insertions, 368 deletions
diff --git a/applications/dolphin/scenes/assets/emotes.h b/applications/dolphin/scenes/assets/emotes.h index 8f2f5611..6c3f0dba 100644 --- a/applications/dolphin/scenes/assets/emotes.h +++ b/applications/dolphin/scenes/assets/emotes.h @@ -1,15 +1,12 @@ #pragma once -static const char* emotes_list[] = { - "(O_o)", "(!_?)", "(^_^)", "(*__*)", "(@_@)", "(X_x)", "(>_<)", "(^ ^)", "(^_^)", - "(-_-)", "(~_~)", "(#^.^#)", "(^ ^)", "(^.^)", "(-.-)", "zZzZ", "(^_-)", "(^_-)", - "(+_+)", "(+o+)", "(' ')", "('-')", "('.')", "('_')", "(* > *)", "(o o)", "(^_^)", - "(^O^)", "(^o^)", "(^o^)", "(._.)", "(_^_)", "('_')", "('_;)", "(T_T)", "(;_;)", - "(ー_ー)", "(-.-)", "(^o^)", "(-_-)", "(=_=)", "(=^ ^=)", "(. .)", "(._.)", "( ^m^)", - "(?_?)", "(*^_^*)", "(^<^)", "(^.^)", "(^·^)", "(^.^)", "(^_^.)", "(^_^)", "(^^)", - "(^J^)", "(*^.^*)", "(#^.^#)", "(~o~)", "(^o^)", "(-o-)", "(^. ^)", "(^o^)", "(*^0^*)", - "(*_*)", "(~ o ~)", "(~_~)", "(p_-)", "d[-_-]b", "(^0_0^)", "- ^ -"}; - -static const char* dialogues_list[] = { - "Let's hack!\n\nbla bla bla\nbla bla..", +// temp +const char* console_emotes[] = { + "Run it, m8", + "Lets GOOOO", + "Click it, buddy", + "I wanna play", + "Wtf is this?", + "Just do it", + "JUST DO IT!", }; diff --git a/applications/dolphin/scenes/assets/items.c b/applications/dolphin/scenes/assets/items.c index b23e0b1d..d975551b 100644 --- a/applications/dolphin/scenes/assets/items.c +++ b/applications/dolphin/scenes/assets/items.c @@ -1,49 +1,38 @@ #include <gui/elements.h> #include "applications.h" #include "items_i.h" +#include "emotes.h" +#include <gui/icon_i.h> -const Item TV = { - .layer = 7, - .timeout = 10, - .x = 160, - .y = 34, - .icon = &I_TV_20x24, - .action_name = "Use", - .draw = draw_tv, - .callback = smash_tv}; - -const Item Painting = { - .layer = 3, - .timeout = 20, - .x = 160, - .y = 10, - .icon = &I_Home_painting_17x20, - .action_name = "Inspect", - .draw = NULL, - .callback = inspect_painting}; - -const Item Sofa = { +const Item Food = { .layer = 4, .timeout = 100, - .x = 250, - .y = 34, - .icon = &I_Sofa_40x13, - .action_name = "Sit", - .draw = NULL, - .callback = sofa_sit}; - -const Item PC = { + .pos = + { + .x = 0, + .y = 90, + }, + .width = 60, + .height = 50, + .draw = food_redraw, + .callback = food_callback}; + +const Item Console = { .layer = 4, .timeout = 100, - .x = 400, - .y = 10, - .icon = &I_PC_22x29, - .action_name = "Use", - .draw = NULL, - .callback = pc_callback}; + .pos = + { + .x = 357, + .y = 190, + }, + .width = 40, + .height = 20, + .draw = console_redraw, + .callback = console_callback}; -const Item* Home[ITEMS_NUM] = {&TV, &Sofa, &Painting, &PC}; -const Item** Scenes[1] = {*&Home}; +const Item* Home[] = {&Food, &Console}; + +const Item** Scenes[] = {Home}; const Item** get_scene(SceneState* state) { return Scenes[state->scene_id]; @@ -64,6 +53,37 @@ static void dolphin_scene_start_app(SceneState* state, const FlipperApplication* furi_thread_start(state->scene_app_thread); } +uint16_t roll_new(uint16_t prev, uint16_t max) { + uint16_t val = 999; + while(val != prev) { + val = random() % max; + break; + } + return val; +} + +static void dolphin_scene_type_text( + Canvas* canvas, + SceneState* state, + uint8_t x, + uint8_t y, + const char* text) { + char dialog_str[64]; + char buf[64]; + + strcpy(dialog_str, (char*)text); + + if(state->dialog_progress <= strlen(dialog_str)) { + if(HAL_GetTick() / 10 % 2 == 0) state->dialog_progress++; + dialog_str[state->dialog_progress] = '\0'; + snprintf(buf, state->dialog_progress, dialog_str); + } else { + snprintf(buf, 64, dialog_str); + } + + canvas_draw_str_aligned(canvas, x, y, AlignCenter, AlignCenter, buf); +} + const void scene_activate_item_callback(SceneState* state, Canvas* canvas) { furi_assert(state); furi_assert(canvas); @@ -78,16 +98,32 @@ const void scene_activate_item_callback(SceneState* state, Canvas* canvas) { } } +const Vec2 item_get_pos(SceneState* state, ItemsEnum item) { + const Item** current = get_scene(state); + Vec2 rel_pos = {0, 0}; + + rel_pos.x = DOLPHIN_WIDTH / 2 + (current[item]->pos.x * PARALLAX(current[item]->layer)); + rel_pos.y = DOLPHIN_WIDTH / 4 + (current[item]->pos.y * PARALLAX(current[item]->layer)); + + return rel_pos; +} + const Item* is_nearby(SceneState* state) { furi_assert(state); uint8_t item = 0; bool found = false; const Item** current = get_scene(state); - while(item < ITEMS_NUM) { - int32_t rel = + while(item < ItemsEnumTotal) { + int32_t rel_x = (DOLPHIN_CENTER + DOLPHIN_WIDTH / 2 - - (current[item]->x - state->player_global.x) * PARALLAX(current[item]->layer)); - if(abs(rel) <= DOLPHIN_WIDTH / 2) { + (current[item]->pos.x - state->player_global.x) * PARALLAX(current[item]->layer)); + + uint8_t item_height = current[item]->height; + uint8_t item_width = current[item]->width; + + int32_t rel_y = current[item]->pos.y - state->player_global.y; + + if(abs(rel_x) <= item_width && abs(rel_y) <= item_height) { found = !found; break; } @@ -96,50 +132,102 @@ const Item* is_nearby(SceneState* state) { return found ? current[item] : NULL; } -void draw_tv(Canvas* canvas, void* state) { - furi_assert(state); - SceneState* s = state; - canvas_set_color(canvas, ColorWhite); - canvas_draw_box( - canvas, (TV.x + 3 - s->player_global.x) * PARALLAX(TV.layer), TV.y + 4, 16, 20); - canvas_set_color(canvas, ColorBlack); +void food_redraw(Canvas* canvas, void* s) { + furi_assert(s); + SceneState* state = s; + + const Icon* food_frames[] = { + &I_food1_61x98, + &I_food2_61x98, + &I_food3_61x98, + &I_food4_61x98, + &I_food5_61x98, + &I_food6_61x98, + &I_food7_61x98, + &I_food8_61x98, + &I_food9_61x98, + &I_food10_61x98, + &I_food11_61x98, + &I_food12_61x98, + }; + + uint8_t frame = ((HAL_GetTick() / 200) % SIZEOF_ARRAY(food_frames)); + + if(is_nearby(state) && (state->player_global.y > Food.pos.y)) { + dolphin_scene_type_text( + canvas, + state, + (Food.pos.x - state->player_global.x) * PARALLAX(Food.layer) + 90, + state->screen.y + 8, + console_emotes[state->emote_id]); + + } else { + state->dialog_progress = 0; + state->emote_id = roll_new(state->previous_emote, SIZEOF_ARRAY(console_emotes)); + } + + canvas_draw_icon( + canvas, + (Food.pos.x - state->player_global.x) * PARALLAX(Food.layer), + Food.pos.y - state->player_global.y, + food_frames[frame]); + canvas_set_bitmap_mode(canvas, true); } -void smash_tv(Canvas* canvas, void* state) { - furi_assert(state); - SceneState* s = state; - s->player_flipped = true; - canvas_set_bitmap_mode(canvas, true); - canvas_draw_icon( - canvas, ((TV.x - 5) - s->player_global.x) * PARALLAX(TV.layer), TV.y - 2, &I_FX_Bang_32x6); - canvas_set_bitmap_mode(canvas, false); - if(s->action_timeout < TV.timeout - 2) { - elements_multiline_text_framed(canvas, 80, 24, "Bang!"); +void food_callback(Canvas* canvas, void* s) { + furi_assert(s); + SceneState* state = s; + if(state->use_pending) { + dolphin_scene_start_app(state, &FLIPPER_SCENE_APPS[1]); } } -void sofa_sit(Canvas* canvas, void* state) { - furi_assert(state); - SceneState* s = state; - // temp fix pos - s->player_global.x = 154; - s->dolphin_gfx = &A_FX_Sitting_40x27; - s->dolphin_gfx_b = &I_FX_SittingB_40x27; -} +void console_redraw(Canvas* canvas, void* s) { + furi_assert(s); + SceneState* state = s; -void inspect_painting(Canvas* canvas, void* state) { - furi_assert(state); - SceneState* s = state; - if(s->use_pending) { - dolphin_scene_start_app(s, &FLIPPER_SCENE_APPS[0]); + const Icon* console[] = { + &I_Console_74x67_0, + &I_Console_74x67_1, + &I_Console_74x67_2, + &I_Console_74x67_3, + &I_Console_74x67_4, + &I_Console_74x67_5, + &I_Console_74x67_6, + &I_Console_74x67_7, + &I_Console_74x67_8, + + }; + + uint8_t frame = ((HAL_GetTick() / 100) % SIZEOF_ARRAY(console)); + + canvas_draw_icon( + canvas, + (Console.pos.x - state->player_global.x) * PARALLAX(Console.layer), + Console.pos.y - state->player_global.y, + console[frame]); + + canvas_set_bitmap_mode(canvas, true); + + if(is_nearby(state)) { + dolphin_scene_type_text( + canvas, + state, + (Console.pos.x - state->player_global.x) * PARALLAX(Console.layer) - 25, + Console.pos.y - state->player_global.y + 14, + console_emotes[state->emote_id]); + + } else { + state->dialog_progress = 0; + state->emote_id = roll_new(state->previous_emote, SIZEOF_ARRAY(console_emotes)); } } -void pc_callback(Canvas* canvas, void* state) { - furi_assert(state); - SceneState* s = state; - if(s->use_pending) { - dolphin_scene_start_app(s, &FLIPPER_SCENE_APPS[1]); +void console_callback(Canvas* canvas, void* s) { + furi_assert(s); + SceneState* state = s; + if(state->use_pending) { + dolphin_scene_start_app(state, &FLIPPER_SCENE_APPS[1]); } }
\ No newline at end of file diff --git a/applications/dolphin/scenes/assets/items.h b/applications/dolphin/scenes/assets/items.h index 7e929421..9da4d17c 100644 --- a/applications/dolphin/scenes/assets/items.h +++ b/applications/dolphin/scenes/assets/items.h @@ -1,8 +1,14 @@ #pragma once #include "dolphin/scenes/scene.h" -#define ITEMS_NUM 4 +typedef enum { + ItemsFood, + ItemsConsole, + ItemsEnumTotal, +} ItemsEnum; +uint16_t roll_new(uint16_t prev, uint16_t max); +const Vec2 item_get_pos(SceneState* state, ItemsEnum item); const Item* is_nearby(SceneState* state); const Item** get_scene(SceneState* state); const void scene_activate_item_callback(SceneState* state, Canvas* canvas); diff --git a/applications/dolphin/scenes/assets/items_i.h b/applications/dolphin/scenes/assets/items_i.h index e58256a9..872dee35 100644 --- a/applications/dolphin/scenes/assets/items_i.h +++ b/applications/dolphin/scenes/assets/items_i.h @@ -1,8 +1,8 @@ #pragma once #include "items.h" -void smash_tv(Canvas* canvas, void* state); -void draw_tv(Canvas* canvas, void* state); -void sofa_sit(Canvas* canvas, void* state); -void inspect_painting(Canvas* canvas, void* state); -void pc_callback(Canvas* canvas, void* state); +void food_redraw(Canvas* canvas, void* state); +void food_callback(Canvas* canvas, void* state); + +void console_redraw(Canvas* canvas, void* state); +void console_callback(Canvas* canvas, void* state); diff --git a/applications/dolphin/scenes/assets/meta.h b/applications/dolphin/scenes/assets/meta.h new file mode 100644 index 00000000..467e9ea0 --- /dev/null +++ b/applications/dolphin/scenes/assets/meta.h @@ -0,0 +1,276 @@ +#pragma once +#include "dolphin/scenes/scene.h" + +const DolphinFrame up = { + .frames = + { + { + .f = &I_up1_73x61, + .b = &I_black_up1_73x61, + }, + { + .f = &I_up2_73x61, + .b = &I_black_up2_73x61, + }, + }, + .total = 2, +}; + +const DolphinFrame up_down = { + .frames = + { + { + .f = &I_updown1_73x61, + .b = &I_black_updown1_73x61, + }, + { + .f = &I_updown2_73x61, + .b = &I_black_updown2_73x61, + }, + { + .f = &I_updown3_73x61, + .b = &I_black_updown3_73x61, + }, + }, + .total = 3, +}; + +const DolphinFrame up_right = { + .frames = + { + { + .f = &I_upright1_73x61, + .b = &I_black_upright1_73x61, + }, + { + .f = &I_upright2_73x61, + .b = &I_black_upright2_73x61, + }, + }, + .total = 2, +}; + +const DolphinFrame up_left = { + .frames = + { + { + .f = &I_upleft1_73x61, + .b = &I_black_upleft1_73x61, + }, + { + .f = &I_upleft2_73x61, + .b = &I_black_upleft2_73x61, + }, + }, + .total = 2, +}; + +const DolphinFrame right = { + .frames = + { + { + .f = &I_right1_73x61, + .b = &I_black_right1_73x61, + }, + { + .f = &I_right2_73x61, + .b = &I_black_right2_73x61, + }, + { + .f = &I_right3_73x61, + .b = &I_black_right3_73x61, + }, + }, + .total = 3, +}; + +const DolphinFrame right_up = { + .frames = + { + { + .f = &I_rightup1_73x61, + .b = &I_black_rightup1_73x61, + }, + { + .f = &I_rightup2_73x61, + .b = &I_black_rightup2_73x61, + }, + }, + .total = 2, +}; + +const DolphinFrame right_down = { + .frames = + { + { + .f = &I_rightdown1_73x61, + .b = &I_black_rightdown1_73x61, + }, + { + .f = &I_rightdown2_73x61, + .b = &I_black_rightdown2_73x61, + }, + }, + .total = 2, +}; + +const DolphinFrame right_left = { + .frames = + { + { + .f = &I_rightleft1_73x61, + .b = &I_black_rightleft1_73x61, + }, + { + .f = &I_rightleft2_73x61, + .b = &I_black_rightleft2_73x61, + }, + }, + .total = 2, +}; + +const DolphinFrame down = { + .frames = + { + { + .f = &I_down1_73x61, + .b = &I_black_down1_73x61, + }, + { + .f = &I_down2_73x61, + .b = &I_black_down2_73x61, + }, + }, + .total = 2, +}; + +const DolphinFrame down_up = { + .frames = + { + { + .f = &I_downup1_73x61, + .b = &I_black_downup1_73x61, + }, + { + .f = &I_downup2_73x61, + .b = &I_black_downup2_73x61, + }, + { + .f = &I_downup3_73x61, + .b = &I_black_downup3_73x61, + }, + }, + .total = 3, +}; + +const DolphinFrame down_left = { + .frames = + { + { + .f = &I_downleft1_73x61, + .b = &I_black_downleft1_73x61, + }, + { + .f = &I_downleft2_73x61, + .b = &I_black_downleft2_73x61, + }, + { + .f = &I_downleft3_73x61, + .b = &I_black_downleft3_73x61, + }, + }, + .total = 3, +}; + +const DolphinFrame down_right = { + .frames = + { + { + .f = &I_downright1_73x61, + .b = &I_black_downright1_73x61, + }, + { + .f = &I_downright2_73x61, + .b = &I_black_downright2_73x61, + }, + { + .f = &I_downright3_73x61, + .b = &I_black_downright3_73x61, + }, + }, + .total = 3, +}; + +const DolphinFrame left = { + .frames = + { + { + .f = &I_left1_73x61, + .b = &I_black_left1_73x61, + }, + { + .f = &I_left2_73x61, + .b = &I_black_left2_73x61, + }, + { + .f = &I_left3_73x61, + .b = &I_black_left3_73x61, + }, + }, + .total = 3, +}; + +const DolphinFrame left_up = { + .frames = + { + { + .f = &I_leftup1_73x61, + .b = &I_black_leftup1_73x61, + }, + { + .f = &I_leftup2_73x61, + .b = &I_black_leftup2_73x61, + }, + }, + .total = 2, +}; + +const DolphinFrame left_down = { + .frames = + { + { + .f = &I_leftdown1_73x61, + .b = &I_black_leftdown1_73x61, + }, + { + .f = &I_leftdown2_73x61, + .b = &I_black_leftdown2_73x61, + }, + }, + .total = 2, +}; + +const DolphinFrame left_right = { + .frames = + { + { + .f = &I_rightleft1_73x61, + .b = &I_black_rightleft1_73x61, + }, + { + .f = &I_rightleft2_73x61, + .b = &I_black_rightleft2_73x61, + }, + }, + .total = 2, +}; + +const DolphinFrame* frames[4][4] = { + [DirUp] = {[DirUp] = &up, [DirRight] = &up_right, [DirDown] = &up_down, [DirLeft] = &up_left}, + [DirRight] = + {[DirUp] = &right_up, [DirRight] = &right, [DirDown] = &right_down, [DirLeft] = &right_left}, + [DirDown] = + {[DirUp] = &down_up, [DirRight] = &down_right, [DirDown] = &down, [DirLeft] = &down_left}, + [DirLeft] = + {[DirUp] = &left_up, [DirRight] = &left_right, [DirDown] = &left_down, [DirLeft] = &left}, +}; diff --git a/applications/dolphin/scenes/scene.c b/applications/dolphin/scenes/scene.c index 5bacca3d..ed15592a 100644 --- a/applications/dolphin/scenes/scene.c +++ b/applications/dolphin/scenes/scene.c @@ -52,7 +52,7 @@ void scene_alloc() { // SceneAppGui scene_app_gui = furi_alloc(sizeof(SceneAppGui)); - scene_app_gui->mqueue = osMessageQueueNew(2, sizeof(AppEvent), NULL); + scene_app_gui->mqueue = osMessageQueueNew(8, sizeof(AppEvent), NULL); scene_app_gui->gui = furi_record_open("gui"); scene_app_gui->view_port = view_port_alloc(); scene_app_gui->timer = @@ -62,10 +62,18 @@ void scene_alloc() { SceneState* scene_state = furi_alloc(sizeof(SceneState)); scene_state->player.y = DOLPHIN_DEFAULT_Y; scene_state->player.x = DOLPHIN_CENTER; - scene_state->player_global.x = random() % WORLD_WIDTH / 4; + + scene_state->player_global.x = 160; + scene_state->player_global.y = WORLD_HEIGHT; + + scene_state->frame_group = DirRight; + scene_state->frame_type = DirRight; + scene_state->frame_pending = DirRight; + scene_state->last_group = DirRight; + scene_state->screen.x = scene_state->player.x; scene_state->screen.y = scene_state->player.y; - + // scene_state->debug = true; scene_state_mutex = furi_alloc(sizeof(ValueMutex)); furi_check(init_mutex(scene_state_mutex, scene_state, sizeof(SceneState))); @@ -73,7 +81,7 @@ void scene_alloc() { view_port_draw_callback_set(scene_app_gui->view_port, dolphin_scene_redraw, scene_state_mutex); view_port_input_callback_set( scene_app_gui->view_port, scene_engine_input_callback, scene_app_gui->mqueue); - gui_add_view_port(scene_app_gui->gui, scene_app_gui->view_port, GuiLayerMain); + gui_add_view_port(scene_app_gui->gui, scene_app_gui->view_port, GuiLayerFullscreen); view_port_enabled_set(scene_app_gui->view_port, true); printf("scene_alloc: complete\r\n"); } diff --git a/applications/dolphin/scenes/scene.h b/applications/dolphin/scenes/scene.h index a803eeed..78783769 100644 --- a/applications/dolphin/scenes/scene.h +++ b/applications/dolphin/scenes/scene.h @@ -16,26 +16,28 @@ // player #define DOLPHIN_WIDTH 32 #define DOLPHIN_HEIGHT 32 -#define DOLPHIN_CENTER (SCREEN_WIDTH / 2 - DOLPHIN_WIDTH / 2) -#define SPEED_X 2 -#define ACTIONS_NUM 5 -#define DOLPHIN_DEFAULT_Y 20 +#define DOLPHIN_CENTER (SCREEN_WIDTH / 2 - DOLPHIN_WIDTH) +#define SPEED_X 4 +#define SPEED_Y 4 +#define ACTIONS_NUM 4 +#define DOLPHIN_DEFAULT_Y 2 +#define MAX_FRAMES 3 + // world -#define WORLD_WIDTH 2048 -#define WORLD_HEIGHT 64 +#define WORLD_WIDTH 256 +#define WORLD_HEIGHT 192 #define LAYERS 8 -#define SCENE_ZOOM 9 #define DOLPHIN_LAYER 6 #define PARALLAX_MOD 7 #define PARALLAX(layer) layer / PARALLAX_MOD - layer #define DIALOG_PROGRESS 250 -enum Actions { SLEEP = 0, IDLE, WALK, EMOTE, INTERACT, MINDCONTROL }; +enum Actions { IDLE = 0, EMOTE, INTERACT, MINDCONTROL }; static const uint16_t default_timeout[] = - {[SLEEP] = 300, [IDLE] = 100, [WALK] = 100, [EMOTE] = 50, [INTERACT] = 10, [MINDCONTROL] = 50}; + {[IDLE] = 100, [EMOTE] = 50, [INTERACT] = 10, [MINDCONTROL] = 50}; typedef enum { EventTypeTick, @@ -64,47 +66,60 @@ typedef struct { typedef struct { uint8_t layer; uint16_t timeout; - int32_t x; - int32_t y; - const Icon* icon; - char action_name[16]; + Vec2 pos; + + uint8_t width; + uint8_t height; + void (*draw)(Canvas* canvas, void* model); void (*callback)(Canvas* canvas, void* model); } Item; +typedef enum { + DirUp = 0, + DirRight, + DirDown, + DirLeft, +} FrameDirectionEnum; + +typedef struct { + const Icon* f; + const Icon* b; +} DolphinGfxAsset; + +typedef struct { + const DolphinGfxAsset frames[MAX_FRAMES]; + const uint8_t total; +} DolphinFrame; + typedef struct { - /// Vec2 player; Vec2 player_global; Vec2 player_v; Vec2 screen; - const Icon* dolphin_gfx; - const Icon* dolphin_gfx_b; // temp + FrameDirectionEnum frame_group; + FrameDirectionEnum last_group; + FrameDirectionEnum frame_pending; + FrameDirectionEnum frame_type; - bool player_flipped; + const DolphinFrame* current_frame; + + bool transition; + bool transition_pending; bool use_pending; - // dolphin_scene_debug bool debug; uint8_t player_anim; - uint8_t scene_id; + uint8_t frame_idx; + uint8_t scene_id; uint8_t emote_id; uint8_t previous_emote; - uint8_t dialogue_id; - uint8_t previous_dialogue; - - uint32_t action_timeout; - uint8_t poi; - uint8_t action; - uint8_t next_action; uint8_t prev_action; - - int8_t zoom_v; - uint8_t scene_zoom; + uint8_t action_timeout; uint8_t dialog_progress; FuriThread* scene_app_thread; diff --git a/applications/dolphin/scenes/scene_controls.c b/applications/dolphin/scenes/scene_controls.c index ba3857b3..0d54f91b 100644 --- a/applications/dolphin/scenes/scene_controls.c +++ b/applications/dolphin/scenes/scene_controls.c @@ -6,43 +6,31 @@ void dolphin_scene_handle_user_input(SceneState* state, InputEvent* input) { furi_assert(state); furi_assert(input); - // dolphin_scene_debug - if(input->type == InputTypeShort) { - if(input->key == InputKeyUp) { - state->debug = !state->debug; - } - } - // toggle mind control on any user interaction + state->last_group = state->frame_group; if(input->type == InputTypePress) { - if(input->key == InputKeyLeft || input->key == InputKeyRight || input->key == InputKeyOk) { - state->action = MINDCONTROL; - } - } - // zoom poc for tests - if(input->type == InputTypePress) { - if(input->key == InputKeyDown) { - state->zoom_v = SPEED_X; - } - } else if(input->type == InputTypeRelease) { - if(input->key == InputKeyDown) { - state->zoom_v = -SPEED_X * 2; - state->dialog_progress = 0; - } + state->action = MINDCONTROL; } - // mind control + if(state->action == MINDCONTROL) { if(input->type == InputTypePress) { if(input->key == InputKeyRight) { - state->player_flipped = false; + state->player_v.y = 0; state->player_v.x = SPEED_X; } else if(input->key == InputKeyLeft) { - state->player_flipped = true; + state->player_v.y = 0; state->player_v.x = -SPEED_X; - } - } else if(input->type == InputTypeRelease) { - if(input->key == InputKeyRight || input->key == InputKeyLeft) { + } else if(input->key == InputKeyUp) { state->player_v.x = 0; + state->player_v.y = -SPEED_Y; + } else if(input->key == InputKeyDown) { + state->player_v.x = 0; + state->player_v.y = SPEED_Y; } + } + + if(input->type == InputTypeRelease) { + state->player_v.x = 0; + state->player_v.y = 0; } else if(input->type == InputTypeShort) { if(input->key == InputKeyOk) { state->prev_action = MINDCONTROL; @@ -59,13 +47,14 @@ void dolphin_scene_coordinates(SceneState* state, uint32_t dt) { // global pos state->player_global.x = CLAMP(state->player_global.x + state->player_v.x, WORLD_WIDTH, 0); + state->player_global.y = CLAMP(state->player_global.y + state->player_v.y, WORLD_HEIGHT, 0); - // zoom handlers - state->scene_zoom = CLAMP(state->scene_zoom + state->zoom_v, SCENE_ZOOM, 0); - state->player.x = CLAMP(state->player.x - (state->zoom_v * (SPEED_X * 2)), DOLPHIN_CENTER, 0); - state->player.y = CLAMP(state->player.y - (state->zoom_v * SPEED_X / 2), DOLPHIN_DEFAULT_Y, 3); - - //center screen - state->screen.x = state->player_global.x - state->player.x; - state->player_anim = (state->player_global.x / 10) % 2; + // nudge camera postition + if(state->player_global.x > 170) { + state->player.x = + CLAMP(state->player.x - state->player_v.x / 2, DOLPHIN_CENTER, -DOLPHIN_WIDTH / 2); + } else if(state->player_global.x < 70) { + state->player.x = + CLAMP(state->player.x - state->player_v.x / 2, DOLPHIN_WIDTH * 2, DOLPHIN_CENTER); + } }
\ No newline at end of file diff --git a/applications/dolphin/scenes/scene_dolphin_state.c b/applications/dolphin/scenes/scene_dolphin_state.c index 632676b6..8d0886bd 100644 --- a/applications/dolphin/scenes/scene_dolphin_state.c +++ b/applications/dolphin/scenes/scene_dolphin_state.c @@ -1,74 +1,32 @@ #include <furi.h> #include "scene.h" -#include "assets/emotes.h" - -static uint16_t roll_new(uint16_t prev, uint16_t max) { - uint16_t val = 999; - while(val != prev) { - val = random() % max; - break; - } - return val; -} +#include "assets/items.h" static void scene_proceed_action(SceneState* state) { furi_assert(state); - state->prev_action = state->action; - state->action = (state->prev_action != state->next_action) ? - state->next_action : - roll_new(state->next_action, ACTIONS_NUM); + state->action = roll_new(state->prev_action, ACTIONS_NUM); state->action_timeout = default_timeout[state->action]; } -static void scene_dolphin_go_to_poi(SceneState* state) { - furi_assert(state); - if(state->player_global.x < state->poi) { - state->player_flipped = false; - state->player_v.x = SPEED_X / 2; - } else if(state->player_global.x > state->poi) { - state->player_flipped = true; - state->player_v.x = -SPEED_X / 2; - } -} - static void scene_action_handler(SceneState* state) { furi_assert(state); - if(state->action == MINDCONTROL && state->player_v.x != 0) { - state->action_timeout = default_timeout[state->action]; + if(state->action == MINDCONTROL) { + if(state->player_v.x != 0 || state->player_v.y != 0) { + state->action_timeout = default_timeout[state->action]; + } } if(state->action_timeout > 0) { state->action_timeout--; - } else { - if(random() % 1000 > 500) { - state->next_action = roll_new(state->prev_action, ACTIONS_NUM); - state->poi = roll_new(state->player_global.x, WORLD_WIDTH / 4); - } } } void dolphin_scene_update_state(SceneState* state, uint32_t t, uint32_t dt) { furi_assert(state); scene_action_handler(state); - UNUSED(dialogues_list); switch(state->action) { - case WALK: - if(state->player_global.x == state->poi) { - state->player_v.x = 0; - scene_proceed_action(state); - } else { - scene_dolphin_go_to_poi(state); - } - break; - case EMOTE: - state->player_flipped = false; - if(state->action_timeout == 0) { - scene_proceed_action(state); - state->emote_id = roll_new(state->previous_emote, SIZEOF_ARRAY(emotes_list)); - break; - } case INTERACT: if(state->action_timeout == 0) { if(state->prev_action == MINDCONTROL) { @@ -78,20 +36,9 @@ void dolphin_scene_update_state(SceneState* state, uint32_t t, uint32_t dt) { } } break; - case SLEEP: - if(state->poi != 154) { // temp - state->poi = 154; - } else if(state->player_global.x != state->poi) { - scene_dolphin_go_to_poi(state); - } else { - state->player_v.x = 0; - if(state->action_timeout == 0) { - state->poi = roll_new(state->player_global.x, WORLD_WIDTH / 4); - scene_proceed_action(state); - } - break; - } + default: + if(state->action_timeout == 0) { scene_proceed_action(state); } diff --git a/applications/dolphin/scenes/scene_gfx.c b/applications/dolphin/scenes/scene_gfx.c index 0d279345..0f722980 100644 --- a/applications/dolphin/scenes/scene_gfx.c +++ b/applications/dolphin/scenes/scene_gfx.c @@ -1,101 +1,46 @@ #include <furi.h> #include "scene.h" -#include "assets/emotes.h" #include "assets/items.h" +#include "assets/meta.h" #include <gui/elements.h> -const char* action_str[] = {"Sleep", "Idle", "Walk", "Emote", "Use", "MC"}; - -static void scene_draw_hint(SceneState* state, Canvas* canvas, bool glitching) { - furi_assert(state); - furi_assert(canvas); - char buf[32]; - - const Item* near = is_nearby(state); - if(near) { - int32_t hint_pos_x = (near->x - state->player_global.x) * PARALLAX(near->layer) + 25; - int8_t hint_pos_y = near->y < 15 ? near->y + 4 : near->y - 16; - - strcpy(buf, near->action_name); - if(glitching) { - for(size_t g = 0; g != state->action_timeout; g++) { - buf[(g * 23) % strlen(buf)] = ' ' + (random() % g * 17) % ('z' - ' '); - } - } - - canvas_draw_str(canvas, hint_pos_x, hint_pos_y, buf); +void dolphin_scene_transition_handler(SceneState* state) { + uint8_t speed_mod = (state->player_v.x || state->player_v.y || state->transition) ? 6 : 10; + + if(state->player_v.x < 0) { + state->frame_pending = DirLeft; + } else if(state->player_v.x > 0) { + state->frame_pending = DirRight; + } else if(state->player_v.y < 0) { + state->frame_pending = DirUp; + } else if(state->player_v.y > 0) { + state->frame_pending = DirDown; } -} + state->transition_pending = state->frame_group != state->frame_pending; -static void scene_draw_current_emote(SceneState* state, Canvas* canvas) { - furi_assert(state); - furi_assert(canvas); - elements_multiline_text_framed(canvas, 80, 20, (char*)emotes_list[state->emote_id]); -} - -static void scene_draw_sleep_emote(SceneState* state, Canvas* canvas) { - furi_assert(state); - furi_assert(canvas); - - char dialog_str[] = "zZzZ.."; - // 2do - sofa x pos getter - if(state->player_global.x == 154 && state->action_timeout % 100 < 50) { - if(state->dialog_progress < strlen(dialog_str)) { - if(state->action_timeout % 10 == 0) state->dialog_progress++; - - dialog_str[state->dialog_progress + 1] = '\0'; - canvas_draw_str(canvas, 80, 20, dialog_str); - } - - } else { - state->dialog_progress = 0; + if(*&frames[state->frame_group][state->frame_type]->frames[state->frame_idx].f) { + state->current_frame = *&frames[state->frame_group][state->frame_type]; } -} -static void scene_draw_dialog(SceneState* state, Canvas* canvas) { - furi_assert(state); - furi_assert(canvas); + uint8_t total = state->current_frame->frames[2].f == NULL ? 2 : 3; - char dialog_str[64]; - char buf[64]; - - strcpy(dialog_str, (char*)dialogues_list[state->dialogue_id]); - - if(state->dialog_progress <= strlen(dialog_str)) { - if(state->action_timeout % 2 == 0) state->dialog_progress++; - dialog_str[state->dialog_progress] = '\0'; - snprintf(buf, state->dialog_progress, dialog_str); - } else { - snprintf(buf, 64, dialog_str); + if(state->transition_pending && !state->frame_idx) { + state->transition_pending = false; + state->transition = true; } - elements_multiline_text_framed(canvas, 68, 16, buf); -} - -/* -static void draw_idle_emote(SceneState* state, Canvas* canvas){ - if(state->action_timeout % 50 < 40 && state->prev_action == MINDCONTROL){ - elements_multiline_text_framed(canvas, 68, 16, "WUT?!"); + if(state->transition) { + state->frame_type = state->frame_pending; + state->frame_group = state->last_group; + state->transition = !(state->frame_idx == total - 1); + } else { + state->frame_group = state->frame_type; } -} -*/ - -static void draw_idle_emote(SceneState* state, Canvas* canvas) { - furi_assert(state); - furi_assert(canvas); - char dialog_str[] = "..."; + state->player_anim++; - if(state->action_timeout % 100 < 50) { - if(state->dialog_progress < strlen(dialog_str)) { - if(state->action_timeout % 10 == 0) state->dialog_progress++; - - dialog_str[state->dialog_progress + 1] = '\0'; - canvas_draw_str(canvas, 70, 15, dialog_str); - } - - } else { - state->dialog_progress = 0; + if(!(state->player_anim % speed_mod)) { + state->frame_idx = (state->frame_idx + 1) % total; } } @@ -103,44 +48,24 @@ void dolphin_scene_render_dolphin(SceneState* state, Canvas* canvas) { furi_assert(state); furi_assert(canvas); - if(state->scene_zoom == SCENE_ZOOM) { - state->dolphin_gfx = &I_DolphinExcited_64x63; - } else if(state->action == SLEEP && state->player_global.x == 154) { // 2do - sofa x pos getter - state->dolphin_gfx = &A_FX_Sitting_40x27; - state->dolphin_gfx_b = &I_FX_SittingB_40x27; - } else if(state->action != INTERACT) { - if(state->player_v.x < 0 || state->player_flipped) { - if(state->player_anim == 0) { - state->dolphin_gfx = &I_WalkL1_32x32; - state->dolphin_gfx_b = &I_WalkLB1_32x32; - - } else { - state->dolphin_gfx = &I_WalkL2_32x32; - state->dolphin_gfx_b = &I_WalkLB2_32x32; - } - } else if(state->player_v.x > 0 || !state->player_flipped) { - if(state->player_anim == 0) { - state->dolphin_gfx = &I_WalkR1_32x32; - state->dolphin_gfx_b = &I_WalkRB1_32x32; - - } else { - state->dolphin_gfx = &I_WalkR2_32x32; - state->dolphin_gfx_b = &I_WalkRB2_32x32; - } - } - } + dolphin_scene_transition_handler(state); canvas_set_bitmap_mode(canvas, true); canvas_set_color(canvas, ColorWhite); - canvas_draw_icon(canvas, state->player.x, state->player.y, state->dolphin_gfx_b); + canvas_draw_icon( + canvas, state->player.x, state->player.y, state->current_frame->frames[state->frame_idx].b); canvas_set_color(canvas, ColorBlack); - canvas_draw_icon(canvas, state->player.x, state->player.y, state->dolphin_gfx); + canvas_draw_icon( + canvas, state->player.x, state->player.y, state->current_frame->frames[state->frame_idx].f); canvas_set_bitmap_mode(canvas, false); } -static bool item_screen_bounds(int32_t pos) { +static bool item_screen_bounds_x(int32_t pos) { return pos > -SCREEN_WIDTH && pos < (SCREEN_WIDTH * 2); } +static bool item_screen_bounds_y(int32_t pos) { + return pos > -SCREEN_HEIGHT * 2 && pos < (SCREEN_HEIGHT * 2); +} void dolphin_scene_render(SceneState* state, Canvas* canvas, uint32_t t) { furi_assert(state); @@ -151,24 +76,17 @@ void dolphin_scene_render(SceneState* state, Canvas* canvas, uint32_t t) { const Item** current_scene = get_scene(state); for(uint8_t l = 0; l < LAYERS; l++) { - if(state->scene_zoom < SCENE_ZOOM) { - for(uint8_t i = 0; i < ITEMS_NUM; i++) { - int32_t item_pos = (current_scene[i]->x - state->player_global.x); - if(item_screen_bounds(item_pos)) { - if(current_scene[i]->draw) current_scene[i]->draw(canvas, state); - - if(l == current_scene[i]->layer) { - canvas_draw_icon( - canvas, - item_pos * PARALLAX(l), - current_scene[i]->y, - current_scene[i]->icon); - canvas_set_bitmap_mode(canvas, false); + for(uint8_t i = 0; i < ItemsEnumTotal; i++) { + int32_t item_pos_X = (current_scene[i]->pos.x - state->player_global.x); + int32_t item_pos_Y = (current_scene[i]->pos.y - state->player_global.y); + + if(item_screen_bounds_x(item_pos_X) && item_screen_bounds_y(item_pos_Y)) { + if(l == current_scene[i]->layer) { + if(current_scene[i]->draw) { + current_scene[i]->draw(canvas, state); } } } - - if(l == 0) canvas_draw_line(canvas, 0, 42, 128, 42); } if(l == DOLPHIN_LAYER) dolphin_scene_render_dolphin(state, canvas); @@ -188,24 +106,16 @@ void dolphin_scene_render_state(SceneState* state, Canvas* canvas) { if(state->debug) { sprintf( buf, - "x:%ld>%d %ld %s", - state->player_global.x, - state->poi, - state->action_timeout, - action_str[state->action]); + "%d:%d %d/%dP%dL%d T%d-%d", + state->frame_idx, + state->current_frame->frames[2].f == NULL ? 2 : 3, + state->frame_group, + state->frame_type, + state->frame_pending, + state->last_group, + state->transition_pending, + state->transition); canvas_draw_str(canvas, 0, 13, buf); } - - if(state->scene_zoom == SCENE_ZOOM) - scene_draw_dialog(state, canvas); - else if(state->action == EMOTE) - scene_draw_current_emote(state, canvas); - else if(state->action == MINDCONTROL) - scene_draw_hint(state, canvas, state->action_timeout > 45); - else if(state->action == INTERACT) - scene_activate_item_callback(state, canvas); - else if(state->action == SLEEP) - scene_draw_sleep_emote(state, canvas); - else if(state->action == IDLE) - draw_idle_emote(state, canvas); + if(state->action == INTERACT) scene_activate_item_callback(state, canvas); }
\ No newline at end of file |