psx - settings framework and implement mednafen-compatible display mode

This commit is contained in:
zeromus 2014-12-14 08:48:23 +00:00
parent 7c9f7706d3
commit ede9620446
10 changed files with 469 additions and 321 deletions

View File

@ -261,7 +261,7 @@ namespace BizHawk.Client.Common
nextEmulator = new PSP(nextComm, file.Name); nextEmulator = new PSP(nextComm, file.Name);
break; break;
case "PSX": case "PSX":
nextEmulator = new Octoshock(nextComm, disc, null); nextEmulator = new Octoshock(nextComm, disc, null, GetCoreSettings<Octoshock>(), GetCoreSyncSettings<Octoshock>());
nextEmulator.CoreComm.RomStatusDetails = "PSX etc."; nextEmulator.CoreComm.RomStatusDetails = "PSX etc.";
break; break;
case "PCE": case "PCE":
@ -423,7 +423,7 @@ namespace BizHawk.Client.Common
core = CoreInventory.Instance["GBA", "VBA-Next"]; core = CoreInventory.Instance["GBA", "VBA-Next"];
break; break;
case "PSX": case "PSX":
nextEmulator = new Octoshock(nextComm, null, rom.FileData); nextEmulator = new Octoshock(nextComm, null, rom.FileData, GetCoreSettings<Octoshock>(), GetCoreSyncSettings<Octoshock>());
nextEmulator.CoreComm.RomStatusDetails = "PSX etc."; nextEmulator.CoreComm.RomStatusDetails = "PSX etc.";
break; break;
case "DEBUG": case "DEBUG":

View File

@ -539,6 +539,7 @@
</Compile> </Compile>
<Compile Include="MainForm.Hotkey.cs"> <Compile Include="MainForm.Hotkey.cs">
<DependentUpon>MainForm.cs</DependentUpon> <DependentUpon>MainForm.cs</DependentUpon>
<SubType>Form</SubType>
</Compile> </Compile>
<Compile Include="MainForm.Movie.cs"> <Compile Include="MainForm.Movie.cs">
<DependentUpon>MainForm.cs</DependentUpon> <DependentUpon>MainForm.cs</DependentUpon>

View File

@ -1786,8 +1786,11 @@ namespace BizHawk.Client.EmuHawk
private void PSXOptionsMenuItem_Click(object sender, EventArgs e) private void PSXOptionsMenuItem_Click(object sender, EventArgs e)
{ {
//help me, i dont want to mess with doing this the right way right now var result = PSXOptions.DoSettingsDialog(this);
new PSXOptions().ShowDialog(); if (result == DialogResult.OK)
{
FrameBufferResized();
}
} }
private void FlushSaveRAMMenuItem_Click(object sender, EventArgs e) private void FlushSaveRAMMenuItem_Click(object sender, EventArgs e)
@ -2091,7 +2094,7 @@ namespace BizHawk.Client.EmuHawk
if (result == DialogResult.OK) if (result == DialogResult.OK)
{ {
FrameBufferResized(); FrameBufferResized();
SynchChrome(); //not sure if we'll end up needing to do this due to framebuffer resizing, putting it here for now anyway though SynchChrome();
} }
} }

View File

