Start merging files
This commit is contained in:
@@ -1,550 +0,0 @@
|
|||||||
/* 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, uint8_t *databuf, size_t databufsize)
|
|
||||||
{
|
|
||||||
FCEUFILE *fp;
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
fp = FCEU_fopen(name, NULL, "rb", 0, databuf, databufsize);
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
#include "drivers/libretro/fceu/fceu-endian.c"
|
#include "drivers/libretro/fceu/fceu-endian.c"
|
||||||
#include "drivers/libretro/fceu/fceu-memory.c"
|
#include "drivers/libretro/fceu/fceu-memory.c"
|
||||||
#include "drivers/libretro/fceu/misc.c"
|
#include "drivers/libretro/fceu/misc.c"
|
||||||
#include "drivers/libretro/fceu/fceu.c"
|
#include "fceu.c"
|
||||||
//#include "fceustr.c"
|
//#include "fceustr.c"
|
||||||
#include "drivers/libretro/fceu/fds.c"
|
#include "drivers/libretro/fceu/fds.c"
|
||||||
#include "drivers/libretro/fceu/file.c"
|
#include "drivers/libretro/fceu/file.c"
|
||||||
|
|||||||
295
src/fceu.c
295
src/fceu.c
@@ -41,7 +41,6 @@
|
|||||||
#include "cheat.h"
|
#include "cheat.h"
|
||||||
#include "palette.h"
|
#include "palette.h"
|
||||||
#include "state.h"
|
#include "state.h"
|
||||||
#include "movie.h"
|
|
||||||
#include "video.h"
|
#include "video.h"
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
@@ -62,14 +61,17 @@ static readfunc *AReadG;
|
|||||||
static writefunc *BWriteG;
|
static writefunc *BWriteG;
|
||||||
static int RWWrap = 0;
|
static int RWWrap = 0;
|
||||||
|
|
||||||
static DECLFW(BNull) {
|
static DECLFW(BNull)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static DECLFR(ANull) {
|
static DECLFR(ANull)
|
||||||
|
{
|
||||||
return(X.DB);
|
return(X.DB);
|
||||||
}
|
}
|
||||||
|
|
||||||
int AllocGenieRW(void) {
|
int AllocGenieRW(void)
|
||||||
|
{
|
||||||
if (!(AReadG = (readfunc*)FCEU_malloc(0x8000 * sizeof(readfunc))))
|
if (!(AReadG = (readfunc*)FCEU_malloc(0x8000 * sizeof(readfunc))))
|
||||||
return 0;
|
return 0;
|
||||||
if (!(BWriteG = (writefunc*)FCEU_malloc(0x8000 * sizeof(writefunc))))
|
if (!(BWriteG = (writefunc*)FCEU_malloc(0x8000 * sizeof(writefunc))))
|
||||||
@@ -78,62 +80,71 @@ int AllocGenieRW(void) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlushGenieRW(void) {
|
void FlushGenieRW(void)
|
||||||
int32 x;
|
{
|
||||||
|
int32 x;
|
||||||
|
|
||||||
if (RWWrap) {
|
if (RWWrap)
|
||||||
for (x = 0; x < 0x8000; x++) {
|
{
|
||||||
ARead[x + 0x8000] = AReadG[x];
|
for (x = 0; x < 0x8000; x++)
|
||||||
BWrite[x + 0x8000] = BWriteG[x];
|
{
|
||||||
}
|
ARead[x + 0x8000] = AReadG[x];
|
||||||
free(AReadG);
|
BWrite[x + 0x8000] = BWriteG[x];
|
||||||
free(BWriteG);
|
}
|
||||||
AReadG = 0;
|
free(AReadG);
|
||||||
BWriteG = 0;
|
free(BWriteG);
|
||||||
RWWrap = 0;
|
AReadG = 0;
|
||||||
}
|
BWriteG = 0;
|
||||||
|
}
|
||||||
|
RWWrap = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
readfunc FASTAPASS(1) GetReadHandler(int32 a) {
|
readfunc FASTAPASS(1) GetReadHandler(int32 a)
|
||||||
|
{
|
||||||
if (a >= 0x8000 && RWWrap)
|
if (a >= 0x8000 && RWWrap)
|
||||||
return AReadG[a - 0x8000];
|
return AReadG[a - 0x8000];
|
||||||
else
|
else
|
||||||
return ARead[a];
|
return ARead[a];
|
||||||
}
|
}
|
||||||
|
|
||||||
void FASTAPASS(3) SetReadHandler(int32 start, int32 end, readfunc func) {
|
void FASTAPASS(3) SetReadHandler(int32 start, int32 end, readfunc func)
|
||||||
|
{
|
||||||
int32 x;
|
int32 x;
|
||||||
|
|
||||||
if (!func)
|
if (!func)
|
||||||
func = ANull;
|
func = ANull;
|
||||||
|
|
||||||
if (RWWrap)
|
if (RWWrap)
|
||||||
for (x = end; x >= start; x--) {
|
for (x = end; x >= start; x--)
|
||||||
if (x >= 0x8000)
|
{
|
||||||
AReadG[x - 0x8000] = func;
|
if (x >= 0x8000)
|
||||||
else
|
AReadG[x - 0x8000] = func;
|
||||||
ARead[x] = func;
|
else
|
||||||
}
|
ARead[x] = func;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
for (x = end; x >= start; x--)
|
for (x = end; x >= start; x--)
|
||||||
ARead[x] = func;
|
ARead[x] = func;
|
||||||
}
|
}
|
||||||
|
|
||||||
writefunc FASTAPASS(1) GetWriteHandler(int32 a) {
|
writefunc FASTAPASS(1) GetWriteHandler(int32 a)
|
||||||
|
{
|
||||||
if (RWWrap && a >= 0x8000)
|
if (RWWrap && a >= 0x8000)
|
||||||
return BWriteG[a - 0x8000];
|
return BWriteG[a - 0x8000];
|
||||||
else
|
else
|
||||||
return BWrite[a];
|
return BWrite[a];
|
||||||
}
|
}
|
||||||
|
|
||||||
void FASTAPASS(3) SetWriteHandler(int32 start, int32 end, writefunc func) {
|
void FASTAPASS(3) SetWriteHandler(int32 start, int32 end, writefunc func)
|
||||||
|
{
|
||||||
int32 x;
|
int32 x;
|
||||||
|
|
||||||
if (!func)
|
if (!func)
|
||||||
func = BNull;
|
func = BNull;
|
||||||
|
|
||||||
if (RWWrap)
|
if (RWWrap)
|
||||||
for (x = end; x >= start; x--) {
|
for (x = end; x >= start; x--)
|
||||||
|
{
|
||||||
if (x >= 0x8000)
|
if (x >= 0x8000)
|
||||||
BWriteG[x - 0x8000] = func;
|
BWriteG[x - 0x8000] = func;
|
||||||
else
|
else
|
||||||
@@ -152,50 +163,58 @@ uint8 RAM[0x800];
|
|||||||
|
|
||||||
uint8 PAL = 0;
|
uint8 PAL = 0;
|
||||||
|
|
||||||
static DECLFW(BRAML) {
|
static DECLFW(BRAML)
|
||||||
|
{
|
||||||
RAM[A] = V;
|
RAM[A] = V;
|
||||||
}
|
}
|
||||||
|
|
||||||
static DECLFR(ARAML) {
|
static DECLFR(ARAML)
|
||||||
|
{
|
||||||
return RAM[A];
|
return RAM[A];
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef COPYFAMI
|
#ifndef COPYFAMI
|
||||||
static DECLFW(BRAMH) {
|
static DECLFW(BRAMH)
|
||||||
|
{
|
||||||
RAM[A & 0x7FF] = V;
|
RAM[A & 0x7FF] = V;
|
||||||
}
|
}
|
||||||
|
|
||||||
static DECLFR(ARAMH) {
|
static DECLFR(ARAMH)
|
||||||
|
{
|
||||||
return RAM[A & 0x7FF];
|
return RAM[A & 0x7FF];
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void CloseGame(void) {
|
void FCEUI_CloseGame(void)
|
||||||
if (GameInfo) {
|
{
|
||||||
if (FCEUnetplay)
|
if (!GameInfo)
|
||||||
FCEUD_NetworkClose();
|
return;
|
||||||
if (GameInfo->name) {
|
|
||||||
free(GameInfo->name);
|
if (GameInfo->name)
|
||||||
GameInfo->name = 0;
|
free(GameInfo->name);
|
||||||
}
|
GameInfo->name = 0;
|
||||||
if (GameInfo->type != GIT_NSF)
|
if (GameInfo->type != GIT_NSF)
|
||||||
FCEU_FlushGameCheats(0, 0);
|
FCEU_FlushGameCheats(0, 0);
|
||||||
GameInterface(GI_CLOSE);
|
GameInterface(GI_CLOSE);
|
||||||
ResetExState(0, 0);
|
ResetExState(0, 0);
|
||||||
FCEU_CloseGenie();
|
FCEU_CloseGenie();
|
||||||
free(GameInfo);
|
free(GameInfo);
|
||||||
GameInfo = 0;
|
GameInfo = 0;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResetGameLoaded(void) {
|
void ResetGameLoaded(void)
|
||||||
if (GameInfo) CloseGame();
|
{
|
||||||
|
if (GameInfo)
|
||||||
|
FCEUI_CloseGame();
|
||||||
|
|
||||||
GameStateRestore = NULL;
|
GameStateRestore = NULL;
|
||||||
PPU_hook = NULL;
|
PPU_hook = NULL;
|
||||||
GameHBIRQHook = NULL;
|
GameHBIRQHook = NULL;
|
||||||
|
|
||||||
if (GameExpSound.Kill)
|
if (GameExpSound.Kill)
|
||||||
GameExpSound.Kill();
|
GameExpSound.Kill();
|
||||||
memset(&GameExpSound, 0, sizeof(GameExpSound));
|
memset(&GameExpSound, 0, sizeof(GameExpSound));
|
||||||
|
|
||||||
MapIRQHook = NULL;
|
MapIRQHook = NULL;
|
||||||
MMC5Hack = 0;
|
MMC5Hack = 0;
|
||||||
PEC586Hack = 0;
|
PEC586Hack = 0;
|
||||||
@@ -208,79 +227,77 @@ int iNESLoad(const char *name, FCEUFILE *fp);
|
|||||||
int FDSLoad(const char *name, FCEUFILE *fp);
|
int FDSLoad(const char *name, FCEUFILE *fp);
|
||||||
int NSFLoad(FCEUFILE *fp);
|
int NSFLoad(FCEUFILE *fp);
|
||||||
|
|
||||||
FCEUGI *FCEUI_LoadGame(const char *name) {
|
FCEUGI *FCEUI_LoadGame(const char *name, uint8_t *databuf, size_t databufsize)
|
||||||
FCEUFILE *fp;
|
{
|
||||||
char *ipsfn;
|
FCEUFILE *fp;
|
||||||
|
|
||||||
ResetGameLoaded();
|
ResetGameLoaded();
|
||||||
|
|
||||||
GameInfo = malloc(sizeof(FCEUGI));
|
GameInfo = malloc(sizeof(FCEUGI));
|
||||||
memset(GameInfo, 0, sizeof(FCEUGI));
|
memset(GameInfo, 0, sizeof(FCEUGI));
|
||||||
|
|
||||||
GameInfo->soundchan = 0;
|
GameInfo->soundchan = 0;
|
||||||
GameInfo->soundrate = 0;
|
GameInfo->soundrate = 0;
|
||||||
GameInfo->name = 0;
|
GameInfo->name = 0;
|
||||||
GameInfo->type = GIT_CART;
|
GameInfo->type = GIT_CART;
|
||||||
GameInfo->vidsys = GIV_USER;
|
GameInfo->vidsys = GIV_USER;
|
||||||
GameInfo->input[0] = GameInfo->input[1] = -1;
|
GameInfo->input[0] = GameInfo->input[1] = -1;
|
||||||
GameInfo->inputfc = -1;
|
GameInfo->inputfc = -1;
|
||||||
GameInfo->cspecial = 0;
|
GameInfo->cspecial = 0;
|
||||||
|
|
||||||
FCEU_printf("Loading %s...\n\n", name);
|
FCEU_printf("Loading %s...\n\n", name);
|
||||||
|
|
||||||
GetFileBase(name);
|
GetFileBase(name);
|
||||||
|
|
||||||
ipsfn = FCEU_MakeFName(FCEUMKF_IPS, 0, 0);
|
fp = FCEU_fopen(name, NULL, "rb", 0, databuf, databufsize);
|
||||||
fp = FCEU_fopen(name, ipsfn, "rb", 0);
|
|
||||||
free(ipsfn);
|
|
||||||
|
|
||||||
if (!fp) {
|
if (!fp) {
|
||||||
FCEU_PrintError("Error opening \"%s\"!", name);
|
FCEU_PrintError("Error opening \"%s\"!", name);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iNESLoad(name, fp))
|
if (iNESLoad(name, fp))
|
||||||
goto endlseq;
|
goto endlseq;
|
||||||
if (NSFLoad(fp))
|
if (NSFLoad(fp))
|
||||||
goto endlseq;
|
goto endlseq;
|
||||||
if (UNIFLoad(name, fp))
|
if (UNIFLoad(name, fp))
|
||||||
goto endlseq;
|
goto endlseq;
|
||||||
if (FDSLoad(name, fp))
|
if (FDSLoad(name, fp))
|
||||||
goto endlseq;
|
goto endlseq;
|
||||||
|
|
||||||
FCEU_PrintError("An error occurred while loading the file.");
|
FCEU_PrintError("An error occurred while loading the file.");
|
||||||
FCEU_fclose(fp);
|
FCEU_fclose(fp);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
endlseq:
|
endlseq:
|
||||||
FCEU_fclose(fp);
|
FCEU_fclose(fp);
|
||||||
|
|
||||||
FCEU_ResetVidSys();
|
FCEU_ResetVidSys();
|
||||||
if (GameInfo->type != GIT_NSF)
|
if (GameInfo->type != GIT_NSF)
|
||||||
if (FSettings.GameGenie)
|
if (FSettings.GameGenie)
|
||||||
FCEU_OpenGenie();
|
FCEU_OpenGenie();
|
||||||
|
|
||||||
PowerNES();
|
PowerNES();
|
||||||
FCEUSS_CheckStates();
|
FCEUSS_CheckStates();
|
||||||
FCEUMOV_CheckMovies();
|
|
||||||
|
|
||||||
if (GameInfo->type != GIT_NSF) {
|
if (GameInfo->type != GIT_NSF) {
|
||||||
FCEU_LoadGamePalette();
|
FCEU_LoadGamePalette();
|
||||||
FCEU_LoadGameCheats(0);
|
FCEU_LoadGameCheats(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
FCEU_ResetPalette();
|
FCEU_ResetPalette();
|
||||||
FCEU_ResetMessages(); // Save state, status messages, etc.
|
FCEU_ResetMessages(); // Save state, status messages, etc.
|
||||||
|
|
||||||
return(GameInfo);
|
return(GameInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
int CopyFamiLoad(void);
|
int CopyFamiLoad(void);
|
||||||
|
|
||||||
FCEUGI *FCEUI_CopyFamiStart(void) {
|
FCEUGI *FCEUI_CopyFamiStart(void)
|
||||||
|
{
|
||||||
ResetGameLoaded();
|
ResetGameLoaded();
|
||||||
|
|
||||||
GameInfo = malloc(sizeof(FCEUGI));
|
GameInfo = (FCEUGI*)malloc(sizeof(FCEUGI));
|
||||||
memset(GameInfo, 0, sizeof(FCEUGI));
|
memset(GameInfo, 0, sizeof(FCEUGI));
|
||||||
|
|
||||||
GameInfo->soundchan = 0;
|
GameInfo->soundchan = 0;
|
||||||
@@ -306,7 +323,6 @@ FCEUGI *FCEUI_CopyFamiStart(void) {
|
|||||||
|
|
||||||
PowerNES();
|
PowerNES();
|
||||||
FCEUSS_CheckStates();
|
FCEUSS_CheckStates();
|
||||||
FCEUMOV_CheckMovies();
|
|
||||||
|
|
||||||
if (GameInfo->type != GIT_NSF) {
|
if (GameInfo->type != GIT_NSF) {
|
||||||
FCEU_LoadGamePalette();
|
FCEU_LoadGamePalette();
|
||||||
@@ -356,20 +372,19 @@ void FCEUI_Emulate(uint8 **pXBuf, int32 **SoundBuf, int32 *SoundBufSize, int ski
|
|||||||
*SoundBufSize = ssize;
|
*SoundBufSize = ssize;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FCEUI_CloseGame(void) {
|
|
||||||
CloseGame();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ResetNES(void) {
|
void ResetNES(void)
|
||||||
FCEUMOV_AddCommand(FCEUNPCMD_RESET);
|
{
|
||||||
if (!GameInfo) return;
|
if (!GameInfo)
|
||||||
|
return;
|
||||||
GameInterface(GI_RESETM2);
|
GameInterface(GI_RESETM2);
|
||||||
FCEUSND_Reset();
|
FCEUSND_Reset();
|
||||||
FCEUPPU_Reset();
|
FCEUPPU_Reset();
|
||||||
X6502_Reset();
|
X6502_Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FCEU_MemoryRand(uint8 *ptr, uint32 size) {
|
void FCEU_MemoryRand(uint8 *ptr, uint32 size)
|
||||||
|
{
|
||||||
int x = 0;
|
int x = 0;
|
||||||
while (size) {
|
while (size) {
|
||||||
// *ptr = (x & 4) ? 0xFF : 0x00; // Huang Di DEBUG MODE enabled by default
|
// *ptr = (x & 4) ? 0xFF : 0x00; // Huang Di DEBUG MODE enabled by default
|
||||||
@@ -386,12 +401,14 @@ void FCEU_MemoryRand(uint8 *ptr, uint32 size) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void hand(X6502 *X, int type, uint32 A) {
|
void hand(X6502 *X, int type, uint32 A)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void PowerNES(void) {
|
void PowerNES(void)
|
||||||
FCEUMOV_AddCommand(FCEUNPCMD_POWER);
|
{
|
||||||
if (!GameInfo) return;
|
if (!GameInfo)
|
||||||
|
return;
|
||||||
|
|
||||||
FCEU_CheatResetRAM();
|
FCEU_CheatResetRAM();
|
||||||
FCEU_CheatAddRAM(2, 0, RAM);
|
FCEU_CheatAddRAM(2, 0, RAM);
|
||||||
@@ -426,13 +443,13 @@ void PowerNES(void) {
|
|||||||
if (GameInfo->type == GIT_VSUNI)
|
if (GameInfo->type == GIT_VSUNI)
|
||||||
FCEU_VSUniPower();
|
FCEU_VSUniPower();
|
||||||
|
|
||||||
|
|
||||||
timestampbase = 0;
|
timestampbase = 0;
|
||||||
X6502_Power();
|
X6502_Power();
|
||||||
FCEU_PowerCheats();
|
FCEU_PowerCheats();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FCEU_ResetVidSys(void) {
|
void FCEU_ResetVidSys(void)
|
||||||
|
{
|
||||||
int w;
|
int w;
|
||||||
|
|
||||||
if (GameInfo->vidsys == GIV_NTSC)
|
if (GameInfo->vidsys == GIV_NTSC)
|
||||||
@@ -450,8 +467,8 @@ void FCEU_ResetVidSys(void) {
|
|||||||
|
|
||||||
FCEUS FSettings;
|
FCEUS FSettings;
|
||||||
|
|
||||||
void FCEU_printf(char *format, ...) {
|
void FCEU_printf(char *format, ...)
|
||||||
FILE *ofile;
|
{
|
||||||
char temp[2048];
|
char temp[2048];
|
||||||
|
|
||||||
va_list ap;
|
va_list ap;
|
||||||
@@ -460,14 +477,11 @@ void FCEU_printf(char *format, ...) {
|
|||||||
vsprintf(temp, format, ap);
|
vsprintf(temp, format, ap);
|
||||||
FCEUD_Message(temp);
|
FCEUD_Message(temp);
|
||||||
|
|
||||||
ofile = fopen("stdout.txt", "ab");
|
|
||||||
fwrite(temp, 1, strlen(temp), ofile);
|
|
||||||
fclose(ofile);
|
|
||||||
|
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FCEU_PrintError(char *format, ...) {
|
void FCEU_PrintError(char *format, ...)
|
||||||
|
{
|
||||||
char temp[2048];
|
char temp[2048];
|
||||||
|
|
||||||
va_list ap;
|
va_list ap;
|
||||||
@@ -479,29 +493,37 @@ void FCEU_PrintError(char *format, ...) {
|
|||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FCEUI_SetRenderedLines(int ntscf, int ntscl, int palf, int pall) {
|
void FCEUI_SetRenderedLines(int ntscf, int ntscl, int palf, int pall)
|
||||||
|
{
|
||||||
FSettings.UsrFirstSLine[0] = ntscf;
|
FSettings.UsrFirstSLine[0] = ntscf;
|
||||||
FSettings.UsrLastSLine[0] = ntscl;
|
FSettings.UsrLastSLine[0] = ntscl;
|
||||||
FSettings.UsrFirstSLine[1] = palf;
|
FSettings.UsrFirstSLine[1] = palf;
|
||||||
FSettings.UsrLastSLine[1] = pall;
|
FSettings.UsrLastSLine[1] = pall;
|
||||||
if (PAL) {
|
if (PAL)
|
||||||
|
{
|
||||||
FSettings.FirstSLine = FSettings.UsrFirstSLine[1];
|
FSettings.FirstSLine = FSettings.UsrFirstSLine[1];
|
||||||
FSettings.LastSLine = FSettings.UsrLastSLine[1];
|
FSettings.LastSLine = FSettings.UsrLastSLine[1];
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
FSettings.FirstSLine = FSettings.UsrFirstSLine[0];
|
FSettings.FirstSLine = FSettings.UsrFirstSLine[0];
|
||||||
FSettings.LastSLine = FSettings.UsrLastSLine[0];
|
FSettings.LastSLine = FSettings.UsrLastSLine[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FCEUI_SetVidSystem(int a) {
|
void FCEUI_SetVidSystem(int a)
|
||||||
|
{
|
||||||
FSettings.PAL = a ? 1 : 0;
|
FSettings.PAL = a ? 1 : 0;
|
||||||
if (GameInfo) {
|
|
||||||
FCEU_ResetVidSys();
|
if (!GameInfo)
|
||||||
FCEU_ResetPalette();
|
return;
|
||||||
}
|
|
||||||
|
FCEU_ResetVidSys();
|
||||||
|
FCEU_ResetPalette();
|
||||||
}
|
}
|
||||||
|
|
||||||
int FCEUI_GetCurrentVidSystem(int *slstart, int *slend) {
|
int FCEUI_GetCurrentVidSystem(int *slstart, int *slend)
|
||||||
|
{
|
||||||
if (slstart)
|
if (slstart)
|
||||||
*slstart = FSettings.FirstSLine;
|
*slstart = FSettings.FirstSLine;
|
||||||
if (slend)
|
if (slend)
|
||||||
@@ -509,15 +531,18 @@ int FCEUI_GetCurrentVidSystem(int *slstart, int *slend) {
|
|||||||
return(PAL);
|
return(PAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FCEUI_SetGameGenie(int a) {
|
void FCEUI_SetGameGenie(int a)
|
||||||
|
{
|
||||||
FSettings.GameGenie = a ? 1 : 0;
|
FSettings.GameGenie = a ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FCEUI_SetSnapName(int a) {
|
void FCEUI_SetSnapName(int a)
|
||||||
|
{
|
||||||
FSettings.SnapName = a;
|
FSettings.SnapName = a;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 FCEUI_GetDesiredFPS(void) {
|
int32 FCEUI_GetDesiredFPS(void)
|
||||||
|
{
|
||||||
if (PAL)
|
if (PAL)
|
||||||
return(838977920); // ~50.007
|
return(838977920); // ~50.007
|
||||||
else
|
else
|
||||||
|
|||||||
Reference in New Issue
Block a user