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 Detected)"); SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape); } /// /// Tape message that is fired when a tape is started automatically /// public void OSD_TapePlayingAuto() { StringBuilder sb = new StringBuilder(); sb.Append("PLAYING (Auto Tape Trap Detected)"); SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape); } /// /// Tape message that is fired when a new block starts playing /// public void OSD_TapePlayingBlockInfo(string blockinfo) { StringBuilder sb = new StringBuilder(); sb.Append("...Starting Block "+ blockinfo); SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape); } /// /// Tape message that is fired when a tape block is skipped (because it is empty) /// public void OSD_TapePlayingSkipBlockInfo(string blockinfo) { StringBuilder sb = new StringBuilder(); sb.Append("...Skipping Empty Block " + blockinfo); SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape); } /// /// Tape message that is fired when a tape is started automatically /// public void OSD_TapeEndDetected(string blockinfo) { StringBuilder sb = new StringBuilder(); sb.Append("...Skipping Empty Block " + blockinfo); SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape); } /// /// Tape message that is fired when user has manually skipped to the next block /// public void OSD_TapeNextBlock(string blockinfo) { StringBuilder sb = new StringBuilder(); sb.Append("Manual Skip Next " + blockinfo); SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape); } /// /// Tape message that is fired when user has manually skipped to the next block /// public void OSD_TapePrevBlock(string blockinfo) { StringBuilder sb = new StringBuilder(); sb.Append("Manual Skip Prev " + blockinfo); SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape); } /// /// Tape message that prints the current status of the tape device /// public void OSD_ShowTapeStatus() { StringBuilder sb = new StringBuilder(); sb.Append("Status: "); if (_machine.TapeDevice.TapeIsPlaying) sb.Append("PLAYING"); else sb.Append("STOPPED"); SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape); sb.Clear(); sb.Append("Tape: " + _machine.TapeMediaIndex + ": " + _gameInfo[_machine.TapeMediaIndex].Name); SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape); sb.Clear(); sb.Append("Block: "); sb.Append("(" + (_machine.TapeDevice.CurrentDataBlockIndex + 1) + " of " + _machine.TapeDevice.DataBlocks.Count() + ") " + _machine.TapeDevice.DataBlocks[_machine.TapeDevice.CurrentDataBlockIndex].BlockDescription); SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape); sb.Clear(); sb.Append("Block Pos: "); int pos = _machine.TapeDevice.Position; int end = _machine.TapeDevice.DataBlocks[_machine.TapeDevice.CurrentDataBlockIndex].DataPeriods.Count; double p = 0; if (end != 0) p = ((double)pos / (double)end) * (double)100; sb.Append(p.ToString("N0") + "%"); SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape); sb.Clear(); } #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 } } }