misc tool cleanups

This commit is contained in:
adelikat 2019-12-22 16:42:51 -06:00
parent 0fe2205057
commit 5eee9a6004
31 changed files with 1119 additions and 1282 deletions

View File

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Drawing; using System.Drawing;
using System.Linq; using System.Linq;
using System.Reflection;
using System.Text; using System.Text;
using System.Windows.Forms; using System.Windows.Forms;
@ -88,6 +89,41 @@ namespace BizHawk.Client.EmuHawk.WinFormExtensions
return Color.FromArgb(col); return Color.FromArgb(col);
} }
public static T Clone<T>(this T controlToClone)
where T : Control
{
PropertyInfo[] controlProperties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
Type t = controlToClone.GetType();
T instance = Activator.CreateInstance(t) as T;
t.GetProperty("AutoSize")?.SetValue(instance, false, null);
for (int i = 0; i < 3; i++)
{
foreach (var propInfo in controlProperties)
{
if (!propInfo.CanWrite)
{
continue;
}
if (propInfo.Name != "AutoSize" && propInfo.Name != "WindowTarget")
{
propInfo.SetValue(instance, propInfo.GetValue(controlToClone, null), null);
}
}
}
if (instance is RetainedViewportPanel panel)
{
var cloneBmp = (controlToClone as RetainedViewportPanel).GetBitmap().Clone() as Bitmap;
panel.SetBitmap(cloneBmp);
}
return instance;
}
#region Enumerable to Enumerable<T> #region Enumerable to Enumerable<T>
/// <summary> /// <summary>

View File

@ -1767,7 +1767,7 @@ namespace BizHawk.Client.EmuHawk
private void PceTileViewerMenuItem_Click(object sender, EventArgs e) private void PceTileViewerMenuItem_Click(object sender, EventArgs e)
{ {
Tools.Load<PCETileViewer>(); Tools.Load<PceTileViewer>();
} }
private void PceSoundDebuggerMenuItem_Click(object sender, EventArgs e) private void PceSoundDebuggerMenuItem_Click(object sender, EventArgs e)
@ -1978,7 +1978,7 @@ namespace BizHawk.Client.EmuHawk
private void SmsVdpViewerMenuItem_Click(object sender, EventArgs e) private void SmsVdpViewerMenuItem_Click(object sender, EventArgs e)
{ {
Tools.Load<SmsVDPViewer>(); Tools.Load<SmsVdpViewer>();
} }
private void SMSControllerStandardToolStripMenuItem_Click(object sender, EventArgs e) private void SMSControllerStandardToolStripMenuItem_Click(object sender, EventArgs e)
@ -2141,7 +2141,7 @@ namespace BizHawk.Client.EmuHawk
private void GbGpuViewerMenuItem_Click(object sender, EventArgs e) private void GbGpuViewerMenuItem_Click(object sender, EventArgs e)
{ {
Tools.Load<GBGPUView>(); Tools.Load<GbGpuView>();
} }
private void GBGameGenieMenuItem_Click(object sender, EventArgs e) private void GBGameGenieMenuItem_Click(object sender, EventArgs e)
@ -2165,7 +2165,7 @@ namespace BizHawk.Client.EmuHawk
private void GbaGpuViewerMenuItem_Click(object sender, EventArgs e) private void GbaGpuViewerMenuItem_Click(object sender, EventArgs e)
{ {
Tools.Load<GBAGPUView>(); Tools.Load<GbaGpuView>();
} }
private void UsemGBAMenuItem_Click(object sender, EventArgs e) private void UsemGBAMenuItem_Click(object sender, EventArgs e)
@ -2472,7 +2472,7 @@ namespace BizHawk.Client.EmuHawk
private void GenVdpViewerMenuItem_Click(object sender, EventArgs e) private void GenVdpViewerMenuItem_Click(object sender, EventArgs e)
{ {
Tools.Load<GenVDPViewer>(); Tools.Load<GenVdpViewer>();
} }
private void GenesisSettingsMenuItem_Click(object sender, EventArgs e) private void GenesisSettingsMenuItem_Click(object sender, EventArgs e)

View File

@ -35,9 +35,7 @@
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit; this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
this.Name = "RegisterBoxControl"; this.Name = "RegisterBoxControl";
this.Size = new System.Drawing.Size(240, 217); this.Size = new System.Drawing.Size(240, 217);
this.Load += new System.EventHandler(this.RegisterBoxControl_Load);
this.ResumeLayout(false); this.ResumeLayout(false);
} }
#endregion #endregion

View File

@ -3,7 +3,6 @@ using System.Drawing;
using System.Linq; using System.Linq;
using System.Windows.Forms; using System.Windows.Forms;
using BizHawk.Client.Common;
using BizHawk.Common.NumberExtensions; using BizHawk.Common.NumberExtensions;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
@ -14,9 +13,9 @@ namespace BizHawk.Client.EmuHawk
public IDebuggable Core { get; set; } public IDebuggable Core { get; set; }
public GenericDebugger ParentDebugger { get; set; } public GenericDebugger ParentDebugger { get; set; }
private bool _supressChangeEvents = false; private bool _suppressChangeEvents;
private bool _canGetCpuRegisters = false; private bool _canGetCpuRegisters;
private bool _canSetCpuRegisters = false; private bool _canSetCpuRegisters;
public RegisterBoxControl() public RegisterBoxControl()
{ {
@ -24,18 +23,12 @@ namespace BizHawk.Client.EmuHawk
AutoScroll = true; AutoScroll = true;
} }
private void RegisterBoxControl_Load(object sender, EventArgs e)
{
}
public void NewUpdate(ToolFormUpdateType type) { }
public void UpdateValues() public void UpdateValues()
{ {
if (this.Enabled) if (Enabled)
{ {
var registers = Core.GetCpuFlagsAndRegisters(); var registers = Core.GetCpuFlagsAndRegisters();
_supressChangeEvents = true; _suppressChangeEvents = true;
foreach (var register in registers) foreach (var register in registers)
{ {
@ -55,11 +48,11 @@ namespace BizHawk.Client.EmuHawk
if (_canSetCpuRegisters) if (_canSetCpuRegisters)
{ {
foreach (var textbox in Controls.OfType<TextBox>()) foreach (var textBox in Controls.OfType<TextBox>())
{ {
if (textbox.Name == register.Key) if (textBox.Name == register.Key)
{ {
textbox.Text = register.Value.Value.ToHexString(register.Value.BitSize / 4); textBox.Text = register.Value.Value.ToHexString(register.Value.BitSize / 4);
} }
} }
} }
@ -75,7 +68,7 @@ namespace BizHawk.Client.EmuHawk
} }
} }
_supressChangeEvents = false; _suppressChangeEvents = false;
} }
} }
@ -85,7 +78,7 @@ namespace BizHawk.Client.EmuHawk
{ {
try try
{ {
var registers = Core.GetCpuFlagsAndRegisters(); Core.GetCpuFlagsAndRegisters();
return true; return true;
} }
catch (NotImplementedException) catch (NotImplementedException)
@ -117,7 +110,7 @@ namespace BizHawk.Client.EmuHawk
public void GenerateUI() public void GenerateUI()
{ {
this.Controls.Clear(); Controls.Clear();
_canGetCpuRegisters = CanGetCpuRegisters; _canGetCpuRegisters = CanGetCpuRegisters;
_canSetCpuRegisters = CanSetCpuRegisters; _canSetCpuRegisters = CanSetCpuRegisters;
@ -125,7 +118,7 @@ namespace BizHawk.Client.EmuHawk
if (!_canGetCpuRegisters && !_canSetCpuRegisters) if (!_canGetCpuRegisters && !_canSetCpuRegisters)
{ {
ParentDebugger.DisableRegisterBox(); ParentDebugger.DisableRegisterBox();
this.Enabled = false; Enabled = false;
} }
var registers = Core.GetCpuFlagsAndRegisters(); var registers = Core.GetCpuFlagsAndRegisters();
@ -133,7 +126,7 @@ namespace BizHawk.Client.EmuHawk
int y = UIHelper.ScaleY(0); int y = UIHelper.ScaleY(0);
var maxCharSize = registers.Where(r => r.Value.BitSize != 1).Max(r => r.Key.Length); var maxCharSize = registers.Where(r => r.Value.BitSize != 1).Max(r => r.Key.Length);
var width = maxCharSize * (int)this.Font.Size; var width = maxCharSize * (int)Font.Size;
if (width < 20) if (width < 20)
{ {
width = 20; width = 20;
@ -141,7 +134,7 @@ namespace BizHawk.Client.EmuHawk
foreach (var register in registers.Where(r => r.Value.BitSize != 1)) foreach (var register in registers.Where(r => r.Value.BitSize != 1))
{ {
this.Controls.Add(new Label Controls.Add(new Label
{ {
Text = register.Key, Text = register.Key,
Location = new Point(UIHelper.ScaleX(5), y + UIHelper.ScaleY(2)), Location = new Point(UIHelper.ScaleX(5), y + UIHelper.ScaleY(2)),
@ -162,7 +155,7 @@ namespace BizHawk.Client.EmuHawk
t.TextChanged += (o, e) => t.TextChanged += (o, e) =>
{ {
if (!_supressChangeEvents) if (!_suppressChangeEvents)
{ {
try try
{ {
@ -181,11 +174,11 @@ namespace BizHawk.Client.EmuHawk
} }
}; };
this.Controls.Add(t); Controls.Add(t);
} }
else else
{ {
this.Controls.Add(new Label Controls.Add(new Label
{ {
Name = register.Key, Name = register.Key,
Text = register.Value.Value.ToHexString(register.Value.BitSize / 4), Text = register.Value.Value.ToHexString(register.Value.BitSize / 4),
@ -226,7 +219,7 @@ namespace BizHawk.Client.EmuHawk
c.CheckedChanged += (o, e) => c.CheckedChanged += (o, e) =>
{ {
if (!_supressChangeEvents) if (!_suppressChangeEvents)
{ {
try try
{ {
@ -234,9 +227,9 @@ namespace BizHawk.Client.EmuHawk
} }
catch (InvalidOperationException) // TODO: This is hacky stuff because NES doesn't support setting flags! Need to know when a core supports this or not, and enable/disable the box accordingly catch (InvalidOperationException) // TODO: This is hacky stuff because NES doesn't support setting flags! Need to know when a core supports this or not, and enable/disable the box accordingly
{ {
_supressChangeEvents = true; _suppressChangeEvents = true;
c.Checked = !c.Checked; c.Checked = !c.Checked;
_supressChangeEvents = false; _suppressChangeEvents = false;
c.Enabled = false; c.Enabled = false;
} }
} }
@ -245,7 +238,7 @@ namespace BizHawk.Client.EmuHawk
p.Controls.Add(c); p.Controls.Add(c);
} }
this.Controls.Add(p); Controls.Add(p);
} }
} }
} }

View File

@ -1,6 +1,6 @@
namespace BizHawk.Client.EmuHawk namespace BizHawk.Client.EmuHawk
{ {
partial class GBGPUView partial class GbGpuView
{ {
/// <summary> /// <summary>
/// Required designer variable. /// Required designer variable.
@ -360,7 +360,7 @@
this.buttonChangeColor.TabIndex = 1; this.buttonChangeColor.TabIndex = 1;
this.buttonChangeColor.Text = "Change Color..."; this.buttonChangeColor.Text = "Change Color...";
this.buttonChangeColor.UseVisualStyleBackColor = true; this.buttonChangeColor.UseVisualStyleBackColor = true;
this.buttonChangeColor.Click += new System.EventHandler(this.buttonChangeColor_Click); this.buttonChangeColor.Click += new System.EventHandler(this.ButtonChangeColor_Click);
// //
// panelSpriteBackColor // panelSpriteBackColor
// //
@ -506,13 +506,11 @@
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.Icon = global::BizHawk.Client.EmuHawk.Properties.Resources.gambatte_MultiSize; this.Icon = global::BizHawk.Client.EmuHawk.Properties.Resources.gambatte_MultiSize;
this.MainMenuStrip = this.menuStrip1; this.MainMenuStrip = this.menuStrip1;
this.Name = "GBGPUView"; this.Name = "GbGpuView";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "GPU Viewer"; this.Text = "GPU Viewer";
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.GBGPUView_FormClosing); this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.GbGpuView_FormClosed);
this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.GBGPUView_FormClosed); this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.GbGpuView_KeyDown);
this.Load += new System.EventHandler(this.GBGPUView_Load);
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.GBGPUView_KeyDown);
this.groupBox1.ResumeLayout(false); this.groupBox1.ResumeLayout(false);
this.groupBox1.PerformLayout(); this.groupBox1.PerformLayout();
this.groupBox2.ResumeLayout(false); this.groupBox2.ResumeLayout(false);

View File

@ -1,20 +1,18 @@
using System; using System;
using System.Drawing; using System.Drawing;
using System.Drawing.Imaging;
using System.Text; using System.Text;
using System.Windows.Forms; using System.Windows.Forms;
using BizHawk.Common.NumberExtensions; using BizHawk.Common.NumberExtensions;
using BizHawk.Client.Common;
using BizHawk.Emulation.Cores.Nintendo.Gameboy;
using BizHawk.Client.EmuHawk.WinFormExtensions; using BizHawk.Client.EmuHawk.WinFormExtensions;
using System.Collections.Generic;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
using BizHawk.Emulation.Cores.Consoles.Nintendo.Gameboy; using BizHawk.Emulation.Cores.Consoles.Nintendo.Gameboy;
using BizHawk.Common; using BizHawk.Common;
namespace BizHawk.Client.EmuHawk namespace BizHawk.Client.EmuHawk
{ {
public partial class GBGPUView : Form, IToolFormAutoConfig public partial class GbGpuView : Form, IToolFormAutoConfig
{ {
[RequiredService] [RequiredService]
public IGameboyCommon Gb { get; private set; } public IGameboyCommon Gb { get; private set; }
@ -40,14 +38,14 @@ namespace BizHawk.Client.EmuHawk
private bool _cgb; // set once at start private bool _cgb; // set once at start
private int _lcdc; // set at each callback private int _lcdc; // set at each callback
private IntPtr tilespal; // current palette to use on tiles private IntPtr _tilesPal; // current palette to use on tiles
private Color _spriteback; private Color _spriteback;
[ConfigPersist] [ConfigPersist]
public Color Spriteback public Color Spriteback
{ {
get { return _spriteback; } get => _spriteback;
set set
{ {
_spriteback = Color.FromArgb(255, value); // force fully opaque _spriteback = Color.FromArgb(255, value); // force fully opaque
@ -56,10 +54,10 @@ namespace BizHawk.Client.EmuHawk
} }
} }
public bool AskSaveChanges() { return true; } public bool AskSaveChanges() => true;
public bool UpdateBefore { get { return true; } } public bool UpdateBefore => true;
public GBGPUView() public GbGpuView()
{ {
InitializeComponent(); InitializeComponent();
bmpViewBG.ChangeBitmapSize(256, 256); bmpViewBG.ChangeBitmapSize(256, 256);
@ -78,9 +76,9 @@ namespace BizHawk.Client.EmuHawk
KeyPreview = true; KeyPreview = true;
_messagetimer.Interval = 5000; _messageTimer.Interval = 5000;
_messagetimer.Tick += messagetimer_Tick; _messageTimer.Tick += MessageTimer_Tick;
Spriteback = Color.Lime; // will be overrided from config after construct Spriteback = Color.Lime; // will be overridden from config after construct
} }
public void Restart() public void Restart()
@ -89,12 +87,9 @@ namespace BizHawk.Client.EmuHawk
_lcdc = 0; _lcdc = 0;
_memory = Gb.GetGPU(); _memory = Gb.GetGPU();
tilespal = _memory.Bgpal; _tilesPal = _memory.Bgpal;
if (_cgb) label4.Enabled = _cgb;
label4.Enabled = true;
else
label4.Enabled = false;
bmpViewBG.Clear(); bmpViewBG.Clear();
bmpViewWin.Clear(); bmpViewWin.Clear();
bmpViewTiles1.Clear(); bmpViewTiles1.Clear();
@ -104,7 +99,7 @@ namespace BizHawk.Client.EmuHawk
bmpViewOAM.Clear(); bmpViewOAM.Clear();
bmpViewDetails.Clear(); bmpViewDetails.Clear();
bmpViewMemory.Clear(); bmpViewMemory.Clear();
cbscanline_emu = -4; // force refresh _cbScanlineEmu = -4; // force refresh
} }
@ -144,35 +139,35 @@ namespace BizHawk.Client.EmuHawk
/// <param name="dest">top left origin on 32bit bitmap</param> /// <param name="dest">top left origin on 32bit bitmap</param>
/// <param name="pitch">pitch of bitmap in 4 byte units</param> /// <param name="pitch">pitch of bitmap in 4 byte units</param>
/// <param name="pal">4 palette colors</param> /// <param name="pal">4 palette colors</param>
/// <param name="hflip">true to flip horizontally</param> /// <param name="hFlip">true to flip horizontally</param>
/// <param name="vflip">true to flip vertically</param> /// <param name="vFlip">true to flip vertically</param>
static unsafe void DrawTileHv(byte* tile, int* dest, int pitch, int* pal, bool hflip, bool vflip) static unsafe void DrawTileHv(byte* tile, int* dest, int pitch, int* pal, bool hFlip, bool vFlip)
{ {
if (vflip) if (vFlip)
dest += pitch * 7; dest += pitch * 7;
for (int y = 0; y < 8; y++) for (int y = 0; y < 8; y++)
{ {
int loplane = *tile++; int loPlane = *tile++;
int hiplane = *tile++; int hiPlane = *tile++;
hiplane <<= 1; // msb hiPlane <<= 1; // msb
if (!hflip) if (!hFlip)
dest += 7; dest += 7;
for (int x = 0; x < 8; x++) // right to left for (int x = 0; x < 8; x++) // right to left
{ {
int color = loplane & 1 | hiplane & 2; int color = loPlane & 1 | hiPlane & 2;
*dest = (int)(pal[color] | 0xFF000000); *dest = (int)(pal[color] | 0xFF000000);
if (!hflip) if (!hFlip)
dest--; dest--;
else else
dest++; dest++;
loplane >>= 1; loPlane >>= 1;
hiplane >>= 1; hiPlane >>= 1;
} }
if (!hflip) if (!hFlip)
dest++; dest++;
else else
dest -= 8; dest -= 8;
if (!vflip) if (!vFlip)
dest += pitch; dest += pitch;
else else
dest -= pitch; dest -= pitch;
@ -184,39 +179,39 @@ namespace BizHawk.Client.EmuHawk
/// </summary> /// </summary>
/// <param name="b">bitmap to draw to, should be 256x256</param> /// <param name="b">bitmap to draw to, should be 256x256</param>
/// <param name="_map">tilemap, 32x32 bytes. extended tilemap assumed to be @+8k</param> /// <param name="_map">tilemap, 32x32 bytes. extended tilemap assumed to be @+8k</param>
/// <param name="_tiles">base tiledata location. second bank tiledata assumed to be @+8k</param> /// <param name="tiles">base tiledata location. second bank tiledata assumed to be @+8k</param>
/// <param name="wrap">true if tileindexes are s8 (not u8)</param> /// <param name="wrap">true if tileindexes are s8 (not u8)</param>
/// <param name="_pal">8 palettes (4 colors each)</param> /// <param name="_pal">8 palettes (4 colors each)</param>
static unsafe void DrawBGCGB(Bitmap b, IntPtr _map, IntPtr _tiles, bool wrap, IntPtr _pal) static unsafe void DrawBgCgb(Bitmap b, IntPtr _map, IntPtr tiles, bool wrap, IntPtr _pal)
{ {
var lockdata = b.LockBits(new Rectangle(0, 0, 256, 256), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); var lockData = b.LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
byte* map = (byte*)_map; byte* map = (byte*)_map;
int* dest = (int*)lockdata.Scan0; int* dest = (int*)lockData.Scan0;
int pitch = lockdata.Stride / sizeof(int); // in int*s, not bytes int pitch = lockData.Stride / sizeof(int); // in int*s, not bytes
int* pal = (int*)_pal; int* pal = (int*)_pal;
for (int ty = 0; ty < 32; ty++) for (int ty = 0; ty < 32; ty++)
{ {
for (int tx = 0; tx < 32; tx++) for (int tx = 0; tx < 32; tx++)
{ {
int tileindex = map[0]; int tileIndex = map[0];
int tileext = map[8192]; int tileExt = map[8192];
if (wrap && tileindex >= 128) if (wrap && tileIndex >= 128)
tileindex -= 256; tileIndex -= 256;
byte* tile = (byte*)(_tiles + tileindex * 16); byte* tile = (byte*)(tiles + tileIndex * 16);
if (tileext.Bit(3)) // second bank if (tileExt.Bit(3)) // second bank
tile += 8192; tile += 8192;
int* thispal = pal + 4 * (tileext & 7); int* thisPal = pal + 4 * (tileExt & 7);
DrawTileHv(tile, dest, pitch, thispal, tileext.Bit(5), tileext.Bit(6)); DrawTileHv(tile, dest, pitch, thisPal, tileExt.Bit(5), tileExt.Bit(6));
map++; map++;
dest += 8; dest += 8;
} }
dest -= 256; dest -= 256;
dest += pitch * 8; dest += pitch * 8;
} }
b.UnlockBits(lockdata); b.UnlockBits(lockData);
} }
/// <summary> /// <summary>
@ -227,22 +222,22 @@ namespace BizHawk.Client.EmuHawk
/// <param name="_tiles">base tiledata location</param> /// <param name="_tiles">base tiledata location</param>
/// <param name="wrap">true if tileindexes are s8 (not u8)</param> /// <param name="wrap">true if tileindexes are s8 (not u8)</param>
/// <param name="_pal">1 palette (4 colors)</param> /// <param name="_pal">1 palette (4 colors)</param>
static unsafe void DrawBGDMG(Bitmap b, IntPtr _map, IntPtr _tiles, bool wrap, IntPtr _pal) private static unsafe void DrawBgDmg(Bitmap b, IntPtr _map, IntPtr _tiles, bool wrap, IntPtr _pal)
{ {
var lockdata = b.LockBits(new Rectangle(0, 0, 256, 256), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); var lockData = b.LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
byte* map = (byte*)_map; byte* map = (byte*)_map;
int* dest = (int*)lockdata.Scan0; int* dest = (int*)lockData.Scan0;
int pitch = lockdata.Stride / sizeof(int); // in int*s, not bytes int pitch = lockData.Stride / sizeof(int); // in int*s, not bytes
int* pal = (int*)_pal; int* pal = (int*)_pal;
for (int ty = 0; ty < 32; ty++) for (int ty = 0; ty < 32; ty++)
{ {
for (int tx = 0; tx < 32; tx++) for (int tx = 0; tx < 32; tx++)
{ {
int tileindex = map[0]; int tileIndex = map[0];
if (wrap && tileindex >= 128) if (wrap && tileIndex >= 128)
tileindex -= 256; tileIndex -= 256;
byte* tile = (byte*)(_tiles + tileindex * 16); byte* tile = (byte*)(_tiles + tileIndex * 16);
DrawTile(tile, dest, pitch, pal); DrawTile(tile, dest, pitch, pal);
map++; map++;
dest += 8; dest += 8;
@ -250,7 +245,7 @@ namespace BizHawk.Client.EmuHawk
dest -= 256; dest -= 256;
dest += pitch * 8; dest += pitch * 8;
} }
b.UnlockBits(lockdata); b.UnlockBits(lockData);
} }
/// <summary> /// <summary>
@ -259,11 +254,11 @@ namespace BizHawk.Client.EmuHawk
/// <param name="b">bitmap to draw to, should be 128x192</param> /// <param name="b">bitmap to draw to, should be 128x192</param>
/// <param name="_tiles">base tile address</param> /// <param name="_tiles">base tile address</param>
/// <param name="_pal">single palette to use on all tiles</param> /// <param name="_pal">single palette to use on all tiles</param>
static unsafe void DrawTiles(Bitmap b, IntPtr _tiles, IntPtr _pal) private static unsafe void DrawTiles(Bitmap b, IntPtr _tiles, IntPtr _pal)
{ {
var lockdata = b.LockBits(new Rectangle(0, 0, 128, 192), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); var lockData = b.LockBits(new Rectangle(0, 0, 128, 192), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
int* dest = (int*)lockdata.Scan0; int* dest = (int*)lockData.Scan0;
int pitch = lockdata.Stride / sizeof(int); int pitch = lockData.Stride / sizeof(int);
int* pal = (int*)_pal; int* pal = (int*)_pal;
byte* tile = (byte*)_tiles; byte* tile = (byte*)_tiles;
@ -278,7 +273,7 @@ namespace BizHawk.Client.EmuHawk
dest -= 128; dest -= 128;
dest += pitch * 8; dest += pitch * 8;
} }
b.UnlockBits(lockdata); b.UnlockBits(lockData);
} }
/// <summary> /// <summary>
@ -290,39 +285,50 @@ namespace BizHawk.Client.EmuHawk
/// <param name="_pal">2 (dmg) or 8 (cgb) palettes</param> /// <param name="_pal">2 (dmg) or 8 (cgb) palettes</param>
/// <param name="tall">true for 8x16 sprites; else 8x8</param> /// <param name="tall">true for 8x16 sprites; else 8x8</param>
/// <param name="cgb">true for cgb (more palettes, second bank tiles)</param> /// <param name="cgb">true for cgb (more palettes, second bank tiles)</param>
static unsafe void DrawOam(Bitmap b, IntPtr _oam, IntPtr _tiles, IntPtr _pal, bool tall, bool cgb) private static unsafe void DrawOam(Bitmap b, IntPtr _oam, IntPtr _tiles, IntPtr _pal, bool tall, bool cgb)
{ {
var lockdata = b.LockBits(new Rectangle(0, 0, 320, tall ? 16 : 8), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); var lockData = b.LockBits(new Rectangle(0, 0, 320, tall ? 16 : 8), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
int* dest = (int*)lockdata.Scan0; int* dest = (int*)lockData.Scan0;
int pitch = lockdata.Stride / sizeof(int); int pitch = lockData.Stride / sizeof(int);
int* pal = (int*)_pal; int* pal = (int*)_pal;
byte* oam = (byte*)_oam; byte* oam = (byte*)_oam;
for (int s = 0; s < 40; s++) for (int s = 0; s < 40; s++)
{ {
oam += 2; // ypos, xpos oam += 2; // yPos, xPos
int tileindex = *oam++; int tileIndex = *oam++;
int flags = *oam++; int flags = *oam++;
bool vflip = flags.Bit(6); bool vFlip = flags.Bit(6);
bool hflip = flags.Bit(5); bool hFlip = flags.Bit(5);
if (tall) if (tall)
// i assume 8x16 vflip flips the whole thing, not just each tile? {
if (vflip) // i assume 8x16 vFlip flips the whole thing, not just each tile?
tileindex |= 1; if (vFlip)
{
tileIndex |= 1;
}
else else
tileindex &= 0xfe; {
byte* tile = (byte*)(_tiles + tileindex * 16); tileIndex &= 0xfe;
int* thispal = pal + 4 * (cgb ? flags & 7 : flags >> 4 & 1); }
}
byte* tile = (byte*)(_tiles + tileIndex * 16);
int* thisPal = pal + 4 * (cgb ? flags & 7 : flags >> 4 & 1);
if (cgb && flags.Bit(3)) if (cgb && flags.Bit(3))
tile += 8192; tile += 8192;
DrawTileHv(tile, dest, pitch, thispal, hflip, vflip); DrawTileHv(tile, dest, pitch, thisPal, hFlip, vFlip);
if (tall) if (tall)
DrawTileHv(tile + 16, dest + pitch * 8, pitch, thispal, hflip, vflip); {
DrawTileHv(tile + 16, dest + pitch * 8, pitch, thisPal, hFlip, vFlip);
}
dest += 8; dest += 8;
} }
b.UnlockBits(lockdata);
b.UnlockBits(lockData);
} }
/// <summary> /// <summary>
@ -333,9 +339,9 @@ namespace BizHawk.Client.EmuHawk
/// <param name="numpals">number of palettes (not colors)</param> /// <param name="numpals">number of palettes (not colors)</param>
static unsafe void DrawPal(Bitmap b, IntPtr _pal, int numpals) static unsafe void DrawPal(Bitmap b, IntPtr _pal, int numpals)
{ {
var lockdata = b.LockBits(new Rectangle(0, 0, numpals, 4), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); var lockData = b.LockBits(new Rectangle(0, 0, numpals, 4), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
int* dest = (int*)lockdata.Scan0; int* dest = (int*)lockData.Scan0;
int pitch = lockdata.Stride / sizeof(int); int pitch = lockData.Stride / sizeof(int);
int* pal = (int*)_pal; int* pal = (int*)_pal;
for (int px = 0; px < numpals; px++) for (int px = 0; px < numpals; px++)
@ -348,7 +354,7 @@ namespace BizHawk.Client.EmuHawk
dest -= pitch * 4; dest -= pitch * 4;
dest++; dest++;
} }
b.UnlockBits(lockdata); b.UnlockBits(lockData);
} }
#endregion #endregion
@ -357,10 +363,10 @@ namespace BizHawk.Client.EmuHawk
{ {
using (_memory.EnterExit()) using (_memory.EnterExit())
{ {
var _bgpal = _memory.Bgpal; var bgPal = _memory.Bgpal;
var _sppal = _memory.Sppal; var spPal = _memory.Sppal;
var _oam = _memory.Oam; var oam = _memory.Oam;
var _vram = _memory.Vram; var vram = _memory.Vram;
_lcdc = lcdc; _lcdc = lcdc;
// set alpha on all pixels // set alpha on all pixels
@ -381,35 +387,35 @@ namespace BizHawk.Client.EmuHawk
// bg maps // bg maps
if (!_cgb) if (!_cgb)
{ {
DrawBGDMG( DrawBgDmg(
bmpViewBG.BMP, bmpViewBG.BMP,
_vram + (lcdc.Bit(3) ? 0x1c00 : 0x1800), vram + (lcdc.Bit(3) ? 0x1c00 : 0x1800),
_vram + (lcdc.Bit(4) ? 0x0000 : 0x1000), vram + (lcdc.Bit(4) ? 0x0000 : 0x1000),
!lcdc.Bit(4), !lcdc.Bit(4),
_bgpal); bgPal);
DrawBGDMG( DrawBgDmg(
bmpViewWin.BMP, bmpViewWin.BMP,
_vram + (lcdc.Bit(6) ? 0x1c00 : 0x1800), vram + (lcdc.Bit(6) ? 0x1c00 : 0x1800),
_vram + 0x1000, // force win to second tile bank??? vram + 0x1000, // force win to second tile bank???
true, true,
_bgpal); bgPal);
} }
else else
{ {
DrawBGCGB( DrawBgCgb(
bmpViewBG.BMP, bmpViewBG.BMP,
_vram + (lcdc.Bit(3) ? 0x1c00 : 0x1800), vram + (lcdc.Bit(3) ? 0x1c00 : 0x1800),
_vram + (lcdc.Bit(4) ? 0x0000 : 0x1000), vram + (lcdc.Bit(4) ? 0x0000 : 0x1000),
!lcdc.Bit(4), !lcdc.Bit(4),
_bgpal); bgPal);
DrawBGCGB( DrawBgCgb(
bmpViewWin.BMP, bmpViewWin.BMP,
_vram + (lcdc.Bit(6) ? 0x1c00 : 0x1800), vram + (lcdc.Bit(6) ? 0x1c00 : 0x1800),
_vram + 0x1000, // force win to second tile bank??? vram + 0x1000, // force win to second tile bank???
true, true,
_bgpal); bgPal);
} }
bmpViewBG.Refresh(); bmpViewBG.Refresh();
bmpViewWin.Refresh(); bmpViewWin.Refresh();
@ -417,11 +423,11 @@ namespace BizHawk.Client.EmuHawk
// tile display // tile display
// TODO: user selects palette to use, instead of fixed palette 0 // TODO: user selects palette to use, instead of fixed palette 0
// or possibly "smart" where, if a tile is in use, it's drawn with one of the palettes actually being used with it? // or possibly "smart" where, if a tile is in use, it's drawn with one of the palettes actually being used with it?
DrawTiles(bmpViewTiles1.BMP, _vram, tilespal); DrawTiles(bmpViewTiles1.BMP, vram, _tilesPal);
bmpViewTiles1.Refresh(); bmpViewTiles1.Refresh();
if (_cgb) if (_cgb)
{ {
DrawTiles(bmpViewTiles2.BMP, _vram + 0x2000, tilespal); DrawTiles(bmpViewTiles2.BMP, vram + 0x2000, _tilesPal);
bmpViewTiles2.Refresh(); bmpViewTiles2.Refresh();
} }
@ -434,8 +440,8 @@ namespace BizHawk.Client.EmuHawk
bmpViewSPPal.ChangeBitmapSize(8, 4); bmpViewSPPal.ChangeBitmapSize(8, 4);
if (bmpViewSPPal.Width != 128) if (bmpViewSPPal.Width != 128)
bmpViewSPPal.Width = 128; bmpViewSPPal.Width = 128;
DrawPal(bmpViewBGPal.BMP, _bgpal, 8); DrawPal(bmpViewBGPal.BMP, bgPal, 8);
DrawPal(bmpViewSPPal.BMP, _sppal, 8); DrawPal(bmpViewSPPal.BMP, spPal, 8);
} }
else else
{ {
@ -445,8 +451,8 @@ namespace BizHawk.Client.EmuHawk
bmpViewSPPal.ChangeBitmapSize(2, 4); bmpViewSPPal.ChangeBitmapSize(2, 4);
if (bmpViewSPPal.Width != 32) if (bmpViewSPPal.Width != 32)
bmpViewSPPal.Width = 32; bmpViewSPPal.Width = 32;
DrawPal(bmpViewBGPal.BMP, _bgpal, 1); DrawPal(bmpViewBGPal.BMP, bgPal, 1);
DrawPal(bmpViewSPPal.BMP, _sppal, 2); DrawPal(bmpViewSPPal.BMP, spPal, 2);
} }
bmpViewBGPal.Refresh(); bmpViewBGPal.Refresh();
bmpViewSPPal.Refresh(); bmpViewSPPal.Refresh();
@ -464,25 +470,18 @@ namespace BizHawk.Client.EmuHawk
if (bmpViewOAM.Height != 8) if (bmpViewOAM.Height != 8)
bmpViewOAM.Height = 8; bmpViewOAM.Height = 8;
} }
DrawOam(bmpViewOAM.BMP, _oam, _vram, _sppal, lcdc.Bit(2), _cgb); DrawOam(bmpViewOAM.BMP, oam, vram, spPal, lcdc.Bit(2), _cgb);
bmpViewOAM.Refresh(); bmpViewOAM.Refresh();
} }
// try to run the current mouseover, to refresh if the mouse is being held over a pane while the emulator runs // try to run the current mouseover, to refresh if the mouse is being held over a pane while the emulator runs
// this doesn't really work well; the update rate seems to be throttled // this doesn't really work well; the update rate seems to be throttled
MouseEventArgs e = new MouseEventArgs(MouseButtons.None, 0, Cursor.Position.X, Cursor.Position.Y, 0); var e = new MouseEventArgs(MouseButtons.None, 0, Cursor.Position.X, Cursor.Position.Y, 0);
OnMouseMove(e); OnMouseMove(e);
} }
private void GBGPUView_FormClosed(object sender, FormClosedEventArgs e) private void GbGpuView_FormClosed(object sender, FormClosedEventArgs e)
{
if (Gb != null)
{
Gb.SetScanlineCallback(null, 0);
}
}
private void GBGPUView_Load(object sender, EventArgs e)
{ {
Gb?.SetScanlineCallback(null, 0);
} }
#region refresh #region refresh
@ -498,44 +497,43 @@ namespace BizHawk.Client.EmuHawk
labelScanline.Enabled = false; labelScanline.Enabled = false;
hScrollBarScanline.Enabled = false; hScrollBarScanline.Enabled = false;
buttonRefresh.Enabled = false; buttonRefresh.Enabled = false;
cbscanline = -1; _cbScanline = -1;
} }
else if (radioButtonRefreshScanline.Checked) else if (radioButtonRefreshScanline.Checked)
{ {
labelScanline.Enabled = true; labelScanline.Enabled = true;
hScrollBarScanline.Enabled = true; hScrollBarScanline.Enabled = true;
buttonRefresh.Enabled = false; buttonRefresh.Enabled = false;
cbscanline = (hScrollBarScanline.Value + 145) % 154; _cbScanline = (hScrollBarScanline.Value + 145) % 154;
} }
else if (radioButtonRefreshManual.Checked) else if (radioButtonRefreshManual.Checked)
{ {
labelScanline.Enabled = false; labelScanline.Enabled = false;
hScrollBarScanline.Enabled = false; hScrollBarScanline.Enabled = false;
buttonRefresh.Enabled = true; buttonRefresh.Enabled = true;
cbscanline = -2; _cbScanline = -2;
} }
} }
private void buttonRefresh_Click(object sender, EventArgs e) private void buttonRefresh_Click(object sender, EventArgs e)
{ {
if (cbscanline == -2) if (_cbScanline == -2)
{
Gb.SetScanlineCallback(ScanlineCallback, -2); Gb.SetScanlineCallback(ScanlineCallback, -2);
} }
}
private void hScrollBarScanline_ValueChanged(object sender, EventArgs e) private void hScrollBarScanline_ValueChanged(object sender, EventArgs e)
{ {
labelScanline.Text = ((hScrollBarScanline.Value + 145) % 154).ToString(); labelScanline.Text = ((hScrollBarScanline.Value + 145) % 154).ToString();
cbscanline = (hScrollBarScanline.Value + 145) % 154; _cbScanline = (hScrollBarScanline.Value + 145) % 154;
} }
/// <summary> // 0..153: scanline number. -1: frame. -2: manual
/// 0..153: scanline number. -1: frame. -2: manual private int _cbScanline;
/// </summary>
int cbscanline; // what was last passed to the emu core
/// <summary> private int _cbScanlineEmu = -4; // force refresh
/// what was last passed to the emu core
/// </summary>
int cbscanline_emu = -4; // force refresh
public void NewUpdate(ToolFormUpdateType type) { } public void NewUpdate(ToolFormUpdateType type) { }
@ -548,25 +546,26 @@ namespace BizHawk.Client.EmuHawk
{ {
return; return;
} }
else if (Gb != null)
if (Gb != null)
{ {
if (!Visible) if (!Visible)
{ {
if (cbscanline_emu != -2) if (_cbScanlineEmu != -2)
{ {
cbscanline_emu = -2; _cbScanlineEmu = -2;
Gb.SetScanlineCallback(null, 0); Gb.SetScanlineCallback(null, 0);
} }
} }
else else
{ {
if (cbscanline != cbscanline_emu) if (_cbScanline != _cbScanlineEmu)
{ {
cbscanline_emu = cbscanline; _cbScanlineEmu = _cbScanline;
if (cbscanline == -2) if (_cbScanline == -2)
Gb.SetScanlineCallback(null, 0); Gb.SetScanlineCallback(null, 0);
else else
Gb.SetScanlineCallback(ScanlineCallback, cbscanline); Gb.SetScanlineCallback(ScanlineCallback, _cbScanline);
} }
} }
} }
@ -588,8 +587,7 @@ namespace BizHawk.Client.EmuHawk
private void SaveDetails() private void SaveDetails()
{ {
_freezeLabel = groupBoxDetails.Text; _freezeLabel = groupBoxDetails.Text;
if (_freezeBmp != null) _freezeBmp?.Dispose();
_freezeBmp.Dispose();
_freezeBmp = (Bitmap)bmpViewDetails.BMP.Clone(); _freezeBmp = (Bitmap)bmpViewDetails.BMP.Clone();
_freezeDetails = labelDetails.Text; _freezeDetails = labelDetails.Text;
} }
@ -620,10 +618,8 @@ namespace BizHawk.Client.EmuHawk
{ {
using (_memory.EnterExit()) using (_memory.EnterExit())
{ {
var _bgpal = _memory.Bgpal; var bgPal = _memory.Bgpal;
var _sppal = _memory.Sppal; var spPal = _memory.Sppal;
var _oam = _memory.Oam;
var _vram = _memory.Vram;
bmpViewDetails.ChangeBitmapSize(8, 10); bmpViewDetails.ChangeBitmapSize(8, 10);
if (bmpViewDetails.Height != 80) if (bmpViewDetails.Height != 80)
@ -631,43 +627,44 @@ namespace BizHawk.Client.EmuHawk
var sb = new StringBuilder(); var sb = new StringBuilder();
x /= 16; x /= 16;
y /= 16; y /= 16;
int* pal = (int*)(sprite ? _sppal : _bgpal) + x * 4; int* pal = (int*)(sprite ? spPal : bgPal) + x * 4;
int color = pal[y]; int color = pal[y];
sb.AppendLine($"Palette {x}"); sb.AppendLine($"Palette {x}");
sb.AppendLine($"Color {y}"); sb.AppendLine($"Color {y}");
sb.AppendLine($"(R,G,B) = ({color >> 16 & 255},{color >> 8 & 255},{color & 255})"); sb.AppendLine($"(R,G,B) = ({color >> 16 & 255},{color >> 8 & 255},{color & 255})");
var lockdata = bmpViewDetails.BMP.LockBits(new Rectangle(0, 0, 8, 10), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); var lockData = bmpViewDetails.BMP.LockBits(new Rectangle(0, 0, 8, 10), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
int* dest = (int*)lockdata.Scan0; int* dest = (int*)lockData.Scan0;
int pitch = lockdata.Stride / sizeof(int); int pitch = lockData.Stride / sizeof(int);
for (int py = 0; py < 10; py++) for (int py = 0; py < 10; py++)
{ {
for (int px = 0; px < 8; px++) for (int px = 0; px < 8; px++)
{ {
if (py < 8) if (py < 8)
{
*dest++ = color; *dest++ = color;
}
else else
{
*dest++ = pal[px / 2]; *dest++ = pal[px / 2];
} }
}
dest -= 8; dest -= 8;
dest += pitch; dest += pitch;
} }
bmpViewDetails.BMP.UnlockBits(lockdata); bmpViewDetails.BMP.UnlockBits(lockData);
labelDetails.Text = sb.ToString(); labelDetails.Text = sb.ToString();
bmpViewDetails.Refresh(); bmpViewDetails.Refresh();
} }
} }
unsafe void TileMouseover(int x, int y, bool secondbank) unsafe void TileMouseover(int x, int y, bool secondBank)
{ {
using (_memory.EnterExit()) using (_memory.EnterExit())
{ {
var _bgpal = _memory.Bgpal; var vram = _memory.Vram;
var _sppal = _memory.Sppal;
var _oam = _memory.Oam;
var _vram = _memory.Vram;
// todo: draw with a specific palette // todo: draw with a specific palette
bmpViewDetails.ChangeBitmapSize(8, 8); bmpViewDetails.ChangeBitmapSize(8, 8);
@ -676,63 +673,60 @@ namespace BizHawk.Client.EmuHawk
var sb = new StringBuilder(); var sb = new StringBuilder();
x /= 8; x /= 8;
y /= 8; y /= 8;
int tileindex = y * 16 + x; int tileIndex = y * 16 + x;
int tileoffs = tileindex * 16; int tileOffset = tileIndex * 16;
if (_cgb) sb.AppendLine(_cgb
sb.AppendLine($"Tile #{tileindex} @{(secondbank ? 1 : 0)}:{tileoffs + 0x8000:x4}"); ? $"Tile #{tileIndex} @{(secondBank ? 1 : 0)}:{tileOffset + 0x8000:x4}"
else : $"Tile #{tileIndex} @{tileOffset + 0x8000:x4}");
sb.AppendLine($"Tile #{tileindex} @{tileoffs + 0x8000:x4}");
var lockdata = bmpViewDetails.BMP.LockBits(new Rectangle(0, 0, 8, 8), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); var lockData = bmpViewDetails.BMP.LockBits(new Rectangle(0, 0, 8, 8), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
DrawTile((byte*)_vram + tileoffs + (secondbank ? 8192 : 0), (int*)lockdata.Scan0, lockdata.Stride / sizeof(int), (int*)tilespal); DrawTile((byte*)vram + tileOffset + (secondBank ? 8192 : 0), (int*)lockData.Scan0, lockData.Stride / sizeof(int), (int*)_tilesPal);
bmpViewDetails.BMP.UnlockBits(lockdata); bmpViewDetails.BMP.UnlockBits(lockData);
labelDetails.Text = sb.ToString(); labelDetails.Text = sb.ToString();
bmpViewDetails.Refresh(); bmpViewDetails.Refresh();
} }
} }
unsafe void TilemapMouseover(int x, int y, bool win) unsafe void TileMapMouseover(int x, int y, bool win)
{ {
using (_memory.EnterExit()) using (_memory.EnterExit())
{ {
var _bgpal = _memory.Bgpal; var _bgpal = _memory.Bgpal;
var _sppal = _memory.Sppal;
var _oam = _memory.Oam;
var _vram = _memory.Vram; var _vram = _memory.Vram;
bmpViewDetails.ChangeBitmapSize(8, 8); bmpViewDetails.ChangeBitmapSize(8, 8);
if (bmpViewDetails.Height != 64) if (bmpViewDetails.Height != 64)
bmpViewDetails.Height = 64; bmpViewDetails.Height = 64;
var sb = new StringBuilder(); var sb = new StringBuilder();
bool secondmap = win ? _lcdc.Bit(6) : _lcdc.Bit(3); bool secondMap = win ? _lcdc.Bit(6) : _lcdc.Bit(3);
int mapoffs = secondmap ? 0x1c00 : 0x1800; int mapOffset = secondMap ? 0x1c00 : 0x1800;
x /= 8; x /= 8;
y /= 8; y /= 8;
mapoffs += y * 32 + x; mapOffset += y * 32 + x;
byte* mapbase = (byte*)_vram + mapoffs; byte* mapBase = (byte*)_vram + mapOffset;
int tileindex = mapbase[0]; int tileIndex = mapBase[0];
if (win || !_lcdc.Bit(4)) // 0x9000 base if (win || !_lcdc.Bit(4)) // 0x9000 base
if (tileindex < 128) if (tileIndex < 128)
tileindex += 256; // compute all if from 0x8000 base tileIndex += 256; // compute all if from 0x8000 base
int tileoffs = tileindex * 16; int tileOffset = tileIndex * 16;
var lockdata = bmpViewDetails.BMP.LockBits(new Rectangle(0, 0, 8, 8), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); var lockData = bmpViewDetails.BMP.LockBits(new Rectangle(0, 0, 8, 8), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
if (!_cgb) if (!_cgb)
{ {
sb.AppendLine($"{(win ? "Win" : "BG")} Map ({x},{y}) @{mapoffs + 0x8000:x4}"); sb.AppendLine($"{(win ? "Win" : "BG")} Map ({x},{y}) @{mapOffset + 0x8000:x4}");
sb.AppendLine($" Tile #{tileindex} @{tileoffs + 0x8000:x4}"); sb.AppendLine($" Tile #{tileIndex} @{tileOffset + 0x8000:x4}");
DrawTile((byte*)_vram + tileoffs, (int*)lockdata.Scan0, lockdata.Stride / sizeof(int), (int*)_bgpal); DrawTile((byte*)_vram + tileOffset, (int*)lockData.Scan0, lockData.Stride / sizeof(int), (int*)_bgpal);
} }
else else
{ {
int tileext = mapbase[8192]; int tileExt = mapBase[8192];
sb.AppendLine($"{(win ? "Win" : "BG")} Map ({x},{y}) @{mapoffs + 0x8000:x4}"); sb.AppendLine($"{(win ? "Win" : "BG")} Map ({x},{y}) @{mapOffset + 0x8000:x4}");
sb.AppendLine($" Tile #{tileindex} @{(tileext.Bit(3) ? 1 : 0)}:{tileoffs + 0x8000:x4}"); sb.AppendLine($" Tile #{tileIndex} @{(tileExt.Bit(3) ? 1 : 0)}:{tileOffset + 0x8000:x4}");
sb.AppendLine($" Palette {tileext & 7}"); sb.AppendLine($" Palette {tileExt & 7}");
sb.AppendLine($" Flags {(tileext.Bit(5) ? 'H' : ' ')}{(tileext.Bit(6) ? 'V' : ' ')}{(tileext.Bit(7) ? 'P' : ' ')}"); sb.AppendLine($" Flags {(tileExt.Bit(5) ? 'H' : ' ')}{(tileExt.Bit(6) ? 'V' : ' ')}{(tileExt.Bit(7) ? 'P' : ' ')}");
DrawTileHv((byte*)_vram + tileoffs + (tileext.Bit(3) ? 8192 : 0), (int*)lockdata.Scan0, lockdata.Stride / sizeof(int), (int*)_bgpal + 4 * (tileext & 7), tileext.Bit(5), tileext.Bit(6)); DrawTileHv((byte*)_vram + tileOffset + (tileExt.Bit(3) ? 8192 : 0), (int*)lockData.Scan0, lockData.Stride / sizeof(int), (int*)_bgpal + 4 * (tileExt & 7), tileExt.Bit(5), tileExt.Bit(6));
} }
bmpViewDetails.BMP.UnlockBits(lockdata); bmpViewDetails.BMP.UnlockBits(lockData);
labelDetails.Text = sb.ToString(); labelDetails.Text = sb.ToString();
bmpViewDetails.Refresh(); bmpViewDetails.Refresh();
} }
@ -742,10 +736,9 @@ namespace BizHawk.Client.EmuHawk
{ {
using (_memory.EnterExit()) using (_memory.EnterExit())
{ {
var _bgpal = _memory.Bgpal; var spPal = _memory.Sppal;
var _sppal = _memory.Sppal; var oam = _memory.Oam;
var _oam = _memory.Oam; var vram = _memory.Vram;
var _vram = _memory.Vram;
bool tall = _lcdc.Bit(2); bool tall = _lcdc.Bit(2);
x /= 8; x /= 8;
@ -755,37 +748,40 @@ namespace BizHawk.Client.EmuHawk
bmpViewDetails.Height = bmpViewDetails.BMP.Height * 8; bmpViewDetails.Height = bmpViewDetails.BMP.Height * 8;
var sb = new StringBuilder(); var sb = new StringBuilder();
byte* oament = (byte*)_oam + 4 * x; byte* oament = (byte*)oam + 4 * x;
int sy = oament[0]; int sy = oament[0];
int sx = oament[1]; int sx = oament[1];
int tilenum = oament[2]; int tileNum = oament[2];
int flags = oament[3]; int flags = oament[3];
bool hflip = flags.Bit(5); bool hFlip = flags.Bit(5);
bool vflip = flags.Bit(6); bool vFlip = flags.Bit(6);
if (tall) if (tall)
tilenum = vflip ? tilenum | 1 : tilenum & ~1; {
int tileoffs = tilenum * 16; tileNum = vFlip ? tileNum | 1 : tileNum & ~1;
}
int tileOffset = tileNum * 16;
sb.AppendLine($"Sprite #{x} @{4 * x + 0xfe00:x4}"); sb.AppendLine($"Sprite #{x} @{4 * x + 0xfe00:x4}");
sb.AppendLine($" (x,y) = ({sx},{sy})"); sb.AppendLine($" (x,y) = ({sx},{sy})");
var lockdata = bmpViewDetails.BMP.LockBits(new Rectangle(0, 0, 8, tall ? 16 : 8), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); var lockData = bmpViewDetails.BMP.LockBits(new Rectangle(0, 0, 8, tall ? 16 : 8), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
if (_cgb) if (_cgb)
{ {
sb.AppendLine($" Tile #{(y == 1 ? tilenum ^ 1 : tilenum)} @{(flags.Bit(3) ? 1 : 0)}:{tileoffs + 0x8000:x4}"); sb.AppendLine($" Tile #{(y == 1 ? tileNum ^ 1 : tileNum)} @{(flags.Bit(3) ? 1 : 0)}:{tileOffset + 0x8000:x4}");
sb.AppendLine($" Palette {flags & 7}"); sb.AppendLine($" Palette {flags & 7}");
DrawTileHv((byte*)_vram + tileoffs + (flags.Bit(3) ? 8192 : 0), (int*)lockdata.Scan0, lockdata.Stride / sizeof(int), (int*)_sppal + 4 * (flags & 7), hflip, vflip); DrawTileHv((byte*)vram + tileOffset + (flags.Bit(3) ? 8192 : 0), (int*)lockData.Scan0, lockData.Stride / sizeof(int), (int*)spPal + 4 * (flags & 7), hFlip, vFlip);
if (tall) if (tall)
DrawTileHv((byte*)_vram + (tileoffs ^ 16) + (flags.Bit(3) ? 8192 : 0), (int*)(lockdata.Scan0 + lockdata.Stride * 8), lockdata.Stride / sizeof(int), (int*)_sppal + 4 * (flags & 7), hflip, vflip); DrawTileHv((byte*)vram + (tileOffset ^ 16) + (flags.Bit(3) ? 8192 : 0), (int*)(lockData.Scan0 + lockData.Stride * 8), lockData.Stride / sizeof(int), (int*)spPal + 4 * (flags & 7), hFlip, vFlip);
} }
else else
{ {
sb.AppendLine($" Tile #{(y == 1 ? tilenum ^ 1 : tilenum)} @{tileoffs + 0x8000:x4}"); sb.AppendLine($" Tile #{(y == 1 ? tileNum ^ 1 : tileNum)} @{tileOffset + 0x8000:x4}");
sb.AppendLine($" Palette {(flags.Bit(4) ? 1 : 0)}"); sb.AppendLine($" Palette {(flags.Bit(4) ? 1 : 0)}");
DrawTileHv((byte*)_vram + tileoffs, (int*)lockdata.Scan0, lockdata.Stride / sizeof(int), (int*)_sppal + (flags.Bit(4) ? 4 : 0), hflip, vflip); DrawTileHv((byte*)vram + tileOffset, (int*)lockData.Scan0, lockData.Stride / sizeof(int), (int*)spPal + (flags.Bit(4) ? 4 : 0), hFlip, vFlip);
if (tall) if (tall)
DrawTileHv((byte*)_vram + (tileoffs ^ 16), (int*)(lockdata.Scan0 + lockdata.Stride * 8), lockdata.Stride / sizeof(int), (int*)_sppal + 4 * (flags.Bit(4) ? 4 : 0), hflip, vflip); DrawTileHv((byte*)vram + (tileOffset ^ 16), (int*)(lockData.Scan0 + lockData.Stride * 8), lockData.Stride / sizeof(int), (int*)spPal + 4 * (flags.Bit(4) ? 4 : 0), hFlip, vFlip);
} }
sb.AppendLine($" Flags {(hflip ? 'H' : ' ')}{(vflip ? 'V' : ' ')}{(flags.Bit(7) ? 'P' : ' ')}"); sb.AppendLine($" Flags {(hFlip ? 'H' : ' ')}{(vFlip ? 'V' : ' ')}{(flags.Bit(7) ? 'P' : ' ')}");
bmpViewDetails.BMP.UnlockBits(lockdata); bmpViewDetails.BMP.UnlockBits(lockData);
labelDetails.Text = sb.ToString(); labelDetails.Text = sb.ToString();
bmpViewDetails.Refresh(); bmpViewDetails.Refresh();
} }
@ -804,7 +800,7 @@ namespace BizHawk.Client.EmuHawk
private void bmpViewBG_MouseMove(object sender, MouseEventArgs e) private void bmpViewBG_MouseMove(object sender, MouseEventArgs e)
{ {
TilemapMouseover(e.X, e.Y, false); TileMapMouseover(e.X, e.Y, false);
} }
private void bmpViewWin_MouseEnter(object sender, EventArgs e) private void bmpViewWin_MouseEnter(object sender, EventArgs e)
@ -820,7 +816,7 @@ namespace BizHawk.Client.EmuHawk
private void bmpViewWin_MouseMove(object sender, MouseEventArgs e) private void bmpViewWin_MouseMove(object sender, MouseEventArgs e)
{ {
TilemapMouseover(e.X, e.Y, true); TileMapMouseover(e.X, e.Y, true);
} }
private void bmpViewTiles1_MouseEnter(object sender, EventArgs e) private void bmpViewTiles1_MouseEnter(object sender, EventArgs e)
@ -918,17 +914,17 @@ namespace BizHawk.Client.EmuHawk
else if (e.Button == MouseButtons.Left) else if (e.Button == MouseButtons.Left)
{ {
if (sender == bmpViewBGPal) if (sender == bmpViewBGPal)
tilespal = _memory.Bgpal + e.X / 16 * 16; _tilesPal = _memory.Bgpal + e.X / 16 * 16;
else if (sender == bmpViewSPPal) else if (sender == bmpViewSPPal)
tilespal = _memory.Sppal + e.X / 16 * 16; _tilesPal = _memory.Sppal + e.X / 16 * 16;
} }
} }
#region copyimage #region copyimage
private readonly Timer _messagetimer = new Timer(); private readonly Timer _messageTimer = new Timer();
private void GBGPUView_KeyDown(object sender, KeyEventArgs e) private void GbGpuView_KeyDown(object sender, KeyEventArgs e)
{ {
if (ModifierKeys.HasFlag(Keys.Control) && e.KeyCode == Keys.C) if (ModifierKeys.HasFlag(Keys.Control) && e.KeyCode == Keys.C)
{ {
@ -942,46 +938,39 @@ namespace BizHawk.Client.EmuHawk
top = found; top = found;
} while (found != null && found.HasChildren); } while (found != null && found.HasChildren);
if (found is BmpView) if (found is BmpView bv)
{ {
var bv = found as BmpView;
Clipboard.SetImage(bv.BMP); Clipboard.SetImage(bv.BMP);
labelClipboard.Text = $"{found.Text} copied to clipboard."; labelClipboard.Text = $"{bv.Text} copied to clipboard.";
_messagetimer.Stop(); _messageTimer.Stop();
_messagetimer.Start(); _messageTimer.Start();
}
} }
} }
} private void MessageTimer_Tick(object sender, EventArgs e)
void messagetimer_Tick(object sender, EventArgs e)
{ {
_messagetimer.Stop(); _messageTimer.Stop();
labelClipboard.Text = "CTRL+C copies the pane under the mouse."; labelClipboard.Text = "CTRL+C copies the pane under the mouse.";
} }
#endregion #endregion
private void GBGPUView_FormClosing(object sender, FormClosingEventArgs e) private void ButtonChangeColor_Click(object sender, EventArgs e)
{ {
} using var dlg = new ColorDialog
private void buttonChangeColor_Click(object sender, EventArgs e)
{ {
using (var dlg = new ColorDialog()) AllowFullOpen = true,
{ AnyColor = true,
dlg.AllowFullOpen = true; FullOpen = true,
dlg.AnyColor = true; Color = Spriteback
dlg.FullOpen = true; };
dlg.Color = Spriteback;
var result = dlg.ShowHawkDialog(); var result = dlg.ShowHawkDialog();
if (result == DialogResult.OK) if (result.IsOk())
{ {
Spriteback = dlg.Color; Spriteback = dlg.Color;
} }
} }
} }
} }
}

View File

@ -22,9 +22,9 @@ namespace BizHawk.Client.EmuHawk
private readonly Dictionary<char, int> _gameGenieTable = new Dictionary<char, int>(); private readonly Dictionary<char, int> _gameGenieTable = new Dictionary<char, int>();
private bool _processing; private bool _processing;
public bool AskSaveChanges() { return true; } public bool AskSaveChanges() => true;
public bool UpdateBefore { get { return false; } } public bool UpdateBefore => false;
public void Restart() public void Restart()
{ {
@ -140,7 +140,7 @@ namespace BizHawk.Client.EmuHawk
} }
} }
private string GBGGEncode(int val, int add, int cmp) private string GbGgEncode(int val, int add, int cmp)
{ {
char[] letters = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; char[] letters = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
string code = ""; string code = "";
@ -186,14 +186,9 @@ namespace BizHawk.Client.EmuHawk
addcheatbt.Enabled = false; addcheatbt.Enabled = false;
//"Game Boy/Game Gear Game Genie Encoder / Decoder" //"Game Boy/Game Gear Game Genie Encoder / Decoder"
if (Emulator.SystemId == "GB") Text = Emulator.SystemId == "GB"
{ ? "Game Boy Game Genie Encoder/Decoder"
Text = "Game Boy Game Genie Encoder/Decoder"; : "Game Gear Game Genie Encoder/Decoder";
}
else
{
Text = "Game Gear Game Genie Encoder/Decoder";
}
} }
#region Dialog and Control Events #region Dialog and Control Events
@ -300,7 +295,7 @@ namespace BizHawk.Client.EmuHawk
cmp = int.Parse(CompareBox.Text, NumberStyles.HexNumber); cmp = int.Parse(CompareBox.Text, NumberStyles.HexNumber);
} }
GGCodeMaskBox.Text = GBGGEncode(val, add, cmp); GGCodeMaskBox.Text = GbGgEncode(val, add, cmp);
addcheatbt.Enabled = true; addcheatbt.Enabled = true;
} }
else else
@ -346,7 +341,7 @@ namespace BizHawk.Client.EmuHawk
cmp = int.Parse(CompareBox.Text, NumberStyles.HexNumber); cmp = int.Parse(CompareBox.Text, NumberStyles.HexNumber);
} }
GGCodeMaskBox.Text = GBGGEncode(val, add, cmp); GGCodeMaskBox.Text = GbGgEncode(val, add, cmp);
addcheatbt.Enabled = true; addcheatbt.Enabled = true;
} }
else else
@ -391,7 +386,7 @@ namespace BizHawk.Client.EmuHawk
cmp = int.Parse(CompareBox.Text, NumberStyles.HexNumber); cmp = int.Parse(CompareBox.Text, NumberStyles.HexNumber);
} }
GGCodeMaskBox.Text = GBGGEncode(val, add, cmp); GGCodeMaskBox.Text = GbGgEncode(val, add, cmp);
addcheatbt.Enabled = true; addcheatbt.Enabled = true;
} }
else else

