Example #1
0
void SaveAs(const std::string& filename)
{
	// Pause the core while we save the state
	bool wasUnpaused = Core::PauseAndLock(true);

	// Measure the size of the buffer.
	u8 *ptr = NULL;
	PointerWrap p(&ptr, PointerWrap::MODE_MEASURE);
	DoState(p);
	const size_t buffer_size = reinterpret_cast<size_t>(ptr);

	// Then actually do the write.
	{
		std::lock_guard<std::mutex> lk(g_cs_current_buffer);
		g_current_buffer.resize(buffer_size);
		ptr = &g_current_buffer[0];
		p.SetMode(PointerWrap::MODE_WRITE);
		DoState(p);
	}

	if (p.GetMode() == PointerWrap::MODE_WRITE)
	{
		Core::DisplayMessage("Saving State...", 1000);
		if ((Movie::IsRecordingInput() || Movie::IsPlayingInput()) && !Movie::IsJustStartingRecordingInputFromSaveState())
			Movie::SaveRecording((filename + ".dtm").c_str());
		else if (!Movie::IsRecordingInput() && !Movie::IsPlayingInput())
			File::Delete(filename + ".dtm");

		CompressAndDumpState_args save_args;
		save_args.buffer_vector = &g_current_buffer;
		save_args.buffer_mutex = &g_cs_current_buffer;
		save_args.filename = filename;

		Flush();
		g_save_thread = std::thread(CompressAndDumpState, save_args);
		g_compressAndDumpStateSyncEvent.Wait();

		g_last_filename = filename;
	}
	else
	{
		// someone aborted the save by changing the mode?
		Core::DisplayMessage("Unable to Save : Internal DoState Error", 4000);
	}

	// Resume the core and disable stepping
	Core::PauseAndLock(false, wasUnpaused);
}
Example #2
0
void SaveToBuffer(std::vector<u8>& buffer)
{
	bool wasUnpaused = Core::PauseAndLock(true);

	u8* ptr = NULL;
	PointerWrap p(&ptr, PointerWrap::MODE_MEASURE);

	DoState(p);
	const size_t buffer_size = reinterpret_cast<size_t>(ptr);
	buffer.resize(buffer_size);
	
	ptr = &buffer[0];
	p.SetMode(PointerWrap::MODE_WRITE);
	DoState(p);

	Core::PauseAndLock(false, wasUnpaused);
}
Example #3
0
bool GameFileCache::SyncCacheFile(bool save)
{
  const char* open_mode = save ? "wb" : "rb";
  File::IOFile f(m_path, open_mode);
  if (!f)
    return false;
  bool success = false;
  if (save)
  {
    // Measure the size of the buffer.
    u8* ptr = nullptr;
    PointerWrap p(&ptr, PointerWrap::MODE_MEASURE);
    DoState(&p);
    const size_t buffer_size = reinterpret_cast<size_t>(ptr);

    // Then actually do the write.
    std::vector<u8> buffer(buffer_size);
    ptr = &buffer[0];
    p.SetMode(PointerWrap::MODE_WRITE);
    DoState(&p, buffer_size);
    if (f.WriteBytes(buffer.data(), buffer.size()))
      success = true;
  }
  else
  {
    std::vector<u8> buffer(f.GetSize());
    if (!buffer.empty() && f.ReadBytes(buffer.data(), buffer.size()))
    {
      u8* ptr = buffer.data();
      PointerWrap p(&ptr, PointerWrap::MODE_READ);
      DoState(&p, buffer.size());
      if (p.GetMode() == PointerWrap::MODE_READ)
        success = true;
    }
  }
  if (!success)
  {
    // If some file operation failed, try to delete the probably-corrupted cache
    f.Close();
    File::Delete(m_path);
  }
  return success;
}
Example #4
0
void VerifyBuffer(std::vector<u8>& buffer)
{
	bool wasUnpaused = Core::PauseAndLock(true);

	u8* ptr = &buffer[0];
	PointerWrap p(&ptr, PointerWrap::MODE_VERIFY);
	DoState(p);

	Core::PauseAndLock(false, wasUnpaused);
}
Example #5
0
void LoadFromBuffer(std::vector<u8>& buffer)
{
  if (NetPlay::IsNetPlayRunning())
  {
    OSD::AddMessage("Loading savestates is disabled in Netplay to prevent desyncs");
    return;
  }

  bool wasUnpaused = Core::PauseAndLock(true);

  u8* ptr = &buffer[0];
  PointerWrap p(&ptr, PointerWrap::MODE_READ);
  DoState(p);

  Core::PauseAndLock(false, wasUnpaused);
}
void GCMemcardDirectory::DoState(PointerWrap &p)
{
	m_LastBlock = -1;
	m_LastBlockAddress = nullptr;
	p.Do(m_SaveDirectory);
	p.DoPOD<Header>(m_hdr);
	p.DoPOD<Directory>(m_dir1);
	p.DoPOD<Directory>(m_dir2);
	p.DoPOD<BlockAlloc>(m_bat1);
	p.DoPOD<BlockAlloc>(m_bat2);
	int numSaves = (int)m_saves.size();
	p.Do(numSaves);
	m_saves.resize(numSaves);
	for (auto itr = m_saves.begin(); itr != m_saves.end(); ++itr)
	{
		itr->DoState(p);
	}
}
Example #7
0
void VerifyAt(const std::string& filename)
{
	bool wasUnpaused = Core::PauseAndLock(true);

	std::vector<u8> buffer;
	LoadFileStateData(filename, buffer);

	if (!buffer.empty())
	{
		u8 *ptr = &buffer[0];
		PointerWrap p(&ptr, PointerWrap::MODE_VERIFY);
		DoState(p);

		if (p.GetMode() == PointerWrap::MODE_VERIFY)
			Core::DisplayMessage(StringFromFormat("Verified state at %s", filename.c_str()).c_str(), 2000);
		else
			Core::DisplayMessage("Unable to Verify : Can't verify state from other revisions !", 4000);
	}

	Core::PauseAndLock(false, wasUnpaused);
}
Example #8
0
void VideoCommon_DoState(PointerWrap &p)
{
    DoState(p);
	//TODO: search for more data that should be saved and add it here
}
Example #9
0
void LoadAs(const std::string& filename)
{
	// Stop the core while we load the state
	bool wasUnpaused = Core::PauseAndLock(true);

#if defined _DEBUG && defined _WIN32
	// we use _CRTDBG_DELAY_FREE_MEM_DF (as a speed hack?),
	// but it was causing us to leak gigantic amounts of memory here,
	// enough that only a few savestates could be loaded before crashing,
	// so let's disable it temporarily.
	int tmpflag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
	if (g_loadDepth == 0)
		_CrtSetDbgFlag(tmpflag & ~_CRTDBG_DELAY_FREE_MEM_DF);
#endif

	g_loadDepth++;

	// Save temp buffer for undo load state
	{
		std::lock_guard<std::mutex> lk(g_cs_undo_load_buffer);
		SaveToBuffer(g_undo_load_buffer);
	}

	bool loaded = false;
	bool loadedSuccessfully = false;

	// brackets here are so buffer gets freed ASAP
	{
		std::vector<u8> buffer;
		LoadFileStateData(filename, buffer);

		if (!buffer.empty())
		{
			u8 *ptr = &buffer[0];
			PointerWrap p(&ptr, PointerWrap::MODE_READ);
			DoState(p);
			loaded = true;
			loadedSuccessfully = (p.GetMode() == PointerWrap::MODE_READ);
		}
	}

	if (loaded)
	{
		if (loadedSuccessfully)
		{
			Core::DisplayMessage(StringFromFormat("Loaded state from %s", filename.c_str()).c_str(), 2000);
			if (File::Exists(filename + ".dtm"))
				Movie::LoadInput((filename + ".dtm").c_str());
			else if (!Movie::IsJustStartingRecordingInputFromSaveState())
				Movie::EndPlayInput(false);
		}
		else
		{
			// failed to load
			Core::DisplayMessage("Unable to Load : Can't load state from other revisions !", 4000);

			// since we could be in an inconsistent state now (and might crash or whatever), undo.
			if (g_loadDepth < 2)
				UndoLoadState();
		}
	}

	if (g_onAfterLoadCb)
		g_onAfterLoadCb();

	g_loadDepth--;

#if defined _DEBUG && defined _WIN32
	// restore _CRTDBG_DELAY_FREE_MEM_DF
	if (g_loadDepth == 0)
		_CrtSetDbgFlag(tmpflag);
#endif

	// resume dat core
	Core::PauseAndLock(false, wasUnpaused);
}
Example #10
0
MvcModel::StateType MvcModel::State() const
{
    return DoState();
}
Example #11
0
void LoadAs(const std::string& filename)
{
  if (!Core::IsRunning())
  {
    return;
  }
  else if (NetPlay::IsNetPlayRunning())
  {
    OSD::AddMessage("Loading savestates is disabled in Netplay to prevent desyncs");
    return;
  }

  // Stop the core while we load the state
  bool wasUnpaused = Core::PauseAndLock(true);

  g_loadDepth++;

  // Save temp buffer for undo load state
  if (!Movie::IsJustStartingRecordingInputFromSaveState())
  {
    std::lock_guard<std::mutex> lk(g_cs_undo_load_buffer);
    SaveToBuffer(g_undo_load_buffer);
    if (Movie::IsMovieActive())
      Movie::SaveRecording(File::GetUserPath(D_STATESAVES_IDX) + "undo.dtm");
    else if (File::Exists(File::GetUserPath(D_STATESAVES_IDX) + "undo.dtm"))
      File::Delete(File::GetUserPath(D_STATESAVES_IDX) + "undo.dtm");
  }

  bool loaded = false;
  bool loadedSuccessfully = false;
  std::string version_created_by;

  // brackets here are so buffer gets freed ASAP
  {
    std::vector<u8> buffer;
    LoadFileStateData(filename, buffer);

    if (!buffer.empty())
    {
      u8* ptr = &buffer[0];
      PointerWrap p(&ptr, PointerWrap::MODE_READ);
      version_created_by = DoState(p);
      loaded = true;
      loadedSuccessfully = (p.GetMode() == PointerWrap::MODE_READ);
    }
  }

  if (loaded)
  {
    if (loadedSuccessfully)
    {
      Core::DisplayMessage(StringFromFormat("Loaded state from %s", filename.c_str()), 2000);
      if (File::Exists(filename + ".dtm"))
        Movie::LoadInput(filename + ".dtm");
      else if (!Movie::IsJustStartingRecordingInputFromSaveState() &&
               !Movie::IsJustStartingPlayingInputFromSaveState())
        Movie::EndPlayInput(false);
    }
    else
    {
      // failed to load
      Core::DisplayMessage("Unable to load: Can't load state from other versions!", 4000);
      if (!version_created_by.empty())
        Core::DisplayMessage("The savestate was created using " + version_created_by, 4000);

      // since we could be in an inconsistent state now (and might crash or whatever), undo.
      if (g_loadDepth < 2)
        UndoLoadState();
    }
  }

  if (g_onAfterLoadCb)
    g_onAfterLoadCb();

  g_loadDepth--;

  // resume dat core
  Core::PauseAndLock(false, wasUnpaused);
}
Example #12
0
void VideoCommon_DoState(PointerWrap &p)
{
	DoState(p);
}