OSD info on branch hover is mandatory, so I'm not removing it. drawing the branch OSD-framebuffer on the emulator screen is barely possible without butchering everything, so I'm not doing it. instead, keep both core and client framebuffers and use them where they make sense: osd FB shows up on hover, core FB goes to emulator screen on branch load.
This commit is contained in:
feos 2019-06-09 20:34:14 +03:00
parent 1ac27e3c25
commit f5bcdc4aba
5 changed files with 133 additions and 112 deletions

View File

@ -60,6 +60,8 @@ namespace BizHawk.Client.Common
public static BinaryStateLump BranchInputLog { get; private set; }
[Name("Branches\\FrameBuffer", "bmp")]
public static BinaryStateLump BranchFrameBuffer { get; private set; }
[Name("Branches\\CoreFrameBuffer", "bmp")]
public static BinaryStateLump BranchCoreFrameBuffer { get; private set; }
[Name("Branches\\LagLog", "bin")]
public static BinaryStateLump BranchLagLog { get; private set; }
[Name("Branches\\Header", "json")]

View File

@ -12,6 +12,7 @@ namespace BizHawk.Client.Common
public int Frame { get; set; }
public byte[] CoreData { get; set; }
public IStringLog InputLog { get; set; }
public BitmapBuffer CoreFrameBuffer { get; set; }
public BitmapBuffer OSDFrameBuffer { get; set; }
public TasLagLog LagLog { get; set; }
public TasMovieChangeLog ChangeLog { get; set; }
@ -50,6 +51,7 @@ namespace BizHawk.Client.Common
var ncore = new IndexedStateLump(BinaryStateLump.BranchCoreData);
var ninput = new IndexedStateLump(BinaryStateLump.BranchInputLog);
var nframebuffer = new IndexedStateLump(BinaryStateLump.BranchFrameBuffer);
var ncoreframebuffer = new IndexedStateLump(BinaryStateLump.BranchCoreFrameBuffer);
var nlaglog = new IndexedStateLump(BinaryStateLump.BranchLagLog);
var nmarkers = new IndexedStateLump(BinaryStateLump.BranchMarkers);
var nusertext = new IndexedStateLump(BinaryStateLump.BranchUserText);
@ -86,6 +88,12 @@ namespace BizHawk.Client.Common
QuickBmpFile.Save(vp, s, b.OSDFrameBuffer.Width, b.OSDFrameBuffer.Height);
});
bs.PutLump(ncoreframebuffer, delegate(Stream s)
{
var vp = new BitmapBufferVideoProvider(b.CoreFrameBuffer);
QuickBmpFile.Save(vp, s, b.CoreFrameBuffer.Width, b.CoreFrameBuffer.Height);
});
bs.PutLump(nlaglog, delegate(BinaryWriter bw)
{
b.LagLog.Save(bw);
@ -105,6 +113,7 @@ namespace BizHawk.Client.Common
ncore.Increment();
ninput.Increment();
nframebuffer.Increment();
ncoreframebuffer.Increment();
nlaglog.Increment();
nmarkers.Increment();
nusertext.Increment();
@ -117,6 +126,7 @@ namespace BizHawk.Client.Common
var ncore = new IndexedStateLump(BinaryStateLump.BranchCoreData);
var ninput = new IndexedStateLump(BinaryStateLump.BranchInputLog);
var nframebuffer = new IndexedStateLump(BinaryStateLump.BranchFrameBuffer);
var ncoreframebuffer = new IndexedStateLump(BinaryStateLump.BranchCoreFrameBuffer);
var nlaglog = new IndexedStateLump(BinaryStateLump.BranchLagLog);
var nmarkers = new IndexedStateLump(BinaryStateLump.BranchMarkers);
var nusertext = new IndexedStateLump(BinaryStateLump.BranchUserText);
@ -180,7 +190,14 @@ namespace BizHawk.Client.Common
b.OSDFrameBuffer = new BitmapBuffer(vp.BufferWidth, vp.BufferHeight, vp.VideoBuffer);
});
bl.GetLump(nlaglog, true, delegate(BinaryReader br)
bl.GetLump(ncoreframebuffer, false, delegate(Stream s, long length)
{
var vp = new QuickBmpFile.LoadedBMP();
QuickBmpFile.Load(vp, s);
b.CoreFrameBuffer = new BitmapBuffer(vp.BufferWidth, vp.BufferHeight, vp.VideoBuffer);
});
bl.GetLump(nlaglog, false, delegate(BinaryReader br)
{
b.LagLog = new TasLagLog();
b.LagLog.Load(br);
@ -217,6 +234,7 @@ namespace BizHawk.Client.Common
ncore.Increment();
ninput.Increment();
nframebuffer.Increment();
ncoreframebuffer.Increment();
nlaglog.Increment();
nmarkers.Increment();
nusertext.Increment();

View File

@ -2023,7 +2023,7 @@ namespace BizHawk.Client.EmuHawk
}
}
private BitmapBuffer MakeScreenshotImage()
public BitmapBuffer MakeScreenshotImage()
{
return GlobalWin.DisplayManager.RenderVideoProvider(_currentVideoProvider);
}

View File

@ -182,6 +182,7 @@ namespace BizHawk.Client.EmuHawk
Frame = Tastudio.Emulator.Frame,
CoreData = (byte[])(Tastudio.StatableEmulator.SaveStateBinary().Clone()),
InputLog = Movie.InputLog.Clone(),
CoreFrameBuffer = GlobalWin.MainForm.MakeScreenshotImage(),
OSDFrameBuffer = GlobalWin.MainForm.CaptureOSD(),
LagLog = Movie.TasLagLog.Clone(),
ChangeLog = new TasMovieChangeLog(Movie),
@ -203,7 +204,7 @@ namespace BizHawk.Client.EmuHawk
var stateInfo = new KeyValuePair<int, byte[]>(branch.Frame, branch.CoreData);
Tastudio.LoadState(stateInfo);
Movie.TasStateManager.Capture(true);
QuickBmpFile.Copy(new BitmapBufferVideoProvider(branch.OSDFrameBuffer), Tastudio.VideoProvider);
QuickBmpFile.Copy(new BitmapBufferVideoProvider(branch.CoreFrameBuffer), Tastudio.VideoProvider);
if (Tastudio.Settings.OldControlSchemeForBranches && Tastudio.TasPlaybackBox.RecordingMode)
Movie.Truncate(branch.Frame);

View File

@ -1,120 +1,120 @@
using System.Drawing;
using System.Windows.Forms;
using System.Drawing;
using System.Windows.Forms;
using BizHawk.Client.Common;
// We pretend it's a tooltip kind of thing, so show only the actual contents
// and avoid stealing forcus, while still being topmost
// http://stackoverflow.com/a/25219399/2792852
// This is not an actual tooltip, because they can't reliably fade in and out with trasparency
namespace BizHawk.Client.EmuHawk
{
public partial class ScreenshotForm : Form
namespace BizHawk.Client.EmuHawk
{
public partial class ScreenshotForm : Form
{
private const int WS_EX_TOPMOST = 0x00000008;
private const int Interval = 40;
private const int Interval = 40;
private const double AlphaStep = 0.125;
private readonly Timer _showTimer = new Timer();
private readonly Timer _hideTimer = new Timer();
private TasBranch _branch;
private int _drawingHeight;
new public Font Font;
new public int Padding;
new public string Text;
public ScreenshotForm()
{
InitializeComponent();
var fontSize = 10;
var fontStyle = FontStyle.Regular;
Font = new Font(FontFamily.GenericMonospace, fontSize, fontStyle);
_drawingHeight = 0;
Padding = 0;
Opacity = 0;
_showTimer.Interval = Interval;
_showTimer.Tick += (sender, e) =>
{
if ((Opacity += AlphaStep) >= 1)
{
_showTimer.Stop();
}
};
_hideTimer.Interval = Interval;
_hideTimer.Tick += (sender, e) =>
{
if ((Opacity -= AlphaStep) <= 0)
{
_hideTimer.Stop();
Hide();
}
};
}
public void UpdateValues(TasBranch branch, Point location , int width, int height, int padding)
{
_branch = branch;
Width = width;
Padding = padding;
_drawingHeight = height;
Text = _branch.UserText;
Location = location;
if (Padding > 0)
{
Padding += 2;
}
Height = _drawingHeight + Padding;
Refresh();
}
protected override void OnPaint(PaintEventArgs e)
{
_branch.OSDFrameBuffer.DiscardAlpha();
var bitmap = _branch.OSDFrameBuffer.ToSysdrawingBitmap();
e.Graphics.DrawImage(bitmap, new Rectangle(0, 0, Width, _drawingHeight));
if (Padding > 0)
{
e.Graphics.DrawRectangle(new Pen(Brushes.Black), new Rectangle(new Point(0, _drawingHeight), new Size(Width - 1, Padding - 1)));
e.Graphics.DrawString(Text, Font, Brushes.Black, new Rectangle(2, _drawingHeight, Width - 2, Height));
}
base.OnPaint(e);
}
public void FadeIn()
{
_showTimer.Stop();
_hideTimer.Stop();
_showTimer.Start();
Show();
}
public void FadeOut()
{
_showTimer.Stop();
_hideTimer.Stop();
_hideTimer.Start();
}
// avoid stealing focus
protected override bool ShowWithoutActivation => true;
protected override CreateParams CreateParams
{
get
{
CreateParams createParams = base.CreateParams;
createParams.ExStyle |= WS_EX_TOPMOST;
return createParams;
}
}
}
}
private readonly Timer _showTimer = new Timer();
private readonly Timer _hideTimer = new Timer();
private TasBranch _branch;
private int _drawingHeight;
new public Font Font;
new public int Padding;
new public string Text;
public ScreenshotForm()
{
InitializeComponent();
var fontSize = 10;
var fontStyle = FontStyle.Regular;
Font = new Font(FontFamily.GenericMonospace, fontSize, fontStyle);
_drawingHeight = 0;
Padding = 0;
Opacity = 0;
_showTimer.Interval = Interval;
_showTimer.Tick += (sender, e) =>
{
if ((Opacity += AlphaStep) >= 1)
{
_showTimer.Stop();
}
};
_hideTimer.Interval = Interval;
_hideTimer.Tick += (sender, e) =>
{
if ((Opacity -= AlphaStep) <= 0)
{
_hideTimer.Stop();
Hide();
}
};
}
public void UpdateValues(TasBranch branch, Point location , int width, int height, int padding)
{
_branch = branch;
Width = width;
Padding = padding;
_drawingHeight = height;
Text = _branch.UserText;
Location = location;
if (Padding > 0)
{
Padding += 2;
}
Height = _drawingHeight + Padding;
Refresh();
}
protected override void OnPaint(PaintEventArgs e)
{
_branch.OSDFrameBuffer.DiscardAlpha();
var bitmap = _branch.OSDFrameBuffer.ToSysdrawingBitmap();
e.Graphics.DrawImage(bitmap, new Rectangle(0, 0, Width, _drawingHeight));
if (Padding > 0)
{
e.Graphics.DrawRectangle(new Pen(Brushes.Black), new Rectangle(new Point(0, _drawingHeight), new Size(Width - 1, Padding - 1)));
e.Graphics.DrawString(Text, Font, Brushes.Black, new Rectangle(2, _drawingHeight, Width - 2, Height));
}
base.OnPaint(e);
}
public void FadeIn()
{
_showTimer.Stop();
_hideTimer.Stop();
_showTimer.Start();
Show();
}
public void FadeOut()
{
_showTimer.Stop();
_hideTimer.Stop();
_hideTimer.Start();
}
// avoid stealing focus
protected override bool ShowWithoutActivation => true;
protected override CreateParams CreateParams
{
get
{
CreateParams createParams = base.CreateParams;
createParams.ExStyle |= WS_EX_TOPMOST;
return createParams;
}
}
}
}