Finished updating common, next up gb folder
This commit is contained in:
parent
fa33b8eea4
commit
59577d666f
|
@ -10,13 +10,13 @@
|
||||||
#ifndef __LIBRETRO__
|
#ifndef __LIBRETRO__
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
#if defined (BSD) || defined (__NetBSD__)
|
#if defined(BSD) || defined(__NetBSD__)
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#endif
|
#endif
|
||||||
#if defined(__APPLE__) || defined (BSD) || defined (__NetBSD__)
|
#if defined(__APPLE__) || defined(BSD) || defined(__NetBSD__)
|
||||||
typedef off_t __off64_t; /* off_t is 64 bits on BSD. */
|
typedef off_t __off64_t; /* off_t is 64 bits on BSD. */
|
||||||
#define fseeko64 fseeko
|
#define fseeko64 fseeko
|
||||||
#define ftello64 ftello
|
#define ftello64 ftello
|
||||||
#else
|
#else
|
||||||
typedef off64_t __off64_t;
|
typedef off64_t __off64_t;
|
||||||
#endif /* __APPLE__ || BSD */
|
#endif /* __APPLE__ || BSD */
|
||||||
|
@ -29,442 +29,453 @@ typedef off64_t __off64_t;
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#define fseeko64 _fseeki64
|
#define fseeko64 _fseeki64
|
||||||
#define ftello64 _ftelli64
|
#define ftello64 _ftelli64
|
||||||
typedef __int64 __off64_t;
|
typedef __int64 __off64_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static int readInt2(FILE* f)
|
||||||
static int readInt2(FILE *f)
|
|
||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
int c = fgetc(f);
|
|
||||||
if(c == EOF)
|
|
||||||
return -1;
|
|
||||||
res = c;
|
|
||||||
c = fgetc(f);
|
|
||||||
if(c == EOF)
|
|
||||||
return -1;
|
|
||||||
return c + (res<<8);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int readInt3(FILE *f)
|
|
||||||
{
|
|
||||||
int res = 0;
|
|
||||||
int c = fgetc(f);
|
|
||||||
if(c == EOF)
|
|
||||||
return -1;
|
|
||||||
res = c;
|
|
||||||
c = fgetc(f);
|
|
||||||
if(c == EOF)
|
|
||||||
return -1;
|
|
||||||
res = c + (res<<8);
|
|
||||||
c = fgetc(f);
|
|
||||||
if(c == EOF)
|
|
||||||
return -1;
|
|
||||||
return c + (res<<8);
|
|
||||||
}
|
|
||||||
|
|
||||||
static s64 readInt4(FILE *f)
|
|
||||||
{
|
|
||||||
s64 tmp, res = 0;
|
|
||||||
int c;
|
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++) {
|
|
||||||
c = fgetc(f);
|
|
||||||
if (c == EOF)
|
|
||||||
return -1;
|
|
||||||
tmp = c;
|
|
||||||
res = res + (tmp << (i*8));
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
static s64 readInt8(FILE *f)
|
|
||||||
{
|
|
||||||
s64 tmp, res = 0;
|
|
||||||
int c;
|
|
||||||
|
|
||||||
for (int i = 0; i < 8; i++) {
|
|
||||||
c = fgetc(f);
|
|
||||||
if (c == EOF)
|
|
||||||
return -1;
|
|
||||||
tmp = c;
|
|
||||||
res = res + (tmp << (i*8));
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
static s64 readVarPtr(FILE *f)
|
|
||||||
{
|
|
||||||
s64 offset = 0, shift = 1;
|
|
||||||
for (;;) {
|
|
||||||
int c = fgetc(f);
|
int c = fgetc(f);
|
||||||
if (c == EOF) return 0;
|
if (c == EOF)
|
||||||
offset += (c & 0x7F) * shift;
|
return -1;
|
||||||
if (c & 0x80) break;
|
res = c;
|
||||||
shift <<= 7;
|
c = fgetc(f);
|
||||||
offset += shift;
|
if (c == EOF)
|
||||||
}
|
return -1;
|
||||||
return offset;
|
return c + (res << 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int readInt3(FILE* f)
|
||||||
|
{
|
||||||
|
int res = 0;
|
||||||
|
int c = fgetc(f);
|
||||||
|
if (c == EOF)
|
||||||
|
return -1;
|
||||||
|
res = c;
|
||||||
|
c = fgetc(f);
|
||||||
|
if (c == EOF)
|
||||||
|
return -1;
|
||||||
|
res = c + (res << 8);
|
||||||
|
c = fgetc(f);
|
||||||
|
if (c == EOF)
|
||||||
|
return -1;
|
||||||
|
return c + (res << 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
static s64 readInt4(FILE* f)
|
||||||
|
{
|
||||||
|
s64 tmp, res = 0;
|
||||||
|
int c;
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
c = fgetc(f);
|
||||||
|
if (c == EOF)
|
||||||
|
return -1;
|
||||||
|
tmp = c;
|
||||||
|
res = res + (tmp << (i * 8));
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static s64 readInt8(FILE* f)
|
||||||
|
{
|
||||||
|
s64 tmp, res = 0;
|
||||||
|
int c;
|
||||||
|
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
c = fgetc(f);
|
||||||
|
if (c == EOF)
|
||||||
|
return -1;
|
||||||
|
tmp = c;
|
||||||
|
res = res + (tmp << (i * 8));
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static s64 readVarPtr(FILE* f)
|
||||||
|
{
|
||||||
|
s64 offset = 0, shift = 1;
|
||||||
|
for (;;) {
|
||||||
|
int c = fgetc(f);
|
||||||
|
if (c == EOF)
|
||||||
|
return 0;
|
||||||
|
offset += (c & 0x7F) * shift;
|
||||||
|
if (c & 0x80)
|
||||||
|
break;
|
||||||
|
shift <<= 7;
|
||||||
|
offset += shift;
|
||||||
|
}
|
||||||
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef MIN
|
#ifndef MIN
|
||||||
#define MIN(a,b) (((a)<(b))?(a):(b))
|
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static uLong computePatchCRC(FILE *f, unsigned int size)
|
static uLong computePatchCRC(FILE* f, unsigned int size)
|
||||||
{
|
{
|
||||||
Bytef buf[4096];
|
Bytef buf[4096];
|
||||||
long readed;
|
long readed;
|
||||||
|
|
||||||
uLong crc = crc32(0L, Z_NULL, 0);
|
uLong crc = crc32(0L, Z_NULL, 0);
|
||||||
do {
|
do {
|
||||||
readed = fread(buf, 1, MIN(size, sizeof(buf)), f);
|
readed = fread(buf, 1, MIN(size, sizeof(buf)), f);
|
||||||
crc = crc32(crc, buf, readed);
|
crc = crc32(crc, buf, readed);
|
||||||
size -= readed;
|
size -= readed;
|
||||||
} while (readed > 0);
|
} while (readed > 0);
|
||||||
return crc;
|
return crc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool patchApplyIPS(const char *patchname, u8 **r, int *s)
|
static bool patchApplyIPS(const char* patchname, uint8_t** r, int* s)
|
||||||
{
|
{
|
||||||
// from the IPS spec at http://zerosoft.zophar.net/ips.htm
|
// from the IPS spec at http://zerosoft.zophar.net/ips.htm
|
||||||
FILE *f = fopen(patchname, "rb");
|
FILE* f = fopen(patchname, "rb");
|
||||||
if(!f)
|
if (!f)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
u8 *rom = *r;
|
uint8_t* rom = *r;
|
||||||
int size = *s;
|
int size = *s;
|
||||||
if(fgetc(f) == 'P' &&
|
if (fgetc(f) == 'P' && fgetc(f) == 'A' && fgetc(f) == 'T' && fgetc(f) == 'C' && fgetc(f) == 'H') {
|
||||||
fgetc(f) == 'A' &&
|
int b;
|
||||||
fgetc(f) == 'T' &&
|
int offset;
|
||||||
fgetc(f) == 'C' &&
|
int len;
|
||||||
fgetc(f) == 'H') {
|
|
||||||
int b;
|
|
||||||
int offset;
|
|
||||||
int len;
|
|
||||||
|
|
||||||
result = true;
|
result = true;
|
||||||
|
|
||||||
for(;;) {
|
for (;;) {
|
||||||
// read offset
|
// read offset
|
||||||
offset = readInt3(f);
|
offset = readInt3(f);
|
||||||
// if offset == EOF, end of patch
|
// if offset == EOF, end of patch
|
||||||
if(offset == 0x454f46 || offset == -1)
|
if (offset == 0x454f46 || offset == -1)
|
||||||
break;
|
break;
|
||||||
// read length
|
// read length
|
||||||
len = readInt2(f);
|
len = readInt2(f);
|
||||||
if(!len) {
|
if (!len) {
|
||||||
// len == 0, RLE block
|
// len == 0, RLE block
|
||||||
len = readInt2(f);
|
len = readInt2(f);
|
||||||
// byte to fill
|
// byte to fill
|
||||||
int c = fgetc(f);
|
int c = fgetc(f);
|
||||||
if(c == -1)
|
if (c == -1)
|
||||||
break;
|
break;
|
||||||
b = (u8)c;
|
b = (uint8_t)c;
|
||||||
} else
|
} else
|
||||||
b= -1;
|
b = -1;
|
||||||
// check if we need to reallocate our ROM
|
// check if we need to reallocate our ROM
|
||||||
if((offset + len) >= size) {
|
if ((offset + len) >= size) {
|
||||||
size *= 2;
|
size *= 2;
|
||||||
rom = (u8 *)realloc(rom, size);
|
rom = (uint8_t*)realloc(rom, size);
|
||||||
*r = rom;
|
*r = rom;
|
||||||
*s = size;
|
*s = size;
|
||||||
}
|
}
|
||||||
if(b == -1) {
|
if (b == -1) {
|
||||||
// normal block, just read the data
|
// normal block, just read the data
|
||||||
if(fread(&rom[offset], 1, len, f) != (size_t)len)
|
if (fread(&rom[offset], 1, len, f) != (size_t)len)
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
// fill the region with the given byte
|
// fill the region with the given byte
|
||||||
while(len--) {
|
while (len--) {
|
||||||
rom[offset++] = b;
|
rom[offset++] = b;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
// close the file
|
||||||
// close the file
|
fclose(f);
|
||||||
fclose(f);
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool patchApplyUPS(const char *patchname, u8 **rom, int *size)
|
static bool patchApplyUPS(const char* patchname, uint8_t** rom, int* size)
|
||||||
{
|
{
|
||||||
s64 srcCRC, dstCRC, patchCRC;
|
s64 srcCRC, dstCRC, patchCRC;
|
||||||
|
|
||||||
FILE *f = fopen(patchname, "rb");
|
FILE* f = fopen(patchname, "rb");
|
||||||
if (!f)
|
if (!f)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
fseeko64(f, 0, SEEK_END);
|
fseeko64(f, 0, SEEK_END);
|
||||||
__off64_t patchSize = ftello64(f);
|
__off64_t patchSize = ftello64(f);
|
||||||
if (patchSize < 20) {
|
if (patchSize < 20) {
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
fseeko64(f, 0, SEEK_SET);
|
|
||||||
if(fgetc(f) != 'U' || fgetc(f) != 'P' || fgetc(f) != 'S' || fgetc(f) != '1') {
|
|
||||||
fclose(f);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
fseeko64(f, -12, SEEK_END);
|
|
||||||
srcCRC = readInt4(f);
|
|
||||||
dstCRC = readInt4(f);
|
|
||||||
patchCRC = readInt4(f);
|
|
||||||
if (srcCRC == -1 || dstCRC == -1 || patchCRC == -1) {
|
|
||||||
fclose(f);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
fseeko64(f, 0, SEEK_SET);
|
|
||||||
u32 crc = computePatchCRC(f, patchSize-4);
|
|
||||||
|
|
||||||
if (crc != patchCRC) {
|
|
||||||
fclose(f);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
crc = crc32(0L, Z_NULL, 0);
|
|
||||||
crc = crc32(crc, *rom, *size);
|
|
||||||
|
|
||||||
fseeko64(f, 4, SEEK_SET);
|
|
||||||
s64 dataSize;
|
|
||||||
s64 srcSize = readVarPtr(f);
|
|
||||||
s64 dstSize = readVarPtr(f);
|
|
||||||
|
|
||||||
if (crc == srcCRC) {
|
|
||||||
if (srcSize != *size) {
|
|
||||||
fclose(f);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
dataSize = dstSize;
|
|
||||||
} else if (crc == dstCRC) {
|
fseeko64(f, 0, SEEK_SET);
|
||||||
if (dstSize != *size) {
|
if (fgetc(f) != 'U' || fgetc(f) != 'P' || fgetc(f) != 'S' || fgetc(f) != '1') {
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
dataSize = srcSize;
|
|
||||||
} else {
|
fseeko64(f, -12, SEEK_END);
|
||||||
|
srcCRC = readInt4(f);
|
||||||
|
dstCRC = readInt4(f);
|
||||||
|
patchCRC = readInt4(f);
|
||||||
|
if (srcCRC == -1 || dstCRC == -1 || patchCRC == -1) {
|
||||||
|
fclose(f);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fseeko64(f, 0, SEEK_SET);
|
||||||
|
uint32_t crc = computePatchCRC(f, patchSize - 4);
|
||||||
|
|
||||||
|
if (crc != patchCRC) {
|
||||||
|
fclose(f);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
crc = crc32(0L, Z_NULL, 0);
|
||||||
|
crc = crc32(crc, *rom, *size);
|
||||||
|
|
||||||
|
fseeko64(f, 4, SEEK_SET);
|
||||||
|
s64 dataSize;
|
||||||
|
s64 srcSize = readVarPtr(f);
|
||||||
|
s64 dstSize = readVarPtr(f);
|
||||||
|
|
||||||
|
if (crc == srcCRC) {
|
||||||
|
if (srcSize != *size) {
|
||||||
|
fclose(f);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
dataSize = dstSize;
|
||||||
|
} else if (crc == dstCRC) {
|
||||||
|
if (dstSize != *size) {
|
||||||
|
fclose(f);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
dataSize = srcSize;
|
||||||
|
} else {
|
||||||
|
fclose(f);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (dataSize > *size) {
|
||||||
|
*rom = (uint8_t*)realloc(*rom, dataSize);
|
||||||
|
memset(*rom + *size, 0, dataSize - *size);
|
||||||
|
*size = dataSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
s64 relative = 0;
|
||||||
|
uint8_t* mem;
|
||||||
|
while (ftello64(f) < patchSize - 12) {
|
||||||
|
relative += readVarPtr(f);
|
||||||
|
if (relative > dataSize)
|
||||||
|
continue;
|
||||||
|
mem = *rom + relative;
|
||||||
|
for (s64 i = relative; i < dataSize; i++) {
|
||||||
|
int x = fgetc(f);
|
||||||
|
relative++;
|
||||||
|
if (!x)
|
||||||
|
break;
|
||||||
|
if (i < dataSize) {
|
||||||
|
*mem++ ^= x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
if (dataSize > *size) {
|
|
||||||
*rom = (u8*)realloc(*rom, dataSize);
|
|
||||||
memset(*rom + *size, 0, dataSize - *size);
|
|
||||||
*size = dataSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
s64 relative = 0;
|
static int ppfVersion(FILE* f)
|
||||||
u8 *mem;
|
{
|
||||||
while(ftello64(f) < patchSize - 12) {
|
fseeko64(f, 0, SEEK_SET);
|
||||||
relative += readVarPtr(f);
|
if (fgetc(f) != 'P' || fgetc(f) != 'P' || fgetc(f) != 'F') //-V501
|
||||||
if (relative > dataSize) continue;
|
return 0;
|
||||||
mem = *rom + relative;
|
switch (fgetc(f)) {
|
||||||
for(s64 i = relative; i < dataSize; i++) {
|
case '1':
|
||||||
int x = fgetc(f);
|
return 1;
|
||||||
relative++;
|
case '2':
|
||||||
if (!x) break;
|
return 2;
|
||||||
if (i < dataSize) {
|
case '3':
|
||||||
*mem++ ^= x;
|
return 3;
|
||||||
}
|
default:
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fclose(f);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ppfVersion(FILE *f)
|
static int ppfFileIdLen(FILE* f, int version)
|
||||||
{
|
{
|
||||||
fseeko64(f, 0, SEEK_SET);
|
if (version == 2) {
|
||||||
if (fgetc(f) != 'P' || fgetc(f) != 'P' || fgetc(f) != 'F') //-V501
|
fseeko64(f, -8, SEEK_END);
|
||||||
return 0;
|
} else {
|
||||||
switch(fgetc(f)){
|
fseeko64(f, -6, SEEK_END);
|
||||||
case '1': return 1;
|
}
|
||||||
case '2': return 2;
|
|
||||||
case '3': return 3;
|
if (fgetc(f) != '.' || fgetc(f) != 'D' || fgetc(f) != 'I' || fgetc(f) != 'Z')
|
||||||
default: return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
return (version == 2) ? readInt4(f) : readInt2(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ppfFileIdLen(FILE *f, int version)
|
static bool patchApplyPPF1(FILE* f, uint8_t** rom, int* size)
|
||||||
{
|
{
|
||||||
if (version == 2) {
|
fseek(f, 0, SEEK_END);
|
||||||
fseeko64(f, -8, SEEK_END);
|
int count = ftell(f);
|
||||||
} else {
|
if (count < 56)
|
||||||
fseeko64(f, -6, SEEK_END);
|
return false;
|
||||||
}
|
count -= 56;
|
||||||
|
|
||||||
if (fgetc(f) != '.' || fgetc(f) != 'D' || fgetc(f) != 'I' || fgetc(f) != 'Z')
|
fseek(f, 56, SEEK_SET);
|
||||||
return 0;
|
|
||||||
|
|
||||||
return (version == 2) ? readInt4(f) : readInt2(f);
|
uint8_t* mem = *rom;
|
||||||
|
|
||||||
|
while (count > 0) {
|
||||||
|
int offset = readInt4(f);
|
||||||
|
if (offset == -1)
|
||||||
|
break;
|
||||||
|
int len = fgetc(f);
|
||||||
|
if (len == EOF)
|
||||||
|
break;
|
||||||
|
if (offset + len > *size)
|
||||||
|
break;
|
||||||
|
if (fread(&mem[offset], 1, len, f) != (size_t)len)
|
||||||
|
break;
|
||||||
|
count -= 4 + 1 + len;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (count == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool patchApplyPPF1(FILE *f, u8 **rom, int *size)
|
static bool patchApplyPPF2(FILE* f, uint8_t** rom, int* size)
|
||||||
{
|
{
|
||||||
fseek(f, 0, SEEK_END);
|
fseek(f, 0, SEEK_END);
|
||||||
int count = ftell(f);
|
int count = ftell(f);
|
||||||
if (count < 56)
|
if (count < 56 + 4 + 1024)
|
||||||
return false;
|
return false;
|
||||||
count -= 56;
|
count -= 56 + 4 + 1024;
|
||||||
|
|
||||||
fseek(f, 56, SEEK_SET);
|
fseek(f, 56, SEEK_SET);
|
||||||
|
|
||||||
u8 *mem = *rom;
|
int datalen = readInt4(f);
|
||||||
|
if (datalen != *size)
|
||||||
|
return false;
|
||||||
|
|
||||||
while (count > 0) {
|
uint8_t* mem = *rom;
|
||||||
int offset = readInt4(f);
|
|
||||||
if (offset == -1)
|
|
||||||
break;
|
|
||||||
int len = fgetc(f);
|
|
||||||
if (len == EOF)
|
|
||||||
break;
|
|
||||||
if (offset+len > *size)
|
|
||||||
break;
|
|
||||||
if (fread(&mem[offset], 1, len, f) != (size_t)len)
|
|
||||||
break;
|
|
||||||
count -= 4 + 1 + len;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (count == 0);
|
uint8_t block[1024];
|
||||||
}
|
|
||||||
|
|
||||||
static bool patchApplyPPF2(FILE *f, u8 **rom, int *size)
|
|
||||||
{
|
|
||||||
fseek(f, 0, SEEK_END);
|
|
||||||
int count = ftell(f);
|
|
||||||
if (count < 56+4+1024)
|
|
||||||
return false;
|
|
||||||
count -= 56+4+1024;
|
|
||||||
|
|
||||||
fseek(f, 56, SEEK_SET);
|
|
||||||
|
|
||||||
int datalen = readInt4(f);
|
|
||||||
if (datalen != *size)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
u8 *mem = *rom;
|
|
||||||
|
|
||||||
u8 block[1024];
|
|
||||||
fread(&block, 1, 1024, f);
|
|
||||||
if (memcmp(&mem[0x9320], &block, 1024) != 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
int idlen = ppfFileIdLen(f, 2);
|
|
||||||
if (idlen > 0)
|
|
||||||
count -= 16 + 16 + idlen;
|
|
||||||
|
|
||||||
fseek(f, 56+4+1024, SEEK_SET);
|
|
||||||
|
|
||||||
while (count > 0) {
|
|
||||||
int offset = readInt4(f);
|
|
||||||
if (offset == -1)
|
|
||||||
break;
|
|
||||||
int len = fgetc(f);
|
|
||||||
if (len == EOF)
|
|
||||||
break;
|
|
||||||
if (offset+len > *size)
|
|
||||||
break;
|
|
||||||
if (fread(&mem[offset], 1, len, f) != (size_t)len)
|
|
||||||
break;
|
|
||||||
count -= 4 + 1 + len;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (count == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool patchApplyPPF3(FILE *f, u8 **rom, int *size)
|
|
||||||
{
|
|
||||||
fseek(f, 0, SEEK_END);
|
|
||||||
int count = ftell(f);
|
|
||||||
if (count < 56+4+1024)
|
|
||||||
return false;
|
|
||||||
count -= 56+4;
|
|
||||||
|
|
||||||
fseek(f, 56, SEEK_SET);
|
|
||||||
|
|
||||||
int imagetype = fgetc(f);
|
|
||||||
int blockcheck = fgetc(f);
|
|
||||||
int undo = fgetc(f);
|
|
||||||
fgetc(f);
|
|
||||||
|
|
||||||
u8 *mem = *rom;
|
|
||||||
|
|
||||||
if (blockcheck) {
|
|
||||||
u8 block[1024];
|
|
||||||
fread(&block, 1, 1024, f);
|
fread(&block, 1, 1024, f);
|
||||||
if (memcmp(&mem[(imagetype == 0) ? 0x9320 : 0x80A0], &block, 1024) != 0)
|
if (memcmp(&mem[0x9320], &block, 1024) != 0)
|
||||||
return false;
|
return false;
|
||||||
count -= 1024;
|
|
||||||
}
|
|
||||||
|
|
||||||
int idlen = ppfFileIdLen(f, 2);
|
int idlen = ppfFileIdLen(f, 2);
|
||||||
if (idlen > 0)
|
if (idlen > 0)
|
||||||
count -= 16 + 16 + idlen;
|
count -= 16 + 16 + idlen;
|
||||||
|
|
||||||
fseek(f, 56+4+(blockcheck ? 1024 : 0), SEEK_SET);
|
fseek(f, 56 + 4 + 1024, SEEK_SET);
|
||||||
|
|
||||||
while (count > 0) {
|
while (count > 0) {
|
||||||
__off64_t offset = readInt8(f);
|
int offset = readInt4(f);
|
||||||
if (offset == -1)
|
if (offset == -1)
|
||||||
break;
|
break;
|
||||||
int len = fgetc(f);
|
int len = fgetc(f);
|
||||||
if (len == EOF)
|
if (len == EOF)
|
||||||
break;
|
break;
|
||||||
if (offset+len > *size)
|
if (offset + len > *size)
|
||||||
break;
|
break;
|
||||||
if (fread(&mem[offset], 1, len, f) != (size_t)len)
|
if (fread(&mem[offset], 1, len, f) != (size_t)len)
|
||||||
break;
|
break;
|
||||||
if (undo) fseeko64(f, len, SEEK_CUR);
|
count -= 4 + 1 + len;
|
||||||
count -= 8 + 1 + len;
|
}
|
||||||
if (undo) count -= len;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (count == 0);
|
return (count == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool patchApplyPPF(const char *patchname, u8 **rom, int *size)
|
static bool patchApplyPPF3(FILE* f, uint8_t** rom, int* size)
|
||||||
{
|
{
|
||||||
FILE *f = fopen(patchname, "rb");
|
fseek(f, 0, SEEK_END);
|
||||||
if (!f)
|
int count = ftell(f);
|
||||||
return false;
|
if (count < 56 + 4 + 1024)
|
||||||
|
return false;
|
||||||
|
count -= 56 + 4;
|
||||||
|
|
||||||
bool res = false;
|
fseek(f, 56, SEEK_SET);
|
||||||
|
|
||||||
int version = ppfVersion(f);
|
int imagetype = fgetc(f);
|
||||||
switch (version) {
|
int blockcheck = fgetc(f);
|
||||||
case 1: res = patchApplyPPF1(f, rom, size); break;
|
int undo = fgetc(f);
|
||||||
case 2: res = patchApplyPPF2(f, rom, size); break;
|
fgetc(f);
|
||||||
case 3: res = patchApplyPPF3(f, rom, size); break;
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(f);
|
uint8_t* mem = *rom;
|
||||||
return res;
|
|
||||||
|
if (blockcheck) {
|
||||||
|
uint8_t block[1024];
|
||||||
|
fread(&block, 1, 1024, f);
|
||||||
|
if (memcmp(&mem[(imagetype == 0) ? 0x9320 : 0x80A0], &block, 1024) != 0)
|
||||||
|
return false;
|
||||||
|
count -= 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
int idlen = ppfFileIdLen(f, 2);
|
||||||
|
if (idlen > 0)
|
||||||
|
count -= 16 + 16 + idlen;
|
||||||
|
|
||||||
|
fseek(f, 56 + 4 + (blockcheck ? 1024 : 0), SEEK_SET);
|
||||||
|
|
||||||
|
while (count > 0) {
|
||||||
|
__off64_t offset = readInt8(f);
|
||||||
|
if (offset == -1)
|
||||||
|
break;
|
||||||
|
int len = fgetc(f);
|
||||||
|
if (len == EOF)
|
||||||
|
break;
|
||||||
|
if (offset + len > *size)
|
||||||
|
break;
|
||||||
|
if (fread(&mem[offset], 1, len, f) != (size_t)len)
|
||||||
|
break;
|
||||||
|
if (undo)
|
||||||
|
fseeko64(f, len, SEEK_CUR);
|
||||||
|
count -= 8 + 1 + len;
|
||||||
|
if (undo)
|
||||||
|
count -= len;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (count == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool patchApplyPPF(const char* patchname, uint8_t** rom, int* size)
|
||||||
|
{
|
||||||
|
FILE* f = fopen(patchname, "rb");
|
||||||
|
if (!f)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bool res = false;
|
||||||
|
|
||||||
|
int version = ppfVersion(f);
|
||||||
|
switch (version) {
|
||||||
|
case 1:
|
||||||
|
res = patchApplyPPF1(f, rom, size);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
res = patchApplyPPF2(f, rom, size);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
res = patchApplyPPF3(f, rom, size);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool applyPatch(const char *patchname, u8 **rom, int *size)
|
bool applyPatch(const char* patchname, uint8_t** rom, int* size)
|
||||||
{
|
{
|
||||||
#ifndef __LIBRETRO__
|
#ifndef __LIBRETRO__
|
||||||
if (strlen(patchname) < 5)
|
if (strlen(patchname) < 5)
|
||||||
return false;
|
return false;
|
||||||
const char * p = strrchr(patchname, '.');
|
const char* p = strrchr(patchname, '.');
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
return false;
|
return false;
|
||||||
if (_stricmp(p, ".ips") == 0)
|
if (_stricmp(p, ".ips") == 0)
|
||||||
return patchApplyIPS(patchname, rom, size);
|
return patchApplyIPS(patchname, rom, size);
|
||||||
if (_stricmp(p, ".ups") == 0)
|
if (_stricmp(p, ".ups") == 0)
|
||||||
return patchApplyUPS(patchname, rom, size);
|
return patchApplyUPS(patchname, rom, size);
|
||||||
if (_stricmp(p, ".ppf") == 0)
|
if (_stricmp(p, ".ppf") == 0)
|
||||||
return patchApplyPPF(patchname, rom, size);
|
return patchApplyPPF(patchname, rom, size);
|
||||||
#endif
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,6 @@
|
||||||
|
|
||||||
#include "Types.h"
|
#include "Types.h"
|
||||||
|
|
||||||
bool applyPatch(const char *patchname, u8 **rom, int *size);
|
bool applyPatch(const char *patchname, uint8_t **rom, int *size);
|
||||||
|
|
||||||
#endif // PATCH_H
|
#endif // PATCH_H
|
||||||
|
|
|
@ -11,16 +11,14 @@
|
||||||
#include <ppcintrinsics.h>
|
#include <ppcintrinsics.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "Types.h"
|
|
||||||
|
|
||||||
// swaps a 16-bit value
|
// swaps a 16-bit value
|
||||||
static inline u16 swap16(u16 v)
|
static inline uint16_t swap16(u16 v)
|
||||||
{
|
{
|
||||||
return (v << 8) | (v >> 8);
|
return (v << 8) | (v >> 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
// swaps a 32-bit value
|
// swaps a 32-bit value
|
||||||
static inline u32 swap32(u32 v)
|
static inline uint32_t swap32(uint32_t v)
|
||||||
{
|
{
|
||||||
return (v << 24) | ((v << 8) & 0xff0000) | ((v >> 8) & 0xff00) | (v >> 24);
|
return (v << 24) | ((v << 8) & 0xff0000) | ((v >> 8) & 0xff00) | (v >> 24);
|
||||||
}
|
}
|
||||||
|
@ -47,16 +45,16 @@ static inline u32 swap32(u32 v)
|
||||||
#define WRITE32LE(base, value) __asm__("stwbrx %0, 0, %1" : : "r"(value), "r"(base) : "memory")
|
#define WRITE32LE(base, value) __asm__("stwbrx %0, 0, %1" : : "r"(value), "r"(base) : "memory")
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#define READ16LE(x) swap16(*((u16 *)(x)))
|
#define READ16LE(x) swap16(*((uint16_t *)(x)))
|
||||||
#define READ32LE(x) swap32(*((u32 *)(x)))
|
#define READ32LE(x) swap32(*((uint32_t *)(x)))
|
||||||
#define WRITE16LE(x, v) *((u16 *)x) = swap16((v))
|
#define WRITE16LE(x, v) *((uint16_t *)x) = swap16((v))
|
||||||
#define WRITE32LE(x, v) *((u32 *)x) = swap32((v))
|
#define WRITE32LE(x, v) *((uint32_t *)x) = swap32((v))
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
#define READ16LE(x) *((u16 *)x)
|
#define READ16LE(x) *((uint16_t *)x)
|
||||||
#define READ32LE(x) *((u32 *)x)
|
#define READ32LE(x) *((uint32_t *)x)
|
||||||
#define WRITE16LE(x, v) *((u16 *)x) = (v)
|
#define WRITE16LE(x, v) *((uint16_t *)x) = (v)
|
||||||
#define WRITE32LE(x, v) *((u32 *)x) = (v)
|
#define WRITE32LE(x, v) *((uint32_t *)x) = (v)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // PORT_H
|
#endif // PORT_H
|
||||||
|
|
|
@ -18,8 +18,6 @@
|
||||||
#ifndef __VBA_SOUND_DRIVER_H__
|
#ifndef __VBA_SOUND_DRIVER_H__
|
||||||
#define __VBA_SOUND_DRIVER_H__
|
#define __VBA_SOUND_DRIVER_H__
|
||||||
|
|
||||||
#include "Types.h"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sound driver abstract interface for the core to use to output sound.
|
* Sound driver abstract interface for the core to use to output sound.
|
||||||
* Subclass this to implement a new sound driver.
|
* Subclass this to implement a new sound driver.
|
||||||
|
@ -56,7 +54,7 @@ class SoundDriver
|
||||||
/**
|
/**
|
||||||
* Write length bytes of data from the finalWave buffer to the driver output buffer.
|
* Write length bytes of data from the finalWave buffer to the driver output buffer.
|
||||||
*/
|
*/
|
||||||
virtual void write(u16 *finalWave, int length) = 0;
|
virtual void write(uint16_t *finalWave, int length) = 0;
|
||||||
|
|
||||||
virtual void setThrottle(unsigned short throttle){};
|
virtual void setThrottle(unsigned short throttle){};
|
||||||
};
|
};
|
||||||
|
|
|
@ -34,12 +34,12 @@ SoundSDL::SoundSDL():
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundSDL::soundCallback(void *data, u8 *stream, int len)
|
void SoundSDL::soundCallback(void *data, uint8_t *stream, int len)
|
||||||
{
|
{
|
||||||
reinterpret_cast<SoundSDL*>(data)->read(reinterpret_cast<u16 *>(stream), len);
|
reinterpret_cast<SoundSDL*>(data)->read(reinterpret_cast<uint16_t *>(stream), len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundSDL::read(u16 * stream, int length)
|
void SoundSDL::read(uint16_t * stream, int length)
|
||||||
{
|
{
|
||||||
if (!_initialized || length <= 0 || !emulating)
|
if (!_initialized || length <= 0 || !emulating)
|
||||||
return;
|
return;
|
||||||
|
@ -62,7 +62,7 @@ void SoundSDL::read(u16 * stream, int length)
|
||||||
SDL_SemPost (_semBufferEmpty);
|
SDL_SemPost (_semBufferEmpty);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundSDL::write(u16 * finalWave, int length)
|
void SoundSDL::write(uint16_t * finalWave, int length)
|
||||||
{
|
{
|
||||||
if (!_initialized)
|
if (!_initialized)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -36,7 +36,7 @@ class SoundSDL : public SoundDriver
|
||||||
virtual void write(u16 *finalWave, int length);
|
virtual void write(u16 *finalWave, int length);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RingBuffer<u16> _rbuf;
|
RingBuffer<uint16_t> _rbuf;
|
||||||
|
|
||||||
SDL_mutex *_mutex;
|
SDL_mutex *_mutex;
|
||||||
SDL_sem *_semBufferFull;
|
SDL_sem *_semBufferFull;
|
||||||
|
@ -51,7 +51,7 @@ class SoundSDL : public SoundDriver
|
||||||
static const float _delay;
|
static const float _delay;
|
||||||
|
|
||||||
static void soundCallback(void *data, u8 *stream, int length);
|
static void soundCallback(void *data, u8 *stream, int length);
|
||||||
virtual void read(u16 *stream, int length);
|
virtual void read(uint16_t *stream, int length);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __VBA_SOUND_SDL_H__
|
#endif // __VBA_SOUND_SDL_H__
|
||||||
|
|
|
@ -285,14 +285,14 @@ MediaRet MediaRecorder::finish_setup(const char *fname)
|
||||||
case CODEC_ID_PCM_U16BE:
|
case CODEC_ID_PCM_U16BE:
|
||||||
frame_len = sample_len;
|
frame_len = sample_len;
|
||||||
}
|
}
|
||||||
audio_buf = (u8 *)malloc(AUDIO_BUF_LEN);
|
audio_buf = (uint8_t *)malloc(AUDIO_BUF_LEN);
|
||||||
if(!audio_buf) {
|
if(!audio_buf) {
|
||||||
avformat_free_context(oc);
|
avformat_free_context(oc);
|
||||||
oc = NULL;
|
oc = NULL;
|
||||||
return MRET_ERR_NOMEM;
|
return MRET_ERR_NOMEM;
|
||||||
}
|
}
|
||||||
if(frame_len != sample_len && (frame_len > sample_len || sample_len % frame_len)) {
|
if(frame_len != sample_len && (frame_len > sample_len || sample_len % frame_len)) {
|
||||||
audio_buf2 = (u16 *)malloc(frame_len);
|
audio_buf2 = (uint16_t *)malloc(frame_len);
|
||||||
if(!audio_buf2) {
|
if(!audio_buf2) {
|
||||||
avformat_free_context(oc);
|
avformat_free_context(oc);
|
||||||
oc = NULL;
|
oc = NULL;
|
||||||
|
@ -304,7 +304,7 @@ MediaRet MediaRecorder::finish_setup(const char *fname)
|
||||||
if(video_buf)
|
if(video_buf)
|
||||||
free(video_buf);
|
free(video_buf);
|
||||||
if(vid_st) {
|
if(vid_st) {
|
||||||
video_buf = (u8 *)malloc(VIDEO_BUF_LEN);
|
video_buf = (uint8_t *)malloc(VIDEO_BUF_LEN);
|
||||||
if(!video_buf) {
|
if(!video_buf) {
|
||||||
avformat_free_context(oc);
|
avformat_free_context(oc);
|
||||||
oc = NULL;
|
oc = NULL;
|
||||||
|
@ -361,7 +361,7 @@ void MediaRecorder::Stop()
|
||||||
{
|
{
|
||||||
if(oc) {
|
if(oc) {
|
||||||
if(in_audio_buf2)
|
if(in_audio_buf2)
|
||||||
AddFrame((u16 *)0);
|
AddFrame((uint16_t *)0);
|
||||||
av_write_trailer(oc);
|
av_write_trailer(oc);
|
||||||
avformat_free_context(oc);
|
avformat_free_context(oc);
|
||||||
oc = NULL;
|
oc = NULL;
|
||||||
|
@ -395,7 +395,7 @@ MediaRecorder::~MediaRecorder()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Still needs updating for avcodec_encode_video2
|
// Still needs updating for avcodec_encode_video2
|
||||||
MediaRet MediaRecorder::AddFrame(const u8 *vid)
|
MediaRet MediaRecorder::AddFrame(const uint8_t *vid)
|
||||||
{
|
{
|
||||||
if(!oc || !vid_st)
|
if(!oc || !vid_st)
|
||||||
return MRET_OK;
|
return MRET_OK;
|
||||||
|
@ -527,7 +527,7 @@ static inline int MediaRecorderEncodeAudio(AVCodecContext *ctx,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
MediaRet MediaRecorder::AddFrame(const u16 *aud)
|
MediaRet MediaRecorder::AddFrame(const uint16_t *aud)
|
||||||
{
|
{
|
||||||
if(!oc || !aud_st)
|
if(!oc || !aud_st)
|
||||||
return MRET_OK;
|
return MRET_OK;
|
||||||
|
|
Loading…
Reference in New Issue