├── .gitignore
├── .gitmodules
├── LICENSE.md
├── README.md
├── ReShade.sln
├── ReShade.vcxproj
├── ReShade.vcxproj.filters
├── ReShadeFX.vcxproj
├── ReShadeFX.vcxproj.filters
├── deps
├── ImGui.props
├── ImGui.vcxproj
├── MinHook.props
├── MinHook.vcxproj
├── MinHook.vcxproj.filters
├── Windows.props
├── gl3w.props
├── gl3w.vcxproj
├── stb.props
├── stb.vcxproj
├── stb_image_dds
│ └── stb_image_dds.h
└── stb_impl.c
├── res
├── exports.def
├── resource.h
├── resource.rc
├── resource.rc2
├── shader_copy_ps.hlsl
├── shader_copy_vs.hlsl
├── shader_imgui_ps.hlsl
└── shader_imgui_vs.hlsl
├── setup
├── Glass.cs
├── IniFile.cs
├── PEInfo.cs
├── Properties
│ ├── App.xaml
│ ├── Assembly.manifest
│ ├── AssemblyInfo.cs
│ └── Icon.ico
├── ReShade Setup.csproj
├── Select.xaml
├── Select.xaml.cs
├── Wizard.xaml
└── Wizard.xaml.cs
├── source
├── com_ptr.hpp
├── constant_folding.cpp
├── d3d10
│ ├── d3d10.cpp
│ ├── d3d10.hpp
│ ├── d3d10_device.cpp
│ ├── d3d10_device.hpp
│ ├── d3d10_effect_compiler.cpp
│ ├── d3d10_effect_compiler.hpp
│ ├── d3d10_runtime.cpp
│ ├── d3d10_runtime.hpp
│ ├── d3d10_stateblock.cpp
│ └── d3d10_stateblock.hpp
├── d3d11
│ ├── d3d11.cpp
│ ├── d3d11.hpp
│ ├── d3d11_device.cpp
│ ├── d3d11_device.hpp
│ ├── d3d11_device_context.cpp
│ ├── d3d11_device_context.hpp
│ ├── d3d11_effect_compiler.cpp
│ ├── d3d11_effect_compiler.hpp
│ ├── d3d11_runtime.cpp
│ ├── d3d11_runtime.hpp
│ ├── d3d11_stateblock.cpp
│ └── d3d11_stateblock.hpp
├── d3d9
│ ├── d3d9.cpp
│ ├── d3d9.hpp
│ ├── d3d9_device.cpp
│ ├── d3d9_device.hpp
│ ├── d3d9_effect_compiler.cpp
│ ├── d3d9_effect_compiler.hpp
│ ├── d3d9_runtime.cpp
│ ├── d3d9_runtime.hpp
│ ├── d3d9_swapchain.cpp
│ └── d3d9_swapchain.hpp
├── directory_watcher.cpp
├── directory_watcher.hpp
├── dllmain.cpp
├── dllmodule.cpp
├── dllmodule.hpp
├── dxgi
│ ├── dxgi.cpp
│ ├── dxgi.hpp
│ ├── dxgi_device.cpp
│ ├── dxgi_device.hpp
│ ├── dxgi_swapchain.cpp
│ └── dxgi_swapchain.hpp
├── effect_lexer.cpp
├── effect_lexer.hpp
├── effect_parser.cpp
├── effect_parser.hpp
├── effect_preprocessor.cpp
├── effect_preprocessor.hpp
├── effect_symbol_table.cpp
├── effect_symbol_table.hpp
├── effect_syntax_tree.hpp
├── effect_syntax_tree_nodes.hpp
├── filesystem.cpp
├── filesystem.hpp
├── hook.cpp
├── hook.hpp
├── hook_manager.cpp
├── hook_manager.hpp
├── ini_file.cpp
├── ini_file.hpp
├── input.cpp
├── input.hpp
├── log.cpp
├── log.hpp
├── module.cpp
├── module.hpp
├── moving_average.hpp
├── opengl
│ ├── opengl_effect_compiler.cpp
│ ├── opengl_effect_compiler.hpp
│ ├── opengl_runtime.cpp
│ ├── opengl_runtime.hpp
│ ├── opengl_stateblock.cpp
│ ├── opengl_stateblock.hpp
│ ├── opengl_stubs.hpp
│ ├── opengl_stubs_internal.hpp
│ ├── stubs_gl.cpp
│ └── stubs_wgl.cpp
├── resource_loading.cpp
├── resource_loading.hpp
├── runtime.cpp
├── runtime.hpp
├── runtime_objects.cpp
├── runtime_objects.hpp
├── source_location.hpp
├── string_codecvt.hpp
├── variant.hpp
└── windows
│ ├── user32.cpp
│ └── ws2_32.cpp
└── tools
└── verbuild.exe
/.gitignore:
--------------------------------------------------------------------------------
1 | # Build results
2 | [Bb]in/
3 | [Oo]bj/
4 | [Ii]ntermediate/
5 | [Bb]uild/
6 | [Dd]ebug/
7 | [Rr]elease/
8 | *.cso
9 |
10 | # Visual Studio cache files
11 | .vs/
12 | ipch/
13 | *.aps
14 | *.VC.db
15 | *.VC.opendb
16 | *.sdf
17 | *.opensdf
18 | *.suo
19 | *.user
20 |
21 | # Temporary OS files
22 | .DS_Store
23 | Thumbs.db
24 |
25 | # Versioning
26 | /res/Version.h
27 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "imgui"]
2 | path = deps/imgui
3 | url = https://github.com/ocornut/imgui.git
4 | [submodule "minhook"]
5 | path = deps/minhook
6 | url = https://github.com/TsudaKageyu/minhook.git
7 | [submodule "stb"]
8 | path = deps/stb
9 | url = https://github.com/nothings/stb.git
10 | [submodule "gl3w"]
11 | path = deps/gl3w
12 | url = https://github.com/skaslev/gl3w.git
13 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | Copyright 2014 Patrick Mours. All rights reserved.
2 |
3 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
4 |
5 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
6 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
7 | * Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
8 |
9 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
10 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ReShade
2 | =======
3 |
4 | ReShade is an advanced, fully generic post-processing injector for games and video software. Imagine your favorite game with ambient occlusion, real depth of field effects, color correction and more ... ReShade exposes an automated and generic way to access both frame color and depth information and all the tools to make it happen.
5 |
6 | ## Building
7 |
8 | You'll need both Git and Visual Studio 2017 or higher to build ReShade. Latter is required since the project makes use of some C++14 and C++17 features. Additionally a Python 2.7.9 or later (Python 3 is supported as well) installation is necessary for the `gl3w` dependency to build.
9 |
10 | 1. Clone this repository including all Git submodules
11 | 2. Open the Visual Studio solution
12 | 3. Select either the "32-bit" or "64-bit" target platform and build the solution (this will build ReShade and all dependencies)
13 |
14 | ## Contributing
15 |
16 | Any contributions to the project are welcomed, it's recommended to use GitHub [pull requests](https://help.github.com/articles/using-pull-requests/).
17 |
18 | ## License
19 |
20 | All the source code is licensed under the conditions of the [BSD 3-clause license](LICENSE.md).
21 |
--------------------------------------------------------------------------------
/ReShadeFX.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/deps/ImGui.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | $(SolutionDir)deps\imgui;%(AdditionalIncludeDirectories)
7 |
8 |
9 | ImGui.lib;%(AdditionalDependencies)
10 |
11 |
12 |
--------------------------------------------------------------------------------
/deps/ImGui.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Debug
10 | x64
11 |
12 |
13 | Release
14 | Win32
15 |
16 |
17 | Release
18 | x64
19 |
20 |
21 |
22 | {9A62233B-0B70-4B48-91E8-35AA666BC32E}
23 | 10.0.16299.0
24 |
25 |
26 |
27 | $(SolutionDir)bin\$(Platform)\$(Configuration)\
28 | $(SolutionDir)intermediate\$(ProjectName)\$(Platform)\$(Configuration)\
29 | StaticLibrary
30 | Unicode
31 | v141
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | MultiThreadedDebugDLL
40 |
41 |
42 |
43 |
44 | MultiThreadedDebugDLL
45 |
46 |
47 |
48 |
49 | MultiThreaded
50 | NDEBUG;%(PreprocessorDefinitions)
51 |
52 |
53 |
54 |
55 | MultiThreaded
56 | NDEBUG;%(PreprocessorDefinitions)
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/deps/MinHook.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | $(SolutionDir)deps\minhook\include;%(AdditionalIncludeDirectories)
7 |
8 |
9 | MinHook.lib;%(AdditionalDependencies)
10 |
11 |
12 |
--------------------------------------------------------------------------------
/deps/MinHook.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Debug
10 | x64
11 |
12 |
13 | Release
14 | Win32
15 |
16 |
17 | Release
18 | x64
19 |
20 |
21 |
22 | {783FEDFB-5124-4F8C-87BC-70AA8490266B}
23 | 10.0.16299.0
24 |
25 |
26 |
27 | $(SolutionDir)bin\$(Platform)\$(Configuration)\
28 | $(SolutionDir)intermediate\$(ProjectName)\$(Platform)\$(Configuration)\
29 | StaticLibrary
30 | Unicode
31 | v141
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | MultiThreadedDebugDLL
40 |
41 |
42 |
43 |
44 | MultiThreadedDebugDLL
45 |
46 |
47 |
48 |
49 | MultiThreaded
50 |
51 |
52 |
53 |
54 | MultiThreaded
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/deps/MinHook.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4f094667-e67f-4105-b94d-5ffd7bc80831}
6 |
7 |
8 | {6d8d397a-3296-469c-bfc1-0138956f951d}
9 |
10 |
11 |
12 |
13 | HDE
14 |
15 |
16 | HDE
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | HDE
25 |
26 |
27 | HDE
28 |
29 |
30 | HDE
31 |
32 |
33 | HDE
34 |
35 |
36 | HDE
37 |
38 |
39 | API
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/deps/Windows.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Shlwapi.lib;%(AdditionalDependencies)
7 |
8 |
9 |
--------------------------------------------------------------------------------
/deps/gl3w.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | $(SolutionDir)deps\gl3w\include;%(AdditionalIncludeDirectories)
7 |
8 |
9 | gl3W.lib;%(AdditionalDependencies)
10 |
11 |
12 |
--------------------------------------------------------------------------------
/deps/gl3w.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Debug
10 | x64
11 |
12 |
13 | Release
14 | Win32
15 |
16 |
17 | Release
18 | x64
19 |
20 |
21 |
22 | {09C0D610-9B82-40D8-B37E-0D26E3BFF77F}
23 | 10.0.16299.0
24 |
25 |
26 |
27 | $(SolutionDir)bin\$(Platform)\$(Configuration)\
28 | $(SolutionDir)intermediate\$(ProjectName)\$(Platform)\$(Configuration)\
29 | StaticLibrary
30 | Unicode
31 | v141
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | gl3w\include;%(AdditionalIncludeDirectories)
40 |
41 |
42 |
43 |
44 | MultiThreadedDebugDLL
45 | _GDI32_;%(PreprocessorDefinitions)
46 |
47 |
48 |
49 |
50 | MultiThreadedDebugDLL
51 | _GDI32_;%(PreprocessorDefinitions)
52 |
53 |
54 |
55 |
56 | MultiThreaded
57 | _GDI32_;%(PreprocessorDefinitions)
58 |
59 |
60 |
61 |
62 | MultiThreaded
63 | _GDI32_;%(PreprocessorDefinitions)
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 | $(CleanDependsOn);
77 | CleanGL3WSources;
78 |
79 |
80 | GenerateGL3WSources;
81 | $(BuildDependsOn);
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
--------------------------------------------------------------------------------
/deps/stb.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | $(SolutionDir)deps\stb;$(SolutionDir)deps\stb_image_dds;%(AdditionalIncludeDirectories)
7 | _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
8 |
9 |
10 | stb.lib;%(AdditionalDependencies)
11 |
12 |
13 |
--------------------------------------------------------------------------------
/deps/stb.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Debug
10 | x64
11 |
12 |
13 | Release
14 | Win32
15 |
16 |
17 | Release
18 | x64
19 |
20 |
21 |
22 | {723BDEF8-4A39-4961-BDAB-54074012FF47}
23 | 10.0.16299.0
24 |
25 |
26 |
27 | $(SolutionDir)bin\$(Platform)\$(Configuration)\
28 | $(SolutionDir)intermediate\$(ProjectName)\$(Platform)\$(Configuration)\
29 | StaticLibrary
30 | Unicode
31 | v141
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | stb;stb_image_dds;%(AdditionalIncludeDirectories)
40 |
41 |
42 |
43 |
44 | MultiThreadedDebugDLL
45 |
46 |
47 |
48 |
49 | MultiThreadedDebugDLL
50 |
51 |
52 |
53 |
54 | MultiThreaded
55 | NDEBUG;%(PreprocessorDefinitions)
56 |
57 |
58 |
59 |
60 | MultiThreaded
61 | NDEBUG;%(PreprocessorDefinitions)
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
--------------------------------------------------------------------------------
/deps/stb_impl.c:
--------------------------------------------------------------------------------
1 | #define STB_IMAGE_IMPLEMENTATION
2 | #define STB_IMAGE_DDS_IMPLEMENTATION
3 | #define STB_IMAGE_WRITE_IMPLEMENTATION
4 | #define STB_IMAGE_RESIZE_IMPLEMENTATION
5 |
6 | #include "stb_image.h"
7 | #include "stb_image_dds.h"
8 | #include "stb_image_write.h"
9 | #include "stb_image_resize.h"
10 |
--------------------------------------------------------------------------------
/res/resource.h:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/04348/reshade_custom/27ffee5852b436d37697c2fd0ee44cdf7423599a/res/resource.h
--------------------------------------------------------------------------------
/res/resource.rc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/04348/reshade_custom/27ffee5852b436d37697c2fd0ee44cdf7423599a/res/resource.rc
--------------------------------------------------------------------------------
/res/resource.rc2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/04348/reshade_custom/27ffee5852b436d37697c2fd0ee44cdf7423599a/res/resource.rc2
--------------------------------------------------------------------------------
/res/shader_copy_ps.hlsl:
--------------------------------------------------------------------------------
1 | Texture2D texture0 : register(t0);
2 | SamplerState sampler0 : register(s0);
3 |
4 | float4 main(float4 vpos : SV_POSITION, float2 uv : TEXCOORD) : SV_TARGET
5 | {
6 | return float4(texture0.Sample(sampler0, uv).rgb, 1.0);
7 | }
8 |
--------------------------------------------------------------------------------
/res/shader_copy_vs.hlsl:
--------------------------------------------------------------------------------
1 | void main(uint id : SV_VertexID, out float4 pos : SV_Position, out float2 uv : TEXCOORD)
2 | {
3 | uv.x = (id == 2) ? 2.0 : 0.0;
4 | uv.y = (id == 1) ? 2.0 : 0.0;
5 | pos = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
6 | }
7 |
--------------------------------------------------------------------------------
/res/shader_imgui_ps.hlsl:
--------------------------------------------------------------------------------
1 | Texture2D texture0 : register(t0);
2 | SamplerState sampler0 : register(s0);
3 |
4 | float4 main(float4 vpos : SV_POSITION, float4 col : COLOR0, float2 uv : TEXCOORD0) : SV_TARGET
5 | {
6 | return col * texture0.Sample(sampler0, uv);
7 | }
8 |
--------------------------------------------------------------------------------
/res/shader_imgui_vs.hlsl:
--------------------------------------------------------------------------------
1 | cbuffer Globals : register(b0)
2 | {
3 | float4x4 ProjectionMatrix;
4 | };
5 |
6 | struct VS_INPUT
7 | {
8 | float2 pos : POSITION;
9 | float4 col : COLOR0;
10 | float2 uv : TEXCOORD0;
11 | };
12 | struct PS_INPUT
13 | {
14 | float4 pos : SV_POSITION;
15 | float4 col : COLOR0;
16 | float2 uv : TEXCOORD0;
17 | };
18 |
19 | void main(VS_INPUT input, out PS_INPUT output)
20 | {
21 | output.pos = mul(ProjectionMatrix, float4(input.pos.xy, 0.f, 1.f));
22 | output.col = input.col;
23 | output.uv = input.uv;
24 | }
25 |
--------------------------------------------------------------------------------
/setup/Glass.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 | using System.Windows;
4 | using System.Windows.Interop;
5 | using System.Windows.Media;
6 |
7 | public static class Glass
8 | {
9 | [StructLayout(LayoutKind.Sequential)]
10 | private struct MARGINS
11 | {
12 | public int cxLeftWidth;
13 | public int cxRightWidth;
14 | public int cyTopHeight;
15 | public int cyBottomHeight;
16 | }
17 |
18 | [DllImport("dwmapi.dll")]
19 | private static extern int DwmIsCompositionEnabled(out bool enabled);
20 | [DllImport("dwmapi.dll")]
21 | private static extern int DwmExtendFrameIntoClientArea(IntPtr hwnd, ref MARGINS pMarInset);
22 | [DllImport("user32.dll")]
23 | private static extern int GetWindowLong(IntPtr hwnd, int index);
24 | [DllImport("user32.dll")]
25 | private static extern int SetWindowLong(IntPtr hwnd, int index, int newStyle);
26 | [DllImport("user32.dll")]
27 | private static extern bool SetWindowPos(IntPtr hwnd, IntPtr hwndInsertAfter, int x, int y, int width, int height, uint flags);
28 | [DllImport("user32.dll")]
29 | private static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
30 |
31 | public static bool IsEnabled
32 | {
33 | get
34 | {
35 | bool enabled = false;
36 | DwmIsCompositionEnabled(out enabled);
37 |
38 | return enabled;
39 | }
40 | }
41 |
42 | public static void HideIcon(Window window)
43 | {
44 | IntPtr hwnd = new WindowInteropHelper(window).Handle;
45 |
46 | const int WM_SETICON = 0x0080;
47 |
48 | SendMessage(hwnd, WM_SETICON, new IntPtr(1), IntPtr.Zero);
49 | SendMessage(hwnd, WM_SETICON, IntPtr.Zero, IntPtr.Zero);
50 |
51 | const int GWL_EXSTYLE = -20;
52 | const int WS_EX_DLGMODALFRAME = 0x0001;
53 |
54 | SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_DLGMODALFRAME);
55 |
56 | const int SWP_NOSIZE = 0x0001;
57 | const int SWP_NOMOVE = 0x0002;
58 | const int SWP_NOZORDER = 0x0004;
59 | const int SWP_FRAMECHANGED = 0x0020;
60 |
61 | SetWindowPos(hwnd, IntPtr.Zero, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED);
62 | }
63 | public static void HideSystemMenu(Window window, bool hidden = true)
64 | {
65 | IntPtr hwnd = new WindowInteropHelper(window).Handle;
66 |
67 | const int GWL_STYLE = -16;
68 | const int WS_SYSMENU = 0x80000;
69 |
70 | if (hidden)
71 | {
72 | SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_SYSMENU);
73 | }
74 | else
75 | {
76 | SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) | WS_SYSMENU);
77 | }
78 | }
79 |
80 | public static bool ExtendFrame(Window window)
81 | {
82 | return ExtendFrame(window, new Thickness(-1, -1, -1, -1));
83 | }
84 | public static bool ExtendFrame(Window window, Thickness margin)
85 | {
86 | if (!IsEnabled)
87 | {
88 | return false;
89 | }
90 |
91 | IntPtr hwnd = new WindowInteropHelper(window).Handle;
92 |
93 | if (hwnd == IntPtr.Zero)
94 | {
95 | throw new InvalidOperationException("The window must be shown before extending glass effect.");
96 | }
97 |
98 | // Adapted from http://blogs.msdn.com/b/adam_nathan/archive/2006/05/04/589686.aspx
99 | window.Background = Brushes.Transparent;
100 | HwndSource.FromHwnd(hwnd).CompositionTarget.BackgroundColor = Colors.Transparent;
101 |
102 | var margins = new MARGINS {
103 | cxLeftWidth = (int)margin.Left,
104 | cxRightWidth = (int)margin.Right,
105 | cyTopHeight = (int)margin.Top,
106 | cyBottomHeight = (int)margin.Bottom
107 | };
108 |
109 | DwmExtendFrameIntoClientArea(hwnd, ref margins);
110 |
111 | return true;
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/setup/IniFile.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 | using System.Runtime.InteropServices;
3 |
4 | public static class IniFile
5 | {
6 | [DllImport("kernel32", CharSet = CharSet.Unicode)]
7 | private static extern int GetPrivateProfileString(string section, string key, string defaultValue, StringBuilder value, int size, string filePath);
8 | [DllImport("kernel32", CharSet = CharSet.Unicode, SetLastError = true)]
9 | [return: MarshalAs(UnmanagedType.Bool)]
10 | private static extern bool WritePrivateProfileString(string section, string key, string value, string filePath);
11 |
12 | public static string ReadValue(string file, string section, string key, string defaultValue = "")
13 | {
14 | var value = new StringBuilder(512);
15 | GetPrivateProfileString(section, key, defaultValue, value, value.Capacity, file);
16 | return value.ToString();
17 | }
18 | public static bool WriteValue(string file, string section, string key, string value)
19 | {
20 | return WritePrivateProfileString(section, key, value, file);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/setup/PEInfo.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Runtime.InteropServices;
4 | using System.Security;
5 |
6 | public unsafe class PEInfo
7 | {
8 | public enum BinaryType : ushort
9 | {
10 | IMAGE_FILE_MACHINE_UNKNOWN = 0x0,
11 | IMAGE_FILE_MACHINE_I386 = 0x14c,
12 | IMAGE_FILE_MACHINE_AMD64 = 0x8664,
13 | }
14 |
15 | [StructLayout(LayoutKind.Sequential)]
16 | private struct LOADED_IMAGE
17 | {
18 | public IntPtr ModuleName;
19 | public IntPtr hFile;
20 | public IntPtr MappedAddress;
21 | public IntPtr FileHeader;
22 | public IntPtr LastRvaSection;
23 | public uint NumberOfSections;
24 | public IntPtr Sections;
25 | public uint Characteristics;
26 | public ushort fSystemImage;
27 | public ushort fDOSImage;
28 | public ushort fReadOnly;
29 | public ushort Version;
30 | public IntPtr Flink;
31 | public IntPtr BLink;
32 | public uint SizeOfImage;
33 | }
34 | [StructLayout(LayoutKind.Explicit)]
35 | private struct IMAGE_NT_HEADERS
36 | {
37 | [FieldOffset(0)]
38 | public uint Signature;
39 | [FieldOffset(4)]
40 | public IMAGE_FILE_HEADER FileHeader;
41 | }
42 | [StructLayout(LayoutKind.Sequential)]
43 | private struct IMAGE_FILE_HEADER
44 | {
45 | public BinaryType Machine;
46 | public ushort NumberOfSections;
47 | public uint TimeDateStamp;
48 | public uint PointerToSymbolTable;
49 | public uint NumberOfSymbols;
50 | public ushort SizeOfOptionalHeader;
51 | public ushort Characteristics;
52 | }
53 | [StructLayout(LayoutKind.Explicit)]
54 | private struct IMAGE_IMPORT_DESCRIPTOR
55 | {
56 | #region union
57 | [FieldOffset(0)]
58 | public UInt32 Characteristics;
59 | [FieldOffset(0)]
60 | public UInt32 OriginalFirstThunk;
61 | #endregion
62 |
63 | [FieldOffset(4)]
64 | public uint TimeDateStamp;
65 | [FieldOffset(8)]
66 | public uint ForwarderChain;
67 | [FieldOffset(12)]
68 | public uint Name;
69 | [FieldOffset(16)]
70 | public uint FirstThunk;
71 | }
72 |
73 | [DllImport("dbghelp.dll"), SuppressUnmanagedCodeSecurity]
74 | private static extern void* ImageDirectoryEntryToData(void* pBase, bool mappedAsImage, ushort directoryEntry, out uint size);
75 | [DllImport("dbghelp.dll"), SuppressUnmanagedCodeSecurity]
76 | private static extern IntPtr ImageRvaToVa(IntPtr pNtHeaders, IntPtr pBase, uint rva, IntPtr pLastRvaSection);
77 | [DllImport("imagehlp.dll"), SuppressUnmanagedCodeSecurity]
78 | private static extern bool MapAndLoad(string imageName, string dllPath, out LOADED_IMAGE loadedImage, bool dotDll, bool readOnly);
79 |
80 | private readonly BinaryType _binaryType = BinaryType.IMAGE_FILE_MACHINE_UNKNOWN;
81 | private readonly List _modules = new List();
82 |
83 | // Adapted from http://stackoverflow.com/a/4696857/2055880
84 | public PEInfo(string path)
85 | {
86 | uint size;
87 | LOADED_IMAGE image;
88 |
89 | if (MapAndLoad(path, null, out image, true, true) && image.MappedAddress != IntPtr.Zero)
90 | {
91 | var imports = (IMAGE_IMPORT_DESCRIPTOR*)ImageDirectoryEntryToData((void*)image.MappedAddress, false, 1, out size);
92 |
93 | if (imports != null)
94 | {
95 | while (imports->OriginalFirstThunk != 0)
96 | {
97 | _modules.Add(Marshal.PtrToStringAnsi(ImageRvaToVa(image.FileHeader, image.MappedAddress, imports->Name, IntPtr.Zero)));
98 |
99 | ++imports;
100 | }
101 | }
102 |
103 | _binaryType = ((IMAGE_NT_HEADERS*)image.FileHeader)->FileHeader.Machine;
104 | }
105 | }
106 |
107 | public BinaryType Type
108 | {
109 | get { return _binaryType; }
110 | }
111 | public IEnumerable Modules
112 | {
113 | get { return _modules; }
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/setup/Properties/App.xaml:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/setup/Properties/Assembly.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/setup/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 |
3 | [assembly: AssemblyTitle("ReShade Setup")]
4 | [assembly: AssemblyVersion("1.4.0.0")]
5 | [assembly: AssemblyDescription("")]
6 | [assembly: AssemblyConfiguration("")]
7 | [assembly: AssemblyCompany("crosire")]
8 | [assembly: AssemblyProduct("ReShade")]
9 | [assembly: AssemblyCopyright("Copyright © 2014. All rights reserved.")]
10 |
--------------------------------------------------------------------------------
/setup/Properties/Icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/04348/reshade_custom/27ffee5852b436d37697c2fd0ee44cdf7423599a/setup/Properties/Icon.ico
--------------------------------------------------------------------------------
/setup/ReShade Setup.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {3B7009FA-0B09-4F27-8126-0885E66A5679}
6 | Debug
7 | AnyCPU
8 | WinExe
9 | ReShade Setup
10 | Properties\Icon.ico
11 | $(SolutionDir)\bin\$(Platform)\$(Configuration)\
12 | $(SolutionDir)\intermediate\$(AssemblyName)\$(Platform)\$(Configuration)\
13 | Properties
14 | ReShade.Setup
15 | v4.6
16 | 512
17 | Properties\Assembly.manifest
18 | 4
19 |
20 |
21 |
22 | AnyCPU
23 | true
24 | full
25 | false
26 | DEBUG;TRACE
27 | true
28 | true
29 | true
30 |
31 |
32 | AnyCPU
33 | none
34 | true
35 | true
36 | false
37 | false
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | MSBuild:Compile
50 | Designer
51 |
52 |
53 |
54 |
55 |
56 | Designer
57 | MSBuild:Compile
58 |
59 |
60 | Designer
61 | MSBuild:Compile
62 |
63 |
64 | Select.xaml
65 |
66 |
67 | Wizard.xaml
68 |
69 |
70 |
71 |
72 | Code
73 |
74 |
75 |
76 |
77 |
78 | Designer
79 |
80 |
81 |
82 |
83 | false
84 |
85 |
86 |
87 |
88 |
89 |
90 |
--------------------------------------------------------------------------------
/setup/Select.xaml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/setup/Select.xaml.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | using System.Collections.Generic;
7 | using System.ComponentModel;
8 | using System.IO;
9 | using System.Linq;
10 | using System.Windows;
11 | using System.Windows.Controls;
12 |
13 | namespace ReShade.Setup
14 | {
15 | public partial class SelectWindow : Window
16 | {
17 | public class EffectItem : INotifyPropertyChanged
18 | {
19 | public string Name { get; set; }
20 | public string Path { get; set; }
21 |
22 | public bool IsChecked
23 | {
24 | get
25 | {
26 | return _isChecked;
27 | }
28 | set
29 | {
30 | _isChecked = value;
31 | PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("IsChecked"));
32 | }
33 | }
34 |
35 | private bool _isChecked = true;
36 | public event PropertyChangedEventHandler PropertyChanged;
37 | }
38 |
39 | public SelectWindow(IEnumerable effectFiles)
40 | {
41 | InitializeComponent();
42 |
43 | EffectList.ItemsSource =
44 | effectFiles
45 | .Where(it => Path.GetExtension(it) == ".fx")
46 | .Select(it => new EffectItem {
47 | Name = Path.GetFileName(it),
48 | Path = it
49 | });
50 | }
51 |
52 | public IEnumerable GetSelection()
53 | {
54 | return EffectList.Items.Cast();
55 | }
56 |
57 | private void ChangeChecked(object sender, RoutedEventArgs e)
58 | {
59 | var button = (Button)sender;
60 | bool check = (string)button.Content == "Check All";
61 | button.Content = check ? "Uncheck All" : "Check All";
62 |
63 | foreach (EffectItem item in EffectList.Items)
64 | {
65 | item.IsChecked = check;
66 | }
67 | }
68 | private void ConfirmSelection(object sender, RoutedEventArgs e)
69 | {
70 | Close();
71 | }
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/setup/Wizard.xaml:
--------------------------------------------------------------------------------
1 |
13 |
15 |
25 |
28 |
35 |
42 |
49 |
50 |
51 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/source/com_ptr.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #pragma once
7 |
8 | #include
9 |
10 | template
11 | class com_ptr
12 | {
13 | public:
14 | com_ptr() : _object(nullptr) { }
15 | com_ptr(T *object) : _object(nullptr)
16 | {
17 | reset(object);
18 | }
19 | com_ptr(const com_ptr ©) : _object(nullptr)
20 | {
21 | reset(copy._object);
22 | }
23 | com_ptr(com_ptr &&move) : _object(nullptr)
24 | {
25 | std::swap(_object, move._object);
26 | }
27 |
28 | ~com_ptr()
29 | {
30 | reset();
31 | }
32 |
33 | unsigned long ref_count() const
34 | {
35 | return _object->AddRef(), _object->Release();
36 | }
37 |
38 | inline T *get() const
39 | {
40 | return _object;
41 | }
42 | T &operator*() const
43 | {
44 | assert(_object != nullptr);
45 |
46 | return *_object;
47 | }
48 | T *operator->() const
49 | {
50 | assert(_object != nullptr);
51 |
52 | return _object;
53 | }
54 | T **operator&() throw()
55 | {
56 | assert(_object == nullptr);
57 |
58 | return &_object;
59 | }
60 |
61 | void reset(T *object = nullptr)
62 | {
63 | if (_object != nullptr)
64 | {
65 | _object->Release();
66 | }
67 |
68 | _object = object;
69 |
70 | if (_object != nullptr)
71 | {
72 | _object->AddRef();
73 | }
74 | }
75 | com_ptr &operator=(T *object)
76 | {
77 | reset(object);
78 |
79 | return *this;
80 | }
81 | com_ptr &operator=(const com_ptr ©)
82 | {
83 | reset(copy._object);
84 |
85 | return *this;
86 | }
87 | com_ptr &operator=(com_ptr &&move)
88 | {
89 | if (_object != nullptr)
90 | {
91 | _object->Release();
92 | }
93 |
94 | _object = move._object;
95 | move._object = nullptr;
96 |
97 | return *this;
98 | }
99 |
100 | bool operator==(T *other) const
101 | {
102 | return _object == other;
103 | }
104 | bool operator==(const com_ptr &other) const
105 | {
106 | return _object == other._object;
107 | }
108 | friend bool operator==(T *left, const com_ptr &right)
109 | {
110 | return right.operator==(left);
111 | }
112 | bool operator!=(T *other) const
113 | {
114 | return _object != other;
115 | }
116 | bool operator!=(const com_ptr &other) const
117 | {
118 | return _object != other._object;
119 | }
120 | friend bool operator!=(T *left, const com_ptr &right)
121 | {
122 | return right.operator!=(left);
123 | }
124 |
125 | private:
126 | T *_object;
127 | };
128 |
--------------------------------------------------------------------------------
/source/d3d10/d3d10.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #include "log.hpp"
7 | #include "hook_manager.hpp"
8 | #include "d3d10_device.hpp"
9 | #include "../dxgi/dxgi_device.hpp"
10 |
11 | // D3D10
12 | HOOK_EXPORT HRESULT WINAPI D3D10CreateDevice(IDXGIAdapter *pAdapter, D3D10_DRIVER_TYPE DriverType, HMODULE Software, UINT Flags, UINT SDKVersion, ID3D10Device **ppDevice)
13 | {
14 | LOG(INFO) << "Redirecting '" << "D3D10CreateDevice" << "(" << pAdapter << ", " << DriverType << ", " << Software << ", " << std::hex << Flags << std::dec << ", " << SDKVersion << ", " << ppDevice << ")' ...";
15 | LOG(INFO) << "> Passing on to 'D3D10CreateDeviceAndSwapChain1':";
16 |
17 | LoadLibraryW(L"d3d10_1.dll");
18 |
19 | return D3D10CreateDeviceAndSwapChain1(pAdapter, DriverType, Software, Flags, D3D10_FEATURE_LEVEL_10_0, D3D10_1_SDK_VERSION, nullptr, nullptr, reinterpret_cast(ppDevice));
20 | }
21 | HOOK_EXPORT HRESULT WINAPI D3D10CreateDevice1(IDXGIAdapter *pAdapter, D3D10_DRIVER_TYPE DriverType, HMODULE Software, UINT Flags, D3D10_FEATURE_LEVEL1 HardwareLevel, UINT SDKVersion, ID3D10Device1 **ppDevice)
22 | {
23 | LOG(INFO) << "Redirecting '" << "D3D10CreateDevice1" << "(" << pAdapter << ", " << DriverType << ", " << Software << ", " << std::hex << Flags << std::dec << ", " << HardwareLevel << ", " << SDKVersion << ", " << ppDevice << ")' ...";
24 | LOG(INFO) << "> Passing on to 'D3D10CreateDeviceAndSwapChain1':";
25 |
26 | return D3D10CreateDeviceAndSwapChain1(pAdapter, DriverType, Software, Flags, HardwareLevel, SDKVersion, nullptr, nullptr, ppDevice);
27 | }
28 | HOOK_EXPORT HRESULT WINAPI D3D10CreateDeviceAndSwapChain(IDXGIAdapter *pAdapter, D3D10_DRIVER_TYPE DriverType, HMODULE Software, UINT Flags, UINT SDKVersion, DXGI_SWAP_CHAIN_DESC *pSwapChainDesc, IDXGISwapChain **ppSwapChain, ID3D10Device **ppDevice)
29 | {
30 | LOG(INFO) << "Redirecting '" << "D3D10CreateDeviceAndSwapChain" << "(" << pAdapter << ", " << DriverType << ", " << Software << ", " << std::hex << Flags << std::dec << ", " << SDKVersion << ", " << pSwapChainDesc << ", " << ppSwapChain << ", " << ppDevice << ")' ...";
31 | LOG(INFO) << "> Passing on to 'D3D10CreateDeviceAndSwapChain1':";
32 |
33 | LoadLibraryW(L"d3d10_1.dll");
34 |
35 | return D3D10CreateDeviceAndSwapChain1(pAdapter, DriverType, Software, Flags, D3D10_FEATURE_LEVEL_10_0, D3D10_1_SDK_VERSION, pSwapChainDesc, ppSwapChain, reinterpret_cast(ppDevice));
36 | }
37 | HOOK_EXPORT HRESULT WINAPI D3D10CreateDeviceAndSwapChain1(IDXGIAdapter *pAdapter, D3D10_DRIVER_TYPE DriverType, HMODULE Software, UINT Flags, D3D10_FEATURE_LEVEL1 HardwareLevel, UINT SDKVersion, DXGI_SWAP_CHAIN_DESC *pSwapChainDesc, IDXGISwapChain **ppSwapChain, ID3D10Device1 **ppDevice)
38 | {
39 | LOG(INFO) << "Redirecting '" << "D3D10CreateDeviceAndSwapChain1" << "(" << pAdapter << ", " << DriverType << ", " << Software << ", " << std::hex << Flags << ", " << HardwareLevel << std::dec << ", " << SDKVersion << ", " << pSwapChainDesc << ", " << ppSwapChain << ", " << ppDevice << ")' ...";
40 |
41 | #ifdef _DEBUG
42 | Flags |= D3D10_CREATE_DEVICE_DEBUG;
43 | Flags &= ~D3D10_CREATE_DEVICE_PREVENT_ALTERING_LAYER_SETTINGS_FROM_REGISTRY;
44 | #endif
45 |
46 | HRESULT hr = reshade::hooks::call(&D3D10CreateDeviceAndSwapChain1)(pAdapter, DriverType, Software, Flags, HardwareLevel, SDKVersion, nullptr, nullptr, ppDevice);
47 |
48 | if (FAILED(hr))
49 | {
50 | LOG(WARNING) << "> 'D3D10CreateDeviceAndSwapChain1' failed with error code " << std::hex << hr << std::dec << "!";
51 |
52 | return hr;
53 | }
54 |
55 | if (ppDevice != nullptr)
56 | {
57 | IDXGIDevice1 *dxgidevice = nullptr;
58 | ID3D10Device1 *const device = *ppDevice;
59 |
60 | assert(device != nullptr);
61 |
62 | device->QueryInterface(&dxgidevice);
63 |
64 | assert(dxgidevice != nullptr);
65 |
66 | const auto device_proxy = new D3D10Device(device);
67 | device_proxy->_dxgi_device = new DXGIDevice(dxgidevice, device_proxy);
68 |
69 | if (pSwapChainDesc != nullptr)
70 | {
71 | assert(ppSwapChain != nullptr);
72 |
73 | if (pAdapter != nullptr)
74 | {
75 | pAdapter->AddRef();
76 | }
77 | else
78 | {
79 | hr = device_proxy->_dxgi_device->GetAdapter(&pAdapter);
80 |
81 | assert(SUCCEEDED(hr));
82 | }
83 |
84 | IDXGIFactory *factory = nullptr;
85 |
86 | hr = pAdapter->GetParent(IID_PPV_ARGS(&factory));
87 |
88 | assert(SUCCEEDED(hr));
89 |
90 | LOG(INFO) << "> Calling 'IDXGIFactory::CreateSwapChain':";
91 |
92 | hr = factory->CreateSwapChain(device_proxy, pSwapChainDesc, ppSwapChain);
93 |
94 | factory->Release();
95 | pAdapter->Release();
96 | }
97 |
98 | if (SUCCEEDED(hr))
99 | {
100 | LOG(INFO) << "Returning 'IDXGIDevice1' object " << device_proxy->_dxgi_device;
101 | LOG(INFO) << "Returning 'ID3D10Device1' object " << device_proxy;
102 |
103 | *ppDevice = device_proxy;
104 | }
105 | else
106 | {
107 | device_proxy->Release();
108 | }
109 | }
110 |
111 | return hr;
112 | }
113 |
--------------------------------------------------------------------------------
/source/d3d10/d3d10.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #pragma once
7 |
8 | #include "d3d10_runtime.hpp"
9 |
10 | struct __declspec(uuid("88399375-734F-4892-A95F-70DD42CE7CDD")) D3D10Device;
11 |
--------------------------------------------------------------------------------
/source/d3d10/d3d10_effect_compiler.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #pragma once
7 |
8 | #include "effect_syntax_tree.hpp"
9 | #include
10 |
11 | namespace reshade::d3d10
12 | {
13 | #pragma region Forward Declarations
14 | struct d3d10_pass_data;
15 | class d3d10_runtime;
16 | #pragma endregion
17 |
18 | class d3d10_effect_compiler
19 | {
20 | public:
21 | d3d10_effect_compiler(d3d10_runtime *runtime, const reshadefx::syntax_tree &ast, std::string &errors, bool skipoptimization = false);
22 |
23 | bool run();
24 |
25 | private:
26 | void error(const reshadefx::location &location, const std::string &message);
27 | void warning(const reshadefx::location &location, const std::string &message);
28 |
29 | void visit(std::stringstream &output, const reshadefx::nodes::statement_node *node);
30 | void visit(std::stringstream &output, const reshadefx::nodes::expression_node *node);
31 | void visit(std::stringstream &output, const reshadefx::nodes::type_node &type, bool with_qualifiers = true);
32 | void visit(std::stringstream &output, const reshadefx::nodes::lvalue_expression_node *node);
33 | void visit(std::stringstream &output, const reshadefx::nodes::literal_expression_node *node);
34 | void visit(std::stringstream &output, const reshadefx::nodes::expression_sequence_node *node);
35 | void visit(std::stringstream &output, const reshadefx::nodes::unary_expression_node *node);
36 | void visit(std::stringstream &output, const reshadefx::nodes::binary_expression_node *node);
37 | void visit(std::stringstream &output, const reshadefx::nodes::intrinsic_expression_node *node);
38 | void visit(std::stringstream &output, const reshadefx::nodes::conditional_expression_node *node);
39 | void visit(std::stringstream &output, const reshadefx::nodes::swizzle_expression_node *node);
40 | void visit(std::stringstream &output, const reshadefx::nodes::field_expression_node *node);
41 | void visit(std::stringstream &output, const reshadefx::nodes::assignment_expression_node *node);
42 | void visit(std::stringstream &output, const reshadefx::nodes::call_expression_node *node);
43 | void visit(std::stringstream &output, const reshadefx::nodes::constructor_expression_node *node);
44 | void visit(std::stringstream &output, const reshadefx::nodes::initializer_list_node *node);
45 | void visit(std::stringstream &output, const reshadefx::nodes::compound_statement_node *node);
46 | void visit(std::stringstream &output, const reshadefx::nodes::declarator_list_node *node, bool single_statement);
47 | void visit(std::stringstream &output, const reshadefx::nodes::expression_statement_node *node);
48 | void visit(std::stringstream &output, const reshadefx::nodes::if_statement_node *node);
49 | void visit(std::stringstream &output, const reshadefx::nodes::switch_statement_node *node);
50 | void visit(std::stringstream &output, const reshadefx::nodes::case_statement_node *node);
51 | void visit(std::stringstream &output, const reshadefx::nodes::for_statement_node *node);
52 | void visit(std::stringstream &output, const reshadefx::nodes::while_statement_node *node);
53 | void visit(std::stringstream &output, const reshadefx::nodes::return_statement_node *node);
54 | void visit(std::stringstream &output, const reshadefx::nodes::jump_statement_node *node);
55 | void visit(std::stringstream &output, const reshadefx::nodes::struct_declaration_node *node);
56 | void visit(std::stringstream &output, const reshadefx::nodes::variable_declaration_node *node, bool with_type = true);
57 | void visit(std::stringstream &output, const reshadefx::nodes::function_declaration_node *node);
58 |
59 | void visit_texture(const reshadefx::nodes::variable_declaration_node *node);
60 | void visit_sampler(const reshadefx::nodes::variable_declaration_node *node);
61 | void visit_uniform(const reshadefx::nodes::variable_declaration_node *node);
62 | void visit_technique(const reshadefx::nodes::technique_declaration_node *node);
63 | void visit_pass(const reshadefx::nodes::pass_declaration_node *node, d3d10_pass_data &pass);
64 | void visit_pass_shader(const reshadefx::nodes::function_declaration_node *node, const std::string &shadertype, d3d10_pass_data &pass);
65 |
66 | d3d10_runtime *_runtime;
67 | bool _success = true;
68 | const reshadefx::syntax_tree &_ast;
69 | std::string &_errors;
70 | std::stringstream _global_code, _global_uniforms;
71 | bool _skip_shader_optimization, _is_in_parameter_block = false, _is_in_function_block = false;
72 | size_t _uniform_storage_offset = 0, _constant_buffer_size = 0;
73 | HMODULE _d3dcompiler_module = nullptr;
74 | };
75 | }
76 |
--------------------------------------------------------------------------------
/source/d3d10/d3d10_runtime.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #pragma once
7 |
8 | #include
9 | #include "runtime.hpp"
10 | #include "d3d10_stateblock.hpp"
11 |
12 | namespace reshade::d3d10
13 | {
14 | struct d3d10_tex_data : base_object
15 | {
16 | com_ptr texture;
17 | com_ptr srv[2];
18 | com_ptr rtv[2];
19 | };
20 | struct d3d10_pass_data : base_object
21 | {
22 | com_ptr vertex_shader;
23 | com_ptr pixel_shader;
24 | com_ptr blend_state;
25 | com_ptr depth_stencil_state;
26 | UINT stencil_reference;
27 | bool clear_render_targets;
28 | com_ptr render_targets[D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT];
29 | com_ptr render_target_resources[D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT];
30 | D3D10_VIEWPORT viewport;
31 | std::vector> shader_resources;
32 | };
33 | struct d3d10_technique_data : base_object
34 | {
35 | bool query_in_flight = false;
36 | com_ptr timestamp_disjoint;
37 | com_ptr timestamp_query_beg;
38 | com_ptr timestamp_query_end;
39 | };
40 |
41 | class d3d10_runtime : public runtime
42 | {
43 | public:
44 | d3d10_runtime(ID3D10Device1 *device, IDXGISwapChain *swapchain);
45 |
46 | bool on_init(const DXGI_SWAP_CHAIN_DESC &desc);
47 | void on_reset();
48 | void on_reset_effect() override;
49 | static void do_draw_fx(void* runtime);
50 | void draw_fx();
51 | void on_present();
52 | void on_draw_call(UINT vertices);
53 | void on_set_depthstencil_view(ID3D10DepthStencilView *&depthstencil);
54 | void on_get_depthstencil_view(ID3D10DepthStencilView *&depthstencil);
55 | void on_clear_depthstencil_view(ID3D10DepthStencilView *&depthstencil);
56 | void on_copy_resource(ID3D10Resource *&dest, ID3D10Resource *&source);
57 |
58 | void capture_frame(uint8_t *buffer) const override;
59 | bool load_effect(const reshadefx::syntax_tree &ast, std::string &errors) override;
60 | bool update_texture(texture &texture, const uint8_t *data) override;
61 |
62 | void render_technique(const technique &technique) override;
63 | void render_imgui_draw_data(ImDrawData *data) override;
64 |
65 | com_ptr _device;
66 | com_ptr _swapchain;
67 |
68 | com_ptr _backbuffer_texture;
69 | com_ptr _backbuffer_rtv[3];
70 | com_ptr _backbuffer_texture_srv[2], _depthstencil_texture_srv;
71 | std::vector> _effect_sampler_states;
72 | std::unordered_map _effect_sampler_descs;
73 | std::vector> _effect_shader_resources;
74 | std::vector> _constant_buffers;
75 |
76 | private:
77 | struct depth_source_info
78 | {
79 | UINT width, height;
80 | UINT drawcall_count, vertices_count;
81 | };
82 |
83 | bool init_backbuffer_texture();
84 | bool init_default_depth_stencil();
85 | bool init_fx_resources();
86 | bool init_imgui_resources();
87 | bool init_imgui_font_atlas();
88 |
89 | void detect_depth_source();
90 | bool create_depthstencil_replacement(ID3D10DepthStencilView *depthstencil);
91 |
92 | bool _is_multisampling_enabled = false;
93 | DXGI_FORMAT _backbuffer_format = DXGI_FORMAT_UNKNOWN;
94 | d3d10_stateblock _stateblock;
95 | com_ptr _backbuffer, _backbuffer_resolved;
96 | com_ptr _depthstencil, _depthstencil_replacement;
97 | com_ptr _depthstencil_texture;
98 | com_ptr _default_depthstencil;
99 | std::unordered_map _depth_source_table;
100 | com_ptr _copy_vertex_shader;
101 | com_ptr _copy_pixel_shader;
102 | com_ptr _copy_sampler;
103 | com_ptr _effect_rasterizer_state;
104 |
105 | com_ptr _imgui_vertex_buffer, _imgui_index_buffer;
106 | com_ptr _imgui_vertex_shader;
107 | com_ptr _imgui_pixel_shader;
108 | com_ptr _imgui_input_layout;
109 | com_ptr _imgui_constant_buffer;
110 | com_ptr _imgui_texture_sampler;
111 | com_ptr _imgui_rasterizer_state;
112 | com_ptr _imgui_blend_state;
113 | com_ptr _imgui_depthstencil_state;
114 | int _imgui_vertex_buffer_size = 0, _imgui_index_buffer_size = 0;
115 | };
116 | }
117 |
--------------------------------------------------------------------------------
/source/d3d10/d3d10_stateblock.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #include "d3d10_stateblock.hpp"
7 |
8 | namespace reshade::d3d10
9 | {
10 | template
11 | static inline void safe_release(T *&object)
12 | {
13 | if (object != nullptr)
14 | {
15 | object->Release();
16 | object = nullptr;
17 | }
18 | }
19 |
20 | d3d10_stateblock::d3d10_stateblock(const com_ptr &device)
21 | {
22 | ZeroMemory(this, sizeof(*this));
23 |
24 | _device = device;
25 | }
26 | d3d10_stateblock::~d3d10_stateblock()
27 | {
28 | release_all_device_objects();
29 | }
30 |
31 | void d3d10_stateblock::capture()
32 | {
33 | _device->IAGetPrimitiveTopology(&_ia_primitive_topology);
34 | _device->IAGetInputLayout(&_ia_input_layout);
35 |
36 | _device->IAGetVertexBuffers(0, ARRAYSIZE(_ia_vertex_buffers), _ia_vertex_buffers, _ia_vertex_strides, _ia_vertex_offsets);
37 | _device->IAGetIndexBuffer(&_ia_index_buffer, &_ia_index_format, &_ia_index_offset);
38 |
39 | _device->RSGetState(&_rs_state);
40 | _device->RSGetViewports(&_rs_num_viewports, nullptr);
41 | _device->RSGetViewports(&_rs_num_viewports, _rs_viewports);
42 |
43 | _device->VSGetShader(&_vs);
44 | _device->VSGetConstantBuffers(0, ARRAYSIZE(_vs_constant_buffers), _vs_constant_buffers);
45 | _device->VSGetSamplers(0, ARRAYSIZE(_vs_sampler_states), _vs_sampler_states);
46 | _device->VSGetShaderResources(0, ARRAYSIZE(_vs_shader_resources), _vs_shader_resources);
47 |
48 | _device->GSGetShader(&_gs);
49 |
50 | _device->PSGetShader(&_ps);
51 | _device->PSGetConstantBuffers(0, ARRAYSIZE(_ps_constant_buffers), _ps_constant_buffers);
52 | _device->PSGetSamplers(0, ARRAYSIZE(_ps_sampler_states), _ps_sampler_states);
53 | _device->PSGetShaderResources(0, ARRAYSIZE(_ps_shader_resources), _ps_shader_resources);
54 |
55 | _device->OMGetBlendState(&_om_blend_state, _om_blend_factor, &_om_sample_mask);
56 | _device->OMGetDepthStencilState(&_om_depth_stencil_state, &_om_stencil_ref);
57 | _device->OMGetRenderTargets(ARRAYSIZE(_om_render_targets), _om_render_targets, &_om_depth_stencil);
58 | }
59 | void d3d10_stateblock::apply_and_release()
60 | {
61 | _device->IASetPrimitiveTopology(_ia_primitive_topology);
62 | _device->IASetInputLayout(_ia_input_layout);
63 |
64 | _device->IASetVertexBuffers(0, ARRAYSIZE(_ia_vertex_buffers), _ia_vertex_buffers, _ia_vertex_strides, _ia_vertex_offsets);
65 | _device->IASetIndexBuffer(_ia_index_buffer, _ia_index_format, _ia_index_offset);
66 |
67 | _device->RSSetState(_rs_state);
68 | _device->RSSetViewports(_rs_num_viewports, _rs_viewports);
69 |
70 | _device->VSSetShader(_vs);
71 | _device->VSSetConstantBuffers(0, ARRAYSIZE(_vs_constant_buffers), _vs_constant_buffers);
72 | _device->VSSetSamplers(0, ARRAYSIZE(_vs_sampler_states), _vs_sampler_states);
73 | _device->VSSetShaderResources(0, ARRAYSIZE(_vs_shader_resources), _vs_shader_resources);
74 |
75 | _device->GSSetShader(_gs);
76 |
77 | _device->PSSetShader(_ps);
78 | _device->PSSetConstantBuffers(0, ARRAYSIZE(_ps_constant_buffers), _ps_constant_buffers);
79 | _device->PSSetSamplers(0, ARRAYSIZE(_ps_sampler_states), _ps_sampler_states);
80 | _device->PSSetShaderResources(0, ARRAYSIZE(_ps_shader_resources), _ps_shader_resources);
81 |
82 | _device->OMSetBlendState(_om_blend_state, _om_blend_factor, _om_sample_mask);
83 | _device->OMSetDepthStencilState(_om_depth_stencil_state, _om_stencil_ref);
84 | _device->OMSetRenderTargets(ARRAYSIZE(_om_render_targets), _om_render_targets, _om_depth_stencil);
85 |
86 | release_all_device_objects();
87 | }
88 |
89 | void d3d10_stateblock::release_all_device_objects()
90 | {
91 | safe_release(_ia_input_layout);
92 |
93 | for (auto &vertex_buffer : _ia_vertex_buffers)
94 | {
95 | safe_release(vertex_buffer);
96 | }
97 |
98 | safe_release(_ia_index_buffer);
99 |
100 | safe_release(_vs);
101 |
102 | for (auto &constant_buffer : _vs_constant_buffers)
103 | {
104 | safe_release(constant_buffer);
105 | }
106 | for (auto &sampler_state : _vs_sampler_states)
107 | {
108 | safe_release(sampler_state);
109 | }
110 | for (auto &shader_resource : _vs_shader_resources)
111 | {
112 | safe_release(shader_resource);
113 | }
114 |
115 | safe_release(_gs);
116 |
117 | safe_release(_rs_state);
118 |
119 | safe_release(_ps);
120 |
121 | for (auto &constant_buffer : _ps_constant_buffers)
122 | {
123 | safe_release(constant_buffer);
124 | }
125 | for (auto &sampler_state : _ps_sampler_states)
126 | {
127 | safe_release(sampler_state);
128 | }
129 | for (auto &shader_resource : _ps_shader_resources)
130 | {
131 | safe_release(shader_resource);
132 | }
133 |
134 | safe_release(_om_blend_state);
135 | safe_release(_om_depth_stencil_state);
136 |
137 | for (auto &render_target : _om_render_targets)
138 | {
139 | safe_release(render_target);
140 | }
141 |
142 | safe_release(_om_depth_stencil);
143 | }
144 | }
145 |
--------------------------------------------------------------------------------
/source/d3d10/d3d10_stateblock.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #pragma once
7 |
8 | #include
9 | #include
10 |
11 | namespace reshade::d3d10
12 | {
13 | class d3d10_stateblock
14 | {
15 | public:
16 | explicit d3d10_stateblock(const com_ptr &device);
17 | ~d3d10_stateblock();
18 |
19 | void capture();
20 | void apply_and_release();
21 |
22 | private:
23 | void release_all_device_objects();
24 |
25 | com_ptr _device;
26 | ID3D10InputLayout *_ia_input_layout;
27 | D3D10_PRIMITIVE_TOPOLOGY _ia_primitive_topology;
28 | ID3D10Buffer *_ia_vertex_buffers[D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT];
29 | UINT _ia_vertex_strides[D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT];
30 | UINT _ia_vertex_offsets[D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT];
31 | ID3D10Buffer *_ia_index_buffer;
32 | DXGI_FORMAT _ia_index_format;
33 | UINT _ia_index_offset;
34 | ID3D10VertexShader *_vs;
35 | ID3D10Buffer *_vs_constant_buffers[D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT];
36 | ID3D10SamplerState *_vs_sampler_states[D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT];
37 | ID3D10ShaderResourceView *_vs_shader_resources[D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT];
38 | ID3D10GeometryShader *_gs;
39 | ID3D10RasterizerState *_rs_state;
40 | UINT _rs_num_viewports;
41 | D3D10_VIEWPORT _rs_viewports[D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE];
42 | ID3D10PixelShader *_ps;
43 | ID3D10Buffer *_ps_constant_buffers[D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT];
44 | ID3D10SamplerState *_ps_sampler_states[D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT];
45 | ID3D10ShaderResourceView *_ps_shader_resources[D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT];
46 | ID3D10BlendState *_om_blend_state;
47 | FLOAT _om_blend_factor[4];
48 | UINT _om_sample_mask;
49 | ID3D10DepthStencilState *_om_depth_stencil_state;
50 | UINT _om_stencil_ref;
51 | ID3D10RenderTargetView *_om_render_targets[D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT];
52 | ID3D10DepthStencilView *_om_depth_stencil;
53 | };
54 | }
55 |
--------------------------------------------------------------------------------
/source/d3d11/d3d11.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #include "log.hpp"
7 | #include "hook_manager.hpp"
8 | #include "d3d11_device.hpp"
9 | #include "d3d11_device_context.hpp"
10 | #include "../dxgi/dxgi_device.hpp"
11 |
12 | // D3D11
13 | HOOK_EXPORT HRESULT WINAPI D3D11CreateDevice(IDXGIAdapter *pAdapter, D3D_DRIVER_TYPE DriverType, HMODULE Software, UINT Flags, const D3D_FEATURE_LEVEL *pFeatureLevels, UINT FeatureLevels, UINT SDKVersion, ID3D11Device **ppDevice, D3D_FEATURE_LEVEL *pFeatureLevel, ID3D11DeviceContext **ppImmediateContext)
14 | {
15 | LOG(INFO) << "Redirecting '" << "D3D11CreateDevice" << "(" << pAdapter << ", " << DriverType << ", " << Software << ", " << std::hex << Flags << std::dec << ", " << pFeatureLevels << ", " << FeatureLevels << ", " << SDKVersion << ", " << ppDevice << ", " << pFeatureLevel << ", " << ppImmediateContext << ")' ...";
16 | LOG(INFO) << "> Passing on to 'D3D11CreateDeviceAndSwapChain':";
17 |
18 | return D3D11CreateDeviceAndSwapChain(pAdapter, DriverType, Software, Flags, pFeatureLevels, FeatureLevels, SDKVersion, nullptr, nullptr, ppDevice, pFeatureLevel, ppImmediateContext);
19 | }
20 | HOOK_EXPORT HRESULT WINAPI D3D11CreateDeviceAndSwapChain(IDXGIAdapter *pAdapter, D3D_DRIVER_TYPE DriverType, HMODULE Software, UINT Flags, const D3D_FEATURE_LEVEL *pFeatureLevels, UINT FeatureLevels, UINT SDKVersion, const DXGI_SWAP_CHAIN_DESC *pSwapChainDesc, IDXGISwapChain **ppSwapChain, ID3D11Device **ppDevice, D3D_FEATURE_LEVEL *pFeatureLevel, ID3D11DeviceContext **ppImmediateContext)
21 | {
22 | LOG(INFO) << "Redirecting '" << "D3D11CreateDeviceAndSwapChain" << "(" << pAdapter << ", " << DriverType << ", " << Software << ", " << std::hex << Flags << std::dec << ", " << pFeatureLevels << ", " << FeatureLevels << ", " << SDKVersion << ", " << pSwapChainDesc << ", " << ppSwapChain << ", " << ppDevice << ", " << pFeatureLevel << ", " << ppImmediateContext << ")' ...";
23 |
24 | #ifdef _DEBUG
25 | Flags |= D3D11_CREATE_DEVICE_DEBUG;
26 | Flags &= ~D3D11_CREATE_DEVICE_PREVENT_ALTERING_LAYER_SETTINGS_FROM_REGISTRY;
27 | #endif
28 |
29 | D3D_FEATURE_LEVEL FeatureLevel = D3D_FEATURE_LEVEL_11_0;
30 |
31 | HRESULT hr = reshade::hooks::call(&D3D11CreateDeviceAndSwapChain)(pAdapter, DriverType, Software, Flags, pFeatureLevels, FeatureLevels, SDKVersion, nullptr, nullptr, ppDevice, &FeatureLevel, nullptr);
32 |
33 | if (FAILED(hr))
34 | {
35 | LOG(WARNING) << "> 'D3D11CreateDeviceAndSwapChain' failed with error code " << std::hex << hr << std::dec << "!";
36 |
37 | return hr;
38 | }
39 |
40 | LOG(INFO) << "> Using feature level " << std::hex << FeatureLevel << std::dec << ".";
41 |
42 | if (ppDevice != nullptr)
43 | {
44 | IDXGIDevice1 *dxgidevice = nullptr;
45 | ID3D11Device *const device = *ppDevice;
46 | ID3D11DeviceContext *devicecontext = nullptr;
47 |
48 | assert(device != nullptr);
49 |
50 | device->QueryInterface(&dxgidevice);
51 | device->GetImmediateContext(&devicecontext);
52 |
53 | assert(dxgidevice != nullptr);
54 | assert(devicecontext != nullptr);
55 |
56 | const auto device_proxy = new D3D11Device(device);
57 | const auto devicecontext_proxy = new D3D11DeviceContext(device_proxy, devicecontext);
58 | device_proxy->_dxgi_device = new DXGIDevice(dxgidevice, device_proxy);
59 | device_proxy->_immediate_context = devicecontext_proxy;
60 |
61 | if (pSwapChainDesc != nullptr)
62 | {
63 | assert(ppSwapChain != nullptr);
64 |
65 | if (pAdapter != nullptr)
66 | {
67 | pAdapter->AddRef();
68 | }
69 | else
70 | {
71 | hr = device_proxy->_dxgi_device->GetAdapter(&pAdapter);
72 |
73 | assert(SUCCEEDED(hr));
74 | }
75 |
76 | IDXGIFactory *factory = nullptr;
77 |
78 | hr = pAdapter->GetParent(IID_PPV_ARGS(&factory));
79 |
80 | assert(SUCCEEDED(hr));
81 |
82 | LOG(INFO) << "> Calling 'IDXGIFactory::CreateSwapChain':";
83 |
84 | hr = factory->CreateSwapChain(device_proxy, const_cast(pSwapChainDesc), ppSwapChain);
85 |
86 | factory->Release();
87 | pAdapter->Release();
88 | }
89 |
90 | if (SUCCEEDED(hr))
91 | {
92 | LOG(INFO) << "Returning 'IDXGIDevice1' object " << device_proxy->_dxgi_device;
93 | LOG(INFO) << "Returning 'ID3D11Device' object " << device_proxy;
94 |
95 | *ppDevice = device_proxy;
96 |
97 | if (ppImmediateContext != nullptr)
98 | {
99 | LOG(INFO) << "Returning 'ID3D11DeviceContext' object " << devicecontext_proxy;
100 |
101 | devicecontext_proxy->AddRef();
102 | *ppImmediateContext = devicecontext_proxy;
103 | }
104 | }
105 | else
106 | {
107 | device_proxy->Release();
108 | }
109 | }
110 |
111 | if (pFeatureLevel != nullptr)
112 | {
113 | *pFeatureLevel = FeatureLevel;
114 | }
115 |
116 | return hr;
117 | }
118 |
--------------------------------------------------------------------------------
/source/d3d11/d3d11.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #pragma once
7 |
8 | #include "d3d11_runtime.hpp"
9 |
10 | struct __declspec(uuid("72299288-2C68-4AD8-945D-2BFB5AA9C609")) D3D11Device;
11 | struct __declspec(uuid("27B0246B-2152-4D42-AD11-32489472238F")) D3D11DeviceContext;
12 |
--------------------------------------------------------------------------------
/source/d3d11/d3d11_effect_compiler.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #pragma once
7 |
8 | #include "effect_syntax_tree.hpp"
9 | #include
10 |
11 | namespace reshade::d3d11
12 | {
13 | #pragma region Forward Declarations
14 | struct d3d11_pass_data;
15 | class d3d11_runtime;
16 | #pragma endregion
17 |
18 | class d3d11_effect_compiler
19 | {
20 | public:
21 | d3d11_effect_compiler(d3d11_runtime *runtime, const reshadefx::syntax_tree &ast, std::string &errors, bool skipoptimization = false);
22 |
23 | bool run();
24 |
25 | private:
26 | void error(const reshadefx::location &location, const std::string &message);
27 | void warning(const reshadefx::location &location, const std::string &message);
28 |
29 | void visit(std::stringstream &output, const reshadefx::nodes::statement_node *node);
30 | void visit(std::stringstream &output, const reshadefx::nodes::expression_node *node);
31 | void visit(std::stringstream &output, const reshadefx::nodes::type_node &type, bool with_qualifiers = true);
32 | void visit(std::stringstream &output, const reshadefx::nodes::lvalue_expression_node *node);
33 | void visit(std::stringstream &output, const reshadefx::nodes::literal_expression_node *node);
34 | void visit(std::stringstream &output, const reshadefx::nodes::expression_sequence_node *node);
35 | void visit(std::stringstream &output, const reshadefx::nodes::unary_expression_node *node);
36 | void visit(std::stringstream &output, const reshadefx::nodes::binary_expression_node *node);
37 | void visit(std::stringstream &output, const reshadefx::nodes::intrinsic_expression_node *node);
38 | void visit(std::stringstream &output, const reshadefx::nodes::conditional_expression_node *node);
39 | void visit(std::stringstream &output, const reshadefx::nodes::swizzle_expression_node *node);
40 | void visit(std::stringstream &output, const reshadefx::nodes::field_expression_node *node);
41 | void visit(std::stringstream &output, const reshadefx::nodes::assignment_expression_node *node);
42 | void visit(std::stringstream &output, const reshadefx::nodes::call_expression_node *node);
43 | void visit(std::stringstream &output, const reshadefx::nodes::constructor_expression_node *node);
44 | void visit(std::stringstream &output, const reshadefx::nodes::initializer_list_node *node);
45 | void visit(std::stringstream &output, const reshadefx::nodes::compound_statement_node *node);
46 | void visit(std::stringstream &output, const reshadefx::nodes::declarator_list_node *node, bool single_statement);
47 | void visit(std::stringstream &output, const reshadefx::nodes::expression_statement_node *node);
48 | void visit(std::stringstream &output, const reshadefx::nodes::if_statement_node *node);
49 | void visit(std::stringstream &output, const reshadefx::nodes::switch_statement_node *node);
50 | void visit(std::stringstream &output, const reshadefx::nodes::case_statement_node *node);
51 | void visit(std::stringstream &output, const reshadefx::nodes::for_statement_node *node);
52 | void visit(std::stringstream &output, const reshadefx::nodes::while_statement_node *node);
53 | void visit(std::stringstream &output, const reshadefx::nodes::return_statement_node *node);
54 | void visit(std::stringstream &output, const reshadefx::nodes::jump_statement_node *node);
55 | void visit(std::stringstream &output, const reshadefx::nodes::struct_declaration_node *node);
56 | void visit(std::stringstream &output, const reshadefx::nodes::variable_declaration_node *node, bool with_type = true);
57 | void visit(std::stringstream &output, const reshadefx::nodes::function_declaration_node *node);
58 |
59 | void visit_texture(const reshadefx::nodes::variable_declaration_node *node);
60 | void visit_sampler(const reshadefx::nodes::variable_declaration_node *node);
61 | void visit_uniform(const reshadefx::nodes::variable_declaration_node *node);
62 | void visit_technique(const reshadefx::nodes::technique_declaration_node *node);
63 | void visit_pass(const reshadefx::nodes::pass_declaration_node *node, d3d11_pass_data &pass);
64 | void visit_pass_shader(const reshadefx::nodes::function_declaration_node *node, const std::string &shadertype, d3d11_pass_data &pass);
65 |
66 | d3d11_runtime *_runtime;
67 | bool _success = true;
68 | const reshadefx::syntax_tree &_ast;
69 | std::string &_errors;
70 | std::stringstream _global_code, _global_uniforms;
71 | bool _skip_shader_optimization, _is_in_parameter_block = false, _is_in_function_block = false;
72 | size_t _uniform_storage_offset = 0, _constant_buffer_size = 0;
73 | HMODULE _d3dcompiler_module = nullptr;
74 | };
75 | }
76 |
--------------------------------------------------------------------------------
/source/d3d11/d3d11_runtime.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #pragma once
7 |
8 | #include
9 | #include
10 | #include "runtime.hpp"
11 | #include "d3d11_stateblock.hpp"
12 |
13 | namespace reshade::d3d11
14 | {
15 | struct d3d11_tex_data : base_object
16 | {
17 | com_ptr texture;
18 | com_ptr srv[2];
19 | com_ptr rtv[2];
20 | };
21 | struct d3d11_pass_data : base_object
22 | {
23 | com_ptr vertex_shader;
24 | com_ptr pixel_shader;
25 | com_ptr blend_state;
26 | com_ptr depth_stencil_state;
27 | UINT stencil_reference;
28 | bool clear_render_targets;
29 | com_ptr render_targets[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT];
30 | com_ptr render_target_resources[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT];
31 | D3D11_VIEWPORT viewport;
32 | std::vector> shader_resources;
33 | };
34 | struct d3d11_technique_data : base_object
35 | {
36 | bool query_in_flight = false;
37 | com_ptr timestamp_disjoint;
38 | com_ptr timestamp_query_beg;
39 | com_ptr timestamp_query_end;
40 | };
41 |
42 | class d3d11_runtime : public runtime
43 | {
44 | public:
45 | d3d11_runtime(ID3D11Device *device, IDXGISwapChain *swapchain);
46 |
47 | bool on_init(const DXGI_SWAP_CHAIN_DESC &desc);
48 | void on_reset();
49 | void on_reset_effect() override;
50 | static void do_draw_fx(void* runtime);
51 | void draw_fx();
52 | void on_present();
53 | void on_draw_call(ID3D11DeviceContext *context, unsigned int vertices);
54 | void on_set_depthstencil_view(ID3D11DepthStencilView *&depthstencil);
55 | void on_get_depthstencil_view(ID3D11DepthStencilView *&depthstencil);
56 | void on_clear_depthstencil_view(ID3D11DepthStencilView *&depthstencil);
57 | void on_copy_resource(ID3D11Resource *&dest, ID3D11Resource *&source);
58 |
59 | void capture_frame(uint8_t *buffer) const override;
60 | bool load_effect(const reshadefx::syntax_tree &ast, std::string &errors) override;
61 | bool update_texture(texture &texture, const uint8_t *data) override;
62 |
63 | void render_technique(const technique &technique) override;
64 | void render_imgui_draw_data(ImDrawData *data) override;
65 |
66 | com_ptr _device;
67 | com_ptr _immediate_context;
68 | com_ptr _swapchain;
69 |
70 | com_ptr _backbuffer_texture;
71 | com_ptr _backbuffer_texture_srv[2];
72 | com_ptr _backbuffer_rtv[3];
73 | com_ptr _depthstencil_texture_srv;
74 | std::vector> _effect_sampler_states;
75 | std::unordered_map _effect_sampler_descs;
76 | std::vector> _effect_shader_resources;
77 | std::vector> _constant_buffers;
78 |
79 | private:
80 | struct depth_source_info
81 | {
82 | UINT width, height;
83 | UINT drawcall_count, vertices_count;
84 | };
85 |
86 | bool init_backbuffer_texture();
87 | bool init_default_depth_stencil();
88 | bool init_fx_resources();
89 | bool init_imgui_resources();
90 | bool init_imgui_font_atlas();
91 |
92 | void detect_depth_source();
93 | bool create_depthstencil_replacement(ID3D11DepthStencilView *depthstencil);
94 |
95 | bool _is_multisampling_enabled = false;
96 | DXGI_FORMAT _backbuffer_format = DXGI_FORMAT_UNKNOWN;
97 | d3d11_stateblock _stateblock;
98 | com_ptr _backbuffer, _backbuffer_resolved;
99 | com_ptr _depthstencil, _depthstencil_replacement;
100 | com_ptr _depthstencil_texture;
101 | com_ptr _default_depthstencil;
102 | std::unordered_map _depth_source_table;
103 | com_ptr _copy_vertex_shader;
104 | com_ptr _copy_pixel_shader;
105 | com_ptr _copy_sampler;
106 | std::mutex _mutex;
107 | com_ptr _effect_rasterizer_state;
108 |
109 | com_ptr _imgui_vertex_buffer, _imgui_index_buffer;
110 | com_ptr _imgui_vertex_shader;
111 | com_ptr _imgui_pixel_shader;
112 | com_ptr _imgui_input_layout;
113 | com_ptr _imgui_constant_buffer;
114 | com_ptr _imgui_texture_sampler;
115 | com_ptr _imgui_rasterizer_state;
116 | com_ptr _imgui_blend_state;
117 | com_ptr _imgui_depthstencil_state;
118 | int _imgui_vertex_buffer_size = 0, _imgui_index_buffer_size = 0;
119 | };
120 | }
121 |
--------------------------------------------------------------------------------
/source/d3d11/d3d11_stateblock.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #include "d3d11_stateblock.hpp"
7 |
8 | namespace reshade::d3d11
9 | {
10 | template
11 | static inline void safe_release(T *&object)
12 | {
13 | if (object != nullptr)
14 | {
15 | object->Release();
16 | object = nullptr;
17 | }
18 | }
19 |
20 | d3d11_stateblock::d3d11_stateblock(const com_ptr &device)
21 | {
22 | ZeroMemory(this, sizeof(*this));
23 |
24 | _device = device;
25 | _device_feature_level = device->GetFeatureLevel();
26 | }
27 | d3d11_stateblock::~d3d11_stateblock()
28 | {
29 | release_all_device_objects();
30 | }
31 |
32 | void d3d11_stateblock::capture(const com_ptr &devicecontext)
33 | {
34 | _device_context = devicecontext;
35 |
36 | _device_context->IAGetPrimitiveTopology(&_ia_primitive_topology);
37 | _device_context->IAGetInputLayout(&_ia_input_layout);
38 |
39 | if (_device_feature_level > D3D_FEATURE_LEVEL_10_0)
40 | {
41 | _device_context->IAGetVertexBuffers(0, D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT, _ia_vertex_buffers, _ia_vertex_strides, _ia_vertex_offsets);
42 | }
43 | else
44 | {
45 | _device_context->IAGetVertexBuffers(0, D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT, _ia_vertex_buffers, _ia_vertex_strides, _ia_vertex_offsets);
46 | }
47 |
48 | _device_context->IAGetIndexBuffer(&_ia_index_buffer, &_ia_index_format, &_ia_index_offset);
49 |
50 | _device_context->RSGetState(&_rs_state);
51 | _device_context->RSGetViewports(&_rs_num_viewports, nullptr);
52 | _device_context->RSGetViewports(&_rs_num_viewports, _rs_viewports);
53 |
54 | _vs_num_class_instances = ARRAYSIZE(_vs_class_instances);
55 | _device_context->VSGetShader(&_vs, _vs_class_instances, &_vs_num_class_instances);
56 | _device_context->VSGetConstantBuffers(0, ARRAYSIZE(_vs_constant_buffers), _vs_constant_buffers);
57 | _device_context->VSGetSamplers(0, ARRAYSIZE(_vs_sampler_states), _vs_sampler_states);
58 | _device_context->VSGetShaderResources(0, ARRAYSIZE(_vs_shader_resources), _vs_shader_resources);
59 |
60 | if (_device_feature_level >= D3D_FEATURE_LEVEL_10_0)
61 | {
62 | if (_device_feature_level >= D3D_FEATURE_LEVEL_11_0)
63 | {
64 | _hs_num_class_instances = ARRAYSIZE(_hs_class_instances);
65 | _device_context->HSGetShader(&_hs, _hs_class_instances, &_hs_num_class_instances);
66 |
67 | _ds_num_class_instances = ARRAYSIZE(_ds_class_instances);
68 | _device_context->DSGetShader(&_ds, _ds_class_instances, &_ds_num_class_instances);
69 | }
70 |
71 | _gs_num_class_instances = ARRAYSIZE(_gs_class_instances);
72 | _device_context->GSGetShader(&_gs, _gs_class_instances, &_gs_num_class_instances);
73 | }
74 |
75 | _ps_num_class_instances = ARRAYSIZE(_ps_class_instances);
76 | _device_context->PSGetShader(&_ps, _ps_class_instances, &_ps_num_class_instances);
77 | _device_context->PSGetConstantBuffers(0, ARRAYSIZE(_ps_constant_buffers), _ps_constant_buffers);
78 | _device_context->PSGetSamplers(0, ARRAYSIZE(_ps_sampler_states), _ps_sampler_states);
79 | _device_context->PSGetShaderResources(0, ARRAYSIZE(_ps_shader_resources), _ps_shader_resources);
80 |
81 | _device_context->OMGetBlendState(&_om_blend_state, _om_blend_factor, &_om_sample_mask);
82 | _device_context->OMGetDepthStencilState(&_om_depth_stencil_state, &_om_stencil_ref);
83 | _device_context->OMGetRenderTargets(ARRAYSIZE(_om_render_targets), _om_render_targets, &_om_depth_stencil);
84 | }
85 | void d3d11_stateblock::apply_and_release()
86 | {
87 | _device_context->IASetPrimitiveTopology(_ia_primitive_topology);
88 | _device_context->IASetInputLayout(_ia_input_layout);
89 |
90 | if (_device_feature_level > D3D_FEATURE_LEVEL_10_0)
91 | {
92 | _device_context->IASetVertexBuffers(0, D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT, _ia_vertex_buffers, _ia_vertex_strides, _ia_vertex_offsets);
93 | }
94 | else
95 | {
96 | _device_context->IASetVertexBuffers(0, D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT, _ia_vertex_buffers, _ia_vertex_strides, _ia_vertex_offsets);
97 | }
98 |
99 | _device_context->IASetIndexBuffer(_ia_index_buffer, _ia_index_format, _ia_index_offset);
100 |
101 | _device_context->RSSetState(_rs_state);
102 | _device_context->RSSetViewports(_rs_num_viewports, _rs_viewports);
103 |
104 | _device_context->VSSetShader(_vs, _vs_class_instances, _vs_num_class_instances);
105 | _device_context->VSSetConstantBuffers(0, ARRAYSIZE(_vs_constant_buffers), _vs_constant_buffers);
106 | _device_context->VSSetSamplers(0, ARRAYSIZE(_vs_sampler_states), _vs_sampler_states);
107 | _device_context->VSSetShaderResources(0, ARRAYSIZE(_vs_shader_resources), _vs_shader_resources);
108 |
109 | if (_device_feature_level >= D3D_FEATURE_LEVEL_10_0)
110 | {
111 | if (_device_feature_level >= D3D_FEATURE_LEVEL_11_0)
112 | {
113 | _device_context->HSSetShader(_hs, _hs_class_instances, _hs_num_class_instances);
114 |
115 | _device_context->DSSetShader(_ds, _ds_class_instances, _ds_num_class_instances);
116 | }
117 |
118 | _device_context->GSSetShader(_gs, _gs_class_instances, _gs_num_class_instances);
119 | }
120 |
121 | _device_context->PSSetShader(_ps, _ps_class_instances, _ps_num_class_instances);
122 | _device_context->PSSetConstantBuffers(0, ARRAYSIZE(_ps_constant_buffers), _ps_constant_buffers);
123 | _device_context->PSSetSamplers(0, ARRAYSIZE(_ps_sampler_states), _ps_sampler_states);
124 | _device_context->PSSetShaderResources(0, ARRAYSIZE(_ps_shader_resources), _ps_shader_resources);
125 |
126 | _device_context->OMSetBlendState(_om_blend_state, _om_blend_factor, _om_sample_mask);
127 | _device_context->OMSetDepthStencilState(_om_depth_stencil_state, _om_stencil_ref);
128 | _device_context->OMSetRenderTargets(ARRAYSIZE(_om_render_targets), _om_render_targets, _om_depth_stencil);
129 |
130 | release_all_device_objects();
131 |
132 | _device_context.reset();
133 | }
134 |
135 | void d3d11_stateblock::release_all_device_objects()
136 | {
137 | safe_release(_ia_input_layout);
138 |
139 | for (auto &vertex_buffer : _ia_vertex_buffers)
140 | {
141 | safe_release(vertex_buffer);
142 | }
143 |
144 | safe_release(_ia_index_buffer);
145 |
146 | safe_release(_vs);
147 |
148 | for (UINT i = 0; i < _vs_num_class_instances; i++)
149 | {
150 | safe_release(_vs_class_instances[i]);
151 | }
152 | for (auto &constant_buffer : _vs_constant_buffers)
153 | {
154 | safe_release(constant_buffer);
155 | }
156 | for (auto &sampler_state : _vs_sampler_states)
157 | {
158 | safe_release(sampler_state);
159 | }
160 | for (auto &shader_resource : _vs_shader_resources)
161 | {
162 | safe_release(shader_resource);
163 | }
164 |
165 | safe_release(_hs);
166 |
167 | for (UINT i = 0; i < _hs_num_class_instances; i++)
168 | {
169 | safe_release(_hs_class_instances[i]);
170 | }
171 |
172 | safe_release(_ds);
173 |
174 | for (UINT i = 0; i < _ds_num_class_instances; i++)
175 | {
176 | safe_release(_ds_class_instances[i]);
177 | }
178 |
179 | safe_release(_gs);
180 |
181 | for (UINT i = 0; i < _gs_num_class_instances; i++)
182 | {
183 | safe_release(_gs_class_instances[i]);
184 | }
185 |
186 | safe_release(_rs_state);
187 |
188 | safe_release(_ps);
189 |
190 | for (UINT i = 0; i < _ps_num_class_instances; i++)
191 | {
192 | safe_release(_ps_class_instances[i]);
193 | }
194 | for (auto &constant_buffer : _ps_constant_buffers)
195 | {
196 | safe_release(constant_buffer);
197 | }
198 | for (auto &sampler_state : _ps_sampler_states)
199 | {
200 | safe_release(sampler_state);
201 | }
202 | for (auto &shader_resource : _ps_shader_resources)
203 | {
204 | safe_release(shader_resource);
205 | }
206 |
207 | safe_release(_om_blend_state);
208 | safe_release(_om_depth_stencil_state);
209 |
210 | for (auto &render_target : _om_render_targets)
211 | {
212 | safe_release(render_target);
213 | }
214 |
215 | safe_release(_om_depth_stencil);
216 | }
217 | }
218 |
--------------------------------------------------------------------------------
/source/d3d11/d3d11_stateblock.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #pragma once
7 |
8 | #include
9 | #include
10 |
11 | namespace reshade::d3d11
12 | {
13 | class d3d11_stateblock
14 | {
15 | public:
16 | explicit d3d11_stateblock(const com_ptr &device);
17 | ~d3d11_stateblock();
18 |
19 | void capture(const com_ptr &devicecontext);
20 | void apply_and_release();
21 |
22 | private:
23 | void release_all_device_objects();
24 |
25 | D3D_FEATURE_LEVEL _device_feature_level;
26 | com_ptr _device;
27 | com_ptr _device_context;
28 | ID3D11InputLayout *_ia_input_layout;
29 | D3D11_PRIMITIVE_TOPOLOGY _ia_primitive_topology;
30 | ID3D11Buffer *_ia_vertex_buffers[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT];
31 | UINT _ia_vertex_strides[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT];
32 | UINT _ia_vertex_offsets[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT];
33 | ID3D11Buffer *_ia_index_buffer;
34 | DXGI_FORMAT _ia_index_format;
35 | UINT _ia_index_offset;
36 | ID3D11VertexShader *_vs;
37 | UINT _vs_num_class_instances;
38 | ID3D11ClassInstance *_vs_class_instances[256];
39 | ID3D11Buffer *_vs_constant_buffers[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT];
40 | ID3D11SamplerState *_vs_sampler_states[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT];
41 | ID3D11ShaderResourceView *_vs_shader_resources[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT];
42 | ID3D11HullShader *_hs;
43 | UINT _hs_num_class_instances;
44 | ID3D11ClassInstance *_hs_class_instances[256];
45 | ID3D11DomainShader *_ds;
46 | UINT _ds_num_class_instances;
47 | ID3D11ClassInstance *_ds_class_instances[256];
48 | ID3D11GeometryShader *_gs;
49 | UINT _gs_num_class_instances;
50 | ID3D11ClassInstance *_gs_class_instances[256];
51 | ID3D11RasterizerState *_rs_state;
52 | UINT _rs_num_viewports;
53 | D3D11_VIEWPORT _rs_viewports[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE];
54 | ID3D11PixelShader *_ps;
55 | UINT _ps_num_class_instances;
56 | ID3D11ClassInstance *_ps_class_instances[256];
57 | ID3D11Buffer *_ps_constant_buffers[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT];
58 | ID3D11SamplerState *_ps_sampler_states[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT];
59 | ID3D11ShaderResourceView *_ps_shader_resources[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT];
60 | ID3D11BlendState *_om_blend_state;
61 | FLOAT _om_blend_factor[4];
62 | UINT _om_sample_mask;
63 | ID3D11DepthStencilState *_om_depth_stencil_state;
64 | UINT _om_stencil_ref;
65 | ID3D11RenderTargetView *_om_render_targets[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT];
66 | ID3D11DepthStencilView *_om_depth_stencil;
67 | };
68 | }
69 |
--------------------------------------------------------------------------------
/source/d3d9/d3d9.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #pragma once
7 |
8 | #include "d3d9_runtime.hpp"
9 |
10 | struct __declspec(uuid("F1006E9A-1C51-4AF4-ACEF-3605D2D4C8EE")) Direct3DDevice9;
11 | struct __declspec(uuid("BC52FCE4-1EAC-40C8-84CF-863600BBAA01")) Direct3DSwapChain9;
12 |
--------------------------------------------------------------------------------
/source/d3d9/d3d9_effect_compiler.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #pragma once
7 |
8 | #include "effect_syntax_tree.hpp"
9 | #include
10 | #include
11 |
12 | namespace reshade::d3d9
13 | {
14 | #pragma region Forward Declarations
15 | struct d3d9_sampler;
16 | struct d3d9_pass_data;
17 | class d3d9_runtime;
18 | #pragma endregion
19 |
20 | class d3d9_effect_compiler
21 | {
22 | public:
23 | d3d9_effect_compiler(d3d9_runtime *runtime, const reshadefx::syntax_tree &ast, std::string &errors, bool skipoptimization = false);
24 |
25 | bool run();
26 |
27 | private:
28 | void error(const reshadefx::location &location, const std::string &message);
29 | void warning(const reshadefx::location &location, const std::string &message);
30 |
31 | void visit(std::stringstream &output, const reshadefx::nodes::statement_node *node);
32 | void visit(std::stringstream &output, const reshadefx::nodes::expression_node *node);
33 | void visit(std::stringstream &output, const reshadefx::nodes::type_node &type, bool with_qualifiers = true);
34 | void visit(std::stringstream &output, const reshadefx::nodes::lvalue_expression_node *node);
35 | void visit(std::stringstream &output, const reshadefx::nodes::literal_expression_node *node);
36 | void visit(std::stringstream &output, const reshadefx::nodes::expression_sequence_node *node);
37 | void visit(std::stringstream &output, const reshadefx::nodes::unary_expression_node *node);
38 | void visit(std::stringstream &output, const reshadefx::nodes::binary_expression_node *node);
39 | void visit(std::stringstream &output, const reshadefx::nodes::intrinsic_expression_node *node);
40 | void visit(std::stringstream &output, const reshadefx::nodes::conditional_expression_node *node);
41 | void visit(std::stringstream &output, const reshadefx::nodes::swizzle_expression_node *node);
42 | void visit(std::stringstream &output, const reshadefx::nodes::field_expression_node *node);
43 | void visit(std::stringstream &output, const reshadefx::nodes::assignment_expression_node *node);
44 | void visit(std::stringstream &output, const reshadefx::nodes::call_expression_node *node);
45 | void visit(std::stringstream &output, const reshadefx::nodes::constructor_expression_node *node);
46 | void visit(std::stringstream &output, const reshadefx::nodes::initializer_list_node *node);
47 | void visit(std::stringstream &output, const reshadefx::nodes::compound_statement_node *node);
48 | void visit(std::stringstream &output, const reshadefx::nodes::declarator_list_node *node, bool single_statement = false);
49 | void visit(std::stringstream &output, const reshadefx::nodes::expression_statement_node *node);
50 | void visit(std::stringstream &output, const reshadefx::nodes::if_statement_node *node);
51 | void visit(std::stringstream &output, const reshadefx::nodes::switch_statement_node *node);
52 | void visit(std::stringstream &output, const reshadefx::nodes::case_statement_node *node);
53 | void visit(std::stringstream &output, const reshadefx::nodes::for_statement_node *node);
54 | void visit(std::stringstream &output, const reshadefx::nodes::while_statement_node *node);
55 | void visit(std::stringstream &output, const reshadefx::nodes::return_statement_node *node);
56 | void visit(std::stringstream &output, const reshadefx::nodes::jump_statement_node *node);
57 | void visit(std::stringstream &output, const reshadefx::nodes::struct_declaration_node *node);
58 | void visit(std::stringstream &output, const reshadefx::nodes::variable_declaration_node *node, bool with_type = true, bool with_semantic = true);
59 | void visit(std::stringstream &output, const reshadefx::nodes::function_declaration_node *node);
60 |
61 | void visit_texture(const reshadefx::nodes::variable_declaration_node *node);
62 | void visit_sampler(const reshadefx::nodes::variable_declaration_node *node);
63 | void visit_uniform(const reshadefx::nodes::variable_declaration_node *node);
64 | void visit_technique(const reshadefx::nodes::technique_declaration_node *node);
65 | void visit_pass(const reshadefx::nodes::pass_declaration_node *node, d3d9_pass_data &pass);
66 | void visit_pass_shader(const reshadefx::nodes::function_declaration_node *node, const std::string &shadertype, const std::string &samplers, d3d9_pass_data &pass);
67 |
68 | struct function
69 | {
70 | std::string code;
71 | std::vector dependencies;
72 | std::unordered_set sampler_dependencies;
73 | };
74 |
75 | d3d9_runtime *_runtime;
76 | bool _success = true;
77 | const reshadefx::syntax_tree &_ast;
78 | std::string &_errors;
79 | size_t _uniform_storage_offset = 0, _constant_register_count = 0;
80 | std::stringstream _global_code, _global_uniforms;
81 | bool _skip_shader_optimization;
82 | const reshadefx::nodes::function_declaration_node *_current_function;
83 | std::unordered_map _samplers;
84 | std::unordered_map _functions;
85 | HMODULE _d3dcompiler_module = nullptr;
86 | };
87 | }
88 |
--------------------------------------------------------------------------------
/source/d3d9/d3d9_runtime.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #pragma once
7 |
8 | #include
9 | #include "runtime.hpp"
10 | #include "com_ptr.hpp"
11 |
12 | namespace reshade::d3d9
13 | {
14 | struct d3d9_sampler
15 | {
16 | DWORD states[12];
17 | struct d3d9_tex_data *texture;
18 | };
19 |
20 | struct d3d9_tex_data : base_object
21 | {
22 | com_ptr texture;
23 | com_ptr surface;
24 | };
25 | struct d3d9_pass_data : base_object
26 | {
27 | com_ptr vertex_shader;
28 | com_ptr pixel_shader;
29 | d3d9_sampler samplers[16] = { };
30 | DWORD sampler_count = 0;
31 | com_ptr stateblock;
32 | bool clear_render_targets = false;
33 | IDirect3DSurface9 *render_targets[8] = { };
34 | };
35 |
36 | class d3d9_runtime : public runtime
37 | {
38 | public:
39 | d3d9_runtime(IDirect3DDevice9 *device, IDirect3DSwapChain9 *swapchain);
40 |
41 | bool on_init(const D3DPRESENT_PARAMETERS &pp);
42 | void on_reset();
43 | static void do_draw_fx(void* runtime);
44 | void draw_fx();
45 | void on_present();
46 | void on_draw_call(D3DPRIMITIVETYPE type, UINT count);
47 | void on_set_depthstencil_surface(IDirect3DSurface9 *&depthstencil);
48 | void on_get_depthstencil_surface(IDirect3DSurface9 *&depthstencil);
49 |
50 | void capture_frame(uint8_t *buffer) const override;
51 | bool load_effect(const reshadefx::syntax_tree &ast, std::string &errors) override;
52 | bool update_texture(texture &texture, const uint8_t *data) override;
53 | bool update_texture_reference(texture &texture, texture_reference id);
54 |
55 | void render_technique(const technique &technique) override;
56 | void render_imgui_draw_data(ImDrawData *data) override;
57 |
58 | com_ptr _d3d;
59 | com_ptr _device;
60 | com_ptr _swapchain;
61 |
62 | com_ptr _backbuffer, _backbuffer_resolved;
63 | com_ptr _backbuffer_texture;
64 | com_ptr _backbuffer_texture_surface;
65 | com_ptr _depthstencil_texture;
66 |
67 | private:
68 | struct depth_source_info
69 | {
70 | UINT width, height;
71 | UINT drawcall_count, vertices_count;
72 | };
73 |
74 | bool init_backbuffer_texture();
75 | bool init_default_depth_stencil();
76 | bool init_fx_resources();
77 | bool init_imgui_font_atlas();
78 |
79 | void detect_depth_source();
80 | bool create_depthstencil_replacement(IDirect3DSurface9 *depthstencil);
81 |
82 | UINT _behavior_flags, _num_simultaneous_rendertargets, _num_samplers;
83 | bool _is_multisampling_enabled = false;
84 | D3DFORMAT _backbuffer_format = D3DFMT_UNKNOWN;
85 | com_ptr _stateblock;
86 | com_ptr _depthstencil, _depthstencil_replacement, _default_depthstencil;
87 | std::unordered_map _depth_source_table;
88 |
89 | com_ptr _effect_triangle_buffer;
90 | com_ptr _effect_triangle_layout;
91 |
92 | com_ptr _imgui_vertex_buffer;
93 | com_ptr _imgui_index_buffer;
94 | int _imgui_vertex_buffer_size = 0, _imgui_index_buffer_size = 0;
95 | };
96 | }
97 |
--------------------------------------------------------------------------------
/source/d3d9/d3d9_swapchain.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #include "log.hpp"
7 | #include "d3d9_device.hpp"
8 | #include "d3d9_swapchain.hpp"
9 |
10 | // IDirect3DSwapChain9
11 | HRESULT STDMETHODCALLTYPE Direct3DSwapChain9::QueryInterface(REFIID riid, void **ppvObj)
12 | {
13 | if (ppvObj == nullptr)
14 | {
15 | return E_POINTER;
16 | }
17 | else if (
18 | riid == __uuidof(this) ||
19 | riid == __uuidof(IUnknown) ||
20 | riid == __uuidof(IDirect3DSwapChain9) ||
21 | riid == __uuidof(IDirect3DSwapChain9Ex))
22 | {
23 | #pragma region Update to IDirect3DSwapChain9Ex interface
24 | if (!_extended_interface && riid == __uuidof(IDirect3DSwapChain9Ex))
25 | {
26 | IDirect3DSwapChain9Ex *swapchainex = nullptr;
27 |
28 | if (FAILED(_orig->QueryInterface(IID_PPV_ARGS(&swapchainex))))
29 | {
30 | return E_NOINTERFACE;
31 | }
32 |
33 | _orig->Release();
34 |
35 | LOG(INFO) << "Upgraded 'IDirect3DSwapChain9' object " << this << " to 'IDirect3DSwapChain9Ex'.";
36 |
37 | _orig = swapchainex;
38 | _extended_interface = true;
39 | }
40 | #pragma endregion
41 |
42 | AddRef();
43 |
44 | *ppvObj = this;
45 |
46 | return S_OK;
47 | }
48 |
49 | return _orig->QueryInterface(riid, ppvObj);
50 | }
51 | ULONG STDMETHODCALLTYPE Direct3DSwapChain9::AddRef()
52 | {
53 | _ref++;
54 |
55 | return _orig->AddRef();
56 | }
57 | ULONG STDMETHODCALLTYPE Direct3DSwapChain9::Release()
58 | {
59 | if (--_ref == 0)
60 | {
61 | assert(_runtime != nullptr);
62 |
63 | _runtime->on_reset();
64 |
65 | _runtime.reset();
66 |
67 | const auto it = std::find(_device->_additional_swapchains.begin(), _device->_additional_swapchains.end(), this);
68 |
69 | if (it != _device->_additional_swapchains.end())
70 | {
71 | _device->_additional_swapchains.erase(it);
72 |
73 | _device->Release();
74 | }
75 | }
76 |
77 | ULONG ref = _orig->Release();
78 |
79 | if (_ref == 0 && ref != 0)
80 | {
81 | LOG(WARNING) << "Reference count for 'IDirect3DSwapChain9" << (_extended_interface ? "Ex" : "") << "' object " << this << " is inconsistent: " << ref << ", but expected 0.";
82 |
83 | ref = 0;
84 | }
85 |
86 | if (ref == 0)
87 | {
88 | assert(_ref <= 0);
89 |
90 | LOG(INFO) << "Destroyed 'IDirect3DSwapChain9" << (_extended_interface ? "Ex" : "") << "' object " << this << ".";
91 |
92 | delete this;
93 | }
94 |
95 | return ref;
96 | }
97 | HRESULT STDMETHODCALLTYPE Direct3DSwapChain9::Present(const RECT *pSourceRect, const RECT *pDestRect, HWND hDestWindowOverride, const RGNDATA *pDirtyRegion, DWORD dwFlags)
98 | {
99 | assert(_runtime != nullptr);
100 |
101 | _runtime->on_present();
102 |
103 | return _orig->Present(pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion, dwFlags);
104 | }
105 | HRESULT STDMETHODCALLTYPE Direct3DSwapChain9::GetFrontBufferData(IDirect3DSurface9 *pDestSurface)
106 | {
107 | return _orig->GetFrontBufferData(pDestSurface);
108 | }
109 | HRESULT STDMETHODCALLTYPE Direct3DSwapChain9::GetBackBuffer(UINT iBackBuffer, D3DBACKBUFFER_TYPE Type, IDirect3DSurface9 **ppBackBuffer)
110 | {
111 | return _orig->GetBackBuffer(iBackBuffer, Type, ppBackBuffer);
112 | }
113 | HRESULT STDMETHODCALLTYPE Direct3DSwapChain9::GetRasterStatus(D3DRASTER_STATUS *pRasterStatus)
114 | {
115 | return _orig->GetRasterStatus(pRasterStatus);
116 | }
117 | HRESULT STDMETHODCALLTYPE Direct3DSwapChain9::GetDisplayMode(D3DDISPLAYMODE *pMode)
118 | {
119 | return _orig->GetDisplayMode(pMode);
120 | }
121 | HRESULT STDMETHODCALLTYPE Direct3DSwapChain9::GetDevice(IDirect3DDevice9 **ppDevice)
122 | {
123 | if (ppDevice == nullptr)
124 | {
125 | return D3DERR_INVALIDCALL;
126 | }
127 |
128 | _device->AddRef();
129 |
130 | *ppDevice = _device;
131 |
132 | return D3D_OK;
133 | }
134 | HRESULT STDMETHODCALLTYPE Direct3DSwapChain9::GetPresentParameters(D3DPRESENT_PARAMETERS *pPresentationParameters)
135 | {
136 | return _orig->GetPresentParameters(pPresentationParameters);
137 | }
138 |
139 | // IDirect3DSwapChain9Ex
140 | HRESULT STDMETHODCALLTYPE Direct3DSwapChain9::GetLastPresentCount(UINT *pLastPresentCount)
141 | {
142 | assert(_extended_interface);
143 |
144 | return static_cast(_orig)->GetLastPresentCount(pLastPresentCount);
145 | }
146 | HRESULT STDMETHODCALLTYPE Direct3DSwapChain9::GetPresentStats(D3DPRESENTSTATS *pPresentationStatistics)
147 | {
148 | assert(_extended_interface);
149 |
150 | return static_cast(_orig)->GetPresentStats(pPresentationStatistics);
151 | }
152 | HRESULT STDMETHODCALLTYPE Direct3DSwapChain9::GetDisplayModeEx(D3DDISPLAYMODEEX *pMode, D3DDISPLAYROTATION *pRotation)
153 | {
154 | assert(_extended_interface);
155 |
156 | return static_cast(_orig)->GetDisplayModeEx(pMode, pRotation);
157 | }
158 |
--------------------------------------------------------------------------------
/source/d3d9/d3d9_swapchain.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #pragma once
7 |
8 | #include "d3d9.hpp"
9 |
10 | struct Direct3DSwapChain9 : IDirect3DSwapChain9Ex
11 | {
12 | Direct3DSwapChain9(Direct3DDevice9 *device, IDirect3DSwapChain9 *original, const std::shared_ptr &runtime) :
13 | _orig(original),
14 | _extended_interface(false),
15 | _device(device),
16 | _runtime(runtime) { }
17 | Direct3DSwapChain9(Direct3DDevice9 *device, IDirect3DSwapChain9Ex *original, const std::shared_ptr &runtime) :
18 | _orig(original),
19 | _extended_interface(true),
20 | _device(device),
21 | _runtime(runtime) { }
22 |
23 | Direct3DSwapChain9(const Direct3DSwapChain9 &) = delete;
24 | Direct3DSwapChain9 &operator=(const Direct3DSwapChain9 &) = delete;
25 |
26 | #pragma region IUnknown
27 | virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObj) override;
28 | virtual ULONG STDMETHODCALLTYPE AddRef() override;
29 | virtual ULONG STDMETHODCALLTYPE Release() override;
30 | #pragma endregion
31 | #pragma region IDirect3DSwapChain9
32 | virtual HRESULT STDMETHODCALLTYPE Present(const RECT *pSourceRect, const RECT *pDestRect, HWND hDestWindowOverride, const RGNDATA *pDirtyRegion, DWORD dwFlags) override;
33 | virtual HRESULT STDMETHODCALLTYPE GetFrontBufferData(IDirect3DSurface9 *pDestSurface) override;
34 | virtual HRESULT STDMETHODCALLTYPE GetBackBuffer(UINT iBackBuffer, D3DBACKBUFFER_TYPE Type, IDirect3DSurface9 **ppBackBuffer) override;
35 | virtual HRESULT STDMETHODCALLTYPE GetRasterStatus(D3DRASTER_STATUS *pRasterStatus) override;
36 | virtual HRESULT STDMETHODCALLTYPE GetDisplayMode(D3DDISPLAYMODE *pMode) override;
37 | virtual HRESULT STDMETHODCALLTYPE GetDevice(IDirect3DDevice9 **ppDevice) override;
38 | virtual HRESULT STDMETHODCALLTYPE GetPresentParameters(D3DPRESENT_PARAMETERS *pPresentationParameters) override;
39 | #pragma endregion
40 | #pragma region IDirect3DSwapChain9Ex
41 | virtual HRESULT STDMETHODCALLTYPE GetLastPresentCount(UINT *pLastPresentCount) override;
42 | virtual HRESULT STDMETHODCALLTYPE GetPresentStats(D3DPRESENTSTATS *pPresentationStatistics) override;
43 | virtual HRESULT STDMETHODCALLTYPE GetDisplayModeEx(D3DDISPLAYMODEEX *pMode, D3DDISPLAYROTATION *pRotation) override;
44 | #pragma endregion
45 |
46 | LONG _ref = 1;
47 | IDirect3DSwapChain9 *_orig;
48 | bool _extended_interface;
49 | Direct3DDevice9 *const _device;
50 | std::shared_ptr _runtime;
51 | };
52 |
--------------------------------------------------------------------------------
/source/directory_watcher.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #include "directory_watcher.hpp"
7 | #include "string_codecvt.hpp"
8 |
9 | #include
10 |
11 | namespace reshade::filesystem
12 | {
13 | directory_watcher::directory_watcher(const path &path) :
14 | _path(path),
15 | _buffer(sizeof(FILE_NOTIFY_INFORMATION) + MAX_PATH * sizeof(WCHAR))
16 | {
17 | _file_handle = CreateFileW(path.wstring().c_str(), FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, nullptr);
18 | _completion_handle = CreateIoCompletionPort(_file_handle, nullptr, reinterpret_cast(_file_handle), 1);
19 |
20 | OVERLAPPED overlapped = { };
21 | ReadDirectoryChangesW(_file_handle, _buffer.data(), static_cast(_buffer.size()), TRUE, FILE_NOTIFY_CHANGE_LAST_WRITE, nullptr, &overlapped, nullptr);
22 | }
23 | directory_watcher::~directory_watcher()
24 | {
25 | CancelIo(_file_handle);
26 |
27 | CloseHandle(_file_handle);
28 | CloseHandle(_completion_handle);
29 | }
30 |
31 | bool directory_watcher::check(std::vector &modifications)
32 | {
33 | DWORD transferred;
34 | ULONG_PTR key;
35 | OVERLAPPED *overlapped;
36 |
37 | if (!GetQueuedCompletionStatus(_completion_handle, &transferred, &key, &overlapped, 0))
38 | {
39 | return false;
40 | }
41 |
42 | static DWORD s_last_tick_count = 0;
43 | static std::string s_last_filename;
44 |
45 | auto record = reinterpret_cast(_buffer.data());
46 | const auto current_tick_count = GetTickCount();
47 |
48 | while (true)
49 | {
50 | const std::string filename = utf16_to_utf8(record->FileName, record->FileNameLength / sizeof(WCHAR));
51 |
52 | if (filename != s_last_filename || s_last_tick_count + 2000 < current_tick_count)
53 | {
54 | s_last_filename = filename;
55 | s_last_tick_count = current_tick_count;
56 |
57 | modifications.push_back(_path / filename);
58 | }
59 |
60 | if (record->NextEntryOffset == 0)
61 | {
62 | break;
63 | }
64 |
65 | record = reinterpret_cast(reinterpret_cast(record) + record->NextEntryOffset);
66 | }
67 |
68 | overlapped->hEvent = nullptr;
69 |
70 | ReadDirectoryChangesW(_file_handle, _buffer.data(), static_cast(_buffer.size()), TRUE, FILE_NOTIFY_CHANGE_LAST_WRITE, nullptr, overlapped, nullptr);
71 |
72 | return true;
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/source/directory_watcher.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #pragma once
7 |
8 | #include "filesystem.hpp"
9 |
10 | namespace reshade::filesystem
11 | {
12 | class directory_watcher
13 | {
14 | public:
15 | explicit directory_watcher(const path &path);
16 | ~directory_watcher();
17 |
18 | bool check(std::vector &modifications);
19 |
20 | private:
21 | path _path;
22 | std::vector _buffer;
23 | void *_file_handle, *_completion_handle;
24 | };
25 | }
26 |
--------------------------------------------------------------------------------
/source/dllmain.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #include "log.hpp"
7 | #include "filesystem.hpp"
8 | #include "input.hpp"
9 | #include "runtime.hpp"
10 | #include "hook_manager.hpp"
11 | #include "dllmodule.hpp"
12 | #include "version.h"
13 | #include
14 |
15 | HMODULE g_module_handle = nullptr;
16 |
17 | BOOL APIENTRY DllMain(HMODULE hModule, DWORD fdwReason, LPVOID lpvReserved)
18 | {
19 | UNREFERENCED_PARAMETER(lpvReserved);
20 |
21 | using namespace reshade;
22 |
23 | switch (fdwReason)
24 | {
25 | case DLL_PROCESS_ATTACH:
26 | {
27 | g_module_handle = hModule;
28 | runtime::s_reshade_dll_path = filesystem::get_module_path(hModule);
29 | runtime::s_target_executable_path = filesystem::get_module_path(nullptr);
30 |
31 | log::open(filesystem::path(runtime::s_reshade_dll_path).replace_extension(".log"));
32 |
33 | #ifdef WIN64
34 | LOG(INFO) << "Initializing crosire's ReShade version '" VERSION_STRING_FILE "' (64-bit) built on '" VERSION_DATE " " VERSION_TIME "' loaded from " << runtime::s_reshade_dll_path << " to " << runtime::s_target_executable_path << " ...";
35 | #else
36 | LOG(INFO) << "Initializing crosire's ReShade version '" VERSION_STRING_FILE "' (32-bit) built on '" VERSION_DATE " " VERSION_TIME "' loaded from " << runtime::s_reshade_dll_path << " to " << runtime::s_target_executable_path << " ...";
37 | #endif
38 |
39 | const auto system_path = filesystem::get_special_folder_path(filesystem::special_folder::system);
40 | hooks::register_module(system_path / "d3d9.dll");
41 | hooks::register_module(system_path / "d3d10.dll");
42 | hooks::register_module(system_path / "d3d10_1.dll");
43 | hooks::register_module(system_path / "d3d11.dll");
44 | hooks::register_module(system_path / "dxgi.dll");
45 | hooks::register_module(system_path / "opengl32.dll");
46 | hooks::register_module(system_path / "user32.dll");
47 | hooks::register_module(system_path / "ws2_32.dll");
48 | DllModule::LoadModule();
49 |
50 | LOG(INFO) << "Initialized.";
51 | break;
52 | }
53 | case DLL_PROCESS_DETACH:
54 | {
55 | LOG(INFO) << "Exiting ...";
56 |
57 | input::uninstall();
58 | hooks::uninstall();
59 |
60 | LOG(INFO) << "Exited.";
61 | break;
62 | }
63 | }
64 |
65 | return TRUE;
66 | }
67 |
--------------------------------------------------------------------------------
/source/dllmodule.cpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "dllmodule.hpp"
4 |
5 | IModule* DllModule::module;
6 |
7 | bool DllModule::isValid = false;
8 |
9 | void DllModule::CreateModule(CreateModuleType f)
10 | {
11 | DllModule::module = f();
12 | DllModule::isValid = true;
13 | }
14 |
15 | void DllModule::LoadModule()
16 | {
17 | DllModule::isValid = false;
18 | ;
19 | HINSTANCE dllHandle = nullptr;
20 | dllHandle = LoadLibrary(L"module.dll");
21 | LOG(INFO) << "Loadind module..." << dllHandle;
22 | if (NULL != dllHandle)
23 | {
24 | LOG(INFO) << "Loaded shard lib : " << dllHandle;
25 | CreateModuleType create_module = nullptr;
26 | create_module = (CreateModuleType)GetProcAddress(dllHandle, "CreateModule");
27 | if (create_module == nullptr) {
28 | LOG(INFO) << "Error : Can't access CreateModule().";
29 | }
30 | else {
31 | LOG(INFO) << "CreateShard addr : " << (int)create_module;
32 | DllModule::CreateModule(create_module);
33 | }
34 | }
35 | else {
36 | LOG(INFO) << "Error : Can't load module.";
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/source/dllmodule.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "module.hpp"
4 | #include "log.hpp"
5 | #include
6 |
7 | class DllModule {
8 | public:
9 | static void CreateModule(CreateModuleType f);
10 | static void LoadModule();
11 | static bool isValid;
12 |
13 | static IModule* module;
14 | };
15 |
--------------------------------------------------------------------------------
/source/dxgi/dxgi.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #pragma once
7 |
8 | #include
9 |
10 | #include "d3d10/d3d10_device.hpp"
11 | #include "d3d11/d3d11_device.hpp"
12 |
13 | struct __declspec(uuid("CB285C3B-3677-4332-98C7-D6339B9782B1")) DXGIDevice;
14 | struct __declspec(uuid("1F445F9F-9887-4C4C-9055-4E3BADAFCCA8")) DXGISwapChain;
15 |
--------------------------------------------------------------------------------
/source/dxgi/dxgi_device.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #include "log.hpp"
7 | #include "dxgi_device.hpp"
8 | #include "dxgi_swapchain.hpp"
9 |
10 | // IDXGIDevice
11 | HRESULT STDMETHODCALLTYPE DXGIDevice::QueryInterface(REFIID riid, void **ppvObj)
12 | {
13 | if (ppvObj == nullptr)
14 | {
15 | return E_POINTER;
16 | }
17 | else if (
18 | riid == __uuidof(this) ||
19 | riid == __uuidof(IUnknown) ||
20 | riid == __uuidof(IDXGIObject) ||
21 | riid == __uuidof(IDXGIDevice) ||
22 | riid == __uuidof(IDXGIDevice1) ||
23 | riid == __uuidof(IDXGIDevice2) ||
24 | riid == __uuidof(IDXGIDevice3) ||
25 | riid == __uuidof(IDXGIDevice4))
26 | {
27 | #pragma region Update to IDXGIDevice2 interface
28 | if (riid == __uuidof(IDXGIDevice2) && _interface_version < 2)
29 | {
30 | IDXGIDevice2 *device2 = nullptr;
31 |
32 | if (FAILED(_orig->QueryInterface(&device2)))
33 | {
34 | return E_NOINTERFACE;
35 | }
36 |
37 | _orig->Release();
38 |
39 | LOG(INFO) << "Upgraded 'IDXGIDevice" << (_interface_version > 0 ? std::to_string(_interface_version) : "") << "' object " << this << " to 'IDXGIDevice2'.";
40 |
41 | _orig = device2;
42 | _interface_version = 2;
43 | }
44 | #pragma endregion
45 | #pragma region Update to IDXGIDevice3 interface
46 | if (riid == __uuidof(IDXGIDevice3) && _interface_version < 3)
47 | {
48 | IDXGIDevice3 *device3 = nullptr;
49 |
50 | if (FAILED(_orig->QueryInterface(&device3)))
51 | {
52 | return E_NOINTERFACE;
53 | }
54 |
55 | _orig->Release();
56 |
57 | LOG(INFO) << "Upgraded 'IDXGIDevice" << (_interface_version > 0 ? std::to_string(_interface_version) : "") << "' object " << this << " to 'IDXGIDevice3'.";
58 |
59 | _orig = device3;
60 | _interface_version = 3;
61 | }
62 | #pragma endregion
63 | #pragma region Update to IDXGIDevice4 interface
64 | if (riid == __uuidof(IDXGIDevice4) && _interface_version < 4)
65 | {
66 | IDXGIDevice4 *device4 = nullptr;
67 |
68 | if (FAILED(_orig->QueryInterface(&device4)))
69 | {
70 | return E_NOINTERFACE;
71 | }
72 |
73 | _orig->Release();
74 |
75 | LOG(INFO) << "Upgraded 'IDXGIDevice" << (_interface_version > 0 ? std::to_string(_interface_version) : "") << "' object " << this << " to 'IDXGIDevice4'.";
76 |
77 | _orig = device4;
78 | _interface_version = 4;
79 | }
80 | #pragma endregion
81 |
82 | AddRef();
83 |
84 | *ppvObj = this;
85 |
86 | return S_OK;
87 | }
88 |
89 | return _direct3d_device->QueryInterface(riid, ppvObj);
90 | }
91 | ULONG STDMETHODCALLTYPE DXGIDevice::AddRef()
92 | {
93 | _ref++;
94 |
95 | return _orig->AddRef();
96 | }
97 | ULONG STDMETHODCALLTYPE DXGIDevice::Release()
98 | {
99 | ULONG ref = _orig->Release();
100 |
101 | if (--_ref == 0 && ref != 1)
102 | {
103 | LOG(WARNING) << "Reference count for 'IDXGIDevice" << (_interface_version > 0 ? std::to_string(_interface_version) : "") << "' object " << this << " is inconsistent: " << ref << ", but expected 1.";
104 |
105 | ref = 1;
106 | }
107 |
108 | if (ref == 1)
109 | {
110 | assert(_ref <= 0);
111 |
112 | LOG(INFO) << "Destroyed 'IDXGIDevice" << (_interface_version > 0 ? std::to_string(_interface_version) : "") << "' object " << this << ".";
113 |
114 | delete this;
115 | }
116 |
117 | return ref;
118 | }
119 | HRESULT STDMETHODCALLTYPE DXGIDevice::SetPrivateData(REFGUID Name, UINT DataSize, const void *pData)
120 | {
121 | return _orig->SetPrivateData(Name, DataSize, pData);
122 | }
123 | HRESULT STDMETHODCALLTYPE DXGIDevice::SetPrivateDataInterface(REFGUID Name, const IUnknown *pUnknown)
124 | {
125 | return _orig->SetPrivateDataInterface(Name, pUnknown);
126 | }
127 | HRESULT STDMETHODCALLTYPE DXGIDevice::GetPrivateData(REFGUID Name, UINT *pDataSize, void *pData)
128 | {
129 | return _orig->GetPrivateData(Name, pDataSize, pData);
130 | }
131 | HRESULT STDMETHODCALLTYPE DXGIDevice::GetParent(REFIID riid, void **ppParent)
132 | {
133 | return _orig->GetParent(riid, ppParent);
134 | }
135 | HRESULT STDMETHODCALLTYPE DXGIDevice::GetAdapter(IDXGIAdapter **pAdapter)
136 | {
137 | return _orig->GetAdapter(pAdapter);
138 | }
139 | HRESULT STDMETHODCALLTYPE DXGIDevice::CreateSurface(const DXGI_SURFACE_DESC *pDesc, UINT NumSurfaces, DXGI_USAGE Usage, const DXGI_SHARED_RESOURCE *pSharedResource, IDXGISurface **ppSurface)
140 | {
141 | return _orig->CreateSurface(pDesc, NumSurfaces, Usage, pSharedResource, ppSurface);
142 | }
143 | HRESULT STDMETHODCALLTYPE DXGIDevice::QueryResourceResidency(IUnknown *const *ppResources, DXGI_RESIDENCY *pResidencyStatus, UINT NumResources)
144 | {
145 | return _orig->QueryResourceResidency(ppResources, pResidencyStatus, NumResources);
146 | }
147 | HRESULT STDMETHODCALLTYPE DXGIDevice::SetGPUThreadPriority(INT Priority)
148 | {
149 | return _orig->SetGPUThreadPriority(Priority);
150 | }
151 | HRESULT STDMETHODCALLTYPE DXGIDevice::GetGPUThreadPriority(INT *pPriority)
152 | {
153 | return _orig->GetGPUThreadPriority(pPriority);
154 | }
155 |
156 | // IDXGIDevice1
157 | HRESULT STDMETHODCALLTYPE DXGIDevice::SetMaximumFrameLatency(UINT MaxLatency)
158 | {
159 | return _orig->SetMaximumFrameLatency(MaxLatency);
160 | }
161 | HRESULT STDMETHODCALLTYPE DXGIDevice::GetMaximumFrameLatency(UINT *pMaxLatency)
162 | {
163 | return _orig->GetMaximumFrameLatency(pMaxLatency);
164 | }
165 |
166 | // IDXGIDevice2
167 | HRESULT STDMETHODCALLTYPE DXGIDevice::OfferResources(UINT NumResources, IDXGIResource *const *ppResources, DXGI_OFFER_RESOURCE_PRIORITY Priority)
168 | {
169 | assert(_interface_version >= 2);
170 |
171 | return static_cast(_orig)->OfferResources(NumResources, ppResources, Priority);
172 | }
173 | HRESULT STDMETHODCALLTYPE DXGIDevice::ReclaimResources(UINT NumResources, IDXGIResource *const *ppResources, BOOL *pDiscarded)
174 | {
175 | assert(_interface_version >= 2);
176 |
177 | return static_cast(_orig)->ReclaimResources(NumResources, ppResources, pDiscarded);
178 | }
179 | HRESULT STDMETHODCALLTYPE DXGIDevice::EnqueueSetEvent(HANDLE hEvent)
180 | {
181 | assert(_interface_version >= 2);
182 |
183 | return static_cast(_orig)->EnqueueSetEvent(hEvent);
184 | }
185 |
186 | // IDXGIDevice3
187 | void STDMETHODCALLTYPE DXGIDevice::Trim()
188 | {
189 | assert(_interface_version >= 3);
190 |
191 | return static_cast(_orig)->Trim();
192 | }
193 |
194 | // IDXGIDevice4
195 | HRESULT STDMETHODCALLTYPE DXGIDevice::OfferResources1(UINT NumResources, IDXGIResource *const *ppResources, DXGI_OFFER_RESOURCE_PRIORITY Priority, UINT Flags)
196 | {
197 | assert(_interface_version >= 4);
198 |
199 | return static_cast(_orig)->OfferResources1(NumResources, ppResources, Priority, Flags);
200 | }
201 | HRESULT STDMETHODCALLTYPE DXGIDevice::ReclaimResources1(UINT NumResources, IDXGIResource *const *ppResources, DXGI_RECLAIM_RESOURCE_RESULTS *pResults)
202 | {
203 | assert(_interface_version >= 4);
204 |
205 | return static_cast(_orig)->ReclaimResources1(NumResources, ppResources, pResults);
206 | }
207 |
--------------------------------------------------------------------------------
/source/dxgi/dxgi_device.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #pragma once
7 |
8 | #include "dxgi.hpp"
9 |
10 | struct DXGIDevice : IDXGIDevice4
11 | {
12 | DXGIDevice(IDXGIDevice1 *original, D3D10Device *direct3d_device) :
13 | _orig(original),
14 | _interface_version(1),
15 | _direct3d_device(direct3d_device) { }
16 | DXGIDevice(IDXGIDevice1 *original, D3D11Device *direct3d_device) :
17 | _orig(original),
18 | _interface_version(1),
19 | _direct3d_device(direct3d_device) { }
20 |
21 | DXGIDevice(const DXGIDevice &) = delete;
22 | DXGIDevice &operator=(const DXGIDevice &) = delete;
23 |
24 | #pragma region IUnknown
25 | virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObj) override;
26 | virtual ULONG STDMETHODCALLTYPE AddRef() override;
27 | virtual ULONG STDMETHODCALLTYPE Release() override;
28 | #pragma endregion
29 | #pragma region IDXGIObject
30 | virtual HRESULT STDMETHODCALLTYPE SetPrivateData(REFGUID Name, UINT DataSize, const void *pData) override;
31 | virtual HRESULT STDMETHODCALLTYPE SetPrivateDataInterface(REFGUID Name, const IUnknown *pUnknown) override;
32 | virtual HRESULT STDMETHODCALLTYPE GetPrivateData(REFGUID Name, UINT *pDataSize, void *pData) override;
33 | virtual HRESULT STDMETHODCALLTYPE GetParent(REFIID riid, void **ppParent) override;
34 | #pragma endregion
35 | #pragma region IDXGIDevice
36 | virtual HRESULT STDMETHODCALLTYPE GetAdapter(IDXGIAdapter **pAdapter) override;
37 | virtual HRESULT STDMETHODCALLTYPE CreateSurface(const DXGI_SURFACE_DESC *pDesc, UINT NumSurfaces, DXGI_USAGE Usage, const DXGI_SHARED_RESOURCE *pSharedResource, IDXGISurface **ppSurface) override;
38 | virtual HRESULT STDMETHODCALLTYPE QueryResourceResidency(IUnknown *const *ppResources, DXGI_RESIDENCY *pResidencyStatus, UINT NumResources) override;
39 | virtual HRESULT STDMETHODCALLTYPE SetGPUThreadPriority(INT Priority) override;
40 | virtual HRESULT STDMETHODCALLTYPE GetGPUThreadPriority(INT *pPriority) override;
41 | #pragma endregion
42 | #pragma region IDXGIDevice1
43 | virtual HRESULT STDMETHODCALLTYPE SetMaximumFrameLatency(UINT MaxLatency) override;
44 | virtual HRESULT STDMETHODCALLTYPE GetMaximumFrameLatency(UINT *pMaxLatency) override;
45 | #pragma endregion
46 | #pragma region IDXGIDevice2
47 | virtual HRESULT STDMETHODCALLTYPE OfferResources(UINT NumResources, IDXGIResource *const *ppResources, DXGI_OFFER_RESOURCE_PRIORITY Priority) override;
48 | virtual HRESULT STDMETHODCALLTYPE ReclaimResources(UINT NumResources, IDXGIResource *const *ppResources, BOOL *pDiscarded) override;
49 | virtual HRESULT STDMETHODCALLTYPE EnqueueSetEvent(HANDLE hEvent) override;
50 | #pragma endregion
51 | #pragma region IDXGIDevice3
52 | virtual void STDMETHODCALLTYPE Trim() override;
53 | #pragma endregion
54 | #pragma region IDXGIDevice4
55 | virtual HRESULT STDMETHODCALLTYPE OfferResources1(UINT NumResources, IDXGIResource *const *ppResources, DXGI_OFFER_RESOURCE_PRIORITY Priority, UINT Flags) override;
56 | virtual HRESULT STDMETHODCALLTYPE ReclaimResources1(UINT NumResources, IDXGIResource *const *ppResources, DXGI_RECLAIM_RESOURCE_RESULTS *pResults) override;
57 | #pragma endregion
58 |
59 | LONG _ref = 1;
60 | IDXGIDevice1 *_orig;
61 | unsigned int _interface_version;
62 | IUnknown *const _direct3d_device;
63 | };
64 |
--------------------------------------------------------------------------------
/source/dxgi/dxgi_swapchain.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #pragma once
7 |
8 | #include "dxgi.hpp"
9 |
10 | struct DXGISwapChain : IDXGISwapChain4
11 | {
12 | DXGISwapChain(D3D10Device *device, IDXGISwapChain *original, const std::shared_ptr &runtime) :
13 | _orig(original),
14 | _interface_version(0),
15 | _direct3d_device(device),
16 | _direct3d_version(10),
17 | _runtime(runtime) { }
18 | DXGISwapChain(D3D10Device *device, IDXGISwapChain1 *original, const std::shared_ptr &runtime) :
19 | _orig(original),
20 | _interface_version(1),
21 | _direct3d_device(device),
22 | _direct3d_version(10),
23 | _runtime(runtime) { }
24 | DXGISwapChain(D3D11Device *device, IDXGISwapChain *original, const std::shared_ptr &runtime) :
25 | _orig(original),
26 | _interface_version(0),
27 | _direct3d_device(device),
28 | _direct3d_version(11),
29 | _runtime(runtime) { }
30 | DXGISwapChain(D3D11Device *device, IDXGISwapChain1 *original, const std::shared_ptr &runtime) :
31 | _orig(original),
32 | _interface_version(1),
33 | _direct3d_device(device),
34 | _direct3d_version(11),
35 | _runtime(runtime) { }
36 |
37 | DXGISwapChain(const DXGISwapChain &) = delete;
38 | DXGISwapChain &operator=(const DXGISwapChain &) = delete;
39 |
40 | #pragma region IUnknown
41 | virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObj) override;
42 | virtual ULONG STDMETHODCALLTYPE AddRef() override;
43 | virtual ULONG STDMETHODCALLTYPE Release() override;
44 | #pragma endregion
45 | #pragma region IDXGIObject
46 | virtual HRESULT STDMETHODCALLTYPE SetPrivateData(REFGUID Name, UINT DataSize, const void *pData) override;
47 | virtual HRESULT STDMETHODCALLTYPE SetPrivateDataInterface(REFGUID Name, const IUnknown *pUnknown) override;
48 | virtual HRESULT STDMETHODCALLTYPE GetPrivateData(REFGUID Name, UINT *pDataSize, void *pData) override;
49 | virtual HRESULT STDMETHODCALLTYPE GetParent(REFIID riid, void **ppParent) override;
50 | #pragma endregion
51 | #pragma region IDXGIDeviceSubObject
52 | virtual HRESULT STDMETHODCALLTYPE GetDevice(REFIID riid, void **ppDevice) override;
53 | #pragma endregion
54 | #pragma region IDXGISwapChain
55 | virtual HRESULT STDMETHODCALLTYPE Present(UINT SyncInterval, UINT Flags) override;
56 | virtual HRESULT STDMETHODCALLTYPE GetBuffer(UINT Buffer, REFIID riid, void **ppSurface) override;
57 | virtual HRESULT STDMETHODCALLTYPE SetFullscreenState(BOOL Fullscreen, IDXGIOutput *pTarget) override;
58 | virtual HRESULT STDMETHODCALLTYPE GetFullscreenState(BOOL *pFullscreen, IDXGIOutput **ppTarget) override;
59 | virtual HRESULT STDMETHODCALLTYPE GetDesc(DXGI_SWAP_CHAIN_DESC *pDesc) override;
60 | virtual HRESULT STDMETHODCALLTYPE ResizeBuffers(UINT BufferCount, UINT Width, UINT Height, DXGI_FORMAT NewFormat, UINT SwapChainFlags) override;
61 | virtual HRESULT STDMETHODCALLTYPE ResizeTarget(const DXGI_MODE_DESC *pNewTargetParameters) override;
62 | virtual HRESULT STDMETHODCALLTYPE GetContainingOutput(IDXGIOutput **ppOutput) override;
63 | virtual HRESULT STDMETHODCALLTYPE GetFrameStatistics(DXGI_FRAME_STATISTICS *pStats) override;
64 | virtual HRESULT STDMETHODCALLTYPE GetLastPresentCount(UINT *pLastPresentCount) override;
65 | #pragma endregion
66 | #pragma region IDXGISwapChain1
67 | virtual HRESULT STDMETHODCALLTYPE GetDesc1(DXGI_SWAP_CHAIN_DESC1 *pDesc) override;
68 | virtual HRESULT STDMETHODCALLTYPE GetFullscreenDesc(DXGI_SWAP_CHAIN_FULLSCREEN_DESC *pDesc) override;
69 | virtual HRESULT STDMETHODCALLTYPE GetHwnd(HWND *pHwnd) override;
70 | virtual HRESULT STDMETHODCALLTYPE GetCoreWindow(REFIID refiid, void **ppUnk) override;
71 | virtual HRESULT STDMETHODCALLTYPE Present1(UINT SyncInterval, UINT PresentFlags, const DXGI_PRESENT_PARAMETERS *pPresentParameters) override;
72 | virtual BOOL STDMETHODCALLTYPE IsTemporaryMonoSupported() override;
73 | virtual HRESULT STDMETHODCALLTYPE GetRestrictToOutput(IDXGIOutput **ppRestrictToOutput) override;
74 | virtual HRESULT STDMETHODCALLTYPE SetBackgroundColor(const DXGI_RGBA *pColor) override;
75 | virtual HRESULT STDMETHODCALLTYPE GetBackgroundColor(DXGI_RGBA *pColor) override;
76 | virtual HRESULT STDMETHODCALLTYPE SetRotation(DXGI_MODE_ROTATION Rotation) override;
77 | virtual HRESULT STDMETHODCALLTYPE GetRotation(DXGI_MODE_ROTATION *pRotation) override;
78 | #pragma endregion
79 | #pragma region IDXGISwapChain2
80 | virtual HRESULT STDMETHODCALLTYPE SetSourceSize(UINT Width, UINT Height) override;
81 | virtual HRESULT STDMETHODCALLTYPE GetSourceSize(UINT *pWidth, UINT *pHeight) override;
82 | virtual HRESULT STDMETHODCALLTYPE SetMaximumFrameLatency(UINT MaxLatency) override;
83 | virtual HRESULT STDMETHODCALLTYPE GetMaximumFrameLatency(UINT *pMaxLatency) override;
84 | virtual HANDLE STDMETHODCALLTYPE GetFrameLatencyWaitableObject() override;
85 | virtual HRESULT STDMETHODCALLTYPE SetMatrixTransform(const DXGI_MATRIX_3X2_F *pMatrix) override;
86 | virtual HRESULT STDMETHODCALLTYPE GetMatrixTransform(DXGI_MATRIX_3X2_F *pMatrix) override;
87 | #pragma endregion
88 | #pragma region IDXGISwapChain3
89 | virtual UINT STDMETHODCALLTYPE GetCurrentBackBufferIndex() override;
90 | virtual HRESULT STDMETHODCALLTYPE CheckColorSpaceSupport(DXGI_COLOR_SPACE_TYPE ColorSpace, UINT *pColorSpaceSupport) override;
91 | virtual HRESULT STDMETHODCALLTYPE SetColorSpace1(DXGI_COLOR_SPACE_TYPE ColorSpace) override;
92 | virtual HRESULT STDMETHODCALLTYPE ResizeBuffers1(UINT BufferCount, UINT Width, UINT Height, DXGI_FORMAT Format, UINT SwapChainFlags, const UINT *pCreationNodeMask, IUnknown *const *ppPresentQueue) override;
93 | #pragma endregion
94 | #pragma region IDXGISwapChain4
95 | virtual HRESULT STDMETHODCALLTYPE SetHDRMetaData(DXGI_HDR_METADATA_TYPE Type, UINT Size, void *pMetaData) override;
96 | #pragma endregion
97 |
98 | LONG _ref = 1;
99 | IDXGISwapChain *_orig;
100 | unsigned int _interface_version;
101 | IUnknown *const _direct3d_device;
102 | const unsigned int _direct3d_version;
103 | std::shared_ptr _runtime;
104 | };
105 |
--------------------------------------------------------------------------------
/source/effect_lexer.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #pragma once
7 |
8 | #include "source_location.hpp"
9 |
10 | namespace reshadefx
11 | {
12 | ///
13 | /// A collection of identifiers for various possible tokens.
14 | ///
15 | enum class tokenid
16 | {
17 | unknown = -1,
18 | end_of_file = 0,
19 | end_of_line = '\n',
20 |
21 | // operators
22 | space = ' ',
23 | exclaim = '!',
24 | hash = '#',
25 | dollar = '$',
26 | percent = '%',
27 | ampersand = '&',
28 | parenthesis_open = '(',
29 | parenthesis_close = ')',
30 | star = '*',
31 | plus = '+',
32 | comma = ',',
33 | minus = '-',
34 | dot = '.',
35 | slash = '/',
36 | colon = ':',
37 | semicolon = ';',
38 | less = '<',
39 | equal = '=',
40 | greater = '>',
41 | question = '?',
42 | at = '@',
43 | bracket_open = '[',
44 | backslash = '\\',
45 | bracket_close = ']',
46 | caret = '^',
47 | brace_open = '{',
48 | pipe = '|',
49 | brace_close = '}',
50 | tilde = '~',
51 | exclaim_equal = 256 /* != */,
52 | percent_equal /* %= */,
53 | ampersand_ampersand /* && */,
54 | ampersand_equal /* &= */,
55 | star_equal /* *= */,
56 | plus_plus /* ++*/,
57 | plus_equal /* += */,
58 | minus_minus /* -- */,
59 | minus_equal /* -= */,
60 | arrow /* -> */,
61 | ellipsis /* ... */,
62 | slash_equal /* /= */,
63 | colon_colon /* :: */,
64 | less_less_equal /* <<= */,
65 | less_less /* << */,
66 | less_equal /* <= */,
67 | equal_equal /* == */,
68 | greater_greater_equal /* >>= */,
69 | greater_greater /* >> */,
70 | greater_equal /* >= */,
71 | caret_equal /* ^= */,
72 | pipe_equal /* |= */,
73 | pipe_pipe /* || */,
74 |
75 | // identifiers
76 | reserved,
77 | identifier,
78 |
79 | // literals
80 | true_literal,
81 | false_literal,
82 | int_literal,
83 | uint_literal,
84 | float_literal,
85 | double_literal,
86 | string_literal,
87 |
88 | // keywords
89 | namespace_,
90 | struct_,
91 | technique,
92 | pass,
93 | for_,
94 | while_,
95 | do_,
96 | if_,
97 | else_,
98 | switch_,
99 | case_,
100 | default_,
101 | break_,
102 | continue_,
103 | return_,
104 | discard_,
105 | extern_,
106 | static_,
107 | uniform_,
108 | volatile_,
109 | precise,
110 | in,
111 | out,
112 | inout,
113 | const_,
114 | linear,
115 | noperspective,
116 | centroid,
117 | nointerpolation,
118 |
119 | void_,
120 | bool_,
121 | bool2,
122 | bool2x2,
123 | bool3,
124 | bool3x3,
125 | bool4,
126 | bool4x4,
127 | int_,
128 | int2,
129 | int2x2,
130 | int3,
131 | int3x3,
132 | int4,
133 | int4x4,
134 | uint_,
135 | uint2,
136 | uint2x2,
137 | uint3,
138 | uint3x3,
139 | uint4,
140 | uint4x4,
141 | float_,
142 | float2,
143 | float2x2,
144 | float3,
145 | float3x3,
146 | float4,
147 | float4x4,
148 | vector,
149 | matrix,
150 | string_,
151 | texture,
152 | sampler,
153 |
154 | // preprocessor directives
155 | hash_def,
156 | hash_undef,
157 | hash_if,
158 | hash_ifdef,
159 | hash_ifndef,
160 | hash_else,
161 | hash_elif,
162 | hash_endif,
163 | hash_error,
164 | hash_warning,
165 | hash_pragma,
166 | hash_include,
167 | hash_unknown,
168 | };
169 |
170 | ///
171 | /// A structure describing a single token in the input string.
172 | ///
173 | struct token
174 | {
175 | tokenid id;
176 | location location;
177 | size_t offset, length;
178 | union
179 | {
180 | int literal_as_int;
181 | unsigned int literal_as_uint;
182 | float literal_as_float;
183 | double literal_as_double;
184 | };
185 | std::string literal_as_string;
186 |
187 | inline operator tokenid() const { return id; }
188 | };
189 |
190 | ///
191 | /// A lexical analyzer implementation.
192 | ///
193 | class lexer
194 | {
195 | public:
196 | ///
197 | /// Construct a new lexical analyzer for an input string.
198 | ///
199 | /// The string to analyze.
200 | explicit lexer(
201 | const std::string &input,
202 | bool ignore_whitespace = true,
203 | bool ignore_pp_directives = true,
204 | bool ignore_keywords = false,
205 | bool escape_string_literals = true);
206 | ///
207 | /// Construct a copy of an existing instance.
208 | ///
209 | /// The instance to copy.
210 | lexer(const lexer &lexer);
211 | lexer &operator=(const lexer &);
212 |
213 | ///
214 | /// Get the input string this lexical analyzer works on.
215 | ///
216 | /// A constant reference to the input string.
217 | inline const std::string &input_string() const { return _input; }
218 |
219 | ///
220 | /// Perform lexical analysis on the input string and return the next token in sequence.
221 | ///
222 | /// The next token from the input string.
223 | token lex();
224 |
225 | ///
226 | /// Advances to the next token that is not whitespace.
227 | ///
228 | void skip_space();
229 | ///
230 | /// Advances to the next new line, ignoring all tokens.
231 | ///
232 | void skip_to_next_line();
233 |
234 | private:
235 | ///
236 | /// Skips an arbitary amount of characters in the input string.
237 | ///
238 | /// The number of input characters to skip.
239 | void skip(size_t length);
240 |
241 | void parse_identifier(token &tok) const;
242 | bool parse_pp_directive(token &tok);
243 | void parse_string_literal(token &tok, bool escape) const;
244 | void parse_numeric_literal(token &tok) const;
245 |
246 | std::string _input;
247 | location _cur_location;
248 | const std::string::value_type *_cur, *_end;
249 | bool _ignore_whitespace;
250 | bool _ignore_pp_directives;
251 | bool _ignore_keywords;
252 | bool _escape_string_literals;
253 | };
254 | }
255 |
--------------------------------------------------------------------------------
/source/effect_parser.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #pragma once
7 |
8 | #include
9 | #include "effect_lexer.hpp"
10 | #include "effect_syntax_tree.hpp"
11 |
12 | namespace reshadefx
13 | {
14 | ///
15 | /// A parser for the ReShade FX language.
16 | ///
17 | class parser
18 | {
19 | public:
20 | ///
21 | /// Construct a new parser instance.
22 | ///
23 | explicit parser(syntax_tree &ast);
24 | parser(const parser &) = delete;
25 | ~parser();
26 |
27 | parser &operator=(const parser &) = delete;
28 |
29 | ///
30 | /// Gets the list of error messages.
31 | ///
32 | const std::string &errors() const { return _errors; }
33 |
34 | ///
35 | /// Parse the provided input string.
36 | ///
37 | /// The string to analyze.
38 | /// A boolean value indicating whether parsing was successful or not.
39 | bool run(const std::string &source);
40 |
41 | private:
42 | void error(const location &location, unsigned int code, const std::string &message);
43 | void warning(const location &location, unsigned int code, const std::string &message);
44 |
45 | void backup();
46 | void restore();
47 |
48 | bool peek(tokenid tokid) const;
49 | bool peek(char tok) const { return peek(static_cast(tok)); }
50 | bool peek_multary_op(enum nodes::binary_expression_node::op &op, unsigned int &precedence) const;
51 | void consume();
52 | void consume_until(tokenid tokid);
53 | void consume_until(char tok) { return consume_until(static_cast(tok)); }
54 | bool accept(tokenid tokid);
55 | bool accept(char tok) { return accept(static_cast(tok)); }
56 | bool accept_type_class(nodes::type_node &type);
57 | bool accept_type_qualifiers(nodes::type_node &type);
58 | bool accept_unary_op(enum nodes::unary_expression_node::op &op);
59 | bool accept_postfix_op(enum nodes::unary_expression_node::op &op);
60 | bool accept_assignment_op(enum nodes::assignment_expression_node::op &op);
61 | bool expect(tokenid tokid);
62 | bool expect(char tok) { return expect(static_cast(tok)); }
63 |
64 | bool parse_top_level();
65 | bool parse_namespace();
66 | bool parse_type(nodes::type_node &type);
67 | bool parse_expression(nodes::expression_node *&node);
68 | bool parse_expression_unary(nodes::expression_node *&node);
69 | bool parse_expression_multary(nodes::expression_node *&left, unsigned int left_precedence = 0);
70 | bool parse_expression_assignment(nodes::expression_node *&left);
71 | bool parse_statement(nodes::statement_node *&statement, bool scoped = true);
72 | bool parse_statement_block(nodes::statement_node *&statement, bool scoped = true);
73 | bool parse_statement_declarator_list(nodes::statement_node *&statement);
74 | bool parse_array(int &size);
75 | bool parse_annotations(std::unordered_map &annotations);
76 | bool parse_struct(nodes::struct_declaration_node *&structure);
77 | bool parse_function_declaration(nodes::type_node &type, std::string name, nodes::function_declaration_node *&function);
78 | bool parse_variable_declaration(nodes::type_node &type, std::string name, nodes::variable_declaration_node *&variable, bool global = false);
79 | bool parse_variable_assignment(nodes::expression_node *&expression);
80 | bool parse_variable_properties(nodes::variable_declaration_node *variable);
81 | bool parse_variable_properties_expression(nodes::expression_node *&expression);
82 | bool parse_technique(nodes::technique_declaration_node *&technique);
83 | bool parse_technique_pass(nodes::pass_declaration_node *&pass);
84 | bool parse_technique_pass_expression(nodes::expression_node *&expression);
85 |
86 | syntax_tree &_ast;
87 | std::string _errors;
88 | std::unique_ptr _lexer, _lexer_backup;
89 | token _token, _token_next, _token_backup;
90 | std::unique_ptr _symbol_table;
91 | };
92 | }
93 |
--------------------------------------------------------------------------------
/source/effect_preprocessor.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #pragma once
7 |
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include "effect_lexer.hpp"
13 | #include "filesystem.hpp"
14 |
15 | namespace reshadefx
16 | {
17 | ///
18 | /// A C-style pre-processor implementation.
19 | ///
20 | class preprocessor
21 | {
22 | public:
23 | struct macro
24 | {
25 | std::string replacement_list;
26 | bool is_function_like = false, is_variadic = false;
27 | std::vector parameters;
28 | };
29 |
30 | void add_include_path(const reshade::filesystem::path &path);
31 | bool add_macro_definition(const std::string &name, const macro ¯o);
32 | bool add_macro_definition(const std::string &name, const std::string &value = "1");
33 |
34 | const std::string &errors() const { return _errors; }
35 | const std::string ¤t_output() const { return _output; }
36 | const std::vector ¤t_pragmas() const { return _pragmas; }
37 |
38 | bool run(const reshade::filesystem::path &file_path);
39 | bool run(const reshade::filesystem::path &file_path, std::vector &included_files);
40 |
41 | private:
42 | struct if_level
43 | {
44 | token token;
45 | bool value, skipping;
46 | if_level *parent;
47 | };
48 | struct input_level
49 | {
50 | input_level(const std::string &name, const std::string &text, input_level *parent) :
51 | _name(name),
52 | _lexer(new lexer(text, false, false, true, false)),
53 | _parent(parent)
54 | {
55 | _next_token.id = tokenid::unknown;
56 | _next_token.offset = _next_token.length = 0;
57 | }
58 |
59 | std::string _name;
60 | std::unique_ptr _lexer;
61 | token _next_token;
62 | size_t _offset;
63 | std::stack _if_stack;
64 | input_level *_parent;
65 | };
66 |
67 | void error(const location &location, const std::string &message);
68 | void warning(const location &location, const std::string &message);
69 |
70 | lexer ¤t_lexer();
71 | inline token current_token() const { return _token; }
72 | std::stack ¤t_if_stack();
73 | if_level ¤t_if_level();
74 | void push(const std::string &input, const std::string &name = std::string());
75 | bool peek(tokenid token) const;
76 | void consume();
77 | void consume_until(tokenid token);
78 | bool accept(tokenid token);
79 | bool expect(tokenid token);
80 |
81 | void parse();
82 | void parse_def();
83 | void parse_undef();
84 | void parse_if();
85 | void parse_ifdef();
86 | void parse_ifndef();
87 | void parse_elif();
88 | void parse_else();
89 | void parse_endif();
90 | void parse_error();
91 | void parse_warning();
92 | void parse_pragma();
93 | void parse_include();
94 |
95 | bool evaluate_expression();
96 | bool evaluate_identifier_as_macro();
97 |
98 | void expand_macro(const macro ¯o, const std::vector &arguments, std::string &out);
99 | void create_macro_replacement_list(macro ¯o);
100 |
101 | bool _success = true;
102 | token _token;
103 | std::stack _input_stack;
104 | location _output_location;
105 | std::string _output, _errors, _current_token_raw_data;
106 | int _recursion_count = 0;
107 | std::unordered_map _macros;
108 | std::vector _pragmas;
109 | std::vector _include_paths;
110 | std::unordered_map _filecache;
111 | };
112 | }
113 |
--------------------------------------------------------------------------------
/source/effect_symbol_table.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #pragma once
7 |
8 | #include
9 | #include
10 | #include
11 |
12 | namespace reshadefx
13 | {
14 | #pragma region Forward Declarations
15 | namespace nodes
16 | {
17 | struct declaration_node;
18 | struct call_expression_node;
19 | }
20 | #pragma endregion
21 |
22 | ///
23 | /// A scope encapsulating a list of symbols.
24 | ///
25 | struct scope
26 | {
27 | std::string name;
28 | unsigned int level, namespace_level;
29 | };
30 |
31 | ///
32 | /// A single symbol in the symbol table.
33 | ///
34 | using symbol = nodes::declaration_node *;
35 |
36 | ///
37 | /// A symbol table managing a list of scopes and symbols.
38 | ///
39 | class symbol_table
40 | {
41 | public:
42 | symbol_table();
43 |
44 | void enter_scope(symbol parent = nullptr);
45 | void enter_namespace(const std::string &name);
46 | void leave_scope();
47 | void leave_namespace();
48 |
49 | symbol current_parent() const { return _parent_stack.empty() ? nullptr : _parent_stack.top(); }
50 | const scope ¤t_scope() const { return _current_scope; }
51 |
52 | bool insert(symbol symbol, bool global = false);
53 | symbol find(const std::string &name) const;
54 | symbol find(const std::string &name, const scope &scope, bool exclusive) const;
55 | bool resolve_call(nodes::call_expression_node *call, const scope &scope, bool &intrinsic, bool &ambiguous) const;
56 |
57 | private:
58 | scope _current_scope;
59 | std::stack _parent_stack;
60 | std::unordered_map>> _symbol_stack;
61 | };
62 | }
63 |
--------------------------------------------------------------------------------
/source/effect_syntax_tree.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #pragma once
7 |
8 | #include "effect_syntax_tree_nodes.hpp"
9 | #include
10 |
11 | namespace reshadefx
12 | {
13 | class syntax_tree
14 | {
15 | syntax_tree(const syntax_tree &) = delete;
16 | syntax_tree &operator=(const syntax_tree &) = delete;
17 |
18 | public:
19 | syntax_tree() { }
20 |
21 | template
22 | T *make_node(const location &location)
23 | {
24 | const auto node = _pool.add();
25 | node->location = location;
26 |
27 | return node;
28 | }
29 |
30 | std::vector structs;
31 | std::vector variables;
32 | std::vector functions;
33 | std::vector techniques;
34 |
35 | private:
36 | class memory_pool
37 | {
38 | struct page
39 | {
40 | explicit page(size_t size) : cursor(0), memory(size, '\0') { }
41 |
42 | size_t cursor;
43 | std::vector memory;
44 | };
45 | struct nodeinfo
46 | {
47 | size_t size;
48 | void(*dtor)(void *);
49 | unsigned char data[sizeof(node)];
50 | };
51 |
52 | public:
53 | ~memory_pool()
54 | {
55 | clear();
56 | }
57 |
58 | template
59 | T *add()
60 | {
61 | auto size = sizeof(nodeinfo) - sizeof(node) + sizeof(T);
62 | auto page = std::find_if(_pages.begin(), _pages.end(),
63 | [size](const struct page &page)
64 | {
65 | return page.cursor + size < page.memory.size();
66 | });
67 |
68 | if (page == _pages.end())
69 | {
70 | _pages.emplace_back(std::max(size_t(4096), size));
71 |
72 | page = std::prev(_pages.end());
73 | }
74 |
75 | const auto node = new (&page->memory.at(page->cursor)) nodeinfo;
76 | const auto node_data = new (&node->data) T();
77 | node->size = size;
78 | node->dtor = [](void *object) { reinterpret_cast(object)->~T(); };
79 |
80 | page->cursor += node->size;
81 |
82 | return node_data;
83 | }
84 | void clear()
85 | {
86 | for (auto &page : _pages)
87 | {
88 | auto node = reinterpret_cast(&page.memory.front());
89 |
90 | do
91 | {
92 | node->dtor(node->data);
93 | node = reinterpret_cast(reinterpret_cast(node) + node->size);
94 | }
95 | while (node->size > 0 && (page.cursor -= node->size) > 0);
96 | }
97 | }
98 |
99 | private:
100 | std::list _pages;
101 | } _pool;
102 | };
103 | }
104 |
--------------------------------------------------------------------------------
/source/filesystem.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #include "filesystem.hpp"
7 | #include "string_codecvt.hpp"
8 |
9 | #include
10 | #include
11 |
12 | namespace reshade::filesystem
13 | {
14 | bool path::operator==(const path &other) const
15 | {
16 | return _stricmp(_data.c_str(), other._data.c_str()) == 0;
17 | }
18 | bool path::operator!=(const path &other) const
19 | {
20 | return !operator==(other);
21 | }
22 |
23 | std::wstring path::wstring() const
24 | {
25 | return utf8_to_utf16(_data);
26 | }
27 |
28 | std::ostream &operator<<(std::ostream &stream, const path &path)
29 | {
30 | WCHAR username[257];
31 | DWORD username_length = _countof(username);
32 | GetUserNameW(username, &username_length);
33 | username_length -= 1;
34 |
35 | std::wstring result = utf8_to_utf16(path._data);
36 |
37 | for (size_t start_pos = 0; (start_pos = result.find(username, start_pos)) != std::wstring::npos; start_pos += username_length)
38 | {
39 | result.replace(start_pos, username_length, username_length, '*');
40 | }
41 |
42 | return stream << '\'' << utf16_to_utf8(result) << '\'';
43 | }
44 |
45 | bool path::is_absolute() const
46 | {
47 | return PathIsRelativeW(utf8_to_utf16(_data).c_str()) == FALSE;
48 | }
49 |
50 | path path::parent_path() const
51 | {
52 | WCHAR buffer[MAX_PATH] = { };
53 | utf8_to_utf16(_data, buffer);
54 |
55 | PathRemoveFileSpecW(buffer);
56 | return utf16_to_utf8(buffer);
57 | }
58 | path path::filename() const
59 | {
60 | WCHAR buffer[MAX_PATH] = { };
61 | utf8_to_utf16(_data, buffer);
62 |
63 | return utf16_to_utf8(PathFindFileNameW(buffer));
64 | }
65 | path path::filename_without_extension() const
66 | {
67 | WCHAR buffer[MAX_PATH] = { };
68 | utf8_to_utf16(_data, buffer);
69 |
70 | PathRemoveExtensionW(buffer);
71 | return utf16_to_utf8(PathFindFileNameW(buffer));
72 | }
73 | std::string path::extension() const
74 | {
75 | WCHAR buffer[MAX_PATH] = { };
76 | utf8_to_utf16(_data, buffer);
77 |
78 | return utf16_to_utf8(PathFindExtensionW(buffer));
79 | }
80 |
81 | path &path::replace_extension(const std::string &extension)
82 | {
83 | WCHAR buffer[MAX_PATH] = { };
84 | utf8_to_utf16(_data, buffer);
85 |
86 | PathRenameExtensionW(buffer, utf8_to_utf16(extension).c_str());
87 | return operator=(utf16_to_utf8(buffer));
88 | }
89 |
90 | path path::operator/(const path &more) const
91 | {
92 | WCHAR buffer[MAX_PATH] = { };
93 | utf8_to_utf16(_data, buffer);
94 |
95 | PathAppendW(buffer, utf8_to_utf16(more.string()).c_str());
96 | return utf16_to_utf8(buffer);
97 | }
98 |
99 | bool exists(const path &path)
100 | {
101 | return GetFileAttributesW(path.wstring().c_str()) != INVALID_FILE_ATTRIBUTES;
102 | }
103 | path resolve(const path &filename, const std::vector &paths)
104 | {
105 | for (const auto &path : paths)
106 | {
107 | auto result = absolute(filename, path);
108 |
109 | if (exists(result))
110 | {
111 | return result;
112 | }
113 | }
114 |
115 | return filename;
116 | }
117 | path absolute(const path &filename, const path &parent_path)
118 | {
119 | if (filename.is_absolute())
120 | {
121 | return filename;
122 | }
123 |
124 | WCHAR result[MAX_PATH] = { };
125 | PathCombineW(result, utf8_to_utf16(parent_path.string()).c_str(), utf8_to_utf16(filename.string()).c_str());
126 |
127 | return utf16_to_utf8(result);
128 | }
129 |
130 | path get_module_path(void *handle)
131 | {
132 | WCHAR result[MAX_PATH] = { };
133 | GetModuleFileNameW(static_cast(handle), result, MAX_PATH);
134 |
135 | return utf16_to_utf8(result);
136 | }
137 | path get_special_folder_path(special_folder id)
138 | {
139 | WCHAR result[MAX_PATH] = { };
140 |
141 | switch (id)
142 | {
143 | case special_folder::app_data:
144 | SHGetFolderPathW(nullptr, CSIDL_APPDATA, nullptr, SHGFP_TYPE_CURRENT, result);
145 | break;
146 | case special_folder::system:
147 | GetSystemDirectoryW(result, MAX_PATH);
148 | break;
149 | case special_folder::windows:
150 | GetWindowsDirectoryW(result, MAX_PATH);
151 | }
152 |
153 | return utf16_to_utf8(result);
154 | }
155 |
156 | std::vector list_files(const path &path, const std::string &mask, bool recursive)
157 | {
158 | if (!PathIsDirectoryW(path.wstring().c_str()))
159 | {
160 | return { };
161 | }
162 |
163 | WIN32_FIND_DATAW ffd;
164 |
165 | const HANDLE handle = FindFirstFileW((path / mask).wstring().c_str(), &ffd);
166 |
167 | if (handle == INVALID_HANDLE_VALUE)
168 | {
169 | return { };
170 | }
171 |
172 | std::vector result;
173 |
174 | do
175 | {
176 | const auto filename = utf16_to_utf8(ffd.cFileName);
177 |
178 | if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
179 | {
180 | if (recursive)
181 | {
182 | const auto recursive_result = list_files(filename, mask, true);
183 | result.insert(result.end(), recursive_result.begin(), recursive_result.end());
184 | }
185 | }
186 | else
187 | {
188 | result.push_back(path / filename);
189 | }
190 | }
191 | while (FindNextFileW(handle, &ffd));
192 |
193 | FindClose(handle);
194 |
195 | return result;
196 | }
197 | }
198 |
--------------------------------------------------------------------------------
/source/filesystem.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #pragma once
7 |
8 | #include
9 | #include
10 | #include
11 |
12 | namespace reshade::filesystem
13 | {
14 | enum class special_folder
15 | {
16 | app_data,
17 | system,
18 | windows,
19 | };
20 |
21 | class path
22 | {
23 | public:
24 | path() { }
25 | path(const char *data) : _data(data) { }
26 | path(std::string data) : _data(std::move(data)) { }
27 |
28 | bool operator==(const path &other) const;
29 | bool operator!=(const path &other) const;
30 |
31 | std::string &string() { return _data; }
32 | const std::string &string() const { return _data; }
33 | std::wstring wstring() const;
34 |
35 | friend std::ostream &operator<<(std::ostream &stream, const path &path);
36 |
37 | bool empty() const { return _data.empty(); }
38 | size_t length() const { return _data.length(); }
39 | bool is_absolute() const;
40 |
41 | path parent_path() const;
42 | path filename() const;
43 | path filename_without_extension() const;
44 | std::string extension() const;
45 |
46 | path &remove_filename() { return operator=(parent_path()); }
47 | path &replace_extension(const std::string &extension);
48 |
49 | path operator/(const path &more) const;
50 | path operator+(char c) const { return _data + c; }
51 | path operator+(const path &more) const { return _data + more._data; }
52 |
53 | private:
54 | std::string _data;
55 | };
56 |
57 | bool exists(const path &path);
58 | path resolve(const path &filename, const std::vector &paths);
59 | path absolute(const path &filename, const path &parent_path);
60 |
61 | path get_module_path(void *handle);
62 | path get_special_folder_path(special_folder id);
63 |
64 | std::vector list_files(const path &path, const std::string &mask = "*", bool recursive = false);
65 | }
66 |
--------------------------------------------------------------------------------
/source/hook.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #include "hook.hpp"
7 | #include
8 | #include
9 |
10 | namespace reshade
11 | {
12 | static unsigned long s_reference_count = 0;
13 |
14 | void hook::enable(bool enable) const
15 | {
16 | if (enable)
17 | {
18 | MH_QueueEnableHook(target);
19 | }
20 | else
21 | {
22 | MH_QueueDisableHook(target);
23 | }
24 | }
25 |
26 | hook::status hook::install()
27 | {
28 | if (!valid())
29 | {
30 | return hook::status::unsupported_function;
31 | }
32 |
33 | if (s_reference_count++ == 0)
34 | {
35 | MH_Initialize();
36 | }
37 |
38 | const MH_STATUS statuscode = MH_CreateHook(target, replacement, &trampoline);
39 |
40 | if (statuscode == MH_OK || statuscode == MH_ERROR_ALREADY_CREATED)
41 | {
42 | enable(true);
43 |
44 | return hook::status::success;
45 | }
46 |
47 | if (--s_reference_count == 0)
48 | {
49 | MH_Uninitialize();
50 | }
51 |
52 | return static_cast(statuscode);
53 | }
54 | hook::status hook::uninstall()
55 | {
56 | if (!valid())
57 | {
58 | return hook::status::unsupported_function;
59 | }
60 |
61 | const MH_STATUS statuscode = MH_RemoveHook(target);
62 |
63 | if (statuscode == MH_ERROR_NOT_CREATED)
64 | {
65 | return hook::status::success;
66 | }
67 | else if (statuscode != MH_OK)
68 | {
69 | return static_cast(statuscode);
70 | }
71 |
72 | trampoline = nullptr;
73 |
74 | if (--s_reference_count == 0)
75 | {
76 | MH_Uninitialize();
77 | }
78 |
79 | return hook::status::success;
80 | }
81 |
82 | hook::address hook::call() const
83 | {
84 | assert(installed());
85 |
86 | return trampoline;
87 | }
88 |
89 | bool hook::apply_queued_actions()
90 | {
91 | return MH_ApplyQueued() == MH_OK;
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/source/hook.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #pragma once
7 |
8 | namespace reshade
9 | {
10 | struct hook
11 | {
12 | ///
13 | /// Address of a function.
14 | ///
15 | using address = void *;
16 |
17 | ///
18 | /// Enumeration of status codes.
19 | ///
20 | enum class status
21 | {
22 | unknown = -1,
23 | success,
24 | not_executable = 7,
25 | unsupported_function,
26 | allocation_failure,
27 | memory_protection_failure,
28 | };
29 |
30 | ///
31 | /// Actually enable or disable any queues hooks.
32 | ///
33 | static bool apply_queued_actions();
34 |
35 | ///
36 | /// Return whether the hook is valid.
37 | ///
38 | bool valid() const { return target != nullptr && replacement != nullptr && target != replacement; }
39 | ///
40 | /// Return whether the hook is currently installed.
41 | ///
42 | bool installed() const { return trampoline != nullptr; }
43 | ///
44 | /// Return whether the hook is not currently installed.
45 | ///
46 | bool uninstalled() const { return trampoline == nullptr; }
47 |
48 | ///
49 | /// Enable or disable the hook. This queues the action for later execution in .
50 | ///
51 | /// Boolean indicating if hook should be enabled or disabled.
52 | void enable(bool enable) const;
53 | ///
54 | /// Install the hook.
55 | ///
56 | hook::status install();
57 | ///
58 | /// Uninstall the hook.
59 | ///
60 | hook::status uninstall();
61 |
62 | ///
63 | /// Return the trampoline function address of the hook.
64 | ///
65 | address call() const;
66 | template
67 | T call() const { return reinterpret_cast(call()); }
68 |
69 | address target = nullptr;
70 | address trampoline = nullptr;
71 | address replacement = nullptr;
72 | };
73 | }
74 |
--------------------------------------------------------------------------------
/source/hook_manager.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #pragma once
7 |
8 | #include "hook.hpp"
9 | #include "filesystem.hpp"
10 |
11 | #define HOOK_EXPORT extern "C"
12 |
13 | template
14 | inline reshade::hook::address *vtable_from_instance(T *instance)
15 | {
16 | static_assert(std::is_polymorphic::value, "can only get virtual function table from polymorphic types");
17 |
18 | return *reinterpret_cast(instance);
19 | }
20 |
21 | namespace reshade::hooks
22 | {
23 | ///
24 | /// Install hook for the specified target function.
25 | ///
26 | /// The function name. This is used for debugging only.
27 | /// The address of the target function.
28 | /// The address of the hook function.
29 | /// Set this to true to queue the enable action instead of immediately executing it.
30 | /// The status of the hook installation.
31 | bool install(const char *name, hook::address target, hook::address replacement, bool queue_enable = false);
32 | ///
33 | /// Install hook for the specified virtual function table entry.
34 | ///
35 | /// The function name. This is used for debugging only.
36 | /// The virtual function table pointer of the object to targeted object.
37 | /// The index of the target function in the virtual function table.
38 | /// The address of the hook function.
39 | /// The status of the hook installation.
40 | bool install(const char *name, hook::address vtable[], unsigned int offset, hook::address replacement);
41 | ///
42 | /// Uninstall all previously installed hooks.
43 | /// Only call this function as long as the loader-lock is active, since it is not thread-safe.
44 | ///
45 | void uninstall();
46 | ///
47 | /// Register the matching exports in the specified module and install or delay their hooking.
48 | /// Only call this function as long as the loader-lock is active, since it is not thread-safe.
49 | ///
50 | /// The file path to the target module.
51 | void register_module(const filesystem::path &path);
52 |
53 | ///
54 | /// Call the original/trampoline function for the specified hook.
55 | ///
56 | /// The address of the hook function which was previously used to install a hook.
57 | /// The address of original/trampoline function.
58 | hook::address call(hook::address replacement);
59 | template
60 | inline T call(T replacement)
61 | {
62 | return reinterpret_cast(call(reinterpret_cast(replacement)));
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/source/ini_file.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #include "ini_file.hpp"
7 | #include
8 |
9 | namespace reshade
10 | {
11 | static inline void trim(std::string &str, const char *chars = " \t")
12 | {
13 | str.erase(0, str.find_first_not_of(chars));
14 | str.erase(str.find_last_not_of(chars) + 1);
15 | }
16 | static inline std::string trim(const std::string &str, const char *chars = " \t")
17 | {
18 | std::string res(str);
19 | trim(res, chars);
20 | return res;
21 | }
22 |
23 | ini_file::ini_file(const filesystem::path &path) : _path(path)
24 | {
25 | load();
26 | }
27 | ini_file::~ini_file()
28 | {
29 | save();
30 | }
31 |
32 | void ini_file::load()
33 | {
34 | std::string line, section;
35 | std::ifstream file(_path.wstring());
36 |
37 | while (std::getline(file, line))
38 | {
39 | trim(line);
40 |
41 | if (line.empty() || line[0] == ';' || line[0] == '/')
42 | {
43 | continue;
44 | }
45 |
46 | // Read section name
47 | if (line[0] == '[')
48 | {
49 | section = trim(line.substr(0, line.find(']')), " \t[]");
50 | continue;
51 | }
52 |
53 | // Read section content
54 | const auto assign_index = line.find('=');
55 |
56 | if (assign_index != std::string::npos)
57 | {
58 | const auto key = trim(line.substr(0, assign_index));
59 | const auto value = trim(line.substr(assign_index + 1));
60 | std::vector value_splitted;
61 |
62 | for (size_t i = 0, len = value.size(), found; i < len; i = found + 1)
63 | {
64 | found = value.find_first_of(',', i);
65 |
66 | if (found == std::string::npos)
67 | found = len;
68 |
69 | value_splitted.push_back(value.substr(i, found - i));
70 | }
71 |
72 | _sections[section][key] = value_splitted;
73 | }
74 | else
75 | {
76 | _sections[section][line] = 0;
77 | }
78 | }
79 | }
80 | void ini_file::save() const
81 | {
82 | if (!_modified)
83 | {
84 | return;
85 | }
86 |
87 | std::ofstream file(_path.wstring());
88 |
89 | const auto it = _sections.find("");
90 |
91 | if (it != _sections.end())
92 | {
93 | for (const auto §ion_line : it->second)
94 | {
95 | file << section_line.first << '=';
96 |
97 | size_t i = 0;
98 |
99 | for (const auto &item : section_line.second.data())
100 | {
101 | if (i++ != 0)
102 | {
103 | file << ',';
104 | }
105 |
106 | file << item;
107 | }
108 |
109 | file << std::endl;
110 | }
111 |
112 | file << std::endl;
113 | }
114 |
115 | for (const auto §ion : _sections)
116 | {
117 | if (section.first.empty())
118 | {
119 | continue;
120 | }
121 |
122 | file << '[' << section.first << ']' << std::endl;
123 |
124 | for (const auto §ion_line : section.second)
125 | {
126 | file << section_line.first << '=';
127 |
128 | size_t i = 0;
129 |
130 | for (const auto &item : section_line.second.data())
131 | {
132 | if (i++ != 0)
133 | {
134 | file << ',';
135 | }
136 |
137 | file << item;
138 | }
139 |
140 | file << std::endl;
141 | }
142 |
143 | file << std::endl;
144 | }
145 | }
146 | }
147 |
--------------------------------------------------------------------------------
/source/ini_file.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #pragma once
7 |
8 | #include
9 | #include "variant.hpp"
10 | #include "filesystem.hpp"
11 |
12 | namespace reshade
13 | {
14 | class ini_file
15 | {
16 | public:
17 | explicit ini_file(const filesystem::path &path);
18 | ~ini_file();
19 |
20 | template
21 | void get(const std::string §ion, const std::string &key, T &value) const
22 | {
23 | const auto it1 = _sections.find(section);
24 |
25 | if (it1 == _sections.end())
26 | {
27 | return;
28 | }
29 |
30 | const auto it2 = it1->second.find(key);
31 |
32 | if (it2 == it1->second.end())
33 | {
34 | return;
35 | }
36 |
37 | value = it2->second.as();
38 | }
39 | template
40 | void get(const std::string §ion, const std::string &key, T(&values)[SIZE]) const
41 | {
42 | const auto it1 = _sections.find(section);
43 |
44 | if (it1 == _sections.end())
45 | {
46 | return;
47 | }
48 |
49 | const auto it2 = it1->second.find(key);
50 |
51 | if (it2 == it1->second.end())
52 | {
53 | return;
54 | }
55 |
56 | for (size_t i = 0; i < SIZE; i++)
57 | {
58 | values[i] = it2->second.as(i);
59 | }
60 | }
61 | template
62 | void get(const std::string §ion, const std::string &key, std::vector