diff --git a/source/ngc/dvd.cpp b/source/ngc/dvd.cpp index 82c514a..14b6e16 100644 --- a/source/ngc/dvd.cpp +++ b/source/ngc/dvd.cpp @@ -25,9 +25,9 @@ extern "C" { #include "filesel.h" #include "vba.h" -u64 dvddir = 0; -u64 dvdrootdir = 0; -int dvddirlength = 0; +u64 dvddir = 0; // offset of currently selected file or folder +int dvddirlength = 0; // length of currently selected file or folder +u64 dvdrootdir = 0; // offset of DVD root bool isWii = false; #ifdef HW_DOL @@ -35,17 +35,15 @@ bool isWii = false; volatile unsigned long *dvd = (volatile unsigned long *) 0xCC006000; #endif - /** Due to lack of memory, we'll use this little 2k keyhole for all DVD operations **/ -unsigned char DVDreadbuffer[2048] ATTRIBUTE_ALIGN (32); -unsigned char dvdbuffer[2048]; - - /**************************************************************************** * dvd_read * - * The only DVD function we need - you gotta luv gc-linux self-boots! + * Main DVD function, everything else uses this! * returns: 1 - ok ; 0 - error ***************************************************************************/ +#define ALIGN_FORWARD(x,align) ((typeof(x))((((uint32_t)(x)) + (align) - 1) & (~(align-1)))) +#define ALIGN_BACKWARD(x,align) ((typeof(x))(((uint32_t)(x)) & (~(align-1)))) + int dvd_read (void *dst, unsigned int len, u64 offset) { @@ -55,7 +53,9 @@ dvd_read (void *dst, unsigned int len, u64 offset) // don't read past the end of the DVD (1.5 GB for GC DVD, 4.7 GB for DVD) if((offset < 0x57057C00) || (isWii && (offset < 0x118244F00LL))) { - unsigned char *buffer = (unsigned char *) (unsigned int) DVDreadbuffer; + u8 * buffer = (u8 *)memalign(32, 0x8000); + u32 off_size = 0; + DCInvalidateRange ((void *) buffer, len); #ifdef HW_DOL @@ -75,11 +75,17 @@ dvd_read (void *dst, unsigned int len, u64 offset) if (dvd[0] & 0x4) return 0; #else - if (DI_ReadDVD(buffer, len >> 11, (u32)(offset >> 11))) + off_size = offset - ALIGN_BACKWARD(offset,0x800); + if (DI_ReadDVD( + buffer, + (ALIGN_FORWARD(offset + len,0x800) - ALIGN_BACKWARD(offset,0x800)) >> 11, + (u32)(ALIGN_BACKWARD(offset, 0x800) >> 11) + )) return 0; #endif - memcpy (dst, buffer, len); + memcpy (dst, buffer+off_size, len); + free(buffer); return 1; } @@ -238,6 +244,7 @@ getpvd () { int sector = 16; u32 rootdir32; + unsigned char dvdbuffer[2048]; dvddir = dvddirlength = 0; IsJoliet = -1; @@ -322,7 +329,7 @@ bool TestDVD() ***************************************************************************/ static int diroffset = 0; static int -getentry (int entrycount) +getentry (int entrycount, unsigned char dvdbuffer[]) { char fname[512]; /* Huge, but experience has determined this */ char *ptr; @@ -442,6 +449,7 @@ ParseDVDdirectory () u64 rdoffset; int len = 0; int filecount = 0; + unsigned char dvdbuffer[2048]; // initialize selection selection = offset = 0; @@ -461,7 +469,7 @@ ParseDVDdirectory () diroffset = 0; - while (getentry (filecount)) + while (getentry (filecount, dvdbuffer)) { if(strlen(filelist[filecount].filename) > 0 && filecount < MAXFILES) filecount++; diff --git a/source/ngc/filesel.cpp b/source/ngc/filesel.cpp index 6f36913..0313204 100644 --- a/source/ngc/filesel.cpp +++ b/source/ngc/filesel.cpp @@ -340,6 +340,7 @@ int FileSelector (int method) { if(method == METHOD_DVD) { + // go to directory the 7z was in dvddir = filelist[0].offset; dvddirlength = filelist[0].length; } diff --git a/source/ngc/gcunzip.cpp b/source/ngc/gcunzip.cpp index 116f020..69ca37d 100644 --- a/source/ngc/gcunzip.cpp +++ b/source/ngc/gcunzip.cpp @@ -442,18 +442,14 @@ int SzParse(char * filepath, int method) { // Parses the 7z into a full file listing - // store the current 7z data - unsigned int oldLength = filelist[selection].length; - u64 oldOffset = filelist[selection].offset; - // erase all previous entries memset(&filelist, 0, sizeof(FILEENTRIES) * MAXFILES); - // add '..' folder + // add '..' folder in case the user wants exit the 7z strncpy(filelist[0].displayname, "..", 2); filelist[0].flags = 1; - filelist[0].length = oldLength; - filelist[0].offset = oldOffset; // in case the user wants exit 7z + filelist[0].offset = dvddir; + filelist[0].length = dvddirlength; // get contents and parse them into file list structure unsigned int SzI, SzJ;