merge remote master
This commit is contained in:
commit
bae4d53cbf
|
@ -214,7 +214,7 @@ namespace BizHawk.Client.Common
|
||||||
{
|
{
|
||||||
if (_compare.HasValue)
|
if (_compare.HasValue)
|
||||||
{
|
{
|
||||||
if (_compare.Value == _watch.Value)
|
if (_compare.Value == _watch.ValueNoFreeze)
|
||||||
{
|
{
|
||||||
_watch.Poke(GetStringForPulse(_val));
|
_watch.Poke(GetStringForPulse(_val));
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,6 +113,9 @@ namespace BizHawk.Client.Common
|
||||||
public abstract string ValueString { get; }
|
public abstract string ValueString { get; }
|
||||||
public abstract WatchSize Size { get; }
|
public abstract WatchSize Size { get; }
|
||||||
|
|
||||||
|
//zero 15-nov-2015 - bypass LIAR LOGIC, see fdc9ea2aa922876d20ba897fb76909bf75fa6c92 https://github.com/TASVideos/BizHawk/issues/326
|
||||||
|
public abstract int? ValueNoFreeze { get; }
|
||||||
|
|
||||||
public abstract uint MaxValue { get; }
|
public abstract uint MaxValue { get; }
|
||||||
|
|
||||||
public abstract int? Previous { get; }
|
public abstract int? Previous { get; }
|
||||||
|
@ -237,10 +240,11 @@ namespace BizHawk.Client.Common
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected byte GetByte()
|
protected byte GetByte(bool bypassFreeze = false)
|
||||||
{
|
{
|
||||||
if (Global.CheatList.IsActive(_domain, _address))
|
if (!bypassFreeze && Global.CheatList.IsActive(_domain, _address))
|
||||||
{
|
{
|
||||||
|
//LIAR logic
|
||||||
return Global.CheatList.GetByteValue(_domain, _address).Value;
|
return Global.CheatList.GetByteValue(_domain, _address).Value;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -256,10 +260,11 @@ namespace BizHawk.Client.Common
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ushort GetWord()
|
protected ushort GetWord(bool bypassFreeze = false)
|
||||||
{
|
{
|
||||||
if (Global.CheatList.IsActive(_domain, _address))
|
if (!bypassFreeze && Global.CheatList.IsActive(_domain, _address))
|
||||||
{
|
{
|
||||||
|
//LIAR logic
|
||||||
return (ushort)Global.CheatList.GetCheatValue(_domain, _address, WatchSize.Word).Value;
|
return (ushort)Global.CheatList.GetCheatValue(_domain, _address, WatchSize.Word).Value;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -275,10 +280,11 @@ namespace BizHawk.Client.Common
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected uint GetDWord()
|
protected uint GetDWord(bool bypassFreeze = false)
|
||||||
{
|
{
|
||||||
if (Global.CheatList.IsActive(_domain, _address))
|
if (!bypassFreeze && Global.CheatList.IsActive(_domain, _address))
|
||||||
{
|
{
|
||||||
|
//LIAR logic
|
||||||
return (uint)Global.CheatList.GetCheatValue(_domain, _address, WatchSize.DWord).Value;
|
return (uint)Global.CheatList.GetCheatValue(_domain, _address, WatchSize.DWord).Value;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -458,6 +464,11 @@ namespace BizHawk.Client.Common
|
||||||
get { return null; }
|
get { return null; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override int? ValueNoFreeze
|
||||||
|
{
|
||||||
|
get { return null; }
|
||||||
|
}
|
||||||
|
|
||||||
public override int? Previous
|
public override int? Previous
|
||||||
{
|
{
|
||||||
get { return null; }
|
get { return null; }
|
||||||
|
@ -562,6 +573,11 @@ namespace BizHawk.Client.Common
|
||||||
get { return GetByte(); }
|
get { return GetByte(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override int? ValueNoFreeze
|
||||||
|
{
|
||||||
|
get { return GetByte(true); }
|
||||||
|
}
|
||||||
|
|
||||||
public override string ValueString
|
public override string ValueString
|
||||||
{
|
{
|
||||||
get { return FormatValue(GetByte()); }
|
get { return FormatValue(GetByte()); }
|
||||||
|
@ -792,6 +808,11 @@ namespace BizHawk.Client.Common
|
||||||
get { return GetWord(); }
|
get { return GetWord(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override int? ValueNoFreeze
|
||||||
|
{
|
||||||
|
get { return GetWord(true); }
|
||||||
|
}
|
||||||
|
|
||||||
public override int? Previous
|
public override int? Previous
|
||||||
{
|
{
|
||||||
get { return _previous; }
|
get { return _previous; }
|
||||||
|
@ -1008,6 +1029,11 @@ namespace BizHawk.Client.Common
|
||||||
get { return (int)GetDWord(); }
|
get { return (int)GetDWord(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override int? ValueNoFreeze
|
||||||
|
{
|
||||||
|
get { return (int)GetDWord(true); }
|
||||||
|
}
|
||||||
|
|
||||||
public override int? Previous
|
public override int? Previous
|
||||||
{
|
{
|
||||||
get { return (int)_previous; }
|
get { return (int)_previous; }
|
||||||
|
|
|
@ -1185,7 +1185,7 @@ namespace BizHawk.Client.EmuHawk
|
||||||
ThrottleMessage();
|
ThrottleMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RunLibretroCoreChooser()
|
public bool RunLibretroCoreChooser()
|
||||||
{
|
{
|
||||||
var ofd = new OpenFileDialog();
|
var ofd = new OpenFileDialog();
|
||||||
|
|
||||||
|
@ -1203,9 +1203,11 @@ namespace BizHawk.Client.EmuHawk
|
||||||
ofd.Filter = "Libretro Cores (*.dll)|*.dll";
|
ofd.Filter = "Libretro Cores (*.dll)|*.dll";
|
||||||
|
|
||||||
if (ofd.ShowDialog() == DialogResult.Cancel)
|
if (ofd.ShowDialog() == DialogResult.Cancel)
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
Global.Config.LibretroCore = ofd.FileName;
|
Global.Config.LibretroCore = ofd.FileName;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setLibretroCoreToolStripMenuItem_Click(object sender, EventArgs e)
|
private void setLibretroCoreToolStripMenuItem_Click(object sender, EventArgs e)
|
||||||
|
|
|
@ -595,7 +595,7 @@ namespace BizHawk.Client.EmuHawk
|
||||||
#region Properties
|
#region Properties
|
||||||
|
|
||||||
public string CurrentlyOpenRom; //todo - delete me and use only args instead
|
public string CurrentlyOpenRom; //todo - delete me and use only args instead
|
||||||
LoadRomArgs CurrentlyOpenRomArgs;
|
public LoadRomArgs CurrentlyOpenRomArgs;
|
||||||
public bool PauseAVI = false;
|
public bool PauseAVI = false;
|
||||||
public bool PressFrameAdvance = false;
|
public bool PressFrameAdvance = false;
|
||||||
public bool PressRewind = false;
|
public bool PressRewind = false;
|
||||||
|
|
|
@ -51,8 +51,8 @@ namespace BizHawk.Client.EmuHawk
|
||||||
|
|
||||||
private void btnSetLibretroCore_Click(object sender, EventArgs e)
|
private void btnSetLibretroCore_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
mainForm.RunLibretroCoreChooser();
|
if(mainForm.RunLibretroCoreChooser())
|
||||||
RefreshLibretroCore(false);
|
RefreshLibretroCore(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
LibRetroEmulator.RetroDescription CurrentDescription;
|
LibRetroEmulator.RetroDescription CurrentDescription;
|
||||||
|
|
|
@ -3,15 +3,32 @@ using System.Windows.Forms;
|
||||||
using BizHawk.Emulation.Common;
|
using BizHawk.Emulation.Common;
|
||||||
using BizHawk.Client.Common;
|
using BizHawk.Client.Common;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace BizHawk.Client.EmuHawk
|
namespace BizHawk.Client.EmuHawk
|
||||||
{
|
{
|
||||||
[ToolAttributes(released: true, supportedSystems: new[] { "GB" })]
|
|
||||||
|
//TODO:
|
||||||
|
//Add Support/Handling for The Following Systems and Devices:
|
||||||
|
//GB/GBC: Pro Action Replay
|
||||||
|
//GBA: GameShark, Action Replay (Same?), Code Breaker
|
||||||
|
//GameGear: Game Genie, Pro Action Replay
|
||||||
|
//NES: Game Genie, Pro Action Replay
|
||||||
|
//PSX: Code Breaker, Action Replay, Game Busters (What is that?!)
|
||||||
|
//SMS: Pro Action Replay
|
||||||
|
//SNES: Game Genie, Pro Action Replay
|
||||||
|
//Saturn: Pro Action Replay (Is it the same as GameShark? Appears to be so?)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[ToolAttributes(released: true, supportedSystems: new[] { "GB", "GBA", "GEN", "N64", "PSX", "SAT", "SMS", "SNES" })]
|
||||||
public partial class GameShark : Form, IToolForm, IToolFormAutoConfig
|
public partial class GameShark : Form, IToolForm, IToolFormAutoConfig
|
||||||
{
|
{
|
||||||
//We are using Memory Domains, so we NEED this.
|
//We are using Memory Domains, so we NEED this.
|
||||||
[RequiredService]
|
[RequiredService]
|
||||||
private IMemoryDomains MemoryDomains { get; set; }
|
private IMemoryDomains MemoryDomains { get; set; }
|
||||||
|
[RequiredService]
|
||||||
|
private IEmulator Emulator { get; set; }
|
||||||
public GameShark()
|
public GameShark()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
@ -45,22 +62,88 @@ namespace BizHawk.Client.EmuHawk
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//My Variables
|
||||||
|
string parseString = null;
|
||||||
|
string RAMAddress = null;
|
||||||
|
string RAMValue = null;
|
||||||
|
int byteSize = 0;
|
||||||
|
string testo = null;
|
||||||
private void btnGo_Click(object sender, EventArgs e)
|
private void btnGo_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
//This line ONLY applies to GB/GBC codes.
|
//Reset Variables
|
||||||
|
parseString = null;
|
||||||
|
RAMAddress = null;
|
||||||
|
RAMValue = null;
|
||||||
|
byteSize = 0;
|
||||||
|
//We want Upper Case.
|
||||||
|
txtCheat.Text = txtCheat.Text.ToUpper();
|
||||||
|
//What System are we running?
|
||||||
|
switch (Emulator.SystemId)
|
||||||
|
{
|
||||||
|
case "GB":
|
||||||
|
GB();
|
||||||
|
break;
|
||||||
|
case "GBA":
|
||||||
|
GBA();
|
||||||
|
break;
|
||||||
|
case "GEN":
|
||||||
|
GEN();
|
||||||
|
break;
|
||||||
|
case "N64":
|
||||||
|
//This determies what kind of Code we have
|
||||||
|
testo = txtCheat.Text.Remove(2, 11);
|
||||||
|
N64();
|
||||||
|
break;
|
||||||
|
case "PSX":
|
||||||
|
//This determies what kind of Code we have
|
||||||
|
testo = txtCheat.Text.Remove(2, 11);
|
||||||
|
PSX();
|
||||||
|
break;
|
||||||
|
case "SAT":
|
||||||
|
//This determies what kind of Code we have
|
||||||
|
testo = txtCheat.Text.Remove(2, 11);
|
||||||
|
SAT();
|
||||||
|
break;
|
||||||
|
case "SMS":
|
||||||
|
SMS();
|
||||||
|
break;
|
||||||
|
case "SNES":
|
||||||
|
//Currently only does Action Replay
|
||||||
|
SNES();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
//This should NEVER happen
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void GB()
|
||||||
|
{
|
||||||
|
//This Check ONLY applies to GB/GBC codes.
|
||||||
if (txtCheat.Text.Length != 8)
|
if (txtCheat.Text.Length != 8)
|
||||||
{
|
{
|
||||||
MessageBox.Show("All GameShark and CodeBreaker cheats need to be Eight characters in Length", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
MessageBox.Show("All GameShark Codes need to be Eight characters in Length", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
testo = txtCheat.Text.Remove(2, 6);
|
||||||
|
//Let's make sure we start with zero. We have a good length, and a good starting zero, we should be good. Hopefully.
|
||||||
|
switch (testo)
|
||||||
|
{
|
||||||
|
//Is this 00 or 01?
|
||||||
|
case "00":
|
||||||
|
case "01":
|
||||||
|
//Good.
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
//No.
|
||||||
|
MessageBox.Show("All GameShark Codes for GameBoy need to start with 00 or 01", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
//Sample Input for GB/GBC:
|
//Sample Input for GB/GBC:
|
||||||
//010FF6C1
|
//010FF6C1
|
||||||
//Becomes:
|
//Becomes:
|
||||||
//Address C1F6
|
//Address C1F6
|
||||||
//Value 0F
|
//Value 0F
|
||||||
string parseString = null;
|
|
||||||
string RAMAddress = null;
|
|
||||||
string RAMValue = null;
|
|
||||||
parseString = txtCheat.Text.Remove(0, 2);
|
parseString = txtCheat.Text.Remove(0, 2);
|
||||||
//Now we need to break it down a little more.
|
//Now we need to break it down a little more.
|
||||||
RAMValue = parseString.Remove(2, 4);
|
RAMValue = parseString.Remove(2, 4);
|
||||||
|
@ -77,18 +160,596 @@ namespace BizHawk.Client.EmuHawk
|
||||||
//System Bus Domain, The Address to Watch, Byte size (Byte), Hex Display, Description. Not Big Endian.
|
//System Bus Domain, The Address to Watch, Byte size (Byte), Hex Display, Description. Not Big Endian.
|
||||||
var watch = Watch.GenerateWatch(MemoryDomains["System Bus"], long.Parse(RAMAddress, NumberStyles.HexNumber), Watch.WatchSize.Byte, Watch.DisplayType.Hex, txtDescription.Text, false);
|
var watch = Watch.GenerateWatch(MemoryDomains["System Bus"], long.Parse(RAMAddress, NumberStyles.HexNumber), Watch.WatchSize.Byte, Watch.DisplayType.Hex, txtDescription.Text, false);
|
||||||
//Take Watch, Add our Value we want, and it should be active when addded?
|
//Take Watch, Add our Value we want, and it should be active when addded?
|
||||||
Global.CheatList.Add(new Cheat(watch, int.Parse(RAMValue, NumberStyles.HexNumber)));
|
Global.CheatList.Add(new Cheat(watch, int.Parse(RAMValue, NumberStyles.HexNumber)));
|
||||||
//Clear old Inputs
|
//Clear old Inputs
|
||||||
txtCheat.Clear();
|
txtCheat.Clear();
|
||||||
txtDescription.Clear();
|
txtDescription.Clear();
|
||||||
}
|
}
|
||||||
|
//Someone broke the world?
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
MessageBox.Show("An Error occured:" + ex.GetType().ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
MessageBox.Show("An Error occured: " + ex.GetType().ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private void GBA()
|
||||||
|
{
|
||||||
|
//Nothing, yet
|
||||||
|
//Sample of Decryption Code from mGBA
|
||||||
|
//const uint32_t GBACheatGameSharkSeeds[4] = { 0x09F4FBBD, 0x9681884A, 0x352027E9, 0xF3DEE5A7 };
|
||||||
|
/* void GBACheatDecryptGameShark(uint32_t* op1, uint32_t* op2, const uint32_t* seeds) {
|
||||||
|
uint32_t sum = 0xC6EF3720;
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < 32; ++i)
|
||||||
|
{
|
||||||
|
*op2 -= ((*op1 << 4) + seeds[2]) ^ (*op1 + sum) ^ ((*op1 >> 5) + seeds[3]);
|
||||||
|
*op1 -= ((*op2 << 4) + seeds[0]) ^ (*op2 + sum) ^ ((*op2 >> 5) + seeds[1]);
|
||||||
|
sum -= 0x9E3779B9;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
private void btnClear_Click(object sender, EventArgs e)
|
}
|
||||||
|
//This applies to the Genesis Game Genie.
|
||||||
|
private readonly Dictionary<char, int> _GENgameGenieTable = new Dictionary<char, int>
|
||||||
|
{
|
||||||
|
{ '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 }
|
||||||
|
};
|
||||||
|
private void GEN()
|
||||||
|
{
|
||||||
|
//Game Genie only, for now.
|
||||||
|
//This applies to the Game Genie
|
||||||
|
if (txtCheat.Text.Length == 9 && txtCheat.Text.Contains("-"))
|
||||||
|
{
|
||||||
|
if (txtCheat.Text.IndexOf("-") != 5)
|
||||||
|
{
|
||||||
|
MessageBox.Show("All Genesis Game Genie Codes need to contain a dash after the fourth character", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (txtCheat.Text.Contains("I") == true | txtCheat.Text.Contains("O") == true | txtCheat.Text.Contains("Q") == true | txtCheat.Text.Contains("U") == true)
|
||||||
|
{
|
||||||
|
MessageBox.Show("All Genesis Game Genie Codes do not use I, O, Q or U.", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//This is taken from the GenGameGenie.CS file.
|
||||||
|
string code = txtCheat.Text;
|
||||||
|
int val = 0;
|
||||||
|
int add = 0;
|
||||||
|
string address = null;
|
||||||
|
string value = null;
|
||||||
|
//Remove the -
|
||||||
|
code = code.Remove(4, 1);
|
||||||
|
long hexcode = 0;
|
||||||
|
|
||||||
|
// convert code to a long binary string
|
||||||
|
foreach (var t in code)
|
||||||
|
{
|
||||||
|
hexcode <<= 5;
|
||||||
|
int y;
|
||||||
|
_GENgameGenieTable.TryGetValue(t, out 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;
|
||||||
|
|
||||||
|
val = (int)(decoded & 0x000000FFFF);
|
||||||
|
add = (int)((decoded & 0xFFFFFF0000) >> 16);
|
||||||
|
//Make our Strings get the Hex Values.
|
||||||
|
address = add.ToString("X6");
|
||||||
|
value = val.ToString("X4");
|
||||||
|
//Game Geneie, modifies the "ROM" which is why it says, "MD CART"
|
||||||
|
var watch = Watch.GenerateWatch(MemoryDomains["MD CART"], long.Parse(address, NumberStyles.HexNumber), Watch.WatchSize.Word, Watch.DisplayType.Hex, txtDescription.Text, true);
|
||||||
|
//Add Cheat
|
||||||
|
Global.CheatList.Add(new Cheat(watch, val));
|
||||||
|
}
|
||||||
|
//Action Replay?
|
||||||
|
if (txtCheat.Text.Contains(":"))
|
||||||
|
{
|
||||||
|
//We start from Zero.
|
||||||
|
if (txtCheat.Text.IndexOf(":") != 6)
|
||||||
|
{
|
||||||
|
MessageBox.Show("All Genesis Action Replay/Pro Action Replay Codes need to contain a colon after the sixth character", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//Problem: I don't know what the Non-FF Style codes are.
|
||||||
|
//TODO: Fix that.
|
||||||
|
if (txtCheat.Text.StartsWith("FF") == false)
|
||||||
|
{
|
||||||
|
MessageBox.Show("This Action Replay Code, is not understood by this tool.", "Tool Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//Now to do some work.
|
||||||
|
//Determine Length, to Determine Byte Size
|
||||||
|
|
||||||
|
parseString = txtCheat.Text.Remove(0, 2);
|
||||||
|
switch (txtCheat.Text.Length)
|
||||||
|
{
|
||||||
|
case 9:
|
||||||
|
//Sample Code of 1-Byte:
|
||||||
|
//FFF761:64
|
||||||
|
//Becomes:
|
||||||
|
//Address: F761
|
||||||
|
//Value: 64
|
||||||
|
RAMAddress = parseString.Remove(4, 3);
|
||||||
|
RAMValue = parseString.Remove(0, 5);
|
||||||
|
byteSize = 1;
|
||||||
|
break;
|
||||||
|
case 11:
|
||||||
|
//Sample Code of 2-Byte:
|
||||||
|
//FFF761:6411
|
||||||
|
//Becomes:
|
||||||
|
//Address: F761
|
||||||
|
//Value: 6411
|
||||||
|
RAMAddress = parseString.Remove(4, 5);
|
||||||
|
RAMValue = parseString.Remove(0, 5);
|
||||||
|
byteSize = 2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
//We could have checked above but here is fine, since it's a quick check due to one of three possibilities.
|
||||||
|
MessageBox.Show("All Genesis Action Replay/Pro Action Replay Codes need to be either 9 or 11 characters in length", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//Try and add.
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//A Watch needs to be generated so we can make a cheat out of that. This is due to how the Cheat engine works.
|
||||||
|
//System Bus Domain, The Address to Watch, Byte size (Byte), Hex Display, Description, Big Endian.
|
||||||
|
if (byteSize == 1)
|
||||||
|
{
|
||||||
|
var watch = Watch.GenerateWatch(MemoryDomains["68K RAM"], long.Parse(RAMAddress, NumberStyles.HexNumber), Watch.WatchSize.Byte, Watch.DisplayType.Hex, txtDescription.Text, false);
|
||||||
|
//Take Watch, Add our Value we want, and it should be active when addded?
|
||||||
|
Global.CheatList.Add(new Cheat(watch, int.Parse(RAMValue, NumberStyles.HexNumber)));
|
||||||
|
//Clear old Inputs
|
||||||
|
txtCheat.Clear();
|
||||||
|
txtDescription.Clear();
|
||||||
|
}
|
||||||
|
if (byteSize == 2)
|
||||||
|
{
|
||||||
|
var watch = Watch.GenerateWatch(MemoryDomains["68K RAM"], long.Parse(RAMAddress, NumberStyles.HexNumber), Watch.WatchSize.Word, Watch.DisplayType.Hex, txtDescription.Text, true);
|
||||||
|
//Take Watch, Add our Value we want, and it should be active when addded?
|
||||||
|
Global.CheatList.Add(new Cheat(watch, int.Parse(RAMValue, NumberStyles.HexNumber)));
|
||||||
|
//Clear old Inputs
|
||||||
|
txtCheat.Clear();
|
||||||
|
txtDescription.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
//Someone broke the world?
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show("An Error occured: " + ex.GetType().ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void N64()
|
||||||
|
{
|
||||||
|
//These codes, more or less work without Needing much work.
|
||||||
|
if (txtCheat.Text.IndexOf(" ") != 8)
|
||||||
|
{
|
||||||
|
MessageBox.Show("All N64 GameShark Codes need to contain a space after the eighth character", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (txtCheat.Text.Length != 13)
|
||||||
|
{
|
||||||
|
MessageBox.Show("All N64 GameShark Codes need to be 13 characters in length.", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//We need to determine what kind of cheat this is.
|
||||||
|
//I need to determine if this is a Byte or Word.
|
||||||
|
switch (testo)
|
||||||
|
{
|
||||||
|
//80 and 81 are the most common, so let's not get all worried.
|
||||||
|
case "80":
|
||||||
|
//Byte
|
||||||
|
byteSize = 8;
|
||||||
|
break;
|
||||||
|
case "81":
|
||||||
|
//Word
|
||||||
|
byteSize = 16;
|
||||||
|
break;
|
||||||
|
//Case A0 and A1 means "Write to Uncached address.
|
||||||
|
case "A0":
|
||||||
|
//Byte
|
||||||
|
byteSize = 8;
|
||||||
|
break;
|
||||||
|
case "A1":
|
||||||
|
//Word
|
||||||
|
byteSize = 16;
|
||||||
|
break;
|
||||||
|
//Do we support the GameShark Button? No. But these cheats, can be toggled. Which "Counts"
|
||||||
|
//<Ocean_Prince> Consequences be damned!
|
||||||
|
case "88":
|
||||||
|
//Byte
|
||||||
|
byteSize = 8;
|
||||||
|
break;
|
||||||
|
case "89":
|
||||||
|
//Word
|
||||||
|
byteSize = 16;
|
||||||
|
break;
|
||||||
|
//These are compare Address X to Value Y, then apply Value B to Address A
|
||||||
|
//This is not supported, yet
|
||||||
|
//TODO: When BizHawk supports a compare RAM Address's value is true then apply a value to another address, make it a thing.
|
||||||
|
case "D0":
|
||||||
|
//Byte
|
||||||
|
case "D1":
|
||||||
|
//Word
|
||||||
|
case "D2":
|
||||||
|
//Byte
|
||||||
|
case "D3":
|
||||||
|
//Word
|
||||||
|
MessageBox.Show("The code you entered is not supported by BizHawk.", "Emulator Error", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
|
return;
|
||||||
|
//These codes are for Disabling the Expansion Pak. that's a bad thing? Assuming bad codes, until told otherwise.
|
||||||
|
case "EE":
|
||||||
|
case "DD":
|
||||||
|
case "CC":
|
||||||
|
MessageBox.Show("The code you entered is for Disabling the Expansion Pak. This is not allowed by this tool.", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
|
return;
|
||||||
|
//Enable Code
|
||||||
|
//Not Necessary? Think so?
|
||||||
|
case "DE":
|
||||||
|
//Single Write ON-Boot code.
|
||||||
|
//Not Necessary? Think so?
|
||||||
|
case "F0":
|
||||||
|
case "F1":
|
||||||
|
case "2A":
|
||||||
|
case "3C":
|
||||||
|
case "FF":
|
||||||
|
MessageBox.Show("The code you entered is not needed by Bizhawk.", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
|
return;
|
||||||
|
//TODO: Make Patch Code (5000XXYY) work.
|
||||||
|
case "50":
|
||||||
|
//Word?
|
||||||
|
MessageBox.Show("The code you entered is not supported by this tool. Please Submit the Game's Name, Cheat/Code and Purpose to the BizHawk forums.", "Tool Error", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
|
return;
|
||||||
|
//I hope this isn't a thing.
|
||||||
|
default:
|
||||||
|
MessageBox.Show("The GameShark code entered is not a recognized format.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
//Leave this Method, before someone gets hurt.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//Now to get clever.
|
||||||
|
//Sample Input for N64:
|
||||||
|
//8133B21E 08FF
|
||||||
|
//Becomes:
|
||||||
|
//Address 33B21E
|
||||||
|
//Value 08FF
|
||||||
|
|
||||||
|
//Note, 80XXXXXX 00YY
|
||||||
|
//Is Byte, not Word
|
||||||
|
//Remove the 80 Octect
|
||||||
|
parseString = txtCheat.Text.Remove(0, 2);
|
||||||
|
//Get RAM Address
|
||||||
|
RAMAddress = parseString.Remove(6, 5);
|
||||||
|
//Get RAM Value
|
||||||
|
RAMValue = parseString.Remove(0, 7);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//A Watch needs to be generated so we can make a cheat out of that. This is due to how the Cheat engine works.
|
||||||
|
//System Bus Domain, The Address to Watch, Byte size (Word), Hex Display, Description, Big Endian.
|
||||||
|
if (byteSize == 8)
|
||||||
|
{
|
||||||
|
//We have a Byte sized value
|
||||||
|
var watch = Watch.GenerateWatch(MemoryDomains["RDRAM"], long.Parse(RAMAddress, NumberStyles.HexNumber), Watch.WatchSize.Byte, Watch.DisplayType.Hex, txtDescription.Text, true);
|
||||||
|
//Take Watch, Add our Value we want, and it should be active when addded?
|
||||||
|
Global.CheatList.Add(new Cheat(watch, int.Parse(RAMValue, NumberStyles.HexNumber)));
|
||||||
|
}
|
||||||
|
if (byteSize == 16)
|
||||||
|
{
|
||||||
|
//We have a Word (Double Byte) sized Value
|
||||||
|
var watch = Watch.GenerateWatch(MemoryDomains["RDRAM"], long.Parse(RAMAddress, NumberStyles.HexNumber), Watch.WatchSize.Word, Watch.DisplayType.Hex, txtDescription.Text, true);
|
||||||
|
//Take Watch, Add our Value we want, and it should be active when addded?
|
||||||
|
Global.CheatList.Add(new Cheat(watch, int.Parse(RAMValue, NumberStyles.HexNumber)));
|
||||||
|
}
|
||||||
|
//Clear old Inputs
|
||||||
|
txtCheat.Clear();
|
||||||
|
txtDescription.Clear();
|
||||||
|
}
|
||||||
|
//Someone broke the world?
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show("An Error occured: " + ex.GetType().ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void PSX()
|
||||||
|
{
|
||||||
|
//These codes, more or less work without Needing much work.
|
||||||
|
if (txtCheat.Text.IndexOf(" ") != 8)
|
||||||
|
{
|
||||||
|
MessageBox.Show("All PSX GameShark Codes need to contain a space after the eighth character", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (txtCheat.Text.Length != 13)
|
||||||
|
{
|
||||||
|
MessageBox.Show("All PSX GameShark Cheats need to be 13 characters in length.", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//We need to determine what kind of cheat this is.
|
||||||
|
//I need to determine if this is a Byte or Word.
|
||||||
|
switch (testo)
|
||||||
|
{
|
||||||
|
//30 80 Cheats mean, "Write, don't care otherwise."
|
||||||
|
case "30":
|
||||||
|
byteSize = 8;
|
||||||
|
break;
|
||||||
|
case "80":
|
||||||
|
byteSize = 16;
|
||||||
|
break;
|
||||||
|
//When value hits YYYY, make the next cheat go off
|
||||||
|
case "E0":
|
||||||
|
//E0 byteSize = 8;
|
||||||
|
case "E1":
|
||||||
|
//E1 byteSize = 8;
|
||||||
|
case "E2":
|
||||||
|
//E2 byteSize = 8;
|
||||||
|
case "D0":
|
||||||
|
//D0 byteSize = 16;
|
||||||
|
case "D1":
|
||||||
|
//D1 byteSize = 16;
|
||||||
|
case "D2":
|
||||||
|
//D2 byteSize = 16;
|
||||||
|
case "D3":
|
||||||
|
//D3 byteSize = 16;
|
||||||
|
case "D4":
|
||||||
|
//D4 byteSize = 16;
|
||||||
|
case "D5":
|
||||||
|
//D5 byteSize = 16;
|
||||||
|
case "D6":
|
||||||
|
//D6 byteSize = 16;
|
||||||
|
|
||||||
|
//Increment/Decrement Codes
|
||||||
|
case "10":
|
||||||
|
//10 byteSize = 16;
|
||||||
|
case "11":
|
||||||
|
//11 byteSize = 16;
|
||||||
|
case "20":
|
||||||
|
//20 byteSize = 8
|
||||||
|
case "21":
|
||||||
|
//21 byteSize = 8
|
||||||
|
MessageBox.Show("The code you entered is not supported by BizHawk.", "Emulator Error", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
|
return;
|
||||||
|
case "C0":
|
||||||
|
case "C1":
|
||||||
|
//Slow-Mo
|
||||||
|
case "40":
|
||||||
|
MessageBox.Show("The code you entered is not needed by Bizhawk.", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
|
return;
|
||||||
|
case "C2":
|
||||||
|
case "50":
|
||||||
|
//Word?
|
||||||
|
MessageBox.Show("The code you entered is not supported by this tool. Please Submit the Game's Name, Cheat/Code and Purpose to the BizHawk forums.", "Tool Error", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
|
return;
|
||||||
|
//Something wrong with their input.
|
||||||
|
default:
|
||||||
|
MessageBox.Show("The GameShark code entered is not a recognized format.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
//Leave this Method, before someone gets hurt.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//Sample Input for PSX:
|
||||||
|
//800D10BA 0009
|
||||||
|
//Address: 0D10BA
|
||||||
|
//Value: 0009
|
||||||
|
//Remove first two octets
|
||||||
|
parseString = txtCheat.Text.Remove(0, 2);
|
||||||
|
//Get RAM Address
|
||||||
|
RAMAddress = parseString.Remove(6, 5);
|
||||||
|
//Get RAM Value
|
||||||
|
RAMValue = parseString.Remove(0, 7);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//A Watch needs to be generated so we can make a cheat out of that. This is due to how the Cheat engine works.
|
||||||
|
//System Bus Domain, The Address to Watch, Byte size (Word), Hex Display, Description. Big Endian.
|
||||||
|
|
||||||
|
//My Consern is that Work RAM High may be incorrect?
|
||||||
|
if (byteSize == 8)
|
||||||
|
{
|
||||||
|
//We have a Byte sized value
|
||||||
|
var watch = Watch.GenerateWatch(MemoryDomains["MainRAM"], long.Parse(RAMAddress, NumberStyles.HexNumber), Watch.WatchSize.Word, Watch.DisplayType.Hex, txtDescription.Text, false);
|
||||||
|
//Take Watch, Add our Value we want, and it should be active when addded?
|
||||||
|
Global.CheatList.Add(new Cheat(watch, int.Parse(RAMValue, NumberStyles.HexNumber)));
|
||||||
|
}
|
||||||
|
if (byteSize == 16)
|
||||||
|
{
|
||||||
|
//We have a Word (Double Byte) sized Value
|
||||||
|
var watch = Watch.GenerateWatch(MemoryDomains["MainRAM"], long.Parse(RAMAddress, NumberStyles.HexNumber), Watch.WatchSize.Byte, Watch.DisplayType.Hex, txtDescription.Text, false);
|
||||||
|
//Take Watch, Add our Value we want, and it should be active when addded?
|
||||||
|
Global.CheatList.Add(new Cheat(watch, int.Parse(RAMValue, NumberStyles.HexNumber)));
|
||||||
|
}
|
||||||
|
//Clear old Inputs
|
||||||
|
txtCheat.Clear();
|
||||||
|
txtDescription.Clear();
|
||||||
|
}
|
||||||
|
//Someone broke the world?
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show("An Error occured: " + ex.GetType().ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
private void SAT()
|
||||||
|
{
|
||||||
|
//Not yet.
|
||||||
|
if (txtCheat.Text.IndexOf(" ") != 8)
|
||||||
|
{
|
||||||
|
MessageBox.Show("All Saturn GameShark Codes need to contain a space after the eighth character", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (txtCheat.Text.Length != 13)
|
||||||
|
{
|
||||||
|
MessageBox.Show("All Saturn GameShark Cheats need to be 13 characters in length.", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//This is a special test. Only the first character really matters? 16 or 36?
|
||||||
|
testo = testo.Remove(1, 1);
|
||||||
|
switch (testo)
|
||||||
|
{
|
||||||
|
case "1":
|
||||||
|
byteSize = 16;
|
||||||
|
break;
|
||||||
|
case "3":
|
||||||
|
byteSize = 8;
|
||||||
|
break;
|
||||||
|
//0 writes once.
|
||||||
|
case "0":
|
||||||
|
//D is RAM Equal To Activator, do Next Value
|
||||||
|
case "D":
|
||||||
|
MessageBox.Show("The code you entered is not supported by BizHawk.", "Emulator Error", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
|
return;
|
||||||
|
case "F":
|
||||||
|
MessageBox.Show("The code you entered is not needed by Bizhawk.", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
MessageBox.Show("The GameShark code entered is not a recognized format.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
//Leave this Method, before someone gets hurt.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//Sample Input for Saturn:
|
||||||
|
//160949FC 0090
|
||||||
|
//Address: 0949FC
|
||||||
|
//Value: 90
|
||||||
|
//Note, 3XXXXXXX are Big Endian
|
||||||
|
//Remove first two octets
|
||||||
|
parseString = txtCheat.Text.Remove(0, 2);
|
||||||
|
//Get RAM Address
|
||||||
|
RAMAddress = parseString.Remove(6, 5);
|
||||||
|
//Get RAM Value
|
||||||
|
RAMValue = parseString.Remove(0, 7);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//A Watch needs to be generated so we can make a cheat out of that. This is due to how the Cheat engine works.
|
||||||
|
//System Bus Domain, The Address to Watch, Byte size (Word), Hex Display, Description. Big Endian.
|
||||||
|
|
||||||
|
//My Consern is that Work RAM High may be incorrect?
|
||||||
|
if (byteSize == 8)
|
||||||
|
{
|
||||||
|
//We have a Byte sized value
|
||||||
|
var watch = Watch.GenerateWatch(MemoryDomains["Work Ram High"], long.Parse(RAMAddress, NumberStyles.HexNumber), Watch.WatchSize.Word, Watch.DisplayType.Hex, txtDescription.Text, true);
|
||||||
|
//Take Watch, Add our Value we want, and it should be active when addded?
|
||||||
|
Global.CheatList.Add(new Cheat(watch, int.Parse(RAMValue, NumberStyles.HexNumber)));
|
||||||
|
}
|
||||||
|
if (byteSize == 16)
|
||||||
|
{
|
||||||
|
//We have a Word (Double Byte) sized Value
|
||||||
|
var watch = Watch.GenerateWatch(MemoryDomains["Work Ram High"], long.Parse(RAMAddress, NumberStyles.HexNumber), Watch.WatchSize.Byte, Watch.DisplayType.Hex, txtDescription.Text, true);
|
||||||
|
//Take Watch, Add our Value we want, and it should be active when addded?
|
||||||
|
Global.CheatList.Add(new Cheat(watch, int.Parse(RAMValue, NumberStyles.HexNumber)));
|
||||||
|
}
|
||||||
|
//Clear old Inputs
|
||||||
|
txtCheat.Clear();
|
||||||
|
txtDescription.Clear();
|
||||||
|
}
|
||||||
|
//Someone broke the world?
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show("An Error occured: " + ex.GetType().ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void SMS()
|
||||||
|
{
|
||||||
|
//This is FUN!
|
||||||
|
if (txtCheat.Text.IndexOf("-") != 4)
|
||||||
|
{
|
||||||
|
MessageBox.Show("All Master System Action Replay Codes need to contain a dash after the fourth character.", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (txtCheat.Text.Length != 9)
|
||||||
|
{
|
||||||
|
MessageBox.Show("All Master System Action Replay Codes need to nine charaters in length.", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
parseString = txtCheat.Text;
|
||||||
|
parseString = parseString.Remove(0, 2);
|
||||||
|
//MessageBox.Show(parseString);
|
||||||
|
RAMAddress = parseString.Remove(4, 2);
|
||||||
|
//MessageBox.Show(RAMAddress);
|
||||||
|
RAMAddress = RAMAddress.Replace("-", "");
|
||||||
|
MessageBox.Show(RAMAddress);
|
||||||
|
RAMValue = parseString.Remove(0, 5);
|
||||||
|
MessageBox.Show(RAMValue);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//A Watch needs to be generated so we can make a cheat out of that. This is due to how the Cheat engine works.
|
||||||
|
//System Bus Domain, The Address to Watch, Byte size (Byte), Hex Display, Description. Not Big Endian.
|
||||||
|
var watch = Watch.GenerateWatch(MemoryDomains["Main RAM"], long.Parse(RAMAddress, NumberStyles.HexNumber), Watch.WatchSize.Byte, Watch.DisplayType.Hex, txtDescription.Text, false);
|
||||||
|
//Take Watch, Add our Value we want, and it should be active when addded?
|
||||||
|
Global.CheatList.Add(new Cheat(watch, int.Parse(RAMValue, NumberStyles.HexNumber)));
|
||||||
|
//Clear old Inputs
|
||||||
|
txtCheat.Clear();
|
||||||
|
txtDescription.Clear();
|
||||||
|
}
|
||||||
|
//Someone broke the world?
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show("An Error occured: " + ex.GetType().ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void SNES()
|
||||||
|
{
|
||||||
|
//TODO: Sample Code and Get Smarter?
|
||||||
|
//This ONLY applies to Action Replay.
|
||||||
|
if (txtCheat.Text.Length != 8)
|
||||||
|
{
|
||||||
|
MessageBox.Show("All Action Replay Codes need to be Eight characters in Length", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//The Action Replay, is odd.
|
||||||
|
//Checking won't be done.
|
||||||
|
//Remove first two octets
|
||||||
|
RAMAddress = txtCheat.Text.Remove(6, 2);
|
||||||
|
//Get RAM Value
|
||||||
|
RAMValue = txtCheat.Text.Remove(0, 6);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//A Watch needs to be generated so we can make a cheat out of that. This is due to how the Cheat engine works.
|
||||||
|
//System Bus Domain, The Address to Watch, Byte size (Byte), Hex Display, Description. Not Big Endian.
|
||||||
|
var watch = Watch.GenerateWatch(MemoryDomains["System Bus"], long.Parse(RAMAddress, NumberStyles.HexNumber), Watch.WatchSize.Byte, Watch.DisplayType.Hex, txtDescription.Text, false);
|
||||||
|
//Take Watch, Add our Value we want, and it should be active when addded?
|
||||||
|
Global.CheatList.Add(new Cheat(watch, int.Parse(RAMValue, NumberStyles.HexNumber)));
|
||||||
|
//Clear old Inputs
|
||||||
|
txtCheat.Clear();
|
||||||
|
txtDescription.Clear();
|
||||||
|
}
|
||||||
|
//Someone broke the world?
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show("An Error occured: " + ex.GetType().ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void btnClear_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
//Clear old Inputs
|
//Clear old Inputs
|
||||||
txtCheat.Clear();
|
txtCheat.Clear();
|
||||||
|
@ -97,7 +758,9 @@ namespace BizHawk.Client.EmuHawk
|
||||||
|
|
||||||
private void GameShark_Load(object sender, EventArgs e)
|
private void GameShark_Load(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
|
//Welp, let's determine what System we got.
|
||||||
|
//NOTE: This is a sloppy Debugger/testing code. For Bad Development usage. DO NOT release with that line uncommented
|
||||||
|
//MessageBox.Show(Emulator.SystemId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -367,8 +367,8 @@ namespace BizHawk.Client.EmuHawk
|
||||||
|
|
||||||
private static byte[] GetRomBytes()
|
private static byte[] GetRomBytes()
|
||||||
{
|
{
|
||||||
var path = GlobalWin.MainForm.CurrentlyOpenRom;
|
var path = GlobalWin.MainForm.CurrentlyOpenRomArgs.OpenAdvanced.SimplePath;
|
||||||
if (path == null)
|
if (string.IsNullOrEmpty(path))
|
||||||
{
|
{
|
||||||
return new byte[] { 0xFF };
|
return new byte[] { 0xFF };
|
||||||
}
|
}
|
||||||
|
|
|
@ -1160,6 +1160,10 @@ namespace BizHawk.Client.EmuHawk
|
||||||
{
|
{
|
||||||
var bg = si.BG[(int)CurrDisplaySelection];
|
var bg = si.BG[(int)CurrDisplaySelection];
|
||||||
|
|
||||||
|
//unavailable BG for this mode
|
||||||
|
if (bg.Bpp == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
if (bg.TileSize == 16) { tx /= 2; ty /= 2; } //worry about this later. need to pass a different flag into `currViewingTile`
|
if (bg.TileSize == 16) { tx /= 2; ty /= 2; } //worry about this later. need to pass a different flag into `currViewingTile`
|
||||||
|
|
||||||
int tloc = ty * bg.ScreenSizeInTiles.Width + tx;
|
int tloc = ty * bg.ScreenSizeInTiles.Width + tx;
|
||||||
|
|
|
@ -240,6 +240,19 @@ namespace BizHawk.Common
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
static double GetDouble(IntPtr first, IntPtr second)
|
||||||
|
{
|
||||||
|
var ms = new MemoryStream(8);
|
||||||
|
var bw = new BinaryWriter(ms);
|
||||||
|
bw.Write(first.ToInt32());
|
||||||
|
bw.Write(second.ToInt32());
|
||||||
|
bw.Flush();
|
||||||
|
ms.Position = 0;
|
||||||
|
var br = new BinaryReader(ms);
|
||||||
|
return br.ReadDouble();
|
||||||
|
}
|
||||||
|
|
||||||
#region sprintf
|
#region sprintf
|
||||||
public static string sprintf( string Format, Func<IntPtr> fetcher )
|
public static string sprintf( string Format, Func<IntPtr> fetcher )
|
||||||
{
|
{
|
||||||
|
@ -458,23 +471,23 @@ namespace BizHawk.Common
|
||||||
#endregion
|
#endregion
|
||||||
#region f - double number
|
#region f - double number
|
||||||
case 'f': // double
|
case 'f': // double
|
||||||
throw new InvalidOperationException("cataleptic kangaroo orchestra");
|
o = GetDouble(n, fetcher());
|
||||||
//w = FormatNumber( ( flagGroupThousands ? "n" : "f" ), flagAlternate,
|
w = FormatNumber( ( flagGroupThousands ? "n" : "f" ), flagAlternate,
|
||||||
// fieldLength, fieldPrecision, flagLeft2Right,
|
fieldLength, fieldPrecision, flagLeft2Right,
|
||||||
// flagPositiveSign, flagPositiveSpace,
|
flagPositiveSign, flagPositiveSpace,
|
||||||
// paddingCharacter, o );
|
paddingCharacter, o );
|
||||||
//defaultParamIx++;
|
defaultParamIx++;
|
||||||
//break;
|
break;
|
||||||
#endregion
|
#endregion
|
||||||
#region e - exponent number
|
#region e - exponent number
|
||||||
case 'e': // double / exponent
|
case 'e': // double / exponent
|
||||||
throw new InvalidOperationException("cataleptic kangaroo orchestra");
|
o = GetDouble(n, fetcher());
|
||||||
//w = FormatNumber( "e", flagAlternate,
|
w = FormatNumber( "e", flagAlternate,
|
||||||
// fieldLength, fieldPrecision, flagLeft2Right,
|
fieldLength, fieldPrecision, flagLeft2Right,
|
||||||
// flagPositiveSign, flagPositiveSpace,
|
flagPositiveSign, flagPositiveSpace,
|
||||||
// paddingCharacter, o );
|
paddingCharacter, o );
|
||||||
//defaultParamIx++;
|
defaultParamIx++;
|
||||||
//break;
|
break;
|
||||||
#endregion
|
#endregion
|
||||||
#region E - exponent number
|
#region E - exponent number
|
||||||
case 'E': // double / exponent
|
case 'E': // double / exponent
|
||||||
|
|
|
@ -73,6 +73,4 @@ namespace BizHawk.Common
|
||||||
}
|
}
|
||||||
|
|
||||||
static System.Threading.Thread thread;
|
static System.Threading.Thread thread;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
|
@ -32,10 +32,20 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES
|
||||||
WriteHook((uint)addr, value);
|
WriteHook((uint)addr, value);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//not supported yet
|
||||||
case eMessage.eMessage_BRK_hook_nmi:
|
case eMessage.eMessage_BRK_hook_nmi:
|
||||||
break;
|
break;
|
||||||
case eMessage.eMessage_BRK_hook_irq:
|
case eMessage.eMessage_BRK_hook_irq:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case eMessage.eMessage_BRK_scanlineStart:
|
||||||
|
int line = brPipe.ReadInt32();
|
||||||
|
if (scanlineStart != null)
|
||||||
|
scanlineStart(line);
|
||||||
|
SPECIAL_Resume();
|
||||||
|
break;
|
||||||
|
|
||||||
} //switch(msg)
|
} //switch(msg)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,7 +61,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES
|
||||||
eMessage_SIG_input_state,
|
eMessage_SIG_input_state,
|
||||||
eMessage_SIG_input_notify,
|
eMessage_SIG_input_notify,
|
||||||
eMessage_SIG_audio_flush,
|
eMessage_SIG_audio_flush,
|
||||||
eMessage_SIG_scanlineStart,
|
|
||||||
eMessage_SIG_path_request,
|
eMessage_SIG_path_request,
|
||||||
eMessage_SIG_trace_callback,
|
eMessage_SIG_trace_callback,
|
||||||
eMessage_SIG_allocSharedMemory, //?
|
eMessage_SIG_allocSharedMemory, //?
|
||||||
|
@ -73,6 +72,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES
|
||||||
eMessage_BRK_hook_write,
|
eMessage_BRK_hook_write,
|
||||||
eMessage_BRK_hook_nmi,
|
eMessage_BRK_hook_nmi,
|
||||||
eMessage_BRK_hook_irq,
|
eMessage_BRK_hook_irq,
|
||||||
|
eMessage_BRK_scanlineStart,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -70,17 +70,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES
|
||||||
brPipe.ReadInt32(); //dummy synchronization
|
brPipe.ReadInt32(); //dummy synchronization
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case eMessage.eMessage_SIG_scanlineStart:
|
|
||||||
{
|
|
||||||
int line = brPipe.ReadInt32();
|
|
||||||
if (scanlineStart != null)
|
|
||||||
scanlineStart(line);
|
|
||||||
|
|
||||||
//we have to notify the unmanaged process that we're done peeking thruogh its memory and whatnot so it can proceed with emulation
|
|
||||||
//HUM??????????? BRK_COMPLETE???? SCANLINE CB NEEDS RE-EVALUATING
|
|
||||||
WritePipeMessage(eMessage.eMessage_BRK_Complete);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case eMessage.eMessage_SIG_path_request:
|
case eMessage.eMessage_SIG_path_request:
|
||||||
{
|
{
|
||||||
int slot = brPipe.ReadInt32();
|
int slot = brPipe.ReadInt32();
|
||||||
|
|
|
@ -6,8 +6,7 @@
|
||||||
//http://wiki.superfamicom.org/snes/show/Registers
|
//http://wiki.superfamicom.org/snes/show/Registers
|
||||||
|
|
||||||
//TODO
|
//TODO
|
||||||
//SF2 title art doesnt seem to show up..
|
//when a BG is not available, the last rendered BG still shows up. should clear it
|
||||||
//scanline control doesnt work?
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
|
@ -645,6 +644,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void DecodeBG(int* screen, int stride, TileEntry[] map, int tiledataBaseAddr, ScreenSize size, int bpp, int tilesize, int paletteStart)
|
public void DecodeBG(int* screen, int stride, TileEntry[] map, int tiledataBaseAddr, ScreenSize size, int bpp, int tilesize, int paletteStart)
|
||||||
{
|
{
|
||||||
|
//emergency backstop. this can only happen if we're displaying an unavailable BG or other similar such value
|
||||||
|
if (bpp == 0) return;
|
||||||
|
|
||||||
int ncolors = 1 << bpp;
|
int ncolors = 1 << bpp;
|
||||||
|
|
||||||
int[] tileBuf = new int[16*16];
|
int[] tileBuf = new int[16*16];
|
||||||
|
|
|
@ -95,7 +95,6 @@ enum eMessage : int32
|
||||||
eMessage_SIG_input_state,
|
eMessage_SIG_input_state,
|
||||||
eMessage_SIG_input_notify,
|
eMessage_SIG_input_notify,
|
||||||
eMessage_SIG_audio_flush,
|
eMessage_SIG_audio_flush,
|
||||||
eMessage_SIG_scanlineStart,
|
|
||||||
eMessage_SIG_path_request,
|
eMessage_SIG_path_request,
|
||||||
eMessage_SIG_trace_callback,
|
eMessage_SIG_trace_callback,
|
||||||
eMessage_SIG_allocSharedMemory, //?
|
eMessage_SIG_allocSharedMemory, //?
|
||||||
|
@ -107,6 +106,7 @@ enum eMessage : int32
|
||||||
eMessage_BRK_hook_write,
|
eMessage_BRK_hook_write,
|
||||||
eMessage_BRK_hook_nmi,
|
eMessage_BRK_hook_nmi,
|
||||||
eMessage_BRK_hook_irq,
|
eMessage_BRK_hook_irq,
|
||||||
|
eMessage_BRK_scanlineStart, //implemented as a BRK because that's really what it is, its just a graphical event and not a CPU event
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -122,6 +122,7 @@ enum eEmulationCallback
|
||||||
{
|
{
|
||||||
eEmulationCallback_snes_video_refresh,
|
eEmulationCallback_snes_video_refresh,
|
||||||
eEmulationCallback_snes_audio_flush,
|
eEmulationCallback_snes_audio_flush,
|
||||||
|
eEmulationCallback_snes_scanline,
|
||||||
eEmulationCallback_snes_input_poll,
|
eEmulationCallback_snes_input_poll,
|
||||||
eEmulationCallback_snes_input_state,
|
eEmulationCallback_snes_input_state,
|
||||||
eEmulationCallback_snes_input_notify,
|
eEmulationCallback_snes_input_notify,
|
||||||
|
@ -162,6 +163,10 @@ struct EmulationControl
|
||||||
unsigned height;
|
unsigned height;
|
||||||
} cb_video_refresh_params;
|
} cb_video_refresh_params;
|
||||||
struct
|
struct
|
||||||
|
{
|
||||||
|
int32_t scanline;
|
||||||
|
} cb_scanline_params;
|
||||||
|
struct
|
||||||
{
|
{
|
||||||
unsigned port, device, index, id;
|
unsigned port, device, index, id;
|
||||||
int16_t result;
|
int16_t result;
|
||||||
|
@ -552,14 +557,10 @@ const char* snes_path_request(int slot, const char* hint)
|
||||||
void RunControlMessageLoop();
|
void RunControlMessageLoop();
|
||||||
void snes_scanlineStart(int line)
|
void snes_scanlineStart(int line)
|
||||||
{
|
{
|
||||||
//TODO
|
s_EmulationControl.exitReason = eEmulationExitReason_BRK;
|
||||||
//WritePipe(eMessage_snes_cb_scanlineStart);
|
s_EmulationControl.hookExitType = eMessage_BRK_scanlineStart;
|
||||||
//WritePipe(line);
|
s_EmulationControl.cb_scanline_params.scanline = line;
|
||||||
|
SETCONTROL;
|
||||||
////we've got to wait for the frontend to finish processing.
|
|
||||||
////in theory we could let emulation proceed after snagging the vram and registers, and do decoding and stuff on another thread...
|
|
||||||
////but its too hard for now.
|
|
||||||
//RunMessageLoop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class SharedMemoryBlock
|
class SharedMemoryBlock
|
||||||
|
@ -979,9 +980,10 @@ TOP:
|
||||||
char* buf = (char*)hMapFilePtr + destOfs;
|
char* buf = (char*)hMapFilePtr + destOfs;
|
||||||
int bufsize = 512 * 480 * 4;
|
int bufsize = 512 * 480 * 4;
|
||||||
memcpy(buf,s_EmulationControl.cb_video_refresh_params.data,bufsize);
|
memcpy(buf,s_EmulationControl.cb_video_refresh_params.data,bufsize);
|
||||||
WritePipe((char)0); //dummy synchronization
|
WritePipe((char)0); //dummy synchronization (alert frontend we're done with buffer)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case eEmulationCallback_snes_audio_flush:
|
case eEmulationCallback_snes_audio_flush:
|
||||||
Handle_SIG_audio_flush();
|
Handle_SIG_audio_flush();
|
||||||
break;
|
break;
|
||||||
|
@ -1029,6 +1031,10 @@ TOP:
|
||||||
s_EmulationControl.exitReason = eEmulationExitReason_NotSet;
|
s_EmulationControl.exitReason = eEmulationExitReason_NotSet;
|
||||||
switch(s_EmulationControl.hookExitType)
|
switch(s_EmulationControl.hookExitType)
|
||||||
{
|
{
|
||||||
|
case eMessage_BRK_scanlineStart:
|
||||||
|
WritePipe(eMessage_BRK_scanlineStart);
|
||||||
|
WritePipe((uint32)s_EmulationControl.hookAddr);
|
||||||
|
break;
|
||||||
case eMessage_BRK_hook_exec:
|
case eMessage_BRK_hook_exec:
|
||||||
WritePipe(eMessage_BRK_hook_exec);
|
WritePipe(eMessage_BRK_hook_exec);
|
||||||
WritePipe((uint32)s_EmulationControl.hookAddr);
|
WritePipe((uint32)s_EmulationControl.hookAddr);
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue