GameShark - move genesis game genie coding logic to its own class

This commit is contained in:
adelikat 2020-02-28 19:12:46 -06:00
parent 5dfc93deaf
commit d2fd1dc11c
2 changed files with 94 additions and 69 deletions

View File

@ -0,0 +1,89 @@
using System;
using System.Collections.Generic;
namespace BizHawk.Client.Common.cheats
{
public class GenesisGameGenieDecoder
{
private readonly string _code;
private readonly Dictionary<char, long> _genGameGenieTable = 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 GenesisGameGenieDecoder(string code)
{
_code = code;
Decode();
}
public int Address { get; private set; }
public int Value { get; private set; }
public void Decode()
{
if (_code.IndexOf("-") != 4)
{
throw new InvalidOperationException("All Genesis 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"))
{
throw new InvalidOperationException("Genesis Game Genie Codes do not use I, O, Q or U.");
}
// Remove the -
string code = _code.Remove(4, 1);
long hexCode = 0;
// convert code to a long binary string
foreach (var t in code)
{
hexCode <<= 5;
_genGameGenieTable.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;
Value = (int)(decoded & 0x000000FFFF);
Address= (int)((decoded & 0xFFFFFF0000) >> 16);
}
}
}

View File

@ -4,6 +4,7 @@ using System.Globalization;
using System.Windows.Forms;
using BizHawk.Emulation.Common;
using BizHawk.Client.Common;
using BizHawk.Client.Common.cheats;
// TODO:
// Add Support/Handling for The Following Systems and Devices:
@ -42,42 +43,6 @@ namespace BizHawk.Client.EmuHawk
['F'] = 15
};
private readonly Dictionary<char, long> _genGameGenieTable = 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
};
// 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
@ -2353,8 +2318,7 @@ namespace BizHawk.Client.EmuHawk
private void Gen()
{
// Game Genie only, for now.
// This applies to the Game Genie
// Game Genie only
if (_singleCheat.Length == 9 && _singleCheat.Contains("-"))
{
if (_singleCheat.IndexOf("-") != 4)
@ -2368,39 +2332,11 @@ namespace BizHawk.Client.EmuHawk
return;
}
// This is taken from the GenGameGenie.CS file.
string code = _singleCheat;
// Remove the -
code = code.Remove(4, 1);
long hexCode = 0;
// convert code to a long binary string
foreach (var t in code)
{
hexCode <<= 5;
_genGameGenieTable.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;
var val = (int)(decoded & 0x000000FFFF);
var add = (int)((decoded & 0xFFFFFF0000) >> 16);
// Make our Strings get the Hex Values.
string address = add.ToString("X6");
var decoder = new GenesisGameGenieDecoder(_singleCheat);
// Game Genie, modifies the "ROM" which is why it says, "MD CART"
var watch = Watch.GenerateWatch(MemoryDomains["M68K BUS"], long.Parse(address, NumberStyles.HexNumber), WatchSize.Word, Common.DisplayType.Hex, true, txtDescription.Text);
// Add Cheat
Global.CheatList.Add(new Cheat(watch, val));
var watch = Watch.GenerateWatch(MemoryDomains["M68K BUS"], decoder.Address, WatchSize.Word, Common.DisplayType.Hex, true, txtDescription.Text);
Global.CheatList.Add(new Cheat(watch, decoder.Value));
}
// Action Replay?