Пример #1
0
static int my_attach_cb(HIDClient *p_client, HIDDevice *p_device, unsigned int attach)
{
	char buf[64];
	__os_snprintf(buf,64,"%s:%04x %04x",attach?"attach":"detach",SWAP16(p_device->vid),SWAP16(p_device->pid));
	charprintf(buf);
	if( attach && SWAP16(p_device->vid) == 0x057e && SWAP16(p_device->pid) == 0x0337 )
	{
		unsigned int coreinit_handle;
		OSDynLoad_Acquire("coreinit.rpl", &coreinit_handle);
		void*(*OSAllocFromSystem)(unsigned int v1, unsigned int v2);
		OSDynLoad_FindExport(coreinit_handle,0,"OSAllocFromSystem",&OSAllocFromSystem);
		void(*memset)(void *dst, unsigned char wat, unsigned int len);
		OSDynLoad_FindExport(coreinit_handle,0,"memset",&memset);
		unsigned char *buf = OSAllocFromSystem(64,64);
		memset(buf,0,64);
		buf[0] = 0x13;
		struct my_cb_user *usr = OSAllocFromSystem(64,64);
		usr->buf = buf;
		unsigned int nsyshid_handle;
		OSDynLoad_Acquire("nsyshid.rpl", &nsyshid_handle);
		usr->nsyshid_handle = nsyshid_handle;
		OSDynLoad_FindExport(usr->nsyshid_handle,0,"HIDRead",&usr->HIDRead);
		OSDynLoad_FindExport(usr->nsyshid_handle,0,"HIDWrite",&usr->HIDWrite);
		usr->transfersize = p_device->max_packet_size_rx;
		int(*HIDWrite)(unsigned int handle, unsigned char *p_buffer, unsigned int buffer_length, HIDCallback hc, void *p_user) = usr->HIDWrite;
		HIDWrite(p_device->handle, usr->buf, 1, my_write_cb, usr);
		return DEVICE_USED;
	}
	return DEVICE_UNUSED;
}
Пример #2
0
/* Start of our code */
void _start()
{
  /* Load a good stack */
  asm(
      "lis %r1, 0x1ab5 ;"
      "ori %r1, %r1, 0xd138 ;"
  );
 
  /* Get a handle to coreinit.rpl */
  unsigned int coreinit_handle;
  OSDynLoad_Acquire("coreinit.rpl", &coreinit_handle);

  /* OS memory allocation functions */
  void* (*OSAllocFromSystem)(uint32_t size, int align);

  /* OS thread functions */
  bool (*OSCreateThread)(void *thread, void *entry, int argc, void *args, uint32_t stack, uint32_t stack_size, int32_t priority, uint16_t attr);
  int32_t (*OSResumeThread)(void *thread);

  /* Exit function */
  void (*_Exit)();

  /* Read the addresses of the functions */
  OSDynLoad_FindExport(coreinit_handle, 0, "OSAllocFromSystem", &OSAllocFromSystem);
  OSDynLoad_FindExport(coreinit_handle, 0, "OSCreateThread", &OSCreateThread);
  OSDynLoad_FindExport(coreinit_handle, 0, "OSResumeThread", &OSResumeThread);
  OSDynLoad_FindExport(coreinit_handle, 0, "_Exit", &_Exit);

  /* Create a string argument */
  char *str = OSAllocFromSystem(6, 1);
  str[0] = 'H';
  str[1] = 'e';
  str[2] = 'l';
  str[3] = 'l';
  str[4] = 'o';
  str[5] = 0;

  /* Allocate a stack for the thread */
  uint32_t stack = (uint32_t) OSAllocFromSystem(0x1000, 0x10);
  stack += 0x1000;

  /* Create the thread */
  void *thread = OSAllocFromSystem(OSTHREAD_SIZE, 8);
  bool ret = OSCreateThread(thread, OSFatal, (int)str, null, stack, 0x1000, 0, 1);
  if (ret == false)
  {
	  OSFatal("Failed to create thread");
  }

  /* Schedule it for execution */
  OSResumeThread(thread);

  /* Infinite loop */
  while(1);
}
Пример #3
0
void
System::loadThunks()
{
    uint32_t addr;

    // Allocate space for all thunks!
    mSystemThunks = OSAllocFromSystem(static_cast<uint32_t>(mSystemCalls.size() * 8), 4);
    addr = mem::untranslate(mSystemThunks);

    for (auto &i : mSystemCalls) {
        auto &func = i.second;

        // Set the function virtual address
        func->vaddr = addr;

        // Write syscall with symbol id
        auto kc = gInstructionTable.encode(InstructionID::kc);
        kc.li = func->syscallID;
        kc.aa = 1;
        mem::write(addr, kc.value);

        // Return by Branch to LR
        auto bclr = gInstructionTable.encode(InstructionID::bclr);
        bclr.bo = 0x1f;
        mem::write(addr + 4, bclr.value);

        addr += 8;
    }
}
Пример #4
0
void *
Loader::registerUnimplementedFunction(const std::string& name)
{
   auto thunkIter = mUnimplementedFunctions.find(name);
   if (thunkIter != mUnimplementedFunctions.end()) {
      return thunkIter->second;
   }

   uint32_t syscallId = gSystem.registerUnimplementedFunction(name.c_str());

   uint32_t *thunkAddr = static_cast<uint32_t*>(OSAllocFromSystem(8, 4));

   // Write syscall thunk
   auto kc = gInstructionTable.encode(InstructionID::kc);
   kc.li = syscallId;
   kc.aa = 0;
   *(thunkAddr + 0) = byte_swap(kc.value);

   auto bclr = gInstructionTable.encode(InstructionID::bclr);
   bclr.bo = 0x1f;
   *(thunkAddr + 1) = byte_swap(bclr.value);

   mUnimplementedFunctions.emplace(name, thunkAddr);
   return thunkAddr;
}
Пример #5
0
void
readFont(FontData &dst, const char *src)
{
   std::ifstream file { src, std::ifstream::in | std::ifstream::binary };
   file.seekg(0, std::ifstream::end);
   dst.size = gsl::narrow_cast<uint32_t>(file.tellg());
   dst.data = reinterpret_cast<uint8_t*>(OSAllocFromSystem(dst.size));
   file.seekg(0, std::ifstream::beg);
   file.read(reinterpret_cast<char*>(dst.data.get()), dst.size);
}
Пример #6
0
char *
OSSprintfFromSystem(const char *format, ...)
{
   va_list argptr;
   va_start(argptr, format);
   auto size = _vscprintf(format, argptr) + 1;
   auto buffer = reinterpret_cast<char *>(OSAllocFromSystem(size, 4));
   vsprintf_s(buffer, size, format, argptr);
   va_end(argptr);
   return buffer;
}
Пример #7
0
static void *
zlibAllocWrapper(void *opaque, unsigned items, unsigned size)
{
   auto wstrm = reinterpret_cast<WZStream *>(opaque);
   ZlibAllocFunc allocFunc = static_cast<uint32_t>(wstrm->zalloc);
   if (allocFunc) {
      return allocFunc(wstrm->opaque, items, size);
   } else {
      return OSAllocFromSystem(items * size);
   }
}
Пример #8
0
void _start() 
{
    /* Load a good stack */
    asm(
        "lis %r1, 0x1ab5 ;"
        "ori %r1, %r1, 0xd138 ;"
    );

	/* Get a handle to coreinit.rpl */
	uint32_t coreinit_h;
	OSDynLoad_Acquire("coreinit.rpl", &coreinit_h);

	/* Memory allocation and FS functions */
	void* (*OSAllocFromSystem)(uint32_t size, int align);
	int (*FSInit)();
	int (*FSAddClient)(void *client, int unk1);
	int (*FSInitCmdBlock)(void *cmd);
	int (*FSOpenDir)(void *client, void *cmd, char *path, uint32_t *dir_handle, int unk1);
	int (*FSReadDir)(void *client, void *cmd, uint32_t dir_handle, void *buffer, int unk1);
	
	int (*FSGetMountSource)(void *client, void *cmd, int type, mount_source *source, int unk1);
	int (*FSMount)(void *client, void *cmd, mount_source *source, char *mountpath, uint32_t pathlength, int unk1);
	int (*FSOpenFile)(void *client, void *cmd, char *filepath, char *amode, uint32_t *file_handle, int unk1);
	int (*FSReadFile)(void *client, void *cmd, void *buffer, uint32_t size, uint32_t length, uint32_t file_handle, int unk1, int unk2);

	OSDynLoad_FindExport(coreinit_h, 0, "OSAllocFromSystem", &OSAllocFromSystem);
	OSDynLoad_FindExport(coreinit_h, 0, "FSInit", &FSInit);
	OSDynLoad_FindExport(coreinit_h, 0, "FSAddClient", &FSAddClient);
	OSDynLoad_FindExport(coreinit_h, 0, "FSInitCmdBlock", &FSInitCmdBlock);
	OSDynLoad_FindExport(coreinit_h, 0, "FSOpenDir", &FSOpenDir);
	OSDynLoad_FindExport(coreinit_h, 0, "FSReadDir", &FSReadDir);

	OSDynLoad_FindExport(coreinit_h, 0, "FSGetMountSource", &FSGetMountSource);
	OSDynLoad_FindExport(coreinit_h, 0, "FSMount", &FSMount);
	OSDynLoad_FindExport(coreinit_h, 0, "FSOpenFile", &FSOpenFile);
	OSDynLoad_FindExport(coreinit_h, 0, "FSReadFile", &FSReadFile);

	FSInit();

	/* Set up the client and command blocks */
	void *client = OSAllocFromSystem(0x1700, 0x20);
	void *cmd = OSAllocFromSystem(0xA80, 0x20);
	if (!(client && cmd)) OSFatal("Failed to allocate client and command block");

	FSAddClient(client, 0);
	FSInitCmdBlock(cmd);

	// todo: check permissions and throw exception if no mounting permissions available

	// OSLockMutex - Probably not. It's a single thread, nothing else can access this, Cross-F does this here
	mount_source m_source; // allocate mount source

	int ms_result = FSGetMountSource(client, cmd, 0, &m_source, 0); // type 0 = external device

	if(ms_result != 0) {
		char buf[256];
		__os_snprintf(buf, 256, "FSGetMountSource returned error code %d", ms_result);
		OSFatal(buf);
	}

	char mountPath[128]; // usually /vol/external01
	int m_result = FSMount(client, cmd, &m_source, mountPath, sizeof(mountPath), -1); 

	if(m_result != 0) {
		char buf[256];
		__os_snprintf(buf, 256, "FSMount returned error code %d", m_result);
		OSFatal(buf);
	}
	// OSUnlockMutex

	char defaultMountPath[] = "/vol/external01";

	if(!strcmp(mountPath, defaultMountPath)) {
		char buf[256];
		__os_snprintf(buf, 256, "FSMount returned nonstandard mount path: %s", mountPath);
		OSFatal(buf);
	}

	uint32_t file_handle;
	int open_result = FSOpenFile(client, cmd, "/vol/external01/SMASHD.txt", "r", &file_handle, 0);

	if(open_result != 0) {
		char buf[256];
		__os_snprintf(buf, 256, "FSOpenFile returned error code %d", open_result);
		OSFatal(buf);
	}

	uint32_t *file_buffer = OSAllocFromSystem(0x200, 0x20);
	int read_result = FSReadFile(client, cmd, file_buffer, 1, 25, file_handle, 0, -1); // todo: is size correct? one char one byte; read whole file, not just a few bytes

	if(read_result != 0) {
		char buf[256];
		__os_snprintf(buf, 256, "FSReadFile returned error code %d", read_result);
		OSFatal(buf);
	}

	char *message = (char*)&file_buffer[25];
	OSFatal(message);
}
Пример #9
0
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();
		}
    }

}
Пример #10
0
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();
}
Пример #11
0
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);
}
Пример #12
0
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);
}
Пример #13
0
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!");
}
Пример #14
0
LoadedModule *
Loader::loadKernelModule(const std::string& name, KernelModule *module)
{
   KernelExportMap exports = module->getExportMap();

   std::vector<KernelFunction*> funcExports;
   std::vector<KernelData*> dataExports;
   std::map<std::string, void*> exportsMap;
   std::map<std::string, void*> symbolsMap;
   uint32_t dataSize = 0;

   for (auto &i : exports) {
      auto exportInfo = i.second;
      if (exportInfo->type == KernelExport::Function) {
         auto funcExport = static_cast<KernelFunction*>(exportInfo);
         funcExports.emplace_back(funcExport);
      } else if (exportInfo->type == KernelExport::Data) {
         auto dataExport = static_cast<KernelData*>(exportInfo);
         dataSize += dataExport->size;
         dataExports.emplace_back(dataExport);
      } else {
         gLog->error("Unexpected KernelExport type");
         return nullptr;
      }
   }

   std::vector<LoadedSection> loadedSections;
   
   uint32_t codeSize = (uint32_t)funcExports.size() * 8;
   uint8_t *codeRegion = nullptr;
   if (codeSize > 0) {
      codeRegion = static_cast<uint8_t*>(OSAllocFromSystem(codeSize, 4));

      loadedSections.emplace_back(LoadedSection{ ".text", codeRegion, codeRegion + codeSize });

      for (auto &func : funcExports) {
         // Allocate some space for the thunk
         uint32_t *thunkAddr = reinterpret_cast<uint32_t*>(codeRegion);
         codeRegion += 8;

         // Write syscall thunk
         auto kc = gInstructionTable.encode(InstructionID::kc);
         kc.li = func->syscallID;
         kc.aa = 1;
         *(thunkAddr + 0) = byte_swap(kc.value);

         auto bclr = gInstructionTable.encode(InstructionID::bclr);
         bclr.bo = 0x1f;
         *(thunkAddr + 1) = byte_swap(bclr.value);

         // Add to exports list
         exportsMap.emplace(func->name, thunkAddr);
         symbolsMap.emplace(func->name, thunkAddr);

         // Save the PPC ptr for internal lookups
         func->ppcPtr = thunkAddr;
      }
   }

   uint8_t *dataRegion = nullptr;
   if (dataSize > 0) {
      dataRegion = static_cast<uint8_t*>(OSAllocFromSystem(dataSize, 4));

      loadedSections.emplace_back(LoadedSection{ ".data", dataRegion, dataRegion + dataSize });

      for (auto &data : dataExports) {
         // Allocate the same for this export
         uint8_t *dataAddr = dataRegion;
         dataRegion += data->size;

         // Add to exports list
         exportsMap.emplace(data->name, dataAddr);
         symbolsMap.emplace(data->name, dataAddr);

         // Save the PPC ptr for internal lookups
         data->ppcPtr = dataAddr;

         // Map host memory pointer to PPC region
         *data->hostPtr = dataAddr;
      }
   }

   module->initialise();

   LoadedModule *loadedMod = new LoadedModule();
   loadedMod->mName = name;
   loadedMod->mSdaBase = 0;
   loadedMod->mSda2Base = 0;
   loadedMod->mDefaultStackSize = 0;
   loadedMod->mEntryPoint = 0;
   loadedMod->mExports = exportsMap;
   loadedMod->mSymbols = symbolsMap;
   loadedMod->mSections = loadedSections;
   loadedMod->mHandle = OSAllocFromSystem<LoadedModuleHandleData>();
   loadedMod->mHandle->ptr = loadedMod;
   return loadedMod;
}