252 lines
5.6 KiB
C#
252 lines
5.6 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.PCEngine;
|
|
using System.Drawing.Imaging;
|
|
using BizHawk.Emulation.Common;
|
|
|
|
namespace BizHawk.Client.EmuHawk
|
|
{
|
|
public partial class PCETileViewer : Form, IToolFormAutoConfig
|
|
{
|
|
[RequiredService]
|
|
public PCEngine emu { get; private set; }
|
|
|
|
private VDC vdc;
|
|
private VCE vce;
|
|
|
|
private int bgpalnum;
|
|
private int sppalnum;
|
|
|
|
public PCETileViewer()
|
|
{
|
|
InitializeComponent();
|
|
bmpViewBG.ChangeBitmapSize(512, 256);
|
|
bmpViewSP.ChangeBitmapSize(512, 256);
|
|
bmpViewBGPal.ChangeBitmapSize(256, 256);
|
|
bmpViewSPPal.ChangeBitmapSize(256, 256);
|
|
}
|
|
|
|
#region IToolForm
|
|
|
|
public void UpdateValues()
|
|
{
|
|
DrawBacks();
|
|
DrawSprites();
|
|
DrawPalettes();
|
|
bmpViewBG.Refresh();
|
|
bmpViewBGPal.Refresh();
|
|
bmpViewSP.Refresh();
|
|
bmpViewSPPal.Refresh();
|
|
}
|
|
|
|
public void FastUpdate()
|
|
{
|
|
// Do nothing
|
|
}
|
|
|
|
unsafe static void Draw16x16(byte* src, int* dest, int pitch, int* pal)
|
|
{
|
|
int inc = pitch - 16;
|
|
dest -= inc;
|
|
for (int i = 0; i < 256; i++)
|
|
{
|
|
if ((i & 15) == 0)
|
|
dest += inc;
|
|
*dest++ = pal[*src++];
|
|
}
|
|
}
|
|
|
|
unsafe static void Draw8x8(byte* src, int* dest, int pitch, int* pal)
|
|
{
|
|
int inc = pitch - 8;
|
|
dest -= inc;
|
|
for (int i = 0; i < 64; i++)
|
|
{
|
|
if ((i & 7) == 0)
|
|
dest += inc;
|
|
*dest++ = pal[*src++];
|
|
}
|
|
}
|
|
|
|
unsafe void DrawSprites()
|
|
{
|
|
var lockdata = bmpViewSP.bmp.LockBits(new Rectangle(0, 0, 512, 256), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
|
|
|
|
int* dest = (int*)lockdata.Scan0;
|
|
int pitch = lockdata.Stride / sizeof(int);
|
|
fixed (byte* src = vdc.SpriteBuffer)
|
|
fixed (int* pal = &vce.Palette[256 + sppalnum * 16])
|
|
{
|
|
for (int tile = 0; tile < 512; tile++)
|
|
{
|
|
int srcaddr = tile * 256;
|
|
int tx = tile & 31;
|
|
int ty = tile >> 5;
|
|
int destaddr = ty * 16 * pitch + tx * 16;
|
|
Draw16x16(src + srcaddr, dest + destaddr, pitch, pal);
|
|
}
|
|
}
|
|
bmpViewSP.bmp.UnlockBits(lockdata);
|
|
}
|
|
|
|
unsafe void DrawBacks()
|
|
{
|
|
var lockdata = bmpViewBG.bmp.LockBits(new Rectangle(0, 0, 512, 256), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
|
|
|
|
int* dest = (int*)lockdata.Scan0;
|
|
int pitch = lockdata.Stride / sizeof(int);
|
|
fixed (byte* src = vdc.PatternBuffer)
|
|
fixed (int* pal = &vce.Palette[0 + bgpalnum * 16])
|
|
{
|
|
for (int tile = 0; tile < 2048; tile++)
|
|
{
|
|
int srcaddr = tile * 64;
|
|
int tx = tile & 63;
|
|
int ty = tile >> 6;
|
|
int destaddr = ty * 8 * pitch + tx * 8;
|
|
Draw8x8(src + srcaddr, dest + destaddr, pitch, pal);
|
|
}
|
|
}
|
|
bmpViewBG.bmp.UnlockBits(lockdata);
|
|
}
|
|
|
|
unsafe void DrawPalettes()
|
|
{
|
|
fixed (int* pal = vce.Palette)
|
|
{
|
|
DrawPalette(bmpViewBGPal.bmp, pal);
|
|
DrawPalette(bmpViewSPPal.bmp, pal + 256);
|
|
}
|
|
}
|
|
|
|
unsafe static void DrawPalette(Bitmap bmp, int* pal)
|
|
{
|
|
var lockdata = bmp.LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
|
|
|
|
int* dest = (int*)lockdata.Scan0;
|
|
int pitch = lockdata.Stride / sizeof(int);
|
|
int inc = pitch - 256;
|
|
for (int j = 0; j < 256; j++)
|
|
{
|
|
for (int i = 0; i < 256; i++)
|
|
{
|
|
int pindex = j & 0xf0 | i >> 4;
|
|
*dest++ = pal[pindex];
|
|
}
|
|
dest += inc;
|
|
}
|
|
bmp.UnlockBits(lockdata);
|
|
}
|
|
|
|
public void Restart()
|
|
{
|
|
vce = emu.VCE;
|
|
|
|
if (emu.SystemId == "SGX")
|
|
{
|
|
checkBoxVDC2.Enabled = true;
|
|
}
|
|
else
|
|
{
|
|
checkBoxVDC2.Enabled = false;
|
|
checkBoxVDC2.Checked = false;
|
|
}
|
|
checkBoxVDC2_CheckedChanged(null, null);
|
|
}
|
|
|
|
public bool AskSaveChanges()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
public bool UpdateBefore
|
|
{
|
|
get { return true; }
|
|
}
|
|
|
|
#endregion
|
|
|
|
private void checkBoxVDC2_CheckedChanged(object sender, EventArgs e)
|
|
{
|
|
vdc = checkBoxVDC2.Checked ? emu.VDC2 : emu.VDC1;
|
|
UpdateValues();
|
|
}
|
|
|
|
private void bmpViewBGPal_MouseClick(object sender, MouseEventArgs e)
|
|
{
|
|
int p = Math.Min(Math.Max(e.Y / 16, 0), 15);
|
|
bgpalnum = p;
|
|
DrawBacks();
|
|
bmpViewBG.Refresh();
|
|
}
|
|
|
|
private void bmpViewSPPal_MouseClick(object sender, MouseEventArgs e)
|
|
{
|
|
int p = Math.Min(Math.Max(e.Y / 16, 0), 15);
|
|
sppalnum = p;
|
|
DrawSprites();
|
|
bmpViewSP.Refresh();
|
|
}
|
|
|
|
private void PCETileViewer_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 closeToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
Close();
|
|
}
|
|
|
|
private void saveBackgroundScreenshotToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
bmpViewBG.SaveFile();
|
|
}
|
|
|
|
private void saveSpriteScreenshotToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
bmpViewSP.SaveFile();
|
|
}
|
|
|
|
private void PCETileViewer_Load(object sender, EventArgs e)
|
|
{
|
|
vce = emu.VCE;
|
|
}
|
|
|
|
private void RefreshFloatingWindowControl()
|
|
{
|
|
}
|
|
|
|
protected override void OnShown(EventArgs e)
|
|
{
|
|
RefreshFloatingWindowControl();
|
|
base.OnShown(e);
|
|
}
|
|
}
|
|
}
|