mirror of
https://github.com/TombEngine/TombEngine.git
synced 2025-05-02 09:47:58 +03:00
Merge branch 'develop' into test
This commit is contained in:
commit
034ef1dd1b
35 changed files with 882 additions and 654 deletions
|
@ -21,6 +21,8 @@ Version 1.0.7
|
||||||
- ItemFlags[6] = Distance to use the switch. (example: MySwitch:SetItemFlags(Distance Position, 6)
|
- ItemFlags[6] = Distance to use the switch. (example: MySwitch:SetItemFlags(Distance Position, 6)
|
||||||
* Implement squash and stretch water bubbles.
|
* Implement squash and stretch water bubbles.
|
||||||
* Prevent Lara from drawing weapons during parallel bar swinging.
|
* Prevent Lara from drawing weapons during parallel bar swinging.
|
||||||
|
* Implement squash and stretch water bubbles.
|
||||||
|
* Implement a new pickup display inspired by OpenLara.
|
||||||
|
|
||||||
Lua API Changes
|
Lua API Changes
|
||||||
* Fix Camera:SetPosition not updating camera position when it is played simultaneously.
|
* Fix Camera:SetPosition not updating camera position when it is played simultaneously.
|
||||||
|
|
215
TombEngine/Game/Hud/Hud.cpp
Normal file
215
TombEngine/Game/Hud/Hud.cpp
Normal file
|
@ -0,0 +1,215 @@
|
||||||
|
#include "framework.h"
|
||||||
|
#include "Game/Hud/Hud.h"
|
||||||
|
|
||||||
|
#include "Game/control/control.h"
|
||||||
|
#include "Game/Hud/PickupSummary.h"
|
||||||
|
#include "Game/items.h"
|
||||||
|
#include "Game/Lara/lara.h"
|
||||||
|
#include "Game/Lara/lara_helpers.h"
|
||||||
|
#include "Renderer/Renderer11.h"
|
||||||
|
|
||||||
|
using namespace TEN::Math;
|
||||||
|
using namespace TEN::Renderer;
|
||||||
|
|
||||||
|
extern RendererHUDBar* g_HealthBar;
|
||||||
|
extern RendererHUDBar* g_DashBar;
|
||||||
|
extern RendererHUDBar* g_AirBar;
|
||||||
|
|
||||||
|
namespace TEN::Hud
|
||||||
|
{
|
||||||
|
HudController g_Hud = HudController();
|
||||||
|
|
||||||
|
void HudController::Update()
|
||||||
|
{
|
||||||
|
this->PickupSummary.Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void HudController::Draw() const
|
||||||
|
{
|
||||||
|
this->PickupSummary.Draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
void HudController::Clear()
|
||||||
|
{
|
||||||
|
this->PickupSummary.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr auto HEALTH_BAR_TIMER_MAX = 40.0f;
|
||||||
|
|
||||||
|
struct HealthBarData
|
||||||
|
{
|
||||||
|
float Value = LARA_HEALTH_MAX;
|
||||||
|
float PrevValue = LARA_HEALTH_MAX;
|
||||||
|
float MutateAmount = 0.0f;
|
||||||
|
float Timer = HEALTH_BAR_TIMER_MAX;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto HealthBar = HealthBarData();
|
||||||
|
|
||||||
|
static void DrawHealthBarOverlay(ItemInfo* item, float value)
|
||||||
|
{
|
||||||
|
const auto& player = *GetLaraInfo(item);
|
||||||
|
|
||||||
|
if (CurrentLevel != 0)
|
||||||
|
g_Renderer.DrawBar(value, g_HealthBar, ID_HEALTH_BAR_TEXTURE, GlobalCounter, player.PoisonPotency != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DrawHealthBar(ItemInfo* item, float value)
|
||||||
|
{
|
||||||
|
const auto& player = *GetLaraInfo(item);
|
||||||
|
|
||||||
|
g_Renderer.DrawBar(value, g_HealthBar, ID_HEALTH_BAR_TEXTURE, GlobalCounter, player.PoisonPotency != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DrawHealthBar(ItemInfo* item, bool doFlash)
|
||||||
|
{
|
||||||
|
const auto& player = *GetLaraInfo(item);
|
||||||
|
|
||||||
|
// Flash when at critical capacity and bar is not transitioning.
|
||||||
|
if (HealthBar.Value <= LARA_HEALTH_CRITICAL)
|
||||||
|
{
|
||||||
|
if (!BinocularRange)
|
||||||
|
{
|
||||||
|
if (doFlash || HealthBar.MutateAmount)
|
||||||
|
DrawHealthBar(item, HealthBar.Value / LARA_HEALTH_MAX);
|
||||||
|
else
|
||||||
|
DrawHealthBar(item, 0.0f);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (doFlash || HealthBar.MutateAmount)
|
||||||
|
DrawHealthBarOverlay(item, HealthBar.Value / LARA_HEALTH_MAX);
|
||||||
|
else
|
||||||
|
DrawHealthBarOverlay(item, 0.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (HealthBar.Timer > 0.0f || HealthBar.Value <= 0.0f ||
|
||||||
|
player.Control.HandStatus == HandStatus::WeaponReady &&
|
||||||
|
player.Control.Weapon.GunType != LaraWeaponType::Torch ||
|
||||||
|
player.PoisonPotency)
|
||||||
|
{
|
||||||
|
if (!BinocularRange)
|
||||||
|
DrawHealthBar(item, HealthBar.Value / LARA_HEALTH_MAX);
|
||||||
|
else
|
||||||
|
DrawHealthBarOverlay(item, HealthBar.Value / LARA_HEALTH_MAX);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DrawAirBar(float value)
|
||||||
|
{
|
||||||
|
g_Renderer.DrawBar(value, g_AirBar, ID_AIR_BAR_TEXTURE, 0, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DrawAirBar(ItemInfo* item, bool doFlash)
|
||||||
|
{
|
||||||
|
const auto& player = *GetLaraInfo(item);
|
||||||
|
|
||||||
|
if (player.Air == LARA_AIR_MAX || item->HitPoints <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (player.Vehicle == NO_ITEM ||
|
||||||
|
g_Level.Items[player.Vehicle].ObjectNumber != ID_UPV)
|
||||||
|
{
|
||||||
|
if (player.Control.WaterStatus != WaterStatus::Underwater &&
|
||||||
|
player.Control.WaterStatus != WaterStatus::TreadWater &&
|
||||||
|
!(TestEnvironment(ENV_FLAG_SWAMP, item) && player.WaterSurfaceDist < -(CLICK(3) - 1)))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float air = player.Air;
|
||||||
|
if (air < 0.0f)
|
||||||
|
{
|
||||||
|
air = 0.0f;
|
||||||
|
}
|
||||||
|
else if (air > LARA_AIR_MAX)
|
||||||
|
{
|
||||||
|
air = LARA_AIR_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (air <= LARA_AIR_CRITICAL)
|
||||||
|
{
|
||||||
|
if (doFlash)
|
||||||
|
DrawAirBar(air / LARA_AIR_MAX);
|
||||||
|
else
|
||||||
|
DrawAirBar(0.0f);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DrawAirBar(air / LARA_AIR_MAX);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DrawSprintBar(float value)
|
||||||
|
{
|
||||||
|
g_Renderer.DrawBar(value, g_DashBar, ID_DASH_BAR_TEXTURE, 0, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DrawSprintBar(ItemInfo* item)
|
||||||
|
{
|
||||||
|
const auto& player = *GetLaraInfo(item);
|
||||||
|
|
||||||
|
if (player.SprintEnergy < LARA_SPRINT_ENERGY_MAX)
|
||||||
|
DrawSprintBar(player.SprintEnergy / LARA_SPRINT_ENERGY_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateBars(ItemInfo* item)
|
||||||
|
{
|
||||||
|
const auto& player = *GetLaraInfo(item);
|
||||||
|
|
||||||
|
if (HealthBar.Timer > 0.0f)
|
||||||
|
HealthBar.Timer -= 1.0f;
|
||||||
|
|
||||||
|
float hitPoints = item->HitPoints;
|
||||||
|
if (hitPoints < 0.0f)
|
||||||
|
{
|
||||||
|
hitPoints = 0.0f;
|
||||||
|
}
|
||||||
|
else if (hitPoints > LARA_HEALTH_MAX)
|
||||||
|
{
|
||||||
|
hitPoints = LARA_HEALTH_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Smoothly transition health bar display.
|
||||||
|
|
||||||
|
if (HealthBar.PrevValue != hitPoints)
|
||||||
|
{
|
||||||
|
HealthBar.MutateAmount += HealthBar.PrevValue - hitPoints;
|
||||||
|
HealthBar.PrevValue = hitPoints;
|
||||||
|
HealthBar.Timer = HEALTH_BAR_TIMER_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((HealthBar.Value - HealthBar.MutateAmount) < 0.0f)
|
||||||
|
{
|
||||||
|
HealthBar.MutateAmount = HealthBar.Value;
|
||||||
|
}
|
||||||
|
else if ((HealthBar.Value - HealthBar.MutateAmount) > LARA_HEALTH_MAX)
|
||||||
|
{
|
||||||
|
HealthBar.MutateAmount = HealthBar.Value - LARA_HEALTH_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
HealthBar.Value -= HealthBar.MutateAmount / 3;
|
||||||
|
HealthBar.MutateAmount -= HealthBar.MutateAmount / 3;
|
||||||
|
|
||||||
|
if (abs(HealthBar.MutateAmount) < 0.5f)
|
||||||
|
{
|
||||||
|
HealthBar.MutateAmount = 0.0f;
|
||||||
|
HealthBar.Value = hitPoints;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawHud(ItemInfo* item)
|
||||||
|
{
|
||||||
|
static bool doFlash = false;
|
||||||
|
if ((GameTimer & 0x07) == 0x07)
|
||||||
|
doFlash = !doFlash;
|
||||||
|
|
||||||
|
if (CurrentLevel == 0 || CinematicBarsHeight > 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
DrawSprintBar(item);
|
||||||
|
DrawHealthBar(item, doFlash);
|
||||||
|
DrawAirBar(item, doFlash);
|
||||||
|
}
|
||||||
|
}
|
24
TombEngine/Game/Hud/Hud.h
Normal file
24
TombEngine/Game/Hud/Hud.h
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
#pragma once
|
||||||
|
#include "Game/Hud/PickupSummary.h"
|
||||||
|
|
||||||
|
struct ItemInfo;
|
||||||
|
|
||||||
|
namespace TEN::Hud
|
||||||
|
{
|
||||||
|
class HudController
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// Components
|
||||||
|
PickupSummaryController PickupSummary = {};
|
||||||
|
|
||||||
|
// Utilities
|
||||||
|
void Update();
|
||||||
|
void Draw() const;
|
||||||
|
void Clear();
|
||||||
|
};
|
||||||
|
|
||||||
|
extern HudController g_Hud;
|
||||||
|
|
||||||
|
void UpdateBars(ItemInfo* item);
|
||||||
|
void DrawHud(ItemInfo* item);
|
||||||
|
}
|
212
TombEngine/Game/Hud/PickupSummary.cpp
Normal file
212
TombEngine/Game/Hud/PickupSummary.cpp
Normal file
|
@ -0,0 +1,212 @@
|
||||||
|
#include "framework.h"
|
||||||
|
#include "Game/Hud/PickupSummary.h"
|
||||||
|
|
||||||
|
#include "Game/pickup/pickup.h"
|
||||||
|
#include "Math/Math.h"
|
||||||
|
#include "Renderer/Renderer11.h"
|
||||||
|
#include "Specific/clock.h"
|
||||||
|
#include "Specific/setup.h"
|
||||||
|
|
||||||
|
using namespace TEN::Math;
|
||||||
|
using TEN::Renderer::g_Renderer;
|
||||||
|
|
||||||
|
namespace TEN::Hud
|
||||||
|
{
|
||||||
|
constexpr auto DISPLAY_PICKUP_COUNT_MAX = 64;
|
||||||
|
|
||||||
|
bool DisplayPickup::IsOffscreen() const
|
||||||
|
{
|
||||||
|
constexpr auto SCREEN_THRESHOLD_COEFF = 0.1f;
|
||||||
|
constexpr auto SCREEN_THRESHOLD = Vector2(SCREEN_SPACE_RES.x * SCREEN_THRESHOLD_COEFF, SCREEN_SPACE_RES.y * SCREEN_THRESHOLD_COEFF);
|
||||||
|
|
||||||
|
return (Position.x <= -SCREEN_THRESHOLD.x ||
|
||||||
|
Position.y <= -SCREEN_THRESHOLD.y ||
|
||||||
|
Position.x >= (SCREEN_SPACE_RES.x + SCREEN_THRESHOLD.x) ||
|
||||||
|
Position.y >= (SCREEN_SPACE_RES.y + SCREEN_THRESHOLD.y));
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayPickup::Update(bool isHead)
|
||||||
|
{
|
||||||
|
constexpr auto LIFE_BUFFER = 0.2f;
|
||||||
|
constexpr auto SCALE_MAX = 0.4f;
|
||||||
|
constexpr auto SCALE_MIN = 0.2f;
|
||||||
|
constexpr auto HIDE_VELOCITY_COEFF = 3 / 100.0f;
|
||||||
|
constexpr auto POSITION_LERP_ALPHA = 0.2f;
|
||||||
|
constexpr auto STRING_SCALAR_ALPHA = 0.25f;
|
||||||
|
constexpr auto ROTATION = EulerAngles(0, ANGLE(3.0f), 0);
|
||||||
|
|
||||||
|
// Move offscreen.
|
||||||
|
if (Life <= 0.0f && isHead)
|
||||||
|
{
|
||||||
|
auto vel = Vector2(SCREEN_SPACE_RES.x * HIDE_VELOCITY_COEFF, 0.0f);
|
||||||
|
this->Position += vel;
|
||||||
|
}
|
||||||
|
// Update position, scale, and opacity.
|
||||||
|
else if (Life > 0.0f)
|
||||||
|
{
|
||||||
|
float totalDist = Vector2::Distance(Origin, Target);
|
||||||
|
float coveredDist = Vector2::Distance(Origin, Position);
|
||||||
|
|
||||||
|
// Handle edge case when stack shifts.
|
||||||
|
if (coveredDist > totalDist)
|
||||||
|
{
|
||||||
|
this->Origin = Position;
|
||||||
|
totalDist = Vector2::Distance(Origin, Target);
|
||||||
|
coveredDist = Vector2::Distance(Origin, Position);
|
||||||
|
}
|
||||||
|
|
||||||
|
float alpha = coveredDist / totalDist;
|
||||||
|
|
||||||
|
this->Position = Vector2::Lerp(Position, Target, POSITION_LERP_ALPHA);
|
||||||
|
this->Scale = std::max(Lerp(SCALE_MIN, SCALE_MAX, alpha), Scale);
|
||||||
|
this->Opacity = std::max(Lerp(0.0f, 1.0f, alpha), Opacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update orientation.
|
||||||
|
this->Orientation += ROTATION;
|
||||||
|
|
||||||
|
// Update string scale.
|
||||||
|
float alpha = Scale / SCALE_MAX;
|
||||||
|
this->StringScale = Lerp(0.0f, 1.0f, alpha) * (1.0f + StringScalar);
|
||||||
|
this->StringScalar = Lerp(StringScalar, 0.0f, STRING_SCALAR_ALPHA);
|
||||||
|
|
||||||
|
// Update life.
|
||||||
|
this->Life -= 1.0f;
|
||||||
|
if (!isHead)
|
||||||
|
this->Life = std::max(Life, round(LIFE_BUFFER * FPS));
|
||||||
|
}
|
||||||
|
|
||||||
|
void PickupSummaryController::AddDisplayPickup(GAME_OBJECT_ID objectID, const Vector3& pos)
|
||||||
|
{
|
||||||
|
constexpr auto DEFAULT_POSITION = Vector2(0.0f, 0.0f);
|
||||||
|
constexpr auto LIFE_MAX = 2.5f;
|
||||||
|
constexpr auto STRING_SCALAR_MAX = 0.6f;
|
||||||
|
|
||||||
|
// TODO: Call this elsewhere, maybe in pickup.cpp. -- Sezz 2023.02.06
|
||||||
|
PickedUpObject(objectID);
|
||||||
|
|
||||||
|
// Increment count of existing display pickup if it exists.
|
||||||
|
for (auto& pickup : this->DisplayPickups)
|
||||||
|
{
|
||||||
|
// Ignore already disappearing display pickups.
|
||||||
|
if (pickup.Life <= 0.0f)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (pickup.ObjectID == objectID)
|
||||||
|
{
|
||||||
|
pickup.Count++;
|
||||||
|
pickup.Life = round(LIFE_MAX * FPS);
|
||||||
|
pickup.StringScalar = STRING_SCALAR_MAX;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create new display pickup.
|
||||||
|
auto& pickup = this->GetNewDisplayPickup();
|
||||||
|
|
||||||
|
auto screenPos = g_Renderer.GetScreenSpacePosition(pos);
|
||||||
|
if (screenPos == INVALID_SCREEN_SPACE_POSITION)
|
||||||
|
screenPos = DEFAULT_POSITION;
|
||||||
|
|
||||||
|
pickup.ObjectID = objectID;
|
||||||
|
pickup.Count = 1;
|
||||||
|
pickup.Position =
|
||||||
|
pickup.Origin = screenPos;
|
||||||
|
pickup.Target = Vector2::Zero;
|
||||||
|
pickup.Life = round(LIFE_MAX * FPS);
|
||||||
|
pickup.Scale = 0.0f;
|
||||||
|
pickup.Opacity = 0.0f;
|
||||||
|
pickup.HideVelocity = 0.0f;
|
||||||
|
pickup.StringScale = 0.0f;
|
||||||
|
pickup.StringScalar = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PickupSummaryController::Update()
|
||||||
|
{
|
||||||
|
if (DisplayPickups.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Get and apply stack screen positions as targets.
|
||||||
|
auto stackPositions = this->GetStackPositions();
|
||||||
|
for (int i = 0; i < stackPositions.size(); i++)
|
||||||
|
this->DisplayPickups[i].Target = stackPositions[i];
|
||||||
|
|
||||||
|
// Update display pickups.
|
||||||
|
bool isHead = true;
|
||||||
|
for (auto& pickup : this->DisplayPickups)
|
||||||
|
{
|
||||||
|
pickup.Update(isHead);
|
||||||
|
isHead = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->ClearInactiveDisplayPickups();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PickupSummaryController::Draw() const
|
||||||
|
{
|
||||||
|
//this->DrawDebug();
|
||||||
|
|
||||||
|
if (DisplayPickups.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Draw display pickups.
|
||||||
|
for (const auto& pickup : this->DisplayPickups)
|
||||||
|
{
|
||||||
|
if (pickup.IsOffscreen())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
g_Renderer.DrawPickup(pickup);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PickupSummaryController::Clear()
|
||||||
|
{
|
||||||
|
this->DisplayPickups.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Vector2> PickupSummaryController::GetStackPositions() const
|
||||||
|
{
|
||||||
|
constexpr auto STACK_HEIGHT_MAX = 6;
|
||||||
|
constexpr auto SCREEN_SCALE_COEFF = 1 / 7.0f;
|
||||||
|
constexpr auto SCREEN_OFFSET_COEFF = 1 / 7.0f;
|
||||||
|
constexpr auto SCREEN_SCALE = Vector2(SCREEN_SPACE_RES.x * SCREEN_SCALE_COEFF, SCREEN_SPACE_RES.y * SCREEN_SCALE_COEFF);
|
||||||
|
constexpr auto SCREEN_OFFSET = Vector2(SCREEN_SPACE_RES.y * SCREEN_OFFSET_COEFF);
|
||||||
|
|
||||||
|
// Calculate screen positions.
|
||||||
|
auto stackPositions = std::vector<Vector2>{};
|
||||||
|
for (int i = 0; i < DisplayPickups.size(); i++)
|
||||||
|
{
|
||||||
|
auto relPos = (i < STACK_HEIGHT_MAX) ? (Vector2(0.0f, i) * SCREEN_SCALE) : Vector2(0.0f, SCREEN_SPACE_RES.y);
|
||||||
|
auto pos = (SCREEN_SPACE_RES - relPos) - SCREEN_OFFSET;
|
||||||
|
stackPositions.push_back(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
return stackPositions;
|
||||||
|
}
|
||||||
|
|
||||||
|
DisplayPickup& PickupSummaryController::GetNewDisplayPickup()
|
||||||
|
{
|
||||||
|
// Add and return new display pickup.
|
||||||
|
if (DisplayPickups.size() < DISPLAY_PICKUP_COUNT_MAX)
|
||||||
|
return this->DisplayPickups.emplace_back();
|
||||||
|
|
||||||
|
// Clear and return most recent display pickup.
|
||||||
|
auto& pickup = this->DisplayPickups.back();
|
||||||
|
pickup = DisplayPickup();
|
||||||
|
return pickup;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PickupSummaryController::ClearInactiveDisplayPickups()
|
||||||
|
{
|
||||||
|
this->DisplayPickups.erase(
|
||||||
|
std::remove_if(
|
||||||
|
this->DisplayPickups.begin(), this->DisplayPickups.end(),
|
||||||
|
[](const DisplayPickup& pickup) { return ((pickup.Life <= 0.0f) && pickup.IsOffscreen()); }),
|
||||||
|
this->DisplayPickups.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
void PickupSummaryController::DrawDebug() const
|
||||||
|
{
|
||||||
|
g_Renderer.PrintDebugMessage("Num. display pickups: %d", DisplayPickups.size());
|
||||||
|
}
|
||||||
|
}
|
52
TombEngine/Game/Hud/PickupSummary.h
Normal file
52
TombEngine/Game/Hud/PickupSummary.h
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
#pragma once
|
||||||
|
#include "Math/Math.h"
|
||||||
|
#include "Objects/game_object_ids.h"
|
||||||
|
|
||||||
|
using namespace TEN::Math;
|
||||||
|
|
||||||
|
namespace TEN::Hud
|
||||||
|
{
|
||||||
|
struct DisplayPickup
|
||||||
|
{
|
||||||
|
GAME_OBJECT_ID ObjectID = ID_NO_OBJECT;
|
||||||
|
unsigned int Count = 0;
|
||||||
|
|
||||||
|
Vector2 Position = Vector2::Zero;
|
||||||
|
Vector2 Origin = Vector2::Zero;
|
||||||
|
Vector2 Target = Vector2::Zero;
|
||||||
|
EulerAngles Orientation = EulerAngles::Zero;
|
||||||
|
|
||||||
|
float Life = 0.0f;
|
||||||
|
float Scale = 0.0f;
|
||||||
|
float Opacity = 0.0f; // BIG TODO: Object transparency in renderer.
|
||||||
|
float HideVelocity = 0.0f;
|
||||||
|
float StringScale = 0.0f;
|
||||||
|
float StringScalar = 0.0f;
|
||||||
|
|
||||||
|
bool IsOffscreen() const;
|
||||||
|
void Update(bool isHead);
|
||||||
|
};
|
||||||
|
|
||||||
|
class PickupSummaryController
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
// Components
|
||||||
|
std::deque<DisplayPickup> DisplayPickups = {};
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Utilities
|
||||||
|
void AddDisplayPickup(GAME_OBJECT_ID objectID, const Vector3& pos);
|
||||||
|
|
||||||
|
void Update();
|
||||||
|
void Draw() const;
|
||||||
|
void Clear();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Helpers
|
||||||
|
std::vector<Vector2> GetStackPositions() const;
|
||||||
|
DisplayPickup& GetNewDisplayPickup();
|
||||||
|
void ClearInactiveDisplayPickups();
|
||||||
|
|
||||||
|
void DrawDebug() const;
|
||||||
|
};
|
||||||
|
}
|
|
@ -4,7 +4,7 @@
|
||||||
#include "Game/animation.h"
|
#include "Game/animation.h"
|
||||||
#include "Game/camera.h"
|
#include "Game/camera.h"
|
||||||
#include "Game/collision/collide_room.h"
|
#include "Game/collision/collide_room.h"
|
||||||
#include "Game/health.h"
|
#include "Game/Hud/Hud.h"
|
||||||
#include "Game/items.h"
|
#include "Game/items.h"
|
||||||
#include "Game/Lara/lara.h"
|
#include "Game/Lara/lara.h"
|
||||||
#include "Game/Lara/lara_tests.h"
|
#include "Game/Lara/lara_tests.h"
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include "framework.h"
|
#include "framework.h"
|
||||||
#include "Game/Lara/lara_initialise.h"
|
#include "Game/Lara/lara_initialise.h"
|
||||||
|
|
||||||
#include "Game/health.h"
|
#include "Game/Hud/Hud.h"
|
||||||
#include "Game/items.h"
|
#include "Game/items.h"
|
||||||
#include "Game/Lara/lara.h"
|
#include "Game/Lara/lara.h"
|
||||||
#include "Game/Lara/lara_flare.h"
|
#include "Game/Lara/lara_flare.h"
|
||||||
|
|
|
@ -545,8 +545,6 @@ void ClampRotation(Pose& outPose, short angle, short rotation)
|
||||||
|
|
||||||
Vector3i GetJointPosition(ItemInfo* item, int jointIndex, const Vector3i& relOffset)
|
Vector3i GetJointPosition(ItemInfo* item, int jointIndex, const Vector3i& relOffset)
|
||||||
{
|
{
|
||||||
// Use matrices done in the renderer to transform the offset vector.
|
// Use matrices done in renderer to transform relative offset.
|
||||||
auto pos = relOffset.ToVector3();
|
return Vector3i(g_Renderer.GetAbsEntityBonePosition(item->Index, jointIndex, relOffset.ToVector3()));
|
||||||
g_Renderer.GetItemAbsBonePosition(item->Index, pos, jointIndex);
|
|
||||||
return Vector3i(pos);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,11 +24,11 @@
|
||||||
#include "Game/effects/tomb4fx.h"
|
#include "Game/effects/tomb4fx.h"
|
||||||
#include "Game/effects/weather.h"
|
#include "Game/effects/weather.h"
|
||||||
#include "Game/Gui.h"
|
#include "Game/Gui.h"
|
||||||
|
#include "Game/Hud/Hud.h"
|
||||||
#include "Game/Lara/lara.h"
|
#include "Game/Lara/lara.h"
|
||||||
#include "Game/Lara/lara_cheat.h"
|
#include "Game/Lara/lara_cheat.h"
|
||||||
#include "Game/Lara/lara_helpers.h"
|
#include "Game/Lara/lara_helpers.h"
|
||||||
#include "Game/Lara/lara_one_gun.h"
|
#include "Game/Lara/lara_one_gun.h"
|
||||||
#include "Game/health.h"
|
|
||||||
#include "Game/items.h"
|
#include "Game/items.h"
|
||||||
#include "Game/pickup/pickup.h"
|
#include "Game/pickup/pickup.h"
|
||||||
#include "Game/room.h"
|
#include "Game/room.h"
|
||||||
|
@ -68,6 +68,7 @@ using namespace TEN::Entities::Generic;
|
||||||
using namespace TEN::Entities::Switches;
|
using namespace TEN::Entities::Switches;
|
||||||
using namespace TEN::Entities::TR4;
|
using namespace TEN::Entities::TR4;
|
||||||
using namespace TEN::Floordata;
|
using namespace TEN::Floordata;
|
||||||
|
using namespace TEN::Hud;
|
||||||
using namespace TEN::Input;
|
using namespace TEN::Input;
|
||||||
using namespace TEN::Math;
|
using namespace TEN::Math;
|
||||||
using namespace TEN::Renderer;
|
using namespace TEN::Renderer;
|
||||||
|
@ -213,9 +214,10 @@ GameStatus ControlPhase(int numFrames)
|
||||||
UpdateBeetleSwarm();
|
UpdateBeetleSwarm();
|
||||||
UpdateLocusts();
|
UpdateLocusts();
|
||||||
|
|
||||||
// Update screen UI and overlays.
|
// Update HUD.
|
||||||
UpdateBars(LaraItem);
|
UpdateBars(LaraItem);
|
||||||
UpdateFadeScreenAndCinematicBars();
|
UpdateFadeScreenAndCinematicBars();
|
||||||
|
g_Hud.Update();
|
||||||
|
|
||||||
// Rumble screen (like in submarine level of TRC).
|
// Rumble screen (like in submarine level of TRC).
|
||||||
if (g_GameFlow->GetLevel(CurrentLevel)->Rumble)
|
if (g_GameFlow->GetLevel(CurrentLevel)->Rumble)
|
||||||
|
@ -285,7 +287,6 @@ GameStatus DoLevel(int levelIndex, bool loadGame)
|
||||||
|
|
||||||
// Initialize items, effects, lots, and cameras.
|
// Initialize items, effects, lots, and cameras.
|
||||||
InitialiseFXArray(true);
|
InitialiseFXArray(true);
|
||||||
InitialisePickupDisplay();
|
|
||||||
InitialiseCamera();
|
InitialiseCamera();
|
||||||
InitialiseSpotCamSequences(isTitle);
|
InitialiseSpotCamSequences(isTitle);
|
||||||
InitialiseHair();
|
InitialiseHair();
|
||||||
|
@ -411,6 +412,9 @@ void CleanUp()
|
||||||
// Clear swarm enemies.
|
// Clear swarm enemies.
|
||||||
ClearSwarmEnemies(nullptr);
|
ClearSwarmEnemies(nullptr);
|
||||||
|
|
||||||
|
// Clear HUD.
|
||||||
|
g_Hud.Clear();
|
||||||
|
|
||||||
// Clear soundtrack masks.
|
// Clear soundtrack masks.
|
||||||
ClearSoundTrackMasks();
|
ClearSoundTrackMasks();
|
||||||
|
|
||||||
|
@ -434,9 +438,10 @@ void InitialiseScripting(int levelIndex, bool loadGame)
|
||||||
g_GameScript->InitCallbacks();
|
g_GameScript->InitCallbacks();
|
||||||
g_GameStringsHandler->SetCallbackDrawString([](std::string const key, D3DCOLOR col, int x, int y, int flags)
|
g_GameStringsHandler->SetCallbackDrawString([](std::string const key, D3DCOLOR col, int x, int y, int flags)
|
||||||
{
|
{
|
||||||
g_Renderer.AddString(float(x) / float(g_Configuration.Width) * REFERENCE_RES_WIDTH,
|
g_Renderer.AddString(
|
||||||
float(y) / float(g_Configuration.Height) * REFERENCE_RES_HEIGHT,
|
float(x) / float(g_Configuration.Width) * SCREEN_SPACE_RES.x,
|
||||||
key.c_str(), col, flags);
|
float(y) / float(g_Configuration.Height) * SCREEN_SPACE_RES.y,
|
||||||
|
key.c_str(), col, flags);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,8 +33,8 @@ using namespace TEN::Utils;
|
||||||
namespace TEN::Gui
|
namespace TEN::Gui
|
||||||
{
|
{
|
||||||
constexpr int LINE_HEIGHT = 25;
|
constexpr int LINE_HEIGHT = 25;
|
||||||
constexpr int PHD_CENTER_X = REFERENCE_RES_WIDTH / 2;
|
constexpr int PHD_CENTER_X = SCREEN_SPACE_RES.x / 2;
|
||||||
constexpr int PHD_CENTER_Y = REFERENCE_RES_HEIGHT / 2;
|
constexpr int PHD_CENTER_Y = SCREEN_SPACE_RES.y / 2;
|
||||||
|
|
||||||
constexpr int VOLUME_MAX = 100;
|
constexpr int VOLUME_MAX = 100;
|
||||||
|
|
||||||
|
@ -2486,12 +2486,14 @@ namespace TEN::Gui
|
||||||
g_Renderer.AddString(PHD_CENTER_X, 380, &invTextBuffer[0], PRINTSTRING_COLOR_YELLOW, PRINTSTRING_CENTER | PRINTSTRING_OUTLINE);
|
g_Renderer.AddString(PHD_CENTER_X, 380, &invTextBuffer[0], PRINTSTRING_COLOR_YELLOW, PRINTSTRING_CENTER | PRINTSTRING_OUTLINE);
|
||||||
|
|
||||||
if (n == *CurrentAmmoType)
|
if (n == *CurrentAmmoType)
|
||||||
g_Renderer.DrawObjectOn2DPosition(x, y, objectNumber, AmmoObjectList[n].Orientation, scaler);
|
g_Renderer.DrawObjectOn2DPosition(objectNumber, Vector2(x, y), AmmoObjectList[n].Orientation, scaler);
|
||||||
else
|
else
|
||||||
g_Renderer.DrawObjectOn2DPosition(x, y, objectNumber, AmmoObjectList[n].Orientation, scaler);
|
g_Renderer.DrawObjectOn2DPosition(objectNumber, Vector2(x, y), AmmoObjectList[n].Orientation, scaler);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
g_Renderer.DrawObjectOn2DPosition(x, y, objectNumber, AmmoObjectList[n].Orientation, scaler);
|
{
|
||||||
|
g_Renderer.DrawObjectOn2DPosition(objectNumber, Vector2(x, y), AmmoObjectList[n].Orientation, scaler);
|
||||||
|
}
|
||||||
|
|
||||||
xPos += OBJLIST_SPACING;
|
xPos += OBJLIST_SPACING;
|
||||||
}
|
}
|
||||||
|
@ -2775,9 +2777,9 @@ namespace TEN::Gui
|
||||||
|
|
||||||
int objectNumber;
|
int objectNumber;
|
||||||
if (ringIndex == (int)RingTypes::Inventory)
|
if (ringIndex == (int)RingTypes::Inventory)
|
||||||
objectNumber = int(PHD_CENTER_Y - (REFERENCE_RES_HEIGHT + 1) * 0.0625 * 2.5);
|
objectNumber = int(PHD_CENTER_Y - (SCREEN_SPACE_RES.y + 1) * 0.0625 * 2.5);
|
||||||
else
|
else
|
||||||
objectNumber = int(PHD_CENTER_Y + (REFERENCE_RES_HEIGHT + 1) * 0.0625 * 2.0);
|
objectNumber = int(PHD_CENTER_Y + (SCREEN_SPACE_RES.y + 1) * 0.0625 * 2.0);
|
||||||
|
|
||||||
g_Renderer.AddString(PHD_CENTER_X, objectNumber, textBufferMe, PRINTSTRING_COLOR_YELLOW, PRINTSTRING_CENTER | PRINTSTRING_OUTLINE);
|
g_Renderer.AddString(PHD_CENTER_X, objectNumber, textBufferMe, PRINTSTRING_COLOR_YELLOW, PRINTSTRING_CENTER | PRINTSTRING_OUTLINE);
|
||||||
}
|
}
|
||||||
|
@ -2830,7 +2832,7 @@ namespace TEN::Gui
|
||||||
auto& orientation = Rings[ringIndex]->CurrentObjectList[n].Orientation;
|
auto& orientation = Rings[ringIndex]->CurrentObjectList[n].Orientation;
|
||||||
int bits = InventoryObjectTable[Rings[ringIndex]->CurrentObjectList[n].InventoryItem].MeshBits;
|
int bits = InventoryObjectTable[Rings[ringIndex]->CurrentObjectList[n].InventoryItem].MeshBits;
|
||||||
|
|
||||||
g_Renderer.DrawObjectOn2DPosition(x, ringIndex == (int)RingTypes::Inventory ? y : y2, objectNumber, orientation, scaler, bits);
|
g_Renderer.DrawObjectOn2DPosition(objectNumber, Vector2(x, (ringIndex == (int)RingTypes::Inventory) ? y : y2), orientation, scaler, bits);
|
||||||
|
|
||||||
if (++n >= Rings[ringIndex]->NumObjectsInList)
|
if (++n >= Rings[ringIndex]->NumObjectsInList)
|
||||||
n = 0;
|
n = 0;
|
||||||
|
@ -3043,7 +3045,7 @@ namespace TEN::Gui
|
||||||
// TODO
|
// TODO
|
||||||
return;
|
return;
|
||||||
|
|
||||||
g_Renderer.DrawObjectOn2DPosition(130, 480, ID_COMPASS_ITEM, EulerAngles(ANGLE(90.0f), 0, ANGLE(180.0f)), InventoryObjectTable[INV_OBJECT_COMPASS].Scale1);
|
g_Renderer.DrawObjectOn2DPosition(ID_COMPASS_ITEM, Vector2(130, 480), EulerAngles(ANGLE(90.0f), 0, ANGLE(180.0f)), InventoryObjectTable[INV_OBJECT_COMPASS].Scale1);
|
||||||
short compassSpeed = phd_sin(CompassNeedleAngle - item->Pose.Orientation.y);
|
short compassSpeed = phd_sin(CompassNeedleAngle - item->Pose.Orientation.y);
|
||||||
short compassAngle = (item->Pose.Orientation.y + compassSpeed) - ANGLE(180.0f);
|
short compassAngle = (item->Pose.Orientation.y + compassSpeed) - ANGLE(180.0f);
|
||||||
Matrix::CreateRotationY(compassAngle);
|
Matrix::CreateRotationY(compassAngle);
|
||||||
|
|
|
@ -1,285 +0,0 @@
|
||||||
#include "framework.h"
|
|
||||||
#include "Game/health.h"
|
|
||||||
|
|
||||||
#include "Game/animation.h"
|
|
||||||
#include "Game/camera.h"
|
|
||||||
#include "Game/control/control.h"
|
|
||||||
#include "Game/items.h"
|
|
||||||
#include "Game/Lara/lara.h"
|
|
||||||
#include "Game/Lara/lara_helpers.h"
|
|
||||||
#include "Game/Lara/lara_tests.h"
|
|
||||||
#include "Game/pickup/pickup.h"
|
|
||||||
#include "Renderer/Renderer11.h"
|
|
||||||
#include "Specific/level.h"
|
|
||||||
|
|
||||||
using namespace TEN::Renderer;
|
|
||||||
|
|
||||||
short PickupX;
|
|
||||||
short PickupY;
|
|
||||||
short PickupVel;
|
|
||||||
short CurrentPickup;
|
|
||||||
DisplayPickup Pickups[MAX_COLLECTED_PICKUPS];
|
|
||||||
|
|
||||||
float HealthBarOldValue = LARA_HEALTH_MAX;
|
|
||||||
float HealthBarValue = HealthBarOldValue;
|
|
||||||
float HealthBarMutateAmount = 0;
|
|
||||||
int HealthBarTimer = 40;
|
|
||||||
bool EnableSmoothHealthBar = true;
|
|
||||||
|
|
||||||
extern RendererHUDBar* g_HealthBar;
|
|
||||||
extern RendererHUDBar* g_DashBar;
|
|
||||||
extern RendererHUDBar* g_AirBar;
|
|
||||||
|
|
||||||
void DrawHUD(ItemInfo* item)
|
|
||||||
{
|
|
||||||
static bool doFlash = false;
|
|
||||||
if ((GameTimer & 0x07) == 0x07)
|
|
||||||
doFlash = !doFlash;
|
|
||||||
|
|
||||||
if (CurrentLevel == 0 || CinematicBarsHeight > 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
DrawSprintBar(LaraItem);
|
|
||||||
DrawHealthBar(LaraItem, doFlash);
|
|
||||||
DrawAirBar(LaraItem, doFlash);
|
|
||||||
DrawAllPickups();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DrawHealthBarOverlay(ItemInfo* item, int value)
|
|
||||||
{
|
|
||||||
const auto& lara = *GetLaraInfo(item);
|
|
||||||
|
|
||||||
if (CurrentLevel)
|
|
||||||
g_Renderer.DrawBar(value, g_HealthBar, ID_HEALTH_BAR_TEXTURE, GlobalCounter, Lara.PoisonPotency);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DrawHealthBar(ItemInfo* item, float value)
|
|
||||||
{
|
|
||||||
const auto& lara = *GetLaraInfo(item);
|
|
||||||
|
|
||||||
g_Renderer.DrawBar(value, g_HealthBar, ID_HEALTH_BAR_TEXTURE, GlobalCounter, lara.PoisonPotency);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DrawHealthBar(ItemInfo* item, bool doFlash)
|
|
||||||
{
|
|
||||||
const auto& lara = *GetLaraInfo(item);
|
|
||||||
|
|
||||||
// Flash when at critical capacity and bar is not transitioning.
|
|
||||||
if (HealthBarValue <= LARA_HEALTH_CRITICAL)
|
|
||||||
{
|
|
||||||
if (!BinocularRange)
|
|
||||||
{
|
|
||||||
if (doFlash || HealthBarMutateAmount)
|
|
||||||
DrawHealthBar(item, HealthBarValue / LARA_HEALTH_MAX);
|
|
||||||
else
|
|
||||||
DrawHealthBar(item, 0.0f);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (doFlash || HealthBarMutateAmount)
|
|
||||||
DrawHealthBarOverlay(item, HealthBarValue / LARA_HEALTH_MAX);
|
|
||||||
else
|
|
||||||
DrawHealthBarOverlay(item, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (HealthBarTimer > 0 || HealthBarValue <= 0 ||
|
|
||||||
lara.Control.HandStatus == HandStatus::WeaponReady &&
|
|
||||||
lara.Control.Weapon.GunType != LaraWeaponType::Torch ||
|
|
||||||
lara.PoisonPotency)
|
|
||||||
{
|
|
||||||
if (!BinocularRange)
|
|
||||||
DrawHealthBar(item, HealthBarValue / LARA_HEALTH_MAX);
|
|
||||||
else
|
|
||||||
DrawHealthBarOverlay(item, HealthBarValue / LARA_HEALTH_MAX);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DrawAirBar(float value)
|
|
||||||
{
|
|
||||||
g_Renderer.DrawBar(value, g_AirBar,ID_AIR_BAR_TEXTURE, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DrawAirBar(ItemInfo* item, bool doFlash)
|
|
||||||
{
|
|
||||||
const auto& lara = *GetLaraInfo(item);
|
|
||||||
|
|
||||||
if (lara.Air == LARA_AIR_MAX || item->HitPoints <= 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (lara.Vehicle == NO_ITEM ||
|
|
||||||
g_Level.Items[lara.Vehicle].ObjectNumber != ID_UPV)
|
|
||||||
{
|
|
||||||
if (lara.Control.WaterStatus != WaterStatus::Underwater &&
|
|
||||||
lara.Control.WaterStatus != WaterStatus::TreadWater &&
|
|
||||||
!(TestEnvironment(ENV_FLAG_SWAMP, item) && lara.WaterSurfaceDist < -(CLICK(3) - 1)))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
float air = lara.Air;
|
|
||||||
if (air < 0.0f)
|
|
||||||
{
|
|
||||||
air = 0.0f;
|
|
||||||
}
|
|
||||||
else if (air > LARA_AIR_MAX)
|
|
||||||
{
|
|
||||||
air = LARA_AIR_MAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (air <= LARA_AIR_CRITICAL)
|
|
||||||
{
|
|
||||||
if (doFlash)
|
|
||||||
DrawAirBar(air / LARA_AIR_MAX);
|
|
||||||
else
|
|
||||||
DrawAirBar(0.0f);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DrawAirBar(air / LARA_AIR_MAX);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DrawSprintBar(float value)
|
|
||||||
{
|
|
||||||
g_Renderer.DrawBar(value, g_DashBar, ID_DASH_BAR_TEXTURE, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DrawSprintBar(ItemInfo* item)
|
|
||||||
{
|
|
||||||
const auto& lara = *GetLaraInfo(item);
|
|
||||||
|
|
||||||
if (lara.SprintEnergy < LARA_SPRINT_ENERGY_MAX)
|
|
||||||
DrawSprintBar(lara.SprintEnergy / LARA_SPRINT_ENERGY_MAX);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DrawAllPickups()
|
|
||||||
{
|
|
||||||
auto& pickup = Pickups[CurrentPickup];
|
|
||||||
|
|
||||||
if (pickup.Life > 0)
|
|
||||||
{
|
|
||||||
if (PickupX > 0)
|
|
||||||
PickupX += -PickupX >> 3;
|
|
||||||
else
|
|
||||||
pickup.Life--;
|
|
||||||
}
|
|
||||||
else if (pickup.Life == 0)
|
|
||||||
{
|
|
||||||
if (PickupX < 128)
|
|
||||||
{
|
|
||||||
if (PickupVel < 16)
|
|
||||||
PickupVel++;
|
|
||||||
|
|
||||||
PickupX += PickupVel;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pickup.Life = -1;
|
|
||||||
PickupVel = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < MAX_COLLECTED_PICKUPS; i++)
|
|
||||||
{
|
|
||||||
if (Pickups[CurrentPickup].Life > 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
CurrentPickup++;
|
|
||||||
CurrentPickup &= (MAX_COLLECTED_PICKUPS - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i == MAX_COLLECTED_PICKUPS)
|
|
||||||
{
|
|
||||||
CurrentPickup = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
g_Renderer.DrawPickup(Pickups[CurrentPickup].ObjectNumber);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AddDisplayPickup(GAME_OBJECT_ID objectNumber)
|
|
||||||
{
|
|
||||||
for (auto& pickup : Pickups)
|
|
||||||
{
|
|
||||||
if (pickup.Life < 0)
|
|
||||||
{
|
|
||||||
pickup.Life = 45;
|
|
||||||
pickup.ObjectNumber = objectNumber;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// No free slot found; pickup the object without displaying it.
|
|
||||||
PickedUpObject(objectNumber);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InitialisePickupDisplay()
|
|
||||||
{
|
|
||||||
for (auto& pickup : Pickups)
|
|
||||||
pickup.Life = -1;
|
|
||||||
|
|
||||||
PickupX = 128;
|
|
||||||
PickupY = 128;
|
|
||||||
PickupVel = 0;
|
|
||||||
CurrentPickup = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void UpdateBars(ItemInfo* item)
|
|
||||||
{
|
|
||||||
if (HealthBarTimer)
|
|
||||||
HealthBarTimer--;
|
|
||||||
|
|
||||||
const auto& lara = *GetLaraInfo(item);
|
|
||||||
|
|
||||||
float hitPoints = item->HitPoints;
|
|
||||||
|
|
||||||
if (hitPoints < 0)
|
|
||||||
{
|
|
||||||
hitPoints = 0;
|
|
||||||
}
|
|
||||||
else if (hitPoints > LARA_HEALTH_MAX)
|
|
||||||
{
|
|
||||||
hitPoints = LARA_HEALTH_MAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Smoothly transition health bar display.
|
|
||||||
if (EnableSmoothHealthBar)
|
|
||||||
{
|
|
||||||
if (HealthBarOldValue != hitPoints)
|
|
||||||
{
|
|
||||||
HealthBarMutateAmount += HealthBarOldValue - hitPoints;
|
|
||||||
HealthBarOldValue = hitPoints;
|
|
||||||
HealthBarTimer = 40;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (HealthBarValue - HealthBarMutateAmount < 0)
|
|
||||||
{
|
|
||||||
HealthBarMutateAmount = HealthBarValue;
|
|
||||||
}
|
|
||||||
else if (HealthBarValue - HealthBarMutateAmount > LARA_HEALTH_MAX)
|
|
||||||
{
|
|
||||||
HealthBarMutateAmount = HealthBarValue - LARA_HEALTH_MAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
HealthBarValue -= HealthBarMutateAmount / 3;
|
|
||||||
HealthBarMutateAmount -= HealthBarMutateAmount / 3;
|
|
||||||
|
|
||||||
if (HealthBarMutateAmount > -0.5f && HealthBarMutateAmount < 0.5f)
|
|
||||||
{
|
|
||||||
HealthBarMutateAmount = 0;
|
|
||||||
HealthBarValue = hitPoints;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Discretely transition health bar display.
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (HealthBarOldValue != hitPoints)
|
|
||||||
{
|
|
||||||
HealthBarOldValue = hitPoints;
|
|
||||||
HealthBarValue = hitPoints;
|
|
||||||
HealthBarTimer = 40;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,31 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include "Game/items.h"
|
|
||||||
|
|
||||||
#define MAX_COLLECTED_PICKUPS 32
|
|
||||||
|
|
||||||
enum GAME_OBJECT_ID : short;
|
|
||||||
|
|
||||||
struct DisplayPickup
|
|
||||||
{
|
|
||||||
int Life;
|
|
||||||
short ObjectNumber;
|
|
||||||
};
|
|
||||||
|
|
||||||
void DrawHUD(ItemInfo* item);
|
|
||||||
void DrawHealthBarOverlay(ItemInfo* item, int value);
|
|
||||||
void DrawHealthBar(ItemInfo* item, float value);
|
|
||||||
void DrawHealthBar(ItemInfo* item, bool doFlash);
|
|
||||||
void DrawAirBar(float value);
|
|
||||||
void DrawAirBar(ItemInfo* item, bool doFlash);
|
|
||||||
void DrawSprintBar(float value);
|
|
||||||
void DrawSprintBar(ItemInfo* item);
|
|
||||||
void UpdateBars(ItemInfo* item);
|
|
||||||
void AddDisplayPickup(GAME_OBJECT_ID objectNumber);
|
|
||||||
void DrawAllPickups();
|
|
||||||
void InitialisePickupDisplay();
|
|
||||||
|
|
||||||
extern short PickupX;
|
|
||||||
extern short PickupY;
|
|
||||||
extern DisplayPickup Pickups[MAX_COLLECTED_PICKUPS];
|
|
||||||
|
|
||||||
extern bool EnableSmoothHealthBar;
|
|
|
@ -7,8 +7,8 @@
|
||||||
#include "Game/collision/collide_item.h"
|
#include "Game/collision/collide_item.h"
|
||||||
#include "Game/effects/debris.h"
|
#include "Game/effects/debris.h"
|
||||||
#include "Game/Gui.h"
|
#include "Game/Gui.h"
|
||||||
|
#include "Game/Hud/Hud.h"
|
||||||
#include "Game/items.h"
|
#include "Game/items.h"
|
||||||
#include "Game/health.h"
|
|
||||||
#include "Game/Lara/lara.h"
|
#include "Game/Lara/lara.h"
|
||||||
#include "Game/Lara/lara_fire.h"
|
#include "Game/Lara/lara_fire.h"
|
||||||
#include "Game/Lara/lara_flare.h"
|
#include "Game/Lara/lara_flare.h"
|
||||||
|
@ -31,6 +31,7 @@
|
||||||
#include "Scripting/Include/Flow/ScriptInterfaceFlowHandler.h"
|
#include "Scripting/Include/Flow/ScriptInterfaceFlowHandler.h"
|
||||||
|
|
||||||
using namespace TEN::Entities::Generic;
|
using namespace TEN::Entities::Generic;
|
||||||
|
using namespace TEN::Hud;
|
||||||
using namespace TEN::Input;
|
using namespace TEN::Input;
|
||||||
|
|
||||||
static auto PickUpPosition = Vector3i(0, 0, -100);
|
static auto PickUpPosition = Vector3i(0, 0, -100);
|
||||||
|
@ -39,12 +40,10 @@ const ObjectCollisionBounds PickUpBounds =
|
||||||
GameBoundingBox(
|
GameBoundingBox(
|
||||||
-CLICK(1), CLICK(1),
|
-CLICK(1), CLICK(1),
|
||||||
-200, 200,
|
-200, 200,
|
||||||
-CLICK(1), CLICK(1)
|
-CLICK(1), CLICK(1)),
|
||||||
),
|
|
||||||
std::pair(
|
std::pair(
|
||||||
EulerAngles(ANGLE(-45.0f), 0, ANGLE(-45.0f)),
|
EulerAngles(ANGLE(-45.0f), 0, ANGLE(-45.0f)),
|
||||||
EulerAngles(ANGLE(45.0f), 0, ANGLE(45.0f))
|
EulerAngles(ANGLE(45.0f), 0, ANGLE(45.0f)))
|
||||||
)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static auto HiddenPickUpPosition = Vector3i(0, 0, -690);
|
static auto HiddenPickUpPosition = Vector3i(0, 0, -690);
|
||||||
|
@ -53,12 +52,10 @@ const ObjectCollisionBounds HiddenPickUpBounds =
|
||||||
GameBoundingBox(
|
GameBoundingBox(
|
||||||
-CLICK(1), CLICK(1),
|
-CLICK(1), CLICK(1),
|
||||||
-100, 100,
|
-100, 100,
|
||||||
-800, -CLICK(1)
|
-800, -CLICK(1)),
|
||||||
),
|
|
||||||
std::pair(
|
std::pair(
|
||||||
EulerAngles(ANGLE(-45.0f), ANGLE(-30.0f), ANGLE(-45.0f)),
|
EulerAngles(ANGLE(-45.0f), ANGLE(-30.0f), ANGLE(-45.0f)),
|
||||||
EulerAngles(ANGLE(45.0f), ANGLE(30.0f), ANGLE(45.0f))
|
EulerAngles(ANGLE(45.0f), ANGLE(30.0f), ANGLE(45.0f)))
|
||||||
)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static auto CrowbarPickUpPosition = Vector3i(0, 0, 215);
|
static auto CrowbarPickUpPosition = Vector3i(0, 0, 215);
|
||||||
|
@ -67,12 +64,10 @@ const ObjectCollisionBounds CrowbarPickUpBounds =
|
||||||
GameBoundingBox(
|
GameBoundingBox(
|
||||||
-CLICK(1), CLICK(1),
|
-CLICK(1), CLICK(1),
|
||||||
-100, 100,
|
-100, 100,
|
||||||
200, CLICK(2)
|
200, CLICK(2) ),
|
||||||
),
|
|
||||||
std::pair(
|
std::pair(
|
||||||
EulerAngles(ANGLE(-45.0f), ANGLE(-30.0f), ANGLE(-45.0f)),
|
EulerAngles(ANGLE(-45.0f), ANGLE(-30.0f), ANGLE(-45.0f)),
|
||||||
EulerAngles(ANGLE(45.0f), ANGLE(30.0f), ANGLE(45.0f))
|
EulerAngles(ANGLE(45.0f), ANGLE(30.0f), ANGLE(45.0f)))
|
||||||
)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static auto JobyCrowPickUpPosition = Vector3i(-224, 0, 240);
|
static auto JobyCrowPickUpPosition = Vector3i(-224, 0, 240);
|
||||||
|
@ -81,12 +76,10 @@ const ObjectCollisionBounds JobyCrowPickUpBounds =
|
||||||
GameBoundingBox(
|
GameBoundingBox(
|
||||||
-CLICK(2), 0,
|
-CLICK(2), 0,
|
||||||
-100, 100,
|
-100, 100,
|
||||||
0, CLICK(2)
|
0, CLICK(2)),
|
||||||
),
|
|
||||||
std::pair(
|
std::pair(
|
||||||
EulerAngles(ANGLE(-45.0f), ANGLE(-30.0f), ANGLE(-45.0f)),
|
EulerAngles(ANGLE(-45.0f), ANGLE(-30.0f), ANGLE(-45.0f)),
|
||||||
EulerAngles(ANGLE(45.0f), ANGLE(30.0f), ANGLE(45.0f))
|
EulerAngles(ANGLE(45.0f), ANGLE(30.0f), ANGLE(45.0f)))
|
||||||
)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static auto PlinthPickUpPosition = Vector3i(0, 0, -460);
|
static auto PlinthPickUpPosition = Vector3i(0, 0, -460);
|
||||||
|
@ -95,12 +88,10 @@ ObjectCollisionBounds PlinthPickUpBounds =
|
||||||
GameBoundingBox(
|
GameBoundingBox(
|
||||||
-CLICK(1), CLICK(1),
|
-CLICK(1), CLICK(1),
|
||||||
-640, 640,
|
-640, 640,
|
||||||
-511, 0
|
-511, 0),
|
||||||
),
|
|
||||||
std::pair(
|
std::pair(
|
||||||
EulerAngles(ANGLE(-45.0f), ANGLE(-30.0f), ANGLE(-45.0f)),
|
EulerAngles(ANGLE(-45.0f), ANGLE(-30.0f), ANGLE(-45.0f)),
|
||||||
EulerAngles(ANGLE(45.0f), ANGLE(30.0f), ANGLE(45.0f))
|
EulerAngles(ANGLE(45.0f), ANGLE(30.0f), ANGLE(45.0f)))
|
||||||
)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static auto PickUpPositionUW = Vector3i(0, -200, -350);
|
static auto PickUpPositionUW = Vector3i(0, -200, -350);
|
||||||
|
@ -109,12 +100,10 @@ const ObjectCollisionBounds PickUpBoundsUW =
|
||||||
GameBoundingBox(
|
GameBoundingBox(
|
||||||
-CLICK(2), CLICK(2),
|
-CLICK(2), CLICK(2),
|
||||||
-CLICK(2), CLICK(2),
|
-CLICK(2), CLICK(2),
|
||||||
-CLICK(2), CLICK(2)
|
-CLICK(2), CLICK(2)),
|
||||||
),
|
|
||||||
std::pair(
|
std::pair(
|
||||||
EulerAngles(ANGLE(-45.0f), ANGLE(-45.0f), ANGLE(-45.0f)),
|
EulerAngles(ANGLE(-45.0f), ANGLE(-45.0f), ANGLE(-45.0f)),
|
||||||
EulerAngles(ANGLE(45.0f), ANGLE(45.0f), ANGLE(45.0f))
|
EulerAngles(ANGLE(45.0f), ANGLE(45.0f), ANGLE(45.0f)))
|
||||||
)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static auto SOPos = Vector3i::Zero;
|
static auto SOPos = Vector3i::Zero;
|
||||||
|
@ -123,8 +112,7 @@ ObjectCollisionBounds SOBounds =
|
||||||
GameBoundingBox::Zero,
|
GameBoundingBox::Zero,
|
||||||
std::pair(
|
std::pair(
|
||||||
EulerAngles(ANGLE(-45.0f), ANGLE(-30.0f), ANGLE(-45.0f)),
|
EulerAngles(ANGLE(-45.0f), ANGLE(-30.0f), ANGLE(-45.0f)),
|
||||||
EulerAngles(ANGLE(45.0f), ANGLE(30.0f), ANGLE(45.0f))
|
EulerAngles(ANGLE(45.0f), ANGLE(30.0f), ANGLE(45.0f)))
|
||||||
)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
short SearchCollectFrames[4] = { 180, 100, 153, 83 };
|
short SearchCollectFrames[4] = { 180, 100, 153, 83 };
|
||||||
|
@ -136,8 +124,7 @@ const ObjectCollisionBounds MSBounds =
|
||||||
GameBoundingBox::Zero,
|
GameBoundingBox::Zero,
|
||||||
std::pair(
|
std::pair(
|
||||||
EulerAngles(ANGLE(-10.0f), ANGLE(-30.0f), ANGLE(-10.0f)),
|
EulerAngles(ANGLE(-10.0f), ANGLE(-30.0f), ANGLE(-10.0f)),
|
||||||
EulerAngles(ANGLE(10.0f), ANGLE(30.0f), ANGLE(10.0f))
|
EulerAngles(ANGLE(10.0f), ANGLE(30.0f), ANGLE(10.0f)))
|
||||||
)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int NumRPickups;
|
int NumRPickups;
|
||||||
|
@ -154,6 +141,7 @@ bool SetInventoryCount(GAME_OBJECT_ID objectID, int count)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -215,7 +203,7 @@ void CollectCarriedItems(ItemInfo* item)
|
||||||
{
|
{
|
||||||
auto* pickupItem = &g_Level.Items[pickupNumber];
|
auto* pickupItem = &g_Level.Items[pickupNumber];
|
||||||
|
|
||||||
AddDisplayPickup(pickupItem->ObjectNumber);
|
g_Hud.PickupSummary.AddDisplayPickup(pickupItem->ObjectNumber, pickupItem->Pose.Position.ToVector3());
|
||||||
KillItem(pickupNumber);
|
KillItem(pickupNumber);
|
||||||
|
|
||||||
pickupNumber = pickupItem->CarriedItem;
|
pickupNumber = pickupItem->CarriedItem;
|
||||||
|
@ -239,7 +227,7 @@ void CollectMultiplePickups(int itemNumber)
|
||||||
if (!Objects[currentItem->ObjectNumber].isPickup)
|
if (!Objects[currentItem->ObjectNumber].isPickup)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
AddDisplayPickup(currentItem->ObjectNumber);
|
g_Hud.PickupSummary.AddDisplayPickup(currentItem->ObjectNumber, currentItem->Pose.Position.ToVector3());
|
||||||
if (currentItem->TriggerFlags & 0x100)
|
if (currentItem->TriggerFlags & 0x100)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < g_Level.NumItems; i++)
|
for (int i = 0; i < g_Level.NumItems; i++)
|
||||||
|
@ -281,7 +269,7 @@ void DoPickup(ItemInfo* laraItem)
|
||||||
|
|
||||||
if (pickupItem->ObjectNumber == ID_BURNING_TORCH_ITEM)
|
if (pickupItem->ObjectNumber == ID_BURNING_TORCH_ITEM)
|
||||||
{
|
{
|
||||||
AddDisplayPickup(ID_BURNING_TORCH_ITEM);
|
g_Hud.PickupSummary.AddDisplayPickup(ID_BURNING_TORCH_ITEM, pickupItem->Pose.Position.ToVector3());
|
||||||
GetFlameTorch();
|
GetFlameTorch();
|
||||||
lara->Torch.IsLit = (pickupItem->ItemFlags[3] & 1);
|
lara->Torch.IsLit = (pickupItem->ItemFlags[3] & 1);
|
||||||
|
|
||||||
|
@ -322,7 +310,7 @@ void DoPickup(ItemInfo* laraItem)
|
||||||
{
|
{
|
||||||
if (laraItem->Animation.AnimNumber == LA_UNDERWATER_PICKUP) //dirty but what can I do, it uses the same state
|
if (laraItem->Animation.AnimNumber == LA_UNDERWATER_PICKUP) //dirty but what can I do, it uses the same state
|
||||||
{
|
{
|
||||||
AddDisplayPickup(pickupItem->ObjectNumber);
|
g_Hud.PickupSummary.AddDisplayPickup(pickupItem->ObjectNumber, pickupItem->Pose.Position.ToVector3());
|
||||||
if (!(pickupItem->TriggerFlags & 0xC0))
|
if (!(pickupItem->TriggerFlags & 0xC0))
|
||||||
KillItem(pickupItemNumber);
|
KillItem(pickupItemNumber);
|
||||||
else
|
else
|
||||||
|
@ -340,7 +328,7 @@ void DoPickup(ItemInfo* laraItem)
|
||||||
{
|
{
|
||||||
if (laraItem->Animation.AnimNumber == LA_CROWBAR_PRY_WALL_SLOW)
|
if (laraItem->Animation.AnimNumber == LA_CROWBAR_PRY_WALL_SLOW)
|
||||||
{
|
{
|
||||||
AddDisplayPickup(ID_CROWBAR_ITEM);
|
g_Hud.PickupSummary.AddDisplayPickup(ID_CROWBAR_ITEM, pickupItem->Pose.Position.ToVector3());
|
||||||
lara->Inventory.HasCrowbar = true;
|
lara->Inventory.HasCrowbar = true;
|
||||||
KillItem(pickupItemNumber);
|
KillItem(pickupItemNumber);
|
||||||
}
|
}
|
||||||
|
@ -355,7 +343,7 @@ void DoPickup(ItemInfo* laraItem)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
AddDisplayPickup(pickupItem->ObjectNumber);
|
g_Hud.PickupSummary.AddDisplayPickup(pickupItem->ObjectNumber, pickupItem->Pose.Position.ToVector3());
|
||||||
if (pickupItem->TriggerFlags & 0x100)
|
if (pickupItem->TriggerFlags & 0x100)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < g_Level.NumItems; i++)
|
for (int i = 0; i < g_Level.NumItems; i++)
|
||||||
|
@ -1249,9 +1237,13 @@ void SearchObjectControl(short itemNumber)
|
||||||
else if (item->ObjectNumber == ID_SEARCH_OBJECT2)
|
else if (item->ObjectNumber == ID_SEARCH_OBJECT2)
|
||||||
{
|
{
|
||||||
if (frameNumber == 18)
|
if (frameNumber == 18)
|
||||||
|
{
|
||||||
item->MeshBits = 1;
|
item->MeshBits = 1;
|
||||||
|
}
|
||||||
else if (frameNumber == 172)
|
else if (frameNumber == 172)
|
||||||
|
{
|
||||||
item->MeshBits = 2;
|
item->MeshBits = 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (item->ObjectNumber == ID_SEARCH_OBJECT4)
|
else if (item->ObjectNumber == ID_SEARCH_OBJECT4)
|
||||||
{
|
{
|
||||||
|
@ -1284,7 +1276,7 @@ void SearchObjectControl(short itemNumber)
|
||||||
|
|
||||||
if (Objects[item2->ObjectNumber].isPickup)
|
if (Objects[item2->ObjectNumber].isPickup)
|
||||||
{
|
{
|
||||||
AddDisplayPickup(item2->ObjectNumber);
|
g_Hud.PickupSummary.AddDisplayPickup(item2->ObjectNumber, item2->Pose.Position.ToVector3());
|
||||||
KillItem(item->ItemFlags[1]);
|
KillItem(item->ItemFlags[1]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1299,7 +1291,9 @@ void SearchObjectControl(short itemNumber)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
CollectCarriedItems(item);
|
CollectCarriedItems(item);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -12,17 +12,6 @@ using namespace TEN::Math;
|
||||||
//{
|
//{
|
||||||
const EulerAngles EulerAngles::Zero = EulerAngles(0, 0, 0);
|
const EulerAngles EulerAngles::Zero = EulerAngles(0, 0, 0);
|
||||||
|
|
||||||
EulerAngles::EulerAngles()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
EulerAngles::EulerAngles(short x, short y, short z)
|
|
||||||
{
|
|
||||||
this->x = x;
|
|
||||||
this->y = y;
|
|
||||||
this->z = z;
|
|
||||||
}
|
|
||||||
|
|
||||||
EulerAngles::EulerAngles(const Vector3& direction)
|
EulerAngles::EulerAngles(const Vector3& direction)
|
||||||
{
|
{
|
||||||
auto directionNorm = direction;
|
auto directionNorm = direction;
|
||||||
|
@ -40,11 +29,11 @@ using namespace TEN::Math;
|
||||||
|
|
||||||
EulerAngles::EulerAngles(const Quaternion& quat)
|
EulerAngles::EulerAngles(const Quaternion& quat)
|
||||||
{
|
{
|
||||||
static constexpr auto singularityThreshold = 1.0f - EPSILON;
|
constexpr auto SINGULARITY_THRESHOLD = 1.0f - EPSILON;
|
||||||
|
|
||||||
// Handle singularity case.
|
// Handle singularity case.
|
||||||
float sinP = ((quat.w * quat.x) - (quat.y * quat.z)) * 2;
|
float sinP = ((quat.w * quat.x) - (quat.y * quat.z)) * 2;
|
||||||
if (abs(sinP) > singularityThreshold)
|
if (abs(sinP) > SINGULARITY_THRESHOLD)
|
||||||
{
|
{
|
||||||
if (sinP > 0.0f)
|
if (sinP > 0.0f)
|
||||||
*this = EulerAngles(FROM_RAD(PI_DIV_2), 0, FROM_RAD(atan2(quat.z, quat.w) * 2.0f));
|
*this = EulerAngles(FROM_RAD(PI_DIV_2), 0, FROM_RAD(atan2(quat.z, quat.w) * 2.0f));
|
||||||
|
|
|
@ -15,12 +15,12 @@
|
||||||
static const EulerAngles Zero; // TODO: Should be "Identity", not "Zero".
|
static const EulerAngles Zero; // TODO: Should be "Identity", not "Zero".
|
||||||
|
|
||||||
// Constructors
|
// Constructors
|
||||||
EulerAngles();
|
constexpr EulerAngles() {};
|
||||||
EulerAngles(short x, short y, short z);
|
constexpr EulerAngles(short x, short y, short z) { this->x = x; this->y = y; this->z = z; };
|
||||||
EulerAngles(const Vector3& direction);
|
EulerAngles(const Vector3& direction);
|
||||||
EulerAngles(const AxisAngle& axisAngle);
|
EulerAngles(const AxisAngle& axisAngle);
|
||||||
EulerAngles(const Quaternion& quat);
|
EulerAngles(const Quaternion& quat);
|
||||||
EulerAngles(const Matrix& rotMatrix);
|
EulerAngles(const Matrix& rotMatrix);
|
||||||
|
|
||||||
// Utilities
|
// Utilities
|
||||||
static bool Compare(const EulerAngles& eulers0, const EulerAngles& eulers1, short epsilon = 2);
|
static bool Compare(const EulerAngles& eulers0, const EulerAngles& eulers1, short epsilon = 2);
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
#include "Game/items.h"
|
#include "Game/items.h"
|
||||||
#include "Math/Objects/EulerAngles.h"
|
#include "Math/Objects/EulerAngles.h"
|
||||||
#include "Math/Objects/Pose.h"
|
#include "Math/Objects/Pose.h"
|
||||||
|
#include "Objects/game_object_ids.h"
|
||||||
|
#include "Specific/setup.h"
|
||||||
|
|
||||||
//namespace TEN::Math
|
//namespace TEN::Math
|
||||||
//{
|
//{
|
||||||
|
@ -24,6 +26,11 @@
|
||||||
this->Z2 = (int)round(z2);
|
this->Z2 = (int)round(z2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GameBoundingBox::GameBoundingBox(GAME_OBJECT_ID objectID, int animNumber, int frameNumber)
|
||||||
|
{
|
||||||
|
*this = GetFrame(objectID, animNumber, frameNumber)->boundingBox;
|
||||||
|
}
|
||||||
|
|
||||||
GameBoundingBox::GameBoundingBox(ItemInfo* item)
|
GameBoundingBox::GameBoundingBox(ItemInfo* item)
|
||||||
{
|
{
|
||||||
int rate = 0;
|
int rate = 0;
|
||||||
|
@ -53,15 +60,14 @@
|
||||||
|
|
||||||
Vector3 GameBoundingBox::GetCenter() const
|
Vector3 GameBoundingBox::GetCenter() const
|
||||||
{
|
{
|
||||||
return ((Vector3(this->X1, this->Y1, this->Z1) + Vector3(this->X2, this->Y2, this->Z2)) / 2.0f);
|
return ((Vector3(X1, Y1, Z1) + Vector3(X2, Y2, Z2)) / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3 GameBoundingBox::GetExtents() const
|
Vector3 GameBoundingBox::GetExtents() const
|
||||||
{
|
{
|
||||||
return ((Vector3(this->X2, this->Y2, this->Z2) - Vector3(this->X1, this->Y1, this->Z1)) / 2.0f);
|
return ((Vector3(X2, Y2, Z2) - Vector3(X1, Y1, Z1)) / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: Previously phd_RotBoundingBoxNoPersp().
|
|
||||||
void GameBoundingBox::RotateNoPersp(const EulerAngles& orient, const GameBoundingBox& bounds)
|
void GameBoundingBox::RotateNoPersp(const EulerAngles& orient, const GameBoundingBox& bounds)
|
||||||
{
|
{
|
||||||
auto rotMatrix = orient.ToRotationMatrix();
|
auto rotMatrix = orient.ToRotationMatrix();
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
enum GAME_OBJECT_ID : short;
|
||||||
class EulerAngles;
|
class EulerAngles;
|
||||||
struct ItemInfo;
|
|
||||||
class Pose;
|
class Pose;
|
||||||
|
struct ItemInfo;
|
||||||
|
struct ObjectInfo;
|
||||||
|
|
||||||
//namespace TEN::Math
|
//namespace TEN::Math
|
||||||
//{
|
//{
|
||||||
|
@ -23,6 +25,7 @@ class Pose;
|
||||||
// Constructors
|
// Constructors
|
||||||
GameBoundingBox();
|
GameBoundingBox();
|
||||||
GameBoundingBox(float x1, float x2, float y1, float y2, float z1, float z2);
|
GameBoundingBox(float x1, float x2, float y1, float y2, float z1, float z2);
|
||||||
|
GameBoundingBox(GAME_OBJECT_ID objectID, int animNumber = 0, int frameNumber = 0);
|
||||||
GameBoundingBox(ItemInfo* item);
|
GameBoundingBox(ItemInfo* item);
|
||||||
|
|
||||||
// Getters
|
// Getters
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#include "Game/items.h"
|
#include "Game/items.h"
|
||||||
#include "Game/pickup/pickup.h"
|
#include "Game/pickup/pickup.h"
|
||||||
#include "Specific/setup.h"
|
#include "Specific/setup.h"
|
||||||
#include "Game/health.h"
|
#include "Game/Hud/Hud.h"
|
||||||
#include "Game/collision/collide_item.h"
|
#include "Game/collision/collide_item.h"
|
||||||
|
|
||||||
using namespace TEN::Input;
|
using namespace TEN::Input;
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
#include "Game/effects/tomb4fx.h"
|
#include "Game/effects/tomb4fx.h"
|
||||||
#include "Game/items.h"
|
#include "Game/items.h"
|
||||||
#include "Game/effects/simple_particle.h"
|
#include "Game/effects/simple_particle.h"
|
||||||
#include "Game/health.h"
|
#include "Game/Hud/Hud.h"
|
||||||
#include "Game/camera.h"
|
#include "Game/camera.h"
|
||||||
#include "Game/animation.h"
|
#include "Game/animation.h"
|
||||||
#include "Math/Random.h"
|
#include "Math/Random.h"
|
||||||
|
|
|
@ -117,7 +117,7 @@ namespace TEN::Renderer
|
||||||
Vector3(x + w, HUD_ZERO_Y + y + h, 0.5),
|
Vector3(x + w, HUD_ZERO_Y + y + h, 0.5),
|
||||||
|
|
||||||
};
|
};
|
||||||
const float HUD_BORDER_WIDTH = borderSize * (REFERENCE_RES_WIDTH / REFERENCE_RES_HEIGHT);
|
const float HUD_BORDER_WIDTH = borderSize * (SCREEN_SPACE_RES.x / SCREEN_SPACE_RES.y);
|
||||||
const float HUD_BORDER_HEIGT = borderSize;
|
const float HUD_BORDER_HEIGT = borderSize;
|
||||||
array<Vector3, 16> barBorderVertices = {
|
array<Vector3, 16> barBorderVertices = {
|
||||||
//top left
|
//top left
|
||||||
|
@ -377,35 +377,35 @@ namespace TEN::Renderer
|
||||||
switch (blendMode)
|
switch (blendMode)
|
||||||
{
|
{
|
||||||
case BLENDMODE_ALPHABLEND:
|
case BLENDMODE_ALPHABLEND:
|
||||||
m_context->OMSetBlendState(m_states->NonPremultiplied(), NULL, 0xFFFFFFFF);
|
m_context->OMSetBlendState(m_states->NonPremultiplied(), nullptr, 0xFFFFFFFF);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BLENDMODE_ALPHATEST:
|
case BLENDMODE_ALPHATEST:
|
||||||
m_context->OMSetBlendState(m_states->Opaque(), NULL, 0xFFFFFFFF);
|
m_context->OMSetBlendState(m_states->Opaque(), nullptr, 0xFFFFFFFF);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BLENDMODE_OPAQUE:
|
case BLENDMODE_OPAQUE:
|
||||||
m_context->OMSetBlendState(m_states->Opaque(), NULL, 0xFFFFFFFF);
|
m_context->OMSetBlendState(m_states->Opaque(), nullptr, 0xFFFFFFFF);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BLENDMODE_SUBTRACTIVE:
|
case BLENDMODE_SUBTRACTIVE:
|
||||||
m_context->OMSetBlendState(m_subtractiveBlendState.Get(), NULL, 0xFFFFFFFF);
|
m_context->OMSetBlendState(m_subtractiveBlendState.Get(), nullptr, 0xFFFFFFFF);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BLENDMODE_ADDITIVE:
|
case BLENDMODE_ADDITIVE:
|
||||||
m_context->OMSetBlendState(m_states->Additive(), NULL, 0xFFFFFFFF);
|
m_context->OMSetBlendState(m_states->Additive(), nullptr, 0xFFFFFFFF);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BLENDMODE_SCREEN:
|
case BLENDMODE_SCREEN:
|
||||||
m_context->OMSetBlendState(m_screenBlendState.Get(), NULL, 0xFFFFFFFF);
|
m_context->OMSetBlendState(m_screenBlendState.Get(), nullptr, 0xFFFFFFFF);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BLENDMODE_LIGHTEN:
|
case BLENDMODE_LIGHTEN:
|
||||||
m_context->OMSetBlendState(m_lightenBlendState.Get(), NULL, 0xFFFFFFFF);
|
m_context->OMSetBlendState(m_lightenBlendState.Get(), nullptr, 0xFFFFFFFF);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BLENDMODE_EXCLUDE:
|
case BLENDMODE_EXCLUDE:
|
||||||
m_context->OMSetBlendState(m_excludeBlendState.Get(), NULL, 0xFFFFFFFF);
|
m_context->OMSetBlendState(m_excludeBlendState.Get(), nullptr, 0xFFFFFFFF);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -426,7 +426,6 @@ namespace TEN::Renderer
|
||||||
default:
|
default:
|
||||||
SetDepthState(DEPTH_STATE_READ_ONLY_ZBUFFER);
|
SetDepthState(DEPTH_STATE_READ_ONLY_ZBUFFER);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,9 @@
|
||||||
|
|
||||||
#include "Game/items.h"
|
#include "Game/items.h"
|
||||||
#include "Game/animation.h"
|
#include "Game/animation.h"
|
||||||
#include "Game/gui.h"
|
#include "Game/Gui.h"
|
||||||
|
#include "Game/Hud/Hud.h"
|
||||||
|
#include "Game/Hud/PickupSummary.h"
|
||||||
#include "Game/effects/effects.h"
|
#include "Game/effects/effects.h"
|
||||||
#include "Game/effects/Electricity.h"
|
#include "Game/effects/Electricity.h"
|
||||||
#include "Specific/level.h"
|
#include "Specific/level.h"
|
||||||
|
@ -53,6 +55,7 @@ struct RendererRectangle;
|
||||||
|
|
||||||
using namespace TEN::Effects::Electricity;
|
using namespace TEN::Effects::Electricity;
|
||||||
using namespace TEN::Gui;
|
using namespace TEN::Gui;
|
||||||
|
using namespace TEN::Hud;
|
||||||
|
|
||||||
namespace TEN::Renderer
|
namespace TEN::Renderer
|
||||||
{
|
{
|
||||||
|
@ -244,8 +247,9 @@ namespace TEN::Renderer
|
||||||
|
|
||||||
struct RendererLine2D
|
struct RendererLine2D
|
||||||
{
|
{
|
||||||
Vector2 Vertices[2];
|
Vector2 Origin = Vector2::Zero;
|
||||||
Vector4 Color;
|
Vector2 Target = Vector2::Zero;
|
||||||
|
Vector4 Color = Vector4::Zero;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RendererRect2D
|
struct RendererRect2D
|
||||||
|
@ -454,9 +458,6 @@ namespace TEN::Renderer
|
||||||
|
|
||||||
// A flag to prevent extra renderer object addition
|
// A flag to prevent extra renderer object addition
|
||||||
bool m_Locked = false;
|
bool m_Locked = false;
|
||||||
|
|
||||||
// Misc
|
|
||||||
int m_pickupRotation = 0;
|
|
||||||
|
|
||||||
// Caching state changes
|
// Caching state changes
|
||||||
TextureBase* lastTexture;
|
TextureBase* lastTexture;
|
||||||
|
@ -655,19 +656,19 @@ namespace TEN::Renderer
|
||||||
void PrintDebugMessage(LPCSTR message, ...);
|
void PrintDebugMessage(LPCSTR message, ...);
|
||||||
void DrawDebugInfo(RenderView& view);
|
void DrawDebugInfo(RenderView& view);
|
||||||
void SwitchDebugPage(bool back);
|
void SwitchDebugPage(bool back);
|
||||||
void DrawPickup(short objectNum);
|
void DrawPickup(const DisplayPickup& pickup);
|
||||||
int Synchronize();
|
int Synchronize();
|
||||||
void AddString(int x, int y, const char* string, D3DCOLOR color, int flags);
|
void AddString(int x, int y, const char* string, D3DCOLOR color, int flags);
|
||||||
|
void AddString(const std::string& string, const Vector2& pos, const Color& color, float scale, int flags);
|
||||||
void FreeRendererData();
|
void FreeRendererData();
|
||||||
void AddDynamicLight(int x, int y, int z, short falloff, byte r, byte g, byte b);
|
void AddDynamicLight(int x, int y, int z, short falloff, byte r, byte g, byte b);
|
||||||
void RenderLoadingScreen(float percentage);
|
void RenderLoadingScreen(float percentage);
|
||||||
void UpdateProgress(float value);
|
void UpdateProgress(float value);
|
||||||
void GetLaraBonePosition(Vector3* pos, int bone);
|
|
||||||
void ToggleFullScreen(bool force = false);
|
void ToggleFullScreen(bool force = false);
|
||||||
void SetFullScreen();
|
void SetFullScreen();
|
||||||
bool IsFullsScreen();
|
bool IsFullsScreen();
|
||||||
void RenderTitleImage();
|
void RenderTitleImage();
|
||||||
void AddLine2D(int x1, int y1, int x2, int y2, byte r, byte g, byte b, byte a);
|
void AddLine2D(const Vector2& origin, const Vector2& target, const Color& color);
|
||||||
void AddLine3D(Vector3 start, Vector3 end, Vector4 color);
|
void AddLine3D(Vector3 start, Vector3 end, Vector4 color);
|
||||||
void AddBox(Vector3 min, Vector3 max, Vector4 color);
|
void AddBox(Vector3 min, Vector3 max, Vector4 color);
|
||||||
void AddBox(Vector3* corners, Vector4 color);
|
void AddBox(Vector3* corners, Vector4 color);
|
||||||
|
@ -679,13 +680,16 @@ namespace TEN::Renderer
|
||||||
void FlipRooms(short roomNumber1, short roomNumber2);
|
void FlipRooms(short roomNumber1, short roomNumber2);
|
||||||
void UpdateLaraAnimations(bool force);
|
void UpdateLaraAnimations(bool force);
|
||||||
void UpdateItemAnimations(int itemNumber, bool force);
|
void UpdateItemAnimations(int itemNumber, bool force);
|
||||||
void GetItemAbsBonePosition(int itemNumber, Vector3& pos, int jointIndex);
|
|
||||||
int GetSpheres(short itemNumber, BoundingSphere* ptr, char worldSpace, Matrix local);
|
int GetSpheres(short itemNumber, BoundingSphere* ptr, char worldSpace, Matrix local);
|
||||||
void GetBoneMatrix(short itemNumber, int jointIndex, Matrix* outMatrix);
|
void GetBoneMatrix(short itemNumber, int jointIndex, Matrix* outMatrix);
|
||||||
void DrawObjectOn2DPosition(short x, short y, short objectNum, EulerAngles orient, float scale1, int meshBits = NO_JOINT_BITS);
|
void DrawObjectOn2DPosition(int objectNumber, Vector2 pos, EulerAngles orient, float scale1, float opacity = 1.0f, int meshBits = NO_JOINT_BITS);
|
||||||
void SetLoadingScreen(std::wstring& fileName);
|
void SetLoadingScreen(std::wstring& fileName);
|
||||||
void SetTextureOrDefault(Texture2D& texture, std::wstring path);
|
void SetTextureOrDefault(Texture2D& texture, std::wstring path);
|
||||||
std::string GetDefaultAdapterName();
|
std::string GetDefaultAdapterName();
|
||||||
|
|
||||||
|
Vector2i GetScreenResolution() const;
|
||||||
|
Vector2 GetScreenSpacePosition(const Vector3& pos) const;
|
||||||
|
Vector3 GetAbsEntityBonePosition(int itemNumber, int jointIndex, const Vector3& relOffset = Vector3::Zero);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Renderer11 g_Renderer;
|
extern Renderer11 g_Renderer;
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
#include "Game/effects/tomb4fx.h"
|
#include "Game/effects/tomb4fx.h"
|
||||||
#include "Game/effects/weather.h"
|
#include "Game/effects/weather.h"
|
||||||
#include "Game/Gui.h"
|
#include "Game/Gui.h"
|
||||||
#include "Game/health.h"
|
#include "Game/Hud/Hud.h"
|
||||||
#include "Game/items.h"
|
#include "Game/items.h"
|
||||||
#include "Game/Lara/lara.h"
|
#include "Game/Lara/lara.h"
|
||||||
#include "Game/savegame.h"
|
#include "Game/savegame.h"
|
||||||
|
@ -31,6 +31,7 @@
|
||||||
#include "Specific/winmain.h"
|
#include "Specific/winmain.h"
|
||||||
|
|
||||||
using namespace TEN::Entities::Generic;
|
using namespace TEN::Entities::Generic;
|
||||||
|
using namespace TEN::Hud;
|
||||||
|
|
||||||
extern TEN::Renderer::RendererHUDBar* g_HealthBar;
|
extern TEN::Renderer::RendererHUDBar* g_HealthBar;
|
||||||
extern TEN::Renderer::RendererHUDBar* g_AirBar;
|
extern TEN::Renderer::RendererHUDBar* g_AirBar;
|
||||||
|
@ -355,38 +356,29 @@ namespace TEN::Renderer
|
||||||
|
|
||||||
m_context->VSSetShader(m_vsSolid.Get(), nullptr, 0);
|
m_context->VSSetShader(m_vsSolid.Get(), nullptr, 0);
|
||||||
m_context->PSSetShader(m_psSolid.Get(), nullptr, 0);
|
m_context->PSSetShader(m_psSolid.Get(), nullptr, 0);
|
||||||
Matrix world = Matrix::CreateOrthographicOffCenter(0, m_screenWidth, m_screenHeight, 0, m_viewport.MinDepth,
|
auto worldMatrix = Matrix::CreateOrthographicOffCenter(0, m_screenWidth, m_screenHeight, 0, m_viewport.MinDepth, m_viewport.MaxDepth);
|
||||||
m_viewport.MaxDepth);
|
|
||||||
|
|
||||||
m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST);
|
m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST);
|
||||||
m_context->IASetInputLayout(m_inputLayout.Get());
|
m_context->IASetInputLayout(m_inputLayout.Get());
|
||||||
|
|
||||||
m_primitiveBatch->Begin();
|
m_primitiveBatch->Begin();
|
||||||
|
|
||||||
for (int i = 0; i < m_lines2DToDraw.size(); i++)
|
for (const auto& line : m_lines2DToDraw)
|
||||||
{
|
{
|
||||||
RendererLine2D* line = &m_lines2DToDraw[i];
|
auto v1 = RendererVertex();
|
||||||
|
v1.Position.x = line.Origin.x;
|
||||||
RendererVertex v1;
|
v1.Position.y = line.Origin.y;
|
||||||
v1.Position.x = line->Vertices[0].x;
|
|
||||||
v1.Position.y = line->Vertices[0].y;
|
|
||||||
v1.Position.z = 1.0f;
|
v1.Position.z = 1.0f;
|
||||||
v1.Color.x = line->Color.x / 255.0f;
|
v1.Color = line.Color;
|
||||||
v1.Color.y = line->Color.y / 255.0f;
|
|
||||||
v1.Color.z = line->Color.z / 255.0f;
|
|
||||||
v1.Color.w = line->Color.w / 255.0f;
|
|
||||||
|
|
||||||
RendererVertex v2;
|
auto v2 = RendererVertex();
|
||||||
v2.Position.x = line->Vertices[1].x;
|
v2.Position.x = line.Target.x;
|
||||||
v2.Position.y = line->Vertices[1].y;
|
v2.Position.y = line.Target.y;
|
||||||
v2.Position.z = 1.0f;
|
v2.Position.z = 1.0f;
|
||||||
v2.Color.x = line->Color.x / 255.0f;
|
v2.Color = line.Color;
|
||||||
v2.Color.y = line->Color.y / 255.0f;
|
|
||||||
v2.Color.z = line->Color.z / 255.0f;
|
|
||||||
v2.Color.w = line->Color.w / 255.0f;
|
|
||||||
|
|
||||||
v1.Position = Vector3::Transform(v1.Position, world);
|
v1.Position = Vector3::Transform(v1.Position, worldMatrix);
|
||||||
v2.Position = Vector3::Transform(v2.Position, world);
|
v2.Position = Vector3::Transform(v2.Position, worldMatrix);
|
||||||
|
|
||||||
v1.Position.z = 0.5f;
|
v1.Position.z = 0.5f;
|
||||||
v2.Position.z = 0.5f;
|
v2.Position.z = 0.5f;
|
||||||
|
@ -1494,8 +1486,9 @@ namespace TEN::Renderer
|
||||||
// Draw GUI stuff at the end
|
// Draw GUI stuff at the end
|
||||||
DrawLines2D();
|
DrawLines2D();
|
||||||
|
|
||||||
// Bars
|
// Draw HUD.
|
||||||
DrawHUD(LaraItem);
|
g_Hud.Draw();
|
||||||
|
DrawHud(LaraItem);
|
||||||
|
|
||||||
// Draw binoculars or lasersight
|
// Draw binoculars or lasersight
|
||||||
DrawOverlays(view);
|
DrawOverlays(view);
|
||||||
|
|
|
@ -74,7 +74,7 @@ namespace TEN::Renderer
|
||||||
g_LoadingBar = new RendererHUDBar(m_device.Get(), 325, 550, 150, 8, 1, airColors);
|
g_LoadingBar = new RendererHUDBar(m_device.Get(), 325, 550, 150, 8, 1, airColors);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer11::DrawBar(float percent, const RendererHUDBar* const bar, GAME_OBJECT_ID textureSlot, int frame, bool poison)
|
void Renderer11::DrawBar(float percent, const RendererHUDBar* const bar, GAME_OBJECT_ID textureSlot, int frame, bool isPoisoned)
|
||||||
{
|
{
|
||||||
UINT strides = sizeof(RendererVertex);
|
UINT strides = sizeof(RendererVertex);
|
||||||
UINT offset = 0;
|
UINT offset = 0;
|
||||||
|
@ -87,8 +87,8 @@ namespace TEN::Renderer
|
||||||
m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||||
m_context->IASetIndexBuffer(bar->IndexBufferBorder.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
|
m_context->IASetIndexBuffer(bar->IndexBufferBorder.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
|
||||||
|
|
||||||
m_context->VSSetShader(m_vsHUD.Get(), NULL, 0);
|
m_context->VSSetShader(m_vsHUD.Get(), nullptr, 0);
|
||||||
m_context->PSSetShader(m_psHUDTexture.Get(), NULL, 0);
|
m_context->PSSetShader(m_psHUDTexture.Get(), nullptr, 0);
|
||||||
|
|
||||||
SetBlendMode(BLENDMODE_OPAQUE);
|
SetBlendMode(BLENDMODE_OPAQUE);
|
||||||
SetDepthState(DEPTH_STATE_NONE);
|
SetDepthState(DEPTH_STATE_NONE);
|
||||||
|
@ -108,11 +108,11 @@ namespace TEN::Renderer
|
||||||
m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||||
m_context->IASetIndexBuffer(bar->InnerIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
|
m_context->IASetIndexBuffer(bar->InnerIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
|
||||||
|
|
||||||
m_context->VSSetShader(m_vsHUD.Get(), NULL, 0);
|
m_context->VSSetShader(m_vsHUD.Get(), nullptr, 0);
|
||||||
m_context->PSSetShader(m_psHUDBarColor.Get(), NULL, 0);
|
m_context->PSSetShader(m_psHUDBarColor.Get(), nullptr, 0);
|
||||||
|
|
||||||
m_stHUDBar.Percent = percent;
|
m_stHUDBar.Percent = percent;
|
||||||
m_stHUDBar.Poisoned = poison;
|
m_stHUDBar.Poisoned = isPoisoned;
|
||||||
m_stHUDBar.Frame = frame;
|
m_stHUDBar.Frame = frame;
|
||||||
m_cbHUDBar.updateData(m_stHUDBar, m_context.Get());
|
m_cbHUDBar.updateData(m_stHUDBar, m_context.Get());
|
||||||
BindConstantBufferVS(CB_HUD_BAR, m_cbHUDBar.get());
|
BindConstantBufferVS(CB_HUD_BAR, m_cbHUDBar.get());
|
||||||
|
@ -170,13 +170,9 @@ namespace TEN::Renderer
|
||||||
DrawIndexedTriangles(12, 0, 0);
|
DrawIndexedTriangles(12, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer11::AddLine2D(int x1, int y1, int x2, int y2, byte r, byte g, byte b, byte a) {
|
void Renderer11::AddLine2D(const Vector2& origin, const Vector2& target, const Color& color)
|
||||||
RendererLine2D line;
|
{
|
||||||
|
auto line = RendererLine2D{ origin, target, color };
|
||||||
line.Vertices[0] = Vector2(x1, y1);
|
|
||||||
line.Vertices[1] = Vector2(x2, y2);
|
|
||||||
line.Color = Vector4(r, g, b, a);
|
|
||||||
|
|
||||||
m_lines2DToDraw.push_back(line);
|
m_lines2DToDraw.push_back(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#include "Game/control/control.h"
|
#include "Game/control/control.h"
|
||||||
#include "Game/control/volume.h"
|
#include "Game/control/volume.h"
|
||||||
#include "Game/Gui.h"
|
#include "Game/Gui.h"
|
||||||
#include "Game/health.h"
|
#include "Game/Hud/Hud.h"
|
||||||
#include "Game/Lara/lara.h"
|
#include "Game/Lara/lara.h"
|
||||||
#include "Game/savegame.h"
|
#include "Game/savegame.h"
|
||||||
#include "Math/Math.h"
|
#include "Math/Math.h"
|
||||||
|
@ -16,6 +16,7 @@
|
||||||
#include "Specific/trutils.h"
|
#include "Specific/trutils.h"
|
||||||
#include "Specific/winmain.h"
|
#include "Specific/winmain.h"
|
||||||
|
|
||||||
|
using namespace TEN::Hud;
|
||||||
using namespace TEN::Input;
|
using namespace TEN::Input;
|
||||||
using namespace TEN::Math;
|
using namespace TEN::Math;
|
||||||
|
|
||||||
|
@ -505,61 +506,67 @@ namespace TEN::Renderer
|
||||||
DrawAllStrings();
|
DrawAllStrings();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer11::DrawPickup(short objectNum)
|
void Renderer11::DrawPickup(const DisplayPickup& pickup)
|
||||||
{
|
{
|
||||||
// Clear just the Z-buffer so we can start drawing on top of the scene
|
static const auto COUNT_STRING_PREFIX = std::string(" ");
|
||||||
|
|
||||||
|
// Clear only Z-buffer to draw on top of the scene.
|
||||||
ID3D11DepthStencilView* dsv;
|
ID3D11DepthStencilView* dsv;
|
||||||
m_context->OMGetRenderTargets(1, nullptr, &dsv);
|
m_context->OMGetRenderTargets(1, nullptr, &dsv);
|
||||||
m_context->ClearDepthStencilView(dsv, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
|
m_context->ClearDepthStencilView(dsv, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
|
||||||
|
|
||||||
DrawObjectOn2DPosition(700 + PickupX, 450, objectNum, EulerAngles(0, m_pickupRotation, 0), 0.5f); // TODO: + PickupY
|
// Draw display pickup.
|
||||||
m_pickupRotation += 45 * 360 / 30;
|
DrawObjectOn2DPosition(pickup.ObjectID, pickup.Position, pickup.Orientation, pickup.Scale);
|
||||||
|
|
||||||
|
// Draw count string.
|
||||||
|
if (pickup.Count > 1)
|
||||||
|
{
|
||||||
|
AddString(
|
||||||
|
COUNT_STRING_PREFIX + std::to_string(pickup.Count),
|
||||||
|
pickup.Position, Color(PRINTSTRING_COLOR_WHITE), pickup.StringScale, SF());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer11::DrawObjectOn2DPosition(short x, short y, short objectNum, EulerAngles orient, float scale1, int meshBits)
|
// TODO: Handle opacity
|
||||||
|
void Renderer11::DrawObjectOn2DPosition(int objectNumber, Vector2 screenPos, EulerAngles orient, float scale, float opacity, int meshBits)
|
||||||
{
|
{
|
||||||
Matrix translation;
|
constexpr auto AMBIENT_LIGHT_COLOR = Vector4(0.5f, 0.5f, 0.5f, 1.0f);
|
||||||
Matrix rotation;
|
|
||||||
Matrix world;
|
|
||||||
Matrix view;
|
|
||||||
Matrix projection;
|
|
||||||
Matrix scale;
|
|
||||||
|
|
||||||
UINT stride = sizeof(RendererVertex);
|
UINT stride = sizeof(RendererVertex);
|
||||||
UINT offset = 0;
|
UINT offset = 0;
|
||||||
|
|
||||||
float factorX = m_screenWidth / REFERENCE_RES_WIDTH;
|
auto screenRes = GetScreenResolution();
|
||||||
float factorY = m_screenHeight / REFERENCE_RES_HEIGHT;
|
auto factor = Vector2(
|
||||||
|
screenRes.x / SCREEN_SPACE_RES.x,
|
||||||
|
screenRes.y / SCREEN_SPACE_RES.y);
|
||||||
|
|
||||||
x *= factorX;
|
screenPos *= factor;
|
||||||
y *= factorY;
|
scale *= (factor.x > factor.y) ? factor.y : factor.x;
|
||||||
scale1 *= factorX > factorY ? factorY : factorX;
|
|
||||||
|
|
||||||
auto index = g_Gui.ConvertObjectToInventoryItem(objectNum);
|
|
||||||
|
|
||||||
|
int index = g_Gui.ConvertObjectToInventoryItem(objectNumber);
|
||||||
if (index != -1)
|
if (index != -1)
|
||||||
{
|
{
|
||||||
auto& invObject = InventoryObjectTable[index];
|
const auto& invObject = InventoryObjectTable[index];
|
||||||
y += invObject.YOffset;
|
|
||||||
|
screenPos.y += invObject.YOffset;
|
||||||
orient += invObject.Orientation;
|
orient += invObject.Orientation;
|
||||||
}
|
}
|
||||||
|
|
||||||
view = Matrix::CreateLookAt(Vector3(0.0f, 0.0f, 2048.0f), Vector3(0.0f, 0.0f, 0.0f), Vector3(0.0f, -1.0f, 0.0f));
|
auto viewMatrix = Matrix::CreateLookAt(Vector3(0.0f, 0.0f, BLOCK(2)), Vector3::Zero, Vector3::Down);
|
||||||
projection = Matrix::CreateOrthographic(m_screenWidth, m_screenHeight, -1024.0f, 1024.0f);
|
auto projMatrix = Matrix::CreateOrthographic(m_screenWidth, m_screenHeight, -BLOCK(1), BLOCK(1));
|
||||||
|
|
||||||
auto& moveableObj = m_moveableObjects[objectNum];
|
auto& moveableObject = m_moveableObjects[objectNumber];
|
||||||
if (!moveableObj)
|
if (!moveableObject)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto* obj = &Objects[objectNum];
|
const auto& object = Objects[objectNumber];
|
||||||
|
if (object.animIndex != -1)
|
||||||
if (obj->animIndex != -1)
|
|
||||||
{
|
{
|
||||||
AnimFrame* frame[] = { &g_Level.Frames[g_Level.Anims[obj->animIndex].FramePtr] };
|
AnimFrame* frame[] = { &g_Level.Frames[g_Level.Anims[object.animIndex].FramePtr] };
|
||||||
UpdateAnimation(nullptr, *moveableObj, frame, 0, 0, 0xFFFFFFFF);
|
UpdateAnimation(nullptr, *moveableObject, frame, 0, 0, 0xFFFFFFFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto pos = m_viewportToolkit.Unproject(Vector3(x, y, 1), projection, view, Matrix::Identity);
|
auto pos = m_viewportToolkit.Unproject(Vector3(screenPos.x, screenPos.y, 1.0f), projMatrix, viewMatrix, Matrix::Identity);
|
||||||
|
|
||||||
// Set vertex buffer.
|
// Set vertex buffer.
|
||||||
m_context->IASetVertexBuffers(0, 1, m_moveablesVertexBuffer.Buffer.GetAddressOf(), &stride, &offset);
|
m_context->IASetVertexBuffers(0, 1, m_moveablesVertexBuffer.Buffer.GetAddressOf(), &stride, &offset);
|
||||||
|
@ -572,41 +579,39 @@ namespace TEN::Renderer
|
||||||
m_context->PSSetShader(m_psInventory.Get(), nullptr, 0);
|
m_context->PSSetShader(m_psInventory.Get(), nullptr, 0);
|
||||||
|
|
||||||
// Set matrices.
|
// Set matrices.
|
||||||
CCameraMatrixBuffer HudCamera;
|
CCameraMatrixBuffer hudCamera;
|
||||||
HudCamera.CamDirectionWS = -Vector4::UnitZ;
|
hudCamera.CamDirectionWS = -Vector4::UnitZ;
|
||||||
HudCamera.ViewProjection = view * projection;
|
hudCamera.ViewProjection = viewMatrix * projMatrix;
|
||||||
m_cbCameraMatrices.updateData(HudCamera, m_context.Get());
|
m_cbCameraMatrices.updateData(hudCamera, m_context.Get());
|
||||||
BindConstantBufferVS(CB_CAMERA, m_cbCameraMatrices.get());
|
BindConstantBufferVS(CB_CAMERA, m_cbCameraMatrices.get());
|
||||||
|
|
||||||
for (int n = 0; n < (*moveableObj).ObjectMeshes.size(); n++)
|
for (int n = 0; n < (*moveableObject).ObjectMeshes.size(); n++)
|
||||||
{
|
{
|
||||||
if (meshBits && !(meshBits & (1 << n)))
|
if (meshBits && !(meshBits & (1 << n)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
auto* mesh = (*moveableObject).ObjectMeshes[n];
|
||||||
|
|
||||||
auto* mesh = (*moveableObj).ObjectMeshes[n];
|
// Construct world matrix.
|
||||||
|
auto tMatrix = Matrix::CreateTranslation(pos.x, pos.y, pos.z + BLOCK(1));
|
||||||
|
auto rotMatrix = orient.ToRotationMatrix();
|
||||||
|
auto scaleMatrix = Matrix::CreateScale(scale);
|
||||||
|
auto worldMatrix = scaleMatrix * rotMatrix * tMatrix;
|
||||||
|
|
||||||
// Finish the world matrix
|
if (object.animIndex != -1)
|
||||||
translation = Matrix::CreateTranslation(pos.x, pos.y, pos.z + 1024.0f);
|
m_stItem.World = (*moveableObject).AnimationTransforms[n] * worldMatrix;
|
||||||
rotation = orient.ToRotationMatrix();
|
|
||||||
scale = Matrix::CreateScale(scale1);
|
|
||||||
|
|
||||||
world = scale * rotation;
|
|
||||||
world = world * translation;
|
|
||||||
|
|
||||||
if (obj->animIndex != -1)
|
|
||||||
m_stItem.World = ((*moveableObj).AnimationTransforms[n] * world);
|
|
||||||
else
|
else
|
||||||
m_stItem.World = ((*moveableObj).BindPoseTransforms[n] * world);
|
m_stItem.World = (*moveableObject).BindPoseTransforms[n] * worldMatrix;
|
||||||
|
|
||||||
m_stItem.BoneLightModes[n] = LIGHT_MODES::LIGHT_MODE_DYNAMIC;
|
m_stItem.BoneLightModes[n] = LIGHT_MODES::LIGHT_MODE_DYNAMIC;
|
||||||
m_stItem.Color = Vector4::One;
|
m_stItem.Color = Vector4::One;
|
||||||
m_stItem.AmbientLight = Vector4(0.5f, 0.5f, 0.5f, 1.0f);
|
m_stItem.AmbientLight = AMBIENT_LIGHT_COLOR;
|
||||||
|
|
||||||
m_cbItem.updateData(m_stItem, m_context.Get());
|
m_cbItem.updateData(m_stItem, m_context.Get());
|
||||||
BindConstantBufferVS(CB_ITEM, m_cbItem.get());
|
BindConstantBufferVS(CB_ITEM, m_cbItem.get());
|
||||||
BindConstantBufferPS(CB_ITEM, m_cbItem.get());
|
BindConstantBufferPS(CB_ITEM, m_cbItem.get());
|
||||||
|
|
||||||
for (auto& bucket : mesh->Buckets)
|
for (const auto& bucket : mesh->Buckets)
|
||||||
{
|
{
|
||||||
if (bucket.NumVertices == 0)
|
if (bucket.NumVertices == 0)
|
||||||
continue;
|
continue;
|
||||||
|
@ -619,12 +624,10 @@ namespace TEN::Renderer
|
||||||
BindTexture(TEXTURE_NORMAL_MAP, &std::get<1>(m_moveablesTextures[bucket.Texture]), SAMPLER_NONE);
|
BindTexture(TEXTURE_NORMAL_MAP, &std::get<1>(m_moveablesTextures[bucket.Texture]), SAMPLER_NONE);
|
||||||
|
|
||||||
SetAlphaTest(
|
SetAlphaTest(
|
||||||
bucket.BlendMode == BLENDMODE_ALPHATEST ? ALPHA_TEST_GREATER_THAN : ALPHA_TEST_NONE,
|
(bucket.BlendMode == BLENDMODE_ALPHATEST) ? ALPHA_TEST_GREATER_THAN : ALPHA_TEST_NONE,
|
||||||
ALPHA_TEST_THRESHOLD
|
ALPHA_TEST_THRESHOLD);
|
||||||
);
|
|
||||||
|
|
||||||
DrawIndexedTriangles(bucket.NumIndices, bucket.StartIndex, 0);
|
DrawIndexedTriangles(bucket.NumIndices, bucket.StartIndex, 0);
|
||||||
|
|
||||||
m_numMoveablesDrawCalls++;
|
m_numMoveablesDrawCalls++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -633,7 +636,7 @@ namespace TEN::Renderer
|
||||||
void Renderer11::RenderTitleImage()
|
void Renderer11::RenderTitleImage()
|
||||||
{
|
{
|
||||||
Texture2D texture;
|
Texture2D texture;
|
||||||
SetTextureOrDefault(texture, TEN::Utils::FromChar(g_GameFlow->IntroImagePath.c_str()));
|
SetTextureOrDefault(texture, TEN::Utils::ToWString(g_GameFlow->IntroImagePath.c_str()));
|
||||||
|
|
||||||
if (!texture.Texture)
|
if (!texture.Texture)
|
||||||
return;
|
return;
|
||||||
|
@ -651,7 +654,9 @@ namespace TEN::Renderer
|
||||||
timeout--;
|
timeout--;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
currentFade = std::clamp(currentFade -= FADE_FACTOR, 0.0f, 1.0f);
|
currentFade = std::clamp(currentFade -= FADE_FACTOR, 0.0f, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
DrawFullScreenImage(texture.ShaderResourceView.Get(), Smoothstep(currentFade), m_backBufferRTV, m_depthStencilView);
|
DrawFullScreenImage(texture.ShaderResourceView.Get(), Smoothstep(currentFade), m_backBufferRTV, m_depthStencilView);
|
||||||
Synchronize();
|
Synchronize();
|
||||||
|
@ -662,6 +667,8 @@ namespace TEN::Renderer
|
||||||
|
|
||||||
void Renderer11::DrawExamines()
|
void Renderer11::DrawExamines()
|
||||||
{
|
{
|
||||||
|
constexpr auto SCREEN_POS = Vector2(400.0f, 300.0f);
|
||||||
|
|
||||||
static EulerAngles orient = EulerAngles::Zero;
|
static EulerAngles orient = EulerAngles::Zero;
|
||||||
static float scaler = 1.2f;
|
static float scaler = 1.2f;
|
||||||
|
|
||||||
|
@ -695,23 +702,26 @@ namespace TEN::Renderer
|
||||||
|
|
||||||
float savedScale = object.Scale1;
|
float savedScale = object.Scale1;
|
||||||
object.Scale1 = scaler;
|
object.Scale1 = scaler;
|
||||||
DrawObjectOn2DPosition(400, 300, g_Gui.ConvertInventoryItemToObject(invItem), orient, object.Scale1);
|
DrawObjectOn2DPosition(g_Gui.ConvertInventoryItemToObject(invItem), SCREEN_POS, orient, object.Scale1);
|
||||||
object.Scale1 = savedScale;
|
object.Scale1 = savedScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer11::DrawDiary()
|
void Renderer11::DrawDiary()
|
||||||
{
|
{
|
||||||
unsigned int currentPage = Lara.Inventory.Diary.CurrentPage;
|
constexpr auto SCREEN_POS = Vector2(400.0f, 300.0f);
|
||||||
|
|
||||||
const auto& object = InventoryObjectTable[INV_OBJECT_OPEN_DIARY];
|
const auto& object = InventoryObjectTable[INV_OBJECT_OPEN_DIARY];
|
||||||
|
unsigned int currentPage = Lara.Inventory.Diary.CurrentPage;
|
||||||
|
|
||||||
DrawObjectOn2DPosition(400, 300, g_Gui.ConvertInventoryItemToObject(INV_OBJECT_OPEN_DIARY), object.Orientation, object.Scale1);
|
DrawObjectOn2DPosition(g_Gui.ConvertInventoryItemToObject(INV_OBJECT_OPEN_DIARY), SCREEN_POS, object.Orientation, object.Scale1);
|
||||||
|
|
||||||
for (size_t i = 0; i < MAX_DIARY_STRINGS_PER_PAGE; i++)
|
for (int i = 0; i < MAX_DIARY_STRINGS_PER_PAGE; i++)
|
||||||
{
|
{
|
||||||
if (!Lara.Inventory.Diary.Pages[Lara.Inventory.Diary.CurrentPage].Strings[i].Position.x && !Lara.Inventory.Diary.Pages[Lara.Inventory.Diary.CurrentPage].
|
if (!Lara.Inventory.Diary.Pages[Lara.Inventory.Diary.CurrentPage].Strings[i].Position.x && !Lara.Inventory.Diary.Pages[Lara.Inventory.Diary.CurrentPage].
|
||||||
Strings[i].Position.y && !Lara.Inventory.Diary.Pages[Lara.Inventory.Diary.CurrentPage].Strings[i].StringID)
|
Strings[i].Position.y && !Lara.Inventory.Diary.Pages[Lara.Inventory.Diary.CurrentPage].Strings[i].StringID)
|
||||||
|
{
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
//AddString(Lara.Diary.Pages[currentPage].Strings[i].x, Lara.Diary.Pages[currentPage].Strings[i].y, g_GameFlow->GetString(Lara.Diary.Pages[currentPage].Strings[i].stringID), PRINTSTRING_COLOR_WHITE, 0);
|
//AddString(Lara.Diary.Pages[currentPage].Strings[i].x, Lara.Diary.Pages[currentPage].Strings[i].y, g_GameFlow->GetString(Lara.Diary.Pages[currentPage].Strings[i].stringID), PRINTSTRING_COLOR_WHITE, 0);
|
||||||
}
|
}
|
||||||
|
@ -719,8 +729,7 @@ namespace TEN::Renderer
|
||||||
DrawAllStrings();
|
DrawAllStrings();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer11::RenderInventoryScene(ID3D11RenderTargetView* target, ID3D11DepthStencilView* depthTarget,
|
void Renderer11::RenderInventoryScene(ID3D11RenderTargetView* target, ID3D11DepthStencilView* depthTarget, ID3D11ShaderResourceView* background)
|
||||||
ID3D11ShaderResourceView* background)
|
|
||||||
{
|
{
|
||||||
// Set basic render states
|
// Set basic render states
|
||||||
SetBlendMode(BLENDMODE_OPAQUE, true);
|
SetBlendMode(BLENDMODE_OPAQUE, true);
|
||||||
|
@ -761,12 +770,12 @@ namespace TEN::Renderer
|
||||||
|
|
||||||
if (drawLogo)
|
if (drawLogo)
|
||||||
{
|
{
|
||||||
float factorX = (float)m_screenWidth / REFERENCE_RES_WIDTH;
|
float factorX = (float)m_screenWidth / SCREEN_SPACE_RES.x;
|
||||||
float factorY = (float)m_screenHeight / REFERENCE_RES_HEIGHT;
|
float factorY = (float)m_screenHeight / SCREEN_SPACE_RES.y;
|
||||||
float scale = m_screenWidth > m_screenHeight ? factorX : factorY;
|
float scale = m_screenWidth > m_screenHeight ? factorX : factorY;
|
||||||
|
|
||||||
int logoLeft = (REFERENCE_RES_WIDTH / 2) - (LogoWidth / 2);
|
int logoLeft = (SCREEN_SPACE_RES.x / 2) - (LogoWidth / 2);
|
||||||
int logoRight = (REFERENCE_RES_WIDTH / 2) + (LogoWidth / 2);
|
int logoRight = (SCREEN_SPACE_RES.x / 2) + (LogoWidth / 2);
|
||||||
int logoBottom = LogoTop + LogoHeight;
|
int logoBottom = LogoTop + LogoHeight;
|
||||||
|
|
||||||
RECT rect;
|
RECT rect;
|
||||||
|
@ -919,13 +928,11 @@ namespace TEN::Renderer
|
||||||
case RENDERER_DEBUG_PAGE::DIMENSION_STATS:
|
case RENDERER_DEBUG_PAGE::DIMENSION_STATS:
|
||||||
PrintDebugMessage("Lara Location: %d %d", LaraItem->Location.roomNumber, LaraItem->Location.yNumber);
|
PrintDebugMessage("Lara Location: %d %d", LaraItem->Location.roomNumber, LaraItem->Location.yNumber);
|
||||||
PrintDebugMessage("Lara RoomNumber: %d", LaraItem->RoomNumber);
|
PrintDebugMessage("Lara RoomNumber: %d", LaraItem->RoomNumber);
|
||||||
PrintDebugMessage("LaraItem BoxNumber: %d",/* canJump: %d, canLongJump: %d, canMonkey: %d,*/
|
PrintDebugMessage("LaraItem BoxNumber: %d",/* canJump: %d, canLongJump: %d, canMonkey: %d,*/ LaraItem->BoxNumber);
|
||||||
LaraItem->BoxNumber);
|
|
||||||
PrintDebugMessage("Lara Pos: %d %d %d", LaraItem->Pose.Position.x, LaraItem->Pose.Position.y, LaraItem->Pose.Position.z);
|
PrintDebugMessage("Lara Pos: %d %d %d", LaraItem->Pose.Position.x, LaraItem->Pose.Position.y, LaraItem->Pose.Position.z);
|
||||||
PrintDebugMessage("Lara Rot: %d %d %d", LaraItem->Pose.Orientation.x, LaraItem->Pose.Orientation.y, LaraItem->Pose.Orientation.z);
|
PrintDebugMessage("Lara Rot: %d %d %d", LaraItem->Pose.Orientation.x, LaraItem->Pose.Orientation.y, LaraItem->Pose.Orientation.z);
|
||||||
PrintDebugMessage("Lara WaterSurfaceDist: %d", Lara.WaterSurfaceDist);
|
PrintDebugMessage("Lara WaterSurfaceDist: %d", Lara.WaterSurfaceDist);
|
||||||
PrintDebugMessage("Room: %d %d %d %d", r->x, r->z, r->x + r->xSize * SECTOR(1),
|
PrintDebugMessage("Room: %d %d %d %d", r->x, r->z, r->x + r->xSize * SECTOR(1), r->z + r->zSize * SECTOR(1));
|
||||||
r->z + r->zSize * SECTOR(1));
|
|
||||||
PrintDebugMessage("Room.y, minFloor, maxCeiling: %d %d %d ", r->y, r->minfloor, r->maxceiling);
|
PrintDebugMessage("Room.y, minFloor, maxCeiling: %d %d %d ", r->y, r->minfloor, r->maxceiling);
|
||||||
PrintDebugMessage("Camera.pos: %d %d %d", Camera.pos.x, Camera.pos.y, Camera.pos.z);
|
PrintDebugMessage("Camera.pos: %d %d %d", Camera.pos.x, Camera.pos.y, Camera.pos.z);
|
||||||
PrintDebugMessage("Camera.target: %d %d %d", Camera.target.x, Camera.target.y, Camera.target.z);
|
PrintDebugMessage("Camera.target: %d %d %d", Camera.target.x, Camera.target.y, Camera.target.z);
|
||||||
|
|
|
@ -240,12 +240,12 @@ constexpr auto FAST_ALPHA_BLEND_THRESHOLD = 0.5f;
|
||||||
|
|
||||||
constexpr auto MAX_BONES = 32;
|
constexpr auto MAX_BONES = 32;
|
||||||
|
|
||||||
constexpr auto REFERENCE_FONT_SIZE = 35.0f;
|
constexpr auto SCREEN_SPACE_RES = Vector2(800.0f, 600.0f);
|
||||||
constexpr auto REFERENCE_RES_WIDTH = 800.0f;
|
constexpr auto INVALID_SCREEN_SPACE_POSITION = Vector2(FLT_MAX, FLT_MAX);
|
||||||
constexpr auto REFERENCE_RES_HEIGHT = 600.0f;
|
constexpr auto REFERENCE_FONT_SIZE = 35.0f;
|
||||||
constexpr auto HUD_UNIT_X = 1.0f / REFERENCE_RES_WIDTH;
|
constexpr auto HUD_UNIT_X = 1.0f / SCREEN_SPACE_RES.x;
|
||||||
constexpr auto HUD_UNIT_Y = 1.0f / REFERENCE_RES_HEIGHT;
|
constexpr auto HUD_UNIT_Y = 1.0f / SCREEN_SPACE_RES.y;
|
||||||
constexpr auto HUD_ZERO_Y = -REFERENCE_RES_HEIGHT;
|
constexpr auto HUD_ZERO_Y = -SCREEN_SPACE_RES.y;
|
||||||
|
|
||||||
constexpr auto UNDERWATER_FOG_MIN_DISTANCE = 4;
|
constexpr auto UNDERWATER_FOG_MIN_DISTANCE = 4;
|
||||||
constexpr auto UNDERWATER_FOG_MAX_DISTANCE = 30;
|
constexpr auto UNDERWATER_FOG_MAX_DISTANCE = 30;
|
||||||
|
|
|
@ -365,7 +365,9 @@ namespace TEN::Renderer
|
||||||
bool Renderer11::SphereBoxIntersection(BoundingBox box, Vector3 sphereCentre, float sphereRadius)
|
bool Renderer11::SphereBoxIntersection(BoundingBox box, Vector3 sphereCentre, float sphereRadius)
|
||||||
{
|
{
|
||||||
if (sphereRadius == 0.0f)
|
if (sphereRadius == 0.0f)
|
||||||
|
{
|
||||||
return box.Contains(sphereCentre);
|
return box.Contains(sphereCentre);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
BoundingSphere sphere = BoundingSphere(sphereCentre, sphereRadius);
|
BoundingSphere sphere = BoundingSphere(sphereCentre, sphereRadius);
|
||||||
|
@ -373,10 +375,6 @@ namespace TEN::Renderer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer11::GetLaraBonePosition(Vector3 *pos, int bone)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void Renderer11::FlipRooms(short roomNumber1, short roomNumber2)
|
void Renderer11::FlipRooms(short roomNumber1, short roomNumber2)
|
||||||
{
|
{
|
||||||
std::swap(m_rooms[roomNumber1], m_rooms[roomNumber2]);
|
std::swap(m_rooms[roomNumber1], m_rooms[roomNumber2]);
|
||||||
|
@ -407,31 +405,6 @@ namespace TEN::Renderer
|
||||||
return m_meshes[meshIndex];
|
return m_meshes[meshIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer11::GetItemAbsBonePosition(int itemNumber, Vector3& pos, int jointIndex)
|
|
||||||
{
|
|
||||||
auto* rendererItem = &m_items[itemNumber];
|
|
||||||
auto* nativeItem = &g_Level.Items[itemNumber];
|
|
||||||
|
|
||||||
rendererItem->ItemNumber = itemNumber;
|
|
||||||
|
|
||||||
if (!rendererItem)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!rendererItem->DoneAnimations)
|
|
||||||
{
|
|
||||||
if (itemNumber == Lara.ItemNumber)
|
|
||||||
UpdateLaraAnimations(false);
|
|
||||||
else
|
|
||||||
UpdateItemAnimations(itemNumber, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (jointIndex >= MAX_BONES)
|
|
||||||
jointIndex = 0;
|
|
||||||
|
|
||||||
auto world = rendererItem->AnimationTransforms[jointIndex] * rendererItem->World;
|
|
||||||
pos = Vector3::Transform(pos, world);
|
|
||||||
}
|
|
||||||
|
|
||||||
int Renderer11::GetSpheres(short itemNumber, BoundingSphere* spheres, char worldSpace, Matrix local)
|
int Renderer11::GetSpheres(short itemNumber, BoundingSphere* spheres, char worldSpace, Matrix local)
|
||||||
{
|
{
|
||||||
auto* itemToDraw = &m_items[itemNumber];
|
auto* itemToDraw = &m_items[itemNumber];
|
||||||
|
@ -532,4 +505,63 @@ namespace TEN::Renderer
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
Vector2i Renderer11::GetScreenResolution() const
|
||||||
|
{
|
||||||
|
return Vector2i(m_screenWidth, m_screenHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector2 Renderer11::GetScreenSpacePosition(const Vector3& pos) const
|
||||||
|
{
|
||||||
|
auto point = Vector4(pos.x, pos.y, pos.z, 1.0f);
|
||||||
|
auto cameraPos = Vector4(
|
||||||
|
gameCamera.camera.WorldPosition.x,
|
||||||
|
gameCamera.camera.WorldPosition.y,
|
||||||
|
gameCamera.camera.WorldPosition.z,
|
||||||
|
1.0f);
|
||||||
|
auto cameraDirection = Vector4(
|
||||||
|
gameCamera.camera.WorldDirection.x,
|
||||||
|
gameCamera.camera.WorldDirection.y,
|
||||||
|
gameCamera.camera.WorldDirection.z,
|
||||||
|
1.0f);
|
||||||
|
|
||||||
|
// If point is behind camera, return invalid screen space position.
|
||||||
|
if ((point - cameraPos).Dot(cameraDirection) < 0.0f)
|
||||||
|
return INVALID_SCREEN_SPACE_POSITION;
|
||||||
|
|
||||||
|
// Calculate clip space coords.
|
||||||
|
point = Vector4::Transform(point, gameCamera.camera.ViewProjection);
|
||||||
|
|
||||||
|
// Calculate normalized device coords.
|
||||||
|
point /= point.w;
|
||||||
|
|
||||||
|
// Calculate and return screen space position.
|
||||||
|
return Vector2(
|
||||||
|
((point.x + 1.0f) * SCREEN_SPACE_RES.x) / 2,
|
||||||
|
((1.0f - point.y) * SCREEN_SPACE_RES.y) / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 Renderer11::GetAbsEntityBonePosition(int itemNumber, int jointIndex, const Vector3& relOffset)
|
||||||
|
{
|
||||||
|
auto* rendererItem = &m_items[itemNumber];
|
||||||
|
|
||||||
|
rendererItem->ItemNumber = itemNumber;
|
||||||
|
|
||||||
|
if (!rendererItem)
|
||||||
|
return Vector3::Zero;
|
||||||
|
|
||||||
|
if (!rendererItem->DoneAnimations)
|
||||||
|
{
|
||||||
|
if (itemNumber == Lara.ItemNumber)
|
||||||
|
UpdateLaraAnimations(false);
|
||||||
|
else
|
||||||
|
UpdateItemAnimations(itemNumber, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (jointIndex >= MAX_BONES)
|
||||||
|
jointIndex = 0;
|
||||||
|
|
||||||
|
auto world = rendererItem->AnimationTransforms[jointIndex] * rendererItem->World;
|
||||||
|
return Vector3::Transform(relOffset, world);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -116,7 +116,7 @@ void TEN::Renderer::Renderer11::Initialise(int w, int h, bool windowed, HWND han
|
||||||
m_cbHUD = CreateConstantBuffer<CHUDBuffer>();
|
m_cbHUD = CreateConstantBuffer<CHUDBuffer>();
|
||||||
m_cbSprite = CreateConstantBuffer<CSpriteBuffer>();
|
m_cbSprite = CreateConstantBuffer<CSpriteBuffer>();
|
||||||
m_stHUD.View = Matrix::CreateLookAt(Vector3::Zero, Vector3(0, 0, 1), Vector3(0, -1, 0));
|
m_stHUD.View = Matrix::CreateLookAt(Vector3::Zero, Vector3(0, 0, 1), Vector3(0, -1, 0));
|
||||||
m_stHUD.Projection = Matrix::CreateOrthographicOffCenter(0, REFERENCE_RES_WIDTH, 0, REFERENCE_RES_HEIGHT, 0, 1.0f);
|
m_stHUD.Projection = Matrix::CreateOrthographicOffCenter(0, SCREEN_SPACE_RES.x, 0, SCREEN_SPACE_RES.y, 0, 1.0f);
|
||||||
m_cbHUD.updateData(m_stHUD, m_context.Get());
|
m_cbHUD.updateData(m_stHUD, m_context.Get());
|
||||||
m_currentCausticsFrame = 0;
|
m_currentCausticsFrame = 0;
|
||||||
|
|
||||||
|
|
|
@ -60,7 +60,7 @@ namespace TEN::Renderer
|
||||||
dxgiAdapter->GetDesc(&adapterDesc);
|
dxgiAdapter->GetDesc(&adapterDesc);
|
||||||
dxgiFactory->Release();
|
dxgiFactory->Release();
|
||||||
|
|
||||||
return TEN::Utils::FromWchar(adapterDesc.Description);
|
return TEN::Utils::ToString(adapterDesc.Description);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer11::SetTextureOrDefault(Texture2D& texture, std::wstring path)
|
void Renderer11::SetTextureOrDefault(Texture2D& texture, std::wstring path)
|
||||||
|
|
|
@ -1,57 +1,54 @@
|
||||||
#include "framework.h"
|
#include "framework.h"
|
||||||
#include "Renderer/Renderer11.h"
|
#include "Renderer/Renderer11.h"
|
||||||
|
|
||||||
#include "Specific/trutils.h"
|
#include "Specific/trutils.h"
|
||||||
|
|
||||||
namespace TEN::Renderer
|
namespace TEN::Renderer
|
||||||
{
|
{
|
||||||
void Renderer11::AddString(int x, int y, const char* string, D3DCOLOR color, int flags)
|
void Renderer11::AddString(int x, int y, const char* string, D3DCOLOR color, int flags)
|
||||||
|
{
|
||||||
|
AddString(std::string(string), Vector2(x, y), Color(color), 1.0f, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer11::AddString(const std::string& string, const Vector2& pos, const Color& color, float scale, int flags)
|
||||||
{
|
{
|
||||||
if (m_Locked)
|
if (m_Locked)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (string == NULL)
|
if (string.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
float factorX = m_screenWidth / REFERENCE_RES_WIDTH;
|
auto screenRes = GetScreenResolution();
|
||||||
float factorY = m_screenHeight / REFERENCE_RES_HEIGHT;
|
auto factor = Vector2(screenRes.x / SCREEN_SPACE_RES.x, screenRes.y / SCREEN_SPACE_RES.y);
|
||||||
float UIScale = m_screenWidth > m_screenHeight ? factorY : factorX;
|
float UIScale = (screenRes.x > screenRes.y) ? factor.y : factor.x;
|
||||||
float fontSpacing = m_gameFont->GetLineSpacing();
|
float fontSpacing = m_gameFont->GetLineSpacing();
|
||||||
float fontScale = REFERENCE_FONT_SIZE / fontSpacing;
|
float fontScale = REFERENCE_FONT_SIZE / fontSpacing;
|
||||||
|
|
||||||
float currentY = 0;
|
auto stringLines = SplitString(string);
|
||||||
|
float yOffset = 0.0f;
|
||||||
auto lines = TEN::Utils::SplitString(string);
|
for (const auto& line : stringLines)
|
||||||
|
|
||||||
for (auto line : lines)
|
|
||||||
{
|
{
|
||||||
auto cLine = line.c_str();
|
// Prepare structure for renderer.
|
||||||
|
RendererStringToDraw rString;
|
||||||
|
rString.String = TEN::Utils::ToWString(line);
|
||||||
|
rString.Flags = flags;
|
||||||
|
rString.X = 0;
|
||||||
|
rString.Y = 0;
|
||||||
|
rString.Color = color.ToVector3() * UCHAR_MAX;
|
||||||
|
rString.Scale = (UIScale * fontScale) * scale;
|
||||||
|
|
||||||
// Convert the string to wstring
|
// Measure string.
|
||||||
int sizeNeeded = MultiByteToWideChar(CP_UTF8, 0, cLine, line.size(), NULL, 0);
|
auto size = Vector2(m_gameFont->MeasureString(rString.String.c_str()));
|
||||||
std::wstring wstr(sizeNeeded, 0);
|
float width = size.x * rString.Scale;
|
||||||
MultiByteToWideChar(CP_UTF8, 0, cLine, strlen(cLine), &wstr[0], sizeNeeded);
|
|
||||||
|
|
||||||
// Prepare the structure for the renderer
|
rString.X = (flags & PRINTSTRING_CENTER) ? ((pos.x * factor.x) - (width / 2.0f)) : (pos.x * factor.x);
|
||||||
RendererStringToDraw str;
|
rString.Y = (pos.y * UIScale) + yOffset;
|
||||||
str.String = wstr;
|
|
||||||
str.Flags = flags;
|
|
||||||
str.X = 0;
|
|
||||||
str.Y = 0;
|
|
||||||
str.Color = Vector3((color >> 16) & 0xFF, (color >> 8) & 0xFF, color & 0xFF);
|
|
||||||
str.Scale = UIScale * fontScale;
|
|
||||||
|
|
||||||
// Measure the string
|
|
||||||
Vector2 size = m_gameFont->MeasureString(wstr.c_str());
|
|
||||||
float width = size.x * str.Scale;
|
|
||||||
|
|
||||||
str.X = (flags & PRINTSTRING_CENTER) ? (float)x * factorX - (width / 2.0f) : (float)x * factorX;
|
|
||||||
str.Y = y * UIScale + currentY;
|
|
||||||
|
|
||||||
if (flags & PRINTSTRING_BLINK)
|
if (flags & PRINTSTRING_BLINK)
|
||||||
{
|
{
|
||||||
str.Color = Vector3(m_blinkColorValue, m_blinkColorValue, m_blinkColorValue);
|
rString.Color = Vector3(m_blinkColorValue, m_blinkColorValue, m_blinkColorValue);
|
||||||
|
|
||||||
if (!m_blinkUpdated)
|
if (!m_blinkUpdated)
|
||||||
{
|
{
|
||||||
|
@ -64,24 +61,23 @@ namespace TEN::Renderer
|
||||||
m_blinkColorDirection = 1;
|
m_blinkColorDirection = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_blinkColorValue > 255)
|
if (m_blinkColorValue > UCHAR_MAX)
|
||||||
{
|
{
|
||||||
m_blinkColorValue = 255;
|
m_blinkColorValue = UCHAR_MAX;
|
||||||
m_blinkColorDirection = -1;
|
m_blinkColorDirection = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_strings.push_back(str);
|
m_strings.push_back(rString);
|
||||||
|
|
||||||
currentY += fontSpacing * 1.1f;
|
yOffset += fontSpacing * 1.1f;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (std::exception& ex)
|
catch (std::exception& ex)
|
||||||
{
|
{
|
||||||
TENLog(std::string("Unable to process string: '") + string +
|
TENLog(std::string("Unable to process string: '") + string + "'. Exception: " + std::string(ex.what()), LogLevel::Error);
|
||||||
"'. Exception: " + std::string(ex.what()), LogLevel::Error);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,20 +87,24 @@ namespace TEN::Renderer
|
||||||
|
|
||||||
m_spriteBatch->Begin();
|
m_spriteBatch->Begin();
|
||||||
|
|
||||||
for (int i = 0; i < m_strings.size(); i++)
|
for (const auto& rString : m_strings)
|
||||||
{
|
{
|
||||||
RendererStringToDraw* str = &m_strings[i];
|
// Draw shadow.
|
||||||
|
if (rString.Flags & PRINTSTRING_OUTLINE)
|
||||||
// Draw shadow if needed
|
{
|
||||||
if (str->Flags & PRINTSTRING_OUTLINE)
|
m_gameFont->DrawString(
|
||||||
m_gameFont->DrawString(m_spriteBatch.get(), str->String.c_str(), Vector2(str->X + shadeOffset * str->Scale, str->Y + shadeOffset * str->Scale),
|
m_spriteBatch.get(), rString.String.c_str(),
|
||||||
|
Vector2(rString.X + shadeOffset * rString.Scale, rString.Y + shadeOffset * rString.Scale),
|
||||||
Vector4(0.0f, 0.0f, 0.0f, 1.0f) * ScreenFadeCurrent,
|
Vector4(0.0f, 0.0f, 0.0f, 1.0f) * ScreenFadeCurrent,
|
||||||
0.0f, Vector4::Zero, str->Scale);
|
0.0f, Vector4::Zero, rString.Scale);
|
||||||
|
}
|
||||||
|
|
||||||
// Draw string
|
// Draw string.
|
||||||
m_gameFont->DrawString(m_spriteBatch.get(), str->String.c_str(), Vector2(str->X, str->Y),
|
m_gameFont->DrawString(
|
||||||
Vector4(str->Color.x / 255.0f, str->Color.y / 255.0f, str->Color.z / 255.0f, 1.0f) * ScreenFadeCurrent,
|
m_spriteBatch.get(), rString.String.c_str(),
|
||||||
0.0f, Vector4::Zero, str->Scale);
|
Vector2(rString.X, rString.Y),
|
||||||
|
Vector4(rString.Color.x / UCHAR_MAX, rString.Color.y / UCHAR_MAX, rString.Color.z / UCHAR_MAX, 1.0f) * ScreenFadeCurrent,
|
||||||
|
0.0f, Vector4::Zero, rString.Scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_spriteBatch->End();
|
m_spriteBatch->End();
|
||||||
|
|
|
@ -215,17 +215,13 @@ namespace TEN::Input
|
||||||
{
|
{
|
||||||
for (int i = 0; i < KEY_COUNT; i++)
|
for (int i = 0; i < KEY_COUNT; i++)
|
||||||
{
|
{
|
||||||
if (ActionQueue[i] != QueueState::None)
|
if (ActionQueue[i] == QueueState::None)
|
||||||
{
|
continue;
|
||||||
if (ActionQueue[i] == QueueState::Push)
|
|
||||||
{
|
if (ActionQueue[i] == QueueState::Push)
|
||||||
ActionMap[i].Update(true);
|
ActionMap[i].Update(true);
|
||||||
}
|
else
|
||||||
else
|
ActionMap[i].Clear();
|
||||||
{
|
|
||||||
ActionMap[i].Clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1038,7 +1038,7 @@ unsigned int _stdcall LoadLevel(void* data)
|
||||||
FILE* filePtr = nullptr;
|
FILE* filePtr = nullptr;
|
||||||
char* dataPtr = nullptr;
|
char* dataPtr = nullptr;
|
||||||
|
|
||||||
g_Renderer.SetLoadingScreen(TEN::Utils::FromChar(level->LoadScreenFileName.c_str()));
|
g_Renderer.SetLoadingScreen(TEN::Utils::ToWString(level->LoadScreenFileName.c_str()));
|
||||||
|
|
||||||
SetScreenFadeIn(FADE_SCREEN_SPEED);
|
SetScreenFadeIn(FADE_SCREEN_SPEED);
|
||||||
g_Renderer.UpdateProgress(0);
|
g_Renderer.UpdateProgress(0);
|
||||||
|
|
|
@ -5,52 +5,60 @@
|
||||||
|
|
||||||
namespace TEN::Utils
|
namespace TEN::Utils
|
||||||
{
|
{
|
||||||
std::string ToUpper(std::string source)
|
std::string ToUpper(std::string string)
|
||||||
{
|
{
|
||||||
std::transform(source.begin(), source.end(), source.begin(), [](unsigned char c) { return std::toupper(c); });
|
std::transform(string.begin(), string.end(), string.begin(), [](unsigned char c) { return std::toupper(c); });
|
||||||
return source;
|
return string;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ToLower(std::string source)
|
std::string ToLower(std::string string)
|
||||||
{
|
{
|
||||||
std::transform(source.begin(), source.end(), source.begin(), [](unsigned char c) { return std::tolower(c); });
|
std::transform(string.begin(), string.end(), string.begin(), [](unsigned char c) { return std::tolower(c); });
|
||||||
return source;
|
return string;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string FromWchar(const wchar_t* source)
|
std::string ToString(const wchar_t* string)
|
||||||
{
|
{
|
||||||
std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> converter;
|
auto converter = std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t>();
|
||||||
return converter.to_bytes(std::wstring(source));
|
return converter.to_bytes(std::wstring(string));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::wstring FromChar(const char* source)
|
std::wstring ToWString(const std::string& string)
|
||||||
|
{
|
||||||
|
auto cString = string.c_str();
|
||||||
|
int size = MultiByteToWideChar(CP_UTF8, 0, cString, string.size(), nullptr, 0);
|
||||||
|
auto wString = std::wstring(size, 0);
|
||||||
|
MultiByteToWideChar(CP_UTF8, 0, cString, strlen(cString), &wString[0], size);
|
||||||
|
return wString;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::wstring ToWString(const char* source)
|
||||||
{
|
{
|
||||||
wchar_t buffer[UCHAR_MAX];
|
wchar_t buffer[UCHAR_MAX];
|
||||||
std::mbstowcs(buffer, source, UCHAR_MAX);
|
std::mbstowcs(buffer, source, UCHAR_MAX);
|
||||||
return std::wstring(buffer);
|
return std::wstring(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> SplitString(const std::string& source)
|
std::vector<std::string> SplitString(const std::string& string)
|
||||||
{
|
{
|
||||||
std::vector<std::string> strings;
|
auto strings = std::vector<std::string>{};
|
||||||
|
|
||||||
// String is single line; exit early.
|
// String is single line; exit early.
|
||||||
if (source.find('\n') == std::string::npos)
|
if (string.find('\n') == std::string::npos)
|
||||||
{
|
{
|
||||||
strings.push_back(source);
|
strings.push_back(string);
|
||||||
return strings;
|
return strings;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string::size_type pos = 0;
|
std::string::size_type pos = 0;
|
||||||
std::string::size_type prev = 0;
|
std::string::size_type prev = 0;
|
||||||
while ((pos = source.find('\n', prev)) != std::string::npos)
|
while ((pos = string.find('\n', prev)) != std::string::npos)
|
||||||
{
|
{
|
||||||
strings.push_back(source.substr(prev, pos - prev));
|
strings.push_back(string.substr(prev, pos - prev));
|
||||||
prev = pos + 1;
|
prev = pos + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
strings.push_back(source.substr(prev));
|
strings.push_back(string.substr(prev));
|
||||||
|
|
||||||
return strings;
|
return strings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,14 +74,14 @@ namespace TEN::Utils
|
||||||
|
|
||||||
int size = GetFileVersionInfoSizeA(fileName, NULL);
|
int size = GetFileVersionInfoSizeA(fileName, NULL);
|
||||||
|
|
||||||
if (!size)
|
if (size == 0)
|
||||||
{
|
{
|
||||||
TENLog("GetFileVersionInfoSizeA failed", LogLevel::Error);
|
TENLog("GetFileVersionInfoSizeA failed", LogLevel::Error);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
std::unique_ptr<unsigned char> buffer(new unsigned char[size]);
|
std::unique_ptr<unsigned char> buffer(new unsigned char[size]);
|
||||||
|
|
||||||
// Load the version info.
|
// Load version info.
|
||||||
if (!GetFileVersionInfoA(fileName, 0, size, buffer.get()))
|
if (!GetFileVersionInfoA(fileName, 0, size, buffer.get()))
|
||||||
{
|
{
|
||||||
TENLog("GetFileVersionInfoA failed", LogLevel::Error);
|
TENLog("GetFileVersionInfoA failed", LogLevel::Error);
|
||||||
|
@ -96,6 +104,7 @@ namespace TEN::Utils
|
||||||
}
|
}
|
||||||
|
|
||||||
if (productVersion)
|
if (productVersion)
|
||||||
|
{
|
||||||
return
|
return
|
||||||
{
|
{
|
||||||
HIWORD(info->dwProductVersionMS),
|
HIWORD(info->dwProductVersionMS),
|
||||||
|
@ -103,7 +112,9 @@ namespace TEN::Utils
|
||||||
HIWORD(info->dwProductVersionLS),
|
HIWORD(info->dwProductVersionLS),
|
||||||
LOWORD(info->dwProductVersionLS)
|
LOWORD(info->dwProductVersionLS)
|
||||||
};
|
};
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
return
|
return
|
||||||
{
|
{
|
||||||
HIWORD(info->dwFileVersionMS),
|
HIWORD(info->dwFileVersionMS),
|
||||||
|
@ -111,5 +122,6 @@ namespace TEN::Utils
|
||||||
HIWORD(info->dwFileVersionLS),
|
HIWORD(info->dwFileVersionLS),
|
||||||
LOWORD(info->dwFileVersionLS)
|
LOWORD(info->dwFileVersionLS)
|
||||||
};
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace TEN::Utils
|
namespace TEN::Utils
|
||||||
{
|
{
|
||||||
std::string ToUpper(std::string source);
|
// String utilities
|
||||||
std::string ToLower(std::string source);
|
std::string ToUpper(std::string string);
|
||||||
std::string FromWchar(const wchar_t* source);
|
std::string ToLower(std::string string);
|
||||||
std::wstring FromChar(const char* source);
|
std::string ToString(const wchar_t* string);
|
||||||
std::vector<std::string> SplitString(const std::string& source);
|
std::wstring ToWString(const std::string& string);
|
||||||
|
std::wstring ToWString(const char* string);
|
||||||
|
std::vector<std::string> SplitString(const std::string& string);
|
||||||
|
|
||||||
std::vector<unsigned short> GetProductOrFileVersion(bool productVersion);
|
std::vector<unsigned short> GetProductOrFileVersion(bool productVersion);
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ extern "C"
|
||||||
|
|
||||||
bool ArgEquals(wchar_t* incomingArg, std::string name)
|
bool ArgEquals(wchar_t* incomingArg, std::string name)
|
||||||
{
|
{
|
||||||
auto lowerArg = TEN::Utils::ToLower(TEN::Utils::FromWchar(incomingArg));
|
auto lowerArg = TEN::Utils::ToLower(TEN::Utils::ToString(incomingArg));
|
||||||
return (lowerArg == "-" + name) || (lowerArg == "/" + name);
|
return (lowerArg == "-" + name) || (lowerArg == "/" + name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,7 +259,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||||
}
|
}
|
||||||
else if (ArgEquals(argv[i], "level") && argc > (i + 1))
|
else if (ArgEquals(argv[i], "level") && argc > (i + 1))
|
||||||
{
|
{
|
||||||
levelFile = TEN::Utils::FromWchar(argv[i + 1]);
|
levelFile = TEN::Utils::ToString(argv[i + 1]);
|
||||||
}
|
}
|
||||||
else if (ArgEquals(argv[i], "hash") && argc > (i + 1))
|
else if (ArgEquals(argv[i], "hash") && argc > (i + 1))
|
||||||
{
|
{
|
||||||
|
|
|
@ -166,6 +166,7 @@ CALL gen.bat</Command>
|
||||||
<ClInclude Include="Game\effects\item_fx.h" />
|
<ClInclude Include="Game\effects\item_fx.h" />
|
||||||
<ClInclude Include="Game\effects\Electricity.h" />
|
<ClInclude Include="Game\effects\Electricity.h" />
|
||||||
<ClInclude Include="Game\GuiObjects.h" />
|
<ClInclude Include="Game\GuiObjects.h" />
|
||||||
|
<ClInclude Include="Game\Hud\PickupSummary.h" />
|
||||||
<ClInclude Include="Math\Objects\AxisAngle.h" />
|
<ClInclude Include="Math\Objects\AxisAngle.h" />
|
||||||
<ClInclude Include="Objects\TR1\Trap\DamoclesSword.h" />
|
<ClInclude Include="Objects\TR1\Trap\DamoclesSword.h" />
|
||||||
<ClInclude Include="Objects\TR5\Entity\HeavyGuard.h" />
|
<ClInclude Include="Objects\TR5\Entity\HeavyGuard.h" />
|
||||||
|
@ -582,7 +583,7 @@ CALL gen.bat</Command>
|
||||||
<ClInclude Include="Game\effects\effects.h" />
|
<ClInclude Include="Game\effects\effects.h" />
|
||||||
<ClInclude Include="Game\control\flipeffect.h" />
|
<ClInclude Include="Game\control\flipeffect.h" />
|
||||||
<ClInclude Include="Game\effects\hair.h" />
|
<ClInclude Include="Game\effects\hair.h" />
|
||||||
<ClInclude Include="Game\health.h" />
|
<ClInclude Include="Game\Hud\Hud.h" />
|
||||||
<ClInclude Include="Game\items.h" />
|
<ClInclude Include="Game\items.h" />
|
||||||
<ClInclude Include="Game\Lara\lara.h" />
|
<ClInclude Include="Game\Lara\lara.h" />
|
||||||
<ClInclude Include="Game\Lara\lara_one_gun.h" />
|
<ClInclude Include="Game\Lara\lara_one_gun.h" />
|
||||||
|
@ -643,6 +644,7 @@ CALL gen.bat</Command>
|
||||||
<ClCompile Include="Game\collision\floordata.cpp" />
|
<ClCompile Include="Game\collision\floordata.cpp" />
|
||||||
<ClCompile Include="Game\effects\footprint.cpp" />
|
<ClCompile Include="Game\effects\footprint.cpp" />
|
||||||
<ClCompile Include="Game\GuiObjects.cpp" />
|
<ClCompile Include="Game\GuiObjects.cpp" />
|
||||||
|
<ClCompile Include="Game\Hud\PickupSummary.cpp" />
|
||||||
<ClCompile Include="Math\Objects\AxisAngle.cpp" />
|
<ClCompile Include="Math\Objects\AxisAngle.cpp" />
|
||||||
<ClCompile Include="Objects\TR1\Trap\DamoclesSword.cpp" />
|
<ClCompile Include="Objects\TR1\Trap\DamoclesSword.cpp" />
|
||||||
<ClCompile Include="Objects\TR5\Entity\HeavyGuard.cpp" />
|
<ClCompile Include="Objects\TR5\Entity\HeavyGuard.cpp" />
|
||||||
|
@ -944,7 +946,7 @@ CALL gen.bat</Command>
|
||||||
<ClCompile Include="Game\effects\effects.cpp" />
|
<ClCompile Include="Game\effects\effects.cpp" />
|
||||||
<ClCompile Include="Game\control\flipeffect.cpp" />
|
<ClCompile Include="Game\control\flipeffect.cpp" />
|
||||||
<ClCompile Include="Game\effects\hair.cpp" />
|
<ClCompile Include="Game\effects\hair.cpp" />
|
||||||
<ClCompile Include="Game\health.cpp" />
|
<ClCompile Include="Game\Hud\Hud.cpp" />
|
||||||
<ClCompile Include="Game\items.cpp" />
|
<ClCompile Include="Game\items.cpp" />
|
||||||
<ClCompile Include="Game\Lara\lara.cpp" />
|
<ClCompile Include="Game\Lara\lara.cpp" />
|
||||||
<ClCompile Include="Game\Lara\lara_one_gun.cpp" />
|
<ClCompile Include="Game\Lara\lara_one_gun.cpp" />
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue