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:
|
||||
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 )
|
||||
{}
|
||||
};
|
||||
|
@ -96,7 +96,7 @@ namespace Exception
|
|||
BaseException( msg )
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
class OutOfMemory : public RuntimeError
|
||||
{
|
||||
public:
|
||||
|
@ -114,6 +114,16 @@ namespace Exception
|
|||
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
|
||||
// seeing these.
|
||||
class IndexBoundsFault : public LogicError
|
||||
|
@ -142,6 +152,132 @@ namespace Exception
|
|||
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
|
||||
class FreezePluginFailure : public RuntimeError
|
||||
{
|
||||
|
@ -208,96 +344,6 @@ namespace Exception
|
|||
, 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
|
||||
|
|
|
@ -30,7 +30,6 @@ s32 psxNextCounter;
|
|||
u32 psxNextsCounter;
|
||||
u8 psxhblankgate = 0;
|
||||
u8 psxvblankgate = 0;
|
||||
u8 psxcntmask = 0;
|
||||
|
||||
// flags when the gate is off or counter disabled. (do not count)
|
||||
#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));
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
Freeze(psxCounters);
|
||||
Freeze(psxNextCounter);
|
||||
Freeze(psxNextsCounter);
|
||||
|
||||
if( IsLoading() )
|
||||
psxRcntSetGates();
|
||||
}
|
||||
|
|
|
@ -98,16 +98,13 @@ void sio2_setSend3(u32 index, u32 value)
|
|||
{
|
||||
// int i;
|
||||
sio2.packet.sendArray3[index]=value;
|
||||
#ifdef PAD_LOG
|
||||
// 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.sendArray2[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");
|
||||
PAD_LOG("[%d] : 0x%08X ", index,sio2.packet.sendArray3[index]);
|
||||
PAD_LOG("\n");
|
||||
PAD_LOG("[%d] : 0x%08X\n", index,sio2.packet.sendArray3[index]);
|
||||
// }
|
||||
#endif
|
||||
} //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));
|
||||
madr++;
|
||||
if(sio2.packet.sendSize == BUFSIZE) {
|
||||
HW_DMA11_MADR = madr;
|
||||
PSX_INT(IopEvt_Dma11,(size>>2)); // Interrupts should always occur at the end
|
||||
return;
|
||||
}
|
||||
if(sio2.packet.sendSize == BUFSIZE)
|
||||
goto finished;
|
||||
}
|
||||
}
|
||||
|
||||
finished:
|
||||
HW_DMA11_MADR = madr;
|
||||
PSX_INT(IopEvt_Dma11,(size>>2)); // Interrupts should always occur at the end
|
||||
}
|
||||
|
|
140
pcsx2/Sio.cpp
140
pcsx2/Sio.cpp
|
@ -23,12 +23,12 @@
|
|||
|
||||
_sio sio;
|
||||
|
||||
static FILE * MemoryCard1, * MemoryCard2;
|
||||
static FILE * MemoryCard1=NULL, * MemoryCard2=NULL;
|
||||
|
||||
static const u8 cardh[4] = { 0xFF, 0xFF, 0x5a, 0x5d };
|
||||
|
||||
// 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
|
||||
// feeding them through the IOP's branch test. (see SIO.H for details)
|
||||
|
@ -68,8 +68,11 @@ void sioInit()
|
|||
{
|
||||
memzero_obj(sio);
|
||||
|
||||
MemoryCard1 = LoadMcd(1);
|
||||
MemoryCard2 = LoadMcd(2);
|
||||
if( MemoryCard1 == NULL )
|
||||
MemoryCard1 = LoadMcd(1);
|
||||
|
||||
if( MemoryCard2 == NULL )
|
||||
MemoryCard2 = LoadMcd(2);
|
||||
|
||||
// Transfer(?) Ready and the Buffer is Empty
|
||||
sio.StatReg = TX_RDY | TX_EMPTY;
|
||||
|
@ -81,6 +84,9 @@ void psxSIOShutdown()
|
|||
{
|
||||
if(MemoryCard1) fclose(MemoryCard1);
|
||||
if(MemoryCard2) fclose(MemoryCard2);
|
||||
|
||||
MemoryCard1 = NULL;
|
||||
MemoryCard2 = NULL;
|
||||
}
|
||||
|
||||
u8 sioRead8() {
|
||||
|
@ -538,23 +544,32 @@ void SaveState::sioFreeze()
|
|||
*************** 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;
|
||||
|
||||
if (mcd == 1) {
|
||||
strcpy(str, Config.Mcd1);
|
||||
} else {
|
||||
strcpy(str, Config.Mcd2);
|
||||
}
|
||||
if (*str == 0) sprintf(str, MEMCARDS_DIR "/Mcd00%d.ps2", mcd);
|
||||
f = fopen(str, "r+b");
|
||||
str = (mcd == 1) ? Config.Mcd1 : Config.Mcd2;
|
||||
|
||||
if( str.empty() )
|
||||
Path::Combine( str, MEMCARDS_DIR, fmt_string( "Mcd00%d.ps2", mcd ) );
|
||||
|
||||
if( !Path::Exists(str) )
|
||||
CreateMcd(str.c_str());
|
||||
|
||||
#ifdef WIN32
|
||||
NTFS_CompressFile( str.c_str() );
|
||||
#endif
|
||||
|
||||
f = fopen(str.c_str(), "r+b");
|
||||
|
||||
if (f == NULL) {
|
||||
CreateMcd(str);
|
||||
f = fopen(str, "r+b");
|
||||
}
|
||||
if (f == NULL) {
|
||||
Msgbox::Alert("Failed loading MemCard %s", params str);
|
||||
Msgbox::Alert("Failed loading MemCard from file: %hs", params &str);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -573,76 +588,51 @@ void SeekMcd(FILE *f, u32 adr) {
|
|||
fseek(f, adr, SEEK_SET);
|
||||
}
|
||||
|
||||
void ReadMcd(int mcd, u8 *data, u32 adr, int size) {
|
||||
if(mcd == 1)
|
||||
{
|
||||
if (MemoryCard1 == NULL) {
|
||||
memset(data, 0, size);
|
||||
return;
|
||||
}
|
||||
SeekMcd(MemoryCard1, adr);
|
||||
fread(data, 1, size, MemoryCard1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (MemoryCard2 == NULL) {
|
||||
memset(data, 0, size);
|
||||
return;
|
||||
}
|
||||
SeekMcd(MemoryCard2, adr);
|
||||
fread(data, 1, size, MemoryCard2);
|
||||
void ReadMcd(int mcd, u8 *data, u32 adr, int size)
|
||||
{
|
||||
FILE* const mcfp = (mcd == 1) ? MemoryCard1 : MemoryCard2;
|
||||
|
||||
if (mcfp == NULL) {
|
||||
memset(data, 0, size);
|
||||
return;
|
||||
}
|
||||
SeekMcd(mcfp, adr);
|
||||
fread(data, 1, size, mcfp);
|
||||
}
|
||||
|
||||
void SaveMcd(int mcd, const u8 *data, u32 adr, int size) {
|
||||
if(mcd == 1)
|
||||
void SaveMcd(int mcd, const u8 *data, u32 adr, int size)
|
||||
{
|
||||
FILE* const mcfp = (mcd == 1) ? MemoryCard1 : MemoryCard2;
|
||||
|
||||
SeekMcd(mcfp, adr);
|
||||
u8 *currentdata = (u8 *)malloc(size);
|
||||
fread(currentdata, 1, size, mcfp);
|
||||
for (int i=0; i<size; i++)
|
||||
{
|
||||
SeekMcd(MemoryCard1, adr);
|
||||
u8 *currentdata = (u8 *)malloc(size);
|
||||
fread(currentdata, 1, size, MemoryCard1);
|
||||
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(MemoryCard1, adr);
|
||||
fwrite(currentdata, 1, size, MemoryCard1);
|
||||
if ((currentdata[i] & data[i]) != data[i])
|
||||
Console::Notice("MemoryCard : writing odd data");
|
||||
currentdata[i] &= data[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
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);
|
||||
}
|
||||
SeekMcd(mcfp, adr);
|
||||
fwrite(currentdata, 1, size, mcfp);
|
||||
|
||||
free(currentdata);
|
||||
}
|
||||
|
||||
|
||||
void EraseMcd(int mcd, u32 adr) {
|
||||
void EraseMcd(int mcd, u32 adr)
|
||||
{
|
||||
u8 data[528*16];
|
||||
memset8_obj<0xff>(data); // clears to -1's
|
||||
if(mcd == 1)
|
||||
{
|
||||
SeekMcd(MemoryCard1, adr);
|
||||
fwrite(data, 1, 528*16, MemoryCard1);
|
||||
}
|
||||
else
|
||||
{
|
||||
SeekMcd(MemoryCard2, adr);
|
||||
fwrite(data, 1, 528*16, MemoryCard2);
|
||||
}
|
||||
|
||||
FILE* const mcfp = (mcd == 1) ? MemoryCard1 : MemoryCard2;
|
||||
SeekMcd(mcfp, adr);
|
||||
fwrite(data, 1, 528*16, mcfp);
|
||||
}
|
||||
|
||||
|
||||
void CreateMcd(char *mcd) {
|
||||
void CreateMcd(const char *mcd)
|
||||
{
|
||||
FILE *fp;
|
||||
int i=0, j=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 SaveMcd(int mcd, const u8 *data, u32 adr, int size);
|
||||
void EraseMcd(int mcd, u32 adr);
|
||||
void CreateMcd(char *mcd);
|
||||
void CreateMcd(const char *mcd);
|
||||
|
||||
struct McdBlock {
|
||||
char Title[48];
|
||||
|
|
|
@ -2594,6 +2594,10 @@
|
|||
RelativePath="..\..\ThreadTools.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\WinCompressNTFS.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\WinThreads.cpp"
|
||||
>
|
||||
|
|
|
@ -99,8 +99,22 @@ extern int g_SaveGSStream;
|
|||
|
||||
|
||||
// sets the contents of the Pcsx2 status bar...
|
||||
void StatusBar_Notice( const std::string& text );
|
||||
void StatusBar_SetMsg( const std::string& text );
|
||||
extern void StatusBar_Notice( 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
|
||||
|
||||
|
|
|
@ -757,6 +757,11 @@ bool SysInit()
|
|||
CreateDirectory(MEMCARDS_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 )
|
||||
emuLog = fopen(g_TestRun.plogname, "w");
|
||||
|
||||
|
|
Loading…
Reference in New Issue