BizHawk/BizHawk.MultiClient/tools/HexEditor.cs

363 lines
12 KiB
C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Globalization;
namespace BizHawk.MultiClient
{
public partial class HexEditor : Form
{
//TODO:
//different back color for frozen addresses
//Find text box - autohighlights matches, and shows total matches
//Users can customize background, & text colors
//Tool strip
//Text box showing currently highlighted address(es) & total
//Show num addresses in group box title (show "address" if 1 address)
//big font for currently mouse over'ed value?
//Unfreeze All items - this one is tricky though, the dialog should keep track of
// which addresses were frozen using this dialog (its own cheatList), and only
// remove those from the Cheats window cheat list
int defaultWidth;
int defaultHeight;
List<ToolStripMenuItem> domainMenuItems = new List<ToolStripMenuItem>();
public HexEditor()
{
InitializeComponent();
Closing += (o, e) => SaveConfigSettings();
}
public void SaveConfigSettings()
{
if (Global.Config.HexEditorSaveWindowPosition)
{
Global.Config.HexEditorWndx = this.Location.X;
Global.Config.HexEditorWndy = this.Location.Y;
Global.Config.HexEditorWidth = this.Right - this.Left;
Global.Config.HexEditorHeight = this.Bottom - this.Top;
}
}
private void HexEditor_Load(object sender, EventArgs e)
{
defaultWidth = this.Size.Width; //Save these first so that the user can restore to its original size
defaultHeight = this.Size.Height;
if (Global.Config.HexEditorSaveWindowPosition)
{
if (Global.Config.HexEditorSaveWindowPosition && Global.Config.HexEditorWndx >= 0 && Global.Config.HexEditorWndy >= 0)
this.Location = new Point(Global.Config.HexEditorWndx, Global.Config.HexEditorWndy);
if (Global.Config.HexEditorWidth >= 0 && Global.Config.HexEditorHeight >= 0)
{
this.Size = new System.Drawing.Size(Global.Config.HexEditorWidth, Global.Config.HexEditorHeight);
}
}
SetMemoryDomainMenu();
}
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
this.Close();
}
public void UpdateValues()
{
if (!this.IsHandleCreated || this.IsDisposed) return;
MemoryViewer.Refresh();
}
public void Restart()
{
if (!this.IsHandleCreated || this.IsDisposed) return;
SetMemoryDomainMenu(); //Calls update routines
MemoryViewer.ResetScrollBar();
}
private void restoreWindowSizeToolStripMenuItem_Click(object sender, EventArgs e)
{
this.Size = new System.Drawing.Size(defaultWidth, defaultHeight);
}
private void autoloadToolStripMenuItem_Click(object sender, EventArgs e)
{
Global.Config.AutoLoadHexEditor ^= true;
}
private void optionsToolStripMenuItem_DropDownOpened(object sender, EventArgs e)
{
enToolStripMenuItem.Checked = MemoryViewer.BigEndian;
switch (MemoryViewer.GetDataSize())
{
default:
case 1:
byteToolStripMenuItem.Checked = true;
byteToolStripMenuItem1.Checked = false;
byteToolStripMenuItem2.Checked = false;
break;
case 2:
byteToolStripMenuItem.Checked = false;
byteToolStripMenuItem1.Checked = true;
byteToolStripMenuItem2.Checked = false;
break;
case 4:
byteToolStripMenuItem.Checked = false;
byteToolStripMenuItem1.Checked = false;
byteToolStripMenuItem2.Checked = true;
break;
}
if (MemoryViewer.GetHighlightedAddress() >= 0)
{
addToRamWatchToolStripMenuItem1.Enabled = true;
freezeAddressToolStripMenuItem.Enabled = true;
}
else
{
addToRamWatchToolStripMenuItem1.Enabled = false;
freezeAddressToolStripMenuItem.Enabled = false;
}
}
private void SetMemoryDomain(int pos)
{
if (pos < Global.Emulator.MemoryDomains.Count) //Sanity check
{
MemoryViewer.SetMemoryDomain(Global.Emulator.MemoryDomains[pos]);
}
UpdateDomainString();
MemoryViewer.ResetScrollBar();
}
private void UpdateDomainString()
{
string memoryDomain = MemoryViewer.GetMemoryDomainStr();
string systemID = Global.Emulator.SystemId;
MemoryViewer.Text = systemID + " " + memoryDomain;
}
private void SetMemoryDomainMenu()
{
memoryDomainsToolStripMenuItem.DropDownItems.Clear();
if (Global.Emulator.MemoryDomains.Count > 0)
{
for (int x = 0; x < Global.Emulator.MemoryDomains.Count; x++)
{
string str = Global.Emulator.MemoryDomains[x].ToString();
var item = new ToolStripMenuItem();
item.Text = str;
{
int z = x;
item.Click += (o, ev) => SetMemoryDomain(z);
}
if (x == 0)
{
SetMemoryDomain(x);
}
memoryDomainsToolStripMenuItem.DropDownItems.Add(item);
domainMenuItems.Add(item);
}
}
else
memoryDomainsToolStripMenuItem.Enabled = false;
}
public void GoToAddress(int address)
{
if (address < MemoryViewer.GetSize())
{
MemoryViewer.SetHighlighted(address);
MemoryViewer.Refresh();
}
}
private void goToAddressToolStripMenuItem_Click(object sender, EventArgs e)
{
InputPrompt i = new InputPrompt();
i.Text = "Go to Address";
i.SetMessage("Enter a hexadecimal value");
i.ShowDialog();
if (i.UserOK)
{
if (InputValidate.IsValidHexNumber(i.UserText))
{
GoToAddress(int.Parse(i.UserText, NumberStyles.HexNumber));
}
}
}
private void HexEditor_Resize(object sender, EventArgs e)
{
MemoryViewer.SetUpScrollBar();
MemoryViewer.Refresh();
}
private void byteToolStripMenuItem_Click(object sender, EventArgs e)
{
MemoryViewer.SetDataSize(1);
}
private void byteToolStripMenuItem1_Click(object sender, EventArgs e)
{
MemoryViewer.SetDataSize(2);
}
private void byteToolStripMenuItem2_Click(object sender, EventArgs e)
{
MemoryViewer.SetDataSize(4);
}
private void enToolStripMenuItem_Click(object sender, EventArgs e)
{
MemoryViewer.BigEndian ^= true;
}
private void MemoryViewer_Paint(object sender, PaintEventArgs e)
{
}
private void AddToRamWatch()
{
//Add to RAM Watch
int address = MemoryViewer.GetPointedAddress();
if (address >= 0)
{
Watch w = new Watch();
w.address = address;
switch (MemoryViewer.GetDataSize())
{
default:
case 1:
w.type = atype.BYTE;
break;
case 2:
w.type = atype.WORD;
break;
case 4:
w.type = atype.DWORD;
break;
}
w.bigendian = MemoryViewer.BigEndian;
w.signed = asigned.HEX;
Global.MainForm.LoadRamWatch();
Global.MainForm.RamWatch1.AddWatch(w);
}
}
private void MemoryViewer_MouseDoubleClick(object sender, MouseEventArgs e)
{
AddToRamWatch();
}
private void pokeToolStripMenuItem_Click(object sender, EventArgs e)
{
int p = MemoryViewer.GetPointedAddress();
if (p >= 0)
{
InputPrompt i = new InputPrompt();
i.Text = "Poke " + String.Format("{0:X}", p);
i.SetMessage("Enter a hexadecimal value");
i.ShowDialog();
if (i.UserOK)
{
if (InputValidate.IsValidHexNumber(i.UserText))
{
int value = int.Parse(i.UserText, NumberStyles.HexNumber);
MemoryViewer.HighlightPointed();
MemoryViewer.PokeHighlighted(value);
}
}
}
}
private void addToRamWatchToolStripMenuItem_Click(object sender, EventArgs e)
{
AddToRamWatch();
}
private void addToRamWatchToolStripMenuItem1_Click(object sender, EventArgs e)
{
AddToRamWatch();
}
private void saveWindowsSettingsToolStripMenuItem_Click(object sender, EventArgs e)
{
Global.Config.HexEditorSaveWindowPosition ^= true;
}
private void settingsToolStripMenuItem_DropDownOpened(object sender, EventArgs e)
{
autoloadToolStripMenuItem.Checked = Global.Config.AutoLoadHexEditor;
saveWindowsSettingsToolStripMenuItem.Checked = Global.Config.HexEditorSaveWindowPosition;
}
private void freezeToolStripMenuItem_Click(object sender, EventArgs e)
{
FreezeAddress();
}
private void FreezeAddress()
{
int address = MemoryViewer.GetPointedAddress();
if (address >= 0)
{
Cheat c = new Cheat();
c.address = address;
c.value = MemoryViewer.GetPointedValue();
c.domain = MemoryViewer.GetDomain();
//TODO: multibyte
switch (MemoryViewer.GetDataSize())
{
default:
case 1:
break;
case 2:
break;
case 4:
break;
}
//w.bigendian = MemoryViewer.BigEndian;
Global.MainForm.Cheats1.AddCheat(c);
}
}
private void freezeAddressToolStripMenuItem_Click(object sender, EventArgs e)
{
FreezeAddress();
}
private void CheckDomainMenuItems()
{
for (int x = 0; x < domainMenuItems.Count; x++)
{
if (MemoryViewer.GetDomain().Name == domainMenuItems[x].Text)
domainMenuItems[x].Checked = true;
else
domainMenuItems[x].Checked = false;
}
}
private void memoryDomainsToolStripMenuItem_DropDownOpened(object sender, EventArgs e)
{
CheckDomainMenuItems();
}
}
}