Dehardcode quick actions and menu actions (#1154)

* Hotkey progress

* Fix scrolling; fix x64 compiler errors

* Dehardcode item hotkeys

* Move player quick actions to more appropriate file

* Get weapon scrolling to work

* Move SayNo action

* Update gui.cpp

* Add menu controls screen

* Dehardcode more menu actions

* Simplify

* Move helper functions

* Simplify

* Use std::string for key names; fix crouch action

* Fix lean reset

* Update lara_helpers.cpp

* Fix binding application

* Update gui.cpp

* Update gui.cpp

* Reorder input actions; update script enum

* Update gui.cpp

* Fix menu highlight error

* Fix default xbone bindings

* Simplify action string categories

* Commit to tentative Light action; prepare more vehicle action code

* Move medipack code to subfunction

* Move medipack code to subfunction

* Update lara_helpers.cpp

* Remove flare no

* Add missing comma

* Rename Light back to Flare

* Rename Option to Inventory

* Update lara_helpers.cpp

* Update lara_helpers.cpp

* Update strings

* Fix typo

* Fix medipack functionality

* Update arrow positioning and make arrows flash

* Update input strings and defaults

* Update action order

* Remove include

* Add arrow string constants

* Update Renderer11DrawMenu.cpp

* Update Renderer11DrawMenu.cpp

* Update Renderer11DrawMenu.cpp

* Address PR comments

* Update lara_helpers.cpp

* Use consistent line spacing

* Update Renderer11DrawMenu.cpp

---------

Co-authored-by: Lwmte <3331699+Lwmte@users.noreply.github.com>
This commit is contained in:
Sezz 2023-07-15 23:28:19 +10:00 committed by GitHub
parent b5eb8088fa
commit c1b674be8d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 876 additions and 496 deletions

View file

@ -5,6 +5,47 @@ corresponding to languages in the table at the end of this file.
local strings =
{
actions_accelerate = { "Accelerate" },
actions_reverse = { "Reverse" },
actions_speed = { "Speed" },
actions_slow = { "Slow" },
actions_brake = { "Brake" },
actions_fire = { "Fire" },
actions_action = { "Action" },
actions_sprint = { "Sprint" },
actions_draw = { "Draw" },
actions_crouch = { "Crouch" },
actions_inventory = { "Inventory" },
actions_jump = { "Jump" },
actions_look = { "Look" },
actions_backward = { "Backward" },
actions_forward = { "Forward" },
actions_left = { "Left" },
actions_right = { "Right" },
actions_roll = { "Roll" },
actions_step_left = { "Step Left" },
actions_step_right = { "Step Right" },
actions_pause = { "Pause" },
actions_walk = { "Walk" },
actions_save = { "Save" },
actions_load = { "Load" },
actions_select = { "Select" },
actions_deselect = { "Deselect" },
actions_large_medipack = { "Large Medipack" },
actions_flare = { "Flare" },
actions_next_weapon = { "Next Weapon" },
actions_previous_weapon = { "Previous Weapon" },
actions_small_medipack = { "Small Medipack" },
actions_weapon_1 = { "Weapon 1" },
actions_weapon_2 = { "Weapon 2" },
actions_weapon_3 = { "Weapon 3" },
actions_weapon_4 = { "Weapon 4" },
actions_weapon_5 = { "Weapon 5" },
actions_weapon_6 = { "Weapon 6" },
actions_weapon_7 = { "Weapon 7" },
actions_weapon_8 = { "Weapon 8" },
actions_weapon_9 = { "Weapon 9" },
actions_weapon_10 = { "Weapon 10" },
window_title = { "TombEngine" },
all = { "All" },
apply = { "Apply" },
@ -19,24 +60,7 @@ local strings =
combine = { "Combine" },
combine_with = { "Combine With" },
controls = { "Controls" },
controls_action = { "Action" },
controls_sprint = { "Sprint" },
controls_draw_weapon = { "Draw Weapon" },
controls_crouch = { "Crouch" },
controls_inventory = { "Inventory" },
controls_jump = { "Jump" },
controls_look = { "Look" },
controls_move_backward = { "Move Backward" },
controls_move_forward = { "Move Forward" },
controls_move_left = { "Move Left" },
controls_move_right = { "Move Right" },
controls_roll = { "Roll" },
controls_step_left = { "Step Left" },
controls_step_right = { "Step Right" },
controls_pause = { "Pause" },
controls_use_flare = { "Use Flare" },
controls_walk = { "Walk" },
controls_defaults = { "Reset to Defaults" },
reset_to_defaults = { "Reset to Defaults" },
crossbow = { "Crossbow" },
crossbow_normal_ammo = { "Crossbow Normal Ammo" },
crossbow_poison_ammo = { "Crossbow Poison Ammo" },
@ -55,6 +79,7 @@ local strings =
exit_game = { "Exit Game" },
exit_to_title = { "Exit to Title" },
flares = { "Flares" },
general_actions = { "General Actions"},
grenade_launcher = { "Grenade Launcher" },
grenade_launcher_normal_ammo = { "Grenade Launcher Normal Ammo" },
grenade_launcher_super_ammo = { "Grenade Launcher Super Ammo" },
@ -71,6 +96,7 @@ local strings =
lara_home = { "Lara's Home" },
large_medipack = { "Large Medipack" },
lasersight = { "Lasersight" },
menu_actions = { "Menu Actions" },
music_volume = { "Music Volume" },
new_game = { "New Game" },
none = { "None" },
@ -125,6 +151,8 @@ local strings =
waiting_for_input = { "Waiting For Input" },
windowed = { "Windowed" },
load_game = { "Load Game" },
quick_actions = { "Quick Actions" },
vehicle_actions = { "Vehicle Actions" },
test_level = { "Test Level" },
waterskin_small_empty = { "Small Waterskin (Empty)" },
waterskin_small_1l = { "Small Waterskin (1L)" },
@ -140,13 +168,7 @@ local strings =
mechanical_scarab = { "Mechanical Scarab With Winding Key" },
mechanical_scarab_1 = { "Mechanical Scarab (No Winding Key)" },
mechanical_scarab_2 = { "Mechanical Scarab Winding Key" },
title = { "Title" },
accelerate = { "Accelerate" },
reverse = { "Reverse" },
speed = { "Speed" },
slow = { "Slow" },
brake = { "Brake" },
fire = { "Fire" }
title = { "Title" }
}
TEN.Flow.SetStrings(strings)

View file

@ -491,6 +491,7 @@ void LaraControl(ItemInfo* item, CollisionInfo* coll)
if (lara->Status.Stamina < LARA_STAMINA_MAX && item->Animation.ActiveState != LS_SPRINT)
lara->Status.Stamina++;
HandlePlayerQuickActions(*item);
RumbleLaraHealthCondition(item);
bool isWater = TestEnvironment(ENV_FLAG_WATER, item);
@ -707,9 +708,7 @@ void LaraControl(ItemInfo* item, CollisionInfo* coll)
}
if (TestEnvironment(ENV_FLAG_DAMAGE, item) && item->HitPoints > 0)
{
item->HitPoints--;
}
if (item->HitPoints <= 0)
{

View file

@ -252,7 +252,7 @@ void lara_as_run_forward(ItemInfo* item, CollisionInfo* coll)
return;
}
if (TrInput & (IN_LEFT | IN_RIGHT))
if (IsHeld(In::Left) || IsHeld(In::Right))
{
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_FAST_TURN_RATE_MAX);
ModulateLaraLean(item, coll, LARA_LEAN_RATE, LARA_LEAN_MAX);
@ -418,8 +418,8 @@ void lara_as_idle(ItemInfo* item, CollisionInfo* coll)
if (!IsHeld(In::Jump) || isSwamp) // JUMP locks orientation outside swamps.
{
// Sidestep locks orientation.
if ((IsHeld(In::LeftStep) || (IsHeld(In::Walk) && IsHeld(In::Left))) ||
(IsHeld(In::RightStep) || (IsHeld(In::Walk) && IsHeld(In::Right))))
if ((IsHeld(In::StepLeft) || (IsHeld(In::Walk) && IsHeld(In::Left))) ||
(IsHeld(In::StepRight) || (IsHeld(In::Walk) && IsHeld(In::Right))))
{
ModulateLaraTurnRateY(item, 0, 0, 0);
}
@ -508,7 +508,7 @@ void lara_as_idle(ItemInfo* item, CollisionInfo* coll)
}
}
if (IsHeld(In::LeftStep) || (IsHeld(In::Walk) && IsHeld(In::Left)))
if (IsHeld(In::StepLeft) || (IsHeld(In::Walk) && IsHeld(In::Left)))
{
if (TestLaraStepLeft(item, coll))
item->Animation.TargetState = LS_STEP_LEFT;
@ -517,7 +517,7 @@ void lara_as_idle(ItemInfo* item, CollisionInfo* coll)
return;
}
else if (IsHeld(In::RightStep) || (IsHeld(In::Walk) && IsHeld(In::Right)))
else if (IsHeld(In::StepRight) || (IsHeld(In::Walk) && IsHeld(In::Right)))
{
if (TestLaraStepRight(item, coll))
item->Animation.TargetState = LS_STEP_RIGHT;
@ -798,7 +798,7 @@ void lara_as_run_back(ItemInfo* item, CollisionInfo* coll)
{
auto* lara = GetLaraInfo(item);
if (TrInput & (IN_LEFT | IN_RIGHT))
if (IsHeld(In::Left) || IsHeld(In::Right))
{
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_MED_TURN_RATE_MAX);
ModulateLaraLean(item, coll, LARA_LEAN_RATE / 4, LARA_LEAN_MAX / 3);
@ -1464,7 +1464,7 @@ void lara_as_walk_back(ItemInfo* item, CollisionInfo* coll)
return;
}
if (TrInput & (IN_LEFT | IN_RIGHT))
if (IsHeld(In::Left) || IsHeld(In::Right))
{
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_SLOW_TURN_RATE_MAX);
ModulateLaraLean(item, coll, LARA_LEAN_RATE / 4, LARA_LEAN_MAX / 3);
@ -1485,7 +1485,7 @@ void PseudoLaraAsSwampWalkBack(ItemInfo* item, CollisionInfo* coll)
{
auto* lara = GetLaraInfo(item);
if (TrInput & (IN_LEFT | IN_RIGHT))
if (IsHeld(In::Left) || IsHeld(In::Right))
{
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_SLOW_TURN_RATE_MAX / 3);
ModulateLaraLean(item, coll, LARA_LEAN_RATE / 3, LARA_LEAN_MAX / 3);
@ -1825,7 +1825,7 @@ void lara_as_step_right(ItemInfo* item, CollisionInfo* coll)
ModulateLaraTurnRateY(item, 0, 0, 0);
else
{
if (TrInput & (IN_LEFT | IN_RIGHT))
if (IsHeld(In::Left) || IsHeld(In::Right))
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_SLOW_TURN_RATE_MAX);
}
@ -1919,7 +1919,7 @@ void lara_as_step_left(ItemInfo* item, CollisionInfo* coll)
ModulateLaraTurnRateY(item, 0, 0, 0);
else
{
if (TrInput & (IN_LEFT | IN_RIGHT))
if (IsHeld(In::Left) || IsHeld(In::Right))
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_SLOW_TURN_RATE_MAX);
}
@ -2142,7 +2142,7 @@ void lara_as_wade_forward(ItemInfo* item, CollisionInfo* coll)
return;
}
if (TrInput & (IN_LEFT | IN_RIGHT))
if (IsHeld(In::Left) || IsHeld(In::Right))
{
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_MED_TURN_RATE_MAX);
ModulateLaraLean(item, coll, LARA_LEAN_RATE / 2, LARA_LEAN_MAX);
@ -2174,7 +2174,7 @@ void PseudoLaraAsSwampWadeForward(ItemInfo* item, CollisionInfo* coll)
{
auto* lara = GetLaraInfo(item);
if (TrInput & (IN_LEFT | IN_RIGHT))
if (IsHeld(In::Left) || IsHeld(In::Right))
{
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_SWAMP_TURN_RATE_MAX);
ModulateLaraLean(item, coll, LARA_LEAN_RATE / 3, LARA_LEAN_MAX * 0.6f);
@ -2263,7 +2263,7 @@ void lara_as_sprint(ItemInfo* item, CollisionInfo* coll)
return;
}
if (TrInput & (IN_LEFT | IN_RIGHT))
if (IsHeld(In::Left) || IsHeld(In::Right))
{
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_SLOW_TURN_RATE_MAX);
ModulateLaraLean(item, coll, LARA_LEAN_RATE, LARA_LEAN_MAX);
@ -2399,7 +2399,7 @@ void lara_as_sprint_dive(ItemInfo* item, CollisionInfo* coll)
if (lara->Control.Count.Run > LARA_RUN_JUMP_TIME)
lara->Control.Count.Run = LARA_RUN_JUMP_TIME;
if (TrInput & (IN_LEFT | IN_RIGHT))
if (IsHeld(In::Left) || IsHeld(In::Right))
{
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_SLOW_TURN_RATE_MAX);
ModulateLaraLean(item, coll, LARA_LEAN_RATE, LARA_LEAN_MAX * 0.6f);

