mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-13 07:49:19 +01:00
Flushing the memory card data to the hard-drive is now being done in a separate thread. Eliminates emulation delay/hang during memory card flush.
I made this because for some reason my HD is probably failing and saving hangs the emulation for a couple of seconds (at least in SA2:B). Now everything runs smoothly. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3415 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
e8767497b5
commit
2f0c872cd2
@ -98,38 +98,62 @@ CEXIMemoryCard::CEXIMemoryCard(const std::string& _rName, const std::string& _rF
|
|||||||
WARN_LOG(EXPANSIONINTERFACE, "No memory card found. Will create new.");
|
WARN_LOG(EXPANSIONINTERFACE, "No memory card found. Will create new.");
|
||||||
Flush();
|
Flush();
|
||||||
}
|
}
|
||||||
|
flushThread = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flush memory card contents to disc
|
THREAD_RETURN innerFlush(void *pArgs)
|
||||||
void CEXIMemoryCard::Flush(bool exiting)
|
|
||||||
{
|
{
|
||||||
|
flushStruct *data = ((flushStruct *)pArgs);
|
||||||
FILE* pFile = NULL;
|
FILE* pFile = NULL;
|
||||||
pFile = fopen(m_strFilename.c_str(), "wb");
|
pFile = fopen(data->filename.c_str(), "wb");
|
||||||
|
|
||||||
if (!pFile)
|
if (!pFile)
|
||||||
{
|
{
|
||||||
std::string dir;
|
std::string dir;
|
||||||
SplitPath(m_strFilename, &dir, 0, 0);
|
SplitPath(data->filename, &dir, 0, 0);
|
||||||
if(!File::IsDirectory(dir.c_str()))
|
if(!File::IsDirectory(dir.c_str()))
|
||||||
File::CreateFullPath(dir.c_str());
|
File::CreateFullPath(dir.c_str());
|
||||||
pFile = fopen(m_strFilename.c_str(), "wb");
|
pFile = fopen(data->filename.c_str(), "wb");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pFile) // Note - pFile changed inside above if
|
if (!pFile) // Note - pFile changed inside above if
|
||||||
{
|
{
|
||||||
PanicAlert("Could not write memory card file %s.\n\n"
|
PanicAlert("Could not write memory card file %s.\n\n"
|
||||||
"Are you running Dolphin from a CD/DVD, or is the save file maybe write protected?", m_strFilename.c_str());
|
"Are you running Dolphin from a CD/DVD, or is the save file maybe write protected?", data->filename.c_str());
|
||||||
return;
|
delete data;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fwrite(memory_card_content, memory_card_size, 1, pFile);
|
fwrite(data->memcardContent, data->memcardSize, 1, pFile);
|
||||||
fclose(pFile);
|
fclose(pFile);
|
||||||
|
|
||||||
if (!exiting)
|
if (!data->bExiting)
|
||||||
{
|
Core::DisplayMessage(StringFromFormat("Wrote memory card %c contents to %s", data->memcardIndex ? 'B' : 'A',
|
||||||
Core::DisplayMessage(StringFromFormat("Wrote memory card %c contents to %s", card_index ? 'B' : 'A', m_strFilename.c_str()).c_str(), 4000);
|
data->filename.c_str()).c_str(), 4000);
|
||||||
|
|
||||||
|
delete data;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Flush memory card contents to disc
|
||||||
|
void CEXIMemoryCard::Flush(bool exiting)
|
||||||
|
{
|
||||||
|
if(flushThread)
|
||||||
|
delete flushThread;
|
||||||
|
|
||||||
|
if(!exiting)
|
||||||
|
Core::DisplayMessage(StringFromFormat("Writing to memory card %c", card_index ? 'B' : 'A'), 1000);
|
||||||
|
|
||||||
|
flushStruct *fs = new flushStruct;
|
||||||
|
fs->filename = m_strFilename;
|
||||||
|
fs->memcardContent = memory_card_content;
|
||||||
|
fs->memcardIndex = card_index;
|
||||||
|
fs->memcardSize = memory_card_size;
|
||||||
|
fs->bExiting = exiting;
|
||||||
|
|
||||||
|
flushThread = new Common::Thread(innerFlush, fs);
|
||||||
|
if(exiting)
|
||||||
|
flushThread->WaitForDeath();
|
||||||
}
|
}
|
||||||
|
|
||||||
CEXIMemoryCard::~CEXIMemoryCard()
|
CEXIMemoryCard::~CEXIMemoryCard()
|
||||||
@ -137,6 +161,9 @@ CEXIMemoryCard::~CEXIMemoryCard()
|
|||||||
Flush(true);
|
Flush(true);
|
||||||
delete [] memory_card_content;
|
delete [] memory_card_content;
|
||||||
memory_card_content = NULL;
|
memory_card_content = NULL;
|
||||||
|
if(flushThread)
|
||||||
|
delete flushThread;
|
||||||
|
flushThread = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CEXIMemoryCard::IsPresent()
|
bool CEXIMemoryCard::IsPresent()
|
||||||
|
@ -18,6 +18,15 @@
|
|||||||
#ifndef _EXI_DEVICEMEMORYCARD_H
|
#ifndef _EXI_DEVICEMEMORYCARD_H
|
||||||
#define _EXI_DEVICEMEMORYCARD_H
|
#define _EXI_DEVICEMEMORYCARD_H
|
||||||
|
|
||||||
|
// Data structure to be passed to the flushing thread.
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
bool bExiting;
|
||||||
|
std::string filename;
|
||||||
|
u8 *memcardContent;
|
||||||
|
int memcardSize, memcardIndex;
|
||||||
|
} flushStruct;
|
||||||
|
|
||||||
class CEXIMemoryCard : public IEXIDevice
|
class CEXIMemoryCard : public IEXIDevice
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -77,6 +86,8 @@ private:
|
|||||||
int memory_card_size; //! in bytes, must be power of 2.
|
int memory_card_size; //! in bytes, must be power of 2.
|
||||||
u8 *memory_card_content;
|
u8 *memory_card_content;
|
||||||
|
|
||||||
|
Common::Thread *flushThread;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void TransferByte(u8 &byte);
|
virtual void TransferByte(u8 &byte);
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user