Skip to content

Commit

Permalink
Add CharaLODMultiplier hook & CVar, minor cleanups
Browse files Browse the repository at this point in the history
  • Loading branch information
emoose committed Sep 28, 2021
1 parent 442f296 commit 1beedbd
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 42 deletions.
6 changes: 6 additions & 0 deletions Arise-SDK.ini
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@
; (set this to -1 to disable the NPC distance changes)
MinimumNPCDistance = 50000

; CharaLODMultiplier: how much to multiply AriseCharacter LOD distances
; affects both NPCs & monsters, game defaults can be pretty low, recommend a multiplier of 5 or above
; (can be controlled ingame via sdk.CharaLODMultiplier cvar)
; (game default: 1)
CharaLODMultiplier = 5

; Override*SharpenFilterStrength - allows overriding the two sharpen filters the game applies
; setting to 0 will disable the filter, -1 will leave the filter set to games default, anything else will force the filter to that value
; (can be controlled ingame via sdk.CharaSharpenFilterStrength & sdk.StageSharpenFilterStrength cvars)
Expand Down
10 changes: 2 additions & 8 deletions PostProcOverrides.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include "pch.h"

FPostProcessSettings_Overrides PostProcOverrides;
std::vector<IConsoleVariable*> CVarsPostProc;
extern std::vector<IConsoleVariable*> CVarPointers;

