336 lines
7.4 KiB
C#
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
|
|
}
|
|
}
|