psx - improve framebuffer clipping method, add deinterlacer settings, fix some PAR for PAL games; fix bugs in GameExtraPadding handling

This commit is contained in:
zeromus 2015-08-09 11:35:22 -05:00
parent d0f56ac98d
commit 0cd3a82862
10 changed files with 459 additions and 188 deletions

View File

@ -143,6 +143,28 @@ namespace BizHawk.Client.EmuHawk
} }
} }
System.Windows.Forms.Padding CalculateCompleteContentPadding(bool user, bool source)
{
var padding = new System.Windows.Forms.Padding();
if(user)
padding += GameExtraPadding;
//an experimental feature
if(source)
if (Global.Emulator is BizHawk.Emulation.Cores.Sony.PSX.Octoshock)
{
var psx = Global.Emulator as BizHawk.Emulation.Cores.Sony.PSX.Octoshock;
var core_padding = psx.VideoProvider_Padding;
padding.Left += core_padding.Width / 2;
padding.Right += core_padding.Width - core_padding.Width / 2;
padding.Top += core_padding.Height / 2;
padding.Bottom += core_padding.Height - core_padding.Height / 2;
}
return padding;
}
FilterProgram BuildDefaultChain(Size chain_insize, Size chain_outsize, bool includeOSD) FilterProgram BuildDefaultChain(Size chain_insize, Size chain_outsize, bool includeOSD)
{ {
//select user special FX shader chain //select user special FX shader chain
@ -183,18 +205,23 @@ namespace BizHawk.Client.EmuHawk
chain.AddFilter(fInput, "input"); chain.AddFilter(fInput, "input");
//if a non-zero padding is required, add a filter to allow for that //if a non-zero padding is required, add a filter to allow for that
if (GameExtraPadding.Vertical != 0 || GameExtraPadding.Horizontal != 0) //note, we have two sources of padding right now.. one can come from the videoprovider and one from the user.
//we're combining these now and just using black, for sake of being lean, despite the discussion below:
//keep in mind, the videoprovider design in principle might call for another color.
//we havent really been using this very hard, but users will probably want black there (they could fill it to another color if needed tho)
var padding = CalculateCompleteContentPadding(true,true);
if (padding.Vertical != 0 || padding.Horizontal != 0)
{ {
//TODO - add another filter just for this, its cumebrsome to use final presentation... I think. but maybe theres enough similarities to justify it. //TODO - add another filter just for this, its cumbersome to use final presentation... I think. but maybe theres enough similarities to justify it.
Size size = chain_insize; Size size = chain_insize;
size.Width += GameExtraPadding.Horizontal; size.Width += padding.Horizontal;
size.Height += GameExtraPadding.Vertical; size.Height += padding.Vertical;
Filters.FinalPresentation fPadding = new Filters.FinalPresentation(size); Filters.FinalPresentation fPadding = new Filters.FinalPresentation(size);
chain.AddFilter(fPadding, "padding"); chain.AddFilter(fPadding, "padding");
fPadding.GuiRenderer = Renderer; fPadding.GuiRenderer = Renderer;
fPadding.GL = GL; fPadding.GL = GL;
fPadding.Config_PadOnly = true; fPadding.Config_PadOnly = true;
fPadding.Padding = GameExtraPadding; fPadding.Padding = padding;
} }
//add lua layer 'emu' //add lua layer 'emu'
@ -367,6 +394,14 @@ namespace BizHawk.Client.EmuHawk
virtualHeight = Global.Config.DispCustomUserARHeight; virtualHeight = Global.Config.DispCustomUserARHeight;
} }
var padding = CalculateCompleteContentPadding(true, false);
virtualWidth += padding.Horizontal;
virtualHeight += padding.Vertical;
padding = CalculateCompleteContentPadding(true, true);
bufferWidth += padding.Horizontal;
bufferHeight += padding.Vertical;
//Console.WriteLine("DISPZOOM " + zoom); //test //Console.WriteLine("DISPZOOM " + zoom); //test
//old stuff //old stuff
@ -505,6 +540,10 @@ namespace BizHawk.Client.EmuHawk
} }
} }
var padding = CalculateCompleteContentPadding(true,false);
vw += padding.Horizontal;
vh += padding.Vertical;
int[] videoBuffer = videoProvider.GetVideoBuffer(); int[] videoBuffer = videoProvider.GetVideoBuffer();
TESTEROO: TESTEROO:

View File

@ -217,7 +217,7 @@ namespace BizHawk.Client.EmuHawk.Filters
//TODO - redundant fix //TODO - redundant fix
LL = new LetterboxingLogic(); LL = new LetterboxingLogic();
LL.vx += Padding.Left; LL.vx += Padding.Left;
LL.vy += Padding.Right; LL.vy += Padding.Top;
LL.vw = size.Width; LL.vw = size.Width;
LL.vh = size.Height; LL.vh = size.Height;
} }
@ -250,7 +250,7 @@ namespace BizHawk.Client.EmuHawk.Filters
//TODO - redundant fix //TODO - redundant fix
LL = new LetterboxingLogic(); LL = new LetterboxingLogic();
LL.vx += Padding.Left; LL.vx += Padding.Left;
LL.vy += Padding.Right; LL.vy += Padding.Top;
LL.vw = InputSize.Width; LL.vw = InputSize.Width;
LL.vh = InputSize.Height; LL.vh = InputSize.Height;
} }

View File

