19 Commits
Author SHA1 Message Date
nastys 1c026e2661 Update repo URL 2022-01-27 14:00:28 +01:00
nastys bef5d481a5 Launcher hotfix 2021-11-10 22:47:21 +01:00
nastys ea159ed465 Update mdata SFV 2021-10-27 18:14:45 +02:00
nastys 8b5b514368 2.6.5a: [DivaMovie] Change "hardware decoding" to "hybrid decoding" to avoid confusion 2021-10-08 12:34:17 +02:00
nastys 66db5deb2b 2.6.5a: Fix PlayerData, auto-disable DivaMovie if DXVA-HW is available (unless forced - fixes random black backgrounds) 2021-10-07 23:10:40 +02:00
nastys e8c2ac672a 2.6.5a: DivaMovie enabled by default again, but warns the user if it should be disabled 2021-10-07 19:04:48 +02:00
nastys 7df98ea648 2.6.5: macOS and Linux fixes, fix refl/refr patches 2021-10-07 16:31:11 +02:00
nastys 162cc52c6b 2.6.4: forgot to move termination byte (oops) 2021-09-29 19:29:03 +02:00
nastys c2343f79f2 2.6.4: PD Loader version text fix 2021-09-29 19:24:07 +02:00
nastys ea968b1762 2.6.4: replace refl/refr default option with 512x256 and restore uint type 2021-09-29 19:13:21 +02:00
nastys 4149a3c8e9 2.6.3: fix reflect/refract data type pt3 2021-09-29 19:05:08 +02:00
nastys d8693781ba 2.6.3: fix reflect/refract data type pt2 2021-09-29 19:03:57 +02:00
nastys 49e2b03159 2.6.2: fix reflect/refract data type 2021-09-29 19:01:44 +02:00
nastys bc925fd514 2.6.2: maximum hand size 100X, pv customization toggle, fix typo in Credits, option for disabling custom refract/refrect res, version in-game 2021-09-29 18:13:11 +02:00
nastys b511bf64c3 2.6b: fix display resolution combobox 2021-09-23 22:13:40 +02:00
nastys db159fde81 2.6a: bug fixes 2021-09-23 00:28:00 +02:00
nastys 4ebc4b3f85 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 2021-09-20 22:12:41 +02:00
nastys f93dab0b9a (2.5.3) Fix hand size 2021-09-04 23:18:23 +02:00
nastys eb17a30a06 (2.5.2) Fix manual Turing GPU; work around hand size upgrade error 2021-09-04 20:34:52 +02:00
34 changed files with 9613 additions and 25965 deletions
+63 -63
View File
@@ -1,63 +1,63 @@
###############################################################################
# Set default behavior to automatically normalize line endings.
###############################################################################
* text=auto
###############################################################################
# Set default behavior for command prompt diff.
#
# This is need for earlier builds of msysgit that does not have it on by
# default for csharp files.
# Note: This is only used by command line
###############################################################################
#*.cs diff=csharp
###############################################################################
# Set the merge driver for project and solution files
#
# Merging from the command prompt will add diff markers to the files if there
# are conflicts (Merging from VS is not affected by the settings below, in VS
# the diff markers are never inserted). Diff markers may cause the following
# file extensions to fail to load in VS. An alternative would be to treat
# these files as binary and thus will always conflict and require user
# intervention with every merge. To do so, just uncomment the entries below
###############################################################################
#*.sln merge=binary
#*.csproj merge=binary
#*.vbproj merge=binary
#*.vcxproj merge=binary
#*.vcproj merge=binary
#*.dbproj merge=binary
#*.fsproj merge=binary
#*.lsproj merge=binary
#*.wixproj merge=binary
#*.modelproj merge=binary
#*.sqlproj merge=binary
#*.wwaproj merge=binary
###############################################################################
# behavior for image files
#
# image files are treated as binary by default.
###############################################################################
#*.jpg binary
#*.png binary
#*.gif binary
###############################################################################
# diff behavior for common document formats
#
# Convert binary document formats to text before diffing them. This feature
# is only available from the command line. Turn it on by uncommenting the
# entries below.
###############################################################################
#*.doc diff=astextplain
#*.DOC diff=astextplain
#*.docx diff=astextplain
#*.DOCX diff=astextplain
#*.dot diff=astextplain
#*.DOT diff=astextplain
#*.pdf diff=astextplain
#*.PDF diff=astextplain
#*.rtf diff=astextplain
#*.RTF diff=astextplain
###############################################################################
# Set default behavior to automatically normalize line endings.
###############################################################################
* binary
###############################################################################
# Set default behavior for command prompt diff.
#
# This is need for earlier builds of msysgit that does not have it on by
# default for csharp files.
# Note: This is only used by command line
###############################################################################
#*.cs diff=csharp
###############################################################################
# Set the merge driver for project and solution files
#
# Merging from the command prompt will add diff markers to the files if there
# are conflicts (Merging from VS is not affected by the settings below, in VS
# the diff markers are never inserted). Diff markers may cause the following
# file extensions to fail to load in VS. An alternative would be to treat
# these files as binary and thus will always conflict and require user
# intervention with every merge. To do so, just uncomment the entries below
###############################################################################
#*.sln merge=binary
#*.csproj merge=binary
#*.vbproj merge=binary
#*.vcxproj merge=binary
#*.vcproj merge=binary
#*.dbproj merge=binary
#*.fsproj merge=binary
#*.lsproj merge=binary
#*.wixproj merge=binary
#*.modelproj merge=binary
#*.sqlproj merge=binary
#*.wwaproj merge=binary
###############################################################################
# behavior for image files
#
# image files are treated as binary by default.
###############################################################################
#*.jpg binary
#*.png binary
#*.gif binary
###############################################################################
# diff behavior for common document formats
#
# Convert binary document formats to text before diffing them. This feature
# is only available from the command line. Turn it on by uncommenting the
# entries below.
###############################################################################
#*.doc diff=astextplain
#*.DOC diff=astextplain
#*.docx diff=astextplain
#*.DOCX diff=astextplain
#*.dot diff=astextplain
#*.DOT diff=astextplain
#*.pdf diff=astextplain
#*.PDF diff=astextplain
#*.rtf diff=astextplain
#*.RTF diff=astextplain
+4 -1
View File
@@ -1,3 +1,6 @@
._*
.DS_Store
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
@@ -341,4 +344,4 @@ healthchecksdb
# Exclude data folder
!data/*
!data/debug/*
!data/debug/*
+2 -2
View File
@@ -15000,8 +15000,8 @@ source code}{}}}\rtlch\dbch\af8\hich\af5 \ltrch\fs22\lang16\ulnone\ulc0\b0\loch\
\par \pard\plain \s0\dbch\af6\langfe1081\dbch\af7\afs24\alang1081\ql\nowidctlpar\hyphpar0\ltrpar\cf0\loch\f3\fs24\lang1040\kerning1\sl276\slmult1\ql\sb0\sa200{\rtlch\dbch\af8\hich\af5 \ltrch\fs22\lang16\ulnone\ulc0\b0\loch\f5\loch
For information on getting and installing the latest release,}
\par \pard\plain \s0\dbch\af6\langfe1081\dbch\af7\afs24\alang1081\ql\nowidctlpar\hyphpar0\ltrpar\cf0\loch\f3\fs24\lang1040\kerning1\sl276\slmult1\ql\sb0\sa200{\rtlch\dbch\af8\hich\af5 \ltrch\fs22\lang16\ulnone\ulc0\b0\loch\f5\loch
please read the wiki at }{{\field{\*\fldinst HYPERLINK "https://notabug.org/PDModdingCommunity/PD-Loader/wiki" }{\fldrslt {\rtlch\dbch\af8\hich\af5 \ltrch\langfe255\cf9\lang255\ul\ulc0\fs22\lang16\ulnone\ulc0\b0\loch\f5\loch
https://notabug.org/PDModdingCommunity/PD-Loader/wiki}}}}
please read the wiki at }{{\field{\*\fldinst HYPERLINK "https://github.com/PDModdingCommunity/PD-Loader/wiki" }{\fldrslt {\rtlch\dbch\af8\hich\af5 \ltrch\langfe255\cf9\lang255\ul\ulc0\fs22\lang16\ulnone\ulc0\b0\loch\f5\loch
https://github.com/PDModdingCommunity/PD-Loader/wiki}}}}
\par \pard\plain \s0\dbch\af6\langfe1081\dbch\af7\afs24\alang1081\ql\nowidctlpar\hyphpar0\ltrpar\cf0\loch\f3\fs24\lang1040\kerning1\sl276\slmult1\ql\sb0\sa200{\rtlch\dbch\af8\hich\af5 \ltrch\fs22\lang16\ulnone\ulc0\b0\loch\f5\loch
If you've already read it, pay more attention and you'll find the right link.}
\par \pard\plain \s0\dbch\af6\langfe1081\dbch\af7\afs24\alang1081\ql\nowidctlpar\hyphpar0\ltrpar\cf0\loch\f3\fs24\lang1040\kerning1\sl276\slmult1\ql\sb0\sa200\rtlch\dbch\af8\hich\af5 \ltrch\fs22\lang16\ulnone\ulc0\b0\loch\f5\loch
+1 -1
View File
@@ -3,7 +3,7 @@ If you just wanted to play the game, you downloaded the wrong thing.
Do not click the download button next to the git URL, that's for the source code.
For information on getting and installing the latest release,
please read the wiki at https://notabug.org/nastys/PD-Loader/wiki
please read the wiki at https://github.com/nastys/PD-Loader/wiki
If you've already read it, pay more attention and you'll find the right link.
You should also read the wiki if you have any issues, before asking questions.
@@ -0,0 +1,2 @@
[InternetShortcut]
URL=https://dotnet.microsoft.com/download/dotnet-framework/net48
+2
View File
@@ -0,0 +1,2 @@
[InternetShortcut]
URL=https://www.quicksfv.org/qsfv236x64.exe
@@ -0,0 +1,2 @@
[InternetShortcut]
URL=https://aka.ms/vs/16/release/vc_redist.x64.exe
+1 -1
View File
@@ -2,5 +2,5 @@
Prop3=19,11
[InternetShortcut]
IDList=
URL=https://notabug.org/PDModdingCommunity/PD-Loader/wiki
URL=https://github.com/PDModdingCommunity/PD-Loader/wiki
HotKey=0
Binary file not shown.
+158 -154
View File
@@ -1,154 +1,158 @@
#########################################
# /!\ WARNING: DO NOT EDIT WITH NOTEPAD!#
#########################################
[Global]
# Load plugins including below options
Enable=1
[GPU]
# Force GPU model -- -1=auto, 0=Kepler, 1=Maxwell, 2=Turing, 3=Ampere
Model=-1
[Launcher]
# Forces the launcher to be skipped, you can use the --launch parameter instead of this.
Skip=0
# Disables unsupported GPU warning dialogs.
No_GPU_Dialog=0
# Sets the dark colour scheme in the launcher.
Dark_Launcher=0
# Enables acrylic blur in the launcher on Windows 10 20H2 or later.
Acrylic_Blur=0
#Ignores some OpenGL-related errors. Don't use both patches at the same time unless you're know what you're doing
OpenGL_Patch_A=0
#Ignores some OpenGL-related errors. Don't use both patches at the same time unless you're know what you're doing
OpenGL_Patch_B=0
# Command line arguments
Command_Line=
# Launches divahook.bat intead of diva.exe.
Use_divahook_bat=0
[Patches]
#Disable movies (enable this if the game hangs when loading certain PVs)
No_Movies=0
#Enable custom MP4 adv movies (experimental)
MP4_Movies=1
#Enable or disable mouse cursor
Cursor=1
#Use 2 channels instead of 4 (when not using DivaSound)
Stereo=1
#Skip one or more menus -- 0=disabled, 1=guest, 2=guest+normal
Quick_Start=1
#Disable the scrolling sound effect
No_Scrolling_SFX=0
#Enhanced Stage Manager (sets a custom number of stages; "stage_manager" should be disabled in "components.ini")
#Number of stages (0 = disabled)
Enhanced_Stage_Manager=0
#Use encore stages or not
Enhanced_Stage_Manager_Encore=1
#Change the mouth animations -- 0=default, 1=force PDA, 2=force FT
Force_Mouth=0
#Change the expressions -- 0=default, 1=force PDA, 2=force FT
Force_Expressions=0
#Change the look animations -- 0=default, 1=force PDA, 2=force FT
Force_Look=0
#Disable hand scaling
No_Hand_Scaling=0
#Default hand size -- -1=default, 12200=PDA
Default_Hand_Size=-1
#Sing missed notes
Sing_Missed=0
#Hide the volume and SE control buttons
Hide_Volume=0
#Remove the photo controls during PV playback
No_PV_UI=0
#Hide the watermark that's usually shown in PV viewing mode
Hide_PV_Watermark=0
#Set the card reader and network status icons -- 0=default, 1=hidden, 2=error, 3=OK, 4=partial OK
Status_Icons=0
#Disable showing lyrics
No_Lyrics=0
#Disable the error banner
No_Error=1
#Hide "CREDIT(S)"/"FREE PLAY"
Hide_Freeplay=0
#Show "FREE PLAY" instead of "CREDIT(S)" and don't require credits
Freeplay=1
#Show "PD Loader" instead of "FREE PLAY"
PDLoaderText=1
#Freeze the timer
No_Timer=1
#Disable the timer sprite
No_Timer_Sprite=1
#Unlock PSEUDO modules (incomplete, will default to Miku)
Unlock_Pseudo=0
#Enable the card menu (incomplete, it doesn't bypass the card prompt)
Card=0
#Allow using a real arcade slider attached to COM11 (or PS4 official FT controller)
Hardware_Slider=0
#Enable custom patches
Custom_Patches=1
#Prevent data deletion
Prevent_Data_Deletion=0
[Graphics]
# Lag Compensation
Lag_Compensation = 0
# Set to -1 to unlock the frame rate.
FPS.Limit=60
# Reduces FPS Limiter CPU usage
# (may have less consistent performance)
FPS.Limit.LightMode=1
# Enable debug warnings for lightweight limiter
FPS.Limit.Verbose=0
# Temporal Anti-Aliasing
TAA=1
# Morphological Anti-Aliasing
MLAA=1
# MAG Filter -- 0=default (bilinear), 1=nearest-neighbour, 2=sharpen, 3=cone (smooth)
MAG=0
# Depth of Field
DOF=1
# Reflections
Reflections=1
# Shadows
Shadows=1
# Transparent Meshes
Punchthrough=1
# Glare
Glare=1
# Shader
Shader=1
# Toon shader (press F9 to toggle) -- 0=default, 1=force on, 2=force off
NPR1=0
# Disable all 3D passes. WARNING: The extended data will be deleted unless Prevent Data Deletion is enabled.
2D=0
# FrameRateManager motion rate (fps)
FRM.Motion.Rate=400
[Resolution]
# 0 = Windowed, 1 = Fast, 2 = Exclusive, 3 = Safe
# For same as screen res: -1x-1
Display=1
Width=-1
Height=-1
# Fullscreen only options
BitDepth=32
RefreshRate=60
# Set a custom internal render resolution
# Same as window: -1x-1
# HD : 1280x720
# FHD : 1920x1080
# WQHD : 2560x1440
# 4K UHD: 3840x2160
# 5K UHD: 5120x2880
# 8K UHD: 7680x4320
r.Enable=0
r.Width=1920
r.Height=1080
[plugins]
DivaWig.dva=0
DSCRemote.dva=0
custom_freeplay_text_example.p=0
#########################################
# /!\ WARNING: DO NOT EDIT WITH NOTEPAD!#
#########################################
[Global]
# Load plugins including below options
Enable=1
[GPU]
# Force GPU model -- -1=auto, 0=Kepler, 1=Maxwell/Pascal, 2=Turing, 3=Ampere
Model=-1
[Launcher]
# Forces the launcher to be skipped, you can use the --launch parameter instead of this.
Skip=0
# Disables unsupported GPU warning dialogs.
No_GPU_Dialog=0
# Sets the dark colour scheme in the launcher.
Dark_Launcher=0
# Enables acrylic blur in the launcher on Windows 10 20H2 or later.
Acrylic_Blur=0
#Ignores some OpenGL-related errors. Don't use both patches at the same time unless you're know what you're doing
OpenGL_Patch_A=0
#Ignores some OpenGL-related errors. Don't use both patches at the same time unless you're know what you're doing
OpenGL_Patch_B=0
# Command line arguments
Command_Line=
# Launches divahook.bat/start.bat intead of diva.exe.
Use_divahook_bat=0
[Patches]
#Disable movies (enable this if the game hangs when loading certain PVs)
No_Movies=0
#Enable custom MP4 adv movies (experimental)
MP4_Movies=1
#Enable or disable mouse cursor
Cursor=1
#Use 2 channels instead of 4 (when not using DivaSound)
Stereo=1
#Skip one or more menus -- 0=disabled, 1=guest, 2=guest+normal
Quick_Start=0
#Disable the scrolling sound effect
No_Scrolling_SFX=0
#Enhanced Stage Manager (sets a custom number of stages; "stage_manager" should be disabled in "components.ini")
#Number of stages (0 = disabled)
Enhanced_Stage_Manager=0
#Use encore stages or not
Enhanced_Stage_Manager_Encore=1
#Enable PV Customization below
Enable_PV_Customization=0
#Change the mouth animations -- 0=default, 1=force PDA, 2=force FT
Force_Mouth=0
#Change the expressions -- 0=default, 1=force PDA, 2=force FT
Force_Expressions=0
#Change the look animations -- 0=default, 1=force PDA, 2=force FT
Force_Look=0
#Disable hand scaling
No_Hand_Scaling=0
#Default hand size -- 0-10000=default, 12200=PDA, 1000000=maximum
Default_Hand_Size_uint=0
#Sing missed notes
Sing_Missed=0
#Hide the volume and SE control buttons
Hide_Volume=0
#Remove the photo controls during PV playback
No_PV_UI=0
#Hide the watermark that's usually shown in PV viewing mode
Hide_PV_Watermark=0
#Set the card reader and network status icons -- 0=default, 1=hidden, 2=error, 3=OK, 4=partial OK
Status_Icons=0
#Disable showing lyrics
No_Lyrics=0
#Disable the error banner
No_Error=1
#Hide "CREDIT(S)"/"FREE PLAY"
Hide_Freeplay=0
#Show "FREE PLAY" instead of "CREDIT(S)" and don't require credits
Freeplay=1
#Show "PD Loader" instead of "FREE PLAY"
PDLoaderText=1
#Freeze the timer
No_Timer=1
#Disable the timer sprite
No_Timer_Sprite=1
#Unlock PSEUDO modules (incomplete, will default to Miku)
Unlock_Pseudo=0
#Enable the card menu (incomplete, it doesn't bypass the card prompt)
Card=0
#Allow using a real arcade slider attached to COM11 (or PS4 official FT controller)
Hardware_Slider=0
#Enable custom patches
Custom_Patches=1
#Prevent data deletion
Prevent_Data_Deletion=0
[Graphics]
# Lag Compensation
Lag_Compensation = 0
# Set to -1 to unlock the frame rate.
FPS.Limit=60
# Reduces FPS Limiter CPU usage
# (may have less consistent performance)
FPS.Limit.LightMode=1
# Enable debug warnings for lightweight limiter
FPS.Limit.Verbose=0
# Temporal Anti-Aliasing
TAA=1
# Morphological Anti-Aliasing
MLAA=1
# MAG Filter -- 0=default (bilinear), 1=nearest-neighbour, 2=sharpen, 3=cone (smooth)
MAG=0
# Depth of Field
DOF=1
# Reflections
Reflections=1
# Gamma -- 0 or 100=default, 125=console-like
Gamma=100
# Shadows
Shadows=1
# Transparent Meshes
Punchthrough=1
# Glare
Glare=1
# Shader
Shader=1
# Toon shader (press F9 to toggle) -- 0=default, 1=force on, 2=force off
NPR1=0
# Disable all 3D passes. WARNING: The extended data will be deleted unless Prevent Data Deletion is enabled.
2D=0
# FrameRateManager motion rate (fps)
FRM.Motion.Rate=400
[Resolution]
# 0 = Windowed, 1 = Fast, 2 = Exclusive, 3 = Safe
# For same as screen res: -1x-1
Display=1
Width=-1
Height=-1
# Fullscreen only options
BitDepth=32
RefreshRate=60
# Set a custom internal render resolution
# Same as window: -1x-1
# HD : 1280x720
# FHD : 1920x1080
# WQHD : 2560x1440
# 4K UHD: 3840x2160
# 5K UHD: 5120x2880
# 8K UHD: 7680x4320
r.Enable=0
r.Width=1920
r.Height=1080
[plugins]
DivaWig.dva=0
DSCRemote.dva=0
custom_freeplay_text_example.p=0
@@ -24,7 +24,9 @@ VID = 046D
PID = C216
# Rumble (Xinput)
rumble =true
rumble = true
xinput_rumble_intensity_left = 8000
xinput_rumble_intensity_right = 4000
# Pause when focus is lost
autopause =true
@@ -59,6 +61,7 @@ MENU_L = Left, Up, Ds4_L1, XINPUT_LS, Ds4_DPad_Left, Ds4_DPad_Up, XINPUT_LEFT, X
MENU_R = Right, Down, Ds4_R1, XINPUT_RS, Ds4_DPad_Right, Ds4_DPad_Down, XINPUT_RIGHT, XINPUT_DOWN, E, O, Ds4_L_Stick_Right, XINPUT_LRIGHT, Ds4_L_Stick_Down, XINPUT_LDOWN, Ds4_R_Stick_Right, XINPUT_RRIGHT, Ds4_R_Stick_Down, XINPUT_RDOWN
MENU_CIRCLE = Spacebar
TOON = F9
COIN = F10
# Touch Slider:
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -36,7 +36,7 @@ namespace GPUModel
{
// detected model can be overridden -- 0: Kepler, 1: Maxwell, 2: Turing, 3: Ampere
int nGPUModel = GetPrivateProfileIntW(L"gpu", L"model", -1, CONFIG_FILE);
if (nGPUModel >= 0 && nGPUModel <= 2)
if (nGPUModel >= 0 && nGPUModel <= 3)
{
std::string arch;
switch (nGPUModel)
File diff suppressed because it is too large Load Diff
@@ -1,98 +1,98 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<ProjectGuid>{1994C586-F73B-4EF2-BA3E-2A0FC3034B1A}</ProjectGuid>
<RootNamespace>DivaMovie</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<TargetExt>.dva</TargetExt>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<TargetExt>.dva</TargetExt>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>..\..\..\dependencies\detours\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalOptions>-d2FH4- %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<AdditionalLibraryDirectories>..\..\..\dependencies\detours\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>detours.lib;evr.lib;mfplat.lib;mfuuid.lib;strmiids.lib;syelog.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalOptions>-d2:-FH4- %(AdditionalOptions)</AdditionalOptions>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>..\..\..\dependencies\detours\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<AdditionalOptions>-d2FH4- %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>detours.lib;evr.lib;mfplat.lib;mfuuid.lib;syelog.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>..\..\..\dependencies\detours\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalOptions>-d2:-FH4- %(AdditionalOptions)</AdditionalOptions>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="dllmain.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="framework.h" />
<ClInclude Include="PluginConfigApi.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<ProjectGuid>{1994C586-F73B-4EF2-BA3E-2A0FC3034B1A}</ProjectGuid>
<RootNamespace>DivaMovie</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<TargetExt>.dva</TargetExt>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<TargetExt>.dva</TargetExt>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>..\..\..\dependencies\simpleini;..\..\..\dependencies\detours\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalOptions>-d2FH4- %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<AdditionalLibraryDirectories>..\..\..\dependencies\detours\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>detours.lib;evr.lib;mfplat.lib;mfuuid.lib;strmiids.lib;syelog.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalOptions>-d2:-FH4- %(AdditionalOptions)</AdditionalOptions>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>..\..\..\dependencies\simpleini;..\..\..\dependencies\detours\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<AdditionalOptions>-d2FH4- %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>detours.lib;evr.lib;mfplat.lib;mfuuid.lib;syelog.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>..\..\..\dependencies\detours\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalOptions>-d2:-FH4- %(AdditionalOptions)</AdditionalOptions>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="dllmain.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="framework.h" />
<ClInclude Include="PluginConfigApi.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
+231 -212
View File
@@ -1,213 +1,232 @@
#include "framework.h"
#include "PluginConfigApi.h"
#include <evr.h>
#include <d3d9.h>
#include <dvdmedia.h>
#include <dxva2api.h>
#include <mfapi.h>
#include <mferror.h>
#include <mftransform.h>
bool forceSoftwareDecoding = false, debug = false;
IDirect3DDeviceManager9* deviceManager;
IMFTransform* mfTransform;
int width;
int height;
unsigned long samplesize;
unsigned long subtype;
IMFSample* dstSample;
IDirect3DSurface9* dstSurface;
IMFSample* srcSample;
IMFMediaBuffer* srcBuffer;
HRESULT initialize(IMFTransform* transform)
{
HRESULT result = S_OK;
IMFMediaType* type = NULL;
IMFMediaBuffer* buffer = NULL;
HANDLE hDevice = NULL;
IDirectXVideoAccelerationService* service = NULL;
AM_MEDIA_TYPE* format = NULL;
VIDEOINFOHEADER2* header = NULL;
// Release what we already had beforehand
SAFE_RELEASE(mfTransform);
SAFE_RELEASE(dstSample);
SAFE_RELEASE(dstSurface);
SAFE_RELEASE(srcSample);
SAFE_RELEASE(srcBuffer);
ASSERT(transform->GetOutputCurrentType(0, &type));
ASSERT(type->GetRepresentation(AM_MEDIA_TYPE_REPRESENTATION, (void**)&format));
header = (VIDEOINFOHEADER2*)format->pbFormat;
width = header->bmiHeader.biWidth;
height = header->bmiHeader.biHeight;
samplesize = format->lSampleSize;
subtype = format->subtype.Data1;
// System memory sample
ASSERT(MFCreateSample(&srcSample));
ASSERT(MFCreateMemoryBuffer(format->lSampleSize, &buffer));
ASSERT(srcSample->AddBuffer(buffer));
ASSERT(buffer->QueryInterface(&srcBuffer));
// Video memory sample
ASSERT(deviceManager->OpenDeviceHandle(&hDevice));
ASSERT(deviceManager->GetVideoService(hDevice, __uuidof(IDirectXVideoAccelerationService), (void**)& service));
ASSERT(service->CreateSurface(width, height, 0, (D3DFORMAT)subtype, D3DPOOL_DEFAULT, 0, DXVA2_VideoSoftwareRenderTarget, &dstSurface, NULL));
ASSERT(MFCreateVideoSampleFromSurface(dstSurface, &dstSample));
ASSERT(deviceManager->CloseDeviceHandle(hDevice));
mfTransform = transform;
mfTransform->AddRef();
end:
if (format)
type->FreeRepresentation(AM_MEDIA_TYPE_REPRESENTATION, format);
SAFE_RELEASE(service);
SAFE_RELEASE(buffer);
SAFE_RELEASE(type);
return result;
}
VTABLE_HOOK(HRESULT, IMFTransform, ProcessOutput, DWORD dwFlags, DWORD cOutputBufferCount,
MFT_OUTPUT_DATA_BUFFER* pOutputSamples, DWORD* pdwStatus)
{
if (pOutputSamples->pSample != NULL || deviceManager == NULL || cOutputBufferCount != 1)
return originalProcessOutput(This, dwFlags, cOutputBufferCount, pOutputSamples, pdwStatus);
HRESULT result = S_OK;
if (mfTransform != This)
ASSERT(initialize(This));
pOutputSamples->pSample = srcSample;
pOutputSamples->pSample->AddRef();
ASSERT(originalProcessOutput(This, dwFlags, cOutputBufferCount, pOutputSamples, pdwStatus));
D3DLOCKED_RECT rect;
BYTE* buf;
ASSERT(srcBuffer->Lock(&buf, NULL, NULL));
ASSERT(dstSurface->LockRect(&rect, NULL, NULL));
ASSERT(MFCopyImage((BYTE*)rect.pBits, rect.Pitch, buf, samplesize, samplesize, 1));
ASSERT(dstSurface->UnlockRect());
ASSERT(srcBuffer->Unlock());
LONGLONG duration;
ASSERT(srcSample->GetSampleDuration(&duration));
ASSERT(dstSample->SetSampleDuration(duration));
LONGLONG time;
ASSERT(srcSample->GetSampleTime(&time));
ASSERT(dstSample->SetSampleTime(time));
DWORD flags;
ASSERT(srcSample->GetSampleFlags(&flags));
ASSERT(dstSample->SetSampleFlags(flags));
pOutputSamples->pSample->Release();
pOutputSamples->pSample = dstSample;
pOutputSamples->pSample->AddRef();
end:
return result;
}
VTABLE_HOOK(HRESULT, IMFTransform, ProcessMessage, MFT_MESSAGE_TYPE eMessage, ULONG_PTR ulParam)
{
if (forceSoftwareDecoding)
{
if (eMessage == MFT_MESSAGE_SET_D3D_MANAGER) {
PRINT("[DivaMovie] Force Software Decoding enabled\n");
INSTALL_VTABLE_HOOK(This, ProcessOutput, 25);
return S_OK;
}
return originalProcessMessage(This, eMessage, ulParam);
}
else
{
HRESULT result = originalProcessMessage(This, eMessage, ulParam);
if (eMessage == MFT_MESSAGE_SET_D3D_MANAGER && result == MF_E_UNSUPPORTED_D3D_TYPE)
{
PRINT("[DivaMovie] This system does not support DXVA hardware decoding\n");
result = originalProcessMessage(This, eMessage, NULL);
if (SUCCEEDED(result))
INSTALL_VTABLE_HOOK(This, ProcessOutput, 25);
}
return result;
}
}
HOOK(void*, IMFTransformInitializer, 0x140420B90, void* a1, void* a2, IMFTransform** transform)
{
void* result = originalIMFTransformInitializer(a1, a2, transform);
INSTALL_VTABLE_HOOK(*transform, ProcessMessage, 23);
return result;
}
HOOK(HRESULT, DXVA2CreateDirect3DDeviceManager, PROC_ADDRESS("dxva2.dll", "DXVA2CreateDirect3DDeviceManager9"),
UINT* pResetToken, IDirect3DDeviceManager9** ppDeviceManager)
{
HRESULT result = originalDXVA2CreateDirect3DDeviceManager(pResetToken, ppDeviceManager);
if (FAILED(result))
return result;
if (deviceManager)
deviceManager->Release();
deviceManager = *ppDeviceManager;
deviceManager->AddRef();
return result;
}
void loadConfig() {
forceSoftwareDecoding = GetPrivateProfileIntW(L"general", L"force_software_decoding", 0, CONFIG_FILE) > 0 ? true : false;
debug = GetPrivateProfileIntW(L"general", L"debug", 0, CONFIG_FILE) > 0 ? true : false;
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
if (ul_reason_for_call == DLL_PROCESS_ATTACH)
{
loadConfig();
INSTALL_HOOK(DXVA2CreateDirect3DDeviceManager);
INSTALL_HOOK(IMFTransformInitializer);
}
return TRUE;
}
PluginConfig::PluginConfigOption config[] = {
{ PluginConfig::CONFIG_BOOLEAN, new PluginConfig::PluginConfigBooleanData{ L"force_software_decoding", L"general", CONFIG_FILE, L"Force Software Decoding", L"Use software decoding even on systems that support DXVA hardware decoding.", false } },
{ PluginConfig::CONFIG_BOOLEAN, new PluginConfig::PluginConfigBooleanData{ L"debug", L"general", CONFIG_FILE, L"Debug", L"Enable PRINT (possibly at the cost of performance).", false } },
};
extern "C" __declspec(dllexport) LPCWSTR GetPluginName(void)
{
return L"DivaMovie";
}
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.";
}
extern "C" __declspec(dllexport) PluginConfig::PluginConfigArray GetPluginOptions(void)
{
return PluginConfig::PluginConfigArray{ _countof(config), config };
#include "framework.h"
#include "PluginConfigApi.h"
#include <evr.h>
#include <d3d9.h>
#include <dvdmedia.h>
#include <dxva2api.h>
#include <mfapi.h>
#include <mferror.h>
#include <mftransform.h>
#include <SimpleIni.h>
bool forceSoftwareDecoding = false, forceHybridDecoding = false, debug = false;
IDirect3DDeviceManager9* deviceManager;
IMFTransform* mfTransform;
int width;
int height;
unsigned long samplesize;
unsigned long subtype;
IMFSample* dstSample;
IDirect3DSurface9* dstSurface;
IMFSample* srcSample;
IMFMediaBuffer* srcBuffer;
HRESULT initialize(IMFTransform* transform)
{
HRESULT result = S_OK;
IMFMediaType* type = NULL;
IMFMediaBuffer* buffer = NULL;
HANDLE hDevice = NULL;
IDirectXVideoAccelerationService* service = NULL;
AM_MEDIA_TYPE* format = NULL;
VIDEOINFOHEADER2* header = NULL;
// Release what we already had beforehand
SAFE_RELEASE(mfTransform);
SAFE_RELEASE(dstSample);
SAFE_RELEASE(dstSurface);
SAFE_RELEASE(srcSample);
SAFE_RELEASE(srcBuffer);
ASSERT(transform->GetOutputCurrentType(0, &type));
ASSERT(type->GetRepresentation(AM_MEDIA_TYPE_REPRESENTATION, (void**)&format));
header = (VIDEOINFOHEADER2*)format->pbFormat;
width = header->bmiHeader.biWidth;
height = header->bmiHeader.biHeight;
samplesize = format->lSampleSize;
subtype = format->subtype.Data1;
// System memory sample
ASSERT(MFCreateSample(&srcSample));
ASSERT(MFCreateMemoryBuffer(format->lSampleSize, &buffer));
ASSERT(srcSample->AddBuffer(buffer));
ASSERT(buffer->QueryInterface(&srcBuffer));
// Video memory sample
ASSERT(deviceManager->OpenDeviceHandle(&hDevice));
ASSERT(deviceManager->GetVideoService(hDevice, __uuidof(IDirectXVideoAccelerationService), (void**)& service));
ASSERT(service->CreateSurface(width, height, 0, (D3DFORMAT)subtype, D3DPOOL_DEFAULT, 0, DXVA2_VideoSoftwareRenderTarget, &dstSurface, NULL));
ASSERT(MFCreateVideoSampleFromSurface(dstSurface, &dstSample));
ASSERT(deviceManager->CloseDeviceHandle(hDevice));
mfTransform = transform;
mfTransform->AddRef();
end:
if (format)
type->FreeRepresentation(AM_MEDIA_TYPE_REPRESENTATION, format);
SAFE_RELEASE(service);
SAFE_RELEASE(buffer);
SAFE_RELEASE(type);
return result;
}
VTABLE_HOOK(HRESULT, IMFTransform, ProcessOutput, DWORD dwFlags, DWORD cOutputBufferCount,
MFT_OUTPUT_DATA_BUFFER* pOutputSamples, DWORD* pdwStatus)
{
if (pOutputSamples->pSample != NULL || deviceManager == NULL || cOutputBufferCount != 1)
return originalProcessOutput(This, dwFlags, cOutputBufferCount, pOutputSamples, pdwStatus);
HRESULT result = S_OK;
if (mfTransform != This)
ASSERT(initialize(This));
pOutputSamples->pSample = srcSample;
pOutputSamples->pSample->AddRef();
ASSERT(originalProcessOutput(This, dwFlags, cOutputBufferCount, pOutputSamples, pdwStatus));
D3DLOCKED_RECT rect;
BYTE* buf;
ASSERT(srcBuffer->Lock(&buf, NULL, NULL));
ASSERT(dstSurface->LockRect(&rect, NULL, NULL));
ASSERT(MFCopyImage((BYTE*)rect.pBits, rect.Pitch, buf, samplesize, samplesize, 1));
ASSERT(dstSurface->UnlockRect());
ASSERT(srcBuffer->Unlock());
LONGLONG duration;
ASSERT(srcSample->GetSampleDuration(&duration));
ASSERT(dstSample->SetSampleDuration(duration));
LONGLONG time;
ASSERT(srcSample->GetSampleTime(&time));
ASSERT(dstSample->SetSampleTime(time));
DWORD flags;
ASSERT(srcSample->GetSampleFlags(&flags));
ASSERT(dstSample->SetSampleFlags(flags));
pOutputSamples->pSample->Release();
pOutputSamples->pSample = dstSample;
pOutputSamples->pSample->AddRef();
end:
return result;
}
VTABLE_HOOK(HRESULT, IMFTransform, ProcessMessage, MFT_MESSAGE_TYPE eMessage, ULONG_PTR ulParam)
{
if (forceSoftwareDecoding)
{
if (eMessage == MFT_MESSAGE_SET_D3D_MANAGER) {
PRINT("[DivaMovie] Force Software Decoding enabled\n");
INSTALL_VTABLE_HOOK(This, ProcessOutput, 25);
return S_OK;
}
return originalProcessMessage(This, eMessage, ulParam);
}
else
{
HRESULT result = originalProcessMessage(This, eMessage, ulParam);
if (eMessage == MFT_MESSAGE_SET_D3D_MANAGER && result == MF_E_UNSUPPORTED_D3D_TYPE)
{
PRINT("[DivaMovie] This system does not support DXVA hardware decoding\n");
result = originalProcessMessage(This, eMessage, NULL);
if (SUCCEEDED(result))
INSTALL_VTABLE_HOOK(This, ProcessOutput, 25);
}
else if (!forceHybridDecoding && eMessage == MFT_MESSAGE_SET_D3D_MANAGER && result == 0)
{
static bool warn = false;
if (!warn)
{
MessageBoxW(0, L"Your system supports DXVA hardware decoding.\nDivaMovie will be disabled.\n\nIt is highly recommended to restart the game now.", L"DivaMovie", MB_ICONWARNING);
CSimpleIniW ini_reader;
ini_reader.SetUnicode(false);
ini_reader.LoadFile(MASTER_CONFIG_FILE);
ini_reader.SetValue(L"plugins", L"DivaMovie.dva", L"0");
ini_reader.SaveFile(MASTER_CONFIG_FILE);
warn = true;
}
}
return result;
}
}
HOOK(void*, IMFTransformInitializer, 0x140420B90, void* a1, void* a2, IMFTransform** transform)
{
void* result = originalIMFTransformInitializer(a1, a2, transform);
INSTALL_VTABLE_HOOK(*transform, ProcessMessage, 23);
return result;
}
HOOK(HRESULT, DXVA2CreateDirect3DDeviceManager, PROC_ADDRESS("dxva2.dll", "DXVA2CreateDirect3DDeviceManager9"),
UINT* pResetToken, IDirect3DDeviceManager9** ppDeviceManager)
{
HRESULT result = originalDXVA2CreateDirect3DDeviceManager(pResetToken, ppDeviceManager);
if (FAILED(result))
return result;
if (deviceManager)
deviceManager->Release();
deviceManager = *ppDeviceManager;
deviceManager->AddRef();
return result;
}
void loadConfig() {
forceSoftwareDecoding = GetPrivateProfileIntW(L"general", L"force_software_decoding", 0, CONFIG_FILE) > 0 ? true : false;
forceHybridDecoding = GetPrivateProfileIntW(L"general", L"force_hybrid_decoding", 0, CONFIG_FILE) > 0 ? true : false;
debug = GetPrivateProfileIntW(L"general", L"debug", 0, CONFIG_FILE) > 0 ? true : false;
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
if (ul_reason_for_call == DLL_PROCESS_ATTACH)
{
loadConfig();
INSTALL_HOOK(DXVA2CreateDirect3DDeviceManager);
INSTALL_HOOK(IMFTransformInitializer);
}
return TRUE;
}
PluginConfig::PluginConfigOption config[] = {
{ PluginConfig::CONFIG_BOOLEAN, new PluginConfig::PluginConfigBooleanData{ L"force_software_decoding", L"general", CONFIG_FILE, L"Force Software Decoding", L"Use software decoding even on systems that support DXVA hardware decoding.", false } },
{ PluginConfig::CONFIG_BOOLEAN, new PluginConfig::PluginConfigBooleanData{ L"force_hybrid_decoding", L"general", CONFIG_FILE, L"Force Hybrid Decoding", L"Do not disable DivaMovie on systems that support DXVA hardware decoding.\nCan cause issues on recent drivers.", false } },
{ PluginConfig::CONFIG_BOOLEAN, new PluginConfig::PluginConfigBooleanData{ L"debug", L"general", CONFIG_FILE, L"Debug (slow!)", L"Enable PRINT (possibly at the cost of performance).", false } },
};
extern "C" __declspec(dllexport) LPCWSTR GetPluginName(void)
{
return L"DivaMovie";
}
extern "C" __declspec(dllexport) LPCWSTR GetPluginDescription(void)
{
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)
{
return PluginConfig::PluginConfigArray{ _countof(config), config };
}
@@ -1,74 +1,77 @@
#pragma once
#define WIN32_LEAN_AND_MEAN
#include <cstdio>
#include <windows.h>
#include <detours.h>
#include <string>
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\\DivaMovie.ini";
LPCWSTR CONFIG_FILE = CONFIG_FILE_STRING.c_str();
#define PRINT(value, ...) if (debug) printf(value, __VA_ARGS__);
#define PROC_ADDRESS(libraryName, procName) \
GetProcAddress(LoadLibrary(TEXT(libraryName)), procName)
#define SAFE_RELEASE(object) if (object) { object->Release(); object = NULL; }
#define VTABLE_HOOK(returnType, className, functionName, ...) \
typedef returnType functionName(className* This, __VA_ARGS__); \
functionName* original##functionName; \
returnType implOf##functionName(className* This, __VA_ARGS__)
#define INSTALL_VTABLE_HOOK(object, functionName, functionIndex) \
{ \
void** addr = &(*(void***)object)[functionIndex]; \
if (*addr != implOf##functionName) \
{ \
PRINT("[DivaMovie] Installing %s hook...\n", #functionName); \
original##functionName = (functionName*)*addr; \
DWORD oldProtect; \
VirtualProtect(addr, sizeof(void*), PAGE_EXECUTE_READWRITE, &oldProtect); \
*addr = implOf##functionName; \
VirtualProtect(addr, sizeof(void*), oldProtect, NULL); \
} \
}
#define HOOK(returnType, function, location, ...) \
typedef returnType function(__VA_ARGS__); \
function* original##function = (function*)location; \
returnType implOf##function(__VA_ARGS__)
#define INSTALL_HOOK(functionName) \
{ \
PRINT("[DivaMovie] Installing %s hook...\n", #functionName); \
DetourTransactionBegin(); \
DetourUpdateThread(GetCurrentThread()); \
DetourAttach((void**)&original##functionName, implOf##functionName); \
DetourTransactionCommit(); \
}
#define ASSERT(function) \
if (FAILED(result = (function))) \
{ \
PRINT("[DivaMovie] %s failed (error code: 0x%08x)\n", #function, (unsigned int)result); \
goto end; \
} /*\
else \
{ \
PRINT("[DivaMovie] %s succeeded\n", #function); \
}*/
#pragma once
#define WIN32_LEAN_AND_MEAN
#include <cstdio>
#include <windows.h>
#include <detours.h>
#include <string>
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\\DivaMovie.ini";
LPCWSTR CONFIG_FILE = CONFIG_FILE_STRING.c_str();
std::wstring MASTER_CONFIG_FILE_STRING = DirPath() + L"\\plugins\\config.ini";
LPCWSTR MASTER_CONFIG_FILE = MASTER_CONFIG_FILE_STRING.c_str();
#define PRINT(value, ...) if (debug) printf(value, __VA_ARGS__);
#define PROC_ADDRESS(libraryName, procName) \
GetProcAddress(LoadLibrary(TEXT(libraryName)), procName)
#define SAFE_RELEASE(object) if (object) { object->Release(); object = NULL; }
#define VTABLE_HOOK(returnType, className, functionName, ...) \
typedef returnType functionName(className* This, __VA_ARGS__); \
functionName* original##functionName; \
returnType implOf##functionName(className* This, __VA_ARGS__)
#define INSTALL_VTABLE_HOOK(object, functionName, functionIndex) \
{ \
void** addr = &(*(void***)object)[functionIndex]; \
if (*addr != implOf##functionName) \
{ \
PRINT("[DivaMovie] Installing %s hook...\n", #functionName); \
original##functionName = (functionName*)*addr; \
DWORD oldProtect; \
VirtualProtect(addr, sizeof(void*), PAGE_EXECUTE_READWRITE, &oldProtect); \
*addr = implOf##functionName; \
VirtualProtect(addr, sizeof(void*), oldProtect, NULL); \
} \
}
#define HOOK(returnType, function, location, ...) \
typedef returnType function(__VA_ARGS__); \
function* original##function = (function*)location; \
returnType implOf##function(__VA_ARGS__)
#define INSTALL_HOOK(functionName) \
{ \
PRINT("[DivaMovie] Installing %s hook...\n", #functionName); \
DetourTransactionBegin(); \
DetourUpdateThread(GetCurrentThread()); \
DetourAttach((void**)&original##functionName, implOf##functionName); \
DetourTransactionCommit(); \
}
#define ASSERT(function) \
if (FAILED(result = (function))) \
{ \
PRINT("[DivaMovie] %s failed (error code: 0x%08x)\n", #function, (unsigned int)result); \
goto end; \
} /*\
else \
{ \
PRINT("[DivaMovie] %s succeeded\n", #function); \
}*/
+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;
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+267 -254
View File
@@ -1,255 +1,268 @@
#include "windows.h"
#include "vector"
#include <tchar.h>
#include <GL/freeglut.h>
#include <iostream>
#include <fstream>
#include <filesystem>
#include <sstream>
#include <iomanip>
#include "PluginConfigApi.h"
#include "PatchApplier.h"
#include "PatchApplier600.h"
#include "PatchApplier710.h"
#include <detours.h>
#include "framework.h"
#pragma comment(lib, "detours.lib")
unsigned short game_version = 710;
void InjectCode(void* address, const std::vector<uint8_t> data);
void ApplyPatches();
void ApplyCustomPatches(std::wstring CPATCH_FILE_STRING);
HMODULE *hModulePtr;
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
hModulePtr = &hModule;
if (*(char*)0x140A570F0 == '6') game_version = 600;
ApplyPatches();
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
void ApplyPatches() {
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;
PatchApplier* pa;
switch (game_version)
{
case 600:
pa = new PatchApplier600;
break;
default:
pa = new PatchApplier710;
}
pa->ApplyPatches();
printf("[Patches] Patches applied\n");
if (nCustomPatches)
{
std::cout << "[Patches] Reading custom patches...\n";
try {
for (std::filesystem::path p : std::filesystem::directory_iterator("../patches"))
{
std::string extension = std::filesystem::path(p).extension().string();
if ((extension == ".p" || extension == ".P" || extension == ".p2" || extension == ".P2") &&
GetPrivateProfileIntW(L"plugins", std::filesystem::path(p).filename().c_str(), TRUE, CONFIG_FILE))
{
std::cout << "[Patches] Reading custom patch file: " << std::filesystem::path(p).filename().string() << std::endl;
ApplyCustomPatches(std::filesystem::path(p).wstring());
}
}
}
catch (const std::filesystem::filesystem_error &e) {
std::cout << "[Patches] File system error " << e.what() << " " << e.path1() << " " << e.path2() << " " << e.code() << std::endl;
}
std::cout << "[Patches] All custom patches applied\n";
}
}
void ApplyCustomPatches(std::wstring CPATCH_FILE_STRING)
{
LPCWSTR CPATCH_FILE = CPATCH_FILE_STRING.c_str();
std::ifstream fileStream(CPATCH_FILE_STRING);
if (!fileStream.is_open())
return;
std::string line;
// check for BOM
std::getline(fileStream, line);
if (line.size() >= 3 && line.rfind("\xEF\xBB\xBF", 0) == 0)
fileStream.seekg(3);
else
fileStream.seekg(0);
while (std::getline(fileStream, line))
{
if (line[0] == '#')
{
std::cout << "[Patches]" << line.substr(1, line.size()-1) << std::endl;
continue;
}
if (line == "IGNORE") break;
if (line.find(':') == std::string::npos || (line[0] == '/' && line[1] == '/')) continue;
std::vector<std::string> commentHSplit = SplitString(line, "#");
std::vector<std::string> commentDSSplit = SplitString(commentHSplit[0], "//");
std::vector<std::string> colonSplit = SplitString(commentDSSplit[0], ":");
if (colonSplit.size() != 2) continue;
bool echo = true;
if (colonSplit[0].at(0) == '@')
{
echo = false;
colonSplit[0].at(0) = ' ';
}
long long int address;
std::istringstream iss(colonSplit[0]);
iss >> std::setbase(16) >> address;
if (address == 0) std::cout << "[Patches] Custom patch address wrong: " << std::hex << address << std::endl;
if (colonSplit[1].at(0) == '!')
{
if (echo) std::cout << "[Patches] Patching: " << std::hex << address << ":!";
std::vector<std::string> fullColonSplit = SplitString(line, ":");
for (int i = 1; i < fullColonSplit[1].size(); i++)
{
unsigned char byte_u = fullColonSplit[1].at(i);
if(byte_u=='\\' && i<fullColonSplit[1].size())
{
switch (fullColonSplit[1].at(i + 1))
{
case '0':
byte_u = '\0';
i++;
break;
case 'n':
byte_u = '\n';
i++;
break;
case 't':
byte_u = '\t';
i++;
break;
case 'r':
byte_u = '\r';
i++;
break;
case 'b':
byte_u = '\b';
i++;
break;
case 'a':
byte_u = '\a';
i++;
break;
case 'f':
byte_u = '\f';
i++;
break;
case 'v':
byte_u = '\v';
i++;
break;
case '\\':
byte_u = '\\';
i++;
break;
}
}
if (echo) std::cout << byte_u;
std::vector<uint8_t> patch = { byte_u };
InjectCode((void*)address, patch);
address++;
}
if (echo) std::cout << std::endl;
}
else
{
std::vector<std::string> bytes = SplitString(colonSplit[1], " ");
if (bytes.size() < 1) continue;
std::string comment_string = "";
int comment_counter = 0;
if (commentHSplit.size() > 1)
{
bool ignore = 1;
for (std::string comment : commentHSplit)
{
if (ignore)
{
ignore = 0;
continue;
}
comment_string = comment_string + comment;
}
}
if (echo) std::cout << "[Patches] Patching: " << std::hex << address << ":";
for (std::string bytestring : bytes)
{
int byte;
std::istringstream issb(bytestring);
issb >> std::setbase(16) >> byte;
unsigned char byte_u = byte;
if (echo)
{
std::cout << std::hex << byte << " ";
if (comment_counter < comment_string.length())
{
std::cout << "(" << comment_string.at(comment_counter) << ") ";
comment_counter++;
}
}
std::vector<uint8_t> patch = { byte_u };
InjectCode((void*)address, patch);
address++;
}
if (echo) std::cout << std::endl;
else if (comment_string.length() > 0)
{
std::cout << "[Patches]";;
if (comment_string.at(0) != ' ') std::cout << ' ';
std::cout << comment_string << std::endl;
}
}
}
fileStream.close();
}
using namespace PluginConfig;
extern "C" __declspec(dllexport) LPCWSTR GetPluginName(void)
{
return L"Patches";
}
extern "C" __declspec(dllexport) LPCWSTR GetPluginDescription(void)
{
return L"Applies patches/tweaks to the game before it starts.\nThis plugin is required.";
#include "windows.h"
#include "vector"
#include <tchar.h>
#include <GL/freeglut.h>
#include <iostream>
#include <fstream>
#include <filesystem>
#include <sstream>
#include <iomanip>
#include "PluginConfigApi.h"
#include "PatchApplier.h"
#include "PatchApplier600.h"
#include "PatchApplier710.h"
#include <detours.h>
#include "framework.h"
#pragma comment(lib, "detours.lib")
unsigned short game_version = 710;
void InjectCode(void* address, const std::vector<uint8_t> data);
void ApplyPatches();
void ApplyCustomPatches(std::wstring CPATCH_FILE_STRING);
HMODULE *hModulePtr;
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
hModulePtr = &hModule;
if (*(char*)0x140A570F0 == '6') game_version = 600;
ApplyPatches();
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
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;
PatchApplier* pa;
switch (game_version)
{
case 600:
pa = new PatchApplier600;
break;
default:
pa = new PatchApplier710;
}
pa->ApplyPatches();
printf("[Patches] Patches applied\n");
if (nCustomPatches)
{
std::cout << "[Patches] Reading custom patches...\n";
try {
for (std::filesystem::path p : std::filesystem::directory_iterator("../patches"))
{
if (std::filesystem::path(p).filename().string()._Starts_with("._")) continue; // exclude macOS metadata
std::string extension = std::filesystem::path(p).extension().string();
if ((extension == ".p" || extension == ".P" || extension == ".p2" || extension == ".P2") &&
GetPrivateProfileIntW(L"plugins", std::filesystem::path(p).filename().c_str(), TRUE, CONFIG_FILE))
{
std::cout << "[Patches] Reading custom patch file: " << std::filesystem::path(p).filename().string() << std::endl;
ApplyCustomPatches(std::filesystem::path(p).wstring());
}
else std::cout << "[Patches] Skipping disabled patch file: " << std::filesystem::path(p).filename().string() << std::endl;
}
}
catch (const std::filesystem::filesystem_error &e) {
std::cout << "[Patches] File system error " << e.what() << " " << e.path1() << " " << e.path2() << " " << e.code() << std::endl;
}
std::cout << "[Patches] All custom patches applied\n";
}
}
void ApplyCustomPatches(std::wstring CPATCH_FILE_STRING)
{
LPCWSTR CPATCH_FILE = CPATCH_FILE_STRING.c_str();
std::ifstream fileStream(CPATCH_FILE_STRING);
if (!fileStream.is_open())
return;
std::string line;
// check for BOM
std::getline(fileStream, line);
if (line.size() >= 3 && line.rfind("\xEF\xBB\xBF", 0) == 0)
fileStream.seekg(3);
else
fileStream.seekg(0);
while (std::getline(fileStream, line))
{
if (line[0] == '#')
{
std::cout << "[Patches]" << line.substr(1, line.size()-1) << std::endl;
continue;
}
if (line == "IGNORE") break;
if (line.find(':') == std::string::npos || (line[0] == '/' && line[1] == '/')) continue;
std::vector<std::string> commentHSplit = SplitString(line, "#");
std::vector<std::string> commentDSSplit = SplitString(commentHSplit[0], "//");
std::vector<std::string> colonSplit = SplitString(commentDSSplit[0], ":");
if (colonSplit.size() != 2) continue;
bool echo = true;
if (colonSplit[0].at(0) == '@')
{
echo = false;
colonSplit[0].at(0) = ' ';
}
long long int address;
std::istringstream iss(colonSplit[0]);
iss >> std::setbase(16) >> address;
if (address == 0) std::cout << "[Patches] Custom patch address wrong: " << std::hex << address << std::endl;
if (colonSplit[1].at(0) == '!')
{
if (echo) std::cout << "[Patches] Patching: " << std::hex << address << ":!";
std::vector<std::string> fullColonSplit = SplitString(line, ":");
for (int i = 1; i < fullColonSplit[1].size(); i++)
{
unsigned char byte_u = fullColonSplit[1].at(i);
if(byte_u=='\\' && i<fullColonSplit[1].size())
{
switch (fullColonSplit[1].at(i + 1))
{
case '0':
byte_u = '\0';
i++;
break;
case 'n':
byte_u = '\n';
i++;
break;
case 't':
byte_u = '\t';
i++;
break;
case 'r':
byte_u = '\r';
i++;
break;
case 'b':
byte_u = '\b';
i++;
break;
case 'a':
byte_u = '\a';
i++;
break;
case 'f':
byte_u = '\f';
i++;
break;
case 'v':
byte_u = '\v';
i++;
break;
case '\\':
byte_u = '\\';
i++;
break;
}
}
if (echo) std::cout << byte_u;
std::vector<uint8_t> patch = { byte_u };
InjectCode((void*)address, patch);
address++;
}
if (echo) std::cout << std::endl;
}
else
{
std::vector<std::string> bytes = SplitString(colonSplit[1], " ");
if (bytes.size() < 1) continue;
std::string comment_string = "";
int comment_counter = 0;
if (commentHSplit.size() > 1)
{
bool ignore = 1;
for (std::string comment : commentHSplit)
{
if (ignore)
{
ignore = 0;
continue;
}
comment_string = comment_string + comment;
}
}
if (echo) std::cout << "[Patches] Patching: " << std::hex << address << ":";
for (std::string bytestring : bytes)
{
int byte;
std::istringstream issb(bytestring);
issb >> std::setbase(16) >> byte;
unsigned char byte_u = byte;
if (echo)
{
std::cout << std::hex << byte << " ";
if (comment_counter < comment_string.length())
{
std::cout << "(" << comment_string.at(comment_counter) << ") ";
comment_counter++;
}
}
std::vector<uint8_t> patch = { byte_u };
InjectCode((void*)address, patch);
address++;
}
if (echo) std::cout << std::endl;
else if (comment_string.length() > 0)
{
std::cout << "[Patches]";;
if (comment_string.at(0) != ' ') std::cout << ' ';
std::cout << comment_string << std::endl;
}
}
}
fileStream.close();
}
using namespace PluginConfig;
extern "C" __declspec(dllexport) LPCWSTR GetPluginName(void)
{
return L"Patches";
}
extern "C" __declspec(dllexport) LPCWSTR GetPluginDescription(void)
{
return L"Applies patches/tweaks to the game before it starts.\nThis plugin is required.";
}
+132 -129
View File
@@ -1,129 +1,132 @@
#pragma once
#include "windows.h"
#include <string>
#include <vector>
std::string TrimString(const std::string& str, const std::string& whitespace)
{
const size_t strBegin = str.find_first_not_of(whitespace);
if (strBegin == std::string::npos)
return "";
const size_t strEnd = str.find_last_not_of(whitespace);
const size_t strRange = strEnd - strBegin + 1;
return str.substr(strBegin, strRange);
}
std::vector<std::string> SplitString(const std::string& str, const std::string& delim)
{
std::vector<std::string> tokens;
size_t prev = 0, pos = 0;
do
{
pos = str.find(delim, prev);
if (pos == std::string::npos)
pos = str.length();
std::string token = str.substr(prev, pos - prev);
if (!token.empty())
tokens.push_back(token);
prev = pos + delim.length();
} while (pos < str.length() && prev < str.length());
return tokens;
}
void InjectCode(void* address, const std::vector<uint8_t> 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);
}
// patchMovieExt will modify an extension to mp4 only if the file exists on disk as an mp4
void patchMovieExt(std::string moviefile, void* address)
{
bool isinmdata = 0;
try {
for (std::filesystem::path p : std::filesystem::directory_iterator("../mdata"))
{
if (std::filesystem::path(p).filename().string().at(0) != 'M' || std::filesystem::path(p).filename().string().length() > 4) continue;
if (std::filesystem::exists(p.string() + "/rom/movie/" + moviefile + ".mp4"))
{
isinmdata = 1;
//std::cout << "[Patches] Movie " << moviefile << ".mp4 found in M" << ss.str() << std::endl;
break;
}
}
}
catch (const std::filesystem::filesystem_error& e) {
std::cout << "[Patches] File system error " << e.what() << " " << e.path1() << " " << e.path2() << " " << e.code() << std::endl;
}
if (isinmdata || std::filesystem::exists("../rom/movie/" + moviefile + ".mp4"))
{
InjectCode(address, { 0x6D, 0x70, 0x34 });
std::cout << "[Patches] Movie " << moviefile << " patched to mp4\n";
return;
}
//std::cout << "[Patches] Movie " << moviefile << " NOT patched to mp4\n";
return;
}
const LPCWSTR CONFIG_FILE = 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 nMP4Movies = GetPrivateProfileIntW(L"patches", L"mp4_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 nNoTimerSprite = GetPrivateProfileIntW(L"patches", L"no_timer_sprite", 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 nUnlockPseudo = GetPrivateProfileIntW(L"patches", L"unlock_pseudo", FALSE, CONFIG_FILE);
auto nCard = GetPrivateProfileIntW(L"patches", L"card", 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);
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 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 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 nShadows = GetPrivateProfileIntW(L"graphics", L"shadows", TRUE, CONFIG_FILE);
auto nPunchthrough = GetPrivateProfileIntW(L"graphics", L"punchthrough", TRUE, CONFIG_FILE);
auto nGlare = GetPrivateProfileIntW(L"graphics", L"glare", TRUE, CONFIG_FILE);
auto nShader = GetPrivateProfileIntW(L"graphics", L"shader", TRUE, CONFIG_FILE);
auto n2D = GetPrivateProfileIntW(L"graphics", L"2D", FALSE, CONFIG_FILE);
auto nNoDelete = GetPrivateProfileIntW(L"patches", L"prevent_data_deletion", FALSE, CONFIG_FILE);
auto nReflectResWidth = GetPrivateProfileIntW(L"graphics", L"reflect_res_width", 512, CONFIG_FILE);
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);
#pragma once
#include "windows.h"
#include <string>
#include <vector>
std::string TrimString(const std::string& str, const std::string& whitespace)
{
const size_t strBegin = str.find_first_not_of(whitespace);
if (strBegin == std::string::npos)
return "";
const size_t strEnd = str.find_last_not_of(whitespace);
const size_t strRange = strEnd - strBegin + 1;
return str.substr(strBegin, strRange);
}
std::vector<std::string> SplitString(const std::string& str, const std::string& delim)
{
std::vector<std::string> tokens;
size_t prev = 0, pos = 0;
do
{
pos = str.find(delim, prev);
if (pos == std::string::npos)
pos = str.length();
std::string token = str.substr(prev, pos - prev);
if (!token.empty())
tokens.push_back(token);
prev = pos + delim.length();
} while (pos < str.length() && prev < str.length());
return tokens;
}
void InjectCode(void* address, const std::vector<uint8_t> 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);
}
// patchMovieExt will modify an extension to mp4 only if the file exists on disk as an mp4
void patchMovieExt(std::string moviefile, void* address)
{
bool isinmdata = 0;
try {
for (std::filesystem::path p : std::filesystem::directory_iterator("../mdata"))
{
if (std::filesystem::path(p).filename().string().at(0) != 'M' || std::filesystem::path(p).filename().string().length() > 4) continue;
if (std::filesystem::exists(p.string() + "/rom/movie/" + moviefile + ".mp4"))
{
isinmdata = 1;
//std::cout << "[Patches] Movie " << moviefile << ".mp4 found in M" << ss.str() << std::endl;
break;
}
}
}
catch (const std::filesystem::filesystem_error& e) {
std::cout << "[Patches] File system error " << e.what() << " " << e.path1() << " " << e.path2() << " " << e.code() << std::endl;
}
if (isinmdata || std::filesystem::exists("../rom/movie/" + moviefile + ".mp4"))
{
InjectCode(address, { 0x6D, 0x70, 0x34 });
std::cout << "[Patches] Movie " << moviefile << " patched to mp4\n";
return;
}
//std::cout << "[Patches] Movie " << moviefile << " NOT patched to mp4\n";
return;
}
const LPCWSTR CONFIG_FILE = 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 nMP4Movies = GetPrivateProfileIntW(L"patches", L"mp4_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 nNoTimerSprite = GetPrivateProfileIntW(L"patches", L"no_timer_sprite", 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 nUnlockPseudo = GetPrivateProfileIntW(L"patches", L"unlock_pseudo", FALSE, CONFIG_FILE);
auto nCard = GetPrivateProfileIntW(L"patches", L"card", 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);
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", 0, CONFIG_FILE);
auto nNoScrollingSfx = GetPrivateProfileIntW(L"patches", L"no_scrolling_sfx", FALSE, CONFIG_FILE);
auto nEnablePvCustomization = GetPrivateProfileIntW(L"patches", L"enable_pv_customization", FALSE, CONFIG_FILE);
auto nNoHandScaling = GetPrivateProfileIntW(L"patches", L"no_hand_scaling", FALSE, CONFIG_FILE);
auto nDefaultHandSize = GetPrivateProfileIntW(L"patches", L"default_hand_size_uint", 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);
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 nShadows = GetPrivateProfileIntW(L"graphics", L"shadows", TRUE, CONFIG_FILE);
auto nPunchthrough = GetPrivateProfileIntW(L"graphics", L"punchthrough", TRUE, CONFIG_FILE);
auto nGlare = GetPrivateProfileIntW(L"graphics", L"glare", TRUE, CONFIG_FILE);
auto nShader = GetPrivateProfileIntW(L"graphics", L"shader", TRUE, CONFIG_FILE);
auto n2D = GetPrivateProfileIntW(L"graphics", L"2D", FALSE, CONFIG_FILE);
auto nNoDelete = GetPrivateProfileIntW(L"patches", L"prevent_data_deletion", FALSE, CONFIG_FILE);
auto nReflectResWidth = GetPrivateProfileIntW(L"graphics", L"reflect_res_width", 512, CONFIG_FILE);
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 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;
};
}