mirror of
https://github.com/dborth/snes9xgx.git
synced 2024-11-01 00:15:14 +01:00
fix GC DVD support
This commit is contained in:
parent
1a366b7a1f
commit
d253f9f590
@ -11,7 +11,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <dvd.h>
|
|
||||||
|
|
||||||
#include "menudraw.h"
|
#include "menudraw.h"
|
||||||
#include "snes9xGx.h"
|
#include "snes9xGx.h"
|
||||||
@ -20,6 +19,10 @@
|
|||||||
extern int offset;
|
extern int offset;
|
||||||
extern int selection;
|
extern int selection;
|
||||||
extern FILEENTRIES filelist[MAXFILES];
|
extern FILEENTRIES filelist[MAXFILES];
|
||||||
|
extern int maxfiles;
|
||||||
|
u64 dvddir = 0;
|
||||||
|
u64 dvdrootdir = 0;
|
||||||
|
int dvddirlength = 0;
|
||||||
|
|
||||||
/** DVD I/O Address base **/
|
/** DVD I/O Address base **/
|
||||||
volatile unsigned long *dvd = (volatile unsigned long *) 0xCC006000;
|
volatile unsigned long *dvd = (volatile unsigned long *) 0xCC006000;
|
||||||
@ -105,8 +108,6 @@ dvd_read (void *dst, unsigned int len, u64 offset)
|
|||||||
/** Minimal Primary Volume Descriptor **/
|
/** Minimal Primary Volume Descriptor **/
|
||||||
#define PVDROOT 0x9c
|
#define PVDROOT 0x9c
|
||||||
static int IsJoliet = 0;
|
static int IsJoliet = 0;
|
||||||
u64 rootdir = 0;
|
|
||||||
int rootdirlength = 0;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Primary Volume Descriptor
|
* Primary Volume Descriptor
|
||||||
@ -117,62 +118,81 @@ int rootdirlength = 0;
|
|||||||
int
|
int
|
||||||
getpvd ()
|
getpvd ()
|
||||||
{
|
{
|
||||||
int sector = 16;
|
int sector = 16;
|
||||||
u32 rootdir32;
|
u32 rootdir32;
|
||||||
|
|
||||||
rootdir = rootdirlength = 0;
|
dvddir = dvddirlength = 0;
|
||||||
IsJoliet = -1;
|
IsJoliet = -1;
|
||||||
|
|
||||||
/** Look for Joliet PVD first **/
|
/** Look for Joliet PVD first **/
|
||||||
while (sector < 32)
|
while (sector < 32)
|
||||||
{
|
|
||||||
if (dvd_read (dvdbuffer, 2048, (u64)(sector << 11)))
|
|
||||||
{
|
{
|
||||||
if (memcmp (&dvdbuffer, "\2CD001\1", 8) == 0)
|
if (dvd_read (dvdbuffer, 2048, (u64)(sector << 11)))
|
||||||
{
|
{
|
||||||
memcpy(&rootdir32, &dvdbuffer[PVDROOT + EXTENT], 4);
|
if (memcmp (&dvdbuffer, "\2CD001\1", 8) == 0)
|
||||||
rootdir = (u64)rootdir32;
|
{
|
||||||
rootdir <<= 11;
|
memcpy(&rootdir32, &dvdbuffer[PVDROOT + EXTENT], 4);
|
||||||
memcpy (&rootdirlength, &dvdbuffer[PVDROOT + FILE_LENGTH], 4);
|
dvddir = (u64)rootdir32;
|
||||||
IsJoliet = 1;
|
dvddir <<= 11;
|
||||||
break;
|
dvdrootdir = dvddir;
|
||||||
}
|
memcpy (&dvddirlength, &dvdbuffer[PVDROOT + FILE_LENGTH], 4);
|
||||||
|
IsJoliet = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return 0; /*** Can't read sector! ***/
|
||||||
|
sector++;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
return 0; /*** Can't read sector! ***/
|
|
||||||
|
|
||||||
sector++;
|
if (IsJoliet > 0) /*** Joliet PVD Found ? ***/
|
||||||
}
|
return 1;
|
||||||
|
|
||||||
if (IsJoliet > 0) /*** Joliet PVD Found ? ***/
|
sector = 16;
|
||||||
return 1;
|
|
||||||
|
|
||||||
sector = 16;
|
|
||||||
|
|
||||||
/*** Look for standard ISO9660 PVD ***/
|
/*** Look for standard ISO9660 PVD ***/
|
||||||
while (sector < 32)
|
while (sector < 32)
|
||||||
{
|
|
||||||
if (dvd_read (&dvdbuffer, 2048, sector << 11))
|
|
||||||
{
|
{
|
||||||
if (memcmp (&dvdbuffer, "\1CD001\1", 8) == 0)
|
if (dvd_read (&dvdbuffer, 2048, sector << 11))
|
||||||
{
|
{
|
||||||
memcpy (&rootdir32, &dvdbuffer[PVDROOT + EXTENT], 4);
|
if (memcmp (&dvdbuffer, "\1CD001\1", 8) == 0)
|
||||||
rootdir = (u64)rootdir32;
|
{
|
||||||
rootdir <<= 11;
|
memcpy (&rootdir32, &dvdbuffer[PVDROOT + EXTENT], 4);
|
||||||
memcpy (&rootdirlength, &dvdbuffer[PVDROOT + FILE_LENGTH], 4);
|
dvddir = (u64)rootdir32;
|
||||||
IsJoliet = 0;
|
dvddir <<= 11;
|
||||||
break;
|
dvdrootdir = dvddir;
|
||||||
}
|
memcpy (&dvddirlength, &dvdbuffer[PVDROOT + FILE_LENGTH], 4);
|
||||||
|
IsJoliet = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return 0; /*** Can't read sector! ***/
|
||||||
|
sector++;
|
||||||
}
|
}
|
||||||
else
|
return (IsJoliet == 0);
|
||||||
return 0; /*** Can't read sector! ***/
|
}
|
||||||
|
|
||||||
sector++;
|
/****************************************************************************
|
||||||
|
* TestDVD()
|
||||||
|
*
|
||||||
|
* Tests if a ISO9660 DVD is inserted and available
|
||||||
|
****************************************************************************/
|
||||||
|
bool TestDVD()
|
||||||
|
{
|
||||||
|
// DVD not available on Wii - disable
|
||||||
|
#ifdef HW_RVL
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
if (!getpvd())
|
||||||
|
{
|
||||||
return (IsJoliet == 0);
|
DVD_Mount();
|
||||||
|
if (!getpvd())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -185,112 +205,112 @@ static int diroffset = 0;
|
|||||||
static int
|
static int
|
||||||
getentry (int entrycount)
|
getentry (int entrycount)
|
||||||
{
|
{
|
||||||
char fname[512]; /* Huge, but experience has determined this */
|
char fname[512]; /* Huge, but experience has determined this */
|
||||||
char *ptr;
|
char *ptr;
|
||||||
char *filename;
|
char *filename;
|
||||||
char *filenamelength;
|
char *filenamelength;
|
||||||
char *rr;
|
char *rr;
|
||||||
int j;
|
int j;
|
||||||
u32 offset32;
|
u32 offset32;
|
||||||
|
|
||||||
/* Basic checks */
|
/* Basic checks */
|
||||||
if (entrycount >= MAXFILES)
|
if (entrycount >= MAXFILES)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (diroffset >= 2048)
|
if (diroffset >= 2048)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/** Decode this entry **/
|
/** Decode this entry **/
|
||||||
if (dvdbuffer[diroffset]) /* Record length available */
|
if (dvdbuffer[diroffset]) /* Record length available */
|
||||||
{
|
|
||||||
/* Update offsets into sector buffer */
|
|
||||||
ptr = (char *) &dvdbuffer[0];
|
|
||||||
ptr += diroffset;
|
|
||||||
filename = ptr + FILENAME;
|
|
||||||
filenamelength = ptr + FILENAME_LENGTH;
|
|
||||||
|
|
||||||
/* Check for wrap round - illegal in ISO spec,
|
|
||||||
* but certain crap writers do it! */
|
|
||||||
if ((diroffset + dvdbuffer[diroffset]) > 2048)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (*filenamelength)
|
|
||||||
{
|
{
|
||||||
memset (&fname, 0, 512);
|
/* Update offsets into sector buffer */
|
||||||
|
ptr = (char *) &dvdbuffer[0];
|
||||||
|
ptr += diroffset;
|
||||||
|
filename = ptr + FILENAME;
|
||||||
|
filenamelength = ptr + FILENAME_LENGTH;
|
||||||
|
|
||||||
if (!IsJoliet) /*** Do ISO 9660 first ***/
|
/* Check for wrap round - illegal in ISO spec,
|
||||||
strcpy (fname, filename);
|
* but certain crap writers do it! */
|
||||||
else
|
if ((diroffset + dvdbuffer[diroffset]) > 2048)
|
||||||
{ /*** The more tortuous unicode joliet entries ***/
|
return 0;
|
||||||
|
|
||||||
for (j = 0; j < (*filenamelength >> 1); j++)
|
if (*filenamelength)
|
||||||
{
|
{
|
||||||
fname[j] = filename[j * 2 + 1];
|
memset (&fname, 0, 512);
|
||||||
}
|
|
||||||
|
|
||||||
fname[j] = 0;
|
if (!IsJoliet) /*** Do ISO 9660 first ***/
|
||||||
|
strcpy (fname, filename);
|
||||||
|
else
|
||||||
|
{ /*** The more tortuous unicode joliet entries ***/
|
||||||
|
for (j = 0; j < (*filenamelength >> 1); j++)
|
||||||
|
{
|
||||||
|
fname[j] = filename[j * 2 + 1];
|
||||||
|
}
|
||||||
|
|
||||||
if (strlen (fname) >= MAXJOLIET)
|
fname[j] = 0;
|
||||||
fname[MAXJOLIET] = 0;
|
|
||||||
|
|
||||||
if (strlen (fname) == 0)
|
if (strlen (fname) >= MAXJOLIET)
|
||||||
fname[0] = filename[0];
|
fname[MAXJOLIET] = 0;
|
||||||
}
|
|
||||||
|
|
||||||
if (strlen (fname) == 0)
|
if (strlen (fname) == 0)
|
||||||
strcpy (fname, "ROOT");
|
fname[0] = filename[0];
|
||||||
else
|
}
|
||||||
{
|
|
||||||
if (fname[0] == 1)
|
|
||||||
strcpy (fname, "..");
|
|
||||||
else
|
|
||||||
{ /*
|
|
||||||
* Move *filenamelength to t,
|
|
||||||
* Only to stop gcc warning for noobs :)
|
|
||||||
*/
|
|
||||||
int t = *filenamelength;
|
|
||||||
fname[t] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (strlen (fname) == 0) // root entry
|
||||||
|
{
|
||||||
|
fname[0] = 0; // we'll skip it by setting the filename to 0 length
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (fname[0] == 1)
|
||||||
|
{
|
||||||
|
if(dvddir == dvdrootdir) // at root already, don't show ..
|
||||||
|
fname[0] = 0;
|
||||||
|
else
|
||||||
|
strcpy (fname, "..");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Move *filenamelength to t,
|
||||||
|
* Only to stop gcc warning for noobs :)
|
||||||
|
*/
|
||||||
|
int t = *filenamelength;
|
||||||
|
fname[t] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
/** Rockridge Check **/
|
/** Rockridge Check **/
|
||||||
rr = strstr (fname, ";");
|
rr = strstr (fname, ";");
|
||||||
if (rr != NULL)
|
if (rr != NULL)
|
||||||
*rr = 0;
|
*rr = 0;
|
||||||
|
|
||||||
strcpy (filelist[entrycount].filename, fname);
|
strcpy (filelist[entrycount].filename, fname);
|
||||||
fname[MAXDISPLAY] = 0;
|
fname[MAXDISPLAY] = 0;
|
||||||
strcpy (filelist[entrycount].displayname, fname);
|
strcpy (filelist[entrycount].displayname, fname);
|
||||||
|
|
||||||
memcpy (&offset32,
|
memcpy (&offset32, &dvdbuffer[diroffset + EXTENT], 4);
|
||||||
&dvdbuffer[diroffset + EXTENT], 4);
|
|
||||||
filelist[entrycount].offset = (u64)offset32;
|
|
||||||
memcpy (&filelist[entrycount].length,
|
|
||||||
&dvdbuffer[diroffset + FILE_LENGTH], 4);
|
|
||||||
memcpy (&filelist[entrycount].flags,
|
|
||||||
&dvdbuffer[diroffset + FILE_FLAGS], 1);
|
|
||||||
|
|
||||||
filelist[entrycount].offset <<= 11;
|
filelist[entrycount].offset = (u64)offset32;
|
||||||
filelist[entrycount].flags = filelist[entrycount].flags & 2;
|
memcpy (&filelist[entrycount].length, &dvdbuffer[diroffset + FILE_LENGTH], 4);
|
||||||
|
memcpy (&filelist[entrycount].flags, &dvdbuffer[diroffset + FILE_FLAGS], 1);
|
||||||
|
|
||||||
|
filelist[entrycount].offset <<= 11;
|
||||||
|
filelist[entrycount].flags = filelist[entrycount].flags & 2;
|
||||||
|
|
||||||
/*** Prepare for next entry ***/
|
/*** Prepare for next entry ***/
|
||||||
diroffset += dvdbuffer[diroffset];
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
|
diroffset += dvdbuffer[diroffset];
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* parseDVDdirectory
|
* parseDVDdirectory
|
||||||
*
|
*
|
||||||
* This function will parse the directory tree.
|
* This function will parse the directory tree.
|
||||||
* It relies on rootdir and rootdirlength being pre-populated by a call to
|
* It relies on dvddir and dvddirlength being pre-populated by a call to
|
||||||
* getpvd, a previous parse or a menu selection.
|
* getpvd, a previous parse or a menu selection.
|
||||||
*
|
*
|
||||||
* The return value is number of files collected, or 0 on failure.
|
* The return value is number of files collected, or 0 on failure.
|
||||||
@ -298,48 +318,115 @@ getentry (int entrycount)
|
|||||||
int
|
int
|
||||||
ParseDVDdirectory ()
|
ParseDVDdirectory ()
|
||||||
{
|
{
|
||||||
int pdlength;
|
int pdlength;
|
||||||
u64 pdoffset;
|
u64 pdoffset;
|
||||||
u64 rdoffset;
|
u64 rdoffset;
|
||||||
int len = 0;
|
int len = 0;
|
||||||
int filecount = 0;
|
int filecount = 0;
|
||||||
|
|
||||||
// initialize selection
|
// initialize selection
|
||||||
selection = offset = 0;
|
selection = offset = 0;
|
||||||
|
|
||||||
pdoffset = rdoffset = rootdir;
|
pdoffset = rdoffset = dvddir;
|
||||||
pdlength = rootdirlength;
|
pdlength = dvddirlength;
|
||||||
filecount = 0;
|
filecount = 0;
|
||||||
|
|
||||||
/*** Clear any existing values ***/
|
// Clear any existing values
|
||||||
memset (&filelist, 0, sizeof (FILEENTRIES) * MAXFILES);
|
memset (&filelist, 0, sizeof (FILEENTRIES) * MAXFILES);
|
||||||
|
|
||||||
/*** Get as many files as possible ***/
|
/*** Get as many files as possible ***/
|
||||||
while (len < pdlength)
|
while (len < pdlength)
|
||||||
{
|
|
||||||
if (dvd_read (&dvdbuffer, 2048, pdoffset) == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
diroffset = 0;
|
|
||||||
|
|
||||||
while (getentry (filecount))
|
|
||||||
{
|
{
|
||||||
if (filecount < MAXFILES)
|
if (dvd_read (&dvdbuffer, 2048, pdoffset) == 0)
|
||||||
filecount++;
|
return 0;
|
||||||
|
|
||||||
|
diroffset = 0;
|
||||||
|
|
||||||
|
while (getentry (filecount))
|
||||||
|
{
|
||||||
|
if(strlen(filelist[filecount].filename) > 0 && filecount < MAXFILES)
|
||||||
|
filecount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
len += 2048;
|
||||||
|
pdoffset = rdoffset + len;
|
||||||
}
|
}
|
||||||
|
|
||||||
len += 2048;
|
// Sort the file list
|
||||||
pdoffset = rdoffset + len;
|
qsort(filelist, filecount, sizeof(FILEENTRIES), FileSortCallback);
|
||||||
}
|
|
||||||
|
|
||||||
return filecount;
|
return filecount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DirectorySearch
|
||||||
|
*
|
||||||
|
* Searches for the directory name specified within the current directory
|
||||||
|
* Returns the index of the directory, or 0 if not found
|
||||||
|
*/
|
||||||
|
int DirectorySearch(char dir[512])
|
||||||
|
{
|
||||||
|
for (int i = 0; i < maxfiles; i++ )
|
||||||
|
if (strcmp(filelist[i].filename, dir) == 0)
|
||||||
|
return i;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SwitchDVDFolder
|
||||||
|
*
|
||||||
|
* Function to switch to the directory snes9x/roms, if it exists
|
||||||
|
* Also loads the folder contents
|
||||||
|
* Recursively searches for any directory path 'dir' specified
|
||||||
|
*/
|
||||||
|
bool SwitchDVDFolder(char * dir, int maxDepth)
|
||||||
|
{
|
||||||
|
if(maxDepth > 8) // only search to a max depth of 8 levels
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bool lastdir = false;
|
||||||
|
char * nextdir = 0;
|
||||||
|
unsigned int t = strcspn(dir, "/");
|
||||||
|
|
||||||
|
if(t != strlen(dir))
|
||||||
|
nextdir = dir + t + 1; // next directory path to find
|
||||||
|
else
|
||||||
|
lastdir = true;
|
||||||
|
|
||||||
|
dir[t] = 0;
|
||||||
|
|
||||||
|
int dirindex = DirectorySearch(dir);
|
||||||
|
if(dirindex)
|
||||||
|
{
|
||||||
|
dvddir = filelist[dirindex].offset;
|
||||||
|
dvddirlength = filelist[dirindex].length;
|
||||||
|
maxfiles = ParseDVDdirectory();
|
||||||
|
|
||||||
|
if(lastdir)
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return SwitchDVDFolder(nextdir, maxDepth++);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SwitchDVDFolder(char * dir)
|
||||||
|
{
|
||||||
|
// strip off leading/trailing slashes on the directory path
|
||||||
|
// we don't want to screw up our recursion!
|
||||||
|
if(dir[0] == '/')
|
||||||
|
dir = dir + 1;
|
||||||
|
if(dir[strlen(dir)-1] == '/')
|
||||||
|
dir[strlen(dir)-1] = 0;
|
||||||
|
|
||||||
|
return SwitchDVDFolder(dir, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* LoadDVDFile
|
* LoadDVDFile
|
||||||
* This function will load a file from DVD, in BIN, SMD or ZIP format.
|
* This function will load a file from DVD, in BIN, SMD or ZIP format.
|
||||||
* The values for offset and length are inherited from rootdir and
|
* The values for offset and length are inherited from dvddir and
|
||||||
* rootdirlength.
|
* dvddirlength.
|
||||||
*
|
*
|
||||||
* The buffer parameter should re-use the initial ROM buffer.
|
* The buffer parameter should re-use the initial ROM buffer.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -347,47 +434,42 @@ ParseDVDdirectory ()
|
|||||||
int
|
int
|
||||||
LoadDVDFile (unsigned char *buffer)
|
LoadDVDFile (unsigned char *buffer)
|
||||||
{
|
{
|
||||||
int offset;
|
int offset;
|
||||||
int blocks;
|
int blocks;
|
||||||
int i;
|
int i;
|
||||||
u64 discoffset;
|
u64 discoffset;
|
||||||
char readbuffer[2048];
|
char readbuffer[2048];
|
||||||
|
|
||||||
// How many 2k blocks to read
|
// How many 2k blocks to read
|
||||||
blocks = rootdirlength / 2048;
|
blocks = dvddirlength / 2048;
|
||||||
offset = 0;
|
offset = 0;
|
||||||
discoffset = rootdir;
|
discoffset = dvddir;
|
||||||
ShowAction ((char*) "Loading...");
|
ShowAction ((char*) "Loading...");
|
||||||
dvd_read (readbuffer, 2048, discoffset);
|
dvd_read (readbuffer, 2048, discoffset);
|
||||||
|
|
||||||
if (!IsZipFile (readbuffer))
|
if (!IsZipFile (readbuffer))
|
||||||
|
{
|
||||||
|
for (i = 0; i < blocks; i++)
|
||||||
|
{
|
||||||
|
dvd_read (readbuffer, 2048, discoffset);
|
||||||
|
memcpy (buffer + offset, readbuffer, 2048);
|
||||||
|
offset += 2048;
|
||||||
|
discoffset += 2048;
|
||||||
|
}
|
||||||
|
|
||||||
{
|
/*** And final cleanup ***/
|
||||||
for (i = 0; i < blocks; i++)
|
if (dvddirlength % 2048)
|
||||||
|
{
|
||||||
{
|
i = dvddirlength % 2048;
|
||||||
dvd_read (readbuffer, 2048, discoffset);
|
dvd_read (readbuffer, 2048, discoffset);
|
||||||
memcpy (buffer + offset, readbuffer, 2048);
|
memcpy (buffer + offset, readbuffer, i);
|
||||||
offset += 2048;
|
}
|
||||||
discoffset += 2048;
|
}
|
||||||
}
|
else
|
||||||
|
{
|
||||||
/*** And final cleanup ***/
|
return UnZipBuffer (buffer, discoffset, 1, NULL); // unzip from dvd
|
||||||
if (rootdirlength % 2048)
|
}
|
||||||
|
return dvddirlength;
|
||||||
{
|
|
||||||
i = rootdirlength % 2048;
|
|
||||||
dvd_read (readbuffer, 2048, discoffset);
|
|
||||||
memcpy (buffer + offset, readbuffer, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
|
|
||||||
{
|
|
||||||
return UnZipBuffer (buffer, discoffset, 1, NULL); // unzip from dvd
|
|
||||||
}
|
|
||||||
return rootdirlength;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -401,17 +483,16 @@ LoadDVDFile (unsigned char *buffer)
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
void uselessinquiry ()
|
void uselessinquiry ()
|
||||||
{
|
{
|
||||||
|
dvd[0] = 0;
|
||||||
|
dvd[1] = 0;
|
||||||
|
dvd[2] = 0x12000000;
|
||||||
|
dvd[3] = 0;
|
||||||
|
dvd[4] = 0x20;
|
||||||
|
dvd[5] = 0x80000000;
|
||||||
|
dvd[6] = 0x20;
|
||||||
|
dvd[7] = 1;
|
||||||
|
|
||||||
dvd[0] = 0;
|
while (dvd[7] & 1);
|
||||||
dvd[1] = 0;
|
|
||||||
dvd[2] = 0x12000000;
|
|
||||||
dvd[3] = 0;
|
|
||||||
dvd[4] = 0x20;
|
|
||||||
dvd[5] = 0x80000000;
|
|
||||||
dvd[6] = 0x20;
|
|
||||||
dvd[7] = 1;
|
|
||||||
|
|
||||||
while (dvd[7] & 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void dvd_motor_off( )
|
void dvd_motor_off( )
|
||||||
|
@ -10,12 +10,11 @@
|
|||||||
#ifndef _NGCDVD_
|
#ifndef _NGCDVD_
|
||||||
#define _NGCDVD_
|
#define _NGCDVD_
|
||||||
|
|
||||||
extern u64 rootdir;
|
|
||||||
extern int rootdirlength;
|
|
||||||
|
|
||||||
int getpvd ();
|
int getpvd ();
|
||||||
int ParseDVDdirectory ();
|
int ParseDVDdirectory ();
|
||||||
int LoadDVDFile (unsigned char *buffer);
|
int LoadDVDFile (unsigned char *buffer);
|
||||||
|
bool TestDVD();
|
||||||
int dvd_read (void *dst, unsigned int len, u64 offset);
|
int dvd_read (void *dst, unsigned int len, u64 offset);
|
||||||
|
bool SwitchDVDFolder(char dir[]);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -123,6 +123,9 @@ ParseFATdirectory(int method)
|
|||||||
// initialize selection
|
// initialize selection
|
||||||
selection = offset = 0;
|
selection = offset = 0;
|
||||||
|
|
||||||
|
// Clear any existing values
|
||||||
|
memset (&filelist, 0, sizeof (FILEENTRIES) * MAXFILES);
|
||||||
|
|
||||||
// open the directory
|
// open the directory
|
||||||
fatdir = diropen(currentdir);
|
fatdir = diropen(currentdir);
|
||||||
if (fatdir == NULL)
|
if (fatdir == NULL)
|
||||||
|
@ -38,7 +38,11 @@ char currentdir[MAXPATHLEN];
|
|||||||
int maxfiles;
|
int maxfiles;
|
||||||
extern int screenheight;
|
extern int screenheight;
|
||||||
extern unsigned long ARAM_ROMSIZE;
|
extern unsigned long ARAM_ROMSIZE;
|
||||||
int havedir = 0;
|
|
||||||
|
int havedir = -1;
|
||||||
|
extern u64 dvddir;
|
||||||
|
extern int dvddirlength;
|
||||||
|
|
||||||
int hasloaded = 0;
|
int hasloaded = 0;
|
||||||
|
|
||||||
// Global file entry table
|
// Global file entry table
|
||||||
@ -68,7 +72,7 @@ int autoLoadMethod()
|
|||||||
return METHOD_SD;
|
return METHOD_SD;
|
||||||
else if(ChangeFATInterface(METHOD_USB, SILENT))
|
else if(ChangeFATInterface(METHOD_USB, SILENT))
|
||||||
return METHOD_USB;
|
return METHOD_USB;
|
||||||
else if(false) // FIX ME - WARNING - MOUNTING DVD in Wii mode hangs
|
else if(TestDVD())
|
||||||
return METHOD_DVD;
|
return METHOD_DVD;
|
||||||
else if(ConnectShare (SILENT))
|
else if(ConnectShare (SILENT))
|
||||||
return METHOD_SMB;
|
return METHOD_SMB;
|
||||||
@ -108,12 +112,20 @@ int autoSaveMethod()
|
|||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Update curent directory name
|
* Update curent directory name
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
int UpdateDirName()
|
int UpdateDirName(int method)
|
||||||
{
|
{
|
||||||
int size=0;
|
int size=0;
|
||||||
char *test;
|
char *test;
|
||||||
char temp[1024];
|
char temp[1024];
|
||||||
|
|
||||||
|
// update DVD directory (does not utilize 'currentdir')
|
||||||
|
if(method == METHOD_DVD)
|
||||||
|
{
|
||||||
|
dvddir = filelist[selection].offset;
|
||||||
|
dvddirlength = filelist[selection].length;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* current directory doesn't change */
|
/* current directory doesn't change */
|
||||||
if (strcmp(filelist[selection].filename,".") == 0)
|
if (strcmp(filelist[selection].filename,".") == 0)
|
||||||
{
|
{
|
||||||
@ -257,7 +269,7 @@ FileSelector (int method)
|
|||||||
if (filelist[selection].flags) // This is directory
|
if (filelist[selection].flags) // This is directory
|
||||||
{
|
{
|
||||||
/* update current directory and set new entry list if directory has changed */
|
/* update current directory and set new entry list if directory has changed */
|
||||||
int status = UpdateDirName();
|
int status = UpdateDirName(method);
|
||||||
if (status == 1) // ok, open directory
|
if (status == 1) // ok, open directory
|
||||||
{
|
{
|
||||||
switch (method)
|
switch (method)
|
||||||
@ -284,7 +296,7 @@ FileSelector (int method)
|
|||||||
}
|
}
|
||||||
else if (status == -1) // directory name too long
|
else if (status == -1) // directory name too long
|
||||||
{
|
{
|
||||||
haverom = 1; // quit menu
|
haverom = 1; // quit menu
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // this is a file
|
else // this is a file
|
||||||
@ -303,6 +315,8 @@ FileSelector (int method)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case METHOD_DVD:
|
case METHOD_DVD:
|
||||||
|
dvddir = filelist[selection].offset;
|
||||||
|
dvddirlength = filelist[selection].length;
|
||||||
ARAM_ROMSIZE = LoadDVDFile (Memory.ROM);
|
ARAM_ROMSIZE = LoadDVDFile (Memory.ROM);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -336,7 +350,6 @@ FileSelector (int method)
|
|||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
VIDEO_WaitVSync();
|
VIDEO_WaitVSync();
|
||||||
//if ((strcmp(filelist[1].filename,"..") == 0) && (strlen (filelist[0].filename) != 0))
|
|
||||||
if ( strcmp(filelist[0].filename,"..") == 0 )
|
if ( strcmp(filelist[0].filename,"..") == 0 )
|
||||||
{
|
{
|
||||||
selection = 0;
|
selection = 0;
|
||||||
@ -441,25 +454,27 @@ OpenDVD (int method)
|
|||||||
if (!getpvd())
|
if (!getpvd())
|
||||||
{
|
{
|
||||||
ShowAction((char*) "Loading DVD...");
|
ShowAction((char*) "Loading DVD...");
|
||||||
DVD_Mount(); /* mount the DVD unit again */
|
DVD_Mount(); // mount the DVD unit again
|
||||||
havedir = 0; /* this may be a new DVD: content need to be parsed again */
|
|
||||||
if (!getpvd())
|
if (!getpvd())
|
||||||
return 0; /* no correct ISO9660 DVD */
|
return 0; // not a ISO9660 DVD
|
||||||
}
|
}
|
||||||
|
|
||||||
if (havedir == 0)
|
maxfiles = ParseDVDdirectory(); // load root folder
|
||||||
|
|
||||||
|
// switch to rom folder
|
||||||
|
SwitchDVDFolder(GCSettings.LoadFolder);
|
||||||
|
|
||||||
|
if (maxfiles > 0)
|
||||||
{
|
{
|
||||||
maxfiles = ParseDVDdirectory();
|
return FileSelector (method);
|
||||||
if (maxfiles > 0)
|
|
||||||
{
|
|
||||||
return FileSelector (method);
|
|
||||||
havedir = 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return FileSelector (method);
|
{
|
||||||
|
// no entries found
|
||||||
return 0;
|
WaitPrompt ((char *)"No Files Found!");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
@ -77,6 +77,11 @@ CardFileExists (char *filename, int slot)
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
bool TestCard(int slot, bool silent)
|
bool TestCard(int slot, bool silent)
|
||||||
{
|
{
|
||||||
|
// Memory Cards do not work in Wii mode - disable
|
||||||
|
#ifdef HW_RVL
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*** Initialize Card System ***/
|
/*** Initialize Card System ***/
|
||||||
memset (SysArea, 0, CARD_WORKAREA);
|
memset (SysArea, 0, CARD_WORKAREA);
|
||||||
CARD_Init ("SNES", "00");
|
CARD_Init ("SNES", "00");
|
||||||
@ -112,58 +117,24 @@ bool TestCard(int slot, bool silent)
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* MountCard
|
* MountCard
|
||||||
*
|
*
|
||||||
* Mounts the memory card in the given slot. Error checking is done and
|
* Mounts the memory card in the given slot.
|
||||||
* workarounds implemented for when the mount fails.
|
|
||||||
* Returns the result of the last attempted CARD_Mount command.
|
* Returns the result of the last attempted CARD_Mount command.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
int MountCard(int cslot, bool silent)
|
int MountCard(int cslot, bool silent)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret = -1;
|
||||||
int tries;
|
int tries = 0;
|
||||||
|
|
||||||
EXI_ProbeReset();
|
*(unsigned long *) (0xcc006800) |= 1 << 13; // Disable Encryption
|
||||||
|
|
||||||
// Mount the card
|
// Mount the card
|
||||||
ret = CARD_Mount (cslot, SysArea, NULL);
|
while ( tries < 10 && ret != 0)
|
||||||
|
|
||||||
tries = 0;
|
|
||||||
while ( tries < 3 && ret == CARD_ERROR_IOERROR )
|
|
||||||
{
|
{
|
||||||
EXI_ProbeReset ();
|
EXI_ProbeReset ();
|
||||||
if (cslot == CARD_SLOTA)
|
|
||||||
WaitPrompt((char*) "Replug card in slot A!");
|
|
||||||
else
|
|
||||||
WaitPrompt((char*) "Replug card in slot B!");
|
|
||||||
|
|
||||||
ret = CARD_Mount (cslot, SysArea, NULL);
|
ret = CARD_Mount (cslot, SysArea, NULL);
|
||||||
|
VIDEO_WaitVSync ();
|
||||||
tries++;
|
tries++;
|
||||||
}
|
}
|
||||||
|
|
||||||
tries = 0;
|
|
||||||
while ( tries < 2 && ret == CARD_ERROR_NOCARD )
|
|
||||||
{
|
|
||||||
EXI_ProbeReset ();
|
|
||||||
|
|
||||||
if(!silent)
|
|
||||||
ShowAction ((char*) "Mounting card...");
|
|
||||||
CARD_Unmount (cslot);
|
|
||||||
usleep(500000); // wait half second
|
|
||||||
ret = CARD_Mount (cslot, SysArea, NULL);
|
|
||||||
tries++;
|
|
||||||
}
|
|
||||||
|
|
||||||
tries = 0;
|
|
||||||
while ( tries < 3 && ret == CARD_ERROR_UNLOCKED )
|
|
||||||
{
|
|
||||||
EXI_ProbeReset ();
|
|
||||||
|
|
||||||
if(!silent)
|
|
||||||
ShowAction ((char*) "Waiting for unlock...");
|
|
||||||
usleep(500000); // wait half second
|
|
||||||
ret = CARD_Probe(cslot);
|
|
||||||
tries++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,24 +140,36 @@ PreferencesMenu ()
|
|||||||
while (quit == 0)
|
while (quit == 0)
|
||||||
{
|
{
|
||||||
// some load/save methods are not implemented - here's where we skip them
|
// some load/save methods are not implemented - here's where we skip them
|
||||||
|
// they need to be skipped in the order they were enumerated in snes9xGX.h
|
||||||
|
|
||||||
#ifndef HW_RVL
|
|
||||||
// no USB ports on GameCube
|
// no USB ports on GameCube
|
||||||
if(GCSettings.LoadMethod == METHOD_USB)
|
#ifndef HW_RVL
|
||||||
GCSettings.LoadMethod++;
|
if(GCSettings.LoadMethod == METHOD_USB)
|
||||||
if(GCSettings.SaveMethod == METHOD_USB)
|
GCSettings.LoadMethod++;
|
||||||
GCSettings.SaveMethod++;
|
if(GCSettings.SaveMethod == METHOD_USB)
|
||||||
#else
|
GCSettings.SaveMethod++;
|
||||||
// Wii DVD access not implemented
|
|
||||||
if(GCSettings.LoadMethod == METHOD_DVD)
|
|
||||||
GCSettings.LoadMethod++;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(GCSettings.SaveMethod == METHOD_DVD) // saving to DVD is impossible
|
// disable DVD access in Wii mode
|
||||||
|
#ifdef HW_RVL
|
||||||
|
if(GCSettings.LoadMethod == METHOD_DVD)
|
||||||
|
GCSettings.LoadMethod++;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// saving to DVD is impossible
|
||||||
|
if(GCSettings.SaveMethod == METHOD_DVD)
|
||||||
GCSettings.SaveMethod++;
|
GCSettings.SaveMethod++;
|
||||||
|
|
||||||
#ifdef HW_RVL
|
// disable SMB in GC mode (stalls out)
|
||||||
|
#ifndef HW_RVL
|
||||||
|
if(GCSettings.LoadMethod == METHOD_SMB)
|
||||||
|
GCSettings.LoadMethod++;
|
||||||
|
if(GCSettings.SaveMethod == METHOD_SMB)
|
||||||
|
GCSettings.SaveMethod++;
|
||||||
|
#endif
|
||||||
|
|
||||||
// disable MC saving in Wii mode - does not work for some reason!
|
// disable MC saving in Wii mode - does not work for some reason!
|
||||||
|
#ifdef HW_RVL
|
||||||
if(GCSettings.SaveMethod == METHOD_MC_SLOTA)
|
if(GCSettings.SaveMethod == METHOD_MC_SLOTA)
|
||||||
GCSettings.SaveMethod++;
|
GCSettings.SaveMethod++;
|
||||||
if(GCSettings.SaveMethod == METHOD_MC_SLOTB)
|
if(GCSettings.SaveMethod == METHOD_MC_SLOTB)
|
||||||
|
@ -25,6 +25,8 @@
|
|||||||
#include "smbop.h"
|
#include "smbop.h"
|
||||||
#include "filesel.h"
|
#include "filesel.h"
|
||||||
|
|
||||||
|
#include "mxml.h"
|
||||||
|
|
||||||
extern unsigned char savebuffer[];
|
extern unsigned char savebuffer[];
|
||||||
extern int currconfig[4];
|
extern int currconfig[4];
|
||||||
|
|
||||||
@ -39,6 +41,82 @@ extern unsigned int ncpadmap[];
|
|||||||
|
|
||||||
char prefscomment[2][32] = { {PREFSVERSTRING}, {"Preferences"} };
|
char prefscomment[2][32] = { {PREFSVERSTRING}, {"Preferences"} };
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Prepare Preferences Data
|
||||||
|
*
|
||||||
|
* This sets up the save buffer for saving.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void CreateXmlFile(char* filename)
|
||||||
|
{
|
||||||
|
mxml_node_t *xml;
|
||||||
|
mxml_node_t *data;
|
||||||
|
mxml_node_t *group;
|
||||||
|
|
||||||
|
xml = mxmlNewXML("1.0");
|
||||||
|
|
||||||
|
data = mxmlNewElement(xml, "screen");
|
||||||
|
|
||||||
|
//Create Some config value
|
||||||
|
mxmlElementSetAttr(data, "height","480");
|
||||||
|
|
||||||
|
mxmlElementSetAttr(data, "width","640");
|
||||||
|
|
||||||
|
//Lets do some sub items for funs
|
||||||
|
group = mxmlNewElement(data, "properties");
|
||||||
|
mxmlElementSetAttr(group, "username", "beardface");
|
||||||
|
|
||||||
|
mxmlElementSetAttr(group, "favorite_food", "dead babies");
|
||||||
|
|
||||||
|
/* now lets save the xml file to a file! */
|
||||||
|
FILE *fp;
|
||||||
|
fp = fopen(filename, "w");
|
||||||
|
|
||||||
|
mxmlSaveFile(xml, fp, MXML_NO_CALLBACK);
|
||||||
|
|
||||||
|
/*Time to clean up!*/
|
||||||
|
fclose(fp);
|
||||||
|
mxmlDelete(group);
|
||||||
|
mxmlDelete(data);
|
||||||
|
mxmlDelete(xml);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Prepare Preferences Data
|
||||||
|
*
|
||||||
|
* This sets up the save buffer for saving.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void LoadXmlFile(char* filename)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
mxml_node_t *tree;
|
||||||
|
mxml_node_t *data;
|
||||||
|
mxml_node_t *group;
|
||||||
|
|
||||||
|
/*Load our xml file! */
|
||||||
|
fp = fopen(filename, "r");
|
||||||
|
tree = mxmlLoadFile(NULL, fp, MXML_NO_CALLBACK);
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
/*Load and printf our values! */
|
||||||
|
/* As a note, its a good idea to normally check if node* is NULL */
|
||||||
|
data = mxmlFindElement(tree, tree, "screen", NULL, NULL, MXML_DESCEND);
|
||||||
|
|
||||||
|
printf("Loaded following values from xml file:\n");
|
||||||
|
printf(" Height: %s\n",mxmlElementGetAttr(data,"height"));
|
||||||
|
printf(" Width: %s\n",mxmlElementGetAttr(data,"width"));
|
||||||
|
|
||||||
|
group = mxmlFindElement(tree, tree, "properties", NULL, NULL, MXML_DESCEND);
|
||||||
|
printf(" %s's favorite food is %s\n",mxmlElementGetAttr(group, "username"), mxmlElementGetAttr(group, "favorite_food"));
|
||||||
|
|
||||||
|
/* Yay Done! Now lets be considerate programmers, and put memory back how
|
||||||
|
we found it before we started playing with it...*/
|
||||||
|
mxmlDelete(group);
|
||||||
|
mxmlDelete(data);
|
||||||
|
mxmlDelete(tree);
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Prepare Preferences Data
|
* Prepare Preferences Data
|
||||||
*
|
*
|
||||||
|
@ -85,11 +85,13 @@ bool InitializeNetwork(bool silent)
|
|||||||
bool
|
bool
|
||||||
ConnectShare (bool silent)
|
ConnectShare (bool silent)
|
||||||
{
|
{
|
||||||
// Crashes system in GameCube mode - so disable for now
|
// Crashes or stalls system in GameCube mode - so disable
|
||||||
#ifdef HW_RVL // Wii mode
|
#ifndef HW_RVL
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
|
||||||
if(!networkInit)
|
if(!networkInit)
|
||||||
networkInit = InitializeNetwork(silent);
|
networkInit = InitializeNetwork(silent);
|
||||||
#endif
|
|
||||||
|
|
||||||
if(networkInit)
|
if(networkInit)
|
||||||
{
|
{
|
||||||
@ -152,6 +154,9 @@ ParseSMBdirectory ()
|
|||||||
// initialize selection
|
// initialize selection
|
||||||
selection = offset = 0;
|
selection = offset = 0;
|
||||||
|
|
||||||
|
// Clear any existing values
|
||||||
|
memset (&filelist, 0, sizeof (FILEENTRIES) * MAXFILES);
|
||||||
|
|
||||||
if(strlen(currentdir) <= 1) // root
|
if(strlen(currentdir) <= 1) // root
|
||||||
sprintf(searchpath, "*");
|
sprintf(searchpath, "*");
|
||||||
else
|
else
|
||||||
|
@ -885,8 +885,10 @@ main ()
|
|||||||
//fatInit(8192, false);
|
//fatInit(8192, false);
|
||||||
//fat_enable_readahead_all();
|
//fat_enable_readahead_all();
|
||||||
|
|
||||||
// Initialize DVD subsystem
|
// Initialize DVD subsystem (GameCube only)
|
||||||
|
#ifndef HW_RVL
|
||||||
DVD_Init ();
|
DVD_Init ();
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef FORCE_WII
|
#ifdef FORCE_WII
|
||||||
isWii = TRUE;
|
isWii = TRUE;
|
||||||
|
Loading…
Reference in New Issue
Block a user