diff --git a/src/client/Client.cpp b/src/client/Client.cpp index 108121e..71c0848 100644 --- a/src/client/Client.cpp +++ b/src/client/Client.cpp @@ -136,6 +136,24 @@ int32_t InitializeEngineCallback(const void* a1, void* a2) { return 1; } +void SetPaths() { + // SFile::DisableSFileCheckDisk(); + // SFile::EnableDirectAccess(0); + + char buffer[STORM_MAX_PATH] = {0}; + + const char* datadir = CmdLineGetString(CMD_DATA_DIR); + if (*datadir == '\0') { + OsGetExePath(buffer, STORM_MAX_PATH); + datadir = buffer; + } + + SFile::SetBasePath(datadir); + SFile::SetDataPath("Data\\"); + + OsSetCurrentDirectory(datadir); +} + int32_t InitializeGlobal() { // TODO @@ -155,10 +173,11 @@ int32_t InitializeGlobal() { // ClientServices::LoadCDKey(); + SetPaths(); + ConsoleInitializeClientCommand(); - ConsoleInitializeClientCVar("Config.wtf"); - + CVar::Initialize("Config.wtf"); // sub_7663F0(); // v18 = 0; diff --git a/src/console/CVar.cpp b/src/console/CVar.cpp index 3673491..974a78b 100644 --- a/src/console/CVar.cpp +++ b/src/console/CVar.cpp @@ -3,6 +3,8 @@ #include "console/Types.hpp" #include "console/Line.hpp" + +#include #include bool CVar::m_needsSave; @@ -165,6 +167,103 @@ int32_t CVar::Update() { return 1; } +static int32_t s_CreatePathDirectories(const char* szPath) { + return true == OsCreateDirectory(szPath, 1); +} + +int32_t CVar::Load(HOSFILE file) { + char fastData[2048] = {0}; + char line[2048] = {0}; + + auto size = OsGetFileSize(file); + + char* data = nullptr; + + if (0x1fff < size) { + data = SMemAlloc(size + 1, __FILE__, __LINE__, 0); + } else { + data = fastData; + } + + auto grown = 0x1FFF >= size; + + int32_t result = 0; + size_t bytesRead = 0; + + if (OsReadFile(file, data, size, &bytesRead) == 0) { + result = 0; + } else { + data[size] = '\0'; + auto curr = data; + + // Skip over UTF-8 byte order mark + if ((((data != nullptr) && (2 < bytesRead)) && (data[0] == 0xef)) && ((data[1] == 0xbb && (data[2] == 0xbf)))) { + curr = data + 3; + } + + do { + SStrTokenize(&curr, line, 0x800, "\r\n", 0); + + // Do not execute commands other than "set ..." + if (SStrCmpI(line, "SET ", 4) == 0) { + // Execute without adding to history + ConsoleCommandExecute(line, 0); + } + + result = 1; + } while ((curr != nullptr) && (*curr != '\0')) + } + + if (grown) { + SMemFree(data, __FILE__, __LINE__, 0); + } + + return result; +} + +int32_t CVar::Load(const char* filename) { + char path[STORM_MAX_PATH] = {0}; + + auto file = OsCreateFile(filename, OS_GENERIC_READ, 0, OS_CREATE_NEW | OS_CREATE_ALWAYS, OS_FILE_ATTRIBUTE_NORMAL, 0x3f3f3f3f); + + if (file == HOSFILE_INVALID) { + SStrPrintf(path, STORM_MAX_PATH, "WTF\\%s", filename); + file = OsCreateFile(filename, OS_GENERIC_READ, 0, OS_CREATE_NEW | OS_CREATE_ALWAYS, OS_FILE_ATTRIBUTE_NORMAL, 0x3f3f3f3f); + if (file == HOSFILE_INVALID) { + return 0; + } + } + + auto result = CVar::Load(file); + + OsCloseFile(file); + + return result; +} + +void CVar::Initialize(const char* filename) { + STORM_ASSERT(filename); + s_filename = filename; + + // Get data path + char path[STORM_MAX_PATH] = {0}; + SFile::GetBasePath(path, STORM_MAX_PATH); + SStrPrintf(path, STORM_MAX_PATH, "%s%s\\", path, "WTF"); + + s_CreatePathDirectories(path); + + static ConsoleCommandList baseCommands[] = { + { "set", SetCommandHandler, "Set the value of a CVar" }, + { "cvar_reset", CvarResetCommandHandler, "Set the value of a CVar to it's startup value" }, + { "cvar_default", CvarDefaultCommandHandler, "Set the value of a CVar to it's coded default value" }, + { "cvarlist", CvarListCommandHandler, "List cvars" } + }; + + CONSOLE_REGISTER_LIST(DEFAULT, baseCommands); + + CVar::Load(s_filename); +} + int32_t CvarCommandHandler(const char* command, const char* arguments) { auto cvar = CVar::Lookup(command); STORM_ASSERT(cvar); diff --git a/src/console/CVar.hpp b/src/console/CVar.hpp index 5cafccd..1bada15 100644 --- a/src/console/CVar.hpp +++ b/src/console/CVar.hpp @@ -4,6 +4,7 @@ #include #include #include +#include class CVar : public TSHashObject { public: @@ -14,6 +15,7 @@ class CVar : public TSHashObject { // Static functions static CVar* Lookup(const char* name); static CVar* Register(const char*, const char*, uint32_t, const char*, bool (*)(CVar*, const char*, const char*, void*), uint32_t, bool, void*, bool); + static void Initialize(const char* filename); // Member variables uint32_t m_category = 0; @@ -33,6 +35,8 @@ class CVar : public TSHashObject { CVar(); int32_t GetInt(); const char* GetString(void); + int32_t Load(const char* filename); + int32_t Load(HOSFILE fileHandle); void InternalSet(const char*, bool, bool, bool, bool); bool Set(const char*, bool, bool, bool, bool); int32_t Update(); diff --git a/src/util/SFile.cpp b/src/util/SFile.cpp index 9aafa45..2ccc464 100644 --- a/src/util/SFile.cpp +++ b/src/util/SFile.cpp @@ -4,6 +4,9 @@ #include #include +static char s_basepath[STORM_MAX_PATH] = {0}; +static char s_datapath[STORM_MAX_PATH] = {0}; + // TODO Proper implementation int32_t SFile::Close(SFile* file) { delete file->m_filename; @@ -125,3 +128,42 @@ int32_t SFile::Unload(void* ptr) { SMemFree(ptr, __FILE__, __LINE__, 0); return 1; } + +int32_t SFile::SetBasePath(const char* path) { + SStrCopy(s_basepath, path, STORM_MAX_PATH); + + if (s_basepath != '\0') { + auto len = SStrLen(s_basepath); + if (s_basepath[len-1] != '\\') { + SStrPack(s_basepath, "\\", STORM_MAX_PATH); + } + } + + // TODO + + // SFileSetBasePath(path); + + return 1; +} + +int32_t SFile::SetDataPath(const char* path) { + SStrCopy(s_datapath, path, STORM_MAX_PATH); + + if (s_datapath != '\0') { + auto len = SStrLen(s_datapath); + if (s_basepath[len-1] != '\\') { + SStrPack(s_datapath, "\\", STORM_MAX_PATH); + } + } + + return 1; +} + +int32_t SFile::GetBasePath(char* buffer, size_t bufferchars) { + SStrCopy(buffer, s_basepath, bufferchars); + return 1; +} + +int32_t SFile::GetDataPath(char* buffer, size_t bufferchars) { + SStrCopy(buffer, s_datapath, bufferchars); +} diff --git a/src/util/SFile.hpp b/src/util/SFile.hpp index cce13f6..6dd3508 100644 --- a/src/util/SFile.hpp +++ b/src/util/SFile.hpp @@ -21,6 +21,10 @@ class SFile { static int32_t OpenEx(SArchive*, const char*, uint32_t, SFile**); static int32_t Read(SFile*, void*, size_t, size_t*, SOVERLAPPED*, TASYNCPARAMBLOCK*); static int32_t Unload(void*); + static int32_t SetBasePath(const char* path); + static int32_t SetDataPath(const char* path); + static int32_t GetBasePath(char* path, size_t capacity); + static int32_t GetDataPath(char* path, size_t capacity); // Member variables const char* m_filename;