From ca2ed262e07390f8dfdc77b259ec66389a7b918b Mon Sep 17 00:00:00 2001 From: Lorenzo Ferrillo Date: Fri, 29 Mar 2024 23:21:18 +0100 Subject: [PATCH] Fix crash when using edited shaderpackages, caused by an OBMM bug, remove some bugfixes, offloaded to another OBSE plugin --- Configurator/src/main_config.rs | 2 +- TESReloaded/Core/EquipmentManager.cpp | 2 +- TESReloaded/Core/Hooks/FormsCommon.cpp | 5 +++- TESReloaded/Core/Hooks/Oblivion/Hooks.cpp | 25 +++++++++--------- TESReloaded/Core/Hooks/Oblivion/ShaderIO.cpp | 10 ++++++-- TESReloaded/Core/TextureManager.cpp | 1 - TESReloaded/Framework/Oblivion/Game.h | 10 +++++--- TESReloaded/Framework/Oblivion/GameNi.h | 27 +++++++++++++++++++- 8 files changed, 59 insertions(+), 23 deletions(-) diff --git a/Configurator/src/main_config.rs b/Configurator/src/main_config.rs index 4305b8c4..9548a08a 100644 --- a/Configurator/src/main_config.rs +++ b/Configurator/src/main_config.rs @@ -400,7 +400,7 @@ impl Default for WaterEngine{ fn default() -> Self{ WaterEngine{ ReflectionMapSize : 512, - SetAtmoshpere : false + SetAtmoshpere : false, } } } diff --git a/TESReloaded/Core/EquipmentManager.cpp b/TESReloaded/Core/EquipmentManager.cpp index 8e4bbff2..b5b7a1e2 100644 --- a/TESReloaded/Core/EquipmentManager.cpp +++ b/TESReloaded/Core/EquipmentManager.cpp @@ -22,7 +22,7 @@ void EquipmentManager::LoadForms() { OnBackAnim->flags = 0; OnBackAnim->SetFile("Characters\\_Male\\IdleAnims\\oronbackanim.kf"); OnBackAnim->animFlags = TESIdleForm::AnimFlag::kAnimFlag_SpecialIdle; - DataHandler->AddData(OnBackAnim); + DataHandler->AddDagta(OnBackAnim); } #endif } diff --git a/TESReloaded/Core/Hooks/FormsCommon.cpp b/TESReloaded/Core/Hooks/FormsCommon.cpp index 6c5289a0..efd75614 100644 --- a/TESReloaded/Core/Hooks/FormsCommon.cpp +++ b/TESReloaded/Core/Hooks/FormsCommon.cpp @@ -18,7 +18,10 @@ bool __cdecl LoadFormHook(TESForm* Form, UInt32 ModEntry) { case TESForm::FormType::kFormType_Water: { TESWaterForm* Water = (TESWaterForm*)Form; - if (TheSettingManager->Config->Main.RemoveUnderwater) Water->RemoveUnderwaterFog(); + if (TheSettingManager->Config->Main.RemoveUnderwater) { + Logger::Log("Remove Underwater Fog from %s %s", Water->GetEditorName(), Water->GetName()); + Water->RemoveUnderwaterFog(); + } } break; default: diff --git a/TESReloaded/Core/Hooks/Oblivion/Hooks.cpp b/TESReloaded/Core/Hooks/Oblivion/Hooks.cpp index 52d6e590..8bdc9749 100644 --- a/TESReloaded/Core/Hooks/Oblivion/Hooks.cpp +++ b/TESReloaded/Core/Hooks/Oblivion/Hooks.cpp @@ -19,11 +19,12 @@ void __cdecl NameThread(int threadID, const char* name) { static const UInt32 kRetU = 0x0053B175; static const UInt32 kRet = 0x0053B20C; -static const UInt32 SceneGraph_GetChildNiAvNodeVtbl = 0x005645B0; void __declspec(naked) SetAtmosphereUnderwater() { __asm { pushad } +// Logger::Log("%u", Tes->sky->unk0DC); +// Tes->sky->unk0DC = 0; if (TheSettingManager->Config->WaterEngine.SetAtmoshpere) { __asm { popad @@ -43,7 +44,6 @@ void AttachHooks() { HMODULE Module = NULL; char Filename[MAX_PATH]; ffi::Config* SettingsMain = TheSettingManager->Config; - DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); DetourAttach(&(PVOID&)RemoveTexture, &RemoveTextureH); @@ -141,10 +141,11 @@ void AttachHooks() { SafeWrite32(0x0076BD75, sizeof(RenderManager)); SafeWrite32(0x00406775, sizeof(PlayerCharacterEx)); SafeWrite32(0x0046451E, sizeof(PlayerCharacterEx)); -#ifdef EXPERIMENTAL_FEATURES SafeWrite32(0x004486ED, sizeof(TESWeatherEx)); SafeWrite32(0x0044CBE3, sizeof(TESWeatherEx)); +#ifdef EXPERIMENTAL_FEATURES + SafeWrite8(0x00564523, sizeof(bhkCollisionObjectEx)); SafeWrite8(0x0089E983, sizeof(bhkCollisionObjectEx)); SafeWrite8(0x0089EA16, sizeof(bhkCollisionObjectEx)); @@ -180,8 +181,13 @@ void AttachHooks() { SafeWrite32(0x007C1103, SettingsMain->WaterEngine.ReflectionMapSize); // RenderedSurface SafeWrite8(0x0049EBAC, 0); // Avoids to change the shader for the skydome when underwaterb (avoid using Fade shaders) - SafeWriteJump(0x0053B11F, (UInt32)SetAtmosphereUnderwater); // Avoids to change atmosphere colors when underwater - SafeWriteJump(0x00542F63, 0x00542FC1); // Avoids to remove the sun over the scene when underwater + SafeWriteJump(0x0053B11F, (UInt32)SetAtmosphereUnderwater); // Avoids to change atmosphere colors when underwater. + if(SettingsMain->Main.RemoveUnderwater) SafeWriteJump(0x00542F63, 0x00542FC1); // Avoids to remove the sun over the scene when underwater. Prevent rendering the vanilla underwater fog. Actually turn the Sky green + if (!SettingsMain->Main.RemoveUnderwater) + Logger::Log("[WARNING] RemoveUnderwater=false is incompatible with showing the Sun when underwater. Vanilla Sun behaviour restored. "); + if (!SettingsMain->Main.RemoveUnderwater && SettingsMain->Main.RemoveFogPass) + Logger::Log("[WARNING] RemoveUnderwater=false and RemoveFogPass=true are incompatible. Disabling RemoveFogPass. Could experience visual problems"); + SafeWriteJump(Jumpers::DetectorWindow::CreateTreeViewHook, (UInt32)DetectorWindowCreateTreeViewHook); SafeWriteJump(Jumpers::DetectorWindow::DumpAttributesHook, (UInt32)DetectorWindowDumpAttributesHook); @@ -195,8 +201,8 @@ void AttachHooks() { SafeWriteJump(Jumpers::Shadows::AddCastShadowFlagHook, (UInt32)AddCastShadowFlagHook); // SafeWriteJump(Jumpers::WaterHeightMap::Hook, (UInt32)WaterHeightMapHook); SafeWriteJump(Jumpers::EndProcess::Hook, (UInt32)EndProcessHook); - - if(SettingsMain->Main.RemoveFogPass) SafeWriteJump(Jumpers::SkipFogPass::Hook, (UInt32)SkipFogPassHook); + /*RemoveUnderwater must be true for this hook to not cause glitches*/ + if(SettingsMain->Main.RemoveFogPass && SettingsMain->Main.RemoveUnderwater) SafeWriteJump(Jumpers::SkipFogPass::Hook, (UInt32)SkipFogPassHook); SafeWriteJump(0x00553EAC, 0x00553EB2); // Patches the use of Lighting30Shader only for the hair SafeWriteJump(0x007D1BC4, 0x007D1BFD); // Patches the use of Lighting30Shader only for the hair @@ -205,15 +211,11 @@ void AttachHooks() { SafeWriteJump(0x0049C8CB, 0x0049C931); // Avoids to manage the cells culling for reflections SafeWriteJump(0x004965A8, 0x0049660F); // Skip the scale in the detector window SafeWriteJump(0x0049849A, 0x004984A0); // Skips antialiasing deactivation if HDR is enabled on the D3DDevice - SafeWriteJump(0x004984BD, 0x004984CD); // Skips antialiasing deactivation if AllowScreenshot is enabled SafeWriteJump(0x005DEE60, 0x005DEE68); // Skips antialiasing deactivation if HDR is enabled on loading the video menu SafeWriteJump(0x005DF69E, 0x005DF755); // Skips HDR deactivation changing antialising (video menu) SafeWriteJump(0x00497D5A, 0x00497D63); // Unlocks antialising bar if HDR is enabled (video menu) SafeWriteJump(0x005DF8E9, 0x005DF983); // Skips antialising deactivation changing HDR (video menu) SafeWriteJump(0x006738B1, 0x00673935); // Cancels the fPlayerDeathReloadTime - SafeWrite8(0x0040CE11, 0); // Stops to clear the depth buffer when rendering the 1st person node - SafeWriteNop(0x00498968, 2); // Stops Disabling refraction shaders when MSAA, Non detection path - SafeWriteJump(0x004988D8, 0x0049896A);// Stops Disabling refraction shaders when MSAA, AMD Path *Pointers::ShaderParams::WaterHighResolution = 1; @@ -280,7 +282,6 @@ void AttachHooks() { SafeWriteJump(Jumpers::Camera::HeadTrackingHook, (UInt32)HeadTrackingHook); SafeWriteJump(Jumpers::Camera::SpineTrackingHook, (UInt32)SpineTrackingHook); SafeWriteJump(Jumpers::Camera::SetReticleOffsetHook, (UInt32)SetReticleOffsetHook); - SafeWriteJump(0x0066B769, 0x0066B795); // Does not lower the player Z axis value (fixes the bug of the camera on feet after resurrection) SafeWriteJump(0x00666704, 0x0066672D); // Enables the zoom with the bow } diff --git a/TESReloaded/Core/Hooks/Oblivion/ShaderIO.cpp b/TESReloaded/Core/Hooks/Oblivion/ShaderIO.cpp index 28ac4730..c2855b20 100644 --- a/TESReloaded/Core/Hooks/Oblivion/ShaderIO.cpp +++ b/TESReloaded/Core/Hooks/Oblivion/ShaderIO.cpp @@ -4,7 +4,10 @@ NiD3DVertexShader* (__thiscall* CreateVertexShader)(BSShader*, char*, char*, cha NiD3DVertexShader* __fastcall CreateVertexShaderHook(BSShader* This, UInt32 edx, char* FileName, char* Arg2, char* ShaderType, char* ShaderName, UInt32 Arg5, UInt32 Arg6) { NiD3DVertexShaderEx* VertexShader = (NiD3DVertexShaderEx*)(*CreateVertexShader)(This, FileName, Arg2, ShaderType, ShaderName, Arg5, Arg6); - + if (!VertexShader) { + Logger::Log("[WARNING] Vertex Shader %s failed to load. This is caused by mods modifying shaderpackages by OBMM.", ShaderName); + return VertexShader; + } VertexShader->ShaderProg = NULL; VertexShader->ShaderProgE = NULL; VertexShader->ShaderProgI = NULL; @@ -19,7 +22,10 @@ NiD3DPixelShader* (__thiscall* CreatePixelShader)(BSShader*, char*, char*, char* NiD3DPixelShader* __fastcall CreatePixelShaderHook(BSShader* This, UInt32 edx, char* FileName, char* Arg2, char* ShaderType, char* ShaderName, UInt32 Arg5, UInt32 Arg6) { NiD3DPixelShaderEx* PixelShader = (NiD3DPixelShaderEx*)(*CreatePixelShader)(This, FileName, Arg2, ShaderType, ShaderName, Arg5, Arg6); - + if (!PixelShader) { + Logger::Log("[WARNING] Pixel Shader %s failed to load. This is caused by mods modifying shaderpackages by OBMM.", ShaderName); + return PixelShader; + } PixelShader->ShaderProg = NULL; PixelShader->ShaderProgE = NULL; PixelShader->ShaderProgI = NULL; diff --git a/TESReloaded/Core/TextureManager.cpp b/TESReloaded/Core/TextureManager.cpp index baabd2fa..59b8402f 100644 --- a/TESReloaded/Core/TextureManager.cpp +++ b/TESReloaded/Core/TextureManager.cpp @@ -123,7 +123,6 @@ void TextureManager::Initialize() { // create one texture per Exterior ShadowMap type float multiple = i == ShadowManager::ShadowMapTypeEnum::MapLod ? 2.0f : 1.0f; // double the size of lod map only ShadowMapSize = ShadowsExteriors->ShadowMapResolution * multiple; - Logger::Log("%u %u", ShadowMapSize, ShadowsExteriors->ShadowMode); if (FAILED(Device->CreateTexture(ShadowMapSize, ShadowMapSize, 1, D3DUSAGE_RENDERTARGET, D3DFMT_G32R32F, D3DPOOL_DEFAULT, &TheTextureManager->ShadowMapTexture[i], NULL))) { Logger::Log("Cannot create texture"); } diff --git a/TESReloaded/Framework/Oblivion/Game.h b/TESReloaded/Framework/Oblivion/Game.h index b7c3c6d4..71dcf182 100644 --- a/TESReloaded/Framework/Oblivion/Game.h +++ b/TESReloaded/Framework/Oblivion/Game.h @@ -1,4 +1,5 @@ #pragma once +#include "GameNi.h" class DetectorWindow; class INISettingCollection; @@ -1021,10 +1022,9 @@ assert(sizeof(TESWeather) == 0x148); class TESWeatherEx : public TESWeather { public: - ColorData colorsb[kNumColorTypes]; char EditorName[40]; }; -assert(sizeof(TESWeatherEx) == 0x210); +assert(sizeof(TESWeatherEx) == 0x170); class TESClimate : public TESForm { public: @@ -3145,8 +3145,8 @@ assert(sizeof(Stars) == 0x010); class Clouds : public SkyObject { public: - UInt32 unk08; // 08 - UInt32 unk0C; // 0C + NiNode* unk08; // 08 + NiNode* unk0C; // 0C UInt32 unk10; // 10 UInt32 unk14; // 14 }; @@ -4130,6 +4130,8 @@ namespace Pointers { static char* (__cdecl* GetPassDescription)(UInt32) = (char* (__cdecl*)(UInt32))0x007B4920; static void (__cdecl* BeginRendering)(UInt32, NiRenderTargetGroup*) = (void (__cdecl*)(UInt32, NiRenderTargetGroup*))0x007D7280; static void (* EndRendering)() = (void (*)())0x007D72D0; + static NiSourceTexture* (__cdecl* TextureLoadByFilename)(const char*, NiTexture::FormatPrefs*, bool) = (NiSourceTexture* (__cdecl*)(const char*, NiTexture::FormatPrefs*, bool))0x00701E00; + } namespace VirtualTables { static const void* NiNode = (void*)0x00A7E38C; diff --git a/TESReloaded/Framework/Oblivion/GameNi.h b/TESReloaded/Framework/Oblivion/GameNi.h index 3b21cbc2..3ce05d9c 100644 --- a/TESReloaded/Framework/Oblivion/GameNi.h +++ b/TESReloaded/Framework/Oblivion/GameNi.h @@ -295,6 +295,9 @@ class NiTList { virtual Entry* AllocateEntry(); virtual void Free(Entry* entry); + void FreeAllNodes() { + ThisCall(0x00573880, this); + } Entry* start; // 004 Entry* end; // 008 UInt32 numItems; // 00C @@ -947,13 +950,18 @@ class NiSourceTexture : public NiTexture { UInt8 unk030; // 030 - is static? UInt8 unk031[3]; // 031 - void* unk034; // 034 + const char* unk034; // 034 PArtial name maybe? const char* fileName; // 038 NiPixelData* pixelData; // 03C UInt8 loadDirectToRender; // 040 UInt8 persistRenderData; // 041 UInt8 pad042[2]; // 042 void* unk044; // 044 + + NiSourceTexture() { + memset(this, 0, sizeof(NiSourceTexture)); + ThisCall(0x00701CD0, this); + } }; assert(sizeof(NiSourceTexture) == 0x048); @@ -2048,6 +2056,23 @@ class BSShaderLightingProperty : public BSShaderProperty { }; assert(sizeof(BSShaderLightingProperty) == 0x09C); +class WaterShaderProperty : public BSShaderProperty { +public: + UInt32 unk06C; // 06C + UInt8 unk070; // 070 + UInt8 unk071; // 071 + UInt8 unk072; // 072 + UInt8 pad073; // 073 + UInt32 unk074; // 074 + UInt32 unk078; // 078 + float unk07C; // 07C - init'd to 1 + float unk080; // 080 + UInt8 unk084; // 084 + UInt8 unk085; // 085 + UInt8 pad086[2]; // 086 +}; +assert(sizeof(WaterShaderProperty) == 0x088); + class BSShaderPPLightingProperty : public BSShaderLightingProperty { public: virtual void* Unk_1A(void * arg);