View file

@ -35,9 +35,6 @@ void lara_as_swimcheat(ItemInfo* item, CollisionInfo* coll)
if (TrInput & IN_ACTION)
TriggerDynamicLight(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, 31, 150, 150, 150);
if (TrInput & IN_OPTION)
lara->Control.TurnRate = -ANGLE(12.0f);
if (TrInput & IN_JUMP)
{
item->Animation.Velocity.y += LARA_SWIM_VELOCITY_ACCEL * 2;

View file

@ -65,7 +65,7 @@ void lara_as_crouch_idle(ItemInfo* item, CollisionInfo* coll)
if (TrInput & (IN_LEFT | IN_RIGHT))
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_CRAWL_TURN_RATE_MAX);
if ((TrInput & IN_CROUCH || lara->Control.KeepLow) &&
if ((IsHeld(In::Crouch) || lara->Control.KeepLow) &&
lara->Control.WaterStatus != WaterStatus::Wade)
{
if (TrInput & IN_ROLL || (TrInput & IN_FORWARD && TrInput & IN_BACK))
@ -243,7 +243,7 @@ void lara_as_crouch_turn_left(ItemInfo* item, CollisionInfo* coll)
if (TrInput & IN_LOOK)
LookUpDown(item);
if ((TrInput & IN_CROUCH || lara->Control.KeepLow) &&
if ((IsHeld(In::Crouch) || lara->Control.KeepLow) &&
lara->Control.WaterStatus != WaterStatus::Wade)
{
if (TrInput & IN_SPRINT && TestLaraCrouchRoll(item, coll) &&
@ -300,7 +300,7 @@ void lara_as_crouch_turn_right(ItemInfo* item, CollisionInfo* coll)
if (TrInput & IN_LOOK)
LookUpDown(item);
if ((TrInput & IN_CROUCH || lara->Control.KeepLow) &&
if ((IsHeld(In::Crouch) || lara->Control.KeepLow) &&
lara->Control.WaterStatus != WaterStatus::Wade)
{
if (TrInput & IN_SPRINT && TestLaraCrouchRoll(item, coll) &&
@ -348,7 +348,7 @@ void lara_as_crouch_turn_180(ItemInfo* item, CollisionInfo* coll)
AlignLaraToSurface(item);
if ((TrInput & IN_CROUCH || lara->Control.KeepLow) &&
if ((IsHeld(In::Crouch) || lara->Control.KeepLow) &&
lara->Control.WaterStatus != WaterStatus::Wade)
{
if (TrInput & (IN_FORWARD | IN_BACK) && TestLaraCrouchToCrawl(item))
@ -409,7 +409,7 @@ void lara_as_crawl_idle(ItemInfo* item, CollisionInfo* coll)
if (TrInput & (IN_LEFT | IN_RIGHT))
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_CRAWL_TURN_RATE_MAX);
if ((TrInput & IN_CROUCH || lara->Control.KeepLow) &&
if ((IsHeld(In::Crouch) || lara->Control.KeepLow) &&
lara->Control.WaterStatus != WaterStatus::Wade)
{
if (TrInput & IN_ROLL || (TrInput & IN_FORWARD && TrInput & IN_BACK))
@ -419,7 +419,7 @@ void lara_as_crawl_idle(ItemInfo* item, CollisionInfo* coll)
}
if ((TrInput & IN_SPRINT && TestLaraCrouchRoll(item, coll)) ||
(TrInput & (IN_DRAW | IN_FLARE) &&
((IsHeld(In::Draw) || IsHeld(In::Flare)) &&
!IsStandingWeapon(item, lara->Control.Weapon.GunType) && HasStateDispatch(item, LS_CROUCH_IDLE)))
{
item->Animation.TargetState = LS_CROUCH_IDLE;
@ -548,7 +548,7 @@ void lara_as_crawl_forward(ItemInfo* item, CollisionInfo* coll)
ModulateLaraCrawlFlex(item, LARA_CRAWL_FLEX_RATE, LARA_CRAWL_FLEX_MAX);
}
if ((TrInput & IN_CROUCH || lara->Control.KeepLow) &&
if ((IsHeld(In::Crouch) || lara->Control.KeepLow) &&
lara->Control.WaterStatus != WaterStatus::Wade)
{
if (TrInput & IN_SPRINT && TestLaraCrouchRoll(item, coll))
@ -644,7 +644,7 @@ void lara_as_crawl_back(ItemInfo* item, CollisionInfo* coll)
ModulateLaraCrawlFlex(item, LARA_CRAWL_FLEX_RATE, LARA_CRAWL_FLEX_MAX);
}
if ((TrInput & IN_CROUCH || lara->Control.KeepLow) &&
if ((IsHeld(In::Crouch) || lara->Control.KeepLow) &&
lara->Control.WaterStatus != WaterStatus::Wade)
{
if (TrInput & IN_BACK)
@ -725,7 +725,7 @@ void lara_as_crawl_turn_left(ItemInfo* item, CollisionInfo* coll)
return;
}
if ((TrInput & IN_CROUCH || lara->Control.KeepLow) &&
if ((IsHeld(In::Crouch) || lara->Control.KeepLow) &&
lara->Control.WaterStatus != WaterStatus::Wade)
{
if (TrInput & IN_SPRINT && TestLaraCrouchRoll(item, coll))
@ -786,7 +786,7 @@ void lara_as_crawl_turn_right(ItemInfo* item, CollisionInfo* coll)
return;
}
if ((TrInput & IN_CROUCH || lara->Control.KeepLow) &&
if ((IsHeld(In::Crouch) || lara->Control.KeepLow) &&
lara->Control.WaterStatus != WaterStatus::Wade)
{
if (TrInput & IN_SPRINT && TestLaraCrouchRoll(item, coll))
@ -839,7 +839,7 @@ void lara_as_crawl_turn_180(ItemInfo* item, CollisionInfo* coll)
AlignLaraToSurface(item);
if ((TrInput & IN_CROUCH || lara->Control.KeepLow) &&
if ((IsHeld(In::Crouch) || lara->Control.KeepLow) &&
lara->Control.WaterStatus != WaterStatus::Wade)
{
item->Animation.TargetState = LS_CRAWL_IDLE;

View file

@ -501,7 +501,7 @@ void HandleWeapon(ItemInfo& laraItem)
else if (player.Control.HandStatus == HandStatus::Free)
{
// Draw weapon.
if (IsHeld(In::DrawWeapon))
if (IsHeld(In::Draw))
{
// No weapon - no any actions.
if (player.Control.Weapon.LastGunType != LaraWeaponType::None)
@ -529,7 +529,7 @@ void HandleWeapon(ItemInfo& laraItem)
}
}
if ((IsHeld(In::DrawWeapon) && player.Control.Weapon.LastGunType != LaraWeaponType::None) ||
if ((IsHeld(In::Draw) && player.Control.Weapon.LastGunType != LaraWeaponType::None) ||
player.Control.Weapon.RequestGunType != player.Control.Weapon.GunType)
{
if (player.Control.IsLow &&
@ -578,7 +578,7 @@ void HandleWeapon(ItemInfo& laraItem)
}
else if (player.Control.HandStatus == HandStatus::WeaponReady)
{
if (IsHeld(In::DrawWeapon) ||
if (IsHeld(In::Draw) ||
player.Control.Weapon.RequestGunType != player.Control.Weapon.GunType)
{
player.Control.HandStatus = HandStatus::WeaponUndraw;

View file

@ -13,6 +13,7 @@
#include "Game/Lara/lara_collide.h"
#include "Game/Lara/lara_fire.h"
#include "Game/Lara/lara_tests.h"
#include "Game/savegame.h"
#include "Game/Setup.h"
#include "Math/Math.h"
#include "Renderer/Renderer11.h"
@ -68,7 +69,7 @@ void HandleLaraMovementParameters(ItemInfo* item, CollisionInfo* coll)
lara->Control.RunJumpQueued = false;
// Reset lean.
if ((!lara->Control.IsMoving || (lara->Control.IsMoving && !(TrInput & (IN_LEFT | IN_RIGHT)))) &&
if ((!lara->Control.IsMoving || (lara->Control.IsMoving && !(IsHeld(In::Left) || IsHeld(In::Right)))) &&
(!lara->Control.IsLow && item->Animation.ActiveState != LS_DEATH)) // HACK: Don't interfere with surface alignment in crouch, crawl, and death states.
{
ResetPlayerLean(item, 1 / 6.0f);
@ -76,20 +77,186 @@ void HandleLaraMovementParameters(ItemInfo* item, CollisionInfo* coll)
// Reset crawl flex.
if (!(TrInput & IN_LOOK) && coll->Setup.Height > LARA_HEIGHT - LARA_HEADROOM && // HACK
(!item->Animation.Velocity.z || (item->Animation.Velocity.z && !(TrInput & (IN_LEFT | IN_RIGHT)))))
(!item->Animation.Velocity.z || (item->Animation.Velocity.z && !(IsHeld(In::Left) || IsHeld(In::Right)))))
{
ResetPlayerFlex(item, 0.1f);
}
// Apply and reset turn rate.
item->Pose.Orientation.y += lara->Control.TurnRate;
if (!(TrInput & (IN_LEFT | IN_RIGHT)))
if (!(IsHeld(In::Left) || IsHeld(In::Right)))
lara->Control.TurnRate = 0;
lara->Control.IsLow = false;
lara->Control.IsMonkeySwinging = false;
}
static void UsePlayerMedipack(ItemInfo& item)
{
auto& player = GetLaraInfo(item);
// Can't use medipack; return early.
if (item.HitPoints <= 0 ||
(item.HitPoints >= LARA_HEALTH_MAX && player.Status.Poison == 0))
{
return;
}
bool hasUsedMedipack = false;
if (IsClicked(In::SmallMedipack) &&
player.Inventory.TotalSmallMedipacks != 0)
{
hasUsedMedipack = true;
item.HitPoints += LARA_HEALTH_MAX / 2;
if (item.HitPoints > LARA_HEALTH_MAX)
item.HitPoints = LARA_HEALTH_MAX;
if (player.Inventory.TotalSmallMedipacks != -1)
player.Inventory.TotalSmallMedipacks--;
}
else if (IsClicked(In::LargeMedipack) &&
player.Inventory.TotalLargeMedipacks != 0)
{
hasUsedMedipack = true;
item.HitPoints = LARA_HEALTH_MAX;
if (player.Inventory.TotalLargeMedipacks != -1)
player.Inventory.TotalLargeMedipacks--;
}
if (hasUsedMedipack)
{
player.Status.Poison = 0;
Statistics.Game.HealthUsed++;
SoundEffect(SFX_TR4_MENU_MEDI, nullptr, SoundEnvironment::Always);
}
}
static std::optional<LaraWeaponType> GetPlayerScrolledWeaponType(const ItemInfo& item, LaraWeaponType currentWeaponType, bool getPrev)
{
static const auto SCROLL_WEAPON_TYPES = std::vector<LaraWeaponType>
{
LaraWeaponType::Pistol,
LaraWeaponType::Shotgun,
LaraWeaponType::Uzi,
LaraWeaponType::Revolver,
LaraWeaponType::GrenadeLauncher,
LaraWeaponType::Crossbow,
LaraWeaponType::HarpoonGun,
LaraWeaponType::HK,
LaraWeaponType::RocketLauncher
};
auto& player = GetLaraInfo(item);
// Get vector index for current weapon type.
auto currentIndex = std::optional<unsigned int>(std::nullopt);
for (int i = 0; i < SCROLL_WEAPON_TYPES.size(); i++)
{
if (SCROLL_WEAPON_TYPES[i] == currentWeaponType)
{
currentIndex = i;
break;
}
}
// Invalid current weapon type; return nullopt.
if (!currentIndex.has_value())
return std::nullopt;
// Getter for next index.
auto getNextIndex = [getPrev](unsigned int index)
{
return (index + (getPrev ? ((unsigned int)SCROLL_WEAPON_TYPES.size() - 1) : 1)) % (unsigned int)SCROLL_WEAPON_TYPES.size();
};
// Get next valid weapon type in sequence.
unsigned int nextIndex = getNextIndex(*currentIndex);
while (nextIndex != *currentIndex)
{
auto nextWeaponType = SCROLL_WEAPON_TYPES[nextIndex];
if (player.Weapons[(int)nextWeaponType].Present)
return nextWeaponType;
nextIndex = getNextIndex(nextIndex);
}
// No valid weapon type; return nullopt.
return std::nullopt;
}
void HandlePlayerQuickActions(ItemInfo& item)
{
auto& player = GetLaraInfo(item);
// Handle medipacks.
if (IsClicked(In::SmallMedipack) || IsClicked(In::LargeMedipack))
UsePlayerMedipack(item);
// Handle weapon scroll requests.
if (IsClicked(In::PreviousWeapon) || IsClicked(In::NextWeapon))
{
bool getPrev = IsClicked(In::PreviousWeapon);
auto weaponType = GetPlayerScrolledWeaponType(item, player.Control.Weapon.GunType, getPrev);
if (weaponType.has_value())
player.Control.Weapon.RequestGunType = *weaponType;
}
// Handle weapon requests.
if (IsClicked(In::Weapon1) && player.Weapons[(int)LaraWeaponType::Pistol].Present)
player.Control.Weapon.RequestGunType = LaraWeaponType::Pistol;
if (IsClicked(In::Weapon2) && player.Weapons[(int)LaraWeaponType::Shotgun].Present)
player.Control.Weapon.RequestGunType = LaraWeaponType::Shotgun;
if (IsClicked(In::Weapon3) && player.Weapons[(int)LaraWeaponType::Uzi].Present)
player.Control.Weapon.RequestGunType = LaraWeaponType::Uzi;
if (IsClicked(In::Weapon4) && player.Weapons[(int)LaraWeaponType::Revolver].Present)
player.Control.Weapon.RequestGunType = LaraWeaponType::Revolver;
if (IsClicked(In::Weapon5) && player.Weapons[(int)LaraWeaponType::GrenadeLauncher].Present)
player.Control.Weapon.RequestGunType = LaraWeaponType::GrenadeLauncher;
if (IsClicked(In::Weapon6) && player.Weapons[(int)LaraWeaponType::Crossbow].Present)
player.Control.Weapon.RequestGunType = LaraWeaponType::Crossbow;
if (IsClicked(In::Weapon7) && player.Weapons[(int)LaraWeaponType::HarpoonGun].Present)
player.Control.Weapon.RequestGunType = LaraWeaponType::HarpoonGun;
if (IsClicked(In::Weapon8) && player.Weapons[(int)LaraWeaponType::HK].Present)
player.Control.Weapon.RequestGunType = LaraWeaponType::HK;
if (IsClicked(In::Weapon9) && player.Weapons[(int)LaraWeaponType::RocketLauncher].Present)
player.Control.Weapon.RequestGunType = LaraWeaponType::RocketLauncher;
// TODO: 10th possible weapon, probably grapple gun.
/*if (IsClicked(In::Weapon10) && player.Weapons[(int)LaraWeaponType::].Present)
player.Control.Weapon.RequestGunType = LaraWeaponType::;*/
// TODO: Could theoretically remove SwitchTarget and instead do unique behaviour handling using only Look. -- Sezz 2023.07.08
// HACK: Handle target switch when locked on to an entity.
if (player.Control.HandStatus == HandStatus::WeaponReady &&
player.TargetEntity != nullptr)
{
if (IsClicked(In::Look))
{
ActionMap[(int)In::SwitchTarget].Update(true);
}
else
{
ClearAction(In::SwitchTarget);
}
}
else
{
ClearAction(In::SwitchTarget);
}
}
bool HandleLaraVehicle(ItemInfo* item, CollisionInfo* coll)
{
auto* lara = GetLaraInfo(item);
@ -229,7 +396,7 @@ void HandlePlayerAirBubbles(ItemInfo* item)
SoundEffect(SFX_TR4_LARA_BUBBLES, &item->Pose, SoundEnvironment::Water);
const auto& level = *g_GameFlow->GetLevel(CurrentLevel);
auto pos = (level.GetLaraType() == LaraType::Divesuit) ?
GetJointPosition(item, LM_TORSO, Vector3i(0, -192, -160)).ToVector3() :
GetJointPosition(item, LM_HEAD, Vector3i(0, -4, -64)).ToVector3();
@ -513,7 +680,7 @@ void ModulateLaraSwimTurnRates(ItemInfo* item, CollisionInfo* coll)
auto* lara = GetLaraInfo(item);
/*if (TrInput & (IN_FORWARD | IN_BACK))
ModulateLaraTurnRateX(item, 0, 0, 0);*/
ModulateLaraTurnRateX(item, 0, 0, 0);*/
if (TrInput & IN_FORWARD)
item->Pose.Orientation.x -= ANGLE(3.0f);
@ -686,7 +853,7 @@ void ModulateLaraSlideVelocity(ItemInfo* item, CollisionInfo* coll)
//lara->ExtraVelocity.y += slideVelocity * phd_sin(steepness);
}
//else
//lara->ExtraVelocity.x += minVelocity;
//lara->ExtraVelocity.x += minVelocity;
}
void AlignLaraToSurface(ItemInfo* item, float alpha)

View file

@ -12,6 +12,7 @@ struct VaultTestResult;
// -----------------------------
void HandleLaraMovementParameters(ItemInfo* item, CollisionInfo* coll);
void HandlePlayerQuickActions(ItemInfo& item);
bool HandleLaraVehicle(ItemInfo* item, CollisionInfo* coll);
void HandlePlayerWetnessDrips(ItemInfo& item);
void HandlePlayerDiveBubbles(ItemInfo& item);

View file

@ -265,12 +265,12 @@ void lara_as_jump_prepare(ItemInfo* item, CollisionInfo* coll)
}
// JUMP key repressed without directional key; cancel directional jump lock.
if (DbInput & IN_JUMP && !IsDirectionActionHeld())
if (DbInput & IN_JUMP && !IsDirectionalActionHeld())
lara->Control.JumpDirection = JumpDirection::None;
if (((TrInput & IN_FORWARD &&
!(TrInput & IN_BACK && lara->Control.JumpDirection == JumpDirection::Back)) || // Back jump takes priority in this exception.
!IsDirectionActionHeld() && lara->Control.JumpDirection == JumpDirection::Forward) &&
!IsDirectionalActionHeld() && lara->Control.JumpDirection == JumpDirection::Forward) &&
TestLaraJumpForward(item, coll))
{
item->Animation.TargetState = LS_JUMP_FORWARD;
@ -278,7 +278,7 @@ void lara_as_jump_prepare(ItemInfo* item, CollisionInfo* coll)
return;
}
else if ((TrInput & IN_BACK ||
!IsDirectionActionHeld() && lara->Control.JumpDirection == JumpDirection::Back) &&
!IsDirectionalActionHeld() && lara->Control.JumpDirection == JumpDirection::Back) &&
TestLaraJumpBack(item, coll))
{
item->Animation.TargetState = LS_JUMP_BACK;
@ -287,7 +287,7 @@ void lara_as_jump_prepare(ItemInfo* item, CollisionInfo* coll)
}
if ((TrInput & IN_LEFT ||
!IsDirectionActionHeld() && lara->Control.JumpDirection == JumpDirection::Left) &&
!IsDirectionalActionHeld() && lara->Control.JumpDirection == JumpDirection::Left) &&
TestLaraJumpLeft(item, coll))
{
item->Animation.TargetState = LS_JUMP_LEFT;
@ -295,7 +295,7 @@ void lara_as_jump_prepare(ItemInfo* item, CollisionInfo* coll)
return;
}
else if ((TrInput & IN_RIGHT ||
!IsDirectionActionHeld() && lara->Control.JumpDirection == JumpDirection::Right) &&
!IsDirectionalActionHeld() && lara->Control.JumpDirection == JumpDirection::Right) &&
TestLaraJumpRight(item, coll))
{
item->Animation.TargetState = LS_JUMP_RIGHT;

View file

@ -1194,11 +1194,11 @@ bool TestLaraPose(ItemInfo* item, CollisionInfo* coll)
if (TestEnvironment(ENV_FLAG_SWAMP, item))
return false;
if (!(TrInput & (IN_FLARE | IN_DRAW)) && // Avoid unsightly concurrent actions.
if (!IsHeld(In::Draw) && !IsHeld(In::Flare) && // Avoid unsightly concurrent actions.
lara->Control.HandStatus == HandStatus::Free && // Hands are free.
(lara->Control.Weapon.GunType != LaraWeaponType::Flare || // Flare is not being handled.
lara->Flare.Life) &&
lara->Context.Vehicle == NO_ITEM) // Not in a vehicle.
lara->Context.Vehicle == NO_ITEM) // Not in a vehicle.
{
return true;
}
@ -1665,7 +1665,7 @@ bool TestLaraCrouchToCrawl(ItemInfo* item)
{
auto* lara = GetLaraInfo(item);
if (!(TrInput & (IN_FLARE | IN_DRAW)) && // Avoid unsightly concurrent actions.
if (!IsHeld(In::Draw) && !IsHeld(In::Flare) && // Avoid unsightly concurrent actions.
lara->Control.HandStatus == HandStatus::Free && // Hands are free.
(lara->Control.Weapon.GunType != LaraWeaponType::Flare || // Not handling flare. TODO: Should be allowed, but the flare animation bugs out right now. @Sezz 2022.03.18
lara->Flare.Life))

View file

@ -1171,7 +1171,7 @@ void BinocularCamera(ItemInfo* item)
if (!LaserSight)
{
if (IsClicked(In::Deselect) ||
IsClicked(In::DrawWeapon) ||
IsClicked(In::Draw) ||
IsClicked(In::Look) ||
IsHeld(In::Flare))
{

View file

@ -633,7 +633,7 @@ GameStatus HandleMenuCalls(bool isTitle)
if (g_Gui.CallPause())
result = GameStatus::ExitToTitle;
}
else if ((IsClicked(In::Option) || g_Gui.GetEnterInventory() != NO_ITEM) &&
else if ((IsClicked(In::Inventory) || g_Gui.GetEnterInventory() != NO_ITEM) &&
LaraItem->HitPoints > 0 && !BinocularOn)
{
if (g_Gui.CallInventory(LaraItem, true))

View file

@ -41,7 +41,7 @@ namespace TEN::Gui
GuiController g_Gui;
const char* OptionStrings[] =
std::vector<const char*> OptionStrings = std::vector<const char*>
{
STRING_USE,
STRING_CHOOSE_AMMO,
@ -58,31 +58,61 @@ namespace TEN::Gui
// STRING_READ_DIARY
};
const char* ControlStrings[] =
std::vector<const char*> GeneralActionStrings =
{
STRING_CONTROLS_MOVE_FORWARD,
STRING_CONTROLS_MOVE_BACKWARD,
STRING_CONTROLS_MOVE_LEFT,
STRING_CONTROLS_MOVE_RIGHT,
STRING_CONTROLS_CROUCH,
STRING_CONTROLS_SPRINT,
STRING_CONTROLS_WALK,
STRING_CONTROLS_JUMP,
STRING_CONTROLS_ACTION,
STRING_CONTROLS_DRAW_WEAPON,
STRING_CONTROLS_USE_FLARE,
STRING_CONTROLS_LOOK,
STRING_CONTROLS_ROLL,
STRING_CONTROLS_INVENTORY,
STRING_CONTROLS_PAUSE,
STRING_CONTROLS_STEP_LEFT,
STRING_CONTROLS_STEP_RIGHT,
STRING_CONTROLS_V_ACCELERATE,
STRING_CONTROLS_V_REVERSE,
STRING_CONTROLS_V_SPEED,
STRING_CONTROLS_V_SLOW,
STRING_CONTROLS_V_BRAKE,
STRING_CONTROLS_V_FIRE
STRING_ACTIONS_FORWARD,
STRING_ACTIONS_BACKWARD,
STRING_ACTIONS_LEFT,
STRING_ACTIONS_RIGHT,
STRING_ACTIONS_STEP_LEFT,
STRING_ACTIONS_STEP_RIGHT,
STRING_ACTIONS_ACTION,
STRING_ACTIONS_WALK,
STRING_ACTIONS_SPRINT,
STRING_ACTIONS_CROUCH,
STRING_ACTIONS_JUMP,
STRING_ACTIONS_ROLL,
STRING_ACTIONS_DRAW,
STRING_ACTIONS_LOOK
};
std::vector<const char*> VehicleActionStrings =
{
STRING_ACTIONS_ACCELERATE,
STRING_ACTIONS_REVERSE,
STRING_ACTIONS_SPEED,
STRING_ACTIONS_SLOW,
STRING_ACTIONS_BRAKE,
STRING_ACTIONS_FIRE
};
std::vector<const char*> QuickActionStrings =
{
STRING_ACTIONS_FLARE,
STRING_ACTIONS_SMALL_MEDIPACK,
STRING_ACTIONS_LARGE_MEDIPACK,
STRING_ACTIONS_PREVIOUS_WEAPON,
STRING_ACTIONS_NEXT_WEAPON,
STRING_ACTIONS_WEAPON_1,
STRING_ACTIONS_WEAPON_2,
STRING_ACTIONS_WEAPON_3,
STRING_ACTIONS_WEAPON_4,
STRING_ACTIONS_WEAPON_5,
STRING_ACTIONS_WEAPON_6,
STRING_ACTIONS_WEAPON_7,
STRING_ACTIONS_WEAPON_8,
STRING_ACTIONS_WEAPON_9,
STRING_ACTIONS_WEAPON_10
};
std::vector<const char*> MenuActionStrings =
{
STRING_ACTIONS_SELECT,
STRING_ACTIONS_DESELECT,
STRING_ACTIONS_PAUSE,
STRING_ACTIONS_INVENTORY,
STRING_ACTIONS_SAVE,
STRING_ACTIONS_LOAD
};
bool GuiController::GuiIsPulsed(ActionID actionID) const
@ -90,7 +120,8 @@ namespace TEN::Gui
constexpr auto DELAY = 0.1f;
constexpr auto INITIAL_DELAY = 0.4f;
auto oppositeAction = In::None;
// Pulse only directional inputs.
auto oppositeAction = std::optional<ActionID>(std::nullopt);
switch (actionID)
{
case In::Forward:
@ -108,9 +139,12 @@ namespace TEN::Gui
case In::Right:
oppositeAction = In::Left;
break;
default:
break;
}
bool isActionLocked = (oppositeAction == In::None) ? false : IsHeld(oppositeAction);
bool isActionLocked = oppositeAction.has_value() ? IsHeld(*oppositeAction) : false;
return (IsPulsed(actionID, DELAY, INITIAL_DELAY) && !isActionLocked);
}
@ -121,7 +155,7 @@ namespace TEN::Gui
bool GuiController::GuiIsDeselected() const
{
return (IsClicked(In::Deselect) && CanDeselect());
return ((IsClicked(In::Deselect) || IsClicked(In::Draw)) && CanDeselect());
}
bool GuiController::CanSelect() const
@ -265,7 +299,10 @@ namespace TEN::Gui
HandleDisplaySettingsInput(false);
return inventoryResult;
case Menu::Controls:
case Menu::GeneralActions:
//case Menu::VehicleControls:
case Menu::QuickActions:
case Menu::MenuActions:
HandleControlSettingsInput(item, false);
return inventoryResult;
@ -312,8 +349,7 @@ namespace TEN::Gui
SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always);
}
if (GuiIsDeselected() &&
MenuToDisplay != Menu::Title)
if (GuiIsDeselected() && MenuToDisplay != Menu::Title)
{
MenuToDisplay = Menu::Title;
SelectedOption = selectedOptionBackup;
@ -552,7 +588,26 @@ namespace TEN::Gui
void GuiController::HandleControlSettingsInput(ItemInfo* item, bool fromPauseMenu)
{
static const int numControlSettingsOptions = KEY_COUNT + 2;
unsigned int numControlSettingsOptions = 0;
switch (MenuToDisplay)
{
default:
case Menu::GeneralActions:
numControlSettingsOptions = (int)GeneralActionStrings.size() + 2;
break;
/*case Menu::VehicleControls:
numControlSettingsOptions = (int)VehicleControlStrings.size() + 2;
break;*/
case Menu::QuickActions:
numControlSettingsOptions = (int)QuickActionStrings.size() + 2;
break;
case Menu::MenuActions:
numControlSettingsOptions = (int)MenuActionStrings.size() + 2;
break;
}
OptionCount = numControlSettingsOptions;
CurrentSettings.WaitingForKey = false;
@ -598,9 +653,28 @@ namespace TEN::Gui
if (selectedKey == MAX_INPUT_SLOTS)
selectedKey = 0;
if (selectedKey && g_KeyNames[selectedKey])
if (selectedKey && !g_KeyNames[selectedKey].empty())
{
KeyboardLayout[1][SelectedOption] = selectedKey;
unsigned int baseIndex = 0;
switch (MenuToDisplay)
{
/*case Menu::VehicleControls:
numControlSettingsOptions = (unsigned int)GeneralControlStrings.size();
break;*/
case Menu::QuickActions:
baseIndex = unsigned int(GeneralActionStrings.size());
break;
case Menu::MenuActions:
baseIndex = unsigned int(GeneralActionStrings.size() + QuickActionStrings.size());
break;
default:
break;
}
KeyboardLayout[1][baseIndex + SelectedOption] = selectedKey;
DefaultConflict();
CurrentSettings.WaitingForKey = false;
@ -645,6 +719,43 @@ namespace TEN::Gui
SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always);
}
// HACK: Menu screen scroll.
if (GuiIsPulsed(In::Left) || GuiIsPulsed(In::Right))
{
auto menu = std::optional<Menu>(std::nullopt);
if (GuiIsPulsed(In::Left))
{
if ((int)MenuToDisplay == (int)Menu::GeneralActions)
{
menu = Menu::MenuActions;
}
else
{
menu = Menu((int)MenuToDisplay - 1);
}
}
else if (GuiIsPulsed(In::Right))
{
if ((int)MenuToDisplay == (int)Menu::MenuActions)
{
menu = Menu::GeneralActions;
}
else
{
menu = Menu((int)MenuToDisplay + 1);
}
}
if (menu.has_value())
{
MenuToDisplay = *menu;
SelectedOption = 0;
SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always);
return;
}
}
if (GuiIsSelected())
{
// Defaults.
@ -718,7 +829,7 @@ namespace TEN::Gui
case OptionsOption::Controls:
BackupOptions();
MenuToDisplay = Menu::Controls;
MenuToDisplay = Menu::GeneralActions;
SelectedOption = 0;
break;
}
@ -935,7 +1046,10 @@ namespace TEN::Gui
HandleDisplaySettingsInput(true);
return InventoryResult::None;
case Menu::Controls:
case Menu::GeneralActions:
//case Menu::VehicleControls:
case Menu::QuickActions:
case Menu::MenuActions:
HandleControlSettingsInput(item, true);
return InventoryResult::None;
@ -3012,7 +3126,7 @@ namespace TEN::Gui
UpdateInputActions(item);
if (IsClicked(In::Option))
if (IsClicked(In::Deselect))
{
SoundEffect(SFX_TR4_MENU_SELECT, nullptr, SoundEnvironment::Always);
exitLoop = true;

View file

@ -76,7 +76,10 @@ namespace TEN::Gui
LoadGame,
Options,
Display,
Controls,
GeneralActions,
//VehicleActions,
QuickActions,
MenuActions,
OtherSettings
};
@ -226,5 +229,9 @@ namespace TEN::Gui
};
extern GuiController g_Gui;
extern const char* ControlStrings[];
extern std::vector<const char*> OptionStrings;
extern std::vector<const char*> GeneralActionStrings;
extern std::vector<const char*> VehicleActionStrings;
extern std::vector<const char*> QuickActionStrings;
extern std::vector<const char*> MenuActionStrings;
}

View file

@ -99,8 +99,13 @@ namespace TEN::Renderer
void Renderer11::RenderOptionsMenu(Menu menu, int initialY)
{
constexpr auto RIGHT_ARROW_X_OFFSET = SCREEN_SPACE_RES.x - MenuLeftSideEntry;
static const auto LEFT_ARROW_STRING = std::string("<");
static const auto RIGHT_ARROW_STRING = std::string(">");
static const auto CONTROL_SETTINGS_BLOCK_Y_OFFSET = (MenuVerticalNarrowLineSpacing * (int)QuickActionStrings.size()) + (MenuVerticalBlockSpacing * 2);
int y = 0;
auto title_option = g_Gui.GetSelectedOption();
auto titleOption = g_Gui.GetSelectedOption();
char stringBuffer[32] = {};
auto screenResolution = g_Configuration.SupportedScreenResolutions[g_Gui.GetCurrentSettings().SelectedScreenResolution];
@ -112,45 +117,43 @@ namespace TEN::Renderer
const char* antialiasMode;
switch (g_Gui.GetCurrentSettings().Configuration.Antialiasing)
{
default:
case AntialiasingMode::None:
antialiasMode = STRING_ANTIALIASING_NONE;
break;
default:
case AntialiasingMode::None:
antialiasMode = STRING_ANTIALIASING_NONE;
break;
case AntialiasingMode::Low:
antialiasMode = STRING_ANTIALIASING_LOW;
break;
case AntialiasingMode::Low:
antialiasMode = STRING_ANTIALIASING_LOW;
break;
case AntialiasingMode::Medium:
antialiasMode = STRING_ANTIALIASING_MEDIUM;
break;
case AntialiasingMode::Medium:
antialiasMode = STRING_ANTIALIASING_MEDIUM;
break;
case AntialiasingMode::High:
antialiasMode = STRING_ANTIALIASING_HIGH;
break;
case AntialiasingMode::High:
antialiasMode = STRING_ANTIALIASING_HIGH;
break;
}
switch (menu)
{
case Menu::Options:
// Setup needed parameters
y = initialY;
// Display
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_DISPLAY), PRINTSTRING_COLOR_WHITE, SF_Center(title_option == 0));
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_DISPLAY), PRINTSTRING_COLOR_WHITE, SF_Center(titleOption == 0));
GetNextLinePosition(&y);
// Other options
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_OTHER_SETTINGS), PRINTSTRING_COLOR_WHITE, SF_Center(title_option == 1));
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_OTHER_SETTINGS), PRINTSTRING_COLOR_WHITE, SF_Center(titleOption == 1));
GetNextLinePosition(&y);
// Controls
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_CONTROLS), PRINTSTRING_COLOR_WHITE, SF_Center(title_option == 2));
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_CONTROLS), PRINTSTRING_COLOR_WHITE, SF_Center(titleOption == 2));
break;
case Menu::Display:
// Setup needed parameters
y = MenuVerticalDisplaySettings;
@ -159,40 +162,39 @@ namespace TEN::Renderer
GetNextBlockPosition(&y);
// Screen resolution
AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_SCREEN_RESOLUTION), PRINTSTRING_COLOR_ORANGE, SF(title_option == 0));
AddString(MenuRightSideEntry, y, stringBuffer, PRINTSTRING_COLOR_WHITE, SF(title_option == 0));
AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_SCREEN_RESOLUTION), PRINTSTRING_COLOR_ORANGE, SF(titleOption == 0));
AddString(MenuRightSideEntry, y, stringBuffer, PRINTSTRING_COLOR_WHITE, SF(titleOption == 0));
GetNextLinePosition(&y);
// Windowed mode
AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_WINDOWED), PRINTSTRING_COLOR_ORANGE, SF(title_option == 1));
AddString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().Configuration.Windowed), PRINTSTRING_COLOR_WHITE, SF(title_option == 1));
AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_WINDOWED), PRINTSTRING_COLOR_ORANGE, SF(titleOption == 1));
AddString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().Configuration.Windowed), PRINTSTRING_COLOR_WHITE, SF(titleOption == 1));
GetNextLinePosition(&y);
// Enable dynamic shadows
AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_SHADOWS), PRINTSTRING_COLOR_ORANGE, SF(title_option == 2));
AddString(MenuRightSideEntry, y, g_GameFlow->GetString(shadowMode), PRINTSTRING_COLOR_WHITE, SF(title_option == 2));
AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_SHADOWS), PRINTSTRING_COLOR_ORANGE, SF(titleOption == 2));
AddString(MenuRightSideEntry, y, g_GameFlow->GetString(shadowMode), PRINTSTRING_COLOR_WHITE, SF(titleOption == 2));
GetNextLinePosition(&y);
// Enable caustics
AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_CAUSTICS), PRINTSTRING_COLOR_ORANGE, SF(title_option == 3));
AddString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().Configuration.EnableCaustics), PRINTSTRING_COLOR_WHITE, SF(title_option == 3));
AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_CAUSTICS), PRINTSTRING_COLOR_ORANGE, SF(titleOption == 3));
AddString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().Configuration.EnableCaustics), PRINTSTRING_COLOR_WHITE, SF(titleOption == 3));
GetNextLinePosition(&y);
// Enable antialiasing
AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_ANTIALIASING), PRINTSTRING_COLOR_ORANGE, SF(title_option == 4));
AddString(MenuRightSideEntry, y, g_GameFlow->GetString(antialiasMode), PRINTSTRING_COLOR_WHITE, SF(title_option == 4));
AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_ANTIALIASING), PRINTSTRING_COLOR_ORANGE, SF(titleOption == 4));
AddString(MenuRightSideEntry, y, g_GameFlow->GetString(antialiasMode), PRINTSTRING_COLOR_WHITE, SF(titleOption == 4));
GetNextBlockPosition(&y);
// Apply
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_APPLY), PRINTSTRING_COLOR_ORANGE, SF_Center(title_option == 5));
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_APPLY), PRINTSTRING_COLOR_ORANGE, SF_Center(titleOption == 5));
GetNextLinePosition(&y);
// Cancel
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_CANCEL), PRINTSTRING_COLOR_ORANGE, SF_Center(title_option == 6));
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_CANCEL), PRINTSTRING_COLOR_ORANGE, SF_Center(titleOption == 6));
break;
case Menu::OtherSettings:
// Setup needed parameters
y = MenuVerticalOtherSettings;
@ -201,8 +203,8 @@ namespace TEN::Renderer
GetNextBlockPosition(&y);
// Enable sound special effects
AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_REVERB), PRINTSTRING_COLOR_ORANGE, SF(title_option == 0));
AddString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().Configuration.EnableReverb), PRINTSTRING_COLOR_WHITE, SF(title_option == 0));
AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_REVERB), PRINTSTRING_COLOR_ORANGE, SF(titleOption == 0));
AddString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().Configuration.EnableReverb), PRINTSTRING_COLOR_WHITE, SF(titleOption == 0));
GetNextLinePosition(&y);
// Initialize bars, if not yet done. Must be done here because we're calculating Y coord on the fly.
@ -210,89 +212,200 @@ namespace TEN::Renderer
InitializeMenuBars(y);
// Music volume
AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_MUSIC_VOLUME), PRINTSTRING_COLOR_ORANGE, SF(title_option == 1));
AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_MUSIC_VOLUME), PRINTSTRING_COLOR_ORANGE, SF(titleOption == 1));
DrawBar(g_Gui.GetCurrentSettings().Configuration.MusicVolume / 100.0f, *g_MusicVolumeBar, ID_SFX_BAR_TEXTURE, 0, false);
GetNextLinePosition(&y);
// Sound FX volume
AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_SFX_VOLUME), PRINTSTRING_COLOR_ORANGE, SF(title_option == 2));
AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_SFX_VOLUME), PRINTSTRING_COLOR_ORANGE, SF(titleOption == 2));
DrawBar(g_Gui.GetCurrentSettings().Configuration.SfxVolume / 100.0f, *g_SFXVolumeBar, ID_SFX_BAR_TEXTURE, 0, false);
GetNextBlockPosition(&y);
// Subtitles
AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_SUBTITLES), PRINTSTRING_COLOR_ORANGE, SF(title_option == 3));
AddString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().Configuration.EnableSubtitles), PRINTSTRING_COLOR_WHITE, SF(title_option == 3));
AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_SUBTITLES), PRINTSTRING_COLOR_ORANGE, SF(titleOption == 3));
AddString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().Configuration.EnableSubtitles), PRINTSTRING_COLOR_WHITE, SF(titleOption == 3));
GetNextLinePosition(&y);
// Auto targeting
AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_AUTO_TARGET), PRINTSTRING_COLOR_ORANGE, SF(title_option == 4));
AddString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().Configuration.AutoTarget), PRINTSTRING_COLOR_WHITE, SF(title_option == 4));
AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_AUTO_TARGET), PRINTSTRING_COLOR_ORANGE, SF(titleOption == 4));
AddString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().Configuration.AutoTarget), PRINTSTRING_COLOR_WHITE, SF(titleOption == 4));
GetNextLinePosition(&y);
// Vibration
AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_RUMBLE), PRINTSTRING_COLOR_ORANGE, SF(title_option == 5));
AddString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().Configuration.EnableRumble), PRINTSTRING_COLOR_WHITE, SF(title_option == 5));
AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_RUMBLE), PRINTSTRING_COLOR_ORANGE, SF(titleOption == 5));
AddString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().Configuration.EnableRumble), PRINTSTRING_COLOR_WHITE, SF(titleOption == 5));
GetNextLinePosition(&y);
// Thumbstick camera
AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_THUMBSTICK_CAMERA), PRINTSTRING_COLOR_ORANGE, SF(title_option == 6));
AddString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().Configuration.EnableThumbstickCameraControl), PRINTSTRING_COLOR_WHITE, SF(title_option == 6));
AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_THUMBSTICK_CAMERA), PRINTSTRING_COLOR_ORANGE, SF(titleOption == 6));
AddString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().Configuration.EnableThumbstickCameraControl), PRINTSTRING_COLOR_WHITE, SF(titleOption == 6));
GetNextBlockPosition(&y);
// Apply
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_APPLY), PRINTSTRING_COLOR_ORANGE, SF_Center(title_option == 7));
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_APPLY), PRINTSTRING_COLOR_ORANGE, SF_Center(titleOption == 7));
GetNextLinePosition(&y);
// Cancel
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_CANCEL), PRINTSTRING_COLOR_ORANGE, SF_Center(title_option == 8));
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_CANCEL), PRINTSTRING_COLOR_ORANGE, SF_Center(titleOption == 8));
break;
case Menu::Controls:
// Setup needed parameters
y = MenuVerticalTop;
// Title
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_CONTROLS), PRINTSTRING_COLOR_YELLOW, SF_Center());
GetNextBlockPosition(&y);
// Control listing
for (int k = 0; k < KEY_COUNT; k++)
case Menu::GeneralActions:
{
AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(ControlStrings[k]), PRINTSTRING_COLOR_WHITE, SF(title_option == k));
// Set up needed parameters.
y = MenuVerticalTop;
if (g_Gui.GetCurrentSettings().WaitingForKey && title_option == k)
AddString(MenuRightSideEntry, y, g_GameFlow->GetString(STRING_WAITING_FOR_INPUT), PRINTSTRING_COLOR_YELLOW, SF(true));
else
// Arrows
AddString(RIGHT_ARROW_X_OFFSET, y, RIGHT_ARROW_STRING.c_str(), PRINTSTRING_COLOR_YELLOW, SF(true));
// Title
auto titleString = std::string(g_GameFlow->GetString(STRING_GENERAL_ACTIONS));
AddString(MenuCenterEntry, y, titleString.c_str(), PRINTSTRING_COLOR_YELLOW, SF_Center());
GetNextBlockPosition(&y);
// General action listing
for (int k = 0; k < GeneralActionStrings.size(); k++)
{
int index = KeyboardLayout[1][k] ? KeyboardLayout[1][k] : KeyboardLayout[0][k];
AddString(MenuRightSideEntry, y, (char*)g_KeyNames[index], PRINTSTRING_COLOR_ORANGE, SF(false));
AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(GeneralActionStrings[k]), PRINTSTRING_COLOR_WHITE, SF(titleOption == k));
if (g_Gui.GetCurrentSettings().WaitingForKey && titleOption == k)
{
AddString(MenuRightSideEntry, y, g_GameFlow->GetString(STRING_WAITING_FOR_INPUT), PRINTSTRING_COLOR_YELLOW, SF(true));
}
else
{
int index = KeyboardLayout[1][k] ? KeyboardLayout[1][k] : KeyboardLayout[0][k];
AddString(MenuRightSideEntry, y, g_KeyNames[index].c_str(), PRINTSTRING_COLOR_ORANGE, SF(false));
}
if (k < (GeneralActionStrings.size() - 1))
GetNextNarrowLinePosition(&y);
}
if (k < KEY_COUNT - 1)
GetNextNarrowLinePosition(&y);
else
GetNextBlockPosition(&y);
y = CONTROL_SETTINGS_BLOCK_Y_OFFSET;
// Reset to defaults
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_RESET_TO_DEFAULTS), PRINTSTRING_COLOR_ORANGE, SF_Center(titleOption == GeneralActionStrings.size()));
GetNextLinePosition(&y);
// Apply
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_APPLY), PRINTSTRING_COLOR_ORANGE, SF_Center(titleOption == (GeneralActionStrings.size() + 1)));
GetNextLinePosition(&y);
// Cancel
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_CANCEL), PRINTSTRING_COLOR_ORANGE, SF_Center(titleOption == (GeneralActionStrings.size() + 2)));
break;
}
// Defaults
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_CONTROLS_DEFAULTS), PRINTSTRING_COLOR_ORANGE, SF_Center(title_option == 17));
GetNextLinePosition(&y);
// Apply
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_APPLY), PRINTSTRING_COLOR_ORANGE, SF_Center(title_option == 18));
GetNextLinePosition(&y);
// Cancel
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_CANCEL), PRINTSTRING_COLOR_ORANGE, SF_Center(title_option == 19));
/*case Menu::VehicleControls:
{
break;
}*/
case Menu::QuickActions:
{
// Set up needed parameters.
y = MenuVerticalTop;
// Arrows
AddString(MenuLeftSideEntry, y, LEFT_ARROW_STRING.c_str(), PRINTSTRING_COLOR_YELLOW, SF(true));
AddString(RIGHT_ARROW_X_OFFSET, y, RIGHT_ARROW_STRING.c_str(), PRINTSTRING_COLOR_YELLOW, SF(true));
// Title
auto titleString = std::string(g_GameFlow->GetString(STRING_QUICK_ACTIONS));
AddString(MenuCenterEntry, y, titleString.c_str(), PRINTSTRING_COLOR_YELLOW, SF_Center());
GetNextBlockPosition(&y);
int baseIndex = KEY_FLARE;
// Quick action listing
for (int k = 0; k < QuickActionStrings.size(); k++)
{
AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(QuickActionStrings[k]), PRINTSTRING_COLOR_WHITE, SF(titleOption == k));
if (g_Gui.GetCurrentSettings().WaitingForKey && titleOption == k)
{
AddString(MenuRightSideEntry, y, g_GameFlow->GetString(STRING_WAITING_FOR_INPUT), PRINTSTRING_COLOR_YELLOW, SF(true));
}
else
{
int index = KeyboardLayout[1][baseIndex + k] ? KeyboardLayout[1][baseIndex + k] : KeyboardLayout[0][baseIndex + k];
AddString(MenuRightSideEntry, y, g_KeyNames[index].c_str(), PRINTSTRING_COLOR_ORANGE, SF(false));
}
if (k < (QuickActionStrings.size() - 1))
GetNextNarrowLinePosition(&y);
}
y = CONTROL_SETTINGS_BLOCK_Y_OFFSET;
// Reset to defaults
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_RESET_TO_DEFAULTS), PRINTSTRING_COLOR_ORANGE, SF_Center(titleOption == QuickActionStrings.size()));
GetNextLinePosition(&y);
// Apply
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_APPLY), PRINTSTRING_COLOR_ORANGE, SF_Center(titleOption == (QuickActionStrings.size() + 1)));
GetNextLinePosition(&y);
// Cancel
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_CANCEL), PRINTSTRING_COLOR_ORANGE, SF_Center(titleOption == (QuickActionStrings.size() + 2)));
break;
}
case Menu::MenuActions:
{
// Setup needed parameters.
y = MenuVerticalTop;
// Arrows
AddString(MenuLeftSideEntry, y, LEFT_ARROW_STRING.c_str(), PRINTSTRING_COLOR_YELLOW, SF(true));
// Title
auto titleString = std::string(g_GameFlow->GetString(STRING_MENU_ACTIONS));
AddString(MenuCenterEntry, y, titleString.c_str(), PRINTSTRING_COLOR_YELLOW, SF_Center());
GetNextBlockPosition(&y);
int baseIndex = KEY_SELECT;
// Menu action listing.
for (int k = 0; k < MenuActionStrings.size(); k++)
{
AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(MenuActionStrings[k]), PRINTSTRING_COLOR_WHITE, SF(titleOption == k));
if (g_Gui.GetCurrentSettings().WaitingForKey && titleOption == k)
{
AddString(MenuRightSideEntry, y, g_GameFlow->GetString(STRING_WAITING_FOR_INPUT), PRINTSTRING_COLOR_YELLOW, SF(true));
}
else
{
int index = KeyboardLayout[1][baseIndex + k] ? KeyboardLayout[1][baseIndex + k] : KeyboardLayout[0][baseIndex + k];
AddString(MenuRightSideEntry, y, g_KeyNames[index].c_str(), PRINTSTRING_COLOR_ORANGE, SF(false));
}
if (k < (MenuActionStrings.size() - 1))
GetNextNarrowLinePosition(&y);
}
y = CONTROL_SETTINGS_BLOCK_Y_OFFSET;
// Reset to defaults
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_RESET_TO_DEFAULTS), PRINTSTRING_COLOR_ORANGE, SF_Center(titleOption == MenuActionStrings.size()));
GetNextLinePosition(&y);
// Apply
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_APPLY), PRINTSTRING_COLOR_ORANGE, SF_Center(titleOption == (MenuActionStrings.size() + 1)));
GetNextLinePosition(&y);
// Cancel
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_CANCEL), PRINTSTRING_COLOR_ORANGE, SF_Center(titleOption == (MenuActionStrings.size() + 2)));
break;
}
}
}
void Renderer11::RenderTitleMenu(Menu menu)
{
int y = MenuVerticalBottomCenter;
auto title_option = g_Gui.GetSelectedOption();
auto titleOption = g_Gui.GetSelectedOption();
// HACK: Check if it works properly -- Lwmte, 07.06.22
if (menu == Menu::LoadGame && !g_GameFlow->EnableLoadSave)
@ -303,19 +416,19 @@ namespace TEN::Renderer
case Menu::Title:
// New game
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_NEW_GAME), PRINTSTRING_COLOR_WHITE, SF_Center(title_option == 0));
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_NEW_GAME), PRINTSTRING_COLOR_WHITE, SF_Center(titleOption == 0));
GetNextLinePosition(&y);
// Load game
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_LOAD_GAME), PRINTSTRING_COLOR_WHITE, SF_Center(title_option == 1));
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_LOAD_GAME), PRINTSTRING_COLOR_WHITE, SF_Center(titleOption == 1));
GetNextLinePosition(&y);
// Options
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_OPTIONS), PRINTSTRING_COLOR_WHITE, SF_Center(title_option == 2));
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_OPTIONS), PRINTSTRING_COLOR_WHITE, SF_Center(titleOption == 2));
GetNextLinePosition(&y);
// Exit game
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_EXIT_GAME), PRINTSTRING_COLOR_WHITE, SF_Center(title_option == 3));
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_EXIT_GAME), PRINTSTRING_COLOR_WHITE, SF_Center(titleOption == 3));
break;
case Menu::LoadGame:
@ -335,13 +448,16 @@ namespace TEN::Renderer
for (int i = 1; i < g_GameFlow->GetNumLevels(); i++)
{
AddString(MenuCenterEntry, y, g_GameFlow->GetString(g_GameFlow->GetLevel(i)->NameStringKey.c_str()),
PRINTSTRING_COLOR_WHITE, SF_Center(title_option == i - 1));
PRINTSTRING_COLOR_WHITE, SF_Center(titleOption == i - 1));
GetNextNarrowLinePosition(&y);
}
break;
case Menu::Options:
case Menu::Controls:
case Menu::GeneralActions:
//case Menu::VehicleControls:
case Menu::QuickActions:
case Menu::MenuActions:
case Menu::Display:
case Menu::OtherSettings:
RenderOptionsMenu(menu, MenuVerticalOptionsTitle);
@ -352,7 +468,7 @@ namespace TEN::Renderer
void Renderer11::RenderPauseMenu(Menu menu)
{
int y = 0;
auto pause_option = g_Gui.GetSelectedOption();
auto pauseOption = g_Gui.GetSelectedOption();
switch (g_Gui.GetMenuToDisplay())
{
@ -362,19 +478,19 @@ namespace TEN::Renderer
y = MenuVerticalPause;
// Header
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_CONTROLS_PAUSE), PRINTSTRING_COLOR_ORANGE, SF_Center());
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_ACTIONS_PAUSE), PRINTSTRING_COLOR_ORANGE, SF_Center());
GetNextBlockPosition(&y);
// Statistics
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_STATISTICS), PRINTSTRING_COLOR_WHITE, SF_Center(pause_option == 0));
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_STATISTICS), PRINTSTRING_COLOR_WHITE, SF_Center(pauseOption == 0));
GetNextLinePosition(&y);
// Options
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_OPTIONS), PRINTSTRING_COLOR_WHITE, SF_Center(pause_option == 1));
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_OPTIONS), PRINTSTRING_COLOR_WHITE, SF_Center(pauseOption == 1));
GetNextLinePosition(&y);
// Exit to title
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_EXIT_TO_TITLE), PRINTSTRING_COLOR_WHITE, SF_Center(pause_option == 2));
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_EXIT_TO_TITLE), PRINTSTRING_COLOR_WHITE, SF_Center(pauseOption == 2));
break;
case Menu::Statistics:
@ -382,7 +498,10 @@ namespace TEN::Renderer
break;
case Menu::Options:
case Menu::Controls:
case Menu::GeneralActions:
//case Menu::VehicleControls:
case Menu::QuickActions:
case Menu::MenuActions:
case Menu::Display:
case Menu::OtherSettings:
RenderOptionsMenu(menu, MenuVerticalOptionsPause);

View file

@ -43,6 +43,7 @@
#define STRING_SEPARATE "separate"
#define STRING_CHOOSE_AMMO "choose_ammo"
#define STRING_SELECT_LEVEL "select_level"
#define STRING_GENERAL_ACTIONS "general_actions"
#define STRING_GRENADE_LAUNCHER "grenade_launcher"
#define STRING_GRENADE_LAUNCHER_AMMO_1 "grenade_launcher_normal_ammo"
#define STRING_GRENADE_LAUNCHER_AMMO_2 "grenade_launcher_super_ammo"
@ -82,30 +83,33 @@
#define STRING_RUMBLE "rumble"
#define STRING_THUMBSTICK_CAMERA "thumbstick_camera"
#define STRING_SUBTITLES "subtitles"
#define STRING_CONTROLS_MOVE_FORWARD "controls_move_forward"
#define STRING_CONTROLS_MOVE_BACKWARD "controls_move_backward"
#define STRING_CONTROLS_MOVE_LEFT "controls_move_left"
#define STRING_CONTROLS_MOVE_RIGHT "controls_move_right"
#define STRING_CONTROLS_CROUCH "controls_crouch"
#define STRING_CONTROLS_SPRINT "controls_sprint"
#define STRING_CONTROLS_WALK "controls_walk"
#define STRING_CONTROLS_JUMP "controls_jump"
#define STRING_CONTROLS_ACTION "controls_action"
#define STRING_CONTROLS_DRAW_WEAPON "controls_draw_weapon"
#define STRING_CONTROLS_USE_FLARE "controls_use_flare"
#define STRING_CONTROLS_LOOK "controls_look"
#define STRING_CONTROLS_ROLL "controls_roll"
#define STRING_CONTROLS_INVENTORY "controls_inventory"
#define STRING_CONTROLS_PAUSE "controls_pause"
#define STRING_CONTROLS_STEP_LEFT "controls_step_left"
#define STRING_CONTROLS_STEP_RIGHT "controls_step_right"
#define STRING_CONTROLS_V_ACCELERATE "controls_accelerate"
#define STRING_CONTROLS_V_REVERSE "controls_reverse"
#define STRING_CONTROLS_V_SPEED "controls_speed"
#define STRING_CONTROLS_V_SLOW "controls_slow"
#define STRING_CONTROLS_V_BRAKE "controls_brake"
#define STRING_CONTROLS_V_FIRE "controls_fire"
#define STRING_CONTROLS_DEFAULTS "controls_defaults"
#define STRING_ACTIONS_FORWARD "actions_forward"
#define STRING_ACTIONS_BACKWARD "actions_backward"
#define STRING_ACTIONS_LEFT "actions_left"
#define STRING_ACTIONS_RIGHT "actions_right"
#define STRING_ACTIONS_CROUCH "actions_crouch"
#define STRING_ACTIONS_SPRINT "actions_sprint"
#define STRING_ACTIONS_WALK "actions_walk"
#define STRING_ACTIONS_JUMP "actions_jump"
#define STRING_ACTIONS_ACTION "actions_action"
#define STRING_ACTIONS_DRAW "actions_draw"
#define STRING_ACTIONS_LOOK "actions_look"
#define STRING_ACTIONS_ROLL "actions_roll"
#define STRING_ACTIONS_INVENTORY "actions_inventory"
#define STRING_ACTIONS_PAUSE "actions_pause"
#define STRING_ACTIONS_SAVE "actions_save"
#define STRING_ACTIONS_LOAD "actions_load"
#define STRING_ACTIONS_SELECT "actions_select"
#define STRING_ACTIONS_DESELECT "actions_deselect"
#define STRING_ACTIONS_STEP_LEFT "actions_step_left"
#define STRING_ACTIONS_STEP_RIGHT "actions_step_right"
#define STRING_ACTIONS_ACCELERATE "actions_accelerate"
#define STRING_ACTIONS_REVERSE "actions_reverse"
#define STRING_ACTIONS_SPEED "actions_speed"
#define STRING_ACTIONS_SLOW "actions_slow"
#define STRING_ACTIONS_BRAKE "actions_brake"
#define STRING_ACTIONS_FIRE "actions_fire"
#define STRING_RESET_TO_DEFAULTS "reset_to_defaults"
#define STRING_TITLE_ITEMS "items"
#define STRING_TITLE_PUZZLES "puzzles"
#define STRING_TITLE_SETTINGS "settings"
@ -131,6 +135,23 @@
#define STRING_AMMO_USED "ammo_used"
#define STRING_TOTAL_SECRETS_FOUND "total_secrets_found"
#define STRING_LEVEL_SECRETS_FOUND "level_secrets_found"
#define STRING_MENU_ACTIONS "menu_actions"
#define STRING_QUICK_ACTIONS "quick_actions"
#define STRING_ACTIONS_LARGE_MEDIPACK "actions_large_medipack"
#define STRING_ACTIONS_FLARE "actions_flare"
#define STRING_ACTIONS_NEXT_WEAPON "actions_next_weapon"
#define STRING_ACTIONS_PREVIOUS_WEAPON "actions_previous_weapon"
#define STRING_ACTIONS_SMALL_MEDIPACK "actions_small_medipack"
#define STRING_ACTIONS_WEAPON_1 "actions_weapon_1"
#define STRING_ACTIONS_WEAPON_2 "actions_weapon_2"
#define STRING_ACTIONS_WEAPON_3 "actions_weapon_3"
#define STRING_ACTIONS_WEAPON_4 "actions_weapon_4"
#define STRING_ACTIONS_WEAPON_5 "actions_weapon_5"
#define STRING_ACTIONS_WEAPON_6 "actions_weapon_6"
#define STRING_ACTIONS_WEAPON_7 "actions_weapon_7"
#define STRING_ACTIONS_WEAPON_8 "actions_weapon_8"
#define STRING_ACTIONS_WEAPON_9 "actions_weapon_9"
#define STRING_ACTIONS_WEAPON_10 "actions_weapon_10"
#define STRING_WATERSKIN_SMALL_EMPTY "waterskin_small_empty"
#define STRING_WATERSKIN_SMALL_1L "waterskin_small_1l"
#define STRING_WATERSKIN_SMALL_2L "waterskin_small_2l"
@ -145,3 +166,4 @@
#define STRING_MECHANICAL_SCARAB "mechanical_scarab"
#define STRING_MECHANICAL_SCARAB_1 "mechanical_scarab_1"
#define STRING_MECHANICAL_SCARAB_2 "mechanical_scarab_2"
#define STRING_VEHICLE_ACTIONS "vehicle_actions"

