From 9f01ff0ea70d3ce4ccc35a1b8291f2cf14dbe28d Mon Sep 17 00:00:00 2001 From: Kawe Mazidjatari <48657826+Mauler125@users.noreply.github.com> Date: Wed, 17 Apr 2024 20:49:22 +0200 Subject: [PATCH] Launcher: surface and launcher code overhaul - SDK Launcher is now a proper GUI app (no longer defaults to terminal, but can of course still be used in the terminal). - Set uniform font on all controls (GetStockObject sometimes returns fonts that isn't currently supported on the UI layout causing text to clip; we don't show in other languages or character encodings so we should just default to Microsoft Sans Serif). - Make anchors uniform for all controls (resize not yet supported). - Don't attempt to send commands to game instances if command string is null or empty. - Clamp surface console list size to window size. - Remove surface console logger boilerplate (surface logging is now a dedicated function). - Use actual SDK logging system for console prints/warnings/errors. - Fixed bug where the use of a shared stack buffer caused truncated parts of the file name to end up in the command line text. --- src/sdklauncher/CMakeLists.txt | 21 ++++ src/sdklauncher/basepanel.cpp | 120 +++++++++++++++-------- src/sdklauncher/basepanel.h | 6 +- src/sdklauncher/sdklauncher.cpp | 166 +++++++++++++++++++++----------- src/sdklauncher/sdklauncher.h | 34 ++----- 5 files changed, 226 insertions(+), 121 deletions(-) diff --git a/src/sdklauncher/CMakeLists.txt b/src/sdklauncher/CMakeLists.txt index be513530..624779da 100644 --- a/src/sdklauncher/CMakeLists.txt +++ b/src/sdklauncher/CMakeLists.txt @@ -3,7 +3,26 @@ add_module( "exe" "sdklauncher" "" ${FOLDER_CONTEXT} TRUE TRUE ) start_sources() +add_sources( SOURCE_GROUP "Foundation" + "${ENGINE_SOURCE_DIR}/tier0/plat_time.cpp" + "${ENGINE_SOURCE_DIR}/public/tier0/platform.h" +) + add_sources( SOURCE_GROUP "Core" + "${ENGINE_SOURCE_DIR}/core/logger.cpp" + "${ENGINE_SOURCE_DIR}/core/logger.h" + "${ENGINE_SOURCE_DIR}/core/logdef.cpp" + "${ENGINE_SOURCE_DIR}/core/logdef.h" + "${ENGINE_SOURCE_DIR}/core/termutil.cpp" + "${ENGINE_SOURCE_DIR}/core/termutil.h" +) + +add_sources( SOURCE_GROUP "Windows" + "${ENGINE_SOURCE_DIR}/windows/console.cpp" + "${ENGINE_SOURCE_DIR}/windows/console.h" +) + +add_sources( SOURCE_GROUP "App" "sdklauncher.cpp" "sdklauncher.h" "sdklauncher_const.h" @@ -29,11 +48,13 @@ set_target_properties( ${PROJECT_NAME} PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY "$(ProjectDir)../../../${BUILD_OUTPUT_DIR}/" ) target_compile_definitions( ${PROJECT_NAME} PRIVATE + "_TOOLS" "SDKLAUNCHER" ) target_precompile_headers( ${PROJECT_NAME} PRIVATE "sdklauncher_pch.h" ) +target_link_options( ${PROJECT_NAME} PRIVATE "/SUBSYSTEM:WINDOWS" ) target_link_libraries( ${PROJECT_NAME} PRIVATE "tier0" "tier1" diff --git a/src/sdklauncher/basepanel.cpp b/src/sdklauncher/basepanel.cpp index e145a917..60498406 100644 --- a/src/sdklauncher/basepanel.cpp +++ b/src/sdklauncher/basepanel.cpp @@ -11,6 +11,29 @@ extern CFileSystem_Stdio* FileSystem(); +//----------------------------------------------------------------------------- +// Purpose: creates a font by name +//----------------------------------------------------------------------------- +HFONT CreateFontByName(const char* const name, const int size) +{ + return CreateFont( + size, // Height of font + 0, // Width of font + 0, // Angle of escapement + 0, // Orientation angle + FW_NORMAL, // Font weight + FALSE, // Italic + FALSE, // Underline + FALSE, // Strikeout + DEFAULT_CHARSET, // Character set identifier + OUT_DEFAULT_PRECIS, // Output precision + CLIP_DEFAULT_PRECIS, // Clipping precision + DEFAULT_QUALITY, // Output quality + DEFAULT_PITCH | FF_DONTCARE, // Pitch and family + TEXT(name) // Font name + ); +} + //----------------------------------------------------------------------------- // Purpose: creates the surface layout //----------------------------------------------------------------------------- @@ -20,6 +43,9 @@ void CSurface::Init() const INT WindowX = 800; const INT WindowY = 353; + const HFONT font = (HFONT)CreateFontByName("Microsoft Sans Serif", -11); + this->SetFont(new Drawing::Font(this->_Handle, font, true)); + this->SuspendLayout(); this->SetAutoScaleDimensions({ 6, 13 }); this->SetAutoScaleMode(Forms::AutoScaleMode::Font); @@ -141,7 +167,7 @@ void CSurface::Init() this->m_PlaylistFileLabel->SetLocation({ 311, 32 }); this->m_PlaylistFileLabel->SetTabIndex(0); this->m_PlaylistFileLabel->SetText("Playlists file"); - this->m_PlaylistFileLabel->SetAnchor(Forms::AnchorStyles::Bottom | Forms::AnchorStyles::Left); + this->m_PlaylistFileLabel->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left); this->m_GameGroupExt->AddControl(this->m_PlaylistFileLabel); // ######################################################################## @@ -423,7 +449,7 @@ void CSurface::Init() this->m_WidthTextBox->SetTabIndex(0); this->m_WidthTextBox->SetReadOnly(false); this->m_WidthTextBox->SetText(""); - this->m_WidthTextBox->SetAnchor(Forms::AnchorStyles::Bottom | Forms::AnchorStyles::Right); + this->m_WidthTextBox->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left); this->m_EngineVideoGroup->AddControl(this->m_WidthTextBox); this->m_HeightTextBox = new UIX::UIXTextBox(); @@ -432,7 +458,7 @@ void CSurface::Init() this->m_HeightTextBox->SetTabIndex(0); this->m_HeightTextBox->SetReadOnly(false); this->m_HeightTextBox->SetText(""); - this->m_HeightTextBox->SetAnchor(Forms::AnchorStyles::Bottom | Forms::AnchorStyles::Right); + this->m_HeightTextBox->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left); this->m_EngineVideoGroup->AddControl(this->m_HeightTextBox); this->m_ResolutionLabel = new UIX::UIXLabel(); @@ -452,7 +478,7 @@ void CSurface::Init() this->m_ConsoleGroup->SetLocation({ 359, 160 }); this->m_ConsoleGroup->SetTabIndex(0); this->m_ConsoleGroup->SetText("Console"); - this->m_ConsoleGroup->SetAnchor(Forms::AnchorStyles::Bottom | Forms::AnchorStyles::Left | Forms::AnchorStyles::Right); + this->m_ConsoleGroup->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left); this->AddControl(this->m_ConsoleGroup); this->m_ConsoleGroupExt = new UIX::UIXGroupBox(); @@ -460,7 +486,7 @@ void CSurface::Init() this->m_ConsoleGroupExt->SetLocation({ 359, 174 }); this->m_ConsoleGroupExt->SetTabIndex(0); this->m_ConsoleGroupExt->SetText(""); - this->m_ConsoleGroupExt->SetAnchor(Forms::AnchorStyles::Bottom | Forms::AnchorStyles::Left | Forms::AnchorStyles::Right); + this->m_ConsoleGroupExt->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left); this->AddControl(this->m_ConsoleGroupExt); this->m_ConsoleListView = new UIX::UIXListView(); @@ -468,7 +494,7 @@ void CSurface::Init() this->m_ConsoleListView->SetLocation({ 1, -23 }); // HACK: hide columns this->m_ConsoleListView->SetTabIndex(0); this->m_ConsoleListView->SetBackColor(Drawing::Color(29, 33, 37)); - this->m_ConsoleListView->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Bottom | Forms::AnchorStyles::Left | Forms::AnchorStyles::Right); + this->m_ConsoleListView->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left); this->m_ConsoleListView->SetView(Forms::View::Details); this->m_ConsoleListView->SetVirtualMode(true); this->m_ConsoleListView->SetFullRowSelect(true); @@ -484,7 +510,7 @@ void CSurface::Init() this->m_ConsoleCommandTextBox->SetTabIndex(0); this->m_ConsoleCommandTextBox->SetReadOnly(false); this->m_ConsoleCommandTextBox->SetText(""); - this->m_ConsoleCommandTextBox->SetAnchor(Forms::AnchorStyles::Bottom | Forms::AnchorStyles::Left); + this->m_ConsoleCommandTextBox->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left); this->m_ConsoleGroupExt->AddControl(this->m_ConsoleCommandTextBox); this->m_ConsoleSendCommand = new UIX::UIXButton(); @@ -493,7 +519,7 @@ void CSurface::Init() this->m_ConsoleSendCommand->SetTabIndex(0); this->m_ConsoleSendCommand->SetText("Send"); this->m_ConsoleSendCommand->SetBackColor(Drawing::Color(3, 102, 214)); - this->m_ConsoleSendCommand->SetAnchor(Forms::AnchorStyles::None); + this->m_ConsoleSendCommand->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left); this->m_ConsoleSendCommand->Click += &ForwardCommandToGame; this->m_ConsoleGroupExt->AddControl(this->m_ConsoleSendCommand); @@ -681,10 +707,7 @@ void CSurface::OnClose(const std::unique_ptr& /*pEventArgs //----------------------------------------------------------------------------- void CSurface::CleanSDK(Forms::Control* pSender) { - CSurface* pSurface = reinterpret_cast(pSender->FindForm()); - pSurface->m_LogList.push_back(LogList_t(spdlog::level::info, "Running cleaner for SDK installation\n")); - pSurface->m_ConsoleListView->SetVirtualListSize(static_cast(pSurface->m_LogList.size())); - + Msg(eDLL_T::COMMON, "Running cleaner for SDK installation\n"); std::system("bin\\clean_sdk.bat"); } @@ -694,10 +717,7 @@ void CSurface::CleanSDK(Forms::Control* pSender) //----------------------------------------------------------------------------- void CSurface::UpdateSDK(Forms::Control* pSender) { - CSurface* pSurface = reinterpret_cast(pSender->FindForm()); - pSurface->m_LogList.push_back(LogList_t(spdlog::level::info, "Running updater for SDK installation\n")); - pSurface->m_ConsoleListView->SetVirtualListSize(static_cast(pSurface->m_LogList.size())); - + Msg(eDLL_T::COMMON, "Running updater for SDK installation\n"); std::system("bin\\update_sdk.bat"); } @@ -708,19 +728,15 @@ void CSurface::UpdateSDK(Forms::Control* pSender) void CSurface::LaunchGame(Forms::Control* pSender) { CSurface* pSurface = reinterpret_cast(pSender->FindForm()); - - pSurface->m_LogList.clear(); // Clear console. - pSurface->m_ConsoleListView->SetVirtualListSize(0); - pSurface->m_ConsoleListView->Refresh(); - string svParameter; + pSurface->AppendParameterInternal(svParameter, "-launcher"); - eLaunchMode launchMode = g_Launcher.BuildParameter(svParameter); + eLaunchMode launchMode = SDKLauncher()->BuildParameter(svParameter); uint64_t nProcessorAffinity = pSurface->GetProcessorAffinity(svParameter); - if (g_Launcher.CreateLaunchContext(launchMode, nProcessorAffinity, svParameter.c_str(), "startup_launcher.cfg")) - g_Launcher.LaunchProcess(); + if (SDKLauncher()->CreateLaunchContext(launchMode, nProcessorAffinity, svParameter.c_str(), "startup_launcher.cfg")) + SDKLauncher()->LaunchProcess(); } //----------------------------------------------------------------------------- @@ -819,6 +835,26 @@ void CSurface::ReloadPlaylists(Forms::Control* pSender) pSurface->ParsePlaylists(); } +//----------------------------------------------------------------------------- +// Purpose: adds a log to the surface console +// Input : type - +// Input : *pszText - +//----------------------------------------------------------------------------- +void CSurface::AddLog(const LogType_t type, const char* const pszText) +{ + m_LogList.push_back(LogList_t(type, pszText)); + + // Clamp the log list size, as we cannot fit more elements than + // 8 in the console window. + while (m_LogList.size() > 8) + { + m_LogList.erase(m_LogList.begin()); + } + + m_ConsoleListView->SetVirtualListSize(static_cast(m_LogList.size())); + m_ConsoleListView->Refresh(); +} + //----------------------------------------------------------------------------- // Purpose: copies selected virtual items to clipboard // Input : &pEventArgs - @@ -859,30 +895,34 @@ void CSurface::GetVirtualItem(const std::unique_ptrSubItemIndex) { case 0: - pEventArgs->Style.ForeColor = cColor[pSurface->m_LogList[pEventArgs->ItemIndex].m_nLevel]; - pEventArgs->Text = svLevel[pSurface->m_LogList[pEventArgs->ItemIndex].m_nLevel]; + pEventArgs->Style.ForeColor = cColor[(int)pSurface->m_LogList[pEventArgs->ItemIndex].m_nLevel]; + pEventArgs->Text = svLevel[(int)pSurface->m_LogList[pEventArgs->ItemIndex].m_nLevel]; break; case 1: pEventArgs->Text = pSurface->m_LogList[pEventArgs->ItemIndex].m_svText; @@ -905,7 +945,11 @@ void CSurface::ForwardCommandToGame(Forms::Control* pSender) if (vecHandles.empty()) return; - const string kzCommand = pSurface->m_ConsoleCommandTextBox->Text().ToCString(); + const String kzCommand = pSurface->m_ConsoleCommandTextBox->Text(); + + if (String::IsNullOrEmpty(kzCommand)) + return; + bool bSuccess = false; for (const HWND hWindow : vecHandles) @@ -913,7 +957,7 @@ void CSurface::ForwardCommandToGame(Forms::Control* pSender) char szWindowName[256]; GetWindowTextA(hWindow, szWindowName, 256); - COPYDATASTRUCT cData = { 0, (DWORD)(std::min)(kzCommand.size(), (size_t)259) + 1, (void*)kzCommand.c_str() }; + COPYDATASTRUCT cData = { 0, (DWORD)(std::min)(kzCommand.Length(), (uint32_t)259) + 1, (void*)kzCommand.ToCString() }; bool bProcessingMessage = SendMessageA(hWindow, WM_COPYDATA, NULL, (LPARAM)&cData); // WM_COPYDATA will only return 0 or 1, that's why we use a boolean. if (bProcessingMessage && !bSuccess) { @@ -923,9 +967,7 @@ void CSurface::ForwardCommandToGame(Forms::Control* pSender) if (bSuccess) // At least one game instance received the command. { - pSurface->m_LogList.push_back(LogList_t((spdlog::level::level_enum)2, kzCommand)); - pSurface->m_ConsoleListView->SetVirtualListSize(static_cast(pSurface->m_LogList.size())); - pSurface->m_ConsoleListView->Refresh(); + pSurface->AddLog(LogType_t::LOG_INFO, Format("Sent command: %s\n", kzCommand.ToCString()).c_str()); pSurface->m_ConsoleCommandTextBox->SetText(""); } } diff --git a/src/sdklauncher/basepanel.h b/src/sdklauncher/basepanel.h index d1705e33..cc3036c6 100644 --- a/src/sdklauncher/basepanel.h +++ b/src/sdklauncher/basepanel.h @@ -2,13 +2,13 @@ struct LogList_t { - LogList_t(const spdlog::level::level_enum nLevel, const string& svText) + LogList_t(const LogType_t nLevel, const string& svText) { m_nLevel = nLevel; m_svText = svText; } - spdlog::level::level_enum m_nLevel; + LogType_t m_nLevel; string m_svText; }; @@ -23,6 +23,8 @@ public: std::vector m_LogList; void Init(); + void AddLog(const LogType_t type, const char* const pszText); + eLaunchMode BuildParameter(string& svParameter); private: diff --git a/src/sdklauncher/sdklauncher.cpp b/src/sdklauncher/sdklauncher.cpp index 23b09dc7..13b07962 100644 --- a/src/sdklauncher/sdklauncher.cpp +++ b/src/sdklauncher/sdklauncher.cpp @@ -3,16 +3,21 @@ // Purpose: SDK launcher implementation. // //=============================================================================// +#include "core/logger.h" +#include "core/logdef.h" +#include "tier0/cpu.h" #include "tier0/binstream.h" #include "tier1/fmtstr.h" #include "basepanel.h" #include "sdklauncher.h" +#include "windows/console.h" #include "vstdlib/keyvaluessystem.h" #include "filesystem/filesystem_std.h" static CKeyValuesSystem s_KeyValuesSystem; -static CFileSystem_Stdio g_FullFileSystem; +static CFileSystem_Stdio s_FullFileSystem; +static CLauncher s_Launcher; /////////////////////////////////////////////////////////////////////////////// // Purpose: keyvalues singleton accessor @@ -27,7 +32,28 @@ IKeyValuesSystem* KeyValuesSystem() /////////////////////////////////////////////////////////////////////////////// CFileSystem_Stdio* FileSystem() { - return &g_FullFileSystem; + return &s_FullFileSystem; +} + +/////////////////////////////////////////////////////////////////////////////// +// Purpose: launcher singleton accessor. +/////////////////////////////////////////////////////////////////////////////// +CLauncher* SDKLauncher() +{ + return &s_Launcher; +} + +/////////////////////////////////////////////////////////////////////////////// +// Purpose: launcher logger sink +/////////////////////////////////////////////////////////////////////////////// +void LauncherLoggerSink(LogType_t logType, LogLevel_t logLevel, eDLL_T context, + const char* pszLogger, const char* pszFormat, va_list args, + const UINT exitCode /*= NO_ERROR*/, const char* pszUptimeOverride /*= nullptr*/) +{ + const string buffer = FormatV(pszFormat, args); + + SDKLauncher()->AddLog(logType, buffer.c_str()); + EngineLoggerSink(logType, logLevel, context, pszLogger, pszFormat, args, exitCode, pszUptimeOverride); } /////////////////////////////////////////////////////////////////////////////// @@ -38,30 +64,42 @@ void CLauncher::RunSurface() Forms::Application::EnableVisualStyles(); UIX::UIXTheme::InitializeRenderer(new Themes::KoreTheme()); - m_Surface.Init(); - Forms::Application::Run(&g_Launcher.m_Surface, false); + m_pSurface = new CSurface(); + m_pSurface->Init(); + + Forms::Application::Run(m_pSurface, true); UIX::UIXTheme::ShutdownRenderer(); } /////////////////////////////////////////////////////////////////////////////// -// Purpose: initializes the console (development only) +// Purpose: initializes the launcher /////////////////////////////////////////////////////////////////////////////// -void CLauncher::InitConsole() +void CLauncher::Init() { - AllocConsole(); - freopen("conin$", "r", stdin); - freopen("conout$", "w", stdout); - freopen("conout$", "w", stderr); + g_CoreMsgVCallback = &LauncherLoggerSink; // Setup logger callback sink. + + // Init time. + Plat_FloatTime(); + SpdLog_Init(true); } /////////////////////////////////////////////////////////////////////////////// -// Purpose: initializes the logger +// Purpose: de-initializes the launcher /////////////////////////////////////////////////////////////////////////////// -void CLauncher::InitLogger() +void CLauncher::Shutdown() { - m_pLogger->set_pattern("[%^%l%$] %v"); - m_pLogger->set_level(spdlog::level::trace); - spdlog::set_default_logger(m_pLogger); // Set as default. + SpdLog_Shutdown(); +} + +/////////////////////////////////////////////////////////////////////////////// +// Purpose: adds a log to the surface console +/////////////////////////////////////////////////////////////////////////////// +void CLauncher::AddLog(const LogType_t level, const char* szText) +{ + if (m_pSurface) + { + m_pSurface->AddLog(level, szText); + } } /////////////////////////////////////////////////////////////////////////////// @@ -120,13 +158,13 @@ int CLauncher::HandleCommandLine(int argc, char* argv[]) /////////////////////////////////////////////////////////////////////////////// int CLauncher::HandleInput() { - std::cout << "----------------------------------------------------------------------------------------------------------------------" << std::endl; - AddLog(spdlog::level::level_enum::warn, "The '%s' options are for development purposes; use the '%s' options for default usage.\n", "DEV", "PROD"); - std::cout << "----------------------------------------------------------------------------------------------------------------------" << std::endl; - AddLog(spdlog::level::level_enum::info, "%-6s ('0' = %s | '1' = %s).\n", "GAME", "DEV", "PROD"); - AddLog(spdlog::level::level_enum::info, "%-6s ('2' = %s | '3' = %s).\n", "SERVER", "DEV", "PROD"); - AddLog(spdlog::level::level_enum::info, "%-6s ('4' = %s | '5' = %s).\n", "CLIENT", "DEV", "PROD"); - std::cout << "----------------------------------------------------------------------------------------------------------------------" << std::endl; + Msg(eDLL_T::NONE, "--------------------------------------------------------------------------------------------------------------\n"); + Warning(eDLL_T::COMMON, "The '%s' options are for development purposes; use the '%s' options for default usage.\n", "DEV", "PROD"); + Msg(eDLL_T::NONE, "--------------------------------------------------------------------------------------------------------------\n"); + Msg(eDLL_T::COMMON, "%-6s ('0' = %s | '1' = %s).\n", "GAME", "DEV", "PROD"); + Msg(eDLL_T::COMMON, "%-6s ('2' = %s | '3' = %s).\n", "SERVER", "DEV", "PROD"); + Msg(eDLL_T::COMMON, "%-6s ('4' = %s | '5' = %s).\n", "CLIENT", "DEV", "PROD"); + Msg(eDLL_T::NONE, "--------------------------------------------------------------------------------------------------------------\n"); std::cout << "User input: "; std::string input; @@ -142,17 +180,24 @@ int CLauncher::HandleInput() } else { - AddLog(spdlog::level::level_enum::err, "Invalid mode (range 0-5).\n"); + Error(eDLL_T::COMMON, 0, "Invalid mode (range 0-5).\n"); + Sleep(2500); + return EXIT_FAILURE; } } catch (const std::exception& e) { - AddLog(spdlog::level::level_enum::err, "SDK Launcher only takes numerical input (error = %s).\n", e.what()); + Error(eDLL_T::COMMON, 0, "SDK Launcher only takes numerical input (error = %s).\n", e.what()); + Sleep(2500); + return EXIT_FAILURE; } } - AddLog(spdlog::level::level_enum::err, "SDK Launcher requires numerical input.\n"); + + Error(eDLL_T::COMMON, 0, "SDK Launcher requires numerical input.\n"); + Sleep(2500); + return EXIT_FAILURE; } @@ -229,14 +274,13 @@ bool CLauncher::CreateLaunchContext(eLaunchMode lMode, uint64_t nProcessorAffini } default: { - AddLog(spdlog::level::level_enum::err, "No launch mode specified.\n"); + Error(eDLL_T::COMMON, 0, "No launch mode specified.\n"); return false; } } SetupLaunchContext(szConfig, szGameDLL, szCommandLine); - AddLog(spdlog::level::level_enum::info, "*** LAUNCHING %s [%s] ***\n", - szContext, szLevel); + Msg(eDLL_T::COMMON, "*** LAUNCHING %s [%s] ***\n", szContext, szLevel); return true; } @@ -251,20 +295,19 @@ bool CLauncher::CreateLaunchContext(eLaunchMode lMode, uint64_t nProcessorAffini void CLauncher::SetupLaunchContext(const char* szConfig, const char* szGameDll, const char* szCommandLine) { CIOStream cfgFile; + + CFmtStrN<1024> cfgFileName; CFmtStrMax commandLine; if (szConfig && szConfig[0]) { - commandLine.Format(GAME_CFG_PATH"%s", szConfig); + cfgFileName.Format(GAME_CFG_PATH"%s", szConfig); - if (cfgFile.Open(commandLine.String(), CIOStream::READ)) + if (cfgFile.Open(cfgFileName.String(), CIOStream::READ)) { - // Reuse the stack string for the actual command line buffer. - commandLine.Clear(); - if (!cfgFile.ReadString(commandLine.Access(), commandLine.GetMaxLength())) { - AddLog(spdlog::level::level_enum::err, "Failed to read file '%s'!\n", szConfig); + Error(eDLL_T::COMMON, 0, "Failed to read file '%s'!\n", szConfig); } else { @@ -273,7 +316,7 @@ void CLauncher::SetupLaunchContext(const char* szConfig, const char* szGameDll, } else // Failed to open config file. { - AddLog(spdlog::level::level_enum::err, "Failed to open file '%s'!\n", szConfig); + Error(eDLL_T::COMMON, 0, "Failed to open file '%s'!\n", szConfig); } } @@ -287,11 +330,11 @@ void CLauncher::SetupLaunchContext(const char* szConfig, const char* szGameDll, /////////////////////////////////////////////////////////////////////////// // Print the file paths and arguments. - std::cout << "----------------------------------------------------------------------------------------------------------------------" << std::endl; - AddLog(spdlog::level::level_enum::debug, "- CWD: %s\n", m_svCurrentDir.c_str()); - AddLog(spdlog::level::level_enum::debug, "- EXE: %s\n", m_svGameDll.c_str()); - AddLog(spdlog::level::level_enum::debug, "- CLI: %s\n", commandLine.String()); - std::cout << "----------------------------------------------------------------------------------------------------------------------" << std::endl; + Msg(eDLL_T::NONE, "--------------------------------------------------------------------------------------------------------------\n"); + Msg(eDLL_T::COMMON, "- CWD: %s\n", m_svCurrentDir.c_str()); + Msg(eDLL_T::COMMON, "- EXE: %s\n", m_svGameDll.c_str()); + Msg(eDLL_T::COMMON, "- CLI: %s\n", commandLine.String()); + Msg(eDLL_T::NONE, "--------------------------------------------------------------------------------------------------------------\n"); } /////////////////////////////////////////////////////////////////////////////// @@ -386,28 +429,39 @@ BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) /////////////////////////////////////////////////////////////////////////////// // EntryPoint. /////////////////////////////////////////////////////////////////////////////// -int main(int argc, char* argv[]/*, char* envp[]*/) +int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw) { - g_Launcher.InitLogger(); - if (argc < 2) + CheckSystemCPUForSSE2(); + if (__argc < 2) { -#ifdef NDEBUG - FreeConsole(); -#endif // NDEBUG - g_Launcher.RunSurface(); +#ifdef _DEBUG + Console_Init(true, true); +#endif // _DEBUG + SDKLauncher()->Init(); + SDKLauncher()->RunSurface(); + SDKLauncher()->Shutdown(); +#ifdef _DEBUG + Console_Shutdown(); +#endif // _DEBUG } else { - int results = g_Launcher.HandleCommandLine(argc, argv); - if (results != -1) - return results; + if (!Console_Init(true)) + return EXIT_FAILURE; - return g_Launcher.HandleInput(); + SDKLauncher()->Init(); + + int cmdRet = SDKLauncher()->HandleCommandLine(__argc, __argv); + + if (cmdRet == -1) + cmdRet = SDKLauncher()->HandleInput(); + + SDKLauncher()->Shutdown(); + + if (!Console_Shutdown()) + return EXIT_FAILURE; + + return cmdRet; } return EXIT_SUCCESS; } - -/////////////////////////////////////////////////////////////////////////////// -// Singleton Launcher. -/////////////////////////////////////////////////////////////////////////////// -CLauncher g_Launcher("win_console"); diff --git a/src/sdklauncher/sdklauncher.h b/src/sdklauncher/sdklauncher.h index b2533855..b27eb700 100644 --- a/src/sdklauncher/sdklauncher.h +++ b/src/sdklauncher/sdklauncher.h @@ -4,9 +4,9 @@ class CLauncher { public: - CLauncher(const char* pszLoggerName) + CLauncher() { - m_pLogger = spdlog::stdout_color_mt(pszLoggerName); + m_pSurface = nullptr; m_ProcessorAffinity = NULL; m_svCurrentDir = fs::current_path().u8string(); } @@ -14,25 +14,12 @@ public: { } - void AddLog(spdlog::level::level_enum nLevel, const char* szFormat, ...) - { - string svBuffer; - va_list args; - va_start(args, szFormat); - svBuffer = FormatV(szFormat, args); - va_end(args); - - m_pLogger->log(nLevel, svBuffer); - m_pLogger->flush(); - - m_Surface.m_LogList.push_back(LogList_t(nLevel, svBuffer)); - m_Surface.ConsoleListView()->SetVirtualListSize(static_cast(m_Surface.m_LogList.size())); - m_Surface.ConsoleListView()->Refresh(); - } - void RunSurface(); - void InitConsole(); - void InitLogger(); + + void Init(); + void Shutdown(); + + void AddLog(const LogType_t level, const char* szText); int HandleCommandLine(int argc, char* argv[]); int HandleInput(); @@ -41,11 +28,10 @@ public: void SetupLaunchContext(const char* szConfig, const char* szGameDll, const char* szCommandLine); bool LaunchProcess() const; - eLaunchMode BuildParameter(string& parameterList) { return m_Surface.BuildParameter(parameterList); } + eLaunchMode BuildParameter(string& parameterList) { return m_pSurface->BuildParameter(parameterList); } private: - CSurface m_Surface; - std::shared_ptr m_pLogger; + CSurface* m_pSurface; uint64_t m_ProcessorAffinity; @@ -56,4 +42,4 @@ private: BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam); -extern CLauncher g_Launcher; +extern CLauncher* SDKLauncher();