diff --git a/src/BizHawk.Tests/BizHawk.Tests.csproj b/src/BizHawk.Tests/BizHawk.Tests.csproj index aea54efd1d..2904403492 100644 --- a/src/BizHawk.Tests/BizHawk.Tests.csproj +++ b/src/BizHawk.Tests/BizHawk.Tests.csproj @@ -16,6 +16,7 @@ + @@ -25,4 +26,7 @@ + + + diff --git a/src/BizHawk.Tests/Client.Common/lua/LuaScripts/DrawTest1.lua b/src/BizHawk.Tests/Client.Common/lua/LuaScripts/DrawTest1.lua new file mode 100644 index 0000000000..b88fb6a12e --- /dev/null +++ b/src/BizHawk.Tests/Client.Common/lua/LuaScripts/DrawTest1.lua @@ -0,0 +1,4 @@ +while true do + gui.drawRectangle(2, 2, 0, 0, 0xffff0000, 0, "client") + emu.frameadvance() +end diff --git a/src/BizHawk.Tests/Client.Common/lua/LuaScripts/DrawTest2.lua b/src/BizHawk.Tests/Client.Common/lua/LuaScripts/DrawTest2.lua new file mode 100644 index 0000000000..91d9ccac07 --- /dev/null +++ b/src/BizHawk.Tests/Client.Common/lua/LuaScripts/DrawTest2.lua @@ -0,0 +1,4 @@ +while true do + gui.drawRectangle(2, 4, 0, 0, 0xff00ff00, 0, "client") + emu.frameadvance() +end diff --git a/src/BizHawk.Tests/Client.Common/lua/TestLuaDrawing.cs b/src/BizHawk.Tests/Client.Common/lua/TestLuaDrawing.cs new file mode 100644 index 0000000000..5e7f1bf18a --- /dev/null +++ b/src/BizHawk.Tests/Client.Common/lua/TestLuaDrawing.cs @@ -0,0 +1,78 @@ +using System.Drawing; +using System.IO; + +using BizHawk.Bizware.BizwareGL; +using BizHawk.Client.Common; +using BizHawk.Emulation.Common; +using BizHawk.Tests.Mocks; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace BizHawk.Tests.Client.Common.Lua +{ + [TestClass] + public class TestLuaDrawing + { +#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. + // null values are initialized in the setup method + private ILuaLibraries luaLibraries = null; + private DisplayManagerBase displayManager = null; +#pragma warning restore CS8625 // Cannot convert null literal to non-nullable reference type. + + private const string pathToTestLuaScripts = "Client.Common/lua/LuaScripts"; + + [TestInitialize] + public void TestSetup() + { + Config config = new Config(); + IGameInfo gameInfo = new GameInfo(); + + IMainFormForApi mainForm = new MockMainFormForApi(new NullEmulator()); + displayManager = new TestDisplayManager(mainForm.Emulator); + + luaLibraries = new TestLuaLibraries( + mainForm, + displayManager, + config, + gameInfo + ); + luaLibraries.Restart(config, gameInfo); + } + + private LuaFile AddScript(string path, bool autoStart = true) + { + LuaFile luaFile = new LuaFile("", path); + luaLibraries.ScriptList.Add(luaFile); + luaLibraries.EnableLuaFile(luaFile); + + if (autoStart) + luaLibraries.ResumeScript(luaFile); + + return luaFile; + } + + [TestMethod] + public void TestDrawingWithOneScript() + { + AddScript(Path.Combine(pathToTestLuaScripts, "DrawTest1.lua")); + + BitmapBufferVideoProvider vp = new BitmapBufferVideoProvider(new BitmapBuffer(8, 8)); + var buffer = displayManager.RenderOffscreenLua(vp); + + Assert.AreEqual(buffer.GetPixel(2, 2), Color.Red.ToArgb()); + } + + [TestMethod] + public void TestDrawingWithTwoScripts() + { + AddScript(Path.Combine(pathToTestLuaScripts, "DrawTest1.lua")); + AddScript(Path.Combine(pathToTestLuaScripts, "DrawTest2.lua")); + + BitmapBufferVideoProvider vp = new BitmapBufferVideoProvider(new BitmapBuffer(8, 8)); + var buffer = displayManager.RenderOffscreenLua(vp); + + Assert.AreEqual(buffer.GetPixel(2, 2), Color.Red.ToArgb()); + Assert.AreEqual(buffer.GetPixel(2, 4), 0xff00ff00); + } + + } +} \ No newline at end of file diff --git a/src/BizHawk.Tests/Implementations/TestDisplayManager.cs b/src/BizHawk.Tests/Implementations/TestDisplayManager.cs new file mode 100644 index 0000000000..2fe3653378 --- /dev/null +++ b/src/BizHawk.Tests/Implementations/TestDisplayManager.cs @@ -0,0 +1,31 @@ +using System.Drawing; + +using BizHawk.Bizware.Graphics; +using BizHawk.Client.Common; +using BizHawk.Emulation.Common; + +namespace BizHawk.Tests +{ + internal class TestDisplayManager : DisplayManagerBase + { + private Size _screenSize; + + private TestDisplayManager(Config config, IEmulator emulator, InputManager inputManager, IGL_GDIPlus gl) + : base(config, emulator, inputManager, null, gl.DispMethodEnum, gl, new GDIPlusGuiRenderer(gl)) + { + var vp = emulator.AsVideoProviderOrDefault(); + _screenSize = new Size(vp.BufferWidth, vp.BufferHeight); + + } + public TestDisplayManager(IEmulator emulator) + : this(new Config(), emulator, new InputManager(), new IGL_GDIPlus()) + { } + + public override void ActivateOpenGLContext() { } // Nothing. We only use GDIPlus here. + public override Size GetPanelNativeSize() => _screenSize; + protected override void ActivateGraphicsControlContext() { } + protected override Size GetGraphicsControlSize() => _screenSize; + protected override Point GraphicsControlPointToClient(Point p) => p; + protected override void SwapBuffersOfGraphicsControl() { } + } +} diff --git a/src/BizHawk.Tests/Implementations/TestLuaLibraries.cs b/src/BizHawk.Tests/Implementations/TestLuaLibraries.cs new file mode 100644 index 0000000000..7d3a74d70e --- /dev/null +++ b/src/BizHawk.Tests/Implementations/TestLuaLibraries.cs @@ -0,0 +1,22 @@ +using System.Collections.Generic; + +using BizHawk.Client.Common; +using BizHawk.Emulation.Common; + +namespace BizHawk.Tests +{ + internal class TestLuaLibraries : LuaLibrariesBase + { + public TestLuaLibraries(IMainFormForApi mainForm, DisplayManagerBase displayManager, Config config, IGameInfo game) + : base(new LuaFileList( + new List(), () => { }), + new LuaFunctionList(() => { }), + mainForm, + displayManager, + new InputManager(), + config, + game + ) + { } + } +} diff --git a/src/BizHawk.Tests/Mocks/MockMainFormForApi.cs b/src/BizHawk.Tests/Mocks/MockMainFormForApi.cs new file mode 100644 index 0000000000..e6c40f37c4 --- /dev/null +++ b/src/BizHawk.Tests/Mocks/MockMainFormForApi.cs @@ -0,0 +1,70 @@ +using System; +using System.Drawing; + +using BizHawk.Client.Common; +using BizHawk.Emulation.Common; + +namespace BizHawk.Tests.Mocks +{ + internal class MockMainFormForApi : IMainFormForApi + { + public (HttpCommunication HTTP, MemoryMappedFiles MMF, SocketServer Sockets) NetworkingHelpers => (null!, null!, null!); + + public IEmulator Emulator { get; } + + public IMovieSession MovieSession => null!; + + public IToolManager Tools => null!; + + public MockMainFormForApi(IEmulator emulator) + { + Emulator = emulator; + } + + + // Everything below here is not implemented. + public CheatCollection CheatList => throw new NotImplementedException(); + + public Point DesktopLocation => throw new NotImplementedException(); + + public bool EmulatorPaused => throw new NotImplementedException(); + + public bool InvisibleEmulation { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public bool IsSeeking => throw new NotImplementedException(); + + public bool IsTurboing => throw new NotImplementedException(); + + public bool PauseAvi { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public void ClearHolds() => throw new NotImplementedException(); + public void ClickSpeedItem(int num) => throw new NotImplementedException(); + public void CloseEmulator(int? exitCode = null) => throw new NotImplementedException(); + public void CloseRom(bool clearSram = false) => throw new NotImplementedException(); + public void EnableRewind(bool enabled) => throw new NotImplementedException(); + public bool FlushSaveRAM(bool autosave = false) => throw new NotImplementedException(); + public void FrameAdvance() => throw new NotImplementedException(); + public void FrameBufferResized() => throw new NotImplementedException(); + public void FrameSkipMessage() => throw new NotImplementedException(); + public int GetApproxFramerate() => throw new NotImplementedException(); + public bool LoadMovie(string filename, string? archive = null) => throw new NotImplementedException(); + public bool LoadQuickSave(int slot, bool suppressOSD = false) => throw new NotImplementedException(); + public bool LoadRom(string path, LoadRomArgs args) => throw new NotImplementedException(); + public bool LoadState(string path, string userFriendlyStateName, bool suppressOSD = false) => throw new NotImplementedException(); + public void PauseEmulator() => throw new NotImplementedException(); + public bool RebootCore() => throw new NotImplementedException(); + public void Render() => throw new NotImplementedException(); + public bool RestartMovie() => throw new NotImplementedException(); + public void SaveQuickSave(int slot, bool suppressOSD = false, bool fromLua = false) => throw new NotImplementedException(); + public void SaveState(string path, string userFriendlyStateName, bool fromLua = false, bool suppressOSD = false) => throw new NotImplementedException(); + public void SeekFrameAdvance() => throw new NotImplementedException(); + public void StepRunLoop_Throttle() => throw new NotImplementedException(); + public void StopMovie(bool saveChanges = true) => throw new NotImplementedException(); + public void TakeScreenshot() => throw new NotImplementedException(); + public void TakeScreenshot(string path) => throw new NotImplementedException(); + public void TakeScreenshotToClipboard() => throw new NotImplementedException(); + public void TogglePause() => throw new NotImplementedException(); + public void ToggleSound() => throw new NotImplementedException(); + public void UnpauseEmulator() => throw new NotImplementedException(); + } +} diff --git a/src/BizHawk.Tests/PreTests.cs b/src/BizHawk.Tests/PreTests.cs new file mode 100644 index 0000000000..cf76408cf7 --- /dev/null +++ b/src/BizHawk.Tests/PreTests.cs @@ -0,0 +1,17 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace BizHawk.Tests +{ + [TestClass] + public class PreTests + { + [AssemblyInitialize] + public static void PreTestsMethod(TestContext context) + { + // This method will run only once, before all tests. + // So this seems a good place to initialize static classes. + BizHawk.Client.Common.ApiManager.FindApis(BizHawk.Client.Common.ReflectionCache.Types); + } + } + +}