Made custom FCEU API integration code to fix reentrant ROM crashes
in console ports - goes through Griffin file now
This commit is contained in:
103
src/drivers/libretro/fceu/fceu-endian.c
Normal file
103
src/drivers/libretro/fceu/fceu-endian.c
Normal file
@@ -0,0 +1,103 @@
|
||||
/* FCE Ultra - NES/Famicom Emulator
|
||||
*
|
||||
* Copyright notice for this file:
|
||||
* Copyright (C) 2002 Xodnizel
|
||||
*
|
||||
* 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/* Contains file I/O functions that write/read data */
|
||||
/* LSB first. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "fceu-memory.h"
|
||||
#include "fceu-types.h"
|
||||
#include "fceu-endian.h"
|
||||
|
||||
void FlipByteOrder(uint8 *src, uint32 count)
|
||||
{
|
||||
uint8 *start = src;
|
||||
uint8 *end = src + count - 1;
|
||||
|
||||
if ((count & 1) || !count)
|
||||
return; /* This shouldn't happen. */
|
||||
|
||||
while (count--)
|
||||
{
|
||||
uint8 tmp;
|
||||
|
||||
tmp = *end;
|
||||
*end = *start;
|
||||
*start = tmp;
|
||||
end--;
|
||||
start++;
|
||||
}
|
||||
}
|
||||
|
||||
int write16le(uint16 b, FILE *fp)
|
||||
{
|
||||
uint8 s[2];
|
||||
s[0] = b;
|
||||
s[1] = b >> 8;
|
||||
return((fwrite(s, 1, 2, fp) < 2) ? 0 : 2);
|
||||
}
|
||||
|
||||
int write32le(uint32 b, FILE *fp)
|
||||
{
|
||||
uint8 s[4];
|
||||
s[0] = b;
|
||||
s[1] = b >> 8;
|
||||
s[2] = b >> 16;
|
||||
s[3] = b >> 24;
|
||||
return((fwrite(s, 1, 4, fp) < 4) ? 0 : 4);
|
||||
}
|
||||
|
||||
int read32le(uint32 *Bufo, FILE *fp)
|
||||
{
|
||||
uint32 buf;
|
||||
if (fread(&buf, 1, 4, fp) < 4)
|
||||
return 0;
|
||||
#ifdef LSB_FIRST
|
||||
*(uint32*)Bufo = buf;
|
||||
#else
|
||||
*(uint32*)Bufo = ((buf & 0xFF) << 24) | ((buf & 0xFF00) << 8) | ((buf & 0xFF0000) >> 8) | ((buf & 0xFF000000) >> 24);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
int read16le(char *d, FILE *fp)
|
||||
{
|
||||
#ifdef LSB_FIRST
|
||||
return((fread(d, 1, 2, fp) < 2) ? 0 : 2);
|
||||
#else
|
||||
int ret;
|
||||
ret = fread(d + 1, 1, 1, fp);
|
||||
ret += fread(d, 1, 1, fp);
|
||||
return ret < 2 ? 0 : 2;
|
||||
#endif
|
||||
}
|
||||
|
||||
void FCEU_en32lsb(uint8 *buf, uint32 morp)
|
||||
{
|
||||
buf[0] = morp;
|
||||
buf[1] = morp >> 8;
|
||||
buf[2] = morp >> 16;
|
||||
buf[3] = morp >> 24;
|
||||
}
|
||||
|
||||
uint32 FCEU_de32lsb(uint8 *morp)
|
||||
{
|
||||
return(morp[0] | (morp[1] << 8) | (morp[2] << 16) | (morp[3] << 24));
|
||||
}
|
||||
14
src/drivers/libretro/fceu/fceu-endian.h
Normal file
14
src/drivers/libretro/fceu/fceu-endian.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef _FCEU_ENDIAN_H
|
||||
#define _FCEU_ENDIAN_H
|
||||
|
||||
#include "fceu-memory.h"
|
||||
|
||||
int write16le(uint16 b, FILE *fp);
|
||||
int write32le(uint32 b, FILE *fp);
|
||||
int read32le(uint32 *Bufo, FILE *fp);
|
||||
void FlipByteOrder(uint8 *src, uint32 count);
|
||||
|
||||
void FCEU_en32lsb(uint8 *, uint32);
|
||||
uint32 FCEU_de32lsb(uint8 *);
|
||||
|
||||
#endif
|
||||
63
src/drivers/libretro/fceu/fceu-memory.c
Normal file
63
src/drivers/libretro/fceu/fceu-memory.c
Normal file
@@ -0,0 +1,63 @@
|
||||
/* FCE Ultra - NES/Famicom Emulator
|
||||
*
|
||||
* Copyright notice for this file:
|
||||
* Copyright (C) 2002 Xodnizel
|
||||
*
|
||||
* 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "fceu-types.h"
|
||||
#include "fceu.h"
|
||||
#include "fceu-memory.h"
|
||||
#include "general.h"
|
||||
|
||||
void *FCEU_gmalloc(uint32 size)
|
||||
{
|
||||
void *ret;
|
||||
ret = malloc(size);
|
||||
if (!ret)
|
||||
{
|
||||
FCEU_PrintError("Error allocating memory! Doing a hard exit.");
|
||||
exit(1);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *FCEU_malloc(uint32 size)
|
||||
{
|
||||
int retval = 0;
|
||||
void *ret;
|
||||
ret = (void*)malloc(size);
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
FCEU_PrintError("Error allocating memory!");
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void FCEU_free(void *ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
void FCEU_gfree(void *ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
50
src/drivers/libretro/fceu/fceu-memory.h
Normal file
50
src/drivers/libretro/fceu/fceu-memory.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/* FCE Ultra - NES/Famicom Emulator
|
||||
*
|
||||
* Copyright notice for this file:
|
||||
* Copyright (C) 2002 Xodnizel
|
||||
*
|
||||
* 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/* Various macros for faster memory stuff
|
||||
(at least that's the idea)
|
||||
*/
|
||||
|
||||
#ifndef _FCEU_MEMORY_H_
|
||||
#define _FCEU_MEMORY_H_
|
||||
|
||||
#include "fceu-types.h"
|
||||
#include "../memstream.h"
|
||||
|
||||
#define FCEU_dwmemset(d, c, n) { int _x; for (_x = n - 4; _x >= 0; _x -= 4) *(uint32*)& (d)[_x] = c; }
|
||||
|
||||
#define HAVE_MEMSTREAM
|
||||
#define MEM_TYPE memstream_t
|
||||
|
||||
#define fwrite(ptr, size, nmemb, stream) memstream_write((stream), (ptr), (nmemb))
|
||||
#define fclose(fp) memstream_close((fp))
|
||||
#define fgetc(stream) memstream_getc((stream))
|
||||
#define fputc(c, stream) memstream_putc((stream), (c))
|
||||
#define ftell(a) memstream_pos((a))
|
||||
#define fread(ptr, size, nmemb, stream) memstream_read((stream), (ptr), (nmemb))
|
||||
#define fseek(stream, offset, whence) memstream_seek((stream), (offset), (whence))
|
||||
|
||||
void *FCEU_malloc(uint32 size);
|
||||
void *FCEU_gmalloc(uint32 size);
|
||||
void FCEU_gfree(void *ptr);
|
||||
void FCEU_free(void *ptr);
|
||||
void FASTAPASS(3) FCEU_memmove(void *d, void *s, uint32 l);
|
||||
|
||||
#endif
|
||||
553
src/drivers/libretro/fceu/fceu.c
Normal file
553
src/drivers/libretro/fceu/fceu.c
Normal file
@@ -0,0 +1,553 @@
|
||||
/* FCE Ultra - NES/Famicom Emulator
|
||||
*
|
||||
* Copyright notice for this file:
|
||||
* Copyright (C) 2003 Xodnizel
|
||||
*
|
||||
* 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "fceu-types.h"
|
||||
#include "x6502.h"
|
||||
#include "fceu.h"
|
||||
#include "ppu.h"
|
||||
#include "sound.h"
|
||||
#include "netplay.h"
|
||||
#include "general.h"
|
||||
#include "fceu-endian.h"
|
||||
#include "fceu-memory.h"
|
||||
|
||||
#include "cart.h"
|
||||
#include "nsf.h"
|
||||
#include "fds.h"
|
||||
#include "ines.h"
|
||||
#include "unif.h"
|
||||
#include "cheat.h"
|
||||
#include "palette.h"
|
||||
#include "state.h"
|
||||
#include "video.h"
|
||||
#include "input.h"
|
||||
#include "file.h"
|
||||
#include "crc32.h"
|
||||
#include "vsuni.h"
|
||||
|
||||
uint64 timestampbase;
|
||||
|
||||
|
||||
FCEUGI *GameInfo = NULL;
|
||||
void (*GameInterface)(int h);
|
||||
|
||||
void (*GameStateRestore)(int version);
|
||||
|
||||
readfunc ARead[0x10000];
|
||||
writefunc BWrite[0x10000];
|
||||
static readfunc *AReadG;
|
||||
static writefunc *BWriteG;
|
||||
static int RWWrap = 0;
|
||||
|
||||
static DECLFW(BNull)
|
||||
{
|
||||
}
|
||||
|
||||
static DECLFR(ANull)
|
||||
{
|
||||
return(X.DB);
|
||||
}
|
||||
|
||||
int AllocGenieRW(void)
|
||||
{
|
||||
if (!(AReadG = (readfunc*)FCEU_malloc(0x8000 * sizeof(readfunc))))
|
||||
return 0;
|
||||
if (!(BWriteG = (writefunc*)FCEU_malloc(0x8000 * sizeof(writefunc))))
|
||||
return 0;
|
||||
RWWrap = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void FlushGenieRW(void)
|
||||
{
|
||||
int32 x;
|
||||
|
||||
if (RWWrap)
|
||||
{
|
||||
for (x = 0; x < 0x8000; x++)
|
||||
{
|
||||
ARead[x + 0x8000] = AReadG[x];
|
||||
BWrite[x + 0x8000] = BWriteG[x];
|
||||
}
|
||||
free(AReadG);
|
||||
free(BWriteG);
|
||||
AReadG = 0;
|
||||
BWriteG = 0;
|
||||
}
|
||||
RWWrap = 0;
|
||||
}
|
||||
|
||||
readfunc FASTAPASS(1) GetReadHandler(int32 a)
|
||||
{
|
||||
if (a >= 0x8000 && RWWrap)
|
||||
return AReadG[a - 0x8000];
|
||||
else
|
||||
return ARead[a];
|
||||
}
|
||||
|
||||
void FASTAPASS(3) SetReadHandler(int32 start, int32 end, readfunc func)
|
||||
{
|
||||
int32 x;
|
||||
|
||||
if (!func)
|
||||
func = ANull;
|
||||
|
||||
if (RWWrap)
|
||||
for (x = end; x >= start; x--)
|
||||
{
|
||||
if (x >= 0x8000)
|
||||
AReadG[x - 0x8000] = func;
|
||||
else
|
||||
ARead[x] = func;
|
||||
}
|
||||
else
|
||||
for (x = end; x >= start; x--)
|
||||
ARead[x] = func;
|
||||
}
|
||||
|
||||
writefunc FASTAPASS(1) GetWriteHandler(int32 a)
|
||||
{
|
||||
if (RWWrap && a >= 0x8000)
|
||||
return BWriteG[a - 0x8000];
|
||||
else
|
||||
return BWrite[a];
|
||||
}
|
||||
|
||||
void FASTAPASS(3) SetWriteHandler(int32 start, int32 end, writefunc func)
|
||||
{
|
||||
int32 x;
|
||||
|
||||
if (!func)
|
||||
func = BNull;
|
||||
|
||||
if (RWWrap)
|
||||
for (x = end; x >= start; x--)
|
||||
{
|
||||
if (x >= 0x8000)
|
||||
BWriteG[x - 0x8000] = func;
|
||||
else
|
||||
BWrite[x] = func;
|
||||
}
|
||||
else
|
||||
for (x = end; x >= start; x--)
|
||||
BWrite[x] = func;
|
||||
}
|
||||
|
||||
#ifdef COPYFAMI
|
||||
uint8 RAM[0x4000];
|
||||
#else
|
||||
uint8 RAM[0x800];
|
||||
#endif
|
||||
|
||||
uint8 PAL = 0;
|
||||
|
||||
static DECLFW(BRAML)
|
||||
{
|
||||
RAM[A] = V;
|
||||
}
|
||||
|
||||
static DECLFR(ARAML)
|
||||
{
|
||||
return RAM[A];
|
||||
}
|
||||
|
||||
#ifndef COPYFAMI
|
||||
static DECLFW(BRAMH)
|
||||
{
|
||||
RAM[A & 0x7FF] = V;
|
||||
}
|
||||
|
||||
static DECLFR(ARAMH)
|
||||
{
|
||||
return RAM[A & 0x7FF];
|
||||
}
|
||||
#endif
|
||||
|
||||
void FCEUI_CloseGame(void)
|
||||
{
|
||||
if (!GameInfo)
|
||||
return;
|
||||
|
||||
if (GameInfo->name)
|
||||
free(GameInfo->name);
|
||||
GameInfo->name = 0;
|
||||
if (GameInfo->type != GIT_NSF)
|
||||
FCEU_FlushGameCheats(0, 0);
|
||||
GameInterface(GI_CLOSE);
|
||||
ResetExState(0, 0);
|
||||
FCEU_CloseGenie();
|
||||
free(GameInfo);
|
||||
GameInfo = 0;
|
||||
}
|
||||
|
||||
void ResetGameLoaded(void)
|
||||
{
|
||||
if (GameInfo)
|
||||
FCEUI_CloseGame();
|
||||
|
||||
GameStateRestore = NULL;
|
||||
PPU_hook = NULL;
|
||||
GameHBIRQHook = NULL;
|
||||
|
||||
if (GameExpSound.Kill)
|
||||
GameExpSound.Kill();
|
||||
memset(&GameExpSound, 0, sizeof(GameExpSound));
|
||||
|
||||
MapIRQHook = NULL;
|
||||
MMC5Hack = 0;
|
||||
PEC586Hack = 0;
|
||||
PAL &= 1;
|
||||
pale = 0;
|
||||
}
|
||||
|
||||
int UNIFLoad(const char *name, FCEUFILE *fp);
|
||||
int iNESLoad(const char *name, FCEUFILE *fp);
|
||||
int FDSLoad(const char *name, FCEUFILE *fp);
|
||||
int NSFLoad(FCEUFILE *fp);
|
||||
|
||||
FCEUGI *FCEUI_LoadGame(const char *name)
|
||||
{
|
||||
FCEUFILE *fp;
|
||||
char *ipsfn;
|
||||
|
||||
ResetGameLoaded();
|
||||
|
||||
GameInfo = malloc(sizeof(FCEUGI));
|
||||
memset(GameInfo, 0, sizeof(FCEUGI));
|
||||
|
||||
GameInfo->soundchan = 0;
|
||||
GameInfo->soundrate = 0;
|
||||
GameInfo->name = 0;
|
||||
GameInfo->type = GIT_CART;
|
||||
GameInfo->vidsys = GIV_USER;
|
||||
GameInfo->input[0] = GameInfo->input[1] = -1;
|
||||
GameInfo->inputfc = -1;
|
||||
GameInfo->cspecial = 0;
|
||||
|
||||
FCEU_printf("Loading %s...\n\n", name);
|
||||
|
||||
GetFileBase(name);
|
||||
|
||||
ipsfn = FCEU_MakeFName(FCEUMKF_IPS, 0, 0);
|
||||
fp = FCEU_fopen(name, ipsfn, "rb", 0);
|
||||
free(ipsfn);
|
||||
|
||||
if (!fp) {
|
||||
FCEU_PrintError("Error opening \"%s\"!", name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (iNESLoad(name, fp))
|
||||
goto endlseq;
|
||||
if (NSFLoad(fp))
|
||||
goto endlseq;
|
||||
if (UNIFLoad(name, fp))
|
||||
goto endlseq;
|
||||
if (FDSLoad(name, fp))
|
||||
goto endlseq;
|
||||
|
||||
FCEU_PrintError("An error occurred while loading the file.");
|
||||
FCEU_fclose(fp);
|
||||
return 0;
|
||||
|
||||
endlseq:
|
||||
FCEU_fclose(fp);
|
||||
|
||||
FCEU_ResetVidSys();
|
||||
if (GameInfo->type != GIT_NSF)
|
||||
if (FSettings.GameGenie)
|
||||
FCEU_OpenGenie();
|
||||
|
||||
PowerNES();
|
||||
FCEUSS_CheckStates();
|
||||
|
||||
if (GameInfo->type != GIT_NSF) {
|
||||
FCEU_LoadGamePalette();
|
||||
FCEU_LoadGameCheats(0);
|
||||
}
|
||||
|
||||
FCEU_ResetPalette();
|
||||
FCEU_ResetMessages(); // Save state, status messages, etc.
|
||||
|
||||
return(GameInfo);
|
||||
}
|
||||
|
||||
int CopyFamiLoad(void);
|
||||
|
||||
FCEUGI *FCEUI_CopyFamiStart(void)
|
||||
{
|
||||
ResetGameLoaded();
|
||||
|
||||
GameInfo = (FCEUGI*)malloc(sizeof(FCEUGI));
|
||||
memset(GameInfo, 0, sizeof(FCEUGI));
|
||||
|
||||
GameInfo->soundchan = 0;
|
||||
GameInfo->soundrate = 0;
|
||||
GameInfo->name = "copyfami";
|
||||
GameInfo->type = GIT_CART;
|
||||
GameInfo->vidsys = GIV_USER;
|
||||
GameInfo->input[0] = GameInfo->input[1] = -1;
|
||||
GameInfo->inputfc = -1;
|
||||
GameInfo->cspecial = 0;
|
||||
|
||||
FCEU_printf("Starting CopyFamicom...\n\n");
|
||||
|
||||
if (!CopyFamiLoad()) {
|
||||
FCEU_PrintError("An error occurred while starting CopyFamicom.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
FCEU_ResetVidSys();
|
||||
if (GameInfo->type != GIT_NSF)
|
||||
if (FSettings.GameGenie)
|
||||
FCEU_OpenGenie();
|
||||
|
||||
PowerNES();
|
||||
FCEUSS_CheckStates();
|
||||
|
||||
if (GameInfo->type != GIT_NSF) {
|
||||
FCEU_LoadGamePalette();
|
||||
FCEU_LoadGameCheats(0);
|
||||
}
|
||||
|
||||
FCEU_ResetPalette();
|
||||
FCEU_ResetMessages(); // Save state, status messages, etc.
|
||||
|
||||
return(GameInfo);
|
||||
}
|
||||
|
||||
int FCEUI_Initialize(void) {
|
||||
if (!FCEU_InitVirtualVideo())
|
||||
return 0;
|
||||
memset(&FSettings, 0, sizeof(FSettings));
|
||||
FSettings.UsrFirstSLine[0] = 8;
|
||||
FSettings.UsrFirstSLine[1] = 0;
|
||||
FSettings.UsrLastSLine[0] = 231;
|
||||
FSettings.UsrLastSLine[1] = 239;
|
||||
FSettings.SoundVolume = 100;
|
||||
FCEUPPU_Init();
|
||||
X6502_Init();
|
||||
return 1;
|
||||
}
|
||||
|
||||
void FCEUI_Kill(void) {
|
||||
FCEU_KillVirtualVideo();
|
||||
FCEU_KillGenie();
|
||||
}
|
||||
|
||||
void FCEUI_Emulate(uint8 **pXBuf, int32 **SoundBuf, int32 *SoundBufSize, int skip) {
|
||||
int r, ssize;
|
||||
|
||||
FCEU_UpdateInput();
|
||||
if (geniestage != 1) FCEU_ApplyPeriodicCheats();
|
||||
r = FCEUPPU_Loop(skip);
|
||||
|
||||
ssize = FlushEmulateSound();
|
||||
|
||||
timestampbase += timestamp;
|
||||
|
||||
timestamp = 0;
|
||||
|
||||
*pXBuf = skip ? 0 : XBuf;
|
||||
*SoundBuf = WaveFinal;
|
||||
*SoundBufSize = ssize;
|
||||
}
|
||||
|
||||
|
||||
void ResetNES(void)
|
||||
{
|
||||
if (!GameInfo)
|
||||
return;
|
||||
GameInterface(GI_RESETM2);
|
||||
FCEUSND_Reset();
|
||||
FCEUPPU_Reset();
|
||||
X6502_Reset();
|
||||
}
|
||||
|
||||
void FCEU_MemoryRand(uint8 *ptr, uint32 size)
|
||||
{
|
||||
int x = 0;
|
||||
while (size) {
|
||||
// *ptr = (x & 4) ? 0xFF : 0x00; // Huang Di DEBUG MODE enabled by default
|
||||
// Cybernoid NO MUSIC by default
|
||||
// *ptr = (x & 4) ? 0x7F : 0x00; // Huang Di DEBUG MODE enabled by default
|
||||
// Minna no Taabou no Nakayoshi Daisakusen DOESN'T BOOT
|
||||
// Cybernoid NO MUSIC by default
|
||||
// *ptr = (x & 1) ? 0x55 : 0xAA; // F-15 Sity War HISCORE is screwed...
|
||||
// 1942 SCORE/HISCORE is screwed...
|
||||
*ptr = 0xFF;
|
||||
x++;
|
||||
size--;
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
|
||||
void hand(X6502 *X, int type, uint32 A)
|
||||
{
|
||||
}
|
||||
|
||||
void PowerNES(void)
|
||||
{
|
||||
if (!GameInfo)
|
||||
return;
|
||||
|
||||
FCEU_CheatResetRAM();
|
||||
FCEU_CheatAddRAM(2, 0, RAM);
|
||||
|
||||
FCEU_GeniePower();
|
||||
|
||||
#ifndef COPYFAMI
|
||||
FCEU_MemoryRand(RAM, 0x800);
|
||||
#endif
|
||||
|
||||
SetReadHandler(0x0000, 0xFFFF, ANull);
|
||||
SetWriteHandler(0x0000, 0xFFFF, BNull);
|
||||
|
||||
#ifdef COPYFAMI
|
||||
SetReadHandler(0, 0x3FFF, ARAML);
|
||||
SetWriteHandler(0, 0x3FFF, BRAML);
|
||||
#else
|
||||
SetReadHandler(0, 0x7FF, ARAML);
|
||||
SetWriteHandler(0, 0x7FF, BRAML);
|
||||
|
||||
SetReadHandler(0x800, 0x1FFF, ARAMH); /* Part of a little */
|
||||
SetWriteHandler(0x800, 0x1FFF, BRAMH); /* hack for a small speed boost. */
|
||||
#endif
|
||||
InitializeInput();
|
||||
FCEUSND_Power();
|
||||
FCEUPPU_Power();
|
||||
|
||||
/* Have the external game hardware "powered" after the internal NES stuff.
|
||||
Needed for the NSF code and VS System code.
|
||||
*/
|
||||
GameInterface(GI_POWER);
|
||||
if (GameInfo->type == GIT_VSUNI)
|
||||
FCEU_VSUniPower();
|
||||
|
||||
timestampbase = 0;
|
||||
X6502_Power();
|
||||
FCEU_PowerCheats();
|
||||
}
|
||||
|
||||
void FCEU_ResetVidSys(void)
|
||||
{
|
||||
int w;
|
||||
|
||||
if (GameInfo->vidsys == GIV_NTSC)
|
||||
w = 0;
|
||||
else if (GameInfo->vidsys == GIV_PAL)
|
||||
w = 1;
|
||||
else
|
||||
w = FSettings.PAL;
|
||||
|
||||
PAL = w ? 1 : 0;
|
||||
|
||||
FCEUPPU_SetVideoSystem(w);
|
||||
SetSoundVariables();
|
||||
}
|
||||
|
||||
FCEUS FSettings;
|
||||
|
||||
void FCEU_printf(char *format, ...)
|
||||
{
|
||||
char temp[2048];
|
||||
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, format);
|
||||
vsprintf(temp, format, ap);
|
||||
FCEUD_Message(temp);
|
||||
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void FCEU_PrintError(char *format, ...)
|
||||
{
|
||||
char temp[2048];
|
||||
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, format);
|
||||
vsprintf(temp, format, ap);
|
||||
FCEUD_PrintError(temp);
|
||||
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void FCEUI_SetRenderedLines(int ntscf, int ntscl, int palf, int pall)
|
||||
{
|
||||
FSettings.UsrFirstSLine[0] = ntscf;
|
||||
FSettings.UsrLastSLine[0] = ntscl;
|
||||
FSettings.UsrFirstSLine[1] = palf;
|
||||
FSettings.UsrLastSLine[1] = pall;
|
||||
if (PAL)
|
||||
{
|
||||
FSettings.FirstSLine = FSettings.UsrFirstSLine[1];
|
||||
FSettings.LastSLine = FSettings.UsrLastSLine[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
FSettings.FirstSLine = FSettings.UsrFirstSLine[0];
|
||||
FSettings.LastSLine = FSettings.UsrLastSLine[0];
|
||||
}
|
||||
}
|
||||
|
||||
void FCEUI_SetVidSystem(int a)
|
||||
{
|
||||
FSettings.PAL = a ? 1 : 0;
|
||||
|
||||
if (!GameInfo)
|
||||
return;
|
||||
|
||||
FCEU_ResetVidSys();
|
||||
FCEU_ResetPalette();
|
||||
}
|
||||
|
||||
int FCEUI_GetCurrentVidSystem(int *slstart, int *slend)
|
||||
{
|
||||
if (slstart)
|
||||
*slstart = FSettings.FirstSLine;
|
||||
if (slend)
|
||||
*slend = FSettings.LastSLine;
|
||||
return(PAL);
|
||||
}
|
||||
|
||||
void FCEUI_SetGameGenie(int a)
|
||||
{
|
||||
FSettings.GameGenie = a ? 1 : 0;
|
||||
}
|
||||
|
||||
void FCEUI_SetSnapName(int a)
|
||||
{
|
||||
FSettings.SnapName = a;
|
||||
}
|
||||
|
||||
int32 FCEUI_GetDesiredFPS(void)
|
||||
{
|
||||
if (PAL)
|
||||
return(838977920); // ~50.007
|
||||
else
|
||||
return(1008307711); // ~60.1
|
||||
}
|
||||
161
src/drivers/libretro/fceu/file.c
Normal file
161
src/drivers/libretro/fceu/file.c
Normal file
@@ -0,0 +1,161 @@
|
||||
/* FCE Ultra - NES/Famicom Emulator
|
||||
*
|
||||
* Copyright notice for this file:
|
||||
* Copyright (C) 2002 Xodnizel
|
||||
*
|
||||
* 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifdef _WIN32
|
||||
#include <direct.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "fceu-types.h"
|
||||
#include "file.h"
|
||||
#include "fceu-endian.h"
|
||||
#include "fceu-memory.h"
|
||||
#include "driver.h"
|
||||
#include "general.h"
|
||||
|
||||
typedef struct {
|
||||
uint8 *data;
|
||||
uint32 size;
|
||||
uint32 location;
|
||||
} MEMWRAP;
|
||||
|
||||
void ApplyIPS(FILE *ips, MEMWRAP *dest)
|
||||
{
|
||||
}
|
||||
|
||||
static MEMWRAP *MakeMemWrap(void *tz, int type)
|
||||
{
|
||||
MEMWRAP *tmp;
|
||||
|
||||
if (!(tmp = (MEMWRAP*)FCEU_malloc(sizeof(MEMWRAP))))
|
||||
goto doret;
|
||||
tmp->location = 0;
|
||||
|
||||
fseek((FILE*)tz, 0, SEEK_END);
|
||||
tmp->size = ftell((FILE*)tz);
|
||||
fseek((FILE*)tz, 0, SEEK_SET);
|
||||
if (!(tmp->data = (uint8*)FCEU_malloc(tmp->size)))
|
||||
{
|
||||
free(tmp);
|
||||
tmp = 0;
|
||||
goto doret;
|
||||
}
|
||||
fread(tmp->data, 1, tmp->size, (FILE*)tz);
|
||||
|
||||
doret:
|
||||
if (type == 0)
|
||||
fclose((FILE*)tz);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
#ifndef __GNUC__
|
||||
#define strcasecmp strcmp
|
||||
#endif
|
||||
|
||||
FCEUFILE * FCEU_fopen(const char *path, const char *ipsfn, char *mode, char *ext)
|
||||
{
|
||||
FCEUFILE *fceufp;
|
||||
void *t;
|
||||
|
||||
fceufp = (FCEUFILE*)malloc(sizeof(FCEUFILE));
|
||||
|
||||
if ((t = FCEUD_UTF8fopen(path, mode)))
|
||||
{
|
||||
fseek((FILE*)t, 0, SEEK_SET);
|
||||
fceufp->type = 0;
|
||||
fceufp->fp = t;
|
||||
return fceufp;
|
||||
}
|
||||
|
||||
free(fceufp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FCEU_fclose(FCEUFILE *fp)
|
||||
{
|
||||
fclose((FILE*)fp->fp);
|
||||
free(fp);
|
||||
fp = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint64 FCEU_fread(void *ptr, size_t size, size_t nmemb, FCEUFILE *fp)
|
||||
{
|
||||
return fread(ptr, size, nmemb, (FILE*)fp->fp);
|
||||
}
|
||||
|
||||
uint64 FCEU_fwrite(void *ptr, size_t size, size_t nmemb, FCEUFILE *fp)
|
||||
{
|
||||
return fwrite(ptr, size, nmemb, (FILE*)fp->fp);
|
||||
}
|
||||
|
||||
int FCEU_fseek(FCEUFILE *fp, long offset, int whence)
|
||||
{
|
||||
return fseek((FILE*)fp->fp, offset, whence);
|
||||
}
|
||||
|
||||
uint64 FCEU_ftell(FCEUFILE *fp)
|
||||
{
|
||||
return ftell((FILE*)fp->fp);
|
||||
}
|
||||
|
||||
void FCEU_rewind(FCEUFILE *fp)
|
||||
{
|
||||
fseek(fp->fp, 0, SEEK_SET);
|
||||
}
|
||||
|
||||
int FCEU_read16le(uint16 *val, FCEUFILE *fp)
|
||||
{
|
||||
uint8 t[2];
|
||||
|
||||
if (fread(t, 1, 2, (FILE*)fp->fp) != 2)
|
||||
return(0);
|
||||
*val = t[0] | (t[1] << 8);
|
||||
return(1);
|
||||
}
|
||||
|
||||
int FCEU_read32le(uint32 *Bufo, FCEUFILE *fp)
|
||||
{
|
||||
return read32le(Bufo, (FILE*)fp->fp);
|
||||
}
|
||||
|
||||
int FCEU_fgetc(FCEUFILE *fp)
|
||||
{
|
||||
return fgetc((FILE*)fp->fp);
|
||||
}
|
||||
|
||||
uint64 FCEU_fgetsize(FCEUFILE *fp)
|
||||
{
|
||||
long t, r;
|
||||
t = ftell((FILE*)fp->fp);
|
||||
fseek((FILE*)fp->fp, 0, SEEK_END);
|
||||
r = ftell((FILE*)fp->fp);
|
||||
fseek((FILE*)fp->fp, t, SEEK_SET);
|
||||
return r;
|
||||
}
|
||||
|
||||
int FCEU_fisarchive(FCEUFILE *fp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
162
src/drivers/libretro/fceu/general.c
Normal file
162
src/drivers/libretro/fceu/general.c
Normal file
@@ -0,0 +1,162 @@
|
||||
/* FCE Ultra - NES/Famicom Emulator
|
||||
*
|
||||
* Copyright notice for this file:
|
||||
* Copyright (C) 2002 Xodnizel
|
||||
*
|
||||
* 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#ifdef _WIN32
|
||||
#include <direct.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "fceu-types.h"
|
||||
#include "fceu.h"
|
||||
|
||||
#include "general.h"
|
||||
#include "state.h"
|
||||
|
||||
#include "driver.h"
|
||||
|
||||
#include "md5.h"
|
||||
|
||||
static char BaseDirectory[2048];
|
||||
static char FileBase[2048];
|
||||
static char FileExt[2048]; /* Includes the . character, as in ".nes" */
|
||||
|
||||
static char FileBaseDirectory[2048];
|
||||
|
||||
void FCEUI_SetBaseDirectory(char *dir)
|
||||
{
|
||||
strncpy(BaseDirectory, dir, 2047);
|
||||
BaseDirectory[2047] = 0;
|
||||
}
|
||||
|
||||
static char *odirs[FCEUIOD__COUNT] = { 0, 0, 0, 0, 0, 0 }; // odirs, odors. ^_^
|
||||
|
||||
void FCEUI_SetDirOverride(int which, char *n)
|
||||
{
|
||||
odirs[which] = n;
|
||||
|
||||
/* Rebuild cache of present states/movies. */
|
||||
if (GameInfo)
|
||||
{
|
||||
if (which == FCEUIOD_STATE)
|
||||
FCEUSS_CheckStates();
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef HAVE_ASPRINTF
|
||||
static int asprintf(char **strp, const char *fmt, ...) {
|
||||
va_list ap;
|
||||
int ret;
|
||||
|
||||
va_start(ap, fmt);
|
||||
if (!(*strp = malloc(2048)))
|
||||
return(0);
|
||||
ret = vsnprintf(*strp, 2048, fmt, ap);
|
||||
va_end(ap);
|
||||
return(ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
char *FCEU_MakeFName(int type, int id1, char *cd1)
|
||||
{
|
||||
char *ret = 0;
|
||||
struct stat tmpstat;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case FCEUMKF_GGROM:
|
||||
asprintf(&ret, "%s"PSS "gg.rom", BaseDirectory);
|
||||
break;
|
||||
case FCEUMKF_FDSROM:
|
||||
asprintf(&ret, "%s"PSS "disksys.rom", BaseDirectory);
|
||||
break;
|
||||
case FCEUMKF_PALETTE:
|
||||
if (odirs[FCEUIOD_MISC])
|
||||
asprintf(&ret, "%s"PSS "%s.pal", odirs[FCEUIOD_MISC], FileBase);
|
||||
else
|
||||
asprintf(&ret, "%s"PSS "gameinfo"PSS "%s.pal", BaseDirectory, FileBase);
|
||||
break;
|
||||
default:
|
||||
ret = malloc(1);
|
||||
*ret = '\0';
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
|
||||
void GetFileBase(const char *f)
|
||||
{
|
||||
const char *tp1, *tp3;
|
||||
|
||||
#if PSS_STYLE == 4
|
||||
tp1 = ((char*)strrchr(f, ':'));
|
||||
#elif PSS_STYLE == 1
|
||||
tp1 = ((char*)strrchr(f, '/'));
|
||||
#else
|
||||
tp1 = ((char*)strrchr(f, '\\'));
|
||||
#if PSS_STYLE != 3
|
||||
tp3 = ((char*)strrchr(f, '/'));
|
||||
if (tp1 < tp3) tp1 = tp3;
|
||||
#endif
|
||||
#endif
|
||||
if (!tp1)
|
||||
{
|
||||
tp1 = f;
|
||||
strcpy(FileBaseDirectory, ".");
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(FileBaseDirectory, f, tp1 - f);
|
||||
FileBaseDirectory[tp1 - f] = 0;
|
||||
tp1++;
|
||||
}
|
||||
|
||||
if (((tp3 = strrchr(f, '.')) != NULL) && (tp3 > tp1))
|
||||
{
|
||||
memcpy(FileBase, tp1, tp3 - tp1);
|
||||
FileBase[tp3 - tp1] = 0;
|
||||
strcpy(FileExt, tp3);
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(FileBase, tp1);
|
||||
FileExt[0] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 uppow2(uint32 n)
|
||||
{
|
||||
int x;
|
||||
|
||||
for (x = 31; x >= 0; x--)
|
||||
if (n & (1 << x))
|
||||
{
|
||||
if ((1 << x) != n)
|
||||
return(1 << (x + 1));
|
||||
break;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
378
src/drivers/libretro/fceu/input.c
Normal file
378
src/drivers/libretro/fceu/input.c
Normal file
@@ -0,0 +1,378 @@
|
||||
/* FCE Ultra - NES/Famicom Emulator
|
||||
*
|
||||
* Copyright notice for this file:
|
||||
* Copyright (C) 1998 BERO
|
||||
* Copyright (C) 2002 Xodnizel
|
||||
*
|
||||
* 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#include <string.h>
|
||||
|
||||
#include "fceu-types.h"
|
||||
#include "x6502.h"
|
||||
|
||||
#include "fceu.h"
|
||||
|
||||
#include "input.h"
|
||||
#include "vsuni.h"
|
||||
#include "fds.h"
|
||||
|
||||
extern INPUTC *FCEU_InitJoyPad(int w);
|
||||
extern INPUTC *FCEU_InitZapper(int w);
|
||||
extern INPUTC *FCEU_InitMouse(int w);
|
||||
extern INPUTC *FCEU_InitPowerpadA(int w);
|
||||
extern INPUTC *FCEU_InitPowerpadB(int w);
|
||||
extern INPUTC *FCEU_InitArkanoid(int w);
|
||||
|
||||
extern INPUTCFC *FCEU_InitFami4(void);
|
||||
extern INPUTCFC *FCEU_InitArkanoidFC(void);
|
||||
extern INPUTCFC *FCEU_InitSpaceShadow(void);
|
||||
extern INPUTCFC *FCEU_InitFKB(void);
|
||||
extern INPUTCFC *FCEU_InitSuborKB(void);
|
||||
extern INPUTCFC *FCEU_InitPEC586KB(void);
|
||||
extern INPUTCFC *FCEU_InitHS(void);
|
||||
extern INPUTCFC *FCEU_InitMahjong(void);
|
||||
extern INPUTCFC *FCEU_InitQuizKing(void);
|
||||
extern INPUTCFC *FCEU_InitFamilyTrainerA(void);
|
||||
extern INPUTCFC *FCEU_InitFamilyTrainerB(void);
|
||||
extern INPUTCFC *FCEU_InitOekaKids(void);
|
||||
extern INPUTCFC *FCEU_InitTopRider(void);
|
||||
extern INPUTCFC *FCEU_InitBarcodeWorld(void);
|
||||
|
||||
extern uint8 coinon;
|
||||
|
||||
static void *InputDataPtr[2];
|
||||
uint8 LastStrobe;
|
||||
|
||||
static int JPAttrib[2] = { 0, 0 };
|
||||
static int JPType[2] = { 0, 0 };
|
||||
static INPUTC DummyJPort = { 0, 0, 0, 0, 0 };
|
||||
static INPUTC *JPorts[2] = { &DummyJPort, &DummyJPort };
|
||||
|
||||
static int JPAttribFC = 0;
|
||||
static int JPTypeFC = 0;
|
||||
static void *InputDataPtrFC;
|
||||
static INPUTCFC *FCExp = 0;
|
||||
|
||||
void (*InputScanlineHook)(uint8 *bg, uint8 *spr, uint32 linets, int final);
|
||||
|
||||
static DECLFR(JPRead)
|
||||
{
|
||||
uint8 ret = 0;
|
||||
|
||||
if (JPorts[A & 1]->Read)
|
||||
ret |= JPorts[A & 1]->Read(A & 1);
|
||||
|
||||
if (FCExp)
|
||||
if (FCExp->Read)
|
||||
ret = FCExp->Read(A & 1, ret);
|
||||
|
||||
ret |= X.DB & 0xC0;
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
static DECLFW(B4016)
|
||||
{
|
||||
if (FCExp)
|
||||
if (FCExp->Write)
|
||||
FCExp->Write(V & 7);
|
||||
|
||||
if (JPorts[0]->Write)
|
||||
JPorts[0]->Write(V & 1);
|
||||
if (JPorts[1]->Write)
|
||||
JPorts[1]->Write(V & 1);
|
||||
|
||||
if ((LastStrobe & 1) && (!(V & 1)))
|
||||
{
|
||||
if (JPorts[0]->Strobe)
|
||||
JPorts[0]->Strobe(0);
|
||||
if (JPorts[1]->Strobe)
|
||||
JPorts[1]->Strobe(1);
|
||||
if (FCExp)
|
||||
if (FCExp->Strobe)
|
||||
FCExp->Strobe();
|
||||
}
|
||||
LastStrobe = V & 0x1;
|
||||
}
|
||||
|
||||
void FCEU_DrawInput(uint8 *buf)
|
||||
{
|
||||
int x;
|
||||
for (x = 0; x < 2; x++)
|
||||
if (JPorts[x]->Draw)
|
||||
JPorts[x]->Draw(x, buf, JPAttrib[x]);
|
||||
if (FCExp)
|
||||
if (FCExp->Draw)
|
||||
FCExp->Draw(buf, JPAttribFC);
|
||||
}
|
||||
|
||||
void FCEU_UpdateInput(void)
|
||||
{
|
||||
int x;
|
||||
|
||||
for (x = 0; x < 2; x++)
|
||||
{
|
||||
if (JPorts[x] && JPorts[x]->Update)
|
||||
JPorts[x]->Update(x, InputDataPtr[x], JPAttrib[x]);
|
||||
}
|
||||
|
||||
if (FCExp && FCExp->Update)
|
||||
FCExp->Update(InputDataPtrFC, JPAttribFC);
|
||||
|
||||
if (GameInfo && GameInfo->type == GIT_VSUNI)
|
||||
if (coinon) coinon--;
|
||||
}
|
||||
|
||||
static DECLFR(VSUNIRead0)
|
||||
{
|
||||
uint8 ret = 0;
|
||||
|
||||
if (JPorts[0]->Read)
|
||||
ret |= (JPorts[0]->Read(0)) & 1;
|
||||
|
||||
ret |= (vsdip & 3) << 3;
|
||||
if (coinon)
|
||||
ret |= 0x4;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static DECLFR(VSUNIRead1)
|
||||
{
|
||||
uint8 ret = 0;
|
||||
|
||||
if (JPorts[1] && JPorts[1]->Read)
|
||||
ret |= (JPorts[1]->Read(1)) & 1;
|
||||
ret |= vsdip & 0xFC;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void SLHLHook(uint8 *bg, uint8 *spr, uint32 linets, int final)
|
||||
{
|
||||
int x;
|
||||
|
||||
for (x = 0; x < 2; x++)
|
||||
if (JPorts[x] && JPorts[x]->SLHook)
|
||||
JPorts[x]->SLHook(x, bg, spr, linets, final);
|
||||
|
||||
if (FCExp && FCExp->SLHook)
|
||||
FCExp->SLHook(bg, spr, linets, final);
|
||||
}
|
||||
|
||||
static void CheckSLHook(void)
|
||||
{
|
||||
InputScanlineHook = 0;
|
||||
|
||||
if (JPorts[0] && JPorts[0]->SLHook || JPorts[1] && JPorts[1]->SLHook)
|
||||
InputScanlineHook = SLHLHook;
|
||||
|
||||
if (FCExp && FCExp->SLHook)
|
||||
InputScanlineHook = SLHLHook;
|
||||
}
|
||||
|
||||
static void FASTAPASS(1) SetInputStuff(int x)
|
||||
{
|
||||
switch (JPType[x])
|
||||
{
|
||||
case SI_NONE:
|
||||
JPorts[x] = &DummyJPort;
|
||||
break;
|
||||
case SI_GAMEPAD:
|
||||
JPorts[x] = FCEU_InitJoyPad(x);
|
||||
break;
|
||||
case SI_ARKANOID:
|
||||
JPorts[x] = FCEU_InitArkanoid(x);
|
||||
break;
|
||||
case SI_MOUSE:
|
||||
JPorts[x] = FCEU_InitMouse(x);
|
||||
break;
|
||||
case SI_ZAPPER:
|
||||
JPorts[x] = FCEU_InitZapper(x);
|
||||
break;
|
||||
case SI_POWERPADA:
|
||||
JPorts[x] = FCEU_InitPowerpadA(x);
|
||||
break;
|
||||
case SI_POWERPADB:
|
||||
JPorts[x] = FCEU_InitPowerpadB(x);
|
||||
break;
|
||||
}
|
||||
CheckSLHook();
|
||||
}
|
||||
|
||||
static void SetInputStuffFC(void)
|
||||
{
|
||||
switch (JPTypeFC)
|
||||
{
|
||||
case SIFC_NONE:
|
||||
FCExp = 0;
|
||||
break;
|
||||
case SIFC_ARKANOID:
|
||||
FCExp = FCEU_InitArkanoidFC();
|
||||
break;
|
||||
case SIFC_SHADOW:
|
||||
FCExp = FCEU_InitSpaceShadow();
|
||||
break;
|
||||
case SIFC_OEKAKIDS:
|
||||
FCExp = FCEU_InitOekaKids();
|
||||
break;
|
||||
case SIFC_4PLAYER:
|
||||
FCExp = FCEU_InitFami4();
|
||||
break;
|
||||
case SIFC_FKB:
|
||||
FCExp = FCEU_InitFKB();
|
||||
break;
|
||||
case SIFC_SUBORKB:
|
||||
FCExp = FCEU_InitSuborKB();
|
||||
break;
|
||||
case SIFC_PEC586KB:
|
||||
FCExp = FCEU_InitPEC586KB();
|
||||
break;
|
||||
case SIFC_HYPERSHOT:
|
||||
FCExp = FCEU_InitHS();
|
||||
break;
|
||||
case SIFC_MAHJONG:
|
||||
FCExp = FCEU_InitMahjong();
|
||||
break;
|
||||
case SIFC_QUIZKING:
|
||||
FCExp = FCEU_InitQuizKing();
|
||||
break;
|
||||
case SIFC_FTRAINERA:
|
||||
FCExp = FCEU_InitFamilyTrainerA();
|
||||
break;
|
||||
case SIFC_FTRAINERB:
|
||||
FCExp = FCEU_InitFamilyTrainerB();
|
||||
break;
|
||||
case SIFC_BWORLD:
|
||||
FCExp = FCEU_InitBarcodeWorld();
|
||||
break;
|
||||
case SIFC_TOPRIDER:
|
||||
FCExp = FCEU_InitTopRider();
|
||||
break;
|
||||
}
|
||||
CheckSLHook();
|
||||
}
|
||||
|
||||
void InitializeInput(void)
|
||||
{
|
||||
LastStrobe = 0;
|
||||
|
||||
if (GameInfo && GameInfo->type == GIT_VSUNI)
|
||||
{
|
||||
SetReadHandler(0x4016, 0x4016, VSUNIRead0);
|
||||
SetReadHandler(0x4017, 0x4017, VSUNIRead1);
|
||||
}
|
||||
else
|
||||
SetReadHandler(0x4016, 0x4017, JPRead);
|
||||
|
||||
SetWriteHandler(0x4016, 0x4016, B4016);
|
||||
|
||||
SetInputStuff(0);
|
||||
SetInputStuff(1);
|
||||
SetInputStuffFC();
|
||||
}
|
||||
|
||||
void FCEUI_SetInput(int port, int type, void *ptr, int attrib)
|
||||
{
|
||||
JPAttrib[port] = attrib;
|
||||
JPType[port] = type;
|
||||
InputDataPtr[port] = ptr;
|
||||
SetInputStuff(port);
|
||||
}
|
||||
|
||||
void FCEUI_SetInputFC(int type, void *ptr, int attrib)
|
||||
{
|
||||
JPAttribFC = attrib;
|
||||
JPTypeFC = type;
|
||||
InputDataPtrFC = ptr;
|
||||
SetInputStuffFC();
|
||||
}
|
||||
|
||||
void FCEU_DoSimpleCommand(int cmd)
|
||||
{
|
||||
switch (cmd)
|
||||
{
|
||||
case FCEUNPCMD_FDSINSERT:
|
||||
FCEU_FDSInsert(-1);
|
||||
break;
|
||||
case FCEUNPCMD_FDSSELECT:
|
||||
FCEU_FDSSelect();
|
||||
break;
|
||||
case FCEUNPCMD_FDSEJECT:
|
||||
FCEU_FDSEject();
|
||||
break;
|
||||
case FCEUNPCMD_VSUNICOIN:
|
||||
FCEU_VSUniCoin();
|
||||
break;
|
||||
case FCEUNPCMD_VSUNIDIP0:
|
||||
case (FCEUNPCMD_VSUNIDIP0 + 1):
|
||||
case (FCEUNPCMD_VSUNIDIP0 + 2):
|
||||
case (FCEUNPCMD_VSUNIDIP0 + 3):
|
||||
case (FCEUNPCMD_VSUNIDIP0 + 4):
|
||||
case (FCEUNPCMD_VSUNIDIP0 + 5):
|
||||
case (FCEUNPCMD_VSUNIDIP0 + 6):
|
||||
case (FCEUNPCMD_VSUNIDIP0 + 7):
|
||||
FCEU_VSUniToggleDIP(cmd - FCEUNPCMD_VSUNIDIP0);
|
||||
break;
|
||||
case FCEUNPCMD_POWER:
|
||||
PowerNES();
|
||||
break;
|
||||
case FCEUNPCMD_RESET:
|
||||
ResetNES();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void FCEU_QSimpleCommand(int cmd)
|
||||
{
|
||||
FCEU_DoSimpleCommand(cmd);
|
||||
}
|
||||
|
||||
void FCEUI_FDSSelect(void)
|
||||
{
|
||||
FCEU_QSimpleCommand(FCEUNPCMD_FDSSELECT);
|
||||
}
|
||||
|
||||
int FCEUI_FDSInsert(int oride)
|
||||
{
|
||||
FCEU_QSimpleCommand(FCEUNPCMD_FDSINSERT);
|
||||
return(1);
|
||||
}
|
||||
|
||||
int FCEUI_FDSEject(void)
|
||||
{
|
||||
FCEU_QSimpleCommand(FCEUNPCMD_FDSEJECT);
|
||||
return(1);
|
||||
}
|
||||
|
||||
void FCEUI_VSUniToggleDIP(int w)
|
||||
{
|
||||
FCEU_QSimpleCommand(FCEUNPCMD_VSUNIDIP0 + w);
|
||||
}
|
||||
|
||||
void FCEUI_VSUniCoin(void)
|
||||
{
|
||||
FCEU_QSimpleCommand(FCEUNPCMD_VSUNICOIN);
|
||||
}
|
||||
|
||||
void FCEUI_ResetNES(void)
|
||||
{
|
||||
FCEU_QSimpleCommand(FCEUNPCMD_RESET);
|
||||
}
|
||||
|
||||
void FCEUI_PowerNES(void)
|
||||
{
|
||||
FCEU_QSimpleCommand(FCEUNPCMD_POWER);
|
||||
}
|
||||
|
||||
20
src/drivers/libretro/fceu/misc.c
Normal file
20
src/drivers/libretro/fceu/misc.c
Normal file
@@ -0,0 +1,20 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "fceu-types.h"
|
||||
#include "fceu.h"
|
||||
|
||||
#include "driver.h"
|
||||
|
||||
/* wave.c */
|
||||
|
||||
void FCEU_WriteWaveData(int32 *Buffer, int Count) { }
|
||||
int FCEUI_EndWaveRecord(void) { return 0; }
|
||||
int FCEUI_BeginWaveRecord(char *fn) { return 0; }
|
||||
|
||||
/* netplay.c */
|
||||
int FCEUNET_SendFile(uint8 cmd, char *fn) { return 0; }
|
||||
|
||||
/* movie.c */
|
||||
void FCEUMOV_AddJoy(uint8 *js) { }
|
||||
void FCEUMOV_Stop(void) {}
|
||||
void FCEUI_SelectMovie(int w) { }
|
||||
409
src/drivers/libretro/fceu/state.c
Normal file
409
src/drivers/libretro/fceu/state.c
Normal file
@@ -0,0 +1,409 @@
|
||||
/* FCE Ultra - NES/Famicom Emulator
|
||||
*
|
||||
* Copyright notice for this file:
|
||||
* Copyright (C) 2002 Xodnizel
|
||||
*
|
||||
* 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifdef _WIN32
|
||||
#include <direct.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "fceu-types.h"
|
||||
#include "x6502.h"
|
||||
#include "fceu.h"
|
||||
#include "sound.h"
|
||||
#include "fceu-endian.h"
|
||||
#include "fds.h"
|
||||
#include "general.h"
|
||||
#include "state.h"
|
||||
#include "movie.h"
|
||||
#include "fceu-memory.h"
|
||||
#include "ppu.h"
|
||||
#include "netplay.h"
|
||||
#include "video.h"
|
||||
|
||||
static void (*SPreSave)(void);
|
||||
static void (*SPostSave)(void);
|
||||
|
||||
static int SaveStateStatus[10];
|
||||
|
||||
static SFORMAT SFMDATA[64];
|
||||
static int SFEXINDEX;
|
||||
|
||||
#define RLSB FCEUSTATE_RLSB //0x80000000
|
||||
|
||||
extern SFORMAT FCEUPPU_STATEINFO[];
|
||||
extern SFORMAT FCEUSND_STATEINFO[];
|
||||
extern SFORMAT FCEUCTRL_STATEINFO[];
|
||||
|
||||
|
||||
SFORMAT SFCPU[] = {
|
||||
{ &X.PC, 2 | RLSB, "PC\0" },
|
||||
{ &X.A, 1, "A\0\0" },
|
||||
{ &X.X, 1, "X\0\0" },
|
||||
{ &X.Y, 1, "Y\0\0" },
|
||||
{ &X.S, 1, "S\0\0" },
|
||||
{ &X.P, 1, "P\0\0" },
|
||||
{ &X.DB, 1, "DB"},
|
||||
#ifdef COPYFAMI
|
||||
{ RAM, 0x4000, "RAM" },
|
||||
#else
|
||||
{ RAM, 0x800, "RAM" },
|
||||
#endif
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
SFORMAT SFCPUC[] = {
|
||||
{ &X.jammed, 1, "JAMM" },
|
||||
{ &X.IRQlow, 4 | RLSB, "IQLB" },
|
||||
{ &X.tcount, 4 | RLSB, "ICoa" },
|
||||
{ &X.count, 4 | RLSB, "ICou" },
|
||||
{ ×tampbase, sizeof(timestampbase) | RLSB, "TSBS" },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static int SubWrite(MEM_TYPE *st, SFORMAT *sf) {
|
||||
uint32 acc = 0;
|
||||
|
||||
while (sf->v) {
|
||||
if (sf->s == ~0) { // Link to another struct.
|
||||
uint32 tmp;
|
||||
|
||||
if (!(tmp = SubWrite(st, (SFORMAT*)sf->v)))
|
||||
return(0);
|
||||
acc += tmp;
|
||||
sf++;
|
||||
continue;
|
||||
}
|
||||
|
||||
acc += 8; // Description + size
|
||||
acc += sf->s & (~RLSB);
|
||||
|
||||
if (st) { // Are we writing or calculating the size of this block? */
|
||||
fwrite(sf->desc, 1, 4, st);
|
||||
write32le(sf->s & (~RLSB), st);
|
||||
|
||||
#ifndef LSB_FIRST
|
||||
if (sf->s & RLSB)
|
||||
FlipByteOrder(sf->v, sf->s & (~RLSB));
|
||||
#endif
|
||||
|
||||
fwrite((uint8*)sf->v, 1, sf->s & (~RLSB), st);
|
||||
/* Now restore the original byte order. */
|
||||
#ifndef LSB_FIRST
|
||||
if (sf->s & RLSB)
|
||||
FlipByteOrder(sf->v, sf->s & (~RLSB));
|
||||
#endif
|
||||
}
|
||||
sf++;
|
||||
}
|
||||
|
||||
return(acc);
|
||||
}
|
||||
|
||||
static int WriteStateChunk(MEM_TYPE *st, int type, SFORMAT *sf)
|
||||
{
|
||||
int bsize;
|
||||
|
||||
fputc(type, st);
|
||||
|
||||
bsize = SubWrite(0, sf);
|
||||
write32le(bsize, st);
|
||||
|
||||
if (!SubWrite(st, sf))
|
||||
return(0);
|
||||
return(bsize + 5);
|
||||
}
|
||||
|
||||
static SFORMAT *CheckS(SFORMAT *sf, uint32 tsize, char *desc)
|
||||
{
|
||||
while (sf->v)
|
||||
{
|
||||
if (sf->s == ~0)
|
||||
{ /* Link to another SFORMAT structure. */
|
||||
SFORMAT *tmp;
|
||||
if ((tmp = CheckS((SFORMAT*)sf->v, tsize, desc)))
|
||||
return(tmp);
|
||||
sf++;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(desc, sf->desc, 4))
|
||||
{
|
||||
if (tsize != (sf->s & (~RLSB)))
|
||||
return(0);
|
||||
return(sf);
|
||||
}
|
||||
sf++;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int ReadStateChunk(MEM_TYPE *st, SFORMAT *sf, int size)
|
||||
{
|
||||
SFORMAT *tmp;
|
||||
int temp;
|
||||
temp = ftell(st);
|
||||
|
||||
while (ftell(st) < temp + size)
|
||||
{
|
||||
uint32 tsize;
|
||||
char toa[4];
|
||||
if (fread(toa, 1, 4, st) <= 0)
|
||||
return 0;
|
||||
|
||||
read32le(&tsize, st);
|
||||
|
||||
if ((tmp = CheckS(sf, tsize, toa))) {
|
||||
fread((uint8*)tmp->v, 1, tmp->s & (~RLSB), st);
|
||||
|
||||
#ifndef LSB_FIRST
|
||||
if (tmp->s & RLSB)
|
||||
FlipByteOrder(tmp->v, tmp->s & (~RLSB));
|
||||
#endif
|
||||
}
|
||||
else
|
||||
fseek(st, tsize, SEEK_CUR);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ReadStateChunks(MEM_TYPE *st, int32 totalsize)
|
||||
{
|
||||
int t;
|
||||
uint32 size;
|
||||
int ret = 1;
|
||||
|
||||
while (totalsize > 0)
|
||||
{
|
||||
t = fgetc(st);
|
||||
if (t == EOF)
|
||||
break;
|
||||
if (!read32le(&size, st))
|
||||
break;
|
||||
totalsize -= size + 5;
|
||||
|
||||
switch (t)
|
||||
{
|
||||
case 1:
|
||||
if (!ReadStateChunk(st, SFCPU, size))
|
||||
ret = 0;
|
||||
break;
|
||||
case 2:
|
||||
if (!ReadStateChunk(st, SFCPUC, size))
|
||||
ret = 0;
|
||||
else
|
||||
X.mooPI = X.P; // Quick and dirty hack.
|
||||
break;
|
||||
case 3:
|
||||
if (!ReadStateChunk(st, FCEUPPU_STATEINFO, size))
|
||||
ret = 0;
|
||||
break;
|
||||
case 4:
|
||||
if (!ReadStateChunk(st, FCEUCTRL_STATEINFO, size))
|
||||
ret = 0;
|
||||
break;
|
||||
case 5:
|
||||
if (!ReadStateChunk(st, FCEUSND_STATEINFO, size))
|
||||
ret = 0;
|
||||
break;
|
||||
case 0x10:
|
||||
if (!ReadStateChunk(st, SFMDATA, size))
|
||||
ret = 0;
|
||||
break;
|
||||
default:
|
||||
if (fseek(st, size, SEEK_CUR) < 0)
|
||||
goto endo;
|
||||
break;
|
||||
}
|
||||
}
|
||||
endo:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int CurrentState = 0;
|
||||
extern int geniestage;
|
||||
|
||||
int FCEUSS_SaveFP(MEM_TYPE *st)
|
||||
{
|
||||
static uint32 totalsize;
|
||||
uint8 header[16] = { 0 };
|
||||
|
||||
header[0] = 'F';
|
||||
header[1] = 'C';
|
||||
header[2] = 'S';
|
||||
header[3] = 0xFF;
|
||||
|
||||
header[3] = 0xFF;
|
||||
FCEU_en32lsb(header + 8, FCEU_VERSION_NUMERIC);
|
||||
fwrite(header, 1, 16, st);
|
||||
FCEUPPU_SaveState();
|
||||
FCEUSND_SaveState();
|
||||
totalsize = WriteStateChunk(st, 1, SFCPU);
|
||||
totalsize += WriteStateChunk(st, 2, SFCPUC);
|
||||
totalsize += WriteStateChunk(st, 3, FCEUPPU_STATEINFO);
|
||||
totalsize += WriteStateChunk(st, 4, FCEUCTRL_STATEINFO);
|
||||
totalsize += WriteStateChunk(st, 5, FCEUSND_STATEINFO);
|
||||
if (SPreSave)
|
||||
SPreSave();
|
||||
totalsize += WriteStateChunk(st, 0x10, SFMDATA);
|
||||
if (SPreSave)
|
||||
SPostSave();
|
||||
|
||||
fseek(st, 4, SEEK_SET);
|
||||
write32le(totalsize, st);
|
||||
return(1);
|
||||
}
|
||||
|
||||
void FCEUSS_Save(char *fname)
|
||||
{
|
||||
MEM_TYPE *st = NULL;
|
||||
char *fn;
|
||||
|
||||
if (geniestage == 1)
|
||||
{
|
||||
FCEU_DispMessage("Cannot save FCS in GG screen.");
|
||||
return;
|
||||
}
|
||||
|
||||
st = (MEM_TYPE*)memstream_open(1);
|
||||
|
||||
FCEUSS_SaveFP(st);
|
||||
|
||||
SaveStateStatus[CurrentState] = 1;
|
||||
fclose(st);
|
||||
}
|
||||
|
||||
int FCEUSS_LoadFP(MEM_TYPE *st)
|
||||
{
|
||||
int x;
|
||||
uint8 header[16];
|
||||
int stateversion;
|
||||
|
||||
fread(&header, 1, 16, st);
|
||||
if (memcmp(header, "FCS", 3))
|
||||
return(0);
|
||||
|
||||
if (header[3] == 0xFF)
|
||||
stateversion = FCEU_de32lsb(header + 8);
|
||||
else
|
||||
stateversion = header[3] * 100;
|
||||
|
||||
x = ReadStateChunks(st, *(uint32*)(header + 4));
|
||||
if (stateversion < 9500)
|
||||
X.IRQlow = 0;
|
||||
|
||||
if (GameStateRestore)
|
||||
GameStateRestore(stateversion);
|
||||
if (x)
|
||||
{
|
||||
FCEUPPU_LoadState(stateversion);
|
||||
FCEUSND_LoadState(stateversion);
|
||||
}
|
||||
return(x);
|
||||
}
|
||||
|
||||
int FCEUSS_Load(char *fname)
|
||||
{
|
||||
MEM_TYPE *st;
|
||||
char *fn;
|
||||
|
||||
st = (MEM_TYPE*)memstream_open(0);
|
||||
|
||||
if (FCEUSS_LoadFP(st))
|
||||
{
|
||||
SaveStateStatus[CurrentState] = 1;
|
||||
fclose(st);
|
||||
return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
SaveStateStatus[CurrentState] = 1;
|
||||
fclose(st);
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
void FCEUSS_CheckStates(void)
|
||||
{
|
||||
MEM_TYPE *st = NULL;
|
||||
char *fn;
|
||||
int ssel;
|
||||
|
||||
for (ssel = 0; ssel < 10; ssel++)
|
||||
{
|
||||
st = FCEUD_UTF8fopen(fn = FCEU_MakeFName(FCEUMKF_STATE, ssel, 0), "rb");
|
||||
free(fn);
|
||||
if (st)
|
||||
{
|
||||
SaveStateStatus[ssel] = 1;
|
||||
fclose(st);
|
||||
}
|
||||
else
|
||||
SaveStateStatus[ssel] = 0;
|
||||
}
|
||||
|
||||
CurrentState = 0;
|
||||
}
|
||||
|
||||
void ResetExState(void (*PreSave)(void), void (*PostSave)(void))
|
||||
{
|
||||
SPreSave = PreSave;
|
||||
SPostSave = PostSave;
|
||||
SFEXINDEX = 0;
|
||||
}
|
||||
|
||||
void AddExState(void *v, uint32 s, int type, char *desc)
|
||||
{
|
||||
memset(SFMDATA[SFEXINDEX].desc, 0, sizeof(SFMDATA[SFEXINDEX].desc));
|
||||
if (desc)
|
||||
strncpy(SFMDATA[SFEXINDEX].desc, desc, sizeof(SFMDATA[SFEXINDEX].desc));
|
||||
SFMDATA[SFEXINDEX].v = v;
|
||||
SFMDATA[SFEXINDEX].s = s;
|
||||
if (type) SFMDATA[SFEXINDEX].s |= RLSB;
|
||||
if (SFEXINDEX < 63) SFEXINDEX++;
|
||||
SFMDATA[SFEXINDEX].v = 0; // End marker.
|
||||
}
|
||||
|
||||
void FCEUI_SelectState(int w)
|
||||
{
|
||||
if (w == -1)
|
||||
return;
|
||||
|
||||
CurrentState = w;
|
||||
FCEU_DispMessage("-select state-");
|
||||
}
|
||||
|
||||
void FCEUI_SaveState(char *fname)
|
||||
{
|
||||
FCEUSS_Save(fname);
|
||||
}
|
||||
|
||||
void FCEUI_LoadState(char *fname)
|
||||
{
|
||||
FCEUSS_Load(fname);
|
||||
}
|
||||
|
||||
void FCEU_DrawSaveStates(uint8 *XBuf)
|
||||
{
|
||||
}
|
||||
|
||||
109
src/drivers/libretro/fceu/video.c
Normal file
109
src/drivers/libretro/fceu/video.c
Normal file
@@ -0,0 +1,109 @@
|
||||
/* FCE Ultra - NES/Famicom Emulator
|
||||
*
|
||||
* Copyright notice for this file:
|
||||
* Copyright (C) 2002 Xodnizel
|
||||
*
|
||||
* 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "fceu-types.h"
|
||||
#include "video.h"
|
||||
#include "fceu.h"
|
||||
#include "general.h"
|
||||
#include "fceu-memory.h"
|
||||
#include "crc32.h"
|
||||
#include "state.h"
|
||||
#include "palette.h"
|
||||
#include "nsf.h"
|
||||
#include "input.h"
|
||||
#include "vsuni.h"
|
||||
|
||||
uint8 *XBuf = NULL;
|
||||
|
||||
void FCEU_KillVirtualVideo(void)
|
||||
{
|
||||
if (XBuf)
|
||||
free(XBuf);
|
||||
XBuf = 0;
|
||||
}
|
||||
|
||||
int FCEU_InitVirtualVideo(void)
|
||||
{
|
||||
// 256 bytes per scanline, * 240 scanline maximum, +8 for alignment,
|
||||
if (!XBuf)
|
||||
XBuf = (uint8*)(FCEU_malloc(256 * 256 + 8));
|
||||
|
||||
if (!XBuf)
|
||||
return 0;
|
||||
|
||||
if (sizeof(uint8*) == 4)
|
||||
{
|
||||
uint32 m;
|
||||
m = *XBuf;
|
||||
m = (4 - m) & 3;
|
||||
XBuf += m;
|
||||
}
|
||||
memset(XBuf, 128, 256 * 256);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int howlong;
|
||||
static char errmsg[65];
|
||||
|
||||
#include "drawing.h"
|
||||
|
||||
void FCEUI_SaveSnapshot(void) { }
|
||||
|
||||
void FCEU_PutImage(void)
|
||||
{
|
||||
if (GameInfo->type == GIT_NSF)
|
||||
DrawNSF(XBuf);
|
||||
else
|
||||
{
|
||||
if (GameInfo->type == GIT_VSUNI)
|
||||
FCEU_VSUniDraw(XBuf);
|
||||
}
|
||||
if (howlong) howlong--;
|
||||
}
|
||||
|
||||
void FCEU_PutImageDummy(void)
|
||||
{
|
||||
}
|
||||
|
||||
void FCEU_DispMessage(char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, format);
|
||||
vsprintf(errmsg, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
howlong = 180;
|
||||
}
|
||||
|
||||
void FCEU_ResetMessages(void)
|
||||
{
|
||||
howlong = 180;
|
||||
}
|
||||
|
||||
int SaveSnapshot(void)
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
Reference in New Issue
Block a user