#include "../libpcsxcore/psxcounters.h"
#include "../libpcsxcore/psxmem_map.h"
#include "../libpcsxcore/new_dynarec/new_dynarec.h"
+#include "../libpcsxcore/cheat.h"
#include "../plugins/dfsound/out.h"
#include "../plugins/gpulib/cspace.h"
#include "main.h"
static void *vout_buf;
static int vout_width, vout_height;
static int vout_doffs_old, vout_fb_dirty;
+static bool vout_can_dupe;
static int samples_sent, samples_to_send;
static int plugins_opened;
info->geometry.aspect_ratio = 4.0 / 3.0;
}
-/* TODO */
+/* savestates */
size_t retro_serialize_size(void)
{
- return 0;
+ // it's currently 4380651 bytes, but have some reserved for future
+ return 0x430000;
+}
+
+struct save_fp {
+ char *buf;
+ size_t pos;
+ int is_write;
+};
+
+static void *save_open(const char *name, const char *mode)
+{
+ struct save_fp *fp;
+
+ if (name == NULL || mode == NULL)
+ return NULL;
+
+ fp = malloc(sizeof(*fp));
+ if (fp == NULL)
+ return NULL;
+
+ fp->buf = (char *)name;
+ fp->pos = 0;
+ fp->is_write = (mode[0] == 'w' || mode[1] == 'w');
+
+ return fp;
+}
+
+static int save_read(void *file, void *buf, u32 len)
+{
+ struct save_fp *fp = file;
+ if (fp == NULL || buf == NULL)
+ return -1;
+
+ memcpy(buf, fp->buf + fp->pos, len);
+ fp->pos += len;
+ return len;
+}
+
+static int save_write(void *file, const void *buf, u32 len)
+{
+ struct save_fp *fp = file;
+ if (fp == NULL || buf == NULL)
+ return -1;
+
+ memcpy(fp->buf + fp->pos, buf, len);
+ fp->pos += len;
+ return len;
+}
+
+static long save_seek(void *file, long offs, int whence)
+{
+ struct save_fp *fp = file;
+ if (fp == NULL)
+ return -1;
+
+ switch (whence) {
+ case SEEK_CUR:
+ fp->pos += offs;
+ return fp->pos;
+ case SEEK_SET:
+ fp->pos = offs;
+ return fp->pos;
+ default:
+ return -1;
+ }
+}
+
+static void save_close(void *file)
+{
+ struct save_fp *fp = file;
+ size_t r_size = retro_serialize_size();
+ if (fp == NULL)
+ return;
+
+ if (fp->pos > r_size)
+ SysPrintf("ERROR: save buffer overflow detected\n");
+ else if (fp->is_write && fp->pos < r_size)
+ // make sure we don't save trash in leftover space
+ memset(fp->buf + fp->pos, 0, r_size - fp->pos);
+ free(fp);
}
bool retro_serialize(void *data, size_t size)
{
- return false;
+ int ret = SaveState(data);
+ return ret == 0 ? true : false;
}
bool retro_unserialize(const void *data, size_t size)
{
- return false;
+ int ret = LoadState(data);
+ return ret == 0 ? true : false;
}
void retro_cheat_reset(void)
{
+ ClearAllCheats();
}
void retro_cheat_set(unsigned index, bool enabled, const char *code)
{
+ char buf[256];
+ int ret;
+
+ // cheat funcs are destructive, need a copy..
+ strncpy(buf, code, sizeof(buf));
+ buf[sizeof(buf) - 1] = 0;
+
+ if (index < NumCheats)
+ ret = EditCheat(index, "", buf);
+ else
+ ret = AddCheat("", buf);
+
+ if (ret != 0)
+ SysPrintf("Failed to set cheat %#u\n", index);
+ else if (index < NumCheats)
+ Cheats[index].Enabled = enabled;
}
bool retro_load_game(const struct retro_game_info *info)
samples_to_send += 44100 / 60;
- video_cb(vout_fb_dirty ? vout_buf : NULL, vout_width, vout_height, vout_width * 2);
+ video_cb((vout_fb_dirty || !vout_can_dupe) ? vout_buf : NULL,
+ vout_width, vout_height, vout_width * 2);
vout_fb_dirty = 0;
}
level = 1;
environ_cb(RETRO_ENVIRONMENT_SET_PERFORMANCE_LEVEL, &level);
+ environ_cb(RETRO_ENVIRONMENT_GET_CAN_DUPE, &vout_can_dupe);
+
/* Set how much slower PSX CPU runs * 100 (so that 200 is 2 times)
* we have to do this because cache misses and some IO penalties
* are not emulated. Warning: changing this may break compatibility. */
McdDisable[0] = 0;
McdDisable[1] = 1;
init_memcard(Mcd1Data);
+
+ SaveFuncs.open = save_open;
+ SaveFuncs.read = save_read;
+ SaveFuncs.write = save_write;
+ SaveFuncs.seek = save_seek;
+ SaveFuncs.close = save_close;
}
void retro_deinit(void)
cdr.AttenuatorRight[1] = 0x00;
}
-int cdrFreeze(gzFile f, int Mode) {
+int cdrFreeze(void *f, int Mode) {
u32 tmp;
if( Mode == 0 ) {
void cdrWrite1(unsigned char rt);
void cdrWrite2(unsigned char rt);
void cdrWrite3(unsigned char rt);
-int cdrFreeze(gzFile f, int Mode);
+int cdrFreeze(void *f, int Mode);
#ifdef __cplusplus
}
}
}
-int mdecFreeze(gzFile f, int Mode) {
+int mdecFreeze(void *f, int Mode) {
u8 *base = (u8 *)&psxM[0x100000];
u32 v;
void psxDma1(u32 madr, u32 bcr, u32 chcr);
void mdec0Interrupt();
void mdec1Interrupt();
-int mdecFreeze(gzFile f, int Mode);
+int mdecFreeze(void *f, int Mode);
#ifdef __cplusplus
}
#include "mdec.h"
#include "gpu.h"
#include "ppf.h"
+#include <zlib.h>
char CdromId[10] = "";
char CdromLabel[33] = "";
// STATES
+static void *zlib_open(const char *name, const char *mode)
+{
+ return gzopen(name, mode);
+}
+
+static int zlib_read(void *file, void *buf, u32 len)
+{
+ return gzread(file, buf, len);
+}
+
+static int zlib_write(void *file, const void *buf, u32 len)
+{
+ return gzwrite(file, buf, len);
+}
+
+static long zlib_seek(void *file, long offs, int whence)
+{
+ return gzseek(file, offs, whence);
+}
+
+static void zlib_close(void *file)
+{
+ gzclose(file);
+}
+
+struct PcsxSaveFuncs SaveFuncs = {
+ zlib_open, zlib_read, zlib_write, zlib_seek, zlib_close
+};
+
static const char PcsxHeader[32] = "STv4 PCSX v" PACKAGE_VERSION;
// Savestate Versioning!
static const u32 SaveVersion = 0x8b410006;
int SaveState(const char *file) {
- gzFile f;
+ void *f;
GPUFreeze_t *gpufP;
SPUFreeze_t *spufP;
int Size;
unsigned char *pMem;
- f = gzopen(file, "wb");
+ f = SaveFuncs.open(file, "wb");
if (f == NULL) return -1;
new_dyna_save();
- gzwrite(f, (void *)PcsxHeader, 32);
- gzwrite(f, (void *)&SaveVersion, sizeof(u32));
- gzwrite(f, (void *)&Config.HLE, sizeof(boolean));
+ SaveFuncs.write(f, (void *)PcsxHeader, 32);
+ SaveFuncs.write(f, (void *)&SaveVersion, sizeof(u32));
+ SaveFuncs.write(f, (void *)&Config.HLE, sizeof(boolean));
pMem = (unsigned char *)malloc(128 * 96 * 3);
if (pMem == NULL) return -1;
GPU_getScreenPic(pMem);
- gzwrite(f, pMem, 128 * 96 * 3);
+ SaveFuncs.write(f, pMem, 128 * 96 * 3);
free(pMem);
if (Config.HLE)
psxBiosFreeze(1);
- gzwrite(f, psxM, 0x00200000);
- gzwrite(f, psxR, 0x00080000);
- gzwrite(f, psxH, 0x00010000);
- gzwrite(f, (void *)&psxRegs, sizeof(psxRegs));
+ SaveFuncs.write(f, psxM, 0x00200000);
+ SaveFuncs.write(f, psxR, 0x00080000);
+ SaveFuncs.write(f, psxH, 0x00010000);
+ SaveFuncs.write(f, (void *)&psxRegs, sizeof(psxRegs));
// gpu
gpufP = (GPUFreeze_t *)malloc(sizeof(GPUFreeze_t));
gpufP->ulFreezeVersion = 1;
GPU_freeze(1, gpufP);
- gzwrite(f, gpufP, sizeof(GPUFreeze_t));
+ SaveFuncs.write(f, gpufP, sizeof(GPUFreeze_t));
free(gpufP);
// spu
spufP = (SPUFreeze_t *) malloc(16);
SPU_freeze(2, spufP);
- Size = spufP->Size; gzwrite(f, &Size, 4);
+ Size = spufP->Size; SaveFuncs.write(f, &Size, 4);
free(spufP);
spufP = (SPUFreeze_t *) malloc(Size);
SPU_freeze(1, spufP);
- gzwrite(f, spufP, Size);
+ SaveFuncs.write(f, spufP, Size);
free(spufP);
sioFreeze(f, 1);
psxRcntFreeze(f, 1);
mdecFreeze(f, 1);
- gzclose(f);
+ SaveFuncs.close(f);
new_dyna_after_save();
}
int LoadState(const char *file) {
- gzFile f;
+ void *f;
GPUFreeze_t *gpufP;
SPUFreeze_t *spufP;
int Size;
u32 version;
boolean hle;
- f = gzopen(file, "rb");
+ f = SaveFuncs.open(file, "rb");
if (f == NULL) return -1;
- gzread(f, header, sizeof(header));
- gzread(f, &version, sizeof(u32));
- gzread(f, &hle, sizeof(boolean));
+ SaveFuncs.read(f, header, sizeof(header));
+ SaveFuncs.read(f, &version, sizeof(u32));
+ SaveFuncs.read(f, &hle, sizeof(boolean));
if (strncmp("STv4 PCSX", header, 9) != 0 || version != SaveVersion) {
- gzclose(f);
+ SaveFuncs.close(f);
return -1;
}
Config.HLE = hle;
psxBiosInit();
psxCpu->Reset();
- gzseek(f, 128 * 96 * 3, SEEK_CUR);
+ SaveFuncs.seek(f, 128 * 96 * 3, SEEK_CUR);
- gzread(f, psxM, 0x00200000);
- gzread(f, psxR, 0x00080000);
- gzread(f, psxH, 0x00010000);
- gzread(f, (void *)&psxRegs, sizeof(psxRegs));
+ SaveFuncs.read(f, psxM, 0x00200000);
+ SaveFuncs.read(f, psxR, 0x00080000);
+ SaveFuncs.read(f, psxH, 0x00010000);
+ SaveFuncs.read(f, (void *)&psxRegs, sizeof(psxRegs));
if (Config.HLE)
psxBiosFreeze(0);
// gpu
gpufP = (GPUFreeze_t *)malloc(sizeof(GPUFreeze_t));
- gzread(f, gpufP, sizeof(GPUFreeze_t));
+ SaveFuncs.read(f, gpufP, sizeof(GPUFreeze_t));
GPU_freeze(0, gpufP);
free(gpufP);
if (HW_GPU_STATUS == 0)
HW_GPU_STATUS = GPU_readStatus();
// spu
- gzread(f, &Size, 4);
+ SaveFuncs.read(f, &Size, 4);
spufP = (SPUFreeze_t *)malloc(Size);
- gzread(f, spufP, Size);
+ SaveFuncs.read(f, spufP, Size);
SPU_freeze(0, spufP);
free(spufP);
psxRcntFreeze(f, 0);
mdecFreeze(f, 0);
- gzclose(f);
+ SaveFuncs.close(f);
new_dyna_restore();
return 0;
}
int CheckState(const char *file) {
- gzFile f;
+ void *f;
char header[32];
u32 version;
boolean hle;
- f = gzopen(file, "rb");
+ f = SaveFuncs.open(file, "rb");
if (f == NULL) return -1;
- gzread(f, header, sizeof(header));
- gzread(f, &version, sizeof(u32));
- gzread(f, &hle, sizeof(boolean));
+ SaveFuncs.read(f, header, sizeof(header));
+ SaveFuncs.read(f, &version, sizeof(u32));
+ SaveFuncs.read(f, &hle, sizeof(boolean));
- gzclose(f);
+ SaveFuncs.close(f);
if (strncmp("STv4 PCSX", header, 9) != 0 || version != SaveVersion)
return -1;
#include "psxbios.h"
#include "psxhw.h"
#include "gpu.h"
+#include <zlib.h>
#undef SysPrintf
#define SysPrintf if (Config.PsxOut) printf
#include <ctype.h>
#include <sys/types.h>
#include <assert.h>
-#include <zlib.h>
// Define types
typedef int8_t s8;
extern PcsxConfig Config;
extern boolean NetOpened;
+struct PcsxSaveFuncs {
+ void *(*open)(const char *name, const char *mode);
+ int (*read)(void *file, void *buf, u32 len);
+ int (*write)(void *file, const void *buf, u32 len);
+ long (*seek)(void *file, long offs, int whence);
+ void (*close)(void *file);
+};
+extern struct PcsxSaveFuncs SaveFuncs;
+
#define gzfreeze(ptr, size) { \
- if (Mode == 1) gzwrite(f, ptr, size); \
- if (Mode == 0) gzread(f, ptr, size); \
+ if (Mode == 1) SaveFuncs.write(f, ptr, size); \
+ if (Mode == 0) SaveFuncs.read(f, ptr, size); \
}
// Make the timing events trigger faster as we are currently assuming everything
/******************************************************************************/
-s32 psxRcntFreeze( gzFile f, s32 Mode )
+s32 psxRcntFreeze( void *f, s32 Mode )
{
u32 count;
s32 i;
u32 psxRcntRmode(u32 index);
u32 psxRcntRtarget(u32 index);
-s32 psxRcntFreeze(gzFile f, s32 Mode);
+s32 psxRcntFreeze(void *f, s32 Mode);
#ifdef __cplusplus
}
#endif
}
-int psxHwFreeze(gzFile f, int Mode) {
+int psxHwFreeze(void *f, int Mode) {
return 0;
}
void psxHwWrite8(u32 add, u8 value);
void psxHwWrite16(u32 add, u16 value);
void psxHwWrite32(u32 add, u32 value);
-int psxHwFreeze(gzFile f, int Mode);
+int psxHwFreeze(void *f, int Mode);
#ifdef __cplusplus
}
strncpy(Info->Name, ptr, 16);
}
-int sioFreeze(gzFile f, int Mode) {
+int sioFreeze(void *f, int Mode) {
gzfreeze(buf, sizeof(buf));
gzfreeze(&StatReg, sizeof(StatReg));
gzfreeze(&ModeReg, sizeof(ModeReg));
void netError();
void sioInterrupt();
-int sioFreeze(gzFile f, int Mode);
+int sioFreeze(void *f, int Mode);
void LoadMcd(int mcd, char *str);
void LoadMcds(char *mcd1, char *mcd2);
SRC_STANDALONE += gpu.c
SRC_GPULIB += gpulib_if.c
-ifeq "$(ARCH)" "arm"
+#ifeq "$(ARCH)" "arm"
SRC_STANDALONE += draw_pl.c
-else
-SRC_STANDALONE += draw.c
-LDLIBS_STANDALONE += -lX11 -lXv -lXext
-endif
+#else
+#SRC_STANDALONE += draw.c
+#LDLIBS_STANDALONE += -lX11 -lXv -lXext
+#endif
BIN_STANDLALONE = gpuPEOPS.so
BIN_GPULIB = gpu_peops.so