View file

@ -43,21 +43,48 @@ The following constants are inside ActionID.
static const std::unordered_map<std::string, ActionID> ACTION_IDS
{
{ "FORWARD", ActionID::Forward },
{ "BACK", ActionID::Back },
{ "LEFT", ActionID::Left },
{ "RIGHT", ActionID::Right },
{ "CROUCH", ActionID::Crouch },
{ "SPRINT", ActionID::Sprint },
{ "WALK", ActionID::Walk },
{ "JUMP", ActionID::Jump },
{ "ACTION", ActionID::Action },
{ "DRAW", ActionID::DrawWeapon },
{ "FLARE", ActionID::Flare},
{ "LOOK", ActionID::Look },
{ "ROLL", ActionID::Roll },
{ "INVENTORY", ActionID::Option },
{ "PAUSE", ActionID::Pause },
{ "STEPLEFT", ActionID::LeftStep },
{ "STEPRIGHT", ActionID::RightStep }
{ "FORWARD", In::Forward },
{ "BACK", In::Back },
{ "LEFT", In::Left },
{ "RIGHT", In::Right },
{ "STEP_LEFT", In::StepLeft },
{ "STEP_RIGHT", In::StepRight },
{ "ACTION", In::Action },
{ "WALK", In::Walk },
{ "SPRINT", In::Sprint },
{ "CROUCH", In::Crouch },
{ "JUMP", In::Jump },
{ "ROLL", In::Roll },
{ "DRAW", In::Draw },
{ "LOOK", In::Look },
/*{ "ACCELERATE", In::Accelerate },
{ "REVERSE", In::Revers },
{ "SPEED", In::Speed },
{ "SLOW", In::Slow },
{ "BRAKE", In::Brake },
{ "FIRE", In::Fire },*/
{ "FLARE", In::Flare },
{ "SMALL_MEDIPACK", In::SmallMedipack },
{ "LARGE_MEDIPACK", In::LargeMedipack },
{ "PREVIOUS_WEAPON", In::PreviousWeapon },
{ "NEXT_WEAPON", In::NextWeapon },
{ "WEAPON_1", In::Weapon1 },
{ "WEAPON_2", In::Weapon2 },
{ "WEAPON_3", In::Weapon3 },
{ "WEAPON_4", In::Weapon4 },
{ "WEAPON_5", In::Weapon5 },
{ "WEAPON_6", In::Weapon6 },
{ "WEAPON_7", In::Weapon7 },
{ "WEAPON_8", In::Weapon8 },
{ "WEAPON_9", In::Weapon9 },
{ "WEAPON_10", In::Weapon10 },
{ "SELECT", In::Select },
{ "DESELECT", In::Deselect },
{ "PAUSE", In::Pause },
{ "INVENTORY", In::Inventory },
{ "SAVE", In::Save },
{ "LOAD", In::Load }
};

