massive displaymanager/renderpanel refactor. All useful logic is now compact and in DisplayManager. Also, remove the old filter infrastructure, its totally outdated now

This commit is contained in:
zeromus 2014-01-28 04:39:27 +00:00
parent 0d29401101
commit 2275ec234f
18 changed files with 613 additions and 569 deletions

View File

@ -49,7 +49,6 @@ namespace BizHawk.Client.Common
public int Input_Hotkey_OverrideOptions = 0;
public bool StackOSDMessages = true;
public int TargetZoomFactor = 2;
public int TargetDisplayFilter = 0;
public int TargetScanlineFilterIntensity = 0; //choose between 0 and 256
public RecentFiles RecentRoms = new RecentFiles(8);
public bool PauseWhenMenuActivated = true;

View File

@ -251,6 +251,7 @@ namespace BizHawk.Client.Common
var inChangeSequence = false;
// try to set up the buffer in advance so we dont ever have exceptions in here
//zeromus says: this sets off red flags for me. vecna got an exception that might be related to this inflating to 2x the input size. we should add an emergency check, or analyze how much it could inflate by (perhaps 3x would be adequate in every case?)
if (_tempBuf.Length < currentState.Length)
{
_tempBuf = new byte[currentState.Length * 2];

View File

@ -382,9 +382,9 @@
<Compile Include="CustomControls\Win32.cs" />
<Compile Include="DisplayManager\DisplayManager.cs" />
<Compile Include="DisplayManager\DisplaySurface.cs" />
<Compile Include="DisplayManager\IDisplayFilter.cs" />
<Compile Include="DisplayManager\OSDManager.cs" />
<Compile Include="DisplayManager\SwappableBitmapBufferSet.cs" />
<Compile Include="DisplayManager\SwappableDisplaySurfaceSet.cs" />
<Compile Include="DisplayManager\TextureFrugalizer.cs" />
<Compile Include="GlobalWin.cs" />
<Compile Include="Input\GamePad.cs" Condition=" '$(OS)' == 'Windows_NT' " />
<Compile Include="Input\GamePad360.cs" />
@ -453,6 +453,7 @@
<Compile Include="NameStateForm.Designer.cs">
<DependentUpon>NameStateForm.cs</DependentUpon>
</Compile>
<Compile Include="PresentationPanel.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ScanlineSlider.cs">
@ -1155,7 +1156,6 @@
<Compile Include="tools\InputPrompt.Designer.cs">
<DependentUpon>InputPrompt.cs</DependentUpon>
</Compile>
<Compile Include="RenderPanel.cs" />
<Compile Include="ScreenSaver.cs" />
<Compile Include="Sound.cs" />
<Compile Include="tools\ToolBox.cs">
@ -1415,9 +1415,7 @@
<Install>true</Install>
</BootstrapperPackage>
</ItemGroup>
<ItemGroup>
<Folder Include="DisplayManager\Filters\" />
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.

View File

@ -17,93 +17,30 @@ using BizHawk.Bizware.BizwareGL;
namespace BizHawk.Client.EmuHawk
{
public class DisplayFilterAnalysisReport
{
public bool Success;
public Size OutputSize;
}
/// <summary>
/// A DisplayManager is destined forevermore to drive the PresentationPanel it gets initialized with.
/// Its job is to receive OSD and emulator outputs, and produce one single buffer (BitampBuffer? Texture2d?) for display by the PresentationPanel.
/// Details TBD
/// </summary>
public class DisplayManager : IDisposable
{
public DisplayManager()
public DisplayManager(PresentationPanel presentationPanel)
{
//have at least something here at the start
luaNativeSurfacePreOSD = new BitmapBuffer(1, 1);
}
GL = GlobalWin.GL;
this.presentationPanel = presentationPanel;
GraphicsControl = this.presentationPanel.GraphicsControl;
readonly SwappableBitmapBufferSet sourceSurfaceSet = new SwappableBitmapBufferSet();
//it's sort of important for these to be initialized to something nonzero
currEmuWidth = currEmuHeight = 1;
public bool NeedsToPaint { get; set; }
Renderer = new GuiRenderer(GL);
VideoTextureFrugalizer = new TextureFrugalizer(GL);
LuaEmuTextureFrugalizer = new TextureFrugalizer(GL);
DisplaySurface luaEmuSurface = null;
public void PreFrameUpdateLuaSource()
{
luaEmuSurface = luaEmuSurfaceSet.GetCurrent();
}
/// <summary>update Global.RenderPanel from the passed IVideoProvider</summary>
public void UpdateSource(IVideoProvider videoProvider)
{
UpdateSourceEx(videoProvider, GlobalWin.PresentationPanel);
}
/// <summary>
/// update the passed IRenderer with the passed IVideoProvider
/// </summary>
public void UpdateSourceEx(IVideoProvider videoProvider, PresentationPanel renderPanel)
{
var newPendingSurface = sourceSurfaceSet.AllocateSurface(videoProvider.BufferWidth, videoProvider.BufferHeight, false);
newPendingSurface.AcceptIntArray(videoProvider.GetVideoBuffer());
sourceSurfaceSet.SetPending(newPendingSurface);
if (renderPanel == null) return;
currNativeWidth = renderPanel.NativeSize.Width;
currNativeHeight = renderPanel.NativeSize.Height;
currentSourceSurface = sourceSurfaceSet.GetCurrent();
if (currentSourceSurface == null) return;
//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.
CheckFilter();
int w = currNativeWidth;
int h = currNativeHeight;
DisplaySurface luaSurface = luaNativeSurfaceSet.GetCurrent();
//do we have anything to do?
//bool complexComposite = false;
//if (luaEmuSurface != null) complexComposite = true;
//if (luaSurface != null) complexComposite = true;
BitmapBuffer surfaceToRender = filteredSurface;
if (surfaceToRender == null) surfaceToRender = currentSourceSurface;
renderPanel.Clear(Color.FromArgb(videoProvider.BackgroundColor));
renderPanel.Render(surfaceToRender);
//GL TODO - lua unhooked
if (luaEmuSurface != null)
{
renderPanel.RenderOverlay(luaEmuSurface);
}
RenderOSD((IBlitter)renderPanel);
renderPanel.Present();
if (filteredSurface != null)
filteredSurface.Dispose();
filteredSurface = null;
NeedsToPaint = false;
using (var xml = typeof(Program).Assembly.GetManifestResourceStream("BizHawk.Client.EmuHawk.Resources.courier16px.fnt"))
using (var tex = typeof(Program).Assembly.GetManifestResourceStream("BizHawk.Client.EmuHawk.Resources.courier16px_0.png"))
TheOneFont = new StringRenderer(GL, xml, tex);
}
public bool Disposed { get; private set; }
@ -112,18 +49,117 @@ namespace BizHawk.Client.EmuHawk
{
if (Disposed) return;
Disposed = true;
VideoTextureFrugalizer.Dispose();
LuaEmuTextureFrugalizer.Dispose();
}
BitmapBuffer currentSourceSurface, filteredSurface;
//rendering resources:
IGL GL;
StringRenderer TheOneFont;
GuiRenderer Renderer;
//the surface to use to render a lua layer at native resolution (under the OSD)
BitmapBuffer luaNativeSurfacePreOSD;
//layer resources
DisplaySurface luaEmuSurface = null;
PresentationPanel presentationPanel; //well, its the final layer's target, at least
GraphicsControl GraphicsControl; //well, its the final layer's target, at least
public bool NeedsToPaint { get; set; }
public void PreFrameUpdateLuaSource()
{
luaEmuSurface = luaEmuSurfaceSet.GetCurrent();
}
/// <summary>
/// these variables will track the dimensions of the last frame's (or the next frame? this is confusing) emulator native output size
/// </summary>
int currEmuWidth, currEmuHeight;
TextureFrugalizer VideoTextureFrugalizer, LuaEmuTextureFrugalizer;
/// <summary>
/// This will receive an emulated output frame from an IVideoProvider and run it through the complete frame processing pipeline
/// Then it will stuff it into the bound PresentationPanel
/// </summary>
public void UpdateSource(IVideoProvider videoProvider)
{
//wrap the videoprovider data in a BitmapBuffer (no point to refactoring that many IVidepProviders)
BitmapBuffer bb = new BitmapBuffer(videoProvider.BufferWidth, videoProvider.BufferHeight, videoProvider.GetVideoBuffer());
//record the size of what we received, since lua and stuff is gonna want to draw onto it
currEmuWidth = bb.Width;
currEmuHeight = bb.Height;
//now, acquire the data sent from the videoProvider into a texture
var videoTexture = VideoTextureFrugalizer.Get(bb);
//acquire the lua emu surface as a texture
Texture2d luaEmuTexture = null;
if (luaEmuSurface != null)
luaEmuTexture = LuaEmuTextureFrugalizer.Get(luaEmuSurface);
//begin drawing to the PresentationPanel:
GraphicsControl.Begin();
//1. clear it with the background color that the emulator specified
GL.SetClearColor(Color.FromArgb(videoProvider.BackgroundColor));
GL.Clear(OpenTK.Graphics.OpenGL.ClearBufferMask.ColorBufferBit);
//2. begin 2d rendering
Renderer.Begin(GraphicsControl.Width, GraphicsControl.Height);
//3. figure out how to draw the emulator output content
var LL = new LetterboxingLogic(GraphicsControl.Width, GraphicsControl.Height, bb.Width, bb.Height);
//4. draw the emulator content
Renderer.SetBlendState(GL.BlendNone);
Renderer.Modelview.Push();
Renderer.Modelview.Translate(LL.dx, LL.dy);
Renderer.Modelview.Scale(LL.finalScale);
if (Global.Config.DispBlurry)
videoTexture.SetFilterLinear();
else
videoTexture.SetFilterNearest();
Renderer.Draw(videoTexture);
//4.b draw the "lua emu surface" which is designed for art matching up exactly with the emulator output
Renderer.SetBlendState(GL.BlendNormal);
if(luaEmuTexture != null) Renderer.Draw(luaEmuTexture);
Renderer.Modelview.Pop();
//(should we draw native layer lua here? thats broken right now)
//5. draw the native layer OSD
MyBlitter myBlitter = new MyBlitter(this);
myBlitter.ClipBounds = new Rectangle(0, 0, GraphicsControl.Width, GraphicsControl.Height);
GlobalWin.OSD.Begin(myBlitter);
GlobalWin.OSD.DrawScreenInfo(myBlitter);
GlobalWin.OSD.DrawMessages(myBlitter);
//6. finished drawing
Renderer.End();
//7. apply the vsync setting (should probably try to avoid repeating this)
bool vsync = Global.Config.VSyncThrottle || Global.Config.VSync;
presentationPanel.GraphicsControl.SetVsync(vsync);
//7. present and conclude drawing
presentationPanel.GraphicsControl.SwapBuffers();
presentationPanel.GraphicsControl.End();
//cleanup:
bb.Dispose();
NeedsToPaint = false; //??
}
SwappableDisplaySurfaceSet luaNativeSurfaceSet = new SwappableDisplaySurfaceSet();
public void SetLuaSurfaceNativePreOSD(DisplaySurface surface) { luaNativeSurfaceSet.SetPending(surface); }
public DisplaySurface GetLuaSurfaceNative()
{
int currNativeWidth = presentationPanel.NativeSize.Width;
int currNativeHeight = presentationPanel.NativeSize.Height;
return luaNativeSurfaceSet.AllocateSurface(currNativeWidth, currNativeHeight);
}
@ -131,71 +167,74 @@ namespace BizHawk.Client.EmuHawk
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);
return luaEmuSurfaceSet.AllocateSurface(currEmuWidth, currEmuHeight);
}
int currNativeWidth, currNativeHeight;
//helper classes:
/// <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()
class MyBlitter : IBlitter
{
}
/// <summary>
/// resumes the display manager after a suspend
/// </summary>
public void Resume()
{
}
void RenderOSD(IBlitter renderPanel)
{
GlobalWin.OSD.Begin(renderPanel);
renderPanel.Open();
GlobalWin.OSD.DrawScreenInfo(renderPanel);
GlobalWin.OSD.DrawMessages(renderPanel);
renderPanel.Close();
}
void CheckFilter()
{
IDisplayFilter filter = null;
switch (Global.Config.TargetDisplayFilter)
DisplayManager Owner;
public MyBlitter(DisplayManager dispManager)
{
//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;
Owner = dispManager;
}
if (filter == null)
filteredSurface = null;
else
filteredSurface = filter.Execute(currentSourceSurface);
class FontWrapper : IBlitterFont
{
public FontWrapper(StringRenderer font)
{
this.font = font;
}
public readonly StringRenderer font;
}
IBlitterFont IBlitter.GetFontType(string fontType) { return new FontWrapper(Owner.TheOneFont); }
void IBlitter.DrawString(string s, IBlitterFont font, Color color, float x, float y)
{
var stringRenderer = ((FontWrapper)font).font;
Owner.Renderer.SetModulateColor(color);
stringRenderer.RenderString(Owner.Renderer, x, y, s);
Owner.Renderer.SetModulateColorWhite();
}
SizeF IBlitter.MeasureString(string s, IBlitterFont font)
{
var stringRenderer = ((FontWrapper)font).font;
return stringRenderer.Measure(s);
}
public Rectangle ClipBounds { get; set; }
}
SwappableBitmapBufferSet nativeDisplaySurfaceSet = new SwappableBitmapBufferSet();
/// <summary>
/// applies letterboxing logic to figure out how to fit the source dimensions into the target dimensions.
/// In the future this could also apply rules like integer-only scaling, etc.
/// TODO - make this work with a output rect instead of float and dx/dy
/// </summary>
class LetterboxingLogic
{
public LetterboxingLogic(int targetWidth, int targetHeight, int sourceWidth, int sourceHeight)
{
float vw = (float)targetWidth;
float vh = (float)targetHeight;
float widthScale = vw / sourceWidth;
float heightScale = vh / sourceHeight;
finalScale = Math.Min(widthScale, heightScale);
dx = (int)((vw - finalScale * sourceWidth) / 2);
dy = (int)((vh - finalScale * sourceHeight) / 2);
}
//Thread displayThread;
/// <summary>
/// scale to be applied to both x and y
/// </summary>
public float finalScale;
/// <summary>
/// offset
/// </summary>
public float dx, dy;
}
}
}

