2020-06-12 20:51:21 +02:00
|
|
|
#include "hooks_patcher_static.h"
|
2020-04-29 18:02:36 +02:00
|
|
|
#include <wups.h>
|
|
|
|
#include <vpad/input.h>
|
2021-04-07 00:23:23 +02:00
|
|
|
#include <padscore/wpad.h>
|
2020-04-29 18:02:36 +02:00
|
|
|
#include <coreinit/messagequeue.h>
|
|
|
|
#include <coreinit/core.h>
|
2019-02-08 16:42:39 +01:00
|
|
|
|
2021-04-07 00:23:23 +02:00
|
|
|
#include "../utils/ConfigUtils.h"
|
2020-12-26 14:17:50 +01:00
|
|
|
#include "../globals.h"
|
|
|
|
#include "../hooks.h"
|
2019-02-08 16:42:39 +01:00
|
|
|
|
2021-04-07 00:23:23 +02:00
|
|
|
uint8_t vpadPressCooldown = 0xFF;
|
|
|
|
bool configMenuOpened = false;
|
|
|
|
bool wantsToOpenConfigMenu = false;
|
|
|
|
|
|
|
|
DECL_FUNCTION(void, GX2SwapScanBuffers, void) {
|
|
|
|
real_GX2SwapScanBuffers();
|
|
|
|
|
|
|
|
if (wantsToOpenConfigMenu && !configMenuOpened) {
|
|
|
|
configMenuOpened = true;
|
|
|
|
ConfigUtils::openConfigMenu();
|
|
|
|
configMenuOpened = false;
|
|
|
|
wantsToOpenConfigMenu = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
DECL_FUNCTION(void, GX2SetTVBuffer, void *buffer, uint32_t buffer_size, int32_t tv_render_mode, GX2SurfaceFormat format, GX2BufferingMode buffering_mode) {
|
|
|
|
storedTVBuffer.buffer = buffer;
|
|
|
|
storedTVBuffer.buffer_size = buffer_size;
|
|
|
|
storedTVBuffer.mode = tv_render_mode;
|
|
|
|
storedTVBuffer.surface_format = format;
|
|
|
|
storedTVBuffer.buffering_mode = buffering_mode;
|
|
|
|
|
|
|
|
return real_GX2SetTVBuffer(buffer,buffer_size,tv_render_mode,format,buffering_mode);
|
|
|
|
}
|
|
|
|
|
|
|
|
DECL_FUNCTION(void, GX2SetDRCBuffer, void *buffer, uint32_t buffer_size, uint32_t drc_mode, GX2SurfaceFormat surface_format, GX2BufferingMode buffering_mode) {
|
|
|
|
storedDRCBuffer.buffer = buffer;
|
|
|
|
storedDRCBuffer.buffer_size = buffer_size;
|
|
|
|
storedDRCBuffer.mode = drc_mode;
|
|
|
|
storedDRCBuffer.surface_format = surface_format;
|
|
|
|
storedDRCBuffer.buffering_mode = buffering_mode;
|
|
|
|
|
|
|
|
return real_GX2SetDRCBuffer(buffer,buffer_size,drc_mode,surface_format,buffering_mode);
|
2019-02-08 16:42:39 +01:00
|
|
|
}
|
|
|
|
|
2019-11-16 15:12:30 +01:00
|
|
|
static uint32_t lastData0 = 0;
|
2020-06-12 20:51:21 +02:00
|
|
|
DECL_FUNCTION(uint32_t, OSReceiveMessage, OSMessageQueue *queue, OSMessage *message, uint32_t flags) {
|
2020-05-03 12:30:15 +02:00
|
|
|
int32_t res = real_OSReceiveMessage(queue, message, flags);
|
|
|
|
if (queue == OSGetSystemMessageQueue()) {
|
2020-12-26 14:17:50 +01:00
|
|
|
if (message != nullptr && res) {
|
2020-05-03 12:30:15 +02:00
|
|
|
if (lastData0 != message->args[0]) {
|
|
|
|
if (message->args[0] == 0xFACEF000) {
|
2020-04-29 18:02:36 +02:00
|
|
|
CallHook(gPluginInformation, WUPS_LOADER_HOOK_ACQUIRED_FOREGROUND);
|
2020-05-03 12:30:15 +02:00
|
|
|
} else if (message->args[0] == 0xD1E0D1E0) {
|
2020-12-28 14:38:08 +01:00
|
|
|
// Implemented via WUMS Hook
|
2019-11-16 15:12:30 +01:00
|
|
|
}
|
|
|
|
}
|
2020-04-29 18:02:36 +02:00
|
|
|
lastData0 = message->args[0];
|
2019-11-16 15:12:30 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2020-06-12 20:51:21 +02:00
|
|
|
DECL_FUNCTION(void, OSReleaseForeground) {
|
2020-05-03 12:30:15 +02:00
|
|
|
if (OSGetCoreId() == 1) {
|
2020-04-29 18:02:36 +02:00
|
|
|
CallHook(gPluginInformation, WUPS_LOADER_HOOK_RELEASE_FOREGROUND);
|
2019-11-16 15:12:30 +01:00
|
|
|
}
|
|
|
|
real_OSReleaseForeground();
|
|
|
|
}
|
|
|
|
|
2021-04-07 00:23:23 +02:00
|
|
|
DECL_FUNCTION(int32_t, VPADRead, int32_t chan, VPADStatus *buffer, uint32_t buffer_size, int32_t *error) {
|
|
|
|
int32_t result = real_VPADRead(chan, buffer, buffer_size, error);
|
|
|
|
|
|
|
|
if (result > 0 && (buffer[0].hold == (VPAD_BUTTON_L | VPAD_BUTTON_DOWN | VPAD_BUTTON_MINUS)) && vpadPressCooldown == 0 && !configMenuOpened) {
|
|
|
|
wantsToOpenConfigMenu = true;
|
|
|
|
vpadPressCooldown = 0x3C;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (vpadPressCooldown > 0) {
|
|
|
|
vpadPressCooldown--;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
DECL_FUNCTION(void, WPADRead, WPADChan chan, WPADStatusProController *data) {
|
|
|
|
real_WPADRead(chan, data);
|
|
|
|
|
|
|
|
if (!configMenuOpened && data[0].err == 0) {
|
|
|
|
if (data[0].extensionType == WPAD_EXT_CORE || data[0].extensionType == WPAD_EXT_NUNCHUK) {
|
|
|
|
// button data is in the first 2 bytes for wiimotes
|
|
|
|
if (((uint16_t*)data)[0] == (WPAD_BUTTON_B | WPAD_BUTTON_DOWN | WPAD_BUTTON_MINUS)) {
|
|
|
|
wantsToOpenConfigMenu = true;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// TODO does this work for classic controllers?
|
|
|
|
if (data[0].buttons == (WPAD_CLASSIC_BUTTON_L | WPAD_CLASSIC_BUTTON_DOWN | WPAD_CLASSIC_BUTTON_MINUS)) {
|
|
|
|
wantsToOpenConfigMenu = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-12 20:51:21 +02:00
|
|
|
function_replacement_data_t method_hooks_hooks_static[] __attribute__((section(".data"))) = {
|
2021-04-07 00:23:23 +02:00
|
|
|
REPLACE_FUNCTION(GX2SwapScanBuffers, LIBRARY_GX2, GX2SwapScanBuffers),
|
|
|
|
REPLACE_FUNCTION(GX2SetTVBuffer, LIBRARY_GX2, GX2SetTVBuffer),
|
|
|
|
REPLACE_FUNCTION(GX2SetDRCBuffer, LIBRARY_GX2, GX2SetDRCBuffer),
|
|
|
|
REPLACE_FUNCTION(OSReceiveMessage, LIBRARY_COREINIT, OSReceiveMessage),
|
|
|
|
REPLACE_FUNCTION(OSReleaseForeground, LIBRARY_COREINIT, OSReleaseForeground),
|
|
|
|
REPLACE_FUNCTION(VPADRead, LIBRARY_VPAD, VPADRead),
|
|
|
|
REPLACE_FUNCTION(WPADRead, LIBRARY_PADSCORE, WPADRead),
|
2019-02-08 16:42:39 +01:00
|
|
|
};
|
|
|
|
|
2020-06-12 20:51:21 +02:00
|
|
|
uint32_t method_hooks_size_hooks_static __attribute__((section(".data"))) = sizeof(method_hooks_hooks_static) / sizeof(function_replacement_data_t);
|