mirror of
https://github.com/dborth/snes9xgx.git
synced 2024-11-24 03:29:22 +01:00
use snes9x's internal patching system, fix file browser bug
This commit is contained in:
parent
642d17c355
commit
b7881bfa72
@ -634,13 +634,14 @@ ParseDirectory(bool waitParse)
|
|||||||
|
|
||||||
if(IsDeviceRoot(browser.dir))
|
if(IsDeviceRoot(browser.dir))
|
||||||
{
|
{
|
||||||
browser.numEntries = 1;
|
AddBrowserEntry();
|
||||||
sprintf(browserList[0].filename, "..");
|
sprintf(browserList[0].filename, "..");
|
||||||
sprintf(browserList[0].displayname, "Up One Level");
|
sprintf(browserList[0].displayname, "Up One Level");
|
||||||
browserList[0].length = 0;
|
browserList[0].length = 0;
|
||||||
browserList[0].mtime = 0;
|
browserList[0].mtime = 0;
|
||||||
browserList[0].isdir = 1; // flag this as a dir
|
browserList[0].isdir = 1; // flag this as a dir
|
||||||
browserList[0].icon = ICON_FOLDER;
|
browserList[0].icon = ICON_FOLDER;
|
||||||
|
browser.numEntries++;
|
||||||
}
|
}
|
||||||
|
|
||||||
parseHalt = false;
|
parseHalt = false;
|
||||||
|
@ -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 <malloc.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#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++];
|
|
||||||
}
|
|
@ -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
|
|
273
source/patch.cpp
273
source/patch.cpp
@ -1,273 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* Snes9x Nintendo Wii/Gamecube Port
|
|
||||||
*
|
|
||||||
* Tantric 2008-2010
|
|
||||||
*
|
|
||||||
* patch.cpp
|
|
||||||
*
|
|
||||||
* IPS/UPS patch support
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
#include <zlib.h>
|
|
||||||
|
|
||||||
#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 ();
|
|
||||||
}
|
|
@ -204,8 +204,8 @@
|
|||||||
#include "display.h"
|
#include "display.h"
|
||||||
|
|
||||||
#ifdef GEKKO
|
#ifdef GEKKO
|
||||||
|
#include "../filebrowser.h"
|
||||||
extern int WiiFileLoader();
|
extern int WiiFileLoader();
|
||||||
extern void WiiLoadPatch(bool header);
|
|
||||||
extern void WiiSetupCheats();
|
extern void WiiSetupCheats();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1541,11 +1541,7 @@ again:
|
|||||||
return (FALSE);
|
return (FALSE);
|
||||||
|
|
||||||
if (!Settings.NoPatch)
|
if (!Settings.NoPatch)
|
||||||
#ifdef GEKKO
|
|
||||||
WiiLoadPatch(HeaderCount != 0);
|
|
||||||
#else
|
|
||||||
CheckForAnyPatch(filename, HeaderCount != 0, totalFileSize);
|
CheckForAnyPatch(filename, HeaderCount != 0, totalFileSize);
|
||||||
#endif
|
|
||||||
|
|
||||||
int hi_score, lo_score;
|
int hi_score, lo_score;
|
||||||
|
|
||||||
@ -4143,6 +4139,28 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r
|
|||||||
if (Settings.NoPatch)
|
if (Settings.NoPatch)
|
||||||
return;
|
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;
|
STREAM patch_file = NULL;
|
||||||
uint32 i;
|
uint32 i;
|
||||||
long offset = header ? 512 : 0;
|
long offset = header ? 512 : 0;
|
||||||
@ -4590,4 +4608,5 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r
|
|||||||
if (flag)
|
if (flag)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user