@ -32,19 +32,19 @@
this.btnCancel = new System.Windows.Forms.Button(); this.btnCancel = new System.Windows.Forms.Button();
this.btnOk = new System.Windows.Forms.Button(); this.btnOk = new System.Windows.Forms.Button();
this.groupBox1 = new System.Windows.Forms.GroupBox(); this.groupBox1 = new System.Windows.Forms.GroupBox();
this.button1 = new System.Windows.Forms.Button(); this.btnNiceDisplayConfig = new System.Windows.Forms.Button();
this.label2 = new System.Windows.Forms.Label(); this.label2 = new System.Windows.Forms.Label();
this.radioButton2 = new System.Windows.Forms.RadioButton(); this.rbMednafenMode = new System.Windows.Forms.RadioButton();
this.label8 = new System.Windows.Forms.Label(); this.label8 = new System.Windows.Forms.Label();
this.radioButton1 = new System.Windows.Forms.RadioButton(); this.rbPixelPro = new System.Windows.Forms.RadioButton();
this.label3 = new System.Windows.Forms.Label();
this.checkBox1 = new System.Windows.Forms.CheckBox();
this.groupBox2 = new System.Windows.Forms.GroupBox(); this.groupBox2 = new System.Windows.Forms.GroupBox();
this.label6 = new System.Windows.Forms.Label();
this.label1 = new System.Windows.Forms.Label(); this.label1 = new System.Windows.Forms.Label();
this.label5 = new System.Windows.Forms.Label(); this.label5 = new System.Windows.Forms.Label();
this.label4 = new System.Windows.Forms.Label();
this.label7 = new System.Windows.Forms.Label(); this.label7 = new System.Windows.Forms.Label();
this.rbDebugMode = new System.Windows.Forms.RadioButton();
this.label3 = new System.Windows.Forms.Label();
this.rbTweakedMednafenMode = new System.Windows.Forms.RadioButton();
this.label9 = new System.Windows.Forms.Label();
this.groupBox1.SuspendLayout(); this.groupBox1.SuspendLayout();
this.groupBox2.SuspendLayout(); this.groupBox2.SuspendLayout();
this.SuspendLayout(); this.SuspendLayout();
@ -53,7 +53,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(437, 347); this.btnCancel.Location = new System.Drawing.Point(622, 240);
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;
@ -63,59 +63,65 @@
// 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(356, 347); this.btnOk.Location = new System.Drawing.Point(541, 240);
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;
this.btnOk.Text = "OK"; this.btnOk.Text = "OK";
this.btnOk.UseVisualStyleBackColor = true; this.btnOk.UseVisualStyleBackColor = true;
this.btnOk.Click += new System.EventHandler(this.btnOk_Click);
// //
// groupBox1 // groupBox1
// //
this.groupBox1.Controls.Add(this.button1); this.groupBox1.Controls.Add(this.label9);
this.groupBox1.Controls.Add(this.rbTweakedMednafenMode);
this.groupBox1.Controls.Add(this.label3);
this.groupBox1.Controls.Add(this.rbDebugMode);
this.groupBox1.Controls.Add(this.btnNiceDisplayConfig);
this.groupBox1.Controls.Add(this.label2); this.groupBox1.Controls.Add(this.label2);
this.groupBox1.Controls.Add(this.radioButton2); this.groupBox1.Controls.Add(this.rbMednafenMode);
this.groupBox1.Controls.Add(this.label8); this.groupBox1.Controls.Add(this.label8);
this.groupBox1.Controls.Add(this.radioButton1); this.groupBox1.Controls.Add(this.rbPixelPro);
this.groupBox1.Location = new System.Drawing.Point(12, 12); this.groupBox1.Location = new System.Drawing.Point(12, 7);
this.groupBox1.Name = "groupBox1"; this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(276, 265); this.groupBox1.Size = new System.Drawing.Size(474, 256);
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";
// //
// button1 // btnNiceDisplayConfig
// //
this.button1.AutoSize = true; this.btnNiceDisplayConfig.AutoSize = true;
this.button1.Location = new System.Drawing.Point(46, 225); this.btnNiceDisplayConfig.Location = new System.Drawing.Point(140, 221);
this.button1.Name = "button1"; this.btnNiceDisplayConfig.Name = "btnNiceDisplayConfig";
this.button1.Size = new System.Drawing.Size(173, 23); this.btnNiceDisplayConfig.Size = new System.Drawing.Size(173, 23);
this.button1.TabIndex = 24; this.btnNiceDisplayConfig.TabIndex = 24;
this.button1.Text = "Change My Display Configuration"; this.btnNiceDisplayConfig.Text = "Change My Display Options";
this.button1.UseVisualStyleBackColor = true; this.btnNiceDisplayConfig.UseVisualStyleBackColor = true;
this.btnNiceDisplayConfig.Click += new System.EventHandler(this.btnNiceDisplayConfig_Click);
// //
// label2 // label2
// //
this.label2.Location = new System.Drawing.Point(6, 140); this.label2.Location = new System.Drawing.Point(6, 132);
this.label2.Name = "label2"; this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(213, 82); this.label2.Size = new System.Drawing.Size(213, 82);
this.label2.TabIndex = 23; this.label2.TabIndex = 23;
this.label2.Text = resources.GetString("label2.Text"); this.label2.Text = resources.GetString("label2.Text");
// //
// radioButton2 // rbMednafenMode
// //
this.radioButton2.AutoSize = true; this.rbMednafenMode.AutoSize = true;
this.radioButton2.Location = new System.Drawing.Point(6, 120); this.rbMednafenMode.Location = new System.Drawing.Point(6, 116);
this.radioButton2.Name = "radioButton2"; this.rbMednafenMode.Name = "rbMednafenMode";
this.radioButton2.Size = new System.Drawing.Size(145, 17); this.rbMednafenMode.Size = new System.Drawing.Size(145, 17);
this.radioButton2.TabIndex = 22; this.rbMednafenMode.TabIndex = 22;
this.radioButton2.TabStop = true; this.rbMednafenMode.TabStop = true;
this.radioButton2.Text = "Mednafen Mode (4:3 AR)"; this.rbMednafenMode.Text = "Mednafen Mode (4:3 AR)";
this.radioButton2.UseVisualStyleBackColor = true; this.rbMednafenMode.UseVisualStyleBackColor = true;
// //
// label8 // label8
// //
this.label8.Location = new System.Drawing.Point(6, 39); this.label8.Location = new System.Drawing.Point(6, 35);
this.label8.Name = "label8"; this.label8.Name = "label8";
this.label8.Size = new System.Drawing.Size(252, 78); this.label8.Size = new System.Drawing.Size(252, 78);
this.label8.TabIndex = 21; this.label8.TabIndex = 21;
@ -123,57 +129,28 @@
" • Content is pixel perfect\r\n • Aspect ratio is usually wrong\r\n • Game may seen " + " • Content is pixel perfect\r\n • Aspect ratio is usually wrong\r\n • Game may seen " +
"to have scale varying by mode\r\n\r\n\r\n"; "to have scale varying by mode\r\n\r\n\r\n";
// //
// radioButton1 // rbPixelPro
// //
this.radioButton1.AutoSize = true; this.rbPixelPro.AutoSize = true;
this.radioButton1.Location = new System.Drawing.Point(6, 19); this.rbPixelPro.Location = new System.Drawing.Point(6, 19);
this.radioButton1.Name = "radioButton1"; this.rbPixelPro.Name = "rbPixelPro";
this.radioButton1.Size = new System.Drawing.Size(96, 17); this.rbPixelPro.Size = new System.Drawing.Size(96, 17);
this.radioButton1.TabIndex = 0; this.rbPixelPro.TabIndex = 0;
this.radioButton1.TabStop = true; this.rbPixelPro.TabStop = true;
this.radioButton1.Text = "Pixel Pro Mode"; this.rbPixelPro.Text = "Pixel Pro Mode";
this.radioButton1.UseVisualStyleBackColor = true; this.rbPixelPro.UseVisualStyleBackColor = true;
//
// label3
//
this.label3.Location = new System.Drawing.Point(9, 291);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(283, 91);
this.label3.TabIndex = 24;
this.label3.Text = resources.GetString("label3.Text");
//
// checkBox1
//
this.checkBox1.AutoSize = true;
this.checkBox1.Location = new System.Drawing.Point(6, 100);
this.checkBox1.Name = "checkBox1";
this.checkBox1.Size = new System.Drawing.Size(109, 17);
this.checkBox1.TabIndex = 25;
this.checkBox1.Text = "Discard overscan";
this.checkBox1.UseVisualStyleBackColor = true;
// //
// groupBox2 // groupBox2
// //
this.groupBox2.Controls.Add(this.label6);
this.groupBox2.Controls.Add(this.label1); this.groupBox2.Controls.Add(this.label1);
this.groupBox2.Controls.Add(this.label5); this.groupBox2.Controls.Add(this.label5);
this.groupBox2.Controls.Add(this.label4); this.groupBox2.Location = new System.Drawing.Point(492, 7);
this.groupBox2.Controls.Add(this.checkBox1);
this.groupBox2.Location = new System.Drawing.Point(294, 12);
this.groupBox2.Name = "groupBox2"; this.groupBox2.Name = "groupBox2";
this.groupBox2.Size = new System.Drawing.Size(211, 265); this.groupBox2.Size = new System.Drawing.Size(211, 143);
this.groupBox2.TabIndex = 26; this.groupBox2.TabIndex = 26;
this.groupBox2.TabStop = false; this.groupBox2.TabStop = false;
this.groupBox2.Text = "Non-Functional Options"; this.groupBox2.Text = "Non-Functional Options";
// //
// label6
//
this.label6.Location = new System.Drawing.Point(7, 144);
this.label6.Name = "label6";
this.label6.Size = new System.Drawing.Size(197, 21);
this.label6.TabIndex = 29;
this.label6.Text = "Maybe fixes 1x window size problem";
//
// label1 // label1
// //
this.label1.Location = new System.Drawing.Point(6, 21); this.label1.Location = new System.Drawing.Point(6, 21);
@ -184,36 +161,68 @@
// //
// label5 // label5
// //
this.label5.Location = new System.Drawing.Point(6, 201); this.label5.Location = new System.Drawing.Point(8, 45);
this.label5.Name = "label5"; this.label5.Name = "label5";
this.label5.Size = new System.Drawing.Size(197, 21); this.label5.Size = new System.Drawing.Size(197, 21);
this.label5.TabIndex = 27; this.label5.TabIndex = 27;
this.label5.Text = "(Scanline range selection)"; this.label5.Text = "(Scanline range selection)";
// //
// label4
//
this.label4.Location = new System.Drawing.Point(6, 120);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(197, 21);
this.label4.TabIndex = 26;
this.label4.Text = "Decreases resolutions (e.g. 350 to 320)";
//
// label7 // label7
// //
this.label7.Location = new System.Drawing.Point(315, 303); this.label7.Location = new System.Drawing.Point(500, 169);
this.label7.Name = "label7"; this.label7.Name = "label7";
this.label7.Size = new System.Drawing.Size(197, 29); this.label7.Size = new System.Drawing.Size(197, 29);
this.label7.TabIndex = 30; this.label7.TabIndex = 30;
this.label7.Text = "Restart the core to take effect.\r\nSorry, its still in development"; this.label7.Text = "Restart the core to take effect.\r\nSorry, its still in development";
//
// rbDebugMode
//
this.rbDebugMode.AutoSize = true;
this.rbDebugMode.Location = new System.Drawing.Point(246, 19);
this.rbDebugMode.Name = "rbDebugMode";
this.rbDebugMode.Size = new System.Drawing.Size(134, 17);
this.rbDebugMode.TabIndex = 25;
this.rbDebugMode.TabStop = true;
this.rbDebugMode.Text = "Hardcore Debug Mode";
this.rbDebugMode.UseVisualStyleBackColor = true;
//
// label3
//
this.label3.Location = new System.Drawing.Point(246, 39);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(213, 50);
this.label3.TabIndex = 26;
this.label3.Text = "Displays all content unmodified\r\n • Window size will constantly change\r\n • Aspect" +
" ratio is usually wrong";
//
// rbTweakedMednafenMode
//
this.rbTweakedMednafenMode.AutoSize = true;
this.rbTweakedMednafenMode.Location = new System.Drawing.Point(246, 116);
this.rbTweakedMednafenMode.Name = "rbTweakedMednafenMode";
this.rbTweakedMednafenMode.Size = new System.Drawing.Size(193, 17);
this.rbTweakedMednafenMode.TabIndex = 27;
this.rbTweakedMednafenMode.TabStop = true;
this.rbTweakedMednafenMode.Text = "Tweaked Mednafen Mode (4:3 AR)";
this.rbTweakedMednafenMode.UseVisualStyleBackColor = true;
//
// label9
//
this.label9.Location = new System.Drawing.Point(255, 132);
this.label9.Name = "label9";
this.label9.Size = new System.Drawing.Size(213, 79);
this.label9.TabIndex = 28;
this.label9.Text = "Displays all content at as multiple of 400x300.\r\n • Correct aspect ratio\r\n • Gene" +
"rally enjoyable game presentation\r\n • Detail loss at 1x in fewer cases\r\n • Requi" +
"res certain display configuration:\r\n";
// //
// PSXOptions // PSXOptions
// //
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.ClientSize = new System.Drawing.Size(524, 382); this.ClientSize = new System.Drawing.Size(713, 275);
this.Controls.Add(this.label7); this.Controls.Add(this.label7);
this.Controls.Add(this.groupBox2); this.Controls.Add(this.groupBox2);
this.Controls.Add(this.label3);
this.Controls.Add(this.groupBox1); this.Controls.Add(this.groupBox1);
this.Controls.Add(this.btnCancel); this.Controls.Add(this.btnCancel);
this.Controls.Add(this.btnOk); this.Controls.Add(this.btnOk);
@ -225,7 +234,6 @@
this.groupBox1.ResumeLayout(false); this.groupBox1.ResumeLayout(false);
this.groupBox1.PerformLayout(); this.groupBox1.PerformLayout();
this.groupBox2.ResumeLayout(false); this.groupBox2.ResumeLayout(false);
this.groupBox2.PerformLayout();
this.ResumeLayout(false); this.ResumeLayout(false);
} }
@ -235,18 +243,18 @@
private System.Windows.Forms.Button btnCancel; private System.Windows.Forms.Button btnCancel;
private System.Windows.Forms.Button btnOk; private System.Windows.Forms.Button btnOk;
private System.Windows.Forms.GroupBox groupBox1; private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.RadioButton radioButton1; private System.Windows.Forms.RadioButton rbPixelPro;
private System.Windows.Forms.Button button1; private System.Windows.Forms.Button btnNiceDisplayConfig;
private System.Windows.Forms.Label label2; private System.Windows.Forms.Label label2;
private System.Windows.Forms.RadioButton radioButton2; private System.Windows.Forms.RadioButton rbMednafenMode;
private System.Windows.Forms.Label label8; private System.Windows.Forms.Label label8;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.CheckBox checkBox1;
private System.Windows.Forms.GroupBox groupBox2; private System.Windows.Forms.GroupBox groupBox2;
private System.Windows.Forms.Label label5; private System.Windows.Forms.Label label5;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.Label label6;
private System.Windows.Forms.Label label1; private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label7; private System.Windows.Forms.Label label7;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.RadioButton rbDebugMode;
private System.Windows.Forms.Label label9;
private System.Windows.Forms.RadioButton rbTweakedMednafenMode;
} }
} }

