BizHawk/BizHawk.Client.EmuHawk/tools/TraceLogger.cs

409 lines
9.7 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using BizHawk.Client.Common;
namespace BizHawk.Client.EmuHawk
{
2013-11-02 21:31:04 +00:00
public partial class TraceLogger : Form, IToolForm
{
// Refresh rate slider
// Make faster, such as not saving to disk until the logging is stopped, dont' add to Instructions list every frame, etc
private readonly List<string> _instructions = new List<string>();
private FileInfo _logFile;
private int _defaultWidth;
private int _defaultHeight;
2013-11-02 21:31:04 +00:00
public TraceLogger()
{
InitializeComponent();
TraceView.QueryItemText += TraceView_QueryItemText;
TraceView.VirtualMode = true;
2012-09-30 03:49:53 +00:00
2014-01-30 03:34:58 +00:00
TopMost = Global.Config.TraceLoggerSettings.TopMost;
Closing += (o, e) => SaveConfigSettings();
}
public bool UpdateBefore
{
get { return false; }
}
public bool AskSave()
{
return true;
}
private void SaveConfigSettings()
{
Global.CoreComm.Tracer.Enabled = false;
2014-01-30 03:34:58 +00:00
Global.Config.TraceLoggerSettings.Wndx = Location.X;
Global.Config.TraceLoggerSettings.Wndy = Location.Y;
Global.Config.TraceLoggerSettings.Width = Size.Width;
Global.Config.TraceLoggerSettings.Height = Size.Height;
}
2012-09-30 03:09:41 +00:00
private void TraceView_QueryItemText(int index, int column, out string text)
{
2014-01-30 03:34:58 +00:00
text = index < _instructions.Count ? _instructions[index] : string.Empty;
}
private void TraceLogger_Load(object sender, EventArgs e)
{
_defaultWidth = Size.Width;
_defaultHeight = Size.Height;
2014-01-30 03:34:58 +00:00
if (Global.Config.TraceLoggerSettings.UseWindowPosition)
{
Location = Global.Config.TraceLoggerSettings.WindowPosition;
}
if (Global.Config.TraceLoggerSettings.UseWindowSize)
{
Size = Global.Config.TraceLoggerSettings.WindowSize;
}
ClearList();
LoggingEnabled.Checked = true;
2013-10-27 16:26:37 +00:00
Global.CoreComm.Tracer.Enabled = true;
SetTracerBoxTitle();
Restart();
}
public void UpdateValues()
{
TraceView.BlazingFast = !GlobalWin.MainForm.EmulatorPaused;
if (ToWindowRadio.Checked)
{
LogToWindow();
}
else
{
LogToFile();
}
}
public void Restart()
{
if (!IsHandleCreated || IsDisposed)
{
return;
}
else
{
if (Global.Emulator.CoreComm.CpuTraceAvailable)
{
ClearList();
TraceView.Columns[0].Text = Global.Emulator.CoreComm.TraceHeader;
}
else
{
Close();
}
}
}
private void ClearList()
{
_instructions.Clear();
TraceView.ItemCount = 0;
SetTracerBoxTitle();
}
private void LogToFile()
{
using (var sw = new StreamWriter(_logFile.FullName, true))
{
2013-10-27 16:26:37 +00:00
sw.Write(Global.CoreComm.Tracer.TakeContents());
}
}
private void LogToWindow()
{
var instructions = Global.CoreComm.Tracer.TakeContents().Split('\n');
2014-01-30 03:34:58 +00:00
if (!string.IsNullOrWhiteSpace(instructions[0]))
{
_instructions.AddRange(instructions);
}
if (_instructions.Count >= Global.Config.TraceLoggerMaxLines)
{
2014-01-30 03:34:58 +00:00
_instructions.RemoveRange(0, _instructions.Count - Global.Config.TraceLoggerMaxLines);
}
TraceView.ItemCount = _instructions.Count;
}
private Point GetPromptPoint()
{
return PointToScreen(
new Point(TraceView.Location.X + 30, TraceView.Location.Y + 30)
);
}
private void SetTracerBoxTitle()
{
2013-10-27 16:26:37 +00:00
if (Global.CoreComm.Tracer.Enabled)
{
if (ToFileRadio.Checked)
{
TracerBox.Text = "Trace log - logging to file...";
}
else if (_instructions.Any())
{
TracerBox.Text = "Trace log - logging - " + _instructions.Count + " instructions";
}
else
{
TracerBox.Text = "Trace log - logging...";
}
}
else
{
if (_instructions.Any())
{
TracerBox.Text = "Trace log - " + _instructions.Count + " instructions";
}
else
{
TracerBox.Text = "Trace log";
}
}
}
private void CloseFile()
{
// TODO: save the remaining instructions in CoreComm
}
private FileInfo GetFileFromUser()
{
var sfd = new SaveFileDialog();
if (_logFile == null)
{
sfd.FileName = PathManager.FilesystemSafeName(Global.Game) + ".txt";
sfd.InitialDirectory = PathManager.MakeAbsolutePath(Global.Config.PathEntries.LogPathFragment, null);
}
2014-01-30 03:34:58 +00:00
else if (!string.IsNullOrWhiteSpace(_logFile.FullName))
{
sfd.FileName = PathManager.FilesystemSafeName(Global.Game);
sfd.InitialDirectory = Path.GetDirectoryName(_logFile.FullName);
}
else
{
sfd.FileName = Path.GetFileNameWithoutExtension(_logFile.FullName);
sfd.InitialDirectory = PathManager.MakeAbsolutePath(Global.Config.PathEntries.LogPathFragment, null);
}
sfd.Filter = "Text Files (*.txt)|*.txt|Log Files (*.log)|*.log|All Files|*.*";
sfd.RestoreDirectory = true;
var result = sfd.ShowHawkDialog();
if (result == DialogResult.OK)
{
return new FileInfo(sfd.FileName);
}
else
{
return null;
}
}
private void DumpListToDisk(FileSystemInfo file)
{
using (var sw = new StreamWriter(file.FullName))
{
foreach (var instruction in _instructions)
{
sw.WriteLine(instruction);
}
}
}
2014-01-30 03:34:58 +00:00
private void RefreshFloatingWindowControl()
{
Owner = Global.Config.TraceLoggerSettings.FloatingWindow ? null : GlobalWin.MainForm;
}
#region Events
#region Menu Items
private void SaveLogMenuItem_Click(object sender, EventArgs e)
{
var file = GetFileFromUser();
if (file != null)
{
DumpListToDisk(file);
GlobalWin.OSD.AddMessage("Log dumped to " + file.FullName);
}
}
private void ExitMenuItem_Click(object sender, EventArgs e)
{
Close();
}
private void CopyMenuItem_Click(object sender, EventArgs e)
{
var indices = TraceView.SelectedIndices;
if (indices.Count > 0)
{
var blob = new StringBuilder();
foreach (int index in indices)
{
blob.AppendLine(_instructions[index]);
}
blob.Remove(blob.Length - 2, 2); // Lazy way to not have a line break at the end
Clipboard.SetDataObject(blob.ToString());
}
}
2012-11-28 18:59:56 +00:00
private void SelectAllMenuItem_Click(object sender, EventArgs e)
{
for (var i = 0; i < _instructions.Count; i++)
{
TraceView.SelectItem(i, true);
}
}
private void MaxLinesMenuItem_Click(object sender, EventArgs e)
{
var prompt = new InputPrompt();
prompt.SetMessage("Max lines to display in the window");
prompt.SetInitialValue(Global.Config.TraceLoggerMaxLines.ToString());
prompt.TextInputType = InputPrompt.InputType.UNSIGNED;
prompt._Location = GetPromptPoint();
prompt.ShowDialog();
if (prompt.UserOK)
{
var max = int.Parse(prompt.UserText);
if (max > 0)
{
Global.Config.TraceLoggerMaxLines = max;
}
}
}
private void OptionsSubMenu_DropDownOpened(object sender, EventArgs e)
{
AutoloadMenuItem.Checked = Global.Config.TraceLoggerAutoLoad;
2014-01-30 03:34:58 +00:00
SaveWindowPositionMenuItem.Checked = Global.Config.TraceLoggerSettings.SaveWindowPosition;
AlwaysOnTopMenuItem.Checked = Global.Config.TraceLoggerSettings.TopMost;
FloatingWindowMenuItem.Checked = Global.Config.TraceLoggerSettings.FloatingWindow;
}
private void AutoloadMenuItem_Click(object sender, EventArgs e)
{
Global.Config.TraceLoggerAutoLoad ^= true;
}
private void SaveWindowPositionMenuItem_Click(object sender, EventArgs e)
2012-11-28 18:59:56 +00:00
{
2014-01-30 03:34:58 +00:00
Global.Config.TraceLoggerSettings.SaveWindowPosition ^= true;
2012-11-28 18:59:56 +00:00
}
private void AlwaysOnTopMenuItem_Click(object sender, EventArgs e)
2012-11-28 18:59:56 +00:00
{
2014-01-30 03:34:58 +00:00
Global.Config.TraceLoggerSettings.TopMost ^= true;
TopMost = Global.Config.TraceLoggerSettings.TopMost;
}
private void FloatingWindowMenuItem_Click(object sender, EventArgs e)
{
Global.Config.TraceLoggerSettings.FloatingWindow ^= true;
RefreshFloatingWindowControl();
}
private void RestoreDefaultSettingsMenuItem_Click(object sender, EventArgs e)
{
Size = new Size(_defaultWidth, _defaultHeight);
Global.Config.TraceLoggerSettings.SaveWindowPosition = true;
Global.Config.TraceLoggerSettings.TopMost = false;
Global.Config.TraceLoggerSettings.FloatingWindow = false;
RefreshFloatingWindowControl();
}
#endregion
#region Dialog and ListView Events
private void LoggingEnabled_CheckedChanged(object sender, EventArgs e)
{
Global.CoreComm.Tracer.Enabled = LoggingEnabled.Checked;
SetTracerBoxTitle();
}
private void ClearButton_Click(object sender, EventArgs e)
{
ClearList();
}
private void BrowseBox_Click(object sender, EventArgs e)
{
var file = GetFileFromUser();
if (file != null)
{
_logFile = file;
FileBox.Text = _logFile.FullName;
}
2012-11-28 18:59:56 +00:00
}
private void ToFileRadio_CheckedChanged(object sender, EventArgs e)
2012-11-28 18:59:56 +00:00
{
if (ToFileRadio.Checked)
{
FileBox.Visible = true;
BrowseBox.Visible = true;
var name = PathManager.FilesystemSafeName(Global.Game);
var filename = Path.Combine(PathManager.MakeAbsolutePath(Global.Config.PathEntries.LogPathFragment, null), name) + ".txt";
_logFile = new FileInfo(filename);
if (_logFile.Directory != null && !_logFile.Directory.Exists)
{
_logFile.Directory.Create();
}
if (_logFile.Exists)
{
_logFile.Delete();
_logFile.Create();
}
else
{
_logFile.Create();
}
FileBox.Text = _logFile.FullName;
}
else
{
CloseFile();
FileBox.Visible = false;
BrowseBox.Visible = false;
}
SetTracerBoxTitle();
2012-11-28 18:59:56 +00:00
}
2014-01-30 03:34:58 +00:00
protected override void OnShown(EventArgs e)
{
RefreshFloatingWindowControl();
base.OnShown(e);
}
#endregion
#endregion
}
}