hook up melonds screen control stuff to settings

This commit is contained in:
zeromus 2020-03-31 18:29:58 -04:00
parent 5f24392b41
commit 667a218c58
8 changed files with 83 additions and 124 deletions

View File

@ -257,8 +257,9 @@ namespace BizHawk.Client.Common
Bind("Tools", "Toggle All Cheats"),
Bind("DS", "Increment View"),
Bind("DS", "Decrement View"),
Bind("NDS", "Next Screen Layout"),
Bind("NDS", "Previous Screen Layout"),
Bind("NDS", "Screen Rotate"),
};
// set ordinals based on order in list

View File

@ -8,7 +8,7 @@ using NLua;
// ReSharper disable UnusedMember.Global
namespace BizHawk.Client.Common.lua
{
[Description("Functions specific to DSHawk (functions may not run when an Genesis game is not loaded)")]
[Description("Functions specific to DSHawk (functions may not run when an NDS game is not loaded)")]
public sealed class DSLuaLibrary : DelegatingLuaLibrary
{
public DSLuaLibrary(Lua lua)
@ -17,21 +17,9 @@ namespace BizHawk.Client.Common.lua
public DSLuaLibrary(Lua lua, Action<string> logOutputCallback)
: base(lua, logOutputCallback) { }
public override string Name => "ds";
public override string Name => "nds";
[RequiredService]
public IEmulator Emulator { get; set; }
[LuaMethodExample("touchStartX = ds.touchScreenStart().X")]
[LuaMethod("touchScreenStart", "Gets the buffer coordinates that represent the start of the touch screen area. If the touch screen is not currently being displayed, nil will be returned.")]
public Point? TouchScreenStart()
{
if (Emulator is MelonDS ds)
{
return ds.TouchScreenStart;
}
return null;
}
}
}

View File

