move NES game genie encoding/decoding logic into specialized classes in client.common and refactor the dialog and lua functions accordingly
This commit is contained in:
parent
a11019ee6c
commit
f7138e6514
|
@ -124,6 +124,7 @@
|
||||||
<Compile Include="movie\MultitrackRecording.cs" />
|
<Compile Include="movie\MultitrackRecording.cs" />
|
||||||
<Compile Include="movie\Subtitle.cs" />
|
<Compile Include="movie\Subtitle.cs" />
|
||||||
<Compile Include="movie\SubtitleList.cs" />
|
<Compile Include="movie\SubtitleList.cs" />
|
||||||
|
<Compile Include="NESGameGenieEncoderDecoder.cs" />
|
||||||
<Compile Include="PathManager.cs" />
|
<Compile Include="PathManager.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="RecentFiles.cs" />
|
<Compile Include="RecentFiles.cs" />
|
||||||
|
|
|
@ -0,0 +1,175 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace BizHawk.Client.Common
|
||||||
|
{
|
||||||
|
public class NESGameGenieDecoder
|
||||||
|
{
|
||||||
|
public int Address { get; private set; }
|
||||||
|
public int Value { get; private set; }
|
||||||
|
public int? Compare { get; private set; }
|
||||||
|
|
||||||
|
private readonly string _code = String.Empty;
|
||||||
|
|
||||||
|
public NESGameGenieDecoder(string code)
|
||||||
|
{
|
||||||
|
_code = code;
|
||||||
|
Decode();
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
};
|
||||||
|
|
||||||
|
public void Decode()
|
||||||
|
{
|
||||||
|
//char 3 bit 3 denotes the code length.
|
||||||
|
if (_code.Length == 6)
|
||||||
|
{
|
||||||
|
//Char # | 1 | 2 | 3 | 4 | 5 | 6 |
|
||||||
|
//Bit # |3|2|1|0|3|2|1|0|3|2|1|0|3|2|1|0|3|2|1|0|3|2|1|0|
|
||||||
|
//maps to|1|6|7|8|H|2|3|4|-|I|J|K|L|A|B|C|D|M|N|O|5|E|F|G|
|
||||||
|
Value = 0;
|
||||||
|
Address = 0x8000;
|
||||||
|
int x;
|
||||||
|
|
||||||
|
GameGenieTable.TryGetValue(_code[0], out x);
|
||||||
|
Value |= (x & 0x07);
|
||||||
|
Value |= (x & 0x08) << 4;
|
||||||
|
|
||||||
|
GameGenieTable.TryGetValue(_code[1], out x);
|
||||||
|
Value |= (x & 0x07) << 4;
|
||||||
|
Address |= (x & 0x08) << 4;
|
||||||
|
|
||||||
|
GameGenieTable.TryGetValue(_code[2], out x);
|
||||||
|
Address |= (x & 0x07) << 4;
|
||||||
|
|
||||||
|
GameGenieTable.TryGetValue(_code[3], out x);
|
||||||
|
Address |= (x & 0x07) << 12;
|
||||||
|
Address |= (x & 0x08);
|
||||||
|
|
||||||
|
GameGenieTable.TryGetValue(_code[4], out x);
|
||||||
|
Address |= (x & 0x07);
|
||||||
|
Address |= (x & 0x08) << 8;
|
||||||
|
|
||||||
|
GameGenieTable.TryGetValue(_code[5], out x);
|
||||||
|
Address |= (x & 0x07) << 8;
|
||||||
|
Value |= (x & 0x08);
|
||||||
|
}
|
||||||
|
else if (_code.Length == 8)
|
||||||
|
{
|
||||||
|
//Char # | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
|
||||||
|
//Bit # |3|2|1|0|3|2|1|0|3|2|1|0|3|2|1|0|3|2|1|0|3|2|1|0|3|2|1|0|3|2|1|0|
|
||||||
|
//maps to|1|6|7|8|H|2|3|4|-|I|J|K|L|A|B|C|D|M|N|O|%|E|F|G|!|^|&|*|5|@|#|$|
|
||||||
|
Value = 0;
|
||||||
|
Address = 0x8000;
|
||||||
|
Compare = 0;
|
||||||
|
int x;
|
||||||
|
|
||||||
|
GameGenieTable.TryGetValue(_code[0], out x);
|
||||||
|
Value |= (x & 0x07);
|
||||||
|
Value |= (x & 0x08) << 4;
|
||||||
|
|
||||||
|
GameGenieTable.TryGetValue(_code[1], out x);
|
||||||
|
Value |= (x & 0x07) << 4;
|
||||||
|
Address |= (x & 0x08) << 4;
|
||||||
|
|
||||||
|
GameGenieTable.TryGetValue(_code[2], out x);
|
||||||
|
Address |= (x & 0x07) << 4;
|
||||||
|
|
||||||
|
GameGenieTable.TryGetValue(_code[3], out x);
|
||||||
|
Address |= (x & 0x07) << 12;
|
||||||
|
Address |= (x & 0x08);
|
||||||
|
|
||||||
|
GameGenieTable.TryGetValue(_code[4], out x);
|
||||||
|
Address |= (x & 0x07);
|
||||||
|
Address |= (x & 0x08) << 8;
|
||||||
|
|
||||||
|
GameGenieTable.TryGetValue(_code[5], out x);
|
||||||
|
Address |= (x & 0x07) << 8;
|
||||||
|
Compare |= (x & 0x08);
|
||||||
|
|
||||||
|
GameGenieTable.TryGetValue(_code[6], out x);
|
||||||
|
Compare |= (x & 0x07);
|
||||||
|
Compare |= (x & 0x08) << 4;
|
||||||
|
|
||||||
|
GameGenieTable.TryGetValue(_code[7], out x);
|
||||||
|
Compare |= (x & 0x07) << 4;
|
||||||
|
Value |= (x & 0x08);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class NESGameGenieEncoder
|
||||||
|
{
|
||||||
|
private readonly char[] letters = { 'A', 'P', 'Z', 'L', 'G', 'I', 'T', 'Y', 'E', 'O', 'X', 'U', 'K', 'S', 'V', 'N' };
|
||||||
|
|
||||||
|
private int _address;
|
||||||
|
private int _value;
|
||||||
|
private int? _compare;
|
||||||
|
|
||||||
|
public string GameGenieCode { get; private set; }
|
||||||
|
|
||||||
|
public NESGameGenieEncoder(int address, int value, int? compare)
|
||||||
|
{
|
||||||
|
_address = address;
|
||||||
|
if (_address >= 0x8000)
|
||||||
|
{
|
||||||
|
_address -= 0x8000;
|
||||||
|
}
|
||||||
|
_value = value;
|
||||||
|
_compare = compare;
|
||||||
|
|
||||||
|
GameGenieCode = String.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Encode()
|
||||||
|
{
|
||||||
|
byte[] num = { 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||||
|
num[0] = (byte)((_value & 7) + ((_value >> 4) & 8));
|
||||||
|
num[1] = (byte)(((_value >> 4) & 7) + ((_address >> 4) & 8));
|
||||||
|
num[2] = (byte)(((_address >> 4) & 7));
|
||||||
|
num[3] = (byte)((_address >> 12) + (_address & 8));
|
||||||
|
num[4] = (byte)((_address & 7) + ((_address >> 8) & 8));
|
||||||
|
num[5] = (byte)(((_address >> 8) & 7));
|
||||||
|
|
||||||
|
if (_compare.HasValue)
|
||||||
|
{
|
||||||
|
num[2] += 8;
|
||||||
|
num[5] += (byte)(_compare & 8);
|
||||||
|
num[6] = (byte)((_compare & 7) + ((_compare >> 4) & 8));
|
||||||
|
num[7] = (byte)(((_compare >> 4) & 7) + (_value & 8));
|
||||||
|
for (int i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
GameGenieCode += letters[num[i]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
num[5] += (byte)(_value & 8);
|
||||||
|
for (int i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
GameGenieCode += letters[num[i]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return GameGenieCode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,7 +25,7 @@ namespace BizHawk.MultiClient
|
||||||
"setclipleftandright",
|
"setclipleftandright",
|
||||||
"setdispbackground",
|
"setdispbackground",
|
||||||
"setdispsprites",
|
"setdispsprites",
|
||||||
"setscanlines",
|
"setscanlines"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,26 +34,20 @@ namespace BizHawk.MultiClient
|
||||||
{
|
{
|
||||||
if (Global.Emulator is NES)
|
if (Global.Emulator is NES)
|
||||||
{
|
{
|
||||||
NESGameGenie gg = new NESGameGenie();
|
var decoder = new NESGameGenieDecoder(code);
|
||||||
gg.DecodeGameGenieCode(code);
|
Watch watch = Watch.GenerateWatch(
|
||||||
if (gg.Address.HasValue && gg.Value.HasValue)
|
Global.Emulator.MemoryDomains[1],
|
||||||
{
|
decoder.Address,
|
||||||
Watch watch = Watch.GenerateWatch(
|
Watch.WatchSize.Byte,
|
||||||
Global.Emulator.MemoryDomains[1],
|
Watch.DisplayType.Hex,
|
||||||
gg.Address.Value,
|
code,
|
||||||
Watch.WatchSize.Byte,
|
false
|
||||||
Watch.DisplayType.Hex,
|
);
|
||||||
code,
|
Global.CheatList.Add(new Cheat(
|
||||||
false
|
watch,
|
||||||
);
|
decoder.Value,
|
||||||
|
decoder.Compare
|
||||||
Global.CheatList.Add(new Cheat(
|
));
|
||||||
watch,
|
|
||||||
gg.Value.Value,
|
|
||||||
gg.Compare
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
ToolHelpers.UpdateCheatRelatedTools();
|
ToolHelpers.UpdateCheatRelatedTools();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,14 +100,10 @@ namespace BizHawk.MultiClient
|
||||||
{
|
{
|
||||||
if (Global.Emulator is NES)
|
if (Global.Emulator is NES)
|
||||||
{
|
{
|
||||||
NESGameGenie gg = new NESGameGenie();
|
var decoder = new NESGameGenieDecoder(code);
|
||||||
gg.DecodeGameGenieCode(code);
|
Global.CheatList.RemoveRange(
|
||||||
if (gg.Address.HasValue && gg.Value.HasValue)
|
Global.CheatList.Where(x => x.Address == decoder.Address)
|
||||||
{
|
);
|
||||||
var cheats = Global.CheatList.Where(x => x.Address == gg.Address);
|
|
||||||
Global.CheatList.RemoveRange(cheats);
|
|
||||||
}
|
|
||||||
|
|
||||||
ToolHelpers.UpdateCheatRelatedTools();
|
ToolHelpers.UpdateCheatRelatedTools();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,15 +5,14 @@ using System.Windows.Forms;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
|
||||||
using BizHawk.Client.Common;
|
using BizHawk.Client.Common;
|
||||||
using BizHawk.Emulation.Consoles.Nintendo;
|
|
||||||
|
|
||||||
namespace BizHawk.MultiClient
|
namespace BizHawk.MultiClient
|
||||||
{
|
{
|
||||||
public partial class NESGameGenie : Form
|
public partial class NESGameGenie : Form
|
||||||
{
|
{
|
||||||
private int? _address = null;
|
private int? _address;
|
||||||
private int? _value = null;
|
private int? _value;
|
||||||
private int? _compare = null;
|
private int? _compare;
|
||||||
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
|
||||||
|
@ -63,83 +62,12 @@ namespace BizHawk.MultiClient
|
||||||
|
|
||||||
public void DecodeGameGenieCode(string code)
|
public void DecodeGameGenieCode(string code)
|
||||||
{
|
{
|
||||||
//char 3 bit 3 denotes the code length.
|
|
||||||
if (code.Length == 6)
|
|
||||||
{
|
|
||||||
//Char # | 1 | 2 | 3 | 4 | 5 | 6 |
|
|
||||||
//Bit # |3|2|1|0|3|2|1|0|3|2|1|0|3|2|1|0|3|2|1|0|3|2|1|0|
|
|
||||||
//maps to|1|6|7|8|H|2|3|4|-|I|J|K|L|A|B|C|D|M|N|O|5|E|F|G|
|
|
||||||
_value = 0;
|
|
||||||
_address = 0x8000;
|
|
||||||
int x;
|
|
||||||
|
|
||||||
GameGenieTable.TryGetValue(code[0], out x);
|
var decoder = new NESGameGenieDecoder(code);
|
||||||
_value |= (x & 0x07);
|
_address = decoder.Address;
|
||||||
_value |= (x & 0x08) << 4;
|
_value = decoder.Value;
|
||||||
|
_compare = decoder.Compare;
|
||||||
GameGenieTable.TryGetValue(code[1], out x);
|
SetProperties();
|
||||||
_value |= (x & 0x07) << 4;
|
|
||||||
_address |= (x & 0x08) << 4;
|
|
||||||
|
|
||||||
GameGenieTable.TryGetValue(code[2], out x);
|
|
||||||
_address |= (x & 0x07) << 4;
|
|
||||||
|
|
||||||
GameGenieTable.TryGetValue(code[3], out x);
|
|
||||||
_address |= (x & 0x07) << 12;
|
|
||||||
_address |= (x & 0x08);
|
|
||||||
|
|
||||||
GameGenieTable.TryGetValue(code[4], out x);
|
|
||||||
_address |= (x & 0x07);
|
|
||||||
_address |= (x & 0x08) << 8;
|
|
||||||
|
|
||||||
GameGenieTable.TryGetValue(code[5], out x);
|
|
||||||
_address |= (x & 0x07) << 8;
|
|
||||||
_value |= (x & 0x08);
|
|
||||||
|
|
||||||
SetProperties();
|
|
||||||
}
|
|
||||||
else if (code.Length == 8)
|
|
||||||
{
|
|
||||||
//Char # | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
|
|
||||||
//Bit # |3|2|1|0|3|2|1|0|3|2|1|0|3|2|1|0|3|2|1|0|3|2|1|0|3|2|1|0|3|2|1|0|
|
|
||||||
//maps to|1|6|7|8|H|2|3|4|-|I|J|K|L|A|B|C|D|M|N|O|%|E|F|G|!|^|&|*|5|@|#|$|
|
|
||||||
_value = 0;
|
|
||||||
_address = 0x8000;
|
|
||||||
_compare = 0;
|
|
||||||
int x;
|
|
||||||
|
|
||||||
GameGenieTable.TryGetValue(code[0], out x);
|
|
||||||
_value |= (x & 0x07);
|
|
||||||
_value |= (x & 0x08) << 4;
|
|
||||||
|
|
||||||
GameGenieTable.TryGetValue(code[1], out x);
|
|
||||||
_value |= (x & 0x07) << 4;
|
|
||||||
_address |= (x & 0x08) << 4;
|
|
||||||
|
|
||||||
GameGenieTable.TryGetValue(code[2], out x);
|
|
||||||
_address |= (x & 0x07) << 4;
|
|
||||||
|
|
||||||
GameGenieTable.TryGetValue(code[3], out x);
|
|
||||||
_address |= (x & 0x07) << 12;
|
|
||||||
_address |= (x & 0x08);
|
|
||||||
|
|
||||||
GameGenieTable.TryGetValue(code[4], out x);
|
|
||||||
_address |= (x & 0x07);
|
|
||||||
_address |= (x & 0x08) << 8;
|
|
||||||
|
|
||||||
GameGenieTable.TryGetValue(code[5], out x);
|
|
||||||
_address |= (x & 0x07) << 8;
|
|
||||||
_compare |= (x & 0x08);
|
|
||||||
|
|
||||||
GameGenieTable.TryGetValue(code[6], out x);
|
|
||||||
_compare |= (x & 0x07);
|
|
||||||
_compare |= (x & 0x08) << 4;
|
|
||||||
|
|
||||||
GameGenieTable.TryGetValue(code[7], out x);
|
|
||||||
_compare |= (x & 0x07) << 4;
|
|
||||||
_value |= (x & 0x08);
|
|
||||||
SetProperties();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetProperties()
|
private void SetProperties()
|
||||||
|
@ -196,36 +124,7 @@ namespace BizHawk.MultiClient
|
||||||
_address = AddressBox.ToRawInt();
|
_address = AddressBox.ToRawInt();
|
||||||
_value = ValueBox.ToRawInt();
|
_value = ValueBox.ToRawInt();
|
||||||
_compare = CompareBox.ToRawInt();
|
_compare = CompareBox.ToRawInt();
|
||||||
|
GameGenieCode.Text = new NESGameGenieEncoder(_address.Value, _value.Value, _compare).Encode();
|
||||||
char[] letters = { 'A', 'P', 'Z', 'L', 'G', 'I', 'T', 'Y', 'E', 'O', 'X', 'U', 'K', 'S', 'V', 'N' };
|
|
||||||
if (_address >= 0x8000)
|
|
||||||
_address -= 0x8000;
|
|
||||||
GameGenieCode.Text = String.Empty;
|
|
||||||
byte[] num = { 0, 0, 0, 0, 0, 0, 0, 0 };
|
|
||||||
num[0] = (byte)((_value & 7) + ((_value >> 4) & 8));
|
|
||||||
num[1] = (byte)(((_value >> 4) & 7) + ((_address >> 4) & 8));
|
|
||||||
num[2] = (byte)(((_address >> 4) & 7));
|
|
||||||
num[3] = (byte)((_address >> 12) + (_address & 8));
|
|
||||||
num[4] = (byte)((_address & 7) + ((_address >> 8) & 8));
|
|
||||||
num[5] = (byte)(((_address >> 8) & 7));
|
|
||||||
|
|
||||||
if (_compare < 0 || CompareBox.Text.Length == 0)
|
|
||||||
{
|
|
||||||
num[5] += (byte)(_value & 8);
|
|
||||||
for (int x = 0; x < 6; x++)
|
|
||||||
GameGenieCode.Text += letters[num[x]];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
num[2] += 8;
|
|
||||||
num[5] += (byte)(_compare & 8);
|
|
||||||
num[6] = (byte)((_compare & 7) + ((_compare >> 4) & 8));
|
|
||||||
num[7] = (byte)(((_compare >> 4) & 7) + (_value & 8));
|
|
||||||
for (int i = 0; i < 8; i++)
|
|
||||||
{
|
|
||||||
GameGenieCode.Text += letters[num[i]];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddCheatClick()
|
private void AddCheatClick()
|
||||||
|
@ -249,10 +148,10 @@ namespace BizHawk.MultiClient
|
||||||
Global.CheatList.Add(new Cheat(
|
Global.CheatList.Add(new Cheat(
|
||||||
watch,
|
watch,
|
||||||
ValueBox.ToRawInt(),
|
ValueBox.ToRawInt(),
|
||||||
compare,
|
compare
|
||||||
enabled: true));
|
));
|
||||||
|
|
||||||
GlobalWinF.MainForm.Cheats_UpdateValues();
|
ToolHelpers.UpdateCheatRelatedTools();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -378,7 +277,6 @@ namespace BizHawk.MultiClient
|
||||||
{
|
{
|
||||||
if (Encoding.Checked && AddressBox.Text.Length > 0)
|
if (Encoding.Checked && AddressBox.Text.Length > 0)
|
||||||
{
|
{
|
||||||
int _address = int.Parse(AddressBox.Text, NumberStyles.HexNumber);
|
|
||||||
if (!String.IsNullOrEmpty(ValueBox.Text))
|
if (!String.IsNullOrEmpty(ValueBox.Text))
|
||||||
{
|
{
|
||||||
EncodeGameGenie();
|
EncodeGameGenie();
|
||||||
|
|
Loading…
Reference in New Issue