Added parser for CT files
Early support for Cheat Engine memory tweaks
This commit is contained in:
parent
6b6f6265f5
commit
c6968ebb8a
|
@ -64,6 +64,8 @@
|
||||||
<Reference Include="System.Xml" />
|
<Reference Include="System.Xml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="DebuggerExtras\CheatTable.cs" />
|
||||||
|
<Compile Include="DebuggerExtras\CheatTableReader.cs" />
|
||||||
<Compile Include="DebuggerSymbols\Kernel\KernelSymbolProvider.cs" />
|
<Compile Include="DebuggerSymbols\Kernel\KernelSymbolProvider.cs" />
|
||||||
<Compile Include="Debugger\Debugger.cs" />
|
<Compile Include="Debugger\Debugger.cs" />
|
||||||
<Compile Include="Debugger\DebuggerEventInterfaces.cs" />
|
<Compile Include="Debugger\DebuggerEventInterfaces.cs" />
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
// Written by x1nixmzeng for the Cxbx-Reloaded project
|
||||||
|
//
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace CxbxDebugger
|
||||||
|
{
|
||||||
|
namespace CheatEngine
|
||||||
|
{
|
||||||
|
public struct State
|
||||||
|
{
|
||||||
|
public uint Value;
|
||||||
|
public bool Activated;
|
||||||
|
public uint RealAddress;
|
||||||
|
};
|
||||||
|
|
||||||
|
public enum Variable
|
||||||
|
{
|
||||||
|
Unknown,
|
||||||
|
Bytes4,
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct CheatEntry
|
||||||
|
{
|
||||||
|
public string ID;
|
||||||
|
public string Description;
|
||||||
|
public State LastState;
|
||||||
|
public uint Color;
|
||||||
|
public Variable VariableType;
|
||||||
|
public string Address;
|
||||||
|
};
|
||||||
|
|
||||||
|
public struct CodeEntry
|
||||||
|
{
|
||||||
|
public string Description;
|
||||||
|
public uint Address;
|
||||||
|
public string ModuleName;
|
||||||
|
public uint ModuleNameOffset;
|
||||||
|
public byte[] Before;
|
||||||
|
public byte[] Actual;
|
||||||
|
public byte[] After;
|
||||||
|
};
|
||||||
|
|
||||||
|
public struct CheatTable
|
||||||
|
{
|
||||||
|
public List<CheatEntry> CheatEntries;
|
||||||
|
public List<CodeEntry> CodeList;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,300 @@
|
||||||
|
// Written by x1nixmzeng for the Cxbx-Reloaded project
|
||||||
|
//
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Xml;
|
||||||
|
|
||||||
|
namespace CxbxDebugger
|
||||||
|
{
|
||||||
|
namespace CheatEngine
|
||||||
|
{
|
||||||
|
public enum CTReaderResult
|
||||||
|
{
|
||||||
|
Success,
|
||||||
|
LoadFailed,
|
||||||
|
MissingNode,
|
||||||
|
UnsupportedVersion,
|
||||||
|
}
|
||||||
|
|
||||||
|
public class CheatTableReader
|
||||||
|
{
|
||||||
|
CheatTable CTRef;
|
||||||
|
|
||||||
|
public CTReaderResult Load(CheatTable ct, string filename)
|
||||||
|
{
|
||||||
|
XmlDocument doc = new XmlDocument();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
doc.Load(filename);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return CTReaderResult.LoadFailed;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ParseDocument(doc);
|
||||||
|
}
|
||||||
|
|
||||||
|
private CTReaderResult ParseDocument(XmlNode root)
|
||||||
|
{
|
||||||
|
foreach (XmlNode xnode in root.ChildNodes)
|
||||||
|
{
|
||||||
|
switch (xnode.NodeType)
|
||||||
|
{
|
||||||
|
case XmlNodeType.Element:
|
||||||
|
{
|
||||||
|
if (xnode.Name == "CheatTable")
|
||||||
|
{
|
||||||
|
return ParseCheatTable(xnode);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return CTReaderResult.MissingNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
private CTReaderResult ParseCheatTable(XmlNode root)
|
||||||
|
{
|
||||||
|
foreach (XmlAttribute attr in root.Attributes)
|
||||||
|
{
|
||||||
|
if (attr.Name == "CheatEngineTableVersion")
|
||||||
|
{
|
||||||
|
if (attr.Value != "21")
|
||||||
|
{
|
||||||
|
return CTReaderResult.UnsupportedVersion;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (XmlNode xnode in root.ChildNodes)
|
||||||
|
{
|
||||||
|
switch (xnode.NodeType)
|
||||||
|
{
|
||||||
|
case XmlNodeType.Element:
|
||||||
|
{
|
||||||
|
switch (xnode.Name)
|
||||||
|
{
|
||||||
|
case "CheatEntries":
|
||||||
|
{
|
||||||
|
ParseCheatEntries(xnode);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case "CheatCodes":
|
||||||
|
{
|
||||||
|
ParseCheatCodes(xnode);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return CTReaderResult.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ParseCheatEntries(XmlNode root)
|
||||||
|
{
|
||||||
|
foreach (XmlNode xnode in root.ChildNodes)
|
||||||
|
{
|
||||||
|
switch (xnode.NodeType)
|
||||||
|
{
|
||||||
|
case XmlNodeType.Element:
|
||||||
|
{
|
||||||
|
if (xnode.Name == "CheatEntry")
|
||||||
|
{
|
||||||
|
ParseCheatEntry(xnode);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ParseCheatCodes(XmlNode root)
|
||||||
|
{
|
||||||
|
foreach (XmlNode xnode in root.ChildNodes)
|
||||||
|
{
|
||||||
|
switch (xnode.NodeType)
|
||||||
|
{
|
||||||
|
case XmlNodeType.Element:
|
||||||
|
{
|
||||||
|
if (xnode.Name == "CodeEntry")
|
||||||
|
{
|
||||||
|
ParseCodeEntry(xnode);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static uint GetHexNumber(string numeric_string)
|
||||||
|
{
|
||||||
|
uint swap = 0;
|
||||||
|
uint.TryParse(numeric_string, System.Globalization.NumberStyles.HexNumber, null, out swap);
|
||||||
|
return swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static uint GetNumber(string numeric_string)
|
||||||
|
{
|
||||||
|
uint swap = 0;
|
||||||
|
uint.TryParse(numeric_string, System.Globalization.NumberStyles.Integer, null, out swap);
|
||||||
|
return swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ParseCheatEntry(XmlNode root)
|
||||||
|
{
|
||||||
|
CheatEntry Entry = new CheatEntry();
|
||||||
|
|
||||||
|
foreach (XmlNode xnode in root.ChildNodes)
|
||||||
|
{
|
||||||
|
switch (xnode.NodeType)
|
||||||
|
{
|
||||||
|
case XmlNodeType.Element:
|
||||||
|
{
|
||||||
|
switch (xnode.Name)
|
||||||
|
{
|
||||||
|
case "ID":
|
||||||
|
Entry.ID = xnode.InnerText;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "Description":
|
||||||
|
Entry.Description = xnode.InnerText;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "LastState":
|
||||||
|
|
||||||
|
foreach (XmlAttribute attr in xnode.Attributes)
|
||||||
|
{
|
||||||
|
switch (attr.Name)
|
||||||
|
{
|
||||||
|
case "Value":
|
||||||
|
Entry.LastState.Value = GetNumber(attr.Value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "Activated":
|
||||||
|
Entry.LastState.Activated = (GetNumber(attr.Value) != 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "RealAddress":
|
||||||
|
Entry.LastState.RealAddress = GetHexNumber(attr.Value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "Color":
|
||||||
|
Entry.Color = GetHexNumber(xnode.InnerText);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "VariableType":
|
||||||
|
|
||||||
|
switch (xnode.InnerText)
|
||||||
|
{
|
||||||
|
case "4 Bytes":
|
||||||
|
Entry.VariableType = Variable.Bytes4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Entry.VariableType = Variable.Unknown;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "Address":
|
||||||
|
Entry.Address = xnode.InnerText;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CTRef.CheatEntries.Add(Entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ParseCodeEntry(XmlNode root)
|
||||||
|
{
|
||||||
|
CodeEntry Entry = new CodeEntry();
|
||||||
|
|
||||||
|
foreach (XmlNode xnode in root.ChildNodes)
|
||||||
|
{
|
||||||
|
switch (xnode.NodeType)
|
||||||
|
{
|
||||||
|
case XmlNodeType.Element:
|
||||||
|
{
|
||||||
|
switch (xnode.Name)
|
||||||
|
{
|
||||||
|
case "Description":
|
||||||
|
Entry.Description = xnode.InnerText;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "Address":
|
||||||
|
Entry.Address = GetHexNumber(xnode.InnerText);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "ModuleName":
|
||||||
|
Entry.ModuleName = xnode.InnerText;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "ModuleNameOffset":
|
||||||
|
Entry.ModuleNameOffset = GetHexNumber(xnode.InnerText);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "Before":
|
||||||
|
Entry.Before = ParseBytes(xnode);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "Actual":
|
||||||
|
Entry.Actual = ParseBytes(xnode);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "After":
|
||||||
|
Entry.After = ParseBytes(xnode);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CTRef.CodeList.Add(Entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] ParseBytes(XmlNode root)
|
||||||
|
{
|
||||||
|
List<byte> Bytes = new List<byte>();
|
||||||
|
|
||||||
|
foreach (XmlNode xnode in root.ChildNodes)
|
||||||
|
{
|
||||||
|
switch (xnode.NodeType)
|
||||||
|
{
|
||||||
|
case XmlNodeType.Element:
|
||||||
|
{
|
||||||
|
if (xnode.Name == "Byte")
|
||||||
|
{
|
||||||
|
uint Value = GetHexNumber(xnode.InnerText);
|
||||||
|
Bytes.Add((byte)(Value & 0xFF));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Bytes.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue