2.6: start.bat, quick start warning, fully fix hand size, gamma control, fix coin, customizable toon key, rumble intensity, error 998 explaination, divawig enum, launcher option tab cleanup, gpu driver version detection, precise lag compensation, 7.10 check

This commit is contained in:
nastys
2021-09-20 22:12:41 +02:00
parent f93dab0b9a
commit 4ebc4b3f85
17 changed files with 812 additions and 457 deletions
+1 -1
View File
@@ -184,7 +184,7 @@ void LoadDVA(std::wstring &path, LPCWSTR dir, LPCWSTR fileName)
msg.append(L"\n\nIs the Microsoft Visual C++ Redistributable for Visual Studio 2019 (x64) installed?");
break;
case 998:
msg.append(L"\n\nAre all dependencies installed?\nIf the problem persists, please disable this plugin.");
msg.append(L"\n\nPossible causes:\n- a dependency is not installed; or\n- GPU detection failed (select the GPU Type manually/force Novidia in its Config).");
break;
default:
msg.append(L"\n\nAre all dependencies installed?");
+30 -27
View File
@@ -7,33 +7,36 @@
#include <tchar.h>
#include <thread>
#define HEAD_ACCESSORY 0
#define HAIR 1
#define UNKNOWN_1 2
#define UNKNOWN_2 3
#define FACE_ACCESSORY 4
#define UNKNOWN_3 5
#define FACE_TEXTURES 6
#define UNKNOWN_4 7
#define CHEST_ACCESSORY 8
#define UNKNOWN_5 9
#define BODY 10
#define UNKNOWN_6 11
#define UNKNOWN_7 12
#define UNKNOWN_8 13
#define HANDS 14,
#define UNKNOWN_9 15
#define BACK_ACCESSORY 16
#define UNKNOWN_10 17
#define UNKNOWN_11 18
#define UNKNOWN_12 19
#define UNKNOWN_13 20
#define UNKNOWN_14 21
#define UNKNOWN_15 22
#define UNKNOWN_16 23
#define HEAD 24
#define ALL -1
#define NONE -2
static const enum module_part
{
HEAD_ACCESSORY,
HAIR,
UNKNOWN_1,
UNKNOWN_2,
FACE_ACCESSORY,
UNKNOWN_3,
FACE_TEXTURES,
UNKNOWN_4,
CHEST_ACCESSORY,
UNKNOWN_5,
BODY,
UNKNOWN_6,
UNKNOWN_7,
UNKNOWN_8,
HANDS,
UNKNOWN_9,
BACK_ACCESSORY,
UNKNOWN_10,
UNKNOWN_11,
UNKNOWN_12,
UNKNOWN_13,
UNKNOWN_14,
UNKNOWN_15,
UNKNOWN_16,
HEAD,
ALL = -1,
NONE = -2
};
using namespace std;
@@ -285,6 +285,43 @@ public:
}
};
class OptionMetaSectionLabel : public ConfigOptionBase
{
public:
OptionMetaSectionLabel(LPCWSTR friendlyName)
{
_friendlyName = friendlyName;
}
virtual int AddToPanel(Panel^ panel, unsigned int left, unsigned int top, ToolTip^ tooltip)
{
Label^ lab = gcnew Label();
lab->Text = gcnew String(_friendlyName);
lab->Left = left + 2;
lab->Top = top;
lab->Font = gcnew System::Drawing::Font(lab->Font->Name, 12.0f, System::Drawing::FontStyle::Bold);
lab->AutoSize = true;
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;
}
lab->Scale(ScaleWidth, ScaleHeight);
panel->Controls->Add(lab);
mainControlHandle = lab->Handle;
int ControlHeight = lab->Font->Height / ScaleHeight;
return ControlHeight + ControlSpacing;
}
};
class OptionMetaSpacer : public ConfigOptionBase
{
public:
+27 -23
View File
@@ -167,6 +167,7 @@ ConfigOptionBase* graphicsArray[] = {
new BooleanOption(L"reflections", GRAPHICS_SECTION, CONFIG_FILE, L"Reflections", L"Enable or disable reflections.", true, false),
new ResolutionOption(L"reflect_res_width", L"reflect_res_height", GRAPHICS_SECTION, CONFIG_FILE, L"Reflection Res:", L"Sets the reflection buffer resolution (instead of 512x256).", resolution(512, 256), std::vector<resolution>({resolution(256,256), resolution(512,256), resolution(512,512), resolution(1024,1024), resolution(2048,2048), resolution(4096,4096)}), true, (ResolutionOptionOpts)0),
new ResolutionOption(L"refract_res_width", L"refract_res_height", GRAPHICS_SECTION, CONFIG_FILE, L"Refraction Res:", L"Sets the refraction buffer resolution (instead of 512x256).", resolution(512, 256), std::vector<resolution>({resolution(256,256), resolution(512,256), resolution(512,512), resolution(1024,1024), resolution(2048,2048), resolution(4096,4096)}), true, (ResolutionOptionOpts)0),
new NumericOption(L"gamma", GRAPHICS_SECTION, CONFIG_FILE, L"Gamma:", L"Increase to darken shadows.\nSet to 125 for a console-like experience.\n\nDefault: 0 or 100", 100, 0, 200),
new BooleanOption(L"shadows", GRAPHICS_SECTION, CONFIG_FILE, L"Shadows", L"Enable or disable shadows.", true, false),
new BooleanOption(L"punchthrough", GRAPHICS_SECTION, CONFIG_FILE, L"Transparent Meshes", L"Show transparent meshes.", true, false),
new BooleanOption(L"glare", GRAPHICS_SECTION, CONFIG_FILE, L"Glare", L"Enable or disable glare.", true, false),
@@ -177,6 +178,7 @@ ConfigOptionBase* graphicsArray[] = {
};
ConfigOptionBase* optionsArray[] = {
new OptionMetaSectionLabel(L"Compatibility"),
new BooleanOption(L"no_movies", PATCHES_SECTION, CONFIG_FILE, L"Disable Movies", L"Disable movies (enable this if the game hangs when loading certain PVs).", false, false),
new BooleanOption(L"mp4_movies", PATCHES_SECTION, CONFIG_FILE, L"Custom MP4 Adv Movies", L"Enable MP4 (instead of WMV) advertise/attract movies.", false, false),
new BooleanOption(L"cursor", PATCHES_SECTION, CONFIG_FILE, L"Cursor", L"Enable or disable the mouse cursor.", true, false),
@@ -184,25 +186,41 @@ ConfigOptionBase* optionsArray[] = {
new OptionMetaSeparator(),
new OptionMetaSpacer(8),
new OptionMetaSectionLabel(L"Controller Options"),
new BooleanOption(L"rumble", KEYCONFIG_SECTION, KEYCONFIG_FILE, L"XInput Rumble", L"Enables rumble during chainslides.", true, true),
new NumericOption(L"xinput_rumble_intensity_left", KEYCONFIG_SECTION, KEYCONFIG_FILE, L"Left motor:", L"Left rumble motor intensity (XInput).\n\nDefault: 8000", 8000, 0, USHRT_MAX),
new NumericOption(L"xinput_rumble_intensity_right", KEYCONFIG_SECTION, KEYCONFIG_FILE, L"Right motor:", L"Right rumble motor intensity (XInput).\n\nDefault: 4000", 4000, 0, USHRT_MAX),
new NumericOption(L"xinput_preferred", KEYCONFIG_SECTION, KEYCONFIG_FILE, L"XInput Controller Num:", L"Sets the preferred XInput controller.\nIf unavailable, the next connected controller is used.", 0, 0, 3),
new BooleanOption(L"hardware_slider", PATCHES_SECTION, CONFIG_FILE, L"Use Hardware Slider", L"Enable this if using a real arcade slider.\n(set the slider to port COM11)", false, false),
new OptionMetaSeparator(),
new OptionMetaSpacer(8),
new OptionMetaSectionLabel(L"PV Selector"),
new DropdownOption(L"quick_start", PATCHES_SECTION, CONFIG_FILE, L"Quick Start:", L"Skip one or more menus.", 1, std::vector<LPCWSTR>({ L"Disabled", L"Guest", L"Guest + Normal" })),
new BooleanOption(L"no_scrolling_sfx", PATCHES_SECTION, CONFIG_FILE, L"Disable Scrolling SFX", L"Disable the scrolling sound effect.", false, false),
new BooleanOption(L"unlock_pseudo", PATCHES_SECTION, CONFIG_FILE, L"Unlock PSEUDO modules (incomplete)", L"Lets you play any PV with any performer.\n(incomplete, recommended modules will default to Miku)", false, false),
new BooleanOption(L"card", PATCHES_SECTION, CONFIG_FILE, L"Unlock card menu (incomplete)", L"Enables the card menu.\n(incomplete, it doesn't bypass the card prompt)", false, false),
new OptionMetaSeparator(),
new OptionMetaSpacer(8),
new OptionMetaSectionLabel(L"Stages/Songs"),
new NumericOption(L"Enhanced_Stage_Manager", PATCHES_SECTION, CONFIG_FILE, L"Number of Stages:", L"Set the number of stages (0 = default).", 0, 0, INT_MAX),
new BooleanOption(L"Enhanced_Stage_Manager_Encore", PATCHES_SECTION, CONFIG_FILE, L"Encore", L"Enable encore stages.", true, false),
new BooleanOption(L"sing_missed", PATCHES_SECTION, CONFIG_FILE, L"Sing Missed", L"Sing missed notes.", false, false),
new BooleanOption(L"autopause", KEYCONFIG_SECTION, KEYCONFIG_FILE, L"Pause Automatically", L"Pause when focus is lost.", true, true),
new OptionMetaSeparator(),
new OptionMetaSpacer(8),
new OptionMetaSectionLabel(L"PV Customization"),
new DropdownOption(L"force_mouth", PATCHES_SECTION, CONFIG_FILE, L"Mouth Type:", L"Change the mouth animations.", 0, std::vector<LPCWSTR>({ L"Default", L"Force PDA", L"Force FT" })),
new DropdownOption(L"force_expressions", PATCHES_SECTION, CONFIG_FILE, L"Expression Type:", L"Change the expressions.", 0, std::vector<LPCWSTR>({ L"Default", L"Force PDA", L"Force FT" })),
new DropdownOption(L"force_look", PATCHES_SECTION, CONFIG_FILE, L"Look Type:", L"Change the look animations.", 0, std::vector<LPCWSTR>({ L"Default", L"Force PDA", L"Force FT" })),
new BooleanOption(L"no_hand_scaling", PATCHES_SECTION, CONFIG_FILE, L"No Hand Scaling", L"Disable hand scaling.", false, false),
new NumericOption(L"default_hand_size", PATCHES_SECTION, CONFIG_FILE, L"Default Hand Size:", L"-1: default\n12200: PDA", -1, -1, INT_MAX),
new BooleanOption(L"sing_missed", PATCHES_SECTION, CONFIG_FILE, L"Sing Missed", L"Sing missed notes.", false, false),
new NumericOption(L"default_hand_size", PATCHES_SECTION, CONFIG_FILE, L"Default Hand Size:", L"0-10000: default\n12200: PDA", 0, 0, INT_MAX),
new OptionMetaSeparator(),
new OptionMetaSpacer(8),
new OptionMetaSectionLabel(L"UI Elements"),
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_pv_ui", PATCHES_SECTION, CONFIG_FILE, L"Disable PV UI", L"Remove the photo controls during PV playback.", false, false),
new BooleanOption(L"hide_pv_watermark", PATCHES_SECTION, CONFIG_FILE, L"Hide PV Watermark", L"Hide the watermark that's usually shown in PV viewing mode.", false, false),
@@ -217,46 +235,32 @@ ConfigOptionBase* optionsArray[] = {
new OptionMetaSeparator(),
new OptionMetaSpacer(8),
new BooleanOption(L"unlock_pseudo", PATCHES_SECTION, CONFIG_FILE, L"Unlock PSEUDO modules (incomplete)", L"Lets you play any PV with any performer.\n(incomplete, recommended modules will default to Miku)", false, false),
new BooleanOption(L"card", PATCHES_SECTION, CONFIG_FILE, L"Unlock card menu (incomplete)", L"Enables the card menu.\n(incomplete, it doesn't bypass the card prompt)", false, false),
new OptionMetaSeparator(),
new OptionMetaSpacer(8),
new OptionMetaSectionLabel(L"Framerate"),
new BooleanOption(L"FPS.Limit.LightMode", GRAPHICS_SECTION, CONFIG_FILE, L"Use Lightweight Limiter", L"Makes the FPS limiter use less CPU.\nMay have less consistent performance.", true, false),
new NumericOption(L"FPS.Limit", GRAPHICS_SECTION, CONFIG_FILE, L"FPS Limit:", L"Allows you to set a frame rate cap. Set to -1 to unlock the frame rate.", 60, -1, INT_MAX),
new NumericOption(L"frm.motion.rate", GRAPHICS_SECTION, CONFIG_FILE, L"FRM Motion Rate:", L"Sets the motion rate (fps) for the Frame Rate Manager component.\nLarger values should be smoother, but more CPU intensive and possibly buggier.", 300, 1, INT_MAX),
new OptionMetaSeparator(),
new OptionMetaSpacer(8),
new BooleanOption(L"autopause", KEYCONFIG_SECTION, KEYCONFIG_FILE, L"Pause Automatically", L"Pause when focus is lost.", true, true),
new OptionMetaSeparator(),
new OptionMetaSpacer(8),
new BooleanOption(L"rumble", KEYCONFIG_SECTION, KEYCONFIG_FILE, L"XInput Rumble", L"Enables rumble during chainslides.", true, true),
new NumericOption(L"xinput_preferred", KEYCONFIG_SECTION, KEYCONFIG_FILE, L"XInput Controller Num:", L"Sets the preferred XInput controller.\nIf unavailable, the next connected controller is used.", 0, 0, 3),
new OptionMetaSeparator(),
new OptionMetaSpacer(8),
new BooleanOption(L"hardware_slider", PATCHES_SECTION, CONFIG_FILE, L"Use Hardware Slider", L"Enable this if using a real arcade slider.\n(set the slider to port COM11)", false, false),
new OptionMetaSeparator(),
new OptionMetaSpacer(8),
new OptionMetaSectionLabel(L"Advanced Compatibility"),
new BooleanOption(L"opengl_patch_a", LAUNCHER_SECTION, CONFIG_FILE, L"OpenGL Patch A", L"Ignores some OpenGL-related errors. Don't use both patches at the same time unless you're know what you're doing.", false, false),
new BooleanOption(L"opengl_patch_b", LAUNCHER_SECTION, CONFIG_FILE, L"OpenGL Patch B", L"Ignores some OpenGL-related errors. Don't use both patches at the same time unless you're know what you're doing.", false, false),
new OptionMetaSeparator(),
new OptionMetaSpacer(8),
new OptionMetaSectionLabel(L"Loader"),
new BooleanOption(L"custom_patches", PATCHES_SECTION, CONFIG_FILE, L"Enable Custom Patches", L"Enables all custom patches.", true, false),
//new BooleanOption(L"ignore_exe_checksum", PATCHES_SECTION, CONFIG_FILE, L"Ignore exe checksum", L"Use at your own risk.", false, false),
new BooleanOption(L"prevent_data_deletion", PATCHES_SECTION, CONFIG_FILE, L"Prevent Data Deletion", L"Prevents the game from deleting files.", false, false),
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),
new BooleanOption(L"use_divahook_bat", LAUNCHER_SECTION, CONFIG_FILE, L"Use divahook.bat", L"Launches divahook.bat intead of diva.exe.", false, false),
new OptionMetaSeparator(),
new OptionMetaSpacer(8),
new OptionMetaSectionLabel(L"Launcher"),
new BooleanOption(L"dark_launcher", LAUNCHER_SECTION, CONFIG_FILE, L"Dark Launcher", L"Sets the dark colour scheme in the launcher.", false, false),
new BooleanOption(L"acrylic_blur", LAUNCHER_SECTION, CONFIG_FILE, L"Acrylic Blur", L"Enables acrylic blur in the launcher on Windows 10 20H2 or later.", false, false),
new BooleanOption(L"no_gpu_dialog", LAUNCHER_SECTION, CONFIG_FILE, L"Disable GPU Warning", L"Disables the warning dialog for unsupported GPUs.", false, false),
//new BooleanOption(L"ignore_exe_checksum", PATCHES_SECTION, CONFIG_FILE, L"Ignore exe checksum", L"Use at your own risk.", false, false),
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),
new BooleanOption(L"use_divahook_bat", LAUNCHER_SECTION, CONFIG_FILE, L"Use divahook.bat/start.bat", L"Launches divahook.bat/start.bat intead of diva.exe.", false, false),
};
ConfigOptionBase* playerdataArray[] = {
+298 -123
View File
@@ -10,6 +10,7 @@
#include "GPUModel.h"
#include "WineVer.h"
#include "composition.h"
#include <filesystem>
namespace Launcher {
@@ -198,11 +199,26 @@ namespace Launcher {
vendor = vendor->Replace(" Corporation", ""); // this is useless.. remove it to help ensure the GPU type line fits
String^ renderer = gcnew String((char*)glGetString(GL_RENDERER));
String^ version = gcnew String((char*)glGetString(GL_VERSION));
version = version->Replace(" Profile Context", ""); // we don't need this, either
String^ gpuModel = gcnew String(GPUModel::getGpuName().c_str());
String^ wineVersion = gcnew String(WineVer::getWineVer().c_str());
int driver_version_major = 1;
int driver_version_minor = 0;
auto version_split = version->Split(' ');
if (version_split->Length > 1) // make sure we don't use the OpenGL version instead of the driver version
{
String^ driver_version = gcnew String(version_split[version_split->Length - 1]);
auto driver_version_split_major_minor = driver_version->Split('.');
if (driver_version_split_major_minor->Length >= 2)
{
driver_version_major = int::Parse(driver_version_split_major_minor[0]);
driver_version_minor = int::Parse(driver_version_split_major_minor[1]);
}
}
glutDestroyWindow(window); // destroy the window so it doesn't remain on screen
if (glutMainLoopEventDynamic != NULL) glutMainLoopEventDynamic(); // freeglut needs this
@@ -227,9 +243,19 @@ namespace Launcher {
if (hasNovidia)
{
this->labelGPU->Text += "Issues: AMD GPU support is unofficial.";
GPUIssueText = "AMD GPUs are not supported without mods.\nThe PD Loader AMDPack seems to be installed, but please keep in mind that it may have issues.";
this->labelGPU->LinkColor = System::Drawing::Color::Yellow;
if (wineVersion == "" && (driver_version_major < 21 || (driver_version_major == 21 && driver_version_minor < 6)))
{
this->labelGPU->Text += L"Driver has known issues.";
GPUIssueText = L"The graphics driver you're using has known issues. Please install the latest driver from your GPU vendor's website.";
this->labelGPU->LinkColor = System::Drawing::Color::Orange;
showGpuDialog = true;
}
else
{
this->labelGPU->Text += "Issues: AMD GPU support is unofficial.";
GPUIssueText = "AMD GPUs are not supported without mods.\nThe PD Loader AMDPack seems to be installed, but please keep in mind that it may have issues.";
this->labelGPU->LinkColor = System::Drawing::Color::Yellow;
}
}
else
{
@@ -239,71 +265,81 @@ namespace Launcher {
showGpuDialog = true;
}
}
else if (!vendor->Contains("NVIDIA"))
else if (vendor->Contains("NVIDIA"))
{
this->labelGPU->Text += "Issues: UNSUPPORTED GPU!";
GPUIssueText = "Your graphics card is not supported. Only NVIDIA GPUs are recommended. (though AMD ones can be used with mods)\nPlease use a GTX 600 series or later NVIDIA GPU.\n\nIf you have a laptop with an NVIDIA GPU and wish to use it instead of the detected GPU, you may need to set diva.exe to use it in Windows settings or NVIDIA Control Panel.\n\nOwners of other GPUs may be able to run the game using plugins or mods, but 3D graphics will probably not work.";
this->labelGPU->LinkColor = System::Drawing::Color::Red;
showGpuDialog = true;
}
else if (gpuModel->StartsWith("GA")) // unconfirmed??
{
this->labelGPU->Text += "Issues: Ampere GPU detected! Unknown issues.\n(Click for more information)";
GPUIssueText = "Ampere GPUs have not been tested yet. On the previous generation Turing GPUs (GTX 16xx/RTX 20xx), some important character shaders have issues resulting in lines/noise.\nPlease make sure the ShaderPatch plugin is enabled and report any further issues to the developers.";
this->labelGPU->LinkColor = System::Drawing::Color::Yellow;
}
else if (gpuModel->StartsWith("TU"))
{
this->labelGPU->Text += "Issues: Turing GPU detected! Possible noise.\n(Click for more information)";
GPUIssueText = "On Turing GPUs (GTX 16xx/RTX 20xx), some important character shaders have issues resulting in lines/noise.\nPlease make sure the ShaderPatch plugin is enabled.";
this->labelGPU->LinkColor = System::Drawing::Color::Yellow;
}
else if (gpuModel->StartsWith("GM") || gpuModel->StartsWith("GP") || gpuModel->StartsWith("GV"))
{
this->labelGPU->Text += "Issues: May have minor noise on some stages.\n(Click for more information)";
GPUIssueText = "On Maxwell GPUs (~GTX 900) or newer, some minor stage shaders create noise.\nPlease make sure the ShaderPatch plugin is enabled.";
this->labelGPU->LinkColor = System::Drawing::Color::Teal;
}
else if (gpuModel->StartsWith("GK"))
{
this->labelGPU->Text += "Issues: None.";
GPUIssueText = "Your GPU should have no issues running the game.";
this->labelGPU->LinkColor = System::Drawing::Color::LightBlue;
}
else if (gpuModel->StartsWith("GF"))
{
if (version[0] < '4')
if (wineVersion == "" && (driver_version_major > 446 && driver_version_major < 460))
{
this->labelGPU->Text += "Issues: Driver too old.";
GPUIssueText = "Your GPU should be able to run the game, but it looks like your OpenGL version is too old.\nA driver update should fix this.";
this->labelGPU->Text += L"Driver has known issues.";
GPUIssueText = L"The graphics driver you're using has known issues. Please install the latest driver from your GPU vendor's website.";
this->labelGPU->LinkColor = System::Drawing::Color::Orange;
showGpuDialog = true;
}
else
else if (gpuModel->StartsWith("GA")) // unconfirmed??
{
this->labelGPU->Text += "Issues: No known issues.";
GPUIssueText = "Your GPU should have no issues running the game, but it is older than the GPU the game was originally designed for (GTX 650 Ti).\nThere may be some issues with graphics.\nPlease report any issues so that they can be analysed and potentially fixed.";
this->labelGPU->Text += L"Issues: Ampere GPU detected! Possible noise.\n(Click for more information)";
GPUIssueText = L"On Ampere GPUs (RTX 30xx), some important character shaders have issues resulting in lines/noise.\nPlease make sure the ShaderPatch plugin is enabled.";
this->labelGPU->LinkColor = System::Drawing::Color::Yellow;
}
else if (gpuModel->StartsWith("TU") || gpuModel->StartsWith("GV")) // let's assume Volta is like Turing for now
{
this->labelGPU->Text += L"Issues: Ampere GPU detected! Possible noise.\n(Click for more information)";
GPUIssueText = L"On Turing GPUs (GTX 16xx/RTX 20xx), some important character shaders have issues resulting in lines/noise.\nPlease make sure the ShaderPatch plugin is enabled.";
this->labelGPU->LinkColor = System::Drawing::Color::Yellow;
}
else if (gpuModel->StartsWith("GM") || gpuModel->StartsWith("GP"))
{
this->labelGPU->Text += L"Issues: May have minor noise on some stages.\n(Click for more information)";
GPUIssueText = L"On Maxwell GPUs (~GTX 900) and newer, some minor stage shaders create noise.\nPlease make sure the ShaderPatch plugin is enabled.";
this->labelGPU->LinkColor = System::Drawing::Color::Teal;
}
}
else if (version[0] >= '4' && gpuModel->Length > 0 && !gpuModel->StartsWith("Unk") && !gpuModel->StartsWith("Oth"))
{
this->labelGPU->Text += "Issues: GPU may be too new.\n(Click for more information)";
GPUIssueText = "It looks like your GPU may be too new. Only up to Turing (GTX 16xx/RTX 20xx) is currently supported.\nGood news: the game should be capable of running, but shader patches (probably needed) may not support it yet.\nYou will likely see lines/noise on important character shaders and some minor stage shaders.\nPlease report any issues so that ShaderPatch can be updated.";
this->labelGPU->LinkColor = System::Drawing::Color::Orange;
}
else if (gpuModel->StartsWith("G") || gpuModel->StartsWith("NV") || gpuModel->StartsWith("NB") || gpuModel->StartsWith("N10") || gpuModel->StartsWith("MCP"))
{
this->labelGPU->Text += "Issues: GPU too old! 3D rendering might be broken.\n(Click for more information)";
GPUIssueText = "Your GPU is very old and does not support rendering techniques used by the game.\nYou may be able to play, but graphics will likely have major issues.\nPlease upgrade to a GTX 600 series or later GPU.";
this->labelGPU->LinkColor = System::Drawing::Color::Orange;
showGpuDialog = true;
else if (gpuModel->StartsWith("GK"))
{
this->labelGPU->Text += L"Issues: None.";
GPUIssueText = L"Your GPU should have no issues running the game.";
this->labelGPU->LinkColor = System::Drawing::Color::LightBlue;
}
else if (gpuModel->StartsWith("GF"))
{
if (version[0] < '4')
{
this->labelGPU->Text += L"Issues: Driver too old.";
GPUIssueText = L"Your GPU should be able to run the game, but it looks like your OpenGL version is too old.\nA driver update should fix this.";
this->labelGPU->LinkColor = System::Drawing::Color::Orange;
showGpuDialog = true;
}
else
{
this->labelGPU->Text += L"Issues: No known issues.";
GPUIssueText = L"Your GPU should have no issues running the game, but it is older than the GPU the game was originally designed for (GTX 650 Ti).\nThere may be some issues with graphics.\nPlease report any issues so that they can be analysed and potentially fixed.";
this->labelGPU->LinkColor = System::Drawing::Color::Teal;
}
}
else if (gpuModel->StartsWith("G") || gpuModel->StartsWith("NV") || gpuModel->StartsWith("NB") || gpuModel->StartsWith("N10") || gpuModel->StartsWith("MCP"))
{
this->labelGPU->Text += L"Issues: GPU too old! 3D rendering might be broken.\n(Click for more information)";
GPUIssueText = L"Your GPU is very old and does not support rendering techniques used by the game.\nYou may be able to play, but graphics will likely have major issues.\nPlease upgrade to a GTX 600 series or later GPU.";
this->labelGPU->LinkColor = System::Drawing::Color::Orange;
showGpuDialog = true;
}
else if (version[0] >= '4' && gpuModel->Length > 0 && !gpuModel->StartsWith("Unk") && !gpuModel->StartsWith("Oth"))
{
this->labelGPU->Text += L"Issues: GPU may be too new.\n(Click for more information)";
GPUIssueText = L"It looks like your GPU may be too new. Only up to Ampere (RTX 30xx) is currently supported.\nGood news: the game should be capable of running, but shader patches (probably needed) may not support it yet.\nYou will likely see lines/noise on important character shaders and some minor stage shaders.\nPlease report any issues so that ShaderPatch can be updated.\nYou can also try forcing a specific GPU workaround type.";
this->labelGPU->LinkColor = System::Drawing::Color::Orange;
}
else
{
this->labelGPU->Text += L"Issues: Unable to detect GPU architecture.\n(Click for more information)";
GPUIssueText = L"It looks like you have an NVIDIA GPU, but something went wrong while trying to determine your GPU's architecture (type).\nThis may be a caused by a bug, but it probably indicates potential issues.\nPlease make sure you have a GTX 600 series or later GPU. (GTX 400 series or later should also work)";
this->labelGPU->LinkColor = System::Drawing::Color::Orange;
showGpuDialog = true;
}
}
else //if (gpuModel->Length == 0 || gpuModel->StartsWith("Unk") || gpuModel->StartsWith("Oth"))
{
this->labelGPU->Text += "Issues: Unable to detect GPU architecture.\n(Click for more information)";
GPUIssueText = "It looks like you have an NVIDIA GPU, but something went wrong while trying to determine your GPU's architecture (type).\nThis may be a caused by a bug, but it probably indicates potential issues.\nPlease make sure you have a GTX 600 series or later GPU. (GTX 400 series or later should also work)";
this->labelGPU->LinkColor = System::Drawing::Color::Orange;
this->labelGPU->Text += L"Issues: UNSUPPORTED GPU!";
GPUIssueText = L"Your graphics card is not supported. Only NVIDIA GPUs are recommended (though AMD ones can be used with mods).\nPlease use a GTX 600 series or later NVIDIA GPU.\n\nIf you have a laptop with an NVIDIA GPU and wish to use it instead of the detected GPU, you may need to set diva.exe to use it in Windows settings or NVIDIA Control Panel.\n\nOwners of other GPUs may be able to run the game using plugins or mods, but 3D graphics will probably not work.";
this->labelGPU->LinkColor = System::Drawing::Color::Red;
showGpuDialog = true;
}
int linkEnd = this->labelGPU->Text->Length - linkStart;
@@ -344,7 +380,7 @@ namespace Launcher {
void updateLagCompMsec()
{
this->groupBox_Lag->Text = "Lag Compensation (" + this->trackBar_LagCompensation->Value * 10 + " msec)";
this->groupBox_Lag->Text = "Lag Compensation (" + this->trackBar_LagCompensation->Value + " msec)";
}
void updateStyle()
@@ -532,29 +568,45 @@ private: System::Windows::Forms::Button^ button_Wiki;
this->tabPage_Plugins->SuspendLayout();
this->tabPage_Credits->SuspendLayout();
this->SuspendLayout();
//
// button_Launch
//
this->button_Launch->BackColor = System::Drawing::Color::White;
this->button_Launch->FlatAppearance->BorderColor = System::Drawing::SystemColors::Control;
this->button_Launch->FlatStyle = System::Windows::Forms::FlatStyle::Flat;
this->button_Launch->Location = System::Drawing::Point(172, 389);
this->button_Launch->Location = System::Drawing::Point(344, 778);
this->button_Launch->Margin = System::Windows::Forms::Padding(6);
this->button_Launch->Name = L"button_Launch";
this->button_Launch->Size = System::Drawing::Size(217, 23);
this->button_Launch->Size = System::Drawing::Size(434, 46);
this->button_Launch->TabIndex = 20;
this->button_Launch->Text = L"Launch";
this->button_Launch->UseVisualStyleBackColor = false;
this->button_Launch->Click += gcnew System::EventHandler(this, &ui::Button_Launch_Click);
//
// groupBox_ScreenRes
//
this->groupBox_ScreenRes->Controls->Add(this->panel_ScreenRes);
this->groupBox_ScreenRes->FlatStyle = System::Windows::Forms::FlatStyle::Flat;
this->groupBox_ScreenRes->Location = System::Drawing::Point(5, 6);
this->groupBox_ScreenRes->Location = System::Drawing::Point(10, 12);
this->groupBox_ScreenRes->Margin = System::Windows::Forms::Padding(6);
this->groupBox_ScreenRes->Name = L"groupBox_ScreenRes";
this->groupBox_ScreenRes->Size = System::Drawing::Size(263, 113);
this->groupBox_ScreenRes->Padding = System::Windows::Forms::Padding(6);
this->groupBox_ScreenRes->Size = System::Drawing::Size(526, 226);
this->groupBox_ScreenRes->TabIndex = 10;
this->groupBox_ScreenRes->TabStop = false;
this->groupBox_ScreenRes->Text = L"Screen Resolution";
//
// panel_ScreenRes
//
this->panel_ScreenRes->AutoScroll = true;
this->panel_ScreenRes->Location = System::Drawing::Point(5, 19);
this->panel_ScreenRes->Location = System::Drawing::Point(10, 38);
this->panel_ScreenRes->Margin = System::Windows::Forms::Padding(6);
this->panel_ScreenRes->Name = L"panel_ScreenRes";
this->panel_ScreenRes->Size = System::Drawing::Size(253, 89);
this->panel_ScreenRes->Size = System::Drawing::Size(506, 178);
this->panel_ScreenRes->TabIndex = 0;
//
// tabControl
//
this->tabControl->Controls->Add(this->tabPage_Resolution);
this->tabControl->Controls->Add(this->tabPage_Patches);
this->tabControl->Controls->Add(this->tabPage_Playerdata);
@@ -562,10 +614,14 @@ private: System::Windows::Forms::Button^ button_Wiki;
this->tabControl->Controls->Add(this->tabPage_Plugins);
this->tabControl->Controls->Add(this->tabPage_Credits);
this->tabControl->Location = System::Drawing::Point(0, 0);
this->tabControl->Margin = System::Windows::Forms::Padding(6);
this->tabControl->Name = L"tabControl";
this->tabControl->SelectedIndex = 0;
this->tabControl->Size = System::Drawing::Size(560, 384);
this->tabControl->Size = System::Drawing::Size(1120, 768);
this->tabControl->TabIndex = 10;
//
// tabPage_Resolution
//
this->tabPage_Resolution->BackColor = System::Drawing::Color::White;
this->tabPage_Resolution->BackgroundImageLayout = System::Windows::Forms::ImageLayout::Stretch;
this->tabPage_Resolution->Controls->Add(this->groupBox_Lag);
@@ -575,181 +631,270 @@ private: System::Windows::Forms::Button^ button_Wiki;
this->tabPage_Resolution->Controls->Add(this->groupBox_ScreenRes);
this->tabPage_Resolution->ForeColor = 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_Resolution->Location = System::Drawing::Point(4, 22);
this->tabPage_Resolution->Location = System::Drawing::Point(8, 39);
this->tabPage_Resolution->Margin = System::Windows::Forms::Padding(6);
this->tabPage_Resolution->Name = L"tabPage_Resolution";
this->tabPage_Resolution->Padding = System::Windows::Forms::Padding(3);
this->tabPage_Resolution->Size = System::Drawing::Size(552, 358);
this->tabPage_Resolution->Padding = System::Windows::Forms::Padding(6);
this->tabPage_Resolution->Size = System::Drawing::Size(1104, 721);
this->tabPage_Resolution->TabIndex = 0;
this->tabPage_Resolution->Text = L"Graphics";
//
// groupBox_Lag
//
this->groupBox_Lag->Controls->Add(this->trackBar_LagCompensation);
this->groupBox_Lag->FlatStyle = System::Windows::Forms::FlatStyle::Flat;
this->groupBox_Lag->Location = System::Drawing::Point(5, 282);
this->groupBox_Lag->Location = System::Drawing::Point(10, 564);
this->groupBox_Lag->Margin = System::Windows::Forms::Padding(6);
this->groupBox_Lag->Name = L"groupBox_Lag";
this->groupBox_Lag->Size = System::Drawing::Size(263, 70);
this->groupBox_Lag->Padding = System::Windows::Forms::Padding(6);
this->groupBox_Lag->Size = System::Drawing::Size(526, 140);
this->groupBox_Lag->TabIndex = 21;
this->groupBox_Lag->TabStop = false;
this->groupBox_Lag->Text = L"Lag Compensation";
this->trackBar_LagCompensation->Location = System::Drawing::Point(7, 20);
this->trackBar_LagCompensation->Maximum = 50;
//
// trackBar_LagCompensation
//
this->trackBar_LagCompensation->LargeChange = 1;
this->trackBar_LagCompensation->Location = System::Drawing::Point(14, 40);
this->trackBar_LagCompensation->Margin = System::Windows::Forms::Padding(6);
this->trackBar_LagCompensation->Maximum = 500;
this->trackBar_LagCompensation->Name = L"trackBar_LagCompensation";
this->trackBar_LagCompensation->Size = System::Drawing::Size(250, 45);
this->trackBar_LagCompensation->Size = System::Drawing::Size(500, 90);
this->trackBar_LagCompensation->TabIndex = 0;
this->trackBar_LagCompensation->ValueChanged += gcnew System::EventHandler(this, &ui::trackBar_LagCompensation_ValueChanged);
//
// groupBox_Details
//
this->groupBox_Details->Controls->Add(this->panel_Details);
this->groupBox_Details->FlatStyle = System::Windows::Forms::FlatStyle::Flat;
this->groupBox_Details->Location = System::Drawing::Point(274, 6);
this->groupBox_Details->Location = System::Drawing::Point(548, 12);
this->groupBox_Details->Margin = System::Windows::Forms::Padding(6);
this->groupBox_Details->Name = L"groupBox_Details";
this->groupBox_Details->Size = System::Drawing::Size(272, 346);
this->groupBox_Details->Padding = System::Windows::Forms::Padding(6);
this->groupBox_Details->Size = System::Drawing::Size(544, 692);
this->groupBox_Details->TabIndex = 11;
this->groupBox_Details->TabStop = false;
this->groupBox_Details->Text = L"Details";
//
// panel_Details
//
this->panel_Details->AutoScroll = true;
this->panel_Details->Location = System::Drawing::Point(5, 19);
this->panel_Details->Location = System::Drawing::Point(10, 38);
this->panel_Details->Margin = System::Windows::Forms::Padding(6);
this->panel_Details->Name = L"panel_Details";
this->panel_Details->Size = System::Drawing::Size(261, 321);
this->panel_Details->Size = System::Drawing::Size(522, 642);
this->panel_Details->TabIndex = 0;
//
// labelGPU
//
this->labelGPU->AutoSize = true;
this->labelGPU->BackColor = System::Drawing::Color::Transparent;
this->labelGPU->ForeColor = System::Drawing::Color::Black;
this->labelGPU->Location = System::Drawing::Point(5, 209);
this->labelGPU->Margin = System::Windows::Forms::Padding(2, 0, 2, 0);
this->labelGPU->MinimumSize = System::Drawing::Size(263, 13);
this->labelGPU->Location = System::Drawing::Point(10, 418);
this->labelGPU->Margin = System::Windows::Forms::Padding(4, 0, 4, 0);
this->labelGPU->MinimumSize = System::Drawing::Size(526, 26);
this->labelGPU->Name = L"labelGPU";
this->labelGPU->Size = System::Drawing::Size(263, 13);
this->labelGPU->Size = System::Drawing::Size(526, 26);
this->labelGPU->TabIndex = 21;
this->labelGPU->TextAlign = System::Drawing::ContentAlignment::MiddleLeft;
//
// groupBox_InternalRes
//
this->groupBox_InternalRes->Controls->Add(this->panel_IntRes);
this->groupBox_InternalRes->FlatStyle = System::Windows::Forms::FlatStyle::Flat;
this->groupBox_InternalRes->Location = System::Drawing::Point(5, 124);
this->groupBox_InternalRes->Location = System::Drawing::Point(10, 248);
this->groupBox_InternalRes->Margin = System::Windows::Forms::Padding(6);
this->groupBox_InternalRes->Name = L"groupBox_InternalRes";
this->groupBox_InternalRes->Size = System::Drawing::Size(263, 83);
this->groupBox_InternalRes->Padding = System::Windows::Forms::Padding(6);
this->groupBox_InternalRes->Size = System::Drawing::Size(526, 166);
this->groupBox_InternalRes->TabIndex = 20;
this->groupBox_InternalRes->TabStop = false;
this->groupBox_InternalRes->Text = L"Internal Resolution (Quality)";
//
// panel_IntRes
//
this->panel_IntRes->AutoScroll = true;
this->panel_IntRes->Location = System::Drawing::Point(5, 19);
this->panel_IntRes->Location = System::Drawing::Point(10, 38);
this->panel_IntRes->Margin = System::Windows::Forms::Padding(6);
this->panel_IntRes->Name = L"panel_IntRes";
this->panel_IntRes->Size = System::Drawing::Size(253, 59);
this->panel_IntRes->Size = System::Drawing::Size(506, 118);
this->panel_IntRes->TabIndex = 1;
//
// tabPage_Patches
//
this->tabPage_Patches->BackColor = System::Drawing::Color::White;
this->tabPage_Patches->Controls->Add(this->panel_Patches);
this->tabPage_Patches->ForeColor = 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_Patches->Location = System::Drawing::Point(4, 22);
this->tabPage_Patches->Location = System::Drawing::Point(8, 39);
this->tabPage_Patches->Margin = System::Windows::Forms::Padding(6);
this->tabPage_Patches->Name = L"tabPage_Patches";
this->tabPage_Patches->Size = System::Drawing::Size(552, 358);
this->tabPage_Patches->Size = System::Drawing::Size(1104, 721);
this->tabPage_Patches->TabIndex = 1;
this->tabPage_Patches->Text = L"Options";
//
// panel_Patches
//
this->panel_Patches->AutoScroll = true;
this->panel_Patches->Location = System::Drawing::Point(0, 0);
this->panel_Patches->Margin = System::Windows::Forms::Padding(6);
this->panel_Patches->Name = L"panel_Patches";
this->panel_Patches->Size = System::Drawing::Size(552, 358);
this->panel_Patches->Size = System::Drawing::Size(1104, 716);
this->panel_Patches->TabIndex = 9;
//
// tabPage_Playerdata
//
this->tabPage_Playerdata->BackColor = System::Drawing::Color::White;
this->tabPage_Playerdata->Controls->Add(this->panel_Playerdata);
this->tabPage_Playerdata->ForeColor = 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_Playerdata->Location = System::Drawing::Point(4, 22);
this->tabPage_Playerdata->Location = System::Drawing::Point(8, 39);
this->tabPage_Playerdata->Margin = System::Windows::Forms::Padding(6);
this->tabPage_Playerdata->Name = L"tabPage_Playerdata";
this->tabPage_Playerdata->Size = System::Drawing::Size(552, 358);
this->tabPage_Playerdata->Size = System::Drawing::Size(1104, 721);
this->tabPage_Playerdata->TabIndex = 3;
this->tabPage_Playerdata->Text = L"Player";
//
// panel_Playerdata
//
this->panel_Playerdata->AutoScroll = true;
this->panel_Playerdata->Location = System::Drawing::Point(0, 0);
this->panel_Playerdata->Margin = System::Windows::Forms::Padding(6);
this->panel_Playerdata->Name = L"panel_Playerdata";
this->panel_Playerdata->Size = System::Drawing::Size(552, 358);
this->panel_Playerdata->Size = System::Drawing::Size(1104, 716);
this->panel_Playerdata->TabIndex = 1;
//
// tabPage_Components
//
this->tabPage_Components->BackColor = System::Drawing::Color::White;
this->tabPage_Components->Controls->Add(this->panel_Components);
this->tabPage_Components->ForeColor = 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_Components->Location = System::Drawing::Point(4, 22);
this->tabPage_Components->Location = System::Drawing::Point(8, 39);
this->tabPage_Components->Margin = System::Windows::Forms::Padding(6);
this->tabPage_Components->Name = L"tabPage_Components";
this->tabPage_Components->Padding = System::Windows::Forms::Padding(3);
this->tabPage_Components->Size = System::Drawing::Size(552, 358);
this->tabPage_Components->Padding = System::Windows::Forms::Padding(6);
this->tabPage_Components->Size = System::Drawing::Size(1104, 721);
this->tabPage_Components->TabIndex = 2;
this->tabPage_Components->Text = L"Components";
//
// panel_Components
//
this->panel_Components->AutoScroll = true;
this->panel_Components->Location = System::Drawing::Point(0, 0);
this->panel_Components->Margin = System::Windows::Forms::Padding(6);
this->panel_Components->Name = L"panel_Components";
this->panel_Components->Size = System::Drawing::Size(552, 358);
this->panel_Components->Size = System::Drawing::Size(1104, 716);
this->panel_Components->TabIndex = 0;
//
// tabPage_Plugins
//
this->tabPage_Plugins->BackColor = System::Drawing::Color::White;
this->tabPage_Plugins->Controls->Add(this->panel_Custom);
this->tabPage_Plugins->Controls->Add(this->panel_Plugins);
this->tabPage_Plugins->ForeColor = 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->Location = System::Drawing::Point(4, 22);
this->tabPage_Plugins->Location = System::Drawing::Point(8, 39);
this->tabPage_Plugins->Margin = System::Windows::Forms::Padding(6);
this->tabPage_Plugins->Name = L"tabPage_Plugins";
this->tabPage_Plugins->Padding = System::Windows::Forms::Padding(3);
this->tabPage_Plugins->Size = System::Drawing::Size(552, 358);
this->tabPage_Plugins->Padding = System::Windows::Forms::Padding(6);
this->tabPage_Plugins->Size = System::Drawing::Size(1104, 721);
this->tabPage_Plugins->TabIndex = 3;
this->tabPage_Plugins->Text = L"Plugins and Patches";
//
// panel_Custom
//
this->panel_Custom->AutoScroll = true;
this->panel_Custom->Location = System::Drawing::Point(276, 0);
this->panel_Custom->Location = System::Drawing::Point(552, 0);
this->panel_Custom->Margin = System::Windows::Forms::Padding(6);
this->panel_Custom->Name = L"panel_Custom";
this->panel_Custom->Size = System::Drawing::Size(276, 358);
this->panel_Custom->Size = System::Drawing::Size(552, 716);
this->panel_Custom->TabIndex = 3;
//
// panel_Plugins
//
this->panel_Plugins->AutoScroll = true;
this->panel_Plugins->Location = System::Drawing::Point(0, 0);
this->panel_Plugins->Margin = System::Windows::Forms::Padding(6);
this->panel_Plugins->Name = L"panel_Plugins";
this->panel_Plugins->Size = System::Drawing::Size(276, 358);
this->panel_Plugins->Size = System::Drawing::Size(552, 716);
this->panel_Plugins->TabIndex = 0;
//
// tabPage_Credits
//
this->tabPage_Credits->Controls->Add(this->creditsTextBox);
this->tabPage_Credits->Location = System::Drawing::Point(4, 22);
this->tabPage_Credits->Margin = System::Windows::Forms::Padding(2);
this->tabPage_Credits->Location = System::Drawing::Point(8, 39);
this->tabPage_Credits->Margin = System::Windows::Forms::Padding(4);
this->tabPage_Credits->Name = L"tabPage_Credits";
this->tabPage_Credits->Padding = System::Windows::Forms::Padding(2);
this->tabPage_Credits->Size = System::Drawing::Size(552, 358);
this->tabPage_Credits->Padding = System::Windows::Forms::Padding(4);
this->tabPage_Credits->Size = System::Drawing::Size(1104, 721);
this->tabPage_Credits->TabIndex = 5;
this->tabPage_Credits->Text = L"Credits";
this->tabPage_Credits->UseVisualStyleBackColor = true;
//
// creditsTextBox
//
this->creditsTextBox->BackColor = System::Drawing::Color::White;
this->creditsTextBox->ForeColor = 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->creditsTextBox->Location = System::Drawing::Point(0, 0);
this->creditsTextBox->Margin = System::Windows::Forms::Padding(2);
this->creditsTextBox->Margin = System::Windows::Forms::Padding(4);
this->creditsTextBox->Multiline = true;
this->creditsTextBox->Name = L"creditsTextBox";
this->creditsTextBox->ReadOnly = true;
this->creditsTextBox->ScrollBars = System::Windows::Forms::ScrollBars::Both;
this->creditsTextBox->Size = System::Drawing::Size(552, 358);
this->creditsTextBox->Size = System::Drawing::Size(1100, 712);
this->creditsTextBox->TabIndex = 0;
this->creditsTextBox->Text = resources->GetString(L"creditsTextBox.Text");
//
// button_Discord
//
this->button_Discord->BackColor = System::Drawing::Color::FromArgb(static_cast<System::Int32>(static_cast<System::Byte>(242)), static_cast<System::Int32>(static_cast<System::Byte>(242)),
static_cast<System::Int32>(static_cast<System::Byte>(242)));
this->button_Discord->Cursor = System::Windows::Forms::Cursors::Hand;
this->button_Discord->FlatAppearance->BorderSize = 0;
this->button_Discord->FlatStyle = System::Windows::Forms::FlatStyle::Flat;
this->button_Discord->Image = (cli::safe_cast<System::Drawing::Image^>(resources->GetObject(L"button_Discord.Image")));
this->button_Discord->Location = System::Drawing::Point(496, 384);
this->button_Discord->Location = System::Drawing::Point(992, 768);
this->button_Discord->Margin = System::Windows::Forms::Padding(6);
this->button_Discord->Name = L"button_Discord";
this->button_Discord->Size = System::Drawing::Size(32, 32);
this->button_Discord->Size = System::Drawing::Size(64, 64);
this->button_Discord->TabIndex = 31;
this->button_Discord->UseVisualStyleBackColor = false;
this->button_Discord->Click += gcnew System::EventHandler(this, &ui::button_Discord_Click);
//
// button_github
//
this->button_github->BackColor = System::Drawing::Color::FromArgb(static_cast<System::Int32>(static_cast<System::Byte>(242)), static_cast<System::Int32>(static_cast<System::Byte>(242)),
static_cast<System::Int32>(static_cast<System::Byte>(242)));
this->button_github->Cursor = System::Windows::Forms::Cursors::Hand;
this->button_github->FlatAppearance->BorderSize = 0;
this->button_github->FlatStyle = System::Windows::Forms::FlatStyle::Flat;
this->button_github->Image = (cli::safe_cast<System::Drawing::Image^>(resources->GetObject(L"button_github.Image")));
this->button_github->Location = System::Drawing::Point(528, 384);
this->button_github->Location = System::Drawing::Point(1056, 768);
this->button_github->Margin = System::Windows::Forms::Padding(6);
this->button_github->Name = L"button_github";
this->button_github->Size = System::Drawing::Size(32, 32);
this->button_github->Size = System::Drawing::Size(64, 64);
this->button_github->TabIndex = 32;
this->button_github->UseVisualStyleBackColor = false;
this->button_github->Click += gcnew System::EventHandler(this, &ui::button_github_Click);
//
// button_Apply
//
this->button_Apply->BackColor = System::Drawing::Color::White;
this->button_Apply->FlatAppearance->BorderColor = System::Drawing::SystemColors::Control;
this->button_Apply->FlatStyle = System::Windows::Forms::FlatStyle::Flat;
this->button_Apply->Location = System::Drawing::Point(4, 389);
this->button_Apply->Location = System::Drawing::Point(8, 778);
this->button_Apply->Margin = System::Windows::Forms::Padding(6);
this->button_Apply->Name = L"button_Apply";
this->button_Apply->Size = System::Drawing::Size(69, 23);
this->button_Apply->Size = System::Drawing::Size(138, 46);
this->button_Apply->TabIndex = 33;
this->button_Apply->Text = L"Apply";
this->button_Apply->UseVisualStyleBackColor = false;
this->button_Apply->Click += gcnew System::EventHandler(this, &ui::button_Apply_Click);
//
// button_Wiki
//
this->button_Wiki->BackColor = System::Drawing::Color::FromArgb(static_cast<System::Int32>(static_cast<System::Byte>(242)), static_cast<System::Int32>(static_cast<System::Byte>(242)),
static_cast<System::Int32>(static_cast<System::Byte>(242)));
this->button_Wiki->BackgroundImage = (cli::safe_cast<System::Drawing::Image^>(resources->GetObject(L"button_Wiki.BackgroundImage")));
@@ -757,20 +902,24 @@ private: System::Windows::Forms::Button^ button_Wiki;
this->button_Wiki->Cursor = System::Windows::Forms::Cursors::Hand;
this->button_Wiki->FlatAppearance->BorderSize = 0;
this->button_Wiki->FlatStyle = System::Windows::Forms::FlatStyle::Flat;
this->button_Wiki->Location = System::Drawing::Point(464, 384);
this->button_Wiki->Location = System::Drawing::Point(928, 768);
this->button_Wiki->Margin = System::Windows::Forms::Padding(6);
this->button_Wiki->Name = L"button_Wiki";
this->button_Wiki->Size = System::Drawing::Size(32, 32);
this->button_Wiki->Size = System::Drawing::Size(64, 64);
this->button_Wiki->TabIndex = 34;
this->button_Wiki->UseVisualStyleBackColor = false;
this->button_Wiki->Click += gcnew System::EventHandler(this, &ui::button_Wiki_Click);
//
// ui
//
this->AcceptButton = this->button_Launch;
this->AutoScaleDimensions = System::Drawing::SizeF(96, 96);
this->AutoScaleDimensions = System::Drawing::SizeF(192, 192);
this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Dpi;
this->AutoSize = true;
this->AutoSizeMode = System::Windows::Forms::AutoSizeMode::GrowAndShrink;
this->BackColor = System::Drawing::Color::Magenta;
this->BackgroundImageLayout = System::Windows::Forms::ImageLayout::Stretch;
this->ClientSize = System::Drawing::Size(560, 417);
this->ClientSize = System::Drawing::Size(1120, 834);
this->Controls->Add(this->button_Wiki);
this->Controls->Add(this->button_Apply);
this->Controls->Add(this->tabControl);
@@ -784,10 +933,11 @@ private: System::Windows::Forms::Button^ button_Wiki;
this->HelpButton = true;
this->Icon = (cli::safe_cast<System::Drawing::Icon^>(resources->GetObject(L"$this.Icon")));
this->KeyPreview = true;
this->Margin = System::Windows::Forms::Padding(6);
this->MaximizeBox = false;
this->Name = L"ui";
this->StartPosition = System::Windows::Forms::FormStartPosition::CenterScreen;
this->Text = L"PD Launcher (2.5.3)";
this->Text = L"PD Launcher (2.6)";
this->TransparencyKey = System::Drawing::Color::Magenta;
this->FormClosing += gcnew System::Windows::Forms::FormClosingEventHandler(this, &ui::Ui_FormClosing);
this->FormClosed += gcnew System::Windows::Forms::FormClosedEventHandler(this, &ui::Ui_FormClosed);
@@ -896,13 +1046,38 @@ private: System::Void Button_Launch_Click(System::Object^ sender, System::EventA
SaveSettings();
if(GetPrivateProfileIntW(LAUNCHER_SECTION, L"use_divahook_bat", FALSE, CONFIG_FILE))
if (GetPrivateProfileIntW(LAUNCHER_SECTION, L"use_divahook_bat", FALSE, CONFIG_FILE))
{
if (GetPrivateProfileIntW(L"patches", L"quick_start", 1, CONFIG_FILE) > 0)
{
SkinnedMessageBox::Show(this, L"\"Quick Start\" and \"Use divahook.bat / start.bat\" cannot be enabled at the same time.", "PD Launcher", MessageBoxButtons::OK, MessageBoxIcon::Error);
return;
}
DIVA_EXECUTABLE = NULL;
wstring DIVA_EXECUTABLE_LAUNCH_STRING = L"cmd.exe /C \"";
DIVA_EXECUTABLE_LAUNCH_STRING.append(DIVA_DIRPATH);
DIVA_EXECUTABLE_LAUNCH_STRING.append(L"\\divahook.bat\"");
DIVA_EXECUTABLE_LAUNCH = const_cast<WCHAR*>(DIVA_EXECUTABLE_LAUNCH_STRING.c_str());
wstring DIVA_EXECUTABLE_LAUNCH_STRING_cmd = L"cmd.exe /C \"";
const wstring DIVA_EXECUTABLE_LAUNCH_STRING_path = DIVA_DIRPATH;
wstring DIVAHOOK_BAT_PATH = DIVA_EXECUTABLE_LAUNCH_STRING_path;
DIVAHOOK_BAT_PATH.append(L"\\divahook.bat");
if (std::filesystem::exists(DIVAHOOK_BAT_PATH))
{
DIVA_EXECUTABLE_LAUNCH_STRING_cmd.append(DIVAHOOK_BAT_PATH);
DIVA_EXECUTABLE_LAUNCH_STRING_cmd.append(L"\"");
DIVA_EXECUTABLE_LAUNCH = const_cast<WCHAR*>(DIVA_EXECUTABLE_LAUNCH_STRING_cmd.c_str());
}
else
{
wstring START_BAT_PATH = DIVA_EXECUTABLE_LAUNCH_STRING_path;
START_BAT_PATH.append(L"\\start.bat");
if (std::filesystem::exists(START_BAT_PATH))
{
DIVA_EXECUTABLE_LAUNCH_STRING_cmd.append(START_BAT_PATH);
DIVA_EXECUTABLE_LAUNCH_STRING_cmd.append(L"\"");
DIVA_EXECUTABLE_LAUNCH = const_cast<WCHAR*>(DIVA_EXECUTABLE_LAUNCH_STRING_cmd.c_str());
}
else if (SkinnedMessageBox::Show(this, L"divahook.bat/start.bat not found.\nThe game will start normally/offline.\n\nNOTE: Disable \"Use divahook.bat / start.bat\" to avoid this warning.", "PD Launcher", MessageBoxButtons::OKCancel, MessageBoxIcon::Warning) != System::Windows::Forms::DialogResult::OK) return;
}
}
else
{
+364 -260
View File
@@ -237,61 +237,62 @@ AMD compatibilty pack dependencies have additional licenses, detailed in the AMD
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="button_Discord.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAACoAAAApCAYAAABDV7v1AAAABGdBTUEAALGPC/xhBQAAA7dJREFUWEft
mElME2EUxwdDgh6NVw8e9OzZGwcv3ryZePKmUQodREAN1Ah0BmQTVJZgQFABE1kEl7iAEQWjAiIEOtMW
aJGyFWgpbWG6PL+vnSmFDrL0KyHaf/LPtPNm3vtN37dMSkUVlYwuqMYOJmRz52g1n0UzfF4knKTmmERG
p1CotEfFsjsTTU8colmuKTmXh70wzfL6S6qxY2L57SsxZ0SBEng2JoyklSzXp1Bo40SE7Qm1xSaXLOJm
uZMiwtaKj++MlU2yB1aqtadEjK0VBd2G/2/QtAItFFSPQ2HNOKQX+s9dzeMh5Y7/c2o+D8W141BWb4Rb
93Xr7t3MxEFLHxugd8gCtS2T0PJhBj73LsCwfhkMJicYp5y+Y9+wFd53m6Gh3QSD/BJ0fJ2HG0Va2XyS
iYLWtZpgbn4FBjkrCIIHtpLb7QXNKH4IB3oYm2xOyURBdQY7rKxuDbhRHo8XvF4vlKBuyOXFJgaaXa4X
y+5eliXBN5bl8hMDHUDtDleCywO5VWOy+YmAXkcTYWPLcSttdhcsLbt8rQ2W3ekCq83lA8PXScKf2z7O
huTHJgJaXGsAFyoqCRcc0FjRcBiFzFIdfPqxIEYA5i0C5FePwc1iLTS8nl53H1YXWiXkahABbe+cC/ll
1BVrLax89luMANQ0TwbOq+7pYcEqiBG/8CogxYNNBPTtF7NYxi8MipcqKf7w+RpoT/9i4PztB6Ngd7jE
iF+rgjsQDzYR0K6g1mJhUDz+Wjtm4enLKVhddYsRf6y7f9Fb0zLpnTE713VCUlpBaA0ioD0DFrEEoEnl
BtOMM2QCbSbHitu34OPFX1JGSei2SgT0TdfaGPWg4y/eCnUvTGgDWN4UGK8SPT8XoR5to0vLQuB+86IA
19C7wMYaREBTUas6vy2AxeYviD1jXoHiR+OQiSZMeeMENL6agqZ30/CkzQR364yQjl5c8Nh2OP3DwuX2
gH7CDiV18rsTEVDJORWj0IpeREbQvv0dvZjgtyi56yQX1RhAb7T7JlhZg9G3ZMldh00UNJKOgpL2vwlK
UaoDNMs75RKFYzqX96K8NnyUi2PvEJSiaDVXKJcoXCsZTaWS5Zo3g90x6Pl0w2Ga5Yb+9vS7Mc1q6uNV
nbFKhm+Qy71jUKyLWboTKGFGMstXo6S1RMxyVTj3FfXIkSRGU4bOCWGDBimGooCgA4pRMhyLAAN/xoUL
GjGdUWjj0JhNQZNsfl+DSkpQc2fpXM6x70GxFAx3+jIzdFz8GlVUFEVRfwDiv42+8CmffAAAAABJRU5E
rkJggg==
iVBORw0KGgoAAAANSUhEUgAAACoAAAApCAYAAABDV7v1AAAABGdBTUEAALGPC/xhBQAAA7hJREFUWEft
mEtME0EYgIshUY/GqwcPevbsjYMXb95MPHnTKAUWEVADNQLdFnlUUHkEA4IKmMhD8BEf1IiCUQERIt3t
g7ZIodBCS+mDbbu/MyUtLaVAYbYa7CSTbbrT///+50xHJEqOpAeiPXBeMnkgvZg5S0nZIopmS4WYmVKG
zqA1YrFEfWRHMaCoqYOUjOnIlrOQiEnJWO1FyeTRuGEzSibECNCfCMigjiwZMywWq/fHBYvC7EgkZEiX
jDmxbdC0NGXqX4FEaZYlVZ9MgpL0/v/t0bxyNZQ36qGiSQ/5Fatt7EopCzm3Vz/nlrGgaNZDTasRbt7T
bKvNEfdo9SMDDI3boLlrGrrem+HT0AL80i6DweQG44w78Bz+ZYd3AxZo6zXBGLsEfV+scL1SvSkwUdCW
bhPMWz0wxtiB4/yw1fD5eFDpsBEuZIwjcaAagxM8K1sDrjfA7+eB53moQtGIVYDEPFpcq93KgVu+ty1x
gVzeCJYY6CgK924H5/WDvGFSONBrqBDWhxyH0uH0wtKyF3Bow4fT7QW7wwsYDK8LDvy558OccKCKZgN4
kdJwhaMqOxTX6qCwWgMfvy+E3lltHJQ1TsINhRraXs1G/A4v6kddQrDQ9yrnozwjrVsLYf3T3yHQps7p
EIjkrhYW7FyEt3EXEAz0zWdLhDIcQtyqggofPFsDHRxZDH1/674OnC5vxG9XOJ9woP1hocVaMSjOv+6+
OXjyYgZWVnwRaTEwssg3dU3zZos7IhLBRXnl0ZVPpOoHR20hEA+CMpndUQUUqyO4PL5Aw8fNPzgKqqK3
VSKgr/vXctSPvPmTtUPLcxNoDMsxgXGXGPyxCK1oG11a5kKetSxycBWdBdbnKRHQXBQq5dcFsDlWFeJp
tnhA8VAPhahgatunoP3lDHS8nYXHPSa402KEfHRwwbntcq+mhdfnB+2UE6paNt6diIAGrS+p00E3OohM
oH37GzqY4FPUZmfSyiYDaI1OwAVW02YMtCzBt1CSh2TB2pPQkFg+0dALCbw3QUUiyT50c+Em7TlKzvJI
rgM/iRQT/l9NSZkK0qCBHKRV9ehGpDMWbFyhx6Dn8g2H0N3T+GbW78QQSqZqTZMoU7Notm0j2XGDYtgL
RZrjSGBBtoxtREKbiUwZ04BlX5ZOHM6kVTVIJhdu8I5Aw65WUkQiIDhDklOyaEYWfhm3W9BtXwfFu/A0
ur1DOZuDiswadx+NVxmJ9elS5gwlZ1z/rEfDjRTTzKlL9PgxEoYnZewZD/wB4r+Nvne+oTwAAAAASUVO
RK5CYII=
</value>
</data>
<data name="button_github.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
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
</value>
</data>
<metadata name="toolTip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
@@ -299,215 +300,318 @@ AMD compatibilty pack dependencies have additional licenses, detailed in the AMD
</metadata>
<data name="button_Wiki.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
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
</value>
</data>
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
@@ -129,6 +129,15 @@ class PatchApplier710 : public PatchApplier {
printf("[Patches] MLAA disabled\n");
}
// gamma
if (nGamma != 100 && nGamma != 0)
{
float gamma_float = (float)nGamma / 100.0f;
InjectCode((void*)(0x1404a863b), { *((uint8_t*)(&gamma_float)), *((uint8_t*)(&gamma_float) + 1), *((uint8_t*)(&gamma_float) + 2), *((uint8_t*)(&gamma_float) + 3) });
printf("[Patches] Gamma: %f\n", gamma_float);
}
// Replace the hardcoded videos with MP4s, if they exist
if (nMP4Movies)
{
@@ -347,6 +356,7 @@ class PatchApplier710 : public PatchApplier {
InjectCode((void*)0x000000014061579B, { 0x90, 0x90, 0x90, 0x8B, 0x42, 0xE0, 0x90, 0x90, 0x90 });
}
// Quick start
if (!nUseDivahookBat)
{
if (nQuickStart == 1) // skip the card/guest screen
{
@@ -369,7 +379,7 @@ class PatchApplier710 : public PatchApplier {
InjectCode((void*)0x0000000140120709, { 0xE9, 0x82, 0x0A, 0x00 });
}
// Default hand size
if (nDefaultHandSize != -1 && nDefaultHandSize != 0)
if (nDefaultHandSize >= 10000)
{
printf("[Patches] Changing default hand size...\n");
const float num = (float)nDefaultHandSize / 10000.0;
@@ -680,13 +690,13 @@ class PatchApplier710 : public PatchApplier {
}
// lag compensation
if (nLagCompensation>0 && nLagCompensation<=50)
if (nLagCompensation > 0 && nLagCompensation <= 500)
{
InjectCode((void*)(0x14011e44e), { 0xf3, 0x0f, 0x10, 0x05, 0x8a, 0xcf, 0x9c, 0x00 }); // hijack xmm0
InjectCode((void*)(0x14011e46b), { 0xf3, 0x0f, 0x11, 0x44, 0x24, 0x20 }); // get value from xmm0 instead of xmm1
float startPos = (float)nLagCompensation / 100.0;
InjectCode((void*)(0x140aeB3e0), { *((uint8_t*)(&startPos)), *((uint8_t*)(&startPos)+1), *((uint8_t*)(&startPos) + 2), *((uint8_t*)(&startPos) + 3) });
float startPos = (float)nLagCompensation / 1000.0f;
InjectCode((void*)(0x140aeB3e0), { *((uint8_t*)(&startPos)), *((uint8_t*)(&startPos) + 1), *((uint8_t*)(&startPos) + 2), *((uint8_t*)(&startPos) + 3) });
printf("[Patches] Lag Compensation: %f\n", startPos);
}
}
@@ -46,6 +46,16 @@ BOOL APIENTRY DllMain(HMODULE hModule,
}
void ApplyPatches() {
if (game_version == 710)
{
const char* exe_ver_string = (const char*)0x140A92CB8;
if (strcmp(exe_ver_string, "7.10.00") != 0)
{
MessageBoxW(nullptr, L"Game version not 7.10. Please verify your files.", L"Patches", MB_ICONERROR);
exit(1);
}
}
std::string version_string = std::to_string(game_version);
version_string.insert(version_string.begin()+1, '.');
std::cout << "[Patches] Game version " + version_string << std::endl;
@@ -104,12 +104,13 @@ auto nTAA = GetPrivateProfileIntW(L"graphics", L"taa", TRUE, CONFIG_FILE);
auto nMLAA = GetPrivateProfileIntW(L"graphics", L"mlaa", TRUE, CONFIG_FILE);
auto nDoF = GetPrivateProfileIntW(L"graphics", L"dof", TRUE, CONFIG_FILE);
auto nMAG = GetPrivateProfileIntW(L"graphics", L"mag", 0, CONFIG_FILE);
auto nGamma = GetPrivateProfileIntW(L"graphics", L"gamma", 100, CONFIG_FILE);
auto nStereo = GetPrivateProfileIntW(L"patches", L"stereo", TRUE, CONFIG_FILE);
auto nCustomPatches = GetPrivateProfileIntW(L"patches", L"custom_patches", TRUE, CONFIG_FILE);
auto nQuickStart = GetPrivateProfileIntW(L"patches", L"quick_start", 1, CONFIG_FILE);
auto nNoScrollingSfx = GetPrivateProfileIntW(L"patches", L"no_scrolling_sfx", FALSE, CONFIG_FILE);
auto nNoHandScaling = GetPrivateProfileIntW(L"patches", L"no_hand_scaling", FALSE, CONFIG_FILE);
auto nDefaultHandSize = GetPrivateProfileIntW(L"patches", L"default_hand_size", -1, CONFIG_FILE);
auto nDefaultHandSize = GetPrivateProfileIntW(L"patches", L"default_hand_size", 0, CONFIG_FILE);
auto nSingMissed = GetPrivateProfileIntW(L"patches", L"sing_missed", FALSE, CONFIG_FILE);
auto nForceMouth = GetPrivateProfileIntW(L"patches", L"force_mouth", 0, CONFIG_FILE);
auto nForceExpressions = GetPrivateProfileIntW(L"patches", L"force_expressions", 0, CONFIG_FILE);
@@ -126,4 +127,5 @@ auto nReflectResWidth = GetPrivateProfileIntW(L"graphics", L"reflect_res_width",
auto nReflectResHeight = GetPrivateProfileIntW(L"graphics", L"reflect_res_height", 256, CONFIG_FILE);
auto nRefractResWidth = GetPrivateProfileIntW(L"graphics", L"refract_res_width", 512, CONFIG_FILE);
auto nRefractResHeight = GetPrivateProfileIntW(L"graphics", L"refract_res_height", 256, CONFIG_FILE);
auto nLagCompensation = GetPrivateProfileIntW(L"graphics", L"lag_compensation", 0, CONFIG_FILE);
auto nLagCompensation = GetPrivateProfileIntW(L"graphics", L"lag_compensation", 0, CONFIG_FILE);
auto nUseDivahookBat = GetPrivateProfileIntW(L"launcher", L"use_divahook_bat", FALSE, CONFIG_FILE);
@@ -82,6 +82,7 @@ namespace TLAC::Components
MenuCircleBinding = new Binding();
CoinBinding = new Binding();
ToonBinding = new Binding();
FileSystem::ConfigFile configFile(framework::GetModuleDirectory(), KEY_CONFIG_FILE_NAME);
configFile.OpenRead();
@@ -100,6 +101,7 @@ namespace TLAC::Components
Config::BindConfigKeys(configFile.ConfigMap, "MENU_L", *MenuLBinding, { "Left", "Up" });
Config::BindConfigKeys(configFile.ConfigMap, "MENU_R", *MenuRBinding, { "Down", "Right" });
Config::BindConfigKeys(configFile.ConfigMap, "MENU_CIRCLE", *MenuCircleBinding, { "D", "L", "Spacebar" });
Config::BindConfigKeys(configFile.ConfigMap, "TOON", *ToonBinding, { "F9" });
Config::BindConfigKeys(configFile.ConfigMap, "COIN", *CoinBinding, { "F10" });
mouseScrollPvSelection = configFile.GetBooleanValue("mouse_scroll_pv_selection");
@@ -168,6 +170,12 @@ namespace TLAC::Components
// repress held down buttons to not block input
//inputState->Down.Buttons ^= inputState->Tapped.Buttons;
if (CoinBinding->AnyTapped())
addCoin();
if (ToonBinding->AnyTapped())
toggleNpr1();
}
HoldState InputEmulator::GetHoldState()
@@ -299,9 +307,6 @@ namespace TLAC::Components
if (buttonTestFunc(RightBinding))
buttons |= JVS_R;
if (buttonTestFunc(CoinBinding))
addCoin();
return buttons;
}
@@ -345,9 +350,6 @@ namespace TLAC::Components
if (keyboard->IsIntervalTapped(VK_SPACE))
inputKey = 0x20;
if (keyboard->IsIntervalTapped(VK_F9))
toggleNpr1();
if (keyboard->IsDoubleTapped(VK_ESCAPE))
*(bool*)SHOULD_EXIT_BOOL_ADDRESS = true;
@@ -39,6 +39,7 @@ namespace TLAC::Components
Input::Binding* MenuCircleBinding;
Input::Binding* CoinBinding;
Input::Binding* ToonBinding;
InputEmulator();
~InputEmulator();
@@ -23,12 +23,12 @@ namespace TLAC::FileSystem
return found;
}
int ConfigFile::GetIntegerValue(const std::string& key)
int ConfigFile::GetIntegerValue(const std::string& key, int defaultval)
{
auto pair = ConfigMap.find(key);
bool found = pair != ConfigMap.end();
return found ? atoi(pair->second.c_str()) : 0;
return found ? atoi(pair->second.c_str()) : defaultval;
}
bool ConfigFile::GetBooleanValue(const std::string& key)
@@ -14,7 +14,7 @@ namespace TLAC::FileSystem
std::unordered_map<std::string, std::string> ConfigMap;
bool TryGetValue(const std::string &key, std::string **value);
int GetIntegerValue(const std::string& key);
int GetIntegerValue(const std::string& key, int defaultval = 0);
bool GetBooleanValue(const std::string& key);
float GetFloatValue(const std::string& key);
std::string GetStringValue(const std::string& key);
@@ -16,6 +16,8 @@ namespace TLAC::Input
config.OpenRead();
xinput_num = config.GetIntegerValue("xinput_preferred");
rumble = config.GetBooleanValue("rumble");
rumble_left = config.GetIntegerValue("xinput_rumble_intensity_left", 8000);
rumble_right = config.GetIntegerValue("xinput_rumble_intensity_right", 4000);
}
Xinput* Xinput::GetInstance()
@@ -256,8 +258,8 @@ namespace TLAC::Input
{
XINPUT_VIBRATION vibration;
ZeroMemory(&vibration, sizeof(XINPUT_VIBRATION));
vibration.wLeftMotorSpeed = 8000; // use any value between 0-65535 here
vibration.wRightMotorSpeed = 4000; // use any value between 0-65535 here
vibration.wLeftMotorSpeed = rumble_left; // use any value between 0-65535 here
vibration.wRightMotorSpeed = rumble_right; // use any value between 0-65535 here
XInputSetState(xc_pref, &vibration);
}
else
@@ -48,7 +48,7 @@ namespace TLAC::Input
void SetTapStates(BYTE keycode, float elapsed);
int xinput_num;
int xinput_num, rumble_left, rumble_right;
bool rumble;
};
}