refactor: Cleanup develhook logic
> refactor hooks::devel to work better with hooks::wmisc > minor naming consistency changes
This commit is contained in:
+81
-66
@@ -12,32 +12,50 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
|
||||||
namespace hooks::devel::thumbnail
|
namespace hooks::devel
|
||||||
{
|
{
|
||||||
typedef int (*BmswSymlink_t)(const char *srcwpath, const char *dstwpath, int canonic);
|
static class Thumbnail : public Routine
|
||||||
static BmswSymlink_t BmswSymlink;
|
|
||||||
|
|
||||||
void run()
|
|
||||||
{
|
{
|
||||||
HMODULE bmsw_ = nullptr;
|
public:
|
||||||
if ((bmsw_ = libutils::try_library(MODULE_PATH / "bmsound-wine.dll")))
|
using Routine::Routine;
|
||||||
|
void entry_main() override
|
||||||
{
|
{
|
||||||
BmswSymlink = (BmswSymlink_t) GetProcAddress(bmsw_, "BmswSymlink");
|
|
||||||
}
|
|
||||||
|
|
||||||
log_warning("hooks::devel::thumbnail", "Forcing thumbnail patch..");
|
log_warning("hooks::devel::thumbnail", "Forcing thumbnail patch..");
|
||||||
hooks::wmisc::apply_performance_hacks(avs::game::DLL_INSTANCE, "LDJ", "20250825");
|
hooks::wmisc::apply_performance_hacks(avs::game::DLL_INSTANCE, "FORCE", "thumbnail");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} thumbnail_("thum_test");
|
||||||
|
|
||||||
namespace hooks::devel::avs_fs
|
static class Msacm : public Routine
|
||||||
{
|
{
|
||||||
static constexpr char needle_[] = ""; // set to "" to print all
|
public:
|
||||||
static avs::core::AVS_FS_LSTAT_T avs_fs_lstat_;
|
using Routine::Routine;
|
||||||
static avs::core::AVS_FS_MOUNT_T avs_fs_mount_;
|
void entry_main() override
|
||||||
static avs::core::AVS_FS_OPEN_T avs_fs_open_;
|
{
|
||||||
|
log_warning("hooks::devel::msacm", "Forcing msacm patch..");
|
||||||
|
hooks::wmisc::apply_performance_hacks(avs::game::DLL_INSTANCE, "FORCE", "msacm");
|
||||||
|
}
|
||||||
|
} msacm_("acm_test");
|
||||||
|
|
||||||
int on_avs_fs_lstat(const char *path, struct avs::core::avs_stat *stat)
|
static class Wmisc : public Routine
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using Routine::Routine;
|
||||||
|
void attach() override
|
||||||
|
{
|
||||||
|
log_warning("hooks::devel::wmisc", "Disabling auto-patching..");
|
||||||
|
hooks::wmisc::skip_patching_by_model(true);
|
||||||
|
}
|
||||||
|
} wmisc_("wmisc_test");
|
||||||
|
|
||||||
|
static class Avs_fs : public Routine
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
static constexpr char needle_[] = ""; // set to "" to print all
|
||||||
|
inline static avs::core::AVS_FS_LSTAT_T avs_fs_lstat_;
|
||||||
|
inline static avs::core::AVS_FS_MOUNT_T avs_fs_mount_;
|
||||||
|
inline static avs::core::AVS_FS_OPEN_T avs_fs_open_;
|
||||||
|
|
||||||
|
static int on_avs_fs_lstat(const char *path, struct avs::core::avs_stat *stat)
|
||||||
{
|
{
|
||||||
if (strstr(path, needle_))
|
if (strstr(path, needle_))
|
||||||
{
|
{
|
||||||
@@ -45,7 +63,7 @@ int on_avs_fs_lstat(const char *path, struct avs::core::avs_stat *stat)
|
|||||||
}
|
}
|
||||||
return avs_fs_lstat_(path, stat);
|
return avs_fs_lstat_(path, stat);
|
||||||
}
|
}
|
||||||
avs::core::avs_file_t on_avs_fs_mount(const char *mountpoint, const char *fsroot, const char *fstype, void *data)
|
static avs::core::avs_file_t on_avs_fs_mount(const char *mountpoint, const char *fsroot, const char *fstype, void *data)
|
||||||
{
|
{
|
||||||
if (strstr(fsroot, needle_))
|
if (strstr(fsroot, needle_))
|
||||||
{
|
{
|
||||||
@@ -53,7 +71,7 @@ avs::core::avs_file_t on_avs_fs_mount(const char *mountpoint, const char *fsroot
|
|||||||
}
|
}
|
||||||
return avs_fs_mount_(mountpoint, fsroot, fstype, data);
|
return avs_fs_mount_(mountpoint, fsroot, fstype, data);
|
||||||
}
|
}
|
||||||
avs::core::avs_file_t on_avs_fs_open(const char *name, uint16_t mode, int flags)
|
static avs::core::avs_file_t on_avs_fs_open(const char *name, uint16_t mode, int flags)
|
||||||
{
|
{
|
||||||
if (strstr(name, needle_))
|
if (strstr(name, needle_))
|
||||||
{
|
{
|
||||||
@@ -61,26 +79,17 @@ avs::core::avs_file_t on_avs_fs_open(const char *name, uint16_t mode, int flags)
|
|||||||
}
|
}
|
||||||
return avs_fs_open_(name, mode, flags);
|
return avs_fs_open_(name, mode, flags);
|
||||||
}
|
}
|
||||||
void run()
|
|
||||||
|
public:
|
||||||
|
using Routine::Routine;
|
||||||
|
void entry_main() override
|
||||||
{
|
{
|
||||||
detour::trampoline(reinterpret_cast<void *>(avs::core::avs_fs_lstat), reinterpret_cast<void *>(on_avs_fs_lstat), reinterpret_cast<void **>(&avs_fs_lstat_));
|
detour::trampoline(reinterpret_cast<void *>(avs::core::avs_fs_lstat), reinterpret_cast<void *>(on_avs_fs_lstat), reinterpret_cast<void **>(&avs_fs_lstat_));
|
||||||
detour::trampoline(reinterpret_cast<void *>(avs::core::avs_fs_mount), reinterpret_cast<void *>(on_avs_fs_mount), reinterpret_cast<void **>(&avs_fs_mount_));
|
detour::trampoline(reinterpret_cast<void *>(avs::core::avs_fs_mount), reinterpret_cast<void *>(on_avs_fs_mount), reinterpret_cast<void **>(&avs_fs_mount_));
|
||||||
detour::trampoline(reinterpret_cast<void *>(avs::core::avs_fs_open), reinterpret_cast<void *>(on_avs_fs_open), reinterpret_cast<void **>(&avs_fs_open_));
|
detour::trampoline(reinterpret_cast<void *>(avs::core::avs_fs_open), reinterpret_cast<void *>(on_avs_fs_open), reinterpret_cast<void **>(&avs_fs_open_));
|
||||||
}
|
}
|
||||||
}
|
} avs_fs_("avs_fs_detour");
|
||||||
|
|
||||||
namespace hooks::devel
|
|
||||||
{
|
|
||||||
void (*routine_cb_[devel_routine_last])() ={
|
|
||||||
[avs_fs_detour] = avs_fs::run,
|
|
||||||
[sndb_test] = nullptr,
|
|
||||||
[thum_test] = thumbnail::run
|
|
||||||
};
|
|
||||||
|
|
||||||
//static constexpr unsigned int to_hash(const char *str, int h = 0)
|
|
||||||
//{
|
|
||||||
// return !str[h] ? 5381 : (to_hash(str, h + 1) * 33) ^ str[h];
|
|
||||||
//}
|
|
||||||
std::vector<std::string> from_env(const char *str)
|
std::vector<std::string> from_env(const char *str)
|
||||||
{
|
{
|
||||||
std::vector<std::string> r;
|
std::vector<std::string> r;
|
||||||
@@ -94,50 +103,56 @@ std::vector<std::string> from_env(const char *str)
|
|||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
static devel_routine_t routines()
|
static std::vector<Routine*> &routines()
|
||||||
{
|
{
|
||||||
static devel_routine_t routines_ = -1;
|
static std::vector<Routine*> routines_;
|
||||||
if (routines_ == static_cast<devel_routine_t>(-1))
|
if (routines_.empty())
|
||||||
{
|
{
|
||||||
routines_ = 0;
|
//Default routines
|
||||||
for (const auto &routine: from_env("SPICE_DEVEL"))
|
routines_.push_back(&avs_fs_);
|
||||||
{
|
routines_.push_back(&thumbnail_);
|
||||||
switch (to_hash(routine.c_str()))
|
routines_.push_back(&msacm_);
|
||||||
{
|
routines_.push_back(&wmisc_);
|
||||||
case to_hash("avs_fs_detour"):
|
|
||||||
routines_ |= 1 << avs_fs_detour;
|
|
||||||
break;
|
|
||||||
case to_hash("sndb_test"):
|
|
||||||
routines_ |= 1 << sndb_test;
|
|
||||||
break;
|
|
||||||
case to_hash("thum_test"):
|
|
||||||
routines_ |= 1 << thum_test;
|
|
||||||
break;
|
|
||||||
case to_hash("acm_test"):
|
|
||||||
routines_ |= 1 << acm_test;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return routines_;
|
return routines_;
|
||||||
}
|
}
|
||||||
bool active_routine(hooks::devel::devel_routine_t val)
|
Routine *active_routine(const char *name)
|
||||||
{
|
{
|
||||||
return routines() & (1 << val);
|
unsigned int hash = to_hash(name);
|
||||||
|
for (auto &routine: routines())
|
||||||
|
{
|
||||||
|
if (routine->hash() == hash)
|
||||||
|
return routine;
|
||||||
}
|
}
|
||||||
void bind_routine(devel_routine_t val, void (*cb)())
|
return nullptr;
|
||||||
|
}
|
||||||
|
void bind_routine(Routine *routine)
|
||||||
{
|
{
|
||||||
routine_cb_[val] = cb;
|
routines().push_back(routine);
|
||||||
|
}
|
||||||
|
void log_environment()
|
||||||
|
{
|
||||||
|
log_warning("hooks::devel", "WINEDLLOVERRIDES: '{}'", getenv("WINEDLLOVERRIDES") ? getenv("WINEDLLOVERRIDES") : "null");
|
||||||
}
|
}
|
||||||
void entry_main()
|
void entry_main()
|
||||||
{
|
{
|
||||||
if (routines()) log_info("hooks::devel", "Processing subroutines..");
|
log_environment();
|
||||||
for (devel_routine_t i = 0; i < devel_routine_last; i++)
|
const auto rnames = from_env("SPICE_DEVEL");
|
||||||
|
if (!rnames.empty()) log_info("hooks::devel", "Run subroutines..");
|
||||||
|
for (const auto &routinename: from_env("SPICE_DEVEL"))
|
||||||
{
|
{
|
||||||
if (active_routine(i) && routine_cb_[i]) routine_cb_[i]();
|
Routine *routine = active_routine(routinename.c_str());
|
||||||
|
if (routine) routine->entry_main();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void attach()
|
||||||
|
{
|
||||||
|
const auto rnames = from_env("SPICE_DEVEL");
|
||||||
|
if (!rnames.empty()) log_info("hooks::devel", "Attach subroutines..");
|
||||||
|
for (const auto &rname: rnames)
|
||||||
|
{
|
||||||
|
Routine *routine = active_routine(rname.c_str());
|
||||||
|
if (routine) routine->attach();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+14
-9
@@ -1,20 +1,25 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include "util/utils.h"
|
||||||
|
|
||||||
|
|
||||||
namespace hooks::devel
|
namespace hooks::devel
|
||||||
{
|
{
|
||||||
//_INFO: order matters, low level routines first (if you want them active during later routines)
|
//_INFO: use attach()/entry_main() to run task before game::attach()/game::entry_main()
|
||||||
enum devel_routine : uint32_t
|
class Routine
|
||||||
{
|
{
|
||||||
avs_fs_detour = 0,
|
private:
|
||||||
sndb_test,
|
unsigned int hash_;
|
||||||
thum_test,
|
public:
|
||||||
devel_routine_last
|
[[nodiscard]] inline unsigned int constexpr hash() const { return hash_; }
|
||||||
|
virtual void attach() {}
|
||||||
|
virtual void entry_main() {}
|
||||||
|
explicit Routine(const char *name) : hash_(to_hash(name)) {}
|
||||||
|
virtual ~Routine() = default;
|
||||||
};
|
};
|
||||||
typedef uint32_t devel_routine_t;
|
|
||||||
|
|
||||||
bool active_routine(devel_routine_t val);
|
Routine *active_routine(const char *name);
|
||||||
void bind_routine(devel_routine_t val, void (*cb)());
|
void bind_routine(Routine *routine);
|
||||||
|
void attach();
|
||||||
void entry_main();
|
void entry_main();
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-2
@@ -769,7 +769,11 @@ void *on_enum_valid_soundbanks(void *song, int32_t difficulty, int32_t unk2)
|
|||||||
*((char *) song + offset_.DAT_song_id + 8 + difficulty) = suffix;
|
*((char *) song + offset_.DAT_song_id + 8 + difficulty) = suffix;
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
void run_tests()
|
static class Tests : public hooks::devel::Routine
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using Routine::Routine;
|
||||||
|
void entry_main() override
|
||||||
{
|
{
|
||||||
size_t szs3p;
|
size_t szs3p;
|
||||||
BYTE *wav = nullptr;
|
BYTE *wav = nullptr;
|
||||||
@@ -868,6 +872,7 @@ void run_tests()
|
|||||||
snd_bank::flush_cache();
|
snd_bank::flush_cache();
|
||||||
mf_broken::deinit();
|
mf_broken::deinit();
|
||||||
}
|
}
|
||||||
|
} tests_("sndb_test");
|
||||||
void init(HINSTANCE hmodule, const char *model, const char *ext)
|
void init(HINSTANCE hmodule, const char *model, const char *ext)
|
||||||
{
|
{
|
||||||
if (false && IsDebuggerPresent())
|
if (false && IsDebuggerPresent())
|
||||||
@@ -960,7 +965,7 @@ void init(HINSTANCE hmodule, const char *model, const char *ext)
|
|||||||
// Setup on_enum_valid_ksbd and optional tests
|
// Setup on_enum_valid_ksbd and optional tests
|
||||||
offset_.guard = new memutils::VProtectGuard((void *) offset_.RD_05d_2dx, SNDPATHFMTMAX);
|
offset_.guard = new memutils::VProtectGuard((void *) offset_.RD_05d_2dx, SNDPATHFMTMAX);
|
||||||
detour::trampoline(reinterpret_cast<void *>(offset_.TX_BmsbEnumValidSoundbanks), reinterpret_cast<void *>(on_enum_valid_soundbanks), reinterpret_cast<void **>(&BmsbEnumValidSoundbanks));
|
detour::trampoline(reinterpret_cast<void *>(offset_.TX_BmsbEnumValidSoundbanks), reinterpret_cast<void *>(on_enum_valid_soundbanks), reinterpret_cast<void **>(&BmsbEnumValidSoundbanks));
|
||||||
hooks::devel::bind_routine(hooks::devel::sndb_test, run_tests);
|
hooks::devel::bind_routine(&tests_);
|
||||||
|
|
||||||
log_info("hooks::soundbank", "Soundbank preprocessor ready");
|
log_info("hooks::soundbank", "Soundbank preprocessor ready");
|
||||||
}
|
}
|
||||||
|
|||||||
+24
-5
@@ -55,7 +55,7 @@ MMRESULT __stdcall on_acmFormatSuggest(HANDLE had, LPWAVEFORMATEX pwfxSrc, LPWAV
|
|||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
void run(HINSTANCE hmodule)
|
void attach(HINSTANCE hmodule)
|
||||||
{
|
{
|
||||||
// Override acmFormatSuggest
|
// Override acmFormatSuggest
|
||||||
HMODULE msacm = nullptr;
|
HMODULE msacm = nullptr;
|
||||||
@@ -89,7 +89,7 @@ bool on_thum_exists_(void *titleUTF_getter, int32_t id, char flag)
|
|||||||
|
|
||||||
return it->second;
|
return it->second;
|
||||||
}
|
}
|
||||||
void run(HINSTANCE hmodule)
|
void attach(HINSTANCE hmodule)
|
||||||
{
|
{
|
||||||
// Reverse lookup function head (PUSH RDI) for ThumExists() specific signature, quietly fail if invalid
|
// Reverse lookup function head (PUSH RDI) for ThumExists() specific signature, quietly fail if invalid
|
||||||
intptr_t beg, match, TX_ThumExists;
|
intptr_t beg, match, TX_ThumExists;
|
||||||
@@ -107,18 +107,37 @@ void run(HINSTANCE hmodule)
|
|||||||
|
|
||||||
namespace hooks::wmisc
|
namespace hooks::wmisc
|
||||||
{
|
{
|
||||||
|
static bool patchmodel_ = true;
|
||||||
|
void skip_patching_by_model(bool val)
|
||||||
|
{
|
||||||
|
patchmodel_ = !val;
|
||||||
|
}
|
||||||
void apply_performance_hacks(HINSTANCE hmodule, const char *model, const char *ext)
|
void apply_performance_hacks(HINSTANCE hmodule, const char *model, const char *ext)
|
||||||
{
|
{
|
||||||
|
if (!patchmodel_ && strcmp(model, "FORCE") != 0) return;
|
||||||
|
|
||||||
log_info("hooks::wmisc", "Enabling performance patches for {}-{}", model, ext);
|
log_info("hooks::wmisc", "Enabling performance patches for {}-{}", model, ext);
|
||||||
switch (to_hash(model))
|
switch (to_hash(model))
|
||||||
{
|
{
|
||||||
case to_hash("LDJ"):
|
case to_hash("LDJ"):
|
||||||
thumbnail::run(hmodule);
|
thumbnail::attach(hmodule);
|
||||||
msacm::run(hmodule);
|
msacm::attach(hmodule);
|
||||||
|
break;
|
||||||
|
case to_hash("FORCE"):
|
||||||
|
switch (to_hash(ext))
|
||||||
|
{
|
||||||
|
case to_hash("thumbnail"):
|
||||||
|
thumbnail::attach(hmodule);
|
||||||
|
break;
|
||||||
|
case to_hash("msacm"):
|
||||||
|
msacm::attach(hmodule);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,5 +4,6 @@
|
|||||||
|
|
||||||
namespace hooks::wmisc
|
namespace hooks::wmisc
|
||||||
{
|
{
|
||||||
|
void skip_patching_by_model(bool val);
|
||||||
void apply_performance_hacks(HINSTANCE hmodule, const char *model, const char *ext);
|
void apply_performance_hacks(HINSTANCE hmodule, const char *model, const char *ext);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2069,6 +2069,9 @@ int main_implementation(int argc, char *argv[]) {
|
|||||||
// load game
|
// load game
|
||||||
avs::game::load_dll();
|
avs::game::load_dll();
|
||||||
|
|
||||||
|
// devel attach
|
||||||
|
hooks::devel::attach();
|
||||||
|
|
||||||
// attach games
|
// attach games
|
||||||
for (auto game : games) {
|
for (auto game : games) {
|
||||||
game->attach();
|
game->attach();
|
||||||
|
|||||||
Reference in New Issue
Block a user