Patches by chrono:
[CORE] Add UPS/PPF patch support [SDL] Add UPS/PPF patch support [SDL] Fix memory leak
This commit is contained in:
parent
dcc2f30119
commit
89c0a7b049
|
@ -134,6 +134,7 @@ SET(SRC_MAIN
|
|||
src/Mode3.cpp
|
||||
src/Mode4.cpp
|
||||
src/Mode5.cpp
|
||||
src/Patch.cpp
|
||||
src/pixel.cpp
|
||||
src/RTC.cpp
|
||||
src/scanline.cpp
|
||||
|
|
|
@ -0,0 +1,464 @@
|
|||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2004-2006 Forgotten and the VBA development team
|
||||
// Copyright (C) 2007-2008 VBA-M development team and Shay Green
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2, or(at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software Foundation,
|
||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <zlib.h>
|
||||
|
||||
#include "System.h"
|
||||
// #include "NLS.h"
|
||||
// #include "Util.h"
|
||||
// #include "Flash.h"
|
||||
// #include "agb/GBA.h"
|
||||
// #include "Globals.h"
|
||||
// #include "RTC.h"
|
||||
// #include "Port.h"
|
||||
|
||||
#ifndef _MSC_VER
|
||||
#define _stricmp strcasecmp
|
||||
#endif // ! _MSC_VER
|
||||
|
||||
#if defined(__APPLE__) || defined (MACOSX)
|
||||
#define fseeko64 fseeko
|
||||
#define ftello64 ftello
|
||||
typedef off_t __off64_t;
|
||||
#endif /* __APPLE__ || MACOSX */
|
||||
|
||||
static int readInt2(FILE *f)
|
||||
{
|
||||
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);
|
||||
if (c == EOF) 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(FILE *f, unsigned int size)
|
||||
{
|
||||
Bytef buf[4096];
|
||||
long readed;
|
||||
|
||||
uLong crc = crc32(0L, Z_NULL, 0);
|
||||
do {
|
||||
readed = fread(buf, 1, MIN(size, sizeof(buf)), f);
|
||||
crc = crc32(crc, buf, readed);
|
||||
size -= readed;
|
||||
} while (readed > 0);
|
||||
return crc;
|
||||
}
|
||||
|
||||
static bool patchApplyIPS(const char *patchname, u8 **r, int *s)
|
||||
{
|
||||
// from the IPS spec at http://zerosoft.zophar.net/ips.htm
|
||||
FILE *f = fopen(patchname, "rb");
|
||||
if(!f)
|
||||
return false;
|
||||
|
||||
bool result = false;
|
||||
|
||||
u8 *rom = *r;
|
||||
int size = *s;
|
||||
if(fgetc(f) == 'P' &&
|
||||
fgetc(f) == 'A' &&
|
||||
fgetc(f) == 'T' &&
|
||||
fgetc(f) == 'C' &&
|
||||
fgetc(f) == 'H') {
|
||||
int b;
|
||||
int offset;
|
||||
int len;
|
||||
|
||||
result = true;
|
||||
|
||||
for(;;) {
|
||||
// read offset
|
||||
offset = readInt3(f);
|
||||
// if offset == EOF, end of patch
|
||||
if(offset == 0x454f46 || offset == -1)
|
||||
break;
|
||||
// read length
|
||||
len = readInt2(f);
|
||||
if(!len) {
|
||||
// len == 0, RLE block
|
||||
len = readInt2(f);
|
||||
// byte to fill
|
||||
int c = fgetc(f);
|
||||
if(c == -1)
|
||||
break;
|
||||
b = (u8)c;
|
||||
} else
|
||||
b= -1;
|
||||
// check if we need to reallocate our ROM
|
||||
if((offset + len) >= size) {
|
||||
size *= 2;
|
||||
rom = (u8 *)realloc(rom, size);
|
||||
*r = rom;
|
||||
*s = size;
|
||||
}
|
||||
if(b == -1) {
|
||||
// normal block, just read the data
|
||||
if(fread(&rom[offset], 1, len, f) != (size_t)len)
|
||||
break;
|
||||
} else {
|
||||
// fill the region with the given byte
|
||||
while(len--) {
|
||||
rom[offset++] = b;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// close the file
|
||||
fclose(f);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool patchApplyUPS(const char *patchname, u8 **rom, int *size)
|
||||
{
|
||||
s64 srcCRC, dstCRC, patchCRC;
|
||||
|
||||
FILE *f = fopen(patchname, "rb");
|
||||
if (!f)
|
||||
return false;
|
||||
|
||||
fseeko64(f, 0, SEEK_END);
|
||||
__off64_t patchSize = ftello64(f);
|
||||
if (patchSize < 20) {
|
||||
fclose(f);
|
||||
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) {
|
||||
dataSize = srcSize;
|
||||
} else if (crc == dstCRC) {
|
||||
dataSize = dstSize;
|
||||
} else {
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
if (dataSize != *size) {
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
|
||||
s64 relative = 0;
|
||||
u8 *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);
|
||||
return true;
|
||||
}
|
||||
|
||||
static int ppfVersion(FILE *f)
|
||||
{
|
||||
fseeko64(f, 0, SEEK_SET);
|
||||
if (fgetc(f) != 'P' || fgetc(f) != 'P' || fgetc(f) != 'F')
|
||||
return 0;
|
||||
switch(fgetc(f)){
|
||||
case '1': return 1;
|
||||
case '2': return 2;
|
||||
case '3': return 3;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int ppfFileIdLen(FILE *f, int version)
|
||||
{
|
||||
if (version == 2) {
|
||||
fseeko64(f, -8, SEEK_END);
|
||||
} else {
|
||||
fseeko64(f, -6, SEEK_END);
|
||||
}
|
||||
|
||||
if (fgetc(f) != '.' || fgetc(f) != 'D' || fgetc(f) != 'I' || fgetc(f) != 'Z')
|
||||
return 0;
|
||||
|
||||
return (version == 2) ? readInt4(f) : readInt2(f);
|
||||
}
|
||||
|
||||
static bool patchApplyPPF1(FILE *f, u8 **rom, int *size)
|
||||
{
|
||||
fseek(f, 0, SEEK_END);
|
||||
int count = ftell(f);
|
||||
if (count < 56)
|
||||
return false;
|
||||
count -= 56;
|
||||
|
||||
fseek(f, 56, SEEK_SET);
|
||||
|
||||
u8 *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 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);
|
||||
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, u8 **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;
|
||||
}
|
||||
|
||||
bool applyPatch(const char *patchname, u8 **rom, int *size)
|
||||
{
|
||||
if (strlen(patchname) < 5)
|
||||
return false;
|
||||
const char * p = strrchr(patchname, '.');
|
||||
if (p == NULL)
|
||||
return false;
|
||||
if (_stricmp(p, ".ips") == 0)
|
||||
return patchApplyIPS(patchname, rom, size);
|
||||
if (_stricmp(p, ".ups") == 0)
|
||||
return patchApplyUPS(patchname, rom, size);
|
||||
if (_stricmp(p, ".ppf") == 0)
|
||||
return patchApplyPPF(patchname, rom, size);
|
||||
return false;
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
// -*- C++ -*-
|
||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||
// Copyright (C) 1999-2003 Forgotten
|
||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2, or(at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software Foundation,
|
||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#ifndef VBA_PATCH_H
|
||||
#define VBA_PATCH_H
|
||||
|
||||
#include "System.h"
|
||||
|
||||
bool applyPatch(const char *patchname, u8 **rom, int *size);
|
||||
|
||||
#endif
|
92
src/Util.cpp
92
src/Util.cpp
|
@ -34,6 +34,7 @@ extern "C" {
|
|||
#include "agb/GBA.h"
|
||||
#include "Globals.h"
|
||||
#include "RTC.h"
|
||||
#include "Patch.h"
|
||||
#include "Port.h"
|
||||
|
||||
#include "fex.h"
|
||||
|
@ -330,96 +331,9 @@ bool utilWriteBMPFile(const char *fileName, int w, int h, u8 *pix)
|
|||
return true;
|
||||
}
|
||||
|
||||
static int utilReadInt2(FILE *f)
|
||||
{
|
||||
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 utilReadInt3(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);
|
||||
}
|
||||
|
||||
void utilApplyIPS(const char *ips, u8 **r, int *s)
|
||||
{
|
||||
// from the IPS spec at http://zerosoft.zophar.net/ips.htm
|
||||
FILE *f = fopen(ips, "rb");
|
||||
if(!f)
|
||||
return;
|
||||
u8 *rom = *r;
|
||||
int size = *s;
|
||||
if(fgetc(f) == 'P' &&
|
||||
fgetc(f) == 'A' &&
|
||||
fgetc(f) == 'T' &&
|
||||
fgetc(f) == 'C' &&
|
||||
fgetc(f) == 'H') {
|
||||
int b;
|
||||
int offset;
|
||||
int len;
|
||||
for(;;) {
|
||||
// read offset
|
||||
offset = utilReadInt3(f);
|
||||
// if offset == EOF, end of patch
|
||||
if(offset == 0x454f46)
|
||||
break;
|
||||
// read length
|
||||
len = utilReadInt2(f);
|
||||
if(!len) {
|
||||
// len == 0, RLE block
|
||||
len = utilReadInt2(f);
|
||||
// byte to fill
|
||||
int c = fgetc(f);
|
||||
if(c == -1)
|
||||
break;
|
||||
b = (u8)c;
|
||||
} else
|
||||
b= -1;
|
||||
// check if we need to reallocate our ROM
|
||||
if((offset + len) >= size) {
|
||||
size *= 2;
|
||||
rom = (u8 *)realloc(rom, size);
|
||||
*r = rom;
|
||||
*s = size;
|
||||
}
|
||||
if(b == -1) {
|
||||
// normal block, just read the data
|
||||
if(fread(&rom[offset], 1, len, f) != (size_t)len)
|
||||
break;
|
||||
} else {
|
||||
// fill the region with the given byte
|
||||
while(len--) {
|
||||
rom[offset++] = b;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// close the file
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
//TODO: Modify ZSNES code for this
|
||||
void utilApplyUPS(const char *ips, u8 **r, int *s)
|
||||
void utilApplyIPS(const char *ips, u8 **rom, int *size)
|
||||
{
|
||||
applyPatch(ips, rom, size);
|
||||
}
|
||||
|
||||
extern bool cpuIsMultiBoot;
|
||||
|
|
103
src/sdl/SDL.cpp
103
src/sdl/SDL.cpp
|
@ -40,6 +40,7 @@
|
|||
#include "../agb/GBA.h"
|
||||
#include "../agb/agbprint.h"
|
||||
#include "../Flash.h"
|
||||
#include "../Patch.h"
|
||||
#include "../RTC.h"
|
||||
#include "../Sound.h"
|
||||
#include "../Util.h"
|
||||
|
@ -150,7 +151,6 @@ FilterFunc filterFunction = 0;
|
|||
IFBFilterFunc ifbFunction = 0;
|
||||
IFBFilter ifbType = kIFBNone;
|
||||
char filename[2048];
|
||||
char ipsname[2048];
|
||||
char biosFileName[2048];
|
||||
char gbBiosFileName[2048];
|
||||
char captureDir[2048];
|
||||
|
@ -185,10 +185,10 @@ static int saveSlotPosition = 0; // default is the slot from normal F1
|
|||
static int sdlOpenglScale = 1;
|
||||
// will scale window on init by this much
|
||||
static int sdlSoundToggledOff = 0;
|
||||
// allow up to 100 IPS patches given on commandline
|
||||
#define IPS_MAX_NUM 100
|
||||
int sdl_ips_num = 0;
|
||||
char * (sdl_ips_names[IPS_MAX_NUM]) = { NULL }; // and so on
|
||||
// allow up to 100 IPS/UPS/PPF patches given on commandline
|
||||
#define PATCH_MAX_NUM 100
|
||||
int sdl_patch_num = 0;
|
||||
char * (sdl_patch_names[PATCH_MAX_NUM]) = { NULL }; // and so on
|
||||
|
||||
#define REWIND_NUM 8
|
||||
#define REWIND_SIZE 400000
|
||||
|
@ -214,7 +214,7 @@ bool debugger = false;
|
|||
bool debuggerStub = false;
|
||||
int fullscreen = 0;
|
||||
int sdlFlashSize = 0;
|
||||
int sdlAutoIPS = 1;
|
||||
int sdlAutoPatch = 1;
|
||||
int sdlRtcEnable = 0;
|
||||
int sdlAgbPrint = 0;
|
||||
int sdlMirroringEnable = 0;
|
||||
|
@ -259,11 +259,11 @@ struct option sdlOptions[] = {
|
|||
{ "fullscreen", no_argument, &fullscreen, 1 },
|
||||
{ "gdb", required_argument, 0, 'G' },
|
||||
{ "help", no_argument, &sdlPrintUsage, 1 },
|
||||
{ "ips", required_argument, 0, 'i' },
|
||||
{ "patch", required_argument, 0, 'i' },
|
||||
{ "no-agb-print", no_argument, &sdlAgbPrint, 0 },
|
||||
{ "no-auto-frameskip", no_argument, &autoFrameSkip, 0 },
|
||||
{ "no-debug", no_argument, 0, 'N' },
|
||||
{ "no-ips", no_argument, &sdlAutoIPS, 0 },
|
||||
{ "no-patch", no_argument, &sdlAutoPatch, 0 },
|
||||
{ "no-opengl", no_argument, &openGL, 0 },
|
||||
{ "no-pause-when-inactive", no_argument, &pauseWhenInactive, 0 },
|
||||
{ "no-rtc", no_argument, &sdlRtcEnable, 0 },
|
||||
|
@ -1760,7 +1760,7 @@ Options:\n\
|
|||
printf(" %d - %s\n", i, getFilterName((Filter)i));
|
||||
printf("\
|
||||
-h, --help Print this help\n\
|
||||
-i, --ips=PATCH Apply given IPS patch\n\
|
||||
-i, --patch=PATCH Apply given patch\n\
|
||||
-p, --profile=[HERTZ] Enable profiling\n\
|
||||
-s, --frameskip=FRAMESKIP Set frame skip (0...9)\n\
|
||||
-t, --save-type=TYPE Set the available save type\n\
|
||||
|
@ -1787,7 +1787,7 @@ Long options only:\n\
|
|||
--auto-frameskip Enable auto frameskipping\n\
|
||||
--no-agb-print Disable AGBPrint support\n\
|
||||
--no-auto-frameskip Disable auto frameskipping\n\
|
||||
--no-ips Do not apply IPS patch\n\
|
||||
--no-patch Do not automatically apply patch\n\
|
||||
--no-pause-when-inactive Don't pause when inactive\n\
|
||||
--no-rtc Disable RTC support\n\
|
||||
--no-show-speed Don't show emulation speed\n\
|
||||
|
@ -1796,7 +1796,7 @@ Long options only:\n\
|
|||
--rtc Enable RTC support\n\
|
||||
--show-speed-normal Show emulation speed\n\
|
||||
--show-speed-detailed Show detailed speed data\n\
|
||||
--cheat 'CHEAT' add a cheat\n\
|
||||
--cheat 'CHEAT' Add a cheat\n\
|
||||
");
|
||||
}
|
||||
|
||||
|
@ -1848,7 +1848,6 @@ int main(int argc, char **argv)
|
|||
captureDir[0] = 0;
|
||||
saveDir[0] = 0;
|
||||
batteryDir[0] = 0;
|
||||
ipsname[0] = 0;
|
||||
|
||||
int op = -1;
|
||||
|
||||
|
@ -1933,16 +1932,15 @@ int main(int argc, char **argv)
|
|||
break;
|
||||
case 'i':
|
||||
if(optarg == NULL) {
|
||||
fprintf(stderr, "Missing IPS name\n");
|
||||
fprintf(stderr, "Missing patch name\n");
|
||||
exit(-1);
|
||||
}
|
||||
// strcpy(ipsname, optarg);
|
||||
if (sdl_ips_num >= IPS_MAX_NUM) {
|
||||
fprintf(stderr, "Too many IPS patches given at %s (max is %d). Ignoring.\n", optarg, IPS_MAX_NUM);
|
||||
if (sdl_patch_num >= PATCH_MAX_NUM) {
|
||||
fprintf(stderr, "Too many patches given at %s (max is %d). Ignoring.\n", optarg, PATCH_MAX_NUM);
|
||||
} else {
|
||||
sdl_ips_names[sdl_ips_num] = (char *)malloc(1 + strlen(optarg));
|
||||
strcpy(sdl_ips_names[sdl_ips_num], optarg);
|
||||
sdl_ips_num++;
|
||||
sdl_patch_names[sdl_patch_num] = (char *)malloc(1 + strlen(optarg));
|
||||
strcpy(sdl_patch_names[sdl_patch_num], optarg);
|
||||
sdl_patch_num++;
|
||||
}
|
||||
break;
|
||||
case 'G':
|
||||
|
@ -2110,14 +2108,26 @@ int main(int argc, char **argv)
|
|||
if(p)
|
||||
*p = 0;
|
||||
|
||||
// if(ipsname[0] == 0)
|
||||
// sprintf(ipsname, "%s.ips", filename);
|
||||
if (sdl_ips_num == 0)
|
||||
if (sdlAutoPatch && sdl_patch_num == 0)
|
||||
{
|
||||
char * tmp;
|
||||
// no patch given yet - look for ROMBASENAME.ips
|
||||
sprintf(ipsname, "%s.ips", filename);
|
||||
sdl_ips_names[0] = ipsname;
|
||||
sdl_ips_num++;
|
||||
tmp = (char *)malloc(strlen(filename) + 4 + 1);
|
||||
sprintf(tmp, "%s.ips", filename);
|
||||
sdl_patch_names[sdl_patch_num] = tmp;
|
||||
sdl_patch_num++;
|
||||
|
||||
// no patch given yet - look for ROMBASENAME.ups
|
||||
tmp = (char *)malloc(strlen(filename) + 4 + 1);
|
||||
sprintf(tmp, "%s.ups", filename);
|
||||
sdl_patch_names[sdl_patch_num] = tmp;
|
||||
sdl_patch_num++;
|
||||
|
||||
// no patch given yet - look for ROMBASENAME.ppf
|
||||
tmp = (char *)malloc(strlen(filename) + 4 + 1);
|
||||
sprintf(tmp, "%s.ppf", filename);
|
||||
sdl_patch_names[sdl_patch_num] = tmp;
|
||||
sdl_patch_num++;
|
||||
}
|
||||
|
||||
bool failed = false;
|
||||
|
@ -2139,22 +2149,19 @@ int main(int argc, char **argv)
|
|||
if (gbHardware & 5)
|
||||
gbCPUInit(gbBiosFileName, useBios);
|
||||
|
||||
gbReset();
|
||||
cartridgeType = IMAGE_GB;
|
||||
emulator = GBSystem;
|
||||
if(sdlAutoIPS) {
|
||||
int size = gbRomSize, patchnum;
|
||||
// utilApplyIPS(ipsname, &gbRom, &size);
|
||||
for (patchnum = 0; patchnum < sdl_ips_num; patchnum++) {
|
||||
fprintf(stdout, "Trying IPS patch %s.\n", sdl_ips_names[patchnum]);
|
||||
utilApplyIPS(sdl_ips_names[patchnum], &gbRom, &size);
|
||||
}
|
||||
if(size != gbRomSize) {
|
||||
extern bool gbUpdateSizes();
|
||||
gbUpdateSizes();
|
||||
gbReset();
|
||||
}
|
||||
int size = gbRomSize, patchnum;
|
||||
for (patchnum = 0; patchnum < sdl_patch_num; patchnum++) {
|
||||
fprintf(stdout, "Trying patch %s%s\n", sdl_patch_names[patchnum],
|
||||
applyPatch(sdl_patch_names[patchnum], &gbRom, &size) ? " [success]" : "");
|
||||
}
|
||||
if(size != gbRomSize) {
|
||||
extern bool gbUpdateSizes();
|
||||
gbUpdateSizes();
|
||||
gbReset();
|
||||
}
|
||||
gbReset();
|
||||
}
|
||||
} else if(type == IMAGE_GBA) {
|
||||
int size = CPULoadRom(szFile);
|
||||
|
@ -2168,18 +2175,12 @@ int main(int argc, char **argv)
|
|||
emulator = GBASystem;
|
||||
|
||||
CPUInit(biosFileName, useBios);
|
||||
CPUReset();
|
||||
if(sdlAutoIPS) {
|
||||
int size = 0x2000000, patchnum;
|
||||
// utilApplyIPS(ipsname, &rom, &size);
|
||||
for (patchnum = 0; patchnum < sdl_ips_num; patchnum++) {
|
||||
fprintf(stdout, "Trying IPS patch %s.\n", sdl_ips_names[patchnum]);
|
||||
utilApplyIPS(sdl_ips_names[patchnum], &rom, &size);
|
||||
}
|
||||
if(size != 0x2000000) {
|
||||
CPUReset();
|
||||
}
|
||||
int patchnum;
|
||||
for (patchnum = 0; patchnum < sdl_patch_num; patchnum++) {
|
||||
fprintf(stdout, "Trying patch %s%s\n", sdl_patch_names[patchnum],
|
||||
applyPatch(sdl_patch_names[patchnum], &rom, &size) ? " [success]" : "");
|
||||
}
|
||||
CPUReset();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2361,6 +2362,10 @@ int main(int argc, char **argv)
|
|||
filterPix = NULL;
|
||||
}
|
||||
|
||||
for (int i = 0; i < sdl_patch_num; i++) {
|
||||
free(sdl_patch_names[i]);
|
||||
}
|
||||
|
||||
#if WITH_LIRC
|
||||
StopLirc();
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue