private unsafe void appUpdateExDetour(context_t *context) { //var deltaTime = context->fpr[1]; //timer -= deltaTime; //if ( timer <= 0d ) //{ // sndManGetBgm.GetWrapper()( context ); // context->r3 = ( ulong )( 0x2290 + ( updateCounter % 10 ) ); // sndManPlayBgm.GetWrapper()( context ); // //Bindings.VirtualMemory.Read( 0xCFF4C4, out int value ); // //value += 1; // //Bindings.VirtualMemory.Write( 0xCFF4C4, ref value ); // timer = 20f; //} ++updateCounter; if (mHandleInput && context->state == 0) { //var tempContext = *context; //tempContext.r3 = ( ulong )( 0x2BC ); //sndManPlayBgm.GetWrapper()( &tempContext ); //context->r3 = 0x2BC; //sndManGetBgm.GetWrapper()( context ); // TODO: maybe try setting the CIA & LR, invalidating the status (non zero) and then calling the function // in the hopes it gets scheduled...? //var tempContext = *context; //context->r3 = 1; //context->r4 = 0; //context->r5 = 0; //context->r6 = 8; //context->cia = 0x10DB4; //seqManTransition.GetWrapper()( context ); //*context = tempContext; var bgm = CallFunction(sndManGetBgm, context); mLogger.WriteLine($"bgm = {bgm:X8}"); CallFunction(sndManPlayBgm, context, (context) => { context.Value->r3 = 0x12C; //ontext.Value->r3 = bgm + 1; }); //CallFunction( seqManTransition, context, ( context ) => // { // context.Value->r3 = 1; // context.Value->r4 = 0; // context.Value->r5 = 0; // context.Value->r6 = 8; // } ); mHandleInput = false; } mAppUpdateExHook.OriginalFunction(context); }
//private ulong CallFunction( PPUFunction function, context_t* context, Action<Ptr<context_t>> setArgsAction = default) //{ // // Save context // var originalContext = *context; // if ( setArgsAction != default ) // setArgsAction( context ); // // Set return address to dummy function address // context->cia = 0; // context->lr = mDummyFunction.VirtualAddress; // IFunction<PPUFunctionDelegate> currentFunction = function; // var currentFunctionAddress = function.VirtualAddress; // while ( true ) // { // // Call function (which may or may not run) // context->cia = 0; // currentFunction.GetWrapper()( context ); // if ( context->cia == currentFunctionAddress ) // { // // Function hasn't actually run (blocked by __check which sets the cia) // } // else if ( context->cia != mDummyFunction.VirtualAddress ) // { // // Function was actually run (not blocked by __check), but still has more functions to execute // // Get next function in call chain // currentFunctionAddress = ( uint )context->lr; // currentFunction = Bindings.PPUFunctions[currentFunctionAddress]; // } // else if ( context->cia == mDummyFunction.VirtualAddress ) // { // // Assume function was actually executed if cia is now the previously set return address // break; // } // else // { // throw new NotImplementedException(); // } // } // // Save return value // var returnValue = context->r3; // // Restore registers // Copy( context, context->gpr, originalContext.gpr ); // return returnValue; //} private ulong CallFunction(PPUFunction function, context_t *context, Action <Ptr <context_t> > setArgsAction = default) { // Save context var originalContext = *context; if (setArgsAction != default) { setArgsAction(context); } context->lr = mDummyFunction.VirtualAddress; var currentFunction = function; while (true) { // Call function (which may or may not run) context->cia = 0; currentFunction.GetWrapper()(context); // Check if our sentinel exit function has been run if (context->cia == 0xDEADBABE) { break; } if (context->lr != mDummyFunction.VirtualAddress) { // Call next function in chain currentFunction = Bindings.PPUFunctions[( uint )context->lr]; } } // Save return value var returnValue = context->r3; // Restore registers Copy(context, context->gpr, originalContext.gpr); return(returnValue); }
private void taskProc_fld_mainDetour(context_t *context) { mTaskProcFldMainHook.OriginalFunction(context); }
private void DummyFunctionDetour(context_t *context) { // Used to keep track of function execution context->cia = 0xDEADBABE; }