Skip to content

Commit

Permalink
re2gc softlock fix
Browse files Browse the repository at this point in the history
  • Loading branch information
ThirteenAG committed Oct 21, 2023
1 parent cb9bdd9 commit 182ebb7
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 37 deletions.
2 changes: 2 additions & 0 deletions .github/docs/re4.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

![](https://habrastorage.org/webt/ow/yy/mg/owyymgpibfqzfbwyf_iqoiqrede.png) Added an option to enable [Logitech G LIGHTSYNC RGB Lighting](https://www.logitechg.com/innovation/lightsync-rgb.html)

https://github.com/ThirteenAG/WidescreenFixesPack/assets/4904157/92ea000b-4646-40d6-9133-05e57e517e18

Installation:
Download and extract the archive to the game directory, where the exe is located.

Expand Down
47 changes: 28 additions & 19 deletions includes/dolphin/dolphin.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class Dolphin
return hook::pattern("0F B6 C8 E8 ? ? ? ? 33 D2");
}

static void SetIsThrottlerTempDisabled(bool disable)
static inline void SetIsThrottlerTempDisabled(bool disable)
{
if (!_SetIsThrottlerTempDisabled)
{
Expand All @@ -30,33 +30,42 @@ class Dolphin
return _SetIsThrottlerTempDisabled(disable);
}

static void MenuBarClearCache()
static inline void MenuBarClearCache()
{
if (!_MenuBarClearCache)
__try
{
auto pattern = hook::pattern("45 33 C9 45 33 C0 33 D2");
if (!pattern.empty())
[]()
{
for (size_t i = 0; i < pattern.size(); i++)
if (!_MenuBarClearCache)
{
auto range_pattern = hook::pattern((uintptr_t)pattern.get(i).get<uintptr_t>(0), (uintptr_t)pattern.get(i).get<uintptr_t>(200), "45 ? ? ? 8D");
if (!range_pattern.empty())
auto pattern = hook::pattern("45 33 C9 45 33 C0 33 D2");
if (!pattern.empty())
{
auto str = injector::ReadRelativeOffset(range_pattern.get(0).get<uintptr_t>(6)).get_raw<char>();
if (MemoryValid(str) && std::string_view(str) == "Clear Cache")
for (size_t i = 0; i < pattern.size(); i++)
{
_MenuBarClearCache = (void(__fastcall*)())(injector::ReadRelativeOffset(pattern.get(i).get<uintptr_t>(22)).as_int());
break;
auto range_pattern = hook::pattern((uintptr_t)pattern.get(i).get<uintptr_t>(0), (uintptr_t)pattern.get(i).get<uintptr_t>(200), "45 ? ? ? 8D");
if (!range_pattern.empty())
{
auto str = injector::ReadRelativeOffset(range_pattern.get(0).get<uintptr_t>(6)).get_raw<char>();
if (MemoryValid(str) && std::string_view(str) == "Clear Cache")
{
_MenuBarClearCache = (void(__fastcall*)())(injector::ReadRelativeOffset(pattern.get(i).get<uintptr_t>(22)).as_int());
break;
}
}
}
}
}
}
else
return _MenuBarClearCache();
}();
}
__except ((GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
{
}
else
return _MenuBarClearCache();
}

static void FindEmulatorMemory()
static inline void FindEmulatorMemory()
{
while (GameMemoryStart == 0)
{
Expand All @@ -81,7 +90,7 @@ class Dolphin
}
}

static bool MemoryValid()
static inline bool MemoryValid()
{
static MEMORY_BASIC_INFORMATION MemoryInf;
if (GameMemoryStart == 0 || VirtualQuery((LPCVOID)GameMemoryStart, &MemoryInf, sizeof(MemoryInf)) == 0 || MemoryInf.AllocationProtect != PAGE_READWRITE)
Expand All @@ -94,15 +103,15 @@ class Dolphin
}

template <typename T>
static bool MemoryValid(T addr)
static inline bool MemoryValid(T addr)
{
static MEMORY_BASIC_INFORMATION MemoryInf;
if (addr == 0 || VirtualQuery((LPCVOID)addr, &MemoryInf, sizeof(MemoryInf)) == 0 || MemoryInf.AllocationProtect != PAGE_READWRITE)
return false;
return true;
}

static std::string_view GameID()
static inline std::string_view GameID()
{
static auto default_id = "";
if (MemoryValid(GameMemoryStart))
Expand Down
130 changes: 112 additions & 18 deletions source/ResidentEvil2.Dolphin.FusionMod/dllmain.cpp
Original file line number Diff line number Diff line change
@@ -1,42 +1,68 @@
#include "stdafx.h"
#include <assembly64.hpp>
#include <dolphin/dolphin.h>
#include <LEDEffects.h>

static bool bLogiLedInitialized = false;

void Init()
{
CIniReader iniReader("");
static bool bEnableDoorSkip = iniReader.ReadInteger("MAIN", "EnableDoorSkip", 1) != 0;
static bool bUnthrottleEmuDuringDoorSkip = iniReader.ReadInteger("MAIN", "UnthrottleEmuDuringDoorSkip", 1) != 0;
static bool bLightSyncRGB = iniReader.ReadInteger("MAIN", "LightSyncRGB", 1) != 0;

if (!bEnableDoorSkip && !bUnthrottleEmuDuringDoorSkip)
if (!bEnableDoorSkip && !bUnthrottleEmuDuringDoorSkip && !bLightSyncRGB)
return;

if (bLightSyncRGB && !bLogiLedInitialized && false)
{
bLogiLedInitialized = LogiLedInit();
if (bLogiLedInitialized) {
LogiLedStopEffects();
LEDEffects::SetLighting(52, 0, 0); //logo red

IATHook::Replace(GetModuleHandleA(NULL), "KERNEL32.DLL",
std::forward_as_tuple("ExitProcessImplementation", static_cast<void(__stdcall*)(UINT)>([](UINT uExitCode) {
if (bLogiLedInitialized) {
LogiLedShutdown();
bLogiLedInitialized = false;
}
ExitProcess(uExitCode);
}))
);
}
}

std::thread([]()
{
using namespace powerpc;
using namespace std::chrono_literals;

static auto swap16 = [](uint16_t n) -> uint16_t
{
return (n >> 8) | (n << 8);
};

static auto convert = [](uint32_t n) -> uint32_t
{
auto ptr = (unsigned char*)&n;
return (ptr[1] << 24) | (ptr[0] << 16) | 0 | 0;
};

static uint32_t* data = nullptr;
static int16_t* sPlayerHealth = nullptr;
while (true)
{
std::this_thread::yield();
std::this_thread::sleep_for(std::chrono::milliseconds(100));
if (Dolphin::MemoryValid())
{
if (Dolphin::GameID() == "GHAE08" || Dolphin::GameID() == "GHAP08")
{
static uint32_t* memcheck = nullptr;
static uint32_t bytes = 0;
if (data == nullptr || (memcheck && *memcheck != bytes))
if (data == nullptr || (Dolphin::MemoryValid(memcheck) && *memcheck != bytes))
{
auto swap16 = [](uint16_t n) -> uint16_t
{
return (n >> 8) | (n << 8);
};
auto convert = [](uint32_t n) -> uint32_t
{
auto ptr = (unsigned char*)&n;
return (ptr[1] << 24) | (ptr[0] << 16) | 0 | 0;
};
auto pattern = hook::pattern(Dolphin::GameMemoryStart, Dolphin::GameMemoryEnd, "38 a0 00 01 3c 60 ? ? 38 83 ? ? 90 a4 00 00 3c 60");
if (pattern.size() >= 1)
{
Expand All @@ -48,19 +74,29 @@ void Init()
if (a != 0 && b != 0)
data = (uint32_t*)((convert(a) - int16_t(0 - b) + c) - Dolphin::ImageBase + Dolphin::GameMemoryStart);
}
if (bEnableDoorSkip)

if (bLogiLedInitialized)
{
pattern = hook::pattern(Dolphin::GameMemoryStart, Dolphin::GameMemoryEnd, "7f a0 22 14 ? ? ? ? ? ? ? ? 38 00 00 00 ? ? ? ? 38 00 00 00");
LogiLedStopEffects();
LEDEffects::SetLighting(52, 0, 0); //logo red

auto pattern = hook::pattern(Dolphin::GameMemoryStart, Dolphin::GameMemoryEnd, "3c 60 ? ? 38 63 ? ? ? ? ? ? 2c 00 00 00 ? ? ? ? 38 00 ? ? 3c 60 ? ? 38 63 ? ? ? ? ? ? 3c 60 ? ? 38 63 ? ? ? ? ? ? 54 00 02 94");
if (pattern.size() >= 1)
{
injector::WriteMemory(pattern.get(0).get<void>(4), li(r0, 10), true);
Dolphin::MenuBarClearCache();
uint16_t a = swap16(*pattern.get(0).get<uint16_t>(2));
uint16_t b = swap16(*pattern.get(0).get<uint16_t>(6));
uint16_t c = swap16(*pattern.get(0).get<uint16_t>(10));
if (a != 0 && b != 0)
sPlayerHealth = (int16_t*)((convert(a) + b + c) - Dolphin::ImageBase + Dolphin::GameMemoryStart);
}
}

pattern = hook::pattern(Dolphin::GameMemoryStart, Dolphin::GameMemoryEnd, "54 7d 04 3e 38 00 00 01 98 1f 00 01 38 00 00 00");
if (bEnableDoorSkip)
{
auto pattern = hook::pattern(Dolphin::GameMemoryStart, Dolphin::GameMemoryEnd, "28 00 00 00 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 54 00 03 9c 28 00 00 00 ? ? ? ? 38 00 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 48 00 ? ? 48 00");
if (pattern.size() >= 1)
{
injector::WriteMemory(pattern.get(0).get<void>(4), li(r0, 0), true);
injector::WriteMemory<uint16_t>(pattern.get(0).get<void>(4), 0x0048, true); // bne -> b
Dolphin::MenuBarClearCache();
}
}
Expand All @@ -71,12 +107,63 @@ void Init()
{
Dolphin::SetIsThrottlerTempDisabled(true);
}

if (bLogiLedInitialized)
{
if (Dolphin::MemoryValid(sPlayerHealth))
{
int16_t health1 = (int16_t)swap16(*sPlayerHealth);
auto poisoned = *(int8_t*)((uintptr_t)sPlayerHealth + 0xC2);
if (health1 > 1)
{
if (health1 <= 20) {
if (!poisoned)
LEDEffects::SetLighting(26, 4, 4, true, false); //red
else
LEDEffects::SetLighting(51, 4, 53, true, false); //purple
LEDEffects::DrawCardiogram(100, 0, 0, 0, 0, 0); //red
}
else if (health1 <= 40) {
if (!poisoned)
LEDEffects::SetLighting(100, 39, 13, true, false); //orange
else
LEDEffects::SetLighting(51, 4, 53, true, false); //purple
LEDEffects::DrawCardiogram(100, 0, 0, 0, 0, 0); //red
}
else if (health1 <= 100) {
if (!poisoned)
LEDEffects::SetLighting(52, 48, 0, true, false); //orange
else
LEDEffects::SetLighting(51, 4, 53, true, false); //purple
LEDEffects::DrawCardiogram(67, 0, 0, 0, 0, 0); //orange
}
else {
if (!poisoned)
LEDEffects::SetLighting(0, 48, 0, true, false); //green
else
LEDEffects::SetLighting(51, 4, 53, true, false); //purple
LEDEffects::DrawCardiogram(0, 100, 0, 0, 0, 0); //green
}
}
else
{
LEDEffects::SetLighting(26, 4, 4, false); //red
LEDEffects::DrawCardiogram(100, 0, 0, 0, 0, 0);
}
}
else
{
LogiLedStopEffects();
LEDEffects::SetLighting(52, 0, 0); //logo red
}
}
}
}
}
else
{
data = nullptr;
sPlayerHealth = nullptr;
}
}
}
Expand All @@ -97,5 +184,12 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID lpReserved)
{
if (!IsUALPresent()) { InitializeASI(); }
}
else if (reason == DLL_PROCESS_DETACH)
{
if (bLogiLedInitialized) {
LogiLedShutdown();
bLogiLedInitialized = false;
}
}
return TRUE;
}

0 comments on commit 182ebb7

Please sign in to comment.