View File

@ -9,246 +9,179 @@ using BizHawk.Client.Common;
namespace BizHawk.Client.EmuHawk
{
/// <summary>
/// encapsulates thread-safe concept of pending/current display surfaces, reusing buffers where matching
/// sizes are available and keeping them cleaned up when they dont seem like theyll need to be used anymore
/// This is a wrapper for a Bitmap, basically, which can also be a int[].
/// It should be phased out, in favor of BitmapBuffer and Texture2d's
/// </summary>
class SwappableDisplaySurfaceSet
public unsafe class DisplaySurface : IDisposable
{
DisplaySurface Pending, Current;
Queue<DisplaySurface> ReleasedSurfaces = new Queue<DisplaySurface>();
Bitmap bmp;
BitmapData bmpdata;
int[] pixels;
/// <summary>
/// retrieves a surface with the specified size, reusing an old buffer if available and clearing if requested
/// </summary>
public DisplaySurface AllocateSurface(int width, int height, bool needsClear = true)
public unsafe void Clear()
{
for (; ; )
{
DisplaySurface trial;
lock (this)
{
if (ReleasedSurfaces.Count == 0) break;
trial = ReleasedSurfaces.Dequeue();
}
if (trial.Width == width && trial.Height == height)
{
if (needsClear) trial.Clear();
return trial;
}
trial.Dispose();
}
return new DisplaySurface(width, height);
FromBitmap(false);
Util.Memset(PixelPtr, 0, Stride * Height);
}
public Bitmap PeekBitmap()
{
ToBitmap();
return bmp;
}
/// <summary>
/// sets the provided buffer as pending. takes control of the supplied buffer
/// returns a Graphics object used to render to this surface. be sure to dispose it!
/// </summary>
public void SetPending(DisplaySurface newPending)
public Graphics GetGraphics()
{
lock (this)
ToBitmap();
return Graphics.FromImage(bmp);
}
public unsafe void ToBitmap(bool copy=true)
{
if (isBitmap) return;
isBitmap = true;
if (bmp == null)
{
if (Pending != null) ReleasedSurfaces.Enqueue(Pending);
Pending = newPending;
bmp = new Bitmap(Width, Height, PixelFormat.Format32bppArgb);
}
if (copy)
{
bmpdata = bmp.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
int w = Width;
int h = Height;
int stride = bmpdata.Stride / 4;
int* bmpbuf = (int*)bmpdata.Scan0.ToPointer();
for (int y = 0, i = 0; y < h; y++)
for (int x = 0; x < w; x++)
bmpbuf[y * stride + x] = pixels[i++];
bmp.UnlockBits(bmpdata);
}
}
public bool IsBitmap { get { return isBitmap; } }
bool isBitmap = false;
public unsafe void FromBitmap(bool copy=true)
{
if (!isBitmap) return;
isBitmap = false;
if (copy)
{
bmpdata = bmp.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
int w = Width;
int h = Height;
int stride = bmpdata.Stride / 4;
int* bmpbuf = (int*)bmpdata.Scan0.ToPointer();
for (int y = 0, i = 0; y < h; y++)
for (int x = 0; x < w; x++)
pixels[i++] = bmpbuf[y * stride + x];
bmp.UnlockBits(bmpdata);
}
}
public void ReleaseSurface(DisplaySurface surface)
public static DisplaySurface DisplaySurfaceWrappingBitmap(Bitmap bmp)
{
lock (this) ReleasedSurfaces.Enqueue(surface);
DisplaySurface ret = new DisplaySurface();
ret.Width = bmp.Width;
ret.Height = bmp.Height;
ret.bmp = bmp;
ret.isBitmap = true;
return ret;
}
/// <summary>
/// returns the current buffer, making the most recent pending buffer (if there is such) as the new current first.
/// </summary>
public DisplaySurface GetCurrent()
private DisplaySurface()
{
lock (this)
{
if (Pending != null)
{
if (Current != null) ReleasedSurfaces.Enqueue(Current);
Current = Pending;
Pending = null;
}
}
return Current;
}
}
public unsafe class DisplaySurface : IDisposable
{
Bitmap bmp;
BitmapData bmpdata;
int[] pixels;
public unsafe void Clear()
{
FromBitmap(false);
Util.Memset(PixelPtr, 0, Stride * Height);
}
public Bitmap PeekBitmap()
{
ToBitmap();
return bmp;
}
/// <summary>
/// returns a Graphics object used to render to this surface. be sure to dispose it!
/// </summary>
public Graphics GetGraphics()
{
ToBitmap();
return Graphics.FromImage(bmp);
}
public unsafe void ToBitmap(bool copy=true)
{
if (isBitmap) return;
isBitmap = true;
if (bmp == null)
{
bmp = new Bitmap(Width, Height, PixelFormat.Format32bppArgb);
}
if (copy)
public DisplaySurface(int width, int height)
{
bmpdata = bmp.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
int w = Width;
int h = Height;
int stride = bmpdata.Stride / 4;
int* bmpbuf = (int*)bmpdata.Scan0.ToPointer();
for (int y = 0, i = 0; y < h; y++)
for (int x = 0; x < w; x++)
bmpbuf[y * stride + x] = pixels[i++];
bmp.UnlockBits(bmpdata);
}
}
public bool IsBitmap { get { return isBitmap; } }
bool isBitmap = false;
public unsafe void FromBitmap(bool copy=true)
{
if (!isBitmap) return;
isBitmap = false;
if (copy)
{
bmpdata = bmp.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
int w = Width;
int h = Height;
int stride = bmpdata.Stride / 4;
int* bmpbuf = (int*)bmpdata.Scan0.ToPointer();
for (int y = 0, i = 0; y < h; y++)
for (int x = 0; x < w; x++)
pixels[i++] = bmpbuf[y * stride + x];
bmp.UnlockBits(bmpdata);
}
}
public static DisplaySurface DisplaySurfaceWrappingBitmap(Bitmap bmp)
{
DisplaySurface ret = new DisplaySurface();
ret.Width = bmp.Width;
ret.Height = bmp.Height;
ret.bmp = bmp;
ret.isBitmap = true;
return ret;
}
private DisplaySurface()
{
}
public DisplaySurface(int width, int height)
{
//can't create a bitmap with zero dimensions, so for now, just bump it up to one
if (width == 0) width = 1;
if (height == 0) height = 1;
//can't create a bitmap with zero dimensions, so for now, just bump it up to one
if (width == 0) width = 1;
if (height == 0) height = 1;
Width = width;
Height = height;
Width = width;
Height = height;
pixels = new int[width * height];
LockPixels();
pixels = new int[width * height];
LockPixels();
}
public int* PixelPtr { get { return (int*)ptr; } }
public IntPtr PixelIntPtr { get { return new IntPtr(ptr); } }
public int Stride { get { return Width*4; } }
public int OffsetOf(int x, int y) { return y * Stride + x*4; }
void* ptr;
GCHandle handle;
void LockPixels()
{
UnlockPixels();
handle = GCHandle.Alloc(pixels, GCHandleType.Pinned);
ptr = handle.AddrOfPinnedObject().ToPointer();
}
void UnlockPixels()
{
if(handle.IsAllocated) handle.Free();
}
/// <summary>
/// returns a new surface
/// </summary>
/// <param name="xpad"></param>
/// <param name="ypad"></param>
/// <returns></returns>
public DisplaySurface ToPaddedSurface(int xpad0, int ypad0, int xpad1, int ypad1)
{
int new_width = Width + xpad0 + xpad1;
int new_height = Height + ypad0 + ypad1;
DisplaySurface ret = new DisplaySurface(new_width, new_height);
int* dptr = ret.PixelPtr;
int* sptr = PixelPtr;
int dstride = ret.Stride / 4;
int sstride = Stride / 4;
for (int y = 0; y < Height; y++)
for (int x = 0; x < Width; x++)
{
dptr[(y + ypad0) * dstride + x + xpad0] = sptr[y * sstride + x];
}
return ret;
}
public int Width { get; private set; }
public int Height { get; private set; }
public void Dispose()
{
if (bmp != null)
bmp.Dispose();
bmp = null;
UnlockPixels();
}
//public unsafe int[] ToIntArray() { }
public void AcceptIntArray(int[] newpixels)
{
FromBitmap(false);
UnlockPixels();
pixels = newpixels;
LockPixels();
}
}
public int* PixelPtr { get { return (int*)ptr; } }
public IntPtr PixelIntPtr { get { return new IntPtr(ptr); } }
public int Stride { get { return Width*4; } }
public int OffsetOf(int x, int y) { return y * Stride + x*4; }
void* ptr;
GCHandle handle;
void LockPixels()
{
UnlockPixels();
handle = GCHandle.Alloc(pixels, GCHandleType.Pinned);
ptr = handle.AddrOfPinnedObject().ToPointer();
}
void UnlockPixels()
{
if(handle.IsAllocated) handle.Free();
}
/// <summary>
/// returns a new surface
/// </summary>
/// <param name="xpad"></param>
/// <param name="ypad"></param>
/// <returns></returns>
public DisplaySurface ToPaddedSurface(int xpad0, int ypad0, int xpad1, int ypad1)
{
int new_width = Width + xpad0 + xpad1;
int new_height = Height + ypad0 + ypad1;
DisplaySurface ret = new DisplaySurface(new_width, new_height);
int* dptr = ret.PixelPtr;
int* sptr = PixelPtr;
int dstride = ret.Stride / 4;
int sstride = Stride / 4;
for (int y = 0; y < Height; y++)
for (int x = 0; x < Width; x++)
{
dptr[(y + ypad0) * dstride + x + xpad0] = sptr[y * sstride + x];
}
return ret;
}
public int Width { get; private set; }
public int Height { get; private set; }
public void Dispose()
{
if (bmp != null)
bmp.Dispose();
bmp = null;
UnlockPixels();
}
//public unsafe int[] ToIntArray() { }
public void AcceptIntArray(int[] newpixels)
{
FromBitmap(false);
UnlockPixels();
pixels = newpixels;
LockPixels();
}
}
}

