void DrawArgsSelector(char *fileName) { Parameters* params = getParameters(); int param_selection = 0; int params_per_page = 6; while ((PAD_ButtonsHeld(0) & PAD_BUTTON_A)){ VIDEO_WaitVSync (); } while(1) { doBackdrop(); DrawEmptyBox(20,60, vmode->fbWidth-20, 460, COLOR_BLACK); sprintf(txtbuffer, "%s Parameters:", fileName); WriteFontStyled(25, 62, txtbuffer, GetTextScaleToFitInWidth(txtbuffer, vmode->fbWidth-50), false, defaultColor); int j = 0; int current_view_start = MIN(MAX(0,param_selection-params_per_page/2),MAX(0,params->num_params-params_per_page)); int current_view_end = MIN(params->num_params, MAX(param_selection+params_per_page/2,params_per_page)); int scrollBarHeight = 90+(params_per_page*20); int scrollBarTabHeight = (int)((float)scrollBarHeight/(float)params->num_params); DrawVertScrollBar(vmode->fbWidth-45, 120, 25, scrollBarHeight, (float)((float)param_selection/(float)(params->num_params-1)),scrollBarTabHeight); for(j = 0; current_view_start<current_view_end; ++current_view_start,++j) { drawParameterForArgsSelector(¶ms->parameters[current_view_start], 25, 120+j*35, current_view_start==param_selection); } // Write about the default if there is any DrawTransparentBox( 35, 350, vmode->fbWidth-35, 400); WriteFontStyled(33, 345, "Default values will be used by the DOL being loaded if a", 0.8f, false, defaultColor); WriteFontStyled(33, 365, "parameter is not enabled. Please check the documentation", 0.8f, false, defaultColor); WriteFontStyled(33, 385, "for this DOL if you are unsure of the default values.", 0.8f, false, defaultColor); WriteFontStyled(640/2, 440, "(A) Toggle Param - (Start) Load the DOL", 1.0f, true, defaultColor); DrawFrameFinish(); while (!(PAD_ButtonsHeld(0) & (PAD_BUTTON_RIGHT|PAD_BUTTON_LEFT|PAD_BUTTON_UP|PAD_BUTTON_DOWN|PAD_BUTTON_START|PAD_BUTTON_A))) { VIDEO_WaitVSync (); } u16 btns = PAD_ButtonsHeld(0); if((btns & (PAD_BUTTON_RIGHT|PAD_BUTTON_LEFT)) && params->parameters[param_selection].enable) { int curValIdx = params->parameters[param_selection].currentValueIdx; int maxValIdx = params->parameters[param_selection].num_values; curValIdx = btns & PAD_BUTTON_LEFT ? ((--curValIdx < 0) ? maxValIdx-1 : curValIdx):((curValIdx + 1) % maxValIdx); params->parameters[param_selection].currentValueIdx = curValIdx; } if(btns & (PAD_BUTTON_UP|PAD_BUTTON_DOWN)) { param_selection = btns & PAD_BUTTON_UP ? ((--param_selection < 0) ? params->num_params-1 : param_selection) :((param_selection + 1) % params->num_params); } if(btns & PAD_BUTTON_A) { params->parameters[param_selection].enable ^= 1; } if(btns & PAD_BUTTON_START) { break; } while (PAD_ButtonsHeld(0) & (PAD_BUTTON_RIGHT|PAD_BUTTON_LEFT|PAD_BUTTON_UP|PAD_BUTTON_DOWN|PAD_BUTTON_START|PAD_BUTTON_A)) { VIDEO_WaitVSync (); } } }
// Checks if devices are available, prints name of device being detected for slow init devices void populateDeviceAvailability() { DrawFrameStart(); DrawMessageBox(D_INFO, "Detecting devices ...\nThis can be skipped by holding B next time"); DrawFrameFinish(); if(PAD_ButtonsHeld(0) & PAD_BUTTON_B) { deviceHandler_setAllDevicesAvailable(); return; } const DISC_INTERFACE* carda = &__io_gcsda; const DISC_INTERFACE* cardb = &__io_gcsdb; // DVD deviceHandler_setDeviceAvailable(DVD_DISC, swissSettings.hasDVDDrive); // SD Gecko DrawFrameStart(); DrawMessageBox(D_INFO, "Detecting devices [SD] ...\nThis can be skipped by holding B next time"); DrawFrameFinish(); deviceHandler_setDeviceAvailable(SD_CARD, carda->isInserted() || cardb->isInserted()); // IDE-EXI DrawFrameStart(); DrawMessageBox(D_INFO, "Detecting devices [IDE-EXI] ...\nThis can be skipped by holding B next time"); DrawFrameFinish(); deviceHandler_setDeviceAvailable(IDEEXI, ide_exi_inserted(0) || ide_exi_inserted(1)); // Qoob deviceHandler_setDeviceAvailable(QOOB_FLASH, 0); // Hidden by default, add auto detect at some point // WODE deviceHandler_setDeviceAvailable(WODE, 0); // Hidden by default, add auto detect at some point // Memory card DrawFrameStart(); DrawMessageBox(D_INFO, "Detecting devices [Memory Card] ...\nThis can be skipped by holding B next time"); DrawFrameFinish(); deviceHandler_setDeviceAvailable(MEMCARD, (initialize_card(0)==CARD_ERROR_READY) || (initialize_card(1)==CARD_ERROR_READY)); // WKF/WASP DrawFrameStart(); DrawMessageBox(D_INFO, "Detecting devices [WKF/WASP] ...\nThis can be skipped by holding B next time"); DrawFrameFinish(); deviceHandler_setDeviceAvailable(WKF, swissSettings.hasDVDDrive && (__wkfSpiReadId() != 0 && __wkfSpiReadId() != 0xFFFFFFFF)); // USB Gecko deviceHandler_setDeviceAvailable(USBGECKO, usb_isgeckoalive(1)); // BBA/SAMBA deviceHandler_setDeviceAvailable(SAMBA, exi_bba_exists()); // System, always there deviceHandler_setDeviceAvailable(SYS, 1); }
void load_config(int forceSlot) { // Try to open up the config .ini in case it hasn't been opened already (SD, IDE-EXI only) if(!config_init(forceSlot)) { if(curDevice == SD_CARD || curDevice == IDEEXI || forceSlot) { if(!config_create(forceSlot)) { DrawFrameStart(); DrawMessageBox(D_INFO,"Failed to create configuration file!"); DrawFrameFinish(); sleep(1); } } } else { DrawFrameStart(); sprintf(txtbuffer,"Loaded %i entries from the config file",config_get_count()); DrawMessageBox(D_INFO,txtbuffer); DrawFrameFinish(); memcpy(&swissSettings, config_get_swiss_settings(), sizeof(SwissSettings)); } }
int deviceHandler_USBGecko_init(file_handle* file) { DrawFrameStart(); DrawMessageBox(D_INFO,"Looking for USBGecko in Slot B"); DrawFrameFinish(); if(usb_isgeckoalive(1)) { int retries = 1000; DrawFrameStart(); DrawMessageBox(D_INFO,"Waiting for PC ..."); DrawFrameFinish(); usb_flush(1); usbgecko_lock_file(0); // Wait for the PC and retry 1000 times while(!usbgecko_pc_ready() && retries) { VIDEO_WaitVSync(); retries--; } if(!retries) { DrawFrameStart(); DrawMessageBox(D_INFO,"Couldn't find PC!"); DrawFrameFinish(); sleep(5); return 0; // Didn't find the PC } else { DrawFrameStart(); DrawMessageBox(D_INFO,"Found PC !!"); DrawFrameFinish(); return 1; } } else { return 0; } }
int deviceHandler_USBGecko_readDir(file_handle* ffile, file_handle** dir, unsigned int type){ // Set everything up to read int num_entries = 0, i = 0; file_handle *entry = NULL; if(strlen(ffile->name)!=1) { i = num_entries = 1; *dir = malloc( num_entries * sizeof(file_handle) ); memset(*dir,0,sizeof(file_handle) * num_entries); (*dir)[0].fileAttrib = IS_SPECIAL; strcpy((*dir)[0].name, ".."); } DrawFrameStart(); DrawMessageBox(D_INFO,"Read directory!"); DrawFrameFinish(); // Read each entry of the directory int res = usbgecko_open_dir(&ffile->name[0]); if(!res) return -1; while( (entry = usbgecko_get_entry()) != NULL ){ // Make sure we have room for this one if(i == num_entries) { ++num_entries; *dir = realloc( *dir, num_entries * sizeof(file_handle) ); } sprintf((*dir)[i].name, "%s", entry->name); (*dir)[i].offset = 0; (*dir)[i].size = entry->size; (*dir)[i].fileAttrib = entry->fileAttrib; (*dir)[i].fp = 0; (*dir)[i].fileBase = 0; (*dir)[i].meta = 0; ++i; } return num_entries; }
int DrawYesNoDialog(char *message) { int sel = 0; while ((PAD_ButtonsHeld(0) & PAD_BUTTON_A)){ VIDEO_WaitVSync (); } while(1) { doBackdrop(); DrawEmptyBox(75,190, vmode->fbWidth-78, 330, COLOR_BLACK); WriteFontStyled(640/2, 215, message, 1.0f, true, defaultColor); DrawSelectableButton(100, 280, -1, 310, "Yes", (sel==1) ? B_SELECTED:B_NOSELECT,-1); DrawSelectableButton(380, 280, -1, 310, "No", (!sel) ? B_SELECTED:B_NOSELECT,-1); DrawFrameFinish(); while (!(PAD_ButtonsHeld(0) & PAD_BUTTON_RIGHT) && !(PAD_ButtonsHeld(0) & PAD_BUTTON_LEFT) && !(PAD_ButtonsHeld(0) & PAD_BUTTON_B)&& !(PAD_ButtonsHeld(0) & PAD_BUTTON_A)) { VIDEO_WaitVSync (); } u16 btns = PAD_ButtonsHeld(0); if((btns & PAD_BUTTON_RIGHT) || (btns & PAD_BUTTON_LEFT)) { sel^=1; } if((btns & PAD_BUTTON_A) || (btns & PAD_BUTTON_B)) break; while (!(!(PAD_ButtonsHeld(0) & PAD_BUTTON_RIGHT) && !(PAD_ButtonsHeld(0) & PAD_BUTTON_LEFT) && !(PAD_ButtonsHeld(0) & PAD_BUTTON_B) && !(PAD_ButtonsHeld(0) & PAD_BUTTON_A))) { VIDEO_WaitVSync (); } } while ((PAD_ButtonsHeld(0) & PAD_BUTTON_A)){ VIDEO_WaitVSync (); } return sel; }
/* 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]; }
void DrawCheatsSelector(char *fileName) { CheatEntries* cheats = getCheats(); int cheat_selection = 0; int cheats_per_page = 6; while ((PAD_ButtonsHeld(0) & PAD_BUTTON_A)){ VIDEO_WaitVSync (); } while(1) { doBackdrop(); DrawEmptyBox(20,60, vmode->fbWidth-20, 460, COLOR_BLACK); sprintf(txtbuffer, "%s Cheats:", fileName); WriteFontStyled(25, 62, txtbuffer, GetTextScaleToFitInWidth(txtbuffer, vmode->fbWidth-50), false, defaultColor); int j = 0; int current_view_start = MIN(MAX(0,cheat_selection-cheats_per_page/2),MAX(0,cheats->num_cheats-cheats_per_page)); int current_view_end = MIN(cheats->num_cheats, MAX(cheat_selection+cheats_per_page/2,cheats_per_page)); int scrollBarHeight = 90+(cheats_per_page*20); int scrollBarTabHeight = (int)((float)scrollBarHeight/(float)cheats->num_cheats); DrawVertScrollBar(vmode->fbWidth-45, 120, 25, scrollBarHeight, (float)((float)cheat_selection/(float)(cheats->num_cheats-1)),scrollBarTabHeight); for(j = 0; current_view_start<current_view_end; ++current_view_start,++j) { drawCheatForCheatsSelector(&cheats->cheat[current_view_start], 25, 120+j*35, current_view_start==cheat_selection); } // Write about how many cheats are enabled DrawTransparentBox( 35, 350, vmode->fbWidth-35, 410); WriteFontStyled(33, 345, "Space taken by cheats:", 0.8f, false, defaultColor); GXColor noColor = (GXColor) {0,0,0,0}; //blank GXColor borderColor = (GXColor) {200,200,200,GUI_MSGBOX_ALPHA}; //silver GXColor progressBarColor = (GXColor) {255,128,0,GUI_MSGBOX_ALPHA}; //orange float multiplier = (float)getEnabledCheatsSize() / (float)kenobi_get_maxsize(); DrawSimpleBox( 33, 370, vmode->fbWidth-66, 20, 0, noColor, borderColor); DrawSimpleBox( 33, 370, (int)((vmode->fbWidth-66)*multiplier), 20, 0, progressBarColor, noColor); sprintf(txtbuffer, "WiiRD Debug %s", swissSettings.wiirdDebug ? "Enabled":"Disabled"); WriteFontStyled(33, 395, txtbuffer, 0.8f, false, defaultColor); WriteFontStyled(640/2, 440, "(A) Toggle Cheat - (X) WiiRD Debug - (B) Return", 0.9f, true, defaultColor); DrawFrameFinish(); while (!(PAD_ButtonsHeld(0) & (PAD_BUTTON_UP|PAD_BUTTON_DOWN|PAD_BUTTON_B|PAD_BUTTON_A|PAD_BUTTON_X))) { VIDEO_WaitVSync (); } u16 btns = PAD_ButtonsHeld(0); if(btns & (PAD_BUTTON_UP|PAD_BUTTON_DOWN)) { cheat_selection = btns & PAD_BUTTON_UP ? ((--cheat_selection < 0) ? cheats->num_cheats-1 : cheat_selection) :((cheat_selection + 1) % cheats->num_cheats); } if(btns & PAD_BUTTON_A) { cheats->cheat[cheat_selection].enabled ^= 1; if(getEnabledCheatsSize() > kenobi_get_maxsize()) // No room cheats->cheat[cheat_selection].enabled = 0; } if(btns & PAD_BUTTON_X) { swissSettings.wiirdDebug ^=1; } if(btns & PAD_BUTTON_B) { break; } while (PAD_ButtonsHeld(0) & (PAD_BUTTON_UP|PAD_BUTTON_DOWN|PAD_BUTTON_B|PAD_BUTTON_A|PAD_BUTTON_X)) { VIDEO_WaitVSync (); } } }
// Returns the number of filesToPatch and fills out the filesToPatch array passed in (pre-allocated) int parse_gcm(file_handle *file, ExecutableFile *filesToPatch) { DiskHeader header; char *FST; char filename[256]; int numFiles = 0; // Grab disc header memset(&header,0,sizeof(DiskHeader)); deviceHandler_seekFile(file,0,DEVICE_HANDLER_SEEK_SET); if(deviceHandler_readFile(file,&header,sizeof(DiskHeader)) != sizeof(DiskHeader)) { return -1; } // Alloc and read FST FST=(char*)memalign(32,header.FSTSize); if(!FST) { return -1; } deviceHandler_seekFile(file,header.FSTOffset,DEVICE_HANDLER_SEEK_SET); if(deviceHandler_readFile(file,FST,header.FSTSize) != header.FSTSize) { free(FST); return -1; } u32 entries=*(unsigned int*)&FST[8]; u32 string_table_offset=FST_ENTRY_SIZE*entries; int i; // go through every entry for (i=1;i<entries;i++) { u32 offset=i*0x0c; if(FST[offset]==0) //skip directories { u32 file_offset,size = 0; u32 filename_offset=((*(unsigned int*)&FST[offset]) & 0x00FFFFFF); memset(&filename[0],0,256); memcpy(&filename[0],&FST[string_table_offset+filename_offset],255); memcpy(&file_offset,&FST[offset+4],4); memcpy(&size,&FST[offset+8],4); if(endsWith(filename,".dol") || endsWith(filename,".DOL")) { filesToPatch[numFiles].offset = file_offset; filesToPatch[numFiles].size = size; filesToPatch[numFiles].type = PATCH_DOL; memcpy(&filesToPatch[numFiles].name,&filename[0],64); numFiles++; } if((endsWith(filename,".elf") || endsWith(filename,".ELF")) && size < 12*1024*1024) { filesToPatch[numFiles].offset = file_offset; filesToPatch[numFiles].size = size; filesToPatch[numFiles].type = PATCH_ELF; memcpy(&filesToPatch[numFiles].name,&filename[0],64); numFiles++; } if(strstr(filename,"execD.img")) { filesToPatch[numFiles].offset = file_offset; filesToPatch[numFiles].size = size; filesToPatch[numFiles].type = PATCH_LOADER; memcpy(&filesToPatch[numFiles].name,&filename[0],64); numFiles++; } if(endsWith(filename,".tgc") || endsWith(filename,".TGC")) { // Go through all the TGC's internal files ExecutableFile *filesInTGCToPatch = memalign(32, sizeof(ExecutableFile)*32); int numTGCFilesToPatch = parse_tgc(file, filesInTGCToPatch, file_offset), j; for(j=0; j<numTGCFilesToPatch; j++) { memcpy(&filesToPatch[numFiles], &filesInTGCToPatch[j], sizeof(ExecutableFile)); numFiles++; } free(filesInTGCToPatch); } } } free(FST); // Some games contain a single "default.dol", these do not need // pre-patching because they are what is actually pointed to by the apploader (and loaded by us) if(numFiles==1 && (!strcmp(&filesToPatch[0].name[0],"default.dol"))) { numFiles = 0; } // Multi-DOL games may re-load the main DOL, so make sure we patch it too. if(numFiles>0) { DOLHEADER dolhdr; u32 main_dol_size = 0; // Calc size deviceHandler_seekFile(file,GCMDisk.DOLOffset,DEVICE_HANDLER_SEEK_SET); if(deviceHandler_readFile(file,&dolhdr,DOLHDRLENGTH) != DOLHDRLENGTH) { DrawFrameStart(); DrawMessageBox(D_FAIL, "Failed to read Main DOL Header"); DrawFrameFinish(); while(1); } for (i = 0; i < MAXTEXTSECTION; i++) { if (dolhdr.textLength[i] + dolhdr.textOffset[i] > main_dol_size) main_dol_size = dolhdr.textLength[i] + dolhdr.textOffset[i]; } for (i = 0; i < MAXDATASECTION; i++) { if (dolhdr.dataLength[i] + dolhdr.dataOffset[i] > main_dol_size) main_dol_size = dolhdr.dataLength[i] + dolhdr.dataOffset[i]; } filesToPatch[numFiles].offset = GCMDisk.DOLOffset; filesToPatch[numFiles].size = main_dol_size; filesToPatch[numFiles].type = PATCH_DOL; sprintf(filesToPatch[numFiles].name, "Main DOL"); numFiles++; // Patch the apploader too! // Calc Apploader trailer size u32 appldr_info[2]; deviceHandler_seekFile(file,0x2454,DEVICE_HANDLER_SEEK_SET); if(deviceHandler_readFile(file,&appldr_info,8) != 8) { DrawFrameStart(); DrawMessageBox(D_FAIL, "Failed to read Apploader info"); DrawFrameFinish(); while(1); } filesToPatch[numFiles].size = appldr_info[1]; filesToPatch[numFiles].offset = 0x2460 + appldr_info[0]; filesToPatch[numFiles].type = PATCH_LOADER; sprintf(filesToPatch[numFiles].name, "Apploader Trailer"); numFiles++; } return numFiles; }
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; }
void settings_draw_page(int page_num, int option, file_handle *file) { doBackdrop(); DrawEmptyBox(20,60, vmode->fbWidth-20, 460, COLOR_BLACK); // Save Settings to current device (**Shown on all tabs**) /** Global Settings (Page 1/) */ // IPL/Game Language [English/German/French/Spanish/Italian/Dutch] // IPL/Game Audio [Mono/Stereo] // SD/IDE Speed [16/32 MHz] // Swiss Video Mode [576i (PAL 50Hz), 480i (NTSC 60Hz), 480p (NTSC 60Hz)] // Stop DVD Motor on startup [Yes/No] /** Advanced Settings (Page 2/) */ // Enable USB Gecko Debug via Slot B [Yes/No] // Force No DVD Drive Mode [Yes/No] // Hide Unknown file types [Yes/No] // TO BE IMPLEMENTED /** Current Game Settings - only if a valid GCM file is highlighted (Page 3/) */ // Force Video Mode [576i (PAL 50Hz), 480i (NTSC 60Hz), 480p (NTSC 60Hz), Auto] // Mute Audio Streaming [Yes/No] // Try to mute audio stutter [Yes/No] if(!page_num) { WriteFont(30, 65, "Global Settings (1/3):"); WriteFontStyled(30, 120, "IPL/Game Language:", 1.0f, false, defaultColor); DrawSelectableButton(400, 120, -1, 150, getSramLang(swissSettings.sramLanguage), option == 0 ? B_SELECTED:B_NOSELECT,-1); WriteFontStyled(30, 160, "IPL/Game Audio:", 1.0f, false, defaultColor); DrawSelectableButton(400, 160, -1, 190, swissSettings.sramStereo ? "Stereo":"Mono", option == 1 ? B_SELECTED:B_NOSELECT,-1); WriteFontStyled(30, 200, "SD/IDE Speed:", 1.0f, false, defaultColor); DrawSelectableButton(400, 200, -1, 230, swissSettings.exiSpeed ? "32 MHz":"16 MHz", option == 2 ? B_SELECTED:B_NOSELECT,-1); WriteFontStyled(30, 240, "Swiss Video Mode:", 1.0f, false, defaultColor); DrawSelectableButton(400, 240, -1, 270, uiVModeStr[swissSettings.uiVMode], option == 3 ? B_SELECTED:B_NOSELECT,-1); } else if(page_num == 1) { WriteFont(30, 65, "Advanced Settings (2/3):"); WriteFontStyled(30, 120, "Enable USB Gecko Debug via Slot B:", 1.0f, false, defaultColor); DrawSelectableButton(500, 120, -1, 150, swissSettings.debugUSB ? "Yes":"No", option == 0 ? B_SELECTED:B_NOSELECT,-1); WriteFontStyled(30, 160, "Force No DVD Drive Mode:", 1.0f, false, defaultColor); DrawSelectableButton(500, 160, -1, 190, swissSettings.hasDVDDrive ? "No":"Yes", option == 1 ? B_SELECTED:B_NOSELECT,-1); WriteFontStyled(30, 200, "Hide Unknown file types:", 1.0f, false, defaultColor); DrawSelectableButton(500, 200, -1, 230, swissSettings.hideUnknownFileTypes ? "Yes":"No", option == 2 ? B_SELECTED:B_NOSELECT,-1); WriteFontStyled(30, 240, "Stop DVD Motor on startup:", 1.0f, false, defaultColor); DrawSelectableButton(500, 240, -1, 270, swissSettings.stopMotor ? "Yes":"No", option == 3 ? B_SELECTED:B_NOSELECT,-1); WriteFontStyled(30, 280, "Enable WiiRD debugging in Games:", 1.0f, false, defaultColor); DrawSelectableButton(500, 280, -1, 310, swissSettings.wiirdDebug ? "Yes":"No", option == 4 ? B_SELECTED:B_NOSELECT,-1); WriteFontStyled(30, 320, "Enable File Management:", 1.0f, false, defaultColor); DrawSelectableButton(500, 320, -1, 350, swissSettings.enableFileManagement ? "Yes":"No", option == 5 ? B_SELECTED:B_NOSELECT,-1); } else if(page_num == 2) { WriteFont(30, 65, "Current Game Settings (3/3):"); WriteFontStyled(30, 110, "Force Video Mode:", 1.0f, false, file != NULL ? defaultColor : disabledColor); DrawSelectableButton(480, 110, -1, 135, gameVModeStr[swissSettings.gameVMode], option == 0 ? B_SELECTED:B_NOSELECT,-1); WriteFontStyled(30, 140, "If Progressive, Soften:", 1.0f, false, file != NULL ? defaultColor : disabledColor); DrawSelectableButton(480, 140, -1, 165, softProgressiveStr[swissSettings.softProgressive], option == 1 ? B_SELECTED:B_NOSELECT,-1); WriteFontStyled(30, 170, "Force Widescreen:", 1.0f, false, file != NULL ? defaultColor : disabledColor); DrawSelectableButton(480, 170, -1, 195, forceWidescreenStr[swissSettings.forceWidescreen], option == 2 ? B_SELECTED:B_NOSELECT,-1); WriteFontStyled(30, 200, "Force Anisotropy:", 1.0f, false, file != NULL ? defaultColor : disabledColor); DrawSelectableButton(480, 200, -1, 225, swissSettings.forceAnisotropy ? "Yes":"No", option == 3 ? B_SELECTED:B_NOSELECT,-1); WriteFontStyled(30, 230, "Disable Audio Streaming:", 1.0f, false, file != NULL ? defaultColor : disabledColor); DrawSelectableButton(480, 230, -1, 255, swissSettings.muteAudioStreaming ? "Yes":"No", option == 4 ? B_SELECTED:B_NOSELECT,-1); WriteFontStyled(30, 260, "Force Encoding:", 1.0f, false, file != NULL ? defaultColor : disabledColor); DrawSelectableButton(480, 260, -1, 285, forceEncodingStr[swissSettings.forceEncoding], option == 5 ? B_SELECTED:B_NOSELECT,-1); } if(page_num != 0) { DrawSelectableButton(40, 390, -1, 420, "Back", option == settings_count_pp[page_num]-(page_num != 2 ? 3:2) ? B_SELECTED:B_NOSELECT,-1); } if(page_num != 2) { DrawSelectableButton(510, 390, -1, 420, "Next", option == settings_count_pp[page_num]-2 ? B_SELECTED:B_NOSELECT,-1); } DrawSelectableButton(100, 425, -1, 455, "Save & Exit", option == settings_count_pp[page_num]-1 ? B_SELECTED:B_NOSELECT,-1); DrawSelectableButton(320, 425, -1, 455, "Discard & Exit", option == settings_count_pp[page_num] ? B_SELECTED:B_NOSELECT,-1); DrawFrameFinish(); }
int show_settings(file_handle *file, ConfigEntry *config) { int page = 0, option = 0; // Refresh SRAM in case user changed it from IPL refreshSRAM(); // Copy current settings to a temp copy in case the user cancels out memcpy((void*)&tempSettings,(void*)&swissSettings, sizeof(SwissSettings)); // Setup the settings for the current game if(config != NULL) { page = 2; } while (PAD_ButtonsHeld(0) & PAD_BUTTON_A) { VIDEO_WaitVSync (); } while(1) { settings_draw_page(page, option, file); while (!((PAD_ButtonsHeld(0) & PAD_BUTTON_RIGHT) || (PAD_ButtonsHeld(0) & PAD_BUTTON_LEFT) || (PAD_ButtonsHeld(0) & PAD_BUTTON_UP) || (PAD_ButtonsHeld(0) & PAD_BUTTON_DOWN) || (PAD_ButtonsHeld(0) & PAD_BUTTON_B) || (PAD_ButtonsHeld(0) & PAD_BUTTON_A) || (PAD_ButtonsHeld(0) & PAD_TRIGGER_R) || (PAD_ButtonsHeld(0) & PAD_TRIGGER_L))) { VIDEO_WaitVSync (); } u16 btns = PAD_ButtonsHeld(0); if(btns & PAD_BUTTON_RIGHT) { // If we're on a button (Back, Next, Save, Exit), allow left/right movement if((page != 1) && (option >= settings_count_pp[page]-2) && option < settings_count_pp[page]) { option++; } else if((page == 1) && (option >= settings_count_pp[page]-3) && option < settings_count_pp[page]) { option++; } else { settings_toggle(page, option, 1, file); } } if(btns & PAD_BUTTON_LEFT) { // If we're on a button (Back, Next, Save, Exit), allow left/right movement if((page != 1) && (option > settings_count_pp[page]-2)) { option--; } else if((page == 1) && (option > settings_count_pp[page]-3)) { option--; } else { settings_toggle(page, option, -1, file); } } if((btns & PAD_BUTTON_DOWN) && option < settings_count_pp[page]) option++; if((btns & PAD_BUTTON_UP) && option > 0) option--; if((btns & PAD_TRIGGER_R) && page < 2) { page++; option = 0; } if((btns & PAD_TRIGGER_L) && page > 0) { page--; option = 0; } if((btns & PAD_BUTTON_B)) option = settings_count_pp[page]; // Handle all options/buttons here if((btns & PAD_BUTTON_A)) { // Generic Save/Cancel/Back/Next button actions if(option == settings_count_pp[page]-1) { DrawFrameStart(); DrawMessageBox(D_INFO,"Saving changes!"); DrawFrameFinish(); // Change Swiss video mode if it was modified. if(tempSettings.uiVMode != swissSettings.uiVMode) { GXRModeObj *newmode = getModeFromSwissSetting(swissSettings.uiVMode); initialise_video(newmode); vmode = newmode; } // Save settings to SRAM sram = __SYS_LockSram(); sram->lang = swissSettings.sramLanguage; sram->flags = swissSettings.sramStereo ? (sram->flags|0x04):(sram->flags&~0x04); sram->flags = (swissSettings.sramVideo&0x03)|(sram->flags&~0x03); __SYS_UnlockSram(1); while(!__SYS_SyncSram()); // Update our .ini if(config != NULL) { config->gameVMode = swissSettings.gameVMode; config->softProgressive = swissSettings.softProgressive; config->muteAudioStreaming = swissSettings.muteAudioStreaming; config->forceWidescreen = swissSettings.forceWidescreen; config->forceAnisotropy = swissSettings.forceAnisotropy; config->forceEncoding = swissSettings.forceEncoding; } else { // Save the Swiss system settings since we're called from the main menu if((curDevice == SD_CARD)||(curDevice == IDEEXI)) { DrawFrameStart(); DrawMessageBox(D_INFO,"Saving Config ..."); DrawFrameFinish(); config_copy_swiss_settings(&swissSettings); if(config_update_file()) { DrawFrameStart(); DrawMessageBox(D_INFO,"Config Saved Successfully!"); DrawFrameFinish(); } else { DrawFrameStart(); DrawMessageBox(D_INFO,"Config Failed to Save!"); DrawFrameFinish(); } } } return 1; } if(option == settings_count_pp[page]) { // Exit without saving (revert) memcpy((void*)&swissSettings, (void*)&tempSettings, sizeof(SwissSettings)); return 0; } if((page != 2) && (option == settings_count_pp[page]-2)) { page++; option = 0; } if((page != 0) && (option == settings_count_pp[page]-(page != 2 ? 3:2))) { page--; option = 0; } } while ((PAD_ButtonsHeld(0) & PAD_BUTTON_RIGHT) || (PAD_ButtonsHeld(0) & PAD_BUTTON_LEFT) || (PAD_ButtonsHeld(0) & PAD_BUTTON_UP) || (PAD_ButtonsHeld(0) & PAD_BUTTON_DOWN) || (PAD_ButtonsHeld(0) & PAD_BUTTON_B) || (PAD_ButtonsHeld(0) & PAD_BUTTON_A) || (PAD_ButtonsHeld(0) & PAD_TRIGGER_R) || (PAD_ButtonsHeld(0) & PAD_TRIGGER_L)) { VIDEO_WaitVSync (); } } }
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(); }