diff --git a/UnleashedRecomp/CMakeLists.txt b/UnleashedRecomp/CMakeLists.txt index 746d0da..71729da 100644 --- a/UnleashedRecomp/CMakeLists.txt +++ b/UnleashedRecomp/CMakeLists.txt @@ -50,10 +50,12 @@ set(SWA_APU_CXX_SOURCES set(SWA_HID_CXX_SOURCES "hid/hid.cpp" + "hid/driver/sdl_hid.cpp" ) set(SWA_CXX_SOURCES "main.cpp" + "misc_impl.cpp" ${SWA_KERNEL_CXX_SOURCES} ${SWA_CPU_CXX_SOURCES} diff --git a/UnleashedRecomp/cpu/code_cache.cpp b/UnleashedRecomp/cpu/code_cache.cpp index 84df9dd..f23a924 100644 --- a/UnleashedRecomp/cpu/code_cache.cpp +++ b/UnleashedRecomp/cpu/code_cache.cpp @@ -38,10 +38,10 @@ void* CodeCache::Find(uint32_t guest) const SWA_API PPCFunc* KeFindHostFunction(uint32_t guest) { - return static_cast(gCodeCache.Find(guest)); + return static_cast(g_codeCache.Find(guest)); } SWA_API void KeInsertHostFunction(uint32_t guest, PPCFunc* function) { - gCodeCache.Insert(guest, function); + g_codeCache.Insert(guest, function); } diff --git a/UnleashedRecomp/cpu/code_cache.h b/UnleashedRecomp/cpu/code_cache.h index 09d7451..35d610b 100644 --- a/UnleashedRecomp/cpu/code_cache.h +++ b/UnleashedRecomp/cpu/code_cache.h @@ -16,4 +16,4 @@ struct CodeCache SWA_API PPCFunc* KeFindHostFunction(uint32_t guest); SWA_API void KeInsertHostFunction(uint32_t guest, PPCFunc* function); -extern CodeCache gCodeCache; +extern CodeCache g_codeCache; diff --git a/UnleashedRecomp/cpu/guest_code.h b/UnleashedRecomp/cpu/guest_code.h index 9c92095..11a2708 100644 --- a/UnleashedRecomp/cpu/guest_code.h +++ b/UnleashedRecomp/cpu/guest_code.h @@ -13,7 +13,7 @@ struct GuestCode inline static void Run(void* hostAddress, PPCContext* ctx) { ctx->fpscr.loadFromHost(); - reinterpret_cast(hostAddress)(*ctx, reinterpret_cast(gMemory.base)); + reinterpret_cast(hostAddress)(*ctx, reinterpret_cast(g_memory.base)); } inline static void Run(void* hostAddress) diff --git a/UnleashedRecomp/cpu/guest_thread.cpp b/UnleashedRecomp/cpu/guest_thread.cpp index 7bffa7e..c13f580 100644 --- a/UnleashedRecomp/cpu/guest_thread.cpp +++ b/UnleashedRecomp/cpu/guest_thread.cpp @@ -24,30 +24,30 @@ DWORD GuestThread::Start(uint32_t function) DWORD GuestThread::Start(const GuestThreadParameter& parameter) { - auto* thread = (uint8_t*)gUserHeap.Alloc(TOTAL_SIZE); + auto* thread = (uint8_t*)g_userHeap.Alloc(TOTAL_SIZE); const auto procMask = (uint8_t)(parameter.flags >> 24); const auto cpuNumber = procMask == 0 ? 0 : 7 - std::countl_zero(procMask); memset(thread, 0, TOTAL_SIZE); - *(uint32_t*)thread = std::byteswap(gMemory.MapVirtual(thread + PCR_SIZE)); // tls pointer - *(uint32_t*)(thread + 0x100) = std::byteswap(gMemory.MapVirtual(thread + PCR_SIZE + TLS_SIZE)); // teb pointer + *(uint32_t*)thread = std::byteswap(g_memory.MapVirtual(thread + PCR_SIZE)); // tls pointer + *(uint32_t*)(thread + 0x100) = std::byteswap(g_memory.MapVirtual(thread + PCR_SIZE + TLS_SIZE)); // teb pointer *(thread + 0x10C) = cpuNumber; *(uint32_t*)(thread + PCR_SIZE + 0x10) = 0xFFFFFFFF; // that one TLS entry that felt quirky *(uint32_t*)(thread + PCR_SIZE + TLS_SIZE + 0x14C) = std::byteswap(GetCurrentThreadId()); // thread id PPCContext ppcContext{}; - ppcContext.fn = (uint8_t*)gCodeCache.bucket; - ppcContext.r1.u64 = gMemory.MapVirtual(thread + PCR_SIZE + TLS_SIZE + TEB_SIZE + STACK_SIZE); // stack pointer + ppcContext.fn = (uint8_t*)g_codeCache.bucket; + ppcContext.r1.u64 = g_memory.MapVirtual(thread + PCR_SIZE + TLS_SIZE + TEB_SIZE + STACK_SIZE); // stack pointer ppcContext.r3.u64 = parameter.value; - ppcContext.r13.u64 = gMemory.MapVirtual(thread); + ppcContext.r13.u64 = g_memory.MapVirtual(thread); SetPPCContext(ppcContext); - GuestCode::Run(gCodeCache.Find(parameter.function), &ppcContext, gMemory.Translate(0), gMemory.Translate(ppcContext.r1.u32)); - gUserHeap.Free(thread); + GuestCode::Run(g_codeCache.Find(parameter.function), &ppcContext, g_memory.Translate(0), g_memory.Translate(ppcContext.r1.u32)); + g_userHeap.Free(thread); return (DWORD)ppcContext.r3.u64; } @@ -99,7 +99,7 @@ void GuestThread::SetThreadName(uint32_t id, const char* name) void GuestThread::SetLastError(DWORD error) { - auto* thread = (char*)gMemory.Translate(GetPPCContext()->r13.u32); + auto* thread = (char*)g_memory.Translate(GetPPCContext()->r13.u32); if (*(DWORD*)(thread + 0x150)) { // Program doesn't want errors @@ -113,14 +113,14 @@ void GuestThread::SetLastError(DWORD error) PPCContext* GuestThread::Invoke(uint32_t address) { auto* ctx = GetPPCContext(); - GuestCode::Run(gCodeCache.Find(address), ctx); + GuestCode::Run(g_codeCache.Find(address), ctx); return ctx; } void SetThreadNameImpl(uint32_t a1, uint32_t threadId, uint32_t* name) { - GuestThread::SetThreadName(threadId, (const char*)gMemory.Translate(std::byteswap(*name))); + GuestThread::SetThreadName(threadId, (const char*)g_memory.Translate(std::byteswap(*name))); } int GetThreadPriorityImpl(uint32_t hThread) @@ -133,19 +133,6 @@ DWORD SetThreadIdealProcessorImpl(uint32_t hThread, DWORD dwIdealProcessor) return SetThreadIdealProcessor((HANDLE)hThread, dwIdealProcessor); } -GUEST_FUNCTION_HOOK(sub_831B0ED0, memcpy); -GUEST_FUNCTION_HOOK(sub_831CCB98, memcpy); -GUEST_FUNCTION_HOOK(sub_831CEAE0, memcpy); -GUEST_FUNCTION_HOOK(sub_831CEE04, memcpy); -GUEST_FUNCTION_HOOK(sub_831CF2D0, memcpy); -GUEST_FUNCTION_HOOK(sub_831CF660, memcpy); -GUEST_FUNCTION_HOOK(sub_831B1358, memcpy); -GUEST_FUNCTION_HOOK(sub_831B5E00, memmove); -GUEST_FUNCTION_HOOK(sub_831B0BA0, memset); -GUEST_FUNCTION_HOOK(sub_831CCAA0, memset); - -GUEST_FUNCTION_HOOK(sub_82BD4CA8, OutputDebugStringA); - GUEST_FUNCTION_HOOK(sub_82DFA2E8, SetThreadNameImpl); GUEST_FUNCTION_HOOK(sub_82BD57A8, GetThreadPriorityImpl); GUEST_FUNCTION_HOOK(sub_82BD5910, SetThreadIdealProcessorImpl); diff --git a/UnleashedRecomp/hid/driver/sdl_hid.cpp b/UnleashedRecomp/hid/driver/sdl_hid.cpp new file mode 100644 index 0000000..f3066f1 --- /dev/null +++ b/UnleashedRecomp/hid/driver/sdl_hid.cpp @@ -0,0 +1,256 @@ +#include +#include +#include +#define VIBRATION_TIMEOUT_MS 5000 + +class Controller +{ +public: + SDL_GameController* controller{}; + SDL_Joystick* joystick{}; + SDL_JoystickID id{ -1 }; + XAMINPUT_GAMEPAD state{}; + XAMINPUT_VIBRATION vibration{ 0, 0 }; + + Controller() = default; + explicit Controller(int index) : Controller(SDL_GameControllerOpen(index)) + { + + } + + Controller(SDL_GameController* controller) : controller(controller) + { + if (!controller) + { + return; + } + + joystick = SDL_GameControllerGetJoystick(controller); + id = SDL_JoystickInstanceID(joystick); + } + + void Close() + { + if (controller == nullptr) + { + return; + } + + SDL_GameControllerClose(controller); + controller = nullptr; + joystick = nullptr; + id = -1; + } + + void PollAxis() + { + auto& pad = state; + pad.sThumbLX = SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_LEFTX); + pad.sThumbLY = ~SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_LEFTY); + + pad.sThumbRX = SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_RIGHTX); + pad.sThumbRY = ~SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_RIGHTY); + + pad.bLeftTrigger = SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_TRIGGERLEFT) >> 7; + pad.bRightTrigger = SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_TRIGGERRIGHT) >> 7; + } + + #define TRANSLATE_INPUT(S, X) SDL_GameControllerGetButton(controller, S) << FirstBitLow(X) + void Poll() + { + if (controller == nullptr) + { + return; + } + auto& pad = state; + pad.wButtons = 0; + + pad.wButtons |= TRANSLATE_INPUT(SDL_CONTROLLER_BUTTON_DPAD_UP, XAMINPUT_GAMEPAD_DPAD_UP); + pad.wButtons |= TRANSLATE_INPUT(SDL_CONTROLLER_BUTTON_DPAD_DOWN, XAMINPUT_GAMEPAD_DPAD_DOWN); + pad.wButtons |= TRANSLATE_INPUT(SDL_CONTROLLER_BUTTON_DPAD_LEFT, XAMINPUT_GAMEPAD_DPAD_LEFT); + pad.wButtons |= TRANSLATE_INPUT(SDL_CONTROLLER_BUTTON_DPAD_RIGHT, XAMINPUT_GAMEPAD_DPAD_RIGHT); + + pad.wButtons |= TRANSLATE_INPUT(SDL_CONTROLLER_BUTTON_START, XAMINPUT_GAMEPAD_START); + pad.wButtons |= TRANSLATE_INPUT(SDL_CONTROLLER_BUTTON_BACK, XAMINPUT_GAMEPAD_BACK); + + pad.wButtons |= TRANSLATE_INPUT(SDL_CONTROLLER_BUTTON_LEFTSTICK, XAMINPUT_GAMEPAD_LEFT_THUMB); + pad.wButtons |= TRANSLATE_INPUT(SDL_CONTROLLER_BUTTON_RIGHTSTICK, XAMINPUT_GAMEPAD_RIGHT_THUMB); + + pad.wButtons |= TRANSLATE_INPUT(SDL_CONTROLLER_BUTTON_LEFTSHOULDER, XAMINPUT_GAMEPAD_LEFT_SHOULDER); + pad.wButtons |= TRANSLATE_INPUT(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, XAMINPUT_GAMEPAD_RIGHT_SHOULDER); + + pad.wButtons |= TRANSLATE_INPUT(SDL_CONTROLLER_BUTTON_A, XAMINPUT_GAMEPAD_A); + pad.wButtons |= TRANSLATE_INPUT(SDL_CONTROLLER_BUTTON_B, XAMINPUT_GAMEPAD_B); + pad.wButtons |= TRANSLATE_INPUT(SDL_CONTROLLER_BUTTON_X, XAMINPUT_GAMEPAD_X); + pad.wButtons |= TRANSLATE_INPUT(SDL_CONTROLLER_BUTTON_Y, XAMINPUT_GAMEPAD_Y); + } + + void SetVibration(const XAMINPUT_VIBRATION& vibration) + { + if (controller == nullptr) + { + return; + } + + this->vibration = vibration; + SDL_GameControllerRumble(controller, vibration.wLeftMotorSpeed * 256, vibration.wRightMotorSpeed * 256, VIBRATION_TIMEOUT_MS); + } +}; + +std::array g_controllers; + +inline Controller* EnsureController(DWORD dwUserIndex) +{ + if (!g_controllers[dwUserIndex].controller) + { + return nullptr; + } + + return &g_controllers[dwUserIndex]; +} + +inline size_t FindFreeController() +{ + for (size_t i = 0; i < g_controllers.size(); i++) + { + if (!g_controllers[i].controller) + { + return i; + } + } + + return -1; +} + +inline Controller* FindController(int which) +{ + for (auto& controller : g_controllers) + { + if (controller.id == which) + { + return &controller; + } + } + + return nullptr; +} + +int OnSDLEvent(void*, SDL_Event* event) +{ + if (event->type >= SDL_CONTROLLERAXISMOTION && event->type < SDL_FINGERDOWN) + { + if (event->type == SDL_CONTROLLERDEVICEADDED) + { + const auto freeIndex = FindFreeController(); + if (freeIndex != -1) + { + g_controllers[freeIndex] = Controller(event->cdevice.which); + } + } + if (event->type == SDL_CONTROLLERDEVICEREMOVED) + { + auto* controller = FindController(event->cdevice.which); + if (controller) + { + controller->Close(); + } + } + else if (event->type == SDL_CONTROLLERBUTTONDOWN || event->type == SDL_CONTROLLERBUTTONUP || event->type == SDL_CONTROLLERAXISMOTION) + { + auto* controller = FindController(event->cdevice.which); + if (controller) + { + if (event->type == SDL_CONTROLLERAXISMOTION) + { + controller->PollAxis(); + } + else + { + controller->Poll(); + } + } + } + } + + return 0; +} + +void hid::detail::Init() +{ + SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS3, "1"); + SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS4, "1"); + SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS5, "1"); + SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_WII, "1"); + SDL_SetHint(SDL_HINT_XINPUT_ENABLED, "1"); + + SDL_InitSubSystem(SDL_INIT_EVENTS); + + SDL_AddEventWatch(OnSDLEvent, nullptr); + + SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER); +} + +uint32_t hid::detail::GetState(uint32_t dwUserIndex, XAMINPUT_STATE* pState) +{ + static DWORD packet; + if (!pState) + { + return ERROR_BAD_ARGUMENTS; + } + + memset(pState, 0, sizeof(*pState)); + pState->dwPacketNumber = packet++; + + SDL_JoystickUpdate(); + auto* controller = EnsureController(dwUserIndex); + if (controller == nullptr) + { + return ERROR_DEVICE_NOT_CONNECTED; + } + + pState->Gamepad = g_controllers[dwUserIndex].state; + return ERROR_SUCCESS; +} + +uint32_t hid::detail::SetState(uint32_t dwUserIndex, XAMINPUT_VIBRATION* pVibration) +{ + if (!pVibration) + { + return ERROR_BAD_ARGUMENTS; + } + + SDL_JoystickUpdate(); + auto* controller = EnsureController(dwUserIndex); + if (controller == nullptr) + { + return ERROR_DEVICE_NOT_CONNECTED; + } + + controller->SetVibration(*pVibration); + return ERROR_SUCCESS; +} + +uint32_t hid::detail::GetCapabilities(uint32_t dwUserIndex, XAMINPUT_CAPABILITIES* pCaps) +{ + if (!pCaps) + { + return ERROR_BAD_ARGUMENTS; + } + + SDL_JoystickUpdate(); + auto* controller = EnsureController(dwUserIndex); + if (controller == nullptr) + { + return ERROR_DEVICE_NOT_CONNECTED; + } + + memset(pCaps, 0, sizeof(*pCaps)); + pCaps->Type = XAMINPUT_DEVTYPE_GAMEPAD; + pCaps->SubType = XAMINPUT_DEVSUBTYPE_GAMEPAD; // TODO: other types? + pCaps->Flags = 0; + + pCaps->Gamepad = controller->state; + pCaps->Vibration = controller->vibration; + + return ERROR_SUCCESS; +} diff --git a/UnleashedRecomp/hid/hid.cpp b/UnleashedRecomp/hid/hid.cpp index 712f233..c08961a 100644 --- a/UnleashedRecomp/hid/hid.cpp +++ b/UnleashedRecomp/hid/hid.cpp @@ -1,22 +1,23 @@ #include #include "hid.h" +#include "hid_detail.h" -DWORD hid::GetState(DWORD dwUserIndex, XAMINPUT_STATE* pState) +void hid::Init() { - return 1; + detail::Init(); } -DWORD hid::SetState(DWORD dwUserIndex, XAMINPUT_VIBRATION* pVibration) +uint32_t hid::GetState(uint32_t dwUserIndex, XAMINPUT_STATE* pState) { - return 1; + return detail::GetState(dwUserIndex, pState); } -DWORD hid::GetCapabilities(DWORD dwUserIndex, XAMINPUT_CAPABILITIES* pCaps) +uint32_t hid::SetState(uint32_t dwUserIndex, XAMINPUT_VIBRATION* pVibration) { - return 1; + return detail::SetState(dwUserIndex, pVibration); } -int hid::OnSDLEvent(void*, SDL_Event* event) +uint32_t hid::GetCapabilities(uint32_t dwUserIndex, XAMINPUT_CAPABILITIES* pCaps) { - return 0; + return detail::GetCapabilities(dwUserIndex, pCaps); } diff --git a/UnleashedRecomp/hid/hid.h b/UnleashedRecomp/hid/hid.h index a0a68f9..90370d3 100644 --- a/UnleashedRecomp/hid/hid.h +++ b/UnleashedRecomp/hid/hid.h @@ -4,10 +4,8 @@ union SDL_Event; namespace hid { void Init(); - DWORD GetState(DWORD dwUserIndex, XAMINPUT_STATE* pState); - DWORD SetState(DWORD dwUserIndex, XAMINPUT_VIBRATION* pVibration); + uint32_t GetState(uint32_t dwUserIndex, XAMINPUT_STATE* pState); + uint32_t SetState(uint32_t dwUserIndex, XAMINPUT_VIBRATION* pVibration); - DWORD GetCapabilities(DWORD dwUserIndex, XAMINPUT_CAPABILITIES* pCaps); - - int OnSDLEvent(void*, SDL_Event* event); -} \ No newline at end of file + uint32_t GetCapabilities(uint32_t dwUserIndex, XAMINPUT_CAPABILITIES* pCaps); +} diff --git a/UnleashedRecomp/hid/hid_detail.h b/UnleashedRecomp/hid/hid_detail.h new file mode 100644 index 0000000..1e9ca1b --- /dev/null +++ b/UnleashedRecomp/hid/hid_detail.h @@ -0,0 +1,10 @@ +#pragma once +namespace hid::detail +{ + void Init(); + + uint32_t GetState(uint32_t dwUserIndex, XAMINPUT_STATE* pState); + uint32_t SetState(uint32_t dwUserIndex, XAMINPUT_VIBRATION* pVibration); + + uint32_t GetCapabilities(uint32_t dwUserIndex, XAMINPUT_CAPABILITIES* pCaps); +} diff --git a/UnleashedRecomp/kernel/heap.cpp b/UnleashedRecomp/kernel/heap.cpp index 4443837..efa59a6 100644 --- a/UnleashedRecomp/kernel/heap.cpp +++ b/UnleashedRecomp/kernel/heap.cpp @@ -8,11 +8,11 @@ constexpr size_t RESERVED_END = 0xA0000000; void Heap::Init() { - gMemory.Alloc(0x20000, RESERVED_BEGIN - 0x20000, MEM_COMMIT); - heap = o1heapInit(gMemory.Translate(0x20000), RESERVED_BEGIN - 0x20000); + g_memory.Alloc(0x20000, RESERVED_BEGIN - 0x20000, MEM_COMMIT); + heap = o1heapInit(g_memory.Translate(0x20000), RESERVED_BEGIN - 0x20000); - gMemory.Alloc(RESERVED_END, 0x100000000 - RESERVED_END, MEM_COMMIT); - physicalHeap = o1heapInit(gMemory.Translate(RESERVED_END), 0x100000000 - RESERVED_END); + g_memory.Alloc(RESERVED_END, 0x100000000 - RESERVED_END, MEM_COMMIT); + physicalHeap = o1heapInit(g_memory.Translate(RESERVED_END), 0x100000000 - RESERVED_END); } void* Heap::Alloc(size_t size) @@ -62,35 +62,35 @@ size_t Heap::Size(void* ptr) uint32_t RtlAllocateHeap(uint32_t heapHandle, uint32_t flags, uint32_t size) { - void* ptr = gUserHeap.Alloc(size); + void* ptr = g_userHeap.Alloc(size); if ((flags & 0x8) != 0) memset(ptr, 0, size); assert(ptr); - return gMemory.MapVirtual(ptr); + return g_memory.MapVirtual(ptr); } uint32_t RtlReAllocateHeap(uint32_t heapHandle, uint32_t flags, uint32_t memoryPointer, uint32_t size) { - void* ptr = gUserHeap.Alloc(size); + void* ptr = g_userHeap.Alloc(size); if ((flags & 0x8) != 0) memset(ptr, 0, size); if (memoryPointer != 0) { - void* oldPtr = gMemory.Translate(memoryPointer); - memcpy(ptr, oldPtr, std::min(size, gUserHeap.Size(oldPtr))); - gUserHeap.Free(oldPtr); + void* oldPtr = g_memory.Translate(memoryPointer); + memcpy(ptr, oldPtr, std::min(size, g_userHeap.Size(oldPtr))); + g_userHeap.Free(oldPtr); } assert(ptr); - return gMemory.MapVirtual(ptr); + return g_memory.MapVirtual(ptr); } uint32_t RtlFreeHeap(uint32_t heapHandle, uint32_t flags, uint32_t memoryPointer) { if (memoryPointer != NULL) - gUserHeap.Free(gMemory.Translate(memoryPointer)); + g_userHeap.Free(g_memory.Translate(memoryPointer)); return true; } @@ -98,7 +98,7 @@ uint32_t RtlFreeHeap(uint32_t heapHandle, uint32_t flags, uint32_t memoryPointer uint32_t RtlSizeHeap(uint32_t heapHandle, uint32_t flags, uint32_t memoryPointer) { if (memoryPointer != NULL) - return (uint32_t)gUserHeap.Size(gMemory.Translate(memoryPointer)); + return (uint32_t)g_userHeap.Size(g_memory.Translate(memoryPointer)); return 0; } @@ -106,20 +106,20 @@ uint32_t RtlSizeHeap(uint32_t heapHandle, uint32_t flags, uint32_t memoryPointer SWA_API uint32_t XAlloc(uint32_t size, uint32_t flags) { void* ptr = (flags & 0x80000000) != 0 ? - gUserHeap.AllocPhysical(size, (1ull << ((flags >> 24) & 0xF))) : - gUserHeap.Alloc(size); + g_userHeap.AllocPhysical(size, (1ull << ((flags >> 24) & 0xF))) : + g_userHeap.Alloc(size); if ((flags & 0x40000000) != 0) memset(ptr, 0, size); assert(ptr); - return gMemory.MapVirtual(ptr); + return g_memory.MapVirtual(ptr); } SWA_API void XFree(uint32_t baseAddress, uint32_t flags) { if (baseAddress != NULL) - gUserHeap.Free(gMemory.Translate(baseAddress)); + g_userHeap.Free(g_memory.Translate(baseAddress)); } GUEST_FUNCTION_STUB(sub_82BD7788); // HeapCreate diff --git a/UnleashedRecomp/kernel/heap.h b/UnleashedRecomp/kernel/heap.h index e3e2ef7..26f8066 100644 --- a/UnleashedRecomp/kernel/heap.h +++ b/UnleashedRecomp/kernel/heap.h @@ -35,4 +35,4 @@ struct Heap } }; -extern Heap gUserHeap; \ No newline at end of file +extern Heap g_userHeap; diff --git a/UnleashedRecomp/kernel/imports.cpp b/UnleashedRecomp/kernel/imports.cpp index 4a8548f..be0a3fe 100644 --- a/UnleashedRecomp/kernel/imports.cpp +++ b/UnleashedRecomp/kernel/imports.cpp @@ -701,7 +701,7 @@ void KfAcquireSpinLock(uint32_t* spinLock) const auto ctx = GetPPCContext(); //printf("!!! STUB !!! KfAcquireSpinLock\n"); - while (InterlockedCompareExchange((volatile long*)spinLock, std::byteswap(*(uint32_t*)(gMemory.Translate(ctx->r13.u32 + 0x110))), 0) != 0) + while (InterlockedCompareExchange((volatile long*)spinLock, std::byteswap(*(uint32_t*)(g_memory.Translate(ctx->r13.u32 + 0x110))), 0) != 0) { Sleep(0); } @@ -717,7 +717,7 @@ void MmFreePhysicalMemory(uint32_t type, uint32_t guestAddress) { //printf("!!! STUB !!! MmFreePhysicalMemory\n"); if (guestAddress != NULL) - gUserHeap.Free(gMemory.Translate(guestAddress)); + g_userHeap.Free(g_memory.Translate(guestAddress)); } bool VdPersistDisplay(uint32_t a1, uint32_t* a2) @@ -748,7 +748,7 @@ void KeAcquireSpinLockAtRaisedIrql(uint32_t* spinLock) const auto ctx = GetPPCContext(); //printf("!!! STUB !!! KeAcquireSpinLockAtRaisedIrql\n"); - while (InterlockedCompareExchange((volatile long*)spinLock, std::byteswap(*(uint32_t*)(gMemory.Translate(ctx->r13.u32 + 0x110))), 0) != 0) + while (InterlockedCompareExchange((volatile long*)spinLock, std::byteswap(*(uint32_t*)(g_memory.Translate(ctx->r13.u32 + 0x110))), 0) != 0) { Sleep(0); } @@ -891,7 +891,7 @@ uint32_t MmAllocatePhysicalMemoryEx( uint32_t alignment) { printf("MmAllocatePhysicalMemoryEx(): %x %x %x %x %x %x\n", flags, size, protect, minAddress, maxAddress, alignment); - return gMemory.MapVirtual(gUserHeap.AllocPhysical(size, alignment)); + return g_memory.MapVirtual(g_userHeap.AllocPhysical(size, alignment)); } void ObDeleteSymbolicLink() @@ -997,7 +997,7 @@ DWORD XMsgInProcessCall(uint32_t app, uint32_t message, XDWORD* param1, XDWORD* if (message == 0x7001B) { - uint32_t* ptr = (uint32_t*)gMemory.Translate(param1[1]); + uint32_t* ptr = (uint32_t*)g_memory.Translate(param1[1]); ptr[0] = 0; ptr[1] = 0; } diff --git a/UnleashedRecomp/kernel/memory.cpp b/UnleashedRecomp/kernel/memory.cpp index 2e1b791..cd4c2dc 100644 --- a/UnleashedRecomp/kernel/memory.cpp +++ b/UnleashedRecomp/kernel/memory.cpp @@ -33,5 +33,5 @@ uint32_t Memory::MapVirtual(void* host) const noexcept SWA_API void* MmGetHostAddress(uint32_t ptr) { - return gMemory.Translate(ptr); + return g_memory.Translate(ptr); } diff --git a/UnleashedRecomp/kernel/memory.h b/UnleashedRecomp/kernel/memory.h index 591602f..bd2c5d9 100644 --- a/UnleashedRecomp/kernel/memory.h +++ b/UnleashedRecomp/kernel/memory.h @@ -19,4 +19,4 @@ public: }; SWA_API void* MmGetHostAddress(uint32_t ptr); -extern Memory gMemory; +extern Memory g_memory; diff --git a/UnleashedRecomp/main.cpp b/UnleashedRecomp/main.cpp index cca736d..af2ae66 100644 --- a/UnleashedRecomp/main.cpp +++ b/UnleashedRecomp/main.cpp @@ -10,15 +10,16 @@ #include #include #include +#include #define GAME_XEX_PATH "game:\\default.xex" const size_t XMAIOBegin = 0x7FEA0000; const size_t XMAIOEnd = XMAIOBegin + 0x0000FFFF; -Memory gMemory{ reinterpret_cast(0x100000000), 0x100000000 }; -Heap gUserHeap; -CodeCache gCodeCache; +Memory g_memory{ reinterpret_cast(0x100000000), 0x100000000 }; +Heap g_userHeap; +CodeCache g_codeCache; // Name inspired from nt's entry point void KiSystemStartup() @@ -27,11 +28,11 @@ void KiSystemStartup() CoInitializeEx(nullptr, COINIT_MULTITHREADED); #endif - gMemory.Alloc(0x10000, 0x1000, MEM_COMMIT); - gUserHeap.Init(); - gCodeCache.Init(); + g_memory.Alloc(0x10000, 0x1000, MEM_COMMIT); + g_userHeap.Init(); + g_codeCache.Init(); - gMemory.Alloc(XMAIOBegin, 0xFFFF, MEM_COMMIT); + g_memory.Alloc(XMAIOBegin, 0xFFFF, MEM_COMMIT); const auto gameContent = XamMakeContent(XCONTENTTYPE_RESERVED, "Game"); const auto updateContent = XamMakeContent(XCONTENTTYPE_RESERVED, "Update"); @@ -55,6 +56,7 @@ void KiSystemStartup() XamContentCreateEx(0, "D", &gameContent, OPEN_EXISTING, nullptr, nullptr, 0, 0, nullptr); XAudioInitializeSystem(); + hid::Init(); } uint32_t LdrLoadModule(const char* path) @@ -69,7 +71,7 @@ uint32_t LdrLoadModule(const char* path) auto* xex = reinterpret_cast(loadResult->data()); auto security = reinterpret_cast((char*)xex + xex->AddressOfSecurityInfo); - gMemory.Alloc(security->ImageBase, security->SizeOfImage, MEM_COMMIT); + g_memory.Alloc(security->ImageBase, security->SizeOfImage, MEM_COMMIT); auto format = Xex2FindOptionalHeader(xex, XEX_HEADER_FILE_FORMAT_INFO); auto entry = *Xex2FindOptionalHeader(xex, XEX_HEADER_ENTRY_POINT); @@ -79,7 +81,7 @@ uint32_t LdrLoadModule(const char* path) if (format->CompressionType == 1) { auto srcData = (char*)xex + xex->SizeOfHeader; - auto destData = (char*)gMemory.Translate(security->ImageBase); + auto destData = (char*)g_memory.Translate(security->ImageBase); auto numBlocks = (format->SizeOfHeader / sizeof(XEX_BASIC_FILE_COMPRESSION_INFO)) - 1; auto blocks = reinterpret_cast(format + 1); diff --git a/UnleashedRecomp/misc_impl.cpp b/UnleashedRecomp/misc_impl.cpp new file mode 100644 index 0000000..3b7bf15 --- /dev/null +++ b/UnleashedRecomp/misc_impl.cpp @@ -0,0 +1,318 @@ +#include "stdafx.h" +#include + +// TODO: Multiplatform support +void CriErrNotify1(const char* message) +{ + OutputDebugStringA(message); + OutputDebugStringA("\n"); +} + +void CriErrNotify2(uint32_t category, const char* message) +{ + OutputDebugStringA(message); + OutputDebugStringA("\n"); +} + +BOOL QueryPerformanceCounterImpl(LARGE_INTEGER* lpPerformanceCount) +{ + BOOL result = QueryPerformanceCounter(lpPerformanceCount); + ByteSwap(lpPerformanceCount->QuadPart); + return result; +} + +BOOL QueryPerformanceFrequencyImpl(LARGE_INTEGER* lpFrequency) +{ + BOOL result = QueryPerformanceFrequency(lpFrequency); + ByteSwap(lpFrequency->QuadPart); + return result; +} + +// https://learn.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-memorystatus +typedef struct _XMEMORYSTATUS { + XDWORD dwLength; + XDWORD dwMemoryLoad; + XDWORD dwTotalPhys; + XDWORD dwAvailPhys; + XDWORD dwTotalPageFile; + XDWORD dwAvailPageFile; + XDWORD dwTotalVirtual; + XDWORD dwAvailVirtual; +} XMEMORYSTATUS, *XLPMEMORYSTATUS; + +void GlobalMemoryStatusImpl(XLPMEMORYSTATUS lpMemoryStatus) +{ + lpMemoryStatus->dwLength = sizeof(XMEMORYSTATUS); + lpMemoryStatus->dwMemoryLoad = 0; + lpMemoryStatus->dwTotalPhys = 0x20000000; + lpMemoryStatus->dwAvailPhys = 0x20000000; + lpMemoryStatus->dwTotalPageFile = 0x20000000; + lpMemoryStatus->dwAvailPageFile = 0x20000000; + lpMemoryStatus->dwTotalVirtual = 0x20000000; + lpMemoryStatus->dwAvailVirtual = 0x20000000; +} + +GUEST_FUNCTION_HOOK(sub_831B0ED0, memcpy); +GUEST_FUNCTION_HOOK(sub_831CCB98, memcpy); +GUEST_FUNCTION_HOOK(sub_831CEAE0, memcpy); +GUEST_FUNCTION_HOOK(sub_831CEE04, memcpy); +GUEST_FUNCTION_HOOK(sub_831CF2D0, memcpy); +GUEST_FUNCTION_HOOK(sub_831CF660, memcpy); +GUEST_FUNCTION_HOOK(sub_831B1358, memcpy); +GUEST_FUNCTION_HOOK(sub_831B5E00, memmove); +GUEST_FUNCTION_HOOK(sub_831B0BA0, memset); +GUEST_FUNCTION_HOOK(sub_831CCAA0, memset); + +GUEST_FUNCTION_HOOK(sub_82BD4CA8, OutputDebugStringA); + +#ifdef _DEBUG +GUEST_FUNCTION_HOOK(sub_8312EB48, CriErrNotify1); +GUEST_FUNCTION_HOOK(sub_83185B00, CriErrNotify1); +GUEST_FUNCTION_HOOK(sub_831683E0, CriErrNotify2); +#endif + +GUEST_FUNCTION_HOOK(sub_82BD4AC8, QueryPerformanceCounterImpl); +GUEST_FUNCTION_HOOK(sub_831CD040, QueryPerformanceFrequencyImpl); + +GUEST_FUNCTION_HOOK(sub_82BD4BC0, GlobalMemoryStatusImpl); + +#if defined(PPC_CONFIG_NON_VOLATILE_AS_LOCAL) && defined(PPC_CONFIG_NON_ARGUMENT_AS_LOCAL) + +GUEST_FUNCTION_STUB(sub_831B1400); +GUEST_FUNCTION_STUB(__savefpr_15); +GUEST_FUNCTION_STUB(__savefpr_16); +GUEST_FUNCTION_STUB(__savefpr_17); +GUEST_FUNCTION_STUB(__savefpr_18); +GUEST_FUNCTION_STUB(__savefpr_19); +GUEST_FUNCTION_STUB(__savefpr_20); +GUEST_FUNCTION_STUB(__savefpr_21); +GUEST_FUNCTION_STUB(__savefpr_22); +GUEST_FUNCTION_STUB(__savefpr_23); +GUEST_FUNCTION_STUB(__savefpr_24); +GUEST_FUNCTION_STUB(__savefpr_25); +GUEST_FUNCTION_STUB(__savefpr_26); +GUEST_FUNCTION_STUB(__savefpr_27); +GUEST_FUNCTION_STUB(__savefpr_28); +GUEST_FUNCTION_STUB(__savefpr_29); +GUEST_FUNCTION_STUB(__savefpr_30); +GUEST_FUNCTION_STUB(__savefpr_31); +GUEST_FUNCTION_STUB(sub_831B144C); +GUEST_FUNCTION_STUB(__restfpr_15); +GUEST_FUNCTION_STUB(__restfpr_16); +GUEST_FUNCTION_STUB(__restfpr_17); +GUEST_FUNCTION_STUB(__restfpr_18); +GUEST_FUNCTION_STUB(__restfpr_19); +GUEST_FUNCTION_STUB(__restfpr_20); +GUEST_FUNCTION_STUB(__restfpr_21); +GUEST_FUNCTION_STUB(__restfpr_22); +GUEST_FUNCTION_STUB(__restfpr_23); +GUEST_FUNCTION_STUB(__restfpr_24); +GUEST_FUNCTION_STUB(__restfpr_25); +GUEST_FUNCTION_STUB(__restfpr_26); +GUEST_FUNCTION_STUB(__restfpr_27); +GUEST_FUNCTION_STUB(__restfpr_28); +GUEST_FUNCTION_STUB(__restfpr_29); +GUEST_FUNCTION_STUB(__restfpr_30); +GUEST_FUNCTION_STUB(__restfpr_31); +GUEST_FUNCTION_STUB(sub_831B0AF0); +GUEST_FUNCTION_STUB(__savegprlr_15); +GUEST_FUNCTION_STUB(__savegprlr_16); +GUEST_FUNCTION_STUB(__savegprlr_17); +GUEST_FUNCTION_STUB(__savegprlr_18); +GUEST_FUNCTION_STUB(__savegprlr_19); +GUEST_FUNCTION_STUB(__savegprlr_20); +GUEST_FUNCTION_STUB(__savegprlr_21); +GUEST_FUNCTION_STUB(__savegprlr_22); +GUEST_FUNCTION_STUB(__savegprlr_23); +GUEST_FUNCTION_STUB(__savegprlr_24); +GUEST_FUNCTION_STUB(__savegprlr_25); +GUEST_FUNCTION_STUB(__savegprlr_26); +GUEST_FUNCTION_STUB(__savegprlr_27); +GUEST_FUNCTION_STUB(__savegprlr_28); +GUEST_FUNCTION_STUB(__savegprlr_29); +GUEST_FUNCTION_STUB(__savegprlr_30); +GUEST_FUNCTION_STUB(__savegprlr_31); +GUEST_FUNCTION_STUB(sub_831B0B40); +GUEST_FUNCTION_STUB(__restgprlr_15); +GUEST_FUNCTION_STUB(__restgprlr_16); +GUEST_FUNCTION_STUB(__restgprlr_17); +GUEST_FUNCTION_STUB(__restgprlr_18); +GUEST_FUNCTION_STUB(__restgprlr_19); +GUEST_FUNCTION_STUB(__restgprlr_20); +GUEST_FUNCTION_STUB(__restgprlr_21); +GUEST_FUNCTION_STUB(__restgprlr_22); +GUEST_FUNCTION_STUB(__restgprlr_23); +GUEST_FUNCTION_STUB(__restgprlr_24); +GUEST_FUNCTION_STUB(__restgprlr_25); +GUEST_FUNCTION_STUB(__restgprlr_26); +GUEST_FUNCTION_STUB(__restgprlr_27); +GUEST_FUNCTION_STUB(__restgprlr_28); +GUEST_FUNCTION_STUB(__restgprlr_29); +GUEST_FUNCTION_STUB(__restgprlr_30); +GUEST_FUNCTION_STUB(__restgprlr_31); +GUEST_FUNCTION_STUB(sub_831B3450); +GUEST_FUNCTION_STUB(__savevmx_15); +GUEST_FUNCTION_STUB(__savevmx_16); +GUEST_FUNCTION_STUB(__savevmx_17); +GUEST_FUNCTION_STUB(__savevmx_18); +GUEST_FUNCTION_STUB(__savevmx_19); +GUEST_FUNCTION_STUB(__savevmx_20); +GUEST_FUNCTION_STUB(__savevmx_21); +GUEST_FUNCTION_STUB(__savevmx_22); +GUEST_FUNCTION_STUB(__savevmx_23); +GUEST_FUNCTION_STUB(__savevmx_24); +GUEST_FUNCTION_STUB(__savevmx_25); +GUEST_FUNCTION_STUB(__savevmx_26); +GUEST_FUNCTION_STUB(__savevmx_27); +GUEST_FUNCTION_STUB(__savevmx_28); +GUEST_FUNCTION_STUB(__savevmx_29); +GUEST_FUNCTION_STUB(__savevmx_30); +GUEST_FUNCTION_STUB(__savevmx_31); +GUEST_FUNCTION_STUB(__savevmx_64); +GUEST_FUNCTION_STUB(__savevmx_65); +GUEST_FUNCTION_STUB(__savevmx_66); +GUEST_FUNCTION_STUB(__savevmx_67); +GUEST_FUNCTION_STUB(__savevmx_68); +GUEST_FUNCTION_STUB(__savevmx_69); +GUEST_FUNCTION_STUB(__savevmx_70); +GUEST_FUNCTION_STUB(__savevmx_71); +GUEST_FUNCTION_STUB(__savevmx_72); +GUEST_FUNCTION_STUB(__savevmx_73); +GUEST_FUNCTION_STUB(__savevmx_74); +GUEST_FUNCTION_STUB(__savevmx_75); +GUEST_FUNCTION_STUB(__savevmx_76); +GUEST_FUNCTION_STUB(__savevmx_77); +GUEST_FUNCTION_STUB(__savevmx_78); +GUEST_FUNCTION_STUB(__savevmx_79); +GUEST_FUNCTION_STUB(__savevmx_80); +GUEST_FUNCTION_STUB(__savevmx_81); +GUEST_FUNCTION_STUB(__savevmx_82); +GUEST_FUNCTION_STUB(__savevmx_83); +GUEST_FUNCTION_STUB(__savevmx_84); +GUEST_FUNCTION_STUB(__savevmx_85); +GUEST_FUNCTION_STUB(__savevmx_86); +GUEST_FUNCTION_STUB(__savevmx_87); +GUEST_FUNCTION_STUB(__savevmx_88); +GUEST_FUNCTION_STUB(__savevmx_89); +GUEST_FUNCTION_STUB(__savevmx_90); +GUEST_FUNCTION_STUB(__savevmx_91); +GUEST_FUNCTION_STUB(__savevmx_92); +GUEST_FUNCTION_STUB(__savevmx_93); +GUEST_FUNCTION_STUB(__savevmx_94); +GUEST_FUNCTION_STUB(__savevmx_95); +GUEST_FUNCTION_STUB(__savevmx_96); +GUEST_FUNCTION_STUB(__savevmx_97); +GUEST_FUNCTION_STUB(__savevmx_98); +GUEST_FUNCTION_STUB(__savevmx_99); +GUEST_FUNCTION_STUB(__savevmx_100); +GUEST_FUNCTION_STUB(__savevmx_101); +GUEST_FUNCTION_STUB(__savevmx_102); +GUEST_FUNCTION_STUB(__savevmx_103); +GUEST_FUNCTION_STUB(__savevmx_104); +GUEST_FUNCTION_STUB(__savevmx_105); +GUEST_FUNCTION_STUB(__savevmx_106); +GUEST_FUNCTION_STUB(__savevmx_107); +GUEST_FUNCTION_STUB(__savevmx_108); +GUEST_FUNCTION_STUB(__savevmx_109); +GUEST_FUNCTION_STUB(__savevmx_110); +GUEST_FUNCTION_STUB(__savevmx_111); +GUEST_FUNCTION_STUB(__savevmx_112); +GUEST_FUNCTION_STUB(__savevmx_113); +GUEST_FUNCTION_STUB(__savevmx_114); +GUEST_FUNCTION_STUB(__savevmx_115); +GUEST_FUNCTION_STUB(__savevmx_116); +GUEST_FUNCTION_STUB(__savevmx_117); +GUEST_FUNCTION_STUB(__savevmx_118); +GUEST_FUNCTION_STUB(__savevmx_119); +GUEST_FUNCTION_STUB(__savevmx_120); +GUEST_FUNCTION_STUB(__savevmx_121); +GUEST_FUNCTION_STUB(__savevmx_122); +GUEST_FUNCTION_STUB(__savevmx_123); +GUEST_FUNCTION_STUB(__savevmx_124); +GUEST_FUNCTION_STUB(__savevmx_125); +GUEST_FUNCTION_STUB(__savevmx_126); +GUEST_FUNCTION_STUB(__savevmx_127); +GUEST_FUNCTION_STUB(sub_831B36E8); +GUEST_FUNCTION_STUB(__restvmx_15); +GUEST_FUNCTION_STUB(__restvmx_16); +GUEST_FUNCTION_STUB(__restvmx_17); +GUEST_FUNCTION_STUB(__restvmx_18); +GUEST_FUNCTION_STUB(__restvmx_19); +GUEST_FUNCTION_STUB(__restvmx_20); +GUEST_FUNCTION_STUB(__restvmx_21); +GUEST_FUNCTION_STUB(__restvmx_22); +GUEST_FUNCTION_STUB(__restvmx_23); +GUEST_FUNCTION_STUB(__restvmx_24); +GUEST_FUNCTION_STUB(__restvmx_25); +GUEST_FUNCTION_STUB(__restvmx_26); +GUEST_FUNCTION_STUB(__restvmx_27); +GUEST_FUNCTION_STUB(__restvmx_28); +GUEST_FUNCTION_STUB(__restvmx_29); +GUEST_FUNCTION_STUB(__restvmx_30); +GUEST_FUNCTION_STUB(__restvmx_31); +GUEST_FUNCTION_STUB(__restvmx_64); +GUEST_FUNCTION_STUB(__restvmx_65); +GUEST_FUNCTION_STUB(__restvmx_66); +GUEST_FUNCTION_STUB(__restvmx_67); +GUEST_FUNCTION_STUB(__restvmx_68); +GUEST_FUNCTION_STUB(__restvmx_69); +GUEST_FUNCTION_STUB(__restvmx_70); +GUEST_FUNCTION_STUB(__restvmx_71); +GUEST_FUNCTION_STUB(__restvmx_72); +GUEST_FUNCTION_STUB(__restvmx_73); +GUEST_FUNCTION_STUB(__restvmx_74); +GUEST_FUNCTION_STUB(__restvmx_75); +GUEST_FUNCTION_STUB(__restvmx_76); +GUEST_FUNCTION_STUB(__restvmx_77); +GUEST_FUNCTION_STUB(__restvmx_78); +GUEST_FUNCTION_STUB(__restvmx_79); +GUEST_FUNCTION_STUB(__restvmx_80); +GUEST_FUNCTION_STUB(__restvmx_81); +GUEST_FUNCTION_STUB(__restvmx_82); +GUEST_FUNCTION_STUB(__restvmx_83); +GUEST_FUNCTION_STUB(__restvmx_84); +GUEST_FUNCTION_STUB(__restvmx_85); +GUEST_FUNCTION_STUB(__restvmx_86); +GUEST_FUNCTION_STUB(__restvmx_87); +GUEST_FUNCTION_STUB(__restvmx_88); +GUEST_FUNCTION_STUB(__restvmx_89); +GUEST_FUNCTION_STUB(__restvmx_90); +GUEST_FUNCTION_STUB(__restvmx_91); +GUEST_FUNCTION_STUB(__restvmx_92); +GUEST_FUNCTION_STUB(__restvmx_93); +GUEST_FUNCTION_STUB(__restvmx_94); +GUEST_FUNCTION_STUB(__restvmx_95); +GUEST_FUNCTION_STUB(__restvmx_96); +GUEST_FUNCTION_STUB(__restvmx_97); +GUEST_FUNCTION_STUB(__restvmx_98); +GUEST_FUNCTION_STUB(__restvmx_99); +GUEST_FUNCTION_STUB(__restvmx_100); +GUEST_FUNCTION_STUB(__restvmx_101); +GUEST_FUNCTION_STUB(__restvmx_102); +GUEST_FUNCTION_STUB(__restvmx_103); +GUEST_FUNCTION_STUB(__restvmx_104); +GUEST_FUNCTION_STUB(__restvmx_105); +GUEST_FUNCTION_STUB(__restvmx_106); +GUEST_FUNCTION_STUB(__restvmx_107); +GUEST_FUNCTION_STUB(__restvmx_108); +GUEST_FUNCTION_STUB(__restvmx_109); +GUEST_FUNCTION_STUB(__restvmx_110); +GUEST_FUNCTION_STUB(__restvmx_111); +GUEST_FUNCTION_STUB(__restvmx_112); +GUEST_FUNCTION_STUB(__restvmx_113); +GUEST_FUNCTION_STUB(__restvmx_114); +GUEST_FUNCTION_STUB(__restvmx_115); +GUEST_FUNCTION_STUB(__restvmx_116); +GUEST_FUNCTION_STUB(__restvmx_117); +GUEST_FUNCTION_STUB(__restvmx_118); +GUEST_FUNCTION_STUB(__restvmx_119); +GUEST_FUNCTION_STUB(__restvmx_120); +GUEST_FUNCTION_STUB(__restvmx_121); +GUEST_FUNCTION_STUB(__restvmx_122); +GUEST_FUNCTION_STUB(__restvmx_123); +GUEST_FUNCTION_STUB(__restvmx_124); +GUEST_FUNCTION_STUB(__restvmx_125); +GUEST_FUNCTION_STUB(__restvmx_126); +GUEST_FUNCTION_STUB(__restvmx_127); + +#endif