void PostProc_AddCVars(IConsoleManager* ConsoleManager)
{
Expand All @@ -10,7 +10,7 @@ void PostProc_AddCVars(IConsoleManager* ConsoleManager)
#pragma region FPostProcessSetting CVars

#define OVERRIDE_CVAR(x) \
CVarsPostProc.push_back(ConsoleManager->RegisterConsoleVariableRef(L"" #x, PostProcOverrides.x, L"", 0));
CVarPointers.push_back(ConsoleManager->RegisterConsoleVariableRef(L"" #x, PostProcOverrides.x, L"", 0));

OVERRIDE_CVAR(WhiteTemp);
OVERRIDE_CVAR(WhiteTint);
Expand Down Expand Up @@ -726,12 +726,6 @@ void PostProc_AddCVars(IConsoleManager* ConsoleManager)
#pragma endregion
}

void PostProc_RemoveCVars(IConsoleManager* ConsoleManager)
{
for (auto& CVarPostProc : CVarsPostProc)
ConsoleManager->UnregisterConsoleObject(CVarPostProc);
}

void PostProc_Init()
{
// Init all post proc overrides to -1...
Expand Down
135 changes: 102 additions & 33 deletions dllmain.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "pch.h"

#define SDK_VERSION "0.1.20"
#define SDK_VERSION "0.1.21"

const uint32_t Addr_Timestamp = 0x1E0;
const uint32_t Value_Timestamp = 1626315361; // 2021/07/15 02:16:01
Expand Down Expand Up @@ -53,6 +53,10 @@ struct
bool CutsceneRenderFix_EnableScreenPercentage = false;
float OverrideTemporalAAJitterScale = -1;
float OverrideTemporalAASharpness = -1;
#ifdef _DEBUG
bool UseUE4TAA = false;
#endif
float CharaLODMultiplier = 1;
} Options;

bool TryLoadINIOptions(const WCHAR* IniFilePath)
Expand All @@ -77,6 +81,12 @@ bool TryLoadINIOptions(const WCHAR* IniFilePath)
Options.OverrideTemporalAAJitterScale = INI_GetFloat(IniPath, L"Graphics", L"OverrideTAAJitterScale", Options.OverrideTemporalAAJitterScale);
Options.OverrideTemporalAASharpness = INI_GetFloat(IniPath, L"Graphics", L"OverrideTAASharpness", Options.OverrideTemporalAASharpness);

#ifdef _DEBUG
Options.UseUE4TAA = INI_GetBool(IniPath, L"Graphics", L"UseUE4TAA", Options.UseUE4TAA);
#endif

Options.CharaLODMultiplier = INI_GetFloat(IniPath, L"Graphics", L"CharaLODMultiplier", Options.CharaLODMultiplier);

if (Options.MinNPCDistance >= 0 && FadeInDelta >= Options.MinNPCDistance)
Options.MinNPCDistance = (FadeInDelta + 1);

Expand Down Expand Up @@ -208,15 +218,7 @@ void* FSceneView__EndFinalPostprocessSettings_Hook(uint8_t* thisptr, void* a2)
return ret;
}

IConsoleVariable* CVarCharaSharpenFilterStrength;
IConsoleVariable* CVarStageSharpenFilterStrength;
IConsoleVariable* CVarMinStageEdgeBaseDistance;
IConsoleVariable* CVarDisableCutsceneCA;
IConsoleVariable* CVarCutsceneRenderFix;
IConsoleVariable* CVarCutsceneRenderFixScreenPercentage;
IConsoleVariable* CVarForceLOD;
IConsoleVariable* CVarTAAJitterScale;
IConsoleVariable* CVarTAASharpness;
std::vector<IConsoleVariable*> CVarPointers;

const uint32_t Addr_IConsoleManager__Singleton = 0x4A97AC8;

Expand All @@ -228,20 +230,26 @@ void CVarSystemResolution_ctor_Hook()
CVarSystemResolution_ctor_Orig();
auto consoleManager = *(IConsoleManager**)(mBaseAddress + Addr_IConsoleManager__Singleton);

CVarCharaSharpenFilterStrength = consoleManager->RegisterConsoleVariableRef(L"sdk.CharaSharpenFilterStrength", Options.OverrideCharaSharpenFilterStrength, L"Adjust sharpen filter applied to characters", 0);
CVarStageSharpenFilterStrength = consoleManager->RegisterConsoleVariableRef(L"sdk.StageSharpenFilterStrength", Options.OverrideStageSharpenFilterStrength, L"Adjust sharpen filter applied to the game world", 0);
CVarMinStageEdgeBaseDistance = consoleManager->RegisterConsoleVariableRef(L"sdk.MinStageEdgeBaseDistance", Options.MinStageEdgeBaseDistance, L"Allows increasing the distance that cel-shading is applied for", 0);
CVarDisableCutsceneCA = consoleManager->RegisterConsoleVariableRef(L"sdk.DisableCutsceneCA", Options.DisableCutsceneCA, L"Whether to prevent chromatic aberration from being applied (this setting affects the whole game, not just cutscenes)", 0);
CVarPointers.push_back(consoleManager->RegisterConsoleVariableRef(L"sdk.CharaSharpenFilterStrength", Options.OverrideCharaSharpenFilterStrength, L"Adjust sharpen filter applied to characters", 0));
CVarPointers.push_back(consoleManager->RegisterConsoleVariableRef(L"sdk.StageSharpenFilterStrength", Options.OverrideStageSharpenFilterStrength, L"Adjust sharpen filter applied to the game world", 0));
CVarPointers.push_back(consoleManager->RegisterConsoleVariableRef(L"sdk.MinStageEdgeBaseDistance", Options.MinStageEdgeBaseDistance, L"Allows increasing the distance that cel-shading is applied for", 0));
CVarPointers.push_back(consoleManager->RegisterConsoleVariableRef(L"sdk.DisableCutsceneCA", Options.DisableCutsceneCA, L"Whether to prevent chromatic aberration from being applied (this setting affects the whole game, not just cutscenes)", 0));

CVarCutsceneRenderFix = consoleManager->RegisterConsoleVariableRef(L"sdk.CutsceneRenderFix", Options.CutsceneRenderFix, L"Enable/disable skit cutscene resolution scaling", 0);
CVarCutsceneRenderFixScreenPercentage = consoleManager->RegisterConsoleVariableRef(L"sdk.CutsceneRenderFixScreenPercentage", Options.CutsceneRenderFix_EnableScreenPercentage, L"Whether or not r.ScreenPercentage should affect skit cutscene resolution", 0);
CVarPointers.push_back(consoleManager->RegisterConsoleVariableRef(L"sdk.CutsceneRenderFix", Options.CutsceneRenderFix, L"Enable/disable skit cutscene resolution scaling", 0));
CVarPointers.push_back(consoleManager->RegisterConsoleVariableRef(L"sdk.CutsceneRenderFixScreenPercentage", Options.CutsceneRenderFix_EnableScreenPercentage, L"Whether or not r.ScreenPercentage should affect skit cutscene resolution", 0));

CVarTAAJitterScale = consoleManager->RegisterConsoleVariableRef(L"sdk.TAAJitterScale", Options.OverrideTemporalAAJitterScale, L"Adjust jittering applied to the games TAA (game default has this set to 0, doesn't really seem to work that well, was probably disabled for a reason...)", 0);
CVarTAASharpness = consoleManager->RegisterConsoleVariableRef(L"sdk.TAASharpness", Options.OverrideTemporalAASharpness, L"Adjust sharpening effect applied to TAA", 0);
CVarPointers.push_back(consoleManager->RegisterConsoleVariableRef(L"sdk.TAAJitterScale", Options.OverrideTemporalAAJitterScale, L"Adjust jittering applied to the games TAA (game default has this set to 0, doesn't really seem to work that well, was probably disabled for a reason...)", 0));
CVarPointers.push_back(consoleManager->RegisterConsoleVariableRef(L"sdk.TAASharpness", Options.OverrideTemporalAASharpness, L"Adjust sharpening effect applied to TAA", 0));

#ifdef _DEBUG
CVarPointers.push_back(consoleManager->RegisterConsoleVariableRef(L"sdk.UseUE4TAA", Options.UseUE4TAA, L"Use UE4's TAA method instead of TO14 custom one", 0));
#endif

CVarPointers.push_back(consoleManager->RegisterConsoleVariableRef(L"sdk.CharaLODMultiplier", Options.CharaLODMultiplier, L"Multiplier of Chara LODs", 0));

// usually created by UE4 inside EXPOSE_FORCE_LOD builds, which shipping builds sadly aren't
// not too hard to reimpl though
CVarForceLOD = consoleManager->RegisterConsoleVariableRef(L"r.ForceLOD", Options.ForcedLODLevel, L"LOD level to force, -1 is off.", ECVF_Scalability | ECVF_Default | ECVF_RenderThreadSafe);
CVarPointers.push_back(consoleManager->RegisterConsoleVariableRef(L"r.ForceLOD", Options.ForcedLODLevel, L"LOD level to force, -1 is off.", ECVF_Scalability | ECVF_Default | ECVF_RenderThreadSafe));

CVarCopyValuesToCVars = consoleManager->RegisterConsoleVariableRef(L"pp.CopyValuesToCVars", PostProc_CopyValuesToCVars, L"If set, will copy values from FPostProcessSettings into cvars for viewing", 0);

Expand All @@ -256,18 +264,11 @@ void CVarSystemResolution_dtor_Hook()
CVarSystemResolution_dtor_Orig();
auto consoleManager = *(IConsoleManager**)(mBaseAddress + Addr_IConsoleManager__Singleton);

PostProc_RemoveCVars(consoleManager);

consoleManager->UnregisterConsoleObject(CVarCopyValuesToCVars);
consoleManager->UnregisterConsoleObject(CVarTAASharpness);
consoleManager->UnregisterConsoleObject(CVarTAAJitterScale);
consoleManager->UnregisterConsoleObject(CVarForceLOD);
consoleManager->UnregisterConsoleObject(CVarCutsceneRenderFixScreenPercentage);
consoleManager->UnregisterConsoleObject(CVarCutsceneRenderFix);
consoleManager->UnregisterConsoleObject(CVarDisableCutsceneCA);
consoleManager->UnregisterConsoleObject(CVarMinStageEdgeBaseDistance);
consoleManager->UnregisterConsoleObject(CVarStageSharpenFilterStrength);
consoleManager->UnregisterConsoleObject(CVarCharaSharpenFilterStrength);

for (auto& cvar : CVarPointers)
consoleManager->UnregisterConsoleObject(cvar);
CVarPointers.clear();
}

struct __declspec(align(4)) FMarkRelevantStaticMeshesForViewData
Expand Down Expand Up @@ -360,8 +361,34 @@ void CreateRenderTarget2D_Hook(UTextureRenderTarget2D* thisptr)
UTexture__UpdateResource(thisptr);
}

#ifdef _DEBUG
const uint32_t Addr_FAchCharacterLODData_Reader_Hook = 0x6D46A7;
const uint32_t Addr_FAchCharacterLODData_Reader_Trampoline = 0x6D3CB1;

void FAchCharacterLODData_Reader_Hook(void* Dst, void* Src, size_t Size)
{
// this func copies some floats from FAchCharacterLODData.LODDistances into some stack var
// we just hook the memcpy call it uses and modify the floats after :)
// TODO: would be better if we could hook the code that actually reads this data in the first place, and modify the FAchCharacterLODData directly instead...

memcpy(Dst, Src, Size);

if (Options.CharaLODMultiplier != 1)
{
uint32_t NumLods = Size / sizeof(float);
float* DstFloats = (float*)Dst;
for (int i = 0; i < NumLods; i++)
{
DstFloats[i] *= Options.CharaLODMultiplier;
}
}

// the copied floats seem to get read by
// 1406D46D0 - F3 0F10 00 - movss xmm0,[rax] <<
// 141253C47 - 48 89 03 - mov [rbx],rax <<
// 141253B2E - 48 8B 06 - mov rax,[rsi] <<
}

#ifdef _DEBUG
// hook for testing stuff
// previously was a seperate thread, but that wasn't in sync with the game engine that well
// hooking engine loop should solve that though :)
Expand All @@ -373,10 +400,40 @@ void FEngineLoop__Tick_Hook(void* thisptr)
{
FEngineLoop__Tick_Orig(thisptr);

static bool PrevUseUE4TAA = false;
if (PrevUseUE4TAA != Options.UseUE4TAA)
{
PrevUseUE4TAA = Options.UseUE4TAA;
// Options.UseUE4TAA was changed, modify our patch...
SafeWriteModule(0x2175D8A + 6, PrevUseUE4TAA ? uint32_t(EAntiAliasingMethod::AAM_TemporalAA) : uint32_t(EAntiAliasingMethod::AAM_HybirdAA));
}

bool performAction = (GetKeyState(VK_HOME) & 0x8000);
if (!performAction)
return;

auto ttt = UObject::FindObjects<UAchCharacterLODDatabase>();
auto ttt2 = UObject::FindObjects<UAchProjectSettings>();

for (auto& bleh : ttt)
{
for (int i = 0; i < bleh->Database.Record.Num(); i++)
{
auto* record = &bleh->Database.Record[i];
record = record;
}
}

for (auto& bleh : ttt2)
{
for (int i = 0; i < bleh->DefaultCharacterLODs.Num(); i++)
{
auto* record = &bleh->DefaultCharacterLODs[i];
record = record;
}
}

/*
static float newDist = 1.0f;
static float newFactor = 10.0f;
static bool whoa = false;
Expand All @@ -399,11 +456,11 @@ void FEngineLoop__Tick_Hook(void* thisptr)
float prevDist = obj->StreamingDistanceMultiplier;
if (whoa)
obj->StreamingDistanceMultiplier = newDist;
}
}*/
}

#endif


void InitPlugin()
{
PostProc_Init();
Expand Down Expand Up @@ -431,6 +488,18 @@ void InitPlugin()
// Add support for r.ForceLOD
MH_GameHook(FRelevancePacket__FRelevancePacket);

if (true)
{
// Have to write a trampoline somewhere near the hooked addr, needs 12 bytes...
uint8_t trampoline[] = { 0x48, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFF, 0xE0 };

*(uintptr_t*)&trampoline[2] = (uintptr_t)&FAchCharacterLODData_Reader_Hook;

SafeWrite(mBaseAddress + Addr_FAchCharacterLODData_Reader_Trampoline, trampoline, 12);

PatchCall(mBaseAddress + Addr_FAchCharacterLODData_Reader_Hook, mBaseAddress + Addr_FAchCharacterLODData_Reader_Trampoline);
}

// Render target resizing (fixing cutscene/skit resolution)
if (Options.CutsceneRenderFix)
{
Expand Down
1 change: 0 additions & 1 deletion pch.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ float INI_GetFloat(const WCHAR* IniPath, const WCHAR* Section, const WCHAR* Key,

// PostProcOverrides.cpp
void PostProc_AddCVars(IConsoleManager* ConsoleManager);
void PostProc_RemoveCVars(IConsoleManager* ConsoleManager);
void PostProc_Init();
void PostProc_DoOverrides(bool CopyValuesToCVars, FPostProcessSettings* FinalPostProcessSettings);

Expand Down

0 comments on commit 1beedbd

Please sign in to comment.