BSNES Region Override (#3169)

* region override for bsnes

* hook up SnesInitData right. still needs region override sync setting

* settings stuff, also need to make sure sameboy is using the right region for sgb

* and build

* clearer struct definition; move struct to header file

Co-authored-by: Morilli <35152647+Morilli@users.noreply.github.com>
This commit is contained in:
CasualPokePlayer 2022-03-04 05:21:53 -08:00 committed by GitHub
parent 8e233a0e3b
commit 114124c82e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 787 additions and 712 deletions

Binary file not shown.

View File

@ -1,12 +1,12 @@
namespace BizHawk.Client.EmuHawk
{
partial class BSNESOptions
{
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
@ -18,339 +18,362 @@
components.Dispose();
}
base.Dispose(disposing);
}
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.btnOk = new System.Windows.Forms.Button();
this.btnCancel = new System.Windows.Forms.Button();
this.cbDoubleSize = new System.Windows.Forms.CheckBox();
this.lblDoubleSize = new BizHawk.WinForms.Controls.LocLabelEx();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.lblPriority1 = new BizHawk.WinForms.Controls.LocLabelEx();
this.lblPriority0 = new BizHawk.WinForms.Controls.LocLabelEx();
this.Bg4_0Checkbox = new System.Windows.Forms.CheckBox();
this.Bg3_0Checkbox = new System.Windows.Forms.CheckBox();
this.Bg2_0Checkbox = new System.Windows.Forms.CheckBox();
this.Bg1_0Checkbox = new System.Windows.Forms.CheckBox();
this.Bg4_1Checkbox = new System.Windows.Forms.CheckBox();
this.Bg3_1Checkbox = new System.Windows.Forms.CheckBox();
this.Bg2_1Checkbox = new System.Windows.Forms.CheckBox();
this.Bg1_1Checkbox = new System.Windows.Forms.CheckBox();
this.Obj4Checkbox = new System.Windows.Forms.CheckBox();
this.Obj3Checkbox = new System.Windows.Forms.CheckBox();
this.Obj2Checkbox = new System.Windows.Forms.CheckBox();
this.Obj1Checkbox = new System.Windows.Forms.CheckBox();
this.EntropyBox = new System.Windows.Forms.ComboBox();
this.lblEntropy = new BizHawk.WinForms.Controls.LocLabelEx();
this.cbGameHotfixes = new System.Windows.Forms.CheckBox();
this.cbFastPPU = new System.Windows.Forms.CheckBox();
this.cbCropSGBFrame = new System.Windows.Forms.CheckBox();
this.cbUseSGB2 = new System.Windows.Forms.CheckBox();
this.groupBox1.SuspendLayout();
this.SuspendLayout();
//
// btnOk
//
this.btnOk.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnOk.Location = new System.Drawing.Point(136, 303);
this.btnOk.Name = "btnOk";
this.btnOk.Size = new System.Drawing.Size(75, 23);
this.btnOk.TabIndex = 0;
this.btnOk.Text = "OK";
this.btnOk.UseVisualStyleBackColor = true;
this.btnOk.Click += new System.EventHandler(this.BtnOk_Click);
//
// btnCancel
//
this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.btnCancel.Location = new System.Drawing.Point(217, 303);
this.btnCancel.Name = "btnCancel";
this.btnCancel.Size = new System.Drawing.Size(75, 23);
this.btnCancel.TabIndex = 1;
this.btnCancel.Text = "Cancel";
this.btnCancel.UseVisualStyleBackColor = true;
this.btnCancel.Click += new System.EventHandler(this.BtnCancel_Click);
//
// cbDoubleSize
//
this.cbDoubleSize.AutoSize = true;
this.cbDoubleSize.Location = new System.Drawing.Point(18, 16);
this.cbDoubleSize.Name = "cbDoubleSize";
this.cbDoubleSize.Size = new System.Drawing.Size(178, 17);
this.cbDoubleSize.TabIndex = 6;
this.cbDoubleSize.Text = "Always Double-Size Framebuffer";
this.cbDoubleSize.UseVisualStyleBackColor = true;
//
// lblDoubleSize
//
this.lblDoubleSize.Location = new System.Drawing.Point(33, 34);
this.lblDoubleSize.MaximumSize = new System.Drawing.Size(260, 0);
this.lblDoubleSize.Name = "lblDoubleSize";
this.lblDoubleSize.Text = "Some games are changing the resolution constantly (e.g. SD3) so this option can f" +
"orce the SNES output to stay double-size always.";
//
// groupBox1
//
this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.groupBox1.Controls.Add(this.lblPriority1);
this.groupBox1.Controls.Add(this.lblPriority0);
this.groupBox1.Controls.Add(this.Bg4_0Checkbox);
this.groupBox1.Controls.Add(this.Bg3_0Checkbox);
this.groupBox1.Controls.Add(this.Bg2_0Checkbox);
this.groupBox1.Controls.Add(this.Bg1_0Checkbox);
this.groupBox1.Controls.Add(this.Bg4_1Checkbox);
this.groupBox1.Controls.Add(this.Bg3_1Checkbox);
this.groupBox1.Controls.Add(this.Bg2_1Checkbox);
this.groupBox1.Controls.Add(this.Bg1_1Checkbox);
this.groupBox1.Controls.Add(this.Obj4Checkbox);
this.groupBox1.Controls.Add(this.Obj3Checkbox);
this.groupBox1.Controls.Add(this.Obj2Checkbox);
this.groupBox1.Controls.Add(this.Obj1Checkbox);
this.groupBox1.Location = new System.Drawing.Point(18, 165);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(274, 132);
this.groupBox1.TabIndex = 11;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "Display";
//
// lblPriority1
//
this.lblPriority1.Location = new System.Drawing.Point(220, 14);
this.lblPriority1.MaximumSize = new System.Drawing.Size(100, 0);
this.lblPriority1.Name = "lblPriority1";
this.lblPriority1.Text = "Priority 1";
//
// lblPriority0
//
this.lblPriority0.Location = new System.Drawing.Point(162, 14);
this.lblPriority0.MaximumSize = new System.Drawing.Size(100, 0);
this.lblPriority0.Name = "lblPriority0";
this.lblPriority0.Text = "Priority 0";
this.lblPriority0.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// Bg4_0Checkbox
//
this.Bg4_0Checkbox.AutoSize = true;
this.Bg4_0Checkbox.CheckAlign = System.Drawing.ContentAlignment.MiddleRight;
this.Bg4_0Checkbox.Location = new System.Drawing.Point(128, 99);
this.Bg4_0Checkbox.Name = "Bg4_0Checkbox";
this.Bg4_0Checkbox.Size = new System.Drawing.Size(62, 17);
this.Bg4_0Checkbox.TabIndex = 11;
this.Bg4_0Checkbox.Text = "BG 4 ";
this.Bg4_0Checkbox.UseVisualStyleBackColor = true;
//
// Bg3_0Checkbox
//
this.Bg3_0Checkbox.AutoSize = true;
this.Bg3_0Checkbox.CheckAlign = System.Drawing.ContentAlignment.MiddleRight;
this.Bg3_0Checkbox.Location = new System.Drawing.Point(128, 76);
this.Bg3_0Checkbox.Name = "Bg3_0Checkbox";
this.Bg3_0Checkbox.Size = new System.Drawing.Size(62, 17);
this.Bg3_0Checkbox.TabIndex = 10;
this.Bg3_0Checkbox.Text = "BG 3 ";
this.Bg3_0Checkbox.UseVisualStyleBackColor = true;
//
// Bg2_0Checkbox
//
this.Bg2_0Checkbox.AutoSize = true;
this.Bg2_0Checkbox.CheckAlign = System.Drawing.ContentAlignment.MiddleRight;
this.Bg2_0Checkbox.Location = new System.Drawing.Point(128, 53);
this.Bg2_0Checkbox.Name = "Bg2_0Checkbox";
this.Bg2_0Checkbox.Size = new System.Drawing.Size(62, 17);
this.Bg2_0Checkbox.TabIndex = 9;
this.Bg2_0Checkbox.Text = "BG 2 ";
this.Bg2_0Checkbox.UseVisualStyleBackColor = true;
//
// Bg1_0Checkbox
//
this.Bg1_0Checkbox.AutoSize = true;
this.Bg1_0Checkbox.CheckAlign = System.Drawing.ContentAlignment.MiddleRight;
this.Bg1_0Checkbox.Location = new System.Drawing.Point(128, 30);
this.Bg1_0Checkbox.Name = "Bg1_0Checkbox";
this.Bg1_0Checkbox.Size = new System.Drawing.Size(62, 17);
this.Bg1_0Checkbox.TabIndex = 8;
this.Bg1_0Checkbox.Text = "BG 1 ";
this.Bg1_0Checkbox.UseVisualStyleBackColor = true;
//
// Bg4_1Checkbox
//
this.Bg4_1Checkbox.AutoSize = true;
this.Bg4_1Checkbox.Location = new System.Drawing.Point(234, 100);
this.Bg4_1Checkbox.Name = "Bg4_1Checkbox";
this.Bg4_1Checkbox.Size = new System.Drawing.Size(15, 14);
this.Bg4_1Checkbox.TabIndex = 7;
this.Bg4_1Checkbox.UseVisualStyleBackColor = true;
//
// Bg3_1Checkbox
//
this.Bg3_1Checkbox.AutoSize = true;
this.Bg3_1Checkbox.Location = new System.Drawing.Point(234, 77);
this.Bg3_1Checkbox.Name = "Bg3_1Checkbox";
this.Bg3_1Checkbox.Size = new System.Drawing.Size(15, 14);
this.Bg3_1Checkbox.TabIndex = 6;
this.Bg3_1Checkbox.UseVisualStyleBackColor = true;
//
// Bg2_1Checkbox
//
this.Bg2_1Checkbox.AutoSize = true;
this.Bg2_1Checkbox.Location = new System.Drawing.Point(234, 54);
this.Bg2_1Checkbox.Name = "Bg2_1Checkbox";
this.Bg2_1Checkbox.Size = new System.Drawing.Size(15, 14);
this.Bg2_1Checkbox.TabIndex = 5;
this.Bg2_1Checkbox.UseVisualStyleBackColor = true;
//
// Bg1_1Checkbox
//
this.Bg1_1Checkbox.AutoSize = true;
this.Bg1_1Checkbox.Location = new System.Drawing.Point(234, 31);
this.Bg1_1Checkbox.Name = "Bg1_1Checkbox";
this.Bg1_1Checkbox.Size = new System.Drawing.Size(15, 14);
this.Bg1_1Checkbox.TabIndex = 4;
this.Bg1_1Checkbox.UseVisualStyleBackColor = true;
//
// Obj4Checkbox
//
this.Obj4Checkbox.AutoSize = true;
this.Obj4Checkbox.Location = new System.Drawing.Point(21, 99);
this.Obj4Checkbox.Name = "Obj4Checkbox";
this.Obj4Checkbox.Size = new System.Drawing.Size(55, 17);
this.Obj4Checkbox.TabIndex = 3;
this.Obj4Checkbox.Text = "OBJ 4";
this.Obj4Checkbox.UseVisualStyleBackColor = true;
//
// Obj3Checkbox
//
this.Obj3Checkbox.AutoSize = true;
this.Obj3Checkbox.Location = new System.Drawing.Point(21, 76);
this.Obj3Checkbox.Name = "Obj3Checkbox";
this.Obj3Checkbox.Size = new System.Drawing.Size(55, 17);
this.Obj3Checkbox.TabIndex = 2;
this.Obj3Checkbox.Text = "OBJ 3";
this.Obj3Checkbox.UseVisualStyleBackColor = true;
//
// Obj2Checkbox
//
this.Obj2Checkbox.AutoSize = true;
this.Obj2Checkbox.Location = new System.Drawing.Point(21, 53);
this.Obj2Checkbox.Name = "Obj2Checkbox";
this.Obj2Checkbox.Size = new System.Drawing.Size(55, 17);
this.Obj2Checkbox.TabIndex = 1;
this.Obj2Checkbox.Text = "OBJ 2";
this.Obj2Checkbox.UseVisualStyleBackColor = true;
//
// Obj1Checkbox
//
this.Obj1Checkbox.AutoSize = true;
this.Obj1Checkbox.Location = new System.Drawing.Point(21, 30);
this.Obj1Checkbox.Name = "Obj1Checkbox";
this.Obj1Checkbox.Size = new System.Drawing.Size(55, 17);
this.Obj1Checkbox.TabIndex = 0;
this.Obj1Checkbox.Text = "OBJ 1";
this.Obj1Checkbox.UseVisualStyleBackColor = true;
//
// EntropyBox
//
this.EntropyBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.EntropyBox.FormattingEnabled = true;
this.EntropyBox.Items.AddRange(new object[] {
"None",
"Low",
"High"});
this.EntropyBox.Location = new System.Drawing.Point(164, 138);
this.EntropyBox.Name = "EntropyBox";
this.EntropyBox.Size = new System.Drawing.Size(128, 21);
this.EntropyBox.TabIndex = 14;
//
// lblEntropy
//
this.lblEntropy.Location = new System.Drawing.Point(249, 117);
this.lblEntropy.Name = "lblEntropy";
this.lblEntropy.Text = "Entropy";
//
// cbGameHotfixes
//
this.cbGameHotfixes.AutoSize = true;
this.cbGameHotfixes.Location = new System.Drawing.Point(18, 111);
this.cbGameHotfixes.Name = "cbGameHotfixes";
this.cbGameHotfixes.Size = new System.Drawing.Size(93, 17);
this.cbGameHotfixes.TabIndex = 22;
this.cbGameHotfixes.Text = "Game hotfixes";
this.cbGameHotfixes.UseVisualStyleBackColor = true;
//
// cbFastPPU
//
this.cbFastPPU.AutoSize = true;
this.cbFastPPU.Location = new System.Drawing.Point(18, 138);
this.cbFastPPU.Name = "cbFastPPU";
this.cbFastPPU.Size = new System.Drawing.Size(90, 17);
this.cbFastPPU.TabIndex = 23;
this.cbFastPPU.Text = "Use fast PPU";
this.cbFastPPU.UseVisualStyleBackColor = true;
this.cbFastPPU.CheckedChanged += new System.EventHandler(this.FastPPU_CheckedChanged);
//
// cbCropSGBFrame
//
this.cbCropSGBFrame.AutoSize = true;
this.cbCropSGBFrame.Location = new System.Drawing.Point(18, 84);
this.cbCropSGBFrame.Name = "cbCropSGBFrame";
this.cbCropSGBFrame.Size = new System.Drawing.Size(105, 17);
this.cbCropSGBFrame.TabIndex = 27;
this.cbCropSGBFrame.Text = "Crop SGB Frame";
this.cbCropSGBFrame.UseVisualStyleBackColor = true;
//
// cbUseSGB2
//
this.cbUseSGB2.AutoSize = true;
this.cbUseSGB2.Location = new System.Drawing.Point(129, 84);
this.cbUseSGB2.Name = "cbUseSGB2";
this.cbUseSGB2.Size = new System.Drawing.Size(76, 17);
this.cbUseSGB2.TabIndex = 30;
this.cbUseSGB2.Text = "Use SGB2";
this.cbUseSGB2.UseVisualStyleBackColor = true;
//
// BSNESOptions
//
this.AcceptButton = this.btnOk;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this.btnCancel;
this.ClientSize = new System.Drawing.Size(304, 338);
this.Controls.Add(this.cbUseSGB2);
this.Controls.Add(this.cbCropSGBFrame);
this.Controls.Add(this.cbFastPPU);
this.Controls.Add(this.cbGameHotfixes);
this.Controls.Add(this.lblEntropy);
this.Controls.Add(this.EntropyBox);
this.Controls.Add(this.groupBox1);
this.Controls.Add(this.lblDoubleSize);
this.Controls.Add(this.cbDoubleSize);
this.Controls.Add(this.btnCancel);
this.Controls.Add(this.btnOk);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "BSNESOptions";
this.ShowIcon = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "BSNES Options";
this.groupBox1.ResumeLayout(false);
this.groupBox1.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
{
this.btnOk = new System.Windows.Forms.Button();
this.btnCancel = new System.Windows.Forms.Button();
this.cbDoubleSize = new System.Windows.Forms.CheckBox();
this.lblDoubleSize = new BizHawk.WinForms.Controls.LocLabelEx();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.lblPriority1 = new BizHawk.WinForms.Controls.LocLabelEx();
this.lblPriority0 = new BizHawk.WinForms.Controls.LocLabelEx();
this.Bg4_0Checkbox = new System.Windows.Forms.CheckBox();
this.Bg3_0Checkbox = new System.Windows.Forms.CheckBox();
this.Bg2_0Checkbox = new System.Windows.Forms.CheckBox();
this.Bg1_0Checkbox = new System.Windows.Forms.CheckBox();
this.Bg4_1Checkbox = new System.Windows.Forms.CheckBox();
this.Bg3_1Checkbox = new System.Windows.Forms.CheckBox();
this.Bg2_1Checkbox = new System.Windows.Forms.CheckBox();
this.Bg1_1Checkbox = new System.Windows.Forms.CheckBox();
this.Obj4Checkbox = new System.Windows.Forms.CheckBox();
this.Obj3Checkbox = new System.Windows.Forms.CheckBox();
this.Obj2Checkbox = new System.Windows.Forms.CheckBox();
this.Obj1Checkbox = new System.Windows.Forms.CheckBox();
this.EntropyBox = new System.Windows.Forms.ComboBox();
this.lblEntropy = new BizHawk.WinForms.Controls.LocLabelEx();
this.RegionBox = new System.Windows.Forms.ComboBox();
this.lblRegion = new BizHawk.WinForms.Controls.LocLabelEx();
this.cbGameHotfixes = new System.Windows.Forms.CheckBox();
this.cbFastPPU = new System.Windows.Forms.CheckBox();
this.cbCropSGBFrame = new System.Windows.Forms.CheckBox();
this.cbUseSGB2 = new System.Windows.Forms.CheckBox();
this.groupBox1.SuspendLayout();
this.SuspendLayout();
//
// btnOk
//
this.btnOk.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnOk.Location = new System.Drawing.Point(136, 321);
this.btnOk.Name = "btnOk";
this.btnOk.Size = new System.Drawing.Size(75, 23);
this.btnOk.TabIndex = 0;
this.btnOk.Text = "OK";
this.btnOk.UseVisualStyleBackColor = true;
this.btnOk.Click += new System.EventHandler(this.BtnOk_Click);
//
// btnCancel
//
this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.btnCancel.Location = new System.Drawing.Point(217, 321);
this.btnCancel.Name = "btnCancel";
this.btnCancel.Size = new System.Drawing.Size(75, 23);
this.btnCancel.TabIndex = 1;
this.btnCancel.Text = "Cancel";
this.btnCancel.UseVisualStyleBackColor = true;
this.btnCancel.Click += new System.EventHandler(this.BtnCancel_Click);
//
// cbDoubleSize
//
this.cbDoubleSize.AutoSize = true;
this.cbDoubleSize.Location = new System.Drawing.Point(18, 16);
this.cbDoubleSize.Name = "cbDoubleSize";
this.cbDoubleSize.Size = new System.Drawing.Size(178, 17);
this.cbDoubleSize.TabIndex = 6;
this.cbDoubleSize.Text = "Always Double-Size Framebuffer";
this.cbDoubleSize.UseVisualStyleBackColor = true;
//
// lblDoubleSize
//
this.lblDoubleSize.Location = new System.Drawing.Point(33, 34);
this.lblDoubleSize.MaximumSize = new System.Drawing.Size(260, 0);
this.lblDoubleSize.Name = "lblDoubleSize";
this.lblDoubleSize.Text = "Some games are changing the resolution constantly (e.g. SD3) so this option can f" +
"orce the SNES output to stay double-size always.";
//
// groupBox1
//
this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.groupBox1.Controls.Add(this.lblPriority1);
this.groupBox1.Controls.Add(this.lblPriority0);
this.groupBox1.Controls.Add(this.Bg4_0Checkbox);
this.groupBox1.Controls.Add(this.Bg3_0Checkbox);
this.groupBox1.Controls.Add(this.Bg2_0Checkbox);
this.groupBox1.Controls.Add(this.Bg1_0Checkbox);
this.groupBox1.Controls.Add(this.Bg4_1Checkbox);
this.groupBox1.Controls.Add(this.Bg3_1Checkbox);
this.groupBox1.Controls.Add(this.Bg2_1Checkbox);
this.groupBox1.Controls.Add(this.Bg1_1Checkbox);
this.groupBox1.Controls.Add(this.Obj4Checkbox);
this.groupBox1.Controls.Add(this.Obj3Checkbox);
this.groupBox1.Controls.Add(this.Obj2Checkbox);
this.groupBox1.Controls.Add(this.Obj1Checkbox);
this.groupBox1.Location = new System.Drawing.Point(18, 183);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(274, 132);
this.groupBox1.TabIndex = 11;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "Display";
//
// lblPriority1
//
this.lblPriority1.Location = new System.Drawing.Point(220, 14);
this.lblPriority1.MaximumSize = new System.Drawing.Size(100, 0);
this.lblPriority1.Name = "lblPriority1";
this.lblPriority1.Text = "Priority 1";
//
// lblPriority0
//
this.lblPriority0.Location = new System.Drawing.Point(162, 14);
this.lblPriority0.MaximumSize = new System.Drawing.Size(100, 0);
this.lblPriority0.Name = "lblPriority0";
this.lblPriority0.Text = "Priority 0";
this.lblPriority0.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// Bg4_0Checkbox
//
this.Bg4_0Checkbox.AutoSize = true;
this.Bg4_0Checkbox.CheckAlign = System.Drawing.ContentAlignment.MiddleRight;
this.Bg4_0Checkbox.Location = new System.Drawing.Point(128, 99);
this.Bg4_0Checkbox.Name = "Bg4_0Checkbox";
this.Bg4_0Checkbox.Size = new System.Drawing.Size(62, 17);
this.Bg4_0Checkbox.TabIndex = 11;
this.Bg4_0Checkbox.Text = "BG 4 ";
this.Bg4_0Checkbox.UseVisualStyleBackColor = true;
//
// Bg3_0Checkbox
//
this.Bg3_0Checkbox.AutoSize = true;
this.Bg3_0Checkbox.CheckAlign = System.Drawing.ContentAlignment.MiddleRight;
this.Bg3_0Checkbox.Location = new System.Drawing.Point(128, 76);
this.Bg3_0Checkbox.Name = "Bg3_0Checkbox";
this.Bg3_0Checkbox.Size = new System.Drawing.Size(62, 17);
this.Bg3_0Checkbox.TabIndex = 10;
this.Bg3_0Checkbox.Text = "BG 3 ";
this.Bg3_0Checkbox.UseVisualStyleBackColor = true;
//
// Bg2_0Checkbox
//
this.Bg2_0Checkbox.AutoSize = true;
this.Bg2_0Checkbox.CheckAlign = System.Drawing.ContentAlignment.MiddleRight;
this.Bg2_0Checkbox.Location = new System.Drawing.Point(128, 53);
this.Bg2_0Checkbox.Name = "Bg2_0Checkbox";
this.Bg2_0Checkbox.Size = new System.Drawing.Size(62, 17);
this.Bg2_0Checkbox.TabIndex = 9;
this.Bg2_0Checkbox.Text = "BG 2 ";
this.Bg2_0Checkbox.UseVisualStyleBackColor = true;
//
// Bg1_0Checkbox
//
this.Bg1_0Checkbox.AutoSize = true;
this.Bg1_0Checkbox.CheckAlign = System.Drawing.ContentAlignment.MiddleRight;
this.Bg1_0Checkbox.Location = new System.Drawing.Point(128, 30);
this.Bg1_0Checkbox.Name = "Bg1_0Checkbox";
this.Bg1_0Checkbox.Size = new System.Drawing.Size(62, 17);
this.Bg1_0Checkbox.TabIndex = 8;
this.Bg1_0Checkbox.Text = "BG 1 ";
this.Bg1_0Checkbox.UseVisualStyleBackColor = true;
//
// Bg4_1Checkbox
//
this.Bg4_1Checkbox.AutoSize = true;
this.Bg4_1Checkbox.Location = new System.Drawing.Point(234, 100);
this.Bg4_1Checkbox.Name = "Bg4_1Checkbox";
this.Bg4_1Checkbox.Size = new System.Drawing.Size(15, 14);
this.Bg4_1Checkbox.TabIndex = 7;
this.Bg4_1Checkbox.UseVisualStyleBackColor = true;
//
// Bg3_1Checkbox
//
this.Bg3_1Checkbox.AutoSize = true;
this.Bg3_1Checkbox.Location = new System.Drawing.Point(234, 77);
this.Bg3_1Checkbox.Name = "Bg3_1Checkbox";
this.Bg3_1Checkbox.Size = new System.Drawing.Size(15, 14);
this.Bg3_1Checkbox.TabIndex = 6;
this.Bg3_1Checkbox.UseVisualStyleBackColor = true;
//
// Bg2_1Checkbox
//
this.Bg2_1Checkbox.AutoSize = true;
this.Bg2_1Checkbox.Location = new System.Drawing.Point(234, 54);
this.Bg2_1Checkbox.Name = "Bg2_1Checkbox";
this.Bg2_1Checkbox.Size = new System.Drawing.Size(15, 14);
this.Bg2_1Checkbox.TabIndex = 5;
this.Bg2_1Checkbox.UseVisualStyleBackColor = true;
//
// Bg1_1Checkbox
//
this.Bg1_1Checkbox.AutoSize = true;
this.Bg1_1Checkbox.Location = new System.Drawing.Point(234, 31);
this.Bg1_1Checkbox.Name = "Bg1_1Checkbox";
this.Bg1_1Checkbox.Size = new System.Drawing.Size(15, 14);
this.Bg1_1Checkbox.TabIndex = 4;
this.Bg1_1Checkbox.UseVisualStyleBackColor = true;
//
// Obj4Checkbox
//
this.Obj4Checkbox.AutoSize = true;
this.Obj4Checkbox.Location = new System.Drawing.Point(21, 99);
this.Obj4Checkbox.Name = "Obj4Checkbox";
this.Obj4Checkbox.Size = new System.Drawing.Size(55, 17);
this.Obj4Checkbox.TabIndex = 3;
this.Obj4Checkbox.Text = "OBJ 4";
this.Obj4Checkbox.UseVisualStyleBackColor = true;
//
// Obj3Checkbox
//
this.Obj3Checkbox.AutoSize = true;
this.Obj3Checkbox.Location = new System.Drawing.Point(21, 76);
this.Obj3Checkbox.Name = "Obj3Checkbox";
this.Obj3Checkbox.Size = new System.Drawing.Size(55, 17);
this.Obj3Checkbox.TabIndex = 2;
this.Obj3Checkbox.Text = "OBJ 3";
this.Obj3Checkbox.UseVisualStyleBackColor = true;
//
// Obj2Checkbox
//
this.Obj2Checkbox.AutoSize = true;
this.Obj2Checkbox.Location = new System.Drawing.Point(21, 53);
this.Obj2Checkbox.Name = "Obj2Checkbox";
this.Obj2Checkbox.Size = new System.Drawing.Size(55, 17);
this.Obj2Checkbox.TabIndex = 1;
this.Obj2Checkbox.Text = "OBJ 2";
this.Obj2Checkbox.UseVisualStyleBackColor = true;
//
// Obj1Checkbox
//
this.Obj1Checkbox.AutoSize = true;
this.Obj1Checkbox.Location = new System.Drawing.Point(21, 30);
this.Obj1Checkbox.Name = "Obj1Checkbox";
this.Obj1Checkbox.Size = new System.Drawing.Size(55, 17);
this.Obj1Checkbox.TabIndex = 0;
this.Obj1Checkbox.Text = "OBJ 1";
this.Obj1Checkbox.UseVisualStyleBackColor = true;
//
// EntropyBox
//
this.EntropyBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.EntropyBox.FormattingEnabled = true;
this.EntropyBox.Items.AddRange(new object[] {
"None",
"Low",
"High"});
this.EntropyBox.Location = new System.Drawing.Point(18, 150);
this.EntropyBox.Name = "EntropyBox";
this.EntropyBox.Size = new System.Drawing.Size(128, 21);
this.EntropyBox.TabIndex = 14;
//
// lblEntropy
//
this.lblEntropy.Location = new System.Drawing.Point(15, 134);
this.lblEntropy.Name = "lblEntropy";
this.lblEntropy.Text = "Entropy";
//
// RegionBox
//
this.RegionBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.RegionBox.FormattingEnabled = true;
this.RegionBox.Items.AddRange(new object[] {
"Auto",
"NTSC",
"PAL"});
this.RegionBox.Location = new System.Drawing.Point(159, 150);
this.RegionBox.Name = "RegionBox";
this.RegionBox.Size = new System.Drawing.Size(128, 21);
this.RegionBox.TabIndex = 15;
//
// lblRegion
//
this.lblRegion.Location = new System.Drawing.Point(156, 134);
this.lblRegion.Name = "lblRegion";
this.lblRegion.Text = "Region";
//
// cbGameHotfixes
//
this.cbGameHotfixes.AutoSize = true;
this.cbGameHotfixes.Location = new System.Drawing.Point(18, 107);
this.cbGameHotfixes.Name = "cbGameHotfixes";
this.cbGameHotfixes.Size = new System.Drawing.Size(93, 17);
this.cbGameHotfixes.TabIndex = 22;
this.cbGameHotfixes.Text = "Game hotfixes";
this.cbGameHotfixes.UseVisualStyleBackColor = true;
//
// cbFastPPU
//
this.cbFastPPU.AutoSize = true;
this.cbFastPPU.Location = new System.Drawing.Point(159, 107);
this.cbFastPPU.Name = "cbFastPPU";
this.cbFastPPU.Size = new System.Drawing.Size(90, 17);
this.cbFastPPU.TabIndex = 23;
this.cbFastPPU.Text = "Use fast PPU";
this.cbFastPPU.UseVisualStyleBackColor = true;
this.cbFastPPU.CheckedChanged += new System.EventHandler(this.FastPPU_CheckedChanged);
//
// cbCropSGBFrame
//
this.cbCropSGBFrame.AutoSize = true;
this.cbCropSGBFrame.Location = new System.Drawing.Point(18, 84);
this.cbCropSGBFrame.Name = "cbCropSGBFrame";
this.cbCropSGBFrame.Size = new System.Drawing.Size(105, 17);
this.cbCropSGBFrame.TabIndex = 27;
this.cbCropSGBFrame.Text = "Crop SGB Frame";
this.cbCropSGBFrame.UseVisualStyleBackColor = true;
//
// cbUseSGB2
//
this.cbUseSGB2.AutoSize = true;
this.cbUseSGB2.Location = new System.Drawing.Point(159, 84);
this.cbUseSGB2.Name = "cbUseSGB2";
this.cbUseSGB2.Size = new System.Drawing.Size(76, 17);
this.cbUseSGB2.TabIndex = 30;
this.cbUseSGB2.Text = "Use SGB2";
this.cbUseSGB2.UseVisualStyleBackColor = true;
//
// BSNESOptions
//
this.AcceptButton = this.btnOk;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this.btnCancel;
this.ClientSize = new System.Drawing.Size(304, 356);
this.Controls.Add(this.cbUseSGB2);
this.Controls.Add(this.cbCropSGBFrame);
this.Controls.Add(this.cbFastPPU);
this.Controls.Add(this.cbGameHotfixes);
this.Controls.Add(this.lblEntropy);
this.Controls.Add(this.EntropyBox);
this.Controls.Add(this.lblRegion);
this.Controls.Add(this.RegionBox);
this.Controls.Add(this.groupBox1);
this.Controls.Add(this.lblDoubleSize);
this.Controls.Add(this.cbDoubleSize);
this.Controls.Add(this.btnCancel);
this.Controls.Add(this.btnOk);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "BSNESOptions";
this.ShowIcon = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "BSNES Options";
this.groupBox1.ResumeLayout(false);
this.groupBox1.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Button btnOk;
private System.Windows.Forms.Button btnCancel;
private System.Windows.Forms.CheckBox cbDoubleSize;
@ -365,7 +388,9 @@
private System.Windows.Forms.CheckBox Obj2Checkbox;
private System.Windows.Forms.CheckBox Obj1Checkbox;
private System.Windows.Forms.ComboBox EntropyBox;
private WinForms.Controls.LocLabelEx lblEntropy;
private WinForms.Controls.LocLabelEx lblEntropy;
private System.Windows.Forms.ComboBox RegionBox;
private WinForms.Controls.LocLabelEx lblRegion;
private System.Windows.Forms.CheckBox cbGameHotfixes;
private System.Windows.Forms.CheckBox cbFastPPU;
private System.Windows.Forms.CheckBox Bg1_0Checkbox;

View File

@ -20,6 +20,7 @@ namespace BizHawk.Client.EmuHawk
AlwaysDoubleSize = s.AlwaysDoubleSize,
CropSGBFrame = s.CropSGBFrame,
Entropy = ss.Entropy,
RegionOverride = ss.RegionOverride,
Hotfixes = ss.Hotfixes,
FastPPU = ss.FastPPU,
UseSGB2 = ss.UseSGB2,
@ -43,6 +44,7 @@ namespace BizHawk.Client.EmuHawk
s.AlwaysDoubleSize = dlg.AlwaysDoubleSize;
s.CropSGBFrame = dlg.CropSGBFrame;
ss.Entropy = dlg.Entropy;
ss.RegionOverride = dlg.RegionOverride;
ss.Hotfixes = dlg.Hotfixes;
ss.FastPPU = dlg.FastPPU;
ss.UseSGB2 = dlg.UseSGB2;
@ -100,6 +102,12 @@ namespace BizHawk.Client.EmuHawk
init => EntropyBox.SelectedIndex = (int) value;
}
private BsnesApi.REGION_OVERRIDE RegionOverride
{
get => (BsnesApi.REGION_OVERRIDE)RegionBox.SelectedIndex;
init => RegionBox.SelectedIndex = (int)value;
}
private bool ShowObj1 { get => Obj1Checkbox.Checked; init => Obj1Checkbox.Checked = value; }
private bool ShowObj2 { get => Obj2Checkbox.Checked; init => Obj2Checkbox.Checked = value; }
private bool ShowObj3 { get => Obj3Checkbox.Checked; init => Obj3Checkbox.Checked = value; }

View File

@ -1,120 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -1,253 +1,263 @@
using System;
using System.IO;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.InteropServices;
using BizHawk.Common;
using BizHawk.Emulation.Cores.Waterbox;
using BizHawk.BizInvoke;
using BizHawk.Emulation.Common;
using System.Linq;
namespace BizHawk.Emulation.Cores.Nintendo.BSNES
{
public abstract unsafe class BsnesCoreImpl
{
[BizImport(CallingConvention.Cdecl)]
public abstract void snes_set_audio_enabled(bool enabled);
[BizImport(CallingConvention.Cdecl)]
public abstract void snes_set_video_enabled(bool enabled);
[BizImport(CallingConvention.Cdecl)]
public abstract void snes_set_layer_enables(ref BsnesApi.LayerEnables layerEnables);
[BizImport(CallingConvention.Cdecl)]
public abstract void snes_set_trace_enabled(bool enabled);
[BizImport(CallingConvention.Cdecl)]
public abstract void snes_set_hooks_enabled(bool readHookEnabled, bool writeHookEnabled, bool executeHookEnabled);
[BizImport(CallingConvention.Cdecl)]
public abstract BsnesApi.SNES_REGION snes_get_region();
[BizImport(CallingConvention.Cdecl)]
public abstract BsnesApi.SNES_MAPPER snes_get_mapper();
[BizImport(CallingConvention.Cdecl)]
public abstract void* snes_get_memory_region(int id, out int size, out int wordSize);
[BizImport(CallingConvention.Cdecl)]
public abstract byte snes_bus_read(uint address);
[BizImport(CallingConvention.Cdecl)]
public abstract void snes_bus_write(uint address, byte value);
[BizImport(CallingConvention.Cdecl)]
public abstract void snes_set_callbacks(IntPtr[] snesCallbacks);
[BizImport(CallingConvention.Cdecl)]
public abstract void snes_init(BsnesApi.ENTROPY entropy, BsnesApi.BSNES_INPUT_DEVICE left,
BsnesApi.BSNES_INPUT_DEVICE right, ushort mergedBools);// bool hotfixes, bool fastPPU);
[BizImport(CallingConvention.Cdecl)]
public abstract void snes_power();
[BizImport(CallingConvention.Cdecl)]
public abstract void snes_term();
[BizImport(CallingConvention.Cdecl)]
public abstract void snes_reset();
[BizImport(CallingConvention.Cdecl)]
public abstract void snes_run();
[BizImport(CallingConvention.Cdecl)]
public abstract void snes_serialize(byte[] serializedData, int serializedSize);
[BizImport(CallingConvention.Cdecl)]
public abstract void snes_unserialize(byte[] serializedData, int serializedSize);
[BizImport(CallingConvention.Cdecl)]
public abstract int snes_serialized_size();
[BizImport(CallingConvention.Cdecl)]
public abstract void snes_load_cartridge_normal(string baseRomPath, byte[] romData, int romSize);
[BizImport(CallingConvention.Cdecl)]
public abstract void snes_load_cartridge_super_gameboy(string baseRomPath, byte[] romData, byte[] sgbRomData, ulong mergedRomSizes);
[BizImport(CallingConvention.Cdecl)]
public abstract void snes_get_cpu_registers(ref BsnesApi.CpuRegisters registers);
[BizImport(CallingConvention.Cdecl)]
public abstract void snes_set_cpu_register(string register, uint value);
[BizImport(CallingConvention.Cdecl)]
public abstract bool snes_cpu_step();
}
public unsafe partial class BsnesApi : IDisposable, IMonitor, IStatable
{
internal WaterboxHost exe;
internal BsnesCoreImpl core;
private readonly ICallingConventionAdapter _adapter;
private bool _disposed;
public void Enter()
{
exe.Enter();
}
public void Exit()
{
exe.Exit();
}
private readonly List<string> _readonlyFiles = new();
public void AddReadonlyFile(byte[] data, string name)
{
// current logic potentially requests the same name twice; once for program and once for data
// because this gets mapped to the same file, we only add it once
if (!_readonlyFiles.Contains(name))
{
exe.AddReadonlyFile(data, name);
_readonlyFiles.Add(name);
}
}
public void SetCallbacks(SnesCallbacks callbacks)
{
var functionPointerArray = callbacks
.AllDelegatesInMemoryOrder()
.Select(f => _adapter.GetFunctionPointerForDelegate(f))
.ToArray();
core.snes_set_callbacks(functionPointerArray);
}
public BsnesApi(string dllPath, CoreComm comm, IEnumerable<Delegate> allCallbacks)
{
exe = new WaterboxHost(new WaterboxOptions
{
Filename = "bsnes.wbx",
Path = dllPath,
SbrkHeapSizeKB = 12 * 1024,
using System;
using System.IO;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.InteropServices;
using BizHawk.Common;
using BizHawk.Emulation.Cores.Waterbox;
using BizHawk.BizInvoke;
using BizHawk.Emulation.Common;
using System.Linq;
namespace BizHawk.Emulation.Cores.Nintendo.BSNES
{
public abstract unsafe class BsnesCoreImpl
{
[BizImport(CallingConvention.Cdecl)]
public abstract void snes_set_audio_enabled(bool enabled);
[BizImport(CallingConvention.Cdecl)]
public abstract void snes_set_video_enabled(bool enabled);
[BizImport(CallingConvention.Cdecl)]
public abstract void snes_set_layer_enables(ref BsnesApi.LayerEnables layerEnables);
[BizImport(CallingConvention.Cdecl)]
public abstract void snes_set_trace_enabled(bool enabled);
[BizImport(CallingConvention.Cdecl)]
public abstract void snes_set_hooks_enabled(bool readHookEnabled, bool writeHookEnabled, bool executeHookEnabled);
[BizImport(CallingConvention.Cdecl)]
public abstract BsnesApi.SNES_REGION snes_get_region();
[BizImport(CallingConvention.Cdecl)]
public abstract BsnesApi.SNES_MAPPER snes_get_mapper();
[BizImport(CallingConvention.Cdecl)]
public abstract void* snes_get_memory_region(int id, out int size, out int wordSize);
[BizImport(CallingConvention.Cdecl)]
public abstract byte snes_bus_read(uint address);
[BizImport(CallingConvention.Cdecl)]
public abstract void snes_bus_write(uint address, byte value);
[BizImport(CallingConvention.Cdecl)]
public abstract void snes_set_callbacks(IntPtr[] snesCallbacks);
[BizImport(CallingConvention.Cdecl)]
public abstract void snes_init(ref BsnesApi.SnesInitData initData);
[BizImport(CallingConvention.Cdecl)]
public abstract void snes_power();
[BizImport(CallingConvention.Cdecl)]
public abstract void snes_term();
[BizImport(CallingConvention.Cdecl)]
public abstract void snes_reset();
[BizImport(CallingConvention.Cdecl)]
public abstract void snes_run();
[BizImport(CallingConvention.Cdecl)]
public abstract void snes_serialize(byte[] serializedData, int serializedSize);
[BizImport(CallingConvention.Cdecl)]
public abstract void snes_unserialize(byte[] serializedData, int serializedSize);
[BizImport(CallingConvention.Cdecl)]
public abstract int snes_serialized_size();
[BizImport(CallingConvention.Cdecl)]
public abstract void snes_load_cartridge_normal(string baseRomPath, byte[] romData, int romSize);
[BizImport(CallingConvention.Cdecl)]
public abstract void snes_load_cartridge_super_gameboy(string baseRomPath, byte[] romData, byte[] sgbRomData, ulong mergedRomSizes);
[BizImport(CallingConvention.Cdecl)]
public abstract void snes_get_cpu_registers(ref BsnesApi.CpuRegisters registers);
[BizImport(CallingConvention.Cdecl)]
public abstract void snes_set_cpu_register(string register, uint value);
[BizImport(CallingConvention.Cdecl)]
public abstract bool snes_cpu_step();
}
public unsafe partial class BsnesApi : IDisposable, IMonitor, IStatable
{
internal WaterboxHost exe;
internal BsnesCoreImpl core;
private readonly ICallingConventionAdapter _adapter;
private bool _disposed;
public void Enter()
{
exe.Enter();
}
public void Exit()
{
exe.Exit();
}
private readonly List<string> _readonlyFiles = new();
public void AddReadonlyFile(byte[] data, string name)
{
// current logic potentially requests the same name twice; once for program and once for data
// because this gets mapped to the same file, we only add it once
if (!_readonlyFiles.Contains(name))
{
exe.AddReadonlyFile(data, name);
_readonlyFiles.Add(name);
}
}
public void SetCallbacks(SnesCallbacks callbacks)
{
var functionPointerArray = callbacks
.AllDelegatesInMemoryOrder()
.Select(f => _adapter.GetFunctionPointerForDelegate(f))
.ToArray();
core.snes_set_callbacks(functionPointerArray);
}
public BsnesApi(string dllPath, CoreComm comm, IEnumerable<Delegate> allCallbacks)
{
exe = new WaterboxHost(new WaterboxOptions
{
Filename = "bsnes.wbx",
Path = dllPath,
SbrkHeapSizeKB = 12 * 1024,
InvisibleHeapSizeKB = 136 * 1024, // TODO: Roms get saved here and in mmap, consider consolidating?
MmapHeapSizeKB = 33 * 1024, // TODO: check whether this needs to be larger; it depends on the rom size
PlainHeapSizeKB = 1 * 1024,
SealedHeapSizeKB = 0,
SkipCoreConsistencyCheck = comm.CorePreferences.HasFlag(CoreComm.CorePreferencesFlags.WaterboxCoreConsistencyCheck),
SkipMemoryConsistencyCheck = comm.CorePreferences.HasFlag(CoreComm.CorePreferencesFlags.WaterboxMemoryConsistencyCheck),
});
using (exe.EnterExit())
{
// Marshal checks that function pointers passed to GetDelegateForFunctionPointer are
// _currently_ valid when created, even though they don't need to be valid until
// the delegate is later invoked. so GetInvoker needs to be acquired within a lock.
_adapter = CallingConventionAdapters.MakeWaterbox(allCallbacks, exe);
this.core = BizInvoker.GetInvoker<BsnesCoreImpl>(exe, exe, _adapter);
}
}
public void Dispose()
{
if (!_disposed)
{
_disposed = true;
exe.Dispose();
exe = null;
core = null;
// serializedSize = 0;
}
}
public delegate void snes_video_frame_t(ushort* data, int width, int height, int pitch);
public delegate void snes_audio_sample_t(short left, short right);
public delegate short snes_input_poll_t(int port, int index, int id);
public delegate void snes_controller_latch_t();
public delegate void snes_no_lag_t(bool sgb_poll);
public delegate string snes_path_request_t(int slot, string hint, bool required);
public delegate void snes_trace_t(string disassembly, string register_info);
public delegate void snes_read_hook_t(uint address);
public delegate void snes_write_hook_t(uint address, byte value);
public delegate void snes_exec_hook_t(uint address);
[StructLayout(LayoutKind.Sequential)]
public struct CpuRegisters
{
public uint pc;
public ushort a, x, y, z, s, d;
public byte b, p, mdr;
public bool e;
public ushort v, h;
}
[Flags]
public enum RegisterFlags : byte
{
C = 1,
Z = 2,
I = 4,
D = 8,
X = 16,
M = 32,
V = 64,
N = 128,
}
[StructLayout(LayoutKind.Sequential)]
public struct LayerEnables
{
public bool BG1_Prio0, BG1_Prio1;
public bool BG2_Prio0, BG2_Prio1;
public bool BG3_Prio0, BG3_Prio1;
public bool BG4_Prio0, BG4_Prio1;
public bool Obj_Prio0, Obj_Prio1, Obj_Prio2, Obj_Prio3;
}
[StructLayout(LayoutKind.Sequential)]
public class SnesCallbacks
{
public snes_video_frame_t videoFrameCb;
public snes_audio_sample_t audioSampleCb;
public snes_input_poll_t inputPollCb;
public snes_controller_latch_t controllerLatchCb;
public snes_no_lag_t noLagCb;
public snes_path_request_t pathRequestCb;
public snes_trace_t traceCb;
public snes_read_hook_t readHookCb;
public snes_write_hook_t writeHookCb;
public snes_exec_hook_t execHookCb;
private static List<FieldInfo> FieldsInOrder;
public IEnumerable<Delegate> AllDelegatesInMemoryOrder()
{
FieldsInOrder ??= GetType()
.GetFields()
.OrderBy(BizInvokerUtilities.ComputeFieldOffset)
.ToList();
return FieldsInOrder
.Select(f => (Delegate)f.GetValue(this));
}
}
public void Seal()
{
exe.Seal();
foreach (var s in _readonlyFiles)
{
exe.RemoveReadonlyFile(s);
}
_readonlyFiles.Clear();
}
// TODO: confirm that the serializedSize is CONSTANT for any given game,
// else this might be problematic
// private int serializedSize;// = 284275;
public void SaveStateBinary(BinaryWriter writer)
{
// if (serializedSize == 0)
// serializedSize = _core.snes_serialized_size();
// TODO: do some profiling and testing to check whether this is actually better than _exe.SaveStateBinary(writer);
// re-adding bsnes's own serialization will need to be done once it's confirmed to be deterministic, aka after libco update
// byte[] serializedData = new byte[serializedSize];
// _core.snes_serialize(serializedData, serializedSize);
// writer.Write(serializedData);
exe.SaveStateBinary(writer);
}
public void LoadStateBinary(BinaryReader reader)
{
// byte[] serializedData = reader.ReadBytes(serializedSize);
// _core.snes_unserialize(serializedData, serializedSize);
exe.LoadStateBinary(reader);
}
}
}
PlainHeapSizeKB = 1 * 1024,
SealedHeapSizeKB = 0,
SkipCoreConsistencyCheck = comm.CorePreferences.HasFlag(CoreComm.CorePreferencesFlags.WaterboxCoreConsistencyCheck),
SkipMemoryConsistencyCheck = comm.CorePreferences.HasFlag(CoreComm.CorePreferencesFlags.WaterboxMemoryConsistencyCheck),
});
using (exe.EnterExit())
{
// Marshal checks that function pointers passed to GetDelegateForFunctionPointer are
// _currently_ valid when created, even though they don't need to be valid until
// the delegate is later invoked. so GetInvoker needs to be acquired within a lock.
_adapter = CallingConventionAdapters.MakeWaterbox(allCallbacks, exe);
this.core = BizInvoker.GetInvoker<BsnesCoreImpl>(exe, exe, _adapter);
}
}
public void Dispose()
{
if (!_disposed)
{
_disposed = true;
exe.Dispose();
exe = null;
core = null;
// serializedSize = 0;
}
}
public delegate void snes_video_frame_t(ushort* data, int width, int height, int pitch);
public delegate void snes_audio_sample_t(short left, short right);
public delegate short snes_input_poll_t(int port, int index, int id);
public delegate void snes_controller_latch_t();
public delegate void snes_no_lag_t(bool sgb_poll);
public delegate string snes_path_request_t(int slot, string hint, bool required);
public delegate void snes_trace_t(string disassembly, string register_info);
public delegate void snes_read_hook_t(uint address);
public delegate void snes_write_hook_t(uint address, byte value);
public delegate void snes_exec_hook_t(uint address);
[StructLayout(LayoutKind.Sequential)]
public struct CpuRegisters
{
public uint pc;
public ushort a, x, y, z, s, d;
public byte b, p, mdr;
public bool e;
public ushort v, h;
}
[Flags]
public enum RegisterFlags : byte
{
C = 1,
Z = 2,
I = 4,
D = 8,
X = 16,
M = 32,
V = 64,
N = 128,
}
[StructLayout(LayoutKind.Sequential)]
public struct LayerEnables
{
public bool BG1_Prio0, BG1_Prio1;
public bool BG2_Prio0, BG2_Prio1;
public bool BG3_Prio0, BG3_Prio1;
public bool BG4_Prio0, BG4_Prio1;
public bool Obj_Prio0, Obj_Prio1, Obj_Prio2, Obj_Prio3;
}
[StructLayout(LayoutKind.Sequential)]
public class SnesCallbacks
{
public snes_video_frame_t videoFrameCb;
public snes_audio_sample_t audioSampleCb;
public snes_input_poll_t inputPollCb;
public snes_controller_latch_t controllerLatchCb;
public snes_no_lag_t noLagCb;
public snes_path_request_t pathRequestCb;
public snes_trace_t traceCb;
public snes_read_hook_t readHookCb;
public snes_write_hook_t writeHookCb;
public snes_exec_hook_t execHookCb;
private static List<FieldInfo> FieldsInOrder;
public IEnumerable<Delegate> AllDelegatesInMemoryOrder()
{
FieldsInOrder ??= GetType()
.GetFields()
.OrderBy(BizInvokerUtilities.ComputeFieldOffset)
.ToList();
return FieldsInOrder
.Select(f => (Delegate)f.GetValue(this));
}
}
[StructLayout(LayoutKind.Sequential)]
public struct SnesInitData
{
public ENTROPY entropy;
public BSNES_INPUT_DEVICE left_port;
public BSNES_INPUT_DEVICE right_port;
public bool hotfixes;
public bool fast_ppu;
public REGION_OVERRIDE region_override;
}
public void Seal()
{
exe.Seal();
foreach (var s in _readonlyFiles)
{
exe.RemoveReadonlyFile(s);
}
_readonlyFiles.Clear();
}
// TODO: confirm that the serializedSize is CONSTANT for any given game,
// else this might be problematic
// private int serializedSize;// = 284275;
public void SaveStateBinary(BinaryWriter writer)
{
// if (serializedSize == 0)
// serializedSize = _core.snes_serialized_size();
// TODO: do some profiling and testing to check whether this is actually better than _exe.SaveStateBinary(writer);
// re-adding bsnes's own serialization will need to be done once it's confirmed to be deterministic, aka after libco update
// byte[] serializedData = new byte[serializedSize];
// _core.snes_serialize(serializedData, serializedSize);
// writer.Write(serializedData);
exe.SaveStateBinary(writer);
}
public void LoadStateBinary(BinaryReader reader)
{
// byte[] serializedData = reader.ReadBytes(serializedSize);
// _core.snes_unserialize(serializedData, serializedSize);
exe.LoadStateBinary(reader);
}
}
}

View File

@ -61,5 +61,12 @@
NTSC = 0,
PAL = 1
}
public enum REGION_OVERRIDE : uint
{
Auto,
NTSC,
PAL
}
}
}

