Merge branch 'master' of somewhatlurker/PD-Loader into master
This commit is contained in:
@@ -158,7 +158,8 @@ void FindFiles(WIN32_FIND_DATAW* fd)
|
||||
if (fd->cFileName[pos - 4] == '.' &&
|
||||
(fd->cFileName[pos - 3] == 'd' || fd->cFileName[pos - 3] == 'D') &&
|
||||
(fd->cFileName[pos - 2] == 'v' || fd->cFileName[pos - 2] == 'V') &&
|
||||
(fd->cFileName[pos - 1] == 'a' || fd->cFileName[pos - 1] == 'A'))
|
||||
(fd->cFileName[pos - 1] == 'a' || fd->cFileName[pos - 1] == 'A') &&
|
||||
GetPrivateProfileIntW(L"plugins", fd->cFileName, TRUE, iniPaths))
|
||||
{
|
||||
auto path = dir + L'\\' + fd->cFileName;
|
||||
|
||||
|
||||
@@ -82,6 +82,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="src\framework.h" />
|
||||
<ClInclude Include="src\PluginConfigApi.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
|
||||
@@ -23,5 +23,8 @@
|
||||
<ClInclude Include="src\framework.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\PluginConfigApi.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,168 @@
|
||||
#pragma once
|
||||
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
||||
#include <windows.h>
|
||||
#include <vector>
|
||||
|
||||
// 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;
|
||||
}
|
||||
};
|
||||
|
||||
namespace PluginConfig
|
||||
{
|
||||
#pragma pack(push, 1)
|
||||
enum ConfigType {
|
||||
CONFIG_BOOLEAN,
|
||||
CONFIG_NUMERIC,
|
||||
CONFIG_STRING,
|
||||
CONFIG_DROPDOWN_INDEX,
|
||||
CONFIG_DROPDOWN_TEXT,
|
||||
CONFIG_DROPDOWN_NUMBER,
|
||||
CONFIG_RESOLUTION,
|
||||
CONFIG_GROUP_START,
|
||||
CONFIG_GROUP_END,
|
||||
CONFIG_BUTTON,
|
||||
CONFIG_SPACER
|
||||
};
|
||||
|
||||
struct PluginConfigBooleanData {
|
||||
LPCWSTR iniVarName;
|
||||
LPCWSTR iniSectionName;
|
||||
LPCWSTR iniFilePath;
|
||||
LPCWSTR friendlyName;
|
||||
LPCWSTR description;
|
||||
bool defaultVal;
|
||||
bool saveAsString;
|
||||
};
|
||||
|
||||
struct PluginConfigNumericData {
|
||||
LPCWSTR iniVarName;
|
||||
LPCWSTR iniSectionName;
|
||||
LPCWSTR iniFilePath;
|
||||
LPCWSTR friendlyName;
|
||||
LPCWSTR description;
|
||||
int defaultVal;
|
||||
int minVal;
|
||||
int maxVal;
|
||||
};
|
||||
|
||||
struct PluginConfigStringData {
|
||||
LPCWSTR iniVarName;
|
||||
LPCWSTR iniSectionName;
|
||||
LPCWSTR iniFilePath;
|
||||
LPCWSTR friendlyName;
|
||||
LPCWSTR description;
|
||||
LPCWSTR defaultVal;
|
||||
bool useUtf8;
|
||||
};
|
||||
|
||||
struct PluginConfigDropdownIndexData {
|
||||
LPCWSTR iniVarName;
|
||||
LPCWSTR iniSectionName;
|
||||
LPCWSTR iniFilePath;
|
||||
LPCWSTR friendlyName;
|
||||
LPCWSTR description;
|
||||
int defaultVal;
|
||||
std::vector<LPCWSTR> valueStrings;
|
||||
};
|
||||
|
||||
struct PluginConfigDropdownTextData {
|
||||
LPCWSTR iniVarName;
|
||||
LPCWSTR iniSectionName;
|
||||
LPCWSTR iniFilePath;
|
||||
LPCWSTR friendlyName;
|
||||
LPCWSTR description;
|
||||
LPCWSTR defaultVal;
|
||||
std::vector<LPCWSTR> valueStrings;
|
||||
bool editable;
|
||||
bool useUtf8;
|
||||
};
|
||||
|
||||
struct PluginConfigDropdownNumberData {
|
||||
LPCWSTR iniVarName;
|
||||
LPCWSTR iniSectionName;
|
||||
LPCWSTR iniFilePath;
|
||||
LPCWSTR friendlyName;
|
||||
LPCWSTR description;
|
||||
int defaultVal;
|
||||
std::vector<int> valueInts;
|
||||
bool editable;
|
||||
};
|
||||
|
||||
struct PluginConfigResolutionData {
|
||||
LPCWSTR iniVarName;
|
||||
LPCWSTR iniVarName2;
|
||||
LPCWSTR iniSectionName;
|
||||
LPCWSTR iniFilePath;
|
||||
LPCWSTR friendlyName;
|
||||
LPCWSTR description;
|
||||
resolution defaultVal;
|
||||
std::vector<resolution> valueResolutions;
|
||||
bool editable;
|
||||
};
|
||||
|
||||
struct PluginConfigGroupData
|
||||
{
|
||||
LPCWSTR name;
|
||||
int height;
|
||||
};
|
||||
|
||||
struct PluginConfigButtonData {
|
||||
LPCWSTR friendlyName;
|
||||
LPCWSTR description;
|
||||
void(*func)();
|
||||
};
|
||||
|
||||
struct PluginConfigSpacerData {
|
||||
int height;
|
||||
};
|
||||
|
||||
struct PluginConfigOption
|
||||
{
|
||||
ConfigType cfgType;
|
||||
void* data;
|
||||
};
|
||||
|
||||
struct PluginConfigArray
|
||||
{
|
||||
int len;
|
||||
PluginConfigOption* options;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "framework.h"
|
||||
#include "PluginConfigApi.h"
|
||||
#include <detours.h>
|
||||
#pragma comment(lib, "detours.lib")
|
||||
|
||||
@@ -7,6 +8,7 @@
|
||||
#include <vector>
|
||||
#include <strsafe.h>
|
||||
#include <bassasio.h>
|
||||
#include <shellapi.h>
|
||||
|
||||
void InjectCode(void* address, const std::vector<uint8_t> data)
|
||||
{
|
||||
@@ -410,3 +412,37 @@ BOOL APIENTRY DllMain(HMODULE hModule,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
using namespace PluginConfig;
|
||||
|
||||
void OpenWiki()
|
||||
{
|
||||
ShellExecuteW(NULL, L"open", L"https://github.com/somewhatlurker/DivaSound/wiki", NULL, NULL, SW_SHOW);
|
||||
}
|
||||
|
||||
PluginConfigOption config[] = {
|
||||
{ CONFIG_DROPDOWN_TEXT, new PluginConfigDropdownTextData{L"backend", L"general", CONFIG_FILE, L"Backend:", L"Sets the audio output protocol.", L"WASAPI", std::vector<LPCWSTR>({ L"WASAPI", L"WASAPI_Exclusive" }), true, false } },
|
||||
{ CONFIG_DROPDOWN_NUMBER, new PluginConfigDropdownNumberData{ L"channels", L"general", CONFIG_FILE, L"Channels:", L"Sets the number of channels.", 2, std::vector<int>({ 2, 4 }), false } },
|
||||
{ CONFIG_DROPDOWN_NUMBER, new PluginConfigDropdownNumberData{ L"bit_depth", L"general", CONFIG_FILE, L"Bit Depth:", L"Sets the audio sample format.\n(32 uses floating point samples)", 16, std::vector<int>({ 16, 24, 32 }), false } },
|
||||
{ CONFIG_NUMERIC, new PluginConfigNumericData{ L"buffer_size", L"buffer", CONFIG_FILE, L"Target Buffer Size:", L"Sets the target buffer size in ms.\nWASAPI will often ignore this and adapt to your hardware config automatically.", 10, 1, 100 } },
|
||||
{ CONFIG_NUMERIC, new PluginConfigNumericData{ L"periods", L"buffer", CONFIG_FILE, L"Buffer Periods:", L"Sets how often the buffer should be filled.\nFewer periods usually allows for lower latency, but lowering this may cause issues.", 2, 1, 8 } },
|
||||
{ CONFIG_BOOLEAN, new PluginConfigBooleanData{ L"alternate_init", L"general", CONFIG_FILE, L"Use new init", L"Use the full initialisation replacement.\nTry unchecking this if DivaSound seems to cause crashes.", true } },
|
||||
{ CONFIG_SPACER, new PluginConfigSpacerData{ 8 } },
|
||||
{ CONFIG_BUTTON, new PluginConfigButtonData{ L"Help", L"Get help on the DivaSound wiki.", OpenWiki } },
|
||||
{ CONFIG_SPACER, new PluginConfigSpacerData{ 8 } },
|
||||
};
|
||||
|
||||
extern "C" __declspec(dllexport) LPCWSTR GetPluginName(void)
|
||||
{
|
||||
return L"DivaSound";
|
||||
}
|
||||
|
||||
extern "C" __declspec(dllexport) LPCWSTR GetPluginDescription(void)
|
||||
{
|
||||
return L"DivaSound Plugin by somewhatlurker\n\nDivaSound replaces the game's original audio output,\nimproving device support and adding configurable options.";
|
||||
}
|
||||
|
||||
extern "C" __declspec(dllexport) PluginConfigArray GetPluginOptions(void)
|
||||
{
|
||||
return PluginConfigArray{ _countof(config), config };
|
||||
}
|
||||
@@ -9,6 +9,8 @@
|
||||
|
||||
#include <msclr\marshal_cppstd.h>
|
||||
|
||||
#include "PluginConfigApi.h"
|
||||
|
||||
using namespace System;
|
||||
using namespace System::Windows::Forms;
|
||||
|
||||
@@ -16,6 +18,7 @@ float BaseScaleSize = 96;
|
||||
int Col1Width = 110;
|
||||
int Col2Left = 114;
|
||||
int Col2Width = 110;
|
||||
int ConfigBtnLeft = 160;
|
||||
int ControlSpacing = 6;
|
||||
|
||||
// Custom function. Works like GetPrivateProfileIntW but returns bool. Can detect a numeric value or string.
|
||||
@@ -39,46 +42,9 @@ bool GetPrivateProfileBoolW(LPCWSTR lpAppName, LPCWSTR lpKeyName, bool 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;
|
||||
}
|
||||
};
|
||||
// declare this early (actual definitions below)
|
||||
class ConfigOptionBase;
|
||||
Panel^ MakePanel(int width, int height, std::vector<ConfigOptionBase*> &cfg, ToolTip^ tooltip, bool* hasChanged);
|
||||
|
||||
|
||||
ref class ComboboxValidation
|
||||
@@ -178,7 +144,78 @@ public:
|
||||
|
||||
};
|
||||
|
||||
static ref class ChangeHandler
|
||||
ref class PluginConfigHandler
|
||||
{
|
||||
public:
|
||||
Form^ form;
|
||||
|
||||
PluginConfigHandler(Panel^ optspanel, String^ title)
|
||||
{
|
||||
form = gcnew Form();
|
||||
|
||||
form->Text = title;
|
||||
|
||||
form->FormBorderStyle = FormBorderStyle::FixedDialog;
|
||||
form->StartPosition = FormStartPosition::CenterScreen;
|
||||
form->MaximizeBox = false;
|
||||
form->MinimizeBox = false;
|
||||
form->ShowInTaskbar = false;
|
||||
form->ShowIcon = false;
|
||||
//form->TopMost = true;
|
||||
|
||||
form->BackColor = Drawing::Color::FromArgb(64, 64, 64);
|
||||
form->ForeColor = Drawing::Color::White;
|
||||
|
||||
optspanel->Left = 0;
|
||||
optspanel->Top = 0;
|
||||
|
||||
Button^ OkBtn = gcnew Button();
|
||||
OkBtn->Text = L"OK";
|
||||
OkBtn->Left = 4;
|
||||
OkBtn->Top = optspanel->Bottom + 4;
|
||||
OkBtn->AutoSize = true;
|
||||
OkBtn->FlatStyle = System::Windows::Forms::FlatStyle::Flat;
|
||||
|
||||
form->ClientSize = Drawing::Size(optspanel->Width, OkBtn->Bottom + 4);
|
||||
|
||||
form->Controls->Add(optspanel);
|
||||
form->Controls->Add(OkBtn);
|
||||
form->AcceptButton = OkBtn;
|
||||
|
||||
form->FormClosing += gcnew System::Windows::Forms::FormClosingEventHandler(this, &PluginConfigHandler::FormClosing);
|
||||
OkBtn->Click += gcnew EventHandler(this, &PluginConfigHandler::OkClick);
|
||||
}
|
||||
|
||||
System::Void OpenForm(System::Object^ sender, System::EventArgs^ e)
|
||||
{
|
||||
// ShowDialog seems to prevent disposal by copying the panel...
|
||||
// which would be fine if I didn't rely on using the control handles
|
||||
// MessageBox::Show(form->Controls[0]->Handle.ToString());
|
||||
|
||||
//Application::OpenForms[0]->Enabled = false;
|
||||
form->Owner = Application::OpenForms[0];
|
||||
if (form->Visible)
|
||||
form->Hide();
|
||||
form->Show();
|
||||
}
|
||||
|
||||
System::Void FormClosing(System::Object^ sender, FormClosingEventArgs^ e)
|
||||
{
|
||||
if (e->CloseReason == CloseReason::UserClosing)
|
||||
{
|
||||
form->Hide();
|
||||
//Application::OpenForms[0]->Enabled = true;
|
||||
e->Cancel = true;
|
||||
}
|
||||
}
|
||||
|
||||
System::Void OkClick(System::Object^ sender, System::EventArgs^ e)
|
||||
{
|
||||
form->Close();
|
||||
}
|
||||
};
|
||||
|
||||
ref class ChangeHandler
|
||||
{
|
||||
public:
|
||||
bool* changebool;
|
||||
@@ -194,6 +231,22 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
ref class CustomFuncHandler
|
||||
{
|
||||
public:
|
||||
void(*_func)();
|
||||
|
||||
CustomFuncHandler(void(*func)())
|
||||
{
|
||||
_func = func;
|
||||
}
|
||||
|
||||
System::Void RunFunc(System::Object^ sender, System::EventArgs^ e)
|
||||
{
|
||||
_func();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class ConfigOptionBase
|
||||
{
|
||||
@@ -220,6 +273,42 @@ public:
|
||||
};
|
||||
|
||||
|
||||
class OptionMetaGroupStart : public ConfigOptionBase
|
||||
{
|
||||
public:
|
||||
int _height;
|
||||
|
||||
OptionMetaGroupStart(LPCWSTR friendlyName, int height)
|
||||
{
|
||||
_friendlyName = friendlyName;
|
||||
_height = height;
|
||||
}
|
||||
};
|
||||
class OptionMetaGroupEnd : public ConfigOptionBase
|
||||
{
|
||||
public:
|
||||
OptionMetaGroupEnd()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class OptionMetaSpacer : public ConfigOptionBase
|
||||
{
|
||||
public:
|
||||
int _height;
|
||||
|
||||
OptionMetaSpacer(int height)
|
||||
{
|
||||
_height = height;
|
||||
}
|
||||
|
||||
virtual int AddToPanel(Panel^ panel, unsigned int left, unsigned int top, ToolTip^ tooltip)
|
||||
{
|
||||
return _height;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class BooleanOption : public ConfigOptionBase
|
||||
{
|
||||
public:
|
||||
@@ -252,15 +341,20 @@ public:
|
||||
cb->BackColor = System::Drawing::Color::FromArgb(0, 0, 0, 0);
|
||||
|
||||
Form^ RootForm = panel->FindForm();
|
||||
Drawing::SizeF CurrentScaleSize = RootForm->CurrentAutoScaleDimensions;
|
||||
float ScaleWidth = CurrentScaleSize.Width / BaseScaleSize;
|
||||
float ScaleHeight = CurrentScaleSize.Height / BaseScaleSize;
|
||||
float ScaleWidth = 1.0f;
|
||||
float ScaleHeight = 1.0f;
|
||||
if (RootForm)
|
||||
{
|
||||
Drawing::SizeF CurrentScaleSize = RootForm->CurrentAutoScaleDimensions;
|
||||
ScaleWidth = CurrentScaleSize.Width / BaseScaleSize;
|
||||
ScaleHeight = CurrentScaleSize.Height / BaseScaleSize;
|
||||
}
|
||||
cb->Scale(ScaleWidth, ScaleHeight);
|
||||
|
||||
tooltip->SetToolTip(cb, gcnew String(_description));
|
||||
|
||||
if (hasChanged == nullptr)
|
||||
hasChanged = new bool;
|
||||
hasChanged = new bool(false);
|
||||
ChangeHandler^ changehandler = gcnew ChangeHandler(hasChanged);
|
||||
cb->CheckedChanged += gcnew System::EventHandler(changehandler, &ChangeHandler::SetChanged);
|
||||
|
||||
@@ -325,9 +419,14 @@ public:
|
||||
numberbox->AutoSize = true;
|
||||
|
||||
Form^ RootForm = panel->FindForm();
|
||||
Drawing::SizeF CurrentScaleSize = RootForm->CurrentAutoScaleDimensions;
|
||||
float ScaleWidth = CurrentScaleSize.Width / BaseScaleSize;
|
||||
float ScaleHeight = CurrentScaleSize.Height / BaseScaleSize;
|
||||
float ScaleWidth = 1.0f;
|
||||
float ScaleHeight = 1.0f;
|
||||
if (RootForm)
|
||||
{
|
||||
Drawing::SizeF CurrentScaleSize = RootForm->CurrentAutoScaleDimensions;
|
||||
ScaleWidth = CurrentScaleSize.Width / BaseScaleSize;
|
||||
ScaleHeight = CurrentScaleSize.Height / BaseScaleSize;
|
||||
}
|
||||
label->Scale(ScaleWidth, ScaleHeight);
|
||||
numberbox->Scale(ScaleWidth, ScaleHeight);
|
||||
|
||||
@@ -335,7 +434,7 @@ public:
|
||||
tooltip->SetToolTip(numberbox, gcnew String(_description));
|
||||
|
||||
if (hasChanged == nullptr)
|
||||
hasChanged = new bool;
|
||||
hasChanged = new bool(false);
|
||||
ChangeHandler^ changehandler = gcnew ChangeHandler(hasChanged);
|
||||
numberbox->ValueChanged += gcnew System::EventHandler(changehandler, &ChangeHandler::SetChanged);
|
||||
|
||||
@@ -404,9 +503,14 @@ public:
|
||||
textbox->AutoSize = true;
|
||||
|
||||
Form^ RootForm = panel->FindForm();
|
||||
Drawing::SizeF CurrentScaleSize = RootForm->CurrentAutoScaleDimensions;
|
||||
float ScaleWidth = CurrentScaleSize.Width / BaseScaleSize;
|
||||
float ScaleHeight = CurrentScaleSize.Height / BaseScaleSize;
|
||||
float ScaleWidth = 1.0f;
|
||||
float ScaleHeight = 1.0f;
|
||||
if (RootForm)
|
||||
{
|
||||
Drawing::SizeF CurrentScaleSize = RootForm->CurrentAutoScaleDimensions;
|
||||
ScaleWidth = CurrentScaleSize.Width / BaseScaleSize;
|
||||
ScaleHeight = CurrentScaleSize.Height / BaseScaleSize;
|
||||
}
|
||||
label->Scale(ScaleWidth, ScaleHeight);
|
||||
textbox->Scale(ScaleWidth, ScaleHeight);
|
||||
|
||||
@@ -419,7 +523,7 @@ public:
|
||||
tooltip->SetToolTip(textbox, gcnew String(_description));
|
||||
|
||||
if (hasChanged == nullptr)
|
||||
hasChanged = new bool;
|
||||
hasChanged = new bool(false);
|
||||
ChangeHandler^ changehandler = gcnew ChangeHandler(hasChanged);
|
||||
textbox->TextChanged += gcnew System::EventHandler(changehandler, &ChangeHandler::SetChanged);
|
||||
|
||||
@@ -498,9 +602,14 @@ public:
|
||||
combobox->DropDownStyle = ComboBoxStyle::DropDownList;
|
||||
|
||||
Form^ RootForm = panel->FindForm();
|
||||
Drawing::SizeF CurrentScaleSize = RootForm->CurrentAutoScaleDimensions;
|
||||
float ScaleWidth = CurrentScaleSize.Width / BaseScaleSize;
|
||||
float ScaleHeight = CurrentScaleSize.Height / BaseScaleSize;
|
||||
float ScaleWidth = 1.0f;
|
||||
float ScaleHeight = 1.0f;
|
||||
if (RootForm)
|
||||
{
|
||||
Drawing::SizeF CurrentScaleSize = RootForm->CurrentAutoScaleDimensions;
|
||||
ScaleWidth = CurrentScaleSize.Width / BaseScaleSize;
|
||||
ScaleHeight = CurrentScaleSize.Height / BaseScaleSize;
|
||||
}
|
||||
label->Scale(ScaleWidth, ScaleHeight);
|
||||
combobox->Scale(ScaleWidth, ScaleHeight);
|
||||
|
||||
@@ -508,7 +617,7 @@ public:
|
||||
tooltip->SetToolTip(combobox, gcnew String(_description));
|
||||
|
||||
if (hasChanged == nullptr)
|
||||
hasChanged = new bool;
|
||||
hasChanged = new bool(false);
|
||||
ChangeHandler^ changehandler = gcnew ChangeHandler(hasChanged);
|
||||
combobox->SelectedIndexChanged += gcnew System::EventHandler(changehandler, &ChangeHandler::SetChanged);
|
||||
|
||||
@@ -532,14 +641,15 @@ public:
|
||||
};
|
||||
|
||||
|
||||
class EditableDropdownOption : public ConfigOptionBase
|
||||
class DropdownTextOption : public ConfigOptionBase
|
||||
{
|
||||
public:
|
||||
LPCWSTR _defaultVal;
|
||||
std::vector<LPCWSTR> _valueStrings;
|
||||
bool _editable;
|
||||
bool _useUtf8;
|
||||
|
||||
EditableDropdownOption(LPCWSTR iniVarName, LPCWSTR iniSectionName, LPCWSTR iniFilePath, LPCWSTR friendlyName, LPCWSTR description, LPCWSTR defaultVal, std::vector<LPCWSTR> valueStrings, bool useUtf8)
|
||||
DropdownTextOption(LPCWSTR iniVarName, LPCWSTR iniSectionName, LPCWSTR iniFilePath, LPCWSTR friendlyName, LPCWSTR description, LPCWSTR defaultVal, std::vector<LPCWSTR> valueStrings, bool editable, bool useUtf8)
|
||||
{
|
||||
_iniVarName = iniVarName;
|
||||
_iniSectionName = iniSectionName;
|
||||
@@ -548,6 +658,7 @@ public:
|
||||
_description = description;
|
||||
_defaultVal = defaultVal;
|
||||
_valueStrings = valueStrings;
|
||||
_editable = editable;
|
||||
_useUtf8 = useUtf8;
|
||||
}
|
||||
|
||||
@@ -582,12 +693,21 @@ public:
|
||||
combobox->Width = Col2Width;
|
||||
combobox->AutoSize = true;
|
||||
combobox->FlatStyle = System::Windows::Forms::FlatStyle::Flat;
|
||||
combobox->DropDownStyle = ComboBoxStyle::DropDown;
|
||||
|
||||
if (_editable)
|
||||
combobox->DropDownStyle = ComboBoxStyle::DropDown;
|
||||
else
|
||||
combobox->DropDownStyle = ComboBoxStyle::DropDownList;
|
||||
|
||||
Form^ RootForm = panel->FindForm();
|
||||
Drawing::SizeF CurrentScaleSize = RootForm->CurrentAutoScaleDimensions;
|
||||
float ScaleWidth = CurrentScaleSize.Width / BaseScaleSize;
|
||||
float ScaleHeight = CurrentScaleSize.Height / BaseScaleSize;
|
||||
float ScaleWidth = 1.0f;
|
||||
float ScaleHeight = 1.0f;
|
||||
if (RootForm)
|
||||
{
|
||||
Drawing::SizeF CurrentScaleSize = RootForm->CurrentAutoScaleDimensions;
|
||||
ScaleWidth = CurrentScaleSize.Width / BaseScaleSize;
|
||||
ScaleHeight = CurrentScaleSize.Height / BaseScaleSize;
|
||||
}
|
||||
label->Scale(ScaleWidth, ScaleHeight);
|
||||
combobox->Scale(ScaleWidth, ScaleHeight);
|
||||
|
||||
@@ -601,9 +721,12 @@ public:
|
||||
tooltip->SetToolTip(combobox, gcnew String(_description));
|
||||
|
||||
if (hasChanged == nullptr)
|
||||
hasChanged = new bool;
|
||||
hasChanged = new bool(false);
|
||||
ChangeHandler^ changehandler = gcnew ChangeHandler(hasChanged);
|
||||
combobox->TextChanged += gcnew System::EventHandler(changehandler, &ChangeHandler::SetChanged);
|
||||
if (_editable)
|
||||
combobox->TextChanged += gcnew System::EventHandler(changehandler, &ChangeHandler::SetChanged);
|
||||
else
|
||||
combobox->SelectedIndexChanged += gcnew System::EventHandler(changehandler, &ChangeHandler::SetChanged);
|
||||
|
||||
panel->Controls->Add(label);
|
||||
panel->Controls->Add(combobox);
|
||||
@@ -639,13 +762,14 @@ public:
|
||||
};
|
||||
|
||||
|
||||
class EditableDropdownNumberOption : public ConfigOptionBase
|
||||
class DropdownNumberOption : public ConfigOptionBase
|
||||
{
|
||||
public:
|
||||
int _defaultVal;
|
||||
std::vector<int> _valueInts;
|
||||
bool _editable;
|
||||
|
||||
EditableDropdownNumberOption(LPCWSTR iniVarName, LPCWSTR iniSectionName, LPCWSTR iniFilePath, LPCWSTR friendlyName, LPCWSTR description, int defaultVal, std::vector<int> valueInts)
|
||||
DropdownNumberOption(LPCWSTR iniVarName, LPCWSTR iniSectionName, LPCWSTR iniFilePath, LPCWSTR friendlyName, LPCWSTR description, int defaultVal, std::vector<int> valueInts, bool editable)
|
||||
{
|
||||
_iniVarName = iniVarName;
|
||||
_iniSectionName = iniSectionName;
|
||||
@@ -654,6 +778,7 @@ public:
|
||||
_description = description;
|
||||
_defaultVal = defaultVal;
|
||||
_valueInts = valueInts;
|
||||
_editable = editable;
|
||||
}
|
||||
|
||||
virtual int AddToPanel(Panel^ panel, unsigned int left, unsigned int top, ToolTip^ tooltip)
|
||||
@@ -682,12 +807,21 @@ public:
|
||||
combobox->Width = Col2Width;
|
||||
combobox->AutoSize = true;
|
||||
combobox->FlatStyle = System::Windows::Forms::FlatStyle::Flat;
|
||||
combobox->DropDownStyle = ComboBoxStyle::DropDown;
|
||||
|
||||
if (_editable)
|
||||
combobox->DropDownStyle = ComboBoxStyle::DropDown;
|
||||
else
|
||||
combobox->DropDownStyle = ComboBoxStyle::DropDownList;
|
||||
|
||||
Form^ RootForm = panel->FindForm();
|
||||
Drawing::SizeF CurrentScaleSize = RootForm->CurrentAutoScaleDimensions;
|
||||
float ScaleWidth = CurrentScaleSize.Width / BaseScaleSize;
|
||||
float ScaleHeight = CurrentScaleSize.Height / BaseScaleSize;
|
||||
float ScaleWidth = 1.0f;
|
||||
float ScaleHeight = 1.0f;
|
||||
if (RootForm)
|
||||
{
|
||||
Drawing::SizeF CurrentScaleSize = RootForm->CurrentAutoScaleDimensions;
|
||||
ScaleWidth = CurrentScaleSize.Width / BaseScaleSize;
|
||||
ScaleHeight = CurrentScaleSize.Height / BaseScaleSize;
|
||||
}
|
||||
label->Scale(ScaleWidth, ScaleHeight);
|
||||
combobox->Scale(ScaleWidth, ScaleHeight);
|
||||
|
||||
@@ -698,9 +832,12 @@ public:
|
||||
combobox->Leave += gcnew System::EventHandler(validation, &ComboboxValidation::CheckNumberLeave);
|
||||
|
||||
if (hasChanged == nullptr)
|
||||
hasChanged = new bool;
|
||||
hasChanged = new bool(false);
|
||||
ChangeHandler^ changehandler = gcnew ChangeHandler(hasChanged);
|
||||
combobox->TextChanged += gcnew System::EventHandler(changehandler, &ChangeHandler::SetChanged);
|
||||
if (_editable)
|
||||
combobox->TextChanged += gcnew System::EventHandler(changehandler, &ChangeHandler::SetChanged);
|
||||
else
|
||||
combobox->SelectedIndexChanged += gcnew System::EventHandler(changehandler, &ChangeHandler::SetChanged);
|
||||
|
||||
panel->Controls->Add(label);
|
||||
panel->Controls->Add(combobox);
|
||||
@@ -729,8 +866,9 @@ public:
|
||||
LPCWSTR _iniVarName2;
|
||||
resolution _defaultVal;
|
||||
std::vector<resolution> _valueResolutions;
|
||||
bool _editable;
|
||||
|
||||
ResolutionOption(LPCWSTR iniVarName, LPCWSTR iniVarName2, LPCWSTR iniSectionName, LPCWSTR iniFilePath, LPCWSTR friendlyName, LPCWSTR description, 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, bool editable)
|
||||
{
|
||||
_iniVarName = iniVarName;
|
||||
_iniVarName2 = iniVarName2;
|
||||
@@ -740,6 +878,7 @@ public:
|
||||
_description = description;
|
||||
_defaultVal = defaultVal;
|
||||
_valueResolutions = valueResolutions;
|
||||
_editable = editable;
|
||||
}
|
||||
|
||||
virtual int AddToPanel(Panel^ panel, unsigned int left, unsigned int top, ToolTip^ tooltip)
|
||||
@@ -777,12 +916,21 @@ public:
|
||||
combobox->Width = Col2Width;
|
||||
combobox->AutoSize = true;
|
||||
combobox->FlatStyle = System::Windows::Forms::FlatStyle::Flat;
|
||||
combobox->DropDownStyle = ComboBoxStyle::DropDown;
|
||||
|
||||
if (_editable)
|
||||
combobox->DropDownStyle = ComboBoxStyle::DropDown;
|
||||
else
|
||||
combobox->DropDownStyle = ComboBoxStyle::DropDownList;
|
||||
|
||||
Form^ RootForm = panel->FindForm();
|
||||
Drawing::SizeF CurrentScaleSize = RootForm->CurrentAutoScaleDimensions;
|
||||
float ScaleWidth = CurrentScaleSize.Width / BaseScaleSize;
|
||||
float ScaleHeight = CurrentScaleSize.Height / BaseScaleSize;
|
||||
float ScaleWidth = 1.0f;
|
||||
float ScaleHeight = 1.0f;
|
||||
if (RootForm)
|
||||
{
|
||||
Drawing::SizeF CurrentScaleSize = RootForm->CurrentAutoScaleDimensions;
|
||||
ScaleWidth = CurrentScaleSize.Width / BaseScaleSize;
|
||||
ScaleHeight = CurrentScaleSize.Height / BaseScaleSize;
|
||||
}
|
||||
label->Scale(ScaleWidth, ScaleHeight);
|
||||
combobox->Scale(ScaleWidth, ScaleHeight);
|
||||
|
||||
@@ -790,9 +938,12 @@ public:
|
||||
tooltip->SetToolTip(combobox, gcnew String(_description));
|
||||
|
||||
if (hasChanged == nullptr)
|
||||
hasChanged = new bool;
|
||||
hasChanged = new bool(false);
|
||||
ChangeHandler^ changehandler = gcnew ChangeHandler(hasChanged);
|
||||
combobox->TextChanged += gcnew System::EventHandler(changehandler, &ChangeHandler::SetChanged);
|
||||
if (_editable)
|
||||
combobox->TextChanged += gcnew System::EventHandler(changehandler, &ChangeHandler::SetChanged);
|
||||
else
|
||||
combobox->SelectedIndexChanged += gcnew System::EventHandler(changehandler, &ChangeHandler::SetChanged);
|
||||
|
||||
ComboboxValidation^ validation = gcnew ComboboxValidation(combobox);
|
||||
combobox->Leave += gcnew System::EventHandler(validation, &ComboboxValidation::CheckResolutionLeave);
|
||||
@@ -823,4 +974,209 @@ public:
|
||||
WritePrivateProfileStringW(_iniSectionName, _iniVarName2, tempWStr.c_str(), _iniFilePath);
|
||||
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
class ButtonOption : public ConfigOptionBase
|
||||
{
|
||||
public:
|
||||
void(*_func)();
|
||||
|
||||
ButtonOption(LPCWSTR friendlyName, LPCWSTR description, void(*func)())
|
||||
{
|
||||
_friendlyName = friendlyName;
|
||||
_description = description;
|
||||
_func = func;
|
||||
}
|
||||
|
||||
virtual int AddToPanel(Panel^ panel, unsigned int left, unsigned int top, ToolTip^ tooltip)
|
||||
{
|
||||
Button^ button = gcnew Button();
|
||||
|
||||
button->Text = gcnew String(_friendlyName);
|
||||
button->Left = left;
|
||||
button->Top = top;
|
||||
button->AutoSize = true;
|
||||
button->FlatStyle = System::Windows::Forms::FlatStyle::Flat;
|
||||
|
||||
Form^ RootForm = panel->FindForm();
|
||||
float ScaleWidth = 1.0f;
|
||||
float ScaleHeight = 1.0f;
|
||||
if (RootForm)
|
||||
{
|
||||
Drawing::SizeF CurrentScaleSize = RootForm->CurrentAutoScaleDimensions;
|
||||
ScaleWidth = CurrentScaleSize.Width / BaseScaleSize;
|
||||
ScaleHeight = CurrentScaleSize.Height / BaseScaleSize;
|
||||
}
|
||||
button->Scale(ScaleWidth, ScaleHeight);
|
||||
|
||||
tooltip->SetToolTip(button, gcnew String(_description));
|
||||
|
||||
CustomFuncHandler^ funchandler = gcnew CustomFuncHandler(_func);
|
||||
button->Click += gcnew System::EventHandler(funchandler, &CustomFuncHandler::RunFunc);
|
||||
|
||||
panel->Controls->Add(button);
|
||||
|
||||
int ControlHeight = button->Height / ScaleHeight;
|
||||
return ControlHeight + ControlSpacing;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class PluginOption : public ConfigOptionBase
|
||||
{
|
||||
public:
|
||||
bool _defaultVal;
|
||||
std::vector<ConfigOptionBase*> _configopts;
|
||||
|
||||
PluginOption(LPCWSTR iniVarName, LPCWSTR iniSectionName, LPCWSTR iniFilePath, LPCWSTR friendlyName, LPCWSTR description, bool defaultVal, std::vector<ConfigOptionBase*> configopts)
|
||||
{
|
||||
_iniVarName = iniVarName;
|
||||
_iniSectionName = iniSectionName;
|
||||
_iniFilePath = iniFilePath;
|
||||
_friendlyName = friendlyName;
|
||||
_description = description;
|
||||
_defaultVal = defaultVal;
|
||||
_configopts = configopts;
|
||||
}
|
||||
|
||||
virtual int AddToPanel(Panel^ panel, unsigned int left, unsigned int top, ToolTip^ tooltip)
|
||||
{
|
||||
CheckBox^ cb = gcnew CheckBox();
|
||||
Button^ button = gcnew Button();
|
||||
|
||||
cb->Text = gcnew String(_friendlyName);
|
||||
cb->Checked = GetPrivateProfileBoolW(_iniSectionName, _iniVarName, _defaultVal, _iniFilePath);
|
||||
cb->Left = left + 2;
|
||||
cb->Top = top + 3;
|
||||
cb->AutoSize = true;
|
||||
cb->FlatStyle = System::Windows::Forms::FlatStyle::Flat;
|
||||
|
||||
// hack to ensure high contrast
|
||||
cb->BackColor = System::Drawing::Color::FromArgb(0, 0, 0, 0);
|
||||
|
||||
button->Text = L"Config";
|
||||
button->Left = left + ConfigBtnLeft;
|
||||
button->Top = top;
|
||||
button->AutoSize = true;
|
||||
button->FlatStyle = System::Windows::Forms::FlatStyle::Flat;
|
||||
|
||||
Form^ RootForm = panel->FindForm();
|
||||
float ScaleWidth = 1.0f;
|
||||
float ScaleHeight = 1.0f;
|
||||
if (RootForm)
|
||||
{
|
||||
Drawing::SizeF CurrentScaleSize = RootForm->CurrentAutoScaleDimensions;
|
||||
ScaleWidth = CurrentScaleSize.Width / BaseScaleSize;
|
||||
ScaleHeight = CurrentScaleSize.Height / BaseScaleSize;
|
||||
}
|
||||
cb->Scale(ScaleWidth, ScaleHeight);
|
||||
button->Scale(ScaleWidth, ScaleHeight);
|
||||
|
||||
tooltip->SetToolTip(cb, gcnew String(_description));
|
||||
|
||||
if (hasChanged == nullptr)
|
||||
hasChanged = new bool(false);
|
||||
ChangeHandler^ changehandler = gcnew ChangeHandler(hasChanged);
|
||||
cb->CheckedChanged += gcnew System::EventHandler(changehandler, &ChangeHandler::SetChanged);
|
||||
|
||||
panel->Controls->Add(cb);
|
||||
mainControlHandle = cb->Handle;
|
||||
|
||||
if (_configopts.size() > 0)
|
||||
{
|
||||
ToolTip^ paneltooltip = gcnew ToolTip();
|
||||
Panel^ configPanel = MakePanel((Col2Left + Col2Width + 64), 250, _configopts, paneltooltip, hasChanged);
|
||||
configPanel->Scale(ScaleWidth, ScaleHeight);
|
||||
PluginConfigHandler^ confighandler = gcnew PluginConfigHandler(configPanel, gcnew String(_friendlyName) + " Options");
|
||||
button->Click += gcnew System::EventHandler(confighandler, &PluginConfigHandler::OpenForm);
|
||||
|
||||
panel->Controls->Add(button);
|
||||
}
|
||||
|
||||
int ControlHeight = button->Height / ScaleHeight;
|
||||
return ControlHeight + ControlSpacing;
|
||||
}
|
||||
|
||||
virtual void SaveOption()
|
||||
{
|
||||
bool boolEnabled = ((CheckBox^)CheckBox::FromHandle(mainControlHandle))->Checked;
|
||||
|
||||
WritePrivateProfileStringW(_iniSectionName, _iniVarName, boolEnabled ? L"1" : L"0", _iniFilePath);
|
||||
|
||||
for (ConfigOptionBase* opt : _configopts)
|
||||
{
|
||||
opt->SaveOption();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Panel^ MakePanel(int width, int height, std::vector<ConfigOptionBase*> &cfg, ToolTip^ tooltip, bool* hasChanged)
|
||||
{
|
||||
Panel^ outpanel = gcnew Panel();
|
||||
outpanel->Width = width;
|
||||
outpanel->Height = height;
|
||||
outpanel->AutoScroll = true;
|
||||
|
||||
Form^ RootForm = outpanel->FindForm();
|
||||
float ScaleWidth = 1.0f;
|
||||
float ScaleHeight = 1.0f;
|
||||
if (RootForm)
|
||||
{
|
||||
Drawing::SizeF CurrentScaleSize = RootForm->CurrentAutoScaleDimensions;
|
||||
ScaleWidth = CurrentScaleSize.Width / BaseScaleSize;
|
||||
ScaleHeight = CurrentScaleSize.Height / BaseScaleSize;
|
||||
}
|
||||
|
||||
int curX = 12;
|
||||
int curY = 3;
|
||||
|
||||
for (int i = 0; i < cfg.size(); i++)
|
||||
{
|
||||
if (typeid(*cfg[i]).hash_code() == typeid(OptionMetaGroupEnd).hash_code())
|
||||
continue;
|
||||
|
||||
if (typeid(*cfg[i]).hash_code() == typeid(OptionMetaGroupStart).hash_code())
|
||||
{
|
||||
OptionMetaGroupStart* groupData = (OptionMetaGroupStart*)(cfg[i]);
|
||||
GroupBox^ groupbox = gcnew GroupBox();
|
||||
groupbox->Width = width - (ScaleWidth * 8);
|
||||
groupbox->Height = ScaleHeight * groupData->_height;
|
||||
groupbox->Left = ScaleWidth * 4;
|
||||
groupbox->Top = ScaleHeight * curY;
|
||||
groupbox->Text = gcnew String(groupData->_friendlyName);
|
||||
|
||||
// find the end of this group by simple iteration keeping track of indent level
|
||||
int level = 1;
|
||||
int endidx;
|
||||
for (endidx = i + 1; endidx < cfg.size(); endidx++)
|
||||
{
|
||||
if (typeid(*cfg[endidx]).hash_code() == typeid(OptionMetaGroupStart).hash_code())
|
||||
level++;
|
||||
if (typeid(*cfg[endidx]).hash_code() == typeid(OptionMetaGroupEnd).hash_code())
|
||||
level--;
|
||||
|
||||
if (level == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
Panel^ groupPanel = MakePanel(groupbox->Width - (ScaleWidth * 8), groupbox->Height - (ScaleHeight * 10), std::vector<ConfigOptionBase*>(&(cfg[i + 1]), &(cfg[endidx])), tooltip, hasChanged);
|
||||
groupPanel->Left = ScaleWidth * 12;
|
||||
groupPanel->Top = ScaleHeight * (curY + 8);
|
||||
|
||||
groupbox->Controls->Add(groupPanel);
|
||||
outpanel->Controls->Add(groupbox);
|
||||
|
||||
i = endidx;
|
||||
curY += groupData->_height;
|
||||
}
|
||||
else
|
||||
{
|
||||
cfg[i]->hasChanged = hasChanged;
|
||||
curY += cfg[i]->AddToPanel(outpanel, curX, curY, tooltip);
|
||||
}
|
||||
}
|
||||
|
||||
return outpanel;
|
||||
}
|
||||
@@ -167,6 +167,8 @@
|
||||
<ItemGroup>
|
||||
<ClInclude Include="ConfigOption.h" />
|
||||
<ClInclude Include="framework.h" />
|
||||
<ClInclude Include="PluginConfig.h" />
|
||||
<ClInclude Include="PluginConfigApi.h" />
|
||||
<ClInclude Include="SkinnedMessageBox.h" />
|
||||
<ClInclude Include="TabPadding.h" />
|
||||
<ClInclude Include="ui.h">
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
#pragma once
|
||||
#include "ConfigOption.h"
|
||||
#include "PluginConfigApi.h"
|
||||
|
||||
namespace PluginConfig
|
||||
{
|
||||
ConfigOptionBase* GetConfigOption(PluginConfigOption cfg)
|
||||
{
|
||||
PluginConfigBooleanData* boolData = (PluginConfigBooleanData*)(cfg.data);
|
||||
PluginConfigNumericData* numericData = (PluginConfigNumericData*)(cfg.data);
|
||||
PluginConfigStringData* stringData = (PluginConfigStringData*)(cfg.data);
|
||||
PluginConfigDropdownIndexData* ddIdxData = (PluginConfigDropdownIndexData*)(cfg.data);
|
||||
PluginConfigDropdownTextData* ddTextData = (PluginConfigDropdownTextData*)(cfg.data);
|
||||
PluginConfigDropdownNumberData* ddNumberData = (PluginConfigDropdownNumberData*)(cfg.data);
|
||||
PluginConfigResolutionData* resData = (PluginConfigResolutionData*)(cfg.data);
|
||||
PluginConfigGroupData* groupData = (PluginConfigGroupData*)(cfg.data);
|
||||
PluginConfigButtonData* btnData = (PluginConfigButtonData*)(cfg.data);
|
||||
PluginConfigSpacerData* spacerData = (PluginConfigSpacerData*)(cfg.data);
|
||||
|
||||
switch (cfg.cfgType)
|
||||
{
|
||||
case CONFIG_BOOLEAN:
|
||||
return new BooleanOption(boolData->iniVarName, boolData->iniSectionName, boolData->iniFilePath, boolData->friendlyName, boolData->description, boolData->defaultVal, boolData->saveAsString);
|
||||
case CONFIG_NUMERIC:
|
||||
return new NumericOption(numericData->iniVarName, numericData->iniSectionName, numericData->iniFilePath, numericData->friendlyName, numericData->description, numericData->defaultVal, numericData->minVal, numericData->maxVal);
|
||||
case CONFIG_STRING:
|
||||
return new StringOption(stringData->iniVarName, stringData->iniSectionName, stringData->iniFilePath, stringData->friendlyName, stringData->description, stringData->defaultVal, stringData->useUtf8);
|
||||
case CONFIG_DROPDOWN_INDEX:
|
||||
return new DropdownOption(ddIdxData->iniVarName, ddIdxData->iniSectionName, ddIdxData->iniFilePath, ddIdxData->friendlyName, ddIdxData->description, ddIdxData->defaultVal, ddIdxData->valueStrings);
|
||||
case CONFIG_DROPDOWN_TEXT:
|
||||
return new DropdownTextOption(ddTextData->iniVarName, ddTextData->iniSectionName, ddTextData->iniFilePath, ddTextData->friendlyName, ddTextData->description, ddTextData->defaultVal, ddTextData->valueStrings, ddTextData->editable, ddTextData->useUtf8);
|
||||
case CONFIG_DROPDOWN_NUMBER:
|
||||
return new DropdownNumberOption(ddNumberData->iniVarName, ddNumberData->iniSectionName, ddNumberData->iniFilePath, ddNumberData->friendlyName, ddNumberData->description, ddNumberData->defaultVal, ddNumberData->valueInts, ddNumberData->editable);
|
||||
case CONFIG_RESOLUTION:
|
||||
return new ResolutionOption(resData->iniVarName, resData->iniVarName2, resData->iniSectionName, resData->iniFilePath, resData->friendlyName, resData->description, resData->defaultVal, resData->valueResolutions, resData->editable);
|
||||
case CONFIG_GROUP_START:
|
||||
return new OptionMetaGroupStart(groupData->name, groupData->height);
|
||||
case CONFIG_GROUP_END:
|
||||
return new OptionMetaGroupEnd();
|
||||
case CONFIG_BUTTON:
|
||||
return new ButtonOption(btnData->friendlyName, btnData->description, btnData->func);
|
||||
case CONFIG_SPACER:
|
||||
return new OptionMetaSpacer(spacerData->height);
|
||||
default:
|
||||
return new ConfigOptionBase();
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<ConfigOptionBase*> GetConfigOptionVec(PluginConfigArray &in)
|
||||
{
|
||||
std::vector<ConfigOptionBase*> outvec;
|
||||
for (int i = 0; i < in.len; i++)
|
||||
{
|
||||
// basic check for validity
|
||||
if (in.options[i].data == nullptr)
|
||||
break;
|
||||
|
||||
outvec.push_back(GetConfigOption(in.options[i]));
|
||||
}
|
||||
return outvec;
|
||||
}
|
||||
|
||||
/*std::vector<PluginConfigOption> testcfg =
|
||||
{
|
||||
PluginConfigOption{ CONFIG_GROUP_START, new PluginConfigGroupData{L"Screen Resolution", 400 } },
|
||||
PluginConfigOption{ CONFIG_DROPDOWN_INDEX, new PluginConfigDropdownIndexData{ L"display", RESOLUTION_SECTION, CONFIG_FILE, L"Display:", L"Sets the window/screen mode.", 0, std::vector<LPCWSTR>({ L"Windowed", L"Borderless", L"Fullscreen" }) } },
|
||||
PluginConfigOption{ CONFIG_RESOLUTION, new PluginConfigResolutionData{ L"width", L"height", RESOLUTION_SECTION, CONFIG_FILE, L"Resolution:", L"Sets the display resolution.", resolution(1280, 720), getScreenResolutionsVec(screenModes) } }
|
||||
};*/
|
||||
|
||||
//std::vector<ConfigOptionBase*> testcfgconfigopts = GetConfigOptionVec(testcfg);
|
||||
};
|
||||
@@ -0,0 +1,168 @@
|
||||
#pragma once
|
||||
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
||||
#include <windows.h>
|
||||
#include <vector>
|
||||
|
||||
// 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;
|
||||
}
|
||||
};
|
||||
|
||||
namespace PluginConfig
|
||||
{
|
||||
#pragma pack(push, 1)
|
||||
enum ConfigType {
|
||||
CONFIG_BOOLEAN,
|
||||
CONFIG_NUMERIC,
|
||||
CONFIG_STRING,
|
||||
CONFIG_DROPDOWN_INDEX,
|
||||
CONFIG_DROPDOWN_TEXT,
|
||||
CONFIG_DROPDOWN_NUMBER,
|
||||
CONFIG_RESOLUTION,
|
||||
CONFIG_GROUP_START,
|
||||
CONFIG_GROUP_END,
|
||||
CONFIG_BUTTON,
|
||||
CONFIG_SPACER
|
||||
};
|
||||
|
||||
struct PluginConfigBooleanData {
|
||||
LPCWSTR iniVarName;
|
||||
LPCWSTR iniSectionName;
|
||||
LPCWSTR iniFilePath;
|
||||
LPCWSTR friendlyName;
|
||||
LPCWSTR description;
|
||||
bool defaultVal;
|
||||
bool saveAsString;
|
||||
};
|
||||
|
||||
struct PluginConfigNumericData {
|
||||
LPCWSTR iniVarName;
|
||||
LPCWSTR iniSectionName;
|
||||
LPCWSTR iniFilePath;
|
||||
LPCWSTR friendlyName;
|
||||
LPCWSTR description;
|
||||
int defaultVal;
|
||||
int minVal;
|
||||
int maxVal;
|
||||
};
|
||||
|
||||
struct PluginConfigStringData {
|
||||
LPCWSTR iniVarName;
|
||||
LPCWSTR iniSectionName;
|
||||
LPCWSTR iniFilePath;
|
||||
LPCWSTR friendlyName;
|
||||
LPCWSTR description;
|
||||
LPCWSTR defaultVal;
|
||||
bool useUtf8;
|
||||
};
|
||||
|
||||
struct PluginConfigDropdownIndexData {
|
||||
LPCWSTR iniVarName;
|
||||
LPCWSTR iniSectionName;
|
||||
LPCWSTR iniFilePath;
|
||||
LPCWSTR friendlyName;
|
||||
LPCWSTR description;
|
||||
int defaultVal;
|
||||
std::vector<LPCWSTR> valueStrings;
|
||||
};
|
||||
|
||||
struct PluginConfigDropdownTextData {
|
||||
LPCWSTR iniVarName;
|
||||
LPCWSTR iniSectionName;
|
||||
LPCWSTR iniFilePath;
|
||||
LPCWSTR friendlyName;
|
||||
LPCWSTR description;
|
||||
LPCWSTR defaultVal;
|
||||
std::vector<LPCWSTR> valueStrings;
|
||||
bool editable;
|
||||
bool useUtf8;
|
||||
};
|
||||
|
||||
struct PluginConfigDropdownNumberData {
|
||||
LPCWSTR iniVarName;
|
||||
LPCWSTR iniSectionName;
|
||||
LPCWSTR iniFilePath;
|
||||
LPCWSTR friendlyName;
|
||||
LPCWSTR description;
|
||||
int defaultVal;
|
||||
std::vector<int> valueInts;
|
||||
bool editable;
|
||||
};
|
||||
|
||||
struct PluginConfigResolutionData {
|
||||
LPCWSTR iniVarName;
|
||||
LPCWSTR iniVarName2;
|
||||
LPCWSTR iniSectionName;
|
||||
LPCWSTR iniFilePath;
|
||||
LPCWSTR friendlyName;
|
||||
LPCWSTR description;
|
||||
resolution defaultVal;
|
||||
std::vector<resolution> valueResolutions;
|
||||
bool editable;
|
||||
};
|
||||
|
||||
struct PluginConfigGroupData
|
||||
{
|
||||
LPCWSTR name;
|
||||
int height;
|
||||
};
|
||||
|
||||
struct PluginConfigButtonData {
|
||||
LPCWSTR friendlyName;
|
||||
LPCWSTR description;
|
||||
void(*func)();
|
||||
};
|
||||
|
||||
struct PluginConfigSpacerData {
|
||||
int height;
|
||||
};
|
||||
|
||||
struct PluginConfigOption
|
||||
{
|
||||
ConfigType cfgType;
|
||||
void* data;
|
||||
};
|
||||
|
||||
struct PluginConfigArray
|
||||
{
|
||||
int len;
|
||||
PluginConfigOption* options;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
}
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <algorithm>
|
||||
|
||||
#include "ConfigOption.h"
|
||||
#include "PluginConfig.h"
|
||||
|
||||
int (__cdecl* divaMain)(int argc, const char** argv, const char** envp) = (int(__cdecl*)(int argc, const char** argv, const char** envp))0x140194D90;
|
||||
|
||||
@@ -34,13 +35,15 @@ LPCWSTR DIVA_EXECUTABLE = DIVA_EXECUTABLE_STRING.c_str();
|
||||
wstring DIVA_EXECUTABLE_LAUNCH_STRING = DIVA_EXECUTABLE_STRING + L" --launch";
|
||||
LPWSTR DIVA_EXECUTABLE_LAUNCH = const_cast<WCHAR*>(DIVA_EXECUTABLE_LAUNCH_STRING.c_str());
|
||||
|
||||
wstring CONFIG_FILE_STRING = DirPath() + L"\\plugins\\config.ini";
|
||||
wstring PLUGINS_DIR = DirPath() + L"\\plugins";
|
||||
|
||||
wstring CONFIG_FILE_STRING = PLUGINS_DIR + L"\\config.ini";
|
||||
LPCWSTR CONFIG_FILE = CONFIG_FILE_STRING.c_str();
|
||||
|
||||
wstring COMPONENTS_FILE_STRING = DirPath() + L"\\plugins\\components.ini";
|
||||
wstring COMPONENTS_FILE_STRING = PLUGINS_DIR + L"\\components.ini";
|
||||
LPCWSTR COMPONENTS_FILE = COMPONENTS_FILE_STRING.c_str();
|
||||
|
||||
wstring PLAYERDATA_FILE_STRING = DirPath() + L"\\plugins\\playerdata.ini";
|
||||
wstring PLAYERDATA_FILE_STRING = PLUGINS_DIR + L"\\playerdata.ini";
|
||||
LPCWSTR PLAYERDATA_FILE = PLAYERDATA_FILE_STRING.c_str();
|
||||
|
||||
LPCWSTR PATCHES_SECTION = L"patches";
|
||||
@@ -124,17 +127,17 @@ 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));
|
||||
ResolutionOption* DisplayResolutionOption = new ResolutionOption(L"width", L"height", RESOLUTION_SECTION, CONFIG_FILE, L"Resolution:", L"Sets the display resolution.", resolution(1280, 720), getScreenResolutionsVec(screenModes), true);
|
||||
|
||||
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)),
|
||||
//new DropdownNumberOption(L"bitdepth", RESOLUTION_SECTION, CONFIG_FILE, L"Bit Depth:", L"Sets the display bit depth.", 32, getScreenDepthsVec(screenModes), true),
|
||||
new DropdownNumberOption(L"refreshrate", RESOLUTION_SECTION, CONFIG_FILE, L"Refresh Rate:", L"Sets the display refresh rate.", 60, getScreenRatesVec(screenModes), true),
|
||||
};
|
||||
|
||||
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(1600,900), resolution(1920,1080), resolution(2560,1440), resolution(3200,1800), resolution(3840,2160), resolution(5120,2880), resolution(6400,3600), resolution(7680,4320) }));
|
||||
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(1600,900), resolution(1920,1080), resolution(2560,1440), resolution(3200,1800), resolution(3840,2160), resolution(5120,2880), resolution(6400,3600), resolution(7680,4320) }), true);
|
||||
|
||||
ConfigOptionBase* internalResolutionArray[] = {
|
||||
InternalResolutionCheckbox,
|
||||
@@ -181,6 +184,7 @@ ConfigOptionBase* playerdataArray[] = {
|
||||
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"act_toggle", PLAYERDATA_SECTION, PLAYERDATA_FILE, L"Button SE", L"Enables button/slider sounds.", true, true),
|
||||
|
||||
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),
|
||||
@@ -265,6 +269,87 @@ void PrependFile(LPCSTR newStr, LPCWSTR fileName)
|
||||
}
|
||||
|
||||
|
||||
struct PluginInfo {
|
||||
HMODULE handle;
|
||||
std::wstring filename;
|
||||
std::wstring name;
|
||||
std::wstring description;
|
||||
std::vector<ConfigOptionBase*> configopts;
|
||||
};
|
||||
std::vector<PluginInfo> LoadPlugins()
|
||||
{
|
||||
std::vector<PluginInfo> outvec;
|
||||
|
||||
HANDLE hFind;
|
||||
WIN32_FIND_DATAW ffd;
|
||||
|
||||
hFind = FindFirstFileW((PLUGINS_DIR + L"\\*.dva").c_str(), &ffd);
|
||||
if (hFind != INVALID_HANDLE_VALUE) {
|
||||
do {
|
||||
if (!(ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
|
||||
{
|
||||
auto pos = wcslen(ffd.cFileName);
|
||||
|
||||
if (ffd.cFileName[pos - 4] == '.' &&
|
||||
(ffd.cFileName[pos - 3] == 'd' || ffd.cFileName[pos - 3] == 'D') &&
|
||||
(ffd.cFileName[pos - 2] == 'v' || ffd.cFileName[pos - 2] == 'V') &&
|
||||
(ffd.cFileName[pos - 1] == 'a' || ffd.cFileName[pos - 1] == 'A'))
|
||||
{
|
||||
PluginInfo thisplugin;
|
||||
thisplugin.handle = LoadLibraryW((PLUGINS_DIR + L"\\" + ffd.cFileName).c_str());
|
||||
thisplugin.filename = ffd.cFileName;
|
||||
|
||||
if (thisplugin.handle == NULL)
|
||||
continue;
|
||||
|
||||
auto nameFunc = (LPCWSTR(*)())GetProcAddress(thisplugin.handle, "GetPluginName");
|
||||
auto descFunc = (LPCWSTR(*)())GetProcAddress(thisplugin.handle, "GetPluginDescription");
|
||||
auto optsFunc = (PluginConfig::PluginConfigArray(*)())GetProcAddress(thisplugin.handle, "GetPluginOptions");
|
||||
|
||||
if (nameFunc != NULL)
|
||||
thisplugin.name = nameFunc();
|
||||
else
|
||||
thisplugin.name = thisplugin.filename;
|
||||
|
||||
if (descFunc != NULL)
|
||||
thisplugin.description = descFunc();
|
||||
else
|
||||
thisplugin.description = (thisplugin.filename + L" Plugin").c_str();
|
||||
|
||||
if (optsFunc != NULL)
|
||||
thisplugin.configopts = PluginConfig::GetConfigOptionVec(optsFunc());
|
||||
|
||||
// sometimes this might screw with custom button config, so let's just not free stuff
|
||||
// FreeLibrary(thisplugin.handle);
|
||||
|
||||
outvec.push_back(thisplugin);
|
||||
}
|
||||
}
|
||||
} while (FindNextFileW(hFind, &ffd));
|
||||
FindClose(hFind);
|
||||
}
|
||||
|
||||
return outvec;
|
||||
}
|
||||
// don't load until actually needed to avoid loading disabled plugins
|
||||
std::vector<PluginInfo> AllPlugins; // = LoadPlugins();
|
||||
|
||||
std::vector<PluginOption*> GetPluginOptions(std::vector<PluginInfo>* plugins)
|
||||
{
|
||||
std::vector<PluginOption*> outvec;
|
||||
|
||||
for (PluginInfo &pi : *plugins)
|
||||
{
|
||||
PluginOption* opt = new PluginOption(pi.filename.c_str(), L"plugins", CONFIG_FILE, pi.name.c_str(), pi.description.c_str(), true, pi.configopts);
|
||||
outvec.push_back(opt);
|
||||
}
|
||||
|
||||
return outvec;
|
||||
}
|
||||
// don't load until actually needed to avoid loading disabled plugins
|
||||
std::vector<PluginOption*> AllPluginOpts; // = GetPluginOptions(&AllPlugins);
|
||||
|
||||
|
||||
// used to trick Optimus into switching to the NVIDIA GPU
|
||||
HMODULE nvcudaModule = LoadLibraryW(L"nvcuda.dll");
|
||||
// cuInit actually returns a CUresult, but we don't really care about it
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <GL\freeglut.h>
|
||||
#include <GL\GL.h>
|
||||
#include "SkinnedMessageBox.h"
|
||||
#include "PluginConfig.h"
|
||||
|
||||
namespace Launcher {
|
||||
|
||||
@@ -90,6 +91,7 @@ namespace Launcher {
|
||||
this->panel_Patches->PerformLayout();
|
||||
|
||||
|
||||
|
||||
this->panel_Playerdata->SuspendLayout();
|
||||
|
||||
// populate playerdata options from array in framework
|
||||
@@ -118,6 +120,20 @@ namespace Launcher {
|
||||
this->panel_Components->PerformLayout();
|
||||
|
||||
|
||||
AllPlugins = LoadPlugins();
|
||||
AllPluginOpts = GetPluginOptions(&AllPlugins);
|
||||
|
||||
this->panel_Plugins->SuspendLayout();
|
||||
|
||||
int pluginsY = 3;
|
||||
for (ConfigOptionBase* option : AllPluginOpts)
|
||||
{
|
||||
option->hasChanged = ConfigHasChanged;
|
||||
pluginsY += option->AddToPanel(panel_Plugins, 12, pluginsY, toolTip1);
|
||||
}
|
||||
this->panel_Plugins->ResumeLayout(false);
|
||||
this->panel_Plugins->PerformLayout();
|
||||
|
||||
|
||||
// trick Optimus into switching to the NVIDIA GPU
|
||||
if (cuInit != NULL) cuInit(0);
|
||||
@@ -176,6 +192,8 @@ namespace Launcher {
|
||||
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::TabPage^ tabPage_Plugins;
|
||||
private: System::Windows::Forms::Panel^ panel_Plugins;
|
||||
private: System::Windows::Forms::Button^ button_Discord;
|
||||
private: System::Windows::Forms::Button^ button_github;
|
||||
private: System::Windows::Forms::TabPage^ tabPage_Playerdata;
|
||||
@@ -231,6 +249,8 @@ namespace Launcher {
|
||||
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->tabPage_Plugins = (gcnew System::Windows::Forms::TabPage());
|
||||
this->panel_Plugins = (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));
|
||||
@@ -242,6 +262,7 @@ namespace Launcher {
|
||||
this->tabPage_Patches->SuspendLayout();
|
||||
this->tabPage_Playerdata->SuspendLayout();
|
||||
this->tabPage_Components->SuspendLayout();
|
||||
this->tabPage_Plugins->SuspendLayout();
|
||||
this->SuspendLayout();
|
||||
//
|
||||
// button_Launch
|
||||
@@ -299,6 +320,7 @@ namespace Launcher {
|
||||
this->tabControl->Controls->Add(this->tabPage_Patches);
|
||||
this->tabControl->Controls->Add(this->tabPage_Playerdata);
|
||||
this->tabControl->Controls->Add(this->tabPage_Components);
|
||||
this->tabControl->Controls->Add(this->tabPage_Plugins);
|
||||
this->tabControl->Location = System::Drawing::Point(0, 0);
|
||||
this->tabControl->Margin = System::Windows::Forms::Padding(4);
|
||||
this->tabControl->Name = L"tabControl";
|
||||
@@ -420,6 +442,28 @@ namespace Launcher {
|
||||
this->panel_Components->Size = System::Drawing::Size(429, 425);
|
||||
this->panel_Components->TabIndex = 0;
|
||||
//
|
||||
// tabPage_Plugins
|
||||
//
|
||||
this->tabPage_Plugins->BackColor = System::Drawing::Color::FromArgb(static_cast<System::Int32>(static_cast<System::Byte>(64)),
|
||||
static_cast<System::Int32>(static_cast<System::Byte>(64)), static_cast<System::Int32>(static_cast<System::Byte>(64)));
|
||||
this->tabPage_Plugins->Controls->Add(this->panel_Plugins);
|
||||
this->tabPage_Plugins->Location = System::Drawing::Point(4, 32);
|
||||
this->tabPage_Plugins->Margin = System::Windows::Forms::Padding(4);
|
||||
this->tabPage_Plugins->Name = L"tabPage_Plugins";
|
||||
this->tabPage_Plugins->Padding = System::Windows::Forms::Padding(4);
|
||||
this->tabPage_Plugins->Size = System::Drawing::Size(433, 429);
|
||||
this->tabPage_Plugins->TabIndex = 3;
|
||||
this->tabPage_Plugins->Text = L"Plugins";
|
||||
//
|
||||
// panel_Plugins
|
||||
//
|
||||
this->panel_Plugins->AutoScroll = true;
|
||||
this->panel_Plugins->Location = System::Drawing::Point(0, 0);
|
||||
this->panel_Plugins->Margin = System::Windows::Forms::Padding(4);
|
||||
this->panel_Plugins->Name = L"panel_Plugins";
|
||||
this->panel_Plugins->Size = System::Drawing::Size(429, 425);
|
||||
this->panel_Plugins->TabIndex = 0;
|
||||
//
|
||||
// button_Discord
|
||||
//
|
||||
this->button_Discord->BackColor = System::Drawing::Color::Transparent;
|
||||
@@ -504,6 +548,7 @@ namespace Launcher {
|
||||
this->tabPage_Patches->ResumeLayout(false);
|
||||
this->tabPage_Playerdata->ResumeLayout(false);
|
||||
this->tabPage_Components->ResumeLayout(false);
|
||||
this->tabPage_Plugins->ResumeLayout(false);
|
||||
this->ResumeLayout(false);
|
||||
|
||||
}
|
||||
@@ -533,6 +578,11 @@ private: System::Void SaveSettings() {
|
||||
{
|
||||
component->SaveOption();
|
||||
}
|
||||
|
||||
for (ConfigOptionBase* option : AllPluginOpts)
|
||||
{
|
||||
option->SaveOption();
|
||||
}
|
||||
}
|
||||
private: System::Void Ui_Load(System::Object^ sender, System::EventArgs^ e){
|
||||
}
|
||||
|
||||
@@ -16,5 +16,6 @@ namespace TLAC::Components
|
||||
bool ShowExcellentClearBorder;
|
||||
bool UseCard;
|
||||
bool GameModifierOptions;
|
||||
bool ActionSE;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -237,6 +237,7 @@ namespace TLAC::Components
|
||||
customPlayerData->ShowGreatClearBorder = config.GetBooleanValue("border_great");
|
||||
customPlayerData->UseCard = config.GetBooleanValue("use_card");
|
||||
customPlayerData->GameModifierOptions = config.GetBooleanValue("gamemode_options");
|
||||
customPlayerData->ActionSE = config.GetBooleanValue("act_toggle");
|
||||
moduleCardWorkaround = config.GetBooleanValue("module_card_workaround");
|
||||
|
||||
if (moduleCardWorkaround) {
|
||||
@@ -313,15 +314,14 @@ namespace TLAC::Components
|
||||
setIfNotEqual(&playerData->btn_se_equip, customPlayerData->BtnSeEquip, -1);
|
||||
setIfNotEqual(&playerData->slide_se_equip, customPlayerData->SlideSeEquip, -1);
|
||||
setIfNotEqual(&playerData->chainslide_se_equip, customPlayerData->ChainslideSeEquip, -1);
|
||||
setIfNotEqual(&playerData->act_toggle, customPlayerData->ActionSE, 1);
|
||||
|
||||
// Display clear borders on the progress bar
|
||||
*(byte*)(PLAYER_DATA_ADDRESS + 0xD94) = (customPlayerData->ShowExcellentClearBorder << 1) | (customPlayerData->ShowGreatClearBorder);
|
||||
|
||||
if (customPlayerData->UseCard)
|
||||
playerData->use_card = 1; // required to allow for module selection
|
||||
playerData->use_card = customPlayerData->UseCard; // required to allow for module selection
|
||||
|
||||
if (customPlayerData->GameModifierOptions)
|
||||
playerData->game_opts = 1; // hi-speed, etc..
|
||||
playerData->game_opts = customPlayerData->GameModifierOptions; // hi-speed, etc..
|
||||
|
||||
memset((void*)MODULE_TABLE_START, 0xFF, 128);
|
||||
memset((void*)ITEM_TABLE_START, 0xFF, 128);
|
||||
|
||||
Reference in New Issue
Block a user