Merge pull request #1775 from TASVideos/log-as-tool
Remove Log windows as console option, and make LogWindow a Tool
This commit is contained in:
commit
094ae65e06
|
@ -105,7 +105,6 @@ namespace BizHawk.Client.Common
|
||||||
public bool MoviesInAWE = false;
|
public bool MoviesInAWE = false;
|
||||||
public bool HotkeyConfigAutoTab = true;
|
public bool HotkeyConfigAutoTab = true;
|
||||||
public bool InputConfigAutoTab = true;
|
public bool InputConfigAutoTab = true;
|
||||||
public bool ShowLogWindow = false;
|
|
||||||
public bool BackupSavestates = true;
|
public bool BackupSavestates = true;
|
||||||
public bool SaveScreenshotWithStates = true;
|
public bool SaveScreenshotWithStates = true;
|
||||||
public int BigScreenshotSize = 128 * 1024;
|
public int BigScreenshotSize = 128 * 1024;
|
||||||
|
@ -115,7 +114,6 @@ namespace BizHawk.Client.Common
|
||||||
public bool AutofireLagFrames = true;
|
public bool AutofireLagFrames = true;
|
||||||
public int SaveSlot = 0; // currently selected savestate slot
|
public int SaveSlot = 0; // currently selected savestate slot
|
||||||
public bool AutoLoadLastSaveSlot = false;
|
public bool AutoLoadLastSaveSlot = false;
|
||||||
public bool WIN32_CONSOLE = true;
|
|
||||||
public bool SkipLagFrame = false;
|
public bool SkipLagFrame = false;
|
||||||
public bool SuppressAskSave = false;
|
public bool SuppressAskSave = false;
|
||||||
public bool AVI_CaptureOSD = false;
|
public bool AVI_CaptureOSD = false;
|
||||||
|
@ -313,13 +311,6 @@ namespace BizHawk.Client.Common
|
||||||
public string SoundDevice = "";
|
public string SoundDevice = "";
|
||||||
public int SoundBufferSizeMs = 100;
|
public int SoundBufferSizeMs = 100;
|
||||||
|
|
||||||
// Log Window
|
|
||||||
public bool LogWindowSaveWindowPosition = true;
|
|
||||||
public int LogWindowWndx = -1;
|
|
||||||
public int LogWindowWndy = -1;
|
|
||||||
public int LogWindowWidth = -1;
|
|
||||||
public int LogWindowHeight = -1;
|
|
||||||
|
|
||||||
// Lua
|
// Lua
|
||||||
public RecentFiles RecentLua = new RecentFiles(8);
|
public RecentFiles RecentLua = new RecentFiles(8);
|
||||||
public RecentFiles RecentLuaSession = new RecentFiles(8);
|
public RecentFiles RecentLuaSession = new RecentFiles(8);
|
||||||
|
|
|
@ -658,7 +658,6 @@
|
||||||
<Compile Include="IControlMainform.cs" />
|
<Compile Include="IControlMainform.cs" />
|
||||||
<Compile Include="Input\IPCKeyInput.cs" />
|
<Compile Include="Input\IPCKeyInput.cs" />
|
||||||
<Compile Include="JumpLists.cs" />
|
<Compile Include="JumpLists.cs" />
|
||||||
<Compile Include="LogConsole.cs" />
|
|
||||||
<Compile Include="LogWindow.cs">
|
<Compile Include="LogWindow.cs">
|
||||||
<SubType>Form</SubType>
|
<SubType>Form</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
|
|
@ -1,290 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Text;
|
|
||||||
using System.IO;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.Windows.Forms;
|
|
||||||
|
|
||||||
using BizHawk.Common;
|
|
||||||
using BizHawk.Client.Common;
|
|
||||||
|
|
||||||
// thanks! - http://sharp-developer.net/ru/CodeBank/WinForms/GuiConsole.aspx
|
|
||||||
// todo - quit using Console.WriteLine (well, we can leave it hooked up as a backstop)
|
|
||||||
// use a different method instead, so we can collect unicode data
|
|
||||||
// also, collect log data independently of whether the log window is open
|
|
||||||
// we also need to dice it into lines so that we can have a backlog policy
|
|
||||||
|
|
||||||
namespace BizHawk.Client.EmuHawk
|
|
||||||
{
|
|
||||||
internal static class LogConsole
|
|
||||||
{
|
|
||||||
public static bool ConsoleVisible { get; private set; }
|
|
||||||
|
|
||||||
private static LogWindow _window;
|
|
||||||
private static LogStream _logStream;
|
|
||||||
private static bool _needToRelease;
|
|
||||||
|
|
||||||
private class LogStream : Stream
|
|
||||||
{
|
|
||||||
public override bool CanRead => false;
|
|
||||||
public override bool CanSeek => false;
|
|
||||||
public override bool CanWrite => true;
|
|
||||||
|
|
||||||
public override void Flush()
|
|
||||||
{
|
|
||||||
//TODO - maybe this will help with decoding
|
|
||||||
}
|
|
||||||
|
|
||||||
public override long Length => throw new NotImplementedException();
|
|
||||||
|
|
||||||
public override long Position
|
|
||||||
{
|
|
||||||
get => throw new NotImplementedException();
|
|
||||||
set => throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int Read(byte[] buffer, int offset, int count)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override long Seek(long offset, SeekOrigin origin)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void SetLength(long value)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Write(byte[] buffer, int offset, int count)
|
|
||||||
{
|
|
||||||
// TODO - buffer undecoded characters (this may be important)
|
|
||||||
//(use decoder = System.Text.Encoding.Unicode.GetDecoder())
|
|
||||||
string str = Encoding.ASCII.GetString(buffer, offset, count);
|
|
||||||
Emit?.Invoke(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action<string> Emit;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static string SkipEverythingButProgramInCommandLine(string cmdLine)
|
|
||||||
{
|
|
||||||
// skip past the program name. can anyone think of a better way to do this?
|
|
||||||
// we could use CommandLineToArgvW (commented out below) but then we would just have to re-assemble and potentially re-quote it
|
|
||||||
int childCmdLine = 0;
|
|
||||||
int lastSlash = 0;
|
|
||||||
int lastGood = 0;
|
|
||||||
bool quote = false;
|
|
||||||
for (; ; )
|
|
||||||
{
|
|
||||||
char cur = cmdLine[childCmdLine];
|
|
||||||
childCmdLine++;
|
|
||||||
if (childCmdLine == cmdLine.Length) break;
|
|
||||||
bool thisIsQuote = (cur == '\"');
|
|
||||||
if (cur == '\\' || cur == '/')
|
|
||||||
{
|
|
||||||
lastSlash = childCmdLine;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (quote)
|
|
||||||
{
|
|
||||||
if (thisIsQuote)
|
|
||||||
quote = false;
|
|
||||||
else lastGood = childCmdLine;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (cur == ' ' || cur == '\t')
|
|
||||||
break;
|
|
||||||
if (thisIsQuote)
|
|
||||||
quote = true;
|
|
||||||
lastGood = childCmdLine;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
string remainder = cmdLine.Substring(childCmdLine);
|
|
||||||
string path = cmdLine.Substring(lastSlash, lastGood - lastSlash);
|
|
||||||
return $"{path} {remainder}";
|
|
||||||
}
|
|
||||||
|
|
||||||
private static IntPtr _oldOut, _conOut;
|
|
||||||
private static bool _hasConsole;
|
|
||||||
private static bool _attachedConsole;
|
|
||||||
private static bool _shouldRedirectStdout;
|
|
||||||
public static void CreateConsole()
|
|
||||||
{
|
|
||||||
// (see desmume for the basis of some of this logic)
|
|
||||||
if (_hasConsole)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_oldOut == IntPtr.Zero)
|
|
||||||
{
|
|
||||||
_oldOut = ConsoleImports.GetStdHandle( -11 ); // STD_OUTPUT_HANDLE
|
|
||||||
}
|
|
||||||
|
|
||||||
var fileType = ConsoleImports.GetFileType(_oldOut);
|
|
||||||
|
|
||||||
// stdout is already connected to something. keep using it and don't let the console interfere
|
|
||||||
_shouldRedirectStdout = (fileType == ConsoleImports.FileType.FileTypeUnknown || fileType == ConsoleImports.FileType.FileTypePipe);
|
|
||||||
|
|
||||||
// attach to an existing console
|
|
||||||
_attachedConsole = false;
|
|
||||||
|
|
||||||
// ever since a recent KB, XP-based systems glitch out when AttachConsole is called and there's no console to attach to.
|
|
||||||
if (Environment.OSVersion.Version.Major != 5)
|
|
||||||
{
|
|
||||||
if (ConsoleImports.AttachConsole(-1))
|
|
||||||
{
|
|
||||||
_hasConsole = true;
|
|
||||||
_attachedConsole = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_attachedConsole)
|
|
||||||
{
|
|
||||||
ConsoleImports.FreeConsole();
|
|
||||||
if (ConsoleImports.AllocConsole())
|
|
||||||
{
|
|
||||||
//set icons for the console so we can tell them apart from the main window
|
|
||||||
Win32Imports.SendMessage(ConsoleImports.GetConsoleWindow(), 0x0080/*WM_SETICON*/, (IntPtr)0/*ICON_SMALL*/, Properties.Resources.console16x16.GetHicon());
|
|
||||||
Win32Imports.SendMessage(ConsoleImports.GetConsoleWindow(), 0x0080/*WM_SETICON*/, (IntPtr)1/*ICON_LARGE*/, Properties.Resources.console32x32.GetHicon());
|
|
||||||
_hasConsole = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MessageBox.Show($"Couldn't allocate win32 console: {Marshal.GetLastWin32Error()}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_hasConsole)
|
|
||||||
{
|
|
||||||
IntPtr ptr = ConsoleImports.GetCommandLine();
|
|
||||||
string commandLine = Marshal.PtrToStringAuto(ptr);
|
|
||||||
Console.Title = SkipEverythingButProgramInCommandLine(commandLine);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_shouldRedirectStdout)
|
|
||||||
{
|
|
||||||
_conOut = ConsoleImports.CreateFile("CONOUT$", 0x40000000, 2, IntPtr.Zero, 3, 0, IntPtr.Zero);
|
|
||||||
|
|
||||||
if (!ConsoleImports.SetStdHandle(-11, _conOut))
|
|
||||||
throw new Exception($"{nameof(ConsoleImports.SetStdHandle)}() failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
//DotNetRewireConout();
|
|
||||||
_hasConsole = true;
|
|
||||||
|
|
||||||
if (_attachedConsole)
|
|
||||||
{
|
|
||||||
Console.WriteLine();
|
|
||||||
Console.WriteLine("use cmd /c {0} to get more sensible console behaviour", Path.GetFileName(PathManager.GetGlobalBasePathAbsolute()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ReleaseConsole()
|
|
||||||
{
|
|
||||||
if (!_hasConsole)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_shouldRedirectStdout)
|
|
||||||
{
|
|
||||||
ConsoleImports.CloseHandle(_conOut);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_attachedConsole)
|
|
||||||
{
|
|
||||||
ConsoleImports.FreeConsole();
|
|
||||||
}
|
|
||||||
|
|
||||||
ConsoleImports.SetStdHandle(-11, _oldOut);
|
|
||||||
|
|
||||||
_conOut = IntPtr.Zero;
|
|
||||||
_hasConsole = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// pops the console in front of the main window (where it should probably go after booting up the game).
|
|
||||||
/// maybe this should be optional, or maybe we can somehow position the console sensibly.
|
|
||||||
/// sometimes it annoys me, but i really need it on top while debugging or else i will be annoyed.
|
|
||||||
/// best of all would be to position it beneath the BizHawk main window somehow.
|
|
||||||
/// </summary>
|
|
||||||
public static void PositionConsole()
|
|
||||||
{
|
|
||||||
if (ConsoleVisible == false)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Global.Config.WIN32_CONSOLE)
|
|
||||||
{
|
|
||||||
IntPtr x = ConsoleImports.GetConsoleWindow();
|
|
||||||
ConsoleImports.SetForegroundWindow(x);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void ShowConsole(MainForm parent)
|
|
||||||
{
|
|
||||||
if (ConsoleVisible) return;
|
|
||||||
ConsoleVisible = true;
|
|
||||||
|
|
||||||
if (Global.Config.WIN32_CONSOLE)
|
|
||||||
{
|
|
||||||
_needToRelease = true;
|
|
||||||
CreateConsole();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_logStream = new LogStream();
|
|
||||||
Log.HACK_LOG_STREAM = _logStream;
|
|
||||||
Console.SetOut(new StreamWriter(_logStream) { AutoFlush = true });
|
|
||||||
_window = new LogWindow(parent);
|
|
||||||
_window.Show();
|
|
||||||
_logStream.Emit = str => { _window.Append(str); };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void HideConsole()
|
|
||||||
{
|
|
||||||
if (ConsoleVisible == false)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Console.SetOut(TextWriter.Null);
|
|
||||||
ConsoleVisible = false;
|
|
||||||
if (_needToRelease)
|
|
||||||
{
|
|
||||||
ReleaseConsole();
|
|
||||||
_needToRelease = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_logStream.Close();
|
|
||||||
_logStream = null;
|
|
||||||
Log.HACK_LOG_STREAM = null;
|
|
||||||
_window.Close();
|
|
||||||
_window = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void NotifyLogWindowClosing()
|
|
||||||
{
|
|
||||||
Console.SetOut(TextWriter.Null);
|
|
||||||
ConsoleVisible = false;
|
|
||||||
_logStream?.Close();
|
|
||||||
Log.HACK_LOG_STREAM = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void SaveConfigSettings()
|
|
||||||
{
|
|
||||||
if (_window != null && _window.IsHandleCreated)
|
|
||||||
{
|
|
||||||
_window.SaveConfigSettings();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,6 +1,4 @@
|
||||||
using System.Windows.Forms;
|
namespace BizHawk.Client.EmuHawk
|
||||||
|
|
||||||
namespace BizHawk.Client.EmuHawk
|
|
||||||
{
|
{
|
||||||
partial class LogWindow
|
partial class LogWindow
|
||||||
{
|
{
|
||||||
|
@ -38,6 +36,7 @@ namespace BizHawk.Client.EmuHawk
|
||||||
this.AddToGameDbBtn = new System.Windows.Forms.Button();
|
this.AddToGameDbBtn = new System.Windows.Forms.Button();
|
||||||
this.virtualListView1 = new System.Windows.Forms.ListView();
|
this.virtualListView1 = new System.Windows.Forms.ListView();
|
||||||
this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
||||||
|
this.MenuStrip = new MenuStripEx();
|
||||||
this.tableLayoutPanel1.SuspendLayout();
|
this.tableLayoutPanel1.SuspendLayout();
|
||||||
this.SuspendLayout();
|
this.SuspendLayout();
|
||||||
//
|
//
|
||||||
|
@ -107,7 +106,6 @@ namespace BizHawk.Client.EmuHawk
|
||||||
//
|
//
|
||||||
// AddToGameDbBtn
|
// AddToGameDbBtn
|
||||||
//
|
//
|
||||||
this.AddToGameDbBtn.Image = global::BizHawk.Client.EmuHawk.Properties.Resources.RetroQuestion;
|
|
||||||
this.AddToGameDbBtn.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
this.AddToGameDbBtn.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||||
this.AddToGameDbBtn.Location = new System.Drawing.Point(246, 3);
|
this.AddToGameDbBtn.Location = new System.Drawing.Point(246, 3);
|
||||||
this.AddToGameDbBtn.Name = "AddToGameDbBtn";
|
this.AddToGameDbBtn.Name = "AddToGameDbBtn";
|
||||||
|
@ -125,18 +123,26 @@ namespace BizHawk.Client.EmuHawk
|
||||||
this.virtualListView1.Dock = System.Windows.Forms.DockStyle.Fill;
|
this.virtualListView1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||||
this.virtualListView1.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
this.virtualListView1.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||||
this.virtualListView1.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.None;
|
this.virtualListView1.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.None;
|
||||||
this.virtualListView1.VirtualListSize = 0;
|
this.virtualListView1.HideSelection = false;
|
||||||
this.virtualListView1.Location = new System.Drawing.Point(0, 0);
|
this.virtualListView1.Location = new System.Drawing.Point(0, 24);
|
||||||
this.virtualListView1.Name = "virtualListView1";
|
this.virtualListView1.Name = "virtualListView1";
|
||||||
this.virtualListView1.Size = new System.Drawing.Size(675, 367);
|
this.virtualListView1.Size = new System.Drawing.Size(675, 343);
|
||||||
this.virtualListView1.TabIndex = 8;
|
this.virtualListView1.TabIndex = 8;
|
||||||
this.virtualListView1.UseCompatibleStateImageBehavior = false;
|
this.virtualListView1.UseCompatibleStateImageBehavior = false;
|
||||||
this.virtualListView1.View = System.Windows.Forms.View.Details;
|
this.virtualListView1.View = System.Windows.Forms.View.Details;
|
||||||
this.virtualListView1.VirtualMode = true;
|
this.virtualListView1.VirtualMode = true;
|
||||||
this.virtualListView1.RetrieveVirtualItem += new RetrieveVirtualItemEventHandler(this.ListView_QueryItemText);
|
this.virtualListView1.RetrieveVirtualItem += new System.Windows.Forms.RetrieveVirtualItemEventHandler(this.ListView_QueryItemText);
|
||||||
this.virtualListView1.ClientSizeChanged += new System.EventHandler(this.ListView_ClientSizeChanged);
|
this.virtualListView1.ClientSizeChanged += new System.EventHandler(this.ListView_ClientSizeChanged);
|
||||||
this.virtualListView1.KeyDown += new System.Windows.Forms.KeyEventHandler(this.ListView_KeyDown);
|
this.virtualListView1.KeyDown += new System.Windows.Forms.KeyEventHandler(this.ListView_KeyDown);
|
||||||
//
|
//
|
||||||
|
// MenuStrip
|
||||||
|
//
|
||||||
|
this.MenuStrip.Location = new System.Drawing.Point(0, 0);
|
||||||
|
this.MenuStrip.Name = "MenuStrip";
|
||||||
|
this.MenuStrip.Size = new System.Drawing.Size(675, 24);
|
||||||
|
this.MenuStrip.TabIndex = 9;
|
||||||
|
this.MenuStrip.Text = "menuStrip1";
|
||||||
|
//
|
||||||
// LogWindow
|
// LogWindow
|
||||||
//
|
//
|
||||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||||
|
@ -145,6 +151,8 @@ namespace BizHawk.Client.EmuHawk
|
||||||
this.ClientSize = new System.Drawing.Size(675, 397);
|
this.ClientSize = new System.Drawing.Size(675, 397);
|
||||||
this.Controls.Add(this.virtualListView1);
|
this.Controls.Add(this.virtualListView1);
|
||||||
this.Controls.Add(this.tableLayoutPanel1);
|
this.Controls.Add(this.tableLayoutPanel1);
|
||||||
|
this.Controls.Add(this.MenuStrip);
|
||||||
|
this.MainMenuStrip = this.MenuStrip;
|
||||||
this.MinimumSize = new System.Drawing.Size(171, 97);
|
this.MinimumSize = new System.Drawing.Size(171, 97);
|
||||||
this.Name = "LogWindow";
|
this.Name = "LogWindow";
|
||||||
this.ShowIcon = false;
|
this.ShowIcon = false;
|
||||||
|
@ -167,5 +175,6 @@ namespace BizHawk.Client.EmuHawk
|
||||||
private System.Windows.Forms.Button buttonCopy;
|
private System.Windows.Forms.Button buttonCopy;
|
||||||
private System.Windows.Forms.Button buttonCopyAll;
|
private System.Windows.Forms.Button buttonCopyAll;
|
||||||
private System.Windows.Forms.Button AddToGameDbBtn;
|
private System.Windows.Forms.Button AddToGameDbBtn;
|
||||||
|
private MenuStripEx MenuStrip;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,52 +1,81 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Drawing;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
using BizHawk.Common;
|
||||||
using BizHawk.Emulation.Common;
|
using BizHawk.Emulation.Common;
|
||||||
using BizHawk.Emulation.Common.IEmulatorExtensions;
|
using BizHawk.Emulation.Common.IEmulatorExtensions;
|
||||||
using BizHawk.Client.Common;
|
using BizHawk.Client.Common;
|
||||||
|
using BizHawk.Client.EmuHawk.WinFormExtensions;
|
||||||
|
|
||||||
//todo - perks - pause, copy to clipboard, backlog length limiting
|
// todo - perks - pause, copy to clipboard, backlog length limiting
|
||||||
|
|
||||||
namespace BizHawk.Client.EmuHawk
|
namespace BizHawk.Client.EmuHawk
|
||||||
{
|
{
|
||||||
public partial class LogWindow : Form
|
public partial class LogWindow : ToolFormBase, IToolFormAutoConfig
|
||||||
{
|
{
|
||||||
//TODO: only show add to game db when this is a Rom details dialog
|
// TODO: only show add to game db when this is a Rom details dialog
|
||||||
//Let user decide what type (instead of always adding it as a good dump)
|
// Let user decide what type (instead of always adding it as a good dump)
|
||||||
private readonly List<string> _lines = new List<string>();
|
private readonly List<string> _lines = new List<string>();
|
||||||
private readonly MainForm _mainForm;
|
private LogStream _logStream;
|
||||||
|
|
||||||
public LogWindow(MainForm mainForm)
|
[RequiredService]
|
||||||
|
private IEmulator Emulator { get; set; }
|
||||||
|
|
||||||
|
public LogWindow()
|
||||||
{
|
{
|
||||||
_mainForm = mainForm;
|
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
Closing += (o, e) =>
|
Closing += (o, e) =>
|
||||||
{
|
{
|
||||||
Global.Config.ShowLogWindow = false;
|
Detach();
|
||||||
mainForm.NotifyLogWindowClosing();
|
|
||||||
LogConsole.NotifyLogWindowClosing();
|
|
||||||
SaveConfigSettings();
|
|
||||||
};
|
};
|
||||||
ListView_ClientSizeChanged(null, null);
|
ListView_ClientSizeChanged(null, null);
|
||||||
|
Attach();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ShowReport(string title, string report, MainForm parent)
|
public void UpdateValues() { } // TODO
|
||||||
|
|
||||||
|
public void NewUpdate(ToolFormUpdateType type) { }
|
||||||
|
|
||||||
|
public void FastUpdate() { }
|
||||||
|
|
||||||
|
public void Restart() { }
|
||||||
|
|
||||||
|
public bool AskSaveChanges() => true;
|
||||||
|
public bool UpdateBefore => true;
|
||||||
|
|
||||||
|
private void Attach()
|
||||||
|
{
|
||||||
|
_logStream = new LogStream();
|
||||||
|
Log.HACK_LOG_STREAM = _logStream;
|
||||||
|
Console.SetOut(new StreamWriter(_logStream) { AutoFlush = true });
|
||||||
|
_logStream.Emit = Append;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Detach()
|
||||||
|
{
|
||||||
|
Console.SetOut(new StreamWriter(Console.OpenStandardOutput())
|
||||||
|
{
|
||||||
|
AutoFlush = true
|
||||||
|
});
|
||||||
|
_logStream.Close();
|
||||||
|
_logStream = null;
|
||||||
|
Log.HACK_LOG_STREAM = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ShowReport(string title, string report)
|
||||||
{
|
{
|
||||||
using var dlg = new LogWindow(parent);
|
|
||||||
var ss = report.Split('\n');
|
var ss = report.Split('\n');
|
||||||
foreach (var s in ss)
|
foreach (var s in ss)
|
||||||
{
|
{
|
||||||
dlg._lines.Add(s.TrimEnd('\r'));
|
_lines.Add(s.TrimEnd('\r'));
|
||||||
}
|
}
|
||||||
|
|
||||||
dlg.virtualListView1.VirtualListSize = ss.Length;
|
virtualListView1.VirtualListSize = ss.Length;
|
||||||
dlg.Text = title;
|
Text = title;
|
||||||
dlg.btnClear.Visible = false;
|
btnClear.Visible = false;
|
||||||
dlg.ShowDialog(parent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Append(string str)
|
public void Append(string str)
|
||||||
|
@ -76,31 +105,9 @@ namespace BizHawk.Client.EmuHawk
|
||||||
|
|
||||||
private void LogWindow_Load(object sender, EventArgs e)
|
private void LogWindow_Load(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (Global.Config.LogWindowSaveWindowPosition)
|
|
||||||
{
|
|
||||||
if (Global.Config.LogWindowSaveWindowPosition && Global.Config.LogWindowWndx >= 0 && Global.Config.LogWindowWndy >= 0)
|
|
||||||
Location = new Point(Global.Config.LogWindowWndx, Global.Config.LogWindowWndy);
|
|
||||||
|
|
||||||
if (Global.Config.LogWindowWidth >= 0 && Global.Config.LogWindowHeight >= 0)
|
|
||||||
{
|
|
||||||
Size = new Size(Global.Config.LogWindowWidth, Global.Config.LogWindowHeight);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
HideShowGameDbButton();
|
HideShowGameDbButton();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SaveConfigSettings()
|
|
||||||
{
|
|
||||||
if (Global.Config.LogWindowSaveWindowPosition)
|
|
||||||
{
|
|
||||||
Global.Config.LogWindowWndx = Location.X;
|
|
||||||
Global.Config.LogWindowWndy = Location.Y;
|
|
||||||
Global.Config.LogWindowWidth = Right - Left;
|
|
||||||
Global.Config.LogWindowHeight = Bottom - Top;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ListView_QueryItemText(object sender, RetrieveVirtualItemEventArgs e)
|
private void ListView_QueryItemText(object sender, RetrieveVirtualItemEventArgs e)
|
||||||
{
|
{
|
||||||
e.Item = new ListViewItem(_lines[e.ItemIndex]);
|
e.Item = new ListViewItem(_lines[e.ItemIndex]);
|
||||||
|
@ -139,7 +146,7 @@ namespace BizHawk.Client.EmuHawk
|
||||||
|
|
||||||
private void HideShowGameDbButton()
|
private void HideShowGameDbButton()
|
||||||
{
|
{
|
||||||
AddToGameDbBtn.Visible = Global.Emulator.CanGenerateGameDBEntries()
|
AddToGameDbBtn.Visible = Emulator.CanGenerateGameDBEntries()
|
||||||
&& (Global.Game.Status == RomStatus.Unknown || Global.Game.Status == RomStatus.NotInDatabase);
|
&& (Global.Game.Status == RomStatus.Unknown || Global.Game.Status == RomStatus.NotInDatabase);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,15 +154,60 @@ namespace BizHawk.Client.EmuHawk
|
||||||
{
|
{
|
||||||
using var picker = new RomStatusPicker();
|
using var picker = new RomStatusPicker();
|
||||||
var result = picker.ShowDialog();
|
var result = picker.ShowDialog();
|
||||||
if (result == DialogResult.OK)
|
if (result.IsOk())
|
||||||
{
|
{
|
||||||
var gameDbEntry = Global.Emulator.AsGameDBEntryGenerator().GenerateGameDbEntry();
|
var gameDbEntry = Emulator.AsGameDBEntryGenerator().GenerateGameDbEntry();
|
||||||
var userDb = Path.Combine(PathManager.GetExeDirectoryAbsolute(), "gamedb", "gamedb_user.txt");
|
var userDb = Path.Combine(PathManager.GetExeDirectoryAbsolute(), "gamedb", "gamedb_user.txt");
|
||||||
Global.Game.Status = gameDbEntry.Status = picker.PickedStatus;
|
Global.Game.Status = gameDbEntry.Status = picker.PickedStatus;
|
||||||
Database.SaveDatabaseEntry(userDb, gameDbEntry);
|
Database.SaveDatabaseEntry(userDb, gameDbEntry);
|
||||||
_mainForm.UpdateDumpIcon();
|
MainForm.UpdateDumpIcon();
|
||||||
HideShowGameDbButton();
|
HideShowGameDbButton();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class LogStream : Stream
|
||||||
|
{
|
||||||
|
public override bool CanRead => false;
|
||||||
|
public override bool CanSeek => false;
|
||||||
|
public override bool CanWrite => true;
|
||||||
|
|
||||||
|
public override void Flush()
|
||||||
|
{
|
||||||
|
//TODO - maybe this will help with decoding
|
||||||
|
}
|
||||||
|
|
||||||
|
public override long Length => throw new NotImplementedException();
|
||||||
|
|
||||||
|
public override long Position
|
||||||
|
{
|
||||||
|
get => throw new NotImplementedException();
|
||||||
|
set => throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int Read(byte[] buffer, int offset, int count)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override long Seek(long offset, SeekOrigin origin)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SetLength(long value)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Write(byte[] buffer, int offset, int count)
|
||||||
|
{
|
||||||
|
// TODO - buffer undecoded characters (this may be important)
|
||||||
|
//(use decoder = System.Text.Encoding.Unicode.GetDecoder())
|
||||||
|
string str = Encoding.ASCII.GetString(buffer, offset, count);
|
||||||
|
Emit?.Invoke(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Action<string> Emit;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,4 +117,7 @@
|
||||||
<resheader name="writer">
|
<resheader name="writer">
|
||||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
</resheader>
|
</resheader>
|
||||||
|
<metadata name="MenuStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>17, 17</value>
|
||||||
|
</metadata>
|
||||||
</root>
|
</root>
|
|
@ -747,13 +747,11 @@ namespace BizHawk.Client.EmuHawk
|
||||||
SwitchToFullscreenMenuItem.ShortcutKeyDisplayString = Config.HotkeyBindings["Full Screen"].Bindings;
|
SwitchToFullscreenMenuItem.ShortcutKeyDisplayString = Config.HotkeyBindings["Full Screen"].Bindings;
|
||||||
|
|
||||||
DisplayStatusBarMenuItem.Checked = Config.DispChrome_StatusBarWindowed;
|
DisplayStatusBarMenuItem.Checked = Config.DispChrome_StatusBarWindowed;
|
||||||
DisplayLogWindowMenuItem.Checked = Config.ShowLogWindow;
|
DisplayLogWindowMenuItem.Checked = Tools.IsLoaded<LogWindow>();
|
||||||
|
|
||||||
DisplayLagCounterMenuItem.Enabled = Emulator.CanPollInput();
|
DisplayLagCounterMenuItem.Enabled = Emulator.CanPollInput();
|
||||||
|
|
||||||
DisplayMessagesMenuItem.Checked = Config.DisplayMessages;
|
DisplayMessagesMenuItem.Checked = Config.DisplayMessages;
|
||||||
|
|
||||||
DisplayLogWindowMenuItem.Enabled = !OSTailoredCode.IsUnixHost;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WindowSizeSubMenu_DropDownOpened(object sender, EventArgs e)
|
private void WindowSizeSubMenu_DropDownOpened(object sender, EventArgs e)
|
||||||
|
@ -847,16 +845,7 @@ namespace BizHawk.Client.EmuHawk
|
||||||
|
|
||||||
private void DisplayLogWindowMenuItem_Click(object sender, EventArgs e)
|
private void DisplayLogWindowMenuItem_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
Config.ShowLogWindow ^= true;
|
Tools.Load<LogWindow>();
|
||||||
|
|
||||||
if (Config.ShowLogWindow)
|
|
||||||
{
|
|
||||||
LogConsole.ShowConsole(this);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LogConsole.HideConsole();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -3194,7 +3183,8 @@ namespace BizHawk.Client.EmuHawk
|
||||||
if (!string.IsNullOrEmpty(details))
|
if (!string.IsNullOrEmpty(details))
|
||||||
{
|
{
|
||||||
Sound.StopSound();
|
Sound.StopSound();
|
||||||
LogWindow.ShowReport("Dump Status Report", details, this);
|
Tools.Load<LogWindow>();
|
||||||
|
((LogWindow) Tools.Get<LogWindow>()).ShowReport("Dump Status Report", details);
|
||||||
Sound.StartSound();
|
Sound.StartSound();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -223,11 +223,6 @@ namespace BizHawk.Client.EmuHawk
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
SetImages();
|
SetImages();
|
||||||
Game = GameInfo.NullInstance;
|
Game = GameInfo.NullInstance;
|
||||||
if (Config.ShowLogWindow && !OSTailoredCode.IsUnixHost)
|
|
||||||
{
|
|
||||||
LogConsole.ShowConsole(this);
|
|
||||||
DisplayLogWindowMenuItem.Checked = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
_throttle = new Throttle();
|
_throttle = new Throttle();
|
||||||
|
|
||||||
|
@ -512,7 +507,6 @@ namespace BizHawk.Client.EmuHawk
|
||||||
public int ProgramRunLoop()
|
public int ProgramRunLoop()
|
||||||
{
|
{
|
||||||
CheckMessages(); // can someone leave a note about why this is needed?
|
CheckMessages(); // can someone leave a note about why this is needed?
|
||||||
if (!OSTailoredCode.IsUnixHost) LogConsole.PositionConsole();
|
|
||||||
|
|
||||||
// needs to be done late, after the log console snaps on top
|
// needs to be done late, after the log console snaps on top
|
||||||
// fullscreen should snap on top even harder!
|
// fullscreen should snap on top even harder!
|
||||||
|
@ -1220,11 +1214,6 @@ namespace BizHawk.Client.EmuHawk
|
||||||
Tools.Load<LuaConsole>();
|
Tools.Load<LuaConsole>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void NotifyLogWindowClosing()
|
|
||||||
{
|
|
||||||
DisplayLogWindowMenuItem.Checked = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ClickSpeedItem(int num)
|
public void ClickSpeedItem(int num)
|
||||||
{
|
{
|
||||||
if ((ModifierKeys & Keys.Control) != 0)
|
if ((ModifierKeys & Keys.Control) != 0)
|
||||||
|
@ -2407,11 +2396,6 @@ namespace BizHawk.Client.EmuHawk
|
||||||
Config.MainWndy = -1;
|
Config.MainWndy = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Config.ShowLogWindow)
|
|
||||||
{
|
|
||||||
LogConsole.SaveConfigSettings();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(path))
|
if (string.IsNullOrEmpty(path))
|
||||||
{
|
{
|
||||||
path = PathManager.DefaultIniPath;
|
path = PathManager.DefaultIniPath;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -63,7 +63,6 @@ namespace BizHawk.Client.EmuHawk
|
||||||
groupBox2.Enabled = AutosaveSRAMCheckbox.Checked;
|
groupBox2.Enabled = AutosaveSRAMCheckbox.Checked;
|
||||||
AutosaveSaveRAMSeconds = _config.FlushSaveRamFrames / 60;
|
AutosaveSaveRAMSeconds = _config.FlushSaveRamFrames / 60;
|
||||||
FrameAdvSkipLagCheckbox.Checked = _config.SkipLagFrame;
|
FrameAdvSkipLagCheckbox.Checked = _config.SkipLagFrame;
|
||||||
LogWindowAsConsoleCheckbox.Checked = _config.WIN32_CONSOLE;
|
|
||||||
LuaDuringTurboCheckbox.Checked = _config.RunLuaDuringTurbo;
|
LuaDuringTurboCheckbox.Checked = _config.RunLuaDuringTurbo;
|
||||||
cbMoviesOnDisk.Checked = _config.MoviesOnDisk;
|
cbMoviesOnDisk.Checked = _config.MoviesOnDisk;
|
||||||
cbMoviesInAWE.Checked = _config.MoviesInAWE;
|
cbMoviesInAWE.Checked = _config.MoviesInAWE;
|
||||||
|
@ -79,14 +78,6 @@ namespace BizHawk.Client.EmuHawk
|
||||||
default:
|
default:
|
||||||
throw new ArgumentOutOfRangeException();
|
throw new ArgumentOutOfRangeException();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LogConsole.ConsoleVisible)
|
|
||||||
{
|
|
||||||
LogWindowAsConsoleCheckbox.Enabled = false;
|
|
||||||
toolTip1.SetToolTip(
|
|
||||||
LogWindowAsConsoleCheckbox,
|
|
||||||
"This can not be changed while the log window is open. I know, it's annoying.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OkBtn_Click(object sender, EventArgs e)
|
private void OkBtn_Click(object sender, EventArgs e)
|
||||||
|
@ -109,7 +100,6 @@ namespace BizHawk.Client.EmuHawk
|
||||||
if (_mainForm.AutoFlushSaveRamIn > _config.FlushSaveRamFrames)
|
if (_mainForm.AutoFlushSaveRamIn > _config.FlushSaveRamFrames)
|
||||||
_mainForm.AutoFlushSaveRamIn = _config.FlushSaveRamFrames;
|
_mainForm.AutoFlushSaveRamIn = _config.FlushSaveRamFrames;
|
||||||
_config.SkipLagFrame = FrameAdvSkipLagCheckbox.Checked;
|
_config.SkipLagFrame = FrameAdvSkipLagCheckbox.Checked;
|
||||||
_config.WIN32_CONSOLE = LogWindowAsConsoleCheckbox.Checked;
|
|
||||||
_config.RunLuaDuringTurbo = LuaDuringTurboCheckbox.Checked;
|
_config.RunLuaDuringTurbo = LuaDuringTurboCheckbox.Checked;
|
||||||
_config.MoviesOnDisk = cbMoviesOnDisk.Checked;
|
_config.MoviesOnDisk = cbMoviesOnDisk.Checked;
|
||||||
_config.MoviesInAWE = cbMoviesInAWE.Checked;
|
_config.MoviesInAWE = cbMoviesInAWE.Checked;
|
||||||
|
|
|
@ -101,7 +101,6 @@
|
||||||
<Compile Include="Win32/ThreadHacks.cs" />
|
<Compile Include="Win32/ThreadHacks.cs" />
|
||||||
<Compile Include="Win32/Win32Imports.cs" />
|
<Compile Include="Win32/Win32Imports.cs" />
|
||||||
<Compile Include="Win32\AVIWriterImports.cs" />
|
<Compile Include="Win32\AVIWriterImports.cs" />
|
||||||
<Compile Include="Win32\ConsoleImports.cs" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
|
|
|
@ -1,50 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace BizHawk.Common
|
|
||||||
{
|
|
||||||
public static class ConsoleImports
|
|
||||||
{
|
|
||||||
public enum FileType : uint
|
|
||||||
{
|
|
||||||
FileTypeUnknown = 0,
|
|
||||||
FileTypeDisk = 1,
|
|
||||||
FileTypeChar = 2,
|
|
||||||
FileTypePipe = 3,
|
|
||||||
FileTypeRemote = 0x8000
|
|
||||||
}
|
|
||||||
|
|
||||||
[DllImport("kernel32.dll")]
|
|
||||||
public static extern FileType GetFileType(IntPtr hFile);
|
|
||||||
|
|
||||||
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
|
|
||||||
public static extern IntPtr GetCommandLine();
|
|
||||||
|
|
||||||
[DllImport("kernel32.dll", SetLastError = true)]
|
|
||||||
public static extern IntPtr GetConsoleWindow();
|
|
||||||
|
|
||||||
[DllImport("user32.dll", SetLastError = true)]
|
|
||||||
public static extern bool SetForegroundWindow(IntPtr hWnd);
|
|
||||||
|
|
||||||
[DllImport("kernel32.dll", SetLastError = true)]
|
|
||||||
public static extern bool AttachConsole(int dwProcessId);
|
|
||||||
|
|
||||||
[DllImport("kernel32.dll", SetLastError = true)]
|
|
||||||
public static extern bool AllocConsole();
|
|
||||||
|
|
||||||
[DllImport("kernel32.dll", SetLastError = false)]
|
|
||||||
public static extern bool FreeConsole();
|
|
||||||
|
|
||||||
[DllImport("kernel32.dll", SetLastError = true)]
|
|
||||||
public static extern IntPtr GetStdHandle(int nStdHandle);
|
|
||||||
|
|
||||||
[DllImport("kernel32.dll", SetLastError = true)]
|
|
||||||
public static extern bool SetStdHandle(int nStdHandle, IntPtr hConsoleOutput);
|
|
||||||
|
|
||||||
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
|
||||||
public static extern IntPtr CreateFile(string fileName, int desiredAccess, int shareMode, IntPtr securityAttributes, int creationDisposition, int flagsAndAttributes, IntPtr templateFile);
|
|
||||||
|
|
||||||
[DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true)]
|
|
||||||
public static extern bool CloseHandle(IntPtr handle);
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue