fp: Merge TELY_Game and FP_Game
This commit is contained in:
parent
9abaf8fd5f
commit
6d33b18364
257
feely_pona.cpp
257
feely_pona.cpp
@ -47,12 +47,11 @@ void TELY_DLL_Init(void *user_data)
|
||||
// NOTE: TELY Game =============================================================================
|
||||
|
||||
TELY_Assets *assets = &platform->assets;
|
||||
Feely_Pona *pona = Dqn_Arena_New(&platform->arena, Feely_Pona, Dqn_ZeroMem_Yes);
|
||||
TELY_Game *game = &pona->game;
|
||||
FP_Game *game = Dqn_Arena_New(&platform->arena, FP_Game, Dqn_ZeroMem_Yes);
|
||||
game->chunk_pool.arena = &platform->arena;
|
||||
platform->user_data = game;
|
||||
{
|
||||
TELY_AssetSpriteSheet *sheet = &pona->hero_sprite_sheet;
|
||||
TELY_AssetSpriteSheet *sheet = &game->hero_sprite_sheet;
|
||||
Dqn_ThreadScratch scratch = Dqn_Thread_GetScratch(nullptr);
|
||||
Dqn_String8 sheet_path = Dqn_FsPath_ConvertF(scratch.arena, "%.*s/adventurer-v1.5-sheet.png", DQN_STRING_FMT(assets->textures_dir));
|
||||
sheet->tex_handle = platform->func_load_texture(assets, DQN_STRING8("Hero"), sheet_path);
|
||||
@ -83,11 +82,11 @@ void TELY_DLL_Init(void *user_data)
|
||||
{DQN_STRING8("Leap slice C"), /*index*/ 103, /*count*/ 6},
|
||||
};
|
||||
|
||||
pona->hero_sprite_anims = Dqn_Slice_Alloc<TELY_AssetSpriteAnimation>(&platform->arena, DQN_ARRAY_UCOUNT(hero_anims), Dqn_ZeroMem_No);
|
||||
DQN_MEMCPY(pona->hero_sprite_anims.data, &hero_anims, sizeof(hero_anims[0]) * DQN_ARRAY_UCOUNT(hero_anims));
|
||||
game->hero_sprite_anims = Dqn_Slice_Alloc<TELY_AssetSpriteAnimation>(&platform->arena, DQN_ARRAY_UCOUNT(hero_anims), Dqn_ZeroMem_No);
|
||||
DQN_MEMCPY(game->hero_sprite_anims.data, &hero_anims, sizeof(hero_anims[0]) * DQN_ARRAY_UCOUNT(hero_anims));
|
||||
}
|
||||
|
||||
game->entities = Dqn_VArray_Init<TELY_GameEntity>(&platform->arena, 1024 * 8);
|
||||
game->entities = Dqn_VArray_Init<FP_GameEntity>(&platform->arena, 1024 * 8);
|
||||
game->root_entity = Dqn_VArray_Make(&game->entities, 1, Dqn_ZeroMem_No);
|
||||
Dqn_FArray_Add(&game->parent_entity_stack, game->root_entity->handle);
|
||||
|
||||
@ -95,32 +94,32 @@ void TELY_DLL_Init(void *user_data)
|
||||
{
|
||||
// NOTE: Setup entity-tree =================================================================
|
||||
|
||||
TELY_GameEntity *f = TELY_Game_MakeEntityPointerF(game, "F");
|
||||
TELY_Game_PushParentEntity(game, f->handle);
|
||||
TELY_GameEntity *b = TELY_Game_MakeEntityPointerF(game, "B");
|
||||
TELY_GameEntity *g = TELY_Game_MakeEntityPointerF(game, "G");
|
||||
TELY_Game_PushParentEntity(game, b->handle);
|
||||
TELY_GameEntity *a = TELY_Game_MakeEntityPointerF(game, "A");
|
||||
TELY_GameEntity *d = TELY_Game_MakeEntityPointerF(game, "D");
|
||||
TELY_Game_PushParentEntity(game, d->handle);
|
||||
TELY_GameEntity *c = TELY_Game_MakeEntityPointerF(game, "C");
|
||||
TELY_GameEntity *e = TELY_Game_MakeEntityPointerF(game, "E");
|
||||
TELY_Game_PopParentEntity(game);
|
||||
TELY_Game_PopParentEntity(game);
|
||||
FP_GameEntity *f = FP_Game_MakeEntityPointerF(game, "F");
|
||||
FP_Game_PushParentEntity(game, f->handle);
|
||||
FP_GameEntity *b = FP_Game_MakeEntityPointerF(game, "B");
|
||||
FP_GameEntity *g = FP_Game_MakeEntityPointerF(game, "G");
|
||||
FP_Game_PushParentEntity(game, b->handle);
|
||||
FP_GameEntity *a = FP_Game_MakeEntityPointerF(game, "A");
|
||||
FP_GameEntity *d = FP_Game_MakeEntityPointerF(game, "D");
|
||||
FP_Game_PushParentEntity(game, d->handle);
|
||||
FP_GameEntity *c = FP_Game_MakeEntityPointerF(game, "C");
|
||||
FP_GameEntity *e = FP_Game_MakeEntityPointerF(game, "E");
|
||||
FP_Game_PopParentEntity(game);
|
||||
FP_Game_PopParentEntity(game);
|
||||
|
||||
TELY_Game_PushParentEntity(game, g->handle);
|
||||
TELY_GameEntity *i = TELY_Game_MakeEntityPointerF(game, "I");
|
||||
TELY_Game_PushParentEntity(game, i->handle);
|
||||
TELY_GameEntity *h = TELY_Game_MakeEntityPointerF(game, "H");
|
||||
TELY_Game_PopParentEntity(game);
|
||||
TELY_Game_PopParentEntity(game);
|
||||
TELY_Game_PopParentEntity(game);
|
||||
FP_Game_PushParentEntity(game, g->handle);
|
||||
FP_GameEntity *i = FP_Game_MakeEntityPointerF(game, "I");
|
||||
FP_Game_PushParentEntity(game, i->handle);
|
||||
FP_GameEntity *h = FP_Game_MakeEntityPointerF(game, "H");
|
||||
FP_Game_PopParentEntity(game);
|
||||
FP_Game_PopParentEntity(game);
|
||||
FP_Game_PopParentEntity(game);
|
||||
|
||||
// NOTE: Pre order test ====================================================================
|
||||
|
||||
TELY_GameEntity *pre_order_walk[9] = {};
|
||||
FP_GameEntity *pre_order_walk[9] = {};
|
||||
Dqn_usize pre_order_walk_count = 0;
|
||||
for (TELY_GameEntityIterator it = {}; TELY_Game_DFSPreOrderWalkEntityTree(game, &it, game->root_entity);) {
|
||||
for (FP_GameEntityIterator it = {}; FP_Game_DFSPreOrderWalkEntityTree(game, &it, game->root_entity);) {
|
||||
DQN_ASSERT(pre_order_walk_count < DQN_ARRAY_UCOUNT(pre_order_walk));
|
||||
pre_order_walk[pre_order_walk_count++] = it.entity;
|
||||
}
|
||||
@ -138,9 +137,9 @@ void TELY_DLL_Init(void *user_data)
|
||||
|
||||
// NOTE: Post order test ===================================================================
|
||||
|
||||
TELY_GameEntity *post_order_walk[9] = {};
|
||||
FP_GameEntity *post_order_walk[9] = {};
|
||||
Dqn_usize post_order_walk_count = 0;
|
||||
for (TELY_GameEntityIterator it = {}; TELY_Game_DFSPostOrderWalkEntityTree(game, &it, game->root_entity);) {
|
||||
for (FP_GameEntityIterator it = {}; FP_Game_DFSPostOrderWalkEntityTree(game, &it, game->root_entity);) {
|
||||
DQN_ASSERT(post_order_walk_count < DQN_ARRAY_UCOUNT(post_order_walk));
|
||||
post_order_walk[post_order_walk_count++] = it.entity;
|
||||
}
|
||||
@ -157,7 +156,7 @@ void TELY_DLL_Init(void *user_data)
|
||||
DQN_ASSERT(post_order_walk[8] == f);
|
||||
|
||||
// NOTE: Cleanup ===========================================================================
|
||||
TELY_Game_DeleteEntity(game, game->root_entity->handle);
|
||||
FP_Game_DeleteEntity(game, game->root_entity->handle);
|
||||
DQN_ASSERT(game->root_entity->first_child == nullptr);
|
||||
DQN_ASSERT(game->root_entity->last_child == nullptr);
|
||||
DQN_ASSERT(game->root_entity->next == nullptr);
|
||||
@ -167,65 +166,60 @@ void TELY_DLL_Init(void *user_data)
|
||||
|
||||
// NOTE: Hero
|
||||
{
|
||||
TELY_GameEntity *hero = TELY_Game_MakeEntityPointerF(game, "Hero");
|
||||
FP_GameEntity *hero = FP_Game_MakeEntityPointerF(game, "Hero");
|
||||
hero->local_pos = Dqn_V2_InitNx2(100.f, 100.f);
|
||||
hero->size_scale = Dqn_V2_InitNx1(4);
|
||||
hero->sprite_sheet = &pona->hero_sprite_sheet;
|
||||
hero->sprite_anims = pona->hero_sprite_anims;
|
||||
hero->local_hit_box_size = Dqn_V2_InitV2I(pona->hero_sprite_sheet.sprite_size);
|
||||
hero->flags |= TELY_EntityFlag_Clickable;
|
||||
hero->flags |= TELY_EntityFlag_MoveByKeyboard;
|
||||
hero->flags |= TELY_EntityFlag_MoveByMouse;
|
||||
hero->sprite_sheet = &game->hero_sprite_sheet;
|
||||
hero->sprite_anims = game->hero_sprite_anims;
|
||||
hero->local_hit_box_size = Dqn_V2_InitV2I(game->hero_sprite_sheet.sprite_size);
|
||||
hero->flags |= FP_EntityFlag_Clickable;
|
||||
hero->flags |= FP_EntityFlag_MoveByKeyboard;
|
||||
hero->flags |= FP_EntityFlag_MoveByMouse;
|
||||
game->clicked_entity = hero->handle;
|
||||
}
|
||||
|
||||
// NOTE: Enemy
|
||||
{
|
||||
TELY_GameEntity *enemy = TELY_Game_MakeEntityPointerF(game, "Enemy");
|
||||
FP_GameEntity *enemy = FP_Game_MakeEntityPointerF(game, "Enemy");
|
||||
enemy->local_pos = Dqn_V2_InitNx2(300.f, 300.f);
|
||||
enemy->size_scale = Dqn_V2_InitNx1(4);
|
||||
enemy->sprite_sheet = &pona->hero_sprite_sheet;
|
||||
enemy->sprite_anims = pona->hero_sprite_anims;
|
||||
enemy->local_hit_box_size = Dqn_V2_InitV2I(pona->hero_sprite_sheet.sprite_size);
|
||||
enemy->flags |= TELY_EntityFlag_Clickable;
|
||||
enemy->flags |= TELY_EntityFlag_MoveByKeyboard;
|
||||
enemy->flags |= TELY_EntityFlag_MoveByMouse;
|
||||
enemy->sprite_sheet = &game->hero_sprite_sheet;
|
||||
enemy->sprite_anims = game->hero_sprite_anims;
|
||||
enemy->local_hit_box_size = Dqn_V2_InitV2I(game->hero_sprite_sheet.sprite_size);
|
||||
enemy->flags |= FP_EntityFlag_Clickable;
|
||||
enemy->flags |= FP_EntityFlag_MoveByKeyboard;
|
||||
enemy->flags |= FP_EntityFlag_MoveByMouse;
|
||||
}
|
||||
|
||||
// NOTE: Wall
|
||||
{
|
||||
TELY_GameEntity *entity = TELY_Game_MakeEntityPointerF(game, "V. Wall");
|
||||
FP_GameEntity *entity = FP_Game_MakeEntityPointerF(game, "V. Wall");
|
||||
entity->local_pos = Dqn_V2_InitNx2(100.f, 300.f);
|
||||
entity->local_hit_box_size = Dqn_V2_InitNx2(100.f, 300.f);
|
||||
entity->flags |= TELY_EntityFlag_Clickable;
|
||||
entity->flags |= TELY_EntityFlag_MoveByKeyboard;
|
||||
entity->flags |= TELY_EntityFlag_MoveByMouse;
|
||||
entity->flags |= FP_EntityFlag_Clickable;
|
||||
entity->flags |= FP_EntityFlag_MoveByKeyboard;
|
||||
entity->flags |= FP_EntityFlag_MoveByMouse;
|
||||
|
||||
TELY_GameShape *wall = Dqn_FArray_Make(&entity->shapes, Dqn_ZeroMem_Yes);
|
||||
wall->type = TELY_GameShapeType_Rect;
|
||||
FP_GameShape *wall = Dqn_FArray_Make(&entity->shapes, Dqn_ZeroMem_Yes);
|
||||
wall->type = FP_GameShapeType_Rect;
|
||||
wall->p2 = entity->local_hit_box_size;
|
||||
wall->colour = TELY_COLOUR_GREEN_DARK_KHAKI_V4;
|
||||
}
|
||||
|
||||
uint16_t font_size = 18;
|
||||
game->camera.scale = Dqn_V2_InitNx1(1);
|
||||
pona->inter_regular_font = platform->func_load_font(assets, DQN_STRING8("Inter (Regular)"), DQN_STRING8("Data/Inter-Regular.otf"), font_size);
|
||||
pona->inter_italic_font = platform->func_load_font(assets, DQN_STRING8("Inter (Italic)"), DQN_STRING8("Data/Inter-Italic.otf"), font_size);
|
||||
pona->jetbrains_mono_font = platform->func_load_font(assets, DQN_STRING8("JetBrains Mono NL (Regular)"), DQN_STRING8("Data/JetBrainsMonoNL-Regular.ttf"), font_size);
|
||||
pona->test_audio = platform->func_load_audio(assets, DQN_STRING8("Test Audio"), DQN_STRING8("Data/Audio/Purrple Cat - Moonwinds.qoa"));
|
||||
game->inter_regular_font = platform->func_load_font(assets, DQN_STRING8("Inter (Regular)"), DQN_STRING8("Data/Inter-Regular.otf"), font_size);
|
||||
game->inter_italic_font = platform->func_load_font(assets, DQN_STRING8("Inter (Italic)"), DQN_STRING8("Data/Inter-Italic.otf"), font_size);
|
||||
game->jetbrains_mono_font = platform->func_load_font(assets, DQN_STRING8("JetBrains Mono NL (Regular)"), DQN_STRING8("Data/JetBrainsMonoNL-Regular.ttf"), font_size);
|
||||
game->test_audio = platform->func_load_audio(assets, DQN_STRING8("Test Audio"), DQN_STRING8("Data/Audio/Purrple Cat - Moonwinds.qoa"));
|
||||
|
||||
// NOTE: TELY audio ============================================================================
|
||||
|
||||
TELY_Audio *audio = &platform->audio;
|
||||
audio->chunk_pool = &game->chunk_pool;
|
||||
|
||||
// NOTE: TELY ui ===============================================================================
|
||||
|
||||
TELY_UI *ui = &game->ui;
|
||||
ui->arena.allocs_are_allowed_to_leak = true;
|
||||
}
|
||||
|
||||
void TELY_Game_EntityChangeState(TELY_GameEntity *entity, TELY_GameEntityState state)
|
||||
void FP_Game_EntityChangeState(FP_GameEntity *entity, FP_GameEntityState state)
|
||||
{
|
||||
if (entity->state == state)
|
||||
return;
|
||||
@ -237,18 +231,18 @@ void TELY_Game_EntityChangeState(TELY_GameEntity *entity, TELY_GameEntityState s
|
||||
// decouple the state from the animation, e.g. the wall doesn't have an animation
|
||||
uint16_t desired_sprite_anim_index = 0;
|
||||
switch (state) {
|
||||
case TELY_GameEntityState_Nil: {
|
||||
case FP_GameEntityState_Nil: {
|
||||
} break;
|
||||
|
||||
case TELY_GameEntityState_Idle: {
|
||||
case FP_GameEntityState_Idle: {
|
||||
desired_sprite_anim_index = TELY_Asset_GetSpriteAnim(entity->sprite_anims, DQN_STRING8("Idle"));
|
||||
} break;
|
||||
|
||||
case TELY_GameEntityState_Attack: {
|
||||
case FP_GameEntityState_Attack: {
|
||||
desired_sprite_anim_index = TELY_Asset_GetSpriteAnim(entity->sprite_anims, DQN_STRING8("Attack A"));
|
||||
} break;
|
||||
|
||||
case TELY_GameEntityState_Run: {
|
||||
case FP_GameEntityState_Run: {
|
||||
desired_sprite_anim_index = TELY_Asset_GetSpriteAnim(entity->sprite_anims, DQN_STRING8("Running"));
|
||||
} break;
|
||||
}
|
||||
@ -366,7 +360,7 @@ Dqn_Slice<Dqn_V2I> AStarPathFind(Dqn_Arena *arena, TELY_Platform *platform, Dqn_
|
||||
return result;
|
||||
}
|
||||
|
||||
void FP_GameUpdate(TELY_Platform *platform, TELY_Game *game, TELY_Renderer *renderer, TELY_PlatformInput *input)
|
||||
void FP_GameUpdate(TELY_Platform *platform, FP_Game *game, TELY_Renderer *renderer, TELY_PlatformInput *input)
|
||||
{
|
||||
if (TELY_Platform_InputKeyIsReleased(input->mouse_left))
|
||||
game->clicked_entity = game->prev_active_entity;
|
||||
@ -383,19 +377,19 @@ void FP_GameUpdate(TELY_Platform *platform, TELY_Game *game, TELY_Renderer *rend
|
||||
|
||||
if (game->clicked_entity.id) {
|
||||
if (TELY_Platform_InputScanCodeIsPressed(input, TELY_PlatformInputScanCode_Delete))
|
||||
TELY_Game_DeleteEntity(game, game->clicked_entity);
|
||||
FP_Game_DeleteEntity(game, game->clicked_entity);
|
||||
|
||||
TELY_GameEntity *player = TELY_Game_GetEntity(game, game->clicked_entity);
|
||||
FP_GameEntity *player = FP_Game_GetEntity(game, game->clicked_entity);
|
||||
if (player) {
|
||||
if (TELY_Platform_InputScanCodeIsDown(input, TELY_PlatformInputScanCode_J)) {
|
||||
TELY_Game_EntityChangeState(player, TELY_GameEntityState_Attack);
|
||||
FP_Game_EntityChangeState(player, FP_GameEntityState_Attack);
|
||||
}
|
||||
|
||||
if (player->state != TELY_GameEntityState_Attack) {
|
||||
if (player->state != FP_GameEntityState_Attack) {
|
||||
if (dir_vector.x || dir_vector.y) {
|
||||
TELY_Game_EntityChangeState(player, TELY_GameEntityState_Run);
|
||||
FP_Game_EntityChangeState(player, FP_GameEntityState_Run);
|
||||
} else {
|
||||
TELY_Game_EntityChangeState(player, TELY_GameEntityState_Idle);
|
||||
FP_Game_EntityChangeState(player, FP_GameEntityState_Idle);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -403,36 +397,36 @@ void FP_GameUpdate(TELY_Platform *platform, TELY_Game *game, TELY_Renderer *rend
|
||||
game->camera.world_pos += dir_vector * 5.f;
|
||||
}
|
||||
|
||||
for (TELY_GameEntityIterator it = {}; TELY_Game_DFSPostOrderWalkEntityTree(game, &it, game->root_entity); ) {
|
||||
TELY_GameEntity *entity = it.entity;
|
||||
for (FP_GameEntityIterator it = {}; FP_Game_DFSPostOrderWalkEntityTree(game, &it, game->root_entity); ) {
|
||||
FP_GameEntity *entity = it.entity;
|
||||
entity->alive_time_s += input->delta_s;
|
||||
|
||||
// NOTE: Move entity by keyboard ===========================================================
|
||||
Dqn_V2 acceleration = {};
|
||||
if (game->clicked_entity == entity->handle) {
|
||||
if (entity->flags & TELY_EntityFlag_MoveByKeyboard) {
|
||||
if (entity->flags & FP_EntityFlag_MoveByKeyboard) {
|
||||
acceleration = dir_vector * 10000000.f;
|
||||
if (dir_vector.x)
|
||||
entity->facing_left = dir_vector.x < 0.f;
|
||||
}
|
||||
}
|
||||
|
||||
Dqn_V2 entity_world_pos = TELY_Game_CalcEntityWorldPos(game, entity->handle);
|
||||
Dqn_V2 entity_world_pos = FP_Game_CalcEntityWorldPos(game, entity->handle);
|
||||
if (entity->name == DQN_STRING8("Enemy")) {
|
||||
if (entity->handle != game->clicked_entity && entity->stalk_entity != game->clicked_entity) {
|
||||
entity->stalk_entity = game->clicked_entity;
|
||||
}
|
||||
|
||||
TELY_GameEntity *stalk_entity = TELY_Game_GetEntity(game, entity->stalk_entity);
|
||||
FP_GameEntity *stalk_entity = FP_Game_GetEntity(game, entity->stalk_entity);
|
||||
if (stalk_entity) {
|
||||
Dqn_V2 stalk_world_pos = TELY_Game_CalcEntityWorldPos(game, stalk_entity->handle);
|
||||
Dqn_V2 stalk_world_pos = FP_Game_CalcEntityWorldPos(game, stalk_entity->handle);
|
||||
Dqn_V2I stalk_tile = Dqn_V2I_InitNx2(stalk_world_pos.x / FP_TILE_SIZE, stalk_world_pos.y / FP_TILE_SIZE);
|
||||
if (entity->stalk_entity_last_known_tile != stalk_tile) {
|
||||
entity->stalk_entity_last_known_tile = stalk_tile;
|
||||
|
||||
// NOTE: Dealloc all waypoints
|
||||
for (TELY_GameWaypoint *waypoint = entity->waypoints->next; waypoint != entity->waypoints; ) {
|
||||
TELY_GameWaypoint *next = waypoint->next;
|
||||
for (FP_GameWaypoint *waypoint = entity->waypoints->next; waypoint != entity->waypoints; ) {
|
||||
FP_GameWaypoint *next = waypoint->next;
|
||||
TELY_ChunkPool_Dealloc(&game->chunk_pool, waypoint);
|
||||
waypoint = next;
|
||||
}
|
||||
@ -443,7 +437,7 @@ void FP_GameUpdate(TELY_Platform *platform, TELY_Game *game, TELY_Renderer *rend
|
||||
Dqn_Slice<Dqn_V2I> path_find = AStarPathFind(&platform->arena, platform, entity_tile, stalk_tile);
|
||||
|
||||
for (Dqn_usize index = path_find.size - 1; index < path_find.size; index--) {
|
||||
TELY_GameWaypoint *waypoint = TELY_ChunkPool_New(&game->chunk_pool, TELY_GameWaypoint);
|
||||
FP_GameWaypoint *waypoint = TELY_ChunkPool_New(&game->chunk_pool, FP_GameWaypoint);
|
||||
waypoint->pos = path_find.data[index];
|
||||
waypoint->next = entity->waypoints;
|
||||
waypoint->prev = entity->waypoints->prev;
|
||||
@ -454,13 +448,13 @@ void FP_GameUpdate(TELY_Platform *platform, TELY_Game *game, TELY_Renderer *rend
|
||||
}
|
||||
}
|
||||
|
||||
for (TELY_GameWaypoint *waypoint = entity->waypoints->next; waypoint != entity->waypoints; waypoint = waypoint->next) {
|
||||
for (FP_GameWaypoint *waypoint = entity->waypoints->next; waypoint != entity->waypoints; waypoint = waypoint->next) {
|
||||
Dqn_V2 circle_pos = Dqn_V2_InitNx2(waypoint->pos.x * FP_TILE_SIZE + FP_TILE_SIZE * .5f, waypoint->pos.y * FP_TILE_SIZE + FP_TILE_SIZE * .5f);
|
||||
TELY_Render_CircleColourV4(renderer, circle_pos, 4.f, TELY_RenderShapeMode_Fill, TELY_COLOUR_MAGENTA_V4);
|
||||
}
|
||||
|
||||
if (entity->waypoints->next != entity->waypoints) {
|
||||
TELY_GameWaypoint *waypoint = entity->waypoints->next;
|
||||
FP_GameWaypoint *waypoint = entity->waypoints->next;
|
||||
Dqn_V2I target_tile = entity->waypoints->next->pos;
|
||||
Dqn_V2 target_pos = Dqn_V2_InitNx2(target_tile.x * FP_TILE_SIZE + FP_TILE_SIZE *.5f, target_tile.y * FP_TILE_SIZE + FP_TILE_SIZE * .5f);
|
||||
Dqn_V2 entity_to_target_pos = target_pos - entity_world_pos;
|
||||
@ -487,42 +481,42 @@ void FP_GameUpdate(TELY_Platform *platform, TELY_Game *game, TELY_Renderer *rend
|
||||
Dqn_V2 delta_p = (acceleration * 0.5f * t_squared) + (entity->velocity * t);
|
||||
entity->local_pos += delta_p;
|
||||
|
||||
Dqn_Rect world_hit_box = TELY_Game_CalcEntityWorldHitBox(game, entity->handle);
|
||||
Dqn_Rect world_hit_box = FP_Game_CalcEntityWorldHitBox(game, entity->handle);
|
||||
Dqn_Rect new_world_hit_box = world_hit_box;
|
||||
new_world_hit_box.pos += delta_p;
|
||||
|
||||
for (TELY_GameEntityIterator collider_it = {}; TELY_Game_DFSPostOrderWalkEntityTree(game, &collider_it, game->root_entity); ) {
|
||||
TELY_GameEntity *collider = collider_it.entity;
|
||||
for (FP_GameEntityIterator collider_it = {}; FP_Game_DFSPostOrderWalkEntityTree(game, &collider_it, game->root_entity); ) {
|
||||
FP_GameEntity *collider = collider_it.entity;
|
||||
if (collider->handle == entity->handle)
|
||||
continue;
|
||||
|
||||
// TODO(doyle): Minkowski sweep?
|
||||
Dqn_Rect collider_world_hit_box = TELY_Game_CalcEntityWorldHitBox(game, collider->handle);
|
||||
Dqn_Rect collider_world_hit_box = FP_Game_CalcEntityWorldHitBox(game, collider->handle);
|
||||
if (Dqn_Rect_Intersects(new_world_hit_box, collider_world_hit_box)) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: Move entity by mouse ==============================================================
|
||||
if (game->active_entity == entity->handle && entity->flags & TELY_EntityFlag_MoveByMouse) {
|
||||
if (entity->flags & TELY_EntityFlag_MoveByMouse) {
|
||||
if (game->active_entity == entity->handle && entity->flags & FP_EntityFlag_MoveByMouse) {
|
||||
if (entity->flags & FP_EntityFlag_MoveByMouse) {
|
||||
entity->velocity = {};
|
||||
entity->local_pos += input->mouse_p_delta;
|
||||
}
|
||||
}
|
||||
|
||||
if (entity->flags & TELY_EntityFlag_DeriveHitBoxFromChildrenBoundingBox) {
|
||||
if (entity->flags & FP_EntityFlag_DeriveHitBoxFromChildrenBoundingBox) {
|
||||
Dqn_Rect children_bbox = {};
|
||||
|
||||
// TODO(doyle): Is the hit box supposed to include the containing
|
||||
// entity itself? Not sure
|
||||
children_bbox.pos = TELY_Game_CalcEntityWorldPos(game, entity->handle);
|
||||
children_bbox.pos = FP_Game_CalcEntityWorldPos(game, entity->handle);
|
||||
|
||||
for (TELY_GameEntityIterator child_it = {}; TELY_Game_DFSPreOrderWalkEntityTree(game, &child_it, entity);) {
|
||||
TELY_GameEntity *child = child_it.entity;
|
||||
for (FP_GameEntityIterator child_it = {}; FP_Game_DFSPreOrderWalkEntityTree(game, &child_it, entity);) {
|
||||
FP_GameEntity *child = child_it.entity;
|
||||
DQN_ASSERT(child != entity);
|
||||
|
||||
Dqn_Rect bbox = TELY_Game_CalcEntityWorldBoundingBox(game, child->handle);
|
||||
Dqn_Rect bbox = FP_Game_CalcEntityWorldBoundingBox(game, child->handle);
|
||||
children_bbox = Dqn_Rect_Union(children_bbox, bbox);
|
||||
}
|
||||
|
||||
@ -550,22 +544,22 @@ void FP_GameUpdate(TELY_Platform *platform, TELY_Game *game, TELY_Renderer *rend
|
||||
|
||||
if (action_is_done) {
|
||||
switch (entity->state) {
|
||||
case TELY_GameEntityState_Nil: break;
|
||||
case TELY_GameEntityState_Idle: break;
|
||||
case TELY_GameEntityState_Attack: {
|
||||
TELY_Game_EntityChangeState(entity, TELY_GameEntityState_Idle);
|
||||
case FP_GameEntityState_Nil: break;
|
||||
case FP_GameEntityState_Idle: break;
|
||||
case FP_GameEntityState_Attack: {
|
||||
FP_Game_EntityChangeState(entity, FP_GameEntityState_Idle);
|
||||
} break;
|
||||
|
||||
case TELY_GameEntityState_Run: {
|
||||
case FP_GameEntityState_Run: {
|
||||
if (dir_vector.x == 0 && dir_vector.y == 0)
|
||||
TELY_Game_EntityChangeState(entity, TELY_GameEntityState_Idle);
|
||||
FP_Game_EntityChangeState(entity, FP_GameEntityState_Idle);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: Calculate entity attack box =======================================================
|
||||
if (entity->state == TELY_GameEntityState_Attack) {
|
||||
if (entity->state == FP_GameEntityState_Attack) {
|
||||
|
||||
entity->attack_box_size = entity->local_hit_box_size;
|
||||
TELY_AssetSpriteSheet const *sprite_sheet = entity->sprite_sheet;
|
||||
@ -587,18 +581,18 @@ void FP_GameUpdate(TELY_Platform *platform, TELY_Game *game, TELY_Renderer *rend
|
||||
}
|
||||
|
||||
// NOTE: Do attacks ============================================================================
|
||||
for (TELY_GameEntityIterator attacker_it = {}; TELY_Game_DFSPostOrderWalkEntityTree(game, &attacker_it, game->root_entity); ) {
|
||||
TELY_GameEntity *attacker = attacker_it.entity;
|
||||
for (FP_GameEntityIterator attacker_it = {}; FP_Game_DFSPostOrderWalkEntityTree(game, &attacker_it, game->root_entity); ) {
|
||||
FP_GameEntity *attacker = attacker_it.entity;
|
||||
|
||||
// NOTE: Resolve attack boxes
|
||||
if (Dqn_V2_Area(attacker->attack_box_size)) {
|
||||
Dqn_Rect attacker_box = TELY_Game_CalcEntityAttackWorldHitBox(game, attacker->handle);
|
||||
for (TELY_GameEntityIterator defender_it = {}; TELY_Game_DFSPostOrderWalkEntityTree(game, &defender_it, game->root_entity); ) {
|
||||
TELY_GameEntity *defender = defender_it.entity;
|
||||
Dqn_Rect attacker_box = FP_Game_CalcEntityAttackWorldHitBox(game, attacker->handle);
|
||||
for (FP_GameEntityIterator defender_it = {}; FP_Game_DFSPostOrderWalkEntityTree(game, &defender_it, game->root_entity); ) {
|
||||
FP_GameEntity *defender = defender_it.entity;
|
||||
if (defender->handle == attacker->handle)
|
||||
continue;
|
||||
|
||||
Dqn_Rect defender_box = TELY_Game_CalcEntityWorldHitBox(game, defender->handle);
|
||||
Dqn_Rect defender_box = FP_Game_CalcEntityWorldHitBox(game, defender->handle);
|
||||
Dqn_Rect hit_rect = Dqn_Rect_Intersection(attacker_box, defender_box);
|
||||
|
||||
if (!Dqn_Rect_Area(hit_rect))
|
||||
@ -624,10 +618,10 @@ void FP_GameUpdate(TELY_Platform *platform, TELY_Game *game, TELY_Renderer *rend
|
||||
}
|
||||
}
|
||||
|
||||
void FP_GameRender(TELY_Game *game, TELY_Platform *platform, TELY_Renderer *renderer)
|
||||
void FP_GameRender(FP_Game *game, TELY_Platform *platform, TELY_Renderer *renderer)
|
||||
{
|
||||
TELY_PlatformInput *input = &platform->input;
|
||||
Dqn_M2x3 model_view = TELY_Game_CameraModelViewM2x3(game->camera, platform);
|
||||
Dqn_M2x3 model_view = FP_Game_CameraModelViewM2x3(game->camera, platform);
|
||||
Dqn_V2 world_mouse_p = Dqn_M2x3_MulV2(model_view, input->mouse_p);
|
||||
|
||||
// NOTE: Draw tiles ============================================================================
|
||||
@ -647,31 +641,31 @@ void FP_GameRender(TELY_Game *game, TELY_Platform *platform, TELY_Renderer *rend
|
||||
}
|
||||
|
||||
// NOTE: Draw entities =========================================================================
|
||||
for (TELY_GameEntityIterator it = {}; TELY_Game_DFSPostOrderWalkEntityTree(game, &it, game->root_entity); ) {
|
||||
TELY_GameEntity *entity = it.entity;
|
||||
for (FP_GameEntityIterator it = {}; FP_Game_DFSPostOrderWalkEntityTree(game, &it, game->root_entity); ) {
|
||||
FP_GameEntity *entity = it.entity;
|
||||
entity->alive_time_s += input->delta_s;
|
||||
|
||||
// NOTE: Render shapes in entity ===========================================================
|
||||
Dqn_V2 world_pos = TELY_Game_CalcEntityWorldPos(game, entity->handle);
|
||||
for (TELY_GameShape const &shape_ : entity->shapes) {
|
||||
TELY_GameShape const *shape = &shape_;
|
||||
Dqn_V2 world_pos = FP_Game_CalcEntityWorldPos(game, entity->handle);
|
||||
for (FP_GameShape const &shape_ : entity->shapes) {
|
||||
FP_GameShape const *shape = &shape_;
|
||||
Dqn_V2 local_to_world_p1 = world_pos + shape->p1;
|
||||
Dqn_V2 local_to_world_p2 = world_pos + shape->p2;
|
||||
switch (shape->type) {
|
||||
case TELY_GameShapeType_None: {
|
||||
case FP_GameShapeType_None: {
|
||||
} break;
|
||||
|
||||
case TELY_GameShapeType_Circle: {
|
||||
case FP_GameShapeType_Circle: {
|
||||
TELY_Render_CircleColourV4(renderer, local_to_world_p1, shape->circle_radius, shape->render_mode, shape->colour);
|
||||
} break;
|
||||
|
||||
case TELY_GameShapeType_Rect: {
|
||||
case FP_GameShapeType_Rect: {
|
||||
Dqn_Rect rect = Dqn_Rect_InitV2x2(local_to_world_p1, local_to_world_p2 - local_to_world_p1);
|
||||
rect.pos -= rect.size * .5f;
|
||||
TELY_Render_RectColourV4(renderer, rect, shape->render_mode, shape->colour);
|
||||
} break;
|
||||
|
||||
case TELY_GameShapeType_Line: {
|
||||
case FP_GameShapeType_Line: {
|
||||
TELY_Render_LineColourV4(renderer, local_to_world_p1, local_to_world_p2, shape->colour, shape->line_thickness);
|
||||
} break;
|
||||
}
|
||||
@ -704,7 +698,7 @@ void FP_GameRender(TELY_Game *game, TELY_Platform *platform, TELY_Renderer *rend
|
||||
|
||||
// NOTE: Render attack box =================================================================
|
||||
{
|
||||
Dqn_Rect attack_box = TELY_Game_CalcEntityAttackWorldHitBox(game, entity->handle);
|
||||
Dqn_Rect attack_box = FP_Game_CalcEntityAttackWorldHitBox(game, entity->handle);
|
||||
TELY_Render_RectColourV4(renderer, attack_box, TELY_RenderShapeMode_Line, TELY_COLOUR_RED_TOMATO_V4);
|
||||
}
|
||||
|
||||
@ -712,10 +706,10 @@ void FP_GameRender(TELY_Game *game, TELY_Platform *platform, TELY_Renderer *rend
|
||||
TELY_Render_CircleColourV4(renderer, world_pos, 4.f, TELY_RenderShapeMode_Fill, TELY_COLOUR_RED_TOMATO_V4);
|
||||
|
||||
// NOTE: Render hot/active entity ==========================================================
|
||||
Dqn_Rect world_hit_box = TELY_Game_CalcEntityWorldHitBox(game, entity->handle);
|
||||
Dqn_Rect world_hit_box = FP_Game_CalcEntityWorldHitBox(game, entity->handle);
|
||||
if (game->clicked_entity == entity->handle) {
|
||||
TELY_Render_RectColourV4(renderer, world_hit_box, TELY_RenderShapeMode_Line, TELY_COLOUR_WHITE_PALE_GOLDENROD_V4);
|
||||
} else if (game->hot_entity == entity->handle || (entity->flags & TELY_EntityFlag_DrawHitBox)) {
|
||||
} else if (game->hot_entity == entity->handle || (entity->flags & FP_EntityFlag_DrawHitBox)) {
|
||||
Dqn_V4 hot_colour = game->hot_entity == entity->handle ? TELY_COLOUR_RED_TOMATO_V4 : TELY_Colour_V4Alpha(TELY_COLOUR_YELLOW_SANDY_V4, .5f);
|
||||
TELY_Render_RectColourV4(renderer, world_hit_box, TELY_RenderShapeMode_Line, hot_colour);
|
||||
|
||||
@ -724,7 +718,7 @@ void FP_GameRender(TELY_Game *game, TELY_Platform *platform, TELY_Renderer *rend
|
||||
if (game->clicked_entity == entity->handle || game->hot_entity == entity->handle) {
|
||||
if (entity->name.size) {
|
||||
Dqn_V2I player_tile = Dqn_V2I_InitNx2(world_pos.x / FP_TILE_SIZE, world_pos.y / FP_TILE_SIZE);
|
||||
Dqn_V2 entity_world_pos = TELY_Game_CalcEntityWorldPos(game, entity->handle);
|
||||
Dqn_V2 entity_world_pos = FP_Game_CalcEntityWorldPos(game, entity->handle);
|
||||
Dqn_ThreadScratch scratch = Dqn_Thread_GetScratch(nullptr);
|
||||
Dqn_String8 label = Dqn_String8_InitF(scratch.allocator,
|
||||
"%.*s (%.1f, %.1f) (%I32d, %I32d)",
|
||||
@ -746,15 +740,10 @@ void TELY_DLL_FrameUpdate(void *user_data)
|
||||
TELY_PlatformInput *input = &platform->input;
|
||||
TELY_Assets *assets = &platform->assets;
|
||||
TELY_Renderer *renderer = &platform->renderer;
|
||||
Feely_Pona *pona = DQN_CAST(Feely_Pona *) platform->user_data;
|
||||
TELY_Game *game = &pona->game;
|
||||
TELY_UI *ui = &game->ui;
|
||||
|
||||
TELY_UI_FrameSetup(ui, assets, &platform->frame_arena);
|
||||
TELY_UI_PushFont(ui, pona->jetbrains_mono_font);
|
||||
FP_Game *game = DQN_CAST(FP_Game *) platform->user_data;
|
||||
|
||||
TELY_Render_ClearColourV3(renderer, TELY_COLOUR_BLACK_MIDNIGHT_V4.rgb);
|
||||
TELY_Render_PushFont(renderer, pona->jetbrains_mono_font);
|
||||
TELY_Render_PushFont(renderer, game->jetbrains_mono_font);
|
||||
{
|
||||
Dqn_ThreadScratch scratch = Dqn_Thread_GetScratch(nullptr);
|
||||
Dqn_String8Builder builder = {};
|
||||
@ -797,14 +786,14 @@ void TELY_DLL_FrameUpdate(void *user_data)
|
||||
Dqn_FArray_Clear(&game->parent_entity_stack);
|
||||
Dqn_FArray_Add(&game->parent_entity_stack, game->root_entity->handle);
|
||||
|
||||
Dqn_M2x3 model_view = TELY_Game_CameraModelViewM2x3(game->camera, platform);
|
||||
Dqn_M2x3 model_view = FP_Game_CameraModelViewM2x3(game->camera, platform);
|
||||
Dqn_V2 world_mouse_p = Dqn_M2x3_MulV2(model_view, input->mouse_p);
|
||||
|
||||
// =============================================================================================
|
||||
|
||||
TELY_Audio *audio = &platform->audio;
|
||||
if (audio->playback_size == 0) {
|
||||
TELY_Audio_Play(audio, pona->test_audio, 1.f /*volume*/);
|
||||
TELY_Audio_Play(audio, game->test_audio, 1.f /*volume*/);
|
||||
}
|
||||
|
||||
// =============================================================================================
|
||||
@ -813,15 +802,15 @@ void TELY_DLL_FrameUpdate(void *user_data)
|
||||
if (game->prev_active_entity.id)
|
||||
game->active_entity = game->prev_active_entity;
|
||||
} else {
|
||||
for (TELY_GameEntityIterator it = {}; TELY_Game_DFSPreOrderWalkEntityTree(game, &it, game->root_entity); ) {
|
||||
TELY_GameEntity *entity = it.entity;
|
||||
for (FP_GameEntityIterator it = {}; FP_Game_DFSPreOrderWalkEntityTree(game, &it, game->root_entity); ) {
|
||||
FP_GameEntity *entity = it.entity;
|
||||
if (entity->local_hit_box_size.x <= 0 || entity->local_hit_box_size.y <= 0)
|
||||
continue;
|
||||
|
||||
if ((entity->flags & TELY_EntityFlag_Clickable) == 0)
|
||||
if ((entity->flags & FP_EntityFlag_Clickable) == 0)
|
||||
continue;
|
||||
|
||||
Dqn_Rect world_hit_box = TELY_Game_CalcEntityWorldHitBox(game, entity->handle);
|
||||
Dqn_Rect world_hit_box = FP_Game_CalcEntityWorldHitBox(game, entity->handle);
|
||||
if (!Dqn_Rect_ContainsPoint(world_hit_box, world_mouse_p))
|
||||
continue;
|
||||
|
||||
|
143
feely_pona.h
143
feely_pona.h
@ -3,13 +3,140 @@
|
||||
#include "feely_pona_unity.h"
|
||||
#endif
|
||||
|
||||
struct Feely_Pona
|
||||
enum FP_EntityFlag
|
||||
{
|
||||
TELY_Game game;
|
||||
TELY_AssetFontHandle inter_regular_font;
|
||||
TELY_AssetFontHandle inter_italic_font;
|
||||
TELY_AssetFontHandle jetbrains_mono_font;
|
||||
Dqn_Slice<TELY_AssetSpriteAnimation> hero_sprite_anims;
|
||||
TELY_AssetSpriteSheet hero_sprite_sheet;
|
||||
TELY_AssetAudioHandle test_audio;
|
||||
FP_EntityFlag_Clickable = 1 << 0,
|
||||
FP_EntityFlag_MoveByKeyboard = 1 << 1,
|
||||
FP_EntityFlag_MoveByMouse = 1 << 2,
|
||||
FP_EntityFlag_DrawHitBox = 1 << 3,
|
||||
FP_EntityFlag_DeriveHitBoxFromChildrenBoundingBox = 1 << 4,
|
||||
};
|
||||
|
||||
enum FP_GameShapeType
|
||||
{
|
||||
FP_GameShapeType_None,
|
||||
FP_GameShapeType_Circle,
|
||||
FP_GameShapeType_Rect,
|
||||
FP_GameShapeType_Line,
|
||||
};
|
||||
|
||||
struct FP_GameShape
|
||||
{
|
||||
FP_GameShapeType type;
|
||||
Dqn_V2 p1;
|
||||
Dqn_V2 p2;
|
||||
Dqn_V4 colour;
|
||||
Dqn_f32 line_thickness;
|
||||
Dqn_f32 circle_radius;
|
||||
TELY_RenderShapeMode render_mode;
|
||||
};
|
||||
|
||||
const uint64_t FP_GAME_ENTITY_HANDLE_GENERATION_MASK = 0xFFFF'0000'0000'0000;
|
||||
const uint64_t FP_GAME_ENTITY_HANDLE_GENERATION_RSHIFT = 48;
|
||||
const uint64_t FP_GAME_ENTITY_HANDLE_GENERATION_MAX = FP_GAME_ENTITY_HANDLE_GENERATION_MASK >> FP_GAME_ENTITY_HANDLE_GENERATION_RSHIFT;
|
||||
|
||||
const uint64_t FP_GAME_ENTITY_HANDLE_INDEX_MASK = 0x0000'FFFF'FFFF'FFFF;
|
||||
const uint64_t FP_GAME_ENTITY_HANDLE_INDEX_MAX = FP_GAME_ENTITY_HANDLE_INDEX_MASK - 1;
|
||||
struct FP_GameEntityHandle
|
||||
{
|
||||
uint64_t id;
|
||||
};
|
||||
|
||||
enum FP_GameEntityState
|
||||
{
|
||||
FP_GameEntityState_Nil,
|
||||
FP_GameEntityState_Idle,
|
||||
FP_GameEntityState_Attack,
|
||||
FP_GameEntityState_Run,
|
||||
};
|
||||
|
||||
struct FP_GameEntityAnimation
|
||||
{
|
||||
uint16_t index;
|
||||
uint16_t frame;
|
||||
uint16_t ticks;
|
||||
uint16_t ticks_per_frame;
|
||||
};
|
||||
|
||||
struct FP_GameWaypoint
|
||||
{
|
||||
Dqn_V2I pos;
|
||||
FP_GameWaypoint *next;
|
||||
FP_GameWaypoint *prev;
|
||||
};
|
||||
|
||||
struct FP_GameEntity
|
||||
{
|
||||
Dqn_String8 name;
|
||||
FP_GameEntityHandle handle;
|
||||
TELY_AssetSpriteSheet *sprite_sheet;
|
||||
Dqn_Slice<TELY_AssetSpriteAnimation> sprite_anims;
|
||||
Dqn_V2 size_scale;
|
||||
FP_GameEntityAnimation anim;
|
||||
FP_GameEntityState state;
|
||||
Dqn_V2 velocity;
|
||||
|
||||
FP_GameEntityHandle stalk_entity;
|
||||
Dqn_V2I stalk_entity_last_known_tile;
|
||||
FP_GameWaypoint *waypoints;
|
||||
|
||||
// NOTE: The entity hit box is positioned at the center of the entity.
|
||||
Dqn_V2 local_hit_box_size;
|
||||
Dqn_V2 local_hit_box_offset;
|
||||
|
||||
Dqn_V2 attack_box_size;
|
||||
Dqn_V2 attack_box_offset;
|
||||
|
||||
uint64_t flags;
|
||||
bool facing_left;
|
||||
Dqn_V2 local_pos;
|
||||
Dqn_f64 alive_time_s;
|
||||
Dqn_FArray<FP_GameShape, 4> shapes;
|
||||
FP_GameEntity *next;
|
||||
FP_GameEntity *prev;
|
||||
FP_GameEntity *first_child;
|
||||
FP_GameEntity *last_child;
|
||||
FP_GameEntity *parent;
|
||||
};
|
||||
|
||||
struct FP_GameEntityIterator
|
||||
{
|
||||
bool init;
|
||||
Dqn_usize iteration_count;
|
||||
|
||||
FP_GameEntity *entity;
|
||||
FP_GameEntity *last_visited;
|
||||
|
||||
FP_GameEntity *entity_parent;
|
||||
FP_GameEntity *entity_next;
|
||||
FP_GameEntity *entity_first_child;
|
||||
};
|
||||
|
||||
struct FP_GameCamera
|
||||
{
|
||||
Dqn_V2 world_pos;
|
||||
Dqn_f32 rotate_rads;
|
||||
Dqn_V2 scale;
|
||||
};
|
||||
|
||||
struct FP_Game
|
||||
{
|
||||
TELY_ChunkPool chunk_pool;
|
||||
TELY_AssetFontHandle inter_regular_font;
|
||||
TELY_AssetFontHandle inter_italic_font;
|
||||
TELY_AssetFontHandle jetbrains_mono_font;
|
||||
TELY_AssetAudioHandle test_audio;
|
||||
Dqn_Slice<TELY_AssetSpriteAnimation> hero_sprite_anims;
|
||||
TELY_AssetSpriteSheet hero_sprite_sheet;
|
||||
Dqn_FArray<FP_GameEntityHandle, 8> parent_entity_stack;
|
||||
Dqn_VArray<FP_GameEntity> entities;
|
||||
FP_GameEntity *root_entity;
|
||||
FP_GameEntity *entity_free_list;
|
||||
FP_GameEntityHandle clicked_entity;
|
||||
FP_GameEntityHandle hot_entity;
|
||||
FP_GameEntityHandle active_entity;
|
||||
FP_GameEntityHandle prev_clicked_entity;
|
||||
FP_GameEntityHandle prev_hot_entity;
|
||||
FP_GameEntityHandle prev_active_entity;
|
||||
FP_GameCamera camera;
|
||||
};
|
||||
|
@ -3,19 +3,19 @@
|
||||
#include "playground_unity.h"
|
||||
#endif
|
||||
|
||||
static bool operator==(TELY_GameEntityHandle const &lhs, TELY_GameEntityHandle const &rhs)
|
||||
static bool operator==(FP_GameEntityHandle const &lhs, FP_GameEntityHandle const &rhs)
|
||||
{
|
||||
bool result = lhs.id == rhs.id;
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool operator!=(TELY_GameEntityHandle const &lhs, TELY_GameEntityHandle const &rhs)
|
||||
static bool operator!=(FP_GameEntityHandle const &lhs, FP_GameEntityHandle const &rhs)
|
||||
{
|
||||
bool result = !(lhs == rhs);
|
||||
return result;
|
||||
}
|
||||
|
||||
static Dqn_M2x3 TELY_Game_CameraModelViewM2x3(TELY_GameCamera camera, TELY_Platform *platform)
|
||||
static Dqn_M2x3 FP_Game_CameraModelViewM2x3(FP_GameCamera camera, TELY_Platform *platform)
|
||||
{
|
||||
Dqn_M2x3 result = Dqn_M2x3_Identity();
|
||||
if (platform) {
|
||||
@ -28,24 +28,24 @@ static Dqn_M2x3 TELY_Game_CameraModelViewM2x3(TELY_GameCamera camera, TELY_Platf
|
||||
return result;
|
||||
}
|
||||
|
||||
static TELY_GameEntity *TELY_Game_GetEntity(TELY_Game *game, TELY_GameEntityHandle handle)
|
||||
static FP_GameEntity *FP_Game_GetEntity(FP_Game *game, FP_GameEntityHandle handle)
|
||||
{
|
||||
TELY_GameEntity *result = nullptr;
|
||||
FP_GameEntity *result = nullptr;
|
||||
if (!game)
|
||||
return result;
|
||||
|
||||
result = game->entities.data;
|
||||
uint64_t index_from_handle = handle.id & TELY_GAME_ENTITY_HANDLE_INDEX_MASK;
|
||||
uint64_t index_from_handle = handle.id & FP_GAME_ENTITY_HANDLE_INDEX_MASK;
|
||||
if (index_from_handle >= game->entities.size)
|
||||
return result;
|
||||
|
||||
TELY_GameEntity *candidate = game->entities.data + index_from_handle;
|
||||
FP_GameEntity *candidate = game->entities.data + index_from_handle;
|
||||
if (candidate->handle == handle)
|
||||
result = candidate;
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool TELY_Game_DFSPreOrderWalkEntityTree(TELY_Game *game, TELY_GameEntityIterator *it, TELY_GameEntity *root)
|
||||
static bool FP_Game_DFSPreOrderWalkEntityTree(FP_Game *game, FP_GameEntityIterator *it, FP_GameEntity *root)
|
||||
{
|
||||
if (!game || !it || !root)
|
||||
return false;
|
||||
@ -88,7 +88,7 @@ static bool TELY_Game_DFSPreOrderWalkEntityTree(TELY_Game *game, TELY_GameEntity
|
||||
return it->entity->handle != root->handle;
|
||||
}
|
||||
|
||||
static bool TELY_Game_DFSPostOrderWalkEntityTree(TELY_Game *game, TELY_GameEntityIterator *it, TELY_GameEntity *root)
|
||||
static bool FP_Game_DFSPostOrderWalkEntityTree(FP_Game *game, FP_GameEntityIterator *it, FP_GameEntity *root)
|
||||
{
|
||||
if (!game || !it || !root)
|
||||
return false;
|
||||
@ -149,39 +149,39 @@ static bool TELY_Game_DFSPostOrderWalkEntityTree(TELY_Game *game, TELY_GameEntit
|
||||
|
||||
|
||||
// NOTE: Parent entity
|
||||
static void TELY_Game_PushParentEntity(TELY_Game *game, TELY_GameEntityHandle handle)
|
||||
static void FP_Game_PushParentEntity(FP_Game *game, FP_GameEntityHandle handle)
|
||||
{
|
||||
DQN_ASSERTF(game->parent_entity_stack.size >= 1, "Sentinel/nil entity has not been assigned as the 0th slot yet");
|
||||
if (game)
|
||||
Dqn_FArray_Add(&game->parent_entity_stack, handle);
|
||||
}
|
||||
|
||||
static void TELY_Game_PopParentEntity(TELY_Game *game)
|
||||
static void FP_Game_PopParentEntity(FP_Game *game)
|
||||
{
|
||||
// NOTE: 0th slot is reserved for the nil entity
|
||||
if (game && game->parent_entity_stack.size > 1)
|
||||
Dqn_FArray_PopBack(&game->parent_entity_stack, 1);
|
||||
}
|
||||
|
||||
static TELY_GameEntityHandle TELY_Game_ActiveParentEntity(TELY_Game const *game)
|
||||
static FP_GameEntityHandle FP_Game_ActiveParentEntity(FP_Game const *game)
|
||||
{
|
||||
TELY_GameEntityHandle result = {};
|
||||
FP_GameEntityHandle result = {};
|
||||
if (!game || !game->parent_entity_stack.size)
|
||||
return result;
|
||||
result = game->parent_entity_stack.data[game->parent_entity_stack.size - 1];
|
||||
return result;
|
||||
}
|
||||
|
||||
static TELY_GameEntity *TELY_Game_ActiveParentEntityPointer(TELY_Game const *game)
|
||||
static FP_GameEntity *FP_Game_ActiveParentEntityPointer(FP_Game const *game)
|
||||
{
|
||||
TELY_GameEntityHandle handle = TELY_Game_ActiveParentEntity(game);
|
||||
TELY_GameEntity *result = TELY_Game_GetEntity(DQN_CAST(TELY_Game *)game, handle);
|
||||
FP_GameEntityHandle handle = FP_Game_ActiveParentEntity(game);
|
||||
FP_GameEntity *result = FP_Game_GetEntity(DQN_CAST(FP_Game *)game, handle);
|
||||
return result;
|
||||
}
|
||||
|
||||
static TELY_GameEntity *TELY_Game_MakeEntityPointerFV(TELY_Game *game, DQN_FMT_STRING_ANNOTATE char const *fmt, va_list args)
|
||||
static FP_GameEntity *FP_Game_MakeEntityPointerFV(FP_Game *game, DQN_FMT_STRING_ANNOTATE char const *fmt, va_list args)
|
||||
{
|
||||
TELY_GameEntity *result = nullptr;
|
||||
FP_GameEntity *result = nullptr;
|
||||
if (!game)
|
||||
return result;
|
||||
|
||||
@ -194,24 +194,24 @@ static TELY_GameEntity *TELY_Game_MakeEntityPointerFV(TELY_Game *game, DQN_FMT_S
|
||||
game->entity_free_list = game->entity_free_list->next;
|
||||
result->next = nullptr;
|
||||
} else {
|
||||
if (game->entities.size >= (TELY_GAME_ENTITY_HANDLE_INDEX_MAX + 1))
|
||||
if (game->entities.size >= (FP_GAME_ENTITY_HANDLE_INDEX_MAX + 1))
|
||||
return result;
|
||||
|
||||
result = Dqn_VArray_Make(&game->entities, 1, Dqn_ZeroMem_Yes);
|
||||
if (!result)
|
||||
return result;
|
||||
result->handle.id = (game->entities.size - 1) & TELY_GAME_ENTITY_HANDLE_INDEX_MASK;
|
||||
result->handle.id = (game->entities.size - 1) & FP_GAME_ENTITY_HANDLE_INDEX_MASK;
|
||||
}
|
||||
|
||||
result->size_scale = Dqn_V2_InitNx1(1);
|
||||
result->parent = TELY_Game_ActiveParentEntityPointer(game);
|
||||
result->parent = FP_Game_ActiveParentEntityPointer(game);
|
||||
result->name = TELY_ChunkPool_AllocFmtFV(&game->chunk_pool, fmt, args);
|
||||
result->waypoints = TELY_ChunkPool_New(&game->chunk_pool, TELY_GameWaypoint);
|
||||
result->waypoints = TELY_ChunkPool_New(&game->chunk_pool, FP_GameWaypoint);
|
||||
result->waypoints->next = result->waypoints;
|
||||
result->waypoints->prev = result->waypoints;
|
||||
|
||||
// NOTE: Attach entity as a child to the parent
|
||||
TELY_GameEntity *parent = result->parent;
|
||||
FP_GameEntity *parent = result->parent;
|
||||
if (parent->first_child)
|
||||
parent->last_child->next = result;
|
||||
else
|
||||
@ -225,38 +225,38 @@ static TELY_GameEntity *TELY_Game_MakeEntityPointerFV(TELY_Game *game, DQN_FMT_S
|
||||
return result;
|
||||
}
|
||||
|
||||
static TELY_GameEntity *TELY_Game_MakeEntityPointerF(TELY_Game *game, DQN_FMT_STRING_ANNOTATE char const *fmt, ...)
|
||||
static FP_GameEntity *FP_Game_MakeEntityPointerF(FP_Game *game, DQN_FMT_STRING_ANNOTATE char const *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
TELY_GameEntity *result = TELY_Game_MakeEntityPointerFV(game, fmt, args);
|
||||
FP_GameEntity *result = FP_Game_MakeEntityPointerFV(game, fmt, args);
|
||||
va_end(args);
|
||||
return result;
|
||||
}
|
||||
|
||||
static TELY_GameEntityHandle TELY_Game_MakeEntityF(TELY_Game *game, DQN_FMT_STRING_ANNOTATE char const *fmt, ...)
|
||||
static FP_GameEntityHandle FP_Game_MakeEntityF(FP_Game *game, DQN_FMT_STRING_ANNOTATE char const *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
TELY_GameEntity *entity = TELY_Game_MakeEntityPointerF(game, fmt, args);
|
||||
FP_GameEntity *entity = FP_Game_MakeEntityPointerF(game, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
TELY_GameEntityHandle result = {};
|
||||
FP_GameEntityHandle result = {};
|
||||
if (entity)
|
||||
result = entity->handle;
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool TELY_Game_IsNilEntity(TELY_GameEntity *entity)
|
||||
static bool FP_Game_IsNilEntity(FP_GameEntity *entity)
|
||||
{
|
||||
bool result = entity ? ((entity->handle.id & TELY_GAME_ENTITY_HANDLE_INDEX_MASK) == 0) : true;
|
||||
bool result = entity ? ((entity->handle.id & FP_GAME_ENTITY_HANDLE_INDEX_MASK) == 0) : true;
|
||||
return result;
|
||||
}
|
||||
|
||||
static void TELY_Game_DetachEntityIntoFreeList(TELY_Game *game, TELY_GameEntityHandle handle)
|
||||
static void FP_Game_DetachEntityIntoFreeList(FP_Game *game, FP_GameEntityHandle handle)
|
||||
{
|
||||
TELY_GameEntity *entity = TELY_Game_GetEntity(game, handle);
|
||||
if (TELY_Game_IsNilEntity(entity))
|
||||
FP_GameEntity *entity = FP_Game_GetEntity(game, handle);
|
||||
if (FP_Game_IsNilEntity(entity))
|
||||
return;
|
||||
|
||||
// NOTE: Entities in the entity tree always have a parent (except for the
|
||||
@ -267,11 +267,11 @@ static void TELY_Game_DetachEntityIntoFreeList(TELY_Game *game, TELY_GameEntityH
|
||||
if (!DQN_CHECK(entity->parent))
|
||||
return;
|
||||
|
||||
uint64_t const entity_index_from_handle = entity->handle.id & TELY_GAME_ENTITY_HANDLE_INDEX_MASK;
|
||||
uint64_t const entity_index_from_handle = entity->handle.id & FP_GAME_ENTITY_HANDLE_INDEX_MASK;
|
||||
DQN_ASSERT(entity_index_from_handle < game->entities.size);
|
||||
|
||||
uint64_t const entity_generation_raw = entity->handle.id & TELY_GAME_ENTITY_HANDLE_GENERATION_MASK;
|
||||
uint64_t const entity_generation = entity_generation_raw >> TELY_GAME_ENTITY_HANDLE_GENERATION_RSHIFT;
|
||||
uint64_t const entity_generation_raw = entity->handle.id & FP_GAME_ENTITY_HANDLE_GENERATION_MASK;
|
||||
uint64_t const entity_generation = entity_generation_raw >> FP_GAME_ENTITY_HANDLE_GENERATION_RSHIFT;
|
||||
uint64_t const new_entity_generation = entity_generation + 1;
|
||||
|
||||
// NOTE: De-attach entity from adjacent children
|
||||
@ -282,7 +282,7 @@ static void TELY_Game_DetachEntityIntoFreeList(TELY_Game *game, TELY_GameEntityH
|
||||
entity->next->prev = entity->prev;
|
||||
|
||||
// NOTE: De-attach from parent
|
||||
TELY_GameEntity *parent = entity->parent;
|
||||
FP_GameEntity *parent = entity->parent;
|
||||
if (parent->first_child == entity)
|
||||
parent->first_child = entity->next;
|
||||
|
||||
@ -296,7 +296,7 @@ static void TELY_Game_DetachEntityIntoFreeList(TELY_Game *game, TELY_GameEntityH
|
||||
// NOTE: Update the incremented handle disassociating all prior handles
|
||||
// to this entity which would reference older generation values
|
||||
*entity = {};
|
||||
entity->handle.id = entity_index_from_handle | (new_entity_generation << TELY_GAME_ENTITY_HANDLE_GENERATION_RSHIFT);
|
||||
entity->handle.id = entity_index_from_handle | (new_entity_generation << FP_GAME_ENTITY_HANDLE_GENERATION_RSHIFT);
|
||||
|
||||
// NOTE: Attach entity to the free list
|
||||
entity->next = game->entity_free_list;
|
||||
@ -310,34 +310,34 @@ static void TELY_Game_DetachEntityIntoFreeList(TELY_Game *game, TELY_GameEntityH
|
||||
}
|
||||
}
|
||||
|
||||
static void TELY_Game_DeleteEntity(TELY_Game *game, TELY_GameEntityHandle handle)
|
||||
static void FP_Game_DeleteEntity(FP_Game *game, FP_GameEntityHandle handle)
|
||||
{
|
||||
uint64_t index_from_handle = handle.id & TELY_GAME_ENTITY_HANDLE_INDEX_MASK;
|
||||
uint64_t index_from_handle = handle.id & FP_GAME_ENTITY_HANDLE_INDEX_MASK;
|
||||
if (!game || !DQN_CHECK(index_from_handle < game->entities.size))
|
||||
return;
|
||||
|
||||
TELY_GameEntity *root = game->entities.data + index_from_handle;
|
||||
FP_GameEntity *root = game->entities.data + index_from_handle;
|
||||
if (root->handle != handle)
|
||||
return;
|
||||
|
||||
// NOTE: The iterator snaps a copy of all the internal n-ary tree pointers
|
||||
// so as we delete we do not accidentally invalidate any of the pointers.
|
||||
for (TELY_GameEntityIterator it = {}; TELY_Game_DFSPostOrderWalkEntityTree(game, &it, root); ) {
|
||||
for (FP_GameEntityIterator it = {}; FP_Game_DFSPostOrderWalkEntityTree(game, &it, root); ) {
|
||||
DQN_ASSERT(it.entity != root);
|
||||
TELY_GameEntity *entity = it.entity;
|
||||
TELY_Game_DetachEntityIntoFreeList(game, entity->handle);
|
||||
FP_GameEntity *entity = it.entity;
|
||||
FP_Game_DetachEntityIntoFreeList(game, entity->handle);
|
||||
}
|
||||
|
||||
TELY_Game_DetachEntityIntoFreeList(game, root->handle);
|
||||
FP_Game_DetachEntityIntoFreeList(game, root->handle);
|
||||
}
|
||||
|
||||
static Dqn_V2 TELY_Game_CalcEntityWorldPos(TELY_Game const *game, TELY_GameEntityHandle handle)
|
||||
static Dqn_V2 FP_Game_CalcEntityWorldPos(FP_Game const *game, FP_GameEntityHandle handle)
|
||||
{
|
||||
Dqn_V2 result = {};
|
||||
if (!game)
|
||||
return result;
|
||||
|
||||
for (TELY_GameEntity const *entity = TELY_Game_GetEntity(DQN_CAST(TELY_Game *) game, handle);
|
||||
for (FP_GameEntity const *entity = FP_Game_GetEntity(DQN_CAST(FP_Game *) game, handle);
|
||||
entity != game->root_entity;
|
||||
entity = entity->parent) {
|
||||
result += entity->local_pos;
|
||||
@ -345,68 +345,68 @@ static Dqn_V2 TELY_Game_CalcEntityWorldPos(TELY_Game const *game, TELY_GameEntit
|
||||
return result;
|
||||
}
|
||||
|
||||
static Dqn_Rect TELY_Game_CalcEntityLocalHitBox(TELY_Game const *game, TELY_GameEntityHandle handle)
|
||||
static Dqn_Rect FP_Game_CalcEntityLocalHitBox(FP_Game const *game, FP_GameEntityHandle handle)
|
||||
{
|
||||
TELY_GameEntity *entity = TELY_Game_GetEntity(DQN_CAST(TELY_Game *)game, handle);
|
||||
FP_GameEntity *entity = FP_Game_GetEntity(DQN_CAST(FP_Game *)game, handle);
|
||||
Dqn_V2 half_hit_box_size = entity->local_hit_box_size * .5f;
|
||||
Dqn_Rect result = Dqn_Rect_InitV2x2(entity->local_hit_box_offset - half_hit_box_size, entity->local_hit_box_size);
|
||||
return result;
|
||||
}
|
||||
|
||||
static Dqn_Rect TELY_Game_CalcEntityWorldHitBox(TELY_Game const *game, TELY_GameEntityHandle handle)
|
||||
static Dqn_Rect FP_Game_CalcEntityWorldHitBox(FP_Game const *game, FP_GameEntityHandle handle)
|
||||
{
|
||||
TELY_GameEntity *entity = TELY_Game_GetEntity(DQN_CAST(TELY_Game *) game, handle);
|
||||
Dqn_V2 world_pos = TELY_Game_CalcEntityWorldPos(game, handle);
|
||||
Dqn_Rect local_hit_box = TELY_Game_CalcEntityLocalHitBox(game, entity->handle);
|
||||
FP_GameEntity *entity = FP_Game_GetEntity(DQN_CAST(FP_Game *) game, handle);
|
||||
Dqn_V2 world_pos = FP_Game_CalcEntityWorldPos(game, handle);
|
||||
Dqn_Rect local_hit_box = FP_Game_CalcEntityLocalHitBox(game, entity->handle);
|
||||
Dqn_Rect result = Dqn_Rect_InitV2x2(world_pos + local_hit_box.pos, local_hit_box.size);
|
||||
return result;
|
||||
}
|
||||
|
||||
static Dqn_Rect TELY_Game_CalcEntityAttackWorldHitBox(TELY_Game const *game, TELY_GameEntityHandle handle)
|
||||
static Dqn_Rect FP_Game_CalcEntityAttackWorldHitBox(FP_Game const *game, FP_GameEntityHandle handle)
|
||||
{
|
||||
TELY_GameEntity *entity = TELY_Game_GetEntity(DQN_CAST(TELY_Game *) game, handle);
|
||||
Dqn_V2 world_pos = TELY_Game_CalcEntityWorldPos(game, handle);
|
||||
FP_GameEntity *entity = FP_Game_GetEntity(DQN_CAST(FP_Game *) game, handle);
|
||||
Dqn_V2 world_pos = FP_Game_CalcEntityWorldPos(game, handle);
|
||||
Dqn_V2 half_hit_box_size = entity->attack_box_size * .5f;
|
||||
Dqn_Rect result = Dqn_Rect_InitV2x2(world_pos + entity->attack_box_offset - half_hit_box_size, entity->attack_box_size);
|
||||
return result;
|
||||
}
|
||||
|
||||
static Dqn_Rect TELY_Game_CalcEntityArrayWorldBoundingBox(TELY_Game const *game, TELY_GameEntityHandle const *handles, Dqn_usize count)
|
||||
static Dqn_Rect FP_Game_CalcEntityArrayWorldBoundingBox(FP_Game const *game, FP_GameEntityHandle const *handles, Dqn_usize count)
|
||||
{
|
||||
Dqn_Rect result = {};
|
||||
if (!game || !handles)
|
||||
return result;
|
||||
|
||||
DQN_FOR_UINDEX(index, count) {
|
||||
TELY_GameEntityHandle handle = handles[index];
|
||||
TELY_GameEntity const *entity = TELY_Game_GetEntity(DQN_CAST(TELY_Game *) game, handle);
|
||||
Dqn_Rect bbox = TELY_Game_CalcEntityLocalHitBox(game, entity->handle);
|
||||
for (TELY_GameShape const &shape_ : entity->shapes) {
|
||||
TELY_GameShape const *shape = &shape_;
|
||||
FP_GameEntityHandle handle = handles[index];
|
||||
FP_GameEntity const *entity = FP_Game_GetEntity(DQN_CAST(FP_Game *) game, handle);
|
||||
Dqn_Rect bbox = FP_Game_CalcEntityLocalHitBox(game, entity->handle);
|
||||
for (FP_GameShape const &shape_ : entity->shapes) {
|
||||
FP_GameShape const *shape = &shape_;
|
||||
switch (shape->type) {
|
||||
case TELY_GameShapeType_None: {
|
||||
case FP_GameShapeType_None: {
|
||||
} break;
|
||||
|
||||
case TELY_GameShapeType_Circle: {
|
||||
case FP_GameShapeType_Circle: {
|
||||
Dqn_Rect rect =
|
||||
Dqn_Rect_InitV2x2(shape->p1 - shape->circle_radius, Dqn_V2_InitNx1(shape->circle_radius * 2.f));
|
||||
bbox = Dqn_Rect_Union(bbox, rect);
|
||||
} break;
|
||||
|
||||
case TELY_GameShapeType_Rect: /*FALLTHRU*/
|
||||
case TELY_GameShapeType_Line: {
|
||||
case FP_GameShapeType_Rect: /*FALLTHRU*/
|
||||
case FP_GameShapeType_Line: {
|
||||
Dqn_V2 min = Dqn_V2_Min(shape->p1, shape->p2);
|
||||
Dqn_V2 max = Dqn_V2_Max(shape->p1, shape->p2);
|
||||
Dqn_Rect rect = Dqn_Rect_InitV2x2(min, max - min);
|
||||
|
||||
if (shape->type == TELY_GameShapeType_Rect)
|
||||
if (shape->type == FP_GameShapeType_Rect)
|
||||
rect.pos -= rect.size * .5f;
|
||||
|
||||
bbox = Dqn_Rect_Union(bbox, rect);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
bbox.pos += TELY_Game_CalcEntityWorldPos(game, entity->handle);
|
||||
bbox.pos += FP_Game_CalcEntityWorldPos(game, entity->handle);
|
||||
|
||||
if (index)
|
||||
result = Dqn_Rect_Union(result, bbox);
|
||||
@ -416,8 +416,8 @@ static Dqn_Rect TELY_Game_CalcEntityArrayWorldBoundingBox(TELY_Game const *game,
|
||||
return result;
|
||||
}
|
||||
|
||||
static Dqn_Rect TELY_Game_CalcEntityWorldBoundingBox(TELY_Game *game, TELY_GameEntityHandle handle)
|
||||
static Dqn_Rect FP_Game_CalcEntityWorldBoundingBox(FP_Game *game, FP_GameEntityHandle handle)
|
||||
{
|
||||
Dqn_Rect result = TELY_Game_CalcEntityArrayWorldBoundingBox(game, &handle, 1);
|
||||
Dqn_Rect result = FP_Game_CalcEntityArrayWorldBoundingBox(game, &handle, 1);
|
||||
return result;
|
||||
}
|
||||
|
@ -1,171 +0,0 @@
|
||||
#if defined(__clang__)
|
||||
#pragma once
|
||||
#include "feely_pona_unity.h"
|
||||
#endif
|
||||
|
||||
enum TELY_EntityFlag
|
||||
{
|
||||
TELY_EntityFlag_Clickable = 1 << 0,
|
||||
TELY_EntityFlag_MoveByKeyboard = 1 << 1,
|
||||
TELY_EntityFlag_MoveByMouse = 1 << 2,
|
||||
TELY_EntityFlag_DrawHitBox = 1 << 3,
|
||||
TELY_EntityFlag_DeriveHitBoxFromChildrenBoundingBox = 1 << 4,
|
||||
};
|
||||
|
||||
enum TELY_GameShapeType
|
||||
{
|
||||
TELY_GameShapeType_None,
|
||||
TELY_GameShapeType_Circle,
|
||||
TELY_GameShapeType_Rect,
|
||||
TELY_GameShapeType_Line,
|
||||
};
|
||||
|
||||
struct TELY_GameShape
|
||||
{
|
||||
TELY_GameShapeType type;
|
||||
Dqn_V2 p1;
|
||||
Dqn_V2 p2;
|
||||
Dqn_V4 colour;
|
||||
Dqn_f32 line_thickness;
|
||||
Dqn_f32 circle_radius;
|
||||
TELY_RenderShapeMode render_mode;
|
||||
};
|
||||
|
||||
const uint64_t TELY_GAME_ENTITY_HANDLE_GENERATION_MASK = 0xFFFF'0000'0000'0000;
|
||||
const uint64_t TELY_GAME_ENTITY_HANDLE_GENERATION_RSHIFT = 48;
|
||||
const uint64_t TELY_GAME_ENTITY_HANDLE_GENERATION_MAX = TELY_GAME_ENTITY_HANDLE_GENERATION_MASK >> TELY_GAME_ENTITY_HANDLE_GENERATION_RSHIFT;
|
||||
|
||||
const uint64_t TELY_GAME_ENTITY_HANDLE_INDEX_MASK = 0x0000'FFFF'FFFF'FFFF;
|
||||
const uint64_t TELY_GAME_ENTITY_HANDLE_INDEX_MAX = TELY_GAME_ENTITY_HANDLE_INDEX_MASK - 1;
|
||||
struct TELY_GameEntityHandle
|
||||
{
|
||||
uint64_t id;
|
||||
};
|
||||
|
||||
enum TELY_GameEntityState
|
||||
{
|
||||
TELY_GameEntityState_Nil,
|
||||
TELY_GameEntityState_Idle,
|
||||
TELY_GameEntityState_Attack,
|
||||
TELY_GameEntityState_Run,
|
||||
};
|
||||
|
||||
struct TELY_GameEntityAnimation
|
||||
{
|
||||
uint16_t index;
|
||||
uint16_t frame;
|
||||
uint16_t ticks;
|
||||
uint16_t ticks_per_frame;
|
||||
};
|
||||
|
||||
struct TELY_GameWaypoint
|
||||
{
|
||||
Dqn_V2I pos;
|
||||
TELY_GameWaypoint *next;
|
||||
TELY_GameWaypoint *prev;
|
||||
};
|
||||
|
||||
struct TELY_GameEntity
|
||||
{
|
||||
Dqn_String8 name;
|
||||
TELY_GameEntityHandle handle;
|
||||
TELY_AssetSpriteSheet *sprite_sheet;
|
||||
Dqn_Slice<TELY_AssetSpriteAnimation> sprite_anims;
|
||||
Dqn_V2 size_scale;
|
||||
TELY_GameEntityAnimation anim;
|
||||
TELY_GameEntityState state;
|
||||
Dqn_V2 velocity;
|
||||
|
||||
TELY_GameEntityHandle stalk_entity;
|
||||
Dqn_V2I stalk_entity_last_known_tile;
|
||||
TELY_GameWaypoint *waypoints;
|
||||
|
||||
// NOTE: The entity hit box is positioned at the center of the entity.
|
||||
Dqn_V2 local_hit_box_size;
|
||||
Dqn_V2 local_hit_box_offset;
|
||||
|
||||
Dqn_V2 attack_box_size;
|
||||
Dqn_V2 attack_box_offset;
|
||||
|
||||
uint64_t flags;
|
||||
bool facing_left;
|
||||
Dqn_V2 local_pos;
|
||||
Dqn_f64 alive_time_s;
|
||||
Dqn_FArray<TELY_GameShape, 4> shapes;
|
||||
TELY_GameEntity *next;
|
||||
TELY_GameEntity *prev;
|
||||
TELY_GameEntity *first_child;
|
||||
TELY_GameEntity *last_child;
|
||||
TELY_GameEntity *parent;
|
||||
};
|
||||
|
||||
struct TELY_GameEntityIterator
|
||||
{
|
||||
bool init;
|
||||
Dqn_usize iteration_count;
|
||||
|
||||
TELY_GameEntity *entity;
|
||||
TELY_GameEntity *last_visited;
|
||||
|
||||
TELY_GameEntity *entity_parent;
|
||||
TELY_GameEntity *entity_next;
|
||||
TELY_GameEntity *entity_first_child;
|
||||
};
|
||||
|
||||
struct TELY_FreyaGameMath
|
||||
{
|
||||
TELY_GameEntityHandle lec01_group_box;
|
||||
TELY_GameEntityHandle lec01_axis;
|
||||
TELY_GameEntityHandle lec01_point_a;
|
||||
TELY_GameEntityHandle lec01_point_b;
|
||||
|
||||
TELY_GameEntityHandle lec01_task01_group_box;
|
||||
TELY_GameEntityHandle lec01_task01_radial_trigger;
|
||||
Dqn_f32 lec01_task01_radial_trigger_radius;
|
||||
TELY_GameEntityHandle lec01_task01_player;
|
||||
|
||||
TELY_GameEntityHandle lec01_task02_group_box;
|
||||
TELY_GameEntityHandle lec01_task02_ray_begin;
|
||||
TELY_GameEntityHandle lec01_task02_ray_end;
|
||||
TELY_GameEntityHandle lec01_task02_surface;
|
||||
};
|
||||
|
||||
struct TELY_GameCamera
|
||||
{
|
||||
Dqn_V2 world_pos;
|
||||
Dqn_f32 rotate_rads;
|
||||
Dqn_V2 scale;
|
||||
};
|
||||
|
||||
struct TELY_Game
|
||||
{
|
||||
TELY_Platform *platform;
|
||||
TELY_RFui rfui;
|
||||
TELY_UI ui;
|
||||
TELY_ChunkPool chunk_pool;
|
||||
TELY_AssetFontHandle inter_regular_font;
|
||||
TELY_AssetFontHandle inter_italic_font;
|
||||
TELY_AssetFontHandle jetbrains_mono_font;
|
||||
TELY_AssetAudioHandle test_audio;
|
||||
|
||||
Dqn_Slice<TELY_AssetSpriteAnimation> hero_sprite_anims;
|
||||
TELY_AssetSpriteSheet hero_sprite_sheet;
|
||||
|
||||
Dqn_FArray<TELY_GameEntityHandle, 8> parent_entity_stack;
|
||||
Dqn_VArray<TELY_GameEntity> entities;
|
||||
TELY_GameEntity *root_entity;
|
||||
TELY_GameEntity *entity_free_list;
|
||||
|
||||
TELY_GameEntityHandle clicked_entity;
|
||||
TELY_GameEntityHandle hot_entity;
|
||||
TELY_GameEntityHandle active_entity;
|
||||
|
||||
TELY_GameEntityHandle prev_clicked_entity;
|
||||
TELY_GameEntityHandle prev_hot_entity;
|
||||
TELY_GameEntityHandle prev_active_entity;
|
||||
|
||||
TELY_FreyaGameMath freya_game_math;
|
||||
|
||||
TELY_GameCamera camera;
|
||||
|
||||
};
|
@ -62,7 +62,6 @@ DQN_MSVC_WARNING_DISABLE(4505) // warning C4505: unreferenced function with inte
|
||||
|
||||
// NOTE: feely_pona ================================================================================
|
||||
|
||||
#include "feely_pona_game.h"
|
||||
#include "feely_pona.h"
|
||||
|
||||
#include "feely_pona_game.cpp"
|
||||
|
Loading…
Reference in New Issue
Block a user