View File

@ -27,6 +27,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.BSNES
|| o.RightPort != _syncSettings.RightPort
|| o.LimitAnalogChangeSensitivity != _syncSettings.LimitAnalogChangeSensitivity
|| o.Entropy != _syncSettings.Entropy
|| o.RegionOverride != _syncSettings.RegionOverride
|| o.Hotfixes != _syncSettings.Hotfixes
|| o.FastPPU != _syncSettings.FastPPU
|| o.UseSGB2 != _syncSettings.UseSGB2;
@ -72,6 +73,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.BSNES
public BsnesApi.ENTROPY Entropy { get; set; } = BsnesApi.ENTROPY.Low;
public BsnesApi.REGION_OVERRIDE RegionOverride { get; set; } = BsnesApi.REGION_OVERRIDE.Auto;
public bool Hotfixes { get; set; } = true;
public bool FastPPU { get; set; } = true;

View File

@ -71,8 +71,16 @@ namespace BizHawk.Emulation.Cores.Nintendo.BSNES
generate_palette();
// TODO: massive random hack till waterboxhost gets fixed to support 5+ args
ushort mergedBools = (ushort) ((_syncSettings.Hotfixes ? 1 << 8 : 0) | (_syncSettings.FastPPU ? 1 : 0));
Api.core.snes_init(_syncSettings.Entropy, _syncSettings.LeftPort, _syncSettings.RightPort, mergedBools);
BsnesApi.SnesInitData snesInitData = new()
{
entropy = _syncSettings.Entropy,
left_port = _syncSettings.LeftPort,
right_port = _syncSettings.RightPort,
hotfixes = _syncSettings.Hotfixes,
fast_ppu = _syncSettings.FastPPU,
region_override = _syncSettings.RegionOverride,
};
Api.core.snes_init(ref snesInitData);
Api.SetCallbacks(callbacks);
// start up audio resampler

