void MC_FormatMode(s32 slot) { int erase = 1; int err; //0 = B wass pressed -> ask again if (!slot){ erase = WaitPromptChoice("Are you sure you want to format memory card in slot A?", "Format", "Cancel"); }else{ erase = WaitPromptChoice("Are you sure you want to format memory card in slot B?", "Format", "Cancel"); } if (!erase){ if (!slot){ erase = WaitPromptChoiceAZ("All contents of memory card in slot A will be erased!", "Format", "Cancel"); }else{ erase = WaitPromptChoiceAZ("All contents of memory card in slot B will be erased!", "Format", "Cancel"); } if (!erase) { /*** Try to mount the card ***/ err = MountCard(slot); if (err < 0) { WaitCardError("MCFormat Mount", err); return; /*** Unable to mount the card ***/ } ShowAction("Formatting card..."); /*** Format the card ***/ CARD_Format(slot); usleep(1000*1000); /*** Try to mount the card ***/ err = MountCard(slot); if (err < 0) { WaitCardError("MCFormat Mount", err); return; /*** Unable to mount the card ***/ }else { WaitPrompt("Format completed successfully"); } CARD_Unmount(slot); return; } } WaitPrompt("Format operation cancelled"); return; }
/**************************************************************************** * LoadMCFile * Load savebuffer from Memory Card file ***************************************************************************/ int LoadMCFile (char *buf, int slot, char *filename, bool silent) { int CardError; unsigned int blocks; unsigned int SectorSize; int bytesleft = 0; int bytesread = 0; /*** Initialize Card System ***/ memset (SysArea, 0, CARD_WORKAREA); CARD_Init ("VBA0", "00"); /*** Try to mount the card ***/ CardError = MountCard(slot, NOTSILENT); if (CardError == 0) { /*** Get Sector Size ***/ CARD_GetSectorSize (slot, &SectorSize); if (!CardFileExists (filename, slot)) { if (!silent) WaitPrompt("Unable to open file"); return 0; } memset (&CardFile, 0, sizeof (CardFile)); CardError = CARD_Open (slot, filename, &CardFile); blocks = CardFile.len; if (blocks < SectorSize) blocks = SectorSize; if (blocks % SectorSize) blocks += SectorSize; memset (buf, 0, 0x22000); bytesleft = blocks; bytesread = 0; while (bytesleft > 0) { CARD_Read (&CardFile, buf + bytesread, SectorSize, bytesread); bytesleft -= SectorSize; bytesread += SectorSize; } CARD_Close (&CardFile); CARD_Unmount (slot); } else if (slot == CARD_SLOTA) WaitPrompt("Unable to Mount Slot A Memory Card!"); else WaitPrompt("Unable to Mount Slot B Memory Card!"); return bytesread; }
u16 FreeBlocks(s32 chn) { s32 err; static u8 noinserted = 0; u16 freeblocks = 0; /*** Try to mount the card ***/ err = MountCard(chn); if (err < 0) { //We want to allow browsing saves in sd even with no card if (err == CARD_ERROR_NOCARD) { noinserted = 1; if(chn) ShowAction("No card inserted in slot B!"); else ShowAction("No card inserted in slot A!"); return 0; }else { WaitCardError("CardMount", err); return 0; /*** Unable to mount the card ***/ } }else{ err = CARD_GetFreeBlocks(chn, &freeblocks); if (err < 0) { CARD_Unmount(chn); //We want to allow browsing saves in sd even with no card if (err == CARD_ERROR_NOCARD) { noinserted = 1; if(chn) ShowAction("No card inserted in slot B!"); else ShowAction("No card inserted in slot A!"); return 0; }else { WaitCardError("FreeBlocks", err); return 0; } } } if (noinserted) { if (mode == 300)//Backup mode writeStatusBar("Pick a file using UP or DOWN ", "Press A to backup savegame"); else if (mode == 400)//Restore mode writeStatusBar("Pick a file using UP or DOWN", "Press A to restore to Memory Card "); else writeStatusBar("",""); } CARD_Unmount(chn); return freeblocks; }
/**************************************************************************** * CardGetDirectory * * Returns number of files found on a card. ****************************************************************************/ int CardGetDirectory (int slot) { int err; char company[4]; char gamecode[6]; //add null char company[2] = gamecode[4] = 0; /*** Clear the work area ***/ memset (SysArea, 0, CARD_WORKAREA); /*** Initialise the Card system, show all ***/ CARD_Init(NULL, NULL); /*** Try to mount the card ***/ err = MountCard(slot); if (err < 0) { WaitCardError("CardMount", err); return 0; /*** Unable to mount the card ***/ } //Ensure we are in show all mode CARD_SetCompany(NULL); CARD_SetGamecode(NULL); /*** Retrieve the directory listing ***/ cardcount = 0; err = CARD_FindFirst (slot, &CardDir, true); //true means we want to showall while (err != CARD_ERROR_NOFILE) { memcpy (&CardList[cardcount], &CardDir, sizeof (card_dir)); memset (filelist[cardcount], 0, 1024); memcpy (company, &CardDir.company, 2); memcpy (gamecode, &CardDir.gamecode, 4); //This array will store what will show in left window sprintf ((char*)filelist[cardcount], "%s-%s-%s", company, gamecode, CardDir.filename); cardcount++; err = CARD_FindNext (&CardDir); } /*** Release as soon as possible ***/ CARD_Unmount (slot); maxfile = cardcount; return cardcount; }
/**************************************************************************** * TestCard * * Checks to see if a card is in the card slot specified ***************************************************************************/ bool TestCard(int slot, bool silent) { // Memory Cards do not work in Wii mode - disable #ifdef HW_RVL return false; #endif /*** Initialize Card System ***/ memset (SysArea, 0, CARD_WORKAREA); CARD_Init ("VBA0", "00"); /*** Try to mount the card ***/ if (MountCard(slot, silent) == 0) { // Mount successful! if(!silent) { if (slot == CARD_SLOTA) WaitPrompt("Mounted Slot A Memory Card!"); else WaitPrompt("Mounted Slot B Memory Card!"); } CARD_Unmount (slot); return true; } else { if(!silent) { if (slot == CARD_SLOTA) WaitPrompt("Unable to Mount Slot A Memory Card!"); else WaitPrompt("Unable to Mount Slot B Memory Card!"); } return false; } }
void MC_DeleteMode(int slot) { int memitems, err; int selected = 0; int erase; displaypath = 0; clearRightPane(); DrawText(386,130,"D e l e t e M o d e"); DrawText(386,134,"_____________________"); char msg[1024]; writeStatusBar("Reading memory card... ", ""); /*** Get the directory listing from the memory card ***/ memitems = CardGetDirectory (slot); setfontsize (14); writeStatusBar("Choose a file with UP button or DOWN button ", "Press A button to delete ") ; /*** If it's a blank card, get out of here ***/ if (!memitems) { WaitPrompt ("No saved games to delete !"); } else { while(1) { // TODO: implement showselector selected = ShowSelector(1); if (cancel) { WaitPrompt ("Delete action cancelled !"); return; } //0 = Z or 2 was pressed -> delete the file erase = WaitPromptChoiceAZ("Are you sure you want to delete the file?", "Delete", "Cancel"); if (!erase) { // selected = 1; /*** Delete the file ***/ sprintf(msg, "Deleting \"%s\"", CardList[selected].filename); writeStatusBar(msg,""); //WaitPrompt(msg); /*** Try to mount the card ***/ err = MountCard(slot); if (err < 0) { WaitCardError("MCDel Mount", err); return; /*** Unable to mount the card ***/ } /*** Initialise for this company & gamecode ***/ CARD_SetCompany(CardList[selected].company); CARD_SetGamecode(CardList[selected].gamecode); err = CARD_Delete(slot, (char *) &CardList[selected].filename); if (err < 0) { WaitCardError("MCDel", err); } else { WaitPrompt("Delete complete"); } CARD_Unmount(slot); return; } offsetchanged = true; } } }
/**************************************************************************** * CardWriteFile * * Relies on *GOOD* data being placed in the FileBuffer prior to calling. * See ReadSMBImage ****************************************************************************/ int CardWriteFile (int slot) { char company[4]; char gamecode[6]; char filename[CARD_FILENAMELEN]; int err, ret; u32 SectorSize; int offset; int written; int filelen; char txt[128]; //add null char company[2] = gamecode[4] = 0; memset (SysArea, 0, CARD_WORKAREA); memset(filename, 0, CARD_FILENAMELEN); ExtractGCIHeader(); memcpy(company, &gci.company, 2); memcpy(gamecode, &gci.gamecode, 4); memcpy(filename, &gci.filename, CARD_FILENAMELEN); filelen = gci.filesize8 * 8192; /*** Mount the card ***/ err = MountCard(slot); if (err < 0) { WaitCardError("CardMount", err); return 0; /*** Unable to mount the card ***/ } CARD_GetSectorSize (slot, &SectorSize); /*** Initialise for this company & gamecode ***/ CARD_SetCompany(company); CARD_SetGamecode(gamecode); /*** If this file exists, abort ***/ err = CARD_FindFirst (slot, &CardDir, false); while (err != CARD_ERROR_NOFILE) { if ((memcmp(CardDir.gamecode, &gamecode, 4) == 0) && (memcmp(CardDir.company, &company, 2) == 0) && (strcmp ((char *) CardDir.filename, (char *)filename) == 0)) { /*** Found the file - prompt user ***/ sprintf(txt, "Savegame %s(%s%s) already exists. Overwrite?", (char *)filename, gamecode, company); ret = WaitPromptChoice(txt, "Overwrite", "Cancel"); if (!ret){ sprintf(txt, "Are you -SURE- you want to overwrite %s?", (char *)filename); ret = WaitPromptChoiceAZ(txt, "Overwrite", "Cancel"); if(!ret){ err = CARD_Delete(slot, (char *) &filename); if (err < 0) { WaitCardError("MCDel", err); CARD_Unmount (slot); return 0; } err = CARD_FindFirst (slot, &CardDir, false); continue; } } /*** User canceled - abort ***/ CARD_Unmount (slot); WaitCardError("File already exists", err); return 0; } err = CARD_FindNext (&CardDir); } tryagain: /*** Initialise for this company & gamecode ***/ //Again just in case, as this is very important for propper restoring CARD_SetCompany(company); CARD_SetGamecode(gamecode); /*** Now restore the file from backup ***/ err = CARD_Create (slot, (char *) filename, filelen, &CardFile); if (err < 0) { if (err == CARD_ERROR_EXIST) { /*** Found the file - prompt user ***/ sprintf(txt, "File %s(%s%s) already exists. Overwrite?", (char *) filename, gamecode, company); ret = WaitPromptChoice(txt, "Overwrite", "Cancel"); if (!ret){ sprintf(txt, "Are you -SURE- you want to overwrite %s?", (char *) filename); ret = WaitPromptChoiceAZ(txt, "Overwrite", "Cancel"); if(!ret){ err = CARD_Delete(slot, (char *) &filename); if (err < 0) { WaitCardError("MCDel", err); CARD_Unmount (slot); return 0; } goto tryagain; } } } CARD_Unmount (slot); WaitCardError("CardCreate", err); return 0; } //Thanks to Ralf, validate F-zero and PSO savegames FZEROGX_MakeSaveGameValid(slot); PSO_MakeSaveGameValid(slot); /*** Now write the file data, in sector sized chunks ***/ offset = 0; while (offset < filelen) { if ((offset + SectorSize) <= filelen) { written = CARD_Write (&CardFile, FileBuffer + MCDATAOFFSET + offset + OFFSET, SectorSize, offset); } else { written = CARD_Write (&CardFile, FileBuffer + MCDATAOFFSET + offset + OFFSET, ((offset + SectorSize) - filelen), offset); } offset += SectorSize; } OFFSET = 0; #ifdef STATUSOGC /*** Finally, update the status ***/ CARD_SetStatus (slot, CardFile.filenum, &CardStatus); //For some reason this sets the file to Move->allowed, Copy->not allowed, Public file instead of the actual permission value CARD_SetAttributes(slot, CardFile.filenum, &permission); #else __card_setstatusex(slot, CardFile.filenum, &gci); #endif CARD_Close (&CardFile); CARD_Unmount (slot); return 1; }
/**************************************************************************** * CardReadFile * * Retrieve a file from the previously populated list. * Place in filebuffer space, for collection by SMB write. ****************************************************************************/ int CardReadFile (int slot, int id) { int bytesdone = 0; int err; u32 SectorSize; char company[4]; char gamecode[6]; int filesize; if (id >= cardcount) { WaitPrompt("Bad id"); return 0; /*** Bad id ***/ } /*** Clear the work buffers ***/ memset (FileBuffer, 0, MAXFILEBUFFER); memset (SysArea, 0, CARD_WORKAREA); //add null char company[2] = gamecode[4] = 0; memcpy (company, &CardList[id].company, 2); memcpy (gamecode, &CardList[id].gamecode, 4); /*** Mount the card ***/ err = MountCard(slot); if (err < 0) { WaitCardError("CardMount", err); return 0; /*** Unable to mount the card ***/ } /*** Retrieve sector size ***/ CARD_GetSectorSize (slot, &SectorSize); /*** Initialise for this company & gamecode ***/ CARD_SetCompany(company); CARD_SetGamecode(gamecode); /*** Open the file ***/ err = CARD_Open (slot, (char *) &CardList[id].filename, &CardFile); if (err < 0) { CARD_Unmount (slot); WaitCardError("CardOpen", err); return 0; } #ifdef STATUSOGC /*** Get card status info ***/ CARD_GetStatus (slot, CardFile.filenum, &CardStatus); CARD_GetAttributes(slot,CardFile.filenum, &permission); GCIMakeHeader(); #else //get directory entry (same as gci header, but with all the data) memset(&gci,0,sizeof(GCI)); __card_getstatusex(slot,CardFile.filenum,&gci); /*** Copy to head of buffer ***/ memcpy(FileBuffer, &gci, sizeof(GCI)); #endif /*** Copy the file contents to the buffer ***/ filesize = CardFile.len; while (bytesdone < filesize) { CARD_Read (&CardFile, FileBuffer + MCDATAOFFSET + bytesdone, SectorSize, bytesdone); bytesdone += SectorSize; } /*** Close the file ***/ CARD_Close (&CardFile); /*** Unmount the card ***/ CARD_Unmount (slot); return filesize + MCDATAOFFSET; }
//TODO: get icon and banner settings int CardReadFileHeader (int slot, int id) { int bytesdone = 0; int err; u32 SectorSize; char company[4]; char gamecode[6]; int filesize; int i; u16 check_fmt, check_speed; if (id >= cardcount) { WaitPrompt("Bad id"); return 0; /*** Bad id ***/ } /*** Clear the work buffers ***/ memset (FileBuffer, 0, MAXFILEBUFFER); memset (CommentBuffer, 0, 64); memset (SysArea, 0, CARD_WORKAREA); //add null char company[2] = gamecode[4] = 0; memcpy (company, &CardList[id].company, 2); memcpy (gamecode, &CardList[id].gamecode, 4); /*** Mount the card ***/ err = MountCard(slot); if (err < 0) { WaitCardError("CardMount", err); return 0; /*** Unable to mount the card ***/ } /*** Retrieve sector size ***/ CARD_GetSectorSize (slot, &SectorSize); /*** Initialise for this company & gamecode ***/ CARD_SetCompany((const char*)company); CARD_SetGamecode((const char*)gamecode); /*** Open the file ***/ err = CARD_Open (slot, (char *) &CardList[id].filename, &CardFile); if (err < 0) { CARD_Unmount (slot); WaitCardError("CardOpen", err); return 0; } #ifdef STATUSOGC /*** Get card status info ***/ CARD_GetStatus (slot, CardFile.filenum, &CardStatus); CARD_GetAttributes(slot,CardFile.filenum, &permission); GCIMakeHeader(); #else //get directory entry (same as gci header, but with all the data) memset(&gci,0,sizeof(GCI)); __card_getstatusex(slot,CardFile.filenum,&gci); /*** Copy to head of buffer ***/ memcpy(FileBuffer, &gci, sizeof(GCI)); #endif /*** Copy the file contents to the buffer ***/ filesize = CardFile.len; while (bytesdone < filesize) { CARD_Read (&CardFile, FileBuffer + MCDATAOFFSET + bytesdone, SectorSize, bytesdone); bytesdone += SectorSize; } /*** Get the Banner/Icon Data from the memory card file. Very specific if/else setup to minimize data copies. ***/ u8* offset = FileBuffer + MCDATAOFFSET + gci.icon_addr; /*** Get the Banner/Icon Data from the save file ***/ if ((gci.banner_fmt&CARD_BANNER_MASK) == CARD_BANNER_RGB) { //RGB banners are 96*32*2 in size memcpy(bannerdata, offset, 6144); offset += 6144; } else if ((gci.banner_fmt&CARD_BANNER_MASK) == CARD_BANNER_CI) { memcpy(bannerdataCI, offset, 3072); offset += 3072; memcpy(tlutbanner, offset, 512); offset += 512; } //Icon data int shared_pal = 0; lastframe = 0; numicons = 0; int j =0; i=0; int current_icon = 0; for (current_icon=0;i<CARD_MAXICONS;++current_icon){ //no need to clear all values since we will only use the ones until lasticon frametable[current_icon] = 0; iconindex[current_icon] = 0; //Animation speed is mandatory to be set even for a single icon //When a speed is 0 there are no more icons //Some games may have bits set after the "blank icon" both in //speed (Baten Kaitos) and format (Wario Ware Inc.) bytes, which are just garbage if (!SDCARD_GetIconSpeed(gci.icon_speed,current_icon)){ break; }else {//We've got a frame lastframe+=SDCARD_GetIconSpeed(gci.icon_speed,current_icon)*4;//Count the total frames frametable[current_icon]=lastframe; //Store the end frame of the icon if (SDCARD_GetIconFmt(gci.icon_fmt,current_icon) != 0) { //count the number of real icons numicons++; iconindex[current_icon]=current_icon; //Map the icon //CI with shared palette if (SDCARD_GetIconFmt(gci.icon_fmt,current_icon) == 1) { memcpy(icondata[current_icon], offset, 1024); offset += 1024; shared_pal = 1; } //CI with palette after the icon else if (SDCARD_GetIconFmt(gci.icon_fmt,current_icon) == 3) { memcpy(icondata[current_icon], offset, 1024); offset += 1024; memcpy(tlut[current_icon], offset, 512); offset += 512; } //RGB 16 bit icon else if (SDCARD_GetIconFmt(gci.icon_fmt,current_icon) == 2) { memcpy(icondataRGB[current_icon], offset, 2048); offset += 2048; } }else { //Get next real icon for(j=current_icon;j<CARD_MAXICONS;++j){ if (SDCARD_GetIconFmt(gci.icon_fmt,j) != 0) { iconindex[current_icon]=j; //Map blank frame to next real icon break; } } } } } lasticon = current_icon-1; //Now get icon indexes for ping-pong style icons if (SDCARD_GetIconAnim(gci.banner_fmt) == CARD_ANIM_BOUNCE && current_icon>1) //We need at least 3 icons { j=current_icon; for (i = current_icon-2; 0 < i; --i, ++j) { lastframe += SDCARD_GetIconSpeed(gci.icon_speed,i)*4; frametable[j] = lastframe; iconindex[j] = iconindex[i]; } lasticon = j-1; } //Get the shared palette if (shared_pal) memcpy(tlut[8], offset, 512); /*** Get the comment (two 32 byte strings) into buffer ***/ memcpy(CommentBuffer, FileBuffer + MCDATAOFFSET + gci.comment_addr, 64); /*** Close the file ***/ CARD_Close (&CardFile); /*** Unmount the card ***/ CARD_Unmount (slot); return filesize + MCDATAOFFSET; }
//--------------------------------------------------------------------------------- int main() { //--------------------------------------------------------------------------------- VIDEO_Init(); rmode = VIDEO_GetPreferredMode(NULL); PAD_Init(); xfb = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode)); VIDEO_Configure(rmode); VIDEO_SetNextFramebuffer(xfb); VIDEO_SetBlack(FALSE); VIDEO_Flush(); VIDEO_WaitVSync(); if(rmode->viTVMode&VI_NON_INTERLACE) VIDEO_WaitVSync(); console_init(xfb,20,64,rmode->fbWidth,rmode->xfbHeight,rmode->fbWidth*2); VIDEO_SetNextFramebuffer(xfb); int slot = CARD_SLOTA; u32 i; int tomenu = 0; u16 buttonsDown; u8 pressed = 0; int filesize; int bytesdone = 0; while(1){ VIDEO_ClearFrameBuffer (rmode, xfb, COLOR_BLACK); listpos=0; tomenu=0; pressed = 0; printf("\x1b[2;0H"); printf("Memory Card Loader 0.2 by Suloku\n"); printf("********************************\n\n"); printf("Press A or B button to select a slot.\n"); while (1){ PAD_ScanPads(); buttonsDown=PAD_ButtonsDown(0); if (buttonsDown & PAD_BUTTON_A){ slot = CARD_SLOTA; pressed = 1;} if (buttonsDown & PAD_BUTTON_B){ slot = CARD_SLOTB; pressed = 1;} if (buttonsDown & PAD_BUTTON_START){ PSOreload();} VIDEO_WaitVSync(); if (pressed) break; } printf("Mounting card in slot %s...", (slot==0?"A":"B")); int Slot_error = MountCard(slot); printf("code %d. ",Slot_error); int CardError; if (Slot_error >= 0) { printf("Sector size is %d bytes.\n",sectsize); printf("Reading memory card files..."); card_dir CardDir; card_file CardFile; CardError = CARD_FindFirst(slot, &CardDir, true); cardcount = 0; while ( CARD_ERROR_NOFILE != CardError ) { if (strncmp ("DOLX", (char *)CardDir.gamecode, 4) == 0){ memcpy (&CardList[cardcount], &CardDir, sizeof (card_dir)); cardcount++; } CardError = CARD_FindNext(&CardDir); } printf("finished.\n\n"); if (cardcount == 0){ printf("No dol files in memory card in slot %s\n\n", (slot==0?"A":"B")); waitA(); }else{ while (1){ pressed = 0; VIDEO_ClearFrameBuffer (rmode, xfb, COLOR_BLACK); printf("\x1b[2;0H"); printf("Memory Card Loader 0.1 by Suloku\n"); printf("********************************\n\n"); printf("Dol files in memory card %s: %d\n\n", (slot==0?"A":"B"), cardcount); if (listpos!=0) printf ("/\\/\\\n"); else printf(" \n"); for (i=listpos; i<listpos+10; i++){ printf (" "); if (i==listpos) printf ("-->"); printf("%s \n",CardList[i].filename); if (i>= cardcount )break; } printf("\x1b[18;0H"); if (cardcount >=10 && listpos != cardcount-1) printf ("\\/\\/\n"); else{ printf(" \n"); } printf("\n\t\tPress B button to go back to slot select.\n\n"); while (1){ PAD_ScanPads(); buttonsDown=PAD_ButtonsDown(0); if (buttonsDown & PAD_BUTTON_UP){ listpos--; if (listpos <0) listpos = 0; pressed = 1; } if (buttonsDown & PAD_BUTTON_DOWN){ listpos++; if (listpos >= cardcount-1) listpos = cardcount-1; pressed = 1; } if (buttonsDown & PAD_BUTTON_LEFT){ listpos-=10; if (listpos <0) listpos = 0; pressed = 1; } if (buttonsDown & PAD_BUTTON_RIGHT){ listpos+=10; if (listpos >= cardcount-1) listpos = cardcount-1; pressed = 1; } if (buttonsDown & PAD_BUTTON_A){ printf("Loading %s...\n", CardList[listpos].filename); /*** Initialise for this company & gamecode ***/ //add null char company[2] = gamecode[4] = 0; memcpy (company, &CardList[listpos].company, 2); memcpy (gamecode, &CardList[listpos].gamecode, 4); CARD_SetCompany(company); CARD_SetGamecode(gamecode); CardError = CARD_Open(slot ,(char*)&CardList[listpos].filename,&CardFile); if (CardError < 0) { CARD_Unmount (slot); printf("Error %d while opening file.\n", CardError); waitA(); }else{ /*** Copy the file contents to the buffer ***/ filesize = CardFile.len; u8 *dolbuffer = (u8*) memalign(32, filesize); while (bytesdone < filesize) { CardError= CARD_Read(&CardFile, dolbuffer+bytesdone, sectsize, bytesdone); bytesdone += sectsize; } CARD_Close(&CardFile); CARD_Unmount(slot); //boot dol //This will load cli_buffer and cli_size getclifrombuffer(dolbuffer, filesize); if (cli_buffer!=NULL){ // Build a command line to pass to the DOL int argc2 = 0; char *argv2[1024]; //add a terminating null character for last argument if needed if (cli_buffer[cli_size-1] != '\0'){ cli_buffer[cli_size] = '\0'; cli_size += 1; } // CLI parse char bootpath[CARD_FILENAMELEN+10]; sprintf(bootpath, "mc%d:/%s", slot, (char*)&CardList[listpos].filename); argv2[argc2] = bootpath; argc2++; // First argument is at the beginning of the file if(cli_buffer[0] != '\r' && cli_buffer[0] != '\n') { argv2[argc2] = cli_buffer; argc2++; } // Search for the others after each newline int i; for(i = 0; i < cli_size; i++) { if(cli_buffer[i] == '\r' || cli_buffer[i] == '\n') { cli_buffer[i] = '\0'; } else if(cli_buffer[i - 1] == '\0') { argv2[argc2] = cli_buffer + i; argc2++; if(argc2 >= 1024) break; } } DOLtoARAM(dolbuffer, argc2, argc2 == 0 ? NULL : argv2); }else{ DOLtoARAM(dolbuffer, 0, NULL); } //If we get here dol was invalid if(dolbuffer != NULL) free(dolbuffer); printf("Not a valid dol file.\n"); waitA(); tomenu = 1; } pressed = 1; } if (buttonsDown & PAD_BUTTON_B){ pressed = 1;tomenu=1;} if (buttonsDown & PAD_BUTTON_START){ PSOreload();} VIDEO_WaitVSync(); if (pressed) break; } if (tomenu) break; } } CARD_Unmount(slot); }else{ printf("\n\nCan't mount card in slot %s!\n", (slot==0?"A":"B")); waitA(); } } return 0; }
/**************************************************************************** * SaveMCFile * Write savebuffer to Memory Card file ***************************************************************************/ int SaveMCFile (char *buf, int slot, char *filename, int datasize, bool silent) { int CardError; unsigned int blocks; unsigned int SectorSize; char msg[80]; if(datasize <= 0) return 0; /*** Initialize Card System ***/ memset (SysArea, 0, CARD_WORKAREA); CARD_Init ("VBA0", "00"); /*** Try to mount the card ***/ CardError = MountCard(slot, NOTSILENT); if (CardError == 0) { /*** Get Sector Size ***/ CARD_GetSectorSize (slot, &SectorSize); /*** Calculate number of blocks required ***/ blocks = (datasize / SectorSize) * SectorSize; if (datasize % SectorSize) blocks += SectorSize; /*** Does this file exist ? ***/ if (CardFileExists (filename, slot)) { /*** Try to open the file ***/ CardError = CARD_Open (slot, filename, &CardFile); if (CardError) { CARD_Unmount (slot); WaitPrompt("Unable to open card file!"); return 0; } if ( (s32)blocks > CardFile.len ) /*** new data is longer ***/ { CARD_Close (&CardFile); /*** Try to create temp file to check available space ***/ CardError = CARD_Create (slot, "TEMPFILESNES9XGX201", blocks, &CardFile); if (CardError) { CARD_Unmount (slot); WaitPrompt("Not enough space to update file!"); return 0; } /*** Delete the temporary file ***/ CARD_Close (&CardFile); CardError = CARD_Delete(slot, "TEMPFILESNES9XGX201"); if (CardError) { CARD_Unmount (slot); WaitPrompt("Unable to delete temporary file!"); return 0; } /*** Delete the existing shorter file ***/ CardError = CARD_Delete(slot, filename); if (CardError) { CARD_Unmount (slot); WaitPrompt("Unable to delete existing file!"); return 0; } /*** Create new, longer file ***/ CardError = CARD_Create (slot, filename, blocks, &CardFile); if (CardError) { CARD_Unmount (slot); WaitPrompt("Unable to create updated card file!"); return 0; } } } else /*** no file existed, create new one ***/ { /*** Create new file ***/ CardError = CARD_Create (slot, filename, blocks, &CardFile); if (CardError) { CARD_Unmount (slot); if ( CardError == CARD_ERROR_INSSPACE ) WaitPrompt("Not enough space to create file!"); else WaitPrompt("Unable to create card file!"); return 0; } } /*** Now, have an open file handle, ready to send out the data ***/ CARD_GetStatus (slot, CardFile.filenum, &CardStatus); CardStatus.icon_addr = 0x0; CardStatus.icon_fmt = 2; CardStatus.icon_speed = 1; CardStatus.comment_addr = 2048; CARD_SetStatus (slot, CardFile.filenum, &CardStatus); int byteswritten = 0; int bytesleft = blocks; while (bytesleft > 0) { CardError = CARD_Write (&CardFile, buf + byteswritten, SectorSize, byteswritten); bytesleft -= SectorSize; byteswritten += SectorSize; sprintf (msg, "Wrote %d of %d bytes", byteswritten, blocks); ShowProgress (msg, byteswritten, blocks); } CARD_Close (&CardFile); CARD_Unmount (slot); if ( GCSettings.VerifySaves ) { /*** Verify the written file, but only up to the length we wrote because the file could be longer due to past writes ***/ if ( VerifyMCFile (buf, slot, filename, byteswritten) ) return byteswritten; else return 0; } else return byteswritten; } else if (slot == CARD_SLOTA) WaitPrompt("Unable to Mount Slot A Memory Card!"); else WaitPrompt("Unable to Mount Slot B Memory Card!"); return 0; }
/**************************************************************************** * Verify Memory Card file against buffer ***************************************************************************/ int VerifyMCFile (char *buf, int slot, char *filename, int datasize) { int CardError; unsigned int blocks; unsigned int SectorSize; char msg[80]; int bytesleft = 0; int bytesread = 0; /*** Initialize Card System ***/ memset (SysArea, 0, CARD_WORKAREA); CARD_Init ("VBA0", "00"); /*** Try to mount the card ***/ CardError = MountCard(slot, NOTSILENT); if (CardError == 0) { /*** Get Sector Size ***/ CARD_GetSectorSize (slot, &SectorSize); if (!CardFileExists (filename, slot)) { CARD_Unmount (slot); WaitPrompt("Unable to open file for verify!"); return 0; } memset (&CardFile, 0, sizeof (CardFile)); CardError = CARD_Open (slot, filename, &CardFile); blocks = CardFile.len; if (blocks < SectorSize) blocks = SectorSize; if (blocks % SectorSize) blocks += SectorSize; if (blocks > (unsigned int)datasize) blocks = datasize; memset (verifbuffer, 0, VERIFBUFFERSIZE); bytesleft = blocks; bytesread = 0; while (bytesleft > 0) { CARD_Read (&CardFile, verifbuffer, SectorSize, bytesread); if ( memcmp (buf + bytesread, verifbuffer, (unsigned int)bytesleft < SectorSize ? bytesleft : SectorSize) ) { CARD_Close (&CardFile); CARD_Unmount (slot); WaitPrompt("File did not verify!"); return 0; } bytesleft -= SectorSize; bytesread += SectorSize; sprintf (msg, "Verified %d of %d bytes", bytesread, blocks); ShowProgress (msg, bytesread, blocks); } CARD_Close (&CardFile); CARD_Unmount (slot); return 1; } else if (slot == CARD_SLOTA) WaitPrompt("Unable to Mount Slot A Memory Card!"); else WaitPrompt("Unable to Mount Slot B Memory Card!"); return 0; }