mirror of
https://github.com/PretendoNetwork/Inkay.git
synced 2026-04-25 08:00:41 -05:00
feat(p2p): Port overrides for Splatoon and MK8
Some checks are pending
Inkay-CI / build-inkay (push) Waiting to run
Some checks are pending
Inkay-CI / build-inkay (push) Waiting to run
This commit is contained in:
parent
727f11d04d
commit
a6b91be935
|
|
@ -22,9 +22,56 @@
|
|||
#include "utils/replace_mem.h"
|
||||
|
||||
#include <optional>
|
||||
#include <algorithm>
|
||||
#include <string_view>
|
||||
using namespace std::string_view_literals;
|
||||
|
||||
static struct {
|
||||
std::array<uint64_t, 3> tid;
|
||||
uint32_t min_port_addr;
|
||||
uint32_t max_port_addr;
|
||||
std::string_view rpx;
|
||||
} generic_patch_games [] = {
|
||||
{ // MARIO KART 8
|
||||
{ 0x00050000'1010ec00, 0x00050000'1010ed00, 0x00050000'1010eb00 },
|
||||
0x101a9a52,
|
||||
0x101a9a54,
|
||||
"Turbo.rpx"sv,
|
||||
},
|
||||
{ // Splatoon
|
||||
{ 0x00050000'10176900, 0x00050000'10176a00, 0x00050000'10162b00 },
|
||||
0x101e8952,
|
||||
0x101e8954,
|
||||
"Gambit.rpx"sv,
|
||||
},
|
||||
};
|
||||
|
||||
static void generic_peertopeer_patch() {
|
||||
uint64_t tid = OSGetTitleID();
|
||||
|
||||
for (const auto& patch : generic_patch_games) {
|
||||
if (std::ranges::find(patch.tid, tid) == patch.tid.end()) continue;
|
||||
|
||||
std::optional<OSDynLoad_NotifyData> game = search_for_rpl(patch.rpx);
|
||||
if (!game) {
|
||||
DEBUG_FUNCTION_LINE("Couldn't find game rpx! (%s)", patch.rpx.data());
|
||||
return;
|
||||
}
|
||||
|
||||
auto port = get_console_peertopeer_port();
|
||||
DEBUG_FUNCTION_LINE_VERBOSE("Will use port %d. %08x", port, game->textAddr);
|
||||
|
||||
auto target = (uint16_t *)rpl_addr(*game, patch.min_port_addr);
|
||||
replace_unsigned<uint16_t>(target, 0xc000, port);
|
||||
|
||||
target = (uint16_t *)rpl_addr(*game, patch.max_port_addr);
|
||||
replace_unsigned<uint16_t>(target, 0xffff, port);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void minecraft_peertopeer_patch() {
|
||||
std::optional<OSDynLoad_NotifyData> minecraft = search_for_rpl("Minecraft.Client.rpx");
|
||||
std::optional<OSDynLoad_NotifyData> minecraft = search_for_rpl("Minecraft.Client.rpx"sv);
|
||||
if (!minecraft) {
|
||||
DEBUG_FUNCTION_LINE("Couldn't find minecraft rpx!");
|
||||
return;
|
||||
|
|
@ -33,12 +80,12 @@ static void minecraft_peertopeer_patch() {
|
|||
auto port = get_console_peertopeer_port();
|
||||
DEBUG_FUNCTION_LINE_VERBOSE("Will use port %d. %08x", port, minecraft->textAddr);
|
||||
|
||||
uint32_t *target_func = rpl_addr(*minecraft, 0x03579530);
|
||||
auto target_func = (uint32_t *)rpl_addr(*minecraft, 0x03579530);
|
||||
replace_instruction(&target_func[0], 0x3c600001, 0x3c600000); // li r3, 0
|
||||
replace_instruction(&target_func[1], 0x3863c000, 0x60630000 | port); // ori r3, r3, port
|
||||
// blr
|
||||
|
||||
target_func = rpl_addr(*minecraft, 0x0357953c);
|
||||
target_func = (uint32_t *)rpl_addr(*minecraft, 0x0357953c);
|
||||
replace_instruction(&target_func[0], 0x3c600001, 0x3c600000); // li r3, 0
|
||||
replace_instruction(&target_func[1], 0x3863ffff, 0x60630000 | port); // ori r3, r3, port
|
||||
// blr
|
||||
|
|
@ -56,6 +103,6 @@ void peertopeer_patch() {
|
|||
|
||||
minecraft_peertopeer_patch();
|
||||
} else {
|
||||
DEBUG_FUNCTION_LINE_VERBOSE("Game has no p2p patches, will skip.\n");
|
||||
generic_peertopeer_patch();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,17 +73,30 @@ void replaceBulk(uint32_t start, uint32_t size, std::span<const replacement> rep
|
|||
#endif
|
||||
}
|
||||
|
||||
bool replace_instruction(uint32_t *inst, uint32_t orignal_value, uint32_t new_value) {
|
||||
if (*inst != orignal_value) return false;
|
||||
template <typename U>
|
||||
requires std::integral<U>
|
||||
bool replace_unsigned(U *addr, U original_value, U new_value) {
|
||||
if (*addr != original_value) return false;
|
||||
|
||||
KernelCopyData(
|
||||
OSEffectiveToPhysical((uint32_t) inst),
|
||||
OSEffectiveToPhysical((uint32_t) addr),
|
||||
OSEffectiveToPhysical((uint32_t) &new_value),
|
||||
sizeof(new_value)
|
||||
);
|
||||
DCFlushRange(inst, sizeof(new_value));
|
||||
ICInvalidateRange(inst, sizeof(new_value));
|
||||
DCFlushRange(addr, sizeof(new_value));
|
||||
|
||||
DEBUG_FUNCTION_LINE_VERBOSE("%08x is now %08x", inst, *inst);
|
||||
return *inst == new_value;
|
||||
return *addr == new_value;
|
||||
}
|
||||
template bool replace_unsigned<uint64_t>(uint64_t *, uint64_t, uint64_t);
|
||||
template bool replace_unsigned<uint32_t>(uint32_t *, uint32_t, uint32_t);
|
||||
template bool replace_unsigned<uint16_t>(uint16_t *, uint16_t, uint16_t);
|
||||
template bool replace_unsigned<uint8_t>(uint8_t *, uint8_t, uint8_t);
|
||||
|
||||
bool replace_instruction(uint32_t *inst, uint32_t original_value, uint32_t new_value) {
|
||||
bool res = replace_unsigned<uint32_t>(inst, original_value, new_value);
|
||||
if (!res) return res;
|
||||
|
||||
ICInvalidateRange(inst, sizeof(new_value));
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,4 +28,8 @@ struct replacement {
|
|||
|
||||
void replaceBulk(uint32_t start, uint32_t size, std::span<const replacement> replacements);
|
||||
|
||||
bool replace_instruction(uint32_t *inst, uint32_t orignal_value, uint32_t new_value);
|
||||
template <typename U>
|
||||
requires std::integral<U>
|
||||
bool replace_unsigned(U *addr, U original_value, U new_value);
|
||||
|
||||
bool replace_instruction(uint32_t *inst, uint32_t original_value, uint32_t new_value);
|
||||
|
|
|
|||
|
|
@ -19,10 +19,10 @@
|
|||
|
||||
std::optional<OSDynLoad_NotifyData> search_for_rpl(std::string_view name);
|
||||
|
||||
constexpr uint32_t *rpl_addr(OSDynLoad_NotifyData rpl, uint32_t cemu_addr) {
|
||||
constexpr void *rpl_addr(OSDynLoad_NotifyData rpl, uint32_t cemu_addr) {
|
||||
if (cemu_addr < 0x1000'0000) {
|
||||
return (uint32_t *)(rpl.textAddr + cemu_addr - 0x0200'0000);
|
||||
return (void *)(rpl.textAddr + cemu_addr - 0x0200'0000);
|
||||
} else {
|
||||
return (uint32_t *)(rpl.dataAddr + cemu_addr - 0x1000'0000);
|
||||
return (void *)(rpl.dataAddr + cemu_addr - 0x1000'0000);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user