diff --git a/External/tely b/External/tely index a1e15e3..77f354a 160000 --- a/External/tely +++ b/External/tely @@ -1 +1 @@ -Subproject commit a1e15e336b6d9eac5538392d2c473c7b740364d5 +Subproject commit 77f354ae49aa6421c7d86d6f2254c926fceef9bc diff --git a/feely_pona.cpp b/feely_pona.cpp index 55d981e..8a8820f 100644 --- a/feely_pona.cpp +++ b/feely_pona.cpp @@ -38,7 +38,7 @@ static void FP_EmitParticle(FP_Game *game, FP_ParticleDescriptor descriptor, Dqn } } -static TELY_AssetSpriteSheet FP_LoadSpriteSheetFromSpec(TELY_Platform *platform, TELY_Assets *assets, Dqn_Arena *arena, Dqn_Str8 sheet_name) +static TELY_AssetSpriteSheet FP_LoadSpriteSheetFromSpec(TELY_OS *os, TELY_Assets *assets, Dqn_Arena *arena, Dqn_Str8 sheet_name) { TELY_AssetSpriteSheet result = {}; Dqn_ThreadScratch scratch = Dqn_Thread_GetScratch(arena); @@ -47,7 +47,7 @@ static TELY_AssetSpriteSheet FP_LoadSpriteSheetFromSpec(TELY_Platform *platform, // NOTE: Load the sprite meta file ========================================================= Dqn_Str8 sprite_spec_path = Dqn_FsPath_ConvertF(scratch.arena, "%.*s/%.*s.txt", DQN_STR_FMT(assets->textures_dir), DQN_STR_FMT(sheet_name)); - Dqn_Str8 sprite_spec_buffer = platform->func_load_file(scratch.arena, sprite_spec_path); + Dqn_Str8 sprite_spec_buffer = os->funcs.load_file(scratch.arena, sprite_spec_path); Dqn_Str8SplitAllocResult lines = Dqn_Str8_SplitAlloc(scratch.allocator, sprite_spec_buffer, DQN_STR8("\n")); Dqn_usize sprite_rect_index = 0; Dqn_usize sprite_anim_index = 0; @@ -62,7 +62,7 @@ static TELY_AssetSpriteSheet FP_LoadSpriteSheetFromSpec(TELY_Platform *platform, // NOTE: Sprite sheet path Dqn_Str8 sprite_sheet_path = Dqn_FsPath_ConvertF(scratch.arena, "%.*s/%.*s", DQN_STR_FMT(assets->textures_dir), DQN_STR_FMT(line_splits.data[1])); - result.tex_handle = platform->func_load_texture(assets, sheet_name, sprite_sheet_path); + result.tex_handle = os->funcs.load_texture(assets, sheet_name, sprite_sheet_path); DQN_ASSERTF(Dqn_Fs_Exists(sprite_sheet_path), "Required file does not exist '%.*s'", DQN_STR_FMT(sprite_sheet_path)); // NOTE: Total sprite frame count @@ -127,18 +127,18 @@ static TELY_AssetSpriteSheet FP_LoadSpriteSheetFromSpec(TELY_Platform *platform, static void FP_SetDefaultGamepadBindings(FP_GameControls *controls) { // NOTE: Note up/down/left/right uses analog sticks, non-negotiable. - controls->attack.gamepad_key = TELY_PlatformInputGamepadKey_X; - controls->range_attack.gamepad_key = TELY_PlatformInputGamepadKey_Y; - controls->build_mode.gamepad_key = TELY_PlatformInputGamepadKey_L3; - controls->strafe.gamepad_key = TELY_PlatformInputGamepadKey_B; - controls->dash.gamepad_key = TELY_PlatformInputGamepadKey_A; - controls->buy_building.gamepad_key = TELY_PlatformInputGamepadKey_LeftBumper; - controls->buy_upgrade.gamepad_key = TELY_PlatformInputGamepadKey_RightBumper; - controls->move_building_ui_cursor_left.gamepad_key = TELY_PlatformInputGamepadKey_DLeft; - controls->move_building_ui_cursor_right.gamepad_key = TELY_PlatformInputGamepadKey_DRight; + controls->attack.gamepad_key = TELY_OSInputGamepadKey_X; + controls->range_attack.gamepad_key = TELY_OSInputGamepadKey_Y; + controls->build_mode.gamepad_key = TELY_OSInputGamepadKey_L3; + controls->strafe.gamepad_key = TELY_OSInputGamepadKey_B; + controls->dash.gamepad_key = TELY_OSInputGamepadKey_A; + controls->buy_building.gamepad_key = TELY_OSInputGamepadKey_LeftBumper; + controls->buy_upgrade.gamepad_key = TELY_OSInputGamepadKey_RightBumper; + controls->move_building_ui_cursor_left.gamepad_key = TELY_OSInputGamepadKey_DLeft; + controls->move_building_ui_cursor_right.gamepad_key = TELY_OSInputGamepadKey_DRight; } -static bool FP_ListenForNewPlayer(TELY_PlatformInput *input, FP_Game *game) +static bool FP_ListenForNewPlayer(TELY_OSInput *input, FP_Game *game) { bool result = false; if (game->play.players.size == 2) @@ -159,8 +159,8 @@ static bool FP_ListenForNewPlayer(TELY_PlatformInput *input, FP_Game *game) } } - bool keyboard_pressed = !keyboard_already_allocated && TELY_Platform_InputScanCodeIsPressed(input, TELY_PlatformInputScanCode_B); - bool gamepad_pressed = TELY_Platform_InputGamepadKeyIsPressed(input, gamepad_index, TELY_PlatformInputGamepadKey_Start); + bool keyboard_pressed = !keyboard_already_allocated && TELY_OSInput_ScanKeyIsPressed(input, TELY_OSInputScanKey_B); + bool gamepad_pressed = TELY_OSInput_GamepadKeyIsPressed(input, gamepad_index, TELY_OSInputGamepadKey_Start); if (keyboard_pressed || gamepad_pressed) { FP_GameEntityHandle terry_handle = {}; @@ -178,19 +178,19 @@ static bool FP_ListenForNewPlayer(TELY_PlatformInput *input, FP_Game *game) FP_GameControls *controls = &terry->controls; if (keyboard_pressed) { controls->mode = FP_GameControlMode_Keyboard; - controls->up.scan_code = TELY_PlatformInputScanCode_W; - controls->down.scan_code = TELY_PlatformInputScanCode_S; - controls->left.scan_code = TELY_PlatformInputScanCode_A; - controls->right.scan_code = TELY_PlatformInputScanCode_D; - controls->attack.scan_code = TELY_PlatformInputScanCode_J; - controls->range_attack.scan_code = TELY_PlatformInputScanCode_K; - controls->build_mode.scan_code = TELY_PlatformInputScanCode_H; - controls->strafe.scan_code = TELY_PlatformInputScanCode_L; - controls->dash.scan_code = TELY_PlatformInputScanCode_N; - controls->buy_building.scan_code = TELY_PlatformInputScanCode_U; - controls->buy_upgrade.scan_code = TELY_PlatformInputScanCode_I; - controls->move_building_ui_cursor_left.scan_code = TELY_PlatformInputScanCode_Q; - controls->move_building_ui_cursor_right.scan_code = TELY_PlatformInputScanCode_E; + controls->up.scan_key = TELY_OSInputScanKey_W; + controls->down.scan_key = TELY_OSInputScanKey_S; + controls->left.scan_key = TELY_OSInputScanKey_A; + controls->right.scan_key = TELY_OSInputScanKey_D; + controls->attack.scan_key = TELY_OSInputScanKey_J; + controls->range_attack.scan_key = TELY_OSInputScanKey_K; + controls->build_mode.scan_key = TELY_OSInputScanKey_H; + controls->strafe.scan_key = TELY_OSInputScanKey_L; + controls->dash.scan_key = TELY_OSInputScanKey_N; + controls->buy_building.scan_key = TELY_OSInputScanKey_U; + controls->buy_upgrade.scan_key = TELY_OSInputScanKey_I; + controls->move_building_ui_cursor_left.scan_key = TELY_OSInputScanKey_Q; + controls->move_building_ui_cursor_right.scan_key = TELY_OSInputScanKey_E; } else { controls->mode = FP_GameControlMode_Gamepad; controls->gamepad_index = gamepad_index; @@ -202,7 +202,7 @@ static bool FP_ListenForNewPlayer(TELY_PlatformInput *input, FP_Game *game) return result; } -static void FP_PlayReset(FP_Game *game, TELY_Platform *platform) +static void FP_PlayReset(FP_Game *game, TELY_OS *os) { FP_GamePlay *play = &game->play; if (game->play.root_entity) @@ -211,7 +211,7 @@ static void FP_PlayReset(FP_Game *game, TELY_Platform *platform) Dqn_VArray shallow_entities_copy = play->entities; DQN_MEMSET(play, 0, sizeof(*play)); - play->chunk_pool = &platform->chunk_pool; + play->chunk_pool = &os->chunk_pool; play->meters_to_pixels = 65.416f; play->entities = shallow_entities_copy; @@ -223,7 +223,7 @@ static void FP_PlayReset(FP_Game *game, TELY_Platform *platform) play->root_entity = Dqn_VArray_Make(&play->entities, Dqn_ZeroMem_No); Dqn_FArray_Add(&play->parent_entity_stack, play->root_entity->handle); - Dqn_PCG32_Seed(&play->rng, platform->core.epoch_time); + Dqn_PCG32_Seed(&play->rng, os->core.epoch_time); // NOTE: Map =================================================================================== { @@ -393,61 +393,54 @@ static void FP_PlayReset(FP_Game *game, TELY_Platform *platform) play->camera.size = FP_TARGET_VIEWPORT_SIZE; } -#if defined(DQN_OS_WIN32) - #define FP_DLL_FUNCTION extern "C" __declspec(dllexport) -#else - #define FP_DLL_FUNCTION -#endif - -FP_DLL_FUNCTION -void TELY_DLL_Reload(void *user_data) +TELY_OS_DLL_FUNCTION +void TELY_OS_DLLReload(TELY_OS *os) { - TELY_Platform *platform = DQN_CAST(TELY_Platform *)user_data; - Dqn_Library_SetPointer(platform->core.dqn_lib); - platform->func_set_window_title(DQN_STR8("Terry Cherry")); + Dqn_Library_SetPointer(os->core.dqn_lib); + os->funcs.set_window_title(DQN_STR8("Terry Cherry")); } -FP_DLL_FUNCTION -void TELY_DLL_Init(void *user_data) +TELY_OS_DLL_FUNCTION +void TELY_OS_DLLInit(TELY_OS *os) { - TELY_Platform *platform = DQN_CAST(TELY_Platform *)user_data; - TELY_DLL_Reload(user_data); - - FP_UnitTests(platform); + TELY_OS_DLLReload(os); + FP_UnitTests(os); // NOTE: TELY Game ============================================================================= - TELY_Assets *assets = &platform->assets; - FP_Game *game = Dqn_Arena_New(&platform->arena, FP_Game, Dqn_ZeroMem_Yes); + TELY_Assets *assets = &os->assets; + FP_Game *game = Dqn_Arena_New(&os->arena, FP_Game, Dqn_ZeroMem_Yes); - Dqn_f32 font_scalar = FP_TARGET_VIEWPORT_SIZE.w / DQN_CAST(Dqn_f32)platform->core.window_size.x; - uint16_t font_size = DQN_CAST(uint16_t)(18 * font_scalar); - game->inter_regular_font_large = platform->func_load_font(assets, DQN_STR8("Inter (Regular)"), DQN_STR8("Data/Fonts/Inter-Regular.otf"), DQN_CAST(uint16_t)(font_size * 5.f)); - game->inter_regular_font = platform->func_load_font(assets, DQN_STR8("Inter (Regular)"), DQN_STR8("Data/Fonts/Inter-Regular.otf"), DQN_CAST(uint16_t)(font_size)); - game->inter_italic_font = platform->func_load_font(assets, DQN_STR8("Inter (Italic)"), DQN_STR8("Data/Fonts/Inter-Italic.otf"), font_size); - game->jetbrains_mono_font = platform->func_load_font(assets, DQN_STR8("JetBrains Mono NL (Regular)"), DQN_STR8("Data/Fonts/JetBrainsMonoNL-Regular.ttf"), font_size); - game->talkco_font = platform->func_load_font(assets, DQN_STR8("Talkco"), DQN_STR8("Data/Fonts/Talkco.otf"), font_size); - game->talkco_font_large = platform->func_load_font(assets, DQN_STR8("Talkco"), DQN_STR8("Data/Fonts/Talkco.otf"), DQN_CAST(uint16_t)(font_size * 1.5f)); - game->talkco_font_xlarge = platform->func_load_font(assets, DQN_STR8("Talkco"), DQN_STR8("Data/Fonts/Talkco.otf"), DQN_CAST(uint16_t)(font_size * 2.f)); - game->audio[FP_GameAudio_TerryHit] = platform->func_load_audio(assets, DQN_STR8("Terry Hit"), DQN_STR8("Data/Audio/terry_hit.ogg")); - game->audio[FP_GameAudio_Ching] = platform->func_load_audio(assets, DQN_STR8("Ching"), DQN_STR8("Data/Audio/ching.ogg")); - game->audio[FP_GameAudio_Church] = platform->func_load_audio(assets, DQN_STR8("Church"), DQN_STR8("Data/Audio/church.ogg")); - game->audio[FP_GameAudio_Club] = platform->func_load_audio(assets, DQN_STR8("Club"), DQN_STR8("Data/Audio/club_terry.ogg")); - game->audio[FP_GameAudio_Dog] = platform->func_load_audio(assets, DQN_STR8("Dog"), DQN_STR8("Data/Audio/dog.ogg")); - game->audio[FP_GameAudio_MerchantGhost] = platform->func_load_audio(assets, DQN_STR8("Ghost"), DQN_STR8("Data/Audio/merchant_ghost.ogg")); - game->audio[FP_GameAudio_MerchantGym] = platform->func_load_audio(assets, DQN_STR8("Gym"), DQN_STR8("Data/Audio/merchant_gym.ogg")); - game->audio[FP_GameAudio_MerchantPhone] = platform->func_load_audio(assets, DQN_STR8("Phone"), DQN_STR8("Data/Audio/merchant_tech.ogg")); - game->audio[FP_GameAudio_MerchantTerry] = platform->func_load_audio(assets, DQN_STR8("Door"), DQN_STR8("Data/Audio/merchant_terry.ogg")); - game->audio[FP_GameAudio_Message] = platform->func_load_audio(assets, DQN_STR8("Message"), DQN_STR8("Data/Audio/message.ogg")); - game->audio[FP_GameAudio_Monkey] = platform->func_load_audio(assets, DQN_STR8("Monkey"), DQN_STR8("Data/Audio/monkey.ogg")); - game->audio[FP_GameAudio_Plane] = platform->func_load_audio(assets, DQN_STR8("Plane"), DQN_STR8("Data/Audio/airport.ogg")); - game->audio[FP_GameAudio_PortalDestroy] = platform->func_load_audio(assets, DQN_STR8("Portal Destroy"), DQN_STR8("Data/Audio/portal_destroy.ogg")); - game->audio[FP_GameAudio_Smooch] = platform->func_load_audio(assets, DQN_STR8("Smooch"), DQN_STR8("Data/Audio/smooch.ogg")); - game->audio[FP_GameAudio_Woosh] = platform->func_load_audio(assets, DQN_STR8("Woosh"), DQN_STR8("Data/Audio/woosh.ogg")); + Dqn_f32 font_scalar = FP_TARGET_VIEWPORT_SIZE.w / DQN_CAST(Dqn_f32)os->core.window_size.x; + game->font_size = DQN_CAST(uint16_t)(18 * font_scalar); + game->large_font_size = DQN_CAST(uint16_t)(game->font_size * .5f); + game->large_talkco_font_size = DQN_CAST(uint16_t)(game->font_size * 1.5f); + game->xlarge_talkco_font_size = DQN_CAST(uint16_t)(game->font_size * 2.f); + + game->inter_regular_font = TELY_Asset_LoadFont(assets, DQN_STR8("Inter (Regular)"), DQN_STR8("Data/Fonts/Inter-Regular.otf")); + game->inter_italic_font = TELY_Asset_LoadFont(assets, DQN_STR8("Inter (Italic)"), DQN_STR8("Data/Fonts/Inter-Italic.otf")); + game->jetbrains_mono_font = TELY_Asset_LoadFont(assets, DQN_STR8("JetBrains Mono NL (Regular)"), DQN_STR8("Data/Fonts/JetBrainsMonoNL-Regular.ttf")); + game->talkco_font = TELY_Asset_LoadFont(assets, DQN_STR8("Talkco"), DQN_STR8("Data/Fonts/Talkco.otf")); + + game->audio[FP_GameAudio_TerryHit] = os->funcs.load_audio(assets, DQN_STR8("Terry Hit"), DQN_STR8("Data/Audio/terry_hit.ogg")); + game->audio[FP_GameAudio_Ching] = os->funcs.load_audio(assets, DQN_STR8("Ching"), DQN_STR8("Data/Audio/ching.ogg")); + game->audio[FP_GameAudio_Church] = os->funcs.load_audio(assets, DQN_STR8("Church"), DQN_STR8("Data/Audio/church.ogg")); + game->audio[FP_GameAudio_Club] = os->funcs.load_audio(assets, DQN_STR8("Club"), DQN_STR8("Data/Audio/club_terry.ogg")); + game->audio[FP_GameAudio_Dog] = os->funcs.load_audio(assets, DQN_STR8("Dog"), DQN_STR8("Data/Audio/dog.ogg")); + game->audio[FP_GameAudio_MerchantGhost] = os->funcs.load_audio(assets, DQN_STR8("Ghost"), DQN_STR8("Data/Audio/merchant_ghost.ogg")); + game->audio[FP_GameAudio_MerchantGym] = os->funcs.load_audio(assets, DQN_STR8("Gym"), DQN_STR8("Data/Audio/merchant_gym.ogg")); + game->audio[FP_GameAudio_MerchantPhone] = os->funcs.load_audio(assets, DQN_STR8("Phone"), DQN_STR8("Data/Audio/merchant_tech.ogg")); + game->audio[FP_GameAudio_MerchantTerry] = os->funcs.load_audio(assets, DQN_STR8("Door"), DQN_STR8("Data/Audio/merchant_terry.ogg")); + game->audio[FP_GameAudio_Message] = os->funcs.load_audio(assets, DQN_STR8("Message"), DQN_STR8("Data/Audio/message.ogg")); + game->audio[FP_GameAudio_Monkey] = os->funcs.load_audio(assets, DQN_STR8("Monkey"), DQN_STR8("Data/Audio/monkey.ogg")); + game->audio[FP_GameAudio_Plane] = os->funcs.load_audio(assets, DQN_STR8("Plane"), DQN_STR8("Data/Audio/airport.ogg")); + game->audio[FP_GameAudio_PortalDestroy] = os->funcs.load_audio(assets, DQN_STR8("Portal Destroy"), DQN_STR8("Data/Audio/portal_destroy.ogg")); + game->audio[FP_GameAudio_Smooch] = os->funcs.load_audio(assets, DQN_STR8("Smooch"), DQN_STR8("Data/Audio/smooch.ogg")); + game->audio[FP_GameAudio_Woosh] = os->funcs.load_audio(assets, DQN_STR8("Woosh"), DQN_STR8("Data/Audio/woosh.ogg")); // NOTE: Load sprite sheets ==================================================================== - platform->user_data = game; - game->atlas_sprite_sheet = FP_LoadSpriteSheetFromSpec(platform, assets, &platform->arena, DQN_STR8("atlas")); - FP_PlayReset(game, platform); + os->user_data = game; + game->atlas_sprite_sheet = FP_LoadSpriteSheetFromSpec(os, assets, &os->arena, DQN_STR8("atlas")); + FP_PlayReset(game, os); } @@ -508,7 +501,7 @@ static void FP_AppendMobSpawnerWaypoints(FP_Game *game, FP_GameEntityHandle src_ } } -static void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_PlatformInput *input, FP_GameEntity *entity, Dqn_V2 *acceleration_meters_per_s) +static void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_OSInput *input, FP_GameEntity *entity, Dqn_V2 *acceleration_meters_per_s) { TELY_AssetSpriteSheet *sheet = &game->atlas_sprite_sheet; FP_GameEntityAction *action = &entity->action; @@ -1301,25 +1294,25 @@ static void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_P } } -static void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_PlatformInput *input, TELY_Audio *audio) +static void FP_Update(TELY_OS *os, FP_Game *game, TELY_OSInput *input, TELY_Audio *audio) { Dqn_Profiler_ZoneScopeWithIndex("FP_Update", FP_ProfileZone_FPUpdate); game->play.update_counter++; Dqn_ProfilerZone update_zone = Dqn_Profiler_BeginZoneWithIndex(DQN_STR8("FP_Update: Entity loop"), FP_ProfileZone_FPUpdate_EntityLoop); if (game->play.state == FP_GameState_Play && game->play.perry_joined != FP_GamePerryJoins_Enters) { - game->play.clock_ms = DQN_CAST(uint64_t)(platform->input.timer_s * 1000.f); + game->play.clock_ms = DQN_CAST(uint64_t)(os->input.timer_s * 1000.f); DQN_MSVC_WARNING_PUSH DQN_MSVC_WARNING_DISABLE(4127) // Conditional expression is constant 'FP_DEVELOPER_MODE' - if (FP_DEVELOPER_MODE && TELY_Platform_InputKeyIsReleased(input->mouse_left)) + if (FP_DEVELOPER_MODE && TELY_OSInput_KeyIsReleased(input->mouse_left)) game->play.clicked_entity = game->play.prev_active_entity; - if (TELY_Platform_InputScanCodeIsPressed(input, TELY_PlatformInputScanCode_Escape)) + if (TELY_OSInput_ScanKeyIsPressed(input, TELY_OSInputScanKey_Escape)) game->play.state = FP_GameState_Pause; if (FP_DEVELOPER_MODE && game->play.clicked_entity.id) { - if (TELY_Platform_InputScanCodeIsPressed(input, TELY_PlatformInputScanCode_Delete)) + if (TELY_OSInput_ScanKeyIsPressed(input, TELY_OSInputScanKey_Delete)) FP_Game_DeleteEntity(game, game->play.clicked_entity); } DQN_MSVC_WARNING_POP @@ -1347,8 +1340,8 @@ static void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_PlatformInput // NOTE: Gamepad movement input if (controls->mode == FP_GameControlMode_Gamepad) { - dir_vector.x += input->left_stick[controls->gamepad_index].x; - dir_vector.y += input->left_stick[controls->gamepad_index].y; + TELY_OSInputGamepad *gamepad = input->gamepads + controls->gamepad_index; + dir_vector += gamepad->left_stick; } // TODO(doyle): Some bug, diagonal is still faster @@ -1945,7 +1938,7 @@ static void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_PlatformInput // NOTE: Tick the state machine // NOTE: This can delete the entity! Take caution FP_GameEntityHandle entity_handle = entity->handle; - FP_EntityActionStateMachine(game, &platform->audio, input, entity, &acceleration_meters_per_s); + FP_EntityActionStateMachine(game, &os->audio, input, entity, &acceleration_meters_per_s); // NOTE: Limit the entity to within bounds of the camera only in multiplayer =========== bool entity_is_oob_with_camera = false; @@ -2304,7 +2297,7 @@ static void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_PlatformInput // NOTE: Clamp camera to map bounds ============================================================ { - Dqn_V2 window_size = Dqn_V2_InitV2I(platform->core.window_size); + Dqn_V2 window_size = Dqn_V2_InitV2I(os->core.window_size); camera->scale = window_size / camera->size; Dqn_V2 camera_size_screen = camera->size * camera->scale; @@ -2323,27 +2316,27 @@ static void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_PlatformInput Dqn_Profiler_EndZone(update_zone); } -static Dqn_Str8 FP_ScanCodeToLabel(Dqn_Arena *arena, TELY_PlatformInputScanCode scan_code) +static Dqn_Str8 FP_ScanKeyToLabel(Dqn_Arena *arena, TELY_OSInputScanKey scan_key) { Dqn_Str8 result = {}; Dqn_Allocator allocator = Dqn_Arena_Allocator(arena); - if (scan_code >= TELY_PlatformInputScanCode_A && scan_code <= TELY_PlatformInputScanCode_Z) { - char scan_code_ch = DQN_CAST(char)('A' + (scan_code - TELY_PlatformInputScanCode_A)); - result = Dqn_Str8_InitF(allocator, "[%c]", scan_code_ch); + if (scan_key >= TELY_OSInputScanKey_A && scan_key <= TELY_OSInputScanKey_Z) { + char scan_key_ch = DQN_CAST(char)('A' + (scan_key - TELY_OSInputScanKey_A)); + result = Dqn_Str8_InitF(allocator, "[%c]", scan_key_ch); } else { - if (scan_code == TELY_PlatformInputScanCode_Up) { + if (scan_key == TELY_OSInputScanKey_Up) { result = Dqn_Str8_InitF(allocator, "[Up]"); - } else if (scan_code == TELY_PlatformInputScanCode_Down) { + } else if (scan_key == TELY_OSInputScanKey_Down) { result = Dqn_Str8_InitF(allocator, "[Down]"); - } else if (scan_code == TELY_PlatformInputScanCode_Left) { + } else if (scan_key == TELY_OSInputScanKey_Left) { result = Dqn_Str8_InitF(allocator, "[Left]"); - } else if (scan_code == TELY_PlatformInputScanCode_Right) { + } else if (scan_key == TELY_OSInputScanKey_Right) { result = Dqn_Str8_InitF(allocator, "[Right]"); - } else if (scan_code == TELY_PlatformInputScanCode_Semicolon) { + } else if (scan_key == TELY_OSInputScanKey_Semicolon) { result = Dqn_Str8_InitF(allocator, "[;]"); - } else if (scan_code == TELY_PlatformInputScanCode_Apostrophe) { + } else if (scan_key == TELY_OSInputScanKey_Apostrophe) { result = Dqn_Str8_InitF(allocator, "[']"); - } else if (scan_code == TELY_PlatformInputScanCode_Backslash) { + } else if (scan_key == TELY_OSInputScanKey_Backslash) { result = Dqn_Str8_InitF(allocator, "[/]"); } } @@ -2366,20 +2359,20 @@ static void FP_DrawBillboardKeyBindHint(TELY_Renderer *renderer, if (mode == FP_GameControlMode_Gamepad) { Dqn_Str8 tex_name = {}; - if (key_bind.gamepad_key == TELY_PlatformInputGamepadKey_A) + if (key_bind.gamepad_key == TELY_OSInputGamepadKey_A) tex_name = g_anim_names.merchant_button_a; - else if (key_bind.gamepad_key == TELY_PlatformInputGamepadKey_B) + else if (key_bind.gamepad_key == TELY_OSInputGamepadKey_B) tex_name = g_anim_names.merchant_button_b; - else if (key_bind.gamepad_key == TELY_PlatformInputGamepadKey_X) + else if (key_bind.gamepad_key == TELY_OSInputGamepadKey_X) tex_name = g_anim_names.merchant_button_x; - else if (key_bind.gamepad_key == TELY_PlatformInputGamepadKey_Y) + else if (key_bind.gamepad_key == TELY_OSInputGamepadKey_Y) tex_name = g_anim_names.merchant_button_y; if (tex_name.size) { TELY_AssetSpriteAnimation *anim = TELY_Asset_GetSpriteAnimation(&game->atlas_sprite_sheet, tex_name); Dqn_Rect button_rect = game->atlas_sprite_sheet.rects.data[anim->index]; - Dqn_V2 text_size = TELY_Asset_MeasureText(TELY_Render_Font(renderer, assets), player_prefix); + Dqn_V2 text_size = TELY_Asset_MeasureText(assets, TELY_Render_ActiveFont(renderer), player_prefix); TELY_Render_Text(renderer, draw_p, Dqn_V2_InitNx2(0, +1.f), player_prefix); Dqn_Rect gamepad_btn_rect = {}; @@ -2395,22 +2388,22 @@ static void FP_DrawBillboardKeyBindHint(TELY_Renderer *renderer, TELY_COLOUR_WHITE_V4); } } else { - Dqn_Str8 key_bind_label = FP_ScanCodeToLabel(scratch.arena, key_bind.scan_code); + Dqn_Str8 key_bind_label = FP_ScanKeyToLabel(scratch.arena, key_bind.scan_key); TELY_Render_TextF(renderer, draw_p, Dqn_V2_InitNx2(0, +1.f), "%.*s%.*s", DQN_STR_FMT(player_prefix), DQN_STR_FMT(key_bind_label)); } } -static void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *renderer, TELY_Audio *audio) +static void FP_Render(FP_Game *game, TELY_OS *os, TELY_Renderer *renderer, TELY_Audio *audio) { Dqn_Profiler_ZoneScopeWithIndex("FP_Render", FP_ProfileZone_FPRender); - TELY_PlatformInput *input = &platform->input; + TELY_OSInput *input = &os->input; TELY_RFui *rfui = &game->rfui; - TELY_Assets *assets = &platform->assets; + TELY_Assets *assets = &os->assets; TELY_Render_ClearColourV3(renderer, TELY_COLOUR_BLACK_MIDNIGHT_V4.rgb); - TELY_Render_PushFont(renderer, game->jetbrains_mono_font); - TELY_RFui_FrameSetup(rfui, &platform->frame_arena); - TELY_RFui_PushFont(rfui, game->jetbrains_mono_font); + TELY_Render_PushFontSize(renderer, game->jetbrains_mono_font, game->font_size); + TELY_RFui_FrameSetup(rfui, &os->frame_arena); + TELY_RFui_PushFontSize(rfui, game->jetbrains_mono_font, game->font_size); FP_GameCamera shake_camera = game->play.camera; { @@ -2441,18 +2434,18 @@ static void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *ren Dqn_V2 world_mouse_p = Dqn_M2x3_MulV2(camera_xforms.view_model, input->mouse_p); // NOTE: Draw tiles ============================================================================ - Dqn_usize tile_count_x = DQN_CAST(Dqn_usize)(platform->core.window_size.w / game->play.tile_size); - Dqn_usize tile_count_y = DQN_CAST(Dqn_usize)(platform->core.window_size.h / game->play.tile_size); + Dqn_usize tile_count_x = DQN_CAST(Dqn_usize)(os->core.window_size.w / game->play.tile_size); + Dqn_usize tile_count_y = DQN_CAST(Dqn_usize)(os->core.window_size.h / game->play.tile_size); for (Dqn_usize x = 0; x < tile_count_x; x++) { Dqn_V2 start = Dqn_V2_InitNx2((x + 1) * game->play.tile_size, 0); - Dqn_V2 end = Dqn_V2_InitNx2(start.x, platform->core.window_size.h); + Dqn_V2 end = Dqn_V2_InitNx2(start.x, os->core.window_size.h); TELY_Render_LineColourV4(renderer, start, end, TELY_Colour_V4Alpha(TELY_COLOUR_WHITE_V4, .25f), 1.f); } for (Dqn_usize y = 0; y < tile_count_y; y++) { Dqn_V2 start = Dqn_V2_InitNx2(0, (y + 1) * game->play.tile_size); - Dqn_V2 end = Dqn_V2_InitNx2(platform->core.window_size.w, start.y); + Dqn_V2 end = Dqn_V2_InitNx2(os->core.window_size.w, start.y); TELY_Render_LineColourV4(renderer, start, end, TELY_Colour_V4Alpha(TELY_COLOUR_WHITE_V4, .25f), 1.f); } @@ -2798,7 +2791,7 @@ static void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *ren if (game->play.hot_entity == entity->handle) { if (entity->name.size) { Dqn_V2I player_tile = Dqn_V2I_InitNx2(world_pos.x / game->play.tile_size, world_pos.y / game->play.tile_size); - Dqn_f32 line_height = TELY_Render_FontHeight(renderer, &platform->assets); + Dqn_f32 line_height = TELY_Render_FontHeight(renderer); Dqn_V2 draw_p = world_mouse_p; TELY_Render_TextF(renderer, draw_p, Dqn_V2_InitNx2(0.f, 1), "%.*s", DQN_STR_FMT(entity->name)); draw_p.y += line_height; TELY_Render_TextF(renderer, draw_p, Dqn_V2_InitNx2(0.f, 1), "World Pos: (%.1f, %.1f)", world_pos.x, world_pos.y); draw_p.y += line_height; @@ -2818,7 +2811,7 @@ static void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *ren } if (entity->type == FP_EntityType_Billboard) { - TELY_Render_PushFont(renderer, game->talkco_font); + TELY_Render_PushFontSize(renderer, game->talkco_font, game->font_size); DQN_DEFER { TELY_Render_PopFont(renderer); }; DQN_FOR_UINDEX (player_index, game->play.players.size) { FP_GameEntityHandle player_handle = game->play.players.data[player_index]; @@ -2828,7 +2821,7 @@ static void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *ren switch (state) { case FP_EntityBillboardState_Attack: { Dqn_V2 draw_p = Dqn_Rect_InterpolatedPoint(world_hit_box, Dqn_V2_InitNx2(0.6f, 0.2f)); - draw_p.y += TELY_Render_FontHeight(renderer, assets) * player_index; + draw_p.y += TELY_Render_FontHeight(renderer) * player_index; TELY_Render_PushColourV4(renderer, colour_accent_yellow); FP_DrawBillboardKeyBindHint(renderer, assets, game, player_index, controls->mode, controls->attack, draw_p, true /*draw_player_prefix*/); TELY_Render_PopColourV4(renderer); @@ -2836,7 +2829,7 @@ static void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *ren case FP_EntityBillboardState_Dash: { Dqn_V2 draw_p = Dqn_Rect_InterpolatedPoint(world_hit_box, Dqn_V2_InitNx2(0.505f, -0.08f)); - draw_p.y += TELY_Render_FontHeight(renderer, assets) * player_index; + draw_p.y += TELY_Render_FontHeight(renderer) * player_index; TELY_Render_PushColourV4(renderer, TELY_Colour_V4InitRGBU32(0xFFE726)); FP_DrawBillboardKeyBindHint(renderer, assets, game, player_index, controls->mode, controls->dash, draw_p, true /*draw_player_prefix*/); TELY_Render_PopColourV4(renderer); @@ -2847,7 +2840,7 @@ static void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *ren case FP_EntityBillboardState_RangeAttack: { Dqn_V2 draw_p = Dqn_Rect_InterpolatedPoint(world_hit_box, Dqn_V2_InitNx2(0.20f, -0.13f)); - draw_p.y += TELY_Render_FontHeight(renderer, assets) * player_index; + draw_p.y += TELY_Render_FontHeight(renderer) * player_index; TELY_Render_PushColourV4(renderer, TELY_Colour_V4InitRGBU32(0x364659)); FP_DrawBillboardKeyBindHint(renderer, assets, game, player_index, controls->mode, controls->range_attack, draw_p, true /*draw_player_prefix*/); TELY_Render_PopColourV4(renderer); @@ -2855,7 +2848,7 @@ static void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *ren case FP_EntityBillboardState_Strafe: { Dqn_V2 draw_p = Dqn_Rect_InterpolatedPoint(world_hit_box, Dqn_V2_InitNx2(0.36f, -0.15f)); - draw_p.y += TELY_Render_FontHeight(renderer, assets) * player_index; + draw_p.y += TELY_Render_FontHeight(renderer) * player_index; TELY_Render_PushColourV4(renderer, TELY_Colour_V4InitRGBU32(0xFF68A8)); FP_DrawBillboardKeyBindHint(renderer, assets, game, player_index, controls->mode, controls->strafe, draw_p, true /*draw_player_prefix*/); TELY_Render_PopColourV4(renderer); @@ -2863,25 +2856,25 @@ static void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *ren case FP_EntityBillboardState_Build: { Dqn_V2 draw_p = Dqn_Rect_InterpolatedPoint(world_hit_box, Dqn_V2_InitNx2(0.065f, 0.2f)); - draw_p.y += TELY_Render_FontHeight(renderer, assets) * player_index; + draw_p.y += TELY_Render_FontHeight(renderer) * player_index; TELY_Render_PushColourV4(renderer, colour_accent_yellow); FP_DrawBillboardKeyBindHint(renderer, assets, game, player_index, controls->mode, controls->build_mode, draw_p, true /*draw_player_prefix*/); TELY_Render_PopColourV4(renderer); draw_p = Dqn_Rect_InterpolatedPoint(world_hit_box, Dqn_V2_InitNx2(0.35f, 0.2f)); - draw_p.y += TELY_Render_FontHeight(renderer, assets) * player_index; + draw_p.y += TELY_Render_FontHeight(renderer) * player_index; TELY_Render_PushColourV4(renderer, TELY_Colour_V4InitRGBU32(0xFF68A8)); FP_DrawBillboardKeyBindHint(renderer, assets, game, player_index, controls->mode, controls->move_building_ui_cursor_left, draw_p, true /*draw_player_prefix*/); TELY_Render_PopColourV4(renderer); draw_p = Dqn_Rect_InterpolatedPoint(world_hit_box, Dqn_V2_InitNx2(0.44f, 0.2f)); - draw_p.y += TELY_Render_FontHeight(renderer, assets) * player_index; + draw_p.y += TELY_Render_FontHeight(renderer) * player_index; TELY_Render_PushColourV4(renderer, TELY_Colour_V4InitRGBU32(0xFF68A8)); FP_DrawBillboardKeyBindHint(renderer, assets, game, player_index, controls->mode, controls->move_building_ui_cursor_right, draw_p, false /*draw_player_prefix*/); TELY_Render_PopColourV4(renderer); draw_p = Dqn_Rect_InterpolatedPoint(world_hit_box, Dqn_V2_InitNx2(0.665f, 0.2f)); - draw_p.y += TELY_Render_FontHeight(renderer, assets) * player_index; + draw_p.y += TELY_Render_FontHeight(renderer) * player_index; TELY_Render_PushColourV4(renderer, TELY_COLOUR_BLACK_V4); FP_DrawBillboardKeyBindHint(renderer, assets, game, player_index, controls->mode, controls->attack, draw_p, true /*draw_player_prefix*/); TELY_Render_PopColourV4(renderer); @@ -2899,7 +2892,7 @@ static void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *ren // NOTE: Shake the world =================================================================== Dqn_Rect window_rect = {}; - window_rect.size = Dqn_V2_InitV2I(platform->core.window_size); + window_rect.size = Dqn_V2_InitV2I(os->core.window_size); Dqn_f32 tex_scalar = {}; { @@ -3007,7 +3000,7 @@ static void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *ren Dqn_V2 const player_avatar_base_pos[] = { Dqn_V2_InitNx1(32.f), - Dqn_V2_InitNx2(platform->core.window_size.x - 320.f, 32.f), + Dqn_V2_InitNx2(os->core.window_size.x - 320.f, 32.f), }; DQN_ASSERT(game->play.players.size <= DQN_ARRAY_UCOUNT(player_avatar_base_pos)); @@ -3015,7 +3008,7 @@ static void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *ren if (game->play.players.size == 1) { // NOTE: We show the Press to join for the remaining 2nd player TELY_Render_PushTransform(renderer, Dqn_M2x3_Identity()); - TELY_Render_PushFont(renderer, game->talkco_font); + TELY_Render_PushFontSize(renderer, game->talkco_font, game->font_size); DQN_DEFER { TELY_Render_PopFont(renderer); TELY_Render_PopTransform(renderer); @@ -3028,7 +3021,7 @@ static void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *ren else join_game_key = DQN_STR8(""); - Dqn_f32 font_height = TELY_Render_FontHeight(renderer, assets); + Dqn_f32 font_height = TELY_Render_FontHeight(renderer); Dqn_V2 base_p = player_avatar_base_pos[game->play.players.size]; TELY_Render_TextF(renderer, base_p, Dqn_V2_Zero, "Press %.*s", DQN_STR_FMT(join_game_key)); base_p.y += font_height; FP_ListenForNewPlayer(input, game); @@ -3144,7 +3137,7 @@ static void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *ren } TELY_Render_PushColourV4(renderer, TELY_COLOUR_BLACK_V4); - TELY_Render_PushFont(renderer, game->talkco_font_large); + TELY_Render_PushFontSize(renderer, game->talkco_font, game->large_talkco_font_size); DQN_DEFER { TELY_Render_PopFont(renderer); TELY_Render_PopColourV4(renderer); @@ -3180,10 +3173,10 @@ static void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *ren 0.f /*rotation*/, tex_mod_colour); } else { - Dqn_ThreadScratch scratch = Dqn_Thread_GetScratch(nullptr); - TELY_AssetFont const *font = TELY_Render_Font(renderer, assets); - Dqn_Str8 key_bind_label = FP_ScanCodeToLabel(scratch.arena, key_bind.scan_code); - interact_btn_rect.size = TELY_Asset_MeasureText(font, key_bind_label); + Dqn_ThreadScratch scratch = Dqn_Thread_GetScratch(nullptr); + TELY_AssetFontSizeHandle font_size = TELY_Render_ActiveFont(renderer); + Dqn_Str8 key_bind_label = FP_ScanKeyToLabel(scratch.arena, key_bind.scan_key); + interact_btn_rect.size = TELY_Asset_MeasureText(assets, font_size, key_bind_label); Dqn_Rect key_bind_rect = interact_btn_rect; key_bind_rect.pos.y += interact_btn_rect.size.y * .3f; @@ -3204,13 +3197,13 @@ static void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *ren bool trigger_buy_anim = false; if (have_enough_coins) { - if (TELY_Platform_InputScanCodeIsPressed(input, key_bind.scan_code)) { + if (TELY_OSInput_ScanKeyIsPressed(input, key_bind.scan_key)) { game->play.player_trigger_purchase_building_timestamp = game->play.clock_ms + buy_duration_ms; - } else if (TELY_Platform_InputScanCodeIsDown(input, key_bind.scan_code)) { + } else if (TELY_OSInput_ScanKeyIsDown(input, key_bind.scan_key)) { trigger_buy_anim = true; if (game->play.clock_ms > game->play.player_trigger_purchase_building_timestamp) game->play.player_trigger_purchase_building_timestamp = game->play.clock_ms; - } else if (TELY_Platform_InputScanCodeIsReleased(input, key_bind.scan_code)) { + } else if (TELY_OSInput_ScanKeyIsReleased(input, key_bind.scan_key)) { if (game->play.clock_ms > game->play.player_trigger_purchase_building_timestamp) { if (mapping.inventory_count) { player->coins -= *mapping.building_base_price; @@ -3295,10 +3288,10 @@ static void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *ren 0.f /*rotation*/, tex_mod_colour); } else { - Dqn_ThreadScratch scratch = Dqn_Thread_GetScratch(nullptr); - TELY_AssetFont const *font = TELY_Render_Font(renderer, assets); - Dqn_Str8 key_bind_label = FP_ScanCodeToLabel(scratch.arena, key_bind.scan_code); - interact_btn_rect.size = TELY_Asset_MeasureText(font, key_bind_label); + Dqn_ThreadScratch scratch = Dqn_Thread_GetScratch(nullptr); + TELY_AssetFontSizeHandle font_size = TELY_Render_ActiveFont(renderer); + Dqn_Str8 key_bind_label = FP_ScanKeyToLabel(scratch.arena, key_bind.scan_key); + interact_btn_rect.size = TELY_Asset_MeasureText(assets, font_size, key_bind_label); Dqn_Rect key_bind_rect = interact_btn_rect; key_bind_rect.pos.y += interact_btn_rect.size.y * .3f; @@ -3336,13 +3329,13 @@ static void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *ren bool trigger_buy_anim = false; if (have_enough_coins) { - if (TELY_Platform_InputScanCodeIsPressed(input, key_bind.scan_code)) { + if (TELY_OSInput_ScanKeyIsPressed(input, key_bind.scan_key)) { game->play.player_trigger_purchase_upgrade_timestamp = game->play.clock_ms + buy_duration_ms; - } else if (TELY_Platform_InputScanCodeIsDown(input, key_bind.scan_code)) { + } else if (TELY_OSInput_ScanKeyIsDown(input, key_bind.scan_key)) { trigger_buy_anim = true; if (game->play.clock_ms > game->play.player_trigger_purchase_upgrade_timestamp) game->play.player_trigger_purchase_upgrade_timestamp = game->play.clock_ms; - } else if (TELY_Platform_InputScanCodeIsReleased(input, key_bind.scan_code)) { + } else if (TELY_OSInput_ScanKeyIsReleased(input, key_bind.scan_key)) { if (game->play.clock_ms > game->play.player_trigger_purchase_upgrade_timestamp) { player->coins -= *mapping.upgrade_base_price; *mapping.upgrade_base_price *= 1; @@ -3411,11 +3404,11 @@ static void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *ren 0.f, TELY_COLOUR_WHITE_V4); - TELY_Render_PushFont(renderer, game->talkco_font); + TELY_Render_PushFontSize(renderer, game->talkco_font, game->font_size); DQN_DEFER { TELY_Render_PopFont(renderer); }; next_pos = Dqn_Rect_InterpolatedPoint(player_avatar_rect, Dqn_V2_InitNx2(1.f, 0)); - Dqn_f32 font_height = TELY_Render_FontHeight(renderer, &platform->assets); + Dqn_f32 font_height = TELY_Render_FontHeight(renderer); // NOTE: Health bar ==================================================== Dqn_f32 bar_height = font_height * .75f; @@ -3677,7 +3670,7 @@ static void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *ren else if (building.type == FP_EntityType_ChurchTerry) building_count = player->inventory.churchs; - TELY_Render_PushFont(renderer, game->talkco_font); + TELY_Render_PushFontSize(renderer, game->talkco_font, game->font_size); DQN_DEFER { TELY_Render_PopFont(renderer); }; Dqn_V2 label_p = Dqn_Rect_InterpolatedPoint(rect, Dqn_V2_InitNx2(0.5f, 1.25f)); @@ -3694,7 +3687,7 @@ static void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *ren TELY_Render_PushTransform(renderer, Dqn_M2x3_Identity()); DQN_DEFER { TELY_Render_PopTransform(renderer); }; - TELY_Render_PushFont(renderer, game->talkco_font_large); + TELY_Render_PushFontSize(renderer, game->talkco_font, game->large_talkco_font_size); DQN_DEFER { TELY_Render_PopFont(renderer); }; uint64_t time_until_next_wave_ms = 0; @@ -3704,7 +3697,7 @@ static void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *ren } } - Dqn_f32 mid_x = platform->core.window_size.x * .5f; + Dqn_f32 mid_x = os->core.window_size.x * .5f; if (time_until_next_wave_ms) { TELY_Render_TextF(renderer, Dqn_V2_InitNx2(mid_x, first_player_avatar_rect.pos.y), @@ -3721,13 +3714,13 @@ static void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *ren TELY_Render_PushTransform(renderer, Dqn_M2x3_Identity()); DQN_DEFER { TELY_Render_PopTransform(renderer); }; - Dqn_f32 font_height = TELY_Render_FontHeight(renderer, assets); - Dqn_f32 bar_height = font_height * 1.25f; + Dqn_f32 font_height = TELY_Render_FontHeight(renderer); + Dqn_f32 bar_height = font_height * 1.25f; { TELY_AssetSpriteAnimation *anim = TELY_Asset_GetSpriteAnimation(&game->atlas_sprite_sheet, g_anim_names.heart); FP_GameEntity *heart = FP_Game_GetEntity(game, game->play.heart); - Dqn_f32 max_width = platform->core.window_size.x * .5f; - Dqn_V2 draw_p = Dqn_V2_InitNx2(platform->core.window_size.x * .25f, first_player_avatar_rect.pos.y + bar_height); + Dqn_f32 max_width = os->core.window_size.x * .5f; + Dqn_V2 draw_p = Dqn_V2_InitNx2(os->core.window_size.x * .25f, first_player_avatar_rect.pos.y + bar_height); Dqn_f32 health_t = heart->hp / DQN_CAST(Dqn_f32)heart->hp_cap; Dqn_Rect health_rect = Dqn_Rect_InitNx4(draw_p.x, draw_p.y, max_width, bar_height); Dqn_Rect curr_health_rect = Dqn_Rect_InitNx4(draw_p.x, draw_p.y, max_width * health_t, bar_height); @@ -3755,7 +3748,7 @@ static void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *ren 0.f /*rotation*/, TELY_COLOUR_WHITE_V4); - TELY_Render_PushFont(renderer, game->talkco_font_large); + TELY_Render_PushFontSize(renderer, game->talkco_font, game->large_talkco_font_size); DQN_DEFER { TELY_Render_PopFont(renderer); }; TELY_Render_TextF(renderer, Dqn_Rect_InterpolatedPoint(heart_icon_rect, Dqn_V2_InitNx2(1.f, 0.65f)), Dqn_V2_Zero, "Terry's Heart"); } @@ -3772,7 +3765,7 @@ static void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *ren // NOTE: Add scanlines into the game for A E S T H E T I C S =================================== if (game->play.state == FP_GameState_Play) { - Dqn_V2 screen_size = Dqn_V2_InitNx2(platform->core.window_size.w, platform->core.window_size.h); + Dqn_V2 screen_size = Dqn_V2_InitNx2(os->core.window_size.w, os->core.window_size.h); Dqn_f32 scanline_gap = 4.0f; Dqn_f32 scanline_thickness = 3.0f; FP_GameRenderScanlines(renderer, scanline_gap, scanline_thickness, screen_size); @@ -3784,7 +3777,7 @@ static void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *ren TELY_Render_PushTransform(renderer, Dqn_M2x3_Identity()); DQN_DEFER { TELY_Render_PopTransform(renderer); }; - Dqn_V2I inset = platform->core.window_size * .05f; + Dqn_V2I inset = os->core.window_size * .05f; Dqn_f32 min_inset = DQN_CAST(Dqn_f32)DQN_MIN(inset.x, inset.y); Dqn_V2 draw_p = Dqn_V2_InitNx2(min_inset, min_inset); @@ -3793,11 +3786,11 @@ static void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *ren Dqn_V4 bg_colour = TELY_Colour_V4InitRGBAU32(0x301010FF); // NOTE: Maroon TELY_Render_RectColourV4( renderer, - Dqn_Rect_InitNx4(0, 0, DQN_CAST(Dqn_f32)platform->core.window_size.x, DQN_CAST(Dqn_f32)platform->core.window_size.y), + Dqn_Rect_InitNx4(0, 0, DQN_CAST(Dqn_f32)os->core.window_size.x, DQN_CAST(Dqn_f32)os->core.window_size.y), TELY_RenderShapeMode_Fill, bg_colour); - Dqn_Rect window_rect = Dqn_Rect_InitNx4(0, 0, DQN_CAST(Dqn_f32)platform->core.window_size.w, DQN_CAST(Dqn_f32)platform->core.window_size.h); + Dqn_Rect window_rect = Dqn_Rect_InitNx4(0, 0, DQN_CAST(Dqn_f32)os->core.window_size.w, DQN_CAST(Dqn_f32)os->core.window_size.h); if (game->play.state == FP_GameState_IntroScreen || game->play.state == FP_GameState_LoseGame) { Dqn_f32 tex_scalar = 0.f; { @@ -3892,7 +3885,7 @@ static void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *ren TELY_COLOUR_WHITE_V4); } - TELY_Render_PushFont(renderer, game->inter_regular_font); + TELY_Render_PushFontSize(renderer, game->inter_regular_font, game->font_size); Dqn_f32 t = (DQN_SINF(DQN_CAST(Dqn_f32)input->timer_s * 5.f) + 1.f) / 2.f; TELY_Render_PushColourV4(renderer, TELY_Colour_V4Alpha(TELY_COLOUR_WHITE_V4, t)); TELY_Render_TextF(renderer, Dqn_Rect_InterpolatedPoint(window_rect, Dqn_V2_InitNx2(0.5f, 0.925f)), Dqn_V2_InitNx1(0.5f), "Press or to %s", game->play.state == FP_GameState_IntroScreen ? "start" : "restart"); @@ -3901,37 +3894,37 @@ static void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *ren TELY_Render_PopFont(renderer); if (game->play.state == FP_GameState_LoseGame) - FP_PlayReset(game, platform); + FP_PlayReset(game, os); if (FP_ListenForNewPlayer(input, game)) game->play.state = FP_GameState_Play; } else if (game->play.state == FP_GameState_Pause) { - TELY_Render_PushFont(renderer, game->inter_regular_font_large); - TELY_Render_TextF(renderer, draw_p, Dqn_V2_Zero, "Paused"); draw_p.y += TELY_Render_FontHeight(renderer, assets); + TELY_Render_PushFontSize(renderer, game->inter_regular_font, game->large_font_size); + TELY_Render_TextF(renderer, draw_p, Dqn_V2_Zero, "Paused"); draw_p.y += TELY_Render_FontHeight(renderer); TELY_Render_PopFont(renderer); - TELY_Render_PushFont(renderer, game->inter_regular_font); - TELY_Render_TextF(renderer, draw_p, Dqn_V2_Zero, "Press enter to resume"); draw_p.y += TELY_Render_FontHeight(renderer, assets); + TELY_Render_PushFontSize(renderer, game->inter_regular_font, game->font_size); + TELY_Render_TextF(renderer, draw_p, Dqn_V2_Zero, "Press enter to resume"); draw_p.y += TELY_Render_FontHeight(renderer); TELY_Render_PopFont(renderer); TELY_Render_PopColourV4(renderer); - if (TELY_Platform_InputScanCodeIsPressed(input, TELY_PlatformInputScanCode_Return)) + if (TELY_OSInput_ScanKeyIsPressed(input, TELY_OSInputScanKey_Return)) game->play.state = FP_GameState_Play; } else { DQN_ASSERT(game->play.state == FP_GameState_WinGame); - TELY_Render_PushFont(renderer, game->inter_regular_font_large); - TELY_Render_TextF(renderer, draw_p, Dqn_V2_Zero, "Terry has been saved"); draw_p.y += TELY_Render_FontHeight(renderer, assets); - TELY_Render_TextF(renderer, draw_p, Dqn_V2_Zero, "from his terrible calamity"); draw_p.y += TELY_Render_FontHeight(renderer, assets); + TELY_Render_PushFontSize(renderer, game->inter_regular_font, game->large_font_size); + TELY_Render_TextF(renderer, draw_p, Dqn_V2_Zero, "Terry has been saved"); draw_p.y += TELY_Render_FontHeight(renderer); + TELY_Render_TextF(renderer, draw_p, Dqn_V2_Zero, "from his terrible calamity"); draw_p.y += TELY_Render_FontHeight(renderer); TELY_Render_PopFont(renderer); - TELY_Render_PushFont(renderer, game->inter_regular_font); - TELY_Render_TextF(renderer, draw_p, Dqn_V2_Zero, "He lives for yet another day and another love"); draw_p.y += TELY_Render_FontHeight(renderer, assets); - TELY_Render_TextF(renderer, draw_p, Dqn_V2_Zero, "Press enter to restart"); draw_p.y += TELY_Render_FontHeight(renderer, assets); + TELY_Render_PushFontSize(renderer, game->inter_regular_font, game->font_size); + TELY_Render_TextF(renderer, draw_p, Dqn_V2_Zero, "He lives for yet another day and another love"); draw_p.y += TELY_Render_FontHeight(renderer); + TELY_Render_TextF(renderer, draw_p, Dqn_V2_Zero, "Press enter to restart"); draw_p.y += TELY_Render_FontHeight(renderer); TELY_Render_PopFont(renderer); TELY_Render_PopColourV4(renderer); - if (TELY_Platform_InputScanCodeIsPressed(input, TELY_PlatformInputScanCode_Return)) - FP_PlayReset(game, platform); + if (TELY_OSInput_ScanKeyIsPressed(input, TELY_OSInputScanKey_Return)) + FP_PlayReset(game, os); } Dqn_f32 scanline_gap = 4.0f; @@ -3978,7 +3971,7 @@ static void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *ren // NOTE: Debug UI ============================================================================== - if (TELY_Platform_InputScanCodeIsPressed(input, TELY_PlatformInputScanCode_F1)) + if (TELY_OSInput_ScanKeyIsPressed(input, TELY_OSInputScanKey_F1)) game->play.debug_ui = !game->play.debug_ui; DQN_MSVC_WARNING_PUSH @@ -4009,7 +4002,7 @@ static void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *ren info_column.widget->semantic_position[TELY_RFuiAxis_X].kind = TELY_RFuiPositionKind_Absolute; info_column.widget->semantic_position[TELY_RFuiAxis_X].value = next_y; info_column.widget->semantic_position[TELY_RFuiAxis_Y].kind = TELY_RFuiPositionKind_Absolute; - info_column.widget->semantic_position[TELY_RFuiAxis_Y].value = platform->core.window_size.h - TELY_Render_FontHeight(renderer, assets); + info_column.widget->semantic_position[TELY_RFuiAxis_Y].value = os->core.window_size.h - TELY_Render_FontHeight(renderer); { TELY_RFuiResult row = TELY_RFui_Row(rfui, DQN_STR8("Info Bar")); @@ -4021,19 +4014,19 @@ static void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *ren builder.allocator = scratch.allocator; Dqn_Str8Builder_AppendF(&builder, "TELY"); - if (Dqn_Str8_IsValid(platform->core.os_name)) { - Dqn_Str8Builder_AppendF(&builder, " | %.*s", DQN_STR_FMT(platform->core.os_name)); + if (Dqn_Str8_IsValid(os->core.os_name)) { + Dqn_Str8Builder_AppendF(&builder, " | %.*s", DQN_STR_FMT(os->core.os_name)); } Dqn_Str8Builder_AppendF(&builder, " | %dx%d %.1fHz | TSC %.1f GHz", - platform->core.window_size.w, - platform->core.window_size.h, - platform->core.display.refresh_rate, - platform->core.tsc_per_second / 1'000'000'000.0); + os->core.window_size.w, + os->core.window_size.h, + os->core.display.refresh_rate, + os->core.tsc_per_second / 1'000'000'000.0); - if (platform->core.ram_mb) - Dqn_Str8Builder_AppendF(&builder, " | RAM %.1fGB", platform->core.ram_mb / 1024.0); + if (os->core.ram_mb) + Dqn_Str8Builder_AppendF(&builder, " | RAM %.1fGB", os->core.ram_mb / 1024.0); DQN_MSVC_WARNING_PUSH DQN_MSVC_WARNING_DISABLE(6272 6271) @@ -4059,23 +4052,23 @@ static void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *ren if (TELY_RFui_ButtonF(rfui, "F1 Debug info").clicked) game->play.debug_ui = !game->play.debug_ui; - if (TELY_RFui_ButtonF(rfui, "F2 Add coins x10,000").clicked || TELY_Platform_InputScanCodeIsPressed(input, TELY_PlatformInputScanCode_F2)) { + if (TELY_RFui_ButtonF(rfui, "F2 Add coins x10,000").clicked || TELY_OSInput_ScanKeyIsPressed(input, TELY_OSInputScanKey_F2)) { for (FP_GameEntityHandle player_handle : game->play.players) { FP_GameEntity *player = FP_Game_GetEntity(game, player_handle); player->coins += 10'000; } } - if (TELY_RFui_ButtonF(rfui, "F3 Win game").clicked || TELY_Platform_InputScanCodeIsPressed(input, TELY_PlatformInputScanCode_F3)) + if (TELY_RFui_ButtonF(rfui, "F3 Win game").clicked || TELY_OSInput_ScanKeyIsPressed(input, TELY_OSInputScanKey_F3)) game->play.state = FP_GameState_WinGame; - if (TELY_RFui_ButtonF(rfui, "F4 Lose game").clicked || TELY_Platform_InputScanCodeIsPressed(input, TELY_PlatformInputScanCode_F4)) + if (TELY_RFui_ButtonF(rfui, "F4 Lose game").clicked || TELY_OSInput_ScanKeyIsPressed(input, TELY_OSInputScanKey_F4)) game->play.state = FP_GameState_LoseGame; - if (TELY_RFui_ButtonF(rfui, "F5 Reset game").clicked || TELY_Platform_InputScanCodeIsPressed(input, TELY_PlatformInputScanCode_F5)) - FP_PlayReset(game, platform); + if (TELY_RFui_ButtonF(rfui, "F5 Reset game").clicked || TELY_OSInput_ScanKeyIsPressed(input, TELY_OSInputScanKey_F5)) + FP_PlayReset(game, os); - if (TELY_RFui_ButtonF(rfui, "F6 Increase health").clicked || TELY_Platform_InputScanCodeIsPressed(input, TELY_PlatformInputScanCode_F6)) { + if (TELY_RFui_ButtonF(rfui, "F6 Increase health").clicked || TELY_OSInput_ScanKeyIsPressed(input, TELY_OSInputScanKey_F6)) { for (FP_GameEntityHandle player_handle : game->play.players) { FP_GameEntity *player = FP_Game_GetEntity(game, player_handle); player->hp_cap += FP_DEFAULT_DAMAGE; @@ -4083,7 +4076,7 @@ static void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *ren } } - if (TELY_RFui_ButtonF(rfui, "F7 Increase stamina").clicked || TELY_Platform_InputScanCodeIsPressed(input, TELY_PlatformInputScanCode_F7)) { + if (TELY_RFui_ButtonF(rfui, "F7 Increase stamina").clicked || TELY_OSInput_ScanKeyIsPressed(input, TELY_OSInputScanKey_F7)) { for (FP_GameEntityHandle player_handle : game->play.players) { FP_GameEntity *player = FP_Game_GetEntity(game, player_handle); player->stamina_cap += DQN_CAST(uint16_t)(FP_TERRY_DASH_STAMINA_COST * .5f); @@ -4091,7 +4084,7 @@ static void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *ren } } - if (TELY_RFui_ButtonF(rfui, "F8 Increase mobile data").clicked || TELY_Platform_InputScanCodeIsPressed(input, TELY_PlatformInputScanCode_F8)) { + if (TELY_RFui_ButtonF(rfui, "F8 Increase mobile data").clicked || TELY_OSInput_ScanKeyIsPressed(input, TELY_OSInputScanKey_F8)) { for (FP_GameEntityHandle player_handle : game->play.players) { FP_GameEntity *player = FP_Game_GetEntity(game, player_handle); player->terry_mobile_data_plan_cap += DQN_KILOBYTES(1); @@ -4099,10 +4092,10 @@ static void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *ren } } - if (TELY_RFui_ButtonF(rfui, "F9 %s god mode", game->play.god_mode ? "Disable" : "Enable").clicked || TELY_Platform_InputScanCodeIsPressed(input, TELY_PlatformInputScanCode_F9)) + if (TELY_RFui_ButtonF(rfui, "F9 %s god mode", game->play.god_mode ? "Disable" : "Enable").clicked || TELY_OSInput_ScanKeyIsPressed(input, TELY_OSInputScanKey_F9)) game->play.god_mode = !game->play.god_mode; - if (TELY_RFui_ButtonF(rfui, "F11 Building inventory +1").clicked || TELY_Platform_InputScanCodeIsPressed(input, TELY_PlatformInputScanCode_F11)) { + if (TELY_RFui_ButtonF(rfui, "F11 Building inventory +1").clicked || TELY_OSInput_ScanKeyIsPressed(input, TELY_OSInputScanKey_F11)) { for (FP_GameEntityHandle player_handle : game->play.players) { FP_GameEntity *player = FP_Game_GetEntity(game, player_handle); player->inventory.clubs += 1; @@ -4112,7 +4105,7 @@ static void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *ren } } - if (TELY_RFui_ButtonF(rfui, "1 %s HUD", game->play.debug_hide_hud ? "Show" : "Hide").clicked || TELY_Platform_InputScanCodeIsPressed(input, TELY_PlatformInputScanCode_1)) + if (TELY_RFui_ButtonF(rfui, "1 %s HUD", game->play.debug_hide_hud ? "Show" : "Hide").clicked || TELY_OSInput_ScanKeyIsPressed(input, TELY_OSInputScanKey_1)) game->play.debug_hide_hud = !game->play.debug_hide_hud; if (TELY_RFui_ButtonF(rfui, "%s bounding rects", game->play.debug_hide_bounding_rectangles ? "Show" : "Hide").clicked) @@ -4123,7 +4116,7 @@ static void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *ren } if (0) { - next_y += TELY_Asset_GetFont(assets, TELY_RFui_ActiveFont(rfui))->pixel_height; + next_y += TELY_RFui_ActiveFont(rfui).size; TELY_RFuiResult bar = TELY_RFui_Column(rfui, DQN_STR8("Memory bar")); bar.widget->semantic_position[TELY_RFuiAxis_X].kind = TELY_RFuiPositionKind_Absolute; bar.widget->semantic_position[TELY_RFuiAxis_X].value = 10.f; @@ -4134,23 +4127,23 @@ static void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *ren DQN_DEFER { TELY_RFui_PopParent(rfui); }; { - Dqn_ArenaInfo arena_info = Dqn_Arena_Info(&platform->arena); + Dqn_ArenaInfo arena_info = Dqn_Arena_Info(&os->arena); DQN_MSVC_WARNING_PUSH DQN_MSVC_WARNING_DISABLE(6271) // warning C6271: Extra argument passed to 'TELY_RFui_TextF'. TELY_RFui_TextF(rfui, "Platform Arena[%I64u]: %_$$d/%_$$d (HWM %_$$d, COMMIT %_$$d)", - platform->arena.blocks, + os->arena.blocks, arena_info.used, arena_info.capacity, arena_info.used_hwm, arena_info.commit); DQN_MSVC_WARNING_POP - next_y += TELY_Asset_GetFont(assets, TELY_RFui_ActiveFont(rfui))->pixel_height; + next_y += TELY_RFui_ActiveFont(rfui).size; } for (Dqn_ArenaCatalogItem *item = g_dqn_library->arena_catalog.sentinel.next; item != &g_dqn_library->arena_catalog.sentinel; item = item->next) { if (item != g_dqn_library->arena_catalog.sentinel.next) - next_y += TELY_Asset_GetFont(assets, TELY_RFui_ActiveFont(rfui))->pixel_height; + next_y += TELY_RFui_ActiveFont(rfui).size; Dqn_Arena *arena = item->arena; Dqn_ArenaInfo arena_info = Dqn_Arena_Info(arena); @@ -4170,7 +4163,7 @@ static void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *ren // NOTE: Profiler if (0) { - next_y += TELY_Asset_GetFont(assets, TELY_RFui_ActiveFont(rfui))->pixel_height; + next_y += TELY_RFui_ActiveFont(rfui).size; TELY_RFuiResult profiler_layout = TELY_RFui_Column(rfui, DQN_STR8("Profiler Bar")); profiler_layout.widget->semantic_position[TELY_RFuiAxis_X].kind = TELY_RFuiPositionKind_Absolute; profiler_layout.widget->semantic_position[TELY_RFuiAxis_X].value = 10.f; @@ -4181,9 +4174,9 @@ static void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *ren DQN_DEFER { TELY_RFui_PopParent(rfui); }; // TODO(doyle): On emscripten we need to use Dqn_OS_PerfCounterNow() however those - // require OS functions which need to be exposed into the platform layer. + // require OS functions which need to be exposed into the os layer. #if 0 - Dqn_f64 const tsc_frequency = DQN_CAST(Dqn_f64)TELY_Platform_PerfCounterFrequency(&platform->core); + Dqn_f64 const tsc_frequency = DQN_CAST(Dqn_f64)TELY_OS_PerfCounterFrequency(&os->core); Dqn_ProfilerAnchor *anchors = Dqn_Profiler_AnchorBuffer(Dqn_ProfilerAnchorBuffer_Back); for (size_t anchor_index = 1; anchor_index < DQN_PROFILER_ANCHOR_BUFFER_SIZE; anchor_index++) { Dqn_ProfilerAnchor const *anchor = anchors + anchor_index; @@ -4216,14 +4209,13 @@ static void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *ren } } -FP_DLL_FUNCTION -void TELY_DLL_FrameUpdate(void *user_data) +TELY_OS_DLL_FUNCTION +void TELY_OS_DLLFrameUpdate(TELY_OS *os) { - TELY_Platform *platform = DQN_CAST(TELY_Platform *) user_data; - TELY_PlatformInput *input = &platform->input; - TELY_Assets *assets = &platform->assets; - TELY_Renderer *renderer = &platform->renderer; - FP_Game *game = DQN_CAST(FP_Game *) platform->user_data; + TELY_OSInput *input = &os->input; + TELY_Assets *assets = &os->assets; + TELY_Renderer *renderer = &os->renderer; + FP_Game *game = DQN_CAST(FP_Game *) os->user_data; // ============================================================================================= @@ -4237,7 +4229,7 @@ void TELY_DLL_FrameUpdate(void *user_data) // ============================================================================================= - TELY_Audio *audio = &platform->audio; + TELY_Audio *audio = &os->audio; #if 0 if (audio->playback_size == 0) { @@ -4248,7 +4240,7 @@ void TELY_DLL_FrameUpdate(void *user_data) // ============================================================================================= if (game->play.state == FP_GameState_Play) { - if (TELY_Platform_InputKeyWasDown(input->mouse_left) && TELY_Platform_InputKeyIsDown(input->mouse_left)) { + if (TELY_OSInput_KeyWasDown(input->mouse_left) && TELY_OSInput_KeyIsDown(input->mouse_left)) { if (game->play.prev_active_entity.id) game->play.active_entity = game->play.prev_active_entity; } else { @@ -4268,7 +4260,7 @@ void TELY_DLL_FrameUpdate(void *user_data) continue; game->play.hot_entity = entity->handle; - if (TELY_Platform_InputKeyIsPressed(input->mouse_left)) { + if (TELY_OSInput_KeyIsPressed(input->mouse_left)) { game->play.active_entity = entity->handle; game->play.clicked_entity = entity->handle; } @@ -4279,10 +4271,10 @@ void TELY_DLL_FrameUpdate(void *user_data) for (game->play.delta_s_accumulator += DQN_CAST(Dqn_f32)input->delta_s; game->play.delta_s_accumulator > FP_GAME_PHYSICS_STEP; game->play.delta_s_accumulator -= FP_GAME_PHYSICS_STEP) { - FP_Update(platform, game, input, audio); + FP_Update(os, game, input, audio); } - FP_Render(game, platform, renderer, audio); + FP_Render(game, os, renderer, audio); TELY_Audio_MixPlaybackSamples(audio, assets); } diff --git a/feely_pona_build.cpp b/feely_pona_build.cpp index df99fb1..5851573 100644 --- a/feely_pona_build.cpp +++ b/feely_pona_build.cpp @@ -97,7 +97,7 @@ int main(int argc, char const **argv) dry_run = true; } else if (arg == DQN_STR8("--web")) { target_web = true; - } else if (arg == DQN_STR8("--dev-fast-build")) { + } else if (arg == DQN_STR8("--fast-dev-build")) { dev_fast_build = true; } else { PRINT_HELP; @@ -302,14 +302,21 @@ int main(int argc, char const **argv) DQN_DEFER { feely_pona_no_dll_timings[1] = Dqn_OS_PerfCounterNow(); }; Dqn_CPPBuildCompileFile build_file = {}; - build_file.input_file_path = Dqn_FsPath_ConvertF(scratch.arena, "%.*s/feely_pona_unity_nodll.h", DQN_STR_FMT(code_dir)); + build_file.input_file_path = Dqn_FsPath_ConvertF(scratch.arena, "%.*s/feely_pona_unity.h", DQN_STR_FMT(code_dir)); + build_file.output_file_path = Dqn_FsPath_ConvertF(scratch.arena, "terry_cherry"); build_file.flags = Dqn_Slice_InitCArrayCopy(scratch.arena, {DQN_STR8("/Tp")}); + Dqn_List compile_flags = Dqn_List_InitSliceCopy(scratch.arena, 16, common_compile_flags); + Dqn_List_AddCArray(&compile_flags, { + DQN_STR8("/D TELY_WITH_PLATFORM"), + DQN_STR8("/D FEELY_PONA_IMPLEMENTATION"), + }); + Dqn_CPPBuildContext feely_pona_no_dll_build_context = {}; feely_pona_no_dll_build_context.compiler = Dqn_CPPBuildCompiler_MSVC; feely_pona_no_dll_build_context.compile_files = Dqn_Slice_InitCArrayCopy(scratch.arena, {build_file}); feely_pona_no_dll_build_context.include_dirs = Dqn_Slice_InitCArrayCopy(scratch.arena, {raylib_dir}); - feely_pona_no_dll_build_context.compile_flags = common_compile_flags; + feely_pona_no_dll_build_context.compile_flags = Dqn_List_ToSliceCopy(&compile_flags, scratch.arena); feely_pona_no_dll_build_context.build_dir = build_dir; feely_pona_no_dll_build_context.link_flags = feely_pona_platform_link_flags; @@ -329,12 +336,14 @@ int main(int argc, char const **argv) Dqn_CPPBuildCompileFile build_file = {}; build_file.input_file_path = Dqn_FsPath_ConvertF(scratch.arena, "%.*s/feely_pona_unity.h", DQN_STR_FMT(code_dir)); - build_file.output_file_path = Dqn_FsPath_ConvertF(scratch.arena, "tely_dll_msvc", DQN_STR_FMT(code_dir)); + build_file.output_file_path = Dqn_FsPath_ConvertF(scratch.arena, "terry_cherry_dev_dll"); build_file.flags = Dqn_Slice_InitCArrayCopy(scratch.arena, {DQN_STR8("/Tp")}); - Dqn_List compile_flags = Dqn_List_InitSliceCopy(scratch.arena, 128, common_compile_flags); - Dqn_List_Add(&compile_flags, DQN_STR8("/LD")); - Dqn_List_Add(&compile_flags, DQN_STR8("/Fetely_dll_msvc")); + Dqn_List compile_flags = Dqn_List_InitSliceCopy(scratch.arena, 16, common_compile_flags); + Dqn_List_AddCArray(&compile_flags, { + DQN_STR8("/LD"), + DQN_STR8("/D FEELY_PONA_IMPLEMENTATION"), + }); if (!dev_fast_build) Dqn_List_Add(&compile_flags, DQN_STR8("/analyze")); @@ -361,12 +370,15 @@ int main(int argc, char const **argv) DQN_DEFER { feely_pona_platform_timings[1] = Dqn_OS_PerfCounterNow(); }; Dqn_CPPBuildCompileFile build_file = {}; - build_file.input_file_path = Dqn_FsPath_ConvertF(scratch.arena, "%.*s/tely_platform_raylib_unity.h", DQN_STR_FMT(tely_dir)); - build_file.output_file_path = Dqn_FsPath_ConvertF(scratch.arena, "feely_pona_msvc", DQN_STR_FMT(code_dir)); + build_file.input_file_path = Dqn_FsPath_ConvertF(scratch.arena, "%.*s/feely_pona_unity.h", DQN_STR_FMT(code_dir)); + build_file.output_file_path = Dqn_FsPath_ConvertF(scratch.arena, "terry_cherry_dev", DQN_STR_FMT(code_dir)); build_file.flags = Dqn_Slice_InitCArrayCopy(scratch.arena, {DQN_STR8("/Tp")}); Dqn_List compile_flags = Dqn_List_InitSliceCopy(scratch.arena, 128, common_compile_flags); - Dqn_List_Add(&compile_flags, DQN_STR8("/Fefeely_pona_msvc")); + Dqn_List_AddCArray(&compile_flags, { + DQN_STR8("/D TELY_WITH_PLATFORM"), + DQN_STR8("/D TELY_WITH_PLATFORM_DLL"), + }); Dqn_CPPBuildContext build_context = {}; build_context.compiler = Dqn_CPPBuildCompiler_MSVC; @@ -380,7 +392,7 @@ int main(int argc, char const **argv) Dqn_Str8 cmd = Dqn_CPPBuild_ToCommandLine(build_context, Dqn_CPPBuildMode_AlwaysRebuild, scratch.allocator); Dqn_Print_StdLnF(Dqn_PrintStd_Out, "%.*s\n", DQN_STR_FMT(cmd)); } else { - Dqn_Str8 exe_path = Dqn_FsPath_ConvertF(scratch.arena, "%.*s/feely_pona_msvc.exe", DQN_STR_FMT(build_dir)); + Dqn_Str8 exe_path = Dqn_FsPath_ConvertF(scratch.arena, "%.*s/terry_cherry_dev_msvc.exe", DQN_STR_FMT(build_dir)); bool exe_is_locked = false; if (Dqn_Fs_Exists(exe_path)) { Dqn_FsFile exe_file = Dqn_Fs_OpenFile(exe_path, Dqn_FsFileOpen_OpenIfExist, Dqn_FsFileAccess_Read | Dqn_FsFileAccess_Write); @@ -528,10 +540,10 @@ int main(int argc, char const **argv) Dqn_CPPBuildContext build_context = {}; build_context.compile_file_obj_suffix = DQN_CPP_BUILD_OBJ_SUFFIX_O; build_context.compile_files = Dqn_Slice_InitCArrayCopy(scratch.arena, { - Dqn_CPPBuildCompileFile{{}, Dqn_FsPath_ConvertF(scratch.arena, "%.*s/feely_pona_unity_nodll.cpp", DQN_STR_FMT(code_dir)) }, + Dqn_CPPBuildCompileFile{{}, Dqn_FsPath_ConvertF(scratch.arena, "%.*s/feely_pona_unity.cpp", DQN_STR_FMT(code_dir)) }, }); - Dqn_Str8 output_name = DQN_STR8("Terry_Cherry"); + Dqn_Str8 output_name = DQN_STR8("Terry_Cherry_Emscripten"); Dqn_List compile_flags = Dqn_List_InitCArrayCopy(scratch.arena, 32, { DQN_STR8("cmd"), DQN_STR8("/C"), DQN_STR8("emcc.bat"), DQN_STR8("-o"), Dqn_Str8_InitF(scratch.allocator, "%.*s.html", DQN_STR_FMT(output_name)), @@ -545,6 +557,8 @@ int main(int argc, char const **argv) DQN_STR8("--preload-file"), DQN_STR8("Data"), DQN_STR8("-msimd128"), DQN_STR8("-msse2"), + DQN_STR8("-D"), DQN_STR8("TELY_WITH_PLATFORM"), + DQN_STR8("-D"), DQN_STR8("FEELY_PONA_IMPLEMENTATION"), }); Dqn_List_AddList(&compile_flags, build_specific_compile_flags); @@ -559,7 +573,7 @@ int main(int argc, char const **argv) } // NOTE: Move the files to a directory - Dqn_Str8 folder_path = Dqn_FsPath_ConvertF(scratch.arena, "%.*s/%.*s_Emscripten", DQN_STR_FMT(build_dir), DQN_STR_FMT(output_name)); + Dqn_Str8 folder_path = Dqn_FsPath_ConvertF(scratch.arena, "%.*s/%.*s", DQN_STR_FMT(build_dir), DQN_STR_FMT(output_name)); if (!Dqn_Fs_DirExists(folder_path)) { Dqn_Str8 mkdir_cmd = Dqn_Str8_InitF(scratch.allocator, "mkdir %.*s", DQN_STR_FMT(folder_path)); Dqn_OS_ExecOrAbort(mkdir_cmd, {}); @@ -574,7 +588,7 @@ int main(int argc, char const **argv) for (Dqn_Str8 file_ext : generated_file_extension) { Dqn_Str8 src_path = Dqn_FsPath_ConvertF(scratch.arena, "%.*s/%.*s.%.*s", DQN_STR_FMT(build_dir), DQN_STR_FMT(output_name), DQN_STR_FMT(file_ext)); - Dqn_Str8 dest_path = Dqn_FsPath_ConvertF(scratch.arena, "%.*s/%.*s.%.*s", DQN_STR_FMT(folder_path), DQN_STR_FMT(output_name), DQN_STR_FMT(file_ext)); + Dqn_Str8 dest_path = Dqn_FsPath_ConvertF(scratch.arena, "%.*s/Terry_Cherry.%.*s", DQN_STR_FMT(folder_path), DQN_STR_FMT(file_ext)); Dqn_Str8 cmd = Dqn_Str8_InitF(scratch.allocator, "cmd /C move /Y %.*s %.*s", DQN_STR_FMT(src_path), DQN_STR_FMT(dest_path)); if (dry_run) { Dqn_Print_StdLnF(Dqn_PrintStd_Out, "%.*s\n", DQN_STR_FMT(cmd)); diff --git a/feely_pona_game.cpp b/feely_pona_game.cpp index 455e5cb..d5bea2b 100644 --- a/feely_pona_game.cpp +++ b/feely_pona_game.cpp @@ -3,24 +3,24 @@ #include "feely_pona_unity.h" #endif -static bool FP_Game_KeyBindIsPressed(TELY_PlatformInput const *input, FP_GameControls const *controls, FP_GameKeyBind key_bind) +static bool FP_Game_KeyBindIsPressed(TELY_OSInput const *input, FP_GameControls const *controls, FP_GameKeyBind key_bind) { bool result = false; if (controls->mode == FP_GameControlMode_Keyboard) { - result = TELY_Platform_InputScanCodeIsPressed(input, key_bind.scan_code); + result = TELY_OSInput_ScanKeyIsPressed(input, key_bind.scan_key); } else { - result = TELY_Platform_InputGamepadKeyIsPressed(input, controls->gamepad_index, key_bind.gamepad_key); + result = TELY_OSInput_GamepadKeyIsPressed(input, controls->gamepad_index, key_bind.gamepad_key); } return result; } -static bool FP_Game_KeyBindIsDown(TELY_PlatformInput const *input, FP_GameControls const *controls, FP_GameKeyBind key_bind) +static bool FP_Game_KeyBindIsDown(TELY_OSInput const *input, FP_GameControls const *controls, FP_GameKeyBind key_bind) { bool result = false; if (controls->mode == FP_GameControlMode_Keyboard) { - result = TELY_Platform_InputScanCodeIsDown(input, key_bind.scan_code); + result = TELY_OSInput_ScanKeyIsDown(input, key_bind.scan_key); } else { - result = TELY_Platform_InputGamepadKeyIsDown(input, controls->gamepad_index, key_bind.gamepad_key); + result = TELY_OSInput_GamepadKeyIsDown(input, controls->gamepad_index, key_bind.gamepad_key); } return result; } diff --git a/feely_pona_game.h b/feely_pona_game.h index e19a889..cd638f6 100644 --- a/feely_pona_game.h +++ b/feely_pona_game.h @@ -168,8 +168,8 @@ enum FP_GameInGameMenu struct FP_GameKeyBind { - TELY_PlatformInputScanCode scan_code; - TELY_PlatformInputGamepadKey gamepad_key; + TELY_OSInputScanKey scan_key; + TELY_OSInputGamepadKey gamepad_key; }; enum FP_GameControlMode @@ -433,18 +433,20 @@ struct FP_GamePlay struct FP_Game { - TELY_AssetFontHandle inter_regular_font_large; TELY_AssetFontHandle inter_regular_font; TELY_AssetFontHandle inter_italic_font; TELY_AssetFontHandle jetbrains_mono_font; TELY_AssetFontHandle talkco_font; - TELY_AssetFontHandle talkco_font_large; - TELY_AssetFontHandle talkco_font_xlarge; + TELY_AssetAudioHandle audio[FP_GameAudio_Count]; TELY_AssetSpriteSheet atlas_sprite_sheet; TELY_RFui rfui; FP_GamePlay play; Dqn_Arena *frame_arena; + uint16_t font_size; + uint16_t large_font_size; + uint16_t large_talkco_font_size; + uint16_t xlarge_talkco_font_size; }; struct FP_GameAStarNode diff --git a/feely_pona_misc.cpp b/feely_pona_misc.cpp index a4dd324..b7541ff 100644 --- a/feely_pona_misc.cpp +++ b/feely_pona_misc.cpp @@ -3,7 +3,7 @@ #include "feely_pona_unity.h" #endif -void FP_UnitTests(TELY_Platform *platform) +void FP_UnitTests(TELY_OS *os) { { uint32_t array[] = {1}; @@ -318,9 +318,9 @@ void FP_UnitTests(TELY_Platform *platform) } { - Dqn_Arena_TempMemoryScope(&platform->arena); + Dqn_Arena_TempMemoryScope(&os->arena); TELY_ChunkPool pool = {}; - pool.arena = &platform->arena; + pool.arena = &os->arena; void *bytes16 = TELY_ChunkPool_Alloc(&pool, 16); TELY_ChunkPool_Dealloc(&pool, bytes16); @@ -346,13 +346,13 @@ void FP_UnitTests(TELY_Platform *platform) } // NOTE: Unit test DFS pre-order and post-order walk - Dqn_Arena_TempMemoryScope(&platform->arena); + Dqn_Arena_TempMemoryScope(&os->arena); TELY_ChunkPool chunk_pool = {}; - chunk_pool.arena = &platform->arena; + chunk_pool.arena = &os->arena; - FP_Game *game = Dqn_Arena_New(&platform->arena, FP_Game, Dqn_ZeroMem_Yes); + FP_Game *game = Dqn_Arena_New(&os->arena, FP_Game, Dqn_ZeroMem_Yes); game->play.chunk_pool = &chunk_pool; - game->play.entities = Dqn_VArray_Init(&platform->arena, 1024 * 8); + game->play.entities = Dqn_VArray_Init(&os->arena, 1024 * 8); game->play.root_entity = Dqn_VArray_Make(&game->play.entities, Dqn_ZeroMem_No); Dqn_FArray_Add(&game->play.parent_entity_stack, game->play.root_entity->handle); diff --git a/feely_pona_sprite_packer.cpp b/feely_pona_sprite_packer.cpp index 1cee10d..ff56319 100644 --- a/feely_pona_sprite_packer.cpp +++ b/feely_pona_sprite_packer.cpp @@ -37,17 +37,17 @@ struct SpriteSpecification uint16_t frames_per_second; }; -static Dqn_String8 SpriteAnimNameFromFilePath(Dqn_String8 path) +static Dqn_Str8 SpriteAnimNameFromFilePath(Dqn_Str8 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; + Dqn_Str8 file_name = Dqn_Str8_FileNameFromPath(path); + Dqn_Str8 file_name_without_extension = Dqn_Str8_BinarySplit(file_name, DQN_STR8(".")).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 = {}; + Dqn_Str8 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("_")); + Dqn_Str8BinarySplitResult split = Dqn_Str8_BinarySplitReverse(file_name_without_extension, DQN_STR8("_")); result = split.lhs; } else { result = file_name_without_extension; @@ -67,26 +67,26 @@ int main(int argc, char const *argv[]) } // NOTE: Verify some arguments ================================================================= - Dqn_String8 atlas_dimensions = Dqn_String8_InitCString8(argv[1]); - Dqn_String8 sprite_spec_path = Dqn_String8_InitCString8(argv[2]); - Dqn_String8 dir = Dqn_String8_InitCString8(argv[3]); + Dqn_Str8 atlas_dimensions = Dqn_Str8_InitCStr8(argv[1]); + Dqn_Str8 sprite_spec_path = Dqn_Str8_InitCStr8(argv[2]); + Dqn_Str8 dir = Dqn_Str8_InitCStr8(argv[3]); if (!Dqn_Fs_Exists(sprite_spec_path)) { - Dqn_Log_ErrorF("Sprite specification file does not exist, we tried to find \"%.*s\" but it does not exist", DQN_STRING_FMT(sprite_spec_path)); + Dqn_Log_ErrorF("Sprite specification file does not exist, we tried to find \"%.*s\" but it does not exist", DQN_STR_FMT(sprite_spec_path)); return -1; } if (!Dqn_Fs_DirExists(dir)) { - Dqn_Log_ErrorF("Directory to load sprites from does not exist, we tried to find \"%.*s\" but it does not exist", DQN_STRING_FMT(dir)); + Dqn_Log_ErrorF("Directory to load sprites from does not exist, we tried to find \"%.*s\" but it does not exist", DQN_STR_FMT(dir)); return -1; } // NOTE: Parse the atlas size ================================================================== Dqn_V2I atlas_size = {}; { - Dqn_String8BinarySplitResult atlas_dimensions_split = Dqn_String8_BinarySplit(atlas_dimensions, DQN_STRING8("x")); - Dqn_String8ToU64Result width = Dqn_String8_ToU64(atlas_dimensions_split.lhs, 0); - Dqn_String8ToU64Result height = Dqn_String8_ToU64(atlas_dimensions_split.rhs, 0); + Dqn_Str8BinarySplitResult atlas_dimensions_split = Dqn_Str8_BinarySplit(atlas_dimensions, DQN_STR8("x")); + Dqn_Str8ToU64Result width = Dqn_Str8_ToU64(atlas_dimensions_split.lhs, 0); + Dqn_Str8ToU64Result height = Dqn_Str8_ToU64(atlas_dimensions_split.rhs, 0); if (!width.success || width.value == 0) { Dqn_Log_ErrorF("Width for the sprite atlas was not a number > 0"); @@ -106,51 +106,51 @@ int main(int argc, char const *argv[]) Dqn_DSMap sprite_spec_table = Dqn_DSMap_Init(1024); { Dqn_ThreadScratch inner_scratch = Dqn_Thread_GetScratch(scratch.arena); - Dqn_String8 sprite_spec_buffer = Dqn_Fs_Read(sprite_spec_path, inner_scratch.allocator); - Dqn_String8SplitAllocResult sprite_spec_lines = Dqn_String8_SplitAlloc(inner_scratch.allocator, sprite_spec_buffer, DQN_STRING8("\n")); + Dqn_Str8 sprite_spec_buffer = Dqn_Fs_Read(sprite_spec_path, inner_scratch.allocator); + Dqn_Str8SplitAllocResult sprite_spec_lines = Dqn_Str8_SplitAlloc(inner_scratch.allocator, sprite_spec_buffer, DQN_STR8("\n")); DQN_FOR_UINDEX(line_index, sprite_spec_lines.size) { - Dqn_String8 line = Dqn_String8_TrimWhitespaceAround(sprite_spec_lines.data[line_index]); + Dqn_Str8 line = Dqn_Str8_TrimWhitespaceAround(sprite_spec_lines.data[line_index]); if (line.size == 0) // NOTE: Support empty lines, just ignore them continue; - Dqn_String8SplitAllocResult line_parts = Dqn_String8_SplitAlloc(inner_scratch.allocator, line, DQN_STRING8(";")); + Dqn_Str8SplitAllocResult line_parts = Dqn_Str8_SplitAlloc(inner_scratch.allocator, line, DQN_STR8(";")); DQN_ASSERTF(line_parts.size == 2, "Line must have 2 parts in the sprite specification\n" "\n" ";\\n\n" "\n" - "Line was '%.*s' loaded from '%.*s'", DQN_STRING_FMT(line), DQN_STRING_FMT(sprite_spec_path)); + "Line was '%.*s' loaded from '%.*s'", DQN_STR_FMT(line), DQN_STR_FMT(sprite_spec_path)); - Dqn_String8 anim_name = line_parts.data[0]; - Dqn_String8ToU64Result frames_per_second = Dqn_String8_ToU64(line_parts.data[1], 0); + Dqn_Str8 anim_name = line_parts.data[0]; + Dqn_Str8ToU64Result frames_per_second = Dqn_Str8_ToU64(line_parts.data[1], 0); DQN_ASSERTF(frames_per_second.success, "Frames per second was not a convertible number, line was '%.*s'", line); - Dqn_DSMapResult slot = Dqn_DSMap_MakeKeyString8Copy(&sprite_spec_table, scratch.allocator, anim_name); + Dqn_DSMapResult slot = Dqn_DSMap_MakeKeyStr8Copy(&sprite_spec_table, scratch.allocator, anim_name); slot.value->frames_per_second = DQN_CAST(uint16_t)frames_per_second.value; } } // NOTE: Get the list of files ================================================================= - Dqn_List file_list_raw = Dqn_List_Init(scratch.arena, 128); + Dqn_List file_list_raw = Dqn_List_Init(scratch.arena, 128); for (Dqn_Win_FolderIterator it = {}; Dqn_Win_FolderIterate(dir, &it); ) { - if (Dqn_String8_EndsWithInsensitive(it.file_name, DQN_STRING8(".png"))) { - Dqn_String8 *item = Dqn_List_Make(&file_list_raw, Dqn_ZeroMem_Yes); - *item = Dqn_FsPath_ConvertF(scratch.arena, "%.*s/%.*s", DQN_STRING_FMT(dir), DQN_STRING_FMT(it.file_name)); + if (Dqn_Str8_EndsWithInsensitive(it.file_name, DQN_STR8(".png"))) { + Dqn_Str8 *item = Dqn_List_Make(&file_list_raw, Dqn_ZeroMem_Yes); + *item = Dqn_FsPath_ConvertF(scratch.arena, "%.*s/%.*s", DQN_STR_FMT(dir), DQN_STR_FMT(it.file_name)); } } // NOTE: Sort the list of files ================================================================ if (file_list_raw.count == 0) { - Dqn_Log_InfoF("There are no '.png' files in the directory '%.*s' to create an atlas from, exiting", DQN_STRING_FMT(dir)); + Dqn_Log_InfoF("There are no '.png' files in the directory '%.*s' to create an atlas from, exiting", DQN_STR_FMT(dir)); return 0; } // NOTE: Bubble sort the file list naturally =================================================== - Dqn_Slice file_list = Dqn_List_ToSliceCopy(&file_list_raw, scratch.arena); + Dqn_Slice file_list = Dqn_List_ToSliceCopy(&file_list_raw, scratch.arena); for (bool swapped = true; swapped; ) { swapped = false; for (Dqn_usize list_index = 0; list_index < file_list.size - 1; list_index++) { - Dqn_String8 left = file_list.data[list_index + 0]; - Dqn_String8 right = file_list.data[list_index + 1]; + Dqn_Str8 left = file_list.data[list_index + 0]; + Dqn_Str8 right = file_list.data[list_index + 1]; if (strnatcmp(left.data, right.data) > 0) { DQN_SWAP(file_list.data[list_index + 0], file_list.data[list_index + 1]); swapped = true; @@ -165,7 +165,7 @@ int main(int argc, char const *argv[]) // NOTE: Load the sprites to determine their dimensions for rect packing ======================= Dqn_SArray rects = Dqn_SArray_Init(scratch.arena, file_list.size, Dqn_ZeroMem_Yes); - for (Dqn_String8 it : file_list) { + for (Dqn_Str8 it : file_list) { int x = 0, y = 0, channels_in_file = 0; stbi_uc *pixels = stbi_load(it.data, &x, &y, &channels_in_file, 4 /*desired_channels*/); DQN_ASSERT(pixels); @@ -177,16 +177,16 @@ int main(int argc, char const *argv[]) rect->h = y; // NOTE: Enumerate the number of frames for this animation ================================= - Dqn_String8 anim_prefix = SpriteAnimNameFromFilePath(it); - Dqn_String8 file_name = Dqn_String8_FileNameFromPath(it); - DQN_ASSERTF(!Dqn_String8_HasChar(file_name, ';'), + Dqn_Str8 anim_prefix = SpriteAnimNameFromFilePath(it); + Dqn_Str8 file_name = Dqn_Str8_FileNameFromPath(it); + DQN_ASSERTF(!Dqn_Str8_HasChar(file_name, ';'), "\n\nSprite frame loaded from file\n" " '%.*s'\n" "\n" "however the file name has a semicolon which is not supported because we use a semicolon to delimit our sprite specification", - DQN_STRING_FMT(file_name)); + DQN_STR_FMT(file_name)); - Dqn_DSMapResult slot = Dqn_DSMap_FindKeyString8(&sprite_spec_table, anim_prefix); + Dqn_DSMapResult slot = Dqn_DSMap_FindKeyStr8(&sprite_spec_table, anim_prefix); DQN_ASSERTF(slot.found, "\n\nSprite frame loaded from file\n" " '%.*s'\n" @@ -196,12 +196,12 @@ int main(int argc, char const *argv[]) "\n" "Add a line in format of ; to the file, e.g.\n" " %.*s;8\n", - DQN_STRING_FMT(it), - DQN_STRING_FMT(sprite_spec_path), - DQN_STRING_FMT(anim_prefix)); + DQN_STR_FMT(it), + DQN_STR_FMT(sprite_spec_path), + DQN_STR_FMT(anim_prefix)); slot.value->frame_count++; - Dqn_Log_InfoF("Packing sprite: %.*s", DQN_STRING_FMT(it)); + Dqn_Log_InfoF("Packing sprite: %.*s", DQN_STR_FMT(it)); } // NOTE: Pack the rects ======================================================================== @@ -217,7 +217,7 @@ int main(int argc, char const *argv[]) int final_bpp = 4; int final_image_stride = atlas_size.w * final_bpp; char *final_image = Dqn_Arena_NewArray(scratch.arena, char, atlas_size.h * final_image_stride, Dqn_ZeroMem_Yes); - Dqn_String8 atlas_path = Dqn_String8_InitF(scratch.allocator, "%.*s.png", DQN_STRING_FMT(dir)); + Dqn_Str8 atlas_path = Dqn_Str8_InitF(scratch.allocator, "%.*s.png", DQN_STR_FMT(dir)); // NOTE: Generate the meta file ================================================================ // NOTE: Count the number of animations we loaded frames fore @@ -231,18 +231,18 @@ int main(int argc, char const *argv[]) } } - Dqn_String8 meta_path = Dqn_String8_InitF(scratch.allocator, "%.*s.txt", DQN_STRING_FMT(dir)); + Dqn_Str8 meta_path = Dqn_Str8_InitF(scratch.allocator, "%.*s.txt", DQN_STR_FMT(dir)); Dqn_FsFile meta_file = Dqn_Fs_OpenFile(meta_path, Dqn_FsFileOpen_CreateAlways, Dqn_FsFileAccess_Write); Dqn_Fs_WriteFileF(&meta_file, "@file;%.*s;%d;%d\n", - DQN_STRING_FMT(Dqn_String8_FileNameFromPath(atlas_path)), + DQN_STR_FMT(Dqn_Str8_FileNameFromPath(atlas_path)), DQN_CAST(int) num_anim_rects, DQN_CAST(int) num_anims); - Dqn_Log_InfoF("Generating meta file: %.*s", DQN_STRING_FMT(meta_path)); - Dqn_String8 active_anim_prefix = {}; + Dqn_Log_InfoF("Generating meta file: %.*s", DQN_STR_FMT(meta_path)); + Dqn_Str8 active_anim_prefix = {}; DQN_FOR_UINDEX (file_list_index, file_list.size) { - Dqn_String8 it = file_list.data[file_list_index]; + Dqn_Str8 it = file_list.data[file_list_index]; int w, h, channels_in_file; stbi_uc *loaded_image = stbi_load(it.data, &w, &h, &channels_in_file, 4 /*desired_channels*/); @@ -263,22 +263,22 @@ int main(int argc, char const *argv[]) stbi_image_free(loaded_image); // NOTE: Detect what animation we are currently processing ================================= - Dqn_String8 anim_prefix = SpriteAnimNameFromFilePath(it); + Dqn_Str8 anim_prefix = SpriteAnimNameFromFilePath(it); 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 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); + Dqn_DSMapResult slot = Dqn_DSMap_FindKeyStr8(&sprite_spec_table, active_anim_prefix); + Dqn_Fs_WriteFileF(&meta_file, "@anim;%.*s;%u;%u\n", DQN_STR_FMT(active_anim_prefix), slot.value->frames_per_second, slot.value->frame_count); } // NOTE: Write the sprite rectangles in ==================================================== - Dqn_String8 file_name = Dqn_String8_FileNameFromPath(it); - Dqn_Fs_WriteFileF(&meta_file, "%d;%d;%d;%d;%.*s", packed_rect.x, packed_rect.y, packed_rect.w, packed_rect.h, DQN_STRING_FMT(file_name)); + Dqn_Str8 file_name = Dqn_Str8_FileNameFromPath(it); + Dqn_Fs_WriteFileF(&meta_file, "%d;%d;%d;%d;%.*s", packed_rect.x, packed_rect.y, packed_rect.w, packed_rect.h, DQN_STR_FMT(file_name)); if (file_list_index != (file_list.size - 1)) Dqn_Fs_WriteFileF(&meta_file, "\n"); } - Dqn_Log_InfoF("Generating atlas: %.*s", DQN_STRING_FMT(atlas_path)); + Dqn_Log_InfoF("Generating atlas: %.*s", DQN_STR_FMT(atlas_path)); stbi_write_png(atlas_path.data, atlas_size.w, atlas_size.h, 4, final_image, final_image_stride); return 0; } diff --git a/feely_pona_unity.cpp b/feely_pona_unity.cpp new file mode 100644 index 0000000..fd0f865 --- /dev/null +++ b/feely_pona_unity.cpp @@ -0,0 +1 @@ +#include "feely_pona_unity.h" diff --git a/feely_pona_unity.h b/feely_pona_unity.h index 3d88b63..b9fccff 100644 --- a/feely_pona_unity.h +++ b/feely_pona_unity.h @@ -1,65 +1,13 @@ -// ================================================================================================= +// NOTE: feely_pona ================================================================================ +// Unity build header to compile the entire application as a single translation unit -// NOTE(doyle): Work-around for clangd to correctly resolve symbols in unity -// builds by providing symbol definition and prototypes by including this -// mega-header in all files and using the "#pragma once" directive to -// avoid multiple defined symbols when compiling the unity build itself. -// -// See: https://www.frogtoss.com/labs/clangd-with-unity-builds.html - -#pragma once - -// NOTE: DQN ======================================================================================= - -// NOTE: C-strings declared in a ternary cause global-buffer-overflow in -// MSVC2022. -// stb_sprintf assumes c-string literals are 4 byte aligned which is always -// true, however, reading past the end of a string whose size is not a multiple -// of 4 is UB causing ASAN to complain. -#if defined(_MSC_VER) && !defined(__clang__) - #define STBSP__ASAN __declspec(no_sanitize_address) -#endif - -#define DQN_ASAN_POISON 0 -#define DQN_ASAN_VET_POISON 1 -#define DQN_ONLY_RECT -#define DQN_ONLY_V2 -#define DQN_ONLY_V3 -#define DQN_ONLY_V4 -#define DQN_ONLY_WIN -#define DQN_ONLY_FARRAY -#define DQN_ONLY_PROFILER -#define DQN_ONLY_SLICE -#define DQN_ONLY_LIST -#define DQN_ONLY_VARRAY -#define DQN_ONLY_DSMAP -#define DQN_ONLY_FS -#define _CRT_SECURE_NO_WARNINGS -#define DQN_IMPLEMENTATION -#include "External/tely/External/dqn/dqn.h" - -// NOTE: TELY ====================================================================================== - -DQN_MSVC_WARNING_PUSH -DQN_MSVC_WARNING_DISABLE(4505) // warning C4505: unreferenced function with internal linkage has been removed -#include "External/tely/tely_profile.h" -#include "External/tely/tely_platform_input.h" -#include "External/tely/tely_tools.h" -#include "External/tely/tely_asset.h" -#include "External/tely/tely_colour.h" -#include "External/tely/tely_render.h" -#include "External/tely/tely_audio.h" -#include "External/tely/tely_platform.h" -#include "External/tely/tely_rfui.h" - -#include "External/tely/tely_tools.cpp" -#include "External/tely/tely_asset.cpp" -#include "External/tely/tely_audio.cpp" -#include "External/tely/tely_render.cpp" -#include "External/tely/tely_platform_input.cpp" -#include "External/tely/tely_rfui.cpp" +#define TELY_PLATFORM_DLL_FILE_NAME "terry_cherry_dev_dll_msvc" +#include "External/tely/tely_os_raylib_unity.h" // NOTE: feely_pona ================================================================================ +#if defined(_CLANGD) || defined(FEELY_PONA_IMPLEMENTATION) +DQN_MSVC_WARNING_PUSH +DQN_MSVC_WARNING_DISABLE(4505) // warning C4505: unreferenced function with internal linkage has been removed #include "feely_pona.h" #include "feely_pona_stdlib.h" #include "feely_pona_entity.h" @@ -71,3 +19,4 @@ DQN_MSVC_WARNING_DISABLE(4505) // warning C4505: unreferenced function with inte #include "feely_pona_misc.cpp" #include "feely_pona.cpp" DQN_MSVC_WARNING_POP +#endif diff --git a/feely_pona_unity_nodll.cpp b/feely_pona_unity_nodll.cpp deleted file mode 100644 index 21e4e76..0000000 --- a/feely_pona_unity_nodll.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "feely_pona_unity_nodll.h" diff --git a/feely_pona_unity_nodll.h b/feely_pona_unity_nodll.h deleted file mode 100644 index f0cfa73..0000000 --- a/feely_pona_unity_nodll.h +++ /dev/null @@ -1,102 +0,0 @@ -// ================================================================================================= - -// NOTE(doyle): Work-around for clangd to correctly resolve symbols in unity -// builds by providing symbol definition and prototypes by including this -// mega-header in all files and using the "#pragma once" directive to -// avoid multiple defined symbols when compiling the unity build itself. -// -// See: https://www.frogtoss.com/labs/clangd-with-unity-builds.html - -#pragma once - -// NOTE: DQN ======================================================================================= - -// NOTE: C-strings declared in a ternary cause global-buffer-overflow in -// MSVC2022. -// stb_sprintf assumes c-string literals are 4 byte aligned which is always -// true, however, reading past the end of a string whose size is not a multiple -// of 4 is UB causing ASAN to complain. -#if defined(_MSC_VER) && !defined(__clang__) - #define STBSP__ASAN __declspec(no_sanitize_address) -#endif - -#define DQN_ASAN_POISON 0 -#define DQN_ASAN_VET_POISON 1 -#define DQN_ONLY_RECT -#define DQN_ONLY_V2 -#define DQN_ONLY_V3 -#define DQN_ONLY_V4 -#define DQN_ONLY_WIN -#define DQN_ONLY_FARRAY -#define DQN_ONLY_PROFILER -#define DQN_ONLY_SLICE -#define DQN_ONLY_LIST -#define DQN_ONLY_VARRAY -#define DQN_ONLY_DSMAP -#define DQN_ONLY_FS -#define _CRT_SECURE_NO_WARNINGS -#define DQN_IMPLEMENTATION -#include "External/tely/External/dqn/dqn.h" - -// NOTE: STB Headers =============================================================================== - -DQN_GCC_WARNING_PUSH -DQN_GCC_WARNING_DISABLE(-Wunused-function) -#include "External/tely/External/stb/stb_image.h" -DQN_GCC_WARNING_POP - -// ================================================================================================= - -#include "External/tely/External/raylib/raylib.h" -#include "External/tely/External/raylib/rlgl.h" -#include "External/tely/External/raylib/external/glfw/include/GLFW/glfw3.h" - -// NOTE: TELY ====================================================================================== - -DQN_MSVC_WARNING_PUSH -DQN_MSVC_WARNING_DISABLE(4505) // warning C4505: unreferenced function with internal linkage has been removed - -DQN_GCC_WARNING_PUSH -DQN_GCC_WARNING_DISABLE(-Wunused-function) - -#include "External/tely/tely_profile.h" -#include "External/tely/tely_platform_input.h" -#include "External/tely/tely_tools.h" -#include "External/tely/tely_asset.h" -#include "External/tely/tely_colour.h" -#include "External/tely/tely_render.h" -#include "External/tely/tely_audio.h" -#include "External/tely/tely_platform.h" -#include "External/tely/tely_rfui.h" - -#include "External/tely/tely_tools.cpp" -#include "External/tely/tely_asset.cpp" -#include "External/tely/tely_audio.cpp" -#include "External/tely/tely_render.cpp" -#include "External/tely/tely_platform_input.cpp" -#include "External/tely/tely_rfui.cpp" - -// NOTE: feely_pona ================================================================================ -#include "feely_pona.h" -#include "feely_pona_stdlib.h" -#include "feely_pona_entity.h" -#include "feely_pona_game.h" - -#include "feely_pona_entity.cpp" -#include "feely_pona_game.cpp" -#include "feely_pona_entity_create.cpp" -#include "feely_pona_misc.cpp" -#include "feely_pona.cpp" -DQN_MSVC_WARNING_POP -DQN_GCC_WARNING_POP - -#if defined(DQN_PLATFORM_EMSCRIPTEN) -#include -#include -#endif - -// NOTE: TELY_Platform ============================================================================= -#define TELY_PLATFORM_NO_DLL -#include "External/tely/tely_platform.cpp" -#include "External/tely/tely_platform_raylib.cpp" -