mirror of
https://github.com/dborth/fceugx.git
synced 2024-11-01 06:55:05 +01:00
sync to FCEUX svn
This commit is contained in:
parent
e147c806b4
commit
2c662616c5
@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
static uint8 reg[16], is153;
|
static uint8 reg[16], is153;
|
||||||
static uint8 IRQa;
|
static uint8 IRQa;
|
||||||
static uint16 IRQCount, IRQLatch;
|
static int16 IRQCount, IRQLatch;
|
||||||
|
|
||||||
static uint8 *WRAM=NULL;
|
static uint8 *WRAM=NULL;
|
||||||
static uint32 WRAMSIZE;
|
static uint32 WRAMSIZE;
|
||||||
@ -35,7 +35,7 @@ static SFORMAT StateRegs[]=
|
|||||||
{reg, 16, "REGS"},
|
{reg, 16, "REGS"},
|
||||||
{&IRQa, 1, "IRQA"},
|
{&IRQa, 1, "IRQA"},
|
||||||
{&IRQCount, 2, "IRQC"},
|
{&IRQCount, 2, "IRQC"},
|
||||||
{&IRQLatch, 2, "IRQL"},
|
{&IRQLatch, 2, "IRQL"}, // need for Famicom Jump II - Saikyou no 7 Nin (J) [!]
|
||||||
{0}
|
{0}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -75,18 +75,18 @@ static void BandaiSync(void)
|
|||||||
setprg16(0x8000,reg[8]);
|
setprg16(0x8000,reg[8]);
|
||||||
setprg16(0xC000,~0);
|
setprg16(0xC000,~0);
|
||||||
}
|
}
|
||||||
switch(reg[9])
|
switch(reg[9]&3)
|
||||||
{
|
{
|
||||||
case 0: setmirror(MI_V); break;
|
case 0: setmirror(MI_V); break;
|
||||||
case 1: setmirror(MI_H); break;
|
case 1: setmirror(MI_H); break;
|
||||||
case 2: setmirror(MI_0); break;
|
case 2: setmirror(MI_0); break;
|
||||||
case 3: setmirror(MI_1); break;
|
case 3: setmirror(MI_1); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static DECLFW(BandaiWrite)
|
static DECLFW(BandaiWrite)
|
||||||
{
|
{
|
||||||
A&=0x0F;
|
A&=0x0F;
|
||||||
if(A<0x0A)
|
if(A<0x0A)
|
||||||
{
|
{
|
||||||
reg[A&0x0F]=V;
|
reg[A&0x0F]=V;
|
||||||
@ -96,9 +96,9 @@ static DECLFW(BandaiWrite)
|
|||||||
switch(A)
|
switch(A)
|
||||||
{
|
{
|
||||||
case 0x0A: X6502_IRQEnd(FCEU_IQEXT); IRQa=V&1; IRQCount=IRQLatch; break;
|
case 0x0A: X6502_IRQEnd(FCEU_IQEXT); IRQa=V&1; IRQCount=IRQLatch; break;
|
||||||
case 0x0B: IRQLatch&=0xFF00; IRQLatch|=V; break;
|
case 0x0B: IRQLatch&=0xFF00; IRQLatch|=V; break;
|
||||||
case 0x0C: IRQLatch&=0xFF; IRQLatch|=V<<8; break;
|
case 0x0C: IRQLatch&=0xFF; IRQLatch|=V<<8; break;
|
||||||
case 0x0D: break;// Serial EEPROM control port
|
case 0x0D: break;// Serial EEPROM control port
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,7 +115,7 @@ static void mmc5_PPUWrite(uint32 A, uint8 V) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 mmc5_PPURead(uint32 A) {
|
uint8 FASTCALL mmc5_PPURead(uint32 A) {
|
||||||
if(A<0x2000)
|
if(A<0x2000)
|
||||||
{
|
{
|
||||||
if(ppuphase == PPUPHASE_BG)
|
if(ppuphase == PPUPHASE_BG)
|
||||||
|
@ -99,6 +99,8 @@ void ResetCartMapping(void)
|
|||||||
{
|
{
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
|
PPU_ResetHooks();
|
||||||
|
|
||||||
for(x=0;x<32;x++)
|
for(x=0;x<32;x++)
|
||||||
{
|
{
|
||||||
Page[x]=nothing-x*2048;
|
Page[x]=nothing-x*2048;
|
||||||
@ -293,7 +295,7 @@ void setchr8r(int r, unsigned int V)
|
|||||||
if(CHRram[r])
|
if(CHRram[r])
|
||||||
PPUCHRRAM|=(255);
|
PPUCHRRAM|=(255);
|
||||||
else
|
else
|
||||||
PPUCHRRAM=0;
|
PPUCHRRAM=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setchr1(unsigned int A, unsigned int V)
|
void setchr1(unsigned int A, unsigned int V)
|
||||||
@ -437,7 +439,7 @@ static uint8 *GENIEROM=0;
|
|||||||
|
|
||||||
void FixGenieMap(void);
|
void FixGenieMap(void);
|
||||||
|
|
||||||
// Called when a game(file) is opened successfully.
|
// Called when a game(file) is opened successfully.
|
||||||
void OpenGenie(void)
|
void OpenGenie(void)
|
||||||
{
|
{
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
|
@ -16,9 +16,11 @@ char *FCEUI_GetAboutString() {
|
|||||||
const char *aboutTemplate =
|
const char *aboutTemplate =
|
||||||
FCEU_NAME_AND_VERSION "\n\n\
|
FCEU_NAME_AND_VERSION "\n\n\
|
||||||
Authors:\n\
|
Authors:\n\
|
||||||
zeromus, adelikat, CaH4e3\n\n\
|
zeromus, adelikat,\n\n\
|
||||||
Contributers:\n\
|
Contributers:\n\
|
||||||
Acmlm,DWEdit,QFox\n\
|
Acmlm,CaH4e3\n\
|
||||||
|
DWEdit,QFox\n\
|
||||||
|
qeed,Shinydoofy,ugetab\n\
|
||||||
\n\
|
\n\
|
||||||
FCEUX 2.0\n\
|
FCEUX 2.0\n\
|
||||||
mz, nitsujrehtona, Lukas Sabota,\n\
|
mz, nitsujrehtona, Lukas Sabota,\n\
|
||||||
|
@ -624,10 +624,22 @@ void DebugCycle() {
|
|||||||
else
|
else
|
||||||
vblankScanLines = 0;
|
vblankScanLines = 0;
|
||||||
|
|
||||||
|
if (GameInfo->type==GIT_NSF)
|
||||||
|
{
|
||||||
|
if ((_PC >= 0x3801) && (_PC <= 0x3824)) return;
|
||||||
|
}
|
||||||
|
|
||||||
if (numWPs || dbgstate.step || dbgstate.runline || dbgstate.stepout || watchpoint[64].flags || dbgstate.badopbreak)
|
if (numWPs || dbgstate.step || dbgstate.runline || dbgstate.stepout || watchpoint[64].flags || dbgstate.badopbreak)
|
||||||
breakpoint();
|
breakpoint();
|
||||||
if(debug_loggingCD) LogCDData();
|
if(debug_loggingCD) LogCDData();
|
||||||
|
|
||||||
//mbg 6/30/06 - this was commented out when i got here. i dont understand it anyway
|
//mbg 6/30/06 - this was commented out when i got here. i dont understand it anyway
|
||||||
//if(logging || (hMemView && (EditingMode == 2))) LogInstruction();
|
//if(logging || (hMemView && (EditingMode == 2))) LogInstruction();
|
||||||
FCEUD_TraceInstruction();
|
|
||||||
}
|
//This needs to be windows only or else the linux build system will fail since logging is declared in a
|
||||||
|
//windows source file
|
||||||
|
#ifdef WIN32
|
||||||
|
extern volatile int logging; //UGETAB: This is required to be an extern, because the info isn't set here
|
||||||
|
if(logging) FCEUD_TraceInstruction();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
@ -292,7 +292,7 @@ static void AllocBuffers()
|
|||||||
void win_AllocBuffers(uint8 **GameMemBlock, uint8 **RAM);
|
void win_AllocBuffers(uint8 **GameMemBlock, uint8 **RAM);
|
||||||
win_AllocBuffers(&GameMemBlock, &RAM);
|
win_AllocBuffers(&GameMemBlock, &RAM);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
GameMemBlock = (uint8*)FCEU_gmalloc(131072);
|
GameMemBlock = (uint8*)FCEU_gmalloc(131072);
|
||||||
RAM = (uint8*)FCEU_gmalloc(0x800);
|
RAM = (uint8*)FCEU_gmalloc(0x800);
|
||||||
@ -304,7 +304,7 @@ static void FreeBuffers() {
|
|||||||
#ifdef _USE_SHARED_MEMORY_
|
#ifdef _USE_SHARED_MEMORY_
|
||||||
void win_FreeBuffers(uint8 *GameMemBlock, uint8 *RAM);
|
void win_FreeBuffers(uint8 *GameMemBlock, uint8 *RAM);
|
||||||
win_FreeBuffers(GameMemBlock, RAM);
|
win_FreeBuffers(GameMemBlock, RAM);
|
||||||
#else
|
#else
|
||||||
FCEU_free(GameMemBlock);
|
FCEU_free(GameMemBlock);
|
||||||
FCEU_free(RAM);
|
FCEU_free(RAM);
|
||||||
#endif
|
#endif
|
||||||
@ -314,7 +314,7 @@ static void FreeBuffers() {
|
|||||||
uint8 PAL=0;
|
uint8 PAL=0;
|
||||||
|
|
||||||
static DECLFW(BRAML)
|
static DECLFW(BRAML)
|
||||||
{
|
{
|
||||||
RAM[A]=V;
|
RAM[A]=V;
|
||||||
#ifdef _S9XLUA_H
|
#ifdef _S9XLUA_H
|
||||||
FCEU_LuaWriteInform();
|
FCEU_LuaWriteInform();
|
||||||
@ -361,7 +361,7 @@ void ResetGameLoaded(void)
|
|||||||
int UNIFLoad(const char *name, FCEUFILE *fp);
|
int UNIFLoad(const char *name, FCEUFILE *fp);
|
||||||
int iNESLoad(const char *name, FCEUFILE *fp, int OverwriteVidMode);
|
int iNESLoad(const char *name, FCEUFILE *fp, int OverwriteVidMode);
|
||||||
int FDSLoad(const char *name, FCEUFILE *fp);
|
int FDSLoad(const char *name, FCEUFILE *fp);
|
||||||
int NSFLoad(FCEUFILE *fp);
|
int NSFLoad(const char *name, FCEUFILE *fp);
|
||||||
|
|
||||||
//char lastLoadedGameName [2048] = {0,}; // hack for movie WRAM clearing on record from poweron
|
//char lastLoadedGameName [2048] = {0,}; // hack for movie WRAM clearing on record from poweron
|
||||||
|
|
||||||
@ -424,7 +424,7 @@ FCEUGI *FCEUI_LoadGameVirtual(const char *name, int OverwriteVidMode)
|
|||||||
goto endlseq;*/
|
goto endlseq;*/
|
||||||
if(iNESLoad(name,fp,OverwriteVidMode))
|
if(iNESLoad(name,fp,OverwriteVidMode))
|
||||||
goto endlseq;
|
goto endlseq;
|
||||||
if(NSFLoad(fp))
|
if(NSFLoad(name,fp))
|
||||||
goto endlseq;
|
goto endlseq;
|
||||||
if(UNIFLoad(name,fp))
|
if(UNIFLoad(name,fp))
|
||||||
goto endlseq;
|
goto endlseq;
|
||||||
@ -612,7 +612,7 @@ void FCEUI_Emulate(uint8 **pXBuf, int32 **SoundBuf, int32 *SoundBufSize, int ski
|
|||||||
r = FCEUPPU_Loop(skip);
|
r = FCEUPPU_Loop(skip);
|
||||||
|
|
||||||
if (skip != 2) ssize=FlushEmulateSound(); //If skip = 2 we are skipping sound processing
|
if (skip != 2) ssize=FlushEmulateSound(); //If skip = 2 we are skipping sound processing
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
//These Windows only dialogs need to be updated only once per frame so they are included here
|
//These Windows only dialogs need to be updated only once per frame so they are included here
|
||||||
UpdateCheatList();
|
UpdateCheatList();
|
||||||
@ -631,12 +631,12 @@ void FCEUI_Emulate(uint8 **pXBuf, int32 **SoundBuf, int32 *SoundBufSize, int ski
|
|||||||
*SoundBuf=0;
|
*SoundBuf=0;
|
||||||
*SoundBufSize=0;
|
*SoundBufSize=0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*SoundBuf=WaveFinal;
|
*SoundBuf=WaveFinal;
|
||||||
*SoundBufSize=ssize;
|
*SoundBufSize=ssize;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (EmulationPaused&2 && ( !frameAdvanceLagSkip || !lagFlag) )
|
if (EmulationPaused&2 && ( !frameAdvanceLagSkip || !lagFlag) )
|
||||||
//Lots of conditions here. EmulationPaused&2 must be true. In addition frameAdvanceLagSkip or lagFlag must be false
|
//Lots of conditions here. EmulationPaused&2 must be true. In addition frameAdvanceLagSkip or lagFlag must be false
|
||||||
{
|
{
|
||||||
@ -646,12 +646,12 @@ void FCEUI_Emulate(uint8 **pXBuf, int32 **SoundBuf, int32 *SoundBufSize, int ski
|
|||||||
if(soundoptions&SO_MUTEFA) //mute the frame advance if the user requested it
|
if(soundoptions&SO_MUTEFA) //mute the frame advance if the user requested it
|
||||||
*SoundBufSize=0; //keep sound muted
|
*SoundBufSize=0; //keep sound muted
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
currMovieData.TryDumpIncremental();
|
currMovieData.TryDumpIncremental();
|
||||||
|
|
||||||
if (lagFlag)
|
if (lagFlag)
|
||||||
{
|
{
|
||||||
lagCounter++;
|
lagCounter++;
|
||||||
justLagged = true;
|
justLagged = true;
|
||||||
@ -663,8 +663,8 @@ void FCEUI_Emulate(uint8 **pXBuf, int32 **SoundBuf, int32 *SoundBufSize, int ski
|
|||||||
}
|
}
|
||||||
|
|
||||||
void FCEUI_CloseGame(void)
|
void FCEUI_CloseGame(void)
|
||||||
{
|
{
|
||||||
if(!FCEU_IsValidUI(FCEUI_CLOSEGAME))
|
if(!FCEU_IsValidUI(FCEUI_CLOSEGAME))
|
||||||
return;
|
return;
|
||||||
CloseGame();
|
CloseGame();
|
||||||
}
|
}
|
||||||
@ -701,7 +701,7 @@ void hand(X6502 *X, int type, unsigned int A)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int suppressAddPowerCommand=0; // hack... yeah, I know...
|
int suppressAddPowerCommand=0; // hack... yeah, I know...
|
||||||
void PowerNES(void)
|
void PowerNES(void)
|
||||||
{
|
{
|
||||||
//void MapperInit();
|
//void MapperInit();
|
||||||
//MapperInit();
|
//MapperInit();
|
||||||
@ -740,7 +740,7 @@ void PowerNES(void)
|
|||||||
extern int disableBatteryLoading;
|
extern int disableBatteryLoading;
|
||||||
if(disableBatteryLoading)
|
if(disableBatteryLoading)
|
||||||
GameInterface(GI_RESETSAVE);
|
GameInterface(GI_RESETSAVE);
|
||||||
|
|
||||||
|
|
||||||
timestampbase=0;
|
timestampbase=0;
|
||||||
LagCounterReset();
|
LagCounterReset();
|
||||||
@ -757,9 +757,9 @@ void FCEU_ResetVidSys(void)
|
|||||||
int w;
|
int w;
|
||||||
|
|
||||||
if(GameInfo->vidsys==GIV_NTSC)
|
if(GameInfo->vidsys==GIV_NTSC)
|
||||||
w=0;
|
w=0;
|
||||||
else if(GameInfo->vidsys==GIV_PAL)
|
else if(GameInfo->vidsys==GIV_PAL)
|
||||||
w=1;
|
w=1;
|
||||||
else
|
else
|
||||||
w=FSettings.PAL;
|
w=FSettings.PAL;
|
||||||
|
|
||||||
@ -899,7 +899,7 @@ void UpdateAutosave(void)
|
|||||||
{
|
{
|
||||||
if(!EnableAutosave)
|
if(!EnableAutosave)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
char * f;
|
char * f;
|
||||||
AutosaveCounter = (AutosaveCounter + 1) % 256;
|
AutosaveCounter = (AutosaveCounter + 1) % 256;
|
||||||
if(AutosaveCounter == 0)
|
if(AutosaveCounter == 0)
|
||||||
@ -1083,7 +1083,7 @@ bool FCEUXLoad(const char *name, FCEUFILE *fp)
|
|||||||
|
|
||||||
cart->chrPages = head.VROM_size;
|
cart->chrPages = head.VROM_size;
|
||||||
|
|
||||||
cart->mirroring = (head.ROM_type&1);
|
cart->mirroring = (head.ROM_type&1);
|
||||||
if(head.ROM_type&8) cart->mirroring=2;
|
if(head.ROM_type&8) cart->mirroring=2;
|
||||||
|
|
||||||
//skip trainer
|
//skip trainer
|
||||||
@ -1105,7 +1105,7 @@ bool FCEUXLoad(const char *name, FCEUFILE *fp)
|
|||||||
ResetCartMapping();
|
ResetCartMapping();
|
||||||
SetupCartPRGMapping(0,(uint8*)cart->PRG,cart->prgSize,0);
|
SetupCartPRGMapping(0,(uint8*)cart->PRG,cart->prgSize,0);
|
||||||
SetupCartCHRMapping(0,(uint8*)cart->CHR,cart->chrSize,0);
|
SetupCartCHRMapping(0,(uint8*)cart->CHR,cart->chrSize,0);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1116,4 +1116,4 @@ uint8 FCEU_ReadRomByte(uint32 i) {
|
|||||||
if(i < 16+PRGsize[0])return PRGptr[0][i-16];
|
if(i < 16+PRGsize[0])return PRGptr[0][i-16];
|
||||||
if(i < 16+PRGsize[0]+CHRsize[0])return CHRptr[0][i-16-PRGsize[0]];
|
if(i < 16+PRGsize[0]+CHRsize[0])return CHRptr[0][i-16-PRGsize[0]];
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
@ -35,12 +35,13 @@
|
|||||||
#include "cart.h"
|
#include "cart.h"
|
||||||
#include "netplay.h"
|
#include "netplay.h"
|
||||||
#include "driver.h"
|
#include "driver.h"
|
||||||
|
#include "movie.h"
|
||||||
|
|
||||||
// TODO: Add code to put a delay in between the time a disk is inserted
|
// TODO: Add code to put a delay in between the time a disk is inserted
|
||||||
// and the when it can be successfully read/written to. This should
|
// and the when it can be successfully read/written to. This should
|
||||||
// prevent writes to wrong places OR add code to prevent disk ejects
|
// prevent writes to wrong places OR add code to prevent disk ejects
|
||||||
// when the virtual motor is on(mmm...virtual motor).
|
// when the virtual motor is on(mmm...virtual motor).
|
||||||
extern int disableBatteryLoading;
|
extern int disableBatteryLoading;
|
||||||
|
|
||||||
static DECLFR(FDSRead4030);
|
static DECLFR(FDSRead4030);
|
||||||
static DECLFR(FDSRead4031);
|
static DECLFR(FDSRead4031);
|
||||||
@ -68,7 +69,11 @@ static int32 IRQLatch,IRQCount;
|
|||||||
static uint8 IRQa;
|
static uint8 IRQa;
|
||||||
static void FDSClose(void);
|
static void FDSClose(void);
|
||||||
|
|
||||||
|
#ifdef GEKKO
|
||||||
uint8 FDSBIOS[8192];
|
uint8 FDSBIOS[8192];
|
||||||
|
#else
|
||||||
|
static uint8 FDSBIOS[8192];
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Original disk data backup, to help in creating save states. */
|
/* Original disk data backup, to help in creating save states. */
|
||||||
static uint8 *diskdatao[8]={0,0,0,0,0,0,0,0};
|
static uint8 *diskdatao[8]={0,0,0,0,0,0,0,0};
|
||||||
@ -94,7 +99,7 @@ void FDSGI(GI h)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void FDSStateRestore(int version)
|
static void FDSStateRestore(int version)
|
||||||
{
|
{
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
setmirror(((FDSRegs[5]&8)>>3)^1);
|
setmirror(((FDSRegs[5]&8)>>3)^1);
|
||||||
@ -133,7 +138,7 @@ static void FDSInit(void)
|
|||||||
SetReadHandler(0x4032,0x4032,FDSRead4032);
|
SetReadHandler(0x4032,0x4032,FDSRead4032);
|
||||||
SetReadHandler(0x4033,0x4033,FDSRead4033);
|
SetReadHandler(0x4033,0x4033,FDSRead4033);
|
||||||
|
|
||||||
SetWriteHandler(0x4020,0x4025,FDSWrite);
|
SetWriteHandler(0x4020,0x4025,FDSWrite);
|
||||||
|
|
||||||
SetWriteHandler(0x6000,0xdfff,FDSRAMWrite);
|
SetWriteHandler(0x6000,0xdfff,FDSRAMWrite);
|
||||||
SetReadHandler(0x6000,0xdfff,FDSRAMRead);
|
SetReadHandler(0x6000,0xdfff,FDSRAMRead);
|
||||||
@ -147,17 +152,22 @@ static void FDSInit(void)
|
|||||||
|
|
||||||
void FCEU_FDSInsert(void)
|
void FCEU_FDSInsert(void)
|
||||||
{
|
{
|
||||||
|
if(FCEUI_EmulationPaused()) EmulationPaused |= 2;
|
||||||
|
|
||||||
|
if(FCEUMOV_Mode(MOVIEMODE_RECORD))
|
||||||
|
FCEUMOV_AddCommand(FCEUNPCMD_FDSINSERT);
|
||||||
|
|
||||||
if(TotalSides==0)
|
if(TotalSides==0)
|
||||||
{
|
{
|
||||||
FCEU_DispMessage("Not FDS; can't eject disk.");
|
FCEU_DispMessage("Not FDS; can't eject disk.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(InDisk==255)
|
if(InDisk==255)
|
||||||
{
|
{
|
||||||
FCEU_DispMessage("Disk %d Side %s Inserted",SelectDisk>>1,(SelectDisk&1)?"B":"A");
|
FCEU_DispMessage("Disk %d Side %s Inserted",SelectDisk>>1,(SelectDisk&1)?"B":"A");
|
||||||
InDisk=SelectDisk;
|
InDisk=SelectDisk;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FCEU_DispMessage("Disk %d Side %s Ejected",SelectDisk>>1,(SelectDisk&1)?"B":"A");
|
FCEU_DispMessage("Disk %d Side %s Ejected",SelectDisk>>1,(SelectDisk&1)?"B":"A");
|
||||||
InDisk=255;
|
InDisk=255;
|
||||||
@ -171,6 +181,11 @@ InDisk=255;
|
|||||||
*/
|
*/
|
||||||
void FCEU_FDSSelect(void)
|
void FCEU_FDSSelect(void)
|
||||||
{
|
{
|
||||||
|
if(FCEUI_EmulationPaused()) EmulationPaused |= 2;
|
||||||
|
|
||||||
|
if(FCEUMOV_Mode(MOVIEMODE_RECORD))
|
||||||
|
FCEUMOV_AddCommand(FCEUNPCMD_FDSSELECT);
|
||||||
|
|
||||||
if(TotalSides==0)
|
if(TotalSides==0)
|
||||||
{
|
{
|
||||||
FCEU_DispMessage("Not FDS; can't select disk.");
|
FCEU_DispMessage("Not FDS; can't select disk.");
|
||||||
@ -198,14 +213,14 @@ static void FDSFix(int a)
|
|||||||
IRQCount=IRQLatch=0;
|
IRQCount=IRQLatch=0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
IRQCount=IRQLatch;
|
IRQCount=IRQLatch;
|
||||||
//IRQCount=IRQLatch; //0xFFFF;
|
//IRQCount=IRQLatch; //0xFFFF;
|
||||||
X6502_IRQBegin(FCEU_IQEXT);
|
X6502_IRQBegin(FCEU_IQEXT);
|
||||||
//printf("IRQ: %d\n",timestamp);
|
//printf("IRQ: %d\n",timestamp);
|
||||||
// printf("IRQ: %d\n",scanline);
|
// printf("IRQ: %d\n",scanline);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(DiskSeekIRQ>0)
|
if(DiskSeekIRQ>0)
|
||||||
{
|
{
|
||||||
DiskSeekIRQ-=a;
|
DiskSeekIRQ-=a;
|
||||||
if(DiskSeekIRQ<=0)
|
if(DiskSeekIRQ<=0)
|
||||||
@ -250,14 +265,14 @@ static DECLFR(FDSRead4031)
|
|||||||
return z;
|
return z;
|
||||||
}
|
}
|
||||||
static DECLFR(FDSRead4032)
|
static DECLFR(FDSRead4032)
|
||||||
{
|
{
|
||||||
uint8 ret;
|
uint8 ret;
|
||||||
|
|
||||||
ret=X.DB&~7;
|
ret=X.DB&~7;
|
||||||
if(InDisk==255)
|
if(InDisk==255)
|
||||||
ret|=5;
|
ret|=5;
|
||||||
|
|
||||||
if(InDisk==255 || !(FDSRegs[5]&1) || (FDSRegs[5]&2))
|
if(InDisk==255 || !(FDSRegs[5]&1) || (FDSRegs[5]&2))
|
||||||
ret|=2;
|
ret|=2;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -356,7 +371,7 @@ static DECLFW(FDSSWrite)
|
|||||||
A-=0x4080;
|
A-=0x4080;
|
||||||
switch(A)
|
switch(A)
|
||||||
{
|
{
|
||||||
case 0x0:
|
case 0x0:
|
||||||
case 0x4: if(V&0x80)
|
case 0x4: if(V&0x80)
|
||||||
amplitude[(A&0xF)>>2]=V&0x3F; //)>0x20?0x20:(V&0x3F);
|
amplitude[(A&0xF)>>2]=V&0x3F; //)>0x20?0x20:(V&0x3F);
|
||||||
break;
|
break;
|
||||||
@ -372,7 +387,7 @@ static DECLFW(FDSSWrite)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
//if(A>=0x7 && A!=0x8 && A<=0xF)
|
//if(A>=0x7 && A!=0x8 && A<=0xF)
|
||||||
//if(A==0xA || A==0x9)
|
//if(A==0xA || A==0x9)
|
||||||
//printf("$%04x:$%02x\n",A,V);
|
//printf("$%04x:$%02x\n",A,V);
|
||||||
SPSG[A]=V;
|
SPSG[A]=V;
|
||||||
}
|
}
|
||||||
@ -439,7 +454,7 @@ static INLINE void ClockRise(void)
|
|||||||
b19shiftreg60=(SPSG[0x2]|((SPSG[0x3]&0xF)<<8));
|
b19shiftreg60=(SPSG[0x2]|((SPSG[0x3]&0xF)<<8));
|
||||||
b17latch76=(SPSG[0x6]|((SPSG[0x07]&0xF)<<8))+b17latch76;
|
b17latch76=(SPSG[0x6]|((SPSG[0x07]&0xF)<<8))+b17latch76;
|
||||||
|
|
||||||
if(!(SPSG[0x7]&0x80))
|
if(!(SPSG[0x7]&0x80))
|
||||||
{
|
{
|
||||||
int t=fdso.mwave[(b17latch76>>13)&0x1F]&7;
|
int t=fdso.mwave[(b17latch76>>13)&0x1F]&7;
|
||||||
int t2=amplitude[1];
|
int t2=amplitude[1];
|
||||||
@ -459,13 +474,13 @@ static INLINE void ClockRise(void)
|
|||||||
b8shiftreg88=0x80 + adj;
|
b8shiftreg88=0x80 + adj;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
b8shiftreg88=0x80;
|
b8shiftreg88=0x80;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
b19shiftreg60<<=1;
|
b19shiftreg60<<=1;
|
||||||
b8shiftreg88>>=1;
|
b8shiftreg88>>=1;
|
||||||
}
|
}
|
||||||
// b24adder66=(b24latch68+b19shiftreg60)&0x3FFFFFF;
|
// b24adder66=(b24latch68+b19shiftreg60)&0x3FFFFFF;
|
||||||
@ -495,7 +510,7 @@ dogk:
|
|||||||
if(fdso.envcount<=0)
|
if(fdso.envcount<=0)
|
||||||
{
|
{
|
||||||
fdso.envcount+=SPSG[0xA]*3;
|
fdso.envcount+=SPSG[0xA]*3;
|
||||||
DoEnv();
|
DoEnv();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(fdso.count>=32768) goto dogk;
|
if(fdso.count>=32768) goto dogk;
|
||||||
@ -702,7 +717,7 @@ static int SubLoad(FCEUFILE *fp)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
TotalSides=header[4];
|
TotalSides=header[4];
|
||||||
|
|
||||||
@ -752,7 +767,7 @@ static void PostSave(void)
|
|||||||
|
|
||||||
for(b=0; b<65500; b++)
|
for(b=0; b<65500; b++)
|
||||||
diskdata[x][b] ^= diskdatao[x][b];
|
diskdata[x][b] ^= diskdatao[x][b];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -770,7 +785,7 @@ int FDSLoad(const char *name, FCEUFILE *fp)
|
|||||||
#ifndef GEKKO
|
#ifndef GEKKO
|
||||||
fn = strdup(FCEU_MakeFName(FCEUMKF_FDSROM,0,0).c_str());
|
fn = strdup(FCEU_MakeFName(FCEUMKF_FDSROM,0,0).c_str());
|
||||||
|
|
||||||
if(!(zp=FCEUD_UTF8fopen(fn,"rb")))
|
if(!(zp=FCEUD_UTF8fopen(fn,"rb")))
|
||||||
{
|
{
|
||||||
FCEU_PrintError("FDS BIOS ROM image missing!");
|
FCEU_PrintError("FDS BIOS ROM image missing!");
|
||||||
FreeFDSMemory();
|
FreeFDSMemory();
|
||||||
@ -830,7 +845,7 @@ if (!disableBatteryLoading)
|
|||||||
|
|
||||||
for(x=0;x<TotalSides;x++)
|
for(x=0;x<TotalSides;x++)
|
||||||
{
|
{
|
||||||
char temp[5];
|
char temp[5];
|
||||||
sprintf(temp,"DDT%d",x);
|
sprintf(temp,"DDT%d",x);
|
||||||
AddExState(diskdata[x],65500,0,temp);
|
AddExState(diskdata[x],65500,0,temp);
|
||||||
}
|
}
|
||||||
@ -882,7 +897,7 @@ void FDSClose(void)
|
|||||||
|
|
||||||
for(x=0;x<TotalSides;x++)
|
for(x=0;x<TotalSides;x++)
|
||||||
{
|
{
|
||||||
if(fwrite(diskdata[x],1,65500,fp)!=65500)
|
if(fwrite(diskdata[x],1,65500,fp)!=65500)
|
||||||
{
|
{
|
||||||
FCEU_PrintError("Error saving FDS image!");
|
FCEU_PrintError("Error saving FDS image!");
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
@ -36,7 +36,11 @@
|
|||||||
#include "utils/endian.h"
|
#include "utils/endian.h"
|
||||||
#include "utils/memory.h"
|
#include "utils/memory.h"
|
||||||
#include "utils/md5.h"
|
#include "utils/md5.h"
|
||||||
|
#ifdef GEKKO
|
||||||
#include "unzip.h"
|
#include "unzip.h"
|
||||||
|
#else
|
||||||
|
#include "utils/unzip.h"
|
||||||
|
#endif
|
||||||
#include "driver.h"
|
#include "driver.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "fceu.h"
|
#include "fceu.h"
|
||||||
@ -603,7 +607,7 @@ std::string FCEU_MakeFName(int type, int id1, const char *cd1)
|
|||||||
if(odirs[FCEUIOD_MOVIES])
|
if(odirs[FCEUIOD_MOVIES])
|
||||||
sprintf(ret,"%s"PSS"%s-%d.fm2",odirs[FCEUIOD_MOVIES],FileBase, id1);
|
sprintf(ret,"%s"PSS"%s-%d.fm2",odirs[FCEUIOD_MOVIES],FileBase, id1);
|
||||||
else
|
else
|
||||||
sprintf(ret,"%s"PSS"movie"PSS"%s-%d.fm2",BaseDirectory.c_str(),FileBase, id1);
|
sprintf(ret,"%s"PSS"movies"PSS"%s-%d.fm2",BaseDirectory.c_str(),FileBase, id1);
|
||||||
id1++;
|
id1++;
|
||||||
} while (stat(ret, &fileInfo) == 0);
|
} while (stat(ret, &fileInfo) == 0);
|
||||||
break;
|
break;
|
||||||
|
@ -14,11 +14,13 @@
|
|||||||
#include "palette.h"
|
#include "palette.h"
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "fceu.h"
|
#include "fceu.h"
|
||||||
|
#include "netplay.h"
|
||||||
#include "driver.h"
|
#include "driver.h"
|
||||||
#include "state.h"
|
#include "state.h"
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
#include "video.h"
|
#include "video.h"
|
||||||
#include "movie.h"
|
#include "movie.h"
|
||||||
|
#include "fds.h"
|
||||||
#ifdef _S9XLUA_H
|
#ifdef _S9XLUA_H
|
||||||
#include "fceulua.h"
|
#include "fceulua.h"
|
||||||
#endif
|
#endif
|
||||||
@ -972,7 +974,7 @@ void FCEUMOV_AddInputState()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
MovieRecord* mr = &currMovieData.records[currFrameCounter];
|
MovieRecord* mr = &currMovieData.records[currFrameCounter];
|
||||||
|
|
||||||
//reset and power cycle if necessary
|
//reset and power cycle if necessary
|
||||||
if(mr->command_power())
|
if(mr->command_power())
|
||||||
PowerNES();
|
PowerNES();
|
||||||
@ -980,6 +982,12 @@ void FCEUMOV_AddInputState()
|
|||||||
if(mr->command_reset())
|
if(mr->command_reset())
|
||||||
ResetNES();
|
ResetNES();
|
||||||
|
|
||||||
|
if(mr->command_fds_insert())
|
||||||
|
FCEU_FDSInsert();
|
||||||
|
|
||||||
|
if(mr->command_fds_select())
|
||||||
|
FCEU_FDSSelect();
|
||||||
|
|
||||||
joyports[0].load(mr);
|
joyports[0].load(mr);
|
||||||
joyports[1].load(mr);
|
joyports[1].load(mr);
|
||||||
}
|
}
|
||||||
@ -993,13 +1001,13 @@ void FCEUMOV_AddInputState()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//pause the movie at a specified frame
|
//pause the movie at a specified frame
|
||||||
if(FCEUMOV_ShouldPause() && FCEUI_EmulationPaused()==0)
|
if(FCEUMOV_ShouldPause() && FCEUI_EmulationPaused()==0)
|
||||||
{
|
{
|
||||||
FCEUI_ToggleEmulationPause();
|
FCEUI_ToggleEmulationPause();
|
||||||
FCEU_DispMessage("Paused at specified movie frame");
|
FCEU_DispMessage("Paused at specified movie frame");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else if(movieMode == MOVIEMODE_RECORD)
|
else if(movieMode == MOVIEMODE_RECORD)
|
||||||
{
|
{
|
||||||
@ -1033,6 +1041,11 @@ void FCEUMOV_AddCommand(int cmd)
|
|||||||
//NOTE: EMOVIECMD matches FCEUNPCMD_RESET and FCEUNPCMD_POWER
|
//NOTE: EMOVIECMD matches FCEUNPCMD_RESET and FCEUNPCMD_POWER
|
||||||
//we are lucky (well, I planned it that way)
|
//we are lucky (well, I planned it that way)
|
||||||
|
|
||||||
|
switch(cmd) {
|
||||||
|
case FCEUNPCMD_FDSINSERT: cmd = MOVIECMD_FDS_INSERT; break;
|
||||||
|
case FCEUNPCMD_FDSSELECT: cmd = MOVIECMD_FDS_SELECT; break;
|
||||||
|
}
|
||||||
|
|
||||||
_currCommand |= cmd;
|
_currCommand |= cmd;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -1485,4 +1498,4 @@ bool CheckFileExists(const char* filename)
|
|||||||
#else
|
#else
|
||||||
return false;
|
return false;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -65,6 +65,8 @@ enum EMOVIECMD
|
|||||||
{
|
{
|
||||||
MOVIECMD_RESET = 1,
|
MOVIECMD_RESET = 1,
|
||||||
MOVIECMD_POWER = 2,
|
MOVIECMD_POWER = 2,
|
||||||
|
MOVIECMD_FDS_INSERT = 4,
|
||||||
|
MOVIECMD_FDS_SELECT = 8
|
||||||
};
|
};
|
||||||
|
|
||||||
EMOVIEMODE FCEUMOV_Mode();
|
EMOVIEMODE FCEUMOV_Mode();
|
||||||
@ -104,6 +106,8 @@ public:
|
|||||||
uint8 commands;
|
uint8 commands;
|
||||||
bool command_reset() { return (commands&MOVIECMD_RESET)!=0; }
|
bool command_reset() { return (commands&MOVIECMD_RESET)!=0; }
|
||||||
bool command_power() { return (commands&MOVIECMD_POWER)!=0; }
|
bool command_power() { return (commands&MOVIECMD_POWER)!=0; }
|
||||||
|
bool command_fds_insert() { return (commands&MOVIECMD_FDS_INSERT)!=0; }
|
||||||
|
bool command_fds_select() { return (commands&MOVIECMD_FDS_SELECT)!=0; }
|
||||||
|
|
||||||
void toggleBit(int joy, int bit)
|
void toggleBit(int joy, int bit)
|
||||||
{
|
{
|
||||||
|
@ -109,15 +109,19 @@ static DECLFR(NSFROMRead)
|
|||||||
|
|
||||||
static int doreset=0;
|
static int doreset=0;
|
||||||
static int NSFNMIFlags;
|
static int NSFNMIFlags;
|
||||||
static uint8 *NSFDATA=0;
|
uint8 *NSFDATA=0;
|
||||||
static int NSFMaxBank;
|
int NSFMaxBank;
|
||||||
|
|
||||||
static int NSFSize;
|
static int NSFSize;
|
||||||
static uint8 BSon;
|
static uint8 BSon;
|
||||||
|
static uint8 BankCounter;
|
||||||
|
|
||||||
static uint16 PlayAddr;
|
static uint16 PlayAddr;
|
||||||
static uint16 InitAddr;
|
static uint16 InitAddr;
|
||||||
static uint16 LoadAddr;
|
static uint16 LoadAddr;
|
||||||
|
|
||||||
|
extern char LoadedRomFName[2048];
|
||||||
|
|
||||||
NSF_HEADER NSFHeader; //mbg merge 6/29/06 - needs to be global
|
NSF_HEADER NSFHeader; //mbg merge 6/29/06 - needs to be global
|
||||||
|
|
||||||
void NSFMMC5_Close(void);
|
void NSFMMC5_Close(void);
|
||||||
@ -156,11 +160,11 @@ static INLINE void BANKSET(uint32 A, uint32 bank)
|
|||||||
bank&=NSFMaxBank;
|
bank&=NSFMaxBank;
|
||||||
if(NSFHeader.SoundChip&4)
|
if(NSFHeader.SoundChip&4)
|
||||||
memcpy(ExWRAM+(A-0x6000),NSFDATA+(bank<<12),4096);
|
memcpy(ExWRAM+(A-0x6000),NSFDATA+(bank<<12),4096);
|
||||||
else
|
else
|
||||||
setprg4(A,bank);
|
setprg4(A,bank);
|
||||||
}
|
}
|
||||||
|
|
||||||
int NSFLoad(FCEUFILE *fp)
|
int NSFLoad(const char *name, FCEUFILE *fp)
|
||||||
{
|
{
|
||||||
int x;
|
int x;
|
||||||
#ifndef GEKKO
|
#ifndef GEKKO
|
||||||
@ -188,7 +192,7 @@ int NSFLoad(FCEUFILE *fp)
|
|||||||
NSFSize=FCEU_fgetsize(fp)-0x80;
|
NSFSize=FCEU_fgetsize(fp)-0x80;
|
||||||
|
|
||||||
NSFMaxBank=((NSFSize+(LoadAddr&0xfff)+4095)/4096);
|
NSFMaxBank=((NSFSize+(LoadAddr&0xfff)+4095)/4096);
|
||||||
NSFMaxBank=uppow2(NSFMaxBank);
|
NSFMaxBank=PRGsize[0]=uppow2(NSFMaxBank);
|
||||||
|
|
||||||
if(!(NSFDATA=(uint8 *)FCEU_malloc(NSFMaxBank*4096)))
|
if(!(NSFDATA=(uint8 *)FCEU_malloc(NSFMaxBank*4096)))
|
||||||
return 0;
|
return 0;
|
||||||
@ -200,6 +204,30 @@ int NSFLoad(FCEUFILE *fp)
|
|||||||
NSFMaxBank--;
|
NSFMaxBank--;
|
||||||
|
|
||||||
BSon=0;
|
BSon=0;
|
||||||
|
for(x=0;x<8;x++)
|
||||||
|
{
|
||||||
|
BSon|=NSFHeader.BankSwitch[x];
|
||||||
|
}
|
||||||
|
|
||||||
|
if(BSon==0)
|
||||||
|
{
|
||||||
|
BankCounter=0x00;
|
||||||
|
|
||||||
|
if ((NSFHeader.LoadAddressHigh & 0x70) >= 0x70)
|
||||||
|
{
|
||||||
|
//Ice Climber, and other F000 base address tunes need this
|
||||||
|
BSon=0xFF;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for(x=(NSFHeader.LoadAddressHigh & 0x70) / 0x10;x<8;x++)
|
||||||
|
{
|
||||||
|
NSFHeader.BankSwitch[x]=BankCounter;
|
||||||
|
BankCounter+=0x01;
|
||||||
|
}
|
||||||
|
BSon=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for(x=0;x<8;x++)
|
for(x=0;x<8;x++)
|
||||||
BSon|=NSFHeader.BankSwitch[x];
|
BSon|=NSFHeader.BankSwitch[x];
|
||||||
|
|
||||||
@ -226,6 +254,8 @@ int NSFLoad(FCEUFILE *fp)
|
|||||||
|
|
||||||
GameInterface=NSFGI;
|
GameInterface=NSFGI;
|
||||||
|
|
||||||
|
strcpy(LoadedRomFName,name);
|
||||||
|
|
||||||
FCEU_printf("NSF Loaded. File information:\n\n");
|
FCEU_printf("NSF Loaded. File information:\n\n");
|
||||||
FCEU_printf(" Name: %s\n Artist: %s\n Copyright: %s\n\n",NSFHeader.SongName,NSFHeader.Artist,NSFHeader.Copyright);
|
FCEU_printf(" Name: %s\n Artist: %s\n Copyright: %s\n\n",NSFHeader.SongName,NSFHeader.Artist,NSFHeader.Copyright);
|
||||||
if(NSFHeader.SoundChip)
|
if(NSFHeader.SoundChip)
|
||||||
@ -331,7 +361,7 @@ void NSF_init(void)
|
|||||||
SetReadHandler(0x3ff0,0x3fff,NSF_read);
|
SetReadHandler(0x3ff0,0x3fff,NSF_read);
|
||||||
|
|
||||||
|
|
||||||
if(NSFHeader.SoundChip&1) {
|
if(NSFHeader.SoundChip&1) {
|
||||||
NSFVRC6_Init();
|
NSFVRC6_Init();
|
||||||
} else if(NSFHeader.SoundChip&2) {
|
} else if(NSFHeader.SoundChip&2) {
|
||||||
NSFVRC7_Init();
|
NSFVRC7_Init();
|
||||||
@ -370,7 +400,7 @@ static DECLFW(NSF_write)
|
|||||||
A&=0xF;
|
A&=0xF;
|
||||||
BANKSET((A*4096),V);
|
BANKSET((A*4096),V);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static DECLFR(NSF_read)
|
static DECLFR(NSF_read)
|
||||||
@ -393,13 +423,13 @@ static DECLFR(NSF_read)
|
|||||||
BWrite[0x4000+x](0x4000+x,0);
|
BWrite[0x4000+x](0x4000+x,0);
|
||||||
BWrite[0x4015](0x4015,0xF);
|
BWrite[0x4015](0x4015,0xF);
|
||||||
|
|
||||||
if(NSFHeader.SoundChip&4)
|
if(NSFHeader.SoundChip&4)
|
||||||
{
|
{
|
||||||
BWrite[0x4017](0x4017,0xC0); /* FDS BIOS writes $C0 */
|
BWrite[0x4017](0x4017,0xC0); /* FDS BIOS writes $C0 */
|
||||||
BWrite[0x4089](0x4089,0x80);
|
BWrite[0x4089](0x4089,0x80);
|
||||||
BWrite[0x408A](0x408A,0xE8);
|
BWrite[0x408A](0x408A,0xE8);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
memset(ExWRAM,0x00,8192);
|
memset(ExWRAM,0x00,8192);
|
||||||
BWrite[0x4017](0x4017,0xC0);
|
BWrite[0x4017](0x4017,0xC0);
|
||||||
@ -453,8 +483,8 @@ void DrawNSF(uint8 *XBuf)
|
|||||||
y=142+((Bufpl[(x*l)>>8]*mul)>>14);
|
y=142+((Bufpl[(x*l)>>8]*mul)>>14);
|
||||||
if(y<240)
|
if(y<240)
|
||||||
XBuf[x+y*256]=3;
|
XBuf[x+y*256]=3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(special==1)
|
else if(special==1)
|
||||||
{
|
{
|
||||||
if(FSettings.SoundVolume)
|
if(FSettings.SoundVolume)
|
||||||
@ -493,7 +523,7 @@ void DrawNSF(uint8 *XBuf)
|
|||||||
n=120+r*sin(t);
|
n=120+r*sin(t);
|
||||||
|
|
||||||
if(m<256 && n<240)
|
if(m<256 && n<240)
|
||||||
XBuf[m+n*256]=3;
|
XBuf[m+n*256]=3;
|
||||||
|
|
||||||
}
|
}
|
||||||
for(x=128;x<256;x++)
|
for(x=128;x<256;x++)
|
||||||
@ -533,9 +563,9 @@ void DrawNSF(uint8 *XBuf)
|
|||||||
tmp=FCEU_GetJoyJoy();
|
tmp=FCEU_GetJoyJoy();
|
||||||
if((tmp&JOY_RIGHT) && !(last&JOY_RIGHT))
|
if((tmp&JOY_RIGHT) && !(last&JOY_RIGHT))
|
||||||
{
|
{
|
||||||
if(CurrentSong<NSFHeader.TotalSongs)
|
if(CurrentSong<NSFHeader.TotalSongs)
|
||||||
{
|
{
|
||||||
CurrentSong++;
|
CurrentSong++;
|
||||||
SongReload=0xFF;
|
SongReload=0xFF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,8 @@ typedef struct {
|
|||||||
void NSF_init(void);
|
void NSF_init(void);
|
||||||
void DrawNSF(uint8 *XBuf);
|
void DrawNSF(uint8 *XBuf);
|
||||||
extern NSF_HEADER NSFHeader; //mbg merge 6/29/06
|
extern NSF_HEADER NSFHeader; //mbg merge 6/29/06
|
||||||
|
extern uint8 *NSFDATA;
|
||||||
|
extern int NSFMaxBank;
|
||||||
void NSFDealloc(void);
|
void NSFDealloc(void);
|
||||||
void NSFDodo(void);
|
void NSFDodo(void);
|
||||||
void DoNSFFrame(void);
|
void DoNSFFrame(void);
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "driver.h"
|
#include "driver.h"
|
||||||
|
|
||||||
|
|
||||||
#define VBlankON (PPU[0]&0x80) //Generate VBlank NMI
|
#define VBlankON (PPU[0]&0x80) //Generate VBlank NMI
|
||||||
#define Sprite16 (PPU[0]&0x20) //Sprites 8x16/8x8
|
#define Sprite16 (PPU[0]&0x20) //Sprites 8x16/8x8
|
||||||
#define BGAdrHI (PPU[0]&0x10) //BG pattern adr $0000/$1000
|
#define BGAdrHI (PPU[0]&0x10) //BG pattern adr $0000/$1000
|
||||||
@ -68,7 +69,6 @@ static uint32 ppulut1[256];
|
|||||||
static uint32 ppulut2[256];
|
static uint32 ppulut2[256];
|
||||||
static uint32 ppulut3[128];
|
static uint32 ppulut3[128];
|
||||||
|
|
||||||
PPUPHASE ppuphase;
|
|
||||||
int test = 0;
|
int test = 0;
|
||||||
|
|
||||||
template<typename T, int BITS>
|
template<typename T, int BITS>
|
||||||
@ -102,45 +102,81 @@ BITREVLUT<uint8,8> bitrevlut;
|
|||||||
|
|
||||||
struct PPUSTATUS
|
struct PPUSTATUS
|
||||||
{
|
{
|
||||||
int sl;
|
int32 sl;
|
||||||
int cycle, end_cycle;
|
int32 cycle, end_cycle;
|
||||||
};
|
};
|
||||||
struct SPRITE_READ
|
struct SPRITE_READ
|
||||||
{
|
{
|
||||||
int num;
|
int32 num;
|
||||||
int count;
|
int32 count;
|
||||||
int fetch;
|
int32 fetch;
|
||||||
int found;
|
int32 found;
|
||||||
int found_pos[8];
|
int32 found_pos[8];
|
||||||
int ret;
|
int32 ret;
|
||||||
int last;
|
int32 last;
|
||||||
int mode;
|
int32 mode;
|
||||||
|
|
||||||
|
void reset() {
|
||||||
|
num = count = fetch = found = ret = last = mode = 0;
|
||||||
|
found_pos[0] = found_pos[1] = found_pos[2] = found_pos[3] = 0;
|
||||||
|
found_pos[4] = found_pos[5] = found_pos[6] = found_pos[7] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void start_scanline()
|
||||||
|
{
|
||||||
|
num = 1;
|
||||||
|
found = 0;
|
||||||
|
fetch = 1;
|
||||||
|
count = 0;
|
||||||
|
last = 64;
|
||||||
|
mode = 0;
|
||||||
|
found_pos[0] = found_pos[1] = found_pos[2] = found_pos[3] = 0;
|
||||||
|
found_pos[4] = found_pos[5] = found_pos[6] = found_pos[7] = 0;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
struct SPRITE_READ spr_read = { 0 };
|
|
||||||
|
//doesn't need to be savestated as it is just a reflection of the current position in the ppu loop
|
||||||
|
PPUPHASE ppuphase;
|
||||||
|
|
||||||
|
//this needs to be savestated since a game may be trying to read from this across vblanks
|
||||||
|
SPRITE_READ spr_read;
|
||||||
|
|
||||||
|
//definitely needs to be savestated
|
||||||
|
uint8 idleSynch = 1;
|
||||||
|
|
||||||
//uses the internal counters concept at http://nesdev.icequake.net/PPU%20addressing.txt
|
//uses the internal counters concept at http://nesdev.icequake.net/PPU%20addressing.txt
|
||||||
struct PPUREGS {
|
struct PPUREGS {
|
||||||
|
//normal clocked regs. as the game can interfere with these at any time, they need to be savestated
|
||||||
uint32 fv;//3
|
uint32 fv;//3
|
||||||
uint32 v;//1
|
uint32 v;//1
|
||||||
uint32 h;//1
|
uint32 h;//1
|
||||||
uint32 vt;//5
|
uint32 vt;//5
|
||||||
uint32 ht;//5
|
uint32 ht;//5
|
||||||
uint32 fh;//3
|
|
||||||
uint32 s;//1
|
|
||||||
uint32 par;//8
|
|
||||||
uint32 ar;//2
|
|
||||||
|
|
||||||
uint32 _fv, _v, _h, _vt, _ht;
|
|
||||||
|
|
||||||
struct PPUSTATUS status;
|
|
||||||
|
|
||||||
PPUREGS()
|
|
||||||
: fv(0), v(0), h(0), vt(0), ht(0), fh(0), s(0), par(0), ar(0)
|
|
||||||
, _fv(0), _v(0), _h(0), _vt(0), _ht(0)
|
|
||||||
{ status.cycle = 0; status.end_cycle = 341;
|
|
||||||
status.sl = 241;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
//temp unlatched regs (need savestating, can be written to at any time)
|
||||||
|
uint32 _fv, _v, _h, _vt, _ht;
|
||||||
|
|
||||||
|
//other regs that need savestating
|
||||||
|
uint32 fh;//3 (horz scroll)
|
||||||
|
uint32 s;//1 ($2000 bit 4: "Background pattern table address (0: $0000; 1: $1000)")
|
||||||
|
|
||||||
|
//other regs that don't need saving
|
||||||
|
uint32 par;//8 (sort of a hack, just stored in here, but not managed by this system)
|
||||||
|
|
||||||
|
//cached state data. these are always reset at the beginning of a frame and don't need saving
|
||||||
|
//but just to be safe, we're gonna save it
|
||||||
|
PPUSTATUS status;
|
||||||
|
|
||||||
|
void reset()
|
||||||
|
{
|
||||||
|
fv = v = h = vt = ht = 0;
|
||||||
|
fh = par = s = 0;
|
||||||
|
_fv = _v = _h = _vt = _ht = 0;
|
||||||
|
status.cycle = 0;
|
||||||
|
status.end_cycle = 341;
|
||||||
|
status.sl = 241;
|
||||||
|
}
|
||||||
|
|
||||||
void install_latches() {
|
void install_latches() {
|
||||||
fv = _fv;
|
fv = _fv;
|
||||||
v = _v;
|
v = _v;
|
||||||
@ -365,6 +401,8 @@ int FCEUPPU_GetAttr(int ntnum, int xt, int yt) {
|
|||||||
inline void FFCEUX_PPUWrite_Default(uint32 A, uint8 V) {
|
inline void FFCEUX_PPUWrite_Default(uint32 A, uint8 V) {
|
||||||
uint32 tmp = A;
|
uint32 tmp = A;
|
||||||
|
|
||||||
|
if(PPU_hook) PPU_hook(A);
|
||||||
|
|
||||||
if(tmp<0x2000)
|
if(tmp<0x2000)
|
||||||
{
|
{
|
||||||
if(PPUCHRRAM&(1<<(tmp>>10)))
|
if(PPUCHRRAM&(1<<(tmp>>10)))
|
||||||
@ -390,9 +428,11 @@ inline void FFCEUX_PPUWrite_Default(uint32 A, uint8 V) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 FFCEUX_PPURead_Default(uint32 A) {
|
uint8 FASTCALL FFCEUX_PPURead_Default(uint32 A) {
|
||||||
uint32 tmp = A;
|
uint32 tmp = A;
|
||||||
|
|
||||||
|
if(PPU_hook) PPU_hook(A);
|
||||||
|
|
||||||
if(tmp<0x2000)
|
if(tmp<0x2000)
|
||||||
{
|
{
|
||||||
return VPage[tmp>>10][tmp];
|
return VPage[tmp>>10][tmp];
|
||||||
@ -421,15 +461,10 @@ uint8 FFCEUX_PPURead_Default(uint32 A) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint8 (*FFCEUX_PPURead)(uint32 A) = 0;
|
uint8 (FASTCALL *FFCEUX_PPURead)(uint32 A) = 0;
|
||||||
void (*FFCEUX_PPUWrite)(uint32 A, uint8 V) = 0;
|
void (*FFCEUX_PPUWrite)(uint32 A, uint8 V) = 0;
|
||||||
|
|
||||||
#define CALL_PPUREAD(A) (FFCEUX_PPURead?FFCEUX_PPURead(A):(\
|
#define CALL_PPUREAD(A) (FFCEUX_PPURead(A))
|
||||||
((A)<0x2000)? \
|
|
||||||
VPage[(A)>>10][(A)] \
|
|
||||||
: vnapage[((A)>>10)&0x3][(A)&0x3FF] \
|
|
||||||
))
|
|
||||||
|
|
||||||
|
|
||||||
#define CALL_PPUWRITE(A,V) (FFCEUX_PPUWrite?FFCEUX_PPUWrite(A,V):FFCEUX_PPUWrite_Default(A,V))
|
#define CALL_PPUWRITE(A,V) (FFCEUX_PPUWrite?FFCEUX_PPUWrite(A,V):FFCEUX_PPUWrite_Default(A,V))
|
||||||
|
|
||||||
@ -1777,6 +1812,11 @@ void FCEUPPU_Init(void)
|
|||||||
makeppulut();
|
makeppulut();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PPU_ResetHooks()
|
||||||
|
{
|
||||||
|
FFCEUX_PPURead = FFCEUX_PPURead_Default;
|
||||||
|
}
|
||||||
|
|
||||||
void FCEUPPU_Reset(void)
|
void FCEUPPU_Reset(void)
|
||||||
{
|
{
|
||||||
VRAMBuffer=PPU[0]=PPU[1]=PPU_status=PPU[3]=0;
|
VRAMBuffer=PPU[0]=PPU[1]=PPU_status=PPU[3]=0;
|
||||||
@ -1786,7 +1826,11 @@ void FCEUPPU_Reset(void)
|
|||||||
vtoggle = 0;
|
vtoggle = 0;
|
||||||
ppudead = 2;
|
ppudead = 2;
|
||||||
kook = 0;
|
kook = 0;
|
||||||
|
idleSynch = 1;
|
||||||
// XOffset=0;
|
// XOffset=0;
|
||||||
|
|
||||||
|
ppur.reset();
|
||||||
|
spr_read.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FCEUPPU_Power(void)
|
void FCEUPPU_Power(void)
|
||||||
@ -1823,7 +1867,7 @@ void FCEUPPU_Power(void)
|
|||||||
|
|
||||||
int FCEUPPU_Loop(int skip)
|
int FCEUPPU_Loop(int skip)
|
||||||
{
|
{
|
||||||
if(newppu) {
|
if((newppu) && (GameInfo->type!=GIT_NSF)) {
|
||||||
int FCEUX_PPU_Loop(int skip);
|
int FCEUX_PPU_Loop(int skip);
|
||||||
return FCEUX_PPU_Loop(skip);
|
return FCEUX_PPU_Loop(skip);
|
||||||
}
|
}
|
||||||
@ -1988,6 +2032,41 @@ SFORMAT FCEUPPU_STATEINFO[]={
|
|||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
SFORMAT FCEU_NEWPPU_STATEINFO[] = {
|
||||||
|
{ &idleSynch, 1, "IDLS" },
|
||||||
|
{ &spr_read.num, 4|FCEUSTATE_RLSB, "SR_0" },
|
||||||
|
{ &spr_read.count, 4|FCEUSTATE_RLSB, "SR_1" },
|
||||||
|
{ &spr_read.fetch, 4|FCEUSTATE_RLSB, "SR_2" },
|
||||||
|
{ &spr_read.found, 4|FCEUSTATE_RLSB, "SR_3" },
|
||||||
|
{ &spr_read.found_pos[0], 4|FCEUSTATE_RLSB, "SRx0" },
|
||||||
|
{ &spr_read.found_pos[0], 4|FCEUSTATE_RLSB, "SRx1" },
|
||||||
|
{ &spr_read.found_pos[0], 4|FCEUSTATE_RLSB, "SRx2" },
|
||||||
|
{ &spr_read.found_pos[0], 4|FCEUSTATE_RLSB, "SRx3" },
|
||||||
|
{ &spr_read.found_pos[0], 4|FCEUSTATE_RLSB, "SRx4" },
|
||||||
|
{ &spr_read.found_pos[0], 4|FCEUSTATE_RLSB, "SRx5" },
|
||||||
|
{ &spr_read.found_pos[0], 4|FCEUSTATE_RLSB, "SRx6" },
|
||||||
|
{ &spr_read.found_pos[0], 4|FCEUSTATE_RLSB, "SRx7" },
|
||||||
|
{ &spr_read.ret, 4|FCEUSTATE_RLSB, "SR_4" },
|
||||||
|
{ &spr_read.last, 4|FCEUSTATE_RLSB, "SR_5" },
|
||||||
|
{ &spr_read.mode, 4|FCEUSTATE_RLSB, "SR_6" },
|
||||||
|
{ &ppur.fv, 4|FCEUSTATE_RLSB, "PFVx" },
|
||||||
|
{ &ppur.v, 4|FCEUSTATE_RLSB, "PVxx" },
|
||||||
|
{ &ppur.h, 4|FCEUSTATE_RLSB, "PHxx" },
|
||||||
|
{ &ppur.vt, 4|FCEUSTATE_RLSB, "PVTx" },
|
||||||
|
{ &ppur.ht, 4|FCEUSTATE_RLSB, "PHTx" },
|
||||||
|
{ &ppur._fv, 4|FCEUSTATE_RLSB, "P_FV" },
|
||||||
|
{ &ppur._v, 4|FCEUSTATE_RLSB, "P_Vx" },
|
||||||
|
{ &ppur._h, 4|FCEUSTATE_RLSB, "P_Hx" },
|
||||||
|
{ &ppur._vt, 4|FCEUSTATE_RLSB, "P_VT" },
|
||||||
|
{ &ppur._ht, 4|FCEUSTATE_RLSB, "P_HT" },
|
||||||
|
{ &ppur.fh, 4|FCEUSTATE_RLSB, "PFHx" },
|
||||||
|
{ &ppur.s, 4|FCEUSTATE_RLSB, "PSxx" },
|
||||||
|
{ &ppur.status.sl, 4|FCEUSTATE_RLSB, "PST0" },
|
||||||
|
{ &ppur.status.cycle, 4|FCEUSTATE_RLSB, "PST1" },
|
||||||
|
{ &ppur.status.end_cycle, 4|FCEUSTATE_RLSB, "PST2" },
|
||||||
|
{ 0 }
|
||||||
|
};
|
||||||
|
|
||||||
void FCEUPPU_SaveState(void)
|
void FCEUPPU_SaveState(void)
|
||||||
{
|
{
|
||||||
TempAddrT=TempAddr;
|
TempAddrT=TempAddr;
|
||||||
@ -2000,13 +2079,14 @@ int pputime=0;
|
|||||||
int totpputime=0;
|
int totpputime=0;
|
||||||
const int kLineTime=341;
|
const int kLineTime=341;
|
||||||
const int kFetchTime=2;
|
const int kFetchTime=2;
|
||||||
int idleSynch = 1;
|
|
||||||
|
|
||||||
void runppu(int x) {
|
void runppu(int x) {
|
||||||
//pputime+=x;
|
//pputime+=x;
|
||||||
//if(cputodo<200) return;
|
//if(cputodo<200) return;
|
||||||
|
|
||||||
ppur.status.cycle = (ppur.status.cycle + x) %
|
ppur.status.cycle = (ppur.status.cycle + x) %
|
||||||
ppur.status.end_cycle;
|
ppur.status.end_cycle;
|
||||||
|
|
||||||
X6502_Run(x);
|
X6502_Run(x);
|
||||||
//pputime -= cputodo<<2;
|
//pputime -= cputodo<<2;
|
||||||
}
|
}
|
||||||
@ -2016,7 +2096,7 @@ struct BGData {
|
|||||||
struct Record {
|
struct Record {
|
||||||
uint8 nt, at, pt[2];
|
uint8 nt, at, pt[2];
|
||||||
|
|
||||||
void Read() {
|
INLINE void Read() {
|
||||||
RefreshAddr = ppur.get_ntread();
|
RefreshAddr = ppur.get_ntread();
|
||||||
nt = CALL_PPUREAD(RefreshAddr);
|
nt = CALL_PPUREAD(RefreshAddr);
|
||||||
runppu(kFetchTime);
|
runppu(kFetchTime);
|
||||||
@ -2056,6 +2136,7 @@ struct BGData {
|
|||||||
|
|
||||||
int framectr=0;
|
int framectr=0;
|
||||||
int FCEUX_PPU_Loop(int skip) {
|
int FCEUX_PPU_Loop(int skip) {
|
||||||
|
|
||||||
//262 scanlines
|
//262 scanlines
|
||||||
if (ppudead)
|
if (ppudead)
|
||||||
{
|
{
|
||||||
@ -2071,7 +2152,7 @@ int FCEUX_PPU_Loop(int skip) {
|
|||||||
runppu(20*kLineTime);
|
runppu(20*kLineTime);
|
||||||
ppur.status.sl = 0;
|
ppur.status.sl = 0;
|
||||||
runppu(242*kLineTime);
|
runppu(242*kLineTime);
|
||||||
ppudead = 0;
|
--ppudead;
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2108,26 +2189,20 @@ int FCEUX_PPU_Loop(int skip) {
|
|||||||
//if(PPUON)
|
//if(PPUON)
|
||||||
// ppur.install_latches();
|
// ppur.install_latches();
|
||||||
|
|
||||||
uint8 oams[2][64][7];
|
static uint8 oams[2][64][8]; //[7] turned to [8] for faster indexing
|
||||||
int oamcounts[2]={0,0};
|
static int oamcounts[2]={0,0};
|
||||||
int oamslot=0;
|
static int oamslot=0;
|
||||||
int oamcount;
|
static int oamcount;
|
||||||
|
|
||||||
//capture the initial xscroll
|
//capture the initial xscroll
|
||||||
//int xscroll = ppur.fh;
|
//int xscroll = ppur.fh;
|
||||||
//render 241 scanlines (including 1 dummy at beginning)
|
//render 241 scanlines (including 1 dummy at beginning)
|
||||||
for(int sl=0;sl<241;sl++) {
|
for(int sl=0;sl<241;sl++) {
|
||||||
spr_read.num = 1;
|
spr_read.start_scanline();
|
||||||
spr_read.found = 0;
|
|
||||||
spr_read.fetch = 1;
|
|
||||||
spr_read.count = 0;
|
|
||||||
spr_read.last = 64;
|
|
||||||
spr_read.mode = 0;
|
|
||||||
memset(spr_read.found_pos, 0, sizeof(spr_read.found_pos));
|
|
||||||
|
|
||||||
ppur.status.sl = sl;
|
ppur.status.sl = sl;
|
||||||
|
|
||||||
int yp = sl-1;
|
const int yp = sl-1;
|
||||||
ppuphase = PPUPHASE_BG;
|
ppuphase = PPUPHASE_BG;
|
||||||
|
|
||||||
if(sl != 0) {
|
if(sl != 0) {
|
||||||
@ -2139,8 +2214,8 @@ int FCEUX_PPU_Loop(int skip) {
|
|||||||
|
|
||||||
|
|
||||||
//twiddle the oam buffers
|
//twiddle the oam buffers
|
||||||
int scanslot = oamslot^1;
|
const int scanslot = oamslot^1;
|
||||||
int renderslot = oamslot;
|
const int renderslot = oamslot;
|
||||||
oamslot ^= 1;
|
oamslot ^= 1;
|
||||||
|
|
||||||
oamcount = oamcounts[renderslot];
|
oamcount = oamcounts[renderslot];
|
||||||
@ -2151,25 +2226,26 @@ int FCEUX_PPU_Loop(int skip) {
|
|||||||
for(int xt=0;xt<32;xt++) {
|
for(int xt=0;xt<32;xt++) {
|
||||||
bgdata.main[xt+2].Read();
|
bgdata.main[xt+2].Read();
|
||||||
|
|
||||||
|
|
||||||
//ok, we're also going to draw here.
|
//ok, we're also going to draw here.
|
||||||
//unless we're on the first dummy scanline
|
//unless we're on the first dummy scanline
|
||||||
if(sl != 0) {
|
if(sl != 0) {
|
||||||
int xstart = xt<<3;
|
int xstart = xt<<3;
|
||||||
oamcount = oamcounts[renderslot];
|
oamcount = oamcounts[renderslot];
|
||||||
uint8 *target=XBuf+(yp<<8)+xstart;
|
uint8 * const target=XBuf+(yp<<8)+xstart;
|
||||||
uint8 *ptr = target;
|
uint8 *ptr = target;
|
||||||
int rasterpos = xstart;
|
int rasterpos = xstart;
|
||||||
|
|
||||||
//check all the conditions that can cause things to render in these 8px
|
//check all the conditions that can cause things to render in these 8px
|
||||||
bool renderspritenow = SpriteON && rendersprites && (xt>0 || SpriteLeft8);
|
const bool renderspritenow = SpriteON && rendersprites && (xt>0 || SpriteLeft8);
|
||||||
bool renderbgnow = ScreenON && renderbg && (xt>0 || BGLeft8);
|
const bool renderbgnow = ScreenON && renderbg && (xt>0 || BGLeft8);
|
||||||
for(int xp=0;xp<8;xp++,rasterpos++) {
|
for(int xp=0;xp<8;xp++,rasterpos++) {
|
||||||
|
|
||||||
//bg pos is different from raster pos due to its offsetability.
|
//bg pos is different from raster pos due to its offsetability.
|
||||||
//so adjust for that here
|
//so adjust for that here
|
||||||
int bgpos = rasterpos + ppur.fh;
|
const int bgpos = rasterpos + ppur.fh;
|
||||||
int bgpx = bgpos&7;
|
const int bgpx = bgpos&7;
|
||||||
int bgtile = bgpos>>3;
|
const int bgtile = bgpos>>3;
|
||||||
|
|
||||||
uint8 pixel=0, pixelcolor;
|
uint8 pixel=0, pixelcolor;
|
||||||
|
|
||||||
@ -2236,7 +2312,7 @@ int FCEUX_PPU_Loop(int skip) {
|
|||||||
//look for sprites (was supposed to run concurrent with bg rendering)
|
//look for sprites (was supposed to run concurrent with bg rendering)
|
||||||
oamcounts[scanslot] = 0;
|
oamcounts[scanslot] = 0;
|
||||||
oamcount=0;
|
oamcount=0;
|
||||||
int spriteHeight = Sprite16?16:8;
|
const int spriteHeight = Sprite16?16:8;
|
||||||
for(int i=0;i<64;i++) {
|
for(int i=0;i<64;i++) {
|
||||||
uint8* spr = SPRAM+i*4;
|
uint8* spr = SPRAM+i*4;
|
||||||
if(yp >= spr[0] && yp < spr[0]+spriteHeight) {
|
if(yp >= spr[0] && yp < spr[0]+spriteHeight) {
|
||||||
@ -2289,9 +2365,9 @@ int FCEUX_PPU_Loop(int skip) {
|
|||||||
//this is how we support the no 8 sprite limit feature.
|
//this is how we support the no 8 sprite limit feature.
|
||||||
//not that at some point we may need a virtual CALL_PPUREAD which just peeks and doesnt increment any counters
|
//not that at some point we may need a virtual CALL_PPUREAD which just peeks and doesnt increment any counters
|
||||||
//this could be handy for the debugging tools also
|
//this could be handy for the debugging tools also
|
||||||
bool realSprite = (s<8);
|
const bool realSprite = (s<8);
|
||||||
|
|
||||||
uint8* oam = oams[scanslot][s];
|
uint8* const oam = oams[scanslot][s];
|
||||||
uint32 line = yp - oam[0];
|
uint32 line = yp - oam[0];
|
||||||
if(oam[2]&0x80) //vflip
|
if(oam[2]&0x80) //vflip
|
||||||
line = spriteHeight-line-1;
|
line = spriteHeight-line-1;
|
||||||
|
@ -18,8 +18,17 @@ void FCEUPPU_SaveState(void);
|
|||||||
void FCEUPPU_LoadState(int version);
|
void FCEUPPU_LoadState(int version);
|
||||||
uint8* FCEUPPU_GetCHR(uint32 vadr, uint32 refreshaddr);
|
uint8* FCEUPPU_GetCHR(uint32 vadr, uint32 refreshaddr);
|
||||||
|
|
||||||
extern uint8 (*FFCEUX_PPURead)(uint32 A);
|
#ifdef _MSC_VER
|
||||||
|
#define FASTCALL __fastcall
|
||||||
|
#else
|
||||||
|
#define FASTCALL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void PPU_ResetHooks();
|
||||||
|
extern uint8 (FASTCALL *FFCEUX_PPURead)(uint32 A);
|
||||||
extern void (*FFCEUX_PPUWrite)(uint32 A, uint8 V);
|
extern void (*FFCEUX_PPUWrite)(uint32 A, uint8 V);
|
||||||
|
extern uint8 FASTCALL FFCEUX_PPURead_Default(uint32 A);
|
||||||
|
void FFCEUX_PPUWrite_Default(uint32 A, uint8 V);
|
||||||
|
|
||||||
extern int scanline;
|
extern int scanline;
|
||||||
extern uint8 PPU[4];
|
extern uint8 PPU[4];
|
||||||
|
@ -75,6 +75,7 @@ static int SFEXINDEX;
|
|||||||
|
|
||||||
|
|
||||||
extern SFORMAT FCEUPPU_STATEINFO[];
|
extern SFORMAT FCEUPPU_STATEINFO[];
|
||||||
|
extern SFORMAT FCEU_NEWPPU_STATEINFO[];
|
||||||
extern SFORMAT FCEUSND_STATEINFO[];
|
extern SFORMAT FCEUSND_STATEINFO[];
|
||||||
extern SFORMAT FCEUCTRL_STATEINFO[];
|
extern SFORMAT FCEUCTRL_STATEINFO[];
|
||||||
extern SFORMAT FCEUMOV_STATEINFO[];
|
extern SFORMAT FCEUMOV_STATEINFO[];
|
||||||
@ -248,6 +249,7 @@ static bool ReadStateChunks(std::istream* is, int32 totalsize)
|
|||||||
{
|
{
|
||||||
case 1:if(!ReadStateChunk(is,SFCPU,size)) ret=false;break;
|
case 1:if(!ReadStateChunk(is,SFCPU,size)) ret=false;break;
|
||||||
case 3:if(!ReadStateChunk(is,FCEUPPU_STATEINFO,size)) ret=false;break;
|
case 3:if(!ReadStateChunk(is,FCEUPPU_STATEINFO,size)) ret=false;break;
|
||||||
|
case 31:if(!ReadStateChunk(is,FCEU_NEWPPU_STATEINFO,size)) ret=false;break;
|
||||||
case 4:if(!ReadStateChunk(is,FCEUCTRL_STATEINFO,size)) ret=false;break;
|
case 4:if(!ReadStateChunk(is,FCEUCTRL_STATEINFO,size)) ret=false;break;
|
||||||
case 7:
|
case 7:
|
||||||
if(!FCEUMOV_ReadState(is,size)) {
|
if(!FCEUMOV_ReadState(is,size)) {
|
||||||
@ -355,6 +357,7 @@ bool FCEUSS_SaveMS(std::ostream* outstream, int compressionLevel)
|
|||||||
totalsize=WriteStateChunk(os,1,SFCPU);
|
totalsize=WriteStateChunk(os,1,SFCPU);
|
||||||
totalsize+=WriteStateChunk(os,2,SFCPUC);
|
totalsize+=WriteStateChunk(os,2,SFCPUC);
|
||||||
totalsize+=WriteStateChunk(os,3,FCEUPPU_STATEINFO);
|
totalsize+=WriteStateChunk(os,3,FCEUPPU_STATEINFO);
|
||||||
|
totalsize+=WriteStateChunk(os,31,FCEU_NEWPPU_STATEINFO);
|
||||||
totalsize+=WriteStateChunk(os,4,FCEUCTRL_STATEINFO);
|
totalsize+=WriteStateChunk(os,4,FCEUCTRL_STATEINFO);
|
||||||
totalsize+=WriteStateChunk(os,5,FCEUSND_STATEINFO);
|
totalsize+=WriteStateChunk(os,5,FCEUSND_STATEINFO);
|
||||||
if(FCEUMOV_Mode(MOVIEMODE_PLAY|MOVIEMODE_RECORD))
|
if(FCEUMOV_Mode(MOVIEMODE_PLAY|MOVIEMODE_RECORD))
|
||||||
@ -451,7 +454,7 @@ void FCEUSS_Save(const char *fname)
|
|||||||
fn = strdup(FCEU_MakeFName(FCEUMKF_STATE,CurrentState,0).c_str());
|
fn = strdup(FCEU_MakeFName(FCEUMKF_STATE,CurrentState,0).c_str());
|
||||||
|
|
||||||
//backup existing savestate first
|
//backup existing savestate first
|
||||||
if (CheckFileExists(fn))
|
if (CheckFileExists(fn))
|
||||||
{
|
{
|
||||||
CreateBackupSaveState(fn); //Make a backup of previous savestate before overwriting it
|
CreateBackupSaveState(fn); //Make a backup of previous savestate before overwriting it
|
||||||
strcpy(lastSavestateMade,fn); //Remember what the last savestate filename was (for undoing later)
|
strcpy(lastSavestateMade,fn); //Remember what the last savestate filename was (for undoing later)
|
||||||
@ -459,7 +462,7 @@ void FCEUSS_Save(const char *fname)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
undoSS = false; //so backup made so lastSavestateMade does have a backup file, so no undo
|
undoSS = false; //so backup made so lastSavestateMade does have a backup file, so no undo
|
||||||
|
|
||||||
st = FCEUD_UTF8_fstream(fn,"wb");
|
st = FCEUD_UTF8_fstream(fn,"wb");
|
||||||
free(fn);
|
free(fn);
|
||||||
}
|
}
|
||||||
@ -500,7 +503,7 @@ int FCEUSS_LoadFP_old(std::istream* is, ENUM_SSLOADPARAMS params)
|
|||||||
//{
|
//{
|
||||||
// fn=FCEU_MakeFName(FCEUMKF_NPTEMP,0,0);
|
// fn=FCEU_MakeFName(FCEUMKF_NPTEMP,0,0);
|
||||||
// FILE *fp;
|
// FILE *fp;
|
||||||
//
|
//
|
||||||
// if((fp=fopen(fn,"wb")))
|
// if((fp=fopen(fn,"wb")))
|
||||||
// {
|
// {
|
||||||
// if(FCEUSS_SaveFP(fp))
|
// if(FCEUSS_SaveFP(fp))
|
||||||
@ -555,7 +558,7 @@ int FCEUSS_LoadFP_old(std::istream* is, ENUM_SSLOADPARAMS params)
|
|||||||
if(x)
|
if(x)
|
||||||
{
|
{
|
||||||
FCEUPPU_LoadState(stateversion);
|
FCEUPPU_LoadState(stateversion);
|
||||||
FCEUSND_LoadState(stateversion);
|
FCEUSND_LoadState(stateversion);
|
||||||
x=FCEUMOV_PostLoad();
|
x=FCEUMOV_PostLoad();
|
||||||
}
|
}
|
||||||
if(fn)
|
if(fn)
|
||||||
@ -564,7 +567,7 @@ int FCEUSS_LoadFP_old(std::istream* is, ENUM_SSLOADPARAMS params)
|
|||||||
//{
|
//{
|
||||||
// * Oops! Load the temporary savestate */
|
// * Oops! Load the temporary savestate */
|
||||||
// FILE *fp;
|
// FILE *fp;
|
||||||
//
|
//
|
||||||
// if((fp=fopen(fn,"rb")))
|
// if((fp=fopen(fn,"rb")))
|
||||||
// {
|
// {
|
||||||
// FCEUSS_LoadFP(fp,SSLOADPARAM_NOBACKUP);
|
// FCEUSS_LoadFP(fp,SSLOADPARAM_NOBACKUP);
|
||||||
@ -600,7 +603,7 @@ bool FCEUSS_LoadFP(std::istream* is, ENUM_SSLOADPARAMS params)
|
|||||||
if(!ret && backup) FCEUSS_LoadFP(&msBackupSavestate,SSLOADPARAM_NOBACKUP);
|
if(!ret && backup) FCEUSS_LoadFP(&msBackupSavestate,SSLOADPARAM_NOBACKUP);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int totalsize = FCEU_de32lsb(header + 4);
|
int totalsize = FCEU_de32lsb(header + 4);
|
||||||
int stateversion = FCEU_de32lsb(header + 8);
|
int stateversion = FCEU_de32lsb(header + 8);
|
||||||
int comprlen = FCEU_de32lsb(header + 12);
|
int comprlen = FCEU_de32lsb(header + 12);
|
||||||
@ -752,8 +755,8 @@ void ResetExState(void (*PreSave)(void), void (*PostSave)(void))
|
|||||||
free(SFMDATA[x].desc);
|
free(SFMDATA[x].desc);
|
||||||
}
|
}
|
||||||
// adelikat, 3/14/09: had to add this to clear out the size parameter. NROM(mapper 0) games were having savestate crashes if loaded after a non NROM game because the size variable was carrying over and causing savestates to save too much data
|
// adelikat, 3/14/09: had to add this to clear out the size parameter. NROM(mapper 0) games were having savestate crashes if loaded after a non NROM game because the size variable was carrying over and causing savestates to save too much data
|
||||||
SFMDATA[0].s = 0;
|
SFMDATA[0].s = 0;
|
||||||
|
|
||||||
SPreSave = PreSave;
|
SPreSave = PreSave;
|
||||||
SPostSave = PostSave;
|
SPostSave = PostSave;
|
||||||
SFEXINDEX=0;
|
SFEXINDEX=0;
|
||||||
@ -814,7 +817,7 @@ void FCEUI_SaveState(const char *fname)
|
|||||||
if(!FCEU_IsValidUI(FCEUI_SAVESTATE)) return;
|
if(!FCEU_IsValidUI(FCEUI_SAVESTATE)) return;
|
||||||
|
|
||||||
StateShow=0;
|
StateShow=0;
|
||||||
|
|
||||||
FCEUSS_Save(fname);
|
FCEUSS_Save(fname);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -833,10 +836,10 @@ void FCEUI_LoadState(const char *fname)
|
|||||||
from this ;)).
|
from this ;)).
|
||||||
*/
|
*/
|
||||||
BackupLoadState(); //Backup the current state before loading a new one
|
BackupLoadState(); //Backup the current state before loading a new one
|
||||||
|
|
||||||
if (!movie_readonly && autoMovieBackup && freshMovie) //If auto-backup is on, movie has not been altered this session and the movie is in read+write mode
|
if (!movie_readonly && autoMovieBackup && freshMovie) //If auto-backup is on, movie has not been altered this session and the movie is in read+write mode
|
||||||
{
|
{
|
||||||
FCEUI_MakeBackupMovie(false); //Backup the movie before the contents get altered, but do not display messages
|
FCEUI_MakeBackupMovie(false); //Backup the movie before the contents get altered, but do not display messages
|
||||||
}
|
}
|
||||||
if(FCEUSS_Load(fname))
|
if(FCEUSS_Load(fname))
|
||||||
{
|
{
|
||||||
@ -890,8 +893,8 @@ string GenerateBackupSaveStateFn(const char *fname)
|
|||||||
string filename;
|
string filename;
|
||||||
filename = fname; //Convert fname to a string object
|
filename = fname; //Convert fname to a string object
|
||||||
int x = filename.find_last_of("."); //Find file extension
|
int x = filename.find_last_of("."); //Find file extension
|
||||||
filename.insert(x,"-bak"); //add "-bak" before the dot.
|
filename.insert(x,"-bak"); //add "-bak" before the dot.
|
||||||
|
|
||||||
return filename;
|
return filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -910,15 +913,15 @@ void SwapSaveState()
|
|||||||
//--------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------
|
||||||
//Both files must exist
|
//Both files must exist
|
||||||
//--------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
if (!lastSavestateMade)
|
if (!lastSavestateMade)
|
||||||
{
|
{
|
||||||
FCEUI_DispMessage("Can't Undo");
|
FCEUI_DispMessage("Can't Undo");
|
||||||
FCEUI_printf("Undo savestate was attempted but unsuccessful because there was not a recently used savestate.\n");
|
FCEUI_printf("Undo savestate was attempted but unsuccessful because there was not a recently used savestate.\n");
|
||||||
return; //If there is no last savestate, can't undo
|
return; //If there is no last savestate, can't undo
|
||||||
}
|
}
|
||||||
string backup = GenerateBackupSaveStateFn(lastSavestateMade); //Get filename of backup state
|
string backup = GenerateBackupSaveStateFn(lastSavestateMade); //Get filename of backup state
|
||||||
if (!CheckFileExists(backup.c_str()))
|
if (!CheckFileExists(backup.c_str()))
|
||||||
{
|
{
|
||||||
FCEUI_DispMessage("Can't Undo");
|
FCEUI_DispMessage("Can't Undo");
|
||||||
FCEUI_printf("Undo savestate was attempted but unsuccessful because there was not a backup of the last used savestate.\n");
|
FCEUI_printf("Undo savestate was attempted but unsuccessful because there was not a backup of the last used savestate.\n");
|
||||||
@ -930,11 +933,11 @@ void SwapSaveState()
|
|||||||
//--------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------
|
||||||
string temp = backup; //Put backup filename in temp
|
string temp = backup; //Put backup filename in temp
|
||||||
temp.append("x"); //Add x
|
temp.append("x"); //Add x
|
||||||
|
|
||||||
rename(backup.c_str(),temp.c_str()); //rename backup file to temp file
|
rename(backup.c_str(),temp.c_str()); //rename backup file to temp file
|
||||||
rename(lastSavestateMade,backup.c_str()); //rename current as backup
|
rename(lastSavestateMade,backup.c_str()); //rename current as backup
|
||||||
rename(temp.c_str(),lastSavestateMade); //rename backup as current
|
rename(temp.c_str(),lastSavestateMade); //rename backup as current
|
||||||
|
|
||||||
undoSS = true; //Just in case, if this was run, then there is definately a last savestate and backup
|
undoSS = true; //Just in case, if this was run, then there is definately a last savestate and backup
|
||||||
if (redoSS) //This was a redo function, so if run again it will be an undo again
|
if (redoSS) //This was a redo function, so if run again it will be an undo again
|
||||||
redoSS = false;
|
redoSS = false;
|
||||||
@ -943,8 +946,8 @@ void SwapSaveState()
|
|||||||
|
|
||||||
FCEUI_DispMessage("%s restored",backup.c_str());
|
FCEUI_DispMessage("%s restored",backup.c_str());
|
||||||
FCEUI_printf("%s restored\n",backup.c_str());
|
FCEUI_printf("%s restored\n",backup.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//Loadstate backup functions
|
//Loadstate backup functions
|
||||||
@ -957,7 +960,7 @@ string GetBackupFileName()
|
|||||||
//particularly from unintentional loadstating
|
//particularly from unintentional loadstating
|
||||||
string filename;
|
string filename;
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
filename = strdup(FCEU_MakeFName(FCEUMKF_STATE,CurrentState,0).c_str()); //Generate normal savestate filename
|
filename = strdup(FCEU_MakeFName(FCEUMKF_STATE,CurrentState,0).c_str()); //Generate normal savestate filename
|
||||||
x = filename.find_last_of("."); //Find last dot
|
x = filename.find_last_of("."); //Find last dot
|
||||||
filename = filename.substr(0,x); //Chop off file extension
|
filename = filename.substr(0,x); //Chop off file extension
|
||||||
@ -971,11 +974,11 @@ bool CheckBackupSaveStateExist()
|
|||||||
//This function simply checks to see if the backup loadstate exists, the backup loadstate is a special savestate
|
//This function simply checks to see if the backup loadstate exists, the backup loadstate is a special savestate
|
||||||
//That is made before loading any state, so that the user never loses his data
|
//That is made before loading any state, so that the user never loses his data
|
||||||
string filename = GetBackupFileName(); //Get backup savestate filename
|
string filename = GetBackupFileName(); //Get backup savestate filename
|
||||||
|
|
||||||
//Check if this filename exists
|
//Check if this filename exists
|
||||||
fstream test;
|
fstream test;
|
||||||
test.open(filename.c_str(),fstream::in);
|
test.open(filename.c_str(),fstream::in);
|
||||||
|
|
||||||
if (test.fail())
|
if (test.fail())
|
||||||
{
|
{
|
||||||
test.close();
|
test.close();
|
||||||
@ -1019,4 +1022,4 @@ void RedoLoadState()
|
|||||||
}
|
}
|
||||||
redoLS = false; //Flag that RedoLoadState can not be run again
|
redoLS = false; //Flag that RedoLoadState can not be run again
|
||||||
undoLS = true; //Flag that LoadBackup can be run again
|
undoLS = true; //Flag that LoadBackup can be run again
|
||||||
}
|
}
|
@ -23,8 +23,8 @@
|
|||||||
#define __FCEU_TYPES
|
#define __FCEU_TYPES
|
||||||
|
|
||||||
#define FCEU_NAME "FCEUX"
|
#define FCEU_NAME "FCEUX"
|
||||||
#define FCEU_VERSION_STRING "2.1.1-interim"
|
#define FCEU_VERSION_STRING "2.1.2-interim"
|
||||||
#define FCEU_VERSION_NUMERIC 20100
|
#define FCEU_VERSION_NUMERIC 21020
|
||||||
#define FCEU_NAME_AND_VERSION FCEU_NAME " " FCEU_VERSION_STRING
|
#define FCEU_NAME_AND_VERSION FCEU_NAME " " FCEU_VERSION_STRING
|
||||||
|
|
||||||
///causes the code fragment argument to be compiled in if the build includes debugging
|
///causes the code fragment argument to be compiled in if the build includes debugging
|
||||||
|
@ -81,7 +81,7 @@ int GCMemROM(int method, int size)
|
|||||||
delete fceumem;
|
delete fceumem;
|
||||||
fceumem = new memorystream((char *) nesrom, size);
|
fceumem = new memorystream((char *) nesrom, size);
|
||||||
fceufp->stream = fceumem;
|
fceufp->stream = fceumem;
|
||||||
romLoaded = NSFLoad(fceufp);
|
romLoaded = NSFLoad(romFilename, fceufp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!romLoaded)
|
if(!romLoaded)
|
||||||
|
@ -40,7 +40,7 @@ int AddCheatEntry(char *name, uint32 addr, uint8 val, int compare, int status, i
|
|||||||
extern int FDSLoad(const char *name, FCEUFILE *fp);
|
extern int FDSLoad(const char *name, FCEUFILE *fp);
|
||||||
extern int iNESLoad(const char *name, FCEUFILE *fp, int o);
|
extern int iNESLoad(const char *name, FCEUFILE *fp, int o);
|
||||||
extern int UNIFLoad(const char *name, FCEUFILE *fp);
|
extern int UNIFLoad(const char *name, FCEUFILE *fp);
|
||||||
extern int NSFLoad(FCEUFILE *fp);
|
extern int NSFLoad(const char *name, FCEUFILE *fp);
|
||||||
extern uint8 FDSBIOS[8192];
|
extern uint8 FDSBIOS[8192];
|
||||||
extern uint8 *GENIEROM;
|
extern uint8 *GENIEROM;
|
||||||
extern FCEUGI *GameInfo;
|
extern FCEUGI *GameInfo;
|
||||||
|
Loading…
Reference in New Issue
Block a user