The read-only movie flag now taken into account for save states. Fixes Issue 4463.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@7674 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
2b9b4a3306
commit
ebce13fba7
|
@ -18,6 +18,7 @@
|
||||||
#include "Movie.h"
|
#include "Movie.h"
|
||||||
|
|
||||||
#include "Core.h"
|
#include "Core.h"
|
||||||
|
#include "ConfigManager.h"
|
||||||
#include "Thread.h"
|
#include "Thread.h"
|
||||||
#include "FileUtil.h"
|
#include "FileUtil.h"
|
||||||
#include "PowerPC/PowerPC.h"
|
#include "PowerPC/PowerPC.h"
|
||||||
|
@ -25,15 +26,6 @@
|
||||||
#include "HW/Wiimote.h"
|
#include "HW/Wiimote.h"
|
||||||
#include "IPC_HLE/WII_IPC_HLE_Device_usb.h"
|
#include "IPC_HLE/WII_IPC_HLE_Device_usb.h"
|
||||||
#include "VideoBackendBase.h"
|
#include "VideoBackendBase.h"
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
#include <io.h> //_chsize_s
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <share.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#else
|
|
||||||
#include <unistd.h> //truncate
|
|
||||||
#endif
|
|
||||||
#include "State.h"
|
#include "State.h"
|
||||||
|
|
||||||
// large enough for just over 24 hours of single-player recording
|
// large enough for just over 24 hours of single-player recording
|
||||||
|
@ -166,6 +158,11 @@ bool IsPlayingInput()
|
||||||
return (g_playMode == MODE_PLAYING);
|
return (g_playMode == MODE_PLAYING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsReadOnly()
|
||||||
|
{
|
||||||
|
return g_bReadOnly;
|
||||||
|
}
|
||||||
|
|
||||||
bool IsUsingPad(int controller)
|
bool IsUsingPad(int controller)
|
||||||
{
|
{
|
||||||
return ((g_numPads & (1 << controller)) != 0);
|
return ((g_numPads & (1 << controller)) != 0);
|
||||||
|
@ -178,18 +175,37 @@ bool IsUsingWiimote(int wiimote)
|
||||||
|
|
||||||
void ChangePads(bool instantly)
|
void ChangePads(bool instantly)
|
||||||
{
|
{
|
||||||
if (Core::GetState() != Core::CORE_UNINITIALIZED)
|
if (Core::GetState() == Core::CORE_UNINITIALIZED)
|
||||||
{
|
return;
|
||||||
|
|
||||||
|
int controllers = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
if (SConfig::GetInstance().m_SIDevice[i] == SI_GC_CONTROLLER)
|
||||||
|
controllers |= (1 << i);
|
||||||
|
|
||||||
|
if (instantly && (g_numPads & 0x0F) == controllers)
|
||||||
|
return;
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
if (instantly) // Changes from savestates need to be instantaneous
|
if (instantly) // Changes from savestates need to be instantaneous
|
||||||
SerialInterface::AddDevice(IsUsingPad(i) ? SI_GC_CONTROLLER : SI_NONE, i);
|
SerialInterface::AddDevice(IsUsingPad(i) ? SI_GC_CONTROLLER : SI_NONE, i);
|
||||||
else
|
else
|
||||||
SerialInterface::ChangeDevice(IsUsingPad(i) ? SI_GC_CONTROLLER : SI_NONE, i);
|
SerialInterface::ChangeDevice(IsUsingPad(i) ? SI_GC_CONTROLLER : SI_NONE, i);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void ChangeWiiPads()
|
void ChangeWiiPads(bool instantly)
|
||||||
{
|
{
|
||||||
|
int controllers = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
if (g_wiimote_sources[i] != WIIMOTE_SRC_NONE)
|
||||||
|
controllers |= (1 << i);
|
||||||
|
|
||||||
|
// This is important for Wiimotes, because they can desync easily if they get re-activated
|
||||||
|
if (instantly && (g_numPads >> 4) == controllers)
|
||||||
|
return;
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
g_wiimote_sources[i] = IsUsingWiimote(i) ? WIIMOTE_SRC_EMU : WIIMOTE_SRC_NONE;
|
g_wiimote_sources[i] = IsUsingWiimote(i) ? WIIMOTE_SRC_EMU : WIIMOTE_SRC_NONE;
|
||||||
|
@ -213,9 +229,7 @@ bool BeginRecordingInput(int controllers)
|
||||||
|
|
||||||
g_numPads = controllers;
|
g_numPads = controllers;
|
||||||
|
|
||||||
g_frameCounter = 0;
|
g_frameCounter = g_lagCounter = g_InputCounter = 0;
|
||||||
g_lagCounter = 0;
|
|
||||||
g_InputCounter = 0;
|
|
||||||
g_rerecords = 0;
|
g_rerecords = 0;
|
||||||
g_playMode = MODE_RECORDING;
|
g_playMode = MODE_RECORDING;
|
||||||
inputOffset = 0;
|
inputOffset = 0;
|
||||||
|
@ -416,13 +430,14 @@ void LoadInput(const char *filename)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!g_bReadOnly)
|
||||||
tmpHeader.numRerecords++;
|
tmpHeader.numRerecords++;
|
||||||
|
|
||||||
t_record.Seek(0, SEEK_SET);
|
t_record.Seek(0, SEEK_SET);
|
||||||
t_record.WriteArray(&tmpHeader, 1);
|
t_record.WriteArray(&tmpHeader, 1);
|
||||||
|
|
||||||
g_frameCounter = tmpHeader.frameCount;
|
g_frameCounter = tmpHeader.frameCount;
|
||||||
g_totalFrameCount = tmpHeader.frameCount;
|
g_totalFrameCount = (tmpHeader.totalFrameCount ? tmpHeader.totalFrameCount : tmpHeader.frameCount);
|
||||||
g_InputCounter = tmpHeader.InputCount;
|
g_InputCounter = tmpHeader.InputCount;
|
||||||
|
|
||||||
g_numPads = tmpHeader.numControllers;
|
g_numPads = tmpHeader.numControllers;
|
||||||
|
@ -430,21 +445,28 @@ void LoadInput(const char *filename)
|
||||||
ChangePads(true);
|
ChangePads(true);
|
||||||
|
|
||||||
if (Core::g_CoreStartupParameter.bWii)
|
if (Core::g_CoreStartupParameter.bWii)
|
||||||
ChangeWiiPads();
|
ChangeWiiPads(true);
|
||||||
|
|
||||||
inputOffset = t_record.GetSize() - 256;
|
inputOffset = t_record.GetSize() - 256;
|
||||||
delete tmpInput;
|
delete tmpInput;
|
||||||
tmpInput = new u8[MAX_DTM_LENGTH];
|
tmpInput = new u8[MAX_DTM_LENGTH];
|
||||||
t_record.ReadArray(tmpInput, inputOffset);
|
t_record.ReadArray(tmpInput, inputOffset);
|
||||||
|
|
||||||
t_record.Close();
|
t_record.Close();
|
||||||
|
|
||||||
g_rerecords = tmpHeader.numRerecords;
|
g_rerecords = tmpHeader.numRerecords;
|
||||||
|
|
||||||
|
if (g_bReadOnly)
|
||||||
|
{
|
||||||
|
tmpLength = inputOffset;
|
||||||
|
inputOffset = tmpHeader.frameStart;
|
||||||
|
Core::DisplayMessage("Resuming movie playback", 2000);
|
||||||
|
g_playMode = MODE_PLAYING;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
Core::DisplayMessage("Resuming movie recording", 2000);
|
Core::DisplayMessage("Resuming movie recording", 2000);
|
||||||
|
|
||||||
g_playMode = MODE_RECORDING;
|
g_playMode = MODE_RECORDING;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PlayController(SPADStatus *PadStatus, int controllerID)
|
void PlayController(SPADStatus *PadStatus, int controllerID)
|
||||||
{
|
{
|
||||||
|
@ -599,11 +621,6 @@ void SaveRecording(const char *filename)
|
||||||
{
|
{
|
||||||
File::IOFile save_record(filename, "wb");
|
File::IOFile save_record(filename, "wb");
|
||||||
|
|
||||||
// NOTE: Eventually this will not happen in
|
|
||||||
// read-only mode, but we need a way for the save state to
|
|
||||||
// store the current point in the file first.
|
|
||||||
// if (!g_bReadOnly)
|
|
||||||
{
|
|
||||||
// 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));
|
||||||
|
@ -625,10 +642,20 @@ void SaveRecording(const char *filename)
|
||||||
// header.videoBackend;
|
// header.videoBackend;
|
||||||
// header.audioEmulator;
|
// header.audioEmulator;
|
||||||
|
|
||||||
save_record.WriteArray(&header, 1);
|
if (g_bReadOnly)
|
||||||
|
{
|
||||||
|
header.frameStart = inputOffset;
|
||||||
|
header.totalFrameCount = g_totalFrameCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool success = save_record.WriteArray(tmpInput, inputOffset);
|
save_record.WriteArray(&header, 1);
|
||||||
|
|
||||||
|
bool success;
|
||||||
|
|
||||||
|
if (g_bReadOnly)
|
||||||
|
success = save_record.WriteArray(tmpInput, tmpLength);
|
||||||
|
else
|
||||||
|
success = save_record.WriteArray(tmpInput, inputOffset);
|
||||||
|
|
||||||
if (success && g_bRecordingFromSaveState)
|
if (success && g_bRecordingFromSaveState)
|
||||||
{
|
{
|
||||||
|
|
|
@ -87,7 +87,11 @@ struct DTMHeader {
|
||||||
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
|
||||||
|
|
||||||
u8 reserved[127]; // Make heading 256 bytes, just because we can
|
// only used in read-only savestates
|
||||||
|
u64 frameStart; // Offset to resume playback on
|
||||||
|
u64 totalFrameCount; // Total frames, same as normal dtm's frameCount
|
||||||
|
|
||||||
|
u8 reserved[111]; // Make heading 256 bytes, just because we can
|
||||||
};
|
};
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
@ -100,11 +104,12 @@ bool IsAutoFiring();
|
||||||
bool IsRecordingInput();
|
bool IsRecordingInput();
|
||||||
bool IsRecordingInputFromSaveState();
|
bool IsRecordingInputFromSaveState();
|
||||||
bool IsPlayingInput();
|
bool IsPlayingInput();
|
||||||
|
bool IsReadOnly();
|
||||||
|
|
||||||
bool IsUsingPad(int controller);
|
bool IsUsingPad(int controller);
|
||||||
bool IsUsingWiimote(int wiimote);
|
bool IsUsingWiimote(int wiimote);
|
||||||
void ChangePads(bool instantly = false);
|
void ChangePads(bool instantly = false);
|
||||||
void ChangeWiiPads();
|
void ChangeWiiPads(bool instantly = false);
|
||||||
|
|
||||||
void SetFrameStepping(bool bEnabled);
|
void SetFrameStepping(bool bEnabled);
|
||||||
void SetFrameStopping(bool bEnabled);
|
void SetFrameStopping(bool bEnabled);
|
||||||
|
|
|
@ -716,6 +716,12 @@ void CFrame::OnRecord(wxCommandEvent& WXUNUSED (event))
|
||||||
{
|
{
|
||||||
int controllers = 0;
|
int controllers = 0;
|
||||||
|
|
||||||
|
if (Movie::IsReadOnly())
|
||||||
|
{
|
||||||
|
PanicAlertT("Cannot record movies in read-only mode.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
if (SConfig::GetInstance().m_SIDevice[i] == SI_GC_CONTROLLER)
|
if (SConfig::GetInstance().m_SIDevice[i] == SI_GC_CONTROLLER)
|
||||||
controllers |= (1 << i);
|
controllers |= (1 << i);
|
||||||
|
|
Loading…
Reference in New Issue