From 23c07cdb678fc3b782140b32a1ee54e3b05e798a Mon Sep 17 00:00:00 2001 From: Asnivor Date: Mon, 5 Mar 2018 13:29:34 +0000 Subject: [PATCH] OSD message handling implementation --- BizHawk.Client.Common/RomLoader.cs | 11 +- .../BizHawk.Emulation.Cores.csproj | 1 + .../Hardware/Datacorder/DatacorderDevice.cs | 5 + .../Machine/SpectrumBase.Input.cs | 57 ++++- .../Machine/SpectrumBase.Media.cs | 3 + .../SinclairSpectrum/ZXSpectrum.ISettable.cs | 21 ++ .../SinclairSpectrum/ZXSpectrum.Messaging.cs | 197 ++++++++++++++++++ .../Computers/SinclairSpectrum/ZXSpectrum.cs | 6 +- 8 files changed, 291 insertions(+), 10 deletions(-) create mode 100644 BizHawk.Emulation.Cores/Computers/SinclairSpectrum/ZXSpectrum.Messaging.cs diff --git a/BizHawk.Client.Common/RomLoader.cs b/BizHawk.Client.Common/RomLoader.cs index 3bc0b7059a..39ae27262e 100644 --- a/BizHawk.Client.Common/RomLoader.cs +++ b/BizHawk.Client.Common/RomLoader.cs @@ -659,10 +659,17 @@ namespace BizHawk.Client.Common (C64.C64SyncSettings)GetCoreSyncSettings()); break; case "ZXSpectrum": + + List zxGI = new List(); + foreach (var a in xmlGame.Assets) + { + zxGI.Add(new GameInfo { Name = Path.GetFileNameWithoutExtension(a.Key) }); + } + nextEmulator = new ZXSpectrum( nextComm, xmlGame.Assets.Select(a => a.Value), //.First(), - GameInfo.NullInstance, + zxGI, // GameInfo.NullInstance, (ZXSpectrum.ZXSpectrumSettings)GetCoreSettings(), (ZXSpectrum.ZXSpectrumSyncSettings)GetCoreSyncSettings()); break; @@ -1000,7 +1007,7 @@ namespace BizHawk.Client.Common nextEmulator = c64; break; case "ZXSpectrum": - var zx = new ZXSpectrum(nextComm, Enumerable.Repeat(rom.RomData, 1), rom.GameInfo, GetCoreSettings(), GetCoreSyncSettings()); + var zx = new ZXSpectrum(nextComm, Enumerable.Repeat(rom.RomData, 1), Enumerable.Repeat(rom.GameInfo, 1).ToList(), GetCoreSettings(), GetCoreSyncSettings()); nextEmulator = zx; break; case "GBA": diff --git a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj index 6149403b27..d85d488b0a 100644 --- a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj +++ b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj @@ -296,6 +296,7 @@ + diff --git a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Datacorder/DatacorderDevice.cs b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Datacorder/DatacorderDevice.cs index be24dffbc9..eb37c02cf4 100644 --- a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Datacorder/DatacorderDevice.cs +++ b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Datacorder/DatacorderDevice.cs @@ -133,6 +133,8 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum if (_tapeIsPlaying) return; + _machine.Spectrum.OSD_TapePlaying(); + // update the lastCycle _lastCycle = _cpu.TotalExecutedCycles; @@ -183,6 +185,8 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum if (!_tapeIsPlaying) return; + _machine.Spectrum.OSD_TapeStopped(); + // sign that the tape is no longer playing _tapeIsPlaying = false; @@ -224,6 +228,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum public void RTZ() { Stop(); + _machine.Spectrum.OSD_TapeRTZ(); _currentDataBlockIndex = 0; } diff --git a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/SpectrumBase.Input.cs b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/SpectrumBase.Input.cs index 8a4837ac9f..97bd1c0e5f 100644 --- a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/SpectrumBase.Input.cs +++ b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/SpectrumBase.Input.cs @@ -13,6 +13,12 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum string NextTape = "Insert Next Tape"; string PrevTape = "Insert Previous Tape"; + bool pressed_Play = false; + bool pressed_Stop = false; + bool pressed_RTZ = false; + bool pressed_NextTape = false; + bool pressed_PrevTape = false; + public void PollInput() { Spectrum.InputCallbacks.Call(); @@ -22,8 +28,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum // parse single keyboard matrix keys for (var i = 0; i < KeyboardDevice.KeyboardMatrix.Length; i++) { - - string key = KeyboardDevice.KeyboardMatrix[i]; bool prevState = KeyboardDevice.GetKeyStatus(key); bool currState = Spectrum._controller.IsPressed(key); @@ -57,28 +61,67 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum // Tape control if (Spectrum._controller.IsPressed(Play)) { - TapeDevice.Play(); + if (!pressed_Play) + { + Spectrum.OSD_FireInputMessage(Play); + TapeDevice.Play(); + pressed_Play = true; + } } + else + pressed_Play = false; + if (Spectrum._controller.IsPressed(Stop)) { - TapeDevice.Stop(); + if (!pressed_Stop) + { + Spectrum.OSD_FireInputMessage(Stop); + TapeDevice.Stop(); + pressed_Stop = true; + } } + else + pressed_Stop = false; + if (Spectrum._controller.IsPressed(RTZ)) { - TapeDevice.RTZ(); + if (!pressed_RTZ) + { + Spectrum.OSD_FireInputMessage(RTZ); + TapeDevice.RTZ(); + pressed_RTZ = true; + } } + else + pressed_RTZ = false; + if (Spectrum._controller.IsPressed(Record)) { } if (Spectrum._controller.IsPressed(NextTape)) { - TapeMediaIndex++; + if (!pressed_NextTape) + { + Spectrum.OSD_FireInputMessage(NextTape); + TapeMediaIndex++; + pressed_NextTape = true; + } } + else + pressed_NextTape = false; + if (Spectrum._controller.IsPressed(PrevTape)) { - TapeMediaIndex--; + if (!pressed_PrevTape) + { + Spectrum.OSD_FireInputMessage(PrevTape); + TapeMediaIndex--; + pressed_PrevTape = true; + } } + else + pressed_PrevTape = false; } } } diff --git a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/SpectrumBase.Media.cs b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/SpectrumBase.Media.cs index 3c60ad48df..aa1b943823 100644 --- a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/SpectrumBase.Media.cs +++ b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/SpectrumBase.Media.cs @@ -56,6 +56,8 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum // load the media into the tape device tapeMediaIndex = result; + // fire osd message + Spectrum.OSD_TapeInserted(); LoadTapeMedia(); } } @@ -103,6 +105,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum { mediaImages = files; LoadAllMedia(); + Spectrum.OSD_TapeInit(); } /// diff --git a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/ZXSpectrum.ISettable.cs b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/ZXSpectrum.ISettable.cs index df56bd1b5b..f964d6f43d 100644 --- a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/ZXSpectrum.ISettable.cs +++ b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/ZXSpectrum.ISettable.cs @@ -48,6 +48,11 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum [DefaultValue(true)] public bool StereoSound { get; set; } + [DisplayName("Core OSD Message Verbosity")] + [Description("Full: Display all GUI messages\nMedium: Display only emulator/device generated messages\nNone: Show no messages")] + [DefaultValue(OSDVerbosity.Medium)] + public OSDVerbosity OSDMessageVerbosity { get; set; } + public ZXSpectrumSettings Clone() { @@ -98,6 +103,22 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum } } + public enum OSDVerbosity + { + /// + /// Show all OSD messages + /// + Full, + /// + /// Only show machine/device generated messages + /// + Medium, + /// + /// No core-driven OSD messages + /// + None + } + /// /// The size of the Spectrum border /// diff --git a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/ZXSpectrum.Messaging.cs b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/ZXSpectrum.Messaging.cs new file mode 100644 index 0000000000..2d83819f95 --- /dev/null +++ b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/ZXSpectrum.Messaging.cs @@ -0,0 +1,197 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum +{ + /// + /// Handles all messaging (OSD) operations + /// + public partial class ZXSpectrum + { + /// + /// Writes a message to the OSD + /// + /// + /// + public void SendMessage(string message, MessageCategory category) + { + if (!CheckMessageSettings(category)) + return; + + StringBuilder sb = new StringBuilder(); + + switch (category) + { + case MessageCategory.Tape: + sb.Append("DATACORDER: "); + sb.Append(message); + break; + case MessageCategory.Input: + sb.Append("INPUT DETECTED: "); + sb.Append(message); + break; + case MessageCategory.Disk: + sb.Append("DISK DRIVE: "); + sb.Append(message); + break; + case MessageCategory.Emulator: + case MessageCategory.Misc: + sb.Append("ZXHAWK: "); + sb.Append(message); + break; + } + + CoreComm.Notify(sb.ToString()); + } + + #region Input Message Methods + + /// + /// Called when certain input presses are detected + /// + /// + public void OSD_FireInputMessage(string input) + { + StringBuilder sb = new StringBuilder(); + sb.Append(input); + SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Input); + } + + #endregion + + #region TapeDevice Message Methods + + /// + /// Tape message that is fired on core init + /// + public void OSD_TapeInit() + { + StringBuilder sb = new StringBuilder(); + sb.Append("Tape Media Imported (count: " + _gameInfo.Count() + ")"); + sb.Append("\n"); + for (int i = 0; i < _gameInfo.Count(); i++) + sb.Append(i.ToString() + ": " + _gameInfo[i].Name + "\n"); + + SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Emulator); + } + + /// + /// Tape message that is fired when tape is playing + /// + public void OSD_TapePlaying() + { + StringBuilder sb = new StringBuilder(); + sb.Append("PLAYING (" + _machine.TapeMediaIndex + ": " + _gameInfo[_machine.TapeMediaIndex].Name + ")"); + + SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape); + } + + /// + /// Tape message that is fired when tape is stopped + /// + public void OSD_TapeStopped() + { + StringBuilder sb = new StringBuilder(); + sb.Append("STOPPED (" + _machine.TapeMediaIndex + ": " + _gameInfo[_machine.TapeMediaIndex].Name + ")"); + + SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape); + } + + /// + /// Tape message that is fired when tape is rewound + /// + public void OSD_TapeRTZ() + { + StringBuilder sb = new StringBuilder(); + sb.Append("REWOUND (" + _machine.TapeMediaIndex + ": " + _gameInfo[_machine.TapeMediaIndex].Name + ")"); + + SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape); + } + + /// + /// Tape message that is fired when a new tape is inserted into the datacorder + /// + public void OSD_TapeInserted() + { + StringBuilder sb = new StringBuilder(); + sb.Append("TAPE INSERTED (" + _machine.TapeMediaIndex + ": " + _gameInfo[_machine.TapeMediaIndex].Name + ")"); + + SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape); + } + + + /// + /// Tape message that is fired when a tape is stopped automatically + /// + public void OSD_TapeStoppedAuto() + { + StringBuilder sb = new StringBuilder(); + sb.Append("STOPPED (Auto Tape Trap) (" + _machine.TapeMediaIndex + ": " + _gameInfo[_machine.TapeMediaIndex].Name + ")"); + + SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape); + } + + #endregion + + + + /// + /// Checks whether message category is allowed to be sent + /// + /// + /// + public bool CheckMessageSettings(MessageCategory category) + { + switch (Settings.OSDMessageVerbosity) + { + case OSDVerbosity.Full: + return true; + case OSDVerbosity.None: + return false; + case OSDVerbosity.Medium: + switch (category) + { + case MessageCategory.Disk: + case MessageCategory.Emulator: + case MessageCategory.Tape: + case MessageCategory.Misc: + return true; + default: + return false; + } + default: + return true; + } + } + + /// + /// Defines the different message categories + /// + public enum MessageCategory + { + /// + /// No defined category as such + /// + Misc, + /// + /// User generated input messages (at the moment only tape/disk controls) + /// + Input, + /// + /// Tape device generated messages + /// + Tape, + /// + /// Disk device generated messages + /// + Disk, + /// + /// Emulator generated messages + /// + Emulator + } + } +} diff --git a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/ZXSpectrum.cs b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/ZXSpectrum.cs index 4c1a1be8d4..df56791f0c 100644 --- a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/ZXSpectrum.cs +++ b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/ZXSpectrum.cs @@ -19,7 +19,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum public partial class ZXSpectrum : IDebuggable, IInputPollable, IStatable, IRegionable { [CoreConstructor("ZXSpectrum")] - public ZXSpectrum(CoreComm comm, IEnumerable files, GameInfo game, object settings, object syncSettings) + public ZXSpectrum(CoreComm comm, IEnumerable files, List game, object settings, object syncSettings) { PutSyncSettings((ZXSpectrumSyncSettings)syncSettings ?? new ZXSpectrumSyncSettings()); PutSettings((ZXSpectrumSettings)settings ?? new ZXSpectrumSettings()); @@ -30,6 +30,8 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum CoreComm = comm; + _gameInfo = game; + _cpu = new Z80A(); _tracer = new TraceBuffer { Header = _cpu.TraceHeader }; @@ -101,6 +103,8 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum public IController _controller; private SpectrumBase _machine; + private List _gameInfo; + private SoundProviderMixer SoundMixer; private DCFilter dcf;