void OSSleepTicks(Time ticks) { if (1) { OSTestThreadCancel(); gLog->warn("Ignoring unimplemented OSSleepTicks"); return; } auto thread = OSGetCurrentThread(); OSLockScheduler(); // Create the alarm user data auto data = OSAllocFromSystem<SleepAlarmData>(); data->thread = thread; // Create an alarm to trigger wakeup auto alarm = OSAllocFromSystem<OSAlarm>(); OSCreateAlarm(alarm); OSSetAlarmUserData(alarm, data); OSSetAlarm(alarm, ticks, pSleepAlarmHandler); // Sleep thread OSSleepThreadNoLock(nullptr); OSRescheduleNoLock(); OSFreeToSystem(data); OSFreeToSystem(alarm); OSUnlockScheduler(); }
void CoreFreeDefaultHeap() { // Delete all base heaps for (auto i = 0u; i < static_cast<size_t>(BaseHeapType::Max); ++i) { if (gMemArenas[i]) { auto heap = reinterpret_cast<CommonHeap*>(gMemArenas[i]); switch (heap->tag) { case HeapType::ExpandedHeap: MEMDestroyExpHeap(reinterpret_cast<ExpandedHeap*>(heap)); break; case HeapType::FrameHeap: MEMDestroyFrmHeap(reinterpret_cast<FrameHeap*>(heap)); break; case HeapType::UnitHeap: case HeapType::UserHeap: case HeapType::BlockHeap: default: assert(false); } gMemArenas[i] = nullptr; } } // Delete system heap MEMDestroyExpHeap(gSystemHeap); gSystemHeap = nullptr; // Free function pointers if (pMEMAllocFromDefaultHeap) { OSFreeToSystem(pMEMAllocFromDefaultHeap); pMEMAllocFromDefaultHeap = nullptr; } if (pMEMAllocFromDefaultHeapEx) { OSFreeToSystem(pMEMAllocFromDefaultHeap); pMEMAllocFromDefaultHeap = nullptr; } if (pMEMFreeToDefaultHeap) { OSFreeToSystem(pMEMAllocFromDefaultHeap); pMEMAllocFromDefaultHeap = nullptr; } }
/** * Wait for an event value to be TRUE with a timeout * * Behaves the same than OSWaitEvent but with a timeout. * * Returns TRUE if the event was signalled, FALSE if wait timed out. */ BOOL OSWaitEventWithTimeout(OSEvent *event, OSTime timeout) { BOOL result = TRUE; OSLockScheduler(); // Check if event is already set if (event->value) { if (event->mode == OSEventMode::AutoReset) { // Reset event event->value = FALSE; } OSUnlockScheduler(); return TRUE; } // Setup some alarm data for callback auto data = OSAllocFromSystem<EventAlarmData>(); data->event = event; data->thread = OSGetCurrentThread(); data->timeout = FALSE; // Create an alarm to trigger timeout auto alarm = OSAllocFromSystem<OSAlarm>(); OSCreateAlarm(alarm); OSSetAlarmUserData(alarm, data); OSSetAlarm(alarm, timeout, pEventAlarmHandler); // Wait for the event OSSleepThreadNoLock(&event->queue); OSRescheduleNoLock(); if (data->timeout) { // Timed out, remove from wait queue OSEraseFromThreadQueue(&event->queue, data->thread); result = FALSE; } OSFreeToSystem(data); OSFreeToSystem(alarm); OSUnlockScheduler(); return result; }
static void zlibFreeWrapper(void *opaque, void *address) { auto wstrm = reinterpret_cast<WZStream *>(opaque); ZlibFreeFunc freeFunc = static_cast<uint32_t>(wstrm->zfree); if (freeFunc) { freeFunc(wstrm->opaque, address); } else { OSFreeToSystem(address); } }
void OSSleepTicks(OSTime ticks) { auto thread = OSGetCurrentThread(); OSLockScheduler(); // Create the alarm user data auto data = OSAllocFromSystem<SleepAlarmData>(); data->thread = thread; // Create an alarm to trigger wakeup auto alarm = OSAllocFromSystem<OSAlarm>(); OSCreateAlarm(alarm); OSSetAlarmUserData(alarm, data); OSSetAlarm(alarm, ticks, pSleepAlarmHandler); // Sleep thread OSSleepThreadNoLock(nullptr); OSRescheduleNoLock(); OSFreeToSystem(data); OSFreeToSystem(alarm); OSUnlockScheduler(); }
void _main() { /****************************> Fix Stack <****************************/ //Load a good stack asm( "lis %r1, 0x1ab5 ;" "ori %r1, %r1, 0xd138 ;" ); /****************************> Get Handles <****************************/ //Get a handle to coreinit.rpl unsigned int coreinit_handle, vpad_handle, sysapp_handle, avm_handle; OSDynLoad_Acquire("coreinit.rpl", &coreinit_handle); OSDynLoad_Acquire("vpad.rpl", &vpad_handle); OSDynLoad_Acquire("sysapp.rpl", &sysapp_handle); // CreeperMario: Get a handle to the audio/video manager - avm.rpl OSDynLoad_Acquire("avm.rpl", &avm_handle); // STUFF VPADData vpad_data; int(*VPADRead)(int controller, VPADData *buffer, unsigned int num, int *err); OSDynLoad_FindExport(vpad_handle, 0, "VPADRead", &VPADRead); // Sysapp stuff int(*SYSLaunchMenu)(); OSDynLoad_FindExport(sysapp_handle, 0, "SYSLaunchMenu", &SYSLaunchMenu); // please dont break stuff... int(*SYSLaunchTitle) (int bit1, int bit2); OSDynLoad_FindExport(sysapp_handle, 0, "SYSLaunchTitle", &SYSLaunchTitle); int(*_Exit)(); OSDynLoad_FindExport(coreinit_handle, 0, "_Exit", &_Exit); /****************************> External Prototypes <****************************/ //OSScreen functions void(*OSScreenInit)(); unsigned int(*OSScreenGetBufferSizeEx)(unsigned int bufferNum); unsigned int(*OSScreenSetBufferEx)(unsigned int bufferNum, void * addr); //OS Memory functions void*(*memset)(void * dest, uint32_t value, uint32_t bytes); void*(*OSAllocFromSystem)(uint32_t size, int align); void(*OSFreeToSystem)(void *ptr); //IM functions int(*IM_Open)(); int(*IM_Close)(int fd); int(*IM_SetDeviceState)(int fd, void *mem, int state, int a, int b); // CreeperMario: TV Screen scaling functions bool(*AVMSetTVScale)(int width, int height); /****************************> Exports <****************************/ //OSScreen functions OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenInit", &OSScreenInit); OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenGetBufferSizeEx", &OSScreenGetBufferSizeEx); OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenSetBufferEx", &OSScreenSetBufferEx); //OS Memory functions OSDynLoad_FindExport(coreinit_handle, 0, "memset", &memset); OSDynLoad_FindExport(coreinit_handle, 0, "OSAllocFromSystem", &OSAllocFromSystem); OSDynLoad_FindExport(coreinit_handle, 0, "OSFreeToSystem", &OSFreeToSystem); //IM functions OSDynLoad_FindExport(coreinit_handle, 0, "IM_Open", &IM_Open); OSDynLoad_FindExport(coreinit_handle, 0, "IM_Close", &IM_Close); OSDynLoad_FindExport(coreinit_handle, 0, "IM_SetDeviceState", &IM_SetDeviceState); // CreeperMario: TV Screen scaling functions OSDynLoad_FindExport(avm_handle, 0, "AVMSetTVScale", &AVMSetTVScale); /*** CreeperMario: Set the TV screen to the proper 'scale factor'. ***/ AVMSetTVScale(854, 480); /****************************> Initial Setup <****************************/ //Restart system to get lib access int fd = IM_Open(); void *mem = OSAllocFromSystem(0x100, 64); memset(mem, 0, 0x100); //set restart flag to force quit browser IM_SetDeviceState(fd, mem, 3, 0, 0); IM_Close(fd); OSFreeToSystem(mem); //wait a bit for browser end unsigned int t1 = 0x15000000; while(t1--) ; //Call the Screen initilzation function. OSScreenInit(); //Grab the buffer size for each screen (TV and gamepad) int buf0_size = OSScreenGetBufferSizeEx(0); int buf1_size = OSScreenGetBufferSizeEx(1); //Set the buffer area. OSScreenSetBufferEx(0, (void *)0xF4000000); OSScreenSetBufferEx(1, (void *)0xF4000000 + buf0_size); //Clear both framebuffers. doclearstuff(); // Define struct for global variables! struct cGlobals caveGlobals; // Variables n stuff! caveGlobals.food = 0; caveGlobals.row = 1; caveGlobals.col = 1; caveGlobals.level = 1; caveGlobals.dogsteps = 0; caveGlobals.dogalive = 1; caveGlobals.mysteps = 0; caveGlobals.maxhealth = 10; caveGlobals.curhealth = 10; // Start at level 1 (obviously!) changelevel(&caveGlobals); // Draw Buffers and Initial Screen __os_snprintf(caveGlobals.mystat, 64, " "); doclearstuff(); drawstuff(&caveGlobals); flipBuffers(); int err; while(1) { VPADRead(0, &vpad_data, 1, &err); // Quit if (vpad_data.btn_trigger & BUTTON_HOME) { doclearstuff(); __os_snprintf(caveGlobals.endgame, 256, "Thanks for Playing!\nYour Final Level: %d \n\n\nBy: SonyUSA", caveGlobals.level); drawString(0, 0, caveGlobals.endgame); flipBuffers(); t1 = 0x50000000; while(t1--) ; //Maybe fix for exit crash? doclearstuff(); flipBuffers(); doclearstuff(); flipBuffers(); //Ape escape! SYSLaunchMenu(); _Exit(); } //Grab Stuff (A) if (vpad_data.btn_release & BUTTON_A) { //Checks for Food if (caveGlobals.nMapArray[caveGlobals.col][caveGlobals.row] == 8) { doclearstuff(); __os_snprintf(caveGlobals.mystat, 64, "Got it!"); drawString(25, 17, caveGlobals.mystat); caveGlobals.food += 1; caveGlobals.nMapArray[caveGlobals.col][caveGlobals.row] = 2; drawstuff(&caveGlobals); flipBuffers(); } //Check for Potions if (caveGlobals.nMapArray[caveGlobals.col][caveGlobals.row] == 11) { doclearstuff(); __os_snprintf(caveGlobals.mystat, 64, "*Gulp!*"); drawString(25, 17, caveGlobals.mystat); caveGlobals.curhealth += 5; caveGlobals.nMapArray[caveGlobals.col][caveGlobals.row] = 2; //Make sure we don't go over health limit if (caveGlobals.curhealth > caveGlobals.maxhealth) { caveGlobals.curhealth = caveGlobals.maxhealth; } drawstuff(&caveGlobals); dog(&caveGlobals); flipBuffers(); } //Checks for Stairs if (caveGlobals.nMapArray[caveGlobals.col][caveGlobals.row] == 9) { caveGlobals.level += 1; doclearstuff(); changelevel(&caveGlobals); drawstuff(&caveGlobals); flipBuffers(); } } //Search for Hidden Traps and Doors if (vpad_data.btn_trigger & BUTTON_Y) { doclearstuff(); drawstuff(&caveGlobals); dog(&caveGlobals); //Ask the player which way to search __os_snprintf(caveGlobals.mystat, 64, "Search Which Way?"); drawString(22, 17, caveGlobals.mystat); flipBuffers(); //Lets use a while loop so players cant just hold down search while they are walking! Cheating gits! while(2) { VPADRead(0, &vpad_data, 1, &err); // Search Up if (vpad_data.btn_release & BUTTON_UP) { // Traps if (ishtrap(&caveGlobals, caveGlobals.row, caveGlobals.col -1 ) == true ) { doclearstuff(); __os_snprintf(caveGlobals.mystat, 64, "It's a trap!"); drawString(25, 17, caveGlobals.mystat); caveGlobals.nMapArray[caveGlobals.col -1][caveGlobals.row] = 6; drawstuff(&caveGlobals); flipBuffers(); break; } // Doors if (ishdoor(&caveGlobals, caveGlobals.row, caveGlobals.col -1 ) == true ) { doclearstuff(); __os_snprintf(caveGlobals.mystat, 64, "A Secret Door!"); drawString(22, 17, caveGlobals.mystat); caveGlobals.nMapArray[caveGlobals.col -1][caveGlobals.row] = 4; drawstuff(&caveGlobals); flipBuffers(); break; } // If nothing is found... doclearstuff(); drawstuff(&caveGlobals); __os_snprintf(caveGlobals.mystat, 64, "Nothing There!"); drawString(23, 17, caveGlobals.mystat); flipBuffers(); break; } // Search Down if (vpad_data.btn_release & BUTTON_DOWN) { // Traps if (ishtrap(&caveGlobals, caveGlobals.row, caveGlobals.col +1 ) == true ) { doclearstuff(); __os_snprintf(caveGlobals.mystat, 64, "It's a trap!"); drawString(25, 17, caveGlobals.mystat); caveGlobals.nMapArray[caveGlobals.col +1][caveGlobals.row] = 6; drawstuff(&caveGlobals); flipBuffers(); break; } // Doors if (ishdoor(&caveGlobals, caveGlobals.row, caveGlobals.col +1 ) == true ) { doclearstuff(); __os_snprintf(caveGlobals.mystat, 64, "A Secret Door!"); drawString(22, 17, caveGlobals.mystat); caveGlobals.nMapArray[caveGlobals.col +1][caveGlobals.row] = 4; drawstuff(&caveGlobals); flipBuffers(); break; } // If nothing is found... doclearstuff(); drawstuff(&caveGlobals); __os_snprintf(caveGlobals.mystat, 64, "Nothing There!"); drawString(23, 17, caveGlobals.mystat); flipBuffers(); break; } // Search Right if (vpad_data.btn_release & BUTTON_RIGHT) { // Traps if (ishtrap(&caveGlobals, caveGlobals.row +1 , caveGlobals.col ) == true ) { doclearstuff(); __os_snprintf(caveGlobals.mystat, 64, "It's a trap!"); drawString(25, 17, caveGlobals.mystat); caveGlobals.nMapArray[caveGlobals.col][caveGlobals.row +1] = 6; drawstuff(&caveGlobals); flipBuffers(); break; } // Doors if (ishdoor(&caveGlobals, caveGlobals.row +1 , caveGlobals.col ) == true ) { doclearstuff(); __os_snprintf(caveGlobals.mystat, 64, "A Secret Door!"); drawString(22, 17, caveGlobals.mystat); caveGlobals.nMapArray[caveGlobals.col][caveGlobals.row +1] = 4; drawstuff(&caveGlobals); flipBuffers(); break; } // If nothing is found... doclearstuff(); drawstuff(&caveGlobals); __os_snprintf(caveGlobals.mystat, 64, "Nothing There!"); drawString(23, 17, caveGlobals.mystat); flipBuffers(); break; } // Search Left if (vpad_data.btn_release & BUTTON_LEFT) { // Traps if (ishtrap(&caveGlobals, caveGlobals.row -1 , caveGlobals.col ) == true ) { doclearstuff(); __os_snprintf(caveGlobals.mystat, 64, "It's a trap!"); drawString(25, 17, caveGlobals.mystat); caveGlobals.nMapArray[caveGlobals.col][caveGlobals.row -1] = 6; drawstuff(&caveGlobals); flipBuffers(); break; } // Doors if (ishdoor(&caveGlobals, caveGlobals.row -1 , caveGlobals.col ) == true ) { doclearstuff(); __os_snprintf(caveGlobals.mystat, 64, "A Secret Door!"); drawString(22, 17, caveGlobals.mystat); caveGlobals.nMapArray[caveGlobals.col][caveGlobals.row -1] = 4; drawstuff(&caveGlobals); flipBuffers(); break; } // If nothing is found... doclearstuff(); drawstuff(&caveGlobals); __os_snprintf(caveGlobals.mystat, 64, "Nothing There!"); drawString(23, 17, caveGlobals.mystat); flipBuffers(); break; } } } //Open and Close Doors (X + Direction) if (vpad_data.btn_hold & BUTTON_X) { if (vpad_data.btn_trigger & BUTTON_DOWN) { if (isclosedoor(&caveGlobals, caveGlobals.row, caveGlobals.col +1 ) == true ) { doclearstuff(); drawstuff(&caveGlobals); caveGlobals.nMapArray[caveGlobals.col +1][caveGlobals.row] = 5; flipBuffers(); } else if (isopendoor(&caveGlobals, caveGlobals.row, caveGlobals.col +1 ) == true ) { doclearstuff(); drawstuff(&caveGlobals); caveGlobals.nMapArray[caveGlobals.col +1][caveGlobals.row] = 4; flipBuffers(); } } if (vpad_data.btn_trigger & BUTTON_UP) { if (isclosedoor(&caveGlobals, caveGlobals.row, caveGlobals.col -1 ) == true ) { doclearstuff(); drawstuff(&caveGlobals); caveGlobals.nMapArray[caveGlobals.col -1][caveGlobals.row] = 5; flipBuffers(); } else if (isopendoor(&caveGlobals, caveGlobals.row, caveGlobals.col -1 ) == true ) { doclearstuff(); drawstuff(&caveGlobals); caveGlobals.nMapArray[caveGlobals.col -1][caveGlobals.row] = 4; flipBuffers(); } } if (vpad_data.btn_trigger & BUTTON_LEFT) { if (isclosedoor(&caveGlobals, caveGlobals.row -1 , caveGlobals.col ) == true ) { doclearstuff(); drawstuff(&caveGlobals); caveGlobals.nMapArray[caveGlobals.col][caveGlobals.row -1] = 5; flipBuffers(); } else if (isopendoor(&caveGlobals, caveGlobals.row -1 , caveGlobals.col ) == true ) { doclearstuff(); drawstuff(&caveGlobals); caveGlobals.nMapArray[caveGlobals.col][caveGlobals.row -1] = 4; flipBuffers(); } } if (vpad_data.btn_trigger & BUTTON_RIGHT) { if (isclosedoor(&caveGlobals, caveGlobals.row +1 , caveGlobals.col ) == true ) { doclearstuff(); drawstuff(&caveGlobals); caveGlobals.nMapArray[caveGlobals.col][caveGlobals.row +1] = 5; flipBuffers(); } else if (isopendoor(&caveGlobals, caveGlobals.row +1 , caveGlobals.col ) == true ) { doclearstuff(); drawstuff(&caveGlobals); caveGlobals.nMapArray[caveGlobals.col][caveGlobals.row +1] = 4; flipBuffers(); } } } // Movement //Down if (vpad_data.btn_trigger & BUTTON_DOWN) { if (canmove(&caveGlobals, caveGlobals.row, caveGlobals.col +1 ) == true ) { doclearstuff(); dog(&caveGlobals); caveGlobals.col += 1; drawstuff(&caveGlobals); if (istrap(&caveGlobals, caveGlobals.row, caveGlobals.col ) == true ) { __os_snprintf(caveGlobals.mystat, 64, "Ouch!"); drawString(25, 17, caveGlobals.mystat); caveGlobals.curhealth -= 1; } if (ishtrap(&caveGlobals, caveGlobals.row, caveGlobals.col ) == true ) { __os_snprintf(caveGlobals.mystat, 64, "Ouch!"); drawString(25, 17, caveGlobals.mystat); caveGlobals.curhealth -= 1; caveGlobals.nMapArray[caveGlobals.col][caveGlobals.row] = 6; } flipBuffers(); } } //Up if (vpad_data.btn_trigger & BUTTON_UP) { if (canmove(&caveGlobals, caveGlobals.row, caveGlobals.col -1 ) == true ) { doclearstuff(); dog(&caveGlobals); caveGlobals.col -= 1; drawstuff(&caveGlobals); if (istrap(&caveGlobals, caveGlobals.row, caveGlobals.col ) == true ) { __os_snprintf(caveGlobals.mystat, 64, "Ouch!"); drawString(25, 17, caveGlobals.mystat); caveGlobals.curhealth -= 1; } if (ishtrap(&caveGlobals, caveGlobals.row, caveGlobals.col ) == true ) { __os_snprintf(caveGlobals.mystat, 64, "Ouch!"); drawString(25, 17, caveGlobals.mystat); caveGlobals.curhealth -= 1; caveGlobals.nMapArray[caveGlobals.col][caveGlobals.row] = 6; } flipBuffers(); } } //Left if (vpad_data.btn_trigger & BUTTON_LEFT) { if (canmove(&caveGlobals, caveGlobals.row -1 , caveGlobals.col ) == true ) { doclearstuff(); dog(&caveGlobals); caveGlobals.row -= 1; drawstuff(&caveGlobals); if (istrap(&caveGlobals, caveGlobals.row, caveGlobals.col ) == true ) { __os_snprintf(caveGlobals.mystat, 64, "Ouch!"); drawString(25, 17, caveGlobals.mystat); caveGlobals.curhealth -= 1; } if (ishtrap(&caveGlobals, caveGlobals.row, caveGlobals.col ) == true ) { __os_snprintf(caveGlobals.mystat, 64, "Ouch!"); drawString(25, 17, caveGlobals.mystat); caveGlobals.curhealth -= 1; caveGlobals.nMapArray[caveGlobals.col][caveGlobals.row] = 6; } flipBuffers(); } } //Right if (vpad_data.btn_trigger & BUTTON_RIGHT) { if (canmove(&caveGlobals, caveGlobals.row +1 , caveGlobals.col ) == true ) { doclearstuff(); dog(&caveGlobals); caveGlobals.row += 1; drawstuff(&caveGlobals); if (istrap(&caveGlobals, caveGlobals.row, caveGlobals.col ) == true ) { __os_snprintf(caveGlobals.mystat, 64, "Ouch!"); drawString(25, 17, caveGlobals.mystat); caveGlobals.curhealth -= 1; } if (ishtrap(&caveGlobals, caveGlobals.row, caveGlobals.col ) == true ) { __os_snprintf(caveGlobals.mystat, 64, "Ouch!"); drawString(25, 17, caveGlobals.mystat); caveGlobals.curhealth -= 1; caveGlobals.nMapArray[caveGlobals.col][caveGlobals.row] = 6; } flipBuffers(); } } //Feed the doggy if (vpad_data.btn_trigger & BUTTON_PLUS) { if (caveGlobals.dogalive == 1) { if (caveGlobals.food >= 1) { doclearstuff(); __os_snprintf(caveGlobals.mystat, 64, "*crunch* Woof!"); drawString(24, 17, caveGlobals.mystat); caveGlobals.food -= 1; caveGlobals.dogsteps -= 60; //Make sure we don't go negative in dog health if (caveGlobals.dogsteps <= 0) { caveGlobals.dogsteps = 0;} drawstuff(&caveGlobals); dog(&caveGlobals); flipBuffers(); } } } // Check if the player is dead if(caveGlobals.curhealth == 0) { doclearstuff(); __os_snprintf(caveGlobals.endgame, 256, "You're Dead!\nNow how will you get iosu? :/ \n\nThanks for Playing! \n\n\nBy: SonyUSA"); drawString(0, 0, caveGlobals.endgame); flipBuffers(); t1 = 0x80000000; while(t1--) ; SYSLaunchMenu(); _Exit(); } // Cheat and go to next level with Minus key if(vpad_data.btn_release & BUTTON_MINUS) { caveGlobals.level += 1; doclearstuff(); changelevel(&caveGlobals); drawstuff(&caveGlobals); flipBuffers(); } } }
void _start() { /****************************> Fix Stack <****************************/ //Load a good stack asm( "lis %r1, 0x1ab5 ;" "ori %r1, %r1, 0xd138 ;" ); /****************************> Get Handles <****************************/ //Get a handle to coreinit.rpl unsigned int coreinit_handle, avm_handle; OSDynLoad_Acquire("coreinit.rpl", &coreinit_handle); // CreeperMario: Get a handle to the audio/video manager - avm.rpl OSDynLoad_Acquire("avm.rpl", &avm_handle); /****************************> External Prototypes <****************************/ //OSScreen functions void(*OSScreenInit)(); unsigned int(*OSScreenGetBufferSizeEx)(unsigned int bufferNum); unsigned int(*OSScreenSetBufferEx)(unsigned int bufferNum, void * addr); //OS Memory functions void*(*memset)(void * dest, uint32_t value, uint32_t bytes); void*(*OSAllocFromSystem)(uint32_t size, int align); void(*OSFreeToSystem)(void *ptr); //IM functions int(*IM_Open)(); int(*IM_Close)(int fd); int(*IM_SetDeviceState)(int fd, void *mem, int state, int a, int b); // CreeperMario: Audio/Video manager functions bool(*AVMSetTVScale)(int width, int height); /****************************> Exports <****************************/ //OSScreen functions OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenInit", &OSScreenInit); OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenGetBufferSizeEx", &OSScreenGetBufferSizeEx); OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenSetBufferEx", &OSScreenSetBufferEx); //OS Memory functions OSDynLoad_FindExport(coreinit_handle, 0, "memset", &memset); OSDynLoad_FindExport(coreinit_handle, 0, "OSAllocFromSystem", &OSAllocFromSystem); OSDynLoad_FindExport(coreinit_handle, 0, "OSFreeToSystem", &OSFreeToSystem); //IM functions OSDynLoad_FindExport(coreinit_handle, 0, "IM_Open", &IM_Open); OSDynLoad_FindExport(coreinit_handle, 0, "IM_Close", &IM_Close); OSDynLoad_FindExport(coreinit_handle, 0, "IM_SetDeviceState", &IM_SetDeviceState); // CreeperMario: Audio/Video manager functions OSDynLoad_FindExport(avm_handle, 0, "AVMSetTVScale", &AVMSetTVScale); /*** CreeperMario: Set the TV Screen's 'scale factor'. ***/ AVMSetTVScale(854, 480); /****************************> Initial Setup <****************************/ //Restart system to get lib access int fd = IM_Open(); void *mem = OSAllocFromSystem(0x100, 64); memset(mem, 0, 0x100); //set restart flag to force quit browser IM_SetDeviceState(fd, mem, 3, 0, 0); IM_Close(fd); OSFreeToSystem(mem); //wait a bit for browser end unsigned int t1 = 0x1FFFFFFF; while(t1--) ; //Call the Screen initilzation function. OSScreenInit(); //Grab the buffer size for each screen (TV and gamepad) int buf0_size = OSScreenGetBufferSizeEx(0); int buf1_size = OSScreenGetBufferSizeEx(1); //Set the buffer area. OSScreenSetBufferEx(0, (void *)0xF4000000); OSScreenSetBufferEx(1, (void *)0xF4000000 + buf0_size); //Clear both framebuffers. // I don't do this here, and do it at the start of entry point to use my services struct // int ii = 0; // for (ii; ii < 2; ii++) // { // fillScreen(0,0,0,0); // flipBuffers(); // } //Jump to entry point. _entryPoint(); }
void _start() { /* Get a handle to coreinit.rpl */ unsigned int coreinit_handle; OSDynLoad_Acquire("coreinit.rpl", &coreinit_handle); //OS memory functions void* (*memcpy)(void *dest, void *src, uint32_t length); void* (*memset)(void * dest, uint32_t value, uint32_t bytes); void* (*OSAllocFromSystem)(uint32_t size, int align); void (*OSFreeToSystem)(void *ptr); OSDynLoad_FindExport(coreinit_handle, 0, "memcpy", &memcpy); OSDynLoad_FindExport(coreinit_handle, 0, "memset", &memset); OSDynLoad_FindExport(coreinit_handle, 0, "OSAllocFromSystem", &OSAllocFromSystem); OSDynLoad_FindExport(coreinit_handle, 0, "OSFreeToSystem", &OSFreeToSystem); void (*OSCoherencyBarrier)(); OSDynLoad_FindExport(coreinit_handle, 0, "OSCoherencyBarrier", &OSCoherencyBarrier); void (*_Exit)(); OSDynLoad_FindExport(coreinit_handle, 0, "_Exit", &_Exit); //DC memory functions void (*DCFlushRangeNoSync)(void *buffer, uint32_t length); void (*DCInvalidateRange)(void *buffer, uint32_t length); OSDynLoad_FindExport(coreinit_handle, 0, "DCFlushRangeNoSync", &DCFlushRangeNoSync); OSDynLoad_FindExport(coreinit_handle, 0, "DCInvalidateRange", &DCInvalidateRange); //LC memory functions void* (*LCAlloc)( uint32_t bytes ); void (*LCDealloc)(); uint32_t (*LCHardwareIsAvailable)(); uint32_t (*LCIsDMAEnabled)(); void (*LCEnableDMA)(); void (*LCDisableDMA)(); void (*LCLoadDMABlocks)(void* lc_addr, void* src_addr, uint32_t blocks); void (*LCStoreDMABlocks)(void* dest_addr, void* lc_addr, uint32_t blocks); void (*LCWaitDMAQueue)( uint32_t length ); OSDynLoad_FindExport(coreinit_handle, 0, "LCAlloc", &LCAlloc); OSDynLoad_FindExport(coreinit_handle, 0, "LCDealloc", &LCDealloc); OSDynLoad_FindExport(coreinit_handle, 0, "LCHardwareIsAvailable", &LCHardwareIsAvailable); OSDynLoad_FindExport(coreinit_handle, 0, "LCIsDMAEnabled", &LCIsDMAEnabled); OSDynLoad_FindExport(coreinit_handle, 0, "LCEnableDMA", &LCEnableDMA); OSDynLoad_FindExport(coreinit_handle, 0, "LCDisableDMA", &LCDisableDMA); OSDynLoad_FindExport(coreinit_handle, 0, "LCLoadDMABlocks", &LCLoadDMABlocks); OSDynLoad_FindExport(coreinit_handle, 0, "LCStoreDMABlocks", &LCStoreDMABlocks); OSDynLoad_FindExport(coreinit_handle, 0, "LCWaitDMAQueue", &LCWaitDMAQueue); //Used for keeping track of vairables to print to screen char output[1000]; //Alloc 64 byte alligned space void* src_addr=OSAllocFromSystem(512,64); void* dest_addr=OSAllocFromSystem(512,64); //Store some debug values __os_snprintf(output, 1000, "src_addr:%02x,",(uint32_t)src_addr); __os_snprintf(output+strlen(output), 255, "dest_addr: %02x,", (uint32_t)dest_addr); //Number of 32bit blocks to copy. Must be multiple of 2 between [0,127] uint32_t blocks=2; //2 32bit blocks //Do something to the source memset(src_addr,1,64); //Grab values for debug uint32_t * src_val=src_addr; uint32_t * dest_val=dest_addr; __os_snprintf(output+strlen(output), 255, "Old src_val: %02x\n",src_val[0]); __os_snprintf(output+strlen(output), 255, "Old dest_val: %02x,",dest_val[0]); //Get some locked cache address space void *lc_addr=LCAlloc(512); //512 Minmum. Must be multiple of 512. //Calculate size from blocks to flush/invalidate range properly uint32_t size; //If blocks is set to 0, the transaction will default to 128 blocks if(blocks==0) { size=32*128; } else { size=32*blocks; } //Flush the range at the source to ensure cache gets written back to memory. DCFlushRangeNoSync(src_addr,size); //Invalidate the range at the destination DCInvalidateRange(dest_addr,size); //Sync OSCoherencyBarrier(); //Check to see of DMA hardware is avaliable if(LCHardwareIsAvailable()!=1) { OSFatal("Hardware is not avaliable."); } //Gets the current state of DMA, so we can restore it after our copy uint32_t dmaState=LCIsDMAEnabled(); //Checks to see if DMA is enabled, if not it will try to enable it. if(dmaState!=1) { LCEnableDMA(); dmaState=LCIsDMAEnabled(); if(dmaState!=1) { OSFatal("Can't enable DMA"); } } //Load memory to locked cache LCLoadDMABlocks(lc_addr,src_addr,blocks); LCWaitDMAQueue(0); //Store memory from locked cache LCStoreDMABlocks(dest_addr,lc_addr,blocks); LCWaitDMAQueue(0); //If DMA was not previously enabled, then disable it to restore state. if(dmaState!=1) { LCDisableDMA(); dmaState=LCIsDMAEnabled(); //If DMA failed to disable, return error code if(dmaState!=1) { OSFatal("Couldn't Disable DMA"); } } __os_snprintf(output+strlen(output), 255, "New src_val: %02x,",src_val[0]); __os_snprintf(output+strlen(output), 255, "New dest_val: %02x,",dest_val[0]); //Cleanup LCDealloc(lc_addr); OSFreeToSystem(dest_addr); OSFreeToSystem(src_addr); OSFatal(output); }
void GameLoaderRun() { auto appModule = gLoader.loadRPL(gGameRpx.c_str()); if (!appModule) { gLog->error("Could not load {}", gGameRpx); return; } gSystem.setUserModule(appModule); gDebugControl.preLaunch(); gLog->debug("Succesfully loaded {}", gGameRpx); // Call the RPX __preinit_user if it is defined auto userPreinit = appModule->findFuncExport<void, be_ptr<CommonHeap>*, be_ptr<CommonHeap>*, be_ptr<CommonHeap>*>("__preinit_user"); if (userPreinit) { struct HeapHandles { be_ptr<CommonHeap> mem1Heap; be_ptr<CommonHeap> fgHeap; be_ptr<CommonHeap> mem2Heap; }; HeapHandles *wiiHandles = OSAllocFromSystem<HeapHandles>(); wiiHandles->mem1Heap = MEMGetBaseHeapHandle(BaseHeapType::MEM1); wiiHandles->fgHeap = MEMGetBaseHeapHandle(BaseHeapType::FG); wiiHandles->mem2Heap = MEMGetBaseHeapHandle(BaseHeapType::MEM2); userPreinit(&wiiHandles->mem1Heap, &wiiHandles->fgHeap, &wiiHandles->mem2Heap); MEMSetBaseHeapHandle(BaseHeapType::MEM1, wiiHandles->mem1Heap); MEMSetBaseHeapHandle(BaseHeapType::FG, wiiHandles->fgHeap); MEMSetBaseHeapHandle(BaseHeapType::MEM2, wiiHandles->mem2Heap); OSFreeToSystem(wiiHandles); } // Create default threads for (auto i = 0u; i < CoreCount; ++i) { auto thread = OSAllocFromSystem<OSThread>(); auto stackSize = appModule->defaultStackSize; auto stack = reinterpret_cast<uint8_t*>(OSAllocFromSystem(stackSize, 8)); auto name = OSSprintfFromSystem("Default Thread %d", i); OSCreateThread(thread, 0u, 0, nullptr, reinterpret_cast<be_val<uint32_t>*>(stack + stackSize), stackSize, 16, static_cast<OSThreadAttributes::Flags>(1 << i)); OSSetDefaultThread(i, thread); OSSetThreadName(thread, name); } // Create interrupt threads for (auto i = 0u; i < CoreCount; ++i) { auto thread = OSAllocFromSystem<OSThread>(); auto stackSize = 16 * 1024; auto stack = reinterpret_cast<uint8_t*>(OSAllocFromSystem(stackSize, 8)); auto name = OSSprintfFromSystem("Interrupt Thread %d", i); OSCreateThread(thread, InterruptThreadEntryPoint, i, nullptr, reinterpret_cast<be_val<uint32_t>*>(stack + stackSize), stackSize, -1, static_cast<OSThreadAttributes::Flags>(1 << i)); OSSetInterruptThread(i, thread); OSSetThreadName(thread, name); OSResumeThread(thread); } // Run thread 1 OSRunThread(OSGetDefaultThread(1), appModule->entryPoint, 0, nullptr); }
void _start() { asm( "lis %r1, 0x1ab5 ;" "ori %r1, %r1, 0xd138 ;" ); unsigned int coreinit_handle, gx2_handle; OSDynLoad_Acquire("coreinit", &coreinit_handle); OSDynLoad_Acquire("gx2", &gx2_handle); //OS Memory functions void*(*memset)(void * dest, unsigned int value, unsigned int bytes); void*(*OSAllocFromSystem)(unsigned int size, int align); void(*OSFreeToSystem)(void *ptr); //IM functions int(*IM_Open)(); int(*IM_Close)(int fd); int(*IM_SetDeviceState)(int fd, void *mem, int state, int a, int b); //OS Memory functions OSDynLoad_FindExport(coreinit_handle, 0, "memset", &memset); OSDynLoad_FindExport(coreinit_handle, 0, "OSAllocFromSystem", &OSAllocFromSystem); OSDynLoad_FindExport(coreinit_handle, 0, "OSFreeToSystem", &OSFreeToSystem); //IM functions OSDynLoad_FindExport(coreinit_handle, 0, "IM_Open", &IM_Open); OSDynLoad_FindExport(coreinit_handle, 0, "IM_Close", &IM_Close); OSDynLoad_FindExport(coreinit_handle, 0, "IM_SetDeviceState", &IM_SetDeviceState); //Restart system to get lib access int fd = IM_Open(); void *mem = OSAllocFromSystem(0x100, 64); memset(mem, 0, 0x100); //set restart flag to force quit browser IM_SetDeviceState(fd, mem, 3, 0, 0); IM_Close(fd); OSFreeToSystem(mem); //wait a bit for browser end unsigned int t1 = 0x1FFFFFFF; while(t1--) ; /* Get the framebuffer of the TV or DRC */ void(*GX2SwapScanBuffers)(); OSDynLoad_FindExport(gx2_handle, 0, "GX2SwapScanBuffers", &GX2SwapScanBuffers); unsigned char *abuseFunc = (unsigned char*)GX2SwapScanBuffers; unsigned short f_hi = *(unsigned short*)(abuseFunc+0x12); unsigned short f_lo = *(unsigned short*)(abuseFunc+0x16); unsigned int gx2settingBase = (((f_lo & 0x8000) ? (f_hi-1) : f_hi) << 16) | f_lo; unsigned int args[2]; args[0] = *((unsigned int*)(gx2settingBase + 0x304)); args[1] = *((unsigned int*)(gx2settingBase + 0x304 + 0x20)); int(*OSGetCoreId)(); OSDynLoad_FindExport(coreinit_handle, 0, "OSGetCoreId", &OSGetCoreId); void(*OSTestThreadCancel)(); OSDynLoad_FindExport(coreinit_handle, 0, "OSTestThreadCancel", &OSTestThreadCancel); void(*GX2Shutdown)(); OSDynLoad_FindExport(gx2_handle, 0, "GX2Shutdown", &GX2Shutdown); int(*GX2GetMainCoreId)(); OSDynLoad_FindExport(gx2_handle, 0, "GX2GetMainCoreId", &GX2GetMainCoreId); /* Prepare for our own death */ void*(*OSGetCurrentThread)(); OSDynLoad_FindExport(coreinit_handle, 0, "OSGetCurrentThread", &OSGetCurrentThread); void *myBorkedThread = OSGetCurrentThread(); int (*OSSuspendThread)(void *thread); OSDynLoad_FindExport(coreinit_handle, 0, "OSSuspendThread", &OSSuspendThread); /* Prepare for thread startups */ int (*OSCreateThread)(void *thread, void *entry, int argc, void *args, unsigned int stack, unsigned int stack_size, int priority, unsigned short attr); int (*OSResumeThread)(void *thread); int (*OSIsThreadTerminated)(void *thread); OSDynLoad_FindExport(coreinit_handle, 0, "OSCreateThread", &OSCreateThread); OSDynLoad_FindExport(coreinit_handle, 0, "OSResumeThread", &OSResumeThread); OSDynLoad_FindExport(coreinit_handle, 0, "OSIsThreadTerminated", &OSIsThreadTerminated); /* Allocate a stack for the thread */ unsigned int stack = (unsigned int) OSAllocFromSystem(0x1000, 0x10); stack += 0x1000; /* Create the thread */ void *thread = OSAllocFromSystem(OSTHREAD_SIZE, 8); if(OSGetCoreId() != GX2GetMainCoreId()) //needed for access without crashing { int ret = OSCreateThread(thread, GX2Shutdown, 0, (void*)0, stack, 0x1000, 0, 0x10 | (1<<GX2GetMainCoreId())); if (ret == 0) OSFatal("Failed to create thread"); /* Schedule it for execution */ OSResumeThread(thread); while(OSIsThreadTerminated(thread) == 0) ; } else //same core, easy GX2Shutdown(); //current thread is broken, switch to a working one in core 1 int ret = OSCreateThread(thread, myGXthread, 2, args, stack, 0x1000, 0, 0xA); if (ret == 0) OSFatal("Failed to create thread"); /* Schedule it for execution */ OSResumeThread(thread); /* SO UGLY but it works magically */ while(1) ; //would be better but again, crashes 5.3.2 //OSSuspendThread(myBorkedThread); //OSFatal("I am still not dead!"); }