Misc: Added "Remove sprite limit" option
This commit is contained in:
parent
ce34b517b1
commit
56d2580fbf
7 changed files with 64 additions and 13 deletions
|
@ -9,6 +9,7 @@ enum EmulationFlags
|
|||
ShowFPS = 0x02,
|
||||
VerticalSync = 0x04,
|
||||
AllowInvalidInput = 0x08,
|
||||
RemoveSpriteLimit = 0x10,
|
||||
|
||||
Mmc3IrqAltBehavior = 0x8000,
|
||||
};
|
||||
|
|
50
Core/PPU.cpp
50
Core/PPU.cpp
|
@ -439,13 +439,8 @@ void PPU::LoadTileInfo()
|
|||
}
|
||||
}
|
||||
|
||||
void PPU::LoadSpriteTileInfo()
|
||||
void PPU::LoadSprite(uint8_t spriteY, uint8_t tileIndex, uint8_t attributes, uint8_t spriteX, bool extraSprite)
|
||||
{
|
||||
uint32_t spriteAddr = _spriteIndex * 4;
|
||||
uint8_t spriteY = _secondarySpriteRAM[spriteAddr];
|
||||
uint8_t tileIndex = _secondarySpriteRAM[spriteAddr + 1];
|
||||
uint8_t attributes = _secondarySpriteRAM[spriteAddr + 2];
|
||||
uint8_t spriteX = _secondarySpriteRAM[spriteAddr + 3];
|
||||
bool backgroundPriority = (attributes & 0x20) == 0x20;
|
||||
bool horizontalMirror = (attributes & 0x40) == 0x40;
|
||||
bool verticalMirror = (attributes & 0x80) == 0x80;
|
||||
|
@ -464,17 +459,23 @@ void PPU::LoadSpriteTileInfo()
|
|||
tileAddr = ((tileIndex << 4) | _flags.SpritePatternAddr) + lineOffset;
|
||||
}
|
||||
|
||||
if(_spriteIndex < _spriteCount && spriteY < 240) {
|
||||
if((_spriteIndex < _spriteCount || extraSprite) && spriteY < 240) {
|
||||
_spriteTiles[_spriteIndex].BackgroundPriority = backgroundPriority;
|
||||
_spriteTiles[_spriteIndex].HorizontalMirror = horizontalMirror;
|
||||
_spriteTiles[_spriteIndex].VerticalMirror = verticalMirror;
|
||||
_spriteTiles[_spriteIndex].PaletteOffset = ((attributes & 0x03) << 2) | 0x10;
|
||||
_spriteTiles[_spriteIndex].LowByte = _memoryManager->ReadVRAM(tileAddr);
|
||||
_spriteTiles[_spriteIndex].HighByte = _memoryManager->ReadVRAM(tileAddr + 8);
|
||||
if(extraSprite) {
|
||||
//Use DebugReadVRAM for extra sprites to prevent most side-effects.
|
||||
_spriteTiles[_spriteIndex].LowByte = _memoryManager->DebugReadVRAM(tileAddr);
|
||||
_spriteTiles[_spriteIndex].HighByte = _memoryManager->DebugReadVRAM(tileAddr + 8);
|
||||
} else {
|
||||
_spriteTiles[_spriteIndex].LowByte = _memoryManager->ReadVRAM(tileAddr);
|
||||
_spriteTiles[_spriteIndex].HighByte = _memoryManager->ReadVRAM(tileAddr + 8);
|
||||
}
|
||||
_spriteTiles[_spriteIndex].TileAddr = tileAddr;
|
||||
_spriteTiles[_spriteIndex].OffsetY = lineOffset;
|
||||
_spriteTiles[_spriteIndex].SpriteX = spriteX;
|
||||
} else {
|
||||
} else if(!extraSprite) {
|
||||
//Fetches to sprite 0xFF for remaining sprites/hidden - used by MMC3 IRQ counter
|
||||
lineOffset = 0;
|
||||
tileIndex = 0xFF;
|
||||
|
@ -491,6 +492,25 @@ void PPU::LoadSpriteTileInfo()
|
|||
_spriteIndex++;
|
||||
}
|
||||
|
||||
void PPU::LoadExtraSprites()
|
||||
{
|
||||
if(_spriteCount == 8 && EmulationSettings::CheckFlag(EmulationFlags::RemoveSpriteLimit)) {
|
||||
for(uint32_t i = _overflowSpriteAddr; i < 0x100; i += 4) {
|
||||
uint8_t spriteY = _spriteRAM[i];
|
||||
if(_scanline >= spriteY && _scanline < spriteY + (_flags.LargeSprites ? 16 : 8)) {
|
||||
LoadSprite(spriteY, _spriteRAM[i + 1], _spriteRAM[i + 2], _spriteRAM[i + 3], true);
|
||||
_spriteCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PPU::LoadSpriteTileInfo()
|
||||
{
|
||||
uint8_t *spriteAddr = _secondarySpriteRAM + _spriteIndex * 4;
|
||||
LoadSprite(*spriteAddr, *(spriteAddr+1), *(spriteAddr+2), *(spriteAddr+3), false);
|
||||
}
|
||||
|
||||
void PPU::LoadNextTile()
|
||||
{
|
||||
_state.LowBitShift |= _nextTile.LowByte;
|
||||
|
@ -677,6 +697,7 @@ void PPU::CopyOAMData()
|
|||
_sprite0Added = false;
|
||||
_spriteInRange = false;
|
||||
_secondaryOAMAddr = 0;
|
||||
_overflowSpriteAddr = 0;
|
||||
|
||||
_oamCopyDone = false;
|
||||
_spriteAddrH = (_state.SpriteRamAddr >> 2) & 0x3F;
|
||||
|
@ -684,6 +705,8 @@ void PPU::CopyOAMData()
|
|||
} else if(_cycle == 256) {
|
||||
_sprite0Visible = _sprite0Added;
|
||||
_spriteCount = (_secondaryOAMAddr >> 2);
|
||||
|
||||
LoadExtraSprites();
|
||||
}
|
||||
|
||||
if(_cycle & 0x01) {
|
||||
|
@ -727,6 +750,11 @@ void PPU::CopyOAMData()
|
|||
}
|
||||
} else {
|
||||
//8 sprites have been found, check next sprite for overflow + emulate PPU bug
|
||||
if(_overflowSpriteAddr == 0) {
|
||||
//Used to remove sprite limit
|
||||
_overflowSpriteAddr = _spriteAddrH * 4;
|
||||
}
|
||||
|
||||
if(_spriteInRange) {
|
||||
//Sprite is visible, consider this to be an overflow
|
||||
_statusFlags.SpriteOverflow = true;
|
||||
|
@ -878,7 +906,7 @@ void PPU::StreamState(bool saving)
|
|||
Stream<uint8_t>(_previousTile.HighByte);
|
||||
Stream<uint32_t>(_previousTile.PaletteOffset);
|
||||
|
||||
for(int i = 0; i < 8; i++) {
|
||||
for(int i = 0; i < 64; i++) {
|
||||
Stream<uint8_t>(_spriteTiles[i].SpriteX);
|
||||
Stream<uint8_t>(_spriteTiles[i].LowByte);
|
||||
Stream<uint8_t>(_spriteTiles[i].HighByte);
|
||||
|
|
|
@ -123,11 +123,12 @@ class PPU : public IMemoryHandler, public Snapshotable
|
|||
TileInfo _nextTile;
|
||||
TileInfo _previousTile;
|
||||
|
||||
SpriteInfo _spriteTiles[8];
|
||||
SpriteInfo _spriteTiles[64];
|
||||
uint32_t _spriteCount = 0;
|
||||
uint32_t _secondaryOAMAddr = 0;
|
||||
bool _sprite0Visible = false;
|
||||
|
||||
uint32_t _overflowSpriteAddr = 0;
|
||||
uint32_t _spriteIndex = 0;
|
||||
|
||||
uint8_t _openBus = 0;
|
||||
|
@ -178,7 +179,9 @@ class PPU : public IMemoryHandler, public Snapshotable
|
|||
void WritePaletteRAM(uint16_t addr, uint8_t value);
|
||||
|
||||
void LoadTileInfo();
|
||||
void LoadSprite(uint8_t spriteY, uint8_t tileIndex, uint8_t attributes, uint8_t spriteX, bool extraSprite);
|
||||
void LoadSpriteTileInfo();
|
||||
void LoadExtraSprites();
|
||||
void ShiftTileRegisters();
|
||||
void InitializeShiftRegisters();
|
||||
void LoadNextTile();
|
||||
|
|
|
@ -17,6 +17,7 @@ namespace Mesen.GUI.Config
|
|||
public bool AutoLoadIpsPatches = true;
|
||||
public bool AssociateNesFiles = false;
|
||||
public bool AllowInvalidInput = false;
|
||||
public bool RemoveSpriteLimit = false;
|
||||
|
||||
public bool UseAlternativeMmc3Irq = false;
|
||||
|
||||
|
@ -40,6 +41,7 @@ namespace Mesen.GUI.Config
|
|||
|
||||
InteropEmu.SetFlag(EmulationFlags.Mmc3IrqAltBehavior, preferenceInfo.UseAlternativeMmc3Irq);
|
||||
InteropEmu.SetFlag(EmulationFlags.AllowInvalidInput, preferenceInfo.AllowInvalidInput);
|
||||
InteropEmu.SetFlag(EmulationFlags.RemoveSpriteLimit, preferenceInfo.RemoveSpriteLimit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
17
GUI.NET/Forms/Config/frmPreferences.Designer.cs
generated
17
GUI.NET/Forms/Config/frmPreferences.Designer.cs
generated
|
@ -47,6 +47,7 @@
|
|||
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.chkUseAlternativeMmc3Irq = new System.Windows.Forms.CheckBox();
|
||||
this.chkAllowInvalidInput = new System.Windows.Forms.CheckBox();
|
||||
this.chkRemoveSpriteLimit = new System.Windows.Forms.CheckBox();
|
||||
this.tlpMain.SuspendLayout();
|
||||
this.flowLayoutPanel6.SuspendLayout();
|
||||
this.tabMain.SuspendLayout();
|
||||
|
@ -273,10 +274,13 @@
|
|||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel1.Controls.Add(this.chkUseAlternativeMmc3Irq, 0, 0);
|
||||
this.tableLayoutPanel1.Controls.Add(this.chkAllowInvalidInput, 0, 1);
|
||||
this.tableLayoutPanel1.Controls.Add(this.chkRemoveSpriteLimit, 0, 2);
|
||||
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tableLayoutPanel1.Location = new System.Drawing.Point(3, 3);
|
||||
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
this.tableLayoutPanel1.RowCount = 2;
|
||||
this.tableLayoutPanel1.RowCount = 4;
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel1.Size = new System.Drawing.Size(380, 207);
|
||||
|
@ -302,6 +306,16 @@
|
|||
this.chkAllowInvalidInput.Text = "Allow invalid input (e.g Down + Up or Left + Right at the same time)";
|
||||
this.chkAllowInvalidInput.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// chkRemoveSpriteLimit
|
||||
//
|
||||
this.chkRemoveSpriteLimit.AutoSize = true;
|
||||
this.chkRemoveSpriteLimit.Location = new System.Drawing.Point(3, 49);
|
||||
this.chkRemoveSpriteLimit.Name = "chkRemoveSpriteLimit";
|
||||
this.chkRemoveSpriteLimit.Size = new System.Drawing.Size(205, 17);
|
||||
this.chkRemoveSpriteLimit.TabIndex = 2;
|
||||
this.chkRemoveSpriteLimit.Text = "Remove sprite limit (Reduces flashing)";
|
||||
this.chkRemoveSpriteLimit.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// frmPreferences
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
|
@ -352,5 +366,6 @@
|
|||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
|
||||
private System.Windows.Forms.CheckBox chkUseAlternativeMmc3Irq;
|
||||
private System.Windows.Forms.CheckBox chkAllowInvalidInput;
|
||||
private System.Windows.Forms.CheckBox chkRemoveSpriteLimit;
|
||||
}
|
||||
}
|
|
@ -25,6 +25,7 @@ namespace Mesen.GUI.Forms.Config
|
|||
|
||||
AddBinding("UseAlternativeMmc3Irq", chkUseAlternativeMmc3Irq);
|
||||
AddBinding("AllowInvalidInput", chkAllowInvalidInput);
|
||||
AddBinding("RemoveSpriteLimit", chkRemoveSpriteLimit);
|
||||
}
|
||||
|
||||
protected override void OnFormClosed(FormClosedEventArgs e)
|
||||
|
|
|
@ -432,6 +432,7 @@ namespace Mesen.GUI
|
|||
ShowFPS = 0x02,
|
||||
VerticalSync = 0x04,
|
||||
AllowInvalidInput = 0x08,
|
||||
RemoveSpriteLimit = 0x10,
|
||||
|
||||
Mmc3IrqAltBehavior = 0x8000,
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue