mirror of
https://github.com/dborth/snes9xgx.git
synced 2025-01-24 00:51:14 +01:00
rewrite code to allow for file/directory retry on fails
This commit is contained in:
parent
ffec5f0799
commit
faea01e64f
@ -23,10 +23,11 @@ extern "C" {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "snes9xGX.h"
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
#include "gcunzip.h"
|
#include "gcunzip.h"
|
||||||
#include "filebrowser.h"
|
#include "filebrowser.h"
|
||||||
#include "snes9xGX.h"
|
#include "fileop.h"
|
||||||
|
|
||||||
#define MAXDVDFILES 2000
|
#define MAXDVDFILES 2000
|
||||||
|
|
||||||
@ -502,7 +503,7 @@ getentry (int entrycount, unsigned char dvdbuffer[])
|
|||||||
* The return value is number of files collected, or -1 on failure.
|
* The return value is number of files collected, or -1 on failure.
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
int
|
int
|
||||||
ParseDVDdirectory ()
|
ParseDVDdirectory (bool change)
|
||||||
{
|
{
|
||||||
int pdlength;
|
int pdlength;
|
||||||
u64 pdoffset;
|
u64 pdoffset;
|
||||||
@ -513,6 +514,9 @@ ParseDVDdirectory ()
|
|||||||
|
|
||||||
// reset browser
|
// reset browser
|
||||||
ResetBrowser();
|
ResetBrowser();
|
||||||
|
|
||||||
|
if(change && !ChangeInterface(METHOD_DVD, NOTSILENT))
|
||||||
|
return 0;
|
||||||
|
|
||||||
pdoffset = rdoffset = dvddir;
|
pdoffset = rdoffset = dvddir;
|
||||||
pdlength = dvddirlength;
|
pdlength = dvddirlength;
|
||||||
@ -601,7 +605,7 @@ static bool SwitchDVDFolderR(char * dir, int maxDepth)
|
|||||||
if(browserList[dirindex].isdir) // only parse directories
|
if(browserList[dirindex].isdir) // only parse directories
|
||||||
{
|
{
|
||||||
UpdateDirName(METHOD_DVD);
|
UpdateDirName(METHOD_DVD);
|
||||||
ParseDVDdirectory();
|
ParseDVDdirectory(false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -636,7 +640,7 @@ bool SwitchDVDFolder(char origdir[])
|
|||||||
dvddir = dvdrootdir;
|
dvddir = dvdrootdir;
|
||||||
dvddirlength = dvdrootlength;
|
dvddirlength = dvdrootlength;
|
||||||
browser.dir[0] = 0;
|
browser.dir[0] = 0;
|
||||||
ParseDVDdirectory();
|
ParseDVDdirectory(true);
|
||||||
|
|
||||||
return SwitchDVDFolderR(dirptr, 0);
|
return SwitchDVDFolderR(dirptr, 0);
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
#define _NGCDVD_
|
#define _NGCDVD_
|
||||||
|
|
||||||
bool MountDVD(bool silent);
|
bool MountDVD(bool silent);
|
||||||
int ParseDVDdirectory();
|
int ParseDVDdirectory(bool change);
|
||||||
void SetDVDdirectory(u64 dir, int length);
|
void SetDVDdirectory(u64 dir, int length);
|
||||||
bool SwitchDVDFolder(char dir[]);
|
bool SwitchDVDFolder(char dir[]);
|
||||||
|
|
||||||
|
@ -501,11 +501,11 @@ int BrowserChangeFolder(int method)
|
|||||||
switch (method)
|
switch (method)
|
||||||
{
|
{
|
||||||
case METHOD_DVD:
|
case METHOD_DVD:
|
||||||
ParseDVDdirectory();
|
ParseDVDdirectory(true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ParseDirectory();
|
ParseDirectory(method);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -530,25 +530,18 @@ OpenGameList ()
|
|||||||
if(method == METHOD_AUTO)
|
if(method == METHOD_AUTO)
|
||||||
method = autoLoadMethod();
|
method = autoLoadMethod();
|
||||||
|
|
||||||
if(ChangeInterface(method, NOTSILENT))
|
// change current dir to roms directory
|
||||||
|
switch(method)
|
||||||
{
|
{
|
||||||
// change current dir to roms directory
|
case METHOD_DVD:
|
||||||
switch(method)
|
browser.dir[0] = 0;
|
||||||
{
|
if(ParseDVDdirectory(true)) // Parse root directory
|
||||||
case METHOD_DVD:
|
|
||||||
browser.dir[0] = 0;
|
|
||||||
ParseDVDdirectory(); // Parse root directory
|
|
||||||
SwitchDVDFolder(GCSettings.LoadFolder); // switch to ROM folder
|
SwitchDVDFolder(GCSettings.LoadFolder); // switch to ROM folder
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
sprintf(browser.dir, "/%s", GCSettings.LoadFolder);
|
sprintf(browser.dir, "/%s", GCSettings.LoadFolder);
|
||||||
ParseDirectory(); // Parse root directory
|
ParseDirectory(method); // Parse root directory
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ResetBrowser();
|
|
||||||
}
|
}
|
||||||
return browser.numEntries;
|
return browser.numEntries;
|
||||||
}
|
}
|
||||||
|
@ -182,6 +182,7 @@ bool MountFAT(int method)
|
|||||||
unmountRequired[method] = false;
|
unmountRequired[method] = false;
|
||||||
fatUnmount(rootdir);
|
fatUnmount(rootdir);
|
||||||
disc->shutdown();
|
disc->shutdown();
|
||||||
|
isMounted[method] = false;
|
||||||
}
|
}
|
||||||
if(!isMounted[method])
|
if(!isMounted[method])
|
||||||
{
|
{
|
||||||
@ -269,42 +270,51 @@ bool ChangeInterface(int method, bool silent)
|
|||||||
* Browse subdirectories
|
* Browse subdirectories
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
int
|
int
|
||||||
ParseDirectory()
|
ParseDirectory(int method)
|
||||||
{
|
{
|
||||||
DIR_ITER *dir;
|
DIR_ITER *dir = NULL;
|
||||||
char fulldir[MAXPATHLEN];
|
char fulldir[MAXPATHLEN];
|
||||||
char filename[MAXPATHLEN];
|
char filename[MAXPATHLEN];
|
||||||
char tmpname[MAXPATHLEN];
|
char tmpname[MAXPATHLEN];
|
||||||
struct stat filestat;
|
struct stat filestat;
|
||||||
struct tm * timeinfo;
|
struct tm * timeinfo;
|
||||||
char msg[128];
|
char msg[128];
|
||||||
|
int retry = 1;
|
||||||
ShowAction("Loading...");
|
|
||||||
|
|
||||||
// reset browser
|
// reset browser
|
||||||
ResetBrowser();
|
ResetBrowser();
|
||||||
|
|
||||||
// add device to path
|
ShowAction("Loading...");
|
||||||
sprintf(fulldir, "%s%s", rootdir, browser.dir);
|
|
||||||
|
|
||||||
// open the directory
|
// open the directory
|
||||||
dir = diropen(fulldir);
|
while(dir == NULL && retry == 1)
|
||||||
|
{
|
||||||
|
if(ChangeInterface(method, NOTSILENT))
|
||||||
|
{
|
||||||
|
sprintf(fulldir, "%s%s", rootdir, browser.dir); // add device to path
|
||||||
|
dir = diropen(fulldir);
|
||||||
|
if(dir == NULL)
|
||||||
|
{
|
||||||
|
unmountRequired[method] = true;
|
||||||
|
sprintf(msg, "Error opening %s", fulldir);
|
||||||
|
retry = ErrorPromptRetry(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we can't open the dir, try opening the root dir
|
||||||
if (dir == NULL)
|
if (dir == NULL)
|
||||||
{
|
{
|
||||||
sprintf(msg, "Error opening %s", fulldir);
|
if(ChangeInterface(method, SILENT))
|
||||||
ErrorPrompt(msg);
|
|
||||||
|
|
||||||
// if we can't open the dir, open root dir
|
|
||||||
sprintf(browser.dir,"/");
|
|
||||||
|
|
||||||
dir = diropen(rootdir);
|
|
||||||
|
|
||||||
if (dir == NULL)
|
|
||||||
{
|
{
|
||||||
sprintf(msg, "Error opening %s", rootdir);
|
sprintf(browser.dir,"/");
|
||||||
ErrorPrompt(msg);
|
dir = diropen(rootdir);
|
||||||
return -1;
|
if (dir == NULL)
|
||||||
|
{
|
||||||
|
sprintf(msg, "Error opening %s", rootdir);
|
||||||
|
ErrorPrompt(msg);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -430,9 +440,8 @@ LoadFile (char * rbuffer, char *filepath, u32 length, int method, bool silent)
|
|||||||
char zipbuffer[2048];
|
char zipbuffer[2048];
|
||||||
u32 size = 0;
|
u32 size = 0;
|
||||||
u32 readsize = 0;
|
u32 readsize = 0;
|
||||||
|
char fullpath[MAXPATHLEN];
|
||||||
if(!ChangeInterface(method, silent))
|
int retry = 1;
|
||||||
return 0;
|
|
||||||
|
|
||||||
switch(method)
|
switch(method)
|
||||||
{
|
{
|
||||||
@ -451,64 +460,75 @@ LoadFile (char * rbuffer, char *filepath, u32 length, int method, bool silent)
|
|||||||
// since we're loading a file
|
// since we're loading a file
|
||||||
LWP_SuspendThread (devicethread);
|
LWP_SuspendThread (devicethread);
|
||||||
|
|
||||||
// add device to filepath
|
// open the file
|
||||||
char fullpath[1024];
|
while(!size && retry == 1)
|
||||||
sprintf(fullpath, "%s%s", rootdir, filepath);
|
|
||||||
|
|
||||||
file = fopen (fullpath, "rb");
|
|
||||||
|
|
||||||
if (file > 0)
|
|
||||||
{
|
{
|
||||||
if(length > 0 && length <= 2048) // do a partial read (eg: to check file header)
|
if(ChangeInterface(method, silent))
|
||||||
{
|
{
|
||||||
size = fread (rbuffer, 1, length, file);
|
sprintf(fullpath, "%s%s", rootdir, filepath); // add device to filepath
|
||||||
}
|
file = fopen (fullpath, "rb");
|
||||||
else // load whole file
|
|
||||||
{
|
|
||||||
readsize = fread (zipbuffer, 1, 2048, file);
|
|
||||||
|
|
||||||
if(readsize > 0)
|
if(file > 0)
|
||||||
{
|
{
|
||||||
if (IsZipFile (zipbuffer))
|
if(length > 0 && length <= 2048) // do a partial read (eg: to check file header)
|
||||||
{
|
{
|
||||||
size = UnZipBuffer ((unsigned char *)rbuffer, method); // unzip
|
size = fread (rbuffer, 1, length, file);
|
||||||
}
|
}
|
||||||
else
|
else // load whole file
|
||||||
{
|
{
|
||||||
struct stat fileinfo;
|
readsize = fread (zipbuffer, 1, 2048, file);
|
||||||
fstat(file->_file, &fileinfo);
|
|
||||||
size = fileinfo.st_size;
|
|
||||||
|
|
||||||
memcpy (rbuffer, zipbuffer, readsize); // copy what we already read
|
if(readsize > 0)
|
||||||
|
|
||||||
u32 offset = readsize;
|
|
||||||
u32 nextread = 0;
|
|
||||||
while(offset < size)
|
|
||||||
{
|
{
|
||||||
if(size - offset > 1024*512) nextread = 1024*512;
|
if (IsZipFile (zipbuffer))
|
||||||
else nextread = size-offset;
|
{
|
||||||
ShowProgress ("Loading...", offset, size);
|
size = UnZipBuffer ((unsigned char *)rbuffer, method); // unzip
|
||||||
readsize = fread (rbuffer + offset, 1, nextread, file); // read in 512K chunks
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
struct stat fileinfo;
|
||||||
|
fstat(file->_file, &fileinfo);
|
||||||
|
size = fileinfo.st_size;
|
||||||
|
|
||||||
if(readsize <= 0 || readsize > (1024*512))
|
memcpy (rbuffer, zipbuffer, readsize); // copy what we already read
|
||||||
break; // read failure
|
|
||||||
|
|
||||||
if(readsize > 0)
|
u32 offset = readsize;
|
||||||
offset += readsize;
|
u32 nextread = 0;
|
||||||
|
while(offset < size)
|
||||||
|
{
|
||||||
|
if(size - offset > 1024*512) nextread = 1024*512;
|
||||||
|
else nextread = size-offset;
|
||||||
|
ShowProgress ("Loading...", offset, size);
|
||||||
|
readsize = fread (rbuffer + offset, 1, nextread, file); // read in next chunk
|
||||||
|
|
||||||
|
if(readsize <= 0 || readsize > nextread)
|
||||||
|
break; // read failure
|
||||||
|
|
||||||
|
if(readsize > 0)
|
||||||
|
offset += readsize;
|
||||||
|
}
|
||||||
|
CancelAction();
|
||||||
|
|
||||||
|
if(offset != size) // # bytes read doesn't match # expected
|
||||||
|
size = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
CancelAction();
|
|
||||||
|
|
||||||
if(offset != size) // # bytes read doesn't match # expected
|
|
||||||
size = 0;
|
|
||||||
}
|
}
|
||||||
|
fclose (file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!size)
|
||||||
|
{
|
||||||
|
if(!silent)
|
||||||
|
{
|
||||||
|
unmountRequired[method] = true;
|
||||||
|
retry = ErrorPromptRetry("Error loading file!");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
retry = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fclose (file);
|
|
||||||
}
|
|
||||||
if(!size && !silent)
|
|
||||||
{
|
|
||||||
unmountRequired[method] = true;
|
|
||||||
ErrorPrompt("Error loading file!");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// go back to checking if devices were inserted/removed
|
// go back to checking if devices were inserted/removed
|
||||||
@ -529,12 +549,11 @@ u32 LoadFile(char * filepath, int method, bool silent)
|
|||||||
u32
|
u32
|
||||||
SaveFile (char * buffer, char *filepath, u32 datasize, int method, bool silent)
|
SaveFile (char * buffer, char *filepath, u32 datasize, int method, bool silent)
|
||||||
{
|
{
|
||||||
if(datasize == 0)
|
char fullpath[MAXPATHLEN];
|
||||||
return 0;
|
|
||||||
|
|
||||||
u32 written = 0;
|
u32 written = 0;
|
||||||
|
int retry = 1;
|
||||||
|
|
||||||
if(!ChangeInterface(method, silent))
|
if(datasize == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ShowAction("Saving...");
|
ShowAction("Saving...");
|
||||||
@ -542,38 +561,41 @@ SaveFile (char * buffer, char *filepath, u32 datasize, int method, bool silent)
|
|||||||
if(method == METHOD_MC_SLOTA || method == METHOD_MC_SLOTB)
|
if(method == METHOD_MC_SLOTA || method == METHOD_MC_SLOTB)
|
||||||
{
|
{
|
||||||
if(method == METHOD_MC_SLOTA)
|
if(method == METHOD_MC_SLOTA)
|
||||||
written = SaveMCFile (buffer, CARD_SLOTA, filepath, datasize, silent);
|
return SaveMCFile (buffer, CARD_SLOTA, filepath, datasize, silent);
|
||||||
else
|
else
|
||||||
written = SaveMCFile (buffer, CARD_SLOTB, filepath, datasize, silent);
|
return SaveMCFile (buffer, CARD_SLOTB, filepath, datasize, silent);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
// stop checking if devices were removed/inserted
|
|
||||||
// since we're saving a file
|
|
||||||
LWP_SuspendThread (devicethread);
|
|
||||||
|
|
||||||
// add device to filepath
|
// stop checking if devices were removed/inserted
|
||||||
char fullpath[1024];
|
// since we're saving a file
|
||||||
sprintf(fullpath, "%s%s", rootdir, filepath);
|
LWP_SuspendThread (devicethread);
|
||||||
|
|
||||||
// open file for writing
|
while(!written && retry == 1)
|
||||||
file = fopen (fullpath, "wb");
|
{
|
||||||
|
if(ChangeInterface(method, silent))
|
||||||
if (file > 0)
|
|
||||||
{
|
{
|
||||||
written = fwrite (savebuffer, 1, datasize, file);
|
sprintf(fullpath, "%s%s", rootdir, filepath); // add device to filepath
|
||||||
fclose (file);
|
file = fopen (fullpath, "wb");
|
||||||
|
|
||||||
|
if (file > 0)
|
||||||
|
{
|
||||||
|
written = fwrite (savebuffer, 1, datasize, file);
|
||||||
|
if(written < datasize) written = 0;
|
||||||
|
fclose (file);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!written)
|
if(!written)
|
||||||
|
{
|
||||||
unmountRequired[method] = true;
|
unmountRequired[method] = true;
|
||||||
|
if(!silent)
|
||||||
|
retry = ErrorPromptRetry("Error saving file!");
|
||||||
|
else
|
||||||
|
retry = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// go back to checking if devices were inserted/removed
|
// go back to checking if devices were inserted/removed
|
||||||
LWP_ResumeThread (devicethread);
|
LWP_ResumeThread (devicethread);
|
||||||
}
|
|
||||||
|
|
||||||
if(!written && !silent)
|
|
||||||
ErrorPrompt("Error saving file!");
|
|
||||||
|
|
||||||
CancelAction();
|
CancelAction();
|
||||||
return written;
|
return written;
|
||||||
|
@ -27,7 +27,7 @@ void InitDeviceThread();
|
|||||||
void MountAllFAT();
|
void MountAllFAT();
|
||||||
void UnmountAllFAT();
|
void UnmountAllFAT();
|
||||||
bool ChangeInterface(int method, bool silent);
|
bool ChangeInterface(int method, bool silent);
|
||||||
int ParseDirectory();
|
int ParseDirectory(int method);
|
||||||
void AllocSaveBuffer();
|
void AllocSaveBuffer();
|
||||||
void FreeSaveBuffer();
|
void FreeSaveBuffer();
|
||||||
u32 LoadFile(char * rbuffer, char *filepath, u32 length, int method, bool silent);
|
u32 LoadFile(char * rbuffer, char *filepath, u32 length, int method, bool silent);
|
||||||
|
@ -179,6 +179,7 @@ WindowPrompt(const char *title, const char *msg, const char *btn1Label, const ch
|
|||||||
promptWindow.Append(&btn2);
|
promptWindow.Append(&btn2);
|
||||||
|
|
||||||
promptWindow.SetEffect(EFFECT_SLIDE_TOP | EFFECT_SLIDE_IN, 50);
|
promptWindow.SetEffect(EFFECT_SLIDE_TOP | EFFECT_SLIDE_IN, 50);
|
||||||
|
CancelAction();
|
||||||
HaltGui();
|
HaltGui();
|
||||||
mainWindow->SetState(STATE_DISABLED);
|
mainWindow->SetState(STATE_DISABLED);
|
||||||
mainWindow->Append(&promptWindow);
|
mainWindow->Append(&promptWindow);
|
||||||
@ -465,13 +466,16 @@ ShowAction (const char *msg)
|
|||||||
|
|
||||||
void ErrorPrompt(const char *msg)
|
void ErrorPrompt(const char *msg)
|
||||||
{
|
{
|
||||||
CancelAction();
|
|
||||||
WindowPrompt("Error", msg, "OK", NULL);
|
WindowPrompt("Error", msg, "OK", NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ErrorPromptRetry(const char *msg)
|
||||||
|
{
|
||||||
|
return WindowPrompt("Error", msg, "Retry", "Cancel");
|
||||||
|
}
|
||||||
|
|
||||||
void InfoPrompt(const char *msg)
|
void InfoPrompt(const char *msg)
|
||||||
{
|
{
|
||||||
CancelAction();
|
|
||||||
WindowPrompt("Information", msg, "OK", NULL);
|
WindowPrompt("Information", msg, "OK", NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1435,7 +1439,7 @@ static int MenuGameSaves(int action)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
strncpy(browser.dir, GCSettings.SaveFolder, 200);
|
strncpy(browser.dir, GCSettings.SaveFolder, 200);
|
||||||
ParseDirectory();
|
ParseDirectory(GCSettings.SaveMethod);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i=0; i < browser.numEntries; i++)
|
for(i=0; i < browser.numEntries; i++)
|
||||||
@ -1485,6 +1489,17 @@ static int MenuGameSaves(int action)
|
|||||||
{
|
{
|
||||||
saves.previewImg[j] = new GuiImageData(savebuffer);
|
saves.previewImg[j] = new GuiImageData(savebuffer);
|
||||||
}
|
}
|
||||||
|
/*char scrfile2[1024];
|
||||||
|
sprintf(scrfile, "%s/%s.png", GCSettings.SaveFolder, tmp);
|
||||||
|
sprintf(scrfile2, "%s/resave/%s.png", GCSettings.SaveFolder, tmp);
|
||||||
|
|
||||||
|
AllocSaveBuffer();
|
||||||
|
int scrsize = LoadFile(scrfile, GCSettings.SaveMethod, SILENT);
|
||||||
|
if(scrsize > 0)
|
||||||
|
{
|
||||||
|
//saves.previewImg[j] = new GuiImageData(savebuffer);
|
||||||
|
SaveFile(scrfile2, scrsize, GCSettings.SaveMethod, SILENT);
|
||||||
|
}*/
|
||||||
FreeSaveBuffer();
|
FreeSaveBuffer();
|
||||||
}
|
}
|
||||||
strftime(saves.date[j], 20, "%a %b %d", &browserList[j].mtime);
|
strftime(saves.date[j], 20, "%a %b %d", &browserList[j].mtime);
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
void InitGUIThreads();
|
void InitGUIThreads();
|
||||||
void MainMenu (int menuitem);
|
void MainMenu (int menuitem);
|
||||||
void ErrorPrompt(const char * msg);
|
void ErrorPrompt(const char * msg);
|
||||||
|
int ErrorPromptRetry(const char * msg);
|
||||||
void InfoPrompt(const char * msg);
|
void InfoPrompt(const char * msg);
|
||||||
void ShowAction (const char *msg);
|
void ShowAction (const char *msg);
|
||||||
void CancelAction();
|
void CancelAction();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user