Squashed commit of the following:

Partially move inventory control from renderer
    Exit statistics with accept key as well
    Fix blinking
    Fix various remaining problems
    Add missing string
    Fix some menus
    Finalizing GUI rewrite
    Work
This commit is contained in:
Lwmte 2022-06-07 03:59:02 +03:00
parent c387b7f3a4
commit e127534165
14 changed files with 1196 additions and 1409 deletions

View file

@ -780,7 +780,7 @@ local strings = {
""
},
savegame_timestamp = {
"%d Days %d:%d:%d",
"%02d Days %02d:%02d:%02d",
"",
"",
"",
@ -889,6 +889,16 @@ local strings = {
"",
""
},
options = {
"Options",
"",
"",
"",
"",
"",
"",
""
},
sound = {
"Sound settings",
"",

View file

@ -490,7 +490,7 @@ GameStatus DoTitle(int index, std::string const& ambient)
g_GameScript->InitCallbacks();
g_GameStringsHandler->SetCallbackDrawString([](std::string const key, D3DCOLOR col, int x, int y, int flags)
{
g_Renderer.DrawString(float(x)/float(g_Configuration.Width) * ASSUMED_WIDTH_FOR_TEXT_DRAWING, float(y)/float(g_Configuration.Height) * ASSUMED_HEIGHT_FOR_TEXT_DRAWING, key.c_str(), col, flags);
g_Renderer.DrawString(float(x)/float(g_Configuration.Width) * REFERENCE_RES_WIDTH, float(y)/float(g_Configuration.Height) * REFERENCE_RES_HEIGHT, key.c_str(), col, flags);
});
}
@ -609,7 +609,7 @@ GameStatus DoLevel(int index, std::string const& ambient, bool loadFromSavegame)
g_GameScript->InitCallbacks();
g_GameStringsHandler->SetCallbackDrawString([](std::string const key, D3DCOLOR col, int x, int y, int flags)
{
g_Renderer.DrawString(float(x)/float(g_Configuration.Width) * ASSUMED_WIDTH_FOR_TEXT_DRAWING, float(y)/float(g_Configuration.Height) * ASSUMED_HEIGHT_FOR_TEXT_DRAWING, key.c_str(), col, flags);
g_Renderer.DrawString(float(x)/float(g_Configuration.Width) * REFERENCE_RES_WIDTH, float(y)/float(g_Configuration.Height) * REFERENCE_RES_HEIGHT, key.c_str(), col, flags);
});
}

View file

@ -626,15 +626,27 @@ InventoryResult GuiController::TitleOptions()
DoDebouncedInput();
if (menu_to_display == Menu::Title || menu_to_display == Menu::SelectLevel ||
menu_to_display == Menu::LoadGame || menu_to_display == Menu::Options)
if (menu_to_display == Menu::LoadGame)
{
DoLoad();
if (invMode == InventoryMode::InGame)
{
menu_to_display = Menu::Title;
selected_option = selected_option_bak;
}
}
else if (menu_to_display == Menu::Title ||
menu_to_display == Menu::SelectLevel ||
menu_to_display == Menu::Options)
{
if (goUp)
{
if (selected_option <= 0)
selected_option += option_count;
if (menu_to_display == Menu::LoadGame)
selected_save_slot = (selected_save_slot <= 0) ? option_count : selected_option - 1;
else
selected_option--;
selected_option = (selected_option <= 0) ? option_count : selected_option - 1;
SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always);
}
@ -705,13 +717,12 @@ InventoryResult GuiController::TitleOptions()
}
else if (menu_to_display == Menu::LoadGame)
{
if (!SavegameInfos[selected_option].Present)
if (!SavegameInfos[selected_save_slot].Present)
SayNo();
else
{
SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always);
g_GameFlow->SelectedSaveGame = selected_option;
selected_option = 0;
g_GameFlow->SelectedSaveGame = selected_save_slot;
ret = InventoryResult::LoadGame;
}
}
@ -1250,8 +1261,10 @@ InventoryResult GuiController::DoPauseMenu()
if (goSelect)
{
if (menu_to_display == Menu::Pause)
switch (menu_to_display)
{
case Menu::Pause:
switch (selected_option)
{
case 0:
@ -1268,9 +1281,10 @@ InventoryResult GuiController::DoPauseMenu()
invMode = InventoryMode::None;
return InventoryResult::ExitToTitle;
}
}
else if (menu_to_display == Menu::Options)
{
break;
case Menu::Options:
switch (selected_option)
{
case 0:
@ -1289,6 +1303,12 @@ InventoryResult GuiController::DoPauseMenu()
menu_to_display = Menu::Sound;
break;
}
break;
case Menu::Statistics:
menu_to_display = Menu::Pause;
SoundEffect(SFX_TR4_MENU_SELECT, nullptr, SoundEnvironment::Always);
break;
}
}
@ -2250,7 +2270,7 @@ void GuiController::UseCurrentItem()
}
}
void GuiController::HandleInventoryMenu()
void GuiController::DoInventory()
{
int n;
unsigned __int64 opts;
@ -2260,7 +2280,7 @@ void GuiController::HandleInventoryMenu()
if (rings[(int)RingTypes::Ammo]->ringactive)
{
g_Renderer.DrawString(phd_centerx, phd_centery, g_GameFlow->GetString(optmessages[5]), PRINTSTRING_COLOR_WHITE, PRINTSTRING_BLINK | PRINTSTRING_CENTER);
g_Renderer.DrawString(phd_centerx, phd_centery, g_GameFlow->GetString(optmessages[5]), PRINTSTRING_COLOR_WHITE, PRINTSTRING_BLINK | PRINTSTRING_CENTER | PRINTSTRING_OUTLINE);
if (rings[(int)RingTypes::Inventory]->objlistmovement)
return;
@ -2452,12 +2472,12 @@ void GuiController::HandleInventoryMenu()
{
if (i == current_selected_option)
{
g_Renderer.DrawString(phd_centerx, ypos, current_options[i].text, PRINTSTRING_COLOR_WHITE, PRINTSTRING_BLINK | PRINTSTRING_CENTER);
g_Renderer.DrawString(phd_centerx, ypos, current_options[i].text, PRINTSTRING_COLOR_WHITE, PRINTSTRING_BLINK | PRINTSTRING_CENTER | PRINTSTRING_OUTLINE);
ypos += font_height;
}
else
{
g_Renderer.DrawString(phd_centerx, ypos, current_options[i].text, PRINTSTRING_COLOR_WHITE, PRINTSTRING_CENTER);
g_Renderer.DrawString(phd_centerx, ypos, current_options[i].text, PRINTSTRING_COLOR_WHITE, PRINTSTRING_CENTER | PRINTSTRING_OUTLINE);
ypos += font_height;
}
}
@ -2722,7 +2742,7 @@ void GuiController::DrawAmmoSelector()
sprintf(&invTextBuffer[0], "%d x %s", ammo_object_list[n].amount, g_GameFlow->GetString(inventry_objects_list[ammo_object_list[n].invitem].objname));
if (ammo_selector_fade_val)
g_Renderer.DrawString(phd_centerx, 380, &invTextBuffer[0], PRINTSTRING_COLOR_YELLOW, PRINTSTRING_CENTER);
g_Renderer.DrawString(phd_centerx, 380, &invTextBuffer[0], PRINTSTRING_COLOR_YELLOW, PRINTSTRING_CENTER | PRINTSTRING_OUTLINE);
if (n == *current_ammo_type)
@ -3028,7 +3048,7 @@ void GuiController::DrawCurrentObjectList(int ringnum)
else
objmeup = (int)((phd_winymax + 1) * 0.0625 * 3.0 + phd_centery);
g_Renderer.DrawString(phd_centerx, ringnum == (int)RingTypes::Inventory ? 230 : 300, textbufme, PRINTSTRING_COLOR_YELLOW, PRINTSTRING_CENTER);
g_Renderer.DrawString(phd_centerx, ringnum == (int)RingTypes::Inventory ? 230 : 300, textbufme, PRINTSTRING_COLOR_YELLOW, PRINTSTRING_CENTER | PRINTSTRING_OUTLINE);
}
if (!i && !rings[ringnum]->objlistmovement)
@ -3204,25 +3224,36 @@ int GuiController::CallInventory(bool reset_mode)
return return_value;
DoDebouncedInput();
if (invMode == InventoryMode::Statistics)
DoStatisticsMode();
if (invMode == InventoryMode::Examine)
DoExamineMode();
if (invMode == InventoryMode::Diary)
DoDiary();
if (invMode == InventoryMode::Load)
return_value = DoLoad();
if (invMode == InventoryMode::Save)
DoSave();
DrawInventory();
DrawCompass();
switch (invMode)
{
case InventoryMode::InGame:
DoInventory();
break;
case InventoryMode::Statistics:
DoStatisticsMode();
break;
case InventoryMode::Examine:
DoExamineMode();
break;
case InventoryMode::Diary:
DoDiary();
break;
case InventoryMode::Load:
return_value = DoLoad();
break;
case InventoryMode::Save:
DoSave();
break;
}
if (useItem && !TrInput)
val = 1;
@ -3310,7 +3341,7 @@ void GuiController::DoDiary()
short GuiController::GetLoadSaveSelection()
{
return selected_slot;
return selected_save_slot;
}
int GuiController::DoLoad()
@ -3321,30 +3352,30 @@ int GuiController::DoLoad()
{
SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always);
if (selected_slot == SAVEGAME_MAX - 1)
selected_slot -= SAVEGAME_MAX - 1; //go back up
if (selected_save_slot == SAVEGAME_MAX - 1)
selected_save_slot -= SAVEGAME_MAX - 1; //go back up
else
selected_slot++;
selected_save_slot++;
}
if (goUp)
{
SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always);
if (selected_slot== 0)
selected_slot += SAVEGAME_MAX - 1; //go back down
if (selected_save_slot== 0)
selected_save_slot += SAVEGAME_MAX - 1; //go back down
else
selected_slot--;
selected_save_slot--;
}
if (goSelect)
{
if (!SavegameInfos[selected_slot].Present)
if (!SavegameInfos[selected_save_slot].Present)
SayNo();
else
{
SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always);
g_GameFlow->SelectedSaveGame = selected_slot;
g_GameFlow->SelectedSaveGame = selected_save_slot;
ExitInvLoop = 1;
return 1;
}
@ -3368,26 +3399,26 @@ void GuiController::DoSave()
{
SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always);
if (selected_slot == SAVEGAME_MAX - 1)
selected_slot -= SAVEGAME_MAX - 1; //go back up
if (selected_save_slot == SAVEGAME_MAX - 1)
selected_save_slot -= SAVEGAME_MAX - 1; //go back up
else
selected_slot++;
selected_save_slot++;
}
if (goUp)
{
SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always);
if (selected_slot == 0)
selected_slot += SAVEGAME_MAX - 1; //go back down
if (selected_save_slot == 0)
selected_save_slot += SAVEGAME_MAX - 1; //go back down
else
selected_slot--;
selected_save_slot--;
}
if (goSelect)
{
SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always);
SaveGame::Save(selected_slot);
SaveGame::Save(selected_save_slot);
ExitInvLoop = 1; //exit inv if the user has saved
}

