Compare commits

...

24 Commits

Author SHA1 Message Date
03920e311c fp: Update website directory to 'Terry_Cherry' 2024-01-21 00:37:07 +11:00
ee95cefdff fp: Update build script for new tely 2023-12-01 16:46:58 +11:00
4d1fffcc02 build: Fix sokol_audio outputting .obj file 2023-11-27 00:13:04 +11:00
8663f1b73c fp: Don't use pthreads for emscripten, needs webserver config 2023-11-27 00:08:49 +11:00
00986fa6a1 fp: Async load audio 2023-11-26 23:45:50 +11:00
13d356cbfd fp: Fix UB in copies of posix synchronisation primitives 2023-11-26 21:59:36 +11:00
5ac952eb83 fp: Fix more threading bugs on Windows 2023-11-26 18:51:36 +11:00
04b4f61810 build: Get changes for linux 2023-11-26 18:43:04 +11:00
5868fc96df fp: Add posix implementation of pthreads 2023-11-26 18:32:59 +11:00
bca013bf05 fp: Support building via GCC on Windows 2023-11-26 16:54:21 +11:00
801b9051c9 fp: Address warnings on GCC 2023-11-26 16:28:35 +11:00
f176d66058 build: Fix emscripten build using MSVC style flags 2023-11-26 16:03:53 +11:00
20d7b7763b build: Fix compile errors on Windows from Linux changes 2023-11-26 14:03:46 +11:00
05788cc726 build: Get basic linux build working 2023-11-26 00:52:50 +11:00
88d996af87 build: Add flags for linux build 2023-11-25 18:28:55 +11:00
f8890f0be2 fp: Start working on linux support 2023-11-24 00:22:07 +11:00
50d6271413 fp: Use audio handles 2023-11-21 22:47:54 +11:00
93e5302c60 fp: Add initial impl of fade in and out wave music 2023-11-21 00:14:50 +11:00
b03c6c3e56 fp: Get new audio stop functionality 2023-11-15 09:47:34 +11:00
074ba436cb Honestly i'm floundering right now 2023-11-14 09:05:25 +11:00
2d685fcdb9 Submodule changes 2023-11-14 08:59:28 +11:00
ebc969603d tely: Add a way to stop music from playing 2023-11-14 08:44:10 +11:00
d0b3ce1bd0 fp: Add potential ambience and background music options 2023-11-09 08:37:08 +11:00
97a83b20f6 fp: Add entrance sounds for perry and game start 2023-11-06 08:29:55 +11:00
18 changed files with 731 additions and 766 deletions

1
.gitignore vendored
View File

@ -1,5 +1,6 @@
Build/ Build/
Nocheckin/ Nocheckin/
feely_pona_build.exe feely_pona_build.exe
feely_pona_build
feely_pona_version.txt feely_pona_version.txt
Tools/emsdk Tools/emsdk

