mirror of
https://github.com/TombEngine/TombEngine.git
synced 2025-04-28 15:57:59 +03:00
Merge remote-tracking branch 'origin/DisplayString_Scale' into DisplayString_Scale
This commit is contained in:
commit
0a3c0beaca
76 changed files with 1857 additions and 527 deletions
|
@ -14,11 +14,14 @@ Version 1.1.1
|
|||
* Fix volume change in settings not affecting voice track.
|
||||
* Fix several lighting bugs.
|
||||
* Fix savegame count not properly increasing.
|
||||
* Overhaul look mode:
|
||||
- Allow for consistent and wider viewing angles while crawling, crouching, and hanging.
|
||||
- Improve movement and control.
|
||||
* Fix regeneration of non-ammo pickups with OCB 128.
|
||||
* Overhaul look-around feature:
|
||||
- Allow for more consistent and wider viewing angles while crawling, crouching, and hanging.
|
||||
- Improve look camera movement and control.
|
||||
- Re-enable looking while performing up jump, backward jump, or backward crawl.
|
||||
- Add functionality to rotate slowly when holding Walk while using binoculars or lasersight.
|
||||
* Add target highlighter system with toggle in Sound and Gameplay settings.
|
||||
* Add sprint slide state 191.
|
||||
* Add swinging blade.
|
||||
* Add crumbling platform and add new OCBs for behaviour:
|
||||
- OCB 0: Default behaviour. When the player steps on the platform, it will shake and crumble after 1.2 seconds.
|
||||
|
@ -27,12 +30,13 @@ Version 1.1.1
|
|||
- A negative value requires a trigger to activate.
|
||||
|
||||
Lua API changes:
|
||||
* Add DisplaySprite object.
|
||||
* Add Flow::EnableLoadSave() function to disable savegames.
|
||||
* Add Flow::EnablePointFilter() function to disable bilinear filtering.
|
||||
* Add Lara::GetAmmoType() function to read the ammo that Lara is using.
|
||||
* Add Lara::GetControlLock() and Lara::SetControlLock() functions to handle controls locking.
|
||||
* Add Logic.HandleEvent() function to call node events.
|
||||
* Add functions to load, save, and delete savegames.
|
||||
* Add functions to load, save, delete and check existence of savegames.
|
||||
* Add DisplayStringOption.RIGHT and DisplayStringOption.BLINK flags for DisplayString.
|
||||
* Make Vec2 object float-based instead of integer-based.
|
||||
* Add Vec2 arithmetic for division with a number and multiplication with another Vec2.
|
||||
|
|
|
@ -50,7 +50,7 @@ local strings =
|
|||
ammo_used = { "Ammo Used" },
|
||||
antialiasing = { "Antialiasing" },
|
||||
apply = { "Apply" },
|
||||
auto_target = { "Automatic Targeting" },
|
||||
automatic_targeting = { "Automatic Targeting" },
|
||||
back = { "Back" },
|
||||
cancel = { "Cancel" },
|
||||
caustics = { "Underwater Caustics" },
|
||||
|
@ -71,13 +71,15 @@ local strings =
|
|||
examine = { "Examine" },
|
||||
exit_game = { "Exit Game" },
|
||||
exit_to_title = { "Exit to Title" },
|
||||
general_actions = { "General Actions"},
|
||||
general_actions = { "General Actions" },
|
||||
high = { "High" },
|
||||
level_secrets_found = { "Secrets Found in Level" },
|
||||
load_game = { "Load Game" },
|
||||
low = { "Low" },
|
||||
medium = { "Medium" },
|
||||
menu_actions = { "Menu Actions" },
|
||||
mouse_sensitivity = { "Mouse Sensitivity" },
|
||||
mouse_smoothing = { "Mouse Smoothing" },
|
||||
music_volume = { "Music Volume" },
|
||||
new_game = { "New Game" },
|
||||
none = { "None" },
|
||||
|
@ -101,6 +103,7 @@ local strings =
|
|||
sound = { "Sound" },
|
||||
statistics = { "Statistics" },
|
||||
subtitles = { "Subtitles" },
|
||||
target_highlighter = { "Target Highlighter" },
|
||||
thumbstick_camera = { "Thumbstick Camera" },
|
||||
time_taken = { "Time Taken" },
|
||||
total_secrets_found = { "Secrets Found Total" },
|
||||
|
@ -112,6 +115,7 @@ local strings =
|
|||
waiting_for_input = { "Waiting For Input" },
|
||||
window_title = { "TombEngine" },
|
||||
windowed = { "Windowed" },
|
||||
unlimited = { "Unlimited %s" },
|
||||
}
|
||||
|
||||
TEN.Flow.SetStrings(strings)
|
||||
|
|
|
@ -11,20 +11,23 @@ namespace TEN::Hud
|
|||
{
|
||||
HudController g_Hud = {};
|
||||
|
||||
void HudController::Update(const ItemInfo& item)
|
||||
void HudController::Update(const ItemInfo& playerItem)
|
||||
{
|
||||
TargetHighlighter.Update(playerItem);
|
||||
PickupSummary.Update();
|
||||
StatusBars.Update(item);
|
||||
StatusBars.Update(playerItem);
|
||||
}
|
||||
|
||||
void HudController::Draw(const ItemInfo& item) const
|
||||
void HudController::Draw(const ItemInfo& playerItem) const
|
||||
{
|
||||
TargetHighlighter.Draw();
|
||||
PickupSummary.Draw();
|
||||
StatusBars.Draw(item);
|
||||
StatusBars.Draw(playerItem);
|
||||
}
|
||||
|
||||
void HudController::Clear()
|
||||
{
|
||||
TargetHighlighter.Clear();
|
||||
PickupSummary.Clear();
|
||||
StatusBars.Clear();
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
#include "Game/Hud/PickupSummary.h"
|
||||
#include "Game/Hud/StatusBars.h"
|
||||
#include "Game/Hud/TargetHighlighter.h"
|
||||
|
||||
struct ItemInfo;
|
||||
|
||||
|
@ -10,12 +11,13 @@ namespace TEN::Hud
|
|||
{
|
||||
public:
|
||||
// Members
|
||||
StatusBarsController StatusBars = {};
|
||||
PickupSummaryController PickupSummary = {};
|
||||
StatusBarsController StatusBars = {};
|
||||
PickupSummaryController PickupSummary = {};
|
||||
TargetHighlighterController TargetHighlighter = {};
|
||||
|
||||
// Utilities
|
||||
void Update(const ItemInfo& item);
|
||||
void Draw(const ItemInfo& item) const;
|
||||
void Update(const ItemInfo& playerItem);
|
||||
void Draw(const ItemInfo& playerItem) const;
|
||||
void Clear();
|
||||
};
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ namespace TEN::Hud
|
|||
|
||||
float Life = 0.0f;
|
||||
float Scale = 0.0f;
|
||||
float Opacity = 0.0f; // BIG TODO: Object transparency in renderer.
|
||||
float Opacity = 0.0f;
|
||||
float HideVelocity = 0.0f;
|
||||
float StringScale = 0.0f;
|
||||
float StringScalar = 0.0f;
|
||||
|
|
379
TombEngine/Game/Hud/TargetHighlighter.cpp
Normal file
379
TombEngine/Game/Hud/TargetHighlighter.cpp
Normal file
|
@ -0,0 +1,379 @@
|
|||
#include "framework.h"
|
||||
#include "Game/Hud/TargetHighlighter.h"
|
||||
|
||||
#include "Game/camera.h"
|
||||
#include "Game/effects/DisplaySprite.h"
|
||||
#include "Game/items.h"
|
||||
#include "Game/lara/lara_fire.h"
|
||||
#include "Game/lara/lara_helpers.h"
|
||||
#include "Math/Math.h"
|
||||
#include "Renderer/Renderer11.h"
|
||||
#include "Specific/configuration.h"
|
||||
#include "Specific/trutils.h"
|
||||
|
||||
using namespace TEN::Effects::DisplaySprite;
|
||||
using namespace TEN::Math;
|
||||
using namespace TEN::Utils;
|
||||
using TEN::Renderer::g_Renderer;
|
||||
|
||||
namespace TEN::Hud
|
||||
{
|
||||
float CrosshairData::GetScale(float cameraDist) const
|
||||
{
|
||||
constexpr auto RANGE = BLOCK(10);
|
||||
constexpr auto CROSSHAIR_SCALE_MAX = 0.15f;
|
||||
constexpr auto CROSSHAIR_SCALE_MIN = CROSSHAIR_SCALE_MAX / 3;
|
||||
|
||||
auto alpha = cameraDist / RANGE;
|
||||
return Lerp(CROSSHAIR_SCALE_MAX, CROSSHAIR_SCALE_MIN, alpha);
|
||||
}
|
||||
|
||||
float CrosshairData::GetRadius() const
|
||||
{
|
||||
// Get screen aspect ratio.
|
||||
auto screenRes = g_Renderer.GetScreenResolution().ToVector2();
|
||||
float screenResAspect = screenRes.x / screenRes.y;
|
||||
|
||||
return ((((SCREEN_SPACE_RES.x * Scale) / 2) * (RadiusScale * PulseScale)) * screenResAspect);
|
||||
}
|
||||
|
||||
Vector2 CrosshairData::GetPositionOffset(short orientOffset) const
|
||||
{
|
||||
constexpr auto ANGLE_OFFSET = ANGLE(-360.0f / (SEGMENT_COUNT * 2));
|
||||
|
||||
float offsetDist = GetRadius();
|
||||
auto relPosOffset = Vector2(offsetDist, 0.0f);
|
||||
auto rotMatrix = Matrix::CreateRotationZ(TO_RAD((Orientation + orientOffset) + ANGLE_OFFSET));
|
||||
|
||||
auto posOffset = Vector2::Transform(relPosOffset, rotMatrix);
|
||||
return GetAspectCorrect2DPosition(posOffset);
|
||||
}
|
||||
|
||||
void CrosshairData::SetPrimary()
|
||||
{
|
||||
IsPrimary = true;
|
||||
ColorTarget = COLOR_RED;
|
||||
}
|
||||
|
||||
void CrosshairData::SetPeripheral()
|
||||
{
|
||||
IsPrimary = false;
|
||||
ColorTarget = COLOR_GRAY;
|
||||
}
|
||||
|
||||
bool CrosshairData::IsOffscreen() const
|
||||
{
|
||||
if (!Position.has_value())
|
||||
return true;
|
||||
|
||||
// TODO: Not working?
|
||||
float screenEdgeThreshold = GetRadius();
|
||||
return (Position->x <= -screenEdgeThreshold ||
|
||||
Position->y <= -screenEdgeThreshold ||
|
||||
Position->x >= (SCREEN_SPACE_RES.x + screenEdgeThreshold) ||
|
||||
Position->y >= (SCREEN_SPACE_RES.y + screenEdgeThreshold));
|
||||
}
|
||||
|
||||
void CrosshairData::Update(const Vector3& targetPos, bool isActive, bool doPulse)
|
||||
{
|
||||
constexpr auto ROT = ANGLE(2.0f);
|
||||
constexpr auto ALIGN_ANGLE_STEP = ANGLE(360.0f / SEGMENT_COUNT);
|
||||
constexpr auto SCALE_PRIMARY = 0.75f;
|
||||
constexpr auto SCALE_PERIPHERAL = 0.5f;
|
||||
constexpr auto RADIUS_SCALE_PRIMARY = 0.5f;
|
||||
constexpr auto RADIUS_SCALE_PERIPHERAL = 0.25f;
|
||||
constexpr auto PULSE_SCALE_MAX = 1.3f;
|
||||
constexpr auto MORPH_LERP_ALPHA = 0.3f;
|
||||
constexpr auto ORIENT_LERP_ALPHA = 0.1f;
|
||||
constexpr auto RADIUS_LERP_ALPHA = 0.2f;
|
||||
|
||||
// Update active status.
|
||||
IsActive = isActive;
|
||||
|
||||
// Update position.
|
||||
Position = g_Renderer.Get2DPosition(targetPos);
|
||||
|
||||
// Update orientation.
|
||||
if (IsPrimary)
|
||||
{
|
||||
Orientation += ROT;
|
||||
}
|
||||
else
|
||||
{
|
||||
short closestAlignAngle = round(Orientation / ALIGN_ANGLE_STEP) * ALIGN_ANGLE_STEP;
|
||||
Orientation = (short)round(Lerp(Orientation, closestAlignAngle, ORIENT_LERP_ALPHA));
|
||||
}
|
||||
|
||||
// Update scale.
|
||||
if (IsActive)
|
||||
{
|
||||
float cameraDist = Vector3::Distance(Camera.pos.ToVector3(), targetPos);
|
||||
float scaleTarget = GetScale(cameraDist) * (IsPrimary ? SCALE_PRIMARY : SCALE_PERIPHERAL);
|
||||
|
||||
Scale = Lerp(Scale, scaleTarget, MORPH_LERP_ALPHA);
|
||||
}
|
||||
else
|
||||
{
|
||||
Scale = Lerp(Scale, 0.0f, MORPH_LERP_ALPHA / 2);
|
||||
}
|
||||
|
||||
// Update color.
|
||||
if (!IsActive)
|
||||
{
|
||||
ColorTarget = CrosshairData::COLOR_GRAY;
|
||||
ColorTarget.w = 0.0f;
|
||||
}
|
||||
Color = Vector4::Lerp(Color, ColorTarget, MORPH_LERP_ALPHA);
|
||||
|
||||
float radiusScaleTarget = IsPrimary ? RADIUS_SCALE_PRIMARY : RADIUS_SCALE_PERIPHERAL;
|
||||
if (!IsActive)
|
||||
radiusScaleTarget = RADIUS_SCALE_PERIPHERAL;
|
||||
|
||||
// Update radius scale.
|
||||
RadiusScale = Lerp(RadiusScale, radiusScaleTarget, RADIUS_LERP_ALPHA);
|
||||
|
||||
// Update pulse scale.
|
||||
PulseScale = doPulse ? PULSE_SCALE_MAX : Lerp(PulseScale, 1.0f, MORPH_LERP_ALPHA);
|
||||
|
||||
// Update segments.
|
||||
for (auto& segment : Segments)
|
||||
segment.PosOffset = GetPositionOffset(segment.OrientOffset);
|
||||
}
|
||||
|
||||
void CrosshairData::Draw() const
|
||||
{
|
||||
constexpr auto SPRITE_SEQUENCE_OBJECT_ID = ID_CROSSHAIR;
|
||||
constexpr auto STATIC_ELEMENT_SPRITE_ID = 0;
|
||||
constexpr auto SEGMENT_ELEMENT_SPRITE_ID = 1;
|
||||
constexpr auto PRIORITY = 0; // TODO: Check later. May interfere with Lua display sprites. -- Sezz 2023.10.06
|
||||
constexpr auto ALIGN_MODE = DisplaySpriteAlignMode::Center;
|
||||
constexpr auto SCALE_MODE = DisplaySpriteScaleMode::Fill;
|
||||
constexpr auto BLEND_MODE = BLEND_MODES::BLENDMODE_ALPHABLEND;
|
||||
|
||||
if (IsOffscreen())
|
||||
return;
|
||||
|
||||
// Draw main static element.
|
||||
AddDisplaySprite(
|
||||
SPRITE_SEQUENCE_OBJECT_ID, STATIC_ELEMENT_SPRITE_ID,
|
||||
*Position, Orientation, Vector2(Scale), Color,
|
||||
PRIORITY, ALIGN_MODE, SCALE_MODE, BLEND_MODE);
|
||||
|
||||
// Draw animated outer segment elements.
|
||||
for (const auto& segment : Segments)
|
||||
{
|
||||
auto pos = *Position + segment.PosOffset;
|
||||
short orient = Orientation + segment.OrientOffset;
|
||||
auto scale = Vector2(Scale / 2);
|
||||
|
||||
AddDisplaySprite(
|
||||
SPRITE_SEQUENCE_OBJECT_ID, SEGMENT_ELEMENT_SPRITE_ID,
|
||||
pos, orient, scale, Color,
|
||||
PRIORITY, ALIGN_MODE, SCALE_MODE, BLEND_MODE);
|
||||
}
|
||||
}
|
||||
|
||||
void TargetHighlighterController::Update(const ItemInfo& playerItem)
|
||||
{
|
||||
// Check if target highlighter is enabled.
|
||||
if (!g_Configuration.EnableTargetHighlighter)
|
||||
{
|
||||
if (!Crosshairs.empty())
|
||||
Crosshairs.clear();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& player = GetLaraInfo(playerItem);
|
||||
|
||||
// Loop over player targets.
|
||||
auto itemNumbers = std::vector<int>{};
|
||||
for (const auto* itemPtr : player.TargetList)
|
||||
{
|
||||
if (itemPtr == nullptr)
|
||||
continue;
|
||||
|
||||
// Collect item number.
|
||||
itemNumbers.push_back(itemPtr->Index);
|
||||
|
||||
// Find crosshair at item number key.
|
||||
auto it = Crosshairs.find(itemPtr->Index);
|
||||
if (it == Crosshairs.end())
|
||||
continue;
|
||||
|
||||
// Set crosshair as primary or peripheral.
|
||||
auto& crosshair = it->second;
|
||||
if (player.TargetEntity != nullptr &&
|
||||
itemPtr->Index == player.TargetEntity->Index)
|
||||
{
|
||||
crosshair.SetPrimary();
|
||||
}
|
||||
else
|
||||
{
|
||||
crosshair.SetPeripheral();
|
||||
}
|
||||
}
|
||||
|
||||
// Update crosshairs.
|
||||
Update(itemNumbers);
|
||||
}
|
||||
|
||||
void TargetHighlighterController::Draw() const
|
||||
{
|
||||
//DrawDebug();
|
||||
|
||||
if (Crosshairs.empty())
|
||||
return;
|
||||
|
||||
for (const auto& [itemNumber, crosshair] : Crosshairs)
|
||||
crosshair.Draw();
|
||||
}
|
||||
|
||||
void TargetHighlighterController::Clear()
|
||||
{
|
||||
*this = {};
|
||||
}
|
||||
|
||||
void TargetHighlighterController::Update(const std::vector<int>& itemNumbers)
|
||||
{
|
||||
constexpr auto TARGET_BONE_ID = 0;
|
||||
|
||||
// No crosshairs to update; return early.
|
||||
if (Crosshairs.empty() && itemNumbers.empty())
|
||||
return;
|
||||
|
||||
// Update active crosshairs.
|
||||
for (int itemNumber : itemNumbers)
|
||||
{
|
||||
const auto& item = g_Level.Items[itemNumber];
|
||||
auto targetPos = GetJointPosition(item, TARGET_BONE_ID).ToVector3();
|
||||
|
||||
// Update existing active crosshair.
|
||||
auto it = Crosshairs.find(itemNumber);
|
||||
if (it != Crosshairs.end())
|
||||
{
|
||||
auto& crosshair = it->second;
|
||||
if (crosshair.IsActive)
|
||||
{
|
||||
crosshair.Update(targetPos, true, item.HitStatus);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Add new active crosshair.
|
||||
AddCrosshair(itemNumber, targetPos);
|
||||
}
|
||||
|
||||
// Update inactive crosshairs.
|
||||
for (auto& [itemNumber, crosshair] : Crosshairs)
|
||||
{
|
||||
// Find crosshairs at absent item number keys.
|
||||
if (Contains(itemNumbers, itemNumber))
|
||||
continue;
|
||||
|
||||
const auto& item = g_Level.Items[itemNumber];
|
||||
auto targetPos = GetJointPosition(item, 0).ToVector3();
|
||||
|
||||
// Update inactive crosshair.
|
||||
crosshair.Update(targetPos, false, item.HitStatus);
|
||||
}
|
||||
|
||||
ClearInactiveCrosshairs();
|
||||
}
|
||||
|
||||
CrosshairData& TargetHighlighterController::GetNewCrosshair(int itemNumber)
|
||||
{
|
||||
constexpr auto CROSSHAIR_COUNT_MAX = 16;
|
||||
|
||||
// Map is full; clear smallest crosshair.
|
||||
if (Crosshairs.size() >= CROSSHAIR_COUNT_MAX)
|
||||
{
|
||||
int key = 0;
|
||||
float smallestScale = INFINITY;
|
||||
|
||||
for (auto& [itemNumber, crosshair] : Crosshairs)
|
||||
{
|
||||
if (crosshair.Scale < smallestScale)
|
||||
{
|
||||
key = itemNumber;
|
||||
smallestScale = crosshair.Scale;
|
||||
}
|
||||
}
|
||||
|
||||
Crosshairs.erase(key);
|
||||
}
|
||||
|
||||
// Return new crosshair.
|
||||
Crosshairs.insert({ itemNumber, {} });
|
||||
auto& crosshair = Crosshairs.at(itemNumber);
|
||||
crosshair = {};
|
||||
return crosshair;
|
||||
}
|
||||
|
||||
// TODO: If crosshair happens to be in view upon spawn, first frame is sometimes garbage.
|
||||
void TargetHighlighterController::AddCrosshair(int itemNumber, const Vector3& targetPos)
|
||||
{
|
||||
constexpr auto SCALE_START = 0.75f;
|
||||
constexpr auto RADIUS_SCALE_START = 1.5f * SQRT_2;
|
||||
constexpr auto ANGLE_STEP = ANGLE(360.0f / CrosshairData::SEGMENT_COUNT);
|
||||
|
||||
auto pos = g_Renderer.Get2DPosition(targetPos);
|
||||
if (!pos.has_value())
|
||||
return;
|
||||
|
||||
// Create new crosshair.
|
||||
auto& crosshair = GetNewCrosshair(itemNumber);
|
||||
|
||||
crosshair.IsActive = true;
|
||||
crosshair.IsPrimary = false;
|
||||
crosshair.Position = *pos;
|
||||
crosshair.Orientation = 0;
|
||||
crosshair.Scale = SCALE_START;
|
||||
crosshair.Color = CrosshairData::COLOR_GRAY;
|
||||
crosshair.Color.w = 0.0f;
|
||||
crosshair.ColorTarget = CrosshairData::COLOR_GRAY;
|
||||
crosshair.RadiusScale = RADIUS_SCALE_START;
|
||||
crosshair.PulseScale = 1.0f;
|
||||
|
||||
// Initialize segments.
|
||||
short angleOffset = 0;
|
||||
for (auto& segment : crosshair.Segments)
|
||||
{
|
||||
segment.PosOffset = crosshair.GetPositionOffset(segment.OrientOffset);
|
||||
segment.OrientOffset = angleOffset;
|
||||
|
||||
angleOffset += ANGLE_STEP;
|
||||
}
|
||||
}
|
||||
|
||||
void TargetHighlighterController::ClearInactiveCrosshairs()
|
||||
{
|
||||
for (auto it = Crosshairs.begin(); it != Crosshairs.end();)
|
||||
{
|
||||
const auto& crosshair = it->second;
|
||||
(!crosshair.IsActive && crosshair.Scale <= EPSILON) ?
|
||||
(it = Crosshairs.erase(it)) : ++it;
|
||||
}
|
||||
}
|
||||
|
||||
void TargetHighlighterController::DrawDebug() const
|
||||
{
|
||||
unsigned int visibleCount = 0;
|
||||
unsigned int primaryCount = 0;
|
||||
unsigned int peripheralCount = 0;
|
||||
|
||||
for (const auto& [itemNumber, crosshair] : Crosshairs)
|
||||
{
|
||||
crosshair.IsPrimary ? primaryCount++ : peripheralCount++;
|
||||
|
||||
if (!crosshair.IsOffscreen())
|
||||
visibleCount++;
|
||||
}
|
||||
|
||||
g_Renderer.PrintDebugMessage("TARGET HIGHLIGHTER DEBUG");
|
||||
g_Renderer.PrintDebugMessage(g_Configuration.EnableTargetHighlighter ? "Enabled" : "Disabled");
|
||||
g_Renderer.PrintDebugMessage("Visible crosshairs: %d", visibleCount);
|
||||
g_Renderer.PrintDebugMessage("Primary crosshairs: %d", primaryCount);
|
||||
g_Renderer.PrintDebugMessage("Peripheral crosshairs: %d", peripheralCount);
|
||||
}
|
||||
}
|
77
TombEngine/Game/Hud/TargetHighlighter.h
Normal file
77
TombEngine/Game/Hud/TargetHighlighter.h
Normal file
|
@ -0,0 +1,77 @@
|
|||
#pragma once
|
||||
|
||||
struct ItemInfo;
|
||||
|
||||
namespace TEN::Hud
|
||||
{
|
||||
class CrosshairData
|
||||
{
|
||||
private:
|
||||
struct SegmentData
|
||||
{
|
||||
Vector2 PosOffset = Vector2::Zero;
|
||||
short OrientOffset = 0;
|
||||
};
|
||||
|
||||
public:
|
||||
// Constants
|
||||
static constexpr auto COLOR_RED = Vector4(1.0f, 0.2f, 0.2f, 0.9f);
|
||||
static constexpr auto COLOR_GRAY = Vector4(0.5f, 0.5f, 0.5f, 0.5f);
|
||||
static constexpr auto SEGMENT_COUNT = 4;
|
||||
|
||||
// Members
|
||||
bool IsActive = false;
|
||||
bool IsPrimary = false;
|
||||
|
||||
std::optional<Vector2> Position = std::nullopt;
|
||||
short Orientation = 0;
|
||||
float Scale = 0.0f;
|
||||
Vector4 Color = Vector4::Zero;
|
||||
Vector4 ColorTarget = Vector4::Zero;
|
||||
|
||||
float RadiusScale = 0.0f;
|
||||
float PulseScale = 0.0f;
|
||||
|
||||
std::array<SegmentData, SEGMENT_COUNT> Segments = {};
|
||||
|
||||
// Getters
|
||||
float GetScale(float cameraDist) const;
|
||||
float GetRadius() const;
|
||||
Vector2 GetPositionOffset(short orientOffset) const;
|
||||
|
||||
// Setters
|
||||
void SetPrimary();
|
||||
void SetPeripheral();
|
||||
|
||||
// Inquirers
|
||||
bool IsOffscreen() const;
|
||||
|
||||
// Utilities
|
||||
void Update(const Vector3& targetPos, bool isActive, bool doPulse);
|
||||
void Draw() const;
|
||||
};
|
||||
|
||||
class TargetHighlighterController
|
||||
{
|
||||
private:
|
||||
// Members
|
||||
std::unordered_map<int, CrosshairData> Crosshairs = {}; // Key = item number.
|
||||
|
||||
public:
|
||||
// Utilities
|
||||
void Update(const ItemInfo& playerItem);
|
||||
void Draw() const;
|
||||
void Clear();
|
||||
|
||||
private:
|
||||
// Update helpers
|
||||
void Update(const std::vector<int>& itemNumbers);
|
||||
|
||||
// Object helpers
|
||||
CrosshairData& GetNewCrosshair(int itemNumber);
|
||||
void AddCrosshair(int itemNumber, const Vector3& targetPos);
|
||||
void ClearInactiveCrosshairs();
|
||||
|
||||
void DrawDebug() const;
|
||||
};
|
||||
}
|
|
@ -245,6 +245,8 @@ std::function<LaraRoutineFunction> lara_control_routines[NUM_LARA_STATES + 1] =
|
|||
lara_as_null,
|
||||
lara_as_null,
|
||||
lara_as_use_puzzle,//189
|
||||
lara_as_null,//190
|
||||
lara_as_sprint_slide,//191
|
||||
};
|
||||
|
||||
std::function<LaraRoutineFunction> lara_collision_routines[NUM_LARA_STATES + 1] =
|
||||
|
@ -439,6 +441,8 @@ std::function<LaraRoutineFunction> lara_collision_routines[NUM_LARA_STATES + 1]
|
|||
lara_void_func,
|
||||
lara_void_func,
|
||||
lara_default_col,//189
|
||||
lara_void_func,//190
|
||||
lara_col_sprint_slide,//191
|
||||
};
|
||||
|
||||
void LaraControl(ItemInfo* item, CollisionInfo* coll)
|
||||
|
|
|
@ -2426,7 +2426,7 @@ void lara_as_sprint_dive(ItemInfo* item, CollisionInfo* coll)
|
|||
}
|
||||
|
||||
// State: LS_SPRINT_DIVE (74)
|
||||
// Control: lara_col_sprint_dive()
|
||||
// Control: lara_as_sprint_dive()
|
||||
void lara_col_sprint_dive(ItemInfo* item, CollisionInfo* coll)
|
||||
{
|
||||
auto* lara = GetLaraInfo(item);
|
||||
|
@ -2458,3 +2458,77 @@ void lara_col_sprint_dive(ItemInfo* item, CollisionInfo* coll)
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Useful for having the player sweep under a gate. No default animation is currently included,
|
||||
// but later one will be added to avoid making this an "insider feature". -- Sezz 2023.10.12
|
||||
// State: LS_SPRINT_SLIDE (191)
|
||||
// Collision: lara_col_sprint_slide()
|
||||
void lara_as_sprint_slide(ItemInfo* item, CollisionInfo* coll)
|
||||
{
|
||||
auto& player = GetLaraInfo(*item);
|
||||
|
||||
player.Control.Look.Mode = LookMode::Horizontal;
|
||||
|
||||
player.Control.Count.Run++;
|
||||
if (player.Control.Count.Run > LARA_RUN_JUMP_TIME)
|
||||
player.Control.Count.Run = LARA_RUN_JUMP_TIME;
|
||||
|
||||
if (IsHeld(In::Left) || IsHeld(In::Right))
|
||||
{
|
||||
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_SLOW_TURN_RATE_MAX);
|
||||
ModulateLaraLean(item, coll, LARA_LEAN_RATE, LARA_LEAN_MAX * 0.6f);
|
||||
}
|
||||
|
||||
if ((player.Control.KeepLow || IsHeld(In::Crouch)) && HasStateDispatch(item, LS_CROUCH_IDLE) &&
|
||||
TestLaraCrouch(item))
|
||||
{
|
||||
item->Animation.TargetState = LS_CROUCH_IDLE;
|
||||
return;
|
||||
}
|
||||
|
||||
item->Animation.TargetState = LS_RUN_FORWARD;
|
||||
}
|
||||
|
||||
// State: LS_SPRINT_SLIDE (191)
|
||||
// Control: lara_as_sprint_slide()
|
||||
void lara_col_sprint_slide(ItemInfo* item, CollisionInfo* coll)
|
||||
{
|
||||
auto& player = GetLaraInfo(*item);
|
||||
|
||||
player.Control.MoveAngle = item->Pose.Orientation.y;
|
||||
player.Control.KeepLow = TestLaraKeepLow(item, coll);
|
||||
player.Control.IsLow = true;
|
||||
coll->Setup.Height = LARA_HEIGHT_CRAWL;
|
||||
coll->Setup.LowerFloorBound = NO_LOWER_BOUND;
|
||||
coll->Setup.UpperFloorBound = -(CLICK(1) - 1);
|
||||
coll->Setup.LowerCeilingBound = 0;
|
||||
coll->Setup.BlockFloorSlopeUp = true;
|
||||
coll->Setup.ForwardAngle = player.Control.MoveAngle;
|
||||
GetCollisionInfo(coll, item);
|
||||
|
||||
LaraDeflectEdge(item, coll);
|
||||
|
||||
if (TestLaraHitCeiling(coll))
|
||||
{
|
||||
SetLaraHitCeiling(item, coll);
|
||||
return;
|
||||
}
|
||||
|
||||
if (TestLaraFall(item, coll))
|
||||
{
|
||||
SetLaraFallAnimation(item);
|
||||
return;
|
||||
}
|
||||
|
||||
if (TestLaraSlide(item, coll))
|
||||
{
|
||||
SetLaraSlideAnimation(item, coll);
|
||||
return;
|
||||
}
|
||||
|
||||
if (TestLaraStep(item, coll) && coll->CollisionType != CT_FRONT)
|
||||
{
|
||||
DoLaraStep(item, coll);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -73,3 +73,5 @@ void lara_as_sprint(ItemInfo* item, CollisionInfo* coll);
|
|||
void lara_col_sprint(ItemInfo* item, CollisionInfo* coll);
|
||||
void lara_as_sprint_dive(ItemInfo* item, CollisionInfo* coll);
|
||||
void lara_col_sprint_dive(ItemInfo* item, CollisionInfo* coll);
|
||||
void lara_as_sprint_slide(ItemInfo* item, CollisionInfo* coll);
|
||||
void lara_col_sprint_slide(ItemInfo* item, CollisionInfo* coll);
|
||||
|
|
|
@ -282,6 +282,15 @@ WeaponInfo Weapons[(int)LaraWeaponType::NumWeapons] =
|
|||
}
|
||||
};
|
||||
|
||||
// TODO: Use map like in GetWeaponAnimData();
|
||||
const WeaponInfo& GetWeaponInfo(LaraWeaponType weaponType)
|
||||
{
|
||||
if ((int)weaponType < 0 || (int)weaponType >= (int)LaraWeaponType::NumWeapons)
|
||||
return Weapons[0];
|
||||
|
||||
return (Weapons[(int)weaponType]);
|
||||
}
|
||||
|
||||
void InitializeNewWeapon(ItemInfo& laraItem)
|
||||
{
|
||||
auto& player = *GetLaraInfo(&laraItem);
|
||||
|
@ -469,6 +478,15 @@ GAME_OBJECT_ID GetWeaponObjectMeshID(ItemInfo& laraItem, LaraWeaponType weaponTy
|
|||
}
|
||||
}
|
||||
|
||||
static void ClearPlayerTargets(ItemInfo& playerItem)
|
||||
{
|
||||
auto& player = GetLaraInfo(playerItem);
|
||||
|
||||
player.TargetEntity = nullptr;
|
||||
player.TargetList.fill(nullptr);
|
||||
player.LastTargets.fill(nullptr);
|
||||
}
|
||||
|
||||
void HandleWeapon(ItemInfo& laraItem)
|
||||
{
|
||||
auto& player = *GetLaraInfo(&laraItem);
|
||||
|
@ -545,7 +563,7 @@ void HandleWeapon(ItemInfo& laraItem)
|
|||
(player.Control.Weapon.RequestGunType == LaraWeaponType::HarpoonGun ||
|
||||
player.Control.WaterStatus == WaterStatus::Dry ||
|
||||
(player.Control.WaterStatus == WaterStatus::Wade &&
|
||||
player.Context.WaterSurfaceDist > -Weapons[(int)player.Control.Weapon.GunType].GunHeight))))
|
||||
player.Context.WaterSurfaceDist > -GetWeaponInfo(player.Control.Weapon.GunType).GunHeight))))
|
||||
{
|
||||
if (player.Control.Weapon.GunType == LaraWeaponType::Flare)
|
||||
{
|
||||
|
@ -586,7 +604,7 @@ void HandleWeapon(ItemInfo& laraItem)
|
|||
else if (player.Control.Weapon.GunType != LaraWeaponType::HarpoonGun &&
|
||||
player.Control.WaterStatus != WaterStatus::Dry &&
|
||||
(player.Control.WaterStatus != WaterStatus::Wade ||
|
||||
player.Context.WaterSurfaceDist < -Weapons[(int)player.Control.Weapon.GunType].GunHeight))
|
||||
player.Context.WaterSurfaceDist < -GetWeaponInfo(player.Control.Weapon.GunType).GunHeight))
|
||||
{
|
||||
player.Control.HandStatus = HandStatus::WeaponUndraw;
|
||||
}
|
||||
|
@ -647,6 +665,7 @@ void HandleWeapon(ItemInfo& laraItem)
|
|||
break;
|
||||
|
||||
case HandStatus::WeaponUndraw:
|
||||
ClearPlayerTargets(laraItem);
|
||||
laraItem.Model.MeshIndex[LM_HEAD] = laraItem.Model.BaseMesh + LM_HEAD;
|
||||
|
||||
switch (player.Control.Weapon.GunType)
|
||||
|
@ -791,7 +810,7 @@ FireWeaponType FireWeapon(LaraWeaponType weaponType, ItemInfo& targetEntity, Ite
|
|||
if (!ammo.HasInfinite())
|
||||
ammo--;
|
||||
|
||||
const auto& weapon = Weapons[(int)weaponType];
|
||||
const auto& weapon = GetWeaponInfo(weaponType);
|
||||
|
||||
auto wobbledArmOrient = EulerAngles(
|
||||
armOrient.x + (Random::GenerateAngle(0, ANGLE(180.0f)) - ANGLE(90.0f)) * weapon.ShotAccuracy / 65536,
|
||||
|
|
|
@ -48,11 +48,12 @@ extern WeaponInfo Weapons[(int)LaraWeaponType::NumWeapons];
|
|||
|
||||
void InitializeNewWeapon(ItemInfo& laraItem);
|
||||
|
||||
Ammo& GetAmmo(LaraInfo& lara, LaraWeaponType weaponType);
|
||||
GameVector GetTargetPoint(ItemInfo& targetEntity);
|
||||
HolsterSlot GetWeaponHolsterSlot(LaraWeaponType weaponType);
|
||||
GAME_OBJECT_ID GetWeaponObjectID(LaraWeaponType weaponType);
|
||||
GAME_OBJECT_ID GetWeaponObjectMeshID(ItemInfo& laraItem, LaraWeaponType weaponType);
|
||||
const WeaponInfo& GetWeaponInfo(LaraWeaponType weaponType);
|
||||
Ammo& GetAmmo(LaraInfo& lara, LaraWeaponType weaponType);
|
||||
GameVector GetTargetPoint(ItemInfo& targetEntity);
|
||||
HolsterSlot GetWeaponHolsterSlot(LaraWeaponType weaponType);
|
||||
GAME_OBJECT_ID GetWeaponObjectID(LaraWeaponType weaponType);
|
||||
GAME_OBJECT_ID GetWeaponObjectMeshID(ItemInfo& laraItem, LaraWeaponType weaponType);
|
||||
|
||||
void HandleWeapon(ItemInfo& laraItem);
|
||||
void AimWeapon(ItemInfo& laraItem, ArmInfo& arm, const WeaponInfo& weaponInfo);
|
||||
|
|
|
@ -211,6 +211,8 @@ enum LaraState
|
|||
// 174-188 reserved for "true" ladders. -- Sezz 2023.04.16
|
||||
|
||||
LS_REMOVE_PUZZLE = 189,
|
||||
LS_RESERVED_PUSHABLE_STATE = 190,
|
||||
LS_SPRINT_SLIDE = 191,
|
||||
|
||||
NUM_LARA_STATES
|
||||
};
|
||||
|
|
|
@ -33,17 +33,16 @@ struct WeaponAnimData
|
|||
|
||||
static WeaponAnimData GetWeaponAnimData(LaraWeaponType weaponType)
|
||||
{
|
||||
static const auto DEFAULT_WEAPON_ANIM_DATA = WeaponAnimData{ ID_LARA, 0, 0, 0, 0 };
|
||||
static const auto ANIM_DATA_MAP = std::unordered_map<LaraWeaponType, WeaponAnimData>
|
||||
static const auto ANIM_DATA_MAP = std::unordered_map<LaraWeaponType, WeaponAnimData>
|
||||
{
|
||||
{ LaraWeaponType::None, WeaponAnimData{ ID_LARA, 0, 0, 0, 0 } },
|
||||
{ LaraWeaponType::Pistol, WeaponAnimData{ ID_PISTOLS_ANIM, 4, 5, 13, 24 } },
|
||||
{ LaraWeaponType::Revolver, WeaponAnimData{ ID_REVOLVER_ANIM , 7, 8, 15, 29 } },
|
||||
{ LaraWeaponType::Uzi, WeaponAnimData{ ID_UZI_ANIM, 4, 5, 13, 24 } }
|
||||
};
|
||||
|
||||
|
||||
auto it = ANIM_DATA_MAP.find(weaponType);
|
||||
return ((it != ANIM_DATA_MAP.end()) ? it->second : DEFAULT_WEAPON_ANIM_DATA);
|
||||
return ((it != ANIM_DATA_MAP.end()) ? it->second : ANIM_DATA_MAP.at(LaraWeaponType::None));
|
||||
}
|
||||
|
||||
static Vector3i GetWeaponSmokeRelOffset(LaraWeaponType weaponType, bool isRightWeapon)
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "Game/effects/debris.h"
|
||||
#include "Game/effects/Blood.h"
|
||||
#include "Game/effects/Bubble.h"
|
||||
#include "Game/effects/DisplaySprite.h"
|
||||
#include "Game/effects/Drip.h"
|
||||
#include "Game/effects/effects.h"
|
||||
#include "Game/effects/Electricity.h"
|
||||
|
@ -62,6 +63,7 @@ using namespace std::chrono;
|
|||
using namespace TEN::Effects;
|
||||
using namespace TEN::Effects::Blood;
|
||||
using namespace TEN::Effects::Bubble;
|
||||
using namespace TEN::Effects::DisplaySprite;
|
||||
using namespace TEN::Effects::Drip;
|
||||
using namespace TEN::Effects::Electricity;
|
||||
using namespace TEN::Effects::Environment;
|
||||
|
@ -118,6 +120,9 @@ int DrawPhase(bool isTitle)
|
|||
g_Renderer.Render();
|
||||
}
|
||||
|
||||
// Clear display sprites.
|
||||
ClearDisplaySprites();
|
||||
|
||||
Camera.numberFrames = g_Renderer.Synchronize();
|
||||
return Camera.numberFrames;
|
||||
}
|
||||
|
@ -416,6 +421,7 @@ void CleanUp()
|
|||
StreamerEffect.Clear();
|
||||
ClearUnderwaterBloodParticles();
|
||||
ClearBubbles();
|
||||
ClearDisplaySprites();
|
||||
ClearFootprints();
|
||||
ClearDrips();
|
||||
ClearRipples();
|
||||
|
|
38
TombEngine/Game/effects/DisplaySprite.cpp
Normal file
38
TombEngine/Game/effects/DisplaySprite.cpp
Normal file
|
@ -0,0 +1,38 @@
|
|||
#include "framework.h"
|
||||
#include "Game/effects/DisplaySprite.h"
|
||||
|
||||
#include "Game/effects/effects.h"
|
||||
#include "Game/Setup.h"
|
||||
#include "Math/Math.h"
|
||||
#include "Objects/objectslist.h"
|
||||
#include "Renderer/Renderer11.h"
|
||||
|
||||
using namespace TEN::Math;
|
||||
|
||||
namespace TEN::Effects::DisplaySprite
|
||||
{
|
||||
std::vector<DisplaySprite> DisplaySprites = {};
|
||||
|
||||
void AddDisplaySprite(GAME_OBJECT_ID objectID, int spriteID, const Vector2& pos, short orient, const Vector2& scale, const Vector4& color,
|
||||
int priority, DisplaySpriteAlignMode alignMode, DisplaySpriteScaleMode scaleMode, BLEND_MODES blendMode)
|
||||
{
|
||||
auto displaySprite = DisplaySprite{};
|
||||
displaySprite.ObjectID = objectID;
|
||||
displaySprite.SpriteID = spriteID;
|
||||
displaySprite.Position = pos;
|
||||
displaySprite.Orientation = orient;
|
||||
displaySprite.Scale = scale;
|
||||
displaySprite.Color = color;
|
||||
displaySprite.Priority = priority;
|
||||
displaySprite.AlignMode = alignMode;
|
||||
displaySprite.ScaleMode = scaleMode;
|
||||
displaySprite.BlendMode = blendMode;
|
||||
|
||||
DisplaySprites.push_back(displaySprite);
|
||||
}
|
||||
|
||||
void ClearDisplaySprites()
|
||||
{
|
||||
DisplaySprites.clear();
|
||||
}
|
||||
}
|
48
TombEngine/Game/effects/DisplaySprite.h
Normal file
48
TombEngine/Game/effects/DisplaySprite.h
Normal file
|
@ -0,0 +1,48 @@
|
|||
#pragma once
|
||||
#include "Objects/game_object_ids.h"
|
||||
#include "Renderer/Renderer11Enums.h"
|
||||
|
||||
namespace TEN::Effects::DisplaySprite
|
||||
{
|
||||
enum class DisplaySpriteAlignMode
|
||||
{
|
||||
Center,
|
||||
CenterTop,
|
||||
CenterBottom,
|
||||
CenterLeft,
|
||||
CenterRight,
|
||||
TopLeft,
|
||||
TopRight,
|
||||
BottomLeft,
|
||||
BottomRight
|
||||
};
|
||||
|
||||
enum class DisplaySpriteScaleMode
|
||||
{
|
||||
Fit,
|
||||
Fill,
|
||||
Stretch
|
||||
};
|
||||
|
||||
struct DisplaySprite
|
||||
{
|
||||
GAME_OBJECT_ID ObjectID = ID_DEFAULT_SPRITES;
|
||||
int SpriteID = 0;
|
||||
|
||||
Vector2 Position = Vector2::Zero;
|
||||
short Orientation = 0;
|
||||
Vector2 Scale = Vector2::One;
|
||||
Vector4 Color = Vector4::One;
|
||||
|
||||
int Priority = 0;
|
||||
DisplaySpriteAlignMode AlignMode = DisplaySpriteAlignMode::Center;
|
||||
DisplaySpriteScaleMode ScaleMode = DisplaySpriteScaleMode::Fit;
|
||||
BLEND_MODES BlendMode = BLENDMODE_ALPHABLEND;
|
||||
};
|
||||
|
||||
extern std::vector<DisplaySprite> DisplaySprites;
|
||||
|
||||
void AddDisplaySprite(GAME_OBJECT_ID objectID, int spriteID, const Vector2& pos, short orient, const Vector2& scale, const Vector4& color,
|
||||
int priority, DisplaySpriteAlignMode alignMode, DisplaySpriteScaleMode scaleMode, BLEND_MODES blendMode);
|
||||
void ClearDisplaySprites();
|
||||
}
|
|
@ -181,7 +181,7 @@ namespace TEN::Gui
|
|||
return false;
|
||||
|
||||
// Avoid Select or Action release interference when entering inventory.
|
||||
if (GetActionTimeActive(In::Select) < TimeInMenu || GetActionTimeActive(In::Action) < TimeInMenu)
|
||||
if (GetActionTimeActive(In::Select) < TimeInMenu && GetActionTimeActive(In::Action) < TimeInMenu)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
@ -871,14 +871,16 @@ namespace TEN::Gui
|
|||
MusicVolume,
|
||||
SfxVolume,
|
||||
Subtitles,
|
||||
AutoTarget,
|
||||
AutoTargeting,
|
||||
TargetHighlighter,
|
||||
ToggleRumble,
|
||||
ThumbstickCameraControl,
|
||||
|
||||
Apply,
|
||||
Cancel
|
||||
};
|
||||
|
||||
static const int numOtherSettingsOptions = 8;
|
||||
static const int numOtherSettingsOptions = 9;
|
||||
|
||||
OptionCount = numOtherSettingsOptions;
|
||||
|
||||
|
@ -903,11 +905,21 @@ namespace TEN::Gui
|
|||
CurrentSettings.Configuration.EnableReverb = !CurrentSettings.Configuration.EnableReverb;
|
||||
break;
|
||||
|
||||
case OtherSettingsOption::AutoTarget:
|
||||
case OtherSettingsOption::Subtitles:
|
||||
SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always);
|
||||
CurrentSettings.Configuration.EnableSubtitles = !CurrentSettings.Configuration.EnableSubtitles;
|
||||
break;
|
||||
|
||||
case OtherSettingsOption::AutoTargeting:
|
||||
SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always);
|
||||
CurrentSettings.Configuration.EnableAutoTargeting = !CurrentSettings.Configuration.EnableAutoTargeting;
|
||||
break;
|
||||
|
||||
case OtherSettingsOption::TargetHighlighter:
|
||||
SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always);
|
||||
CurrentSettings.Configuration.EnableTargetHighlighter = !CurrentSettings.Configuration.EnableTargetHighlighter;
|
||||
break;
|
||||
|
||||
case OtherSettingsOption::ToggleRumble:
|
||||
SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always);
|
||||
CurrentSettings.Configuration.EnableRumble = !CurrentSettings.Configuration.EnableRumble;
|
||||
|
@ -917,11 +929,6 @@ namespace TEN::Gui
|
|||
SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always);
|
||||
CurrentSettings.Configuration.EnableThumbstickCamera = !CurrentSettings.Configuration.EnableThumbstickCamera;
|
||||
break;
|
||||
|
||||
case OtherSettingsOption::Subtitles:
|
||||
SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always);
|
||||
CurrentSettings.Configuration.EnableSubtitles = !CurrentSettings.Configuration.EnableSubtitles;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2710,7 +2717,7 @@ namespace TEN::Gui
|
|||
|
||||
if (AmmoObjectList[n].Amount == -1)
|
||||
{
|
||||
sprintf(&invTextBuffer[0], "Unlimited %s", g_GameFlow->GetString(InventoryObjectTable[AmmoObjectList[n].InventoryItem].ObjectName));
|
||||
sprintf(&invTextBuffer[0], g_GameFlow->GetString(STRING_UNLIMITED), g_GameFlow->GetString(InventoryObjectTable[AmmoObjectList[n].InventoryItem].ObjectName));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -3033,7 +3040,7 @@ namespace TEN::Gui
|
|||
{
|
||||
if (numItems == -1)
|
||||
{
|
||||
sprintf(textBuffer, "Unlimited %s", g_GameFlow->GetString(invObject.ObjectName));
|
||||
sprintf(textBuffer, g_GameFlow->GetString(STRING_UNLIMITED), g_GameFlow->GetString(invObject.ObjectName));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -827,6 +827,9 @@ void RegeneratePickups()
|
|||
case ID_SHOTGUN_AMMO2_ITEM:
|
||||
ammo = lara->Weapons[(int)LaraWeaponType::Shotgun].Ammo[(int)WeaponAmmoType::Ammo2];
|
||||
break;
|
||||
|
||||
default:
|
||||
continue; // Don't regenerate anything but ammo.
|
||||
}
|
||||
|
||||
if (ammo == 0)
|
||||
|
|
|
@ -70,7 +70,7 @@ void SaveGame::LoadSavegameInfos()
|
|||
// Try loading savegame.
|
||||
for (int i = 0; i < SAVEGAME_MAX; i++)
|
||||
{
|
||||
if (!DoesSaveGameExist(i))
|
||||
if (!DoesSaveGameExist(i, true))
|
||||
continue;
|
||||
|
||||
SavegameInfos[i].Present = true;
|
||||
|
@ -175,11 +175,13 @@ bool SaveGame::IsSaveGameSlotValid(int slot)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool SaveGame::DoesSaveGameExist(int slot)
|
||||
bool SaveGame::DoesSaveGameExist(int slot, bool silent)
|
||||
{
|
||||
if (!std::filesystem::is_regular_file(GetSavegameFilename(slot)))
|
||||
{
|
||||
TENLog("Attempted to access missing savegame slot " + std::to_string(slot), LogLevel::Warning);
|
||||
if (!silent)
|
||||
TENLog("Attempted to access missing savegame slot " + std::to_string(slot), LogLevel::Warning);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -60,5 +60,5 @@ public:
|
|||
static void LoadSavegameInfos();
|
||||
static void Delete(int slot);
|
||||
|
||||
static bool DoesSaveGameExist(int slot);
|
||||
static bool DoesSaveGameExist(int slot, bool silent = false);
|
||||
};
|
||||
|
|
|
@ -72,7 +72,7 @@ namespace TEN::Entities::Creatures::TR2
|
|||
InitializeItem(skidooItemNumber); g_Level.NumItems++;
|
||||
|
||||
// Register snowmobile gun for driver to control.
|
||||
riderItem.Data = skidooItemNumber;
|
||||
riderItem.ItemFlags[0] = skidooItemNumber;
|
||||
}
|
||||
|
||||
void InitializeSkidooMan(short itemNumber)
|
||||
|
@ -118,17 +118,17 @@ namespace TEN::Entities::Creatures::TR2
|
|||
void SkidooManControl(short riderItemNumber)
|
||||
{
|
||||
auto& riderItem = g_Level.Items[riderItemNumber];
|
||||
if (!riderItem.Data)
|
||||
if (!riderItem.ItemFlags[0])
|
||||
{
|
||||
// Create snowmobile.
|
||||
CreateSkidooGun(riderItem);
|
||||
if (!riderItem.Data)
|
||||
if (!riderItem.ItemFlags[0])
|
||||
TENLog("Skidoo rider data does not contain skidoo item ID.", LogLevel::Error);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int skidooItemNumber = (short)riderItem.Data;
|
||||
int skidooItemNumber = (short)riderItem.ItemFlags[0];
|
||||
auto* skidooItem = &g_Level.Items[skidooItemNumber];
|
||||
|
||||
if (!skidooItem->Data)
|
||||
|
|
|
@ -994,6 +994,8 @@ enum GAME_OBJECT_ID : short
|
|||
ID_AIR_BAR_TEXTURE,
|
||||
ID_DASH_BAR_TEXTURE,
|
||||
ID_SFX_BAR_TEXTURE,
|
||||
// NOTE: 1378 - 1379 reserved for blood effects. -- Sezz 2023.05.29
|
||||
ID_CROSSHAIR = 1380,
|
||||
|
||||
ID_PANEL_BORDER = 1400,
|
||||
ID_PANEL_MIDDLE,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "framework.h"
|
||||
#include "RenderView.h"
|
||||
#include "Renderer/RenderView/RenderView.h"
|
||||
|
||||
namespace TEN::Renderer
|
||||
{
|
||||
|
@ -46,6 +46,7 @@ namespace TEN::Renderer
|
|||
RoomsToDraw.clear();
|
||||
LightsToDraw.clear();
|
||||
SpritesToDraw.clear();
|
||||
DisplaySpritesToDraw.clear();
|
||||
SortedStaticsToDraw.clear();
|
||||
FogBulbsToDraw.clear();
|
||||
}
|
||||
|
|
|
@ -1,15 +1,12 @@
|
|||
#pragma once
|
||||
#include <vector>
|
||||
#include <d3d11.h>
|
||||
#include <SimpleMath.h>
|
||||
|
||||
#include "Game/camera.h"
|
||||
#include "Renderer/Frustum.h"
|
||||
#include "Renderer/ConstantBuffers/CameraMatrixBuffer.h"
|
||||
#include "Renderer/Frustum.h"
|
||||
#include "Specific/memory/LinearArrayBuffer.h"
|
||||
#include "Renderer/RendererSprite2D.h"
|
||||
#include "Renderer/RendererSprites.h"
|
||||
#include "Renderer/RendererTransparentFace.h"
|
||||
#include "Renderer/Structures/RendererFogBulb.h"
|
||||
#include "Specific/memory/LinearArrayBuffer.h"
|
||||
|
||||
namespace TEN::Renderer
|
||||
{
|
||||
|
@ -19,6 +16,7 @@ namespace TEN::Renderer
|
|||
struct RendererEffect;
|
||||
struct RendererRoom;
|
||||
struct RendererTransparentFace;
|
||||
|
||||
constexpr auto MAX_ROOMS_DRAW = 256;
|
||||
constexpr auto MAX_STATICS_DRAW = 128;
|
||||
constexpr auto MAX_EFFECTS_DRAW = 16;
|
||||
|
@ -26,9 +24,6 @@ namespace TEN::Renderer
|
|||
constexpr auto MAX_LIGHTS_DRAW = 48;
|
||||
constexpr auto MAX_FOG_BULBS_DRAW = 32;
|
||||
constexpr auto MAX_SPRITES_DRAW = 512;
|
||||
using DirectX::SimpleMath::Vector3;
|
||||
using DirectX::SimpleMath::Vector2;
|
||||
using DirectX::SimpleMath::Matrix;
|
||||
|
||||
struct RenderViewCamera
|
||||
{
|
||||
|
@ -51,15 +46,18 @@ namespace TEN::Renderer
|
|||
struct RenderView
|
||||
{
|
||||
RenderViewCamera Camera;
|
||||
D3D11_VIEWPORT Viewport;
|
||||
std::vector<RendererRoom*> RoomsToDraw;
|
||||
std::vector<RendererLight*> LightsToDraw;
|
||||
std::vector<RendererFogBulb> FogBulbsToDraw;
|
||||
std::vector<RendererSpriteToDraw> SpritesToDraw;
|
||||
std::map<int, std::vector<RendererStatic*>> SortedStaticsToDraw;
|
||||
D3D11_VIEWPORT Viewport;
|
||||
|
||||
std::vector<RendererRoom*> RoomsToDraw = {};
|
||||
std::vector<RendererLight*> LightsToDraw = {};
|
||||
std::vector<RendererFogBulb> FogBulbsToDraw = {};
|
||||
std::vector<RendererSpriteToDraw> SpritesToDraw = {};
|
||||
std::vector<RendererDisplaySpriteToDraw> DisplaySpritesToDraw = {};
|
||||
std::map<int, std::vector<RendererStatic*>> SortedStaticsToDraw = {};
|
||||
|
||||
RenderView(CAMERA_INFO* cam, float roll, float fov, float nearPlane, float farPlane, int w, int h);
|
||||
RenderView(const Vector3& pos, const Vector3& dir, const Vector3& up, int w, int h, int room, float nearPlane, float farPlane, float fov);
|
||||
|
||||
void fillConstantBuffer(CCameraMatrixBuffer& bufferToFill);
|
||||
void clear();
|
||||
};
|
||||
|
|
|
@ -555,9 +555,10 @@ namespace TEN::Renderer
|
|||
void DrawEffect(RenderView& view, RendererEffect* effect, RendererPass rendererPass);
|
||||
void DrawSplashes(RenderView& view);
|
||||
void DrawSprites(RenderView& view);
|
||||
void DrawDisplaySprites(RenderView& view);
|
||||
void DrawSortedFaces(RenderView& view);
|
||||
void DrawLines3D(RenderView& view);
|
||||
void DrawLines2D();
|
||||
void DrawLinesIn2DSpace();
|
||||
void DrawOverlays(RenderView& view);
|
||||
void DrawRopes(RenderView& view);
|
||||
void DrawBats(RenderView& view);
|
||||
|
@ -745,8 +746,9 @@ namespace TEN::Renderer
|
|||
std::optional<Vector2> Get2DPosition(const Vector3& pos) const;
|
||||
Vector3 GetAbsEntityBonePosition(int itemNumber, int jointIndex, const Vector3& relOffset = Vector3::Zero);
|
||||
|
||||
void DrawSpriteIn2DSpace(GAME_OBJECT_ID spriteID, unsigned int spriteIndex, const Vector2& pos2D, short orient2D,
|
||||
const Vector4& color, const Vector2& size);
|
||||
void AddDisplaySprite(const RendererSprite& sprite, const Vector2& pos2D, short orient, const Vector2& size, const Vector4& color,
|
||||
int priority, BLEND_MODES blendMode, const Vector2& aspectCorrection, RenderView& renderView);
|
||||
void CollectDisplaySprites(RenderView& renderView);
|
||||
};
|
||||
|
||||
extern Renderer11 g_Renderer;
|
||||
|
|
|
@ -164,8 +164,8 @@ namespace TEN::Renderer
|
|||
m_spritesTextures.resize(g_Level.SpritesTextures.size());
|
||||
for (int i = 0; i < g_Level.SpritesTextures.size(); i++)
|
||||
{
|
||||
TEXTURE *texture = &g_Level.SpritesTextures[i];
|
||||
m_spritesTextures[i] = Texture2D(m_device.Get(), texture->colorMapData.data(), (int)texture->colorMapData.size());
|
||||
auto& texture = g_Level.SpritesTextures[i];
|
||||
m_spritesTextures[i] = Texture2D(m_device.Get(), texture.colorMapData.data(), (int)texture.colorMapData.size());
|
||||
}
|
||||
|
||||
if (m_spritesTextures.size() > 0)
|
||||
|
|
|
@ -372,7 +372,7 @@ namespace TEN::Renderer
|
|||
}
|
||||
}
|
||||
|
||||
void Renderer11::DrawLines2D()
|
||||
void Renderer11::DrawLinesIn2DSpace()
|
||||
{
|
||||
SetBlendMode(BLENDMODE_OPAQUE);
|
||||
SetDepthState(DEPTH_STATE_READ_ONLY_ZBUFFER);
|
||||
|
@ -539,9 +539,7 @@ namespace TEN::Renderer
|
|||
void Renderer11::DrawBats(RenderView& view)
|
||||
{
|
||||
if (!Objects[ID_BATS_EMITTER].loaded)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RendererMesh* mesh = GetMesh(Objects[ID_BATS_EMITTER].meshIndex + (GlobalCounter & 3));
|
||||
|
||||
|
@ -607,47 +605,43 @@ namespace TEN::Renderer
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Renderer11::DrawScarabs(RenderView& view)
|
||||
{
|
||||
if (!Objects[ID_LITTLE_BEETLE].loaded)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RendererMesh* mesh = GetMesh(Objects[ID_LITTLE_BEETLE].meshIndex + ((Wibble >> 2) % 2));
|
||||
|
||||
int littleBeetlesCount = 0;
|
||||
const auto& mesh = *GetMesh(Objects[ID_LITTLE_BEETLE].meshIndex + ((Wibble >> 2) % 2));
|
||||
|
||||
unsigned int beetleCount = 0;
|
||||
for (int i = 0; i < TEN::Entities::TR4::NUM_BEETLES; i++)
|
||||
{
|
||||
auto* beetle = &TEN::Entities::TR4::BeetleSwarm[i];
|
||||
const auto& beetle = TEN::Entities::TR4::BeetleSwarm[i];
|
||||
|
||||
if (beetle->On)
|
||||
if (beetle.On)
|
||||
{
|
||||
RendererRoom& room = m_rooms[beetle->RoomNumber];
|
||||
auto& room = m_rooms[beetle.RoomNumber];
|
||||
|
||||
Matrix translation = Matrix::CreateTranslation(beetle->Pose.Position.x, beetle->Pose.Position.y, beetle->Pose.Position.z);
|
||||
Matrix rotation = beetle->Pose.Orientation.ToRotationMatrix();
|
||||
Matrix world = rotation * translation;
|
||||
auto tMatrix = Matrix::CreateTranslation(beetle.Pose.Position.x, beetle.Pose.Position.y, beetle.Pose.Position.z);
|
||||
auto rotMatrix = beetle.Pose.Orientation.ToRotationMatrix();
|
||||
auto worldMatrix = rotMatrix * tMatrix;
|
||||
|
||||
m_stInstancedStaticMeshBuffer.StaticMeshes[littleBeetlesCount].World = world;
|
||||
m_stInstancedStaticMeshBuffer.StaticMeshes[littleBeetlesCount].Ambient = room.AmbientLight;
|
||||
m_stInstancedStaticMeshBuffer.StaticMeshes[littleBeetlesCount].Color = Vector4::One;
|
||||
m_stInstancedStaticMeshBuffer.StaticMeshes[littleBeetlesCount].LightMode = mesh->LightMode;
|
||||
BindInstancedStaticLights(room.LightsToDraw, littleBeetlesCount);
|
||||
m_stInstancedStaticMeshBuffer.StaticMeshes[beetleCount].World = worldMatrix;
|
||||
m_stInstancedStaticMeshBuffer.StaticMeshes[beetleCount].Ambient = room.AmbientLight;
|
||||
m_stInstancedStaticMeshBuffer.StaticMeshes[beetleCount].Color = Vector4::One;
|
||||
m_stInstancedStaticMeshBuffer.StaticMeshes[beetleCount].LightMode = mesh.LightMode;
|
||||
BindInstancedStaticLights(room.LightsToDraw, beetleCount);
|
||||
|
||||
littleBeetlesCount++;
|
||||
beetleCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (littleBeetlesCount > 0)
|
||||
if (beetleCount > 0)
|
||||
{
|
||||
m_context->VSSetShader(m_vsInstancedStaticMeshes.Get(), nullptr, 0);
|
||||
m_context->PSSetShader(m_psInstancedStaticMeshes.Get(), nullptr, 0);
|
||||
|
||||
UINT stride = sizeof(RendererVertex);
|
||||
UINT offset = 0;
|
||||
unsigned int stride = sizeof(RendererVertex);
|
||||
unsigned int offset = 0;
|
||||
|
||||
m_context->IASetVertexBuffers(0, 1, m_moveablesVertexBuffer.Buffer.GetAddressOf(), &stride, &offset);
|
||||
m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
|
@ -661,19 +655,17 @@ namespace TEN::Renderer
|
|||
BindConstantBufferVS(CB_INSTANCED_STATICS, m_cbInstancedStaticMeshBuffer.get());
|
||||
BindConstantBufferPS(CB_INSTANCED_STATICS, m_cbInstancedStaticMeshBuffer.get());
|
||||
|
||||
for (auto& bucket : mesh->Buckets)
|
||||
for (const auto& bucket : mesh.Buckets)
|
||||
{
|
||||
if (bucket.NumVertices == 0 && bucket.BlendMode == BLEND_MODES::BLENDMODE_OPAQUE)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
SetBlendMode(bucket.BlendMode);
|
||||
|
||||
BindTexture(TEXTURE_COLOR_MAP, &std::get<0>(m_moveablesTextures[bucket.Texture]), SAMPLER_ANISOTROPIC_CLAMP);
|
||||
BindTexture(TEXTURE_NORMAL_MAP, &std::get<1>(m_moveablesTextures[bucket.Texture]), SAMPLER_NONE);
|
||||
|
||||
DrawIndexedInstancedTriangles(bucket.NumIndices, littleBeetlesCount, bucket.StartIndex, 0);
|
||||
DrawIndexedInstancedTriangles(bucket.NumIndices, beetleCount, bucket.StartIndex, 0);
|
||||
|
||||
m_numStaticsDrawCalls++;
|
||||
}
|
||||
|
@ -1418,15 +1410,15 @@ namespace TEN::Renderer
|
|||
|
||||
void Renderer11::RenderScene(ID3D11RenderTargetView* target, ID3D11DepthStencilView* depthTarget, RenderView& view)
|
||||
{
|
||||
ResetDebugVariables();
|
||||
m_Locked = false;
|
||||
|
||||
using ns = std::chrono::nanoseconds;
|
||||
using get_time = std::chrono::steady_clock;
|
||||
|
||||
ScriptInterfaceLevel* level = g_GameFlow->GetLevel(CurrentLevel);
|
||||
ResetDebugVariables();
|
||||
m_Locked = false;
|
||||
|
||||
auto& level = *g_GameFlow->GetLevel(CurrentLevel);
|
||||
|
||||
// Prepare the scene to draw
|
||||
// Prepare scene to draw.
|
||||
auto time1 = std::chrono::high_resolution_clock::now();
|
||||
CollectRooms(view, false);
|
||||
auto timeRoomsCollector = std::chrono::high_resolution_clock::now();
|
||||
|
@ -1446,39 +1438,38 @@ namespace TEN::Renderer
|
|||
m_timeUpdate = (std::chrono::duration_cast<ns>(time2 - time1)).count() / 1000000;
|
||||
time1 = time2;
|
||||
|
||||
// Reset GPU state
|
||||
// Reset GPU state.
|
||||
SetBlendMode(BLENDMODE_OPAQUE, true);
|
||||
SetDepthState(DEPTH_STATE_WRITE_ZBUFFER, true);
|
||||
SetCullMode(CULL_MODE_CCW, true);
|
||||
|
||||
// Bind and clear render target
|
||||
// Bind and clear render target.
|
||||
m_context->ClearRenderTargetView(m_renderTarget.RenderTargetView.Get(), Colors::Black);
|
||||
m_context->ClearDepthStencilView(m_renderTarget.DepthStencilView.Get(), D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
|
||||
|
||||
m_context->ClearRenderTargetView(m_depthMap.RenderTargetView.Get(), Colors::White);
|
||||
m_context->ClearDepthStencilView(m_depthMap.DepthStencilView.Get(), D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
|
||||
|
||||
ID3D11RenderTargetView* m_pRenderViews[2];
|
||||
m_pRenderViews[0] = m_renderTarget.RenderTargetView.Get();
|
||||
m_pRenderViews[1] = m_depthMap.RenderTargetView.Get();
|
||||
m_context->OMSetRenderTargets(2, &m_pRenderViews[0], m_renderTarget.DepthStencilView.Get());
|
||||
ID3D11RenderTargetView* pRenderViewPtrs[2];
|
||||
pRenderViewPtrs[0] = m_renderTarget.RenderTargetView.Get();
|
||||
pRenderViewPtrs[1] = m_depthMap.RenderTargetView.Get();
|
||||
m_context->OMSetRenderTargets(2, &pRenderViewPtrs[0], m_renderTarget.DepthStencilView.Get());
|
||||
|
||||
m_context->RSSetViewports(1, &view.Viewport);
|
||||
ResetScissor();
|
||||
|
||||
// The camera constant buffer contains matrices, camera position, fog values and other
|
||||
// things that are shared for all shaders
|
||||
// Camera constant buffer contains matrices, camera position, fog values, and other things that are shared for all shaders.
|
||||
CCameraMatrixBuffer cameraConstantBuffer;
|
||||
view.fillConstantBuffer(cameraConstantBuffer);
|
||||
cameraConstantBuffer.Frame = GlobalCounter;
|
||||
cameraConstantBuffer.CameraUnderwater = g_Level.Rooms[cameraConstantBuffer.RoomNumber].flags & ENV_FLAG_WATER;
|
||||
|
||||
if (level->GetFogEnabled())
|
||||
if (level.GetFogEnabled())
|
||||
{
|
||||
auto fogCol = level->GetFogColor();
|
||||
cameraConstantBuffer.FogColor = Vector4(fogCol.GetR() / 255.0f, fogCol.GetG() / 255.0f, fogCol.GetB() / 255.0f, 1.0f);
|
||||
cameraConstantBuffer.FogMinDistance = level->GetFogMinDistance();
|
||||
cameraConstantBuffer.FogMaxDistance = level->GetFogMaxDistance();
|
||||
auto fogColor = level.GetFogColor();
|
||||
cameraConstantBuffer.FogColor = Vector4(fogColor.GetR() / 255.0f, fogColor.GetG() / 255.0f, fogColor.GetB() / 255.0f, 1.0f);
|
||||
cameraConstantBuffer.FogMinDistance = level.GetFogMinDistance();
|
||||
cameraConstantBuffer.FogMaxDistance = level.GetFogMaxDistance();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1502,10 +1493,10 @@ namespace TEN::Renderer
|
|||
BindConstantBufferVS(CB_CAMERA, m_cbCameraMatrices.get());
|
||||
BindConstantBufferPS(CB_CAMERA, m_cbCameraMatrices.get());
|
||||
|
||||
// Draw the horizon and the sky
|
||||
// Draw horizon and sky.
|
||||
DrawHorizonAndSky(view, m_renderTarget.DepthStencilView.Get());
|
||||
|
||||
// Draw opaque and alpha test faces
|
||||
// Draw opaque and alpha faces.
|
||||
DrawRooms(view, RendererPass::Opaque);
|
||||
DrawItems(view, RendererPass::Opaque);
|
||||
DrawStatics(view, RendererPass::Opaque);
|
||||
|
@ -1518,11 +1509,10 @@ namespace TEN::Renderer
|
|||
DrawLocusts(view);
|
||||
DrawDebris(view, RendererPass::Opaque);
|
||||
|
||||
m_context->OMSetRenderTargets(1, m_renderTarget.RenderTargetView.GetAddressOf(),
|
||||
m_renderTarget.DepthStencilView.Get());
|
||||
m_context->OMSetRenderTargets(1, m_renderTarget.RenderTargetView.GetAddressOf(), m_renderTarget.DepthStencilView.Get());
|
||||
|
||||
// Do special effects and weather
|
||||
// NOTE: functions here just fill the sprites to draw array
|
||||
// Prepare special effects and weather.
|
||||
// NOTE: Functions here merely fill array of sprites to draw.
|
||||
DrawFires(view);
|
||||
DrawSmokes(view);
|
||||
DrawSmokeParticles(view);
|
||||
|
@ -1545,11 +1535,19 @@ namespace TEN::Renderer
|
|||
DrawStreamers(view);
|
||||
DrawLaserBarriers(view);
|
||||
|
||||
// Here is where we actually output sprites
|
||||
// Output sprites.
|
||||
DrawSprites(view);
|
||||
DrawLines3D(view);
|
||||
|
||||
// Draw immediately additive and unsorted blended faces, and collect all sorted blend modes faces for later
|
||||
// Collect all sorted blend modes faces for later.
|
||||
DrawRooms(view, RendererPass::CollectSortedFaces);
|
||||
DrawItems(view, RendererPass::CollectSortedFaces);
|
||||
DrawStatics(view, RendererPass::CollectSortedFaces);
|
||||
|
||||
// Draw all sorted blend mode faces collected in previous steps.
|
||||
DrawSortedFaces(view);
|
||||
|
||||
// Draw immediate transparent faces (i.e. additive)
|
||||
DrawRooms(view, RendererPass::Transparent);
|
||||
DrawItems(view, RendererPass::Transparent);
|
||||
DrawStatics(view, RendererPass::Transparent);
|
||||
|
@ -1558,18 +1556,20 @@ namespace TEN::Renderer
|
|||
DrawGunFlashes(view);
|
||||
DrawBaddyGunflashes(view);
|
||||
|
||||
// Draw all sorted blend mode faces collected in the previous steps
|
||||
DrawSortedFaces(view);
|
||||
|
||||
// Draw post-process effects (cinematic bars, fade, flash, HDR, tone mapping, etc.).
|
||||
DrawPostprocess(target, depthTarget, view);
|
||||
|
||||
// Draw GUI stuff at the end
|
||||
DrawLines2D();
|
||||
// Draw GUI elements at end.
|
||||
DrawLinesIn2DSpace();
|
||||
|
||||
// Draw HUD.
|
||||
g_Hud.Draw(*LaraItem);
|
||||
|
||||
// Draw binoculars or lasersight
|
||||
// Draw display sprites sorted by priority.
|
||||
CollectDisplaySprites(view);
|
||||
DrawDisplaySprites(view);
|
||||
|
||||
// Draw binoculars or lasersight.
|
||||
DrawOverlays(view);
|
||||
|
||||
time2 = std::chrono::high_resolution_clock::now();
|
||||
|
@ -1876,7 +1876,8 @@ namespace TEN::Renderer
|
|||
|
||||
for (auto& bucket : refMesh->Buckets)
|
||||
{
|
||||
if (!((bucket.BlendMode == BLENDMODE_OPAQUE || bucket.BlendMode == BLENDMODE_ALPHATEST) ^ (rendererPass == RendererPass::Transparent)))
|
||||
if (!((bucket.BlendMode == BLENDMODE_OPAQUE || bucket.BlendMode == BLENDMODE_ALPHATEST) ^
|
||||
(rendererPass == RendererPass::Transparent)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -1898,9 +1899,8 @@ namespace TEN::Renderer
|
|||
{
|
||||
SetBlendMode(bucket.BlendMode);
|
||||
SetAlphaTest(
|
||||
bucket.BlendMode == BLENDMODE_ALPHATEST ? ALPHA_TEST_GREATER_THAN : ALPHA_TEST_NONE,
|
||||
ALPHA_TEST_THRESHOLD
|
||||
);
|
||||
(bucket.BlendMode == BLENDMODE_ALPHATEST) ? ALPHA_TEST_GREATER_THAN : ALPHA_TEST_NONE,
|
||||
ALPHA_TEST_THRESHOLD);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1924,7 +1924,7 @@ namespace TEN::Renderer
|
|||
}
|
||||
|
||||
// Collect sorted blend modes faces ordered by room, if transparent pass
|
||||
if (rendererPass == RendererPass::Transparent)
|
||||
if (rendererPass == RendererPass::CollectSortedFaces)
|
||||
{
|
||||
Vector3 cameraPosition = Vector3(Camera.pos.x, Camera.pos.y, Camera.pos.z);
|
||||
|
||||
|
@ -1940,11 +1940,6 @@ namespace TEN::Renderer
|
|||
|
||||
for (auto& bucket : mesh->Buckets)
|
||||
{
|
||||
if (!((bucket.BlendMode == BLENDMODE_OPAQUE || bucket.BlendMode == BLENDMODE_ALPHATEST) ^ (rendererPass == RendererPass::Transparent)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (bucket.NumVertices == 0)
|
||||
{
|
||||
continue;
|
||||
|
@ -1989,19 +1984,19 @@ namespace TEN::Renderer
|
|||
UINT stride = sizeof(RendererVertex);
|
||||
UINT offset = 0;
|
||||
|
||||
// Bind vertex and index buffer
|
||||
// Bind vertex and index buffer.
|
||||
m_context->IASetVertexBuffers(0, 1, m_roomsVertexBuffer.Buffer.GetAddressOf(), &stride, &offset);
|
||||
m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
m_context->IASetInputLayout(m_inputLayout.Get());
|
||||
m_context->IASetIndexBuffer(m_roomsIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
|
||||
|
||||
// Bind pixel shaders
|
||||
// Bind pixel shaders.
|
||||
m_context->PSSetShader(m_psRooms.Get(), nullptr, 0);
|
||||
|
||||
BindConstantBufferVS(CB_ROOM, m_cbRoom.get());
|
||||
BindConstantBufferPS(CB_ROOM, m_cbRoom.get());
|
||||
|
||||
// Bind caustics texture
|
||||
// Bind caustics texture.
|
||||
if (!m_sprites.empty())
|
||||
{
|
||||
int nmeshes = -Objects[ID_CAUSTICS_TEXTURES].nmeshes;
|
||||
|
@ -2009,13 +2004,13 @@ namespace TEN::Renderer
|
|||
int causticsFrame = std::min(nmeshes ? meshIndex + ((GlobalCounter) % nmeshes) : meshIndex, (int)m_sprites.size());
|
||||
BindTexture(TEXTURE_CAUSTICS, m_sprites[causticsFrame].Texture, SAMPLER_ANISOTROPIC_CLAMP);
|
||||
|
||||
// Strange packing due to particular HLSL 16 bytes alignment requirements
|
||||
// NOTE: Strange packing due to particular HLSL 16 bytes alignment requirements.
|
||||
RendererSprite* causticsSprite = &m_sprites[causticsFrame];
|
||||
m_stRoom.CausticsStartUV = causticsSprite->UV[0];
|
||||
m_stRoom.CausticsScale = Vector2(causticsSprite->Width / (float)causticsSprite->Texture->Width, causticsSprite->Height / (float)causticsSprite->Texture->Height);
|
||||
}
|
||||
|
||||
// Set shadow map data and bind shadow map texture
|
||||
// Set shadow map data and bind shadow map texture.
|
||||
if (m_shadowLight != nullptr)
|
||||
{
|
||||
memcpy(&m_stShadowMap.Light, m_shadowLight, sizeof(ShaderLight));
|
||||
|
@ -2071,14 +2066,15 @@ namespace TEN::Renderer
|
|||
continue;
|
||||
}
|
||||
|
||||
if (!((bucket.BlendMode == BLENDMODE_OPAQUE || bucket.BlendMode == BLENDMODE_ALPHATEST) ^ (rendererPass == RendererPass::Transparent)))
|
||||
if (!((bucket.BlendMode == BLENDMODE_OPAQUE || bucket.BlendMode == BLENDMODE_ALPHATEST) ^
|
||||
(rendererPass == RendererPass::Transparent || rendererPass == RendererPass::CollectSortedFaces)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (DoesBlendModeRequireSorting(bucket.BlendMode))
|
||||
if (rendererPass == RendererPass::CollectSortedFaces && DoesBlendModeRequireSorting(bucket.BlendMode))
|
||||
{
|
||||
// Collect transparent faces
|
||||
// Collect transparent faces.
|
||||
for (int j = 0; j < bucket.Polygons.size(); j++)
|
||||
{
|
||||
RendererPolygon* p = &bucket.Polygons[j];
|
||||
|
@ -2178,20 +2174,20 @@ namespace TEN::Renderer
|
|||
|
||||
void Renderer11::DrawHorizonAndSky(RenderView& renderView, ID3D11DepthStencilView* depthTarget)
|
||||
{
|
||||
ScriptInterfaceLevel* level = g_GameFlow->GetLevel(CurrentLevel);
|
||||
auto* levelPtr = g_GameFlow->GetLevel(CurrentLevel);
|
||||
|
||||
bool anyOutsideRooms = false;
|
||||
for (int k = 0; k < renderView.RoomsToDraw.size(); k++)
|
||||
{
|
||||
ROOM_INFO* nativeRoom = &g_Level.Rooms[renderView.RoomsToDraw[k]->RoomNumber];
|
||||
if (nativeRoom->flags & ENV_FLAG_OUTSIDE)
|
||||
const auto& nativeRoom = g_Level.Rooms[renderView.RoomsToDraw[k]->RoomNumber];
|
||||
if (nativeRoom.flags & ENV_FLAG_OUTSIDE)
|
||||
{
|
||||
anyOutsideRooms = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!level->Horizon || !anyOutsideRooms)
|
||||
if (!levelPtr->Horizon || !anyOutsideRooms)
|
||||
return;
|
||||
|
||||
if (Lara.Control.Look.OpticRange != 0)
|
||||
|
@ -2201,7 +2197,7 @@ namespace TEN::Renderer
|
|||
UINT offset = 0;
|
||||
|
||||
// Draw sky.
|
||||
Matrix rotation = Matrix::CreateRotationX(PI);
|
||||
auto rotation = Matrix::CreateRotationX(PI);
|
||||
|
||||
m_context->VSSetShader(m_vsSky.Get(), nullptr, 0);
|
||||
m_context->PSSetShader(m_psSky.Get(), nullptr, 0);
|
||||
|
@ -2221,9 +2217,9 @@ namespace TEN::Renderer
|
|||
{
|
||||
auto weather = TEN::Effects::Environment::Weather;
|
||||
|
||||
Matrix translation = Matrix::CreateTranslation(Camera.pos.x + weather.SkyPosition(s) - i * SKY_SIZE,
|
||||
auto translation = Matrix::CreateTranslation(Camera.pos.x + weather.SkyPosition(s) - i * SKY_SIZE,
|
||||
Camera.pos.y - 1536.0f, Camera.pos.z);
|
||||
Matrix world = rotation * translation;
|
||||
auto world = rotation * translation;
|
||||
|
||||
m_stSky.World = (rotation * translation);
|
||||
m_stSky.Color = weather.SkyColor(s);
|
||||
|
@ -2239,7 +2235,7 @@ namespace TEN::Renderer
|
|||
|
||||
m_context->ClearDepthStencilView(depthTarget, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1, 0);
|
||||
|
||||
// Draw horizon
|
||||
// Draw horizon.
|
||||
if (m_moveableObjects[ID_HORIZON].has_value())
|
||||
{
|
||||
m_context->IASetVertexBuffers(0, 1, m_moveablesVertexBuffer.Buffer.GetAddressOf(), &stride, &offset);
|
||||
|
@ -2247,7 +2243,7 @@ namespace TEN::Renderer
|
|||
m_context->IASetInputLayout(m_inputLayout.Get());
|
||||
m_context->IASetIndexBuffer(m_moveablesIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
|
||||
|
||||
RendererObject& moveableObj = *m_moveableObjects[ID_HORIZON];
|
||||
auto& moveableObj = *m_moveableObjects[ID_HORIZON];
|
||||
|
||||
m_stSky.World = Matrix::CreateTranslation(Camera.pos.x, Camera.pos.y, Camera.pos.z);
|
||||
m_stSky.Color = Vector4::One;
|
||||
|
@ -2259,9 +2255,9 @@ namespace TEN::Renderer
|
|||
|
||||
for (int k = 0; k < moveableObj.ObjectMeshes.size(); k++)
|
||||
{
|
||||
RendererMesh* mesh = moveableObj.ObjectMeshes[k];
|
||||
auto* meshPtr = moveableObj.ObjectMeshes[k];
|
||||
|
||||
for (auto& bucket : mesh->Buckets)
|
||||
for (auto& bucket : meshPtr->Buckets)
|
||||
{
|
||||
if (bucket.NumVertices == 0)
|
||||
continue;
|
||||
|
@ -2271,11 +2267,11 @@ namespace TEN::Renderer
|
|||
BindTexture(TEXTURE_NORMAL_MAP, &std::get<1>(m_moveablesTextures[bucket.Texture]),
|
||||
SAMPLER_ANISOTROPIC_CLAMP);
|
||||
|
||||
// Always render horizon as alpha-blended surface
|
||||
// Always render horizon as alpha-blended surface.
|
||||
SetBlendMode(bucket.BlendMode == BLEND_MODES::BLENDMODE_ALPHATEST ? BLEND_MODES::BLENDMODE_ALPHABLEND : bucket.BlendMode);
|
||||
SetAlphaTest(ALPHA_TEST_NONE, ALPHA_TEST_THRESHOLD);
|
||||
|
||||
// Draw vertices
|
||||
// Draw vertices.
|
||||
DrawIndexedTriangles(bucket.NumIndices, bucket.StartIndex, 0);
|
||||
|
||||
m_numMoveablesDrawCalls++;
|
||||
|
@ -2283,7 +2279,7 @@ namespace TEN::Renderer
|
|||
}
|
||||
}
|
||||
|
||||
// Clear just the Z-buffer so we can start drawing on top of the horizon
|
||||
// Clear just the Z-buffer to start drawing on top of horizon.
|
||||
m_context->ClearDepthStencilView(depthTarget, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
|
||||
}
|
||||
|
||||
|
@ -2297,19 +2293,18 @@ namespace TEN::Renderer
|
|||
|
||||
void Renderer11::DrawMoveableMesh(RendererItem* itemToDraw, RendererMesh* mesh, RendererRoom* room, int boneIndex, RendererPass rendererPass)
|
||||
{
|
||||
Vector3 cameraPosition = Vector3(Camera.pos.x, Camera.pos.y, Camera.pos.z);
|
||||
auto cameraPos = Camera.pos.ToVector3();
|
||||
|
||||
for (auto& bucket : mesh->Buckets)
|
||||
{
|
||||
if (!((bucket.BlendMode == BLENDMODE_OPAQUE || bucket.BlendMode == BLENDMODE_ALPHATEST) ^ (rendererPass == RendererPass::Transparent)))
|
||||
if (!((bucket.BlendMode == BLENDMODE_OPAQUE || bucket.BlendMode == BLENDMODE_ALPHATEST) ^
|
||||
(rendererPass == RendererPass::Transparent || rendererPass == RendererPass::CollectSortedFaces)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (bucket.NumVertices == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (rendererPass == RendererPass::ShadowMap)
|
||||
{
|
||||
|
@ -2320,21 +2315,21 @@ namespace TEN::Renderer
|
|||
|
||||
m_numMoveablesDrawCalls++;
|
||||
}
|
||||
else if (DoesBlendModeRequireSorting(bucket.BlendMode))
|
||||
else if (rendererPass == RendererPass::CollectSortedFaces && DoesBlendModeRequireSorting(bucket.BlendMode))
|
||||
{
|
||||
// Collect transparent faces
|
||||
for (int j = 0; j < bucket.Polygons.size(); j++)
|
||||
{
|
||||
RendererPolygon* p = &bucket.Polygons[j];
|
||||
auto* polygonPtr = &bucket.Polygons[j];
|
||||
|
||||
// As polygon distance, for moveables, we use the averaged distance
|
||||
Vector3 centre = Vector3::Transform(
|
||||
p->centre, itemToDraw->AnimationTransforms[boneIndex] * itemToDraw->World);
|
||||
int distance = (centre - cameraPosition).Length();
|
||||
// Use averaged distance as polygon distance for moveables.
|
||||
auto centre = Vector3::Transform(
|
||||
polygonPtr->centre, itemToDraw->AnimationTransforms[boneIndex] * itemToDraw->World);
|
||||
int distance = (centre - cameraPos).Length();
|
||||
|
||||
RendererTransparentFace face;
|
||||
face.type = RendererTransparentFaceType::TRANSPARENT_FACE_MOVEABLE;
|
||||
face.info.polygon = p;
|
||||
face.info.polygon = polygonPtr;
|
||||
face.distance = distance;
|
||||
face.info.animated = bucket.Animated;
|
||||
face.info.texture = bucket.Texture;
|
||||
|
@ -2362,8 +2357,7 @@ namespace TEN::Renderer
|
|||
SetBlendMode(bucket.BlendMode);
|
||||
SetAlphaTest(
|
||||
bucket.BlendMode == BLENDMODE_ALPHATEST ? ALPHA_TEST_GREATER_THAN : ALPHA_TEST_NONE,
|
||||
ALPHA_TEST_THRESHOLD
|
||||
);
|
||||
ALPHA_TEST_THRESHOLD);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "Game/camera.h"
|
||||
#include "Game/control/control.h"
|
||||
#include "Game/spotcam.h"
|
||||
#include "Game/effects/DisplaySprite.h"
|
||||
#include "Game/effects/weather.h"
|
||||
#include "Game/Lara/lara.h"
|
||||
#include "Game/Setup.h"
|
||||
|
@ -12,6 +13,7 @@
|
|||
#include "Objects/Utils/object_helper.h"
|
||||
#include "Specific/trutils.h"
|
||||
|
||||
using namespace TEN::Effects::DisplaySprite;
|
||||
using namespace TEN::Effects::Environment;
|
||||
using namespace TEN::Math;
|
||||
|
||||
|
@ -379,67 +381,77 @@ namespace TEN::Renderer
|
|||
DrawFullScreenQuad(texture, Vector3(fade), true);
|
||||
}
|
||||
|
||||
void Renderer11::DrawSpriteIn2DSpace(GAME_OBJECT_ID spriteID, unsigned int spriteIndex, const Vector2& pos2D, short orient2D,
|
||||
const Vector4& color, const Vector2& size)
|
||||
void Renderer11::DrawDisplaySprites(RenderView& renderView)
|
||||
{
|
||||
constexpr auto VERTEX_COUNT = 4;
|
||||
constexpr auto UV_CONSTRAINTS = std::array<Vector2, VERTEX_COUNT>
|
||||
{
|
||||
Vector2(0.0f),
|
||||
Vector2(1.0f, 0.0f),
|
||||
Vector2(1.0f),
|
||||
Vector2(0.0f, 1.0f)
|
||||
};
|
||||
constexpr auto VERTEX_COUNT = 4;
|
||||
|
||||
// Calculate vertex base.
|
||||
auto halfSize = size / 2;
|
||||
auto vertexPoints = std::array<Vector2, VERTEX_COUNT>
|
||||
{
|
||||
halfSize,
|
||||
Vector2(-halfSize.x, halfSize.y),
|
||||
-halfSize,
|
||||
Vector2(halfSize.x, -halfSize.y)
|
||||
};
|
||||
|
||||
// Transform vertices.
|
||||
auto rotMatrix = Matrix::CreateRotationZ(TO_RAD(orient2D + ANGLE(180.0f))); // NOTE: +Y is down.
|
||||
for (auto& vertexPoint : vertexPoints)
|
||||
{
|
||||
// Rotate.
|
||||
vertexPoint = Vector2::Transform(vertexPoint, rotMatrix);
|
||||
|
||||
// Adjust for aspect ratio and convert to NDC.
|
||||
vertexPoint = TEN::Utils::GetAspectCorrect2DPosition(vertexPoint);
|
||||
vertexPoint += pos2D;
|
||||
vertexPoint = TEN::Utils::Convert2DPositionToNDC(vertexPoint);
|
||||
}
|
||||
|
||||
// Define renderer vertices.
|
||||
auto vertices = std::array<RendererVertex, VERTEX_COUNT>{};
|
||||
for (int i = 0; i < vertices.size(); i++)
|
||||
{
|
||||
vertices[i].Position = Vector3(vertexPoints[i]);
|
||||
vertices[i].UV = UV_CONSTRAINTS[i];
|
||||
vertices[i].Color = color;
|
||||
}
|
||||
|
||||
SetBlendMode(BLENDMODE_ALPHABLEND);
|
||||
if (renderView.DisplaySpritesToDraw.empty())
|
||||
return;
|
||||
|
||||
m_context->VSSetShader(m_vsFullScreenQuad.Get(), nullptr, 0);
|
||||
m_context->PSSetShader(m_psFullScreenQuad.Get(), nullptr, 0);
|
||||
|
||||
const auto& spritePtr = m_sprites[Objects[spriteID].meshIndex + spriteIndex];
|
||||
auto* texturePtr = spritePtr.Texture->ShaderResourceView.Get();
|
||||
m_context->PSSetShaderResources(0, 1, &texturePtr);
|
||||
|
||||
auto* sampler = m_states->AnisotropicClamp();
|
||||
m_context->PSSetSamplers(0, 1, &sampler);
|
||||
|
||||
m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
m_context->IASetInputLayout(m_inputLayout.Get());
|
||||
|
||||
m_primitiveBatch->Begin();
|
||||
m_primitiveBatch->DrawQuad(vertices[0], vertices[1], vertices[2], vertices[3]);
|
||||
Texture2D* texture2DPtr = nullptr;
|
||||
for (const auto& spriteToDraw : renderView.DisplaySpritesToDraw)
|
||||
{
|
||||
if (texture2DPtr == nullptr)
|
||||
{
|
||||
m_primitiveBatch->Begin();
|
||||
|
||||
BindTexture(TEXTURE_COLOR_MAP, spriteToDraw.SpritePtr->Texture, SAMPLER_ANISOTROPIC_CLAMP);
|
||||
SetBlendMode(spriteToDraw.BlendMode);
|
||||
}
|
||||
else if (texture2DPtr != spriteToDraw.SpritePtr->Texture || lastBlendMode != spriteToDraw.BlendMode)
|
||||
{
|
||||
m_primitiveBatch->End();
|
||||
m_primitiveBatch->Begin();
|
||||
|
||||
BindTexture(TEXTURE_COLOR_MAP, spriteToDraw.SpritePtr->Texture, SAMPLER_ANISOTROPIC_CLAMP);
|
||||
SetBlendMode(spriteToDraw.BlendMode);
|
||||
}
|
||||
|
||||
// Calculate vertex base.
|
||||
auto vertices = std::array<Vector2, VERTEX_COUNT>
|
||||
{
|
||||
spriteToDraw.Size / 2,
|
||||
Vector2(-spriteToDraw.Size.x, spriteToDraw.Size.y) / 2,
|
||||
-spriteToDraw.Size / 2,
|
||||
Vector2(spriteToDraw.Size.x, -spriteToDraw.Size.y) / 2
|
||||
};
|
||||
|
||||
// Transform vertices.
|
||||
// NOTE: Must rotate 180 degrees to account for +Y being down.
|
||||
auto rotMatrix = Matrix::CreateRotationZ(TO_RAD(spriteToDraw.Orientation + ANGLE(180.0f)));
|
||||
for (auto& vertex : vertices)
|
||||
{
|
||||
// Rotate.
|
||||
vertex = Vector2::Transform(vertex, rotMatrix);
|
||||
|
||||
// Apply aspect correction.
|
||||
vertex *= spriteToDraw.AspectCorrection;
|
||||
|
||||
// Offset to position and convert to NDC.
|
||||
vertex += spriteToDraw.Position;
|
||||
vertex = TEN::Utils::Convert2DPositionToNDC(vertex);
|
||||
}
|
||||
|
||||
// Define renderer vertices.
|
||||
auto rVertices = std::array<RendererVertex, VERTEX_COUNT>{};
|
||||
for (int i = 0; i < rVertices.size(); i++)
|
||||
{
|
||||
rVertices[i].Position = Vector3(vertices[i]);
|
||||
rVertices[i].UV = spriteToDraw.SpritePtr->UV[i];
|
||||
rVertices[i].Color = Vector4(spriteToDraw.Color.x, spriteToDraw.Color.y, spriteToDraw.Color.z, spriteToDraw.Color.w);
|
||||
}
|
||||
|
||||
m_primitiveBatch->DrawQuad(rVertices[0], rVertices[1], rVertices[2], rVertices[3]);
|
||||
|
||||
texture2DPtr = spriteToDraw.SpritePtr->Texture;
|
||||
}
|
||||
|
||||
m_primitiveBatch->End();
|
||||
}
|
||||
|
||||
|
@ -453,11 +465,11 @@ namespace TEN::Renderer
|
|||
|
||||
if (fit)
|
||||
{
|
||||
ID3D11Texture2D* texture2D;
|
||||
texture->GetResource(reinterpret_cast<ID3D11Resource**>(&texture2D));
|
||||
ID3D11Texture2D* texture2DPtr;
|
||||
texture->GetResource(reinterpret_cast<ID3D11Resource**>(&texture2DPtr));
|
||||
|
||||
auto desc = D3D11_TEXTURE2D_DESC();
|
||||
texture2D->GetDesc(&desc);
|
||||
texture2DPtr->GetDesc(&desc);
|
||||
|
||||
float screenAspect = float(m_screenWidth) / float(m_screenHeight);
|
||||
float imageAspect = float(desc.Width) / float(desc.Height);
|
||||
|
@ -541,7 +553,7 @@ namespace TEN::Renderer
|
|||
}
|
||||
}
|
||||
|
||||
Vector2 scale = Vector2(sprite->Width / (float)sprite->Texture->Width, sprite->Height / (float)sprite->Texture->Height);
|
||||
auto scale = Vector2(sprite->Width / (float)sprite->Texture->Width, sprite->Height / (float)sprite->Texture->Height);
|
||||
uvStart.x = uvStart.x * scale.x + sprite->UV[0].x;
|
||||
uvStart.y = uvStart.y * scale.y + sprite->UV[0].y;
|
||||
uvEnd.x = uvEnd.x * scale.x + sprite->UV[0].x;
|
||||
|
@ -581,7 +593,7 @@ namespace TEN::Renderer
|
|||
m_context->PSSetShader(m_psFullScreenQuad.Get(), nullptr, 0);
|
||||
|
||||
m_context->PSSetShaderResources(0, 1, &texture);
|
||||
ID3D11SamplerState* sampler = m_states->AnisotropicClamp();
|
||||
auto* sampler = m_states->AnisotropicClamp();
|
||||
m_context->PSSetSamplers(0, 1, &sampler);
|
||||
|
||||
m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
|
@ -591,4 +603,165 @@ namespace TEN::Renderer
|
|||
m_primitiveBatch->DrawQuad(vertices[0], vertices[1], vertices[2], vertices[3]);
|
||||
m_primitiveBatch->End();
|
||||
}
|
||||
|
||||
void Renderer11::AddDisplaySprite(const RendererSprite& sprite, const Vector2& pos2D, short orient, const Vector2& size, const Vector4& color,
|
||||
int priority, BLEND_MODES blendMode, const Vector2& aspectCorrection, RenderView& renderView)
|
||||
{
|
||||
auto spriteToDraw = RendererDisplaySpriteToDraw{};
|
||||
|
||||
spriteToDraw.SpritePtr = &sprite;
|
||||
spriteToDraw.Position = pos2D;
|
||||
spriteToDraw.Orientation = orient;
|
||||
spriteToDraw.Size = size;
|
||||
spriteToDraw.Color = color;
|
||||
spriteToDraw.Priority = priority;
|
||||
spriteToDraw.BlendMode = blendMode;
|
||||
spriteToDraw.AspectCorrection = aspectCorrection;
|
||||
|
||||
renderView.DisplaySpritesToDraw.push_back(spriteToDraw);
|
||||
}
|
||||
|
||||
void Renderer11::CollectDisplaySprites(RenderView& renderView)
|
||||
{
|
||||
constexpr auto DISPLAY_SPACE_ASPECT = SCREEN_SPACE_RES.x / SCREEN_SPACE_RES.y;
|
||||
|
||||
// Calculate screen aspect ratio.
|
||||
auto screenRes = GetScreenResolution().ToVector2();
|
||||
float screenResAspect = screenRes.x / screenRes.y;
|
||||
|
||||
// Calculate aspect ratio correction base.
|
||||
auto aspectCorrectionBase = screenResAspect / DISPLAY_SPACE_ASPECT;
|
||||
|
||||
for (const auto& displaySprite : DisplaySprites)
|
||||
{
|
||||
const auto& sprite = m_sprites[Objects[displaySprite.ObjectID].meshIndex + displaySprite.SpriteID];
|
||||
|
||||
// Calculate sprite aspect ratio.
|
||||
float spriteAspect = (float)sprite.Width / (float)sprite.Height;
|
||||
|
||||
auto halfSize = Vector2::Zero;
|
||||
auto aspectCorrection = Vector2::One;
|
||||
|
||||
// Calculate size and aspect correction.
|
||||
switch (displaySprite.ScaleMode)
|
||||
{
|
||||
default:
|
||||
case DisplaySpriteScaleMode::Fit:
|
||||
if (screenResAspect >= spriteAspect)
|
||||
{
|
||||
halfSize = (Vector2(SCREEN_SPACE_RES.y) * displaySprite.Scale) / 2;
|
||||
halfSize.x *= (spriteAspect >= 1.0f) ? spriteAspect : (1.0f / spriteAspect);
|
||||
|
||||
aspectCorrection.x = 1.0f / aspectCorrectionBase;
|
||||
}
|
||||
else
|
||||
{
|
||||
halfSize = (Vector2(SCREEN_SPACE_RES.x) * displaySprite.Scale) / 2;
|
||||
halfSize.y *= (spriteAspect >= 1.0f) ? (1.0f / spriteAspect) : spriteAspect;
|
||||
|
||||
aspectCorrection.y = aspectCorrectionBase;
|
||||
}
|
||||
break;
|
||||
|
||||
case DisplaySpriteScaleMode::Fill:
|
||||
if (screenResAspect >= spriteAspect)
|
||||
{
|
||||
halfSize = (Vector2(SCREEN_SPACE_RES.x) * displaySprite.Scale) / 2;
|
||||
halfSize.y *= (spriteAspect >= 1.0f) ? (1.0f / spriteAspect) : spriteAspect;
|
||||
|
||||
aspectCorrection.y = aspectCorrectionBase;
|
||||
}
|
||||
else
|
||||
{
|
||||
halfSize = (Vector2(SCREEN_SPACE_RES.y) * displaySprite.Scale) / 2;
|
||||
halfSize.x *= (spriteAspect >= 1.0f) ? spriteAspect : (1.0f / spriteAspect);
|
||||
|
||||
aspectCorrection.x = 1.0f / aspectCorrectionBase;
|
||||
}
|
||||
break;
|
||||
|
||||
case DisplaySpriteScaleMode::Stretch:
|
||||
if (screenResAspect >= 1.0f)
|
||||
{
|
||||
halfSize = (SCREEN_SPACE_RES.x * displaySprite.Scale) / 2;
|
||||
halfSize.y *= (screenResAspect >= 1.0f) ? (1.0f / screenResAspect) : screenResAspect;
|
||||
|
||||
aspectCorrection.y = aspectCorrectionBase;
|
||||
}
|
||||
else
|
||||
{
|
||||
halfSize = (Vector2(SCREEN_SPACE_RES.y) * displaySprite.Scale) / 2;
|
||||
halfSize.x *= (screenResAspect >= 1.0f) ? (1.0f / screenResAspect) : screenResAspect;
|
||||
|
||||
aspectCorrection.x = 1.0f / aspectCorrectionBase;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Calculate position offset.
|
||||
auto offset = Vector2::Zero;
|
||||
switch (displaySprite.AlignMode)
|
||||
{
|
||||
default:
|
||||
case DisplaySpriteAlignMode::Center:
|
||||
break;
|
||||
|
||||
case DisplaySpriteAlignMode::CenterTop:
|
||||
offset = Vector2(0.0f, halfSize.y);
|
||||
break;
|
||||
|
||||
case DisplaySpriteAlignMode::CenterBottom:
|
||||
offset = Vector2(0.0f, -halfSize.y);
|
||||
break;
|
||||
|
||||
case DisplaySpriteAlignMode::CenterLeft:
|
||||
offset = Vector2(halfSize.x, 0.0f);
|
||||
break;
|
||||
|
||||
case DisplaySpriteAlignMode::CenterRight:
|
||||
offset = Vector2(-halfSize.x, 0.0f);
|
||||
break;
|
||||
|
||||
case DisplaySpriteAlignMode::TopLeft:
|
||||
offset = Vector2(halfSize.x, halfSize.y);
|
||||
break;
|
||||
|
||||
case DisplaySpriteAlignMode::TopRight:
|
||||
offset = Vector2(-halfSize.x, halfSize.y);
|
||||
break;
|
||||
|
||||
case DisplaySpriteAlignMode::BottomLeft:
|
||||
offset = Vector2(halfSize.x, -halfSize.y);
|
||||
break;
|
||||
|
||||
case DisplaySpriteAlignMode::BottomRight:
|
||||
offset = Vector2(-halfSize.x, -halfSize.y);
|
||||
break;
|
||||
}
|
||||
offset *= aspectCorrection;
|
||||
|
||||
AddDisplaySprite(
|
||||
sprite,
|
||||
displaySprite.Position + offset,
|
||||
displaySprite.Orientation,
|
||||
halfSize * 2,
|
||||
displaySprite.Color,
|
||||
displaySprite.Priority,
|
||||
displaySprite.BlendMode,
|
||||
aspectCorrection,
|
||||
renderView);
|
||||
}
|
||||
|
||||
std::sort(
|
||||
renderView.DisplaySpritesToDraw.begin(), renderView.DisplaySpritesToDraw.end(),
|
||||
[](const RendererDisplaySpriteToDraw& spriteToDraw0, const RendererDisplaySpriteToDraw& spriteToDraw1)
|
||||
{
|
||||
// Same priority; sort by blend mode.
|
||||
if (spriteToDraw0.Priority == spriteToDraw1.Priority)
|
||||
return (spriteToDraw0.BlendMode < spriteToDraw1.BlendMode);
|
||||
|
||||
// Sort by priority.
|
||||
return (spriteToDraw0.Priority < spriteToDraw1.Priority);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "Math/Math.h"
|
||||
#include "Objects/TR5/Trap/LaserBarrier.h"
|
||||
#include "Objects/Utils/object_helper.h"
|
||||
#include "Renderer/RendererSprite2D.h"
|
||||
#include "Renderer/RendererSprites.h"
|
||||
#include "Renderer/Quad/RenderQuad.h"
|
||||
#include "Specific/level.h"
|
||||
|
@ -1191,7 +1192,7 @@ namespace TEN::Renderer
|
|||
currentSpriteBucket.SpritesToDraw.clear();
|
||||
}
|
||||
|
||||
//HACK: prevent sprites like Explosionsmoke which have blendmode_subtractive from having laser effects
|
||||
// HACK: Prevent sprites like Explosionsmoke which have blendmode_subtractive from having laser effects.
|
||||
if (DoesBlendModeRequireSorting(rDrawSprite.BlendMode) && currentSpriteBucket.RenderType)
|
||||
{
|
||||
// If blend mode requires sorting, save sprite for later.
|
||||
|
@ -1205,7 +1206,7 @@ namespace TEN::Renderer
|
|||
|
||||
for (int j = 0; j < view.RoomsToDraw.size(); j++)
|
||||
{
|
||||
short roomNumber = view.RoomsToDraw[j]->RoomNumber;
|
||||
int roomNumber = view.RoomsToDraw[j]->RoomNumber;
|
||||
if (g_Level.Rooms[roomNumber].Active() && IsPointInRoom(Vector3i(rDrawSprite.pos), roomNumber))
|
||||
{
|
||||
view.RoomsToDraw[j]->TransparentFacesToDraw.push_back(face);
|
||||
|
@ -1362,8 +1363,8 @@ namespace TEN::Renderer
|
|||
UINT stride = sizeof(RendererVertex);
|
||||
UINT offset = 0;
|
||||
|
||||
m_context->VSSetShader(m_vsSprites.Get(), NULL, 0);
|
||||
m_context->PSSetShader(m_psSprites.Get(), NULL, 0);
|
||||
m_context->VSSetShader(m_vsSprites.Get(), nullptr, 0);
|
||||
m_context->PSSetShader(m_psSprites.Get(), nullptr, 0);
|
||||
|
||||
m_transparentFacesVertexBuffer.Update(m_context.Get(), m_transparentFacesVertices, 0, (int)m_transparentFacesVertices.size());
|
||||
|
||||
|
@ -1398,7 +1399,7 @@ namespace TEN::Renderer
|
|||
|
||||
void Renderer11::DrawEffect(RenderView& view, RendererEffect* effect, RendererPass rendererPass)
|
||||
{
|
||||
RendererRoom const& room = m_rooms[effect->RoomNumber];
|
||||
const auto& room = m_rooms[effect->RoomNumber];
|
||||
|
||||
m_stStatic.World = effect->World;
|
||||
m_stStatic.Color = effect->Color;
|
||||
|
@ -1418,16 +1419,19 @@ namespace TEN::Renderer
|
|||
SetAlphaTest(ALPHA_TEST_GREATER_THAN, ALPHA_TEST_THRESHOLD);
|
||||
}
|
||||
|
||||
RendererMesh* mesh = effect->Mesh;
|
||||
BLEND_MODES lastBlendMode = BLEND_MODES::BLENDMODE_UNSET;
|
||||
auto* meshPtr = effect->Mesh;
|
||||
auto lastBlendMode = BLEND_MODES::BLENDMODE_UNSET;
|
||||
|
||||
for (auto& bucket : mesh->Buckets)
|
||||
for (auto& bucket : meshPtr->Buckets)
|
||||
{
|
||||
if (bucket.NumVertices == 0)
|
||||
continue;
|
||||
|
||||
if (!((bucket.BlendMode == BLENDMODE_OPAQUE || bucket.BlendMode == BLENDMODE_ALPHATEST) ^ (rendererPass == RendererPass::Transparent)))
|
||||
if (!((bucket.BlendMode == BLENDMODE_OPAQUE || bucket.BlendMode == BLENDMODE_ALPHATEST) ^
|
||||
(rendererPass == RendererPass::Transparent)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
BindTexture(TEXTURE_COLOR_MAP, &std::get<0>(m_moveablesTextures[bucket.Texture]), SAMPLER_ANISOTROPIC_CLAMP);
|
||||
BindTexture(TEXTURE_NORMAL_MAP, &std::get<1>(m_moveablesTextures[bucket.Texture]), SAMPLER_ANISOTROPIC_CLAMP);
|
||||
|
@ -1436,13 +1440,12 @@ namespace TEN::Renderer
|
|||
|
||||
DrawIndexedTriangles(bucket.NumIndices, bucket.StartIndex, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Renderer11::DrawEffects(RenderView& view, RendererPass rendererPass)
|
||||
{
|
||||
m_context->VSSetShader(m_vsStatics.Get(), NULL, 0);
|
||||
m_context->PSSetShader(m_psStatics.Get(), NULL, 0);
|
||||
m_context->VSSetShader(m_vsStatics.Get(), nullptr, 0);
|
||||
m_context->PSSetShader(m_psStatics.Get(), nullptr, 0);
|
||||
|
||||
BindConstantBufferVS(CB_STATIC, m_cbStatic.get());
|
||||
BindConstantBufferPS(CB_STATIC, m_cbStatic.get());
|
||||
|
@ -1455,23 +1458,23 @@ namespace TEN::Renderer
|
|||
m_context->IASetInputLayout(m_inputLayout.Get());
|
||||
m_context->IASetIndexBuffer(m_moveablesIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
|
||||
|
||||
for (auto room : view.RoomsToDraw)
|
||||
for (auto* roomPtr : view.RoomsToDraw)
|
||||
{
|
||||
for (auto effect : room->EffectsToDraw)
|
||||
for (auto* effectPtr : roomPtr->EffectsToDraw)
|
||||
{
|
||||
RendererRoom const& room = m_rooms[effect->RoomNumber];
|
||||
ObjectInfo* obj = &Objects[effect->ObjectNumber];
|
||||
const auto& room = m_rooms[effectPtr->RoomNumber];
|
||||
const auto& object = Objects[effectPtr->ObjectNumber];
|
||||
|
||||
if (obj->drawRoutine && obj->loaded)
|
||||
DrawEffect(view, effect, rendererPass);
|
||||
if (object.drawRoutine && object.loaded)
|
||||
DrawEffect(view, effectPtr, rendererPass);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Renderer11::DrawDebris(RenderView& view, RendererPass rendererPass)
|
||||
{
|
||||
m_context->VSSetShader(m_vsStatics.Get(), NULL, 0);
|
||||
m_context->PSSetShader(m_psStatics.Get(), NULL, 0);
|
||||
m_context->VSSetShader(m_vsStatics.Get(), nullptr, 0);
|
||||
m_context->PSSetShader(m_psStatics.Get(), nullptr, 0);
|
||||
|
||||
BindConstantBufferVS(CB_STATIC, m_cbStatic.get());
|
||||
BindConstantBufferPS(CB_STATIC, m_cbStatic.get());
|
||||
|
@ -1479,18 +1482,21 @@ namespace TEN::Renderer
|
|||
extern std::vector<DebrisFragment> DebrisFragments;
|
||||
std::vector<RendererVertex> vertices;
|
||||
|
||||
BLEND_MODES lastBlendMode = BLEND_MODES::BLENDMODE_UNSET;
|
||||
auto lastBlendMode = BLEND_MODES::BLENDMODE_UNSET;
|
||||
|
||||
for (auto deb = DebrisFragments.begin(); deb != DebrisFragments.end(); deb++)
|
||||
{
|
||||
if (deb->active)
|
||||
{
|
||||
if (!((deb->mesh.blendMode == BLENDMODE_OPAQUE || deb->mesh.blendMode == BLENDMODE_ALPHATEST) ^ (rendererPass == RendererPass::Transparent)))
|
||||
if (!((deb->mesh.blendMode == BLENDMODE_OPAQUE || deb->mesh.blendMode == BLENDMODE_ALPHATEST) ^
|
||||
(rendererPass == RendererPass::Transparent)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Matrix translation = Matrix::CreateTranslation(deb->worldPosition.x, deb->worldPosition.y, deb->worldPosition.z);
|
||||
Matrix rotation = Matrix::CreateFromQuaternion(deb->rotation);
|
||||
Matrix world = rotation * translation;
|
||||
auto translation = Matrix::CreateTranslation(deb->worldPosition.x, deb->worldPosition.y, deb->worldPosition.z);
|
||||
auto rotation = Matrix::CreateFromQuaternion(deb->rotation);
|
||||
auto world = rotation * translation;
|
||||
|
||||
m_primitiveBatch->Begin();
|
||||
|
||||
|
|
|
@ -227,26 +227,31 @@ namespace TEN::Renderer
|
|||
GetNextLinePosition(&y);
|
||||
|
||||
// Auto targeting
|
||||
AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_AUTO_TARGET), PRINTSTRING_COLOR_ORANGE, SF(titleOption == 4));
|
||||
AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_AUTOMATIC_TARGETING), PRINTSTRING_COLOR_ORANGE, SF(titleOption == 4));
|
||||
AddString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().Configuration.EnableAutoTargeting), PRINTSTRING_COLOR_WHITE, SF(titleOption == 4));
|
||||
GetNextLinePosition(&y);
|
||||
|
||||
// Target highlighter
|
||||
AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_TARGET_HIGHLIGHTER), PRINTSTRING_COLOR_ORANGE, SF(titleOption == 5));
|
||||
AddString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().Configuration.EnableTargetHighlighter), PRINTSTRING_COLOR_WHITE, SF(titleOption == 5));
|
||||
GetNextLinePosition(&y);
|
||||
|
||||
// Vibration
|
||||
AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_RUMBLE), PRINTSTRING_COLOR_ORANGE, SF(titleOption == 5));
|
||||
AddString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().Configuration.EnableRumble), PRINTSTRING_COLOR_WHITE, SF(titleOption == 5));
|
||||
AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_RUMBLE), PRINTSTRING_COLOR_ORANGE, SF(titleOption == 6));
|
||||
AddString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().Configuration.EnableRumble), PRINTSTRING_COLOR_WHITE, SF(titleOption == 6));
|
||||
GetNextLinePosition(&y);
|
||||
|
||||
// Thumbstick camera
|
||||
AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_THUMBSTICK_CAMERA), PRINTSTRING_COLOR_ORANGE, SF(titleOption == 6));
|
||||
AddString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().Configuration.EnableThumbstickCamera), PRINTSTRING_COLOR_WHITE, SF(titleOption == 6));
|
||||
AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_THUMBSTICK_CAMERA), PRINTSTRING_COLOR_ORANGE, SF(titleOption == 7));
|
||||
AddString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().Configuration.EnableThumbstickCamera), PRINTSTRING_COLOR_WHITE, SF(titleOption == 7));
|
||||
GetNextBlockPosition(&y);
|
||||
|
||||
// Apply
|
||||
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_APPLY), PRINTSTRING_COLOR_ORANGE, SF_Center(titleOption == 7));
|
||||
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_APPLY), PRINTSTRING_COLOR_ORANGE, SF_Center(titleOption == 8));
|
||||
GetNextLinePosition(&y);
|
||||
|
||||
// Cancel
|
||||
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_CANCEL), PRINTSTRING_COLOR_ORANGE, SF_Center(titleOption == 8));
|
||||
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_CANCEL), PRINTSTRING_COLOR_ORANGE, SF_Center(titleOption == 9));
|
||||
break;
|
||||
|
||||
case Menu::GeneralActions:
|
||||
|
@ -562,7 +567,7 @@ namespace TEN::Renderer
|
|||
break;
|
||||
}
|
||||
|
||||
DrawLines2D();
|
||||
DrawLinesIn2DSpace();
|
||||
DrawAllStrings();
|
||||
}
|
||||
|
||||
|
|
|
@ -42,6 +42,8 @@ enum LIGHT_TYPES
|
|||
|
||||
enum BLEND_MODES
|
||||
{
|
||||
BLENDMODE_UNSET = -1,
|
||||
|
||||
BLENDMODE_OPAQUE = 0,
|
||||
BLENDMODE_ALPHATEST = 1,
|
||||
BLENDMODE_ADDITIVE = 2,
|
||||
|
@ -51,8 +53,7 @@ enum BLEND_MODES
|
|||
BLENDMODE_EXCLUDE = 8,
|
||||
BLENDMODE_SCREEN = 9,
|
||||
BLENDMODE_LIGHTEN = 10,
|
||||
BLENDMODE_ALPHABLEND = 11,
|
||||
BLENDMODE_UNSET = -1
|
||||
BLENDMODE_ALPHABLEND = 11
|
||||
};
|
||||
|
||||
enum CULL_MODES
|
||||
|
@ -205,7 +206,8 @@ enum RendererPass
|
|||
{
|
||||
ShadowMap,
|
||||
Opaque,
|
||||
Transparent
|
||||
Transparent,
|
||||
CollectSortedFaces
|
||||
};
|
||||
|
||||
constexpr auto TEXTURE_HEIGHT = 256;
|
||||
|
|
|
@ -19,47 +19,48 @@ using namespace TEN::Math;
|
|||
namespace TEN::Renderer
|
||||
{
|
||||
using TEN::Memory::LinearArrayBuffer;
|
||||
using std::vector;
|
||||
|
||||
void Renderer11::CollectRooms(RenderView& renderView, bool onlyRooms)
|
||||
{
|
||||
constexpr auto VIEW_PORT = Vector4(-1.0f, -1.0f, 1.0f, 1.0f);
|
||||
|
||||
m_visitedRoomsStack.clear();
|
||||
|
||||
for (int i = 0; i < g_Level.Rooms.size(); i++)
|
||||
{
|
||||
RendererRoom* room = &m_rooms[i];
|
||||
auto& room = m_rooms[i];
|
||||
|
||||
room->ItemsToDraw.clear();
|
||||
room->EffectsToDraw.clear();
|
||||
room->TransparentFacesToDraw.clear();
|
||||
room->StaticsToDraw.clear();
|
||||
room->LightsToDraw.clear();
|
||||
room->Visited = false;
|
||||
room->ViewPort = Vector4(-1.0f, -1.0f, 1.0f, 1.0f);
|
||||
room.ItemsToDraw.clear();
|
||||
room.EffectsToDraw.clear();
|
||||
room.TransparentFacesToDraw.clear();
|
||||
room.StaticsToDraw.clear();
|
||||
room.LightsToDraw.clear();
|
||||
room.Visited = false;
|
||||
room.ViewPort = VIEW_PORT;
|
||||
|
||||
for (int j = 0; j < room->Doors.size(); j++)
|
||||
for (auto& door : room.Doors)
|
||||
{
|
||||
room->Doors[j].Visited = false;
|
||||
room->Doors[j].InvisibleFromCamera = false;
|
||||
room->Doors[j].DotProduct = FLT_MAX;
|
||||
door.Visited = false;
|
||||
door.InvisibleFromCamera = false;
|
||||
door.DotProduct = FLT_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
GetVisibleRooms(NO_ROOM, renderView.Camera.RoomNumber, Vector4(-1.0f, -1.0f, 1.0f, 1.0f), false, 0, onlyRooms, renderView);
|
||||
GetVisibleRooms(NO_ROOM, renderView.Camera.RoomNumber, VIEW_PORT, false, 0, onlyRooms, renderView);
|
||||
|
||||
m_invalidateCache = false;
|
||||
|
||||
// Prepare the real DX scissor test rectangle
|
||||
for (auto room : renderView.RoomsToDraw)
|
||||
// Prepare real DX scissor test rectangle.
|
||||
for (auto* roomPtr : renderView.RoomsToDraw)
|
||||
{
|
||||
room->ClipBounds.left = (room->ViewPort.x + 1.0f) * m_screenWidth * 0.5f;
|
||||
room->ClipBounds.bottom = (1.0f - room->ViewPort.y) * m_screenHeight * 0.5f;
|
||||
room->ClipBounds.right = (room->ViewPort.z + 1.0f) * m_screenWidth * 0.5f;
|
||||
room->ClipBounds.top = (1.0f - room->ViewPort.w) * m_screenHeight * 0.5f;
|
||||
roomPtr->ClipBounds.left = (roomPtr->ViewPort.x + 1.0f) * m_screenWidth * 0.5f;
|
||||
roomPtr->ClipBounds.bottom = (1.0f - roomPtr->ViewPort.y) * m_screenHeight * 0.5f;
|
||||
roomPtr->ClipBounds.right = (roomPtr->ViewPort.z + 1.0f) * m_screenWidth * 0.5f;
|
||||
roomPtr->ClipBounds.top = (1.0f - roomPtr->ViewPort.w) * m_screenHeight * 0.5f;
|
||||
}
|
||||
|
||||
// Collect fog bulbs
|
||||
vector<RendererFogBulb> tempFogBulbs;
|
||||
// Collect fog bulbs.
|
||||
std::vector<RendererFogBulb> tempFogBulbs;
|
||||
tempFogBulbs.reserve(MAX_FOG_BULBS_DRAW);
|
||||
|
||||
for (auto& room : m_rooms)
|
||||
|
@ -67,12 +68,13 @@ namespace TEN::Renderer
|
|||
if (!g_Level.Rooms[room.RoomNumber].Active())
|
||||
continue;
|
||||
|
||||
for (auto& light : room.Lights)
|
||||
for (const auto& light : room.Lights)
|
||||
{
|
||||
if (light.Type != LIGHT_TYPE_FOG_BULB)
|
||||
continue;
|
||||
|
||||
if (renderView.Camera.Frustum.SphereInFrustum(light.Position, light.Out * 1.2f)) /* Test a bigger radius for avoiding bad clipping */
|
||||
// Test bigger radius to avoid bad clipping.
|
||||
if (renderView.Camera.Frustum.SphereInFrustum(light.Position, light.Out * 1.2f))
|
||||
{
|
||||
RendererFogBulb bulb;
|
||||
|
||||
|
@ -88,19 +90,17 @@ namespace TEN::Renderer
|
|||
}
|
||||
}
|
||||
|
||||
// Sort fog bulbs.
|
||||
std::sort(
|
||||
tempFogBulbs.begin(),
|
||||
tempFogBulbs.end(),
|
||||
[](RendererFogBulb a, RendererFogBulb b)
|
||||
[](const RendererFogBulb& bulb0, const RendererFogBulb& bulb1)
|
||||
{
|
||||
return a.Distance < b.Distance;
|
||||
}
|
||||
);
|
||||
return bulb0.Distance < bulb1.Distance;
|
||||
});
|
||||
|
||||
for (int i = 0; i < std::min(MAX_FOG_BULBS_DRAW, (int)tempFogBulbs.size()); i++)
|
||||
{
|
||||
renderView.FogBulbsToDraw.push_back(tempFogBulbs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
bool Renderer11::CheckPortal(short parentRoomNumber, RendererDoor* door, Vector4 viewPort, Vector4* clipPort, RenderView& renderView)
|
||||
|
@ -296,7 +296,7 @@ namespace TEN::Renderer
|
|||
m_dotProducts++;
|
||||
}
|
||||
|
||||
if (door->DotProduct <= 0)
|
||||
if (door->DotProduct < 0)
|
||||
{
|
||||
door->InvisibleFromCamera = true;
|
||||
continue;
|
||||
|
|
|
@ -529,14 +529,14 @@ namespace TEN::Renderer
|
|||
gameCamera.Camera.WorldPosition.y,
|
||||
gameCamera.Camera.WorldPosition.z,
|
||||
1.0f);
|
||||
auto cameraDirection = Vector4(
|
||||
auto cameraDir = Vector4(
|
||||
gameCamera.Camera.WorldDirection.x,
|
||||
gameCamera.Camera.WorldDirection.y,
|
||||
gameCamera.Camera.WorldDirection.z,
|
||||
1.0f);
|
||||
|
||||
// Point is behind camera; return nullopt.
|
||||
if ((point - cameraPos).Dot(cameraDirection) < 0.0f)
|
||||
if ((point - cameraPos).Dot(cameraDir) < 0.0f)
|
||||
return std::nullopt;
|
||||
|
||||
// Calculate clip space coords.
|
||||
|
|
22
TombEngine/Renderer/RendererSprite2D.h
Normal file
22
TombEngine/Renderer/RendererSprite2D.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
#pragma once
|
||||
#include "Renderer/Renderer11Enums.h"
|
||||
|
||||
namespace TEN::Renderer
|
||||
{
|
||||
struct RendererSprite;
|
||||
|
||||
struct RendererDisplaySpriteToDraw
|
||||
{
|
||||
const RendererSprite* SpritePtr = nullptr;
|
||||
|
||||
Vector2 Position = Vector2::Zero;
|
||||
short Orientation = 0;
|
||||
Vector2 Size = Vector2::Zero;
|
||||
Vector4 Color = Vector4::Zero;
|
||||
|
||||
int Priority = 0;
|
||||
BLEND_MODES BlendMode = BLENDMODE_ALPHABLEND;
|
||||
|
||||
Vector2 AspectCorrection = Vector2::One;
|
||||
};
|
||||
}
|
|
@ -1,8 +1,9 @@
|
|||
using CallbackDrawString = std::function<void(
|
||||
const std::string&,
|
||||
D3DCOLOR,
|
||||
int, //x
|
||||
int, //y
|
||||
float, //scale
|
||||
int //flags
|
||||
)>;
|
||||
|
||||
using CallbackDrawString = std::function<
|
||||
void(
|
||||
const std::string&,
|
||||
D3DCOLOR,
|
||||
int, // X
|
||||
int, // X
|
||||
float, // Scale
|
||||
int)>; // Flags
|
||||
|
|
|
@ -79,7 +79,8 @@
|
|||
#define STRING_SOUND "sound"
|
||||
#define STRING_ENABLE_SOUND "enable_sound"
|
||||
#define STRING_REVERB "reverb"
|
||||
#define STRING_AUTO_TARGET "auto_target"
|
||||
#define STRING_AUTOMATIC_TARGETING "automatic_targeting"
|
||||
#define STRING_TARGET_HIGHLIGHTER "target_highlighter"
|
||||
#define STRING_RUMBLE "rumble"
|
||||
#define STRING_THUMBSTICK_CAMERA "thumbstick_camera"
|
||||
#define STRING_SUBTITLES "subtitles"
|
||||
|
@ -167,3 +168,4 @@
|
|||
#define STRING_MECHANICAL_SCARAB_1 "mechanical_scarab_1"
|
||||
#define STRING_MECHANICAL_SCARAB_2 "mechanical_scarab_2"
|
||||
#define STRING_VEHICLE_ACTIONS "vehicle_actions"
|
||||
#define STRING_UNLIMITED "unlimited"
|
||||
|
|
|
@ -27,6 +27,25 @@ static constexpr char ScriptReserved_Vec3[] = "Vec3";
|
|||
static constexpr char ScriptReserved_Rotation[] = "Rotation";
|
||||
static constexpr char ScriptReserved_LevelFunc[] = "LevelFunc";
|
||||
|
||||
// DisplaySprite object
|
||||
static constexpr char ScriptReserved_DisplaySprite[] = "DisplaySprite";
|
||||
static constexpr char ScriptReserved_DisplayStringGetObjectID[] = "GetObjectID";
|
||||
static constexpr char ScriptReserved_DisplayStringGetSpriteID[] = "GetSpriteID";
|
||||
static constexpr char ScriptReserved_DisplayStringGetPosition[] = "GetPosition";
|
||||
static constexpr char ScriptReserved_DisplayStringGetRotation[] = "GetRotation";
|
||||
static constexpr char ScriptReserved_DisplayStringGetScale[] = "GetScale";
|
||||
static constexpr char ScriptReserved_DisplayStringGetColor[] = "GetColor";
|
||||
static constexpr char ScriptReserved_DisplayStringSetObjectID[] = "SetObjectID";
|
||||
static constexpr char ScriptReserved_DisplayStringSetSpriteID[] = "SetSpriteID";
|
||||
static constexpr char ScriptReserved_DisplayStringSetPosition[] = "SetPosition";
|
||||
static constexpr char ScriptReserved_DisplayStringSetRotation[] = "SetRotation";
|
||||
static constexpr char ScriptReserved_DisplayStringSetScale[] = "SetScale";
|
||||
static constexpr char ScriptReserved_DisplayStringSetColor[] = "SetColor";
|
||||
static constexpr char ScriptReserved_DisplaySpriteDraw[] = "Draw";
|
||||
static constexpr char ScriptReserved_DisplaySpriteEnum[] = "DisplaySpriteEnum";
|
||||
static constexpr char ScriptReserved_DisplaySpriteEnumAlignMode[] = "AlignMode";
|
||||
static constexpr char ScriptReserved_DisplaySpriteEnumScaleMode[] = "ScaleMode";
|
||||
|
||||
// Built-in LevelFuncs
|
||||
static constexpr char ScriptReserved_OnStart[] = "OnStart";
|
||||
static constexpr char ScriptReserved_OnLoad[] = "OnLoad";
|
||||
|
@ -177,6 +196,7 @@ static constexpr char ScriptReserved_EndLevel[] = "EndLevel";
|
|||
static constexpr char ScriptReserved_SaveGame[] = "SaveGame";
|
||||
static constexpr char ScriptReserved_LoadGame[] = "LoadGame";
|
||||
static constexpr char ScriptReserved_DeleteSaveGame[] = "DeleteSaveGame";
|
||||
static constexpr char ScriptReserved_DoesSaveGameExist[] = "DoesSaveGameExist";
|
||||
static constexpr char ScriptReserved_GetSecretCount[] = "GetSecretCount";
|
||||
static constexpr char ScriptReserved_SetSecretCount[] = "SetSecretCount";
|
||||
static constexpr char ScriptReserved_SetTotalSecretCount[] = "SetTotalSecretCount";
|
||||
|
@ -234,8 +254,8 @@ static constexpr char ScriptReserved_GetRoomsByTag[] = "GetRoomsByTag";
|
|||
static constexpr char ScriptReserved_GetRoomByName[] = "GetRoomByName";
|
||||
static constexpr char ScriptReserved_CalculateDistance[] = "CalculateDistance";
|
||||
static constexpr char ScriptReserved_CalculateHorizontalDistance[] = "CalculateHorizontalDistance";
|
||||
static constexpr char ScriptReserved_ScreenToPercent[] = "ScreenToPercent";
|
||||
static constexpr char ScriptReserved_PercentToScreen[] = "PercentToScreen";
|
||||
static constexpr char ScriptReserved_ScreenToPercent[] = "ScreenToPercent";
|
||||
static constexpr char ScriptReserved_HasLineOfSight[] = "HasLineOfSight";
|
||||
|
||||
static constexpr char ScriptReserved_AddCallback[] = "AddCallback";
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "Scripting/Include/ScriptInterfaceState.h"
|
||||
|
||||
#include "Scripting/Internal/ReservedScriptNames.h"
|
||||
#include "Scripting/Internal/TEN/DisplaySprite/ScriptDisplaySprite.h"
|
||||
#include "Scripting/Internal/TEN/Effects/EffectsFunctions.h"
|
||||
#include "Scripting/Internal/TEN/Flow/FlowHandler.h"
|
||||
#include "Scripting/Internal/TEN/Inventory/InventoryHandler.h"
|
||||
|
@ -10,8 +11,10 @@
|
|||
#include "Scripting/Internal/TEN/Objects/ObjectsHandler.h"
|
||||
#include "Scripting/Internal/TEN/Strings/StringsHandler.h"
|
||||
|
||||
static sol::state s_solState;
|
||||
static sol::table s_rootTable;
|
||||
using namespace TEN::Scripting::DisplaySprite;
|
||||
|
||||
static sol::state SolState;
|
||||
static sol::table RootTable;
|
||||
|
||||
int lua_exception_handler(lua_State* luaStatePtr, sol::optional<const std::exception&> exception, sol::string_view description)
|
||||
{
|
||||
|
@ -20,36 +23,38 @@ int lua_exception_handler(lua_State* luaStatePtr, sol::optional<const std::excep
|
|||
|
||||
ScriptInterfaceGame* ScriptInterfaceState::CreateGame()
|
||||
{
|
||||
return new LogicHandler(&s_solState, s_rootTable);
|
||||
return new LogicHandler(&SolState, RootTable);
|
||||
}
|
||||
|
||||
ScriptInterfaceFlowHandler* ScriptInterfaceState::CreateFlow()
|
||||
{
|
||||
return new FlowHandler(&s_solState, s_rootTable);
|
||||
return new FlowHandler(&SolState, RootTable);
|
||||
}
|
||||
|
||||
ScriptInterfaceObjectsHandler* ScriptInterfaceState::CreateObjectsHandler()
|
||||
{
|
||||
return new ObjectsHandler(&s_solState, s_rootTable);
|
||||
return new ObjectsHandler(&SolState, RootTable);
|
||||
}
|
||||
|
||||
ScriptInterfaceStringsHandler* ScriptInterfaceState::CreateStringsHandler()
|
||||
{
|
||||
return new StringsHandler(&s_solState, s_rootTable);
|
||||
return new StringsHandler(&SolState, RootTable);
|
||||
}
|
||||
|
||||
void ScriptInterfaceState::Init(const std::string& assetsDir)
|
||||
{
|
||||
s_solState.open_libraries(sol::lib::base, sol::lib::math, sol::lib::package, sol::lib::coroutine, sol::lib::table, sol::lib::string, sol::lib::debug);
|
||||
SolState.open_libraries(
|
||||
sol::lib::base, sol::lib::math, sol::lib::package, sol::lib::coroutine,
|
||||
sol::lib::table, sol::lib::string, sol::lib::debug);
|
||||
|
||||
s_solState.script("package.path=\"" + assetsDir + "Scripts/?.lua\"");
|
||||
s_solState.set_exception_handler(lua_exception_handler);
|
||||
SolState.script("package.path=\"" + assetsDir + "Scripts/?.lua\"");
|
||||
SolState.set_exception_handler(lua_exception_handler);
|
||||
|
||||
s_rootTable = sol::table{ s_solState.lua_state(), sol::create };
|
||||
s_solState.set(ScriptReserved_TEN, s_rootTable);
|
||||
RootTable = sol::table(SolState.lua_state(), sol::create);
|
||||
SolState.set(ScriptReserved_TEN, RootTable);
|
||||
|
||||
// Misc. handlers not assigned above.
|
||||
InventoryHandler::Register(&s_solState, s_rootTable);
|
||||
Misc::Register(&s_solState, s_rootTable);
|
||||
Effects::Register(&s_solState, s_rootTable);
|
||||
InventoryHandler::Register(&SolState, RootTable);
|
||||
Misc::Register(&SolState, RootTable);
|
||||
Effects::Register(&SolState, RootTable);
|
||||
}
|
||||
|
|
|
@ -28,9 +28,9 @@
|
|||
// This alias is an effort to avoid the above problems.
|
||||
template <typename ... Ts> using TypeOrNil = std::variant<Ts..., sol::nil_t, sol::object>;
|
||||
|
||||
// To be used with TypeOrNil to fill arguments with default values if said arguments weren't given by the script.
|
||||
#define USE_IF_HAVE(Type, ifThere, ifNotThere) \
|
||||
(std::holds_alternative<Type>(ifThere) ? std::get<Type>(ifThere) : ifNotThere)
|
||||
// Used with TypeOrNil to fill arguments with default values if arguments in script not provided.
|
||||
#define USE_IF_HAVE(Type, valueIfExists, valueIfMissing) \
|
||||
(std::holds_alternative<Type>(valueIfExists) ? std::get<Type>(valueIfExists) : valueIfMissing)
|
||||
|
||||
template<typename T> bool IsValidOptionalArg(const TypeOrNil<T> & arg)
|
||||
{
|
||||
|
|
50
TombEngine/Scripting/Internal/TEN/DisplaySprite/AlignModes.h
Normal file
50
TombEngine/Scripting/Internal/TEN/DisplaySprite/AlignModes.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
#pragma once
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "Game/Effects/DisplaySprite.h"
|
||||
|
||||
using namespace TEN::Effects::DisplaySprite;
|
||||
|
||||
namespace TEN::Scripting::DisplaySprite
|
||||
{
|
||||
/***
|
||||
Constants for display sprite align modes.
|
||||
@enum DisplaySprite.AlignMode
|
||||
@pragma nostrip
|
||||
*/
|
||||
|
||||
/*** DisplaySprite.AlignMode constants.
|
||||
|
||||
The following constants are inside AlignMode.
|
||||
|
||||
CENTER
|
||||
CENTER_TOP
|
||||
CENTER_BOTTOM
|
||||
CENTER_LEFT
|
||||
CENTER_RIGHT
|
||||
TOP_LEFT
|
||||
TOP_RIGHT
|
||||
BOTTOM_LEFT
|
||||
BOTTOM_RIGHT
|
||||
|
||||
@section DisplaySprite.AlignMode
|
||||
*/
|
||||
|
||||
/*** Table of display sprite align modes.
|
||||
@table CONSTANT_STRING_HERE
|
||||
*/
|
||||
|
||||
static const std::unordered_map<std::string, DisplaySpriteAlignMode> DISPLAY_SPRITE_ALIGN_MODES
|
||||
{
|
||||
{ "CENTER", DisplaySpriteAlignMode::Center },
|
||||
{ "CENTER_TOP", DisplaySpriteAlignMode::CenterTop },
|
||||
{ "CENTER_BOTTOM", DisplaySpriteAlignMode::CenterBottom },
|
||||
{ "CENTER_LEFT", DisplaySpriteAlignMode::CenterLeft },
|
||||
{ "CENTER_RIGHT", DisplaySpriteAlignMode::CenterRight },
|
||||
{ "TOP_LEFT", DisplaySpriteAlignMode::TopLeft },
|
||||
{ "TOP_RIGHT", DisplaySpriteAlignMode::TopRight },
|
||||
{ "BOTTOM_LEFT", DisplaySpriteAlignMode::BottomLeft },
|
||||
{ "BOTTOM_RIGHT", DisplaySpriteAlignMode::BottomRight }
|
||||
};
|
||||
}
|
38
TombEngine/Scripting/Internal/TEN/DisplaySprite/ScaleModes.h
Normal file
38
TombEngine/Scripting/Internal/TEN/DisplaySprite/ScaleModes.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
#pragma once
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "Game/effects/DisplaySprite.h"
|
||||
|
||||
using namespace TEN::Effects::DisplaySprite;
|
||||
|
||||
namespace TEN::Scripting::DisplaySprite
|
||||
{
|
||||
/***
|
||||
Constants for display sprite scale modes.
|
||||
@enum DisplaySprite.ScaleMode
|
||||
@pragma nostrip
|
||||
*/
|
||||
|
||||
/*** DisplaySprite.ScaleMode constants.
|
||||
|
||||
The following constants are inside DisplaySprite.ScaleMode.
|
||||
|
||||
FIT
|
||||
FILL
|
||||
STRETCH
|
||||
|
||||
@section DisplaySprite.ScaleMode
|
||||
*/
|
||||
|
||||
/*** Table of display sprite scale modes.
|
||||
@table CONSTANT_STRING_HERE
|
||||
*/
|
||||
|
||||
static const std::unordered_map<std::string, DisplaySpriteScaleMode> DISPLAY_SPRITE_SCALE_MODES
|
||||
{
|
||||
{ "FIT", DisplaySpriteScaleMode::Fit },
|
||||
{ "FILL", DisplaySpriteScaleMode::Fill },
|
||||
{ "STRETCH", DisplaySpriteScaleMode::Stretch }
|
||||
};
|
||||
}
|
|
@ -0,0 +1,254 @@
|
|||
#include "framework.h"
|
||||
#include "Scripting/Internal/TEN/DisplaySprite/ScriptDisplaySprite.h"
|
||||
|
||||
#include "Game/effects/DisplaySprite.h"
|
||||
#include "Game/Setup.h"
|
||||
#include "Objects/game_object_ids.h"
|
||||
#include "Renderer/Renderer11.h"
|
||||
#include "Scripting/Internal/LuaHandler.h"
|
||||
#include "Scripting/Internal/ReservedScriptNames.h"
|
||||
#include "Scripting/Internal/TEN/Color/Color.h"
|
||||
#include "Scripting/Internal/TEN/DisplaySprite/AlignModes.h"
|
||||
#include "Scripting/Internal/TEN/DisplaySprite/ScaleModes.h"
|
||||
#include "Scripting/Internal/TEN/Vec2/Vec2.h"
|
||||
|
||||
using namespace TEN::Effects::DisplaySprite;
|
||||
using TEN::Renderer::g_Renderer;
|
||||
|
||||
namespace TEN::Scripting::DisplaySprite
|
||||
{
|
||||
void ScriptDisplaySprite::Register(sol::state& state, sol::table& parent)
|
||||
{
|
||||
using ctors = sol::constructors<
|
||||
ScriptDisplaySprite(GAME_OBJECT_ID, int, const Vec2&, float, const Vec2&, const ScriptColor&),
|
||||
ScriptDisplaySprite(GAME_OBJECT_ID, int, const Vec2&, float, const Vec2&)>;
|
||||
|
||||
// Register type.
|
||||
parent.new_usertype<ScriptDisplaySprite>(
|
||||
ScriptReserved_DisplaySprite,
|
||||
ctors(),
|
||||
sol::call_constructor, ctors(),
|
||||
|
||||
/*** Get the object ID of the sprite sequence object used by the display sprite.
|
||||
@function DisplaySprite:GetObjectID()
|
||||
@treturn Objects.ObjID Sprite sequence object ID.
|
||||
*/
|
||||
ScriptReserved_DisplayStringGetObjectID, &ScriptDisplaySprite::GetObjectID,
|
||||
|
||||
/*** Get the sprite ID in the sprite sequence object used by the display sprite.
|
||||
@function DisplaySprite:GetSpriteID()
|
||||
@treturn int Sprite ID in the sprite sequence object.
|
||||
*/
|
||||
ScriptReserved_DisplayStringGetSpriteID, &ScriptDisplaySprite::GetSpriteID,
|
||||
|
||||
/*** Get the display position of the display sprite in percent.
|
||||
@function DisplaySprite:GetPosition()
|
||||
@treturn Vec2 Display position in percent.
|
||||
*/
|
||||
ScriptReserved_DisplayStringGetPosition, &ScriptDisplaySprite::GetPosition,
|
||||
|
||||
/*** Get the rotation of the display sprite in degrees.
|
||||
@function DisplaySprite:GetRotation()
|
||||
@treturn float Rotation in degrees.
|
||||
*/
|
||||
ScriptReserved_DisplayStringGetRotation, &ScriptDisplaySprite::GetRotation,
|
||||
|
||||
/*** Get the horizontal and vertical scale of the display sprite in percent.
|
||||
@function DisplaySprite:GetScale()
|
||||
@treturn Vec2 Horizontal and vertical scale in percent.
|
||||
*/
|
||||
ScriptReserved_DisplayStringGetScale, &ScriptDisplaySprite::GetScale,
|
||||
|
||||
/*** Get the color of the display sprite.
|
||||
@function DisplaySprite:GetColor()
|
||||
@treturn Color Color.
|
||||
*/
|
||||
ScriptReserved_DisplayStringGetColor, &ScriptDisplaySprite::GetColor,
|
||||
|
||||
/*** Set the sprite sequence object ID used by the display sprite.
|
||||
@function DisplaySprite:SetObjectID(Objects.ObjID)
|
||||
@tparam Objects.ObjID New sprite sequence object ID.
|
||||
*/
|
||||
ScriptReserved_DisplayStringSetObjectID, &ScriptDisplaySprite::SetObjectID,
|
||||
|
||||
/*** Set the sprite ID in the sprite sequence object used by the display sprite.
|
||||
@function DisplaySprite:SetSpriteID(int)
|
||||
@tparam int New sprite ID in the sprite sequence object.
|
||||
*/
|
||||
ScriptReserved_DisplayStringSetSpriteID, &ScriptDisplaySprite::SetSpriteID,
|
||||
|
||||
/*** Set the display position of the display sprite in percent.
|
||||
@function DisplaySprite:SetPosition(Vec2)
|
||||
@tparam Vec2 New display position in percent.
|
||||
*/
|
||||
ScriptReserved_DisplayStringSetPosition, &ScriptDisplaySprite::SetPosition,
|
||||
|
||||
/*** Set the rotation of the display sprite in degrees.
|
||||
@function DisplaySprite:SetRotation(float)
|
||||
@tparam float New rotation in degrees.
|
||||
*/
|
||||
ScriptReserved_DisplayStringSetRotation, &ScriptDisplaySprite::SetRotation,
|
||||
|
||||
/*** Set the horizontal and vertical scale of the display sprite in percent.
|
||||
@function DisplaySprite:SetScale(Vec2)
|
||||
@tparam float New horizontal and vertical scale in percent.
|
||||
*/
|
||||
ScriptReserved_DisplayStringSetScale, &ScriptDisplaySprite::SetScale,
|
||||
|
||||
/*** Set the color of the display sprite.
|
||||
@function DisplaySprite:SetColor(Color)
|
||||
@tparam float New color.
|
||||
*/
|
||||
ScriptReserved_DisplayStringSetColor, &ScriptDisplaySprite::SetColor,
|
||||
|
||||
/*** Draw the display sprite in display space for the current frame.
|
||||
@function DisplaySprite:Draw
|
||||
@tparam Objects.ObjID[opt] priority Draw priority. Can be thought of as a layer, with higher values having precedence. __Default: 0__
|
||||
@tparam DisplaySprite.AlignMode[opt] alignMode Align mode interpreting an offset from the sprite's position. __Default: DisplaySprite.AlignMode.CENTER__
|
||||
@tparam DisplaySprite.ScaleMode[opt] scaleMode Scale mode interpreting the display sprite's horizontal and vertical scale. __Default: DisplaySprite.ScaleMode.FIT__
|
||||
@tparam Effects.BlendID[opt] blendMode Blend mode. __Default: Effects.BlendID.ALPHABLEND__
|
||||
*/
|
||||
ScriptReserved_DisplaySpriteDraw, &ScriptDisplaySprite::Draw);
|
||||
|
||||
auto table = sol::table(state.lua_state(), sol::create);
|
||||
parent.set(ScriptReserved_DisplaySpriteEnum, table);
|
||||
|
||||
// Register enums.
|
||||
auto handler = LuaHandler(&state);
|
||||
handler.MakeReadOnlyTable(table, ScriptReserved_DisplaySpriteEnumAlignMode, DISPLAY_SPRITE_ALIGN_MODES);
|
||||
handler.MakeReadOnlyTable(table, ScriptReserved_DisplaySpriteEnumScaleMode, DISPLAY_SPRITE_SCALE_MODES);
|
||||
}
|
||||
|
||||
/*** Create a DisplaySprite.
|
||||
@function DisplaySprite
|
||||
@tparam Objects.ObjID ID of the sprite sequence object.
|
||||
@tparam int int spriteID ID of the sprite in the sequence.
|
||||
@tparam Vec2 pos Display position in percent.
|
||||
@tparam float rot Rotation in degrees.
|
||||
@tparam Vec2 scale Horizontal and vertical scale in percent. Scaling is interpreted by the DisplaySpriteEnum.ScaleMode passed to the Draw() function call.
|
||||
@tparam Color color[opt] Color. __Default: Color(255, 255, 255, 255)__
|
||||
@treturn DisplaySprite A new DisplaySprite object.
|
||||
*/
|
||||
ScriptDisplaySprite::ScriptDisplaySprite(GAME_OBJECT_ID objectID, int spriteID, const Vec2& pos, float rot, const Vec2& scale, const ScriptColor& color)
|
||||
{
|
||||
ObjectID = objectID;
|
||||
SpriteID = spriteID;
|
||||
Position = pos;
|
||||
Rotation = rot;
|
||||
Scale = scale;
|
||||
Color = color;
|
||||
}
|
||||
|
||||
ScriptDisplaySprite::ScriptDisplaySprite(GAME_OBJECT_ID objectID, int spriteID, const Vec2& pos, float rot, const Vec2& scale)
|
||||
{
|
||||
static const auto DEFAULT_COLOR = ScriptColor(255, 255, 255, 255);
|
||||
|
||||
*this = ScriptDisplaySprite(objectID, spriteID, pos, rot, scale, DEFAULT_COLOR);
|
||||
}
|
||||
|
||||
GAME_OBJECT_ID ScriptDisplaySprite::GetObjectID() const
|
||||
{
|
||||
return ObjectID;
|
||||
}
|
||||
|
||||
int ScriptDisplaySprite::GetSpriteID() const
|
||||
{
|
||||
return SpriteID;
|
||||
}
|
||||
|
||||
Vec2 ScriptDisplaySprite::GetPosition() const
|
||||
{
|
||||
return Position;
|
||||
}
|
||||
|
||||
float ScriptDisplaySprite::GetRotation() const
|
||||
{
|
||||
return Rotation;
|
||||
}
|
||||
|
||||
Vec2 ScriptDisplaySprite::GetScale() const
|
||||
{
|
||||
return Scale;
|
||||
}
|
||||
|
||||
ScriptColor ScriptDisplaySprite::GetColor() const
|
||||
{
|
||||
return Color;
|
||||
}
|
||||
|
||||
void ScriptDisplaySprite::SetObjectID(GAME_OBJECT_ID objectID)
|
||||
{
|
||||
ObjectID = objectID;
|
||||
}
|
||||
|
||||
void ScriptDisplaySprite::SetSpriteID(int spriteID)
|
||||
{
|
||||
SpriteID = spriteID;
|
||||
}
|
||||
|
||||
void ScriptDisplaySprite::SetPosition(const Vec2& pos)
|
||||
{
|
||||
Position = pos;
|
||||
}
|
||||
|
||||
void ScriptDisplaySprite::SetRotation(float rot)
|
||||
{
|
||||
Rotation = rot;
|
||||
}
|
||||
|
||||
void ScriptDisplaySprite::SetScale(const Vec2& scale)
|
||||
{
|
||||
Scale = scale;
|
||||
}
|
||||
|
||||
void ScriptDisplaySprite::SetColor(const ScriptColor& color)
|
||||
{
|
||||
Color = color;
|
||||
}
|
||||
|
||||
void ScriptDisplaySprite::Draw(sol::optional<int> priority, sol::optional<DisplaySpriteAlignMode> alignMode,
|
||||
sol::optional<DisplaySpriteScaleMode> scaleMode, sol::optional<BLEND_MODES> blendMode)
|
||||
{
|
||||
// NOTE: Conversion from more intuitive 100x100 screen space resolution to internal 800x600 is required.
|
||||
// In a future refactor, everything will use 100x100 natively. -- Sezz 2023.08.31
|
||||
constexpr auto POS_CONVERSION_COEFF = Vector2(SCREEN_SPACE_RES.x / 100, SCREEN_SPACE_RES.y / 100);
|
||||
constexpr auto SCALE_CONVERSION_COEFF = 0.01f;
|
||||
|
||||
constexpr auto DEFAULT_PRIORITY = 0;
|
||||
constexpr auto DEFAULT_ALIGN_MODE = DisplaySpriteAlignMode::Center;
|
||||
constexpr auto DEFAULT_SCALE_MODE = DisplaySpriteScaleMode::Fit;
|
||||
constexpr auto DEFAULT_BLEND_MODE = BLENDMODE_ALPHABLEND;
|
||||
|
||||
// Object is not a sprite sequence object; return early.
|
||||
if (ObjectID < GAME_OBJECT_ID::ID_HORIZON || ObjectID >= GAME_OBJECT_ID::ID_NUMBER_OBJECTS)
|
||||
{
|
||||
TENLog("Attempted to draw display sprite from non-sprite sequence object " + std::to_string(ObjectID), LogLevel::Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
// Sprite missing or sequence not found; return early.
|
||||
const auto& object = Objects[ObjectID];
|
||||
if (!object.loaded || SpriteID >= abs(object.nmeshes))
|
||||
{
|
||||
TENLog(
|
||||
"Attempted to draw missing sprite " + std::to_string(SpriteID) +
|
||||
" from sprite sequence object " + std::to_string(ObjectID) +
|
||||
" as display sprite.",
|
||||
LogLevel::Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
auto convertedPos = Vector2(Position.x, Position.y) * POS_CONVERSION_COEFF;
|
||||
short convertedRot = ANGLE(Rotation);
|
||||
auto convertedScale = Vector2(Scale.x, Scale.y) * SCALE_CONVERSION_COEFF;
|
||||
auto convertedColor = Vector4(Color.GetR(), Color.GetG(), Color.GetB(), Color.GetA()) / UCHAR_MAX;
|
||||
|
||||
AddDisplaySprite(
|
||||
ObjectID, SpriteID,
|
||||
convertedPos, convertedRot, convertedScale, convertedColor,
|
||||
priority.value_or(DEFAULT_PRIORITY),
|
||||
alignMode.value_or(DEFAULT_ALIGN_MODE),
|
||||
scaleMode.value_or(DEFAULT_SCALE_MODE),
|
||||
blendMode.value_or(DEFAULT_BLEND_MODE));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
#pragma once
|
||||
#include "Game/effects/DisplaySprite.h"
|
||||
#include "Objects/game_object_ids.h"
|
||||
#include "Scripting/Internal/TEN/Color/Color.h"
|
||||
#include "Scripting/Internal/TEN/Vec2/Vec2.h"
|
||||
|
||||
using namespace TEN::Effects::DisplaySprite;
|
||||
|
||||
enum BLEND_MODE;
|
||||
|
||||
namespace TEN::Scripting::DisplaySprite
|
||||
{
|
||||
class ScriptDisplaySprite
|
||||
{
|
||||
public:
|
||||
static void Register(sol::state& state, sol::table& parent);
|
||||
|
||||
private:
|
||||
// Members
|
||||
GAME_OBJECT_ID ObjectID = GAME_OBJECT_ID::ID_DEFAULT_SPRITES;
|
||||
int SpriteID = 0;
|
||||
|
||||
Vec2 Position = Vec2(0.0f, 0.0f);
|
||||
float Rotation = 0.0f;
|
||||
Vec2 Scale = Vec2(0.0f, 0.0f);
|
||||
ScriptColor Color = ScriptColor(255, 255, 255, 255);
|
||||
|
||||
public:
|
||||
// Constructors
|
||||
ScriptDisplaySprite(GAME_OBJECT_ID objectID, int spriteID, const Vec2& pos, float rot, const Vec2& scale, const ScriptColor& color);
|
||||
ScriptDisplaySprite(GAME_OBJECT_ID objectID, int spriteID, const Vec2& pos, float rot, const Vec2& scale);
|
||||
|
||||
// Getters
|
||||
GAME_OBJECT_ID GetObjectID() const;
|
||||
int GetSpriteID() const;
|
||||
Vec2 GetPosition() const;
|
||||
float GetRotation() const;
|
||||
Vec2 GetScale() const;
|
||||
ScriptColor GetColor() const;
|
||||
|
||||
// Setters
|
||||
void SetObjectID(GAME_OBJECT_ID objectID);
|
||||
void SetSpriteID(int spriteID);
|
||||
void SetPosition(const Vec2& pos);
|
||||
void SetRotation(float rot);
|
||||
void SetScale(const Vec2& scale);
|
||||
void SetColor(const ScriptColor& color);
|
||||
|
||||
// Utilities
|
||||
void Draw(sol::optional<int> priority, sol::optional<DisplaySpriteAlignMode> alignMode,
|
||||
sol::optional<DisplaySpriteScaleMode> scaleMode, sol::optional<BLEND_MODES> blendMode);
|
||||
};
|
||||
}
|
|
@ -1,10 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
// Last generated on 31/7/2022.
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "Renderer/Renderer11Enums.h"
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
|
||||
/***
|
||||
Constants for blend mode IDs.
|
||||
|
@ -34,17 +32,16 @@ The following constants are inside BlendID.
|
|||
@table CONSTANT_STRING_HERE
|
||||
*/
|
||||
|
||||
|
||||
static const std::unordered_map<std::string, BLEND_MODES> BLEND_IDS
|
||||
{
|
||||
{"OPAQUE", BLENDMODE_OPAQUE},
|
||||
{"ALPHATEST", BLENDMODE_ALPHATEST},
|
||||
{"ADDITIVE", BLENDMODE_ADDITIVE},
|
||||
{"NOZTEST", BLENDMODE_NOZTEST},
|
||||
{"SUBTRACTIVE", BLENDMODE_SUBTRACTIVE},
|
||||
{"WIREFRAME", BLENDMODE_WIREFRAME},
|
||||
{"EXCLUDE", BLENDMODE_EXCLUDE},
|
||||
{"SCREEN", BLENDMODE_SCREEN},
|
||||
{"LIGHTEN", BLENDMODE_LIGHTEN},
|
||||
{"ALPHABLEND", BLENDMODE_ALPHABLEND}
|
||||
{ "OPAQUE", BLENDMODE_OPAQUE },
|
||||
{ "ALPHATEST", BLENDMODE_ALPHATEST },
|
||||
{ "ADDITIVE", BLENDMODE_ADDITIVE },
|
||||
{ "NOZTEST", BLENDMODE_NOZTEST },
|
||||
{ "SUBTRACTIVE", BLENDMODE_SUBTRACTIVE },
|
||||
{ "WIREFRAME", BLENDMODE_WIREFRAME },
|
||||
{ "EXCLUDE", BLENDMODE_EXCLUDE },
|
||||
{ "SCREEN", BLENDMODE_SCREEN },
|
||||
{ "LIGHTEN", BLENDMODE_LIGHTEN },
|
||||
{ "ALPHABLEND", BLENDMODE_ALPHABLEND }
|
||||
};
|
||||
|
|
|
@ -32,11 +32,11 @@ The following constants are inside EffectID.
|
|||
|
||||
static const std::unordered_map<std::string, EffectType> EFFECT_IDS
|
||||
{
|
||||
{"NONE", EffectType::None},
|
||||
{"FIRE", EffectType::Fire},
|
||||
{"SPARKS", EffectType::Sparks},
|
||||
{"SMOKE", EffectType::Smoke},
|
||||
{"ELECTRICIGNITE", EffectType::ElectricIgnite},
|
||||
{"REDIGNITE", EffectType::RedIgnite},
|
||||
{"CUSTOM", EffectType::Custom}
|
||||
{ "NONE", EffectType::None },
|
||||
{ "FIRE", EffectType::Fire },
|
||||
{ "SPARKS", EffectType::Sparks },
|
||||
{ "SMOKE", EffectType::Smoke},
|
||||
{ "ELECTRICIGNITE", EffectType::ElectricIgnite },
|
||||
{ "REDIGNITE", EffectType::RedIgnite },
|
||||
{ "CUSTOM", EffectType::Custom }
|
||||
};
|
||||
|
|
|
@ -3,9 +3,10 @@
|
|||
|
||||
#include "Game/camera.h"
|
||||
#include "Game/collision/collide_room.h"
|
||||
#include "Game/control/los.h"
|
||||
#include "Game/effects/DisplaySprite.h"
|
||||
#include "Game/effects/effects.h"
|
||||
#include "Game/effects/Electricity.h"
|
||||
#include "Game/control/los.h"
|
||||
#include "Game/effects/explosion.h"
|
||||
#include "Game/effects/spark.h"
|
||||
#include "Game/effects/tomb4fx.h"
|
||||
|
@ -19,6 +20,7 @@
|
|||
#include "Scripting/Internal/TEN/Effects/BlendIDs.h"
|
||||
#include "Scripting/Internal/TEN/Effects/EffectIDs.h"
|
||||
#include "Scripting/Internal/TEN/Vec3/Vec3.h"
|
||||
#include "Scripting/Internal/TEN/Vec2/Vec2.h"
|
||||
#include "Sound/sound.h"
|
||||
#include "Specific/clock.h"
|
||||
|
||||
|
@ -28,6 +30,7 @@ Functions to generate effects.
|
|||
@pragma nostrip
|
||||
*/
|
||||
|
||||
using namespace TEN::Effects::DisplaySprite;
|
||||
using namespace TEN::Effects::Electricity;
|
||||
using namespace TEN::Effects::Environment;
|
||||
using namespace TEN::Effects::Explosion;
|
||||
|
@ -318,9 +321,9 @@ namespace Effects
|
|||
Weather.Flash(color.GetR(), color.GetG(), color.GetB(), (USE_IF_HAVE(float, speed, 1.0)) / (float)FPS);
|
||||
}
|
||||
|
||||
void Register(sol::state* state, sol::table& parent)
|
||||
void Register(sol::state* state, sol::table& parent)
|
||||
{
|
||||
sol::table tableEffects = { state->lua_state(), sol::create };
|
||||
auto tableEffects = sol::table(state->lua_state(), sol::create);
|
||||
parent.set(ScriptReserved_Effects, tableEffects);
|
||||
|
||||
tableEffects.set_function(ScriptReserved_EmitLightningArc, &EmitLightningArc);
|
||||
|
@ -333,7 +336,7 @@ namespace Effects
|
|||
tableEffects.set_function(ScriptReserved_FlashScreen, &FlashScreen);
|
||||
tableEffects.set_function(ScriptReserved_MakeEarthquake, &Earthquake);
|
||||
|
||||
LuaHandler handler{ state };
|
||||
auto handler = LuaHandler{ state };
|
||||
handler.MakeReadOnlyTable(tableEffects, ScriptReserved_BlendID, BLEND_IDS);
|
||||
handler.MakeReadOnlyTable(tableEffects, ScriptReserved_EffectID, EFFECT_IDS);
|
||||
}
|
||||
|
|
|
@ -20,5 +20,5 @@ struct Animations
|
|||
bool HasOverhangClimb; // Overhang functionality.
|
||||
bool HasLedgeJumps; // Jump up or back from a ledge.
|
||||
|
||||
static void Register(sol::table &);
|
||||
static void Register(sol::table&);
|
||||
};
|
||||
|
|
|
@ -8,6 +8,9 @@
|
|||
#include "Scripting/Include/Objects/ScriptInterfaceObjectsHandler.h"
|
||||
#include "Scripting/Include/Strings/ScriptInterfaceStringsHandler.h"
|
||||
#include "Scripting/Internal/ReservedScriptNames.h"
|
||||
#include "Scripting/Internal/TEN/DisplaySprite/AlignModes.h"
|
||||
#include "Scripting/Internal/TEN/DisplaySprite/ScaleModes.h"
|
||||
#include "Scripting/Internal/TEN/DisplaySprite/ScriptDisplaySprite.h"
|
||||
#include "Scripting/Internal/TEN/Flow/InventoryItem/InventoryItem.h"
|
||||
#include "Scripting/Internal/TEN/Logic/LevelFunc.h"
|
||||
#include "Scripting/Internal/TEN/Vec2/Vec2.h"
|
||||
|
@ -15,6 +18,8 @@
|
|||
#include "Sound/sound.h"
|
||||
#include "Specific/trutils.h"
|
||||
|
||||
using namespace TEN::Scripting::DisplaySprite;
|
||||
|
||||
/***
|
||||
Functions that (mostly) don't directly impact in-game mechanics. Used for setup
|
||||
in gameflow.lua, settings.lua and strings.lua; some can be used in level
|
||||
|
@ -28,7 +33,8 @@ ScriptInterfaceObjectsHandler* g_GameScriptEntities;
|
|||
ScriptInterfaceStringsHandler* g_GameStringsHandler;
|
||||
ScriptInterfaceFlowHandler* g_GameFlow;
|
||||
|
||||
FlowHandler::FlowHandler(sol::state* lua, sol::table& parent) : m_handler(lua)
|
||||
FlowHandler::FlowHandler(sol::state* lua, sol::table& parent) :
|
||||
m_handler(lua)
|
||||
{
|
||||
/*** gameflow.lua.
|
||||
These functions are called in gameflow.lua, a file loosely equivalent to winroomedit's SCRIPT.DAT.
|
||||
|
@ -151,6 +157,14 @@ level count, jumps to title.
|
|||
*/
|
||||
tableFlow.set_function(ScriptReserved_DeleteSaveGame, &FlowHandler::DeleteSaveGame, this);
|
||||
|
||||
/***
|
||||
Check if a savegame exists.
|
||||
@function DoesSaveGameExist
|
||||
@tparam int slotID ID of the savegame slot to check.
|
||||
@treturn bool true if the savegame exists, false if not.
|
||||
*/
|
||||
tableFlow.set_function(ScriptReserved_DoesSaveGameExist, &FlowHandler::DoesSaveGameExist, this);
|
||||
|
||||
/***
|
||||
Returns the player's current per-game secret count.
|
||||
@function GetSecretCount
|
||||
|
@ -222,6 +236,7 @@ Specify which translations in the strings table correspond to which languages.
|
|||
tableFlow.set_function(ScriptReserved_SetLanguageNames, &FlowHandler::SetLanguageNames, this);
|
||||
|
||||
ScriptColor::Register(parent);
|
||||
ScriptDisplaySprite::Register(*lua, parent);
|
||||
Rotation::Register(parent);
|
||||
Vec2::Register(parent);
|
||||
Vec3::Register(parent);
|
||||
|
@ -233,11 +248,11 @@ Specify which translations in the strings table correspond to which languages.
|
|||
Settings::Register(tableFlow);
|
||||
Fog::Register(tableFlow);
|
||||
|
||||
m_handler.MakeReadOnlyTable(tableFlow, ScriptReserved_WeatherType, kWeatherTypes);
|
||||
m_handler.MakeReadOnlyTable(tableFlow, ScriptReserved_LaraType, kLaraTypes);
|
||||
m_handler.MakeReadOnlyTable(tableFlow, ScriptReserved_WeatherType, WEATHER_TYPES);
|
||||
m_handler.MakeReadOnlyTable(tableFlow, ScriptReserved_LaraType, PLAYER_TYPES);
|
||||
m_handler.MakeReadOnlyTable(tableFlow, ScriptReserved_RotationAxis, ROTATION_AXES);
|
||||
m_handler.MakeReadOnlyTable(tableFlow, ScriptReserved_ItemAction, ITEM_MENU_ACTIONS);
|
||||
m_handler.MakeReadOnlyTable(tableFlow, ScriptReserved_ErrorMode, kErrorModes);
|
||||
m_handler.MakeReadOnlyTable(tableFlow, ScriptReserved_ErrorMode, ERROR_MODES);
|
||||
}
|
||||
|
||||
FlowHandler::~FlowHandler()
|
||||
|
@ -430,6 +445,11 @@ void FlowHandler::DeleteSaveGame(int slot)
|
|||
SaveGame::Delete(slot);
|
||||
}
|
||||
|
||||
bool FlowHandler::DoesSaveGameExist(int slot)
|
||||
{
|
||||
return SaveGame::DoesSaveGameExist(slot, true);
|
||||
}
|
||||
|
||||
int FlowHandler::GetSecretCount() const
|
||||
{
|
||||
return Statistics.Game.Secrets;
|
||||
|
|
|
@ -63,6 +63,7 @@ public:
|
|||
void SaveGame(int slot);
|
||||
void LoadGame(int slot);
|
||||
void DeleteSaveGame(int slot);
|
||||
bool DoesSaveGameExist(int slot);
|
||||
int GetSecretCount() const;
|
||||
void SetSecretCount(int secretsNum);
|
||||
void AddSecret(int levelSecretIndex);
|
||||
|
|
|
@ -8,7 +8,7 @@ Fog
|
|||
@pragma nostrip
|
||||
*/
|
||||
|
||||
void Fog::Register(sol::table & parent)
|
||||
void Fog::Register(sol::table& parent)
|
||||
{
|
||||
using ctors = sol::constructors<Fog(ScriptColor const&, short, short)>;
|
||||
parent.new_usertype<Fog>("Fog",
|
||||
|
|
|
@ -20,5 +20,5 @@ struct Fog
|
|||
void SetColor(ScriptColor const& col);
|
||||
ScriptColor GetColor() const;
|
||||
|
||||
static void Register(sol::table &);
|
||||
static void Register(sol::table&);
|
||||
};
|
||||
|
|
|
@ -14,7 +14,7 @@ These are things things which aren't present in the compiled level file itself.
|
|||
@function Level
|
||||
@treturn Level a Level object
|
||||
*/
|
||||
void Level::Register(sol::table & parent)
|
||||
void Level::Register(sol::table& parent)
|
||||
{
|
||||
parent.new_usertype<Level>("Level",
|
||||
sol::constructors<Level()>(),
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include "Scripting/Include/ScriptInterfaceLevel.h"
|
||||
#include "Scripting/Internal/TEN/Flow/InventoryItem/InventoryItem.h"
|
||||
|
||||
static const std::unordered_map<std::string, WeatherType> kWeatherTypes
|
||||
static const std::unordered_map<std::string, WeatherType> WEATHER_TYPES
|
||||
{
|
||||
{"None", WeatherType::None},
|
||||
{"Rain", WeatherType::Rain},
|
||||
|
@ -14,7 +14,7 @@ static const std::unordered_map<std::string, WeatherType> kWeatherTypes
|
|||
};
|
||||
|
||||
|
||||
static const std::unordered_map<std::string, LaraType> kLaraTypes
|
||||
static const std::unordered_map<std::string, LaraType> PLAYER_TYPES
|
||||
{
|
||||
{"Normal", LaraType::Normal},
|
||||
{"Young", LaraType::Young},
|
||||
|
@ -50,7 +50,7 @@ struct Level : public ScriptInterfaceLevel
|
|||
LaraType GetLaraType() const override;
|
||||
void SetWeatherStrength(float val);
|
||||
void SetLevelFarView(short val);
|
||||
static void Register(sol::table & parent);
|
||||
static void Register(sol::table& parent);
|
||||
WeatherType GetWeatherType() const override;
|
||||
short GetMirrorRoom() const override;
|
||||
short GetFogMinDistance() const override;
|
||||
|
|
|
@ -12,7 +12,7 @@ struct Mirror
|
|||
int StartZ{ 0 };
|
||||
int EndZ{ 0 };
|
||||
|
||||
static void Register(sol::table & parent);
|
||||
static void Register(sol::table& parent);
|
||||
Mirror() = default;
|
||||
|
||||
Mirror(short room, int startX, int endX, int startZ, int endZ);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#include "Scripting/Internal/ScriptAssert.h"
|
||||
#include <string>
|
||||
|
||||
static const std::unordered_map<std::string, ErrorMode> kErrorModes {
|
||||
static const std::unordered_map<std::string, ErrorMode> ERROR_MODES {
|
||||
{"SILENT", ErrorMode::Silent},
|
||||
{"WARN", ErrorMode::Warn},
|
||||
{"TERMINATE", ErrorMode::Terminate}
|
||||
|
|
|
@ -61,12 +61,12 @@ namespace InventoryHandler
|
|||
|
||||
void Register(sol::state* state, sol::table& parent)
|
||||
{
|
||||
sol::table table_inventory{ state->lua_state(), sol::create };
|
||||
parent.set(ScriptReserved_Inventory, table_inventory);
|
||||
auto tableInventory = sol::table{ state->lua_state(), sol::create };
|
||||
parent.set(ScriptReserved_Inventory, tableInventory);
|
||||
|
||||
table_inventory.set_function(ScriptReserved_GiveInvItem, &GiveItem);
|
||||
table_inventory.set_function(ScriptReserved_TakeInvItem, &TakeItem);
|
||||
table_inventory.set_function(ScriptReserved_GetInvItemCount, &GetItemCount);
|
||||
table_inventory.set_function(ScriptReserved_SetInvItemCount, &SetItemCount);
|
||||
tableInventory.set_function(ScriptReserved_GiveInvItem, &GiveItem);
|
||||
tableInventory.set_function(ScriptReserved_TakeInvItem, &TakeItem);
|
||||
tableInventory.set_function(ScriptReserved_GetInvItemCount, &GetItemCount);
|
||||
tableInventory.set_function(ScriptReserved_SetInvItemCount, &SetItemCount);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,10 +14,12 @@
|
|||
#include "Scripting/Internal/ReservedScriptNames.h"
|
||||
#include "Scripting/Internal/ScriptAssert.h"
|
||||
#include "Scripting/Internal/ScriptUtil.h"
|
||||
#include "Scripting/Internal/TEN/Color/Color.h"
|
||||
#include "Scripting/Internal/TEN/Misc/ActionIDs.h"
|
||||
#include "Scripting/Internal/TEN/Misc/CameraTypes.h"
|
||||
#include "Scripting/Internal/TEN/Misc/LevelLog.h"
|
||||
#include "Scripting/Internal/TEN/Misc/SoundTrackTypes.h"
|
||||
#include "Scripting/Internal/TEN/Vec2/Vec2.h"
|
||||
#include "Scripting/Internal/TEN/Vec3/Vec3.h"
|
||||
#include "Sound/sound.h"
|
||||
#include "Specific/clock.h"
|
||||
|
@ -308,11 +310,12 @@ namespace Misc
|
|||
return (int)round(Vector3::Distance(p1, p2));
|
||||
}
|
||||
|
||||
// TODO: Deprecated. Also should not use int!
|
||||
///Calculate the horizontal distance between two positions.
|
||||
//@function CalculateHorizontalDistance
|
||||
//@tparam Vec3 posA first position
|
||||
//@tparam Vec3 posB second position
|
||||
//@treturn int the direct distance on the XZ plane from one position to the other
|
||||
//@treturn float the direct distance on the XZ plane from one position to the other
|
||||
static int CalculateHorizontalDistance(const Vec3& pos1, const Vec3& pos2)
|
||||
{
|
||||
auto p1 = Vector2(pos1.x, pos1.z);
|
||||
|
@ -320,49 +323,49 @@ namespace Misc
|
|||
return (int)round(Vector2::Distance(p1, p2));
|
||||
}
|
||||
|
||||
///Translate a pair of percentages to screen-space pixel coordinates.
|
||||
//To be used with @{Strings.DisplayString:SetPosition} and @{Strings.DisplayString}.
|
||||
/// Translate a pair display position coordinates to pixel coordinates.
|
||||
//To be used with @{ Strings.DisplayString:SetPosition } and @{ Strings.DisplayString }.
|
||||
//@function PercentToScreen
|
||||
//@tparam float x percent value to translate to x-coordinate
|
||||
//@tparam float y percent value to translate to y-coordinate
|
||||
//@treturn int x coordinate in pixels
|
||||
//@treturn int y coordinate in pixels
|
||||
//@tparam float x X component of the display position.
|
||||
//@tparam float y Y component of the display position.
|
||||
//@treturn int x X coordinate in pixels.
|
||||
//@treturn int y Y coordinate in pixels.
|
||||
//@usage
|
||||
//local halfwayX, halfwayY = PercentToScreen(50, 50)
|
||||
//local baddy
|
||||
//local spawnLocationNullmesh = GetMoveableByName("position_behind_left_pillar")
|
||||
//local str1 = DisplayString("You spawned a baddy!", halfwayX, halfwayY, Color(255, 100, 100), false, {DisplayStringOption.SHADOW, DisplayStringOption.CENTER})
|
||||
//local str1 = DisplayString("You spawned an enemy!", halfwayX, halfwayY, Color(255, 100, 100), false, { DisplayStringOption.SHADOW, DisplayStringOption.CENTER })
|
||||
//
|
||||
//LevelFuncs.triggerOne = function(obj)
|
||||
// ShowString(str1, 4)
|
||||
//end
|
||||
static std::tuple<int, int> PercentToScreen(double x, double y)
|
||||
static std::tuple<int, int> PercentToScreen(float x, float y)
|
||||
{
|
||||
auto fWidth = static_cast<double>(g_Configuration.ScreenWidth);
|
||||
auto fHeight = static_cast<double>(g_Configuration.ScreenHeight);
|
||||
int resX = static_cast<int>(std::round(fWidth / 100.0 * x));
|
||||
int resY = static_cast<int>(std::round(fHeight / 100.0 * y));
|
||||
//todo this still assumes a resolution of 800/600. account for this somehow
|
||||
float fWidth = g_Configuration.ScreenWidth;
|
||||
float fHeight = g_Configuration.ScreenHeight;
|
||||
int resX = (int)std::round(fWidth / 100.0f * x);
|
||||
int resY = (int)std::round(fHeight / 100.0f * y);
|
||||
|
||||
return std::make_tuple(resX, resY);
|
||||
}
|
||||
|
||||
///Translate a pair of coordinates to percentages of window dimensions.
|
||||
//To be used with @{Strings.DisplayString:GetPosition}.
|
||||
/// Translate a pair of pixel coordinates to display position coordinates.
|
||||
//To be used with @{ Strings.DisplayString:GetPosition }.
|
||||
//@function ScreenToPercent
|
||||
//@tparam int x pixel value to translate to a percentage of the window width
|
||||
//@tparam int y pixel value to translate to a percentage of the window height
|
||||
//@treturn float x coordinate as percentage
|
||||
//@treturn float y coordinate as percentage
|
||||
static std::tuple<double, double> ScreenToPercent(int x, int y)
|
||||
//@tparam int x X pixel coordinate to translate to display position.
|
||||
//@tparam int y Y pixel coordinate to translate to display position.
|
||||
//@treturn float x X component of display position.
|
||||
//@treturn float y Y component of display position.
|
||||
static std::tuple<float, float> ScreenToPercent(int x, int y)
|
||||
{
|
||||
auto fWidth = static_cast<double>(g_Configuration.ScreenWidth);
|
||||
auto fHeight = static_cast<double>(g_Configuration.ScreenHeight);
|
||||
double resX = x / fWidth * 100.0;
|
||||
double resY = y / fHeight * 100.0;
|
||||
float fWidth = g_Configuration.ScreenWidth;
|
||||
float fHeight = g_Configuration.ScreenHeight;
|
||||
float resX = x / fWidth * 100.0f;
|
||||
float resY = y / fHeight * 100.0f;
|
||||
return std::make_tuple(resX, resY);
|
||||
}
|
||||
|
||||
/// Reset object camera back to Lara and deactivate object camera.
|
||||
/// Reset object camera back to the player and deactivate object camera.
|
||||
//@function ResetObjCamera
|
||||
static void ResetObjCamera()
|
||||
{
|
||||
|
|
|
@ -19,7 +19,7 @@ static auto newindex_error = newindex_error_maker(AIObject, ScriptReserved_AIObj
|
|||
AIObject::AIObject(AI_OBJECT & ref) : m_aiObject{ref}
|
||||
{};
|
||||
|
||||
void AIObject::Register(sol::table & parent)
|
||||
void AIObject::Register(sol::table& parent)
|
||||
{
|
||||
parent.new_usertype<AIObject>(ScriptReserved_AIObject,
|
||||
sol::no_constructor, // ability to spawn new ones could be added later
|
||||
|
|
|
@ -20,7 +20,7 @@ public:
|
|||
AIObject& operator=(AIObject const& other) = delete;
|
||||
AIObject(AIObject const& other) = delete;
|
||||
|
||||
static void Register(sol::table & parent);
|
||||
static void Register(sol::table& parent);
|
||||
|
||||
Vec3 GetPos() const;
|
||||
void SetPos(Vec3 const& pos);
|
||||
|
|
|
@ -22,7 +22,7 @@ static auto newindex_error = newindex_error_maker(CameraObject, ScriptReserved_C
|
|||
CameraObject::CameraObject(LevelCameraInfo & ref) : m_camera{ref}
|
||||
{};
|
||||
|
||||
void CameraObject::Register(sol::table & parent)
|
||||
void CameraObject::Register(sol::table& parent)
|
||||
{
|
||||
parent.new_usertype<CameraObject>(ScriptReserved_Camera,
|
||||
sol::no_constructor, // ability to spawn new ones could be added later
|
||||
|
|
|
@ -22,7 +22,7 @@ public:
|
|||
CameraObject& operator=(CameraObject const& other) = delete;
|
||||
CameraObject(CameraObject const& other) = delete;
|
||||
|
||||
static void Register(sol::table &);
|
||||
static void Register(sol::table&);
|
||||
Vec3 GetPos() const;
|
||||
void SetPos(Vec3 const& pos);
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ public:
|
|||
void UndrawWeapon();
|
||||
void ThrowAwayTorch();
|
||||
bool TorchIsLit() const;
|
||||
static void Register(sol::table & parent);
|
||||
static void Register(sol::table& parent);
|
||||
using Moveable::Moveable;
|
||||
};
|
||||
|
||||
|
|
|
@ -76,19 +76,18 @@ most can just be ignored (see usage).
|
|||
@tparam string name Lua name of the item
|
||||
@tparam Vec3 position position in level
|
||||
@tparam[opt] Rotation rotation rotation about x, y, and z axes (default Rotation(0, 0, 0))
|
||||
@int[opt] room room ID item is in (default: calculated automatically)
|
||||
@int[opt] roomID room ID item is in (default: calculated automatically)
|
||||
@int[opt=0] animNumber anim number
|
||||
@int[opt=0] frameNumber frame number
|
||||
@int[opt=10] hp HP of item
|
||||
@int[opt=0] OCB ocb of item (default 0)
|
||||
@tparam[opt] table AIBits table with AI bits (default {0,0,0,0,0,0})
|
||||
@tparam[opt] table AIBits table with AI bits (default { 0, 0, 0, 0, 0, 0 })
|
||||
@treturn Moveable A new Moveable object (a wrapper around the new object)
|
||||
@usage
|
||||
local item = Moveable(
|
||||
TEN.Objects.ObjID.PISTOLS_ITEM, -- object id
|
||||
"test", -- name
|
||||
Vec3(18907, 0, 21201)
|
||||
)
|
||||
Vec3(18907, 0, 21201))
|
||||
*/
|
||||
static std::unique_ptr<Moveable> Create(
|
||||
GAME_OBJECT_ID objID,
|
||||
|
|
|
@ -2157,6 +2157,7 @@ static const std::unordered_map<std::string, GAME_OBJECT_ID> kObjIDs {
|
|||
{ "AIR_BAR_TEXTURE", ID_AIR_BAR_TEXTURE },
|
||||
{ "DASH_BAR_TEXTURE", ID_DASH_BAR_TEXTURE },
|
||||
{ "SFX_BAR_TEXTURE", ID_SFX_BAR_TEXTURE },
|
||||
{ "CROSSHAIR", ID_CROSSHAIR },
|
||||
{ "PANEL_BORDER", ID_PANEL_BORDER },
|
||||
{ "PANEL_MIDDLE", ID_PANEL_MIDDLE },
|
||||
{ "PANEL_CORNER", ID_PANEL_CORNER },
|
||||
|
|
|
@ -19,14 +19,14 @@ when you need to use screen-space coordinates.
|
|||
@pragma nostrip
|
||||
*/
|
||||
|
||||
UserDisplayString::UserDisplayString(const std::string& key, int x, int y, float scale, D3DCOLOR color, const FlagArray& flags, bool translated) :
|
||||
m_key{ key },
|
||||
m_x{ x },
|
||||
m_y{ y },
|
||||
m_scale{ scale },
|
||||
m_color{ color },
|
||||
m_flags{ flags },
|
||||
m_isTranslated{ translated }
|
||||
UserDisplayString::UserDisplayString(const std::string& key, int x, int y, float scale, D3DCOLOR color, const FlagArray& flags, bool isTranslated) :
|
||||
m_key(key),
|
||||
m_x(x),
|
||||
m_y(y),
|
||||
m_scale(scale),
|
||||
m_color(color),
|
||||
m_flags(flags),
|
||||
m_isTranslated(isTranslated)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -120,21 +120,21 @@ void DisplayString::Register(sol::table& parent)
|
|||
/// Get the display string's color
|
||||
// @function DisplayString:GetColor
|
||||
// @treturn Color a copy of the display string's color
|
||||
ScriptReserved_GetColor, &DisplayString::GetCol,
|
||||
ScriptReserved_GetColor, &DisplayString::GetColor,
|
||||
|
||||
/// Set the display string's color
|
||||
// @function DisplayString:SetColor
|
||||
// @tparam Color color the new color of the display string
|
||||
ScriptReserved_SetColor, &DisplayString::SetCol,
|
||||
ScriptReserved_SetColor, &DisplayString::SetColor,
|
||||
|
||||
/// Get the string key to use. If `translated` is true when @{DisplayString}
|
||||
/// Get the string key to use. If `isTranslated` is true when @{ DisplayString }
|
||||
// is called, this will be the string key for the translation that will be displayed.
|
||||
// If false or omitted, this will be the string that's displayed.
|
||||
// @function DisplayString:GetKey
|
||||
// @treturn string the string to use
|
||||
ScriptReserved_GetKey, &DisplayString::GetKey,
|
||||
|
||||
/// Set the string key to use. If `translated` is true when @{DisplayString}
|
||||
/// Set the string key to use. If `isTranslated` is true when @{ DisplayString }
|
||||
// is called, this will be the string key for the translation that will be displayed.
|
||||
// If false or omitted, this will be the string that's displayed.
|
||||
// @function DisplayString:SetKey
|
||||
|
@ -154,15 +154,15 @@ void DisplayString::Register(sol::table& parent)
|
|||
/// Set the position of the string.
|
||||
// Screen-space coordinates are expected.
|
||||
// @function DisplayString:SetPosition
|
||||
// @tparam int x x-coordinate of the string
|
||||
// @tparam int y y-coordinate of the string
|
||||
// @tparam int x X component.
|
||||
// @tparam int y Y component.
|
||||
ScriptReserved_SetPosition, &DisplayString::SetPos,
|
||||
|
||||
/// Get the position of the string.
|
||||
// Screen-space coordinates are returned.
|
||||
// @function DisplayString:GetPosition
|
||||
// @treturn int x-coordinate of the string
|
||||
// @treturn int y-coordinate of the string
|
||||
// @treturn int x X component.
|
||||
// @treturn int y Y component.
|
||||
ScriptReserved_GetPosition, &DisplayString::GetPos,
|
||||
|
||||
/// Set the display string's flags
|
||||
|
@ -183,8 +183,7 @@ void DisplayString::Register(sol::table& parent)
|
|||
// @function DisplayString:SetTranslated
|
||||
// @tparam bool shouldTranslate if true, the string's key will be used as the key for the translation that will be displayed.
|
||||
// If false, the key itself will be displayed
|
||||
ScriptReserved_SetTranslated, &DisplayString::SetTranslated
|
||||
);
|
||||
ScriptReserved_SetTranslated, &DisplayString::SetTranslated);
|
||||
}
|
||||
|
||||
DisplayStringIDType DisplayString::GetID() const
|
||||
|
@ -217,7 +216,7 @@ std::tuple<int, int> DisplayString::GetPos() const
|
|||
return std::make_tuple(displayString.m_x, displayString.m_y);
|
||||
}
|
||||
|
||||
void DisplayString::SetCol(const ScriptColor& color)
|
||||
void DisplayString::SetColor(const ScriptColor& color)
|
||||
{
|
||||
UserDisplayString& displayString = s_getItemCallback(m_id).value();
|
||||
displayString.m_color = color;
|
||||
|
@ -226,10 +225,10 @@ void DisplayString::SetCol(const ScriptColor& color)
|
|||
//s_addItemCallback(m_id, s);
|
||||
}
|
||||
|
||||
ScriptColor DisplayString::GetCol()
|
||||
ScriptColor DisplayString::GetColor()
|
||||
{
|
||||
UserDisplayString& s = s_getItemCallback(m_id).value();
|
||||
return s.m_color;
|
||||
UserDisplayString& displayString = s_getItemCallback(m_id).value();
|
||||
return displayString.m_color;
|
||||
}
|
||||
|
||||
void DisplayString::SetKey(const std::string& key)
|
||||
|
|
|
@ -4,24 +4,25 @@
|
|||
|
||||
#include "Scripting/Internal/TEN/Color/Color.h"
|
||||
|
||||
enum class DisplayStringOptions : size_t
|
||||
enum class DisplayStringOptions
|
||||
{
|
||||
CENTER,
|
||||
OUTLINE,
|
||||
RIGHT,
|
||||
BLINK,
|
||||
NUM_OPTIONS
|
||||
Center,
|
||||
Outline,
|
||||
Right,
|
||||
Blink,
|
||||
|
||||
Count
|
||||
};
|
||||
|
||||
static const std::unordered_map<std::string, DisplayStringOptions> kDisplayStringOptionNames
|
||||
static const std::unordered_map<std::string, DisplayStringOptions> DISPLAY_STRING_OPTION_NAMES
|
||||
{
|
||||
{"CENTER", DisplayStringOptions::CENTER},
|
||||
{"SHADOW", DisplayStringOptions::OUTLINE},
|
||||
{"RIGHT", DisplayStringOptions::RIGHT},
|
||||
{"BLINK", DisplayStringOptions::BLINK}
|
||||
{ "CENTER", DisplayStringOptions::Center },
|
||||
{ "SHADOW", DisplayStringOptions::Outline },
|
||||
{ "RIGHT", DisplayStringOptions::Right },
|
||||
{ "BLINK", DisplayStringOptions::Blink }
|
||||
};
|
||||
|
||||
using FlagArray = std::array<bool, static_cast<size_t>(DisplayStringOptions::NUM_OPTIONS)>;
|
||||
using FlagArray = std::array<bool, (int)DisplayStringOptions::Count>;
|
||||
// Used to store data used to render the string.
|
||||
// This is separate from DisplayString because the lifetimes of the classes differ slightly.
|
||||
|
||||
|
@ -69,8 +70,8 @@ public:
|
|||
void SetPos(int x, int y);
|
||||
std::tuple<int, int> GetPos() const;
|
||||
|
||||
void SetCol(const ScriptColor&);
|
||||
ScriptColor GetCol();
|
||||
void SetColor(const ScriptColor&);
|
||||
ScriptColor GetColor();
|
||||
|
||||
void SetKey(const std::string&);
|
||||
std::string GetKey() const;
|
||||
|
|
|
@ -12,7 +12,8 @@ On-screen strings.
|
|||
@pragma nostrip
|
||||
*/
|
||||
|
||||
StringsHandler::StringsHandler(sol::state* lua, sol::table & parent) : LuaHandler{ lua }
|
||||
StringsHandler::StringsHandler(sol::state* lua, sol::table& parent) :
|
||||
LuaHandler{ lua }
|
||||
{
|
||||
sol::table table_strings{ m_lua->lua_state(), sol::create };
|
||||
parent.set(ScriptReserved_Strings, table_strings);
|
||||
|
@ -46,12 +47,11 @@ Checks if the string is shown
|
|||
|
||||
DisplayString::Register(table_strings);
|
||||
DisplayString::SetCallbacks(
|
||||
[this](auto && ... param) {return SetDisplayString(std::forward<decltype(param)>(param)...); },
|
||||
[this](auto && ... param) {return ScheduleRemoveDisplayString(std::forward<decltype(param)>(param)...); },
|
||||
[this](auto && ... param) {return GetDisplayString(std::forward<decltype(param)>(param)...); }
|
||||
);
|
||||
[this](auto && ... param) { return SetDisplayString(std::forward<decltype(param)>(param)...); },
|
||||
[this](auto && ... param) { return ScheduleRemoveDisplayString(std::forward<decltype(param)>(param)...); },
|
||||
[this](auto && ... param) { return GetDisplayString(std::forward<decltype(param)>(param)...); });
|
||||
|
||||
MakeReadOnlyTable(table_strings, ScriptReserved_DisplayStringOption, kDisplayStringOptionNames);
|
||||
MakeReadOnlyTable(table_strings, ScriptReserved_DisplayStringOption, DISPLAY_STRING_OPTION_NAMES);
|
||||
}
|
||||
|
||||
std::optional<std::reference_wrapper<UserDisplayString>> StringsHandler::GetDisplayString(DisplayStringIDType id)
|
||||
|
@ -116,16 +116,16 @@ void StringsHandler::ProcessDisplayStrings(float deltaTime)
|
|||
auto cstr = str.m_isTranslated ? g_GameFlow->GetString(str.m_key.c_str()) : str.m_key.c_str();
|
||||
int flags = 0;
|
||||
|
||||
if (str.m_flags[static_cast<size_t>(DisplayStringOptions::CENTER)])
|
||||
if (str.m_flags[(size_t)DisplayStringOptions::Center])
|
||||
flags |= PRINTSTRING_CENTER;
|
||||
|
||||
if (str.m_flags[static_cast<size_t>(DisplayStringOptions::RIGHT)])
|
||||
if (str.m_flags[(size_t)DisplayStringOptions::Right])
|
||||
flags |= PRINTSTRING_RIGHT;
|
||||
|
||||
if (str.m_flags[static_cast<size_t>(DisplayStringOptions::OUTLINE)])
|
||||
if (str.m_flags[(size_t)DisplayStringOptions::Outline])
|
||||
flags |= PRINTSTRING_OUTLINE;
|
||||
|
||||
if (str.m_flags[static_cast<size_t>(DisplayStringOptions::BLINK)])
|
||||
if (str.m_flags[(size_t)DisplayStringOptions::Blink])
|
||||
flags |= PRINTSTRING_BLINK;
|
||||
|
||||
m_callbackDrawSring(cstr, str.m_color, str.m_x, str.m_y, str.m_scale, flags);
|
||||
|
|
|
@ -1,32 +1,31 @@
|
|||
#include "./VertexInput.hlsli"
|
||||
|
||||
struct PixelShaderInput
|
||||
{
|
||||
float4 Position: SV_POSITION;
|
||||
float2 UV: TEXCOORD;
|
||||
float4 Color: COLOR;
|
||||
};
|
||||
|
||||
Texture2D Texture : register(t0);
|
||||
SamplerState Sampler : register(s0);
|
||||
|
||||
PixelShaderInput VS(VertexShaderInput input)
|
||||
{
|
||||
PixelShaderInput output;
|
||||
|
||||
output.Position = float4(input.Position, 1.0f);
|
||||
output.Color = input.Color;
|
||||
output.UV = input.UV;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
float4 PS(PixelShaderInput input) : SV_TARGET
|
||||
{
|
||||
float4 output = Texture.Sample(Sampler, input.UV);
|
||||
float3 colorMul = min(input.Color.xyz, 1.0f);
|
||||
output.xyz = output.xyz * colorMul.xyz;
|
||||
//output.w = 1.0f;
|
||||
|
||||
return output;
|
||||
}
|
||||
#include "./VertexInput.hlsli"
|
||||
|
||||
struct PixelShaderInput
|
||||
{
|
||||
float4 Position: SV_POSITION;
|
||||
float2 UV: TEXCOORD;
|
||||
float4 Color: COLOR;
|
||||
};
|
||||
|
||||
Texture2D Texture : register(t0);
|
||||
SamplerState Sampler : register(s0);
|
||||
|
||||
PixelShaderInput VS(VertexShaderInput input)
|
||||
{
|
||||
PixelShaderInput output;
|
||||
|
||||
output.Position = float4(input.Position, 1.0f);
|
||||
output.Color = input.Color;
|
||||
output.UV = input.UV;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
float4 PS(PixelShaderInput input) : SV_TARGET
|
||||
{
|
||||
float4 output = Texture.Sample(Sampler, input.UV);
|
||||
float4 colorMul = min(input.Color, 1.0f);
|
||||
output = output * colorMul;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
|
|
@ -230,6 +230,7 @@ bool SaveConfiguration()
|
|||
// Set Gameplay keys.
|
||||
if (SetBoolRegKey(gameplayKey, REGKEY_ENABLE_SUBTITLES, g_Configuration.EnableSubtitles) != ERROR_SUCCESS ||
|
||||
SetBoolRegKey(gameplayKey, REGKEY_ENABLE_AUTO_TARGETING, g_Configuration.EnableAutoTargeting) != ERROR_SUCCESS ||
|
||||
SetBoolRegKey(gameplayKey, REGKEY_ENABLE_TARGET_HIGHLIGHTER, g_Configuration.EnableTargetHighlighter) != ERROR_SUCCESS ||
|
||||
SetBoolRegKey(gameplayKey, REGKEY_ENABLE_RUMBLE, g_Configuration.EnableRumble) != ERROR_SUCCESS ||
|
||||
SetBoolRegKey(gameplayKey, REGKEY_ENABLE_THUMBSTICK_CAMERA, g_Configuration.EnableThumbstickCamera) != ERROR_SUCCESS)
|
||||
{
|
||||
|
@ -308,6 +309,7 @@ void InitDefaultConfiguration()
|
|||
|
||||
g_Configuration.EnableSubtitles = true;
|
||||
g_Configuration.EnableAutoTargeting = true;
|
||||
g_Configuration.EnableTargetHighlighter = false;
|
||||
g_Configuration.EnableRumble = true;
|
||||
g_Configuration.EnableThumbstickCamera = false;
|
||||
|
||||
|
@ -400,12 +402,14 @@ bool LoadConfiguration()
|
|||
|
||||
bool enableSubtitles = true;
|
||||
bool enableAutoTargeting = true;
|
||||
bool enableTargetHighlighter = true;
|
||||
bool enableRumble = true;
|
||||
bool enableThumbstickCamera = true;
|
||||
|
||||
// Load Gameplay keys.
|
||||
if (GetBoolRegKey(gameplayKey, REGKEY_ENABLE_SUBTITLES, &enableSubtitles, true) != ERROR_SUCCESS ||
|
||||
GetBoolRegKey(gameplayKey, REGKEY_ENABLE_AUTO_TARGETING, &enableAutoTargeting, true) != ERROR_SUCCESS ||
|
||||
GetBoolRegKey(gameplayKey, REGKEY_ENABLE_TARGET_HIGHLIGHTER, &enableTargetHighlighter, true) != ERROR_SUCCESS ||
|
||||
GetBoolRegKey(gameplayKey, REGKEY_ENABLE_RUMBLE, &enableRumble, true) != ERROR_SUCCESS ||
|
||||
GetBoolRegKey(gameplayKey, REGKEY_ENABLE_THUMBSTICK_CAMERA, &enableThumbstickCamera, true) != ERROR_SUCCESS)
|
||||
{
|
||||
|
@ -470,6 +474,7 @@ bool LoadConfiguration()
|
|||
g_Configuration.SoundDevice = soundDevice;
|
||||
|
||||
g_Configuration.EnableAutoTargeting = enableAutoTargeting;
|
||||
g_Configuration.EnableTargetHighlighter = enableTargetHighlighter;
|
||||
g_Configuration.EnableRumble = enableRumble;
|
||||
g_Configuration.EnableThumbstickCamera = enableThumbstickCamera;
|
||||
g_Configuration.EnableSubtitles = enableSubtitles;
|
||||
|
|
|
@ -31,10 +31,11 @@ constexpr auto REGKEY_MUSIC_VOLUME = "MusicVolume";
|
|||
constexpr auto REGKEY_SFX_VOLUME = "SfxVolume";
|
||||
|
||||
// Gameplay keys
|
||||
constexpr auto REGKEY_ENABLE_SUBTITLES = "EnableSubtitles";
|
||||
constexpr auto REGKEY_ENABLE_AUTO_TARGETING = "EnableAutoTargeting";
|
||||
constexpr auto REGKEY_ENABLE_RUMBLE = "EnableRumble";
|
||||
constexpr auto REGKEY_ENABLE_THUMBSTICK_CAMERA = "EnableThumbstickCamera";
|
||||
constexpr auto REGKEY_ENABLE_SUBTITLES = "EnableSubtitles";
|
||||
constexpr auto REGKEY_ENABLE_AUTO_TARGETING = "EnableAutoTargeting";
|
||||
constexpr auto REGKEY_ENABLE_TARGET_HIGHLIGHTER = "EnableTargetHighlighter";
|
||||
constexpr auto REGKEY_ENABLE_RUMBLE = "EnableRumble";
|
||||
constexpr auto REGKEY_ENABLE_THUMBSTICK_CAMERA = "EnableThumbstickCamera";
|
||||
|
||||
struct GameConfiguration
|
||||
{
|
||||
|
@ -56,10 +57,11 @@ struct GameConfiguration
|
|||
int SfxVolume = 0;
|
||||
|
||||
// Gameplay
|
||||
bool EnableSubtitles = false;
|
||||
bool EnableAutoTargeting = false;
|
||||
bool EnableRumble = false;
|
||||
bool EnableThumbstickCamera = false;
|
||||
bool EnableSubtitles = false;
|
||||
bool EnableAutoTargeting = false;
|
||||
bool EnableTargetHighlighter = false;
|
||||
bool EnableRumble = false;
|
||||
bool EnableThumbstickCamera = false;
|
||||
|
||||
// Input
|
||||
std::vector<int> Bindings = {};
|
||||
|
|
|
@ -155,31 +155,32 @@ namespace TEN::Utils
|
|||
return strings;
|
||||
}
|
||||
|
||||
Vector2 GetAspectCorrect2DPosition(Vector2 pos2D)
|
||||
Vector2 GetAspectCorrect2DPosition(const Vector2& pos)
|
||||
{
|
||||
constexpr auto SCREEN_SPACE_ASPECT_RATIO = SCREEN_SPACE_RES.x / SCREEN_SPACE_RES.y;
|
||||
constexpr auto DISPLAY_SPACE_ASPECT = SCREEN_SPACE_RES.x / SCREEN_SPACE_RES.y;
|
||||
|
||||
auto screenRes = g_Renderer.GetScreenResolution().ToVector2();
|
||||
float screenResAspectRatio = screenRes.x / screenRes.y;
|
||||
float aspectRatioDelta = screenResAspectRatio - SCREEN_SPACE_ASPECT_RATIO;
|
||||
float screenResAspect = screenRes.x / screenRes.y;
|
||||
float aspectDelta = screenResAspect - DISPLAY_SPACE_ASPECT;
|
||||
|
||||
if (aspectRatioDelta > EPSILON)
|
||||
auto correctedPos = pos;
|
||||
if (aspectDelta > EPSILON)
|
||||
{
|
||||
pos2D.x *= 1.0f - (aspectRatioDelta / 2);
|
||||
correctedPos.x *= 1.0f - (aspectDelta / 2);
|
||||
}
|
||||
else if (aspectRatioDelta < -EPSILON)
|
||||
else if (aspectDelta < -EPSILON)
|
||||
{
|
||||
pos2D.y *= 1.0f - (aspectRatioDelta / 2);
|
||||
correctedPos.y *= 1.0f - (aspectDelta / 2);
|
||||
}
|
||||
|
||||
return pos2D;
|
||||
return correctedPos;
|
||||
}
|
||||
|
||||
Vector2 Convert2DPositionToNDC(const Vector2& pos2D)
|
||||
Vector2 Convert2DPositionToNDC(const Vector2& pos)
|
||||
{
|
||||
return Vector2(
|
||||
((pos2D.x * 2) / SCREEN_SPACE_RES.x) - 1.0f,
|
||||
1.0f - ((pos2D.y * 2) / SCREEN_SPACE_RES.y));
|
||||
((pos.x * 2) / SCREEN_SPACE_RES.x) - 1.0f,
|
||||
1.0f - ((pos.y * 2) / SCREEN_SPACE_RES.y));
|
||||
}
|
||||
|
||||
Vector2 ConvertNDCTo2DPosition(const Vector2& ndc)
|
||||
|
|
|
@ -14,8 +14,8 @@ namespace TEN::Utils
|
|||
std::vector<std::string> SplitString(const std::string& string);
|
||||
|
||||
// 2D space utilities
|
||||
Vector2 GetAspectCorrect2DPosition(Vector2 pos2D);
|
||||
Vector2 Convert2DPositionToNDC(const Vector2& pos2D);
|
||||
Vector2 GetAspectCorrect2DPosition(const Vector2& pos);
|
||||
Vector2 Convert2DPositionToNDC(const Vector2& pos);
|
||||
Vector2 ConvertNDCTo2DPosition(const Vector2& ndc);
|
||||
|
||||
std::vector<unsigned short> GetProductOrFileVersion(bool productVersion);
|
||||
|
|
|
@ -62,14 +62,14 @@ Vector2i GetScreenResolution()
|
|||
|
||||
std::vector<Vector2i> GetAllSupportedScreenResolutions()
|
||||
{
|
||||
std::vector<Vector2i> result;
|
||||
auto resList = std::vector<Vector2i>{};
|
||||
|
||||
DEVMODE dm = { 0 };
|
||||
dm.dmSize = sizeof(dm);
|
||||
for (int iModeNum = 0; EnumDisplaySettings(NULL, iModeNum, &dm) != 0; iModeNum++)
|
||||
{
|
||||
bool add = true;
|
||||
for (auto m : result)
|
||||
for (auto m : resList)
|
||||
{
|
||||
if (m.x == dm.dmPelsWidth && m.y == dm.dmPelsHeight)
|
||||
{
|
||||
|
@ -79,30 +79,19 @@ std::vector<Vector2i> GetAllSupportedScreenResolutions()
|
|||
}
|
||||
if (add)
|
||||
{
|
||||
Vector2i resolution;
|
||||
resolution.x = dm.dmPelsWidth;
|
||||
resolution.y = dm.dmPelsHeight;
|
||||
result.push_back(resolution);
|
||||
auto res = Vector2i(dm.dmPelsWidth, dm.dmPelsHeight);
|
||||
resList.push_back(res);
|
||||
}
|
||||
}
|
||||
|
||||
std::sort(
|
||||
result.begin(),
|
||||
result.end(),
|
||||
resList.begin(), resList.end(),
|
||||
[](Vector2i& a, Vector2i& b)
|
||||
{
|
||||
if (a.x == b.x)
|
||||
{
|
||||
return (a.y < b.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (a.x < b.x);
|
||||
}
|
||||
}
|
||||
);
|
||||
return ((a.x == b.x) ? (a.y < b.y) : (a.x < b.x));
|
||||
});
|
||||
|
||||
return result;
|
||||
return resList;
|
||||
}
|
||||
|
||||
void DisableDpiAwareness()
|
||||
|
|
|
@ -324,10 +324,12 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)"</Command>
|
|||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Game\effects\Bubble.h" />
|
||||
<ClInclude Include="Game\effects\DisplaySprite.h" />
|
||||
<ClInclude Include="Game\GuiObjects.h" />
|
||||
<ClInclude Include="Game\Hud\Hud.h" />
|
||||
<ClInclude Include="Game\Hud\PickupSummary.h" />
|
||||
<ClInclude Include="Game\Hud\StatusBars.h" />
|
||||
<ClInclude Include="Game\Hud\TargetHighlighter.h" />
|
||||
<ClInclude Include="Game\Lara\lara.h" />
|
||||
<ClInclude Include="Game\Lara\lara_basic.h" />
|
||||
<ClInclude Include="Game\Lara\lara_cheat.h" />
|
||||
|
@ -671,6 +673,7 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)"</Command>
|
|||
<ClInclude Include="Renderer\Frustum.h" />
|
||||
<ClInclude Include="Renderer\IndexBuffer\IndexBuffer.h" />
|
||||
<ClInclude Include="Renderer\Quad\RenderQuad.h" />
|
||||
<ClInclude Include="Renderer\RendererSprite2D.h" />
|
||||
<ClInclude Include="Renderer\RenderTarget2D\RenderTarget2D.h" />
|
||||
<ClInclude Include="Renderer\RenderTargetCubeArray\RenderTargetCubeArray.h" />
|
||||
<ClInclude Include="Renderer\RenderTargetCube\RenderTargetCube.h" />
|
||||
|
@ -711,6 +714,9 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)"</Command>
|
|||
<ClInclude Include="Scripting\Internal\ScriptAssert.h" />
|
||||
<ClInclude Include="Scripting\Internal\ScriptUtil.h" />
|
||||
<ClInclude Include="Scripting\Internal\TEN\Color\Color.h" />
|
||||
<ClInclude Include="Scripting\Internal\TEN\DisplaySprite\AlignModes.h" />
|
||||
<ClInclude Include="Scripting\Internal\TEN\DisplaySprite\ScaleModes.h" />
|
||||
<ClInclude Include="Scripting\Internal\TEN\DisplaySprite\ScriptDisplaySprite.h" />
|
||||
<ClInclude Include="Scripting\Internal\TEN\Effects\BlendIDs.h" />
|
||||
<ClInclude Include="Scripting\Internal\TEN\Effects\EffectIDs.h" />
|
||||
<ClInclude Include="Scripting\Internal\TEN\Effects\EffectsFunctions.h" />
|
||||
|
@ -802,6 +808,7 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)"</Command>
|
|||
<ClCompile Include="Game\effects\Bubble.cpp" />
|
||||
<ClCompile Include="Game\effects\chaffFX.cpp" />
|
||||
<ClCompile Include="Game\effects\debris.cpp" />
|
||||
<ClCompile Include="Game\effects\DisplaySprite.cpp" />
|
||||
<ClCompile Include="Game\effects\Drip.cpp" />
|
||||
<ClCompile Include="Game\effects\effects.cpp" />
|
||||
<ClCompile Include="Game\effects\Electricity.cpp" />
|
||||
|
@ -821,6 +828,7 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)"</Command>
|
|||
<ClCompile Include="Game\Hud\Hud.cpp" />
|
||||
<ClCompile Include="Game\Hud\PickupSummary.cpp" />
|
||||
<ClCompile Include="Game\Hud\StatusBars.cpp" />
|
||||
<ClCompile Include="Game\Hud\TargetHighlighter.cpp" />
|
||||
<ClCompile Include="Game\itemdata\creature_info.cpp" />
|
||||
<ClCompile Include="Game\itemdata\itemdata.cpp" />
|
||||
<ClCompile Include="Game\items.cpp" />
|
||||
|
@ -1128,6 +1136,7 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)"</Command>
|
|||
<ClCompile Include="Scripting\Internal\ScriptInterfaceState.cpp" />
|
||||
<ClCompile Include="Scripting\Internal\ScriptUtil.cpp" />
|
||||
<ClCompile Include="Scripting\Internal\TEN\Color\Color.cpp" />
|
||||
<ClCompile Include="Scripting\Internal\TEN\DisplaySprite\ScriptDisplaySprite.cpp" />
|
||||
<ClCompile Include="Scripting\Internal\TEN\Effects\EffectsFunctions.cpp" />
|
||||
<ClCompile Include="Scripting\Internal\TEN\Flow\Animations\Animations.cpp" />
|
||||
<ClCompile Include="Scripting\Internal\TEN\Flow\FlowHandler.cpp" />
|
||||
|
|
|
@ -6,8 +6,7 @@
|
|||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LocalDebuggerWorkingDirectory>$(SolutionDir)Build\$(Configuration)\</LocalDebuggerWorkingDirectory>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
<LocalDebuggerCommandArguments>-gameDir "P:\Projects\TombEngineAssets" -debug</LocalDebuggerCommandArguments>
|
||||
<RemoteDebuggerCommandArguments>-gameDir "P:\Projects\TombEngineAssets" -debug</RemoteDebuggerCommandArguments>
|
||||
<LocalDebuggerCommandArguments>/debug</LocalDebuggerCommandArguments>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LocalDebuggerWorkingDirectory>$(SolutionDir)Build\$(Configuration)\</LocalDebuggerWorkingDirectory>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue