From ae76335cad0e837e790c5338ee00ef5256fff317 Mon Sep 17 00:00:00 2001 From: YoshiRulz Date: Thu, 23 Jul 2026 01:33:03 +1000 Subject: [PATCH 1/6] Remove `IGuiApi.{Get,Set}Padding`, which seems to have never been used --- src/BizHawk.Client.Common/Api/Classes/GuiApi.cs | 10 ---------- src/BizHawk.Client.Common/Api/Interfaces/IGuiApi.cs | 5 ----- 2 files changed, 15 deletions(-) diff --git a/src/BizHawk.Client.Common/Api/Classes/GuiApi.cs b/src/BizHawk.Client.Common/Api/Classes/GuiApi.cs index ce448247e00..53fc2c32219 100644 --- a/src/BizHawk.Client.Common/Api/Classes/GuiApi.cs +++ b/src/BizHawk.Client.Common/Api/Classes/GuiApi.cs @@ -47,8 +47,6 @@ private static Bitmap NullGraphicsBitmap private Color _defaultTextBackground = Color.FromArgb(128, 0, 0, 0); - private (int Left, int Top, int Right, int Bottom) _padding = (0, 0, 0, 0); - private FontFamily[]/*?*/ _pixelFonts = null; private DisplaySurfaceID? _usingSurfaceID; @@ -129,14 +127,6 @@ public void DrawNew(string name, bool clear) public void DrawFinish() => LogCallback("the `DrawFinish()` function has been deprecated"); - public void SetPadding(int all) => _padding = (all, all, all, all); - - public void SetPadding(int x, int y) => _padding = (x / 2, y / 2, x / 2 + x & 1, y / 2 + y & 1); - - public void SetPadding(int l, int t, int r, int b) => _padding = (l, t, r, b); - - public (int Left, int Top, int Right, int Bottom) GetPadding() => _padding; - public void AddMessage(string message, [LiteralExpected] int? duration = null) => _dialogController.AddOnScreenMessage(message, duration); diff --git a/src/BizHawk.Client.Common/Api/Interfaces/IGuiApi.cs b/src/BizHawk.Client.Common/Api/Interfaces/IGuiApi.cs index a2c3311037a..4cbf36b98e9 100644 --- a/src/BizHawk.Client.Common/Api/Interfaces/IGuiApi.cs +++ b/src/BizHawk.Client.Common/Api/Interfaces/IGuiApi.cs @@ -26,11 +26,6 @@ public interface IGuiApi : IDisposable, IExternalApi [Obsolete("Always true")] bool HasGUISurface { get; } - void SetPadding(int all); - void SetPadding(int x, int y); - void SetPadding(int l, int t, int r, int b); - (int Left, int Top, int Right, int Bottom) GetPadding(); - void AddMessage(string message, int? duration = null); void ClearGraphics(DisplaySurfaceID? surfaceID = null); From 8e7f36b3281aa7b1ef810fffb9f95b329ab1b593 Mon Sep 17 00:00:00 2001 From: YoshiRulz Date: Thu, 23 Jul 2026 01:36:46 +1000 Subject: [PATCH 2/6] Remove `IGuiApi` members deprecated in 2.6 see 7749d0238 --- .../Api/Classes/GuiApi.cs | 18 ------------------ .../Api/Interfaces/IGuiApi.cs | 9 --------- .../tools/Lua/Libraries/GuiLuaLibrary.cs | 14 -------------- 3 files changed, 41 deletions(-) diff --git a/src/BizHawk.Client.Common/Api/Classes/GuiApi.cs b/src/BizHawk.Client.Common/Api/Classes/GuiApi.cs index 53fc2c32219..df9300b891e 100644 --- a/src/BizHawk.Client.Common/Api/Classes/GuiApi.cs +++ b/src/BizHawk.Client.Common/Api/Classes/GuiApi.cs @@ -50,7 +50,6 @@ private static Bitmap NullGraphicsBitmap private FontFamily[]/*?*/ _pixelFonts = null; private DisplaySurfaceID? _usingSurfaceID; - public bool HasGUISurface => true; public GuiApi( IDialogController dialogController, @@ -110,23 +109,6 @@ public void WithSurface(DisplaySurfaceID surfaceID, Action drawingCallsFunc) } } - public void DrawNew(string name, bool clear) - { - switch (name) - { - case null: - case "emu": - LogCallback("the `DrawNew(\"emu\")` function has been deprecated"); - return; - case "native": - throw new InvalidOperationException("the ability to draw in the margins with `DrawNew(\"native\")` has been removed"); - default: - throw new InvalidOperationException("invalid surface name"); - } - } - - public void DrawFinish() => LogCallback("the `DrawFinish()` function has been deprecated"); - public void AddMessage(string message, [LiteralExpected] int? duration = null) => _dialogController.AddOnScreenMessage(message, duration); diff --git a/src/BizHawk.Client.Common/Api/Interfaces/IGuiApi.cs b/src/BizHawk.Client.Common/Api/Interfaces/IGuiApi.cs index 4cbf36b98e9..6932fe9ea03 100644 --- a/src/BizHawk.Client.Common/Api/Interfaces/IGuiApi.cs +++ b/src/BizHawk.Client.Common/Api/Interfaces/IGuiApi.cs @@ -17,15 +17,6 @@ public interface IGuiApi : IDisposable, IExternalApi [Obsolete("use the other overload e.g. `APIs.Gui.WithSurface(..., gui => { gui.DrawLine(...); });`")] void WithSurface(DisplaySurfaceID surfaceID, Action drawingCallsFunc); - [Obsolete("No longer supported, no-op.")] - void DrawNew(string name, bool clear = true); - - [Obsolete("No longer supported, no-op.")] - void DrawFinish(); - - [Obsolete("Always true")] - bool HasGUISurface { get; } - void AddMessage(string message, int? duration = null); void ClearGraphics(DisplaySurfaceID? surfaceID = null); diff --git a/src/BizHawk.Client.EmuHawk/tools/Lua/Libraries/GuiLuaLibrary.cs b/src/BizHawk.Client.EmuHawk/tools/Lua/Libraries/GuiLuaLibrary.cs index 4c06f27caa2..a42067eab9e 100644 --- a/src/BizHawk.Client.EmuHawk/tools/Lua/Libraries/GuiLuaLibrary.cs +++ b/src/BizHawk.Client.EmuHawk/tools/Lua/Libraries/GuiLuaLibrary.cs @@ -18,20 +18,6 @@ public GuiLuaLibrary(ILuaLibraries luaLibsImpl, ApiContainer apiContainer, Actio private DisplaySurfaceID UseOrFallback(string surfaceName) => DisplaySurfaceIDParser.Parse(surfaceName) ?? _rememberedSurfaceID; -#pragma warning disable CS0612 -#pragma warning disable CS0618 - [LuaDeprecatedMethod] - [LuaMethod("DrawNew", "Changes drawing target to the specified lua surface name. This may clobber any previous drawing to this surface (pass false if you don't want it to)")] - public void DrawNew(string name, bool? clear = true) - => APIs.Gui.DrawNew(name, clear ?? true); - - [LuaDeprecatedMethod] - [LuaMethod("DrawFinish", "Finishes drawing to the current lua surface and causes it to get displayed.")] - public void DrawFinish() - => APIs.Gui.DrawFinish(); -#pragma warning restore CS0612 -#pragma warning restore CS0618 - [LuaMethodExample("gui.addmessage( \"Some message\" );")] [LuaMethod("addmessage", "Adds a message to the OSD's message area")] public void AddMessage(string message) From bcd0fe4b0453892b8124d870d6c6963c82c6d5a5 Mon Sep 17 00:00:00 2001 From: YoshiRulz Date: Wed, 22 Jul 2026 23:37:38 +1000 Subject: [PATCH 3/6] Remove `IGuiApi.DrawText`, deprecated in 2.9 see 6387291e3 --- src/BizHawk.Client.Common/Api/Classes/GuiApi.cs | 10 ---------- src/BizHawk.Client.Common/Api/Interfaces/IGuiApi.cs | 4 ---- 2 files changed, 14 deletions(-) diff --git a/src/BizHawk.Client.Common/Api/Classes/GuiApi.cs b/src/BizHawk.Client.Common/Api/Classes/GuiApi.cs index df9300b891e..2450719b4f3 100644 --- a/src/BizHawk.Client.Common/Api/Classes/GuiApi.cs +++ b/src/BizHawk.Client.Common/Api/Classes/GuiApi.cs @@ -462,16 +462,6 @@ public void DrawString(int x, int y, string message, Color? forecolor = null, Co } } - public void DrawText(int x, int y, string message, Color? forecolor = null, Color? backcolor = null, string fontfamily = null, DisplaySurfaceID? surfaceID = null) - => PixelText( - x: x, - y: y, - message: message, - forecolor: forecolor, - backcolor: backcolor, - fontfamily: fontfamily, - surfaceID: surfaceID); - public void PixelText( int x, int y, diff --git a/src/BizHawk.Client.Common/Api/Interfaces/IGuiApi.cs b/src/BizHawk.Client.Common/Api/Interfaces/IGuiApi.cs index 6932fe9ea03..379a8626ab5 100644 --- a/src/BizHawk.Client.Common/Api/Interfaces/IGuiApi.cs +++ b/src/BizHawk.Client.Common/Api/Interfaces/IGuiApi.cs @@ -46,10 +46,6 @@ public interface IGuiApi : IDisposable, IExternalApi /// exposed to Lua as gui.drawString and alias gui.drawText void DrawString(int x, int y, string message, Color? forecolor = null, Color? backcolor = null, int? fontsize = null, string fontfamily = null, string fontstyle = null, string horizalign = null, string vertalign = null, DisplaySurfaceID? surfaceID = null); - /// exposed to Lua as gui.pixelText - [Obsolete("method renamed to PixelText to match Lua")] - void DrawText(int x, int y, string message, Color? forecolor = null, Color? backcolor = null, string fontfamily = null, DisplaySurfaceID? surfaceID = null); - /// exposed to Lua as gui.pixelText void PixelText(int x, int y, string message, Color? forecolor = null, Color? backcolor = null, string fontfamily = null, DisplaySurfaceID? surfaceID = null); From 52eb7c367ca79f28fe0c8e8a5505eb1a754baadf Mon Sep 17 00:00:00 2001 From: YoshiRulz Date: Wed, 22 Jul 2026 23:41:11 +1000 Subject: [PATCH 4/6] Remove `IGuiApi.{Get,Set}Attributes`, deprecated in 2.10 see 476ac94d8 --- src/BizHawk.Client.Common/Api/Classes/GuiApi.cs | 7 ------- src/BizHawk.Client.Common/Api/Interfaces/IGuiApi.cs | 6 ------ 2 files changed, 13 deletions(-) diff --git a/src/BizHawk.Client.Common/Api/Classes/GuiApi.cs b/src/BizHawk.Client.Common/Api/Classes/GuiApi.cs index 2450719b4f3..3f56ed29738 100644 --- a/src/BizHawk.Client.Common/Api/Classes/GuiApi.cs +++ b/src/BizHawk.Client.Common/Api/Classes/GuiApi.cs @@ -2,7 +2,6 @@ using System.Diagnostics.CodeAnalysis; using System.Drawing; using System.Drawing.Drawing2D; -using System.Drawing.Imaging; using System.Drawing.Text; using System.IO; using System.Linq; @@ -77,12 +76,6 @@ private I2DRenderer Get2DRenderer(DisplaySurfaceID? surfaceID) public void ToggleCompositingMode() => _compositingMode = (CompositingMode) (1 - (int) _compositingMode); // enum has two members, 0 and 1 - public ImageAttributes GetAttributes() => null; - - public void SetAttributes(ImageAttributes a) - { - } - public void WithSurface(DisplaySurfaceID surfaceID, Action drawingCallsFunc) { _usingSurfaceID = surfaceID; diff --git a/src/BizHawk.Client.Common/Api/Interfaces/IGuiApi.cs b/src/BizHawk.Client.Common/Api/Interfaces/IGuiApi.cs index 379a8626ab5..105f7930dc9 100644 --- a/src/BizHawk.Client.Common/Api/Interfaces/IGuiApi.cs +++ b/src/BizHawk.Client.Common/Api/Interfaces/IGuiApi.cs @@ -1,5 +1,4 @@ using System.Drawing; -using System.Drawing.Imaging; namespace BizHawk.Client.Common { @@ -7,11 +6,6 @@ public interface IGuiApi : IDisposable, IExternalApi { void ToggleCompositingMode(); - [Obsolete("No longer supported, returns null always.")] - ImageAttributes GetAttributes(); - [Obsolete("No longer supported, no-op.")] - void SetAttributes(ImageAttributes a); - void WithSurface(DisplaySurfaceID surfaceID, Action drawingCallsFunc); [Obsolete("use the other overload e.g. `APIs.Gui.WithSurface(..., gui => { gui.DrawLine(...); });`")] From fb026b127a81728ffc6677ae37b7ba75ca2f610c Mon Sep 17 00:00:00 2001 From: YoshiRulz Date: Thu, 23 Jul 2026 01:37:18 +1000 Subject: [PATCH 5/6] Remove `IGuiApi.WithSurface` w/o delegate argument, deprecated in 2.10 see 1bc1f1b3d --- src/BizHawk.Client.Common/Api/Classes/GuiApi.cs | 13 ------------- src/BizHawk.Client.Common/Api/Interfaces/IGuiApi.cs | 3 --- 2 files changed, 16 deletions(-) diff --git a/src/BizHawk.Client.Common/Api/Classes/GuiApi.cs b/src/BizHawk.Client.Common/Api/Classes/GuiApi.cs index 3f56ed29738..7dd69b91ee6 100644 --- a/src/BizHawk.Client.Common/Api/Classes/GuiApi.cs +++ b/src/BizHawk.Client.Common/Api/Classes/GuiApi.cs @@ -89,19 +89,6 @@ public void WithSurface(DisplaySurfaceID surfaceID, Action drawingCalls } } - public void WithSurface(DisplaySurfaceID surfaceID, Action drawingCallsFunc) - { - _usingSurfaceID = surfaceID; - try - { - drawingCallsFunc(); - } - finally - { - _usingSurfaceID = null; - } - } - public void AddMessage(string message, [LiteralExpected] int? duration = null) => _dialogController.AddOnScreenMessage(message, duration); diff --git a/src/BizHawk.Client.Common/Api/Interfaces/IGuiApi.cs b/src/BizHawk.Client.Common/Api/Interfaces/IGuiApi.cs index 105f7930dc9..70ca92b88b3 100644 --- a/src/BizHawk.Client.Common/Api/Interfaces/IGuiApi.cs +++ b/src/BizHawk.Client.Common/Api/Interfaces/IGuiApi.cs @@ -8,9 +8,6 @@ public interface IGuiApi : IDisposable, IExternalApi void WithSurface(DisplaySurfaceID surfaceID, Action drawingCallsFunc); - [Obsolete("use the other overload e.g. `APIs.Gui.WithSurface(..., gui => { gui.DrawLine(...); });`")] - void WithSurface(DisplaySurfaceID surfaceID, Action drawingCallsFunc); - void AddMessage(string message, int? duration = null); void ClearGraphics(DisplaySurfaceID? surfaceID = null); From 827055bd2a43dae130aa7a82911f6e3d7d1c0a78 Mon Sep 17 00:00:00 2001 From: YoshiRulz Date: Thu, 23 Jul 2026 00:24:08 +1000 Subject: [PATCH 6/6] Create shim over `GuiApi` so it can only be used via `WithSurface` see 7749d0238 --- src/BizHawk.Client.Common/Api/ApiManager.cs | 1 + .../Api/Classes/GuiApi.cs | 23 +- .../Api/Classes/GuiApiShim.cs | 241 ++++++++++++++++++ .../tools/Lua/Libraries/GuiLuaLibrary.cs | 30 +-- 4 files changed, 267 insertions(+), 28 deletions(-) create mode 100644 src/BizHawk.Client.Common/Api/Classes/GuiApiShim.cs diff --git a/src/BizHawk.Client.Common/Api/ApiManager.cs b/src/BizHawk.Client.Common/Api/ApiManager.cs index ae0310ab38d..cf3f8d00d7e 100644 --- a/src/BizHawk.Client.Common/Api/ApiManager.cs +++ b/src/BizHawk.Client.Common/Api/ApiManager.cs @@ -23,6 +23,7 @@ static ApiManager() public static void AddApiType(Type type) { + if (type == typeof(GuiApi)) return; // using `GuiApiShim` instead var interfaceType = type.GetInterfaces().FirstOrDefault(t => typeof(IExternalApi).IsAssignableFrom(t) && t != typeof(IExternalApi)); if (interfaceType == null) return; // if we couldn't determine what it's implementing, then it's not an api impl. type var ctor = type.GetConstructors().Single(); diff --git a/src/BizHawk.Client.Common/Api/Classes/GuiApi.cs b/src/BizHawk.Client.Common/Api/Classes/GuiApi.cs index 7dd69b91ee6..fce4fff50b2 100644 --- a/src/BizHawk.Client.Common/Api/Classes/GuiApi.cs +++ b/src/BizHawk.Client.Common/Api/Classes/GuiApi.cs @@ -27,8 +27,8 @@ private static Bitmap NullGraphicsBitmap private readonly IDialogController _dialogController; - [RequiredService] - private IEmulator Emulator { get; set; } +// [RequiredService] + internal IEmulator Emulator { get; set; } private readonly Action LogCallback; @@ -48,7 +48,7 @@ private static Bitmap NullGraphicsBitmap private FontFamily[]/*?*/ _pixelFonts = null; - private DisplaySurfaceID? _usingSurfaceID; + internal DisplaySurfaceID? SurfaceID { get; set; } = null; public GuiApi( IDialogController dialogController, @@ -69,7 +69,8 @@ private IReadOnlyList PixelFonts private I2DRenderer Get2DRenderer(DisplaySurfaceID? surfaceID) { - var nnID = surfaceID ?? _usingSurfaceID ?? throw new Exception(); + if (surfaceID is not null && surfaceID != SurfaceID) throw new InvalidOperationException($"Mixed drawing surfaces! (Draw call targeting {surfaceID} within {nameof(WithSurface)}({SurfaceID}) scope)"); + var nnID = surfaceID ?? SurfaceID ?? throw new Exception(); return _displayManager.GetApiHawk2DRenderer(nnID); } @@ -78,15 +79,11 @@ public void ToggleCompositingMode() public void WithSurface(DisplaySurfaceID surfaceID, Action drawingCallsFunc) { - _usingSurfaceID = surfaceID; - try - { - drawingCallsFunc(this); - } - finally - { - _usingSurfaceID = null; - } + const string ERR_MSG_NESTED = $"Nested call to {nameof(IGuiApi)}.{nameof(WithSurface)} (or reference stored out of scope)!"; + if (surfaceID != SurfaceID) throw new InvalidOperationException(ERR_MSG_NESTED); + // else it should be fine, but warn anyway + LogCallback(ERR_MSG_NESTED); + drawingCallsFunc(this); } public void AddMessage(string message, [LiteralExpected] int? duration = null) diff --git a/src/BizHawk.Client.Common/Api/Classes/GuiApiShim.cs b/src/BizHawk.Client.Common/Api/Classes/GuiApiShim.cs new file mode 100644 index 00000000000..aaa96e50b59 --- /dev/null +++ b/src/BizHawk.Client.Common/Api/Classes/GuiApiShim.cs @@ -0,0 +1,241 @@ +using System.Diagnostics.CodeAnalysis; +using System.Drawing; +using System.Runtime.CompilerServices; + +using BizHawk.Emulation.Common; + +namespace BizHawk.Client.Common +{ + public sealed class GuiApiShim : IGuiApi + { + private static InvalidOperationException CantDrawOutsideBatch + => new($"Can't make draw calls outside {nameof(WithSurface)}! Check you're calling this method on the instance passed to the lambda."); + + private readonly GuiApi _realImpl; + + [RequiredService] + private IEmulator Emulator + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => _realImpl.Emulator; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + set => _realImpl.Emulator = value; + } + + public GuiApiShim( + IDialogController dialogController, + DisplayManagerBase displayManager, + Action logCallback) + => _realImpl = new(dialogController, displayManager, logCallback); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AddMessage(string message, [LiteralExpected] int? duration = null) + => _realImpl.AddMessage(message, duration: duration); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ClearGraphics(DisplaySurfaceID? surfaceID = null) + => _realImpl.ClearGraphics(surfaceID); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ClearImageCache() + => _realImpl.ClearImageCache(); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ClearText() + => _realImpl.ClearText(); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Dispose() + => _realImpl.Dispose(); + + public void DrawAxis(int x, int y, int size, Color? color = null, DisplaySurfaceID? surfaceID = null) + => throw CantDrawOutsideBatch; + + public void DrawBezier( + Point p1, + Point p2, + Point p3, + Point p4, + Color? color = null, + DisplaySurfaceID? surfaceID = null) + => throw CantDrawOutsideBatch; + + public void DrawBeziers(Point[] points, Color? color = null, DisplaySurfaceID? surfaceID = null) + => throw CantDrawOutsideBatch; + + public void DrawBox( + int x, + int y, + int x2, + int y2, + Color? line = null, + Color? background = null, + DisplaySurfaceID? surfaceID = null) + => throw CantDrawOutsideBatch; + + public void DrawEllipse( + int x, + int y, + int width, + int height, + Color? line = null, + Color? background = null, + DisplaySurfaceID? surfaceID = null) + => throw CantDrawOutsideBatch; + + public void DrawIcon( + string path, + int x, + int y, + int? width = null, + int? height = null, + DisplaySurfaceID? surfaceID = null) + => throw CantDrawOutsideBatch; + + public void DrawImage( + Image img, + int x, + int y, + int? width = null, + int? height = null, + bool cache = true, + DisplaySurfaceID? surfaceID = null) + => throw CantDrawOutsideBatch; + + public void DrawImage( + string path, + int x, + int y, + int? width = null, + int? height = null, + bool cache = true, + DisplaySurfaceID? surfaceID = null) + => throw CantDrawOutsideBatch; + + public void DrawImageRegion( + Image img, + int source_x, + int source_y, + int source_width, + int source_height, + int dest_x, + int dest_y, + int? dest_width = null, + int? dest_height = null, + DisplaySurfaceID? surfaceID = null) + => throw CantDrawOutsideBatch; + + public void DrawImageRegion( + string path, + int source_x, + int source_y, + int source_width, + int source_height, + int dest_x, + int dest_y, + int? dest_width = null, + int? dest_height = null, + DisplaySurfaceID? surfaceID = null) + => throw CantDrawOutsideBatch; + + public void DrawLine(int x1, int y1, int x2, int y2, Color? color = null, DisplaySurfaceID? surfaceID = null) + => throw CantDrawOutsideBatch; + + public void DrawPie( + int x, + int y, + int width, + int height, + int startangle, + int sweepangle, + Color? line = null, + Color? background = null, + DisplaySurfaceID? surfaceID = null) + => throw CantDrawOutsideBatch; + + public void DrawPixel(int x, int y, Color? color = null, DisplaySurfaceID? surfaceID = null) + => throw CantDrawOutsideBatch; + + public void DrawPolygon( + Point[] points, + Color? line = null, + Color? background = null, + DisplaySurfaceID? surfaceID = null) + => throw CantDrawOutsideBatch; + + public void DrawRectangle( + int x, + int y, + int width, + int height, + Color? line = null, + Color? background = null, + DisplaySurfaceID? surfaceID = null) + => throw CantDrawOutsideBatch; + + public void DrawString( + int x, + int y, + string message, + Color? forecolor = null, + Color? backcolor = null, + int? fontsize = null, + string fontfamily = null, + string fontstyle = null, + string horizalign = null, + string vertalign = null, + DisplaySurfaceID? surfaceID = null) + => throw CantDrawOutsideBatch; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Color GetDefaultTextBackground() + => _realImpl.GetDefaultTextBackground(); + + public void PixelText( + int x, + int y, + string message, + Color? forecolor = null, + Color? backcolor = null, + string fontfamily = null, + DisplaySurfaceID? surfaceID = null) + => throw CantDrawOutsideBatch; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void SetDefaultBackgroundColor(Color color) + => _realImpl.SetDefaultBackgroundColor(color); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void SetDefaultForegroundColor(Color color) + => _realImpl.SetDefaultForegroundColor(color); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void SetDefaultPixelFont(string fontfamily) + => _realImpl.SetDefaultPixelFont(fontfamily); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void SetDefaultTextBackground(Color color) + => _realImpl.SetDefaultTextBackground(color); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Text(int x, int y, string message, Color? forecolor = null, string anchor = null) + => _realImpl.Text(x: x, y: y, message: message, forecolor, anchor: anchor); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToggleCompositingMode() + => _realImpl.ToggleCompositingMode(); + + public void WithSurface(DisplaySurfaceID surfaceID, Action drawingCallsFunc) + { + _realImpl.SurfaceID = surfaceID; + try + { + drawingCallsFunc(_realImpl); + } + finally + { + _realImpl.SurfaceID = null; + } + } + } +} diff --git a/src/BizHawk.Client.EmuHawk/tools/Lua/Libraries/GuiLuaLibrary.cs b/src/BizHawk.Client.EmuHawk/tools/Lua/Libraries/GuiLuaLibrary.cs index a42067eab9e..77af5cb3c0c 100644 --- a/src/BizHawk.Client.EmuHawk/tools/Lua/Libraries/GuiLuaLibrary.cs +++ b/src/BizHawk.Client.EmuHawk/tools/Lua/Libraries/GuiLuaLibrary.cs @@ -74,7 +74,7 @@ public void DrawBezier( break; } } - APIs.Gui.DrawBezier(pointsArr[0], pointsArr[1], pointsArr[2], pointsArr[3], _th.ParseColor(color), surfaceID: UseOrFallback(surfaceName)); + APIs.Gui.WithSurface(UseOrFallback(surfaceName), g => g.DrawBezier(pointsArr[0], pointsArr[1], pointsArr[2], pointsArr[3], _th.ParseColor(color))); } catch (Exception) { @@ -92,7 +92,7 @@ public void DrawBox( [LuaColorParam] object line = null, [LuaColorParam] object background = null, string surfaceName = null) - => APIs.Gui.DrawBox(x, y, x2, y2, _th.SafeParseColor(line), _th.SafeParseColor(background), surfaceID: UseOrFallback(surfaceName)); + => APIs.Gui.WithSurface(UseOrFallback(surfaceName), g => g.DrawBox(x, y, x2, y2, _th.SafeParseColor(line), _th.SafeParseColor(background))); [LuaMethodExample("gui.drawEllipse( 16, 32, 77, 99, 0x007F00FF, 0x7F7F7FFF );")] [LuaMethod("drawEllipse", "Draws an ellipse at the given coordinates and the given width and height. Line is the color of the ellipse. Background is the optional fill color")] @@ -104,7 +104,7 @@ public void DrawEllipse( [LuaColorParam] object line = null, [LuaColorParam] object background = null, string surfaceName = null) - => APIs.Gui.DrawEllipse(x, y, width, height, _th.SafeParseColor(line), _th.SafeParseColor(background), surfaceID: UseOrFallback(surfaceName)); + => APIs.Gui.WithSurface(UseOrFallback(surfaceName), g => g.DrawEllipse(x, y, width, height, _th.SafeParseColor(line), _th.SafeParseColor(background))); [LuaMethodExample(""" gui.drawIcon("C:\\sample.ico", 16, 32, 18, 24); @@ -121,7 +121,7 @@ public void DrawIcon( int? width = null, int? height = null, string surfaceName = null) - => APIs.Gui.DrawIcon(path, x, y, width, height, surfaceID: UseOrFallback(surfaceName)); + => APIs.Gui.WithSurface(UseOrFallback(surfaceName), g => g.DrawIcon(path, x, y, width, height)); [LuaMethodExample(""" gui.drawImage("C:\\sample.bmp", 16, 32, 18, 24, false); @@ -140,7 +140,7 @@ public void DrawImage( int? height = null, bool cache = true, string surfaceName = null) - => APIs.Gui.DrawImage(path, x, y, width, height, cache, surfaceID: UseOrFallback(surfaceName)); + => APIs.Gui.WithSurface(UseOrFallback(surfaceName), g => g.DrawImage(path, x, y, width, height, cache)); [LuaMethodExample("gui.clearImageCache( );")] [LuaMethod("clearImageCache", "clears the image cache that is built up by using gui.drawImage, also releases the file handle for cached images")] @@ -166,7 +166,7 @@ public void DrawImageRegion( int? dest_width = null, int? dest_height = null, string surfaceName = null) - => APIs.Gui.DrawImageRegion(path, source_x, source_y, source_width, source_height, dest_x, dest_y, dest_width, dest_height, surfaceID: UseOrFallback(surfaceName)); + => APIs.Gui.WithSurface(UseOrFallback(surfaceName), g => g.DrawImageRegion(path, source_x, source_y, source_width, source_height, dest_x, dest_y, dest_width, dest_height)); [LuaMethodExample("gui.drawLine( 161, 321, 162, 322, 0xFFFFFFFF );")] [LuaMethod("drawLine", "Draws a line from the first coordinate pair to the 2nd. Color is optional (if not specified it will be drawn black)")] @@ -177,7 +177,7 @@ public void DrawLine( int y2, [LuaColorParam] object color = null, string surfaceName = null) - => APIs.Gui.DrawLine(x1, y1, x2, y2, _th.SafeParseColor(color), surfaceID: UseOrFallback(surfaceName)); + => APIs.Gui.WithSurface(UseOrFallback(surfaceName), g => g.DrawLine(x1, y1, x2, y2, _th.SafeParseColor(color))); [LuaMethodExample("gui.drawAxis( 16, 32, 15, 0xFFFFFFFF );")] [LuaMethod("drawAxis", "Draws an axis of the specified size at the coordinate pair.)")] @@ -187,7 +187,7 @@ public void DrawAxis( int size, [LuaColorParam] object color = null, string surfaceName = null) - => APIs.Gui.DrawAxis(x, y, size, _th.SafeParseColor(color), surfaceID: UseOrFallback(surfaceName)); + => APIs.Gui.WithSurface(UseOrFallback(surfaceName), g => g.DrawAxis(x, y, size, _th.SafeParseColor(color))); [LuaMethodExample("gui.drawPie( 16, 32, 77, 99, 180, 90, 0x007F00FF, 0x7F7F7FFF );")] [LuaMethod("drawPie", "draws a Pie shape at the given coordinates and the given width and height")] @@ -201,7 +201,7 @@ public void DrawPie( [LuaColorParam] object line = null, [LuaColorParam] object background = null, string surfaceName = null) - => APIs.Gui.DrawPie(x, y, width, height, startangle, sweepangle, _th.SafeParseColor(line), _th.SafeParseColor(background), surfaceID: UseOrFallback(surfaceName)); + => APIs.Gui.WithSurface(UseOrFallback(surfaceName), g => g.DrawPie(x, y, width, height, startangle, sweepangle, _th.SafeParseColor(line), _th.SafeParseColor(background))); [LuaMethodExample("gui.drawPixel( 16, 32, 0xFFFFFFFF );")] [LuaMethod("drawPixel", "Draws a single pixel at the given coordinates in the given color. Color is optional (if not specified it will be drawn black)")] @@ -210,7 +210,7 @@ public void DrawPixel( int y, [LuaColorParam] object color = null, string surfaceName = null) - => APIs.Gui.DrawPixel(x, y, _th.SafeParseColor(color), surfaceID: UseOrFallback(surfaceName)); + => APIs.Gui.WithSurface(UseOrFallback(surfaceName), g => g.DrawPixel(x, y, _th.SafeParseColor(color))); [LuaMethodExample(""" gui.drawPolygon({ { 5, 10 }, { 10, 10 }, { 10, 20 }, { 5, 20 } }, 10, 30, 0x007F00FF, 0x7F7F7FFF); @@ -241,7 +241,7 @@ public void DrawPolygon( pointsArr[i] = new Point((int) point[0] + (offsetX ?? 0), (int) point[1] + (offsetY ?? 0)); i++; } - APIs.Gui.DrawPolygon(pointsArr, _th.SafeParseColor(line), _th.SafeParseColor(background), surfaceID: UseOrFallback(surfaceName)); + APIs.Gui.WithSurface(UseOrFallback(surfaceName), g => g.DrawPolygon(pointsArr, _th.SafeParseColor(line), _th.SafeParseColor(background))); } catch (Exception) { @@ -259,7 +259,7 @@ public void DrawRectangle( [LuaColorParam] object line = null, [LuaColorParam] object background = null, string surfaceName = null) - => APIs.Gui.DrawRectangle(x, y, width, height, _th.SafeParseColor(line), _th.SafeParseColor(background), surfaceID: UseOrFallback(surfaceName)); + => APIs.Gui.WithSurface(UseOrFallback(surfaceName), g => g.DrawRectangle(x, y, width, height, _th.SafeParseColor(line), _th.SafeParseColor(background))); [LuaMethodExample("gui.drawString( 16, 32, \"Some message\", 0x7F0000FF, 0x00007FFF, 8, \"Arial Narrow\", \"bold\", \"center\", \"middle\" );")] [LuaMethod("drawString", "Draws the given message in the emulator screen space (like all draw functions) at the given x,y coordinates and the given color. The default color is white. A fontfamily can be specified and is monospace generic if none is specified (font family options are the same as the .NET FontFamily class). The fontsize default is 12. The default font style is regular. Font style options are regular, bold, italic, strikethrough, underline. Horizontal alignment options are left (default), center, or right. Vertical alignment options are bottom (default), middle, or top. Alignment options specify which ends of the text will be drawn at the x and y coordinates. For pixel-perfect font look, make sure to disable aspect ratio correction.")] @@ -275,7 +275,7 @@ public void DrawString( string horizalign = null, string vertalign = null, string surfaceName = null) - => APIs.Gui.DrawString( + => APIs.Gui.WithSurface(UseOrFallback(surfaceName), g => g.DrawString( x: x, y: y, message: message, @@ -286,7 +286,7 @@ public void DrawString( fontstyle: fontstyle, horizalign: horizalign, vertalign: vertalign, - surfaceID: UseOrFallback(surfaceName)); + surfaceID: UseOrFallback(surfaceName))); /// TODO do this in Lua binding code? [LuaMethodExample("gui.drawText( 16, 32, \"Some message\", 0x7F0000FF, 0x00007FFF, 8, \"Arial Narrow\", \"bold\", \"center\", \"middle\" );")] @@ -326,7 +326,7 @@ public void PixelText( [LuaColorParam] object backcolor = null, string fontfamily = null, string surfaceName = null) - => APIs.Gui.PixelText(x, y, message, _th.SafeParseColor(forecolor), _th.SafeParseColor(backcolor) ?? APIs.Gui.GetDefaultTextBackground(), fontfamily, surfaceID: UseOrFallback(surfaceName)); + => APIs.Gui.WithSurface(UseOrFallback(surfaceName), g => g.PixelText(x, y, message, _th.SafeParseColor(forecolor), _th.SafeParseColor(backcolor) ?? APIs.Gui.GetDefaultTextBackground(), fontfamily)); [LuaMethodExample("gui.text( 16, 32, \"Some message\", 0x7F0000FF, \"bottomleft\" );")] [LuaMethod("text", "Displays the given text on the screen at the given coordinates. Optional Foreground color. The optional anchor flag anchors the text to one of the four corners. Anchor flag parameters: topleft, topright, bottomleft, bottomright. This function is generally much faster than other text drawing functions, at the cost of customization.")]