Merge somewhatlurker's changes to the launcher

This commit is contained in:
nastys
2019-08-02 23:59:08 +02:00
parent 58bd356aa3
commit a8f6f1e8ea
5 changed files with 1031 additions and 761 deletions
@@ -0,0 +1,703 @@
#pragma once
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
// Windows Header Files
#include <windows.h>
#include <string>
#include <fstream>
#include <vector>
#include <msclr\marshal_cppstd.h>
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<Char>^ digitsarray = gcnew cli::array<Char>{ L'0', L'1', L'2', L'3', L'4', L'5', L'6', L'7', L'8', L'9' };
System::Collections::Generic::List<Char>^ digitslist = gcnew System::Collections::Generic::List<Char>(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<Char>^ digitsarray = gcnew cli::array<Char>{ L'0', L'1', L'2', L'3', L'4', L'5', L'6', L'7', L'8', L'9' };
System::Collections::Generic::List<Char>^ digitslist = gcnew System::Collections::Generic::List<Char>(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<std::wstring>(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<std::wstring>(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<LPCWSTR> _valueStrings;
DropdownOption(LPCWSTR iniVarName, LPCWSTR iniSectionName, LPCWSTR iniFilePath, LPCWSTR friendlyName, LPCWSTR description, int defaultVal, std::vector<LPCWSTR> 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<System::String^>(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<std::wstring>(tempSysStr);
WritePrivateProfileStringW(_iniSectionName, _iniVarName, tempWStr.c_str(), _iniFilePath);
}
};
class EditableDropdownOption : public ConfigOptionBase
{
public:
LPCWSTR _defaultVal;
std::vector<LPCWSTR> _valueStrings;
bool _useUtf8;
EditableDropdownOption(LPCWSTR iniVarName, LPCWSTR iniSectionName, LPCWSTR iniFilePath, LPCWSTR friendlyName, LPCWSTR description, LPCWSTR defaultVal, std::vector<LPCWSTR> 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<System::String^>(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<std::wstring>(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<int> _valueInts;
EditableDropdownNumberOption(LPCWSTR iniVarName, LPCWSTR iniSectionName, LPCWSTR iniFilePath, LPCWSTR friendlyName, LPCWSTR description, int defaultVal, std::vector<int> 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<std::wstring>(tempSysStr);
WritePrivateProfileStringW(_iniSectionName, _iniVarName, tempWStr.c_str(), _iniFilePath);
}
};
class ResolutionOption : public ConfigOptionBase
{
public:
LPCWSTR _iniVarName2;
resolution _defaultVal;
std::vector<resolution> _valueResolutions;
ResolutionOption(LPCWSTR iniVarName, LPCWSTR iniVarName2, LPCWSTR iniSectionName, LPCWSTR iniFilePath, LPCWSTR friendlyName, LPCWSTR description, resolution defaultVal, std::vector<resolution> 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<String^>^ resolutionArray;
tempSysStr = ((ComboBox^)ComboBox::FromHandle(mainControlHandle))->Text;
resolutionArray = tempSysStr->Split('x');
tempSysStr = resolutionArray[0];
tempWStr = msclr::interop::marshal_as<std::wstring>(tempSysStr);
WritePrivateProfileStringW(_iniSectionName, _iniVarName, tempWStr.c_str(), _iniFilePath);
tempSysStr = resolutionArray[1];
tempWStr = msclr::interop::marshal_as<std::wstring>(tempSysStr);
WritePrivateProfileStringW(_iniSectionName, _iniVarName2, tempWStr.c_str(), _iniFilePath);
}
};
@@ -165,6 +165,7 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="ConfigOption.h" />
<ClInclude Include="framework.h" />
<ClInclude Include="TabPadding.h" />
<ClInclude Include="ui.h">
+155 -56
View File
@@ -1,10 +1,14 @@
#pragma once
#pragma once
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
// Windows Header Files
#include <windows.h>
#include <string>
#include <fstream>
#include <vector>
#include <algorithm>
#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<DEVMODEW> getScreenModes() {
static std::vector<DEVMODEW> outVec = std::vector<DEVMODEW>();
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<resolution> getScreenResolutionsVec(std::vector<DEVMODEW> &screenModes) {
static std::vector<resolution> outVec = std::vector<resolution>();
{ 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<int> getScreenDepthsVec(std::vector<DEVMODEW> &screenModes) {
static std::vector<int> outVec = std::vector<int>();
{ 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<int> getScreenRatesVec(std::vector<DEVMODEW> &screenModes) {
static std::vector<int> outVec = std::vector<int>();
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<DEVMODEW> screenModes = getScreenModes();
DropdownOption* DisplayModeDropdown = new DropdownOption(L"display", RESOLUTION_SECTION, CONFIG_FILE, L"Display:", L"Sets the window/screen mode.", 0, std::vector<LPCWSTR>({ 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>({ 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<LPCWSTR>({ 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)
File diff suppressed because it is too large Load Diff
@@ -166,6 +166,9 @@
rkJggg==
</value>
</data>
<metadata name="toolTip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<data name="$this.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAAuQAAAJYCAYAAAAqrPNrAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAL