diff --git a/Source/Common/Common.vcxproj b/Source/Common/Common.vcxproj index 4ce014430..e8ba6cbe8 100644 --- a/Source/Common/Common.vcxproj +++ b/Source/Common/Common.vcxproj @@ -43,6 +43,7 @@ + Create @@ -64,6 +65,7 @@ + diff --git a/Source/Common/Common.vcxproj.filters b/Source/Common/Common.vcxproj.filters index 437d0328f..69caab164 100644 --- a/Source/Common/Common.vcxproj.filters +++ b/Source/Common/Common.vcxproj.filters @@ -62,6 +62,9 @@ Source Files + + Source Files + @@ -124,5 +127,8 @@ Header Files + + Header Files + \ No newline at end of file diff --git a/Source/Common/Random.cpp b/Source/Common/Random.cpp new file mode 100644 index 000000000..54bc07126 --- /dev/null +++ b/Source/Common/Random.cpp @@ -0,0 +1,54 @@ +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2017 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +/* + * Implements the CRandom class. + * + * This class implements the Lehmer Random Number Generator. + * + */ + +#include "stdafx.h" +#include "Random.h" +#include + +CRandom::CRandom() +{ + m_state = (uint32_t)time(NULL); +} + +CRandom::CRandom(uint32_t state_value) +{ + m_state = state_value; +} + +uint32_t CRandom::randomizer(uint32_t val) +{ + return ((uint64_t)val * 279470273UL) % 4294967291UL; +} + +uint32_t CRandom::next() +{ + m_state = randomizer(m_state); + return m_state; +} + +void CRandom::set_state(uint32_t state_value) +{ + if (state_value == 0) + m_state = 1; + else + m_state = state_value; +} + +uint32_t CRandom::get_state() +{ + return m_state; +} diff --git a/Source/Common/Random.h b/Source/Common/Random.h new file mode 100644 index 000000000..aeb33536a --- /dev/null +++ b/Source/Common/Random.h @@ -0,0 +1,32 @@ +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2017 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +/* + * Defines the CRandom class. + * + * This class implements the Lehmer Random Number Generator. + * + */ +#pragma once +#include + +class CRandom +{ +public: + CRandom(); + CRandom(uint32_t seed_value); + uint32_t next(); + uint32_t get_state(); + void set_state(uint32_t state_value); + +protected: + uint32_t randomizer(uint32_t val); + uint32_t m_state; +}; diff --git a/Source/Project64-core/N64System/Mips/Dma.cpp b/Source/Project64-core/N64System/Mips/Dma.cpp index abfa03ab3..b5eb0ad54 100644 --- a/Source/Project64-core/N64System/Mips/Dma.cpp +++ b/Source/Project64-core/N64System/Mips/Dma.cpp @@ -458,9 +458,11 @@ void CDMA::PI_DMA_WRITE() { g_Recompiler->ClearRecompCode_Phys(g_Reg->PI_DRAM_ADDR_REG, g_Reg->PI_WR_LEN_REG, CRecompiler::Remove_DMA); } - g_Reg->PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY; - g_Reg->MI_INTR_REG |= MI_INTR_PI; - g_Reg->CheckInterrupts(); + g_SystemTimer->SetTimer(g_SystemTimer->PiTimer, PI_WR_LEN_REG/8 + (g_Random->next() % 0x40), false); + + //g_Reg->PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY; + //g_Reg->MI_INTR_REG |= MI_INTR_PI; + //g_Reg->CheckInterrupts(); //ChangeTimer(PiTimer,(int32_t)(PI_WR_LEN_REG * 8.9) + 50); //ChangeTimer(PiTimer,(int32_t)(PI_WR_LEN_REG * 8.9)); return; diff --git a/Source/Project64-core/N64System/Mips/PifRam.cpp b/Source/Project64-core/N64System/Mips/PifRam.cpp index 8b4ba49d7..9583070f4 100644 --- a/Source/Project64-core/N64System/Mips/PifRam.cpp +++ b/Source/Project64-core/N64System/Mips/PifRam.cpp @@ -358,13 +358,14 @@ void CPifRam::SI_DMA_READ() if (g_System->bDelaySI()) { - g_SystemTimer->SetTimer(CSystemTimer::SiTimer, 0x900, false); + g_SystemTimer->SetTimer(CSystemTimer::SiTimer, 0x900 + (g_Random->next() % 0x40), false); } else { - g_Reg->MI_INTR_REG |= MI_INTR_SI; - g_Reg->SI_STATUS_REG |= SI_STATUS_INTERRUPT; - g_Reg->CheckInterrupts(); + g_SystemTimer->SetTimer(CSystemTimer::SiTimer, g_Random->next() % 0x40, false); + //g_Reg->MI_INTR_REG |= MI_INTR_SI; + //g_Reg->SI_STATUS_REG |= SI_STATUS_INTERRUPT; + //g_Reg->CheckInterrupts(); } } diff --git a/Source/Project64-core/N64System/N64Class.cpp b/Source/Project64-core/N64System/N64Class.cpp index 2f56f5221..d3190edfc 100644 --- a/Source/Project64-core/N64System/N64Class.cpp +++ b/Source/Project64-core/N64System/N64Class.cpp @@ -30,7 +30,7 @@ #pragma warning(disable:4355) // Disable 'this' : used in base member initializer list -CN64System::CN64System(CPlugins * Plugins, bool SavesReadOnly, bool SyncSystem) : +CN64System::CN64System(CPlugins * Plugins, uint32_t randomizer_seed, bool SavesReadOnly, bool SyncSystem) : CSystemEvents(this, Plugins), m_EndEmulation(false), m_SaveUsing((SAVE_CHIP_TYPE)g_Settings->LoadDword(Game_SaveChip)), @@ -57,7 +57,8 @@ CN64System::CN64System(CPlugins * Plugins, bool SavesReadOnly, bool SyncSystem) m_thread(NULL), m_hPauseEvent(true), m_CheatsSlectionChanged(false), - m_SyncCpu(SyncSystem) + m_SyncCpu(SyncSystem), + m_Random(randomizer_seed) { WriteTrace(TraceN64System, TraceDebug, "Start"); memset(m_LastSuccessSyncPC, 0, sizeof(m_LastSuccessSyncPC)); @@ -110,7 +111,7 @@ CN64System::CN64System(CPlugins * Plugins, bool SavesReadOnly, bool SyncSystem) g_Plugins->CopyPlugins(g_Settings->LoadStringVal(Directory_PluginSync)); m_SyncPlugins = new CPlugins(Directory_PluginSync, true); m_SyncPlugins->SetRenderWindows(g_Plugins->SyncWindow(), NULL); - m_SyncCPU = new CN64System(m_SyncPlugins, true, true); + m_SyncCPU = new CN64System(m_SyncPlugins, randomizer_seed, true, true); } Reset(true, true); @@ -359,7 +360,7 @@ bool CN64System::RunFileImage(const char * FileLoc) void CN64System::RunLoadedImage(void) { WriteTrace(TraceN64System, TraceDebug, "Start"); - g_BaseSystem = new CN64System(g_Plugins, false, false); + g_BaseSystem = new CN64System(g_Plugins, (uint32_t)time(NULL), false, false); if (g_BaseSystem) { g_BaseSystem->StartEmulation(true); @@ -716,6 +717,7 @@ void CN64System::Reset(bool bInitReg, bool ClearMenory) m_SyncCPU->Reset(bInitReg, ClearMenory); } g_Settings->SaveBool(GameRunning_InReset, true); + WriteTrace(TraceN64System, TraceDebug, "Done"); } @@ -763,6 +765,7 @@ bool CN64System::SetActiveSystem(bool bActive) R4300iOp::m_TestTimer = m_TestTimer; R4300iOp::m_NextInstruction = m_NextInstruction; R4300iOp::m_JumpToLocation = m_JumpToLocation; + g_Random = &m_Random; } else { @@ -782,6 +785,7 @@ bool CN64System::SetActiveSystem(bool bActive) g_Plugins = m_Plugins; g_TLBLoadAddress = NULL; g_TLBStoreAddress = NULL; + g_Random = NULL; } } diff --git a/Source/Project64-core/N64System/N64Class.h b/Source/Project64-core/N64System/N64Class.h index 63d04d1b7..909cc0732 100644 --- a/Source/Project64-core/N64System/N64Class.h +++ b/Source/Project64-core/N64System/N64Class.h @@ -10,6 +10,7 @@ ****************************************************************************/ #pragma once +#include #include #include #include @@ -48,7 +49,7 @@ class CN64System : protected CDebugSettings { public: - CN64System(CPlugins * Plugins, bool SavesReadOnly, bool SyncSystem); + CN64System(CPlugins * Plugins, uint32_t randomizer_seed, bool SavesReadOnly, bool SyncSystem); virtual ~CN64System(void); CCheats m_Cheats; @@ -164,6 +165,7 @@ private: uint32_t m_SyncCount; bool m_SyncCpu; bool m_CheatsSlectionChanged; + CRandom m_Random; //When Syncing cores this is the PC where it last Sync'ed correctly uint32_t m_LastSuccessSyncPC[10]; diff --git a/Source/Project64-core/N64System/SystemGlobals.cpp b/Source/Project64-core/N64System/SystemGlobals.cpp index d6e058b1c..84552337b 100644 --- a/Source/Project64-core/N64System/SystemGlobals.cpp +++ b/Source/Project64-core/N64System/SystemGlobals.cpp @@ -32,5 +32,6 @@ uint32_t * g_TLBStoreAddress = NULL; CDebugger * g_Debugger = NULL; uint8_t ** g_RecompPos = NULL; CMempak * g_Mempak = NULL; +CRandom * g_Random = NULL; int * g_NextTimer; \ No newline at end of file diff --git a/Source/Project64-core/N64System/SystemGlobals.h b/Source/Project64-core/N64System/SystemGlobals.h index 3ebbff683..b1bfd0521 100644 --- a/Source/Project64-core/N64System/SystemGlobals.h +++ b/Source/Project64-core/N64System/SystemGlobals.h @@ -62,4 +62,7 @@ extern CDebugger * g_Debugger; extern uint8_t ** g_RecompPos; class CMempak; -extern CMempak * g_Mempak; \ No newline at end of file +extern CMempak * g_Mempak; + +class CRandom; +extern CRandom * g_Random;