@ -182,17 +182,6 @@ namespace BizHawk.Client.EmuHawk.Filters
//TODO: actually use this
bool nop = false;
//SCREEN CONTROL VALUES
//-------------------
public int Gap = 0;
public int ScreenRotationDegreesCW = 0;
public enum ScreenLayout
{
Vertical, Horizontal, Top, Bottom
}
ScreenLayout Layout = ScreenLayout.Vertical;
//-------------------
//matrices used for transforming screens
Matrix4 matTop, matBot;
Matrix4 matTopInvert, matBotInvert;
@ -229,23 +218,33 @@ namespace BizHawk.Client.EmuHawk.Filters
//set up transforms for each screen based on screen control values
//this will be TRICKY depending on how many features we have, but once it's done, everything should be easy
var settings = nds.GetSettings();
//gap only applies to vertical, I guess
if (Layout == ScreenLayout.Vertical)
if (settings.ScreenLayout == MelonDS.ScreenLayoutKind.Vertical)
{
bot.Translate(0, 192);
bot.Translate(0, Gap);
bot.Translate(0, settings.ScreenGap);
}
else if (Layout == ScreenLayout.Horizontal)
else if (settings.ScreenLayout == MelonDS.ScreenLayoutKind.Horizontal)
{
bot.Translate(256, 0);
}
else if (Layout == ScreenLayout.Top)
else if (settings.ScreenLayout == MelonDS.ScreenLayoutKind.Top)
{
//do nothing here, we'll discard bottom screen
}
top.RotateZ(ScreenRotationDegreesCW);
bot.RotateZ(ScreenRotationDegreesCW);
//this doesn't make any sense, it's likely to be too much for a monitor to gracefully handle too
if (settings.ScreenLayout != MelonDS.ScreenLayoutKind.Horizontal)
{
int rot = 0;
if (settings.ScreenRotation == MelonDS.ScreenRotationKind.Rotate90) rot = 90;
if (settings.ScreenRotation == MelonDS.ScreenRotationKind.Rotate180) rot = 180;
if (settings.ScreenRotation == MelonDS.ScreenRotationKind.Rotate270) rot = 270;
top.RotateZ(rot);
bot.RotateZ(rot);
}
//-----------------------------------
@ -287,14 +286,14 @@ namespace BizHawk.Client.EmuHawk.Filters
//the size can now be determined in a kind of fluffily magical way by transforming edges and checking the bounds
float fxmin = 100000, fymin = 100000, fxmax = -100000, fymax = -100000;
if (Layout != ScreenLayout.Bottom)
if (settings.ScreenLayout != MelonDS.ScreenLayoutKind.Bottom)
{
fxmin = Math.Min(Math.Min(Math.Min(Math.Min(top_TL.X, top_TR.X), top_BL.X), top_BR.X), fxmin);
fymin = Math.Min(Math.Min(Math.Min(Math.Min(top_TL.Y, top_TR.Y), top_BL.Y), top_BR.Y), fymin);
fxmax = Math.Max(Math.Max(Math.Max(Math.Max(top_TL.X, top_TR.X), top_BL.X), top_BR.X), fxmax);
fymax = Math.Max(Math.Max(Math.Max(Math.Max(top_TL.Y, top_TR.Y), top_BL.Y), top_BR.Y), fymax);
}
if (Layout != ScreenLayout.Top)
if (settings.ScreenLayout != MelonDS.ScreenLayoutKind.Top)
{
fxmin = Math.Min(Math.Min(Math.Min(Math.Min(bot_TL.X, bot_TR.X), bot_BL.X), bot_BR.X), fxmin);
fymin = Math.Min(Math.Min(Math.Min(Math.Min(bot_TL.Y, bot_TR.Y), bot_BL.Y), bot_BR.Y), fymin);
@ -339,7 +338,8 @@ namespace BizHawk.Client.EmuHawk.Filters
point.Y *= 2;
//in case we're in this layout, we get confused, so fix it
if (Layout == ScreenLayout.Top)
var settings = nds.GetSettings();
if (settings.ScreenLayout == MelonDS.ScreenLayoutKind.Top)
point = Vector2.Zero;
//TODO: we probably need more subtle logic here.
@ -375,10 +375,11 @@ namespace BizHawk.Client.EmuHawk.Filters
//draw screens
bool renderTop = false;
bool renderBottom = false;
if (Layout == ScreenLayout.Bottom) renderBottom = true;
if (Layout == ScreenLayout.Top) renderTop = true;
if (Layout == ScreenLayout.Vertical) renderTop = renderBottom = true;
if (Layout == ScreenLayout.Horizontal) renderTop = renderBottom = true;
var settings = nds.GetSettings();
if (settings.ScreenLayout == MelonDS.ScreenLayoutKind.Bottom) renderBottom = true;
if (settings.ScreenLayout == MelonDS.ScreenLayoutKind.Top) renderTop = true;
if (settings.ScreenLayout == MelonDS.ScreenLayoutKind.Vertical) renderTop = renderBottom = true;
if (settings.ScreenLayout == MelonDS.ScreenLayoutKind.Horizontal) renderTop = renderBottom = true;
if (renderTop)
{

View File

@ -2040,6 +2040,7 @@ namespace BizHawk.Client.EmuHawk
private void NDSSettingsMenuItem_Click(object sender, EventArgs e)
{
GenericCoreConfig.DoDialog(this, "NDS Settings", false, true);
FrameBufferResized();
}
private void NDSSyncSettingsMenuItem_Click(object sender, EventArgs e)

View File

@ -756,23 +756,42 @@ namespace BizHawk.Client.EmuHawk
break;
// DS
case "Increment View":
ToggleDSView();
case "Next Screen Layout":
IncrementDSLayout(1);
break;
case "Decrement View":
ToggleDSView(true);
case "Previous Screen Layout":
IncrementDSLayout(-1);
break;
case "Screen Rotate":
IncrementDSScreenRotate();
break;
}
return true;
}
private void ToggleDSView(bool decrement = false)
private void IncrementDSScreenRotate()
{
if (Emulator is MelonDS ds)
{
var settings = ds.GetSettings();
var num = (int)settings.ScreenOptions;
if (settings.ScreenRotation == MelonDS.ScreenRotationKind.Rotate0) settings.ScreenRotation = settings.ScreenRotation = MelonDS.ScreenRotationKind.Rotate90;
else if (settings.ScreenRotation == MelonDS.ScreenRotationKind.Rotate90) settings.ScreenRotation = settings.ScreenRotation = MelonDS.ScreenRotationKind.Rotate180;
else if (settings.ScreenRotation == MelonDS.ScreenRotationKind.Rotate180) settings.ScreenRotation = settings.ScreenRotation = MelonDS.ScreenRotationKind.Rotate270;
else if (settings.ScreenRotation == MelonDS.ScreenRotationKind.Rotate270) settings.ScreenRotation = settings.ScreenRotation = MelonDS.ScreenRotationKind.Rotate0;
ds.PutSettings(settings);
AddOnScreenMessage($"Screen rotation to {settings.ScreenRotation}");
FrameBufferResized();
}
}
private void IncrementDSLayout(int delta)
{
bool decrement = delta == -1;
if (Emulator is MelonDS ds)
{
var settings = ds.GetSettings();
var num = (int)settings.ScreenLayout;
if (decrement)
{
num--;
@ -781,14 +800,17 @@ namespace BizHawk.Client.EmuHawk
{
num++;
}
var next = (MelonDS.VideoScreenOptions)Enum.Parse(typeof(MelonDS.VideoScreenOptions), num.ToString());
if (!typeof(MelonDS.VideoScreenOptions).IsEnumDefined(next))
var next = (MelonDS.ScreenLayoutKind)Enum.Parse(typeof(MelonDS.ScreenLayoutKind), num.ToString());
if (!typeof(MelonDS.ScreenLayoutKind).IsEnumDefined(next))
{
next = default;
}
settings.ScreenOptions = next;
settings.ScreenLayout = next;
ds.PutSettings(settings);
AddOnScreenMessage($"Screen layout to {next}");
FrameBufferResized();
}
}

View File

@ -112,8 +112,6 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
}
}
public Point? TouchScreenStart => _settings.TouchScreenStart();
/// <summary>
/// MelonDS expects bios and firmware files at a specific location.
/// This should never be called without an accompanying call to PutSyncSettings.

View File

@ -78,62 +78,28 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
[DllImport(dllPath)]
private static extern uint GetTimeAtBoot();
public enum VideoScreenOptions
public enum ScreenLayoutKind
{
Default,
TopOnly,
BottomOnly,
SideBySideLR,
SideBySideRL,
Rotate90,
Rotate270
Vertical, Horizontal, Top, Bottom
}
public enum ScreenRotationKind
{
Rotate0, Rotate90, Rotate180, Rotate270
}
public class MelonSettings
{
[DisplayName("Screen Configuration")]
[Description("Adjusts the orientation of the 2 displays")]
public VideoScreenOptions ScreenOptions { get; set; } = VideoScreenOptions.Default;
[DisplayName("Screen Layout")]
[Description("Adjusts the layout of the screens")]
public ScreenLayoutKind ScreenLayout { get; set; } = ScreenLayoutKind.Vertical;
[DisplayName("Rotation")]
[Description("Adjusts the orientation of the screens")]
public ScreenRotationKind ScreenRotation { get; set; } = ScreenRotationKind.Rotate0;
[DisplayName("Screen Gap")]
public int ScreenGap { get; set; }
public Point? TouchScreenStart() =>
ScreenOptions switch
{
VideoScreenOptions.TopOnly => null,
VideoScreenOptions.BottomOnly => null,
VideoScreenOptions.SideBySideLR => new Point(NativeWidth, 0),
VideoScreenOptions.SideBySideRL => new Point(0, 0),
VideoScreenOptions.Rotate90 => new Point(0, 0),
VideoScreenOptions.Rotate270 => new Point(256, 0),
_ => new Point(0, NativeHeight + ScreenGap)
};
public int Width() =>
ScreenOptions switch
{
VideoScreenOptions.SideBySideLR => NativeWidth * 2,
VideoScreenOptions.SideBySideRL => NativeWidth * 2,
VideoScreenOptions.Rotate90 => NativeHeight * 2,
VideoScreenOptions.Rotate270 => NativeHeight * 2,
_ => NativeWidth
};
// TODO: padding
public int Height() =>
ScreenOptions switch
{
VideoScreenOptions.TopOnly => NativeHeight,
VideoScreenOptions.BottomOnly => NativeHeight,
VideoScreenOptions.SideBySideLR => NativeHeight,
VideoScreenOptions.SideBySideRL => NativeHeight,
VideoScreenOptions.Rotate90 => NativeWidth,
VideoScreenOptions.Rotate270 => NativeWidth,
_ => (NativeHeight * 2) + ScreenGap
};
}
public class MelonSyncSettings

View File

@ -7,18 +7,11 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
{
unsafe partial class MelonDS : IVideoProvider
{
public const int NativeWidth = 256;
public int VirtualWidth => 256;
public int VirtualHeight => 384;
/// <summary>
/// for a single screen
/// </summary>
public const int NativeHeight = 192;
public int VirtualWidth => BufferWidth;
public int VirtualHeight => BufferHeight;
public int BufferWidth => _settings.Width();
public int BufferHeight => _settings.Height();
public int BufferWidth => 256;
public int BufferHeight => 384;
public int VsyncNumerator => 60;
@ -40,20 +33,9 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
{
if (!_getNewBuffer) return _buffer;
_getNewBuffer = false;
return _buffer = _settings.ScreenOptions switch
{
VideoScreenOptions.Default => ScreenArranger.UprightStack(TopScreen, BottomScreen, _settings.ScreenGap),
VideoScreenOptions.TopOnly => ScreenArranger.Copy(TopScreen),
VideoScreenOptions.BottomOnly => ScreenArranger.Copy(BottomScreen),
VideoScreenOptions.SideBySideLR => ScreenArranger.UprightSideBySide(TopScreen, BottomScreen, _settings.ScreenGap),
VideoScreenOptions.SideBySideRL => ScreenArranger.UprightSideBySide(BottomScreen, TopScreen, _settings.ScreenGap),
VideoScreenOptions.Rotate90 => ScreenArranger.Rotate90Stack(TopScreen, BottomScreen, _settings.ScreenGap),
VideoScreenOptions.Rotate270 => ScreenArranger.Rotate270Stack(BottomScreen, TopScreen, _settings.ScreenGap),
_ => throw new InvalidOperationException()
};
return _buffer = ScreenArranger.UprightStack(TopScreen, BottomScreen, 0);
}
private VideoScreen TopScreen => new VideoScreen(GetTopScreenBuffer(), NativeWidth, NativeHeight);
private VideoScreen BottomScreen => new VideoScreen(GetBottomScreenBuffer(), NativeWidth, NativeHeight);
private VideoScreen TopScreen => new VideoScreen(GetTopScreenBuffer(), 256, 192);
private VideoScreen BottomScreen => new VideoScreen(GetBottomScreenBuffer(), 256, 192);
}
}