diff --git a/BizHawk.MultiClient/DisplayManager/DisplayManager.cs b/BizHawk.MultiClient/DisplayManager/DisplayManager.cs index c681c24a9a..18bee888bf 100644 --- a/BizHawk.MultiClient/DisplayManager/DisplayManager.cs +++ b/BizHawk.MultiClient/DisplayManager/DisplayManager.cs @@ -290,30 +290,27 @@ namespace BizHawk.MultiClient { public string FPS { get; set; } public string MT { get; set; } - private Font MessageFont; - private Font AlertFont; + IBlitterFont MessageFont; + IBlitterFont AlertFont; public void Dispose() { - if (MessageFont != null) - { - MessageFont.Dispose(); - MessageFont = null; - } - if (AlertFont != null) - { - AlertFont.Dispose(); - AlertFont = null; - } - } - public OSDManager() - { - //MessageFont = new Font(Device, 16, 0, FontWeight.Bold, 1, false, CharacterSet.Default, Precision.Default, FontQuality.Default, PitchAndFamily.Default | PitchAndFamily.DontCare, "Courier"); - //AlertFont = new Font(Device, 16, 0, FontWeight.ExtraBold, 1, true, CharacterSet.Default, Precision.Default, FontQuality.Default, PitchAndFamily.Default | PitchAndFamily.DontCare, "Courier"); - MessageFont = new Font("Courier", 14, FontStyle.Bold, GraphicsUnit.Pixel); - AlertFont = new Font("Courier", 14, FontStyle.Bold, GraphicsUnit.Pixel); + } - private float GetX(Graphics g, int x, int anchor, Font font, string message) + public void Begin(IBlitter blitter) + { + MessageFont = blitter.GetFontType("MessageFont"); + AlertFont = blitter.GetFontType("AlertFont"); + } + + public System.Drawing.Color FixedMessagesColor { get { return System.Drawing.Color.FromArgb(Global.Config.MessagesColor); } } + public System.Drawing.Color FixedAlertMessageColor { get { return System.Drawing.Color.FromArgb(Global.Config.AlertMessageColor); } } + + public OSDManager() + { + } + + private float GetX(IBlitter g, int x, int anchor, IBlitterFont font, string message) { var size = g.MeasureString(message, font); //Rectangle rect = g.MeasureString(Sprite, message, new DrawTextFormat()); @@ -329,7 +326,7 @@ namespace BizHawk.MultiClient } } - private float GetY(Graphics g, int y, int anchor, Font font, string message) + private float GetY(IBlitter g, int y, int anchor, IBlitterFont font, string message) { var size = g.MeasureString(message, font); switch (anchor) @@ -377,9 +374,9 @@ namespace BizHawk.MultiClient messages.Add(new UIMessage { Message = message, ExpireAt = DateTime.Now + TimeSpan.FromSeconds(2) }); } - public void AddGUIText(string message, int x, int y, bool alert, Brush BackGround, Brush ForeColor, int anchor) + public void AddGUIText(string message, int x, int y, bool alert, Color BackGround, Color ForeColor, int anchor) { - GUITextList.Add(new UIDisplay { Message = message, X = x, Y = y, BackGround = BackGround, ForeColor = ForeColor, Alert = alert, Anchor = anchor }); + GUITextList.Add(new UIDisplay { Message = message, X = x, Y = y, BackGround = BackGround, ForeColor = ForeColor, Alert = alert, Anchor = anchor }); } public void ClearGUIText() @@ -388,7 +385,7 @@ namespace BizHawk.MultiClient } - public void DrawMessages(Graphics g) + public void DrawMessages(IBlitter g) { //todo - not so much brush object churn? @@ -399,31 +396,29 @@ namespace BizHawk.MultiClient { float x = 3; float y = g.ClipBounds.Height - (line * 18); - g.DrawString(messages[i].Message, MessageFont, Brushes.Black, x + 2, y + 2); - using(var brush = new SolidBrush(Color.FromArgb(Global.Config.MessagesColor))) - g.DrawString(messages[i].Message, MessageFont, brush, x, y); + g.DrawString(messages[i].Message, MessageFont, Color.Black, x + 2, y + 2); + g.DrawString(messages[i].Message, MessageFont, FixedMessagesColor, x, y); } for (int x = 0; x < GUITextList.Count; x++) { - try - { - float posx = GetX(g, GUITextList[x].X, GUITextList[x].Anchor, MessageFont, GUITextList[x].Message); - float posy = GetY(g, GUITextList[x].Y, GUITextList[x].Anchor, MessageFont, GUITextList[x].Message); + try + { + float posx = GetX(g, GUITextList[x].X, GUITextList[x].Anchor, MessageFont, GUITextList[x].Message); + float posy = GetY(g, GUITextList[x].Y, GUITextList[x].Anchor, MessageFont, GUITextList[x].Message); - g.DrawString(GUITextList[x].Message, MessageFont, GUITextList[x].BackGround, posx + 2, posy + 2); - g.DrawString(GUITextList[x].Message, MessageFont, Brushes.Gray, posx + 1, posy + 1); + g.DrawString(GUITextList[x].Message, MessageFont, GUITextList[x].BackGround, posx + 2, posy + 2); + g.DrawString(GUITextList[x].Message, MessageFont, Color.Gray, posx + 1, posy + 1); - if (GUITextList[x].Alert) - using(var brush = new SolidBrush(Color.FromArgb(Global.Config.AlertMessageColor))) - g.DrawString(GUITextList[x].Message, MessageFont, brush, posx,posy); - else - g.DrawString(GUITextList[x].Message, MessageFont, GUITextList[x].ForeColor, posx, posy); - } - catch (Exception e) - { - return; - } - } + if (GUITextList[x].Alert) + g.DrawString(GUITextList[x].Message, MessageFont, FixedMessagesColor, posx, posy); + else + g.DrawString(GUITextList[x].Message, MessageFont, GUITextList[x].ForeColor, posx, posy); + } + catch (Exception e) + { + return; + } + } } @@ -450,16 +445,15 @@ namespace BizHawk.MultiClient /// /// Display all screen info objects like fps, frame counter, lag counter, and input display /// - public void DrawScreenInfo(Graphics g) + public void DrawScreenInfo(IBlitter g) { if (Global.Config.DisplayFrameCounter) { string message = MakeFrameCounter(); float x = GetX(g, Global.Config.DispFrameCx, Global.Config.DispFrameanchor, MessageFont, message); float y = GetY(g, Global.Config.DispFrameCy, Global.Config.DispFrameanchor, MessageFont, message); - g.DrawString(message, MessageFont, Brushes.Black, x + 1, y + 1); - using(var brush = new SolidBrush(Color.FromArgb(Global.Config.MessagesColor))) - g.DrawString(message, MessageFont, brush, x, y ); + g.DrawString(message, MessageFont, Color.Black, x + 1, y + 1); + g.DrawString(message, MessageFont, Color.FromArgb(Global.Config.MessagesColor), x, y); } if (Global.Config.DisplayInput) { @@ -474,27 +468,24 @@ namespace BizHawk.MultiClient else c = Color.FromArgb(Global.Config.MessagesColor); - g.DrawString(input, MessageFont, Brushes.Black, x+1,y+1); - using(var brush = new SolidBrush(c)) - g.DrawString(input, MessageFont, brush, x,y); + g.DrawString(input, MessageFont, Color.Black, x+1,y+1); + g.DrawString(input, MessageFont, c, x,y); } if (Global.MovieSession.MultiTrack.IsActive) { - g.DrawString(MT, MessageFont, Brushes.Black, + g.DrawString(MT, MessageFont, Color.Black, Global.Config.DispFPSx + 1, //TODO: Multitrack position variables Global.Config.DispFPSy + 1); - using(var brush = new SolidBrush(Color.FromArgb(Global.Config.MessagesColor))) - g.DrawString(MT, MessageFont, Brushes.Black, - Global.Config.DispFPSx, //TODO: Multitrack position variables - Global.Config.DispFPSy); + g.DrawString(MT, MessageFont, FixedMessagesColor, + Global.Config.DispFPSx, //TODO: Multitrack position variables + Global.Config.DispFPSy); } if (Global.Config.DisplayFPS && FPS != null) { float x = GetX(g, Global.Config.DispFPSx, Global.Config.DispFPSanchor, MessageFont, FPS); float y = GetY(g, Global.Config.DispFPSy, Global.Config.DispFPSanchor, MessageFont, FPS); - g.DrawString(FPS, MessageFont, Brushes.Black, x + 1, y + 1); - using(var brush = new SolidBrush(Color.FromArgb(Global.Config.MessagesColor))) - g.DrawString(FPS, MessageFont, brush, x, y); + g.DrawString(FPS, MessageFont, Color.Black, x + 1, y + 1); + g.DrawString(FPS, MessageFont, FixedMessagesColor, x, y); } if (Global.Config.DisplayLagCounter) @@ -505,21 +496,19 @@ namespace BizHawk.MultiClient { float x = GetX(g, Global.Config.DispLagx, Global.Config.DispLaganchor, AlertFont, counter); float y = GetY(g, Global.Config.DispLagy, Global.Config.DispLaganchor, AlertFont, counter); - g.DrawString(MakeLagCounter(), AlertFont, Brushes.Black, + g.DrawString(MakeLagCounter(), AlertFont, Color.Black, Global.Config.DispLagx + 1, Global.Config.DispLagy + 1); - using(var brush = new SolidBrush(Color.FromArgb(Global.Config.AlertMessageColor))) - g.DrawString(MakeLagCounter(), AlertFont, brush, - Global.Config.DispLagx, - Global.Config.DispLagy); + g.DrawString(MakeLagCounter(), AlertFont, FixedAlertMessageColor, + Global.Config.DispLagx, + Global.Config.DispLagy); } else { float x = GetX(g, Global.Config.DispLagx, Global.Config.DispLaganchor, MessageFont, counter); float y = GetY(g, Global.Config.DispLagy, Global.Config.DispLaganchor, MessageFont, counter); - g.DrawString(counter, MessageFont, Brushes.Black, x + 1, y + 1); - using(var brush = new SolidBrush(Color.FromArgb(Global.Config.MessagesColor))) - g.DrawString(counter, MessageFont, brush, x , y ); + g.DrawString(counter, MessageFont, Color.Black, x + 1, y + 1); + g.DrawString(counter, MessageFont, FixedMessagesColor, x , y ); } } @@ -528,26 +517,26 @@ namespace BizHawk.MultiClient string rerec = MakeRerecordCount(); float x = GetX(g, Global.Config.DispRecx, Global.Config.DispRecanchor, MessageFont, rerec); float y = GetY(g, Global.Config.DispRecy, Global.Config.DispRecanchor, MessageFont, rerec); - g.DrawString(rerec, MessageFont, Brushes.Black, x + 1, y + 1); - using(var brush = new SolidBrush(Color.FromArgb(Global.Config.MessagesColor))) - g.DrawString(rerec, MessageFont, brush, x , y); + g.DrawString(rerec, MessageFont, Color.Black, x + 1, y + 1); + g.DrawString(rerec, MessageFont, FixedMessagesColor, x, y); } if (Global.MovieSession.Movie.Mode == MOVIEMODE.PLAY) { - int r = (int)g.ClipBounds.Width; Point[] p = { new Point(r - 20, 2), new Point(r - 4, 12), new Point(r - 20, 22) }; - g.FillPolygon(new SolidBrush(Color.Red), p); - g.DrawPolygon(new Pen(new SolidBrush(Color.Pink)), p); + //TODO + //g.FillPolygon(new SolidBrush(Color.Red), p); + //g.DrawPolygon(new Pen(new SolidBrush(Color.Pink)), p); } else if (Global.MovieSession.Movie.Mode == MOVIEMODE.RECORD) { - g.FillEllipse(new SolidBrush(Color.Red), new Rectangle((int)g.ClipBounds.Width - 22, 2, 20, 20)); - g.DrawEllipse(new Pen(new SolidBrush(Color.Pink)), new Rectangle((int)g.ClipBounds.Width - 22, 2, 20, 20)); + //TODO + //g.FillEllipse(new SolidBrush(Color.Red), new Rectangle((int)g.ClipBounds.Width - 22, 2, 20, 20)); + //g.DrawEllipse(new Pen(new SolidBrush(Color.Pink)), new Rectangle((int)g.ClipBounds.Width - 22, 2, 20, 20)); } if (Global.MovieSession.Movie.Mode != MOVIEMODE.INACTIVE && Global.Config.DisplaySubtitles) @@ -557,11 +546,10 @@ namespace BizHawk.MultiClient if (s == null) return; for (int i = 0; i < s.Count; i++) { - g.DrawString(s[i].Message, MessageFont, Brushes.Black, + g.DrawString(s[i].Message, MessageFont, Color.Black, s[i].X + 1, s[i].Y + 1); - using (var brush = new SolidBrush(Color.FromArgb((int)s[i].Color))) - g.DrawString(s[i].Message, MessageFont, brush, - s[i].X, s[i].Y); + g.DrawString(s[i].Message, MessageFont, Color.FromArgb((int)s[i].Color), + s[i].X, s[i].Y); } } @@ -585,12 +573,6 @@ namespace BizHawk.MultiClient { //have at least something here at the start luaNativeSurfacePreOSD = new DisplaySurface(1, 1); - - wakeupEvent = new EventWaitHandle(false, EventResetMode.AutoReset); - suspendReplyEvent = new EventWaitHandle(false, EventResetMode.AutoReset); - displayThread = new Thread(ThreadProc); - displayThread.IsBackground = true; - displayThread.Start(); } volatile bool VsyncToggle = false; @@ -598,31 +580,50 @@ namespace BizHawk.MultiClient SwappableDisplaySurfaceSet sourceSurfaceSet = new SwappableDisplaySurfaceSet(); public void UpdateSource(IVideoProvider videoProvider) { - VsyncRequested = Global.Config.DisplayVSync; - - //needsclear = false because we're about to clobber the data with AcceptIntArray var newPendingSurface = sourceSurfaceSet.AllocateSurface(videoProvider.BufferWidth, videoProvider.BufferHeight, false); - newPendingSurface.AcceptIntArray((int[])videoProvider.GetVideoBuffer().Clone()); + newPendingSurface.AcceptIntArray(videoProvider.GetVideoBuffer()); sourceSurfaceSet.SetPending(newPendingSurface); - wakeupEvent.Set(); + + var renderPanel = Global.RenderPanel; + if (renderPanel == null) return; - if (VsyncRequested) - { - VsyncToggle = true; + currNativeWidth = Global.RenderPanel.NativeSize.Width; + currNativeHeight = Global.RenderPanel.NativeSize.Height; + + //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. + //IDisplayFilter filter = new Hq2xBase_Super2xSai(); + //var tempSurface = filter.Execute(currentSourceSurface); + //currentSourceSurface.Dispose(); + //currentSourceSurface = tempSurface; + + currentSourceSurface = sourceSurfaceSet.GetCurrent(); + + if (currentSourceSurface == null) return; + + int w = currNativeWidth; + int h = currNativeHeight; + + DisplaySurface luaEmuSurface = luaEmuSurfaceSet.GetCurrent(); + DisplaySurface luaSurface = luaNativeSurfaceSet.GetCurrent(); + + //do we have anything to do? + //bool complexComposite = false; + //if (luaEmuSurface != null) complexComposite = true; + //if (luaSurface != null) complexComposite = true; + + Global.RenderPanel.Clear(Color.FromArgb(videoProvider.BackgroundColor)); + Global.RenderPanel.Render(currentSourceSurface); + if (luaEmuSurface != null) + Global.RenderPanel.RenderOverlay(luaEmuSurface); + + RenderOSD(); + + Global.RenderPanel.Present(); - for (; ; ) - { - //if (Direct3DRenderPanel.vsyncEvent.WaitOne(1)) break; - if (!VsyncToggle) break; - Application.DoEvents(); - } - } - //for(;;) - //{ - // if (Direct3DRenderPanel.vsyncEvent.WaitOne(1)) break; - // Application.DoEvents(); - //} } public bool Disposed { get; private set; } @@ -630,10 +631,6 @@ namespace BizHawk.MultiClient public void Dispose() { if (Disposed) return; - shutdownFlag = true; - VsyncToggle = true; - while (shutdownFlag) Thread.Sleep(1); - wakeupEvent.Dispose(); Disposed = true; } @@ -663,42 +660,13 @@ namespace BizHawk.MultiClient } int currNativeWidth, currNativeHeight; - EventWaitHandle wakeupEvent, suspendReplyEvent; - bool shutdownFlag, suspendFlag; - void ThreadProc() - { - for (; ; ) - { - Display(); - - //wait until we receive something interesting, or just a little while anyway - wakeupEvent.WaitOne(1); - - if (suspendFlag) - { - suspendFlag = false; - suspendReplyEvent.Set(); - wakeupEvent.WaitOne(); - suspendReplyEvent.Set(); - wakeupEvent.WaitOne(); - suspendReplyEvent.Set(); - } - - if (shutdownFlag) break; - } - shutdownFlag = false; - } + /// /// suspends the display manager so that tricky things can be changed without the display thread going in and getting all confused and hating /// public void Suspend() { - suspendFlag = true; - wakeupEvent.Set(); - suspendReplyEvent.WaitOne(); - wakeupEvent.Set(); - suspendReplyEvent.WaitOne(); } /// @@ -706,126 +674,20 @@ namespace BizHawk.MultiClient /// public void Resume() { - wakeupEvent.Set(); - suspendReplyEvent.WaitOne(); + } + + void RenderOSD() + { + Global.OSD.Begin((IBlitter)Global.RenderPanel); + ((IBlitter)Global.RenderPanel).Open(); + Global.OSD.DrawScreenInfo((IBlitter)Global.RenderPanel); + Global.OSD.DrawMessages((IBlitter)Global.RenderPanel); + ((IBlitter)Global.RenderPanel).Close(); } SwappableDisplaySurfaceSet nativeDisplaySurfaceSet = new SwappableDisplaySurfaceSet(); - /// - /// internal display worker proc; runs through the multiply layered display pipeline - /// - void Display() - { - var renderPanel = Global.RenderPanel; - if (renderPanel == null) return; - - currNativeWidth = Global.RenderPanel.NativeSize.Width; - currNativeHeight = Global.RenderPanel.NativeSize.Height; - - //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. - //IDisplayFilter filter = new Hq2xBase_Super2xSai(); - //var tempSurface = filter.Execute(currentSourceSurface); - //currentSourceSurface.Dispose(); - //currentSourceSurface = tempSurface; - - currentSourceSurface = sourceSurfaceSet.GetCurrent(); - - if (currentSourceSurface == null) return; - - int w = currNativeWidth; - int h = currNativeHeight; - - DisplaySurface luaEmuSurface = luaEmuSurfaceSet.GetCurrent(); - DisplaySurface luaSurface = luaNativeSurfaceSet.GetCurrent(); - - //do we have anything to do? - bool complexComposite = false; - if (luaEmuSurface != null) complexComposite = true; - if (luaSurface != null) complexComposite = true; - - if (!complexComposite) - { - if (Global.Config.SuppressGui) - { - Global.RenderPanel.Render(currentSourceSurface); - } - else - { - Global.RenderPanel.Render(currentSourceSurface); - var nativeBmp = nativeDisplaySurfaceSet.AllocateSurface(w, h, true); - using (var g = Graphics.FromImage(nativeBmp.PeekBitmap())) - { - Global.OSD.DrawScreenInfo(g); - Global.OSD.DrawMessages(g); - //Thread.Sleep(1); - } - nativeBmp.FromBitmap(); - Global.RenderPanel.RenderOverlay(nativeBmp); - //release the native resolution image - nativeDisplaySurfaceSet.ReleaseSurface(nativeBmp); - //Global.RenderPanel.Present(); - } - } - else - { - var nativeBmp = nativeDisplaySurfaceSet.AllocateSurface(w, h, true); - using (var g = Graphics.FromImage(nativeBmp.PeekBitmap())) - { - //scale the source bitmap to the desired size of the render panel - g.PixelOffsetMode = PixelOffsetMode.HighSpeed; - g.InterpolationMode = InterpolationMode.NearestNeighbor; - g.CompositingMode = CompositingMode.SourceCopy; - g.CompositingQuality = CompositingQuality.HighSpeed; - g.DrawImage(currentSourceSurface.PeekBitmap(), 0, 0, w, h); - - //switch to fancier composition for OSD overlays and such - g.CompositingMode = CompositingMode.SourceOver; - - //this could have been done onto the source surface earlier and then scaled only once but the whole composition system needs revising, soo.. - if (luaEmuSurface != null) g.DrawImage(luaEmuSurface.PeekBitmap(), 0, 0, w, h); - g.Clip = new Region(new Rectangle(0, 0, nativeBmp.Width, nativeBmp.Height)); - - //apply a lua layer - if (luaSurface != null) g.DrawImageUnscaled(luaSurface.PeekBitmap(), 0, 0); - //although we may want to change this if we want to fade out messages or have some other fancy alpha faded gui stuff - - //draw the OSD at native resolution - if (!Global.Config.SuppressGui) - { - Global.OSD.DrawScreenInfo(g); - Global.OSD.DrawMessages(g); - } - g.Clip.Dispose(); - } - - //send the native resolution image to the render panel - Global.RenderPanel.Render(nativeBmp); - //Global.RenderPanel.Present(); - - //release the native resolution image - nativeDisplaySurfaceSet.ReleaseSurface(nativeBmp); - } - - Global.RenderPanel.Present(); - - if (VsyncRequested) - { - for (; ; ) - { - //if (Direct3DRenderPanel.vsyncEvent.WaitOne(1)) break; - if (VsyncToggle) break; - } - VsyncToggle = false; - } - - - } - Thread displayThread; } } \ No newline at end of file diff --git a/BizHawk.MultiClient/LuaImplementation.cs b/BizHawk.MultiClient/LuaImplementation.cs index 166ec408e3..a36061e494 100644 --- a/BizHawk.MultiClient/LuaImplementation.cs +++ b/BizHawk.MultiClient/LuaImplementation.cs @@ -168,33 +168,28 @@ namespace BizHawk.MultiClient return Convert.ToUInt32((double)lua_arg); } - public Pen GetPen(object color) - { - System.Drawing.Pen myPen; - if (color.GetType() == typeof(Double)) - { - myPen = new System.Drawing.Pen(System.Drawing.Color.FromArgb(int.Parse(long.Parse(color.ToString()).ToString("X"), System.Globalization.NumberStyles.HexNumber))); - } - else - { - myPen = new System.Drawing.Pen(System.Drawing.Color.FromName(color.ToString().ToLower())); - } - return myPen; - } - public SolidBrush GetBrush(object color) - { - System.Drawing.SolidBrush myBrush; - if (color.GetType() == typeof(Double)) - { - myBrush = new System.Drawing.SolidBrush(System.Drawing.Color.FromArgb(int.Parse(long.Parse(color.ToString()).ToString("X"), System.Globalization.NumberStyles.HexNumber))); - } - else - { - myBrush = new System.Drawing.SolidBrush(System.Drawing.Color.FromName(color.ToString().ToLower())); - } - return myBrush; - } + public Color GetColor(object color) + { + if (color.GetType() == typeof(Double)) + { + return System.Drawing.Color.FromArgb(int.Parse(long.Parse(color.ToString()).ToString("X"), System.Globalization.NumberStyles.HexNumber)); + } + else + { + return System.Drawing.Color.FromName(color.ToString().ToLower()); + } + } + + public SolidBrush GetBrush(object color) + { + return new System.Drawing.SolidBrush(GetColor(color)); + } + public Pen GetPen(object color) + { + return new System.Drawing.Pen(GetColor(color)); + } + /** * LuaInterface requires the exact match of parameter count, @@ -455,12 +450,12 @@ namespace BizHawk.MultiClient a = LuaInt(anchor); } } - Global.OSD.AddGUIText(luaStr.ToString(), LuaInt(luaX), LuaInt(luaY), alert, GetBrush(background), GetBrush(forecolor), a); + Global.OSD.AddGUIText(luaStr.ToString(), LuaInt(luaX), LuaInt(luaY), alert, GetColor(background), GetColor(forecolor), a); } - public void gui_text(object luaX, object luaY, object luaStr, object background = null, object forecolor = null, object anchor = null) + public void gui_text(object luaX, object luaY, object luaStr, object background = null, object forecolor = null, object anchor = null) { - do_gui_text(luaX, luaY, luaStr, false, background, forecolor, anchor); + do_gui_text(luaX, luaY, luaStr, false, background, forecolor, anchor); } public void gui_alert(object luaX, object luaY, object luaStr, object anchor = null) @@ -524,7 +519,8 @@ namespace BizHawk.MultiClient int int_height = LuaInt(height); g.DrawRectangle(GetPen(line), int_x, int_y, int_width, int_height); if (background != null) - g.FillRectangle(GetBrush(background), int_x, int_y, int_width, int_height); + using(var brush = GetBrush(background)) + g.FillRectangle(brush, int_x, int_y, int_width, int_height); } catch(Exception) { @@ -572,10 +568,14 @@ namespace BizHawk.MultiClient { try { - g.DrawEllipse(GetPen(line), LuaInt(X), LuaInt(Y), LuaInt(width), LuaInt(height)); - if (background != null) + using (var pen = GetPen(line)) { - g.FillEllipse(GetBrush(background), LuaInt(X), LuaInt(Y), LuaInt(width), LuaInt(height)); + g.DrawEllipse(pen, LuaInt(X), LuaInt(Y), LuaInt(width), LuaInt(height)); + if (background != null) + { + using (var brush = GetBrush(background)) + g.FillEllipse(brush, LuaInt(X), LuaInt(Y), LuaInt(width), LuaInt(height)); + } } } @@ -601,11 +601,15 @@ namespace BizHawk.MultiClient Points[i] = new System.Drawing.Point(LuaInt(point[1]), LuaInt(point[2])); i++; } - - g.DrawPolygon(GetPen(line), Points); - if (background != null) + + using (var pen = GetPen(line)) { - g.FillPolygon(GetBrush(background), Points); + g.DrawPolygon(pen, Points); + if (background != null) + { + using (var brush = GetBrush(background)) + g.FillPolygon(brush, Points); + } } } catch (Exception) @@ -645,10 +649,14 @@ namespace BizHawk.MultiClient { try { - g.DrawPie(GetPen(line), LuaInt(X), LuaInt(Y), LuaInt(width), LuaInt(height), LuaInt(startangle), LuaInt(sweepangle)); - if (background != null) + using(var pen = GetPen(line)) { - g.FillPie(GetBrush(background), LuaInt(X), LuaInt(Y), LuaInt(width), LuaInt(height), LuaInt(startangle), LuaInt(sweepangle)); + g.DrawPie(pen, LuaInt(X), LuaInt(Y), LuaInt(width), LuaInt(height), LuaInt(startangle), LuaInt(sweepangle)); + if (background != null) + { + using(var brush = GetBrush(background)) + g.FillPie(brush, LuaInt(X), LuaInt(Y), LuaInt(width), LuaInt(height), LuaInt(startangle), LuaInt(sweepangle)); + } } } diff --git a/BizHawk.MultiClient/RenderPanel.cs b/BizHawk.MultiClient/RenderPanel.cs index 4bffa580d7..fb3bbc0722 100644 --- a/BizHawk.MultiClient/RenderPanel.cs +++ b/BizHawk.MultiClient/RenderPanel.cs @@ -2,6 +2,7 @@ using System.Runtime.InteropServices; using System.Collections.Generic; using System.Drawing; +using sysdrawingfont=System.Drawing.Font; using sysdrawing2d=System.Drawing.Drawing2D; using System.Drawing.Imaging; using System.IO; @@ -11,7 +12,7 @@ using System.Windows.Forms; #if WINDOWS using SlimDX; using SlimDX.Direct3D9; -using Font = SlimDX.Direct3D9.Font; +using d3d9font=SlimDX.Direct3D9.Font; #endif using BizHawk.Core; @@ -63,7 +64,6 @@ namespace BizHawk.MultiClient } } - // If we need to recreate the texture, do so. if (needsRecreating) { @@ -83,6 +83,8 @@ namespace BizHawk.MultiClient Texture = new Texture(GraphicsDevice, textureWidth, textureHeight, 1, Usage.Dynamic, Format.A8R8G8B8, Pool.Default); } + surface.FromBitmap(); + // Copy the image data to the texture. using (var Data = Texture.LockRectangle(0, LockFlags.Discard | LockFlags.NoDirtyUpdate).Data) { @@ -122,34 +124,29 @@ namespace BizHawk.MultiClient } #endif - public interface IRenderer : IDisposable { void FastRenderAndPresent(DisplaySurface surface); void Render(DisplaySurface surface); void RenderOverlay(DisplaySurface surface); + void Clear(System.Drawing.Color color); void Present(); bool Resized { get; set; } Size NativeSize { get; } } - public class SysdrawingRenderPanel : IRenderer + public class SysdrawingRenderPanel : IRenderer, IBlitter { + sysdrawingfont MessageFont; + sysdrawingfont AlertFont; + DisplaySurface tempBuffer; + Graphics g; + public bool Resized { get; set; } public void Dispose() { } public void Render(DisplaySurface surface) { backingControl.ReleaseCallback = RetainedViewportPanelDisposeCallback; - //Color BackgroundColor = Color.FromArgb(video.BackgroundColor); - //int[] data = video.GetVideoBuffer(); - - //Bitmap bmp = new Bitmap(video.BufferWidth, video.BufferHeight, PixelFormat.Format32bppArgb); - //BitmapData bmpdata = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); - - ////TODO - this is not very intelligent. no handling of pitch, for instance - //Marshal.Copy(data, 0, bmpdata.Scan0, bmp.Width * bmp.Height); - - //bmp.UnlockBits(bmpdata); lock(this) tempBuffer = surfaceSet.AllocateSurface(backingControl.Width, backingControl.Height, false); @@ -158,7 +155,52 @@ namespace BizHawk.MultiClient } SwappableDisplaySurfaceSet surfaceSet = new SwappableDisplaySurfaceSet(); - DisplaySurface tempBuffer; + class FontWrapper : IBlitterFont + { + public FontWrapper(sysdrawingfont font) + { + this.font = font; + } + public sysdrawingfont font; + } + + public Size NativeSize { get { return backingControl.ClientSize; } } + + IBlitterFont IBlitter.GetFontType(string fontType) + { + if (fontType == "MessageFont") return new FontWrapper(MessageFont); + if (fontType == "AlertFont") return new FontWrapper(AlertFont); + return null; + } + + void IBlitter.Open() + { + g = Graphics.FromImage(tempBuffer.PeekBitmap()); + } + + void IBlitter.Close() + { + g.Dispose(); + } + + void IBlitter.DrawString(string s, IBlitterFont font, Color color, float x, float y) + { + using (var brush = new SolidBrush(color)) + g.DrawString(s, ((FontWrapper)font).font, brush, x, y); + } + + SizeF IBlitter.MeasureString(string s, IBlitterFont _font) + { + var font = ((FontWrapper)_font).font; + return g.MeasureString(s, font); + } + + public void Clear(Color color) + { + //todo + } + + Rectangle IBlitter.ClipBounds { get; set; } bool RetainedViewportPanelDisposeCallback(Bitmap bmp) { @@ -205,13 +247,28 @@ namespace BizHawk.MultiClient public SysdrawingRenderPanel(RetainedViewportPanel control) { backingControl = control; + MessageFont = new sysdrawingfont("Courier", 14, FontStyle.Bold, GraphicsUnit.Pixel); + AlertFont = new sysdrawingfont("Courier", 14, FontStyle.Bold, GraphicsUnit.Pixel); } RetainedViewportPanel backingControl; - public Size NativeSize { get { return backingControl.ClientSize; } } } + public interface IBlitter + { + void Open(); + void Close(); + 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; } + } + + public interface IBlitterFont { } + + #if WINDOWS - public class Direct3DRenderPanel : IRenderer + + public class Direct3DRenderPanel : IRenderer, IBlitter { public Color BackgroundColor { get; set; } public bool Resized { get; set; } @@ -222,11 +279,48 @@ namespace BizHawk.MultiClient private Control backingControl; public ImageTexture Texture; private Sprite Sprite; + private d3d9font MessageFont; + private d3d9font AlertFont; + + class FontWrapper : IBlitterFont + { + public FontWrapper(d3d9font font) + { + this.font = font; + } + public d3d9font font; + } + + void IBlitter.Open() {} + void IBlitter.Close() {} private bool Vsync; public Size NativeSize { get { return backingControl.ClientSize; } } + IBlitterFont IBlitter.GetFontType(string fontType) + { + if (fontType == "MessageFont") return new FontWrapper(MessageFont); + if (fontType == "AlertFont") return new FontWrapper(AlertFont); + return null; + } + + Color4 col(Color c) { return new Color4(c.ToArgb()); } + + void IBlitter.DrawString(string s, IBlitterFont font, Color color, float x, float y) + { + ((FontWrapper)font).font.DrawString(null, s, (int)x + 1, (int)y + 1, col(color)); + } + + SizeF IBlitter.MeasureString(string s, IBlitterFont _font) + { + var font = ((FontWrapper)_font).font; + Rectangle r = font.MeasureString(null, s, DrawTextFormat.Left); + return new SizeF(r.Width, r.Height); + } + + Rectangle IBlitter.ClipBounds { get; set; } + public Direct3DRenderPanel(Direct3D direct3D, Control control) { d3d = direct3D; @@ -259,6 +353,17 @@ namespace BizHawk.MultiClient Device.Dispose(); Device = null; } + + if (MessageFont != null) + { + MessageFont.Dispose(); + MessageFont = null; + } + if (AlertFont != null) + { + AlertFont.Dispose(); + AlertFont = null; + } } private bool VsyncRequested @@ -291,6 +396,11 @@ namespace BizHawk.MultiClient Sprite = new Sprite(Device); Texture = new ImageTexture(Device); + MessageFont = new d3d9font(Device, 16, 0, FontWeight.Bold, 1, false, CharacterSet.Default, Precision.Default, FontQuality.Default, PitchAndFamily.Default | PitchAndFamily.DontCare, "Courier"); + AlertFont = new d3d9font(Device, 16, 0, FontWeight.ExtraBold, 1, true, CharacterSet.Default, Precision.Default, FontQuality.Default, PitchAndFamily.Default | PitchAndFamily.DontCare, "Courier"); + // NOTE: if you add ANY objects, like new fonts, textures, etc, to this method + // ALSO add dispose code in DestroyDevice() or you will be responsible for VRAM memory leaks. + } public void Render() @@ -342,27 +452,27 @@ namespace BizHawk.MultiClient } } + void RenderPrep() + { + if (Device == null || Resized || Vsync != VsyncRequested) + backingControl.Invoke(() => CreateDevice()); + Resized = false; + } + + public void Clear(Color color) + { + Device.Clear(ClearFlags.Target, col(color), 0.0f, 0); + } + private void RenderExec(DisplaySurface surface, bool overlay) { + RenderPrep(); if (surface == null) { Render(); return; } - if (Device == null || Resized || Vsync != VsyncRequested) - backingControl.Invoke(() => CreateDevice()); - Resized = false; - - - - //TODO - //BackgroundColor = Color.FromArgb(video.BackgroundColor); - if (overlay) - { - //return; - } - Texture.SetImage(surface, surface.Width, surface.Height); if(!overlay) Device.Clear(ClearFlags.Target, BackgroundColor, 0.0f, 0); @@ -380,7 +490,6 @@ namespace BizHawk.MultiClient Device.SetSamplerState(0, SamplerState.MinFilter, TextureFilter.Point); Sprite.Transform = Matrix.Scaling(finalScale, finalScale, 0f); Sprite.Draw(Texture.Texture, new Rectangle(0, 0, surface.Width, surface.Height), new Vector3(surface.Width / 2f, surface.Height / 2f, 0), new Vector3(backingControl.Size.Width / 2f / finalScale, backingControl.Size.Height / 2f / finalScale, 0), Color.White); - //if (overlay) Device.SetRenderState(RenderState.AlphaBlendEnable, false); Sprite.End(); Device.EndScene(); @@ -388,7 +497,6 @@ namespace BizHawk.MultiClient public void Present() { - //Device.Present(SlimDX.Direct3D9.Present.DoNotWait); Device.Present(SlimDX.Direct3D9.Present.None); vsyncEvent.Set(); } @@ -423,7 +531,7 @@ namespace BizHawk.MultiClient public int Y; public bool Alert; public int Anchor; - public Brush ForeColor; - public Brush BackGround; + public Color ForeColor; + public Color BackGround; } } diff --git a/BizHawk.MultiClient/tools/RamWatch.cs b/BizHawk.MultiClient/tools/RamWatch.cs index 306232c60d..5228c4c4ea 100644 --- a/BizHawk.MultiClient/tools/RamWatch.cs +++ b/BizHawk.MultiClient/tools/RamWatch.cs @@ -79,7 +79,7 @@ namespace BizHawk.MultiClient { bool alert = Global.CheatList.IsActiveCheat(Domain, watchList[x].address); Global.OSD.AddGUIText(watchList[x].ToString(), - Global.Config.DispRamWatchx, (Global.Config.DispRamWatchy + (x * 14)), alert, Brushes.Black, Brushes.White, 0); + Global.Config.DispRamWatchx, (Global.Config.DispRamWatchy + (x * 14)), alert, Color.Black, Color.White, 0); } }