diff --git a/BizHawk.Emulation.Common/ScreenArranger.cs b/BizHawk.Emulation.Common/ScreenArranger.cs
deleted file mode 100644
index 623a7905a3..0000000000
--- a/BizHawk.Emulation.Common/ScreenArranger.cs
+++ /dev/null
@@ -1,126 +0,0 @@
-using System;
-using System.Diagnostics;
-
-namespace BizHawk.Emulation.Common
-{
- public unsafe class VideoScreen
- {
- public VideoScreen(int* buffer, int width, int height)
- {
- Buffer = buffer;
- Width = width;
- Height = height;
- }
-
- public int* Buffer { get; }
- public int Width { get; }
- public int Height { get; }
-
- public int Length => Width * Height;
- }
-
- /// Provides a way to arrange displays inside a frame buffer.
- public static class ScreenArranger
- {
- /// this is taken as an assumption to allow for simpler algorithms; in the future this may need to be rethought (e.g. for 3DS)
- [Conditional("DEBUG")]
- private static void DebugAssertScreenDimensionsMatch(int lengthA, int lengthB)
- {
- if (lengthA != lengthB) throw new ArgumentException();
- }
-
- [Conditional("DEBUG")]
- private static void DebugAssertPreallocatedBufferSize(int expected, int preallocLength)
- {
- if (preallocLength != expected) throw new Exception();
- }
-
- public static unsafe int[] UprightStack(VideoScreen forTop, VideoScreen forBottom, int gapLineCount = 0)
- {
- DebugAssertScreenDimensionsMatch(forTop.Width, forBottom.Width);
- var outputWidth = forTop.Width;
-
- var gapStartOffset = forTop.Length;
- var screen2StartOffset = gapStartOffset + gapLineCount * outputWidth;
- var bufferLength = screen2StartOffset + forBottom.Height * outputWidth;
- var prealloc = new int[bufferLength]; //TODO actually take a `ref int[] prealloc` (or an int* maybe?)
- DebugAssertPreallocatedBufferSize(bufferLength, prealloc.Length);
-
- for (var i = 0; i < gapStartOffset; i++) prealloc[i] = forTop.Buffer[i]; // copy top screen
- // don't bother writing into the gap
- for (int i = 0, l = forBottom.Length; i < l; i++) prealloc[screen2StartOffset + i] = forBottom.Buffer[i]; // copy bottom screen
- return prealloc;
- }
-
- /// Simply populates a buffer with a single screen
- public static unsafe int[] Copy(VideoScreen screen)
- {
- var bufferLength = screen.Length;
- var prealloc = new int[bufferLength]; //TODO actually take a `ref int[] prealloc` (or an int* maybe?)
- DebugAssertPreallocatedBufferSize(bufferLength, prealloc.Length);
-
- for (var i = 0; i < bufferLength; i++) prealloc[i] = screen.Buffer[i];
- return prealloc;
- }
-
- public static unsafe int[] UprightSideBySide(VideoScreen forLeft, VideoScreen forRight, int gapLineCount = 0)
- {
- DebugAssertScreenDimensionsMatch(forLeft.Height, forRight.Height);
- var outputHeight = forLeft.Height;
-
- var rightOffsetHztl = forLeft.Width + gapLineCount;
- var outputWidth = rightOffsetHztl + forRight.Width;
- var bufferLength = outputHeight * outputWidth; // which = `forLeft.Length + outputHeight * gapLineCount + forRight.Length`
- var prealloc = new int[bufferLength]; //TODO actually take a `ref int[] prealloc` (or an int* maybe?)
- DebugAssertPreallocatedBufferSize(bufferLength, prealloc.Length);
-
- for (var y = 0; y < outputHeight; y++)
- {
- for (int x = 0, w = forLeft.Width; x < w; x++) prealloc[y * outputWidth + x] = forLeft.Buffer[y * w + x]; // copy this row of the left screen
- // don't bother writing into the gap
- for (int x = 0, w = forRight.Width; x < w; x++) prealloc[y * outputWidth + rightOffsetHztl + x] = forRight.Buffer[y * w + x]; // copy this row of the right screen
- }
- return prealloc;
- }
-
- public static unsafe int[] Rotate90Stack(VideoScreen forLeft, VideoScreen forRight, int gapLineCount = 0)
- {
- DebugAssertScreenDimensionsMatch(forLeft.Width, forRight.Width);
- var outputHeight = forLeft.Width;
-
- var rightOffsetHztl = forLeft.Height + gapLineCount;
- var outputWidth = rightOffsetHztl + forRight.Height;
- var bufferLength = outputHeight * outputWidth; // which = `forLeft.Length + outputHeight * gapLineCount + forRight.Length`
- var prealloc = new int[bufferLength]; //TODO actually take a `ref int[] prealloc` (or an int* maybe?)
- DebugAssertPreallocatedBufferSize(bufferLength, prealloc.Length);
-
- for (var y = 0; y < outputHeight; y++)
- {
- for (int x = 0, w = forLeft.Height; x < w; x++) prealloc[y * outputWidth + x] = forLeft.Buffer[(x + 1) * outputHeight - y]; // copy and rotate this column of the top screen to the left of the output
- // don't bother writing into the gap
- for (int x = 0, w = forRight.Height; x < w; x++) prealloc[y * outputWidth + rightOffsetHztl + x] = forRight.Buffer[(x + 1) * outputHeight - y]; // copy and rotate this column of the bottom screen to the right of the output
- }
- return prealloc;
- }
-
- public static unsafe int[] Rotate270Stack(VideoScreen forLeft, VideoScreen forRight, int gapLineCount = 0)
- {
- DebugAssertScreenDimensionsMatch(forLeft.Width, forRight.Width);
- var outputHeight = forLeft.Width;
-
- var rightOffsetHztl = forLeft.Height + gapLineCount;
- var outputWidth = rightOffsetHztl + forRight.Height;
- var bufferLength = outputHeight * outputWidth; // which = `forLeft.Length + outputHeight * gapLineCount + forRight.Length`
- var prealloc = new int[bufferLength]; //TODO actually take a `ref int[] prealloc` (or an int* maybe?)
- DebugAssertPreallocatedBufferSize(bufferLength, prealloc.Length);
-
- for (var y = 0; y < outputHeight; y++)
- {
- for (int x = 0, w = forLeft.Height; x < w; x++) prealloc[y * outputWidth + x] = forLeft.Buffer[(w - x - 1) * outputHeight + y]; // copy and rotate this column of the bottom screen to the left of the output
- // don't bother writing into the gap
- for (int x = 0, w = forRight.Height; x < w; x++) prealloc[y * outputWidth + rightOffsetHztl + x] = forRight.Buffer[(w - x - 1) * outputHeight + y]; // copy and rotate this column of the top screen to the right of the output
- }
- return prealloc;
- }
- }
-}
diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/MelonDS_VideoProvider.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/MelonDS_VideoProvider.cs
index 9ff0f14ddc..3897a9a1b4 100644
--- a/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/MelonDS_VideoProvider.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/MelonDS_VideoProvider.cs
@@ -1,5 +1,4 @@
-using System;
-using System.Runtime.InteropServices;
+using System.Runtime.InteropServices;
using BizHawk.Emulation.Common;
@@ -23,19 +22,33 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
private static extern int* GetTopScreenBuffer();
[DllImport(dllPath)]
private static extern int* GetBottomScreenBuffer();
- [DllImport(dllPath)]
- private static extern int GetScreenBufferSize();
// BizHawk needs to be able to modify the buffer when loading savestates.
- private int[] _buffer;
+ private const int SingleScreenLength = 256 * 192;
+ private readonly int[] _buffer = new int[256 * 192 * 2];
private bool _getNewBuffer = true;
+
public int[] GetVideoBuffer()
{
- if (!_getNewBuffer) return _buffer;
- _getNewBuffer = false;
- return _buffer = ScreenArranger.UprightStack(TopScreen, BottomScreen, 0);
+ if (_getNewBuffer)
+ {
+ _getNewBuffer = false;
+ PopulateBuffer();
+ }
+
+ return _buffer;
+ }
+
+ private void PopulateBuffer()
+ {
+ var top = GetTopScreenBuffer();
+ var bottom = GetBottomScreenBuffer();
+
+ for (var i = 0; i < SingleScreenLength; i++)
+ {
+ _buffer[i] = top[i];
+ _buffer[SingleScreenLength + i] = bottom[i];
+ }
}
- private VideoScreen TopScreen => new VideoScreen(GetTopScreenBuffer(), 256, 192);
- private VideoScreen BottomScreen => new VideoScreen(GetBottomScreenBuffer(), 256, 192);
}
}