Movies: Allow rewinding in movies

This commit is contained in:
Souryo 2017-11-26 18:16:32 -05:00
parent 3348c3d96a
commit a0289a5e95
9 changed files with 28 additions and 18 deletions

View file

@ -30,7 +30,7 @@ void BizhawkMovie::Stop()
bool BizhawkMovie::SetInput(BaseControlDevice *device)
{
SystemActionManager* actionManager = dynamic_cast<SystemActionManager*>(device);
int32_t frameNumber = PPU::GetFrameCount();
int32_t frameNumber = _gameLoaded ? PPU::GetFrameCount() : 0;
if(actionManager) {
if(frameNumber < (int32_t)_systemActionByFrame.size()) {
uint32_t systemAction = _systemActionByFrame[frameNumber];
@ -96,6 +96,8 @@ bool BizhawkMovie::InitializeGameData(ZipReader &reader)
return false;
}
_gameLoaded = false;
while(!fileData.eof()) {
string line;
std::getline(fileData, line);
@ -104,6 +106,7 @@ bool BizhawkMovie::InitializeGameData(ZipReader &reader)
HashInfo hashInfo;
hashInfo.Sha1Hash = line.substr(5, 40);
if(Console::LoadROM("", hashInfo)) {
_gameLoaded = true;
return true;
}
}
@ -113,6 +116,7 @@ bool BizhawkMovie::InitializeGameData(ZipReader &reader)
hashInfo.PrgChrMd5Hash = line.substr(4, 32);
std::transform(hashInfo.PrgChrMd5Hash.begin(), hashInfo.PrgChrMd5Hash.end(), hashInfo.PrgChrMd5Hash.begin(), ::toupper);
if(Console::LoadROM("", hashInfo)) {
_gameLoaded = true;
return true;
}
}

View file

@ -16,6 +16,7 @@ protected:
vector<uint32_t> _systemActionByFrame;
vector<string> _dataByFrame[4];
bool _isPlaying = false;
bool _gameLoaded = false;
RamPowerOnState _originalPowerOnState;
public:

View file

@ -625,10 +625,6 @@ void Console::SaveState(ostream &saveStream)
void Console::LoadState(istream &loadStream, uint32_t stateVersion)
{
if(Instance->_initialized) {
//Stop any movie that might have been playing/recording if a state is loaded
//(Note: Loading a state is disabled in the UI while a movie is playing/recording)
MovieManager::Stop();
Instance->_cpu->LoadSnapshot(&loadStream, stateVersion);
Instance->_ppu->LoadSnapshot(&loadStream, stateVersion);
Instance->_memoryManager->LoadSnapshot(&loadStream, stateVersion);

View file

@ -24,6 +24,7 @@ bool FceuxMovie::InitializeData(stringstream &filestream)
HashInfo hashInfo;
hashInfo.PrgChrMd5Hash = HexUtilities::ToHex(md5array);
if(Console::LoadROM("", hashInfo)) {
_gameLoaded = true;
result = true;
} else {
return false;

View file

@ -152,8 +152,6 @@ void GameClientConnection::DisableControllers()
bool GameClientConnection::SetInput(BaseControlDevice *device)
{
device->SetRawState(ControlDeviceState());
if(_enableControllers) {
uint8_t port = device->GetPort();
while(_inputSize[port] == 0) {
@ -183,7 +181,6 @@ bool GameClientConnection::SetInput(BaseControlDevice *device)
}
device->SetRawState(state);
return true;
}
return true;
}

View file

@ -12,6 +12,7 @@
#include "MovieRecorder.h"
#include "BatteryManager.h"
#include "VirtualFile.h"
#include "PPU.h"
MesenMovie::MesenMovie()
{
@ -33,14 +34,15 @@ void MesenMovie::Stop()
bool MesenMovie::SetInput(BaseControlDevice *device)
{
if(_inputData.size() > _readIndex && _inputData[_readIndex].size() > _deviceIndex) {
device->SetTextState(_inputData[_readIndex][_deviceIndex]);
uint32_t inputRowIndex = _gameLoaded ? PPU::GetFrameCount() - _firstFrameNumber : 0;
if(_inputData.size() > inputRowIndex && _inputData[inputRowIndex].size() > _deviceIndex) {
device->SetTextState(_inputData[inputRowIndex][_deviceIndex]);
_deviceIndex++;
if(_deviceIndex >= _inputData[_readIndex].size()) {
if(_deviceIndex >= _inputData[inputRowIndex].size()) {
//Move to the next frame's data
_deviceIndex = 0;
_readIndex++;
}
} else {
Stop();
@ -88,7 +90,6 @@ bool MesenMovie::Play(VirtualFile &file)
}
}
_readIndex = 0;
_deviceIndex = 0;
ParseSettings(settingsData);
@ -99,20 +100,23 @@ bool MesenMovie::Play(VirtualFile &file)
ControlManager::RegisterInputProvider(this);
ApplySettings();
_gameLoaded = false;
if(!LoadGame()) {
Console::Resume();
return false;
}
_gameLoaded = true;
_firstFrameNumber = 0;
stringstream saveStateData;
if(_reader->GetStream("SaveState.mst", saveStateData)) {
if(!SaveStateManager::LoadState(saveStateData, true)) {
Console::Resume();
return false;
} else {
//Reset to first line of the input log
//TODO: Change this to allow rewinding during movie playback
_readIndex = 0;
_firstFrameNumber = PPU::GetFrameCount();
}
}

View file

@ -15,12 +15,14 @@ private:
VirtualFile _movieFile;
shared_ptr<ZipReader> _reader;
bool _playing = false;
size_t _readIndex = 0;
size_t _deviceIndex = 0;
vector<vector<string>> _inputData;
vector<string> _cheats;
std::unordered_map<string, string> _settings;
string _filename;
bool _gameLoaded = false;
uint32_t _firstFrameNumber = 0;
private:
void ParseSettings(stringstream &data);

View file

@ -8,6 +8,7 @@
#include "EmulationSettings.h"
#include "VideoDecoder.h"
#include "Debugger.h"
#include "MovieManager.h"
const uint32_t SaveStateManager::FileFormatVersion;
atomic<uint32_t> SaveStateManager::_lastIndex(1);
@ -147,6 +148,10 @@ bool SaveStateManager::LoadState(istream &stream, bool hashCheckRequired)
}
}
//Stop any movie that might have been playing/recording if a state is loaded
//(Note: Loading a state is disabled in the UI while a movie is playing/recording)
MovieManager::Stop();
Console::LoadState(stream, fileFormatVersion);
return true;

View file

@ -167,7 +167,7 @@ void ShortcutKeyHandler::CheckMappedKeys()
}
}
if(!isNetplayClient && !isMovieActive && !EmulationSettings::CheckFlag(NsfPlayerEnabled)) {
if(!isNetplayClient && !EmulationSettings::CheckFlag(NsfPlayerEnabled)) {
if(DetectKeyPress(EmulatorShortcut::ToggleRewind)) {
if(RewindManager::IsRewinding()) {
RewindManager::StopRewinding();