View file

@ -402,7 +402,6 @@ public:
int CallInventory(bool reset_mode);
InventoryResult TitleOptions();
InventoryResult DoPauseMenu();
void HandleInventoryMenu();
void DrawInventory();
void DrawCurrentObjectList(int ringnum);
int IsObjectInInventory(short object_number);
@ -460,9 +459,11 @@ private:
void DoDiary();
int DoLoad();
void DoSave();
void DoInventory();
void ConstructCombineObjectList();
/*vars*/
// Input
bool goUp, goDown, goRight, goLeft, goSelect, goDeselect;
bool dbUp, dbDown, dbRight, dbLeft, dbSelect, dbDeselect;
@ -536,14 +537,13 @@ private:
char StashedCurrentHarpoonAmmoType;
char StashedCurrentRocketAmmoType;
// GUI vars
Menu menu_to_display = Menu::Title;
short selected_option;
int selected_option;
int option_count;
int selected_save_slot;
SettingsData CurrentSettings;
// Load / save
short selected_slot;
};
/*inventory*/

View file

@ -13,6 +13,7 @@
#include "Specific/level.h"
using namespace TEN::Renderer;
short PickupX;
short PickupY;
short CurrentPickup;
@ -43,7 +44,7 @@ void DrawHealthBarOverlay(ItemInfo* item, int value)
else
color2 = 0xA00000;
g_Renderer.DrawBar(value, ::g_HealthBar, ID_HEALTH_BAR_TEXTURE, GlobalCounter, Lara.PoisonPotency);
g_Renderer.DrawBar(value, g_HealthBar, ID_HEALTH_BAR_TEXTURE, GlobalCounter, Lara.PoisonPotency);
}
}
@ -52,7 +53,7 @@ void DrawHealthBar(ItemInfo* item, float value)
auto* lara = GetLaraInfo(item);
if (CurrentLevel)
g_Renderer.DrawBar(value, ::g_HealthBar, ID_HEALTH_BAR_TEXTURE, GlobalCounter, Lara.PoisonPotency);
g_Renderer.DrawBar(value, g_HealthBar, ID_HEALTH_BAR_TEXTURE, GlobalCounter, Lara.PoisonPotency);
}
void UpdateHealthBar(ItemInfo* item, int flash)
@ -141,7 +142,7 @@ void UpdateHealthBar(ItemInfo* item, int flash)
void DrawAirBar(float value)
{
if (CurrentLevel)
g_Renderer.DrawBar(value, ::g_AirBar,ID_AIR_BAR_TEXTURE,0,0);
g_Renderer.DrawBar(value, g_AirBar,ID_AIR_BAR_TEXTURE,0,0);
}
void UpdateAirBar(ItemInfo* item, int flash)
@ -180,7 +181,7 @@ void UpdateAirBar(ItemInfo* item, int flash)
void DrawSprintBar(float value)
{
if (CurrentLevel)
g_Renderer.DrawBar(value, ::g_DashBar, ID_DASH_BAR_TEXTURE, 0, 0);
g_Renderer.DrawBar(value, g_DashBar, ID_DASH_BAR_TEXTURE, 0, 0);
}
void UpdateSprintBar(ItemInfo* item)
@ -236,7 +237,7 @@ void DrawAllPickups()
}
}
g_Renderer.drawPickup(Pickups[CurrentPickup].ObjectNumber);
g_Renderer.DrawPickup(Pickups[CurrentPickup].ObjectNumber);
}

View file

@ -19,6 +19,7 @@
#include "RendererBucket.h"
#include "Game/items.h"
#include "Game/animation.h"
#include "Game/gui.h"
#include "Game/effects/effects.h"
#include "IndexBuffer/IndexBuffer.h"
#include "VertexBuffer/VertexBuffer.h"
@ -322,13 +323,16 @@ namespace TEN::Renderer
CAlphaTestBuffer m_stAlphaTest;
ConstantBuffer<CAlphaTestBuffer> m_cbAlphaTest;
// Text and sprites
std::unique_ptr<SpriteFont> m_gameFont;
// Sprites
std::unique_ptr<SpriteBatch> m_spriteBatch;
std::unique_ptr<PrimitiveBatch<RendererVertex>> m_primitiveBatch;
// Text
std::unique_ptr<SpriteFont> m_gameFont;
std::vector<RendererStringToDraw> m_strings;
int m_blinkColorValue;
int m_blinkColorDirection;
std::unique_ptr<PrimitiveBatch<RendererVertex>> m_primitiveBatch;
bool m_blinkUpdated = false;
int m_currentY;
// System resources
@ -531,9 +535,10 @@ namespace TEN::Renderer
void DrawLocusts(RenderView& view);
void RenderInventoryScene(ID3D11RenderTargetView* target, ID3D11DepthStencilView* depthTarget,
ID3D11ShaderResourceView* background);
void RenderTitleMenu();
void RenderPauseMenu();
void RenderTitleMenu(Menu menu);
void RenderPauseMenu(Menu menu);
void RenderLoadSaveMenu();
void RenderOptionsMenu(Menu menu, int initialY);
void RenderNewInventory();
void DrawStatistics();
void DrawExamines();
@ -548,7 +553,8 @@ namespace TEN::Renderer
bool IsRoomUnderwater(short roomNumber);
bool IsInRoom(int x, int y, int z, short roomNumber);
void InitialiseScreen(int w, int h, bool windowed, HWND handle, bool reset);
void InitialiseBars();
void InitialiseGameBars();
void InitialiseMenuBars(int y);
void DrawSmokeParticles(RenderView& view);
void DrawSparkParticles(RenderView& view);
void DrawDripParticles(RenderView& view);
@ -581,7 +587,6 @@ namespace TEN::Renderer
Texture2D CreateDefaultNormalTexture();
void DrawFootprints(RenderView& view);
void DrawLoadingBar(float percent);
Vector2 GetScreenResolution();
inline void DrawIndexedTriangles(int count, int baseIndex, int baseVertex)
{
@ -642,8 +647,8 @@ namespace TEN::Renderer
void PrintDebugMessage(LPCSTR message, ...);
void DrawDebugInfo(RenderView& view);
void SwitchDebugPage(bool back);
void drawPickup(short objectNum);
int SyncRenderer();
void DrawPickup(short objectNum);
int SyncRenderer();
void DrawString(int x, int y, const char* string, D3DCOLOR color, int flags);
void ClearDynamicLights();
void AddDynamicLight(int x, int y, int z, short falloff, byte r, byte g, byte b);

File diff suppressed because it is too large Load diff

View file

@ -11,13 +11,11 @@ using namespace TEN::Effects::Environment;
TEN::Renderer::RendererHUDBar* g_HealthBar;
TEN::Renderer::RendererHUDBar* g_AirBar;
TEN::Renderer::RendererHUDBar* g_DashBar;
TEN::Renderer::RendererHUDBar* g_MusicVolumeBar;
TEN::Renderer::RendererHUDBar* g_SFXVolumeBar;
TEN::Renderer::RendererHUDBar* g_LoadingBar;
namespace TEN::Renderer
{
void Renderer11::InitialiseBars()
void Renderer11::InitialiseGameBars()
{
std::array<Vector4, 5> healthColors =
{
@ -66,24 +64,11 @@ namespace TEN::Renderer
Vector4(78 / 255.0f,4 / 255.0f,0,1),
Vector4(136 / 255.0f,117 / 255.0f,5 / 255.0f,1),
};
std::array<Vector4, 5> soundSettingColors =
{
//top
Vector4(0.18f,0.3f,0.72f,1),
Vector4(0.18f,0.3f,0.72f,1),
//center
Vector4(0.18f,0.3f,0.72f,1),
//bottom
Vector4(0.18f,0.3f,0.72f,1),
Vector4(0.18f,0.3f,0.72f,1),
};
g_HealthBar = new RendererHUDBar(m_device.Get(), 20, 32, 150, 8, 1, healthColors);
g_AirBar = new RendererHUDBar(m_device.Get(), 630, 32, 150, 8, 1, airColors);
g_DashBar = new RendererHUDBar(m_device.Get(), 630, 32 + 8 + 4, 150, 8, 1, dashColors);
g_MusicVolumeBar = new RendererHUDBar(m_device.Get(), 400, 194, 150, 8, 1, soundSettingColors);
g_SFXVolumeBar = new RendererHUDBar(m_device.Get(), 400, 212, 150, 8, 1, soundSettingColors);
g_LoadingBar = new RendererHUDBar(m_device.Get(), 325, 400, 150, 8, 1, airColors);
g_LoadingBar = new RendererHUDBar(m_device.Get(), 325, 550, 150, 8, 1, airColors);
}
void Renderer11::DrawBar(float percent, const RendererHUDBar* const bar, GAME_OBJECT_ID textureSlot, int frame, bool poison)
@ -265,4 +250,127 @@ namespace TEN::Renderer
// TODO: Vignette goes here! -- Lwmte, 21.08.21
}
}
void Renderer11::DoFadingAndCinematicBars(ID3D11RenderTargetView* target, ID3D11DepthStencilView* depthTarget,
RenderView& view)
{
SetBlendMode(BLENDMODE_OPAQUE);
SetCullMode(CULL_MODE_CCW);
m_context->ClearRenderTargetView(target, Colors::Black);
m_context->ClearDepthStencilView(depthTarget, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
m_context->OMSetRenderTargets(1, &target, depthTarget);
m_context->RSSetViewports(1, &view.viewport);
ResetScissor();
RendererVertex vertices[4];
vertices[0].Position.x = -1.0f;
vertices[0].Position.y = 1.0f;
vertices[0].Position.z = 0.0f;
vertices[0].UV.x = 0.0f;
vertices[0].UV.y = 0.0f;
vertices[0].Color = Vector4::One;
vertices[1].Position.x = 1.0f;
vertices[1].Position.y = 1.0f;
vertices[1].Position.z = 0.0f;
vertices[1].UV.x = 1.0f;
vertices[1].UV.y = 0.0f;
vertices[1].Color = Vector4::One;
vertices[2].Position.x = 1.0f;
vertices[2].Position.y = -1.0f;
vertices[2].Position.z = 0.0f;
vertices[2].UV.x = 1.0f;
vertices[2].UV.y = 1.0f;
vertices[2].Color = Vector4::One;
vertices[3].Position.x = -1.0f;
vertices[3].Position.y = -1.0f;
vertices[3].Position.z = 0.0f;
vertices[3].UV.x = 0.0f;
vertices[3].UV.y = 1.0f;
vertices[3].Color = Vector4::One;
m_context->VSSetShader(m_vsFinalPass.Get(), nullptr, 0);
m_context->PSSetShader(m_psFinalPass.Get(), nullptr, 0);
m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
m_context->IASetInputLayout(m_inputLayout.Get());
m_stPostProcessBuffer.ViewportWidth = ScreenWidth;
m_stPostProcessBuffer.ViewportHeight = ScreenHeight;
m_stPostProcessBuffer.ScreenFadeFactor = ScreenFadeCurrent;
m_stPostProcessBuffer.CinematicBarsHeight = CinematicBarsHeight;
m_cbPostProcessBuffer.updateData(m_stPostProcessBuffer, m_context.Get());
m_context->PSSetConstantBuffers(7, 1, m_cbPostProcessBuffer.get());
BindTexture(TEXTURE_COLOR_MAP, &m_renderTarget, SAMPLER_ANISOTROPIC_CLAMP);
m_primitiveBatch->Begin();
m_primitiveBatch->DrawQuad(vertices[0], vertices[1], vertices[2], vertices[3]);
m_primitiveBatch->End();
}
void Renderer11::DrawFullScreenImage(ID3D11ShaderResourceView* texture, float fade, ID3D11RenderTargetView* target,
ID3D11DepthStencilView* depthTarget)
{
// Reset GPU state
SetBlendMode(BLENDMODE_OPAQUE);
SetCullMode(CULL_MODE_NONE);
m_context->OMSetRenderTargets(1, &target, depthTarget);
m_context->RSSetViewports(1, &m_viewport);
ResetScissor();
DrawFullScreenQuad(texture, Vector3(fade, fade, fade));
}
void Renderer11::DrawFullScreenQuad(ID3D11ShaderResourceView* texture, DirectX::SimpleMath::Vector3 color)
{
RendererVertex vertices[4];
vertices[0].Position.x = -1.0f;
vertices[0].Position.y = 1.0f;
vertices[0].Position.z = 0.0f;
vertices[0].UV.x = 0.0f;
vertices[0].UV.y = 0.0f;
vertices[0].Color = Vector4(color.x, color.y, color.z, 1.0f);
vertices[1].Position.x = 1.0f;
vertices[1].Position.y = 1.0f;
vertices[1].Position.z = 0.0f;
vertices[1].UV.x = 1.0f;
vertices[1].UV.y = 0.0f;
vertices[1].Color = Vector4(color.x, color.y, color.z, 1.0f);
vertices[2].Position.x = 1.0f;
vertices[2].Position.y = -1.0f;
vertices[2].Position.z = 0.0f;
vertices[2].UV.x = 1.0f;
vertices[2].UV.y = 1.0f;
vertices[2].Color = Vector4(color.x, color.y, color.z, 1.0f);
vertices[3].Position.x = -1.0f;
vertices[3].Position.y = -1.0f;
vertices[3].Position.z = 0.0f;
vertices[3].UV.x = 0.0f;
vertices[3].UV.y = 1.0f;
vertices[3].Color = Vector4(color.x, color.y, color.z, 1.0f);
m_context->VSSetShader(m_vsFullScreenQuad.Get(), nullptr, 0);
m_context->PSSetShader(m_psFullScreenQuad.Get(), nullptr, 0);
m_context->PSSetShaderResources(0, 1, &texture);
ID3D11SamplerState* 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]);
m_primitiveBatch->End();
}
}

View file

@ -0,0 +1,922 @@
#include "framework.h"
#include "Renderer/Renderer11.h"
#include "Specific/configuration.h"
#include "Game/savegame.h"
#include "Game/health.h"
#include "Game/animation.h"
#include "Game/gui.h"
#include "Game/Lara/lara.h"
#include "Specific/level.h"
#include "Specific/setup.h"
#include "Game/control/control.h"
#include "Scripting/Internal/TEN/Flow//Level/FlowLevel.h"
#include "Specific/winmain.h"
#include "Game/control/volume.h"
extern TEN::Renderer::RendererHUDBar* g_SFXVolumeBar;
extern TEN::Renderer::RendererHUDBar* g_MusicVolumeBar;
namespace TEN::Renderer
{
using namespace TEN::Renderer;
// Horizontal alignment constants
constexpr auto MenuLeftSideEntry = 200;
constexpr auto MenuCenterEntry = 400;
constexpr auto MenuRightSideEntry = 500;
constexpr auto MenuLoadNumberLeftSide = 80;
constexpr auto MenuLoadNameLeftSide = 150;
// Vertical spacing templates
constexpr auto MenuVerticalLineSpacing = 30;
constexpr auto MenuVerticalNarrowLineSpacing = 25;
constexpr auto MenuVerticalBlockSpacing = 50;
// Vertical menu positioning templates
constexpr auto MenuVerticalTopCenter = 200;
constexpr auto MenuVerticalBottomCenter = 400;
constexpr auto MenuVerticalStatisticsTitle = 150;
constexpr auto MenuVerticalOptionsTitle = 350;
constexpr auto MenuVerticalOptionsPause = 275;
// Title logo positioning
constexpr auto LogoTop = 50;
constexpr auto LogoWidth = 300;
constexpr auto LogoHeight = 150;
// Used with distance travelled
constexpr auto UnitsToMeters = 419;
// Helper functions to jump caret to new line
inline void GetNextLinePosition(int* value) { *value += MenuVerticalLineSpacing; }
inline void GetNextNarrowLinePosition(int* value) { *value += MenuVerticalNarrowLineSpacing; }
inline void GetNextBlockPosition(int* value) { *value += MenuVerticalBlockSpacing; }
// Helper functions to construct string flags
inline int SF(bool selected = false) { return PRINTSTRING_OUTLINE | (selected ? PRINTSTRING_BLINK : 0); }
inline int SF_Center(bool selected = false) { return PRINTSTRING_OUTLINE | PRINTSTRING_CENTER | (selected ? PRINTSTRING_BLINK : 0); }
inline int SF_Option(bool selected) { return PRINTSTRING_OUTLINE | PRINTSTRING_DONT_UPDATE_BLINK | (selected ? PRINTSTRING_BLINK : 0); }
inline int SF_Value(bool selected) { return PRINTSTRING_OUTLINE | (selected ? PRINTSTRING_BLINK : 0); }
inline int SF_Selector(bool selected, bool active) { return PRINTSTRING_OUTLINE | (active ? 0 : PRINTSTRING_DONT_UPDATE_BLINK) | (selected ? PRINTSTRING_BLINK : 0); }
// Helper functions to get specific generic strings
inline const char* Str_Enabled(bool enabled = false) { return g_GameFlow->GetString(enabled ? STRING_ENABLED : STRING_DISABLED); }
inline const char* Str_LoadSave(bool save = false) { return g_GameFlow->GetString(save ? STRING_SAVE_GAME : STRING_LOAD_GAME); }
// These bars are only used in menus
TEN::Renderer::RendererHUDBar* g_MusicVolumeBar = nullptr;
TEN::Renderer::RendererHUDBar* g_SFXVolumeBar = nullptr;
void Renderer11::InitialiseMenuBars(int y)
{
std::array<Vector4, 5> soundSettingColors =
{
//top
Vector4(0.18f,0.3f,0.72f,1),
Vector4(0.18f,0.3f,0.72f,1),
//center
Vector4(0.18f,0.3f,0.72f,1),
//bottom
Vector4(0.18f,0.3f,0.72f,1),
Vector4(0.18f,0.3f,0.72f,1),
};
int shift = MenuVerticalLineSpacing / 2;
g_MusicVolumeBar = new RendererHUDBar(m_device.Get(), MenuRightSideEntry, y + shift, 150, 8, 1, soundSettingColors);
GetNextLinePosition(&y);
g_SFXVolumeBar = new RendererHUDBar(m_device.Get(), MenuRightSideEntry, y + shift, 150, 8, 1, soundSettingColors);
}
void Renderer11::RenderOptionsMenu(Menu menu, int initialY)
{
int y = 0;
auto title_option = g_Gui.GetSelectedOption();
char stringBuffer[32] = {};
auto screenResolution = g_Configuration.SupportedScreenResolutions[g_Gui.GetCurrentSettings().selectedScreenResolution];
sprintf(stringBuffer, "%d x %d", screenResolution.x, screenResolution.y);
switch (menu)
{
case Menu::Options:
// Setup needed parameters
y = initialY;
// Display
DrawString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_DISPLAY), PRINTSTRING_COLOR_WHITE, SF_Center(title_option == 0));
GetNextLinePosition(&y);
// Controls
DrawString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_CONTROLS), PRINTSTRING_COLOR_WHITE, SF_Center(title_option == 1));
GetNextLinePosition(&y);
// Sound
DrawString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_SOUND), PRINTSTRING_COLOR_WHITE, SF_Center(title_option == 2));
break;
case Menu::Display:
// Setup needed parameters
y = MenuVerticalTopCenter;
// Title
DrawString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_DISPLAY), PRINTSTRING_COLOR_YELLOW, SF_Center());
GetNextBlockPosition(&y);
// Screen resolution
DrawString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_SCREEN_RESOLUTION), PRINTSTRING_COLOR_ORANGE, SF_Option(title_option == 0));
DrawString(MenuRightSideEntry, y, stringBuffer, PRINTSTRING_COLOR_WHITE, SF_Value(title_option == 0));
GetNextLinePosition(&y);
// Windowed mode
DrawString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_WINDOWED), PRINTSTRING_COLOR_ORANGE, SF_Option(title_option == 1));
DrawString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().conf.Windowed), PRINTSTRING_COLOR_WHITE, SF_Value(title_option == 1));
GetNextLinePosition(&y);
// Enable dynamic shadows
DrawString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_SHADOWS), PRINTSTRING_COLOR_ORANGE, SF_Option(title_option == 2));
DrawString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().conf.EnableShadows), PRINTSTRING_COLOR_WHITE, SF_Value(title_option == 2));
GetNextLinePosition(&y);
// Enable caustics
DrawString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_CAUSTICS), PRINTSTRING_COLOR_ORANGE, SF_Option(title_option == 3));
DrawString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().conf.EnableCaustics), PRINTSTRING_COLOR_WHITE, SF_Value(title_option == 3));
GetNextLinePosition(&y);
// Enable volumetric fog
DrawString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_VOLUMETRIC_FOG), PRINTSTRING_COLOR_ORANGE, SF_Option(title_option == 4));
DrawString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().conf.EnableVolumetricFog), PRINTSTRING_COLOR_WHITE, SF_Value(title_option == 4));
GetNextBlockPosition(&y);
// Apply
DrawString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_APPLY), PRINTSTRING_COLOR_ORANGE, SF_Center(title_option == 5));
GetNextLinePosition(&y);
// Cancel
DrawString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_CANCEL), PRINTSTRING_COLOR_ORANGE, SF_Center(title_option == 6));
break;
case Menu::Sound:
// Setup needed parameters
y = MenuVerticalTopCenter;
// Title
DrawString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_SOUND), PRINTSTRING_COLOR_YELLOW, SF_Center());
GetNextBlockPosition(&y);
// Enable sound special effects
DrawString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_SPECIAL_SOUND_FX), PRINTSTRING_COLOR_ORANGE, SF_Option(title_option == 0));
DrawString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().conf.EnableAudioSpecialEffects), PRINTSTRING_COLOR_WHITE, SF_Value(title_option == 0));
GetNextLinePosition(&y);
// Initialize bars, if not yet done. Must be done here because we're calculating Y coord on the fly.
if (g_MusicVolumeBar == nullptr)
InitialiseMenuBars(y);
// Music volume
DrawString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_MUSIC_VOLUME), PRINTSTRING_COLOR_ORANGE, SF_Option(title_option == 1));
DrawBar(g_Gui.GetCurrentSettings().conf.MusicVolume / 100.0f, g_MusicVolumeBar, ID_SFX_BAR_TEXTURE, 0, false);
GetNextLinePosition(&y);
// Sound FX volume
DrawString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_SFX_VOLUME), PRINTSTRING_COLOR_ORANGE, SF_Option(title_option == 2));
DrawBar(g_Gui.GetCurrentSettings().conf.SfxVolume / 100.0f, g_SFXVolumeBar, ID_SFX_BAR_TEXTURE, 0, false);
GetNextBlockPosition(&y);
// Apply
DrawString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_APPLY), PRINTSTRING_COLOR_ORANGE, SF_Center(title_option == 3));
GetNextLinePosition(&y);
// Cancel
DrawString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_CANCEL), PRINTSTRING_COLOR_ORANGE, SF_Center(title_option == 4));
break;
case Menu::Controls:
// Setup needed parameters
y = MenuVerticalLineSpacing;
// Title
DrawString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_CONTROLS), PRINTSTRING_COLOR_YELLOW, SF_Center());
GetNextBlockPosition(&y);
// Control listing
for (int k = 0; k < 16; k++)
{
DrawString(MenuLeftSideEntry, y, g_GameFlow->GetString(controlmsgs[k]), PRINTSTRING_COLOR_WHITE, SF_Option(title_option == k));
if (g_Gui.GetCurrentSettings().waitingForkey && title_option == k)
DrawString(MenuRightSideEntry, y, g_GameFlow->GetString(STRING_WAITING_FOR_KEY), PRINTSTRING_COLOR_YELLOW, SF(true));
else
DrawString(MenuRightSideEntry, y, (char*)g_KeyNames[KeyboardLayout[1][k]], PRINTSTRING_COLOR_ORANGE, SF(false));
if (k < 15)
GetNextNarrowLinePosition(&y);
else
GetNextBlockPosition(&y);
}
// Apply
DrawString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_APPLY), PRINTSTRING_COLOR_ORANGE, SF_Center(title_option == 16));
GetNextLinePosition(&y);
// Cancel
DrawString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_CANCEL), PRINTSTRING_COLOR_ORANGE, SF_Center(title_option == 17));
break;
}
}
void Renderer11::RenderTitleMenu(Menu menu)
{
int y = MenuVerticalBottomCenter;
auto title_option = g_Gui.GetSelectedOption();
// HACK: Check if it works properly -- Lwmte, 07.06.22
if (menu == Menu::LoadGame && !g_GameFlow->EnableLoadSave)
menu = Menu::Title;
switch (menu)
{
case Menu::Title:
// New game
DrawString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_NEW_GAME), PRINTSTRING_COLOR_WHITE, SF_Center(title_option == 0));
GetNextLinePosition(&y);
// Load game
DrawString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_LOAD_GAME), PRINTSTRING_COLOR_WHITE, SF_Center(title_option == 1));
GetNextLinePosition(&y);
// Options
DrawString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_OPTIONS), PRINTSTRING_COLOR_WHITE, SF_Center(title_option == 2));
GetNextLinePosition(&y);
// Exit game
DrawString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_EXIT_GAME), PRINTSTRING_COLOR_WHITE, SF_Center(title_option == 3));
break;
case Menu::LoadGame:
RenderLoadSaveMenu();
break;
case Menu::SelectLevel:
// Setup needed parameters
y = MenuVerticalLineSpacing;
// Title
DrawString(MenuCenterEntry, 26, g_GameFlow->GetString(STRING_SELECT_LEVEL), PRINTSTRING_COLOR_ORANGE, SF_Center());
GetNextBlockPosition(&y);
// Level listing (starts with 1 because 0 is always title)
for (int i = 1; i < g_GameFlow->GetNumLevels(); i++)
{
DrawString(MenuCenterEntry, y, g_GameFlow->GetString(g_GameFlow->GetLevel(i)->NameStringKey.c_str()),
PRINTSTRING_COLOR_WHITE, SF_Center(title_option == i - 1));
GetNextNarrowLinePosition(&y);
}
break;
case Menu::Options:
case Menu::Controls:
case Menu::Display:
case Menu::Sound:
RenderOptionsMenu(menu, MenuVerticalOptionsTitle);
break;
}
}
void Renderer11::RenderPauseMenu(Menu menu)
{
int y = 0;
auto pause_option = g_Gui.GetSelectedOption();
switch (g_Gui.GetMenuToDisplay())
{
case Menu::Pause:
// Setup needed parameters
y = MenuVerticalOptionsPause;
// Statistics
DrawString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_STATISTICS), PRINTSTRING_COLOR_WHITE, SF_Center(pause_option == 0));
GetNextLinePosition(&y);
// Options
DrawString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_OPTIONS), PRINTSTRING_COLOR_WHITE, SF_Center(pause_option == 1));
GetNextLinePosition(&y);
// Exit to title
DrawString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_EXIT_TO_TITLE), PRINTSTRING_COLOR_WHITE, SF_Center(pause_option == 2));
break;
case Menu::Statistics:
DrawStatistics();
break;
case Menu::Options:
case Menu::Controls:
case Menu::Display:
case Menu::Sound:
RenderOptionsMenu(menu, MenuVerticalOptionsPause);
break;
}
DrawLines2D();
DrawAllStrings();
}
void Renderer11::RenderLoadSaveMenu()
{
if (!g_GameFlow->EnableLoadSave)
{
g_Gui.SetInventoryMode(InventoryMode::InGame);
return;
}
// Setup needed parameters
int y = MenuVerticalLineSpacing;
short selection = g_Gui.GetLoadSaveSelection();
char stringBuffer[255];
LoadSavegameInfos();
// Title
DrawString(MenuCenterEntry, MenuVerticalNarrowLineSpacing, Str_LoadSave(g_Gui.GetInventoryMode() == InventoryMode::Save),
PRINTSTRING_COLOR_ORANGE, SF_Center());
GetNextBlockPosition(&y);
// Savegame listing
for (int n = 0; n < SAVEGAME_MAX; n++)
{
auto& save = SavegameInfos[n];
if (!save.Present)
{
DrawString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_UNUSED), PRINTSTRING_COLOR_WHITE, SF_Center(selection == n));
}
else
{
// Number
sprintf(stringBuffer, "%03d", save.Count);
DrawString(MenuLoadNumberLeftSide, y, stringBuffer, PRINTSTRING_COLOR_WHITE, SF_Value(selection == n));
// Level name
DrawString(MenuLoadNameLeftSide, y, (char*)save.LevelName.c_str(), PRINTSTRING_COLOR_WHITE, SF_Value(selection == n));
// Timestamp
sprintf(stringBuffer, g_GameFlow->GetString(STRING_SAVEGAME_TIMESTAMP), save.Days, save.Hours, save.Minutes, save.Seconds);
DrawString(MenuRightSideEntry, y, stringBuffer, PRINTSTRING_COLOR_WHITE, SF_Value(selection == n));
}
GetNextLinePosition(&y);
}
DrawAllStrings();
}
void Renderer11::DrawStatistics()
{
char buffer[40];
auto seconds = GameTimer / FPS;
auto days = (seconds / (24 * 60 * 60));
auto hours = (seconds % (24 * 60 * 60)) / (60 * 60);
auto min = (seconds / 60) % 60;
auto sec = (seconds % 60);
ScriptInterfaceLevel* lvl = g_GameFlow->GetLevel(CurrentLevel);
auto y = MenuVerticalStatisticsTitle;
// Title
DrawString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_STATISTICS), PRINTSTRING_COLOR_ORANGE, SF_Center());
GetNextBlockPosition(&y);
// Level name
DrawString(MenuCenterEntry, y, g_GameFlow->GetString(lvl->NameStringKey.c_str()), PRINTSTRING_COLOR_WHITE, SF_Center());
GetNextBlockPosition(&y);
// Time taken
sprintf(buffer, "%02d:%02d:%02d", (days * 24) + hours, min, sec);
DrawString(MenuRightSideEntry, y, buffer, PRINTSTRING_COLOR_WHITE, SF());
DrawString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_TIME_TAKEN), PRINTSTRING_COLOR_WHITE, SF());
GetNextLinePosition(&y);
// Distance travelled
sprintf(buffer, "%dm", Statistics.Game.Distance / UnitsToMeters);
DrawString(MenuRightSideEntry, y, buffer, PRINTSTRING_COLOR_WHITE, SF());
DrawString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_DISTANCE_TRAVELLED), PRINTSTRING_COLOR_WHITE, SF());
GetNextLinePosition(&y);
// Ammo used
sprintf(buffer, "%d", Statistics.Game.AmmoUsed);
DrawString(MenuRightSideEntry, y, buffer, PRINTSTRING_COLOR_WHITE, SF());
DrawString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_USED_AMMOS), PRINTSTRING_COLOR_WHITE, SF());
GetNextLinePosition(&y);
// Medipacks used
sprintf(buffer, "%d", Statistics.Game.HealthUsed);
DrawString(MenuRightSideEntry, y, buffer, PRINTSTRING_COLOR_WHITE, SF());
DrawString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_USED_MEDIPACKS), PRINTSTRING_COLOR_WHITE, SF());
GetNextLinePosition(&y);
// Secrets found
sprintf(buffer, "%d / 36", Statistics.Game.Secrets);
DrawString(MenuRightSideEntry, y, buffer, PRINTSTRING_COLOR_WHITE, SF());
DrawString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_SECRETS_FOUND), PRINTSTRING_COLOR_WHITE, SF());
DrawAllStrings();
}
void Renderer11::RenderNewInventory()
{
g_Gui.DrawCurrentObjectList((int)RingTypes::Inventory);
if (g_Gui.GetRings((int)RingTypes::Ammo)->ringactive)
g_Gui.DrawCurrentObjectList((int)RingTypes::Ammo);
g_Gui.DrawAmmoSelector();
g_Gui.FadeAmmoSelector();
g_Gui.DrawCompass();
DrawAllStrings();
}
void Renderer11::DrawPickup(short objectNum)
{
// Clear just the Z-buffer so we can start drawing on top of the scene
ID3D11DepthStencilView* dsv;
m_context->OMGetRenderTargets(1, nullptr, &dsv);
m_context->ClearDepthStencilView(dsv, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
DrawObjectOn2DPosition(700 + PickupX, 450, objectNum, 0, m_pickupRotation, 0, 0.5f); // TODO: + PickupY
m_pickupRotation += 45 * 360 / 30;
}
void Renderer11::DrawObjectOn2DPosition(short x, short y, short objectNum, short rotX, short rotY, short rotZ,
float scale1)
{
Matrix translation;
Matrix rotation;
Matrix world;
Matrix view;
Matrix projection;
Matrix scale;
UINT stride = sizeof(RendererVertex);
UINT offset = 0;
float factorX = ScreenWidth / REFERENCE_RES_WIDTH;
float factorY = ScreenHeight / REFERENCE_RES_HEIGHT;
x *= factorX;
y *= factorY;
scale1 *= factorX > factorY ? factorY : factorX;
auto index = g_Gui.ConvertObjectToInventoryItem(objectNum);
if (index != -1)
{
auto objme = &inventry_objects_list[index];
y += objme->yoff;
rotX += objme->xrot;
rotY += objme->yrot;
rotZ += objme->zrot;
}
view = Matrix::CreateLookAt(Vector3(0.0f, 0.0f, 2048.0f), Vector3(0.0f, 0.0f, 0.0f),
Vector3(0.0f, -1.0f, 0.0f));
projection = Matrix::CreateOrthographic(ScreenWidth, ScreenHeight, -1024.0f, 1024.0f);
auto& moveableObj = m_moveableObjects[objectNum];
if (!moveableObj)
return;
ObjectInfo* obj = &Objects[objectNum];
if (obj->animIndex != -1)
{
ANIM_FRAME* frame[] = { &g_Level.Frames[g_Level.Anims[obj->animIndex].framePtr] };
UpdateAnimation(nullptr, *moveableObj, frame, 0, 0, 0xFFFFFFFF);
}
Vector3 pos = m_viewportToolkit.Unproject(Vector3(x, y, 1), projection, view, Matrix::Identity);
// Set vertex buffer
m_context->IASetVertexBuffers(0, 1, m_moveablesVertexBuffer.Buffer.GetAddressOf(), &stride, &offset);
m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
m_context->IASetInputLayout(m_inputLayout.Get());
m_context->IASetIndexBuffer(m_moveablesIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
// Set shaders
m_context->VSSetShader(m_vsInventory.Get(), nullptr, 0);
m_context->PSSetShader(m_psInventory.Get(), nullptr, 0);
// Set matrices
CCameraMatrixBuffer HudCamera;
HudCamera.ViewProjection = view * projection;
m_cbCameraMatrices.updateData(HudCamera, m_context.Get());
BindConstantBufferVS(CB_CAMERA, m_cbCameraMatrices.get());
for (int n = 0; n < (*moveableObj).ObjectMeshes.size(); n++)
{
RendererMesh* mesh = (*moveableObj).ObjectMeshes[n];
/*if (GLOBAL_invMode)
{
InventoryObject* objme;
objme = &inventry_objects_list[g_Gui.ConvertObjectToInventoryItem(objectNum)];
if (!(objme->meshbits & (1 << n)))
continue;
}*/
// Finish the world matrix
translation = Matrix::CreateTranslation(pos.x, pos.y, pos.z + 1024.0f);
rotation = Matrix::CreateFromYawPitchRoll(TO_RAD(rotY), TO_RAD(rotX), TO_RAD(rotZ));
scale = Matrix::CreateScale(scale1);
world = scale * rotation;
world = world * translation;
if (obj->animIndex != -1)
m_stItem.World = ((*moveableObj).AnimationTransforms[n] * world);
else
m_stItem.World = ((*moveableObj).BindPoseTransforms[n] * world);
m_stItem.AmbientLight = Vector4(0.5f, 0.5f, 0.5f, 1.0f);
m_cbItem.updateData(m_stItem, m_context.Get());
BindConstantBufferVS(CB_ITEM, m_cbItem.get());
BindConstantBufferPS(CB_ITEM, m_cbItem.get());
for (auto& bucket : mesh->buckets)
{
if (bucket.NumVertices == 0)
continue;
SetBlendMode(BLENDMODE_OPAQUE);
SetCullMode(CULL_MODE_CCW);
SetDepthState(DEPTH_STATE_WRITE_ZBUFFER);
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);
SetAlphaTest(
bucket.BlendMode == BLENDMODE_ALPHATEST ? ALPHA_TEST_GREATER_THAN : ALPHA_TEST_NONE,
ALPHA_TEST_THRESHOLD
);
DrawIndexedTriangles(bucket.NumIndices, bucket.StartIndex, 0);
m_numMoveablesDrawCalls++;
}
}
}
void Renderer11::RenderTitleImage()
{
wchar_t introFileChars[255];
std::mbstowcs(introFileChars, g_GameFlow->IntroImagePath.c_str(), 255);
std::wstring titleStringFileName(introFileChars);
Texture2D texture;
SetTextureOrDefault(texture, titleStringFileName);
float currentFade = 0;
while (currentFade <= 1.0f)
{
DrawFullScreenImage(texture.ShaderResourceView.Get(), currentFade, m_backBufferRTV, m_depthStencilView);
SyncRenderer();
currentFade += FADE_FACTOR;
m_swapChain->Present(0, 0);
}
for (int i = 0; i < 20; i++)
{
DrawFullScreenImage(texture.ShaderResourceView.Get(), 1.0f, m_backBufferRTV, m_depthStencilView);
SyncRenderer();
m_swapChain->Present(0, 0);
}
currentFade = 1.0f;
while (currentFade >= 0.0f)
{
DrawFullScreenImage(texture.ShaderResourceView.Get(), currentFade, m_backBufferRTV, m_depthStencilView);
SyncRenderer();
currentFade -= FADE_FACTOR;
m_swapChain->Present(0, 0);
}
}
void Renderer11::DrawExamines()
{
static short xrot = 0, yrot = 0, zrot = 0;
static float scaler = 1.2f;
float saved_scale;
short inv_item = g_Gui.GetRings((int)RingTypes::Inventory)->current_object_list[g_Gui.GetRings(
(int)RingTypes::Inventory)->curobjinlist].invitem;
InventoryObject* obj = &inventry_objects_list[inv_item];
if (TrInput & IN_LEFT)
yrot += ANGLE(3);
if (TrInput & IN_RIGHT)
yrot -= ANGLE(3);
if (TrInput & IN_FORWARD)
xrot += ANGLE(3);
if (TrInput & IN_BACK)
xrot -= ANGLE(3);
if (TrInput & IN_SPRINT)
scaler += 0.03f;
if (TrInput & IN_CROUCH)
scaler -= 0.03f;
if (scaler > 1.6f)
scaler = 1.6f;
if (scaler < 0.8f)
scaler = 0.8f;
saved_scale = obj->scale1;
obj->scale1 = scaler;
DrawObjectOn2DPosition(400, 300, g_Gui.ConvertInventoryItemToObject(inv_item), xrot, yrot, zrot, obj->scale1);
obj->scale1 = saved_scale;
}
void Renderer11::DrawDiary()
{
InventoryObject* obj = &inventry_objects_list[INV_OBJECT_OPEN_DIARY];
short currentPage = Lara.Inventory.Diary.currentPage;
DrawObjectOn2DPosition(400, 300, g_Gui.ConvertInventoryItemToObject(INV_OBJECT_OPEN_DIARY), obj->xrot,
obj->yrot, obj->zrot, obj->scale1);
for (int i = 0; i < MaxStringsPerPage; i++)
{
if (!Lara.Inventory.Diary.Pages[Lara.Inventory.Diary.currentPage].Strings[i].x && !Lara.Inventory.Diary.Pages[Lara.Inventory.Diary.currentPage].
Strings[i].y && !Lara.Inventory.Diary.Pages[Lara.Inventory.Diary.currentPage].Strings[i].stringID)
break;
//DrawString(Lara.Diary.Pages[currentPage].Strings[i].x, Lara.Diary.Pages[currentPage].Strings[i].y, g_GameFlow->GetString(Lara.Diary.Pages[currentPage].Strings[i].stringID), PRINTSTRING_COLOR_WHITE, 0);
}
DrawAllStrings();
}
void Renderer11::RenderInventoryScene(ID3D11RenderTargetView* target, ID3D11DepthStencilView* depthTarget,
ID3D11ShaderResourceView* background)
{
m_lines2DToDraw.clear();
m_strings.clear();
// Set basic render states
SetBlendMode(BLENDMODE_OPAQUE, true);
SetDepthState(DEPTH_STATE_WRITE_ZBUFFER, true);
SetCullMode(CULL_MODE_CCW, true);
// Bind and clear render target
m_context->OMSetRenderTargets(1, &target, depthTarget);
m_context->RSSetViewports(1, &m_viewport);
ResetScissor();
if (background != nullptr)
DrawFullScreenImage(background, 0.5f, target, depthTarget);
m_context->ClearDepthStencilView(depthTarget, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
UINT stride = sizeof(RendererVertex);
UINT offset = 0;
// Set vertex buffer
m_context->IASetVertexBuffers(0, 1, m_moveablesVertexBuffer.Buffer.GetAddressOf(), &stride, &offset);
m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
m_context->IASetInputLayout(m_inputLayout.Get());
m_context->IASetIndexBuffer(m_moveablesIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
// Set shaders
m_context->VSSetShader(m_vsInventory.Get(), nullptr, 0);
m_context->PSSetShader(m_psInventory.Get(), nullptr, 0);
// Set texture
BindTexture(TEXTURE_COLOR_MAP, &std::get<0>(m_moveablesTextures[0]), SAMPLER_ANISOTROPIC_CLAMP);
BindTexture(TEXTURE_NORMAL_MAP, &std::get<1>(m_moveablesTextures[0]), SAMPLER_NONE);
if (CurrentLevel == 0)
{
Menu title_menu = g_Gui.GetMenuToDisplay();
bool drawLogo = (title_menu == Menu::Title || title_menu == Menu::Options);
if (drawLogo)
{
float factorX = (float)ScreenWidth / REFERENCE_RES_WIDTH;
float factorY = (float)ScreenHeight / REFERENCE_RES_HEIGHT;
float scale = ScreenWidth > ScreenHeight ? factorX : factorY;
int logoLeft = (REFERENCE_RES_WIDTH / 2) - (LogoWidth / 2);
int logoRight = (REFERENCE_RES_WIDTH / 2) + (LogoWidth / 2);
int logoBottom = LogoTop + LogoHeight;
RECT rect;
rect.left = logoLeft * scale;
rect.right = logoRight * scale;
rect.top = LogoTop * scale;
rect.bottom = logoBottom * scale;
m_spriteBatch->Begin(SpriteSortMode_BackToFront, m_states->NonPremultiplied());
m_spriteBatch->Draw(m_logo.ShaderResourceView.Get(), rect, Vector4::One * ScreenFadeCurrent);
m_spriteBatch->End();
}
RenderTitleMenu(title_menu);
return;
}
switch (g_Gui.GetInventoryMode())
{
case InventoryMode::Load:
case InventoryMode::Save:
RenderLoadSaveMenu();
return;
case InventoryMode::InGame:
RenderNewInventory();
return;
case InventoryMode::Statistics:
DrawStatistics();
return;
case InventoryMode::Examine:
DrawExamines();
return;
case InventoryMode::Pause:
RenderPauseMenu(g_Gui.GetMenuToDisplay());
return;
case InventoryMode::Diary:
DrawDiary();
return;
}
}
void Renderer11::SetLoadingScreen(std::wstring& fileName)
{
SetTextureOrDefault(loadingScreenTexture, fileName);
}
void Renderer11::RenderLoadingScreen(float percentage)
{
do
{
// Set basic render states
SetBlendMode(BLENDMODE_OPAQUE);
SetCullMode(CULL_MODE_CCW);
// Clear screen
m_context->ClearRenderTargetView(m_backBufferRTV, Colors::Black);
m_context->ClearDepthStencilView(m_depthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
// Bind the back buffer
m_context->OMSetRenderTargets(1, &m_backBufferRTV, m_depthStencilView);
m_context->RSSetViewports(1, &m_viewport);
ResetScissor();
// Draw the full screen background
DrawFullScreenQuad(
loadingScreenTexture.ShaderResourceView.Get(),
Vector3(ScreenFadeCurrent, ScreenFadeCurrent, ScreenFadeCurrent));
m_context->ClearDepthStencilView(m_depthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
DrawLoadingBar(percentage);
m_swapChain->Present(0, 0);
m_context->ClearState();
SyncRenderer();
UpdateFadeScreenAndCinematicBars();
} while (ScreenFading || !ScreenFadedOut);
}
void Renderer11::RenderInventory()
{
m_context->ClearDepthStencilView(m_depthStencilView, D3D11_CLEAR_STENCIL | D3D11_CLEAR_DEPTH, 1.0f, 0);
m_context->ClearRenderTargetView(m_backBufferRTV, Colors::Black);
RenderInventoryScene(m_backBufferRTV, m_depthStencilView, m_dumpScreenRenderTarget.ShaderResourceView.Get());
m_swapChain->Present(0, 0);
}
void Renderer11::RenderTitle()
{
m_context->ClearDepthStencilView(m_depthStencilView, D3D11_CLEAR_STENCIL | D3D11_CLEAR_DEPTH, 1.0f, 0);
m_context->ClearRenderTargetView(m_backBufferRTV, Colors::Black);
RenderScene(m_backBufferRTV, m_depthStencilView, gameCamera);
m_context->ClearDepthStencilView(m_depthStencilView, D3D11_CLEAR_STENCIL | D3D11_CLEAR_DEPTH, 1.0f, 0);
RenderInventoryScene(m_backBufferRTV, m_depthStencilView, nullptr);
#if _DEBUG
DrawString(0, 0, commit.c_str(), D3DCOLOR_ARGB(255, 255, 255, 255), 0);
DrawAllStrings();
#else
DrawAllStrings();
#endif
m_swapChain->Present(0, 0);
}
void Renderer11::DrawDebugInfo(RenderView& view)
{
if (CurrentLevel != 0)
{
m_currentY = 60;
ROOM_INFO* r = &g_Level.Rooms[LaraItem->RoomNumber];
switch (m_numDebugPage)
{
case RENDERER_DEBUG_PAGE::NO_PAGE:
break;
case RENDERER_DEBUG_PAGE::RENDERER_STATS:
PrintDebugMessage("GPU: %s", g_Configuration.AdapterName.c_str());
PrintDebugMessage("Resolution: %d x %d", ScreenWidth, ScreenHeight);
PrintDebugMessage("Fps: %3.2f", m_fps);
PrintDebugMessage("Update time: %d", m_timeUpdate);
PrintDebugMessage("Frame time: %d", m_timeFrame);
PrintDebugMessage("Total draw calls: %d", m_numDrawCalls);
PrintDebugMessage(" For rooms: %d", m_numRoomsDrawCalls);
PrintDebugMessage(" For movables: %d", m_numMoveablesDrawCalls);
PrintDebugMessage(" For statics: %d", m_numStaticsDrawCalls);
PrintDebugMessage(" For sprites: %d", m_numSpritesDrawCalls);
PrintDebugMessage("Total triangles: %d", m_numPolygons);
PrintDebugMessage("Transparent faces draw calls: %d", m_numTransparentDrawCalls);
PrintDebugMessage(" For rooms: %d", m_numRoomsTransparentDrawCalls);
PrintDebugMessage(" For movables: %d", m_numMoveablesTransparentDrawCalls);
PrintDebugMessage(" For statics: %d", m_numStaticsTransparentDrawCalls);
PrintDebugMessage(" For sprites: %d", m_numSpritesTransparentDrawCalls);
PrintDebugMessage("Biggest room's index buffer: %d", m_biggestRoomIndexBuffer);
PrintDebugMessage("Total rooms transparent polygons: %d", numRoomsTransparentPolygons);
PrintDebugMessage("Rooms: %d", view.roomsToDraw.size());
break;
case RENDERER_DEBUG_PAGE::DIMENSION_STATS:
PrintDebugMessage("Lara Location: %d %d", LaraItem->Location.roomNumber, LaraItem->Location.yNumber);
PrintDebugMessage("Lara RoomNumber: %d", LaraItem->RoomNumber);
PrintDebugMessage("LaraItem BoxNumber: %d",/* canJump: %d, canLongJump: %d, canMonkey: %d,*/
LaraItem->BoxNumber);
PrintDebugMessage("Lara Pos: %d %d %d", LaraItem->Pose.Position.x, LaraItem->Pose.Position.y, LaraItem->Pose.Position.z);
PrintDebugMessage("Lara Rot: %d %d %d", LaraItem->Pose.Orientation.x, LaraItem->Pose.Orientation.y, LaraItem->Pose.Orientation.z);
PrintDebugMessage("Lara WaterSurfaceDist: %d", Lara.WaterSurfaceDist);
PrintDebugMessage("Room: %d %d %d %d", r->x, r->z, r->x + r->xSize * SECTOR(1),
r->z + r->zSize * SECTOR(1));
PrintDebugMessage("Room.y, minFloor, maxCeiling: %d %d %d ", r->y, r->minfloor, r->maxceiling);
PrintDebugMessage("Camera.pos: %d %d %d", Camera.pos.x, Camera.pos.y, Camera.pos.z);
PrintDebugMessage("Camera.target: %d %d %d", Camera.target.x, Camera.target.y, Camera.target.z);
PrintDebugMessage("Camera.roomNumber: %d", Camera.pos.roomNumber);
break;
case RENDERER_DEBUG_PAGE::LARA_STATS:
PrintDebugMessage("Lara AnimNumber: %d", LaraItem->Animation.AnimNumber);
PrintDebugMessage("Lara FrameNumber: %d", LaraItem->Animation.FrameNumber);
PrintDebugMessage("Lara ActiveState: %d", LaraItem->Animation.ActiveState);
PrintDebugMessage("Lara TargetState: %d", LaraItem->Animation.TargetState);
PrintDebugMessage("Lara Velocity, VerticalVelocity, LateralVelocity: %d %d %d", LaraItem->Animation.Velocity, LaraItem->Animation.VerticalVelocity, LaraItem->Animation.LateralVelocity);
PrintDebugMessage("Lara ExtraVelocity.x, y, z: %d %d %d", Lara.ExtraVelocity.x, Lara.ExtraVelocity.y, Lara.ExtraVelocity.z);
PrintDebugMessage("Lara WaterStatus: %d", Lara.Control.WaterStatus);
PrintDebugMessage("Lara IsMoving: %d", Lara.Control.IsMoving);
PrintDebugMessage("Lara HandStatus: %d", Lara.Control.HandStatus);
PrintDebugMessage("Lara Airborne: %d", LaraItem->Animation.Airborne);
PrintDebugMessage("Lara CanClimbLadder: %d", Lara.Control.CanClimbLadder);
break;
case RENDERER_DEBUG_PAGE::LOGIC_STATS:
PrintDebugMessage("target hitPoints: %d", Lara.TargetEntity ? Lara.TargetEntity->HitPoints : 0);
PrintDebugMessage("CollidedVolume: %d", TEN::Control::Volumes::CurrentCollidedVolume);
break;
}
}
}
void Renderer11::SwitchDebugPage(bool back)
{
auto index = (int)m_numDebugPage;
if (back)
--index;
else
++index;
if (index < RENDERER_DEBUG_PAGE::NO_PAGE)
index = 4;
else if (index > RENDERER_DEBUG_PAGE::LOGIC_STATS)
index = 0;
m_numDebugPage = (RENDERER_DEBUG_PAGE)index;
}
}

View file

@ -169,9 +169,6 @@ constexpr auto TEXTURE_HEIGHT = 256;
constexpr auto TEXTURE_WIDTH = 256;
constexpr auto TEXTURE_PAGE = (TEXTURE_HEIGHT * TEXTURE_WIDTH);
constexpr auto ASSUMED_WIDTH_FOR_TEXT_DRAWING = 800.0f;
constexpr auto ASSUMED_HEIGHT_FOR_TEXT_DRAWING = 600.0f;
#define TEXTURE_ATLAS_SIZE 4096
#define TEXTURE_PAGE_SIZE 262144
#define NUM_TEXTURE_PAGES_PER_ROW 16
@ -220,24 +217,29 @@ constexpr auto ASSUMED_HEIGHT_FOR_TEXT_DRAWING = 600.0f;
constexpr auto FADE_FRAMES_COUNT = 16;
constexpr auto FADE_FACTOR = 0.0625f;
constexpr auto NUM_LIGHTS_PER_BUFFER = 48;
constexpr auto MAX_LIGHTS_PER_ITEM = 48;
constexpr auto MAX_LIGHTS = 100;
constexpr auto AMBIENT_LIGHT_INTERPOLATION_STEPS = 8;
constexpr auto MAX_DYNAMIC_SHADOWS = 1;
constexpr auto MAX_DYNAMIC_LIGHTS = 1024;
constexpr auto MAX_TRANSPARENT_FACES = 16384;
constexpr auto MAX_TRANSPARENT_VERTICES = (MAX_TRANSPARENT_FACES * 6);
constexpr auto MAX_TRANSPARENT_FACES_PER_ROOM = 16384;
constexpr auto TRANSPARENT_BUCKET_SIZE = (3840 * 16);
constexpr auto ALPHA_TEST_THRESHOLD = 0.5f;
constexpr auto FAST_ALPHA_BLEND_THRESHOLD = 0.5f;
constexpr auto MAX_BONES = 32;
constexpr auto AMBIENT_LIGHT_INTERPOLATION_STEPS = 8;
constexpr auto REFERENCE_RES_WIDTH = 800;
constexpr auto REFERENCE_RES_HEIGHT = 450;
constexpr auto REFERENCE_RES_WIDTH = 800.0f;
constexpr auto REFERENCE_RES_HEIGHT = 600.0f;
constexpr auto HUD_UNIT_X = 1.0f / REFERENCE_RES_WIDTH;
constexpr auto HUD_UNIT_Y = 1.0f / REFERENCE_RES_HEIGHT;
constexpr auto HUD_ZERO_Y = -REFERENCE_RES_HEIGHT;
constexpr auto MAX_DYNAMIC_SHADOWS = 1;
constexpr auto MAX_DYNAMIC_LIGHTS = 1024;
constexpr auto ALPHA_TEST_THRESHOLD = 0.5f;
constexpr auto FAST_ALPHA_BLEND_THRESHOLD = 0.5f;
constexpr auto UNDERWATER_FOG_MIN_DISTANCE = 4;
constexpr auto UNDERWATER_FOG_MAX_DISTANCE = 30;
constexpr auto MAX_ROOM_BOUNDS = 256;

View file

@ -220,7 +220,7 @@ void TEN::Renderer::Renderer11::Initialise(int w, int h, bool windowed, HWND han
rasterizerStateDesc.ScissorEnable = true;
Utils::throwIfFailed(m_device->CreateRasterizerState(&rasterizerStateDesc, m_cullNoneRasterizerState.GetAddressOf()));
InitialiseBars();
InitialiseGameBars();
initQuad(m_device.Get());
}

View file

@ -4,10 +4,8 @@
namespace TEN::Renderer {
void Renderer11::DrawString(int x, int y, const char* string, D3DCOLOR color, int flags)
{
int realX = x;
int realY = y;
float factorX = ScreenWidth / ASSUMED_WIDTH_FOR_TEXT_DRAWING;
float factorY = ScreenHeight / ASSUMED_HEIGHT_FOR_TEXT_DRAWING;
float factorX = ScreenWidth / REFERENCE_RES_WIDTH;
float factorY = ScreenHeight / REFERENCE_RES_HEIGHT;
RECT rect = { 0, 0, 0, 0 };
@ -49,11 +47,15 @@ namespace TEN::Renderer {
if (flags & PRINTSTRING_BLINK)
{
str.Color = Vector3(m_blinkColorValue, m_blinkColorValue, m_blinkColorValue);
if (!(flags & PRINTSTRING_DONT_UPDATE_BLINK))
if (flags & PRINTSTRING_DONT_UPDATE_BLINK)
{
str.Color = Vector3(192);
}
else if (!m_blinkUpdated)
{
str.Color = Vector3(m_blinkColorValue, m_blinkColorValue, m_blinkColorValue);
m_blinkColorValue += m_blinkColorDirection * 16;
m_blinkUpdated = true;
if (m_blinkColorValue < 0)
{
@ -93,5 +95,8 @@ namespace TEN::Renderer {
}
m_spriteBatch->End();
m_blinkUpdated = false;
m_strings.clear();
}
}

View file

@ -12,6 +12,7 @@
#define STRING_SAVE_GAME "save_game"
#define STRING_EXIT_GAME "exit_game"
#define STRING_EXIT_TO_TITLE "exit_to_title"
#define STRING_OPTIONS "options"
#define STRING_UZI "uzi"
#define STRING_PISTOLS "pistols_ammo"
#define STRING_SHOTGUN "shotgun"

View file

@ -627,6 +627,7 @@ CALL gen.bat</Command>
<ClCompile Include="Objects\Effects\flame_emitters.cpp" />
<ClCompile Include="Game\effects\lara_fx.cpp" />
<ClCompile Include="Objects\Generic\Traps\dart_emitter.cpp" />
<ClCompile Include="Renderer\Renderer11DrawMenu.cpp" />
<ClCompile Include="Scripting\Internal\LuaHandler.cpp" />
<ClCompile Include="Scripting\Internal\ScriptAssert.cpp" />
<ClCompile Include="Scripting\Internal\ScriptInterfaceState.cpp" />