View File

@ -1,20 +0,0 @@
using System.Drawing;
using BizHawk.Bizware.BizwareGL;
namespace BizHawk.Client.EmuHawk
{
public interface IDisplayFilter
{
/// <summary>
/// describes how this filter will respond to an input format
/// </summary>
DisplayFilterAnalysisReport Analyze(Size sourceSize);
/// <summary>
/// runs the filter
/// </summary>
BitmapBuffer Execute(BitmapBuffer surface);
}
}

View File

@ -10,6 +10,20 @@ using BizHawk.Bizware.BizwareGL;
namespace BizHawk.Client.EmuHawk
{
/// <summary>
/// This is an old abstracted rendering class that the OSD system is using to get its work done.
/// We should probably just use a GuiRenderer (it was designed to do that) although wrapping it with
/// more information for OSDRendering could be helpful I suppose
/// </summary>
public interface IBlitter
{
IBlitterFont GetFontType(string fontType);
void DrawString(string s, IBlitterFont font, Color color, float x, float y);
SizeF MeasureString(string s, IBlitterFont font);
Rectangle ClipBounds { get; set; }
}
class UIMessage
{
public string Message;

View File

@ -8,6 +8,7 @@ namespace BizHawk.Client.EmuHawk
/// <summary>
/// encapsulates thread-safe concept of pending/current BitmapBuffer, reusing buffers where matching
/// sizes are available and keeping them cleaned up when they dont seem like theyll need to be used anymore
/// This isnt in the csproj right now, but I'm keeping it, in case its handy.
/// </summary>
class SwappableBitmapBufferSet
{

View File

@ -0,0 +1,79 @@
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using BizHawk.Common;
using BizHawk.Client.Common;
namespace BizHawk.Client.EmuHawk
{
/// <summary>
/// encapsulates thread-safe concept of pending/current display surfaces, reusing buffers where matching
/// sizes are available and keeping them cleaned up when they dont seem like theyll need to be used anymore
/// </summary>
class SwappableDisplaySurfaceSet
{
DisplaySurface Pending, Current;
Queue<DisplaySurface> ReleasedSurfaces = new Queue<DisplaySurface>();
/// <summary>
/// retrieves a surface with the specified size, reusing an old buffer if available and clearing if requested
/// </summary>
public DisplaySurface AllocateSurface(int width, int height, bool needsClear = true)
{
for (; ; )
{
DisplaySurface trial;
lock (this)
{
if (ReleasedSurfaces.Count == 0) break;
trial = ReleasedSurfaces.Dequeue();
}
if (trial.Width == width && trial.Height == height)
{
if (needsClear) trial.Clear();
return trial;
}
trial.Dispose();
}
return new DisplaySurface(width, height);
}
/// <summary>
/// sets the provided buffer as pending. takes control of the supplied buffer
/// </summary>
public void SetPending(DisplaySurface newPending)
{
lock (this)
{
if (Pending != null) ReleasedSurfaces.Enqueue(Pending);
Pending = newPending;
}
}
public void ReleaseSurface(DisplaySurface surface)
{
lock (this) ReleasedSurfaces.Enqueue(surface);
}
/// <summary>
/// returns the current buffer, making the most recent pending buffer (if there is such) as the new current first.
/// </summary>
public DisplaySurface GetCurrent()
{
lock (this)
{
if (Pending != null)
{
if (Current != null) ReleasedSurfaces.Enqueue(Current);
Current = Pending;
Pending = null;
}
}
return Current;
}
}
}

View File

@ -0,0 +1,56 @@
using System;
using BizHawk.Common;
using BizHawk.Emulation.Common;
using BizHawk.Client.Common;
using BizHawk.Bizware.BizwareGL;
namespace BizHawk.Client.EmuHawk
{
/// <summary>
/// Recycles a temporary texture to contain a BitmapBuffer's or DisplaySurface's contents, as long as the dimensions match.
/// When the dimensions dont match, a new one will be allocated
/// </summary>
class TextureFrugalizer : IDisposable
{
public TextureFrugalizer(IGL gl)
{
GL = gl;
}
public void Dispose()
{
if (CurrentTexture != null)
{
CurrentTexture.Dispose();
CurrentTexture = null;
}
}
IGL GL;
Texture2d CurrentTexture;
public Texture2d Get(DisplaySurface ds)
{
using (var bb = new BitmapBuffer(ds.PeekBitmap(), new BitmapLoadOptions()))
{
return Get(bb);
}
}
public Texture2d Get(BitmapBuffer bb)
{
if (CurrentTexture == null || CurrentTexture.IntWidth != bb.Width || CurrentTexture.IntHeight != bb.Height)
{
if (CurrentTexture != null)
CurrentTexture.Dispose();
CurrentTexture = GL.LoadTexture(bb);
}
else
{
GL.LoadTextureData(CurrentTexture, bb);
}
return CurrentTexture;
}
}
}

View File

@ -15,7 +15,7 @@ namespace BizHawk.Client.EmuHawk
public static Sound Sound;
public static PresentationPanel PresentationPanel;
public static OSDManager OSD = new OSDManager();
public static DisplayManager DisplayManager = new DisplayManager();
public static DisplayManager DisplayManager;
//input state which has been destined for game controller inputs are coalesced here
//public static ControllerInputCoalescer ControllerInputCoalescer = new ControllerInputCoalescer();

View File

@ -106,16 +106,6 @@
this.SoftResetMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.HardResetMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.ViewSubMenu = new System.Windows.Forms.ToolStripMenuItem();
this.DisplayFilterSubMenu = new System.Windows.Forms.ToolStripMenuItem();
this.DisplayFilterNoneMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.x2SAIMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.SuperX2SAIMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.SuperEagleMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.scanlines2xToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.Scanlines25MenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.Scanlines50MenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.Scanlines75MenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.ScanlinesCustomMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.WindowSizeSubMenu = new System.Windows.Forms.ToolStripMenuItem();
this.x1MenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.x2MenuItem = new System.Windows.Forms.ToolStripMenuItem();
@ -1074,7 +1064,6 @@
// ViewSubMenu
//
this.ViewSubMenu.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.DisplayFilterSubMenu,
this.WindowSizeSubMenu,
this.SwitchToFullscreenMenuItem,
this.toolStripSeparator2,
@ -1092,87 +1081,6 @@
this.ViewSubMenu.Text = "&View";
this.ViewSubMenu.DropDownOpened += new System.EventHandler(this.ViewSubMenu_DropDownOpened);
//
// DisplayFilterSubMenu
//
this.DisplayFilterSubMenu.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.DisplayFilterNoneMenuItem,
this.x2SAIMenuItem,
this.SuperX2SAIMenuItem,
this.SuperEagleMenuItem,
this.scanlines2xToolStripMenuItem});
this.DisplayFilterSubMenu.Name = "DisplayFilterSubMenu";
this.DisplayFilterSubMenu.Size = new System.Drawing.Size(187, 22);
this.DisplayFilterSubMenu.Text = "Display Filter";
this.DisplayFilterSubMenu.DropDownOpened += new System.EventHandler(this.DisplayFilterSubMenu_DropDownOpened);
//
// DisplayFilterNoneMenuItem
//
this.DisplayFilterNoneMenuItem.Name = "DisplayFilterNoneMenuItem";
this.DisplayFilterNoneMenuItem.Size = new System.Drawing.Size(134, 22);
this.DisplayFilterNoneMenuItem.Text = "None";
this.DisplayFilterNoneMenuItem.Click += new System.EventHandler(this.DisplayFilterMenuItem_Click);
//
// x2SAIMenuItem
//
this.x2SAIMenuItem.Name = "x2SAIMenuItem";
this.x2SAIMenuItem.Size = new System.Drawing.Size(134, 22);
this.x2SAIMenuItem.Text = "2xSAI";
this.x2SAIMenuItem.Click += new System.EventHandler(this.DisplayFilterMenuItem_Click);
//
// SuperX2SAIMenuItem
//
this.SuperX2SAIMenuItem.Name = "SuperX2SAIMenuItem";
this.SuperX2SAIMenuItem.Size = new System.Drawing.Size(134, 22);
this.SuperX2SAIMenuItem.Text = "Super 2xSAI";
this.SuperX2SAIMenuItem.Click += new System.EventHandler(this.DisplayFilterMenuItem_Click);
//
// SuperEagleMenuItem
//
this.SuperEagleMenuItem.Name = "SuperEagleMenuItem";
this.SuperEagleMenuItem.Size = new System.Drawing.Size(134, 22);
this.SuperEagleMenuItem.Text = "Super Eagle";
this.SuperEagleMenuItem.Click += new System.EventHandler(this.DisplayFilterMenuItem_Click);
//
// scanlines2xToolStripMenuItem
//
this.scanlines2xToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.Scanlines25MenuItem,
this.Scanlines50MenuItem,
this.Scanlines75MenuItem,
this.ScanlinesCustomMenuItem});
this.scanlines2xToolStripMenuItem.Name = "scanlines2xToolStripMenuItem";
this.scanlines2xToolStripMenuItem.Size = new System.Drawing.Size(134, 22);
this.scanlines2xToolStripMenuItem.Text = "Scanlines";
this.scanlines2xToolStripMenuItem.Click += new System.EventHandler(this.DisplayFilterMenuItem_Click);
//
// Scanlines25MenuItem
//
this.Scanlines25MenuItem.Name = "Scanlines25MenuItem";
this.Scanlines25MenuItem.Size = new System.Drawing.Size(122, 22);
this.Scanlines25MenuItem.Text = "25%";
this.Scanlines25MenuItem.Click += new System.EventHandler(this.DisplayFilterMenuItem_Click);
//
// Scanlines50MenuItem
//
this.Scanlines50MenuItem.Name = "Scanlines50MenuItem";
this.Scanlines50MenuItem.Size = new System.Drawing.Size(122, 22);
this.Scanlines50MenuItem.Text = "50%";
this.Scanlines50MenuItem.Click += new System.EventHandler(this.DisplayFilterMenuItem_Click);
//
// Scanlines75MenuItem
//
this.Scanlines75MenuItem.Name = "Scanlines75MenuItem";
this.Scanlines75MenuItem.Size = new System.Drawing.Size(122, 22);
this.Scanlines75MenuItem.Text = "75%";
this.Scanlines75MenuItem.Click += new System.EventHandler(this.DisplayFilterMenuItem_Click);
//
// ScanlinesCustomMenuItem
//
this.ScanlinesCustomMenuItem.Name = "ScanlinesCustomMenuItem";
this.ScanlinesCustomMenuItem.Size = new System.Drawing.Size(122, 22);
this.ScanlinesCustomMenuItem.Text = "Custom...";
this.ScanlinesCustomMenuItem.Click += new System.EventHandler(this.DisplayFilterMenuItem_Click);
//
// WindowSizeSubMenu
//
this.WindowSizeSubMenu.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
@ -1190,42 +1098,42 @@
// x1MenuItem
//
this.x1MenuItem.Name = "x1MenuItem";
this.x1MenuItem.Size = new System.Drawing.Size(94, 22);
this.x1MenuItem.Size = new System.Drawing.Size(152, 22);
this.x1MenuItem.Text = "&1x";
this.x1MenuItem.Click += new System.EventHandler(this.WindowSize_Click);
//
// x2MenuItem
//
this.x2MenuItem.Name = "x2MenuItem";
this.x2MenuItem.Size = new System.Drawing.Size(94, 22);
this.x2MenuItem.Size = new System.Drawing.Size(152, 22);
this.x2MenuItem.Text = "&2x";
this.x2MenuItem.Click += new System.EventHandler(this.WindowSize_Click);
//
// x3MenuItem
//
this.x3MenuItem.Name = "x3MenuItem";
this.x3MenuItem.Size = new System.Drawing.Size(94, 22);
this.x3MenuItem.Size = new System.Drawing.Size(152, 22);
this.x3MenuItem.Text = "&3x";
this.x3MenuItem.Click += new System.EventHandler(this.WindowSize_Click);
//
// x4MenuItem
//
this.x4MenuItem.Name = "x4MenuItem";
this.x4MenuItem.Size = new System.Drawing.Size(94, 22);
this.x4MenuItem.Size = new System.Drawing.Size(152, 22);
this.x4MenuItem.Text = "&4x";
this.x4MenuItem.Click += new System.EventHandler(this.WindowSize_Click);
//
// x5MenuItem
//
this.x5MenuItem.Name = "x5MenuItem";
this.x5MenuItem.Size = new System.Drawing.Size(94, 22);
this.x5MenuItem.Size = new System.Drawing.Size(152, 22);
this.x5MenuItem.Text = "&5x";
this.x5MenuItem.Click += new System.EventHandler(this.WindowSize_Click);
//
// mzMenuItem
//
this.mzMenuItem.Name = "mzMenuItem";
this.mzMenuItem.Size = new System.Drawing.Size(94, 22);
this.mzMenuItem.Size = new System.Drawing.Size(152, 22);
this.mzMenuItem.Text = "&Max";
this.mzMenuItem.Click += new System.EventHandler(this.WindowSize_Click);
//
@ -1802,21 +1710,21 @@
// SavestateTypeDefaultMenuItem
//
this.SavestateTypeDefaultMenuItem.Name = "SavestateTypeDefaultMenuItem";
this.SavestateTypeDefaultMenuItem.Size = new System.Drawing.Size(152, 22);
this.SavestateTypeDefaultMenuItem.Size = new System.Drawing.Size(109, 22);
this.SavestateTypeDefaultMenuItem.Text = "Default";
this.SavestateTypeDefaultMenuItem.Click += new System.EventHandler(this.SavestateTypeDefaultMenuItem_Click);
//
// SavestateBinaryMenuItem
//
this.SavestateBinaryMenuItem.Name = "SavestateBinaryMenuItem";
this.SavestateBinaryMenuItem.Size = new System.Drawing.Size(152, 22);
this.SavestateBinaryMenuItem.Size = new System.Drawing.Size(109, 22);
this.SavestateBinaryMenuItem.Text = "Binary";
this.SavestateBinaryMenuItem.Click += new System.EventHandler(this.SavestateBinaryMenuItem_Click);
//
// SavestateTextMenuItem
//
this.SavestateTextMenuItem.Name = "SavestateTextMenuItem";
this.SavestateTextMenuItem.Size = new System.Drawing.Size(152, 22);
this.SavestateTextMenuItem.Size = new System.Drawing.Size(109, 22);
this.SavestateTextMenuItem.Text = "Text";
this.SavestateTextMenuItem.Click += new System.EventHandler(this.SavestateTextMenuItem_Click);
//
@ -2803,7 +2711,7 @@
this.ShowMenuContextMenuSeparator,
this.ShowMenuContextMenuItem});
this.MainFormContextMenu.Name = "contextMenuStrip1";
this.MainFormContextMenu.Size = new System.Drawing.Size(217, 468);
this.MainFormContextMenu.Size = new System.Drawing.Size(202, 468);
this.MainFormContextMenu.Closing += new System.Windows.Forms.ToolStripDropDownClosingEventHandler(this.MainFormContextMenu_Closing);
this.MainFormContextMenu.Opening += new System.ComponentModel.CancelEventHandler(this.MainFormContextMenu_Opening);
//
@ -2811,7 +2719,7 @@
//
this.OpenRomContextMenuItem.Image = global::BizHawk.Client.EmuHawk.Properties.Resources.OpenFile;
this.OpenRomContextMenuItem.Name = "OpenRomContextMenuItem";
this.OpenRomContextMenuItem.Size = new System.Drawing.Size(216, 22);
this.OpenRomContextMenuItem.Size = new System.Drawing.Size(201, 22);
this.OpenRomContextMenuItem.Text = "Open Rom";
this.OpenRomContextMenuItem.Click += new System.EventHandler(this.OpenRomMenuItem_Click);
//
@ -2819,7 +2727,7 @@
//
this.LoadLastRomContextMenuItem.Image = global::BizHawk.Client.EmuHawk.Properties.Resources.Recent;
this.LoadLastRomContextMenuItem.Name = "LoadLastRomContextMenuItem";
this.LoadLastRomContextMenuItem.Size = new System.Drawing.Size(216, 22);
this.LoadLastRomContextMenuItem.Size = new System.Drawing.Size(201, 22);
this.LoadLastRomContextMenuItem.Text = "Load Last ROM";
this.LoadLastRomContextMenuItem.Click += new System.EventHandler(this.LoadLastRomContextMenuItem_Click);
//
@ -2827,20 +2735,20 @@
//
this.StopAVContextMenuItem.Image = global::BizHawk.Client.EmuHawk.Properties.Resources.Stop;
this.StopAVContextMenuItem.Name = "StopAVContextMenuItem";
this.StopAVContextMenuItem.Size = new System.Drawing.Size(216, 22);
this.StopAVContextMenuItem.Size = new System.Drawing.Size(201, 22);
this.StopAVContextMenuItem.Text = "Stop AVI/WAV";
this.StopAVContextMenuItem.Click += new System.EventHandler(this.StopAVMenuItem_Click);
//
// ContextSeparator_AfterROM
//
this.ContextSeparator_AfterROM.Name = "ContextSeparator_AfterROM";
this.ContextSeparator_AfterROM.Size = new System.Drawing.Size(213, 6);
this.ContextSeparator_AfterROM.Size = new System.Drawing.Size(198, 6);
//
// RecordMovieContextMenuItem
//
this.RecordMovieContextMenuItem.Image = global::BizHawk.Client.EmuHawk.Properties.Resources.RecordHS;
this.RecordMovieContextMenuItem.Name = "RecordMovieContextMenuItem";
this.RecordMovieContextMenuItem.Size = new System.Drawing.Size(216, 22);
this.RecordMovieContextMenuItem.Size = new System.Drawing.Size(201, 22);
this.RecordMovieContextMenuItem.Text = "Record Movie";
this.RecordMovieContextMenuItem.Click += new System.EventHandler(this.RecordMovieMenuItem_Click);
//
@ -2848,7 +2756,7 @@
//
this.PlayMovieContextMenuItem.Image = global::BizHawk.Client.EmuHawk.Properties.Resources.Play;
this.PlayMovieContextMenuItem.Name = "PlayMovieContextMenuItem";
this.PlayMovieContextMenuItem.Size = new System.Drawing.Size(216, 22);
this.PlayMovieContextMenuItem.Size = new System.Drawing.Size(201, 22);
this.PlayMovieContextMenuItem.Text = "Play Movie";
this.PlayMovieContextMenuItem.Click += new System.EventHandler(this.PlayMovieMenuItem_Click);
//
@ -2856,7 +2764,7 @@
//
this.RestartMovieContextMenuItem.Image = global::BizHawk.Client.EmuHawk.Properties.Resources.restart;
this.RestartMovieContextMenuItem.Name = "RestartMovieContextMenuItem";
this.RestartMovieContextMenuItem.Size = new System.Drawing.Size(216, 22);
this.RestartMovieContextMenuItem.Size = new System.Drawing.Size(201, 22);
this.RestartMovieContextMenuItem.Text = "Restart Movie";
this.RestartMovieContextMenuItem.Click += new System.EventHandler(this.PlayFromBeginningMenuItem_Click);
//
@ -2864,7 +2772,7 @@
//
this.StopMovieContextMenuItem.Image = global::BizHawk.Client.EmuHawk.Properties.Resources.Stop;
this.StopMovieContextMenuItem.Name = "StopMovieContextMenuItem";
this.StopMovieContextMenuItem.Size = new System.Drawing.Size(216, 22);
this.StopMovieContextMenuItem.Size = new System.Drawing.Size(201, 22);
this.StopMovieContextMenuItem.Text = "Stop Movie";
this.StopMovieContextMenuItem.Click += new System.EventHandler(this.StopMovieMenuItem_Click);
//
@ -2872,14 +2780,14 @@
//
this.LoadLastMovieContextMenuItem.Image = global::BizHawk.Client.EmuHawk.Properties.Resources.Recent;
this.LoadLastMovieContextMenuItem.Name = "LoadLastMovieContextMenuItem";
this.LoadLastMovieContextMenuItem.Size = new System.Drawing.Size(216, 22);
this.LoadLastMovieContextMenuItem.Size = new System.Drawing.Size(201, 22);
this.LoadLastMovieContextMenuItem.Text = "Load Last Movie";
this.LoadLastMovieContextMenuItem.Click += new System.EventHandler(this.LoadLastMovieContextMenuItem_Click);
//
// BackupMovieContextMenuItem
//
this.BackupMovieContextMenuItem.Name = "BackupMovieContextMenuItem";
this.BackupMovieContextMenuItem.Size = new System.Drawing.Size(216, 22);
this.BackupMovieContextMenuItem.Size = new System.Drawing.Size(201, 22);
this.BackupMovieContextMenuItem.Text = "Backup Movie";
this.BackupMovieContextMenuItem.Click += new System.EventHandler(this.BackupMovieContextMenuItem_Click);
//
@ -2887,28 +2795,28 @@
//
this.StopNoSaveContextMenuItem.Image = global::BizHawk.Client.EmuHawk.Properties.Resources.Stop;
this.StopNoSaveContextMenuItem.Name = "StopNoSaveContextMenuItem";
this.StopNoSaveContextMenuItem.Size = new System.Drawing.Size(216, 22);
this.StopNoSaveContextMenuItem.Size = new System.Drawing.Size(201, 22);
this.StopNoSaveContextMenuItem.Text = "Stop Movie without Saving";
this.StopNoSaveContextMenuItem.Click += new System.EventHandler(this.StopMovieWithoutSavingMenuItem_Click);
//
// ViewSubtitlesContextMenuItem
//
this.ViewSubtitlesContextMenuItem.Name = "ViewSubtitlesContextMenuItem";
this.ViewSubtitlesContextMenuItem.Size = new System.Drawing.Size(216, 22);
this.ViewSubtitlesContextMenuItem.Size = new System.Drawing.Size(201, 22);
this.ViewSubtitlesContextMenuItem.Text = "View Subtitles";
this.ViewSubtitlesContextMenuItem.Click += new System.EventHandler(this.ViewSubtitlesContextMenuItem_Click);
//
// AddSubtitleContextMenuItem
//
this.AddSubtitleContextMenuItem.Name = "AddSubtitleContextMenuItem";
this.AddSubtitleContextMenuItem.Size = new System.Drawing.Size(216, 22);
this.AddSubtitleContextMenuItem.Size = new System.Drawing.Size(201, 22);
this.AddSubtitleContextMenuItem.Text = "Add Subtitle";
this.AddSubtitleContextMenuItem.Click += new System.EventHandler(this.AddSubtitleContextMenuItem_Click);
//
// ViewCommentsContextMenuItem
//
this.ViewCommentsContextMenuItem.Name = "ViewCommentsContextMenuItem";
this.ViewCommentsContextMenuItem.Size = new System.Drawing.Size(216, 22);
this.ViewCommentsContextMenuItem.Size = new System.Drawing.Size(201, 22);
this.ViewCommentsContextMenuItem.Text = "View Comments";
this.ViewCommentsContextMenuItem.Click += new System.EventHandler(this.ViewCommentsContextMenuItem_Click);
//
@ -2916,27 +2824,27 @@
//
this.SaveMovieContextMenuItem.Image = global::BizHawk.Client.EmuHawk.Properties.Resources.SaveAs;
this.SaveMovieContextMenuItem.Name = "SaveMovieContextMenuItem";
this.SaveMovieContextMenuItem.Size = new System.Drawing.Size(216, 22);
this.SaveMovieContextMenuItem.Size = new System.Drawing.Size(201, 22);
this.SaveMovieContextMenuItem.Text = "Save Movie";
this.SaveMovieContextMenuItem.Click += new System.EventHandler(this.SaveMovieMenuItem_Click);
//
// ContextSeparator_AfterMovie
//
this.ContextSeparator_AfterMovie.Name = "ContextSeparator_AfterMovie";
this.ContextSeparator_AfterMovie.Size = new System.Drawing.Size(213, 6);
this.ContextSeparator_AfterMovie.Size = new System.Drawing.Size(198, 6);
//
// UndoSavestateContextMenuItem
//
this.UndoSavestateContextMenuItem.Image = global::BizHawk.Client.EmuHawk.Properties.Resources.undo;
this.UndoSavestateContextMenuItem.Name = "UndoSavestateContextMenuItem";
this.UndoSavestateContextMenuItem.Size = new System.Drawing.Size(216, 22);
this.UndoSavestateContextMenuItem.Size = new System.Drawing.Size(201, 22);
this.UndoSavestateContextMenuItem.Text = "Undo Savestate";
this.UndoSavestateContextMenuItem.Click += new System.EventHandler(this.UndoSavestateContextMenuItem_Click);
//
// ContextSeparator_AfterUndo
//
this.ContextSeparator_AfterUndo.Name = "ContextSeparator_AfterUndo";
this.ContextSeparator_AfterUndo.Size = new System.Drawing.Size(213, 6);
this.ContextSeparator_AfterUndo.Size = new System.Drawing.Size(198, 6);
//
// ConfigContextMenuItem
//
@ -2953,7 +2861,7 @@
this.toolStripMenuItem6,
this.toolStripMenuItem7});
this.ConfigContextMenuItem.Name = "ConfigContextMenuItem";
this.ConfigContextMenuItem.Size = new System.Drawing.Size(216, 22);
this.ConfigContextMenuItem.Size = new System.Drawing.Size(201, 22);
this.ConfigContextMenuItem.Text = "Config";
//
// controllersToolStripMenuItem1
@ -3043,7 +2951,7 @@
//
this.ScreenshotContextMenuItem.Image = global::BizHawk.Client.EmuHawk.Properties.Resources.camera;
this.ScreenshotContextMenuItem.Name = "ScreenshotContextMenuItem";
this.ScreenshotContextMenuItem.Size = new System.Drawing.Size(216, 22);
this.ScreenshotContextMenuItem.Size = new System.Drawing.Size(201, 22);
this.ScreenshotContextMenuItem.Text = "Screenshot";
this.ScreenshotContextMenuItem.Click += new System.EventHandler(this.ScreenshotMenuItem_Click);
//
@ -3051,26 +2959,26 @@
//
this.CloseRomContextMenuItem.Image = global::BizHawk.Client.EmuHawk.Properties.Resources.Close;
this.CloseRomContextMenuItem.Name = "CloseRomContextMenuItem";
this.CloseRomContextMenuItem.Size = new System.Drawing.Size(216, 22);
this.CloseRomContextMenuItem.Size = new System.Drawing.Size(201, 22);
this.CloseRomContextMenuItem.Text = "Close ROM";
this.CloseRomContextMenuItem.Click += new System.EventHandler(this.CloseRomMenuItem_Click);
//
// ClearSRAMContextMenuItem
//
this.ClearSRAMContextMenuItem.Name = "ClearSRAMContextMenuItem";
this.ClearSRAMContextMenuItem.Size = new System.Drawing.Size(216, 22);
this.ClearSRAMContextMenuItem.Size = new System.Drawing.Size(201, 22);
this.ClearSRAMContextMenuItem.Text = "Close and Clear SRAM";
this.ClearSRAMContextMenuItem.Click += new System.EventHandler(this.ClearSRAMContextMenuItem_Click);
//
// ShowMenuContextMenuSeparator
//
this.ShowMenuContextMenuSeparator.Name = "ShowMenuContextMenuSeparator";
this.ShowMenuContextMenuSeparator.Size = new System.Drawing.Size(213, 6);
this.ShowMenuContextMenuSeparator.Size = new System.Drawing.Size(198, 6);
//
// ShowMenuContextMenuItem
//
this.ShowMenuContextMenuItem.Name = "ShowMenuContextMenuItem";
this.ShowMenuContextMenuItem.Size = new System.Drawing.Size(216, 22);
this.ShowMenuContextMenuItem.Size = new System.Drawing.Size(201, 22);
this.ShowMenuContextMenuItem.Text = "Show Menu";
this.ShowMenuContextMenuItem.Click += new System.EventHandler(this.ShowMenuContextMenuItem_Click);
//
@ -3330,11 +3238,6 @@
private System.Windows.Forms.ToolStripMenuItem SuppressGuiLayerMenuItem;
private System.Windows.Forms.ToolStripMenuItem DontAskToSaveChangesMenuItem;
private System.Windows.Forms.ToolStripMenuItem NESSoundChannelsMenuItem;
private System.Windows.Forms.ToolStripMenuItem DisplayFilterSubMenu;
private System.Windows.Forms.ToolStripMenuItem x2SAIMenuItem;
private System.Windows.Forms.ToolStripMenuItem SuperEagleMenuItem;
private System.Windows.Forms.ToolStripMenuItem SuperX2SAIMenuItem;
private System.Windows.Forms.ToolStripMenuItem DisplayFilterNoneMenuItem;
private System.Windows.Forms.ToolStripMenuItem SNESSubMenu;
private System.Windows.Forms.ToolStripMenuItem SnesGfxDebuggerMenuItem;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator18;
@ -3420,11 +3323,6 @@
private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem6;
private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem7;
private System.Windows.Forms.ToolStripMenuItem StopAVContextMenuItem;
private System.Windows.Forms.ToolStripMenuItem scanlines2xToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem Scanlines25MenuItem;
private System.Windows.Forms.ToolStripMenuItem Scanlines50MenuItem;
private System.Windows.Forms.ToolStripMenuItem Scanlines75MenuItem;
private System.Windows.Forms.ToolStripMenuItem ScanlinesCustomMenuItem;
private System.Windows.Forms.ToolStripMenuItem FdsEjectDiskMenuItem;
private System.Windows.Forms.ToolStripMenuItem DGBSubMenu;
private System.Windows.Forms.ToolStripMenuItem DGBsettingsToolStripMenuItem;

View File

@ -574,27 +574,6 @@ namespace BizHawk.Client.EmuHawk
DisplayLogWindowMenuItem.Checked = Global.Config.ShowLogWindow;
}
private void DisplayFilterSubMenu_DropDownOpened(object sender, EventArgs e)
{
DisplayFilterNoneMenuItem.Checked = Global.Config.TargetDisplayFilter == 0;
x2SAIMenuItem.Checked = Global.Config.TargetDisplayFilter == 1;
SuperX2SAIMenuItem.Checked = Global.Config.TargetDisplayFilter == 2;
SuperEagleMenuItem.Checked = Global.Config.TargetDisplayFilter == 3;
scanlines2xToolStripMenuItem.Checked = Global.Config.TargetDisplayFilter == 4;
}
private void DisplayFilterMenuItem_Click(object sender, EventArgs e)
{
if (sender == DisplayFilterNoneMenuItem) Global.Config.TargetDisplayFilter = 0;
if (sender == x2SAIMenuItem) Global.Config.TargetDisplayFilter = 1;
if (sender == SuperX2SAIMenuItem) Global.Config.TargetDisplayFilter = 2;
if (sender == SuperEagleMenuItem) Global.Config.TargetDisplayFilter = 3;
if (sender == Scanlines25MenuItem) { Global.Config.TargetDisplayFilter = 4; Global.Config.TargetScanlineFilterIntensity = 192; }
if (sender == Scanlines50MenuItem) { Global.Config.TargetDisplayFilter = 4; Global.Config.TargetScanlineFilterIntensity = 128; }
if (sender == Scanlines75MenuItem) { Global.Config.TargetDisplayFilter = 4; Global.Config.TargetScanlineFilterIntensity = 64; }
if (sender == ScanlinesCustomMenuItem) { Global.Config.TargetDisplayFilter = 4; new ScanlineSlider().Show(); }
}
private void WindowSizeSubMenu_DropDownOpened(object sender, EventArgs e)
{
x1MenuItem.Checked =

View File

@ -95,6 +95,7 @@ namespace BizHawk.Client.EmuHawk
//TODO GL - a lot of disorganized wiring-up here
GlobalWin.PresentationPanel = new PresentationPanel();
GlobalWin.DisplayManager = new DisplayManager(GlobalWin.PresentationPanel);
Controls.Add(GlobalWin.PresentationPanel);
Controls.SetChildIndex(GlobalWin.PresentationPanel, 0);

View File

@ -0,0 +1,82 @@
using System;
using System.Drawing;
using sd=System.Drawing;
using sysdrawingfont=System.Drawing.Font;
using sysdrawing2d=System.Drawing.Drawing2D;
using System.IO;
using System.Threading;
using System.Windows.Forms;
#if WINDOWS
using SlimDX;
#endif
using BizHawk.Client.Common;
using BizHawk.Bizware.BizwareGL;
using OpenTK.Graphics.OpenGL;
namespace BizHawk.Client.EmuHawk
{
/// <summary>
/// Thinly wraps a BizwareGL.GraphicsControl for EmuHawk's needs
/// </summary>
public class PresentationPanel
{
public PresentationPanel()
{
GL = GlobalWin.GL;
GraphicsControl = GL.CreateGraphicsControl();
GraphicsControl.Control.Dock = DockStyle.Fill;
GraphicsControl.Control.BackColor = Color.Black;
//pass through these events to the form. we might need a more scalable solution for mousedown etc. for zapper and whatnot.
//http://stackoverflow.com/questions/547172/pass-through-mouse-events-to-parent-control (HTTRANSPARENT)
GraphicsControl.Control.MouseDoubleClick += (o, e) => HandleFullscreenToggle(o, e);
GraphicsControl.Control.MouseClick += (o, e) => GlobalWin.MainForm.MainForm_MouseClick(o, e);
}
public void Dispose()
{
GraphicsControl.Dispose();
}
//graphics resources
IGL GL;
public GraphicsControl GraphicsControl;
private bool Vsync;
public Control Control { get { return GraphicsControl.Control; } }
public static implicit operator Control(PresentationPanel self) { return self.GraphicsControl.Control; }
private void HandleFullscreenToggle(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
GlobalWin.MainForm.ToggleFullscreen();
}
public bool Resized { get; set; }
public sd.Point ScreenToScreen(sd.Point p)
{
//TODO GL - yeah, this is broken for now, sorry.
//This logic now has more to do with DisplayManager
//p = GraphicsControl.Control.PointToClient(p);
//sd.Point ret = new sd.Point(p.X * sw / GraphicsControl.Control.Width,
// p.Y * sh / GraphicsControl.Control.Height);
//return ret;
throw new InvalidOperationException("Not supported right now, sorry");
}
public Size NativeSize { get { return GraphicsControl.Control.ClientSize; } }
}
public interface IBlitterFont { }
}

View File

@ -88,15 +88,6 @@ namespace BizHawk.Client.EmuHawk
}
}
[LuaMethodAttributes(
"getdisplayfilter",
"Gets the current display filter setting, possible values: 'None', 'x2SAI', 'SuperX2SAI', 'SuperEagle', 'Scanlines'"
)]
public string GetDisplayFilter()
{
return _filterMappings[Global.Config.TargetDisplayFilter];
}
[LuaMethodAttributes(
"gettargetscanlineintensity",
"Gets the current scanline intensity setting, used for the scanline display filter"
@ -266,22 +257,6 @@ namespace BizHawk.Client.EmuHawk
GlobalWin.MainForm.TakeScreenshotToClipboard();
}
[LuaMethodAttributes(
"setdisplayfilter",
"Sets the current display filter setting, possible values: 'None', 'x2SAI', 'SuperX2SAI', 'SuperEagle', 'Scanlines'"
)]
public void SetDisplayFilter(string filter)
{
foreach (var kvp in _filterMappings)
{
if (String.Equals(kvp.Value, filter, StringComparison.CurrentCultureIgnoreCase))
{
Global.Config.TargetDisplayFilter = kvp.Key;
return;
}
}
}
[LuaMethodAttributes(
"settargetscanlineintensity",
"Sets the current scanline intensity setting, used for the scanline display filter"

View File

@ -41,7 +41,6 @@ namespace BizHawk.Client.EmuHawk
int defaultWidth; //For saving the default size of the dialog, so the user can restore if desired
int defaultHeight;
SwappableBitmapBufferSet surfaceSet = new SwappableBitmapBufferSet();
List<DisplayTypeItem> displayTypeItems = new List<DisplayTypeItem>();
public bool UpdateBefore { get { return false; } }

View File

@ -14,6 +14,16 @@ namespace BizHawk.Bizware.BizwareGL
public abstract swf.Control Control { get; }
public static implicit operator swf.Control(GraphicsControl ctrl) { return ctrl.Control; }
/// <summary>
/// The width of the control
/// </summary>
public int Width { get { return Control.Width; } }
/// <summary>
/// The height of the control
/// </summary>
public int Height { get { return Control.Height; } }
/// <summary>
/// Sets whether presentation operations on this control will vsync