2009-09-08 12:08:10 +00:00
|
|
|
/* PCSX2 - PS2 Emulator for PCs
|
|
|
|
* Copyright (C) 2002-2009 PCSX2 Dev Team
|
|
|
|
*
|
|
|
|
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
|
|
|
* of the GNU Lesser General Public License as published by the Free Software Found-
|
|
|
|
* ation, either version 3 of the License, or (at your option) any later version.
|
2009-02-09 21:15:56 +00:00
|
|
|
*
|
2009-09-08 12:08:10 +00:00
|
|
|
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
|
|
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
|
|
* PURPOSE. See the GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License along with PCSX2.
|
|
|
|
* If not, see <http://www.gnu.org/licenses/>.
|
2009-02-09 21:15:56 +00:00
|
|
|
*/
|
|
|
|
|
2009-09-08 12:08:10 +00:00
|
|
|
|
2009-02-09 21:15:56 +00:00
|
|
|
#include "PrecompiledHeader.h"
|
|
|
|
|
2009-03-13 06:14:08 +00:00
|
|
|
#include "IopCommon.h"
|
2009-02-09 21:15:56 +00:00
|
|
|
#include "SaveState.h"
|
|
|
|
|
2009-11-07 23:03:03 +00:00
|
|
|
//#include "CDVD/IsoFSdrv.h"
|
2009-08-16 06:26:40 +00:00
|
|
|
#include "ps2/BiosTools.h"
|
|
|
|
|
2009-02-09 21:15:56 +00:00
|
|
|
#include "VUmicro.h"
|
|
|
|
#include "VU.h"
|
|
|
|
#include "iCore.h"
|
2009-06-11 09:02:10 +00:00
|
|
|
#include "sVU_zerorec.h"
|
2009-02-09 21:15:56 +00:00
|
|
|
|
|
|
|
#include "GS.h"
|
|
|
|
#include "COP0.h"
|
|
|
|
#include "Cache.h"
|
2009-08-04 08:21:10 +00:00
|
|
|
#include "AppConfig.h"
|
2009-02-09 21:15:56 +00:00
|
|
|
|
|
|
|
using namespace R5900;
|
|
|
|
|
|
|
|
static void PreLoadPrep()
|
|
|
|
{
|
2009-03-04 11:33:45 +00:00
|
|
|
SysClearExecutionCache();
|
2009-02-09 21:15:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void PostLoadPrep()
|
|
|
|
{
|
2009-09-23 12:53:32 +00:00
|
|
|
memzero(pCache);
|
2009-02-09 21:15:56 +00:00
|
|
|
// WriteCP0Status(cpuRegs.CP0.n.Status.val);
|
|
|
|
for(int i=0; i<48; i++) MapTLB(i);
|
|
|
|
}
|
|
|
|
|
2009-09-16 17:23:02 +00:00
|
|
|
wxString SaveStateBase::GetFilename( int slot )
|
2009-02-09 21:15:56 +00:00
|
|
|
{
|
2009-07-16 09:58:17 +00:00
|
|
|
return (g_Conf->Folders.Savestates +
|
2009-05-01 02:15:18 +00:00
|
|
|
wxsFormat( L"%8.8X.%3.3d", ElfCRC, slot )).GetFullPath();
|
2009-02-09 21:15:56 +00:00
|
|
|
}
|
|
|
|
|
2009-09-16 17:23:02 +00:00
|
|
|
SaveStateBase::SaveStateBase( SafeArray<u8>& memblock ) :
|
|
|
|
m_memory( memblock )
|
|
|
|
, m_version( g_SaveVersion )
|
|
|
|
, m_idx( 0 )
|
|
|
|
, m_sectid( FreezeId_Unknown )
|
|
|
|
, m_pid( PluginId_GS )
|
|
|
|
, m_DidBios( false )
|
2009-02-09 21:15:56 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2009-09-16 17:23:02 +00:00
|
|
|
void SaveStateBase::PrepBlock( int size )
|
2009-02-09 21:15:56 +00:00
|
|
|
{
|
2009-09-16 17:23:02 +00:00
|
|
|
const int end = m_idx+size;
|
|
|
|
if( IsSaving() )
|
|
|
|
m_memory.MakeRoomFor( end );
|
|
|
|
else
|
|
|
|
{
|
2009-11-04 09:30:22 +00:00
|
|
|
if( m_memory.GetSizeInBytes() < end )
|
2009-09-16 17:23:02 +00:00
|
|
|
throw Exception::BadSavedState();
|
|
|
|
}
|
2009-02-09 21:15:56 +00:00
|
|
|
}
|
|
|
|
|
2009-09-16 17:23:02 +00:00
|
|
|
void SaveStateBase::FreezeTag( const char* src )
|
2009-03-19 04:16:24 +00:00
|
|
|
{
|
Lots of new code maintenance stuffs:
* Completely new assertion macros: pxAssert, pxAssertMsg, and pxFail, pxAssertDev (both which default to using a message). These replace *all* wxASSERT, DevAssert, and jASSUME varieties of macros. New macros borrow the best of all assertion worlds: MSVCRT, wxASSERT, and AtlAssume. :)
* Rewrote the Console namespace as a structure called IConsoleWriter, and created several varieties of ConsoleWriters for handling different states of log and console availability (should help reduce overhead of console logging nicely).
* More improvements to the PersistentThread model, using safely interlocked "Do*" style callbacks for starting and cleaning up threads.
* Fixed console logs so that they're readable in Win32 notepad again (the log writer adds CRs to naked LFs).
* Added AppInit.cpp -- contains constructor, destructor, OnInit, and command line parsing mess.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1950 96395faa-99c1-11dd-bbfe-3dabce05a288
2009-10-04 08:27:27 +00:00
|
|
|
const int allowedlen = sizeof( m_tagspace )-1;
|
|
|
|
pxAssertDev( strlen(src) < allowedlen, wxsFormat( L"Tag name exceeds the allowed length of %d chars.", allowedlen) );
|
2009-03-19 04:16:24 +00:00
|
|
|
|
2009-09-23 12:53:32 +00:00
|
|
|
memzero( m_tagspace );
|
2009-09-16 17:23:02 +00:00
|
|
|
strcpy( m_tagspace, src );
|
|
|
|
Freeze( m_tagspace );
|
|
|
|
|
|
|
|
if( strcmp( m_tagspace, src ) != 0 )
|
2009-03-19 04:16:24 +00:00
|
|
|
{
|
Lots of new code maintenance stuffs:
* Completely new assertion macros: pxAssert, pxAssertMsg, and pxFail, pxAssertDev (both which default to using a message). These replace *all* wxASSERT, DevAssert, and jASSUME varieties of macros. New macros borrow the best of all assertion worlds: MSVCRT, wxASSERT, and AtlAssume. :)
* Rewrote the Console namespace as a structure called IConsoleWriter, and created several varieties of ConsoleWriters for handling different states of log and console availability (should help reduce overhead of console logging nicely).
* More improvements to the PersistentThread model, using safely interlocked "Do*" style callbacks for starting and cleaning up threads.
* Fixed console logs so that they're readable in Win32 notepad again (the log writer adds CRs to naked LFs).
* Added AppInit.cpp -- contains constructor, destructor, OnInit, and command line parsing mess.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1950 96395faa-99c1-11dd-bbfe-3dabce05a288
2009-10-04 08:27:27 +00:00
|
|
|
pxFail( "Savestate data corruption detected while reading tag" );
|
2009-04-27 02:04:31 +00:00
|
|
|
throw Exception::BadSavedState(
|
|
|
|
// Untranslated diagnostic msg (use default msg for translation)
|
2009-10-29 13:51:49 +00:00
|
|
|
L"Savestate data corruption detected while reading tag: " + fromUTF8(src)
|
2009-04-27 02:04:31 +00:00
|
|
|
);
|
2009-03-19 04:16:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-09-16 17:23:02 +00:00
|
|
|
void SaveStateBase::FreezeBios()
|
2009-02-09 21:15:56 +00:00
|
|
|
{
|
2009-03-19 04:16:24 +00:00
|
|
|
// Check the BIOS, and issue a warning if the bios for this state
|
|
|
|
// doesn't match the bios currently being used (chances are it'll still
|
|
|
|
// work fine, but some games are very picky).
|
2009-09-16 17:23:02 +00:00
|
|
|
|
2009-09-23 12:53:32 +00:00
|
|
|
char descin[128], desccmp[128];
|
2009-04-27 02:04:31 +00:00
|
|
|
wxString descout;
|
2009-07-16 09:58:17 +00:00
|
|
|
IsBIOS( g_Conf->FullpathToBios(), descout );
|
2009-09-23 12:53:32 +00:00
|
|
|
memzero( descin );
|
|
|
|
memzero( desccmp );
|
|
|
|
|
2009-11-03 20:36:47 +00:00
|
|
|
memcpy_fast( descin, descout.ToUTF8().data(), descout.Length() );
|
|
|
|
memcpy_fast( desccmp, descout.ToUTF8().data(), descout.Length() );
|
2009-09-16 17:23:02 +00:00
|
|
|
|
|
|
|
// ... and only freeze bios info once per state, since the user msg could
|
|
|
|
// become really annoying on a corrupted state or something. (have to always
|
|
|
|
// load though, so that we advance past the duplicated info, if present)
|
|
|
|
|
|
|
|
if( IsLoading() || !m_DidBios )
|
|
|
|
Freeze( descin );
|
|
|
|
|
|
|
|
if( !m_DidBios )
|
2009-03-19 04:16:24 +00:00
|
|
|
{
|
2009-09-23 12:53:32 +00:00
|
|
|
if( memcmp( descin, desccmp, 128 ) != 0 )
|
2009-09-16 17:23:02 +00:00
|
|
|
{
|
Lots of new code maintenance stuffs:
* Completely new assertion macros: pxAssert, pxAssertMsg, and pxFail, pxAssertDev (both which default to using a message). These replace *all* wxASSERT, DevAssert, and jASSUME varieties of macros. New macros borrow the best of all assertion worlds: MSVCRT, wxASSERT, and AtlAssume. :)
* Rewrote the Console namespace as a structure called IConsoleWriter, and created several varieties of ConsoleWriters for handling different states of log and console availability (should help reduce overhead of console logging nicely).
* More improvements to the PersistentThread model, using safely interlocked "Do*" style callbacks for starting and cleaning up threads.
* Fixed console logs so that they're readable in Win32 notepad again (the log writer adds CRs to naked LFs).
* Added AppInit.cpp -- contains constructor, destructor, OnInit, and command line parsing mess.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1950 96395faa-99c1-11dd-bbfe-3dabce05a288
2009-10-04 08:27:27 +00:00
|
|
|
Console.Error(
|
2009-09-16 17:23:02 +00:00
|
|
|
"\n\tWarning: BIOS Version Mismatch, savestate may be unstable!\n"
|
|
|
|
"\t\tCurrent Version: %s\n"
|
|
|
|
"\t\tSavestate Version: %s\n",
|
2009-11-03 20:36:47 +00:00
|
|
|
descout.ToUTF8().data(), descin
|
2009-09-16 17:23:02 +00:00
|
|
|
);
|
|
|
|
}
|
2009-03-19 04:16:24 +00:00
|
|
|
}
|
2009-09-16 17:23:02 +00:00
|
|
|
m_DidBios = true;
|
|
|
|
}
|
2009-02-09 21:15:56 +00:00
|
|
|
|
2009-09-16 17:23:02 +00:00
|
|
|
static const int MainMemorySizeInBytes =
|
|
|
|
Ps2MemSize::Base + Ps2MemSize::Scratch + Ps2MemSize::Hardware +
|
|
|
|
Ps2MemSize::IopRam + Ps2MemSize::IopHardware + 0x0100;
|
|
|
|
|
|
|
|
void SaveStateBase::FreezeMainMemory()
|
|
|
|
{
|
2009-10-07 19:20:11 +00:00
|
|
|
if( IsLoading() )
|
|
|
|
PreLoadPrep();
|
|
|
|
|
2009-03-19 04:16:24 +00:00
|
|
|
// First Block - Memory Dumps
|
|
|
|
// ---------------------------
|
2009-09-16 17:23:02 +00:00
|
|
|
FreezeMem(PS2MEM_BASE, Ps2MemSize::Base); // 32 MB main memory
|
|
|
|
FreezeMem(PS2MEM_SCRATCH, Ps2MemSize::Scratch); // scratch pad
|
|
|
|
FreezeMem(PS2MEM_HW, Ps2MemSize::Hardware); // hardware memory
|
2009-02-09 21:15:56 +00:00
|
|
|
|
2009-03-19 04:16:24 +00:00
|
|
|
FreezeMem(psxM, Ps2MemSize::IopRam); // 2 MB main memory
|
|
|
|
FreezeMem(psxH, Ps2MemSize::IopHardware); // hardware memory
|
|
|
|
FreezeMem(psxS, 0x000100); // iop's sif memory
|
2009-09-16 17:23:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SaveStateBase::FreezeRegisters()
|
|
|
|
{
|
2009-10-07 19:20:11 +00:00
|
|
|
if( IsLoading() )
|
|
|
|
PreLoadPrep();
|
2009-03-19 04:16:24 +00:00
|
|
|
|
|
|
|
// Second Block - Various CPU Registers and States
|
|
|
|
// -----------------------------------------------
|
|
|
|
FreezeTag( "cpuRegs" );
|
2009-09-16 17:23:02 +00:00
|
|
|
Freeze(cpuRegs); // cpu regs + COP0
|
|
|
|
Freeze(psxRegs); // iop regs
|
2009-03-19 04:16:24 +00:00
|
|
|
Freeze(fpuRegs);
|
2009-09-16 17:23:02 +00:00
|
|
|
Freeze(tlb); // tlbs
|
2009-02-09 21:15:56 +00:00
|
|
|
|
2009-03-19 04:16:24 +00:00
|
|
|
// Third Block - Cycle Timers and Events
|
|
|
|
// -------------------------------------
|
|
|
|
FreezeTag( "Cycles" );
|
2009-02-09 21:15:56 +00:00
|
|
|
Freeze(EEsCycle);
|
|
|
|
Freeze(EEoCycle);
|
|
|
|
Freeze(g_nextBranchCycle);
|
|
|
|
Freeze(g_psxNextBranchCycle);
|
|
|
|
Freeze(s_iLastCOP0Cycle);
|
2009-02-19 22:48:05 +00:00
|
|
|
Freeze(s_iLastPERFCycle);
|
2009-02-09 21:15:56 +00:00
|
|
|
|
2009-03-19 04:16:24 +00:00
|
|
|
// Fourth Block - EE-related systems
|
|
|
|
// ---------------------------------
|
2009-09-16 17:23:02 +00:00
|
|
|
FreezeTag( "EE-Subsystems" );
|
2009-02-09 21:15:56 +00:00
|
|
|
rcntFreeze();
|
|
|
|
gsFreeze();
|
|
|
|
vuMicroFreeze();
|
|
|
|
vif0Freeze();
|
|
|
|
vif1Freeze();
|
|
|
|
sifFreeze();
|
|
|
|
ipuFreeze();
|
2009-02-20 00:39:58 +00:00
|
|
|
gifFreeze();
|
2009-03-04 13:05:06 +00:00
|
|
|
sprFreeze();
|
2009-02-09 21:15:56 +00:00
|
|
|
|
2009-03-19 04:16:24 +00:00
|
|
|
// Fifth Block - iop-related systems
|
|
|
|
// ---------------------------------
|
2009-09-16 17:23:02 +00:00
|
|
|
FreezeTag( "IOP-Subsystems" );
|
2009-03-19 04:16:24 +00:00
|
|
|
psxRcntFreeze();
|
2009-02-09 21:15:56 +00:00
|
|
|
sioFreeze();
|
2009-03-19 04:16:24 +00:00
|
|
|
sio2Freeze();
|
2009-02-09 21:15:56 +00:00
|
|
|
cdrFreeze();
|
|
|
|
cdvdFreeze();
|
|
|
|
|
|
|
|
if( IsLoading() )
|
|
|
|
PostLoadPrep();
|
|
|
|
}
|
|
|
|
|
2009-11-04 09:30:22 +00:00
|
|
|
void SaveStateBase::WritebackSectionLength( int seekpos, int sectlen, const wxChar* sectname )
|
2009-02-09 21:15:56 +00:00
|
|
|
{
|
2009-11-04 09:30:22 +00:00
|
|
|
int realsectsize = m_idx - seekpos;
|
|
|
|
if( IsSaving() )
|
|
|
|
{
|
|
|
|
// write back the section length...
|
|
|
|
*((u32*)m_memory.GetPtr(seekpos-4)) = realsectsize;
|
|
|
|
}
|
|
|
|
else // IsLoading!!
|
|
|
|
{
|
|
|
|
if( sectlen != realsectsize ) // if they don't match then we have a problem, jim.
|
|
|
|
{
|
|
|
|
throw Exception::BadSavedState( wxEmptyString,
|
|
|
|
wxsFormat( L"Invalid size encountered on section '%s'.", sectname ),
|
|
|
|
_("The savestate data is invalid or corrupted.")
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SaveStateBase::FreezeSection( int seek_section )
|
|
|
|
{
|
|
|
|
const bool isSeeking = (seek_section != FreezeId_NotSeeking );
|
|
|
|
if( IsSaving() ) pxAssertDev( !isSeeking, "Cannot seek on a saving-mode savestate stream." );
|
|
|
|
|
2009-09-16 17:23:02 +00:00
|
|
|
Freeze( m_sectid );
|
2009-11-04 09:30:22 +00:00
|
|
|
if( seek_section == m_sectid ) return false;
|
2009-02-09 21:15:56 +00:00
|
|
|
|
2009-09-16 17:23:02 +00:00
|
|
|
switch( m_sectid )
|
2009-02-09 21:15:56 +00:00
|
|
|
{
|
2009-09-16 17:23:02 +00:00
|
|
|
case FreezeId_End:
|
|
|
|
return false;
|
|
|
|
|
|
|
|
case FreezeId_Bios:
|
|
|
|
{
|
|
|
|
int sectlen = 128;
|
|
|
|
FreezeTag( "BiosVersion" );
|
|
|
|
Freeze( sectlen );
|
|
|
|
|
2009-09-23 09:53:21 +00:00
|
|
|
if( sectlen != 128 )
|
2009-09-16 17:23:02 +00:00
|
|
|
{
|
|
|
|
throw Exception::BadSavedState( wxEmptyString,
|
|
|
|
L"Invalid size encountered on BiosVersion section.",
|
|
|
|
_("The savestate data is invalid or corrupted.")
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2009-11-04 09:30:22 +00:00
|
|
|
if( isSeeking )
|
|
|
|
m_idx += sectlen;
|
|
|
|
else
|
|
|
|
FreezeBios();
|
2009-09-16 17:23:02 +00:00
|
|
|
m_sectid++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case FreezeId_Memory:
|
|
|
|
{
|
|
|
|
FreezeTag( "MainMemory" );
|
|
|
|
|
2009-09-23 09:53:21 +00:00
|
|
|
int seekpos = m_idx+4;
|
2009-09-16 17:23:02 +00:00
|
|
|
int sectlen = MainMemorySizeInBytes;
|
|
|
|
Freeze( sectlen );
|
|
|
|
if( sectlen != MainMemorySizeInBytes )
|
|
|
|
{
|
|
|
|
throw Exception::BadSavedState( wxEmptyString,
|
|
|
|
L"Invalid size encountered on MainMemory section.",
|
|
|
|
_("The savestate data is invalid or corrupted.")
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2009-11-04 09:30:22 +00:00
|
|
|
if( isSeeking )
|
|
|
|
m_idx += sectlen;
|
|
|
|
else
|
|
|
|
FreezeMainMemory();
|
|
|
|
|
2009-09-23 09:53:21 +00:00
|
|
|
int realsectsize = m_idx - seekpos;
|
Lots of new code maintenance stuffs:
* Completely new assertion macros: pxAssert, pxAssertMsg, and pxFail, pxAssertDev (both which default to using a message). These replace *all* wxASSERT, DevAssert, and jASSUME varieties of macros. New macros borrow the best of all assertion worlds: MSVCRT, wxASSERT, and AtlAssume. :)
* Rewrote the Console namespace as a structure called IConsoleWriter, and created several varieties of ConsoleWriters for handling different states of log and console availability (should help reduce overhead of console logging nicely).
* More improvements to the PersistentThread model, using safely interlocked "Do*" style callbacks for starting and cleaning up threads.
* Fixed console logs so that they're readable in Win32 notepad again (the log writer adds CRs to naked LFs).
* Added AppInit.cpp -- contains constructor, destructor, OnInit, and command line parsing mess.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1950 96395faa-99c1-11dd-bbfe-3dabce05a288
2009-10-04 08:27:27 +00:00
|
|
|
pxAssert( sectlen == realsectsize );
|
2009-09-16 17:23:02 +00:00
|
|
|
m_sectid++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case FreezeId_Registers:
|
|
|
|
{
|
|
|
|
FreezeTag( "HardwareRegisters" );
|
2009-09-23 09:53:21 +00:00
|
|
|
int seekpos = m_idx+4;
|
2009-11-04 09:30:22 +00:00
|
|
|
int sectlen = 0xdead; // gets written back over with "real" data in IsSaving() mode
|
2009-09-16 17:23:02 +00:00
|
|
|
|
2009-11-04 09:30:22 +00:00
|
|
|
Freeze( sectlen );
|
2009-09-16 17:23:02 +00:00
|
|
|
FreezeRegisters();
|
2009-11-04 09:30:22 +00:00
|
|
|
|
|
|
|
WritebackSectionLength( seekpos, sectlen, L"HardwareRegisters" );
|
2009-09-23 09:53:21 +00:00
|
|
|
m_sectid++;
|
2009-09-16 17:23:02 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case FreezeId_Plugin:
|
|
|
|
{
|
|
|
|
FreezeTag( "Plugin" );
|
2009-09-23 09:53:21 +00:00
|
|
|
int seekpos = m_idx+4;
|
2009-11-04 09:30:22 +00:00
|
|
|
int sectlen = 0xdead; // gets written back over with "real" data in IsSaving() mode
|
2009-09-23 12:53:32 +00:00
|
|
|
|
2009-11-04 09:30:22 +00:00
|
|
|
Freeze( sectlen );
|
2009-09-16 17:23:02 +00:00
|
|
|
Freeze( m_pid );
|
|
|
|
|
2009-11-04 09:30:22 +00:00
|
|
|
if( isSeeking )
|
|
|
|
m_idx += sectlen;
|
2009-09-16 17:23:02 +00:00
|
|
|
else
|
2009-11-04 09:30:22 +00:00
|
|
|
g_plugins->Freeze( (PluginsEnum_t)m_pid, *this );
|
2009-09-16 17:23:02 +00:00
|
|
|
|
2009-11-04 09:30:22 +00:00
|
|
|
WritebackSectionLength( seekpos, sectlen, L"HardwareRegisters" );
|
2009-09-16 17:23:02 +00:00
|
|
|
|
2009-11-04 09:30:22 +00:00
|
|
|
// following increments only affect Saving mode, which needs to be sure to save all
|
|
|
|
// plugins (order doesn't matter but sequential is easy enough. (ignored by Loading mode)
|
2009-09-16 17:23:02 +00:00
|
|
|
m_pid++;
|
2009-09-23 09:53:21 +00:00
|
|
|
if( m_pid >= PluginId_Count )
|
|
|
|
m_sectid = FreezeId_End;
|
2009-09-16 17:23:02 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case FreezeId_Unknown:
|
|
|
|
default:
|
Lots of new code maintenance stuffs:
* Completely new assertion macros: pxAssert, pxAssertMsg, and pxFail, pxAssertDev (both which default to using a message). These replace *all* wxASSERT, DevAssert, and jASSUME varieties of macros. New macros borrow the best of all assertion worlds: MSVCRT, wxASSERT, and AtlAssume. :)
* Rewrote the Console namespace as a structure called IConsoleWriter, and created several varieties of ConsoleWriters for handling different states of log and console availability (should help reduce overhead of console logging nicely).
* More improvements to the PersistentThread model, using safely interlocked "Do*" style callbacks for starting and cleaning up threads.
* Fixed console logs so that they're readable in Win32 notepad again (the log writer adds CRs to naked LFs).
* Added AppInit.cpp -- contains constructor, destructor, OnInit, and command line parsing mess.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1950 96395faa-99c1-11dd-bbfe-3dabce05a288
2009-10-04 08:27:27 +00:00
|
|
|
pxAssert( IsSaving() );
|
2009-09-16 17:23:02 +00:00
|
|
|
|
2009-09-23 09:53:21 +00:00
|
|
|
// Skip unknown sections with a warning log.
|
|
|
|
// Maybe it'll work! (haha?)
|
2009-09-16 17:23:02 +00:00
|
|
|
|
2009-09-23 09:53:21 +00:00
|
|
|
int size;
|
|
|
|
Freeze( m_tagspace );
|
|
|
|
Freeze( size );
|
|
|
|
m_tagspace[sizeof(m_tagspace)-1] = 0;
|
|
|
|
|
2009-10-29 13:32:40 +00:00
|
|
|
Console.Warning(
|
2009-09-23 09:53:21 +00:00
|
|
|
"Warning: Unknown tag encountered while loading savestate; going to ignore it!\n"
|
|
|
|
"\tTagname: %s, Size: %d", m_tagspace, size
|
|
|
|
);
|
|
|
|
m_idx += size;
|
2009-09-16 17:23:02 +00:00
|
|
|
break;
|
2009-02-09 21:15:56 +00:00
|
|
|
}
|
2009-09-23 09:53:21 +00:00
|
|
|
|
|
|
|
wxSafeYield( NULL );
|
|
|
|
|
2009-09-16 17:23:02 +00:00
|
|
|
return true;
|
2009-02-09 21:15:56 +00:00
|
|
|
}
|
|
|
|
|
2009-09-16 17:23:02 +00:00
|
|
|
void SaveStateBase::FreezeAll()
|
2009-02-09 21:15:56 +00:00
|
|
|
{
|
2009-11-04 09:30:22 +00:00
|
|
|
if( IsSaving() )
|
|
|
|
{
|
|
|
|
// Loading mode streams will assign these, but saving mode reads them so better
|
|
|
|
// do some setup first.
|
|
|
|
|
|
|
|
m_sectid = (int)FreezeId_End+1;
|
|
|
|
m_pid = PluginId_GS;
|
|
|
|
}
|
2009-02-09 21:15:56 +00:00
|
|
|
|
2009-09-23 09:53:21 +00:00
|
|
|
while( FreezeSection() );
|
2009-02-09 21:15:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// uncompressed to/from memory state saves implementation
|
|
|
|
|
2009-09-16 17:23:02 +00:00
|
|
|
memSavingState::memSavingState( SafeArray<u8>& save_to ) :
|
|
|
|
SaveStateBase( save_to )
|
2009-02-09 21:15:56 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2009-09-16 17:23:02 +00:00
|
|
|
// Saving of state data
|
2009-02-09 21:15:56 +00:00
|
|
|
void memSavingState::FreezeMem( void* data, int size )
|
|
|
|
{
|
2009-11-05 13:13:02 +00:00
|
|
|
m_memory.MakeRoomFor( m_idx+size );
|
|
|
|
memcpy_fast( m_memory.GetPtr(m_idx), data, size );
|
2009-10-09 15:17:53 +00:00
|
|
|
m_idx += size;
|
2009-02-09 21:15:56 +00:00
|
|
|
}
|
|
|
|
|
2009-10-09 17:28:17 +00:00
|
|
|
void memSavingState::FreezeAll()
|
|
|
|
{
|
2009-10-19 11:45:37 +00:00
|
|
|
// 90% of all savestates fit in under 45 megs (and require more than 43 megs, so might as well...)
|
2009-10-09 17:28:17 +00:00
|
|
|
m_memory.ChunkSize = ReallocThreshold;
|
|
|
|
m_memory.MakeRoomFor( MemoryBaseAllocSize );
|
|
|
|
|
|
|
|
_parent::FreezeAll();
|
|
|
|
}
|
|
|
|
|
2009-09-16 17:23:02 +00:00
|
|
|
memLoadingState::memLoadingState( const SafeArray<u8>& load_from ) :
|
|
|
|
SaveStateBase( const_cast<SafeArray<u8>&>(load_from) )
|
2009-02-09 21:15:56 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
memLoadingState::~memLoadingState() { }
|
|
|
|
|
2009-09-16 17:23:02 +00:00
|
|
|
// Loading of state data
|
2009-02-09 21:15:56 +00:00
|
|
|
void memLoadingState::FreezeMem( void* data, int size )
|
|
|
|
{
|
2009-10-09 15:17:53 +00:00
|
|
|
const u8* const src = m_memory.GetPtr(m_idx);
|
|
|
|
m_idx += size;
|
|
|
|
memcpy_fast( data, src, size );
|
2009-02-09 21:15:56 +00:00
|
|
|
}
|
2009-11-04 09:30:22 +00:00
|
|
|
|
|
|
|
bool memLoadingState::SeekToSection( PluginsEnum_t pid )
|
|
|
|
{
|
|
|
|
m_idx = 0; // start from the beginning
|
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
while( FreezeSection( FreezeId_Plugin ) );
|
|
|
|
if( m_sectid == FreezeId_End ) return false;
|
|
|
|
|
|
|
|
FreezeTag( "Plugin" );
|
|
|
|
int seekpos = m_idx + 4;
|
|
|
|
int sectlen = 0xdead;
|
|
|
|
|
|
|
|
Freeze( sectlen );
|
|
|
|
Freeze( m_pid );
|
|
|
|
|
|
|
|
} while( m_pid != pid );
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|