snes-add "always doublesize framebuffer" snes option which makes the logical output of the snes core always sized appropriately for sudden hires-width or interlacing
This commit is contained in:
parent
b2c0910376
commit
45a671ce73
|
@ -284,13 +284,26 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
|
||||||
int field = 0;
|
int field = 0;
|
||||||
void snes_video_refresh(int* data, int width, int height)
|
void snes_video_refresh(int* data, int width, int height)
|
||||||
{
|
{
|
||||||
|
bool doubleSize = CoreComm.SNES_AlwaysDoubleSize;
|
||||||
|
bool lineDouble = doubleSize, dotDouble = doubleSize;
|
||||||
|
|
||||||
vidWidth = width;
|
vidWidth = width;
|
||||||
vidHeight = height;
|
vidHeight = height;
|
||||||
|
|
||||||
|
int yskip = 1, xskip = 1;
|
||||||
|
|
||||||
//if we are in high-res mode, we get double width. so, lets double the height here to keep it square.
|
//if we are in high-res mode, we get double width. so, lets double the height here to keep it square.
|
||||||
//TODO - does interlacing have something to do with the correct way to handle this? need an example that turns it on.
|
//TODO - does interlacing have something to do with the correct way to handle this? need an example that turns it on.
|
||||||
int yskip = 1;
|
|
||||||
if (width == 512)
|
if (width == 512)
|
||||||
|
{
|
||||||
|
vidHeight *= 2;
|
||||||
|
yskip = 2;
|
||||||
|
|
||||||
|
lineDouble = true;
|
||||||
|
//we dont dot double here because the user wanted double res and the game provided double res
|
||||||
|
dotDouble = false;
|
||||||
|
}
|
||||||
|
else if (lineDouble)
|
||||||
{
|
{
|
||||||
vidHeight *= 2;
|
vidHeight *= 2;
|
||||||
yskip = 2;
|
yskip = 2;
|
||||||
|
@ -313,30 +326,36 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
|
||||||
field ^= 1;
|
field ^= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dotDouble)
|
||||||
|
{
|
||||||
|
vidWidth *= 2;
|
||||||
|
xskip = 2;
|
||||||
|
}
|
||||||
|
|
||||||
int size = vidWidth * vidHeight;
|
int size = vidWidth * vidHeight;
|
||||||
if (vidBuffer.Length != size)
|
if (vidBuffer.Length != size)
|
||||||
vidBuffer = new int[size];
|
vidBuffer = new int[size];
|
||||||
|
|
||||||
|
for (int j = 0; j < 2; j++)
|
||||||
for (int y = 0; y < height; y++)
|
{
|
||||||
for (int x = 0; x < width; x++)
|
if (j == 1 && !dotDouble) break;
|
||||||
|
int xbonus = j;
|
||||||
|
for (int i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
int si = y * srcPitch + x + srcStart;
|
//potentially do this twice, if we need to line double
|
||||||
int di = y * vidWidth * yskip + x;
|
if (i == 1 && !lineDouble) break;
|
||||||
int rgb = data[si];
|
|
||||||
vidBuffer[di] = rgb;
|
|
||||||
}
|
|
||||||
|
|
||||||
//alternate scanlines
|
int bonus = i * vidWidth + xbonus;
|
||||||
if (width == 512)
|
for (int y = 0; y < height; y++)
|
||||||
for (int y = 0; y < height; y++)
|
for (int x = 0; x < width; x++)
|
||||||
for (int x = 0; x < width; x++)
|
{
|
||||||
{
|
int si = y * srcPitch + x + srcStart;
|
||||||
int si = y * 1024 + x;
|
int di = y * vidWidth * yskip + x * xskip + bonus;
|
||||||
int di = y * vidWidth * yskip + x + 512;
|
int rgb = data[si];
|
||||||
int rgb = data[si];
|
vidBuffer[di] = rgb;
|
||||||
vidBuffer[di] = rgb;
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void FrameAdvance(bool render, bool rendersound)
|
public void FrameAdvance(bool render, bool rendersound)
|
||||||
|
|
|
@ -18,6 +18,7 @@ namespace BizHawk
|
||||||
public string SNES_ExePath;
|
public string SNES_ExePath;
|
||||||
public string SNES_Profile;
|
public string SNES_Profile;
|
||||||
public bool SNES_UseRingBuffer;
|
public bool SNES_UseRingBuffer;
|
||||||
|
public bool SNES_AlwaysDoubleSize;
|
||||||
|
|
||||||
public bool SNES_ShowBG1_0, SNES_ShowBG2_0, SNES_ShowBG3_0, SNES_ShowBG4_0;
|
public bool SNES_ShowBG1_0, SNES_ShowBG2_0, SNES_ShowBG3_0, SNES_ShowBG4_0;
|
||||||
public bool SNES_ShowBG1_1, SNES_ShowBG2_1, SNES_ShowBG3_1, SNES_ShowBG4_1;
|
public bool SNES_ShowBG1_1, SNES_ShowBG2_1, SNES_ShowBG3_1, SNES_ShowBG4_1;
|
||||||
|
|
|
@ -756,6 +756,7 @@ namespace BizHawk.MultiClient
|
||||||
public NESConsoleButtonTemplate SNESConsoleButtons = new NESConsoleButtonTemplate();
|
public NESConsoleButtonTemplate SNESConsoleButtons = new NESConsoleButtonTemplate();
|
||||||
public string SNESProfile = "Compatibility";
|
public string SNESProfile = "Compatibility";
|
||||||
public bool SNESUseRingBuffer = true;
|
public bool SNESUseRingBuffer = true;
|
||||||
|
public bool SNESAlwaysDoubleSize = false;
|
||||||
|
|
||||||
//TI 83 settings
|
//TI 83 settings
|
||||||
public TI83ControllerTemplate[] TI83Controller = new TI83ControllerTemplate[1];
|
public TI83ControllerTemplate[] TI83Controller = new TI83ControllerTemplate[1];
|
||||||
|
|
|
@ -1856,12 +1856,14 @@ namespace BizHawk.MultiClient
|
||||||
{
|
{
|
||||||
var so = new SNESOptions();
|
var so = new SNESOptions();
|
||||||
so.UseRingBuffer = Global.Config.SNESUseRingBuffer;
|
so.UseRingBuffer = Global.Config.SNESUseRingBuffer;
|
||||||
|
so.AlwaysDoubleSize = Global.Config.SNESAlwaysDoubleSize;
|
||||||
so.Profile = Global.Config.SNESProfile;
|
so.Profile = Global.Config.SNESProfile;
|
||||||
if (so.ShowDialog() == System.Windows.Forms.DialogResult.OK)
|
if (so.ShowDialog() == System.Windows.Forms.DialogResult.OK)
|
||||||
{
|
{
|
||||||
bool reboot = Global.Config.SNESProfile != so.Profile;
|
bool reboot = Global.Config.SNESProfile != so.Profile;
|
||||||
Global.Config.SNESProfile = so.Profile;
|
Global.Config.SNESProfile = so.Profile;
|
||||||
Global.Config.SNESUseRingBuffer = so.UseRingBuffer;
|
Global.Config.SNESUseRingBuffer = so.UseRingBuffer;
|
||||||
|
Global.Config.SNESAlwaysDoubleSize = so.AlwaysDoubleSize;
|
||||||
if (reboot) FlagNeedsReboot();
|
if (reboot) FlagNeedsReboot();
|
||||||
SyncCoreCommInputSignals();
|
SyncCoreCommInputSignals();
|
||||||
}
|
}
|
||||||
|
|
|
@ -436,6 +436,7 @@ namespace BizHawk.MultiClient
|
||||||
|
|
||||||
target.SNES_Profile = Global.Config.SNESProfile;
|
target.SNES_Profile = Global.Config.SNESProfile;
|
||||||
target.SNES_UseRingBuffer = Global.Config.SNESUseRingBuffer;
|
target.SNES_UseRingBuffer = Global.Config.SNESUseRingBuffer;
|
||||||
|
target.SNES_AlwaysDoubleSize = Global.Config.SNESAlwaysDoubleSize;
|
||||||
|
|
||||||
target.GG_HighlightActiveDisplayRegion = Global.Config.GGHighlightActiveDisplayRegion;
|
target.GG_HighlightActiveDisplayRegion = Global.Config.GGHighlightActiveDisplayRegion;
|
||||||
target.GG_ShowClippedRegions = Global.Config.GGShowClippedRegions;
|
target.GG_ShowClippedRegions = Global.Config.GGShowClippedRegions;
|
||||||
|
|
|
@ -35,13 +35,15 @@
|
||||||
this.rbPerformance = new System.Windows.Forms.RadioButton();
|
this.rbPerformance = new System.Windows.Forms.RadioButton();
|
||||||
this.cbRingbuf = new System.Windows.Forms.CheckBox();
|
this.cbRingbuf = new System.Windows.Forms.CheckBox();
|
||||||
this.label1 = new System.Windows.Forms.Label();
|
this.label1 = new System.Windows.Forms.Label();
|
||||||
|
this.cbDoubleSize = new System.Windows.Forms.CheckBox();
|
||||||
|
this.label2 = new System.Windows.Forms.Label();
|
||||||
this.groupBox1.SuspendLayout();
|
this.groupBox1.SuspendLayout();
|
||||||
this.SuspendLayout();
|
this.SuspendLayout();
|
||||||
//
|
//
|
||||||
// btnOk
|
// btnOk
|
||||||
//
|
//
|
||||||
this.btnOk.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
this.btnOk.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||||
this.btnOk.Location = new System.Drawing.Point(141, 172);
|
this.btnOk.Location = new System.Drawing.Point(141, 249);
|
||||||
this.btnOk.Name = "btnOk";
|
this.btnOk.Name = "btnOk";
|
||||||
this.btnOk.Size = new System.Drawing.Size(75, 23);
|
this.btnOk.Size = new System.Drawing.Size(75, 23);
|
||||||
this.btnOk.TabIndex = 0;
|
this.btnOk.TabIndex = 0;
|
||||||
|
@ -53,7 +55,7 @@
|
||||||
//
|
//
|
||||||
this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||||
this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
|
this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
|
||||||
this.btnCancel.Location = new System.Drawing.Point(222, 172);
|
this.btnCancel.Location = new System.Drawing.Point(222, 249);
|
||||||
this.btnCancel.Name = "btnCancel";
|
this.btnCancel.Name = "btnCancel";
|
||||||
this.btnCancel.Size = new System.Drawing.Size(75, 23);
|
this.btnCancel.Size = new System.Drawing.Size(75, 23);
|
||||||
this.btnCancel.TabIndex = 1;
|
this.btnCancel.TabIndex = 1;
|
||||||
|
@ -112,6 +114,25 @@
|
||||||
this.label1.TabIndex = 5;
|
this.label1.TabIndex = 5;
|
||||||
this.label1.Text = "This was designed as an optimization but it isn\'t clear whether it works. Feel fr" +
|
this.label1.Text = "This was designed as an optimization but it isn\'t clear whether it works. Feel fr" +
|
||||||
"ee to try different settings and let us know the results.";
|
"ee to try different settings and let us know the results.";
|
||||||
|
//
|
||||||
|
// cbDoubleSize
|
||||||
|
//
|
||||||
|
this.cbDoubleSize.AutoSize = true;
|
||||||
|
this.cbDoubleSize.Location = new System.Drawing.Point(18, 165);
|
||||||
|
this.cbDoubleSize.Name = "cbDoubleSize";
|
||||||
|
this.cbDoubleSize.Size = new System.Drawing.Size(178, 17);
|
||||||
|
this.cbDoubleSize.TabIndex = 6;
|
||||||
|
this.cbDoubleSize.Text = "Always Double-Size Framebuffer";
|
||||||
|
this.cbDoubleSize.UseVisualStyleBackColor = true;
|
||||||
|
//
|
||||||
|
// label2
|
||||||
|
//
|
||||||
|
this.label2.Location = new System.Drawing.Point(36, 186);
|
||||||
|
this.label2.Name = "label2";
|
||||||
|
this.label2.Size = new System.Drawing.Size(254, 45);
|
||||||
|
this.label2.TabIndex = 7;
|
||||||
|
this.label2.Text = "Some games are changing the resolution constantly (e.g. SD3) so this option can f" +
|
||||||
|
"orce the SNES output to stay double-size always.";
|
||||||
//
|
//
|
||||||
// SNESOptions
|
// SNESOptions
|
||||||
//
|
//
|
||||||
|
@ -119,7 +140,9 @@
|
||||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||||
this.CancelButton = this.btnCancel;
|
this.CancelButton = this.btnCancel;
|
||||||
this.ClientSize = new System.Drawing.Size(300, 198);
|
this.ClientSize = new System.Drawing.Size(300, 275);
|
||||||
|
this.Controls.Add(this.label2);
|
||||||
|
this.Controls.Add(this.cbDoubleSize);
|
||||||
this.Controls.Add(this.label1);
|
this.Controls.Add(this.label1);
|
||||||
this.Controls.Add(this.cbRingbuf);
|
this.Controls.Add(this.cbRingbuf);
|
||||||
this.Controls.Add(this.groupBox1);
|
this.Controls.Add(this.groupBox1);
|
||||||
|
@ -144,5 +167,7 @@
|
||||||
private System.Windows.Forms.RadioButton rbPerformance;
|
private System.Windows.Forms.RadioButton rbPerformance;
|
||||||
private System.Windows.Forms.CheckBox cbRingbuf;
|
private System.Windows.Forms.CheckBox cbRingbuf;
|
||||||
private System.Windows.Forms.Label label1;
|
private System.Windows.Forms.Label label1;
|
||||||
|
private System.Windows.Forms.CheckBox cbDoubleSize;
|
||||||
|
private System.Windows.Forms.Label label2;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -32,6 +32,12 @@ namespace BizHawk.MultiClient
|
||||||
set { cbRingbuf.Checked = value; }
|
set { cbRingbuf.Checked = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool AlwaysDoubleSize
|
||||||
|
{
|
||||||
|
get { return cbDoubleSize.Checked; }
|
||||||
|
set { cbDoubleSize.Checked = value; }
|
||||||
|
}
|
||||||
|
|
||||||
private void btnOk_Click(object sender, EventArgs e)
|
private void btnOk_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
DialogResult = System.Windows.Forms.DialogResult.OK;
|
DialogResult = System.Windows.Forms.DialogResult.OK;
|
||||||
|
|
Loading…
Reference in New Issue