From 79692a6c78879f9b199fca7bb0585a167b5f4cf6 Mon Sep 17 00:00:00 2001 From: rog Date: Thu, 18 Oct 2012 04:18:40 -0400 Subject: [PATCH] save settings necessary for syncing a movie to the .dtm, and load them upon playback --- Source/Core/Core/Src/BootManager.cpp | 15 ++ Source/Core/Core/Src/Core.cpp | 2 +- Source/Core/Core/Src/HW/CPU.cpp | 5 + .../Core/Core/Src/HW/EXI_DeviceMemoryCard.cpp | 3 + Source/Core/Core/Src/Movie.cpp | 138 +++++++++++++++++- Source/Core/Core/Src/Movie.h | 31 +++- 6 files changed, 189 insertions(+), 5 deletions(-) diff --git a/Source/Core/Core/Src/BootManager.cpp b/Source/Core/Core/Src/BootManager.cpp index 120355f029..709053a5e2 100644 --- a/Source/Core/Core/Src/BootManager.cpp +++ b/Source/Core/Core/Src/BootManager.cpp @@ -45,6 +45,7 @@ #include "Core.h" #include "Host.h" #include "VideoBackendBase.h" +#include "Movie.h" namespace BootManager @@ -115,6 +116,20 @@ bool BootCore(const std::string& _rFilename) game_ini.Get("Core", "GFXBackend", &StartUp.m_strVideoBackend, StartUp.m_strVideoBackend.c_str()); VideoBackend::ActivateBackend(StartUp.m_strVideoBackend); + if (Movie::IsPlayingInput() && Movie::IsConfigSaved()) + { + Movie::Init(); + StartUp.bCPUThread = Movie::IsDualCore(); + StartUp.bSkipIdle = Movie::IsSkipIdle(); + StartUp.bDSPHLE = Movie::IsDSPHLE(); + StartUp.bProgressive = Movie::IsProgressive(); + StartUp.bFastDiscSpeed = Movie::IsFastDiscSpeed(); + if (Movie::g_bMemcard && Movie::g_bBlankMC) + { + if (File::Exists("Movie.raw")) + File::Delete("Movie.raw"); + } + } // Wii settings if (StartUp.bWii) { diff --git a/Source/Core/Core/Src/Core.cpp b/Source/Core/Core/Src/Core.cpp index ec3d0e8f70..da9b5795fa 100644 --- a/Source/Core/Core/Src/Core.cpp +++ b/Source/Core/Core/Src/Core.cpp @@ -434,7 +434,7 @@ void EmuThread() CBoot::BootUp(); // Setup our core, but can't use dynarec if we are compare server - if (_CoreParameter.iCPUCore && (!_CoreParameter.bRunCompareServer || + if (Movie::g_CPUCore && (!_CoreParameter.bRunCompareServer || _CoreParameter.bRunCompareClient)) PowerPC::SetMode(PowerPC::MODE_JIT); else diff --git a/Source/Core/Core/Src/HW/CPU.cpp b/Source/Core/Core/Src/HW/CPU.cpp index f760abcec6..a7a272e263 100644 --- a/Source/Core/Core/Src/HW/CPU.cpp +++ b/Source/Core/Core/Src/HW/CPU.cpp @@ -24,6 +24,7 @@ #include "../Core.h" #include "CPU.h" #include "DSP.h" +#include "Movie.h" #include "VideoBackendBase.h" @@ -36,6 +37,10 @@ namespace void CCPU::Init(int cpu_core) { + if (Movie::IsPlayingInput() && Movie::IsConfigSaved()) + { + cpu_core = Movie::GetCPUMode(); + } PowerPC::Init(cpu_core); m_SyncEvent = 0; } diff --git a/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.cpp b/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.cpp index 6f4bc502b6..106e41b16c 100644 --- a/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.cpp +++ b/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.cpp @@ -52,6 +52,9 @@ CEXIMemoryCard::CEXIMemoryCard(const int index) , m_bDirty(false) { m_strFilename = (card_index == 0) ? SConfig::GetInstance().m_strMemoryCardA : SConfig::GetInstance().m_strMemoryCardB; + if (Movie::g_bMemcard && Movie::IsPlayingInput() && Movie::IsConfigSaved() && Movie::g_bBlankMC) + m_strFilename = "Movie.raw"; + // we're potentially leaking events here, since there's no UnregisterEvent until emu shutdown, but I guess it's inconsequential et_this_card = CoreTiming::RegisterEvent((card_index == 0) ? "memcardA" : "memcardB", FlushCallback); diff --git a/Source/Core/Core/Src/Movie.cpp b/Source/Core/Core/Src/Movie.cpp index 79c1cfd023..94edd9dedf 100644 --- a/Source/Core/Core/Src/Movie.cpp +++ b/Source/Core/Core/Src/Movie.cpp @@ -30,6 +30,10 @@ #include "VideoBackendBase.h" #include "State.h" #include "Timer.h" +#include "VideoConfig.h" +#include "HW/EXI.h" +#include "HW/EXI_Device.h" +#include "HW/EXI_Channel.h" // large enough for just over 24 hours of single-player recording #define MAX_DTM_LENGTH (40 * 1024 * 1024) @@ -55,6 +59,16 @@ u64 g_currentFrame = 0, g_totalFrames = 0; // VI u64 g_currentLagCount = 0, g_totalLagCount = 0; // just stats u64 g_currentInputCount = 0, g_totalInputCount = 0; // just stats u64 g_recordingStartTime; // seconds since 1970 that recording started +bool g_bSaveConfig = false; +bool g_bSkipIdle = false; +bool g_bDualCore = false; +bool g_bProgressive = false; +bool g_bDSPHLE = false; +bool g_bFastDiscSpeed = false; +std::string g_videoBackend = "opengl"; +int g_CPUCore = 1; +bool g_bMemcard; +bool g_bBlankMC = false; bool g_bRecordingFromSaveState = false; bool g_bPolled = false; @@ -112,6 +126,30 @@ void Init() g_bPolled = false; g_bFrameStep = false; g_bFrameStop = false; + g_bSaveConfig = false; + g_CPUCore = SConfig::GetInstance().m_LocalCoreStartupParameter.iCPUCore; + g_bMemcard = SConfig::GetInstance().m_EXIDevice[0] == EXIDEVICE_MEMORYCARD; + if (IsRecordingInput() || (!tmpHeader.bSaveConfig && IsPlayingInput())) + { + g_bSkipIdle = SConfig::GetInstance().m_LocalCoreStartupParameter.bSkipIdle; + g_bDualCore = SConfig::GetInstance().m_LocalCoreStartupParameter.bCPUThread; + g_bProgressive = SConfig::GetInstance().m_LocalCoreStartupParameter.bProgressive; + g_bDSPHLE = SConfig::GetInstance().m_LocalCoreStartupParameter.bDSPHLE; + g_bFastDiscSpeed = SConfig::GetInstance().m_LocalCoreStartupParameter.bFastDiscSpeed; + g_videoBackend = SConfig::GetInstance().m_LocalCoreStartupParameter.m_strVideoBackend; + g_bBlankMC = !File::Exists(SConfig::GetInstance().m_strMemoryCardA); + } + else if (IsPlayingInput() && tmpHeader.bSaveConfig) + { + g_bSaveConfig = tmpHeader.bSaveConfig; + g_bSkipIdle = tmpHeader.bSkipIdle; + g_bDualCore = tmpHeader.bDualCore; + g_bProgressive = tmpHeader.bProgressive; + g_bDSPHLE = tmpHeader.bDSPHLE; + g_bFastDiscSpeed = tmpHeader.bFastDiscSpeed; + g_CPUCore = tmpHeader.CPUCore; + g_bBlankMC = tmpHeader.bBlankMC; + } g_frameSkipCounter = g_framesToSkip; memset(&g_padState, 0, sizeof(g_padState)); if (!tmpHeader.bFromSaveState) @@ -249,6 +287,40 @@ bool IsUsingWiimote(int wiimote) return ((g_numPads & (1 << (wiimote + 4))) != 0); } +bool IsConfigSaved() +{ + return g_bSaveConfig; +} +bool IsDualCore() +{ + return g_bDualCore; +} + +bool IsProgressive() +{ + return g_bProgressive; +} + +bool IsSkipIdle() +{ + return g_bSkipIdle; +} + +bool IsDSPHLE() +{ + return g_bDSPHLE; +} + +bool IsFastDiscSpeed() +{ + return g_bFastDiscSpeed; +} + +int GetCPUMode() +{ + return g_CPUCore; +} + void ChangePads(bool instantly) { if (Core::GetState() == Core::CORE_UNINITIALIZED) @@ -311,10 +383,18 @@ bool BeginRecordingInput(int controllers) } g_playMode = MODE_RECORDING; + g_bSkipIdle = SConfig::GetInstance().m_LocalCoreStartupParameter.bSkipIdle; + g_bDualCore = SConfig::GetInstance().m_LocalCoreStartupParameter.bCPUThread; + g_bProgressive = SConfig::GetInstance().m_LocalCoreStartupParameter.bProgressive; + g_bDSPHLE = SConfig::GetInstance().m_LocalCoreStartupParameter.bDSPHLE; + g_bFastDiscSpeed = SConfig::GetInstance().m_LocalCoreStartupParameter.bFastDiscSpeed; + g_videoBackend = SConfig::GetInstance().m_LocalCoreStartupParameter.m_strVideoBackend; + g_CPUCore = SConfig::GetInstance().m_LocalCoreStartupParameter.iCPUCore; + delete [] tmpInput; tmpInput = new u8[MAX_DTM_LENGTH]; g_currentByte = g_totalBytes = 0; - + Core::DisplayMessage("Starting movie recording", 2000); return true; } @@ -580,6 +660,14 @@ bool PlayInput(const char *filename) g_totalInputCount = tmpHeader.inputCount; g_recordingStartTime = tmpHeader.recordingStartTime; + g_bSaveConfig = tmpHeader.bSaveConfig; + g_bSkipIdle = tmpHeader.bSkipIdle; + g_bDualCore = tmpHeader.bDualCore; + g_bProgressive = tmpHeader.bProgressive; + g_bDSPHLE = tmpHeader.bDSPHLE; + g_bFastDiscSpeed = tmpHeader.bFastDiscSpeed; + g_CPUCore = tmpHeader.CPUCore; + g_currentFrame = 0; g_currentLagCount = 0; g_currentInputCount = 0; @@ -720,6 +808,7 @@ void LoadInput(const char *filename) t_record.Close(); g_rerecords = tmpHeader.numRerecords; + g_bSaveConfig = tmpHeader.bSaveConfig; if (!afterEnd) { @@ -756,6 +845,21 @@ static void CheckInputEnd() void PlayController(SPADStatus *PadStatus, int controllerID) { + if (IsPlayingInput() && IsConfigSaved()) + { + SetGraphicsConfig(); + } + if (g_currentFrame == 1) + { + if (tmpHeader.bMemcard) + { + ExpansionInterface::ChangeDevice(0, EXIDEVICE_MEMORYCARD, 0); + } + else if (!tmpHeader.bMemcard) + { + ExpansionInterface::ChangeDevice(0, EXIDEVICE_NONE, 0); + } + } // Correct playback is entirely dependent on the emulator polling the controllers // in the same order done during recording if (!IsPlayingInput() || !IsUsingPad(controllerID) || tmpInput == NULL) @@ -913,11 +1017,28 @@ void SaveRecording(const char *filename) header.inputCount = g_totalInputCount; header.numRerecords = g_rerecords; header.recordingStartTime = g_recordingStartTime; - + + header.bSaveConfig = true; + header.bSkipIdle = g_bSkipIdle; + header.bDualCore = g_bDualCore; + header.bProgressive = g_bProgressive; + header.bDSPHLE = g_bDSPHLE; + header.bFastDiscSpeed = g_bFastDiscSpeed; + strncpy((char *)header.videoBackend, g_videoBackend.c_str(),ARRAYSIZE(header.videoBackend)); + header.CPUCore = g_CPUCore; + header.bEFBAccessEnable = g_ActiveConfig.bEFBAccessEnable; + header.bEFBCopyEnable = g_ActiveConfig.bEFBCopyEnable; + header.bCopyEFBToTexture = g_ActiveConfig.bCopyEFBToTexture; + header.bEFBCopyCacheEnable = g_ActiveConfig.bEFBCopyCacheEnable; + header.bEFBEmulateFormatChanges = g_ActiveConfig.bEFBEmulateFormatChanges; + header.bUseXFB = g_ActiveConfig.bUseXFB; + header.bUseRealXFB = g_ActiveConfig.bUseRealXFB; + header.bMemcard = g_bMemcard; + header.bBlankMC = g_bBlankMC; + // TODO header.uniqueID = 0; // header.author; - // header.videoBackend; // header.audioEmulator; save_record.WriteArray(&header, 1); @@ -947,4 +1068,15 @@ void CallInputManip(SPADStatus *PadStatus, int controllerID) if (mfunc) (*mfunc)(PadStatus, controllerID); } + +void SetGraphicsConfig() +{ + g_Config.bEFBAccessEnable = tmpHeader.bEFBAccessEnable; + g_Config.bEFBCopyEnable = tmpHeader.bEFBCopyEnable; + g_Config.bCopyEFBToTexture = tmpHeader.bCopyEFBToTexture; + g_Config.bEFBCopyCacheEnable = tmpHeader.bEFBCopyCacheEnable; + g_Config.bEFBEmulateFormatChanges = tmpHeader.bEFBEmulateFormatChanges; + g_Config.bUseXFB = tmpHeader.bUseXFB; + g_Config.bUseRealXFB = tmpHeader.bUseRealXFB; +} }; diff --git a/Source/Core/Core/Src/Movie.h b/Source/Core/Core/Src/Movie.h index ac28733221..6a4cc6bbb1 100644 --- a/Source/Core/Core/Src/Movie.h +++ b/Source/Core/Core/Src/Movie.h @@ -60,6 +60,8 @@ struct ControllerState { // Global declarations extern bool g_bFrameStep, g_bPolled, g_bReadOnly; +extern bool g_bSaveConfig, g_bSkipIdle, g_bDualCore, g_bProgressive, g_bDSPHLE, g_bFastDiscSpeed, g_bMemcard, g_bBlankMC; +extern bool g_bEFBAccessEnable, g_bEFBCopyEnable; extern PlayMode g_playMode; extern u32 g_framesToSkip, g_frameSkipCounter; @@ -73,6 +75,8 @@ extern u64 g_currentByte, g_totalBytes; extern u64 g_currentFrame, g_totalFrames; extern u64 g_currentLagCount, g_totalLagCount; extern u64 g_currentInputCount, g_totalInputCount; +extern std::string g_videoBackend; +extern int g_CPUCore; extern u32 g_rerecords; @@ -99,7 +103,23 @@ struct DTMHeader { u64 recordingStartTime; // seconds since 1970 that recording started (used for RTC) - u8 reserved[119]; // Make heading 256 bytes, just because we can + bool bSaveConfig; + bool bSkipIdle; + bool bDualCore; + bool bProgressive; + bool bDSPHLE; + bool bFastDiscSpeed; + u8 CPUCore; + bool bEFBAccessEnable; + bool bEFBCopyEnable; + bool bCopyEFBToTexture; + bool bEFBCopyCacheEnable; + bool bEFBEmulateFormatChanges; + bool bUseXFB; + bool bUseRealXFB; + bool bMemcard; + bool bBlankMC; + u8 reserved[103]; // Make heading 256 bytes, just because we can }; #pragma pack(pop) @@ -118,6 +138,15 @@ bool IsPlayingInput(); bool IsReadOnly(); u64 GetRecordingStartTime(); +bool IsConfigSaved(); +bool IsDualCore(); +bool IsProgressive(); +bool IsSkipIdle(); +bool IsDSPHLE(); +bool IsFastDiscSpeed(); +int GetCPUMode(); +void SetGraphicsConfig(); + bool IsUsingPad(int controller); bool IsUsingWiimote(int wiimote); void ChangePads(bool instantly = false);