View file

@ -8,12 +8,10 @@
#include <OISKeyboard.h>
#include "Game/items.h"
#include "Game/Lara/lara.h"
#include "Game/Lara/lara_helpers.h"
#include "Game/Lara/lara_tests.h"
#include "Game/savegame.h"
#include "Renderer/Renderer11.h"
#include "Sound/sound.h"
#include "Specific/clock.h"
#include "Specific/trutils.h"
#include "Specific/winmain.h"
@ -26,43 +24,43 @@ namespace TEN::Input
{
constexpr int AXIS_DEADZONE = 8000;
const char* g_KeyNames[] =
const std::vector<std::string> g_KeyNames =
{
"<None>", "Esc", "1", "2", "3", "4", "5", "6",
"7", "8", "9", "0", "-", "+", "Back", "Tab",
"Q", "W", "E", "R", "T", "Y", "U", "I",
"O", "P", "<", ">", "Enter", "Ctrl", "A", "S",
"O", "P", "[", "]", "Enter", "Ctrl", "A", "S",
"D", "F", "G", "H", "J", "K", "L", ";",
"'", "`", "Shift", "#", "Z", "X", "C", "V",
"B", "N", "M", ",", ".", "/", "Shift", "Pad X",
"Alt", "Space", "Caps Lock", NULL, NULL, NULL, NULL, NULL,
"Alt", "Space", "Caps Lock", "F1", "F2", "F3", "F4", "F5",
NULL, NULL, NULL, NULL, NULL, "Num Lock", "Scroll Lock", "Pad 7",
"F6", "F7", "F8", "F9", "F10", "Num Lock", "Scroll Lock", "Pad 7",
"Pad 8", "Pad 9", "Pad -", "Pad 4", "Pad 5", "Pad 6", "Pad +", "Pad 1",
"Pad 2", "Pad 3", "Pad 0", "Pad.", NULL, NULL, "\\", NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
"Pad 2", "Pad 3", "Pad 0", "Pad.", "", "", "\\", "",
"", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "",
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, "Pad Enter", "Ctrl", NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, "Shift", NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, "Pad /", NULL, NULL,
"Alt", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Home",
"Up", "Page Up", NULL, "Left", NULL, "Right", NULL, "End",
"Down", "Page Down", "Insert", "Del", NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
"", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "",
"", "", "", "", "Pad Enter", "Ctrl", "", "",
"", "", "", "", "", "", "", "",
"", "", "Shift", "", "", "", "", "",
"", "", "", "", "", "Pad /", "", "",
"Alt", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "Home",
"Up", "Page Up", "", "Left", "", "Right", "", "End",
"Down", "Page Down", "Insert", "Del", "", "", "", "",
"", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "",
"Joy 1", "Joy 2", "Joy 3", "Joy 4", "Joy 5", "Joy 6", "Joy 7", "Joy 8",
"Joy 9", "Joy 10", "Joy 11", "Joy 12", "Joy 13", "Joy 14", "Joy 15", "Joy 16",
@ -88,17 +86,24 @@ namespace TEN::Input
int DbInput = 0;
int TrInput = 0;
auto DefaultBindings = std::vector<int>
// Rows:
// 1. General actions
// 2. Vehicle actions (TODO)
// 3. Quick actions
// 4. Menu controls
const auto DefaultBindings = std::vector<int>
{
KC_UP, KC_DOWN, KC_LEFT, KC_RIGHT, KC_PERIOD, KC_SLASH, KC_RSHIFT, KC_RMENU, KC_RCONTROL, KC_SPACE, KC_COMMA, KC_NUMPAD0, KC_END, KC_ESCAPE, KC_P, KC_PGUP, KC_PGDOWN,
/*KC_RCONTROL, KC_DOWN, KC_SLASH, KC_RSHIFT, KC_RMENU, KC_SPACE,*/ // TODO: Dedicated vehicle actions.
KC_F5, KC_F6, KC_RETURN, KC_ESCAPE, KC_NUMPAD0
KC_UP, KC_DOWN, KC_LEFT, KC_RIGHT, KC_DELETE, KC_PGDOWN, KC_RCONTROL, KC_RSHIFT, KC_SLASH, KC_PERIOD, KC_RMENU, KC_END, KC_SPACE, KC_NUMPAD0,
/*KC_RCONTROL, KC_DOWN, KC_SLASH, KC_RSHIFT, KC_RMENU, KC_SPACE,*/
KC_COMMA, KC_MINUS, KC_EQUALS, KC_LBRACKET, KC_RBRACKET, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0,
KC_RETURN, KC_ESCAPE, KC_P, KC_ESCAPE, KC_F5, KC_F6, KC_NUMPAD0
};
auto XInputBindings = std::vector<int>
const auto XInputBindings = std::vector<int>
{
XB_AXIS_X_NEG, XB_AXIS_X_POS, XB_AXIS_Y_NEG, XB_AXIS_Y_POS, XB_AXIS_LTRIGGER_NEG, XB_AXIS_RTRIGGER_NEG, XB_RSHIFT, XB_X, XB_A, XB_Y, XB_DPAD_DOWN, XB_LSHIFT, XB_B, XB_SELECT, XB_START, XB_LSTICK, XB_RSTICK,
/*KC_RCONTROL, KC_DOWN, KC_SLASH, KC_RSHIFT, KC_RMENU, KC_SPACE,*/ // TODO: Dedicated vehicle actions.
KC_F5, KC_F6, KC_RETURN, KC_ESCAPE, KC_NUMPAD0
XB_AXIS_X_NEG, XB_AXIS_X_POS, XB_AXIS_Y_NEG, XB_AXIS_Y_POS, XB_LSTICK, XB_RSTICK, XB_A, XB_RSHIFT, XB_AXIS_RTRIGGER_NEG, XB_AXIS_LTRIGGER_NEG, XB_X, XB_B, XB_Y, XB_LSHIFT,
/*KC_RCONTROL, KC_DOWN, KC_SLASH, KC_RSHIFT, KC_RMENU, KC_SPACE,*/
XB_DPAD_DOWN, KC_MINUS, KC_EQUALS, KC_LBRACKET, KC_RBRACKET, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0,
KC_RETURN, XB_SELECT, XB_START, XB_SELECT, KC_F5, KC_F6, KC_NUMPAD0
};
// Input bindings. These are primitive mappings to actions.
@ -106,12 +111,16 @@ namespace TEN::Input
short KeyboardLayout[2][KEY_COUNT] =
{
{
KC_UP, KC_DOWN, KC_LEFT, KC_RIGHT, KC_PERIOD, KC_SLASH, KC_RSHIFT, KC_RMENU, KC_RCONTROL, KC_SPACE, KC_COMMA, KC_NUMPAD0, KC_END, KC_ESCAPE, KC_P, KC_PGUP, KC_PGDOWN,
/*KC_RCONTROL, KC_DOWN, KC_SLASH, KC_RSHIFT, KC_RMENU, KC_SPACE*/ // TODO: Dedicated vehicle actions.
KC_UP, KC_DOWN, KC_LEFT, KC_RIGHT, KC_DELETE, KC_PGDOWN, KC_RCONTROL, KC_RSHIFT, KC_SLASH, KC_PERIOD, KC_RMENU, KC_END, KC_SPACE, KC_NUMPAD0,
/*KC_RCONTROL, KC_DOWN, KC_SLASH, KC_RSHIFT, KC_RMENU, KC_SPACE,*/
KC_COMMA, KC_MINUS, KC_EQUALS, KC_LBRACKET, KC_RBRACKET, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0,
KC_RETURN, KC_ESCAPE, KC_P, KC_ESCAPE, KC_F5, KC_F6
},
{
KC_UP, KC_DOWN, KC_LEFT, KC_RIGHT, KC_PERIOD, KC_SLASH, KC_RSHIFT, KC_RMENU, KC_RCONTROL, KC_SPACE, KC_COMMA, KC_NUMPAD0, KC_END, KC_ESCAPE, KC_P, KC_PGUP, KC_PGDOWN,
/*KC_RCONTROL, KC_DOWN, KC_SLASH, KC_RSHIFT, KC_RMENU, KC_SPACE*/ // TODO: Dedicated vehicle actions.
KC_UP, KC_DOWN, KC_LEFT, KC_RIGHT, KC_DELETE, KC_PGDOWN, KC_RCONTROL, KC_RSHIFT, KC_SLASH, KC_PERIOD, KC_RMENU, KC_END, KC_SPACE, KC_NUMPAD0,
/*KC_RCONTROL, KC_DOWN, KC_SLASH, KC_RSHIFT, KC_RMENU, KC_SPACE,*/
KC_COMMA, KC_MINUS, KC_EQUALS, KC_LBRACKET, KC_RBRACKET, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0,
KC_RETURN, KC_ESCAPE, KC_P, KC_ESCAPE, KC_F5, KC_F6
}
};
@ -154,9 +163,13 @@ namespace TEN::Input
OisInputManager->enableAddOnFactory(InputManager::AddOn_All);
if (OisInputManager->getNumberOfDevices(OISKeyboard) == 0)
{
TENLog("Keyboard not found!", LogLevel::Warning);
}
else
{
OisKeyboard = (Keyboard*)OisInputManager->createInputObject(OISKeyboard, true);
}
}
catch (OIS::Exception& ex)
{
@ -269,7 +282,7 @@ namespace TEN::Input
int WrapSimilarKeys(int source)
{
// Merge right/left Ctrl, Shift, and Alt.
// Merge right/left Ctrl, Shift, Alt.
switch (source)
{
@ -310,13 +323,21 @@ namespace TEN::Input
for (int layout = 0; layout <= 1; layout++)
{
if (KeyboardLayout[layout][KEY_FORWARD] == index)
{
AxisMap[(unsigned int)InputAxis::MoveVertical] = 1.0f;
}
else if (KeyboardLayout[layout][KEY_BACK] == index)
{
AxisMap[(unsigned int)InputAxis::MoveVertical] = -1.0f;
}
else if (KeyboardLayout[layout][KEY_LEFT] == index)
{
AxisMap[(unsigned int)InputAxis::MoveHorizontal] = -1.0f;
}
else if (KeyboardLayout[layout][KEY_RIGHT] == index)
{
AxisMap[(unsigned int)InputAxis::MoveHorizontal] = 1.0f;
}
}
}
@ -370,13 +391,21 @@ namespace TEN::Input
// NOTE: abs() operations are needed to avoid issues with inverted axes on different controllers.
if (KeyboardLayout[1][KEY_FORWARD] == usedIndex)
{
AxisMap[InputAxis::MoveVertical] = abs(scaledValue);
}
else if (KeyboardLayout[1][KEY_BACK] == usedIndex)
{
AxisMap[InputAxis::MoveVertical] = -abs(scaledValue);
}
else if (KeyboardLayout[1][KEY_LEFT] == usedIndex)
{
AxisMap[InputAxis::MoveHorizontal] = -abs(scaledValue);
}
else if (KeyboardLayout[1][KEY_RIGHT] == usedIndex)
{
AxisMap[InputAxis::MoveHorizontal] = abs(scaledValue);
}
else if (!LayoutContainsIndex(usedIndex))
{
unsigned int camAxisIndex = (unsigned int)std::clamp((unsigned int)InputAxis::CameraVertical + axis % 2,
@ -489,126 +518,13 @@ namespace TEN::Input
}
}
void HandlePlayerHotkeys(ItemInfo* item)
static void HandleHotkeyActions()
{
static const auto UNAVAILABLE_FLARE_STATES = std::vector<int>
{
LS_CRAWL_FORWARD,
LS_CRAWL_TURN_LEFT,
LS_CRAWL_TURN_RIGHT,
LS_CRAWL_BACK,
LS_CRAWL_TO_HANG,
LS_CRAWL_TURN_180
};
auto& lara = *GetLaraInfo(item);
// Handle hardcoded action-to-key mappings.
ActionMap[(int)In::Save].Update(KeyMap[KC_F5] ? true : false);
ActionMap[(int)In::Load].Update(KeyMap[KC_F6] ? true : false);
ActionMap[(int)In::Select].Update((KeyMap[KC_RETURN] || Key(KEY_ACTION)) ? true : false);
ActionMap[(int)In::Deselect].Update((KeyMap[KC_ESCAPE] || Key(KEY_DRAW)) ? true : false);
// Handle target switch when locked on to an entity.
if (lara.Control.HandStatus == HandStatus::WeaponReady &&
lara.TargetEntity != nullptr)
{
if (IsClicked(In::Look))
{
ActionMap[(int)In::SwitchTarget].Update(true);
//ActionMap[(int)In::Look].Clear();
}
else
{
ClearAction(In::SwitchTarget);
}
}
else
{
ClearAction(In::SwitchTarget);
}
// Handle flares.
if (IsClicked(In::Flare))
{
if (TestState(item->Animation.ActiveState, UNAVAILABLE_FLARE_STATES))
SayNo();
}
// Handle weapon hotkeys.
if (KeyMap[KC_1] && lara.Weapons[(int)LaraWeaponType::Pistol].Present)
lara.Control.Weapon.RequestGunType = LaraWeaponType::Pistol;
if (KeyMap[KC_2] && lara.Weapons[(int)LaraWeaponType::Shotgun].Present)
lara.Control.Weapon.RequestGunType = LaraWeaponType::Shotgun;
if (KeyMap[KC_3] && lara.Weapons[(int)LaraWeaponType::Uzi].Present)
lara.Control.Weapon.RequestGunType = LaraWeaponType::Uzi;
if (KeyMap[KC_4] && lara.Weapons[(int)LaraWeaponType::Revolver].Present)
lara.Control.Weapon.RequestGunType = LaraWeaponType::Revolver;
if (KeyMap[KC_5] && lara.Weapons[(int)LaraWeaponType::GrenadeLauncher].Present)
lara.Control.Weapon.RequestGunType = LaraWeaponType::GrenadeLauncher;
if (KeyMap[KC_6] && lara.Weapons[(int)LaraWeaponType::Crossbow].Present)
lara.Control.Weapon.RequestGunType = LaraWeaponType::Crossbow;
if (KeyMap[KC_7] && lara.Weapons[(int)LaraWeaponType::HarpoonGun].Present)
lara.Control.Weapon.RequestGunType = LaraWeaponType::HarpoonGun;
if (KeyMap[KC_8] && lara.Weapons[(int)LaraWeaponType::HK].Present)
lara.Control.Weapon.RequestGunType = LaraWeaponType::HK;
if (KeyMap[KC_9] && lara.Weapons[(int)LaraWeaponType::RocketLauncher].Present)
lara.Control.Weapon.RequestGunType = LaraWeaponType::RocketLauncher;
// Handle medipack hotkeys.
static bool dbMedipack = true;
if ((KeyMap[KC_MINUS] || KeyMap[KC_EQUALS]) && dbMedipack)
{
if ((item->HitPoints > 0 && item->HitPoints < LARA_HEALTH_MAX) ||
lara.Status.Poison)
{
bool hasUsedMedipack = false;
if (KeyMap[KC_MINUS] &&
lara.Inventory.TotalSmallMedipacks != 0)
{
hasUsedMedipack = true;
item->HitPoints += LARA_HEALTH_MAX / 2;
if (item->HitPoints > LARA_HEALTH_MAX)
item->HitPoints = LARA_HEALTH_MAX;
if (lara.Inventory.TotalSmallMedipacks != -1)
lara.Inventory.TotalSmallMedipacks--;
}
else if (KeyMap[KC_EQUALS] &&
lara.Inventory.TotalLargeMedipacks != 0)
{
hasUsedMedipack = true;
item->HitPoints = LARA_HEALTH_MAX;
if (lara.Inventory.TotalLargeMedipacks != -1)
lara.Inventory.TotalLargeMedipacks--;
}
if (hasUsedMedipack)
{
lara.Status.Poison = 0;
SoundEffect(SFX_TR4_MENU_MEDI, nullptr, SoundEnvironment::Always);
Statistics.Game.HealthUsed++;
}
}
}
dbMedipack = (KeyMap[KC_MINUS] || KeyMap[KC_EQUALS]) ? false : true;
// Save screenshot.
static bool dbScreenshot = true;
if (KeyMap[KC_SYSRQ] && dbScreenshot)
g_Renderer.SaveScreenshot();
dbScreenshot = KeyMap[KC_SYSRQ] ? false : true;
dbScreenshot = !KeyMap[KC_SYSRQ];
// Toggle fullscreen.
static bool dbFullscreen = true;
@ -618,19 +534,19 @@ namespace TEN::Input
SaveConfiguration();
g_Renderer.ToggleFullScreen();
}
dbFullscreen = ((KeyMap[KC_LMENU] || KeyMap[KC_RMENU]) && KeyMap[KC_RETURN]) ? false : true;
dbFullscreen = !((KeyMap[KC_LMENU] || KeyMap[KC_RMENU]) && KeyMap[KC_RETURN]);
if (!DebugMode)
return;
// Handle debug page switch.
// Switch debug page.
static bool dbDebugPage = true;
if ((KeyMap[KC_F10] || KeyMap[KC_F11]) && dbDebugPage)
g_Renderer.SwitchDebugPage(KeyMap[KC_F10]);
dbDebugPage = (KeyMap[KC_F10] || KeyMap[KC_F11]) ? false : true;
dbDebugPage = !(KeyMap[KC_F10] || KeyMap[KC_F11]);
}
void UpdateRumble()
static void UpdateRumble()
{
if (!OisRumble || !OisEffect || !RumbleInfo.Power)
return;
@ -686,18 +602,15 @@ namespace TEN::Input
ReadGameController();
DefaultConflict();
// Update action map (mappable actions only).
// Update action map.
for (int i = 0; i < KEY_COUNT; i++)
{
// TODO: Poll analog value of key. Potentially, any can be a trigger.
ActionMap[i].Update(Key(i) ? true : false);
}
ActionMap[i].Update(Key(i));
if (applyQueue)
ApplyActionQueue();
// Additional handling.
HandlePlayerHotkeys(item);
HandleHotkeyActions();
SolveActionCollisions();
// Port actions back to legacy bit fields.
@ -777,7 +690,6 @@ namespace TEN::Input
}
auto vendor = TEN::Utils::ToLower(OisGamepad->vendor());
if (vendor.find("xbox") != std::string::npos || vendor.find("xinput") != std::string::npos)
{
ApplyBindings(XInputBindings);
@ -851,16 +763,16 @@ namespace TEN::Input
return ActionMap[(int)actionID].GetTimeInactive();
}
bool IsDirectionActionHeld()
bool IsDirectionalActionHeld()
{
return (IsHeld(In::Forward) || IsHeld(In::Back) || IsHeld(In::Left) || IsHeld(In::Right));
}
bool IsWakeActionHeld()
{
if (IsDirectionActionHeld() || IsHeld(In::LeftStep) || IsHeld(In::RightStep) ||
if (IsDirectionalActionHeld() || IsHeld(In::StepLeft) || IsHeld(In::StepRight) ||
IsHeld(In::Walk) || IsHeld(In::Jump) || IsHeld(In::Sprint) || IsHeld(In::Roll) || IsHeld(In::Crouch) ||
IsHeld(In::DrawWeapon) || IsHeld(In::Flare) || IsHeld(In::Action))
IsHeld(In::Draw) || IsHeld(In::Flare) || IsHeld(In::Action))
{
return true;
}
@ -870,6 +782,6 @@ namespace TEN::Input
bool IsOpticActionHeld()
{
return (IsDirectionActionHeld() || IsHeld(In::Action) || IsHeld(In::Crouch) || IsHeld(In::Sprint));
return (IsDirectionalActionHeld() || IsHeld(In::Action) || IsHeld(In::Crouch) || IsHeld(In::Sprint));
}
}

View file

@ -12,7 +12,7 @@ namespace TEN::Input
constexpr int MAX_INPUT_SLOTS = MAX_KEYBOARD_KEYS + MAX_GAMEPAD_KEYS + MAX_GAMEPAD_POV_AXES + MAX_GAMEPAD_AXES * 2;
enum XInputButtons
enum XInputButton
{
XB_START = MAX_KEYBOARD_KEYS,
XB_SELECT,
@ -45,69 +45,69 @@ namespace TEN::Input
XB_DPAD_RIGHT
};
// Deprecated.
enum InputKey
{
KEY_FORWARD,
KEY_BACK,
KEY_LEFT,
KEY_RIGHT,
KEY_CROUCH,
KEY_SPRINT,
KEY_WALK,
KEY_JUMP,
KEY_LEFT_STEP,
KEY_RIGHT_STEP,
KEY_ACTION,
KEY_DRAW,
KEY_FLARE,
KEY_LOOK,
KEY_WALK,
KEY_SPRINT,
KEY_CROUCH,
KEY_JUMP,
KEY_ROLL,
KEY_OPTION,
KEY_DRAW,
KEY_LOOK,
KEY_FLARE,
KEY_SMALL_MEDIPACK,
KEY_LARGE_MEDIPACK,
KEY_PREVIOUS_WEAPON,
KEY_NEXT_WEAPON,
KEY_WEAPON_1,
KEY_WEAPON_2,
KEY_WEAPON_3,
KEY_WEAPON_4,
KEY_WEAPON_5,
KEY_WEAPON_6,
KEY_WEAPON_7,
KEY_WEAPON_8,
KEY_WEAPON_9,
KEY_WEAPON_10,
KEY_SELECT,
KEY_DESELECT,
KEY_PAUSE,
KEY_LSTEP,
KEY_RSTEP,
/*KEY_ACCELERATE,
KEY_REVERSE,
KEY_SPEED,
KEY_SLOW,
KEY_BRAKE,
KEY_FIRE,*/
KEY_INVENTORY,
KEY_SAVE,
KEY_LOAD,
KEY_COUNT
};
// Deprecated.
enum InputActions
{
IN_NONE = 0,
IN_FORWARD = (1 << KEY_FORWARD),
IN_BACK = (1 << KEY_BACK),
IN_LEFT = (1 << KEY_LEFT),
IN_RIGHT = (1 << KEY_RIGHT),
IN_CROUCH = (1 << KEY_CROUCH),
IN_SPRINT = (1 << KEY_SPRINT),
IN_WALK = (1 << KEY_WALK),
IN_JUMP = (1 << KEY_JUMP),
IN_ACTION = (1 << KEY_ACTION),
IN_DRAW = (1 << KEY_DRAW),
IN_FLARE = (1 << KEY_FLARE),
IN_LOOK = (1 << KEY_LOOK),
IN_ROLL = (1 << KEY_ROLL),
IN_OPTION = (1 << KEY_OPTION),
IN_PAUSE = (1 << KEY_PAUSE),
IN_LSTEP = (1 << KEY_LSTEP),
IN_RSTEP = (1 << KEY_RSTEP),
/*IN_ACCELERATE = (1 << KEY_ACCELERATE),
IN_REVERSE = (1 << KEY_REVERSE),
IN_SPEED = (1 << KEY_SPEED),
IN_SLOW = (1 << KEY_SLOW),
IN_BRAKE = (1 << KEY_BRAKE),
IN_FIRE = (1 << KEY_FIRE),*/
IN_NONE = 0,
// Additional input actions without direct key relation
IN_SAVE = (1 << (KEY_COUNT + 0)),
IN_LOAD = (1 << (KEY_COUNT + 1)),
IN_SELECT = (1 << (KEY_COUNT + 2)),
IN_DESELECT = (1 << (KEY_COUNT + 3)),
IN_LOOKSWITCH = (1 << (KEY_COUNT + 4))
IN_FORWARD = (1 << KEY_FORWARD),
IN_BACK = (1 << KEY_BACK),
IN_LEFT = (1 << KEY_LEFT),
IN_RIGHT = (1 << KEY_RIGHT),
IN_LSTEP = (1 << KEY_LEFT_STEP),
IN_RSTEP = (1 << KEY_RIGHT_STEP),
IN_ACTION = (1 << KEY_ACTION),
IN_WALK = (1 << KEY_WALK),
IN_SPRINT = (1 << KEY_SPRINT),
IN_CROUCH = (1 << KEY_CROUCH),
IN_JUMP = (1 << KEY_JUMP),
IN_ROLL = (1 << KEY_ROLL),
IN_DRAW = (1 << KEY_DRAW),
IN_LOOK = (1 << KEY_LOOK)
};
// Temporary input constants for use with vehicles:
@ -160,7 +160,7 @@ namespace TEN::Input
float FadeSpeed = 0.0f;
};
extern const char* g_KeyNames[];
extern const std::vector<std::string> g_KeyNames;
extern std::vector<InputAction> ActionMap;
extern std::vector<QueueState> ActionQueue;
@ -197,7 +197,7 @@ namespace TEN::Input
float GetActionTimeActive(ActionID actionID);
float GetActionTimeInactive(ActionID actionID);
bool IsDirectionActionHeld();
bool IsDirectionalActionHeld();
bool IsWakeActionHeld();
bool IsOpticActionHeld();
}