@ -1879,7 +1879,7 @@ namespace BizHawk.Client.EmuHawk
var video = Global.Emulator.VideoProvider(); var video = Global.Emulator.VideoProvider();
//bool change = false; //bool change = false;
Size currVideoSize = new Size(video.BufferWidth,video.BufferHeight); Size currVideoSize = new Size(video.BufferWidth,video.BufferHeight);
Size currVirtualSize = new Size(video.VirtualWidth,video.VirtualWidth); Size currVirtualSize = new Size(video.VirtualWidth,video.VirtualHeight);
if (currVideoSize != _lastVideoSize || currVirtualSize != _lastVirtualSize) if (currVideoSize != _lastVideoSize || currVirtualSize != _lastVirtualSize)
{ {
_lastVideoSize = currVideoSize; _lastVideoSize = currVideoSize;

View File

@ -44,6 +44,10 @@
this.lblPixelPro = new System.Windows.Forms.Label(); this.lblPixelPro = new System.Windows.Forms.Label();
this.rbPixelPro = new System.Windows.Forms.RadioButton(); this.rbPixelPro = new System.Windows.Forms.RadioButton();
this.groupBox2 = new System.Windows.Forms.GroupBox(); this.groupBox2 = new System.Windows.Forms.GroupBox();
this.groupBox3 = new System.Windows.Forms.GroupBox();
this.rbClipNone = new System.Windows.Forms.RadioButton();
this.rbClipToFramebuffer = new System.Windows.Forms.RadioButton();
this.rbClipBasic = new System.Windows.Forms.RadioButton();
this.lblPAL = new System.Windows.Forms.Label(); this.lblPAL = new System.Windows.Forms.Label();
this.PAL_LastLineNumeric = new System.Windows.Forms.NumericUpDown(); this.PAL_LastLineNumeric = new System.Windows.Forms.NumericUpDown();
this.PAL_FirstLineNumeric = new System.Windows.Forms.NumericUpDown(); this.PAL_FirstLineNumeric = new System.Windows.Forms.NumericUpDown();
@ -54,25 +58,25 @@
this.NTSC_LastLineNumeric = new System.Windows.Forms.NumericUpDown(); this.NTSC_LastLineNumeric = new System.Windows.Forms.NumericUpDown();
this.NTSC_FirstLineNumeric = new System.Windows.Forms.NumericUpDown(); this.NTSC_FirstLineNumeric = new System.Windows.Forms.NumericUpDown();
this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); this.toolTip1 = new System.Windows.Forms.ToolTip(this.components);
this.groupBox3 = new System.Windows.Forms.GroupBox(); this.rbWeave = new System.Windows.Forms.RadioButton();
this.rbClipBasic = new System.Windows.Forms.RadioButton(); this.rbBobOffset = new System.Windows.Forms.RadioButton();
this.rbClipToFramebuffer = new System.Windows.Forms.RadioButton(); this.rbBob = new System.Windows.Forms.RadioButton();
this.rbClipNone = new System.Windows.Forms.RadioButton(); this.groupBox4 = new System.Windows.Forms.GroupBox();
this.label2 = new System.Windows.Forms.Label();
this.groupBox1.SuspendLayout(); this.groupBox1.SuspendLayout();
this.groupBox2.SuspendLayout(); this.groupBox2.SuspendLayout();
this.groupBox3.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.PAL_LastLineNumeric)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.PAL_LastLineNumeric)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.PAL_FirstLineNumeric)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.PAL_FirstLineNumeric)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.NTSC_LastLineNumeric)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.NTSC_LastLineNumeric)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.NTSC_FirstLineNumeric)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.NTSC_FirstLineNumeric)).BeginInit();
this.groupBox3.SuspendLayout(); this.groupBox4.SuspendLayout();
this.SuspendLayout(); this.SuspendLayout();
// //
// btnCancel // btnCancel
// //
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(622, 262); this.btnCancel.Location = new System.Drawing.Point(622, 309);
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 = 3; this.btnCancel.TabIndex = 3;
@ -82,7 +86,7 @@
// 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(541, 262); this.btnOk.Location = new System.Drawing.Point(541, 309);
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 = 2; this.btnOk.TabIndex = 2;
@ -104,7 +108,7 @@
this.groupBox1.Controls.Add(this.rbPixelPro); this.groupBox1.Controls.Add(this.rbPixelPro);
this.groupBox1.Location = new System.Drawing.Point(12, 7); this.groupBox1.Location = new System.Drawing.Point(12, 7);
this.groupBox1.Name = "groupBox1"; this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(474, 278); this.groupBox1.Size = new System.Drawing.Size(474, 293);
this.groupBox1.TabIndex = 6; this.groupBox1.TabIndex = 6;
this.groupBox1.TabStop = false; this.groupBox1.TabStop = false;
this.groupBox1.Text = "Resolution Management"; this.groupBox1.Text = "Resolution Management";
@ -112,7 +116,7 @@
// linkLabel1 // linkLabel1
// //
this.linkLabel1.AutoSize = true; this.linkLabel1.AutoSize = true;
this.linkLabel1.Location = new System.Drawing.Point(327, 248); this.linkLabel1.Location = new System.Drawing.Point(326, 254);
this.linkLabel1.Name = "linkLabel1"; this.linkLabel1.Name = "linkLabel1";
this.linkLabel1.Size = new System.Drawing.Size(53, 13); this.linkLabel1.Size = new System.Drawing.Size(53, 13);
this.linkLabel1.TabIndex = 29; this.linkLabel1.TabIndex = 29;
@ -163,7 +167,7 @@
// btnNiceDisplayConfig // btnNiceDisplayConfig
// //
this.btnNiceDisplayConfig.AutoSize = true; this.btnNiceDisplayConfig.AutoSize = true;
this.btnNiceDisplayConfig.Location = new System.Drawing.Point(146, 238); this.btnNiceDisplayConfig.Location = new System.Drawing.Point(145, 244);
this.btnNiceDisplayConfig.Name = "btnNiceDisplayConfig"; this.btnNiceDisplayConfig.Name = "btnNiceDisplayConfig";
this.btnNiceDisplayConfig.Size = new System.Drawing.Size(173, 23); this.btnNiceDisplayConfig.Size = new System.Drawing.Size(173, 23);
this.btnNiceDisplayConfig.TabIndex = 24; this.btnNiceDisplayConfig.TabIndex = 24;
@ -225,15 +229,68 @@
this.groupBox2.Controls.Add(this.NTSC_FirstLineNumeric); this.groupBox2.Controls.Add(this.NTSC_FirstLineNumeric);
this.groupBox2.Location = new System.Drawing.Point(492, 7); this.groupBox2.Location = new System.Drawing.Point(492, 7);
this.groupBox2.Name = "groupBox2"; this.groupBox2.Name = "groupBox2";
this.groupBox2.Size = new System.Drawing.Size(212, 245); this.groupBox2.Size = new System.Drawing.Size(212, 239);
this.groupBox2.TabIndex = 31; this.groupBox2.TabIndex = 31;
this.groupBox2.TabStop = false; this.groupBox2.TabStop = false;
this.groupBox2.Text = "Drawing Area"; this.groupBox2.Text = "Drawing Area";
// //
// groupBox3
//
this.groupBox3.Controls.Add(this.rbClipNone);
this.groupBox3.Controls.Add(this.rbClipToFramebuffer);
this.groupBox3.Controls.Add(this.rbClipBasic);
this.groupBox3.Location = new System.Drawing.Point(7, 131);
this.groupBox3.Name = "groupBox3";
this.groupBox3.Size = new System.Drawing.Size(197, 88);
this.groupBox3.TabIndex = 46;
this.groupBox3.TabStop = false;
this.groupBox3.Text = "Horizontal Overscan Clipping";
//
// rbClipNone
//
this.rbClipNone.AutoSize = true;
this.rbClipNone.Location = new System.Drawing.Point(6, 19);
this.rbClipNone.Name = "rbClipNone";
this.rbClipNone.Size = new System.Drawing.Size(51, 17);
this.rbClipNone.TabIndex = 48;
this.rbClipNone.TabStop = true;
this.rbClipNone.Text = "None";
this.toolTip1.SetToolTip(this.rbClipNone, resources.GetString("rbClipNone.ToolTip"));
this.rbClipNone.UseVisualStyleBackColor = true;
this.rbClipNone.CheckedChanged += new System.EventHandler(this.rbClipNone_CheckedChanged);
//
// rbClipToFramebuffer
//
this.rbClipToFramebuffer.AutoSize = true;
this.rbClipToFramebuffer.Location = new System.Drawing.Point(6, 65);
this.rbClipToFramebuffer.Name = "rbClipToFramebuffer";
this.rbClipToFramebuffer.Size = new System.Drawing.Size(117, 17);
this.rbClipToFramebuffer.TabIndex = 47;
this.rbClipToFramebuffer.TabStop = true;
this.rbClipToFramebuffer.Text = "Clip To Framebuffer";
this.toolTip1.SetToolTip(this.rbClipToFramebuffer, "Subverts mednafen\'s internal video display field emulation to show only the game\'" +
"s framebuffer.\r\nHorizontal letterbox bars may be re-added in Mednafen-style reso" +
"lution modes to maintain correct AR.");
this.rbClipToFramebuffer.UseVisualStyleBackColor = true;
this.rbClipToFramebuffer.CheckedChanged += new System.EventHandler(this.rbClipToFramebuffer_CheckedChanged);
//
// rbClipBasic
//
this.rbClipBasic.AutoSize = true;
this.rbClipBasic.Location = new System.Drawing.Point(6, 42);
this.rbClipBasic.Name = "rbClipBasic";
this.rbClipBasic.Size = new System.Drawing.Size(91, 17);
this.rbClipBasic.TabIndex = 46;
this.rbClipBasic.TabStop = true;
this.rbClipBasic.Text = "Basic Clipping";
this.toolTip1.SetToolTip(this.rbClipBasic, "A mednafen option -- appears to be 5.5% horizontally");
this.rbClipBasic.UseVisualStyleBackColor = true;
this.rbClipBasic.CheckedChanged += new System.EventHandler(this.rbClipHorizontal_CheckedChanged);
//
// lblPAL // lblPAL
// //
this.lblPAL.AutoSize = true; this.lblPAL.AutoSize = true;
this.lblPAL.Location = new System.Drawing.Point(131, 22); this.lblPAL.Location = new System.Drawing.Point(131, 17);
this.lblPAL.Name = "lblPAL"; this.lblPAL.Name = "lblPAL";
this.lblPAL.Size = new System.Drawing.Size(27, 13); this.lblPAL.Size = new System.Drawing.Size(27, 13);
this.lblPAL.TabIndex = 44; this.lblPAL.TabIndex = 44;
@ -241,7 +298,7 @@
// //
// PAL_LastLineNumeric // PAL_LastLineNumeric
// //
this.PAL_LastLineNumeric.Location = new System.Drawing.Point(124, 67); this.PAL_LastLineNumeric.Location = new System.Drawing.Point(124, 62);
this.PAL_LastLineNumeric.Maximum = new decimal(new int[] { this.PAL_LastLineNumeric.Maximum = new decimal(new int[] {
287, 287,
0, 0,
@ -259,7 +316,7 @@
// //
// PAL_FirstLineNumeric // PAL_FirstLineNumeric
// //
this.PAL_FirstLineNumeric.Location = new System.Drawing.Point(124, 41); this.PAL_FirstLineNumeric.Location = new System.Drawing.Point(124, 36);
this.PAL_FirstLineNumeric.Maximum = new decimal(new int[] { this.PAL_FirstLineNumeric.Maximum = new decimal(new int[] {
287, 287,
0, 0,
@ -273,7 +330,7 @@
// lblNTSC // lblNTSC
// //
this.lblNTSC.AutoSize = true; this.lblNTSC.AutoSize = true;
this.lblNTSC.Location = new System.Drawing.Point(62, 22); this.lblNTSC.Location = new System.Drawing.Point(62, 17);
this.lblNTSC.Name = "lblNTSC"; this.lblNTSC.Name = "lblNTSC";
this.lblNTSC.Size = new System.Drawing.Size(36, 13); this.lblNTSC.Size = new System.Drawing.Size(36, 13);
this.lblNTSC.TabIndex = 41; this.lblNTSC.TabIndex = 41;
@ -281,9 +338,9 @@
// //
// btnAreaFull // btnAreaFull
// //
this.btnAreaFull.Location = new System.Drawing.Point(6, 98); this.btnAreaFull.Location = new System.Drawing.Point(8, 94);
this.btnAreaFull.Name = "btnAreaFull"; this.btnAreaFull.Name = "btnAreaFull";
this.btnAreaFull.Size = new System.Drawing.Size(136, 23); this.btnAreaFull.Size = new System.Drawing.Size(163, 23);
this.btnAreaFull.TabIndex = 40; this.btnAreaFull.TabIndex = 40;
this.btnAreaFull.Text = "Full [0,239] and [0,287]"; this.btnAreaFull.Text = "Full [0,239] and [0,287]";
this.btnAreaFull.UseVisualStyleBackColor = true; this.btnAreaFull.UseVisualStyleBackColor = true;
@ -292,7 +349,7 @@
// label4 // label4
// //
this.label4.AutoSize = true; this.label4.AutoSize = true;
this.label4.Location = new System.Drawing.Point(4, 69); this.label4.Location = new System.Drawing.Point(4, 64);
this.label4.Name = "label4"; this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(49, 13); this.label4.Size = new System.Drawing.Size(49, 13);
this.label4.TabIndex = 24; this.label4.TabIndex = 24;
@ -301,7 +358,7 @@
// label1 // label1
// //
this.label1.AutoSize = true; this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(5, 43); this.label1.Location = new System.Drawing.Point(5, 38);
this.label1.Name = "label1"; this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(48, 13); this.label1.Size = new System.Drawing.Size(48, 13);
this.label1.TabIndex = 23; this.label1.TabIndex = 23;
@ -309,7 +366,7 @@
// //
// NTSC_LastLineNumeric // NTSC_LastLineNumeric
// //
this.NTSC_LastLineNumeric.Location = new System.Drawing.Point(59, 67); this.NTSC_LastLineNumeric.Location = new System.Drawing.Point(59, 62);
this.NTSC_LastLineNumeric.Maximum = new decimal(new int[] { this.NTSC_LastLineNumeric.Maximum = new decimal(new int[] {
239, 239,
0, 0,
@ -327,7 +384,7 @@
// //
// NTSC_FirstLineNumeric // NTSC_FirstLineNumeric
// //
this.NTSC_FirstLineNumeric.Location = new System.Drawing.Point(59, 41); this.NTSC_FirstLineNumeric.Location = new System.Drawing.Point(59, 36);
this.NTSC_FirstLineNumeric.Maximum = new decimal(new int[] { this.NTSC_FirstLineNumeric.Maximum = new decimal(new int[] {
239, 239,
0, 0,
@ -338,67 +395,54 @@
this.NTSC_FirstLineNumeric.TabIndex = 21; this.NTSC_FirstLineNumeric.TabIndex = 21;
this.NTSC_FirstLineNumeric.ValueChanged += new System.EventHandler(this.DrawingArea_ValueChanged); this.NTSC_FirstLineNumeric.ValueChanged += new System.EventHandler(this.DrawingArea_ValueChanged);
// //
// groupBox3 // rbWeave
// //
this.groupBox3.Controls.Add(this.label2); this.rbWeave.AutoSize = true;
this.groupBox3.Controls.Add(this.rbClipNone); this.rbWeave.Location = new System.Drawing.Point(6, 19);
this.groupBox3.Controls.Add(this.rbClipToFramebuffer); this.rbWeave.Name = "rbWeave";
this.groupBox3.Controls.Add(this.rbClipBasic); this.rbWeave.Size = new System.Drawing.Size(60, 17);
this.groupBox3.Location = new System.Drawing.Point(7, 132); this.rbWeave.TabIndex = 48;
this.groupBox3.Name = "groupBox3"; this.rbWeave.TabStop = true;
this.groupBox3.Size = new System.Drawing.Size(197, 106); this.rbWeave.Text = "Weave";
this.groupBox3.TabIndex = 46; this.toolTip1.SetToolTip(this.rbWeave, "Good for low-motion video");
this.groupBox3.TabStop = false; this.rbWeave.UseVisualStyleBackColor = true;
this.groupBox3.Text = "Horizontal Overscan Clipping";
// //
// rbClipBasic // rbBobOffset
// //
this.rbClipBasic.AutoSize = true; this.rbBobOffset.AutoSize = true;
this.rbClipBasic.Location = new System.Drawing.Point(6, 42); this.rbBobOffset.Location = new System.Drawing.Point(122, 19);
this.rbClipBasic.Name = "rbClipBasic"; this.rbBobOffset.Name = "rbBobOffset";
this.rbClipBasic.Size = new System.Drawing.Size(91, 17); this.rbBobOffset.Size = new System.Drawing.Size(75, 17);
this.rbClipBasic.TabIndex = 46; this.rbBobOffset.TabIndex = 47;
this.rbClipBasic.TabStop = true; this.rbBobOffset.TabStop = true;
this.rbClipBasic.Text = "Basic Clipping"; this.rbBobOffset.Text = "Bob Offset";
this.toolTip1.SetToolTip(this.rbClipBasic, "A mednafen option -- appears to be 5.5% horizontally"); this.toolTip1.SetToolTip(this.rbBobOffset, "Good for high-motion video, but is a bit flickery; reduces the subjective vertica" +
this.rbClipBasic.UseVisualStyleBackColor = true; "l resolution.");
this.rbClipBasic.CheckedChanged += new System.EventHandler(this.rbClipHorizontal_CheckedChanged); this.rbBobOffset.UseVisualStyleBackColor = true;
// //
// rbClipToFramebuffer // rbBob
// //
this.rbClipToFramebuffer.AutoSize = true; this.rbBob.AutoSize = true;
this.rbClipToFramebuffer.Location = new System.Drawing.Point(6, 65); this.rbBob.Location = new System.Drawing.Point(72, 19);
this.rbClipToFramebuffer.Name = "rbClipToFramebuffer"; this.rbBob.Name = "rbBob";
this.rbClipToFramebuffer.Size = new System.Drawing.Size(117, 17); this.rbBob.Size = new System.Drawing.Size(44, 17);
this.rbClipToFramebuffer.TabIndex = 47; this.rbBob.TabIndex = 46;
this.rbClipToFramebuffer.TabStop = true; this.rbBob.TabStop = true;
this.rbClipToFramebuffer.Text = "Clip To Framebuffer"; this.rbBob.Text = "Bob";
this.toolTip1.SetToolTip(this.rbClipToFramebuffer, "Subverts mednafen\'s internal video display field emulation to show only the game\'" + this.toolTip1.SetToolTip(this.rbBob, "Good for causing a headache. All glory to Bob.");
"s framebuffer."); this.rbBob.UseVisualStyleBackColor = true;
this.rbClipToFramebuffer.UseVisualStyleBackColor = true;
this.rbClipToFramebuffer.CheckedChanged += new System.EventHandler(this.rbClipToFramebuffer_CheckedChanged);
// //
// rbClipNone // groupBox4
// //
this.rbClipNone.AutoSize = true; this.groupBox4.Controls.Add(this.rbWeave);
this.rbClipNone.Location = new System.Drawing.Point(6, 19); this.groupBox4.Controls.Add(this.rbBobOffset);
this.rbClipNone.Name = "rbClipNone"; this.groupBox4.Controls.Add(this.rbBob);
this.rbClipNone.Size = new System.Drawing.Size(51, 17); this.groupBox4.Location = new System.Drawing.Point(492, 251);
this.rbClipNone.TabIndex = 48; this.groupBox4.Name = "groupBox4";
this.rbClipNone.TabStop = true; this.groupBox4.Size = new System.Drawing.Size(212, 49);
this.rbClipNone.Text = "None"; this.groupBox4.TabIndex = 50;
this.toolTip1.SetToolTip(this.rbClipNone, resources.GetString("rbClipNone.ToolTip")); this.groupBox4.TabStop = false;
this.rbClipNone.UseVisualStyleBackColor = true; this.groupBox4.Text = "Deinterlacing";
this.rbClipNone.CheckedChanged += new System.EventHandler(this.rbClipNone_CheckedChanged);
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(29, 83);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(79, 13);
this.label2.TabIndex = 49;
this.label2.Text = "(and break AR)";
// //
// PSXOptions // PSXOptions
// //
@ -406,7 +450,8 @@
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(713, 297); this.ClientSize = new System.Drawing.Size(713, 344);
this.Controls.Add(this.groupBox4);
this.Controls.Add(this.groupBox2); this.Controls.Add(this.groupBox2);
this.Controls.Add(this.groupBox1); this.Controls.Add(this.groupBox1);
this.Controls.Add(this.btnCancel); this.Controls.Add(this.btnCancel);
@ -420,12 +465,14 @@
this.groupBox1.PerformLayout(); this.groupBox1.PerformLayout();
this.groupBox2.ResumeLayout(false); this.groupBox2.ResumeLayout(false);
this.groupBox2.PerformLayout(); this.groupBox2.PerformLayout();
this.groupBox3.ResumeLayout(false);
this.groupBox3.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.PAL_LastLineNumeric)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.PAL_LastLineNumeric)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.PAL_FirstLineNumeric)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.PAL_FirstLineNumeric)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.NTSC_LastLineNumeric)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.NTSC_LastLineNumeric)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.NTSC_FirstLineNumeric)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.NTSC_FirstLineNumeric)).EndInit();
this.groupBox3.ResumeLayout(false); this.groupBox4.ResumeLayout(false);
this.groupBox3.PerformLayout(); this.groupBox4.PerformLayout();
this.ResumeLayout(false); this.ResumeLayout(false);
} }
@ -460,6 +507,9 @@
private System.Windows.Forms.RadioButton rbClipNone; private System.Windows.Forms.RadioButton rbClipNone;
private System.Windows.Forms.RadioButton rbClipToFramebuffer; private System.Windows.Forms.RadioButton rbClipToFramebuffer;
private System.Windows.Forms.RadioButton rbClipBasic; private System.Windows.Forms.RadioButton rbClipBasic;
private System.Windows.Forms.Label label2; private System.Windows.Forms.GroupBox groupBox4;
private System.Windows.Forms.RadioButton rbWeave;
private System.Windows.Forms.RadioButton rbBobOffset;
private System.Windows.Forms.RadioButton rbBob;
} }
} }

View File

@ -40,6 +40,10 @@ namespace BizHawk.Client.EmuHawk
rbClipBasic.Checked = _settings.HorizontalClipping == Octoshock.eHorizontalClipping.Basic; rbClipBasic.Checked = _settings.HorizontalClipping == Octoshock.eHorizontalClipping.Basic;
rbClipToFramebuffer.Checked = _settings.HorizontalClipping == Octoshock.eHorizontalClipping.Framebuffer; rbClipToFramebuffer.Checked = _settings.HorizontalClipping == Octoshock.eHorizontalClipping.Framebuffer;
rbWeave.Checked = _settings.DeinterlaceMode == Octoshock.eDeinterlaceMode.Weave;
rbBob.Checked = _settings.DeinterlaceMode == Octoshock.eDeinterlaceMode.Bob;
rbBobOffset.Checked = _settings.DeinterlaceMode == Octoshock.eDeinterlaceMode.BobOffset;
NTSC_FirstLineNumeric.Value = _settings.ScanlineStart_NTSC; NTSC_FirstLineNumeric.Value = _settings.ScanlineStart_NTSC;
NTSC_LastLineNumeric.Value = _settings.ScanlineEnd_NTSC; NTSC_LastLineNumeric.Value = _settings.ScanlineEnd_NTSC;
PAL_FirstLineNumeric.Value = _settings.ScanlineStart_PAL; PAL_FirstLineNumeric.Value = _settings.ScanlineStart_PAL;
@ -70,7 +74,7 @@ namespace BizHawk.Client.EmuHawk
return result; return result;
} }
void SyncGuiToTheseSettings(Octoshock.Settings settings) void SyncSettingsFromGui(Octoshock.Settings settings)
{ {
if (rbPixelPro.Checked) settings.ResolutionMode = Octoshock.eResolutionMode.PixelPro; if (rbPixelPro.Checked) settings.ResolutionMode = Octoshock.eResolutionMode.PixelPro;
if (rbDebugMode.Checked) settings.ResolutionMode = Octoshock.eResolutionMode.Debug; if (rbDebugMode.Checked) settings.ResolutionMode = Octoshock.eResolutionMode.Debug;
@ -81,6 +85,10 @@ namespace BizHawk.Client.EmuHawk
if (rbClipBasic.Checked) settings.HorizontalClipping = Octoshock.eHorizontalClipping.Basic; if (rbClipBasic.Checked) settings.HorizontalClipping = Octoshock.eHorizontalClipping.Basic;
if (rbClipToFramebuffer.Checked) settings.HorizontalClipping = Octoshock.eHorizontalClipping.Framebuffer; if (rbClipToFramebuffer.Checked) settings.HorizontalClipping = Octoshock.eHorizontalClipping.Framebuffer;
if(rbWeave.Checked) _settings.DeinterlaceMode = Octoshock.eDeinterlaceMode.Weave;
if(rbBob.Checked) _settings.DeinterlaceMode = Octoshock.eDeinterlaceMode.Bob;
if(rbBobOffset.Checked) _settings.DeinterlaceMode = Octoshock.eDeinterlaceMode.BobOffset;
settings.ScanlineStart_NTSC = (int)NTSC_FirstLineNumeric.Value; settings.ScanlineStart_NTSC = (int)NTSC_FirstLineNumeric.Value;
settings.ScanlineEnd_NTSC = (int)NTSC_LastLineNumeric.Value; settings.ScanlineEnd_NTSC = (int)NTSC_LastLineNumeric.Value;
settings.ScanlineStart_PAL = (int)PAL_FirstLineNumeric.Value; settings.ScanlineStart_PAL = (int)PAL_FirstLineNumeric.Value;
@ -97,7 +105,7 @@ namespace BizHawk.Client.EmuHawk
Global.Config.DispFinalFilter = 1; //bilinear, I hope Global.Config.DispFinalFilter = 1; //bilinear, I hope
} }
SyncGuiToTheseSettings(_settings); SyncSettingsFromGui(_settings);
_settings.Validate(); _settings.Validate();
GlobalWin.MainForm.PutCoreSettings(_settings); GlobalWin.MainForm.PutCoreSettings(_settings);
@ -117,7 +125,7 @@ namespace BizHawk.Client.EmuHawk
void SyncLabels() void SyncLabels()
{ {
var temp = _settings.Clone(); var temp = _settings.Clone();
SyncGuiToTheseSettings(temp); SyncSettingsFromGui(temp);
_settings.Validate(); _settings.Validate();
//actually, I think this is irrelevant. But it's nice in case we want to do some kind of a more detailed simulation later //actually, I think this is irrelevant. But it's nice in case we want to do some kind of a more detailed simulation later
@ -125,16 +133,16 @@ namespace BizHawk.Client.EmuHawk
int h = _previewVideoSize.Height; int h = _previewVideoSize.Height;
temp.ResolutionMode = Octoshock.eResolutionMode.PixelPro; temp.ResolutionMode = Octoshock.eResolutionMode.PixelPro;
var size = Octoshock.CalculateResolution(_previewVideoStandard, temp, w, h); var ri = Octoshock.CalculateResolution(_previewVideoStandard, temp, w, h);
lblPixelPro.Text = lblPixelPro_text.Replace("800x480", string.Format("{0}x{1}", size.Width, size.Height)); ; lblPixelPro.Text = lblPixelPro_text.Replace("800x480", string.Format("{0}x{1}", ri.Resolution.Width, ri.Resolution.Height)); ;
temp.ResolutionMode = Octoshock.eResolutionMode.Mednafen; temp.ResolutionMode = Octoshock.eResolutionMode.Mednafen;
size = Octoshock.CalculateResolution(_previewVideoStandard, temp, w, h); ri = Octoshock.CalculateResolution(_previewVideoStandard, temp, w, h);
lblMednafen.Text = lblMednafen_text.Replace("320x240", string.Format("{0}x{1}", size.Width, size.Height)); lblMednafen.Text = lblMednafen_text.Replace("320x240", string.Format("{0}x{1}", ri.Resolution.Width, ri.Resolution.Height));
temp.ResolutionMode = Octoshock.eResolutionMode.TweakedMednafen; temp.ResolutionMode = Octoshock.eResolutionMode.TweakedMednafen;
size = Octoshock.CalculateResolution(_previewVideoStandard, temp, w, h); ri = Octoshock.CalculateResolution(_previewVideoStandard, temp, w, h);
lblTweakedMednafen.Text = lblTweakedMednafen_text.Replace("400x300", string.Format("{0}x{1}", size.Width, size.Height)); lblTweakedMednafen.Text = lblTweakedMednafen_text.Replace("400x300", string.Format("{0}x{1}", ri.Resolution.Width, ri.Resolution.Height));
} }
private void DrawingArea_ValueChanged(object sender, EventArgs e) private void DrawingArea_ValueChanged(object sender, EventArgs e)
@ -172,5 +180,7 @@ But: 1. we think we improved on it a tiny bit with the tweaked mode
And: 2. It's not suitable for detailed scrutinizing of graphics And: 2. It's not suitable for detailed scrutinizing of graphics
"); ");
} }
} }
} }

