From a6028b055b23ad998f6f15efda3525b21e3d23a1 Mon Sep 17 00:00:00 2001 From: rog Date: Sat, 20 Oct 2012 14:18:42 -0400 Subject: [PATCH] Save disc changes to .dtm, and load the full movie header every time it's loaded. --- Source/Core/Core/Src/HW/DVDInterface.cpp | 12 +++ Source/Core/Core/Src/Movie.cpp | 95 +++++++++++++++++++----- Source/Core/Core/Src/Movie.h | 18 +++-- 3 files changed, 99 insertions(+), 26 deletions(-) diff --git a/Source/Core/Core/Src/HW/DVDInterface.cpp b/Source/Core/Core/Src/HW/DVDInterface.cpp index f2b387fbd6..214fb5dc02 100644 --- a/Source/Core/Core/Src/HW/DVDInterface.cpp +++ b/Source/Core/Core/Src/HW/DVDInterface.cpp @@ -29,6 +29,7 @@ #include "Memmap.h" #include "../VolumeHandler.h" #include "AudioInterface.h" +#include "../Movie.h" // Disc transfer rate measured in bytes per second static const u32 DISC_TRANSFER_RATE_GC = 3125 * 1024; @@ -334,6 +335,17 @@ void ChangeDisc(const char* _newFileName) std::string* _FileName = new std::string(_newFileName); CoreTiming::ScheduleEvent_Threadsafe(0, ejectDisc); CoreTiming::ScheduleEvent_Threadsafe(500000000, insertDisc, (u64)_FileName); + if (Movie::IsRecordingInput()) + { + Movie::g_bDiscChange = true; + std::string fileName = _newFileName; + int sizeofpath = fileName.find_last_of("/\\") + 1; + if (fileName.substr(sizeofpath).length() > 40) + { + PanicAlert("Saving iso filename to .dtm failed; max file name length is 40 characters."); + } + Movie::g_discChange = fileName.substr(sizeofpath); + } } void SetLidOpen(bool _bOpen) diff --git a/Source/Core/Core/Src/Movie.cpp b/Source/Core/Core/Src/Movie.cpp index 94edd9dedf..03f8752e84 100644 --- a/Source/Core/Core/Src/Movie.cpp +++ b/Source/Core/Core/Src/Movie.cpp @@ -34,6 +34,7 @@ #include "HW/EXI.h" #include "HW/EXI_Device.h" #include "HW/EXI_Channel.h" +#include "HW/DVDInterface.h" // large enough for just over 24 hours of single-player recording #define MAX_DTM_LENGTH (40 * 1024 * 1024) @@ -69,6 +70,9 @@ std::string g_videoBackend = "opengl"; int g_CPUCore = 1; bool g_bMemcard; bool g_bBlankMC = false; +bool g_bDiscChange = false; +std::string g_discChange = ""; +std::string author = ""; bool g_bRecordingFromSaveState = false; bool g_bPolled = false; @@ -575,7 +579,8 @@ void RecordInput(SPADStatus *PadStatus, int controllerID) g_padState.R = ((PadStatus->button & PAD_TRIGGER_R) != 0); g_padState.TriggerL = PadStatus->triggerLeft; g_padState.TriggerR = PadStatus->triggerRight; - + g_padState.disc = g_bDiscChange; + g_padState.AnalogStickX = PadStatus->stickX; g_padState.AnalogStickY = PadStatus->stickY; @@ -588,6 +593,11 @@ void RecordInput(SPADStatus *PadStatus, int controllerID) g_totalBytes = g_currentByte; SetInputDisplayString(g_padState, controllerID); + + if (g_bDiscChange) + { + g_bDiscChange = false; + } } void RecordWiimote(int wiimote, u8 *data, const WiimoteEmu::ReportFeatures& rptf, int irMode) @@ -608,6 +618,36 @@ void RecordWiimote(int wiimote, u8 *data, const WiimoteEmu::ReportFeatures& rptf SetWiiInputDisplayString(wiimote, coreData, accelData, irData); } +void ReadHeader() +{ + g_numPads = tmpHeader.numControllers; + g_rerecords = tmpHeader.numRerecords; + + 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; + + for (int i = 0; i < ARRAYSIZE(tmpHeader.videoBackend);i++) + { + g_videoBackend[i] = tmpHeader.videoBackend[i]; + } + + for (int i = 0; i < ARRAYSIZE(tmpHeader.discChange);i++) + { + g_discChange[i] = tmpHeader.discChange[i]; + } + for (int i = 0; i < ARRAYSIZE(tmpHeader.author);i++) + { + author[i] = tmpHeader.author[i]; + } +} + bool PlayInput(const char *filename) { if(!filename || g_playMode != MODE_NONE) @@ -651,23 +691,11 @@ bool PlayInput(const char *filename) goto cleanup; } */ - - g_numPads = tmpHeader.numControllers; - g_rerecords = tmpHeader.numRerecords; + ReadHeader(); g_totalFrames = tmpHeader.frameCount; g_totalLagCount = tmpHeader.lagCount; 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; @@ -706,7 +734,7 @@ void DoState(PointerWrap &p) void LoadInput(const char *filename) { File::IOFile t_record(filename, "r+b"); - + t_record.ReadArray(&tmpHeader, 1); if(tmpHeader.filetype[0] != 'D' || tmpHeader.filetype[1] != 'T' || tmpHeader.filetype[2] != 'M' || tmpHeader.filetype[3] != 0x1A) @@ -715,7 +743,7 @@ void LoadInput(const char *filename) EndPlayInput(false); return; } - + ReadHeader(); if (!g_bReadOnly) { if (g_rerecords > tmpHeader.numRerecords) @@ -726,8 +754,7 @@ void LoadInput(const char *filename) t_record.Seek(0, SEEK_SET); t_record.WriteArray(&tmpHeader, 1); } - - g_numPads = tmpHeader.numControllers; + ChangePads(true); if (Core::g_CoreStartupParameter.bWii) ChangeWiiPads(true); @@ -925,6 +952,34 @@ void PlayController(SPADStatus *PadStatus, int controllerID) PadStatus->button |= PAD_TRIGGER_L; if(g_padState.R) PadStatus->button |= PAD_TRIGGER_R; + if (g_padState.disc) + { + // This implementation assumes the disc change will only happen once. Trying to change more than that will cause + // it to load the last disc every time. As far as i know though, there are no 3+ disc games, so this should be fine. + Core::SetState(Core::CORE_PAUSE); + int numPaths = (int)SConfig::GetInstance().m_ISOFolder.size(); + bool found = false; + std::string path; + for (int i = 0; i < numPaths; i++) + { + path = SConfig::GetInstance().m_ISOFolder[i]; + if (File::Exists((path + '/' + g_discChange.c_str()).c_str())) + { + found = true; + break; + } + } + if (found) + { + DVDInterface::ChangeDisc((path + '/' + g_discChange.c_str()).c_str()); + Core::SetState(Core::CORE_RUN); + } + else + { + Core::SetState(Core::CORE_PAUSE); + PanicAlert("Change the disc to %s", g_discChange.c_str()); + } + } SetInputDisplayString(g_padState, controllerID); @@ -1001,7 +1056,6 @@ void EndPlayInput(bool cont) void SaveRecording(const char *filename) { File::IOFile save_record(filename, "wb"); - // Create the real header now and write it DTMHeader header; memset(&header, 0, sizeof(DTMHeader)); @@ -1035,10 +1089,11 @@ void SaveRecording(const char *filename) header.bUseRealXFB = g_ActiveConfig.bUseRealXFB; header.bMemcard = g_bMemcard; header.bBlankMC = g_bBlankMC; + strncpy((char *)header.discChange, g_discChange.c_str(),ARRAYSIZE(header.discChange)); + strncpy((char *)header.author, author.c_str(),ARRAYSIZE(header.author)); // TODO header.uniqueID = 0; - // header.author; // header.audioEmulator; save_record.WriteArray(&header, 1); diff --git a/Source/Core/Core/Src/Movie.h b/Source/Core/Core/Src/Movie.h index f7a1fd27e9..46ef457f3f 100644 --- a/Source/Core/Core/Src/Movie.h +++ b/Source/Core/Core/Src/Movie.h @@ -49,7 +49,8 @@ struct ControllerState { bool DPadUp:1, DPadDown:1, // Binary D-Pad buttons, 4 bits DPadLeft:1, DPadRight:1; bool L:1, R:1; // Binary triggers, 2 bits - bool reserved:4; // Reserved bits used for padding, 4 bits + bool disc:1; // Checks for disc being changed + bool reserved:3; // Reserved bits used for padding, 4 bits u8 TriggerL, TriggerR; // Triggers, 16 bits u8 AnalogStickX, AnalogStickY; // Main Stick, 16 bits @@ -59,7 +60,7 @@ struct ControllerState { #pragma pack(pop) // Global declarations -extern bool g_bFrameStep, g_bPolled, g_bReadOnly; +extern bool g_bFrameStep, g_bPolled, g_bReadOnly, g_bDiscChange; 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; @@ -77,6 +78,7 @@ extern u64 g_currentLagCount, g_totalLagCount; extern u64 g_currentInputCount, g_totalInputCount; extern std::string g_videoBackend; extern int g_CPUCore; +extern std::string g_discChange; extern u32 g_rerecords; @@ -96,7 +98,7 @@ struct DTMHeader { u64 uniqueID; // (not implemented) A Unique ID comprised of: md5(time + Game ID) u32 numRerecords; // Number of rerecords/'cuts' of this TAS u8 author[32]; // Author's name (encoded in UTF-8) - + u8 videoBackend[16]; // UTF-8 representation of the video backend u8 audioEmulator[16]; // UTF-8 representation of the audio emulator u8 padBackend[16]; // UTF-8 representation of the input backend @@ -109,7 +111,7 @@ struct DTMHeader { bool bProgressive; bool bDSPHLE; bool bFastDiscSpeed; - u8 CPUCore; + u8 CPUCore; // 0 = interpreter, 1 = JIT, 2 = JITIL bool bEFBAccessEnable; bool bEFBCopyEnable; bool bCopyEFBToTexture; @@ -118,8 +120,11 @@ struct DTMHeader { bool bUseXFB; bool bUseRealXFB; bool bMemcard; - bool bBlankMC; - u8 reserved[103]; // Make heading 256 bytes, just because we can + bool bBlankMC; // Create a new memory card when playing back a movie if true + u8 reserved[16]; + u8 discChange[40]; // Name of iso file to switch to, for two disc games. + u8 reserved2[60]; // Make heading 256 bytes, just because we can + }; #pragma pack(pop) @@ -165,6 +170,7 @@ void RecordWiimote(int wiimote, u8* data, const struct WiimoteEmu::ReportFeature bool PlayInput(const char *filename); void LoadInput(const char *filename); +void ReadHeader(); void PlayController(SPADStatus *PadStatus, int controllerID); bool PlayWiimote(int wiimote, u8* data, const struct WiimoteEmu::ReportFeatures& rptf, int irMode); void EndPlayInput(bool cont);