From a8f6f1e8ea724042e487ee791cbaae37c5fcdc1f Mon Sep 17 00:00:00 2001 From: nastys <@> Date: Fri, 2 Aug 2019 23:59:08 +0200 Subject: [PATCH] Merge somewhatlurker's changes to the launcher --- .../source/plugins/Launcher/ConfigOption.h | 703 ++++++++++++++ .../source/plugins/Launcher/Launcher.vcxproj | 1 + .../source/plugins/Launcher/framework.h | 211 +++-- source-code/source/plugins/Launcher/ui.h | 874 ++++-------------- source-code/source/plugins/Launcher/ui.resx | 3 + 5 files changed, 1031 insertions(+), 761 deletions(-) create mode 100644 source-code/source/plugins/Launcher/ConfigOption.h diff --git a/source-code/source/plugins/Launcher/ConfigOption.h b/source-code/source/plugins/Launcher/ConfigOption.h new file mode 100644 index 0000000..0b93897 --- /dev/null +++ b/source-code/source/plugins/Launcher/ConfigOption.h @@ -0,0 +1,703 @@ +#pragma once + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +// Windows Header Files +#include +#include +#include +#include + +#include + +using namespace System; +using namespace System::Windows::Forms; + +// Custom function. Works like GetPrivateProfileIntW but returns bool. Can detect a numeric value or string. +bool GetPrivateProfileBoolW(LPCWSTR lpAppName, LPCWSTR lpKeyName, bool default, LPCWSTR lpFileName) +{ + wchar_t buffer[8]; + GetPrivateProfileStringW(lpAppName, lpKeyName, L"", buffer, 8, lpFileName); + //MessageBoxW(NULL, buffer, NULL, 0); + + for (wchar_t& chr : buffer) + chr = towlower(chr); + + bool out; + if ((lstrcmpW(buffer, L"true") == 0) || (lstrcmpW(buffer, L"1") == 0)) + out = true; + else if ((lstrcmpW(buffer, L"false") == 0) || (lstrcmpW(buffer, L"0") == 0)) + out = false; + else + out = default; + + return out; +} + +// resolution class to store and sort the width and height easily +class resolution +{ +public: + unsigned int width; + unsigned int height; + + resolution() + { + width = 0; + height = 0; + } + + resolution(unsigned int width, unsigned int height) + { + resolution::width = width; + resolution::height = height; + } + + bool operator ==(const resolution &res2) + { + return width == res2.width && height == res2.height; + } + + // in comparisons width takes priority because it's usually displayed first + bool operator <(const resolution &res2) + { + if (width == res2.width) + return height < res2.height; + else + return width < res2.width; + } + bool operator >(const resolution &res2) + { + if (width == res2.width) + return height > res2.height; + else + return width > res2.width; + } +}; + + +ref class ComboboxValidation +{ +public: + ComboBox^ cb; + + ComboboxValidation(ComboBox^ combobox) + { + cb = combobox; + } + + System::Void CheckNumberLeave(System::Object^ sender, System::EventArgs^ e) + { + System::String^ text = cb->Text; + + cli::array^ digitsarray = gcnew cli::array{ L'0', L'1', L'2', L'3', L'4', L'5', L'6', L'7', L'8', L'9' }; + System::Collections::Generic::List^ digitslist = gcnew System::Collections::Generic::List(digitsarray); + + if (text->Length <= 0) + return; + + while (text->Length > 0 && text[0] != L'-' && !digitslist->Contains(text[0])) + { + text = text->Remove(0, 1); + } + + if (text->Length <= 1) // can discard up to 1 now because first digit is known good + { + cb->Text = text; + return; + } + + for (int i = 1; i < text->Length; i++) + { + if (!digitslist->Contains(text[i])) + { + text = text->Remove(i, 1); + i--; // negate the upcoming ++ + } + } + + cb->Text = text; + } + + System::Void CheckResolutionLeave(System::Object^ sender, System::EventArgs^ e) + { + System::String^ text = cb->Text; + + cli::array^ digitsarray = gcnew cli::array{ L'0', L'1', L'2', L'3', L'4', L'5', L'6', L'7', L'8', L'9' }; + System::Collections::Generic::List^ digitslist = gcnew System::Collections::Generic::List(digitsarray); + + int numX = 0; + + if (text->Length <= 0) + { + cb->Text = "x"; + return; + } + + while (text->Length > 0 && text[0] != L'x' && !digitslist->Contains(text[0])) + { + text = text->Remove(0, 1); + } + + if (text[0] == L'x') + { + numX++; + } + + if (text->Length <= 1) // can discard up to 1 now because first digit is known good + { + if (numX == 0) // if that digit wasn't an x though, add one + { + text += "x"; + } + cb->Text = text; + return; + } + + for (int i = 1; i < text->Length; i++) + { + if (!digitslist->Contains(text[i]) && !(numX == 0 && text[i] == L'x' && ++numX)) + { + text = text->Remove(i, 1); + i--; // negate the upcoming ++ + } + } + + if (numX == 0) + { + text += "x"; + } + + cb->Text = text; + } + +}; + + +class ConfigOptionBase +{ +public: + LPCWSTR _iniVarName; + LPCWSTR _iniSectionName; + LPCWSTR _iniFilePath; + + LPCWSTR _friendlyName; + LPCWSTR _description; + + System::IntPtr mainControlHandle; + + virtual int AddToPanel(Panel^ panel, unsigned int left, unsigned int top, ToolTip^ tooltip) + { + return 0; + } + + virtual void SaveOption() + { + return; + } +}; + + +class BooleanOption : public ConfigOptionBase +{ +public: + bool _defaultVal; + bool _saveAsString; + + BooleanOption(LPCWSTR iniVarName, LPCWSTR iniSectionName, LPCWSTR iniFilePath, LPCWSTR friendlyName, LPCWSTR description, bool defaultVal, bool saveAsString) + { + _iniVarName = iniVarName; + _iniSectionName = iniSectionName; + _iniFilePath = iniFilePath; + _friendlyName = friendlyName; + _description = description; + _defaultVal = defaultVal; + _saveAsString = saveAsString; + } + + virtual int AddToPanel(Panel^ panel, unsigned int left, unsigned int top, ToolTip^ tooltip) + { + CheckBox^ cb = gcnew CheckBox(); + + cb->Text = gcnew String(_friendlyName); + cb->Checked = GetPrivateProfileBoolW(_iniSectionName, _iniVarName, _defaultVal, _iniFilePath); + cb->Left = left; + cb->Top = top; + cb->AutoSize = true; + cb->FlatStyle = System::Windows::Forms::FlatStyle::Flat; + + tooltip->SetToolTip(cb, gcnew String(_description)); + + panel->Controls->Add(cb); + mainControlHandle = cb->Handle; + return 23; + } + + virtual void SaveOption() + { + bool boolEnabled = ((CheckBox^)CheckBox::FromHandle(mainControlHandle))->Checked; + + if (_saveAsString) + WritePrivateProfileStringW(_iniSectionName, _iniVarName, boolEnabled ? L"true" : L"false", _iniFilePath); + else + WritePrivateProfileStringW(_iniSectionName, _iniVarName, boolEnabled ? L"1" : L"0", _iniFilePath); + } +}; + + +class NumericOption : public ConfigOptionBase +{ +public: + int _defaultVal; + int _minVal; + int _maxVal; + + NumericOption(LPCWSTR iniVarName, LPCWSTR iniSectionName, LPCWSTR iniFilePath, LPCWSTR friendlyName, LPCWSTR description, int defaultVal, int minVal, int maxVal) + { + _iniVarName = iniVarName; + _iniSectionName = iniSectionName; + _iniFilePath = iniFilePath; + _friendlyName = friendlyName; + _description = description; + _defaultVal = defaultVal; + _minVal = minVal; + _maxVal = maxVal; + } + + virtual int AddToPanel(Panel^ panel, unsigned int left, unsigned int top, ToolTip^ tooltip) + { + Label^ label = gcnew Label(); + NumericUpDown^ numberbox = gcnew NumericUpDown(); + + label->Text = gcnew String(_friendlyName); + label->Left = left; + label->Top = top + 3; + label->Width = 100; + label->AutoSize = true; + label->FlatStyle = System::Windows::Forms::FlatStyle::Flat; + + numberbox->Minimum = _minVal; + numberbox->Maximum = _maxVal; + + numberbox->Value = (int)GetPrivateProfileIntW(_iniSectionName, _iniVarName, _defaultVal, _iniFilePath); // cast to int because this returns uint and breaks -1 + // it seems it does read negative values correctly though... but eventually a parser that properly supports negative numbers would be ideal + numberbox->Left = left + 104; + numberbox->Top = top; + numberbox->Width = 90; + numberbox->AutoSize = true; + + tooltip->SetToolTip(label, gcnew String(_description)); + tooltip->SetToolTip(numberbox, gcnew String(_description)); + + panel->Controls->Add(label); + panel->Controls->Add(numberbox); + mainControlHandle = numberbox->Handle; + return 28; + } + + virtual void SaveOption() + { + System::String^ tempSysStr; + std::wstring tempWStr; + + tempSysStr = Convert::ToInt32(((NumericUpDown^)NumericUpDown::FromHandle(mainControlHandle))->Value).ToString(); + tempWStr = msclr::interop::marshal_as(tempSysStr); + WritePrivateProfileStringW(_iniSectionName, _iniVarName, tempWStr.c_str(), _iniFilePath); + } +}; + + +class StringOption : public ConfigOptionBase +{ +public: + LPCWSTR _defaultVal; + bool _useUtf8; + + StringOption(LPCWSTR iniVarName, LPCWSTR iniSectionName, LPCWSTR iniFilePath, LPCWSTR friendlyName, LPCWSTR description, LPCWSTR defaultVal, bool useUtf8) + { + _iniVarName = iniVarName; + _iniSectionName = iniSectionName; + _iniFilePath = iniFilePath; + _friendlyName = friendlyName; + _description = description; + _defaultVal = defaultVal; + _useUtf8 = useUtf8; + } + + virtual int AddToPanel(Panel^ panel, unsigned int left, unsigned int top, ToolTip^ tooltip) + { + Label^ label = gcnew Label(); + TextBox^ textbox = gcnew TextBox(); + + WCHAR stringBuf[256]; + char utf8Buf[256]; + + label->Text = gcnew String(_friendlyName); + label->Left = left; + label->Top = top + 3; + label->Width = 100; + label->AutoSize = true; + label->FlatStyle = System::Windows::Forms::FlatStyle::Flat; + + GetPrivateProfileStringW(_iniSectionName, _iniVarName, _defaultVal, stringBuf, 256, _iniFilePath); + if (_useUtf8 && wcscmp(_defaultVal, stringBuf) != 0) { // don't convert default value + WideCharToMultiByte(CP_ACP, 0, stringBuf, -1, utf8Buf, 256, NULL, NULL); // convert back to the original ANSI as read from file + MultiByteToWideChar(CP_UTF8, 0, utf8Buf, -1, stringBuf, 256); // now use those bytes to convert from UTF8 + } + + textbox->Text = gcnew String(stringBuf); + textbox->Left = left + 104; + textbox->Top = top; + textbox->Width = 90; + textbox->AutoSize = true; + + // disable editing for utf8 mode because the ANSI hack used may not work correctly + if (_useUtf8) { + textbox->Enabled = false; + } + + tooltip->SetToolTip(label, gcnew String(_description)); + tooltip->SetToolTip(textbox, gcnew String(_description)); + + panel->Controls->Add(label); + panel->Controls->Add(textbox); + mainControlHandle = textbox->Handle; + return 28; + } + + virtual void SaveOption() + { + // disable saving for utf8 mode because the ANSI hack used may not work correctly + if (_useUtf8) + return; + + System::String^ tempSysStr; + std::wstring tempWStr; + WCHAR stringBuf[256]; + char utf8Buf[256]; + + tempSysStr = ((TextBox^)TextBox::FromHandle(mainControlHandle))->Text; + tempWStr = msclr::interop::marshal_as(tempSysStr); + tempWStr.copy(stringBuf, 256, 0); + stringBuf[tempWStr.length()] = 0; + + if (_useUtf8) { + WideCharToMultiByte(CP_UTF8, 0, stringBuf, -1, utf8Buf, 256, NULL, NULL); // convert to UTF8 + MultiByteToWideChar(CP_ACP, 0, utf8Buf, -1, stringBuf, 256); // now convert that to wide chars as if it's ANSI so it saves properly after conversion to ANSI by windows + } + + WritePrivateProfileStringW(_iniSectionName, _iniVarName, stringBuf, _iniFilePath); + } +}; + + +class DropdownOption : public ConfigOptionBase +{ +public: + int _defaultVal; + std::vector _valueStrings; + + DropdownOption(LPCWSTR iniVarName, LPCWSTR iniSectionName, LPCWSTR iniFilePath, LPCWSTR friendlyName, LPCWSTR description, int defaultVal, std::vector valueStrings) + { + _iniVarName = iniVarName; + _iniSectionName = iniSectionName; + _iniFilePath = iniFilePath; + _friendlyName = friendlyName; + _description = description; + _defaultVal = defaultVal; + _valueStrings = valueStrings; + } + + virtual int AddToPanel(Panel^ panel, unsigned int left, unsigned int top, ToolTip^ tooltip) + { + Label^ label = gcnew Label(); + ComboBox^ combobox = gcnew ComboBox(); + + label->Text = gcnew String(_friendlyName); + label->Left = left; + label->Top = top + 3; + label->Width = 100; + label->AutoSize = true; + label->FlatStyle = System::Windows::Forms::FlatStyle::Flat; + + for (LPCWSTR& choice : _valueStrings) { + combobox->Items->Add(msclr::interop::marshal_as(choice)); + } + combobox->SelectedIndex = GetPrivateProfileIntW(_iniSectionName, _iniVarName, _defaultVal, _iniFilePath); + combobox->Left = left + 104; + combobox->Top = top; + combobox->Width = 90; + combobox->AutoSize = true; + combobox->FlatStyle = System::Windows::Forms::FlatStyle::Flat; + combobox->DropDownStyle = ComboBoxStyle::DropDownList; + + tooltip->SetToolTip(label, gcnew String(_description)); + tooltip->SetToolTip(combobox, gcnew String(_description)); + + panel->Controls->Add(label); + panel->Controls->Add(combobox); + mainControlHandle = combobox->Handle; + return 28;; + } + + virtual void SaveOption() + { + System::String^ tempSysStr; + std::wstring tempWStr; + + tempSysStr = Convert::ToInt32(((ComboBox^)ComboBox::FromHandle(mainControlHandle))->SelectedIndex).ToString(); + tempWStr = msclr::interop::marshal_as(tempSysStr); + WritePrivateProfileStringW(_iniSectionName, _iniVarName, tempWStr.c_str(), _iniFilePath); + } +}; + + +class EditableDropdownOption : public ConfigOptionBase +{ +public: + LPCWSTR _defaultVal; + std::vector _valueStrings; + bool _useUtf8; + + EditableDropdownOption(LPCWSTR iniVarName, LPCWSTR iniSectionName, LPCWSTR iniFilePath, LPCWSTR friendlyName, LPCWSTR description, LPCWSTR defaultVal, std::vector valueStrings, bool useUtf8) + { + _iniVarName = iniVarName; + _iniSectionName = iniSectionName; + _iniFilePath = iniFilePath; + _friendlyName = friendlyName; + _description = description; + _defaultVal = defaultVal; + _valueStrings = valueStrings; + _useUtf8 = useUtf8; + } + + virtual int AddToPanel(Panel^ panel, unsigned int left, unsigned int top, ToolTip^ tooltip) + { + Label^ label = gcnew Label(); + ComboBox^ combobox = gcnew ComboBox(); + + WCHAR stringBuf[256]; + char utf8Buf[256]; + + label->Text = gcnew String(_friendlyName); + label->Left = left; + label->Top = top + 3; + label->Width = 100; + label->AutoSize = true; + label->FlatStyle = System::Windows::Forms::FlatStyle::Flat; + + for (LPCWSTR& choice : _valueStrings) { + combobox->Items->Add(msclr::interop::marshal_as(choice)); + } + + GetPrivateProfileStringW(_iniSectionName, _iniVarName, _defaultVal, stringBuf, 256, _iniFilePath); + if (_useUtf8 && wcscmp(_defaultVal, stringBuf) != 0) { // don't convert default value + WideCharToMultiByte(CP_ACP, 0, stringBuf, -1, utf8Buf, 256, NULL, NULL); // convert back to the original ANSI as read from file + MultiByteToWideChar(CP_UTF8, 0, utf8Buf, -1, stringBuf, 256); // now use those bytes to convert from UTF8 + } + + combobox->Text = gcnew String(stringBuf); + combobox->Left = left + 104; + combobox->Top = top; + combobox->Width = 90; + combobox->AutoSize = true; + combobox->FlatStyle = System::Windows::Forms::FlatStyle::Flat; + combobox->DropDownStyle = ComboBoxStyle::DropDown; + + // disable editing for utf8 mode because the ANSI hack used may not work correctly + if (_useUtf8) { + label->Enabled = false; + combobox->Enabled = false; + } + + tooltip->SetToolTip(label, gcnew String(_description)); + tooltip->SetToolTip(combobox, gcnew String(_description)); + + panel->Controls->Add(label); + panel->Controls->Add(combobox); + mainControlHandle = combobox->Handle; + return 28;; + } + + virtual void SaveOption() + { + // disable saving for utf8 mode because the ANSI hack used may not work correctly + if (_useUtf8) + return; + + System::String^ tempSysStr; + std::wstring tempWStr; + WCHAR stringBuf[256]; + char utf8Buf[256]; + + tempSysStr = ((ComboBox^)ComboBox::FromHandle(mainControlHandle))->Text; + tempWStr = msclr::interop::marshal_as(tempSysStr); + tempWStr.copy(stringBuf, 256, 0); + stringBuf[tempWStr.length()] = 0; + + if (_useUtf8) { + WideCharToMultiByte(CP_UTF8, 0, stringBuf, -1, utf8Buf, 256, NULL, NULL); // convert to UTF8 + MultiByteToWideChar(CP_ACP, 0, utf8Buf, -1, stringBuf, 256); // now convert that to wide chars as if it's ANSI so it saves properly after conversion to ANSI by windows + } + + WritePrivateProfileStringW(_iniSectionName, _iniVarName, stringBuf, _iniFilePath); + } +}; + + +class EditableDropdownNumberOption : public ConfigOptionBase +{ +public: + int _defaultVal; + std::vector _valueInts; + + EditableDropdownNumberOption(LPCWSTR iniVarName, LPCWSTR iniSectionName, LPCWSTR iniFilePath, LPCWSTR friendlyName, LPCWSTR description, int defaultVal, std::vector valueInts) + { + _iniVarName = iniVarName; + _iniSectionName = iniSectionName; + _iniFilePath = iniFilePath; + _friendlyName = friendlyName; + _description = description; + _defaultVal = defaultVal; + _valueInts = valueInts; + } + + virtual int AddToPanel(Panel^ panel, unsigned int left, unsigned int top, ToolTip^ tooltip) + { + Label^ label = gcnew Label(); + ComboBox^ combobox = gcnew ComboBox(); + + System::String^ tempSysStr; + + label->Text = gcnew String(_friendlyName); + label->Left = left; + label->Top = top + 3; + label->Width = 100; + label->AutoSize = true; + label->FlatStyle = System::Windows::Forms::FlatStyle::Flat; + + for (int& choice : _valueInts) { + combobox->Items->Add(Convert::ToInt32(choice).ToString()); + } + + tempSysStr = Convert::ToInt32((int)GetPrivateProfileIntW(_iniSectionName, _iniVarName, _defaultVal, _iniFilePath)).ToString(); + + combobox->Text = gcnew String(tempSysStr); + combobox->Left = left + 104; + combobox->Top = top; + combobox->Width = 90; + combobox->AutoSize = true; + combobox->FlatStyle = System::Windows::Forms::FlatStyle::Flat; + combobox->DropDownStyle = ComboBoxStyle::DropDown; + + tooltip->SetToolTip(label, gcnew String(_description)); + tooltip->SetToolTip(combobox, gcnew String(_description)); + + ComboboxValidation^ validation = gcnew ComboboxValidation(combobox); + combobox->Leave += gcnew System::EventHandler(validation, &ComboboxValidation::CheckNumberLeave); + + panel->Controls->Add(label); + panel->Controls->Add(combobox); + mainControlHandle = combobox->Handle; + return 28;; + } + + virtual void SaveOption() + { + System::String^ tempSysStr; + std::wstring tempWStr; + + tempSysStr = ((ComboBox^)ComboBox::FromHandle(mainControlHandle))->Text; + tempWStr = msclr::interop::marshal_as(tempSysStr); + + WritePrivateProfileStringW(_iniSectionName, _iniVarName, tempWStr.c_str(), _iniFilePath); + } +}; + + +class ResolutionOption : public ConfigOptionBase +{ +public: + LPCWSTR _iniVarName2; + resolution _defaultVal; + std::vector _valueResolutions; + + ResolutionOption(LPCWSTR iniVarName, LPCWSTR iniVarName2, LPCWSTR iniSectionName, LPCWSTR iniFilePath, LPCWSTR friendlyName, LPCWSTR description, resolution defaultVal, std::vector valueResolutions) + { + _iniVarName = iniVarName; + _iniVarName2 = iniVarName2; + _iniSectionName = iniSectionName; + _iniFilePath = iniFilePath; + _friendlyName = friendlyName; + _description = description; + _defaultVal = defaultVal; + _valueResolutions = valueResolutions; + } + + virtual int AddToPanel(Panel^ panel, unsigned int left, unsigned int top, ToolTip^ tooltip) + { + Label^ label = gcnew Label(); + ComboBox^ combobox = gcnew ComboBox(); + + System::String^ tempSysStr; + + label->Text = gcnew String(_friendlyName); + label->Left = left; + label->Top = top + 3; + label->Width = 100; + label->AutoSize = true; + label->FlatStyle = System::Windows::Forms::FlatStyle::Flat; + + for (resolution& choice : _valueResolutions) { + tempSysStr = Convert::ToInt32(choice.width).ToString() + L"x" + Convert::ToInt32(choice.height).ToString(); + combobox->Items->Add(tempSysStr); + } + + int width = GetPrivateProfileIntW(_iniSectionName, _iniVarName, -1, _iniFilePath); + int height = GetPrivateProfileIntW(_iniSectionName, _iniVarName2, -1, _iniFilePath); + if (width == -1 || height == -1) { + tempSysStr = Convert::ToInt32(_defaultVal.width).ToString() + L"x" + Convert::ToInt32(_defaultVal.height).ToString(); + combobox->Text = tempSysStr; + } + else { + tempSysStr = Convert::ToInt32(width).ToString() + L"x" + Convert::ToInt32(height).ToString(); + combobox->Text = tempSysStr; + } + + combobox->Left = left + 104; + combobox->Top = top; + combobox->Width = 90; + combobox->AutoSize = true; + combobox->FlatStyle = System::Windows::Forms::FlatStyle::Flat; + combobox->DropDownStyle = ComboBoxStyle::DropDown; + + tooltip->SetToolTip(label, gcnew String(_description)); + tooltip->SetToolTip(combobox, gcnew String(_description)); + + ComboboxValidation^ validation = gcnew ComboboxValidation(combobox); + combobox->Leave += gcnew System::EventHandler(validation, &ComboboxValidation::CheckResolutionLeave); + + panel->Controls->Add(label); + panel->Controls->Add(combobox); + mainControlHandle = combobox->Handle; + return 28;; + } + + virtual void SaveOption() + { + System::String^ tempSysStr; + std::wstring tempWStr; + cli::array^ resolutionArray; + + tempSysStr = ((ComboBox^)ComboBox::FromHandle(mainControlHandle))->Text; + resolutionArray = tempSysStr->Split('x'); + + tempSysStr = resolutionArray[0]; + tempWStr = msclr::interop::marshal_as(tempSysStr); + WritePrivateProfileStringW(_iniSectionName, _iniVarName, tempWStr.c_str(), _iniFilePath); + + tempSysStr = resolutionArray[1]; + tempWStr = msclr::interop::marshal_as(tempSysStr); + WritePrivateProfileStringW(_iniSectionName, _iniVarName2, tempWStr.c_str(), _iniFilePath); + + } +}; \ No newline at end of file diff --git a/source-code/source/plugins/Launcher/Launcher.vcxproj b/source-code/source/plugins/Launcher/Launcher.vcxproj index c698cb9..36a2833 100644 --- a/source-code/source/plugins/Launcher/Launcher.vcxproj +++ b/source-code/source/plugins/Launcher/Launcher.vcxproj @@ -165,6 +165,7 @@ + diff --git a/source-code/source/plugins/Launcher/framework.h b/source-code/source/plugins/Launcher/framework.h index 741e057..f2a38c7 100644 --- a/source-code/source/plugins/Launcher/framework.h +++ b/source-code/source/plugins/Launcher/framework.h @@ -1,10 +1,14 @@ -#pragma once +#pragma once #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers // Windows Header Files #include #include #include +#include +#include + +#include "ConfigOption.h" int (__cdecl* divaMain)(int argc, const char** argv, const char** envp) = (int(__cdecl*)(int argc, const char** argv, const char** envp))0x140194D90; @@ -36,80 +40,175 @@ LPCWSTR CONFIG_FILE = CONFIG_FILE_STRING.c_str(); wstring COMPONENTS_FILE_STRING = DirPath() + L"\\plugins\\components.ini"; LPCWSTR COMPONENTS_FILE = COMPONENTS_FILE_STRING.c_str(); -int nDisplay = GetPrivateProfileIntW(L"resolution", L"display", 0, CONFIG_FILE); -int nWidth = GetPrivateProfileIntW(L"resolution", L"width", 1280, CONFIG_FILE); -int nHeight = GetPrivateProfileIntW(L"resolution", L"height", 720, CONFIG_FILE); +wstring PLAYERDATA_FILE_STRING = DirPath() + L"\\plugins\\playerdata.ini"; +LPCWSTR PLAYERDATA_FILE = PLAYERDATA_FILE_STRING.c_str(); -int nIntRes = GetPrivateProfileIntW(L"resolution", L"r.enable", FALSE, CONFIG_FILE); -int nIntResWidth = GetPrivateProfileIntW(L"resolution", L"r.width", 1280, CONFIG_FILE); -int nIntResHeight = GetPrivateProfileIntW(L"resolution", L"r.height", 720, CONFIG_FILE); - -int nBitDepth = GetPrivateProfileIntW(L"resolution", L"bitdepth", 32, CONFIG_FILE); -int nRefreshRate = GetPrivateProfileIntW(L"resolution", L"refreshrate", 60, CONFIG_FILE); - -int nCursor = GetPrivateProfileIntW(L"patches", L"cursor", TRUE, CONFIG_FILE); -int nHideFreeplay = GetPrivateProfileIntW(L"patches", L"hide_freeplay", FALSE, CONFIG_FILE); -int nStatusIcons = GetPrivateProfileIntW(L"patches", L"status_icons", 0, CONFIG_FILE); -int nHidePVWatermark = GetPrivateProfileIntW(L"patches", L"hide_pv_watermark", FALSE, CONFIG_FILE); -int nNoPVUi = GetPrivateProfileIntW(L"patches", L"no_pv_ui", FALSE, CONFIG_FILE); -int nHideVolCtrl = GetPrivateProfileIntW(L"patches", L"hide_volume", FALSE, CONFIG_FILE); -int nNoLyrics = GetPrivateProfileIntW(L"patches", L"no_lyrics", FALSE, CONFIG_FILE); -int nNoMovies = GetPrivateProfileIntW(L"patches", L"no_movies", FALSE, CONFIG_FILE); -int nNoError = GetPrivateProfileIntW(L"patches", L"no_error", TRUE, CONFIG_FILE); - -int nTAA = GetPrivateProfileIntW(L"graphics", L"TAA", TRUE, CONFIG_FILE); -int nMLAA = GetPrivateProfileIntW(L"graphics", L"MLAA", TRUE, CONFIG_FILE); -int nFPSLimit = GetPrivateProfileIntW(L"graphics", L"FPS.Limit", 0, CONFIG_FILE); +LPCWSTR PATCHES_SECTION = L"patches"; +LPCWSTR GRAPHICS_SECTION = L"graphics"; +LPCWSTR RESOLUTION_SECTION = L"resolution"; +LPCWSTR LAUNCHER_SECTION = L"launcher"; +LPCWSTR COMPONENTS_SECTION = L"components"; +LPCWSTR PLAYERDATA_SECTION = L"playerdata"; int nSkipLauncher = GetPrivateProfileIntW(L"launcher", L"skip", FALSE, CONFIG_FILE); -// Custom function. Works like GetPrivateProfileIntW but returns bool. Can detect a numeric value or string. -bool GetPrivateProfileBoolW(LPCWSTR lpAppName, LPCWSTR lpKeyName, bool default, LPCWSTR lpFileName) -{ - wchar_t buffer[8]; - GetPrivateProfileStringW(lpAppName, lpKeyName, L"", buffer, 8, lpFileName); - //MessageBoxW(NULL, buffer, NULL, 0); +std::vector getScreenModes() { + static std::vector outVec = std::vector(); - for (wchar_t& chr : buffer) - chr = towlower(chr); + DEVMODEW dm = { 0 }; + dm.dmSize = sizeof(dm); + for (int iModeNum = 0; EnumDisplaySettingsW(NULL, iModeNum, &dm) != 0; iModeNum++) + { + outVec.push_back(dm); + } - bool out; - if ((lstrcmpW(buffer, L"true") == 0) || (lstrcmpW(buffer, L"1") == 0)) - out = true; - else if ((lstrcmpW(buffer, L"false") == 0) || (lstrcmpW(buffer, L"0") == 0)) - out = false; - else - out = default; - - return out; + return outVec; } -struct componentInfo { const LPCWSTR name; LPCWSTR friendlyName; LPCWSTR description; System::IntPtr cb; }; -componentInfo componentsArray[] = { - { L"input_emulator", L"Input Emulator", L"Emulates input through keyboard and/or mouse.", System::IntPtr::Zero }, - { L"touch_slider_emulator", L"Slider Emulator", L"Emulates slider through keyboard and/or mouse.", System::IntPtr::Zero }, - { L"touch_panel_emulator", L"Touch Panel Emulator", L"Emulates touch panel through mouse.", System::IntPtr::Zero }, +std::vector getScreenResolutionsVec(std::vector &screenModes) { + static std::vector outVec = std::vector(); - { L"sys_timer", L"Timer Freeze", L"Freezes the PV select timer at 39 seconds.", System::IntPtr::Zero }, + for (DEVMODEW &dm : screenModes) + { + resolution res = resolution(dm.dmPelsWidth, dm.dmPelsHeight); - { L"player_data_manager", L"Player Data Manager", L"Loads user-defined values into the PlayerData struct.\nRequired for modules and game mode modifiers.", System::IntPtr::Zero }, + if (std::find(outVec.begin(), outVec.end(), res) == outVec.end()) { + outVec.push_back(res); + } + } - { L"frame_rate_manager", L"Frame Rate Manager", L"Adjusts animations to the correct speed at different frame rates.\nOnly needed when FPS isn't locket at 60.", System::IntPtr::Zero }, + std::sort(outVec.begin(), outVec.end()); - { L"stage_manager", L"Stage Manager", L"Allows for playing unlimited songs per session.", System::IntPtr::Zero }, + return outVec; +} - { L"fast_loader", L"Fast Loader", L"Skip or speed up unnecessary loading steps.", System::IntPtr::Zero }, +static std::vector getScreenDepthsVec(std::vector &screenModes) { + static std::vector outVec = std::vector(); - { L"camera_controller", L"Camera Controller", L"Enables freecam (toggled using F3).\nWASD to move, SPACE/CTRL for up/down, Q/R to rotate, R/F for zoom.\nHolding SHIFT/ALT changes control speed.", System::IntPtr::Zero }, + for (DEVMODEW &dm : screenModes) + { + int depth = dm.dmBitsPerPel; - { L"scale_component", L"Scale Component", L"Scales the graphics output framebuffer to fill the screen/window.", System::IntPtr::Zero }, + if (depth < 24) + continue; - { L"debug_component", L"Debug Component", L"Allows for changing game state (F4-F8 keys), using dev GUI and tests, and speeding up 2d animations/menus (hold SHIFT+TAB).", System::IntPtr::Zero }, + if (std::find(outVec.begin(), outVec.end(), depth) == outVec.end()) { + outVec.push_back(depth); + } + } - { L"fps_limiter", L"FPS Limiter", L"Lets you set a framerate cap. The value of the limit is in the options tab.", System::IntPtr::Zero }, + std::sort(outVec.begin(), outVec.end()); - { L"target_inspector", L"Target Inspector", L"Enables hold transfers.", System::IntPtr::Zero }, + return outVec; +} + +static std::vector getScreenRatesVec(std::vector &screenModes) { + static std::vector outVec = std::vector(); + + for (DEVMODEW &dm : screenModes) + { + int rate = dm.dmDisplayFrequency; + + if (std::find(outVec.begin(), outVec.end(), rate) == outVec.end()) { + outVec.push_back(rate); + } + } + + std::sort(outVec.begin(), outVec.end()); + + return outVec; +} + +std::vector screenModes = getScreenModes(); + + +DropdownOption* DisplayModeDropdown = new DropdownOption(L"display", RESOLUTION_SECTION, CONFIG_FILE, L"Display:", L"Sets the window/screen mode.", 0, std::vector({ L"Windowed", L"Borderless", L"Fullscreen" })); +ResolutionOption* DisplayResolutionOption = new ResolutionOption(L"width", L"height", RESOLUTION_SECTION, CONFIG_FILE, L"Resolution:", L"Sets the display resolution.", resolution(1280, 720), getScreenResolutionsVec(screenModes)); + +ConfigOptionBase* screenResolutionArray[] = { + DisplayModeDropdown, + DisplayResolutionOption, + new EditableDropdownNumberOption(L"bitdepth", RESOLUTION_SECTION, CONFIG_FILE, L"Bit Depth:", L"Sets the display bit depth.", 32, getScreenDepthsVec(screenModes)), + new EditableDropdownNumberOption(L"refreshrate", RESOLUTION_SECTION, CONFIG_FILE, L"Refresh Rate:", L"Sets the display refresh rate.", 60, getScreenRatesVec(screenModes)), +}; + +BooleanOption* InternalResolutionCheckbox = new BooleanOption(L"r.enable", RESOLUTION_SECTION, CONFIG_FILE, L"Enable", L"Enable or disable custom internal resolution.", false, false); +ResolutionOption* InternalResolutionOption = new ResolutionOption(L"r.width", L"r.height", RESOLUTION_SECTION, CONFIG_FILE, L"Resolution:", L"Sets the internal resolution.", resolution(1280, 720), std::vector({ resolution(640,480), resolution(800,600), resolution(960,720), resolution(1280,720), resolution(1920,1080), resolution(2560,1440), resolution(3840,2160), resolution(5120,2880), resolution(7680,4320) })); + +ConfigOptionBase* internalResolutionArray[] = { + InternalResolutionCheckbox, + InternalResolutionOption +}; + +ConfigOptionBase* optionsArray[] = { + new BooleanOption(L"cursor", PATCHES_SECTION, CONFIG_FILE, L"Cursor", L"Enable or disable the mouse cursor.", true, false), + + new BooleanOption(L"TAA", GRAPHICS_SECTION, CONFIG_FILE, L"TAA", L"Temporal Anti-Aliasing", true, false), + new BooleanOption(L"MLAA", GRAPHICS_SECTION, CONFIG_FILE, L"MLAA", L"Morphological Anti-Aliasing", true, false), + + new BooleanOption(L"hide_freeplay", PATCHES_SECTION, CONFIG_FILE, L"Hide Freeplay", L"Hide Freeplay text.", false, false), + new BooleanOption(L"hide_volume", PATCHES_SECTION, CONFIG_FILE, L"Hide Volume Buttons", L"Hide the volume and SE control buttons.", false, false), + new BooleanOption(L"no_movies", PATCHES_SECTION, CONFIG_FILE, L"Disable Movies", L"Disables movies (enable this if the game hangs when loading certain PVs).", false, false), + new BooleanOption(L"no_pv_ui", PATCHES_SECTION, CONFIG_FILE, L"Disable PV UI", L"Removes the photo controls during PV playback.", false, false), + new BooleanOption(L"no_lyrics", PATCHES_SECTION, CONFIG_FILE, L"Disable Lyrics", L"Disables showing lyrics.", false, false), + new BooleanOption(L"hide_pv_watermark", PATCHES_SECTION, CONFIG_FILE, L"Hide PV Watermark", L"Hides the watermark that's usually shown in PV viewing mode.", false, false), + new BooleanOption(L"no_error", PATCHES_SECTION, CONFIG_FILE, L"Disable Error Banner", L"Disables the error banner on the attract screen.", true, false), + + new BooleanOption(L"skip", LAUNCHER_SECTION, CONFIG_FILE, L"Skip Launcher", L"Forces the launcher to be skipped, you can also use the --launch parameter instead of this.", false, false), + + new DropdownOption(L"status_icons", PATCHES_SECTION, CONFIG_FILE, L"Status Icons:", L"Set the state of card reader and network status icons.", 3, std::vector({ L"Default", L"Hidden", L"Error", L"OK", L"Partial OK" })), + + new NumericOption(L"FPS.Limit", GRAPHICS_SECTION, CONFIG_FILE, L"FPS Limit:", L"Using the FPS limit requires the \"FPS Limiter\" component to be enabled.", 60, 0, INT_MAX), + + new StringOption(L"command_line", LAUNCHER_SECTION, CONFIG_FILE, L"Command Line:", L"Allows setting command line parameters for the game when using the launcher.\nDisabling the launcher will bypass this.", L"", false), +}; + +ConfigOptionBase* playerdataArray[] = { + new StringOption(L"player_name", PLAYERDATA_SECTION, PLAYERDATA_FILE, L"Player Name:", L"Player name shown in game.", L"NO-NAME", true), + new StringOption(L"level_name", PLAYERDATA_SECTION, PLAYERDATA_FILE, L"Level Name:", L"Level (plate) name shown in game.", L"忘れないでね私の声を", true), + + new NumericOption(L"level_plate_id", PLAYERDATA_SECTION, PLAYERDATA_FILE, L"Level Plate:", L"Sets the level background image (plate).", 0, 0, INT_MAX), + new NumericOption(L"skin_equip ", PLAYERDATA_SECTION, PLAYERDATA_FILE, L"Skin:", L"Sets the gameplay UI skin.", 0, 0, INT_MAX), + + new NumericOption(L"btn_se_equip", PLAYERDATA_SECTION, PLAYERDATA_FILE, L"Button Sound:", L"Sets the sound effect for buttons.\n-1 = song default", -1, -1, INT_MAX), + new NumericOption(L"slide_se_equip", PLAYERDATA_SECTION, PLAYERDATA_FILE, L"Slide Sound:", L"Sets the sound effect for slides.\n-1 = song default", -1, -1, INT_MAX), + new NumericOption(L"chainslide_se_equip", PLAYERDATA_SECTION, PLAYERDATA_FILE, L"Chainslide Sound:", L"Sets the sound effect for chain slides.\n-1 = song default", -1, -1, INT_MAX), + + new BooleanOption(L"border_great", PLAYERDATA_SECTION, PLAYERDATA_FILE, L"Clear Border (Great)", L"Shows the clear border for a great rating on the progress bar.", true, true), + new BooleanOption(L"border_excellent", PLAYERDATA_SECTION, PLAYERDATA_FILE, L"Clear Border (Excellent)", L"Shows the clear border for an excellent rating on the progress bar.", true, true), + + new BooleanOption(L"use_card", PLAYERDATA_SECTION, PLAYERDATA_FILE, L"Use Card", L"Enables IC card. This allows module selection.", false, true), + new BooleanOption(L"module_card_workaround", PLAYERDATA_SECTION, PLAYERDATA_FILE, L"Module Selection Workaround", L"Allows module selection without card and tries to improve menu performance.\n(BETA)", true, true), + + new BooleanOption(L"gamemode_options", PLAYERDATA_SECTION, PLAYERDATA_FILE, L"Game Modifiers", L"Allows use of game mode modifiers (hi-speed, hidden, and sudden).", true, true), +}; + + +ConfigOptionBase* componentsArray[] = { + new BooleanOption(L"input_emulator", COMPONENTS_SECTION, COMPONENTS_FILE, L"Input Emulator", L"Emulates input through keyboard and/or mouse.", false, true), + new BooleanOption(L"touch_slider_emulator", COMPONENTS_SECTION, COMPONENTS_FILE, L"Slider Emulator", L"Emulates slider through keyboard and/or mouse.", false, true), + new BooleanOption(L"touch_panel_emulator", COMPONENTS_SECTION, COMPONENTS_FILE, L"Touch Panel Emulator", L"Emulates touch panel through mouse.", false, true), + + new BooleanOption(L"sys_timer", COMPONENTS_SECTION, COMPONENTS_FILE, L"Timer Freeze", L"Freezes the PV select timer at 39 seconds.", false, true), + + new BooleanOption(L"player_data_manager", COMPONENTS_SECTION, COMPONENTS_FILE, L"Player Data Manager", L"Loads user-defined values into the PlayerData struct.\nRequired for modules and game mode modifiers.", false, true), + + new BooleanOption(L"frame_rate_manager", COMPONENTS_SECTION, COMPONENTS_FILE, L"Frame Rate Manager", L"Adjusts animations to the correct speed at different frame rates.\nOnly needed when FPS isn't locket at 60.", false, true), + + new BooleanOption(L"stage_manager", COMPONENTS_SECTION, COMPONENTS_FILE, L"Stage Manager", L"Allows for playing unlimited songs per session.", false, true), + + new BooleanOption(L"fast_loader", COMPONENTS_SECTION, COMPONENTS_FILE, L"Fast Loader", L"Skip or speed up unnecessary loading steps.", false, true), + + new BooleanOption(L"camera_controller", COMPONENTS_SECTION, COMPONENTS_FILE, L"Camera Controller", L"Enables freecam (toggled using F3).\nWASD to move, SPACE/CTRL for up/down, Q/R to rotate, R/F for zoom.\nHolding SHIFT/ALT changes control speed.", false, true), + + new BooleanOption(L"scale_component", COMPONENTS_SECTION, COMPONENTS_FILE, L"Scale Component", L"Scales the graphics output framebuffer to fill the screen/window.", false, true), + + new BooleanOption(L"debug_component", COMPONENTS_SECTION, COMPONENTS_FILE, L"Debug Component", L"Allows for changing game state (F4-F8 keys), using dev GUI and tests, and speeding up 2d animations/menus (hold SHIFT+TAB).", false, true), + + new BooleanOption(L"fps_limiter", COMPONENTS_SECTION, COMPONENTS_FILE, L"FPS Limiter", L"Lets you set a framerate cap. The value of the limit is in the options tab.", false, true), + + new BooleanOption(L"target_inspector", COMPONENTS_SECTION, COMPONENTS_FILE, L"Target Inspector", L"Enables hold transfers.", false, true), }; bool IsLineInFile(LPCSTR searchLine, LPCWSTR fileName) diff --git a/source-code/source/plugins/Launcher/ui.h b/source-code/source/plugins/Launcher/ui.h index ac9fe4a..1a693d4 100644 --- a/source-code/source/plugins/Launcher/ui.h +++ b/source-code/source/plugins/Launcher/ui.h @@ -34,97 +34,80 @@ namespace Launcher { PrependFile("[components]\n", COMPONENTS_FILE); } + // if playerdata.ini has no section name, add one + if (!IsLineInFile("[playerdata]", PLAYERDATA_FILE)) + { + PrependFile("[playerdata]\n", PLAYERDATA_FILE); + } + + + this->panel_ScreenRes->SuspendLayout(); + + // populate options (patches) from array in framework + // (easier than manually setting everything up) + int screenresY = 3; + for (ConfigOptionBase* option : screenResolutionArray) + { + screenresY += option->AddToPanel(panel_ScreenRes, 3, screenresY, toolTip1); + } + ((ComboBox^)ComboBox::FromHandle(DisplayModeDropdown->mainControlHandle))->SelectedIndexChanged += gcnew System::EventHandler(this, &ui::DisplayTypeChangedHandler); + DisplayTypeChangedHandler(this, gcnew EventArgs); // run handler now + this->panel_ScreenRes->ResumeLayout(false); + this->panel_ScreenRes->PerformLayout(); + + + this->panel_IntRes->SuspendLayout(); + + // populate options (patches) from array in framework + // (easier than manually setting everything up) + int intresY = 3; + for (ConfigOptionBase* option : internalResolutionArray) + { + intresY += option->AddToPanel(panel_IntRes, 3, intresY, toolTip1); + } + ((CheckBox^)CheckBox::FromHandle(InternalResolutionCheckbox->mainControlHandle))->CheckedChanged += gcnew System::EventHandler(this, &ui::InternalResEnabledChangedHandler); + InternalResEnabledChangedHandler(this, gcnew EventArgs); // run handler now + this->panel_IntRes->ResumeLayout(false); + this->panel_IntRes->PerformLayout(); + + + this->panel_Patches->SuspendLayout(); + + // populate options (patches) from array in framework + // (easier than manually setting everything up) + int optionsY = 3; + for (ConfigOptionBase* option : optionsArray) + { + optionsY += option->AddToPanel(panel_Patches, 3, optionsY, toolTip1); + } + this->panel_Patches->ResumeLayout(false); + this->panel_Patches->PerformLayout(); + + + this->panel_Playerdata->SuspendLayout(); + + // populate playerdata options from array in framework + // (easier than manually setting everything up) + int playerdataY = 3; + for (ConfigOptionBase* option : playerdataArray) + { + playerdataY += option->AddToPanel(panel_Playerdata, 3, playerdataY, toolTip1); + } + this->panel_Playerdata->ResumeLayout(false); + this->panel_Playerdata->PerformLayout(); + + this->panel_Components->SuspendLayout(); // populate components from array in framework // (easier than manually setting everything up) int componentsY = 3; - for (componentInfo& component : componentsArray) + for (ConfigOptionBase* component : componentsArray) { - CheckBox^ cb = gcnew CheckBox(); - cb->Text = gcnew String(component.friendlyName); - cb->Checked = GetPrivateProfileBoolW(L"components", component.name, false, COMPONENTS_FILE); - cb->Left = 3; - cb->Top = componentsY; - cb->AutoSize = true; - cb->FlatStyle = System::Windows::Forms::FlatStyle::Flat; - panel_Components->Controls->Add(cb); - component.cb = cb->Handle; - componentsY += 23; + componentsY += component->AddToPanel(panel_Components, 3, componentsY, toolTip1); } this->panel_Components->ResumeLayout(false); this->panel_Components->PerformLayout(); - - comboBox_Display->SelectedIndex = nDisplay; - - DEVMODEW dm = { 0 }; - dm.dmSize = sizeof(dm); - for (int iModeNum = 0; EnumDisplaySettingsW(NULL, iModeNum, &dm) != 0; iModeNum++) - { - if (!comboBox_Resolution->Items->Contains(dm.dmPelsWidth + "x" + dm.dmPelsHeight)) - { - comboBox_Resolution->Items->Add(dm.dmPelsWidth + "x" + dm.dmPelsHeight); - } - if (!comboBox_BitDepth->Items->Contains(dm.dmBitsPerPel)) - { - comboBox_BitDepth->Items->Add(dm.dmBitsPerPel); - } - if (!comboBox_RefreshRate->Items->Contains(dm.dmDisplayFrequency)) - { - comboBox_RefreshRate->Items->Add(dm.dmDisplayFrequency); - } - } - - comboBox_intResolution->Items->Add("640x480"); - comboBox_intResolution->Items->Add("960x720"); - comboBox_intResolution->Items->Add("1280x720"); - comboBox_intResolution->Items->Add("1920x1080"); - comboBox_intResolution->Items->Add("2560x1440"); - comboBox_intResolution->Items->Add("3840x2160"); - comboBox_intResolution->Items->Add("5120x2880"); - comboBox_intResolution->Items->Add("7680x4320"); - - comboBox_Resolution->Text = nWidth.ToString() + "x" + nHeight.ToString(); - checkBox_InternalRes->Checked = nIntRes; - comboBox_intResolution->Text = nIntResWidth.ToString() + "x" + nIntResHeight.ToString(); - checkBox_Cursor->Checked = nCursor; - checkBox_HideFreeplay->Checked = nHideFreeplay; - checkBox_HidePVWatermark->Checked = nHidePVWatermark; - checkBox_NoPVUi->Checked = nNoPVUi; - checkBox_NoLyrics->Checked = nNoLyrics; - checkBox_NoMovies->Checked = nNoMovies; - checkBox_HideVolCtrl->Checked = nHideVolCtrl; - comboBox_StatusIcons->SelectedIndex = nStatusIcons; - checkBox_TAA->Checked = nTAA; - checkBox_MLAA->Checked = nMLAA; - checkBox_DisableErrorBanner->Checked = nNoError; - textBox_FPSLimit->Text = nFPSLimit.ToString(); - checkBox_SkipLauncher->Checked = nSkipLauncher; - comboBox_BitDepth->Text = nBitDepth.ToString(); - comboBox_RefreshRate->Text = nRefreshRate.ToString(); - - if (!nIntRes) - { - comboBox_intResolution->Enabled = false; - } - if (nDisplay == 0 || nDisplay == 2) - { - comboBox_Resolution->Enabled = true; - } - else - { - comboBox_Resolution->Enabled = false; - } - if (comboBox_Display->SelectedIndex == 2) - { - comboBox_BitDepth->Enabled = true; - comboBox_RefreshRate->Enabled = true; - } - else - { - comboBox_BitDepth->Enabled = false; - comboBox_RefreshRate->Enabled = false; - } } protected: @@ -140,92 +123,28 @@ namespace Launcher { } private: System::Windows::Forms::Button^ button_Launch; private: System::Windows::Forms::Button^ button_Exit; - private: System::Windows::Forms::Label^ label_Resolution; - - protected: - - - private: System::Windows::Forms::GroupBox^ groupBox_ScreenRes; - - private: System::Windows::Forms::TabControl^ tabControl; private: System::Windows::Forms::TabPage^ tabPage_Resolution; private: System::Windows::Forms::GroupBox^ groupBox_InternalRes; - private: System::Windows::Forms::CheckBox^ checkBox_InternalRes; private: System::Windows::Forms::TabPage^ tabPage_Components; - private: System::Windows::Forms::Panel^ panel_Components; - private: System::Windows::Forms::TabPage^ tabPage_Patches; private: System::Windows::Forms::Panel^ panel_Patches; - - - - private: System::Windows::Forms::Label^ label_FPSLimit; - - - - private: System::Windows::Forms::CheckBox^ checkBox_Cursor; - - private: System::Windows::Forms::Label^ label_intResolution; - - - - - - - private: System::Windows::Forms::TextBox^ textBox_FPSLimit; - private: System::Windows::Forms::CheckBox^ checkBox_HideFreeplay; - private: System::Windows::Forms::CheckBox^ checkBox_MLAA; - private: System::Windows::Forms::CheckBox^ checkBox_TAA; - - private: System::Windows::Forms::CheckBox^ checkBox_HidePVWatermark; - private: System::Windows::Forms::CheckBox^ checkBox_NoLyrics; - private: System::Windows::Forms::CheckBox^ checkBox_NoPVUi; - private: System::Windows::Forms::CheckBox^ checkBox_HideVolCtrl; - private: System::Windows::Forms::ComboBox^ comboBox_Display; - private: System::Windows::Forms::Label^ label_Display; -private: System::Windows::Forms::ComboBox^ comboBox_Resolution; -private: System::Windows::Forms::ComboBox^ comboBox_intResolution; - -private: System::Windows::Forms::ComboBox^ comboBox_StatusIcons; -private: System::Windows::Forms::Label^ label_StatusIcons; -private: System::Windows::Forms::Button^ button_Discord; - -private: System::Windows::Forms::Panel^ panel_innerPatches; - - -private: System::Windows::Forms::TableLayoutPanel^ tableLayoutPanel_FPSLimit; - -private: System::Windows::Forms::TableLayoutPanel^ tableLayoutPanel_Status; - - - - - - -private: System::Windows::Forms::CheckBox^ checkBox_NoMovies; - -private: System::Windows::Forms::Button^ button_github; -private: System::Windows::Forms::CheckBox^ checkBox_DisableErrorBanner; -private: System::Windows::Forms::CheckBox^ checkBox_SkipLauncher; -private: System::Windows::Forms::TableLayoutPanel^ tableLayoutPanel_ScreenRes; -private: System::Windows::Forms::TableLayoutPanel^ tableLayoutPanel_IntRes; -private: System::Windows::Forms::Label^ label_RefreshRate; -private: System::Windows::Forms::ComboBox^ comboBox_BitDepth; -private: System::Windows::Forms::ComboBox^ comboBox_RefreshRate; -private: System::Windows::Forms::Label^ label_BitDepth; - - - - + private: System::Windows::Forms::Button^ button_Discord; + private: System::Windows::Forms::Button^ button_github; + private: System::Windows::Forms::TabPage^ tabPage_Playerdata; + private: System::Windows::Forms::Panel^ panel_Playerdata; + private: System::Windows::Forms::ToolTip^ toolTip1; + private: System::Windows::Forms::Panel^ panel_ScreenRes; + private: System::Windows::Forms::Panel^ panel_IntRes; + private: System::ComponentModel::IContainer^ components; private: /// /// Required designer variable. /// - System::ComponentModel::Container ^components; + #pragma region Windows Form Designer generated code /// @@ -234,61 +153,31 @@ private: System::Windows::Forms::Label^ label_BitDepth; /// void InitializeComponent(void) { - System::ComponentModel::ComponentResourceManager^ resources = (gcnew System::ComponentModel::ComponentResourceManager(ui::typeid)); + this->components = (gcnew System::ComponentModel::Container()); + System::ComponentModel::ComponentResourceManager^ resources = (gcnew System::ComponentModel::ComponentResourceManager(ui::typeid)); this->button_Launch = (gcnew System::Windows::Forms::Button()); this->button_Exit = (gcnew System::Windows::Forms::Button()); - this->label_Resolution = (gcnew System::Windows::Forms::Label()); this->groupBox_ScreenRes = (gcnew System::Windows::Forms::GroupBox()); - this->tableLayoutPanel_ScreenRes = (gcnew System::Windows::Forms::TableLayoutPanel()); - this->label_RefreshRate = (gcnew System::Windows::Forms::Label()); - this->label_Display = (gcnew System::Windows::Forms::Label()); - this->comboBox_Resolution = (gcnew System::Windows::Forms::ComboBox()); - this->comboBox_Display = (gcnew System::Windows::Forms::ComboBox()); - this->comboBox_BitDepth = (gcnew System::Windows::Forms::ComboBox()); - this->comboBox_RefreshRate = (gcnew System::Windows::Forms::ComboBox()); - this->label_BitDepth = (gcnew System::Windows::Forms::Label()); + this->panel_ScreenRes = (gcnew System::Windows::Forms::Panel()); this->tabControl = (gcnew System::Windows::Forms::TabControl()); this->tabPage_Resolution = (gcnew System::Windows::Forms::TabPage()); this->groupBox_InternalRes = (gcnew System::Windows::Forms::GroupBox()); - this->tableLayoutPanel_IntRes = (gcnew System::Windows::Forms::TableLayoutPanel()); - this->comboBox_intResolution = (gcnew System::Windows::Forms::ComboBox()); - this->checkBox_InternalRes = (gcnew System::Windows::Forms::CheckBox()); - this->label_intResolution = (gcnew System::Windows::Forms::Label()); + this->panel_IntRes = (gcnew System::Windows::Forms::Panel()); this->tabPage_Patches = (gcnew System::Windows::Forms::TabPage()); this->panel_Patches = (gcnew System::Windows::Forms::Panel()); - this->panel_innerPatches = (gcnew System::Windows::Forms::Panel()); - this->checkBox_SkipLauncher = (gcnew System::Windows::Forms::CheckBox()); - this->checkBox_DisableErrorBanner = (gcnew System::Windows::Forms::CheckBox()); - this->checkBox_NoMovies = (gcnew System::Windows::Forms::CheckBox()); - this->checkBox_Cursor = (gcnew System::Windows::Forms::CheckBox()); - this->tableLayoutPanel_FPSLimit = (gcnew System::Windows::Forms::TableLayoutPanel()); - this->textBox_FPSLimit = (gcnew System::Windows::Forms::TextBox()); - this->label_FPSLimit = (gcnew System::Windows::Forms::Label()); - this->checkBox_TAA = (gcnew System::Windows::Forms::CheckBox()); - this->tableLayoutPanel_Status = (gcnew System::Windows::Forms::TableLayoutPanel()); - this->label_StatusIcons = (gcnew System::Windows::Forms::Label()); - this->comboBox_StatusIcons = (gcnew System::Windows::Forms::ComboBox()); - this->checkBox_MLAA = (gcnew System::Windows::Forms::CheckBox()); - this->checkBox_HideFreeplay = (gcnew System::Windows::Forms::CheckBox()); - this->checkBox_HidePVWatermark = (gcnew System::Windows::Forms::CheckBox()); - this->checkBox_HideVolCtrl = (gcnew System::Windows::Forms::CheckBox()); - this->checkBox_NoLyrics = (gcnew System::Windows::Forms::CheckBox()); - this->checkBox_NoPVUi = (gcnew System::Windows::Forms::CheckBox()); + this->tabPage_Playerdata = (gcnew System::Windows::Forms::TabPage()); + this->panel_Playerdata = (gcnew System::Windows::Forms::Panel()); this->tabPage_Components = (gcnew System::Windows::Forms::TabPage()); this->panel_Components = (gcnew System::Windows::Forms::Panel()); this->button_Discord = (gcnew System::Windows::Forms::Button()); this->button_github = (gcnew System::Windows::Forms::Button()); + this->toolTip1 = (gcnew System::Windows::Forms::ToolTip(this->components)); this->groupBox_ScreenRes->SuspendLayout(); - this->tableLayoutPanel_ScreenRes->SuspendLayout(); this->tabControl->SuspendLayout(); this->tabPage_Resolution->SuspendLayout(); this->groupBox_InternalRes->SuspendLayout(); - this->tableLayoutPanel_IntRes->SuspendLayout(); this->tabPage_Patches->SuspendLayout(); - this->panel_Patches->SuspendLayout(); - this->panel_innerPatches->SuspendLayout(); - this->tableLayoutPanel_FPSLimit->SuspendLayout(); - this->tableLayoutPanel_Status->SuspendLayout(); + this->tabPage_Playerdata->SuspendLayout(); this->tabPage_Components->SuspendLayout(); this->SuspendLayout(); // @@ -315,20 +204,9 @@ private: System::Windows::Forms::Label^ label_BitDepth; this->button_Exit->Text = L"Exit"; this->button_Exit->Click += gcnew System::EventHandler(this, &ui::Button_Exit_Click); // - // label_Resolution - // - this->label_Resolution->Anchor = System::Windows::Forms::AnchorStyles::Left; - this->label_Resolution->AutoSize = true; - this->label_Resolution->FlatStyle = System::Windows::Forms::FlatStyle::Flat; - this->label_Resolution->Location = System::Drawing::Point(3, 32); - this->label_Resolution->Name = L"label_Resolution"; - this->label_Resolution->Size = System::Drawing::Size(60, 13); - this->label_Resolution->TabIndex = 11; - this->label_Resolution->Text = L"Resolution:"; - // // groupBox_ScreenRes // - this->groupBox_ScreenRes->Controls->Add(this->tableLayoutPanel_ScreenRes); + this->groupBox_ScreenRes->Controls->Add(this->panel_ScreenRes); this->groupBox_ScreenRes->FlatStyle = System::Windows::Forms::FlatStyle::Flat; this->groupBox_ScreenRes->ForeColor = System::Drawing::Color::White; this->groupBox_ScreenRes->Location = System::Drawing::Point(8, 6); @@ -338,114 +216,19 @@ private: System::Windows::Forms::Label^ label_BitDepth; this->groupBox_ScreenRes->TabStop = false; this->groupBox_ScreenRes->Text = L"Screen Resolution"; // - // tableLayoutPanel_ScreenRes + // panel_ScreenRes // - this->tableLayoutPanel_ScreenRes->ColumnCount = 2; - this->tableLayoutPanel_ScreenRes->ColumnStyles->Add((gcnew System::Windows::Forms::ColumnStyle(System::Windows::Forms::SizeType::Percent, - 50))); - this->tableLayoutPanel_ScreenRes->ColumnStyles->Add((gcnew System::Windows::Forms::ColumnStyle(System::Windows::Forms::SizeType::Percent, - 50))); - this->tableLayoutPanel_ScreenRes->Controls->Add(this->label_RefreshRate, 0, 3); - this->tableLayoutPanel_ScreenRes->Controls->Add(this->label_Display, 0, 0); - this->tableLayoutPanel_ScreenRes->Controls->Add(this->comboBox_Resolution, 1, 1); - this->tableLayoutPanel_ScreenRes->Controls->Add(this->label_Resolution, 0, 1); - this->tableLayoutPanel_ScreenRes->Controls->Add(this->comboBox_Display, 1, 0); - this->tableLayoutPanel_ScreenRes->Controls->Add(this->comboBox_BitDepth, 1, 2); - this->tableLayoutPanel_ScreenRes->Controls->Add(this->comboBox_RefreshRate, 1, 3); - this->tableLayoutPanel_ScreenRes->Controls->Add(this->label_BitDepth, 0, 2); - this->tableLayoutPanel_ScreenRes->Location = System::Drawing::Point(9, 19); - this->tableLayoutPanel_ScreenRes->Name = L"tableLayoutPanel_ScreenRes"; - this->tableLayoutPanel_ScreenRes->RowCount = 4; - this->tableLayoutPanel_ScreenRes->RowStyles->Add((gcnew System::Windows::Forms::RowStyle(System::Windows::Forms::SizeType::Percent, - 47.36842F))); - this->tableLayoutPanel_ScreenRes->RowStyles->Add((gcnew System::Windows::Forms::RowStyle(System::Windows::Forms::SizeType::Percent, - 52.63158F))); - this->tableLayoutPanel_ScreenRes->RowStyles->Add((gcnew System::Windows::Forms::RowStyle(System::Windows::Forms::SizeType::Absolute, - 26))); - this->tableLayoutPanel_ScreenRes->RowStyles->Add((gcnew System::Windows::Forms::RowStyle(System::Windows::Forms::SizeType::Absolute, - 28))); - this->tableLayoutPanel_ScreenRes->Size = System::Drawing::Size(193, 107); - this->tableLayoutPanel_ScreenRes->TabIndex = 15; - // - // label_RefreshRate - // - this->label_RefreshRate->Anchor = System::Windows::Forms::AnchorStyles::Left; - this->label_RefreshRate->AutoSize = true; - this->label_RefreshRate->FlatStyle = System::Windows::Forms::FlatStyle::Flat; - this->label_RefreshRate->Location = System::Drawing::Point(3, 86); - this->label_RefreshRate->Name = L"label_RefreshRate"; - this->label_RefreshRate->Size = System::Drawing::Size(73, 13); - this->label_RefreshRate->TabIndex = 105; - this->label_RefreshRate->Text = L"Refresh Rate:"; - // - // label_Display - // - this->label_Display->Anchor = System::Windows::Forms::AnchorStyles::Left; - this->label_Display->AutoSize = true; - this->label_Display->FlatStyle = System::Windows::Forms::FlatStyle::Flat; - this->label_Display->Location = System::Drawing::Point(3, 6); - this->label_Display->Name = L"label_Display"; - this->label_Display->Size = System::Drawing::Size(44, 13); - this->label_Display->TabIndex = 13; - this->label_Display->Text = L"Display:"; - // - // comboBox_Resolution - // - this->comboBox_Resolution->Anchor = System::Windows::Forms::AnchorStyles::Left; - this->comboBox_Resolution->FlatStyle = System::Windows::Forms::FlatStyle::Flat; - this->comboBox_Resolution->FormattingEnabled = true; - this->comboBox_Resolution->Location = System::Drawing::Point(99, 28); - this->comboBox_Resolution->Name = L"comboBox_Resolution"; - this->comboBox_Resolution->Size = System::Drawing::Size(85, 21); - this->comboBox_Resolution->TabIndex = 12; - // - // comboBox_Display - // - this->comboBox_Display->Anchor = System::Windows::Forms::AnchorStyles::Left; - this->comboBox_Display->DropDownStyle = System::Windows::Forms::ComboBoxStyle::DropDownList; - this->comboBox_Display->FlatStyle = System::Windows::Forms::FlatStyle::Flat; - this->comboBox_Display->FormattingEnabled = true; - this->comboBox_Display->Items->AddRange(gcnew cli::array< System::Object^ >(3) { L"Windowed", L"Borderless", L"Fullscreen" }); - this->comboBox_Display->Location = System::Drawing::Point(99, 3); - this->comboBox_Display->Name = L"comboBox_Display"; - this->comboBox_Display->Size = System::Drawing::Size(85, 21); - this->comboBox_Display->TabIndex = 14; - this->comboBox_Display->SelectedIndexChanged += gcnew System::EventHandler(this, &ui::ComboBox_Display_SelectedIndexChanged); - // - // comboBox_BitDepth - // - this->comboBox_BitDepth->FlatStyle = System::Windows::Forms::FlatStyle::Flat; - this->comboBox_BitDepth->FormattingEnabled = true; - this->comboBox_BitDepth->Location = System::Drawing::Point(99, 55); - this->comboBox_BitDepth->Name = L"comboBox_BitDepth"; - this->comboBox_BitDepth->Size = System::Drawing::Size(57, 21); - this->comboBox_BitDepth->TabIndex = 102; - // - // comboBox_RefreshRate - // - this->comboBox_RefreshRate->FlatStyle = System::Windows::Forms::FlatStyle::Flat; - this->comboBox_RefreshRate->FormattingEnabled = true; - this->comboBox_RefreshRate->Location = System::Drawing::Point(99, 81); - this->comboBox_RefreshRate->Name = L"comboBox_RefreshRate"; - this->comboBox_RefreshRate->Size = System::Drawing::Size(57, 21); - this->comboBox_RefreshRate->TabIndex = 103; - // - // label_BitDepth - // - this->label_BitDepth->Anchor = System::Windows::Forms::AnchorStyles::Left; - this->label_BitDepth->AutoSize = true; - this->label_BitDepth->FlatStyle = System::Windows::Forms::FlatStyle::Flat; - this->label_BitDepth->Location = System::Drawing::Point(3, 58); - this->label_BitDepth->Name = L"label_BitDepth"; - this->label_BitDepth->Size = System::Drawing::Size(54, 13); - this->label_BitDepth->TabIndex = 104; - this->label_BitDepth->Text = L"Bit Depth:"; + this->panel_ScreenRes->Location = System::Drawing::Point(4, 19); + this->panel_ScreenRes->Name = L"panel_ScreenRes"; + this->panel_ScreenRes->Size = System::Drawing::Size(200, 108); + this->panel_ScreenRes->TabIndex = 0; // // tabControl // this->tabControl->Appearance = System::Windows::Forms::TabAppearance::FlatButtons; this->tabControl->Controls->Add(this->tabPage_Resolution); this->tabControl->Controls->Add(this->tabPage_Patches); + this->tabControl->Controls->Add(this->tabPage_Playerdata); this->tabControl->Controls->Add(this->tabPage_Components); this->tabControl->Location = System::Drawing::Point(0, 0); this->tabControl->Name = L"tabControl"; @@ -468,7 +251,7 @@ private: System::Windows::Forms::Label^ label_BitDepth; // // groupBox_InternalRes // - this->groupBox_InternalRes->Controls->Add(this->tableLayoutPanel_IntRes); + this->groupBox_InternalRes->Controls->Add(this->panel_IntRes); this->groupBox_InternalRes->FlatStyle = System::Windows::Forms::FlatStyle::Flat; this->groupBox_InternalRes->ForeColor = System::Drawing::Color::White; this->groupBox_InternalRes->Location = System::Drawing::Point(8, 145); @@ -478,57 +261,12 @@ private: System::Windows::Forms::Label^ label_BitDepth; this->groupBox_InternalRes->TabStop = false; this->groupBox_InternalRes->Text = L"Internal Resolution"; // - // tableLayoutPanel_IntRes + // panel_IntRes // - this->tableLayoutPanel_IntRes->ColumnCount = 2; - this->tableLayoutPanel_IntRes->ColumnStyles->Add((gcnew System::Windows::Forms::ColumnStyle(System::Windows::Forms::SizeType::Percent, - 50))); - this->tableLayoutPanel_IntRes->ColumnStyles->Add((gcnew System::Windows::Forms::ColumnStyle(System::Windows::Forms::SizeType::Percent, - 50))); - this->tableLayoutPanel_IntRes->Controls->Add(this->comboBox_intResolution, 1, 1); - this->tableLayoutPanel_IntRes->Controls->Add(this->checkBox_InternalRes, 0, 0); - this->tableLayoutPanel_IntRes->Controls->Add(this->label_intResolution, 0, 1); - this->tableLayoutPanel_IntRes->Location = System::Drawing::Point(6, 19); - this->tableLayoutPanel_IntRes->Name = L"tableLayoutPanel_IntRes"; - this->tableLayoutPanel_IntRes->RowCount = 2; - this->tableLayoutPanel_IntRes->RowStyles->Add((gcnew System::Windows::Forms::RowStyle(System::Windows::Forms::SizeType::Percent, - 50))); - this->tableLayoutPanel_IntRes->RowStyles->Add((gcnew System::Windows::Forms::RowStyle(System::Windows::Forms::SizeType::Percent, - 50))); - this->tableLayoutPanel_IntRes->Size = System::Drawing::Size(196, 57); - this->tableLayoutPanel_IntRes->TabIndex = 24; - // - // comboBox_intResolution - // - this->comboBox_intResolution->FlatStyle = System::Windows::Forms::FlatStyle::Flat; - this->comboBox_intResolution->FormattingEnabled = true; - this->comboBox_intResolution->Location = System::Drawing::Point(101, 31); - this->comboBox_intResolution->Name = L"comboBox_intResolution"; - this->comboBox_intResolution->Size = System::Drawing::Size(85, 21); - this->comboBox_intResolution->TabIndex = 23; - // - // checkBox_InternalRes - // - this->checkBox_InternalRes->Anchor = System::Windows::Forms::AnchorStyles::Left; - this->checkBox_InternalRes->AutoSize = true; - this->checkBox_InternalRes->FlatStyle = System::Windows::Forms::FlatStyle::Flat; - this->checkBox_InternalRes->Location = System::Drawing::Point(3, 5); - this->checkBox_InternalRes->Name = L"checkBox_InternalRes"; - this->checkBox_InternalRes->Size = System::Drawing::Size(56, 17); - this->checkBox_InternalRes->TabIndex = 21; - this->checkBox_InternalRes->Text = L"Enable"; - this->checkBox_InternalRes->CheckedChanged += gcnew System::EventHandler(this, &ui::CheckBox_InternalRes_CheckedChanged); - // - // label_intResolution - // - this->label_intResolution->Anchor = System::Windows::Forms::AnchorStyles::Left; - this->label_intResolution->AutoSize = true; - this->label_intResolution->FlatStyle = System::Windows::Forms::FlatStyle::Flat; - this->label_intResolution->Location = System::Drawing::Point(3, 36); - this->label_intResolution->Name = L"label_intResolution"; - this->label_intResolution->Size = System::Drawing::Size(60, 13); - this->label_intResolution->TabIndex = 22; - this->label_intResolution->Text = L"Resolution:"; + this->panel_IntRes->Location = System::Drawing::Point(4, 19); + this->panel_IntRes->Name = L"panel_IntRes"; + this->panel_IntRes->Size = System::Drawing::Size(200, 58); + this->panel_IntRes->TabIndex = 1; // // tabPage_Patches // @@ -544,230 +282,29 @@ private: System::Windows::Forms::Label^ label_BitDepth; // panel_Patches // this->panel_Patches->AutoScroll = true; - this->panel_Patches->Controls->Add(this->panel_innerPatches); this->panel_Patches->Location = System::Drawing::Point(0, 0); this->panel_Patches->Name = L"panel_Patches"; this->panel_Patches->Size = System::Drawing::Size(225, 232); this->panel_Patches->TabIndex = 9; // - // panel_innerPatches + // tabPage_Playerdata // - this->panel_innerPatches->Controls->Add(this->checkBox_SkipLauncher); - this->panel_innerPatches->Controls->Add(this->checkBox_DisableErrorBanner); - this->panel_innerPatches->Controls->Add(this->checkBox_NoMovies); - this->panel_innerPatches->Controls->Add(this->checkBox_Cursor); - this->panel_innerPatches->Controls->Add(this->tableLayoutPanel_FPSLimit); - this->panel_innerPatches->Controls->Add(this->checkBox_TAA); - this->panel_innerPatches->Controls->Add(this->tableLayoutPanel_Status); - this->panel_innerPatches->Controls->Add(this->checkBox_MLAA); - this->panel_innerPatches->Controls->Add(this->checkBox_HideFreeplay); - this->panel_innerPatches->Controls->Add(this->checkBox_HidePVWatermark); - this->panel_innerPatches->Controls->Add(this->checkBox_HideVolCtrl); - this->panel_innerPatches->Controls->Add(this->checkBox_NoLyrics); - this->panel_innerPatches->Controls->Add(this->checkBox_NoPVUi); - this->panel_innerPatches->Location = System::Drawing::Point(2, 2); - this->panel_innerPatches->Margin = System::Windows::Forms::Padding(2); - this->panel_innerPatches->Name = L"panel_innerPatches"; - this->panel_innerPatches->Size = System::Drawing::Size(204, 311); - this->panel_innerPatches->TabIndex = 115; + this->tabPage_Playerdata->BackColor = System::Drawing::Color::FromArgb(static_cast(static_cast(64)), + static_cast(static_cast(64)), static_cast(static_cast(64))); + this->tabPage_Playerdata->Controls->Add(this->panel_Playerdata); + this->tabPage_Playerdata->Location = System::Drawing::Point(4, 25); + this->tabPage_Playerdata->Name = L"tabPage_Playerdata"; + this->tabPage_Playerdata->Size = System::Drawing::Size(225, 232); + this->tabPage_Playerdata->TabIndex = 3; + this->tabPage_Playerdata->Text = L"Player Data"; // - // checkBox_SkipLauncher + // panel_Playerdata // - this->checkBox_SkipLauncher->AutoSize = true; - this->checkBox_SkipLauncher->FlatStyle = System::Windows::Forms::FlatStyle::Flat; - this->checkBox_SkipLauncher->Location = System::Drawing::Point(3, 227); - this->checkBox_SkipLauncher->Name = L"checkBox_SkipLauncher"; - this->checkBox_SkipLauncher->Size = System::Drawing::Size(92, 17); - this->checkBox_SkipLauncher->TabIndex = 116; - this->checkBox_SkipLauncher->Text = L"Skip Launcher"; - // - // checkBox_DisableErrorBanner - // - this->checkBox_DisableErrorBanner->AutoSize = true; - this->checkBox_DisableErrorBanner->FlatStyle = System::Windows::Forms::FlatStyle::Flat; - this->checkBox_DisableErrorBanner->Location = System::Drawing::Point(3, 204); - this->checkBox_DisableErrorBanner->Name = L"checkBox_DisableErrorBanner"; - this->checkBox_DisableErrorBanner->Size = System::Drawing::Size(120, 17); - this->checkBox_DisableErrorBanner->TabIndex = 115; - this->checkBox_DisableErrorBanner->Text = L"Disable Error Banner"; - // - // checkBox_NoMovies - // - this->checkBox_NoMovies->AutoSize = true; - this->checkBox_NoMovies->FlatStyle = System::Windows::Forms::FlatStyle::Flat; - this->checkBox_NoMovies->Location = System::Drawing::Point(3, 117); - this->checkBox_NoMovies->Margin = System::Windows::Forms::Padding(2); - this->checkBox_NoMovies->Name = L"checkBox_NoMovies"; - this->checkBox_NoMovies->Size = System::Drawing::Size(95, 17); - this->checkBox_NoMovies->TabIndex = 15; - this->checkBox_NoMovies->Text = L"Disable Movies"; - // - // checkBox_Cursor - // - this->checkBox_Cursor->AutoSize = true; - this->checkBox_Cursor->FlatStyle = System::Windows::Forms::FlatStyle::Flat; - this->checkBox_Cursor->Location = System::Drawing::Point(3, 3); - this->checkBox_Cursor->Name = L"checkBox_Cursor"; - this->checkBox_Cursor->Size = System::Drawing::Size(53, 17); - this->checkBox_Cursor->TabIndex = 21; - this->checkBox_Cursor->Text = L"Cursor"; - // - // tableLayoutPanel_FPSLimit - // - this->tableLayoutPanel_FPSLimit->ColumnCount = 2; - this->tableLayoutPanel_FPSLimit->ColumnStyles->Add((gcnew System::Windows::Forms::ColumnStyle(System::Windows::Forms::SizeType::Percent, - 41.4966F))); - this->tableLayoutPanel_FPSLimit->ColumnStyles->Add((gcnew System::Windows::Forms::ColumnStyle(System::Windows::Forms::SizeType::Percent, - 58.5034F))); - this->tableLayoutPanel_FPSLimit->Controls->Add(this->textBox_FPSLimit, 1, 0); - this->tableLayoutPanel_FPSLimit->Controls->Add(this->label_FPSLimit, 0, 0); - this->tableLayoutPanel_FPSLimit->Location = System::Drawing::Point(2, 281); - this->tableLayoutPanel_FPSLimit->Margin = System::Windows::Forms::Padding(2); - this->tableLayoutPanel_FPSLimit->Name = L"tableLayoutPanel_FPSLimit"; - this->tableLayoutPanel_FPSLimit->RowCount = 1; - this->tableLayoutPanel_FPSLimit->RowStyles->Add((gcnew System::Windows::Forms::RowStyle(System::Windows::Forms::SizeType::Percent, - 50))); - this->tableLayoutPanel_FPSLimit->Size = System::Drawing::Size(147, 28); - this->tableLayoutPanel_FPSLimit->TabIndex = 114; - // - // textBox_FPSLimit - // - this->textBox_FPSLimit->BorderStyle = System::Windows::Forms::BorderStyle::FixedSingle; - this->textBox_FPSLimit->Location = System::Drawing::Point(64, 3); - this->textBox_FPSLimit->MaxLength = 3; - this->textBox_FPSLimit->Name = L"textBox_FPSLimit"; - this->textBox_FPSLimit->Size = System::Drawing::Size(79, 20); - this->textBox_FPSLimit->TabIndex = 111; - this->textBox_FPSLimit->TextChanged += gcnew System::EventHandler(this, &ui::TextBox_FPSLimit_TextChanged); - this->textBox_FPSLimit->KeyPress += gcnew System::Windows::Forms::KeyPressEventHandler(this, &ui::TextBox_FPSLimit_KeyPress); - // - // label_FPSLimit - // - this->label_FPSLimit->Anchor = System::Windows::Forms::AnchorStyles::Left; - this->label_FPSLimit->AutoSize = true; - this->label_FPSLimit->FlatStyle = System::Windows::Forms::FlatStyle::Flat; - this->label_FPSLimit->Location = System::Drawing::Point(3, 7); - this->label_FPSLimit->Name = L"label_FPSLimit"; - this->label_FPSLimit->Size = System::Drawing::Size(54, 13); - this->label_FPSLimit->TabIndex = 110; - this->label_FPSLimit->Text = L"FPS Limit:"; - this->label_FPSLimit->TextAlign = System::Drawing::ContentAlignment::MiddleLeft; - // - // checkBox_TAA - // - this->checkBox_TAA->AutoSize = true; - this->checkBox_TAA->FlatStyle = System::Windows::Forms::FlatStyle::Flat; - this->checkBox_TAA->Location = System::Drawing::Point(3, 26); - this->checkBox_TAA->Name = L"checkBox_TAA"; - this->checkBox_TAA->Size = System::Drawing::Size(44, 17); - this->checkBox_TAA->TabIndex = 31; - this->checkBox_TAA->Text = L"TAA"; - // - // tableLayoutPanel_Status - // - this->tableLayoutPanel_Status->ColumnCount = 2; - this->tableLayoutPanel_Status->ColumnStyles->Add((gcnew System::Windows::Forms::ColumnStyle(System::Windows::Forms::SizeType::Percent, - 42.85714F))); - this->tableLayoutPanel_Status->ColumnStyles->Add((gcnew System::Windows::Forms::ColumnStyle(System::Windows::Forms::SizeType::Percent, - 57.14286F))); - this->tableLayoutPanel_Status->Controls->Add(this->label_StatusIcons, 0, 0); - this->tableLayoutPanel_Status->Controls->Add(this->comboBox_StatusIcons, 1, 0); - this->tableLayoutPanel_Status->Location = System::Drawing::Point(2, 249); - this->tableLayoutPanel_Status->Margin = System::Windows::Forms::Padding(2); - this->tableLayoutPanel_Status->Name = L"tableLayoutPanel_Status"; - this->tableLayoutPanel_Status->RowCount = 1; - this->tableLayoutPanel_Status->RowStyles->Add((gcnew System::Windows::Forms::RowStyle(System::Windows::Forms::SizeType::Percent, - 50))); - this->tableLayoutPanel_Status->Size = System::Drawing::Size(147, 28); - this->tableLayoutPanel_Status->TabIndex = 113; - // - // label_StatusIcons - // - this->label_StatusIcons->Anchor = System::Windows::Forms::AnchorStyles::Left; - this->label_StatusIcons->AutoSize = true; - this->label_StatusIcons->FlatStyle = System::Windows::Forms::FlatStyle::Flat; - this->label_StatusIcons->Location = System::Drawing::Point(3, 1); - this->label_StatusIcons->Name = L"label_StatusIcons"; - this->label_StatusIcons->Size = System::Drawing::Size(40, 26); - this->label_StatusIcons->TabIndex = 80; - this->label_StatusIcons->Text = L"Status Icons:"; - this->label_StatusIcons->TextAlign = System::Drawing::ContentAlignment::MiddleLeft; - // - // comboBox_StatusIcons - // - this->comboBox_StatusIcons->DropDownStyle = System::Windows::Forms::ComboBoxStyle::DropDownList; - this->comboBox_StatusIcons->FlatStyle = System::Windows::Forms::FlatStyle::Flat; - this->comboBox_StatusIcons->FormattingEnabled = true; - this->comboBox_StatusIcons->Items->AddRange(gcnew cli::array< System::Object^ >(5) { - L"Default", L"Hidden", L"Error", L"OK", - L"Partial OK" - }); - this->comboBox_StatusIcons->Location = System::Drawing::Point(65, 3); - this->comboBox_StatusIcons->Name = L"comboBox_StatusIcons"; - this->comboBox_StatusIcons->Size = System::Drawing::Size(79, 21); - this->comboBox_StatusIcons->TabIndex = 101; - // - // checkBox_MLAA - // - this->checkBox_MLAA->AutoSize = true; - this->checkBox_MLAA->FlatStyle = System::Windows::Forms::FlatStyle::Flat; - this->checkBox_MLAA->Location = System::Drawing::Point(3, 49); - this->checkBox_MLAA->Name = L"checkBox_MLAA"; - this->checkBox_MLAA->Size = System::Drawing::Size(52, 17); - this->checkBox_MLAA->TabIndex = 41; - this->checkBox_MLAA->Text = L"MLAA"; - // - // checkBox_HideFreeplay - // - this->checkBox_HideFreeplay->AutoSize = true; - this->checkBox_HideFreeplay->FlatStyle = System::Windows::Forms::FlatStyle::Flat; - this->checkBox_HideFreeplay->Location = System::Drawing::Point(3, 72); - this->checkBox_HideFreeplay->Name = L"checkBox_HideFreeplay"; - this->checkBox_HideFreeplay->Size = System::Drawing::Size(101, 17); - this->checkBox_HideFreeplay->TabIndex = 51; - this->checkBox_HideFreeplay->Text = L"Hide Freeplay"; - // - // checkBox_HidePVWatermark - // - this->checkBox_HidePVWatermark->AutoSize = true; - this->checkBox_HidePVWatermark->FlatStyle = System::Windows::Forms::FlatStyle::Flat; - this->checkBox_HidePVWatermark->Location = System::Drawing::Point(3, 181); - this->checkBox_HidePVWatermark->Name = L"checkBox_HidePVWatermark"; - this->checkBox_HidePVWatermark->Size = System::Drawing::Size(117, 17); - this->checkBox_HidePVWatermark->TabIndex = 91; - this->checkBox_HidePVWatermark->Text = L"Hide PV Watermark"; - // - // checkBox_HideVolCtrl - // - this->checkBox_HideVolCtrl->AutoSize = true; - this->checkBox_HideVolCtrl->FlatStyle = System::Windows::Forms::FlatStyle::Flat; - this->checkBox_HideVolCtrl->Location = System::Drawing::Point(3, 95); - this->checkBox_HideVolCtrl->Name = L"checkBox_HideVolCtrl"; - this->checkBox_HideVolCtrl->Size = System::Drawing::Size(122, 17); - this->checkBox_HideVolCtrl->TabIndex = 61; - this->checkBox_HideVolCtrl->Text = L"Hide Volume Buttons"; - // - // checkBox_NoLyrics - // - this->checkBox_NoLyrics->AutoSize = true; - this->checkBox_NoLyrics->FlatStyle = System::Windows::Forms::FlatStyle::Flat; - this->checkBox_NoLyrics->Location = System::Drawing::Point(3, 159); - this->checkBox_NoLyrics->Margin = System::Windows::Forms::Padding(2); - this->checkBox_NoLyrics->Name = L"checkBox_NoLyrics"; - this->checkBox_NoLyrics->Size = System::Drawing::Size(88, 17); - this->checkBox_NoLyrics->TabIndex = 81; - this->checkBox_NoLyrics->Text = L"Disable Lyrics"; - // - // checkBox_NoPVUi - // - this->checkBox_NoPVUi->AutoSize = true; - this->checkBox_NoPVUi->FlatStyle = System::Windows::Forms::FlatStyle::Flat; - this->checkBox_NoPVUi->Location = System::Drawing::Point(3, 138); - this->checkBox_NoPVUi->Margin = System::Windows::Forms::Padding(2); - this->checkBox_NoPVUi->Name = L"checkBox_NoPVUi"; - this->checkBox_NoPVUi->Size = System::Drawing::Size(89, 17); - this->checkBox_NoPVUi->TabIndex = 71; - this->checkBox_NoPVUi->Text = L"Disable PV UI"; + this->panel_Playerdata->AutoScroll = true; + this->panel_Playerdata->Location = System::Drawing::Point(0, 0); + this->panel_Playerdata->Name = L"panel_Playerdata"; + this->panel_Playerdata->Size = System::Drawing::Size(225, 232); + this->panel_Playerdata->TabIndex = 1; // // tabPage_Components // @@ -849,123 +386,40 @@ private: System::Windows::Forms::Label^ label_BitDepth; this->FormClosed += gcnew System::Windows::Forms::FormClosedEventHandler(this, &ui::Ui_FormClosed); this->Load += gcnew System::EventHandler(this, &ui::Ui_Load); this->groupBox_ScreenRes->ResumeLayout(false); - this->tableLayoutPanel_ScreenRes->ResumeLayout(false); - this->tableLayoutPanel_ScreenRes->PerformLayout(); this->tabControl->ResumeLayout(false); this->tabPage_Resolution->ResumeLayout(false); this->groupBox_InternalRes->ResumeLayout(false); - this->tableLayoutPanel_IntRes->ResumeLayout(false); - this->tableLayoutPanel_IntRes->PerformLayout(); this->tabPage_Patches->ResumeLayout(false); - this->panel_Patches->ResumeLayout(false); - this->panel_innerPatches->ResumeLayout(false); - this->panel_innerPatches->PerformLayout(); - this->tableLayoutPanel_FPSLimit->ResumeLayout(false); - this->tableLayoutPanel_FPSLimit->PerformLayout(); - this->tableLayoutPanel_Status->ResumeLayout(false); - this->tableLayoutPanel_Status->PerformLayout(); + this->tabPage_Playerdata->ResumeLayout(false); this->tabPage_Components->ResumeLayout(false); this->ResumeLayout(false); } #pragma endregion -private: System::Void SaveSettings() { - String^ userInput = Convert::ToInt32(comboBox_Display->SelectedIndex).ToString(); - wstring input = msclr::interop::marshal_as(userInput); - WritePrivateProfileStringW(L"resolution", L"display", input.c_str(), CONFIG_FILE); - - userInput = comboBox_Resolution->Text; - cli::array^ ResolutionArray = userInput->Split('x'); - userInput = ResolutionArray[0]; - input = msclr::interop::marshal_as(userInput); - WritePrivateProfileStringW(L"resolution", L"width", input.c_str(), CONFIG_FILE); - - userInput = comboBox_Resolution->Text; - ResolutionArray = userInput->Split('x'); - userInput = ResolutionArray[1]; - input = msclr::interop::marshal_as(userInput); - WritePrivateProfileStringW(L"resolution", L"height", input.c_str(), CONFIG_FILE); - - userInput = Convert::ToInt32(checkBox_InternalRes->Checked).ToString(); - input = msclr::interop::marshal_as(userInput); - WritePrivateProfileStringW(L"resolution", L"r.enable", input.c_str(), CONFIG_FILE); - - userInput = comboBox_intResolution->Text; - cli::array^ intResolutionArray = userInput->Split('x'); - userInput = intResolutionArray[0]; - input = msclr::interop::marshal_as(userInput); - WritePrivateProfileStringW(L"resolution", L"r.width", input.c_str(), CONFIG_FILE); - - userInput = comboBox_BitDepth->Text; - input = msclr::interop::marshal_as(userInput); - WritePrivateProfileStringW(L"resolution", L"bitdepth", input.c_str(), CONFIG_FILE); - - userInput = comboBox_RefreshRate->Text; - input = msclr::interop::marshal_as(userInput); - WritePrivateProfileStringW(L"resolution", L"refreshrate", input.c_str(), CONFIG_FILE); - - userInput = comboBox_intResolution->Text; - intResolutionArray = userInput->Split('x'); - userInput = intResolutionArray[1]; - input = msclr::interop::marshal_as(userInput); - WritePrivateProfileStringW(L"resolution", L"r.height", input.c_str(), CONFIG_FILE); - - userInput = Convert::ToInt32(checkBox_Cursor->Checked).ToString(); - input = msclr::interop::marshal_as(userInput); - WritePrivateProfileStringW(L"patches", L"cursor", input.c_str(), CONFIG_FILE); - - userInput = Convert::ToInt32(checkBox_HideFreeplay->Checked).ToString(); - input = msclr::interop::marshal_as(userInput); - WritePrivateProfileStringW(L"patches", L"hide_freeplay", input.c_str(), CONFIG_FILE); - - userInput = Convert::ToInt32(comboBox_StatusIcons->SelectedIndex).ToString(); - input = msclr::interop::marshal_as(userInput); - WritePrivateProfileStringW(L"patches", L"status_icons", input.c_str(), CONFIG_FILE); - - userInput = Convert::ToInt32(checkBox_HidePVWatermark->Checked).ToString(); - input = msclr::interop::marshal_as(userInput); - WritePrivateProfileStringW(L"patches", L"hide_pv_watermark", input.c_str(), CONFIG_FILE); - - userInput = Convert::ToInt32(checkBox_NoPVUi->Checked).ToString(); - input = msclr::interop::marshal_as(userInput); - WritePrivateProfileStringW(L"patches", L"no_pv_ui", input.c_str(), CONFIG_FILE); - - userInput = Convert::ToInt32(checkBox_NoLyrics->Checked).ToString(); - input = msclr::interop::marshal_as(userInput); - WritePrivateProfileStringW(L"patches", L"no_lyrics", input.c_str(), CONFIG_FILE); - - userInput = Convert::ToInt32(checkBox_NoMovies->Checked).ToString(); - input = msclr::interop::marshal_as(userInput); - WritePrivateProfileStringW(L"patches", L"no_movies", input.c_str(), CONFIG_FILE); - - userInput = Convert::ToInt32(checkBox_HideVolCtrl->Checked).ToString(); - input = msclr::interop::marshal_as(userInput); - WritePrivateProfileStringW(L"patches", L"hide_volume", input.c_str(), CONFIG_FILE); - - userInput = Convert::ToInt32(checkBox_DisableErrorBanner->Checked).ToString(); - input = msclr::interop::marshal_as(userInput); - WritePrivateProfileStringW(L"patches", L"no_error", input.c_str(), CONFIG_FILE); - - userInput = Convert::ToInt32(checkBox_TAA->Checked).ToString(); - input = msclr::interop::marshal_as(userInput); - WritePrivateProfileStringW(L"graphics", L"TAA", input.c_str(), CONFIG_FILE); - - userInput = Convert::ToInt32(checkBox_MLAA->Checked).ToString(); - input = msclr::interop::marshal_as(userInput); - WritePrivateProfileStringW(L"graphics", L"MLAA", input.c_str(), CONFIG_FILE); - - userInput = textBox_FPSLimit->Text; - input = msclr::interop::marshal_as(userInput); - WritePrivateProfileStringW(L"graphics", L"FPS.Limit", input.c_str(), CONFIG_FILE); - - userInput = Convert::ToInt32(checkBox_SkipLauncher->Checked).ToString(); - input = msclr::interop::marshal_as(userInput); - WritePrivateProfileStringW(L"launcher", L"skip", input.c_str(), CONFIG_FILE); - - for (componentInfo& component : componentsArray) +private: System::Void SaveSettings() { + for (ConfigOptionBase* option : screenResolutionArray) { - bool enabled = ((CheckBox^)CheckBox::FromHandle(component.cb))->Checked; - WritePrivateProfileStringW(L"components", component.name, enabled ? L"true" : L"false", COMPONENTS_FILE); + option->SaveOption(); + } + + for (ConfigOptionBase* option : internalResolutionArray) + { + option->SaveOption(); + } + + for (ConfigOptionBase* option : optionsArray) + { + option->SaveOption(); + } + + for (ConfigOptionBase* option : playerdataArray) + { + option->SaveOption(); + } + + for (ConfigOptionBase* component : componentsArray) + { + component->SaveOption(); } } private: System::Void Ui_Load(System::Object^ sender, System::EventArgs^ e){ @@ -977,6 +431,14 @@ private: System::Void Button_Launch_Click(System::Object^ sender, System::EventA SaveSettings(); + // read the command line here so it'll be up to date even if the user changed it + WCHAR stringBuf[256]; + GetPrivateProfileStringW(LAUNCHER_SECTION, L"command_line", L"", stringBuf, 256, CONFIG_FILE); + + DIVA_EXECUTABLE_LAUNCH_STRING += L" " + wstring(stringBuf); + DIVA_EXECUTABLE_LAUNCH = const_cast(DIVA_EXECUTABLE_LAUNCH_STRING.c_str()); + + STARTUPINFOW si; PROCESS_INFORMATION pi; @@ -988,34 +450,47 @@ private: System::Void Button_Launch_Click(System::Object^ sender, System::EventA // this->Close won't work in here since it will prompt the user to save the settings TerminateProcess(GetCurrentProcess(), EXIT_SUCCESS); } -private: System::Void CheckBox_InternalRes_CheckedChanged(System::Object^ sender, System::EventArgs^ e) { - if (checkBox_InternalRes->Checked) +private: System::Void InternalResEnabledChangedHandler(System::Object^ sender, System::EventArgs^ e) { + if (((CheckBox^)CheckBox::FromHandle(InternalResolutionCheckbox->mainControlHandle))->Checked) { - comboBox_intResolution->Enabled = true; + ((Control^)Control::FromHandle(InternalResolutionOption->mainControlHandle))->Enabled = true; } else { - comboBox_intResolution->Enabled = false; + ((Control^)Control::FromHandle(InternalResolutionOption->mainControlHandle))->Enabled = false; } } -private: System::Void ComboBox_Display_SelectedIndexChanged(System::Object^ sender, System::EventArgs^ e) { - if (comboBox_Display->SelectedIndex == 0 || comboBox_Display->SelectedIndex == 2) +private: System::Void DisplayTypeChangedHandler(System::Object^ sender, System::EventArgs^ e) { + int idx = ((ComboBox^)ComboBox::FromHandle(DisplayModeDropdown->mainControlHandle))->SelectedIndex; + + if (idx == 0 || idx == 2) // windowed or fullscreen { - comboBox_Resolution->Enabled = true; + ((Control^)Control::FromHandle(DisplayResolutionOption->mainControlHandle))->Enabled = true; } else { - comboBox_Resolution->Enabled = false; + ((Control^)Control::FromHandle(DisplayResolutionOption->mainControlHandle))->Enabled = false; } - if (comboBox_Display->SelectedIndex == 2) + + if (idx == 2) // fullscreen { - comboBox_BitDepth->Enabled = true; - comboBox_RefreshRate->Enabled = true; + for (ConfigOptionBase* option : screenResolutionArray) + { + if (option != DisplayModeDropdown && option != DisplayResolutionOption) + { + ((Control^)Control::FromHandle(option->mainControlHandle))->Enabled = true; + } + } } else { - comboBox_BitDepth->Enabled = false; - comboBox_RefreshRate->Enabled = false; + for (ConfigOptionBase* option : screenResolutionArray) + { + if (option != DisplayModeDropdown && option != DisplayResolutionOption) + { + ((Control^)Control::FromHandle(option->mainControlHandle))->Enabled = false; + } + } } } private: System::Void Ui_FormClosing(System::Object^ sender, System::Windows::Forms::FormClosingEventArgs^ e) { @@ -1040,20 +515,9 @@ private: System::Void Ui_FormClosed(System::Object^ sender, System::Windows::For private: System::Void button_Discord_Click(System::Object^ sender, System::EventArgs^ e) { System::Diagnostics::Process::Start("https://discord.gg/cvBVGDZ"); } -private: System::Void TextBox_FPSLimit_TextChanged(System::Object^ sender, System::EventArgs^ e) { - if (System::Text::RegularExpressions::Regex::IsMatch(textBox_FPSLimit->Text, " ^ [0-9]")) - { - textBox_FPSLimit->Text = ""; - } -} -private: System::Void TextBox_FPSLimit_KeyPress(System::Object^ sender, System::Windows::Forms::KeyPressEventArgs^ e) { - if (!Char::IsControl(e->KeyChar) && !Char::IsDigit(e->KeyChar) && (e->KeyChar != '.')) - { - e->Handled = true; - } -} private: System::Void button_github_Click(System::Object^ sender, System::EventArgs^ e) { System::Diagnostics::Process::Start("https://notabug.org/nastys/PD-Loader"); } + }; } diff --git a/source-code/source/plugins/Launcher/ui.resx b/source-code/source/plugins/Launcher/ui.resx index 641132d..72c6630 100644 --- a/source-code/source/plugins/Launcher/ui.resx +++ b/source-code/source/plugins/Launcher/ui.resx @@ -166,6 +166,9 @@ rkJggg== + + 17, 17 + iVBORw0KGgoAAAANSUhEUgAAAuQAAAJYCAYAAAAqrPNrAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAL