Merge pull request #1109 from MontyTRC89/assetDir

Game dir arg
This commit is contained in:
hispidence 2023-05-20 21:02:19 +01:00 committed by GitHub
commit 0226d577ce
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 235 additions and 136 deletions

View file

@ -452,7 +452,7 @@ void InitializeScripting(int levelIndex, bool loadGame)
// Run level script if it exists.
if (!level->ScriptFileName.empty())
{
g_GameScript->ExecuteScriptFile(level->ScriptFileName);
g_GameScript->ExecuteScriptFile(g_GameFlow->GetGameDir() + level->ScriptFileName);
g_GameScript->InitCallbacks();
g_GameStringsHandler->SetCallbackDrawString([](std::string const key, D3DCOLOR col, int x, int y, int flags)
{

View file

@ -5,14 +5,15 @@
#include <spdlog/sinks/basic_file_sink.h>
#include <spdlog/sinks/stdout_color_sinks.h>
void InitTENLog()
void InitTENLog(const std::string& logDirContainingDir)
{
// "true" means that we create a new log file each time we run the game.
auto fileSink = std::make_shared<spdlog::sinks::basic_file_sink_mt>("Logs/TENLog.txt", true);
// "true" means create new log file each time game is run.
auto logPath = logDirContainingDir + "Logs/TENLog.txt";
auto fileSink = std::make_shared<spdlog::sinks::basic_file_sink_mt>(logPath, true);
std::shared_ptr<spdlog::logger> logger;
// Set the file and console log targets.
// Set file and console log targets.
auto consoleSink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
logger = std::make_shared<spdlog::logger>(std::string{ "multi_sink" }, spdlog::sinks_init_list{ fileSink, consoleSink });

View file

@ -24,7 +24,7 @@ enum class LogConfig
void TENLog(std::string_view str, LogLevel level = LogLevel::Info, LogConfig config = LogConfig::All, bool allowSpam = false);
void ShutdownTENLog();
void InitTENLog();
void InitTENLog(const std::string& logDirContainingDir);
class TENScriptException : public std::runtime_error
{

View file

@ -50,24 +50,25 @@ const std::string SAVEGAME_PATH = "Save//";
GameStats Statistics;
SaveGameHeader SavegameInfos[SAVEGAME_MAX];
FileStream* SaveGame::m_stream;
FileStream* SaveGame::StreamPtr;
std::string SaveGame::FullSaveDir;
int SaveGame::LastSaveGame;
void LoadSavegameInfos()
void SaveGame::LoadSavegameInfos()
{
for (int i = 0; i < SAVEGAME_MAX; i++)
SavegameInfos[i].Present = false;
if (!std::filesystem::exists(SAVEGAME_PATH))
if (!std::filesystem::exists(FullSaveDir))
return;
// try to load the savegame
// Try loading savegame.
for (int i = 0; i < SAVEGAME_MAX; i++)
{
auto fileName = SAVEGAME_PATH + "savegame." + std::to_string(i);
auto fileName = FullSaveDir + "savegame." + std::to_string(i);
auto savegamePtr = fopen(fileName.c_str(), "rb");
if (savegamePtr == NULL)
if (savegamePtr == nullptr)
continue;
fclose(savegamePtr);
@ -169,7 +170,7 @@ Vector4 ToVector4(const Save::Vector4* vec)
bool SaveGame::Save(int slot)
{
auto fileName = std::string(SAVEGAME_PATH) + "savegame." + std::to_string(slot);
auto fileName = FullSaveDir + "savegame." + std::to_string(slot);
TENLog("Saving to savegame: " + fileName, LogLevel::Info);
ItemInfo itemToSerialize{};
@ -1315,8 +1316,8 @@ bool SaveGame::Save(int slot)
auto bufferToSerialize = fbb.GetBufferPointer();
auto bufferSize = fbb.GetSize();
if (!std::filesystem::exists(SAVEGAME_PATH))
std::filesystem::create_directory(SAVEGAME_PATH);
if (!std::filesystem::exists(FullSaveDir))
std::filesystem::create_directory(FullSaveDir);
std::ofstream fileOut{};
fileOut.open(fileName, std::ios_base::binary | std::ios_base::out);
@ -1326,9 +1327,14 @@ bool SaveGame::Save(int slot)
return true;
}
void SaveGame::AddGameDirToSavePath(const std::string& dirLocation)
{
FullSaveDir = dirLocation + SAVEGAME_PATH;
}
bool SaveGame::Load(int slot)
{
auto fileName = SAVEGAME_PATH + "savegame." + std::to_string(slot);
auto fileName = FullSaveDir + "savegame." + std::to_string(slot);
TENLog("Loading from savegame: " + fileName, LogLevel::Info);
std::ifstream file;
@ -2158,7 +2164,7 @@ bool SaveGame::Load(int slot)
bool SaveGame::LoadHeader(int slot, SaveGameHeader* header)
{
auto fileName = SAVEGAME_PATH + "savegame." + std::to_string(slot);
auto fileName = FullSaveDir + "savegame." + std::to_string(slot);
std::ifstream file;
file.open(fileName, std::ios_base::app | std::ios_base::binary);

View file

@ -44,14 +44,15 @@ extern SaveGameHeader SavegameInfos[SAVEGAME_MAX];
class SaveGame
{
private:
static FileStream* m_stream;
static FileStream* StreamPtr;
static std::string FullSaveDir;
public:
static int LastSaveGame;
static void AddGameDirToSavePath(const std::string& dir);
static bool Load(int slot);
static bool LoadHeader(int slot, SaveGameHeader* header);
static bool Save(int slot);
static void LoadSavegameInfos();
};
void LoadSavegameInfos();

View file

@ -402,7 +402,7 @@ namespace TEN::Renderer
int y = MenuVerticalLineSpacing;
short selection = g_Gui.GetLoadSaveSelection();
char stringBuffer[255];
LoadSavegameInfos();
SaveGame::LoadSavegameInfos();
// Title
AddString(MenuCenterEntry, MenuVerticalNarrowLineSpacing, Str_LoadSave(g_Gui.GetInventoryMode() == InventoryMode::Save),

View file

@ -17,6 +17,11 @@ using std::vector;
extern GameConfiguration g_Configuration;
static std::wstring GetAssetPath(const wchar_t* fileName)
{
return TEN::Utils::ToWString(g_GameFlow->GetGameDir()) + fileName;
}
void TEN::Renderer::Renderer11::Initialize(int w, int h, bool windowed, HWND handle)
{
TENLog("Initializing DX11...", LogLevel::Info);
@ -34,7 +39,7 @@ void TEN::Renderer::Renderer11::Initialize(int w, int h, bool windowed, HWND han
ComPtr<ID3D10Blob> blob;
const D3D_SHADER_MACRO roomDefinesAnimated[] = { "ANIMATED", "", nullptr, nullptr };
m_vsRooms = Utils::compileVertexShader(m_device.Get(),L"Shaders\\DX11_Rooms.fx", "VS", "vs_4_0", nullptr, blob);
m_vsRooms = Utils::compileVertexShader(m_device.Get(),GetAssetPath(L"Shaders\\DX11_Rooms.fx"), "VS", "vs_4_0", nullptr, blob);
// Initialize input layout using the first vertex shader
D3D11_INPUT_ELEMENT_DESC inputLayout[] =
@ -53,36 +58,37 @@ void TEN::Renderer::Renderer11::Initialize(int w, int h, bool windowed, HWND han
};
Utils::throwIfFailed(m_device->CreateInputLayout(inputLayout, 11, blob->GetBufferPointer(), blob->GetBufferSize(), &m_inputLayout));
m_vsRooms_Anim = Utils::compileVertexShader(m_device.Get(), L"Shaders\\DX11_Rooms.fx", "VS", "vs_4_0", &roomDefinesAnimated[0], blob);
m_psRooms = Utils::compilePixelShader(m_device.Get(), L"Shaders\\DX11_Rooms.fx", "PS", "ps_4_1", nullptr, blob);
m_vsItems = Utils::compileVertexShader(m_device.Get(), L"Shaders\\DX11_Items.fx", "VS", "vs_4_0", nullptr, blob);
m_psItems = Utils::compilePixelShader(m_device.Get(), L"Shaders\\DX11_Items.fx", "PS", "ps_4_0", nullptr, blob);
m_vsStatics = Utils::compileVertexShader(m_device.Get(), L"Shaders\\DX11_Statics.fx", "VS", "vs_4_0", nullptr, blob);
m_psStatics = Utils::compilePixelShader(m_device.Get(), L"Shaders\\DX11_Statics.fx", "PS", "ps_4_0", nullptr, blob);
m_vsHairs = Utils::compileVertexShader(m_device.Get(), L"Shaders\\DX11_Hairs.fx", "VS", "vs_4_0", nullptr, blob);
m_psHairs = Utils::compilePixelShader(m_device.Get(), L"Shaders\\DX11_Hairs.fx", "PS", "ps_4_0", nullptr, blob);
m_vsSky = Utils::compileVertexShader(m_device.Get(), L"Shaders\\DX11_Sky.fx", "VS", "vs_4_0", nullptr, blob);
m_psSky = Utils::compilePixelShader(m_device.Get(), L"Shaders\\DX11_Sky.fx", "PS", "ps_4_0", nullptr, blob);
m_vsSprites = Utils::compileVertexShader(m_device.Get(), L"Shaders\\DX11_Sprites.fx", "VS", "vs_4_0", nullptr, blob);
m_psSprites = Utils::compilePixelShader(m_device.Get(), L"Shaders\\DX11_Sprites.fx", "PS", "ps_4_0", nullptr, blob);
m_vsSolid = Utils::compileVertexShader(m_device.Get(), L"Shaders\\DX11_Solid.fx", "VS", "vs_4_0", nullptr, blob);
m_psSolid = Utils::compilePixelShader(m_device.Get(), L"Shaders\\DX11_Solid.fx", "PS", "ps_4_0", nullptr, blob);
m_vsInventory = Utils::compileVertexShader(m_device.Get(), L"Shaders\\DX11_Inventory.fx", "VS", "vs_4_0",nullptr, blob);
m_psInventory = Utils::compilePixelShader(m_device.Get(), L"Shaders\\DX11_Inventory.fx", "PS", "ps_4_0", nullptr, blob);
m_vsFullScreenQuad = Utils::compileVertexShader(m_device.Get(), L"Shaders\\DX11_FullScreenQuad.fx", "VS", "vs_4_0",nullptr, blob);
m_psFullScreenQuad = Utils::compilePixelShader(m_device.Get(), L"Shaders\\DX11_FullScreenQuad.fx", "PS", "ps_4_0", nullptr, blob);
m_vsShadowMap = Utils::compileVertexShader(m_device.Get(), L"Shaders\\DX11_ShadowMap.fx", "VS", "vs_4_0", nullptr, blob);
m_psShadowMap = Utils::compilePixelShader(m_device.Get(), L"Shaders\\DX11_ShadowMap.fx", "PS", "ps_4_0", nullptr, blob);
m_vsHUD = Utils::compileVertexShader(m_device.Get(), L"Shaders\\HUD\\DX11_VS_HUD.hlsl", "VS", "vs_4_0", nullptr, blob);
m_psHUDColor = Utils::compilePixelShader(m_device.Get(), L"Shaders\\HUD\\DX11_PS_HUD.hlsl", "PSColored", "ps_4_0", nullptr, blob);
m_psHUDTexture = Utils::compilePixelShader(m_device.Get(), L"Shaders\\HUD\\DX11_PS_HUD.hlsl", "PSTextured", "ps_4_0", nullptr, blob);
m_psHUDBarColor = Utils::compilePixelShader(m_device.Get(), L"Shaders\\HUD\\DX11_PS_HUDBar.hlsl", "PSTextured", "ps_4_0", nullptr, blob);
m_vsFinalPass = Utils::compileVertexShader(m_device.Get(), L"Shaders\\DX11_FinalPass.fx", "VS", "vs_4_0", nullptr, blob);
m_psFinalPass = Utils::compilePixelShader(m_device.Get(), L"Shaders\\DX11_FinalPass.fx", "PS", "ps_4_0", nullptr, blob);
m_vsInstancedStaticMeshes = Utils::compileVertexShader(m_device.Get(), L"Shaders\\DX11_InstancedStatics.fx", "VS", "vs_4_0", nullptr, blob);
m_psInstancedStaticMeshes = Utils::compilePixelShader(m_device.Get(), L"Shaders\\DX11_InstancedStatics.fx", "PS", "ps_4_0", nullptr, blob);
m_vsInstancedSprites = Utils::compileVertexShader(m_device.Get(), L"Shaders\\DX11_InstancedSprites.fx", "VS", "vs_4_0", nullptr, blob);
m_psInstancedSprites = Utils::compilePixelShader(m_device.Get(), L"Shaders\\DX11_InstancedSprites.fx", "PS", "ps_4_0", nullptr, blob);
// TODO: If shader loading moves to a less hardcoded system we should take the opportunity to apply GetAssetPath more gracefully - squidshire 13/05/2023
m_vsRooms_Anim = Utils::compileVertexShader(m_device.Get(), GetAssetPath(L"Shaders\\DX11_Rooms.fx"), "VS", "vs_4_0", &roomDefinesAnimated[0], blob);
m_psRooms = Utils::compilePixelShader(m_device.Get(), GetAssetPath(L"Shaders\\DX11_Rooms.fx"), "PS", "ps_4_1", nullptr, blob);
m_vsItems = Utils::compileVertexShader(m_device.Get(), GetAssetPath(L"Shaders\\DX11_Items.fx"), "VS", "vs_4_0", nullptr, blob);
m_psItems = Utils::compilePixelShader(m_device.Get(), GetAssetPath(L"Shaders\\DX11_Items.fx"), "PS", "ps_4_0", nullptr, blob);
m_vsStatics = Utils::compileVertexShader(m_device.Get(), GetAssetPath(L"Shaders\\DX11_Statics.fx"), "VS", "vs_4_0", nullptr, blob);
m_psStatics = Utils::compilePixelShader(m_device.Get(), GetAssetPath(L"Shaders\\DX11_Statics.fx"), "PS", "ps_4_0", nullptr, blob);
m_vsHairs = Utils::compileVertexShader(m_device.Get(), GetAssetPath(L"Shaders\\DX11_Hairs.fx"), "VS", "vs_4_0", nullptr, blob);
m_psHairs = Utils::compilePixelShader(m_device.Get(), GetAssetPath(L"Shaders\\DX11_Hairs.fx"), "PS", "ps_4_0", nullptr, blob);
m_vsSky = Utils::compileVertexShader(m_device.Get(), GetAssetPath(L"Shaders\\DX11_Sky.fx"), "VS", "vs_4_0", nullptr, blob);
m_psSky = Utils::compilePixelShader(m_device.Get(), GetAssetPath(L"Shaders\\DX11_Sky.fx"), "PS", "ps_4_0", nullptr, blob);
m_vsSprites = Utils::compileVertexShader(m_device.Get(), GetAssetPath(L"Shaders\\DX11_Sprites.fx"), "VS", "vs_4_0", nullptr, blob);
m_psSprites = Utils::compilePixelShader(m_device.Get(), GetAssetPath(L"Shaders\\DX11_Sprites.fx"), "PS", "ps_4_0", nullptr, blob);
m_vsSolid = Utils::compileVertexShader(m_device.Get(), GetAssetPath(L"Shaders\\DX11_Solid.fx"), "VS", "vs_4_0", nullptr, blob);
m_psSolid = Utils::compilePixelShader(m_device.Get(), GetAssetPath(L"Shaders\\DX11_Solid.fx"), "PS", "ps_4_0", nullptr, blob);
m_vsInventory = Utils::compileVertexShader(m_device.Get(), GetAssetPath(L"Shaders\\DX11_Inventory.fx"), "VS", "vs_4_0",nullptr, blob);
m_psInventory = Utils::compilePixelShader(m_device.Get(), GetAssetPath(L"Shaders\\DX11_Inventory.fx"), "PS", "ps_4_0", nullptr, blob);
m_vsFullScreenQuad = Utils::compileVertexShader(m_device.Get(), GetAssetPath(L"Shaders\\DX11_FullScreenQuad.fx"), "VS", "vs_4_0",nullptr, blob);
m_psFullScreenQuad = Utils::compilePixelShader(m_device.Get(), GetAssetPath(L"Shaders\\DX11_FullScreenQuad.fx"), "PS", "ps_4_0", nullptr, blob);
m_vsShadowMap = Utils::compileVertexShader(m_device.Get(), GetAssetPath(L"Shaders\\DX11_ShadowMap.fx"), "VS", "vs_4_0", nullptr, blob);
m_psShadowMap = Utils::compilePixelShader(m_device.Get(), GetAssetPath(L"Shaders\\DX11_ShadowMap.fx"), "PS", "ps_4_0", nullptr, blob);
m_vsHUD = Utils::compileVertexShader(m_device.Get(), GetAssetPath(L"Shaders\\HUD\\DX11_VS_HUD.hlsl"), "VS", "vs_4_0", nullptr, blob);
m_psHUDColor = Utils::compilePixelShader(m_device.Get(), GetAssetPath(L"Shaders\\HUD\\DX11_PS_HUD.hlsl"), "PSColored", "ps_4_0", nullptr, blob);
m_psHUDTexture = Utils::compilePixelShader(m_device.Get(), GetAssetPath(L"Shaders\\HUD\\DX11_PS_HUD.hlsl"), "PSTextured", "ps_4_0", nullptr, blob);
m_psHUDBarColor = Utils::compilePixelShader(m_device.Get(), GetAssetPath(L"Shaders\\HUD\\DX11_PS_HUDBar.hlsl"), "PSTextured", "ps_4_0", nullptr, blob);
m_vsFinalPass = Utils::compileVertexShader(m_device.Get(), GetAssetPath(L"Shaders\\DX11_FinalPass.fx"), "VS", "vs_4_0", nullptr, blob);
m_psFinalPass = Utils::compilePixelShader(m_device.Get(), GetAssetPath(L"Shaders\\DX11_FinalPass.fx"), "PS", "ps_4_0", nullptr, blob);
m_vsInstancedStaticMeshes = Utils::compileVertexShader(m_device.Get(), GetAssetPath(L"Shaders\\DX11_InstancedStatics.fx"), "VS", "vs_4_0", nullptr, blob);
m_psInstancedStaticMeshes = Utils::compilePixelShader(m_device.Get(), GetAssetPath(L"Shaders\\DX11_InstancedStatics.fx"), "PS", "ps_4_0", nullptr, blob);
m_vsInstancedSprites = Utils::compileVertexShader(m_device.Get(), GetAssetPath(L"Shaders\\DX11_InstancedSprites.fx"), "VS", "vs_4_0", nullptr, blob);
m_psInstancedSprites = Utils::compilePixelShader(m_device.Get(), GetAssetPath(L"Shaders\\DX11_InstancedSprites.fx"), "PS", "ps_4_0", nullptr, blob);
// Initialize input layout using the first vertex
/*D3D11_INPUT_ELEMENT_DESC inputLayoutSprites[] =
@ -319,18 +325,18 @@ void TEN::Renderer::Renderer11::InitializeScreen(int w, int h, HWND handle, bool
void Renderer11::InitializeCommonTextures()
{
// Initialize font
auto fontName = L"Textures/Font.spritefont";
if (!std::filesystem::exists(fontName))
throw std::runtime_error("Font not found, path " + TEN::Utils::ToString(fontName) + " is missing.");
else
m_gameFont = std::make_unique<SpriteFont>(m_device.Get(), L"Textures/Font.spritefont");
// Initialize font.
auto fontPath = GetAssetPath(L"Textures/Font.spritefont");
if (!std::filesystem::exists(fontPath))
throw std::runtime_error("Font not found; path " + TEN::Utils::ToString(fontPath) + " is missing.");
// Initialize common textures
SetTextureOrDefault(m_logo, L"Textures/Logo.png");
SetTextureOrDefault(m_loadingBarBorder, L"Textures/LoadingBarBorder.png");
SetTextureOrDefault(m_loadingBarInner, L"Textures/LoadingBarInner.png");
SetTextureOrDefault(m_whiteTexture, L"Textures/WhiteSprite.png");
m_gameFont = std::make_unique<SpriteFont>(m_device.Get(), fontPath.c_str());
// Initialize common textures.
SetTextureOrDefault(m_logo, GetAssetPath(L"Textures/Logo.png"));
SetTextureOrDefault(m_loadingBarBorder, GetAssetPath(L"Textures/LoadingBarBorder.png"));
SetTextureOrDefault(m_loadingBarInner, GetAssetPath(L"Textures/LoadingBarInner.png"));
SetTextureOrDefault(m_whiteTexture, GetAssetPath(L"Textures/WhiteSprite.png"));
m_whiteSprite.Height = m_whiteTexture.Height;
m_whiteSprite.Width = m_whiteTexture.Width;

View file

@ -22,6 +22,8 @@ public:
virtual ~ScriptInterfaceFlowHandler() = default;
virtual void LoadFlowScript() = 0;
virtual void SetGameDir(const std::string& assetDir) = 0;
virtual std::string GetGameDir() = 0;
virtual int GetNumLevels() const = 0;
virtual char const* GetString(const char* id) const = 0;
virtual bool IsFlyCheatEnabled() const = 0;

View file

@ -11,5 +11,5 @@ public:
static ScriptInterfaceFlowHandler* CreateFlow();
static ScriptInterfaceObjectsHandler* CreateObjectsHandler();
static ScriptInterfaceStringsHandler* CreateStringsHandler();
static void ScriptInterfaceState::Init();
static void ScriptInterfaceState::Init(const std::string& assetsDir);
};

View file

@ -38,10 +38,11 @@ ScriptInterfaceStringsHandler* ScriptInterfaceState::CreateStringsHandler()
return new StringsHandler(&s_solState, s_rootTable);
}
void ScriptInterfaceState::Init()
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);
s_solState.script("package.path=\"Scripts/?.lua\"");
s_solState.script("package.path=\"" + assetsDir + "Scripts/?.lua\"");
s_solState.set_exception_handler(lua_exception_handler);
s_rootTable = sol::table{ s_solState.lua_state(), sol::create };

View file

@ -215,12 +215,22 @@ FlowHandler::~FlowHandler()
delete lev;
}
std::string FlowHandler::GetGameDir()
{
return m_gameDir;
}
void FlowHandler::SetGameDir(const std::string& assetDir)
{
m_gameDir = assetDir;
}
void FlowHandler::SetLanguageNames(sol::as_table_t<std::vector<std::string>> && src)
{
m_languageNames = std::move(src);
}
void FlowHandler::SetStrings(sol::nested<std::unordered_map<std::string, std::vector<std::string>>> && src)
void FlowHandler::SetStrings(sol::nested<std::unordered_map<std::string, std::vector<std::string>>>&& src)
{
m_translationsMap = std::move(src);
}
@ -240,12 +250,12 @@ void FlowHandler::AddLevel(Level const& level)
Levels.push_back(new Level{ level });
}
void FlowHandler::SetIntroImagePath(std::string const& path)
void FlowHandler::SetIntroImagePath(const std::string& path)
{
IntroImagePath = path;
}
void FlowHandler::SetTitleScreenImagePath(std::string const& path)
void FlowHandler::SetTitleScreenImagePath(const std::string& path)
{
TitleScreenImagePath = path;
}
@ -257,9 +267,9 @@ void FlowHandler::SetTotalSecretCount(int secretsNumber)
void FlowHandler::LoadFlowScript()
{
m_handler.ExecuteScript("Scripts/Gameflow.lua");
m_handler.ExecuteScript("Scripts/Strings.lua");
m_handler.ExecuteScript("Scripts/Settings.lua");
m_handler.ExecuteScript(m_gameDir + "Scripts/Gameflow.lua");
m_handler.ExecuteScript(m_gameDir + "Scripts/Strings.lua");
m_handler.ExecuteScript(m_gameDir + "Scripts/Settings.lua");
SetScriptErrorMode(GetSettings()->ErrorMode);
@ -306,21 +316,53 @@ int FlowHandler::GetNumLevels() const
return Levels.size();
}
int FlowHandler::GetLevelNumber(std::string const& fileName)
int FlowHandler::GetLevelNumber(const std::string& fileName)
{
if (fileName.empty())
return -1;
auto lcFilename = TEN::Utils::ToLower(fileName);
auto fileNameWithForwardSlashes = fileName;
std::replace(fileNameWithForwardSlashes.begin(), fileNameWithForwardSlashes.end(), '\\', '/');
for (int i = 0; i < Levels.size(); i++)
auto requestedPath = std::filesystem::path{ fileName };
bool isAbsolute = requestedPath.is_absolute();
if (!isAbsolute)
requestedPath = std::filesystem::path{ GetGameDir() + fileName };
if (std::filesystem::exists(requestedPath))
{
auto level = TEN::Utils::ToLower(this->GetLevel(i)->FileName);
if (level == lcFilename && std::filesystem::exists(fileName))
return i;
auto lcFileName = TEN::Utils::ToLower(fileNameWithForwardSlashes);
if (isAbsolute)
{
for (int i = 0; i < Levels.size(); i++)
{
auto lcFullLevelPathFromFlow = TEN::Utils::ToLower(GetGameDir() + GetLevel(i)->FileName);
std::replace(lcFullLevelPathFromFlow.begin(), lcFullLevelPathFromFlow.end(), '\\', '/');
if (lcFullLevelPathFromFlow == lcFileName)
return i;
}
}
else
{
for (int i = 0; i < Levels.size(); i++)
{
auto lcLevelNameFromFlow = TEN::Utils::ToLower(GetLevel(i)->FileName);
std::replace(lcLevelNameFromFlow.begin(), lcLevelNameFromFlow.end(), '\\', '/');
if (lcLevelNameFromFlow == lcFileName)
return i;
}
}
}
else
{
TENLog("Provided -level arg \"" + fileName + "\" does not exist.");
return -1;
}
TENLog("Specified level filename was not found in script. Level won't be loaded. Please edit level filename in gameflow.lua.");
TENLog("Provided -level arg \"" + fileName + "\" was not found in gameflow.lua.");
return -1;
}

View file

@ -1,4 +1,6 @@
#pragma once
#include <string_view>
#include "LanguageScript.h"
#include "LuaHandler.h"
#include "Logic/LogicHandler.h"
@ -19,6 +21,8 @@ private:
std::map<short, short> m_itemsMap;
std::string m_gameDir;
LuaHandler m_handler;
public:
@ -35,36 +39,38 @@ public:
std::vector<Level*> Levels;
FlowHandler(sol::state* lua, sol::table & parent);
FlowHandler(sol::state* lua, sol::table& parent);
~FlowHandler() override;
void AddLevel(Level const& level);
void LoadFlowScript();
char const* GetString(const char* id) const;
void SetStrings(sol::nested<std::unordered_map<std::string, std::vector<std::string>>> && src);
void SetLanguageNames(sol::as_table_t<std::vector<std::string>> && src);
void SetAnimations(Animations const & src);
void SetSettings(Settings const & src);
Settings* GetSettings();
Level* GetLevel(int id);
Level* GetCurrentLevel();
int GetLevelNumber(std::string const& flieName);
int GetNumLevels() const;
void EndLevel(std::optional<int> nextLevel);
int GetSecretCount() const;
void SetSecretCount(int secretsNum);
void AddSecret(int levelSecretIndex);
void SetIntroImagePath(std::string const& path);
void SetTitleScreenImagePath(std::string const& path);
void SetTotalSecretCount(int secretsNumber);
bool IsFlyCheatEnabled() const;
void EnableFlyCheat(bool flyCheat);
bool IsMassPickupEnabled() const;
void EnableMassPickup(bool massPickup);
bool IsLaraInTitleEnabled() const;
void EnableLaraInTitle(bool laraInTitle);
bool IsLevelSelectEnabled() const;
void EnableLevelSelect(bool laraInTitle);
std::string GetGameDir() override;
void SetGameDir(const std::string& assetDir) override;
void AddLevel(Level const& level);
void LoadFlowScript();
char const* GetString(const char* id) const;
void SetStrings(sol::nested<std::unordered_map<std::string, std::vector<std::string>>>&& src);
void SetLanguageNames(sol::as_table_t<std::vector<std::string>>&& src);
void SetAnimations(const Animations& src);
void SetSettings(const Settings& src);
Settings* GetSettings();
Level* GetLevel(int id);
Level* GetCurrentLevel();
int GetLevelNumber(const std::string& flieName);
int GetNumLevels() const;
void EndLevel(std::optional<int> nextLevel);
int GetSecretCount() const;
void SetSecretCount(int secretsNum);
void AddSecret(int levelSecretIndex);
void SetIntroImagePath(const std::string& path);
void SetTitleScreenImagePath(const std::string& path);
void SetTotalSecretCount(int secretsNumber);
bool IsFlyCheatEnabled() const;
void EnableFlyCheat(bool flyCheat);
bool IsMassPickupEnabled() const;
void EnableMassPickup(bool massPickup);
bool IsLaraInTitleEnabled() const;
void EnableLaraInTitle(bool laraInTitle);
bool IsLevelSelectEnabled() const;
void EnableLevelSelect(bool laraInTitle);
bool HasCrawlExtended() const override { return Anims.HasCrawlExtended; }
bool HasCrouchRoll() const override { return Anims.HasCrouchRoll; }

View file

@ -37,9 +37,15 @@ int SecretSoundIndex = 5;
constexpr int LegacyLoopingTrackMin = 98;
constexpr int LegacyLoopingTrackMax = 111;
static std::string FullAudioDir;
static int GlobalMusicVolume;
static int GlobalFXVolume;
void AddGameDirToAudioPath(const std::string& gameDir)
{
FullAudioDir = gameDir + TRACKS_PATH;
}
void SetVolumeMusic(int vol)
{
GlobalMusicVolume = vol;
@ -338,7 +344,7 @@ void FreeSamples()
void EnumerateLegacyTracks()
{
auto dir = std::filesystem::path(TRACKS_PATH);
auto dir = std::filesystem::path{ FullAudioDir };
if (std::filesystem::exists(dir))
{
try {
@ -408,13 +414,13 @@ void PlaySoundTrack(std::string track, SoundTrackType mode, QWORD position)
break;
}
auto fullTrackName = TRACKS_PATH + track + ".ogg";
auto fullTrackName = FullAudioDir + track + ".ogg";
if (!std::filesystem::exists(fullTrackName))
{
fullTrackName = TRACKS_PATH + track + ".mp3";
fullTrackName = FullAudioDir + track + ".mp3";
if (!std::filesystem::exists(fullTrackName))
{
fullTrackName = TRACKS_PATH + track + ".wav";
fullTrackName = FullAudioDir + track + ".wav";
if (!std::filesystem::exists(fullTrackName))
{
TENLog("No soundtrack files with name '" + track + "' were found", LogLevel::Warning);

View file

@ -144,6 +144,7 @@ extern std::map<std::string, int> SoundTrackMap;
extern std::unordered_map<int, SoundTrackInfo> SoundTracks;
extern int SecretSoundIndex;
void AddGameDirToAudioPath(const std::string& gameDir);
bool SoundEffect(int effectID, Pose* position, SoundEnvironment condition = SoundEnvironment::Land, float pitchMultiplier = 1.0f, float gainMultiplier = 1.0f);
void StopSoundEffect(short effectID);
bool LoadSample(char *buffer, int compSize, int uncompSize, int currentIndex);

View file

@ -1031,23 +1031,26 @@ unsigned int _stdcall LoadLevel(void* data)
auto* level = g_GameFlow->GetLevel(levelIndex);
TENLog("Loading level file: " + level->FileName, LogLevel::Info);
auto assetDir = g_GameFlow->GetGameDir();
auto levelPath = assetDir + level->FileName;
TENLog("Loading level file: " + levelPath, LogLevel::Info);
LevelDataPtr = nullptr;
FILE* filePtr = nullptr;
char* dataPtr = nullptr;
g_Renderer.SetLoadingScreen(TEN::Utils::ToWString(level->LoadScreenFileName.c_str()));
auto loadingScreenPath = TEN::Utils::ToWString(assetDir + level->LoadScreenFileName);
g_Renderer.SetLoadingScreen(loadingScreenPath);
SetScreenFadeIn(FADE_SCREEN_SPEED);
g_Renderer.UpdateProgress(0);
try
{
filePtr = FileOpen(level->FileName.c_str());
filePtr = FileOpen(levelPath.c_str());
if (!filePtr)
throw std::exception((std::string("Unable to read level file: ") + level->FileName).c_str());
throw std::exception{ (std::string{ "Unable to read level file: " } + levelPath).c_str() };
char header[4];
unsigned char version[4];

View file

@ -17,6 +17,11 @@ namespace TEN::Utils
return string;
}
std::string ToString(const std::wstring& string)
{
return ToString(string.c_str());
}
std::string ToString(const wchar_t* string)
{
auto converter = std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t>();

View file

@ -5,6 +5,7 @@ namespace TEN::Utils
// String utilities
std::string ToUpper(std::string string);
std::string ToLower(std::string string);
std::string ToString(const std::wstring& string);
std::string ToString(const wchar_t* string);
std::wstring ToWString(const std::string& string);
std::wstring ToWString(const char* string);

View file

@ -36,7 +36,7 @@ bool DebugMode = false;
HWND WindowsHandle;
DWORD MainThreadID;
// Indicates to hybrid graphics systems to prefer the discrete part by default
// Indicates to hybrid graphics systems to prefer discrete part by default.
extern "C"
{
__declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
@ -239,14 +239,15 @@ int main()
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
// Process command line arguments
// Process command line arguments.
bool setup = false;
std::string levelFile = {};
LPWSTR* argv;
int argc;
argv = CommandLineToArgvW(GetCommandLineW(), &argc);
std::string gameDir{};
// Parse command line arguments
// Parse command line arguments.
for (int i = 1; i < argc; i++)
{
if (ArgEquals(argv[i], "setup"))
@ -265,22 +266,33 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
{
SystemNameHash = std::stoul(std::wstring(argv[i + 1]));
}
else if (ArgEquals(argv[i], "gamedir") && argc > (i + 1))
{
gameDir = TEN::Utils::ToString(argv[i + 1]);
// Replace all backslashes with forward slashes.
std::replace(gameDir.begin(), gameDir.end(), '\\', '/');
// Add trailing slash if missing.
if (gameDir.back() != '/')
gameDir += '/';
}
}
LocalFree(argv);
// Hide console window if mode isn't debug
// Hide console window if mode isn't debug.
#ifndef _DEBUG
if (!DebugMode)
ShowWindow(GetConsoleWindow(), 0);
#endif
// Clear Application Structure
// Clear Application Structure.
memset(&App, 0, sizeof(WINAPP));
// Initialize logging
InitTENLog();
// Initialize logging.
InitTENLog(gameDir);
// Indicate version
// Indicate version.
auto ver = GetProductOrFileVersion(false);
auto windowName = (std::string("Starting TombEngine version ") +
std::to_string(ver[0]) + "." +
@ -288,13 +300,16 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
std::to_string(ver[2]));
TENLog(windowName, LogLevel::Info);
// Collect numbered tracks
SaveGame::AddGameDirToSavePath(gameDir);
AddGameDirToAudioPath(gameDir);
// Collect numbered tracks.
EnumerateLegacyTracks();
// Initialize the new scripting system
ScriptInterfaceState::Init();
// Initialize scripting system.
ScriptInterfaceState::Init(gameDir);
// Initialize scripting
// Initialize scripting.
try
{
g_GameFlow = ScriptInterfaceState::CreateFlow();
@ -314,6 +329,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
//should be moved to LogicHandler or vice versa to make this stuff
//less fragile (squidshire, 16/09/22)
g_GameScript->ShortenTENCalls();
g_GameFlow->SetGameDir(gameDir);
g_GameFlow->LoadFlowScript();
}
catch (TENScriptException const& e)
@ -324,16 +340,16 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
return 0;
}
// Disable DPI scaling on Windows 8.1+ systems
// Disable DPI scaling on Windows 8.1+ systems.
DisableDpiAwareness();
// Setup main window
// Set up main window.
INITCOMMONCONTROLSEX commCtrlInit;
commCtrlInit.dwSize = sizeof(INITCOMMONCONTROLSEX);
commCtrlInit.dwICC = ICC_USEREX_CLASSES | ICC_STANDARD_CLASSES;
InitCommonControlsEx(&commCtrlInit);
// Initialize main window
// Initialize main window.
App.hInstance = hInstance;
App.WindowClass.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));
App.WindowClass.lpszMenuName = NULL;
@ -346,17 +362,17 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
App.WindowClass.cbWndExtra = 0;
App.WindowClass.hCursor = LoadCursor(App.hInstance, IDC_ARROW);
// Register main window
// Register main window.
if (!RegisterClass(&App.WindowClass))
{
TENLog("Unable To Register Window Class", LogLevel::Error);
return 0;
}
// Create the renderer and enumerate adapters and video modes
// Create renderer and enumerate adapters and video modes.
g_Renderer.Create();
// Load configuration and optionally show the setup dialog
// Load configuration and optionally show setup dialog.
InitDefaultConfiguration();
if (setup || !LoadConfiguration())
{
@ -369,7 +385,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
LoadConfiguration();
}
// Setup window dimensions
// Set up window dimensions.
RECT Rect;
Rect.left = 0;
Rect.top = 0;
@ -377,13 +393,13 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
Rect.bottom = g_Configuration.Height;
AdjustWindowRect(&Rect, WS_CAPTION, false);
// Make window handle
// Make window handle.
App.WindowHandle = CreateWindowEx(
0,
"TombEngine",
g_GameFlow->GetString(STRING_WINDOW_TITLE),
WS_OVERLAPPED | WS_CAPTION | WS_MINIMIZEBOX,
CW_USEDEFAULT, // TODO: change this to center of screen !!!
CW_USEDEFAULT, // TODO: change this to center of screen!
CW_USEDEFAULT,
Rect.right - Rect.left,
Rect.bottom - Rect.top,
@ -400,7 +416,9 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
return 0;
}
else
{
WindowsHandle = App.WindowHandle;
}
try
{