summaryrefslogtreecommitdiff
path: root/libpcsxcore
diff options
context:
space:
mode:
authorSND\weimingzhi_cp <SND\weimingzhi_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97>2010-01-23 08:44:23 +0000
committerSND\weimingzhi_cp <SND\weimingzhi_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97>2010-01-23 08:44:23 +0000
commit912c53cda0997e17d32d0b854823c3334b419db5 (patch)
tree158f8a7ae9c68235fe4e1c14fa1efe5533242dc8 /libpcsxcore
parentcd40452e610e32935cfc5bae96cc77209f79e7d9 (diff)
downloadpcsxr-912c53cda0997e17d32d0b854823c3334b419db5.tar.gz
git-svn-id: https://pcsxr.svn.codeplex.com/svn/pcsxr@40648 e17a0e51-4ae3-4d35-97c3-1a29b211df97
Diffstat (limited to 'libpcsxcore')
-rw-r--r--libpcsxcore/Makefile.am4
-rw-r--r--libpcsxcore/Makefile.in24
-rw-r--r--libpcsxcore/cdriso.c9
-rw-r--r--libpcsxcore/cdriso.h10
-rw-r--r--libpcsxcore/cdrom.c3
-rw-r--r--libpcsxcore/misc.c24
-rw-r--r--libpcsxcore/ppf.c322
-rw-r--r--libpcsxcore/ppf.h27
-rw-r--r--libpcsxcore/psxcommon.h1
-rw-r--r--libpcsxcore/r3000a.c2
10 files changed, 405 insertions, 21 deletions
diff --git a/libpcsxcore/Makefile.am b/libpcsxcore/Makefile.am
index 5704ec5e..81c0a439 100644
--- a/libpcsxcore/Makefile.am
+++ b/libpcsxcore/Makefile.am
@@ -47,7 +47,9 @@ libpcsxcore_a_SOURCES = \
$(top_builddir)/libpcsxcore/cheat.c \
$(top_builddir)/libpcsxcore/cheat.h \
$(top_builddir)/libpcsxcore/socket.c \
- $(top_builddir)/libpcsxcore/socket.h
+ $(top_builddir)/libpcsxcore/socket.h \
+ $(top_builddir)/libpcsxcore/ppf.c \
+ $(top_builddir)/libpcsxcore/ppf.h
if ARCH_X86_64
libpcsxcore_a_SOURCES += \
diff --git a/libpcsxcore/Makefile.in b/libpcsxcore/Makefile.in
index 64f1d0b4..3b0925cf 100644
--- a/libpcsxcore/Makefile.in
+++ b/libpcsxcore/Makefile.in
@@ -113,6 +113,8 @@ am__libpcsxcore_a_SOURCES_DIST = \
$(top_builddir)/libpcsxcore/cheat.h \
$(top_builddir)/libpcsxcore/socket.c \
$(top_builddir)/libpcsxcore/socket.h \
+ $(top_builddir)/libpcsxcore/ppf.c \
+ $(top_builddir)/libpcsxcore/ppf.h \
$(top_builddir)/libpcsxcore/ix86_64/iR3000A-64.c \
$(top_builddir)/libpcsxcore/ix86_64/ix86-64.c \
$(top_builddir)/libpcsxcore/ix86_64/ix86_cpudetect.c \
@@ -142,7 +144,8 @@ am_libpcsxcore_a_OBJECTS = psxbios.$(OBJEXT) cdrom.$(OBJEXT) \
decode_xa.$(OBJEXT) r3000a.$(OBJEXT) psxinterpreter.$(OBJEXT) \
gte.$(OBJEXT) psxhle.$(OBJEXT) debug.$(OBJEXT) \
cdriso.$(OBJEXT) cheat.$(OBJEXT) socket.$(OBJEXT) \
- $(am__objects_1) $(am__objects_2) $(am__objects_3)
+ ppf.$(OBJEXT) $(am__objects_1) $(am__objects_2) \
+ $(am__objects_3)
libpcsxcore_a_OBJECTS = $(am_libpcsxcore_a_OBJECTS)
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include
depcomp = $(SHELL) $(top_srcdir)/depcomp
@@ -360,7 +363,9 @@ libpcsxcore_a_SOURCES = $(top_builddir)/libpcsxcore/psxbios.c \
$(top_builddir)/libpcsxcore/cheat.c \
$(top_builddir)/libpcsxcore/cheat.h \
$(top_builddir)/libpcsxcore/socket.c \
- $(top_builddir)/libpcsxcore/socket.h $(am__append_1) \
+ $(top_builddir)/libpcsxcore/socket.h \
+ $(top_builddir)/libpcsxcore/ppf.c \
+ $(top_builddir)/libpcsxcore/ppf.h $(am__append_1) \
$(am__append_2) $(am__append_3)
@ARCH_PPC_TRUE@libpcsxcore_a_CCASFLAGS = -x assembler-with-cpp -mregnames
all: all-am
@@ -431,6 +436,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pR3000A.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugins.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ppc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ppf.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/psxbios.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/psxcounters.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/psxdma.Po@am__quote@
@@ -759,6 +765,20 @@ socket.obj: $(top_builddir)/libpcsxcore/socket.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o socket.obj `if test -f '$(top_builddir)/libpcsxcore/socket.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/socket.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/socket.c'; fi`
+ppf.o: $(top_builddir)/libpcsxcore/ppf.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ppf.o -MD -MP -MF $(DEPDIR)/ppf.Tpo -c -o ppf.o `test -f '$(top_builddir)/libpcsxcore/ppf.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/ppf.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ppf.Tpo $(DEPDIR)/ppf.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/ppf.c' object='ppf.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ppf.o `test -f '$(top_builddir)/libpcsxcore/ppf.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/ppf.c
+
+ppf.obj: $(top_builddir)/libpcsxcore/ppf.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ppf.obj -MD -MP -MF $(DEPDIR)/ppf.Tpo -c -o ppf.obj `if test -f '$(top_builddir)/libpcsxcore/ppf.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/ppf.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/ppf.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ppf.Tpo $(DEPDIR)/ppf.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/ppf.c' object='ppf.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ppf.obj `if test -f '$(top_builddir)/libpcsxcore/ppf.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/ppf.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/ppf.c'; fi`
+
iR3000A-64.o: $(top_builddir)/libpcsxcore/ix86_64/iR3000A-64.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT iR3000A-64.o -MD -MP -MF $(DEPDIR)/iR3000A-64.Tpo -c -o iR3000A-64.o `test -f '$(top_builddir)/libpcsxcore/ix86_64/iR3000A-64.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/ix86_64/iR3000A-64.c
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/iR3000A-64.Tpo $(DEPDIR)/iR3000A-64.Po
diff --git a/libpcsxcore/cdriso.c b/libpcsxcore/cdriso.c
index 159ba8db..bcb077ac 100644
--- a/libpcsxcore/cdriso.c
+++ b/libpcsxcore/cdriso.c
@@ -21,6 +21,7 @@
#include "psxcommon.h"
#include "plugins.h"
#include "cdrom.h"
+#include "cdriso.h"
#ifdef _WIN32
#include <process.h>
@@ -30,14 +31,6 @@
#include <sys/time.h>
#endif
-#define MSF2SECT(m, s, f) (((m) * 60 + (s) - 2) * 75 + (f))
-#define btoi(b) ((b) / 16 * 10 + (b) % 16) /* BCD to u_char */
-
-#define CD_FRAMESIZE_RAW 2352
-#define DATA_SIZE (CD_FRAMESIZE_RAW - 12)
-
-#define SUB_FRAMESIZE 96
-
FILE *cdHandle = NULL;
FILE *cddaHandle = NULL;
FILE *subHandle = NULL;
diff --git a/libpcsxcore/cdriso.h b/libpcsxcore/cdriso.h
index 473ff99e..896dbf82 100644
--- a/libpcsxcore/cdriso.h
+++ b/libpcsxcore/cdriso.h
@@ -21,6 +21,14 @@
#ifndef CDRISO_H
#define CDRISO_H
-int imageReaderInit(void);
+void imageReaderInit(void);
+
+#define MSF2SECT(m, s, f) (((m) * 60 + (s) - 2) * 75 + (f))
+#define btoi(b) ((b) / 16 * 10 + (b) % 16) /* BCD to u_char */
+
+#define CD_FRAMESIZE_RAW 2352
+#define DATA_SIZE (CD_FRAMESIZE_RAW - 12)
+
+#define SUB_FRAMESIZE 96
#endif
diff --git a/libpcsxcore/cdrom.c b/libpcsxcore/cdrom.c
index 9d2eb62a..63dd89b1 100644
--- a/libpcsxcore/cdrom.c
+++ b/libpcsxcore/cdrom.c
@@ -23,6 +23,7 @@
*/
#include "cdrom.h"
+#include "ppf.h"
/* CD-ROM magic numbers */
#define CdlSync 0
@@ -600,6 +601,8 @@ void cdrReadInterrupt() {
}
memcpy(cdr.Transfer, buf, 2340);
+ CheckPPFCache(cdr.Transfer, cdr.Prev[0], cdr.Prev[1], cdr.Prev[2]);
+
cdr.Stat = DataReady;
#ifdef CDR_LOG
diff --git a/libpcsxcore/misc.c b/libpcsxcore/misc.c
index cdcd6cce..4c0e6cfd 100644
--- a/libpcsxcore/misc.c
+++ b/libpcsxcore/misc.c
@@ -25,6 +25,7 @@
#include "misc.h"
#include "cdrom.h"
#include "mdec.h"
+#include "ppf.h"
int Log = 0;
@@ -95,7 +96,8 @@ void mmssdd( char *b, char *p )
#define READTRACK() \
if (CDR_readTrack(time) == -1) return -1; \
- buf = CDR_getBuffer(); if (buf == NULL) return -1;
+ buf = CDR_getBuffer(); \
+ if (buf == NULL) return -1; else CheckPPFCache(buf, time[0], time[1], time[2]);
#define READDIR(_dir) \
READTRACK(); \
@@ -112,8 +114,8 @@ int GetCdromFile(u8 *mdir, u8 *time, s8 *filename) {
int i;
// only try to scan if a filename is given
- if(!strlen(filename)) return -1;
-
+ if (!strlen(filename)) return -1;
+
i = 0;
while (i < 4096) {
dir = (struct iso_directory_record*) &mdir[i];
@@ -123,19 +125,19 @@ int GetCdromFile(u8 *mdir, u8 *time, s8 *filename) {
i += dir->length[0];
if (dir->flags[0] & 0x2) { // it's a dir
- if (!strnicmp((char*)&dir->name[0], filename, dir->name_len[0])) {
+ if (!strnicmp((char *)&dir->name[0], filename, dir->name_len[0])) {
if (filename[dir->name_len[0]] != '\\') continue;
-
- filename+= dir->name_len[0] + 1;
- mmssdd(dir->extent, (char*)time);
+ filename += dir->name_len[0] + 1;
+
+ mmssdd(dir->extent, (char *)time);
READDIR(ddir);
i = 0;
mdir = ddir;
}
} else {
- if (!strnicmp((char*)&dir->name[0], filename, strlen(filename))) {
- mmssdd(dir->extent, (char*)time);
+ if (!strnicmp((char *)&dir->name[0], filename, strlen(filename))) {
+ mmssdd(dir->extent, (char *)time);
break;
}
}
@@ -274,6 +276,8 @@ int CheckCdrom() {
char exename[256];
int i, c;
+ FreePPFCache();
+
time[0] = itob(0);
time[1] = itob(2);
time[2] = itob(0x10);
@@ -344,6 +348,8 @@ int CheckCdrom() {
SysPrintf("CD-ROM Label: %.32s\n", CdromLabel);
SysPrintf("CD-ROM ID: %.9s\n", CdromId);
+ BuildPPFCache();
+
return 0;
}
diff --git a/libpcsxcore/ppf.c b/libpcsxcore/ppf.c
new file mode 100644
index 00000000..42e41124
--- /dev/null
+++ b/libpcsxcore/ppf.c
@@ -0,0 +1,322 @@
+/* PPF Patch Support for PCSX-Reloaded
+ *
+ * Copyright (c) 2009, Wei Mingzhi <whistler_wmz@users.sf.net>.
+ *
+ * Based on P.E.Op.S CDR Plugin by Pete Bernert.
+ * Copyright (c) 2002, Pete Bernert.
+ *
+ * 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 of the License, 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., 51 Franklin Steet, Fifth Floor, Boston, MA 02111-1307 USA
+ */
+
+#include "psxcommon.h"
+#include "ppf.h"
+#include "cdrom.h"
+#include "cdriso.h"
+
+typedef struct tagPPF_DATA {
+ s32 addr;
+ s32 pos;
+ s32 anz;
+ struct tagPPF_DATA *pNext;
+} PPF_DATA;
+
+typedef struct tagPPF_CACHE {
+ s32 addr;
+ struct tagPPF_DATA *pNext;
+} PPF_CACHE;
+
+static PPF_CACHE *ppfCache = NULL;
+static PPF_DATA *ppfHead = NULL;
+static int iPPFNum = 0;
+
+// using a linked data list, and address array
+static void FillPPFCache() {
+ PPF_DATA *p;
+ PPF_CACHE *pc;
+ s32 lastaddr;
+
+ p = ppfHead;
+ lastaddr = -1;
+ iPPFNum = 0;
+
+ while (p != NULL) {
+ if (p->addr != lastaddr) iPPFNum++;
+ lastaddr = p->addr;
+ p = p->pNext;
+ }
+
+ if (iPPFNum <= 0) return;
+
+ pc = ppfCache = (PPF_CACHE *)malloc(iPPFNum * sizeof(PPF_CACHE));
+
+ iPPFNum--;
+ p = ppfHead;
+ lastaddr = -1;
+
+ while (p != NULL) {
+ if (p->addr != lastaddr) {
+ pc->addr = p->addr;
+ pc->pNext = p;
+ pc++;
+ }
+ lastaddr = p->addr;
+ p = p->pNext;
+ }
+}
+
+void FreePPFCache() {
+ PPF_DATA *p = ppfHead;
+ void *pn;
+
+ while (p != NULL) {
+ pn = p->pNext;
+ free(p);
+ p = (PPF_DATA *)pn;
+ }
+ ppfHead = NULL;
+
+ if (ppfCache != NULL) free(ppfCache);
+ ppfCache = NULL;
+}
+
+void CheckPPFCache(unsigned char *pB, int m, int s, int f) {
+ PPF_CACHE *pcstart, *pcend, *pcpos;
+ int addr = MSF2SECT(btoi(m), btoi(s), btoi(f)), pos, anz, start;
+
+ if (ppfCache == NULL) return;
+
+ pcstart = ppfCache;
+ if (addr < pcstart->addr) return;
+ pcend = ppfCache + iPPFNum;
+ if (addr > pcend->addr) return;
+
+ while (1) {
+ if (addr == pcend->addr) { pcpos = pcend; break; }
+
+ pcpos = pcstart + (pcend - pcstart) / 2;
+ if (pcpos == pcstart) break;
+ if (addr < pcpos->addr) {
+ pcend = pcpos;
+ continue;
+ }
+ if (addr > pcpos->addr) {
+ pcstart = pcpos;
+ continue;
+ }
+ break;
+ }
+
+ if (addr == pcpos->addr) {
+ PPF_DATA *p = pcpos->pNext;
+ while (p != NULL && p->addr == addr) {
+ pos = p->pos - (CD_FRAMESIZE_RAW - DATA_SIZE);
+ anz = p->anz;
+ if (pos < 0) { start = -pos; pos = 0; anz -= start; }
+ else start = 0;
+ memcpy(pB + pos, (unsigned char *)(p + 1) + start, anz);
+ p = p->pNext;
+ }
+ }
+}
+
+static void AddToPPF(s32 ladr, s32 pos, s32 anz, s8 *ppfmem) {
+ if (!ppfHead) {
+ ppfHead = (PPF_DATA *)malloc(sizeof(PPF_DATA) + anz);
+ ppfHead->addr = ladr;
+ ppfHead->pNext = NULL;
+ ppfHead->pos = pos;
+ ppfHead->anz = anz;
+ memcpy(ppfHead + 1, ppfmem, anz);
+ iPPFNum = 1;
+ } else {
+ PPF_DATA *p = ppfHead;
+ PPF_DATA *plast = NULL;
+ PPF_DATA *padd;
+ while (p != NULL) {
+ if (ladr < p->addr) break;
+ if (ladr == p->addr) {
+ while (p && ladr == p->addr && pos > p->pos) {
+ plast = p;
+ p = p->pNext;
+ }
+ break;
+ }
+ plast = p;
+ p = p->pNext;
+ }
+ padd = (PPF_DATA *)malloc(sizeof(PPF_DATA) + anz);
+ padd->addr = ladr;
+ padd->pNext = p;
+ padd->pos = pos;
+ padd->anz = anz;
+ memcpy(padd + 1, ppfmem, anz);
+ iPPFNum++;
+ if (plast == NULL) ppfHead = padd;
+ else plast->pNext = padd;
+ }
+}
+
+void BuildPPFCache() {
+ FILE *ppffile;
+ char buffer[12];
+ char method, undo = 0, blockcheck = 0;
+ int dizlen, dizyn;
+ char ppfmem[512], szPPF[MAXPATHLEN];
+ int count, seekpos, pos;
+ u32 anz; // avoids stupid overflows
+ s32 ladr, off, anx;
+
+ ppfHead = NULL;
+
+ // Generate filename in the format of SLUS_123.45
+ buffer[0] = CdromId[0];
+ buffer[1] = CdromId[1];
+ buffer[2] = CdromId[2];
+ buffer[3] = CdromId[3];
+ buffer[4] = '_';
+ buffer[5] = CdromId[4];
+ buffer[6] = CdromId[5];
+ buffer[7] = CdromId[6];
+ buffer[8] = '.';
+ buffer[9] = CdromId[7];
+ buffer[10] = CdromId[8];
+ buffer[11] = '\0';
+
+ sprintf(szPPF, "%s%s", Config.PatchesDir, buffer);
+
+ ppffile = fopen(szPPF, "rb");
+ if (ppffile == NULL) return;
+
+ memset(buffer, 0, 5);
+ fread(buffer, 3, 1, ppffile);
+
+ if (strcmp(buffer, "PPF") != 0) {
+ SysPrintf(_("Invalid PPF patch: %s.\n"), szPPF);
+ fclose(ppffile);
+ return;
+ }
+
+ fseek(ppffile, 5, SEEK_SET);
+ method = fgetc(ppffile);
+
+ switch (method) {
+ case 0: // ppf1
+ fseek(ppffile, 0, SEEK_END);
+ count = ftell(ppffile);
+ count -= 56;
+ seekpos = 56;
+ break;
+
+ case 1: // ppf2
+ fseek(ppffile, -8, SEEK_END);
+
+ memset(buffer, 0, 5);
+ fread(buffer, 4, 1, ppffile);
+
+ if (strcmp(".DIZ", buffer) != 0) {
+ dizyn = 0;
+ } else {
+ fread(&dizlen, 4, 1, ppffile);
+ dizlen = SWAP32(dizlen);
+ dizyn = 1;
+ }
+
+ fseek(ppffile, 0, SEEK_END);
+ count = ftell(ppffile);
+
+ if (dizyn == 0) {
+ count -= 1084;
+ seekpos = 1084;
+ } else {
+ count -= 1084;
+ count -= 38;
+ count -= dizlen;
+ seekpos = 1084;
+ }
+ break;
+
+ case 2: // ppf3
+ fseek(ppffile, 57, SEEK_SET);
+ blockcheck = fgetc(ppffile);
+ undo = fgetc(ppffile);
+
+ fseek(ppffile, -6, SEEK_END);
+ memset(buffer, 0, 5);
+ fread(buffer, 4, 1, ppffile);
+ dizlen = 0;
+
+ if (strcmp(".DIZ", buffer) == 0) {
+ fseek(ppffile, -2, SEEK_END);
+ fread(&dizlen, 2, 1, ppffile);
+ dizlen = SWAP32(dizlen);
+ dizlen += 36;
+ }
+
+ fseek(ppffile, 0, SEEK_END);
+ count = ftell(ppffile);
+ count -= dizlen;
+
+ if (blockcheck) {
+ seekpos = 1084;
+ count -= 1084;
+ } else {
+ seekpos = 60;
+ count -= 60;
+ }
+ break;
+
+ default:
+ fclose(ppffile);
+ SysPrintf(_("Unsupported PPF version (%d).\n"), method + 1);
+ return;
+ }
+
+ // now do the data reading
+ do {
+ fseek(ppffile, seekpos, SEEK_SET);
+ fread(&pos, 4, 1, ppffile);
+ pos = SWAP32(pos);
+
+ if (method == 2) fread(buffer, 4, 1, ppffile); // skip 4 bytes on ppf3 (no int64 support here)
+
+ anz = fgetc(ppffile);
+ fread(ppfmem, anz, 1, ppffile);
+
+ ladr = pos / CD_FRAMESIZE_RAW;
+ off = pos % CD_FRAMESIZE_RAW;
+
+ if (off + anz > CD_FRAMESIZE_RAW) {
+ anx = off + anz - CD_FRAMESIZE_RAW;
+ anz -= (unsigned char)anx;
+ AddToPPF(ladr + 1, 0, anx, ppfmem + anz);
+ }
+
+ AddToPPF(ladr, off, anz, ppfmem); // add to link list
+
+ if (method == 2) {
+ if (undo) anz += anz;
+ anz += 4;
+ }
+
+ seekpos = seekpos + 5 + anz;
+ count = count - 5 - anz;
+ } while (count != 0); // loop til end
+
+ fclose(ppffile);
+
+ FillPPFCache(); // build address array
+
+ SysPrintf(_("Loaded PPF %d.0 patch: %s.\n"), method + 1, szPPF);
+}
diff --git a/libpcsxcore/ppf.h b/libpcsxcore/ppf.h
new file mode 100644
index 00000000..79ade7d1
--- /dev/null
+++ b/libpcsxcore/ppf.h
@@ -0,0 +1,27 @@
+/* PPF Patch Support for PCSX-Reloaded
+ *
+ * Copyright (c) 2009, Wei Mingzhi <whistler_wmz@users.sf.net>.
+ *
+ * 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 of the License, 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., 51 Franklin Steet, Fifth Floor, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __PPF_H__
+#define __PPF_H__
+
+void BuildPPFCache();
+void FreePPFCache();
+void CheckPPFCache(unsigned char *pB, int m, int s, int f);
+
+#endif
diff --git a/libpcsxcore/psxcommon.h b/libpcsxcore/psxcommon.h
index 4dc3bfa1..b2ea8048 100644
--- a/libpcsxcore/psxcommon.h
+++ b/libpcsxcore/psxcommon.h
@@ -98,6 +98,7 @@ typedef struct {
char Bios[MAXPATHLEN];
char BiosDir[MAXPATHLEN];
char PluginsDir[MAXPATHLEN];
+ char PatchesDir[MAXPATHLEN];
long Xa;
long Sio;
long Mdec;
diff --git a/libpcsxcore/r3000a.c b/libpcsxcore/r3000a.c
index 49e4e7f7..8873336f 100644
--- a/libpcsxcore/r3000a.c
+++ b/libpcsxcore/r3000a.c
@@ -84,6 +84,8 @@ void psxShutdown() {
ClearAllCheats();
FreeCheatSearchResults();
FreeCheatSearchMem();
+
+ FreePPFCache();
}
void psxException(u32 code, u32 bd) {