/* Initialise Video, PAD, DVD, Font */ void* Initialise (void) { VIDEO_Init (); PAD_Init (); DVD_Init(); *(volatile unsigned long*)0xcc00643c = 0x00000000; //allow 32mhz exi bus // Disable IPL modchips to allow access to IPL ROM fonts ipl_set_config(6); usleep(1000); //wait for modchip to disable (overkill) __SYS_ReadROM(IPLInfo,256,0); // Read IPL tag // Wii has no IPL tags for "PAL" so let libOGC figure out the video mode if(!is_gamecube()) { vmode = VIDEO_GetPreferredMode(NULL); //Last mode used } else { // Gamecube, determine based on IPL int retPAD = 0, retCnt = 10000; while(retPAD <= 0 && retCnt >= 0) { retPAD = PAD_ScanPads(); usleep(100); retCnt--; } // L Trigger held down ignores the fact that there's a component cable plugged in. if(VIDEO_HaveComponentCable() && !(PAD_ButtonsDown(0) & PAD_TRIGGER_L)) { if(strstr(IPLInfo,"MPAL")!=NULL) { swissSettings.sramVideo = 2; vmode = &TVMpal480Prog; //Progressive 480p } else if((strstr(IPLInfo,"PAL")!=NULL)) { swissSettings.sramVideo = 1; vmode = &TVPal576ProgScale; //Progressive 576p } else { swissSettings.sramVideo = 0; vmode = &TVNtsc480Prog; //Progressive 480p } } else { //try to use the IPL region if(strstr(IPLInfo,"MPAL")!=NULL) { swissSettings.sramVideo = 2; vmode = &TVMpal480IntDf; //PAL-M } else if(strstr(IPLInfo,"PAL")!=NULL) { swissSettings.sramVideo = 1; vmode = &TVPal576IntDfScale; //PAL } else { swissSettings.sramVideo = 0; vmode = &TVNtsc480IntDf; //NTSC } } } initialise_video(vmode); populateVideoStr(vmode); init_font(); init_textures(); whichfb = 0; drive_version(&driveVersion[0]); swissSettings.hasDVDDrive = *(u32*)&driveVersion[0] ? 1 : 0; if(!driveVersion[0]) { // Reset DVD if there was a modchip DrawFrameStart(); WriteFontStyled(640/2, 250, "Initialise DVD .. (HOLD B if NO DVD Drive)", 0.8f, true, defaultColor); DrawFrameFinish(); dvd_reset(); // low-level, basic dvd_read_id(); if(!(PAD_ButtonsHeld(0) & PAD_BUTTON_B)) { dvd_set_streaming(*(char*)0x80000008); } drive_version(&driveVersion[0]); swissSettings.hasDVDDrive = *(u32*)&driveVersion[0] ? 1 : 0; if(!swissSettings.hasDVDDrive) { DrawFrameStart(); DrawMessageBox(D_INFO, "No DVD Drive Detected !!"); DrawFrameFinish(); sleep(2); } } return xfb[0]; }
int patch_gcm(file_handle *file, ExecutableFile *filesToPatch, int numToPatch, int multiDol) { int i, num_patched = 0; // If the current device isn't SD Gecko, init SD Gecko Slot A or B to write patches. if(deviceHandler_initial != &initial_SD0 && deviceHandler_initial != &initial_SD1) { deviceHandler_setStatEnabled(0); if(deviceHandler_FAT_init(&initial_SD0)) { savePatchDevice = 0; } else if(deviceHandler_FAT_init(&initial_SD1)) { savePatchDevice = 1; } deviceHandler_setStatEnabled(1); } // Already using SD Gecko if(deviceHandler_initial == &initial_SD0) savePatchDevice = 0; else if(deviceHandler_initial == &initial_SD1) savePatchDevice = 1; if(savePatchDevice == -1) { DrawFrameStart(); DrawMessageBox(D_FAIL, "No writable device present\nA SD Gecko must be inserted in\n order to utilise patches for this game."); DrawFrameFinish(); sleep(5); return 0; } char patchFileName[256]; char patchDirName[256]; char patchBaseDirName[256]; char gameID[8]; memset(&gameID, 0, 8); memset(&patchDirName, 0, 256); memset(&patchBaseDirName, 0, 256); strncpy((char*)&gameID, (char*)&GCMDisk, 4); sprintf(&patchDirName[0],"%s:/swiss_patches/%s",(savePatchDevice ? "sdb":"sda"), &gameID[0]); sprintf(&patchBaseDirName[0],"%s:/swiss_patches",(savePatchDevice ? "sdb":"sda")); print_gecko("Patch dir will be: %s if required\r\n", patchDirName); *(u32*)VAR_EXECD_OFFSET = 0xFFFFFFFF; // Go through all the possible files we think need patching.. for(i = 0; i < numToPatch; i++) { u32 patched = 0, crc32 = 0; sprintf(txtbuffer, "Patching File %i/%i",i+1,numToPatch); DrawFrameStart(); DrawProgressBar((int)(((float)(i+1)/(float)numToPatch)*100), txtbuffer); DrawFrameFinish(); // Round up to 32 bytes if(filesToPatch[i].size % 0x20) { filesToPatch[i].size += (0x20-(filesToPatch[i].size%0x20)); } if(filesToPatch[i].size > 8*1024*1024) { print_gecko("Skipping %s %iKB too large\r\n", filesToPatch[i].name, filesToPatch[i].size/1024); continue; } print_gecko("Checking %s %iKb\r\n", filesToPatch[i].name, filesToPatch[i].size/1024); if(strstr(filesToPatch[i].name, "execD.")) { *(u32*)VAR_EXECD_OFFSET = filesToPatch[i].offset; } if(strstr(filesToPatch[i].name, "iwanagaD.dol") || strstr(filesToPatch[i].name, "switcherD.dol")) { continue; // skip unused PSO files } int sizeToRead = filesToPatch[i].size; u8 *buffer = (u8*)memalign(32, sizeToRead); deviceHandler_seekFile(file,filesToPatch[i].offset, DEVICE_HANDLER_SEEK_SET); if(deviceHandler_readFile(file,buffer,sizeToRead)!= sizeToRead) { DrawFrameStart(); DrawMessageBox(D_FAIL, "Failed to read!"); DrawFrameFinish(); sleep(5); return 0; } if(curDevice != DVD_DISC) { u32 ret = Patch_DVDLowLevelRead(buffer, sizeToRead, filesToPatch[i].type); if(READ_PATCHED_ALL != ret) { DrawFrameStart(); DrawMessageBox(D_FAIL, "Failed to find necessary functions for patching!"); DrawFrameFinish(); sleep(5); } else patched += 1; } if(swissSettings.debugUSB && usb_isgeckoalive(1) && !swissSettings.wiirdDebug) { patched += Patch_Fwrite(buffer, sizeToRead); } if(swissSettings.wiirdDebug || getEnabledCheatsSize() > 0) { Patch_CheatsHook(buffer, sizeToRead, filesToPatch[i].type); } if(curDevice == DVD_DISC && is_gamecube()) { patched += Patch_DVDLowLevelReadForDVD(buffer, sizeToRead, filesToPatch[i].type); patched += Patch_DVDReset(buffer, sizeToRead); } patched += Patch_VidMode(buffer, sizeToRead, filesToPatch[i].type); patched += Patch_FontEnc(buffer, sizeToRead); if(swissSettings.forceWidescreen) Patch_WideAspect(buffer, sizeToRead, filesToPatch[i].type); if(swissSettings.forceAnisotropy) Patch_TexFilt(buffer, sizeToRead, filesToPatch[i].type); if(patched) { // File handle for a patch we might need to write FILE *patchFile = 0; memset(patchFileName, 0, 256); // Make a base patches dir if we don't have one already if(mkdir(&patchBaseDirName[0], 0777) != 0) { if(errno != EEXIST) { return -2; } } if(mkdir(&patchDirName[0], 0777) != 0) { if(errno != EEXIST) { return -2; } } sprintf(patchFileName, "%s/%i",patchDirName, num_patched); // Work out the crc32 crc32 = Crc32_ComputeBuf( 0, buffer, (u32) sizeToRead); // See if this file already exists, if it does, match crc patchFile = fopen( patchFileName, "rb" ); if(patchFile) { //print_gecko("Old Patch exists\r\n"); u32 oldCrc32 = 0; fseek(patchFile, 0L, SEEK_END); u32 file_size = ftell(patchFile); fseek(patchFile, file_size-4, SEEK_SET); fread(&oldCrc32, 1, 4, patchFile); if(oldCrc32 == crc32) { num_patched++; fclose(patchFile); free(buffer); print_gecko("CRC matched, no need to patch again\r\n"); continue; } else { remove(patchFileName); fclose(patchFile); print_gecko("CRC mismatch, writing patch again\r\n"); } } // Otherwise, write a file out for this game with the patched buffer inside. print_gecko("Writing patch file: %s %i bytes (disc offset %08X)\r\n", patchFileName, sizeToRead, filesToPatch[i].offset); patchFile = fopen(patchFileName, "wb"); fwrite(buffer, 1, sizeToRead, patchFile); u32 magic = SWISS_MAGIC; fwrite(&filesToPatch[i].offset, 1, 4, patchFile); fwrite(&filesToPatch[i].size, 1, 4, patchFile); fwrite(&magic, 1, 4, patchFile); fwrite(&crc32, 1, 4, patchFile); fclose(patchFile); num_patched++; } free(buffer); } return num_patched; }
/* Initialise Video, PAD, DVD, Font */ void Initialise (void) { VIDEO_Init (); PAD_Init (); DVD_Init(); *(volatile unsigned long*)0xcc00643c = 0x00000000; //allow 32mhz exi bus // Disable IPL modchips to allow access to IPL ROM fonts ipl_set_config(6); usleep(1000); //wait for modchip to disable (overkill) __SYS_ReadROM(IPLInfo,256,0); // Read IPL tag // By default, let libOGC figure out the video mode GXRModeObj *vmode = VIDEO_GetPreferredMode(NULL); //Last mode used if(is_gamecube()) { // Gamecube, determine based on IPL int retPAD = 0, retCnt = 10000; while(retPAD <= 0 && retCnt >= 0) { retPAD = PAD_ScanPads(); usleep(100); retCnt--; } // L Trigger held down ignores the fact that there's a component cable plugged in. if(VIDEO_HaveComponentCable() && !(PAD_ButtonsDown(0) & PAD_TRIGGER_L)) { if(strstr(IPLInfo,"MPAL")!=NULL) { swissSettings.sramVideo = 2; vmode = &TVMpal480Prog; //Progressive 480p } else if((strstr(IPLInfo,"PAL")!=NULL)) { swissSettings.sramVideo = 1; vmode = &TVPal576ProgScale; //Progressive 576p } else { swissSettings.sramVideo = 0; vmode = &TVNtsc480Prog; //Progressive 480p } } else { //try to use the IPL region if(strstr(IPLInfo,"MPAL")!=NULL) { swissSettings.sramVideo = 2; vmode = &TVMpal480IntDf; //PAL-M } else if(strstr(IPLInfo,"PAL")!=NULL) { swissSettings.sramVideo = 1; vmode = &TVPal576IntDfScale; //PAL } else { swissSettings.sramVideo = 0; vmode = &TVNtsc480IntDf; //NTSC } } } setVideoMode(vmode); init_font(); DrawInit(); drive_version(&driveVersion[0]); swissSettings.hasDVDDrive = *(u32*)&driveVersion[0] ? 1 : 0; if(!driveVersion[0]) { // Reset DVD if there was a IPL replacement that hasn't done that for us yet uiDrawObj_t *progBox = DrawPublish(DrawProgressBar(true, 0, "Initialise DVD .. (HOLD B if NO DVD Drive)")); dvd_reset(); // low-level, basic dvd_read_id(); if(!(PAD_ButtonsHeld(0) & PAD_BUTTON_B)) { dvd_set_streaming(*(char*)0x80000008); } drive_version(&driveVersion[0]); swissSettings.hasDVDDrive = *(u32*)&driveVersion[0] ? 2 : 0; if(!swissSettings.hasDVDDrive) { DrawDispose(progBox); progBox = DrawPublish(DrawMessageBox(D_INFO, "No DVD Drive Detected !!")); sleep(2); } DrawDispose(progBox); } }
void info_draw_page(int page_num) { doBackdrop(); DrawEmptyBox(20,60, vmode->fbWidth-20, 420, COLOR_BLACK); syssram* sram = __SYS_LockSram(); __SYS_UnlockSram(0); // System Info (Page 1/3) if(!page_num) { WriteFont(30, 65, "System Info (1/3):"); // Model if(is_gamecube()) { if(*(u32*)&driveVersion[0] == 0x20010831) { sprintf(topStr, "Panasonic Q SL-GC10-S"); } else if(IPLInfo[0x55]=='M') { // MPAL 1.1 (Brazil) sprintf(topStr, "Nintendo GameCube DOL-002 (BRA)"); } else if((!IPLInfo[0x55]) // NTSC 1.0 || (IPLInfo[0x55] == 'P' && IPLInfo[0x65]=='0') // PAL 1.0 || (IPLInfo[0x55] != 'P' && IPLInfo[0x65]=='1')) { // NTSC 1.1 sprintf(topStr, "Nintendo GameCube DOL-001"); } else if((IPLInfo[0x55] == 'P' && IPLInfo[0x65]=='0') // PAL 1.1 || IPLInfo[0x65]=='2') { // NTSC 1.2 sprintf(topStr, "Nintendo GameCube DOL-101"); } } else { sprintf(topStr, "Nintendo Wii"); } WriteFontStyled(640/2, 110, topStr, 1.0f, true, defaultColor); // IPL version string if(is_gamecube()) { if(!IPLInfo[0x55]) { sprintf(topStr, "NTSC Revision 1.0"); } else { sprintf(topStr, "%s", &IPLInfo[0x55]); } } else { sprintf(topStr, "Wii IPL"); } WriteFontStyled(640/2, 140, topStr, 1.0f, true, defaultColor); if(swissSettings.hasDVDDrive) { if((!__wkfSpiReadId() || (__wkfSpiReadId() == 0xFFFFFFFF))) { sprintf(topStr, "DVD Drive %02X %02X%02X/%02X (%02X)",driveVersion[2],driveVersion[0],driveVersion[1],driveVersion[3],driveVersion[4]); } else { sprintf(topStr, "WKF Serial %s",wkfGetSerial()); } } else sprintf(topStr, "No DVD Drive present"); WriteFontStyled(640/2, 170, topStr, 1.0f, true, defaultColor); sprintf(topStr, "%s",videoStr); WriteFontStyled(640/2, 200, topStr, 1.0f, true, defaultColor); sprintf(topStr,"%s / %s",getSramLang(sram->lang), sram->flags&4 ? "Stereo":"Mono"); WriteFontStyled(640/2, 230, topStr, 1.0f, true, defaultColor); sprintf(topStr,"PVR %08X ECID %08X:%08X:%08X",mfpvr(),mfspr(0x39C),mfspr(0x39D),mfspr(0x39E)); WriteFontStyled(640/2, 260, topStr, 0.75f, true, defaultColor); } else if(page_num == 1) { WriteFont(30, 65, "Device Info (2/3):"); sprintf(topStr,"BBA: %s", bba_exists ? "Installed":"Not Present"); WriteFont(30, 110, topStr); if(exi_bba_exists()) { sprintf(topStr,"IP: %s", net_initialized ? bba_ip:"Not Available"); } else { sprintf(topStr,"IP: Not Available"); } WriteFont(270, 110, topStr); sprintf(topStr,"Component Cable Plugged in: %s",VIDEO_HaveComponentCable()?"Yes":"No"); WriteFont(30, 140, topStr); if(usb_isgeckoalive(0)||usb_isgeckoalive(1)) { sprintf(topStr,"USB Gecko: Installed in %s",usb_isgeckoalive(0)?"Slot A":"Slot B"); } else { sprintf(topStr,"USB Gecko: Not Present"); } WriteFont(30, 170, topStr); if (!deviceHandler_initial) { sprintf(topStr, "Current Device: No Device Selected"); } else if(deviceHandler_initial == &initial_SD0 || deviceHandler_initial == &initial_SD1) { int slot = (deviceHandler_initial->name[2] == 'b'); sprintf(topStr, "Current Device: %s Card in %s @ %s",!SDHCCard?"SDHC":"SD",!slot?"Slot A":"Slot B",!swissSettings.exiSpeed?"16Mhz":"32Mhz"); } else if(deviceHandler_initial == &initial_DVD) { sprintf(topStr, "Current Device: %s DVD Disc",dvdDiscTypeStr); } else if(deviceHandler_initial == &initial_IDE0 || deviceHandler_initial == &initial_IDE1) { int slot = (deviceHandler_initial->name[3] == 'b'); sprintf(topStr, "Current Device: %d GB HDD in %s",ataDriveInfo.sizeInGigaBytes,!slot?"Slot A":"Slot B"); } else if(deviceHandler_initial == &initial_Qoob) { sprintf(topStr, "Current Device: Qoob IPL Replacement"); } else if(deviceHandler_initial == &initial_WODE) { sprintf(topStr, "Current Device: Wode Jukebox"); } else if(deviceHandler_initial == &initial_CARDA || deviceHandler_initial == &initial_CARDB) { sprintf(topStr, "Current Device: Memory Card in %s",!deviceHandler_initial->fileBase?"Slot A":"Slot B"); } else if(deviceHandler_initial == &initial_USBGecko) { sprintf(topStr, "Current Device: USB Gecko"); } else if(deviceHandler_initial == &initial_WKF) { sprintf(topStr, "Current Device: Wiikey Fusion"); } else if(deviceHandler_initial == &initial_SYS) { sprintf(topStr, "Current Device: System"); } WriteFont(30, 200, topStr); } else if(page_num == 2) { WriteFont(30, 65, "Credits (3/3):"); WriteFontStyled(640/2, 115, "Swiss ver 0.4", 1.0f, true, defaultColor); WriteFontStyled(640/2, 140, "by emu_kidid 2015", 0.75f, true, defaultColor); sprintf(txtbuffer, "Commit %s Revision %s SD Gecko Slot B Cheats Mod", GITREVISION, GITVERSION); WriteFontStyled(640/2, 165, txtbuffer, 0.75f, true, defaultColor); WriteFontStyled(640/2, 210, "Thanks to", 0.75f, true, defaultColor); WriteFontStyled(640/2, 228, "Testers & libOGC/dkPPC authors", 0.75f, true, defaultColor); WriteFontStyled(640/2, 246, "sepp256 for GX / FIX94 for Audio Streaming", 0.75f, true, defaultColor); WriteFontStyled(640/2, 264, "Extrems for video patches / Megalomaniac for builds", 0.75f, true, defaultColor); WriteFontStyled(640/2, 282, "Fishaman P for cheats support with all devices", 0.75f, true, defaultColor); WriteFontStyled(640/2, 318, "Web/Support http://www.gc-forever.com/", 0.75f, true, defaultColor); WriteFontStyled(640/2, 336, "Source at https://github.com/emukidid/swiss-gc", 0.75f, true, defaultColor); WriteFontStyled(640/2, 354, "Visit us at #gc-forever on EFNet", 0.75f, true, defaultColor); } if(page_num != 2) { WriteFont(520, 390, "->"); } if(page_num != 0) { WriteFont(100, 390, "<-"); } WriteFontStyled(640/2, 400, "Press A to return", 1.0f, true, defaultColor); DrawFrameFinish(); }