From 33815a6227e2eb144ec765928c56917360682e81 Mon Sep 17 00:00:00 2001 From: ehoclover Date: Thu, 20 Nov 2025 22:26:45 -0300 Subject: [PATCH] Initial implementation of the AetDB patch --- Source/DivaModLoader/AetDb.cpp | 47 +++++++++++++++++++ Source/DivaModLoader/AetDb.h | 6 +++ Source/DivaModLoader/AetDbImp.asm | 44 +++++++++++++++++ Source/DivaModLoader/Context.cpp | 2 + Source/DivaModLoader/DivaModLoader.vcxproj | 3 ++ .../DivaModLoader.vcxproj.filters | 3 ++ 6 files changed, 105 insertions(+) create mode 100644 Source/DivaModLoader/AetDb.cpp create mode 100644 Source/DivaModLoader/AetDb.h create mode 100644 Source/DivaModLoader/AetDbImp.asm diff --git a/Source/DivaModLoader/AetDb.cpp b/Source/DivaModLoader/AetDb.cpp new file mode 100644 index 0000000..021eaf2 --- /dev/null +++ b/Source/DivaModLoader/AetDb.cpp @@ -0,0 +1,47 @@ +#include "Types.h" +#include "AetDb.h" + +struct AetSetEntry +{ + struct AetSetInfo + { + uint32_t id; + const char* name; + INSERT_PADDING(0x20); + }; + + INSERT_PADDING(0x8); + AetSetInfo info; +}; + +struct AetSetComparer +{ + bool operator()(const AetSetEntry& entry, uint32_t id) const { return entry.info.id < id; } + bool operator()(uint32_t id, const AetSetEntry& entry) const { return id < entry.info.id; } +}; + +static prj::vector* aetSetEntries = reinterpret_cast*>(0x1414AB488); +static AetSetEntry::AetSetInfo* defaultAetSetEntry = reinterpret_cast(0x140DAEC60); + +// See `AetDbImp.asm` for implementation. +HOOK(AetSetEntry::AetSetInfo*, __fastcall, GetAetSetEntry, 0x1518B3D40, void* a1, uint32_t id); + +AetSetEntry::AetSetInfo* getAetSetEntryImp(void* a1, uint32_t id) +{ + // Execute a binary search for the AetSetInfo. This vector is already sorted by the game so + // we don't need to worry about that. Also make sure the returned AetSet id matches because + // when the entry is missing, std::equal_range will return the nearest entry and we don't + // want that! + auto it = std::equal_range(aetSetEntries->begin(), aetSetEntries->end(), id, AetSetComparer()).first; + if (it == aetSetEntries->end() || it->info.id != id) + return defaultAetSetEntry; + + return &it->info; +} + +void AetDB::init() +{ + // NOP-out the code that creates the lookup array for AetSetInfo + WRITE_NOP(0x14029363F, 0x69); + INSTALL_HOOK(GetAetSetEntry); +} \ No newline at end of file diff --git a/Source/DivaModLoader/AetDb.h b/Source/DivaModLoader/AetDb.h new file mode 100644 index 0000000..de3482b --- /dev/null +++ b/Source/DivaModLoader/AetDb.h @@ -0,0 +1,6 @@ +#pragma once + +struct AetDB +{ + static void init(); +}; \ No newline at end of file diff --git a/Source/DivaModLoader/AetDbImp.asm b/Source/DivaModLoader/AetDbImp.asm new file mode 100644 index 0000000..1bb85d2 --- /dev/null +++ b/Source/DivaModLoader/AetDbImp.asm @@ -0,0 +1,44 @@ +.code + +?getAetSetEntryImp@@YAPEAUAetSetInfo@AetSetEntry@@PEAXI@Z proto + +?implOfGetAetSetEntry@@YAPEAUAetSetInfo@AetSetEntry@@PEAXI@Z: + push rbx + push rcx + push rdx + push rsi + push rdi + push r8 + push r9 + push r10 + push r11 + push r12 + push r13 + push r14 + push r15 + + mov r15, rsp + sub rsp, 20h + and rsp, 0FFFFFFFFFFFFFFF0h + + call ?getAetSetEntryImp@@YAPEAUAetSetInfo@AetSetEntry@@PEAXI@Z + mov rsp, r15 + + pop r15 + pop r14 + pop r13 + pop r12 + pop r11 + pop r10 + pop r9 + pop r8 + pop rdi + pop rsi + pop rdx + pop rcx + pop rbx + ret + +public ?implOfGetAetSetEntry@@YAPEAUAetSetInfo@AetSetEntry@@PEAXI@Z + +end \ No newline at end of file diff --git a/Source/DivaModLoader/Context.cpp b/Source/DivaModLoader/Context.cpp index 1adbfa1..d8aed03 100644 --- a/Source/DivaModLoader/Context.cpp +++ b/Source/DivaModLoader/Context.cpp @@ -12,6 +12,7 @@ #include "Utilities.h" #include "PvLoader.h" #include "ThumbnailLoader.h" +#include "AetDb.h" HRESULT(*originalDirectInput8Create)(HINSTANCE, DWORD, REFIID, LPVOID*, LPUNKNOWN); extern "C" __declspec(dllexport) HRESULT DirectInput8Create(HINSTANCE hinst, DWORD dwVersion, REFIID riidltf, LPVOID* ppvOut, LPUNKNOWN punkOuter) @@ -108,4 +109,5 @@ void Context::postInit() CodeLoader::postInit(); PvLoader::init(); ThumbnailLoader::init(); + AetDB::init(); } diff --git a/Source/DivaModLoader/DivaModLoader.vcxproj b/Source/DivaModLoader/DivaModLoader.vcxproj index 8658c65..71b3d02 100644 --- a/Source/DivaModLoader/DivaModLoader.vcxproj +++ b/Source/DivaModLoader/DivaModLoader.vcxproj @@ -100,6 +100,7 @@ + @@ -119,6 +120,7 @@ + @@ -139,6 +141,7 @@ + diff --git a/Source/DivaModLoader/DivaModLoader.vcxproj.filters b/Source/DivaModLoader/DivaModLoader.vcxproj.filters index bedc235..a9861f4 100644 --- a/Source/DivaModLoader/DivaModLoader.vcxproj.filters +++ b/Source/DivaModLoader/DivaModLoader.vcxproj.filters @@ -18,6 +18,7 @@ + @@ -35,11 +36,13 @@ + + \ No newline at end of file