View File

@ -102,7 +102,7 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
ControllerDefinition.FloatRanges.Add( ControllerDefinition.FloatRanges.Add(
//new[] {-1f,-1f,-1f} //this is carefully chosen so that we end up with a -1 disc by default (indicating that it's never been set) //new[] {-1f,-1f,-1f} //this is carefully chosen so that we end up with a -1 disc by default (indicating that it's never been set)
//hmm.. I don't see why this wouldn't work //hmm.. I don't see why this wouldn't work
new[] {0f,1f,1f} new[] { 0f, 1f, 1f }
); );
} }
@ -327,9 +327,10 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
BufferHeight = 288; BufferHeight = 288;
} }
CurrentVideoSize = new System.Drawing.Size(BufferWidth, BufferHeight); CurrentVideoSize = new System.Drawing.Size(BufferWidth, BufferHeight);
var size = Octoshock.CalculateResolution(SystemVidStandard, _Settings, BufferWidth, BufferHeight); var ri = Octoshock.CalculateResolution(SystemVidStandard, _Settings, BufferWidth, BufferHeight);
BufferWidth = VirtualWidth = size.Width; BufferWidth = VirtualWidth = ri.Resolution.Width;
BufferHeight = VirtualHeight = size.Height; BufferHeight = VirtualHeight = ri.Resolution.Height;
//VideoProvider_Padding = new System.Drawing.Size(50,50);
frameBuffer = new int[BufferWidth * BufferHeight]; frameBuffer = new int[BufferWidth * BufferHeight];
} }
@ -354,7 +355,7 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
else else
{ {
//must be a psf //must be a psf
if(psf.LibData != null) if (psf.LibData != null)
fixed (byte* pBuf = psf.LibData) fixed (byte* pBuf = psf.LibData)
OctoshockDll.shock_MountEXE(psx, pBuf, psf.LibData.Length, true); OctoshockDll.shock_MountEXE(psx, pBuf, psf.LibData.Length, true);
fixed (byte* pBuf = psf.Data) fixed (byte* pBuf = psf.Data)
@ -369,7 +370,7 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
//setup the controller based on sync settings //setup the controller based on sync settings
SetControllerButtons(); SetControllerButtons();
var lookup = new Dictionary<ControllerSetting.ControllerType,OctoshockDll.ePeripheralType> { var lookup = new Dictionary<ControllerSetting.ControllerType, OctoshockDll.ePeripheralType> {
{ ControllerSetting.ControllerType.Gamepad, OctoshockDll.ePeripheralType.Pad }, { ControllerSetting.ControllerType.Gamepad, OctoshockDll.ePeripheralType.Pad },
{ ControllerSetting.ControllerType.DualAnalog, OctoshockDll.ePeripheralType.DualAnalog }, { ControllerSetting.ControllerType.DualAnalog, OctoshockDll.ePeripheralType.DualAnalog },
{ ControllerSetting.ControllerType.DualShock, OctoshockDll.ePeripheralType.DualShock }, { ControllerSetting.ControllerType.DualShock, OctoshockDll.ePeripheralType.DualShock },
@ -482,12 +483,21 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
} }
} }
public class ResolutionInfo
{
public System.Drawing.Size Resolution, Padding;
public System.Drawing.Size Total { get { return System.Drawing.Size.Add(Resolution, Padding); } }
}
/// <summary> /// <summary>
/// Calculates what the output resolution would be for the given input resolution and settings /// Calculates what the output resolution would be for the given input resolution and settings
/// </summary> /// </summary>
public static System.Drawing.Size CalculateResolution(OctoshockDll.eVidStandard standard, Settings settings, int w, int h) public static ResolutionInfo CalculateResolution(OctoshockDll.eVidStandard standard, Settings settings, int w, int h)
{ {
ResolutionInfo ret = new ResolutionInfo();
//some of this logic is duplicated in the c++ side, be sure to check there //some of this logic is duplicated in the c++ side, be sure to check there
//TODO - scanline control + framebuffer mode is majorly broken
int virtual_width = 800; int virtual_width = 800;
if (settings.HorizontalClipping == eHorizontalClipping.Basic) virtual_width = 768; if (settings.HorizontalClipping == eHorizontalClipping.Basic) virtual_width = 768;
@ -496,39 +506,105 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
int scanline_start = standard == OctoshockDll.eVidStandard.NTSC ? settings.ScanlineStart_NTSC : settings.ScanlineStart_PAL; int scanline_start = standard == OctoshockDll.eVidStandard.NTSC ? settings.ScanlineStart_NTSC : settings.ScanlineStart_PAL;
int scanline_end = standard == OctoshockDll.eVidStandard.NTSC ? settings.ScanlineEnd_NTSC : settings.ScanlineEnd_PAL; int scanline_end = standard == OctoshockDll.eVidStandard.NTSC ? settings.ScanlineEnd_NTSC : settings.ScanlineEnd_PAL;
int scanline_num = scanline_end - scanline_start + 1; int scanline_num = scanline_end - scanline_start + 1;
//int scanline_num = h; // I wanted to do this, but our logic for mednafen modes here is based on un-doubled resolution. i could do a hack to divide it by 2 though
int real_scanline_num = standard == OctoshockDll.eVidStandard.NTSC ? 240 : 288; int real_scanline_num = standard == OctoshockDll.eVidStandard.NTSC ? 240 : 288;
int VirtualWidth=-1, VirtualHeight=-1; int VirtualWidth=-1, VirtualHeight=-1;
switch (settings.ResolutionMode) switch (settings.ResolutionMode)
{ {
case eResolutionMode.Debug:
VirtualWidth = w;
VirtualHeight = h;
break;
case eResolutionMode.Mednafen: case eResolutionMode.Mednafen:
VirtualWidth = 320;
if (settings.HorizontalClipping == eHorizontalClipping.Basic) //mednafen uses 320xScanlines as the 1x size
VirtualWidth = 302; //it does change the 1x width when doing basic clipping.
//? not sure what this should be //and it does easily change the height when doing scanline removal.
if (settings.HorizontalClipping == eHorizontalClipping.Framebuffer) //now, our framebuffer cropping mode is more complex...
VirtualWidth = 320; VirtualWidth = (standard == OctoshockDll.eVidStandard.NTSC) ? 320 : 363;
VirtualHeight = scanline_num; VirtualHeight = scanline_num;
if (settings.HorizontalClipping == eHorizontalClipping.Basic)
VirtualWidth = (standard == OctoshockDll.eVidStandard.NTSC) ? 302 : 384;
if (settings.HorizontalClipping == eHorizontalClipping.Framebuffer)
{
//mednafen typically sends us a framebuffer with overscan. 350x240 is a nominal example here. it's squished inward to 320x240 for correct PAR.
//ok: here we have a framebuffer without overscan. 320x240 nominal. So the VirtualWidth of what we got is off by a factor of 109.375%
//so a beginning approach would be this:
//VirtualWidth = (int)(VirtualWidth * 320.0f / 350);
//but that will shrink things which are already annoyingly shrunken.
//therefore, lets do that, but then scale the whole window by the same factor so the width becomes unscaled and now the height is scaled up!
//weird, huh?
VirtualHeight = (int)(VirtualHeight * 350.0f / 320);
//now unfortunately we may have lost vertical pixels. common in the case of PAL (rendering 256 on a field of 288)
//therefore we'll be stretching way too much vertically here.
//lets add those pixels back with a new hack
if (standard == OctoshockDll.eVidStandard.PAL)
{
if (h > 288) ret.Padding = new System.Drawing.Size(0, 576 - h);
else ret.Padding = new System.Drawing.Size(0, 288 - h);
}
else
{
if (h > 288) ret.Padding = new System.Drawing.Size(0, 480 - h);
else ret.Padding = new System.Drawing.Size(0, 240 - h);
}
}
break; break;
//384 / 288 = 1.3333333333333333333333333333333
case eResolutionMode.TweakedMednafen:
if (standard == OctoshockDll.eVidStandard.NTSC)
{
//dont make this 430, it's already been turned into 400 from 368+30 and then some fudge factor
VirtualWidth = 400;
VirtualHeight = (int)(scanline_num * 300.0f / 240);
if (settings.HorizontalClipping == eHorizontalClipping.Basic)
VirtualWidth = 378;
}
else
{
//this is a bit tricky. we know we want 400 for the virtualwidth.
VirtualWidth = 400;
if (settings.HorizontalClipping == eHorizontalClipping.Basic)
VirtualWidth = 378;
//I'll be honest, I was just guessing here mostly
//I need the AR to basically work out to be 363/288 (thats what it was in mednafen mode) so...
VirtualHeight = (int)(scanline_num * (400.0f/363*288) / 288);
}
if (settings.HorizontalClipping == eHorizontalClipping.Framebuffer)
{
//see discussion above
VirtualHeight = (int)(VirtualHeight * 350.0f / 320);
if (standard == OctoshockDll.eVidStandard.PAL)
{
if (h > 288) ret.Padding = new System.Drawing.Size(0, 576 - h);
else ret.Padding = new System.Drawing.Size(0, 288 - h);
}
else
{
if (h > 288) ret.Padding = new System.Drawing.Size(0, 480 - h);
else ret.Padding = new System.Drawing.Size(0, 240 - h);
}
}
break;
case eResolutionMode.PixelPro: case eResolutionMode.PixelPro:
VirtualWidth = virtual_width; VirtualWidth = virtual_width;
VirtualHeight = scanline_num * 2; VirtualHeight = scanline_num * 2;
break; break;
case eResolutionMode.TweakedMednafen:
VirtualWidth = 400; case eResolutionMode.Debug:
if (settings.HorizontalClipping == eHorizontalClipping.Basic) VirtualWidth = w;
VirtualWidth = 378; VirtualHeight = h;
if (settings.HorizontalClipping == eHorizontalClipping.Framebuffer)
VirtualWidth = 400;
VirtualHeight = (int)(scanline_num * 300.0f / real_scanline_num);
break; break;
} }
return new System.Drawing.Size(VirtualWidth, VirtualHeight); ret.Resolution = new System.Drawing.Size(VirtualWidth, VirtualHeight);
return ret;
} }
void PokeDisc() void PokeDisc()
@ -551,7 +627,7 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
//if tray open is requested, and valid, apply it //if tray open is requested, and valid, apply it
//in the first frame, go ahead and open it up so we have a chance to put a disc in it //in the first frame, go ahead and open it up so we have a chance to put a disc in it
if (Controller["Open"] && !CurrentTrayOpen || Frame==0) if (Controller["Open"] && !CurrentTrayOpen || Frame == 0)
{ {
OctoshockDll.shock_OpenTray(psx); OctoshockDll.shock_OpenTray(psx);
CurrentTrayOpen = true; CurrentTrayOpen = true;
@ -624,6 +700,10 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
if (_Settings.HorizontalClipping == eHorizontalClipping.Framebuffer) if (_Settings.HorizontalClipping == eHorizontalClipping.Framebuffer)
ropts.renderType = OctoshockDll.eShockRenderType.Framebuffer; ropts.renderType = OctoshockDll.eShockRenderType.Framebuffer;
if (_Settings.DeinterlaceMode == eDeinterlaceMode.Weave) ropts.deinterlaceMode = OctoshockDll.eShockDeinterlaceMode.Weave;
if (_Settings.DeinterlaceMode == eDeinterlaceMode.Bob) ropts.deinterlaceMode = OctoshockDll.eShockDeinterlaceMode.Bob;
if (_Settings.DeinterlaceMode == eDeinterlaceMode.BobOffset) ropts.deinterlaceMode = OctoshockDll.eShockDeinterlaceMode.BobOffset;
OctoshockDll.shock_SetRenderOptions(psx, ref ropts); OctoshockDll.shock_SetRenderOptions(psx, ref ropts);
//prep tracer //prep tracer
@ -668,9 +748,10 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
BufferWidth = w; BufferWidth = w;
BufferHeight = h; BufferHeight = h;
var size = CalculateResolution(this.SystemVidStandard, _Settings, w, h); var ri = CalculateResolution(this.SystemVidStandard, _Settings, w, h);
VirtualWidth = size.Width; VirtualWidth = ri.Resolution.Width;
VirtualHeight = size.Height; VirtualHeight = ri.Resolution.Height;
VideoProvider_Padding = ri.Padding;
int len = w * h; int len = w * h;
if (frameBuffer.Length != len) if (frameBuffer.Length != len)
@ -709,6 +790,7 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
public int BufferWidth { get; private set; } public int BufferWidth { get; private set; }
public int BufferHeight { get; private set; } public int BufferHeight { get; private set; }
public int BackgroundColor { get { return 0; } } public int BackgroundColor { get { return 0; } }
public System.Drawing.Size VideoProvider_Padding { get; private set; }
#region Debugging #region Debugging
@ -876,7 +958,7 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
transaction.transaction = OctoshockDll.eShockStateTransaction.BinarySize; transaction.transaction = OctoshockDll.eShockStateTransaction.BinarySize;
int size = OctoshockDll.shock_StateTransaction(psx, ref transaction); int size = OctoshockDll.shock_StateTransaction(psx, ref transaction);
savebuff = new byte[size]; savebuff = new byte[size];
savebuff2 = new byte[savebuff.Length + 4+ 4+4+1+1+4]; savebuff2 = new byte[savebuff.Length + 4 + 4 + 4 + 1 + 1 + 4];
} }
public void SaveStateBinary(BinaryWriter writer) public void SaveStateBinary(BinaryWriter writer)
@ -1019,6 +1101,13 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
Framebuffer Framebuffer
} }
public enum eDeinterlaceMode
{
Weave,
Bob,
BobOffset
}
public class Settings public class Settings
{ {
[DisplayName("Resolution Mode")] [DisplayName("Resolution Mode")]
@ -1046,6 +1135,9 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
[DefaultValue(287)] [DefaultValue(287)]
public int ScanlineEnd_PAL { get; set; } public int ScanlineEnd_PAL { get; set; }
[DisplayName("DeinterlaceMode")]
[DefaultValue(eDeinterlaceMode.Weave)]
public eDeinterlaceMode DeinterlaceMode { get; set; }
public void Validate() public void Validate()
{ {

View File

@ -89,6 +89,13 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
Framebuffer Framebuffer
}; };
public enum eShockDeinterlaceMode : int
{
Weave,
Bob,
BobOffset
}
public const int SHOCK_OK = 0; public const int SHOCK_OK = 0;
public const int SHOCK_FALSE = 0; public const int SHOCK_FALSE = 0;
public const int SHOCK_TRUE = 1; public const int SHOCK_TRUE = 1;
@ -134,6 +141,7 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
{ {
public int scanline_start, scanline_end; public int scanline_start, scanline_end;
public eShockRenderType renderType; public eShockRenderType renderType;
public eShockDeinterlaceMode deinterlaceMode;
public bool skip; public bool skip;
}; };

Binary file not shown.

View File

@ -46,6 +46,14 @@
//extern MDFNGI EmulatedPSX; //extern MDFNGI EmulatedPSX;
int16 soundbuf[1024 * 1024]; //how big? big enough.
int VTBackBuffer = 0;
static MDFN_Rect VTDisplayRects[2];
#include "video/Deinterlacer.h"
static bool PrevInterlaced;
static Deinterlacer deint;
static EmulateSpecStruct espec;
namespace MDFN_IEN_PSX namespace MDFN_IEN_PSX
{ {
@ -983,6 +991,8 @@ static void PSX_Power(bool powering_up)
IRQ_Power(); IRQ_Power();
ForceEventUpdates(0); ForceEventUpdates(0);
deint.ClearState();
} }
@ -1344,14 +1354,6 @@ EW_EXPORT s32 shock_PowerOff(void* psx)
return SHOCK_ERROR; return SHOCK_ERROR;
} }
int16 soundbuf[1024*1024]; //how big? big enough.
int VTBackBuffer = 0;
static MDFN_Rect VTDisplayRects[2];
#include "video/Deinterlacer.h"
static bool PrevInterlaced;
static Deinterlacer deint;
static EmulateSpecStruct espec;
EW_EXPORT s32 shock_Step(void* psx, eShockStep step) EW_EXPORT s32 shock_Step(void* psx, eShockStep step)
{ {
//only eShockStep_Frame is supported //only eShockStep_Frame is supported
@ -1378,6 +1380,13 @@ EW_EXPORT s32 shock_Step(void* psx, eShockStep step)
//not sure about this //not sure about this
espec.skip = s_ShockConfig.opts.skip; espec.skip = s_ShockConfig.opts.skip;
if (s_ShockConfig.opts.deinterlaceMode == eShockDeinterlaceMode_Weave)
deint.SetType(Deinterlacer::DEINT_WEAVE);
if (s_ShockConfig.opts.deinterlaceMode == eShockDeinterlaceMode_Bob)
deint.SetType(Deinterlacer::DEINT_BOB);
if (s_ShockConfig.opts.deinterlaceMode == eShockDeinterlaceMode_BobOffset)
deint.SetType(Deinterlacer::DEINT_BOB_OFFSET);
//------------------------- //-------------------------
FIO->UpdateInput(); FIO->UpdateInput();
@ -1442,6 +1451,57 @@ EW_EXPORT s32 shock_Step(void* psx, eShockStep step)
return SHOCK_OK; return SHOCK_OK;
} }
struct FramebufferCropInfo
{
int width, height, xo, yo;
};
static void _shock_AnalyzeFramebufferCropInfo(int fbIndex, FramebufferCropInfo* info)
{
//presently, except for contrived test programs, it is safe to assume this is the same for the entire frame (no known use by games)
//however, due to the dump_framebuffer, it may be incorrect at scanline 0. so lets use another one for the heuristic here
//you'd think we could use FirstLine instead of kScanlineWidthHeuristicIndex, but sometimes it hasnt been set (screen off) so it's confusing
int width = VTLineWidths[fbIndex][kScanlineWidthHeuristicIndex];
int height = espec.DisplayRect.h;
int yo = espec.DisplayRect.y;
//fix a common error here from disabled screens (?)
//I think we're lucky in selecting these lines kind of randomly. need a better plan.
if (width <= 0) width = VTLineWidths[fbIndex][0];
if (s_ShockConfig.opts.renderType == eShockRenderType_Framebuffer)
{
//printf("%d %d %d %d | %d | %d\n",yo,height, GPU->GetVertStart(), GPU->GetVertEnd(), espec.DisplayRect.y, GPU->FirstLine);
height = GPU->GetVertEnd() - GPU->GetVertStart();
yo = GPU->FirstLine;
if (espec.DisplayRect.h == 288 || espec.DisplayRect.h == 240)
{
}
else
{
height *= 2;
//only return even scanlines to avoid bouncing the interlacing
if (yo & 1) yo--;
}
//this can happen when the display turns on mid-frame
//maybe an off by one error here..?
if (yo + height >= espec.DisplayRect.h)
yo = espec.DisplayRect.h - height;
//sometimes when changing modes we have trouble..?
if (yo<0) yo = 0;
}
info->width = width;
info->height = height;
info->xo = 0;
info->yo = yo;
}
//`normalizes` the framebuffer to 700x480 by pixel doubling and wrecking the AR a little bit as needed //`normalizes` the framebuffer to 700x480 by pixel doubling and wrecking the AR a little bit as needed
void NormalizeFramebuffer() void NormalizeFramebuffer()
{ {
@ -1470,13 +1530,14 @@ void NormalizeFramebuffer()
//NOTE: this approach is very redundant with the displaymanager AR tracking stuff //NOTE: this approach is very redundant with the displaymanager AR tracking stuff
//however, it will help us avoid stressing the displaymanager (for example, a 700x240 will freak it out kind of. we could send it a much more sensible 700x480) //however, it will help us avoid stressing the displaymanager (for example, a 700x240 will freak it out kind of. we could send it a much more sensible 700x480)
//always fetch description
FramebufferCropInfo cropInfo;
_shock_AnalyzeFramebufferCropInfo(0, &cropInfo);
int width = cropInfo.width;
int height = cropInfo.height;
//presently, except for contrived test programs, it is safe to assume this is the same for the entire frame (no known use by games)
int width = VTLineWidths[0][kScanlineWidthHeuristicIndex];
if(width <= 0) VTLineWidths[0][0];
int height = espec.DisplayRect.h;
int virtual_width = 800; int virtual_width = 800;
int virtual_height = 480;
if (s_ShockConfig.opts.renderType == eShockRenderType_ClipOverscan) if (s_ShockConfig.opts.renderType == eShockRenderType_ClipOverscan)
virtual_width = 756; virtual_width = 756;
@ -1487,7 +1548,7 @@ void NormalizeFramebuffer()
virtual_width = 736; virtual_width = 736;
} }
int xs=1,ys=1,xm=0; int xs=1,ys=1;
//I. as described above //I. as described above
//if(width == 280 && height == 240) {} //if(width == 280 && height == 240) {}
@ -1509,17 +1570,27 @@ void NormalizeFramebuffer()
if(width > 400 && height <= 288) ys=2; if(width > 400 && height <= 288) ys=2;
if(width <= 400 && height > 288) xs=2; if(width <= 400 && height > 288) xs=2;
if(width > 400 && height > 288) {} if(width > 400 && height > 288) {}
//TODO - shrink it entirely if cropping. EDIT-any idea what this means? if you figure it out, just do it. //TODO - shrink it entirely if cropping. EDIT-any idea what this means? if you figure it out, just do it.
xm = (virtual_width-width*xs)/2;
int xm = (virtual_width - width*xs) / 2;
int ym = (virtual_height - height*ys) / 2;
int curr = 0; int curr = 0;
//1. double the height, while cropping down //1. double the height, while cropping down
if(ys==2) //should handle ntsc or pal, but not tested yet for pal if(height != virtual_height)
{ {
uint32* src = VTBuffer[curr]->pixels + (s_ShockConfig.fb_width*espec.DisplayRect.y) + espec.DisplayRect.x; uint32* src = VTBuffer[curr]->pixels + (s_ShockConfig.fb_width*espec.DisplayRect.y) + espec.DisplayRect.x;
uint32* dst = VTBuffer[curr^1]->pixels; uint32* dst = VTBuffer[curr^1]->pixels;
int tocopy = width*4; int tocopy = width*4;
//float from top as needed
memset(dst, 0, ym*tocopy);
dst += width;
if(ys==2)
{
for(int y=0;y<height;y++) for(int y=0;y<height;y++)
{ {
memcpy(dst,src,tocopy); memcpy(dst,src,tocopy);
@ -1528,9 +1599,24 @@ void NormalizeFramebuffer()
dst += width; dst += width;
src += s_FramebufferCurrentWidth; src += s_FramebufferCurrentWidth;
} }
}
else
{
for(int y=0;y<height;y++)
{
memcpy(dst, src, tocopy);
dst += width;
src += s_FramebufferCurrentWidth;
}
}
//fill bottom
int remaining_lines = virtual_height - ym - height*ys;
memset(dst, 0, remaining_lines*tocopy);
//patch up the metrics //patch up the metrics
height *= 2; height = virtual_height; //we floated the content vertically, so this becomes the new height
espec.DisplayRect.x = 0; espec.DisplayRect.x = 0;
espec.DisplayRect.y = 0; espec.DisplayRect.y = 0;
espec.DisplayRect.h = height; espec.DisplayRect.h = height;
@ -1571,7 +1657,8 @@ void NormalizeFramebuffer()
} }
//float the content horizontally //float the content horizontally
for(int x=0;x<xm;x++) int remaining_pixels = virtual_width - xm - width*xs;
for(int x=0;x<remaining_pixels;x++)
*dst++ = 0; *dst++ = 0;
} }
@ -1600,6 +1687,7 @@ EW_EXPORT s32 shock_GetSamples(void* psx, void* buffer)
return espec.SoundBufSize; return espec.SoundBufSize;
} }
EW_EXPORT s32 shock_GetFramebuffer(void* psx, ShockFramebufferInfo* fb) EW_EXPORT s32 shock_GetFramebuffer(void* psx, ShockFramebufferInfo* fb)
{ {
//TODO - fastpath for emitting to the final framebuffer, although if we did that, we'd have to regenerate it every time //TODO - fastpath for emitting to the final framebuffer, although if we did that, we'd have to regenerate it every time
@ -1616,40 +1704,16 @@ EW_EXPORT s32 shock_GetFramebuffer(void* psx, ShockFramebufferInfo* fb)
int fbIndex = s_FramebufferCurrent; int fbIndex = s_FramebufferCurrent;
//always fetch description //always fetch description
//presently, except for contrived test programs, it is safe to assume this is the same for the entire frame (no known use by games) FramebufferCropInfo cropInfo;
//however, due to the dump_framebuffer, it may be incorrect at scanline 0. so lets use another one for the heuristic here _shock_AnalyzeFramebufferCropInfo(fbIndex, &cropInfo);
//you'd think we could use FirstLine instead of kScanlineWidthHeuristicIndex, but sometimes it hasnt been set (screen off) so it's confusing int width = cropInfo.width;
int width = VTLineWidths[fbIndex][kScanlineWidthHeuristicIndex]; int height = cropInfo.height;
int height = espec.DisplayRect.h; int yo = cropInfo.yo;
int yo = espec.DisplayRect.y;
//fix a common error here from disabled screens (?) //sloppy, but the above AnalyzeFramebufferCropInfo() will give us too short of a buffer
//I think we're lucky in selecting these lines kind of randomly. need a better plan. if(fb->flags & eShockFramebufferFlags_Normalize)
if(width <= 0) width = VTLineWidths[fbIndex][0];
if (s_ShockConfig.opts.renderType == eShockRenderType_Framebuffer)
{ {
//printf("%d %d %d %d | %d | %d\n",yo,height, GPU->GetVertStart(), GPU->GetVertEnd(), espec.DisplayRect.y, GPU->FirstLine); height = espec.DisplayRect.h;
height = GPU->GetVertEnd() - GPU->GetVertStart();
yo = GPU->FirstLine;
if(espec.DisplayRect.h == 288 || espec.DisplayRect.h == 240)
{}
else
{
height *= 2;
//only return even scanlines to avoid bouncing the interlacing
if(yo&1) yo--;
}
//this can happen when the display turns on mid-frame
//maybe an off by one error here..?
if (yo + height >= espec.DisplayRect.h)
yo = espec.DisplayRect.h - height;
//sometimes when changing modes we have trouble..?
if (yo<0) yo = 0;
} }
fb->width = width; fb->width = width;

View File

@ -123,6 +123,13 @@ enum eRegion
REGION_NONE = 3 REGION_NONE = 3
}; };
enum eShockDeinterlaceMode
{
eShockDeinterlaceMode_Weave,
eShockDeinterlaceMode_Bob,
eShockDeinterlaceMode_BobOffset
};
enum eShockStep enum eShockStep
{ {
eShockStep_Frame eShockStep_Frame
@ -288,6 +295,7 @@ struct ShockRenderOptions
{ {
s32 scanline_start, scanline_end; s32 scanline_start, scanline_end;
eShockRenderType renderType; eShockRenderType renderType;
eShockDeinterlaceMode deinterlaceMode;
bool skip; bool skip;
}; };