Example #1
0
File: mcard.c Project: suloku/gcmm
/****************************************************************************
 * 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, &sectsize);
	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;
}
Example #2
0
File: mcard.c Project: suloku/gcmm
/****************************************************************************
* 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;
}
Example #3
0
s32 deviceHandler_CARD_deleteFile(file_handle* file) {
	int slot = (!strncmp((const char*)initial_CARDB.name, file->name, 7));
	char *filename = getRelativeName(file->name);
	card_dir* cd = (card_dir*)&file->other;
	
	CARD_SetCompany((const char*)cd->company);
	CARD_SetGamecode((const char*)cd->gamecode);
	
	print_gecko("Deleting: %s from slot %i\r\n", filename, slot);
	
	int ret = CARD_DeleteEntry(slot, cd);
	if(ret != CARD_ERROR_READY) {
		uiDrawObj_t *msgBox = DrawMessageBox(D_FAIL,cardError(ret));
		DrawPublish(msgBox);
		wait_press_A();
		DrawDispose(msgBox);
	}
	return ret;
}
// 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;
}
// This is only called where length = file.size
int deviceHandler_CARD_readFile(file_handle* file, void* buffer, unsigned int length){
	unsigned int slot = file->fileBase>>24, ret = 0, file_no = file->fileBase&0xFFFFFF;
	void *dst = buffer;
	
	// Get the sector size
	u32 SectorSize = 0;
	CARD_GetSectorSize (slot, &SectorSize);
	
	// Create the .gci header
	card_stat CardStat;
	GCI gci;
	CARD_GetStatus(slot,file_no,&CardStat);        
	memset(&gci, 0xFF, sizeof(GCI));
	/*** Populate the GCI ***/
	memcpy(&gci.gamecode, &CardStat.gamecode, 4);
	memcpy(&gci.company, &CardStat.company, 2);
	gci.banner_fmt = CardStat.banner_fmt;
	memcpy(&gci.filename, &CardStat.filename, 0x20);
	gci.time = CardStat.time;
	gci.icon_addr = CardStat.icon_addr;
	gci.icon_fmt = CardStat.icon_fmt;
	gci.icon_speed = CardStat.icon_speed;
	gci.unknown1 = gci.unknown2 = 0;
	gci.index = 32;
	gci.filesize8 = (CardStat.len / 8192);
	gci.comment_addr = CardStat.comment_addr;
	memcpy(dst, &gci, sizeof(GCI));
	dst+= sizeof(GCI);
	
	// Re-init the card with the original file gamecode & company
	char game_code[16];	
	memcpy(&game_code[0],&gci.gamecode, 4);
	game_code[4] = 0;
	CARD_SetGamecode((const char *)&game_code[0]);
	memcpy(&game_code[0],&gci.company, 2);
	game_code[2] = 0;
	CARD_SetCompany((const char *)&game_code[0]);
	
	// Use the original file name
	char file_name[CARD_FILENAMELEN];	
	memset(&file_name[0],0,CARD_FILENAMELEN);
	memcpy(&file_name[0], file->name,strlen(file->name)-4);
	
	print_gecko("Try to open: [%s]\r\n",&file_name[0]);

	// Read the actual file data now
	char *read_buffer = NULL;
	card_file *memcard_file = NULL;
	memcard_file = (card_file*)memalign(32,sizeof(card_file));
	if(!memcard_file) {
		return -2;
	}
	memset(memcard_file, 0, sizeof(card_file));
	
	// Open the Entry
	if((ret = CARD_Open(slot, (const char*)&file_name[0], memcard_file)) != CARD_ERROR_NOFILE){
		/* Allocate the read buffer */
		u32 readSize = ((memcard_file->len % SectorSize) != 0) ? 
						((memcard_file->len/SectorSize)+1) * SectorSize : memcard_file->len;
		read_buffer = memalign(32,SectorSize);
		if(!read_buffer) {
			free(memcard_file);
			return -2;
		}
		
		print_gecko("Reading: [%i] bytes\r\n",readSize);
		
		/* Read the file */
		int i = 0;
		for(i=0;i<(readSize/SectorSize);i++) {
			ret = CARD_Read(memcard_file,read_buffer, SectorSize, i*SectorSize);
			if(!ret) {
				memcpy(dst,read_buffer,(i==(readSize/SectorSize)-1) ? (memcard_file->len % SectorSize):SectorSize);
			}
			dst+=SectorSize;
			print_gecko("Read: [%i] bytes ret [%i]\r\n",SectorSize,ret);
			
		}
	}
	else {
		print_gecko("ret: [%i]\r\n",ret);
		
	}
	CARD_Close(memcard_file);
	free(read_buffer);
	free(memcard_file);      

	return !ret ? length : ret;
}
Example #6
0
File: mcard.c Project: suloku/gcmm
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;
		}
	}
}
Example #7
0
File: mcard.c Project: suloku/gcmm
/****************************************************************************
* 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;
}
Example #8
0
File: mcard.c Project: suloku/gcmm
/****************************************************************************
* 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;
}
Example #9
0
File: mcard.c Project: suloku/gcmm
//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;
}
Example #10
0
// This function should always be called for the FULL length cause CARD is lame like that.
s32 deviceHandler_CARD_writeFile(file_handle* file, void* data, u32 length) {
	
	if(gciInfo == NULL) {	// Swiss ID for this
		CARD_SetGameAndCompany();
	} else {	// Game specific
		char company[4], gamecode[8];
		memset(company, 0, 4);
		memset(gamecode, 0, 8);
		memcpy(gamecode, gciInfo->gamecode, 4);
		memcpy(company, gciInfo->company, 2);
		CARD_SetCompany(company);
		CARD_SetGamecode(gamecode);
	}
	
	card_file cardfile;
	unsigned int slot = (!strncmp((const char*)initial_CARDB.name, file->name, 7)), ret = 0;
	unsigned int adj_length = (length % 8192 == 0 ? length : (length + (8192-length%8192)))+8192;
	char *filename = NULL;
	char fname[CARD_FILENAMELEN+1];
	if(gciInfo != NULL) {
		memset(fname, 0, CARD_FILENAMELEN+1);
		memcpy(fname, gciInfo->filename, CARD_FILENAMELEN);
		filename = &fname[0];
		adj_length = gciInfo->filesize8*8192;
	} else {
		filename = getRelativeName(file->name);
	}
	
	// Open the file based on the slot & file name
	ret = CARD_Open(slot,filename, &cardfile);

	print_gecko("Tried to open: [%s] in slot %s got res: %i\r\n",filename, slot ? "B":"A", ret);
	
	if(ret == CARD_ERROR_NOFILE) {
		// If the file doesn't exist, create it.
		ret = CARD_Create(slot, filename,adj_length,&cardfile);
		print_gecko("Tried to create: [%s] in slot %s got res: %i\r\n",filename, slot ? "B":"A", ret);
		if(ret != CARD_ERROR_READY) {
			return ret;
		}
		ret = CARD_Open(slot,filename, &cardfile);
		print_gecko("Tried to open after create: [%s] in slot %s got res: %i\r\n",filename, slot ? "B":"A", ret);
	}
	
	if(ret != CARD_ERROR_READY) {
		// Something went wrong
		return -1;
	}

	// Write the icon, comment, etc.
	time_t gc_time = time (NULL);
	char *tmpBuffer = memalign(32,adj_length);
	memset(tmpBuffer,0,adj_length);
	if(gciInfo == NULL) {
		strcpy(tmpBuffer, filename);
		strcpy(tmpBuffer+0x20, ctime (&gc_time));
		memcpy(tmpBuffer+0x40, gamecube_rgb, sizeof(gamecube_rgb));	// Copy icon
		memcpy(tmpBuffer+0x2000, data, length);	// Copy data
	}
	else {
		data+=sizeof(GCI);
		memcpy(tmpBuffer, data, length);	// Copy data
	}
	
	// The file exists by now, write at offset.
	int amount_written = 0;
	while(amount_written != adj_length) {
		ret = CARD_Write(&cardfile, tmpBuffer+amount_written, card_sectorsize[slot], file->offset);
		file->offset += card_sectorsize[slot];
		amount_written += card_sectorsize[slot];
		print_gecko("Tried to write: [%s] in slot %s got res: %i\r\n",filename, slot ? "B":"A", ret);
		if(ret != CARD_ERROR_READY) break;
	}
	
	card_stat cardstat;
	if(gciInfo == NULL) {	// Swiss
		memset(&cardstat, 0, sizeof(card_stat));
		memcpy(&cardstat.filename, filename, CARD_FILENAMELEN-1);
		cardstat.time = gc_time;
		cardstat.comment_addr = 0;
		cardstat.icon_addr = 0x40;
		cardstat.icon_speed = CARD_SPEED_FAST;
		cardstat.banner_fmt = CARD_BANNER_NONE;
		cardstat.icon_fmt = CARD_ICON_RGB;
	}
	else {	// Info is coming from a GCI
		cardstat.banner_fmt = gciInfo->banner_fmt;
		cardstat.time = gciInfo->time;
		cardstat.icon_addr = gciInfo->icon_addr;
		cardstat.icon_fmt = gciInfo->icon_fmt;
		cardstat.icon_speed = gciInfo->icon_speed;
		cardstat.comment_addr = gciInfo->comment_addr;
	}
	CARD_SetStatus (slot, cardfile.filenum, &cardstat);
	
	free(tmpBuffer);
	CARD_Close(&cardfile);
	return ret == CARD_ERROR_READY ? length : ret;
}
Example #11
0
s32 deviceHandler_CARD_readFile(file_handle* file, void* buffer, u32 length){
	card_file cardfile;
	void *dst = buffer;
	card_dir* cd = (card_dir*)&file->other;
	char *filename = getRelativeName(file->name);
	unsigned int slot = (!strncmp((const char*)initial_CARDB.name, file->name, 7)), ret = 0;

	if(cd->company[0] == '\0' && cd->gamecode[0] == '\0') {
		// Find the file we don't know about and populate this file_handle if we find it.
		if(!findFile(file)) {
			return CARD_ERROR_NOFILE;
		}
		CARD_SetCompany((const char*)cd->company);
		CARD_SetGamecode((const char*)cd->gamecode);
	} 
	else {
		CARD_SetCompany((const char*)cd->company);
		CARD_SetGamecode((const char*)cd->gamecode);
	}
	int swissFile = !strncmp((const char*)cd->gamecode, "SWIS", 4)
				 && !strncmp((const char*)cd->company, "S0", 2);
	
	// Open the file based on the slot & file name
	ret = CARD_Open(slot,filename, &cardfile);

	print_gecko("Tried to open: [%s] in slot %s got res: %i\r\n",filename, slot ? "B":"A", ret);

	if(ret != CARD_ERROR_READY)	return ret;

	u8 *read_buffer = (u8*)memalign(32,card_sectorsize[slot]);
	if(!read_buffer) {
		return -1;
	}

	/* Read from the file */
	u32 amountRead = 0;
	// If this file was put here by swiss, then skip the first 8192 bytes
	if(swissFile && !isCopyGCIMode) {
		print_gecko("Swiss copied file detected, skipping icon\r\n");
		file->offset += 8192;
	}
	if(isCopyGCIMode) {
		// Write out a .GCI
		card_stat cardstat;
		GCI gci;
		CARD_GetStatus(slot, cardfile.filenum, &cardstat);
		memset(&gci, 0, sizeof(GCI));
		memcpy(&gci.gamecode,cd->gamecode,4);
		memcpy(&gci.company,cd->company,2);
		memcpy(&gci.filename,file->name,CARD_FILENAMELEN);
		gci.reserved01 = 0xFF;
		gci.banner_fmt = cardstat.banner_fmt;
		gci.time = cardstat.time;
		gci.icon_addr = cardstat.icon_addr;
		gci.icon_fmt = cardstat.icon_fmt;
		gci.icon_speed = cardstat.icon_speed;
		gci.unknown1 = cd->permissions;
		gci.filesize8 = cardstat.len / 8192;
		gci.reserved02 = 0xFFFF;
		gci.comment_addr = cardstat.comment_addr;
		memcpy(dst, &gci, sizeof(GCI));
		dst+=sizeof(GCI);
		length-=sizeof(GCI);
		amountRead += sizeof(GCI);
	}
	while(length > 0 && file->offset < file->size) {
		int readsize = length > card_sectorsize[slot] ? card_sectorsize[slot] : length;
		print_gecko("Need to read: [%i] more bytes\r\n", length);
		
		if(file->offset&0x1ff) {
			ret = CARD_ReadUnaligned(&cardfile, read_buffer, card_sectorsize[slot], file->offset, slot);
		}
		else {
			ret = CARD_Read(&cardfile, read_buffer, card_sectorsize[slot], file->offset);
			// Sometimes reads fail the first time stupidly, retry at least once.
			print_gecko("Read: [%i] bytes ret [%i] from offset [%i]\r\n",card_sectorsize[slot],ret, file->offset);
			if(ret == CARD_ERROR_BUSY) {
				print_gecko("Read retry\r\n");
				usleep(2000);
				ret = CARD_Read(&cardfile, read_buffer, card_sectorsize[slot], file->offset);
			}
		}
		
		if(ret == CARD_ERROR_READY)
			memcpy(dst,read_buffer,readsize);
		else 
			return ret;
		dst+=readsize;
		file->offset += readsize;
		length -= readsize;
		amountRead += readsize;
	}
	// For swiss adjusted files, don't trail off the end.
	if(swissFile && length != 0) {
		amountRead+= length;
	}
	DCFlushRange(dst, amountRead);
	CARD_Close(&cardfile);
	free(read_buffer);   

	return amountRead;
}
Example #12
0
//---------------------------------------------------------------------------------
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;
}