BizHawk/BizHawk.Client.EmuHawk/tools/Cheats/CheatEdit.cs

336 lines
7.4 KiB
C#

using System;
using System.Linq;
using System.Windows.Forms;
using BizHawk.Client.Common;
using BizHawk.Emulation.Common;
using BizHawk.Emulation.Common.IEmulatorExtensions;
namespace BizHawk.Client.EmuHawk
{
public partial class CheatEdit : UserControl
{
public IMemoryDomains MemoryDomains { get; set; }
public CheatEdit()
{
InitializeComponent();
AddressBox.Nullable = false;
ValueBox.Nullable = false;
}
#region Privates
private const string HexInd = "0x";
private Cheat _cheat;
private bool _loading;
private bool _editmode;
private Action _addCallback;
private Action _editCallback;
private void CheatEdit_Load(object sender, EventArgs e)
{
Restart();
}
public void Restart()
{
if (MemoryDomains != null) // the designer needs this check
{
DomainDropDown.Items.Clear();
DomainDropDown.Items.AddRange(MemoryDomains
.Where(d => d.CanPoke())
.Select(d => d.ToString())
.ToArray());
if (MemoryDomains.HasSystemBus)
{
DomainDropDown.SelectedItem = MemoryDomains.SystemBus.ToString();
}
else
{
DomainDropDown.SelectedItem = MemoryDomains.MainMemory.ToString();
}
}
SetFormToDefault();
}
private void SetFormToCheat()
{
_loading = true;
SetSizeSelected(_cheat.Size);
PopulateTypeDropdown();
SetTypeSelected(_cheat.Type);
SetDomainSelected(_cheat.Domain);
AddressBox.SetHexProperties(_cheat.Domain.Size);
ValueBox.ByteSize =
CompareBox.ByteSize =
_cheat.Size;
ValueBox.Type =
CompareBox.Type =
_cheat.Type;
ValueHexIndLabel.Text =
CompareHexIndLabel.Text =
_cheat.Type == Watch.DisplayType.Hex ? HexInd : string.Empty;
BigEndianCheckBox.Checked = _cheat.BigEndian.Value;
NameBox.Text = _cheat.Name;
AddressBox.Text = _cheat.AddressStr;
ValueBox.Text = _cheat.ValueStr;
CompareBox.Text = _cheat.Compare.HasValue ? _cheat.CompareStr : String.Empty;
CheckFormState();
if (!_cheat.Compare.HasValue)
{
CompareBox.Text = String.Empty; // Necessary hack until WatchValueBox.ToRawInt() becomes nullable
}
_loading = false;
}
private void SetFormToDefault()
{
_loading = true;
SetSizeSelected(Watch.WatchSize.Byte);
PopulateTypeDropdown();
NameBox.Text = string.Empty;
if (MemoryDomains != null)
{
AddressBox.SetHexProperties(MemoryDomains.SystemBus.Size);
}
ValueBox.ByteSize =
CompareBox.ByteSize =
Watch.WatchSize.Byte;
ValueBox.Type =
CompareBox.Type =
Watch.DisplayType.Hex;
ValueBox.ResetText();
CompareBox.ResetText();
ValueHexIndLabel.Text =
CompareHexIndLabel.Text =
HexInd;
BigEndianCheckBox.Checked = false;
SetTypeSelected(Watch.DisplayType.Hex);
CheckFormState();
CompareBox.Text = string.Empty; // TODO: A needed hack until WatchValueBox.ToRawInt() becomes nullable
_loading = false;
}
private void SetSizeSelected(Watch.WatchSize size)
{
switch (size)
{
default:
case Watch.WatchSize.Byte:
SizeDropDown.SelectedIndex = 0;
break;
case Watch.WatchSize.Word:
SizeDropDown.SelectedIndex = 1;
break;
case Watch.WatchSize.DWord:
SizeDropDown.SelectedIndex = 2;
break;
}
}
private void SetTypeSelected(Watch.DisplayType type)
{
foreach (var item in DisplayTypeDropDown.Items)
{
if (item.ToString() == Watch.DisplayTypeToString(type))
{
DisplayTypeDropDown.SelectedItem = item;
return;
}
}
}
private void SetDomainSelected(MemoryDomain domain)
{
foreach (var item in DomainDropDown.Items)
{
if (item.ToString() == domain.Name)
{
DomainDropDown.SelectedItem = item;
return;
}
}
}
private void PopulateTypeDropdown()
{
DisplayTypeDropDown.Items.Clear();
switch (SizeDropDown.SelectedIndex)
{
default:
case 0:
DisplayTypeDropDown.Items.AddRange(ByteWatch.ValidTypes.ConvertAll(e => Watch.DisplayTypeToString(e)).ToArray());
break;
case 1:
DisplayTypeDropDown.Items.AddRange(WordWatch.ValidTypes.ConvertAll(e => Watch.DisplayTypeToString(e)).ToArray());
break;
case 2:
DisplayTypeDropDown.Items.AddRange(DWordWatch.ValidTypes.ConvertAll(e => Watch.DisplayTypeToString(e)).ToArray());
break;
}
DisplayTypeDropDown.SelectedItem = DisplayTypeDropDown.Items[0];
}
private void CheckFormState()
{
var valid = !String.IsNullOrWhiteSpace(AddressBox.Text) && !String.IsNullOrWhiteSpace(ValueBox.Text);
AddButton.Enabled = valid;
EditButton.Enabled = _editmode && valid;
}
private void SizeDropDown_SelectedIndexChanged(object sender, EventArgs e)
{
if (!_loading)
{
PopulateTypeDropdown();
ValueBox.ByteSize =
CompareBox.ByteSize =
GetCurrentSize();
}
}
private void DomainDropDown_SelectedIndexChanged(object sender, EventArgs e)
{
if (!_loading)
{
var domain = MemoryDomains[DomainDropDown.SelectedItem.ToString()];
AddressBox.SetHexProperties(domain.Size);
}
}
private Watch.WatchSize GetCurrentSize()
{
switch (SizeDropDown.SelectedIndex)
{
default:
case 0:
return Watch.WatchSize.Byte;
case 1:
return Watch.WatchSize.Word;
case 2:
return Watch.WatchSize.DWord;
}
}
private void DisplayTypeDropDown_SelectedIndexChanged(object sender, EventArgs e)
{
ValueBox.Type =
CompareBox.Type =
Watch.StringToDisplayType(DisplayTypeDropDown.SelectedItem.ToString());
}
private void AddButton_Click(object sender, EventArgs e)
{
if (_addCallback != null)
{
_addCallback();
}
}
private void EditButton_Click(object sender, EventArgs e)
{
if (_editCallback != null)
{
_editCallback();
}
}
#endregion
#region API
public void SetCheat(Cheat cheat)
{
_editmode = true;
_cheat = cheat;
if (cheat.IsSeparator)
{
SetFormToDefault();
}
else
{
SetFormToCheat();
}
}
public void ClearForm()
{
_cheat = Cheat.Separator;
_editmode = false;
SetFormToDefault();
}
public Cheat OriginalCheat
{
get { return _cheat; }
}
public Cheat Cheat
{
get
{
var domain = MemoryDomains[DomainDropDown.SelectedItem.ToString()];
var address = AddressBox.ToRawInt().Value;
//var address = AddressBox.ToRawInt() ?? 0;
if (address < domain.Size)
{
var watch = Watch.GenerateWatch(
MemoryDomains[DomainDropDown.SelectedItem.ToString()],
AddressBox.ToRawInt().Value,
GetCurrentSize(),
Watch.StringToDisplayType(DisplayTypeDropDown.SelectedItem.ToString()),
NameBox.Text,
BigEndianCheckBox.Checked);
return new Cheat(
watch,
ValueBox.ToRawInt().Value,
CompareBox.ToRawInt()
);
}
else
{
MessageBox.Show(address.ToString() + " is not a valid address for the domain " + domain.Name, "Index out of range", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return Cheat.Separator;
}
}
}
public void SetAddEvent(Action addCallback)
{
_addCallback = addCallback;
}
public void SetEditEvent(Action editCallback)
{
_editCallback = editCallback;
}
#endregion
}
}