From 52215061aa16ee107e2ebeba979c5fccb9048dfa Mon Sep 17 00:00:00 2001 From: "andres.delikat" Date: Mon, 27 Jun 2011 01:24:26 +0000 Subject: [PATCH] some implementations necessary for the gameboy controller --- BizHawk.Emulation/Consoles/Gameboy/Gameboy.cs | 49 +- BizHawk.Emulation/Consoles/Sega/SMS/SMS.cs | 638 +++++++++--------- BizHawk.MultiClient/Config.cs | 45 ++ BizHawk.MultiClient/Global.cs | 1 + .../Input/ControllerBinding.cs | 27 + BizHawk.MultiClient/MainForm.cs | 12 + 6 files changed, 442 insertions(+), 330 deletions(-) diff --git a/BizHawk.Emulation/Consoles/Gameboy/Gameboy.cs b/BizHawk.Emulation/Consoles/Gameboy/Gameboy.cs index b7f107d86d..a830a8fca4 100644 --- a/BizHawk.Emulation/Consoles/Gameboy/Gameboy.cs +++ b/BizHawk.Emulation/Consoles/Gameboy/Gameboy.cs @@ -6,6 +6,11 @@ namespace BizHawk.Emulation.Consoles.Gameboy { public partial class Gameboy : IEmulator { + + private int _lagcount = 0; + private bool lagged = true; + private bool islag = false; + public interface IDebuggerAPI { void DoEvents(); @@ -326,8 +331,28 @@ namespace BizHawk.Emulation.Consoles.Gameboy Registers = new TRegisters(this); Registers.LCDC.Poke(0x91); + SetupMemoryDomains(); } + private IList memoryDomains; + + private void SetupMemoryDomains() + { + //TODO: WRAM (0 & 1? or both?) + //TODO: VRAM + //TODO: OAM + //TODO: HRAM + var domains = new List(1); + var SystemBusDomain = new MemoryDomain("System Bus", 0x10000, Endian.Little, + addr => Cpu.ReadMemory((ushort)addr), + (addr, value) => Cpu.WriteMemory((ushort)addr, value)); + domains.Add(SystemBusDomain); + memoryDomains = domains.AsReadOnly(); + } + + public IList MemoryDomains { get { return memoryDomains; } } + public MemoryDomain MainMemory { get { return memoryDomains[0]; } } + public byte ReadMemoryBios(ushort addr) { //we speculate that the bios unmaps itself after the first read of 0x100 @@ -651,9 +676,18 @@ namespace BizHawk.Emulation.Consoles.Gameboy public void FrameAdvance(bool render) { + lagged = true; + Controller.UpdateControls(Frame++); Cpu.ExecuteCycles(4096); - } + if (lagged) + { + _lagcount++; + islag = true; + } + else + islag = false; + } public CoreInputComm CoreInputComm { get; set; } public CoreOutputComm CoreOutputComm { get; private set; } @@ -668,14 +702,10 @@ namespace BizHawk.Emulation.Consoles.Gameboy get { return new NullEmulator(); } } - public int Frame - { - get { return 0; } - //get { throw new NotImplementedException(); } - } + public int Frame { get; set; } - public int LagCount { get { return -1; } set { return; } } //TODO: implement - public bool IsLagFrame { get { return false; } } //TODO: implement + public int LagCount { get { return _lagcount; } set { _lagcount = value; } } + public bool IsLagFrame { get { return islag; } } public byte[] SaveRam { @@ -869,9 +899,6 @@ namespace BizHawk.Emulation.Consoles.Gameboy public bool DeterministicEmulation { get; set; } public string SystemId { get { return "GB"; } } - public IList MemoryDomains { get { throw new NotImplementedException(); } } - public MemoryDomain MainMemory { get { throw new NotImplementedException(); } } - public void Dispose() { } } } \ No newline at end of file diff --git a/BizHawk.Emulation/Consoles/Sega/SMS/SMS.cs b/BizHawk.Emulation/Consoles/Sega/SMS/SMS.cs index 1b9b7ccd51..ae5ae3c9ea 100644 --- a/BizHawk.Emulation/Consoles/Sega/SMS/SMS.cs +++ b/BizHawk.Emulation/Consoles/Sega/SMS/SMS.cs @@ -16,370 +16,370 @@ using BizHawk.Emulation.Sound; namespace BizHawk.Emulation.Consoles.Sega { - public sealed partial class SMS : IEmulator - { - // Constants - public const int BankSize = 16384; + public sealed partial class SMS : IEmulator + { + // Constants + public const int BankSize = 16384; - // ROM - public byte[] RomData; - public byte RomBank0, RomBank1, RomBank2; - public byte RomBanks; - public IList Options; + // ROM + public byte[] RomData; + public byte RomBank0, RomBank1, RomBank2; + public byte RomBanks; + public IList Options; - // SaveRAM - public byte[] SaveRAM = new byte[BankSize*2]; - public byte SaveRamBank; + // SaveRAM + public byte[] SaveRAM = new byte[BankSize * 2]; + public byte SaveRamBank; - public byte[] SaveRam { get { return SaveRAM; } } - public bool SaveRamModified { get; set; } + public byte[] SaveRam { get { return SaveRAM; } } + public bool SaveRamModified { get; set; } - // Machine resources - public Z80A Cpu; - public byte[] SystemRam; - public VDP Vdp; - public SN76489 PSG; - public YM2413 YM2413; - public SoundMixer SoundMixer; - public bool IsGameGear = false; - public bool HasYM2413 = false; + // Machine resources + public Z80A Cpu; + public byte[] SystemRam; + public VDP Vdp; + public SN76489 PSG; + public YM2413 YM2413; + public SoundMixer SoundMixer; + public bool IsGameGear = false; + public bool HasYM2413 = false; - private int _lagcount = 0; - private bool lagged = true; - private bool islag = false; - public int Frame { get; set; } - public int LagCount { get { return _lagcount; } set { _lagcount = value; } } - public bool IsLagFrame { get { return islag; } } - private byte Port01 = 0xFF; - private byte Port02 = 0xFF; - private byte Port3E = 0xAF; - private byte Port3F = 0xFF; + private int _lagcount = 0; + private bool lagged = true; + private bool islag = false; + public int Frame { get; set; } + public int LagCount { get { return _lagcount; } set { _lagcount = value; } } + public bool IsLagFrame { get { return islag; } } + private byte Port01 = 0xFF; + private byte Port02 = 0xFF; + private byte Port3E = 0xAF; + private byte Port3F = 0xFF; - public DisplayType DisplayType { get; set; } - public bool DeterministicEmulation { get; set; } + public DisplayType DisplayType { get; set; } + public bool DeterministicEmulation { get; set; } public SMS() { CoreOutputComm = new CoreOutputComm(); } - public void Init() - { - if (Controller == null) - Controller = NullController.GetNullController(); + public void Init() + { + if (Controller == null) + Controller = NullController.GetNullController(); - Cpu = new Z80A(); - Cpu.RegisterSP = 0xDFF0; - Cpu.ReadHardware = ReadPort; - Cpu.WriteHardware = WritePort; + Cpu = new Z80A(); + Cpu.RegisterSP = 0xDFF0; + Cpu.ReadHardware = ReadPort; + Cpu.WriteHardware = WritePort; - Vdp = new VDP(Cpu, IsGameGear ? VdpMode.GameGear : VdpMode.SMS, DisplayType); - PSG = new SN76489(); - YM2413 = new YM2413(); - SoundMixer = new SoundMixer(YM2413, PSG); - if (HasYM2413 && Options.Contains("WhenFMDisablePSG")) - SoundMixer.DisableSource(PSG); - ActiveSoundProvider = HasYM2413 ? (ISoundProvider) SoundMixer : PSG; + Vdp = new VDP(Cpu, IsGameGear ? VdpMode.GameGear : VdpMode.SMS, DisplayType); + PSG = new SN76489(); + YM2413 = new YM2413(); + SoundMixer = new SoundMixer(YM2413, PSG); + if (HasYM2413 && Options.Contains("WhenFMDisablePSG")) + SoundMixer.DisableSource(PSG); + ActiveSoundProvider = HasYM2413 ? (ISoundProvider)SoundMixer : PSG; - SystemRam = new byte[0x2000]; - if (Options.Contains("CMMapper") == false) - InitSegaMapper(); - else - InitCodeMastersMapper(); + SystemRam = new byte[0x2000]; + if (Options.Contains("CMMapper") == false) + InitSegaMapper(); + else + InitCodeMastersMapper(); - if (Options.Contains("ForceStereo")) - { - byte stereoByte = 0xAD; - if (Options.ContainsStartsWith("StereoByte")) - { - stereoByte = byte.Parse(Options.GetOptionValue("StereoByte")); - } - PSG.StereoPanning = stereoByte; - } + if (Options.Contains("ForceStereo")) + { + byte stereoByte = 0xAD; + if (Options.ContainsStartsWith("StereoByte")) + { + stereoByte = byte.Parse(Options.GetOptionValue("StereoByte")); + } + PSG.StereoPanning = stereoByte; + } - if (Options.Contains("AllowOverclock") && Options.Contains("OverclockSafe")) - Vdp.IPeriod = 512; + if (Options.Contains("AllowOverclock") && Options.Contains("OverclockSafe")) + Vdp.IPeriod = 512; - if (Options.Contains("BIOS")) - { - Port3E = 0xF7; // Disable cartridge, enable BIOS rom - InitBiosMapper(); - } - SetupMemoryDomains(); - } + if (Options.Contains("BIOS")) + { + Port3E = 0xF7; // Disable cartridge, enable BIOS rom + InitBiosMapper(); + } + SetupMemoryDomains(); + } - public void LoadGame(IGame game) - { - RomData = game.GetRomData(); - if (RomData.Length % BankSize != 0) - Array.Resize(ref RomData, ((RomData.Length/BankSize) + 1)*BankSize); - RomBanks = (byte)(RomData.Length/BankSize); - Options = game.GetOptions(); - DisplayType = DisplayType.NTSC; + public void LoadGame(IGame game) + { + RomData = game.GetRomData(); + if (RomData.Length % BankSize != 0) + Array.Resize(ref RomData, ((RomData.Length / BankSize) + 1) * BankSize); + RomBanks = (byte)(RomData.Length / BankSize); + Options = game.GetOptions(); + DisplayType = DisplayType.NTSC; CoreOutputComm.VsyncRate = DisplayType == DisplayType.NTSC ? 60d : 50d; - foreach (string option in Options) - { - var args = option.Split('='); - if (args[0] == "Japan") Region = "Japan"; - else if (args[0] == "PAL") DisplayType = DisplayType.PAL; - } + foreach (string option in Options) + { + var args = option.Split('='); + if (args[0] == "Japan") Region = "Japan"; + else if (args[0] == "PAL") DisplayType = DisplayType.PAL; + } - if (Options.Contains("NotInDatabase") || (Options.Contains("FM") && Options.Contains("UseFM"))) - HasYM2413 = true; + if (Options.Contains("NotInDatabase") || (Options.Contains("FM") && Options.Contains("UseFM"))) + HasYM2413 = true; - Init(); - } + Init(); + } - public byte ReadPort(ushort port) - { - switch (port & 0xFF) - { - case 0x00: return ReadPort0(); - case 0x01: return Port01; - case 0x02: return Port02; - case 0x03: return 0x00; - case 0x04: return 0xFF; - case 0x05: return 0x00; - case 0x06: return 0xFF; - case 0x3E: return Port3E; - case 0x7E: return Vdp.ReadVLineCounter(); - case 0x7F: break; // hline counter TODO - case 0xBE: return Vdp.ReadData(); - case 0xBF: return Vdp.ReadVdpStatus(); - case 0xC0: - case 0xDC: return ReadControls1(); - case 0xC1: - case 0xDD: return ReadControls2(); - case 0xF2: return HasYM2413 ? YM2413.DetectionValue : (byte) 0xFF; - } - return 0xFF; - } + public byte ReadPort(ushort port) + { + switch (port & 0xFF) + { + case 0x00: return ReadPort0(); + case 0x01: return Port01; + case 0x02: return Port02; + case 0x03: return 0x00; + case 0x04: return 0xFF; + case 0x05: return 0x00; + case 0x06: return 0xFF; + case 0x3E: return Port3E; + case 0x7E: return Vdp.ReadVLineCounter(); + case 0x7F: break; // hline counter TODO + case 0xBE: return Vdp.ReadData(); + case 0xBF: return Vdp.ReadVdpStatus(); + case 0xC0: + case 0xDC: return ReadControls1(); + case 0xC1: + case 0xDD: return ReadControls2(); + case 0xF2: return HasYM2413 ? YM2413.DetectionValue : (byte)0xFF; + } + return 0xFF; + } - public void WritePort(ushort port, byte value) - { - switch (port & 0xFF) - { - case 0x01: Port01 = value; break; - case 0x02: Port02 = value; break; - case 0x06: PSG.StereoPanning = value; break; - case 0x3E: Port3E = value; break; - case 0x3F: Port3F = value; break; - case 0x7E: - case 0x7F: PSG.WritePsgData(value, Cpu.TotalExecutedCycles); break; - case 0xBE: Vdp.WriteVdpData(value); break; - case 0xBD: - case 0xBF: Vdp.WriteVdpControl(value); break; - case 0xF0: if (HasYM2413) YM2413.RegisterLatch = value; break; - case 0xF1: if (HasYM2413) YM2413.Write(value); break; - case 0xF2: if (HasYM2413) YM2413.DetectionValue = value; break; - } - } + public void WritePort(ushort port, byte value) + { + switch (port & 0xFF) + { + case 0x01: Port01 = value; break; + case 0x02: Port02 = value; break; + case 0x06: PSG.StereoPanning = value; break; + case 0x3E: Port3E = value; break; + case 0x3F: Port3F = value; break; + case 0x7E: + case 0x7F: PSG.WritePsgData(value, Cpu.TotalExecutedCycles); break; + case 0xBE: Vdp.WriteVdpData(value); break; + case 0xBD: + case 0xBF: Vdp.WriteVdpControl(value); break; + case 0xF0: if (HasYM2413) YM2413.RegisterLatch = value; break; + case 0xF1: if (HasYM2413) YM2413.Write(value); break; + case 0xF2: if (HasYM2413) YM2413.DetectionValue = value; break; + } + } - public void FrameAdvance(bool render) - { - lagged = true; - Controller.UpdateControls(Frame++); - PSG.BeginFrame(Cpu.TotalExecutedCycles); + public void FrameAdvance(bool render) + { + lagged = true; + Controller.UpdateControls(Frame++); + PSG.BeginFrame(Cpu.TotalExecutedCycles); - if (IsGameGear == false) - Cpu.NonMaskableInterrupt = Controller["Pause"]; + if (IsGameGear == false) + Cpu.NonMaskableInterrupt = Controller["Pause"]; - Vdp.ExecFrame(render); - PSG.EndFrame(Cpu.TotalExecutedCycles); - if (lagged) - { - _lagcount++; - islag = true; - } - else - islag = false; - } + Vdp.ExecFrame(render); + PSG.EndFrame(Cpu.TotalExecutedCycles); + if (lagged) + { + _lagcount++; + islag = true; + } + else + islag = false; + } - public void SaveStateText(TextWriter writer) - { - writer.WriteLine("[SMS]\n"); - Cpu.SaveStateText(writer); - PSG.SaveStateText(writer); - Vdp.SaveStateText(writer); + public void SaveStateText(TextWriter writer) + { + writer.WriteLine("[SMS]\n"); + Cpu.SaveStateText(writer); + PSG.SaveStateText(writer); + Vdp.SaveStateText(writer); - writer.WriteLine("Frame {0}", Frame); - writer.WriteLine("Lag {0}", _lagcount); - writer.WriteLine("Bank0 {0}", RomBank0); - writer.WriteLine("Bank1 {0}", RomBank1); - writer.WriteLine("Bank2 {0}", RomBank2); - writer.Write("RAM "); - SystemRam.SaveAsHex(writer); - writer.WriteLine("Port01 {0:X2}", Port01); - writer.WriteLine("Port02 {0:X2}", Port02); - writer.WriteLine("Port3F {0:X2}", Port3F); - int SaveRamLen = Util.SaveRamBytesUsed(SaveRAM); - if (SaveRamLen > 0) - { - writer.Write("SaveRAM "); - SaveRAM.SaveAsHex(writer, SaveRamLen); - } - if (HasYM2413) - { - writer.Write("FMRegs " ); - YM2413.opll.reg.SaveAsHex(writer); - } - writer.WriteLine("[/SMS]"); - } + writer.WriteLine("Frame {0}", Frame); + writer.WriteLine("Lag {0}", _lagcount); + writer.WriteLine("Bank0 {0}", RomBank0); + writer.WriteLine("Bank1 {0}", RomBank1); + writer.WriteLine("Bank2 {0}", RomBank2); + writer.Write("RAM "); + SystemRam.SaveAsHex(writer); + writer.WriteLine("Port01 {0:X2}", Port01); + writer.WriteLine("Port02 {0:X2}", Port02); + writer.WriteLine("Port3F {0:X2}", Port3F); + int SaveRamLen = Util.SaveRamBytesUsed(SaveRAM); + if (SaveRamLen > 0) + { + writer.Write("SaveRAM "); + SaveRAM.SaveAsHex(writer, SaveRamLen); + } + if (HasYM2413) + { + writer.Write("FMRegs "); + YM2413.opll.reg.SaveAsHex(writer); + } + writer.WriteLine("[/SMS]"); + } - public void LoadStateText(TextReader reader) - { - while (true) - { - string[] args = reader.ReadLine().Split(' '); - if (args[0].Trim() == "") continue; - if (args[0] == "[SMS]") continue; - if (args[0] == "[/SMS]") break; - if (args[0] == "Bank0") - RomBank0 = byte.Parse(args[1]); - else if (args[0] == "Bank1") - RomBank1 = byte.Parse(args[1]); - else if (args[0] == "Bank2") - RomBank2 = byte.Parse(args[1]); - else if (args[0] == "Frame") - Frame = int.Parse(args[1]); - else if (args[0] == "Lag") - _lagcount = int.Parse(args[1]); - else if (args[0] == "RAM") - SystemRam.ReadFromHex(args[1]); - else if (args[0] == "SaveRAM") - { - for (int i = 0; i < SaveRAM.Length; i++) SaveRAM[i] = 0; - SaveRAM.ReadFromHex(args[1]); - } - else if (args[0] == "FMRegs") - { - byte[] regs = new byte[YM2413.opll.reg.Length]; - regs.ReadFromHex(args[1]); - for (byte i = 0; i < regs.Length; i++) - YM2413.Write(i, regs[i]); - } - else if (args[0] == "Port01") - Port01 = byte.Parse(args[1], NumberStyles.HexNumber); - else if (args[0] == "Port02") - Port02 = byte.Parse(args[1], NumberStyles.HexNumber); - else if (args[0] == "Port3F") - Port3F = byte.Parse(args[1], NumberStyles.HexNumber); - else if (args[0] == "[Z80]") - Cpu.LoadStateText(reader); - else if (args[0] == "[PSG]") - PSG.LoadStateText(reader); - else if (args[0] == "[VDP]") - Vdp.LoadStateText(reader); - else - Console.WriteLine("Skipping unrecognized identifier " + args[0]); - } - } + public void LoadStateText(TextReader reader) + { + while (true) + { + string[] args = reader.ReadLine().Split(' '); + if (args[0].Trim() == "") continue; + if (args[0] == "[SMS]") continue; + if (args[0] == "[/SMS]") break; + if (args[0] == "Bank0") + RomBank0 = byte.Parse(args[1]); + else if (args[0] == "Bank1") + RomBank1 = byte.Parse(args[1]); + else if (args[0] == "Bank2") + RomBank2 = byte.Parse(args[1]); + else if (args[0] == "Frame") + Frame = int.Parse(args[1]); + else if (args[0] == "Lag") + _lagcount = int.Parse(args[1]); + else if (args[0] == "RAM") + SystemRam.ReadFromHex(args[1]); + else if (args[0] == "SaveRAM") + { + for (int i = 0; i < SaveRAM.Length; i++) SaveRAM[i] = 0; + SaveRAM.ReadFromHex(args[1]); + } + else if (args[0] == "FMRegs") + { + byte[] regs = new byte[YM2413.opll.reg.Length]; + regs.ReadFromHex(args[1]); + for (byte i = 0; i < regs.Length; i++) + YM2413.Write(i, regs[i]); + } + else if (args[0] == "Port01") + Port01 = byte.Parse(args[1], NumberStyles.HexNumber); + else if (args[0] == "Port02") + Port02 = byte.Parse(args[1], NumberStyles.HexNumber); + else if (args[0] == "Port3F") + Port3F = byte.Parse(args[1], NumberStyles.HexNumber); + else if (args[0] == "[Z80]") + Cpu.LoadStateText(reader); + else if (args[0] == "[PSG]") + PSG.LoadStateText(reader); + else if (args[0] == "[VDP]") + Vdp.LoadStateText(reader); + else + Console.WriteLine("Skipping unrecognized identifier " + args[0]); + } + } - public byte[] SaveStateBinary() - { - var buf = new byte[24802 + 16384 + 16384]; - var stream = new MemoryStream(buf); - var writer = new BinaryWriter(stream); - SaveStateBinary(writer); - writer.Close(); - return buf; - } + public byte[] SaveStateBinary() + { + var buf = new byte[24802 + 16384 + 16384]; + var stream = new MemoryStream(buf); + var writer = new BinaryWriter(stream); + SaveStateBinary(writer); + writer.Close(); + return buf; + } - public void SaveStateBinary(BinaryWriter writer) - { - Cpu.SaveStateBinary(writer); - PSG.SaveStateBinary(writer); - Vdp.SaveStateBinary(writer); + public void SaveStateBinary(BinaryWriter writer) + { + Cpu.SaveStateBinary(writer); + PSG.SaveStateBinary(writer); + Vdp.SaveStateBinary(writer); - writer.Write(Frame); - writer.Write(_lagcount); - writer.Write(RomBank0); - writer.Write(RomBank1); - writer.Write(RomBank2); - writer.Write(SystemRam); - writer.Write(SaveRAM); - writer.Write(Port01); - writer.Write(Port02); - writer.Write(Port3F); - writer.Write(YM2413.opll.reg); - } + writer.Write(Frame); + writer.Write(_lagcount); + writer.Write(RomBank0); + writer.Write(RomBank1); + writer.Write(RomBank2); + writer.Write(SystemRam); + writer.Write(SaveRAM); + writer.Write(Port01); + writer.Write(Port02); + writer.Write(Port3F); + writer.Write(YM2413.opll.reg); + } - public void LoadStateBinary(BinaryReader reader) - { - Cpu.LoadStateBinary(reader); - PSG.LoadStateBinary(reader); - Vdp.LoadStateBinary(reader); + public void LoadStateBinary(BinaryReader reader) + { + Cpu.LoadStateBinary(reader); + PSG.LoadStateBinary(reader); + Vdp.LoadStateBinary(reader); - Frame = reader.ReadInt32(); - _lagcount = reader.ReadInt32(); - RomBank0 = reader.ReadByte(); - RomBank1 = reader.ReadByte(); - RomBank2 = reader.ReadByte(); - SystemRam = reader.ReadBytes(SystemRam.Length); - reader.Read(SaveRAM, 0, SaveRAM.Length); - Port01 = reader.ReadByte(); - Port02 = reader.ReadByte(); - Port3F = reader.ReadByte(); - if (HasYM2413) - { - byte[] regs = new byte[YM2413.opll.reg.Length]; - reader.Read(regs, 0, regs.Length); - for (byte i = 0; i < regs.Length; i++) - YM2413.Write(i, regs[i]); - } - } + Frame = reader.ReadInt32(); + _lagcount = reader.ReadInt32(); + RomBank0 = reader.ReadByte(); + RomBank1 = reader.ReadByte(); + RomBank2 = reader.ReadByte(); + SystemRam = reader.ReadBytes(SystemRam.Length); + reader.Read(SaveRAM, 0, SaveRAM.Length); + Port01 = reader.ReadByte(); + Port02 = reader.ReadByte(); + Port3F = reader.ReadByte(); + if (HasYM2413) + { + byte[] regs = new byte[YM2413.opll.reg.Length]; + reader.Read(regs, 0, regs.Length); + for (byte i = 0; i < regs.Length; i++) + YM2413.Write(i, regs[i]); + } + } - public IVideoProvider VideoProvider { get { return Vdp; } } + public IVideoProvider VideoProvider { get { return Vdp; } } public CoreInputComm CoreInputComm { get; set; } public CoreOutputComm CoreOutputComm { get; private set; } - private ISoundProvider ActiveSoundProvider; - public ISoundProvider SoundProvider { get { return ActiveSoundProvider; } } + private ISoundProvider ActiveSoundProvider; + public ISoundProvider SoundProvider { get { return ActiveSoundProvider; } } - public string SystemId { get { return "SMS"; } } + public string SystemId { get { return "SMS"; } } - private string region = "Export"; - public string Region - { - get { return region; } - set - { - if (value.NotIn(validRegions)) - throw new Exception("Passed value "+value+" is not a valid region!"); - region = value; - } - } + private string region = "Export"; + public string Region + { + get { return region; } + set + { + if (value.NotIn(validRegions)) + throw new Exception("Passed value " + value + " is not a valid region!"); + region = value; + } + } - private readonly string[] validRegions = {"Export", "Japan"}; + private readonly string[] validRegions = { "Export", "Japan" }; - private IList memoryDomains; + private IList memoryDomains; - private void SetupMemoryDomains() - { - var domains = new List(3); - var MainMemoryDomain = new MemoryDomain("Main RAM", SystemRam.Length, Endian.Little, - addr => SystemRam[addr & RamSizeMask], - (addr, value) => SystemRam[addr & RamSizeMask] = value); - var VRamDomain = new MemoryDomain("Video RAM", Vdp.VRAM.Length, Endian.Little, - addr => Vdp.VRAM[addr & 0x3FFF], - (addr, value) => Vdp.VRAM[addr & 0x3FFF] = value); - var SaveRamDomain = new MemoryDomain("Save RAM", SaveRAM.Length, Endian.Little, - addr => SaveRAM[addr%SaveRAM.Length], - (addr, value) => { SaveRAM[addr%SaveRAM.Length]=value; SaveRamModified=true;}); - var SystemBusDomain = new MemoryDomain("System Bus", 0x10000, Endian.Little, - addr => Cpu.ReadMemory((ushort)addr), - (addr, value) => Cpu.WriteMemory((ushort)addr, value)); + private void SetupMemoryDomains() + { + var domains = new List(3); + var MainMemoryDomain = new MemoryDomain("Main RAM", SystemRam.Length, Endian.Little, + addr => SystemRam[addr & RamSizeMask], + (addr, value) => SystemRam[addr & RamSizeMask] = value); + var VRamDomain = new MemoryDomain("Video RAM", Vdp.VRAM.Length, Endian.Little, + addr => Vdp.VRAM[addr & 0x3FFF], + (addr, value) => Vdp.VRAM[addr & 0x3FFF] = value); + var SaveRamDomain = new MemoryDomain("Save RAM", SaveRAM.Length, Endian.Little, + addr => SaveRAM[addr % SaveRAM.Length], + (addr, value) => { SaveRAM[addr % SaveRAM.Length] = value; SaveRamModified = true; }); + var SystemBusDomain = new MemoryDomain("System Bus", 0x10000, Endian.Little, + addr => Cpu.ReadMemory((ushort)addr), + (addr, value) => Cpu.WriteMemory((ushort)addr, value)); - domains.Add(MainMemoryDomain); - domains.Add(VRamDomain); - domains.Add(SaveRamDomain); - domains.Add(SystemBusDomain); - memoryDomains = domains.AsReadOnly(); - } + domains.Add(MainMemoryDomain); + domains.Add(VRamDomain); + domains.Add(SaveRamDomain); + domains.Add(SystemBusDomain); + memoryDomains = domains.AsReadOnly(); + } - public IList MemoryDomains { get { return memoryDomains; } } - public MemoryDomain MainMemory { get { return memoryDomains[0]; } } + public IList MemoryDomains { get { return memoryDomains; } } + public MemoryDomain MainMemory { get { return memoryDomains[0]; } } - public void Dispose() {} - } + public void Dispose() { } + } } \ No newline at end of file diff --git a/BizHawk.MultiClient/Config.cs b/BizHawk.MultiClient/Config.cs index f908f7bdb9..854a216f39 100644 --- a/BizHawk.MultiClient/Config.cs +++ b/BizHawk.MultiClient/Config.cs @@ -15,6 +15,7 @@ NESController[1] = new NESControllerTemplate(false); NESController[2] = new NESControllerTemplate(false); NESController[3] = new NESControllerTemplate(false); + GameBoyController = new NESControllerTemplate(true); TI83Controller[0] = new TI83ControllerTemplate(true); } @@ -390,6 +391,9 @@ //TI 83 settings public TI83ControllerTemplate[] TI83Controller = new TI83ControllerTemplate[1]; + + //GB settings + public GBControllerTemplate GBController = new GBControllerTemplate(); } public class SMSControllerTemplate @@ -509,6 +513,47 @@ } } + public class GBControllerTemplate + { + public string Up; + public string Down; + public string Left; + public string Right; + public string A; + public string B; + public string Start; + public string Select; + public bool Enabled; + public GBControllerTemplate() { } + public GBControllerTemplate(bool defaults) + { + if (defaults) + { + Enabled = true; + Up = "J1 Up, UpArrow"; + Down = "J1 Down, DownArrow"; + Left = "J1 Left, LeftArrow"; + Right = "J1 Right, RightArrow"; + A = "J1 B2, X"; + B = "J1 B1, Z"; + Start = "J1 B8, Return"; + Select = "J1 B7, Space"; + } + else + { + Enabled = false; + Up = ""; + Down = ""; + Right = ""; + Left = ""; + A = ""; + B = ""; + Start = ""; + Select = ""; + } + } + } + public class TI83ControllerTemplate { public string _0; diff --git a/BizHawk.MultiClient/Global.cs b/BizHawk.MultiClient/Global.cs index 345fe83d77..b962850a74 100644 --- a/BizHawk.MultiClient/Global.cs +++ b/BizHawk.MultiClient/Global.cs @@ -20,6 +20,7 @@ namespace BizHawk.MultiClient public static Controller GenControls; public static Controller TI83Controls; public static Controller NESControls; + public static Controller GBControls; public static Controller ActiveController; public static Controller NullControls; } diff --git a/BizHawk.MultiClient/Input/ControllerBinding.cs b/BizHawk.MultiClient/Input/ControllerBinding.cs index e39ed045ff..489a44413c 100644 --- a/BizHawk.MultiClient/Input/ControllerBinding.cs +++ b/BizHawk.MultiClient/Input/ControllerBinding.cs @@ -200,6 +200,19 @@ namespace BizHawk.MultiClient return input.ToString(); } + if (type.Name == "Gameboy Controller") + { + input.Append("|"); + input.Append(IsPressed("Right") ? "R" : "."); + input.Append(IsPressed("Left") ? "L" : "."); + input.Append(IsPressed("Down") ? "D" : "."); + input.Append(IsPressed("Up") ? "U" : "."); + input.Append(IsPressed("Start") ? "S" : "."); + input.Append(IsPressed("Select") ? "s" : "."); + input.Append(IsPressed("B") ? "B" : "."); + input.Append(IsPressed("A") ? "A" : "."); + } + if (type.Name == "NES Controls") { input.Append(IsPressed("Reset") ? "r" : "."); @@ -376,6 +389,20 @@ namespace BizHawk.MultiClient if (mnemonic[19] != '.') programmaticallyPressedButtons.Add("P2 A"); } + if (type.Name == "Gameboy Controller") + { + if (mnemonic.Length < 10) return; + //if (mnemonic[1] != '.' && mnemonic[1] != '0') programmaticallyPressedButtons.Add("Reset"); + if (mnemonic[3] != '.') programmaticallyPressedButtons.Add("P1 Right"); + if (mnemonic[4] != '.') programmaticallyPressedButtons.Add("P1 Left"); + if (mnemonic[5] != '.') programmaticallyPressedButtons.Add("P1 Down"); + if (mnemonic[6] != '.') programmaticallyPressedButtons.Add("P1 Up"); + if (mnemonic[7] != '.') programmaticallyPressedButtons.Add("P1 Start"); + if (mnemonic[8] != '.') programmaticallyPressedButtons.Add("P1 Select"); + if (mnemonic[9] != '.') programmaticallyPressedButtons.Add("P1 B"); + if (mnemonic[10] != '.') programmaticallyPressedButtons.Add("P1 A"); + } + if (type.Name == "TI83 Controls") { if (mnemonic.Length < 50) return; diff --git a/BizHawk.MultiClient/MainForm.cs b/BizHawk.MultiClient/MainForm.cs index 3ef2866d74..8caa2ca2cf 100644 --- a/BizHawk.MultiClient/MainForm.cs +++ b/BizHawk.MultiClient/MainForm.cs @@ -509,6 +509,18 @@ namespace BizHawk.MultiClient } Global.NESControls = nesControls; + var gbControls = new Controller(Gameboy.GbController); + gbControls.BindMulti("Up", Global.Config.GBController.Up); + gbControls.BindMulti("Down", Global.Config.GBController.Down); + gbControls.BindMulti("Left", Global.Config.GBController.Left); + gbControls.BindMulti("Right", Global.Config.GBController.Right); + gbControls.BindMulti("A", Global.Config.GBController.A); + gbControls.BindMulti("B", Global.Config.GBController.B); + gbControls.BindMulti("Select", Global.Config.GBController.Select); + gbControls.BindMulti("Start", Global.Config.GBController.Start); + Global.GBControls = gbControls; + + var genControls = new Controller(Genesis.GenesisController); genControls.BindMulti("P1 Up", Global.Config.GenP1Up); genControls.BindMulti("P1 Left", Global.Config.GenP1Left);