1 using Mesen.GUI.Config; 2 using Mesen.GUI.Controls; 3 using System; 4 using System.Collections.Generic; 5 using System.Drawing; 6 using System.Drawing.Drawing2D; 7 using System.Drawing.Imaging; 8 using System.Linq; 9 using System.Runtime.InteropServices; 10 using System.Text; 11 using System.Threading.Tasks; 12 13 namespace Mesen.GUI.Debugger 14 { 15 public class PpuViewerHelper 16 { 17 private static Font _font = new Font(BaseControl.MonospaceFontFamily, 10); 18 DrawPalettePreview(int paletteIndex, Graphics g)19 public static void DrawPalettePreview(int paletteIndex, Graphics g) 20 { 21 int[] palette = InteropEmu.DebugGetPalette(); 22 GCHandle handle = GCHandle.Alloc(palette, GCHandleType.Pinned); 23 Bitmap source = new Bitmap(4, 1, 4 * 4, PixelFormat.Format32bppPArgb, handle.AddrOfPinnedObject() + paletteIndex * 16); 24 25 g.InterpolationMode = InterpolationMode.NearestNeighbor; 26 g.SmoothingMode = SmoothingMode.None; 27 g.PixelOffsetMode = PixelOffsetMode.Half; 28 29 Matrix transform = g.Transform; 30 g.ScaleTransform(16, 16); 31 g.DrawImageUnscaled(source, 0, 0); 32 33 g.Transform = transform; 34 g.DrawRectangle(Pens.White, 1, 1, 63, 15); 35 } 36 DrawOverlayTooltip(Image dest, string tooltipText, Image tilePreview, int paletteIndex, bool topRightAnchor, Graphics g)37 public static void DrawOverlayTooltip(Image dest, string tooltipText, Image tilePreview, int paletteIndex, bool topRightAnchor, Graphics g) 38 { 39 40 int palettePreviewHeight = paletteIndex >= 0 ? 16 : 0; 41 SizeF requiredSize = g.MeasureString(tooltipText, _font); 42 requiredSize = new SizeF(requiredSize.Width + tilePreview.Width + 13, Math.Max(requiredSize.Height, tilePreview.Height + 10 + palettePreviewHeight)); 43 44 if(topRightAnchor) { 45 g.TranslateTransform(dest.Width - requiredSize.Width - 5, 5); 46 } else { 47 g.TranslateTransform(dest.Width - requiredSize.Width - 5, dest.Height - requiredSize.Height - 5); 48 } 49 50 using(SolidBrush brush = new SolidBrush(Color.FromArgb(180, 0, 0, 0))) { 51 g.FillRectangle(brush, 0, 0, requiredSize.Width, requiredSize.Height); 52 } 53 g.DrawRectangle(Pens.White, 0, 0, requiredSize.Width, requiredSize.Height); 54 g.DrawString(tooltipText, _font, Brushes.White, 5, 5, StringFormat.GenericTypographic); 55 g.DrawImage(tilePreview, requiredSize.Width - tilePreview.Width - 3, 5); 56 g.DrawRectangle(Pens.White, requiredSize.Width - tilePreview.Width - 3, 5, tilePreview.Width - 1, tilePreview.Height - 1); 57 58 if(paletteIndex >= 0) { 59 g.TranslateTransform(requiredSize.Width - tilePreview.Width - 3, tilePreview.Height + 7); 60 PpuViewerHelper.DrawPalettePreview(paletteIndex, g); 61 } 62 } 63 GetPreview(Point originalPos, Size originalSize, int scale, Image source)64 public static Bitmap GetPreview(Point originalPos, Size originalSize, int scale, Image source) 65 { 66 Bitmap tile = new Bitmap(originalSize.Width * scale, originalSize.Height * scale, PixelFormat.Format32bppPArgb); 67 Bitmap tilePreview = new Bitmap(originalSize.Width, originalSize.Height, PixelFormat.Format32bppPArgb); 68 using(Graphics g = Graphics.FromImage(tilePreview)) { 69 g.DrawImage(source, 0, 0, new Rectangle(originalPos.X, originalPos.Y, originalSize.Width, originalSize.Height), GraphicsUnit.Pixel); 70 } 71 using(Graphics g = Graphics.FromImage(tile)) { 72 g.InterpolationMode = InterpolationMode.NearestNeighbor; 73 g.SmoothingMode = SmoothingMode.None; 74 g.PixelOffsetMode = PixelOffsetMode.Half; 75 g.ScaleTransform(scale, scale); 76 g.DrawImageUnscaled(tilePreview, 0, 0); 77 } 78 return tile; 79 } 80 } 81 } 82