vbagx/source/ngc/filesel.cpp

579 lines
15 KiB
C++
Raw Normal View History

/****************************************************************************
2008-09-17 04:27:55 +02:00
* Visual Boy Advance GX
*
2008-09-17 04:27:55 +02:00
* Tantric September 2008
*
* filesel.cpp
*
* Generic file routines - reading, writing, browsing
***************************************************************************/
#include <gccore.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wiiuse/wpad.h>
#include <sys/dir.h>
2008-09-26 08:23:00 +02:00
#include <malloc.h>
#ifdef HW_RVL
extern "C" {
#include <di/di.h>
}
#endif
#include "vba.h"
#include "vbasupport.h"
#include "vmmem.h"
#include "menudraw.h"
#include "video.h"
#include "fileop.h"
#include "filesel.h"
#include "memcardop.h"
#include "input.h"
#include "dvd.h"
2008-12-24 08:52:35 +01:00
#include "networkop.h"
#include "gcunzip.h"
BROWSERINFO browser;
BROWSERENTRY * browserList = NULL; // list of files/folders in browser
2008-12-18 19:58:30 +01:00
char rootdir[10];
char szpath[MAXPATHLEN];
bool inSz = false;
char ROMFilename[512];
bool ROMLoaded = false;
/****************************************************************************
* autoLoadMethod()
* Auto-determines and sets the load method
* Returns method set
****************************************************************************/
int autoLoadMethod()
{
2008-12-18 19:58:30 +01:00
ShowAction ("Attempting to determine load method...");
int method = 0;
2008-12-18 19:58:30 +01:00
if(ChangeInterface(METHOD_SD, SILENT))
method = METHOD_SD;
2008-12-18 19:58:30 +01:00
else if(ChangeInterface(METHOD_USB, SILENT))
method = METHOD_USB;
2008-12-18 19:58:30 +01:00
else if(ChangeInterface(METHOD_DVD, SILENT))
method = METHOD_DVD;
2008-12-18 19:58:30 +01:00
else if(ChangeInterface(METHOD_SMB, SILENT))
method = METHOD_SMB;
else
2008-12-18 19:58:30 +01:00
WaitPrompt("Unable to auto-determine load method!");
2008-12-24 08:52:35 +01:00
if(GCSettings.LoadMethod == METHOD_AUTO)
GCSettings.LoadMethod = method; // save method found for later use
return method;
}
/****************************************************************************
* autoSaveMethod()
* Auto-determines and sets the save method
* Returns method set
****************************************************************************/
int autoSaveMethod(bool silent)
{
if(!silent)
ShowAction ("Attempting to determine save method...");
int method = 0;
2008-12-18 19:58:30 +01:00
if(ChangeInterface(METHOD_SD, SILENT))
method = METHOD_SD;
2008-12-18 19:58:30 +01:00
else if(ChangeInterface(METHOD_USB, SILENT))
method = METHOD_USB;
else if(TestCard(CARD_SLOTA, SILENT))
method = METHOD_MC_SLOTA;
else if(TestCard(CARD_SLOTB, SILENT))
method = METHOD_MC_SLOTB;
2008-12-18 19:58:30 +01:00
else if(ChangeInterface(METHOD_SMB, SILENT))
method = METHOD_SMB;
else if(!silent)
2008-12-18 19:58:30 +01:00
WaitPrompt("Unable to auto-determine save method!");
2008-12-24 08:52:35 +01:00
if(GCSettings.SaveMethod == METHOD_AUTO)
GCSettings.SaveMethod = method; // save method found for later use
return method;
}
/****************************************************************************
* ResetBrowser()
* Clears the file browser memory, and allocates one initial entry
***************************************************************************/
void ResetBrowser()
{
browser.selIndex = browser.pageIndex = 0;
// Clear any existing values
if(browserList != NULL)
{
free(browserList);
browserList = NULL;
}
// set aside space for 1 entry
browserList = (BROWSERENTRY *)malloc(sizeof(BROWSERENTRY));
memset(browserList, 0, sizeof(BROWSERENTRY));
}
/****************************************************************************
* UpdateDirName()
* Update curent directory name for file browser
***************************************************************************/
int UpdateDirName(int method)
{
int size=0;
2008-11-12 08:53:25 +01:00
char * test;
char temp[1024];
2008-11-12 08:53:25 +01:00
// update DVD directory
if(method == METHOD_DVD)
SetDVDdirectory(browserList[browser.selIndex].offset, browserList[browser.selIndex].length);
/* current directory doesn't change */
if (strcmp(browserList[browser.selIndex].filename,".") == 0)
{
return 0;
}
/* go up to parent directory */
else if (strcmp(browserList[browser.selIndex].filename,"..") == 0)
{
/* determine last subdirectory namelength */
sprintf(temp,"%s",browser.dir);
test = strtok(temp,"/");
while (test != NULL)
{
size = strlen(test);
test = strtok(NULL,"/");
}
/* remove last subdirectory name */
size = strlen(browser.dir) - size - 1;
browser.dir[size] = 0;
return 1;
}
/* Open a directory */
else
{
/* test new directory namelength */
if ((strlen(browser.dir)+1+strlen(browserList[browser.selIndex].filename)) < MAXPATHLEN)
{
/* update current directory name */
sprintf(browser.dir, "%s/%s",browser.dir, browserList[browser.selIndex].filename);
return 1;
}
else
{
2008-12-18 19:58:30 +01:00
WaitPrompt("Directory name is too long!");
return -1;
}
}
}
2008-11-12 08:53:25 +01:00
bool MakeFilePath(char filepath[], int type, int method)
{
2008-11-12 08:53:25 +01:00
char file[512];
char folder[1024];
char temppath[MAXPATHLEN];
2008-11-12 08:53:25 +01:00
if(type == FILE_ROM)
{
2008-11-12 08:53:25 +01:00
// Check path length
if ((strlen(browser.dir)+1+strlen(browserList[browser.selIndex].filename)) >= MAXPATHLEN)
2008-11-12 08:53:25 +01:00
{
2008-12-18 19:58:30 +01:00
WaitPrompt("Maximum filepath length reached!");
2008-11-12 08:53:25 +01:00
filepath[0] = 0;
return false;
}
else
2008-11-12 08:53:25 +01:00
{
sprintf(temppath, "%s/%s",browser.dir,browserList[browser.selIndex].filename);
2008-11-12 08:53:25 +01:00
}
}
else
{
2008-11-12 08:53:25 +01:00
switch(type)
{
case FILE_SRAM:
sprintf(folder, GCSettings.SaveFolder);
sprintf(file, "%s.sav", ROMFilename);
break;
case FILE_SNAPSHOT:
sprintf(folder, GCSettings.SaveFolder);
sprintf(file, "%s.sgm", ROMFilename);
break;
case FILE_CHEAT:
sprintf(folder, GCSettings.CheatFolder);
sprintf(file, "%s.cht", ROMFilename);
break;
case FILE_PREF:
sprintf(folder, appPath);
2008-11-12 08:53:25 +01:00
sprintf(file, "%s", PREF_FILE_NAME);
break;
}
switch(method)
{
case METHOD_MC_SLOTA:
case METHOD_MC_SLOTB:
sprintf (temppath, "%s", file);
temppath[31] = 0; // truncate filename
break;
2008-12-18 19:58:30 +01:00
default:
sprintf (temppath, "%s/%s", folder, file);
break;
2008-11-12 08:53:25 +01:00
}
}
strcpy(filepath, temppath);
return true;
}
/****************************************************************************
* FileSortCallback
*
* Quick sort callback to sort file entries with the following order:
* .
* ..
* <dirs>
* <files>
***************************************************************************/
int FileSortCallback(const void *f1, const void *f2)
{
/* Special case for implicit directories */
if(((BROWSERENTRY *)f1)->filename[0] == '.' || ((BROWSERENTRY *)f2)->filename[0] == '.')
{
if(strcmp(((BROWSERENTRY *)f1)->filename, ".") == 0) { return -1; }
if(strcmp(((BROWSERENTRY *)f2)->filename, ".") == 0) { return 1; }
if(strcmp(((BROWSERENTRY *)f1)->filename, "..") == 0) { return -1; }
if(strcmp(((BROWSERENTRY *)f2)->filename, "..") == 0) { return 1; }
}
/* If one is a file and one is a directory the directory is first. */
if(((BROWSERENTRY *)f1)->isdir && !(((BROWSERENTRY *)f2)->isdir)) return -1;
if(!(((BROWSERENTRY *)f1)->isdir) && ((BROWSERENTRY *)f2)->isdir) return 1;
return stricmp(((BROWSERENTRY *)f1)->filename, ((BROWSERENTRY *)f2)->filename);
}
/****************************************************************************
* IsSz
*
* Checks if the specified file is a 7z
***************************************************************************/
bool IsSz()
{
if (strlen(browserList[browser.selIndex].filename) > 4)
{
char * p = strrchr(browserList[browser.selIndex].filename, '.');
if (p != NULL)
if(stricmp(p, ".7z") == 0)
return true;
}
return false;
}
/****************************************************************************
* StripExt
*
* Strips an extension from a filename
***************************************************************************/
void StripExt(char* returnstring, char * inputstring)
{
char* loc_dot;
strcpy (returnstring, inputstring);
loc_dot = strrchr(returnstring,'.');
if (loc_dot != NULL)
*loc_dot = 0; // strip file extension
}
/****************************************************************************
* FileSelector
*
* Let user select a file from the listing
***************************************************************************/
int FileSelector (int method)
{
u32 p = 0;
u32 wp = 0;
u32 ph = 0;
u32 wh = 0;
signed char gc_ay = 0;
signed char gc_sx = 0;
signed char wm_ay = 0;
signed char wm_sx = 0;
int haverom = 0;
int redraw = 1;
int selectit = 0;
int scroll_delay = 0;
bool move_selection = 0;
#define SCROLL_INITIAL_DELAY 15
#define SCROLL_LOOP_DELAY 2
while (haverom == 0)
{
if (redraw)
ShowFiles (browserList, browser.numEntries, browser.pageIndex, browser.selIndex);
redraw = 0;
VIDEO_WaitVSync(); // slow things down a bit so we don't overread the pads
gc_ay = PAD_StickY (0);
gc_sx = PAD_SubStickX (0);
p = PAD_ButtonsDown (0);
ph = PAD_ButtonsHeld (0);
#ifdef HW_RVL
2008-10-09 08:48:46 +02:00
wm_ay = WPAD_Stick (0, 0, 0);
wm_sx = WPAD_Stick (0, 1, 1);
wp = WPAD_ButtonsDown (0);
wh = WPAD_ButtonsHeld (0);
#endif
/*** Check for exit combo ***/
if ( (gc_sx < -70) || (wm_sx < -70) || (wp & WPAD_BUTTON_HOME) || (wp & WPAD_CLASSIC_BUTTON_HOME) )
return 0;
/*** Check buttons, perform actions ***/
if ( (p & PAD_BUTTON_A) || selectit || (wp & (WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A)) )
{
if ( selectit )
selectit = 0;
if (browserList[browser.selIndex].isdir) // This is directory
{
/* update current directory and set new entry list if directory has changed */
int status;
if(inSz && browser.selIndex == 0) // inside a 7z, requesting to leave
{
if(method == METHOD_DVD)
SetDVDdirectory(browserList[0].offset, browserList[0].length);
inSz = false;
status = 1;
SzClose();
}
else
{
status = UpdateDirName(method);
}
if (status == 1) // ok, open directory
{
switch (method)
{
case METHOD_DVD:
browser.numEntries = ParseDVDdirectory();
2008-12-18 19:58:30 +01:00
break;
2008-12-18 19:58:30 +01:00
default:
browser.numEntries = ParseDirectory();
2008-12-18 19:58:30 +01:00
break;
}
if (!browser.numEntries)
{
2008-12-18 19:58:30 +01:00
WaitPrompt ("Error reading directory!");
haverom = 1; // quit menu
}
}
else if (status == -1) // directory name too long
{
haverom = 1; // quit menu
}
}
else // this is a file
{
// 7z file - let's open it up to select a file inside
if(IsSz())
{
// we'll store the 7z filepath for extraction later
2008-11-12 08:53:25 +01:00
if(!MakeFilePath(szpath, FILE_ROM, method))
return 0;
2008-11-12 08:53:25 +01:00
2008-12-18 19:58:30 +01:00
// add device to filepath
char fullpath[1024];
sprintf(fullpath, "%s%s", rootdir, szpath);
strcpy(szpath, fullpath);
int szfiles = SzParse(szpath, method);
if(szfiles)
{
browser.numEntries = szfiles;
inSz = true;
}
else
2008-12-18 19:58:30 +01:00
WaitPrompt("Error opening archive!");
}
else
{
// store the filename (w/o ext) - used for sram/freeze naming
StripExt(ROMFilename, browserList[browser.selIndex].filename);
2008-12-18 19:58:30 +01:00
ShowAction ("Loading...");
ROMLoaded = LoadVBAROM(method);
inSz = false;
if (ROMLoaded)
{
return 1;
}
}
}
redraw = 1;
} // End of A
if ( (p & PAD_BUTTON_B) || (wp & (WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B)) )
{
while ( (PAD_ButtonsDown(0) & PAD_BUTTON_B)
#ifdef HW_RVL
|| (WPAD_ButtonsDown(0) & (WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B))
#endif
)
VIDEO_WaitVSync();
if ( strcmp(browserList[0].filename,"..") == 0 )
{
browser.selIndex = 0;
selectit = 1;
}
else if ( strcmp(browserList[1].filename,"..") == 0 )
{
browser.selIndex = selectit = 1;
} else {
return 0;
}
} // End of B
if ( ((p | ph) & PAD_BUTTON_DOWN) || ((wp | wh) & (WPAD_BUTTON_DOWN | WPAD_CLASSIC_BUTTON_DOWN)) || (gc_ay < -PADCAL) || (wm_ay < -PADCAL) )
{
if ( (p & PAD_BUTTON_DOWN) || (wp & (WPAD_BUTTON_DOWN | WPAD_CLASSIC_BUTTON_DOWN)) ) { /*** Button just pressed ***/
scroll_delay = SCROLL_INITIAL_DELAY; // reset scroll delay.
move_selection = 1; //continue (move selection)
}
else if (scroll_delay == 0) { /*** Button is held ***/
scroll_delay = SCROLL_LOOP_DELAY;
move_selection = 1; //continue (move selection)
} else {
scroll_delay--; // wait
}
if (move_selection)
{
browser.selIndex++;
if (browser.selIndex == browser.numEntries)
browser.selIndex = browser.pageIndex = 0;
if ((browser.selIndex - browser.pageIndex) >= PAGESIZE)
browser.pageIndex += PAGESIZE;
redraw = 1;
move_selection = 0;
}
} // End of down
if ( ((p | ph) & PAD_BUTTON_UP) || ((wp | wh) & (WPAD_BUTTON_UP | WPAD_CLASSIC_BUTTON_UP)) || (gc_ay > PADCAL) || (wm_ay > PADCAL) )
{
if ( (p & PAD_BUTTON_UP) || (wp & (WPAD_BUTTON_UP | WPAD_CLASSIC_BUTTON_UP)) ) { /*** Button just pressed***/
scroll_delay = SCROLL_INITIAL_DELAY; // reset scroll delay.
move_selection = 1; //continue (move selection)
}
else if (scroll_delay == 0) { /*** Button is held ***/
scroll_delay = SCROLL_LOOP_DELAY;
move_selection = 1; //continue (move selection)
} else {
scroll_delay--; // wait
}
if (move_selection)
{
browser.selIndex--;
if (browser.selIndex < 0) {
browser.selIndex = browser.numEntries - 1;
browser.pageIndex = browser.selIndex - PAGESIZE + 1;
}
if (browser.selIndex < browser.pageIndex)
browser.pageIndex -= PAGESIZE;
if (browser.pageIndex < 0)
browser.pageIndex = 0;
redraw = 1;
move_selection = 0;
}
} // End of Up
if ( (p & PAD_BUTTON_LEFT) || (wp & (WPAD_BUTTON_LEFT | WPAD_CLASSIC_BUTTON_LEFT)) )
{
/*** Go back a page ***/
browser.selIndex -= PAGESIZE;
if (browser.selIndex < 0)
{
browser.selIndex = browser.numEntries - 1;
browser.pageIndex = browser.selIndex - PAGESIZE + 1;
}
if (browser.selIndex < browser.pageIndex)
browser.pageIndex -= PAGESIZE;
if (browser.pageIndex < 0)
browser.pageIndex = 0;
redraw = 1;
}
if ( (p & PAD_BUTTON_RIGHT) || (wp & (WPAD_BUTTON_RIGHT | WPAD_CLASSIC_BUTTON_RIGHT)) )
{
/*** Go forward a page ***/
browser.selIndex += PAGESIZE;
if (browser.selIndex > browser.numEntries - 1)
browser.selIndex = browser.pageIndex = 0;
if ((browser.selIndex - browser.pageIndex) >= PAGESIZE)
browser.pageIndex += PAGESIZE;
redraw = 1;
}
}
return 0;
}
/****************************************************************************
2008-12-18 19:58:30 +01:00
* OpenROM
* Opens device specified by method, displays a list of ROMS
***************************************************************************/
int
2008-12-18 19:58:30 +01:00
OpenROM (int method)
{
2008-12-18 19:58:30 +01:00
if(method == METHOD_AUTO)
method = autoLoadMethod();
2008-12-18 19:58:30 +01:00
if(ChangeInterface(method, NOTSILENT))
{
// change current dir to roms directory
switch(method)
{
2008-12-18 19:58:30 +01:00
case METHOD_DVD:
browser.dir[0] = 0;
browser.numEntries = ParseDVDdirectory(); // Parse root directory
2008-12-18 19:58:30 +01:00
SwitchDVDFolder(GCSettings.LoadFolder); // switch to ROM folder
break;
default:
sprintf(browser.dir, "/%s", GCSettings.LoadFolder);
browser.numEntries = ParseDirectory(); // Parse root directory
2008-12-18 19:58:30 +01:00
break;
}
if (browser.numEntries > 0)
{
// Select an entry
return FileSelector (method);
}
else
{
// no entries found
2008-12-18 19:58:30 +01:00
WaitPrompt ("No Files Found!");
return 0;
}
}
return 0;
}