From 378ef2959bedd46036c6838ca4f0d3cf8e0e66aa Mon Sep 17 00:00:00 2001 From: doyle Date: Fri, 29 Sep 2023 17:42:58 +1000 Subject: [PATCH] fp: Load the club terry assets --- Data/Textures/club_terry_resized_25%.png | 3 ++ Data/Textures/club_terry_resized_25%.txt | 3 ++ .../club_terry_alive.png | 3 ++ .../club_terry_dark.png | 3 ++ Data/Textures/sprite_spec.txt | 4 +- build_assets.bat | 1 + feely_pona.cpp | 26 +++++++++++- feely_pona_entity.h | 7 ++++ feely_pona_entity_create.cpp | 18 +++++++++ feely_pona_game.h | 1 + feely_pona_sprite_packer.cpp | 40 ++++++++++++------- 11 files changed, 92 insertions(+), 17 deletions(-) create mode 100644 Data/Textures/club_terry_resized_25%.png create mode 100644 Data/Textures/club_terry_resized_25%.txt create mode 100644 Data/Textures/club_terry_resized_25%/club_terry_alive.png create mode 100644 Data/Textures/club_terry_resized_25%/club_terry_dark.png diff --git a/Data/Textures/club_terry_resized_25%.png b/Data/Textures/club_terry_resized_25%.png new file mode 100644 index 0000000..9f57f0a --- /dev/null +++ b/Data/Textures/club_terry_resized_25%.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:81a5d90d1d579d1b70581e254e557b4185f1b96e132d0f1740edab9d4c245c34 +size 1913012 diff --git a/Data/Textures/club_terry_resized_25%.txt b/Data/Textures/club_terry_resized_25%.txt new file mode 100644 index 0000000..0207f75 --- /dev/null +++ b/Data/Textures/club_terry_resized_25%.txt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c70607ef7d82f762c130a55557e4da729b7112345555b5eedf8fe7d3132faca9 +size 120 diff --git a/Data/Textures/club_terry_resized_25%/club_terry_alive.png b/Data/Textures/club_terry_resized_25%/club_terry_alive.png new file mode 100644 index 0000000..5679b66 --- /dev/null +++ b/Data/Textures/club_terry_resized_25%/club_terry_alive.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:df1e454bdc3d1328d5feab0bf5f9b2fd1770de81142415077d3d188396e8e023 +size 784932 diff --git a/Data/Textures/club_terry_resized_25%/club_terry_dark.png b/Data/Textures/club_terry_resized_25%/club_terry_dark.png new file mode 100644 index 0000000..ca9123c --- /dev/null +++ b/Data/Textures/club_terry_resized_25%/club_terry_dark.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:609229cdd14e0c43d88b70951bad8c5247aad25cf3c0fc9661fb20258a163edd +size 551870 diff --git a/Data/Textures/sprite_spec.txt b/Data/Textures/sprite_spec.txt index feaa75d..075d539 100644 --- a/Data/Textures/sprite_spec.txt +++ b/Data/Textures/sprite_spec.txt @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d532f2c8c4e3de8f8911e667537b5b063ae8564084e70984507f25f1a370f102 -size 479 +oid sha256:1023cacbcc52e050db9675912e1d0bdaa4ac78f3bb4ecc1c3b4f7c15f7368933 +size 520 diff --git a/build_assets.bat b/build_assets.bat index 8b07e1f..14c7dae 100644 --- a/build_assets.bat +++ b/build_assets.bat @@ -14,3 +14,4 @@ if not exist "%sprite_packer%" ( %sprite_packer% 4096x2048 %script_dir%\Data\Textures\sprite_spec.txt %script_dir%\Data\Textures\terry_merchant_resized_25%% || exit /b 1 %sprite_packer% 4096x2048 %script_dir%\Data\Textures\sprite_spec.txt %script_dir%\Data\Textures\smoochie_resized_25%% || exit /b 1 %sprite_packer% 4096x2048 %script_dir%\Data\Textures\sprite_spec.txt %script_dir%\Data\Textures\clinger_resized_25%% || exit /b 1 +%sprite_packer% 4096x2048 %script_dir%\Data\Textures\sprite_spec.txt %script_dir%\Data\Textures\club_terry_resized_25%% || exit /b 1 diff --git a/feely_pona.cpp b/feely_pona.cpp index d65bb69..f69f401 100644 --- a/feely_pona.cpp +++ b/feely_pona.cpp @@ -31,6 +31,9 @@ struct FP_GlobalAnimations Dqn_String8 clinger_death = DQN_STRING8("clinger_death"); Dqn_String8 clinger_walk_up = DQN_STRING8("clinger_walk_up"); Dqn_String8 clinger_walk_down = DQN_STRING8("clinger_walk_down"); + + Dqn_String8 club_terry_alive = DQN_STRING8("club_terry_alive"); + Dqn_String8 club_terry_dark = DQN_STRING8("club_terry_dark"); } g_anim_names; @@ -302,6 +305,7 @@ void TELY_DLL_Init(void *user_data) game->terry_merchant_sprite_sheet = FP_LoadSpriteSheetFromSpec(platform, assets, &platform->arena, DQN_STRING8("terry_merchant_resized_25%")); game->smoochie_sprite_sheet = FP_LoadSpriteSheetFromSpec(platform, assets, &platform->arena, DQN_STRING8("smoochie_resized_25%")); game->clinger_sprite_sheet = FP_LoadSpriteSheetFromSpec(platform, assets, &platform->arena, DQN_STRING8("clinger_resized_25%")); + game->club_terry_sprite_sheet = FP_LoadSpriteSheetFromSpec(platform, assets, &platform->arena, DQN_STRING8("club_terry_resized_25%")); } game->entities = Dqn_VArray_Init(&platform->arena, 1024 * 8); @@ -316,6 +320,7 @@ void TELY_DLL_Init(void *user_data) } FP_Entity_CreateMerchant(game, Dqn_V2_InitNx2(1000, 124), "Merchant"); + FP_Entity_CreateClubTerry(game, Dqn_V2_InitNx2(1000, 400), "Club Terry"); game->tile_size = 37; Dqn_V2I max_tile = platform->core.window_size / game->tile_size; @@ -849,7 +854,6 @@ void FP_EntityActionStateMachine(FP_Game *game, TELY_PlatformInput *input, FP_Ga case FP_EntityType_Merchant: { FP_EntityTerryMerchantState *state = DQN_CAST(FP_EntityTerryMerchantState *)&action->state; TELY_AssetSpriteSheet *sheet = &game->terry_merchant_sprite_sheet; - switch (*state) { case FP_EntityTerryMerchantState_Nil: { action->next_state = FP_EntityTerryMerchantState_Idle; @@ -866,6 +870,26 @@ void FP_EntityActionStateMachine(FP_Game *game, TELY_PlatformInput *input, FP_Ga } } break; + case FP_EntityType_ClubTerry: { + FP_EntityClubTerryState *state = DQN_CAST(FP_EntityClubTerryState *)&action->state; + TELY_AssetSpriteSheet *sheet = &game->club_terry_sprite_sheet; + + switch (*state) { + case FP_EntityClubTerryState_Nil: { + action->next_state = FP_EntityClubTerryState_Idle; + } break; + + case FP_EntityClubTerryState_Idle: { + if (entering_new_state) { + TELY_AssetAnimatedSprite sprite = TELY_Asset_MakeAnimatedSprite(sheet, g_anim_names.club_terry_dark, TELY_AssetFlip_No); + uint64_t duration_ms = FP_GAME_ENTITY_ACTION_INFINITE_TIMER; + FP_Game_EntityActionReset(game, entity->handle, duration_ms, sprite); + } + + } break; + } + } break; + case FP_EntityType_Nil: break; case FP_EntityType_Count: DQN_INVALID_CODE_PATH; break; } diff --git a/feely_pona_entity.h b/feely_pona_entity.h index 07e656e..cbc98c9 100644 --- a/feely_pona_entity.h +++ b/feely_pona_entity.h @@ -9,6 +9,7 @@ enum FP_EntityType FP_EntityType_Terry, FP_EntityType_Smoochie, FP_EntityType_Merchant, + FP_EntityType_ClubTerry, FP_EntityType_Clinger, FP_EntityType_Count, }; @@ -47,3 +48,9 @@ enum FP_EntityTerryMerchantState FP_EntityTerryMerchantState_Nil, FP_EntityTerryMerchantState_Idle, }; + +enum FP_EntityClubTerryState +{ + FP_EntityClubTerryState_Nil, + FP_EntityClubTerryState_Idle, +}; diff --git a/feely_pona_entity_create.cpp b/feely_pona_entity_create.cpp index 3fb78f7..b0cb97a 100644 --- a/feely_pona_entity_create.cpp +++ b/feely_pona_entity_create.cpp @@ -155,3 +155,21 @@ static FP_GameEntityHandle FP_Entity_CreateMerchant(FP_Game *game, Dqn_V2 pos, D return result; } + +static FP_GameEntityHandle FP_Entity_CreateClubTerry(FP_Game *game, Dqn_V2 pos, DQN_FMT_STRING_ANNOTATE char const *fmt, ...) +{ + va_list args; + va_start(args, fmt); + FP_GameEntity *entity = FP_Game_MakeEntityPointerFV(game, fmt, args); + FP_GameEntityHandle result = entity->handle; + va_end(args); + + entity->type = FP_EntityType_ClubTerry; + entity->local_pos = pos; + entity->local_hit_box_size = Dqn_V2_InitNx2(50, 50); + entity->sprite_height.meters = 3.66f; + FP_Entity_AddDebugEditorFlags(game, result); + entity->flags |= FP_GameEntityFlag_NonTraversable; + + return result; +} diff --git a/feely_pona_game.h b/feely_pona_game.h index 70db5be..c1a84da 100644 --- a/feely_pona_game.h +++ b/feely_pona_game.h @@ -205,6 +205,7 @@ struct FP_Game TELY_AssetSpriteSheet smoochie_sprite_sheet; TELY_AssetSpriteSheet terry_merchant_sprite_sheet; TELY_AssetSpriteSheet clinger_sprite_sheet; + TELY_AssetSpriteSheet club_terry_sprite_sheet; FP_GameEntity *root_entity; FP_GameEntity *entity_free_list; diff --git a/feely_pona_sprite_packer.cpp b/feely_pona_sprite_packer.cpp index 70f2c3c..63fed97 100644 --- a/feely_pona_sprite_packer.cpp +++ b/feely_pona_sprite_packer.cpp @@ -30,6 +30,25 @@ struct SpriteSpecification uint16_t frames_per_second; }; +static Dqn_String8 SpriteAnimNameFromFilePath(Dqn_String8 path) +{ + // NOTE: Enumerate the number of frames for this animation ================================= + Dqn_String8 file_name = Dqn_String8_FileNameFromPath(path); + Dqn_String8 file_name_without_extension = Dqn_String8_BinarySplit(file_name, DQN_STRING8(".")).lhs; + + // NOTE: If the sprite is a standalone sprite without any frame suffix (e.g. "_1.png") then + // we accept the entry as the name of the sprite as is. + Dqn_String8 result = {}; + if (Dqn_Char_IsDigit(file_name_without_extension.data[file_name_without_extension.size - 1])) { + Dqn_String8BinarySplitResult split = Dqn_String8_BinarySplitReverse(file_name_without_extension, DQN_STRING8("_")); + result = split.lhs; + } else { + result = file_name_without_extension; + } + + return result; +} + int main(int argc, char const *argv[]) { Dqn_Library_Init(); @@ -131,11 +150,7 @@ int main(int argc, char const *argv[]) rect->h = y; // NOTE: Enumerate the number of frames for this animation ================================= - Dqn_String8 file_name = Dqn_String8_FileNameFromPath(*it.data); - Dqn_String8 file_name_without_extension = Dqn_String8_BinarySplit(file_name, DQN_STRING8(".")).lhs; - Dqn_String8BinarySplitResult split = Dqn_String8_BinarySplitReverse(file_name_without_extension, DQN_STRING8("_")); - Dqn_String8 anim_prefix = split.lhs; - + Dqn_String8 anim_prefix = SpriteAnimNameFromFilePath(*it.data); Dqn_DSMapResult slot = Dqn_DSMap_FindKeyString8(&sprite_spec_table, anim_prefix); DQN_ASSERTF(slot.found, "\n\nSprite frame loaded from file\n" @@ -190,7 +205,7 @@ int main(int argc, char const *argv[]) DQN_CAST(int) num_anims); Dqn_Log_InfoF("Generating meta file: %.*s", DQN_STRING_FMT(meta_path)); - Dqn_String8 anim_prefix = {}; + Dqn_String8 active_anim_prefix = {}; for (Dqn_ListIterator it = {}; Dqn_List_Iterate(&file_list, &it, 0);) { int w, h, channels_in_file; stbi_uc *loaded_image = stbi_load(it.data->data, &w, &h, &channels_in_file, 4 /*desired_channels*/); @@ -211,16 +226,13 @@ int main(int argc, char const *argv[]) stbi_image_free(loaded_image); - // NOTE: Write the sprite and the rects to the sheet - Dqn_String8 file_name = Dqn_String8_FileNameFromPath(*it.data); - Dqn_String8 file_name_to_anim_prefix = Dqn_String8_BinarySplitReverse(file_name, DQN_STRING8("_")).lhs; - // NOTE: Detect what animation we are currently processing ================================= - if (anim_prefix.size == 0 || file_name_to_anim_prefix != anim_prefix) { + Dqn_String8 anim_prefix = SpriteAnimNameFromFilePath(*it.data); + if (active_anim_prefix.size == 0 || active_anim_prefix != anim_prefix) { // NOTE: Anim prefix is different, we are starting a new animation- mark it accordingly - anim_prefix = file_name_to_anim_prefix; - Dqn_DSMapResult slot = Dqn_DSMap_FindKeyString8(&sprite_spec_table, anim_prefix); - Dqn_Fs_WriteFileF(&meta_file, "@anim;%.*s;%u;%u\n", DQN_STRING_FMT(anim_prefix), slot.value->frames_per_second, slot.value->frame_count); + active_anim_prefix = anim_prefix; + Dqn_DSMapResult slot = Dqn_DSMap_FindKeyString8(&sprite_spec_table, active_anim_prefix); + Dqn_Fs_WriteFileF(&meta_file, "@anim;%.*s;%u;%u\n", DQN_STRING_FMT(active_anim_prefix), slot.value->frames_per_second, slot.value->frame_count); } // NOTE: Write the sprite rectangles in ====================================================