#include #include #include "../Daodan.h" #include "Input.h" #include "../Oni/Oni.h" #include "../Daodan_Patch.h" #include "Utility.h" #define EVENT_KEYPRESS_SECURETIME 3 typedef struct { uint32_t key; const char* actionname; ActionEventType_t eventType; uint32_t keydownTimeoutTicks; int64_t lastevent; CustomActionCallback_t callback; CustomActionCallbackArgument callbackArgument; } DD_CustomAction_t; static DD_CustomAction_t customActions[100]; void Input_RegisterCustomAction (const char* actionname, ActionEventType_t eventType, uint32_t keydownTimeoutTicks, CustomActionCallback_t callback, CustomActionCallbackArgument callbackArgument) { uint16_t i = 0; DD_CustomAction_t* cur = customActions; while ( (i < ARRAY_SIZE(customActions)) && (cur->callback != 0)) { cur++; i++; } if (i < ARRAY_SIZE(customActions)) { cur->actionname = actionname; cur->eventType = eventType; cur->keydownTimeoutTicks = keydownTimeoutTicks; cur->callback = callback; cur->callbackArgument = callbackArgument; } else { STARTUPMESSAGE("Registering action %s failed, maximum actions reached", actionname); } } _LIrBinding_Add Oni_LIrBinding_Add = (_LIrBinding_Add)0; uint16_t ONICALL DD_LIrBinding_Add(uint32_t key, const char* name) { DD_CustomAction_t* cur; for (cur = customActions; cur->callback != 0; cur++) { if (!strcmp(name, cur->actionname)) { cur->key = key; return 0; } } return Oni_LIrBinding_Add(key, name); } _LIrActionBuffer_Add Oni_LIrActionBuffer_Add = (_LIrActionBuffer_Add)0; void ONICALL DD_LIrActionBuffer_Add(void* unknown, LItDeviceInput* input) { DD_CustomAction_t* cur; for (cur = customActions; cur->callback != 0; cur++) { if (cur->key == input->input) { int64_t curTime = UUrMachineTime_Sixtieths(); if (cur->eventType == EVENT_KEYPRESS) { if (cur->lastevent + EVENT_KEYPRESS_SECURETIME < curTime) { cur->callback(cur->callbackArgument); } cur->lastevent = curTime; } else if (cur->eventType == EVENT_KEYDOWN) { if (cur->lastevent + cur->keydownTimeoutTicks < curTime) { cur->callback(cur->callbackArgument); cur->lastevent = curTime; } } return; } } Oni_LIrActionBuffer_Add(unknown, input); } void Input_PatchCode () { Oni_LIrBinding_Add = DDrPatch_MakeDetour((void*)LIrBinding_Add, (void*)DD_LIrBinding_Add); Oni_LIrActionBuffer_Add = DDrPatch_MakeDetour((void*)LIrActionBuffer_Add, (void*)DD_LIrActionBuffer_Add); }