2012-04-16 08:18:41 +00:00
|
|
|
|
using System;
|
2013-10-27 22:13:08 +00:00
|
|
|
|
using System.Linq;
|
2012-04-16 08:18:41 +00:00
|
|
|
|
using System.Runtime.InteropServices;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Windows.Forms;
|
|
|
|
|
using System.Drawing;
|
|
|
|
|
using System.Drawing.Drawing2D;
|
|
|
|
|
using System.Drawing.Imaging;
|
|
|
|
|
|
2013-11-04 00:36:15 +00:00
|
|
|
|
using BizHawk.Common;
|
2013-11-04 01:39:19 +00:00
|
|
|
|
using BizHawk.Emulation.Common;
|
2013-10-25 00:57:23 +00:00
|
|
|
|
using BizHawk.Client.Common;
|
|
|
|
|
|
2014-01-27 00:02:21 +00:00
|
|
|
|
using BizHawk.Bizware.BizwareGL;
|
|
|
|
|
|
2013-11-03 03:54:37 +00:00
|
|
|
|
namespace BizHawk.Client.EmuHawk
|
2012-04-16 08:18:41 +00:00
|
|
|
|
{
|
|
|
|
|
public class DisplayFilterAnalysisReport
|
|
|
|
|
{
|
|
|
|
|
public bool Success;
|
|
|
|
|
public Size OutputSize;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public class DisplayManager : IDisposable
|
|
|
|
|
{
|
|
|
|
|
public DisplayManager()
|
|
|
|
|
{
|
|
|
|
|
//have at least something here at the start
|
2014-01-27 00:02:21 +00:00
|
|
|
|
luaNativeSurfacePreOSD = new BitmapBuffer(1, 1);
|
2012-04-16 08:18:41 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-01-27 00:02:21 +00:00
|
|
|
|
readonly SwappableBitmapBufferSet sourceSurfaceSet = new SwappableBitmapBufferSet();
|
2012-09-02 14:54:30 +00:00
|
|
|
|
|
2013-11-23 00:51:31 +00:00
|
|
|
|
public bool NeedsToPaint { get; set; }
|
2012-09-02 14:54:30 +00:00
|
|
|
|
|
|
|
|
|
DisplaySurface luaEmuSurface = null;
|
|
|
|
|
public void PreFrameUpdateLuaSource()
|
|
|
|
|
{
|
|
|
|
|
luaEmuSurface = luaEmuSurfaceSet.GetCurrent();
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-21 18:01:24 +00:00
|
|
|
|
/// <summary>update Global.RenderPanel from the passed IVideoProvider</summary>
|
2012-04-16 08:18:41 +00:00
|
|
|
|
public void UpdateSource(IVideoProvider videoProvider)
|
2012-09-21 18:01:24 +00:00
|
|
|
|
{
|
2014-01-27 06:03:18 +00:00
|
|
|
|
UpdateSourceEx(videoProvider, GlobalWin.PresentationPanel);
|
2012-09-21 18:01:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// update the passed IRenderer with the passed IVideoProvider
|
|
|
|
|
/// </summary>
|
2014-01-27 06:03:18 +00:00
|
|
|
|
public void UpdateSourceEx(IVideoProvider videoProvider, PresentationPanel renderPanel)
|
2012-04-16 08:18:41 +00:00
|
|
|
|
{
|
|
|
|
|
var newPendingSurface = sourceSurfaceSet.AllocateSurface(videoProvider.BufferWidth, videoProvider.BufferHeight, false);
|
2012-06-10 23:27:30 +00:00
|
|
|
|
newPendingSurface.AcceptIntArray(videoProvider.GetVideoBuffer());
|
2012-04-16 08:18:41 +00:00
|
|
|
|
sourceSurfaceSet.SetPending(newPendingSurface);
|
2012-06-10 23:27:30 +00:00
|
|
|
|
|
|
|
|
|
if (renderPanel == null) return;
|
2012-06-10 20:48:04 +00:00
|
|
|
|
|
2012-09-21 18:01:24 +00:00
|
|
|
|
currNativeWidth = renderPanel.NativeSize.Width;
|
|
|
|
|
currNativeHeight = renderPanel.NativeSize.Height;
|
2012-06-10 23:27:30 +00:00
|
|
|
|
|
2012-07-15 07:38:36 +00:00
|
|
|
|
currentSourceSurface = sourceSurfaceSet.GetCurrent();
|
|
|
|
|
|
|
|
|
|
if (currentSourceSurface == null) return;
|
|
|
|
|
|
2012-06-10 23:27:30 +00:00
|
|
|
|
//if we're configured to use a scaling filter, apply it now
|
|
|
|
|
//SHOULD THIS BE RUN REPEATEDLY?
|
|
|
|
|
//some filters may need to run repeatedly (temporal interpolation, ntsc scanline field alternating)
|
|
|
|
|
//but its sort of wasted work.
|
2012-07-15 09:13:46 +00:00
|
|
|
|
CheckFilter();
|
2012-06-10 23:27:30 +00:00
|
|
|
|
|
|
|
|
|
int w = currNativeWidth;
|
|
|
|
|
int h = currNativeHeight;
|
|
|
|
|
|
2012-09-02 14:54:30 +00:00
|
|
|
|
|
2012-06-10 23:27:30 +00:00
|
|
|
|
DisplaySurface luaSurface = luaNativeSurfaceSet.GetCurrent();
|
|
|
|
|
|
|
|
|
|
//do we have anything to do?
|
|
|
|
|
//bool complexComposite = false;
|
|
|
|
|
//if (luaEmuSurface != null) complexComposite = true;
|
|
|
|
|
//if (luaSurface != null) complexComposite = true;
|
|
|
|
|
|
2014-01-27 00:02:21 +00:00
|
|
|
|
BitmapBuffer surfaceToRender = filteredSurface;
|
2012-07-15 09:13:46 +00:00
|
|
|
|
if (surfaceToRender == null) surfaceToRender = currentSourceSurface;
|
|
|
|
|
|
2012-09-21 18:01:24 +00:00
|
|
|
|
renderPanel.Clear(Color.FromArgb(videoProvider.BackgroundColor));
|
|
|
|
|
renderPanel.Render(surfaceToRender);
|
2014-01-27 00:02:21 +00:00
|
|
|
|
|
|
|
|
|
//GL TODO - lua unhooked
|
2012-06-10 23:27:30 +00:00
|
|
|
|
if (luaEmuSurface != null)
|
2012-09-02 14:54:30 +00:00
|
|
|
|
{
|
2014-01-27 00:02:21 +00:00
|
|
|
|
renderPanel.RenderOverlay(luaEmuSurface);
|
2012-09-02 14:54:30 +00:00
|
|
|
|
}
|
2012-06-10 23:27:30 +00:00
|
|
|
|
|
2012-09-21 18:01:24 +00:00
|
|
|
|
RenderOSD((IBlitter)renderPanel);
|
2012-06-10 23:27:30 +00:00
|
|
|
|
|
2012-09-21 18:01:24 +00:00
|
|
|
|
renderPanel.Present();
|
2012-06-10 20:48:04 +00:00
|
|
|
|
|
2012-07-15 09:13:46 +00:00
|
|
|
|
if (filteredSurface != null)
|
|
|
|
|
filteredSurface.Dispose();
|
|
|
|
|
filteredSurface = null;
|
2013-08-23 02:40:14 +00:00
|
|
|
|
|
|
|
|
|
NeedsToPaint = false;
|
2012-04-16 08:18:41 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool Disposed { get; private set; }
|
|
|
|
|
|
|
|
|
|
public void Dispose()
|
|
|
|
|
{
|
|
|
|
|
if (Disposed) return;
|
|
|
|
|
Disposed = true;
|
|
|
|
|
}
|
|
|
|
|
|
2014-01-27 00:02:21 +00:00
|
|
|
|
BitmapBuffer currentSourceSurface, filteredSurface;
|
2012-04-16 08:18:41 +00:00
|
|
|
|
|
|
|
|
|
//the surface to use to render a lua layer at native resolution (under the OSD)
|
2014-01-27 00:02:21 +00:00
|
|
|
|
BitmapBuffer luaNativeSurfacePreOSD;
|
2012-04-16 08:18:41 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SwappableDisplaySurfaceSet luaNativeSurfaceSet = new SwappableDisplaySurfaceSet();
|
|
|
|
|
public void SetLuaSurfaceNativePreOSD(DisplaySurface surface) { luaNativeSurfaceSet.SetPending(surface); }
|
|
|
|
|
public DisplaySurface GetLuaSurfaceNative()
|
|
|
|
|
{
|
|
|
|
|
return luaNativeSurfaceSet.AllocateSurface(currNativeWidth, currNativeHeight);
|
|
|
|
|
}
|
|
|
|
|
|
2012-05-06 07:09:04 +00:00
|
|
|
|
SwappableDisplaySurfaceSet luaEmuSurfaceSet = new SwappableDisplaySurfaceSet();
|
|
|
|
|
public void SetLuaSurfaceEmu(DisplaySurface surface) { luaEmuSurfaceSet.SetPending(surface); }
|
|
|
|
|
public DisplaySurface GetLuaEmuSurfaceEmu()
|
|
|
|
|
{
|
|
|
|
|
int width = 1, height = 1;
|
|
|
|
|
if (currentSourceSurface != null)
|
|
|
|
|
width = currentSourceSurface.Width;
|
|
|
|
|
if (currentSourceSurface != null)
|
|
|
|
|
height = currentSourceSurface.Height;
|
|
|
|
|
return luaEmuSurfaceSet.AllocateSurface(width, height);
|
|
|
|
|
}
|
|
|
|
|
|
2012-04-16 08:18:41 +00:00
|
|
|
|
int currNativeWidth, currNativeHeight;
|
2012-06-10 23:27:30 +00:00
|
|
|
|
|
2012-04-16 08:18:41 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// suspends the display manager so that tricky things can be changed without the display thread going in and getting all confused and hating
|
|
|
|
|
/// </summary>
|
|
|
|
|
public void Suspend()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// resumes the display manager after a suspend
|
|
|
|
|
/// </summary>
|
|
|
|
|
public void Resume()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-21 18:01:24 +00:00
|
|
|
|
void RenderOSD(IBlitter renderPanel)
|
2012-04-16 08:18:41 +00:00
|
|
|
|
{
|
2013-11-03 16:07:58 +00:00
|
|
|
|
GlobalWin.OSD.Begin(renderPanel);
|
2012-09-21 18:01:24 +00:00
|
|
|
|
renderPanel.Open();
|
2013-11-03 16:07:58 +00:00
|
|
|
|
GlobalWin.OSD.DrawScreenInfo(renderPanel);
|
|
|
|
|
GlobalWin.OSD.DrawMessages(renderPanel);
|
2012-09-21 18:01:24 +00:00
|
|
|
|
renderPanel.Close();
|
2012-06-10 23:27:30 +00:00
|
|
|
|
}
|
2012-06-10 20:48:04 +00:00
|
|
|
|
|
2012-07-15 08:50:24 +00:00
|
|
|
|
void CheckFilter()
|
|
|
|
|
{
|
|
|
|
|
IDisplayFilter filter = null;
|
|
|
|
|
switch (Global.Config.TargetDisplayFilter)
|
|
|
|
|
{
|
2014-01-27 00:02:21 +00:00
|
|
|
|
//TODO GL - filters removed
|
|
|
|
|
//case 0:
|
|
|
|
|
// //no filter
|
|
|
|
|
// break;
|
|
|
|
|
//case 1:
|
|
|
|
|
// filter = new Hq2xBase_2xSai();
|
|
|
|
|
// break;
|
|
|
|
|
//case 2:
|
|
|
|
|
// filter = new Hq2xBase_Super2xSai();
|
|
|
|
|
// break;
|
|
|
|
|
//case 3:
|
|
|
|
|
// filter = new Hq2xBase_SuperEagle();
|
|
|
|
|
// break;
|
|
|
|
|
//case 4:
|
|
|
|
|
// filter = new Scanlines2x();
|
|
|
|
|
// break;
|
2012-07-15 08:50:24 +00:00
|
|
|
|
|
|
|
|
|
}
|
2012-07-15 09:13:46 +00:00
|
|
|
|
if (filter == null)
|
|
|
|
|
filteredSurface = null;
|
|
|
|
|
else
|
|
|
|
|
filteredSurface = filter.Execute(currentSourceSurface);
|
2012-07-15 08:50:24 +00:00
|
|
|
|
}
|
2012-06-10 20:48:04 +00:00
|
|
|
|
|
2014-01-27 00:02:21 +00:00
|
|
|
|
SwappableBitmapBufferSet nativeDisplaySurfaceSet = new SwappableBitmapBufferSet();
|
2012-04-16 08:18:41 +00:00
|
|
|
|
|
2013-02-25 01:23:03 +00:00
|
|
|
|
//Thread displayThread;
|
2012-04-16 08:18:41 +00:00
|
|
|
|
}
|
|
|
|
|
}
|