BizHawk/BizHawk.Client.EmuHawk/tools/Genesis/VDPViewer.cs

222 lines
5.4 KiB
C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using BizHawk.Client.Common;
using BizHawk.Emulation.Cores.Consoles.Sega.gpgx;
using System.Drawing.Imaging;
using BizHawk.Emulation.Common;
namespace BizHawk.Client.EmuHawk
{
public partial class GenVDPViewer : Form, IToolFormAutoConfig
{
[RequiredService]
private GPGX Emu { get; set; }
private LibGPGX.VDPView View = new LibGPGX.VDPView();
int palindex = 0;
public GenVDPViewer()
{
InitializeComponent();
bmpViewTiles.ChangeBitmapSize(512, 256);
bmpViewPal.ChangeBitmapSize(16, 4);
}
unsafe static void DrawTile(int* dest, int pitch, byte* src, int* pal)
{
for (int j = 0; j < 8; j++)
{
*dest++ = pal[*src++];
*dest++ = pal[*src++];
*dest++ = pal[*src++];
*dest++ = pal[*src++];
*dest++ = pal[*src++];
*dest++ = pal[*src++];
*dest++ = pal[*src++];
*dest++ = pal[*src++];
dest += pitch - 8;
}
}
unsafe static void DrawNameTable(LibGPGX.VDPNameTable NT, ushort* vram, byte* tiles, int* pal, BmpView bv)
{
ushort* nametable = vram + NT.Baseaddr / 2;
int tilew = NT.Width;
int tileh = NT.Height;
Size pixsize = new Size(tilew * 8, tileh * 8);
bv.Size = pixsize;
bv.ChangeBitmapSize(pixsize);
var lockdata = bv.bmp.LockBits(new Rectangle(Point.Empty, pixsize), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
int pitch = lockdata.Stride / sizeof(int);
int* dest = (int*)lockdata.Scan0;
for (int tiley = 0; tiley < tileh; tiley++)
{
for (int tilex = 0; tilex < tilew; tilex++)
{
ushort bgent = *nametable++;
int palidx = bgent >> 9 & 0x30;
int tileent = bgent & 0x1fff; // h and v flip are stored separately in cache
DrawTile(dest, pitch, tiles + tileent * 64, pal + palidx);
dest += 8;
}
dest -= 8 * tilew;
dest += 8 * pitch;
}
bv.bmp.UnlockBits(lockdata);
bv.Refresh();
}
unsafe void DrawPalettes(int *pal)
{
var lockdata = bmpViewPal.bmp.LockBits(new Rectangle(0, 0, 16, 4), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
int pitch = lockdata.Stride / sizeof(int);
int* dest = (int*)lockdata.Scan0;
for (int j = 0; j < 4; j++)
{
for (int i = 0; i < 16; i++)
*dest++ = *pal++;
dest += pitch - 16;
}
bmpViewPal.bmp.UnlockBits(lockdata);
bmpViewPal.Refresh();
}
unsafe void DrawTiles()
{
var lockdata = bmpViewTiles.bmp.LockBits(new Rectangle(0, 0, 512, 256), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
int pitch = lockdata.Stride / sizeof(int);
int* dest = (int*)lockdata.Scan0;
byte* src = (byte*)View.PatternCache;
int* pal = 0x10 * palindex + (int*)View.ColorCache;
for (int tile = 0; tile < 2048;)
{
DrawTile(dest, pitch, src, pal);
dest += 8;
src += 64;
tile++;
if ((tile & 63) == 0)
dest += 8 * pitch - 512;
}
bmpViewTiles.bmp.UnlockBits(lockdata);
bmpViewTiles.Refresh();
}
public void UpdateValues()
{
if (Emu == null)
return;
Emu.UpdateVDPViewContext(View);
unsafe
{
int* pal = (int*)View.ColorCache;
//for (int i = 0; i < 0x40; i++)
// pal[i] |= unchecked((int)0xff000000);
DrawPalettes(pal);
DrawTiles();
ushort *VRAMNT = (ushort*)View.VRAM;
byte *tiles = (byte*)View.PatternCache;
DrawNameTable(View.NTA, VRAMNT, tiles, pal, bmpViewNTA);
DrawNameTable(View.NTB, VRAMNT, tiles, pal, bmpViewNTB);
DrawNameTable(View.NTW, VRAMNT, tiles, pal, bmpViewNTW);
}
}
public void FastUpdate()
{
// Do nothing
}
public void Restart()
{
UpdateValues();
}
public bool AskSaveChanges()
{
return true;
}
public bool UpdateBefore
{
get { return true; }
}
private void bmpViewPal_MouseClick(object sender, MouseEventArgs e)
{
int idx = e.Y / 16;
idx = Math.Min(3, Math.Max(idx, 0));
palindex = idx;
DrawTiles();
}
private void VDPViewer_KeyDown(object sender, KeyEventArgs e)
{
if (ModifierKeys.HasFlag(Keys.Control) && e.KeyCode == Keys.C)
{
// find the control under the mouse
Point m = Cursor.Position;
Control top = this;
Control found;
do
{
found = top.GetChildAtPoint(top.PointToClient(m));
top = found;
} while (found != null && found.HasChildren);
if (found is BmpView)
{
var bv = found as BmpView;
Clipboard.SetImage(bv.bmp);
}
}
}
private void saveBGAScreenshotToolStripMenuItem_Click(object sender, EventArgs e)
{
bmpViewNTA.SaveFile();
}
private void saveBGBScreenshotToolStripMenuItem_Click(object sender, EventArgs e)
{
bmpViewNTB.SaveFile();
}
private void saveTilesScreenshotToolStripMenuItem_Click(object sender, EventArgs e)
{
bmpViewTiles.SaveFile();
}
private void saveWindowScreenshotToolStripMenuItem_Click(object sender, EventArgs e)
{
bmpViewNTW.SaveFile();
}
private void savePaletteScreenshotToolStripMenuItem_Click(object sender, EventArgs e)
{
bmpViewPal.SaveFile();
}
private void closeToolStripMenuItem_Click(object sender, EventArgs e)
{
Close();
}
private void GenVDPViewer_Load(object sender, EventArgs e)
{
}
}
}