BizHawk/BizHawk.Client.EmuHawk/tools/PCE/PCEBGViewer.cs

168 lines
3.5 KiB
C#

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;
using BizHawk.Client.Common;
using BizHawk.Emulation.Cores.PCEngine;
using BizHawk.Emulation.Common;
namespace BizHawk.Client.EmuHawk
{
public partial class PceBgViewer : Form, IToolFormAutoConfig
{
[RequiredService]
private PCEngine _pce { get; set; }
[ConfigPersist]
private int RefreshRateConfig
{
get
{
return RefreshRate.Value;
}
set
{
RefreshRate.Value = Math.Max(Math.Min(value, RefreshRate.Maximum), RefreshRate.Minimum);
}
}
private int _vdcType;
public PceBgViewer()
{
InitializeComponent();
Activated += (o, e) => Generate();
}
private void PceBgViewer_Load(object sender, EventArgs e)
{
}
private void RefreshFloatingWindowControl()
{
}
#region Public API
public bool AskSaveChanges() { return true; }
public bool UpdateBefore { get { return true; } }
public unsafe void Generate()
{
if (_pce.Frame % RefreshRate.Value != 0)
{
return;
}
var vdc = _vdcType == 0 ? _pce.VDC1 : _pce.VDC2;
var width = 8 * vdc.BatWidth;
var height = 8 * vdc.BatHeight;
var buf = canvas.Bat.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, canvas.Bat.PixelFormat);
var pitch = buf.Stride / 4;
var begin = (int*)buf.Scan0.ToPointer();
int* p = begin;
for (int y = 0; y < height; ++y)
{
int yTile = y / 8;
int yOfs = y % 8;
for (int x = 0; x < width; ++x, ++p)
{
int xTile = x / 8;
int xOfs = x % 8;
int tileNo = vdc.VRAM[(ushort)(((yTile * vdc.BatWidth) + xTile))] & 0x07FF;
int paletteNo = vdc.VRAM[(ushort)(((yTile * vdc.BatWidth) + xTile))] >> 12;
int paletteBase = paletteNo * 16;
byte c = vdc.PatternBuffer[(tileNo * 64) + (yOfs * 8) + xOfs];
if (c == 0)
{
*p = _pce.VCE.Palette[0];
}
else
{
*p = _pce.VCE.Palette[paletteBase + c];
}
}
p += pitch - width;
}
canvas.Bat.UnlockBits(buf);
canvas.Refresh();
}
public void Restart()
{
// Nothing to do
}
public void UpdateValues()
{
Generate();
}
public void FastUpdate()
{
// Do nothing
}
#endregion
#region Events
#region Menu
private void FileSubMenu_DropDownOpened(object sender, EventArgs e)
{
VDC2MenuItem.Enabled = _pce.SystemId == "SGX";
VDC1MenuItem.Checked = _vdcType == 0;
VDC2MenuItem.Checked = _vdcType == 1;
}
private void VDC1MenuItem_Click(object sender, EventArgs e)
{
_vdcType = 0;
}
private void VDC2MenuItem_Click(object sender, EventArgs e)
{
_vdcType = 1;
}
private void ExitMenuItem_Click(object sender, EventArgs e)
{
Close();
}
#endregion
#region Dialog and Controls
private void Canvas_MouseMove(object sender, MouseEventArgs e)
{
var vdc = _vdcType == 0 ? _pce.VDC1 : _pce.VDC2;
int xTile = e.X / 8;
int yTile = e.Y / 8;
int tileNo = vdc.VRAM[(ushort)((yTile * vdc.BatWidth) + xTile)] & 0x07FF;
int paletteNo = vdc.VRAM[(ushort)((yTile * vdc.BatWidth) + xTile)] >> 12;
TileIDLabel.Text = tileNo.ToString();
XYLabel.Text = xTile + ":" + yTile;
PaletteLabel.Text = paletteNo.ToString();
}
protected override void OnShown(EventArgs e)
{
RefreshFloatingWindowControl();
base.OnShown(e);
}
#endregion
#endregion
}
}