@@ -39,10 +39,14 @@ public sealed class GuiApi : IGuiApi
3939
4040 private Color ? _defaultTextBackground = Color . FromArgb ( 128 , 0 , 0 , 0 ) ;
4141
42+ private DisplaySurface _clientSurface ;
43+
4244 private DisplaySurface _GUISurface ;
4345
4446 private ( int Left , int Top , int Right , int Bottom ) _padding = ( 0 , 0 , 0 , 0 ) ;
4547
48+ private DisplaySurfaceID ? _usingSurfaceID = null ;
49+
4650 public bool HasGUISurface => _GUISurface != null ;
4751
4852 public GuiApi ( Action < string > logCallback , IDisplayManagerForApi displayManager )
@@ -55,9 +59,9 @@ public GuiApi(Action<string> logCallback, IDisplayManagerForApi displayManager)
5559
5660 private Pen GetPen ( Color color ) => _pens . TryGetValue ( color , out var p ) ? p : ( _pens [ color ] = new Pen ( color ) ) ;
5761
58- private Graphics GetGraphics ( )
62+ private Graphics GetGraphics ( DisplaySurfaceID ? surfaceID )
5963 {
60- var g = _GUISurface ? . GetGraphics ( ) ?? Graphics . FromImage ( _nullGraphicsBitmap ) ;
64+ var g = GetRelevantSurface ( surfaceID ) ? . GetGraphics ( ) ?? Graphics . FromImage ( _nullGraphicsBitmap ) ;
6165 var ( tx , ty ) = Emulator . ScreenLogicalOffsets ( ) ;
6266 if ( tx != 0 || ty != 0 )
6367 {
@@ -75,25 +79,94 @@ private Graphics GetGraphics()
7579
7680 public void SetAttributes ( ImageAttributes a ) => _attributes = a ;
7781
78- public void DrawNew ( string name , bool clear )
82+ private DisplaySurface GetRelevantSurface ( DisplaySurfaceID ? surfaceID ) => ( surfaceID ?? _usingSurfaceID ) switch
83+ {
84+ DisplaySurfaceID . EmuCore => _GUISurface ,
85+ DisplaySurfaceID . Client => _clientSurface ,
86+ _ => throw new Exception ( )
87+ } ;
88+
89+ private void LockSurface ( DisplaySurfaceID surfaceID )
90+ {
91+ switch ( surfaceID )
92+ {
93+ case DisplaySurfaceID . EmuCore :
94+ if ( _GUISurface != null ) throw new InvalidOperationException ( "attempt to lock surface without unlocking previous" ) ;
95+ _GUISurface = _displayManager . LockApiHawkSurface ( surfaceID , clear : true ) ;
96+ break ;
97+ case DisplaySurfaceID . Client :
98+ if ( _clientSurface != null ) throw new InvalidOperationException ( "attempt to lock surface without unlocking previous" ) ;
99+ _clientSurface = _displayManager . LockApiHawkSurface ( surfaceID , clear : true ) ;
100+ break ;
101+ default :
102+ throw new ArgumentException ( message : "not a valid enum member" , paramName : nameof ( surfaceID ) ) ;
103+ }
104+ }
105+
106+ private void UnlockSurface ( DisplaySurfaceID surfaceID )
107+ {
108+ switch ( surfaceID )
109+ {
110+ case DisplaySurfaceID . EmuCore :
111+ if ( _GUISurface != null ) _displayManager . UnlockApiHawkSurface ( _GUISurface ) ;
112+ _GUISurface = null ;
113+ break ;
114+ case DisplaySurfaceID . Client :
115+ if ( _clientSurface != null ) _displayManager . UnlockApiHawkSurface ( _clientSurface ) ;
116+ _clientSurface = null ;
117+ break ;
118+ default :
119+ throw new ArgumentException ( message : "not a valid enum member" , paramName : nameof ( surfaceID ) ) ;
120+ }
121+ }
122+
123+ public void WithSurface ( DisplaySurfaceID surfaceID , Action drawingCallsFunc )
124+ {
125+ LockSurface ( surfaceID ) ;
126+ _usingSurfaceID = surfaceID ;
127+ try
128+ {
129+ drawingCallsFunc ( ) ;
130+ }
131+ finally
132+ {
133+ _usingSurfaceID = null ;
134+ UnlockSurface ( surfaceID ) ;
135+ }
136+ }
137+
138+ public void LockEmuSurfaceLua ( )
79139 {
80140 try
81141 {
82- DrawFinish ( ) ;
83- _GUISurface = _displayManager . LockLuaSurface ( name , clear ) ;
142+ UnlockSurface ( DisplaySurfaceID . EmuCore ) ;
143+ LockSurface ( DisplaySurfaceID . EmuCore ) ;
84144 }
85145 catch ( InvalidOperationException ex )
86146 {
87147 LogCallback ( ex . ToString ( ) ) ;
88148 }
89149 }
90150
91- public void DrawFinish ( )
151+ public void UnlockEmuSurfaceLua ( ) => UnlockSurface ( DisplaySurfaceID . EmuCore ) ;
152+
153+ public void DrawNew ( string name , bool clear )
92154 {
93- if ( _GUISurface != null ) _displayManager . UnlockLuaSurface ( _GUISurface ) ;
94- _GUISurface = null ;
155+ switch ( name )
156+ {
157+ case null :
158+ case "emu" :
159+ LogCallback ( "the `DrawNew(\" emu\" )` function has been deprecated" ) ;
160+ return ;
161+ case "native" :
162+ throw new InvalidOperationException ( "the ability to draw in the margins with `DrawNew(\" native\" )` has been removed" ) ;
163+ default :
164+ throw new InvalidOperationException ( "invalid surface name" ) ;
165+ }
95166 }
96167
168+ public void DrawFinish ( ) => LogCallback ( "the `DrawFinish()` function has been deprecated" ) ;
169+
97170 public void SetPadding ( int all ) => _padding = ( all , all , all , all ) ;
98171
99172 public void SetPadding ( int x , int y ) => _padding = ( x / 2 , y / 2 , x / 2 + x & 1 , y / 2 + y & 1 ) ;
@@ -104,11 +177,7 @@ public void DrawFinish()
104177
105178 public void AddMessage ( string message ) => _displayManager . OSD . AddMessage ( message ) ;
106179
107- public void ClearGraphics ( )
108- {
109- _GUISurface . Clear ( ) ;
110- DrawFinish ( ) ;
111- }
180+ public void ClearGraphics ( DisplaySurfaceID ? surfaceID = null ) => GetRelevantSurface ( surfaceID ) . Clear ( ) ;
112181
113182 public void ClearText ( ) => _displayManager . OSD . ClearGuiText ( ) ;
114183
@@ -138,11 +207,11 @@ public void SetDefaultPixelFont(string fontfamily)
138207 }
139208 }
140209
141- public void DrawBezier ( Point p1 , Point p2 , Point p3 , Point p4 , Color ? color = null )
210+ public void DrawBezier ( Point p1 , Point p2 , Point p3 , Point p4 , Color ? color = null , DisplaySurfaceID ? surfaceID = null )
142211 {
143212 try
144213 {
145- using var g = GetGraphics ( ) ;
214+ using var g = GetGraphics ( surfaceID ) ;
146215 g . CompositingMode = _compositingMode ;
147216 g . DrawBezier ( GetPen ( color ?? _defaultForeground ) , p1 , p2 , p3 , p4 ) ;
148217 }
@@ -152,11 +221,11 @@ public void DrawBezier(Point p1, Point p2, Point p3, Point p4, Color? color = nu
152221 }
153222 }
154223
155- public void DrawBeziers ( Point [ ] points , Color ? color = null )
224+ public void DrawBeziers ( Point [ ] points , Color ? color = null , DisplaySurfaceID ? surfaceID = null )
156225 {
157226 try
158227 {
159- using var g = GetGraphics ( ) ;
228+ using var g = GetGraphics ( surfaceID ) ;
160229 g . CompositingMode = _compositingMode ;
161230 g . DrawBeziers ( GetPen ( color ?? _defaultForeground ) , points ) ;
162231 }
@@ -166,7 +235,7 @@ public void DrawBeziers(Point[] points, Color? color = null)
166235 }
167236 }
168237
169- public void DrawBox ( int x , int y , int x2 , int y2 , Color ? line = null , Color ? background = null )
238+ public void DrawBox ( int x , int y , int x2 , int y2 , Color ? line = null , Color ? background = null , DisplaySurfaceID ? surfaceID = null )
170239 {
171240 try
172241 {
@@ -192,7 +261,7 @@ public void DrawBox(int x, int y, int x2, int y2, Color? line = null, Color? bac
192261 y -= y2 ;
193262 h = Math . Max ( y2 , 0.1f ) ;
194263 }
195- using var g = GetGraphics ( ) ;
264+ using var g = GetGraphics ( surfaceID ) ;
196265 g . CompositingMode = _compositingMode ;
197266 g . DrawRectangle ( GetPen ( line ?? _defaultForeground ) , x , y , w , h ) ;
198267 var bg = background ?? _defaultBackground ;
@@ -204,11 +273,11 @@ public void DrawBox(int x, int y, int x2, int y2, Color? line = null, Color? bac
204273 }
205274 }
206275
207- public void DrawEllipse ( int x , int y , int width , int height , Color ? line = null , Color ? background = null )
276+ public void DrawEllipse ( int x , int y , int width , int height , Color ? line = null , Color ? background = null , DisplaySurfaceID ? surfaceID = null )
208277 {
209278 try
210279 {
211- using var g = GetGraphics ( ) ;
280+ using var g = GetGraphics ( surfaceID ) ;
212281 var bg = background ?? _defaultBackground ;
213282 if ( bg != null ) g . FillEllipse ( GetBrush ( bg . Value ) , x , y , width , height ) ;
214283 g . CompositingMode = _compositingMode ;
@@ -220,7 +289,7 @@ public void DrawEllipse(int x, int y, int width, int height, Color? line = null,
220289 }
221290 }
222291
223- public void DrawIcon ( string path , int x , int y , int ? width = null , int ? height = null )
292+ public void DrawIcon ( string path , int x , int y , int ? width = null , int ? height = null , DisplaySurfaceID ? surfaceID = null )
224293 {
225294 try
226295 {
@@ -229,7 +298,7 @@ public void DrawIcon(string path, int x, int y, int? width = null, int? height =
229298 AddMessage ( $ "File not found: { path } ") ;
230299 return ;
231300 }
232- using var g = GetGraphics ( ) ;
301+ using var g = GetGraphics ( surfaceID ) ;
233302 g . CompositingMode = _compositingMode ;
234303 g . DrawIcon (
235304 width != null && height != null
@@ -245,9 +314,9 @@ public void DrawIcon(string path, int x, int y, int? width = null, int? height =
245314 }
246315 }
247316
248- public void DrawImage ( Image img , int x , int y , int ? width = null , int ? height = null , bool cache = true )
317+ public void DrawImage ( Image img , int x , int y , int ? width = null , int ? height = null , bool cache = true , DisplaySurfaceID ? surfaceID = null )
249318 {
250- using var g = GetGraphics ( ) ;
319+ using var g = GetGraphics ( surfaceID ) ;
251320 g . CompositingMode = _compositingMode ;
252321 g . DrawImage (
253322 img ,
@@ -260,14 +329,14 @@ public void DrawImage(Image img, int x, int y, int? width = null, int? height =
260329 _attributes
261330 ) ;
262331 }
263- public void DrawImage ( string path , int x , int y , int ? width = null , int ? height = null , bool cache = true )
332+ public void DrawImage ( string path , int x , int y , int ? width = null , int ? height = null , bool cache = true , DisplaySurfaceID ? surfaceID = null )
264333 {
265334 if ( ! File . Exists ( path ) )
266335 {
267336 LogCallback ( $ "File not found: { path } ") ;
268337 return ;
269338 }
270- using var g = GetGraphics ( ) ;
339+ using var g = GetGraphics ( surfaceID ) ;
271340 var isCached = _imageCache . ContainsKey ( path ) ;
272341 var img = isCached ? _imageCache [ path ] : Image . FromFile ( path ) ;
273342 if ( ! isCached && cache ) _imageCache [ path ] = img ;
@@ -290,9 +359,9 @@ public void ClearImageCache()
290359 _imageCache . Clear ( ) ;
291360 }
292361
293- 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 )
362+ 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 )
294363 {
295- using var g = GetGraphics ( ) ;
364+ using var g = GetGraphics ( surfaceID ) ;
296365 g . CompositingMode = _compositingMode ;
297366 g . DrawImage (
298367 img ,
@@ -306,14 +375,14 @@ public void DrawImageRegion(Image img, int source_x, int source_y, int source_wi
306375 ) ;
307376 }
308377
309- 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 )
378+ 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 )
310379 {
311380 if ( ! File . Exists ( path ) )
312381 {
313382 LogCallback ( $ "File not found: { path } ") ;
314383 return ;
315384 }
316- using var g = GetGraphics ( ) ;
385+ using var g = GetGraphics ( surfaceID ) ;
317386 g . CompositingMode = _compositingMode ;
318387 g . DrawImage (
319388 _imageCache . TryGetValue ( path , out var img ) ? img : ( _imageCache [ path ] = Image . FromFile ( path ) ) ,
@@ -327,33 +396,33 @@ public void DrawImageRegion(string path, int source_x, int source_y, int source_
327396 ) ;
328397 }
329398
330- public void DrawLine ( int x1 , int y1 , int x2 , int y2 , Color ? color = null )
399+ public void DrawLine ( int x1 , int y1 , int x2 , int y2 , Color ? color = null , DisplaySurfaceID ? surfaceID = null )
331400 {
332- using var g = GetGraphics ( ) ;
401+ using var g = GetGraphics ( surfaceID ) ;
333402 g . CompositingMode = _compositingMode ;
334403 g . DrawLine ( GetPen ( color ?? _defaultForeground ) , x1 , y1 , x2 , y2 ) ;
335404 }
336405
337- public void DrawAxis ( int x , int y , int size , Color ? color = null )
406+ public void DrawAxis ( int x , int y , int size , Color ? color = null , DisplaySurfaceID ? surfaceID = null )
338407 {
339- DrawLine ( x + size , y , x - size , y , color ?? _defaultForeground ) ;
340- DrawLine ( x , y + size , x , y - size , color ?? _defaultForeground ) ;
408+ DrawLine ( x + size , y , x - size , y , color ?? _defaultForeground , surfaceID : surfaceID ) ;
409+ DrawLine ( x , y + size , x , y - size , color ?? _defaultForeground , surfaceID : surfaceID ) ;
341410 }
342411
343- public void DrawPie ( int x , int y , int width , int height , int startangle , int sweepangle , Color ? line = null , Color ? background = null )
412+ public void DrawPie ( int x , int y , int width , int height , int startangle , int sweepangle , Color ? line = null , Color ? background = null , DisplaySurfaceID ? surfaceID = null )
344413 {
345- using var g = GetGraphics ( ) ;
414+ using var g = GetGraphics ( surfaceID ) ;
346415 g . CompositingMode = _compositingMode ;
347416 var bg = background ?? _defaultBackground ;
348417 if ( bg != null ) g . FillPie ( GetBrush ( bg . Value ) , x , y , width , height , startangle , sweepangle ) ;
349418 g . DrawPie ( GetPen ( line ?? _defaultForeground ) , x + 1 , y + 1 , width - 1 , height - 1 , startangle , sweepangle ) ;
350419 }
351420
352- public void DrawPixel ( int x , int y , Color ? color = null )
421+ public void DrawPixel ( int x , int y , Color ? color = null , DisplaySurfaceID ? surfaceID = null )
353422 {
354423 try
355424 {
356- using var g = GetGraphics ( ) ;
425+ using var g = GetGraphics ( surfaceID ) ;
357426 g . DrawLine ( GetPen ( color ?? _defaultForeground ) , x , y , x + 0.1F , y ) ;
358427 }
359428 catch ( Exception )
@@ -362,11 +431,11 @@ public void DrawPixel(int x, int y, Color? color = null)
362431 }
363432 }
364433
365- public void DrawPolygon ( Point [ ] points , Color ? line = null , Color ? background = null )
434+ public void DrawPolygon ( Point [ ] points , Color ? line = null , Color ? background = null , DisplaySurfaceID ? surfaceID = null )
366435 {
367436 try
368437 {
369- using var g = GetGraphics ( ) ;
438+ using var g = GetGraphics ( surfaceID ) ;
370439 g . DrawPolygon ( GetPen ( line ?? _defaultForeground ) , points ) ;
371440 var bg = background ?? _defaultBackground ;
372441 if ( bg != null ) g . FillPolygon ( GetBrush ( bg . Value ) , points ) ;
@@ -377,17 +446,17 @@ public void DrawPolygon(Point[] points, Color? line = null, Color? background =
377446 }
378447 }
379448
380- public void DrawRectangle ( int x , int y , int width , int height , Color ? line = null , Color ? background = null )
449+ public void DrawRectangle ( int x , int y , int width , int height , Color ? line = null , Color ? background = null , DisplaySurfaceID ? surfaceID = null )
381450 {
382- using var g = GetGraphics ( ) ;
451+ using var g = GetGraphics ( surfaceID ) ;
383452 var w = Math . Max ( width , 0.1F ) ;
384453 var h = Math . Max ( height , 0.1F ) ;
385454 g . DrawRectangle ( GetPen ( line ?? _defaultForeground ) , x , y , w , h ) ;
386455 var bg = background ?? _defaultBackground ;
387456 if ( bg != null ) g . FillRectangle ( GetBrush ( bg . Value ) , x + 1 , y + 1 , Math . Max ( w - 1 , 0 ) , Math . Max ( h - 1 , 0 ) ) ;
388457 }
389458
390- 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 )
459+ 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 )
391460 {
392461 try
393462 {
@@ -402,7 +471,7 @@ public void DrawString(int x, int y, string message, Color? forecolor = null, Co
402471 _ => FontStyle . Regular
403472 } ;
404473
405- using var g = GetGraphics ( ) ;
474+ using var g = GetGraphics ( surfaceID ) ;
406475
407476 // The text isn't written out using GenericTypographic, so measuring it using GenericTypographic seemed to make it worse.
408477 // And writing it out with GenericTypographic just made it uglier. :p
@@ -455,7 +524,7 @@ public void DrawString(int x, int y, string message, Color? forecolor = null, Co
455524 }
456525 }
457526
458- public void DrawText ( int x , int y , string message , Color ? forecolor = null , Color ? backcolor = null , string fontfamily = null )
527+ public void DrawText ( int x , int y , string message , Color ? forecolor = null , Color ? backcolor = null , string fontfamily = null , DisplaySurfaceID ? surfaceID = null )
459528 {
460529 try
461530 {
@@ -479,7 +548,7 @@ public void DrawText(int x, int y, string message, Color? forecolor = null, Colo
479548 index = _defaultPixelFont ;
480549 break ;
481550 }
482- using var g = GetGraphics ( ) ;
551+ using var g = GetGraphics ( surfaceID ) ;
483552 var font = new Font ( _displayManager . CustomFonts . Families [ index ] , 8 , FontStyle . Regular , GraphicsUnit . Pixel ) ;
484553 var sizeOfText = g . MeasureString (
485554 message ,
0 commit comments