void CreateTitleTMD(const char *path, struct dir_discHdr *hdr) { struct stat filestat; if (stat(path, &filestat) == 0) { gprintf("%s Exists!\n", path); return; } gprintf("Creating Game TMD: %s\n", path); wbfs_disc_t *disc = WBFS_OpenDisc(hdr->id, hdr->path); if (!disc) return; u8 *titleTMD = NULL; u32 tmd_size = wbfs_extract_file(disc, (char *) "TMD", (void **)&titleTMD); WBFS_CloseDisc(disc); if(!titleTMD) return; FILE *file = fopen(path, "wb"); if(file) { fwrite(titleTMD, 1, tmd_size, file); gprintf("Written Game TMD to: %s\n", path); fclose(file); } else gprintf("Openning %s failed returning %i\n", path, file); SAFE_FREE(titleTMD); }
s32 WBFS_CheckGame(u8 *discid) { wbfs_disc_t *disc = NULL; /* Try to open game disc */ disc = WBFS_OpenDisc(discid); if (disc) { /* Close disc */ WBFS_CloseDisc(disc); return 1; } return 0; }
s32 WBFS_GameSize(u8 *discid, f32 *size) { wbfs_disc_t *disc = NULL; u32 sectors; /* Open disc */ disc = WBFS_OpenDisc(discid); if (!disc) return -2; /* Get game size in sectors */ sectors = wbfs_disc_sector_used(disc, NULL); /* Copy value */ *size = (disc->p->wbfs_sec_sz / GB_SIZE) * sectors; /* Close disc */ WBFS_CloseDisc(disc); return 0; }
s32 WBFS_GameSize2(u8 *discid, u64 *comp_size, u64 *real_size) { wbfs_disc_t *disc = NULL; u32 sectors, real_sec; /* Open disc */ disc = WBFS_OpenDisc(discid); if (!disc) return -2; /* Get game size in sectors */ sectors = wbfs_disc_sector_used(disc, &real_sec); /* Copy value */ *comp_size = ((u64)disc->p->wbfs_sec_sz) * sectors; *real_size = ((u64)disc->p->wbfs_sec_sz) * real_sec; /* Close disc */ WBFS_CloseDisc(disc); return 0; }
void Menu_Boot() { struct discHdr *header; bool gc = false; header = &gameList[gameSelected]; s32 ret; struct Game_CFG_2 *game_cfg = NULL; /* Clear console */ if (!CFG.direct_launch) { Con_Clear(); } FgColor(CFG.color_header); printf_x(gt("Start this game?")); printf("\n\n"); DefaultColor(); game_cfg = CFG_find_game(header->id); // Get game size gc = header->magic == GC_MAGIC; bool do_skip = !CFG.confirm_start; /* SoundInfo snd; u8 banner_title[84]; memset(banner_title, 0, 84); memset(&snd, 0, sizeof(snd)); WBFS_Banner(header->id, &snd, banner_title, !do_skip, CFG_read_active_game_setting(header->id).write_playlog); */ if (do_skip) { goto skip_confirm; } printf("\n"); /* Show game info */ printf_("%s\n", get_title(header)); printf_("(%.6s)\n\n", header->id); __Menu_ShowGameInfo(true, header->id); /* load game info from XML */ printf("\n"); //Does DL warning apply to launching discs too? Not sure printf_h(gt("Press %s button to continue."), (button_names[CFG.button_confirm.num])); printf("\n"); printf_h(gt("Press %s button to go back."), (button_names[CFG.button_cancel.num])); if (!gc) { printf("\n"); printf_h(gt("Press %s button for options."), (button_names[CFG.button_other.num])); } printf("\n\n"); __console_flush(0); // play banner sound /* if (snd.dsp_data) { SND_PauseVoice(0, 1); // pause mp3 int fmt = (snd.channels == 2) ? VOICE_STEREO_16BIT : VOICE_MONO_16BIT; SND_SetVoice(1, fmt, snd.rate, 0, snd.dsp_data, snd.size, 255,255, //volume,volume, NULL); //DataTransferCallback } */ /* Wait for user answer */ u32 buttons; for (;;) { buttons = Wpad_WaitButtons(); if (buttons & CFG.button_confirm.mask) break; if (buttons & CFG.button_cancel.mask) break; if (!gc && (buttons & CFG.button_other.mask)) break; if (buttons & CFG.button_exit.mask) break; } /* // stop banner sound, resume mp3 if (snd.dsp_data) { SND_StopVoice(1); SAFE_FREE(snd.dsp_data); if (buttons & CFG.button_confirm.mask) { SND_ChangeVolumeVoice(0, 0, 0); } SND_PauseVoice(0, 0); } */ if (buttons & CFG.button_cancel.mask) goto close; if (buttons & CFG.button_exit.mask) { Handle_Home(0); return; } if (!gc && (buttons & CFG.button_other.mask)) { Menu_Boot_Options(header); return; } // A button: continue to boot skip_confirm: if (game_cfg) { CFG.game = game_cfg->curr; } if (CFG.game.write_playlog && set_playrec(header->id, (u8 *) header->title) < 0) { // banner_title) < 0) { printf_(gt("Error storing playlog file.\nStart from the Wii Menu to fix.")); printf("\n"); printf_h(gt("Press %s button to exit."), (button_names[CFG.button_exit.num])); printf("\n"); if (!Menu_Confirm(0)) return; } WBFS_OpenDisc(header->id, header->game_idx); printf("\n"); printf_x(gt("Booting Wii game, please wait...")); printf("\n\n"); // load stuff before ios reloads & services close ocarina_load_code(header->id); load_wip_patches(header->id); // Close the wode stuff WBFS_Close(); use_dvdx = 0; Disc_Init(); ret = Disc_Wait(); if (ret < 0) { printf("Cannot mount newly selected image: %d\n", ret); } Disc_Open(); // stop services (music, gui) Services_Close(); setPlayStat(header->id); //I'd rather do this after the check, but now you unmount fat before that ;) Fat_UnmountAll(); if (gc) { WII_Initialize(); ret = WII_LaunchTitle(0x0000000100000100ULL); } else { switch(CFG.game.language) { // 0 = CFG_LANG_CONSOLE case 0: configbytes[0] = 0xCD; break; case 1: configbytes[0] = 0x00; break; case 2: configbytes[0] = 0x01; break; case 3: configbytes[0] = 0x02; break; case 4: configbytes[0] = 0x03; break; case 5: configbytes[0] = 0x04; break; case 6: configbytes[0] = 0x05; break; case 7: configbytes[0] = 0x06; break; case 8: configbytes[0] = 0x07; break; case 9: configbytes[0] = 0x08; break; case 10: configbytes[0] = 0x09; break; } /* Boot Wii disc */ ret = Disc_WiiBoot(); } printf_(gt("Returned! (ret = %d)"), ret); printf("\n"); printf("\n"); printf_(gt("Press any button to exit...")); printf("\n"); /* Wait for button */ Wpad_WaitButtonsCommon(); exit(0); close: WDVD_StopMotor(); header = &gameList[gameSelected]; Gui_DrawCover(header->id); // Reopen the wode WBFS_Init(); return; }
s32 __SDHC_Ioctlv(u32 cmd, ioctlv *vector, u32 inlen, u32 iolen) { s32 ret = IPC_EINVAL; /* Invalidate cache */ InvalidateVector(vector, inlen, iolen); /* Parse IOCTLV command */ switch (cmd) { /** Initialize SDHC **/ case IOCTL_SDHC_INIT: { /* Initialize SDIO */ ret = !sdio_Startup(); break; } /** Read sectors **/ case IOCTL_SDHC_READ: { u32 sector = *(u32 *)(vector[0].data); u32 numSectors = *(u32 *)(vector[1].data); void *buffer = vector[2].data; /* Read sectors */ ret = !sdio_ReadSectors(sector, numSectors, buffer); break; } /** Write sectors **/ case IOCTL_SDHC_WRITE: { u32 sector = *(u32 *)(vector[0].data); u32 numSectors = *(u32 *)(vector[1].data); void *buffer = vector[2].data; /* Write sectors */ ret = !sdio_WriteSectors(sector, numSectors, buffer); break; } /** Check for SD card **/ case IOCTL_SDHC_ISINSERTED: { /* Check if SD card is inserted */ ret = !sdio_IsInserted(); break; } /** Open WBFS disc **/ case IOCTL_WBFS_OPEN_DISC: { u8 *discid = (u8 *)(vector[0].data); /* Open WBFS disc */ ret = WBFS_OpenDisc(discid); break; } /** Read WBFS disc **/ case IOCTL_WBFS_READ_DISC: { u32 offset = *(u32 *)(vector[0].data); u32 len = *(u32 *)(vector[1].data); void *buffer = vector[2].data; /* Read WBFS disc */ ret = WBFS_Read(buffer, len, offset); if (ret) ret = 0x8000; break; } default: break; } /* Flush cache */ FlushVector(vector, inlen, iolen); return ret; }
void WDMMenu::CheckGameFiles(const struct discHdr * header) { wbfs_disc_t *disc = WBFS_OpenDisc((u8 *) header->id); if (!disc) { WindowPrompt(tr( "ERROR:" ), tr( "Could not open Disc" ), tr( "OK" )); return; } wiidisc_t *wdisc = wd_open_disc((int(*)(void *, u32, u32, void *)) wbfs_disc_read, disc); if (!wdisc) { WindowPrompt(tr( "ERROR:" ), tr( "Could not open Disc" ), tr( "OK" )); return; } FST_ENTRY * fstbuffer = (FST_ENTRY *) wd_extract_file(wdisc, ONLY_GAME_PARTITION, (char*) "FST"); if (!fstbuffer) { WindowPrompt(tr( "ERROR:" ), tr( "Not enough free memory." ), tr( "OK" )); return; } wd_close_disc(wdisc); WBFS_CloseDisc(disc); int position = 0; vector<pair<int, string> > FilesNotInWDM; for(int i = 0; i < wdmFile->size(); ++i) { if(stringcompare(wdmFile->GetDolName(i), "main") == true) { DOLOffsetList.push_back(pair<int, int>(0, wdmFile->GetParameter(i))); Options->SetName(position, "%i.", position+1); Options->SetValue(position, wdmFile->GetReplaceName(i)); position++; } } for (u32 i = 1; i < fstbuffer[0].filelen; i++) { //don't add files that aren't .dol to the list const char * filename = fstfiles(fstbuffer, i); const char * fileext = NULL; if(filename) fileext = strrchr(filename, '.'); if (fileext && strcasecmp(fileext, ".dol") == 0) { char NameCpy[strlen(filename)+1]; strcpy(NameCpy, filename); char *extension = strrchr(NameCpy, '.'); if(extension) *extension = 0; int j; for(j = 0; j < wdmFile->size(); ++j) { if(stringcompare(wdmFile->GetDolName(j), NameCpy) == true) { DOLOffsetList.push_back(pair<int, int>(i, wdmFile->GetParameter(j))); Options->SetName(position, "%i.", position+1); Options->SetValue(position, wdmFile->GetReplaceName(j)); position++; break; } } if(j == wdmFile->size()) FilesNotInWDM.push_back(pair<int, string>(i, filename)); } } for(u32 i = 0; i < FilesNotInWDM.size(); ++i) { DOLOffsetList.push_back(pair<int, int>(FilesNotInWDM[i].first, 1)); Options->SetName(position, "%i.", position+1); Options->SetValue(position, FilesNotInWDM[i].second.c_str()); position++; } free(fstbuffer); }
/******************************************************************************** *Disk Browser *********************************************************************************/ int DiscBrowse(const char * GameID, char * alternatedname, int alternatedname_size) { gprintf("\nDiscBrowser() started"); bool exit = false; int ret = -1, choice; HaltGui(); gprintf("WBFS_OpenDisc\n"); wbfs_disc_t *disc = WBFS_OpenDisc((u8 *) GameID); if (!disc) { ResumeGui(); WindowPrompt(tr( "ERROR:" ), tr( "Could not open Disc" ), tr( "OK" )); return ret; } gprintf("wd_open_disc\n"); wiidisc_t *wdisc = wd_open_disc((int(*)(void *, u32, u32, void *)) wbfs_disc_read, disc); if (!wdisc) { ResumeGui(); WindowPrompt(tr( "ERROR:" ), tr( "Could not open Disc" ), tr( "OK" )); return ret; } gprintf("wd_get_fst\n"); FST_ENTRY * fstbuffer = (FST_ENTRY *) wd_extract_file(wdisc, ONLY_GAME_PARTITION, (char *) "FST"); if (!fstbuffer) { ResumeGui(); WindowPrompt(tr( "ERROR:" ), tr( "Not enough free memory." ), tr( "OK" )); return -1; } gprintf("wd_close_disc\n"); wd_close_disc(wdisc); gprintf("WBFS_CloseDisc\n"); WBFS_CloseDisc(disc); gprintf("options\n"); OptionList options; for (u32 i = 0, position = 0; i < fstbuffer[0].filelen; i++) { //don't add files that aren't .dol to the list const char * filename = fstfiles(fstbuffer, i); const char * fileext = NULL; if(filename) fileext = strrchr(filename, '.'); if (fileext && strcasecmp(fileext, ".dol") == 0) { options.SetName(position, "%s %03i", tr("Offset"), i); options.SetValue(position, filename); position++; } } free(fstbuffer); gprintf("\n%i alt dols found", options.GetLength()+1); if (options.GetLength() <= 0) { WindowPrompt(tr( "ERROR" ), tr( "No DOL file found on disc." ), tr( "OK" )); return ret; } GuiImageData btnOutline(Resources::GetFile("button_dialogue_box.png"), Resources::GetFileSize("button_dialogue_box.png")); GuiImageData settingsbg(Resources::GetFile("settings_background.png"), Resources::GetFileSize("settings_background.png")); GuiTrigger trigA; trigA.SetSimpleTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A); GuiTrigger trigHome; trigHome.SetButtonOnlyTrigger(-1, WPAD_BUTTON_HOME | WPAD_CLASSIC_BUTTON_HOME, 0); GuiTrigger trigB; trigB.SetButtonOnlyTrigger(-1, WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B, PAD_BUTTON_B); GuiText titleTxt(GameTitles.GetTitle(GameID), 28, ( GXColor ) {0, 0, 0, 255}); titleTxt.SetAlignment(ALIGN_CENTER, ALIGN_TOP); titleTxt.SetPosition(12, 40); titleTxt.SetMaxWidth(356, SCROLL_HORIZONTAL); GuiImage settingsbackground(&settingsbg); GuiButton settingsbackgroundbtn(settingsbackground.GetWidth(), settingsbackground.GetHeight()); settingsbackgroundbtn.SetAlignment(ALIGN_LEFT, ALIGN_TOP); settingsbackgroundbtn.SetPosition(0, 0); settingsbackgroundbtn.SetImage(&settingsbackground); GuiText cancelBtnTxt(tr( "Back" ), 22, thColor("r=0 g=0 b=0 a=255 - prompt windows button text color")); cancelBtnTxt.SetMaxWidth(btnOutline.GetWidth() - 30); GuiImage cancelBtnImg(&btnOutline); if (Settings.wsprompt == ON) { cancelBtnTxt.SetWidescreen(Settings.widescreen); cancelBtnImg.SetWidescreen(Settings.widescreen); } GuiButton cancelBtn(&cancelBtnImg, &cancelBtnImg, 2, 3, 180, 400, &trigA, btnSoundOver, btnSoundClick2, 1); cancelBtn.SetScale(0.9); cancelBtn.SetLabel(&cancelBtnTxt); cancelBtn.SetTrigger(&trigB); GuiOptionBrowser optionBrowser3(396, 280, &options, "bg_options_settings.png"); optionBrowser3.SetPosition(0, 90); optionBrowser3.SetAlignment(ALIGN_CENTER, ALIGN_TOP); HaltGui(); GuiWindow w(screenwidth, screenheight); w.Append(&settingsbackgroundbtn); w.Append(&titleTxt); w.Append(&cancelBtn); w.Append(&optionBrowser3); mainWindow->Append(&w); ResumeGui(); while (!exit) { usleep(100); if (shutdown) Sys_Shutdown(); if (reset) Sys_Reboot(); ret = optionBrowser3.GetClickedOption(); if (ret >= 0) { choice = WindowPrompt(options.GetValue(ret), tr( "Load this DOL as alternate DOL?" ), tr( "OK" ), tr( "Cancel" )); if (choice) { snprintf(alternatedname, alternatedname_size, options.GetValue(ret)); const char * offset = options.GetName(ret); if(offset) ret = atoi(offset+strlen("Offset ")); //doloffset else ret = -1; // weird problem exit = true; } } if (cancelBtn.GetState() == STATE_CLICKED) { exit = true; } } HaltGui(); mainWindow->Remove(&w); ResumeGui(); return ret; }