Libretro: Updated code for refactoring + fixed compilation errors

This commit is contained in:
Sour 2018-07-03 23:32:26 -04:00
parent 08aa617a91
commit 454457caf4
7 changed files with 87 additions and 65 deletions

View file

@ -77,6 +77,11 @@ void Console::Init()
void Console::Release(bool forShutdown)
{
if(_slave) {
_slave->Release(true);
_slave.reset();
}
if(forShutdown) {
_videoDecoder->StopThread();
_videoRenderer->StopThread();
@ -105,11 +110,6 @@ void Console::Release(bool forShutdown)
_systemActionManager.reset();
if(_slave) {
_slave->Release(true);
_slave.reset();
}
_master.reset();
_cpu.reset();
_ppu.reset();
@ -625,6 +625,9 @@ void Console::RunSingleFrame()
while(_ppu->GetFrameCount() == lastFrameNumber) {
_cpu->Exec();
if(_slave) {
RunSlaveCpu();
}
}
EmulationSettings::DisableOverclocking(_disableOcNextFrame || NsfMapper::GetInstance());
@ -634,6 +637,20 @@ void Console::RunSingleFrame()
_apu->EndFrame();
}
void Console::RunSlaveCpu()
{
int32_t cycleGap;
while(true) {
//Run the slave until it catches up to the master CPU (and take into account the CPU count overflow that occurs every ~20mins)
cycleGap = _cpu->GetCycleCount() - _slave->_cpu->GetCycleCount();
if(cycleGap > 5 || cycleGap < -10000 || _ppu->GetFrameCount() > _slave->_ppu->GetFrameCount()) {
_slave->_cpu->Exec();
} else {
break;
}
}
}
void Console::Run()
{
Timer clockTimer;
@ -643,8 +660,6 @@ void Console::Run()
int timeLagDataIndex = 0;
double lastFrameMin = 9999;
double lastFrameMax = 0;
int32_t cycleGap = 0;
uint32_t currentFrameNumber = 0;
uint32_t lastFrameNumber = -1;
@ -668,21 +683,11 @@ void Console::Run()
while(true) {
_cpu->Exec();
currentFrameNumber = _ppu->GetFrameCount();
if(_slave) {
while(true) {
//Run the slave until it catches up to the master CPU (and take into account the CPU count overflow that occurs every ~20mins)
cycleGap = _cpu->GetCycleCount() - _slave->_cpu->GetCycleCount();
if(cycleGap > 5 || cycleGap < -10000 || currentFrameNumber > _slave->_ppu->GetFrameCount()) {
_slave->_cpu->Exec();
} else {
break;
}
}
RunSlaveCpu();
}
if(currentFrameNumber != lastFrameNumber) {
if(_ppu->GetFrameCount() != lastFrameNumber) {
_soundMixer->ProcessEndOfFrame();
if(_slave) {
_slave->_soundMixer->ProcessEndOfFrame();

View file

@ -133,6 +133,7 @@ public:
int32_t GetStopCode();
void RunSingleFrame();
void RunSlaveCpu();
bool UpdateHdPackMode();
shared_ptr<SystemActionManager> GetSystemActionManager();

View file

@ -4,10 +4,12 @@
#include "../Core/KeyManager.h"
#include "../Core/FdsSystemActionManager.h"
#include "../Core/VsSystemActionManager.h"
#include "../Core/Console.h"
class LibretroKeyManager : public IKeyManager
{
private:
shared_ptr<Console> _console;
retro_input_state_t _getInputState = nullptr;
retro_input_poll_t _pollInput = nullptr;
bool _mouseButtons[3] = { false, false, false };
@ -28,8 +30,9 @@ private:
}
public:
LibretroKeyManager()
LibretroKeyManager(shared_ptr<Console> console)
{
_console = console;
KeyManager::RegisterKeyManager(this);
}
@ -72,7 +75,7 @@ public:
_mouseButtons[(int)MouseButton::RightButton] = _getInputState(0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_RIGHT) != 0;
_mouseButtons[(int)MouseButton::MiddleButton] = _getInputState(0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_MIDDLE) != 0;
shared_ptr<FdsSystemActionManager> fdsSam = Console::GetInstance()->GetSystemActionManager<FdsSystemActionManager>();
shared_ptr<FdsSystemActionManager> fdsSam = _console->GetSystemActionManager<FdsSystemActionManager>();
if(fdsSam) {
if(ProcessAction(RETRO_DEVICE_ID_JOYPAD_L)) {
fdsSam->InsertNextDisk();
@ -83,7 +86,7 @@ public:
}
}
shared_ptr<VsSystemActionManager> vsSam = Console::GetInstance()->GetSystemActionManager<VsSystemActionManager>();
shared_ptr<VsSystemActionManager> vsSam = _console->GetSystemActionManager<VsSystemActionManager>();
if(vsSam) {
if(ProcessAction(RETRO_DEVICE_ID_JOYPAD_L2)) {
vsSam->InsertCoin(0);

View file

@ -10,6 +10,7 @@
class LibretroRenderer : public IRenderingDevice
{
private:
shared_ptr<Console> _console;
retro_video_refresh_t _sendFrame = nullptr;
retro_environment_t _retroEnv = nullptr;
bool _skipMode = false;
@ -17,14 +18,15 @@ private:
int32_t _previousWidth = -1;
public:
LibretroRenderer()
LibretroRenderer(shared_ptr<Console> console)
{
VideoRenderer::GetInstance()->RegisterRenderingDevice(this);
_console = console;
_console->GetVideoRenderer()->RegisterRenderingDevice(this);
}
~LibretroRenderer()
{
VideoRenderer::GetInstance()->UnregisterRenderingDevice(this);
_console->GetVideoRenderer()->UnregisterRenderingDevice(this);
}
// Inherited via IRenderingDevice
@ -50,10 +52,10 @@ public:
void GetSystemAudioVideoInfo(retro_system_av_info &info, int32_t maxWidth = 0, int32_t maxHeight = 0)
{
info.timing.fps = Console::GetModel() == NesModel::NTSC ? 60.098811862348404716732985230828 : 50.006977968268290848936010226333;
info.timing.fps = _console->GetModel() == NesModel::NTSC ? 60.098811862348404716732985230828 : 50.006977968268290848936010226333;
info.timing.sample_rate = 48000;
float ratio = (float)EmulationSettings::GetAspectRatio();
float ratio = (float)EmulationSettings::GetAspectRatio(_console);
if(ratio == 0.0f) {
ratio = 1.0f;
}

View file

@ -9,16 +9,18 @@ class LibretroSoundManager : public IAudioDevice
private:
retro_audio_sample_batch_t _sendAudioBuffer = nullptr;
bool _skipMode = false;
shared_ptr<Console> _console;
public:
LibretroSoundManager()
LibretroSoundManager(shared_ptr<Console> console)
{
SoundMixer::RegisterAudioDevice(this);
_console = console;
_console->GetSoundMixer()->RegisterAudioDevice(this);
}
~LibretroSoundManager()
{
SoundMixer::RegisterAudioDevice(nullptr);
_console->GetSoundMixer()->RegisterAudioDevice(nullptr);
}
// Inherited via IAudioDevice

View file

@ -21,12 +21,12 @@ SOURCES_C := $(SEVENZIP_DIR)/7zAlloc.c \
SOURCES_CXX := $(LIBRETRO_DIR)/libretro.cpp \
$(CORE_DIR)/APU.cpp \
$(CORE_DIR)/ApuLengthCounter.cpp \
$(CORE_DIR)/Assembler.cpp \
$(CORE_DIR)/AutomaticRomTest.cpp \
$(CORE_DIR)/AutoSaveManager.cpp \
$(CORE_DIR)/AviRecorder.cpp \
$(CORE_DIR)/BaseControlDevice.cpp \
$(CORE_DIR)/BaseExpansionAudio.cpp \
$(CORE_DIR)/BaseMapper.cpp \
$(CORE_DIR)/BaseRenderer.cpp \
$(CORE_DIR)/BaseVideoFilter.cpp \
@ -44,7 +44,7 @@ SOURCES_CXX := $(LIBRETRO_DIR)/libretro.cpp \
$(CORE_DIR)/Debugger.cpp \
$(CORE_DIR)/DebugHud.cpp \
$(CORE_DIR)/DefaultVideoFilter.cpp \
$(CORE_DIR)/RawVideoFilter.cpp \
$(CORE_DIR)/RawVideoFilter.cpp \
$(CORE_DIR)/DeltaModulationChannel.cpp \
$(CORE_DIR)/Disassembler.cpp \
$(CORE_DIR)/DisassemblyInfo.cpp \
@ -52,6 +52,7 @@ SOURCES_CXX := $(LIBRETRO_DIR)/libretro.cpp \
$(CORE_DIR)/ExpressionEvaluator.cpp \
$(CORE_DIR)/FceuxMovie.cpp \
$(CORE_DIR)/FDS.cpp \
$(CORE_DIR)/FdsLoader.cpp \
$(CORE_DIR)/GameClient.cpp \
$(CORE_DIR)/GameClientConnection.cpp \
$(CORE_DIR)/GameConnection.cpp \
@ -62,6 +63,7 @@ SOURCES_CXX := $(LIBRETRO_DIR)/libretro.cpp \
$(CORE_DIR)/HdNesPack.cpp \
$(CORE_DIR)/HdPackBuilder.cpp \
$(CORE_DIR)/HdPackLoader.cpp \
$(CORE_DIR)/HdPpu.cpp \
$(CORE_DIR)/HdVideoFilter.cpp \
$(CORE_DIR)/iNesLoader.cpp \
$(CORE_DIR)/KeyManager.cpp \
@ -74,11 +76,13 @@ SOURCES_CXX := $(LIBRETRO_DIR)/libretro.cpp \
$(CORE_DIR)/MessageManager.cpp \
$(CORE_DIR)/MovieManager.cpp \
$(CORE_DIR)/MovieRecorder.cpp \
$(CORE_DIR)/NotificationManager.cpp \
$(CORE_DIR)/NsfLoader.cpp \
$(CORE_DIR)/NsfMapper.cpp \
$(CORE_DIR)/NsfPpu.cpp \
$(CORE_DIR)/NtscFilter.cpp \
$(CORE_DIR)/OggMixer.cpp \
$(CORE_DIR)/OggReader.cpp \
$(CORE_DIR)/OpenBusHandler.cpp \
$(CORE_DIR)/PPU.cpp \
$(CORE_DIR)/Profiler.cpp \
$(CORE_DIR)/RecordedRomTest.cpp \

View file

@ -14,6 +14,7 @@
#include "../Core/CheatManager.h"
#include "../Core/HdData.h"
#include "../Core/DebuggerTypes.h"
#include "../Core/GameDatabase.h"
#include "../Utilities/FolderUtilities.h"
#include "../Utilities/HexUtilities.h"
@ -50,6 +51,7 @@ static vector<string> gameDb = {
#include "MesenDB.inc"
};
static std::shared_ptr<Console> _console;
static std::unique_ptr<LibretroRenderer> _renderer;
static std::unique_ptr<LibretroSoundManager> _soundManager;
static std::unique_ptr<LibretroKeyManager> _keyManager;
@ -110,9 +112,12 @@ extern "C" {
GameDatabase::LoadGameDb(gameDb);
_renderer.reset(new LibretroRenderer());
_soundManager.reset(new LibretroSoundManager());
_keyManager.reset(new LibretroKeyManager());
_console.reset(new Console());
_console->Init();
_renderer.reset(new LibretroRenderer(_console));
_soundManager.reset(new LibretroSoundManager(_console));
_keyManager.reset(new LibretroKeyManager(_console));
_messageManager.reset(new LibretroMessageManager(logCallback, retroEnv));
EmulationSettings::SetFlags(EmulationFlags::FdsAutoLoadDisk);
@ -124,14 +129,14 @@ extern "C" {
RETRO_API void retro_deinit()
{
Console::GetInstance()->SaveBatteries();
VideoDecoder::Release();
VideoRenderer::Release();
Console::Release();
_renderer.reset();
_soundManager.reset();
_keyManager.reset();
_messageManager.reset();
_console->SaveBatteries();
_console->Release(true);
_console.reset();
}
RETRO_API void retro_set_environment(retro_environment_t env)
@ -252,7 +257,7 @@ extern "C" {
RETRO_API void retro_reset()
{
Console::Reset(true);
_console->Reset(true);
}
void set_flag(const char* flagName, uint64_t flagValue)
@ -615,7 +620,7 @@ extern "C" {
_soundManager->SetSkipMode(true);
for(int i = 0; i < 9; i++) {
//Attempt to speed up to 1000% speed
Console::GetInstance()->RunSingleFrame();
_console->RunSingleFrame();
}
_renderer->SetSkipMode(false);
_soundManager->SetSkipMode(false);
@ -628,12 +633,12 @@ extern "C" {
bool hdPacksEnabled = EmulationSettings::CheckFlag(EmulationFlags::UseHdPacks);
if(hdPacksEnabled != _hdPacksEnabled) {
//Try to load/unload HD pack when the flag is toggled
Console::GetInstance()->UpdateHdPackMode();
_console->UpdateHdPackMode();
_hdPacksEnabled = hdPacksEnabled;
}
}
Console::GetInstance()->RunSingleFrame();
_console->RunSingleFrame();
if(updated) {
//Update geometry after running the frame, in case the console's region changed (affects "auto" aspect ratio)
@ -651,7 +656,7 @@ extern "C" {
RETRO_API bool retro_serialize(void *data, size_t size)
{
std::stringstream ss;
Console::SaveState(ss);
_console->SaveState(ss);
string saveStateData = ss.str();
memset(data, 0, size);
@ -662,13 +667,13 @@ extern "C" {
RETRO_API bool retro_unserialize(const void *data, size_t size)
{
Console::LoadState((uint8_t*)data, (uint32_t)size);
_console->LoadState((uint8_t*)data, (uint32_t)size);
return true;
}
RETRO_API void retro_cheat_reset()
{
CheatManager::GetInstance()->ClearCodes();
_console->GetCheatManager()->ClearCodes();
}
RETRO_API void retro_cheat_set(unsigned index, bool enabled, const char *codeStr)
@ -681,12 +686,12 @@ extern "C" {
if(code.size() == 7 && code[4] == ':') {
string address = code.substr(0, 4);
string value = code.substr(5, 2);
CheatManager::GetInstance()->AddCustomCode(HexUtilities::FromHex(address), HexUtilities::FromHex(value));
_console->GetCheatManager()->AddCustomCode(HexUtilities::FromHex(address), HexUtilities::FromHex(value));
} else if(code.size() == 10 && code[4] == '?' && code[7] == ':') {
string address = code.substr(0, 4);
string comparison = code.substr(5, 2);
string value = code.substr(8, 2);
CheatManager::GetInstance()->AddCustomCode(HexUtilities::FromHex(address), HexUtilities::FromHex(value), HexUtilities::FromHex(comparison));
_console->GetCheatManager()->AddCustomCode(HexUtilities::FromHex(address), HexUtilities::FromHex(value), HexUtilities::FromHex(comparison));
} else if(code.size() == 6 || code.size() == 8) {
//This is either a GG or PAR code
bool isValidGgCode = true;
@ -701,9 +706,9 @@ extern "C" {
}
if(isValidGgCode) {
CheatManager::GetInstance()->AddGameGenieCode(code);
_console->GetCheatManager()->AddGameGenieCode(code);
} else if(isValidParCode) {
CheatManager::GetInstance()->AddProActionRockyCode(HexUtilities::FromHex(code));
_console->GetCheatManager()->AddProActionRockyCode(HexUtilities::FromHex(code));
}
}
@ -830,7 +835,7 @@ extern "C" {
void update_core_controllers()
{
//Setup all "auto" ports
GameDatabase::InitializeInputDevices(Console::GetMapperInfo().Hash.PrgChrCrc32Hash);
GameDatabase::InitializeInputDevices(_console->GetMapperInfo().Hash.PrgChrCrc32Hash);
//TODO: Four Score
@ -895,14 +900,14 @@ extern "C" {
uint32_t i = 0;
uint32_t size = 0;
int32_t startAddr = 0;
uint8_t* internalRam = Console::GetInstance()->GetRamBuffer(DebugMemoryType::InternalRam, size, startAddr);
uint8_t* internalRam = _console->GetRamBuffer(DebugMemoryType::InternalRam, size, startAddr);
_descriptors[i].ptr = internalRam;
_descriptors[i].start = startAddr;
_descriptors[i].len = size;
_descriptors[i].select = 0;
i++;
uint8_t* saveRam = Console::GetInstance()->GetRamBuffer(DebugMemoryType::SaveRam, size, startAddr);
uint8_t* saveRam = _console->GetRamBuffer(DebugMemoryType::SaveRam, size, startAddr);
if(size > 0 && startAddr > 0) {
_descriptors[i].ptr = saveRam;
_descriptors[i].start = startAddr;
@ -911,7 +916,7 @@ extern "C" {
i++;
}
uint8_t* workRam = Console::GetInstance()->GetRamBuffer(DebugMemoryType::WorkRam, size, startAddr);
uint8_t* workRam = _console->GetRamBuffer(DebugMemoryType::WorkRam, size, startAddr);
if(size > 0 && startAddr > 0) {
_descriptors[i].ptr = workRam;
_descriptors[i].start = startAddr;
@ -967,7 +972,7 @@ extern "C" {
EmulationSettings::SetControllerType(1, ControllerType::StandardController);
EmulationSettings::SetControllerType(2, ControllerType::None);
EmulationSettings::SetControllerType(3, ControllerType::None);
bool result = Console::LoadROM(string(game->path));
bool result = _console->Initialize(game->path);
if(result) {
update_core_controllers();
@ -977,7 +982,7 @@ extern "C" {
//Retroarch doesn't like this for netplay or rewinding - it requires the states to always be the exact same size
//So we need to send a large enough size to Retroarch to ensure Mesen's state will always fit within that buffer.
std::stringstream ss;
Console::SaveState(ss);
_console->SaveState(ss);
//Round up to the next 1kb multiple
_saveStateSize = ((ss.str().size() * 2) + 0x400) & ~0x3FF;
@ -994,12 +999,12 @@ extern "C" {
RETRO_API void retro_unload_game()
{
Console::GetInstance()->Stop();
_console->Stop();
}
RETRO_API unsigned retro_get_region()
{
NesModel model = Console::GetModel();
NesModel model = _console->GetModel();
return model == NesModel::NTSC ? RETRO_REGION_NTSC : RETRO_REGION_PAL;
}
@ -1026,8 +1031,8 @@ extern "C" {
default: hscale = 1; break;
}
HdPackData* hdData = Console::GetHdData();
if(hdData != nullptr) {
shared_ptr<HdPackData> hdData = _console->GetHdData();
if(hdData) {
hscale = hdData->Scale;
vscale = hdData->Scale;
}
@ -1044,8 +1049,8 @@ extern "C" {
uint32_t size;
int32_t startAddr;
switch(id) {
case RETRO_MEMORY_SAVE_RAM: return Console::GetInstance()->GetRamBuffer(DebugMemoryType::SaveRam, size, startAddr);
case RETRO_MEMORY_SYSTEM_RAM: return Console::GetInstance()->GetRamBuffer(DebugMemoryType::InternalRam, size, startAddr);
case RETRO_MEMORY_SAVE_RAM: return _console->GetRamBuffer(DebugMemoryType::SaveRam, size, startAddr);
case RETRO_MEMORY_SYSTEM_RAM: return _console->GetRamBuffer(DebugMemoryType::InternalRam, size, startAddr);
}
return nullptr;
}
@ -1055,8 +1060,8 @@ extern "C" {
uint32_t size = 0;
int32_t startAddr;
switch(id) {
case RETRO_MEMORY_SAVE_RAM: Console::GetInstance()->GetRamBuffer(DebugMemoryType::SaveRam, size, startAddr); break;
case RETRO_MEMORY_SYSTEM_RAM: Console::GetInstance()->GetRamBuffer(DebugMemoryType::InternalRam, size, startAddr); break;
case RETRO_MEMORY_SAVE_RAM: _console->GetRamBuffer(DebugMemoryType::SaveRam, size, startAddr); break;
case RETRO_MEMORY_SYSTEM_RAM: _console->GetRamBuffer(DebugMemoryType::InternalRam, size, startAddr); break;
}
return size;
}