fp: Load the club terry assets

This commit is contained in:
doyle 2023-09-29 17:42:58 +10:00
parent 0c68aef519
commit 378ef2959b
11 changed files with 92 additions and 17 deletions

BIN
Data/Textures/club_terry_resized_25%.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Data/Textures/club_terry_resized_25%.txt (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Data/Textures/club_terry_resized_25%/club_terry_alive.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Data/Textures/club_terry_resized_25%/club_terry_dark.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Data/Textures/sprite_spec.txt (Stored with Git LFS)

Binary file not shown.

View File

@ -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\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\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\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

View File

@ -31,6 +31,9 @@ struct FP_GlobalAnimations
Dqn_String8 clinger_death = DQN_STRING8("clinger_death"); Dqn_String8 clinger_death = DQN_STRING8("clinger_death");
Dqn_String8 clinger_walk_up = DQN_STRING8("clinger_walk_up"); Dqn_String8 clinger_walk_up = DQN_STRING8("clinger_walk_up");
Dqn_String8 clinger_walk_down = DQN_STRING8("clinger_walk_down"); 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; 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->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->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->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<FP_GameEntity>(&platform->arena, 1024 * 8); game->entities = Dqn_VArray_Init<FP_GameEntity>(&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_CreateMerchant(game, Dqn_V2_InitNx2(1000, 124), "Merchant");
FP_Entity_CreateClubTerry(game, Dqn_V2_InitNx2(1000, 400), "Club Terry");
game->tile_size = 37; game->tile_size = 37;
Dqn_V2I max_tile = platform->core.window_size / game->tile_size; 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: { case FP_EntityType_Merchant: {
FP_EntityTerryMerchantState *state = DQN_CAST(FP_EntityTerryMerchantState *)&action->state; FP_EntityTerryMerchantState *state = DQN_CAST(FP_EntityTerryMerchantState *)&action->state;
TELY_AssetSpriteSheet *sheet = &game->terry_merchant_sprite_sheet; TELY_AssetSpriteSheet *sheet = &game->terry_merchant_sprite_sheet;
switch (*state) { switch (*state) {
case FP_EntityTerryMerchantState_Nil: { case FP_EntityTerryMerchantState_Nil: {
action->next_state = FP_EntityTerryMerchantState_Idle; action->next_state = FP_EntityTerryMerchantState_Idle;
@ -866,6 +870,26 @@ void FP_EntityActionStateMachine(FP_Game *game, TELY_PlatformInput *input, FP_Ga
} }
} break; } 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_Nil: break;
case FP_EntityType_Count: DQN_INVALID_CODE_PATH; break; case FP_EntityType_Count: DQN_INVALID_CODE_PATH; break;
} }

View File

@ -9,6 +9,7 @@ enum FP_EntityType
FP_EntityType_Terry, FP_EntityType_Terry,
FP_EntityType_Smoochie, FP_EntityType_Smoochie,
FP_EntityType_Merchant, FP_EntityType_Merchant,
FP_EntityType_ClubTerry,
FP_EntityType_Clinger, FP_EntityType_Clinger,
FP_EntityType_Count, FP_EntityType_Count,
}; };
@ -47,3 +48,9 @@ enum FP_EntityTerryMerchantState
FP_EntityTerryMerchantState_Nil, FP_EntityTerryMerchantState_Nil,
FP_EntityTerryMerchantState_Idle, FP_EntityTerryMerchantState_Idle,
}; };
enum FP_EntityClubTerryState
{
FP_EntityClubTerryState_Nil,
FP_EntityClubTerryState_Idle,
};

View File

@ -155,3 +155,21 @@ static FP_GameEntityHandle FP_Entity_CreateMerchant(FP_Game *game, Dqn_V2 pos, D
return result; 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;
}

View File

@ -205,6 +205,7 @@ struct FP_Game
TELY_AssetSpriteSheet smoochie_sprite_sheet; TELY_AssetSpriteSheet smoochie_sprite_sheet;
TELY_AssetSpriteSheet terry_merchant_sprite_sheet; TELY_AssetSpriteSheet terry_merchant_sprite_sheet;
TELY_AssetSpriteSheet clinger_sprite_sheet; TELY_AssetSpriteSheet clinger_sprite_sheet;
TELY_AssetSpriteSheet club_terry_sprite_sheet;
FP_GameEntity *root_entity; FP_GameEntity *root_entity;
FP_GameEntity *entity_free_list; FP_GameEntity *entity_free_list;

View File

@ -30,6 +30,25 @@ struct SpriteSpecification
uint16_t frames_per_second; 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[]) int main(int argc, char const *argv[])
{ {
Dqn_Library_Init(); Dqn_Library_Init();
@ -131,11 +150,7 @@ int main(int argc, char const *argv[])
rect->h = y; rect->h = y;
// NOTE: Enumerate the number of frames for this animation ================================= // NOTE: Enumerate the number of frames for this animation =================================
Dqn_String8 file_name = Dqn_String8_FileNameFromPath(*it.data); Dqn_String8 anim_prefix = SpriteAnimNameFromFilePath(*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_DSMapResult<SpriteSpecification> slot = Dqn_DSMap_FindKeyString8(&sprite_spec_table, anim_prefix); Dqn_DSMapResult<SpriteSpecification> slot = Dqn_DSMap_FindKeyString8(&sprite_spec_table, anim_prefix);
DQN_ASSERTF(slot.found, DQN_ASSERTF(slot.found,
"\n\nSprite frame loaded from file\n" "\n\nSprite frame loaded from file\n"
@ -190,7 +205,7 @@ int main(int argc, char const *argv[])
DQN_CAST(int) num_anims); DQN_CAST(int) num_anims);
Dqn_Log_InfoF("Generating meta file: %.*s", DQN_STRING_FMT(meta_path)); Dqn_Log_InfoF("Generating meta file: %.*s", DQN_STRING_FMT(meta_path));
Dqn_String8 anim_prefix = {}; Dqn_String8 active_anim_prefix = {};
for (Dqn_ListIterator<Dqn_String8> it = {}; Dqn_List_Iterate<Dqn_String8>(&file_list, &it, 0);) { for (Dqn_ListIterator<Dqn_String8> it = {}; Dqn_List_Iterate<Dqn_String8>(&file_list, &it, 0);) {
int w, h, channels_in_file; int w, h, channels_in_file;
stbi_uc *loaded_image = stbi_load(it.data->data, &w, &h, &channels_in_file, 4 /*desired_channels*/); 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); 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 ================================= // 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 // NOTE: Anim prefix is different, we are starting a new animation- mark it accordingly
anim_prefix = file_name_to_anim_prefix; active_anim_prefix = anim_prefix;
Dqn_DSMapResult<SpriteSpecification> slot = Dqn_DSMap_FindKeyString8(&sprite_spec_table, anim_prefix); Dqn_DSMapResult<SpriteSpecification> slot = Dqn_DSMap_FindKeyString8(&sprite_spec_table, active_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); 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 ==================================================== // NOTE: Write the sprite rectangles in ====================================================