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