BIN
Data/Audio/ambience_1.ogg (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Data/Audio/ambience_2.ogg (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Data/Audio/game_start.ogg (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Data/Audio/music_1.ogg (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Data/Audio/music_2.ogg (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Data/Audio/perry_start.ogg (Stored with Git LFS) Normal file

Binary file not shown.

2
External/tely vendored

@ -1 +1 @@
Subproject commit 07b3737cf4e5e68be355630228375c5b5873513f Subproject commit 17b352f0b86c538f6e197f7e3428b4c4e321f651

View File

@ -1,5 +1,5 @@
@echo off @echo off
setlocal setlocal
call build_all.bat %* --fast-dev-build || exit /b 1 call build_all.bat %* || exit /b 1

21
build.sh Executable file
View File

@ -0,0 +1,21 @@
#!/bin/bash
set -e
script_dir=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
build_dir=${script_dir}/Build
code_dir=${script_dir}
# Bootstrap a version
git show -s --date=format:%Y-%m-%d --format=%cd HEAD> feely_pona_version.txt
git rev-parse --short=8 HEAD>> feely_pona_version.txt
git rev-list --count HEAD>> feely_pona_version.txt
# Bootstrap the build program
mkdir --parents ${build_dir}
pushd ${build_dir}
g++ -g -Wall -o feely_pona_build ${code_dir}/feely_pona_build.cpp -lm -lpthread
cp --force feely_pona_build ${code_dir}
popd
# Run the build program
${code_dir}/feely_pona_build $@

View File

@ -5,7 +5,7 @@ set script_dir_backslash=%~dp0
set script_dir=%script_dir_backslash:~0,-1% set script_dir=%script_dir_backslash:~0,-1%
set build_dir=%script_dir%\Build set build_dir=%script_dir%\Build
scp -P 8110 %build_dir%\Terry_Cherry\Terry_Cherry.html doylet@doylet.dev:/selfhost/TerryCherry/index.html scp -P 8110 %build_dir%\Terry_Cherry\Terry_Cherry.html doylet@doylet.dev:/selfhost/Terry_Cherry/index.html
scp -P 8110 %build_dir%\Terry_Cherry\Terry_Cherry.data doylet@doylet.dev:/selfhost/TerryCherry/Terry_Cherry.data scp -P 8110 %build_dir%\Terry_Cherry\Terry_Cherry.data doylet@doylet.dev:/selfhost/Terry_Cherry/Terry_Cherry.data
scp -P 8110 %build_dir%\Terry_Cherry\Terry_Cherry.js doylet@doylet.dev:/selfhost/TerryCherry/Terry_Cherry.js scp -P 8110 %build_dir%\Terry_Cherry\Terry_Cherry.js doylet@doylet.dev:/selfhost/Terry_Cherry/Terry_Cherry.js
scp -P 8110 %build_dir%\Terry_Cherry\Terry_Cherry.wasm doylet@doylet.dev:/selfhost/TerryCherry/Terry_Cherry.wasm scp -P 8110 %build_dir%\Terry_Cherry\Terry_Cherry.wasm doylet@doylet.dev:/selfhost/Terry_Cherry/Terry_Cherry.wasm

View File

@ -127,18 +127,18 @@ static TELY_AssetSpriteSheet FP_LoadSpriteSheetFromSpec(TELY_OS *os, TELY_Assets
static void FP_SetDefaultGamepadBindings(FP_GameControls *controls) static void FP_SetDefaultGamepadBindings(FP_GameControls *controls)
{ {
// NOTE: Note up/down/left/right uses analog sticks, non-negotiable. // NOTE: Note up/down/left/right uses analog sticks, non-negotiable.
controls->attack.gamepad_key = TELY_OSInputGamepadKey_X; controls->attack.gamepad_key = TELY_InputGamepadKey_X;
controls->range_attack.gamepad_key = TELY_OSInputGamepadKey_Y; controls->range_attack.gamepad_key = TELY_InputGamepadKey_Y;
controls->build_mode.gamepad_key = TELY_OSInputGamepadKey_L3; controls->build_mode.gamepad_key = TELY_InputGamepadKey_L3;
controls->strafe.gamepad_key = TELY_OSInputGamepadKey_B; controls->strafe.gamepad_key = TELY_InputGamepadKey_B;
controls->dash.gamepad_key = TELY_OSInputGamepadKey_A; controls->dash.gamepad_key = TELY_InputGamepadKey_A;
controls->buy_building.gamepad_key = TELY_OSInputGamepadKey_LeftBumper; controls->buy_building.gamepad_key = TELY_InputGamepadKey_LeftBumper;
controls->buy_upgrade.gamepad_key = TELY_OSInputGamepadKey_RightBumper; controls->buy_upgrade.gamepad_key = TELY_InputGamepadKey_RightBumper;
controls->move_building_ui_cursor_left.gamepad_key = TELY_OSInputGamepadKey_DLeft; controls->move_building_ui_cursor_left.gamepad_key = TELY_InputGamepadKey_DLeft;
controls->move_building_ui_cursor_right.gamepad_key = TELY_OSInputGamepadKey_DRight; controls->move_building_ui_cursor_right.gamepad_key = TELY_InputGamepadKey_DRight;
} }
static FP_ListenForNewPlayerResult FP_ListenForNewPlayer(TELY_OSInput *input, FP_Game *game, bool tutorial_is_allowed) static FP_ListenForNewPlayerResult FP_ListenForNewPlayer(TELY_Input *input, FP_Game *game, bool tutorial_is_allowed)
{ {
FP_ListenForNewPlayerResult result = {}; FP_ListenForNewPlayerResult result = {};
if (game->play.players.size == 2) if (game->play.players.size == 2)
@ -159,16 +159,16 @@ static FP_ListenForNewPlayerResult FP_ListenForNewPlayer(TELY_OSInput *input, FP
} }
} }
bool keyboard_pressed = !keyboard_already_allocated && TELY_OSInput_ScanKeyIsPressed(input, TELY_OSInputScanKey_B); bool keyboard_pressed = !keyboard_already_allocated && TELY_Input_ScanKeyIsPressed(input, TELY_InputScanKey_B);
bool gamepad_pressed = TELY_OSInput_GamepadKeyIsPressed(input, gamepad_index, TELY_OSInputGamepadKey_Start); bool gamepad_pressed = TELY_Input_GamepadKeyIsPressed(input, gamepad_index, TELY_InputGamepadKey_Start);
if (tutorial_is_allowed) { if (tutorial_is_allowed) {
if (!keyboard_already_allocated && TELY_OSInput_ScanKeyIsPressed(input, TELY_OSInputScanKey_T)) { if (!keyboard_already_allocated && TELY_Input_ScanKeyIsPressed(input, TELY_InputScanKey_T)) {
keyboard_pressed = true; keyboard_pressed = true;
result.tutorial_requested = true; result.tutorial_requested = true;
} }
if (TELY_OSInput_GamepadKeyIsPressed(input, gamepad_index, TELY_OSInputGamepadKey_Select)) { if (TELY_Input_GamepadKeyIsPressed(input, gamepad_index, TELY_InputGamepadKey_Select)) {
gamepad_pressed = true; gamepad_pressed = true;
result.tutorial_requested = true; result.tutorial_requested = true;
} }
@ -190,19 +190,19 @@ static FP_ListenForNewPlayerResult FP_ListenForNewPlayer(TELY_OSInput *input, FP
FP_GameControls *controls = &terry->controls; FP_GameControls *controls = &terry->controls;
if (keyboard_pressed) { if (keyboard_pressed) {
controls->mode = FP_GameControlMode_Keyboard; controls->mode = FP_GameControlMode_Keyboard;
controls->up.scan_key = TELY_OSInputScanKey_W; controls->up.scan_key = TELY_InputScanKey_W;
controls->down.scan_key = TELY_OSInputScanKey_S; controls->down.scan_key = TELY_InputScanKey_S;
controls->left.scan_key = TELY_OSInputScanKey_A; controls->left.scan_key = TELY_InputScanKey_A;
controls->right.scan_key = TELY_OSInputScanKey_D; controls->right.scan_key = TELY_InputScanKey_D;
controls->attack.scan_key = TELY_OSInputScanKey_J; controls->attack.scan_key = TELY_InputScanKey_J;
controls->range_attack.scan_key = TELY_OSInputScanKey_K; controls->range_attack.scan_key = TELY_InputScanKey_K;
controls->build_mode.scan_key = TELY_OSInputScanKey_H; controls->build_mode.scan_key = TELY_InputScanKey_H;
controls->strafe.scan_key = TELY_OSInputScanKey_L; controls->strafe.scan_key = TELY_InputScanKey_L;
controls->dash.scan_key = TELY_OSInputScanKey_N; controls->dash.scan_key = TELY_InputScanKey_N;
controls->buy_building.scan_key = TELY_OSInputScanKey_U; controls->buy_building.scan_key = TELY_InputScanKey_U;
controls->buy_upgrade.scan_key = TELY_OSInputScanKey_I; controls->buy_upgrade.scan_key = TELY_InputScanKey_I;
controls->move_building_ui_cursor_left.scan_key = TELY_OSInputScanKey_Q; controls->move_building_ui_cursor_left.scan_key = TELY_InputScanKey_Q;
controls->move_building_ui_cursor_right.scan_key = TELY_OSInputScanKey_E; controls->move_building_ui_cursor_right.scan_key = TELY_InputScanKey_E;
} else { } else {
controls->mode = FP_GameControlMode_Gamepad; controls->mode = FP_GameControlMode_Gamepad;
controls->gamepad_index = gamepad_index; controls->gamepad_index = gamepad_index;
@ -245,7 +245,10 @@ static void FP_PlayReset(FP_Game *game, TELY_OS *os)
} }
// NOTE: Fisher yates shuffle the list // NOTE: Fisher yates shuffle the list
DQN_MSVC_WARNING_PUSH
DQN_MSVC_WARNING_DISABLE(6293) // Ill-formed for loop (potential wrapping index)
for (Dqn_usize index = DQN_ARRAY_UCOUNT(play->monkey_spawn_shuffled_list) - 1; index < DQN_ARRAY_UCOUNT(play->monkey_spawn_shuffled_list); index--) { for (Dqn_usize index = DQN_ARRAY_UCOUNT(play->monkey_spawn_shuffled_list) - 1; index < DQN_ARRAY_UCOUNT(play->monkey_spawn_shuffled_list); index--) {
DQN_MSVC_WARNING_POP
uint32_t swap_index = Dqn_PCG32_Range(&play->rng, 0, DQN_CAST(uint32_t)index + 1); uint32_t swap_index = Dqn_PCG32_Range(&play->rng, 0, DQN_CAST(uint32_t)index + 1);
DQN_SWAP(play->monkey_spawn_shuffled_list[swap_index], play->monkey_spawn_shuffled_list[index]); DQN_SWAP(play->monkey_spawn_shuffled_list[swap_index], play->monkey_spawn_shuffled_list[index]);
} }
@ -421,6 +424,7 @@ void TELY_OS_DLLInit(TELY_OS *os)
// NOTE: TELY Game ============================================================================= // NOTE: TELY Game =============================================================================
TELY_Assets *assets = &os->assets; TELY_Assets *assets = &os->assets;
assets->chunk_pool = &os->chunk_pool;
FP_Game *game = Dqn_Arena_New(&os->arena, FP_Game, Dqn_ZeroMem_Yes); 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)os->core.window_size.x; Dqn_f32 font_scalar = FP_TARGET_VIEWPORT_SIZE.w / DQN_CAST(Dqn_f32)os->core.window_size.x;
@ -434,21 +438,27 @@ void TELY_OS_DLLInit(TELY_OS *os)
game->jetbrains_mono_font = TELY_Asset_LoadFont(assets, DQN_STR8("JetBrains Mono NL (Regular)"), DQN_STR8("Data/Fonts/JetBrainsMonoNL-Regular.ttf")); 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->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_TerryHit] = TELY_Asset_LoadAudio(assets, os, 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_Ching] = TELY_Asset_LoadAudio(assets, os, 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_Church] = TELY_Asset_LoadAudio(assets, os, 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_Club] = TELY_Asset_LoadAudio(assets, os, 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_Dog] = TELY_Asset_LoadAudio(assets, os, 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_MerchantGhost] = TELY_Asset_LoadAudio(assets, os, 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_MerchantGym] = TELY_Asset_LoadAudio(assets, os, 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_MerchantPhone] = TELY_Asset_LoadAudio(assets, os, 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_MerchantTerry] = TELY_Asset_LoadAudio(assets, os, 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_Message] = TELY_Asset_LoadAudio(assets, os, 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_Monkey] = TELY_Asset_LoadAudio(assets, os, 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_Plane] = TELY_Asset_LoadAudio(assets, os, 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_PortalDestroy] = TELY_Asset_LoadAudio(assets, os, 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_Smooch] = TELY_Asset_LoadAudio(assets, os, 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")); game->audio[FP_GameAudio_Woosh] = TELY_Asset_LoadAudio(assets, os, DQN_STR8("Woosh"), DQN_STR8("Data/Audio/woosh.ogg"));
game->audio[FP_GameAudio_GameStart] = TELY_Asset_LoadAudio(assets, os, DQN_STR8("Game Start"), DQN_STR8("Data/Audio/game_start.ogg"));
game->audio[FP_GameAudio_PerryStart] = TELY_Asset_LoadAudio(assets, os, DQN_STR8("Perry Start"), DQN_STR8("Data/Audio/perry_start.ogg"));
game->audio[FP_GameAudio_Ambience1] = TELY_Asset_LoadAudio(assets, os, DQN_STR8("Ambience one"), DQN_STR8("Data/Audio/ambience_1.ogg"));
game->audio[FP_GameAudio_Ambience2] = TELY_Asset_LoadAudio(assets, os, DQN_STR8("Ambience two"), DQN_STR8("Data/Audio/ambience_2.ogg"));
game->audio[FP_GameAudio_Music1] = TELY_Asset_LoadAudio(assets, os, DQN_STR8("Music one"), DQN_STR8("Data/Audio/music_1.ogg"));
game->audio[FP_GameAudio_Music2] = TELY_Asset_LoadAudio(assets, os, DQN_STR8("Music two"), DQN_STR8("Data/Audio/music_2.ogg"));
// NOTE: Load sprite sheets ==================================================================== // NOTE: Load sprite sheets ====================================================================
os->user_data = game; os->user_data = game;
@ -514,7 +524,7 @@ static void FP_AppendMobSpawnerWaypoints(FP_Game *game, FP_GameEntityHandle src_
} }
} }
static void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_OSInput *input, FP_GameEntity *entity, Dqn_V2 *acceleration_meters_per_s) static void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_Input *input, FP_GameEntity *entity, Dqn_V2 *acceleration_meters_per_s)
{ {
TELY_AssetSpriteSheet *sheet = &game->atlas_sprite_sheet; TELY_AssetSpriteSheet *sheet = &game->atlas_sprite_sheet;
FP_GameEntityAction *action = &entity->action; FP_GameEntityAction *action = &entity->action;
@ -1290,7 +1300,7 @@ static void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_O
} }
} }
static void FP_Update(TELY_OS *os, FP_Game *game, TELY_OSInput *input, TELY_Audio *audio) static void FP_Update(TELY_OS *os, FP_Game *game, TELY_Input *input, TELY_Audio *audio)
{ {
Dqn_Profiler_ZoneScopeWithIndex("FP_Update", FP_ProfileZone_FPUpdate); Dqn_Profiler_ZoneScopeWithIndex("FP_Update", FP_ProfileZone_FPUpdate);
if (game->play.state == FP_GameState_Pause) if (game->play.state == FP_GameState_Pause)
@ -1304,16 +1314,16 @@ static void FP_Update(TELY_OS *os, FP_Game *game, TELY_OSInput *input, TELY_Audi
DQN_MSVC_WARNING_PUSH DQN_MSVC_WARNING_PUSH
DQN_MSVC_WARNING_DISABLE(4127) // Conditional expression is constant 'FP_DEVELOPER_MODE' DQN_MSVC_WARNING_DISABLE(4127) // Conditional expression is constant 'FP_DEVELOPER_MODE'
if (FP_DEVELOPER_MODE && TELY_OSInput_KeyIsReleased(input->mouse_left)) if (FP_DEVELOPER_MODE && TELY_Input_KeyIsReleased(input->mouse_keys[TELY_InputMouseKey_Left]))
game->play.clicked_entity = game->play.prev_active_entity; game->play.clicked_entity = game->play.prev_active_entity;
if (TELY_OSInput_ScanKeyIsPressed(input, TELY_OSInputScanKey_Escape)) { if (TELY_Input_ScanKeyIsPressed(input, TELY_InputScanKey_Escape)) {
game->play.state = FP_GameState_Pause; game->play.state = FP_GameState_Pause;
return; return;
} }
if (FP_DEVELOPER_MODE && game->play.clicked_entity.id) { if (FP_DEVELOPER_MODE && game->play.clicked_entity.id) {
if (TELY_OSInput_ScanKeyIsPressed(input, TELY_OSInputScanKey_Delete)) if (TELY_Input_ScanKeyIsPressed(input, TELY_InputScanKey_Delete))
FP_Game_DeleteEntity(game, game->play.clicked_entity); FP_Game_DeleteEntity(game, game->play.clicked_entity);
} }
DQN_MSVC_WARNING_POP DQN_MSVC_WARNING_POP
@ -1341,7 +1351,7 @@ static void FP_Update(TELY_OS *os, FP_Game *game, TELY_OSInput *input, TELY_Audi
// NOTE: Gamepad movement input // NOTE: Gamepad movement input
if (controls->mode == FP_GameControlMode_Gamepad) { if (controls->mode == FP_GameControlMode_Gamepad) {
TELY_OSInputGamepad *gamepad = input->gamepads + controls->gamepad_index; TELY_InputGamepad *gamepad = input->gamepads + controls->gamepad_index;
dir_vector += gamepad->left_stick; dir_vector += gamepad->left_stick;
} }
@ -2009,12 +2019,18 @@ static void FP_Update(TELY_OS *os, FP_Game *game, TELY_OSInput *input, TELY_Audi
// haven't given the player cooldown yet, so we assign a timestamp for that // haven't given the player cooldown yet, so we assign a timestamp for that
if (game->play.wave_cooldown_timestamp_ms == 0) { if (game->play.wave_cooldown_timestamp_ms == 0) {
game->play.wave_cooldown_timestamp_ms = game->play.clock_ms + FP_COOLDOWN_WAVE_TIME_MS; game->play.wave_cooldown_timestamp_ms = game->play.clock_ms + FP_COOLDOWN_WAVE_TIME_MS;
TELY_Audio_Fade(audio, game->bg_music1, TELY_AudioEffectFade_Out, 2000 /*fade_duration_ms*/);
game->bg_music2 = TELY_Audio_Play(audio, game->audio[FP_GameAudio_Music2], 1.f);
TELY_Audio_Fade(audio, game->bg_music2, TELY_AudioEffectFade_In, 2000 /*fade_duration_ms*/);
} else { } else {
// NOTE: Check if cooldown has elapsed, the next wave can start if so // NOTE: Check if cooldown has elapsed, the next wave can start if so
if (game->play.clock_ms > game->play.wave_cooldown_timestamp_ms) { if (game->play.clock_ms > game->play.wave_cooldown_timestamp_ms) {
game->play.enemies_per_wave = DQN_MAX(5 * DQN_CAST(uint32_t)game->play.mob_spawners.size, DQN_CAST(uint32_t)(game->play.enemies_per_wave * 1.5)); game->play.enemies_per_wave = DQN_MAX(5 * DQN_CAST(uint32_t)game->play.mob_spawners.size, DQN_CAST(uint32_t)(game->play.enemies_per_wave * 1.5));
game->play.enemies_spawned_this_wave = 0; // Important! Reset the spawn count game->play.enemies_spawned_this_wave = 0; // Important! Reset the spawn count
game->play.wave_cooldown_timestamp_ms = 0; // Important! We reset the timestamp for the next wave game->play.wave_cooldown_timestamp_ms = 0; // Important! We reset the timestamp for the next wave
TELY_Audio_Fade(audio, game->bg_music2, TELY_AudioEffectFade_Out, 2000 /*fade_duration_ms*/);
game->bg_music1 = TELY_Audio_Play(audio, game->audio[FP_GameAudio_Music1], 1.f);
TELY_Audio_Fade(audio, game->bg_music1, TELY_AudioEffectFade_In, 2000 /*fade_duration_ms*/);
if (monkey_spawn && game->play.current_wave != 0) { if (monkey_spawn && game->play.current_wave != 0) {
// NOTE: We spawn a monkey at these wave intervals; // NOTE: We spawn a monkey at these wave intervals;
@ -2031,6 +2047,7 @@ static void FP_Update(TELY_OS *os, FP_Game *game, TELY_OSInput *input, TELY_Audi
} }
game->play.current_wave++; game->play.current_wave++;
//TELY_Audio_Stop(audio, game->audio[FP_GameAudio_Music2]);
} }
} }
@ -2421,27 +2438,27 @@ static void FP_Update(TELY_OS *os, FP_Game *game, TELY_OSInput *input, TELY_Audi
Dqn_Profiler_EndZone(update_zone); Dqn_Profiler_EndZone(update_zone);
} }
static Dqn_Str8 FP_ScanKeyToLabel(Dqn_Arena *arena, TELY_OSInputScanKey scan_key) static Dqn_Str8 FP_ScanKeyToLabel(Dqn_Arena *arena, TELY_InputScanKey scan_key)
{ {
Dqn_Str8 result = {}; Dqn_Str8 result = {};
Dqn_Allocator allocator = Dqn_Arena_Allocator(arena); Dqn_Allocator allocator = Dqn_Arena_Allocator(arena);
if (scan_key >= TELY_OSInputScanKey_A && scan_key <= TELY_OSInputScanKey_Z) { if (scan_key >= TELY_InputScanKey_A && scan_key <= TELY_InputScanKey_Z) {
char scan_key_ch = DQN_CAST(char)('A' + (scan_key - TELY_OSInputScanKey_A)); char scan_key_ch = DQN_CAST(char)('A' + (scan_key - TELY_InputScanKey_A));
result = Dqn_Str8_InitF(allocator, "[%c]", scan_key_ch); result = Dqn_Str8_InitF(allocator, "[%c]", scan_key_ch);
} else { } else {
if (scan_key == TELY_OSInputScanKey_Up) { if (scan_key == TELY_InputScanKey_Up) {
result = Dqn_Str8_InitF(allocator, "[Up]"); result = Dqn_Str8_InitF(allocator, "[Up]");
} else if (scan_key == TELY_OSInputScanKey_Down) { } else if (scan_key == TELY_InputScanKey_Down) {
result = Dqn_Str8_InitF(allocator, "[Down]"); result = Dqn_Str8_InitF(allocator, "[Down]");
} else if (scan_key == TELY_OSInputScanKey_Left) { } else if (scan_key == TELY_InputScanKey_Left) {
result = Dqn_Str8_InitF(allocator, "[Left]"); result = Dqn_Str8_InitF(allocator, "[Left]");
} else if (scan_key == TELY_OSInputScanKey_Right) { } else if (scan_key == TELY_InputScanKey_Right) {
result = Dqn_Str8_InitF(allocator, "[Right]"); result = Dqn_Str8_InitF(allocator, "[Right]");
} else if (scan_key == TELY_OSInputScanKey_Semicolon) { } else if (scan_key == TELY_InputScanKey_Semicolon) {
result = Dqn_Str8_InitF(allocator, "[;]"); result = Dqn_Str8_InitF(allocator, "[;]");
} else if (scan_key == TELY_OSInputScanKey_Apostrophe) { } else if (scan_key == TELY_InputScanKey_Apostrophe) {
result = Dqn_Str8_InitF(allocator, "[']"); result = Dqn_Str8_InitF(allocator, "[']");
} else if (scan_key == TELY_OSInputScanKey_Backslash) { } else if (scan_key == TELY_InputScanKey_Backslash) {
result = Dqn_Str8_InitF(allocator, "[/]"); result = Dqn_Str8_InitF(allocator, "[/]");
} }
} }
@ -2464,13 +2481,13 @@ static void FP_DrawBillboardKeyBindHint(TELY_Renderer *renderer,
if (mode == FP_GameControlMode_Gamepad) { if (mode == FP_GameControlMode_Gamepad) {
Dqn_Str8 tex_name = {}; Dqn_Str8 tex_name = {};
if (key_bind.gamepad_key == TELY_OSInputGamepadKey_A) if (key_bind.gamepad_key == TELY_InputGamepadKey_A)
tex_name = g_anim_names.merchant_button_a; tex_name = g_anim_names.merchant_button_a;
else if (key_bind.gamepad_key == TELY_OSInputGamepadKey_B) else if (key_bind.gamepad_key == TELY_InputGamepadKey_B)
tex_name = g_anim_names.merchant_button_b; tex_name = g_anim_names.merchant_button_b;
else if (key_bind.gamepad_key == TELY_OSInputGamepadKey_X) else if (key_bind.gamepad_key == TELY_InputGamepadKey_X)
tex_name = g_anim_names.merchant_button_x; tex_name = g_anim_names.merchant_button_x;
else if (key_bind.gamepad_key == TELY_OSInputGamepadKey_Y) else if (key_bind.gamepad_key == TELY_InputGamepadKey_Y)
tex_name = g_anim_names.merchant_button_y; tex_name = g_anim_names.merchant_button_y;
if (tex_name.size) { if (tex_name.size) {
@ -2501,7 +2518,7 @@ static void FP_DrawBillboardKeyBindHint(TELY_Renderer *renderer,
static void FP_Render(FP_Game *game, TELY_OS *os, 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); Dqn_Profiler_ZoneScopeWithIndex("FP_Render", FP_ProfileZone_FPRender);
TELY_OSInput *input = &os->input; TELY_Input *input = &os->input;
TELY_RFui *rfui = &game->rfui; TELY_RFui *rfui = &game->rfui;
TELY_Assets *assets = &os->assets; TELY_Assets *assets = &os->assets;
@ -3020,6 +3037,7 @@ static void FP_Render(FP_Game *game, TELY_OS *os, TELY_Renderer *renderer, TELY_
game->play.perry_join_splash_screen_shake_triggered = true; game->play.perry_join_splash_screen_shake_triggered = true;
game->play.perry_join_flash_alpha = 1.f; game->play.perry_join_flash_alpha = 1.f;
game->play.perry_join_splash_screen_end_ms = game->play.clock_ms + 2000; game->play.perry_join_splash_screen_end_ms = game->play.clock_ms + 2000;
TELY_Audio_Play(audio, game->audio[FP_GameAudio_PerryStart], 1.f);
} }
} }
@ -3302,13 +3320,13 @@ static void FP_Render(FP_Game *game, TELY_OS *os, TELY_Renderer *renderer, TELY_
bool trigger_buy_anim = false; bool trigger_buy_anim = false;
if (have_enough_coins) { if (have_enough_coins) {
if (TELY_OSInput_ScanKeyIsPressed(input, key_bind.scan_key)) { if (TELY_Input_ScanKeyIsPressed(input, key_bind.scan_key)) {
game->play.player_trigger_purchase_building_timestamp = game->play.clock_ms + buy_duration_ms; game->play.player_trigger_purchase_building_timestamp = game->play.clock_ms + buy_duration_ms;
} else if (TELY_OSInput_ScanKeyIsDown(input, key_bind.scan_key)) { } else if (TELY_Input_ScanKeyIsDown(input, key_bind.scan_key)) {
trigger_buy_anim = true; trigger_buy_anim = true;
if (game->play.clock_ms > game->play.player_trigger_purchase_building_timestamp) if (game->play.clock_ms > game->play.player_trigger_purchase_building_timestamp)
game->play.player_trigger_purchase_building_timestamp = game->play.clock_ms; game->play.player_trigger_purchase_building_timestamp = game->play.clock_ms;
} else if (TELY_OSInput_ScanKeyIsReleased(input, key_bind.scan_key)) { } else if (TELY_Input_ScanKeyIsReleased(input, key_bind.scan_key)) {
if (game->play.clock_ms > game->play.player_trigger_purchase_building_timestamp) { if (game->play.clock_ms > game->play.player_trigger_purchase_building_timestamp) {
if (mapping.inventory_count) { if (mapping.inventory_count) {
player->coins -= *mapping.building_base_price; player->coins -= *mapping.building_base_price;
@ -3434,13 +3452,13 @@ static void FP_Render(FP_Game *game, TELY_OS *os, TELY_Renderer *renderer, TELY_
bool trigger_buy_anim = false; bool trigger_buy_anim = false;
if (have_enough_coins) { if (have_enough_coins) {
if (TELY_OSInput_ScanKeyIsPressed(input, key_bind.scan_key)) { if (TELY_Input_ScanKeyIsPressed(input, key_bind.scan_key)) {
game->play.player_trigger_purchase_upgrade_timestamp = game->play.clock_ms + buy_duration_ms; game->play.player_trigger_purchase_upgrade_timestamp = game->play.clock_ms + buy_duration_ms;
} else if (TELY_OSInput_ScanKeyIsDown(input, key_bind.scan_key)) { } else if (TELY_Input_ScanKeyIsDown(input, key_bind.scan_key)) {
trigger_buy_anim = true; trigger_buy_anim = true;
if (game->play.clock_ms > game->play.player_trigger_purchase_upgrade_timestamp) if (game->play.clock_ms > game->play.player_trigger_purchase_upgrade_timestamp)
game->play.player_trigger_purchase_upgrade_timestamp = game->play.clock_ms; game->play.player_trigger_purchase_upgrade_timestamp = game->play.clock_ms;
} else if (TELY_OSInput_ScanKeyIsReleased(input, key_bind.scan_key)) { } else if (TELY_Input_ScanKeyIsReleased(input, key_bind.scan_key)) {
if (game->play.clock_ms > game->play.player_trigger_purchase_upgrade_timestamp) { if (game->play.clock_ms > game->play.player_trigger_purchase_upgrade_timestamp) {
player->coins -= *mapping.upgrade_base_price; player->coins -= *mapping.upgrade_base_price;
*mapping.upgrade_base_price *= 1; *mapping.upgrade_base_price *= 1;
@ -3978,7 +3996,7 @@ static void FP_Render(FP_Game *game, TELY_OS *os, TELY_Renderer *renderer, TELY_
TELY_Render_PopFont(renderer); TELY_Render_PopFont(renderer);
TELY_Render_PopColourV4(renderer); TELY_Render_PopColourV4(renderer);
if (TELY_OSInput_ScanKeyIsPressed(input, TELY_OSInputScanKey_Return)) if (TELY_Input_ScanKeyIsPressed(input, TELY_InputScanKey_Return))
game->play.state = FP_GameState_Play; game->play.state = FP_GameState_Play;
} }
@ -4123,8 +4141,10 @@ static void FP_Render(FP_Game *game, TELY_OS *os, TELY_Renderer *renderer, TELY_
if (new_player.yes) { if (new_player.yes) {
if (new_player.tutorial_requested) { if (new_player.tutorial_requested) {
game->play.state = FP_GameState_Tutorial; game->play.state = FP_GameState_Tutorial;
TELY_Audio_Play(audio, game->audio[FP_GameAudio_GameStart], 1.f);
} else { } else {
game->play.state = FP_GameState_Play; game->play.state = FP_GameState_Play;
TELY_Audio_Play(audio, game->audio[FP_GameAudio_GameStart], 1.f);
} }
} }
} else { } else {
@ -4140,7 +4160,7 @@ static void FP_Render(FP_Game *game, TELY_OS *os, TELY_Renderer *renderer, TELY_
TELY_Render_PopFont(renderer); TELY_Render_PopFont(renderer);
TELY_Render_PopColourV4(renderer); TELY_Render_PopColourV4(renderer);
if (TELY_OSInput_ScanKeyIsPressed(input, TELY_OSInputScanKey_Return)) if (TELY_Input_ScanKeyIsPressed(input, TELY_InputScanKey_Return))
FP_PlayReset(game, os); FP_PlayReset(game, os);
} }
@ -4188,7 +4208,7 @@ static void FP_Render(FP_Game *game, TELY_OS *os, TELY_Renderer *renderer, TELY_
// NOTE: Debug UI ============================================================================== // NOTE: Debug UI ==============================================================================
if (TELY_OSInput_ScanKeyIsPressed(input, TELY_OSInputScanKey_F1)) if (TELY_Input_ScanKeyIsPressed(input, TELY_InputScanKey_F1))
game->play.debug_ui = !game->play.debug_ui; game->play.debug_ui = !game->play.debug_ui;
DQN_MSVC_WARNING_PUSH DQN_MSVC_WARNING_PUSH
@ -4269,23 +4289,23 @@ static void FP_Render(FP_Game *game, TELY_OS *os, TELY_Renderer *renderer, TELY_
if (TELY_RFui_ButtonF(rfui, "F1 Debug info").clicked) if (TELY_RFui_ButtonF(rfui, "F1 Debug info").clicked)
game->play.debug_ui = !game->play.debug_ui; game->play.debug_ui = !game->play.debug_ui;
if (TELY_RFui_ButtonF(rfui, "F2 Add coins x10,000").clicked || TELY_OSInput_ScanKeyIsPressed(input, TELY_OSInputScanKey_F2)) { if (TELY_RFui_ButtonF(rfui, "F2 Add coins x10,000").clicked || TELY_Input_ScanKeyIsPressed(input, TELY_InputScanKey_F2)) {
for (FP_GameEntityHandle player_handle : game->play.players) { for (FP_GameEntityHandle player_handle : game->play.players) {
FP_GameEntity *player = FP_Game_GetEntity(game, player_handle); FP_GameEntity *player = FP_Game_GetEntity(game, player_handle);
player->coins += 10'000; player->coins += 10'000;
} }
} }
if (TELY_RFui_ButtonF(rfui, "F3 Win game").clicked || TELY_OSInput_ScanKeyIsPressed(input, TELY_OSInputScanKey_F3)) if (TELY_RFui_ButtonF(rfui, "F3 Win game").clicked || TELY_Input_ScanKeyIsPressed(input, TELY_InputScanKey_F3))
game->play.state = FP_GameState_WinGame; game->play.state = FP_GameState_WinGame;
if (TELY_RFui_ButtonF(rfui, "F4 Lose game").clicked || TELY_OSInput_ScanKeyIsPressed(input, TELY_OSInputScanKey_F4)) if (TELY_RFui_ButtonF(rfui, "F4 Lose game").clicked || TELY_Input_ScanKeyIsPressed(input, TELY_InputScanKey_F4))
game->play.state = FP_GameState_LoseGame; game->play.state = FP_GameState_LoseGame;
if (TELY_RFui_ButtonF(rfui, "F5 Reset game").clicked || TELY_OSInput_ScanKeyIsPressed(input, TELY_OSInputScanKey_F5)) if (TELY_RFui_ButtonF(rfui, "F5 Reset game").clicked || TELY_Input_ScanKeyIsPressed(input, TELY_InputScanKey_F5))
FP_PlayReset(game, os); FP_PlayReset(game, os);
if (TELY_RFui_ButtonF(rfui, "F6 Increase health").clicked || TELY_OSInput_ScanKeyIsPressed(input, TELY_OSInputScanKey_F6)) { if (TELY_RFui_ButtonF(rfui, "F6 Increase health").clicked || TELY_Input_ScanKeyIsPressed(input, TELY_InputScanKey_F6)) {
for (FP_GameEntityHandle player_handle : game->play.players) { for (FP_GameEntityHandle player_handle : game->play.players) {
FP_GameEntity *player = FP_Game_GetEntity(game, player_handle); FP_GameEntity *player = FP_Game_GetEntity(game, player_handle);
player->hp_cap += FP_DEFAULT_DAMAGE; player->hp_cap += FP_DEFAULT_DAMAGE;
@ -4293,7 +4313,7 @@ static void FP_Render(FP_Game *game, TELY_OS *os, TELY_Renderer *renderer, TELY_
} }
} }
if (TELY_RFui_ButtonF(rfui, "F7 Increase stamina").clicked || TELY_OSInput_ScanKeyIsPressed(input, TELY_OSInputScanKey_F7)) { if (TELY_RFui_ButtonF(rfui, "F7 Increase stamina").clicked || TELY_Input_ScanKeyIsPressed(input, TELY_InputScanKey_F7)) {
for (FP_GameEntityHandle player_handle : game->play.players) { for (FP_GameEntityHandle player_handle : game->play.players) {
FP_GameEntity *player = FP_Game_GetEntity(game, player_handle); FP_GameEntity *player = FP_Game_GetEntity(game, player_handle);
player->stamina_cap += DQN_CAST(uint16_t)(FP_TERRY_DASH_STAMINA_COST * .5f); player->stamina_cap += DQN_CAST(uint16_t)(FP_TERRY_DASH_STAMINA_COST * .5f);
@ -4301,7 +4321,7 @@ static void FP_Render(FP_Game *game, TELY_OS *os, TELY_Renderer *renderer, TELY_
} }
} }
if (TELY_RFui_ButtonF(rfui, "F8 Increase mobile data").clicked || TELY_OSInput_ScanKeyIsPressed(input, TELY_OSInputScanKey_F8)) { if (TELY_RFui_ButtonF(rfui, "F8 Increase mobile data").clicked || TELY_Input_ScanKeyIsPressed(input, TELY_InputScanKey_F8)) {
for (FP_GameEntityHandle player_handle : game->play.players) { for (FP_GameEntityHandle player_handle : game->play.players) {
FP_GameEntity *player = FP_Game_GetEntity(game, player_handle); FP_GameEntity *player = FP_Game_GetEntity(game, player_handle);
player->terry_mobile_data_plan_cap += DQN_KILOBYTES(1); player->terry_mobile_data_plan_cap += DQN_KILOBYTES(1);
@ -4309,10 +4329,10 @@ static void FP_Render(FP_Game *game, TELY_OS *os, TELY_Renderer *renderer, TELY_
} }
} }
if (TELY_RFui_ButtonF(rfui, "F9 %s god mode", game->play.god_mode ? "Disable" : "Enable").clicked || TELY_OSInput_ScanKeyIsPressed(input, TELY_OSInputScanKey_F9)) if (TELY_RFui_ButtonF(rfui, "F9 %s god mode", game->play.god_mode ? "Disable" : "Enable").clicked || TELY_Input_ScanKeyIsPressed(input, TELY_InputScanKey_F9))
game->play.god_mode = !game->play.god_mode; game->play.god_mode = !game->play.god_mode;
if (TELY_RFui_ButtonF(rfui, "F11 Building inventory +1").clicked || TELY_OSInput_ScanKeyIsPressed(input, TELY_OSInputScanKey_F11)) { if (TELY_RFui_ButtonF(rfui, "F11 Building inventory +1").clicked || TELY_Input_ScanKeyIsPressed(input, TELY_InputScanKey_F11)) {
for (FP_GameEntityHandle player_handle : game->play.players) { for (FP_GameEntityHandle player_handle : game->play.players) {
FP_GameEntity *player = FP_Game_GetEntity(game, player_handle); FP_GameEntity *player = FP_Game_GetEntity(game, player_handle);
player->inventory.clubs += 1; player->inventory.clubs += 1;
@ -4322,7 +4342,7 @@ static void FP_Render(FP_Game *game, TELY_OS *os, TELY_Renderer *renderer, TELY_
} }
} }
if (TELY_RFui_ButtonF(rfui, "1 %s HUD", game->play.debug_hide_hud ? "Show" : "Hide").clicked || TELY_OSInput_ScanKeyIsPressed(input, TELY_OSInputScanKey_1)) if (TELY_RFui_ButtonF(rfui, "1 %s HUD", game->play.debug_hide_hud ? "Show" : "Hide").clicked || TELY_Input_ScanKeyIsPressed(input, TELY_InputScanKey_1))
game->play.debug_hide_hud = !game->play.debug_hide_hud; 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) if (TELY_RFui_ButtonF(rfui, "%s bounding rects", game->play.debug_hide_bounding_rectangles ? "Show" : "Hide").clicked)
@ -4429,7 +4449,7 @@ static void FP_Render(FP_Game *game, TELY_OS *os, TELY_Renderer *renderer, TELY_
TELY_OS_DLL_FUNCTION TELY_OS_DLL_FUNCTION
void TELY_OS_DLLFrameUpdate(TELY_OS *os) void TELY_OS_DLLFrameUpdate(TELY_OS *os)
{ {
TELY_OSInput *input = &os->input; TELY_Input *input = &os->input;
TELY_Renderer *renderer = &os->renderer; TELY_Renderer *renderer = &os->renderer;
FP_Game *game = DQN_CAST(FP_Game *) os->user_data; FP_Game *game = DQN_CAST(FP_Game *) os->user_data;
@ -4445,18 +4465,8 @@ void TELY_OS_DLLFrameUpdate(TELY_OS *os)
// ============================================================================================= // =============================================================================================
TELY_Audio *audio = &os->audio;
#if 0
if (audio->playback_size == 0) {
TELY_Audio_Play(audio, game->audio[FP_GameAudio_TestAudio], 1.f /*volume*/);
}
#endif
// =============================================================================================
if (game->play.state == FP_GameState_Play || game->play.state == FP_GameState_Tutorial) { if (game->play.state == FP_GameState_Play || game->play.state == FP_GameState_Tutorial) {
if (TELY_OSInput_KeyWasDown(input->mouse_left) && TELY_OSInput_KeyIsDown(input->mouse_left)) { if (TELY_Input_KeyWasDown(input->mouse_keys[TELY_InputMouseKey_Left]) && TELY_Input_KeyIsDown(input->mouse_keys[TELY_InputMouseKey_Left])) {
if (game->play.prev_active_entity.id) if (game->play.prev_active_entity.id)
game->play.active_entity = game->play.prev_active_entity; game->play.active_entity = game->play.prev_active_entity;
} else { } else {
@ -4476,7 +4486,7 @@ void TELY_OS_DLLFrameUpdate(TELY_OS *os)
continue; continue;
game->play.hot_entity = entity->handle; game->play.hot_entity = entity->handle;
if (TELY_OSInput_KeyIsPressed(input->mouse_left)) { if (TELY_Input_KeyIsPressed(input->mouse_keys[TELY_InputMouseKey_Left])) {
game->play.active_entity = entity->handle; game->play.active_entity = entity->handle;
game->play.clicked_entity = entity->handle; game->play.clicked_entity = entity->handle;
} }
@ -4484,6 +4494,7 @@ void TELY_OS_DLLFrameUpdate(TELY_OS *os)
} }
} }
TELY_Audio *audio = &os->audio;
for (game->play.delta_s_accumulator += DQN_CAST(Dqn_f32)input->delta_s; 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;
game->play.delta_s_accumulator -= FP_GAME_PHYSICS_STEP) { game->play.delta_s_accumulator -= FP_GAME_PHYSICS_STEP) {

File diff suppressed because it is too large Load Diff

View File

@ -3,24 +3,24 @@
#include "feely_pona_unity.h" #include "feely_pona_unity.h"
#endif #endif
static bool FP_Game_KeyBindIsPressed(TELY_OSInput const *input, FP_GameControls const *controls, FP_GameKeyBind key_bind) static bool FP_Game_KeyBindIsPressed(TELY_Input const *input, FP_GameControls const *controls, FP_GameKeyBind key_bind)
{ {
bool result = false; bool result = false;
if (controls->mode == FP_GameControlMode_Keyboard) { if (controls->mode == FP_GameControlMode_Keyboard) {
result = TELY_OSInput_ScanKeyIsPressed(input, key_bind.scan_key); result = TELY_Input_ScanKeyIsPressed(input, key_bind.scan_key);
} else { } else {
result = TELY_OSInput_GamepadKeyIsPressed(input, controls->gamepad_index, key_bind.gamepad_key); result = TELY_Input_GamepadKeyIsPressed(input, controls->gamepad_index, key_bind.gamepad_key);
} }
return result; return result;
} }
static bool FP_Game_KeyBindIsDown(TELY_OSInput const *input, FP_GameControls const *controls, FP_GameKeyBind key_bind) static bool FP_Game_KeyBindIsDown(TELY_Input const *input, FP_GameControls const *controls, FP_GameKeyBind key_bind)
{ {
bool result = false; bool result = false;
if (controls->mode == FP_GameControlMode_Keyboard) { if (controls->mode == FP_GameControlMode_Keyboard) {
result = TELY_OSInput_ScanKeyIsDown(input, key_bind.scan_key); result = TELY_Input_ScanKeyIsDown(input, key_bind.scan_key);
} else { } else {
result = TELY_OSInput_GamepadKeyIsDown(input, controls->gamepad_index, key_bind.gamepad_key); result = TELY_Input_GamepadKeyIsDown(input, controls->gamepad_index, key_bind.gamepad_key);
} }
return result; return result;
} }
@ -292,19 +292,6 @@ static FP_GameEntity *FP_Game_MakeEntityPointerF(FP_Game *game, DQN_FMT_ATTRIB c
return result; return result;
} }
static FP_GameEntityHandle FP_Game_MakeEntityF(FP_Game *game, DQN_FMT_ATTRIB char const *fmt, ...)
{
va_list args;
va_start(args, fmt);
FP_GameEntity *entity = FP_Game_MakeEntityPointerF(game, fmt, args);
va_end(args);
FP_GameEntityHandle result = {};
if (entity)
result = entity->handle;
return result;
}
static bool FP_Game_IsNilEntity(FP_GameEntity *entity) static bool FP_Game_IsNilEntity(FP_GameEntity *entity)
{ {
bool result = entity ? ((entity->handle.id & FP_GAME_ENTITY_HANDLE_INDEX_MASK) == 0) : true; bool result = entity ? ((entity->handle.id & FP_GAME_ENTITY_HANDLE_INDEX_MASK) == 0) : true;
@ -537,18 +524,6 @@ static void FP_Game_EntityActionReset(FP_Game *game, FP_GameEntityHandle entity_
entity->action.end_at_clock_ms = DQN_MAX(duration_ms, game->play.clock_ms + duration_ms); entity->action.end_at_clock_ms = DQN_MAX(duration_ms, game->play.clock_ms + duration_ms);
} }
static Dqn_V2I FP_Game_WorldPosToTilePos(FP_Game *game, Dqn_V2 world_pos)
{
Dqn_V2I result = Dqn_V2I_InitNx2(world_pos.x / game->play.tile_size, world_pos.y / game->play.tile_size);
return result;
}
static Dqn_V2 FP_Game_TilePosToWorldPos(FP_Game *game, Dqn_V2I tile_pos)
{
Dqn_V2 result = Dqn_V2_InitNx2(tile_pos.x * game->play.tile_size, tile_pos.y * game->play.tile_size);
return result;
}
static Dqn_V2 FP_Game_CalcWaypointWorldPos(FP_Game *game, FP_GameEntityHandle entity_handle, FP_GameWaypoint const *waypoint) static Dqn_V2 FP_Game_CalcWaypointWorldPos(FP_Game *game, FP_GameEntityHandle entity_handle, FP_GameWaypoint const *waypoint)
{ {
Dqn_V2 result = {}; Dqn_V2 result = {};

View File

@ -168,8 +168,8 @@ enum FP_GameInGameMenu
struct FP_GameKeyBind struct FP_GameKeyBind
{ {
TELY_OSInputScanKey scan_key; TELY_InputScanKey scan_key;
TELY_OSInputGamepadKey gamepad_key; TELY_InputGamepadKey gamepad_key;
}; };
enum FP_GameControlMode enum FP_GameControlMode
@ -334,6 +334,12 @@ enum FP_GameAudio
FP_GameAudio_Message, FP_GameAudio_Message,
FP_GameAudio_Monkey, FP_GameAudio_Monkey,
FP_GameAudio_PortalDestroy, FP_GameAudio_PortalDestroy,
FP_GameAudio_GameStart,
FP_GameAudio_PerryStart,
FP_GameAudio_Ambience1,
FP_GameAudio_Ambience2,
FP_GameAudio_Music1,
FP_GameAudio_Music2,
FP_GameAudio_Count, FP_GameAudio_Count,
}; };
@ -475,15 +481,17 @@ struct FP_Game
TELY_AssetFontHandle jetbrains_mono_font; TELY_AssetFontHandle jetbrains_mono_font;
TELY_AssetFontHandle talkco_font; TELY_AssetFontHandle talkco_font;
TELY_AssetAudioHandle audio[FP_GameAudio_Count]; TELY_AssetAudioHandle audio[FP_GameAudio_Count];
TELY_AssetSpriteSheet atlas_sprite_sheet; TELY_AudioPlaybackHandle bg_music1;
TELY_RFui rfui; TELY_AudioPlaybackHandle bg_music2;
FP_GamePlay play; TELY_AssetSpriteSheet atlas_sprite_sheet;
Dqn_Arena *frame_arena; TELY_RFui rfui;
uint16_t font_size; FP_GamePlay play;
uint16_t large_font_size; Dqn_Arena *frame_arena;
uint16_t large_talkco_font_size; uint16_t font_size;
uint16_t xlarge_talkco_font_size; uint16_t large_font_size;
uint16_t large_talkco_font_size;
uint16_t xlarge_talkco_font_size;
}; };
struct FP_GameAStarNode struct FP_GameAStarNode

View File

@ -8,6 +8,8 @@
#define DQN_ONLY_DSMAP #define DQN_ONLY_DSMAP
#define DQN_ONLY_LIST #define DQN_ONLY_LIST
#define DQN_ONLY_FS #define DQN_ONLY_FS
#define DQN_ONLY_SEMAPHORE
#define DQN_ONLY_THREAD
#define _CRT_SECURE_NO_WARNINGS #define _CRT_SECURE_NO_WARNINGS
#define DQN_IMPLEMENTATION #define DQN_IMPLEMENTATION
#include "External/tely/External/dqn/dqn.h" #include "External/tely/External/dqn/dqn.h"
@ -15,13 +17,13 @@
DQN_MSVC_WARNING_PUSH DQN_MSVC_WARNING_PUSH
DQN_MSVC_WARNING_DISABLE(4244) // warning C4244: 'argument': conversion from 'int' to 'short', possible loss of data DQN_MSVC_WARNING_DISABLE(4244) // warning C4244: 'argument': conversion from 'int' to 'short', possible loss of data
#define STB_RECT_PACK_IMPLEMENTATION #define STB_RECT_PACK_IMPLEMENTATION
#include "External/tely/external/stb/stb_rect_pack.h" #include "External/tely/External/stb/stb_rect_pack.h"
#define STB_IMAGE_WRITE_IMPLEMENTATION #define STB_IMAGE_WRITE_IMPLEMENTATION
#include "External/tely/external/stb/stb_image_write.h" #include "External/tely/External/stb/stb_image_write.h"
#define STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_IMPLEMENTATION
#include "External/tely/external/stb/stb_image.h" #include "External/tely/External/stb/stb_image.h"
DQN_MSVC_WARNING_POP DQN_MSVC_WARNING_POP
DQN_MSVC_WARNING_PUSH DQN_MSVC_WARNING_PUSH

View File

@ -2,7 +2,7 @@
// Unity build header to compile the entire application as a single translation unit // Unity build header to compile the entire application as a single translation unit
#define TELY_PLATFORM_DLL_FILE_NAME "terry_cherry_dev_dll" #define TELY_PLATFORM_DLL_FILE_NAME "terry_cherry_dev_dll"
#include "External/tely/tely_os_raylib_unity.h" #include "External/tely/tely_backend_raylib_unity.h"
// NOTE: feely_pona ================================================================================ // NOTE: feely_pona ================================================================================
#if defined(_CLANGD) || defined(FEELY_PONA_IMPLEMENTATION) #if defined(_CLANGD) || defined(FEELY_PONA_IMPLEMENTATION)

Binary file not shown.