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 "../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)

View File

@ -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);

View File

@ -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);