summaryrefslogtreecommitdiff
path: root/Plugin.cs
blob: c64778589e343b68ab05c180a6cba4c998a9fe24 (plain)
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
using System.Reflection;
using System.Runtime.Loader;
using System.Runtime.InteropServices;

using ImGuiNET;
using SharpPluginLoader.Core;
using SharpPluginLoader.Core.Memory;

namespace WorldTuningTool
{
    public unsafe class Plugin : IPlugin
    {
        public string Name => "World Tuning Tool";
        public string Author => "Akon City Software";

        // @TODO:
        //  - Port FXAA object.
        //  - Port some stuff as is.
        //  - OnAreaChange.
        //  - Shadow distance retuning.
        //  - Work out obvious simplifications.
        //  - sMhRenderer vs common parameter address.
        //  - Overrides system.
        //  - Pass on LODs.
        //  - Verbose descriptions.
        //  - Re-implement shadow res override for hoarfrost.
        //  - Exact float flag for hex input?

        private bool dofDisabled = false;
        private Patch jmpOverDof;

        public void SetDofForceOff(bool off)
        {
            if (off && !dofDisabled)
            {
                jmpOverDof.Enable();
            }
            else if (!off && dofDisabled)
            {
                jmpOverDof.Disable();
            }
            dofDisabled = off;
        }

        public bool GetDofDisabled()
        {
            return dofDisabled;
        }

        /*
        public PluginData Initialize()
        {
            PluginData data = new PluginData();
            data.ExportedFunctions.Add(("SetDofForceOff", SetDofForceOff));
            data.ExportedFunctions.Add(("GetDofDisabled", GetDofDisabled));
            return data;
        }
        */

        public void OnPreMain()
        {
            unchecked
            {
                jmpOverDof = new Patch((nint)0x1424233C6, [0xEB]); // je -> jmp.
            }
        }

        private static bool replaceShaderFromFile(ShaderInfo *info, string path)
        {
            if (!System.IO.File.Exists(path))
            {
                Log.Warn($"File not found: {path}.");
                return false;
            }
            byte[] shaderData;
            try
            {
                shaderData = System.IO.File.ReadAllBytes(path);
            }
            catch (Exception)
            {
                Log.Error($"Failed to read: {path}.");
                return false;
            }
            info->Replacement.Length = shaderData.Length;
            info->Replacement.Source = (byte *)Marshal.UnsafeAddrOfPinnedArrayElement<byte>(shaderData, 0);
            return true;
        }

        private string shaderPath = "nativePC/plugins/CSharp/Shaders";
        private bool shadersLoadedOnce = false;
        public unsafe void OnCreateShader(ShaderInfo *info)
        {
            string hash = new string(info->DxbcHash);
            if (!shadersLoadedOnce && hash == "2e4e18fd-6ea5eeae-2de3d65c-26ab36dd")
            {
                if (replaceShaderFromFile(info, $"{shaderPath}/volume_upsample.shdr")) {
                    info->Replacement.Type = ShaderSourceType.BINARY;
                    Log.Info("Volume upsample shader 1 replaced.");
                }
            }
            else if (!shadersLoadedOnce && hash == "e2c8c13e-45bc99b2-4c3d7699-3d66188e")
            {
                if (replaceShaderFromFile(info, $"{shaderPath}/volume_upsample2.shdr")) {
                    info->Replacement.Type = ShaderSourceType.BINARY;
                    Log.Info("Volume upsample shader 2 replaced.");
                }
                // This allows us to A/B using the volume rendering value 2 switch.
                shadersLoadedOnce = true;
            }
            else if (hash == "8cf2a107-ecde214b-9939b350-7b2af1a7")
            {
                if (replaceShaderFromFile(info, $"{shaderPath}/cube_only.shdr")) {
                    info->Replacement.Type = ShaderSourceType.BINARY;
                    Log.Info("Cube Only shader replaced.");
                }
            }
            else if (hash == "b21dd223-98ab56ae-918264e6-eb6e8ee4")
            {
                if (replaceShaderFromFile(info, $"{shaderPath}/sslr.shdr")) {
                    info->Replacement.Type = ShaderSourceType.BINARY;
                    Log.Info("SSLR shader replaced.");
                }
            }
            else if (hash == "9ff245fb-4fd555e0-04d0ef15-84609fe1")
            {
                if (replaceShaderFromFile(info, $"{shaderPath}/fxaa_max_quality.hlsl")) {
                    info->Replacement.Type = ShaderSourceType.HLSL;
                    Log.Info("FXAA shader replaced.");
                }
            }
            else if (hash == "2eed1f00-e24d1b19-9d521064-17b9a586")
            {
                if (replaceShaderFromFile(info, $"{shaderPath}/body_skin.shdr")) {
                    info->Replacement.Type = ShaderSourceType.BINARY;
                    Log.Info("Body skin shader replaced.");
                }
            }
            else if (hash == "8e5e3c09-ebe77ee4-ba1cb659-d25bc7bf")
            {
                if (replaceShaderFromFile(info, $"{shaderPath}/face.shdr")) {
                    info->Replacement.Type = ShaderSourceType.BINARY;
                    Log.Info("Face shader replaced.");
                }
            }
            /*
            else if (hash == "d7e47ffe-82572c64-795c4698-341e5b91")
            {
                if (replaceShaderFromFile(info, $"{shaderPath}/sslr_mips.shdr")) {
                    info->Replacement.Type = ShaderSourceType.BINARY;
                    Log.Info("SSLR mips shader replaced.");
                }
            }
            */
        }

        public void OnLoad()
        {
        }

        public void OnImGuiRender()
        {
            if (ImGui.Checkbox("Disable Depth of Field", ref dofDisabled))
            {
                if (dofDisabled)
                {
                    jmpOverDof.Enable();
                }
                else
                {
                    jmpOverDof.Disable();
                }
            }
        }
    }
}