BSNESv115+: add option for disabling ppu sprite limit

This commit is contained in:
Morilli 2022-11-10 23:22:17 +01:00
parent 066297d5e7
commit c21fedc76a
7 changed files with 133 additions and 102 deletions
Assets/dll
src
BizHawk.Client.EmuHawk/config/SNES
BizHawk.Emulation.Cores/Consoles/Nintendo/BSNES
waterbox/bsnescore/bsnes/target-bsnescore

Binary file not shown.

View File

@ -1,32 +1,32 @@
namespace BizHawk.Client.EmuHawk
{
partial class BSNESOptions
namespace BizHawk.Client.EmuHawk
{
partial class BSNESOptions
{
/// <summary>
/// Required designer variable.
/// </summary>
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
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
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
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;
}
}

View File

@ -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;
}
}
}

View File

@ -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();
}

View File

@ -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;
}

View File

@ -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()
{

View File

@ -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) {