From 8d50cb8cef4beddf5dd4ede0ea7db18cebb9883f Mon Sep 17 00:00:00 2001 From: dborth Date: Sat, 6 Sep 2008 18:24:52 +0000 Subject: [PATCH] bug fixes, finalize 2.0.1 --- readme.txt | 2 +- source/ngc/fceugc.c | 7 +- source/ngc/fceuload.c | 4 +- source/ngc/filesel.h | 2 +- source/ngc/gcunzip.c | 367 ++++++++++++++++++++++++++++++++++++++++++ source/ngc/menu.c | 4 +- 6 files changed, 375 insertions(+), 11 deletions(-) diff --git a/readme.txt b/readme.txt index 5619f13..4ce8e11 100644 --- a/readme.txt +++ b/readme.txt @@ -1,7 +1,7 @@ ¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤ - FCE Ultra GX - - Version 2.0.0 + Version 2.0.1 (Under GPL License) ¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤ diff --git a/source/ngc/fceugc.c b/source/ngc/fceugc.c index 79bdb31..22b3fd0 100644 --- a/source/ngc/fceugc.c +++ b/source/ngc/fceugc.c @@ -81,13 +81,10 @@ int main(int argc, char *argv[]) } FCEUI_SetVidSystem(0); // 0 - NTSC, 1 - PAL - FCEUI_SetGameGenie(0); // 0 - OFF, 1 - ON - FCEUI_SetSoundVolume(100); // 0-100 - FCEUI_SetSoundQuality(1); // 0 - low, 1 - high - cleanSFMDATA(); - GCMemROM(); + cleanSFMDATA(); // clear state data + GCMemROM(); // load color test ROM romLoaded = false; // we start off with only the color test rom // Set Defaults diff --git a/source/ngc/fceuload.c b/source/ngc/fceuload.c index 6ecaaab..6cb603f 100644 --- a/source/ngc/fceuload.c +++ b/source/ngc/fceuload.c @@ -60,8 +60,8 @@ int GCMemROM() /*** Set internal sound information ***/ FCEUI_Sound(SAMPLERATE); - FCEUI_SetSoundQuality(1); - FCEUI_SetSoundVolume(100); + FCEUI_SetSoundVolume(100); // 0-100 + FCEUI_SetSoundQuality(1); // 0 - low, 1 - high FCEUI_SetLowPass(0); InitialisePads(); diff --git a/source/ngc/filesel.h b/source/ngc/filesel.h index 7e7dda8..c5925da 100644 --- a/source/ngc/filesel.h +++ b/source/ngc/filesel.h @@ -12,7 +12,7 @@ #ifndef _NGCFILESEL_ #define _NGCFILESEL_ -#define SAVEBUFFERSIZE ((512 * 1024) + 2048 + 64 + 4 + 4) +#define SAVEBUFFERSIZE (64 * 1024) #define MAXJOLIET 255 #define MAXDISPLAY 54 diff --git a/source/ngc/gcunzip.c b/source/ngc/gcunzip.c index afec97a..1b629ce 100644 --- a/source/ngc/gcunzip.c +++ b/source/ngc/gcunzip.c @@ -225,3 +225,370 @@ UnZipSMBFile (unsigned char *outbuffer, SMBFILE infile) smbfile = infile; return UnZipBuffer(outbuffer, 2); } + +/* + * 7-zip functions are below. Have to be written to work with above. + + + +#include "7zCrc.h" +#include "7zIn.h" +#include "7zExtract.h" + +typedef struct _SzFileInStream +{ + ISzInStream InStream; + u64 offset; // offset of the file + unsigned int len; // length of the file + u64 pos; // current position of the file pointer +} SzFileInStream; + + + + + // 7zip error list +char szerrormsg[][30] = { + "7z: Data error", + "7z: Out of memory", + "7z: CRC Error", + "7z: Not implemented", + "7z: Fail", + "7z: Archive error" +}; + +SZ_RESULT SzRes; + +SzFileInStream SzArchiveStream; +CArchiveDatabaseEx SzDb; +ISzAlloc SzAllocImp; +ISzAlloc SzAllocTempImp; +UInt32 SzBlockIndex = 0xFFFFFFFF; +size_t SzBufferSize; +size_t SzOffset; +size_t SzOutSizeProcessed; +CFileItem *SzF; +char sz_buffer[2048]; + +// needed because there are no header files -.- +//#include +#define MAXFILES 1000 +#define MAXJOLIET 256 + +extern FILEENTRIES filelist[MAXFILES]; + +extern int selection; +extern int maxfiles; +extern int offset; + +// the GC's dvd drive only supports offsets and length which are a multiply 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 +unsigned char dvdsf_buffer[DVD_SECTOR_SIZE]; +u64 dvdsf_last_offset = 0; +u64 dvdsf_last_length = 0; + +int dvd_buffered_read(void *dst, u32 len, u64 offset) { + int ret = 0; + + // only read data if the data inside dvdsf_buffer cannot be used + if(offset != dvdsf_last_offset || len > dvdsf_last_length) { + char msg[1024]; + sprintf(msg, "buff_read: len=%d, offset=%llX, UseSD=%d", len, offset, UseSDCARD); + //WaitPrompt(msg); + memset(&dvdsf_buffer, '\0', DVD_SECTOR_SIZE); + if (UseSDCARD) { + if (filehandle == NULL) + GetSDInfo(); + + fseek(filehandle, offset, SEEK_SET); + fread(&dvdsf_buffer, len, 1, filehandle); + } else if (!UseWiiSDCARD) + ret = dvd_read(&dvdsf_buffer, len, offset); + dvdsf_last_offset = offset; + dvdsf_last_length = len; + } + + memcpy(dst, &dvdsf_buffer, len); + return ret; +} + +int dvd_safe_read(void *dst_v, u32 len, u64 offset) { + 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) { + char msg[1024]; + sprintf(msg, "simple_safe_read: len=%d, offset=%llX, UseSD=%d", len, offset, UseSDCARD); + //WaitPrompt(msg); + int ret = dvd_buffered_read(buffer, len, offset); + memcpy(dst_v, &buffer, len); + return ret; + } else { + char msg[1024]; + sprintf(msg, "complex_safe_read: len=%d, offset=%llX, UseSD=%d", len, offset, UseSDCARD); + //WaitPrompt(msg); + // no errors yet -> ret = 0 + // the return value of dvd_read will be OR'd with ret + // because dvd_read does return 1 on error and 0 on success and + // because 0 | 1 = 1 ret will also contain 1 if at least one error + // occured and 0 otherwise ;) + int ret = 0; // 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) { + // calcualte 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 + } + + //free(tmp); + return ret; + } +} + +// function used by the 7zip SDK to read data from the DVD (fread) +SZ_RESULT SzDvdFileReadImp(void *object, void **buffer, size_t maxRequiredSize, size_t *processedSize) +{ + // the void* object is a SzFileInStream + SzFileInStream *s = (SzFileInStream *)object; + + // calculate dvd sector offset + u64 offset = (u64)(s->offset + s->pos); + + if(maxRequiredSize > 2048) + { + maxRequiredSize = 2048; + } + + // read data + dvd_safe_read(sz_buffer, maxRequiredSize, offset); + *buffer = sz_buffer; + *processedSize = maxRequiredSize; + s->pos += *processedSize; + + return SZ_OK; +} + +// function used by the 7zip SDK to change the filepointer (fseek(object, pos, SEEK_SET)) +SZ_RESULT SzDvdFileSeekImp(void *object, CFileSize pos) +{ + // the void* object is a SzFileInStream + SzFileInStream *s = (SzFileInStream *)object; + + // check if the 7z SDK wants to move the pointer to somewhere after the EOF + if(pos >= s->len) + { + WaitPrompt("7z Error: The 7z SDK wants to start reading somewhere behind the EOF..."); + return SZE_FAIL; + } + + // save new position and return + s->pos = pos; + return SZ_OK; +} + +SZ_RESULT SzDvdIsArchive(u64 dvd_offset) { + // 7z signautre + static Byte Signature[6] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C}; + Byte Candidate[6]; + + // read the data from the DVD + int res = dvd_safe_read (&Candidate, 6, dvd_offset); + char msg[1024]; + + size_t i; + for(i = 0; i < 6; i++) { + if(Candidate[i] != Signature[i]) { + return SZE_FAIL; + } + } + + return SZ_OK; +} + +// display an error message +void SzDisplayError(SZ_RESULT res) +{ + WaitPrompt(szerrormsg[(res - 1)]); +} + +static u64 rootdir; +static int rootdirlength; + +void SzParse(void) { + // save the offset and the length of this file inside the archive stream structure + SzArchiveStream.offset = filelist[selection].offset; + SzArchiveStream.len = filelist[selection].length; + SzArchiveStream.pos = 0; + + // set handler functions for reading data from DVD and setting the position + SzArchiveStream.InStream.Read = SzDvdFileReadImp; + SzArchiveStream.InStream.Seek = SzDvdFileSeekImp; + + // set default 7Zip SDK handlers for allocation and freeing memory + SzAllocImp.Alloc = SzAlloc; + SzAllocImp.Free = SzFree; + SzAllocTempImp.Alloc = SzAllocTemp; + SzAllocTempImp.Free = SzFreeTemp; + + // prepare CRC and 7Zip database structures + InitCrcTable(); + SzArDbExInit(&SzDb); + + // open the archive + SzRes = SzArchiveOpen(&SzArchiveStream.InStream, &SzDb, &SzAllocImp, &SzAllocTempImp); + + if(SzRes != SZ_OK) + { + // free memory used by the 7z SDK + SzArDbExFree(&SzDb, SzAllocImp.Free); + return; + } + else + { + // archive opened successfully + + // erase all previous entries + memset(&filelist, 0, sizeof(FILEENTRIES) * MAXFILES); + + // add '../' folder + strncpy(filelist[0].filename, "../", 3); + filelist[0].length = rootdirlength; // store rootdir in case the user wants to go one folder up + filelist[0].offset = rootdir; // -''- rootdir length -''- + filelist[0].flags = 0; + + // get contents and parse them into the dvd file list structure + unsigned int SzI, SzJ; + SzJ = 1; + for(SzI = 0; SzI < SzDb.Database.NumFiles; SzI++) + { + SzF = SzDb.Database.Files + SzI; + + // skip directories + if(SzF->IsDirectory) + { + continue; + } + + // do not exceed MAXFILES to avoid possible buffer overflows + if(SzJ == (MAXFILES - 1)) + { + break; + } + + // parse information about this file to the dvd file list structure + strncpy(filelist[SzJ].filename, SzF->Name, MAXJOLIET); // copy joliet name (useless...) + filelist[SzJ].filename[MAXJOLIET] = 0; // terminate string + filelist[SzJ].length = SzF->Size; // filesize + filelist[SzJ].offset = SzI; // the extraction function identifies the file with this number + filelist[SzJ].flags = 0; // only files will be displayed (-> no flags) + SzJ++; + } + + // update maxfiles and select the first entry + maxfiles = SzJ; + offset = selection = 0; + return; + } +} + +void SzClose(void) +{ + SzArDbExFree(&SzDb, SzAllocImp.Free); +} + +bool SzExtractROM(int i, unsigned char *buffer) +{ + + // prepare some variables + SzBlockIndex = 0xFFFFFFFF; + SzOffset = 0; + + // Unzip the file + //ShowAction("Un7zipping file. Please wait..."); + WaitPrompt("Un7zipping file. Please wait..."); + SzRes = SzExtract2( + &SzArchiveStream.InStream, + &SzDb, + i, // index of file + &SzBlockIndex, // index of solid block + &buffer, + &SzBufferSize, + &SzOffset, // offset of stream for required file in *outBuffer + &SzOutSizeProcessed, // size of file in *outBuffer + &SzAllocImp, + &SzAllocTempImp); + + // check for errors + if(SzRes != SZ_OK) + { + // display error message + WaitPrompt(szerrormsg[(SzRes - 1)]); + return false; + } + else + { + // close 7Zip archive and free memory + SzArDbExFree(&SzDb, SzAllocImp.Free); + return true; + } +} +*/ diff --git a/source/ngc/menu.c b/source/ngc/menu.c index a288a76..2710f19 100644 --- a/source/ngc/menu.c +++ b/source/ngc/menu.c @@ -35,8 +35,8 @@ #include "gcvideo.h" #include "preferences.h" #include "fceuram.h" +#include "fceuload.h" -extern int GCMemROM(); extern void ResetNES(void); extern void FCEU_ResetPalette(void); @@ -82,7 +82,7 @@ LoadManager () // load the RAM if (GCSettings.AutoLoad == 1) LoadRAM(GCSettings.SaveMethod, SILENT); - else + else if (GCSettings.AutoLoad == 2) LoadState(GCSettings.SaveMethod, SILENT); ResetNES();