Save disc changes to .dtm, and load the full movie header every time it's loaded.

This commit is contained in:
rog 2012-10-20 14:18:42 -04:00
parent 5230146c73
commit a6028b055b
3 changed files with 99 additions and 26 deletions

View File

@ -29,6 +29,7 @@
#include "Memmap.h" #include "Memmap.h"
#include "../VolumeHandler.h" #include "../VolumeHandler.h"
#include "AudioInterface.h" #include "AudioInterface.h"
#include "../Movie.h"
// Disc transfer rate measured in bytes per second // Disc transfer rate measured in bytes per second
static const u32 DISC_TRANSFER_RATE_GC = 3125 * 1024; 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); std::string* _FileName = new std::string(_newFileName);
CoreTiming::ScheduleEvent_Threadsafe(0, ejectDisc); CoreTiming::ScheduleEvent_Threadsafe(0, ejectDisc);
CoreTiming::ScheduleEvent_Threadsafe(500000000, insertDisc, (u64)_FileName); 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) void SetLidOpen(bool _bOpen)

View File

@ -34,6 +34,7 @@
#include "HW/EXI.h" #include "HW/EXI.h"
#include "HW/EXI_Device.h" #include "HW/EXI_Device.h"
#include "HW/EXI_Channel.h" #include "HW/EXI_Channel.h"
#include "HW/DVDInterface.h"
// large enough for just over 24 hours of single-player recording // large enough for just over 24 hours of single-player recording
#define MAX_DTM_LENGTH (40 * 1024 * 1024) #define MAX_DTM_LENGTH (40 * 1024 * 1024)
@ -69,6 +70,9 @@ std::string g_videoBackend = "opengl";
int g_CPUCore = 1; int g_CPUCore = 1;
bool g_bMemcard; bool g_bMemcard;
bool g_bBlankMC = false; bool g_bBlankMC = false;
bool g_bDiscChange = false;
std::string g_discChange = "";
std::string author = "";
bool g_bRecordingFromSaveState = false; bool g_bRecordingFromSaveState = false;
bool g_bPolled = 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.R = ((PadStatus->button & PAD_TRIGGER_R) != 0);
g_padState.TriggerL = PadStatus->triggerLeft; g_padState.TriggerL = PadStatus->triggerLeft;
g_padState.TriggerR = PadStatus->triggerRight; g_padState.TriggerR = PadStatus->triggerRight;
g_padState.disc = g_bDiscChange;
g_padState.AnalogStickX = PadStatus->stickX; g_padState.AnalogStickX = PadStatus->stickX;
g_padState.AnalogStickY = PadStatus->stickY; g_padState.AnalogStickY = PadStatus->stickY;
@ -588,6 +593,11 @@ void RecordInput(SPADStatus *PadStatus, int controllerID)
g_totalBytes = g_currentByte; g_totalBytes = g_currentByte;
SetInputDisplayString(g_padState, controllerID); SetInputDisplayString(g_padState, controllerID);
if (g_bDiscChange)
{
g_bDiscChange = false;
}
} }
void RecordWiimote(int wiimote, u8 *data, const WiimoteEmu::ReportFeatures& rptf, int irMode) 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); 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) bool PlayInput(const char *filename)
{ {
if(!filename || g_playMode != MODE_NONE) if(!filename || g_playMode != MODE_NONE)
@ -651,23 +691,11 @@ bool PlayInput(const char *filename)
goto cleanup; goto cleanup;
} }
*/ */
g_numPads = tmpHeader.numControllers;
g_rerecords = tmpHeader.numRerecords;
ReadHeader();
g_totalFrames = tmpHeader.frameCount; g_totalFrames = tmpHeader.frameCount;
g_totalLagCount = tmpHeader.lagCount; g_totalLagCount = tmpHeader.lagCount;
g_totalInputCount = tmpHeader.inputCount; 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_currentFrame = 0;
g_currentLagCount = 0; g_currentLagCount = 0;
g_currentInputCount = 0; g_currentInputCount = 0;
@ -706,7 +734,7 @@ void DoState(PointerWrap &p)
void LoadInput(const char *filename) void LoadInput(const char *filename)
{ {
File::IOFile t_record(filename, "r+b"); File::IOFile t_record(filename, "r+b");
t_record.ReadArray(&tmpHeader, 1); t_record.ReadArray(&tmpHeader, 1);
if(tmpHeader.filetype[0] != 'D' || tmpHeader.filetype[1] != 'T' || tmpHeader.filetype[2] != 'M' || tmpHeader.filetype[3] != 0x1A) 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); EndPlayInput(false);
return; return;
} }
ReadHeader();
if (!g_bReadOnly) if (!g_bReadOnly)
{ {
if (g_rerecords > tmpHeader.numRerecords) if (g_rerecords > tmpHeader.numRerecords)
@ -726,8 +754,7 @@ void LoadInput(const char *filename)
t_record.Seek(0, SEEK_SET); t_record.Seek(0, SEEK_SET);
t_record.WriteArray(&tmpHeader, 1); t_record.WriteArray(&tmpHeader, 1);
} }
g_numPads = tmpHeader.numControllers;
ChangePads(true); ChangePads(true);
if (Core::g_CoreStartupParameter.bWii) if (Core::g_CoreStartupParameter.bWii)
ChangeWiiPads(true); ChangeWiiPads(true);
@ -925,6 +952,34 @@ void PlayController(SPADStatus *PadStatus, int controllerID)
PadStatus->button |= PAD_TRIGGER_L; PadStatus->button |= PAD_TRIGGER_L;
if(g_padState.R) if(g_padState.R)
PadStatus->button |= PAD_TRIGGER_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); SetInputDisplayString(g_padState, controllerID);
@ -1001,7 +1056,6 @@ void EndPlayInput(bool cont)
void SaveRecording(const char *filename) void SaveRecording(const char *filename)
{ {
File::IOFile save_record(filename, "wb"); File::IOFile save_record(filename, "wb");
// Create the real header now and write it // Create the real header now and write it
DTMHeader header; DTMHeader header;
memset(&header, 0, sizeof(DTMHeader)); memset(&header, 0, sizeof(DTMHeader));
@ -1035,10 +1089,11 @@ void SaveRecording(const char *filename)
header.bUseRealXFB = g_ActiveConfig.bUseRealXFB; header.bUseRealXFB = g_ActiveConfig.bUseRealXFB;
header.bMemcard = g_bMemcard; header.bMemcard = g_bMemcard;
header.bBlankMC = g_bBlankMC; 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 // TODO
header.uniqueID = 0; header.uniqueID = 0;
// header.author;
// header.audioEmulator; // header.audioEmulator;
save_record.WriteArray(&header, 1); save_record.WriteArray(&header, 1);

View File

@ -49,7 +49,8 @@ struct ControllerState {
bool DPadUp:1, DPadDown:1, // Binary D-Pad buttons, 4 bits bool DPadUp:1, DPadDown:1, // Binary D-Pad buttons, 4 bits
DPadLeft:1, DPadRight:1; DPadLeft:1, DPadRight:1;
bool L:1, R:1; // Binary triggers, 2 bits 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 TriggerL, TriggerR; // Triggers, 16 bits
u8 AnalogStickX, AnalogStickY; // Main Stick, 16 bits u8 AnalogStickX, AnalogStickY; // Main Stick, 16 bits
@ -59,7 +60,7 @@ struct ControllerState {
#pragma pack(pop) #pragma pack(pop)
// Global declarations // 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_bSaveConfig, g_bSkipIdle, g_bDualCore, g_bProgressive, g_bDSPHLE, g_bFastDiscSpeed, g_bMemcard, g_bBlankMC;
extern bool g_bEFBAccessEnable, g_bEFBCopyEnable; extern bool g_bEFBAccessEnable, g_bEFBCopyEnable;
extern PlayMode g_playMode; extern PlayMode g_playMode;
@ -77,6 +78,7 @@ extern u64 g_currentLagCount, g_totalLagCount;
extern u64 g_currentInputCount, g_totalInputCount; extern u64 g_currentInputCount, g_totalInputCount;
extern std::string g_videoBackend; extern std::string g_videoBackend;
extern int g_CPUCore; extern int g_CPUCore;
extern std::string g_discChange;
extern u32 g_rerecords; extern u32 g_rerecords;
@ -96,7 +98,7 @@ struct DTMHeader {
u64 uniqueID; // (not implemented) A Unique ID comprised of: md5(time + Game ID) u64 uniqueID; // (not implemented) A Unique ID comprised of: md5(time + Game ID)
u32 numRerecords; // Number of rerecords/'cuts' of this TAS u32 numRerecords; // Number of rerecords/'cuts' of this TAS
u8 author[32]; // Author's name (encoded in UTF-8) u8 author[32]; // Author's name (encoded in UTF-8)
u8 videoBackend[16]; // UTF-8 representation of the video backend u8 videoBackend[16]; // UTF-8 representation of the video backend
u8 audioEmulator[16]; // UTF-8 representation of the audio emulator u8 audioEmulator[16]; // UTF-8 representation of the audio emulator
u8 padBackend[16]; // UTF-8 representation of the input backend u8 padBackend[16]; // UTF-8 representation of the input backend
@ -109,7 +111,7 @@ struct DTMHeader {
bool bProgressive; bool bProgressive;
bool bDSPHLE; bool bDSPHLE;
bool bFastDiscSpeed; bool bFastDiscSpeed;
u8 CPUCore; u8 CPUCore; // 0 = interpreter, 1 = JIT, 2 = JITIL
bool bEFBAccessEnable; bool bEFBAccessEnable;
bool bEFBCopyEnable; bool bEFBCopyEnable;
bool bCopyEFBToTexture; bool bCopyEFBToTexture;
@ -118,8 +120,11 @@ struct DTMHeader {
bool bUseXFB; bool bUseXFB;
bool bUseRealXFB; bool bUseRealXFB;
bool bMemcard; bool bMemcard;
bool bBlankMC; bool bBlankMC; // Create a new memory card when playing back a movie if true
u8 reserved[103]; // Make heading 256 bytes, just because we can 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) #pragma pack(pop)
@ -165,6 +170,7 @@ void RecordWiimote(int wiimote, u8* data, const struct WiimoteEmu::ReportFeature
bool PlayInput(const char *filename); bool PlayInput(const char *filename);
void LoadInput(const char *filename); void LoadInput(const char *filename);
void ReadHeader();
void PlayController(SPADStatus *PadStatus, int controllerID); void PlayController(SPADStatus *PadStatus, int controllerID);
bool PlayWiimote(int wiimote, u8* data, const struct WiimoteEmu::ReportFeatures& rptf, int irMode); bool PlayWiimote(int wiimote, u8* data, const struct WiimoteEmu::ReportFeatures& rptf, int irMode);
void EndPlayInput(bool cont); void EndPlayInput(bool cont);