mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2024-11-05 10:25:07 +01:00
2c2f760f44
.improved hardware initialization (fixes Ultimate Mortal Kombat Trilogy) .improved soft-reset emulation .fixed some menu bugs on Gamecube
306 lines
7.6 KiB
C
306 lines
7.6 KiB
C
/*
|
|
* file_fat.c
|
|
*
|
|
* FAT loading support
|
|
*
|
|
* Eke-Eke (2008,2009)
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*
|
|
********************************************************************************/
|
|
|
|
#include "shared.h"
|
|
#include "gui.h"
|
|
#include "history.h"
|
|
#include "unzip.h"
|
|
#include "filesel.h"
|
|
#include "file_fat.h"
|
|
#include "file_dvd.h"
|
|
|
|
/* current FAT directory */
|
|
static char *fatdir;
|
|
|
|
/* current FAT device */
|
|
static int fatType = -1;
|
|
|
|
/***************************************************************************
|
|
* FAT_ClearDirectory
|
|
*
|
|
* Clear FAT access flag
|
|
***************************************************************************/
|
|
void FAT_ClearDirectory(void)
|
|
{
|
|
fatType = -1;
|
|
}
|
|
|
|
/***************************************************************************
|
|
* FAT_UpdateDirectory
|
|
*
|
|
* Update FAT current directory
|
|
* return zero if exiting root
|
|
***************************************************************************/
|
|
int FAT_UpdateDirectory(bool go_up, char *dirname)
|
|
{
|
|
int size=0;
|
|
char *test;
|
|
char temp[MAXPATHLEN];
|
|
|
|
/* go up to parent directory */
|
|
if (strcmp(dirname,"..") == 0)
|
|
{
|
|
/* determine last subdirectory namelength */
|
|
sprintf(temp,"%s",fatdir);
|
|
test= strtok(temp,"/");
|
|
while (test != NULL)
|
|
{
|
|
size = strlen(test);
|
|
test = strtok(NULL,"/");
|
|
}
|
|
|
|
/* remove last subdirectory name */
|
|
size = strlen(fatdir) - size;
|
|
fatdir[size-1] = 0;
|
|
}
|
|
else if (go_up)
|
|
{
|
|
/* root has no parent directory */
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
/* by default, simply append folder name */
|
|
sprintf(fatdir, "%s%s/",fatdir, dirname);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
/***************************************************************************
|
|
* FAT_ParseDirectory
|
|
*
|
|
* List files into one FAT directory
|
|
***************************************************************************/
|
|
int FAT_ParseDirectory(void)
|
|
{
|
|
int nbfiles = 0;
|
|
char filename[MAXPATHLEN];
|
|
struct stat filestat;
|
|
|
|
/* open directory */
|
|
DIR_ITER *dir = diropen (fatdir);
|
|
if (dir == NULL)
|
|
{
|
|
GUI_WaitPrompt("Error","Unable to open directory !");
|
|
return -1;
|
|
}
|
|
|
|
while ((dirnext(dir, filename, &filestat) == 0) && (nbfiles < MAXFILES))
|
|
{
|
|
if (strcmp(filename,".") != 0)
|
|
{
|
|
memset(&filelist[nbfiles], 0, sizeof (FILEENTRIES));
|
|
sprintf(filelist[nbfiles].filename,"%s",filename);
|
|
filelist[nbfiles].length = filestat.st_size;
|
|
filelist[nbfiles].flags = (filestat.st_mode & S_IFDIR) ? 1 : 0;
|
|
nbfiles++;
|
|
}
|
|
}
|
|
|
|
dirclose(dir);
|
|
|
|
/* Sort the file list */
|
|
qsort(filelist, nbfiles, sizeof(FILEENTRIES), FileSortCallback);
|
|
|
|
return nbfiles;
|
|
}
|
|
|
|
/****************************************************************************
|
|
* FAT_LoadFile
|
|
*
|
|
* This function will load a BIN, SMD or ZIP file from DVD into the ROM buffer.
|
|
* This functions return the actual size of data copied into the buffer
|
|
*
|
|
****************************************************************************/
|
|
int FAT_LoadFile(u8 *buffer, u32 selection)
|
|
{
|
|
char fname[MAXPATHLEN];
|
|
int length = 0;
|
|
|
|
/* Loading from history */
|
|
if(fatType == TYPE_RECENT)
|
|
{
|
|
/* full filename */
|
|
sprintf(fname,"%s%s",history.entries[selection].filepath,filelist[selection].filename);
|
|
|
|
/* get the length of the file */
|
|
struct stat filestat;
|
|
if(stat(fname, &filestat) == 0)
|
|
length = filestat.st_size;
|
|
}
|
|
else
|
|
{
|
|
/* full filename */
|
|
sprintf(fname, "%s%s",fatdir,filelist[selection].filename);
|
|
|
|
/* get the length of the file */
|
|
length = filelist[selection].length;
|
|
}
|
|
|
|
if (length > 0)
|
|
{
|
|
/* Open file */
|
|
FILE *sdfile = fopen(fname, "rb");
|
|
if (sdfile == NULL)
|
|
{
|
|
GUI_WaitPrompt("Error","Unable to open file !");
|
|
return 0;
|
|
}
|
|
|
|
/* Add/move the file to the top of the history. */
|
|
if(fatType == TYPE_RECENT)
|
|
history_add_file(history.entries[selection].filepath, filelist[selection].filename);
|
|
else
|
|
history_add_file(fatdir, filelist[selection].filename);
|
|
|
|
/* file browser should be reinitialized */
|
|
if(fatType == TYPE_RECENT)
|
|
fatType = -1;
|
|
|
|
/* Read first data chunk */
|
|
unsigned char temp[FATCHUNK];
|
|
fread(temp, FATCHUNK, 1, sdfile);
|
|
fclose(sdfile);
|
|
|
|
/* Determine file type */
|
|
if (!IsZipFile ((char *) temp))
|
|
{
|
|
if (length > MAXROMSIZE)
|
|
{
|
|
GUI_WaitPrompt("Error","File size not supported !");
|
|
return 0;
|
|
}
|
|
|
|
/* re-open and read file */
|
|
sdfile = fopen(fname, "rb");
|
|
if (sdfile)
|
|
{
|
|
char msg[64];
|
|
sprintf(msg,"Loading %d bytes ...", length);
|
|
GUI_MsgBoxOpen("Information",msg,1);
|
|
int done = 0;
|
|
while (length > FATCHUNK)
|
|
{
|
|
fread(buffer + done, FATCHUNK, 1, sdfile);
|
|
length -= FATCHUNK;
|
|
done += FATCHUNK;
|
|
}
|
|
fread(buffer + done, length, 1, sdfile);
|
|
done += length;
|
|
fclose(sdfile);
|
|
return done;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* unzip file */
|
|
return UnZipBuffer(buffer, 0, fname);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/****************************************************************************
|
|
* OpenFAT
|
|
*
|
|
* Function to load a FAT directory and display to user.
|
|
****************************************************************************/
|
|
int FAT_Open(int type)
|
|
{
|
|
int max = 0;
|
|
|
|
if (type == TYPE_RECENT)
|
|
{
|
|
/* fetch history list */
|
|
int i;
|
|
for(i=0; i < NUM_HISTORY_ENTRIES; i++)
|
|
{
|
|
if(history.entries[i].filepath[0] > 0)
|
|
{
|
|
filelist[i].offset = 0;
|
|
filelist[i].length = 0;
|
|
filelist[i].flags = 0;
|
|
strncpy(filelist[i].filename,history.entries[i].filename, MAXJOLIET-1);
|
|
filelist[i].filename[MAXJOLIET-1] = '\0';
|
|
max++;
|
|
}
|
|
else
|
|
{
|
|
/* Found the end of the list. */
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* default directory */
|
|
fatdir = config.sddir;
|
|
#ifdef HW_RVL
|
|
if (type == TYPE_USB)
|
|
fatdir = config.usbdir;
|
|
#endif
|
|
|
|
/* verify current dir exists, otherwise browse from root */
|
|
DIR_ITER *dir = diropen(fatdir);
|
|
if (dir)
|
|
dirclose(dir);
|
|
#ifdef HW_RVL
|
|
else if (type == TYPE_USB)
|
|
sprintf (fatdir, "usb:/");
|
|
else
|
|
sprintf (fatdir, "sd:/");
|
|
#else
|
|
else
|
|
sprintf (fatdir, "/");
|
|
#endif
|
|
|
|
/* parse current directory */
|
|
max = FAT_ParseDirectory ();
|
|
}
|
|
|
|
if (max < 0)
|
|
return 0;
|
|
|
|
if (max == 0)
|
|
{
|
|
GUI_WaitPrompt("Error","No files found !");
|
|
return 0;
|
|
}
|
|
|
|
/* check if access type has changed */
|
|
if (type != fatType)
|
|
{
|
|
/* set current access type */
|
|
fatType = type;
|
|
|
|
/* reset File selector */
|
|
ClearSelector(max);
|
|
|
|
/* clear DVD access flag */
|
|
DVD_ClearDirectory();
|
|
}
|
|
|
|
return 1;
|
|
}
|