Skip to content

Commit

Permalink
- Optimized some register writes (fixes FF3 slow battle transition)
Browse files Browse the repository at this point in the history
  • Loading branch information
bubble2k16 committed Jan 19, 2017
1 parent 1eb8709 commit 0442558
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 11 deletions.
Binary file modified snes9x_3ds.3dsx
Binary file not shown.
4 changes: 2 additions & 2 deletions source/3dssnes9x.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
// Uncomment this to convert before releasing this to remove
// all the debugging stuff.
//
//#define RELEASE
#define RELEASE

// Uncomment this to use 2 point geometry shaders on a real 3DS.
//
//#define RELEASE_SHADER
#define RELEASE_SHADER

// Uncomment this to allow user to break into debug mode (for the 65816 CPU)
//
Expand Down
30 changes: 30 additions & 0 deletions source/cpuexec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,35 @@ void S9xDoHBlankProcessing ()
//APU_EXECUTE();
//t3dsEndTiming(21);

static const int addr[] = { 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31 };

// Optimization, for a small number of PPU registers,
// we will trigger the FLUSH_REDRAW here instead of
// us doing it when the register values change. This is
// because some games like FF3 and Ace o Nerae changes
// the registers multiple times in the same scanline,
// even though the end value is the same by the end of
// the scanline. But because they modify the registers,
// the rendering is forced to do a FLUSH_REDRAW.
//
// In this optimization, we simply defer the FLUSH_REDRAW
// until this point here and only when we determine that
// at least one of the registers have changed from the
// value in the previous scanline.
//
for (int i = 0; i < sizeof(addr) / sizeof(int); i++)
{
int a = addr[i];
if (IPPU.DeferredRegisterWrite[a] != 0xff00 &&
IPPU.DeferredRegisterWrite[a] != Memory.FillRAM[a + 0x2100])
{
DEBUG_FLUSH_REDRAW(a + 0x2100, IPPU.DeferredRegisterWrite[a]);
FLUSH_REDRAW();
Memory.FillRAM[a + 0x2100] = IPPU.DeferredRegisterWrite[a];
}
IPPU.DeferredRegisterWrite[a] = 0xff00;
}

#ifndef STORM
if (Settings.SoundSync)
S9xGenerateSound ();
Expand Down Expand Up @@ -583,6 +612,7 @@ void S9xDoHBlankProcessing ()
CPU.Flags &= ~NMI_FLAG;
S9xStartScreenRefresh ();
}

if (CPU.V_Counter >= FIRST_VISIBLE_LINE &&
CPU.V_Counter < PPU.ScreenHeight + FIRST_VISIBLE_LINE)
{
Expand Down
72 changes: 65 additions & 7 deletions source/ppu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -767,16 +767,33 @@ void S9xSetPPU (uint8 Byte, uint16 Address)
break;
case 0x212c:
// Main screen designation (backgrounds 1 - 4 and objects)

// Defer the write. This is ok since the read of this register
// returns the Open Bus value.
//
IPPU.DeferredRegisterWrite[Address - 0x2100] = Byte;
return;

/*
if (Byte != Memory.FillRAM [0x212c])
{
DEBUG_FLUSH_REDRAW(Address, Byte); FLUSH_REDRAW ();
PPU.RecomputeClipWindows = TRUE;
Memory.FillRAM [Address] = Byte;
return;
}
break;
break;*/

case 0x212d:
// Sub-screen designation (backgrounds 1 - 4 and objects)

// Defer the write. This is ok since the read of this register
// returns the Open Bus value.
//
IPPU.DeferredRegisterWrite[Address - 0x2100] = Byte;
return;

/*
if (Byte != Memory.FillRAM [0x212d])
{
DEBUG_FLUSH_REDRAW(Address, Byte); FLUSH_REDRAW ();
Expand All @@ -788,25 +805,52 @@ void S9xSetPPU (uint8 Byte, uint16 Address)
Memory.FillRAM [Address] = Byte;
return;
}
break;
break;*/

case 0x212e:
// Window mask designation for main screen ?

// Defer the write. This is ok since the read of this register
// returns the Open Bus value.
//
IPPU.DeferredRegisterWrite[Address - 0x2100] = Byte;
return;

/*
if (Byte != Memory.FillRAM [0x212e])
{
DEBUG_FLUSH_REDRAW(Address, Byte); FLUSH_REDRAW ();
PPU.RecomputeClipWindows = TRUE;
}
break;
break;*/

case 0x212f:
// Window mask designation for sub-screen ?

// Defer the write. This is ok since the read of this register
// returns the Open Bus value.
//
IPPU.DeferredRegisterWrite[Address - 0x2100] = Byte;
return;

/*
if (Byte != Memory.FillRAM [0x212f])
{
DEBUG_FLUSH_REDRAW(Address, Byte); FLUSH_REDRAW ();
PPU.RecomputeClipWindows = TRUE;
}
break;
break;*/

case 0x2130:
// Fixed colour addition or screen addition

// Defer the write. This is ok since the read of this register
// returns the Open Bus value.
//
IPPU.DeferredRegisterWrite[Address - 0x2100] = Byte;
return;

/*
if (Byte != Memory.FillRAM [0x2130])
{
DEBUG_FLUSH_REDRAW(Address, Byte); FLUSH_REDRAW ();
Expand All @@ -816,9 +860,18 @@ void S9xSetPPU (uint8 Byte, uint16 Address)
missing.direct = 1;
#endif
}
break;
break;*/

case 0x2131:
// Colour addition or subtraction select

// Defer the write. This is ok since the read of this register
// returns the Open Bus value.
//
IPPU.DeferredRegisterWrite[Address - 0x2100] = Byte;
return;

/*
if (Byte != Memory.FillRAM[0x2131])
{
DEBUG_FLUSH_REDRAW(Address, Byte); FLUSH_REDRAW ();
Expand All @@ -843,7 +896,7 @@ void S9xSetPPU (uint8 Byte, uint16 Address)
#endif
Memory.FillRAM[0x2131] = Byte;
}
break;
break; */
case 0x2132:
if (Byte != Memory.FillRAM [0x2132])
{
Expand Down Expand Up @@ -2711,8 +2764,10 @@ void S9xResetPPU ()

Memory.FillRAM[0x4201]=Memory.FillRAM[0x4213]=0xFF;

for (int i = 0; i < 0x100; i++)
IPPU.DeferredRegisterWrite[i] = 0xff00;

S9xInitializeVerticalSections();

}


Expand Down Expand Up @@ -2920,6 +2975,9 @@ void S9xSoftResetPPU ()

Memory.FillRAM[0x4201]=Memory.FillRAM[0x4213]=0xFF;

for (int i = 0; i < 0x100; i++)
IPPU.DeferredRegisterWrite[i] = 0xff00;

S9xInitializeVerticalSections();
}

