BizHawk/BizHawk.Client.Common/cheats/GenesisGameGenieDecoder.cs

88 lines
1.8 KiB
C#

using System;
using System.Collections.Generic;
namespace BizHawk.Client.Common.cheats
{
public static class GenesisGameGenieDecoder
{
private static readonly Dictionary<char, long> GameGenieTable = new Dictionary<char, long>
{
['A'] = 0,
['B'] = 1,
['C'] = 2,
['D'] = 3,
['E'] = 4,
['F'] = 5,
['G'] = 6,
['H'] = 7,
['J'] = 8,
['K'] = 9,
['L'] = 10,
['M'] = 11,
['N'] = 12,
['P'] = 13,
['R'] = 14,
['S'] = 15,
['T'] = 16,
['V'] = 17,
['W'] = 18,
['X'] = 19,
['Y'] = 20,
['Z'] = 21,
['0'] = 22,
['1'] = 23,
['2'] = 24,
['3'] = 25,
['4'] = 26,
['5'] = 27,
['6'] = 28,
['7'] = 29,
['8'] = 30,
['9'] = 31
};
public static IDecodeResult Decode(string code)
{
if (code == null)
{
throw new ArgumentNullException(nameof(code));
}
if (code.IndexOf("-") != 4)
{
return new InvalidCheatCode("Game Genie Codes need to contain a dash after the fourth character");
}
if (code.Contains("I") | code.Contains("O") | code.Contains("Q") | code.Contains("U"))
{
return new InvalidCheatCode("Game Genie Codes do not use I, O, Q or U.");
}
// Remove the -
code = code.Remove(4, 1);
long hexCode = 0;
// convert code to a long binary string
foreach (var t in code)
{
hexCode <<= 5;
GameGenieTable.TryGetValue(t, out var y);
hexCode |= y;
}
long decoded = (hexCode & 0xFF00000000) >> 32;
decoded |= hexCode & 0x00FF000000;
decoded |= (hexCode & 0x0000FF0000) << 16;
decoded |= (hexCode & 0x00000000700) << 5;
decoded |= (hexCode & 0x000000F800) >> 3;
decoded |= (hexCode & 0x00000000FF) << 16;
return new DecodeResult
{
Size = WatchSize.Word,
Value = (int)(decoded & 0x000000FFFF),
Address= (int)((decoded & 0xFFFFFF0000) >> 16)
};
}
}
}