diff --git a/Makefile.gc b/Makefile.gc index 82efa8d..1236b02 100644 --- a/Makefile.gc +++ b/Makefile.gc @@ -41,7 +41,7 @@ LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map #--------------------------------------------------------------------------------- # any extra libraries we wish to link with #--------------------------------------------------------------------------------- -LIBS := -lpng -lmxml -lfat -lz -logc -lfreetype +LIBS := -lpng -lmxml -lfat -liso9660 -lz -logc -lfreetype #--------------------------------------------------------------------------------- # list of directories containing libraries, this must be the top level containing diff --git a/Makefile.wii b/Makefile.wii index c7d3dfa..4b51ea9 100644 --- a/Makefile.wii +++ b/Makefile.wii @@ -41,7 +41,7 @@ LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map -Wl,--cref #--------------------------------------------------------------------------------- # any extra libraries we wish to link with #--------------------------------------------------------------------------------- -LIBS := -ldb -ldi -lpng -lmxml -lwiikeyboard \ +LIBS := -ldb -ldi -liso9660 -lpng -lmxml -lwiikeyboard \ -lfat -lwiiuse -lz -lbte -logc -lasnd -lvorbisidec -lfreetype -ltinysmb #--------------------------------------------------------------------------------- diff --git a/source/ngc/dvd.cpp b/source/ngc/dvd.cpp deleted file mode 100644 index c9e443a..0000000 --- a/source/ngc/dvd.cpp +++ /dev/null @@ -1,823 +0,0 @@ -/**************************************************************************** - * Visual Boy Advance GX - * - * Tantric September 2008 - * - * dvd.cpp - * - * DVD I/O functions - ***************************************************************************/ - -#include -#include -#include -#include -#include -#include - -#ifdef HW_RVL -#include -#endif - -#include "vba.h" -#include "menu.h" -#include "gcunzip.h" -#include "filebrowser.h" -#include "fileop.h" - -static int diroffset = 0; -static u64 dvddir = 0; // offset of currently selected file or folder -static int dvddirlength = 0; // length of currently selected file or folder -static u64 dvdrootdir = 0; // offset of DVD root -static int dvdrootlength = 0; // length of DVD root -static bool isWii = false; - -#ifdef HW_DOL -/** DVD I/O Address base **/ -volatile unsigned long *dvd = (volatile unsigned long *) 0xCC006000; -#endif - -/**************************************************************************** - * dvd_read - * - * 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)))) - -static int -dvd_read (void *dst, unsigned int len, u64 offset) -{ - if (len > 2048) - return 0; /*** We only allow 2k reads **/ - - // 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))) - { - u8 * buffer = (u8 *)memalign(32, 0x8000); - u32 off_size = 0; - - DCInvalidateRange ((void *) buffer, len); - - #ifdef HW_DOL - dvd[0] = 0x2E; - dvd[1] = 0; - dvd[2] = 0xA8000000; - dvd[3] = (u32)(offset >> 2); - dvd[4] = len; - dvd[5] = (u32) buffer; - dvd[6] = len; - dvd[7] = 3; - - // Enable reading with DMA - while (dvd[7] & 1); - - // Ensure it has completed - if (dvd[0] & 0x4) - return 0; - #else - 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+off_size, len); - free(buffer); - return 1; - } - - return 0; -} - -/**************************************************************************** - * dvd_buffered_read - * - * the GC's dvd drive only supports offsets and length which are a multiple - * of 32 bytes additionally the max length of a read is 2048 bytes - * this function removes these limitations - * additionally the 7zip SDK does often read data in 1 byte parts from the - * DVD even when it could read 32 bytes. the dvdsf_buffer has been added to - * avoid having to read the same sector over and over again - ***************************************************************************/ - -#define DVD_LENGTH_MULTIPLY 32 -#define DVD_OFFSET_MULTIPLY 32 -#define DVD_MAX_READ_LENGTH 2048 -#define DVD_SECTOR_SIZE 2048 - -static unsigned char dvdsf_buffer[DVD_SECTOR_SIZE]; -static u64 dvdsf_last_offset = 0; -static u64 dvdsf_last_length = 0; - -static int dvd_buffered_read(void *dst, u32 len, u64 offset) -{ - int ret = 1; - - // only read data if the data inside dvdsf_buffer cannot be used - if(offset != dvdsf_last_offset || len > dvdsf_last_length) - { - memset(&dvdsf_buffer, '\0', DVD_SECTOR_SIZE); - ret = dvd_read(&dvdsf_buffer, len, offset); - dvdsf_last_offset = offset; - dvdsf_last_length = len; - } - - memcpy(dst, &dvdsf_buffer, len); - return ret; -} - -/**************************************************************************** - * dvd_safe_read - * - * A 'safer' DVD read function - * This function relies on dvddir (file offset) being prepopulated! - * returns: 1 - ok ; 0 - error - ***************************************************************************/ -int dvd_safe_read(void *dst_v, u32 len, u64 fileoffset) -{ - u64 offset = dvddir + fileoffset; - - unsigned char buffer[DVD_SECTOR_SIZE]; // buffer for one dvd sector - - // if read size and length are a multiply of DVD_(OFFSET,LENGTH)_MULTIPLY and length < DVD_MAX_READ_LENGTH - // we don't need to fix anything - if(len % DVD_LENGTH_MULTIPLY == 0 && offset % DVD_OFFSET_MULTIPLY == 0 && len <= DVD_MAX_READ_LENGTH) - { - int ret = dvd_buffered_read(buffer, len, offset); - memcpy(dst_v, &buffer, len); - return ret; - } - else - { - // no errors yet -> ret = 1 - // the return value of dvd_read will be AND'd with ret - // because dvd_read does return 0 on error and 1 on success and - // because 1 & 0 = 0 ret will also contain 0 if at least one error - // occured and 1 otherwise ;) - int ret = 1; // return value of dvd_read - - // we might need to fix all 3 issues - unsigned char *dst = (unsigned char *)dst_v; // gcc will not allow to use var[num] on void* types - u64 bytesToRead; // the number of bytes we still need to read & copy to the output buffer - u64 currentOffset; // the current dvd offset - u64 bufferOffset; // the current buffer offset - u64 i, j, k; // temporary variables which might be used for different stuff - // unsigned char buffer[DVD_SECTOR_SIZE]; // buffer for one dvd sector - - currentOffset = offset; - bytesToRead = len; - bufferOffset = 0; - - // fix first issue (offset is not a multiply of 32) - if(offset % DVD_OFFSET_MULTIPLY) - { - // calculate offset of the prior 32 byte position - i = currentOffset - (currentOffset % DVD_OFFSET_MULTIPLY); - - // calculate the offset from which the data of the dvd buffer will be copied - j = currentOffset % DVD_OFFSET_MULTIPLY; - - // calculate the number of bytes needed to reach the next DVD_OFFSET_MULTIPLY byte mark - k = DVD_OFFSET_MULTIPLY - j; - - // maybe we'll only need to copy a few bytes and we therefore don't even reach the next sector - if(k > len) - { - k = len; - } - - // read 32 bytes from the last 32 byte position - ret &= dvd_buffered_read(buffer, DVD_OFFSET_MULTIPLY, i); - - // copy the bytes to the output buffer and update currentOffset, bufferOffset and bytesToRead - memcpy(&dst[bufferOffset], &buffer[j], k); - currentOffset += k; - bufferOffset += k; - bytesToRead -= k; - } - - // fix second issue (more than 2048 bytes are needed) - if(bytesToRead > DVD_MAX_READ_LENGTH) - { - // calculate the number of 2048 bytes sector needed to get all data - i = (bytesToRead - (bytesToRead % DVD_MAX_READ_LENGTH)) / DVD_MAX_READ_LENGTH; - - // read data in 2048 byte sector - for(j = 0; j < i; j++) - { - ret &= dvd_buffered_read(buffer, DVD_MAX_READ_LENGTH, currentOffset); // read sector - memcpy(&dst[bufferOffset], buffer, DVD_MAX_READ_LENGTH); // copy to output buffer - - // update currentOffset, bufferOffset and bytesToRead - currentOffset += DVD_MAX_READ_LENGTH; - bufferOffset += DVD_MAX_READ_LENGTH; - bytesToRead -= DVD_MAX_READ_LENGTH; - } - } - - // fix third issue (length is not a multiply of 32) - if(bytesToRead) - { - ret &= dvd_buffered_read(buffer, DVD_MAX_READ_LENGTH, currentOffset); // read 32 byte from the dvd - memcpy(&dst[bufferOffset], buffer, bytesToRead); // copy bytes to output buffer - } - return ret; - } -} - -/** Minimal ISO Directory Definition **/ -#define RECLEN 0 /* Record length */ -#define EXTENT 6 /* Extent */ -#define FILE_LENGTH 14 /* File length (BIG ENDIAN) */ -#define FILE_FLAGS 25 /* File flags */ -#define FILENAME_LENGTH 32 /* Filename length */ -#define FILENAME 33 /* ASCIIZ filename */ - -/** Minimal Primary Volume Descriptor **/ -#define PVDROOT 0x9c -static int IsJoliet = 0; - -/**************************************************************************** - * Primary Volume Descriptor - * - * The PVD should reside between sector 16 and 31. - * This is for single session DVD only. - ***************************************************************************/ -static int -getpvd () -{ - int sector = 16; - u32 rootdir32; - unsigned char dvdbuffer[2048]; - - dvddir = dvddirlength = 0; - IsJoliet = -1; - - /** Look for Joliet PVD first **/ - while (sector < 32) - { - if (dvd_read (&dvdbuffer, 2048, (u64)(sector << 11))) - { - if (memcmp (&dvdbuffer, "\2CD001\1", 8) == 0) - { - memcpy(&rootdir32, &dvdbuffer[PVDROOT + EXTENT], 4); - dvddir = (u64)rootdir32; - dvddir <<= 11; - memcpy (&dvddirlength, &dvdbuffer[PVDROOT + FILE_LENGTH], 4); - dvdrootdir = dvddir; - dvdrootlength = dvddirlength; - IsJoliet = 1; - break; - } - } - else - return 0; /*** Can't read sector! ***/ - sector++; - } - - if (IsJoliet > 0) /*** Joliet PVD Found ? ***/ - return 1; - - sector = 16; - - /*** Look for standard ISO9660 PVD ***/ - while (sector < 32) - { - if (dvd_read (&dvdbuffer, 2048, sector << 11)) - { - if (memcmp (&dvdbuffer, "\1CD001\1", 8) == 0) - { - memcpy (&rootdir32, &dvdbuffer[PVDROOT + EXTENT], 4); - dvddir = (u64)rootdir32; - dvddir <<= 11; - memcpy (&dvddirlength, &dvdbuffer[PVDROOT + FILE_LENGTH], 4); - dvdrootdir = dvddir; - dvdrootlength = dvddirlength; - IsJoliet = 0; - break; - } - } - else - return 0; /*** Can't read sector! ***/ - sector++; - } - return (IsJoliet == 0); -} - -/**************************************************************************** - * MountDVD() - * - * Tests if a ISO9660 DVD is inserted and available, and mounts it - ***************************************************************************/ -bool MountDVD(bool silent) -{ - bool res = false; - - if (getpvd()) - { - return true; - } - else - { - ShowAction("Loading DVD..."); - #ifdef HW_DOL - DVD_Mount(); // mount the DVD unit again - #else - u32 val; - DI_GetCoverRegister(&val); - if(val & 0x1) // True if no disc inside, use (val & 0x2) for true if disc inside. - { - if(!silent) - ErrorPrompt("No disc inserted!"); - CancelAction(); - return false; - } - DI_Mount(); - while(DI_GetStatus() & DVD_INIT) usleep(20000); - #endif - - if (getpvd()) - res = true; - else if(!silent) - ErrorPrompt("Invalid DVD."); - } - CancelAction(); - return res; -} - -/**************************************************************************** - * getentry - * - * Support function to return the next file entry, if any - * Declared static to avoid accidental external entry. - ***************************************************************************/ -static int -getentry (int entrycount, unsigned char dvdbuffer[]) -{ - char fname[512]; /* Huge, but experience has determined this */ - char *ptr; - char *filename; - char *filenamelength; - char *rr; - int j; - u32 offset32; - - if (diroffset >= 2048 || diroffset < 0) - return 0; - - /** Decode this entry **/ - 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 || (diroffset + dvdbuffer[diroffset]) < 0) - return 0; - - if (*filenamelength) - { - memset (&fname, 0, 512); - - if (!IsJoliet) /*** Do ISO 9660 first ***/ - { - strncpy (fname, filename, 512); - } - else - { /*** The more tortuous unicode joliet entries ***/ - for (j = 0; j < (*filenamelength >> 1); j++) - { - fname[j] = filename[j * 2 + 1]; - } - - fname[j] = 0; - - if (strlen (fname) >= MAXJOLIET) - fname[MAXJOLIET - 1] = 0; - - if (strlen (fname) == 0) - fname[0] = filename[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 **/ - rr = strstr (fname, ";"); - if (rr != NULL) - *rr = 0; - - BROWSERENTRY * newBrowserList = (BROWSERENTRY *)realloc(browserList, (entrycount+1) * sizeof(BROWSERENTRY)); - if(!newBrowserList) // failed to allocate required memory - { - ResetBrowser(); - ErrorPrompt("Out of memory: too many files!"); - return 0; - } - else - { - browserList = newBrowserList; - } - memset(&(browserList[entrycount]), 0, sizeof(BROWSERENTRY)); // clear the new entry - - strncpy (browserList[entrycount].filename, fname, MAXJOLIET); - - if(strcmp(fname,"..") == 0) - { - sprintf(browserList[entrycount].displayname, "Up One Level"); - } - else - { - StripExt(browserList[entrycount].displayname, browserList[entrycount].filename); // hide file extension - } - - memcpy (&offset32, &dvdbuffer[diroffset + EXTENT], 4); - - browserList[entrycount].offset = (u64)offset32; - memcpy (&(browserList[entrycount].length), &dvdbuffer[diroffset + FILE_LENGTH], 4); - memcpy (&(browserList[entrycount].isdir), &dvdbuffer[diroffset + FILE_FLAGS], 1); - - browserList[entrycount].offset <<= 11; - browserList[entrycount].isdir = browserList[entrycount].isdir & 2; - - if(browserList[entrycount].isdir) - browserList[entrycount].icon = ICON_FOLDER; - - /*** Prepare for next entry ***/ - - diroffset += dvdbuffer[diroffset]; - return 1; - } - } - return 0; -} - -/**************************************************************************** - * ParseDVDdirectory - * - * This function will parse the directory tree. - * It relies on dvddir and dvddirlength being pre-populated by a call to - * getpvd, a previous parse or a menu selection. - * - * The return value is number of files collected, or -1 on failure. - ***************************************************************************/ -int -ParseDVDdirectory () -{ - int pdlength; - u64 pdoffset; - u64 rdoffset; - int len = 0; - int filecount = 0; - unsigned char dvdbuffer[2048]; - - // reset browser - ResetBrowser(); - - pdoffset = rdoffset = dvddir; - pdlength = dvddirlength; - filecount = 0; - - /*** Get as many files as possible ***/ - while (len < pdlength) - { - if (dvd_read (&dvdbuffer, 2048, pdoffset) == 0) - return -1; - - diroffset = 0; - - while (getentry (filecount, dvdbuffer)) - { - if(strlen(browserList[filecount].filename) > 0) - filecount++; - } - - len += 2048; - pdoffset = rdoffset + len; - } - - // Sort the file list - qsort(browserList, filecount, sizeof(BROWSERENTRY), FileSortCallback); - - browser.numEntries = filecount; - return filecount; -} - -/**************************************************************************** - * SetDVDdirectory - * Set the current DVD file offset - ***************************************************************************/ -void SetDVDdirectory(u64 dir, int length) -{ - dvddir = dir; - dvddirlength = length; -} - -/**************************************************************************** - * DirectorySearch - * - * Searches for the directory name specified within the current directory - * Returns the index of the directory, or -1 if not found - ***************************************************************************/ -static int DirectorySearch(char dir[512]) -{ - for (int i = 0; i < browser.numEntries; i++ ) - if (strcmp(browserList[i].filename, dir) == 0) - return i; - return -1; -} - -/**************************************************************************** - * SwitchDVDFolderR - * - * Recursively searches for any directory path 'dir' specified - * Also can be used to find and set the offset for a file - * Also loads the directory contents via ParseDVDdirectory() - * It relies on dvddir, dvddirlength, and filelist being pre-populated - ***************************************************************************/ -static bool SwitchDVDFolderR(char * dir, int maxDepth) -{ - if(maxDepth > 8) // only search to a max depth of 8 levels - return false; - - bool lastdir = false; - char * nextdir = NULL; - 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 >= 0) - { - browser.selIndex = dirindex; - - if(browserList[dirindex].isdir) // only parse directories - { - UpdateDirName(); - ParseDVDdirectory(); - } - else - { - dvddir = browserList[dirindex].offset; - dvddirlength = browserList[dirindex].length; - } - - if(lastdir) - return true; - else - return SwitchDVDFolderR(nextdir, maxDepth++); - } - return false; -} - -bool SwitchDVDFolder(char origdir[]) -{ - // make a copy of origdir so we don't mess with original - char dir[1024]; - strncpy(dir, origdir, 1024); - - char * dirptr = dir; - - // strip off leading/trailing slashes on the directory path - // we don't want to screw up our recursion! - if(dir[0] == '/') - dirptr = dirptr + 1; - if(dir[strlen(dir)-1] == '/') - dir[strlen(dir)-1] = 0; - - // start searching at root of DVD - dvddir = dvdrootdir; - dvddirlength = dvdrootlength; - browser.dir[0] = 0; - ParseDVDdirectory(); - - return SwitchDVDFolderR(dirptr, 0); -} - -/**************************************************************************** - * LoadDVDFileOffset - * This function will load a file from DVD - * It assumes dvddir and dvddirlength are prepopulated - ***************************************************************************/ -int -LoadDVDFileOffset (unsigned char *buffer, int length) -{ - int result = 0; - int offset; - int blocks; - int i; - int ret = 0; - u64 discoffset; - char readbuffer[2048]; - - // How many 2k blocks to read - blocks = dvddirlength / 2048; - offset = 0; - discoffset = dvddir; - ShowAction ("Loading..."); - - if(length > 0 && length <= 2048) - { - ret = dvd_read (buffer, length, discoffset); - if(ret <= 0) // read failure - goto done; - else - result = length; - } - else // load whole file - { - ret = dvd_read (readbuffer, 2048, discoffset); - if(ret <= 0) // read failure - goto done; - - if (IsZipFile (readbuffer)) - { - result = UnZipBuffer (buffer, DEVICE_DVD); // unzip from dvd - } - else - { - for (i = 0; i < blocks; i++) - { - ret = dvd_read (readbuffer, 2048, discoffset); - if(ret <= 0) // read failure - goto done; - memcpy (buffer + offset, readbuffer, 2048); - offset += 2048; - discoffset += 2048; - ShowProgress ("Loading...", offset, length); - } - - /*** And final cleanup ***/ - if (dvddirlength % 2048) - { - i = dvddirlength % 2048; - ret = dvd_read (readbuffer, 2048, discoffset); - if(ret <= 0) // read failure - goto done; - memcpy (buffer + offset, readbuffer, i); - } - result = dvddirlength; - } - } -done: - CancelAction(); - return result; -} - -/**************************************************************************** - * LoadDVDFile - * This function will load a file from DVD, given a filepath - * It will attempt to find the offset of the file, and if successful it - * will populate dvddir and dvddirlength, and load the file - ***************************************************************************/ -int -LoadDVDFile(char * buffer, char *filepath, int datasize, bool silent) -{ - int ret = 0; - - // retain original browser information - char origDir[MAXPATHLEN]; - memset(origDir, 0, MAXPATHLEN); - strncpy(origDir, browser.dir, MAXPATHLEN); - int origSelIndex = browser.selIndex; - int origPageIndex = browser.selIndex; - - if(SwitchDVDFolder(filepath)) - ret = LoadDVDFileOffset ((unsigned char *)buffer, datasize); - else if(!silent) - ErrorPrompt("Error loading file!"); - - // restore browser information - memset(browser.dir, 0, MAXPATHLEN); - strncpy(browser.dir, origDir, MAXPATHLEN); - browser.selIndex = origSelIndex; - browser.pageIndex = origPageIndex; - - return ret; -} - -/**************************************************************************** - * uselessinquiry - * - * As the name suggests, this function is quite useless. - * It's only purpose is to stop any pending DVD interrupts while we use the - * memcard interface. - * - * libOGC tends to foul up if you don't, and sometimes does if you do! - ***************************************************************************/ -#ifdef HW_DOL -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; - - while (dvd[7] & 1); -} - -/**************************************************************************** - * dvd_motor_off( ) - * Turns off DVD drive motor so it doesn't make noise (Gamecube only) - ***************************************************************************/ -void dvd_motor_off () -{ - dvd[0] = 0x2e; - dvd[1] = 0; - dvd[2] = 0xe3000000; - dvd[3] = 0; - dvd[4] = 0; - dvd[5] = 0; - dvd[6] = 0; - dvd[7] = 1; // Do immediate - while (dvd[7] & 1); - - /*** PSO Stops blackscreen at reload ***/ - dvd[0] = 0x14; - dvd[1] = 0; -} - -/**************************************************************************** - * dvd_driveid - * - * Gets and returns the dvd driveid - ***************************************************************************/ - -int dvd_driveid() -{ - static unsigned char *inquiry=(unsigned char *)0x80000004; - - dvd[0] = 0x2e; - dvd[1] = 0; - dvd[2] = 0x12000000; - dvd[3] = 0; - dvd[4] = 0x20; - dvd[5] = 0x80000000; - dvd[6] = 0x20; - dvd[7] = 3; - - while( dvd[7] & 1 ); - - DCFlushRange((void *)0x80000000, 32); - - return (int)inquiry[2]; -} - -#endif - -/**************************************************************************** - * SetDVDDriveType() - * - * Sets the DVD drive ID for use to determine disc size (1.5 GB or 4.7 GB) - ***************************************************************************/ -void SetDVDDriveType() -{ - #ifdef HW_RVL - isWii = true; - #else - int drvid = dvd_driveid (); - if ( drvid == 4 || drvid == 6 || drvid == 8 ) - isWii = false; - else - isWii = true; - #endif -} diff --git a/source/ngc/dvd.h b/source/ngc/dvd.h deleted file mode 100644 index 75f2c25..0000000 --- a/source/ngc/dvd.h +++ /dev/null @@ -1,28 +0,0 @@ -/**************************************************************************** - * Visual Boy Advance GX - * - * Tantric September 2008 - * - * dvd.h - * - * DVD I/O functions - ***************************************************************************/ - -#ifndef _NGCDVD_ -#define _NGCDVD_ - -bool MountDVD(bool silent); -int ParseDVDdirectory(); -void SetDVDdirectory(u64 dir, int length); -bool SwitchDVDFolder(char dir[]); - -int LoadDVDFileOffset(unsigned char *buffer, int length); -int LoadDVDFile(char * buffer, char *filepath, int datasize, bool silent); -int dvd_safe_read (void *dst, unsigned int len, u64 offset); - -void SetDVDDriveType(); -#ifdef HW_DOL -void dvd_motor_off (); -#endif - -#endif diff --git a/source/ngc/filebrowser.cpp b/source/ngc/filebrowser.cpp index c519d5e..c47fb11 100644 --- a/source/ngc/filebrowser.cpp +++ b/source/ngc/filebrowser.cpp @@ -21,7 +21,6 @@ #endif #include "vba.h" -#include "dvd.h" #include "vbasupport.h" #include "vmmem.h" #include "filebrowser.h" @@ -197,10 +196,6 @@ int UpdateDirName() FindDevice(browser.dir, &device); - // update DVD directory - if(device == DEVICE_DVD) - SetDVDdirectory(browserList[browser.selIndex].offset, browserList[browser.selIndex].length); - /* current directory doesn't change */ if (strcmp(browserList[browser.selIndex].filename,".") == 0) { @@ -552,9 +547,6 @@ int BrowserChangeFolder() if(inSz && browser.selIndex == 0) // inside a 7z, requesting to leave { - if(device == DEVICE_DVD) - SetDVDdirectory(browserList[0].offset, browserList[0].length); - inSz = false; SzClose(); } @@ -567,18 +559,7 @@ int BrowserChangeFolder() ResetBrowser(); // reset browser if(browser.dir[0] != 0) - { - switch (device) - { - case DEVICE_DVD: - ParseDVDdirectory(); - break; - - default: - ParseDirectory(); - break; - } - } + ParseDirectory(); if(browser.numEntries == 0) { diff --git a/source/ngc/fileop.cpp b/source/ngc/fileop.cpp index 2b5aa6e..a1e3698 100644 --- a/source/ngc/fileop.cpp +++ b/source/ngc/fileop.cpp @@ -20,18 +20,18 @@ #include #include #include +#include +#include +#include #include "vba.h" #include "vbasupport.h" #include "fileop.h" #include "networkop.h" -#include "dvd.h" #include "memcardop.h" #include "gcunzip.h" -#include "video.h" #include "menu.h" #include "filebrowser.h" -#include "preferences.h" #define THREAD_SLEEP 100 @@ -44,9 +44,11 @@ bool isMounted[9] = { false, false, false, false, false, false, false, false, fa #ifdef HW_RVL const DISC_INTERFACE* sd = &__io_wiisd; const DISC_INTERFACE* usb = &__io_usbstorage; + const DISC_INTERFACE* dvd = &__io_wiidvd; #else const DISC_INTERFACE* carda = &__io_gcsda; const DISC_INTERFACE* cardb = &__io_gcsdb; + const DISC_INTERFACE* dvd = &__io_gcdvd; #endif // folder parsing thread @@ -165,6 +167,16 @@ devicecallback (void *arg) } } #endif + if(isMounted[DEVICE_DVD]) + { + if(!dvd->isInserted()) // check if the device was removed + { + printf("dvd removed!\n"); + unmountRequired[DEVICE_DVD] = true; + isMounted[DEVICE_DVD] = false; + } + } + devsleep = 1000*1000; // 1 sec while(devsleep > 0) @@ -300,6 +312,45 @@ void MountAllFAT() #endif } +/**************************************************************************** + * MountDVD() + * + * Tests if a ISO9660 DVD is inserted and available, and mounts it + ***************************************************************************/ +bool MountDVD(bool silent) +{ + if(isMounted[DEVICE_DVD]) + return true; + + ShowAction("Loading DVD..."); + + bool mounted = false; + + if(unmountRequired[DEVICE_DVD]) + { + unmountRequired[DEVICE_DVD] = false; + ISO9660_Unmount(); + } + + mounted = dvd->isInserted(); + + if(!mounted) + { + if(!silent) + ErrorPrompt("No disc inserted!"); + } + else + { + mounted = ISO9660_Mount(); + + if(!mounted && !silent) + ErrorPrompt("Invalid DVD."); + } + CancelAction(); + isMounted[DEVICE_DVD] = mounted; + return mounted; +} + bool FindDevice(char * filepath, int * device) { if(!filepath || filepath[0] == 0) @@ -505,6 +556,7 @@ ParseDirectory(bool waitParse) while(dirIter == NULL && retry == 1) { mounted = ChangeInterface(browser.dir, NOTSILENT); + if(mounted) dirIter = diropen(browser.dir); else @@ -523,10 +575,10 @@ ParseDirectory(bool waitParse) while(!IsDeviceRoot(browser.dir)) { char * devEnd = strrchr(browser.dir, '/'); - + if(devEnd == NULL) break; - + devEnd[0] = 0; // strip remaining file listing dirIter = diropen(browser.dir); if (dirIter) @@ -639,18 +691,10 @@ LoadFile (char * rbuffer, char *filepath, u32 length, bool silent) if(!FindDevice(filepath, &device)) return 0; - switch(device) - { - case DEVICE_DVD: - return LoadDVDFile (rbuffer, StripDevice(filepath), length, silent); - break; - case DEVICE_MC_SLOTA: - return LoadMCFile (rbuffer, CARD_SLOTA, StripDevice(filepath), silent); - break; - case DEVICE_MC_SLOTB: - return LoadMCFile (rbuffer, CARD_SLOTB, StripDevice(filepath), silent); - break; - } + if(device == DEVICE_MC_SLOTA) + return LoadMCFile (rbuffer, CARD_SLOTA, StripDevice(filepath), silent); + else if(device == DEVICE_MC_SLOTB) + return LoadMCFile (rbuffer, CARD_SLOTB, StripDevice(filepath), silent); // stop checking if devices were removed/inserted // since we're loading a file @@ -680,7 +724,7 @@ LoadFile (char * rbuffer, char *filepath, u32 length, bool silent) { if (IsZipFile (zipbuffer)) { - size = UnZipBuffer ((unsigned char *)rbuffer, device); // unzip + size = UnZipBuffer ((unsigned char *)rbuffer); // unzip } else { @@ -761,13 +805,10 @@ SaveFile (char * buffer, char *filepath, u32 datasize, bool silent) ShowAction("Saving..."); - if(device == DEVICE_MC_SLOTA || device == DEVICE_MC_SLOTB) - { - if(device == DEVICE_MC_SLOTA) - return SaveMCFile (buffer, CARD_SLOTA, StripDevice(filepath), datasize, silent); - else - return SaveMCFile (buffer, CARD_SLOTB, StripDevice(filepath), datasize, silent); - } + if(device == DEVICE_MC_SLOTA) + return SaveMCFile (buffer, CARD_SLOTA, StripDevice(filepath), datasize, silent); + else if(device == DEVICE_MC_SLOTB) + return SaveMCFile (buffer, CARD_SLOTB, StripDevice(filepath), datasize, silent); // stop checking if devices were removed/inserted // since we're saving a file diff --git a/source/ngc/gcunzip.cpp b/source/ngc/gcunzip.cpp index 3a8b3e2..4759cc1 100644 --- a/source/ngc/gcunzip.cpp +++ b/source/ngc/gcunzip.cpp @@ -21,7 +21,6 @@ extern "C" { } #include "vba.h" -#include "dvd.h" #include "networkop.h" #include "fileop.h" #include "filebrowser.h" @@ -101,7 +100,7 @@ IsZipFile (char *buffer) ******************************************************************************/ int -UnZipBuffer (unsigned char *outbuffer, int device) +UnZipBuffer (unsigned char *outbuffer) { PKZIPHEADER pkzip; int zipoffset = 0; @@ -110,22 +109,13 @@ UnZipBuffer (unsigned char *outbuffer, int device) z_stream zs; int res; int bufferoffset = 0; - int readoffset = 0; int have = 0; char readbuffer[ZIPCHUNK]; int sizeread = 0; // Read Zip Header - switch (device) - { - case DEVICE_DVD: - sizeread = dvd_safe_read (readbuffer, ZIPCHUNK, 0); - break; - default: - fseek(file, 0, SEEK_SET); - sizeread = fread (readbuffer, 1, ZIPCHUNK, file); - break; - } + fseek(file, 0, SEEK_SET); + sizeread = fread (readbuffer, 1, ZIPCHUNK, file); if(sizeread <= 0) return 0; @@ -188,16 +178,7 @@ UnZipBuffer (unsigned char *outbuffer, int device) zipoffset = 0; zipchunk = ZIPCHUNK; - switch (device) - { - case DEVICE_DVD: - readoffset += ZIPCHUNK; - sizeread = dvd_safe_read (readbuffer, ZIPCHUNK, readoffset); - break; - default: - sizeread = fread (readbuffer, 1, ZIPCHUNK, file); - break; - } + sizeread = fread (readbuffer, 1, ZIPCHUNK, file); if(sizeread <= 0) goto done; // read failure @@ -336,16 +317,8 @@ static SZ_RESULT SzFileReadImp(void *object, void **buffer, size_t maxRequiredSi maxRequiredSize = 2048; // read data - switch (szMethod) - { - case DEVICE_DVD: - sizeread = dvd_safe_read(sz_buffer, maxRequiredSize, offset); - break; - default: - seekok = fseek(file, offset, SEEK_SET); - sizeread = fread(sz_buffer, 1, maxRequiredSize, file); - break; - } + seekok = fseek(file, offset, SEEK_SET); + sizeread = fread(sz_buffer, 1, maxRequiredSize, file); if(seekok != 0 || sizeread <= 0) return SZE_FAILREAD; @@ -405,19 +378,9 @@ int SzParse(char * filepath) SzArchiveStream.pos = 0; // open file - switch (device) - { - case DEVICE_SD: - case DEVICE_USB: - case DEVICE_SMB: - file = fopen (filepath, "rb"); - if(!file) - return 0; - break; - case DEVICE_DVD: - SwitchDVDFolder(filepath); - break; - } + file = fopen (filepath, "rb"); + if(!file) + return 0; // set szMethod to current chosen load device szMethod = device; @@ -507,14 +470,7 @@ int SzParse(char * filepath) CancelAction(); // close file - switch (device) - { - case DEVICE_SD: - case DEVICE_USB: - case DEVICE_SMB: - fclose(file); - break; - } + fclose(file); return nbfiles; } diff --git a/source/ngc/gcunzip.h b/source/ngc/gcunzip.h index c1f2ca1..b63681b 100644 --- a/source/ngc/gcunzip.h +++ b/source/ngc/gcunzip.h @@ -12,7 +12,7 @@ int IsZipFile (char *buffer); char * GetFirstZipFilename(); -int UnZipBuffer (unsigned char *outbuffer, int device); +int UnZipBuffer (unsigned char *outbuffer); int SzParse(char * filepath); int SzExtractFile(int i, unsigned char *buffer); void SzClose(); diff --git a/source/ngc/memcardop.cpp b/source/ngc/memcardop.cpp index 303d69c..9291347 100644 --- a/source/ngc/memcardop.cpp +++ b/source/ngc/memcardop.cpp @@ -21,7 +21,6 @@ #include "preferences.h" #include "filebrowser.h" #include "fileop.h" -#include "dvd.h" #include "images/saveicon.h" static u8 * SysArea = NULL; diff --git a/source/ngc/menu.cpp b/source/ngc/menu.cpp index 0c05982..00733f9 100644 --- a/source/ngc/menu.cpp +++ b/source/ngc/menu.cpp @@ -28,7 +28,6 @@ #include "networkop.h" #include "memcardop.h" #include "fileop.h" -#include "dvd.h" #include "vbaconfig.h" #include "preferences.h" #include "button_mapping.h" @@ -3123,12 +3122,6 @@ static int MenuSettingsFile() if(GCSettings.SaveMethod == DEVICE_DVD) GCSettings.SaveMethod++; - // disable DVD in GC mode (not implemented) - #ifdef HW_DOL - if(GCSettings.LoadMethod == DEVICE_DVD) - GCSettings.LoadMethod++; - #endif - // disable SMB in GC mode (stalls out) #ifdef HW_DOL if(GCSettings.LoadMethod == DEVICE_SMB) diff --git a/source/ngc/vba.cpp b/source/ngc/vba.cpp index 31ab51c..3334e2e 100644 --- a/source/ngc/vba.cpp +++ b/source/ngc/vba.cpp @@ -29,7 +29,6 @@ #include "vbasupport.h" #include "preferences.h" #include "audio.h" -#include "dvd.h" #include "networkop.h" #include "filebrowser.h" #include "fileop.h" @@ -277,7 +276,6 @@ int main(int argc, char *argv[]) DVD_Init (); #endif - SetDVDDriveType(); // Check if DVD drive belongs to a Wii InitialiseSound(); InitialisePalette(); DefaultSettings (); // Set defaults diff --git a/source/ngc/vmmem.cpp b/source/ngc/vmmem.cpp index b999845..9c4a98f 100644 --- a/source/ngc/vmmem.cpp +++ b/source/ngc/vmmem.cpp @@ -160,7 +160,7 @@ bool VMCPULoadROM() VMClose(); VMAllocGBA(); GBAROMSize = 0; - int device = GCSettings.LoadMethod; + rom = (u8 *)MEM2Storage; if(!inSz) @@ -174,17 +174,7 @@ bool VMCPULoadROM() } else { - switch (device) - { - case DEVICE_SD: - case DEVICE_USB: - case DEVICE_SMB: - GBAROMSize = LoadSzFile(szpath, (unsigned char *)rom); - break; - case DEVICE_DVD: - GBAROMSize = SzExtractFile(browserList[browser.selIndex].offset, (unsigned char *)rom); - break; - } + GBAROMSize = LoadSzFile(szpath, (unsigned char *)rom); } if(GBAROMSize)