fp: Add key binding support for p2
This commit is contained in:
parent
13af438612
commit
85fe5c8ff7
2
External/tely
vendored
2
External/tely
vendored
@ -1 +1 @@
|
|||||||
Subproject commit c1056434f07a1f2b12378fee6c5ed33941e2bfcb
|
Subproject commit e1f11120a2a3a2673317db52d73ae30a71faf172
|
428
feely_pona.cpp
428
feely_pona.cpp
@ -89,6 +89,83 @@ static TELY_AssetSpriteSheet FP_LoadSpriteSheetFromSpec(TELY_Platform *platform,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void FP_SetDefaultGamepadBindings(FP_GameControls *controls)
|
||||||
|
{
|
||||||
|
controls->up.gamepad_key = TELY_PlatformInputGamepadKey_DUp;
|
||||||
|
controls->down.gamepad_key = TELY_PlatformInputGamepadKey_DDown;
|
||||||
|
controls->left.gamepad_key = TELY_PlatformInputGamepadKey_DLeft;
|
||||||
|
controls->right.gamepad_key = TELY_PlatformInputGamepadKey_DRight;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool FP_ListenForNewPlayer(TELY_PlatformInput *input, FP_Game *game)
|
||||||
|
{
|
||||||
|
bool result = false;
|
||||||
|
if (game->play.players.size == 2)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
FP_GamePlay *play = &game->play;
|
||||||
|
uint32_t gamepad_index = 0;
|
||||||
|
if (play->players.size) {
|
||||||
|
FP_GameEntityHandle first_player_handle = play->players.data[0];
|
||||||
|
FP_GameEntity *player = FP_Game_GetEntity(game, first_player_handle);
|
||||||
|
if (player->controls.mode == FP_GameControlMode_Gamepad)
|
||||||
|
gamepad_index = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool keyboard_pressed = TELY_Platform_InputScanCodeIsPressed(input, TELY_PlatformInputScanCode_B);
|
||||||
|
bool gamepad_pressed = TELY_Platform_InputGamepadKeyIsPressed(input, gamepad_index, TELY_PlatformInputGamepadKey_Start);
|
||||||
|
|
||||||
|
if (keyboard_pressed || gamepad_pressed) {
|
||||||
|
FP_GameEntityHandle terry_handle = FP_Entity_CreateTerry(game, Dqn_V2_InitNx2(1380, 11), "Terry");
|
||||||
|
Dqn_FArray_Add(&play->players, terry_handle);
|
||||||
|
|
||||||
|
FP_GameEntity *terry = FP_Game_GetEntity(game, terry_handle);
|
||||||
|
FP_GameControls *controls = &terry->controls;
|
||||||
|
if (keyboard_pressed) {
|
||||||
|
controls->mode = FP_GameControlMode_Keyboard;
|
||||||
|
if (play->players.size == 1) {
|
||||||
|
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_G;
|
||||||
|
controls->range_attack.scan_code = TELY_PlatformInputScanCode_H;
|
||||||
|
controls->build_mode.scan_code = TELY_PlatformInputScanCode_F;
|
||||||
|
controls->strafe.scan_code = TELY_PlatformInputScanCode_J;
|
||||||
|
controls->dash.scan_code = TELY_PlatformInputScanCode_V;
|
||||||
|
controls->buy_building.scan_code = TELY_PlatformInputScanCode_T;
|
||||||
|
controls->buy_upgrade.scan_code = TELY_PlatformInputScanCode_Y;
|
||||||
|
} else {
|
||||||
|
controls->up.scan_code = TELY_PlatformInputScanCode_O;
|
||||||
|
controls->down.scan_code = TELY_PlatformInputScanCode_L;
|
||||||
|
controls->left.scan_code = TELY_PlatformInputScanCode_K;
|
||||||
|
controls->right.scan_code = TELY_PlatformInputScanCode_Semicolon;
|
||||||
|
controls->attack.scan_code = TELY_PlatformInputScanCode_Right;
|
||||||
|
controls->range_attack.scan_code = TELY_PlatformInputScanCode_Left;
|
||||||
|
controls->build_mode.scan_code = TELY_PlatformInputScanCode_Up;
|
||||||
|
controls->strafe.scan_code = TELY_PlatformInputScanCode_N;
|
||||||
|
controls->dash.scan_code = TELY_PlatformInputScanCode_Down;
|
||||||
|
controls->buy_building.scan_code = TELY_PlatformInputScanCode_Backslash;
|
||||||
|
controls->buy_upgrade.scan_code = TELY_PlatformInputScanCode_Apostrophe;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
controls->mode = FP_GameControlMode_Gamepad;
|
||||||
|
controls->gamepad_index = gamepad_index;
|
||||||
|
FP_SetDefaultGamepadBindings(controls);
|
||||||
|
}
|
||||||
|
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
static void FP_PlayReset(FP_Game *game, TELY_Platform *platform)
|
static void FP_PlayReset(FP_Game *game, TELY_Platform *platform)
|
||||||
{
|
{
|
||||||
FP_GamePlay *play = &game->play;
|
FP_GamePlay *play = &game->play;
|
||||||
@ -240,47 +317,6 @@ static void FP_PlayReset(FP_Game *game, TELY_Platform *platform)
|
|||||||
Dqn_FArray_Add(&play->portal_monkeys, monkey_c);
|
Dqn_FArray_Add(&play->portal_monkeys, monkey_c);
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: Hero ==================================================================================
|
|
||||||
{
|
|
||||||
FP_GameEntityHandle terry_handle = FP_Entity_CreateTerry(game, Dqn_V2_InitNx2(1434, 11), "Terry");
|
|
||||||
Dqn_FArray_Add(&game->play.players, terry_handle);
|
|
||||||
play->clicked_entity = terry_handle;
|
|
||||||
|
|
||||||
FP_GameEntity *terry = FP_Game_GetEntity(game, terry_handle);
|
|
||||||
FP_GameControls *controls = &terry->controls;
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
FP_GameEntityHandle terry_handle = FP_Entity_CreateTerry(game, Dqn_V2_InitNx2(1380, 11), "Terry 2");
|
|
||||||
Dqn_FArray_Add(&game->play.players, terry_handle);
|
|
||||||
play->clicked_entity = terry_handle;
|
|
||||||
|
|
||||||
FP_GameEntity *terry = FP_Game_GetEntity(game, terry_handle);
|
|
||||||
FP_GameControls *controls = &terry->controls;
|
|
||||||
controls->up.scan_code = TELY_PlatformInputScanCode_Up;
|
|
||||||
controls->down.scan_code = TELY_PlatformInputScanCode_Down;
|
|
||||||
controls->left.scan_code = TELY_PlatformInputScanCode_Left;
|
|
||||||
controls->right.scan_code = TELY_PlatformInputScanCode_Right;
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
Dqn_V2 base_top_left_pos = Dqn_V2_InitNx2(1018, -335);
|
Dqn_V2 base_top_left_pos = Dqn_V2_InitNx2(1018, -335);
|
||||||
Dqn_V2 base_bottom_right_pos = Dqn_V2_InitNx2(2050, +351);
|
Dqn_V2 base_bottom_right_pos = Dqn_V2_InitNx2(2050, +351);
|
||||||
@ -434,6 +470,28 @@ static void FP_AppendMobSpawnerWaypoints(FP_Game *game, FP_GameEntityHandle src_
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool FP_Game_KeyBindIsPressed(TELY_PlatformInput 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);
|
||||||
|
} else {
|
||||||
|
result = TELY_Platform_InputGamepadKeyIsPressed(input, controls->gamepad_index, key_bind.gamepad_key);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FP_Game_KeyBindIsDown(TELY_PlatformInput 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);
|
||||||
|
} else {
|
||||||
|
result = TELY_Platform_InputGamepadKeyIsDown(input, controls->gamepad_index, key_bind.gamepad_key);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_PlatformInput *input, FP_GameEntity *entity, Dqn_V2 *acceleration_meters_per_s)
|
void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_PlatformInput *input, FP_GameEntity *entity, Dqn_V2 *acceleration_meters_per_s)
|
||||||
{
|
{
|
||||||
@ -488,11 +546,9 @@ void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_Platform
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (FP_Game_IsNilEntityHandle(game, entity->carried_monkey)) {
|
if (FP_Game_IsNilEntityHandle(game, entity->carried_monkey)) {
|
||||||
if (TELY_Platform_InputScanCodeIsPressed(input, controls->attack.scan_code) ||
|
if (FP_Game_KeyBindIsPressed(input, controls, controls->attack)) {
|
||||||
TELY_Platform_InputGamepadKeyIsPressed(input, 0, TELY_PlatformInputGamepadKey_X)) {
|
|
||||||
FP_Game_EntityTransitionState(game, entity, FP_EntityTerryState_Attack);
|
FP_Game_EntityTransitionState(game, entity, FP_EntityTerryState_Attack);
|
||||||
} else if (TELY_Platform_InputScanCodeIsPressed(input, controls->range_attack.scan_code) ||
|
} else if (FP_Game_KeyBindIsPressed(input, controls, controls->range_attack)) {
|
||||||
TELY_Platform_InputGamepadKeyIsPressed(input, 0, TELY_PlatformInputGamepadKey_Y)) {
|
|
||||||
FP_Game_EntityTransitionState(game, entity, FP_EntityTerryState_RangeAttack);
|
FP_Game_EntityTransitionState(game, entity, FP_EntityTerryState_RangeAttack);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -553,23 +609,19 @@ void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_Platform
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (FP_Game_IsNilEntityHandle(game, entity->carried_monkey)) {
|
if (FP_Game_IsNilEntityHandle(game, entity->carried_monkey)) {
|
||||||
if (TELY_Platform_InputScanCodeIsPressed(input, controls->attack.scan_code) ||
|
if (FP_Game_KeyBindIsPressed(input, controls, controls->attack)) {
|
||||||
TELY_Platform_InputGamepadKeyIsPressed(input, 0, TELY_PlatformInputGamepadKey_X)) {
|
|
||||||
FP_Game_EntityTransitionState(game, entity, FP_EntityTerryState_Attack);
|
FP_Game_EntityTransitionState(game, entity, FP_EntityTerryState_Attack);
|
||||||
} else if (TELY_Platform_InputScanCodeIsPressed(input, controls->range_attack.scan_code) ||
|
} else if (FP_Game_KeyBindIsPressed(input, controls, controls->range_attack)) {
|
||||||
TELY_Platform_InputGamepadKeyIsPressed(input, 0, TELY_PlatformInputGamepadKey_Y)) {
|
|
||||||
FP_Game_EntityTransitionState(game, entity, FP_EntityTerryState_RangeAttack);
|
FP_Game_EntityTransitionState(game, entity, FP_EntityTerryState_RangeAttack);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FP_Game_IsNilEntityHandle(game, entity->carried_monkey)) {
|
if (FP_Game_IsNilEntityHandle(game, entity->carried_monkey)) {
|
||||||
if (TELY_Platform_InputScanCodeIsPressed(input, controls->dash.scan_code) ||
|
if (FP_Game_KeyBindIsPressed(input, controls, controls->dash))
|
||||||
TELY_Platform_InputGamepadKeyIsPressed(input, 0, TELY_PlatformInputGamepadKey_A)) {
|
|
||||||
FP_Game_EntityTransitionState(game, entity, FP_EntityTerryState_Dash);
|
FP_Game_EntityTransitionState(game, entity, FP_EntityTerryState_Dash);
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (!picked_up_monkey_this_frame && TELY_Platform_InputScanCodeIsPressed(input, controls->attack.scan_code)) {
|
if (!picked_up_monkey_this_frame && FP_Game_KeyBindIsPressed(input, controls, controls->attack)) {
|
||||||
FP_GameEntity *portal_monkey = FP_Game_GetEntity(game, entity->carried_monkey);
|
FP_GameEntity *portal_monkey = FP_Game_GetEntity(game, entity->carried_monkey);
|
||||||
portal_monkey->local_pos = FP_Game_CalcEntityWorldPos(game, entity->handle);
|
portal_monkey->local_pos = FP_Game_CalcEntityWorldPos(game, entity->handle);
|
||||||
entity->carried_monkey = {};
|
entity->carried_monkey = {};
|
||||||
@ -647,14 +699,11 @@ void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_Platform
|
|||||||
FP_Game_EntityActionReset(game, entity->handle, duration_ms, render_data.sprite);
|
FP_Game_EntityActionReset(game, entity->handle, duration_ms, render_data.sprite);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (we_are_clicked_entity) {
|
if (FP_Game_KeyBindIsPressed(input, controls, controls->attack)) {
|
||||||
if (TELY_Platform_InputScanCodeIsPressed(input, controls->attack.scan_code) ||
|
|
||||||
TELY_Platform_InputGamepadKeyIsPressed(input, 0, TELY_PlatformInputGamepadKey_X)) {
|
|
||||||
FP_Game_EntityTransitionState(game, entity, FP_EntitySmoochieState_Attack);
|
FP_Game_EntityTransitionState(game, entity, FP_EntitySmoochieState_Attack);
|
||||||
} else if (acceleration_meters_per_s->x || acceleration_meters_per_s->y) {
|
} else if (acceleration_meters_per_s->x || acceleration_meters_per_s->y) {
|
||||||
FP_Game_EntityTransitionState(game, entity, FP_EntitySmoochieState_Run);
|
FP_Game_EntityTransitionState(game, entity, FP_EntitySmoochieState_Run);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (entity_has_velocity) {
|
if (entity_has_velocity) {
|
||||||
FP_Game_EntityTransitionState(game, entity, FP_EntitySmoochieState_Run);
|
FP_Game_EntityTransitionState(game, entity, FP_EntitySmoochieState_Run);
|
||||||
@ -742,8 +791,7 @@ void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_Platform
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (we_are_clicked_entity) {
|
if (we_are_clicked_entity) {
|
||||||
if (TELY_Platform_InputScanCodeIsPressed(input, controls->attack.scan_code) ||
|
if (FP_Game_KeyBindIsPressed(input, controls, controls->attack)) {
|
||||||
TELY_Platform_InputGamepadKeyIsPressed(input, 0, TELY_PlatformInputGamepadKey_X)) {
|
|
||||||
FP_Game_EntityTransitionState(game, entity, FP_EntitySmoochieState_Attack);
|
FP_Game_EntityTransitionState(game, entity, FP_EntitySmoochieState_Attack);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -768,14 +816,11 @@ void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_Platform
|
|||||||
FP_Game_EntityActionReset(game, entity->handle, duration_ms, render_data.sprite);
|
FP_Game_EntityActionReset(game, entity->handle, duration_ms, render_data.sprite);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (we_are_clicked_entity) {
|
if (FP_Game_KeyBindIsPressed(input, controls, controls->attack)) {
|
||||||
if (TELY_Platform_InputScanCodeIsPressed(input, controls->attack.scan_code) ||
|
|
||||||
TELY_Platform_InputGamepadKeyIsPressed(input, 0, TELY_PlatformInputGamepadKey_X)) {
|
|
||||||
FP_Game_EntityTransitionState(game, entity, FP_EntityClingerState_Attack);
|
FP_Game_EntityTransitionState(game, entity, FP_EntityClingerState_Attack);
|
||||||
} else if (acceleration_meters_per_s->x || acceleration_meters_per_s->y) {
|
} else if (acceleration_meters_per_s->x || acceleration_meters_per_s->y) {
|
||||||
FP_Game_EntityTransitionState(game, entity, FP_EntityClingerState_Run);
|
FP_Game_EntityTransitionState(game, entity, FP_EntityClingerState_Run);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (entity_has_velocity) {
|
if (entity_has_velocity) {
|
||||||
FP_Game_EntityTransitionState(game, entity, FP_EntityClingerState_Run);
|
FP_Game_EntityTransitionState(game, entity, FP_EntityClingerState_Run);
|
||||||
@ -810,12 +855,8 @@ void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_Platform
|
|||||||
FP_Game_EntityActionReset(game, entity->handle, duration_ms, render_data.sprite);
|
FP_Game_EntityActionReset(game, entity->handle, duration_ms, render_data.sprite);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (we_are_clicked_entity) {
|
if (FP_Game_KeyBindIsPressed(input, controls, controls->attack))
|
||||||
if (TELY_Platform_InputScanCodeIsPressed(input, controls->attack.scan_code) ||
|
|
||||||
TELY_Platform_InputGamepadKeyIsPressed(input, 0, TELY_PlatformInputGamepadKey_X)) {
|
|
||||||
FP_Game_EntityTransitionState(game, entity, FP_EntityClingerState_Attack);
|
FP_Game_EntityTransitionState(game, entity, FP_EntityClingerState_Attack);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!entity_has_velocity) {
|
if (!entity_has_velocity) {
|
||||||
FP_Game_EntityTransitionState(game, entity, FP_EntityClingerState_Idle);
|
FP_Game_EntityTransitionState(game, entity, FP_EntityClingerState_Idle);
|
||||||
@ -1021,14 +1062,11 @@ void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_Platform
|
|||||||
FP_Game_EntityActionReset(game, entity->handle, duration_ms, render_data.sprite);
|
FP_Game_EntityActionReset(game, entity->handle, duration_ms, render_data.sprite);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (we_are_clicked_entity) {
|
if (FP_Game_KeyBindIsPressed(input, controls, controls->attack)) {
|
||||||
if (TELY_Platform_InputScanCodeIsPressed(input, controls->attack.scan_code) ||
|
|
||||||
TELY_Platform_InputGamepadKeyIsPressed(input, 0, TELY_PlatformInputGamepadKey_X)) {
|
|
||||||
FP_Game_EntityTransitionState(game, entity, FP_EntityCatfishState_Attack);
|
FP_Game_EntityTransitionState(game, entity, FP_EntityCatfishState_Attack);
|
||||||
} else if (acceleration_meters_per_s->x || acceleration_meters_per_s->y) {
|
} else if (acceleration_meters_per_s->x || acceleration_meters_per_s->y) {
|
||||||
FP_Game_EntityTransitionState(game, entity, FP_EntityCatfishState_Run);
|
FP_Game_EntityTransitionState(game, entity, FP_EntityCatfishState_Run);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (entity_has_velocity) {
|
if (entity_has_velocity) {
|
||||||
FP_Game_EntityTransitionState(game, entity, FP_EntityCatfishState_Run);
|
FP_Game_EntityTransitionState(game, entity, FP_EntityCatfishState_Run);
|
||||||
@ -1062,12 +1100,8 @@ void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_Platform
|
|||||||
FP_Game_EntityActionReset(game, entity->handle, duration_ms, render_data.sprite);
|
FP_Game_EntityActionReset(game, entity->handle, duration_ms, render_data.sprite);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (we_are_clicked_entity) {
|
if (FP_Game_KeyBindIsPressed(input, controls, controls->attack))
|
||||||
if (TELY_Platform_InputScanCodeIsPressed(input, controls->attack.scan_code) ||
|
|
||||||
TELY_Platform_InputGamepadKeyIsPressed(input, 0, TELY_PlatformInputGamepadKey_X)) {
|
|
||||||
FP_Game_EntityTransitionState(game, entity, FP_EntityCatfishState_Attack);
|
FP_Game_EntityTransitionState(game, entity, FP_EntityCatfishState_Attack);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!entity_has_velocity) {
|
if (!entity_has_velocity) {
|
||||||
FP_Game_EntityTransitionState(game, entity, FP_EntityCatfishState_Idle);
|
FP_Game_EntityTransitionState(game, entity, FP_EntityCatfishState_Idle);
|
||||||
@ -1275,13 +1309,13 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_PlatformInput *input
|
|||||||
FP_GameControls const *controls = &entity->controls;
|
FP_GameControls const *controls = &entity->controls;
|
||||||
Dqn_V2 dir_vector = {};
|
Dqn_V2 dir_vector = {};
|
||||||
{
|
{
|
||||||
if (TELY_Platform_InputScanCodeIsDown(input, controls->up.scan_code))
|
if (FP_Game_KeyBindIsDown(input, controls, controls->up))
|
||||||
dir_vector.y = -1.f;
|
dir_vector.y = -1.f;
|
||||||
if (TELY_Platform_InputScanCodeIsDown(input, controls->left.scan_code))
|
if (FP_Game_KeyBindIsDown(input, controls, controls->left))
|
||||||
dir_vector.x = -1.f;
|
dir_vector.x = -1.f;
|
||||||
if (TELY_Platform_InputScanCodeIsDown(input, controls->down.scan_code))
|
if (FP_Game_KeyBindIsDown(input, controls, controls->down))
|
||||||
dir_vector.y = +1.f;
|
dir_vector.y = +1.f;
|
||||||
if (TELY_Platform_InputScanCodeIsDown(input, controls->right.scan_code))
|
if (FP_Game_KeyBindIsDown(input, controls, controls->right))
|
||||||
dir_vector.x = +1.f;
|
dir_vector.x = +1.f;
|
||||||
|
|
||||||
// NOTE: Gamepad movement input
|
// NOTE: Gamepad movement input
|
||||||
@ -1763,7 +1797,7 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_PlatformInput *input
|
|||||||
|
|
||||||
// NOTE: Toggle menu ===============================================================
|
// NOTE: Toggle menu ===============================================================
|
||||||
if (entity->in_game_menu == FP_GameInGameMenu_Nil || entity->in_game_menu == FP_GameInGameMenu_Build) {
|
if (entity->in_game_menu == FP_GameInGameMenu_Nil || entity->in_game_menu == FP_GameInGameMenu_Build) {
|
||||||
if (TELY_Platform_InputScanCodeIsPressed(input, controls->build_mode.scan_code))
|
if (FP_Game_KeyBindIsPressed(input, controls, controls->build_mode))
|
||||||
entity->in_game_menu = DQN_CAST(FP_GameInGameMenu)(DQN_CAST(uint32_t)entity->in_game_menu ^ FP_GameInGameMenu_Build);
|
entity->in_game_menu = DQN_CAST(FP_GameInGameMenu)(DQN_CAST(uint32_t)entity->in_game_menu ^ FP_GameInGameMenu_Build);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1839,8 +1873,7 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_PlatformInput *input
|
|||||||
entity->build_mode_can_place_building |= Dqn_Rect_ContainsPoint(zone_hit_box, placement_pos);
|
entity->build_mode_can_place_building |= Dqn_Rect_ContainsPoint(zone_hit_box, placement_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entity->build_mode_can_place_building &&
|
if (entity->build_mode_can_place_building && FP_Game_KeyBindIsPressed(input, controls, controls->attack)) {
|
||||||
TELY_Platform_InputScanCodeIsPressed(input, controls->attack.scan_code)) {
|
|
||||||
if (placeable_building.type == FP_EntityType_ClubTerry) {
|
if (placeable_building.type == FP_EntityType_ClubTerry) {
|
||||||
FP_Entity_CreateClubTerry(game, placement_pos, "Club Terry");
|
FP_Entity_CreateClubTerry(game, placement_pos, "Club Terry");
|
||||||
TELY_Audio_Play(audio, game->audio[FP_GameAudio_Club], 1.f);
|
TELY_Audio_Play(audio, game->audio[FP_GameAudio_Club], 1.f);
|
||||||
@ -1873,7 +1906,7 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_PlatformInput *input
|
|||||||
acceleration_meters_per_s *= 1.f; // TODO(doyle): Penalise the player
|
acceleration_meters_per_s *= 1.f; // TODO(doyle): Penalise the player
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!TELY_Platform_InputScanCodeIsDown(input, controls->strafe.scan_code)) {
|
if (!FP_Game_KeyBindIsPressed(input, controls, controls->strafe)) {
|
||||||
if (acceleration_meters_per_s.x)
|
if (acceleration_meters_per_s.x)
|
||||||
entity->direction = acceleration_meters_per_s.x > 0.f ? FP_GameDirection_Right : FP_GameDirection_Left;
|
entity->direction = acceleration_meters_per_s.x > 0.f ? FP_GameDirection_Right : FP_GameDirection_Left;
|
||||||
else if (acceleration_meters_per_s.y)
|
else if (acceleration_meters_per_s.y)
|
||||||
@ -1895,7 +1928,7 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_PlatformInput *input
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
Dqn_V2 new_entity_pos = entity_pos;
|
Dqn_V2 new_entity_pos = entity_pos;
|
||||||
Dqn_Rect camera_view_rect = Dqn_Rect_InitV2x2(camera->world_pos_target - (camera->size * .5f) * camera->scale, camera->size * camera->scale);
|
Dqn_Rect camera_view_rect = Dqn_Rect_InitV2x2((camera->size * -.5f) + (camera->world_pos / camera->scale), camera->size);
|
||||||
|
|
||||||
Dqn_Rect entity_hit_box = FP_Game_CalcEntityWorldHitBox(game, entity_handle);
|
Dqn_Rect entity_hit_box = FP_Game_CalcEntityWorldHitBox(game, entity_handle);
|
||||||
Dqn_Rect playable_bounds = Dqn_Rect_ExpandV2(camera_view_rect, -entity_hit_box.size);
|
Dqn_Rect playable_bounds = Dqn_Rect_ExpandV2(camera_view_rect, -entity_hit_box.size);
|
||||||
@ -2167,6 +2200,33 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_PlatformInput *input
|
|||||||
Dqn_Profiler_EndZone(update_zone);
|
Dqn_Profiler_EndZone(update_zone);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Dqn_String8 FP_ScanCodeToLabel(Dqn_Arena *arena, TELY_PlatformInputScanCode scan_code)
|
||||||
|
{
|
||||||
|
Dqn_String8 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_String8_InitF(allocator, "[%c]", scan_code_ch);
|
||||||
|
} else {
|
||||||
|
if (scan_code == TELY_PlatformInputScanCode_Up) {
|
||||||
|
result = Dqn_String8_InitF(allocator, "[Up]");
|
||||||
|
} else if (scan_code == TELY_PlatformInputScanCode_Down) {
|
||||||
|
result = Dqn_String8_InitF(allocator, "[Down]");
|
||||||
|
} else if (scan_code == TELY_PlatformInputScanCode_Left) {
|
||||||
|
result = Dqn_String8_InitF(allocator, "[Left]");
|
||||||
|
} else if (scan_code == TELY_PlatformInputScanCode_Right) {
|
||||||
|
result = Dqn_String8_InitF(allocator, "[Right]");
|
||||||
|
} else if (scan_code == TELY_PlatformInputScanCode_Semicolon) {
|
||||||
|
result = Dqn_String8_InitF(allocator, "[;]");
|
||||||
|
} else if (scan_code == TELY_PlatformInputScanCode_Apostrophe) {
|
||||||
|
result = Dqn_String8_InitF(allocator, "[']");
|
||||||
|
} else if (scan_code == TELY_PlatformInputScanCode_Backslash) {
|
||||||
|
result = Dqn_String8_InitF(allocator, "[/]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *renderer, TELY_Audio *audio)
|
void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *renderer, TELY_Audio *audio)
|
||||||
{
|
{
|
||||||
Dqn_Profiler_ZoneScopeWithIndex("FP_Render", FP_ProfileZone_FPRender);
|
Dqn_Profiler_ZoneScopeWithIndex("FP_Render", FP_ProfileZone_FPRender);
|
||||||
@ -2523,7 +2583,8 @@ void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *renderer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (entity->type == FP_EntityType_Billboard) {
|
if (entity->type == FP_EntityType_Billboard) {
|
||||||
for (FP_GameEntityHandle player_handle : game->play.players) {
|
DQN_FOR_UINDEX (player_index, game->play.players.size) {
|
||||||
|
FP_GameEntityHandle player_handle = game->play.players.data[player_index];
|
||||||
FP_GameEntity const *player = FP_Game_GetEntity(game, player_handle);
|
FP_GameEntity const *player = FP_Game_GetEntity(game, player_handle);
|
||||||
FP_GameControls const *controls = &player->controls;
|
FP_GameControls const *controls = &player->controls;
|
||||||
|
|
||||||
@ -2531,16 +2592,17 @@ void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *renderer,
|
|||||||
FP_GameKeyBind const *key_bind = nullptr;
|
FP_GameKeyBind const *key_bind = nullptr;
|
||||||
Dqn_V2 draw_p = {};
|
Dqn_V2 draw_p = {};
|
||||||
Dqn_V4 colour = TELY_COLOUR_BLACK_V4;
|
Dqn_V4 colour = TELY_COLOUR_BLACK_V4;
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case FP_EntityBillboardState_Attack: {
|
case FP_EntityBillboardState_Attack: {
|
||||||
key_bind = &controls->attack;
|
key_bind = &controls->attack;
|
||||||
draw_p = Dqn_Rect_InterpolatedPoint(world_hit_box, Dqn_V2_InitNx2(0.65f, 0.2f));
|
draw_p = Dqn_Rect_InterpolatedPoint(world_hit_box, Dqn_V2_InitNx2(0.6f, 0.2f));
|
||||||
colour = colour_accent_yellow;
|
colour = colour_accent_yellow;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case FP_EntityBillboardState_Dash: {
|
case FP_EntityBillboardState_Dash: {
|
||||||
key_bind = &controls->dash;
|
key_bind = &controls->dash;
|
||||||
draw_p = Dqn_Rect_InterpolatedPoint(world_hit_box, Dqn_V2_InitNx2(0.62f, -0.07f));
|
draw_p = Dqn_Rect_InterpolatedPoint(world_hit_box, Dqn_V2_InitNx2(0.505f, -0.08f));
|
||||||
colour = TELY_Colour_V4InitRGBU32(0xFFE726);
|
colour = TELY_Colour_V4InitRGBU32(0xFFE726);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
@ -2549,28 +2611,61 @@ void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *renderer,
|
|||||||
|
|
||||||
case FP_EntityBillboardState_RangeAttack: {
|
case FP_EntityBillboardState_RangeAttack: {
|
||||||
key_bind = &controls->range_attack;
|
key_bind = &controls->range_attack;
|
||||||
draw_p = Dqn_Rect_InterpolatedPoint(world_hit_box, Dqn_V2_InitNx2(0.33f, -0.2f));
|
draw_p = Dqn_Rect_InterpolatedPoint(world_hit_box, Dqn_V2_InitNx2(0.20f, -0.13f));
|
||||||
colour = TELY_Colour_V4InitRGBU32(0x364659);
|
colour = TELY_Colour_V4InitRGBU32(0x364659);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case FP_EntityBillboardState_Strafe: {
|
case FP_EntityBillboardState_Strafe: {
|
||||||
key_bind = &controls->dash;
|
key_bind = &controls->dash;
|
||||||
draw_p = Dqn_Rect_InterpolatedPoint(world_hit_box, Dqn_V2_InitNx2(0.52f, -0.15f));
|
draw_p = Dqn_Rect_InterpolatedPoint(world_hit_box, Dqn_V2_InitNx2(0.36f, -0.15f));
|
||||||
colour = TELY_Colour_V4InitRGBU32(0xFF68A8);
|
colour = TELY_Colour_V4InitRGBU32(0xFF68A8);
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
draw_p.y += TELY_Render_FontHeight(renderer, assets) * player_index;
|
||||||
|
|
||||||
if (key_bind) {
|
if (key_bind) {
|
||||||
TELY_Render_PushColourV4(renderer, colour);
|
TELY_Render_PushColourV4(renderer, colour);
|
||||||
TELY_Render_PushFont(renderer, game->talkco_font_xlarge);
|
TELY_Render_PushFont(renderer, game->talkco_font);
|
||||||
DQN_DEFER {
|
DQN_DEFER {
|
||||||
TELY_Render_PopFont(renderer);
|
TELY_Render_PopFont(renderer);
|
||||||
TELY_Render_PopColourV4(renderer);
|
TELY_Render_PopColourV4(renderer);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (key_bind->scan_code >= TELY_PlatformInputScanCode_A && key_bind->scan_code <= TELY_PlatformInputScanCode_Z) {
|
Dqn_ThreadScratch scratch = Dqn_Thread_GetScratch(nullptr);
|
||||||
char scan_code_ch = DQN_CAST(char)('A' + (key_bind->scan_code - TELY_PlatformInputScanCode_A));
|
Dqn_String8 player_prefix = Dqn_String8_InitF(scratch.allocator, "P%zu", player_index);
|
||||||
TELY_Render_TextF(renderer, draw_p, Dqn_V2_InitNx1(0.5f), "[%c]", scan_code_ch);
|
if (controls->mode == FP_GameControlMode_Gamepad) {
|
||||||
|
Dqn_String8 tex_name = {};
|
||||||
|
if (key_bind->gamepad_key == TELY_PlatformInputGamepadKey_A)
|
||||||
|
tex_name = g_anim_names.merchant_button_a;
|
||||||
|
else if (key_bind->gamepad_key == TELY_PlatformInputGamepadKey_B)
|
||||||
|
tex_name = g_anim_names.merchant_button_b;
|
||||||
|
else if (key_bind->gamepad_key == TELY_PlatformInputGamepadKey_X)
|
||||||
|
tex_name = g_anim_names.merchant_button_x;
|
||||||
|
else if (key_bind->gamepad_key == TELY_PlatformInputGamepadKey_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);
|
||||||
|
TELY_Render_TextF(renderer, draw_p, Dqn_V2_InitNx2(0, +1.f), "P%zu", player_index);
|
||||||
|
|
||||||
|
Dqn_Rect gamepad_btn_rect = {};
|
||||||
|
gamepad_btn_rect.size = button_rect.size;
|
||||||
|
gamepad_btn_rect.pos = Dqn_V2_InitNx2(draw_p.x + (text_size.x * 1.25f), draw_p.y - button_rect.size.y);
|
||||||
|
|
||||||
|
TELY_Render_TextureColourV4(renderer,
|
||||||
|
game->atlas_sprite_sheet.tex_handle,
|
||||||
|
button_rect,
|
||||||
|
gamepad_btn_rect,
|
||||||
|
Dqn_V2_Zero /*rotate origin*/,
|
||||||
|
0.f /*rotation*/,
|
||||||
|
TELY_COLOUR_WHITE_V4);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Dqn_String8 key_bind_label = FP_ScanCodeToLabel(scratch.arena, key_bind->scan_code);
|
||||||
|
TELY_Render_TextF(renderer, draw_p, Dqn_V2_InitNx2(0, +1.f), "%.*s %.*s", DQN_STRING_FMT(player_prefix), DQN_STRING_FMT(key_bind_label));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2616,6 +2711,31 @@ void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *renderer,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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_ASSERT(game->play.players.size <= DQN_ARRAY_UCOUNT(player_avatar_base_pos));
|
||||||
|
|
||||||
|
DQN_ASSERTF(game->play.players.size <= 2, "We hardcode 2 player support");
|
||||||
|
if (game->play.players.size == 1) {
|
||||||
|
// NOTE: We show the Press <BTN> to join for the remaining 2nd player
|
||||||
|
TELY_Render_PushTransform(renderer, Dqn_M2x3_Identity());
|
||||||
|
TELY_Render_PushFont(renderer, game->talkco_font);
|
||||||
|
DQN_DEFER {
|
||||||
|
TELY_Render_PopFont(renderer);
|
||||||
|
TELY_Render_PopTransform(renderer);
|
||||||
|
};
|
||||||
|
|
||||||
|
Dqn_f32 font_height = TELY_Render_FontHeight(renderer, assets);
|
||||||
|
Dqn_V2 base_p = player_avatar_base_pos[game->play.players.size];
|
||||||
|
TELY_Render_TextF(renderer, base_p, Dqn_V2_Zero, "Press <B>"); base_p.y += font_height;
|
||||||
|
TELY_Render_TextF(renderer, base_p, Dqn_V2_Zero, "or"); base_p.y += font_height;
|
||||||
|
TELY_Render_TextF(renderer, base_p, Dqn_V2_Zero, "<Gamepad: Start> to join!"); base_p.y += font_height;
|
||||||
|
FP_ListenForNewPlayer(input, game);
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: Render the player(s) HUD and merchant menu interaction ============================
|
||||||
Dqn_Rect first_player_avatar_rect = {};
|
Dqn_Rect first_player_avatar_rect = {};
|
||||||
DQN_FOR_UINDEX (player_index, game->play.players.size) {
|
DQN_FOR_UINDEX (player_index, game->play.players.size) {
|
||||||
FP_GameEntityHandle player_handle = game->play.players.data[player_index];
|
FP_GameEntityHandle player_handle = game->play.players.data[player_index];
|
||||||
@ -2679,6 +2799,7 @@ void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *renderer,
|
|||||||
if (merchant_with_more_than_2_menus_open == mapping.merchant) {
|
if (merchant_with_more_than_2_menus_open == mapping.merchant) {
|
||||||
// NOTE: More than 2 players have activated the same merchant, we just
|
// NOTE: More than 2 players have activated the same merchant, we just
|
||||||
// draw the menus and overlap with the players.
|
// draw the menus and overlap with the players.
|
||||||
|
DQN_ASSERTF(player_index <= 2, "We only handle 2 players gracefully");
|
||||||
if (player_index == 0)
|
if (player_index == 0)
|
||||||
*mapping.menu_pos = top_rect.pos;
|
*mapping.menu_pos = top_rect.pos;
|
||||||
else
|
else
|
||||||
@ -2784,44 +2905,41 @@ void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *renderer,
|
|||||||
// NOTE: Render the (A) button =================================
|
// NOTE: Render the (A) button =================================
|
||||||
Dqn_V4 tex_mod_colour = have_enough_coins ? TELY_COLOUR_WHITE_V4 : TELY_Colour_V4Alpha(TELY_COLOUR_RED_TOMATO_V4, .5f);
|
Dqn_V4 tex_mod_colour = have_enough_coins ? TELY_COLOUR_WHITE_V4 : TELY_Colour_V4Alpha(TELY_COLOUR_RED_TOMATO_V4, .5f);
|
||||||
{
|
{
|
||||||
// NOTE: Render the gamepad button
|
// NOTE: Render the interaction button
|
||||||
Dqn_Rect gamepad_btn_rect = {};
|
Dqn_Rect interact_btn_rect = {};
|
||||||
{
|
interact_btn_rect.pos = Dqn_Rect_InterpolatedPoint(merchant_menu_rect, Dqn_V2_InitNx2(0.345f, 0.41f));
|
||||||
|
if (player->controls.mode == FP_GameControlMode_Gamepad) {
|
||||||
TELY_AssetSpriteAnimation *anim = TELY_Asset_GetSpriteAnimation(&game->atlas_sprite_sheet, g_anim_names.merchant_button_a);
|
TELY_AssetSpriteAnimation *anim = TELY_Asset_GetSpriteAnimation(&game->atlas_sprite_sheet, g_anim_names.merchant_button_a);
|
||||||
Dqn_Rect button_rect = game->atlas_sprite_sheet.rects.data[anim->index];
|
Dqn_Rect button_rect = game->atlas_sprite_sheet.rects.data[anim->index];
|
||||||
gamepad_btn_rect.size = button_rect.size * 1.5f;
|
interact_btn_rect.size = button_rect.size * 1.5f;
|
||||||
gamepad_btn_rect.pos = Dqn_Rect_InterpolatedPoint(merchant_menu_rect, Dqn_V2_InitNx2(0.345f, 0.41f));
|
|
||||||
|
Dqn_Rect key_bind_rect = interact_btn_rect;
|
||||||
|
key_bind_rect.pos.y += interact_btn_rect.size.y * .3f;
|
||||||
|
|
||||||
TELY_Render_TextureColourV4(renderer,
|
TELY_Render_TextureColourV4(renderer,
|
||||||
game->atlas_sprite_sheet.tex_handle,
|
game->atlas_sprite_sheet.tex_handle,
|
||||||
button_rect,
|
button_rect,
|
||||||
gamepad_btn_rect,
|
key_bind_rect,
|
||||||
Dqn_V2_Zero /*rotate origin*/,
|
Dqn_V2_Zero /*rotate origin*/,
|
||||||
0.f /*rotation*/,
|
0.f /*rotation*/,
|
||||||
tex_mod_colour);
|
tex_mod_colour);
|
||||||
}
|
} else {
|
||||||
|
|
||||||
// NOTE: Render the $ cost
|
|
||||||
TELY_Render_TextF(renderer, Dqn_Rect_InterpolatedPoint(gamepad_btn_rect, Dqn_V2_InitNx2(0.5f, -0.8f)), Dqn_V2_InitNx2(0.5, 0.f), "$%u", *mapping.building_base_price);
|
|
||||||
|
|
||||||
// NOTE: Render the keyboard binding =======================================
|
|
||||||
{
|
|
||||||
DQN_ASSERT(key_bind.scan_code >= TELY_PlatformInputScanCode_A && key_bind.scan_code <= TELY_PlatformInputScanCode_Z);
|
|
||||||
char scan_code_ch = DQN_CAST(char)('A' + (key_bind.scan_code - TELY_PlatformInputScanCode_A));
|
|
||||||
|
|
||||||
Dqn_ThreadScratch scratch = Dqn_Thread_GetScratch(nullptr);
|
Dqn_ThreadScratch scratch = Dqn_Thread_GetScratch(nullptr);
|
||||||
TELY_AssetFont const *font = TELY_Render_Font(renderer, assets);
|
TELY_AssetFont const *font = TELY_Render_Font(renderer, assets);
|
||||||
Dqn_String8 key_bind_label = Dqn_String8_InitF(scratch.allocator, "[%c]", scan_code_ch);
|
Dqn_String8 key_bind_label = FP_ScanCodeToLabel(scratch.arena, key_bind.scan_code);
|
||||||
|
interact_btn_rect.size = TELY_Asset_MeasureText(font, key_bind_label);
|
||||||
|
|
||||||
Dqn_Rect key_bind_rect = {};
|
Dqn_Rect key_bind_rect = interact_btn_rect;
|
||||||
key_bind_rect.size = TELY_Asset_MeasureText(font, key_bind_label);
|
key_bind_rect.pos.y += interact_btn_rect.size.y * .3f;
|
||||||
key_bind_rect.pos = Dqn_Rect_InterpolatedPoint(gamepad_btn_rect, Dqn_V2_InitNx2(-0.1f, 1.1f));
|
|
||||||
key_bind_rect = Dqn_Rect_Expand(key_bind_rect, 2.f);
|
|
||||||
|
|
||||||
|
TELY_Render_RectColourV4(renderer, Dqn_Rect_Expand(key_bind_rect, 2.f), TELY_RenderShapeMode_Fill, TELY_Colour_V4Alpha(keybind_btn_shadow_colour, tex_mod_colour.a));
|
||||||
TELY_Render_PushColourV4(renderer, TELY_Colour_V4Alpha(colour_accent_yellow, tex_mod_colour.a));
|
TELY_Render_PushColourV4(renderer, TELY_Colour_V4Alpha(colour_accent_yellow, tex_mod_colour.a));
|
||||||
TELY_Render_RectColourV4(renderer, key_bind_rect, TELY_RenderShapeMode_Fill, TELY_Colour_V4Alpha(keybind_btn_shadow_colour, tex_mod_colour.a));
|
|
||||||
TELY_Render_Text(renderer, Dqn_Rect_InterpolatedPoint(key_bind_rect, Dqn_V2_InitNx1(0.5f)), Dqn_V2_InitNx1(0.5f), key_bind_label);
|
TELY_Render_Text(renderer, Dqn_Rect_InterpolatedPoint(key_bind_rect, Dqn_V2_InitNx1(0.5f)), Dqn_V2_InitNx1(0.5f), key_bind_label);
|
||||||
TELY_Render_PopColourV4(renderer);
|
TELY_Render_PopColourV4(renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: Render the $ cost
|
||||||
|
TELY_Render_TextF(renderer, Dqn_Rect_InterpolatedPoint(interact_btn_rect, Dqn_V2_InitNx2(0.5f, -0.8f)), Dqn_V2_InitNx2(0.5, 0.f), "$%u", *mapping.building_base_price);
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: Render the merchant shop item building ================
|
// NOTE: Render the merchant shop item building ================
|
||||||
@ -2830,7 +2948,7 @@ void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *renderer,
|
|||||||
Dqn_Rect tex_rect = game->atlas_sprite_sheet.rects.data[anim->index];
|
Dqn_Rect tex_rect = game->atlas_sprite_sheet.rects.data[anim->index];
|
||||||
Dqn_Rect dest_rect = {};
|
Dqn_Rect dest_rect = {};
|
||||||
dest_rect.size = tex_rect.size * 0.35f;
|
dest_rect.size = tex_rect.size * 0.35f;
|
||||||
dest_rect.pos = Dqn_Rect_InterpolatedPoint(merchant_menu_rect, Dqn_V2_InitNx2(0.45f, 0.25f) + mapping.building_offset01);
|
dest_rect.pos = Dqn_Rect_InterpolatedPoint(merchant_menu_rect, Dqn_V2_InitNx2(0.42f, 0.25f) + mapping.building_offset01);
|
||||||
TELY_Render_TextureColourV4(renderer,
|
TELY_Render_TextureColourV4(renderer,
|
||||||
game->atlas_sprite_sheet.tex_handle,
|
game->atlas_sprite_sheet.tex_handle,
|
||||||
tex_rect,
|
tex_rect,
|
||||||
@ -2895,32 +3013,47 @@ void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *renderer,
|
|||||||
// NOTE: Render the (B) button =================================
|
// NOTE: Render the (B) button =================================
|
||||||
Dqn_V4 tex_mod_colour = have_enough_coins ? TELY_COLOUR_WHITE_V4 : TELY_Colour_V4Alpha(TELY_COLOUR_RED_TOMATO_V4, .5f);
|
Dqn_V4 tex_mod_colour = have_enough_coins ? TELY_COLOUR_WHITE_V4 : TELY_Colour_V4Alpha(TELY_COLOUR_RED_TOMATO_V4, .5f);
|
||||||
{
|
{
|
||||||
Dqn_V2 interp_pos01 = {};
|
Dqn_V2 interp_pos01 = Dqn_V2_InitNx2(0.7f, 0.41f);
|
||||||
Dqn_Rect gamepad_btn_rect = {};
|
Dqn_Rect interact_btn_rect = {};
|
||||||
// NOTE: Render the gamepad button
|
interact_btn_rect.pos = Dqn_Rect_InterpolatedPoint(merchant_menu_rect, interp_pos01);
|
||||||
{
|
// NOTE: Render the interact button ====================================
|
||||||
|
if (player->controls.mode == FP_GameControlMode_Gamepad) {
|
||||||
TELY_AssetSpriteAnimation *anim = TELY_Asset_GetSpriteAnimation(&game->atlas_sprite_sheet, g_anim_names.merchant_button_b);
|
TELY_AssetSpriteAnimation *anim = TELY_Asset_GetSpriteAnimation(&game->atlas_sprite_sheet, g_anim_names.merchant_button_b);
|
||||||
Dqn_Rect button_rect = game->atlas_sprite_sheet.rects.data[anim->index];
|
Dqn_Rect button_rect = game->atlas_sprite_sheet.rects.data[anim->index];
|
||||||
interp_pos01 = Dqn_V2_InitNx2(0.71f, 0.41f);
|
interact_btn_rect.size = button_rect.size * 1.5f;
|
||||||
gamepad_btn_rect.size = button_rect.size * 1.5f;
|
|
||||||
gamepad_btn_rect.pos = Dqn_Rect_InterpolatedPoint(merchant_menu_rect, interp_pos01);
|
Dqn_Rect key_bind_rect = interact_btn_rect;
|
||||||
|
key_bind_rect.pos.y += interact_btn_rect.size.y * .3f;
|
||||||
|
|
||||||
TELY_Render_TextureColourV4(renderer,
|
TELY_Render_TextureColourV4(renderer,
|
||||||
game->atlas_sprite_sheet.tex_handle,
|
game->atlas_sprite_sheet.tex_handle,
|
||||||
button_rect,
|
button_rect,
|
||||||
gamepad_btn_rect,
|
key_bind_rect,
|
||||||
Dqn_V2_Zero /*rotate origin*/,
|
Dqn_V2_Zero /*rotate origin*/,
|
||||||
0.f /*rotation*/,
|
0.f /*rotation*/,
|
||||||
tex_mod_colour);
|
tex_mod_colour);
|
||||||
|
} else {
|
||||||
|
Dqn_ThreadScratch scratch = Dqn_Thread_GetScratch(nullptr);
|
||||||
|
TELY_AssetFont const *font = TELY_Render_Font(renderer, assets);
|
||||||
|
Dqn_String8 key_bind_label = FP_ScanCodeToLabel(scratch.arena, key_bind.scan_code);
|
||||||
|
interact_btn_rect.size = TELY_Asset_MeasureText(font, key_bind_label);
|
||||||
|
|
||||||
|
Dqn_Rect key_bind_rect = interact_btn_rect;
|
||||||
|
key_bind_rect.pos.y += interact_btn_rect.size.y * .3f;
|
||||||
|
|
||||||
|
TELY_Render_RectColourV4(renderer, Dqn_Rect_Expand(key_bind_rect, 2.f), TELY_RenderShapeMode_Fill, TELY_Colour_V4Alpha(keybind_btn_shadow_colour, tex_mod_colour.a));
|
||||||
|
TELY_Render_PushColourV4(renderer, TELY_Colour_V4Alpha(colour_accent_yellow, tex_mod_colour.a));
|
||||||
|
TELY_Render_Text(renderer, Dqn_Rect_InterpolatedPoint(key_bind_rect, Dqn_V2_InitNx1(0.5f)), Dqn_V2_InitNx1(0.5f), key_bind_label);
|
||||||
|
TELY_Render_PopColourV4(renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: Render the building
|
// NOTE: Render the icon ===============================================
|
||||||
{
|
{
|
||||||
TELY_AssetSpriteAnimation *anim = TELY_Asset_GetSpriteAnimation(&game->atlas_sprite_sheet, mapping.upgrade_icon);
|
TELY_AssetSpriteAnimation *anim = TELY_Asset_GetSpriteAnimation(&game->atlas_sprite_sheet, mapping.upgrade_icon);
|
||||||
Dqn_Rect button_rect = game->atlas_sprite_sheet.rects.data[anim->index];
|
Dqn_Rect button_rect = game->atlas_sprite_sheet.rects.data[anim->index];
|
||||||
Dqn_Rect dest_rect = {};
|
Dqn_Rect dest_rect = {};
|
||||||
dest_rect.size = button_rect.size * .75f;
|
dest_rect.size = button_rect.size * .75f;
|
||||||
dest_rect.pos = Dqn_Rect_InterpolatedPoint(merchant_menu_rect, interp_pos01 + Dqn_V2_InitNx2(0.12f, 0.15f)) - (dest_rect.size * .5f);
|
dest_rect.pos = Dqn_Rect_InterpolatedPoint(merchant_menu_rect, interp_pos01 + Dqn_V2_InitNx2(0.135f, 0.15f)) - (dest_rect.size * .5f);
|
||||||
TELY_Render_TextureColourV4(renderer,
|
TELY_Render_TextureColourV4(renderer,
|
||||||
game->atlas_sprite_sheet.tex_handle,
|
game->atlas_sprite_sheet.tex_handle,
|
||||||
button_rect,
|
button_rect,
|
||||||
@ -2931,27 +3064,8 @@ void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *renderer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: Render the $ cost
|
// NOTE: Render the $ cost
|
||||||
TELY_Render_TextF(renderer, Dqn_Rect_InterpolatedPoint(gamepad_btn_rect, Dqn_V2_InitNx2(1.f, -0.8f)), Dqn_V2_InitNx2(0.5, 0.f), "$%u", *mapping.upgrade_base_price);
|
TELY_Render_TextF(renderer, Dqn_Rect_InterpolatedPoint(interact_btn_rect, Dqn_V2_InitNx2(1.f, -0.8f)), Dqn_V2_InitNx2(0.5, 0.f), "$%u", *mapping.upgrade_base_price);
|
||||||
|
|
||||||
// NOTE: Render the keyboard binding =======================================
|
|
||||||
{
|
|
||||||
DQN_ASSERT(key_bind.scan_code >= TELY_PlatformInputScanCode_A && key_bind.scan_code <= TELY_PlatformInputScanCode_Z);
|
|
||||||
char scan_code_ch = DQN_CAST(char)('A' + (key_bind.scan_code - TELY_PlatformInputScanCode_A));
|
|
||||||
|
|
||||||
Dqn_ThreadScratch scratch = Dqn_Thread_GetScratch(nullptr);
|
|
||||||
TELY_AssetFont const *font = TELY_Render_Font(renderer, assets);
|
|
||||||
Dqn_String8 key_bind_label = Dqn_String8_InitF(scratch.allocator, "[%c]", scan_code_ch);
|
|
||||||
|
|
||||||
Dqn_Rect key_bind_rect = {};
|
|
||||||
key_bind_rect.pos = Dqn_Rect_InterpolatedPoint(gamepad_btn_rect, Dqn_V2_InitNx2(-0.1f, 1.1f));
|
|
||||||
key_bind_rect.size = TELY_Asset_MeasureText(font, key_bind_label);
|
|
||||||
key_bind_rect = Dqn_Rect_Expand(key_bind_rect, 2.f);
|
|
||||||
|
|
||||||
TELY_Render_PushColourV4(renderer, TELY_Colour_V4Alpha(colour_accent_yellow, tex_mod_colour.a));
|
|
||||||
TELY_Render_RectColourV4(renderer, key_bind_rect, TELY_RenderShapeMode_Fill, TELY_Colour_V4Alpha(keybind_btn_shadow_colour, tex_mod_colour.a));
|
|
||||||
TELY_Render_Text(renderer, Dqn_Rect_InterpolatedPoint(key_bind_rect, Dqn_V2_InitNx1(0.5f)), Dqn_V2_InitNx1(0.5f), key_bind_label);
|
|
||||||
TELY_Render_PopColourV4(renderer);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2967,12 +3081,7 @@ void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *renderer,
|
|||||||
|
|
||||||
// NOTE: Render player avatar HUD ==========================================================
|
// NOTE: Render player avatar HUD ==========================================================
|
||||||
Dqn_Rect player_avatar_rect = {};
|
Dqn_Rect player_avatar_rect = {};
|
||||||
if (player_index) {
|
player_avatar_rect.pos = player_avatar_base_pos[player_index];
|
||||||
player_avatar_rect.pos = Dqn_V2_InitNx2(platform->core.window_size.x - 320.f, 32.f);
|
|
||||||
} else {
|
|
||||||
player_avatar_rect.pos = Dqn_V2_InitNx1(32.f);
|
|
||||||
}
|
|
||||||
|
|
||||||
Dqn_V2 next_pos = {};
|
Dqn_V2 next_pos = {};
|
||||||
{
|
{
|
||||||
TELY_Render_PushTransform(renderer, Dqn_M2x3_Identity());
|
TELY_Render_PushTransform(renderer, Dqn_M2x3_Identity());
|
||||||
@ -3340,9 +3449,12 @@ void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *renderer,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: Debug show camera bounds
|
||||||
|
#if 0
|
||||||
FP_GameCamera *camera = &game->play.camera;
|
FP_GameCamera *camera = &game->play.camera;
|
||||||
Dqn_Rect camera_view_rect = Dqn_Rect_InitV2x2(camera->world_pos - (camera->size * .5f) * camera->scale, camera->size * camera->scale);
|
Dqn_Rect camera_view_rect = Dqn_Rect_InitV2x2((camera->size * -.5f) + (camera->world_pos / camera->scale), camera->size);
|
||||||
TELY_Render_RectColourV4(renderer, Dqn_Rect_Expand(camera_view_rect, -5.f), TELY_RenderShapeMode_Line, TELY_COLOUR_RED_V4);
|
TELY_Render_RectColourV4(renderer, Dqn_Rect_Expand(camera_view_rect, -5.f), TELY_RenderShapeMode_Line, TELY_COLOUR_RED_V4);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// NOTE: Add scanlines into the game for A E S T H E T I C S ===================================
|
// NOTE: Add scanlines into the game for A E S T H E T I C S ===================================
|
||||||
@ -3469,15 +3581,15 @@ void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *renderer,
|
|||||||
TELY_Render_PushFont(renderer, game->inter_regular_font);
|
TELY_Render_PushFont(renderer, game->inter_regular_font);
|
||||||
Dqn_f32 t = (DQN_SINF(DQN_CAST(Dqn_f32)input->timer_s * 5.f) + 1.f) / 2.f;
|
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_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 enter to %s", game->play.state == FP_GameState_IntroScreen ? "start" : "restart");
|
TELY_Render_TextF(renderer, Dqn_Rect_InterpolatedPoint(window_rect, Dqn_V2_InitNx2(0.5f, 0.925f)), Dqn_V2_InitNx1(0.5f), "Press <B> or <Gamepad: Start> to %s", game->play.state == FP_GameState_IntroScreen ? "start" : "restart");
|
||||||
|
|
||||||
TELY_Render_PopColourV4(renderer);
|
TELY_Render_PopColourV4(renderer);
|
||||||
TELY_Render_PopFont(renderer);
|
TELY_Render_PopFont(renderer);
|
||||||
|
|
||||||
if (TELY_Platform_InputScanCodeIsPressed(input, TELY_PlatformInputScanCode_Return)) {
|
|
||||||
if (game->play.state == FP_GameState_LoseGame)
|
if (game->play.state == FP_GameState_LoseGame)
|
||||||
FP_PlayReset(game, platform);
|
FP_PlayReset(game, platform);
|
||||||
|
if (FP_ListenForNewPlayer(input, game))
|
||||||
game->play.state = FP_GameState_Play;
|
game->play.state = FP_GameState_Play;
|
||||||
}
|
|
||||||
|
|
||||||
} else if (game->play.state == FP_GameState_Pause) {
|
} else if (game->play.state == FP_GameState_Pause) {
|
||||||
TELY_Render_PushFont(renderer, game->inter_regular_font_large);
|
TELY_Render_PushFont(renderer, game->inter_regular_font_large);
|
||||||
|
@ -171,8 +171,16 @@ struct FP_GameKeyBind
|
|||||||
TELY_PlatformInputGamepadKey gamepad_key;
|
TELY_PlatformInputGamepadKey gamepad_key;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum FP_GameControlMode
|
||||||
|
{
|
||||||
|
FP_GameControlMode_Keyboard,
|
||||||
|
FP_GameControlMode_Gamepad,
|
||||||
|
};
|
||||||
|
|
||||||
struct FP_GameControls
|
struct FP_GameControls
|
||||||
{
|
{
|
||||||
|
FP_GameControlMode mode;
|
||||||
|
uint32_t gamepad_index;
|
||||||
FP_GameKeyBind up;
|
FP_GameKeyBind up;
|
||||||
FP_GameKeyBind down;
|
FP_GameKeyBind down;
|
||||||
FP_GameKeyBind left;
|
FP_GameKeyBind left;
|
||||||
|
Loading…
Reference in New Issue
Block a user