View file

@ -4,28 +4,23 @@ namespace TEN::Input
{
typedef enum class ActionID
{
None = -1,
// Basic control
// General actions
Forward,
Back,
Left,
Right,
Crouch,
Sprint,
Walk,
Jump,
StepLeft,
StepRight,
Action,
DrawWeapon,
Flare, // Convert to generic Light button under Item hotkeys section.
Look,
Walk,
Sprint,
Crouch,
Jump,
Roll,
Option, // Move to GUI control section.
Pause, // Move to GUI control section.
LeftStep,
RightStep,
Draw,
Look,
// Vehicle control
// Vehicle actions
/*Accelerate,
Reverse,
Speed,
@ -33,13 +28,12 @@ namespace TEN::Input
Brake,
Fire,*/
// Item hotkeys
/*Light, // Generic light button may be used for flares.
Binoculars,
// Quick actions
Flare,
SmallMedipack,
BigMedipack,
NextWeapon,
LargeMedipack,
PreviousWeapon,
NextWeapon,
Weapon1,
Weapon2,
Weapon3,
@ -49,16 +43,16 @@ namespace TEN::Input
Weapon7,
Weapon8,
Weapon9,
Weapon10,*/
Weapon10,
// GUI control
/*Option,
Pause,*/
Save,
Load,
// Menu actions
Select,
Deselect,
SwitchTarget, // Look -> SwitchTarget conversion must be handled differently.
Pause,
Inventory,
Save,
Load,
SwitchTarget, // TODO: Look -> SwitchTarget conversion must be handled differently.
Count
} In;
@ -68,7 +62,7 @@ namespace TEN::Input
{
private:
// Members
ActionID ID = In::None;
ActionID ID = In::Forward;
float Value = 0.0f;
float PrevValue = 0.0f;
float TimeActive = 0.0f;

View file

@ -246,7 +246,6 @@ bool SaveConfiguration()
return false;
}
if (SetBoolRegKey(rootKey, REGKEY_ENABLE_RUMBLE, g_Configuration.EnableRumble) != ERROR_SUCCESS)
{
RegCloseKey(rootKey);