using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using BizHawk.Emulation.Common; namespace BizHawk.Emulation.Common { public class CodeDataLog : Dictionary { public CodeDataLog() { } /// /// This is just a hook, if needed, to readily suspend logging, without having to rewire the core /// public bool Active = true; public string SubType; public int SubVer; /// /// Tests whether the other CodeDataLog is structurally identical /// public bool Check(CodeDataLog other) { if (SubType != other.SubType) return false; if (SubVer != other.SubVer) return false; if (this.Count != other.Count) return false; foreach (var kvp in this) { if (!other.ContainsKey(kvp.Key)) return false; var oval = other[kvp.Key]; if (oval.Length != kvp.Value.Length) return false; } return true; } public void LogicalOrFrom(CodeDataLog other) { if (this.Count != other.Count) throw new InvalidDataException("Dictionaries must have the same number of keys!"); foreach (var kvp in other) { byte[] fromdata = kvp.Value; byte[] todata = this[kvp.Key]; if (fromdata.Length != todata.Length) throw new InvalidDataException("Memory regions must be the same size!"); for (int i = 0; i < todata.Length; i++) todata[i] |= fromdata[i]; } } public void ClearData() { foreach (byte[] data in Values) Array.Clear(data, 0, data.Length); } public void Save(Stream s) { _Save(s, true); } Dictionary _Save(Stream s, bool forReal) { var ret = new Dictionary(); var w = new BinaryWriter(s); w.Write("BIZHAWK-CDL-2"); w.Write(SubType.PadRight(15)); w.Write(Count); w.Flush(); long addr = s.Position; if (forReal) { foreach (var kvp in this) { w.Write(kvp.Key); w.Write(kvp.Value.Length); w.Write(kvp.Value); } } else { foreach (var kvp in this) { addr += kvp.Key.Length + 1; //assumes shortly-encoded key names addr += 4; ret[kvp.Key] = addr; addr += kvp.Value.Length; } } w.Flush(); return ret; } public Dictionary GetBlockMap() { return _Save(new MemoryStream(), false); } public void Load(Stream s) { var br = new BinaryReader(s); string id = br.ReadString(); if (id == "BIZHAWK-CDL-1") SubType = "PCE"; else if (id == "BIZHAWK-CDL-2") SubType = br.ReadString().TrimEnd(' '); else throw new InvalidDataException("File is not a Bizhawk CDL file!"); int count = br.ReadInt32(); for (int i = 0; i < count; i++) { string key = br.ReadString(); int len = br.ReadInt32(); byte[] data = br.ReadBytes(len); this[key] = data; } } } }