From 6bbab41b0c7223afcb3e28f829b0e84740cac2b4 Mon Sep 17 00:00:00 2001 From: "andres.delikat" Date: Sat, 24 Sep 2011 17:05:34 +0000 Subject: [PATCH] PCE - Implement PCECD system id in core and in game info. Also set cancel property of LogWindow winform --- .../Consoles/PC Engine/PCEngine.cs | 977 +++++++++--------- BizHawk.MultiClient/LogWindow.Designer.cs | 2 + BizHawk.MultiClient/MainForm.cs | 8 +- BizHawk.MultiClient/config/PathManager.cs | 5 + BizHawk.MultiClient/movie/Movie.cs | 1 + 5 files changed, 511 insertions(+), 482 deletions(-) diff --git a/BizHawk.Emulation/Consoles/PC Engine/PCEngine.cs b/BizHawk.Emulation/Consoles/PC Engine/PCEngine.cs index c4ab277d19..726b849a97 100644 --- a/BizHawk.Emulation/Consoles/PC Engine/PCEngine.cs +++ b/BizHawk.Emulation/Consoles/PC Engine/PCEngine.cs @@ -8,541 +8,558 @@ using BizHawk.DiscSystem; namespace BizHawk.Emulation.Consoles.TurboGrafx { - public enum NecSystemType { TurboGrafx, TurboCD, SuperGrafx } + public enum NecSystemType { TurboGrafx, TurboCD, SuperGrafx } - [CoreVersion("1.2.1", FriendlyName = "TurboHawk16")] - public sealed partial class PCEngine : IEmulator - { - // ROM - public byte[] RomData; - public int RomLength; - Disc disc; + [CoreVersion("1.2.1", FriendlyName = "TurboHawk16")] + public sealed partial class PCEngine : IEmulator + { + // ROM + public byte[] RomData; + public int RomLength; + Disc disc; - // Machine - public NecSystemType Type; - public HuC6280 Cpu; - public VDC VDC1, VDC2; - public VCE VCE; - public VPC VPC; - public ScsiCDBus SCSI; - public ADPCM ADPCM; + // Machine + public NecSystemType Type; + public HuC6280 Cpu; + public VDC VDC1, VDC2; + public VCE VCE; + public VPC VPC; + public ScsiCDBus SCSI; + public ADPCM ADPCM; - public HuC6280PSG PSG; - public CDAudio CDAudio; - public SoundMixer SoundMixer; - public MetaspuSoundProvider SoundSynchronizer; + public HuC6280PSG PSG; + public CDAudio CDAudio; + public SoundMixer SoundMixer; + public MetaspuSoundProvider SoundSynchronizer; - bool TurboGrafx { get { return Type == NecSystemType.TurboGrafx; } } - bool SuperGrafx { get { return Type == NecSystemType.SuperGrafx; } } - bool TurboCD { get { return Type == NecSystemType.TurboCD; } } - - // BRAM - bool BramEnabled = false; - bool BramLocked = true; - byte[] BRAM; + bool TurboGrafx { get { return Type == NecSystemType.TurboGrafx; } } + bool SuperGrafx { get { return Type == NecSystemType.SuperGrafx; } } + bool TurboCD { get { return Type == NecSystemType.TurboCD; } } - // Memory system - public byte[] Ram; // PCE= 8K base ram, SGX= 64k base ram - public byte[] CDRam; // TurboCD extra 64k of ram - public byte[] SuperRam; // Super System Card 192K of additional RAM - public byte[] ArcadeRam; // Arcade Card 2048K of additional RAM + // BRAM + bool BramEnabled = false; + bool BramLocked = true; + byte[] BRAM; - // 21,477,270 Machine clocks / sec - // 7,159,090 Cpu cycles / sec + // Memory system + public byte[] Ram; // PCE= 8K base ram, SGX= 64k base ram + public byte[] CDRam; // TurboCD extra 64k of ram + public byte[] SuperRam; // Super System Card 192K of additional RAM + public byte[] ArcadeRam; // Arcade Card 2048K of additional RAM - public PCEngine(GameInfo game, byte[] rom) - { - CoreOutputComm = new CoreOutputComm(); + private string systemid = "PCE"; - switch (game.System) - { - case "PCE": Type = NecSystemType.TurboGrafx; break; - case "SGX": Type = NecSystemType.SuperGrafx; break; - } - Init(game, rom); - } + // 21,477,270 Machine clocks / sec + // 7,159,090 Cpu cycles / sec - public PCEngine(GameInfo game, Disc disc, byte[] rom) - { - CoreOutputComm = new CoreOutputComm(); - Type = NecSystemType.TurboCD; - this.disc = disc; - Init(game, rom); - } + public PCEngine(GameInfo game, byte[] rom) + { + CoreOutputComm = new CoreOutputComm(); - void Init(GameInfo game, byte[] rom) - { - Controller = NullController.GetNullController(); - Cpu = new HuC6280(); - VCE = new VCE(); - VDC1 = new VDC(Cpu, VCE); - PSG = new HuC6280PSG(); - SCSI = new ScsiCDBus(this, disc); + switch (game.System) + { + case "PCE": + systemid = "PCE"; + Type = NecSystemType.TurboGrafx; + break; + case "SGX": + systemid = "SGX"; + Type = NecSystemType.SuperGrafx; + break; + } + Init(game, rom); + } - if (TurboGrafx) - { - Ram = new byte[0x2000]; - Cpu.ReadMemory21 = ReadMemory; - Cpu.WriteMemory21 = WriteMemory; - Cpu.WriteVDC = VDC1.WriteVDC; - soundProvider = PSG; - CDAudio = new CDAudio(null, 0); - } + public PCEngine(GameInfo game, Disc disc, byte[] rom) + { + systemid = "PCECD"; + CoreOutputComm = new CoreOutputComm(); + Type = NecSystemType.TurboCD; + this.disc = disc; + Init(game, rom); + } - else if (SuperGrafx) - { - VDC2 = new VDC(Cpu, VCE); - VPC = new VPC(VDC1, VDC2, VCE, Cpu); - Ram = new byte[0x8000]; - Cpu.ReadMemory21 = ReadMemorySGX; - Cpu.WriteMemory21 = WriteMemorySGX; - Cpu.WriteVDC = VDC1.WriteVDC; - soundProvider = PSG; - CDAudio = new CDAudio(null, 0); - } + void Init(GameInfo game, byte[] rom) + { + Controller = NullController.GetNullController(); + Cpu = new HuC6280(); + VCE = new VCE(); + VDC1 = new VDC(Cpu, VCE); + PSG = new HuC6280PSG(); + SCSI = new ScsiCDBus(this, disc); - else if (TurboCD) - { - Ram = new byte[0x2000]; - CDRam = new byte[0x10000]; - ADPCM = new ADPCM(this, SCSI); - Cpu.ReadMemory21 = ReadMemoryCD; - Cpu.WriteMemory21 = WriteMemoryCD; - Cpu.WriteVDC = VDC1.WriteVDC; - CDAudio = new CDAudio(disc); - SetCDAudioCallback(); - PSG.MaxVolume = short.MaxValue * 3 / 4; - SoundMixer = new SoundMixer(PSG, CDAudio, ADPCM); - SoundSynchronizer = new MetaspuSoundProvider(ESynchMethod.ESynchMethod_V); - soundProvider = SoundSynchronizer; - Cpu.ThinkAction = (cycles) => { SCSI.Think(); ADPCM.Think(cycles); }; - } + if (TurboGrafx) + { + Ram = new byte[0x2000]; + Cpu.ReadMemory21 = ReadMemory; + Cpu.WriteMemory21 = WriteMemory; + Cpu.WriteVDC = VDC1.WriteVDC; + soundProvider = PSG; + CDAudio = new CDAudio(null, 0); + } - if (rom.Length == 0x60000) - { - // 384k roms require special loading code. Why ;_; - // In memory, 384k roms look like [1st 256k][Then full 384k] - RomData = new byte[0xA0000]; - var origRom = rom; - for (int i=0; i<0x40000; i++) - RomData[i] = origRom[i]; - for (int i = 0; i < 0x60000; i++) - RomData[i+0x40000] = origRom[i]; - RomLength = RomData.Length; - } else if (rom.Length > 1024 * 1024) { - // If the rom is bigger than 1 megabyte, switch to Street Fighter 2 mapper - Cpu.ReadMemory21 = ReadMemorySF2; - Cpu.WriteMemory21 = WriteMemorySF2; - RomData = rom; - RomLength = RomData.Length; - } else { - // normal rom. - RomData = rom; - RomLength = RomData.Length; - } + else if (SuperGrafx) + { + VDC2 = new VDC(Cpu, VCE); + VPC = new VPC(VDC1, VDC2, VCE, Cpu); + Ram = new byte[0x8000]; + Cpu.ReadMemory21 = ReadMemorySGX; + Cpu.WriteMemory21 = WriteMemorySGX; + Cpu.WriteVDC = VDC1.WriteVDC; + soundProvider = PSG; + CDAudio = new CDAudio(null, 0); + } - if (game["BRAM"] || Type == NecSystemType.TurboCD) - { - BramEnabled = true; - BRAM = new byte[2048]; + else if (TurboCD) + { + Ram = new byte[0x2000]; + CDRam = new byte[0x10000]; + ADPCM = new ADPCM(this, SCSI); + Cpu.ReadMemory21 = ReadMemoryCD; + Cpu.WriteMemory21 = WriteMemoryCD; + Cpu.WriteVDC = VDC1.WriteVDC; + CDAudio = new CDAudio(disc); + SetCDAudioCallback(); + PSG.MaxVolume = short.MaxValue * 3 / 4; + SoundMixer = new SoundMixer(PSG, CDAudio, ADPCM); + SoundSynchronizer = new MetaspuSoundProvider(ESynchMethod.ESynchMethod_V); + soundProvider = SoundSynchronizer; + Cpu.ThinkAction = (cycles) => { SCSI.Think(); ADPCM.Think(cycles); }; + } - // pre-format BRAM. damn are we helpful. - BRAM[0] = 0x48; BRAM[1] = 0x55; BRAM[2] = 0x42; BRAM[3] = 0x4D; - BRAM[4] = 0x00; BRAM[5] = 0x88; BRAM[6] = 0x10; BRAM[7] = 0x80; - } + if (rom.Length == 0x60000) + { + // 384k roms require special loading code. Why ;_; + // In memory, 384k roms look like [1st 256k][Then full 384k] + RomData = new byte[0xA0000]; + var origRom = rom; + for (int i = 0; i < 0x40000; i++) + RomData[i] = origRom[i]; + for (int i = 0; i < 0x60000; i++) + RomData[i + 0x40000] = origRom[i]; + RomLength = RomData.Length; + } + else if (rom.Length > 1024 * 1024) + { + // If the rom is bigger than 1 megabyte, switch to Street Fighter 2 mapper + Cpu.ReadMemory21 = ReadMemorySF2; + Cpu.WriteMemory21 = WriteMemorySF2; + RomData = rom; + RomLength = RomData.Length; + } + else + { + // normal rom. + RomData = rom; + RomLength = RomData.Length; + } - if (game["SuperSysCard"]) - SuperRam = new byte[0x30000]; + if (game["BRAM"] || Type == NecSystemType.TurboCD) + { + BramEnabled = true; + BRAM = new byte[2048]; - if (game["ArcadeCard"]) - { - ArcadeRam = new byte[0x200000]; - ArcadeCard = true; - ArcadeCardRewindHack = game["ArcadeRewindHack"]; - for (int i=0; i<4; i++) - ArcadePage[i] = new ArcadeCardPage(); - } + // pre-format BRAM. damn are we helpful. + BRAM[0] = 0x48; BRAM[1] = 0x55; BRAM[2] = 0x42; BRAM[3] = 0x4D; + BRAM[4] = 0x00; BRAM[5] = 0x88; BRAM[6] = 0x10; BRAM[7] = 0x80; + } - if (game["PopulousSRAM"]) - { - PopulousRAM = new byte[0x8000]; - Cpu.ReadMemory21 = ReadMemoryPopulous; - Cpu.WriteMemory21 = WriteMemoryPopulous; - } + if (game["SuperSysCard"]) + SuperRam = new byte[0x30000]; - if (game["ForceSpriteLimit"] || game.NotInDatabase) - { - VDC1.PerformSpriteLimit = true; - if (VDC2 != null) - VDC2.PerformSpriteLimit = true; - } + if (game["ArcadeCard"]) + { + ArcadeRam = new byte[0x200000]; + ArcadeCard = true; + ArcadeCardRewindHack = game["ArcadeRewindHack"]; + for (int i = 0; i < 4; i++) + ArcadePage[i] = new ArcadeCardPage(); + } - if (game["CdVol"]) - CDAudio.MaxVolume = int.Parse(game.OptionValue("CdVol")); - if (game["PsgVol"]) - PSG.MaxVolume = int.Parse(game.OptionValue("PsgVol")); - if (game["AdpcmVol"]) - ADPCM.MaxVolume = int.Parse(game.OptionValue("AdpcmVol")); - if (game["EqualizeVolumes"] || (game.NotInDatabase && TurboCD)) - SoundMixer.EqualizeVolumes(); + if (game["PopulousSRAM"]) + { + PopulousRAM = new byte[0x8000]; + Cpu.ReadMemory21 = ReadMemoryPopulous; + Cpu.WriteMemory21 = WriteMemoryPopulous; + } - // Ok, yes, HBlankPeriod's only purpose is game-specific hax. - // 1) At least they're not coded directly into the emulator, but instead data-driven. - // 2) The games which have custom HBlankPeriods work without it, the override only - // serves to clean up minor gfx anomalies. - // 3) There's no point in haxing the timing with incorrect values in an attempt to avoid this. - // The proper fix is cycle-accurate/bus-accurate timing. That isn't coming to the C# - // version of this core. Let's just acknolwedge that the timing is imperfect and fix - // it in the least intrusive and most honest way we can. + if (game["ForceSpriteLimit"] || game.NotInDatabase) + { + VDC1.PerformSpriteLimit = true; + if (VDC2 != null) + VDC2.PerformSpriteLimit = true; + } - if (game["HBlankPeriod"]) - VDC1.HBlankCycles = int.Parse(game.OptionValue("HBlankPeriod")); + if (game["CdVol"]) + CDAudio.MaxVolume = int.Parse(game.OptionValue("CdVol")); + if (game["PsgVol"]) + PSG.MaxVolume = int.Parse(game.OptionValue("PsgVol")); + if (game["AdpcmVol"]) + ADPCM.MaxVolume = int.Parse(game.OptionValue("AdpcmVol")); + if (game["EqualizeVolumes"] || (game.NotInDatabase && TurboCD)) + SoundMixer.EqualizeVolumes(); - // This is also a hack. Proper multi-res/TV emulation will be a native-code core feature. - - if (game["MultiResHack"]) - { - VDC1.MultiResHack = int.Parse(game.OptionValue("MultiResHack")); - } + // Ok, yes, HBlankPeriod's only purpose is game-specific hax. + // 1) At least they're not coded directly into the emulator, but instead data-driven. + // 2) The games which have custom HBlankPeriods work without it, the override only + // serves to clean up minor gfx anomalies. + // 3) There's no point in haxing the timing with incorrect values in an attempt to avoid this. + // The proper fix is cycle-accurate/bus-accurate timing. That isn't coming to the C# + // version of this core. Let's just acknolwedge that the timing is imperfect and fix + // it in the least intrusive and most honest way we can. - Cpu.ResetPC(); - SetupMemoryDomains(); - } + if (game["HBlankPeriod"]) + VDC1.HBlankCycles = int.Parse(game.OptionValue("HBlankPeriod")); - int _lagcount = 0; - bool lagged = true; - bool islag = false; - public int Frame { get; set; } - public int LagCount { get { return _lagcount; } set { _lagcount = value; } } - public bool IsLagFrame { get { return islag; } } + // This is also a hack. Proper multi-res/TV emulation will be a native-code core feature. - public void ResetFrameCounter() - { - // this should just be a public setter instead of a new method. - Frame = 0; - } + if (game["MultiResHack"]) + { + VDC1.MultiResHack = int.Parse(game.OptionValue("MultiResHack")); + } - public void FrameAdvance(bool render) - { - lagged = true; - Controller.UpdateControls(Frame++); + Cpu.ResetPC(); + SetupMemoryDomains(); + } - PSG.BeginFrame(Cpu.TotalExecutedCycles); + int _lagcount = 0; + bool lagged = true; + bool islag = false; + public int Frame { get; set; } + public int LagCount { get { return _lagcount; } set { _lagcount = value; } } + public bool IsLagFrame { get { return islag; } } - if (SuperGrafx) - VPC.ExecFrame(render); - else - VDC1.ExecFrame(render); + public void ResetFrameCounter() + { + // this should just be a public setter instead of a new method. + Frame = 0; + } - PSG.EndFrame(Cpu.TotalExecutedCycles); - if (TurboCD) - SoundSynchronizer.PullSamples(SoundMixer); + public void FrameAdvance(bool render) + { + lagged = true; + Controller.UpdateControls(Frame++); - if (lagged) - { - _lagcount++; - islag = true; - } - else - islag = false; - } + PSG.BeginFrame(Cpu.TotalExecutedCycles); + + if (SuperGrafx) + VPC.ExecFrame(render); + else + VDC1.ExecFrame(render); + + PSG.EndFrame(Cpu.TotalExecutedCycles); + if (TurboCD) + SoundSynchronizer.PullSamples(SoundMixer); + + if (lagged) + { + _lagcount++; + islag = true; + } + else + islag = false; + } public CoreInputComm CoreInputComm { get; set; } public CoreOutputComm CoreOutputComm { get; private set; } - public IVideoProvider VideoProvider - { - get { return (IVideoProvider) VPC ?? VDC1; } - } + public IVideoProvider VideoProvider + { + get { return (IVideoProvider)VPC ?? VDC1; } + } - ISoundProvider soundProvider; - public ISoundProvider SoundProvider - { - get { return soundProvider; } - } - - public string SystemId { get { return "PCE"; } } - public string Region { get; set; } - public bool DeterministicEmulation { get; set; } + ISoundProvider soundProvider; + public ISoundProvider SoundProvider + { + get { return soundProvider; } + } - public byte[] SaveRam - { - get { return BRAM; } - } + public string SystemId { get { return systemid; } } + public string Region { get; set; } + public bool DeterministicEmulation { get; set; } - public bool SaveRamModified { get; set; } + public byte[] SaveRam + { + get { return BRAM; } + } - public void SaveStateText(TextWriter writer) - { - writer.WriteLine("[PCEngine]"); - writer.Write("RAM "); - Ram.SaveAsHex(writer); - if (PopulousRAM != null) - { - writer.Write("PopulousRAM "); - PopulousRAM.SaveAsHex(writer); - } - writer.WriteLine("Frame {0}", Frame); - writer.WriteLine("Lag {0}", _lagcount); - if (Cpu.ReadMemory21 == ReadMemorySF2) - writer.WriteLine("SF2MapperLatch " + SF2MapperLatch); - writer.WriteLine("IOBuffer {0:X2}", IOBuffer); - writer.Write("CdIoPorts "); CdIoPorts.SaveAsHex(writer); - writer.WriteLine(); + public bool SaveRamModified { get; set; } - if (SuperGrafx) - { - Cpu.SaveStateText(writer); - VPC.SaveStateText(writer); - VCE.SaveStateText(writer); - VDC1.SaveStateText(writer, 1); - VDC2.SaveStateText(writer, 2); - PSG.SaveStateText(writer); - } - else - { - Cpu.SaveStateText(writer); - VCE.SaveStateText(writer); - VDC1.SaveStateText(writer, 1); - PSG.SaveStateText(writer); - } - if (TurboCD) - { - writer.Write("CDRAM "); CDRam.SaveAsHex(writer); - if (SuperRam != null) - { writer.Write("SuperRAM "); SuperRam.SaveAsHex(writer); } + public void SaveStateText(TextWriter writer) + { + writer.WriteLine("[PCEngine]"); + writer.Write("RAM "); + Ram.SaveAsHex(writer); + if (PopulousRAM != null) + { + writer.Write("PopulousRAM "); + PopulousRAM.SaveAsHex(writer); + } + writer.WriteLine("Frame {0}", Frame); + writer.WriteLine("Lag {0}", _lagcount); + if (Cpu.ReadMemory21 == ReadMemorySF2) + writer.WriteLine("SF2MapperLatch " + SF2MapperLatch); + writer.WriteLine("IOBuffer {0:X2}", IOBuffer); + writer.Write("CdIoPorts "); CdIoPorts.SaveAsHex(writer); + writer.WriteLine(); - writer.WriteLine(); - SCSI.SaveStateText(writer); - CDAudio.SaveStateText(writer); - ADPCM.SaveStateText(writer); - } - if (ArcadeCard) - SaveArcadeCardText(writer); + if (SuperGrafx) + { + Cpu.SaveStateText(writer); + VPC.SaveStateText(writer); + VCE.SaveStateText(writer); + VDC1.SaveStateText(writer, 1); + VDC2.SaveStateText(writer, 2); + PSG.SaveStateText(writer); + } + else + { + Cpu.SaveStateText(writer); + VCE.SaveStateText(writer); + VDC1.SaveStateText(writer, 1); + PSG.SaveStateText(writer); + } + if (TurboCD) + { + writer.Write("CDRAM "); CDRam.SaveAsHex(writer); + if (SuperRam != null) + { writer.Write("SuperRAM "); SuperRam.SaveAsHex(writer); } - writer.WriteLine("[/PCEngine]"); - } + writer.WriteLine(); + SCSI.SaveStateText(writer); + CDAudio.SaveStateText(writer); + ADPCM.SaveStateText(writer); + } + if (ArcadeCard) + SaveArcadeCardText(writer); - public void LoadStateText(TextReader reader) - { - while (true) - { - string[] args = reader.ReadLine().Split(' '); - if (args[0].Trim() == "") continue; - if (args[0] == "[PCEngine]") continue; - if (args[0] == "[/PCEngine]") break; - if (args[0] == "Frame") - Frame = int.Parse(args[1]); - else if (args[0] == "Lag") - _lagcount = int.Parse(args[1]); - else if (args[0] == "SF2MapperLatch") - SF2MapperLatch = byte.Parse(args[1]); - else if (args[0] == "IOBuffer") - IOBuffer = byte.Parse(args[1], NumberStyles.HexNumber); - else if (args[0] == "CdIoPorts") - CdIoPorts.ReadFromHex(args[1]); - else if (args[0] == "RAM") - Ram.ReadFromHex(args[1]); - else if (args[0] == "CDRAM") - CDRam.ReadFromHex(args[1]); - else if (args[0] == "SuperRAM") - SuperRam.ReadFromHex(args[1]); - else if (args[0] == "PopulousRAM" && PopulousRAM != null) - PopulousRAM.ReadFromHex(args[1]); - else if (args[0] == "[HuC6280]") - Cpu.LoadStateText(reader); - else if (args[0] == "[PSG]") - PSG.LoadStateText(reader); - else if (args[0] == "[VCE]") - VCE.LoadStateText(reader); - else if (args[0] == "[VPC]") - VPC.LoadStateText(reader); - else if (args[0] == "[VDC1]") - VDC1.LoadStateText(reader, 1); - else if (args[0] == "[VDC2]") - VDC2.LoadStateText(reader, 2); - else if (args[0] == "[SCSI]") - SCSI.LoadStateText(reader); - else if (args[0] == "[CDAudio]") - CDAudio.LoadStateText(reader); - else if (args[0] == "[ADPCM]") - ADPCM.LoadStateText(reader); - else if (args[0] == "[ArcadeCard]") - LoadArcadeCardText(reader); - else - Console.WriteLine("Skipping unrecognized identifier " + args[0]); - } - } + writer.WriteLine("[/PCEngine]"); + } - public void SaveStateBinary(BinaryWriter writer) - { - if (SuperGrafx == false) - { - writer.Write(Ram); - writer.Write(CdIoPorts); - RefreshIRQ2(); - if (BRAM != null) - writer.Write(BRAM); - if (PopulousRAM != null) - writer.Write(PopulousRAM); - if (SuperRam != null) - writer.Write(SuperRam); - if (TurboCD) - { - writer.Write(CDRam); - ADPCM.SaveStateBinary(writer); - CDAudio.SaveStateBinary(writer); - SCSI.SaveStateBinary(writer); - } - if (ArcadeCard) - SaveArcadeCardBinary(writer); - writer.Write(Frame); - writer.Write(_lagcount); - writer.Write(SF2MapperLatch); - writer.Write(IOBuffer); - Cpu.SaveStateBinary(writer); - VCE.SaveStateBinary(writer); - VDC1.SaveStateBinary(writer); - PSG.SaveStateBinary(writer); - } else { - writer.Write(Ram); - writer.Write(Frame); - writer.Write(_lagcount); - writer.Write(IOBuffer); - Cpu.SaveStateBinary(writer); - VCE.SaveStateBinary(writer); - VPC.SaveStateBinary(writer); - VDC1.SaveStateBinary(writer); - VDC2.SaveStateBinary(writer); - PSG.SaveStateBinary(writer); - } - } + public void LoadStateText(TextReader reader) + { + while (true) + { + string[] args = reader.ReadLine().Split(' '); + if (args[0].Trim() == "") continue; + if (args[0] == "[PCEngine]") continue; + if (args[0] == "[/PCEngine]") break; + if (args[0] == "Frame") + Frame = int.Parse(args[1]); + else if (args[0] == "Lag") + _lagcount = int.Parse(args[1]); + else if (args[0] == "SF2MapperLatch") + SF2MapperLatch = byte.Parse(args[1]); + else if (args[0] == "IOBuffer") + IOBuffer = byte.Parse(args[1], NumberStyles.HexNumber); + else if (args[0] == "CdIoPorts") + CdIoPorts.ReadFromHex(args[1]); + else if (args[0] == "RAM") + Ram.ReadFromHex(args[1]); + else if (args[0] == "CDRAM") + CDRam.ReadFromHex(args[1]); + else if (args[0] == "SuperRAM") + SuperRam.ReadFromHex(args[1]); + else if (args[0] == "PopulousRAM" && PopulousRAM != null) + PopulousRAM.ReadFromHex(args[1]); + else if (args[0] == "[HuC6280]") + Cpu.LoadStateText(reader); + else if (args[0] == "[PSG]") + PSG.LoadStateText(reader); + else if (args[0] == "[VCE]") + VCE.LoadStateText(reader); + else if (args[0] == "[VPC]") + VPC.LoadStateText(reader); + else if (args[0] == "[VDC1]") + VDC1.LoadStateText(reader, 1); + else if (args[0] == "[VDC2]") + VDC2.LoadStateText(reader, 2); + else if (args[0] == "[SCSI]") + SCSI.LoadStateText(reader); + else if (args[0] == "[CDAudio]") + CDAudio.LoadStateText(reader); + else if (args[0] == "[ADPCM]") + ADPCM.LoadStateText(reader); + else if (args[0] == "[ArcadeCard]") + LoadArcadeCardText(reader); + else + Console.WriteLine("Skipping unrecognized identifier " + args[0]); + } + } - public void LoadStateBinary(BinaryReader reader) - { - if (SuperGrafx == false) - { - Ram = reader.ReadBytes(0x2000); - CdIoPorts = reader.ReadBytes(16); - if (BRAM != null) - BRAM = reader.ReadBytes(0x800); - if (PopulousRAM != null) - PopulousRAM = reader.ReadBytes(0x8000); - if (SuperRam != null) - SuperRam = reader.ReadBytes(0x30000); - if (TurboCD) - { - CDRam = reader.ReadBytes(0x10000); - ADPCM.LoadStateBinary(reader); - CDAudio.LoadStateBinary(reader); - SCSI.LoadStateBinary(reader); - } - if (ArcadeCard) - LoadArcadeCardBinary(reader); - Frame = reader.ReadInt32(); - _lagcount = reader.ReadInt32(); - SF2MapperLatch = reader.ReadByte(); - IOBuffer = reader.ReadByte(); - Cpu.LoadStateBinary(reader); - VCE.LoadStateBinary(reader); - VDC1.LoadStateBinary(reader); - PSG.LoadStateBinary(reader); - } else { - Ram = reader.ReadBytes(0x8000); - Frame = reader.ReadInt32(); - _lagcount = reader.ReadInt32(); - IOBuffer = reader.ReadByte(); - Cpu.LoadStateBinary(reader); - VCE.LoadStateBinary(reader); - VPC.LoadStateBinary(reader); - VDC1.LoadStateBinary(reader); - VDC2.LoadStateBinary(reader); - PSG.LoadStateBinary(reader); - } - } + public void SaveStateBinary(BinaryWriter writer) + { + if (SuperGrafx == false) + { + writer.Write(Ram); + writer.Write(CdIoPorts); + RefreshIRQ2(); + if (BRAM != null) + writer.Write(BRAM); + if (PopulousRAM != null) + writer.Write(PopulousRAM); + if (SuperRam != null) + writer.Write(SuperRam); + if (TurboCD) + { + writer.Write(CDRam); + ADPCM.SaveStateBinary(writer); + CDAudio.SaveStateBinary(writer); + SCSI.SaveStateBinary(writer); + } + if (ArcadeCard) + SaveArcadeCardBinary(writer); + writer.Write(Frame); + writer.Write(_lagcount); + writer.Write(SF2MapperLatch); + writer.Write(IOBuffer); + Cpu.SaveStateBinary(writer); + VCE.SaveStateBinary(writer); + VDC1.SaveStateBinary(writer); + PSG.SaveStateBinary(writer); + } + else + { + writer.Write(Ram); + writer.Write(Frame); + writer.Write(_lagcount); + writer.Write(IOBuffer); + Cpu.SaveStateBinary(writer); + VCE.SaveStateBinary(writer); + VPC.SaveStateBinary(writer); + VDC1.SaveStateBinary(writer); + VDC2.SaveStateBinary(writer); + PSG.SaveStateBinary(writer); + } + } - public byte[] SaveStateBinary() - { - int buflen = 75887; - if (SuperGrafx) buflen += 90698; - if (BramEnabled) buflen += 2048; - if (PopulousRAM != null) buflen += 0x8000; - if (SuperRam != null) buflen += 0x30000; - if (TurboCD) buflen += 0x20000 + 2165; - if (ArcadeCard) buflen += 42; - if (ArcadeCard && !ArcadeCardRewindHack) buflen += 0x200000; - //Console.WriteLine("LENGTH1 " + buflen); + public void LoadStateBinary(BinaryReader reader) + { + if (SuperGrafx == false) + { + Ram = reader.ReadBytes(0x2000); + CdIoPorts = reader.ReadBytes(16); + if (BRAM != null) + BRAM = reader.ReadBytes(0x800); + if (PopulousRAM != null) + PopulousRAM = reader.ReadBytes(0x8000); + if (SuperRam != null) + SuperRam = reader.ReadBytes(0x30000); + if (TurboCD) + { + CDRam = reader.ReadBytes(0x10000); + ADPCM.LoadStateBinary(reader); + CDAudio.LoadStateBinary(reader); + SCSI.LoadStateBinary(reader); + } + if (ArcadeCard) + LoadArcadeCardBinary(reader); + Frame = reader.ReadInt32(); + _lagcount = reader.ReadInt32(); + SF2MapperLatch = reader.ReadByte(); + IOBuffer = reader.ReadByte(); + Cpu.LoadStateBinary(reader); + VCE.LoadStateBinary(reader); + VDC1.LoadStateBinary(reader); + PSG.LoadStateBinary(reader); + } + else + { + Ram = reader.ReadBytes(0x8000); + Frame = reader.ReadInt32(); + _lagcount = reader.ReadInt32(); + IOBuffer = reader.ReadByte(); + Cpu.LoadStateBinary(reader); + VCE.LoadStateBinary(reader); + VPC.LoadStateBinary(reader); + VDC1.LoadStateBinary(reader); + VDC2.LoadStateBinary(reader); + PSG.LoadStateBinary(reader); + } + } - var buf = new byte[buflen]; - var stream = new MemoryStream(buf); - var writer = new BinaryWriter(stream); - SaveStateBinary(writer); - //Console.WriteLine("LENGTH2 " + stream.Position); - writer.Close(); - return buf; - } + public byte[] SaveStateBinary() + { + int buflen = 75887; + if (SuperGrafx) buflen += 90698; + if (BramEnabled) buflen += 2048; + if (PopulousRAM != null) buflen += 0x8000; + if (SuperRam != null) buflen += 0x30000; + if (TurboCD) buflen += 0x20000 + 2165; + if (ArcadeCard) buflen += 42; + if (ArcadeCard && !ArcadeCardRewindHack) buflen += 0x200000; + //Console.WriteLine("LENGTH1 " + buflen); - void SetupMemoryDomains() - { - var domains = new List(10); - var MainMemoryDomain = new MemoryDomain("Main Memory", Ram.Length, Endian.Little, - addr => Ram[addr & 0x1FFF], - (addr, value) => Ram[addr & 0x1FFF] = value); - domains.Add(MainMemoryDomain); + var buf = new byte[buflen]; + var stream = new MemoryStream(buf); + var writer = new BinaryWriter(stream); + SaveStateBinary(writer); + //Console.WriteLine("LENGTH2 " + stream.Position); + writer.Close(); + return buf; + } - var SystemBusDomain = new MemoryDomain("System Bus", 0x2F0000, Endian.Little, - addr => Cpu.ReadMemory21(addr), - (addr, value) => Cpu.WriteMemory21(addr, value)); - domains.Add(SystemBusDomain); + void SetupMemoryDomains() + { + var domains = new List(10); + var MainMemoryDomain = new MemoryDomain("Main Memory", Ram.Length, Endian.Little, + addr => Ram[addr & 0x1FFF], + (addr, value) => Ram[addr & 0x1FFF] = value); + domains.Add(MainMemoryDomain); - if (BRAM != null) - { - var BRAMMemoryDomain = new MemoryDomain("Battery RAM", Ram.Length, Endian.Little, - addr => BRAM[addr & 0x7FF], - (addr, value) => BRAM[addr & 0x7FF] = value); - domains.Add(BRAMMemoryDomain); - } + var SystemBusDomain = new MemoryDomain("System Bus", 0x2F0000, Endian.Little, + addr => Cpu.ReadMemory21(addr), + (addr, value) => Cpu.WriteMemory21(addr, value)); + domains.Add(SystemBusDomain); - if (TurboCD) - { - var CDRamMemoryDomain = new MemoryDomain("TurboCD RAM", CDRam.Length, Endian.Little, - addr => CDRam[addr & 0xFFFF], - (addr, value) => CDRam[addr & 0xFFFF] = value); - domains.Add(CDRamMemoryDomain); + if (BRAM != null) + { + var BRAMMemoryDomain = new MemoryDomain("Battery RAM", Ram.Length, Endian.Little, + addr => BRAM[addr & 0x7FF], + (addr, value) => BRAM[addr & 0x7FF] = value); + domains.Add(BRAMMemoryDomain); + } - var AdpcmMemoryDomain = new MemoryDomain("ADPCM RAM", ADPCM.RAM.Length, Endian.Little, - addr => ADPCM.RAM[addr & 0xFFFF], - (addr, value) => ADPCM.RAM[addr & 0xFFFF] = value); - domains.Add(AdpcmMemoryDomain); - - if (SuperRam != null) - { - var SuperRamMemoryDomain = new MemoryDomain("Super System Card RAM", SuperRam.Length, Endian.Little, - addr => SuperRam[addr & 0x3FFFF], - (addr, value) => SuperRam[addr & 0x3FFFF] = value); - domains.Add(SuperRamMemoryDomain); - } - } + if (TurboCD) + { + var CDRamMemoryDomain = new MemoryDomain("TurboCD RAM", CDRam.Length, Endian.Little, + addr => CDRam[addr & 0xFFFF], + (addr, value) => CDRam[addr & 0xFFFF] = value); + domains.Add(CDRamMemoryDomain); - if (ArcadeCard) - { - var ArcadeRamMemoryDomain = new MemoryDomain("Aracde Card RAM", ArcadeRam.Length, Endian.Little, - addr => ArcadeRam[addr & 0x1FFFFF], - (addr, value) => ArcadeRam[addr & 0x1FFFFF] = value); - domains.Add(ArcadeRamMemoryDomain); - } + var AdpcmMemoryDomain = new MemoryDomain("ADPCM RAM", ADPCM.RAM.Length, Endian.Little, + addr => ADPCM.RAM[addr & 0xFFFF], + (addr, value) => ADPCM.RAM[addr & 0xFFFF] = value); + domains.Add(AdpcmMemoryDomain); - memoryDomains = domains.AsReadOnly(); - } + if (SuperRam != null) + { + var SuperRamMemoryDomain = new MemoryDomain("Super System Card RAM", SuperRam.Length, Endian.Little, + addr => SuperRam[addr & 0x3FFFF], + (addr, value) => SuperRam[addr & 0x3FFFF] = value); + domains.Add(SuperRamMemoryDomain); + } + } - IList memoryDomains; - public IList MemoryDomains { get { return memoryDomains; } } - public MemoryDomain MainMemory { get { return memoryDomains[0]; } } + if (ArcadeCard) + { + var ArcadeRamMemoryDomain = new MemoryDomain("Aracde Card RAM", ArcadeRam.Length, Endian.Little, + addr => ArcadeRam[addr & 0x1FFFFF], + (addr, value) => ArcadeRam[addr & 0x1FFFFF] = value); + domains.Add(ArcadeRamMemoryDomain); + } - public void Dispose() - { - if (disc != null) - disc.Dispose(); - } - } + memoryDomains = domains.AsReadOnly(); + } + + IList memoryDomains; + public IList MemoryDomains { get { return memoryDomains; } } + public MemoryDomain MainMemory { get { return memoryDomains[0]; } } + + public void Dispose() + { + if (disc != null) + disc.Dispose(); + } + } } diff --git a/BizHawk.MultiClient/LogWindow.Designer.cs b/BizHawk.MultiClient/LogWindow.Designer.cs index 4585185504..ebe7011ff3 100644 --- a/BizHawk.MultiClient/LogWindow.Designer.cs +++ b/BizHawk.MultiClient/LogWindow.Designer.cs @@ -37,6 +37,7 @@ // // btnClose // + this.btnClose.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.btnClose.Location = new System.Drawing.Point(453, 3); this.btnClose.Name = "btnClose"; this.btnClose.Size = new System.Drawing.Size(75, 23); @@ -90,6 +91,7 @@ // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.btnClose; this.ClientSize = new System.Drawing.Size(531, 302); this.Controls.Add(this.textBox1); this.Controls.Add(this.tableLayoutPanel1); diff --git a/BizHawk.MultiClient/MainForm.cs b/BizHawk.MultiClient/MainForm.cs index 4da15df27f..57bd8fe190 100644 --- a/BizHawk.MultiClient/MainForm.cs +++ b/BizHawk.MultiClient/MainForm.cs @@ -796,12 +796,12 @@ namespace BizHawk.MultiClient private string DisplayNameForSystem(string system) { string str = ""; - if (INTERIM) str += "(interim) "; switch (system) { case "SG": str += "SG-1000"; break; case "SMS": str += "Sega Master System"; break; case "GG": str += "Game Gear"; break; + case "PCECD": str += "TurboGrafx-16 (CD)"; break; case "PCE": str += "TurboGrafx-16"; break; case "SGX": str += "SuperGrafx"; break; case "GEN": str += "Genesis"; break; @@ -809,6 +809,7 @@ namespace BizHawk.MultiClient case "NES": str += "NES"; break; case "GB": str += "Game Boy"; break; } + if (INTERIM) str += " (interim)"; return str; } @@ -858,6 +859,7 @@ namespace BizHawk.MultiClient Global.AutoFireController = Global.AutofireSMSControls; break; case "PCE": + case "PCECD": Global.ActiveController = Global.PCEControls; Global.AutoFireController = Global.AutofirePCEControls; break; @@ -975,7 +977,7 @@ namespace BizHawk.MultiClient // what system the game is for. game = new GameInfo(); - game.System = "PCE"; + game.System = "PCECD"; game.Name = Path.GetFileNameWithoutExtension(file.Name); game.Hash = hash; } @@ -983,6 +985,7 @@ namespace BizHawk.MultiClient switch (game.System) { case "PCE": + case "PCECD": if (File.Exists(Global.Config.PathPCEBios) == false) { MessageBox.Show("PCE-CD System Card not found. Please check the BIOS path in Config->Paths->PC Engine."); @@ -1034,6 +1037,7 @@ namespace BizHawk.MultiClient nextEmulator = new SMS(game, rom.RomData); break; case "PCE": + case "PCECD": case "SGX": if (Global.Config.PceSpriteLimit) game.AddOption("ForceSpriteLimit"); nextEmulator = new PCEngine(game, rom.RomData); diff --git a/BizHawk.MultiClient/config/PathManager.cs b/BizHawk.MultiClient/config/PathManager.cs index 7db70651d8..fc9d13b53b 100644 --- a/BizHawk.MultiClient/config/PathManager.cs +++ b/BizHawk.MultiClient/config/PathManager.cs @@ -80,6 +80,7 @@ namespace BizHawk.MultiClient return Global.Config.BaseSMS; case "SGX": case "PCE": + case "PCECD": return Global.Config.BasePCE; case "TI83": return Global.Config.BaseTI83; @@ -245,6 +246,7 @@ namespace BizHawk.MultiClient break; case "SFX": case "PCE": + case "PCECD": path = PathManager.MakeAbsolutePath(Global.Config.PathPCEROMs, "PCE"); break; case "GB": @@ -292,6 +294,7 @@ namespace BizHawk.MultiClient case "SG": return Path.Combine(MakeAbsolutePath(Global.Config.PathSGSaveRAM, "SG"), name + ".SaveRAM"); case "SGX": return Path.Combine(MakeAbsolutePath(Global.Config.PathPCESaveRAM, "PCE"), name + ".SaveRAM"); case "PCE": return Path.Combine(MakeAbsolutePath(Global.Config.PathPCESaveRAM, "PCE"), name + ".SaveRAM"); + case "PCECD": return Path.Combine(MakeAbsolutePath(Global.Config.PathPCESaveRAM, "PCE"), name + ".SaveRAM"); case "GB": return Path.Combine(MakeAbsolutePath(Global.Config.PathGBSaveRAM, "GB"), name + ".SaveRAM"); case "GEN": return Path.Combine(MakeAbsolutePath(Global.Config.PathGenesisSaveRAM, "GEN"), name + ".SaveRAM"); case "NES": return Path.Combine(MakeAbsolutePath(Global.Config.PathNESSaveRAM, "NES"), name + ".SaveRAM"); @@ -312,6 +315,7 @@ namespace BizHawk.MultiClient case "SG": return Path.Combine(MakeAbsolutePath(Global.Config.PathSGSavestates, "SG"), name); case "SGX": return Path.Combine(MakeAbsolutePath(Global.Config.PathPCESavestates, "PCE"), name); case "PCE": return Path.Combine(MakeAbsolutePath(Global.Config.PathPCESavestates, "PCE"), name); + case "PCECD": return Path.Combine(MakeAbsolutePath(Global.Config.PathPCESavestates, "PCE"), name); case "GB": return Path.Combine(MakeAbsolutePath(Global.Config.PathGBSavestates, "GB"), name); case "GEN": return Path.Combine(MakeAbsolutePath(Global.Config.PathGenesisSavestates, "GEN"), name); case "NES": return Path.Combine(MakeAbsolutePath(Global.Config.PathNESSavestates, "NES"), name); @@ -330,6 +334,7 @@ namespace BizHawk.MultiClient case "SG": return Path.Combine(MakeAbsolutePath(Global.Config.PathSGScreenshots, "SG"), name); case "SGX": return Path.Combine(MakeAbsolutePath(Global.Config.PathPCEScreenshots, "PCE"), name); case "PCE": return Path.Combine(MakeAbsolutePath(Global.Config.PathPCEScreenshots, "PCE"), name); + case "PCECD": return Path.Combine(MakeAbsolutePath(Global.Config.PathPCEScreenshots, "PCE"), name); case "GB": return Path.Combine(MakeAbsolutePath(Global.Config.PathGBScreenshots, "GB"), name); case "GEN": return Path.Combine(MakeAbsolutePath(Global.Config.PathGenesisScreenshots, "GEN"), name); case "NES": return Path.Combine(MakeAbsolutePath(Global.Config.PathNESScreenshots, "NES"), name); diff --git a/BizHawk.MultiClient/movie/Movie.cs b/BizHawk.MultiClient/movie/Movie.cs index 1591e3faaf..5a299dc47a 100644 --- a/BizHawk.MultiClient/movie/Movie.cs +++ b/BizHawk.MultiClient/movie/Movie.cs @@ -521,6 +521,7 @@ namespace BizHawk.MultiClient else return frames / NES_NTSC; case "PCE": + case "PCECD": return frames / PCE; //One Day!