diff --git a/Core/AutomaticRomTest.cpp b/Core/AutomaticRomTest.cpp
new file mode 100644
index 00000000..30e15ed9
--- /dev/null
+++ b/Core/AutomaticRomTest.cpp
@@ -0,0 +1,167 @@
+#include "stdafx.h"
+#include "../Utilities/FolderUtilities.h"
+#include "AutomaticRomTest.h"
+#include "EmulationSettings.h"
+#include "Console.h"
+#include "PPU.h"
+#include "VideoDecoder.h"
+#include "StandardController.h"
+
+bool AutomaticRomTest::_running = false;
+
+AutomaticRomTest::AutomaticRomTest()
+{
+ _running = true;
+ _errorCode = 0;
+ MessageManager::RegisterNotificationListener(this);
+}
+
+AutomaticRomTest::~AutomaticRomTest()
+{
+ _running = false;
+ MessageManager::UnregisterNotificationListener(this);
+}
+
+void AutomaticRomTest::ProcessNotification(ConsoleNotificationType type, void* parameter)
+{
+ if(type == ConsoleNotificationType::PpuFrameDone) {
+ uint16_t *frameBuffer = (uint16_t*)parameter;
+ if(PPU::GetFrameCount() == 5) {
+ memcpy(_prevFrameBuffer, frameBuffer, sizeof(_prevFrameBuffer));
+ } else if(PPU::GetFrameCount() == 300) {
+ if(memcmp(_prevFrameBuffer, frameBuffer, sizeof(_prevFrameBuffer)) == 0) {
+ //No change
+ _errorCode |= 0x20;
+ }
+ memcpy(_prevFrameBuffer, frameBuffer, sizeof(_prevFrameBuffer));
+ VideoDecoder::GetInstance()->TakeScreenshot();
+ } else if(PPU::GetFrameCount() == 900) {
+ if(memcmp(_prevFrameBuffer, frameBuffer, sizeof(_prevFrameBuffer)) == 0) {
+ //No change
+ _errorCode |= 0x01;
+ }
+
+ bool allZeros = true;
+ for(int i = 0; i < 256 * 240; i++) {
+ if(frameBuffer[i] != 0) {
+ allZeros = false;
+ break;
+ }
+ }
+
+ if(allZeros) {
+ _errorCode |= 0x04;
+ }
+
+ memcpy(_prevFrameBuffer, frameBuffer, sizeof(_prevFrameBuffer));
+ VideoDecoder::GetInstance()->TakeScreenshot();
+ } else if(PPU::GetFrameCount() == 1800) {
+ bool continueTest = false;
+ if(memcmp(_prevFrameBuffer, frameBuffer, sizeof(_prevFrameBuffer)) == 0) {
+ //No change, change input pattern and keep trying
+ continueTest = true;
+ }
+
+ bool allZeros = true;
+ for(int i = 0; i < 256 * 240; i++) {
+ if(frameBuffer[i] != 0) {
+ allZeros = false;
+ break;
+ }
+ }
+
+ if(allZeros) {
+ _errorCode |= 0x08;
+ }
+
+ VideoDecoder::GetInstance()->TakeScreenshot();
+
+ if(!continueTest) {
+ //Stop test
+ _signal.Signal();
+ }
+ } else if(PPU::GetFrameCount() == 3600) {
+ if(memcmp(_prevFrameBuffer, frameBuffer, sizeof(_prevFrameBuffer)) == 0) {
+ //No change
+ _errorCode |= 0x02;
+ }
+
+ bool allZeros = true;
+ for(int i = 0; i < 256 * 240; i++) {
+ if(frameBuffer[i] != 0) {
+ allZeros = false;
+ break;
+ }
+ }
+
+ if(allZeros) {
+ _errorCode |= 0x40;
+ }
+
+ VideoDecoder::GetInstance()->TakeScreenshot();
+
+ //Stop test
+ _signal.Signal();
+ }
+ }
+}
+
+int32_t AutomaticRomTest::Run(string filename)
+{
+ EmulationSettings::SetEmulationSpeed(0);
+ EmulationSettings::SetMasterVolume(0);
+ Console::Pause();
+ if(Console::LoadROM(filename)) {
+ Console::Resume();
+ EmulationSettings::ClearFlags(EmulationFlags::Paused);
+ _signal.Wait();
+
+ EmulationSettings::SetFlags(EmulationFlags::Paused);
+
+ if(PPU::GetFrameCount() < 1800) {
+ //Finished early
+ _errorCode |= 0x10;
+ }
+
+ EmulationSettings::SetEmulationSpeed(100);
+ EmulationSettings::SetMasterVolume(1.0);
+
+ Console::GetInstance()->Stop();
+
+ return _errorCode;
+ }
+
+ return -1;
+}
+
+bool AutomaticRomTest::Running()
+{
+ return _running;
+}
+
+uint8_t AutomaticRomTest::GetControllerState(uint8_t port)
+{
+ if(port == 0) {
+ uint32_t frameNumber = PPU::GetFrameCount();
+
+ if(frameNumber <= 1800) {
+ if(frameNumber % 30 < 10) {
+ //Press 1 button for 10 frames every second
+ if((frameNumber / 30) % 8 != 1) {
+ return 1 << ((frameNumber / 60) % 8);
+ }
+ }
+ } else {
+ if(frameNumber % 30 < 10) {
+ if((frameNumber / 30) % 2) {
+ return 0x01;
+ } else {
+ return 0x08;
+ }
+ }
+ }
+ return 0;
+ } else {
+ return 0;
+ }
+}
diff --git a/Core/AutomaticRomTest.h b/Core/AutomaticRomTest.h
new file mode 100644
index 00000000..48d9f4cf
--- /dev/null
+++ b/Core/AutomaticRomTest.h
@@ -0,0 +1,23 @@
+#pragma once
+#include "stdafx.h"
+#include "INotificationListener.h"
+#include "../Utilities/AutoResetEvent.h"
+
+class AutomaticRomTest : public INotificationListener
+{
+private:
+ AutoResetEvent _signal;
+ static bool _running;
+ uint16_t _prevFrameBuffer[256 * 240];
+ uint32_t _errorCode;
+
+public:
+ AutomaticRomTest();
+ ~AutomaticRomTest();
+
+ void ProcessNotification(ConsoleNotificationType type, void* parameter) override;
+ int32_t Run(string filename);
+
+ static bool Running();
+ static uint8_t GetControllerState(uint8_t port);
+};
\ No newline at end of file
diff --git a/Core/BaseControlDevice.cpp b/Core/BaseControlDevice.cpp
index b73ed016..77d42e8c 100644
--- a/Core/BaseControlDevice.cpp
+++ b/Core/BaseControlDevice.cpp
@@ -5,6 +5,7 @@
#include "EmulationSettings.h"
#include "GameClient.h"
#include "GameServerConnection.h"
+#include "AutomaticRomTest.h"
BaseControlDevice::BaseControlDevice(uint8_t port)
{
@@ -63,6 +64,8 @@ uint8_t BaseControlDevice::GetControlState()
_currentState = MovieManager::GetState(_port);
} else if(GameClient::Connected()) {
_currentState = GameClient::GetControllerState(_port);
+ } else if(AutomaticRomTest::Running()) {
+ _currentState = AutomaticRomTest::GetControllerState(_port);
} else if(netPlayDevice) {
_currentState = ProcessNetPlayState(netPlayDevice->GetState());
} else {
diff --git a/Core/Console.cpp b/Core/Console.cpp
index 7567029b..c9e950a5 100644
--- a/Core/Console.cpp
+++ b/Core/Console.cpp
@@ -43,7 +43,7 @@ void Console::Release()
Console::Instance.reset(new Console());
}
-void Console::Initialize(string romFilename, stringstream *filestream, string patchFilename, int32_t archiveFileIndex)
+bool Console::Initialize(string romFilename, stringstream *filestream, string patchFilename, int32_t archiveFileIndex)
{
SoundMixer::StopAudio();
@@ -105,16 +105,19 @@ void Console::Initialize(string romFilename, stringstream *filestream, string pa
if(EmulationSettings::GetOverclockRate() != 100) {
MessageManager::DisplayMessage("ClockRate", std::to_string(EmulationSettings::GetOverclockRate()) + "%");
}
+ return true;
} else {
MessageManager::DisplayMessage("Error", "CouldNotLoadFile", FolderUtilities::GetFilename(romFilename, true));
+ return false;
}
}
-void Console::LoadROM(string filepath, stringstream *filestream, int32_t archiveFileIndex, string patchFilepath)
+bool Console::LoadROM(string filepath, stringstream *filestream, int32_t archiveFileIndex, string patchFilepath)
{
Console::Pause();
- Instance->Initialize(filepath, filestream, patchFilepath, archiveFileIndex);
+ bool result = Instance->Initialize(filepath, filestream, patchFilepath, archiveFileIndex);
Console::Resume();
+ return result;
}
bool Console::LoadROM(string romName, uint32_t crc32Hash)
@@ -145,8 +148,7 @@ bool Console::LoadROM(string romName, HashInfo hashInfo)
for(string folder : FolderUtilities::GetKnownGameFolders()) {
string match = RomLoader::FindMatchingRomInFolder(folder, romName, hashInfo, true, archiveFileIndex);
if(!match.empty()) {
- Console::LoadROM(match, nullptr, archiveFileIndex);
- return true;
+ return Console::LoadROM(match, nullptr, archiveFileIndex);
}
}
@@ -154,8 +156,7 @@ bool Console::LoadROM(string romName, HashInfo hashInfo)
for(string folder : FolderUtilities::GetKnownGameFolders()) {
string match = RomLoader::FindMatchingRomInFolder(folder, romName, hashInfo, false, archiveFileIndex);
if(!match.empty()) {
- Console::LoadROM(match, nullptr, archiveFileIndex);
- return true;
+ return Console::LoadROM(match, nullptr, archiveFileIndex);
}
}
diff --git a/Core/Console.h b/Core/Console.h
index cecdb4bb..1509d1ee 100644
--- a/Core/Console.h
+++ b/Core/Console.h
@@ -47,7 +47,7 @@ class Console
bool _initialized = false;
void ResetComponents(bool softReset);
- void Initialize(string filename, stringstream *filestream = nullptr, string patchFilename = "", int32_t archiveFileIndex = -1);
+ bool Initialize(string filename, stringstream *filestream = nullptr, string patchFilename = "", int32_t archiveFileIndex = -1);
void UpdateNesModel(bool sendNotification);
double GetFrameDelay();
@@ -73,7 +73,7 @@ class Console
static void LoadState(istream &loadStream);
static void LoadState(uint8_t *buffer, uint32_t bufferSize);
- static void LoadROM(string filepath, stringstream *filestream = nullptr, int32_t archiveFileIndex = -1, string patchFilepath = "");
+ static bool LoadROM(string filepath, stringstream *filestream = nullptr, int32_t archiveFileIndex = -1, string patchFilepath = "");
static bool LoadROM(string romName, HashInfo hashInfo);
static bool LoadROM(string romName, uint32_t crc32Hash);
static bool LoadROM(string romName, string sha1Hash);
diff --git a/Core/Core.vcxproj b/Core/Core.vcxproj
index 3dddf80f..aa74f7ea 100644
--- a/Core/Core.vcxproj
+++ b/Core/Core.vcxproj
@@ -410,7 +410,8 @@
-
+
+
@@ -764,7 +765,8 @@
-
+
+
diff --git a/Core/Core.vcxproj.filters b/Core/Core.vcxproj.filters
index 54a34887..7be3550d 100644
--- a/Core/Core.vcxproj.filters
+++ b/Core/Core.vcxproj.filters
@@ -553,9 +553,6 @@
Nes
-
- Misc
-
Misc
@@ -1156,6 +1153,12 @@
Movies
+
+ Misc
+
+
+ Misc
+
@@ -1185,9 +1188,6 @@
Debugger
-
- Misc
-
VideoDecoder
@@ -1365,5 +1365,11 @@
Movies
+
+ Misc
+
+
+ Misc
+
\ No newline at end of file
diff --git a/Core/AutoRomTest.cpp b/Core/RecordedRomTest.cpp
similarity index 89%
rename from Core/AutoRomTest.cpp
rename to Core/RecordedRomTest.cpp
index 6fd6d75f..031a6792 100644
--- a/Core/AutoRomTest.cpp
+++ b/Core/RecordedRomTest.cpp
@@ -1,6 +1,6 @@
#include "stdafx.h"
-#include "AutoRomTest.h"
+#include "RecordedRomTest.h"
#include "Console.h"
#include "EmulationSettings.h"
#include "MessageManager.h"
@@ -11,21 +11,21 @@
#include "../Utilities/ZipWriter.h"
#include "../Utilities/ZipReader.h"
-AutoRomTest::AutoRomTest()
+RecordedRomTest::RecordedRomTest()
{
Reset();
MessageManager::RegisterNotificationListener(this);
}
-AutoRomTest::~AutoRomTest()
+RecordedRomTest::~RecordedRomTest()
{
Reset();
MessageManager::UnregisterNotificationListener(this);
}
-void AutoRomTest::SaveFrame(uint16_t* ppuFrameBuffer)
+void RecordedRomTest::SaveFrame(uint16_t* ppuFrameBuffer)
{
uint8_t md5Hash[16];
GetMd5Sum(md5Hash, ppuFrameBuffer, PPU::PixelCount * sizeof(uint16_t));
@@ -47,7 +47,7 @@ void AutoRomTest::SaveFrame(uint16_t* ppuFrameBuffer)
}
}
-void AutoRomTest::ValidateFrame(uint16_t* ppuFrameBuffer)
+void RecordedRomTest::ValidateFrame(uint16_t* ppuFrameBuffer)
{
uint8_t md5Hash[16];
GetMd5Sum(md5Hash, ppuFrameBuffer, PPU::PixelCount * sizeof(uint16_t));
@@ -71,7 +71,7 @@ void AutoRomTest::ValidateFrame(uint16_t* ppuFrameBuffer)
}
}
-void AutoRomTest::ProcessNotification(ConsoleNotificationType type, void* parameter)
+void RecordedRomTest::ProcessNotification(ConsoleNotificationType type, void* parameter)
{
switch(type) {
case ConsoleNotificationType::PpuFrameDone:
@@ -89,7 +89,7 @@ void AutoRomTest::ProcessNotification(ConsoleNotificationType type, void* parame
}
}
-void AutoRomTest::Reset()
+void RecordedRomTest::Reset()
{
memset(_previousHash, 0xFF, 16);
@@ -107,7 +107,7 @@ void AutoRomTest::Reset()
_recordingFromMovie = false;
}
-void AutoRomTest::Record(string filename, bool reset)
+void RecordedRomTest::Record(string filename, bool reset)
{
_filename = filename;
@@ -127,7 +127,7 @@ void AutoRomTest::Record(string filename, bool reset)
}
}
-void AutoRomTest::RecordFromMovie(string testFilename, stringstream &movieStream, bool autoLoadRom)
+void RecordedRomTest::RecordFromMovie(string testFilename, stringstream &movieStream, bool autoLoadRom)
{
_filename = testFilename;
@@ -151,7 +151,7 @@ void AutoRomTest::RecordFromMovie(string testFilename, stringstream &movieStream
}
}
-void AutoRomTest::RecordFromMovie(string testFilename, string movieFilename)
+void RecordedRomTest::RecordFromMovie(string testFilename, string movieFilename)
{
stringstream ss;
ifstream file(movieFilename, ios::in | ios::binary);
@@ -162,7 +162,7 @@ void AutoRomTest::RecordFromMovie(string testFilename, string movieFilename)
}
}
-void AutoRomTest::RecordFromTest(string newTestFilename, string existingTestFilename)
+void RecordedRomTest::RecordFromTest(string newTestFilename, string existingTestFilename)
{
ZipReader zipReader;
zipReader.LoadArchive(existingTestFilename);
@@ -180,7 +180,7 @@ void AutoRomTest::RecordFromTest(string newTestFilename, string existingTestFile
}
}
-int32_t AutoRomTest::Run(string filename)
+int32_t RecordedRomTest::Run(string filename)
{
string testName = FolderUtilities::GetFilename(filename, false);
if(testName.compare("5.MMC3_rev_A") == 0 || testName.compare("6-MMC6") == 0 || testName.compare("6-MMC3_alt") == 0) {
@@ -255,7 +255,7 @@ int32_t AutoRomTest::Run(string filename)
return -1;
}
-void AutoRomTest::Stop()
+void RecordedRomTest::Stop()
{
if(_recording) {
Save();
@@ -263,7 +263,7 @@ void AutoRomTest::Stop()
Reset();
}
-void AutoRomTest::Save()
+void RecordedRomTest::Save()
{
//Wait until the next frame is captured to end the recording
_signal.Wait();
diff --git a/Core/AutoRomTest.h b/Core/RecordedRomTest.h
similarity index 91%
rename from Core/AutoRomTest.h
rename to Core/RecordedRomTest.h
index a3e55565..4eab3f01 100644
--- a/Core/AutoRomTest.h
+++ b/Core/RecordedRomTest.h
@@ -5,7 +5,7 @@
#include "INotificationListener.h"
#include "../Utilities/AutoResetEvent.h"
-class AutoRomTest : public INotificationListener
+class RecordedRomTest : public INotificationListener
{
private:
bool _recording;
@@ -35,8 +35,8 @@ private:
void RecordFromMovie(string testFilename, stringstream &movieStream, bool autoLoadRom);
public:
- AutoRomTest();
- virtual ~AutoRomTest();
+ RecordedRomTest();
+ virtual ~RecordedRomTest();
void ProcessNotification(ConsoleNotificationType type, void* parameter) override;
void Record(string filename, bool reset);
diff --git a/GUI.NET/Forms/frmMain.Designer.cs b/GUI.NET/Forms/frmMain.Designer.cs
index 5da77b7c..f06834d3 100644
--- a/GUI.NET/Forms/frmMain.Designer.cs
+++ b/GUI.NET/Forms/frmMain.Designer.cs
@@ -179,6 +179,7 @@ namespace Mesen.GUI.Forms
this.toolStripMenuItem5 = new System.Windows.Forms.ToolStripSeparator();
this.mnuHelpWindow = new System.Windows.Forms.ToolStripMenuItem();
this.mnuAbout = new System.Windows.Forms.ToolStripMenuItem();
+ this.mnuRunAutomaticTest = new System.Windows.Forms.ToolStripMenuItem();
this.panelRenderer.SuspendLayout();
this.menuStrip.SuspendLayout();
this.SuspendLayout();
@@ -1238,7 +1239,8 @@ namespace Mesen.GUI.Forms
this.mnuTestRecordFrom,
this.mnuTestStopRecording,
this.mnuRunAllTests,
- this.mnuRunAllGameTests});
+ this.mnuRunAllGameTests,
+ this.mnuRunAutomaticTest});
this.mnuTests.Name = "mnuTests";
this.mnuTests.Size = new System.Drawing.Size(231, 22);
this.mnuTests.Text = "Tests";
@@ -1265,28 +1267,28 @@ namespace Mesen.GUI.Forms
//
this.mnuTestRecordStart.Name = "mnuTestRecordStart";
this.mnuTestRecordStart.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.W)));
- this.mnuTestRecordStart.Size = new System.Drawing.Size(143, 22);
+ this.mnuTestRecordStart.Size = new System.Drawing.Size(152, 22);
this.mnuTestRecordStart.Text = "Start";
this.mnuTestRecordStart.Click += new System.EventHandler(this.mnuTestRecordStart_Click);
//
// mnuTestRecordNow
//
this.mnuTestRecordNow.Name = "mnuTestRecordNow";
- this.mnuTestRecordNow.Size = new System.Drawing.Size(143, 22);
+ this.mnuTestRecordNow.Size = new System.Drawing.Size(152, 22);
this.mnuTestRecordNow.Text = "Now";
this.mnuTestRecordNow.Click += new System.EventHandler(this.mnuTestRecordNow_Click);
//
// mnuTestRecordMovie
//
this.mnuTestRecordMovie.Name = "mnuTestRecordMovie";
- this.mnuTestRecordMovie.Size = new System.Drawing.Size(143, 22);
+ this.mnuTestRecordMovie.Size = new System.Drawing.Size(152, 22);
this.mnuTestRecordMovie.Text = "Movie";
this.mnuTestRecordMovie.Click += new System.EventHandler(this.mnuTestRecordMovie_Click);
//
// mnuTestRecordTest
//
this.mnuTestRecordTest.Name = "mnuTestRecordTest";
- this.mnuTestRecordTest.Size = new System.Drawing.Size(143, 22);
+ this.mnuTestRecordTest.Size = new System.Drawing.Size(152, 22);
this.mnuTestRecordTest.Text = "Test";
this.mnuTestRecordTest.Click += new System.EventHandler(this.mnuTestRecordTest_Click);
//
@@ -1406,6 +1408,13 @@ namespace Mesen.GUI.Forms
this.mnuAbout.Text = "About";
this.mnuAbout.Click += new System.EventHandler(this.mnuAbout_Click);
//
+ // mnuRunAutomaticTest
+ //
+ this.mnuRunAutomaticTest.Name = "mnuRunAutomaticTest";
+ this.mnuRunAutomaticTest.Size = new System.Drawing.Size(192, 22);
+ this.mnuRunAutomaticTest.Text = "Run automatic test";
+ this.mnuRunAutomaticTest.Click += new System.EventHandler(this.mnuRunAutomaticTest_Click);
+ //
// frmMain
//
this.AllowDrop = true;
@@ -1580,6 +1589,7 @@ namespace Mesen.GUI.Forms
private System.Windows.Forms.ToolStripMenuItem mnuPrescale6xFilter;
private System.Windows.Forms.ToolStripMenuItem mnuPrescale8xFilter;
private System.Windows.Forms.ToolStripMenuItem mnuPrescale10xFilter;
+ private System.Windows.Forms.ToolStripMenuItem mnuRunAutomaticTest;
}
}
diff --git a/GUI.NET/Forms/frmMain.cs b/GUI.NET/Forms/frmMain.cs
index eb962ebc..b43171f3 100644
--- a/GUI.NET/Forms/frmMain.cs
+++ b/GUI.NET/Forms/frmMain.cs
@@ -1060,7 +1060,7 @@ namespace Mesen.GUI.Forms
Task.Run(() => {
foreach(string filename in ofd.FileNames) {
- int result = InteropEmu.RomTestRun(filename);
+ int result = InteropEmu.RunRecordedTest(filename);
if(result == 0) {
passedTests.Add(Path.GetFileNameWithoutExtension(filename));
@@ -1207,6 +1207,20 @@ namespace Mesen.GUI.Forms
InteropEmu.SetNesModel(ConfigManager.Config.Region);
}
+ private void mnuRunAutomaticTest_Click(object sender, EventArgs e)
+ {
+ using(OpenFileDialog ofd = new OpenFileDialog()) {
+ ofd.SetFilter("*.nes|*.nes");
+ if(ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK) {
+ string filename = ofd.FileName;
+
+ Task.Run(() => {
+ int result = InteropEmu.RunAutomaticTest(filename);
+ });
+ }
+ }
+ }
+
private void mnuRunAllTests_Click(object sender, EventArgs e)
{
string workingDirectory = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location));
diff --git a/GUI.NET/InteropEmu.cs b/GUI.NET/InteropEmu.cs
index 7ebbce58..94dd1de2 100644
--- a/GUI.NET/InteropEmu.cs
+++ b/GUI.NET/InteropEmu.cs
@@ -99,7 +99,8 @@ namespace Mesen.GUI
[DllImport(DLLPath)] public static extern void WaveStop();
[DllImport(DLLPath)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool WaveIsRecording();
- [DllImport(DLLPath)] public static extern Int32 RomTestRun([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]string filename);
+ [DllImport(DLLPath)] public static extern Int32 RunRecordedTest([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]string filename);
+ [DllImport(DLLPath)] public static extern Int32 RunAutomaticTest([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]string filename);
[DllImport(DLLPath)] public static extern void RomTestRecord([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]string filename, [MarshalAs(UnmanagedType.I1)]bool reset);
[DllImport(DLLPath)] public static extern void RomTestRecordFromMovie([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]string testFilename, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]string movieFilename);
[DllImport(DLLPath)] public static extern void RomTestRecordFromTest([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]string newTestFilename, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]string existingTestFilename);
diff --git a/InteropDLL/ConsoleWrapper.cpp b/InteropDLL/ConsoleWrapper.cpp
index 73ff9694..aa7cc8d4 100644
--- a/InteropDLL/ConsoleWrapper.cpp
+++ b/InteropDLL/ConsoleWrapper.cpp
@@ -9,7 +9,8 @@
#include "../Core/CheatManager.h"
#include "../Core/EmulationSettings.h"
#include "../Core/VideoDecoder.h"
-#include "../Core/AutoRomTest.h"
+#include "../Core/AutomaticRomTest.h"
+#include "../Core/RecordedRomTest.h"
#include "../Core/FDS.h"
#include "../Core/VsControlManager.h"
#include "../Core/SoundMixer.h"
@@ -37,7 +38,7 @@ void* _windowHandle = nullptr;
void* _viewerHandle = nullptr;
string _returnString;
string _logString;
-AutoRomTest *_autoRomTest = nullptr;
+RecordedRomTest *_recordedRomTest = nullptr;
typedef void (__stdcall *NotificationListenerCallback)(int);
@@ -313,43 +314,49 @@ namespace InteropEmu {
DllExport void __stdcall WaveStop() { SoundMixer::StopRecording(); }
DllExport bool __stdcall WaveIsRecording() { return SoundMixer::IsRecording(); }
- DllExport int32_t __stdcall RomTestRun(char* filename)
+ DllExport int32_t __stdcall RunRecordedTest(char* filename)
{
- AutoRomTest romTest;
+ RecordedRomTest romTest;
+ return romTest.Run(filename);
+ }
+
+ DllExport int32_t __stdcall RunAutomaticTest(char* filename)
+ {
+ AutomaticRomTest romTest;
return romTest.Run(filename);
}
DllExport void __stdcall RomTestRecord(char* filename, bool reset)
{
- if(_autoRomTest) {
- delete _autoRomTest;
+ if(_recordedRomTest) {
+ delete _recordedRomTest;
}
- _autoRomTest = new AutoRomTest();
- _autoRomTest->Record(filename, reset);
+ _recordedRomTest = new RecordedRomTest();
+ _recordedRomTest->Record(filename, reset);
}
DllExport void __stdcall RomTestRecordFromMovie(char* testFilename, char* movieFilename)
{
- _autoRomTest = new AutoRomTest();
- _autoRomTest->RecordFromMovie(testFilename, movieFilename);
+ _recordedRomTest = new RecordedRomTest();
+ _recordedRomTest->RecordFromMovie(testFilename, movieFilename);
}
DllExport void __stdcall RomTestRecordFromTest(char* newTestFilename, char* existingTestFilename)
{
- _autoRomTest = new AutoRomTest();
- _autoRomTest->RecordFromTest(newTestFilename, existingTestFilename);
+ _recordedRomTest = new RecordedRomTest();
+ _recordedRomTest->RecordFromTest(newTestFilename, existingTestFilename);
}
DllExport void __stdcall RomTestStop()
{
- if(_autoRomTest) {
- _autoRomTest->Stop();
- delete _autoRomTest;
- _autoRomTest = nullptr;
+ if(_recordedRomTest) {
+ _recordedRomTest->Stop();
+ delete _recordedRomTest;
+ _recordedRomTest = nullptr;
}
}
- DllExport bool __stdcall RomTestRecording() { return _autoRomTest != nullptr; }
+ DllExport bool __stdcall RomTestRecording() { return _recordedRomTest != nullptr; }
DllExport void __stdcall SetCheats(CheatInfo cheats[], uint32_t length) { CheatManager::SetCheats(cheats, length); }
diff --git a/TestHelper/TestHelper.cpp b/TestHelper/TestHelper.cpp
index 9374f2c3..37e98f11 100644
--- a/TestHelper/TestHelper.cpp
+++ b/TestHelper/TestHelper.cpp
@@ -46,7 +46,8 @@ public:
extern "C" {
void __stdcall InitializeEmu(const char* homeFolder, void*, void*, bool, bool, bool);
void __stdcall SetControllerType(uint32_t port, ControllerType type);
- int __stdcall RomTestRun(char* filename);
+ int __stdcall RunAutomaticTest(char* filename);
+ int __stdcall RunRecordedTest(char* filename);
void __stdcall LoadROM(char* filename);
void __stdcall Run();
void __stdcall Stop();
@@ -57,21 +58,27 @@ std::thread *runThread = nullptr;
std::atomic testIndex;
vector testFilenames;
vector failedTests;
+vector failedTestErrorCode;
SimpleLock lock;
Timer timer;
+bool automaticTests = false;
+
+void RunEmu()
+{
+ try {
+ Run();
+ } catch(std::exception ex) {
+
+ }
+}
void __stdcall OnNotificationReceived(ConsoleNotificationType type)
{
if(type == ConsoleNotificationType::GameLoaded) {
- runThread = new std::thread(Run);
+ runThread = new std::thread(RunEmu);
}
}
-void RunEmu()
-{
- Run();
-}
-
void RunTest()
{
while(true) {
@@ -82,11 +89,21 @@ void RunTest()
if(index < testFilenames.size()) {
string filepath = testFilenames[index];
string filename = FolderUtilities::GetFilename(filepath, false);
- #ifdef _WIN32
- string command = "TestHelper.exe /testrom \"" + filepath + "\"";
- #else
- string command = "./testhelper /testrom \"" + filepath + "\"";
- #endif
+
+ string command;
+ if(automaticTests) {
+ #ifdef _WIN32
+ command = "TestHelper.exe /autotest \"" + filepath + "\"";
+ #else
+ command = "./testhelper /autotest \"" + filepath + "\"";
+ #endif
+ } else {
+ #ifdef _WIN32
+ command = "TestHelper.exe /testrom \"" + filepath + "\"";
+ #else
+ command = "./testhelper /testrom \"" + filepath + "\"";
+ #endif
+ }
lock.Acquire();
std::cout << std::to_string(index) << ") " << filename << std::endl;
@@ -101,6 +118,7 @@ void RunTest()
//Test failed
lock.Acquire();
failedTests.push_back(filename);
+ failedTestErrorCode.push_back(failedFrames);
std::cout << " **** " << std::to_string(index) << ") " << filename << " failed (" << failedFrames << ")" << std::endl;
lock.Release();
}
@@ -132,18 +150,24 @@ int main(int argc, char* argv[])
signal(SIGSEGV, handler);
#endif
- if(argc <= 2) {
+ if(argc >= 3 && strcmp(argv[1], "/auto") == 0) {
+ string romFolder = argv[2];
+ testFilenames = FolderUtilities::GetFilesInFolder(romFolder, ".nes", true);
+ automaticTests = true;
+ } else if(argc <= 2) {
string testFolder;
if(argc == 1) {
testFolder = FolderUtilities::CombinePath(mesenFolder, "Tests");
} else {
testFolder = argv[1];
}
-
- vector testThreads;
testFilenames = FolderUtilities::GetFilesInFolder(testFolder, ".mtp", true);
- testIndex = 0;
+ automaticTests = false;
+ }
+ if(!testFilenames.empty()) {
+ vector testThreads;
+ testIndex = 0;
timer.Reset();
int numberOfThreads = 4;
@@ -162,9 +186,10 @@ int main(int argc, char* argv[])
std::cout << "------------" << std::endl;
std::cout << "Failed tests" << std::endl;
std::cout << "------------" << std::endl;
- for(string failedTest : failedTests) {
- std::cout << failedTest << std::endl;
+ for(int i = 0; i < failedTests.size(); i++) {
+ std::cout << failedTests[i] << " (" << std::to_string(failedTestErrorCode[i]) << ")" << std::endl;
}
+ std::cout << std::endl << std::to_string(failedTests.size()) << " tests failed." << std::endl;
} else {
std::cout << std::endl << std::endl << "All tests passed.";
}
@@ -179,7 +204,13 @@ int main(int argc, char* argv[])
SetControllerType(0, ControllerType::StandardController);
SetControllerType(1, ControllerType::StandardController);
- int result = RomTestRun(testFilename);
+ int result = 0;
+ if(strcmp(argv[1], "/testrom") == 0) {
+ result = RunRecordedTest(testFilename);
+ } else {
+ result = RunAutomaticTest(testFilename);
+ }
+
if(runThread != nullptr) {
runThread->join();
delete runThread;