mirror of
https://github.com/patchzyy/wiicompiled
synced 2026-10-21 13:54:55 -04:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4e73a51616 | |||
| 7db64ea00a | |||
| a222d02fbf | |||
| 9dfbef00f5 | |||
| 5e337e6ecf |
@@ -54,14 +54,13 @@ foreach ($relative in $sourceFiles | Sort-Object -Unique) {
|
||||
}
|
||||
|
||||
# One synthetic text section: li r3,40; addi r3,r3,2; nop; blr.
|
||||
# Native HLE wrappers also call these guest symbols directly. Give each
|
||||
# Native HLE wrappers also call these eight guest symbols directly. Give each
|
||||
# its own generated blr function so the real product can link without game code.
|
||||
# Keep this list explicit: a new unresolved guest dependency must fail the test.
|
||||
[uint32]$entry = 0x80001000L
|
||||
[uint32[]]$guestCallbacks = @(
|
||||
0x8012B830L, 0x801A0620L, 0x801A1ED8L, 0x801A961CL,
|
||||
0x801AADE0L, 0x801D8D30L, 0x801D9E94L, 0x8055531CL,
|
||||
0x80601C64L, 0x8061E348L, 0x8061E3B4L
|
||||
0x801AADE0L, 0x801D8D30L, 0x801D9E94L, 0x8055531CL
|
||||
)
|
||||
$textSize = [int]($guestCallbacks[-1] - $entry + 4)
|
||||
$dataOffset = 0x100 + $textSize
|
||||
@@ -76,9 +75,9 @@ Write-BigEndian32 0x00 0x100 # text[0] file offset
|
||||
Write-BigEndian32 0x48 $entry # text[0] guest address
|
||||
Write-BigEndian32 0x90 $textSize # text[0] length (unreachable gaps are zero)
|
||||
Write-BigEndian32 0x1C $dataOffset # data[0] file offset
|
||||
Write-BigEndian32 0x64 0x80700000L # data[0] guest address
|
||||
Write-BigEndian32 0x64 0x80600000L # data[0] guest address
|
||||
Write-BigEndian32 0xAC 4 # data[0] length
|
||||
Write-BigEndian32 0xD8 0x80701000L # BSS address
|
||||
Write-BigEndian32 0xD8 0x80601000L # BSS address
|
||||
Write-BigEndian32 0xDC 32 # BSS length
|
||||
Write-BigEndian32 0xE0 $entry # entry point
|
||||
Write-BigEndian32 0x100 0x38600028 # li r3,40
|
||||
@@ -103,8 +102,8 @@ project:
|
||||
memory:
|
||||
base: 0x80000000
|
||||
size: 0x01800000
|
||||
sda_base: 0x80700000
|
||||
sda2_base: 0x80700000
|
||||
sda_base: 0x80600000
|
||||
sda2_base: 0x80600000
|
||||
inputs:
|
||||
dol:
|
||||
path: synthetic.dol
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "friend_code_keyboard.h"
|
||||
#include "settings_overlay.h"
|
||||
#include "runtime_config.h"
|
||||
#include "gx_worker.h"
|
||||
@@ -119,7 +118,6 @@ inline void ProcessAuroraEvents(const AuroraEvent* events) {
|
||||
g_mkwDynamicAspectSurfacePending.store(true, std::memory_order_release);
|
||||
}
|
||||
settings_overlay::HandleEvents(events);
|
||||
FriendCodeKeyboard::HandleEvents(events);
|
||||
}
|
||||
|
||||
inline void ApplyPendingMkwDynamicAspectSurface() {
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <aurora/event.h>
|
||||
|
||||
// Lets the keyboard type into Retro Rewind's friend code entry page.
|
||||
namespace FriendCodeKeyboard {
|
||||
void HandleEvents(const AuroraEvent* events) noexcept;
|
||||
} // namespace FriendCodeKeyboard
|
||||
@@ -729,10 +729,6 @@ MKW_GUEST_ADDRESS(805529A8, 8054CA50, 80552328) // THP::VideoDecoder
|
||||
MKW_GUEST_ADDRESS(80552A74, 8054CB1C, 805523F4) // THP::VideoDecoderOnMemory
|
||||
MKW_GUEST_ADDRESS(8055531C, 8054F2FC, 80554C9C) // RelProlog
|
||||
MKW_GUEST_ADDRESS(805653D0, 80561050, 80564D50)
|
||||
MKW_GUEST_ADDRESS(80601C64, 805DD384, 806013D8) // Page::CheckActions
|
||||
MKW_GUEST_ADDRESS(8061E348, 805EE30C, 8061DABC) // Pages::RegisterFriend::OnDigitClick
|
||||
MKW_GUEST_ADDRESS(8061E3B4, 805EE378, 8061DB28) // Pages::RegisterFriend::OnBackSpaceClick
|
||||
MKW_GUEST_ADDRESS(8061E804, 805EE7C8, 8061DF78) // Pages::RegisterFriend::GetRuntimeTypeInfo
|
||||
MKW_GUEST_ADDRESS(8088F400, 8088AFD0, 8088EA6C)
|
||||
MKW_GUEST_ADDRESS(8088F704, 8088B2D4, 8088ED70)
|
||||
MKW_GUEST_ADDRESS(8088FDB8, 8088B960, 8088F418)
|
||||
|
||||
-3
@@ -8,6 +8,3 @@ MKW_GUEST_FUNCTION_IMPORT(801AADE0, 801AAD40, 801AAD00) // OS::__TimeToSystemTi
|
||||
MKW_GUEST_FUNCTION_IMPORT(801D8D30, 801D8C90, 801D8C50) // NHTTPStartup
|
||||
MKW_GUEST_FUNCTION_IMPORT(801D9E94, 801D9DF4, 801D9DB4) // NHTTPi_GetSystemInfoP
|
||||
MKW_GUEST_FUNCTION_IMPORT(8055531C, 8054F2FC, 80554C9C) // RelProlog
|
||||
MKW_GUEST_FUNCTION_IMPORT(80601C64, 805DD384, 806013D8) // Page::CheckActions
|
||||
MKW_GUEST_FUNCTION_IMPORT(8061E348, 805EE30C, 8061DABC) // Pages::RegisterFriend::OnDigitClick
|
||||
MKW_GUEST_FUNCTION_IMPORT(8061E3B4, 805EE378, 8061DB28) // Pages::RegisterFriend::OnBackSpaceClick
|
||||
|
||||
@@ -1,135 +0,0 @@
|
||||
#include "friend_code_keyboard.h"
|
||||
|
||||
#include "abi_bridge.h"
|
||||
#include "guest_abi/guest_region.h"
|
||||
#include "guest_function_imports.h"
|
||||
#include "input_bindings.h"
|
||||
#include "memory.h"
|
||||
#include "runtime_product.h"
|
||||
|
||||
#include <SDL3/SDL_events.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <cstdint>
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
namespace {
|
||||
|
||||
// UI::RegisterFriendPage
|
||||
constexpr uint32_t kDigitButtonsOffset = 0x44;
|
||||
constexpr uint32_t kPushButtonSize = 0x254;
|
||||
constexpr uint32_t kDigitButtonCount = 10;
|
||||
constexpr uint32_t kButtonDigitOffset = 0x240;
|
||||
constexpr uint32_t kPageStateOffset = 0x8;
|
||||
constexpr uint32_t kPageStateActive = 4;
|
||||
constexpr uint32_t kVtableGetTypeInfoOffset = 0x60;
|
||||
constexpr int kBackspace = -1;
|
||||
constexpr size_t kMaxPendingKeys = 32;
|
||||
|
||||
std::mutex g_pendingMutex;
|
||||
std::vector<int> g_pending;
|
||||
std::atomic_bool g_pageFocused{false};
|
||||
|
||||
std::optional<int> KeyValue(const SDL_KeyboardEvent& key) {
|
||||
if ((key.mod & (SDL_KMOD_CTRL | SDL_KMOD_ALT | SDL_KMOD_GUI)) != 0) {
|
||||
return std::nullopt;
|
||||
}
|
||||
if (key.scancode == SDL_SCANCODE_BACKSPACE) {
|
||||
return kBackspace;
|
||||
}
|
||||
if (key.repeat) {
|
||||
return std::nullopt;
|
||||
}
|
||||
if (key.scancode == SDL_SCANCODE_0 || key.scancode == SDL_SCANCODE_KP_0) {
|
||||
return 0;
|
||||
}
|
||||
if (key.scancode >= SDL_SCANCODE_1 && key.scancode <= SDL_SCANCODE_9) {
|
||||
return 1 + (key.scancode - SDL_SCANCODE_1);
|
||||
}
|
||||
if (key.scancode >= SDL_SCANCODE_KP_1 && key.scancode <= SDL_SCANCODE_KP_9) {
|
||||
return 1 + (key.scancode - SDL_SCANCODE_KP_1);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
bool IsFocusedRegisterFriendPage(uint32_t page) {
|
||||
try {
|
||||
const uint32_t vtable = Memory::Read32(page);
|
||||
return Memory::Read32(vtable + kVtableGetTypeInfoOffset) == MKW_GADDR(8061E804) &&
|
||||
Memory::Read32(page + kPageStateOffset) == kPageStateActive;
|
||||
} catch (const Memory::AccessViolation&) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<uint32_t> DigitButton(uint32_t page, int digit) {
|
||||
for (uint32_t i = 0; i < kDigitButtonCount; ++i) {
|
||||
const uint32_t button = page + kDigitButtonsOffset + i * kPushButtonSize;
|
||||
if (static_cast<int>(Memory::Read32(button + kButtonDigitOffset)) == digit) {
|
||||
return button;
|
||||
}
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
void Type(CpuContext* ctx, uint32_t page, int key) {
|
||||
if (key == kBackspace) {
|
||||
ctx->gpr[3] = page;
|
||||
MKW_GUEST_FUNC(8061E3B4)(ctx);
|
||||
return;
|
||||
}
|
||||
const std::optional<uint32_t> button = DigitButton(page, key);
|
||||
if (!button) {
|
||||
return;
|
||||
}
|
||||
ctx->gpr[3] = page;
|
||||
ctx->gpr[4] = *button;
|
||||
ctx->gpr[5] = 0;
|
||||
MKW_GUEST_FUNC(8061E348)(ctx);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace FriendCodeKeyboard {
|
||||
|
||||
void HandleEvents(const AuroraEvent* events) noexcept {
|
||||
if (!events || !g_pageFocused.load(std::memory_order_acquire) || InputBindings::InputBlocked()) {
|
||||
return;
|
||||
}
|
||||
std::lock_guard lock(g_pendingMutex);
|
||||
for (const AuroraEvent* ev = events; ev->type != AURORA_NONE; ++ev) {
|
||||
if (ev->type != AURORA_SDL_EVENT || ev->sdl.type != SDL_EVENT_KEY_DOWN) {
|
||||
continue;
|
||||
}
|
||||
const std::optional<int> key = KeyValue(ev->sdl.key);
|
||||
if (key && g_pending.size() < kMaxPendingKeys) {
|
||||
g_pending.push_back(*key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace FriendCodeKeyboard
|
||||
|
||||
// Page::CheckActions, only ever called for the topmost page.
|
||||
extern "C" void Page_CheckActions_80601c64(CpuContext* ctx) {
|
||||
const uint32_t page = ctx->gpr[3];
|
||||
MKW_GUEST_FUNC(80601C64)(ctx);
|
||||
|
||||
const bool focused = RuntimeProduct::IsRetroRewind() && IsFocusedRegisterFriendPage(page);
|
||||
g_pageFocused.store(focused, std::memory_order_release);
|
||||
std::vector<int> keys;
|
||||
{
|
||||
std::lock_guard lock(g_pendingMutex);
|
||||
keys.swap(g_pending);
|
||||
}
|
||||
if (!focused || InputBindings::InputBlocked()) {
|
||||
return;
|
||||
}
|
||||
for (const int key : keys) {
|
||||
Type(ctx, page, key);
|
||||
}
|
||||
}
|
||||
|
||||
REGISTER_NATIVE_FUNCTION_AS(0x80601C64, Page_CheckActions_80601c64, "Page_CheckActions_80601c64");
|
||||
Reference in New Issue
Block a user