/**************************************************************************** * MountMC * * Mounts the memory card in the given slot. * Returns the result of the last attempted CARD_Mount command. ***************************************************************************/ static int MountMC(int slot, bool silent) { int ret = -1; int tries = 0; // Initialize Card System SysArea = (u8 *)memalign(32, CARD_WORKAREA); memset (SysArea, 0, CARD_WORKAREA); CARD_Init ("VBA0", "00"); // Mount the card while(tries < 10 && ret != 0) { EXI_ProbeReset(); ret = CARD_Mount (slot, SysArea, NULL); VIDEO_WaitVSync(); tries++; } if(ret != 0 && !silent) { if (slot == CARD_SLOTA) ErrorPrompt("Unable to mount Slot A Memory Card!"); else ErrorPrompt("Unable to mount Slot B Memory Card!"); } return ret; }
/**************************************************************************** * 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; }
/**************************************************************************** * MountCard * * Mounts the memory card in the given slot. * CARD_Mount is called for a maximum of 10 tries * Returns the result of the last attempted CARD_Mount command. ***************************************************************************/ int MountCard(int cslot) { s32 ret = -1; int tries = 0; int isMounted; // Mount the card, try several times as they are tricky while ( (tries < 10) && (ret < 0)) { /*** We already initialized the Memory Card subsystem with CARD_Init() in select_memcard_slot(). Let's reset the EXI subsystem, just to make sure we have no problems mounting the card ***/ EXI_ProbeReset(); CARD_Init (NULL, NULL); //Ensure we start in show all files mode CARD_SetCompany(NULL); CARD_SetGamecode(NULL); /*** Mount the card ***/ ret = CARD_Mount (cslot, SysArea, card_removed); if (ret >= 0) break; VIDEO_WaitVSync (); tries++; } /*** Make sure the card is really mounted ***/ isMounted = CARD_ProbeEx(cslot, &memsize, §size); if (memsize > 0 && sectsize > 0)//then we really mounted de card { return isMounted; } /*** If this point is reached, something went wrong ***/ CARD_Unmount(cslot); return ret; }
int slot_delete(int slot, int device) { char filename[MAXPATHLEN]; int ret = 0; if (!device) { /* FAT support */ if (slot > 0) { /* remove screenshot */ sprintf(filename,"%s/saves/%s__%d.png", DEFAULT_PATH, rom_filename, slot - 1); remove(filename); sprintf (filename,"%s/saves/%s.gp%d", DEFAULT_PATH, rom_filename, slot - 1); } else sprintf (filename,"%s/saves/%s.srm", DEFAULT_PATH, rom_filename); /* Delete file */ ret = remove(filename); } else { /* Memory Card support */ if (slot > 0) sprintf(filename,"MD-%04X.gp%d", rominfo.realchecksum, slot - 1); else sprintf(filename,"MD-%04X.srm", rominfo.realchecksum); /* Initialise the CARD system */ memset(&SysArea, 0, CARD_WORKAREA); CARD_Init("GENP", "00"); /* CARD slot */ device--; /* Mount CARD */ if (CardMount(device)) { /* Delete file */ ret = CARD_Delete(device,filename); CARD_Unmount(device); } } return ret; }
/**************************************************************************** * 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; }
int initialize_card(int slot) { int slot_error = CARD_ERROR_READY, i = 0; if(!card_init[slot]) { /* Pass company identifier and number */ CARD_Init ("SWIE", "SS"); if(!sys_area) sys_area = memalign(32,CARD_WORKAREA); /* Lets try 50 times to mount it. Sometimes it takes a while */ for(i = 0; i<50; i++) { slot_error = CARD_Mount (slot, sys_area, card_removed_cb); if(slot_error == CARD_ERROR_READY) { CARD_GetSectorSize (slot, §or_size); break; } } } card_init[slot] = slot_error == CARD_ERROR_READY ? 1 : 0; return slot_error; }
/**************************************************************************** * 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; } }
int slot_save(int slot, int device) { char filename[MAXPATHLEN]; int filesize, done = 0; int offset = device ? 2112 : 0; u8 *savebuffer; if (slot > 0) { /* allocate buffer */ savebuffer = (u8 *)memalign(32,STATE_SIZE); if (!savebuffer) { GUI_WaitPrompt("Error","Unable to allocate memory !"); return 0; } GUI_MsgBoxOpen("Information","Saving State ...",1); filesize = state_save(&savebuffer[offset]); } else { if (!sram.on) { GUI_WaitPrompt("Error","SRAM is disabled !"); return 0; } /* allocate buffer */ savebuffer = (u8 *)memalign(32,0x10000+offset); if (!savebuffer) { GUI_WaitPrompt("Error","Unable to allocate memory !"); return 0; } GUI_MsgBoxOpen("Information","Saving SRAM ...",1); memcpy(&savebuffer[offset], sram.sram, 0x10000); sram.crc = crc32(0, sram.sram, 0x10000); filesize = 0x10000; } if (!device) { /* FAT support */ if (slot > 0) sprintf(filename, "%s/saves/%s.gp%d", DEFAULT_PATH, rom_filename, slot - 1); else sprintf(filename, "%s/saves/%s.srm", DEFAULT_PATH, rom_filename); /* Open file */ FILE *fp = fopen(filename, "wb"); if (!fp) { GUI_WaitPrompt("Error","Unable to open file !"); free(savebuffer); return 0; } /* Write from buffer (2k blocks) */ while (filesize > FILECHUNK) { fwrite(savebuffer + done, FILECHUNK, 1, fp); done += FILECHUNK; filesize -= FILECHUNK; } /* Write remaining bytes */ fwrite(savebuffer + done, filesize, 1, fp); done += filesize; fclose(fp); } else { /* Memory Card support */ if (slot > 0) sprintf(filename, "MD-%04X.gp%d", rominfo.realchecksum, slot - 1); else sprintf(filename, "MD-%04X.srm", rominfo.realchecksum); /* Initialise the CARD system */ char action[64]; memset(&SysArea, 0, CARD_WORKAREA); CARD_Init("GENP", "00"); /* CARD slot */ device--; /* Attempt to mount the card */ if (!CardMount(device)) { GUI_WaitPrompt("Error","Unable to mount memory card"); free(savebuffer); return 0; } /* Retrieve the sector size */ u32 SectorSize = 0; int CardError = CARD_GetSectorSize(device, &SectorSize); if (!SectorSize) { sprintf(action, "Invalid sector size (%d)", CardError); GUI_WaitPrompt("Error",action); CARD_Unmount(device); free(savebuffer); return 0; } /* Build the output buffer */ char comment[2][32] = { {"Genesis Plus GX"}, {"SRAM Save"} }; strcpy (comment[1], filename); memcpy (&savebuffer[0], &icon, 2048); memcpy (&savebuffer[2048], &comment[0], 64); /* Adjust file size */ filesize += 2112; if (filesize % SectorSize) filesize = ((filesize / SectorSize) + 1) * SectorSize; /* Check if file already exists */ card_file CardFile; if (CARD_Open(device, filename, &CardFile) == CARD_ERROR_READY) { int size = filesize - CardFile.len; CARD_Close(&CardFile); memset(&CardFile,0,sizeof(CardFile)); /* Check file new size */ if (size > 0) { CardError = CARD_Create(device, "TEMP", size, &CardFile); if (CardError) { sprintf(action, "Unable to increase file size (%d)", CardError); GUI_WaitPrompt("Error",action); CARD_Unmount(device); free(savebuffer); return 0; } /* delete temporary file */ CARD_Close(&CardFile); memset(&CardFile,0,sizeof(CardFile)); CARD_Delete(device, "TEMP"); } /* delete previously existing file */ CARD_Delete(device, filename); } /* Create a new file */ CardError = CARD_Create(device, filename, filesize, &CardFile); if (CardError) { sprintf(action, "Unable to create file (%d)", CardError); GUI_WaitPrompt("Error",action); CARD_Unmount(device); free(savebuffer); return 0; } /* Update file informations */ time_t rawtime; time(&rawtime); card_stat CardStatus; CARD_GetStatus(device, CardFile.filenum, &CardStatus); CardStatus.icon_addr = 0x0; CardStatus.icon_fmt = 2; CardStatus.icon_speed = 1; CardStatus.comment_addr = 2048; CardStatus.time = rawtime; CARD_SetStatus(device, CardFile.filenum, &CardStatus); /* Write file sectors */ while (filesize > 0) { CARD_Write(&CardFile, &savebuffer[done], SectorSize, done); filesize -= SectorSize; done += SectorSize; } /* Close file */ CARD_Close(&CardFile); CARD_Unmount(device); } GUI_MsgBoxClose(); free(savebuffer); /* Save screenshot */ if (slot && !device) { sprintf(filename,"%s/saves/%s__%d.png", DEFAULT_PATH, rom_filename, slot - 1); gxSaveScreenshot(filename); } return 1; }
int slot_load(int slot, int device) { char filename[MAXPATHLEN]; int filesize, done = 0; int offset = 0; u8 *savebuffer; if (slot > 0) { GUI_MsgBoxOpen("Information","Loading State ...",1); } else { if (!sram.on) { GUI_WaitPrompt("Error","SRAM is disabled !"); return 0; } GUI_MsgBoxOpen("Information","Loading SRAM ...",1); } if (!device) { /* FAT support */ if (slot > 0) sprintf (filename,"%s/saves/%s.gp%d", DEFAULT_PATH, rom_filename, slot - 1); else sprintf (filename,"%s/saves/%s.srm", DEFAULT_PATH, rom_filename); /* Open file */ FILE *fp = fopen(filename, "rb"); if (!fp) { GUI_WaitPrompt("Error","Unable to open file !"); return 0; } /* Read size */ fseek(fp, 0, SEEK_END); filesize = ftell(fp); fseek(fp, 0, SEEK_SET); /* allocate buffer */ savebuffer = (u8 *)memalign(32,filesize); if (!savebuffer) { GUI_WaitPrompt("Error","Unable to allocate memory !"); fclose(fp); return 0; } /* Read into buffer (2k blocks) */ while (filesize > FILECHUNK) { fread(savebuffer + done, FILECHUNK, 1, fp); done += FILECHUNK; filesize -= FILECHUNK; } /* Read remaining bytes */ fread(savebuffer + done, filesize, 1, fp); done += filesize; fclose(fp); } else { /* Memory Card support */ if (slot > 0) sprintf(filename, "MD-%04X.gp%d", rominfo.realchecksum, slot - 1); else sprintf(filename, "MD-%04X.srm", rominfo.realchecksum); /* Initialise the CARD system */ char action[64]; memset(&SysArea, 0, CARD_WORKAREA); CARD_Init("GENP", "00"); /* CARD slot */ device--; /* Attempt to mount the card */ if (!CardMount(device)) { GUI_WaitPrompt("Error","Unable to mount memory card"); return 0; } /* Retrieve the sector size */ u32 SectorSize = 0; int CardError = CARD_GetSectorSize(device, &SectorSize); if (!SectorSize) { sprintf(action, "Invalid sector size (%d)", CardError); GUI_WaitPrompt("Error",action); CARD_Unmount(device); return 0; } /* Open file */ card_file CardFile; CardError = CARD_Open(device, filename, &CardFile); if (CardError) { sprintf(action, "Unable to open file (%d)", CardError); GUI_WaitPrompt("Error",action); CARD_Unmount(device); return 0; } /* Retrieve file size */ filesize = CardFile.len; if (filesize % SectorSize) filesize = ((filesize / SectorSize) + 1) * SectorSize; /* Allocate buffer */ savebuffer = (u8 *)memalign(32,filesize); if (!savebuffer) { GUI_WaitPrompt("Error","Unable to allocate memory !"); CARD_Close(&CardFile); CARD_Unmount(device); return 0; } /* Read file sectors */ while (filesize > 0) { CARD_Read(&CardFile, &savebuffer[done], SectorSize, done); done += SectorSize; filesize -= SectorSize; } CARD_Close(&CardFile); CARD_Unmount(device); offset = 2112; } if (slot > 0) { /* Load state */ if (!state_load(&savebuffer[offset])) { free(savebuffer); GUI_WaitPrompt("Error","Unable to load state !"); return 0; } } else { /* Load SRAM & update CRC */ memcpy(sram.sram, &savebuffer[offset], 0x10000); sram.crc = crc32(0, sram.sram, 0x10000); } free(savebuffer); GUI_MsgBoxClose(); return 1; }
// Only accepts a .gci file int deviceHandler_CARD_writeFile(file_handle* file, void* data, unsigned int length) { card_stat CardStatus; card_dir CardDir; card_file CardFile; GCI gci; int err = 0; unsigned int SectorSize = 0, slot = file->fileBase>>24; char tmpBuf[5]; /*** Clear out the status ***/ memset(&CardStatus, 0, sizeof(card_stat)); memcpy(&gci, data, sizeof(GCI)); memcpy(&CardStatus.gamecode, &gci.gamecode, 4); memcpy(&CardStatus.company, &gci.company, 2); CardStatus.banner_fmt = gci.banner_fmt; memcpy(&CardStatus.filename, &gci.filename, CARD_FILENAMELEN); CardStatus.time = gci.time; CardStatus.icon_addr = gci.icon_addr; CardStatus.icon_fmt = gci.icon_fmt; CardStatus.icon_speed = gci.icon_speed; CardStatus.len = gci.filesize8 * 8192; CardStatus.comment_addr = gci.comment_addr; CARD_Init((char*)gci.gamecode,(char*)gci.company); memcpy(&tmpBuf[0],(char*)gci.gamecode,4); tmpBuf[4]='\0'; CARD_SetGamecode(&tmpBuf[0]); memcpy(&tmpBuf[0],(char*)gci.company,2); tmpBuf[2]='\0'; CARD_SetCompany(&tmpBuf[0]); err = CARD_Mount (slot, sys_area, NULL); if (err) return -1; CARD_GetSectorSize (slot, &SectorSize); /*** If this file exists, abort ***/ err = CARD_FindFirst (slot, &CardDir, false); while (err != CARD_ERROR_NOFILE){ if (strcmp ((char *) CardDir.filename, (char *)gci.filename) == 0){ /*** Found the file - abort ***/ CARD_Unmount (slot); return -2; } err = CARD_FindNext (&CardDir); } /*** Now restore the file from backup ***/ err = CARD_Create (slot, (char *) gci.filename, gci.filesize8 * 8192, &CardFile); if (err){ CARD_Unmount (slot); return -3; } /*** Now write the file data, in sector sized chunks ***/ int offset = 0; while (offset < (gci.filesize8 * 8192)){ if ((offset + SectorSize) <= (gci.filesize8 * 8192)) { CARD_Write (&CardFile, data + 0x40 + offset, SectorSize, offset); } else { CARD_Write (&CardFile, data + 0x40 + offset, ((offset + SectorSize) - (gci.filesize8 * 8192)), offset); } offset += SectorSize; } /*** Finally, update the status ***/ CARD_SetStatus (slot, CardFile.filenum, &CardStatus); CARD_Close (&CardFile); CARD_Unmount (slot); return length; }
/**************************************************************************** * 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; }
/**************************************************************************** * ManageState * * Here is the main Freeze File Management stuff. * The output file contains an icon (2K), 64 bytes comment and the STATE (~128k) * * direction == 0 save, 1 load. ****************************************************************************/ int ManageState (u8 direction, u8 device) { if (!smsromsize) return 0; char filename[MAXJOLIET]; /* clean buffer */ memset(savebuffer, 0, 0x12000); if (direction) ShowAction ("Loading State ..."); else ShowAction ("Saving State ..."); if (device == 0) { /* FAT support */ sprintf (filename, "%s.spz", rom_filename); return FAT_ManageFile(filename,direction); } /* Memory CARD support */ char action[80]; int CardError; unsigned int SectorSize = 0; int blocks; char comment[2][32] = { {"SMS Plus 1.3 [FRZ]"}, {"Freeze State"} }; int outbytes = 0; int sbo; int state_size = 0; /* First, build a filename */ sprintf (filename, "%08X.spz", (u32)crc32 (0, &cart.rom[0], smsromsize)); strcpy (comment[1], filename); /* set MCARD slot nr. */ u8 CARDSLOT = device - 1; /* Saving */ if (direction == 0) { /*** Build the output buffer ***/ memcpy (&savebuffer, &icon, 2048); memcpy (&savebuffer[2048], &comment[0], 64); state_size = system_save_state(&savebuffer[2112]); } outbytes = 2048 + 64 + state_size; /*** Initialise the CARD system ***/ memset (&SysArea, 0, CARD_WORKAREA); CARD_Init ("SMSP", "00"); /*** Attempt to mount the card ***/ CardError = MountTheCard (CARDSLOT); if (CardError) { /*** Retrieve the sector size ***/ CardError = CARD_GetSectorSize (CARDSLOT, &SectorSize); if (SectorSize) { switch (direction) { case 0: /*** Saving ***/ /*** Determine number of blocks on this card ***/ blocks = (outbytes / SectorSize) * SectorSize; if (outbytes % SectorSize) blocks += SectorSize; /*** Check if a previous save exists ***/ if (CardFileExists (filename,CARDSLOT)) { CardError = CARD_Open (CARDSLOT, filename, &CardFile); if (CardError) { sprintf (action, "Error Open : %d", CardError); WaitPrompt (action); CARD_Unmount (CARDSLOT); return 0; } int size = CardFile.len; CARD_Close (&CardFile); if (size < blocks) { /* new size is bigger: check if there is enough space left */ CardError = CARD_Create (CARDSLOT, "TEMP", blocks-size, &CardFile); if (CardError) { sprintf (action, "Error Update : %d", CardError); WaitPrompt (action); CARD_Unmount (CARDSLOT); return 0; } CARD_Close (&CardFile); CARD_Delete(CARDSLOT, "TEMP"); } /* always delete existing slot */ CARD_Delete(CARDSLOT, filename); } /*** Create a new slot ***/ CardError = CARD_Create (CARDSLOT, filename, blocks, &CardFile); if (CardError) { sprintf (action, "Error create : %d %d", CardError, CARDSLOT); WaitPrompt (action); CARD_Unmount (CARDSLOT); return 0; } /*** Continue and save ***/ CARD_GetStatus (CARDSLOT, CardFile.filenum, &CardStatus); CardStatus.icon_addr = 0x0; CardStatus.icon_fmt = 2; CardStatus.icon_speed = 1; CardStatus.comment_addr = 2048; CARD_SetStatus (CARDSLOT, CardFile.filenum, &CardStatus); /*** And write the blocks out ***/ sbo = 0; while (outbytes > 0) { CardError = CARD_Write (&CardFile, &savebuffer[sbo], SectorSize, sbo); outbytes -= SectorSize; sbo += SectorSize; } CARD_Close (&CardFile); CARD_Unmount (CARDSLOT); sprintf (action, "Saved %d bytes successfully", blocks); WaitPrompt (action); return 1; default: /*** Loading ***/ if (!CardFileExists (filename, CARDSLOT)) { WaitPrompt ("No Savestate Found"); CARD_Unmount (CARDSLOT); return 0; } memset (&CardFile, 0, sizeof (CardFile)); CardError = CARD_Open (CARDSLOT, filename, &CardFile); if (CardError) { sprintf (action, "Error Open : %d", CardError); WaitPrompt (action); CARD_Unmount (CARDSLOT); return 0; } blocks = CardFile.len; if (blocks < SectorSize) blocks = SectorSize; if (blocks % SectorSize) blocks++; /*** Just read the file back in ***/ sbo = 0; int size = blocks; while (blocks > 0) { CARD_Read (&CardFile, &savebuffer[sbo], SectorSize, sbo); sbo += SectorSize; blocks -= SectorSize; } CARD_Close (&CardFile); CARD_Unmount (CARDSLOT); /*** Load State ***/ system_load_state(&savebuffer[2112]); /*** Inform user ***/ sprintf (action, "Loaded %d bytes successfully", size); WaitPrompt (action); return 1; } } WaitPrompt ("Invalid sector size"); return 0; } WaitPrompt ("Unable to mount memory card"); return 0; /*** Signal failure ***/ }
static bool IsGCCardAvailable (void) { CARD_Init (NULL, NULL); return (CARD_Probe (CARD_SLOTA) <= 0) ? false : true; }
/**************************************************************************** * 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; }
void slot_autodetect(int slot, int device, t_slot *ptr) { if (!ptr) return; char filename[MAXPATHLEN]; memset(ptr,0,sizeof(t_slot)); if (!device) { /* FAT support */ if (slot > 0) sprintf (filename,"%s/saves/%s.gp%d", DEFAULT_PATH, rom_filename, slot - 1); else sprintf (filename,"%s/saves/%s.srm", DEFAULT_PATH, rom_filename); /* Open file */ FILE *fp = fopen(filename, "rb"); if (fp) { /* Retrieve date & close */ struct stat filestat; stat(filename, &filestat); struct tm *timeinfo = localtime(&filestat.st_mtime); ptr->year = 1900 + timeinfo->tm_year; ptr->month = timeinfo->tm_mon; ptr->day = timeinfo->tm_mday; ptr->hour = timeinfo->tm_hour; ptr->min = timeinfo->tm_min; fclose(fp); ptr->valid = 1; } } else { /* Memory Card support */ if (slot > 0) sprintf(filename,"MD-%04X.gp%d", rominfo.realchecksum, slot - 1); else sprintf(filename,"MD-%04X.srm", rominfo.realchecksum); /* Initialise the CARD system */ memset(&SysArea, 0, CARD_WORKAREA); CARD_Init("GENP", "00"); /* CARD slot */ device--; /* Mount CARD */ if (CardMount(device)) { /* Open file */ card_file CardFile; if (CARD_Open(device, filename, &CardFile) == CARD_ERROR_READY) { /* Retrieve date & close */ card_stat CardStatus; CARD_GetStatus(device, CardFile.filenum, &CardStatus); time_t rawtime = CardStatus.time; struct tm *timeinfo = localtime(&rawtime); ptr->year = 1900 + timeinfo->tm_year; ptr->month = timeinfo->tm_mon; ptr->day = timeinfo->tm_mday; ptr->hour = timeinfo->tm_hour; ptr->min = timeinfo->tm_min; CARD_Close(&CardFile); ptr->valid = 1; } CARD_Unmount(device); } } }
//--------------------------------------------------------------------------------- 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); printf("Memory Card Demo\n\n"); while (1) { printf("Insert A card in slot B and press A\n"); do { PAD_ScanPads(); if (PAD_ButtonsDown(0) & PAD_BUTTON_START) PSOreload(); VIDEO_WaitVSync(); } while ( !(PAD_ButtonsDown(0) & PAD_BUTTON_A)); printf("Mounting card ...\n"); CARD_Init("DEMO","00"); int SlotB_error = CARD_Mount(CARD_SLOTB, SysArea, card_removed); printf("slot B code %d\n",SlotB_error); int CardError; if (SlotB_error >= 0) { unsigned int SectorSize = 0; CARD_GetSectorSize(CARD_SLOTB,&SectorSize); printf("Sector size is %d bytes.\n\n",SectorSize); char *CardBuffer = (char *)memalign(32,SectorSize); printf("Starting directory\n"); card_dir CardDir; card_file CardFile; CardError = CARD_FindFirst(CARD_SLOTB, &CardDir, true); bool found = false; while ( CARD_ERROR_NOFILE != CardError ) { printf("%s %s %s\n",CardDir.filename,CardDir.gamecode,CardDir.company); CardError = CARD_FindNext(&CardDir); if ( 0 == strcmp (DemoFileName, (char *)CardDir.filename)) found = true; }; printf("Finished directory\n\n"); if (found) { printf("Test file contains :- \n"); CardError = CARD_Open(CARD_SLOTB ,DemoFileName,&CardFile); CARD_Read(&CardFile,CardBuffer,SectorSize,0); printf("%s\n",CardBuffer); CARD_Close(&CardFile); CARD_Delete(CARD_SLOTB,DemoFileName); } else { printf("writing test file ...\n"); CardError = CARD_Create(CARD_SLOTB ,DemoFileName,SectorSize,&CardFile); if (0 == CardError) { time_t gc_time; gc_time = time(NULL); sprintf(CardBuffer,"This text was written by MemCardDemo\nat %s\n",ctime(&gc_time)); CardError = CARD_Write(&CardFile,CardBuffer,SectorSize,0); CardError = CARD_Close(&CardFile); } } CARD_Unmount(CARD_SLOTB); free(CardBuffer); } } }
void MCManage(int mode, int slot) { char mcFilename[80]; int CardError; card_dir CardDir; card_file CardFile; int SectorSize; int found = 0; int FileSize; int actualSize; int savedBytes=0; char debug[128]; CARDSLOT = slot; /*** Build the file name ***/ sprintf(mcFilename, "FCEU-%08x.fcs", iNESGameCRC32); /*** Mount the Card ***/ CARD_Init("FCEU", "00"); /*** Try for memory card in slot A ***/ CardError = CARD_Mount(CARDSLOT, SysArea, CardRemoved ); if ( CardError >= 0 ) { /*** Get card sector size ***/ CardError = CARD_GetSectorSize(CARDSLOT, &SectorSize); switch ( mode ) { case 0 : { /*** Save Game ***/ /*** Look for this file ***/ CardError = CARD_FindFirst(CARDSLOT, &CardDir, true); found = 0; card_stat CardStatus; while ( CardError != CARD_ERROR_NOFILE ) { CardError = CARD_FindNext(&CardDir); if ( strcmp(CardDir.filename, mcFilename) == 0 ) found = 1; } /*** Determine number of sectors required ***/ savedBytes = actualSize = GCFCEUSS_Save(); sprintf(debug, "Saving in MC ..."); ShowAction(debug); FileSize = ( actualSize / SectorSize ) * SectorSize; if ( actualSize % SectorSize ) FileSize += SectorSize; /*** Now write the file out ***/ if ( !found ) CardError = CARD_Create(CARDSLOT, mcFilename, FileSize, &CardFile); else CardError = CARD_Open(CARDSLOT, mcFilename, &CardFile); CARD_GetStatus( CARDSLOT, CardFile.filenum, &CardStatus); CardStatus.icon_addr = 0; CardStatus.icon_fmt = 2; CardStatus.icon_speed = 1; CardStatus.comment_addr = sizeof(saveicon); CARD_SetStatus( CARDSLOT, CardFile.filenum, &CardStatus); /*** Haha! libogc only write one block at a time! ***/ if ( CardError == 0 ) { int sbo = 0; while ( actualSize > 0 ) { CardError = CARD_Write(&CardFile, &statebuffer[sbo], SectorSize, sbo ); actualSize -= SectorSize; sbo += SectorSize; } CardError = CARD_Close(&CardFile); sprintf(debug, "Saved %d bytes successfully!", savedBytes); WaitPrompt(debug); } else WaitPrompt("Save Failed!"); CARD_Unmount(CARDSLOT); } break; /*** End save ***/ case 1: { /*** Load state ***/ /*** Look for this file ***/ CardError = CARD_FindFirst(CARDSLOT, &CardDir, true); memopen(); /*** Clear the buffer ***/ found = 0; while ( CardError != CARD_ERROR_NOFILE ) { CardError = CARD_FindNext(&CardDir); if ( strcmp(CardDir.filename, mcFilename) == 0 ) found = 1; } if ( found == 0 ) { WaitPrompt("No Save Game Found"); CARD_Unmount(CARDSLOT); return; } /*** Load the file into memory ***/ CardError = CARD_Open(CARDSLOT, mcFilename, &CardFile); CardError = CARD_Read(&CardFile, &statebuffer, SectorSize, 0); /*** Get actual size of the file ***/ memcpy(&actualSize, &statebuffer[FILESIZEOFFSET], 4); savedBytes = actualSize; int sbo = SectorSize; actualSize -= SectorSize; while( actualSize > 0 ) { CARD_Read(&CardFile, &statebuffer[sbo], SectorSize, sbo); actualSize -= SectorSize; sbo += SectorSize; } CARD_Close(&CardFile); /*** Finally, do load ***/ GCFCEUSS_Load(); CARD_Unmount(CARDSLOT); sprintf(debug, "Loaded %d bytes successfully!", savedBytes); WaitPrompt(debug); } break; /*** End load ***/ default: break; } } else { WaitPrompt("Cannot Mount Memory Card!"); } }