diff --git a/BizHawk.Emulation/Consoles/Nintendo/SNES/LibsnesCore.cs b/BizHawk.Emulation/Consoles/Nintendo/SNES/LibsnesCore.cs index b86b19ac10..26a26a49b3 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/SNES/LibsnesCore.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/SNES/LibsnesCore.cs @@ -132,7 +132,13 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES BG2_TDADDR = 21, //$210C BG3_TDADDR = 22, - BG4_TDADDR = 23 + BG4_TDADDR = 23, + //$2133 SETINI + SETINI_MODE7_EXTBG = 30, + SETINI_HIRES = 31, + SETINI_OVERSCAN = 32, + SETINI_OBJ_INTERLACE = 33, + SETINI_SCREEN_INTERLACE = 34 } public enum SNES_MEMORY : uint diff --git a/BizHawk.Emulation/Consoles/Nintendo/SNES/SNESGraphicsDecoder.cs b/BizHawk.Emulation/Consoles/Nintendo/SNES/SNESGraphicsDecoder.cs index 9eddd51f69..c30d183d1b 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/SNES/SNESGraphicsDecoder.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/SNES/SNESGraphicsDecoder.cs @@ -136,6 +136,52 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES public BGInfos BG = new BGInfos(); public ModeInfo Mode = new ModeInfo(); + + public bool SETINI_Mode7ExtBG { private set; get; } + public bool SETINI_HiRes { private set; get; } + public bool SETINI_Overscan { private set; get; } + public bool SETINI_ObjInterlace { private set; get; } + public bool SETINI_ScreenInterlace { private set; get; } + + public static ScreenInfo GetScreenInfo() + { + var si = new ScreenInfo(); + + si.SETINI_Mode7ExtBG = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.SETINI_MODE7_EXTBG) == 1; + si.SETINI_HiRes = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.SETINI_HIRES) == 1; + si.SETINI_Overscan = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.SETINI_OVERSCAN) == 1; + si.SETINI_ObjInterlace = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.SETINI_OBJ_INTERLACE) == 1; + si.SETINI_ScreenInterlace = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.SETINI_SCREEN_INTERLACE) == 1; + + si.Mode.MODE = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG_MODE); + si.BG.BG1.Bpp = ModeBpps[si.Mode.MODE, 0]; + si.BG.BG2.Bpp = ModeBpps[si.Mode.MODE, 1]; + si.BG.BG3.Bpp = ModeBpps[si.Mode.MODE, 2]; + si.BG.BG4.Bpp = ModeBpps[si.Mode.MODE, 3]; + + if (si.Mode.MODE == 7 && si.SETINI_Mode7ExtBG) + si.BG.BG2.Bpp = 7; + + si.BG.BG1.TILESIZE = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG1_TILESIZE); + si.BG.BG2.TILESIZE = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG2_TILESIZE); + si.BG.BG3.TILESIZE = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG3_TILESIZE); + si.BG.BG4.TILESIZE = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG4_TILESIZE); + + si.BG.BG1.SCSIZE = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG1_SCSIZE); + si.BG.BG2.SCSIZE = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG2_SCSIZE); + si.BG.BG3.SCSIZE = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG3_SCSIZE); + si.BG.BG4.SCSIZE = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG4_SCSIZE); + si.BG.BG1.SCADDR = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG1_SCADDR); + si.BG.BG2.SCADDR = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG2_SCADDR); + si.BG.BG3.SCADDR = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG3_SCADDR); + si.BG.BG4.SCADDR = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG4_SCADDR); + si.BG.BG1.TDADDR = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG1_TDADDR); + si.BG.BG2.TDADDR = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG2_TDADDR); + si.BG.BG3.TDADDR = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG3_TDADDR); + si.BG.BG4.TDADDR = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG4_TDADDR); + + return si; + } } static int[,] ModeBpps = new[,] { @@ -153,33 +199,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES public ScreenInfo ScanScreenInfo() { - var si = new ScreenInfo(); - - si.Mode.MODE = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG_MODE); - si.BG.BG1.Bpp = ModeBpps[si.Mode.MODE, 0]; - si.BG.BG2.Bpp = ModeBpps[si.Mode.MODE, 1]; - si.BG.BG3.Bpp = ModeBpps[si.Mode.MODE, 2]; - si.BG.BG4.Bpp = ModeBpps[si.Mode.MODE, 3]; - - si.BG.BG1.TILESIZE = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG1_TILESIZE); - si.BG.BG2.TILESIZE = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG2_TILESIZE); - si.BG.BG3.TILESIZE = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG3_TILESIZE); - si.BG.BG4.TILESIZE = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG4_TILESIZE); - - si.BG.BG1.SCSIZE = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG1_SCSIZE); - si.BG.BG2.SCSIZE = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG2_SCSIZE); - si.BG.BG3.SCSIZE = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG3_SCSIZE); - si.BG.BG4.SCSIZE = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG4_SCSIZE); - si.BG.BG1.SCADDR = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG1_SCADDR); - si.BG.BG2.SCADDR = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG2_SCADDR); - si.BG.BG3.SCADDR = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG3_SCADDR); - si.BG.BG4.SCADDR = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG4_SCADDR); - si.BG.BG1.TDADDR = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG1_TDADDR); - si.BG.BG2.TDADDR = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG2_TDADDR); - si.BG.BG3.TDADDR = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG3_TDADDR); - si.BG.BG4.TDADDR = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG4_TDADDR); - - return si; + return ScreenInfo.GetScreenInfo(); } //the same basic color table that libsnes uses to convert from snes 555 to rgba32 @@ -236,19 +256,15 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES /// /// decodes a mode7 BG. youll still need to paletteize and colorize it. /// - public void DecodeMode7BG(int* screen, int stride) + public void DecodeMode7BG(int* screen, int stride, bool extBg) { - int[] tileCache = _tileCache[7]; + int[] tileCache = _tileCache[extBg?17:7]; for (int ty = 0, tidx = 0; ty < 128; ty++) { for (int tx = 0; tx < 128; tx++, tidx++) { int tileEntry = vram[tidx * 2]; int src = tileEntry * 64; - if (tileEntry != 0) - { - int zzz = 9; - } for (int py = 0, pix=src; py < 8; py++) { for (int px = 0; px < 8; px++, pix++) @@ -366,7 +382,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES } } - int[][] _tileCache = new int[9][]; + int[][] _tileCache = new int[18][]; /// /// Caches all tiles at the 2bpp, 4bpp, and 8bpp decoded states. @@ -387,6 +403,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES CacheTiles_Merge(2); CacheTiles_Merge(4); CacheTilesMode7(); + CacheTilesMode7ExtBg(); } public void CacheTilesMode7() @@ -402,6 +419,19 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES } } + + void CacheTilesMode7ExtBg() + { + int numtiles = 256; + int[] tiles = new int[8 * 8 * numtiles]; + _tileCache[17] = tiles; + int[] mode7tiles = _tileCache[7]; + int numPixels = numtiles*8*8; + for (int i = 0; i < numPixels; i++) + tiles[i] = mode7tiles[i] & 0x7F; + } + + /// /// merges one type of tiles with another to create the higher-order bitdepth. /// TODO - templateize this when we change it to c++ @@ -446,11 +476,11 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES /// /// renders the mode7 tiles to a screen with the predefined size. /// - public void RenderMode7TilesToScreen(int* screen, int stride) + public void RenderMode7TilesToScreen(int* screen, int stride, bool ext) { int numTiles = 256; int tilesWide = 16; - int[] tilebuf = _tileCache[7]; + int[] tilebuf = _tileCache[ext?17:7]; for (int i = 0; i < numTiles; i++) { int ty = i / tilesWide; diff --git a/BizHawk.MultiClient/SNESTools/SNESGraphicsDebugger.Designer.cs b/BizHawk.MultiClient/SNESTools/SNESGraphicsDebugger.Designer.cs index 94dcc92a07..18f81f523f 100644 --- a/BizHawk.MultiClient/SNESTools/SNESGraphicsDebugger.Designer.cs +++ b/BizHawk.MultiClient/SNESTools/SNESGraphicsDebugger.Designer.cs @@ -90,16 +90,19 @@ this.label2 = new System.Windows.Forms.Label(); this.txtBG1SizeBits = new System.Windows.Forms.TextBox(); this.groupBox4 = new System.Windows.Forms.GroupBox(); + this.label17 = new System.Windows.Forms.Label(); + this.check2x = new System.Windows.Forms.CheckBox(); this.radioButton15 = new System.Windows.Forms.RadioButton(); this.radioButton14 = new System.Windows.Forms.RadioButton(); + this.label14 = new System.Windows.Forms.Label(); + this.comboDisplayType = new System.Windows.Forms.ComboBox(); + this.radioButton1 = new System.Windows.Forms.RadioButton(); this.grpQuadrants = new System.Windows.Forms.GroupBox(); this.rbQuad3 = new System.Windows.Forms.RadioButton(); this.rbQuad2 = new System.Windows.Forms.RadioButton(); this.rbQuadAll = new System.Windows.Forms.RadioButton(); this.rbQuad1 = new System.Windows.Forms.RadioButton(); this.rbQuad0 = new System.Windows.Forms.RadioButton(); - this.comboDisplayType = new System.Windows.Forms.ComboBox(); - this.radioButton1 = new System.Windows.Forms.RadioButton(); this.radioButton2 = new System.Windows.Forms.RadioButton(); this.radioButton13 = new System.Windows.Forms.RadioButton(); this.radioButton3 = new System.Windows.Forms.RadioButton(); @@ -122,10 +125,19 @@ this.lblDetailsPaletteAddress = new System.Windows.Forms.Label(); this.tabPage2 = new System.Windows.Forms.TabPage(); this.panel2 = new System.Windows.Forms.Panel(); - this.label14 = new System.Windows.Forms.Label(); - this.label17 = new System.Windows.Forms.Label(); - this.check2x = new System.Windows.Forms.CheckBox(); this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); + this.label20 = new System.Windows.Forms.Label(); + this.checkScreenExtbg = new System.Windows.Forms.CheckBox(); + this.label21 = new System.Windows.Forms.Label(); + this.label18391 = new System.Windows.Forms.Label(); + this.checkScreenHires = new System.Windows.Forms.CheckBox(); + this.label198129381279841 = new System.Windows.Forms.Label(); + this.checkScreenOverscan = new System.Windows.Forms.CheckBox(); + this.label123812831 = new System.Windows.Forms.Label(); + this.checkScreenObjInterlace = new System.Windows.Forms.CheckBox(); + this.label2193813 = new System.Windows.Forms.Label(); + this.checkScreenInterlace = new System.Windows.Forms.CheckBox(); + this.radioButton6 = new System.Windows.Forms.RadioButton(); this.paletteViewer = new BizHawk.MultiClient.SNESGraphicsViewer(); this.viewer = new BizHawk.MultiClient.SNESGraphicsViewer(); this.menuStrip1.SuspendLayout(); @@ -312,6 +324,17 @@ // // groupBox2 // + this.groupBox2.Controls.Add(this.label2193813); + this.groupBox2.Controls.Add(this.checkScreenInterlace); + this.groupBox2.Controls.Add(this.label123812831); + this.groupBox2.Controls.Add(this.checkScreenObjInterlace); + this.groupBox2.Controls.Add(this.label198129381279841); + this.groupBox2.Controls.Add(this.checkScreenOverscan); + this.groupBox2.Controls.Add(this.label18391); + this.groupBox2.Controls.Add(this.checkScreenHires); + this.groupBox2.Controls.Add(this.label21); + this.groupBox2.Controls.Add(this.checkScreenExtbg); + this.groupBox2.Controls.Add(this.label20); this.groupBox2.Controls.Add(this.label16); this.groupBox2.Controls.Add(this.txtScreenBG4TSize); this.groupBox2.Controls.Add(this.txtScreenBG3TSize); @@ -330,7 +353,7 @@ this.groupBox2.Controls.Add(this.label5); this.groupBox2.Location = new System.Drawing.Point(0, 0); this.groupBox2.Name = "groupBox2"; - this.groupBox2.Size = new System.Drawing.Size(229, 122); + this.groupBox2.Size = new System.Drawing.Size(229, 160); this.groupBox2.TabIndex = 16; this.groupBox2.TabStop = false; this.groupBox2.Text = "Screen"; @@ -516,7 +539,7 @@ this.groupBox1.Controls.Add(this.txtBG1SizeInTiles); this.groupBox1.Controls.Add(this.label2); this.groupBox1.Controls.Add(this.txtBG1SizeBits); - this.groupBox1.Location = new System.Drawing.Point(0, 125); + this.groupBox1.Location = new System.Drawing.Point(0, 166); this.groupBox1.Name = "groupBox1"; this.groupBox1.Size = new System.Drawing.Size(229, 245); this.groupBox1.TabIndex = 3; @@ -704,7 +727,7 @@ // txtBG1TDAddrBits // this.txtBG1TDAddrBits.BackColor = System.Drawing.Color.LightGreen; - this.txtBG1TDAddrBits.Location = new System.Drawing.Point(6, 180); + this.txtBG1TDAddrBits.Location = new System.Drawing.Point(5, 180); this.txtBG1TDAddrBits.Multiline = true; this.txtBG1TDAddrBits.Name = "txtBG1TDAddrBits"; this.txtBG1TDAddrBits.ReadOnly = true; @@ -743,7 +766,7 @@ // txtBG1SCAddrBits // this.txtBG1SCAddrBits.BackColor = System.Drawing.Color.LightGreen; - this.txtBG1SCAddrBits.Location = new System.Drawing.Point(6, 157); + this.txtBG1SCAddrBits.Location = new System.Drawing.Point(5, 157); this.txtBG1SCAddrBits.Multiline = true; this.txtBG1SCAddrBits.Name = "txtBG1SCAddrBits"; this.txtBG1SCAddrBits.ReadOnly = true; @@ -773,7 +796,7 @@ // txtBG1SizeBits // this.txtBG1SizeBits.BackColor = System.Drawing.Color.LightGreen; - this.txtBG1SizeBits.Location = new System.Drawing.Point(6, 110); + this.txtBG1SizeBits.Location = new System.Drawing.Point(5, 110); this.txtBG1SizeBits.Multiline = true; this.txtBG1SizeBits.Name = "txtBG1SizeBits"; this.txtBG1SizeBits.ReadOnly = true; @@ -783,6 +806,7 @@ // // groupBox4 // + this.groupBox4.Controls.Add(this.radioButton6); this.groupBox4.Controls.Add(this.label17); this.groupBox4.Controls.Add(this.check2x); this.groupBox4.Controls.Add(this.radioButton15); @@ -803,6 +827,29 @@ this.groupBox4.TabIndex = 35; this.groupBox4.TabStop = false; // + // label17 + // + this.label17.AutoSize = true; + this.label17.Location = new System.Drawing.Point(84, 173); + this.label17.Name = "label17"; + this.label17.Size = new System.Drawing.Size(61, 13); + this.label17.TabIndex = 48; + this.label17.Text = "deprecated"; + // + // check2x + // + this.check2x.Appearance = System.Windows.Forms.Appearance.Button; + this.check2x.Location = new System.Drawing.Point(119, 8); + this.check2x.Name = "check2x"; + this.check2x.RightToLeft = System.Windows.Forms.RightToLeft.Yes; + this.check2x.Size = new System.Drawing.Size(39, 21); + this.check2x.TabIndex = 45; + this.check2x.Text = "1024"; + this.toolTip1.SetToolTip(this.check2x, "Sets graphics viewport size to 1024 (unchecked is 512).\r\nContent will be scaled t" + + "o fill specified size"); + this.check2x.UseVisualStyleBackColor = true; + this.check2x.CheckedChanged += new System.EventHandler(this.check2x_CheckedChanged); + // // radioButton15 // this.radioButton15.AutoSize = true; @@ -827,6 +874,51 @@ this.radioButton14.Text = "OBJ"; this.radioButton14.UseVisualStyleBackColor = true; // + // label14 + // + this.label14.AutoSize = true; + this.label14.Location = new System.Drawing.Point(41, 127); + this.label14.Name = "label14"; + this.label14.Size = new System.Drawing.Size(46, 13); + this.label14.TabIndex = 47; + this.label14.Text = "disabled"; + // + // comboDisplayType + // + this.comboDisplayType.DropDownHeight = 200; + this.comboDisplayType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.comboDisplayType.FormattingEnabled = true; + this.comboDisplayType.IntegralHeight = false; + this.comboDisplayType.ItemHeight = 13; + this.comboDisplayType.Items.AddRange(new object[] { + "BG1", + "BG2", + "BG3", + "BG4", + "OBJ", + "2bpp tiles", + "4bpp tiles", + "8bpp tiles", + "Mode7 tiles", + "Mode7Ext tiles"}); + this.comboDisplayType.Location = new System.Drawing.Point(6, 8); + this.comboDisplayType.Name = "comboDisplayType"; + this.comboDisplayType.Size = new System.Drawing.Size(107, 21); + this.comboDisplayType.TabIndex = 18; + this.comboDisplayType.SelectedIndexChanged += new System.EventHandler(this.comboDisplayType_SelectedIndexChanged); + // + // radioButton1 + // + this.radioButton1.AutoSize = true; + this.radioButton1.Enabled = false; + this.radioButton1.Location = new System.Drawing.Point(6, 35); + this.radioButton1.Name = "radioButton1"; + this.radioButton1.Size = new System.Drawing.Size(46, 17); + this.radioButton1.TabIndex = 19; + this.radioButton1.TabStop = true; + this.radioButton1.Text = "BG1"; + this.radioButton1.UseVisualStyleBackColor = true; + // // grpQuadrants // this.grpQuadrants.Controls.Add(this.rbQuad3); @@ -893,41 +985,6 @@ this.rbQuad0.UseVisualStyleBackColor = true; this.rbQuad0.CheckedChanged += new System.EventHandler(this.rbQuad_CheckedChanged); // - // comboDisplayType - // - this.comboDisplayType.DropDownHeight = 200; - this.comboDisplayType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.comboDisplayType.FormattingEnabled = true; - this.comboDisplayType.IntegralHeight = false; - this.comboDisplayType.ItemHeight = 13; - this.comboDisplayType.Items.AddRange(new object[] { - "BG1", - "BG2", - "BG3", - "BG4", - "OBJ", - "2bpp tiles", - "4bpp tiles", - "8bpp tiles", - "Mode7 tiles"}); - this.comboDisplayType.Location = new System.Drawing.Point(6, 8); - this.comboDisplayType.Name = "comboDisplayType"; - this.comboDisplayType.Size = new System.Drawing.Size(107, 21); - this.comboDisplayType.TabIndex = 18; - this.comboDisplayType.SelectedIndexChanged += new System.EventHandler(this.comboDisplayType_SelectedIndexChanged); - // - // radioButton1 - // - this.radioButton1.AutoSize = true; - this.radioButton1.Enabled = false; - this.radioButton1.Location = new System.Drawing.Point(6, 35); - this.radioButton1.Name = "radioButton1"; - this.radioButton1.Size = new System.Drawing.Size(46, 17); - this.radioButton1.TabIndex = 19; - this.radioButton1.TabStop = true; - this.radioButton1.Text = "BG1"; - this.radioButton1.UseVisualStyleBackColor = true; - // // radioButton2 // this.radioButton2.AutoSize = true; @@ -1171,44 +1228,128 @@ this.panel2.Size = new System.Drawing.Size(516, 667); this.panel2.TabIndex = 1; // - // label14 - // - this.label14.AutoSize = true; - this.label14.Location = new System.Drawing.Point(85, 111); - this.label14.Name = "label14"; - this.label14.Size = new System.Drawing.Size(46, 13); - this.label14.TabIndex = 47; - this.label14.Text = "disabled"; - // - // label17 - // - this.label17.AutoSize = true; - this.label17.Location = new System.Drawing.Point(84, 173); - this.label17.Name = "label17"; - this.label17.Size = new System.Drawing.Size(61, 13); - this.label17.TabIndex = 48; - this.label17.Text = "deprecated"; - // - // check2x - // - this.check2x.Appearance = System.Windows.Forms.Appearance.Button; - this.check2x.Location = new System.Drawing.Point(119, 8); - this.check2x.Name = "check2x"; - this.check2x.RightToLeft = System.Windows.Forms.RightToLeft.Yes; - this.check2x.Size = new System.Drawing.Size(39, 21); - this.check2x.TabIndex = 45; - this.check2x.Text = "1024"; - this.toolTip1.SetToolTip(this.check2x, "Sets graphics viewport size to 1024 (unchecked is 512).\r\nContent will be scaled t" + - "o fill specified size"); - this.check2x.UseVisualStyleBackColor = true; - this.check2x.CheckedChanged += new System.EventHandler(this.check2x_CheckedChanged); - // // toolTip1 // this.toolTip1.AutoPopDelay = 5000; this.toolTip1.InitialDelay = 250; this.toolTip1.ReshowDelay = 100; // + // label20 + // + this.label20.AutoSize = true; + this.label20.Location = new System.Drawing.Point(1, 50); + this.label20.Name = "label20"; + this.label20.Size = new System.Drawing.Size(42, 13); + this.label20.TabIndex = 21; + this.label20.Text = "SETINI"; + // + // checkScreenExtbg + // + this.checkScreenExtbg.AutoSize = true; + this.checkScreenExtbg.Enabled = false; + this.checkScreenExtbg.Location = new System.Drawing.Point(10, 66); + this.checkScreenExtbg.Name = "checkScreenExtbg"; + this.checkScreenExtbg.Size = new System.Drawing.Size(15, 14); + this.checkScreenExtbg.TabIndex = 22; + this.checkScreenExtbg.UseVisualStyleBackColor = true; + // + // label21 + // + this.label21.AutoSize = true; + this.label21.Location = new System.Drawing.Point(24, 66); + this.label21.Name = "label21"; + this.label21.Size = new System.Drawing.Size(43, 13); + this.label21.TabIndex = 23; + this.label21.Text = "EXTBG"; + // + // label18391 + // + this.label18391.AutoSize = true; + this.label18391.Location = new System.Drawing.Point(24, 80); + this.label18391.Name = "label18391"; + this.label18391.Size = new System.Drawing.Size(40, 13); + this.label18391.TabIndex = 25; + this.label18391.Text = "HIRES"; + // + // checkScreenHires + // + this.checkScreenHires.AutoSize = true; + this.checkScreenHires.Enabled = false; + this.checkScreenHires.Location = new System.Drawing.Point(10, 80); + this.checkScreenHires.Name = "checkScreenHires"; + this.checkScreenHires.Size = new System.Drawing.Size(15, 14); + this.checkScreenHires.TabIndex = 24; + this.checkScreenHires.UseVisualStyleBackColor = true; + // + // label198129381279841 + // + this.label198129381279841.AutoSize = true; + this.label198129381279841.Location = new System.Drawing.Point(24, 94); + this.label198129381279841.Name = "label198129381279841"; + this.label198129381279841.Size = new System.Drawing.Size(47, 13); + this.label198129381279841.TabIndex = 27; + this.label198129381279841.Text = "O.SCAN"; + // + // checkScreenOverscan + // + this.checkScreenOverscan.AutoSize = true; + this.checkScreenOverscan.Enabled = false; + this.checkScreenOverscan.Location = new System.Drawing.Point(10, 94); + this.checkScreenOverscan.Name = "checkScreenOverscan"; + this.checkScreenOverscan.Size = new System.Drawing.Size(15, 14); + this.checkScreenOverscan.TabIndex = 26; + this.checkScreenOverscan.UseVisualStyleBackColor = true; + // + // label123812831 + // + this.label123812831.AutoSize = true; + this.label123812831.Location = new System.Drawing.Point(24, 107); + this.label123812831.Name = "label123812831"; + this.label123812831.Size = new System.Drawing.Size(49, 13); + this.label123812831.TabIndex = 29; + this.label123812831.Text = "O.INTLC"; + // + // checkScreenObjInterlace + // + this.checkScreenObjInterlace.AutoSize = true; + this.checkScreenObjInterlace.Enabled = false; + this.checkScreenObjInterlace.Location = new System.Drawing.Point(10, 107); + this.checkScreenObjInterlace.Name = "checkScreenObjInterlace"; + this.checkScreenObjInterlace.Size = new System.Drawing.Size(15, 14); + this.checkScreenObjInterlace.TabIndex = 28; + this.checkScreenObjInterlace.UseVisualStyleBackColor = true; + // + // label2193813 + // + this.label2193813.AutoSize = true; + this.label2193813.Location = new System.Drawing.Point(24, 120); + this.label2193813.Name = "label2193813"; + this.label2193813.Size = new System.Drawing.Size(48, 13); + this.label2193813.TabIndex = 31; + this.label2193813.Text = "S.INTLC"; + // + // checkScreenInterlace + // + this.checkScreenInterlace.AutoSize = true; + this.checkScreenInterlace.Enabled = false; + this.checkScreenInterlace.Location = new System.Drawing.Point(10, 120); + this.checkScreenInterlace.Name = "checkScreenInterlace"; + this.checkScreenInterlace.Size = new System.Drawing.Size(15, 14); + this.checkScreenInterlace.TabIndex = 30; + this.checkScreenInterlace.UseVisualStyleBackColor = true; + // + // radioButton6 + // + this.radioButton6.AutoSize = true; + this.radioButton6.Enabled = false; + this.radioButton6.Location = new System.Drawing.Point(56, 99); + this.radioButton6.Name = "radioButton6"; + this.radioButton6.Size = new System.Drawing.Size(73, 17); + this.radioButton6.TabIndex = 49; + this.radioButton6.TabStop = true; + this.radioButton6.Text = "Mode7Ext"; + this.radioButton6.UseVisualStyleBackColor = true; + // // paletteViewer // this.paletteViewer.BackColor = System.Drawing.Color.Transparent; @@ -1368,5 +1509,17 @@ private System.Windows.Forms.Label label14; private System.Windows.Forms.ToolTip toolTip1; private System.Windows.Forms.CheckBox check2x; + private System.Windows.Forms.Label label21; + private System.Windows.Forms.CheckBox checkScreenExtbg; + private System.Windows.Forms.Label label20; + private System.Windows.Forms.Label label18391; + private System.Windows.Forms.CheckBox checkScreenHires; + private System.Windows.Forms.Label label198129381279841; + private System.Windows.Forms.CheckBox checkScreenOverscan; + private System.Windows.Forms.Label label123812831; + private System.Windows.Forms.CheckBox checkScreenObjInterlace; + private System.Windows.Forms.Label label2193813; + private System.Windows.Forms.CheckBox checkScreenInterlace; + private System.Windows.Forms.RadioButton radioButton6; } } \ No newline at end of file diff --git a/BizHawk.MultiClient/SNESTools/SNESGraphicsDebugger.cs b/BizHawk.MultiClient/SNESTools/SNESGraphicsDebugger.cs index a98845dade..a4818fd814 100644 --- a/BizHawk.MultiClient/SNESTools/SNESGraphicsDebugger.cs +++ b/BizHawk.MultiClient/SNESTools/SNESGraphicsDebugger.cs @@ -86,6 +86,7 @@ namespace BizHawk.MultiClient private void sliderScanline_ValueChanged(object sender, EventArgs e) { if (suppression) return; + checkScanlineControl.Checked = true; SyncCore(); suppression = true; nudScanline.Value = 224 - sliderScanline.Value; @@ -123,6 +124,13 @@ namespace BizHawk.MultiClient var gd = new SNESGraphicsDecoder(); var si = gd.ScanScreenInfo(); + checkScreenExtbg.Checked = si.SETINI_Mode7ExtBG; + checkScreenHires.Checked = si.SETINI_HiRes; + checkScreenOverscan.Checked = si.SETINI_Overscan; + checkScreenObjInterlace.Checked = si.SETINI_ObjInterlace; + checkScreenInterlace.Checked = si.SETINI_ScreenInterlace; + + txtModeBits.Text = si.Mode.MODE.ToString(); txtScreenBG1Bpp.Text = FormatBpp(si.BG.BG1.Bpp); txtScreenBG2Bpp.Text = FormatBpp(si.BG.BG2.Bpp); @@ -194,7 +202,13 @@ namespace BizHawk.MultiClient { //256 tiles allocate(128, 128); - gd.RenderMode7TilesToScreen(pixelptr, stride / 4); + gd.RenderMode7TilesToScreen(pixelptr, stride / 4, false); + } + if (selection == "Mode7Ext tiles") + { + //256 tiles + allocate(128, 128); + gd.RenderMode7TilesToScreen(pixelptr, stride / 4, true); } if (selection == "BG1" || selection == "BG2" || selection == "BG3" || selection == "BG4") { @@ -202,18 +216,26 @@ namespace BizHawk.MultiClient var si = gd.ScanScreenInfo(); var bg = si.BG[bgnum]; + bool handled = false; if (bg.Enabled) { - if (bgnum == 1 && si.Mode.MODE == 7) + if (si.Mode.MODE == 7) { - allocate(1024, 1024); - gd.DecodeMode7BG(pixelptr, stride / 4); - int numPixels = 128 * 128 * 8 * 8; - gd.Paletteize(pixelptr, 0, 0, numPixels); - gd.Colorize(pixelptr, 0, numPixels); + bool mode7 = bgnum == 1; + bool mode7extbg = (bgnum == 2 && si.SETINI_Mode7ExtBG); + if(mode7 || mode7extbg) + { + handled = true; + allocate(1024, 1024); + gd.DecodeMode7BG(pixelptr, stride / 4, mode7extbg); + int numPixels = 128 * 128 * 8 * 8; + gd.Paletteize(pixelptr, 0, 0, numPixels); + gd.Colorize(pixelptr, 0, numPixels); + } } else { + handled = true; var dims = bg.ScreenSizeInPixels; dims.Height = dims.Width = Math.Max(dims.Width, dims.Height); allocate(dims.Width, dims.Height); @@ -419,5 +441,7 @@ namespace BizHawk.MultiClient { SyncViewerSize(); } + + } } diff --git a/BizHawk.MultiClient/output/libsneshawk.dll b/BizHawk.MultiClient/output/libsneshawk.dll index 07a20ab094..732824b013 100644 Binary files a/BizHawk.MultiClient/output/libsneshawk.dll and b/BizHawk.MultiClient/output/libsneshawk.dll differ diff --git a/libsnes/bsnes/target-libsnes/libsnes.cpp b/libsnes/bsnes/target-libsnes/libsnes.cpp index 53fe31d37e..01d8549225 100644 --- a/libsnes/bsnes/target-libsnes/libsnes.cpp +++ b/libsnes/bsnes/target-libsnes/libsnes.cpp @@ -310,6 +310,12 @@ int snes_peek_logical_register(int reg) //$210C case SNES_REG_BG3_TDADDR: return SNES::ppu.regs.bg_tdaddr[SNES::PPU::BG3]>>13; case SNES_REG_BG4_TDADDR: return SNES::ppu.regs.bg_tdaddr[SNES::PPU::BG4]>>13; + + case SNES_REG_SETINI_MODE7_EXTBG: return SNES::ppu.regs.mode7_extbg?1:0; + case SNES_REG_SETINI_HIRES: return SNES::ppu.regs.pseudo_hires?1:0; + case SNES_REG_SETINI_OVERSCAN: return SNES::ppu.regs.overscan?1:0; + case SNES_REG_SETINI_OBJ_INTERLACE: return SNES::ppu.regs.oam_interlace?1:0; + case SNES_REG_SETINI_SCREEN_INTERLACE: return SNES::ppu.regs.interlace?1:0; } return 0; } diff --git a/libsnes/bsnes/target-libsnes/libsnes.hpp b/libsnes/bsnes/target-libsnes/libsnes.hpp index ba455b1744..cd56b3787d 100644 --- a/libsnes/bsnes/target-libsnes/libsnes.hpp +++ b/libsnes/bsnes/target-libsnes/libsnes.hpp @@ -161,6 +161,12 @@ void snes_set_scanlineStart(snes_scanlineStart_t); //$210C #define SNES_REG_BG3_TDADDR 22 #define SNES_REG_BG4_TDADDR 23 +//$2133 SETINI +#define SNES_REG_SETINI_MODE7_EXTBG 30 +#define SNES_REG_SETINI_HIRES 31 +#define SNES_REG_SETINI_OVERSCAN 32 +#define SNES_REG_SETINI_OBJ_INTERLACE 33 +#define SNES_REG_SETINI_SCREEN_INTERLACE 34 int snes_peek_logical_register(int reg);