Expand Down
18 changes: 16 additions & 2 deletions source/ppu.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,11 @@ struct InternalPPU {
VerticalSections WindowLRSections; // W1/W2 Left/Right

int HiresFlip;

// Added for register change optimization.
// Helps in reducing number of FLUSH_REDRAWs per frame.
//
int DeferredRegisterWrite[0x100];
};

struct SOBJ
Expand Down Expand Up @@ -297,6 +302,7 @@ struct SPPU {
// Added for OBJ drawing optimization
//
int PriorityDrawFromSprite = -1;

};

#define CLIP_OR 0
Expand Down Expand Up @@ -373,6 +379,8 @@ END_EXTERN_C
#define MAX_5A22_VERSION 0x02


//#define DEBUG_FLUSH_REDRAW(a,b) if (IPPU.PreviousLine != IPPU.CurrentLine && IPPU.RenderThisFrame) { printf ("FD: %04x <- %02x @ Y=%d\n", a, b, IPPU.CurrentLine); } else { printf (" %04x <- %02x @ Y=%d\n", a, b, IPPU.CurrentLine); }
#define DEBUG_FLUSH_REDRAW(a,b)

STATIC inline uint8 REGISTER_4212()
{
Expand Down Expand Up @@ -405,7 +413,7 @@ STATIC inline void REGISTER_2104 (uint8 byte)
{
int addr = ((PPU.OAMAddr & 0x10f) << 1) + (PPU.OAMFlip & 1);
if (byte != PPU.OAMData [addr]){
FLUSH_REDRAW ();
DEBUG_FLUSH_REDRAW(0x2104, byte); FLUSH_REDRAW ();
PPU.OAMData [addr] = byte;
IPPU.OBJChanged = TRUE;

Expand Down Expand Up @@ -449,7 +457,7 @@ STATIC inline void REGISTER_2104 (uint8 byte)
if (lowbyte != PPU.OAMData [addr] ||
highbyte != PPU.OAMData [addr+1])
{
FLUSH_REDRAW ();
DEBUG_FLUSH_REDRAW(0x2104, byte); FLUSH_REDRAW ();
PPU.OAMData [addr] = lowbyte;
PPU.OAMData [addr+1] = highbyte;
IPPU.OBJChanged = TRUE;
Expand Down Expand Up @@ -821,7 +829,10 @@ STATIC inline void REGISTER_2122(uint8 Byte)
// printf ("FLUSH_REDRAW palette @ Y=%d\n", IPPU.CurrentLine);
#endif
if (PPU.CGADD != 0)
{
DEBUG_FLUSH_REDRAW(0x2122, Byte);
FLUSH_REDRAW ();
}
}
PPU.CGDATA[PPU.CGADD] &= 0x00FF;
PPU.CGDATA[PPU.CGADD] |= (Byte & 0x7f) << 8;
Expand Down Expand Up @@ -868,7 +879,10 @@ STATIC inline void REGISTER_2122(uint8 Byte)
// printf ("FLUSH_REDRAW palette @ Y=%d\n", IPPU.CurrentLine);
#endif
if (PPU.CGADD != 0)
{
DEBUG_FLUSH_REDRAW(0x2122, Byte);
FLUSH_REDRAW ();
}
}
PPU.CGDATA[PPU.CGADD] &= 0x7F00;
PPU.CGDATA[PPU.CGADD] |= Byte;
Expand Down

0 comments on commit 0442558

Please sign in to comment.