Add in screen control filter for Citra port

This commit is contained in:
CasualPokePlayer 2023-07-27 22:20:15 -07:00
parent 4217be1528
commit 5607845b24
6 changed files with 106 additions and 27 deletions

View File

@ -16,6 +16,7 @@ using BizHawk.Client.Common.Filters;
using BizHawk.Common.CollectionExtensions;
using BizHawk.Common.PathExtensions;
using BizHawk.Emulation.Common;
using BizHawk.Emulation.Cores.Consoles.Nintendo._3DS;
using BizHawk.Emulation.Cores.Consoles.Nintendo.NDS;
using BizHawk.Emulation.Cores.Sony.PSX;
@ -436,18 +437,10 @@ namespace BizHawk.Client.Common
if (_currentFilterProgram == null) return p;
// otherwise, have the filter program untransform it
Vector2 v = new Vector2(p.X, p.Y);
var v = new Vector2(p.X, p.Y);
v = _currentFilterProgram.UntransformPoint("default", v);
// Poop
//if (Global.Emulator is MelonDS ds && ds.TouchScreenStart.HasValue)
//{
// Point touchLocation = ds.TouchScreenStart.Value;
// v.Y = (int)((double)ds.BufferHeight / MelonDS.NativeHeight * (v.Y - touchLocation.Y));
// v.X = (int)((double)ds.BufferWidth / MelonDS.NativeWidth * (v.X - touchLocation.X));
//}
return new Point((int)v.X, (int)v.Y);
return new((int)v.X, (int)v.Y);
}
/// <summary>
@ -462,9 +455,9 @@ namespace BizHawk.Client.Common
}
// otherwise, have the filter program untransform it
Vector2 v = new Vector2(p.X, p.Y);
var v = new Vector2(p.X, p.Y);
v = _currentFilterProgram.TransformPoint("default", v);
return new Point((int)v.X, (int)v.Y);
return new((int)v.X, (int)v.Y);
}
public virtual Size GetPanelNativeSize() => throw new NotImplementedException();
@ -474,9 +467,6 @@ namespace BizHawk.Client.Common
/// <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.
/// ---
/// If the int[] is size=1, then it contains an openGL texture ID (and the size should be as specified from videoProvider)
/// Don't worry about the case where the frontend isnt using opengl; DisplayManager deals with it
/// </summary>
public void UpdateSource(IVideoProvider videoProvider)
{
@ -494,14 +484,12 @@ namespace BizHawk.Client.Common
private BaseFilter CreateCoreScreenControl()
{
if (GlobalEmulator is NDS nds)
return GlobalEmulator switch
{
//TODO: need to pipe layout settings into here now
var filter = new ScreenControlNDS(nds);
return filter;
}
return null;
NDS nds => new ScreenControlNDS(nds),
Citra citra => new ScreenControl3DS(citra),
_ => null
};
}
/// <summary>

View File

@ -82,7 +82,7 @@ namespace BizHawk.Client.Common.FilterManager
/// </summary>
public Vector2 UntransformPoint(string channel, Vector2 point)
{
for (int i = Filters.Count - 1; i >= 0; i--)
for (var i = Filters.Count - 1; i >= 0; i--)
{
var filter = Filters[i];
point = filter.UntransformPoint(channel, point);

View File

@ -1,9 +1,11 @@
using System;
using System.Drawing;
using BizHawk.Client.Common.FilterManager;
using BizHawk.Emulation.Cores.Consoles.Nintendo.NDS;
using BizHawk.Bizware.BizwareGL;
using BizHawk.Client.Common.FilterManager;
using BizHawk.Emulation.Common;
using BizHawk.Emulation.Cores.Consoles.Nintendo._3DS;
using BizHawk.Emulation.Cores.Consoles.Nintendo.NDS;
namespace BizHawk.Client.Common.Filters
{
@ -416,6 +418,76 @@ namespace BizHawk.Client.Common.Filters
}
}
/// <summary>
/// special screen control features for 3DS
/// in practice, this is only for correcting mouse input
/// as the core internally handles screen drawing madness anyways
/// </summary>
public class ScreenControl3DS : BaseFilter
{
private readonly Citra _citra;
public ScreenControl3DS(Citra citra)
{
_citra = citra;
}
public override Vector2 UntransformPoint(string channel, Vector2 point)
{
if (_citra.TouchScreenEnabled)
{
var rect = _citra.TouchScreenRectangle;
var rotated = _citra.TouchScreenRotated;
var bufferWidth = (float)_citra.AsVideoProvider().BufferWidth;
var bufferHeight = (float)_citra.AsVideoProvider().BufferHeight;
// reset the point's origin to the top left of the screen
point.X -= rect.X;
point.Y -= rect.Y;
if (rotated)
{
// scale our point now
// X is for height here and Y is for width, due to rotation
point.X *= bufferHeight / rect.Width;
point.Y *= bufferWidth / rect.Height;
// adjust point
point = new(bufferWidth - point.Y, point.X);
}
else
{
// scale our point now
point.X *= bufferWidth / rect.Width;
point.Y *= bufferHeight / rect.Height;
}
}
return point;
}
public override Vector2 TransformPoint(string channel, Vector2 point)
{
if (_citra.TouchScreenEnabled)
{
var rect = _citra.TouchScreenRectangle;
var rotated = _citra.TouchScreenRotated;
if (rotated)
{
// adjust point
point = new(point.Y, rect.Height - point.X);
}
// reset the point's origin to the top left of the screen
point.X += rect.X;
point.Y += rect.Y;
// TODO: this doesn't handle "large screen" mode correctly
}
return point;
}
}
public class FinalPresentation : BaseFilter
{
public enum eFilterOption

View File

@ -33,8 +33,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo._3DS
_core.Citra_RunFrame(_context);
_core.Citra_GetVideoDimensions(_context, out _citraVideoProvider.Width, out _citraVideoProvider.Height);
_citraVideoProvider.VideoDirty = true;
OnVideoRefresh();
if (renderSound)
{
@ -50,6 +49,17 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo._3DS
return true;
}
private void OnVideoRefresh()
{
_core.Citra_GetVideoDimensions(_context, out _citraVideoProvider.Width, out _citraVideoProvider.Height);
_citraVideoProvider.VideoDirty = true;
_core.Citra_GetTouchScreenLayout(_context, out var x, out var y, out var width, out var height, out var rotated, out var enabled);
TouchScreenRectangle = new(x, y, width, height);
TouchScreenRotated = rotated;
TouchScreenEnabled = enabled;
}
public void ResetCounters()
{
Frame = 0;

View File

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
@ -34,6 +35,10 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo._3DS
private readonly IntPtr _context;
private readonly CitraVideoProvider _citraVideoProvider;
public Rectangle TouchScreenRectangle { get; private set; }
public bool TouchScreenRotated { get; private set; }
public bool TouchScreenEnabled { get; private set; }
[CoreConstructor(VSystemID.Raw._3DS)]
public Citra(CoreLoadParameters<CitraSettings, CitraSyncSettings> lp)
{
@ -131,6 +136,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo._3DS
}
InitMemoryDomains();
OnVideoRefresh();
}
private IntPtr RequestGLContextCallback()

View File

@ -160,5 +160,8 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo._3DS
[BizImport(cc)]
public abstract void Citra_GetMemoryRegion(IntPtr context, MemoryRegion region, out IntPtr ptr, out int size);
[BizImport(cc)]
public abstract void Citra_GetTouchScreenLayout(IntPtr context, out int x, out int y, out int width, out int height, out bool rotated, out bool enabled);
}
}