convert more decoders

This commit is contained in:
adelikat 2020-02-29 14:24:08 -06:00
parent af513a03ce
commit d0db4188d3
4 changed files with 87 additions and 77 deletions

View File

@ -3,33 +3,30 @@ using System.Globalization;
namespace BizHawk.Client.Common.cheats
{
public class SnesActionReplayDecoder
public static class SnesActionReplayDecoder
{
private readonly string _code;
public SnesActionReplayDecoder(string code)
{
_code = code;
Decode();
}
public int Address { get; private set; }
public int Value { get; private set; }
public int ByteSize => 2;
// Sample Code:
// 7E18A428
// Address: 7E18A4
// Value: 28
public void Decode()
public static IDecodeResult Decode(string code)
{
if (_code.Length != 8)
if (code == null)
{
throw new InvalidOperationException("Pro Action Replay Codes need to be eight characters in length.");
throw new ArgumentNullException(nameof(code));
}
Address = int.Parse(_code.Remove(6, 2), NumberStyles.HexNumber);
Value = int.Parse(_code.Remove(0, 6), NumberStyles.HexNumber);
if (code.Length != 8)
{
return new InvalidCheatCode("Pro Action Replay Codes must to be eight characters.");
}
return new DecodeResult
{
Size = WatchSize.Word,
Address = int.Parse(code.Remove(6, 2), NumberStyles.HexNumber),
Value = int.Parse(code.Remove(0, 6), NumberStyles.HexNumber)
};
}
}
}

View File

@ -1,16 +1,15 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
namespace BizHawk.Client.Common.cheats
{
public class SnesGameGenieDecoder
public static class SnesGameGenieDecoder
{
private readonly string _code;
// including transposition
// Code: D F 4 7 0 9 1 5 6 B C 8 A 2 3 E
// Hex: 0 1 2 3 4 5 6 7 8 9 A B C D E F
// This only applies to the SNES
private readonly Dictionary<char, int> _snesGameGenieTable = new Dictionary<char, int>
private static readonly Dictionary<char, int> SNESGameGenieTable = new Dictionary<char, int>
{
['D'] = 0, // 0000
['F'] = 1, // 0001
@ -30,17 +29,18 @@ namespace BizHawk.Client.Common.cheats
['E'] = 15 // 1111
};
public SnesGameGenieDecoder(string code)
public static IDecodeResult Decode(string code)
{
_code = code?.Replace("-", "") ?? "";
Decode();
}
if (code == null)
{
throw new ArgumentNullException(nameof(code));
}
public int Address { get; private set; }
public int Value { get; private set; }
if (!code.Contains("-") && code.Length != 9)
{
return new InvalidCheatCode("Game genie codes must be 9 characters with a format of xxyy-yyyy");
}
public void Decode()
{
// Code: D F 4 7 0 9 1 5 6 B C 8 A 2 3 E
// Hex: 0 1 2 3 4 5 6 7 8 9 A B C D E F
// XXYY-YYYY, where XX is the value, and YY-YYYY is the address.
@ -48,61 +48,65 @@ namespace BizHawk.Client.Common.cheats
// 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| Value |i|j|k|l|q|r|s|t|o|p|a|b|c|d|u|v|w|x|e|f|g|h|m|n|
// order | Value |a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|
var result = new DecodeResult { Size = WatchSize.Byte };
int x;
// Getting Value
if (_code.Length > 0)
// Value
if (code.Length > 0)
{
_snesGameGenieTable.TryGetValue(_code[0], out x);
Value = x << 4;
SNESGameGenieTable.TryGetValue(code[0], out x);
result.Value = x << 4;
}
if (_code.Length > 1)
if (code.Length > 1)
{
_snesGameGenieTable.TryGetValue(_code[1], out x);
Value |= x;
SNESGameGenieTable.TryGetValue(code[1], out x);
result.Value |= x;
}
// Address
if (_code.Length > 2)
if (code.Length > 2)
{
_snesGameGenieTable.TryGetValue(_code[2], out x);
Address = x << 12;
SNESGameGenieTable.TryGetValue(code[2], out x);
result.Address = x << 12;
}
if (_code.Length > 3)
if (code.Length > 3)
{
_snesGameGenieTable.TryGetValue(_code[3], out x);
Address |= x << 4;
SNESGameGenieTable.TryGetValue(code[3], out x);
result.Address |= x << 4;
}
if (_code.Length > 4)
if (code.Length > 4)
{
_snesGameGenieTable.TryGetValue(_code[4], out x);
Address |= (x & 0xC) << 6;
Address |= (x & 0x3) << 22;
SNESGameGenieTable.TryGetValue(code[4], out x);
result.Address |= (x & 0xC) << 6;
result.Address |= (x & 0x3) << 22;
}
if (_code.Length > 5)
if (code.Length > 5)
{
_snesGameGenieTable.TryGetValue(_code[5], out x);
Address |= (x & 0xC) << 18;
Address |= (x & 0x3) << 2;
SNESGameGenieTable.TryGetValue(code[5], out x);
result.Address |= (x & 0xC) << 18;
result.Address |= (x & 0x3) << 2;
}
if (_code.Length > 6)
if (code.Length > 6)
{
_snesGameGenieTable.TryGetValue(_code[6], out x);
Address |= (x & 0xC) >> 2;
Address |= (x & 0x3) << 18;
SNESGameGenieTable.TryGetValue(code[6], out x);
result.Address |= (x & 0xC) >> 2;
result.Address |= (x & 0x3) << 18;
}
if (_code.Length > 7)
if (code.Length > 7)
{
_snesGameGenieTable.TryGetValue(_code[7], out x);
Address |= (x & 0xC) << 14;
Address |= (x & 0x3) << 10;
SNESGameGenieTable.TryGetValue(code[7], out x);
result.Address |= (x & 0xC) << 14;
result.Address |= (x & 0x3) << 10;
}
return result;
}
}
}

View File

@ -349,29 +349,37 @@ namespace BizHawk.Client.EmuHawk
InputError($"Unknown code type: {code}");
}
private void Snes(string cheat)
private void Snes(string code)
{
if (cheat.Contains("-") && cheat.Length == 9)
if (code.Contains("-") && code.Length == 9)
{
MessageBox.Show("Game genie codes are not currently supported for SNES", "SNES Game Genie not supported", MessageBoxButtons.OK, MessageBoxIcon.Error);
////var decoder = new SnesGameGenieDecoder(_singleCheat);
////var watch = Watch.GenerateWatch(MemoryDomains["CARTROM"], decoder.Address, WatchSize.Byte, Common.DisplayType.Hex, false, txtDescription.Text);
////Global.CheatList.Add(new Cheat(watch, decoder.Value));
//var result = SnesGameGenieDecoder.Decode(code);
//if (result.IsValid)
//{
// var description = Description(code);
// Global.CheatList.Add(result.ToCheat(MemoryDomains.SystemBus, description));
//}
//else
//{
// InputError(result.Error);
//}
}
else if (cheat.Length == 8)
else if (code.Length == 8)
{
var decoder = new SnesActionReplayDecoder(cheat);
var watch = Watch.GenerateWatch(MemoryDomains["System Bus"], decoder.Address, WatchSize.Word, Common.DisplayType.Hex, false, txtDescription.Text);
Global.CheatList.Add(new Cheat(watch, decoder.Value));
}
else if (cheat.Contains("-") && cheat.Length != 9)
{
InputError("Game Genie Codes need to be nine characters in length.");
}
else if (cheat.Length != 9 && cheat.Length != 8)
{
InputError("Pro Action Replay Codes need to be eight characters in length.");
var result = GbGameSharkDecoder.Decode(code);
if (result.IsValid)
{
var description = Description(code);
Global.CheatList.Add(result.ToCheat(MemoryDomains.SystemBus, description));
}
else
{
InputError(result.Error);
}
}
InputError($"Unknown code type: {code}");
}
private void BtnClear_Click(object sender, EventArgs e)

View File

@ -546,6 +546,7 @@
<s:Boolean x:Key="/Default/UserDictionary/Words/=XXXXXX/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=xxxxxxx/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=XXXXXXXX/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=xxyy/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Yabause/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=YYYYYY/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=YYYYYYYY/@EntryIndexedValue">True</s:Boolean>