View File

@ -84,7 +84,7 @@ auto ICD::load() -> bool {
GB_random_set_enabled(configuration.hacks.entropy != "None");
if(Frequency == 0) {
GB_init(&sameboy, GB_MODEL_SGB_NO_SFC);
GB_init(&sameboy, Region::PAL() ? GB_MODEL_SGB_PAL_NO_SFC : GB_MODEL_SGB_NTSC_NO_SFC);
GB_load_boot_rom_from_buffer(&sameboy, (const unsigned char*)&SGB1BootROM[0], 256);
} else {
GB_init(&sameboy, GB_MODEL_SGB2_NO_SFC);

View File

@ -122,16 +122,14 @@ EXPORT void snes_set_callbacks(SnesCallbacks* callbacks)
snesCallbacks = SnesCallbacks(*callbacks);
}
EXPORT void snes_init(int entropy, uint left_port, uint right_port, uint16_t merged_bools)// bool hotfixes, bool fast_ppu)
EXPORT void snes_init(SnesInitData* init_data)
{
bool hotfixes = merged_bools >> 8;
bool fast_ppu = merged_bools & 1;
fprintf(stderr, "snes_init was called!\n");
emulator = new SuperFamicom::Interface;
program = new Program;
string entropy_string;
switch (entropy)
switch (init_data->entropy)
{
case 0: entropy_string = "None"; break;
case 1: entropy_string = "Low"; break;
@ -139,15 +137,17 @@ EXPORT void snes_init(int entropy, uint left_port, uint right_port, uint16_t mer
}
emulator->configure("Hacks/Entropy", entropy_string);
emulator->connect(ID::Port::Controller1, left_port);
emulator->connect(ID::Port::Controller2, right_port);
emulator->connect(ID::Port::Controller1, init_data->left_port);
emulator->connect(ID::Port::Controller2, init_data->right_port);
emulator->configure("Hacks/Hotfixes", hotfixes);
emulator->configure("Hacks/PPU/Fast", fast_ppu);
emulator->configure("Hacks/Hotfixes", init_data->hotfixes);
emulator->configure("Hacks/PPU/Fast", init_data->fast_ppu);
emulator->configure("Video/BlurEmulation", false); // blurs the video when not using fast ppu. I don't like it so I disable it here :)
// needed in order to get audio sync working. should probably figure out what exactly this does or how to change that properly
Emulator::audio.setFrequency(SAMPLE_RATE);
program->regionOverride = init_data->region_override;
}
EXPORT void snes_power(void)

View File

@ -28,6 +28,15 @@ enum SNES_MEMORY {
};
struct SnesInitData {
int entropy;
unsigned left_port;
unsigned right_port;
bool hotfixes;
bool fast_ppu;
int region_override;
};
struct LayerEnables
{
bool BG1_Prio0, BG1_Prio1;

View File

@ -42,6 +42,7 @@ struct Program : Emulator::Platform
bool overscan = false;
uint16_t backdropColor;
int regionOverride = 0;
public:
struct Game {
@ -361,7 +362,11 @@ auto Program::loadSuperFamicom() -> bool
auto heuristics = Heuristics::SuperFamicom(rom, superFamicom.location);
superFamicom.title = heuristics.title();
superFamicom.region = heuristics.videoRegion();
switch (regionOverride) {
case 0: superFamicom.region = heuristics.videoRegion(); break;
case 1: superFamicom.region = "NTSC"; break;
case 2: superFamicom.region = "PAL"; break;
}
superFamicom.manifest = heuristics.manifest();
hackPatchMemory(rom);