From def9581d75c045cab9fba0f848b4f5235fb8456a Mon Sep 17 00:00:00 2001 From: nastys <@> Date: Sat, 18 Sep 2021 19:45:08 +0200 Subject: [PATCH] Initial refactoring (WARNING: largely untested) --- appveyor.yml | 6 + source-code/PD-Loader.sln | 7 + .../source/PD-Loader/PD-Loader.vcxproj | 1 + .../PD-Loader/PD-Loader.vcxproj.filters | 3 + .../source/PD-Loader/Patches/PatchApplier.h | 3 +- .../PD-Loader/Patches/PatchApplier710.h | 643 +++--------------- .../PD-Loader/Patches/PatchApplier710EX.h | 341 ++++++++++ .../PD-Loader/Patches/patches-framework.h | 55 +- source-code/source/PD-Loader/dllmain.cpp | 2 +- source-code/source/PD-Loader/templates.h | 17 - .../source/plugins/DivaMovie/dllmain.cpp | 2 +- .../source/plugins/DivaWig/DivaWig.vcxproj | 1 + .../source/plugins/DivaWig/dllmain.cpp | 191 +++++- .../source/plugins/DivaWig/framework.h | 12 +- .../EnhancedStageManager.filters | 10 + .../EnhancedStageManager.vcxproj | 137 ++++ .../EnhancedStageManager/PluginConfigApi.h | 168 +++++ .../plugins/EnhancedStageManager/dllmain.cpp | 76 +++ .../plugins/EnhancedStageManager/framework.h | 28 + .../plugins/Launcher/Resources.it-IT.restext | 15 - .../plugins/Launcher/Resources.pt-BR.restext | 15 - .../source/plugins/Launcher/Resources.restext | 15 - .../Launcher/Resources.zh-Hans.restext | 15 - .../source/plugins/Launcher/framework.h | 22 +- 24 files changed, 1096 insertions(+), 689 deletions(-) create mode 100644 source-code/source/PD-Loader/Patches/PatchApplier710EX.h create mode 100644 source-code/source/plugins/EnhancedStageManager/EnhancedStageManager.filters create mode 100644 source-code/source/plugins/EnhancedStageManager/EnhancedStageManager.vcxproj create mode 100644 source-code/source/plugins/EnhancedStageManager/PluginConfigApi.h create mode 100644 source-code/source/plugins/EnhancedStageManager/dllmain.cpp create mode 100644 source-code/source/plugins/EnhancedStageManager/framework.h diff --git a/appveyor.yml b/appveyor.yml index b430ef1..0e78310 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -37,5 +37,11 @@ after_build: cd "$env:TMP/full" 7z a "$env:APPVEYOR_BUILD_FOLDER/PD-Loader-$env:CONFIGURATION-AppVeyor-$env:APPVEYOR_REPO_COMMIT.zip" * + + if ( "$env:CONFIGURATION" -imatch "Minimalist" ) + { + rm "$env:TMP/full/plugins/Launcher.dva" + 7z a "$env:APPVEYOR_BUILD_FOLDER/PD-Loader-$env:CONFIGURATION-NoLauncher-AppVeyor-$env:APPVEYOR_REPO_COMMIT.zip" * + } artifacts: - path: PD-Loader-*.zip diff --git a/source-code/PD-Loader.sln b/source-code/PD-Loader.sln index a160530..57a9747 100644 --- a/source-code/PD-Loader.sln +++ b/source-code/PD-Loader.sln @@ -17,6 +17,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DivaMovie", "source\plugins EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ShaderPatch", "source\plugins\ShaderPatch\ShaderPatch.vcxproj", "{C07E495E-A16F-48FA-80E4-0296B5234F0B}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EnhancedStageManager", "source\plugins\EnhancedStageManager\EnhancedStageManager.vcxproj", "{3C8071F4-22C8-DA6E-A075-C5EC646DAB7E}" +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DivaWig", "source\plugins\DivaWig\DivaWig.vcxproj", "{2394C586-F73B-4EF2-BA3E-2A0FC3034B1A}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DSCRemote", "source\plugins\DSCRemote\DSCRemote.vcxproj", "{8544C599-F73B-4EF2-BA3E-2A0FC3034B1A}" @@ -71,6 +73,11 @@ Global {C07E495E-A16F-48FA-80E4-0296B5234F0B}.Minimalist|x64.Build.0 = Minimalist|x64 {C07E495E-A16F-48FA-80E4-0296B5234F0B}.Release|x64.ActiveCfg = Release|x64 {C07E495E-A16F-48FA-80E4-0296B5234F0B}.Release|x64.Build.0 = Release|x64 + {3C8071F4-22C8-DA6E-A075-C5EC646DAB7E}.Debug|x64.ActiveCfg = Debug|x64 + {3C8071F4-22C8-DA6E-A075-C5EC646DAB7E}.Debug|x64.Build.0 = Debug|x64 + {3C8071F4-22C8-DA6E-A075-C5EC646DAB7E}.Minimalist|x64.ActiveCfg = Minimalist|x64 + {3C8071F4-22C8-DA6E-A075-C5EC646DAB7E}.Release|x64.ActiveCfg = Release|x64 + {3C8071F4-22C8-DA6E-A075-C5EC646DAB7E}.Release|x64.Build.0 = Release|x64 {2394C586-F73B-4EF2-BA3E-2A0FC3034B1A}.Debug|x64.ActiveCfg = Debug|x64 {2394C586-F73B-4EF2-BA3E-2A0FC3034B1A}.Debug|x64.Build.0 = Debug|x64 {2394C586-F73B-4EF2-BA3E-2A0FC3034B1A}.Minimalist|x64.ActiveCfg = Minimalist|x64 diff --git a/source-code/source/PD-Loader/PD-Loader.vcxproj b/source-code/source/PD-Loader/PD-Loader.vcxproj index cd0ba34..cecd320 100644 --- a/source-code/source/PD-Loader/PD-Loader.vcxproj +++ b/source-code/source/PD-Loader/PD-Loader.vcxproj @@ -163,6 +163,7 @@ + diff --git a/source-code/source/PD-Loader/PD-Loader.vcxproj.filters b/source-code/source/PD-Loader/PD-Loader.vcxproj.filters index 0b887a9..d9732a8 100644 --- a/source-code/source/PD-Loader/PD-Loader.vcxproj.filters +++ b/source-code/source/PD-Loader/PD-Loader.vcxproj.filters @@ -45,6 +45,9 @@ Header Files + + Header Files + diff --git a/source-code/source/PD-Loader/Patches/PatchApplier.h b/source-code/source/PD-Loader/Patches/PatchApplier.h index cd57a59..bf7b055 100644 --- a/source-code/source/PD-Loader/Patches/PatchApplier.h +++ b/source-code/source/PD-Loader/Patches/PatchApplier.h @@ -3,5 +3,6 @@ // PatchApplier provides the stuff for implementing patches for the specific game version class PatchApplier { public: - virtual void ApplyPatches() {}; + virtual void ApplyPatches() = 0; + void ApplyExPatches() {}; }; \ No newline at end of file diff --git a/source-code/source/PD-Loader/Patches/PatchApplier710.h b/source-code/source/PD-Loader/Patches/PatchApplier710.h index 44c57b9..5fd31e9 100644 --- a/source-code/source/PD-Loader/Patches/PatchApplier710.h +++ b/source-code/source/PD-Loader/Patches/PatchApplier710.h @@ -1,5 +1,3 @@ -#pragma once - #pragma once #include #include "PatchApplier.h" @@ -76,14 +74,12 @@ class PatchApplier710 : public PatchApplier { - // The old stereo patch... - // Use 2 channels instead of 4 - if (nStereo) - { - InjectCode((void*)0x0000000140A860C0, { 0x02 }); - printf("[Patches] Stereo patch enabled\n"); - } - + ///////////////////// + ////// Options ////// + ///////////////////// + + //// Graphics + // Disable AA if (!nTAA) { @@ -113,6 +109,7 @@ class PatchApplier710 : public PatchApplier { printf("[Patches] TAA disabled\n"); } + if (!nMLAA) { // set MLAA var (shouldn't be needed but whatever) @@ -129,12 +126,51 @@ class PatchApplier710 : public PatchApplier { printf("[Patches] MLAA disabled\n"); } - // Hide "FREE PLAY" - if (nHideFreeplay) + // lag compensation + if (nLagCompensation > 0 && nLagCompensation <= 500) { - InjectCode((void*)0x00000001403BABEF, { 0x06, 0xB6 }); - printf("[Patches] Hide FREE PLAY/CREDIT(S) enabled\n"); + 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 / 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); } + + + //// Compatibility + + // Skip loading (and therefore displaying) song movies + if (nNoMovies) + { + InjectCode((void*)0x00000001404EB584, { 0x48, 0xE9 }); + InjectCode((void*)0x00000001404EB471, { 0x48, 0xE9 }); + printf("[Patches] Movies disabled\n"); + } + + // The old stereo patch... + // Use 2 channels instead of 4 + if (nStereo) + { + InjectCode((void*)0x0000000140A860C0, { 0x02 }); + printf("[Patches] Stereo patch enabled\n"); + } + + // OpenGL Patches + /*if (nOGLPatchA) + { + // (call cs:glGetError) -> (xor eax, eax); (nop); (nop); (nop); (nop); + InjectCode((void*)0x000000014069D21D, { 0x31, 0xC0, 0x90, 0x90, 0x90, 0x90 }); + } + if (nOGLPatchB) + { + // (js loc_14069BC32) -> (nop)... + InjectCode((void*)0x000000014069BAF4, { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); + }*/ + + + //// PV Selector + // Enable "FREE PLAY" mode if (nFreeplay || nHideFreeplay) { @@ -153,6 +189,10 @@ class PatchApplier710 : public PatchApplier { printf("[Patches] Show PD Loader text\n"); } } + + + //// UI Elements + // Use GLUT_CURSOR_RIGHT_ARROW instead of GLUT_CURSOR_NONE if (nCursor) { @@ -160,6 +200,43 @@ class PatchApplier710 : public PatchApplier { InjectCode((void*)0x00000001403012b5, { 0xeb }); // Disable debug cursor printf("[Patches] Cursor enabled\n"); } + + // Don't show volume control + if (nHideVolCtrl) + { + // skip SE button + InjectCode((void*)0x00000001409A4D60, { 0xC0, 0xD3 }); + + // skip volume sliders button + InjectCode((void*)0x0000000140A85F10, { 0xE0, 0x50 }); + + printf("[Patches] Volume control hidden\n"); + } + + // Disable the PV screen photo UI + if (nNoPVUi) + { + InjectCode((void*)0x000000014048FA91, { 0xEB, 0x6F }); // skip button panel image (JMP 0x14048FB02) + + // patch minimum PV UI state to 1 instead of 0 + // hook check for lyrics enabled (UI state < 2) to change UI state 0 into 1 + // dump new code in the skipped button panel condition + InjectCode((void*)0x000000014048FA93, { 0xC7, 0x83, 0x58, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 }); // MOV dword ptr [0x158 + RBX],0x1 + InjectCode((void*)0x000000014048FA9D, { 0xC6, 0x80, 0x3A, 0xD1, 0x02, 0x00, 0x01 }); // MOV byte ptr [0x2d13a + RAX],0x1 + InjectCode((void*)0x000000014048FAA4, { 0xE9, 0x8B, 0xFB, 0xFF, 0xFF }); // JMP 0x14048F634 + + InjectCode((void*)0x000000014048F62D, { 0xE9, 0x61, 0x04, 0x00, 0x00 }); // JMP 0x14048FA93 + + printf("[Patches] PV UI disabled\n"); + } + + // Removes PV watermark + if (nHidePVWatermark) + { + InjectCode((void*)0x0000000140A13A88, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }); + printf("[Patches] PV watermark hidden\n"); + } + // Override status icon states to be invalid (hides them) if (nStatusIcons > 0) { @@ -205,39 +282,14 @@ class PatchApplier710 : public PatchApplier { // I was going to use this with a string, but the assignment wasn't behaving well and making separate prints was easier than figuring it out // printf("[Patches] Status icons %s\n", iconType); } - // Removes PV watermark - if (nHidePVWatermark) + + // Hide "FREE PLAY" + if (nHideFreeplay) { - InjectCode((void*)0x0000000140A13A88, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }); - printf("[Patches] PV watermark hidden\n"); + InjectCode((void*)0x00000001403BABEF, { 0x06, 0xB6 }); + printf("[Patches] Hide FREE PLAY/CREDIT(S) enabled\n"); } - // Disable the PV screen photo UI - if (nNoPVUi) - { - InjectCode((void*)0x000000014048FA91, { 0xEB, 0x6F }); // skip button panel image (JMP 0x14048FB02) - // patch minimum PV UI state to 1 instead of 0 - // hook check for lyrics enabled (UI state < 2) to change UI state 0 into 1 - // dump new code in the skipped button panel condition - InjectCode((void*)0x000000014048FA93, { 0xC7, 0x83, 0x58, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 }); // MOV dword ptr [0x158 + RBX],0x1 - InjectCode((void*)0x000000014048FA9D, { 0xC6, 0x80, 0x3A, 0xD1, 0x02, 0x00, 0x01 }); // MOV byte ptr [0x2d13a + RAX],0x1 - InjectCode((void*)0x000000014048FAA4, { 0xE9, 0x8B, 0xFB, 0xFF, 0xFF }); // JMP 0x14048F634 - - InjectCode((void*)0x000000014048F62D, { 0xE9, 0x61, 0x04, 0x00, 0x00 }); // JMP 0x14048FA93 - - printf("[Patches] PV UI disabled\n"); - } - // Don't show volume control - if (nHideVolCtrl) - { - // skip SE button - InjectCode((void*)0x00000001409A4D60, { 0xC0, 0xD3 }); - - // skip volume sliders button - InjectCode((void*)0x0000000140A85F10, { 0xE0, 0x50 }); - - printf("[Patches] Volume control hidden\n"); - } // Skip loading (and therefore displaying) song lyrics if (nNoLyrics) { @@ -245,13 +297,7 @@ class PatchApplier710 : public PatchApplier { InjectCode((void*)0x00000001404E7950, { 0x48, 0xE9 }); // ensure first iteration doesn't run printf("[Patches] Lyrics disabled\n"); } - // Skip loading (and therefore displaying) song movies - if (nNoMovies) - { - InjectCode((void*)0x00000001404EB584, { 0x48, 0xE9 }); - InjectCode((void*)0x00000001404EB471, { 0x48, 0xE9 }); - printf("[Patches] Movies disabled\n"); - } + // Disable error banner if (nNoError) { @@ -259,6 +305,7 @@ class PatchApplier710 : public PatchApplier { InjectCode((void*)0x00000001403B9E9B, { 0x90, 0x90 }); printf("[Patches] Errors Banner disabled\n"); } + // Disable timer if (nNoTimer) { @@ -268,485 +315,7 @@ class PatchApplier710 : public PatchApplier { // Freeze PV selection timer InjectCode((void*)0x00000001405BDFBF, { 0x90, 0x90, 0x90, 0x90 }); } -#ifndef MINIMALIST - // Disable timer sprite - if (nNoTimerSprite) - { - InjectCode((void*)0x00000001409C0758, { 0x00 }); // time_loop - InjectCode((void*)0x0000000140A3D3F0, { 0x00 }); // time_in - InjectCode((void*)0x0000000140A3D3F8, { 0x00 }); // time_out - } - // Unlock PSEUDO modules (which will all default to Miku, unless we also patch them to match the first performer) - if (nUnlockPseudo) - { - InjectCode((void*)0x0000000140A21770, { 0x00 }); - InjectCode((void*)0x0000000140A21780, { 0x00 }); - InjectCode((void*)0x0000000140A21790, { 0x00 }); - InjectCode((void*)0x0000000140A217A0, { 0x00 }); - InjectCode((void*)0x0000000140A217B0, { 0x00 }); - } - // Enable card button by somewhatlurker (pretty much just eye candy for now) - if (nCard) - { - InjectCode((void*)0x0000000140565E6B, { 0x90, 0x90 }); - } - // Quick start - { - if (nQuickStart == 1) // skip the card/guest screen - { - InjectCode((void*)0x0000000140578EA9, { 0xE9, 0x8E, 0x00, 0x00, 0x00 }); - } - else if (nQuickStart == 2) // skip everything; normal mode - { - InjectCode((void*)0x0000000140578EA9, { 0xE9, 0xF1, 0x00, 0x00, 0x00 }); - InjectCode((void*)0x0000000140578E9D, { 0xC7, 0x47, 0x68, 0x28, 0x00, 0x00, 0x00 }); // skip back button error - } - } - // Disable scrolling sound effect - if (nNoScrollingSfx) - { - InjectCode((void*)0x00000001405C84B3, { 0x90, 0x90, 0x90, 0x90, 0x90 }); - } - // Disable hand scaling - if (nNoHandScaling) - { - InjectCode((void*)0x0000000140120709, { 0xE9, 0x82, 0x0A, 0x00 }); - } - // Default hand size - if (nDefaultHandSize != -1) - { - switch (nDefaultHandSize) - { - case 0: - MessageBoxW(nullptr, L"The default hand size is set to 0 in Options.\nHands may disappear.\n\nIf this is not intentional, set it back to -1.", L"Patches", MB_ICONWARNING); - break; - case 1: - MessageBoxW(nullptr, L"The default hand size is set to 1 in Options.\nHands may be extremely small.\n\nIf this is not intentional, set it back to -1.", L"Patches", MB_ICONWARNING); - break; - } - printf("[Patches] Changing default hand size...\n"); - const float num = (float)nDefaultHandSize / 10000.0; - DWORD oldProtect; - float* addr1 = (float*)(0x140506B59); - float* addr2 = (float*)(0x140506B60); - /*float* addr3 = (float*)(0x140506B67); - float* addr4 = (float*)(0x140506B71);*/ - VirtualProtect(addr1, 4, PAGE_EXECUTE_READWRITE, &oldProtect); - VirtualProtect(addr2, 4, PAGE_EXECUTE_READWRITE, &oldProtect); - /*VirtualProtect(addr3, 4, PAGE_EXECUTE_READWRITE, &oldProtect); - VirtualProtect(addr4, 4, PAGE_EXECUTE_READWRITE, &oldProtect);*/ - *addr1 = *addr2 /*= *addr3 = *addr4*/ = num; - VirtualProtect(addr1, 4, oldProtect, nullptr); - VirtualProtect(addr2, 4, oldProtect, nullptr); - /*VirtualProtect(addr3, 4, oldProtect, nullptr); - VirtualProtect(addr4, 4, oldProtect, nullptr);*/ - printf("[Patches] New default hand size: %f\n", num); - } - // Sing missed notes - if (nSingMissed) - { - InjectCode((void*)0x140109044, { 0xEB }); - // Breaks border: - // InjectCode((void*)0x140109096, { 0xEB }); - } - // Force mouth animations - { - if (nForceMouth == 1) // PDA - { - printf("[Patches] Forcing PDA mouth...\n"); - int* mouth_table = (int*)(0x1409A1DC0); - DWORD oldProtect; - VirtualProtect(mouth_table, 44, PAGE_EXECUTE_READWRITE, &oldProtect); - for (int i = 0; i < 11; i++) - { - mouth_table[i]++; - } - VirtualProtect(mouth_table, 44, oldProtect, nullptr); - printf("[Patches] PDA mouth forced\n"); - } - else if (nForceMouth == 2) // FT - { - printf("[Patches] Forcing FT mouth...\n"); - int* mouth_table_oldid = (int*)(0x1409A1E1C); - DWORD oldProtect; - VirtualProtect(mouth_table_oldid, 44, PAGE_EXECUTE_READWRITE, &oldProtect); - for (int i = 0; i < 11; i++) - { - mouth_table_oldid[i]--; - } - VirtualProtect(mouth_table_oldid, 44, oldProtect, nullptr); - printf("[Patches] FT mouth forced\n"); - } - } - // Force expressions - { - if (nForceExpressions == 1) // PDA - { - printf("[Patches] Forcing PDA expressions...\n"); - int* exp_table = (int*)(0x140A21900); - DWORD oldProtect; - VirtualProtect(exp_table, 104, PAGE_EXECUTE_READWRITE, &oldProtect); - for (int i = 0; i < 26; i++) - { - exp_table[i] += 2; - } - VirtualProtect(exp_table, 104, oldProtect, nullptr); - printf("[Patches] PDA expressions forced\n"); - } - else if (nForceExpressions == 2) // FT - { - printf("[Patches] Forcing FT expressions...\n"); - int* exp_table_oldid = (int*)(0x140A219D0); - DWORD oldProtect; - VirtualProtect(exp_table_oldid, 104, PAGE_EXECUTE_READWRITE, &oldProtect); - for (int i = 0; i < 26; i++) - { - exp_table_oldid[i] -= 2; - } - VirtualProtect(exp_table_oldid, 104, oldProtect, nullptr); - printf("[Patches] FT expressions forced\n"); - } - } - // Force look animations - { - if (nForceLook == 1) // PDA - { - printf("[Patches] Forcing PDA look...\n"); - int* look_table = (int*)(0x1409A1D70); - DWORD oldProtect; - VirtualProtect(look_table, 36, PAGE_EXECUTE_READWRITE, &oldProtect); - for (int i = 0; i < 9; i++) - { - look_table[i]++; - } - VirtualProtect(look_table, 36, oldProtect, nullptr); - printf("[Patches] PDA look forced\n"); - } - else if (nForceLook == 2) // FT - { - printf("[Patches] Forcing FT look...\n"); - int* look_table_oldid = (int*)(0x1409A1D9C); - DWORD oldProtect; - VirtualProtect(look_table_oldid, 36, PAGE_EXECUTE_READWRITE, &oldProtect); - for (int i = 0; i < 9; i++) - { - look_table_oldid[i]--; - } - VirtualProtect(look_table_oldid, 36, oldProtect, nullptr); - printf("[Patches] FT look forced\n"); - } - } - // NPR1 - { - if (nNpr1 == 1) // force on - { - InjectCode((void*)0x0000000140502FC0, { 0xC7, 0x05, 0x6E }); - InjectCode((void*)0x0000000140502FC6, { 0x01, 0x00, 0x00, 0x00, 0xC3 }); - - printf("[Patches] NPR1 forced\n"); - } - else if (nNpr1 == 2) // force off - { - InjectCode((void*)0x0000000140502FC0, { 0xC7, 0x05, 0x6E }); - InjectCode((void*)0x0000000140502FC6, { 0x00, 0x00, 0x00, 0x00, 0xC3 }); - - printf("[Patches] NPR1 disabled\n"); - } - } - // Depth of Field - if (!nDoF) - { - InjectCode((void*)0x00000001409476AB, { 0x90, 0x90, 0x90, 0x90, 0x90 }); - - InjectCode((void*)0x00000001411AB650, { 0b00000001 }); - } - // MAG filter - if (nMAG > 0) - { - //InjectCode((void*)0x00000001404AB142, { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); - - unsigned char filter; - switch (nMAG) - { - case 1: // nearest - filter = 0; - InjectCode((void*)0x00000001404ACE56, { 0x90, 0x90 }); - break; - case 2: // sharpen - filter = 3; // sharpen(4tap) - break; - case 3: // cone - filter = 5; // cone(2tap) - break; - default: - filter = 1; - } - - //InjectCode((void*)0x00000001404A864F, { filter }); - //InjectCode((void*)0x00000001411AC518, { filter }); - - InjectCode((void*)0x00000001404ACE8E, { 0xB9, filter, 0x00, 0x00 }); - InjectCode((void*)0x00000001404ACE93, { 0x90 }); - } - // Reflections - if (!nReflections) - { - InjectCode((void*)0x1406477C0, { 0xE9, 0xF3, 0x00, 0x00, 0x00, 0x90 }); - InjectCode((void*)0x1411ADAFC, { 0x00 }); - } - // Shadows - if (!nShadows) - { - //InjectCode((void*)0x140502B44, { 0x90, 0x90, 0x90 }); - //InjectCode((void*)0x140502BB2, { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); - InjectCode((void*)0x140502766, { 0x00 }); - InjectCode((void*)0x1411AD438, { 0x00 }); - InjectCode((void*)0x1411AD320, { 0x00 }); - } - // Punch-through transparency - if (!nPunchthrough) - { - InjectCode((void*)0x1411AD43D, { 0x00 }); - } - // Glare - if (!nGlare) - { - InjectCode((void*)0x1404B2168, { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); - } - // Shader - if (!nShader) - { - InjectCode((void*)0x140C9C48E, { 0x00 }); - } - // 2D - if (n2D) - { - //InjectCode((void*)0x140502B44, { 0x90, 0x90, 0x90 }); - InjectCode((void*)0x140502BB2, { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); - InjectCode((void*)0x140502A3C, { 0x90, 0x90, 0x90, 0x90, 0x90 }); - /*InjectCode((void*)0x1411AD320, { 0x00 }); // shadow - InjectCode((void*)0x1411AD323, { 0x00 }); // reflect - InjectCode((void*)0x1411AD321, { 0x00 }); // SS_SSS - InjectCode((void*)0x1411AD325, { 0x00 }); // preprocess - InjectCode((void*)0x1411AD328, { 0x00 }); // 3D*/ - InjectCode((void*)0x1411AD32A, { 0x01 }); // post process - InjectCode((void*)0x1411AD32B, { 0x01 }); // sprite - - InjectCode((void*)0x140A07920, { 0x00 }); // ignore objset - } - // Prevent data deletion - if (nNoDelete) - { - InjectCode((void*)(0x1406FEF80 + 0x1DB), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); - InjectCode((void*)(0x1407113F0 + 0x13C), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); - InjectCode((void*)(0x140712270 + 0x6C), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); - InjectCode((void*)(0x140712580 + 0x4C), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); - InjectCode((void*)(0x140712580 + 0x7C), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); - InjectCode((void*)(0x140713470 + 0x104), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); - InjectCode((void*)(0x1407135B0 + 0x102), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); - InjectCode((void*)(0x1407135B0 + 0x135), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); - InjectCode((void*)(0x1407135B0 + 0x232), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); - InjectCode((void*)(0x140713810 + 0x3E8), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); - InjectCode((void*)(0x140713D00 + 0x677), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); - InjectCode((void*)(0x1407168A0 + 0x9C), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); - InjectCode((void*)(0x1407168A0 + 0x1D2), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); - InjectCode((void*)(0x1407168A0 + 0x218), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); - InjectCode((void*)(0x1407168A0 + 0x22A), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); - InjectCode((void*)(0x140720910 + 0x25C), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); - InjectCode((void*)(0x140723EE0 + 0xEC), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); - InjectCode((void*)(0x140870DE0 + 0x4), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); - InjectCode((void*)(0x1406FEF80 + 0x1DB), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); - InjectCode((void*)(0x1407113F0 + 0x13C), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); - InjectCode((void*)(0x140712270 + 0x6E), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); - InjectCode((void*)(0x140712580 + 0x4C), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); - InjectCode((void*)(0x140712580 + 0x7C), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); - InjectCode((void*)(0x140713470 + 0x104), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); - InjectCode((void*)(0x1407135B0 + 0x102), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); - InjectCode((void*)(0x1407135B0 + 0x135), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); - InjectCode((void*)(0x1407135B0 + 0x232), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); - InjectCode((void*)(0x140713810 + 0x3E8), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); - InjectCode((void*)(0x140713D00 + 0x677), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); - InjectCode((void*)(0x1407168A0 + 0x9C), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); - InjectCode((void*)(0x1407168A0 + 0x1D2), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); - InjectCode((void*)(0x1407168A0 + 0x218), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); - InjectCode((void*)(0x1407168A0 + 0x22A), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); - InjectCode((void*)(0x140720910 + 0x25C), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); - InjectCode((void*)(0x140723EE0 + 0xEC), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); - InjectCode((void*)(0x1407168A0 + 0x9C), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); - InjectCode((void*)(0x140870DE0 + 0x4), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); - InjectCode((void*)(0x14081B6A4), { 0xC3 }); - - InjectCode((void*)(0x1406E1090 + 0x43C), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); - InjectCode((void*)(0x140718250 + 0x176), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); - InjectCode((void*)(0x140718750 + 0xC9), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); - InjectCode((void*)(0x1407193E0 + 0xFC), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); - InjectCode((void*)(0x1406E1090 + 0x43C), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); - InjectCode((void*)(0x140718250 + 0x176), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); - InjectCode((void*)(0x140718750 + 0xC9), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); - InjectCode((void*)(0x1407193E0 + 0xFC), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); - InjectCode((void*)(0x14081B67A), { 0xC3 }); - } - - // patch refract and reflect buffer sizes - // no need to really check anything before injecting, because reinjecting defaults is fine - InjectCode((void*)(0x140a24424), std::vector((uint8_t*)&nRefractResWidth, (uint8_t*)((int64_t)&nRefractResWidth + 4))); - InjectCode((void*)(0x140a24428), std::vector((uint8_t*)&nRefractResHeight, (uint8_t*)((int64_t)&nRefractResHeight + 4))); - InjectCode((void*)(0x140a2443c), std::vector((uint8_t*)&nReflectResWidth, (uint8_t*)((int64_t)&nReflectResWidth + 4))); - InjectCode((void*)(0x140a24440), std::vector((uint8_t*)&nReflectResHeight, (uint8_t*)((int64_t)&nReflectResHeight + 4))); - // for large reflect resolutions, adjust blur effect amount to not lose the effect - // scaling is based on a 1024 width instead of the original 512px - // because we don't wanna make it too blurry when just being used to smooth jaggies - if (nReflectResWidth >= 2048) - { - int blurAmount = nReflectResWidth / 1024; - - // multiply blur setting - // ECX has blur amount, EDX has blur type - InjectCode((void*)(0x140503000), { 0x89, 0x15, 0x3a, 0xa3, 0xca, 0x00 }); // MOV dword ptr [0x1411ad340], EDX - InjectCode((void*)(0x140503006), { 0xb8 }); // MOV EAX, blurAmount - InjectCode((void*)(0x140503007), std::vector((uint8_t*)&blurAmount, (uint8_t*)((int64_t)&blurAmount + 4))); - InjectCode((void*)(0x14050300b), { 0xf7, 0xe1 }); // MUL (EDX:EAX,)ECX - InjectCode((void*)(0x14050300d), { 0xeb, 0x09 }); // JMP 0x140503018 - InjectCode((void*)(0x140503018), { 0x89, 0x05, 0x1e, 0xa3, 0xca, 0x00 }); // MOV dword ptr [0x1411ad33c], EAX - InjectCode((void*)(0x14050301e), { 0xc3 }); // RET - - // divide dwgui blur amount getting - // RDX gets type, RCX gets amount - InjectCode((void*)(0x140502910), { 0x48, 0x85, 0xd2 }); // TEST RDX, RDX - InjectCode((void*)(0x140502913), { 0x74, 0x08 }); // JZ 0x14050291d - InjectCode((void*)(0x140502915), { 0x8b, 0x05, 0x25, 0xaa, 0xca, 0x00 }); // MOV EAX, dword ptr [0x1411ad340] - InjectCode((void*)(0x14050291b), { 0x89, 0x02 }); // MOV dword ptr [RDX], EAX - - InjectCode((void*)(0x14050291d), { 0x48, 0x85, 0xc9 }); // TEST RCX, RCX - InjectCode((void*)(0x140502920), { 0x74, 0x2d }); // JZ 0x14050294f - InjectCode((void*)(0x140502922), { 0x8b, 0x05, 0x14, 0xaa, 0xca, 0x00 }); // MOV EAX, dword ptr [0x1411ad33c] - - InjectCode((void*)(0x140502928), { 0xeb, 0x0d }); // JMP 0x140502937 - InjectCode((void*)(0x140502937), { 0x49, 0xc7, 0xc0 }); // MOV R8, blurAmount - InjectCode((void*)(0x14050293a), std::vector((uint8_t*)&blurAmount, (uint8_t*)((int64_t)&blurAmount + 4))); - InjectCode((void*)(0x14050293e), { 0xeb, 0x08 }); // JMP 0x140502948 - InjectCode((void*)(0x140502948), { 0x31, 0xd2 }); // XOR EDX,EDX - InjectCode((void*)(0x14050294a), { 0x49, 0xf7, 0xf0 }); // DIV (EDX:EAX,)R8 - - InjectCode((void*)(0x14050294d), { 0x89, 0x01 }); // MOV dword ptr [RCX], EAX - InjectCode((void*)(0x14050294f), { 0xc3 }); // RET - } - - // no message bar - if (nNoMessageBar) - { - InjectCode((void*)(0x1409F6470), { 0x00 }); - - // no scrolling message by snakemi - InjectCode((void*)(0x1403B98FD), { 0x00, 0x00, 0x00, 0x00 }); - InjectCode((void*)(0x1403B9904), { 0x00, 0x00, 0x00, 0x00 }); - InjectCode((void*)(0x1403B990B), { 0x00, 0x00, 0x00, 0x00 }); - } - - // no stage text - if (nNoStageText) - { - InjectCode((void*)(0x140A3D4C8), { 0x00 }); - InjectCode((void*)(0x140A3D4D8), { 0x00 }); - InjectCode((void*)(0x140A3D4E8), { 0x00 }); - InjectCode((void*)(0x140A3D4F8), { 0x00 }); - InjectCode((void*)(0x140A3D508), { 0x00 }); - InjectCode((void*)(0x140A3D518), { 0x00 }); - InjectCode((void*)(0x140A3D530), { 0x00 }); - InjectCode((void*)(0x140A3D540), { 0x00 }); - InjectCode((void*)(0x140A3D550), { 0x00 }); - } - - // no osage play data by Skyth - if (nNoOpd) - { - InjectCode((void*)(0x1404728C0), { 0xC3 }); - InjectCode((void*)(0x1404789C3), { 0x0D }); - } - // gamma - if (nGamma != 100) - { - 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); - } - - // modpack redirection - /*{ - wchar_t* mpstr = NULL; - mpstr = (wchar_t*)malloc(256); - memset(mpstr, 0, 256); - GetPrivateProfileStringW(L"Mods", L"Modpack", L"", mpstr, 256, CONFIG_FILE_NAME); - std::string modpack_name(std::filesystem::path(mpstr).string()); - free(mpstr); - std::cout << "[Patches] Modpack name: " << modpack_name << std::endl; - - if (modpack_name != "") - { - // ram - std::string modpack_path = "modpacks\\" + modpack_name; - std::cout << "[Patches] New ram path: " << modpack_path << std::endl; - char* mpstr_path = (char*)malloc(modpack_path.size()); - memcpy(mpstr_path, modpack_path.c_str(), modpack_path.size()); - InjectLong((void*)0x0000000014096C120, (long)mpstr_path); - - // mdata - std::string modpack_mdata = "modpacks\\" + modpack_name + "\\mdata"; - std::cout << "[Patches] New mdata path: " << modpack_mdata << std::endl; - char* mpstr_mdata = (char*)malloc(modpack_mdata.size()); - memcpy(mpstr_mdata, modpack_mdata.c_str(), modpack_mdata.size()); - InjectCode((void*)0x000000014066CEA0, { 0x48, 0xC7, 0xC2 }); - InjectInt((void*)0x000000014066CEA3, (int)mpstr_mdata); - InjectCode((void*)0x000000014066CE9C, { (unsigned char)modpack_mdata.size() }); - InjectCode((void*)0x000000014066CEAE, { (unsigned char)modpack_mdata.size() }); - } - }*/ -#endif - // Enhanced Stage Manager - if (nEStageManager > 0) - { - // Replace the function that provides the number of stages and compact some of it - InjectCode((void*)0x000000014038AEF0, { 0x48, 0x8B, 0x88, 0x40, 0x01, 0x00, 0x00, 0x48, 0x89, 0x4C, 0x24, 0x20, 0x48, 0x8B, 0xD0, 0x48, 0x8B, 0x88, 0x48, 0x01, 0x00, 0x00, 0x48, 0x89, 0x4C, 0x24, 0x28, 0x8B, 0x88, 0x50, 0x01, 0x00, 0x00, 0x89, 0x4C, 0x24, 0x30, 0x8B, 0x88, 0x54, 0x01, 0x00, 0x00, 0x8B, 0x80, 0x58, 0x01, 0x00, 0x00, 0x89, 0x44, 0x24, 0x38, 0x8B, 0x82, 0x5C, 0x01, 0x00, 0x00, 0x89, 0x4C, 0x24, 0x34, 0x89, 0x44, 0x24, 0x3C, 0x48, 0x8B, 0x82, 0x60, 0x01, 0x00, 0x00, 0x48, 0x89, 0x44, 0x24, 0x40, 0x48, 0x8B, 0x82, 0x68, 0x01, 0x00, 0x00, 0x48, 0x89, 0x44, 0x24, 0x48, 0x48, 0x8B, 0x82, 0x70, 0x01, 0x00, 0x00, 0x48, 0x89, 0x44, 0x24, 0x50, 0x8B, 0x82, 0x78, 0x01, 0x00, 0x00, 0x89, 0x44, 0x24, 0x58, 0x84, 0xC0, 0x74, 0x2A, 0x48, 0x8B, 0x44, 0x24, 0x38, 0x48, 0xC1, 0xE8, 0x20, 0x85, 0xC0, 0x75, 0x1D, 0xE8, 0xD9, 0xD9, 0xE5, 0xFF, 0x48, 0x85, 0xC0, 0x74, 0x13, 0x48, 0x8D, 0x48, 0x10, 0xE8, 0xFB, 0xD3, 0xE5, 0xFF, 0xB9, 0x03, 0x00, 0x00, 0x00, 0x85, 0xC0, 0x0F, 0x45, 0xD9, 0x8B, 0x1D, 0x1B, 0x0C, 0x00, 0x00, 0x83, 0x3D, 0x1C, 0x0C, 0x00, 0x00, 0x00, 0x74, 0x06, 0x8B, 0x1D, 0x10, 0x0C, 0x00, 0x00, 0x8B, 0xC3, 0x48, 0x83, 0xC4, 0x60, 0x5B, 0xC3, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC }); - - // Jump to another section by addding some code to replace the values (Jump 1) - InjectCode((void*)0x000000014038AFF4, { 0xE9, 0x87, 0x0B, 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC }); - - // Jump to another section by addding some code to replace the values (Replace 1/2) while some reserving space for values - InjectCode((void*)0x000000014038BB40, { 0xFF, 0x05, 0x76, 0x00, 0x00, 0x00, 0x8B, 0x0D, 0x70, 0x00, 0x00, 0x00, 0xBA, 0x02, 0x00, 0x00, 0x00, 0x83, 0x3D, 0x60, 0x00, 0x00, 0x00, 0x00, 0x74, 0x02, 0xFF, 0xC2, 0x39, 0xD1, 0x0F, 0x4D, 0xCA, 0x89, 0x48, 0x08, 0xB9, 0x0E, 0x00, 0x00, 0x00, 0xE8, 0x92, 0x98, 0xE0, 0xFF, 0xB0, 0x01, 0x48, 0x83, 0xC4, 0x28, 0xC3, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x44, 0x89, 0x61, 0x08, 0x44, 0x88, 0x61, 0x0C, 0x4C, 0x89, 0x61, 0x10, 0x44, 0x89, 0x25, 0x29, 0x00, 0x00, 0x00, 0xE9, 0x68, 0xF4, 0xFF, 0xFF, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }); - - // Use the value from our own address instead of the original one - InjectCode((void*)0x00000001403F65AF, { 0x48, 0x8D, 0x05, 0x4A, 0x18, 0xDA, 0x00, 0x8B, 0x1D, 0x00, 0x56 }); - - // Jump to another section by addding some code to replace the values (Jump 2) - InjectCode((void*)0x00000001403F6638, { 0xE9, 0x03, 0x55, 0xF9, 0xFF, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC }); - - DWORD StageCountProtect; - VirtualProtect((int32_t*)0x14038BBB0, 0x10, PAGE_EXECUTE_READWRITE, &StageCountProtect); - - int* ESM = (int*)0x000000014038BBB0; - - if (nEStageManagerEncore) - ESM[1] = nEStageManager; - else - ESM[0] = nEStageManager; - - ESM[2] = nEStageManagerEncore; - - printf("[Patches] Enhanced Stage Manager enabled\n"); - } - // OpenGL Patches - /*if (nOGLPatchA) - { - // (call cs:glGetError) -> (xor eax, eax); (nop); (nop); (nop); (nop); - InjectCode((void*)0x000000014069D21D, { 0x31, 0xC0, 0x90, 0x90, 0x90, 0x90 }); - } - if (nOGLPatchB) - { - // (js loc_14069BC32) -> (nop)... - InjectCode((void*)0x000000014069BAF4, { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); - }*/ // The original slider update needs to run for hardware sliders to work -- only patch it when using emulation if (!nHardwareSlider) { @@ -754,18 +323,6 @@ class PatchApplier710 : public PatchApplier { InjectCode((void*)0x000000014061579B, { 0x90, 0x90, 0x90, 0x8B, 0x42, 0xE0, 0x90, 0x90, 0x90 }); } - - // lag compensation - 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 / 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); - } - // debug scaling by somewhatlurker if (nDwguiScaling) { @@ -806,5 +363,7 @@ class PatchApplier710 : public PatchApplier { InjectCode((void*)(0x140300a82), { 0x90, 0x90, 0x90 }); // NOPs InjectCode((void*)(0x140300a88), { 0x90, 0x90, 0x90 }); // NOPs } + ApplyExPatches(); } -}; \ No newline at end of file + #include "PatchApplier710EX.h" +}; diff --git a/source-code/source/PD-Loader/Patches/PatchApplier710EX.h b/source-code/source/PD-Loader/Patches/PatchApplier710EX.h new file mode 100644 index 0000000..3d39373 --- /dev/null +++ b/source-code/source/PD-Loader/Patches/PatchApplier710EX.h @@ -0,0 +1,341 @@ +#pragma once +#ifndef MINIMALIST +void ApplyExPatches() { + //// Graphics + + // MAG filter + if (nMAG > 0) + { + //InjectCode((void*)0x00000001404AB142, { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); + + unsigned char filter; + switch (nMAG) + { + case 1: // nearest + filter = 0; + InjectCode((void*)0x00000001404ACE56, { 0x90, 0x90 }); + break; + case 2: // sharpen + filter = 3; // sharpen(4tap) + break; + case 3: // cone + filter = 5; // cone(2tap) + break; + default: + filter = 1; + } + + //InjectCode((void*)0x00000001404A864F, { filter }); + //InjectCode((void*)0x00000001411AC518, { filter }); + + InjectCode((void*)0x00000001404ACE8E, { 0xB9, filter, 0x00, 0x00 }); + InjectCode((void*)0x00000001404ACE93, { 0x90 }); + } + + // Depth of Field + if (!nDoF) + { + InjectCode((void*)0x00000001409476AB, { 0x90, 0x90, 0x90, 0x90, 0x90 }); + + InjectCode((void*)0x00000001411AB650, { 0b00000001 }); + } + + // Reflections + if (!nReflections) + { + InjectCode((void*)0x1406477C0, { 0xE9, 0xF3, 0x00, 0x00, 0x00, 0x90 }); + InjectCode((void*)0x1411ADAFC, { 0x00 }); + } + + // patch refract and reflect buffer sizes + { + // no need to really check anything before injecting, because reinjecting defaults is fine + InjectCode((void*)(0x140a24424), std::vector((uint8_t*)&nRefractResWidth, (uint8_t*)((int64_t)&nRefractResWidth + 4))); + InjectCode((void*)(0x140a24428), std::vector((uint8_t*)&nRefractResHeight, (uint8_t*)((int64_t)&nRefractResHeight + 4))); + InjectCode((void*)(0x140a2443c), std::vector((uint8_t*)&nReflectResWidth, (uint8_t*)((int64_t)&nReflectResWidth + 4))); + InjectCode((void*)(0x140a24440), std::vector((uint8_t*)&nReflectResHeight, (uint8_t*)((int64_t)&nReflectResHeight + 4))); + // for large reflect resolutions, adjust blur effect amount to not lose the effect + // scaling is based on a 1024 width instead of the original 512px + // because we don't wanna make it too blurry when just being used to smooth jaggies + if (nReflectResWidth >= 2048) + { + int blurAmount = nReflectResWidth / 1024; + + // multiply blur setting + // ECX has blur amount, EDX has blur type + InjectCode((void*)(0x140503000), { 0x89, 0x15, 0x3a, 0xa3, 0xca, 0x00 }); // MOV dword ptr [0x1411ad340], EDX + InjectCode((void*)(0x140503006), { 0xb8 }); // MOV EAX, blurAmount + InjectCode((void*)(0x140503007), std::vector((uint8_t*)&blurAmount, (uint8_t*)((int64_t)&blurAmount + 4))); + InjectCode((void*)(0x14050300b), { 0xf7, 0xe1 }); // MUL (EDX:EAX,)ECX + InjectCode((void*)(0x14050300d), { 0xeb, 0x09 }); // JMP 0x140503018 + InjectCode((void*)(0x140503018), { 0x89, 0x05, 0x1e, 0xa3, 0xca, 0x00 }); // MOV dword ptr [0x1411ad33c], EAX + InjectCode((void*)(0x14050301e), { 0xc3 }); // RET + + // divide dwgui blur amount getting + // RDX gets type, RCX gets amount + InjectCode((void*)(0x140502910), { 0x48, 0x85, 0xd2 }); // TEST RDX, RDX + InjectCode((void*)(0x140502913), { 0x74, 0x08 }); // JZ 0x14050291d + InjectCode((void*)(0x140502915), { 0x8b, 0x05, 0x25, 0xaa, 0xca, 0x00 }); // MOV EAX, dword ptr [0x1411ad340] + InjectCode((void*)(0x14050291b), { 0x89, 0x02 }); // MOV dword ptr [RDX], EAX + + InjectCode((void*)(0x14050291d), { 0x48, 0x85, 0xc9 }); // TEST RCX, RCX + InjectCode((void*)(0x140502920), { 0x74, 0x2d }); // JZ 0x14050294f + InjectCode((void*)(0x140502922), { 0x8b, 0x05, 0x14, 0xaa, 0xca, 0x00 }); // MOV EAX, dword ptr [0x1411ad33c] + + InjectCode((void*)(0x140502928), { 0xeb, 0x0d }); // JMP 0x140502937 + InjectCode((void*)(0x140502937), { 0x49, 0xc7, 0xc0 }); // MOV R8, blurAmount + InjectCode((void*)(0x14050293a), std::vector((uint8_t*)&blurAmount, (uint8_t*)((int64_t)&blurAmount + 4))); + InjectCode((void*)(0x14050293e), { 0xeb, 0x08 }); // JMP 0x140502948 + InjectCode((void*)(0x140502948), { 0x31, 0xd2 }); // XOR EDX,EDX + InjectCode((void*)(0x14050294a), { 0x49, 0xf7, 0xf0 }); // DIV (EDX:EAX,)R8 + + InjectCode((void*)(0x14050294d), { 0x89, 0x01 }); // MOV dword ptr [RCX], EAX + InjectCode((void*)(0x14050294f), { 0xc3 }); // RET + } + } + + // gamma + if (nGamma != 100) + { + 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); + } + + // Shadows + if (!nShadows) + { + //InjectCode((void*)0x140502B44, { 0x90, 0x90, 0x90 }); + //InjectCode((void*)0x140502BB2, { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); + InjectCode((void*)0x140502766, { 0x00 }); + InjectCode((void*)0x1411AD438, { 0x00 }); + InjectCode((void*)0x1411AD320, { 0x00 }); + } + + // Punch-through transparency + if (!nPunchthrough) + { + InjectCode((void*)0x1411AD43D, { 0x00 }); + } + + // Glare + if (!nGlare) + { + InjectCode((void*)0x1404B2168, { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); + } + + // Shader + if (!nShader) + { + InjectCode((void*)0x140C9C48E, { 0x00 }); + } + + // NPR1 + { + if (nNpr1 == 1) // force on + { + InjectCode((void*)0x0000000140502FC0, { 0xC7, 0x05, 0x6E }); + InjectCode((void*)0x0000000140502FC6, { 0x01, 0x00, 0x00, 0x00, 0xC3 }); + + printf("[Patches] NPR1 forced\n"); + } + else if (nNpr1 == 2) // force off + { + InjectCode((void*)0x0000000140502FC0, { 0xC7, 0x05, 0x6E }); + InjectCode((void*)0x0000000140502FC6, { 0x00, 0x00, 0x00, 0x00, 0xC3 }); + + printf("[Patches] NPR1 disabled\n"); + } + } + + // 2D + if (n2D) + { + //InjectCode((void*)0x140502B44, { 0x90, 0x90, 0x90 }); + InjectCode((void*)0x140502BB2, { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); + InjectCode((void*)0x140502A3C, { 0x90, 0x90, 0x90, 0x90, 0x90 }); + /*InjectCode((void*)0x1411AD320, { 0x00 }); // shadow + InjectCode((void*)0x1411AD323, { 0x00 }); // reflect + InjectCode((void*)0x1411AD321, { 0x00 }); // SS_SSS + InjectCode((void*)0x1411AD325, { 0x00 }); // preprocess + InjectCode((void*)0x1411AD328, { 0x00 }); // 3D*/ + InjectCode((void*)0x1411AD32A, { 0x01 }); // post process + InjectCode((void*)0x1411AD32B, { 0x01 }); // sprite + + InjectCode((void*)0x140A07920, { 0x00 }); // ignore objset + } + + + //// Compatibility + + // Prevent data deletion + if (nNoDelete) + { + InjectCode((void*)(0x1406FEF80 + 0x1DB), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); + InjectCode((void*)(0x1407113F0 + 0x13C), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); + InjectCode((void*)(0x140712270 + 0x6C), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); + InjectCode((void*)(0x140712580 + 0x4C), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); + InjectCode((void*)(0x140712580 + 0x7C), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); + InjectCode((void*)(0x140713470 + 0x104), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); + InjectCode((void*)(0x1407135B0 + 0x102), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); + InjectCode((void*)(0x1407135B0 + 0x135), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); + InjectCode((void*)(0x1407135B0 + 0x232), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); + InjectCode((void*)(0x140713810 + 0x3E8), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); + InjectCode((void*)(0x140713D00 + 0x677), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); + InjectCode((void*)(0x1407168A0 + 0x9C), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); + InjectCode((void*)(0x1407168A0 + 0x1D2), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); + InjectCode((void*)(0x1407168A0 + 0x218), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); + InjectCode((void*)(0x1407168A0 + 0x22A), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); + InjectCode((void*)(0x140720910 + 0x25C), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); + InjectCode((void*)(0x140723EE0 + 0xEC), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); + InjectCode((void*)(0x140870DE0 + 0x4), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); + InjectCode((void*)(0x1406FEF80 + 0x1DB), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); + InjectCode((void*)(0x1407113F0 + 0x13C), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); + InjectCode((void*)(0x140712270 + 0x6E), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); + InjectCode((void*)(0x140712580 + 0x4C), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); + InjectCode((void*)(0x140712580 + 0x7C), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); + InjectCode((void*)(0x140713470 + 0x104), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); + InjectCode((void*)(0x1407135B0 + 0x102), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); + InjectCode((void*)(0x1407135B0 + 0x135), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); + InjectCode((void*)(0x1407135B0 + 0x232), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); + InjectCode((void*)(0x140713810 + 0x3E8), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); + InjectCode((void*)(0x140713D00 + 0x677), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); + InjectCode((void*)(0x1407168A0 + 0x9C), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); + InjectCode((void*)(0x1407168A0 + 0x1D2), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); + InjectCode((void*)(0x1407168A0 + 0x218), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); + InjectCode((void*)(0x1407168A0 + 0x22A), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); + InjectCode((void*)(0x140720910 + 0x25C), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); + InjectCode((void*)(0x140723EE0 + 0xEC), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); + InjectCode((void*)(0x1407168A0 + 0x9C), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); + InjectCode((void*)(0x140870DE0 + 0x4), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); + InjectCode((void*)(0x14081B6A4), { 0xC3 }); + + InjectCode((void*)(0x1406E1090 + 0x43C), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); + InjectCode((void*)(0x140718250 + 0x176), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); + InjectCode((void*)(0x140718750 + 0xC9), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); + InjectCode((void*)(0x1407193E0 + 0xFC), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); + InjectCode((void*)(0x1406E1090 + 0x43C), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); + InjectCode((void*)(0x140718250 + 0x176), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); + InjectCode((void*)(0x140718750 + 0xC9), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); + InjectCode((void*)(0x1407193E0 + 0xFC), { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); + InjectCode((void*)(0x14081B67A), { 0xC3 }); + } + + // no osage play data by Skyth + if (nNoOpd) + { + InjectCode((void*)(0x1404728C0), { 0xC3 }); + InjectCode((void*)(0x1404789C3), { 0x0D }); + } + + + //// PV Selector + + // Unlock PSEUDO modules (which will all default to Miku, unless we also patch them to match the first performer) + if (nUnlockPseudo) + { + InjectCode((void*)0x0000000140A21770, { 0x00 }); + InjectCode((void*)0x0000000140A21780, { 0x00 }); + InjectCode((void*)0x0000000140A21790, { 0x00 }); + InjectCode((void*)0x0000000140A217A0, { 0x00 }); + InjectCode((void*)0x0000000140A217B0, { 0x00 }); + } + + // Disable scrolling sound effect + if (nNoScrollingSfx) + { + InjectCode((void*)0x00000001405C84B3, { 0x90, 0x90, 0x90, 0x90, 0x90 }); + } + + + //// UI Elements + + // Disable timer sprite + if (nNoTimerSprite) + { + InjectCode((void*)0x00000001409C0758, { 0x00 }); // time_loop + InjectCode((void*)0x0000000140A3D3F0, { 0x00 }); // time_in + InjectCode((void*)0x0000000140A3D3F8, { 0x00 }); // time_out + } + + // no message bar + if (nNoMessageBar) + { + InjectCode((void*)(0x1409F6470), { 0x00 }); + + // no scrolling message by snakemi + InjectCode((void*)(0x1403B98FD), { 0x00, 0x00, 0x00, 0x00 }); + InjectCode((void*)(0x1403B9904), { 0x00, 0x00, 0x00, 0x00 }); + InjectCode((void*)(0x1403B990B), { 0x00, 0x00, 0x00, 0x00 }); + } + + // no stage text + if (nNoStageText) + { + InjectCode((void*)(0x140A3D4C8), { 0x00 }); + InjectCode((void*)(0x140A3D4D8), { 0x00 }); + InjectCode((void*)(0x140A3D4E8), { 0x00 }); + InjectCode((void*)(0x140A3D4F8), { 0x00 }); + InjectCode((void*)(0x140A3D508), { 0x00 }); + InjectCode((void*)(0x140A3D518), { 0x00 }); + InjectCode((void*)(0x140A3D530), { 0x00 }); + InjectCode((void*)(0x140A3D540), { 0x00 }); + InjectCode((void*)(0x140A3D550), { 0x00 }); + } + + // Enable card button by somewhatlurker (pretty much just eye candy for now) + if (nCard) + { + InjectCode((void*)0x0000000140565E6B, { 0x90, 0x90 }); + } + // Quick start + { + if (nQuickStart == 1) // skip the card/guest screen + { + InjectCode((void*)0x0000000140578EA9, { 0xE9, 0x8E, 0x00, 0x00, 0x00 }); + } + else if (nQuickStart == 2) // skip everything; normal mode + { + InjectCode((void*)0x0000000140578EA9, { 0xE9, 0xF1, 0x00, 0x00, 0x00 }); + InjectCode((void*)0x0000000140578E9D, { 0xC7, 0x47, 0x68, 0x28, 0x00, 0x00, 0x00 }); // skip back button error + } + } + + + // modpack redirection + /*{ + wchar_t* mpstr = NULL; + mpstr = (wchar_t*)malloc(256); + memset(mpstr, 0, 256); + GetPrivateProfileStringW(L"Mods", L"Modpack", L"", mpstr, 256, CONFIG_FILE_NAME); + std::string modpack_name(std::filesystem::path(mpstr).string()); + free(mpstr); + std::cout << "[Patches] Modpack name: " << modpack_name << std::endl; + + if (modpack_name != "") + { + // ram + std::string modpack_path = "modpacks\\" + modpack_name; + std::cout << "[Patches] New ram path: " << modpack_path << std::endl; + char* mpstr_path = (char*)malloc(modpack_path.size()); + memcpy(mpstr_path, modpack_path.c_str(), modpack_path.size()); + InjectLong((void*)0x0000000014096C120, (long)mpstr_path); + + // mdata + std::string modpack_mdata = "modpacks\\" + modpack_name + "\\mdata"; + std::cout << "[Patches] New mdata path: " << modpack_mdata << std::endl; + char* mpstr_mdata = (char*)malloc(modpack_mdata.size()); + memcpy(mpstr_mdata, modpack_mdata.c_str(), modpack_mdata.size()); + InjectCode((void*)0x000000014066CEA0, { 0x48, 0xC7, 0xC2 }); + InjectInt((void*)0x000000014066CEA3, (int)mpstr_mdata); + InjectCode((void*)0x000000014066CE9C, { (unsigned char)modpack_mdata.size() }); + InjectCode((void*)0x000000014066CEAE, { (unsigned char)modpack_mdata.size() }); + } + }*/ +} +#else +void ApplyExPatches() { + return; +}; +#endif \ No newline at end of file diff --git a/source-code/source/PD-Loader/Patches/patches-framework.h b/source-code/source/PD-Loader/Patches/patches-framework.h index 1ee5178..d0731eb 100644 --- a/source-code/source/PD-Loader/Patches/patches-framework.h +++ b/source-code/source/PD-Loader/Patches/patches-framework.h @@ -70,30 +70,41 @@ void InjectLong(void* address, const long data) const LPCWSTR CONFIG_FILE = L"plugins\\config.ini"; const LPCWSTR CONFIG_FILE_NAME = L".\\config.ini"; -auto nCursor = GetPrivateProfileIntW(L"patches", L"cursor", TRUE, CONFIG_FILE); -auto nHideFreeplay = GetPrivateProfileIntW(L"patches", L"hide_freeplay", FALSE, CONFIG_FILE); -auto nFreeplay = GetPrivateProfileIntW(L"patches", L"freeplay", TRUE, CONFIG_FILE); -auto nPDLoaderText = GetPrivateProfileIntW(L"patches", L"pdloadertext", TRUE, CONFIG_FILE); -auto nStatusIcons = GetPrivateProfileIntW(L"patches", L"status_icons", 0, CONFIG_FILE); -auto nHidePVWatermark = GetPrivateProfileIntW(L"patches", L"hide_pv_watermark", FALSE, CONFIG_FILE); -auto nNoPVUi = GetPrivateProfileIntW(L"patches", L"no_pv_ui", FALSE, CONFIG_FILE); -auto nHideVolCtrl = GetPrivateProfileIntW(L"patches", L"hide_volume", FALSE, CONFIG_FILE); -auto nNoLyrics = GetPrivateProfileIntW(L"patches", L"no_lyrics", FALSE, CONFIG_FILE); -auto nNoMovies = GetPrivateProfileIntW(L"patches", L"no_movies", FALSE, CONFIG_FILE); -auto nNoError = GetPrivateProfileIntW(L"patches", L"no_error", FALSE, CONFIG_FILE); -auto nNoTimer = GetPrivateProfileIntW(L"patches", L"no_timer", TRUE, CONFIG_FILE); -auto nEStageManager = GetPrivateProfileIntW(L"patches", L"enhanced_stage_manager", 0, CONFIG_FILE); -auto nEStageManagerEncore = GetPrivateProfileIntW(L"patches", L"enhanced_stage_manager_encore", TRUE, CONFIG_FILE); -auto nHardwareSlider = GetPrivateProfileIntW(L"patches", L"hardware_slider", FALSE, CONFIG_FILE); -//auto nOGLPatchA = GetPrivateProfileIntW(L"patches", L"opengl_patch_a", FALSE, CONFIG_FILE); -//auto nOGLPatchB = GetPrivateProfileIntW(L"patches", L"opengl_patch_b", FALSE, CONFIG_FILE); + +///////////////////// +////// Options ////// +///////////////////// + +// Graphics auto nTAA = GetPrivateProfileIntW(L"graphics", L"taa", TRUE, CONFIG_FILE); auto nMLAA = GetPrivateProfileIntW(L"graphics", L"mlaa", TRUE, CONFIG_FILE); -auto nStereo = GetPrivateProfileIntW(L"patches", L"stereo", TRUE, CONFIG_FILE); +auto nLagCompensation = GetPrivateProfileIntW(L"graphics", L"lag_compensation", 0, CONFIG_FILE); + +// Loader auto nBuiltinPatches = GetPrivateProfileIntW(L"global", L"builtin_patches", TRUE, CONFIG_FILE); auto nCustomPatches = GetPrivateProfileIntW(L"global", L"custom_patches", TRUE, CONFIG_FILE); -auto nLagCompensation = GetPrivateProfileIntW(L"graphics", L"lag_compensation", 0, CONFIG_FILE); + +// Compatibility +auto nNoMovies = GetPrivateProfileIntW(L"patches", L"no_movies", FALSE, CONFIG_FILE); +auto nStereo = GetPrivateProfileIntW(L"patches", L"stereo", TRUE, CONFIG_FILE); + +// PV Selector +auto nFreeplay = GetPrivateProfileIntW(L"patches", L"freeplay", TRUE, CONFIG_FILE); + +// UI Elements +auto nCursor = GetPrivateProfileIntW(L"patches", L"cursor", TRUE, CONFIG_FILE); +auto nHideVolCtrl = GetPrivateProfileIntW(L"patches", L"hide_volume", FALSE, CONFIG_FILE); +auto nNoPVUi = GetPrivateProfileIntW(L"patches", L"no_pv_ui", FALSE, CONFIG_FILE); +auto nHidePVWatermark = GetPrivateProfileIntW(L"patches", L"hide_pv_watermark", FALSE, CONFIG_FILE); +auto nStatusIcons = GetPrivateProfileIntW(L"patches", L"status_icons", 0, CONFIG_FILE); +auto nHideFreeplay = GetPrivateProfileIntW(L"patches", L"hide_freeplay", FALSE, CONFIG_FILE); +auto nNoLyrics = GetPrivateProfileIntW(L"patches", L"no_lyrics", FALSE, CONFIG_FILE); +auto nNoError = GetPrivateProfileIntW(L"patches", L"no_error", FALSE, CONFIG_FILE); +auto nPDLoaderText = GetPrivateProfileIntW(L"patches", L"pdloadertext", TRUE, CONFIG_FILE); +auto nNoTimer = GetPrivateProfileIntW(L"patches", L"no_timer", TRUE, CONFIG_FILE); +auto nHardwareSlider = GetPrivateProfileIntW(L"patches", L"hardware_slider", FALSE, CONFIG_FILE); auto nDwguiScaling = GetPrivateProfileIntW(L"patches", L"dwgui_scaling", FALSE, CONFIG_FILE); + #ifndef MINIMALIST auto nNoTimerSprite = GetPrivateProfileIntW(L"patches", L"no_timer_sprite", TRUE, CONFIG_FILE); auto nUnlockPseudo = GetPrivateProfileIntW(L"patches", L"unlock_pseudo", FALSE, CONFIG_FILE); @@ -102,12 +113,6 @@ auto nDoF = GetPrivateProfileIntW(L"graphics", L"dof", TRUE, CONFIG_FILE); auto nMAG = GetPrivateProfileIntW(L"graphics", L"mag", 0, 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 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); -auto nForceLook = GetPrivateProfileIntW(L"patches", L"force_look", 0, CONFIG_FILE); auto nNpr1 = GetPrivateProfileIntW(L"graphics", L"npr1", 0, CONFIG_FILE); auto nReflections = GetPrivateProfileIntW(L"graphics", L"reflections", TRUE, CONFIG_FILE); auto nGamma = GetPrivateProfileIntW(L"graphics", L"gamma", 100, CONFIG_FILE); diff --git a/source-code/source/PD-Loader/dllmain.cpp b/source-code/source/PD-Loader/dllmain.cpp index d07fdb5..17f3fbb 100644 --- a/source-code/source/PD-Loader/dllmain.cpp +++ b/source-code/source/PD-Loader/dllmain.cpp @@ -222,7 +222,7 @@ void FindFiles(WIN32_FIND_DATAW* fd) { if (fd->cFileName[0] == '.' && fd->cFileName[1] == '_') continue; // exclude macOS metadata - if (!_wcsicmp(fd->cFileName, L"Patches.dva") || !_wcsicmp(fd->cFileName, L"Render.dva")) + if (!_wcsicmp(fd->cFileName, L"Patches.dva") || !_wcsicmp(fd->cFileName, L"Render.dva") || !_wcsicmp(fd->cFileName, L"DivaWig.dva")) { DeleteFileW(fd->cFileName); continue; diff --git a/source-code/source/PD-Loader/templates.h b/source-code/source/PD-Loader/templates.h index 15cdcca..0c0df2f 100644 --- a/source-code/source/PD-Loader/templates.h +++ b/source-code/source/PD-Loader/templates.h @@ -54,23 +54,6 @@ char config_template[] = "# Disable the scrolling sound effect\n" "No_Scrolling_SFX=0\n" #endif -"# Enhanced Stage Manager (sets a custom number of stages; \"stage_manager\" should be disabled in \"components.ini\")\n" -"# Number of stages (0 = disabled)\n" -"Enhanced_Stage_Manager=0\n" -"# Use encore stages or not\n" -"Enhanced_Stage_Manager_Encore=1\n" -#ifndef MINIMALIST -"# Change the mouth animations -- 0=default, 1=force PDA, 2=force FT\n" -"Force_Mouth=0\n" -"# Change the expressions -- 0=default, 1=force PDA, 2=force FT\n" -"Force_Expressions=0\n" -"# Change the look animations -- 0=default, 1=force PDA, 2=force FT\n" -"Force_Look=0\n" -"# Disable hand scaling\n" -"No_Hand_Scaling=0\n" -"# Default hand size -- -1=default, 12200=PDA\n" -"Default_Hand_Size=-1\n" -#endif "# Show \"FREE PLAY\" instead of \"CREDIT(S)\" and don't require credits\n" "Freeplay=1\n" #ifndef MINIMALIST diff --git a/source-code/source/plugins/DivaMovie/dllmain.cpp b/source-code/source/plugins/DivaMovie/dllmain.cpp index ed516fa..11bbdd4 100644 --- a/source-code/source/plugins/DivaMovie/dllmain.cpp +++ b/source-code/source/plugins/DivaMovie/dllmain.cpp @@ -204,7 +204,7 @@ extern "C" __declspec(dllexport) LPCWSTR GetPluginName(void) extern "C" __declspec(dllexport) LPCWSTR GetPluginDescription(void) { - return L"DivaMovie Plugin by Skyth\n\nDivaMovie enables movies on systems that does not support DXVA hardware decoding."; + return L"DivaMovie Plugin by Skyth\n\nDivaMovie enables movies on systems that do not support DXVA hardware decoding."; } extern "C" __declspec(dllexport) PluginConfig::PluginConfigArray GetPluginOptions(void) diff --git a/source-code/source/plugins/DivaWig/DivaWig.vcxproj b/source-code/source/plugins/DivaWig/DivaWig.vcxproj index adbdbcc..b91d393 100644 --- a/source-code/source/plugins/DivaWig/DivaWig.vcxproj +++ b/source-code/source/plugins/DivaWig/DivaWig.vcxproj @@ -19,6 +19,7 @@ {2394C586-F73B-4EF2-BA3E-2A0FC3034B1A} DivaWig 10.0 + CustoMixer diff --git a/source-code/source/plugins/DivaWig/dllmain.cpp b/source-code/source/plugins/DivaWig/dllmain.cpp index 6e72aaf..7af6cf4 100644 --- a/source-code/source/plugins/DivaWig/dllmain.cpp +++ b/source-code/source/plugins/DivaWig/dllmain.cpp @@ -1,5 +1,5 @@ -#include "framework.h" #include "PluginConfigApi.h" +#include "framework.h" #include #include #include @@ -52,20 +52,163 @@ unsigned int last_unload_a2 = 0, last_reload_a2 = 0; __int64 last_unload_a3 = 0, last_reload_a3 = 0;*/ bool dobeep = true, allowReloading = true, debug = false; +int nNoHandScaling, nDefaultHandSize, nSingMissed, nForceMouth, nForceExpressions, nForceLook; void loadConfig() -{ - dobeep = GetPrivateProfileIntW(L"general", L"beep", 1, CONFIG_FILE) > 0 ? true : false; - allowReloading = GetPrivateProfileIntW(L"general", L"reloading", 0, CONFIG_FILE) > 0 ? true : false; +{ + dobeep = GetPrivateProfileIntW(L"wig", L"beep", 1, CONFIG_FILE) > 0 ? true : false; + allowReloading = GetPrivateProfileIntW(L"wig", L"reloading", 0, CONFIG_FILE) > 0 ? true : false; debug = GetPrivateProfileIntW(L"general", L"debug", 0, CONFIG_FILE) > 0 ? true : false; + nSingMissed = GetPrivateProfileIntW(L"patches", L"sing_missed", FALSE, CONFIG_FILE) > 0 ? true : false; + nNoHandScaling = GetPrivateProfileIntW(L"patches", L"no_hand_scaling", FALSE, CONFIG_FILE) > 0 ? true : false; + nDefaultHandSize = GetPrivateProfileIntW(L"patches", L"default_hand_size", -1, CONFIG_FILE); + nForceMouth = GetPrivateProfileIntW(L"patches", L"force_mouth", 0, CONFIG_FILE); + nForceExpressions = GetPrivateProfileIntW(L"patches", L"force_expressions", 0, CONFIG_FILE); + nForceLook = GetPrivateProfileIntW(L"patches", L"force_look", 0, CONFIG_FILE); + return; } +void pvPatches() +{ + cout << "[CustoMixer] Applying PV patches..." << endl; + + // Sing missed notes + if (nSingMissed) + { + InjectCode((void*)0x140109044, { 0xEB }); + // Breaks border: + // InjectCode((void*)0x140109096, { 0xEB }); + } + + // Force mouth animations + { + if (nForceMouth == 1) // PDA + { + printf("[Patches] Forcing PDA mouth...\n"); + int* mouth_table = (int*)(0x1409A1DC0); + DWORD oldProtect; + VirtualProtect(mouth_table, 44, PAGE_EXECUTE_READWRITE, &oldProtect); + for (int i = 0; i < 11; i++) + { + mouth_table[i]++; + } + VirtualProtect(mouth_table, 44, oldProtect, nullptr); + printf("[Patches] PDA mouth forced\n"); + } + else if (nForceMouth == 2) // FT + { + printf("[Patches] Forcing FT mouth...\n"); + int* mouth_table_oldid = (int*)(0x1409A1E1C); + DWORD oldProtect; + VirtualProtect(mouth_table_oldid, 44, PAGE_EXECUTE_READWRITE, &oldProtect); + for (int i = 0; i < 11; i++) + { + mouth_table_oldid[i]--; + } + VirtualProtect(mouth_table_oldid, 44, oldProtect, nullptr); + printf("[Patches] FT mouth forced\n"); + } + } + + // Force expressions + { + if (nForceExpressions == 1) // PDA + { + printf("[Patches] Forcing PDA expressions...\n"); + int* exp_table = (int*)(0x140A21900); + DWORD oldProtect; + VirtualProtect(exp_table, 104, PAGE_EXECUTE_READWRITE, &oldProtect); + for (int i = 0; i < 26; i++) + { + exp_table[i] += 2; + } + VirtualProtect(exp_table, 104, oldProtect, nullptr); + printf("[Patches] PDA expressions forced\n"); + } + else if (nForceExpressions == 2) // FT + { + printf("[Patches] Forcing FT expressions...\n"); + int* exp_table_oldid = (int*)(0x140A219D0); + DWORD oldProtect; + VirtualProtect(exp_table_oldid, 104, PAGE_EXECUTE_READWRITE, &oldProtect); + for (int i = 0; i < 26; i++) + { + exp_table_oldid[i] -= 2; + } + VirtualProtect(exp_table_oldid, 104, oldProtect, nullptr); + printf("[Patches] FT expressions forced\n"); + } + } + + // Force look animations + { + if (nForceLook == 1) // PDA + { + printf("[Patches] Forcing PDA look...\n"); + int* look_table = (int*)(0x1409A1D70); + DWORD oldProtect; + VirtualProtect(look_table, 36, PAGE_EXECUTE_READWRITE, &oldProtect); + for (int i = 0; i < 9; i++) + { + look_table[i]++; + } + VirtualProtect(look_table, 36, oldProtect, nullptr); + printf("[Patches] PDA look forced\n"); + } + else if (nForceLook == 2) // FT + { + printf("[Patches] Forcing FT look...\n"); + int* look_table_oldid = (int*)(0x1409A1D9C); + DWORD oldProtect; + VirtualProtect(look_table_oldid, 36, PAGE_EXECUTE_READWRITE, &oldProtect); + for (int i = 0; i < 9; i++) + { + look_table_oldid[i]--; + } + VirtualProtect(look_table_oldid, 36, oldProtect, nullptr); + printf("[Patches] FT look forced\n"); + } + } + + // Disable hand scaling + if (nNoHandScaling) + { + InjectCode((void*)0x0000000140120709, { 0xE9, 0x82, 0x0A, 0x00 }); + } + + // Default hand size + if (nDefaultHandSize != -1 && nDefaultHandSize < 1) + { + MessageBoxW(nullptr, L"The default hand size is lower than 1 and higher than -1 (default). Hands may disappear.\n\nIf this is not intentional, set it back to -1.", L"CustoMixer", MB_ICONWARNING); + + printf("[Patches] Changing default hand size...\n"); + const float num = (float)nDefaultHandSize / 10000.0; + DWORD oldProtect; + float* addr1 = (float*)(0x140506B59); + float* addr2 = (float*)(0x140506B60); + /*float* addr3 = (float*)(0x140506B67); + float* addr4 = (float*)(0x140506B71);*/ + VirtualProtect(addr1, 4, PAGE_EXECUTE_READWRITE, &oldProtect); + VirtualProtect(addr2, 4, PAGE_EXECUTE_READWRITE, &oldProtect); + /*VirtualProtect(addr3, 4, PAGE_EXECUTE_READWRITE, &oldProtect); + VirtualProtect(addr4, 4, PAGE_EXECUTE_READWRITE, &oldProtect);*/ + *addr1 = *addr2 /*= *addr3 = *addr4*/ = num; + VirtualProtect(addr1, 4, oldProtect, nullptr); + VirtualProtect(addr2, 4, oldProtect, nullptr); + /*VirtualProtect(addr3, 4, oldProtect, nullptr); + VirtualProtect(addr4, 4, oldProtect, nullptr);*/ + printf("[Patches] New default hand size: %f\n", num); + } + + cout << "[CustoMixer] PV patches applied." << endl; +} + void setPartToUpdate(char part, string message, unsigned short beepfreq) { part_to_update = part; - cout << "[DivaWig] " << message << endl; + cout << "[CustoMixer] " << message << endl; if (dobeep) Beep(beepfreq, 300); this_thread::sleep_for(chrono::seconds(1)); @@ -76,7 +219,7 @@ void unloadAll() unloadFunc((uint64_t*)0x1411B7060, 0, 5387286240); unloadFunc((uint64_t*)0x1411B7060, 0, 5387319280); unloadFunc((uint64_t*)0x1411B7060, 0, 5387352320); - cout << "[DivaWig] All unloaded!" << endl; + cout << "[CustoMixer] All unloaded!" << endl; if (dobeep) Beep(500, 100); this_thread::sleep_for(chrono::seconds(1));; } @@ -84,7 +227,7 @@ void unloadAll() void unload(__int64 performer_address) { unloadFunc((uint64_t*)0x1411B7060, 0, performer_address); - cout << "[DivaWig] Performer " << performer_address/33040 + 1 << " unloaded!" << endl; + cout << "[CustoMixer] Performer " << performer_address/33040 + 1 << " unloaded!" << endl; if (dobeep) Beep(500, 100); this_thread::sleep_for(chrono::seconds(1));; } @@ -94,7 +237,7 @@ void loadAll() loadFunc((uint64_t*)0x1411B7060, 0, 5387286240); loadFunc((uint64_t*)0x1411B7060, 0, 5387319280); loadFunc((uint64_t*)0x1411B7060, 0, 5387352320); - cout << "[DivaWig] All loaded!" << endl; + cout << "[CustoMixer] All loaded!" << endl; if (dobeep) Beep(600, 100); this_thread::sleep_for(chrono::seconds(1));; } @@ -102,14 +245,14 @@ void loadAll() void load(__int64 performer_address) { loadFunc((uint64_t*)0x1411B7060, 0, performer_address); - cout << "[DivaWig] Performer " << performer_address / 33040 + 1 << " loaded!" << endl; + cout << "[CustoMixer] Performer " << performer_address / 33040 + 1 << " loaded!" << endl; if (dobeep) Beep(600, 100); this_thread::sleep_for(chrono::seconds(1)); } /*void hookedUnload(uint64_t* a1, unsigned int a2, __int64 a3) { - cout << "[DivaWig] hookedUnload a1: " << a1 << "; a2: " << a2 << "; a3: " << a3 << endl; + cout << "[CustoMixer] hookedUnload a1: " << a1 << "; a2: " << a2 << "; a3: " << a3 << endl; last_unload_a1 = a1; last_unload_a2 = a2; last_unload_a3 = a3; @@ -118,7 +261,7 @@ void load(__int64 performer_address) void hookedLoad(uint64_t* a1, unsigned int a2, __int64 a3) { - cout << "[DivaWig] hookedReload a1: " << a1 << "; a2: " << a2 << "; a3: " << a3 << endl; + cout << "[CustoMixer] hookedReload a1: " << a1 << "; a2: " << a2 << "; a3: " << a3 << endl; last_reload_a1 = a1; last_reload_a2 = a2; last_reload_a3 = a3; @@ -163,7 +306,7 @@ void inputLoop(__int64 a1) __int64 hookedWig(__int64 classp, int module_part, int part_id) { - if (debug) cout << "[DivaWig] Performer: " << (classp-5387286232)/33040+1 << "; Module part: " << module_part << " (" << Strings[module_part] << ")" << "; Default part: " << part_id << "." << endl; + if (debug) cout << "[CustoMixer] Performer: " << (classp-5387286232)/33040+1 << "; Module part: " << module_part << " (" << Strings[module_part] << ")" << "; Default part: " << part_id << "." << endl; if (part_to_update == ALL || part_to_update == module_part) *(int*)(classp + 4i64 * module_part + 8) = part_id; @@ -185,19 +328,19 @@ void hookedThi(unsigned int* a1, unsigned int module_part) BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { - if (ul_reason_for_call == DLL_PROCESS_ATTACH) { loadConfig(); + pvPatches(); DisableThreadLibraryCalls(hModule); DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); - cout << "[DivaWig] Hooking functions..." << endl; + cout << "[CustoMixer] Hooking functions..." << endl; DetourAttach(&(PVOID&)originalWig, (PVOID)hookedWig); DetourAttach(&(PVOID&)originalSec, (PVOID)hookedSec); DetourAttach(&(PVOID&)originalThi, (PVOID)hookedThi); DetourAttach(&(PVOID&)pvTimerUpdate, (PVOID)inputLoop); - cout << "[DivaWig] Functions hooked." << endl; + cout << "[CustoMixer] Functions hooked." << endl; DetourTransactionCommit(); /*if (allowReloading) @@ -221,20 +364,28 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv return TRUE; } +const std::vector typeList = { L"Default", L"PDA", L"PDAFT/PDFT/PDM39" }; + PluginConfig::PluginConfigOption config[] = { - { PluginConfig::CONFIG_BOOLEAN, new PluginConfig::PluginConfigBooleanData{ L"beep", L"general", CONFIG_FILE, L"Beep", L"Beep when selecting the part that should be updated.", true } }, - { PluginConfig::CONFIG_BOOLEAN, new PluginConfig::PluginConfigBooleanData{ L"reloading", L"general", CONFIG_FILE, L"Unloading and loading (experimental)", L"Allow unloading (CTRL+U or U+number) and loading (CTRL+L or L+number).", false } }, - { PluginConfig::CONFIG_BOOLEAN, new PluginConfig::PluginConfigBooleanData{ L"debug", L"general", CONFIG_FILE, L"Debug", L"Print extra information.", false } }, + { PluginConfig::CONFIG_BOOLEAN, new PluginConfig::PluginConfigBooleanData{ L"beep", L"wig", CONFIG_FILE, L"Beep", L"Beep when selecting the part that should be updated.", true } }, + { PluginConfig::CONFIG_BOOLEAN, new PluginConfig::PluginConfigBooleanData{ L"reloading", L"wig", CONFIG_FILE, L"Unloading and loading (experimental)", L"Allow unloading (CTRL+U or U+number) and loading (CTRL+L or L+number).", false } }, + { PluginConfig::CONFIG_BOOLEAN, new PluginConfig::PluginConfigBooleanData{ L"sing_missed", L"patches", CONFIG_FILE, L"Sing Missed Notes", L"Sing Missed Notes.", false } }, + { PluginConfig::CONFIG_BOOLEAN, new PluginConfig::PluginConfigBooleanData{ L"no_hand_scaling", L"patches", CONFIG_FILE, L"No Hand Scaling", L"Disable scripted hand scaling.", false } }, + { PluginConfig::CONFIG_NUMERIC, new PluginConfig::PluginConfigNumericData{ L"default_hand_size", L"patches", CONFIG_FILE, L"Default Hand Size:", L"-1: default\n12200: PDA", -1, -1, INT_MAX } }, + { PluginConfig::CONFIG_DROPDOWN_INDEX, new PluginConfig::PluginConfigDropdownIndexData{ L"force_mouth", L"patches", CONFIG_FILE, L"Mouth Animations:", L"Change the mouth animations.", 0, typeList}}, + { PluginConfig::CONFIG_DROPDOWN_INDEX, new PluginConfig::PluginConfigDropdownIndexData{ L"force_expressions", L"patches", CONFIG_FILE, L"Expr. Animations:", L"Change the expressions.", 0, typeList}}, + { PluginConfig::CONFIG_DROPDOWN_INDEX, new PluginConfig::PluginConfigDropdownIndexData{ L"force_look", L"patches", CONFIG_FILE, L"Look Animations:", L"Change the look animations.", 0, typeList}}, + { PluginConfig::CONFIG_BOOLEAN, new PluginConfig::PluginConfigBooleanData{ L"debug", L"general", CONFIG_FILE, L"Debug", L"Print extra information.", false } }, }; extern "C" __declspec(dllexport) LPCWSTR GetPluginName(void) { - return L"DivaWig"; + return L"CustoMixer"; } extern "C" __declspec(dllexport) LPCWSTR GetPluginDescription(void) { - return L"DivaWig Plugin by nas\n\nDivaWig lets you mix some module parts by pressing CTRL+0~9."; + return L"CustoMixer Plugin by nas\n\nCustoMixer lets you change some PV settings, and mix module parts by pressing CTRL+0~9."; } extern "C" __declspec(dllexport) PluginConfig::PluginConfigArray GetPluginOptions(void) diff --git a/source-code/source/plugins/DivaWig/framework.h b/source-code/source/plugins/DivaWig/framework.h index 740c11e..7f1280e 100644 --- a/source-code/source/plugins/DivaWig/framework.h +++ b/source-code/source/plugins/DivaWig/framework.h @@ -1,6 +1,16 @@ #include #include +void InjectCode(void* address, const std::vector data) +{ + const size_t byteCount = data.size() * sizeof(uint8_t); + + DWORD oldProtect; + VirtualProtect(address, byteCount, PAGE_EXECUTE_READWRITE, &oldProtect); + memcpy(address, data.data(), byteCount); + VirtualProtect(address, byteCount, oldProtect, nullptr); +} + std::wstring ExePath() { WCHAR buffer[MAX_PATH]; GetModuleFileNameW(NULL, buffer, MAX_PATH); @@ -13,5 +23,5 @@ std::wstring DirPath() { return exepath.substr(0, pos); } -std::wstring CONFIG_FILE_STRING = DirPath() + L"\\plugins\\DivaWig.ini"; +std::wstring CONFIG_FILE_STRING = DirPath() + L"\\plugins\\CustoMixer.ini"; LPCWSTR CONFIG_FILE = CONFIG_FILE_STRING.c_str(); diff --git a/source-code/source/plugins/EnhancedStageManager/EnhancedStageManager.filters b/source-code/source/plugins/EnhancedStageManager/EnhancedStageManager.filters new file mode 100644 index 0000000..ce68d0f --- /dev/null +++ b/source-code/source/plugins/EnhancedStageManager/EnhancedStageManager.filters @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/source-code/source/plugins/EnhancedStageManager/EnhancedStageManager.vcxproj b/source-code/source/plugins/EnhancedStageManager/EnhancedStageManager.vcxproj new file mode 100644 index 0000000..cee70d6 --- /dev/null +++ b/source-code/source/plugins/EnhancedStageManager/EnhancedStageManager.vcxproj @@ -0,0 +1,137 @@ + + + + + Debug + x64 + + + Minimalist + x64 + + + Release + x64 + + + + 16.0 + {3C8071F4-22C8-DA6E-A075-C5EC646DAB7E} + EnhancedStageManager + 10.0 + + + + DynamicLibrary + true + v142 + MultiByte + + + DynamicLibrary + false + v142 + true + MultiByte + + + DynamicLibrary + false + v142 + true + MultiByte + + + + + + + + + + + + + + + + + + .dva + + + .dva + + + .dva + + + + Level3 + Disabled + true + true + %(AdditionalIncludeDirectories) + -d2FH4- /utf-8 %(AdditionalOptions) + + + Console + %(AdditionalLibraryDirectories) + %(AdditionalDependencies) + -d2:-FH4- %(AdditionalOptions) + + + + + Level3 + MaxSpeed + true + true + true + true + %(AdditionalIncludeDirectories) + MultiThreadedDLL + -d2FH4- /utf-8 %(AdditionalOptions) + + + Console + true + true + %(AdditionalDependencies) + %(AdditionalLibraryDirectories) + -d2:-FH4- %(AdditionalOptions) + + + + + Level3 + MaxSpeed + true + true + true + true + %(AdditionalIncludeDirectories) + MultiThreadedDLL + -d2FH4- /utf-8 %(AdditionalOptions) + MINIMALIST;_WINDLL;%(PreprocessorDefinitions) + + + Console + true + true + %(AdditionalDependencies) + ..\..\..\dependencies\detours\lib;%(AdditionalLibraryDirectories) + -d2:-FH4- %(AdditionalOptions) + + + + + + + + + + + + + \ No newline at end of file diff --git a/source-code/source/plugins/EnhancedStageManager/PluginConfigApi.h b/source-code/source/plugins/EnhancedStageManager/PluginConfigApi.h new file mode 100644 index 0000000..d0ffd94 --- /dev/null +++ b/source-code/source/plugins/EnhancedStageManager/PluginConfigApi.h @@ -0,0 +1,168 @@ +#pragma once +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +#include +#include + +// 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 valueStrings; + }; + + struct PluginConfigDropdownTextData { + LPCWSTR iniVarName; + LPCWSTR iniSectionName; + LPCWSTR iniFilePath; + LPCWSTR friendlyName; + LPCWSTR description; + LPCWSTR defaultVal; + std::vector valueStrings; + bool editable; + bool useUtf8; + }; + + struct PluginConfigDropdownNumberData { + LPCWSTR iniVarName; + LPCWSTR iniSectionName; + LPCWSTR iniFilePath; + LPCWSTR friendlyName; + LPCWSTR description; + int defaultVal; + std::vector valueInts; + bool editable; + }; + + struct PluginConfigResolutionData { + LPCWSTR iniVarName; + LPCWSTR iniVarName2; + LPCWSTR iniSectionName; + LPCWSTR iniFilePath; + LPCWSTR friendlyName; + LPCWSTR description; + resolution defaultVal; + std::vector 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) +} \ No newline at end of file diff --git a/source-code/source/plugins/EnhancedStageManager/dllmain.cpp b/source-code/source/plugins/EnhancedStageManager/dllmain.cpp new file mode 100644 index 0000000..4c1cafb --- /dev/null +++ b/source-code/source/plugins/EnhancedStageManager/dllmain.cpp @@ -0,0 +1,76 @@ +#include "PluginConfigApi.h" +#include "framework.h" + +int nEStageManager, nEStageManagerEncore; + +void loadConfig() +{ + nEStageManager = GetPrivateProfileIntW(L"patches", L"enhanced_stage_manager", 0, CONFIG_FILE); + nEStageManagerEncore = GetPrivateProfileIntW(L"patches", L"enhanced_stage_manager_encore", FALSE, CONFIG_FILE) > 0 ? true : false; + + if (nEStageManager < 1) nEStageManager = INT_MAX; + + return; +} + +BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) +{ + + if (ul_reason_for_call == DLL_PROCESS_ATTACH) + { + loadConfig(); + + //// TODO: rewrite without injecting assembly + + // Replace the function that provides the number of stages and compact some of it + InjectCode((void*)0x000000014038AEF0, { 0x48, 0x8B, 0x88, 0x40, 0x01, 0x00, 0x00, 0x48, 0x89, 0x4C, 0x24, 0x20, 0x48, 0x8B, 0xD0, 0x48, 0x8B, 0x88, 0x48, 0x01, 0x00, 0x00, 0x48, 0x89, 0x4C, 0x24, 0x28, 0x8B, 0x88, 0x50, 0x01, 0x00, 0x00, 0x89, 0x4C, 0x24, 0x30, 0x8B, 0x88, 0x54, 0x01, 0x00, 0x00, 0x8B, 0x80, 0x58, 0x01, 0x00, 0x00, 0x89, 0x44, 0x24, 0x38, 0x8B, 0x82, 0x5C, 0x01, 0x00, 0x00, 0x89, 0x4C, 0x24, 0x34, 0x89, 0x44, 0x24, 0x3C, 0x48, 0x8B, 0x82, 0x60, 0x01, 0x00, 0x00, 0x48, 0x89, 0x44, 0x24, 0x40, 0x48, 0x8B, 0x82, 0x68, 0x01, 0x00, 0x00, 0x48, 0x89, 0x44, 0x24, 0x48, 0x48, 0x8B, 0x82, 0x70, 0x01, 0x00, 0x00, 0x48, 0x89, 0x44, 0x24, 0x50, 0x8B, 0x82, 0x78, 0x01, 0x00, 0x00, 0x89, 0x44, 0x24, 0x58, 0x84, 0xC0, 0x74, 0x2A, 0x48, 0x8B, 0x44, 0x24, 0x38, 0x48, 0xC1, 0xE8, 0x20, 0x85, 0xC0, 0x75, 0x1D, 0xE8, 0xD9, 0xD9, 0xE5, 0xFF, 0x48, 0x85, 0xC0, 0x74, 0x13, 0x48, 0x8D, 0x48, 0x10, 0xE8, 0xFB, 0xD3, 0xE5, 0xFF, 0xB9, 0x03, 0x00, 0x00, 0x00, 0x85, 0xC0, 0x0F, 0x45, 0xD9, 0x8B, 0x1D, 0x1B, 0x0C, 0x00, 0x00, 0x83, 0x3D, 0x1C, 0x0C, 0x00, 0x00, 0x00, 0x74, 0x06, 0x8B, 0x1D, 0x10, 0x0C, 0x00, 0x00, 0x8B, 0xC3, 0x48, 0x83, 0xC4, 0x60, 0x5B, 0xC3, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC }); + + // Jump to another section by addding some code to replace the values (Jump 1) + InjectCode((void*)0x000000014038AFF4, { 0xE9, 0x87, 0x0B, 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC }); + + // Jump to another section by addding some code to replace the values (Replace 1/2) while some reserving space for values + InjectCode((void*)0x000000014038BB40, { 0xFF, 0x05, 0x76, 0x00, 0x00, 0x00, 0x8B, 0x0D, 0x70, 0x00, 0x00, 0x00, 0xBA, 0x02, 0x00, 0x00, 0x00, 0x83, 0x3D, 0x60, 0x00, 0x00, 0x00, 0x00, 0x74, 0x02, 0xFF, 0xC2, 0x39, 0xD1, 0x0F, 0x4D, 0xCA, 0x89, 0x48, 0x08, 0xB9, 0x0E, 0x00, 0x00, 0x00, 0xE8, 0x92, 0x98, 0xE0, 0xFF, 0xB0, 0x01, 0x48, 0x83, 0xC4, 0x28, 0xC3, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x44, 0x89, 0x61, 0x08, 0x44, 0x88, 0x61, 0x0C, 0x4C, 0x89, 0x61, 0x10, 0x44, 0x89, 0x25, 0x29, 0x00, 0x00, 0x00, 0xE9, 0x68, 0xF4, 0xFF, 0xFF, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }); + + // Use the value from our own address instead of the original one + InjectCode((void*)0x00000001403F65AF, { 0x48, 0x8D, 0x05, 0x4A, 0x18, 0xDA, 0x00, 0x8B, 0x1D, 0x00, 0x56 }); + + // Jump to another section by addding some code to replace the values (Jump 2) + InjectCode((void*)0x00000001403F6638, { 0xE9, 0x03, 0x55, 0xF9, 0xFF, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC }); + + DWORD StageCountProtect; + VirtualProtect((int32_t*)0x14038BBB0, 0x10, PAGE_EXECUTE_READWRITE, &StageCountProtect); + + int* ESM = (int*)0x000000014038BBB0; + + if (nEStageManagerEncore) + ESM[1] = nEStageManager; + else + ESM[0] = nEStageManager; + + ESM[2] = nEStageManagerEncore; + + printf("[Patches] Enhanced Stage Manager enabled\n"); + } + + return TRUE; +} + +PluginConfig::PluginConfigOption config[] = { + { PluginConfig::CONFIG_NUMERIC, new PluginConfig::PluginConfigNumericData{ L"enhanced_stage_manager", L"patches", CONFIG_FILE, L"Stages:", L"Number of stages to play.\n\n0 = maximum", 0, 0, INT_MAX } }, + { PluginConfig::CONFIG_BOOLEAN, new PluginConfig::PluginConfigBooleanData{ L"enhanced_stage_manager_encore", L"patches", CONFIG_FILE, L"Encore", L"Enable Encore stages.", false } }, +}; + +extern "C" __declspec(dllexport) LPCWSTR GetPluginName(void) +{ + return L"Enhanced Stages"; +} + +extern "C" __declspec(dllexport) LPCWSTR GetPluginDescription(void) +{ + return L"Allows you to play as many times in a row as you want.\n\nOriginal implementation by korenkonder."; +} + +extern "C" __declspec(dllexport) PluginConfig::PluginConfigArray GetPluginOptions(void) +{ + return PluginConfig::PluginConfigArray{ _countof(config), config }; +} diff --git a/source-code/source/plugins/EnhancedStageManager/framework.h b/source-code/source/plugins/EnhancedStageManager/framework.h new file mode 100644 index 0000000..07eea0e --- /dev/null +++ b/source-code/source/plugins/EnhancedStageManager/framework.h @@ -0,0 +1,28 @@ +#include +#include +#include + +void InjectCode(void* address, const std::vector data) +{ + const size_t byteCount = data.size() * sizeof(uint8_t); + + DWORD oldProtect; + VirtualProtect(address, byteCount, PAGE_EXECUTE_READWRITE, &oldProtect); + memcpy(address, data.data(), byteCount); + VirtualProtect(address, byteCount, oldProtect, nullptr); +} + +std::wstring ExePath() { + WCHAR buffer[MAX_PATH]; + GetModuleFileNameW(NULL, buffer, MAX_PATH); + return std::wstring(buffer); +} + +std::wstring DirPath() { + std::wstring exepath = ExePath(); + std::wstring::size_type pos = exepath.find_last_of(L"\\/"); + return exepath.substr(0, pos); +} + +std::wstring CONFIG_FILE_STRING = DirPath() + L"\\plugins\\EnhancedStageManager.ini"; +LPCWSTR CONFIG_FILE = CONFIG_FILE_STRING.c_str(); diff --git a/source-code/source/plugins/Launcher/Resources.it-IT.restext b/source-code/source/plugins/Launcher/Resources.it-IT.restext index a6a4bed..d5e1c63 100644 --- a/source-code/source/plugins/Launcher/Resources.it-IT.restext +++ b/source-code/source/plugins/Launcher/Resources.it-IT.restext @@ -98,21 +98,6 @@ Guest + Normal=Ospite + Normale NO_SCROLLING_SFX_NAME=Disabilita suono di scorrimento NO_SCROLLING_SFX_HINT=Disabilita l'effetto sonoro di scorrimento. -ENHANCED_STAGE_MANAGER_NAME=Numero di stage: -ENHANCED_STAGE_MANAGER_HINT=Imposta il numero di stage (Predefinito: 0). -ENHANCED_STAGE_MANAGER_ENCORE_NAME=Encore (bis) -ENHANCED_STAGE_MANAGER_ENCORE_HINT=Disabilita gli stage Encore. - -FORCE_MOUTH_NAME=Stile labiale: -FORCE_MOUTH_HINT=Imposta le animazioni della bocca. -FORCE_EXPRESSIONS_NAME=Stile espressioni: -FORCE_EXPRESSIONS_HINT=Imposta le espressioni facciali. -FORCE_LOOK_NAME=Stile sguardo: -FORCE_LOOK_HINT=Imposta lo sguardo. -NO_HAND_SCALING_NAME=Non ridimensionare le mani -NO_HAND_SCALING_HINT=Disabilita la scalatura dinamica delle mani. -DEFAULT_HAND_SIZE_NAME=Dimensione mani predefinita -DEFAULT_HAND_SIZE_HINT=Predefinita: -1\nPDA: 12200 SING_MISSED_NAME=Canta note mancate SING_MISSED_HINT=Canta le note mancate. diff --git a/source-code/source/plugins/Launcher/Resources.pt-BR.restext b/source-code/source/plugins/Launcher/Resources.pt-BR.restext index d2e8855..87c30d8 100644 --- a/source-code/source/plugins/Launcher/Resources.pt-BR.restext +++ b/source-code/source/plugins/Launcher/Resources.pt-BR.restext @@ -94,21 +94,6 @@ Guest + Normal=Hóspede + Normal NO_SCROLLING_SFX_NAME=Desativar Som de Navegação NO_SCROLLING_SFX_HINT=Desativa o som de navegação da lista de músicas. -ENHANCED_STAGE_MANAGER_NAME=Número de Estágios: -ENHANCED_STAGE_MANAGER_HINT=Configura o número de estágios (Padrão: 0). -ENHANCED_STAGE_MANAGER_ENCORE_NAME=Encore (Bis) -ENHANCED_STAGE_MANAGER_ENCORE_HINT=Habilita estágios Encore. - -FORCE_MOUTH_NAME=Estilo da Boca: -FORCE_MOUTH_HINT=Muda as animações da boca dos personagens. -FORCE_EXPRESSIONS_NAME=Estilo de Expressões: -FORCE_EXPRESSIONS_HINT=Muda as expressões dos personagens. -FORCE_LOOK_NAME=Estilo dos Olhos: -FORCE_LOOK_HINT=Muda as animações dos olhos dos personagens. -NO_HAND_SCALING_NAME=Sem Escala das Mãos -NO_HAND_SCALING_HINT=Desativa a escala de tamanho das mãos dos personagens. -DEFAULT_HAND_SIZE_NAME=Tamanho das Mãos Padrão -DEFAULT_HAND_SIZE_HINT=Padrão: -1\nPDA: 12200 SING_MISSED_NAME=Cantar Notas Perdidas SING_MISSED_HINT=Os vocais não vão parar ao perder notas. diff --git a/source-code/source/plugins/Launcher/Resources.restext b/source-code/source/plugins/Launcher/Resources.restext index 758718d..53f0883 100644 --- a/source-code/source/plugins/Launcher/Resources.restext +++ b/source-code/source/plugins/Launcher/Resources.restext @@ -88,21 +88,6 @@ QUICK_START_HINT=Skip one or more menus. NO_SCROLLING_SFX_NAME=Disable Scrolling SFX NO_SCROLLING_SFX_HINT=Disable the scrolling sound effect. -ENHANCED_STAGE_MANAGER_NAME=Number of Stages: -ENHANCED_STAGE_MANAGER_HINT=Set the number of stages (0 = default). -ENHANCED_STAGE_MANAGER_ENCORE_NAME=Encore -ENHANCED_STAGE_MANAGER_ENCORE_HINT=Enable encore stages. - -FORCE_MOUTH_NAME=Mouth Type: -FORCE_MOUTH_HINT=Change the mouth animations. -FORCE_EXPRESSIONS_NAME=Expression Type: -FORCE_EXPRESSIONS_HINT=Change the expressions. -FORCE_LOOK_NAME=Look Type: -FORCE_LOOK_HINT=Change the look animations. -NO_HAND_SCALING_NAME=No Hand Scaling -NO_HAND_SCALING_HINT=Disable scripted hand scaling. -DEFAULT_HAND_SIZE_NAME=Default Hand Size: -DEFAULT_HAND_SIZE_HINT=-1: default\n12200: PDA SING_MISSED_NAME=Sing Missed Notes SING_MISSED_HINT=Sing missed notes. diff --git a/source-code/source/plugins/Launcher/Resources.zh-Hans.restext b/source-code/source/plugins/Launcher/Resources.zh-Hans.restext index 0fa920b..04db749 100644 --- a/source-code/source/plugins/Launcher/Resources.zh-Hans.restext +++ b/source-code/source/plugins/Launcher/Resources.zh-Hans.restext @@ -84,21 +84,6 @@ Guest + Normal=访客模式+正常模式 NO_SCROLLING_SFX_NAME=停用滑动音效 NO_SCROLLING_SFX_HINT=停用在选歌界面的滑动音效 -ENHANCED_STAGE_MANAGER_NAME=游玩次数: -ENHANCED_STAGE_MANAGER_HINT=设置一次投币 (游戏) 最多可以游玩的次数 (0 = 默认) -ENHANCED_STAGE_MANAGER_ENCORE_NAME=启用 EncoreStage -ENHANCED_STAGE_MANAGER_ENCORE_HINT=启用 Encore Stage\n(在 EncoreStage 下所有难度的歌曲最低达成率均为 80%) - -FORCE_MOUTH_NAME=嘴部动作设定: -FORCE_MOUTH_HINT=调整模型的嘴部动作样式 -FORCE_EXPRESSIONS_NAME=表情设定: -FORCE_EXPRESSIONS_HINT=调整模型的表情样式 -FORCE_LOOK_NAME=外观设定: -FORCE_LOOK_HINT=调整外观样式 -NO_HAND_SCALING_NAME=停用手部缩放 -NO_HAND_SCALING_HINT=停用手部缩放 -DEFAULT_HAND_SIZE_NAME=默认手部大小: -DEFAULT_HAND_SIZE_HINT=默认值:-1\nPDA:12200 SING_MISSED_NAME=停用停止歌唱 SING_MISSED_HINT=停用当 Note 判定为 Miss 时,歌姬暂停歌唱的功能 diff --git a/source-code/source/plugins/Launcher/framework.h b/source-code/source/plugins/Launcher/framework.h index 1fcd4dd..f5fe855 100644 --- a/source-code/source/plugins/Launcher/framework.h +++ b/source-code/source/plugins/Launcher/framework.h @@ -251,11 +251,9 @@ ConfigOptionBase* optionsArray[] = { ConfigOptionBase* options2Array[] = { new OptionMetaSectionLabel(L"SECTION_PV_SELECTOR"), -#ifndef MINIMALIST - new DropdownOption(L"quick_start", PATCHES_SECTION, CONFIG_FILE, L"QUICK_START_NAME", L"QUICK_START_HINT", 1, std::vector({ L"Disabled", L"Guest", L"Guest + Normal" })), -#endif new BooleanOption(L"freeplay", PATCHES_SECTION, CONFIG_FILE, L"FREEPLAY_NAME", L"FREEPLAY_HINT", true, false), #ifndef MINIMALIST + new DropdownOption(L"quick_start", PATCHES_SECTION, CONFIG_FILE, L"QUICK_START_NAME", L"QUICK_START_HINT", 1, std::vector({ L"Disabled", L"Guest", L"Guest + Normal" })), new BooleanOption(L"no_scrolling_sfx", PATCHES_SECTION, CONFIG_FILE, L"NO_SCROLLING_SFX_NAME", L"NO_SCROLLING_SFX_HINT", false, false), new BooleanOption(L"unlock_pseudo", PATCHES_SECTION, CONFIG_FILE, L"UNLOCK_PSEUDO_NAME", L"UNLOCK_PSEUDO_HINT", false, false), #endif @@ -263,11 +261,6 @@ ConfigOptionBase* options2Array[] = { new OptionMetaSpacer(8), new OptionMetaSectionLabel(L"SECTION_ESM"), - new NumericOption(L"Enhanced_Stage_Manager", PATCHES_SECTION, CONFIG_FILE, L"ENHANCED_STAGE_MANAGER_NAME", L"ENHANCED_STAGE_MANAGER_HINT", 0, 0, INT_MAX), - new BooleanOption(L"Enhanced_Stage_Manager_Encore", PATCHES_SECTION, CONFIG_FILE, L"ENHANCED_STAGE_MANAGER_ENCORE_NAME", L"ENHANCED_STAGE_MANAGER_ENCORE_HINT", true, false), -#ifndef MINIMALIST - new BooleanOption(L"sing_missed", PATCHES_SECTION, CONFIG_FILE, L"SING_MISSED_NAME", L"SING_MISSED_HINT", false, false), -#endif new BooleanOption(L"autopause", KEYCONFIG_SECTION, KEYCONFIG_FILE, L"AUTOPAUSE_NAME", L"AUTOPAUSE_HINT", true, true), new OptionMetaSeparator(), new OptionMetaSpacer(8), @@ -290,19 +283,6 @@ ConfigOptionBase* options2Array[] = { new BooleanOption(L"card", PATCHES_SECTION, CONFIG_FILE, L"CARD_NAME", L"CARD_HINT", false, false), #endif new BooleanOption(L"dwgui_scaling", PATCHES_SECTION, CONFIG_FILE, L"DWGUI_SCALING_NAME", L"DWGUI_SCALING_HINT", false, false), -#ifndef MINIMALIST - new OptionMetaSeparator(), - new OptionMetaSpacer(8), - - new OptionMetaSectionLabel(L"SECTION_PV_PATCHES"), - new DropdownOption(L"force_mouth", PATCHES_SECTION, CONFIG_FILE, L"FORCE_MOUTH_NAME", L"FORCE_MOUTH_HINT", 0, std::vector({ L"Default", L"Force PDA", L"Force FT" })), - new DropdownOption(L"force_expressions", PATCHES_SECTION, CONFIG_FILE, L"FORCE_EXPRESSIONS_NAME", L"FORCE_EXPRESSIONS_HINT", 0, std::vector({ L"Default", L"Force PDA", L"Force FT" })), - new DropdownOption(L"force_look", PATCHES_SECTION, CONFIG_FILE, L"FORCE_LOOK_NAME", L"FORCE_LOOK_HINT", 0, std::vector({ L"Default", L"Force PDA", L"Force FT" })), - new BooleanOption(L"no_hand_scaling", PATCHES_SECTION, CONFIG_FILE, L"NO_HAND_SCALING_NAME", L"NO_HAND_SCALING_HINT", false, false), - new NumericOption(L"default_hand_size", PATCHES_SECTION, CONFIG_FILE, L"DEFAULT_HAND_SIZE_NAME", L"DEFAULT_HAND_SIZE_HINT", -1, -1, INT_MAX), - new OptionMetaSeparator(), - new OptionMetaSpacer(8), -#endif }; ConfigOptionBase* playerdataArray[] = {