49static Ret
GenericCall(REL::ID a_id, uint32_t a_offset, Args... args)
51 using func_t = Ret (*)(Args...);
52 static REL::Relocation<func_t> target{a_id, a_offset};
53 return target(std::forward<Args>(args)...);
61 struct Patch : Xbyak::CodeGenerator
63 Patch(std::uintptr_t a_originalFuncAddr, std::size_t a_originalByteLength)
67 for (
size_t i = 0; i < a_originalByteLength; ++i)
69 db(*
reinterpret_cast<std::uint8_t*
>(a_originalFuncAddr + i));
72 dq(a_originalFuncAddr + a_originalByteLength);
76 Patch p(a_src, BYTES);
79 auto& trampoline = SKSE::GetTrampoline();
80 trampoline.write_branch<5>(a_src, T::thunk);
82 auto alloc = trampoline.allocate(p.getSize());
83 std::memcpy(alloc, p.getCode(), p.getSize());
85 T::func =
reinterpret_cast<std::uintptr_t
>(alloc);