Mesen/Core/AutomaticRomTest.cpp

168 lines
3.7 KiB
C++

#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::SetFlags(EmulationFlags::ForceMaxSpeed);
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::ClearFlags(EmulationFlags::ForceMaxSpeed);
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;
}
}