368 lines
8.3 KiB
C#
368 lines
8.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
using System.Windows.Forms;
|
|
|
|
using BizHawk.Client.Common;
|
|
|
|
namespace BizHawk.Client.EmuHawk
|
|
{
|
|
public partial class NESGameGenie : Form, IToolForm
|
|
{
|
|
private readonly Dictionary<char, int> _gameGenieTable = new Dictionary<char, int>
|
|
{
|
|
{ 'A', 0 }, // 0000
|
|
{ 'P', 1 }, // 0001
|
|
{ 'Z', 2 }, // 0010
|
|
{ 'L', 3 }, // 0011
|
|
{ 'G', 4 }, // 0100
|
|
{ 'I', 5 }, // 0101
|
|
{ 'T', 6 }, // 0110
|
|
{ 'Y', 7 }, // 0111
|
|
{ 'E', 8 }, // 1000
|
|
{ 'O', 9 }, // 1001
|
|
{ 'X', 10 }, // 1010
|
|
{ 'U', 11 }, // 1011
|
|
{ 'K', 12 }, // 1100
|
|
{ 'S', 13 }, // 1101
|
|
{ 'V', 14 }, // 1110
|
|
{ 'N', 15 }, // 1111
|
|
};
|
|
|
|
private int? _address;
|
|
private int? _value;
|
|
private int? _compare;
|
|
|
|
public int? Address { get { return _address; } }
|
|
public int? Value { get { return _value; } }
|
|
public int? Compare { get { return _compare; } }
|
|
|
|
public bool AskSave() { return true; }
|
|
public bool UpdateBefore { get { return false; } }
|
|
public void Restart()
|
|
{
|
|
if (Global.Emulator.SystemId != "NES")
|
|
{
|
|
Close();
|
|
}
|
|
}
|
|
|
|
public void UpdateValues()
|
|
{
|
|
if (Global.Emulator.SystemId != "NES")
|
|
{
|
|
Close();
|
|
}
|
|
}
|
|
|
|
public NESGameGenie()
|
|
{
|
|
InitializeComponent();
|
|
Closing += (o, e) =>
|
|
{
|
|
Global.Config.NesGGSettings.Wndx = Location.X;
|
|
Global.Config.NesGGSettings.Wndy = Location.Y;
|
|
};
|
|
TopMost = Global.Config.NesGGSettings.TopMost;
|
|
AddressBox.SetHexProperties(0x10000);
|
|
ValueBox.SetHexProperties(0x100);
|
|
CompareBox.SetHexProperties(0x100);
|
|
}
|
|
|
|
private void NESGameGenie_Load(object sender, EventArgs e)
|
|
{
|
|
AddCheat.Enabled = false;
|
|
|
|
if (Global.Config.NesGGSettings.UseWindowPosition)
|
|
{
|
|
Location = Global.Config.NesGGSettings.WindowPosition;
|
|
}
|
|
}
|
|
|
|
public void DecodeGameGenieCode(string code)
|
|
{
|
|
var decoder = new NESGameGenieDecoder(code);
|
|
_address = decoder.Address;
|
|
_value = decoder.Value;
|
|
_compare = decoder.Compare;
|
|
SetProperties();
|
|
}
|
|
|
|
private void SetProperties()
|
|
{
|
|
if (_address.HasValue)
|
|
{
|
|
AddressBox.SetFromRawInt(_address.Value);
|
|
}
|
|
else
|
|
{
|
|
AddressBox.ResetText();
|
|
}
|
|
|
|
if (_compare.HasValue)
|
|
{
|
|
CompareBox.SetFromRawInt(_compare.Value);
|
|
}
|
|
else
|
|
{
|
|
CompareBox.ResetText();
|
|
}
|
|
|
|
if (_value.HasValue)
|
|
{
|
|
ValueBox.SetFromRawInt(_value.Value);
|
|
}
|
|
else
|
|
{
|
|
ValueBox.ResetText();
|
|
}
|
|
}
|
|
|
|
private void ClearProperties()
|
|
{
|
|
_address = _value = _compare = null;
|
|
|
|
AddressBox.Text =
|
|
CompareBox.Text =
|
|
ValueBox.Text =
|
|
string.Empty;
|
|
|
|
AddCheat.Enabled = false;
|
|
}
|
|
|
|
private void TryEnableAddCheat()
|
|
{
|
|
AddCheat.Enabled = !string.IsNullOrWhiteSpace(AddressBox.Text)
|
|
&& !string.IsNullOrWhiteSpace(ValueBox.Text)
|
|
&& !string.IsNullOrWhiteSpace(GameGenieCode.Text);
|
|
}
|
|
|
|
private void EncodeGameGenie()
|
|
{
|
|
_address = AddressBox.ToRawInt();
|
|
_value = ValueBox.ToRawInt();
|
|
_compare = CompareBox.ToRawInt();
|
|
GameGenieCode.Text = new NESGameGenieEncoder(_address.Value, _value.Value, _compare).Encode();
|
|
}
|
|
|
|
private void RefreshFloatingWindowControl()
|
|
{
|
|
Owner = Global.Config.NesGGSettings.FloatingWindow ? null : GlobalWin.MainForm;
|
|
}
|
|
|
|
#region Events
|
|
|
|
#region File Menu
|
|
|
|
private void OptionsSubMenu_DropDownOpened(object sender, EventArgs e)
|
|
{
|
|
AutoloadMenuItem.Checked = Global.Config.NESGGAutoload;
|
|
SaveWindowPositionMenuItem.Checked = Global.Config.NesGGSettings.SaveWindowPosition;
|
|
AlwaysOnTopMenuItem.Checked = Global.Config.NesGGSettings.TopMost;
|
|
FloatingWindowMenuItem.Checked = Global.Config.NesGGSettings.FloatingWindow;
|
|
}
|
|
|
|
private void AutoloadMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
Global.Config.NESGGAutoload ^= true;
|
|
}
|
|
|
|
private void SaveWindowPositionMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
Global.Config.NesGGSettings.SaveWindowPosition ^= true;
|
|
}
|
|
|
|
private void ExitMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
Close();
|
|
}
|
|
|
|
private void AlwaysOnTopMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
Global.Config.NesGGSettings.TopMost ^= true;
|
|
TopMost = Global.Config.NesGGSettings.TopMost;
|
|
}
|
|
|
|
private void FloatingWindowMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
Global.Config.NesGGSettings.FloatingWindow ^= true;
|
|
RefreshFloatingWindowControl();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Control Events
|
|
|
|
private void GameGenieCode_KeyPress(object sender, KeyPressEventArgs e)
|
|
{
|
|
if (!_gameGenieTable.ContainsKey(char.ToUpper(e.KeyChar)))
|
|
{
|
|
if (Control.ModifierKeys != Keys.None)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (e.KeyChar != (char)Keys.Back || e.KeyChar != '\b' || e.KeyChar == 22 || e.KeyChar == 1 || e.KeyChar == 3)
|
|
{
|
|
e.Handled = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Encoding.Checked = false;
|
|
}
|
|
}
|
|
|
|
private void ClearButton_Click(object sender, EventArgs e)
|
|
{
|
|
ClearProperties();
|
|
GameGenieCode.Text = string.Empty;
|
|
Encoding.Checked = false;
|
|
}
|
|
|
|
private void AddCheat_Click(object sender, EventArgs e)
|
|
{
|
|
if (!string.IsNullOrWhiteSpace(AddressBox.Text) && !string.IsNullOrWhiteSpace(ValueBox.Text))
|
|
{
|
|
var watch = Watch.GenerateWatch(
|
|
Global.Emulator.MemoryDomains["System Bus"],
|
|
AddressBox.ToRawInt().Value,
|
|
Watch.WatchSize.Byte,
|
|
Watch.DisplayType.Hex,
|
|
GameGenieCode.Text,
|
|
false);
|
|
|
|
Global.CheatList.Add(new Cheat(
|
|
watch,
|
|
ValueBox.ToRawInt().Value,
|
|
CompareBox.ToRawInt()
|
|
));
|
|
}
|
|
}
|
|
|
|
private void GameGenieCode_KeyDown(object sender, KeyEventArgs e)
|
|
{
|
|
if (e.KeyData == Keys.Enter)
|
|
{
|
|
if (AddCheat.Enabled)
|
|
{
|
|
AddCheat_Click(null, null);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ValueBox_TextChanged(object sender, EventArgs e)
|
|
{
|
|
if (Encoding.Checked && !string.IsNullOrWhiteSpace(ValueBox.Text))
|
|
{
|
|
var val = int.Parse(ValueBox.Text, NumberStyles.HexNumber);
|
|
if (val > 0 && val < 0x100)
|
|
{
|
|
if (!string.IsNullOrWhiteSpace(AddressBox.Text))
|
|
{
|
|
_value = val;
|
|
EncodeGameGenie();
|
|
}
|
|
}
|
|
}
|
|
|
|
TryEnableAddCheat();
|
|
}
|
|
|
|
private void Keypad_Click(object sender, EventArgs e)
|
|
{
|
|
if (GameGenieCode.Text.Length < 8)
|
|
{
|
|
var code = string.Empty;
|
|
if (sender == A) code = "A";
|
|
if (sender == P) code += "P";
|
|
if (sender == Z) code += "Z";
|
|
if (sender == L) code += "L";
|
|
if (sender == G) code += "G";
|
|
if (sender == I) code += "I";
|
|
if (sender == T) code += "T";
|
|
if (sender == Y) code += "Y";
|
|
if (sender == E) code += "E";
|
|
if (sender == O) code += "O";
|
|
if (sender == X) code += "X";
|
|
if (sender == U) code += "U";
|
|
if (sender == K) code += "K";
|
|
if (sender == S) code += "S";
|
|
if (sender == V) code += "V";
|
|
if (sender == N) code += "N";
|
|
|
|
int x = GameGenieCode.SelectionStart;
|
|
GameGenieCode.Text = GameGenieCode.Text.Insert(x, code);
|
|
GameGenieCode.SelectionStart = x + 1;
|
|
Encoding.Checked = false;
|
|
}
|
|
}
|
|
|
|
private void AddressBox_TextChanged(object sender, EventArgs e)
|
|
{
|
|
if (Encoding.Checked && AddressBox.Text.Length > 0)
|
|
{
|
|
if (!string.IsNullOrEmpty(ValueBox.Text))
|
|
{
|
|
EncodeGameGenie();
|
|
}
|
|
}
|
|
|
|
TryEnableAddCheat();
|
|
}
|
|
|
|
private void CompareBox_TextChanged(object sender, EventArgs e)
|
|
{
|
|
if (Encoding.Checked)
|
|
{
|
|
if (CompareBox.Text.Length > 0)
|
|
{
|
|
var c = int.Parse(CompareBox.Text, NumberStyles.HexNumber);
|
|
if (c > 0 && c < 0x100)
|
|
{
|
|
if (ValueBox.Text.Length > 0 && AddressBox.Text.Length > 0)
|
|
{
|
|
_compare = c;
|
|
EncodeGameGenie();
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
_compare = -1;
|
|
EncodeGameGenie();
|
|
}
|
|
}
|
|
|
|
TryEnableAddCheat();
|
|
}
|
|
|
|
private void GameGenieCode_TextChanged(object sender, EventArgs e)
|
|
{
|
|
if (Encoding.Checked == false)
|
|
{
|
|
if (GameGenieCode.Text.Length == 6 || GameGenieCode.Text.Length == 8)
|
|
{
|
|
DecodeGameGenieCode(GameGenieCode.Text);
|
|
}
|
|
else
|
|
{
|
|
ClearProperties();
|
|
}
|
|
}
|
|
|
|
TryEnableAddCheat();
|
|
}
|
|
|
|
protected override void OnShown(EventArgs e)
|
|
{
|
|
RefreshFloatingWindowControl();
|
|
base.OnShown(e);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#endregion
|
|
}
|
|
}
|