diff --git a/BizHawk.Emulation/Consoles/Nintendo/SNES/LibsnesCore.cs b/BizHawk.Emulation/Consoles/Nintendo/SNES/LibsnesCore.cs index 9a9dd1bb2e..b3fea60889 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/SNES/LibsnesCore.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/SNES/LibsnesCore.cs @@ -284,13 +284,26 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES int field = 0; void snes_video_refresh(int* data, int width, int height) { + bool doubleSize = CoreComm.SNES_AlwaysDoubleSize; + bool lineDouble = doubleSize, dotDouble = doubleSize; + vidWidth = width; 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. //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) + { + 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; yskip = 2; @@ -313,30 +326,36 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES field ^= 1; } + if (dotDouble) + { + vidWidth *= 2; + xskip = 2; + } + int size = vidWidth * vidHeight; if (vidBuffer.Length != size) vidBuffer = new int[size]; - - for (int y = 0; y < height; y++) - for (int x = 0; x < width; x++) + for (int j = 0; j < 2; j++) + { + if (j == 1 && !dotDouble) break; + int xbonus = j; + for (int i = 0; i < 2; i++) { - int si = y * srcPitch + x + srcStart; - int di = y * vidWidth * yskip + x; - int rgb = data[si]; - vidBuffer[di] = rgb; - } + //potentially do this twice, if we need to line double + if (i == 1 && !lineDouble) break; - //alternate scanlines - if (width == 512) - for (int y = 0; y < height; y++) - for (int x = 0; x < width; x++) - { - int si = y * 1024 + x; - int di = y * vidWidth * yskip + x + 512; - int rgb = data[si]; - vidBuffer[di] = rgb; - } + int bonus = i * vidWidth + xbonus; + for (int y = 0; y < height; y++) + for (int x = 0; x < width; x++) + { + int si = y * srcPitch + x + srcStart; + int di = y * vidWidth * yskip + x * xskip + bonus; + int rgb = data[si]; + vidBuffer[di] = rgb; + } + } + } } public void FrameAdvance(bool render, bool rendersound) diff --git a/BizHawk.Emulation/Interfaces/CoreComms.cs b/BizHawk.Emulation/Interfaces/CoreComms.cs index cfef0be1ba..868c03dd0e 100644 --- a/BizHawk.Emulation/Interfaces/CoreComms.cs +++ b/BizHawk.Emulation/Interfaces/CoreComms.cs @@ -18,6 +18,7 @@ namespace BizHawk public string SNES_ExePath; public string SNES_Profile; 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_1, SNES_ShowBG2_1, SNES_ShowBG3_1, SNES_ShowBG4_1; diff --git a/BizHawk.MultiClient/Config.cs b/BizHawk.MultiClient/Config.cs index c36cd43eed..1a33cd3cbe 100644 --- a/BizHawk.MultiClient/Config.cs +++ b/BizHawk.MultiClient/Config.cs @@ -756,6 +756,7 @@ namespace BizHawk.MultiClient public NESConsoleButtonTemplate SNESConsoleButtons = new NESConsoleButtonTemplate(); public string SNESProfile = "Compatibility"; public bool SNESUseRingBuffer = true; + public bool SNESAlwaysDoubleSize = false; //TI 83 settings public TI83ControllerTemplate[] TI83Controller = new TI83ControllerTemplate[1]; diff --git a/BizHawk.MultiClient/MainForm.MenuItems.cs b/BizHawk.MultiClient/MainForm.MenuItems.cs index b6254b4f5b..33f692f104 100644 --- a/BizHawk.MultiClient/MainForm.MenuItems.cs +++ b/BizHawk.MultiClient/MainForm.MenuItems.cs @@ -1856,12 +1856,14 @@ namespace BizHawk.MultiClient { var so = new SNESOptions(); so.UseRingBuffer = Global.Config.SNESUseRingBuffer; + so.AlwaysDoubleSize = Global.Config.SNESAlwaysDoubleSize; so.Profile = Global.Config.SNESProfile; if (so.ShowDialog() == System.Windows.Forms.DialogResult.OK) { bool reboot = Global.Config.SNESProfile != so.Profile; Global.Config.SNESProfile = so.Profile; Global.Config.SNESUseRingBuffer = so.UseRingBuffer; + Global.Config.SNESAlwaysDoubleSize = so.AlwaysDoubleSize; if (reboot) FlagNeedsReboot(); SyncCoreCommInputSignals(); } diff --git a/BizHawk.MultiClient/MainForm.cs b/BizHawk.MultiClient/MainForm.cs index ea774d5e60..82509a4de2 100644 --- a/BizHawk.MultiClient/MainForm.cs +++ b/BizHawk.MultiClient/MainForm.cs @@ -436,6 +436,7 @@ namespace BizHawk.MultiClient target.SNES_Profile = Global.Config.SNESProfile; target.SNES_UseRingBuffer = Global.Config.SNESUseRingBuffer; + target.SNES_AlwaysDoubleSize = Global.Config.SNESAlwaysDoubleSize; target.GG_HighlightActiveDisplayRegion = Global.Config.GGHighlightActiveDisplayRegion; target.GG_ShowClippedRegions = Global.Config.GGShowClippedRegions; diff --git a/BizHawk.MultiClient/SNESTools/SNESOptions.Designer.cs b/BizHawk.MultiClient/SNESTools/SNESOptions.Designer.cs index 84dd3eae15..6679e01b7a 100644 --- a/BizHawk.MultiClient/SNESTools/SNESOptions.Designer.cs +++ b/BizHawk.MultiClient/SNESTools/SNESOptions.Designer.cs @@ -35,13 +35,15 @@ this.rbPerformance = new System.Windows.Forms.RadioButton(); this.cbRingbuf = new System.Windows.Forms.CheckBox(); 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.SuspendLayout(); // // btnOk // 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.Size = new System.Drawing.Size(75, 23); 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.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.Size = new System.Drawing.Size(75, 23); this.btnCancel.TabIndex = 1; @@ -112,6 +114,25 @@ this.label1.TabIndex = 5; 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."; + // + // 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 // @@ -119,7 +140,9 @@ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 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.cbRingbuf); this.Controls.Add(this.groupBox1); @@ -144,5 +167,7 @@ private System.Windows.Forms.RadioButton rbPerformance; private System.Windows.Forms.CheckBox cbRingbuf; private System.Windows.Forms.Label label1; + private System.Windows.Forms.CheckBox cbDoubleSize; + private System.Windows.Forms.Label label2; } } \ No newline at end of file diff --git a/BizHawk.MultiClient/SNESTools/SNESOptions.cs b/BizHawk.MultiClient/SNESTools/SNESOptions.cs index c6b0b58868..d17e6ea67f 100644 --- a/BizHawk.MultiClient/SNESTools/SNESOptions.cs +++ b/BizHawk.MultiClient/SNESTools/SNESOptions.cs @@ -32,6 +32,12 @@ namespace BizHawk.MultiClient set { cbRingbuf.Checked = value; } } + public bool AlwaysDoubleSize + { + get { return cbDoubleSize.Checked; } + set { cbDoubleSize.Checked = value; } + } + private void btnOk_Click(object sender, EventArgs e) { DialogResult = System.Windows.Forms.DialogResult.OK;