View File

@ -7,13 +7,63 @@ using System.Linq;
using System.Text; using System.Text;
using System.Windows.Forms; using System.Windows.Forms;
using BizHawk.Emulation.Cores.Sony.PSX;
using BizHawk.Client.Common;
namespace BizHawk.Client.EmuHawk namespace BizHawk.Client.EmuHawk
{ {
public partial class PSXOptions : Form public partial class PSXOptions : Form
{ {
public PSXOptions() public PSXOptions(Octoshock.Settings settings)
{ {
InitializeComponent(); InitializeComponent();
_settings = settings;
rbPixelPro.Checked = _settings.ResolutionMode == Octoshock.eResolutionMode.PixelPro;
rbDebugMode.Checked = _settings.ResolutionMode == Octoshock.eResolutionMode.Debug;
rbMednafenMode.Checked = _settings.ResolutionMode == Octoshock.eResolutionMode.Mednafen;
rbTweakedMednafenMode.Checked = _settings.ResolutionMode == Octoshock.eResolutionMode.TweakedMednafen;
} }
Octoshock.Settings _settings;
bool _dispSettingsSet = false;
private void btnNiceDisplayConfig_Click(object sender, EventArgs e)
{
_dispSettingsSet = true;
MessageBox.Show("Finetuned Display Options will take effect if you OK from PSX Options");
}
public static DialogResult DoSettingsDialog(IWin32Window owner)
{
var s = ((Octoshock)Global.Emulator).GetSettings();
var ss = ((Octoshock)Global.Emulator).GetSyncSettings();
var dlg = new PSXOptions(s);
var result = dlg.ShowDialog(owner);
return result;
}
private void btnOk_Click(object sender, EventArgs e)
{
if (_dispSettingsSet)
{
Global.Config.DispManagerAR = Config.EDispManagerAR.System;
Global.Config.DispFixAspectRatio = true;
Global.Config.DispFixScaleInteger = false;
Global.Config.DispFinalFilter = 1; //bilinear, I hope
}
if(rbPixelPro.Checked) _settings.ResolutionMode = Octoshock.eResolutionMode.PixelPro;
if(rbDebugMode.Checked) _settings.ResolutionMode = Octoshock.eResolutionMode.Debug;
if(rbMednafenMode.Checked)_settings.ResolutionMode = Octoshock.eResolutionMode.Mednafen;
if(rbTweakedMednafenMode.Checked)_settings.ResolutionMode = Octoshock.eResolutionMode.TweakedMednafen;
GlobalWin.MainForm.PutCoreSettings(_settings);
DialogResult = DialogResult.OK;
Close();
}
} }
} }

View File

@ -125,12 +125,4 @@
• Requires certain display configuration: • Requires certain display configuration:
</value> </value>
</data> </data>
<data name="label3.Text" xml:space="preserve">
<value>Background info:
Here are the possible (NTSC) resolutions:
280x240 350x240 400x240 560x240 700x240
280x480 350x480 400x480 560x480 700x480
This is including some overscan area.
E.g. a 350 wide resolution is for a 320 wide framebuffer</value>
</data>
</root> </root>

View File

@ -4,12 +4,14 @@
//TODO add sram dump option (bold it if dirty) to file menu //TODO add sram dump option (bold it if dirty) to file menu
using System; using System;
using System.ComponentModel;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.IO; using System.IO;
using System.Collections.Generic; using System.Collections.Generic;
using Newtonsoft.Json; using Newtonsoft.Json;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
using BizHawk.Common;
#pragma warning disable 649 //adelikat: Disable dumb warnings until this file is complete #pragma warning disable 649 //adelikat: Disable dumb warnings until this file is complete
@ -21,7 +23,7 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
isPorted: true, isPorted: true,
isReleased: false isReleased: false
)] )]
public unsafe class Octoshock : IEmulator, IVideoProvider, ISyncSoundProvider, IMemoryDomains, ISaveRam, IStatable, IDriveLight, IInputPollable public unsafe class Octoshock : IEmulator, IVideoProvider, ISyncSoundProvider, IMemoryDomains, ISaveRam, IStatable, IDriveLight, IInputPollable, ISettable<Octoshock.Settings, Octoshock.SyncSettings>
{ {
public string SystemId { get { return "PSX"; } } public string SystemId { get { return "PSX"; } }
@ -169,11 +171,14 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
//note: its annoying that we have to have a disc before constructing this. //note: its annoying that we have to have a disc before constructing this.
//might want to change that later. HOWEVER - we need to definitely have a region, at least //might want to change that later. HOWEVER - we need to definitely have a region, at least
public Octoshock(CoreComm comm, DiscSystem.Disc disc, byte[] exe) public Octoshock(CoreComm comm, DiscSystem.Disc disc, byte[] exe, object settings, object syncSettings)
{ {
ServiceProvider = new BasicServiceProvider(this); ServiceProvider = new BasicServiceProvider(this);
CoreComm = comm; CoreComm = comm;
_Settings = (Settings)settings ?? new Settings();
_SyncSettings = (SyncSettings)syncSettings ?? new SyncSettings();
DriveLightEnabled = true; DriveLightEnabled = true;
Attach(); Attach();
@ -232,7 +237,7 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
//set a default framebuffer //set a default framebuffer
BufferWidth = VirtualWidth; BufferWidth = VirtualWidth;
BufferHeight = VirtualHeight; BufferHeight = VirtualHeight;
frameBuffer = new int[BufferWidth*BufferHeight]; frameBuffer = new int[BufferWidth * BufferHeight];
if (disc != null) if (disc != null)
{ {
@ -288,7 +293,7 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
uint buttons = 0; uint buttons = 0;
//dualshock style //dualshock style
if(Controller["Select"]) buttons |= 1; if (Controller["Select"]) buttons |= 1;
if (Controller["L3"]) buttons |= 2; if (Controller["L3"]) buttons |= 2;
if (Controller["R3"]) buttons |= 4; if (Controller["R3"]) buttons |= 4;
if (Controller["Start"]) buttons |= 8; if (Controller["Start"]) buttons |= 8;
@ -323,20 +328,41 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
OctoshockDll.shock_Step(psx, OctoshockDll.eShockStep.Frame); OctoshockDll.shock_Step(psx, OctoshockDll.eShockStep.Frame);
OctoshockDll.ShockFramebufferInfo fb = new OctoshockDll.ShockFramebufferInfo(); //what happens to sound in this case?
fb.flags = OctoshockDll.eShockFramebufferFlags.Normalize;
OctoshockDll.shock_GetFramebuffer(psx, ref fb);
//Console.WriteLine(fb.height);
if (render == false) return; if (render == false) return;
OctoshockDll.ShockFramebufferInfo fb = new OctoshockDll.ShockFramebufferInfo();
if (_Settings.ResolutionMode == eResolutionMode.PixelPro)
fb.flags = OctoshockDll.eShockFramebufferFlags.Normalize;
OctoshockDll.shock_GetFramebuffer(psx, ref fb);
int w = fb.width; int w = fb.width;
int h = fb.height; int h = fb.height;
BufferWidth = w; BufferWidth = w;
BufferHeight = h; BufferHeight = h;
int len = w*h; switch (_Settings.ResolutionMode)
{
case eResolutionMode.Debug:
VirtualWidth = w;
VirtualHeight = h;
break;
case eResolutionMode.Mednafen:
VirtualWidth = 320;
VirtualHeight = 240;
break;
case eResolutionMode.PixelPro:
VirtualWidth = 800;
VirtualHeight = 480;
break;
case eResolutionMode.TweakedMednafen:
VirtualWidth = 400;
VirtualHeight = 300;
break;
}
int len = w * h;
if (frameBuffer.Length != len) if (frameBuffer.Length != len)
{ {
Console.WriteLine("PSX FB size: {0},{1}", fb.width, fb.height); Console.WriteLine("PSX FB size: {0},{1}", fb.width, fb.height);
@ -347,7 +373,6 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
{ {
fb.ptr = ptr; fb.ptr = ptr;
OctoshockDll.shock_GetFramebuffer(psx, ref fb); OctoshockDll.shock_GetFramebuffer(psx, ref fb);
//alpha channel is added in c++, right now. wish we didnt have to do it at all
} }
fixed (short* samples = sbuff) fixed (short* samples = sbuff)
@ -407,7 +432,7 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
#region ISoundProvider #region ISoundProvider
private short[] sbuff = new short[1454*2]; //this is the most ive ever seen.. dont know why private short[] sbuff = new short[1454 * 2]; //this is the most ive ever seen.. dont know why
private int sbuffcontains = 0; private int sbuffcontains = 0;
public ISoundProvider SoundProvider { get { throw new InvalidOperationException(); } } public ISoundProvider SoundProvider { get { throw new InvalidOperationException(); } }
@ -601,5 +626,70 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
} }
#endregion #endregion
#region Settings
Settings _Settings = new Settings();
SyncSettings _SyncSettings;
public enum eResolutionMode
{
PixelPro, Debug,
Mednafen, TweakedMednafen
}
public class SyncSettings
{
public SyncSettings Clone()
{
return (SyncSettings)MemberwiseClone();
}
}
public class Settings
{
[DisplayName("Resolution Mode")]
[Description("Stuf")]
[DefaultValue(eResolutionMode.PixelPro)]
public eResolutionMode ResolutionMode { get; set; }
public Settings()
{
SettingsUtil.SetDefaultValues(this);
}
public Settings Clone()
{
return (Settings)MemberwiseClone();
}
}
public Settings GetSettings()
{
return _Settings.Clone();
}
public SyncSettings GetSyncSettings()
{
return _SyncSettings.Clone();
}
public bool PutSettings(Settings o)
{
_Settings = o;
//TODO
//var native = _Settings.GetNativeSettings();
//BizSwan.bizswan_putsettings(Core, ref native);
return false;
}
public bool PutSyncSettings(SyncSettings o)
{
_SyncSettings = o;
return false;
}
#endregion
} }
} }

View File

@ -5,197 +5,200 @@ using System.Runtime.InteropServices;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
public unsafe static class OctoshockDll namespace BizHawk.Emulation.Cores.Sony.PSX
{ {
const CallingConvention cc = CallingConvention.Cdecl; public unsafe static class OctoshockDll
const string dd = "octoshock.dll";
public enum eRegion : int
{ {
JP = 0, const CallingConvention cc = CallingConvention.Cdecl;
NA = 1, const string dd = "octoshock.dll";
EU = 2,
NONE = 3 //TODO - whats the difference between unset, and region unknown? public enum eRegion : int
{
JP = 0,
NA = 1,
EU = 2,
NONE = 3 //TODO - whats the difference between unset, and region unknown?
}
public enum eShockStep
{
Frame
};
public enum eShockFramebufferFlags
{
None = 0,
Normalize = 1
}
public enum eMemType
{
MainRAM = 0, //2048K
BiosROM = 1, //512K
PIOMem = 2, //64K
GPURAM = 3, //512K
SPURAM = 4 //512K
};
public enum eShockStateTransaction : int
{
BinarySize = 0,
BinaryLoad = 1,
BinarySave = 2,
TextLoad = 3,
TextSave = 4
}
public enum eShockMemcardTransaction
{
Connect = 0, //connects it to the addressed port (not supported yet)
Disconnect = 1, //disconnects it from the addressed port (not supported yet)
Write = 2, //writes from the frontend to the memcard
Read = 3, //reads from the memcard to the frontend. Also clears the dirty flag
CheckDirty = 4, //checks whether the memcard is dirty
};
public enum ePeripheralType
{
None = 0, //can be used to signify disconnection
Pad = 1, //SCPH-1080
DualShock = 2, //SCPH-1200
DualAnalog = 3, //SCPH-1180
Multitap = 10,
};
public const int SHOCK_OK = 0;
public const int SHOCK_FALSE = 0;
public const int SHOCK_TRUE = 1;
public const int SHOCK_ERROR = -1;
public const int SHOCK_NOCANDO = -2;
public const int SHOCK_INVALID_ADDRESS = -3;
[StructLayout(LayoutKind.Sequential)]
public struct ShockDiscInfo
{
public eRegion region;
public unsafe fixed sbyte id[5]; //SCEI, SCEA, SCEE, etc. with null terminator
};
[StructLayout(LayoutKind.Sequential)]
public struct ShockTOCTrack
{
public byte adr;
public byte control;
public uint lba;
};
[StructLayout(LayoutKind.Sequential)]
public struct ShockTOC
{
public byte first_track;
public byte last_track;
public byte disc_type;
};
[StructLayout(LayoutKind.Sequential)]
public struct ShockFramebufferInfo
{
public int width, height;
[MarshalAs(UnmanagedType.I4)]
public eShockFramebufferFlags flags;
public void* ptr;
};
[StructLayout(LayoutKind.Sequential)]
public struct ShockMemcardTransaction
{
[MarshalAs(UnmanagedType.I4)]
public eShockMemcardTransaction transaction;
public void* buffer128k;
};
[StructLayout(LayoutKind.Sequential)]
public struct ShockStateTransaction
{
public eShockStateTransaction transaction;
public void* buffer;
public int bufferLength;
public TextStateFPtrs ff;
};
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int ShockDisc_ReadTOC(IntPtr opaque, ShockTOC* read_target, ShockTOCTrack* tracks101);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int ShockDisc_ReadLBA(IntPtr opaque, int lba, void* dst);
[DllImport(dd)]
public static extern int shock_CreateDisc(out IntPtr outDisc, IntPtr Opaque, int lbaCount, ShockDisc_ReadTOC ReadTOC, ShockDisc_ReadLBA ReadLBA2448, bool suppliesDeinterleavedSubcode);
[DllImport(dd)]
public static extern int shock_DestroyDisc(IntPtr disc);
[DllImport(dd)]
public static extern int shock_AnalyzeDisc(IntPtr disc, out ShockDiscInfo info);
[DllImport(dd)]
public static extern int shock_Create(out IntPtr psx, eRegion region, void* firmware512k);
[DllImport(dd)]
public static extern int shock_Destroy(IntPtr psx);
[DllImport(dd)]
public static extern int shock_Peripheral_Connect(
IntPtr psx,
int address,
[MarshalAs(UnmanagedType.I4)] ePeripheralType type
);
[DllImport(dd)]
public static extern int shock_Peripheral_SetPadInput(IntPtr psx, int address, uint buttons, byte left_x, byte left_y, byte right_x, byte right_y);
[DllImport(dd)]
public static extern int shock_Peripheral_MemcardTransact(IntPtr psx, int address, ref ShockMemcardTransaction transaction);
[DllImport(dd)]
public static extern int shock_MountEXE(IntPtr psx, void* exebuf, int size);
[DllImport(dd)]
public static extern int shock_PowerOn(IntPtr psx);
[DllImport(dd)]
public static extern int shock_PowerOff(IntPtr psx);
[DllImport(dd)]
public static extern int shock_OpenTray(IntPtr psx);
[DllImport(dd)]
public static extern int shock_SetDisc(IntPtr psx, IntPtr disc);
[DllImport(dd)]
public static extern int shock_CloseTray(IntPtr psx);
[DllImport(dd)]
public static extern int shock_Step(IntPtr psx, eShockStep step);
[DllImport(dd)]
public static extern int shock_GetFramebuffer(IntPtr psx, ref ShockFramebufferInfo fb);
[DllImport(dd)]
public static extern int shock_GetSamples(IntPtr psx, void* buffer);
[DllImport(dd)]
public static extern int shock_GetMemData(
IntPtr psx,
out IntPtr ptr,
out int size,
[MarshalAs(UnmanagedType.I4)] eMemType memType
);
[DllImport(dd, CallingConvention = cc)]
public static extern int shock_StateTransaction(IntPtr psx, ref ShockStateTransaction transaction);
} }
public enum eShockStep
{
Frame
};
public enum eShockFramebufferFlags
{
None = 0,
Normalize = 1
}
public enum eMemType
{
MainRAM = 0, //2048K
BiosROM = 1, //512K
PIOMem = 2, //64K
GPURAM = 3, //512K
SPURAM = 4 //512K
};
public enum eShockStateTransaction : int
{
BinarySize=0,
BinaryLoad=1,
BinarySave=2,
TextLoad=3,
TextSave=4
}
public enum eShockMemcardTransaction
{
Connect = 0, //connects it to the addressed port (not supported yet)
Disconnect = 1, //disconnects it from the addressed port (not supported yet)
Write = 2, //writes from the frontend to the memcard
Read = 3, //reads from the memcard to the frontend. Also clears the dirty flag
CheckDirty = 4, //checks whether the memcard is dirty
};
public enum ePeripheralType
{
None = 0, //can be used to signify disconnection
Pad = 1, //SCPH-1080
DualShock = 2, //SCPH-1200
DualAnalog = 3, //SCPH-1180
Multitap = 10,
};
public const int SHOCK_OK = 0;
public const int SHOCK_FALSE = 0;
public const int SHOCK_TRUE = 1;
public const int SHOCK_ERROR = -1;
public const int SHOCK_NOCANDO = -2;
public const int SHOCK_INVALID_ADDRESS = -3;
[StructLayout(LayoutKind.Sequential)]
public struct ShockDiscInfo
{
public eRegion region;
public unsafe fixed sbyte id[5]; //SCEI, SCEA, SCEE, etc. with null terminator
};
[StructLayout(LayoutKind.Sequential)]
public struct ShockTOCTrack
{
public byte adr;
public byte control;
public uint lba;
};
[StructLayout(LayoutKind.Sequential)]
public struct ShockTOC
{
public byte first_track;
public byte last_track;
public byte disc_type;
};
[StructLayout(LayoutKind.Sequential)]
public struct ShockFramebufferInfo
{
public int width, height;
[MarshalAs(UnmanagedType.I4)]
public eShockFramebufferFlags flags;
public void* ptr;
};
[StructLayout(LayoutKind.Sequential)]
public struct ShockMemcardTransaction
{
[MarshalAs(UnmanagedType.I4)]
public eShockMemcardTransaction transaction;
public void* buffer128k;
};
[StructLayout(LayoutKind.Sequential)]
public struct ShockStateTransaction
{
public eShockStateTransaction transaction;
public void* buffer;
public int bufferLength;
public TextStateFPtrs ff;
};
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int ShockDisc_ReadTOC(IntPtr opaque, ShockTOC* read_target, ShockTOCTrack* tracks101);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int ShockDisc_ReadLBA(IntPtr opaque, int lba, void* dst);
[DllImport(dd)]
public static extern int shock_CreateDisc(out IntPtr outDisc, IntPtr Opaque, int lbaCount, ShockDisc_ReadTOC ReadTOC, ShockDisc_ReadLBA ReadLBA2448, bool suppliesDeinterleavedSubcode);
[DllImport(dd)]
public static extern int shock_DestroyDisc(IntPtr disc);
[DllImport(dd)]
public static extern int shock_AnalyzeDisc(IntPtr disc, out ShockDiscInfo info);
[DllImport(dd)]
public static extern int shock_Create(out IntPtr psx, eRegion region, void* firmware512k);
[DllImport(dd)]
public static extern int shock_Destroy(IntPtr psx);
[DllImport(dd)]
public static extern int shock_Peripheral_Connect(
IntPtr psx,
int address,
[MarshalAs(UnmanagedType.I4)] ePeripheralType type
);
[DllImport(dd)]
public static extern int shock_Peripheral_SetPadInput(IntPtr psx, int address, uint buttons, byte left_x, byte left_y, byte right_x, byte right_y);
[DllImport(dd)]
public static extern int shock_Peripheral_MemcardTransact(IntPtr psx, int address, ref ShockMemcardTransaction transaction);
[DllImport(dd)]
public static extern int shock_MountEXE(IntPtr psx, void* exebuf, int size);
[DllImport(dd)]
public static extern int shock_PowerOn(IntPtr psx);
[DllImport(dd)]
public static extern int shock_PowerOff(IntPtr psx);
[DllImport(dd)]
public static extern int shock_OpenTray(IntPtr psx);
[DllImport(dd)]
public static extern int shock_SetDisc(IntPtr psx, IntPtr disc);
[DllImport(dd)]
public static extern int shock_CloseTray(IntPtr psx);
[DllImport(dd)]
public static extern int shock_Step(IntPtr psx, eShockStep step);
[DllImport(dd)]
public static extern int shock_GetFramebuffer(IntPtr psx, ref ShockFramebufferInfo fb);
[DllImport(dd)]
public static extern int shock_GetSamples(IntPtr psx, void* buffer);
[DllImport(dd)]
public static extern int shock_GetMemData(
IntPtr psx,
out IntPtr ptr,
out int size,
[MarshalAs(UnmanagedType.I4)] eMemType memType
);
[DllImport(dd, CallingConvention = cc)]
public static extern int shock_StateTransaction(IntPtr psx, ref ShockStateTransaction transaction);
} }

Binary file not shown.

View File

@ -1513,6 +1513,9 @@ EW_EXPORT s32 shock_GetSamples(void* psx, void* buffer)
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 - let the frontend do this, anyway. need a new filter for it. this was in the plans from the beginning, i just havent done it yet
//if user requires normalization, do it now //if user requires normalization, do it now
if(fb->flags & eShockFramebufferFlags_Normalize) if(fb->flags & eShockFramebufferFlags_Normalize)
if(!s_FramebufferNormalized) if(!s_FramebufferNormalized)
@ -1542,11 +1545,9 @@ EW_EXPORT s32 shock_GetFramebuffer(void* psx, ShockFramebufferInfo* fb)
int tocopy = width*4; int tocopy = width*4;
for(int y=0;y<height;y++) for(int y=0;y<height;y++)
{ {
for(int x=0;x<width;x++) memcpy(dst,src,tocopy);
{ src += s_FramebufferCurrentWidth;
*dst++ = *src++ | 0xFF000000; dst += width;
}
src += s_FramebufferCurrentWidth - width;
} }
return SHOCK_OK; return SHOCK_OK;