2012-09-30 00:53:08 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.ComponentModel;
|
|
|
|
|
using System.Data;
|
|
|
|
|
using System.Drawing;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Windows.Forms;
|
2012-09-30 14:52:36 +00:00
|
|
|
|
using System.IO;
|
2012-09-30 00:53:08 +00:00
|
|
|
|
|
|
|
|
|
namespace BizHawk.MultiClient
|
|
|
|
|
{
|
|
|
|
|
public partial class TraceLogger : Form
|
|
|
|
|
{
|
2012-09-30 16:50:00 +00:00
|
|
|
|
//Refresh rate slider
|
2012-09-30 18:37:59 +00:00
|
|
|
|
//Make faster, such as not saving to disk until the logging is stopped, dont' add to Instructions list every frame, etc
|
|
|
|
|
//Remember window size
|
2012-09-30 15:33:54 +00:00
|
|
|
|
|
2012-09-30 00:53:08 +00:00
|
|
|
|
List<string> Instructions = new List<string>();
|
2012-09-30 14:52:36 +00:00
|
|
|
|
FileInfo LogFile;
|
2012-09-30 00:53:08 +00:00
|
|
|
|
|
|
|
|
|
public TraceLogger()
|
|
|
|
|
{
|
|
|
|
|
InitializeComponent();
|
2012-09-30 03:49:53 +00:00
|
|
|
|
|
2012-09-30 00:53:08 +00:00
|
|
|
|
TraceView.QueryItemText += new QueryItemTextHandler(TraceView_QueryItemText);
|
|
|
|
|
TraceView.QueryItemBkColor += new QueryItemBkColorHandler(TraceView_QueryItemBkColor);
|
|
|
|
|
TraceView.VirtualMode = true;
|
2012-09-30 03:49:53 +00:00
|
|
|
|
|
2012-09-30 00:53:08 +00:00
|
|
|
|
Closing += (o, e) => SaveConfigSettings();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void SaveConfigSettings()
|
|
|
|
|
{
|
2012-09-30 03:49:53 +00:00
|
|
|
|
Global.CoreInputComm.Tracer.Enabled = false;
|
2012-09-30 13:38:37 +00:00
|
|
|
|
Global.Config.TraceLoggerWndx = this.Location.X;
|
|
|
|
|
Global.Config.TraceLoggerWndy = this.Location.Y;
|
2012-09-30 00:53:08 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void TraceView_QueryItemBkColor(int index, int column, ref Color color)
|
|
|
|
|
{
|
|
|
|
|
//TODO
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-30 03:09:41 +00:00
|
|
|
|
private void TraceView_QueryItemText(int index, int column, out string text)
|
2012-09-30 00:53:08 +00:00
|
|
|
|
{
|
2012-09-30 04:28:06 +00:00
|
|
|
|
if (index < Instructions.Count)
|
|
|
|
|
{
|
|
|
|
|
text = Instructions[index];
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
text = "";
|
|
|
|
|
}
|
2012-09-30 00:53:08 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void TraceLogger_Load(object sender, EventArgs e)
|
|
|
|
|
{
|
2012-09-30 13:38:37 +00:00
|
|
|
|
if (Global.Config.TraceLoggerSaveWindowPosition && Global.Config.TraceLoggerWndx >= 0 && Global.Config.TraceLoggerWndy >= 0)
|
|
|
|
|
{
|
|
|
|
|
this.Location = new Point(Global.Config.TraceLoggerWndx, Global.Config.TraceLoggerWndy);
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-30 00:53:08 +00:00
|
|
|
|
ClearList();
|
|
|
|
|
LoggingEnabled.Checked = true;
|
2012-09-30 02:37:00 +00:00
|
|
|
|
Global.CoreInputComm.Tracer.Enabled = true;
|
2012-09-30 13:38:37 +00:00
|
|
|
|
SetTracerBoxTitle();
|
2012-09-30 00:53:08 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void UpdateValues()
|
|
|
|
|
{
|
|
|
|
|
DoInstructions();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Restart()
|
|
|
|
|
{
|
|
|
|
|
if (!this.IsHandleCreated || this.IsDisposed)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2012-09-30 13:38:37 +00:00
|
|
|
|
if (Global.Emulator.CoreOutputComm.CpuTraceAvailable)
|
|
|
|
|
{
|
|
|
|
|
ClearList();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
this.Close();
|
|
|
|
|
}
|
2012-09-30 00:53:08 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void ClearList()
|
|
|
|
|
{
|
|
|
|
|
Instructions.Clear();
|
2012-09-30 04:28:06 +00:00
|
|
|
|
TraceView.ItemCount = 0;
|
2012-10-08 00:27:21 +00:00
|
|
|
|
SetTracerBoxTitle();
|
2012-09-30 00:53:08 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
Close();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void LoggingEnabled_CheckedChanged(object sender, EventArgs e)
|
|
|
|
|
{
|
2012-09-30 02:37:00 +00:00
|
|
|
|
Global.CoreInputComm.Tracer.Enabled = LoggingEnabled.Checked;
|
2012-09-30 13:38:37 +00:00
|
|
|
|
SetTracerBoxTitle();
|
2012-09-30 00:53:08 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void ClearButton_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
ClearList();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void DoInstructions()
|
2012-09-30 14:52:36 +00:00
|
|
|
|
{
|
|
|
|
|
if (ToWindowRadio.Checked)
|
|
|
|
|
{
|
|
|
|
|
LogToWindow();
|
|
|
|
|
SetTracerBoxTitle();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
LogToFile();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void LogToFile()
|
|
|
|
|
{
|
|
|
|
|
using (StreamWriter sw = new StreamWriter(LogFile.FullName, true))
|
|
|
|
|
{
|
|
|
|
|
sw.Write(Global.CoreInputComm.Tracer.TakeContents());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void LogToWindow()
|
2012-09-30 00:53:08 +00:00
|
|
|
|
{
|
2012-09-30 02:37:00 +00:00
|
|
|
|
string[] instructions = Global.CoreInputComm.Tracer.TakeContents().Split('\n');
|
2012-09-30 13:38:37 +00:00
|
|
|
|
if (!String.IsNullOrWhiteSpace(instructions[0]))
|
2012-09-30 02:37:00 +00:00
|
|
|
|
{
|
2012-09-30 13:38:37 +00:00
|
|
|
|
foreach (string s in instructions)
|
|
|
|
|
{
|
|
|
|
|
Instructions.Add(s);
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-30 14:52:36 +00:00
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
if (Instructions.Count >= Global.Config.TraceLoggerMaxLines)
|
|
|
|
|
{
|
|
|
|
|
int x = Instructions.Count - Global.Config.TraceLoggerMaxLines;
|
|
|
|
|
Instructions.RemoveRange(0, x);
|
2012-09-30 02:37:00 +00:00
|
|
|
|
}
|
2012-09-30 14:52:36 +00:00
|
|
|
|
|
|
|
|
|
TraceView.ItemCount = Instructions.Count;
|
2012-09-30 00:53:08 +00:00
|
|
|
|
}
|
2012-09-30 03:09:41 +00:00
|
|
|
|
|
|
|
|
|
private void autoloadToolStripMenuItem_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
Global.Config.TraceLoggerAutoLoad ^= true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void optionsToolStripMenuItem_DropDownOpened(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
autoloadToolStripMenuItem.Checked = Global.Config.TraceLoggerAutoLoad;
|
2012-09-30 13:38:37 +00:00
|
|
|
|
saveWindowPositionToolStripMenuItem.Checked = Global.Config.TraceLoggerSaveWindowPosition;
|
2012-09-30 03:09:41 +00:00
|
|
|
|
}
|
2012-09-30 04:28:06 +00:00
|
|
|
|
|
|
|
|
|
private void CloseButton_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
Close();
|
|
|
|
|
}
|
2012-09-30 13:38:37 +00:00
|
|
|
|
|
|
|
|
|
private void saveWindowPositionToolStripMenuItem_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
Global.Config.TraceLoggerSaveWindowPosition ^= true;
|
|
|
|
|
}
|
|
|
|
|
|
2012-10-02 03:16:28 +00:00
|
|
|
|
private Point GetPromptPoint()
|
|
|
|
|
{
|
|
|
|
|
Point p = new Point(TraceView.Location.X + 30, TraceView.Location.Y + 30);
|
|
|
|
|
Point q = new Point();
|
|
|
|
|
q = PointToScreen(p);
|
|
|
|
|
return q;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-30 13:38:37 +00:00
|
|
|
|
private void setMaxWindowLinesToolStripMenuItem_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
InputPrompt p = new InputPrompt();
|
|
|
|
|
p.SetMessage("Max lines to display in the window");
|
|
|
|
|
p.SetInitialValue(Global.Config.TraceLoggerMaxLines.ToString());
|
|
|
|
|
p.TextInputType = InputPrompt.InputType.UNSIGNED;
|
2012-10-02 03:16:28 +00:00
|
|
|
|
p._Location = GetPromptPoint();
|
2012-09-30 13:38:37 +00:00
|
|
|
|
DialogResult result = p.ShowDialog();
|
|
|
|
|
if (p.UserOK)
|
|
|
|
|
{
|
|
|
|
|
int x = int.Parse(p.UserText);
|
|
|
|
|
if (x > 0)
|
|
|
|
|
{
|
|
|
|
|
Global.Config.TraceLoggerMaxLines = x;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void SetTracerBoxTitle()
|
|
|
|
|
{
|
|
|
|
|
if (Global.CoreInputComm.Tracer.Enabled)
|
|
|
|
|
{
|
2012-09-30 14:52:36 +00:00
|
|
|
|
if (ToFileRadio.Checked)
|
|
|
|
|
{
|
|
|
|
|
TracerBox.Text = "Trace log - logging to file...";
|
|
|
|
|
}
|
|
|
|
|
else if (Instructions.Count > 0)
|
2012-09-30 13:38:37 +00:00
|
|
|
|
{
|
|
|
|
|
TracerBox.Text = "Trace log - logging - " + Instructions.Count.ToString() + " instructions";
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
TracerBox.Text = "Trace log - logging...";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (Instructions.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
TracerBox.Text = "Trace log - " + Instructions.Count.ToString() + " instructions";
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
TracerBox.Text = "Trace log";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-09-30 14:52:36 +00:00
|
|
|
|
|
|
|
|
|
private void ToFileRadio_CheckedChanged(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if (ToFileRadio.Checked)
|
|
|
|
|
{
|
2012-09-30 18:37:59 +00:00
|
|
|
|
FileBox.Visible = true;
|
|
|
|
|
BrowseBox.Visible = true;
|
2012-09-30 14:52:36 +00:00
|
|
|
|
string name = PathManager.FilesystemSafeName(Global.Game);
|
2012-09-30 16:50:00 +00:00
|
|
|
|
string filename = Path.Combine(PathManager.MakeAbsolutePath(Global.Config.LogPath, ""), name) + ".txt";
|
2012-09-30 14:52:36 +00:00
|
|
|
|
LogFile = new FileInfo(filename);
|
|
|
|
|
if (!LogFile.Directory.Exists)
|
|
|
|
|
{
|
|
|
|
|
LogFile.Directory.Create();
|
|
|
|
|
}
|
|
|
|
|
if (LogFile.Exists)
|
|
|
|
|
{
|
|
|
|
|
LogFile.Delete();
|
|
|
|
|
LogFile.Create();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
LogFile.Create();
|
|
|
|
|
}
|
2012-09-30 18:37:59 +00:00
|
|
|
|
|
|
|
|
|
FileBox.Text = LogFile.FullName;
|
2012-09-30 14:52:36 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
CloseFile();
|
2012-09-30 18:37:59 +00:00
|
|
|
|
FileBox.Visible = false;
|
|
|
|
|
BrowseBox.Visible = false;
|
|
|
|
|
|
2012-09-30 14:52:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SetTracerBoxTitle();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void CloseFile()
|
|
|
|
|
{
|
2012-09-30 18:37:59 +00:00
|
|
|
|
//TODO: save the remaining instructions in CoreComm
|
2012-09-30 14:52:36 +00:00
|
|
|
|
}
|
2012-09-30 15:33:54 +00:00
|
|
|
|
|
|
|
|
|
private void TraceView_KeyDown(object sender, KeyEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if (e.Control && e.KeyCode == Keys.C)
|
|
|
|
|
{
|
|
|
|
|
ListView.SelectedIndexCollection indexes = TraceView.SelectedIndices;
|
|
|
|
|
|
|
|
|
|
if (indexes.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
StringBuilder blob = new StringBuilder();
|
|
|
|
|
foreach (int x in indexes)
|
|
|
|
|
{
|
|
|
|
|
blob.Append(Instructions[x]);
|
2012-09-30 18:49:16 +00:00
|
|
|
|
blob.Append("\r\n");
|
2012-09-30 15:33:54 +00:00
|
|
|
|
}
|
2012-09-30 18:49:16 +00:00
|
|
|
|
blob.Remove(blob.Length - 2, 2); //Lazy way to not have a line break at the end
|
2012-09-30 15:33:54 +00:00
|
|
|
|
Clipboard.SetDataObject(blob.ToString());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-09-30 18:37:59 +00:00
|
|
|
|
|
|
|
|
|
private void BrowseBox_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
var file = GetFileFromUser();
|
|
|
|
|
if (file != null)
|
|
|
|
|
{
|
|
|
|
|
LogFile = file;
|
|
|
|
|
FileBox.Text = LogFile.FullName;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private FileInfo GetFileFromUser()
|
|
|
|
|
{
|
|
|
|
|
var sfd = new SaveFileDialog();
|
|
|
|
|
if (LogFile == null)
|
|
|
|
|
{
|
|
|
|
|
string name = PathManager.FilesystemSafeName(Global.Game);
|
|
|
|
|
sfd.FileName = name + ".txt";
|
|
|
|
|
sfd.InitialDirectory = PathManager.MakeAbsolutePath(Global.Config.LogPath, "");
|
|
|
|
|
}
|
|
|
|
|
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.LogPath, "");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sfd.Filter = "Text Files (*.txt)|*.txt|Log Files (*.log)|*.log|All Files|*.*";
|
|
|
|
|
sfd.RestoreDirectory = true;
|
|
|
|
|
Global.Sound.StopSound();
|
|
|
|
|
|
|
|
|
|
var result = sfd.ShowDialog();
|
|
|
|
|
Global.Sound.StartSound();
|
|
|
|
|
if (result != DialogResult.OK)
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return new FileInfo(sfd.FileName);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void saveLogToolStripMenuItem_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
var file = GetFileFromUser();
|
|
|
|
|
if (file != null)
|
|
|
|
|
{
|
|
|
|
|
DumpListToDisk(file);
|
2012-10-08 00:27:21 +00:00
|
|
|
|
Global.OSD.AddMessage("Log dumped to " + file.FullName);
|
2012-09-30 18:37:59 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void DumpListToDisk(FileInfo file)
|
|
|
|
|
{
|
|
|
|
|
using (StreamWriter sw = new StreamWriter(file.FullName))
|
|
|
|
|
{
|
|
|
|
|
foreach (string s in Instructions)
|
|
|
|
|
{
|
|
|
|
|
sw.WriteLine(s);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-09-30 00:53:08 +00:00
|
|
|
|
}
|
|
|
|
|
}
|