Core: Add callback when game resets/loads state
This commit is contained in:
parent
d33725bda5
commit
d7e732a7eb
|
@ -1,5 +1,6 @@
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "VideoInterfaceHandler.h"
|
#include "VideoInterfaceHandler.h"
|
||||||
|
#include <Project64-core\N64System\N64System.h>
|
||||||
#include <Project64-core\N64System\Mips\MemoryVirtualMem.h>
|
#include <Project64-core\N64System\Mips\MemoryVirtualMem.h>
|
||||||
#include <Project64-core\N64System\Mips\SystemTiming.h>
|
#include <Project64-core\N64System\Mips\SystemTiming.h>
|
||||||
#include <Project64-core\N64System\Mips\Register.h>
|
#include <Project64-core\N64System\Mips\Register.h>
|
||||||
|
@ -33,18 +34,27 @@ VideoInterfaceReg::VideoInterfaceReg(uint32_t * VideoInterface) :
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
VideoInterfaceHandler::VideoInterfaceHandler(CMipsMemoryVM & MMU, CPlugins * Plugins, CRegisters & Reg, CSystemTimer & SystemTimer, int32_t & NextTimer) :
|
VideoInterfaceHandler::VideoInterfaceHandler(CN64System & System, CMipsMemoryVM & MMU, CRegisters & Reg) :
|
||||||
VideoInterfaceReg(Reg.m_Video_Interface),
|
VideoInterfaceReg(Reg.m_Video_Interface),
|
||||||
|
m_System(System),
|
||||||
m_MMU(MMU),
|
m_MMU(MMU),
|
||||||
m_Plugins(Plugins),
|
m_Plugins(System.GetPlugins()),
|
||||||
m_Reg(Reg),
|
m_Reg(Reg),
|
||||||
m_SystemTimer(SystemTimer),
|
m_SystemTimer(System.m_SystemTimer),
|
||||||
m_NextTimer(NextTimer),
|
m_NextTimer(System.m_NextTimer),
|
||||||
m_PC(Reg.m_PROGRAM_COUNTER),
|
m_PC(Reg.m_PROGRAM_COUNTER),
|
||||||
m_FieldSerration(0),
|
m_FieldSerration(0),
|
||||||
m_HalfLine(0),
|
m_HalfLine(0),
|
||||||
m_HalfLineCheck(false)
|
m_HalfLineCheck(false)
|
||||||
{
|
{
|
||||||
|
System.RegisterCallBack(CN64SystemCB_Reset, this, (CN64System::CallBackFunction)stSystemReset);
|
||||||
|
System.RegisterCallBack(CN64SystemCB_LoadedGameState, this, (CN64System::CallBackFunction)stLoadedGameState);
|
||||||
|
}
|
||||||
|
|
||||||
|
VideoInterfaceHandler::~VideoInterfaceHandler()
|
||||||
|
{
|
||||||
|
m_System.UnregisterCallBack(CN64SystemCB_Reset, this, (CN64System::CallBackFunction)stSystemReset);
|
||||||
|
m_System.UnregisterCallBack(CN64SystemCB_LoadedGameState, this, (CN64System::CallBackFunction)stLoadedGameState);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VideoInterfaceHandler::Read32(uint32_t Address, uint32_t & Value)
|
bool VideoInterfaceHandler::Read32(uint32_t Address, uint32_t & Value)
|
||||||
|
@ -213,4 +223,18 @@ void VideoInterfaceHandler::UpdateHalfLine()
|
||||||
m_HalfLine |= m_FieldSerration;
|
m_HalfLine |= m_FieldSerration;
|
||||||
VI_V_CURRENT_LINE_REG = m_HalfLine;
|
VI_V_CURRENT_LINE_REG = m_HalfLine;
|
||||||
m_HalfLineCheck = NextViTimer;
|
m_HalfLineCheck = NextViTimer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VideoInterfaceHandler::LoadedGameState(void)
|
||||||
|
{
|
||||||
|
SystemReset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VideoInterfaceHandler::SystemReset(void)
|
||||||
|
{
|
||||||
|
m_FieldSerration = 0;
|
||||||
|
m_HalfLine = 0;
|
||||||
|
m_HalfLineCheck = false;
|
||||||
|
UpdateFieldSerration((VI_STATUS_REG & 0x40) != 0);
|
||||||
|
UpdateHalfLine();
|
||||||
|
}
|
||||||
|
|
|
@ -45,6 +45,7 @@ class CMipsMemoryVM;
|
||||||
class CPlugins;
|
class CPlugins;
|
||||||
class CRegisters;
|
class CRegisters;
|
||||||
class CSystemTimer;
|
class CSystemTimer;
|
||||||
|
class CN64System;
|
||||||
|
|
||||||
class VideoInterfaceHandler :
|
class VideoInterfaceHandler :
|
||||||
public MemoryHandler,
|
public MemoryHandler,
|
||||||
|
@ -54,7 +55,8 @@ class VideoInterfaceHandler :
|
||||||
private CLogging
|
private CLogging
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
VideoInterfaceHandler(CMipsMemoryVM & MMU, CPlugins * Plugins, CRegisters & Reg, CSystemTimer & SystemTimer, int32_t & NextTimer);
|
VideoInterfaceHandler(CN64System & System, CMipsMemoryVM & MMU, CRegisters & Reg);
|
||||||
|
~VideoInterfaceHandler();
|
||||||
|
|
||||||
void UpdateFieldSerration(uint32_t interlaced);
|
void UpdateFieldSerration(uint32_t interlaced);
|
||||||
bool Read32(uint32_t Address, uint32_t & Value);
|
bool Read32(uint32_t Address, uint32_t & Value);
|
||||||
|
@ -65,8 +67,14 @@ private:
|
||||||
VideoInterfaceHandler(const VideoInterfaceHandler &);
|
VideoInterfaceHandler(const VideoInterfaceHandler &);
|
||||||
VideoInterfaceHandler & operator=(const VideoInterfaceHandler &);
|
VideoInterfaceHandler & operator=(const VideoInterfaceHandler &);
|
||||||
|
|
||||||
void UpdateHalfLine();
|
static void stSystemReset(VideoInterfaceHandler * _this) { _this->SystemReset(); }
|
||||||
|
static void stLoadedGameState(VideoInterfaceHandler * _this) { _this->LoadedGameState(); }
|
||||||
|
|
||||||
|
void UpdateHalfLine();
|
||||||
|
void LoadedGameState(void);
|
||||||
|
void SystemReset(void);
|
||||||
|
|
||||||
|
CN64System & m_System;
|
||||||
uint32_t m_FieldSerration;
|
uint32_t m_FieldSerration;
|
||||||
uint32_t m_HalfLine;
|
uint32_t m_HalfLine;
|
||||||
uint32_t m_HalfLineCheck;
|
uint32_t m_HalfLineCheck;
|
||||||
|
|
|
@ -34,7 +34,7 @@ CMipsMemoryVM::CMipsMemoryVM(CN64System & System, CRegisters & Reg, bool SavesRe
|
||||||
m_PeripheralInterfaceHandler(*this, Reg),
|
m_PeripheralInterfaceHandler(*this, Reg),
|
||||||
m_RDRAMInterfaceHandler(Reg),
|
m_RDRAMInterfaceHandler(Reg),
|
||||||
m_SPRegistersHandler(System, *this, Reg),
|
m_SPRegistersHandler(System, *this, Reg),
|
||||||
m_VideoInterfaceHandler(*this, System.GetPlugins(), Reg, System.m_SystemTimer, System.m_NextTimer),
|
m_VideoInterfaceHandler(System, *this, Reg),
|
||||||
m_Rom(nullptr),
|
m_Rom(nullptr),
|
||||||
m_RomSize(0),
|
m_RomSize(0),
|
||||||
m_RomWrittenTo(false),
|
m_RomWrittenTo(false),
|
||||||
|
|
|
@ -152,6 +152,56 @@ CN64System::~CN64System()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CN64System::RegisterCallBack(CN64SystemCB Type, void * Data, CallBackFunction Func)
|
||||||
|
{
|
||||||
|
SETTING_CHANGED_CB Item;
|
||||||
|
Item.Data = Data;
|
||||||
|
Item.Func = Func;
|
||||||
|
|
||||||
|
SETTING_CALLBACK::iterator Callback = m_Callback.find(Type);
|
||||||
|
if (Callback != m_Callback.end())
|
||||||
|
{
|
||||||
|
SETTING_CHANGED_CB_LIST & List = Callback->second;
|
||||||
|
bool found = false;
|
||||||
|
for (SETTING_CHANGED_CB_LIST::const_iterator itr = List.begin(); itr != List.end(); itr++)
|
||||||
|
{
|
||||||
|
if (itr->Data == Data && itr->Func == Func)
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found)
|
||||||
|
{
|
||||||
|
Callback->second.push_back(Item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SETTING_CHANGED_CB_LIST List;
|
||||||
|
List.push_back(Item);
|
||||||
|
m_Callback.insert(SETTING_CALLBACK::value_type(Type, List));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CN64System::UnregisterCallBack(CN64SystemCB Type, void * Data, CallBackFunction Func)
|
||||||
|
{
|
||||||
|
SETTING_CALLBACK::iterator Callback = m_Callback.find(Type);
|
||||||
|
if (Callback != m_Callback.end())
|
||||||
|
{
|
||||||
|
SETTING_CHANGED_CB_LIST & List = Callback->second;
|
||||||
|
bool found = false;
|
||||||
|
for (SETTING_CHANGED_CB_LIST::const_iterator itr = List.begin(); itr != List.end(); itr++)
|
||||||
|
{
|
||||||
|
if (itr->Data == Data && itr->Func == Func)
|
||||||
|
{
|
||||||
|
List.erase(itr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CN64System::ExternalEvent(SystemEvent action)
|
void CN64System::ExternalEvent(SystemEvent action)
|
||||||
{
|
{
|
||||||
WriteTrace(TraceN64System, TraceDebug, "Action: %s", SystemEventName(action));
|
WriteTrace(TraceN64System, TraceDebug, "Action: %s", SystemEventName(action));
|
||||||
|
@ -898,6 +948,7 @@ void CN64System::Reset(bool bInitReg, bool ClearMenory)
|
||||||
{
|
{
|
||||||
m_SyncCPU->Reset(bInitReg, ClearMenory);
|
m_SyncCPU->Reset(bInitReg, ClearMenory);
|
||||||
}
|
}
|
||||||
|
NotifyCallback(CN64SystemCB_Reset);
|
||||||
g_Settings->SaveBool(GameRunning_InReset, false);
|
g_Settings->SaveBool(GameRunning_InReset, false);
|
||||||
|
|
||||||
WriteTrace(TraceN64System, TraceDebug, "Done");
|
WriteTrace(TraceN64System, TraceDebug, "Done");
|
||||||
|
@ -1184,6 +1235,7 @@ void CN64System::ExecuteCPU()
|
||||||
g_Notify->DisplayMessage(2, MSG_EMULATION_STARTED);
|
g_Notify->DisplayMessage(2, MSG_EMULATION_STARTED);
|
||||||
|
|
||||||
m_EndEmulation = false;
|
m_EndEmulation = false;
|
||||||
|
NotifyCallback(CN64SystemCB_LoadedGameState);
|
||||||
|
|
||||||
m_Plugins->RomOpened();
|
m_Plugins->RomOpened();
|
||||||
if (m_SyncCPU)
|
if (m_SyncCPU)
|
||||||
|
@ -2253,6 +2305,7 @@ bool CN64System::LoadState(const char * FileName)
|
||||||
SyncCPU(m_SyncCPU);
|
SyncCPU(m_SyncCPU);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
NotifyCallback(CN64SystemCB_LoadedGameState);
|
||||||
std::string LoadMsg = g_Lang->GetString(MSG_LOADED_STATE);
|
std::string LoadMsg = g_Lang->GetString(MSG_LOADED_STATE);
|
||||||
g_Notify->DisplayMessage(3, stdstr_f("%s %s", LoadMsg.c_str(), stdstr(SaveFile.GetNameExtension()).c_str()).c_str());
|
g_Notify->DisplayMessage(3, stdstr_f("%s %s", LoadMsg.c_str(), stdstr(SaveFile.GetNameExtension()).c_str()).c_str());
|
||||||
WriteTrace(TraceN64System, TraceDebug, "Done");
|
WriteTrace(TraceN64System, TraceDebug, "Done");
|
||||||
|
@ -2277,6 +2330,19 @@ void CN64System::DisplayRSPListCount()
|
||||||
g_Notify->DisplayMessage(0, stdstr_f("Dlist: %d Alist: %d Unknown: %d", m_DlistCount, m_AlistCount, m_UnknownCount).c_str());
|
g_Notify->DisplayMessage(0, stdstr_f("Dlist: %d Alist: %d Unknown: %d", m_DlistCount, m_AlistCount, m_UnknownCount).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CN64System::NotifyCallback(CN64SystemCB Type)
|
||||||
|
{
|
||||||
|
SETTING_CALLBACK::iterator Callback = m_Callback.find(Type);
|
||||||
|
if (Callback != m_Callback.end())
|
||||||
|
{
|
||||||
|
SETTING_CHANGED_CB_LIST & List = Callback->second;
|
||||||
|
for (SETTING_CHANGED_CB_LIST::const_iterator itr = List.begin(); itr != List.end(); itr++)
|
||||||
|
{
|
||||||
|
itr->Func(itr->Data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CN64System::RunRSP()
|
void CN64System::RunRSP()
|
||||||
{
|
{
|
||||||
WriteTrace(TraceRSP, TraceDebug, "Start (SP Status %X)", m_Reg.SP_STATUS_REG);
|
WriteTrace(TraceRSP, TraceDebug, "Start (SP Status %X)", m_Reg.SP_STATUS_REG);
|
||||||
|
|
|
@ -27,7 +27,14 @@ class CPlugins;
|
||||||
class CRSP_Plugin;
|
class CRSP_Plugin;
|
||||||
class CRecompiler;
|
class CRecompiler;
|
||||||
|
|
||||||
|
class VideoInterfaceHandler;
|
||||||
|
|
||||||
//#define TEST_SP_TRACKING // Track the SP to make sure all ops pick it up fine
|
//#define TEST_SP_TRACKING // Track the SP to make sure all ops pick it up fine
|
||||||
|
enum CN64SystemCB
|
||||||
|
{
|
||||||
|
CN64SystemCB_Reset,
|
||||||
|
CN64SystemCB_LoadedGameState,
|
||||||
|
};
|
||||||
|
|
||||||
class CN64System :
|
class CN64System :
|
||||||
public CLogging,
|
public CLogging,
|
||||||
|
@ -38,6 +45,8 @@ class CN64System :
|
||||||
protected CDebugSettings
|
protected CDebugSettings
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
typedef void(*CallBackFunction)(void *);
|
||||||
|
|
||||||
CN64System(CPlugins * Plugins, uint32_t randomizer_seed, bool SavesReadOnly, bool SyncSystem);
|
CN64System(CPlugins * Plugins, uint32_t randomizer_seed, bool SavesReadOnly, bool SyncSystem);
|
||||||
virtual ~CN64System(void);
|
virtual ~CN64System(void);
|
||||||
|
|
||||||
|
@ -55,6 +64,9 @@ public:
|
||||||
static void RunLoadedImage(void);
|
static void RunLoadedImage(void);
|
||||||
static void CloseSystem(void);
|
static void CloseSystem(void);
|
||||||
|
|
||||||
|
void RegisterCallBack(CN64SystemCB Type, void * Data, CallBackFunction Func);
|
||||||
|
void UnregisterCallBack(CN64SystemCB Type, void * Data, CallBackFunction Func);
|
||||||
|
|
||||||
void CloseCpu();
|
void CloseCpu();
|
||||||
void ExternalEvent(SystemEvent action); // Covers GUI interactions and timers etc.
|
void ExternalEvent(SystemEvent action); // Covers GUI interactions and timers etc.
|
||||||
void StartEmulation(bool NewThread);
|
void StartEmulation(bool NewThread);
|
||||||
|
@ -93,6 +105,14 @@ public:
|
||||||
uint32_t JumpToLocation() const { return m_JumpToLocation; }
|
uint32_t JumpToLocation() const { return m_JumpToLocation; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
struct SETTING_CHANGED_CB
|
||||||
|
{
|
||||||
|
void * Data;
|
||||||
|
CallBackFunction Func;
|
||||||
|
};
|
||||||
|
typedef std::vector<SETTING_CHANGED_CB> SETTING_CHANGED_CB_LIST;
|
||||||
|
typedef std::map<CN64SystemCB, SETTING_CHANGED_CB_LIST> SETTING_CALLBACK;
|
||||||
|
|
||||||
// Make sure plugins can directly access this information
|
// Make sure plugins can directly access this information
|
||||||
friend class CGfxPlugin;
|
friend class CGfxPlugin;
|
||||||
friend class CAudioPlugin;
|
friend class CAudioPlugin;
|
||||||
|
@ -108,6 +128,8 @@ private:
|
||||||
friend class R4300iOp32;
|
friend class R4300iOp32;
|
||||||
friend class R4300iOp;
|
friend class R4300iOp;
|
||||||
|
|
||||||
|
friend class VideoInterfaceHandler;
|
||||||
|
|
||||||
// Used for loading and potentially executing the CPU in its own thread
|
// Used for loading and potentially executing the CPU in its own thread
|
||||||
static void StartEmulationThread(CThread * thread);
|
static void StartEmulationThread(CThread * thread);
|
||||||
static bool EmulationStarting(CThread * thread);
|
static bool EmulationStarting(CThread * thread);
|
||||||
|
@ -120,6 +142,7 @@ private:
|
||||||
bool SetActiveSystem(bool bActive = true);
|
bool SetActiveSystem(bool bActive = true);
|
||||||
void InitRegisters(bool bPostPif, CMipsMemoryVM & MMU);
|
void InitRegisters(bool bPostPif, CMipsMemoryVM & MMU);
|
||||||
void DisplayRSPListCount();
|
void DisplayRSPListCount();
|
||||||
|
void NotifyCallback(CN64SystemCB Type);
|
||||||
|
|
||||||
// CPU methods
|
// CPU methods
|
||||||
void ExecuteRecompiler();
|
void ExecuteRecompiler();
|
||||||
|
@ -134,6 +157,7 @@ private:
|
||||||
void TLB_Unmaped(uint32_t VAddr, uint32_t Len);
|
void TLB_Unmaped(uint32_t VAddr, uint32_t Len);
|
||||||
void TLB_Changed();
|
void TLB_Changed();
|
||||||
|
|
||||||
|
SETTING_CALLBACK m_Callback;
|
||||||
CPlugins * const m_Plugins; // The plugin container
|
CPlugins * const m_Plugins; // The plugin container
|
||||||
CPlugins * m_SyncPlugins;
|
CPlugins * m_SyncPlugins;
|
||||||
CN64System * m_SyncCPU;
|
CN64System * m_SyncCPU;
|
||||||
|
|
Loading…
Reference in New Issue