diff --git a/Assets/dll/bsnes.wbx.zst b/Assets/dll/bsnes.wbx.zst
index 5a756f77af..f9859e7b53 100644
Binary files a/Assets/dll/bsnes.wbx.zst and b/Assets/dll/bsnes.wbx.zst differ
diff --git a/src/BizHawk.Client.EmuHawk/config/SNES/BSNESOptions.Designer.cs b/src/BizHawk.Client.EmuHawk/config/SNES/BSNESOptions.Designer.cs
index fb876b63ff..fe288acb4c 100644
--- a/src/BizHawk.Client.EmuHawk/config/SNES/BSNESOptions.Designer.cs
+++ b/src/BizHawk.Client.EmuHawk/config/SNES/BSNESOptions.Designer.cs
@@ -1,32 +1,32 @@
-namespace BizHawk.Client.EmuHawk
-{
- partial class BSNESOptions
+namespace BizHawk.Client.EmuHawk
+{
+ partial class BSNESOptions
{
- ///
- /// Required designer variable.
- ///
+ ///
+ /// Required designer variable.
+ ///
private System.ComponentModel.IContainer components = null;
- ///
- /// Clean up any resources being used.
- ///
- /// true if managed resources should be disposed; otherwise, false.
- protected override void Dispose(bool disposing)
- {
- if (disposing && (components != null))
- {
- components.Dispose();
- }
- base.Dispose(disposing);
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
}
- #region Windows Form Designer generated code
+ #region Windows Form Designer generated code
- ///
- /// Required method for Designer support - do not modify
- /// the contents of this method with the code editor.
- ///
- private void InitializeComponent()
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
{
this.btnOk = new System.Windows.Forms.Button();
this.btnCancel = new System.Windows.Forms.Button();
@@ -57,6 +57,7 @@
this.cbUseSGB2 = new System.Windows.Forms.CheckBox();
this.cbFastDSP = new System.Windows.Forms.CheckBox();
this.cbFastCoprocessor = new System.Windows.Forms.CheckBox();
+ this.cbNoPPUSpriteLimit = new System.Windows.Forms.CheckBox();
this.groupBox1.SuspendLayout();
this.SuspendLayout();
//
@@ -86,7 +87,7 @@
// cbDoubleSize
//
this.cbDoubleSize.AutoSize = true;
- this.cbDoubleSize.Location = new System.Drawing.Point(18, 16);
+ this.cbDoubleSize.Location = new System.Drawing.Point(16, 16);
this.cbDoubleSize.Name = "cbDoubleSize";
this.cbDoubleSize.Size = new System.Drawing.Size(178, 17);
this.cbDoubleSize.TabIndex = 6;
@@ -95,7 +96,7 @@
//
// lblDoubleSize
//
- this.lblDoubleSize.Location = new System.Drawing.Point(33, 34);
+ this.lblDoubleSize.Location = new System.Drawing.Point(31, 33);
this.lblDoubleSize.MaximumSize = new System.Drawing.Size(260, 0);
this.lblDoubleSize.Name = "lblDoubleSize";
this.lblDoubleSize.Text = "Some games are changing the resolution constantly (e.g. SD3) so this option can f" +
@@ -269,14 +270,14 @@
"None",
"Low",
"High"});
- this.EntropyBox.Location = new System.Drawing.Point(18, 173);
+ this.EntropyBox.Location = new System.Drawing.Point(16, 175);
this.EntropyBox.Name = "EntropyBox";
this.EntropyBox.Size = new System.Drawing.Size(128, 21);
this.EntropyBox.TabIndex = 14;
//
// lblEntropy
//
- this.lblEntropy.Location = new System.Drawing.Point(15, 157);
+ this.lblEntropy.Location = new System.Drawing.Point(13, 159);
this.lblEntropy.Name = "lblEntropy";
this.lblEntropy.Text = "Entropy";
//
@@ -288,21 +289,21 @@
"Auto",
"NTSC",
"PAL"});
- this.RegionBox.Location = new System.Drawing.Point(159, 173);
+ this.RegionBox.Location = new System.Drawing.Point(161, 175);
this.RegionBox.Name = "RegionBox";
this.RegionBox.Size = new System.Drawing.Size(128, 21);
this.RegionBox.TabIndex = 15;
//
// lblRegion
//
- this.lblRegion.Location = new System.Drawing.Point(156, 157);
+ this.lblRegion.Location = new System.Drawing.Point(158, 159);
this.lblRegion.Name = "lblRegion";
this.lblRegion.Text = "Region";
//
// cbGameHotfixes
//
this.cbGameHotfixes.AutoSize = true;
- this.cbGameHotfixes.Location = new System.Drawing.Point(18, 107);
+ this.cbGameHotfixes.Location = new System.Drawing.Point(16, 112);
this.cbGameHotfixes.Name = "cbGameHotfixes";
this.cbGameHotfixes.Size = new System.Drawing.Size(93, 17);
this.cbGameHotfixes.TabIndex = 22;
@@ -312,7 +313,7 @@
// cbFastPPU
//
this.cbFastPPU.AutoSize = true;
- this.cbFastPPU.Location = new System.Drawing.Point(159, 107);
+ this.cbFastPPU.Location = new System.Drawing.Point(161, 112);
this.cbFastPPU.Name = "cbFastPPU";
this.cbFastPPU.Size = new System.Drawing.Size(90, 17);
this.cbFastPPU.TabIndex = 23;
@@ -323,7 +324,7 @@
// cbCropSGBFrame
//
this.cbCropSGBFrame.AutoSize = true;
- this.cbCropSGBFrame.Location = new System.Drawing.Point(18, 84);
+ this.cbCropSGBFrame.Location = new System.Drawing.Point(16, 89);
this.cbCropSGBFrame.Name = "cbCropSGBFrame";
this.cbCropSGBFrame.Size = new System.Drawing.Size(105, 17);
this.cbCropSGBFrame.TabIndex = 27;
@@ -333,7 +334,7 @@
// cbUseSGB2
//
this.cbUseSGB2.AutoSize = true;
- this.cbUseSGB2.Location = new System.Drawing.Point(159, 84);
+ this.cbUseSGB2.Location = new System.Drawing.Point(161, 89);
this.cbUseSGB2.Name = "cbUseSGB2";
this.cbUseSGB2.Size = new System.Drawing.Size(76, 17);
this.cbUseSGB2.TabIndex = 30;
@@ -343,7 +344,7 @@
// cbFastDSP
//
this.cbFastDSP.AutoSize = true;
- this.cbFastDSP.Location = new System.Drawing.Point(18, 130);
+ this.cbFastDSP.Location = new System.Drawing.Point(16, 135);
this.cbFastDSP.Name = "cbFastDSP";
this.cbFastDSP.Size = new System.Drawing.Size(101, 17);
this.cbFastDSP.TabIndex = 34;
@@ -353,13 +354,23 @@
// cbFastCoprocessor
//
this.cbFastCoprocessor.AutoSize = true;
- this.cbFastCoprocessor.Location = new System.Drawing.Point(159, 130);
+ this.cbFastCoprocessor.Location = new System.Drawing.Point(161, 135);
this.cbFastCoprocessor.Name = "cbFastCoprocessor";
this.cbFastCoprocessor.Size = new System.Drawing.Size(138, 17);
this.cbFastCoprocessor.TabIndex = 35;
this.cbFastCoprocessor.Text = "Coprocessor Fast Mode";
this.cbFastCoprocessor.UseVisualStyleBackColor = true;
//
+ // cbPPUNoSpriteLimit
+ //
+ this.cbNoPPUSpriteLimit.AutoSize = true;
+ this.cbNoPPUSpriteLimit.Location = new System.Drawing.Point(161, 66);
+ this.cbNoPPUSpriteLimit.Name = "cbNoPPUSpriteLimit";
+ this.cbNoPPUSpriteLimit.Size = new System.Drawing.Size(113, 17);
+ this.cbNoPPUSpriteLimit.TabIndex = 39;
+ this.cbNoPPUSpriteLimit.Text = "No PPU sprite limit";
+ this.cbNoPPUSpriteLimit.UseVisualStyleBackColor = true;
+ //
// BSNESOptions
//
this.AcceptButton = this.btnOk;
@@ -367,6 +378,7 @@
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this.btnCancel;
this.ClientSize = new System.Drawing.Size(304, 379);
+ this.Controls.Add(this.cbNoPPUSpriteLimit);
this.Controls.Add(this.cbFastCoprocessor);
this.Controls.Add(this.cbFastDSP);
this.Controls.Add(this.cbUseSGB2);
@@ -396,36 +408,37 @@
}
- #endregion
+ #endregion
- private System.Windows.Forms.Button btnOk;
- private System.Windows.Forms.Button btnCancel;
- private System.Windows.Forms.CheckBox cbDoubleSize;
- private BizHawk.WinForms.Controls.LocLabelEx lblDoubleSize;
- private System.Windows.Forms.GroupBox groupBox1;
- private System.Windows.Forms.CheckBox Bg4_1Checkbox;
- private System.Windows.Forms.CheckBox Bg3_1Checkbox;
- private System.Windows.Forms.CheckBox Bg2_1Checkbox;
- private System.Windows.Forms.CheckBox Bg1_1Checkbox;
- private System.Windows.Forms.CheckBox Obj4Checkbox;
- private System.Windows.Forms.CheckBox Obj3Checkbox;
- private System.Windows.Forms.CheckBox Obj2Checkbox;
- private System.Windows.Forms.CheckBox Obj1Checkbox;
- private System.Windows.Forms.ComboBox EntropyBox;
+ private System.Windows.Forms.Button btnOk;
+ private System.Windows.Forms.Button btnCancel;
+ private System.Windows.Forms.CheckBox cbDoubleSize;
+ private BizHawk.WinForms.Controls.LocLabelEx lblDoubleSize;
+ private System.Windows.Forms.GroupBox groupBox1;
+ private System.Windows.Forms.CheckBox Bg4_1Checkbox;
+ private System.Windows.Forms.CheckBox Bg3_1Checkbox;
+ private System.Windows.Forms.CheckBox Bg2_1Checkbox;
+ private System.Windows.Forms.CheckBox Bg1_1Checkbox;
+ private System.Windows.Forms.CheckBox Obj4Checkbox;
+ private System.Windows.Forms.CheckBox Obj3Checkbox;
+ private System.Windows.Forms.CheckBox Obj2Checkbox;
+ private System.Windows.Forms.CheckBox Obj1Checkbox;
+ private System.Windows.Forms.ComboBox EntropyBox;
private WinForms.Controls.LocLabelEx lblEntropy;
private System.Windows.Forms.ComboBox RegionBox;
- private WinForms.Controls.LocLabelEx lblRegion;
- private System.Windows.Forms.CheckBox cbGameHotfixes;
- private System.Windows.Forms.CheckBox cbFastPPU;
- private System.Windows.Forms.CheckBox Bg1_0Checkbox;
- private System.Windows.Forms.CheckBox Bg4_0Checkbox;
- private System.Windows.Forms.CheckBox Bg3_0Checkbox;
- private System.Windows.Forms.CheckBox Bg2_0Checkbox;
- private WinForms.Controls.LocLabelEx lblPriority1;
- private WinForms.Controls.LocLabelEx lblPriority0;
- private System.Windows.Forms.CheckBox cbCropSGBFrame;
+ private WinForms.Controls.LocLabelEx lblRegion;
+ private System.Windows.Forms.CheckBox cbGameHotfixes;
+ private System.Windows.Forms.CheckBox cbFastPPU;
+ private System.Windows.Forms.CheckBox Bg1_0Checkbox;
+ private System.Windows.Forms.CheckBox Bg4_0Checkbox;
+ private System.Windows.Forms.CheckBox Bg3_0Checkbox;
+ private System.Windows.Forms.CheckBox Bg2_0Checkbox;
+ private WinForms.Controls.LocLabelEx lblPriority1;
+ private WinForms.Controls.LocLabelEx lblPriority0;
+ private System.Windows.Forms.CheckBox cbCropSGBFrame;
private System.Windows.Forms.CheckBox cbUseSGB2;
private System.Windows.Forms.CheckBox cbFastDSP;
private System.Windows.Forms.CheckBox cbFastCoprocessor;
- }
-}
+ private System.Windows.Forms.CheckBox cbNoPPUSpriteLimit;
+ }
+}
diff --git a/src/BizHawk.Client.EmuHawk/config/SNES/BSNESOptions.cs b/src/BizHawk.Client.EmuHawk/config/SNES/BSNESOptions.cs
index 927c1811aa..7fdfddf854 100644
--- a/src/BizHawk.Client.EmuHawk/config/SNES/BSNESOptions.cs
+++ b/src/BizHawk.Client.EmuHawk/config/SNES/BSNESOptions.cs
@@ -22,6 +22,7 @@ namespace BizHawk.Client.EmuHawk
{
AlwaysDoubleSize = s.AlwaysDoubleSize,
CropSGBFrame = s.CropSGBFrame,
+ NoPPUSpriteLimit = s.NoPPUSpriteLimit,
Entropy = ss.Entropy,
RegionOverride = ss.RegionOverride,
Hotfixes = ss.Hotfixes,
@@ -48,6 +49,7 @@ namespace BizHawk.Client.EmuHawk
s.AlwaysDoubleSize = dlg.AlwaysDoubleSize;
s.CropSGBFrame = dlg.CropSGBFrame;
+ s.NoPPUSpriteLimit = dlg.NoPPUSpriteLimit;
ss.Entropy = dlg.Entropy;
ss.RegionOverride = dlg.RegionOverride;
ss.Hotfixes = dlg.Hotfixes;
@@ -84,6 +86,12 @@ namespace BizHawk.Client.EmuHawk
init => cbCropSGBFrame.Checked = value;
}
+ private bool NoPPUSpriteLimit
+ {
+ get => cbNoPPUSpriteLimit.Checked;
+ init => cbNoPPUSpriteLimit.Checked = value;
+ }
+
private bool Hotfixes
{
get => cbGameHotfixes.Checked;
@@ -93,7 +101,7 @@ namespace BizHawk.Client.EmuHawk
private bool FastPPU
{
get => cbFastPPU.Checked;
- init => cbDoubleSize.Enabled = cbFastPPU.Checked = value;
+ init => cbDoubleSize.Enabled = cbNoPPUSpriteLimit.Enabled = cbFastPPU.Checked = value;
}
private bool FastDSP
@@ -154,7 +162,7 @@ namespace BizHawk.Client.EmuHawk
private void FastPPU_CheckedChanged(object sender, EventArgs e)
{
- cbDoubleSize.Enabled = cbFastPPU.Checked;
+ cbDoubleSize.Enabled = cbNoPPUSpriteLimit.Enabled = cbFastPPU.Checked;
}
}
}
diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/BSNES/BsnesApi.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/BSNES/BsnesApi.cs
index 6019e5cee9..338fe77adf 100644
--- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/BSNES/BsnesApi.cs
+++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/BSNES/BsnesApi.cs
@@ -23,6 +23,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.BSNES
public abstract void snes_set_trace_enabled(bool enabled);
[BizImport(CallingConvention.Cdecl)]
public abstract void snes_set_hooks_enabled(bool readHookEnabled, bool writeHookEnabled, bool executeHookEnabled);
+ [BizImport(CallingConvention.Cdecl)]
+ public abstract void snes_set_ppu_sprite_limit_enabled(bool enabled);
[BizImport(CallingConvention.Cdecl)]
public abstract IntPtr snes_get_audiobuffer_and_size(out int size);
@@ -178,7 +180,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.BSNES
exe.Dispose();
exe = null;
core = null;
- // serializedSize = 0;
}
}
@@ -283,27 +284,25 @@ namespace BizHawk.Emulation.Cores.Nintendo.BSNES
_readonlyFiles.RemoveAll(s => !s.StartsWith("msu1/"));
}
- // TODO: confirm that the serializedSize is CONSTANT for any given game,
- // else this might be problematic
- // private int serializedSize;// = 284275;
+ // private int serializedSize;
public void SaveStateBinary(BinaryWriter writer)
{
- // if (serializedSize == 0)
- // serializedSize = _core.snes_serialized_size();
- // TODO: do some profiling and testing to check whether this is actually better than _exe.SaveStateBinary(writer);
- // re-adding bsnes's own serialization will need to be done once it's confirmed to be deterministic, aka after libco update
+ // commented code left for debug purposes; created savestates are native bsnes savestates
+ // and therefor compatible across minor core updates
+ // if (serializedSize == 0) serializedSize = core.snes_serialized_size();
// byte[] serializedData = new byte[serializedSize];
- // _core.snes_serialize(serializedData, serializedSize);
+ // core.snes_serialize(serializedData, serializedSize);
// writer.Write(serializedData);
exe.SaveStateBinary(writer);
}
public void LoadStateBinary(BinaryReader reader)
{
+ // if (serializedSize == 0) serializedSize = core.snes_serialized_size();
// byte[] serializedData = reader.ReadBytes(serializedSize);
- // _core.snes_unserialize(serializedData, serializedSize);
+ // core.snes_unserialize(serializedData, serializedSize);
exe.LoadStateBinary(reader);
core.snes_msu_sync();
}
diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/BSNES/BsnesCore.IEmulator.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/BSNES/BsnesCore.IEmulator.cs
index 1bba92e6b8..a7f4d0a457 100644
--- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/BSNES/BsnesCore.IEmulator.cs
+++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/BSNES/BsnesCore.IEmulator.cs
@@ -16,27 +16,27 @@ namespace BizHawk.Emulation.Cores.Nintendo.BSNES
public bool FrameAdvance(IController controller, bool render, bool renderSound)
{
using (Api.EnterExit())
- {
- FrameAdvancePre(controller, render, renderSound);
-
- bool resetSignal = controller.IsPressed("Reset");
- if (resetSignal)
- {
- Api.core.snes_reset();
- }
-
- bool powerSignal = controller.IsPressed("Power");
- if (powerSignal)
- {
- Api.core.snes_power();
- }
-
- IsLagFrame = true;
- // run the core for one frame
- Api.core.snes_run(false);
- FrameAdvancePost();
-
- return true;
+ {
+ FrameAdvancePre(controller, render, renderSound);
+
+ bool resetSignal = controller.IsPressed("Reset");
+ if (resetSignal)
+ {
+ Api.core.snes_reset();
+ }
+
+ bool powerSignal = controller.IsPressed("Power");
+ if (powerSignal)
+ {
+ Api.core.snes_power();
+ }
+
+ IsLagFrame = true;
+ // run the core for one frame
+ Api.core.snes_run(false);
+ FrameAdvancePost();
+
+ return true;
}
}
@@ -65,6 +65,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.BSNES
Api.core.snes_set_trace_enabled(_tracer.IsEnabled());
Api.core.snes_set_video_enabled(render);
Api.core.snes_set_audio_enabled(renderSound);
+ Api.core.snes_set_ppu_sprite_limit_enabled(!_settings.NoPPUSpriteLimit);
}
internal void FrameAdvancePost()
@@ -80,13 +81,13 @@ namespace BizHawk.Emulation.Cores.Nintendo.BSNES
}
private int UpdateAudioBuffer()
- {
- var rawAudioBuffer = Api.core.snes_get_audiobuffer_and_size(out var size);
- if (size == 0) return 0;
- if (size > _audioBuffer.Length)
- _audioBuffer = new short[size];
- Marshal.Copy(rawAudioBuffer, _audioBuffer, 0, size);
-
+ {
+ var rawAudioBuffer = Api.core.snes_get_audiobuffer_and_size(out var size);
+ if (size == 0) return 0;
+ if (size > _audioBuffer.Length)
+ _audioBuffer = new short[size];
+ Marshal.Copy(rawAudioBuffer, _audioBuffer, 0, size);
+
return size;
}
diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/BSNES/BsnesCore.ISettable.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/BSNES/BsnesCore.ISettable.cs
index 9ea3abea55..7c04610a1f 100644
--- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/BSNES/BsnesCore.ISettable.cs
+++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/BSNES/BsnesCore.ISettable.cs
@@ -64,6 +64,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.BSNES
public bool AlwaysDoubleSize { get; set; }
public bool CropSGBFrame { get; set; }
+ public bool NoPPUSpriteLimit { get; set; }
public SnesSettings Clone()
{
diff --git a/waterbox/bsnescore/bsnes/target-bsnescore/bsnescore.cpp b/waterbox/bsnescore/bsnes/target-bsnescore/bsnescore.cpp
index 0806915dc8..671ee4b551 100644
--- a/waterbox/bsnescore/bsnes/target-bsnescore/bsnescore.cpp
+++ b/waterbox/bsnescore/bsnes/target-bsnescore/bsnescore.cpp
@@ -264,6 +264,15 @@ EXPORT void snes_set_hooks_enabled(bool read_hook_enabled, bool write_hook_enabl
platform->executeHookEnabled = execute_hook_enabled;
}
+EXPORT void snes_set_ppu_sprite_limit_enabled(bool enabled)
+{
+ if (!SuperFamicom::system.fastPPU()) return;
+
+ // see ppu-fast/ppu.cpp in PPU::power(...)
+ ppufast.ItemLimit = enabled ? 32 : 128;
+ ppufast.TileLimit = enabled ? 34 : 128;
+}
+
uint8_t* snes_get_effective_saveram(int* ram_size) {
if (cartridge.has.SA1) {