hook up melonds screen control stuff to settings
This commit is contained in:
parent
5f24392b41
commit
667a218c58
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue