From b7881bfa72cf947b8a2c8f363c8515fb8e628aed Mon Sep 17 00:00:00 2001 From: dborth Date: Thu, 24 Jun 2010 23:38:05 +0000 Subject: [PATCH] use snes9x's internal patching system, fix file browser bug --- source/fileop.cpp | 3 +- source/memfile.cpp | 132 ------------------- source/memfile.h | 34 ----- source/patch.cpp | 273 --------------------------------------- source/snes9x/memmap.cpp | 29 ++++- 5 files changed, 26 insertions(+), 445 deletions(-) delete mode 100644 source/memfile.cpp delete mode 100644 source/memfile.h delete mode 100644 source/patch.cpp diff --git a/source/fileop.cpp b/source/fileop.cpp index 3eab1df..cd601cf 100644 --- a/source/fileop.cpp +++ b/source/fileop.cpp @@ -634,13 +634,14 @@ ParseDirectory(bool waitParse) if(IsDeviceRoot(browser.dir)) { - browser.numEntries = 1; + AddBrowserEntry(); sprintf(browserList[0].filename, ".."); sprintf(browserList[0].displayname, "Up One Level"); browserList[0].length = 0; browserList[0].mtime = 0; browserList[0].isdir = 1; // flag this as a dir browserList[0].icon = ICON_FOLDER; + browser.numEntries++; } parseHalt = false; diff --git a/source/memfile.cpp b/source/memfile.cpp deleted file mode 100644 index 5fdfdb2..0000000 --- a/source/memfile.cpp +++ /dev/null @@ -1,132 +0,0 @@ -/**************************************************************************** - * Snes9x Nintendo Wii/Gamecube Port - * - * Tantric 2008-2010 - * - * memfile.cpp - * - * Memory-based replacement for standard C file functions - * This allows standard file calls to be replaced by memory based ones - * With little modification required to the code - ***************************************************************************/ -#include -#include -#include - -#include "memfile.h" - -/**************************************************************************** - * memfopen - * memory replacement for fopen - * - * Creates a memory-based file - ***************************************************************************/ -MFILE * memfopen(char * buffer, int size) -{ - MFILE *f = (MFILE *)memalign(32, sizeof(MFILE)); - - f->buffer = buffer; - f->offset = 0; - f->size = size; - - return f; -} - -/**************************************************************************** - * memfclose - * memory replacement for fclose - * - * 'Closes' the memory file specified - ***************************************************************************/ -int memfclose(MFILE * src) -{ - free(src); - return 0; -} - -/**************************************************************************** - * memfseek - * memory replacement for fseek - * - * Sets the position indicator associated with the stream to a new position - * defined by adding offset to a reference position specified by origin. - ***************************************************************************/ -int memfseek ( MFILE * m, long int offset, int origin ) -{ - int success = 0; // 0 indicates success - - switch(origin) - { - case MSEEK_SET: - if(offset >= 0 && offset <= m->size) - m->offset = offset; - else - success = 1; // failure - break; - case MSEEK_CUR: - if((m->offset + offset) >= 0 && (m->offset + offset) <= m->size) - m->offset += offset; - else - success = 1; // failure - break; - case MSEEK_END: - if((m->size + offset) >= 0 && (m->size + offset) <= m->size) - m->offset = m->size + offset; - else - success = 1; // failure - break; - } - return success; -} - -/**************************************************************************** - * memftell - * memory replacement for ftell - * - * Get current position in stream (offset + 1) - ***************************************************************************/ -long int memftell (MFILE * stream) -{ - return stream->offset; // to emulate ftell behavior -} - -/**************************************************************************** - * memfread - * memory replacement for fread - * - * Reads an array of count elements, each one with a size of size bytes, from - * the buffer and stores them in the block of memory specified by ptr. The - * postion indicator of the buffer is advanced by the total amount of bytes - * read. The total amount of bytes read if successful is (size * count). - ***************************************************************************/ -size_t memfread(void * dst, size_t size, size_t count, MFILE * src) -{ - if(src->offset >= src->size) // reached end of buffer - return 0; - - int numbytes = size*count; - - if((src->offset + numbytes) > src->size) // can't read full # requested - numbytes = src->size - src->offset; // do a partial read - - if(numbytes > 0) - memcpy(dst, src->buffer+src->offset, numbytes); - - src->offset += numbytes; - return numbytes; -} - -/**************************************************************************** - * memfgetc - * memory replacement for fgetc - * - * Returns the next character in the buffer specified, and advances the - * postion indicator of the buffer by 1. - ***************************************************************************/ -int memfgetc(MFILE * src) -{ - if(src->offset >= src->size) // reached end of buffer - return MEOF; - else - return src->buffer[src->offset++]; -} diff --git a/source/memfile.h b/source/memfile.h deleted file mode 100644 index ce932bb..0000000 --- a/source/memfile.h +++ /dev/null @@ -1,34 +0,0 @@ -/**************************************************************************** - * Snes9x Nintendo Wii/Gamecube Port - * - * Tantric 2008-2010 - * - * memfile.h - * - * Memory-based replacement for standard C file functions - * This allows standard file calls to be replaced by memory based ones - * With little modification required to the code - ***************************************************************************/ - -#ifndef _MEMFILE_H_ -#define _MEMFILE_H_ - -typedef struct MFile { - char *buffer; // pointer to buffer memory - long int offset; // current position indicator in buffer - long int size; // total file (buffer) size -} MFILE; - -#define MSEEK_SET 0 -#define MSEEK_CUR 1 -#define MSEEK_END 2 -#define MEOF (-1) - -MFILE * memfopen(char * buffer, int size); -int memfclose(MFILE * src); -int memfseek ( MFILE * m, long int offset, int origin ); -long int memftell (MFILE * stream); -size_t memfread(void * dst, size_t size, size_t count, MFILE * src); -int memfgetc(MFILE * src); - -#endif diff --git a/source/patch.cpp b/source/patch.cpp deleted file mode 100644 index 4cef0b4..0000000 --- a/source/patch.cpp +++ /dev/null @@ -1,273 +0,0 @@ -/**************************************************************************** - * Snes9x Nintendo Wii/Gamecube Port - * - * Tantric 2008-2010 - * - * patch.cpp - * - * IPS/UPS patch support - ***************************************************************************/ - -#include - -#include "snes9xgx.h" -#include "menu.h" -#include "memfile.h" -#include "fileop.h" -#include "filebrowser.h" -#include "snes9x/snes9x.h" -#include "snes9x/memmap.h" - -static int readInt2(MFILE *f) { - int res = 0; - int c = memfgetc(f); - if (c == MEOF) - return -1; - res = c; - c = memfgetc(f); - if (c == MEOF) - return -1; - return c + (res << 8); -} - -static int readInt3(MFILE *f) { - int res = 0; - int c = memfgetc(f); - if (c == MEOF) - return -1; - res = c; - c = memfgetc(f); - if (c == MEOF) - return -1; - res = c + (res << 8); - c = memfgetc(f); - if (c == MEOF) - return -1; - return c + (res << 8); -} - -static s64 readInt4(MFILE *f) { - s64 tmp, res = 0; - int c; - - for (int i = 0; i < 4; i++) { - c = memfgetc(f); - if (c == MEOF) - return -1; - tmp = c; - res = res + (tmp << (i * 8)); - } - - return res; -} - -static s64 readVarPtr(MFILE *f) { - s64 offset = 0, shift = 1; - for (;;) { - int c = memfgetc(f); - if (c == MEOF) - return 0; - offset += (c & 0x7F) * shift; - if (c & 0x80) - break; - shift <<= 7; - offset += shift; - } - return offset; -} - -#ifndef MIN -#define MIN(a,b) (((a)<(b))?(a):(b)) -#endif - -static uLong computePatchCRC(MFILE *f, unsigned int size) { - Bytef buf[4096]; - long readed; - - uLong crc = crc32(0L, Z_NULL, 0); - do { - readed = memfread(buf, 1, MIN(size, sizeof(buf)), f); - crc = crc32(crc, buf, readed); - size -= readed; - } while (readed > 0); - - return crc; -} - -bool patchApplyIPS(MFILE * f, bool header, u8 **r, int *s) { - // from the IPS spec at http://zerosoft.zophar.net/ips.htm - - bool result = false; - - u8 *rom = *r; - int size = *s; - if (memfgetc(f) == 'P' && memfgetc(f) == 'A' && memfgetc(f) == 'T' - && memfgetc(f) == 'C' && memfgetc(f) == 'H') { - int b; - int offset; - int len; - - result = true; - - for (;;) { - // read offset - offset = readInt3(f); - // if offset == MEOF, end of patch - if (offset == 0x454f46 || offset == -1) - break; - - if(header) - offset -= 512; - - // read length - len = readInt2(f); - if (!len) { - // len == 0, RLE block - len = readInt2(f); - // byte to fill - int c = memfgetc(f); - if (c == -1) - break; - b = (u8) c; - } else - b = -1; - // check if we need to reallocate our ROM - if ((offset + len) >= size) { -#ifdef GEKKO - size = offset + len; -#else - size *= 2; - rom = (u8 *) realloc(rom, size); -#endif - *r = rom; - *s = size; - } - if (b == -1) { - // normal block, just read the data - if (memfread(&rom[offset], 1, len, f) != (size_t) len) - break; - } else { - // fill the region with the given byte - while (len--) { - rom[offset++] = b; - } - } - } - } - return result; -} - -bool patchApplyUPS(MFILE * f, bool header, u8 **rom, int *size) { - - s64 srcCRC, dstCRC, patchCRC; - - memfseek(f, 0, MSEEK_END); - long int patchSize = memftell(f); - if (patchSize < 20) { - return false; - } - - memfseek(f, 0, MSEEK_SET); - - if (memfgetc(f) != 'U' || memfgetc(f) != 'P' || memfgetc(f) != 'S' - || memfgetc(f) != '1') { - return false; - } - - memfseek(f, -12, MSEEK_END); - srcCRC = readInt4(f); - dstCRC = readInt4(f); - patchCRC = readInt4(f); - if (srcCRC == -1 || dstCRC == -1 || patchCRC == -1) { - return false; - } - - memfseek(f, 0, MSEEK_SET); - u32 crc = computePatchCRC(f, patchSize - 4); - - if (crc != patchCRC) { - return false; - } - - crc = crc32(0L, Z_NULL, 0); - crc = crc32(crc, *rom, *size); - - memfseek(f, 4, MSEEK_SET); - s64 dataSize; - s64 srcSize = readVarPtr(f); - s64 dstSize = readVarPtr(f); - - if (crc == srcCRC) { - dataSize = srcSize; - } else if (crc == dstCRC) { - dataSize = dstSize; - } else { - return false; - } - if (dataSize != *size) { - return false; - } - - s64 relative = 0; - - if(header) - relative -= 512; - - u8 *mem; - while (memftell(f) < patchSize - 12) { - relative += readVarPtr(f); - if (relative > dataSize) - continue; - mem = *rom + relative; - for (s64 i = relative; i < dataSize; i++) { - int x = memfgetc(f); - relative++; - if (!x) - break; - if (i < dataSize) { - *mem++ ^= x; - } - } - } - return true; -} - -void WiiLoadPatch(bool header) -{ - int patchsize = 0; - int patchtype; - char patchpath[2][512]; - - AllocSaveBuffer (); - - memset(patchpath, 0, sizeof(patchpath)); - sprintf(patchpath[0], "%s%s.ips", browser.dir, Memory.ROMFilename); - sprintf(patchpath[1], "%s%s.ups", browser.dir, Memory.ROMFilename); - - for(patchtype=0; patchtype<2; patchtype++) - { - patchsize = LoadFile(patchpath[patchtype], SILENT); - - if(patchsize) - break; - } - - if(patchsize > 0) - { - // create memory file - MFILE * mf = memfopen((char *)savebuffer, patchsize); - - int tmpSize = SNESROMSize; - - if(patchtype == 0) - patchApplyIPS(mf, header, &Memory.ROM, &tmpSize); - else - patchApplyUPS(mf, header, &Memory.ROM, &tmpSize); - - SNESROMSize = tmpSize; - - memfclose(mf); // close memory file - } - - FreeSaveBuffer (); -} diff --git a/source/snes9x/memmap.cpp b/source/snes9x/memmap.cpp index f07e600..8fed370 100644 --- a/source/snes9x/memmap.cpp +++ b/source/snes9x/memmap.cpp @@ -204,8 +204,8 @@ #include "display.h" #ifdef GEKKO +#include "../filebrowser.h" extern int WiiFileLoader(); -extern void WiiLoadPatch(bool header); extern void WiiSetupCheats(); #endif @@ -1541,11 +1541,7 @@ again: return (FALSE); if (!Settings.NoPatch) -#ifdef GEKKO - WiiLoadPatch(HeaderCount != 0); -#else CheckForAnyPatch(filename, HeaderCount != 0, totalFileSize); -#endif int hi_score, lo_score; @@ -4143,6 +4139,28 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r if (Settings.NoPatch) return; +#ifdef GEKKO + int patchtype; + char patchpath[2][512]; + STREAM patchfile = NULL; + long offset = header ? 512 : 0; + + sprintf(patchpath[0], "%s%s.ips", browser.dir, Memory.ROMFilename); + sprintf(patchpath[1], "%s%s.ups", browser.dir, Memory.ROMFilename); + + for(patchtype=0; patchtype<2; patchtype++) + { + if ((patchfile = OPEN_STREAM(patchpath[patchtype], "rb")) != NULL) + { + if(patchtype == 0) + ReadIPSPatch(new fReader(patchfile), offset, rom_size); + else + ReadUPSPatch(new fReader(patchfile), 0, rom_size); + CLOSE_STREAM(patchfile); + break; + } + } +#else STREAM patch_file = NULL; uint32 i; long offset = header ? 512 : 0; @@ -4590,4 +4608,5 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r if (flag) return; } +#endif }