diff --git a/BizHawk.Emulation/Consoles/Nintendo/SNES/SNESGraphicsDecoder.cs b/BizHawk.Emulation/Consoles/Nintendo/SNES/SNESGraphicsDecoder.cs index 208f97554c..968c26137a 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/SNES/SNESGraphicsDecoder.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/SNES/SNESGraphicsDecoder.cs @@ -530,6 +530,15 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES } } + //not being used.. do we need it? + public int[] GetCachedTile(int bpp, int tilenum) + { + int[] ret = new int[8 * 8]; + int idx = tilenum * 64; + for (int i = 0; i < 64; i++) + ret[i] = _tileCache[bpp][idx + i]; + return ret; + } void CacheTilesMode7ExtBg() { @@ -618,16 +627,18 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES /// we might need 16x16 unscrambling and some other perks here eventually. /// provide a start color to use as the basis for the palette /// - public void RenderTilesToScreen(int* screen, int tilesWide, int tilesTall, int stride, int bpp, int startcolor) + public void RenderTilesToScreen(int* screen, int tilesWide, int tilesTall, int stride, int bpp, int startcolor, int startTile = 0, int numTiles = -1) { - int numTiles = 8192 / bpp; + if(numTiles == -1) + numTiles = 8192 / bpp; int[] tilebuf = _tileCache[bpp]; for (int i = 0; i < numTiles; i++) { + int tnum = startTile + i; int ty = i / tilesWide; int tx = i % tilesWide; int dstOfs = (ty * 8) * stride + tx * 8; - int srcOfs = i * 64; + int srcOfs = tnum * 64; for (int y = 0,p=0; y < 8; y++) for (int x = 0; x < 8; x++,p++) { diff --git a/BizHawk.MultiClient/SNESTools/SNESGraphicsDebugger.Designer.cs b/BizHawk.MultiClient/SNESTools/SNESGraphicsDebugger.Designer.cs index 1ca7167ba4..ea8b8a7318 100644 --- a/BizHawk.MultiClient/SNESTools/SNESGraphicsDebugger.Designer.cs +++ b/BizHawk.MultiClient/SNESTools/SNESGraphicsDebugger.Designer.cs @@ -131,6 +131,7 @@ this.radioButton5 = new System.Windows.Forms.RadioButton(); this.radioButton10 = new System.Windows.Forms.RadioButton(); this.groupBox5 = new System.Windows.Forms.GroupBox(); + this.paletteViewer = new BizHawk.MultiClient.SNESGraphicsViewer(); this.tabctrlDetails = new System.Windows.Forms.TabControl(); this.tpPalette = new System.Windows.Forms.TabPage(); this.txtPaletteDetailsIndexSpecific = new System.Windows.Forms.TextBox(); @@ -144,11 +145,11 @@ this.lblDetailsOBJOrBG = new System.Windows.Forms.Label(); this.pnDetailsPaletteColor = new System.Windows.Forms.Panel(); this.lblDetailsPaletteAddress = new System.Windows.Forms.Label(); - this.tabPage2 = new System.Windows.Forms.TabPage(); + this.tpTile = new System.Windows.Forms.TabPage(); this.viewerPanel = new System.Windows.Forms.Panel(); - this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); - this.paletteViewer = new BizHawk.MultiClient.SNESGraphicsViewer(); this.viewer = new BizHawk.MultiClient.SNESGraphicsViewer(); + this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); + this.viewerTile = new BizHawk.MultiClient.SNESGraphicsViewer(); this.menuStrip1.SuspendLayout(); this.tableLayoutPanel1.SuspendLayout(); this.panel1.SuspendLayout(); @@ -162,6 +163,7 @@ this.groupBox5.SuspendLayout(); this.tabctrlDetails.SuspendLayout(); this.tpPalette.SuspendLayout(); + this.tpTile.SuspendLayout(); this.viewerPanel.SuspendLayout(); this.SuspendLayout(); // @@ -1292,10 +1294,21 @@ this.groupBox5.TabStop = false; this.groupBox5.Text = "Palette"; // + // paletteViewer + // + this.paletteViewer.BackColor = System.Drawing.Color.Transparent; + this.paletteViewer.Location = new System.Drawing.Point(6, 14); + this.paletteViewer.Name = "paletteViewer"; + this.paletteViewer.Size = new System.Drawing.Size(307, 307); + this.paletteViewer.TabIndex = 18; + this.paletteViewer.TabStop = false; + this.paletteViewer.MouseClick += new System.Windows.Forms.MouseEventHandler(this.paletteViewer_MouseClick); + this.paletteViewer.MouseMove += new System.Windows.Forms.MouseEventHandler(this.paletteViewer_MouseMove); + // // tabctrlDetails // this.tabctrlDetails.Controls.Add(this.tpPalette); - this.tabctrlDetails.Controls.Add(this.tabPage2); + this.tabctrlDetails.Controls.Add(this.tpTile); this.tabctrlDetails.Location = new System.Drawing.Point(236, 193); this.tabctrlDetails.Name = "tabctrlDetails"; this.tabctrlDetails.SelectedIndex = 0; @@ -1431,15 +1444,16 @@ this.lblDetailsPaletteAddress.TabIndex = 1; this.lblDetailsPaletteAddress.Text = "CGRAM Address "; // - // tabPage2 + // tpTile // - this.tabPage2.Location = new System.Drawing.Point(4, 22); - this.tabPage2.Name = "tabPage2"; - this.tabPage2.Padding = new System.Windows.Forms.Padding(3); - this.tabPage2.Size = new System.Drawing.Size(309, 121); - this.tabPage2.TabIndex = 1; - this.tabPage2.Text = "tabPage2"; - this.tabPage2.UseVisualStyleBackColor = true; + this.tpTile.Controls.Add(this.viewerTile); + this.tpTile.Location = new System.Drawing.Point(4, 22); + this.tpTile.Name = "tpTile"; + this.tpTile.Padding = new System.Windows.Forms.Padding(3); + this.tpTile.Size = new System.Drawing.Size(309, 121); + this.tpTile.TabIndex = 1; + this.tpTile.Text = "Tile"; + this.tpTile.UseVisualStyleBackColor = true; // // viewerPanel // @@ -1453,26 +1467,6 @@ this.viewerPanel.Size = new System.Drawing.Size(516, 667); this.viewerPanel.TabIndex = 1; // - // toolTip1 - // - this.toolTip1.AutoPopDelay = 5000; - this.toolTip1.InitialDelay = 250; - this.toolTip1.ReshowDelay = 100; - // - // paletteViewer - // - this.paletteViewer.BackColor = System.Drawing.Color.Transparent; - this.paletteViewer.Location = new System.Drawing.Point(6, 14); - this.paletteViewer.Name = "paletteViewer"; - this.paletteViewer.Size = new System.Drawing.Size(307, 307); - this.paletteViewer.TabIndex = 18; - this.paletteViewer.TabStop = false; - this.paletteViewer.MouseClick += new System.Windows.Forms.MouseEventHandler(this.paletteViewer_MouseClick); - this.paletteViewer.MouseDown += new System.Windows.Forms.MouseEventHandler(this.paletteViewer_MouseDown); - this.paletteViewer.MouseEnter += new System.EventHandler(this.paletteViewer_MouseEnter); - this.paletteViewer.MouseLeave += new System.EventHandler(this.paletteViewer_MouseLeave); - this.paletteViewer.MouseMove += new System.Windows.Forms.MouseEventHandler(this.paletteViewer_MouseMove); - // // viewer // this.viewer.BackColor = System.Drawing.Color.Transparent; @@ -1485,6 +1479,21 @@ this.viewer.MouseMove += new System.Windows.Forms.MouseEventHandler(this.viewer_MouseMove); this.viewer.MouseUp += new System.Windows.Forms.MouseEventHandler(this.viewer_MouseUp); // + // toolTip1 + // + this.toolTip1.AutoPopDelay = 5000; + this.toolTip1.InitialDelay = 250; + this.toolTip1.ReshowDelay = 100; + // + // viewerTile + // + this.viewerTile.BackColor = System.Drawing.Color.Transparent; + this.viewerTile.Location = new System.Drawing.Point(6, 6); + this.viewerTile.Name = "viewerTile"; + this.viewerTile.Size = new System.Drawing.Size(64, 64); + this.viewerTile.TabIndex = 19; + this.viewerTile.TabStop = false; + // // SNESGraphicsDebugger // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -1517,6 +1526,7 @@ this.tabctrlDetails.ResumeLayout(false); this.tpPalette.ResumeLayout(false); this.tpPalette.PerformLayout(); + this.tpTile.ResumeLayout(false); this.viewerPanel.ResumeLayout(false); this.ResumeLayout(false); this.PerformLayout(); @@ -1614,7 +1624,7 @@ private System.Windows.Forms.Label lblDetailsOBJOrBG; private System.Windows.Forms.Panel pnDetailsPaletteColor; private System.Windows.Forms.Label lblDetailsPaletteAddress; - private System.Windows.Forms.TabPage tabPage2; + private System.Windows.Forms.TabPage tpTile; private System.Windows.Forms.Panel viewerPanel; private SNESGraphicsViewer viewer; private System.Windows.Forms.GroupBox groupBox3; @@ -1644,5 +1654,6 @@ private System.Windows.Forms.Label label23; private System.Windows.Forms.Label label27; private System.Windows.Forms.CheckBox checkScreenCGWSEL_DirectColor; + private SNESGraphicsViewer viewerTile; } } \ No newline at end of file diff --git a/BizHawk.MultiClient/SNESTools/SNESGraphicsDebugger.cs b/BizHawk.MultiClient/SNESTools/SNESGraphicsDebugger.cs index 4549d97260..0351aa3550 100644 --- a/BizHawk.MultiClient/SNESTools/SNESGraphicsDebugger.cs +++ b/BizHawk.MultiClient/SNESTools/SNESGraphicsDebugger.cs @@ -26,6 +26,8 @@ namespace BizHawk.MultiClient { InitializeComponent(); Closing += (o, e) => SaveConfigSettings(); + viewerTile.ScaleImage = true; + viewer.ScaleImage = false; var displayTypeItems = new List(); displayTypeItems.Add(new DisplayTypeItem("BG1", eDisplayType.BG1)); @@ -81,12 +83,17 @@ namespace BizHawk.MultiClient public void UpdateToolsAfter() { SyncCore(); - if (!checkScanlineControl.Checked) UpdateValues(); + if (!checkScanlineControl.Checked) + { + RegenerateData(); + UpdateValues(); + } } public void UpdateToolsLoadstate() { SyncCore(); + RegenerateData(); UpdateValues(); } @@ -129,7 +136,23 @@ namespace BizHawk.MultiClient void ScanlineHook(int line) { int target = (int)nudScanline.Value; - if (target == line) UpdateValues(); + if (target == line) + { + RegenerateData(); + UpdateValues(); + } + } + + SNESGraphicsDecoder gd = new SNESGraphicsDecoder(); + SNESGraphicsDecoder.ScreenInfo si; + + void RegenerateData() + { + gd = null; + if (currentSnesCore == null) return; + gd = new SNESGraphicsDecoder(); + gd.CacheTiles(); + si = gd.ScanScreenInfo(); } void UpdateValues() @@ -137,9 +160,6 @@ namespace BizHawk.MultiClient if (!this.IsHandleCreated || this.IsDisposed) return; if (currentSnesCore == null) return; - var gd = new SNESGraphicsDecoder(); - var si = gd.ScanScreenInfo(); - checkScreenExtbg.Checked = si.SETINI_Mode7ExtBG; checkScreenHires.Checked = si.SETINI_HiRes; checkScreenOverscan.Checked = si.SETINI_Overscan; @@ -183,6 +203,7 @@ namespace BizHawk.MultiClient SyncColorSelection(); RenderView(); RenderPalette(); + RenderTileView(); UpdateColorDetails(); } @@ -204,8 +225,6 @@ namespace BizHawk.MultiClient stride = bmpdata.Stride; }; - var gd = new SNESGraphicsDecoder(); - gd.CacheTiles(); var selection = CurrDisplaySelection; if (selection == eDisplayType.Tiles2bpp) { @@ -313,6 +332,7 @@ namespace BizHawk.MultiClient private void comboDisplayType_SelectedIndexChanged(object sender, EventArgs e) { UpdateValues(); + //change the bg props viewer to match if (IsDisplayTypeBG(CurrDisplaySelection)) comboBGProps.SelectedIndex = DisplayTypeBGNum(CurrDisplaySelection) - 1; @@ -524,21 +544,6 @@ namespace BizHawk.MultiClient } - private void paletteViewer_MouseDown(object sender, MouseEventArgs e) - { - - } - - private void paletteViewer_MouseEnter(object sender, EventArgs e) - { - tabctrlDetails.SelectedIndex = 0; - } - - private void paletteViewer_MouseLeave(object sender, EventArgs e) - { - ClearDetails(); - } - bool TranslatePaletteCoord(Point pt, out Point outpoint) { pt.X -= paletteCellSpacing; @@ -550,15 +555,6 @@ namespace BizHawk.MultiClient return true; } - private void paletteViewer_MouseMove(object sender, MouseEventArgs e) - { - Point pt; - bool valid = TranslatePaletteCoord(e.Location, out pt); - if (!valid) return; - lastColorNum = pt.Y * 16 + pt.X; - UpdateColorDetails(); - } - private void paletteViewer_MouseClick(object sender, MouseEventArgs e) { Point pt; @@ -641,8 +637,80 @@ namespace BizHawk.MultiClient y += dy; viewerPanel.AutoScrollPosition = new Point(-x, -y); } + else + { + UpdateViewerMouseover(e.Location); + } } + int currViewingTile = -1; + int currViewingTileBpp = -1; + void RenderTileView(bool force=false) + { + bool valid = currViewingTile != -1; + if (!valid && !force) return; + + int bpp = currViewingTileBpp; + + var bmp = new Bitmap(8, 8, System.Drawing.Imaging.PixelFormat.Format32bppArgb); + var bmpdata = bmp.LockBits(new Rectangle(0, 0, 8, 8), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); + if(valid) gd.RenderTilesToScreen((int*)bmpdata.Scan0, 1, 1, bmpdata.Stride / 4, bpp, currPaletteSelection.start, currViewingTile, 1); + bmp.UnlockBits(bmpdata); + viewerTile.SetBitmap(bmp); + } + + void UpdateViewerMouseover(Point loc) + { + currViewingTile = -1; + currViewingTileBpp = -1; + int tx = loc.X / 8; + int ty = loc.Y / 8; + switch (CurrDisplaySelection) + { + case eDisplayType.Tiles4bpp: + currViewingTileBpp = 4; + currViewingTile = ty * 64 + tx; + if (currViewingTile < 0 || currViewingTile >= (8192 / currViewingTileBpp)) + currViewingTile = -1; + break; + } + + RenderTileView(true); + } + + private void viewer_MouseEnter(object sender, EventArgs e) + { + tabctrlDetails.SelectedIndex = 1; + } + + private void viewer_MouseLeave(object sender, EventArgs e) + { + ClearDetails(); + } + + private void paletteViewer_MouseDown(object sender, MouseEventArgs e) + { + + } + + private void paletteViewer_MouseEnter(object sender, EventArgs e) + { + tabctrlDetails.SelectedIndex = 0; + } + + private void paletteViewer_MouseLeave(object sender, EventArgs e) + { + ClearDetails(); + } + + private void paletteViewer_MouseMove(object sender, MouseEventArgs e) + { + Point pt; + bool valid = TranslatePaletteCoord(e.Location, out pt); + if (!valid) return; + lastColorNum = pt.Y * 16 + pt.X; + UpdateColorDetails(); + } } diff --git a/BizHawk.MultiClient/SNESTools/SNESGraphicsViewer.cs b/BizHawk.MultiClient/SNESTools/SNESGraphicsViewer.cs index 000db7866a..0aca1fce3f 100644 --- a/BizHawk.MultiClient/SNESTools/SNESGraphicsViewer.cs +++ b/BizHawk.MultiClient/SNESTools/SNESGraphicsViewer.cs @@ -21,15 +21,9 @@ namespace BizHawk.MultiClient protected override void OnPaint(PaintEventArgs e) { - Display(e.Graphics); base.OnPaint(e); } - void Display(Graphics g) - { - g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor; - g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half; - } //todo - screenshot? diff --git a/BizHawk.Util/ViewportPanel.cs b/BizHawk.Util/ViewportPanel.cs index f9768868d8..12e47dcbac 100644 --- a/BizHawk.Util/ViewportPanel.cs +++ b/BizHawk.Util/ViewportPanel.cs @@ -31,13 +31,13 @@ namespace BizHawk.Core threadPaint.Start(); } - public RetainedViewportPanel() + public RetainedViewportPanel(bool doubleBuffer = false) { CreateHandle(); SetStyle(ControlStyles.AllPaintingInWmPaint, true); SetStyle(ControlStyles.UserPaint, true); - SetStyle(ControlStyles.DoubleBuffer, false); + SetStyle(ControlStyles.DoubleBuffer, doubleBuffer); SetStyle(ControlStyles.Opaque, true); SetStyle(ControlStyles.UserMouse, true); @@ -57,6 +57,8 @@ namespace BizHawk.Core CleanupDisposeQueue(); } + public bool ScaleImage = true; + void DoPaint() { if (bmp != null) @@ -67,7 +69,21 @@ namespace BizHawk.Core g.InterpolationMode = InterpolationMode.NearestNeighbor; g.CompositingMode = CompositingMode.SourceCopy; g.CompositingQuality = CompositingQuality.HighSpeed; - g.DrawImage(bmp, 0, 0, Width, Height); + if (ScaleImage) + { + g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor; + g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half; + g.DrawImage(bmp, 0, 0, Width, Height); + } + else + { + using (var sb = new SolidBrush(Color.Black)) + { + g.FillRectangle(sb, bmp.Width, 0, Width - bmp.Width, Height); + g.FillRectangle(sb, 0, bmp.Height, bmp.Width, Height - bmp.Height); + } + g.DrawImageUnscaled(bmp, 0, 0); + } } }