View File

@ -1,50 +1,44 @@
using System; using System;
using System.Drawing; using System.Drawing;
using System.Drawing.Imaging; using System.Drawing.Imaging;
using System.Text;
using System.Windows.Forms; using System.Windows.Forms;
using BizHawk.Common.NumberExtensions;
using BizHawk.Client.Common;
using BizHawk.Emulation.Cores.Nintendo.Gameboy;
using BizHawk.Client.EmuHawk.WinFormExtensions;
using System.Collections.Generic;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
using BizHawk.Emulation.Cores.Consoles.Nintendo.Gameboy; using BizHawk.Emulation.Cores.Consoles.Nintendo.Gameboy;
using BizHawk.Common;
namespace BizHawk.Client.EmuHawk namespace BizHawk.Client.EmuHawk
{ {
public partial class GBPrinterView : Form, IToolFormAutoConfig public partial class GBPrinterView : Form, IToolFormAutoConfig
{ {
const int PaperWidth = 160; private const int PaperWidth = 160;
// the bg color // the bg color
private static readonly uint PaperColor = (uint)Color.AntiqueWhite.ToArgb(); private static readonly uint PaperColor = (uint)Color.AntiqueWhite.ToArgb();
private ColorMatrix PaperAdjustment; private readonly ColorMatrix _paperAdjustment;
[RequiredService] [RequiredService]
public IGameboyCommon Gb { get; private set; } public IGameboyCommon Gb { get; private set; }
// If we've connected the printer yet // If we've connected the printer yet
bool connected = false; private bool _connected;
// the entire bitmap // the entire bitmap
Bitmap printerHistory; private Bitmap _printerHistory;
public GBPrinterView() public GBPrinterView()
{ {
InitializeComponent(); InitializeComponent();
// adjust the color of the printed output to be more papery // adjust the color of the printed output to be more papery
PaperAdjustment = new ColorMatrix(); _paperAdjustment = new ColorMatrix
PaperAdjustment.Matrix00 = (0xFA - 0x10) / 255F; {
PaperAdjustment.Matrix40 = 0x10 / 255F; Matrix00 = (0xFA - 0x10) / 255F,
PaperAdjustment.Matrix11 = (0xEB - 0x10) / 255F; Matrix40 = 0x10 / 255F,
PaperAdjustment.Matrix41 = 0x10 / 255F; Matrix11 = (0xEB - 0x10) / 255F,
PaperAdjustment.Matrix22 = (0xD7 - 0x18) / 255F; Matrix41 = 0x10 / 255F,
PaperAdjustment.Matrix42 = 0x18 / 255F; Matrix22 = (0xD7 - 0x18) / 255F,
Matrix42 = 0x18 / 255F
};
paperView.ChangeBitmapSize(PaperWidth, PaperWidth); paperView.ChangeBitmapSize(PaperWidth, PaperWidth);
@ -53,10 +47,7 @@ namespace BizHawk.Client.EmuHawk
private void GBPrinterView_FormClosed(object sender, FormClosedEventArgs e) private void GBPrinterView_FormClosed(object sender, FormClosedEventArgs e)
{ {
if (Gb != null) Gb?.SetPrinterCallback(null);
{
Gb.SetPrinterCallback(null);
}
} }
public bool UpdateBefore => false; public bool UpdateBefore => false;
@ -73,35 +64,32 @@ namespace BizHawk.Client.EmuHawk
public void Restart() public void Restart()
{ {
// Really, there's not necessarilly a reason to clear it at all, // Really, there's not necessarily a reason to clear it at all,
// since the paper would still be there, // since the paper would still be there,
// but it just seems right to get a blank slate on reset. // but it just seems right to get a blank slate on reset.
ClearPaper(); ClearPaper();
_connected = false;
connected = false;
} }
public void UpdateValues() public void UpdateValues()
{ {
// Automatically connect once the game is running // Automatically connect once the game is running
if (!connected) if (!_connected)
{ {
Gb.SetPrinterCallback(OnPrint); Gb.SetPrinterCallback(OnPrint);
connected = true; _connected = true;
} }
} }
/// <summary> // The printer callback that . See PrinterCallback for details.
/// The printer callback that . See PrinterCallback for details. private void OnPrint(IntPtr image, byte height, byte topMargin, byte bottomMargin, byte exposure)
/// </summary>
void OnPrint(IntPtr image, byte height, byte topMargin, byte bottomMargin, byte exposure)
{ {
// In this implementation: // In this implementation:
// the bottom margin and top margin are just white lines at the top and bottom // the bottom margin and top margin are just white lines at the top and bottom
// exposure is ignored // exposure is ignored
// The page received image // The page received image
Bitmap page = new Bitmap(PaperWidth, height); var page = new Bitmap(PaperWidth, height);
var bmp = page.LockBits(new Rectangle(0, 0, PaperWidth, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); var bmp = page.LockBits(new Rectangle(0, 0, PaperWidth, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
@ -123,17 +111,18 @@ namespace BizHawk.Client.EmuHawk
page.UnlockBits(bmp); page.UnlockBits(bmp);
// add it to the bottom of the history // add it to the bottom of the history
int oldHeight = printerHistory.Height; int oldHeight = _printerHistory.Height;
ResizeHistory(printerHistory.Height + page.Height + topMargin + bottomMargin); ResizeHistory(_printerHistory.Height + page.Height + topMargin + bottomMargin);
using (var g = Graphics.FromImage(printerHistory)) using (var g = Graphics.FromImage(_printerHistory))
{ {
// Make it brown // Make it brown
ImageAttributes a = new ImageAttributes(); var a = new ImageAttributes();
a.SetColorMatrix(PaperAdjustment); a.SetColorMatrix(_paperAdjustment);
g.DrawImage(page, new Rectangle(0, oldHeight + topMargin, page.Width, page.Height), 0F, 0F, page.Width, page.Height, GraphicsUnit.Pixel, a); g.DrawImage(page, new Rectangle(0, oldHeight + topMargin, page.Width, page.Height), 0F, 0F, page.Width, page.Height, GraphicsUnit.Pixel, a);
g.Flush(); g.Flush();
} }
RefreshView(); RefreshView();
} }
@ -144,44 +133,46 @@ namespace BizHawk.Client.EmuHawk
/// <param name="x">X position</param> /// <param name="x">X position</param>
/// <param name="y">Y position</param> /// <param name="y">Y position</param>
/// <param name="c">The ARGB color to set that pixel to</param> /// <param name="c">The ARGB color to set that pixel to</param>
unsafe void SetPixel(BitmapData bmp, int x, int y, uint c) private unsafe void SetPixel(BitmapData bmp, int x, int y, uint c)
{ {
uint* pixel = (uint*)(bmp.Scan0 + x * 4 + y * bmp.Stride); uint* pixel = (uint*)(bmp.Scan0 + x * 4 + y * bmp.Stride);
*pixel = c; *pixel = c;
} }
void ClearPaper() private void ClearPaper()
{ {
ResizeHistory(8); ResizeHistory(8);
RefreshView(); RefreshView();
} }
void ResizeHistory(int height) private void ResizeHistory(int height)
{ {
// copy to a new image of height // copy to a new image of height
var newHistory = new Bitmap(PaperWidth, height); var newHistory = new Bitmap(PaperWidth, height);
using (var g = Graphics.FromImage(newHistory)) using (var g = Graphics.FromImage(newHistory))
{ {
g.Clear(Color.FromArgb((int)PaperColor)); g.Clear(Color.FromArgb((int)PaperColor));
if (printerHistory != null) if (_printerHistory != null)
g.DrawImage(printerHistory, Point.Empty); {
g.DrawImage(_printerHistory, Point.Empty);
}
g.Flush(); g.Flush();
} }
if (printerHistory != null) _printerHistory?.Dispose();
printerHistory.Dispose(); _printerHistory = newHistory;
printerHistory = newHistory;
// Update scrollbar, viewport is a square // Update scrollbar, viewport is a square
paperScroll.Maximum = Math.Max(0, height); paperScroll.Maximum = Math.Max(0, height);
} }
void RefreshView() private void RefreshView()
{ {
using (Graphics g = Graphics.FromImage(paperView.BMP)) using (var g = Graphics.FromImage(paperView.BMP))
{ {
g.Clear(Color.FromArgb((int)PaperColor)); g.Clear(Color.FromArgb((int)PaperColor));
g.DrawImage(printerHistory, new Point(0, -paperScroll.Value)); g.DrawImage(_printerHistory, new Point(0, -paperScroll.Value));
g.Flush(); g.Flush();
} }
@ -193,10 +184,10 @@ namespace BizHawk.Client.EmuHawk
// slight hack to use the nice SaveFile() feature of a BmpView // slight hack to use the nice SaveFile() feature of a BmpView
BmpView toSave = new BmpView(); BmpView toSave = new BmpView();
toSave.ChangeBitmapSize(printerHistory.Size); toSave.ChangeBitmapSize(_printerHistory.Size);
using (var g = Graphics.FromImage(toSave.BMP)) using (var g = Graphics.FromImage(toSave.BMP))
{ {
g.DrawImage(printerHistory, Point.Empty); g.DrawImage(_printerHistory, Point.Empty);
g.Flush(); g.Flush();
} }
toSave.SaveFile(); toSave.SaveFile();
@ -204,10 +195,10 @@ namespace BizHawk.Client.EmuHawk
private void copyToolStripMenuItem_Click(object sender, EventArgs e) private void copyToolStripMenuItem_Click(object sender, EventArgs e)
{ {
Clipboard.SetImage(printerHistory); Clipboard.SetImage(_printerHistory);
} }
private void PaperScroll_ValueChanged(object sender, System.EventArgs e) private void PaperScroll_ValueChanged(object sender, EventArgs e)
{ {
RefreshView(); RefreshView();
} }

View File

@ -1,6 +1,6 @@
namespace BizHawk.Client.EmuHawk namespace BizHawk.Client.EmuHawk
{ {
partial class GBAGPUView partial class GbaGpuView
{ {
/// <summary> /// <summary>
/// Required designer variable. /// Required designer variable.
@ -177,13 +177,12 @@
this.Icon = global::BizHawk.Client.EmuHawk.Properties.Resources.gba_MultiSize.Value; this.Icon = global::BizHawk.Client.EmuHawk.Properties.Resources.gba_MultiSize.Value;
this.KeyPreview = true; this.KeyPreview = true;
this.MainMenuStrip = this.menuStrip1; this.MainMenuStrip = this.menuStrip1;
this.Name = "GBAGPUView"; this.Name = "GbaGpuView";
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Show; this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Show;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "GBA GPU Viewer"; this.Text = "GBA GPU Viewer";
this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.GBAGPUView_FormClosed); this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.GbaGpuView_FormClosed);
this.Load += new System.EventHandler(this.GBAGPUView_Load); this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.GbaGpuView_KeyDown);
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.GBAGPUView_KeyDown);
this.groupBox1.ResumeLayout(false); this.groupBox1.ResumeLayout(false);
this.groupBox1.PerformLayout(); this.groupBox1.PerformLayout();
this.ResumeLayout(false); this.ResumeLayout(false);

View File

@ -1,47 +1,45 @@
using System; using System;
using System.Drawing; using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms; using System.Windows.Forms;
using BizHawk.Common.NumberExtensions; using BizHawk.Common.NumberExtensions;
using BizHawk.Client.Common;
using BizHawk.Emulation.Cores.Nintendo.Gameboy; using BizHawk.Emulation.Cores.Nintendo.Gameboy;
using BizHawk.Emulation.Cores.Nintendo.GBA; using BizHawk.Emulation.Cores.Nintendo.GBA;
using System.Collections.Generic;
using BizHawk.Common; using BizHawk.Common;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
namespace BizHawk.Client.EmuHawk namespace BizHawk.Client.EmuHawk
{ {
public partial class GBAGPUView : Form, IToolFormAutoConfig public partial class GbaGpuView : Form, IToolFormAutoConfig
{ {
[RequiredService] [RequiredService]
IGBAGPUViewable gba { get; set; } private IGBAGPUViewable GBA { get; set; }
// emulator memory areas // emulator memory areas
private IntPtr vram; private IntPtr _vram;
private IntPtr oam; private IntPtr _oam;
private IntPtr mmio; private IntPtr _mmio;
private IntPtr palram; private IntPtr _palRam;
// color conversion to RGB888 // color conversion to RGB888
private readonly int[] ColorConversion; private readonly int[] _colorConversion;
MobileBmpView bg0, bg1, bg2, bg3, bgpal, sppal, sprites, bgtiles16, bgtiles256, sptiles16, sptiles256; private MobileBmpView _bg0, _bg1, _bg2, _bg3, _bgPal, _spPal, _sprites, _bgTiles16, _bgTiles256, _spTiles16, _spTiles256;
// MobileDetailView memory; // MobileDetailView memory;
public bool AskSaveChanges() { return true; } public bool AskSaveChanges() => true;
public bool UpdateBefore { get { return true; } } public bool UpdateBefore => true;
public GBAGPUView() public GbaGpuView()
{ {
InitializeComponent(); InitializeComponent();
// TODO: hook up something // TODO: hook up something
// we do this twice to avoid having to & 0x7fff with every color // we do this twice to avoid having to & 0x7fff with every color
int[] tmp = GBColors.GetLut(GBColors.ColorType.vivid); int[] tmp = GBColors.GetLut(GBColors.ColorType.vivid);
ColorConversion = new int[65536]; _colorConversion = new int[65536];
Buffer.BlockCopy(tmp, 0, ColorConversion, 0, sizeof(int) * tmp.Length); Buffer.BlockCopy(tmp, 0, _colorConversion, 0, sizeof(int) * tmp.Length);
Buffer.BlockCopy(tmp, 0, ColorConversion, sizeof(int) * tmp.Length, sizeof(int) * tmp.Length); Buffer.BlockCopy(tmp, 0, _colorConversion, sizeof(int) * tmp.Length, sizeof(int) * tmp.Length);
radioButtonManual.Checked = true; radioButtonManual.Checked = true;
GenerateWidgets(); GenerateWidgets();
hScrollBar1_ValueChanged(null, null); hScrollBar1_ValueChanged(null, null);
@ -50,22 +48,22 @@ namespace BizHawk.Client.EmuHawk
#region drawing primitives #region drawing primitives
unsafe void DrawTile256(int* dest, int pitch, byte* tile, ushort* palette, bool hflip, bool vflip) private unsafe void DrawTile256(int* dest, int pitch, byte* tile, ushort* palette, bool hFlip, bool vFlip)
{ {
if (vflip) if (vFlip)
{ {
dest += pitch * 7; dest += pitch * 7;
pitch = -pitch; pitch = -pitch;
} }
if (hflip) if (hFlip)
{ {
dest += 7; dest += 7;
for (int y = 0; y < 8; y++) for (int y = 0; y < 8; y++)
{ {
for (int x = 0; x < 8; x++) for (int x = 0; x < 8; x++)
{ {
*dest-- = ColorConversion[palette[*tile++]]; *dest-- = _colorConversion[palette[*tile++]];
} }
dest += 8; dest += 8;
dest += pitch; dest += pitch;
@ -77,7 +75,7 @@ namespace BizHawk.Client.EmuHawk
{ {
for (int x = 0; x < 8; x++) for (int x = 0; x < 8; x++)
{ {
*dest++ = ColorConversion[palette[*tile++]]; *dest++ = _colorConversion[palette[*tile++]];
} }
dest -= 8; dest -= 8;
dest += pitch; dest += pitch;
@ -85,22 +83,22 @@ namespace BizHawk.Client.EmuHawk
} }
} }
unsafe void DrawTile16(int* dest, int pitch, byte* tile, ushort* palette, bool hflip, bool vflip) private unsafe void DrawTile16(int* dest, int pitch, byte* tile, ushort* palette, bool hFlip, bool vFlip)
{ {
if (vflip) if (vFlip)
{ {
dest += pitch * 7; dest += pitch * 7;
pitch = -pitch; pitch = -pitch;
} }
if (hflip) if (hFlip)
{ {
dest += 7; dest += 7;
for (int y = 0; y < 8; y++) for (int y = 0; y < 8; y++)
{ {
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
{ {
*dest-- = ColorConversion[palette[*tile & 15]]; *dest-- = _colorConversion[palette[*tile & 15]];
*dest-- = ColorConversion[palette[*tile >> 4]]; *dest-- = _colorConversion[palette[*tile >> 4]];
tile++; tile++;
} }
dest += 8; dest += 8;
@ -113,8 +111,8 @@ namespace BizHawk.Client.EmuHawk
{ {
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
{ {
*dest++ = ColorConversion[palette[*tile & 15]]; *dest++ = _colorConversion[palette[*tile & 15]];
*dest++ = ColorConversion[palette[*tile >> 4]]; *dest++ = _colorConversion[palette[*tile >> 4]];
tile++; tile++;
} }
dest -= 8; dest -= 8;
@ -130,7 +128,7 @@ namespace BizHawk.Client.EmuHawk
for (int tx = 0; tx < 32; tx++) for (int tx = 0; tx < 32; tx++)
{ {
ushort ntent = *nametable++; ushort ntent = *nametable++;
DrawTile16(dest, pitch, tiles + (ntent & 1023) * 32, (ushort*)palram + (ntent >> 12 << 4), ntent.Bit(10), ntent.Bit(11)); DrawTile16(dest, pitch, tiles + (ntent & 1023) * 32, (ushort*)_palRam + (ntent >> 12 << 4), ntent.Bit(10), ntent.Bit(11));
dest += 8; dest += 8;
} }
dest -= 256; dest -= 256;
@ -145,7 +143,7 @@ namespace BizHawk.Client.EmuHawk
for (int tx = 0; tx < 32; tx++) for (int tx = 0; tx < 32; tx++)
{ {
ushort ntent = *nametable++; ushort ntent = *nametable++;
DrawTile256(dest, pitch, tiles + (ntent & 1023) * 64, (ushort*)palram, ntent.Bit(10), ntent.Bit(11)); DrawTile256(dest, pitch, tiles + (ntent & 1023) * 64, (ushort*)_palRam, ntent.Bit(10), ntent.Bit(11));
dest += 8; dest += 8;
} }
dest -= 256; dest -= 256;
@ -163,7 +161,7 @@ namespace BizHawk.Client.EmuHawk
unsafe void DrawTextBG(int n, MobileBmpView mbv) unsafe void DrawTextBG(int n, MobileBmpView mbv)
{ {
ushort bgcnt = ((ushort*)mmio)[4 + n]; ushort bgcnt = ((ushort*)_mmio)[4 + n];
int ssize = bgcnt >> 14; int ssize = bgcnt >> 14;
switch (ssize) switch (ssize)
{ {
@ -173,56 +171,56 @@ namespace BizHawk.Client.EmuHawk
case 3: mbv.ChangeAllSizes(512, 512); break; case 3: mbv.ChangeAllSizes(512, 512); break;
} }
Bitmap bmp = mbv.BmpView.BMP; Bitmap bmp = mbv.BmpView.BMP;
var lockdata = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); var lockData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
int* pixels = (int*)lockdata.Scan0; int* pixels = (int*)lockData.Scan0;
int pitch = lockdata.Stride / sizeof(int); int pitch = lockData.Stride / sizeof(int);
byte* tiles = (byte*)vram + ((bgcnt & 0xc) << 12); byte* tiles = (byte*)_vram + ((bgcnt & 0xc) << 12);
ushort* nametable = (ushort*)vram + ((bgcnt & 0x1f00) << 2); ushort* nametable = (ushort*)_vram + ((bgcnt & 0x1f00) << 2);
bool eightbit = bgcnt.Bit(7); bool eighthBit = bgcnt.Bit(7);
switch (ssize) switch (ssize)
{ {
case 0: case 0:
DrawTextNameTable(pixels, pitch, nametable, tiles, eightbit); DrawTextNameTable(pixels, pitch, nametable, tiles, eighthBit);
break; break;
case 1: case 1:
DrawTextNameTable(pixels, pitch, nametable, tiles, eightbit); DrawTextNameTable(pixels, pitch, nametable, tiles, eighthBit);
pixels += 256; pixels += 256;
nametable += 1024; nametable += 1024;
DrawTextNameTable(pixels, pitch, nametable, tiles, eightbit); DrawTextNameTable(pixels, pitch, nametable, tiles, eighthBit);
break; break;
case 2: case 2:
DrawTextNameTable(pixels, pitch, nametable, tiles, eightbit); DrawTextNameTable(pixels, pitch, nametable, tiles, eighthBit);
pixels += pitch * 256; pixels += pitch * 256;
nametable += 1024; nametable += 1024;
DrawTextNameTable(pixels, pitch, nametable, tiles, eightbit); DrawTextNameTable(pixels, pitch, nametable, tiles, eighthBit);
break; break;
case 3: case 3:
DrawTextNameTable(pixels, pitch, nametable, tiles, eightbit); DrawTextNameTable(pixels, pitch, nametable, tiles, eighthBit);
pixels += 256; pixels += 256;
nametable += 1024; nametable += 1024;
DrawTextNameTable(pixels, pitch, nametable, tiles, eightbit); DrawTextNameTable(pixels, pitch, nametable, tiles, eighthBit);
pixels -= 256; pixels -= 256;
pixels += pitch * 256; pixels += pitch * 256;
nametable += 1024; nametable += 1024;
DrawTextNameTable(pixels, pitch, nametable, tiles, eightbit); DrawTextNameTable(pixels, pitch, nametable, tiles, eighthBit);
pixels += 256; pixels += 256;
nametable += 1024; nametable += 1024;
DrawTextNameTable(pixels, pitch, nametable, tiles, eightbit); DrawTextNameTable(pixels, pitch, nametable, tiles, eighthBit);
break; break;
} }
bmp.UnlockBits(lockdata); bmp.UnlockBits(lockData);
mbv.BmpView.Refresh(); mbv.BmpView.Refresh();
} }
unsafe void DrawAffineBG(int n, MobileBmpView mbv) unsafe void DrawAffineBG(int n, MobileBmpView mbv)
{ {
ushort bgcnt = ((ushort*)mmio)[4 + n]; ushort bgcnt = ((ushort*)_mmio)[4 + n];
int ssize = bgcnt >> 14; int ssize = bgcnt >> 14;
switch (ssize) switch (ssize)
{ {
@ -232,27 +230,27 @@ namespace BizHawk.Client.EmuHawk
case 3: mbv.ChangeAllSizes(1024, 1024); break; case 3: mbv.ChangeAllSizes(1024, 1024); break;
} }
Bitmap bmp = mbv.BmpView.BMP; Bitmap bmp = mbv.BmpView.BMP;
var lockdata = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); var lockData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
int* pixels = (int*)lockdata.Scan0; int* pixels = (int*)lockData.Scan0;
int pitch = lockdata.Stride / sizeof(int); int pitch = lockData.Stride / sizeof(int);
byte* tiles = (byte*)vram + ((bgcnt & 0xc) << 12); byte* tiles = (byte*)_vram + ((bgcnt & 0xc) << 12);
byte* nametable = (byte*)vram + ((bgcnt & 0x1f00) << 3); byte* nametable = (byte*)_vram + ((bgcnt & 0x1f00) << 3);
for (int ty = 0; ty < bmp.Height / 8; ty++) for (int ty = 0; ty < bmp.Height / 8; ty++)
{ {
for (int tx = 0; tx < bmp.Width / 8; tx++) for (int tx = 0; tx < bmp.Width / 8; tx++)
{ {
DrawTile256(pixels, pitch, tiles + *nametable++ * 64, (ushort*)palram, false, false); DrawTile256(pixels, pitch, tiles + *nametable++ * 64, (ushort*)_palRam, false, false);
pixels += 8; pixels += 8;
} }
pixels -= bmp.Width; pixels -= bmp.Width;
pixels += 8 * pitch; pixels += 8 * pitch;
} }
bmp.UnlockBits(lockdata); bmp.UnlockBits(lockData);
mbv.BmpView.Refresh(); mbv.BmpView.Refresh();
} }
@ -260,73 +258,79 @@ namespace BizHawk.Client.EmuHawk
{ {
mbv.ChangeAllSizes(240, 160); mbv.ChangeAllSizes(240, 160);
Bitmap bmp = mbv.BmpView.BMP; Bitmap bmp = mbv.BmpView.BMP;
var lockdata = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); var lockData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
int* pixels = (int*)lockdata.Scan0; int* pixels = (int*)lockData.Scan0;
int pitch = lockdata.Stride / sizeof(int); int pitch = lockData.Stride / sizeof(int);
ushort* frame = (ushort*)vram; ushort* frame = (ushort*)_vram;
for (int y = 0; y < 160; y++) for (int y = 0; y < 160; y++)
{ {
for (int x = 0; x < 240; x++) for (int x = 0; x < 240; x++)
*pixels++ = ColorConversion[*frame++]; {
*pixels++ = _colorConversion[*frame++];
}
pixels -= 240; pixels -= 240;
pixels += pitch; pixels += pitch;
} }
bmp.UnlockBits(lockdata); bmp.UnlockBits(lockData);
mbv.BmpView.Refresh(); mbv.BmpView.Refresh();
} }
unsafe void DrawM4BG(MobileBmpView mbv, bool secondframe) unsafe void DrawM4BG(MobileBmpView mbv, bool secondFrame)
{ {
mbv.ChangeAllSizes(240, 160); mbv.ChangeAllSizes(240, 160);
Bitmap bmp = mbv.BmpView.BMP; Bitmap bmp = mbv.BmpView.BMP;
var lockdata = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); var lockData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
int* pixels = (int*)lockdata.Scan0; int* pixels = (int*)lockData.Scan0;
int pitch = lockdata.Stride / sizeof(int); int pitch = lockData.Stride / sizeof(int);
byte* frame = (byte*)vram + (secondframe ? 40960 : 0); byte* frame = (byte*)_vram + (secondFrame ? 40960 : 0);
ushort* palette = (ushort*)palram; ushort* palette = (ushort*)_palRam;
for (int y = 0; y < 160; y++) for (int y = 0; y < 160; y++)
{ {
for (int x = 0; x < 240; x++) for (int x = 0; x < 240; x++)
*pixels++ = ColorConversion[palette[*frame++]]; {
*pixels++ = _colorConversion[palette[*frame++]];
}
pixels -= 240; pixels -= 240;
pixels += pitch; pixels += pitch;
} }
bmp.UnlockBits(lockdata); bmp.UnlockBits(lockData);
mbv.BmpView.Refresh(); mbv.BmpView.Refresh();
} }
unsafe void DrawM5BG(MobileBmpView mbv, bool secondframe) unsafe void DrawM5BG(MobileBmpView mbv, bool secondFrame)
{ {
mbv.ChangeAllSizes(160, 128); mbv.ChangeAllSizes(160, 128);
Bitmap bmp = mbv.BmpView.BMP; Bitmap bmp = mbv.BmpView.BMP;
var lockdata = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); var lockData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
int* pixels = (int*)lockdata.Scan0; int* pixels = (int*)lockData.Scan0;
int pitch = lockdata.Stride / sizeof(int); int pitch = lockData.Stride / sizeof(int);
ushort* frame = (ushort*)vram + (secondframe ? 20480 : 0); ushort* frame = (ushort*)_vram + (secondFrame ? 20480 : 0);
for (int y = 0; y < 128; y++) for (int y = 0; y < 128; y++)
{ {
for (int x = 0; x < 160; x++) for (int x = 0; x < 160; x++)
*pixels++ = ColorConversion[*frame++]; *pixels++ = _colorConversion[*frame++];
pixels -= 160; pixels -= 160;
pixels += pitch; pixels += pitch;
} }
bmp.UnlockBits(lockdata); bmp.UnlockBits(lockData);
mbv.BmpView.Refresh(); mbv.BmpView.Refresh();
} }
static readonly int[, ,] spritesizes = { { { 1, 1 }, { 2, 2 }, { 4, 4 }, { 8, 8 } }, { { 2, 1 }, { 4, 1 }, { 4, 2 }, { 8, 4 } }, { { 1, 2 }, { 1, 4 }, { 2, 4 }, { 4, 8 } } }; private static readonly int[, ,] SpriteSizes = { { { 1, 1 }, { 2, 2 }, { 4, 4 }, { 8, 8 } }, { { 2, 1 }, { 4, 1 }, { 4, 2 }, { 8, 4 } }, { { 1, 2 }, { 1, 4 }, { 2, 4 }, { 4, 8 } } };
unsafe void DrawSprite(int* dest, int pitch, ushort* sprite, byte* tiles, bool twodee) unsafe void DrawSprite(int* dest, int pitch, ushort* sprite, byte* tiles, bool twodee)
{ {
@ -341,67 +345,67 @@ namespace BizHawk.Client.EmuHawk
if (shape == 3) if (shape == 3)
return; return;
int size = attr1 >> 14; int size = attr1 >> 14;
int tw = spritesizes[shape, size, 0]; int tw = SpriteSizes[shape, size, 0];
int th = spritesizes[shape, size, 1]; int th = SpriteSizes[shape, size, 1];
bool eightbit = attr0.Bit(13); bool eighthBit = attr0.Bit(13);
bool hflip = attr1.Bit(12); bool hFlip = attr1.Bit(12);
bool vflip = attr1.Bit(13); bool vFlip = attr1.Bit(13);
ushort* palette = (ushort*)palram + 256; ushort* palette = (ushort*)_palRam + 256;
if (!eightbit) if (!eighthBit)
palette += attr2 >> 12 << 4; palette += attr2 >> 12 << 4;
int tileindex = eightbit ? attr2 & 1022 : attr2 & 1023; int tileIndex = eighthBit ? attr2 & 1022 : attr2 & 1023;
int tilestride = twodee ? 1024 - tw * (eightbit ? 64 : 32) : 0; int tileStride = twodee ? 1024 - tw * (eighthBit ? 64 : 32) : 0;
// see if the sprite would read past the end of vram, and skip it if it would // see if the sprite would read past the end of vram, and skip it if it would
{ {
int tileend; int tileEnd;
if (!twodee) if (!twodee)
tileend = tileindex + tw * th * (eightbit ? 2 : 1); tileEnd = tileIndex + tw * th * (eighthBit ? 2 : 1);
else else
tileend = tileindex + tw * (eightbit ? 2 : 1) + (th - 1) * 32; tileEnd = tileIndex + tw * (eighthBit ? 2 : 1) + (th - 1) * 32;
if (tileend > 1024) if (tileEnd > 1024)
return; return;
} }
tiles += 32 * tileindex; tiles += 32 * tileIndex;
if (vflip) if (vFlip)
dest += pitch * 8 * (th - 1); dest += pitch * 8 * (th - 1);
if (hflip) if (hFlip)
dest += 8 * (tw - 1); dest += 8 * (tw - 1);
for (int ty = 0; ty < th; ty++) for (int ty = 0; ty < th; ty++)
{ {
for (int tx = 0; tx < tw; tx++) for (int tx = 0; tx < tw; tx++)
{ {
if (eightbit) if (eighthBit)
{ {
DrawTile256(dest, pitch, tiles, palette, hflip, vflip); DrawTile256(dest, pitch, tiles, palette, hFlip, vFlip);
tiles += 64; tiles += 64;
} }
else else
{ {
DrawTile16(dest, pitch, tiles, palette, hflip, vflip); DrawTile16(dest, pitch, tiles, palette, hFlip, vFlip);
tiles += 32; tiles += 32;
} }
if (hflip) if (hFlip)
dest -= 8; dest -= 8;
else else
dest += 8; dest += 8;
} }
if (hflip) if (hFlip)
dest += tw * 8; dest += tw * 8;
else else
dest -= tw * 8; dest -= tw * 8;
if (vflip) if (vFlip)
dest -= pitch * 8; dest -= pitch * 8;
else else
dest += pitch * 8; dest += pitch * 8;
tiles += tilestride; tiles += tileStride;
} }
} }
@ -409,17 +413,17 @@ namespace BizHawk.Client.EmuHawk
{ {
mbv.BmpView.ChangeBitmapSize(1024, 512); mbv.BmpView.ChangeBitmapSize(1024, 512);
Bitmap bmp = mbv.BmpView.BMP; Bitmap bmp = mbv.BmpView.BMP;
var lockdata = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); var lockData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
// Clear()
Win32Imports.MemSet(lockdata.Scan0, 0xff, (uint)(lockdata.Height * lockdata.Stride));
int* pixels = (int*)lockdata.Scan0; Win32Imports.MemSet(lockData.Scan0, 0xff, (uint)(lockData.Height * lockData.Stride));
int pitch = lockdata.Stride / sizeof(int);
ushort* sprites = (ushort*)oam; int* pixels = (int*)lockData.Scan0;
byte* tiles = (byte*)vram + 65536; int pitch = lockData.Stride / sizeof(int);
ushort dispcnt = ((ushort*)mmio)[0]; ushort* sprites = (ushort*)_oam;
byte* tiles = (byte*)_vram + 65536;
ushort dispcnt = ((ushort*)_mmio)[0];
bool twodee = !dispcnt.Bit(6); bool twodee = !dispcnt.Bit(6);
for (int sy = 0; sy < 8; sy++) for (int sy = 0; sy < 8; sy++)
@ -434,7 +438,7 @@ namespace BizHawk.Client.EmuHawk
pixels += pitch * 64; pixels += pitch * 64;
} }
bmp.UnlockBits(lockdata); bmp.UnlockBits(lockData);
mbv.BmpView.Refresh(); mbv.BmpView.Refresh();
} }
@ -442,22 +446,22 @@ namespace BizHawk.Client.EmuHawk
{ {
mbv.BmpView.ChangeBitmapSize(16, 16); mbv.BmpView.ChangeBitmapSize(16, 16);
Bitmap bmp = mbv.BmpView.BMP; Bitmap bmp = mbv.BmpView.BMP;
var lockdata = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); var lockData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
int* pixels = (int*)lockdata.Scan0; int* pixels = (int*)lockData.Scan0;
int pitch = lockdata.Stride / sizeof(int); int pitch = lockData.Stride / sizeof(int);
ushort* palette = (ushort*)palram + (sprite ? 256 : 0); ushort* palette = (ushort*)_palRam + (sprite ? 256 : 0);
for (int j = 0; j < 16; j++) for (int j = 0; j < 16; j++)
{ {
for (int i = 0; i < 16; i++) for (int i = 0; i < 16; i++)
*pixels++ = ColorConversion[*palette++]; *pixels++ = _colorConversion[*palette++];
pixels -= 16; pixels -= 16;
pixels += pitch; pixels += pitch;
} }
bmp.UnlockBits(lockdata); bmp.UnlockBits(lockData);
mbv.BmpView.Refresh(); mbv.BmpView.Refresh();
} }
@ -492,23 +496,23 @@ namespace BizHawk.Client.EmuHawk
mbv.BmpView.ChangeBitmapSize(tw * 8, 256); mbv.BmpView.ChangeBitmapSize(tw * 8, 256);
Bitmap bmp = mbv.BmpView.BMP; Bitmap bmp = mbv.BmpView.BMP;
var lockdata = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); var lockData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
int* pixels = (int*)lockdata.Scan0; int* pixels = (int*)lockData.Scan0;
int pitch = lockdata.Stride / sizeof(int); int pitch = lockData.Stride / sizeof(int);
byte* tiles = (byte*)vram + 65536; byte* tiles = (byte*)_vram + 65536;
// TODO: palette changing (in 4 bit mode anyway) // TODO: palette changing (in 4 bit mode anyway)
ushort* palette = (ushort*)palram + 256; ushort* palette = (ushort*)_palRam + 256;
if (tophalfonly) if (tophalfonly)
{ {
Win32Imports.MemSet(lockdata.Scan0, 0xff, (uint)(128 * lockdata.Stride)); Win32Imports.MemSet(lockData.Scan0, 0xff, (uint)(128 * lockData.Stride));
pixels += 128 * pitch; pixels += 128 * pitch;
tiles += 16384; tiles += 16384;
} }
DrawTileRange(pixels, pitch, tiles, palette, tw, th, eightbit); DrawTileRange(pixels, pitch, tiles, palette, tw, th, eightbit);
bmp.UnlockBits(lockdata); bmp.UnlockBits(lockData);
mbv.BmpView.Refresh(); mbv.BmpView.Refresh();
} }
@ -519,16 +523,16 @@ namespace BizHawk.Client.EmuHawk
mbv.BmpView.ChangeBitmapSize(tw * 8, th * 8); mbv.BmpView.ChangeBitmapSize(tw * 8, th * 8);
Bitmap bmp = mbv.BmpView.BMP; Bitmap bmp = mbv.BmpView.BMP;
var lockdata = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); var lockData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
int* pixels = (int*)lockdata.Scan0; int* pixels = (int*)lockData.Scan0;
int pitch = lockdata.Stride / sizeof(int); int pitch = lockData.Stride / sizeof(int);
byte* tiles = (byte*)vram; byte* tiles = (byte*)_vram;
// TODO: palette changing (in 4 bit mode anyway) // TODO: palette changing (in 4 bit mode anyway)
ushort* palette = (ushort*)palram; ushort* palette = (ushort*)_palRam;
DrawTileRange(pixels, pitch, tiles, palette, tw, th, eightbit); DrawTileRange(pixels, pitch, tiles, palette, tw, th, eightbit);
bmp.UnlockBits(lockdata); bmp.UnlockBits(lockData);
mbv.BmpView.Refresh(); mbv.BmpView.Refresh();
} }
@ -537,98 +541,97 @@ namespace BizHawk.Client.EmuHawk
unsafe void DrawEverything() unsafe void DrawEverything()
{ {
ushort dispcnt = ((ushort*)mmio)[0]; ushort dispcnt = ((ushort*)_mmio)[0];
int bgmode = dispcnt & 7; int bgMode = dispcnt & 7;
switch (bgmode) switch (bgMode)
{ {
case 0: case 0:
if (bg0.ShouldDraw) DrawTextBG(0, bg0); if (_bg0.ShouldDraw) DrawTextBG(0, _bg0);
if (bg1.ShouldDraw) DrawTextBG(1, bg1); if (_bg1.ShouldDraw) DrawTextBG(1, _bg1);
if (bg2.ShouldDraw) DrawTextBG(2, bg2); if (_bg2.ShouldDraw) DrawTextBG(2, _bg2);
if (bg3.ShouldDraw) DrawTextBG(3, bg3); if (_bg3.ShouldDraw) DrawTextBG(3, _bg3);
if (bgtiles16.ShouldDraw) DrawBGTiles(bgtiles16, false); if (_bgTiles16.ShouldDraw) DrawBGTiles(_bgTiles16, false);
if (bgtiles256.ShouldDraw) DrawBGTiles(bgtiles256, true); if (_bgTiles256.ShouldDraw) DrawBGTiles(_bgTiles256, true);
if (sptiles16.ShouldDraw) DrawSpriteTiles(sptiles16, false, false); if (_spTiles16.ShouldDraw) DrawSpriteTiles(_spTiles16, false, false);
if (sptiles256.ShouldDraw) DrawSpriteTiles(sptiles256, false, true); if (_spTiles256.ShouldDraw) DrawSpriteTiles(_spTiles256, false, true);
break; break;
case 1: case 1:
if (bg0.ShouldDraw) DrawTextBG(0, bg0); if (_bg0.ShouldDraw) DrawTextBG(0, _bg0);
if (bg1.ShouldDraw) DrawTextBG(1, bg1); if (_bg1.ShouldDraw) DrawTextBG(1, _bg1);
if (bg2.ShouldDraw) DrawAffineBG(2, bg2); if (_bg2.ShouldDraw) DrawAffineBG(2, _bg2);
if (bg3.ShouldDraw) bg3.BmpView.Clear(); if (_bg3.ShouldDraw) _bg3.BmpView.Clear();
if (bgtiles16.ShouldDraw) DrawBGTiles(bgtiles16, false); if (_bgTiles16.ShouldDraw) DrawBGTiles(_bgTiles16, false);
if (bgtiles256.ShouldDraw) DrawBGTiles(bgtiles256, true); if (_bgTiles256.ShouldDraw) DrawBGTiles(_bgTiles256, true);
if (sptiles16.ShouldDraw) DrawSpriteTiles(sptiles16, false, false); if (_spTiles16.ShouldDraw) DrawSpriteTiles(_spTiles16, false, false);
if (sptiles256.ShouldDraw) DrawSpriteTiles(sptiles256, false, true); if (_spTiles256.ShouldDraw) DrawSpriteTiles(_spTiles256, false, true);
break; break;
case 2: case 2:
if (bg0.ShouldDraw) bg0.BmpView.Clear(); if (_bg0.ShouldDraw) _bg0.BmpView.Clear();
if (bg1.ShouldDraw) bg1.BmpView.Clear(); if (_bg1.ShouldDraw) _bg1.BmpView.Clear();
if (bg2.ShouldDraw) DrawAffineBG(2, bg2); if (_bg2.ShouldDraw) DrawAffineBG(2, _bg2);
if (bg3.ShouldDraw) DrawAffineBG(3, bg3); if (_bg3.ShouldDraw) DrawAffineBG(3, _bg3);
// while there are no 4bpp tiles possible in mode 2, there might be some in memory // while there are no 4bpp tiles possible in mode 2, there might be some in memory
// due to midframe mode switching. no real reason not to display them if that's // due to midframe mode switching. no real reason not to display them if that's
// what the user wants to see // what the user wants to see
if (bgtiles16.ShouldDraw) DrawBGTiles(bgtiles16, false); if (_bgTiles16.ShouldDraw) DrawBGTiles(_bgTiles16, false);
if (bgtiles256.ShouldDraw) DrawBGTiles(bgtiles256, true); if (_bgTiles256.ShouldDraw) DrawBGTiles(_bgTiles256, true);
if (sptiles16.ShouldDraw) DrawSpriteTiles(sptiles16, false, false); if (_spTiles16.ShouldDraw) DrawSpriteTiles(_spTiles16, false, false);
if (sptiles256.ShouldDraw) DrawSpriteTiles(sptiles256, false, true); if (_spTiles256.ShouldDraw) DrawSpriteTiles(_spTiles256, false, true);
break; break;
case 3: case 3:
if (bg0.ShouldDraw) bg0.BmpView.Clear(); if (_bg0.ShouldDraw) _bg0.BmpView.Clear();
if (bg1.ShouldDraw) bg1.BmpView.Clear(); if (_bg1.ShouldDraw) _bg1.BmpView.Clear();
if (bg2.ShouldDraw) DrawM3BG(bg2); if (_bg2.ShouldDraw) DrawM3BG(_bg2);
if (bg3.ShouldDraw) bg3.BmpView.Clear(); if (_bg3.ShouldDraw) _bg3.BmpView.Clear();
if (bgtiles16.ShouldDraw) bgtiles16.BmpView.Clear(); if (_bgTiles16.ShouldDraw) _bgTiles16.BmpView.Clear();
if (bgtiles256.ShouldDraw) bgtiles256.BmpView.Clear(); if (_bgTiles256.ShouldDraw) _bgTiles256.BmpView.Clear();
if (sptiles16.ShouldDraw) DrawSpriteTiles(sptiles16, true, false); if (_spTiles16.ShouldDraw) DrawSpriteTiles(_spTiles16, true, false);
if (sptiles256.ShouldDraw) DrawSpriteTiles(sptiles256, true, true); if (_spTiles256.ShouldDraw) DrawSpriteTiles(_spTiles256, true, true);
break; break;
//in modes 4, 5, bg3 is repurposed as bg2 invisible frame //in modes 4, 5, bg3 is repurposed as bg2 invisible frame
case 4: case 4:
if (bg0.ShouldDraw) bg0.BmpView.Clear(); if (_bg0.ShouldDraw) _bg0.BmpView.Clear();
if (bg1.ShouldDraw) bg1.BmpView.Clear(); if (_bg1.ShouldDraw) _bg1.BmpView.Clear();
if (bg2.ShouldDraw) DrawM4BG(bg2, dispcnt.Bit(4)); if (_bg2.ShouldDraw) DrawM4BG(_bg2, dispcnt.Bit(4));
if (bg3.ShouldDraw) DrawM4BG(bg3, !dispcnt.Bit(4)); if (_bg3.ShouldDraw) DrawM4BG(_bg3, !dispcnt.Bit(4));
if (bgtiles16.ShouldDraw) bgtiles16.BmpView.Clear(); if (_bgTiles16.ShouldDraw) _bgTiles16.BmpView.Clear();
if (bgtiles256.ShouldDraw) bgtiles256.BmpView.Clear(); if (_bgTiles256.ShouldDraw) _bgTiles256.BmpView.Clear();
if (sptiles16.ShouldDraw) DrawSpriteTiles(sptiles16, true, false); if (_spTiles16.ShouldDraw) DrawSpriteTiles(_spTiles16, true, false);
if (sptiles256.ShouldDraw) DrawSpriteTiles(sptiles256, true, true); if (_spTiles256.ShouldDraw) DrawSpriteTiles(_spTiles256, true, true);
break; break;
case 5: case 5:
if (bg0.ShouldDraw) bg0.BmpView.Clear(); if (_bg0.ShouldDraw) _bg0.BmpView.Clear();
if (bg1.ShouldDraw) bg1.BmpView.Clear(); if (_bg1.ShouldDraw) _bg1.BmpView.Clear();
if (bg2.ShouldDraw) DrawM5BG(bg2, dispcnt.Bit(4)); if (_bg2.ShouldDraw) DrawM5BG(_bg2, dispcnt.Bit(4));
if (bg3.ShouldDraw) DrawM5BG(bg3, !dispcnt.Bit(4)); if (_bg3.ShouldDraw) DrawM5BG(_bg3, !dispcnt.Bit(4));
if (bgtiles16.ShouldDraw) bgtiles16.BmpView.Clear(); if (_bgTiles16.ShouldDraw) _bgTiles16.BmpView.Clear();
if (bgtiles256.ShouldDraw) bgtiles256.BmpView.Clear(); if (_bgTiles256.ShouldDraw) _bgTiles256.BmpView.Clear();
if (sptiles16.ShouldDraw) DrawSpriteTiles(sptiles16, true, false); if (_spTiles16.ShouldDraw) DrawSpriteTiles(_spTiles16, true, false);
if (sptiles256.ShouldDraw) DrawSpriteTiles(sptiles256, true, true); if (_spTiles256.ShouldDraw) DrawSpriteTiles(_spTiles256, true, true);
break; break;
default: default:
// shouldn't happen, but shouldn't be our problem either // shouldn't happen, but shouldn't be our problem either
if (bg0.ShouldDraw) bg0.BmpView.Clear(); if (_bg0.ShouldDraw) _bg0.BmpView.Clear();
if (bg1.ShouldDraw) bg1.BmpView.Clear(); if (_bg1.ShouldDraw) _bg1.BmpView.Clear();
if (bg2.ShouldDraw) bg2.BmpView.Clear(); if (_bg2.ShouldDraw) _bg2.BmpView.Clear();
if (bg3.ShouldDraw) bg3.BmpView.Clear(); if (_bg3.ShouldDraw) _bg3.BmpView.Clear();
if (bgtiles16.ShouldDraw) bgtiles16.BmpView.Clear(); if (_bgTiles16.ShouldDraw) _bgTiles16.BmpView.Clear();
if (bgtiles256.ShouldDraw) bgtiles256.BmpView.Clear(); if (_bgTiles256.ShouldDraw) _bgTiles256.BmpView.Clear();
if (sptiles16.ShouldDraw) sptiles16.BmpView.Clear(); if (_spTiles16.ShouldDraw) _spTiles16.BmpView.Clear();
if (sptiles256.ShouldDraw) sptiles256.BmpView.Clear(); if (_spTiles256.ShouldDraw) _spTiles256.BmpView.Clear();
break; break;
} }
if (bgpal.ShouldDraw) DrawPalette(bgpal, false); if (_bgPal.ShouldDraw) DrawPalette(_bgPal, false);
if (sppal.ShouldDraw) DrawPalette(sppal, true); if (_spPal.ShouldDraw) DrawPalette(_spPal, true);
if (sprites.ShouldDraw) DrawSprites(sprites); if (_sprites.ShouldDraw) DrawSprites(_sprites);
} }
MobileBmpView MakeMBVWidget(string text, int w, int h) private MobileBmpView MakeMBVWidget(string text, int w, int h)
{ {
var mbv = new MobileBmpView(); var mbv = new MobileBmpView { Text = text };
mbv.Text = text;
mbv.BmpView.Text = text; mbv.BmpView.Text = text;
mbv.TopLevel = false; mbv.TopLevel = false;
mbv.ChangeViewSize(w, h); mbv.ChangeViewSize(w, h);
@ -638,10 +641,9 @@ namespace BizHawk.Client.EmuHawk
return mbv; return mbv;
} }
MobileDetailView MakeMDVWidget(string text, int w, int h) private MobileDetailView MakeMDVWidget(string text, int w, int h)
{ {
var mdv = new MobileDetailView(); var mdv = new MobileDetailView { Text = text };
mdv.Text = text;
mdv.BmpView.Text = text; mdv.BmpView.Text = text;
mdv.TopLevel = false; mdv.TopLevel = false;
mdv.ClientSize = new Size(w, h); mdv.ClientSize = new Size(w, h);
@ -654,17 +656,17 @@ namespace BizHawk.Client.EmuHawk
void GenerateWidgets() void GenerateWidgets()
{ {
listBoxWidgets.BeginUpdate(); listBoxWidgets.BeginUpdate();
bg0 = MakeMBVWidget("Background 0", 256, 256); _bg0 = MakeMBVWidget("Background 0", 256, 256);
bg1 = MakeMBVWidget("Background 1", 256, 256); _bg1 = MakeMBVWidget("Background 1", 256, 256);
bg2 = MakeMBVWidget("Background 2", 256, 256); _bg2 = MakeMBVWidget("Background 2", 256, 256);
bg3 = MakeMBVWidget("Background 3", 256, 256); _bg3 = MakeMBVWidget("Background 3", 256, 256);
bgpal = MakeMBVWidget("Background Palettes", 256, 256); _bgPal = MakeMBVWidget("Background Palettes", 256, 256);
sppal = MakeMBVWidget("Sprite Palettes", 256, 256); _spPal = MakeMBVWidget("Sprite Palettes", 256, 256);
sprites = MakeMBVWidget("Sprites", 1024, 512); _sprites = MakeMBVWidget("Sprites", 1024, 512);
sptiles16 = MakeMBVWidget("Sprite Tiles (4bpp)", 256, 256); _spTiles16 = MakeMBVWidget("Sprite Tiles (4bpp)", 256, 256);
sptiles256 = MakeMBVWidget("Sprite Tiles (8bpp)", 128, 256); _spTiles256 = MakeMBVWidget("Sprite Tiles (8bpp)", 128, 256);
bgtiles16 = MakeMBVWidget("Background Tiles (4bpp)", 512, 256); _bgTiles16 = MakeMBVWidget("Background Tiles (4bpp)", 512, 256);
bgtiles256 = MakeMBVWidget("Background Tiles (8bpp)", 256, 256); _bgTiles256 = MakeMBVWidget("Background Tiles (8bpp)", 256, 256);
// todo: finish these // todo: finish these
// MakeMDVWidget("Details", 128, 192); // MakeMDVWidget("Details", 128, 192);
// memory = MakeMDVWidget("Details - Memory", 128, 192); // memory = MakeMDVWidget("Details - Memory", 128, 192);
@ -689,20 +691,24 @@ namespace BizHawk.Client.EmuHawk
{ {
c.Click += (o, e) => top.BringToFront(); c.Click += (o, e) => top.BringToFront();
if (c.HasChildren) if (c.HasChildren)
{
foreach (Control cc in c.Controls) foreach (Control cc in c.Controls)
{
BringToFrontHack(cc, top); BringToFrontHack(cc, top);
} }
}
}
public void Restart() public void Restart()
{ {
var mem = gba.GetMemoryAreas(); var mem = GBA.GetMemoryAreas();
vram = mem.vram; _vram = mem.vram;
palram = mem.palram; _palRam = mem.palram;
oam = mem.oam; _oam = mem.oam;
mmio = mem.mmio; _mmio = mem.mmio;
_cbscanlineEmu = 500; // force an update _cbScanlineEmu = 500; // force an update
UpdateValues(); UpdateValues();
} }
@ -712,18 +718,20 @@ namespace BizHawk.Client.EmuHawk
public void UpdateValues() public void UpdateValues()
{ {
if (!IsHandleCreated || IsDisposed) if (!IsHandleCreated || IsDisposed)
{
return; return;
}
if (_cbscanlineEmu != _cbscanline) if (_cbScanlineEmu != _cbScanline)
{ {
_cbscanlineEmu = _cbscanline; _cbScanlineEmu = _cbScanline;
if (!_cbscanline.HasValue) // manual, deactivate callback if (!_cbScanline.HasValue) // manual, deactivate callback
{ {
gba.SetScanlineCallback(null, 0); GBA.SetScanlineCallback(null, 0);
} }
else else
{ {
gba.SetScanlineCallback(DrawEverything, _cbscanline.Value); GBA.SetScanlineCallback(DrawEverything, _cbScanline.Value);
} }
} }
} }
@ -733,10 +741,6 @@ namespace BizHawk.Client.EmuHawk
// Do nothing // Do nothing
} }
private void GBAGPUView_Load(object sender, EventArgs e)
{
}
void ShowSelectedWidget() void ShowSelectedWidget()
{ {
if (listBoxWidgets.SelectedItem != null) if (listBoxWidgets.SelectedItem != null)
@ -760,8 +764,8 @@ namespace BizHawk.Client.EmuHawk
#region refresh control #region refresh control
private int? _cbscanline = null; private int? _cbScanline;
private int? _cbscanlineEmu = 500; private int? _cbScanlineEmu = 500;
private void RecomputeRefresh() private void RecomputeRefresh()
{ {
@ -769,21 +773,16 @@ namespace BizHawk.Client.EmuHawk
{ {
hScrollBar1.Enabled = true; hScrollBar1.Enabled = true;
buttonRefresh.Enabled = false; buttonRefresh.Enabled = false;
_cbscanline = (hScrollBar1.Value + 160) % 228; _cbScanline = (hScrollBar1.Value + 160) % 228;
} }
else if (radioButtonManual.Checked) else if (radioButtonManual.Checked)
{ {
hScrollBar1.Enabled = false; hScrollBar1.Enabled = false;
buttonRefresh.Enabled = true; buttonRefresh.Enabled = true;
_cbscanline = null; _cbScanline = null;
} }
} }
private void radioButtonFrame_CheckedChanged(object sender, EventArgs e)
{
RecomputeRefresh();
}
private void radioButtonScanline_CheckedChanged(object sender, EventArgs e) private void radioButtonScanline_CheckedChanged(object sender, EventArgs e)
{ {
RecomputeRefresh(); RecomputeRefresh();
@ -791,8 +790,8 @@ namespace BizHawk.Client.EmuHawk
private void hScrollBar1_ValueChanged(object sender, EventArgs e) private void hScrollBar1_ValueChanged(object sender, EventArgs e)
{ {
_cbscanline = (hScrollBar1.Value + 160) % 228; _cbScanline = (hScrollBar1.Value + 160) % 228;
radioButtonScanline.Text = $"Scanline {_cbscanline}"; radioButtonScanline.Text = $"Scanline {_cbScanline}";
} }
private void radioButtonManual_CheckedChanged(object sender, EventArgs e) private void radioButtonManual_CheckedChanged(object sender, EventArgs e)
@ -807,12 +806,9 @@ namespace BizHawk.Client.EmuHawk
#endregion #endregion
private void GBAGPUView_FormClosed(object sender, FormClosedEventArgs e) private void GbaGpuView_FormClosed(object sender, FormClosedEventArgs e)
{ {
if (gba != null) GBA?.SetScanlineCallback(null, 0);
{
gba.SetScanlineCallback(null, 0);
}
} }
#region copy to clipboard #region copy to clipboard
@ -823,7 +819,7 @@ namespace BizHawk.Client.EmuHawk
labelClipboard.Text = "CTRL + C: Copy under mouse to clipboard."; labelClipboard.Text = "CTRL + C: Copy under mouse to clipboard.";
} }
private void GBAGPUView_KeyDown(object sender, KeyEventArgs e) private void GbaGpuView_KeyDown(object sender, KeyEventArgs e)
{ {
if (ModifierKeys.HasFlag(Keys.Control) && e.KeyCode == Keys.C) if (ModifierKeys.HasFlag(Keys.Control) && e.KeyCode == Keys.C)
{ {
@ -837,10 +833,10 @@ namespace BizHawk.Client.EmuHawk
top = found; top = found;
} while (found != null && found.HasChildren); } while (found != null && found.HasChildren);
if (found is BmpView) if (found is BmpView view)
{ {
Clipboard.SetImage((found as BmpView).BMP); Clipboard.SetImage(view.BMP);
labelClipboard.Text = $"{found.Text} copied to clipboard."; labelClipboard.Text = $"{view.Text} copied to clipboard.";
timerMessage.Stop(); timerMessage.Stop();
timerMessage.Start(); timerMessage.Start();
} }

View File

@ -1,10 +1,5 @@
using System; using System.ComponentModel;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing; using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms; using System.Windows.Forms;
namespace BizHawk.Client.EmuHawk namespace BizHawk.Client.EmuHawk
@ -16,10 +11,10 @@ namespace BizHawk.Client.EmuHawk
InitializeComponent(); InitializeComponent();
} }
public BmpView BmpView { get { return bmpView1; } } public BmpView BmpView => bmpView1;
[Browsable(false)] [Browsable(false)]
public bool ShouldDraw { get { return this.Visible; } } public bool ShouldDraw => Visible;
public override string ToString() public override string ToString()
{ {
@ -31,19 +26,16 @@ namespace BizHawk.Client.EmuHawk
bmpView1.Size = size; bmpView1.Size = size;
this.ClientSize = size; this.ClientSize = size;
} }
public void ChangeViewSize(int w, int h) public void ChangeViewSize(int w, int h)
{ {
ChangeViewSize(new Size(w, h)); ChangeViewSize(new Size(w, h));
} }
public void ChangeAllSizes(int w, int h) public void ChangeAllSizes(int w, int h)
{ {
ChangeViewSize(w, h); ChangeViewSize(w, h);
bmpView1.ChangeBitmapSize(w, h); bmpView1.ChangeBitmapSize(w, h);
} }
public void ChangeAllSizes(Size size)
{
ChangeViewSize(size);
bmpView1.ChangeBitmapSize(size);
}
} }
} }

View File

@ -1,10 +1,4 @@
using System; 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 System.Windows.Forms;
using BizHawk.Emulation.Cores.Consoles.Sega.gpgx; using BizHawk.Emulation.Cores.Consoles.Sega.gpgx;
@ -13,7 +7,7 @@ namespace BizHawk.Client.EmuHawk.tools.Genesis
// see GenDbgHlp.cs for a general overview of this // see GenDbgHlp.cs for a general overview of this
public partial class GenDbgWind : Form public partial class GenDbgWind : Form
{ {
GenDbgHlp dbg; private GenDbgHlp _dbg;
public GenDbgWind() public GenDbgWind()
{ {
@ -24,31 +18,37 @@ namespace BizHawk.Client.EmuHawk.tools.Genesis
listBox2.Items.Add(i.ToString()); listBox2.Items.Add(i.ToString());
} }
dbg = new GenDbgHlp(); _dbg = new GenDbgHlp();
} }
private void button1_Click(object sender, EventArgs e) private void button1_Click(object sender, EventArgs e)
{ {
if (listBox1.SelectedIndex != -1) if (listBox1.SelectedIndex != -1)
dbg.SaveState(int.Parse((string)listBox1.SelectedItem)); {
_dbg.SaveState(int.Parse((string)listBox1.SelectedItem));
}
} }
private void button2_Click(object sender, EventArgs e) private void button2_Click(object sender, EventArgs e)
{ {
if (listBox2.SelectedIndex != -1) if (listBox2.SelectedIndex != -1)
dbg.SaveState(int.Parse((string)listBox2.SelectedItem)); {
_dbg.SaveState(int.Parse((string)listBox2.SelectedItem));
}
} }
private void button3_Click(object sender, EventArgs e) private void button3_Click(object sender, EventArgs e)
{ {
if (listBox1.SelectedIndex != -1 && listBox2.SelectedIndex != -1) if (listBox1.SelectedIndex != -1 && listBox2.SelectedIndex != -1)
dbg.Cmp(int.Parse((string)listBox1.SelectedItem), int.Parse((string)listBox2.SelectedItem)); {
_dbg.Cmp(int.Parse((string)listBox1.SelectedItem), int.Parse((string)listBox2.SelectedItem));
}
} }
private void GenDbgWind_FormClosed(object sender, FormClosedEventArgs e) private void GenDbgWind_FormClosed(object sender, FormClosedEventArgs e)
{ {
dbg.Dispose(); _dbg.Dispose();
dbg = null; _dbg = null;
} }
} }
} }

View File

@ -229,7 +229,6 @@
this.ShowIcon = false; this.ShowIcon = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Genesis Game Genie Encoder / Decoder"; this.Text = "Genesis Game Genie Encoder / Decoder";
this.Load += new System.EventHandler(this.GenGameGenie_Load);
this.GameGenieCodeBox.ResumeLayout(false); this.GameGenieCodeBox.ResumeLayout(false);
this.GameGenieCodeBox.PerformLayout(); this.GameGenieCodeBox.PerformLayout();
this.groupBox1.ResumeLayout(false); this.groupBox1.ResumeLayout(false);

View File

@ -5,7 +5,6 @@ using System.Text.RegularExpressions;
using System.Windows.Forms; using System.Windows.Forms;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
using BizHawk.Emulation.Common.IEmulatorExtensions;
using BizHawk.Client.Common; using BizHawk.Client.Common;
using BizHawk.Emulation.Cores.Consoles.Sega.gpgx; using BizHawk.Emulation.Cores.Consoles.Sega.gpgx;
@ -18,7 +17,7 @@ namespace BizHawk.Client.EmuHawk
#pragma warning disable 675 #pragma warning disable 675
/// <summary> /// <summary>
/// For now this is is an unecessary restriction to make sure it doesn't show up as available for non-genesis cores /// For now this is is an unnecessary restriction to make sure it doesn't show up as available for non-genesis cores
/// Note: this unnecessarily prevents it from being on the Genesis core, but that's okay it isn't released /// Note: this unnecessarily prevents it from being on the Genesis core, but that's okay it isn't released
/// Eventually we want a generic game genie tool and a hack like this won't be necessary /// Eventually we want a generic game genie tool and a hack like this won't be necessary
/// </summary> /// </summary>
@ -30,52 +29,47 @@ namespace BizHawk.Client.EmuHawk
private readonly Dictionary<char, int> _gameGenieTable = new Dictionary<char, int> private readonly Dictionary<char, int> _gameGenieTable = new Dictionary<char, int>
{ {
{ 'A', 0 }, ['A'] = 0,
{ 'B', 1 }, ['B'] = 1,
{ 'C', 2 }, ['C'] = 2,
{ 'D', 3 }, ['D'] = 3,
{ 'E', 4 }, ['E'] = 4,
{ 'F', 5 }, ['F'] = 5,
{ 'G', 6 }, ['G'] = 6,
{ 'H', 7 }, ['H'] = 7,
{ 'J', 8 }, ['J'] = 8,
{ 'K', 9 }, ['K'] = 9,
{ 'L', 10 }, ['L'] = 10,
{ 'M', 11 }, ['M'] = 11,
{ 'N', 12 }, ['N'] = 12,
{ 'P', 13 }, ['P'] = 13,
{ 'R', 14 }, ['R'] = 14,
{ 'S', 15 }, ['S'] = 15,
{ 'T', 16 }, ['T'] = 16,
{ 'V', 17 }, ['V'] = 17,
{ 'W', 18 }, ['W'] = 18,
{ 'X', 19 }, ['X'] = 19,
{ 'Y', 20 }, ['Y'] = 20,
{ 'Z', 21 }, ['Z'] = 21,
{ '0', 22 }, ['0'] = 22,
{ '1', 23 }, ['1'] = 23,
{ '2', 24 }, ['2'] = 24,
{ '3', 25 }, ['3'] = 25,
{ '4', 26 }, ['4'] = 26,
{ '5', 27 }, ['5'] = 27,
{ '6', 28 }, ['6'] = 28,
{ '7', 29 }, ['7'] = 29,
{ '8', 30 }, ['8'] = 30,
{ '9', 31 } ['9'] = 31
}; };
private bool _processing; private bool _processing;
private void GenGameGenie_Load(object sender, EventArgs e)
{
}
#region Public API #region Public API
public bool AskSaveChanges() { return true; } public bool AskSaveChanges() => true;
public bool UpdateBefore { get { return false; } } public bool UpdateBefore => false;
public void Restart() public void Restart()
{ {
@ -110,23 +104,22 @@ namespace BizHawk.Client.EmuHawk
// code is code to be converted, val is pointer to value, add is pointer to address // code is code to be converted, val is pointer to value, add is pointer to address
private void GenGGDecode(string code, ref int val, ref int add) private void GenGGDecode(string code, ref int val, ref int add)
{ {
long hexcode = 0; long hexCode = 0;
// convert code to a long binary string // convert code to a long binary string
foreach (var t in code) foreach (var t in code)
{ {
hexcode <<= 5; hexCode <<= 5;
int y; _gameGenieTable.TryGetValue(t, out var y);
_gameGenieTable.TryGetValue(t, out y); hexCode |= y;
hexcode |= y;
} }
long decoded = (hexcode & 0xFF00000000) >> 32; long decoded = (hexCode & 0xFF00000000) >> 32;
decoded |= hexcode & 0x00FF000000; decoded |= hexCode & 0x00FF000000;
decoded |= (hexcode & 0x0000FF0000) << 16; decoded |= (hexCode & 0x0000FF0000) << 16;
decoded |= (hexcode & 0x00000000700) << 5; decoded |= (hexCode & 0x00000000700) << 5;
decoded |= (hexcode & 0x000000F800) >> 3; decoded |= (hexCode & 0x000000F800) >> 3;
decoded |= (hexcode & 0x00000000FF) << 16; decoded |= (hexCode & 0x00000000FF) << 16;
val = (int)(decoded & 0x000000FFFF); val = (int)(decoded & 0x000000FFFF);
add = (int)((decoded & 0xFFFFFF0000) >> 16); add = (int)((decoded & 0xFFFFFF0000) >> 16);
@ -134,10 +127,9 @@ namespace BizHawk.Client.EmuHawk
private static string GenGGEncode(int val, int add) private static string GenGGEncode(int val, int add)
{ {
long encoded;
string code = null; string code = null;
encoded = (long)(val & 0x00FF) << 32; var encoded = (long)(val & 0x00FF) << 32;
encoded |= (val & 0xE000) >> 5; encoded |= (val & 0xE000) >> 5;
encoded |= (val & 0x1F00) << 3; encoded |= (val & 0x1F00) << 3;
encoded |= add & 0xFF0000; encoded |= add & 0xFF0000;
@ -320,7 +312,7 @@ namespace BizHawk.Client.EmuHawk
MemoryDomains["M68K BUS"], MemoryDomains["M68K BUS"],
address, address,
WatchSize.Word, WatchSize.Word,
Client.Common.DisplayType.Hex, Common.DisplayType.Hex,
true, true,
name name
); );

View File

@ -1,6 +1,6 @@
namespace BizHawk.Client.EmuHawk namespace BizHawk.Client.EmuHawk
{ {
partial class GenVDPViewer partial class GenVdpViewer
{ {
/// <summary> /// <summary>
/// Required designer variable. /// Required designer variable.
@ -186,35 +186,35 @@
this.saveBGAScreenshotToolStripMenuItem.Name = "saveBGAScreenshotToolStripMenuItem"; this.saveBGAScreenshotToolStripMenuItem.Name = "saveBGAScreenshotToolStripMenuItem";
this.saveBGAScreenshotToolStripMenuItem.Size = new System.Drawing.Size(208, 22); this.saveBGAScreenshotToolStripMenuItem.Size = new System.Drawing.Size(208, 22);
this.saveBGAScreenshotToolStripMenuItem.Text = "Save BG A Screenshot..."; this.saveBGAScreenshotToolStripMenuItem.Text = "Save BG A Screenshot...";
this.saveBGAScreenshotToolStripMenuItem.Click += new System.EventHandler(this.saveBGAScreenshotToolStripMenuItem_Click); this.saveBGAScreenshotToolStripMenuItem.Click += new System.EventHandler(this.SaveBGAScreenshotToolStripMenuItem_Click);
// //
// saveBGBScreenshotToolStripMenuItem // saveBGBScreenshotToolStripMenuItem
// //
this.saveBGBScreenshotToolStripMenuItem.Name = "saveBGBScreenshotToolStripMenuItem"; this.saveBGBScreenshotToolStripMenuItem.Name = "saveBGBScreenshotToolStripMenuItem";
this.saveBGBScreenshotToolStripMenuItem.Size = new System.Drawing.Size(208, 22); this.saveBGBScreenshotToolStripMenuItem.Size = new System.Drawing.Size(208, 22);
this.saveBGBScreenshotToolStripMenuItem.Text = "Save BG B Screenshot..."; this.saveBGBScreenshotToolStripMenuItem.Text = "Save BG B Screenshot...";
this.saveBGBScreenshotToolStripMenuItem.Click += new System.EventHandler(this.saveBGBScreenshotToolStripMenuItem_Click); this.saveBGBScreenshotToolStripMenuItem.Click += new System.EventHandler(this.SaveBGBScreenshotToolStripMenuItem_Click);
// //
// saveTilesScreenshotToolStripMenuItem // saveTilesScreenshotToolStripMenuItem
// //
this.saveTilesScreenshotToolStripMenuItem.Name = "saveTilesScreenshotToolStripMenuItem"; this.saveTilesScreenshotToolStripMenuItem.Name = "saveTilesScreenshotToolStripMenuItem";
this.saveTilesScreenshotToolStripMenuItem.Size = new System.Drawing.Size(208, 22); this.saveTilesScreenshotToolStripMenuItem.Size = new System.Drawing.Size(208, 22);
this.saveTilesScreenshotToolStripMenuItem.Text = "Save Tiles Screenshot..."; this.saveTilesScreenshotToolStripMenuItem.Text = "Save Tiles Screenshot...";
this.saveTilesScreenshotToolStripMenuItem.Click += new System.EventHandler(this.saveTilesScreenshotToolStripMenuItem_Click); this.saveTilesScreenshotToolStripMenuItem.Click += new System.EventHandler(this.SaveTilesScreenshotToolStripMenuItem_Click);
// //
// saveWindowScreenshotToolStripMenuItem // saveWindowScreenshotToolStripMenuItem
// //
this.saveWindowScreenshotToolStripMenuItem.Name = "saveWindowScreenshotToolStripMenuItem"; this.saveWindowScreenshotToolStripMenuItem.Name = "saveWindowScreenshotToolStripMenuItem";
this.saveWindowScreenshotToolStripMenuItem.Size = new System.Drawing.Size(208, 22); this.saveWindowScreenshotToolStripMenuItem.Size = new System.Drawing.Size(208, 22);
this.saveWindowScreenshotToolStripMenuItem.Text = "Save Window Screenshot..."; this.saveWindowScreenshotToolStripMenuItem.Text = "Save Window Screenshot...";
this.saveWindowScreenshotToolStripMenuItem.Click += new System.EventHandler(this.saveWindowScreenshotToolStripMenuItem_Click); this.saveWindowScreenshotToolStripMenuItem.Click += new System.EventHandler(this.SaveWindowScreenshotToolStripMenuItem_Click);
// //
// savePaletteScreenshotToolStripMenuItem // savePaletteScreenshotToolStripMenuItem
// //
this.savePaletteScreenshotToolStripMenuItem.Name = "savePaletteScreenshotToolStripMenuItem"; this.savePaletteScreenshotToolStripMenuItem.Name = "savePaletteScreenshotToolStripMenuItem";
this.savePaletteScreenshotToolStripMenuItem.Size = new System.Drawing.Size(208, 22); this.savePaletteScreenshotToolStripMenuItem.Size = new System.Drawing.Size(208, 22);
this.savePaletteScreenshotToolStripMenuItem.Text = "Save Palette Screenshot..."; this.savePaletteScreenshotToolStripMenuItem.Text = "Save Palette Screenshot...";
this.savePaletteScreenshotToolStripMenuItem.Click += new System.EventHandler(this.savePaletteScreenshotToolStripMenuItem_Click); this.savePaletteScreenshotToolStripMenuItem.Click += new System.EventHandler(this.SavePaletteScreenshotToolStripMenuItem_Click);
// //
// toolStripSeparator1 // toolStripSeparator1
// //
@ -227,7 +227,7 @@
this.closeToolStripMenuItem.ShortcutKeyDisplayString = "Alt+F4"; this.closeToolStripMenuItem.ShortcutKeyDisplayString = "Alt+F4";
this.closeToolStripMenuItem.Size = new System.Drawing.Size(208, 22); this.closeToolStripMenuItem.Size = new System.Drawing.Size(208, 22);
this.closeToolStripMenuItem.Text = "&Close"; this.closeToolStripMenuItem.Text = "&Close";
this.closeToolStripMenuItem.Click += new System.EventHandler(this.closeToolStripMenuItem_Click); this.closeToolStripMenuItem.Click += new System.EventHandler(this.CloseMenuItem_Click);
// //
// GenVDPViewer // GenVDPViewer
// //
@ -244,10 +244,9 @@
this.Controls.Add(this.menuStrip1); this.Controls.Add(this.menuStrip1);
this.KeyPreview = true; this.KeyPreview = true;
this.MainMenuStrip = this.menuStrip1; this.MainMenuStrip = this.menuStrip1;
this.Name = "GenVDPViewer"; this.Name = "GenVdpViewer";
this.ShowIcon = false; this.ShowIcon = false;
this.Text = "VDP Viewer"; this.Text = "VDP Viewer";
this.Load += new System.EventHandler(this.GenVDPViewer_Load);
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.VDPViewer_KeyDown); this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.VDPViewer_KeyDown);
this.groupBox1.ResumeLayout(false); this.groupBox1.ResumeLayout(false);
this.groupBox2.ResumeLayout(false); this.groupBox2.ResumeLayout(false);

View File

@ -1,12 +1,6 @@
using System; using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing; using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms; using System.Windows.Forms;
using BizHawk.Client.Common;
using System.Drawing.Imaging; using System.Drawing.Imaging;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
using BizHawk.Emulation.Cores.Consoles.Sega.gpgx; using BizHawk.Emulation.Cores.Consoles.Sega.gpgx;
@ -14,29 +8,29 @@ using BizHawk.Common;
namespace BizHawk.Client.EmuHawk namespace BizHawk.Client.EmuHawk
{ {
public partial class GenVDPViewer : Form, IToolFormAutoConfig public partial class GenVdpViewer : Form, IToolFormAutoConfig
{ {
[RequiredService] [RequiredService]
private GPGX Emu { get; set; } private GPGX Emu { get; set; }
private GPGX.VDPView View; private GPGX.VDPView _view;
int palindex = 0; private int _palIndex;
protected override System.Drawing.Point ScrollToControl(System.Windows.Forms.Control activeControl) protected override Point ScrollToControl(Control activeControl)
{ {
// Returning the current location prevents the panel from scrolling to the active control when the panel loses and regains focus // Returning the current location prevents the panel from scrolling to the active control when the panel loses and regains focus
return this.DisplayRectangle.Location; return DisplayRectangle.Location;
} }
public GenVDPViewer() public GenVdpViewer()
{ {
InitializeComponent(); InitializeComponent();
bmpViewTiles.ChangeBitmapSize(512, 256); bmpViewTiles.ChangeBitmapSize(512, 256);
bmpViewPal.ChangeBitmapSize(16, 4); bmpViewPal.ChangeBitmapSize(16, 4);
} }
unsafe static void DrawTile(int* dest, int pitch, byte* src, int* pal) private static unsafe void DrawTile(int* dest, int pitch, byte* src, int* pal)
{ {
for (int j = 0; j < 8; j++) for (int j = 0; j < 8; j++)
{ {
@ -52,23 +46,23 @@ namespace BizHawk.Client.EmuHawk
} }
} }
unsafe static void DrawNameTable(LibGPGX.VDPNameTable NT, ushort* vram, byte* tiles, int* pal, BmpView bv) private static unsafe void DrawNameTable(LibGPGX.VDPNameTable nt, ushort* vram, byte* tiles, int* pal, BmpView bv)
{ {
ushort* nametable = vram + NT.Baseaddr / 2; ushort* nametable = vram + nt.Baseaddr / 2;
int tilew = NT.Width; int tileW = nt.Width;
int tileh = NT.Height; int tileH = nt.Height;
Size pixsize = new Size(tilew * 8, tileh * 8); Size pixSize = new Size(tileW * 8, tileH * 8);
bv.Size = pixsize; bv.Size = pixSize;
bv.ChangeBitmapSize(pixsize); bv.ChangeBitmapSize(pixSize);
var lockdata = bv.BMP.LockBits(new Rectangle(Point.Empty, pixsize), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); var lockData = bv.BMP.LockBits(new Rectangle(Point.Empty, pixSize), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
int pitch = lockdata.Stride / sizeof(int); int pitch = lockData.Stride / sizeof(int);
int* dest = (int*)lockdata.Scan0; int* dest = (int*)lockData.Scan0;
for (int tiley = 0; tiley < tileh; tiley++) for (int tileY = 0; tileY < tileH; tileY++)
{ {
for (int tilex = 0; tilex < tilew; tilex++) for (int tileX = 0; tileX < tileW; tileX++)
{ {
ushort bgent = *nametable++; ushort bgent = *nametable++;
int palidx = bgent >> 9 & 0x30; int palidx = bgent >> 9 & 0x30;
@ -76,18 +70,18 @@ namespace BizHawk.Client.EmuHawk
DrawTile(dest, pitch, tiles + tileent * 64, pal + palidx); DrawTile(dest, pitch, tiles + tileent * 64, pal + palidx);
dest += 8; dest += 8;
} }
dest -= 8 * tilew; dest -= 8 * tileW;
dest += 8 * pitch; dest += 8 * pitch;
} }
bv.BMP.UnlockBits(lockdata); bv.BMP.UnlockBits(lockData);
bv.Refresh(); bv.Refresh();
} }
unsafe void DrawPalettes(int* pal) unsafe void DrawPalettes(int* pal)
{ {
var lockdata = bmpViewPal.BMP.LockBits(new Rectangle(0, 0, 16, 4), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); var lockData = bmpViewPal.BMP.LockBits(new Rectangle(0, 0, 16, 4), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
int pitch = lockdata.Stride / sizeof(int); int pitch = lockData.Stride / sizeof(int);
int* dest = (int*)lockdata.Scan0; int* dest = (int*)lockData.Scan0;
for (int j = 0; j < 4; j++) for (int j = 0; j < 4; j++)
{ {
@ -95,18 +89,18 @@ namespace BizHawk.Client.EmuHawk
*dest++ = *pal++; *dest++ = *pal++;
dest += pitch - 16; dest += pitch - 16;
} }
bmpViewPal.BMP.UnlockBits(lockdata); bmpViewPal.BMP.UnlockBits(lockData);
bmpViewPal.Refresh(); bmpViewPal.Refresh();
} }
unsafe void DrawTiles() unsafe void DrawTiles()
{ {
var lockdata = bmpViewTiles.BMP.LockBits(new Rectangle(0, 0, 512, 256), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); var lockData = bmpViewTiles.BMP.LockBits(new Rectangle(0, 0, 512, 256), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
int pitch = lockdata.Stride / sizeof(int); int pitch = lockData.Stride / sizeof(int);
int* dest = (int*)lockdata.Scan0; int* dest = (int*)lockData.Scan0;
byte* src = (byte*)View.PatternCache; byte* src = (byte*)_view.PatternCache;
int* pal = 0x10 * palindex + (int*)View.ColorCache; int* pal = 0x10 * _palIndex + (int*)_view.ColorCache;
for (int tile = 0; tile < 2048;) for (int tile = 0; tile < 2048;)
{ {
@ -117,7 +111,7 @@ namespace BizHawk.Client.EmuHawk
if ((tile & 63) == 0) if ((tile & 63) == 0)
dest += 8 * pitch - 512; dest += 8 * pitch - 512;
} }
bmpViewTiles.BMP.UnlockBits(lockdata); bmpViewTiles.BMP.UnlockBits(lockData);
bmpViewTiles.Refresh(); bmpViewTiles.Refresh();
} }
@ -126,21 +120,21 @@ namespace BizHawk.Client.EmuHawk
public unsafe void UpdateValues() public unsafe void UpdateValues()
{ {
if (Emu == null) if (Emu == null)
return;
using ((View = Emu.UpdateVDPViewContext()).EnterExit())
{ {
int* pal = (int*)View.ColorCache; return;
//for (int i = 0; i < 0x40; i++) }
// pal[i] |= unchecked((int)0xff000000);
using ((_view = Emu.UpdateVDPViewContext()).EnterExit())
{
int* pal = (int*)_view.ColorCache;
DrawPalettes(pal); DrawPalettes(pal);
DrawTiles(); DrawTiles();
ushort* VRAMNT = (ushort*)View.VRAM; ushort* vramNt = (ushort*)_view.VRAM;
byte* tiles = (byte*)View.PatternCache; byte* tiles = (byte*)_view.PatternCache;
DrawNameTable(View.NTA, VRAMNT, tiles, pal, bmpViewNTA); DrawNameTable(_view.NTA, vramNt, tiles, pal, bmpViewNTA);
DrawNameTable(View.NTB, VRAMNT, tiles, pal, bmpViewNTB); DrawNameTable(_view.NTB, vramNt, tiles, pal, bmpViewNTB);
DrawNameTable(View.NTW, VRAMNT, tiles, pal, bmpViewNTW); DrawNameTable(_view.NTW, vramNt, tiles, pal, bmpViewNTW);
View = null; _view = null;
} }
} }
@ -154,21 +148,15 @@ namespace BizHawk.Client.EmuHawk
UpdateValues(); UpdateValues();
} }
public bool AskSaveChanges() public bool AskSaveChanges() => true;
{
return true;
}
public bool UpdateBefore public bool UpdateBefore => true;
{
get { return true; }
}
private void bmpViewPal_MouseClick(object sender, MouseEventArgs e) private void bmpViewPal_MouseClick(object sender, MouseEventArgs e)
{ {
int idx = e.Y / 16; int idx = e.Y / 16;
idx = Math.Min(3, Math.Max(idx, 0)); idx = Math.Min(3, Math.Max(idx, 0));
palindex = idx; _palIndex = idx;
UpdateValues(); UpdateValues();
} }
@ -186,46 +174,41 @@ namespace BizHawk.Client.EmuHawk
top = found; top = found;
} while (found != null && found.HasChildren); } while (found != null && found.HasChildren);
if (found is BmpView) if (found is BmpView bv)
{ {
var bv = found as BmpView;
Clipboard.SetImage(bv.BMP); Clipboard.SetImage(bv.BMP);
} }
} }
} }
private void saveBGAScreenshotToolStripMenuItem_Click(object sender, EventArgs e) private void SaveBGAScreenshotToolStripMenuItem_Click(object sender, EventArgs e)
{ {
bmpViewNTA.SaveFile(); bmpViewNTA.SaveFile();
} }
private void saveBGBScreenshotToolStripMenuItem_Click(object sender, EventArgs e) private void SaveBGBScreenshotToolStripMenuItem_Click(object sender, EventArgs e)
{ {
bmpViewNTB.SaveFile(); bmpViewNTB.SaveFile();
} }
private void saveTilesScreenshotToolStripMenuItem_Click(object sender, EventArgs e) private void SaveTilesScreenshotToolStripMenuItem_Click(object sender, EventArgs e)
{ {
bmpViewTiles.SaveFile(); bmpViewTiles.SaveFile();
} }
private void saveWindowScreenshotToolStripMenuItem_Click(object sender, EventArgs e) private void SaveWindowScreenshotToolStripMenuItem_Click(object sender, EventArgs e)
{ {
bmpViewNTW.SaveFile(); bmpViewNTW.SaveFile();
} }
private void savePaletteScreenshotToolStripMenuItem_Click(object sender, EventArgs e) private void SavePaletteScreenshotToolStripMenuItem_Click(object sender, EventArgs e)
{ {
bmpViewPal.SaveFile(); bmpViewPal.SaveFile();
} }
private void closeToolStripMenuItem_Click(object sender, EventArgs e) private void CloseMenuItem_Click(object sender, EventArgs e)
{ {
Close(); Close();
} }
private void GenVDPViewer_Load(object sender, EventArgs e)
{
}
} }
} }

View File

@ -19,29 +19,29 @@ namespace BizHawk.Client.EmuHawk
private readonly Dictionary<char, int> _gameGenieTable = new Dictionary<char, int> private readonly Dictionary<char, int> _gameGenieTable = new Dictionary<char, int>
{ {
{ 'A', 0 }, // 0000 ['A'] = 0, // 0000
{ 'P', 1 }, // 0001 ['P'] = 1, // 0001
{ 'Z', 2 }, // 0010 ['Z'] = 2, // 0010
{ 'L', 3 }, // 0011 ['L'] = 3, // 0011
{ 'G', 4 }, // 0100 ['G'] = 4, // 0100
{ 'I', 5 }, // 0101 ['I'] = 5, // 0101
{ 'T', 6 }, // 0110 ['T'] = 6, // 0110
{ 'Y', 7 }, // 0111 ['Y'] = 7, // 0111
{ 'E', 8 }, // 1000 ['E'] = 8, // 1000
{ 'O', 9 }, // 1001 ['O'] = 9, // 1001
{ 'X', 10 }, // 1010 ['X'] = 10, // 1010
{ 'U', 11 }, // 1011 ['U'] = 11, // 1011
{ 'K', 12 }, // 1100 ['K'] = 12, // 1100
{ 'S', 13 }, // 1101 ['S'] = 13, // 1101
{ 'V', 14 }, // 1110 ['V'] = 14, // 1110
{ 'N', 15 }, // 1111 ['N'] = 15 // 1111
}; };
private int? _address; private int? _address;
private int? _value; private int? _value;
private int? _compare; private int? _compare;
public bool AskSaveChanges() { return true; } public bool AskSaveChanges() => true;
public bool UpdateBefore => false; public bool UpdateBefore => false;
public void Restart() public void Restart()

View File

@ -4,14 +4,14 @@ using System.Drawing.Imaging;
namespace BizHawk.Client.EmuHawk namespace BizHawk.Client.EmuHawk
{ {
public class PCEBGCanvas : Control public class PceBgCanvas : Control
{ {
public Bitmap Bat; public Bitmap Bat { get; set; }
private const int BAT_WIDTH = 1024; private const int BAT_WIDTH = 1024;
private const int BAT_HEIGHT = 512; private const int BAT_HEIGHT = 512;
public PCEBGCanvas() public PceBgCanvas()
{ {
Bat = new Bitmap(BAT_WIDTH, BAT_HEIGHT, PixelFormat.Format32bppArgb); Bat = new Bitmap(BAT_WIDTH, BAT_HEIGHT, PixelFormat.Format32bppArgb);
SetStyle(ControlStyles.AllPaintingInWmPaint, true); SetStyle(ControlStyles.AllPaintingInWmPaint, true);

View File

@ -35,7 +35,7 @@
this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
this.ExitMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.ExitMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.groupBox1 = new System.Windows.Forms.GroupBox(); this.groupBox1 = new System.Windows.Forms.GroupBox();
this.canvas = new BizHawk.Client.EmuHawk.PCEBGCanvas(); this.canvas = new BizHawk.Client.EmuHawk.PceBgCanvas();
this.groupBox5 = new System.Windows.Forms.GroupBox(); this.groupBox5 = new System.Windows.Forms.GroupBox();
this.label7 = new System.Windows.Forms.Label(); this.label7 = new System.Windows.Forms.Label();
this.label6 = new System.Windows.Forms.Label(); this.label6 = new System.Windows.Forms.Label();
@ -259,7 +259,6 @@
this.Name = "PceBgViewer"; this.Name = "PceBgViewer";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Background Viewer"; this.Text = "Background Viewer";
this.Load += new System.EventHandler(this.PceBgViewer_Load);
this.PceBgViewerMenu.ResumeLayout(false); this.PceBgViewerMenu.ResumeLayout(false);
this.PceBgViewerMenu.PerformLayout(); this.PceBgViewerMenu.PerformLayout();
this.groupBox1.ResumeLayout(false); this.groupBox1.ResumeLayout(false);
@ -275,7 +274,7 @@
#endregion #endregion
private PCEBGCanvas canvas; private PceBgCanvas canvas;
private MenuStripEx PceBgViewerMenu; private MenuStripEx PceBgViewerMenu;
private System.Windows.Forms.ToolStripMenuItem ViewerSubMenu; private System.Windows.Forms.ToolStripMenuItem ViewerSubMenu;
private System.Windows.Forms.ToolStripMenuItem ExitMenuItem; private System.Windows.Forms.ToolStripMenuItem ExitMenuItem;

View File

@ -10,9 +10,10 @@ namespace BizHawk.Client.EmuHawk
public partial class PceBgViewer : Form, IToolFormAutoConfig public partial class PceBgViewer : Form, IToolFormAutoConfig
{ {
[RequiredService] [RequiredService]
private PCEngine _pce { get; set; } private PCEngine PCE { get; set; }
[ConfigPersist] [ConfigPersist]
// ReSharper disable once UnusedMember.Local
private int RefreshRateConfig private int RefreshRateConfig
{ {
get => RefreshRate.Value; get => RefreshRate.Value;
@ -27,23 +28,19 @@ namespace BizHawk.Client.EmuHawk
Activated += (o, e) => Generate(); Activated += (o, e) => Generate();
} }
private void PceBgViewer_Load(object sender, EventArgs e)
{
}
#region Public API #region Public API
public bool AskSaveChanges() { return true; } public bool AskSaveChanges() => true;
public bool UpdateBefore => true; public bool UpdateBefore => true;
public unsafe void Generate() public unsafe void Generate()
{ {
if (_pce.Frame % RefreshRate.Value != 0) if (PCE.Frame % RefreshRate.Value != 0)
{ {
return; return;
} }
var vdc = _vdcType == 0 ? _pce.VDC1 : _pce.VDC2; var vdc = _vdcType == 0 ? PCE.VDC1 : PCE.VDC2;
var width = 8 * vdc.BatWidth; var width = 8 * vdc.BatWidth;
var height = 8 * vdc.BatHeight; var height = 8 * vdc.BatHeight;
@ -67,11 +64,11 @@ namespace BizHawk.Client.EmuHawk
byte c = vdc.PatternBuffer[(tileNo * 64) + (yOfs * 8) + xOfs]; byte c = vdc.PatternBuffer[(tileNo * 64) + (yOfs * 8) + xOfs];
if (c == 0) if (c == 0)
{ {
*p = _pce.VCE.Palette[0]; *p = PCE.VCE.Palette[0];
} }
else else
{ {
*p = _pce.VCE.Palette[paletteBase + c]; *p = PCE.VCE.Palette[paletteBase + c];
} }
} }
@ -107,7 +104,7 @@ namespace BizHawk.Client.EmuHawk
private void FileSubMenu_DropDownOpened(object sender, EventArgs e) private void FileSubMenu_DropDownOpened(object sender, EventArgs e)
{ {
VDC2MenuItem.Enabled = _pce.SystemId == "SGX"; VDC2MenuItem.Enabled = PCE.SystemId == "SGX";
VDC1MenuItem.Checked = _vdcType == 0; VDC1MenuItem.Checked = _vdcType == 0;
VDC2MenuItem.Checked = _vdcType == 1; VDC2MenuItem.Checked = _vdcType == 1;
@ -132,7 +129,7 @@ namespace BizHawk.Client.EmuHawk
private void Canvas_MouseMove(object sender, MouseEventArgs e) private void Canvas_MouseMove(object sender, MouseEventArgs e)
{ {
var vdc = _vdcType == 0 ? _pce.VDC1 : _pce.VDC2; var vdc = _vdcType == 0 ? PCE.VDC1 : PCE.VDC2;
int xTile = e.X / 8; int xTile = e.X / 8;
int yTile = e.Y / 8; int yTile = e.Y / 8;
int tileNo = vdc.VRAM[(ushort)((yTile * vdc.BatWidth) + xTile)] & 0x07FF; int tileNo = vdc.VRAM[(ushort)((yTile * vdc.BatWidth) + xTile)] & 0x07FF;

View File

@ -93,7 +93,7 @@
this.btnExport.TabIndex = 0; this.btnExport.TabIndex = 0;
this.btnExport.Text = "Export"; this.btnExport.Text = "Export";
this.btnExport.UseVisualStyleBackColor = true; this.btnExport.UseVisualStyleBackColor = true;
this.btnExport.Click += new System.EventHandler(this.btnExport_Click); this.btnExport.Click += new System.EventHandler(this.BtnExport_Click);
// //
// groupBox1 // groupBox1
// //
@ -127,7 +127,6 @@
this.lvPsgWaveforms.UseCompatibleStateImageBehavior = false; this.lvPsgWaveforms.UseCompatibleStateImageBehavior = false;
this.lvPsgWaveforms.View = System.Windows.Forms.View.Details; this.lvPsgWaveforms.View = System.Windows.Forms.View.Details;
this.lvPsgWaveforms.AfterLabelEdit += new System.Windows.Forms.LabelEditEventHandler(this.lvPsgWaveforms_AfterLabelEdit); this.lvPsgWaveforms.AfterLabelEdit += new System.Windows.Forms.LabelEditEventHandler(this.lvPsgWaveforms_AfterLabelEdit);
this.lvPsgWaveforms.ItemActivate += new System.EventHandler(this.lvPsgWaveforms_ItemActivate);
this.lvPsgWaveforms.KeyDown += new System.Windows.Forms.KeyEventHandler(this.lvPsgWaveforms_KeyDown); this.lvPsgWaveforms.KeyDown += new System.Windows.Forms.KeyEventHandler(this.lvPsgWaveforms_KeyDown);
// //
// colName // colName
@ -149,7 +148,7 @@
this.btnReset.TabIndex = 1; this.btnReset.TabIndex = 1;
this.btnReset.Text = "Reset"; this.btnReset.Text = "Reset";
this.btnReset.UseVisualStyleBackColor = true; this.btnReset.UseVisualStyleBackColor = true;
this.btnReset.Click += new System.EventHandler(this.btnReset_Click); this.btnReset.Click += new System.EventHandler(this.BtnReset_Click);
// //
// groupBox2 // groupBox2
// //
@ -186,7 +185,6 @@
this.lvChEn.UseCompatibleStateImageBehavior = false; this.lvChEn.UseCompatibleStateImageBehavior = false;
this.lvChEn.View = System.Windows.Forms.View.List; this.lvChEn.View = System.Windows.Forms.View.List;
this.lvChEn.ItemChecked += new System.Windows.Forms.ItemCheckedEventHandler(this.lvChEn_ItemChecked); this.lvChEn.ItemChecked += new System.Windows.Forms.ItemCheckedEventHandler(this.lvChEn_ItemChecked);
this.lvChEn.ItemSelectionChanged += new System.Windows.Forms.ListViewItemSelectionChangedEventHandler(this.lvChEn_ItemSelectionChanged);
// //
// groupBox3 // groupBox3
// //

View File

@ -14,7 +14,7 @@ namespace BizHawk.Client.EmuHawk
public partial class PCESoundDebugger : Form, IToolFormAutoConfig public partial class PCESoundDebugger : Form, IToolFormAutoConfig
{ {
[RequiredService] [RequiredService]
private PCEngine _pce { get; set; } private PCEngine PCE { get; set; }
public PCESoundDebugger() public PCESoundDebugger()
{ {
@ -25,12 +25,15 @@ namespace BizHawk.Client.EmuHawk
SetStyle(ControlStyles.OptimizedDoubleBuffer, true); SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
} }
readonly byte[] waveformTemp = new byte[32 * 2]; private readonly byte[] _waveformTemp = new byte[32 * 2];
protected override void OnShown(EventArgs e) protected override void OnShown(EventArgs e)
{ {
for (int i = 0; i < lvChEn.Items.Count; i++) for (int i = 0; i < lvChEn.Items.Count; i++)
{
lvChEn.Items[i].Checked = true; lvChEn.Items[i].Checked = true;
}
base.OnShown(e); base.OnShown(e);
} }
@ -38,10 +41,10 @@ namespace BizHawk.Client.EmuHawk
public void UpdateValues() public void UpdateValues()
{ {
foreach (var entry in PSGEntries) foreach (var entry in _psgEntries)
{ {
entry.wasactive = entry.active; entry.WasActive = entry.Active;
entry.active = false; entry.Active = false;
} }
bool sync = false; bool sync = false;
@ -50,9 +53,9 @@ namespace BizHawk.Client.EmuHawk
for (int i = 0; i < 6; i++) for (int i = 0; i < 6; i++)
{ {
var ch = _pce.PSG.Channels[i]; var ch = PCE.PSG.Channels[i];
//these conditions mean a sample isnt playing // these conditions mean a sample isn't playing
if (!ch.Enabled) if (!ch.Enabled)
{ {
lvChannels.Items[i].SubItems[1].Text = "-"; lvChannels.Items[i].SubItems[1].Text = "-";
@ -81,55 +84,60 @@ namespace BizHawk.Client.EmuHawk
// ok, a sample is playing. copy out the waveform // ok, a sample is playing. copy out the waveform
short[] waveform = (short[])ch.Wave.Clone(); short[] waveform = (short[])ch.Wave.Clone();
// hash it // hash it
var ms = new MemoryStream(waveformTemp); var ms = new MemoryStream(_waveformTemp);
var bw = new BinaryWriter(ms); var bw = new BinaryWriter(ms);
foreach (var s in waveform) foreach (var s in waveform)
{
bw.Write(s); bw.Write(s);
bw.Flush(); }
string md5 = waveformTemp.HashMD5();
if (!PSGEntryTable.ContainsKey(md5)) bw.Flush();
string md5 = _waveformTemp.HashMD5();
if (!_psgEntryTable.ContainsKey(md5))
{ {
var entry = new PSGEntry() var entry = new PsgEntry
{ {
hash = md5, Name = md5,
name = md5, WaveForm = waveform,
waveform = waveform, Active = true,
active = true, HitCount = 1,
hitcount = 1, Index = _psgEntries.Count
index = PSGEntries.Count
}; };
PSGEntries.Add(entry); _psgEntries.Add(entry);
PSGEntryTable[md5] = entry; _psgEntryTable[md5] = entry;
sync = true; sync = true;
LastSamples[i] = entry; _lastSamples[i] = entry;
} }
else else
{ {
PSGEntry entry = PSGEntryTable[md5]; PsgEntry entry = _psgEntryTable[md5];
entry.active = true; entry.Active = true;
// are we playing the same sample as before? // are we playing the same sample as before?
if (LastSamples[i] == entry) { } if (_lastSamples[i] != entry)
else
//if (!entry.wasactive)
{ {
LastSamples[i] = entry; _lastSamples[i] = entry;
entry.hitcount++; entry.HitCount++;
if (entry.index < lvPsgWaveforms.Items.Count) if (entry.Index < lvPsgWaveforms.Items.Count)
lvPsgWaveforms.Items[entry.index].SubItems[1].Text = entry.hitcount.ToString(); {
lvPsgWaveforms.Items[entry.Index].SubItems[1].Text = entry.HitCount.ToString();
}
else else
{
sync = true; sync = true;
} }
} }
}
lvChannels.Items[i].SubItems[3].Text = PSGEntryTable[md5].name; lvChannels.Items[i].SubItems[3].Text = _psgEntryTable[md5].Name;
continue; continue;
DEAD: DEAD:
LastSamples[i] = null; _lastSamples[i] = null;
} }
if (sync) if (sync)
@ -143,44 +151,41 @@ namespace BizHawk.Client.EmuHawk
// Todo // Todo
} }
class PSGEntry private class PsgEntry
{ {
public int index; public int Index { get; set; }
public bool active, wasactive; public bool Active { get; set; }
public int hitcount; public bool WasActive { get; set; }
public string hash; public int HitCount { get; set; }
public string name; public string Name { get; set; }
public short[] waveform; public short[] WaveForm { get; set; }
} }
readonly PSGEntry[] LastSamples = new PSGEntry[8]; private readonly PsgEntry[] _lastSamples = new PsgEntry[8];
readonly List<PSGEntry> PSGEntries = new List<PSGEntry>(); private readonly List<PsgEntry> _psgEntries = new List<PsgEntry>();
readonly Dictionary<string, PSGEntry> PSGEntryTable = new Dictionary<string, PSGEntry>(); private readonly Dictionary<string, PsgEntry> _psgEntryTable = new Dictionary<string, PsgEntry>();
public void Restart() public void Restart()
{ {
} }
public bool AskSaveChanges() public bool AskSaveChanges() => true;
{
return true;
}
public bool UpdateBefore => false; public bool UpdateBefore => false;
// 32*16 samples, 16bit, mono, 8khz (but we'll change the sample rate) // 32*16 samples, 16bit, mono, 8khz (but we'll change the sample rate)
static readonly byte[] emptyWav = { private static readonly byte[] EmptyWav = {
0x52, 0x49, 0x46, 0x46, 0x24, 0x04, 0x00, 0x00, 0x57, 0x41, 0x56, 0x45, 0x66, 0x6D, 0x74, 0x20, 0x52, 0x49, 0x46, 0x46, 0x24, 0x04, 0x00, 0x00, 0x57, 0x41, 0x56, 0x45, 0x66, 0x6D, 0x74, 0x20,
0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0xE0, 0x2E, 0x00, 0x00, 0xC0, 0x5D, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0xE0, 0x2E, 0x00, 0x00, 0xC0, 0x5D, 0x00, 0x00,
0x02, 0x00, 0x10, 0x00, 0x64, 0x61, 0x74, 0x61, 0x00, 0x04, 0x00, 0x00, 0x02, 0x00, 0x10, 0x00, 0x64, 0x61, 0x74, 0x61, 0x00, 0x04, 0x00, 0x00,
}; };
private void btnExport_Click(object sender, EventArgs e) private void BtnExport_Click(object sender, EventArgs e)
{ {
string tmpf = $"{Path.GetTempFileName()}.zip"; string tmpFilename = $"{Path.GetTempFileName()}.zip";
using (var stream = new FileStream(tmpf, FileMode.Create, FileAccess.Write, FileShare.Read)) using (var stream = new FileStream(tmpFilename, FileMode.Create, FileAccess.Write, FileShare.Read))
{ {
var zip = new ZipOutputStream(stream) var zip = new ZipOutputStream(stream)
{ {
@ -188,55 +193,54 @@ namespace BizHawk.Client.EmuHawk
UseZip64 = UseZip64.Off UseZip64 = UseZip64.Off
}; };
foreach (var entry in PSGEntries) foreach (var entry in _psgEntries)
{ {
var ze = new ZipEntry($"{entry.name}.wav") { CompressionMethod = CompressionMethod.Deflated }; var ze = new ZipEntry($"{entry.Name}.wav") { CompressionMethod = CompressionMethod.Deflated };
zip.PutNextEntry(ze); zip.PutNextEntry(ze);
var ms = new MemoryStream(); var ms = new MemoryStream();
var bw = new BinaryWriter(ms); var bw = new BinaryWriter(ms);
bw.Write(emptyWav, 0, emptyWav.Length); bw.Write(EmptyWav, 0, EmptyWav.Length);
ms.Position = 0x18; // samplerate and avgbytespersecond ms.Position = 0x18; // samplerate and avgbytespersecond
bw.Write(20000); bw.Write(20000);
bw.Write(20000 * 2); bw.Write(20000 * 2);
bw.Flush(); bw.Flush();
ms.Position = 0x2C; ms.Position = 0x2C;
for (int i = 0; i < 32; i++) for (int i = 0; i < 32; i++)
{
for (int j = 0; j < 16; j++) for (int j = 0; j < 16; j++)
bw.Write(entry.waveform[i]); {
bw.Write(entry.WaveForm[i]);
}
}
bw.Flush(); bw.Flush();
var buf = ms.GetBuffer(); var buf = ms.GetBuffer();
zip.Write(buf, 0, (int)ms.Length); zip.Write(buf, 0, (int)ms.Length);
zip.Flush(); zip.Flush();
zip.CloseEntry(); zip.CloseEntry();
} }
zip.Close(); zip.Close();
stream.Flush(); stream.Flush();
} }
System.Diagnostics.Process.Start(tmpf); System.Diagnostics.Process.Start(tmpFilename);
} }
class ZipDataSource : IStaticDataSource private void BtnReset_Click(object sender, EventArgs e)
{ {
public ZipDataSource(byte[] data) { this.data = data; } _psgEntryTable.Clear();
byte[] data; _psgEntries.Clear();
public Stream GetSource() { return new MemoryStream(data); } for (int i = 0; i < 8; i++) _lastSamples[i] = null;
}
private void btnReset_Click(object sender, EventArgs e)
{
PSGEntryTable.Clear();
PSGEntries.Clear();
for (int i = 0; i < 8; i++) LastSamples[i] = null;
SyncLists(); SyncLists();
} }
void SyncLists() private void SyncLists()
{ {
lvPsgWaveforms.Items.Clear(); lvPsgWaveforms.Items.Clear();
foreach (var entry in PSGEntries) foreach (var entry in _psgEntries)
{ {
var lvi = new ListViewItem(entry.name); var lvi = new ListViewItem(entry.Name);
lvi.SubItems.Add(entry.hitcount.ToString()); lvi.SubItems.Add(entry.HitCount.ToString());
lvPsgWaveforms.Items.Add(lvi); lvPsgWaveforms.Items.Add(lvi);
} }
} }
@ -249,26 +253,18 @@ namespace BizHawk.Client.EmuHawk
} }
} }
private void lvPsgWaveforms_ItemActivate(object sender, EventArgs e)
{
}
private void lvPsgWaveforms_AfterLabelEdit(object sender, LabelEditEventArgs e) private void lvPsgWaveforms_AfterLabelEdit(object sender, LabelEditEventArgs e)
{ {
var entry = PSGEntries[e.Item]; var entry = _psgEntries[e.Item];
entry.name = e.Label; entry.Name = e.Label;
}
private void lvChEn_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
{
} }
private void lvChEn_ItemChecked(object sender, ItemCheckedEventArgs e) private void lvChEn_ItemChecked(object sender, ItemCheckedEventArgs e)
{ {
for (int i = 0; i < 6; i++) for (int i = 0; i < 6; i++)
_pce.PSG.UserMute[i] = !lvChEn.Items[i].Checked; {
PCE.PSG.UserMute[i] = !lvChEn.Items[i].Checked;
}
} }
} }
} }

View File

@ -1,6 +1,6 @@
namespace BizHawk.Client.EmuHawk namespace BizHawk.Client.EmuHawk
{ {
partial class PCETileViewer partial class PceTileViewer
{ {
/// <summary> /// <summary>
/// Required designer variable. /// Required designer variable.
@ -65,7 +65,7 @@
this.bmpViewBGPal.Size = new System.Drawing.Size(256, 256); this.bmpViewBGPal.Size = new System.Drawing.Size(256, 256);
this.bmpViewBGPal.TabIndex = 3; this.bmpViewBGPal.TabIndex = 3;
this.bmpViewBGPal.Text = "bmpView2"; this.bmpViewBGPal.Text = "bmpView2";
this.bmpViewBGPal.MouseClick += new System.Windows.Forms.MouseEventHandler(this.bmpViewBGPal_MouseClick); this.bmpViewBGPal.MouseClick += new System.Windows.Forms.MouseEventHandler(this.BmpViewBGPal_MouseClick);
// //
// bmpViewBG // bmpViewBG
// //
@ -93,7 +93,7 @@
this.bmpViewSPPal.Size = new System.Drawing.Size(256, 256); this.bmpViewSPPal.Size = new System.Drawing.Size(256, 256);
this.bmpViewSPPal.TabIndex = 1; this.bmpViewSPPal.TabIndex = 1;
this.bmpViewSPPal.Text = "bmpView4"; this.bmpViewSPPal.Text = "bmpView4";
this.bmpViewSPPal.MouseClick += new System.Windows.Forms.MouseEventHandler(this.bmpViewSPPal_MouseClick); this.bmpViewSPPal.MouseClick += new System.Windows.Forms.MouseEventHandler(this.BmpViewSPPal_MouseClick);
// //
// bmpViewSP // bmpViewSP
// //
@ -112,7 +112,7 @@
this.checkBoxVDC2.TabIndex = 6; this.checkBoxVDC2.TabIndex = 6;
this.checkBoxVDC2.Text = "VDC 2"; this.checkBoxVDC2.Text = "VDC 2";
this.checkBoxVDC2.UseVisualStyleBackColor = true; this.checkBoxVDC2.UseVisualStyleBackColor = true;
this.checkBoxVDC2.CheckedChanged += new System.EventHandler(this.checkBoxVDC2_CheckedChanged); this.checkBoxVDC2.CheckedChanged += new System.EventHandler(this.CheckBoxVDC2_CheckedChanged);
// //
// label1 // label1
// //
@ -150,14 +150,14 @@
this.saveBackgroundScreenshotToolStripMenuItem.Name = "saveBackgroundScreenshotToolStripMenuItem"; this.saveBackgroundScreenshotToolStripMenuItem.Name = "saveBackgroundScreenshotToolStripMenuItem";
this.saveBackgroundScreenshotToolStripMenuItem.Size = new System.Drawing.Size(198, 22); this.saveBackgroundScreenshotToolStripMenuItem.Size = new System.Drawing.Size(198, 22);
this.saveBackgroundScreenshotToolStripMenuItem.Text = "Save BG Screenshot..."; this.saveBackgroundScreenshotToolStripMenuItem.Text = "Save BG Screenshot...";
this.saveBackgroundScreenshotToolStripMenuItem.Click += new System.EventHandler(this.saveBackgroundScreenshotToolStripMenuItem_Click); this.saveBackgroundScreenshotToolStripMenuItem.Click += new System.EventHandler(this.SaveBackgroundScreenshotMenuItem_Click);
// //
// saveSpriteScreenshotToolStripMenuItem // saveSpriteScreenshotToolStripMenuItem
// //
this.saveSpriteScreenshotToolStripMenuItem.Name = "saveSpriteScreenshotToolStripMenuItem"; this.saveSpriteScreenshotToolStripMenuItem.Name = "saveSpriteScreenshotToolStripMenuItem";
this.saveSpriteScreenshotToolStripMenuItem.Size = new System.Drawing.Size(198, 22); this.saveSpriteScreenshotToolStripMenuItem.Size = new System.Drawing.Size(198, 22);
this.saveSpriteScreenshotToolStripMenuItem.Text = "Save Sprite Screenshot..."; this.saveSpriteScreenshotToolStripMenuItem.Text = "Save Sprite Screenshot...";
this.saveSpriteScreenshotToolStripMenuItem.Click += new System.EventHandler(this.saveSpriteScreenshotToolStripMenuItem_Click); this.saveSpriteScreenshotToolStripMenuItem.Click += new System.EventHandler(this.SaveSpriteScreenshotMenuItem_Click);
// //
// toolStripSeparator1 // toolStripSeparator1
// //
@ -170,7 +170,7 @@
this.closeToolStripMenuItem.ShortcutKeyDisplayString = "Alt+F4"; this.closeToolStripMenuItem.ShortcutKeyDisplayString = "Alt+F4";
this.closeToolStripMenuItem.Size = new System.Drawing.Size(198, 22); this.closeToolStripMenuItem.Size = new System.Drawing.Size(198, 22);
this.closeToolStripMenuItem.Text = "&Close"; this.closeToolStripMenuItem.Text = "&Close";
this.closeToolStripMenuItem.Click += new System.EventHandler(this.closeToolStripMenuItem_Click); this.closeToolStripMenuItem.Click += new System.EventHandler(this.CloseMenuItem_Click);
// //
// PCETileViewer // PCETileViewer
// //
@ -185,10 +185,10 @@
this.Icon = global::BizHawk.Client.EmuHawk.Properties.Resources.pce_MultiSize; this.Icon = global::BizHawk.Client.EmuHawk.Properties.Resources.pce_MultiSize;
this.KeyPreview = true; this.KeyPreview = true;
this.MainMenuStrip = this.menuStrip1; this.MainMenuStrip = this.menuStrip1;
this.Name = "PCETileViewer"; this.Name = "PceTileViewer";
this.Text = "Tile Viewer"; this.Text = "Tile Viewer";
this.Load += new System.EventHandler(this.PCETileViewer_Load); this.Load += new System.EventHandler(this.PceTileViewer_Load);
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.PCETileViewer_KeyDown); this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.PceTileViewer_KeyDown);
this.groupBox1.ResumeLayout(false); this.groupBox1.ResumeLayout(false);
this.groupBox2.ResumeLayout(false); this.groupBox2.ResumeLayout(false);
this.menuStrip1.ResumeLayout(false); this.menuStrip1.ResumeLayout(false);

View File

@ -8,18 +8,18 @@ using BizHawk.Emulation.Common;
namespace BizHawk.Client.EmuHawk namespace BizHawk.Client.EmuHawk
{ {
public partial class PCETileViewer : Form, IToolFormAutoConfig public partial class PceTileViewer : Form, IToolFormAutoConfig
{ {
[RequiredService] [RequiredService]
public PCEngine emu { get; private set; } public PCEngine Emu { get; private set; }
private VDC vdc; private VDC _vdc;
private VCE vce; private VCE _vce;
private int bgpalnum; private int _bgPalNum;
private int sppalnum; private int _spPalNum;
public PCETileViewer() public PceTileViewer()
{ {
InitializeComponent(); InitializeComponent();
bmpViewBG.ChangeBitmapSize(512, 256); bmpViewBG.ChangeBitmapSize(512, 256);
@ -74,49 +74,50 @@ namespace BizHawk.Client.EmuHawk
unsafe void DrawSprites() unsafe void DrawSprites()
{ {
var lockdata = bmpViewSP.BMP.LockBits(new Rectangle(0, 0, 512, 256), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); var lockData = bmpViewSP.BMP.LockBits(new Rectangle(0, 0, 512, 256), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
int* dest = (int*)lockdata.Scan0; int* dest = (int*)lockData.Scan0;
int pitch = lockdata.Stride / sizeof(int); int pitch = lockData.Stride / sizeof(int);
fixed (byte* src = vdc.SpriteBuffer) fixed (byte* src = _vdc.SpriteBuffer)
fixed (int* pal = &vce.Palette[256 + sppalnum * 16]) fixed (int* pal = &_vce.Palette[256 + _spPalNum * 16])
{ {
for (int tile = 0; tile < 512; tile++) for (int tile = 0; tile < 512; tile++)
{ {
int srcaddr = tile * 256; int srcAddr = tile * 256;
int tx = tile & 31; int tx = tile & 31;
int ty = tile >> 5; int ty = tile >> 5;
int destaddr = ty * 16 * pitch + tx * 16; int destAddr = ty * 16 * pitch + tx * 16;
Draw16x16(src + srcaddr, dest + destaddr, pitch, pal); Draw16x16(src + srcAddr, dest + destAddr, pitch, pal);
} }
} }
bmpViewSP.BMP.UnlockBits(lockdata);
bmpViewSP.BMP.UnlockBits(lockData);
} }
unsafe void DrawBacks() unsafe void DrawBacks()
{ {
var lockdata = bmpViewBG.BMP.LockBits(new Rectangle(0, 0, 512, 256), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); var lockData = bmpViewBG.BMP.LockBits(new Rectangle(0, 0, 512, 256), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
int* dest = (int*)lockdata.Scan0; int* dest = (int*)lockData.Scan0;
int pitch = lockdata.Stride / sizeof(int); int pitch = lockData.Stride / sizeof(int);
fixed (byte* src = vdc.PatternBuffer) fixed (byte* src = _vdc.PatternBuffer)
fixed (int* pal = &vce.Palette[0 + bgpalnum * 16]) fixed (int* pal = &_vce.Palette[0 + _bgPalNum * 16])
{ {
for (int tile = 0; tile < 2048; tile++) for (int tile = 0; tile < 2048; tile++)
{ {
int srcaddr = tile * 64; int srcAddr = tile * 64;
int tx = tile & 63; int tx = tile & 63;
int ty = tile >> 6; int ty = tile >> 6;
int destaddr = ty * 8 * pitch + tx * 8; int destAddr = ty * 8 * pitch + tx * 8;
Draw8x8(src + srcaddr, dest + destaddr, pitch, pal); Draw8x8(src + srcAddr, dest + destAddr, pitch, pal);
} }
} }
bmpViewBG.BMP.UnlockBits(lockdata); bmpViewBG.BMP.UnlockBits(lockData);
} }
unsafe void DrawPalettes() unsafe void DrawPalettes()
{ {
fixed (int* pal = vce.Palette) fixed (int* pal = _vce.Palette)
{ {
DrawPalette(bmpViewBGPal.BMP, pal); DrawPalette(bmpViewBGPal.BMP, pal);
DrawPalette(bmpViewSPPal.BMP, pal + 256); DrawPalette(bmpViewSPPal.BMP, pal + 256);
@ -125,28 +126,30 @@ namespace BizHawk.Client.EmuHawk
static unsafe void DrawPalette(Bitmap bmp, int* pal) static unsafe void DrawPalette(Bitmap bmp, int* pal)
{ {
var lockdata = bmp.LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); var lockData = bmp.LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
int* dest = (int*)lockdata.Scan0; int* dest = (int*)lockData.Scan0;
int pitch = lockdata.Stride / sizeof(int); int pitch = lockData.Stride / sizeof(int);
int inc = pitch - 256; int inc = pitch - 256;
for (int j = 0; j < 256; j++) for (int j = 0; j < 256; j++)
{ {
for (int i = 0; i < 256; i++) for (int i = 0; i < 256; i++)
{ {
int pindex = j & 0xf0 | i >> 4; int pIndex = j & 0xf0 | i >> 4;
*dest++ = pal[pindex]; *dest++ = pal[pIndex];
} }
dest += inc; dest += inc;
} }
bmp.UnlockBits(lockdata);
bmp.UnlockBits(lockData);
} }
public void Restart() public void Restart()
{ {
vce = emu.VCE; _vce = Emu.VCE;
if (emu.SystemId == "SGX") if (Emu.SystemId == "SGX")
{ {
checkBoxVDC2.Enabled = true; checkBoxVDC2.Enabled = true;
} }
@ -155,41 +158,39 @@ namespace BizHawk.Client.EmuHawk
checkBoxVDC2.Enabled = false; checkBoxVDC2.Enabled = false;
checkBoxVDC2.Checked = false; checkBoxVDC2.Checked = false;
} }
checkBoxVDC2_CheckedChanged(null, null);
CheckBoxVDC2_CheckedChanged(null, null);
} }
public bool AskSaveChanges() public bool AskSaveChanges() => true;
{
return true;
}
public bool UpdateBefore => true; public bool UpdateBefore => true;
#endregion #endregion
private void checkBoxVDC2_CheckedChanged(object sender, EventArgs e) private void CheckBoxVDC2_CheckedChanged(object sender, EventArgs e)
{ {
vdc = checkBoxVDC2.Checked ? emu.VDC2 : emu.VDC1; _vdc = checkBoxVDC2.Checked ? Emu.VDC2 : Emu.VDC1;
UpdateValues(); UpdateValues();
} }
private void bmpViewBGPal_MouseClick(object sender, MouseEventArgs e) private void BmpViewBGPal_MouseClick(object sender, MouseEventArgs e)
{ {
int p = Math.Min(Math.Max(e.Y / 16, 0), 15); int p = Math.Min(Math.Max(e.Y / 16, 0), 15);
bgpalnum = p; _bgPalNum = p;
DrawBacks(); DrawBacks();
bmpViewBG.Refresh(); bmpViewBG.Refresh();
} }
private void bmpViewSPPal_MouseClick(object sender, MouseEventArgs e) private void BmpViewSPPal_MouseClick(object sender, MouseEventArgs e)
{ {
int p = Math.Min(Math.Max(e.Y / 16, 0), 15); int p = Math.Min(Math.Max(e.Y / 16, 0), 15);
sppalnum = p; _spPalNum = p;
DrawSprites(); DrawSprites();
bmpViewSP.Refresh(); bmpViewSP.Refresh();
} }
private void PCETileViewer_KeyDown(object sender, KeyEventArgs e) private void PceTileViewer_KeyDown(object sender, KeyEventArgs e)
{ {
if (ModifierKeys.HasFlag(Keys.Control) && e.KeyCode == Keys.C) if (ModifierKeys.HasFlag(Keys.Control) && e.KeyCode == Keys.C)
{ {
@ -203,32 +204,31 @@ namespace BizHawk.Client.EmuHawk
top = found; top = found;
} while (found != null && found.HasChildren); } while (found != null && found.HasChildren);
if (found is BmpView) if (found is BmpView bv)
{ {
var bv = found as BmpView;
Clipboard.SetImage(bv.BMP); Clipboard.SetImage(bv.BMP);
} }
} }
} }
private void closeToolStripMenuItem_Click(object sender, EventArgs e) private void CloseMenuItem_Click(object sender, EventArgs e)
{ {
Close(); Close();
} }
private void saveBackgroundScreenshotToolStripMenuItem_Click(object sender, EventArgs e) private void SaveBackgroundScreenshotMenuItem_Click(object sender, EventArgs e)
{ {
bmpViewBG.SaveFile(); bmpViewBG.SaveFile();
} }
private void saveSpriteScreenshotToolStripMenuItem_Click(object sender, EventArgs e) private void SaveSpriteScreenshotMenuItem_Click(object sender, EventArgs e)
{ {
bmpViewSP.SaveFile(); bmpViewSP.SaveFile();
} }
private void PCETileViewer_Load(object sender, EventArgs e) private void PceTileViewer_Load(object sender, EventArgs e)
{ {
vce = emu.VCE; _vce = Emu.VCE;
} }
} }
} }

View File

@ -1,6 +1,6 @@
namespace BizHawk.Client.EmuHawk namespace BizHawk.Client.EmuHawk
{ {
partial class SmsVDPViewer partial class SmsVdpViewer
{ {
/// <summary> /// <summary>
/// Required designer variable. /// Required designer variable.
@ -147,14 +147,14 @@
this.savePalettesScrenshotToolStripMenuItem.Name = "savePalettesScrenshotToolStripMenuItem"; this.savePalettesScrenshotToolStripMenuItem.Name = "savePalettesScrenshotToolStripMenuItem";
this.savePalettesScrenshotToolStripMenuItem.Size = new System.Drawing.Size(203, 22); this.savePalettesScrenshotToolStripMenuItem.Size = new System.Drawing.Size(203, 22);
this.savePalettesScrenshotToolStripMenuItem.Text = "Save Palettes Screnshot..."; this.savePalettesScrenshotToolStripMenuItem.Text = "Save Palettes Screnshot...";
this.savePalettesScrenshotToolStripMenuItem.Click += new System.EventHandler(this.savePalettesScrenshotToolStripMenuItem_Click); this.savePalettesScrenshotToolStripMenuItem.Click += new System.EventHandler(this.SavePalettesScreenshotMenuItem_Click);
// //
// saveBGScreenshotToolStripMenuItem // saveBGScreenshotToolStripMenuItem
// //
this.saveBGScreenshotToolStripMenuItem.Name = "saveBGScreenshotToolStripMenuItem"; this.saveBGScreenshotToolStripMenuItem.Name = "saveBGScreenshotToolStripMenuItem";
this.saveBGScreenshotToolStripMenuItem.Size = new System.Drawing.Size(203, 22); this.saveBGScreenshotToolStripMenuItem.Size = new System.Drawing.Size(203, 22);
this.saveBGScreenshotToolStripMenuItem.Text = "Save BG Screenshot..."; this.saveBGScreenshotToolStripMenuItem.Text = "Save BG Screenshot...";
this.saveBGScreenshotToolStripMenuItem.Click += new System.EventHandler(this.saveBGScreenshotToolStripMenuItem_Click); this.saveBGScreenshotToolStripMenuItem.Click += new System.EventHandler(this.SaveBgScreenshotMenuItem_Click);
// //
// toolStripSeparator1 // toolStripSeparator1
// //
@ -183,9 +183,8 @@
this.Icon = global::BizHawk.Client.EmuHawk.Properties.Resources.sms_MultiSize; this.Icon = global::BizHawk.Client.EmuHawk.Properties.Resources.sms_MultiSize;
this.KeyPreview = true; this.KeyPreview = true;
this.MainMenuStrip = this.menuStrip1; this.MainMenuStrip = this.menuStrip1;
this.Name = "SmsVDPViewer"; this.Name = "SmsVdpViewer";
this.Text = "VDP Viewer"; this.Text = "VDP Viewer";
this.Load += new System.EventHandler(this.VDPViewer_Load);
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.VDPViewer_KeyDown); this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.VDPViewer_KeyDown);
this.groupBox1.ResumeLayout(false); this.groupBox1.ResumeLayout(false);
this.groupBox2.ResumeLayout(false); this.groupBox2.ResumeLayout(false);

View File

@ -1,28 +1,21 @@
using System; using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing; using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms; using System.Windows.Forms;
using BizHawk.Emulation.Cores.Sega.MasterSystem; using BizHawk.Emulation.Cores.Sega.MasterSystem;
using BizHawk.Common;
using BizHawk.Client.Common;
using System.Drawing.Imaging; using System.Drawing.Imaging;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
namespace BizHawk.Client.EmuHawk namespace BizHawk.Client.EmuHawk
{ {
public partial class SmsVDPViewer : Form, IToolFormAutoConfig public partial class SmsVdpViewer : Form, IToolFormAutoConfig
{ {
[RequiredService] [RequiredService]
private SMS sms { get; set; } private SMS Sms { get; set; }
private VDP vdp => sms.Vdp; private VDP Vdp => Sms.Vdp;
int palindex = 0; private int _palIndex;
public SmsVDPViewer() public SmsVdpViewer()
{ {
InitializeComponent(); InitializeComponent();
@ -45,86 +38,86 @@ namespace BizHawk.Client.EmuHawk
static unsafe void Draw8x8hv(byte* src, int* dest, int pitch, int* pal, bool hflip, bool vflip) static unsafe void Draw8x8hv(byte* src, int* dest, int pitch, int* pal, bool hflip, bool vflip)
{ {
int incx = hflip ? -1 : 1; int incX = hflip ? -1 : 1;
int incy = vflip ? -pitch : pitch; int incY = vflip ? -pitch : pitch;
if (hflip) if (hflip)
dest -= incx * 7; dest -= incX * 7;
if (vflip) if (vflip)
dest -= incy * 7; dest -= incY * 7;
incy -= incx * 8; incY -= incX * 8;
for (int j = 0; j < 8; j++) for (int j = 0; j < 8; j++)
{ {
for (int i = 0; i < 8; i++) for (int i = 0; i < 8; i++)
{ {
*dest = pal[*src++]; *dest = pal[*src++];
dest += incx; dest += incX;
} }
dest += incy; dest += incY;
} }
} }
unsafe void DrawTiles(int *pal) unsafe void DrawTiles(int *pal)
{ {
var lockdata = bmpViewTiles.BMP.LockBits(new Rectangle(0, 0, 256, 128), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); var lockData = bmpViewTiles.BMP.LockBits(new Rectangle(0, 0, 256, 128), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
int* dest = (int*)lockdata.Scan0; int* dest = (int*)lockData.Scan0;
int pitch = lockdata.Stride / sizeof(int); int pitch = lockData.Stride / sizeof(int);
fixed (byte* src = vdp.PatternBuffer) fixed (byte* src = Vdp.PatternBuffer)
{ {
for (int tile = 0; tile < 512; tile++) for (int tile = 0; tile < 512; tile++)
{ {
int srcaddr = tile * 64; int srcAddr = tile * 64;
int tx = tile & 31; int tx = tile & 31;
int ty = tile >> 5; int ty = tile >> 5;
int destaddr = ty * 8 * pitch + tx * 8; int destAddr = ty * 8 * pitch + tx * 8;
Draw8x8(src + srcaddr, dest + destaddr, pitch, pal); Draw8x8(src + srcAddr, dest + destAddr, pitch, pal);
} }
} }
bmpViewTiles.BMP.UnlockBits(lockdata); bmpViewTiles.BMP.UnlockBits(lockData);
bmpViewTiles.Refresh(); bmpViewTiles.Refresh();
} }
unsafe void DrawBG(int* pal) unsafe void DrawBG(int* pal)
{ {
int bgheight = vdp.FrameHeight == 192 ? 224 : 256; int bgHeight = Vdp.FrameHeight == 192 ? 224 : 256;
int maxtile = bgheight * 4; int maxTile = bgHeight * 4;
if (bgheight != bmpViewBG.BMP.Height) if (bgHeight != bmpViewBG.BMP.Height)
{ {
bmpViewBG.Height = bgheight; bmpViewBG.Height = bgHeight;
bmpViewBG.ChangeBitmapSize(256, bgheight); bmpViewBG.ChangeBitmapSize(256, bgHeight);
} }
var lockdata = bmpViewBG.BMP.LockBits(new Rectangle(0, 0, 256, bgheight), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); var lockData = bmpViewBG.BMP.LockBits(new Rectangle(0, 0, 256, bgHeight), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
int* dest = (int*)lockdata.Scan0; int* dest = (int*)lockData.Scan0;
int pitch = lockdata.Stride / sizeof(int); int pitch = lockData.Stride / sizeof(int);
fixed (byte* src = vdp.PatternBuffer) fixed (byte* src = Vdp.PatternBuffer)
fixed (byte* vram = vdp.VRAM) fixed (byte* vram = Vdp.VRAM)
{ {
short* map = (short*)(vram + vdp.CalcNameTableBase()); short* map = (short*)(vram + Vdp.CalcNameTableBase());
for (int tile = 0; tile < maxtile; tile++) for (int tile = 0; tile < maxTile; tile++)
{ {
short bgent = *map++; short bgent = *map++;
bool hflip = (bgent & 1 << 9) != 0; bool hFlip = (bgent & 1 << 9) != 0;
bool vflip = (bgent & 1 << 10) != 0; bool vFlip = (bgent & 1 << 10) != 0;
int* tpal = pal + ((bgent & 1 << 11) >> 7); int* tpal = pal + ((bgent & 1 << 11) >> 7);
int srcaddr = (bgent & 511) * 64; int srcAddr = (bgent & 511) * 64;
int tx = tile & 31; int tx = tile & 31;
int ty = tile >> 5; int ty = tile >> 5;
int destaddr = ty * 8 * pitch + tx * 8; int destAddr = ty * 8 * pitch + tx * 8;
Draw8x8hv(src + srcaddr, dest + destaddr, pitch, tpal, hflip, vflip); Draw8x8hv(src + srcAddr, dest + destAddr, pitch, tpal, hFlip, vFlip);
} }
} }
bmpViewBG.BMP.UnlockBits(lockdata); bmpViewBG.BMP.UnlockBits(lockData);
bmpViewBG.Refresh(); bmpViewBG.Refresh();
} }
unsafe void DrawPal(int* pal) unsafe void DrawPal(int* pal)
{ {
var lockdata = bmpViewPalette.BMP.LockBits(new Rectangle(0, 0, 16, 2), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); var lockData = bmpViewPalette.BMP.LockBits(new Rectangle(0, 0, 16, 2), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
int* dest = (int*)lockdata.Scan0; int* dest = (int*)lockData.Scan0;
int pitch = lockdata.Stride / sizeof(int); int pitch = lockData.Stride / sizeof(int);
for (int j = 0; j < 2; j++) for (int j = 0; j < 2; j++)
{ {
@ -132,10 +125,11 @@ namespace BizHawk.Client.EmuHawk
{ {
*dest++ = *pal++; *dest++ = *pal++;
} }
dest -= 16; dest -= 16;
dest += pitch; dest += pitch;
} }
bmpViewPalette.BMP.UnlockBits(lockdata); bmpViewPalette.BMP.UnlockBits(lockData);
bmpViewPalette.Refresh(); bmpViewPalette.Refresh();
} }
@ -145,9 +139,9 @@ namespace BizHawk.Client.EmuHawk
{ {
unsafe unsafe
{ {
fixed (int* pal = vdp.Palette) fixed (int* pal = Vdp.Palette)
{ {
DrawTiles(pal + palindex * 16); DrawTiles(pal + _palIndex * 16);
DrawBG(pal); DrawBG(pal);
DrawPal(pal); DrawPal(pal);
} }
@ -164,22 +158,19 @@ namespace BizHawk.Client.EmuHawk
UpdateValues(); UpdateValues();
} }
public bool AskSaveChanges() public bool AskSaveChanges() => true;
{
return true;
}
public bool UpdateBefore => true; public bool UpdateBefore => true;
private void bmpViewPalette_MouseClick(object sender, MouseEventArgs e) private void bmpViewPalette_MouseClick(object sender, MouseEventArgs e)
{ {
int p = Math.Min(Math.Max(e.Y / 16, 0), 1); int p = Math.Min(Math.Max(e.Y / 16, 0), 1);
palindex = p; _palIndex = p;
unsafe unsafe
{ {
fixed (int* pal = vdp.Palette) fixed (int* pal = Vdp.Palette)
{ {
DrawTiles(pal + palindex * 16); DrawTiles(pal + _palIndex * 16);
} }
} }
} }
@ -198,9 +189,8 @@ namespace BizHawk.Client.EmuHawk
top = found; top = found;
} while (found != null && found.HasChildren); } while (found != null && found.HasChildren);
if (found is BmpView) if (found is BmpView bv)
{ {
var bv = found as BmpView;
Clipboard.SetImage(bv.BMP); Clipboard.SetImage(bv.BMP);
} }
} }
@ -211,21 +201,17 @@ namespace BizHawk.Client.EmuHawk
Close(); Close();
} }
private void VDPViewer_Load(object sender, EventArgs e)
{
}
private void saveTilesScreenshotToolStripMenuItem_Click(object sender, EventArgs e) private void saveTilesScreenshotToolStripMenuItem_Click(object sender, EventArgs e)
{ {
bmpViewTiles.SaveFile(); bmpViewTiles.SaveFile();
} }
private void savePalettesScrenshotToolStripMenuItem_Click(object sender, EventArgs e) private void SavePalettesScreenshotMenuItem_Click(object sender, EventArgs e)
{ {
bmpViewPalette.SaveFile(); bmpViewPalette.SaveFile();
} }
private void saveBGScreenshotToolStripMenuItem_Click(object sender, EventArgs e) private void SaveBgScreenshotMenuItem_Click(object sender, EventArgs e)
{ {
bmpViewBG.SaveFile(); bmpViewBG.SaveFile();
} }

View File

@ -24,22 +24,22 @@ namespace BizHawk.Client.EmuHawk
// Hex: 0 1 2 3 4 5 6 7 8 9 A B C D E F // Hex: 0 1 2 3 4 5 6 7 8 9 A B C D E F
private readonly Dictionary<char, int> _gameGenieTable = new Dictionary<char, int> private readonly Dictionary<char, int> _gameGenieTable = new Dictionary<char, int>
{ {
{ 'D', 0 }, // 0000 ['D'] = 0, // 0000
{ 'F', 1 }, // 0001 ['F'] = 1, // 0001
{ '4', 2 }, // 0010 ['4'] = 2, // 0010
{ '7', 3 }, // 0011 ['7'] = 3, // 0011
{ '0', 4 }, // 0100 ['0'] = 4, // 0100
{ '9', 5 }, // 0101 ['9'] = 5, // 0101
{ '1', 6 }, // 0110 ['1'] = 6, // 0110
{ '5', 7 }, // 0111 ['5'] = 7, // 0111
{ '6', 8 }, // 1000 ['6'] = 8, // 1000
{ 'B', 9 }, // 1001 ['B'] = 9, // 1001
{ 'C', 10 }, // 1010 ['C'] = 10, // 1010
{ '8', 11 }, // 1011 ['8'] = 11, // 1011
{ 'A', 12 }, // 1100 ['A'] = 12, // 1100
{ '2', 13 }, // 1101 ['2'] = 13, // 1101
{ '3', 14 }, // 1110 ['3'] = 14, // 1110
{ 'E', 15 } // 1111 ['E'] = 15 // 1111
}; };
private bool _processing; private bool _processing;
@ -56,8 +56,9 @@ namespace BizHawk.Client.EmuHawk
#region Public API #region Public API
public bool AskSaveChanges() { return true; } public bool AskSaveChanges() => true;
public bool UpdateBefore { get { return false; } } public bool UpdateBefore => false;
public void Restart() public void Restart()
{ {
// Do nothing // Do nothing
@ -216,7 +217,7 @@ namespace BizHawk.Client.EmuHawk
MemoryDomains["System Bus"], MemoryDomains["System Bus"],
address, address,
WatchSize.Byte, WatchSize.Byte,
Client.Common.DisplayType.Hex, Common.DisplayType.Hex,
false, false,
name name
); );

View File

@ -2661,7 +2661,7 @@
// messagetimer // messagetimer
// //
this.messagetimer.Interval = 5000; this.messagetimer.Interval = 5000;
this.messagetimer.Tick += new System.EventHandler(this.messagetimer_Tick); this.messagetimer.Tick += new System.EventHandler(this.MessageTimer_Tick);
// //
// SNESGraphicsDebugger // SNESGraphicsDebugger
// //

View File

@ -26,14 +26,11 @@ using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.Reflection; using System.Drawing.Imaging;
using System.Windows.Forms; using System.Windows.Forms;
using BizHawk.Client.EmuHawk.WinFormExtensions;
using BizHawk.Common.NumberExtensions;
using BizHawk.Client.Common;
using BizHawk.Emulation.Cores.Nintendo.SNES; using BizHawk.Emulation.Cores.Nintendo.SNES;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
using BizHawk.Client.EmuHawk;
using BizHawk.Common; using BizHawk.Common;
namespace BizHawk.Client.EmuHawk namespace BizHawk.Client.EmuHawk
@ -43,7 +40,7 @@ namespace BizHawk.Client.EmuHawk
readonly List<DisplayTypeItem> displayTypeItems = new List<DisplayTypeItem>(); readonly List<DisplayTypeItem> displayTypeItems = new List<DisplayTypeItem>();
public bool UpdateBefore => false; public bool UpdateBefore => false;
public bool AskSaveChanges() { return true; } public bool AskSaveChanges() => true;
[RequiredService] [RequiredService]
private LibsnesCore Emulator { get; set; } private LibsnesCore Emulator { get; set; }
@ -60,7 +57,6 @@ namespace BizHawk.Client.EmuHawk
public void Restart() public void Restart()
{ {
} }
public SNESGraphicsDebugger() public SNESGraphicsDebugger()
@ -92,10 +88,12 @@ namespace BizHawk.Client.EmuHawk
comboDisplayType.DataSource = displayTypeItems; comboDisplayType.DataSource = displayTypeItems;
comboDisplayType.SelectedIndex = 2; comboDisplayType.SelectedIndex = 2;
var paletteTypeItems = new List<PaletteTypeItem>(); var paletteTypeItems = new List<PaletteTypeItem>
paletteTypeItems.Add(new PaletteTypeItem("BizHawk", SnesColors.ColorType.BizHawk)); {
paletteTypeItems.Add(new PaletteTypeItem("bsnes", SnesColors.ColorType.BSNES)); new PaletteTypeItem("BizHawk", SnesColors.ColorType.BizHawk),
paletteTypeItems.Add(new PaletteTypeItem("Snes9X", SnesColors.ColorType.Snes9x)); new PaletteTypeItem("bsnes", SnesColors.ColorType.BSNES),
new PaletteTypeItem("Snes9X", SnesColors.ColorType.Snes9x)
};
suppression = true; suppression = true;
comboPalette.DataSource = paletteTypeItems; comboPalette.DataSource = paletteTypeItems;
comboPalette.SelectedIndex = 0; comboPalette.SelectedIndex = 0;
@ -106,13 +104,12 @@ namespace BizHawk.Client.EmuHawk
SyncViewerSize(); SyncViewerSize();
SyncColorSelection(); SyncColorSelection();
//tabctrlDetails.SelectedIndex = 1;
SetTab(null); SetTab(null);
UserBackdropColor = -1; UserBackdropColor = -1;
} }
LibsnesCore currentSnesCore; private LibsnesCore currentSnesCore;
protected override void OnClosed(EventArgs e) protected override void OnClosed(EventArgs e)
{ {
base.OnClosed(e); base.OnClosed(e);
@ -120,17 +117,17 @@ namespace BizHawk.Client.EmuHawk
currentSnesCore = null; currentSnesCore = null;
} }
string FormatBpp(int bpp) private string FormatBpp(int bpp)
{ {
if (bpp == 0) return "---"; return bpp == 0 ? "---" : bpp.ToString();
else return bpp.ToString();
} }
string FormatVramAddress(int address) string FormatVramAddress(int address)
{ {
int excess = address & 1023; int excess = address & 1023;
if (excess != 0) return $"@{address:X4}"; return excess != 0
else return $"@{address:X4} ({address / 1024}K)"; ? $"@{address:X4}"
: $"@{address:X4} ({address / 1024}K)";
} }
public void NewUpdate(ToolFormUpdateType type) { } public void NewUpdate(ToolFormUpdateType type) { }
@ -181,9 +178,9 @@ namespace BizHawk.Client.EmuHawk
void SyncCore() void SyncCore()
{ {
if (currentSnesCore != Emulator && currentSnesCore != null) if (currentSnesCore != Emulator)
{ {
currentSnesCore.ScanlineHookManager.Unregister(this); currentSnesCore?.ScanlineHookManager.Unregister(this);
} }
if (currentSnesCore != Emulator && Emulator != null) if (currentSnesCore != Emulator && Emulator != null)
@ -205,7 +202,7 @@ namespace BizHawk.Client.EmuHawk
} }
} }
void ScanlineHook(int line) private void ScanlineHook(int line)
{ {
int target = (int)nudScanline.Value; int target = (int)nudScanline.Value;
if (target == line) if (target == line)
@ -215,13 +212,13 @@ namespace BizHawk.Client.EmuHawk
} }
} }
SNESGraphicsDecoder gd; private SNESGraphicsDecoder gd;
SNESGraphicsDecoder.ScreenInfo si; private SNESGraphicsDecoder.ScreenInfo si;
SNESGraphicsDecoder.TileEntry[] map; private SNESGraphicsDecoder.TileEntry[] map;
byte[,] spriteMap = new byte[256, 224]; private byte[,] spriteMap = new byte[256, 224];
SNESGraphicsDecoder.BGMode viewBgMode; private SNESGraphicsDecoder.BGMode viewBgMode;
void RegenerateData() private void RegenerateData()
{ {
gd?.Dispose(); gd?.Dispose();
gd = null; gd = null;
@ -272,9 +269,9 @@ namespace BizHawk.Client.EmuHawk
txtScreenBG3TSize.Text = FormatBpp(si.BG.BG3.TileSize); txtScreenBG3TSize.Text = FormatBpp(si.BG.BG3.TileSize);
txtScreenBG4TSize.Text = FormatBpp(si.BG.BG4.TileSize); txtScreenBG4TSize.Text = FormatBpp(si.BG.BG4.TileSize);
int bgnum = comboBGProps.SelectedIndex + 1; int bgNum = comboBGProps.SelectedIndex + 1;
var bg = si.BG[bgnum]; var bg = si.BG[bgNum];
txtBG1TSizeBits.Text = bg.TILESIZE.ToString(); txtBG1TSizeBits.Text = bg.TILESIZE.ToString();
txtBG1TSizeDescr.Text = string.Format("{0}x{0}", bg.TileSize); txtBG1TSizeDescr.Text = string.Format("{0}x{0}", bg.TileSize);
txtBG1Bpp.Text = FormatBpp(bg.Bpp); txtBG1Bpp.Text = FormatBpp(bg.Bpp);
@ -513,10 +510,10 @@ namespace BizHawk.Client.EmuHawk
} }
} }
class DisplayTypeItem private class DisplayTypeItem
{ {
public eDisplayType Type { get; private set; } public eDisplayType Type { get; }
public string Descr { get; private set; } public string Descr { get; }
public DisplayTypeItem(string descr, eDisplayType type) public DisplayTypeItem(string descr, eDisplayType type)
{ {
Type = type; Type = type;
@ -524,7 +521,7 @@ namespace BizHawk.Client.EmuHawk
} }
} }
class PaletteTypeItem private class PaletteTypeItem
{ {
public SnesColors.ColorType Type { get; } public SnesColors.ColorType Type { get; }
public string Descr { get; } public string Descr { get; }
@ -591,21 +588,24 @@ namespace BizHawk.Client.EmuHawk
InternalUpdateValues(); InternalUpdateValues();
} }
const int paletteCellSize = 16; private const int paletteCellSize = 16;
const int paletteCellSpacing = 3; private const int paletteCellSpacing = 3;
int[] lastPalette; private int[] lastPalette;
int lastColorNum = 0; private int lastColorNum = 0;
int selectedColorNum = 0; private int selectedColorNum = 0;
SNESGraphicsDecoder.PaletteSelection currPaletteSelection; private SNESGraphicsDecoder.PaletteSelection currPaletteSelection;
Rectangle GetPaletteRegion(int start, int num) private Rectangle GetPaletteRegion(int start, int num)
{ {
var ret = new Rectangle(); var ret = new Rectangle
ret.X = start % 16; {
ret.Y = start / 16; X = start % 16,
ret.Width = num; Y = start / 16,
ret.Height = num / 16; Width = num,
Height = num / 16
};
if (ret.Height == 0) ret.Height = 1; if (ret.Height == 0) ret.Height = 1;
if (ret.Width > 16) ret.Width = 16; if (ret.Width > 16) ret.Width = 16;
return ret; return ret;
@ -627,12 +627,12 @@ namespace BizHawk.Client.EmuHawk
int height = cellTotalSize * region.Height; int height = cellTotalSize * region.Height;
var rect = new Rectangle(x, y, width, height); var rect = new Rectangle(x, y, width, height);
using (var pen = new Pen(color)) using var pen = new Pen(color);
g.DrawRectangle(pen, rect); g.DrawRectangle(pen, rect);
} }
//if a tile set is being displayed, this will adapt the user's color selection into a palette to be used for rendering the tiles //if a tile set is being displayed, this will adapt the user's color selection into a palette to be used for rendering the tiles
SNESGraphicsDecoder.PaletteSelection GetPaletteSelectionForTileDisplay(int colorSelection) private SNESGraphicsDecoder.PaletteSelection GetPaletteSelectionForTileDisplay(int colorSelection)
{ {
int bpp = 0; int bpp = 0;
var selection = CurrDisplaySelection; var selection = CurrDisplaySelection;
@ -644,7 +644,7 @@ namespace BizHawk.Client.EmuHawk
if (selection == eDisplayType.OBJTiles0) bpp = 4; if (selection == eDisplayType.OBJTiles0) bpp = 4;
if (selection == eDisplayType.OBJTiles1) bpp = 4; if (selection == eDisplayType.OBJTiles1) bpp = 4;
SNESGraphicsDecoder.PaletteSelection ret = new SNESGraphicsDecoder.PaletteSelection(); var ret = new SNESGraphicsDecoder.PaletteSelection();
if(bpp == 0) return ret; if(bpp == 0) return ret;
//mode7 ext is fixed to use the top 128 colors //mode7 ext is fixed to use the top 128 colors
@ -660,15 +660,12 @@ namespace BizHawk.Client.EmuHawk
return ret; return ret;
} }
SNESGraphicsDecoder NewDecoder() private SNESGraphicsDecoder NewDecoder()
{ {
if (currentSnesCore != null) return currentSnesCore != null ? new SNESGraphicsDecoder(currentSnesCore.Api, currentSnesCore.CurrPalette) : null;
return new SNESGraphicsDecoder(currentSnesCore.Api, currentSnesCore.CurrPalette);
else
return null;
} }
void RenderPalette() private void RenderPalette()
{ {
//var gd = NewDecoder(); //?? //var gd = NewDecoder(); //??
lastPalette = gd.GetPalette(); lastPalette = gd.GetPalette();
@ -684,12 +681,10 @@ namespace BizHawk.Client.EmuHawk
{ {
int rgb555 = lastPalette[y * 16 + x]; int rgb555 = lastPalette[y * 16 + x];
int color = gd.Colorize(rgb555); int color = gd.Colorize(rgb555);
using (var brush = new SolidBrush(Color.FromArgb(color))) using var brush = new SolidBrush(Color.FromArgb(color));
{
g.FillRectangle(brush, new Rectangle(paletteCellSpacing + x * cellTotalSize, paletteCellSpacing + y * cellTotalSize, paletteCellSize, paletteCellSize)); g.FillRectangle(brush, new Rectangle(paletteCellSpacing + x * cellTotalSize, paletteCellSpacing + y * cellTotalSize, paletteCellSize, paletteCellSize));
} }
} }
}
//draw selection boxes: //draw selection boxes:
//first, draw the current selection //first, draw the current selection
@ -719,7 +714,7 @@ namespace BizHawk.Client.EmuHawk
paletteViewer.SetBitmap(bmp); paletteViewer.SetBitmap(bmp);
} }
static string BGModeShortName(SNESGraphicsDecoder.BGMode mode, int bpp) private static string BGModeShortName(SNESGraphicsDecoder.BGMode mode, int bpp)
{ {
if (mode == SNESGraphicsDecoder.BGMode.Unavailable) return "Unavailable"; if (mode == SNESGraphicsDecoder.BGMode.Unavailable) return "Unavailable";
if (mode == SNESGraphicsDecoder.BGMode.Text) return $"Text{bpp}bpp"; if (mode == SNESGraphicsDecoder.BGMode.Text) return $"Text{bpp}bpp";
@ -730,7 +725,7 @@ namespace BizHawk.Client.EmuHawk
throw new InvalidOperationException(); throw new InvalidOperationException();
} }
void UpdateOBJDetails() private void UpdateOBJDetails()
{ {
if (currObjDataState == null) return; if (currObjDataState == null) return;
var oam = new SNESGraphicsDecoder.OAMInfo(gd, si, currObjDataState.Number); var oam = new SNESGraphicsDecoder.OAMInfo(gd, si, currObjDataState.Number);
@ -747,7 +742,7 @@ namespace BizHawk.Client.EmuHawk
txtObjNameAddr.Text = $"@{oam.Address:X4}"; txtObjNameAddr.Text = $"@{oam.Address:X4}";
} }
void UpdateTileDetails() private void UpdateTileDetails()
{ {
if (currTileDataState == null) return; if (currTileDataState == null) return;
var mode = BGModeForDisplayType(currTileDataState.Type); var mode = BGModeForDisplayType(currTileDataState.Type);
@ -760,7 +755,7 @@ namespace BizHawk.Client.EmuHawk
txtTilePalette.Text = $"#{currTileDataState.Palette:X2}"; txtTilePalette.Text = $"#{currTileDataState.Palette:X2}";
} }
void UpdateMapEntryDetails() private void UpdateMapEntryDetails()
{ {
if (currMapEntryState == null) return; if (currMapEntryState == null) return;
txtMapEntryLocation.Text = $"({currMapEntryState.Location.X},{currMapEntryState.Location.Y}), @{currMapEntryState.entry.address:X4}"; txtMapEntryLocation.Text = $"({currMapEntryState.Location.X},{currMapEntryState.Location.Y}), @{currMapEntryState.entry.address:X4}";
@ -787,7 +782,7 @@ namespace BizHawk.Client.EmuHawk
txtMapEntryTileAddr.Text = $"@{addr:X4}"; txtMapEntryTileAddr.Text = $"@{addr:X4}";
} }
void UpdateColorDetails() private void UpdateColorDetails()
{ {
if (lastPalette == null) return; if (lastPalette == null) return;
@ -802,31 +797,23 @@ namespace BizHawk.Client.EmuHawk
txtPaletteDetailsIndexHex.Text = $"${lastColorNum:X2}"; txtPaletteDetailsIndexHex.Text = $"${lastColorNum:X2}";
txtPaletteDetailsIndex.Text = $"{lastColorNum}"; txtPaletteDetailsIndex.Text = $"{lastColorNum}";
//not being used anymore
//if (lastColorNum < 128) lblDetailsOBJOrBG.Text = "(BG:)"; else lblDetailsOBJOrBG.Text = "(OBJ:)";
//txtPaletteDetailsIndexHexSpecific.Text = $"${lastColorNum & 0x7F:X2}";
//txtPaletteDetailsIndexSpecific.Text = $"{lastColorNum & 0x7F}";
txtPaletteDetailsAddress.Text = $"${lastColorNum * 2:X3}"; txtPaletteDetailsAddress.Text = $"${lastColorNum * 2:X3}";
} }
bool TranslatePaletteCoord(Point pt, out Point outpoint) private bool TranslatePaletteCoord(Point pt, out Point outpoint)
{ {
pt.X -= paletteCellSpacing; pt.X -= paletteCellSpacing;
pt.Y -= paletteCellSpacing; pt.Y -= paletteCellSpacing;
int tx = pt.X / (paletteCellSize + paletteCellSpacing); int tx = pt.X / (paletteCellSize + paletteCellSpacing);
int ty = pt.Y / (paletteCellSize + paletteCellSpacing); int ty = pt.Y / (paletteCellSize + paletteCellSpacing);
outpoint = new Point(tx, ty); outpoint = new Point(tx, ty);
if (tx >= 16 || ty >= 16) return false; return tx < 16 && ty < 16;
return true;
} }
private void paletteViewer_MouseClick(object sender, MouseEventArgs e) private void paletteViewer_MouseClick(object sender, MouseEventArgs e)
{ {
Point pt; bool valid = TranslatePaletteCoord(e.Location, out var pt);
bool valid = TranslatePaletteCoord(e.Location, out pt);
if (!valid) return; if (!valid) return;
selectedColorNum = pt.Y * 16 + pt.X; selectedColorNum = pt.Y * 16 + pt.X;
@ -839,31 +826,22 @@ namespace BizHawk.Client.EmuHawk
InternalUpdateValues(); InternalUpdateValues();
} }
void SyncColorSelection() private void SyncColorSelection()
{ {
currPaletteSelection = GetPaletteSelectionForTileDisplay(selectedColorNum); currPaletteSelection = GetPaletteSelectionForTileDisplay(selectedColorNum);
} }
private void pnDetailsPaletteColor_DoubleClick(object sender, EventArgs e) private void pnDetailsPaletteColor_DoubleClick(object sender, EventArgs e)
{ {
//not workign real well... //not working real well...
//var cd = new ColorDialog(); //var cd = new ColorDialog();
//cd.Color = pnDetailsPaletteColor.BackColor; //cd.Color = pnDetailsPaletteColor.BackColor;
//cd.ShowDialog(this); //cd.ShowDialog(this);
} }
private void rbQuad_CheckedChanged(object sender, EventArgs e)
{
SyncViewerSize();
}
void SyncViewerSize() void SyncViewerSize()
{ {
if (check2x.Checked) viewer.Size = check2x.Checked ? new Size(1024, 1024) : new Size(512, 512);
viewer.Size = new Size(1024, 1024);
else
viewer.Size = new Size(512, 512);
} }
private void checkScanlineControl_CheckedChanged(object sender, EventArgs e) private void checkScanlineControl_CheckedChanged(object sender, EventArgs e)
@ -876,8 +854,8 @@ namespace BizHawk.Client.EmuHawk
SyncViewerSize(); SyncViewerSize();
} }
bool viewerPan = false; private bool viewerPan;
Point panStartLocation; private Point panStartLocation;
private void viewer_MouseDown(object sender, MouseEventArgs e) private void viewer_MouseDown(object sender, MouseEventArgs e)
{ {
viewer.Capture = true; viewer.Capture = true;
@ -892,7 +870,7 @@ namespace BizHawk.Client.EmuHawk
Freeze(); Freeze();
} }
void Freeze() private void Freeze()
{ {
groupFreeze.SuspendLayout(); groupFreeze.SuspendLayout();
@ -920,11 +898,6 @@ namespace BizHawk.Client.EmuHawk
groupFreeze.Refresh(); groupFreeze.Refresh();
} }
enum eFreezeTarget
{
MainViewer
}
private void viewer_MouseUp(object sender, MouseEventArgs e) private void viewer_MouseUp(object sender, MouseEventArgs e)
{ {
viewerPan = false; viewerPan = false;
@ -954,15 +927,15 @@ namespace BizHawk.Client.EmuHawk
} }
} }
class MapEntryState private class MapEntryState
{ {
public SNESGraphicsDecoder.TileEntry entry; public SNESGraphicsDecoder.TileEntry entry;
public int bgnum; public int bgnum;
public Point Location; public Point Location;
} }
MapEntryState currMapEntryState; private MapEntryState currMapEntryState;
class TileDataState private class TileDataState
{ {
public eDisplayType Type; public eDisplayType Type;
public int Bpp; public int Bpp;
@ -970,42 +943,42 @@ namespace BizHawk.Client.EmuHawk
public int Address; public int Address;
public int Palette; public int Palette;
} }
TileDataState currTileDataState; private TileDataState currTileDataState;
class ObjDataState private class ObjDataState
{ {
public int Number; public int Number;
} }
ObjDataState currObjDataState; private ObjDataState currObjDataState;
void RenderTileView() private void RenderTileView()
{ {
if (currMapEntryState != null) if (currMapEntryState != null)
{ {
//view a BG tile //view a BG tile
int paletteStart = 0; int paletteStart = 0;
var bgs = currMapEntryState; var bgs = currMapEntryState;
var oneTileEntry = new SNESGraphicsDecoder.TileEntry[] { bgs.entry }; var oneTileEntry = new[] { bgs.entry };
int tileSize = si.BG[bgs.bgnum].TileSize; int tileSize = si.BG[bgs.bgnum].TileSize;
int pixels = tileSize * tileSize; int pixels = tileSize * tileSize;
var bmp = new Bitmap(tileSize, tileSize, System.Drawing.Imaging.PixelFormat.Format32bppArgb); var bmp = new Bitmap(tileSize, tileSize, PixelFormat.Format32bppArgb);
var bmpdata = bmp.LockBits(new Rectangle(0, 0, tileSize, tileSize), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); var bmpData = bmp.LockBits(new Rectangle(0, 0, tileSize, tileSize), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
if (viewBgMode == SNESGraphicsDecoder.BGMode.Mode7) if (viewBgMode == SNESGraphicsDecoder.BGMode.Mode7)
gd.RenderMode7TilesToScreen((int*)bmpdata.Scan0, bmpdata.Stride / 4, false, false, 1, currMapEntryState.entry.tilenum, 1); gd.RenderMode7TilesToScreen((int*)bmpData.Scan0, bmpData.Stride / 4, false, false, 1, currMapEntryState.entry.tilenum, 1);
else if (viewBgMode == SNESGraphicsDecoder.BGMode.Mode7Ext) else if (viewBgMode == SNESGraphicsDecoder.BGMode.Mode7Ext)
gd.RenderMode7TilesToScreen((int*)bmpdata.Scan0, bmpdata.Stride / 4, true, false, 1, currMapEntryState.entry.tilenum, 1); gd.RenderMode7TilesToScreen((int*)bmpData.Scan0, bmpData.Stride / 4, true, false, 1, currMapEntryState.entry.tilenum, 1);
else if (viewBgMode == SNESGraphicsDecoder.BGMode.Mode7DC) else if (viewBgMode == SNESGraphicsDecoder.BGMode.Mode7DC)
gd.RenderMode7TilesToScreen((int*)bmpdata.Scan0, bmpdata.Stride / 4, false, true, 1, currMapEntryState.entry.tilenum, 1); gd.RenderMode7TilesToScreen((int*)bmpData.Scan0, bmpData.Stride / 4, false, true, 1, currMapEntryState.entry.tilenum, 1);
else else
{ {
gd.DecodeBG((int*)bmpdata.Scan0, bmpdata.Stride / 4, oneTileEntry, si.BG[bgs.bgnum].TiledataAddr, SNESGraphicsDecoder.ScreenSize.Hacky_1x1, si.BG[bgs.bgnum].Bpp, tileSize, paletteStart); gd.DecodeBG((int*)bmpData.Scan0, bmpData.Stride / 4, oneTileEntry, si.BG[bgs.bgnum].TiledataAddr, SNESGraphicsDecoder.ScreenSize.Hacky_1x1, si.BG[bgs.bgnum].Bpp, tileSize, paletteStart);
gd.Paletteize((int*)bmpdata.Scan0, 0, 0, pixels); gd.Paletteize((int*)bmpData.Scan0, 0, 0, pixels);
gd.Colorize((int*)bmpdata.Scan0, 0, pixels); gd.Colorize((int*)bmpData.Scan0, 0, pixels);
} }
bmp.UnlockBits(bmpdata); bmp.UnlockBits(bmpData);
viewerMapEntryTile.SetBitmap(bmp); viewerMapEntryTile.SetBitmap(bmp);
} }
else if (currTileDataState != null) else if (currTileDataState != null)
@ -1014,7 +987,7 @@ namespace BizHawk.Client.EmuHawk
int bpp = currTileDataState.Bpp; int bpp = currTileDataState.Bpp;
var bmp = new Bitmap(8, 8, System.Drawing.Imaging.PixelFormat.Format32bppArgb); var bmp = new Bitmap(8, 8, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
var bmpdata = bmp.LockBits(new Rectangle(0, 0, 8, 8), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); var bmpdata = bmp.LockBits(new Rectangle(0, 0, 8, 8), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
if (currTileDataState.Type == eDisplayType.TilesMode7) if (currTileDataState.Type == eDisplayType.TilesMode7)
gd.RenderMode7TilesToScreen((int*)bmpdata.Scan0, bmpdata.Stride / 4, false, false, 1, currTileDataState.Tile, 1); gd.RenderMode7TilesToScreen((int*)bmpdata.Scan0, bmpdata.Stride / 4, false, false, 1, currTileDataState.Tile, 1);
else if (currTileDataState.Type == eDisplayType.TilesMode7Ext) else if (currTileDataState.Type == eDisplayType.TilesMode7Ext)
@ -1038,34 +1011,39 @@ namespace BizHawk.Client.EmuHawk
int width = bounds.Width; int width = bounds.Width;
int height = bounds.Height; int height = bounds.Height;
var bmp = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb); var bmp = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
var bmpdata = bmp.LockBits(new Rectangle(0, 0, width, height), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); var bmpData = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
gd.RenderSpriteToScreen((int*)bmpdata.Scan0, bmpdata.Stride / 4, 0, 0, si, currObjDataState.Number); gd.RenderSpriteToScreen((int*)bmpData.Scan0, bmpData.Stride / 4, 0, 0, si, currObjDataState.Number);
bmp.UnlockBits(bmpdata); bmp.UnlockBits(bmpData);
viewerObj.SetBitmap(bmp); viewerObj.SetBitmap(bmp);
} }
else else
{ {
var bmp = new Bitmap(8, 8, System.Drawing.Imaging.PixelFormat.Format32bppArgb); var bmp = new Bitmap(8, 8, PixelFormat.Format32bppArgb);
viewerTile.SetBitmap(bmp); viewerTile.SetBitmap(bmp);
} }
} }
void HandleTileViewMouseOver(int pxacross, int pxtall, int bpp, int tx, int ty) void HandleTileViewMouseOver(int pxacross, int pxtall, int bpp, int tx, int ty)
{ {
int tilestride = pxacross / 8; int tileStride = pxacross / 8;
int tilesTall = pxtall / 8; int tilesTall = pxtall / 8;
if (tx < 0 || ty < 0 || tx >= tilestride || ty >= tilesTall) if (tx < 0 || ty < 0 || tx >= tileStride || ty >= tilesTall)
{
return; return;
int tilenum = ty * tilestride + tx; }
currTileDataState = new TileDataState();
currTileDataState.Bpp = bpp; int tileNum = ty * tileStride + tx;
currTileDataState.Type = CurrDisplaySelection; currTileDataState = new TileDataState
currTileDataState.Tile = tilenum; {
Bpp = bpp,
Type = CurrDisplaySelection,
Tile = tileNum
};
currTileDataState.Address = (bpp == 7 ? 8 : bpp) * 8 * currTileDataState.Tile; currTileDataState.Address = (bpp == 7 ? 8 : bpp) * 8 * currTileDataState.Tile;
currTileDataState.Palette = currPaletteSelection.start; currTileDataState.Palette = currPaletteSelection.start;
if (CurrDisplaySelection == eDisplayType.OBJTiles0 || CurrDisplaySelection == eDisplayType.OBJTiles1) if (CurrDisplaySelection == eDisplayType.OBJTiles0 || CurrDisplaySelection == eDisplayType.OBJTiles1)
{ {
if (tilenum < 256) if (tileNum < 256)
currTileDataState.Address += si.OBJTable0Addr; currTileDataState.Address += si.OBJTable0Addr;
else else
currTileDataState.Address += si.OBJTable1Addr - (256*32); currTileDataState.Address += si.OBJTable1Addr - (256*32);
@ -1080,20 +1058,18 @@ namespace BizHawk.Client.EmuHawk
SetTab(tpTile); SetTab(tpTile);
} }
void HandleSpriteMouseOver(int px, int py) private void HandleSpriteMouseOver(int px, int py)
{ {
if (px < 0 || py < 0 || px >= 256 || py >= 224) return; if (px < 0 || py < 0 || px >= 256 || py >= 224) return;
int sprite = spriteMap[px,py]; int sprite = spriteMap[px,py];
if(sprite == 0xFF) return; if(sprite == 0xFF) return;
currObjDataState = new ObjDataState(); currObjDataState = new ObjDataState { Number = sprite };
currObjDataState.Number = sprite;
SetTab(tpOBJ); SetTab(tpOBJ);
} }
void HandleObjMouseOver(int px, int py) private void HandleObjMouseOver(int px, int py)
{ {
int ox = px / si.ObjSizeBounds.Width; int ox = px / si.ObjSizeBounds.Width;
int oy = py / si.ObjSizeBounds.Height; int oy = py / si.ObjSizeBounds.Height;
@ -1103,8 +1079,7 @@ namespace BizHawk.Client.EmuHawk
int objNum = oy * 8 + ox; int objNum = oy * 8 + ox;
currObjDataState = new ObjDataState(); currObjDataState = new ObjDataState { Number = objNum };
currObjDataState.Number = objNum;
//RenderView(); // remember, we were going to highlight the selected sprite somehow as we hover over it //RenderView(); // remember, we were going to highlight the selected sprite somehow as we hover over it
SetTab(tpOBJ); SetTab(tpOBJ);
@ -1180,18 +1155,12 @@ namespace BizHawk.Client.EmuHawk
if (tx < 0) break; if (tx < 0) break;
if (ty < 0) break; if (ty < 0) break;
currMapEntryState = new MapEntryState(); currMapEntryState = new MapEntryState
currMapEntryState.bgnum = (int)CurrDisplaySelection; {
currMapEntryState.entry = map[tloc]; bgnum = (int) CurrDisplaySelection,
currMapEntryState.Location = new Point(tx, ty); entry = map[tloc],
Location = new Point(tx, ty)
//public void DecodeBG(int* screen, int stride, TileEntry[] map, int tiledataBaseAddr, ScreenSize size, int bpp, int tilesize, int paletteStart) };
//var map = gd.FetchTilemap(bg.ScreenAddr, bg.ScreenSize);
//int paletteStart = 0;
//gd.DecodeBG(pixelptr, stride / 4, map, bg.TiledataAddr, bg.ScreenSize, bg.Bpp, bg.TileSize, paletteStart);
//gd.Paletteize(pixelptr, 0, 0, numPixels);
SetTab(tpMapEntry); SetTab(tpMapEntry);
} }
@ -1205,27 +1174,12 @@ namespace BizHawk.Client.EmuHawk
} }
} }
private void viewer_MouseLeave(object sender, EventArgs e)
{
SetTab(null);
}
private void paletteViewer_MouseDown(object sender, MouseEventArgs e) private void paletteViewer_MouseDown(object sender, MouseEventArgs e)
{ {
if ((e.Button & MouseButtons.Right) != 0) if ((e.Button & MouseButtons.Right) != 0)
Freeze(); Freeze();
} }
private void paletteViewer_MouseEnter(object sender, EventArgs e)
{
tabctrlDetails.SelectedIndex = 0;
}
private void paletteViewer_MouseLeave(object sender, EventArgs e)
{
SetTab(null);
}
private void paletteViewer_MouseMove(object sender, MouseEventArgs e) private void paletteViewer_MouseMove(object sender, MouseEventArgs e)
{ {
Point pt; Point pt;
@ -1236,7 +1190,7 @@ namespace BizHawk.Client.EmuHawk
SetTab(tpPalette); SetTab(tpPalette);
} }
static int DecodeWinformsColorToSNES(Color winforms) private static int DecodeWinformsColorToSNES(Color winforms)
{ {
int r = winforms.R; int r = winforms.R;
int g = winforms.G; int g = winforms.G;
@ -1248,7 +1202,7 @@ namespace BizHawk.Client.EmuHawk
return col; return col;
} }
void SyncBackdropColor() private void SyncBackdropColor()
{ {
//TODO //TODO
//if (checkBackdropColor.Checked) //if (checkBackdropColor.Checked)
@ -1270,9 +1224,12 @@ namespace BizHawk.Client.EmuHawk
private void pnBackdropColor_MouseDoubleClick(object sender, MouseEventArgs e) private void pnBackdropColor_MouseDoubleClick(object sender, MouseEventArgs e)
{ {
var cd = new ColorDialog(); var cd = new ColorDialog
cd.Color = pnBackdropColor.BackColor; {
if (cd.ShowDialog(this) == DialogResult.OK) Color = pnBackdropColor.BackColor
};
if (cd.ShowDialog(this).IsOk())
{ {
pnBackdropColor.BackColor = cd.Color; pnBackdropColor.BackColor = cd.Color;
UserBackdropColor = pnBackdropColor.BackColor.ToArgb(); UserBackdropColor = pnBackdropColor.BackColor.ToArgb();
@ -1294,22 +1251,21 @@ namespace BizHawk.Client.EmuHawk
top = found; top = found;
} while (found != null && found.HasChildren); } while (found != null && found.HasChildren);
if (found != null && found is SNESGraphicsViewer) if (found is SNESGraphicsViewer v)
{ {
var v = found as SNESGraphicsViewer;
lock (v) lock (v)
{ {
var bmp = v.GetBitmap(); var bmp = v.GetBitmap();
Clipboard.SetImage(bmp); Clipboard.SetImage(bmp);
} }
string label = ""; string label = "";
if (found.Name == "viewer") if (v.Name == "viewer")
label = displayTypeItems.Find((x) => x.Type == CurrDisplaySelection).Descr; label = displayTypeItems.Find((x) => x.Type == CurrDisplaySelection).Descr;
if (found.Name == "viewerTile") if (v.Name == "viewerTile")
label = "Tile"; label = "Tile";
if (found.Name == "viewerMapEntryTile") if (v.Name == "viewerMapEntryTile")
label = "Map Entry"; label = "Map Entry";
if (found.Name == "paletteViewer") if (v.Name == "paletteViewer")
label = "Palette"; label = "Palette";
labelClipboard.Text = $"{label} copied to clipboard."; labelClipboard.Text = $"{label} copied to clipboard.";
messagetimer.Stop(); messagetimer.Stop();
@ -1322,8 +1278,7 @@ namespace BizHawk.Client.EmuHawk
return base.ProcessCmdKey(ref msg, keyData); return base.ProcessCmdKey(ref msg, keyData);
} }
private void MessageTimer_Tick(object sender, EventArgs e)
private void messagetimer_Tick(object sender, EventArgs e)
{ {
messagetimer.Stop(); messagetimer.Stop();
labelClipboard.Text = "CTRL+C copies the pane under the mouse."; labelClipboard.Text = "CTRL+C copies the pane under the mouse.";
@ -1336,10 +1291,7 @@ namespace BizHawk.Client.EmuHawk
Console.WriteLine("set {0}", pal); Console.WriteLine("set {0}", pal);
var s = Emulator.GetSettings(); var s = Emulator.GetSettings();
s.Palette = pal.ToString(); s.Palette = pal.ToString();
if (currentSnesCore != null) currentSnesCore?.PutSettings(s);
{
currentSnesCore.PutSettings(s);
}
RegenerateData(); RegenerateData();
RenderView(); RenderView();
RenderPalette(); RenderPalette();
@ -1404,23 +1356,17 @@ namespace BizHawk.Client.EmuHawk
private void lblEnPrio0_Click(object sender, EventArgs e) private void lblEnPrio0_Click(object sender, EventArgs e)
{ {
bool any = checkEN0_OBJ.Checked || checkEN0_BG1.Checked || checkEN0_BG2.Checked || checkEN0_BG3.Checked || checkEN0_BG4.Checked;
bool all = checkEN0_OBJ.Checked && checkEN0_BG1.Checked && checkEN0_BG2.Checked && checkEN0_BG3.Checked && checkEN0_BG4.Checked; bool all = checkEN0_OBJ.Checked && checkEN0_BG1.Checked && checkEN0_BG2.Checked && checkEN0_BG3.Checked && checkEN0_BG4.Checked;
bool newval; var newVal = !all;
if (all) newval = false; checkEN0_OBJ.Checked = checkEN0_BG1.Checked = checkEN0_BG2.Checked = checkEN0_BG3.Checked = checkEN0_BG4.Checked = newVal;
else newval = true;
checkEN0_OBJ.Checked = checkEN0_BG1.Checked = checkEN0_BG2.Checked = checkEN0_BG3.Checked = checkEN0_BG4.Checked = newval;
} }
private void lblEnPrio1_Click(object sender, EventArgs e) private void lblEnPrio1_Click(object sender, EventArgs e)
{ {
bool any = checkEN1_OBJ.Checked || checkEN1_BG1.Checked || checkEN1_BG2.Checked || checkEN1_BG3.Checked || checkEN1_BG4.Checked;
bool all = checkEN1_OBJ.Checked && checkEN1_BG1.Checked && checkEN1_BG2.Checked && checkEN1_BG3.Checked && checkEN1_BG4.Checked; bool all = checkEN1_OBJ.Checked && checkEN1_BG1.Checked && checkEN1_BG2.Checked && checkEN1_BG3.Checked && checkEN1_BG4.Checked;
bool newval; var newVal = !all;
if (all) newval = false; checkEN1_OBJ.Checked = checkEN1_BG1.Checked = checkEN1_BG2.Checked = checkEN1_BG3.Checked = checkEN1_BG4.Checked = newVal;
else newval = true;
checkEN1_OBJ.Checked = checkEN1_BG1.Checked = checkEN1_BG2.Checked = checkEN1_BG3.Checked = checkEN1_BG4.Checked = newval;
} }
@ -1435,43 +1381,4 @@ namespace BizHawk.Client.EmuHawk
} }
} //class SNESGraphicsDebugger } //class SNESGraphicsDebugger
static class ControlExtensions
{
static string[] secondPass = new[] { "Size" };
public static T Clone<T>(this T controlToClone)
where T : Control
{
PropertyInfo[] controlProperties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
Type t = controlToClone.GetType();
T instance = Activator.CreateInstance(t) as T;
t.GetProperty("AutoSize").SetValue(instance, false, null);
for (int i = 0; i < 3; i++)
{
foreach (PropertyInfo propInfo in controlProperties)
{
if (!propInfo.CanWrite)
continue;
if (propInfo.Name == "AutoSize")
{ }
else if (propInfo.Name == "WindowTarget")
{ }
else
propInfo.SetValue(instance, propInfo.GetValue(controlToClone, null), null);
}
}
if (instance is RetainedViewportPanel)
{
var clonebmp = ((controlToClone) as RetainedViewportPanel).GetBitmap().Clone() as Bitmap;
((instance) as RetainedViewportPanel).SetBitmap(clonebmp);
}
return instance;
}
}
} //namespace BizHawk.Client.EmuHawk } //namespace BizHawk.Client.EmuHawk

View File

@ -9,17 +9,9 @@ namespace BizHawk.Client.EmuHawk
{ {
SetStyle(ControlStyles.SupportsTransparentBackColor, true); SetStyle(ControlStyles.SupportsTransparentBackColor, true);
if (!DesignMode) if (!DesignMode)
{
BackColor = Color.Transparent; BackColor = Color.Transparent;
} }
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
} }
} }
} }

View File

@ -338,6 +338,7 @@
<s:Boolean x:Key="/Default/UserDictionary/Words/=shaders/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=shaders/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=speccy/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=speccy/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Speedruns/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=Speedruns/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Spriteback/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Sram/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=Sram/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=sSeeki/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=sSeeki/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Statable/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=Statable/@EntryIndexedValue">True</s:Boolean>
@ -375,6 +376,7 @@
<s:Boolean x:Key="/Default/UserDictionary/Words/=Vectrex/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=Vectrex/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Virtua/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=Virtua/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Virtualpad/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=Virtualpad/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=vram/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Vsync/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=Vsync/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Winform/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=Winform/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=winforms/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=winforms/@EntryIndexedValue">True</s:Boolean>