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

View File

@ -20,6 +20,7 @@ namespace BizHawk.Client.EmuHawk
AlwaysDoubleSize = s.AlwaysDoubleSize, AlwaysDoubleSize = s.AlwaysDoubleSize,
CropSGBFrame = s.CropSGBFrame, CropSGBFrame = s.CropSGBFrame,
Entropy = ss.Entropy, Entropy = ss.Entropy,
RegionOverride = ss.RegionOverride,
Hotfixes = ss.Hotfixes, Hotfixes = ss.Hotfixes,
FastPPU = ss.FastPPU, FastPPU = ss.FastPPU,
UseSGB2 = ss.UseSGB2, UseSGB2 = ss.UseSGB2,
@ -43,6 +44,7 @@ namespace BizHawk.Client.EmuHawk
s.AlwaysDoubleSize = dlg.AlwaysDoubleSize; s.AlwaysDoubleSize = dlg.AlwaysDoubleSize;
s.CropSGBFrame = dlg.CropSGBFrame; s.CropSGBFrame = dlg.CropSGBFrame;
ss.Entropy = dlg.Entropy; ss.Entropy = dlg.Entropy;
ss.RegionOverride = dlg.RegionOverride;
ss.Hotfixes = dlg.Hotfixes; ss.Hotfixes = dlg.Hotfixes;
ss.FastPPU = dlg.FastPPU; ss.FastPPU = dlg.FastPPU;
ss.UseSGB2 = dlg.UseSGB2; ss.UseSGB2 = dlg.UseSGB2;
@ -100,6 +102,12 @@ namespace BizHawk.Client.EmuHawk
init => EntropyBox.SelectedIndex = (int) value; 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 ShowObj1 { get => Obj1Checkbox.Checked; init => Obj1Checkbox.Checked = value; }
private bool ShowObj2 { get => Obj2Checkbox.Checked; init => Obj2Checkbox.Checked = value; } private bool ShowObj2 { get => Obj2Checkbox.Checked; init => Obj2Checkbox.Checked = value; }
private bool ShowObj3 { get => Obj3Checkbox.Checked; init => Obj3Checkbox.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"?> <?xml version="1.0" encoding="utf-8"?>
<root> <root>
<!-- <!--
Microsoft ResX Schema Microsoft ResX Schema
Version 2.0 Version 2.0
The primary goals of this format is to allow a simple XML format The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes various data types are done through the TypeConverter classes
associated with the data types. associated with the data types.
Example: Example:
... ado.net/XML headers & schema ... ... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader> <resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader> <resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, 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="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="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value> <value>[base64 mime encoded serialized .NET Framework object]</value>
</data> </data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> <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> <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment> <comment>This is a comment</comment>
</data> </data>
There are any number of "resheader" rows that contain simple There are any number of "resheader" rows that contain simple
name/value pairs. name/value pairs.
Each data row contains a name, and value. The row also contains a Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture. text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the Classes that don't support this are serialized and stored with the
mimetype set. mimetype set.
The mimetype is used for serialized objects, and tells the The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly: extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below. read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64 mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding. : and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64 mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding. : and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64 mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter : using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding. : 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: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:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true"> <xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType> <xsd:complexType>
<xsd:choice maxOccurs="unbounded"> <xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata"> <xsd:element name="metadata">
<xsd:complexType> <xsd:complexType>
<xsd:sequence> <xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" /> <xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence> </xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" /> <xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" /> <xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" /> <xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" /> <xsd:attribute ref="xml:space" />
</xsd:complexType> </xsd:complexType>
</xsd:element> </xsd:element>
<xsd:element name="assembly"> <xsd:element name="assembly">
<xsd:complexType> <xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" /> <xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" /> <xsd:attribute name="name" type="xsd:string" />
</xsd:complexType> </xsd:complexType>
</xsd:element> </xsd:element>
<xsd:element name="data"> <xsd:element name="data">
<xsd:complexType> <xsd:complexType>
<xsd:sequence> <xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> <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:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence> </xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> <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="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" /> <xsd:attribute ref="xml:space" />
</xsd:complexType> </xsd:complexType>
</xsd:element> </xsd:element>
<xsd:element name="resheader"> <xsd:element name="resheader">
<xsd:complexType> <xsd:complexType>
<xsd:sequence> <xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence> </xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" /> <xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType> </xsd:complexType>
</xsd:element> </xsd:element>
</xsd:choice> </xsd:choice>
</xsd:complexType> </xsd:complexType>
</xsd:element> </xsd:element>
</xsd:schema> </xsd:schema>
<resheader name="resmimetype"> <resheader name="resmimetype">
<value>text/microsoft-resx</value> <value>text/microsoft-resx</value>
</resheader> </resheader>
<resheader name="version"> <resheader name="version">
<value>2.0</value> <value>2.0</value>
</resheader> </resheader>
<resheader name="reader"> <resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<resheader name="writer"> <resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
</root> </root>

View File

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

View File

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

View File

@ -84,7 +84,7 @@ auto ICD::load() -> bool {
GB_random_set_enabled(configuration.hacks.entropy != "None"); GB_random_set_enabled(configuration.hacks.entropy != "None");
if(Frequency == 0) { 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); GB_load_boot_rom_from_buffer(&sameboy, (const unsigned char*)&SGB1BootROM[0], 256);
} else { } else {
GB_init(&sameboy, GB_MODEL_SGB2_NO_SFC); GB_init(&sameboy, GB_MODEL_SGB2_NO_SFC);

View File

@ -122,16 +122,14 @@ EXPORT void snes_set_callbacks(SnesCallbacks* callbacks)
snesCallbacks = 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"); fprintf(stderr, "snes_init was called!\n");
emulator = new SuperFamicom::Interface; emulator = new SuperFamicom::Interface;
program = new Program; program = new Program;
string entropy_string; string entropy_string;
switch (entropy) switch (init_data->entropy)
{ {
case 0: entropy_string = "None"; break; case 0: entropy_string = "None"; break;
case 1: entropy_string = "Low"; 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->configure("Hacks/Entropy", entropy_string);
emulator->connect(ID::Port::Controller1, left_port); emulator->connect(ID::Port::Controller1, init_data->left_port);
emulator->connect(ID::Port::Controller2, right_port); emulator->connect(ID::Port::Controller2, init_data->right_port);
emulator->configure("Hacks/Hotfixes", hotfixes); emulator->configure("Hacks/Hotfixes", init_data->hotfixes);
emulator->configure("Hacks/PPU/Fast", fast_ppu); 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 :) 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 // 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); Emulator::audio.setFrequency(SAMPLE_RATE);
program->regionOverride = init_data->region_override;
} }
EXPORT void snes_power(void) 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 struct LayerEnables
{ {
bool BG1_Prio0, BG1_Prio1; bool BG1_Prio0, BG1_Prio1;

View File

@ -42,6 +42,7 @@ struct Program : Emulator::Platform
bool overscan = false; bool overscan = false;
uint16_t backdropColor; uint16_t backdropColor;
int regionOverride = 0;
public: public:
struct Game { struct Game {
@ -361,7 +362,11 @@ auto Program::loadSuperFamicom() -> bool
auto heuristics = Heuristics::SuperFamicom(rom, superFamicom.location); auto heuristics = Heuristics::SuperFamicom(rom, superFamicom.location);
superFamicom.title = heuristics.title(); 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(); superFamicom.manifest = heuristics.manifest();
hackPatchMemory(rom); hackPatchMemory(rom);