mirror of https://github.com/PCSX2/pcsx2.git
Added NTFS compression to the memcards folder and any memory cards used from pcsx2. Most memory cards compress exceptionally well (from 16M to 3M typically).
Also in this commit: Some minor code cleanups to sio.cpp, and added some missing setup code to the Iop Counters savestate loader; psxhblankgate and psxvblankgate weren't being re-initialized. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@456 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
b1600e57f7
commit
fcad9f8ebc
|
@ -83,7 +83,7 @@ namespace Exception
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~RuntimeError() throw() {}
|
virtual ~RuntimeError() throw() {}
|
||||||
explicit RuntimeError( const std::string& msg="An unhandled runtime error has occured, somewhere in the depths of Pcsx2's cluttered brain-matter." ) :
|
explicit RuntimeError( const std::string& msg="An unhandled runtime error has occurred, somewhere in the depths of Pcsx2's cluttered brain-matter." ) :
|
||||||
BaseException( msg )
|
BaseException( msg )
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
@ -114,6 +114,16 @@ namespace Exception
|
||||||
LogicError( msg ) {}
|
LogicError( msg ) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// This exception thrown any time an operation is attempted when an object
|
||||||
|
// is in an uninitialized state.
|
||||||
|
class InvalidArgument : public LogicError
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~InvalidArgument() throw() {}
|
||||||
|
explicit InvalidArgument( const std::string& msg="Invalid argument passed to a function." ) :
|
||||||
|
LogicError( msg ) {}
|
||||||
|
};
|
||||||
|
|
||||||
// Keep those array indexers in bounds when using the SafeArray type, or you'll be
|
// Keep those array indexers in bounds when using the SafeArray type, or you'll be
|
||||||
// seeing these.
|
// seeing these.
|
||||||
class IndexBoundsFault : public LogicError
|
class IndexBoundsFault : public LogicError
|
||||||
|
@ -142,6 +152,132 @@ namespace Exception
|
||||||
RuntimeError( msg ) {}
|
RuntimeError( msg ) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class PluginFailure : public RuntimeError
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::string plugin_name; // name of the plugin
|
||||||
|
|
||||||
|
virtual ~PluginFailure() throw() {}
|
||||||
|
explicit PluginFailure( const std::string& plugin, const std::string& msg = "A plugin encountered a critical error." ) :
|
||||||
|
RuntimeError( msg )
|
||||||
|
, plugin_name( plugin ) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class ThreadCreationError : public RuntimeError
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~ThreadCreationError() throw() {}
|
||||||
|
explicit ThreadCreationError( const std::string& msg="Thread could not be created." ) :
|
||||||
|
RuntimeError( msg ) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// This is a "special" exception that's primarily included for safe functioning in the
|
||||||
|
// Win32's ASCII API (ie, the non-Unicode one). Many of the old Win32 APIs don't support
|
||||||
|
// paths over 256 characters.
|
||||||
|
class PathTooLong : public RuntimeError
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~PathTooLong() throw() {}
|
||||||
|
explicit PathTooLong( const std::string& msg=
|
||||||
|
"A Pcsx2 pathname was too long for the system. Please move or reinstall Pcsx2 to\n"
|
||||||
|
"a location on your hard drive that has a shorter path." ) :
|
||||||
|
RuntimeError( msg ) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
// STREAMING EXCEPTIONS
|
||||||
|
|
||||||
|
// Generic stream error. Contains the name of the stream and a message.
|
||||||
|
// This exception is usually thrown via derrived classes, except in the (rare) case of a generic / unknown error.
|
||||||
|
class Stream : public RuntimeError
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::string stream_name; // name of the stream (if applicable)
|
||||||
|
|
||||||
|
virtual ~Stream() throw() {}
|
||||||
|
|
||||||
|
// copy construct!
|
||||||
|
Stream( const Stream& src ) :
|
||||||
|
RuntimeError( src.Message() )
|
||||||
|
, stream_name( src.stream_name ) {}
|
||||||
|
|
||||||
|
explicit Stream(
|
||||||
|
const std::string& objname=std::string(),
|
||||||
|
const std::string& msg="Invalid stream object" ) :
|
||||||
|
RuntimeError( msg + "\n\tFilename: " + objname )
|
||||||
|
, stream_name( objname ) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// A generic base error class for bad streams -- corrupted data, sudden closures, loss of
|
||||||
|
// connection, or anything else that would indicate a failure to read the data after the
|
||||||
|
// stream was successfully opened.
|
||||||
|
class BadStream : public Stream
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~BadStream() throw() {}
|
||||||
|
explicit BadStream(
|
||||||
|
const std::string& objname=std::string(),
|
||||||
|
const std::string& msg="Stream data is corrupted or incomplete, or the stream connection closed unexpectedly" ) :
|
||||||
|
Stream( objname, msg ) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// A generic exception for odd-ball stream creation errors.
|
||||||
|
class CreateStream : public Stream
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~CreateStream() throw() {}
|
||||||
|
explicit CreateStream(
|
||||||
|
const std::string& objname=std::string(),
|
||||||
|
const std::string& msg="Stream could not be created or opened" ) :
|
||||||
|
Stream( objname, msg ) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Exception thrown when an attempt to open a non-existent file is made.
|
||||||
|
// (this exception can also mean file permissions are invalid)
|
||||||
|
class FileNotFound : public CreateStream
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~FileNotFound() throw() {}
|
||||||
|
explicit FileNotFound(
|
||||||
|
const std::string& objname=std::string(),
|
||||||
|
const std::string& msg="File not found" ) :
|
||||||
|
CreateStream( objname, msg ) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class AccessDenied : public CreateStream
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~AccessDenied() throw() {}
|
||||||
|
explicit AccessDenied(
|
||||||
|
const std::string& objname=std::string(),
|
||||||
|
const std::string& msg="Permission denied to file or stream" ) :
|
||||||
|
CreateStream( objname, msg ) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Generic End of Stream exception (sometimes an error, and sometimes just used as a
|
||||||
|
// shortcut for manual feof checks).
|
||||||
|
class EndOfStream : public Stream
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~EndOfStream() throw() {}
|
||||||
|
explicit EndOfStream( const std::string& objname=std::string(), const std::string& msg="End of stream was encountered" ) :
|
||||||
|
Stream( objname, msg ) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
// SAVESTATE EXCEPTIONS
|
||||||
|
|
||||||
|
// Exception thrown when a corrupted or truncated savestate is encountered.
|
||||||
|
class BadSavedState : public BadStream
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~BadSavedState() throw() {}
|
||||||
|
explicit BadSavedState(
|
||||||
|
const std::string& objname=std::string(),
|
||||||
|
const std::string& msg="Savestate data is corrupted or incomplete" ) :
|
||||||
|
BadStream( objname, msg ) {}
|
||||||
|
};
|
||||||
|
|
||||||
// Exception thrown by SaveState class when a critical plugin or gzread
|
// Exception thrown by SaveState class when a critical plugin or gzread
|
||||||
class FreezePluginFailure : public RuntimeError
|
class FreezePluginFailure : public RuntimeError
|
||||||
{
|
{
|
||||||
|
@ -208,96 +344,6 @@ namespace Exception
|
||||||
, Crc_Cdvd( crc_cdvd )
|
, Crc_Cdvd( crc_cdvd )
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
class PluginFailure : public RuntimeError
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
std::string plugin_name; // name of the plugin
|
|
||||||
|
|
||||||
virtual ~PluginFailure() throw() {}
|
|
||||||
explicit PluginFailure( const std::string& plugin, const std::string& msg = "A plugin encountered a critical error." ) :
|
|
||||||
RuntimeError( msg )
|
|
||||||
, plugin_name( plugin ) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
class ThreadCreationError : public RuntimeError
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual ~ThreadCreationError() throw() {}
|
|
||||||
explicit ThreadCreationError( const std::string& msg="Thread could not be created." ) :
|
|
||||||
RuntimeError( msg ) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
// This is a "special" exception that's primarily included for safe functioning in the
|
|
||||||
// Win32's ASCII API (ie, the non-Unicode one). Many of the old Win32 APIs don't support
|
|
||||||
// paths over 256 characters.
|
|
||||||
class PathTooLong : public RuntimeError
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual ~PathTooLong() throw() {}
|
|
||||||
explicit PathTooLong( const std::string& msg=
|
|
||||||
"A Pcsx2 pathname was too long for the system. Please move or reinstall Pcsx2 to\n"
|
|
||||||
"a location on your hard drive that has a shorter path." ) :
|
|
||||||
RuntimeError( msg ) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
|
||||||
// BEGIN STREAMING EXCEPTIONS
|
|
||||||
|
|
||||||
// Generic stream error. Contains the name of the stream and a message.
|
|
||||||
// This exception is usually thrown via derrived classes, except in the (rare) case of a generic / unknown error.
|
|
||||||
class Stream : public RuntimeError
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
std::string stream_name; // name of the stream (if applicable)
|
|
||||||
|
|
||||||
virtual ~Stream() throw() {}
|
|
||||||
|
|
||||||
// copy construct!
|
|
||||||
Stream( const Stream& src ) :
|
|
||||||
RuntimeError( src.Message() )
|
|
||||||
, stream_name( src.stream_name ) {}
|
|
||||||
|
|
||||||
explicit Stream(
|
|
||||||
const std::string& objname=std::string(),
|
|
||||||
const std::string& msg="Invalid stream object" ) :
|
|
||||||
RuntimeError( msg + ": " + objname )
|
|
||||||
, stream_name( objname ) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Exception thrown when a corrupted or truncated savestate is encountered.
|
|
||||||
class BadSavedState : public Stream
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual ~BadSavedState() throw() {}
|
|
||||||
explicit BadSavedState(
|
|
||||||
const std::string& objname=std::string(),
|
|
||||||
const std::string& msg="Corrupted data or end of file encountered while loading savestate" ) :
|
|
||||||
Stream( objname, msg ) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Exception thrown when an attempt to open a non-existant file is made.
|
|
||||||
// (this exception can also mean file permissions are invalid)
|
|
||||||
class FileNotFound : public Stream
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual ~FileNotFound() throw() {}
|
|
||||||
explicit FileNotFound(
|
|
||||||
const std::string& objname=std::string(),
|
|
||||||
const std::string& msg="File not found or permission denied" ) :
|
|
||||||
Stream( objname, msg ) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Generic End of Stream exception (sometimes an error, and sometimes just used as a
|
|
||||||
// shortcut for manual feof checks).
|
|
||||||
class EndOfStream : public Stream
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual ~EndOfStream() throw() {}
|
|
||||||
explicit EndOfStream( const std::string& objname=std::string(), const std::string& msg="End of stream was encountered" ) :
|
|
||||||
Stream( objname, msg ) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -30,7 +30,6 @@ s32 psxNextCounter;
|
||||||
u32 psxNextsCounter;
|
u32 psxNextsCounter;
|
||||||
u8 psxhblankgate = 0;
|
u8 psxhblankgate = 0;
|
||||||
u8 psxvblankgate = 0;
|
u8 psxvblankgate = 0;
|
||||||
u8 psxcntmask = 0;
|
|
||||||
|
|
||||||
// flags when the gate is off or counter disabled. (do not count)
|
// flags when the gate is off or counter disabled. (do not count)
|
||||||
#define IOPCNT_STOPPED (0x10000000ul)
|
#define IOPCNT_STOPPED (0x10000000ul)
|
||||||
|
@ -718,9 +717,30 @@ u64 psxRcntCycles(int index)
|
||||||
return (u64)(psxCounters[index].count + (u32)((psxRegs.cycle - psxCounters[index].sCycleT) / psxCounters[index].rate));
|
return (u64)(psxCounters[index].count + (u32)((psxRegs.cycle - psxCounters[index].sCycleT) / psxCounters[index].rate));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void psxRcntSetGates()
|
||||||
|
{
|
||||||
|
if(psxCounters[0].mode & IOPCNT_ENABLE_GATE)
|
||||||
|
psxhblankgate |= 1;
|
||||||
|
else
|
||||||
|
psxhblankgate &= ~1;
|
||||||
|
|
||||||
|
if(psxCounters[1].mode & IOPCNT_ENABLE_GATE)
|
||||||
|
psxvblankgate |= 1<<1;
|
||||||
|
else
|
||||||
|
psxvblankgate &= ~(1<<1);
|
||||||
|
|
||||||
|
if(psxCounters[3].mode & IOPCNT_ENABLE_GATE)
|
||||||
|
psxvblankgate |= 1<<3;
|
||||||
|
else
|
||||||
|
psxvblankgate &= ~(1<<3);
|
||||||
|
}
|
||||||
|
|
||||||
void SaveState::psxRcntFreeze()
|
void SaveState::psxRcntFreeze()
|
||||||
{
|
{
|
||||||
Freeze(psxCounters);
|
Freeze(psxCounters);
|
||||||
Freeze(psxNextCounter);
|
Freeze(psxNextCounter);
|
||||||
Freeze(psxNextsCounter);
|
Freeze(psxNextsCounter);
|
||||||
|
|
||||||
|
if( IsLoading() )
|
||||||
|
psxRcntSetGates();
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,16 +98,13 @@ void sio2_setSend3(u32 index, u32 value)
|
||||||
{
|
{
|
||||||
// int i;
|
// int i;
|
||||||
sio2.packet.sendArray3[index]=value;
|
sio2.packet.sendArray3[index]=value;
|
||||||
#ifdef PAD_LOG
|
|
||||||
// if (index==15){
|
// if (index==15){
|
||||||
// for (i=0; i<4; i++){PAD_LOG("0x%08X ", sio2.packet.sendArray1[i]);}PAD_LOG("\n");
|
// for (i=0; i<4; i++){PAD_LOG("0x%08X ", sio2.packet.sendArray1[i]);}PAD_LOG("\n");
|
||||||
// for (i=0; i<4; i++){PAD_LOG("0x%08X ", sio2.packet.sendArray2[i]);}PAD_LOG("\n");
|
// for (i=0; i<4; i++){PAD_LOG("0x%08X ", sio2.packet.sendArray2[i]);}PAD_LOG("\n");
|
||||||
// for (i=0; i<8; i++){PAD_LOG("0x%08X ", sio2.packet.sendArray3[i]);}PAD_LOG("\n");
|
// for (i=0; i<8; i++){PAD_LOG("0x%08X ", sio2.packet.sendArray3[i]);}PAD_LOG("\n");
|
||||||
// for ( ; i<16; i++){PAD_LOG("0x%08X ", sio2.packet.sendArray3[i]);}PAD_LOG("\n");
|
// for ( ; i<16; i++){PAD_LOG("0x%08X ", sio2.packet.sendArray3[i]);}PAD_LOG("\n");
|
||||||
PAD_LOG("[%d] : 0x%08X ", index,sio2.packet.sendArray3[index]);
|
PAD_LOG("[%d] : 0x%08X\n", index,sio2.packet.sendArray3[index]);
|
||||||
PAD_LOG("\n");
|
|
||||||
// }
|
// }
|
||||||
#endif
|
|
||||||
} //0->15
|
} //0->15
|
||||||
|
|
||||||
u32 sio2_getSend3(u32 index) {return sio2.packet.sendArray3[index];} //0->15
|
u32 sio2_getSend3(u32 index) {return sio2.packet.sendArray3[index];} //0->15
|
||||||
|
@ -227,14 +224,12 @@ void psxDma11(u32 madr, u32 bcr, u32 chcr) {
|
||||||
{
|
{
|
||||||
sio2_fifoIn(PSXMu8(madr));
|
sio2_fifoIn(PSXMu8(madr));
|
||||||
madr++;
|
madr++;
|
||||||
if(sio2.packet.sendSize == BUFSIZE) {
|
if(sio2.packet.sendSize == BUFSIZE)
|
||||||
HW_DMA11_MADR = madr;
|
goto finished;
|
||||||
PSX_INT(IopEvt_Dma11,(size>>2)); // Interrupts should always occur at the end
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
finished:
|
||||||
HW_DMA11_MADR = madr;
|
HW_DMA11_MADR = madr;
|
||||||
PSX_INT(IopEvt_Dma11,(size>>2)); // Interrupts should always occur at the end
|
PSX_INT(IopEvt_Dma11,(size>>2)); // Interrupts should always occur at the end
|
||||||
}
|
}
|
||||||
|
|
118
pcsx2/Sio.cpp
118
pcsx2/Sio.cpp
|
@ -23,12 +23,12 @@
|
||||||
|
|
||||||
_sio sio;
|
_sio sio;
|
||||||
|
|
||||||
static FILE * MemoryCard1, * MemoryCard2;
|
static FILE * MemoryCard1=NULL, * MemoryCard2=NULL;
|
||||||
|
|
||||||
static const u8 cardh[4] = { 0xFF, 0xFF, 0x5a, 0x5d };
|
static const u8 cardh[4] = { 0xFF, 0xFF, 0x5a, 0x5d };
|
||||||
|
|
||||||
// Memory Card Specs : Sector size etc.
|
// Memory Card Specs : Sector size etc.
|
||||||
static const struct mc_command_0x26_tag mc_command_0x26= {'+', 512, 16, 0x4000, 0x52, 0x5A};
|
static const mc_command_0x26_tag mc_command_0x26= {'+', 512, 16, 0x4000, 0x52, 0x5A};
|
||||||
|
|
||||||
// SIO Inline'd IRQs : Calls the SIO interrupt handlers directly instead of
|
// SIO Inline'd IRQs : Calls the SIO interrupt handlers directly instead of
|
||||||
// feeding them through the IOP's branch test. (see SIO.H for details)
|
// feeding them through the IOP's branch test. (see SIO.H for details)
|
||||||
|
@ -68,7 +68,10 @@ void sioInit()
|
||||||
{
|
{
|
||||||
memzero_obj(sio);
|
memzero_obj(sio);
|
||||||
|
|
||||||
|
if( MemoryCard1 == NULL )
|
||||||
MemoryCard1 = LoadMcd(1);
|
MemoryCard1 = LoadMcd(1);
|
||||||
|
|
||||||
|
if( MemoryCard2 == NULL )
|
||||||
MemoryCard2 = LoadMcd(2);
|
MemoryCard2 = LoadMcd(2);
|
||||||
|
|
||||||
// Transfer(?) Ready and the Buffer is Empty
|
// Transfer(?) Ready and the Buffer is Empty
|
||||||
|
@ -81,6 +84,9 @@ void psxSIOShutdown()
|
||||||
{
|
{
|
||||||
if(MemoryCard1) fclose(MemoryCard1);
|
if(MemoryCard1) fclose(MemoryCard1);
|
||||||
if(MemoryCard2) fclose(MemoryCard2);
|
if(MemoryCard2) fclose(MemoryCard2);
|
||||||
|
|
||||||
|
MemoryCard1 = NULL;
|
||||||
|
MemoryCard2 = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 sioRead8() {
|
u8 sioRead8() {
|
||||||
|
@ -538,23 +544,32 @@ void SaveState::sioFreeze()
|
||||||
*************** MEMORY CARD SPECIFIC FUNCTIONS *****************
|
*************** MEMORY CARD SPECIFIC FUNCTIONS *****************
|
||||||
*******************************************************************
|
*******************************************************************
|
||||||
*******************************************************************/
|
*******************************************************************/
|
||||||
FILE *LoadMcd(int mcd) {
|
|
||||||
char str[g_MaxPath];
|
#ifdef WIN32
|
||||||
|
extern void NTFS_CompressFile( const char* file );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
FILE *LoadMcd(int mcd)
|
||||||
|
{
|
||||||
|
string str;
|
||||||
FILE *f;
|
FILE *f;
|
||||||
|
|
||||||
if (mcd == 1) {
|
str = (mcd == 1) ? Config.Mcd1 : Config.Mcd2;
|
||||||
strcpy(str, Config.Mcd1);
|
|
||||||
} else {
|
if( str.empty() )
|
||||||
strcpy(str, Config.Mcd2);
|
Path::Combine( str, MEMCARDS_DIR, fmt_string( "Mcd00%d.ps2", mcd ) );
|
||||||
}
|
|
||||||
if (*str == 0) sprintf(str, MEMCARDS_DIR "/Mcd00%d.ps2", mcd);
|
if( !Path::Exists(str) )
|
||||||
f = fopen(str, "r+b");
|
CreateMcd(str.c_str());
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
NTFS_CompressFile( str.c_str() );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
f = fopen(str.c_str(), "r+b");
|
||||||
|
|
||||||
if (f == NULL) {
|
if (f == NULL) {
|
||||||
CreateMcd(str);
|
Msgbox::Alert("Failed loading MemCard from file: %hs", params &str);
|
||||||
f = fopen(str, "r+b");
|
|
||||||
}
|
|
||||||
if (f == NULL) {
|
|
||||||
Msgbox::Alert("Failed loading MemCard %s", params str);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -573,76 +588,51 @@ void SeekMcd(FILE *f, u32 adr) {
|
||||||
fseek(f, adr, SEEK_SET);
|
fseek(f, adr, SEEK_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReadMcd(int mcd, u8 *data, u32 adr, int size) {
|
void ReadMcd(int mcd, u8 *data, u32 adr, int size)
|
||||||
if(mcd == 1)
|
|
||||||
{
|
{
|
||||||
if (MemoryCard1 == NULL) {
|
FILE* const mcfp = (mcd == 1) ? MemoryCard1 : MemoryCard2;
|
||||||
|
|
||||||
|
if (mcfp == NULL) {
|
||||||
memset(data, 0, size);
|
memset(data, 0, size);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SeekMcd(MemoryCard1, adr);
|
SeekMcd(mcfp, adr);
|
||||||
fread(data, 1, size, MemoryCard1);
|
fread(data, 1, size, mcfp);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (MemoryCard2 == NULL) {
|
|
||||||
memset(data, 0, size);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
SeekMcd(MemoryCard2, adr);
|
|
||||||
fread(data, 1, size, MemoryCard2);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SaveMcd(int mcd, const u8 *data, u32 adr, int size) {
|
void SaveMcd(int mcd, const u8 *data, u32 adr, int size)
|
||||||
if(mcd == 1)
|
|
||||||
{
|
{
|
||||||
SeekMcd(MemoryCard1, adr);
|
FILE* const mcfp = (mcd == 1) ? MemoryCard1 : MemoryCard2;
|
||||||
|
|
||||||
|
SeekMcd(mcfp, adr);
|
||||||
u8 *currentdata = (u8 *)malloc(size);
|
u8 *currentdata = (u8 *)malloc(size);
|
||||||
fread(currentdata, 1, size, MemoryCard1);
|
fread(currentdata, 1, size, mcfp);
|
||||||
for (int i=0; i<size; i++)
|
for (int i=0; i<size; i++)
|
||||||
{
|
{
|
||||||
if ((currentdata[i] & data[i]) != data[i])
|
if ((currentdata[i] & data[i]) != data[i])
|
||||||
Console::Notice("MemoryCard : writing odd data");
|
Console::Notice("MemoryCard : writing odd data");
|
||||||
currentdata[i] &= data[i];
|
currentdata[i] &= data[i];
|
||||||
}
|
}
|
||||||
SeekMcd(MemoryCard1, adr);
|
SeekMcd(mcfp, adr);
|
||||||
fwrite(currentdata, 1, size, MemoryCard1);
|
fwrite(currentdata, 1, size, mcfp);
|
||||||
}
|
|
||||||
else
|
free(currentdata);
|
||||||
{
|
|
||||||
SeekMcd(MemoryCard2, adr);
|
|
||||||
u8 *currentdata = (u8 *)malloc(size);
|
|
||||||
fread(currentdata, 1, size, MemoryCard2);
|
|
||||||
for (int i=0; i<size; i++)
|
|
||||||
{
|
|
||||||
if ((currentdata[i] & data[i]) != data[i])
|
|
||||||
Console::Notice("MemoryCard : writing odd data");
|
|
||||||
currentdata[i] &= data[i];
|
|
||||||
}
|
|
||||||
SeekMcd(MemoryCard2, adr);
|
|
||||||
fwrite(currentdata, 1, size, MemoryCard2);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void EraseMcd(int mcd, u32 adr) {
|
void EraseMcd(int mcd, u32 adr)
|
||||||
|
{
|
||||||
u8 data[528*16];
|
u8 data[528*16];
|
||||||
memset8_obj<0xff>(data); // clears to -1's
|
memset8_obj<0xff>(data); // clears to -1's
|
||||||
if(mcd == 1)
|
|
||||||
{
|
FILE* const mcfp = (mcd == 1) ? MemoryCard1 : MemoryCard2;
|
||||||
SeekMcd(MemoryCard1, adr);
|
SeekMcd(mcfp, adr);
|
||||||
fwrite(data, 1, 528*16, MemoryCard1);
|
fwrite(data, 1, 528*16, mcfp);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SeekMcd(MemoryCard2, adr);
|
|
||||||
fwrite(data, 1, 528*16, MemoryCard2);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CreateMcd(char *mcd) {
|
void CreateMcd(const char *mcd)
|
||||||
|
{
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
int i=0, j=0;
|
int i=0, j=0;
|
||||||
//int enc[16] = {0x77,0x7f,0x7f,0x77,0x7f,0x7f,0x77,0x7f,0x7f,0x77,0x7f,0x7f,0,0,0,0};
|
//int enc[16] = {0x77,0x7f,0x7f,0x77,0x7f,0x7f,0x77,0x7f,0x7f,0x77,0x7f,0x7f,0,0,0,0};
|
||||||
|
|
|
@ -101,7 +101,7 @@ FILE *LoadMcd(int mcd);
|
||||||
void ReadMcd(int mcd, u8 *data, u32 adr, int size);
|
void ReadMcd(int mcd, u8 *data, u32 adr, int size);
|
||||||
void SaveMcd(int mcd, const u8 *data, u32 adr, int size);
|
void SaveMcd(int mcd, const u8 *data, u32 adr, int size);
|
||||||
void EraseMcd(int mcd, u32 adr);
|
void EraseMcd(int mcd, u32 adr);
|
||||||
void CreateMcd(char *mcd);
|
void CreateMcd(const char *mcd);
|
||||||
|
|
||||||
struct McdBlock {
|
struct McdBlock {
|
||||||
char Title[48];
|
char Title[48];
|
||||||
|
|
|
@ -2594,6 +2594,10 @@
|
||||||
RelativePath="..\..\ThreadTools.cpp"
|
RelativePath="..\..\ThreadTools.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\WinCompressNTFS.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\WinThreads.cpp"
|
RelativePath="..\WinThreads.cpp"
|
||||||
>
|
>
|
||||||
|
|
|
@ -99,8 +99,22 @@ extern int g_SaveGSStream;
|
||||||
|
|
||||||
|
|
||||||
// sets the contents of the Pcsx2 status bar...
|
// sets the contents of the Pcsx2 status bar...
|
||||||
void StatusBar_Notice( const std::string& text );
|
extern void StatusBar_Notice( const std::string& text );
|
||||||
void StatusBar_SetMsg( const std::string& text );
|
extern void StatusBar_SetMsg( const std::string& text );
|
||||||
|
|
||||||
|
// Throws an exception based on the value returned from GetLastError.
|
||||||
|
// Performs an option return value success/fail check on hresult.
|
||||||
|
extern void StreamException_ThrowLastError( const string& streamname, HANDLE result=INVALID_HANDLE_VALUE );
|
||||||
|
|
||||||
|
// Throws an exception based on the given error code (usually taken from ANSI C's errno)
|
||||||
|
extern void StreamException_ThrowFromErrno( const string& streamname, errno_t errcode );
|
||||||
|
|
||||||
|
extern bool StreamException_LogFromErrno( const string& streamname, const char* action, errno_t result );
|
||||||
|
extern bool StreamException_LogLastError( const string& streamname, const char* action, HANDLE result=INVALID_HANDLE_VALUE );
|
||||||
|
|
||||||
|
// Sets the NTFS compression flag for a directory or file.
|
||||||
|
// This function does not operate recursively. If the given directory
|
||||||
|
extern void NTFS_CompressFile( const char* file );
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -757,6 +757,11 @@ bool SysInit()
|
||||||
CreateDirectory(MEMCARDS_DIR, NULL);
|
CreateDirectory(MEMCARDS_DIR, NULL);
|
||||||
CreateDirectory(SSTATES_DIR, NULL);
|
CreateDirectory(SSTATES_DIR, NULL);
|
||||||
|
|
||||||
|
// Set the compression attribute on the Memcards folder.
|
||||||
|
// Memcards generally compress very well via NTFS compression.
|
||||||
|
|
||||||
|
NTFS_CompressFile( MEMCARDS_DIR );
|
||||||
|
|
||||||
if( IsDevBuild && emuLog == NULL && g_TestRun.plogname != NULL )
|
if( IsDevBuild && emuLog == NULL && g_TestRun.plogname != NULL )
|
||||||
emuLog = fopen(g_TestRun.plogname, "w");
|
emuLog = fopen(g_TestRun.plogname, "w");
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue