Wrapped fopen/close/read/write functions inside a simple "IOFile" class. Reading, writing, and error checking became simpler in most cases. It should be near impossible to forget to close a file now that the destructor takes care of it. (I hope this fixes Issue 3635) I have tested the functionality of most things, but it is possible I broke something. :p
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@7328 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
4f69672b2b
commit
59fd1008ca
|
@ -23,7 +23,6 @@ enum {BUF_SIZE = 32*1024};
|
||||||
|
|
||||||
WaveFileWriter::WaveFileWriter()
|
WaveFileWriter::WaveFileWriter()
|
||||||
{
|
{
|
||||||
file = NULL;
|
|
||||||
conv_buffer = 0;
|
conv_buffer = 0;
|
||||||
skip_silence = false;
|
skip_silence = false;
|
||||||
}
|
}
|
||||||
|
@ -46,7 +45,7 @@ bool WaveFileWriter::Start(const char *filename, unsigned int HLESampleRate)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
file = fopen(filename, "wb");
|
file.Open(filename, "wb");
|
||||||
if (!file)
|
if (!file)
|
||||||
{
|
{
|
||||||
PanicAlertT("The file %s could not be opened for writing. Please check if it's already opened by another program.", filename);
|
PanicAlertT("The file %s could not be opened for writing. Please check if it's already opened by another program.", filename);
|
||||||
|
@ -73,36 +72,32 @@ bool WaveFileWriter::Start(const char *filename, unsigned int HLESampleRate)
|
||||||
Write(100 * 1000 * 1000 - 32);
|
Write(100 * 1000 * 1000 - 32);
|
||||||
|
|
||||||
// We are now at offset 44
|
// We are now at offset 44
|
||||||
if (ftello(file) != 44)
|
if (file.Tell() != 44)
|
||||||
PanicAlert("wrong offset: %lld", (long long)ftello(file));
|
PanicAlert("wrong offset: %lld", (long long)file.Tell());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WaveFileWriter::Stop()
|
void WaveFileWriter::Stop()
|
||||||
{
|
{
|
||||||
if (!file)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// u32 file_size = (u32)ftello(file);
|
// u32 file_size = (u32)ftello(file);
|
||||||
fseeko(file, 4, SEEK_SET);
|
file.Seek(4, SEEK_SET);
|
||||||
Write(audio_size + 36);
|
Write(audio_size + 36);
|
||||||
|
|
||||||
fseeko(file, 40, SEEK_SET);
|
file.Seek(40, SEEK_SET);
|
||||||
Write(audio_size);
|
Write(audio_size);
|
||||||
|
|
||||||
fclose(file);
|
file.Close();
|
||||||
file = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WaveFileWriter::Write(u32 value)
|
void WaveFileWriter::Write(u32 value)
|
||||||
{
|
{
|
||||||
fwrite(&value, 4, 1, file);
|
file.WriteArray(&value, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WaveFileWriter::Write4(const char *ptr)
|
void WaveFileWriter::Write4(const char *ptr)
|
||||||
{
|
{
|
||||||
fwrite(ptr, 4, 1, file);
|
file.WriteBytes(ptr, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WaveFileWriter::AddStereoSamples(const short *sample_data, int count)
|
void WaveFileWriter::AddStereoSamples(const short *sample_data, int count)
|
||||||
|
@ -115,7 +110,7 @@ void WaveFileWriter::AddStereoSamples(const short *sample_data, int count)
|
||||||
if (sample_data[i]) all_zero = false;
|
if (sample_data[i]) all_zero = false;
|
||||||
if (all_zero) return;
|
if (all_zero) return;
|
||||||
}
|
}
|
||||||
fwrite(sample_data, count * 4, 1, file);
|
file.WriteBytes(sample_data, count * 4);
|
||||||
audio_size += count * 4;
|
audio_size += count * 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,6 +135,6 @@ void WaveFileWriter::AddStereoSamplesBE(const short *sample_data, int count)
|
||||||
for (int i = 0; i < count * 2; i++)
|
for (int i = 0; i < count * 2; i++)
|
||||||
conv_buffer[i] = Common::swap16((u16)sample_data[i]);
|
conv_buffer[i] = Common::swap16((u16)sample_data[i]);
|
||||||
|
|
||||||
fwrite(conv_buffer, count * 4, 1, file);
|
file.WriteBytes(conv_buffer, count * 4);
|
||||||
audio_size += count * 4;
|
audio_size += count * 4;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,17 +28,19 @@
|
||||||
#ifndef _WAVEFILE_H_
|
#ifndef _WAVEFILE_H_
|
||||||
#define _WAVEFILE_H_
|
#define _WAVEFILE_H_
|
||||||
|
|
||||||
#include <stdio.h>
|
#include "FileUtil.h"
|
||||||
|
|
||||||
class WaveFileWriter
|
class WaveFileWriter
|
||||||
{
|
{
|
||||||
FILE *file;
|
File::IOFile file;
|
||||||
bool skip_silence;
|
bool skip_silence;
|
||||||
u32 audio_size;
|
u32 audio_size;
|
||||||
short *conv_buffer;
|
short *conv_buffer;
|
||||||
void Write(u32 value);
|
void Write(u32 value);
|
||||||
void Write4(const char *ptr);
|
void Write4(const char *ptr);
|
||||||
|
|
||||||
|
WaveFileWriter& operator=(const WaveFileWriter&)/* = delete*/;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
WaveFileWriter();
|
WaveFileWriter();
|
||||||
~WaveFileWriter();
|
~WaveFileWriter();
|
||||||
|
|
|
@ -27,8 +27,6 @@
|
||||||
// - Zero backwards/forwards compatibility
|
// - Zero backwards/forwards compatibility
|
||||||
// - Serialization code for anything complex has to be manually written.
|
// - Serialization code for anything complex has to be manually written.
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -189,63 +187,58 @@ public:
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Check file size
|
// Check file size
|
||||||
u64 fileSize = File::GetSize(_rFilename);
|
const u64 fileSize = File::GetSize(_rFilename);
|
||||||
u64 headerSize = sizeof(SChunkHeader);
|
static const u64 headerSize = sizeof(SChunkHeader);
|
||||||
if (fileSize < headerSize) {
|
if (fileSize < headerSize)
|
||||||
|
{
|
||||||
ERROR_LOG(COMMON,"ChunkReader: File too small");
|
ERROR_LOG(COMMON,"ChunkReader: File too small");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE* pFile = fopen(_rFilename.c_str(), "rb");
|
File::IOFile pFile(_rFilename, "rb");
|
||||||
if (!pFile) {
|
if (!pFile)
|
||||||
|
{
|
||||||
ERROR_LOG(COMMON,"ChunkReader: Can't open file for reading");
|
ERROR_LOG(COMMON,"ChunkReader: Can't open file for reading");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// read the header
|
// read the header
|
||||||
SChunkHeader header;
|
SChunkHeader header;
|
||||||
if (fread(&header, 1, headerSize, pFile) != headerSize) {
|
if (!pFile.ReadArray(&header, 1))
|
||||||
fclose(pFile);
|
{
|
||||||
ERROR_LOG(COMMON,"ChunkReader: Bad header size");
|
ERROR_LOG(COMMON,"ChunkReader: Bad header size");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check revision
|
// Check revision
|
||||||
if (header.Revision != _Revision) {
|
if (header.Revision != _Revision)
|
||||||
fclose(pFile);
|
{
|
||||||
ERROR_LOG(COMMON,"ChunkReader: Wrong file revision, got %d expected %d",
|
ERROR_LOG(COMMON,"ChunkReader: Wrong file revision, got %d expected %d",
|
||||||
header.Revision, _Revision);
|
header.Revision, _Revision);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get size
|
// get size
|
||||||
int sz = (int)(fileSize - headerSize);
|
const int sz = (int)(fileSize - headerSize);
|
||||||
if (header.ExpectedSize != sz) {
|
if (header.ExpectedSize != sz)
|
||||||
fclose(pFile);
|
{
|
||||||
ERROR_LOG(COMMON,"ChunkReader: Bad file size, got %d expected %d",
|
ERROR_LOG(COMMON,"ChunkReader: Bad file size, got %d expected %d",
|
||||||
sz, header.ExpectedSize);
|
sz, header.ExpectedSize);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// read the state
|
// read the state
|
||||||
u8* buffer = new u8[sz];
|
u8* buffer = new u8[sz];
|
||||||
if ((int)fread(buffer, 1, sz, pFile) != sz) {
|
if (!pFile.ReadBytes(buffer, sz))
|
||||||
fclose(pFile);
|
{
|
||||||
ERROR_LOG(COMMON,"ChunkReader: Error reading file");
|
ERROR_LOG(COMMON,"ChunkReader: Error reading file");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// done reading
|
|
||||||
if (fclose(pFile)) {
|
|
||||||
ERROR_LOG(COMMON,"ChunkReader: Error closing file! might be corrupted!");
|
|
||||||
// should never happen!
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
u8 *ptr = buffer;
|
u8 *ptr = buffer;
|
||||||
PointerWrap p(&ptr, PointerWrap::MODE_READ);
|
PointerWrap p(&ptr, PointerWrap::MODE_READ);
|
||||||
_class.DoState(p);
|
_class.DoState(p);
|
||||||
delete [] buffer;
|
delete[] buffer;
|
||||||
|
|
||||||
INFO_LOG(COMMON, "ChunkReader: Done loading %s" , _rFilename.c_str());
|
INFO_LOG(COMMON, "ChunkReader: Done loading %s" , _rFilename.c_str());
|
||||||
return true;
|
return true;
|
||||||
|
@ -255,11 +248,10 @@ public:
|
||||||
template<class T>
|
template<class T>
|
||||||
static bool Save(const std::string& _rFilename, int _Revision, T& _class)
|
static bool Save(const std::string& _rFilename, int _Revision, T& _class)
|
||||||
{
|
{
|
||||||
FILE* pFile;
|
|
||||||
|
|
||||||
INFO_LOG(COMMON, "ChunkReader: Writing %s" , _rFilename.c_str());
|
INFO_LOG(COMMON, "ChunkReader: Writing %s" , _rFilename.c_str());
|
||||||
pFile = fopen(_rFilename.c_str(), "wb");
|
File::IOFile pFile(_rFilename, "wb");
|
||||||
if (!pFile) {
|
if (!pFile)
|
||||||
|
{
|
||||||
ERROR_LOG(COMMON,"ChunkReader: Error opening file for write");
|
ERROR_LOG(COMMON,"ChunkReader: Error opening file for write");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -281,21 +273,18 @@ public:
|
||||||
header.ExpectedSize = (int)sz;
|
header.ExpectedSize = (int)sz;
|
||||||
|
|
||||||
// Write to file
|
// Write to file
|
||||||
if (fwrite(&header, sizeof(SChunkHeader), 1, pFile) != 1) {
|
if (!pFile.WriteArray(&header, 1))
|
||||||
|
{
|
||||||
ERROR_LOG(COMMON,"ChunkReader: Failed writing header");
|
ERROR_LOG(COMMON,"ChunkReader: Failed writing header");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fwrite(buffer, sz, 1, pFile) != 1) {
|
if (!pFile.WriteBytes(buffer, sz))
|
||||||
|
{
|
||||||
ERROR_LOG(COMMON,"ChunkReader: Failed writing data");
|
ERROR_LOG(COMMON,"ChunkReader: Failed writing data");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fclose(pFile)) {
|
|
||||||
ERROR_LOG(COMMON,"ChunkReader: Error closing file! might be corrupted!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
INFO_LOG(COMMON,"ChunkReader: Done writing %s",
|
INFO_LOG(COMMON,"ChunkReader: Done writing %s",
|
||||||
_rFilename.c_str());
|
_rFilename.c_str());
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -700,4 +700,108 @@ bool ReadFileToString(bool text_file, const char *filename, std::string &str)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IOFile::IOFile()
|
||||||
|
: m_file(NULL), m_good(true)
|
||||||
|
{}
|
||||||
|
|
||||||
|
IOFile::IOFile(std::FILE* file)
|
||||||
|
: m_file(file), m_good(true)
|
||||||
|
{}
|
||||||
|
|
||||||
|
IOFile::IOFile(const std::string& filename, const char openmode[])
|
||||||
|
: m_file(NULL), m_good(true)
|
||||||
|
{
|
||||||
|
Open(filename, openmode);
|
||||||
|
}
|
||||||
|
|
||||||
|
IOFile::~IOFile()
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IOFile::Open(const std::string& filename, const char openmode[])
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
#ifdef _WIN32
|
||||||
|
fopen_s(&m_file, filename.c_str(), openmode);
|
||||||
|
#else
|
||||||
|
m_file = fopen(filename.c_str(), openmode);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
m_good = IsOpen();
|
||||||
|
return m_good;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IOFile::Close()
|
||||||
|
{
|
||||||
|
if (!IsOpen() || 0 != std::fclose(m_file))
|
||||||
|
m_good = false;
|
||||||
|
|
||||||
|
m_file = NULL;
|
||||||
|
return m_good;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::FILE* IOFile::ReleaseHandle()
|
||||||
|
{
|
||||||
|
std::FILE* const ret = m_file;
|
||||||
|
m_file = NULL;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IOFile::SetHandle(std::FILE* file)
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
Clear();
|
||||||
|
m_file = file;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 IOFile::GetSize()
|
||||||
|
{
|
||||||
|
if (IsOpen())
|
||||||
|
return File::GetSize(m_file);
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IOFile::Seek(s64 off, int origin)
|
||||||
|
{
|
||||||
|
if (!IsOpen() || 0 != fseeko(m_file, off, origin))
|
||||||
|
m_good = false;
|
||||||
|
|
||||||
|
return m_good;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 IOFile::Tell()
|
||||||
|
{
|
||||||
|
if (IsOpen())
|
||||||
|
return ftello(m_file);
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IOFile::Flush()
|
||||||
|
{
|
||||||
|
if (!IsOpen() || 0 != std::fflush(m_file))
|
||||||
|
m_good = false;
|
||||||
|
|
||||||
|
return m_good;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IOFile::Resize(u64 size)
|
||||||
|
{
|
||||||
|
if (!IsOpen() || 0 !=
|
||||||
|
#ifdef _WIN32
|
||||||
|
// ector: _chsize sucks, not 64-bit safe
|
||||||
|
// F|RES: changed to _chsize_s. i think it is 64-bit safe
|
||||||
|
_chsize_s(_fileno(m_file), size)
|
||||||
|
#else
|
||||||
|
// TODO: handle 64bit and growing
|
||||||
|
ftruncate(fileno(m_file), size)
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
m_good = false;
|
||||||
|
|
||||||
|
return m_good;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
#ifndef _FILEUTIL_H_
|
#ifndef _FILEUTIL_H_
|
||||||
#define _FILEUTIL_H_
|
#define _FILEUTIL_H_
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <cstdio>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -140,6 +142,77 @@ std::string GetBundleDirectory();
|
||||||
bool WriteStringToFile(bool text_file, const std::string &str, const char *filename);
|
bool WriteStringToFile(bool text_file, const std::string &str, const char *filename);
|
||||||
bool ReadFileToString(bool text_file, const char *filename, std::string &str);
|
bool ReadFileToString(bool text_file, const char *filename, std::string &str);
|
||||||
|
|
||||||
|
// simple wrapper for cstdlib file functions to
|
||||||
|
// hopefully will make error checking easier
|
||||||
|
// and make forgetting an fclose() harder
|
||||||
|
class IOFile : NonCopyable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IOFile();
|
||||||
|
IOFile(std::FILE* file);
|
||||||
|
IOFile(const std::string& filename, const char openmode[]);
|
||||||
|
|
||||||
|
~IOFile();
|
||||||
|
|
||||||
|
bool Open(const std::string& filename, const char openmode[]);
|
||||||
|
bool Close();
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool ReadArray(T* data, size_t length)
|
||||||
|
{
|
||||||
|
if (!IsOpen() || length != std::fread(data, sizeof(T), length, m_file))
|
||||||
|
m_good = false;
|
||||||
|
|
||||||
|
return m_good;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool WriteArray(const T* data, size_t length)
|
||||||
|
{
|
||||||
|
if (!IsOpen() || length != std::fwrite(data, sizeof(T), length, m_file))
|
||||||
|
m_good = false;
|
||||||
|
|
||||||
|
return m_good;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ReadBytes(void* data, size_t length)
|
||||||
|
{
|
||||||
|
return ReadArray(reinterpret_cast<char*>(data), length);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WriteBytes(const void* data, size_t length)
|
||||||
|
{
|
||||||
|
return WriteArray(reinterpret_cast<const char*>(data), length);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsOpen() { return NULL != m_file; }
|
||||||
|
|
||||||
|
// m_good is set to false when a read, write or other function fails
|
||||||
|
bool IsGood() { return m_good; }
|
||||||
|
operator void*() { return m_good ? m_file : NULL; }
|
||||||
|
|
||||||
|
std::FILE* ReleaseHandle();
|
||||||
|
|
||||||
|
std::FILE* GetHandle() { return m_file; }
|
||||||
|
|
||||||
|
void SetHandle(std::FILE* file);
|
||||||
|
|
||||||
|
bool Seek(s64 off, int origin);
|
||||||
|
u64 Tell();
|
||||||
|
u64 GetSize();
|
||||||
|
bool Resize(u64 size);
|
||||||
|
bool Flush();
|
||||||
|
|
||||||
|
// clear error state
|
||||||
|
void Clear() { m_good = true; std::clearerr(m_file); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
IOFile& operator=(const IOFile&) /*= delete*/;
|
||||||
|
|
||||||
|
std::FILE* m_file;
|
||||||
|
bool m_good;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -83,7 +83,7 @@ LogManager::LogManager()
|
||||||
m_Log[LogTypes::MEMCARD_MANAGER] = new LogContainer("MemCard Manager", "MemCard Manager");
|
m_Log[LogTypes::MEMCARD_MANAGER] = new LogContainer("MemCard Manager", "MemCard Manager");
|
||||||
m_Log[LogTypes::NETPLAY] = new LogContainer("NETPLAY", "Netplay");
|
m_Log[LogTypes::NETPLAY] = new LogContainer("NETPLAY", "Netplay");
|
||||||
|
|
||||||
m_fileLog = new FileLogListener(File::GetUserPath(F_MAINLOG_IDX));
|
m_fileLog = new FileLogListener(File::GetUserPath(F_MAINLOG_IDX).c_str());
|
||||||
m_consoleLog = new ConsoleListener();
|
m_consoleLog = new ConsoleListener();
|
||||||
|
|
||||||
for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; ++i) {
|
for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; ++i) {
|
||||||
|
@ -176,21 +176,16 @@ void LogContainer::trigger(LogTypes::LOG_LEVELS level, const char *msg) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FileLogListener::FileLogListener(std::string filename) {
|
FileLogListener::FileLogListener(const char *filename)
|
||||||
m_filename = filename;
|
{
|
||||||
m_logfile = fopen(filename.c_str(), "a+");
|
m_logfile.open(filename, std::ios::app);
|
||||||
setEnable(true);
|
setEnable(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
FileLogListener::~FileLogListener() {
|
void FileLogListener::Log(LogTypes::LOG_LEVELS, const char *msg)
|
||||||
if (m_logfile)
|
{
|
||||||
fclose(m_logfile);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileLogListener::Log(LogTypes::LOG_LEVELS, const char *msg) {
|
|
||||||
if (!m_enable || !isValid())
|
if (!m_enable || !isValid())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
fwrite(msg, strlen(msg) * sizeof(char), 1, m_logfile);
|
m_logfile << msg << std::flush;
|
||||||
fflush(m_logfile);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,10 +21,10 @@
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "StringUtil.h"
|
#include "StringUtil.h"
|
||||||
#include "Thread.h"
|
#include "Thread.h"
|
||||||
|
#include "FileUtil.h"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#define MAX_MESSAGES 8000
|
#define MAX_MESSAGES 8000
|
||||||
#define MAX_MSGLEN 1024
|
#define MAX_MSGLEN 1024
|
||||||
|
@ -40,8 +40,7 @@ public:
|
||||||
|
|
||||||
class FileLogListener : public LogListener {
|
class FileLogListener : public LogListener {
|
||||||
public:
|
public:
|
||||||
FileLogListener(std::string filename);
|
FileLogListener(const char *filename);
|
||||||
~FileLogListener();
|
|
||||||
|
|
||||||
void Log(LogTypes::LOG_LEVELS, const char *msg);
|
void Log(LogTypes::LOG_LEVELS, const char *msg);
|
||||||
|
|
||||||
|
@ -60,8 +59,7 @@ public:
|
||||||
const char *getName() const { return "file"; }
|
const char *getName() const { return "file"; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string m_filename;
|
std::ofstream m_logfile;
|
||||||
FILE *m_logfile;
|
|
||||||
bool m_enable;
|
bool m_enable;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -52,20 +52,14 @@ std::string CreateTitleContentPath(u64 _titleID)
|
||||||
|
|
||||||
bool CheckTitleTMD(u64 _titleID)
|
bool CheckTitleTMD(u64 _titleID)
|
||||||
{
|
{
|
||||||
std::string TitlePath;
|
const std::string TitlePath = CreateTitleContentPath(_titleID) + "/title.tmd";
|
||||||
TitlePath = CreateTitleContentPath(_titleID) + "/title.tmd";
|
|
||||||
if (File::Exists(TitlePath))
|
if (File::Exists(TitlePath))
|
||||||
{
|
{
|
||||||
FILE* pTMDFile = fopen(TitlePath.c_str(), "rb");
|
File::IOFile pTMDFile(TitlePath, "rb");
|
||||||
if(pTMDFile)
|
u64 TitleID = 0;
|
||||||
{
|
pTMDFile.Seek(0x18C, SEEK_SET);
|
||||||
u64 TitleID = 0xDEADBEEFDEADBEEFULL;
|
if (pTMDFile.ReadArray(&TitleID, 1) && _titleID == Common::swap64(TitleID))
|
||||||
fseeko(pTMDFile, 0x18C, SEEK_SET);
|
return true;
|
||||||
fread(&TitleID, 8, 1, pTMDFile);
|
|
||||||
fclose(pTMDFile);
|
|
||||||
if (_titleID == Common::swap64(TitleID))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
INFO_LOG(DISCIO, "Invalid or no tmd for title %08x %08x", (u32)(_titleID >> 32), (u32)(_titleID & 0xFFFFFFFF));
|
INFO_LOG(DISCIO, "Invalid or no tmd for title %08x %08x", (u32)(_titleID >> 32), (u32)(_titleID & 0xFFFFFFFF));
|
||||||
return false;
|
return false;
|
||||||
|
@ -73,19 +67,14 @@ bool CheckTitleTMD(u64 _titleID)
|
||||||
|
|
||||||
bool CheckTitleTIK(u64 _titleID)
|
bool CheckTitleTIK(u64 _titleID)
|
||||||
{
|
{
|
||||||
std::string TikPath = Common::CreateTicketFileName(_titleID);
|
const std::string TikPath = Common::CreateTicketFileName(_titleID);
|
||||||
if (File::Exists(TikPath))
|
if (File::Exists(TikPath))
|
||||||
{
|
{
|
||||||
FILE* pTIKFile = fopen(TikPath.c_str(), "rb");
|
File::IOFile pTIKFile(TikPath, "rb");
|
||||||
if(pTIKFile)
|
u64 TitleID = 0;
|
||||||
{
|
pTIKFile.Seek(0x1dC, SEEK_SET);
|
||||||
u64 TitleID = 0xDEADBEEFDEADBEEFULL;
|
if (pTIKFile.ReadArray(&TitleID, 1) && _titleID == Common::swap64(TitleID))
|
||||||
fseeko(pTIKFile, 0x1dC, SEEK_SET);
|
return true;
|
||||||
fread(&TitleID, 8, 1, pTIKFile);
|
|
||||||
fclose(pTIKFile);
|
|
||||||
if (_titleID == Common::swap64(TitleID))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
INFO_LOG(DISCIO, "Invalid or no tik for title %08x %08x", (u32)(_titleID >> 32), (u32)(_titleID & 0xFFFFFFFF));
|
INFO_LOG(DISCIO, "Invalid or no tik for title %08x %08x", (u32)(_titleID >> 32), (u32)(_titleID & 0xFFFFFFFF));
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -57,29 +57,32 @@ bool SysConf::LoadFromFile(const char *filename)
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
FILE* f = fopen(filename, "rb");
|
|
||||||
|
|
||||||
if (f == NULL)
|
File::IOFile f(filename, "rb");
|
||||||
return false;
|
if (f.IsOpen())
|
||||||
bool result = LoadFromFileInternal(f);
|
{
|
||||||
if (result)
|
if (LoadFromFileInternal(f.ReleaseHandle()))
|
||||||
m_Filename = filename;
|
{
|
||||||
fclose(f);
|
m_Filename = filename;
|
||||||
return result;
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SysConf::LoadFromFileInternal(FILE *f)
|
bool SysConf::LoadFromFileInternal(File::IOFile f)
|
||||||
{
|
{
|
||||||
// Fill in infos
|
// Fill in infos
|
||||||
SSysConfHeader s_Header;
|
SSysConfHeader s_Header;
|
||||||
if (fread(&s_Header.version, sizeof(s_Header.version), 1, f) != 1) return false;
|
f.ReadArray(s_Header.version, 4);
|
||||||
if (fread(&s_Header.numEntries, sizeof(s_Header.numEntries), 1, f) != 1) return false;
|
f.ReadArray(&s_Header.numEntries, 1);
|
||||||
s_Header.numEntries = Common::swap16(s_Header.numEntries) + 1;
|
s_Header.numEntries = Common::swap16(s_Header.numEntries) + 1;
|
||||||
|
|
||||||
for (u16 index = 0; index < s_Header.numEntries; index++)
|
for (u16 index = 0; index < s_Header.numEntries; index++)
|
||||||
{
|
{
|
||||||
SSysConfEntry tmpEntry;
|
SSysConfEntry tmpEntry;
|
||||||
if (fread(&tmpEntry.offset, sizeof(tmpEntry.offset), 1, f) != 1) return false;
|
f.ReadArray(&tmpEntry.offset, 1);
|
||||||
tmpEntry.offset = Common::swap16(tmpEntry.offset);
|
tmpEntry.offset = Common::swap16(tmpEntry.offset);
|
||||||
m_Entries.push_back(tmpEntry);
|
m_Entries.push_back(tmpEntry);
|
||||||
}
|
}
|
||||||
|
@ -89,52 +92,62 @@ bool SysConf::LoadFromFileInternal(FILE *f)
|
||||||
i < m_Entries.end() - 1; i++)
|
i < m_Entries.end() - 1; i++)
|
||||||
{
|
{
|
||||||
SSysConfEntry& curEntry = *i;
|
SSysConfEntry& curEntry = *i;
|
||||||
if (fseeko(f, curEntry.offset, SEEK_SET) != 0) return false;
|
f.Seek(curEntry.offset, SEEK_SET);
|
||||||
|
|
||||||
u8 description = 0;
|
u8 description = 0;
|
||||||
if (fread(&description, sizeof(description), 1, f) != 1) return false;
|
f.ReadArray(&description, 1);
|
||||||
// Data type
|
// Data type
|
||||||
curEntry.type = (SysconfType)((description & 0xe0) >> 5);
|
curEntry.type = (SysconfType)((description & 0xe0) >> 5);
|
||||||
// Length of name in bytes - 1
|
// Length of name in bytes - 1
|
||||||
curEntry.nameLength = (description & 0x1f) + 1;
|
curEntry.nameLength = (description & 0x1f) + 1;
|
||||||
// Name
|
// Name
|
||||||
if (fread(&curEntry.name, curEntry.nameLength, 1, f) != 1) return false;
|
f.ReadArray(curEntry.name, curEntry.nameLength);
|
||||||
curEntry.name[curEntry.nameLength] = '\0';
|
curEntry.name[curEntry.nameLength] = '\0';
|
||||||
// Get length of data
|
// Get length of data
|
||||||
curEntry.dataLength = 0;
|
curEntry.dataLength = 0;
|
||||||
switch (curEntry.type)
|
switch (curEntry.type)
|
||||||
{
|
{
|
||||||
case Type_BigArray:
|
case Type_BigArray:
|
||||||
if (fread(&curEntry.dataLength, 2, 1, f) != 1) return false;
|
f.ReadArray(&curEntry.dataLength, 1);
|
||||||
curEntry.dataLength = Common::swap16(curEntry.dataLength);
|
curEntry.dataLength = Common::swap16(curEntry.dataLength);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Type_SmallArray:
|
case Type_SmallArray:
|
||||||
if (fread(&curEntry.dataLength, 1, 1, f) != 1) return false;
|
{
|
||||||
|
u8 dlength = 0;
|
||||||
|
f.ReadBytes(&dlength, 1);
|
||||||
|
curEntry.dataLength = dlength;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case Type_Byte:
|
case Type_Byte:
|
||||||
case Type_Bool:
|
case Type_Bool:
|
||||||
curEntry.dataLength = 1;
|
curEntry.dataLength = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Type_Short:
|
case Type_Short:
|
||||||
curEntry.dataLength = 2;
|
curEntry.dataLength = 2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Type_Long:
|
case Type_Long:
|
||||||
curEntry.dataLength = 4;
|
curEntry.dataLength = 4;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
PanicAlertT("Unknown entry type %i in SYSCONF (%s@%x)!",
|
PanicAlertT("Unknown entry type %i in SYSCONF (%s@%x)!",
|
||||||
curEntry.type, curEntry.name, curEntry.offset);
|
curEntry.type, curEntry.name, curEntry.offset);
|
||||||
return false;
|
return false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
// Fill in the actual data
|
// Fill in the actual data
|
||||||
if (curEntry.dataLength)
|
if (curEntry.dataLength)
|
||||||
{
|
{
|
||||||
curEntry.data = new u8[curEntry.dataLength];
|
curEntry.data = new u8[curEntry.dataLength];
|
||||||
if (fread(curEntry.data, curEntry.dataLength, 1, f) != 1) return false;
|
f.ReadArray(curEntry.data, curEntry.dataLength);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return f.IsGood();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the size of the item in file
|
// Returns the size of the item in file
|
||||||
|
@ -294,88 +307,87 @@ void SysConf::GenerateSysConf()
|
||||||
m_Entries.push_back(items[i]);
|
m_Entries.push_back(items[i]);
|
||||||
|
|
||||||
File::CreateFullPath(m_FilenameDefault);
|
File::CreateFullPath(m_FilenameDefault);
|
||||||
FILE *g = fopen(m_FilenameDefault.c_str(), "wb");
|
File::IOFile g(m_FilenameDefault, "wb");
|
||||||
|
|
||||||
// Write the header and item offsets
|
// Write the header and item offsets
|
||||||
fwrite(&s_Header.version, sizeof(s_Header.version), 1, g);
|
g.WriteArray(&s_Header.version, 1);
|
||||||
fwrite(&s_Header.numEntries, sizeof(u16), 1, g);
|
g.WriteArray(&s_Header.numEntries, 1);
|
||||||
for (int i = 0; i < 27; ++i)
|
for (int i = 0; i != 27; ++i)
|
||||||
{
|
{
|
||||||
u16 tmp_offset = Common::swap16(items[i].offset);
|
const u16 tmp_offset = Common::swap16(items[i].offset);
|
||||||
fwrite(&tmp_offset, 2, 1, g);
|
g.WriteArray(&tmp_offset, 1);
|
||||||
}
|
}
|
||||||
const u16 end_data_offset = Common::swap16(current_offset);
|
const u16 end_data_offset = Common::swap16(current_offset);
|
||||||
fwrite(&end_data_offset, 2, 1, g);
|
g.WriteArray(&end_data_offset, 1);
|
||||||
|
|
||||||
// Write the items
|
// Write the items
|
||||||
const u8 null_byte = 0;
|
const u8 null_byte = 0;
|
||||||
for (int i = 0; i < 27; ++i)
|
for (int i = 0; i != 27; ++i)
|
||||||
{
|
{
|
||||||
u8 description = (items[i].type << 5) | (items[i].nameLength - 1);
|
u8 description = (items[i].type << 5) | (items[i].nameLength - 1);
|
||||||
fwrite(&description, sizeof(description), 1, g);
|
g.WriteArray(&description, 1);
|
||||||
fwrite(&items[i].name, items[i].nameLength, 1, g);
|
g.WriteArray(&items[i].name, items[i].nameLength);
|
||||||
switch (items[i].type)
|
switch (items[i].type)
|
||||||
{
|
{
|
||||||
case Type_BigArray:
|
case Type_BigArray:
|
||||||
{
|
{
|
||||||
u16 tmpDataLength = Common::swap16(items[i].dataLength);
|
const u16 tmpDataLength = Common::swap16(items[i].dataLength);
|
||||||
fwrite(&tmpDataLength, 2, 1, g);
|
g.WriteArray(&tmpDataLength, 1);
|
||||||
fwrite(items[i].data, items[i].dataLength, 1, g);
|
g.WriteBytes(items[i].data, items[i].dataLength);
|
||||||
fwrite(&null_byte, 1, 1, g);
|
g.WriteArray(&null_byte, 1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Type_SmallArray:
|
case Type_SmallArray:
|
||||||
fwrite(&items[i].dataLength, 1, 1, g);
|
g.WriteArray(&items[i].dataLength, 1);
|
||||||
fwrite(items[i].data, items[i].dataLength, 1, g);
|
g.WriteBytes(items[i].data, items[i].dataLength);
|
||||||
fwrite(&null_byte, 1, 1, g);
|
g.WriteBytes(&null_byte, 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fwrite(items[i].data, items[i].dataLength, 1, g);
|
g.WriteBytes(items[i].data, items[i].dataLength);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pad file to the correct size
|
// Pad file to the correct size
|
||||||
const u64 cur_size = File::GetSize(g);
|
const u64 cur_size = g.GetSize();
|
||||||
for (unsigned int i = 0; i < 16380 - cur_size; ++i)
|
for (unsigned int i = 0; i != 16380 - cur_size; ++i)
|
||||||
fwrite(&null_byte, 1, 1, g);
|
g.WriteBytes(&null_byte, 1);
|
||||||
|
|
||||||
// Write the footer
|
// Write the footer
|
||||||
const char footer[5] = "SCed";
|
g.WriteBytes("SCed", 4);
|
||||||
fwrite(&footer, 4, 1, g);
|
|
||||||
|
|
||||||
fclose(g);
|
|
||||||
m_Filename = m_FilenameDefault;
|
m_Filename = m_FilenameDefault;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SysConf::SaveToFile(const char *filename)
|
bool SysConf::SaveToFile(const char *filename)
|
||||||
{
|
{
|
||||||
FILE *f = fopen(filename, "r+b");
|
File::IOFile f(filename, "r+b");
|
||||||
|
|
||||||
if (f == NULL)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
for (std::vector<SSysConfEntry>::iterator i = m_Entries.begin();
|
for (std::vector<SSysConfEntry>::iterator i = m_Entries.begin();
|
||||||
i < m_Entries.end() - 1; i++)
|
i < m_Entries.end() - 1; i++)
|
||||||
{
|
{
|
||||||
// Seek to after the name of this entry
|
// Seek to after the name of this entry
|
||||||
if (fseeko(f, i->offset + i->nameLength + 1, SEEK_SET) != 0) return false;
|
f.Seek(i->offset + i->nameLength + 1, SEEK_SET);
|
||||||
|
|
||||||
// We may have to write array length value...
|
// We may have to write array length value...
|
||||||
if (i->type == Type_BigArray)
|
if (i->type == Type_BigArray)
|
||||||
{
|
{
|
||||||
u16 tmpDataLength = Common::swap16(i->dataLength);
|
const u16 tmpDataLength = Common::swap16(i->dataLength);
|
||||||
if (fwrite(&tmpDataLength, 2, 1, f) != 1) return false;
|
f.WriteArray(&tmpDataLength, 1);
|
||||||
}
|
}
|
||||||
else if (i->type == Type_SmallArray)
|
else if (i->type == Type_SmallArray)
|
||||||
{
|
{
|
||||||
if (fwrite(&i->dataLength, 1, 1, f) != 1) return false;
|
const u8 len = i->dataLength;
|
||||||
|
f.WriteArray(&len, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now write the actual data
|
// Now write the actual data
|
||||||
if (fwrite(i->data, i->dataLength, 1, f) != 1) return false;
|
f.WriteBytes(i->data, i->dataLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(f);
|
return f.IsGood();
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SysConf::Save()
|
bool SysConf::Save()
|
||||||
|
|
|
@ -179,7 +179,7 @@ public:
|
||||||
bool Reload();
|
bool Reload();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool LoadFromFileInternal(FILE *f);
|
bool LoadFromFileInternal(File::IOFile f);
|
||||||
void GenerateSysConf();
|
void GenerateSysConf();
|
||||||
void Clear();
|
void Clear();
|
||||||
|
|
||||||
|
|
|
@ -205,16 +205,16 @@ bool CBoot::SetupWiiMemory(unsigned int _CountryCode)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE* pTmp = fopen(filename.c_str(), "rb");
|
{
|
||||||
|
File::IOFile pTmp(filename, "rb");
|
||||||
if (!pTmp)
|
if (!pTmp)
|
||||||
{
|
{
|
||||||
PanicAlertT("SetupWiiMem: Cant find setting file");
|
PanicAlertT("SetupWiiMem: Cant find setting file");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
fread(Memory::GetPointer(0x3800), 256, 1, pTmp);
|
pTmp.ReadBytes(Memory::GetPointer(0x3800), 256);
|
||||||
fclose(pTmp);
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Set hardcoded global variables to Wii memory. These are partly collected from
|
Set hardcoded global variables to Wii memory. These are partly collected from
|
||||||
|
|
|
@ -29,15 +29,16 @@ CDolLoader::CDolLoader(u8* _pBuffer, u32 _Size)
|
||||||
CDolLoader::CDolLoader(const char* _szFilename)
|
CDolLoader::CDolLoader(const char* _szFilename)
|
||||||
: m_isWii(false)
|
: m_isWii(false)
|
||||||
{
|
{
|
||||||
u64 size = File::GetSize(_szFilename);
|
const u64 size = File::GetSize(_szFilename);
|
||||||
u8* tmpBuffer = new u8[(size_t)size];
|
u8* const tmpBuffer = new u8[(size_t)size];
|
||||||
|
|
||||||
FILE* pStream = fopen(_szFilename, "rb");
|
{
|
||||||
fread(tmpBuffer, (size_t)size, 1, pStream);
|
File::IOFile pStream(_szFilename, "rb");
|
||||||
fclose(pStream);
|
pStream.ReadBytes(tmpBuffer, (size_t)size);
|
||||||
|
}
|
||||||
|
|
||||||
Initialize(tmpBuffer, (u32)size);
|
Initialize(tmpBuffer, (u32)size);
|
||||||
delete [] tmpBuffer;
|
delete[] tmpBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
CDolLoader::~CDolLoader()
|
CDolLoader::~CDolLoader()
|
||||||
|
|
|
@ -27,11 +27,14 @@ bool CBoot::IsElfWii(const char *filename)
|
||||||
{
|
{
|
||||||
/* We already check if filename existed before we called this function, so
|
/* We already check if filename existed before we called this function, so
|
||||||
there is no need for another check, just read the file right away */
|
there is no need for another check, just read the file right away */
|
||||||
FILE *f = fopen(filename, "rb");
|
|
||||||
u64 filesize = File::GetSize(f);
|
const u64 filesize = File::GetSize(filename);
|
||||||
u8 *mem = new u8[(size_t)filesize];
|
u8 *const mem = new u8[(size_t)filesize];
|
||||||
fread(mem, 1, (size_t)filesize, f);
|
|
||||||
fclose(f);
|
{
|
||||||
|
File::IOFile f(filename, "rb");
|
||||||
|
f.ReadBytes(mem, (size_t)filesize);
|
||||||
|
}
|
||||||
|
|
||||||
ElfReader reader(mem);
|
ElfReader reader(mem);
|
||||||
// TODO: Find a more reliable way to distinguish.
|
// TODO: Find a more reliable way to distinguish.
|
||||||
|
@ -44,11 +47,13 @@ bool CBoot::IsElfWii(const char *filename)
|
||||||
|
|
||||||
bool CBoot::Boot_ELF(const char *filename)
|
bool CBoot::Boot_ELF(const char *filename)
|
||||||
{
|
{
|
||||||
FILE *f = fopen(filename, "rb");
|
const u64 filesize = File::GetSize(filename);
|
||||||
u64 filesize = File::GetSize(f);
|
|
||||||
u8 *mem = new u8[(size_t)filesize];
|
u8 *mem = new u8[(size_t)filesize];
|
||||||
fread(mem, 1, (size_t)filesize, f);
|
|
||||||
fclose(f);
|
{
|
||||||
|
File::IOFile f(filename, "rb");
|
||||||
|
f.ReadBytes(mem, (size_t)filesize);
|
||||||
|
}
|
||||||
|
|
||||||
ElfReader reader(mem);
|
ElfReader reader(mem);
|
||||||
reader.LoadInto(0x80000000);
|
reader.LoadInto(0x80000000);
|
||||||
|
|
|
@ -108,19 +108,20 @@ u64 CBoot::Install_WiiWAD(const char* _pFilename)
|
||||||
std::string TMDFileName(ContentPath);
|
std::string TMDFileName(ContentPath);
|
||||||
TMDFileName += "title.tmd";
|
TMDFileName += "title.tmd";
|
||||||
|
|
||||||
FILE* pTMDFile = fopen(TMDFileName.c_str(), "wb");
|
File::IOFile pTMDFile(TMDFileName, "wb");
|
||||||
if (pTMDFile == NULL) {
|
if (!pTMDFile)
|
||||||
|
{
|
||||||
PanicAlertT("WAD installation failed: error creating %s", TMDFileName.c_str());
|
PanicAlertT("WAD installation failed: error creating %s", TMDFileName.c_str());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
fwrite(ContentLoader.GetTmdHeader(), DiscIO::INANDContentLoader::TMD_HEADER_SIZE, 1, pTMDFile);
|
pTMDFile.WriteBytes(ContentLoader.GetTmdHeader(), DiscIO::INANDContentLoader::TMD_HEADER_SIZE);
|
||||||
|
|
||||||
for (u32 i = 0; i < ContentLoader.GetContentSize(); i++)
|
for (u32 i = 0; i < ContentLoader.GetContentSize(); i++)
|
||||||
{
|
{
|
||||||
DiscIO::SNANDContent Content = ContentLoader.GetContent()[i];
|
DiscIO::SNANDContent Content = ContentLoader.GetContent()[i];
|
||||||
|
|
||||||
fwrite(Content.m_Header, DiscIO::INANDContentLoader::CONTENT_HEADER_SIZE, 1, pTMDFile);
|
pTMDFile.WriteBytes(Content.m_Header, DiscIO::INANDContentLoader::CONTENT_HEADER_SIZE);
|
||||||
|
|
||||||
char APPFileName[1024];
|
char APPFileName[1024];
|
||||||
if (Content.m_Type & 0x8000) //shared
|
if (Content.m_Type & 0x8000) //shared
|
||||||
|
@ -136,15 +137,14 @@ u64 CBoot::Install_WiiWAD(const char* _pFilename)
|
||||||
if (!File::Exists(APPFileName))
|
if (!File::Exists(APPFileName))
|
||||||
{
|
{
|
||||||
File::CreateFullPath(APPFileName);
|
File::CreateFullPath(APPFileName);
|
||||||
FILE* pAPPFile = fopen(APPFileName, "wb");
|
File::IOFile pAPPFile(APPFileName, "wb");
|
||||||
if (pAPPFile == NULL)
|
if (!pAPPFile)
|
||||||
{
|
{
|
||||||
PanicAlertT("WAD installation failed: error creating %s", APPFileName);
|
PanicAlertT("WAD installation failed: error creating %s", APPFileName);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
fwrite(Content.m_pData, Content.m_Size, 1, pAPPFile);
|
pAPPFile.WriteBytes(Content.m_pData, Content.m_Size);
|
||||||
fclose(pAPPFile);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -152,7 +152,7 @@ u64 CBoot::Install_WiiWAD(const char* _pFilename)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(pTMDFile);
|
pTMDFile.Close();
|
||||||
|
|
||||||
//Extract and copy WAD's ticket to ticket directory
|
//Extract and copy WAD's ticket to ticket directory
|
||||||
|
|
||||||
|
@ -164,8 +164,9 @@ u64 CBoot::Install_WiiWAD(const char* _pFilename)
|
||||||
sprintf(TicketFileName, "%sticket/%08x/%08x.tik",
|
sprintf(TicketFileName, "%sticket/%08x/%08x.tik",
|
||||||
File::GetUserPath(D_WIIUSER_IDX).c_str(), TitleID_HI, TitleID_LO);
|
File::GetUserPath(D_WIIUSER_IDX).c_str(), TitleID_HI, TitleID_LO);
|
||||||
|
|
||||||
FILE* pTicketFile = fopen(TicketFileName, "wb");
|
File::IOFile pTicketFile(TicketFileName, "wb");
|
||||||
if (pTicketFile == NULL) {
|
if (!pTicketFile)
|
||||||
|
{
|
||||||
PanicAlertT("WAD installation failed: error creating %s", TicketFileName);
|
PanicAlertT("WAD installation failed: error creating %s", TicketFileName);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -173,13 +174,10 @@ u64 CBoot::Install_WiiWAD(const char* _pFilename)
|
||||||
DiscIO::WiiWAD Wad(_pFilename);
|
DiscIO::WiiWAD Wad(_pFilename);
|
||||||
if (!Wad.IsValid())
|
if (!Wad.IsValid())
|
||||||
{
|
{
|
||||||
fclose(pTicketFile);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
fwrite(Wad.GetTicket(), Wad.GetTicketSize(), 1, pTicketFile);
|
pTicketFile.WriteBytes(Wad.GetTicket(), Wad.GetTicketSize());
|
||||||
|
|
||||||
fclose(pTicketFile);
|
|
||||||
|
|
||||||
if (!DiscIO::cUIDsys::AccessInstance().AddTitle(TitleID))
|
if (!DiscIO::cUIDsys::AccessInstance().AddTitle(TitleID))
|
||||||
{
|
{
|
||||||
|
|
|
@ -104,13 +104,12 @@ void Console_Submit(const char *cmd)
|
||||||
u32 end;
|
u32 end;
|
||||||
sscanf(cmd, "%s %08x %08x %s", temp, &start, &end, filename);
|
sscanf(cmd, "%s %08x %08x %s", temp, &start, &end, filename);
|
||||||
|
|
||||||
FILE *f = fopen(filename, "wb");
|
File::IOFile f(filename, "wb");
|
||||||
for (u32 i = start; i < end; i++)
|
for (u32 i = start; i < end; i++)
|
||||||
{
|
{
|
||||||
u8 b = Memory::ReadUnchecked_U8(i);
|
u8 b = Memory::ReadUnchecked_U8(i);
|
||||||
fputc(b,f);
|
fputc(b, f.GetHandle());
|
||||||
}
|
}
|
||||||
fclose(f);
|
|
||||||
INFO_LOG(CONSOLE, "Dumped from %08x to %08x to %s",start,end,filename);
|
INFO_LOG(CONSOLE, "Dumped from %08x to %08x to %s",start,end,filename);
|
||||||
}
|
}
|
||||||
CASE("disa")
|
CASE("disa")
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "DSPHost.h"
|
#include "DSPHost.h"
|
||||||
#include "DSPAnalyzer.h"
|
#include "DSPAnalyzer.h"
|
||||||
#include "MemoryUtil.h"
|
#include "MemoryUtil.h"
|
||||||
|
#include "FileUtil.h"
|
||||||
|
|
||||||
#include "DSPHWInterface.h"
|
#include "DSPHWInterface.h"
|
||||||
#include "DSPIntUtil.h"
|
#include "DSPIntUtil.h"
|
||||||
|
@ -45,12 +46,12 @@ static std::mutex ExtIntCriticalSection;
|
||||||
|
|
||||||
static bool LoadRom(const char *fname, int size_in_words, u16 *rom)
|
static bool LoadRom(const char *fname, int size_in_words, u16 *rom)
|
||||||
{
|
{
|
||||||
FILE *pFile = fopen(fname, "rb");
|
File::IOFile pFile(fname, "rb");
|
||||||
const size_t size_in_bytes = size_in_words * sizeof(u16);
|
const size_t size_in_bytes = size_in_words * sizeof(u16);
|
||||||
if (pFile)
|
if (pFile)
|
||||||
{
|
{
|
||||||
fread(rom, 1, size_in_bytes, pFile);
|
pFile.ReadArray(rom, size_in_words);
|
||||||
fclose(pFile);
|
pFile.Close();
|
||||||
|
|
||||||
// Byteswap the rom.
|
// Byteswap the rom.
|
||||||
for (int i = 0; i < size_in_words; i++)
|
for (int i = 0; i < size_in_words; i++)
|
||||||
|
|
|
@ -50,7 +50,7 @@ DSPDisassembler::~DSPDisassembler()
|
||||||
{
|
{
|
||||||
// Some old code for logging unknown ops.
|
// Some old code for logging unknown ops.
|
||||||
std::string filename = File::GetUserPath(D_DUMPDSP_IDX) + "UnkOps.txt";
|
std::string filename = File::GetUserPath(D_DUMPDSP_IDX) + "UnkOps.txt";
|
||||||
FILE *uo = fopen(filename.c_str(), "w");
|
File::IOFile uo(filename, "w");
|
||||||
if (!uo)
|
if (!uo)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -61,18 +61,17 @@ DSPDisassembler::~DSPDisassembler()
|
||||||
if (iter->second > 0)
|
if (iter->second > 0)
|
||||||
{
|
{
|
||||||
count++;
|
count++;
|
||||||
fprintf(uo, "OP%04x\t%d", iter->first, iter->second);
|
fprintf(uo.GetHandle(), "OP%04x\t%d", iter->first, iter->second);
|
||||||
for (int j = 15; j >= 0; j--) // print op bits
|
for (int j = 15; j >= 0; j--) // print op bits
|
||||||
{
|
{
|
||||||
if ((j & 0x3) == 3)
|
if ((j & 0x3) == 3)
|
||||||
fprintf(uo, "\tb");
|
fprintf(uo.GetHandle(), "\tb");
|
||||||
fprintf(uo, "%d", (iter->first >> j) & 0x1);
|
fprintf(uo.GetHandle(), "%d", (iter->first >> j) & 0x1);
|
||||||
}
|
}
|
||||||
fprintf(uo, "\n");
|
fprintf(uo.GetHandle(), "\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fprintf(uo, "Unknown opcodes count: %d\n", count);
|
fprintf(uo.GetHandle(), "Unknown opcodes count: %d\n", count);
|
||||||
fclose(uo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DSPDisassembler::Disassemble(int start_pc, const std::vector<u16> &code, int base_addr, std::string &text)
|
bool DSPDisassembler::Disassemble(int start_pc, const std::vector<u16> &code, int base_addr, std::string &text)
|
||||||
|
@ -80,9 +79,10 @@ bool DSPDisassembler::Disassemble(int start_pc, const std::vector<u16> &code, in
|
||||||
const char *tmp1 = "tmp1.bin";
|
const char *tmp1 = "tmp1.bin";
|
||||||
|
|
||||||
// First we have to dump the code to a bin file.
|
// First we have to dump the code to a bin file.
|
||||||
FILE *f = fopen(tmp1, "wb");
|
{
|
||||||
fwrite(&code[0], 1, code.size() * 2, f);
|
File::IOFile f(tmp1, "wb");
|
||||||
fclose(f);
|
f.WriteArray(&code[0], code.size());
|
||||||
|
}
|
||||||
|
|
||||||
// Run the two passes.
|
// Run the two passes.
|
||||||
return DisFile(tmp1, base_addr, 1, text) && DisFile(tmp1, base_addr, 2, text);
|
return DisFile(tmp1, base_addr, 1, text) && DisFile(tmp1, base_addr, 2, text);
|
||||||
|
@ -335,25 +335,25 @@ bool DSPDisassembler::DisOpcode(const u16 *binbuf, int base_addr, int pass, u16
|
||||||
|
|
||||||
bool DSPDisassembler::DisFile(const char* name, int base_addr, int pass, std::string &output)
|
bool DSPDisassembler::DisFile(const char* name, int base_addr, int pass, std::string &output)
|
||||||
{
|
{
|
||||||
FILE* in = fopen(name, "rb");
|
File::IOFile in(name, "rb");
|
||||||
if (in == NULL)
|
if (!in)
|
||||||
{
|
{
|
||||||
printf("gd_dis_file: No input\n");
|
printf("gd_dis_file: No input\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int size = (int)File::GetSize(in) & ~1;
|
const int size = ((int)in.GetSize() & ~1) / 2;
|
||||||
u16 *binbuf = new u16[size / 2];
|
u16 *const binbuf = new u16[size];
|
||||||
fread(binbuf, 1, size, in);
|
in.ReadArray(binbuf, size);
|
||||||
fclose(in);
|
in.Close();
|
||||||
|
|
||||||
// Actually do the disassembly.
|
// Actually do the disassembly.
|
||||||
for (u16 pc = 0; pc < (size / 2);)
|
for (u16 pc = 0; pc < size;)
|
||||||
{
|
{
|
||||||
DisOpcode(binbuf, base_addr, pass, &pc, output);
|
DisOpcode(binbuf, base_addr, pass, &pc, output);
|
||||||
if (pass == 2)
|
if (pass == 2)
|
||||||
output.append("\n");
|
output.append("\n");
|
||||||
}
|
}
|
||||||
delete [] binbuf;
|
delete[] binbuf;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,16 +24,14 @@ CDump::CDump(const char* _szFilename) :
|
||||||
m_pData(NULL),
|
m_pData(NULL),
|
||||||
m_bInit(false)
|
m_bInit(false)
|
||||||
{
|
{
|
||||||
FILE* pStream = fopen(_szFilename, "rb");
|
File::IOFile pStream(_szFilename, "rb");
|
||||||
if (pStream != NULL)
|
if (pStream)
|
||||||
{
|
{
|
||||||
m_size = (size_t)File::GetSize(pStream);
|
m_size = (size_t)pStream.GetSize();
|
||||||
|
|
||||||
m_pData = new u8[m_size];
|
m_pData = new u8[m_size];
|
||||||
|
|
||||||
fread(m_pData, m_size, 1, pStream);
|
pStream.ReadArray(m_pData, m_size);
|
||||||
|
|
||||||
fclose(pStream);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
#include "FileUtil.h"
|
||||||
|
|
||||||
// C L A S S
|
// C L A S S
|
||||||
|
|
||||||
|
@ -34,11 +34,10 @@ public:
|
||||||
m_bInit(false)
|
m_bInit(false)
|
||||||
{
|
{
|
||||||
// try to open file
|
// try to open file
|
||||||
FILE* pStream = NULL;
|
File::IOFile pStream(_szFilename, "rb");
|
||||||
fopen_s(&pStream, _szFilename, "rb");
|
|
||||||
if (pStream)
|
if (pStream)
|
||||||
{
|
{
|
||||||
fread(&m_dolheader, 1, sizeof(SDolHeader), pStream);
|
pStream.ReadArray(&m_dolheader, 1);
|
||||||
|
|
||||||
// swap memory
|
// swap memory
|
||||||
u32* p = (u32*)&m_dolheader;
|
u32* p = (u32*)&m_dolheader;
|
||||||
|
@ -52,8 +51,8 @@ public:
|
||||||
{
|
{
|
||||||
u8* pTemp = new u8[m_dolheader.textSize[i]];
|
u8* pTemp = new u8[m_dolheader.textSize[i]];
|
||||||
|
|
||||||
fseek(pStream, m_dolheader.textOffset[i], SEEK_SET);
|
pStream.Seek(m_dolheader.textOffset[i], SEEK_SET);
|
||||||
fread(pTemp, 1, m_dolheader.textSize[i], pStream);
|
pStream.ReadArray(pTemp, m_dolheader.textSize[i]);
|
||||||
|
|
||||||
for (size_t num=0; num<m_dolheader.textSize[i]; num++)
|
for (size_t num=0; num<m_dolheader.textSize[i]; num++)
|
||||||
CMemory::Write_U8(pTemp[num], m_dolheader.textAddress[i] + num);
|
CMemory::Write_U8(pTemp[num], m_dolheader.textAddress[i] + num);
|
||||||
|
@ -69,8 +68,8 @@ public:
|
||||||
{
|
{
|
||||||
u8* pTemp = new u8[m_dolheader.dataSize[i]];
|
u8* pTemp = new u8[m_dolheader.dataSize[i]];
|
||||||
|
|
||||||
fseek(pStream, m_dolheader.dataOffset[i], SEEK_SET);
|
pStream.Seek(m_dolheader.dataOffset[i], SEEK_SET);
|
||||||
fread(pTemp, 1, m_dolheader.dataSize[i], pStream);
|
pStream.ReadArray(pTemp, m_dolheader.dataSize[i]);
|
||||||
|
|
||||||
for (size_t num=0; num<m_dolheader.dataSize[i]; num++)
|
for (size_t num=0; num<m_dolheader.dataSize[i]; num++)
|
||||||
CMemory::Write_U8(pTemp[num], m_dolheader.dataAddress[i] + num);
|
CMemory::Write_U8(pTemp[num], m_dolheader.dataAddress[i] + num);
|
||||||
|
@ -79,7 +78,6 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(pStream);
|
|
||||||
m_bInit = true;
|
m_bInit = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,12 +102,8 @@ void CUCode_Rom::BootUCode()
|
||||||
char binFile[MAX_PATH];
|
char binFile[MAX_PATH];
|
||||||
sprintf(binFile, "%sDSP_UC_%08X.bin", File::GetUserPath(D_DUMPDSP_IDX).c_str(), ector_crc);
|
sprintf(binFile, "%sDSP_UC_%08X.bin", File::GetUserPath(D_DUMPDSP_IDX).c_str(), ector_crc);
|
||||||
|
|
||||||
FILE* pFile = fopen(binFile, "wb");
|
File::IOFile pFile(binFile, "wb");
|
||||||
if (pFile)
|
pFile.WriteArray((u8*)Memory::GetPointer(m_CurrentUCode.m_RAMAddress), m_CurrentUCode.m_Length);
|
||||||
{
|
|
||||||
fwrite((u8*)Memory::GetPointer(m_CurrentUCode.m_RAMAddress), m_CurrentUCode.m_Length, 1, pFile);
|
|
||||||
fclose(pFile);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DEBUG_LOG(DSPHLE, "CurrentUCode SOURCE Addr: 0x%08x", m_CurrentUCode.m_RAMAddress);
|
DEBUG_LOG(DSPHLE, "CurrentUCode SOURCE Addr: 0x%08x", m_CurrentUCode.m_RAMAddress);
|
||||||
|
|
|
@ -148,12 +148,9 @@ void IUCode::PrepareBootUCode(u32 mail)
|
||||||
char binFile[MAX_PATH];
|
char binFile[MAX_PATH];
|
||||||
sprintf(binFile, "%sDSP_UC_%08X.bin", File::GetUserPath(D_DUMPDSP_IDX).c_str(), ector_crc);
|
sprintf(binFile, "%sDSP_UC_%08X.bin", File::GetUserPath(D_DUMPDSP_IDX).c_str(), ector_crc);
|
||||||
|
|
||||||
FILE* pFile = fopen(binFile, "wb");
|
File::IOFile pFile(binFile, "wb");
|
||||||
if (pFile)
|
if (pFile)
|
||||||
{
|
pFile.WriteArray((u8*)Memory::GetPointer(m_NextUCode.iram_mram_addr), m_NextUCode.iram_size);
|
||||||
fwrite((u8*)Memory::GetPointer(m_NextUCode.iram_mram_addr), m_NextUCode.iram_size, 1, pFile);
|
|
||||||
fclose(pFile);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DEBUG_LOG(DSPHLE, "PrepareBootUCode 0x%08x", ector_crc);
|
DEBUG_LOG(DSPHLE, "PrepareBootUCode 0x%08x", ector_crc);
|
||||||
|
|
|
@ -15,11 +15,8 @@
|
||||||
// Official SVN repository and contact information can be found at
|
// Official SVN repository and contact information can be found at
|
||||||
// http://code.google.com/p/dolphin-emu/
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
#include <iostream> // I hope this doesn't break anything
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
|
|
||||||
#include "Common.h" // for Common::swap
|
#include "Common.h" // for Common::swap
|
||||||
|
#include "FileUtil.h"
|
||||||
#include "DSP/DSPCore.h"
|
#include "DSP/DSPCore.h"
|
||||||
#include "DSPLLEGlobals.h"
|
#include "DSPLLEGlobals.h"
|
||||||
|
|
||||||
|
@ -50,19 +47,17 @@ void ProfilerInit()
|
||||||
|
|
||||||
void ProfilerDump(u64 count)
|
void ProfilerDump(u64 count)
|
||||||
{
|
{
|
||||||
FILE* pFile = fopen("DSP_Prof.txt", "wt");
|
File::IOFile pFile("DSP_Prof.txt", "wt");
|
||||||
if (pFile != NULL)
|
if (pFile)
|
||||||
{
|
{
|
||||||
fprintf(pFile, "Number of DSP steps: %llu\n\n", count);
|
fprintf(pFile.GetHandle(), "Number of DSP steps: %llu\n\n", count);
|
||||||
for (int i=0; i<PROFILE_MAP_SIZE;i++)
|
for (int i=0; i<PROFILE_MAP_SIZE;i++)
|
||||||
{
|
{
|
||||||
if (g_profileMap[i] > 0)
|
if (g_profileMap[i] > 0)
|
||||||
{
|
{
|
||||||
fprintf(pFile, "0x%04X: %llu\n", i, g_profileMap[i]);
|
fprintf(pFile.GetHandle(), "0x%04X: %llu\n", i, g_profileMap[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(pFile);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,11 +35,11 @@ bool DumpDSPCode(const u8 *code_be, int size_in_bytes, u32 crc)
|
||||||
sprintf(binFile, "%sDSP_UC_%08X.bin", File::GetUserPath(D_DUMPDSP_IDX).c_str(), crc);
|
sprintf(binFile, "%sDSP_UC_%08X.bin", File::GetUserPath(D_DUMPDSP_IDX).c_str(), crc);
|
||||||
sprintf(txtFile, "%sDSP_UC_%08X.txt", File::GetUserPath(D_DUMPDSP_IDX).c_str(), crc);
|
sprintf(txtFile, "%sDSP_UC_%08X.txt", File::GetUserPath(D_DUMPDSP_IDX).c_str(), crc);
|
||||||
|
|
||||||
FILE* pFile = fopen(binFile, "wb");
|
File::IOFile pFile(binFile, "wb");
|
||||||
if (pFile)
|
if (pFile)
|
||||||
{
|
{
|
||||||
fwrite(code_be, size_in_bytes, 1, pFile);
|
pFile.WriteBytes(code_be, size_in_bytes);
|
||||||
fclose(pFile);
|
pFile.Close();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -71,17 +71,15 @@ bool DumpDSPCode(const u8 *code_be, int size_in_bytes, u32 crc)
|
||||||
bool DumpCWCode(u32 _Address, u32 _Length)
|
bool DumpCWCode(u32 _Address, u32 _Length)
|
||||||
{
|
{
|
||||||
std::string filename = File::GetUserPath(D_DUMPDSP_IDX) + "DSP_UCode.bin";
|
std::string filename = File::GetUserPath(D_DUMPDSP_IDX) + "DSP_UCode.bin";
|
||||||
FILE* pFile = fopen(filename.c_str(), "wb");
|
File::IOFile pFile(filename, "wb");
|
||||||
|
|
||||||
if (pFile != NULL)
|
if (pFile)
|
||||||
{
|
{
|
||||||
for (size_t i = _Address; i < _Address + _Length; i++)
|
for (size_t i = _Address; i != _Address + _Length; ++i)
|
||||||
{
|
{
|
||||||
u16 val = g_dsp.iram[i];
|
u16 val = g_dsp.iram[i];
|
||||||
fprintf(pFile, " cw 0x%04x \n", val);
|
fprintf(pFile.GetHandle(), " cw 0x%04x \n", val);
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(pFile);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,8 +15,6 @@
|
||||||
// Official SVN repository and contact information can be found at
|
// Official SVN repository and contact information can be found at
|
||||||
// http://code.google.com/p/dolphin-emu/
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
#include <iostream> // I hope this doesn't break anything
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
|
@ -25,6 +23,7 @@
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "StringUtil.h"
|
#include "StringUtil.h"
|
||||||
|
#include "FileUtil.h"
|
||||||
|
|
||||||
#include "DSP/DSPCore.h"
|
#include "DSP/DSPCore.h"
|
||||||
#include "DSPSymbols.h"
|
#include "DSPSymbols.h"
|
||||||
|
@ -121,8 +120,9 @@ void DisasssembleRange(u16 start, u16 end)
|
||||||
|
|
||||||
bool ReadAnnotatedAssembly(const char *filename)
|
bool ReadAnnotatedAssembly(const char *filename)
|
||||||
{
|
{
|
||||||
FILE *f = fopen(filename, "r");
|
File::IOFile f(filename, "r");
|
||||||
if (!f) {
|
if (!f)
|
||||||
|
{
|
||||||
ERROR_LOG(DSPLLE, "Bah! ReadAnnotatedAssembly couldn't find the file %s", filename);
|
ERROR_LOG(DSPLLE, "Bah! ReadAnnotatedAssembly couldn't find the file %s", filename);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -139,7 +139,7 @@ bool ReadAnnotatedAssembly(const char *filename)
|
||||||
int symbol_count = 0;
|
int symbol_count = 0;
|
||||||
Symbol current_symbol;
|
Symbol current_symbol;
|
||||||
|
|
||||||
while (fgets(line, 512, f))
|
while (fgets(line, 512, f.GetHandle()))
|
||||||
{
|
{
|
||||||
// Scan string for the first 4-digit hex string.
|
// Scan string for the first 4-digit hex string.
|
||||||
size_t len = strlen(line);
|
size_t len = strlen(line);
|
||||||
|
@ -225,7 +225,6 @@ bool ReadAnnotatedAssembly(const char *filename)
|
||||||
errors++;
|
errors++;
|
||||||
if (errors > 10)
|
if (errors > 10)
|
||||||
{
|
{
|
||||||
fclose(f);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -245,7 +244,7 @@ bool ReadAnnotatedAssembly(const char *filename)
|
||||||
lines.push_back(TabsToSpaces(4, line));
|
lines.push_back(TabsToSpaces(4, line));
|
||||||
line_counter++;
|
line_counter++;
|
||||||
}
|
}
|
||||||
fclose(f);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -146,13 +146,9 @@ CEXIIPL::~CEXIIPL()
|
||||||
m_pIPL = NULL;
|
m_pIPL = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// SRAM
|
// SRAM
|
||||||
FILE *file = fopen(SConfig::GetInstance().m_LocalCoreStartupParameter.m_strSRAM.c_str(), "wb");
|
File::IOFile file(SConfig::GetInstance().m_LocalCoreStartupParameter.m_strSRAM, "wb");
|
||||||
if (file)
|
file.WriteArray(&g_SRAM, 1);
|
||||||
{
|
|
||||||
fwrite(&g_SRAM, 1, 64, file);
|
|
||||||
fclose(file);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
void CEXIIPL::DoState(PointerWrap &p)
|
void CEXIIPL::DoState(PointerWrap &p)
|
||||||
{
|
{
|
||||||
|
@ -161,13 +157,12 @@ void CEXIIPL::DoState(PointerWrap &p)
|
||||||
|
|
||||||
void CEXIIPL::LoadFileToIPL(std::string filename, u32 offset)
|
void CEXIIPL::LoadFileToIPL(std::string filename, u32 offset)
|
||||||
{
|
{
|
||||||
FILE* pStream = fopen(filename.c_str(), "rb");
|
File::IOFile pStream(filename, "rb");
|
||||||
if (pStream != NULL)
|
if (pStream)
|
||||||
{
|
{
|
||||||
u64 filesize = File::GetSize(pStream);
|
u64 filesize = pStream.GetSize();
|
||||||
|
|
||||||
fread(m_pIPL + offset, 1, filesize, pStream);
|
pStream.ReadBytes(m_pIPL + offset, filesize);
|
||||||
fclose(pStream);
|
|
||||||
|
|
||||||
m_FontsLoaded = true;
|
m_FontsLoaded = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,19 +73,17 @@ CEXIMemoryCard::CEXIMemoryCard(const std::string& _rName, const std::string& _rF
|
||||||
|
|
||||||
card_id = 0xc221; // It's a nintendo brand memcard
|
card_id = 0xc221; // It's a nintendo brand memcard
|
||||||
|
|
||||||
FILE* pFile = NULL;
|
File::IOFile pFile(m_strFilename, "rb");
|
||||||
pFile = fopen(m_strFilename.c_str(), "rb");
|
|
||||||
if (pFile)
|
if (pFile)
|
||||||
{
|
{
|
||||||
// Measure size of the memcard file.
|
// Measure size of the memcard file.
|
||||||
memory_card_size = (int)File::GetSize(pFile);
|
memory_card_size = (int)pFile.GetSize();
|
||||||
nintendo_card_id = memory_card_size / SIZE_TO_Mb;
|
nintendo_card_id = memory_card_size / SIZE_TO_Mb;
|
||||||
memory_card_content = new u8[memory_card_size];
|
memory_card_content = new u8[memory_card_size];
|
||||||
memset(memory_card_content, 0xFF, memory_card_size);
|
memset(memory_card_content, 0xFF, memory_card_size);
|
||||||
|
|
||||||
INFO_LOG(EXPANSIONINTERFACE, "Reading memory card %s", m_strFilename.c_str());
|
INFO_LOG(EXPANSIONINTERFACE, "Reading memory card %s", m_strFilename.c_str());
|
||||||
fread(memory_card_content, 1, memory_card_size, pFile);
|
pFile.ReadBytes(memory_card_content, memory_card_size);
|
||||||
fclose(pFile);
|
|
||||||
SetCardFlashID(memory_card_content, card_index);
|
SetCardFlashID(memory_card_content, card_index);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -103,36 +101,30 @@ CEXIMemoryCard::CEXIMemoryCard(const std::string& _rName, const std::string& _rF
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void innerFlush(flushStruct* data)
|
void innerFlush(FlushData* data)
|
||||||
{
|
{
|
||||||
FILE* pFile = NULL;
|
File::IOFile pFile(data->filename, "wb");
|
||||||
pFile = fopen(data->filename.c_str(), "wb");
|
|
||||||
|
|
||||||
if (!pFile)
|
if (!pFile)
|
||||||
{
|
{
|
||||||
std::string dir;
|
std::string dir;
|
||||||
SplitPath(data->filename, &dir, 0, 0);
|
SplitPath(data->filename, &dir, 0, 0);
|
||||||
if(!File::IsDirectory(dir))
|
if (!File::IsDirectory(dir))
|
||||||
File::CreateFullPath(dir);
|
File::CreateFullPath(dir);
|
||||||
pFile = fopen(data->filename.c_str(), "wb");
|
pFile.Open(data->filename, "wb");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pFile) // Note - pFile changed inside above if
|
if (!pFile) // Note - pFile changed inside above if
|
||||||
{
|
{
|
||||||
PanicAlertT("Could not write memory card file %s.\n\n"
|
PanicAlertT("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?", data->filename.c_str());
|
"Are you running Dolphin from a CD/DVD, or is the save file maybe write protected?", data->filename.c_str());
|
||||||
delete data;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fwrite(data->memcardContent, data->memcardSize, 1, pFile);
|
pFile.WriteBytes(data->memcardContent, data->memcardSize);
|
||||||
fclose(pFile);
|
|
||||||
|
|
||||||
if (!data->bExiting)
|
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",
|
||||||
data->filename.c_str()).c_str(), 4000);
|
data->memcardIndex ? 'B' : 'A', data->filename.c_str()).c_str(), 4000);
|
||||||
|
|
||||||
delete data;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,14 +142,13 @@ void CEXIMemoryCard::Flush(bool exiting)
|
||||||
if(!exiting)
|
if(!exiting)
|
||||||
Core::DisplayMessage(StringFromFormat("Writing to memory card %c", card_index ? 'B' : 'A'), 1000);
|
Core::DisplayMessage(StringFromFormat("Writing to memory card %c", card_index ? 'B' : 'A'), 1000);
|
||||||
|
|
||||||
flushStruct *fs = new flushStruct;
|
flushData.filename = m_strFilename;
|
||||||
fs->filename = m_strFilename;
|
flushData.memcardContent = memory_card_content;
|
||||||
fs->memcardContent = memory_card_content;
|
flushData.memcardIndex = card_index;
|
||||||
fs->memcardIndex = card_index;
|
flushData.memcardSize = memory_card_size;
|
||||||
fs->memcardSize = memory_card_size;
|
flushData.bExiting = exiting;
|
||||||
fs->bExiting = exiting;
|
|
||||||
|
|
||||||
flushThread = std::thread(innerFlush, fs);
|
flushThread = std::thread(innerFlush, &flushData);
|
||||||
if (exiting)
|
if (exiting)
|
||||||
flushThread.join();
|
flushThread.join();
|
||||||
|
|
||||||
|
|
|
@ -21,13 +21,13 @@
|
||||||
#include "Thread.h"
|
#include "Thread.h"
|
||||||
|
|
||||||
// Data structure to be passed to the flushing thread.
|
// Data structure to be passed to the flushing thread.
|
||||||
typedef struct
|
struct FlushData
|
||||||
{
|
{
|
||||||
bool bExiting;
|
bool bExiting;
|
||||||
std::string filename;
|
std::string filename;
|
||||||
u8 *memcardContent;
|
u8 *memcardContent;
|
||||||
int memcardSize, memcardIndex;
|
int memcardSize, memcardIndex;
|
||||||
} flushStruct;
|
};
|
||||||
|
|
||||||
class CEXIMemoryCard : public IEXIDevice
|
class CEXIMemoryCard : public IEXIDevice
|
||||||
{
|
{
|
||||||
|
@ -91,6 +91,7 @@ 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;
|
||||||
|
|
||||||
|
FlushData flushData;
|
||||||
std::thread flushThread;
|
std::thread flushThread;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -71,19 +71,19 @@ SRAM sram_dump_german = {{
|
||||||
|
|
||||||
void initSRAM()
|
void initSRAM()
|
||||||
{
|
{
|
||||||
FILE *file = fopen(SConfig::GetInstance().m_LocalCoreStartupParameter.m_strSRAM.c_str(), "rb");
|
File::IOFile file(SConfig::GetInstance().m_LocalCoreStartupParameter.m_strSRAM, "rb");
|
||||||
if (file != NULL)
|
if (file)
|
||||||
{
|
{
|
||||||
if (fread(&g_SRAM, 1, 64, file) < 64) {
|
if (!file.ReadArray(&g_SRAM, 1))
|
||||||
ERROR_LOG(EXPANSIONINTERFACE, "EXI IPL-DEV: Could not read all of SRAM");
|
{
|
||||||
g_SRAM = sram_dump;
|
ERROR_LOG(EXPANSIONINTERFACE, "EXI IPL-DEV: Could not read all of SRAM");
|
||||||
|
g_SRAM = sram_dump;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_SRAM = sram_dump;
|
||||||
}
|
}
|
||||||
fclose(file);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
g_SRAM = sram_dump;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetCardFlashID(u8* buffer, u8 card_index)
|
void SetCardFlashID(u8* buffer, u8 card_index)
|
||||||
|
|
|
@ -56,30 +56,34 @@ void HLE_IPC_CreateVirtualFATFilesystem()
|
||||||
{
|
{
|
||||||
// cdb.vff is a virtual Fat filesystem created on first launch of sysmenu
|
// cdb.vff is a virtual Fat filesystem created on first launch of sysmenu
|
||||||
// we create it here as it is faster ~3 minutes for me when sysmenu does it ~1 second created here
|
// we create it here as it is faster ~3 minutes for me when sysmenu does it ~1 second created here
|
||||||
u8 cdbHDR[0x20] = {'V', 'F', 'F', 0x20, 0xfe, 0xff, 1, 0, 1, 0x40, 0, 0, 0, 0x20};
|
const u8 cdbHDR[0x20] = {'V', 'F', 'F', 0x20, 0xfe, 0xff, 1, 0, 1, 0x40, 0, 0, 0, 0x20};
|
||||||
u8 cdbFAT[4] = {0xf0, 0xff, 0xff, 0xff};
|
const u8 cdbFAT[4] = {0xf0, 0xff, 0xff, 0xff};
|
||||||
FILE * cdbFile = fopen(cdbPath.c_str(), "wb");
|
|
||||||
|
File::IOFile cdbFile(cdbPath, "wb");
|
||||||
if (cdbFile)
|
if (cdbFile)
|
||||||
{
|
{
|
||||||
bool success = true;
|
cdbFile.WriteBytes(cdbHDR, 0x20);
|
||||||
if (fwrite(cdbHDR, 0x20, 1, cdbFile) != 1) success = false;
|
cdbFile.WriteBytes(cdbFAT, 0x4);
|
||||||
if (fwrite(cdbFAT, 0x4, 1, cdbFile) != 1) success = false;
|
cdbFile.Seek(0x14020, SEEK_SET);
|
||||||
fseeko(cdbFile, 0x14020, SEEK_SET);
|
cdbFile.WriteBytes(cdbFAT, 0x4);
|
||||||
if (fwrite(cdbFAT, 0x4, 1, cdbFile) != 1)success = false;
|
|
||||||
// 20 MiB file
|
// 20 MiB file
|
||||||
fseeko(cdbFile, 0x01400000 - 1, SEEK_SET);
|
cdbFile.Seek(0x01400000 - 1, SEEK_SET);
|
||||||
// write the final 0 to 0 file from the second FAT to 20 MiB
|
// write the final 0 to 0 file from the second FAT to 20 MiB
|
||||||
if (fwrite(cdbHDR+14, 1, 1, cdbFile) != 1) success = false;
|
cdbFile.WriteBytes(cdbHDR + 14, 1);
|
||||||
fclose(cdbFile);
|
|
||||||
if (!success) File::Delete(cdbPath);
|
if (!cdbFile.IsGood())
|
||||||
|
{
|
||||||
|
cdbFile.Close();
|
||||||
|
File::Delete(cdbPath);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CWII_IPC_HLE_Device_FileIO::CWII_IPC_HLE_Device_FileIO(u32 _DeviceID, const std::string& _rDeviceName)
|
CWII_IPC_HLE_Device_FileIO::CWII_IPC_HLE_Device_FileIO(u32 _DeviceID, const std::string& _rDeviceName)
|
||||||
: IWII_IPC_HLE_Device(_DeviceID, _rDeviceName, false) // not a real hardware
|
: IWII_IPC_HLE_Device(_DeviceID, _rDeviceName, false) // not a real hardware
|
||||||
, m_pFileHandle(NULL)
|
, m_pFileHandle(NULL)
|
||||||
, m_FileLength(0)
|
, m_FileLength(0)
|
||||||
, m_Mode(0)
|
, m_Mode(0)
|
||||||
, m_Seek(0)
|
, m_Seek(0)
|
||||||
{
|
{
|
||||||
|
@ -94,11 +98,7 @@ bool CWII_IPC_HLE_Device_FileIO::Close(u32 _CommandAddress, bool _bForce)
|
||||||
{
|
{
|
||||||
INFO_LOG(WII_IPC_FILEIO, "FileIO: Close %s (DeviceID=%08x)", m_Name.c_str(), m_DeviceID);
|
INFO_LOG(WII_IPC_FILEIO, "FileIO: Close %s (DeviceID=%08x)", m_Name.c_str(), m_DeviceID);
|
||||||
|
|
||||||
if (m_pFileHandle != NULL)
|
m_pFileHandle.Close();
|
||||||
{
|
|
||||||
fclose(m_pFileHandle);
|
|
||||||
m_pFileHandle = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_FileLength = 0;
|
m_FileLength = 0;
|
||||||
m_Mode = 0;
|
m_Mode = 0;
|
||||||
|
@ -117,18 +117,14 @@ bool CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode)
|
||||||
u32 ReturnValue = 0;
|
u32 ReturnValue = 0;
|
||||||
|
|
||||||
// close the file handle if we get a reopen
|
// close the file handle if we get a reopen
|
||||||
if (m_pFileHandle != NULL)
|
m_pFileHandle.Close();
|
||||||
{
|
|
||||||
fclose(m_pFileHandle);
|
|
||||||
m_pFileHandle = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char Modes[][128] =
|
const char* const Modes[] =
|
||||||
{
|
{
|
||||||
{ "Unk Mode" },
|
"Unk Mode",
|
||||||
{ "Read only" },
|
"Read only",
|
||||||
{ "Write only" },
|
"Write only",
|
||||||
{ "Read and Write" }
|
"Read and Write"
|
||||||
};
|
};
|
||||||
|
|
||||||
m_Filename = std::string(HLE_IPC_BuildFilename(m_Name.c_str(), 64));
|
m_Filename = std::string(HLE_IPC_BuildFilename(m_Name.c_str(), 64));
|
||||||
|
@ -140,11 +136,22 @@ bool CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode)
|
||||||
INFO_LOG(WII_IPC_FILEIO, "FileIO: Open %s (%s)", m_Name.c_str(), Modes[_Mode]);
|
INFO_LOG(WII_IPC_FILEIO, "FileIO: Open %s (%s)", m_Name.c_str(), Modes[_Mode]);
|
||||||
switch(_Mode)
|
switch(_Mode)
|
||||||
{
|
{
|
||||||
case ISFS_OPEN_READ: m_pFileHandle = fopen(m_Filename.c_str(), "rb"); break;
|
case ISFS_OPEN_READ:
|
||||||
|
m_pFileHandle.Open(m_Filename, "rb");
|
||||||
|
break;
|
||||||
|
|
||||||
// "r+b" is technically wrong, but OPEN_WRITE should not truncate the file as "wb" does.
|
// "r+b" is technically wrong, but OPEN_WRITE should not truncate the file as "wb" does.
|
||||||
case ISFS_OPEN_WRITE: m_pFileHandle = fopen(m_Filename.c_str(), "r+b"); break;
|
case ISFS_OPEN_WRITE:
|
||||||
case ISFS_OPEN_RW: m_pFileHandle = fopen(m_Filename.c_str(), "r+b"); break;
|
m_pFileHandle.Open(m_Filename, "r+b");
|
||||||
default: PanicAlertT("FileIO: Unknown open mode : 0x%02x", _Mode); break;
|
break;
|
||||||
|
|
||||||
|
case ISFS_OPEN_RW:
|
||||||
|
m_pFileHandle.Open(m_Filename, "r+b");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
PanicAlertT("FileIO: Unknown open mode : 0x%02x", _Mode);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -155,7 +162,7 @@ bool CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode)
|
||||||
|
|
||||||
if (m_pFileHandle != NULL)
|
if (m_pFileHandle != NULL)
|
||||||
{
|
{
|
||||||
m_FileLength = (u32)File::GetSize(m_pFileHandle);
|
m_FileLength = (u32)m_pFileHandle.GetSize();
|
||||||
ReturnValue = m_DeviceID;
|
ReturnValue = m_DeviceID;
|
||||||
}
|
}
|
||||||
else if (ReturnValue == 0)
|
else if (ReturnValue == 0)
|
||||||
|
@ -173,9 +180,9 @@ bool CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode)
|
||||||
bool CWII_IPC_HLE_Device_FileIO::Seek(u32 _CommandAddress)
|
bool CWII_IPC_HLE_Device_FileIO::Seek(u32 _CommandAddress)
|
||||||
{
|
{
|
||||||
u32 ReturnValue = FS_INVALID_ARGUMENT;
|
u32 ReturnValue = FS_INVALID_ARGUMENT;
|
||||||
s32 SeekPosition = Memory::Read_U32(_CommandAddress + 0xC);
|
const s32 SeekPosition = Memory::Read_U32(_CommandAddress + 0xC);
|
||||||
s32 Mode = Memory::Read_U32(_CommandAddress + 0x10);
|
const s32 Mode = Memory::Read_U32(_CommandAddress + 0x10);
|
||||||
u64 fileSize = File::GetSize(m_pFileHandle);
|
const u64 fileSize = m_pFileHandle.GetSize();
|
||||||
|
|
||||||
INFO_LOG(WII_IPC_FILEIO, "FileIO: Seek Pos: 0x%08x, Mode: %i (%s, Length=0x%08llx)", SeekPosition, Mode, m_Name.c_str(), fileSize);
|
INFO_LOG(WII_IPC_FILEIO, "FileIO: Seek Pos: 0x%08x, Mode: %i (%s, Length=0x%08llx)", SeekPosition, Mode, m_Name.c_str(), fileSize);
|
||||||
|
|
||||||
|
@ -186,14 +193,14 @@ bool CWII_IPC_HLE_Device_FileIO::Seek(u32 _CommandAddress)
|
||||||
{
|
{
|
||||||
// POSIX allows seek past EOF, the Wii does not.
|
// POSIX allows seek past EOF, the Wii does not.
|
||||||
// TODO: Can we check this without tell'ing/seek'ing twice?
|
// TODO: Can we check this without tell'ing/seek'ing twice?
|
||||||
u64 curPos = ftello(m_pFileHandle);
|
const u64 curPos = m_pFileHandle.Tell();
|
||||||
if (fseeko(m_pFileHandle, SeekPosition, seek_mode[Mode]) == 0)
|
if (m_pFileHandle.Seek(SeekPosition, seek_mode[Mode]))
|
||||||
{
|
{
|
||||||
u64 newPos = ftello(m_pFileHandle);
|
const u64 newPos = m_pFileHandle.Tell();
|
||||||
if (newPos > fileSize)
|
if (newPos > fileSize)
|
||||||
{
|
{
|
||||||
ERROR_LOG(WII_IPC_FILEIO, "FILEIO: Seek past EOF - %s", m_Name.c_str());
|
ERROR_LOG(WII_IPC_FILEIO, "FILEIO: Seek past EOF - %s", m_Name.c_str());
|
||||||
fseeko(m_pFileHandle, curPos, SEEK_SET);
|
m_pFileHandle.Seek(curPos, SEEK_SET);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ReturnValue = (u32)newPos;
|
ReturnValue = (u32)newPos;
|
||||||
|
@ -215,12 +222,12 @@ bool CWII_IPC_HLE_Device_FileIO::Seek(u32 _CommandAddress)
|
||||||
|
|
||||||
bool CWII_IPC_HLE_Device_FileIO::Read(u32 _CommandAddress)
|
bool CWII_IPC_HLE_Device_FileIO::Read(u32 _CommandAddress)
|
||||||
{
|
{
|
||||||
u32 ReturnValue = FS_EACCESS;
|
u32 ReturnValue = FS_EACCESS;
|
||||||
u32 Address = Memory::Read_U32(_CommandAddress + 0xC); // Read to this memory address
|
const u32 Address = Memory::Read_U32(_CommandAddress + 0xC); // Read to this memory address
|
||||||
u32 Size = Memory::Read_U32(_CommandAddress + 0x10);
|
const u32 Size = Memory::Read_U32(_CommandAddress + 0x10);
|
||||||
|
|
||||||
if (m_pFileHandle != NULL)
|
if (m_pFileHandle != NULL)
|
||||||
{
|
{
|
||||||
if (m_Mode == ISFS_OPEN_WRITE)
|
if (m_Mode == ISFS_OPEN_WRITE)
|
||||||
{
|
{
|
||||||
WARN_LOG(WII_IPC_FILEIO, "FileIO: Attempted to read 0x%x bytes to 0x%08x on write-only file %s", Size, Address, m_Name.c_str());
|
WARN_LOG(WII_IPC_FILEIO, "FileIO: Attempted to read 0x%x bytes to 0x%08x on write-only file %s", Size, Address, m_Name.c_str());
|
||||||
|
@ -228,24 +235,26 @@ bool CWII_IPC_HLE_Device_FileIO::Read(u32 _CommandAddress)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
INFO_LOG(WII_IPC_FILEIO, "FileIO: Read 0x%x bytes to 0x%08x from %s", Size, Address, m_Name.c_str());
|
INFO_LOG(WII_IPC_FILEIO, "FileIO: Read 0x%x bytes to 0x%08x from %s", Size, Address, m_Name.c_str());
|
||||||
ReturnValue = (u32)fread(Memory::GetPointer(Address), 1, Size, m_pFileHandle);
|
|
||||||
if ((ReturnValue != Size) && ferror(m_pFileHandle)) ReturnValue = FS_EACCESS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ERROR_LOG(WII_IPC_FILEIO, "FileIO: Failed to read from %s (Addr=0x%08x Size=0x%x) - file not open", m_Name.c_str(), Address, Size);
|
|
||||||
}
|
|
||||||
|
|
||||||
Memory::Write_U32(ReturnValue, _CommandAddress + 0x4);
|
ReturnValue = (u32)fread(Memory::GetPointer(Address), 1, Size, m_pFileHandle.GetHandle());
|
||||||
return true;
|
if (ReturnValue != Size && ferror(m_pFileHandle.GetHandle()))
|
||||||
|
ReturnValue = FS_EACCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ERROR_LOG(WII_IPC_FILEIO, "FileIO: Failed to read from %s (Addr=0x%08x Size=0x%x) - file not open", m_Name.c_str(), Address, Size);
|
||||||
|
}
|
||||||
|
|
||||||
|
Memory::Write_U32(ReturnValue, _CommandAddress + 0x4);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWII_IPC_HLE_Device_FileIO::Write(u32 _CommandAddress)
|
bool CWII_IPC_HLE_Device_FileIO::Write(u32 _CommandAddress)
|
||||||
{
|
{
|
||||||
u32 ReturnValue = FS_EACCESS;
|
u32 ReturnValue = FS_EACCESS;
|
||||||
u32 Address = Memory::Read_U32(_CommandAddress + 0xC); // Write data from this memory address
|
const u32 Address = Memory::Read_U32(_CommandAddress + 0xC); // Write data from this memory address
|
||||||
u32 Size = Memory::Read_U32(_CommandAddress + 0x10);
|
const u32 Size = Memory::Read_U32(_CommandAddress + 0x10);
|
||||||
|
|
||||||
INFO_LOG(WII_IPC_FILEIO, "FileIO: Write 0x%04x bytes from 0x%08x to %s", Size, Address, m_Name.c_str());
|
INFO_LOG(WII_IPC_FILEIO, "FileIO: Write 0x%04x bytes from 0x%08x to %s", Size, Address, m_Name.c_str());
|
||||||
|
|
||||||
|
@ -257,69 +266,64 @@ bool CWII_IPC_HLE_Device_FileIO::Write(u32 _CommandAddress)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
size_t Result = fwrite(Memory::GetPointer(Address), Size, 1, m_pFileHandle);
|
if (m_pFileHandle.WriteBytes(Memory::GetPointer(Address), Size))
|
||||||
#if MAX_LOGLEVEL >= DEBUG_LEVEL
|
ReturnValue = Size;
|
||||||
_dbg_assert_msg_(WII_IPC_FILEIO, Result == 1, "fwrite failed");
|
|
||||||
#else
|
|
||||||
(void)Result;
|
|
||||||
#endif
|
|
||||||
ReturnValue = (Result == 1) ? Size : FS_EACCESS;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Memory::Write_U32(ReturnValue, _CommandAddress + 0x4);
|
Memory::Write_U32(ReturnValue, _CommandAddress + 0x4);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWII_IPC_HLE_Device_FileIO::IOCtl(u32 _CommandAddress)
|
bool CWII_IPC_HLE_Device_FileIO::IOCtl(u32 _CommandAddress)
|
||||||
{
|
{
|
||||||
INFO_LOG(WII_IPC_FILEIO, "FileIO: IOCtl (Device=%s)", m_Name.c_str());
|
INFO_LOG(WII_IPC_FILEIO, "FileIO: IOCtl (Device=%s)", m_Name.c_str());
|
||||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||||
DumpCommands(_CommandAddress);
|
DumpCommands(_CommandAddress);
|
||||||
#endif
|
#endif
|
||||||
u32 Parameter = Memory::Read_U32(_CommandAddress + 0xC);
|
const u32 Parameter = Memory::Read_U32(_CommandAddress + 0xC);
|
||||||
|
|
||||||
//u32 BufferIn = Memory::Read_U32(_CommandAddress + 0x10);
|
//u32 BufferIn = Memory::Read_U32(_CommandAddress + 0x10);
|
||||||
//u32 BufferInSize = Memory::Read_U32(_CommandAddress + 0x14);
|
//u32 BufferInSize = Memory::Read_U32(_CommandAddress + 0x14);
|
||||||
//u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18);
|
//u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18);
|
||||||
//u32 BufferOutSize = Memory::Read_U32(_CommandAddress + 0x1C);
|
//u32 BufferOutSize = Memory::Read_U32(_CommandAddress + 0x1C);
|
||||||
|
|
||||||
switch(Parameter)
|
switch(Parameter)
|
||||||
{
|
{
|
||||||
case ISFS_IOCTL_GETFILESTATS:
|
case ISFS_IOCTL_GETFILESTATS:
|
||||||
{
|
{
|
||||||
m_FileLength = (u32)File::GetSize(m_pFileHandle);
|
m_FileLength = (u32)m_pFileHandle.GetSize();
|
||||||
u32 Position = (u32)ftello(m_pFileHandle);
|
const u32 Position = (u32)m_pFileHandle.Tell();
|
||||||
|
|
||||||
u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18);
|
const u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18);
|
||||||
INFO_LOG(WII_IPC_FILEIO, "FileIO: ISFS_IOCTL_GETFILESTATS");
|
INFO_LOG(WII_IPC_FILEIO, "FileIO: ISFS_IOCTL_GETFILESTATS");
|
||||||
INFO_LOG(WII_IPC_FILEIO, " File: %s, Length: %i, Pos: %i", m_Name.c_str(), m_FileLength, Position);
|
INFO_LOG(WII_IPC_FILEIO, " File: %s, Length: %i, Pos: %i", m_Name.c_str(), m_FileLength, Position);
|
||||||
|
|
||||||
Memory::Write_U32(m_FileLength, BufferOut);
|
Memory::Write_U32(m_FileLength, BufferOut);
|
||||||
Memory::Write_U32(Position, BufferOut+4);
|
Memory::Write_U32(Position, BufferOut+4);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
PanicAlert("CWII_IPC_HLE_Device_FileIO: Parameter %i", Parameter);
|
PanicAlert("CWII_IPC_HLE_Device_FileIO: Parameter %i", Parameter);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return Value
|
// Return Value
|
||||||
u32 ReturnValue = 0; // no error
|
const u32 ReturnValue = 0; // no error
|
||||||
Memory::Write_U32(ReturnValue, _CommandAddress + 0x4);
|
Memory::Write_U32(ReturnValue, _CommandAddress + 0x4);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWII_IPC_HLE_Device_FileIO::DoState(PointerWrap &p)
|
void CWII_IPC_HLE_Device_FileIO::DoState(PointerWrap &p)
|
||||||
{
|
{
|
||||||
if (p.GetMode() == PointerWrap::MODE_WRITE)
|
if (p.GetMode() == PointerWrap::MODE_WRITE)
|
||||||
{
|
{
|
||||||
m_Seek = (m_pFileHandle) ? (s32)ftello(m_pFileHandle) : 0;
|
m_Seek = (m_pFileHandle) ? (s32)m_pFileHandle.Tell() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
p.Do(m_Mode);
|
p.Do(m_Mode);
|
||||||
|
@ -330,8 +334,7 @@ void CWII_IPC_HLE_Device_FileIO::DoState(PointerWrap &p)
|
||||||
if (m_Mode)
|
if (m_Mode)
|
||||||
{
|
{
|
||||||
Open(0, m_Mode);
|
Open(0, m_Mode);
|
||||||
if (m_pFileHandle)
|
m_pFileHandle.Seek(m_Seek, SEEK_SET);
|
||||||
fseeko(m_pFileHandle, m_Seek, SEEK_SET);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#define _WII_IPC_HLE_DEVICE_FILEIO_H_
|
#define _WII_IPC_HLE_DEVICE_FILEIO_H_
|
||||||
|
|
||||||
#include "WII_IPC_HLE_Device.h"
|
#include "WII_IPC_HLE_Device.h"
|
||||||
|
#include "FileUtil.h"
|
||||||
|
|
||||||
std::string HLE_IPC_BuildFilename(const char* _pFilename, int _size);
|
std::string HLE_IPC_BuildFilename(const char* _pFilename, int _size);
|
||||||
void HLE_IPC_CreateVirtualFATFilesystem();
|
void HLE_IPC_CreateVirtualFATFilesystem();
|
||||||
|
@ -72,7 +73,7 @@ private:
|
||||||
ISFS_IOCTL_SHUTDOWN
|
ISFS_IOCTL_SHUTDOWN
|
||||||
};
|
};
|
||||||
|
|
||||||
FILE* m_pFileHandle;
|
File::IOFile m_pFileHandle;
|
||||||
u32 m_FileLength;
|
u32 m_FileLength;
|
||||||
u32 m_Mode;
|
u32 m_Mode;
|
||||||
s32 m_Seek;
|
s32 m_Seek;
|
||||||
|
|
|
@ -486,18 +486,15 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
|
||||||
if (File::Exists(TicketFilename))
|
if (File::Exists(TicketFilename))
|
||||||
{
|
{
|
||||||
const u32 SIZE_OF_ONE_TICKET = 676;
|
const u32 SIZE_OF_ONE_TICKET = 676;
|
||||||
FILE* pFile = fopen(TicketFilename.c_str(), "rb");
|
File::IOFile pFile(TicketFilename, "rb");
|
||||||
if (pFile)
|
if (pFile)
|
||||||
{
|
{
|
||||||
unsigned int View = 0;
|
|
||||||
u8 Ticket[SIZE_OF_ONE_TICKET];
|
u8 Ticket[SIZE_OF_ONE_TICKET];
|
||||||
while (View < maxViews && fread(Ticket, SIZE_OF_ONE_TICKET, 1, pFile) == 1)
|
for (unsigned int View = 0; View != maxViews && pFile.ReadBytes(Ticket, SIZE_OF_ONE_TICKET); ++View)
|
||||||
{
|
{
|
||||||
Memory::Write_U32(View, Buffer.PayloadBuffer[0].m_Address + View * 0xD8);
|
Memory::Write_U32(View, Buffer.PayloadBuffer[0].m_Address + View * 0xD8);
|
||||||
Memory::WriteBigEData(Ticket+0x1D0, Buffer.PayloadBuffer[0].m_Address + 4 + View * 0xD8, 212);
|
Memory::WriteBigEData(Ticket+0x1D0, Buffer.PayloadBuffer[0].m_Address + 4 + View * 0xD8, 212);
|
||||||
View++;
|
|
||||||
}
|
}
|
||||||
fclose(pFile);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -865,15 +862,10 @@ u32 CWII_IPC_HLE_Device_es::ES_DIVerify(u8* _pTMD, u32 _sz)
|
||||||
File::CreateFullPath(dataPath);
|
File::CreateFullPath(dataPath);
|
||||||
if(!File::Exists(tmdPath))
|
if(!File::Exists(tmdPath))
|
||||||
{
|
{
|
||||||
FILE* _pTMDFile = fopen(tmdPath.c_str(), "wb");
|
File::IOFile _pTMDFile(tmdPath, "wb");
|
||||||
if (_pTMDFile)
|
if (!_pTMDFile.WriteBytes(_pTMD, _sz))
|
||||||
{
|
ERROR_LOG(WII_IPC_ES, "DIVerify failed to write disc tmd to nand");
|
||||||
if (fwrite(_pTMD, _sz, 1, _pTMDFile) != 1)
|
|
||||||
ERROR_LOG(WII_IPC_ES, "DIVerify failed to write disc tmd to nand");
|
|
||||||
fclose(_pTMDFile);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
DiscIO::cUIDsys::AccessInstance().AddTitle(tmdTitleID);
|
DiscIO::cUIDsys::AccessInstance().AddTitle(tmdTitleID);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -169,11 +169,10 @@ CWII_IPC_HLE_Device_net_ncd_manage::CWII_IPC_HLE_Device_net_ncd_manage(u32 _Devi
|
||||||
: IWII_IPC_HLE_Device(_DeviceID, _rDeviceName)
|
: IWII_IPC_HLE_Device(_DeviceID, _rDeviceName)
|
||||||
{
|
{
|
||||||
// store network configuration
|
// store network configuration
|
||||||
std::string filename(File::GetUserPath(D_WIIUSER_IDX));
|
const std::string filename(File::GetUserPath(D_WIIUSER_IDX) + "shared2/sys/net/02/config.dat");
|
||||||
filename.append("shared2/sys/net/02/config.dat");
|
|
||||||
FILE *file = fopen(filename.c_str(), "rb");
|
|
||||||
|
|
||||||
if (file == NULL || fread(&m_Ifconfig, sizeof(network_config_t), 1, file) != 1)
|
File::IOFile file(filename, "rb");
|
||||||
|
if (!file.ReadBytes(&m_Ifconfig, 1))
|
||||||
{
|
{
|
||||||
INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE: Failed to load /shared2/sys/net/02/config.dat, using dummy configuration");
|
INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE: Failed to load /shared2/sys/net/02/config.dat, using dummy configuration");
|
||||||
|
|
||||||
|
@ -195,10 +194,6 @@ CWII_IPC_HLE_Device_net_ncd_manage::CWII_IPC_HLE_Device_net_ncd_manage(u32 _Devi
|
||||||
m_Ifconfig.connection[0].gateway[2] = 1;
|
m_Ifconfig.connection[0].gateway[2] = 1;
|
||||||
m_Ifconfig.connection[0].gateway[3] = 2;
|
m_Ifconfig.connection[0].gateway[3] = 2;
|
||||||
}
|
}
|
||||||
if (file)
|
|
||||||
{
|
|
||||||
fclose(file);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CWII_IPC_HLE_Device_net_ncd_manage::~CWII_IPC_HLE_Device_net_ncd_manage()
|
CWII_IPC_HLE_Device_net_ncd_manage::~CWII_IPC_HLE_Device_net_ncd_manage()
|
||||||
|
|
|
@ -35,15 +35,6 @@ CWII_IPC_HLE_Device_sdio_slot0::CWII_IPC_HLE_Device_sdio_slot0(u32 _DeviceID, co
|
||||||
, m_Card(NULL)
|
, m_Card(NULL)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
CWII_IPC_HLE_Device_sdio_slot0::~CWII_IPC_HLE_Device_sdio_slot0()
|
|
||||||
{
|
|
||||||
if(m_Card)
|
|
||||||
{
|
|
||||||
fclose(m_Card);
|
|
||||||
m_Card = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CWII_IPC_HLE_Device_sdio_slot0::EventNotify()
|
void CWII_IPC_HLE_Device_sdio_slot0::EventNotify()
|
||||||
{
|
{
|
||||||
if ((SConfig::GetInstance().m_WiiSDCard && m_event.type == EVENT_INSERT) ||
|
if ((SConfig::GetInstance().m_WiiSDCard && m_event.type == EVENT_INSERT) ||
|
||||||
|
@ -60,17 +51,17 @@ bool CWII_IPC_HLE_Device_sdio_slot0::Open(u32 _CommandAddress, u32 _Mode)
|
||||||
{
|
{
|
||||||
INFO_LOG(WII_IPC_SD, "Open");
|
INFO_LOG(WII_IPC_SD, "Open");
|
||||||
|
|
||||||
std::string filename = File::GetUserPath(D_WIIUSER_IDX) + "sd.raw";
|
const std::string filename = File::GetUserPath(D_WIIUSER_IDX) + "sd.raw";
|
||||||
m_Card = fopen(filename.c_str(), "r+b");
|
m_Card.Open(filename, "r+b");
|
||||||
if(!m_Card)
|
if (!m_Card)
|
||||||
{
|
{
|
||||||
WARN_LOG(WII_IPC_SD, "Failed to open SD Card image, trying to create a new 128MB image...");
|
WARN_LOG(WII_IPC_SD, "Failed to open SD Card image, trying to create a new 128MB image...");
|
||||||
if (SDCardCreate(128, filename.c_str()))
|
if (SDCardCreate(128, filename.c_str()))
|
||||||
{
|
{
|
||||||
WARN_LOG(WII_IPC_SD, "Successfully created %s", filename.c_str());
|
WARN_LOG(WII_IPC_SD, "Successfully created %s", filename.c_str());
|
||||||
m_Card = fopen(filename.c_str(), "r+b");
|
m_Card.Open(filename, "r+b");
|
||||||
}
|
}
|
||||||
if(!m_Card)
|
if (!m_Card)
|
||||||
{
|
{
|
||||||
ERROR_LOG(WII_IPC_SD, "Could not open SD Card image or create a new one, are you running from a read-only directory?");
|
ERROR_LOG(WII_IPC_SD, "Could not open SD Card image or create a new one, are you running from a read-only directory?");
|
||||||
}
|
}
|
||||||
|
@ -85,11 +76,7 @@ bool CWII_IPC_HLE_Device_sdio_slot0::Close(u32 _CommandAddress, bool _bForce)
|
||||||
{
|
{
|
||||||
INFO_LOG(WII_IPC_SD, "Close");
|
INFO_LOG(WII_IPC_SD, "Close");
|
||||||
|
|
||||||
if(m_Card)
|
m_Card.Close();
|
||||||
{
|
|
||||||
fclose(m_Card);
|
|
||||||
m_Card = NULL;
|
|
||||||
}
|
|
||||||
m_BlockLength = 0;
|
m_BlockLength = 0;
|
||||||
m_BusWidth = 0;
|
m_BusWidth = 0;
|
||||||
|
|
||||||
|
@ -377,13 +364,12 @@ u32 CWII_IPC_HLE_Device_sdio_slot0::ExecuteCommand(u32 _BufferIn, u32 _BufferInS
|
||||||
{
|
{
|
||||||
u32 size = req.bsize * req.blocks;
|
u32 size = req.bsize * req.blocks;
|
||||||
|
|
||||||
if (fseeko(m_Card, req.arg, SEEK_SET) != 0)
|
if (!m_Card.Seek(req.arg, SEEK_SET))
|
||||||
ERROR_LOG(WII_IPC_SD, "fseeko failed WTF");
|
ERROR_LOG(WII_IPC_SD, "Seek failed WTF");
|
||||||
|
|
||||||
u8* buffer = new u8[size];
|
u8* const buffer = new u8[size];
|
||||||
|
|
||||||
size_t nRead = fread(buffer, req.bsize, req.blocks, m_Card);
|
if (m_Card.ReadBytes(buffer, req.bsize * req.blocks))
|
||||||
if (nRead == req.blocks)
|
|
||||||
{
|
{
|
||||||
u32 i;
|
u32 i;
|
||||||
for (i = 0; i < size; ++i)
|
for (i = 0; i < size; ++i)
|
||||||
|
@ -394,10 +380,8 @@ u32 CWII_IPC_HLE_Device_sdio_slot0::ExecuteCommand(u32 _BufferIn, u32 _BufferInS
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ERROR_LOG(WII_IPC_SD, "Read Failed - "
|
ERROR_LOG(WII_IPC_SD, "Read Failed - error: %i, eof: %i",
|
||||||
"read %lx, error %i, eof? %i",
|
ferror(m_Card.GetHandle()), feof(m_Card.GetHandle()));
|
||||||
(unsigned long)nRead,
|
|
||||||
ferror(m_Card), feof(m_Card));
|
|
||||||
ret = RET_FAIL;
|
ret = RET_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -418,7 +402,7 @@ u32 CWII_IPC_HLE_Device_sdio_slot0::ExecuteCommand(u32 _BufferIn, u32 _BufferInS
|
||||||
{
|
{
|
||||||
u32 size = req.bsize * req.blocks;
|
u32 size = req.bsize * req.blocks;
|
||||||
|
|
||||||
if (fseeko(m_Card, req.arg, SEEK_SET) != 0)
|
if (!m_Card.Seek(req.arg, SEEK_SET))
|
||||||
ERROR_LOG(WII_IPC_SD, "fseeko failed WTF");
|
ERROR_LOG(WII_IPC_SD, "fseeko failed WTF");
|
||||||
|
|
||||||
u8* buffer = new u8[size];
|
u8* buffer = new u8[size];
|
||||||
|
@ -428,13 +412,10 @@ u32 CWII_IPC_HLE_Device_sdio_slot0::ExecuteCommand(u32 _BufferIn, u32 _BufferInS
|
||||||
buffer[i] = Memory::Read_U8(req.addr++);
|
buffer[i] = Memory::Read_U8(req.addr++);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t nWritten = fwrite(buffer, req.bsize, req.blocks, m_Card);
|
if (!m_Card.WriteBytes(buffer, req.bsize * req.blocks))
|
||||||
if (nWritten != req.blocks)
|
|
||||||
{
|
{
|
||||||
ERROR_LOG(WII_IPC_SD, "Write Failed - "
|
ERROR_LOG(WII_IPC_SD, "Write Failed - error: %i, eof: %i",
|
||||||
"wrote %lx, error %i, eof? %i",
|
ferror(m_Card.GetHandle()), feof(m_Card.GetHandle()));
|
||||||
(unsigned long)nWritten,
|
|
||||||
ferror(m_Card), feof(m_Card));
|
|
||||||
ret = RET_FAIL;
|
ret = RET_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,8 +28,6 @@ public:
|
||||||
|
|
||||||
CWII_IPC_HLE_Device_sdio_slot0(u32 _DeviceID, const std::string& _rDeviceName);
|
CWII_IPC_HLE_Device_sdio_slot0(u32 _DeviceID, const std::string& _rDeviceName);
|
||||||
|
|
||||||
virtual ~CWII_IPC_HLE_Device_sdio_slot0();
|
|
||||||
|
|
||||||
bool Open(u32 _CommandAddress, u32 _Mode);
|
bool Open(u32 _CommandAddress, u32 _Mode);
|
||||||
bool Close(u32 _CommandAddress, bool _bForce);
|
bool Close(u32 _CommandAddress, bool _bForce);
|
||||||
bool IOCtl(u32 _CommandAddress);
|
bool IOCtl(u32 _CommandAddress);
|
||||||
|
@ -134,7 +132,7 @@ private:
|
||||||
u32 m_BlockLength;
|
u32 m_BlockLength;
|
||||||
u32 m_BusWidth;
|
u32 m_BusWidth;
|
||||||
|
|
||||||
FILE* m_Card;
|
File::IOFile m_Card;
|
||||||
|
|
||||||
u32 ExecuteCommand(u32 BufferIn, u32 BufferInSize,
|
u32 ExecuteCommand(u32 BufferIn, u32 BufferInSize,
|
||||||
u32 BufferIn2, u32 BufferInSize2,
|
u32 BufferIn2, u32 BufferInSize2,
|
||||||
|
|
|
@ -50,7 +50,7 @@ unsigned int g_framesToSkip = 0, g_frameSkipCounter = 0;
|
||||||
|
|
||||||
int g_numPads = 0;
|
int g_numPads = 0;
|
||||||
ControllerState g_padState;
|
ControllerState g_padState;
|
||||||
FILE *g_recordfd = NULL;
|
File::IOFile g_recordfd;
|
||||||
|
|
||||||
u64 g_frameCounter = 0, g_lagCounter = 0, g_totalFrameCount = 0;
|
u64 g_frameCounter = 0, g_lagCounter = 0, g_totalFrameCount = 0;
|
||||||
bool g_bRecordingFromSaveState = false;
|
bool g_bRecordingFromSaveState = false;
|
||||||
|
@ -209,15 +209,15 @@ bool BeginRecordingInput(int controllers)
|
||||||
g_bRecordingFromSaveState = true;
|
g_bRecordingFromSaveState = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_recordfd = fopen(g_recordFile.c_str(), "wb");
|
if (!g_recordfd.Open(g_recordFile, "wb"))
|
||||||
if(!g_recordfd) {
|
{
|
||||||
PanicAlertT("Error opening file %s for recording", g_recordFile.c_str());
|
PanicAlertT("Error opening file %s for recording", g_recordFile.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write initial empty header
|
// Write initial empty header
|
||||||
DTMHeader dummy;
|
DTMHeader dummy;
|
||||||
fwrite(&dummy, sizeof(DTMHeader), 1, g_recordfd);
|
g_recordfd.WriteArray(&dummy, 1);
|
||||||
|
|
||||||
g_numPads = controllers;
|
g_numPads = controllers;
|
||||||
|
|
||||||
|
@ -328,7 +328,7 @@ void RecordInput(SPADStatus *PadStatus, int controllerID)
|
||||||
g_padState.CStickX = PadStatus->substickX;
|
g_padState.CStickX = PadStatus->substickX;
|
||||||
g_padState.CStickY = PadStatus->substickY;
|
g_padState.CStickY = PadStatus->substickY;
|
||||||
|
|
||||||
fwrite(&g_padState, sizeof(ControllerState), 1, g_recordfd);
|
g_recordfd.WriteArray(&g_padState, 1);
|
||||||
|
|
||||||
SetInputDisplayString(g_padState, controllerID);
|
SetInputDisplayString(g_padState, controllerID);
|
||||||
}
|
}
|
||||||
|
@ -338,8 +338,8 @@ void RecordWiimote(int wiimote, u8 *data, s8 size)
|
||||||
if(!IsRecordingInput() || !IsUsingWiimote(wiimote))
|
if(!IsRecordingInput() || !IsUsingWiimote(wiimote))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
fwrite(&size, 1, 1, g_recordfd);
|
g_recordfd.WriteArray(&size, 1);
|
||||||
fwrite(data, 1, size, g_recordfd);
|
g_recordfd.WriteArray(data, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PlayInput(const char *filename)
|
bool PlayInput(const char *filename)
|
||||||
|
@ -355,11 +355,10 @@ bool PlayInput(const char *filename)
|
||||||
File::Delete(g_recordFile);
|
File::Delete(g_recordFile);
|
||||||
File::Copy(filename, g_recordFile);
|
File::Copy(filename, g_recordFile);
|
||||||
|
|
||||||
g_recordfd = fopen(g_recordFile.c_str(), "r+b");
|
if (!g_recordfd.Open(g_recordFile, "r+b"))
|
||||||
if(!g_recordfd)
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
fread(&header, sizeof(DTMHeader), 1, g_recordfd);
|
g_recordfd.ReadArray(&header, 1);
|
||||||
|
|
||||||
if(header.filetype[0] != 'D' || header.filetype[1] != 'T' || header.filetype[2] != 'M' || header.filetype[3] != 0x1A) {
|
if(header.filetype[0] != 'D' || header.filetype[1] != 'T' || header.filetype[2] != 'M' || header.filetype[3] != 0x1A) {
|
||||||
PanicAlertT("Invalid recording file");
|
PanicAlertT("Invalid recording file");
|
||||||
|
@ -399,19 +398,18 @@ bool PlayInput(const char *filename)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
fclose(g_recordfd);
|
g_recordfd.Close();
|
||||||
g_recordfd = NULL;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoadInput(const char *filename)
|
void LoadInput(const char *filename)
|
||||||
{
|
{
|
||||||
FILE *t_record = fopen(filename, "rb");
|
File::IOFile t_record(filename, "rb");
|
||||||
|
|
||||||
DTMHeader header;
|
DTMHeader header;
|
||||||
|
|
||||||
fread(&header, sizeof(DTMHeader), 1, t_record);
|
t_record.ReadArray(&header, 1);
|
||||||
fclose(t_record);
|
t_record.Close();
|
||||||
|
|
||||||
if(header.filetype[0] != 'D' || header.filetype[1] != 'T' || header.filetype[2] != 'M' || header.filetype[3] != 0x1A)
|
if(header.filetype[0] != 'D' || header.filetype[1] != 'T' || header.filetype[2] != 'M' || header.filetype[3] != 0x1A)
|
||||||
{
|
{
|
||||||
|
@ -433,14 +431,13 @@ void LoadInput(const char *filename)
|
||||||
if (Core::g_CoreStartupParameter.bWii)
|
if (Core::g_CoreStartupParameter.bWii)
|
||||||
ChangeWiiPads();
|
ChangeWiiPads();
|
||||||
|
|
||||||
if (g_recordfd)
|
g_recordfd.Close();
|
||||||
fclose(g_recordfd);
|
|
||||||
|
|
||||||
File::Delete(g_recordFile);
|
File::Delete(g_recordFile);
|
||||||
File::Copy(filename, g_recordFile);
|
File::Copy(filename, g_recordFile);
|
||||||
|
|
||||||
g_recordfd = fopen(g_recordFile.c_str(), "r+b");
|
g_recordfd.Open(g_recordFile, "r+b");
|
||||||
fseeko(g_recordfd, 0, SEEK_END);
|
g_recordfd.Seek(0, SEEK_END);
|
||||||
|
|
||||||
g_rerecords++;
|
g_rerecords++;
|
||||||
|
|
||||||
|
@ -453,11 +450,16 @@ void PlayController(SPADStatus *PadStatus, int controllerID)
|
||||||
{
|
{
|
||||||
// Correct playback is entirely dependent on the emulator polling the controllers
|
// Correct playback is entirely dependent on the emulator polling the controllers
|
||||||
// in the same order done during recording
|
// in the same order done during recording
|
||||||
if(!IsPlayingInput() || !IsUsingPad(controllerID))
|
if (!IsPlayingInput() || !IsUsingPad(controllerID))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
memset(PadStatus, 0, sizeof(SPADStatus));
|
memset(PadStatus, 0, sizeof(SPADStatus));
|
||||||
fread(&g_padState, sizeof(ControllerState), 1, g_recordfd);
|
|
||||||
|
if (!g_recordfd.ReadArray(&g_padState, 1))
|
||||||
|
{
|
||||||
|
Core::DisplayMessage("Movie End", 2000);
|
||||||
|
EndPlayInput(!g_bReadOnly);
|
||||||
|
}
|
||||||
|
|
||||||
PadStatus->triggerLeft = g_padState.TriggerL;
|
PadStatus->triggerLeft = g_padState.TriggerL;
|
||||||
PadStatus->triggerRight = g_padState.TriggerR;
|
PadStatus->triggerRight = g_padState.TriggerR;
|
||||||
|
@ -525,7 +527,7 @@ void PlayController(SPADStatus *PadStatus, int controllerID)
|
||||||
|
|
||||||
SetInputDisplayString(g_padState, controllerID);
|
SetInputDisplayString(g_padState, controllerID);
|
||||||
|
|
||||||
if(feof(g_recordfd) || g_frameCounter >= g_totalFrameCount)
|
if (g_frameCounter >= g_totalFrameCount)
|
||||||
{
|
{
|
||||||
Core::DisplayMessage("Movie End", 2000);
|
Core::DisplayMessage("Movie End", 2000);
|
||||||
EndPlayInput(!g_bReadOnly);
|
EndPlayInput(!g_bReadOnly);
|
||||||
|
@ -538,12 +540,11 @@ bool PlayWiimote(int wiimote, u8 *data, s8 &size)
|
||||||
if(!IsPlayingInput() || !IsUsingWiimote(wiimote))
|
if(!IsPlayingInput() || !IsUsingWiimote(wiimote))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
fread(&count, 1, 1, g_recordfd);
|
g_recordfd.ReadArray(&count, 1);
|
||||||
size = (count > size) ? size : count;
|
size = (count > size) ? size : count;
|
||||||
fread(data, 1, size, g_recordfd);
|
|
||||||
|
|
||||||
// TODO: merge this with the above so that there's no duplicate code
|
// TODO: merge this with the above so that there's no duplicate code
|
||||||
if(feof(g_recordfd) || g_frameCounter >= g_totalFrameCount)
|
if (g_frameCounter >= g_totalFrameCount || !g_recordfd.ReadBytes(data, size))
|
||||||
{
|
{
|
||||||
Core::DisplayMessage("Movie End", 2000);
|
Core::DisplayMessage("Movie End", 2000);
|
||||||
EndPlayInput(!g_bReadOnly);
|
EndPlayInput(!g_bReadOnly);
|
||||||
|
@ -559,19 +560,17 @@ void EndPlayInput(bool cont)
|
||||||
// from the exact point in playback we're at now
|
// from the exact point in playback we're at now
|
||||||
// if playback ends before the end of the file.
|
// if playback ends before the end of the file.
|
||||||
SaveRecording(g_tmpRecordFile.c_str());
|
SaveRecording(g_tmpRecordFile.c_str());
|
||||||
fclose(g_recordfd);
|
g_recordfd.Close();
|
||||||
File::Delete(g_recordFile);
|
File::Delete(g_recordFile);
|
||||||
File::Copy(g_tmpRecordFile, g_recordFile);
|
File::Copy(g_tmpRecordFile, g_recordFile);
|
||||||
g_recordfd = fopen(g_recordFile.c_str(), "r+b");
|
g_recordfd.Open(g_recordFile, "r+b");
|
||||||
fseeko(g_recordfd, 0, SEEK_END);
|
g_recordfd.Seek(0, SEEK_END);
|
||||||
g_playMode = MODE_RECORDING;
|
g_playMode = MODE_RECORDING;
|
||||||
Core::DisplayMessage("Resuming movie recording", 2000);
|
Core::DisplayMessage("Resuming movie recording", 2000);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (g_recordfd)
|
g_recordfd.Close();
|
||||||
fclose(g_recordfd);
|
|
||||||
g_recordfd = NULL;
|
|
||||||
g_numPads = g_rerecords = 0;
|
g_numPads = g_rerecords = 0;
|
||||||
g_totalFrameCount = g_frameCounter = g_lagCounter = 0;
|
g_totalFrameCount = g_frameCounter = g_lagCounter = 0;
|
||||||
g_playMode = MODE_NONE;
|
g_playMode = MODE_NONE;
|
||||||
|
@ -580,14 +579,14 @@ void EndPlayInput(bool cont)
|
||||||
|
|
||||||
void SaveRecording(const char *filename)
|
void SaveRecording(const char *filename)
|
||||||
{
|
{
|
||||||
off_t size = ftello(g_recordfd);
|
const off_t size = g_recordfd.Tell();
|
||||||
|
|
||||||
// NOTE: Eventually this will not happen in
|
// NOTE: Eventually this will not happen in
|
||||||
// read-only mode, but we need a way for the save state to
|
// read-only mode, but we need a way for the save state to
|
||||||
// store the current point in the file first.
|
// store the current point in the file first.
|
||||||
// if (!g_bReadOnly)
|
// if (!g_bReadOnly)
|
||||||
{
|
{
|
||||||
rewind(g_recordfd);
|
rewind(g_recordfd.GetHandle());
|
||||||
|
|
||||||
// Create the real header now and write it
|
// Create the real header now and write it
|
||||||
DTMHeader header;
|
DTMHeader header;
|
||||||
|
@ -609,11 +608,11 @@ void SaveRecording(const char *filename)
|
||||||
// header.videoBackend;
|
// header.videoBackend;
|
||||||
// header.audioEmulator;
|
// header.audioEmulator;
|
||||||
|
|
||||||
fwrite(&header, sizeof(DTMHeader), 1, g_recordfd);
|
g_recordfd.WriteArray(&header, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool success = false;
|
bool success = false;
|
||||||
fclose(g_recordfd);
|
g_recordfd.Close();
|
||||||
File::Delete(filename);
|
File::Delete(filename);
|
||||||
success = File::Copy(g_recordFile, filename);
|
success = File::Copy(g_recordFile, filename);
|
||||||
|
|
||||||
|
@ -649,7 +648,7 @@ void SaveRecording(const char *filename)
|
||||||
else
|
else
|
||||||
Core::DisplayMessage(StringFromFormat("Failed to save %s", filename).c_str(), 2000);
|
Core::DisplayMessage(StringFromFormat("Failed to save %s", filename).c_str(), 2000);
|
||||||
|
|
||||||
g_recordfd = fopen(g_recordFile.c_str(), "r+b");
|
g_recordfd.Open(g_recordFile, "r+b");
|
||||||
fseeko(g_recordfd, size, SEEK_SET);
|
g_recordfd.Seek(size, SEEK_SET);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#define __FRAME_H
|
#define __FRAME_H
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
#include "FileUtil.h"
|
||||||
#include "../../InputCommon/Src/GCPadStatus.h"
|
#include "../../InputCommon/Src/GCPadStatus.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -59,7 +60,7 @@ extern unsigned int g_framesToSkip, g_frameSkipCounter;
|
||||||
extern int g_numPads;
|
extern int g_numPads;
|
||||||
extern ControllerState *g_padStates;
|
extern ControllerState *g_padStates;
|
||||||
extern char g_playingFile[256];
|
extern char g_playingFile[256];
|
||||||
extern FILE *g_recordfd;
|
extern File::IOFile g_recordfd;
|
||||||
extern std::string g_recordFile;
|
extern std::string g_recordFile;
|
||||||
|
|
||||||
extern u64 g_frameCounter, g_lagCounter;
|
extern u64 g_frameCounter, g_lagCounter;
|
||||||
|
|
|
@ -269,19 +269,21 @@ static std::map<u32, int> been_here;
|
||||||
|
|
||||||
static void ImHere()
|
static void ImHere()
|
||||||
{
|
{
|
||||||
static FILE *f = 0;
|
static File::IOFile f;
|
||||||
if (ImHereLog) {
|
if (ImHereLog)
|
||||||
|
{
|
||||||
if (!f)
|
if (!f)
|
||||||
{
|
{
|
||||||
#ifdef _M_X64
|
#ifdef _M_X64
|
||||||
f = fopen("log64.txt", "w");
|
f.Open("log64.txt", "w");
|
||||||
#else
|
#else
|
||||||
f = fopen("log32.txt", "w");
|
f.Open("log32.txt", "w");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
fprintf(f, "%08x\n", PC);
|
fprintf(f.GetHandle(), "%08x\n", PC);
|
||||||
}
|
}
|
||||||
if (been_here.find(PC) != been_here.end()) {
|
if (been_here.find(PC) != been_here.end())
|
||||||
|
{
|
||||||
been_here.find(PC)->second++;
|
been_here.find(PC)->second++;
|
||||||
if ((been_here.find(PC)->second) & 1023)
|
if ((been_here.find(PC)->second) & 1023)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1225,20 +1225,18 @@ InstLoc IRBuilder::isNeg(InstLoc I) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Move the following code to a separated file.
|
// TODO: Move the following code to a separated file.
|
||||||
struct Writer {
|
struct Writer
|
||||||
FILE* file;
|
{
|
||||||
Writer() : file(NULL) {
|
File::IOFile file;
|
||||||
|
Writer() : file(NULL)
|
||||||
|
{
|
||||||
char buffer[1024];
|
char buffer[1024];
|
||||||
sprintf(buffer, "JitIL_IR_%d.txt", (int)time(NULL));
|
sprintf(buffer, "JitIL_IR_%d.txt", (int)time(NULL));
|
||||||
file = fopen(buffer, "w");
|
file.Open(buffer, "w");
|
||||||
setvbuf(file, NULL, _IOFBF, 1024 * 1024);
|
setvbuf(file.GetHandle(), NULL, _IOFBF, 1024 * 1024);
|
||||||
}
|
|
||||||
virtual ~Writer() {
|
|
||||||
if (file) {
|
|
||||||
fclose(file);
|
|
||||||
file = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual ~Writer() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::auto_ptr<Writer> writer;
|
static std::auto_ptr<Writer> writer;
|
||||||
|
@ -1295,7 +1293,7 @@ void IRBuilder::WriteToFile(u64 codeHash) {
|
||||||
writer = std::auto_ptr<Writer>(new Writer);
|
writer = std::auto_ptr<Writer>(new Writer);
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE* file = writer->file;
|
FILE* const file = writer->file.GetHandle();
|
||||||
fprintf(file, "\ncode hash:%016llx\n", codeHash);
|
fprintf(file, "\ncode hash:%016llx\n", codeHash);
|
||||||
|
|
||||||
const InstLoc lastCurReadPtr = curReadPtr;
|
const InstLoc lastCurReadPtr = curReadPtr;
|
||||||
|
|
|
@ -227,19 +227,17 @@ namespace JitILProfiler
|
||||||
{
|
{
|
||||||
char buffer[1024];
|
char buffer[1024];
|
||||||
sprintf(buffer, "JitIL_profiling_%d.csv", (int)time(NULL));
|
sprintf(buffer, "JitIL_profiling_%d.csv", (int)time(NULL));
|
||||||
FILE* file = fopen(buffer, "w");
|
File::IOFile file(buffer, "w");
|
||||||
setvbuf(file, NULL, _IOFBF, 1024 * 1024);
|
setvbuf(file.GetHandle(), NULL, _IOFBF, 1024 * 1024);
|
||||||
fprintf(file, "code hash,total elapsed,number of calls,elapsed per call\n");
|
fprintf(file.GetHandle(), "code hash,total elapsed,number of calls,elapsed per call\n");
|
||||||
for (std::vector<Block>::iterator it = blocks.begin(), itEnd = blocks.end(); it != itEnd; ++it)
|
for (std::vector<Block>::iterator it = blocks.begin(), itEnd = blocks.end(); it != itEnd; ++it)
|
||||||
{
|
{
|
||||||
const u64 codeHash = it->codeHash;
|
const u64 codeHash = it->codeHash;
|
||||||
const u64 totalElapsed = it->totalElapsed;
|
const u64 totalElapsed = it->totalElapsed;
|
||||||
const u64 numberOfCalls = it->numberOfCalls;
|
const u64 numberOfCalls = it->numberOfCalls;
|
||||||
const double elapsedPerCall = totalElapsed / (double)numberOfCalls;
|
const double elapsedPerCall = totalElapsed / (double)numberOfCalls;
|
||||||
fprintf(file, "%016llx,%lld,%lld,%f\n", codeHash, totalElapsed, numberOfCalls, elapsedPerCall);
|
fprintf(file.GetHandle(), "%016llx,%lld,%lld,%f\n", codeHash, totalElapsed, numberOfCalls, elapsedPerCall);
|
||||||
}
|
}
|
||||||
fclose(file);
|
|
||||||
file = NULL;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
std::auto_ptr<JitILProfilerFinalizer> finalizer;
|
std::auto_ptr<JitILProfilerFinalizer> finalizer;
|
||||||
|
@ -369,18 +367,20 @@ static std::map<u32, int> been_here;
|
||||||
|
|
||||||
static void ImHere()
|
static void ImHere()
|
||||||
{
|
{
|
||||||
static FILE *f = 0;
|
static File::IOFile f;
|
||||||
if (ImHereLog)
|
if (ImHereLog)
|
||||||
{
|
{
|
||||||
if (!f)
|
if (!f)
|
||||||
{
|
{
|
||||||
#ifdef _M_X64
|
#ifdef _M_X64
|
||||||
f = fopen("log64.txt", "w");
|
f.Open("log64.txt", "w");
|
||||||
#else
|
#else
|
||||||
f = fopen("log32.txt", "w");
|
f.Open("log32.txt", "w");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
fprintf(f, "%08x r0: %08x r5: %08x r6: %08x\n", PC, PowerPC::ppcState.gpr[0], PowerPC::ppcState.gpr[5], PowerPC::ppcState.gpr[6]); fflush(f);
|
fprintf(f.GetHandle(), "%08x r0: %08x r5: %08x r6: %08x\n", PC, PowerPC::ppcState.gpr[0],
|
||||||
|
PowerPC::ppcState.gpr[5], PowerPC::ppcState.gpr[6]);
|
||||||
|
f.Flush();
|
||||||
}
|
}
|
||||||
if (been_here.find(PC) != been_here.end()) {
|
if (been_here.find(PC) != been_here.end()) {
|
||||||
been_here.find(PC)->second++;
|
been_here.find(PC)->second++;
|
||||||
|
|
|
@ -15,12 +15,13 @@
|
||||||
// Official SVN repository and contact information can be found at
|
// Official SVN repository and contact information can be found at
|
||||||
// http://code.google.com/p/dolphin-emu/
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
#include "Common.h"
|
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
#include "FileUtil.h"
|
||||||
|
|
||||||
#include "../HW/Memmap.h"
|
#include "../HW/Memmap.h"
|
||||||
#include "../PowerPC/PowerPC.h"
|
#include "../PowerPC/PowerPC.h"
|
||||||
#include "../Host.h"
|
#include "../Host.h"
|
||||||
|
@ -206,19 +207,21 @@ void PPCSymbolDB::LogFunctionCall(u32 addr)
|
||||||
// produced by SaveSymbolMap below.
|
// produced by SaveSymbolMap below.
|
||||||
bool PPCSymbolDB::LoadMap(const char *filename)
|
bool PPCSymbolDB::LoadMap(const char *filename)
|
||||||
{
|
{
|
||||||
FILE *f = fopen(filename, "r");
|
File::IOFile f(filename, "r");
|
||||||
if (!f)
|
if (!f)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
bool started = false;
|
bool started = false;
|
||||||
while (!feof(f))
|
|
||||||
|
char line[512];
|
||||||
|
while (fgets(line, 512, f.GetHandle()))
|
||||||
{
|
{
|
||||||
char line[512], temp[256];
|
|
||||||
fgets(line, 511, f);
|
|
||||||
if (strlen(line) < 4)
|
if (strlen(line) < 4)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
char temp[256];
|
||||||
sscanf(line, "%s", temp);
|
sscanf(line, "%s", temp);
|
||||||
|
|
||||||
if (strcmp(temp, "UNUSED")==0) continue;
|
if (strcmp(temp, "UNUSED")==0) continue;
|
||||||
if (strcmp(temp, ".text")==0) {started = true; continue;};
|
if (strcmp(temp, ".text")==0) {started = true; continue;};
|
||||||
if (strcmp(temp, ".init")==0) {started = true; continue;};
|
if (strcmp(temp, ".init")==0) {started = true; continue;};
|
||||||
|
@ -261,7 +264,6 @@ bool PPCSymbolDB::LoadMap(const char *filename)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(f);
|
|
||||||
Index();
|
Index();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -287,14 +289,14 @@ bool PPCSymbolDB::SaveMap(const char *filename, bool WithCodes) const
|
||||||
if (WithCodes) Host_UpdateStatusBar("Saving code, please stand by ...");
|
if (WithCodes) Host_UpdateStatusBar("Saving code, please stand by ...");
|
||||||
|
|
||||||
// Make a file
|
// Make a file
|
||||||
FILE *f = fopen(mapFile.c_str(), "w");
|
File::IOFile f(mapFile, "w");
|
||||||
if (!f) return false;
|
if (!f)
|
||||||
|
return false;
|
||||||
|
|
||||||
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
||||||
// Walk through every code row
|
// Walk through every code row
|
||||||
// -------------------------
|
// -------------------------
|
||||||
fprintf(f, ".text\n"); // Write ".text" at the top
|
fprintf(f.GetHandle(), ".text\n"); // Write ".text" at the top
|
||||||
XFuncMap::const_iterator itr = functions.begin();
|
XFuncMap::const_iterator itr = functions.begin();
|
||||||
u32 LastAddress = 0x80004000;
|
u32 LastAddress = 0x80004000;
|
||||||
std::string LastSymbolName;
|
std::string LastSymbolName;
|
||||||
|
@ -304,7 +306,7 @@ bool PPCSymbolDB::SaveMap(const char *filename, bool WithCodes) const
|
||||||
const Symbol &rSymbol = itr->second;
|
const Symbol &rSymbol = itr->second;
|
||||||
if (!WithCodes)
|
if (!WithCodes)
|
||||||
{
|
{
|
||||||
fprintf(f,"%08x %08x %08x %i %s\n", rSymbol.address, rSymbol.size, rSymbol.address,
|
fprintf(f.GetHandle(),"%08x %08x %08x %i %s\n", rSymbol.address, rSymbol.size, rSymbol.address,
|
||||||
0, rSymbol.name.c_str());
|
0, rSymbol.name.c_str());
|
||||||
++itr;
|
++itr;
|
||||||
}
|
}
|
||||||
|
@ -340,15 +342,15 @@ bool PPCSymbolDB::SaveMap(const char *filename, bool WithCodes) const
|
||||||
int Address = LastAddress + i;
|
int Address = LastAddress + i;
|
||||||
char disasm[256];
|
char disasm[256];
|
||||||
debugger->disasm(Address, disasm, 256);
|
debugger->disasm(Address, disasm, 256);
|
||||||
fprintf(f,"%08x %i %20s %s\n", Address, 0, TempSym.c_str(), disasm);
|
fprintf(f.GetHandle(),"%08x %i %20s %s\n", Address, 0, TempSym.c_str(), disasm);
|
||||||
}
|
}
|
||||||
// Write a blank line after each block
|
// Write a blank line after each block
|
||||||
fprintf(f, "\n");
|
fprintf(f.GetHandle(), "\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// ---------------
|
// ---------------
|
||||||
Host_UpdateStatusBar(StringFromFormat("Saved %s", mapFile.c_str()).c_str());
|
Host_UpdateStatusBar(StringFromFormat("Saved %s", mapFile.c_str()).c_str());
|
||||||
fclose(f);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// ===========
|
// ===========
|
||||||
|
|
|
@ -233,31 +233,34 @@ void PrintInstructionRunCounts()
|
||||||
|
|
||||||
void LogCompiledInstructions()
|
void LogCompiledInstructions()
|
||||||
{
|
{
|
||||||
static int time = 0;
|
static unsigned int time = 0;
|
||||||
FILE *f = fopen(StringFromFormat("%sinst_log%i.txt", File::GetUserPath(D_LOGS_IDX).c_str(), time).c_str(), "w");
|
|
||||||
|
File::IOFile f(StringFromFormat("%sinst_log%i.txt", File::GetUserPath(D_LOGS_IDX).c_str(), time), "w");
|
||||||
for (int i = 0; i < m_numInstructions; i++)
|
for (int i = 0; i < m_numInstructions; i++)
|
||||||
{
|
{
|
||||||
if (m_allInstructions[i]->compileCount > 0) {
|
if (m_allInstructions[i]->compileCount > 0) {
|
||||||
fprintf(f, "%s\t%i\t%i\t%08x\n", m_allInstructions[i]->opname, m_allInstructions[i]->compileCount, m_allInstructions[i]->runCount, m_allInstructions[i]->lastUse);
|
fprintf(f.GetHandle(), "%s\t%i\t%i\t%08x\n", m_allInstructions[i]->opname,
|
||||||
|
m_allInstructions[i]->compileCount, m_allInstructions[i]->runCount, m_allInstructions[i]->lastUse);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fclose(f);
|
|
||||||
f = fopen(StringFromFormat("%sinst_not%i.txt", File::GetUserPath(D_LOGS_IDX).c_str(), time).c_str(), "w");
|
f.Open(StringFromFormat("%sinst_not%i.txt", File::GetUserPath(D_LOGS_IDX).c_str(), time), "w");
|
||||||
for (int i = 0; i < m_numInstructions; i++)
|
for (int i = 0; i < m_numInstructions; i++)
|
||||||
{
|
{
|
||||||
if (m_allInstructions[i]->compileCount == 0) {
|
if (m_allInstructions[i]->compileCount == 0) {
|
||||||
fprintf(f, "%s\t%i\t%i\n", m_allInstructions[i]->opname, m_allInstructions[i]->compileCount, m_allInstructions[i]->runCount);
|
fprintf(f.GetHandle(), "%s\t%i\t%i\n", m_allInstructions[i]->opname,
|
||||||
|
m_allInstructions[i]->compileCount, m_allInstructions[i]->runCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fclose(f);
|
|
||||||
#ifdef OPLOG
|
#ifdef OPLOG
|
||||||
f = fopen(StringFromFormat("%s" OP_TO_LOG "_at.txt", File::GetUserPath(D_LOGS_IDX).c_str(), time).c_str(), "w");
|
f.Open(StringFromFormat("%s" OP_TO_LOG "_at.txt", File::GetUserPath(D_LOGS_IDX).c_str(), time), "w");
|
||||||
for (size_t i = 0; i < rsplocations.size(); i++) {
|
for (size_t i = 0; i < rsplocations.size(); i++) {
|
||||||
fprintf(f, OP_TO_LOG ": %08x\n", rsplocations[i]);
|
fprintf(f.GetHandle(), OP_TO_LOG ": %08x\n", rsplocations[i]);
|
||||||
}
|
}
|
||||||
fclose(f);
|
|
||||||
#endif
|
#endif
|
||||||
time++;
|
|
||||||
|
++time;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "PPCSymbolDB.h"
|
#include "PPCSymbolDB.h"
|
||||||
|
#include "FileUtil.h"
|
||||||
|
|
||||||
namespace Profiler
|
namespace Profiler
|
||||||
{
|
{
|
||||||
|
@ -70,13 +71,13 @@ void WriteProfileResults(const char *filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
sort(stats.begin(), stats.end());
|
sort(stats.begin(), stats.end());
|
||||||
FILE *f = fopen(filename, "w");
|
File::IOFile f(filename, "w");
|
||||||
if (!f)
|
if (!f)
|
||||||
{
|
{
|
||||||
PanicAlert("failed to open %s", filename);
|
PanicAlert("failed to open %s", filename);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fprintf(f, "origAddr\tblkName\tcost\ttimeCost\tpercent\ttimePercent\tOvAllinBlkTime(ms)\tblkCodeSize\n");
|
fprintf(f.GetHandle(), "origAddr\tblkName\tcost\ttimeCost\tpercent\ttimePercent\tOvAllinBlkTime(ms)\tblkCodeSize\n");
|
||||||
for (unsigned int i = 0; i < stats.size(); i++)
|
for (unsigned int i = 0; i < stats.size(); i++)
|
||||||
{
|
{
|
||||||
const JitBlock *block = jit->GetBlockCache()->GetBlock(stats[i].blockNum);
|
const JitBlock *block = jit->GetBlockCache()->GetBlock(stats[i].blockNum);
|
||||||
|
@ -86,17 +87,16 @@ void WriteProfileResults(const char *filename)
|
||||||
double percent = 100.0 * (double)stats[i].cost / (double)cost_sum;
|
double percent = 100.0 * (double)stats[i].cost / (double)cost_sum;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
double timePercent = 100.0 * (double)block->ticCounter / (double)timecost_sum;
|
double timePercent = 100.0 * (double)block->ticCounter / (double)timecost_sum;
|
||||||
fprintf(f, "%08x\t%s\t%llu\t%llu\t%.2lf\t%llf\t%lf\t%i\n",
|
fprintf(f.GetHandle(), "%08x\t%s\t%llu\t%llu\t%.2lf\t%llf\t%lf\t%i\n",
|
||||||
block->originalAddress, name.c_str(), stats[i].cost,
|
block->originalAddress, name.c_str(), stats[i].cost,
|
||||||
block->ticCounter, percent, timePercent,
|
block->ticCounter, percent, timePercent,
|
||||||
(double)block->ticCounter*1000.0/(double)countsPerSec, block->codeSize);
|
(double)block->ticCounter*1000.0/(double)countsPerSec, block->codeSize);
|
||||||
#else
|
#else
|
||||||
fprintf(f, "%08x\t%s\t%llu\t???\t%.2lf\t???\t???\t%i\n",
|
fprintf(f.GetHandle(), "%08x\t%s\t%llu\t???\t%.2lf\t???\t???\t%i\n",
|
||||||
block->originalAddress, name.c_str(), stats[i].cost, percent, block->codeSize);
|
block->originalAddress, name.c_str(), stats[i].cost, percent, block->codeSize);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fclose(f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "PPCAnalyst.h"
|
#include "PPCAnalyst.h"
|
||||||
#include "../HW/Memmap.h"
|
#include "../HW/Memmap.h"
|
||||||
|
#include "FileUtil.h"
|
||||||
|
|
||||||
#include "SignatureDB.h"
|
#include "SignatureDB.h"
|
||||||
#include "PPCSymbolDB.h"
|
#include "PPCSymbolDB.h"
|
||||||
|
@ -36,17 +37,17 @@ struct FuncDesc
|
||||||
|
|
||||||
bool SignatureDB::Load(const char *filename)
|
bool SignatureDB::Load(const char *filename)
|
||||||
{
|
{
|
||||||
FILE *f = fopen(filename, "rb");
|
File::IOFile f(filename, "rb");
|
||||||
if (!f)
|
if (!f)
|
||||||
return false;
|
return false;
|
||||||
u32 fcount = 0;
|
u32 fcount = 0;
|
||||||
fread(&fcount, 4, 1, f);
|
f.ReadArray(&fcount, 1);
|
||||||
for (size_t i = 0; i < fcount; i++)
|
for (size_t i = 0; i < fcount; i++)
|
||||||
{
|
{
|
||||||
FuncDesc temp;
|
FuncDesc temp;
|
||||||
memset(&temp, 0, sizeof(temp));
|
memset(&temp, 0, sizeof(temp));
|
||||||
|
|
||||||
fread(&temp, sizeof(temp), 1, f);
|
f.ReadArray(&temp, 1);
|
||||||
temp.name[sizeof(temp.name)-1] = 0;
|
temp.name[sizeof(temp.name)-1] = 0;
|
||||||
|
|
||||||
DBFunc dbf;
|
DBFunc dbf;
|
||||||
|
@ -54,20 +55,20 @@ bool SignatureDB::Load(const char *filename)
|
||||||
dbf.size = temp.size;
|
dbf.size = temp.size;
|
||||||
database[temp.checkSum] = dbf;
|
database[temp.checkSum] = dbf;
|
||||||
}
|
}
|
||||||
fclose(f);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SignatureDB::Save(const char *filename)
|
bool SignatureDB::Save(const char *filename)
|
||||||
{
|
{
|
||||||
FILE *f = fopen(filename,"wb");
|
File::IOFile f(filename, "wb");
|
||||||
if (!f)
|
if (!f)
|
||||||
{
|
{
|
||||||
ERROR_LOG(OSHLE, "Database save failed");
|
ERROR_LOG(OSHLE, "Database save failed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
int fcount = (int)database.size();
|
u32 fcount = (u32)database.size();
|
||||||
fwrite(&fcount, 4, 1, f);
|
f.WriteArray(&fcount, 1);
|
||||||
for (FuncDB::const_iterator iter = database.begin(); iter != database.end(); ++iter)
|
for (FuncDB::const_iterator iter = database.begin(); iter != database.end(); ++iter)
|
||||||
{
|
{
|
||||||
FuncDesc temp;
|
FuncDesc temp;
|
||||||
|
@ -75,9 +76,9 @@ bool SignatureDB::Save(const char *filename)
|
||||||
temp.checkSum = iter->first;
|
temp.checkSum = iter->first;
|
||||||
temp.size = iter->second.size;
|
temp.size = iter->second.size;
|
||||||
strncpy(temp.name, iter->second.name.c_str(), 127);
|
strncpy(temp.name, iter->second.name.c_str(), 127);
|
||||||
fwrite(&temp, sizeof(temp), 1, f);
|
f.WriteArray(&temp, 1);
|
||||||
}
|
}
|
||||||
fclose(f);
|
|
||||||
INFO_LOG(OSHLE, "Database save successful");
|
INFO_LOG(OSHLE, "Database save successful");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -188,8 +188,8 @@ void CompressAndDumpState(saveStruct* saveArg)
|
||||||
Core::DisplayMessage("Failed to move previous state to state undo backup", 1000);
|
Core::DisplayMessage("Failed to move previous state to state undo backup", 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE *f = fopen(filename.c_str(), "wb");
|
File::IOFile f(filename, "wb");
|
||||||
if (f == NULL)
|
if (!f)
|
||||||
{
|
{
|
||||||
Core::DisplayMessage("Could not save state", 2000);
|
Core::DisplayMessage("Could not save state", 2000);
|
||||||
delete[] buffer;
|
delete[] buffer;
|
||||||
|
@ -200,7 +200,7 @@ void CompressAndDumpState(saveStruct* saveArg)
|
||||||
memcpy(header.gameID, SConfig::GetInstance().m_LocalCoreStartupParameter.GetUniqueID().c_str(), 6);
|
memcpy(header.gameID, SConfig::GetInstance().m_LocalCoreStartupParameter.GetUniqueID().c_str(), 6);
|
||||||
header.sz = bCompressed ? sz : 0;
|
header.sz = bCompressed ? sz : 0;
|
||||||
|
|
||||||
fwrite(&header, sizeof(state_header), 1, f);
|
f.WriteArray(&header, 1);
|
||||||
if (bCompressed)
|
if (bCompressed)
|
||||||
{
|
{
|
||||||
lzo_uint cur_len = 0;
|
lzo_uint cur_len = 0;
|
||||||
|
@ -217,8 +217,8 @@ void CompressAndDumpState(saveStruct* saveArg)
|
||||||
PanicAlertT("Internal LZO Error - compression failed");
|
PanicAlertT("Internal LZO Error - compression failed");
|
||||||
|
|
||||||
// The size of the data to write is 'out_len'
|
// The size of the data to write is 'out_len'
|
||||||
fwrite(&out_len, sizeof(int), 1, f);
|
f.WriteArray(&out_len, 1);
|
||||||
fwrite(out, out_len, 1, f);
|
f.WriteBytes(out, out_len);
|
||||||
|
|
||||||
if (cur_len != IN_LEN)
|
if (cur_len != IN_LEN)
|
||||||
break;
|
break;
|
||||||
|
@ -227,10 +227,9 @@ void CompressAndDumpState(saveStruct* saveArg)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fwrite(buffer, sz, 1, f);
|
f.WriteBytes(buffer, sz);
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(f);
|
|
||||||
delete[] buffer;
|
delete[] buffer;
|
||||||
|
|
||||||
Core::DisplayMessage(StringFromFormat("Saved State to %s",
|
Core::DisplayMessage(StringFromFormat("Saved State to %s",
|
||||||
|
@ -298,7 +297,7 @@ void LoadStateCallback(u64 userdata, int cyclesLate)
|
||||||
SaveBufferStateCallback(userdata, cyclesLate);
|
SaveBufferStateCallback(userdata, cyclesLate);
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE *f = fopen(cur_filename.c_str(), "rb");
|
File::IOFile f(cur_filename, "rb");
|
||||||
if (!f)
|
if (!f)
|
||||||
{
|
{
|
||||||
Core::DisplayMessage("State not found", 2000);
|
Core::DisplayMessage("State not found", 2000);
|
||||||
|
@ -311,7 +310,7 @@ void LoadStateCallback(u64 userdata, int cyclesLate)
|
||||||
state_header header;
|
state_header header;
|
||||||
size_t sz;
|
size_t sz;
|
||||||
|
|
||||||
fread(&header, sizeof(state_header), 1, f);
|
f.ReadArray(&header, 1);
|
||||||
|
|
||||||
if (memcmp(SConfig::GetInstance().m_LocalCoreStartupParameter.GetUniqueID().c_str(), header.gameID, 6))
|
if (memcmp(SConfig::GetInstance().m_LocalCoreStartupParameter.GetUniqueID().c_str(), header.gameID, 6))
|
||||||
{
|
{
|
||||||
|
@ -320,7 +319,6 @@ void LoadStateCallback(u64 userdata, int cyclesLate)
|
||||||
Core::DisplayMessage(StringFromFormat("State belongs to a different game (ID %s)",
|
Core::DisplayMessage(StringFromFormat("State belongs to a different game (ID %s)",
|
||||||
gameID), 2000);
|
gameID), 2000);
|
||||||
|
|
||||||
fclose(f);
|
|
||||||
// Resume the clock
|
// Resume the clock
|
||||||
CCPU::EnableStepping(false);
|
CCPU::EnableStepping(false);
|
||||||
return;
|
return;
|
||||||
|
@ -345,18 +343,17 @@ void LoadStateCallback(u64 userdata, int cyclesLate)
|
||||||
{
|
{
|
||||||
lzo_uint cur_len = 0; // number of bytes to read
|
lzo_uint cur_len = 0; // number of bytes to read
|
||||||
lzo_uint new_len = 0; // number of bytes to write
|
lzo_uint new_len = 0; // number of bytes to write
|
||||||
if (fread(&cur_len, 1, sizeof(int), f) == 0)
|
|
||||||
|
if (!f.ReadArray(&cur_len, 1))
|
||||||
break;
|
break;
|
||||||
if (feof(f))
|
|
||||||
break; // don't know if this happens.
|
f.ReadBytes(out, cur_len);
|
||||||
fread(out, 1, cur_len, f);
|
|
||||||
int res = lzo1x_decompress(out, cur_len, (buffer + i), &new_len, NULL);
|
int res = lzo1x_decompress(out, cur_len, (buffer + i), &new_len, NULL);
|
||||||
if (res != LZO_E_OK)
|
if (res != LZO_E_OK)
|
||||||
{
|
{
|
||||||
// This doesn't seem to happen anymore.
|
// This doesn't seem to happen anymore.
|
||||||
PanicAlertT("Internal LZO Error - decompression failed (%d) (%li, %li) \n"
|
PanicAlertT("Internal LZO Error - decompression failed (%d) (%li, %li) \n"
|
||||||
"Try loading the state again", res, i, new_len);
|
"Try loading the state again", res, i, new_len);
|
||||||
fclose(f);
|
|
||||||
delete[] buffer;
|
delete[] buffer;
|
||||||
// Resume the clock
|
// Resume the clock
|
||||||
CCPU::EnableStepping(false);
|
CCPU::EnableStepping(false);
|
||||||
|
@ -368,14 +365,13 @@ void LoadStateCallback(u64 userdata, int cyclesLate)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sz = (int)(File::GetSize(f) - sizeof(state_header));
|
sz = (int)(f.GetSize() - sizeof(state_header));
|
||||||
buffer = new u8[sz];
|
buffer = new u8[sz];
|
||||||
int x;
|
if (!f.ReadBytes(buffer, sz))
|
||||||
if ((x = (int)fread(buffer, 1, sz, f)) != (int)sz)
|
PanicAlert("wtf? reading bytes: %lu", (unsigned long)sz);
|
||||||
PanicAlert("wtf? %d %lu", x, (unsigned long)sz);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(f);
|
f.Close();
|
||||||
|
|
||||||
u8 *ptr = buffer;
|
u8 *ptr = buffer;
|
||||||
PointerWrap p(&ptr, PointerWrap::MODE_READ);
|
PointerWrap p(&ptr, PointerWrap::MODE_READ);
|
||||||
|
@ -405,7 +401,7 @@ void VerifyStateCallback(u64 userdata, int cyclesLate)
|
||||||
|
|
||||||
State_Flush();
|
State_Flush();
|
||||||
|
|
||||||
FILE *f = fopen(cur_filename.c_str(), "rb");
|
File::IOFile f(cur_filename, "rb");
|
||||||
if (!f)
|
if (!f)
|
||||||
{
|
{
|
||||||
Core::DisplayMessage("State not found", 2000);
|
Core::DisplayMessage("State not found", 2000);
|
||||||
|
@ -416,7 +412,7 @@ void VerifyStateCallback(u64 userdata, int cyclesLate)
|
||||||
state_header header;
|
state_header header;
|
||||||
size_t sz;
|
size_t sz;
|
||||||
|
|
||||||
fread(&header, sizeof(state_header), 1, f);
|
f.ReadArray(&header, 1);
|
||||||
|
|
||||||
if (memcmp(SConfig::GetInstance().m_LocalCoreStartupParameter.GetUniqueID().c_str(), header.gameID, 6))
|
if (memcmp(SConfig::GetInstance().m_LocalCoreStartupParameter.GetUniqueID().c_str(), header.gameID, 6))
|
||||||
{
|
{
|
||||||
|
@ -425,8 +421,6 @@ void VerifyStateCallback(u64 userdata, int cyclesLate)
|
||||||
Core::DisplayMessage(StringFromFormat("State belongs to a different game (ID %s)",
|
Core::DisplayMessage(StringFromFormat("State belongs to a different game (ID %s)",
|
||||||
gameID), 2000);
|
gameID), 2000);
|
||||||
|
|
||||||
fclose(f);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -446,18 +440,17 @@ void VerifyStateCallback(u64 userdata, int cyclesLate)
|
||||||
{
|
{
|
||||||
lzo_uint cur_len = 0;
|
lzo_uint cur_len = 0;
|
||||||
lzo_uint new_len = 0;
|
lzo_uint new_len = 0;
|
||||||
if (fread(&cur_len, 1, sizeof(int), f) == 0)
|
if (!f.ReadArray(&cur_len, 1))
|
||||||
break;
|
break;
|
||||||
if (feof(f))
|
|
||||||
break; // don't know if this happens.
|
f.ReadBytes(out, cur_len);
|
||||||
fread(out, 1, cur_len, f);
|
|
||||||
int res = lzo1x_decompress(out, cur_len, (buffer + i), &new_len, NULL);
|
int res = lzo1x_decompress(out, cur_len, (buffer + i), &new_len, NULL);
|
||||||
if (res != LZO_E_OK)
|
if (res != LZO_E_OK)
|
||||||
{
|
{
|
||||||
// This doesn't seem to happen anymore.
|
// This doesn't seem to happen anymore.
|
||||||
PanicAlertT("Internal LZO Error - decompression failed (%d) (%ld, %ld) \n"
|
PanicAlertT("Internal LZO Error - decompression failed (%d) (%ld, %ld) \n"
|
||||||
"Try verifying the state again", res, i, new_len);
|
"Try verifying the state again", res, i, new_len);
|
||||||
fclose(f);
|
|
||||||
delete [] buffer;
|
delete [] buffer;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -468,14 +461,12 @@ void VerifyStateCallback(u64 userdata, int cyclesLate)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sz = (int)(File::GetSize(f) - sizeof(int));
|
sz = (int)(f.GetSize() - sizeof(int));
|
||||||
buffer = new u8[sz];
|
buffer = new u8[sz];
|
||||||
int x;
|
|
||||||
if ((x = (int)fread(buffer, 1, sz, f)) != (int)sz)
|
|
||||||
PanicAlert("wtf? %d %lu", x, (unsigned long)sz);
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(f);
|
if (!f.ReadBytes(buffer, sz))
|
||||||
|
PanicAlert("wtf? failed to read bytes: %lu", (unsigned long)sz);
|
||||||
|
}
|
||||||
|
|
||||||
u8 *ptr = buffer;
|
u8 *ptr = buffer;
|
||||||
PointerWrap p(&ptr, PointerWrap::MODE_VERIFY);
|
PointerWrap p(&ptr, PointerWrap::MODE_VERIFY);
|
||||||
|
|
|
@ -15,11 +15,11 @@
|
||||||
// Official SVN repository and contact information can be found at
|
// Official SVN repository and contact information can be found at
|
||||||
// http://code.google.com/p/dolphin-emu/
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "Tracer.h"
|
#include "Tracer.h"
|
||||||
|
#include "FileUtil.h"
|
||||||
|
|
||||||
#include "Host.h"
|
#include "Host.h"
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
|
|
||||||
FILE *tracefile;
|
File::IOFile tracefile;
|
||||||
|
|
||||||
bool bReadTrace = false;
|
bool bReadTrace = false;
|
||||||
bool bWriteTrace = false;
|
bool bWriteTrace = false;
|
||||||
|
@ -36,13 +36,13 @@ void StartTrace(bool write)
|
||||||
{
|
{
|
||||||
if (write)
|
if (write)
|
||||||
{
|
{
|
||||||
tracefile = fopen("L:\\trace.dat","wb");
|
tracefile.Open("L:\\trace.dat", "wb");
|
||||||
bReadTrace = false;
|
bReadTrace = false;
|
||||||
bWriteTrace = true;
|
bWriteTrace = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tracefile = fopen("L:\\trace.dat","rb");
|
tracefile.Open("L:\\trace.dat", "rb");
|
||||||
bReadTrace = true;
|
bReadTrace = true;
|
||||||
bWriteTrace = false;
|
bWriteTrace = false;
|
||||||
}
|
}
|
||||||
|
@ -50,11 +50,7 @@ void StartTrace(bool write)
|
||||||
|
|
||||||
void StopTrace()
|
void StopTrace()
|
||||||
{
|
{
|
||||||
if (tracefile)
|
tracefile.Close();
|
||||||
{
|
|
||||||
fclose(tracefile);
|
|
||||||
tracefile = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int stateSize = 32*4;// + 32*16 + 6*4;
|
static int stateSize = 32*4;// + 32*16 + 6*4;
|
||||||
|
@ -63,18 +59,16 @@ int SyncTrace()
|
||||||
{
|
{
|
||||||
if (bWriteTrace)
|
if (bWriteTrace)
|
||||||
{
|
{
|
||||||
fwrite(&PowerPC::ppcState, stateSize, 1, tracefile);
|
tracefile.WriteBytes(&PowerPC::ppcState, stateSize);
|
||||||
fflush(tracefile);
|
tracefile.Flush();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (bReadTrace)
|
if (bReadTrace)
|
||||||
{
|
{
|
||||||
PowerPC::PowerPCState state;
|
PowerPC::PowerPCState state;
|
||||||
if (feof(tracefile))
|
if (!tracefile.ReadBytes(&state, stateSize))
|
||||||
{
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
|
||||||
fread(&state, stateSize, 1, tracefile);
|
|
||||||
bool difference = false;
|
bool difference = false;
|
||||||
for (int i=0; i<32; i++)
|
for (int i=0; i<32; i++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -87,11 +87,10 @@ CBannerLoaderWii::CBannerLoaderWii(DiscIO::IVolume *pVolume)
|
||||||
if (FileSize > 0)
|
if (FileSize > 0)
|
||||||
{
|
{
|
||||||
m_pBannerFile = new u8[FileSize];
|
m_pBannerFile = new u8[FileSize];
|
||||||
FILE* pFile = fopen(Filename, "rb");
|
File::IOFile pFile(Filename, "rb");
|
||||||
if (pFile)
|
if (pFile)
|
||||||
{
|
{
|
||||||
fread(m_pBannerFile, FileSize, 1, pFile);
|
pFile.ReadBytes(m_pBannerFile, FileSize);
|
||||||
fclose(pFile);
|
|
||||||
m_IsValid = true;
|
m_IsValid = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,15 +21,13 @@
|
||||||
namespace DiscIO
|
namespace DiscIO
|
||||||
{
|
{
|
||||||
|
|
||||||
CISOFileReader::CISOFileReader(FILE* file__)
|
CISOFileReader::CISOFileReader(std::FILE* file)
|
||||||
|
: m_file(file)
|
||||||
{
|
{
|
||||||
file_ = file__;
|
m_size = m_file.GetSize();
|
||||||
fseek(file_, 0, SEEK_END);
|
|
||||||
size = ftell(file_);
|
|
||||||
fseek(file_, 0, SEEK_SET);
|
|
||||||
|
|
||||||
memset(&header, 0, sizeof(header));
|
memset(&header, 0, sizeof(header));
|
||||||
fread(&header, sizeof(header), 1, file_);
|
m_file.ReadArray(&header, 1);
|
||||||
|
|
||||||
CISO_Map_t count = 0;
|
CISO_Map_t count = 0;
|
||||||
int idx;
|
int idx;
|
||||||
|
@ -41,18 +39,13 @@ CISOFileReader* CISOFileReader::Create(const char* filename)
|
||||||
{
|
{
|
||||||
if (IsCISOBlob(filename))
|
if (IsCISOBlob(filename))
|
||||||
{
|
{
|
||||||
FILE* f = fopen(filename, "rb");
|
File::IOFile f(filename, "rb");
|
||||||
return new CISOFileReader(f);
|
return new CISOFileReader(f.ReleaseHandle());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
CISOFileReader::~CISOFileReader()
|
|
||||||
{
|
|
||||||
fclose(file_);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CISOFileReader::Read(u64 offset, u64 nbytes, u8* out_ptr)
|
bool CISOFileReader::Read(u64 offset, u64 nbytes, u8* out_ptr)
|
||||||
{
|
{
|
||||||
u64 bytesRead = 0;
|
u64 bytesRead = 0;
|
||||||
|
@ -73,9 +66,7 @@ bool CISOFileReader::Read(u64 offset, u64 nbytes, u8* out_ptr)
|
||||||
// calcualte the base address
|
// calcualte the base address
|
||||||
u64 file_off = CISO_HEAD_SIZE + ciso_map[block] * (u64)header.block_size + data_offset;
|
u64 file_off = CISO_HEAD_SIZE + ciso_map[block] * (u64)header.block_size + data_offset;
|
||||||
|
|
||||||
if (fseeko(file_, (long)file_off, SEEK_SET) != 0)
|
if (!(m_file.Seek(file_off, SEEK_SET) && m_file.ReadBytes(out_ptr, bytes_to_read)))
|
||||||
return false;
|
|
||||||
if (fread(out_ptr, 1, bytes_to_read, file_) != bytes_to_read)
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
out_ptr += bytes_to_read;
|
out_ptr += bytes_to_read;
|
||||||
|
@ -88,15 +79,10 @@ bool CISOFileReader::Read(u64 offset, u64 nbytes, u8* out_ptr)
|
||||||
|
|
||||||
bool IsCISOBlob(const char* filename)
|
bool IsCISOBlob(const char* filename)
|
||||||
{
|
{
|
||||||
FILE* f = fopen(filename, "rb");
|
File::IOFile f(filename, "rb");
|
||||||
|
|
||||||
if (!f)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
CISO_Head_t header;
|
CISO_Head_t header;
|
||||||
fread(&header, sizeof(header), 1, f);
|
return (f.ReadArray(&header, 1) && (memcmp(header.magic, CISO_MAGIC, sizeof(header.magic)) == 0));
|
||||||
fclose(f);
|
|
||||||
return (memcmp(header.magic, CISO_MAGIC, sizeof(header.magic)) == 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -19,8 +19,7 @@
|
||||||
#define _CISO_BLOB_H
|
#define _CISO_BLOB_H
|
||||||
|
|
||||||
#include "Blob.h"
|
#include "Blob.h"
|
||||||
|
#include "FileUtil.h"
|
||||||
#include <cstdio>
|
|
||||||
|
|
||||||
#define CISO_MAGIC "CISO"
|
#define CISO_MAGIC "CISO"
|
||||||
#define CISO_HEAD_SIZE (0x8000)
|
#define CISO_HEAD_SIZE (0x8000)
|
||||||
|
@ -32,12 +31,12 @@ namespace DiscIO
|
||||||
bool IsCISOBlob(const char* filename);
|
bool IsCISOBlob(const char* filename);
|
||||||
|
|
||||||
// Blocks that won't compress to less than 97% of the original size are stored as-is.
|
// Blocks that won't compress to less than 97% of the original size are stored as-is.
|
||||||
typedef struct CISO_Head_t
|
struct CISO_Head_t
|
||||||
{
|
{
|
||||||
u8 magic[4]; // "CISO"
|
u8 magic[4]; // "CISO"
|
||||||
u32 block_size; // stored as litte endian (not network byte order)
|
u32 block_size; // stored as litte endian (not network byte order)
|
||||||
u8 map[CISO_MAP_SIZE]; // 0=unused, 1=used, others=invalid
|
u8 map[CISO_MAP_SIZE]; // 0=unused, 1=used, others=invalid
|
||||||
} CISO_Head_t;
|
};
|
||||||
|
|
||||||
typedef u16 CISO_Map_t;
|
typedef u16 CISO_Map_t;
|
||||||
|
|
||||||
|
@ -45,15 +44,15 @@ const CISO_Map_t CISO_UNUSED_BLOCK = (CISO_Map_t)~0;
|
||||||
|
|
||||||
class CISOFileReader : public IBlobReader
|
class CISOFileReader : public IBlobReader
|
||||||
{
|
{
|
||||||
FILE* file_;
|
File::IOFile m_file;
|
||||||
CISOFileReader(FILE* file__);
|
CISOFileReader(std::FILE* file);
|
||||||
s64 size;
|
s64 m_size;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static CISOFileReader* Create(const char* filename);
|
static CISOFileReader* Create(const char* filename);
|
||||||
~CISOFileReader();
|
|
||||||
u64 GetDataSize() const { return size; }
|
u64 GetDataSize() const { return m_size; }
|
||||||
u64 GetRawSize() const { return size; }
|
u64 GetRawSize() const { return m_size; }
|
||||||
bool Read(u64 offset, u64 nbytes, u8* out_ptr);
|
bool Read(u64 offset, u64 nbytes, u8* out_ptr);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -36,17 +36,17 @@ namespace DiscIO
|
||||||
CompressedBlobReader::CompressedBlobReader(const char *filename)
|
CompressedBlobReader::CompressedBlobReader(const char *filename)
|
||||||
{
|
{
|
||||||
file_name = filename;
|
file_name = filename;
|
||||||
file = fopen(filename, "rb");
|
m_file.Open(filename, "rb");
|
||||||
file_size = File::GetSize(filename);
|
file_size = File::GetSize(filename);
|
||||||
fread(&header, sizeof(CompressedBlobHeader), 1, file);
|
m_file.ReadArray(&header, 1);
|
||||||
|
|
||||||
SetSectorSize(header.block_size);
|
SetSectorSize(header.block_size);
|
||||||
|
|
||||||
// cache block pointers and hashes
|
// cache block pointers and hashes
|
||||||
block_pointers = new u64[header.num_blocks];
|
block_pointers = new u64[header.num_blocks];
|
||||||
fread(block_pointers, sizeof(u64), header.num_blocks, file);
|
m_file.ReadArray(block_pointers, header.num_blocks);
|
||||||
hashes = new u32[header.num_blocks];
|
hashes = new u32[header.num_blocks];
|
||||||
fread(hashes, sizeof(u32), header.num_blocks, file);
|
m_file.ReadArray(hashes, header.num_blocks);
|
||||||
|
|
||||||
data_offset = (sizeof(CompressedBlobHeader))
|
data_offset = (sizeof(CompressedBlobHeader))
|
||||||
+ (sizeof(u64)) * header.num_blocks // skip block pointers
|
+ (sizeof(u64)) * header.num_blocks // skip block pointers
|
||||||
|
@ -72,8 +72,6 @@ CompressedBlobReader::~CompressedBlobReader()
|
||||||
delete [] zlib_buffer;
|
delete [] zlib_buffer;
|
||||||
delete [] block_pointers;
|
delete [] block_pointers;
|
||||||
delete [] hashes;
|
delete [] hashes;
|
||||||
fclose(file);
|
|
||||||
file = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// IMPORTANT: Calling this function invalidates all earlier pointers gotten from this function.
|
// IMPORTANT: Calling this function invalidates all earlier pointers gotten from this function.
|
||||||
|
@ -106,8 +104,8 @@ void CompressedBlobReader::GetBlock(u64 block_num, u8 *out_ptr)
|
||||||
// clear unused part of zlib buffer. maybe this can be deleted when it works fully.
|
// clear unused part of zlib buffer. maybe this can be deleted when it works fully.
|
||||||
memset(zlib_buffer + comp_block_size, 0, zlib_buffer_size - comp_block_size);
|
memset(zlib_buffer + comp_block_size, 0, zlib_buffer_size - comp_block_size);
|
||||||
|
|
||||||
fseeko(file, offset, SEEK_SET);
|
m_file.Seek(offset, SEEK_SET);
|
||||||
fread(zlib_buffer, 1, comp_block_size, file);
|
m_file.ReadBytes(zlib_buffer, comp_block_size);
|
||||||
|
|
||||||
u8* source = zlib_buffer;
|
u8* source = zlib_buffer;
|
||||||
u8* dest = out_ptr;
|
u8* dest = out_ptr;
|
||||||
|
@ -173,16 +171,11 @@ bool CompressFileToBlob(const char* infile, const char* outfile, u32 sub_type,
|
||||||
scrubbing = true;
|
scrubbing = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE* inf = fopen(infile, "rb");
|
File::IOFile inf(infile, "rb");
|
||||||
if (!inf)
|
File::IOFile f(outfile, "wb");
|
||||||
return false;
|
|
||||||
|
|
||||||
FILE* f = fopen(outfile, "wb");
|
if (!f || !inf)
|
||||||
if (!f)
|
|
||||||
{
|
|
||||||
fclose(inf);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
callback("Files opened, ready to compress.", 0, arg);
|
callback("Files opened, ready to compress.", 0, arg);
|
||||||
|
|
||||||
|
@ -201,9 +194,9 @@ bool CompressFileToBlob(const char* infile, const char* outfile, u32 sub_type,
|
||||||
u8* in_buf = new u8[block_size];
|
u8* in_buf = new u8[block_size];
|
||||||
|
|
||||||
// seek past the header (we will write it at the end)
|
// seek past the header (we will write it at the end)
|
||||||
fseeko(f, sizeof(CompressedBlobHeader), SEEK_CUR);
|
f.Seek(sizeof(CompressedBlobHeader), SEEK_CUR);
|
||||||
// seek past the offset and hash tables (we will write them at the end)
|
// seek past the offset and hash tables (we will write them at the end)
|
||||||
fseeko(f, (sizeof(u64) + sizeof(u32)) * header.num_blocks, SEEK_CUR);
|
f.Seek((sizeof(u64) + sizeof(u32)) * header.num_blocks, SEEK_CUR);
|
||||||
|
|
||||||
// Now we are ready to write compressed data!
|
// Now we are ready to write compressed data!
|
||||||
u64 position = 0;
|
u64 position = 0;
|
||||||
|
@ -215,7 +208,7 @@ bool CompressFileToBlob(const char* infile, const char* outfile, u32 sub_type,
|
||||||
{
|
{
|
||||||
if (i % progress_monitor == 0)
|
if (i % progress_monitor == 0)
|
||||||
{
|
{
|
||||||
u64 inpos = ftello(inf);
|
const u64 inpos = inf.Tell();
|
||||||
int ratio = 0;
|
int ratio = 0;
|
||||||
if (inpos != 0)
|
if (inpos != 0)
|
||||||
ratio = (int)(100 * position / inpos);
|
ratio = (int)(100 * position / inpos);
|
||||||
|
@ -229,9 +222,9 @@ bool CompressFileToBlob(const char* infile, const char* outfile, u32 sub_type,
|
||||||
// u64 size = header.block_size;
|
// u64 size = header.block_size;
|
||||||
std::fill(in_buf, in_buf + header.block_size, 0);
|
std::fill(in_buf, in_buf + header.block_size, 0);
|
||||||
if (scrubbing)
|
if (scrubbing)
|
||||||
DiscScrubber::GetNextBlock(inf, in_buf);
|
DiscScrubber::GetNextBlock(inf.GetHandle(), in_buf);
|
||||||
else
|
else
|
||||||
fread(in_buf, header.block_size, 1, inf);
|
inf.ReadBytes(in_buf, header.block_size);
|
||||||
z_stream z;
|
z_stream z;
|
||||||
memset(&z, 0, sizeof(z));
|
memset(&z, 0, sizeof(z));
|
||||||
z.zalloc = Z_NULL;
|
z.zalloc = Z_NULL;
|
||||||
|
@ -256,7 +249,7 @@ bool CompressFileToBlob(const char* infile, const char* outfile, u32 sub_type,
|
||||||
//PanicAlert("%i %i Store %i", i*block_size, position, comp_size);
|
//PanicAlert("%i %i Store %i", i*block_size, position, comp_size);
|
||||||
// let's store uncompressed
|
// let's store uncompressed
|
||||||
offsets[i] |= 0x8000000000000000ULL;
|
offsets[i] |= 0x8000000000000000ULL;
|
||||||
fwrite(in_buf, block_size, 1, f);
|
f.WriteBytes(in_buf, block_size);
|
||||||
hashes[i] = HashAdler32(in_buf, block_size);
|
hashes[i] = HashAdler32(in_buf, block_size);
|
||||||
position += block_size;
|
position += block_size;
|
||||||
num_stored++;
|
num_stored++;
|
||||||
|
@ -265,7 +258,7 @@ bool CompressFileToBlob(const char* infile, const char* outfile, u32 sub_type,
|
||||||
{
|
{
|
||||||
// let's store compressed
|
// let's store compressed
|
||||||
//PanicAlert("Comp %i to %i", block_size, comp_size);
|
//PanicAlert("Comp %i to %i", block_size, comp_size);
|
||||||
fwrite(out_buf, comp_size, 1, f);
|
f.WriteBytes(out_buf, comp_size);
|
||||||
hashes[i] = HashAdler32(out_buf, comp_size);
|
hashes[i] = HashAdler32(out_buf, comp_size);
|
||||||
position += comp_size;
|
position += comp_size;
|
||||||
num_compressed++;
|
num_compressed++;
|
||||||
|
@ -277,10 +270,10 @@ bool CompressFileToBlob(const char* infile, const char* outfile, u32 sub_type,
|
||||||
header.compressed_data_size = position;
|
header.compressed_data_size = position;
|
||||||
|
|
||||||
// Okay, go back and fill in headers
|
// Okay, go back and fill in headers
|
||||||
fseeko(f, 0, SEEK_SET);
|
f.Seek(0, SEEK_SET);
|
||||||
fwrite(&header, sizeof(header), 1, f);
|
f.WriteArray(&header, 1);
|
||||||
fwrite(offsets, sizeof(u64), header.num_blocks, f);
|
f.WriteArray(offsets, header.num_blocks);
|
||||||
fwrite(hashes, sizeof(u32), header.num_blocks, f);
|
f.WriteArray(hashes, header.num_blocks);
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
// Cleanup
|
// Cleanup
|
||||||
|
@ -288,8 +281,7 @@ cleanup:
|
||||||
delete[] out_buf;
|
delete[] out_buf;
|
||||||
delete[] offsets;
|
delete[] offsets;
|
||||||
delete[] hashes;
|
delete[] hashes;
|
||||||
fclose(f);
|
|
||||||
fclose(inf);
|
|
||||||
DiscScrubber::Cleanup();
|
DiscScrubber::Cleanup();
|
||||||
callback("Done compressing disc image.", 1.0f, arg);
|
callback("Done compressing disc image.", 1.0f, arg);
|
||||||
return true;
|
return true;
|
||||||
|
@ -306,7 +298,7 @@ bool DecompressBlobToFile(const char* infile, const char* outfile, CompressCB ca
|
||||||
CompressedBlobReader* reader = CompressedBlobReader::Create(infile);
|
CompressedBlobReader* reader = CompressedBlobReader::Create(infile);
|
||||||
if (!reader) return false;
|
if (!reader) return false;
|
||||||
|
|
||||||
FILE* f = fopen(outfile, "wb");
|
File::IOFile f(outfile, "wb");
|
||||||
const CompressedBlobHeader &header = reader->GetHeader();
|
const CompressedBlobHeader &header = reader->GetHeader();
|
||||||
u8* buffer = new u8[header.block_size];
|
u8* buffer = new u8[header.block_size];
|
||||||
int progress_monitor = max<int>(1, header.num_blocks / 100);
|
int progress_monitor = max<int>(1, header.num_blocks / 100);
|
||||||
|
@ -318,19 +310,12 @@ bool DecompressBlobToFile(const char* infile, const char* outfile, CompressCB ca
|
||||||
callback("Unpacking", (float)i / (float)header.num_blocks, arg);
|
callback("Unpacking", (float)i / (float)header.num_blocks, arg);
|
||||||
}
|
}
|
||||||
reader->Read(i * header.block_size, header.block_size, buffer);
|
reader->Read(i * header.block_size, header.block_size, buffer);
|
||||||
fwrite(buffer, header.block_size, 1, f);
|
f.WriteBytes(buffer, header.block_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete[] buffer;
|
delete[] buffer;
|
||||||
|
|
||||||
#ifdef _WIN32
|
f.Resize(header.data_size);
|
||||||
// ector: _chsize sucks, not 64-bit safe
|
|
||||||
// F|RES: changed to _chsize_s. i think it is 64-bit safe
|
|
||||||
_chsize_s(_fileno(f), header.data_size);
|
|
||||||
#else
|
|
||||||
ftruncate(fileno(f), header.data_size);
|
|
||||||
#endif
|
|
||||||
fclose(f);
|
|
||||||
|
|
||||||
delete reader;
|
delete reader;
|
||||||
|
|
||||||
|
@ -339,15 +324,10 @@ bool DecompressBlobToFile(const char* infile, const char* outfile, CompressCB ca
|
||||||
|
|
||||||
bool IsCompressedBlob(const char* filename)
|
bool IsCompressedBlob(const char* filename)
|
||||||
{
|
{
|
||||||
FILE* f = fopen(filename, "rb");
|
File::IOFile f(filename, "rb");
|
||||||
|
|
||||||
if (!f)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
CompressedBlobHeader header;
|
CompressedBlobHeader header;
|
||||||
fread(&header, sizeof(header), 1, f);
|
return f.ReadArray(&header, 1) && (header.magic_cookie == kBlobCookie);
|
||||||
fclose(f);
|
|
||||||
return header.magic_cookie == kBlobCookie;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -28,10 +28,10 @@
|
||||||
#ifndef COMPRESSED_BLOB_H_
|
#ifndef COMPRESSED_BLOB_H_
|
||||||
#define COMPRESSED_BLOB_H_
|
#define COMPRESSED_BLOB_H_
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "Blob.h"
|
#include "Blob.h"
|
||||||
|
#include "FileUtil.h"
|
||||||
|
|
||||||
namespace DiscIO
|
namespace DiscIO
|
||||||
{
|
{
|
||||||
|
@ -73,7 +73,7 @@ private:
|
||||||
u64 *block_pointers;
|
u64 *block_pointers;
|
||||||
u32 *hashes;
|
u32 *hashes;
|
||||||
int data_offset;
|
int data_offset;
|
||||||
FILE *file;
|
File::IOFile m_file;
|
||||||
u64 file_size;
|
u64 file_size;
|
||||||
u8 *zlib_buffer;
|
u8 *zlib_buffer;
|
||||||
int zlib_buffer_size;
|
int zlib_buffer_size;
|
||||||
|
|
|
@ -56,7 +56,7 @@ DriveReader::DriveReader(const char *drive)
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
SectorReader::SetSectorSize(2048);
|
SectorReader::SetSectorSize(2048);
|
||||||
file_ = fopen(drive, "rb");
|
file_.Open(drive, "rb");
|
||||||
if (file_)
|
if (file_)
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
|
@ -81,9 +81,7 @@ DriveReader::~DriveReader()
|
||||||
hDisc = INVALID_HANDLE_VALUE;
|
hDisc = INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (file_)
|
file_.Close();
|
||||||
fclose(file_);
|
|
||||||
file_ = 0;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,7 +98,7 @@ DriveReader *DriveReader::Create(const char *drive)
|
||||||
|
|
||||||
void DriveReader::GetBlock(u64 block_num, u8 *out_ptr)
|
void DriveReader::GetBlock(u64 block_num, u8 *out_ptr)
|
||||||
{
|
{
|
||||||
u8 * lpSector = new u8[m_blocksize];
|
u8* const lpSector = new u8[m_blocksize];
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
u32 NotUsed;
|
u32 NotUsed;
|
||||||
u64 offset = m_blocksize * block_num;
|
u64 offset = m_blocksize * block_num;
|
||||||
|
@ -110,8 +108,8 @@ void DriveReader::GetBlock(u64 block_num, u8 *out_ptr)
|
||||||
if (!ReadFile(hDisc, lpSector, m_blocksize, (LPDWORD)&NotUsed, NULL))
|
if (!ReadFile(hDisc, lpSector, m_blocksize, (LPDWORD)&NotUsed, NULL))
|
||||||
PanicAlertT("Disc Read Error");
|
PanicAlertT("Disc Read Error");
|
||||||
#else
|
#else
|
||||||
fseeko(file_, m_blocksize*block_num, SEEK_SET);
|
file_.Seek(m_blocksize * block_num, SEEK_SET);
|
||||||
fread(lpSector, 1, m_blocksize, file_);
|
file_.ReadBytes(lpSector, m_blocksize);
|
||||||
#endif
|
#endif
|
||||||
memcpy(out_ptr, lpSector, m_blocksize);
|
memcpy(out_ptr, lpSector, m_blocksize);
|
||||||
delete[] lpSector;
|
delete[] lpSector;
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#define _DRIVE_BLOB_H
|
#define _DRIVE_BLOB_H
|
||||||
|
|
||||||
#include "Blob.h"
|
#include "Blob.h"
|
||||||
|
#include "FileUtil.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
@ -39,7 +40,7 @@ private:
|
||||||
PREVENT_MEDIA_REMOVAL pmrLockCDROM;
|
PREVENT_MEDIA_REMOVAL pmrLockCDROM;
|
||||||
bool IsOK() {return hDisc != INVALID_HANDLE_VALUE;}
|
bool IsOK() {return hDisc != INVALID_HANDLE_VALUE;}
|
||||||
#else
|
#else
|
||||||
FILE* file_;
|
File::IOFile file_;
|
||||||
bool IsOK() {return file_ != 0;}
|
bool IsOK() {return file_ != 0;}
|
||||||
#endif
|
#endif
|
||||||
s64 size;
|
s64 size;
|
||||||
|
|
|
@ -15,40 +15,30 @@
|
||||||
// Official SVN repository and contact information can be found at
|
// Official SVN repository and contact information can be found at
|
||||||
// http://code.google.com/p/dolphin-emu/
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
#include "Blob.h"
|
|
||||||
#include "FileBlob.h"
|
#include "FileBlob.h"
|
||||||
#include "FileUtil.h"
|
|
||||||
|
|
||||||
namespace DiscIO
|
namespace DiscIO
|
||||||
{
|
{
|
||||||
|
|
||||||
PlainFileReader::PlainFileReader(FILE* file__)
|
PlainFileReader::PlainFileReader(std::FILE* file)
|
||||||
|
: m_file(file)
|
||||||
{
|
{
|
||||||
file_ = file__;
|
m_size = m_file.GetSize();
|
||||||
size = File::GetSize(file__);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PlainFileReader* PlainFileReader::Create(const char* filename)
|
PlainFileReader* PlainFileReader::Create(const char* filename)
|
||||||
{
|
{
|
||||||
FILE* f = fopen(filename, "rb");
|
File::IOFile f(filename, "rb");
|
||||||
if (f)
|
if (f)
|
||||||
return new PlainFileReader(f);
|
return new PlainFileReader(f.ReleaseHandle());
|
||||||
else
|
else
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
PlainFileReader::~PlainFileReader()
|
|
||||||
{
|
|
||||||
fclose(file_);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PlainFileReader::Read(u64 offset, u64 nbytes, u8* out_ptr)
|
bool PlainFileReader::Read(u64 offset, u64 nbytes, u8* out_ptr)
|
||||||
{
|
{
|
||||||
int seekStatus = fseeko(file_, offset, SEEK_SET);
|
m_file.Seek(offset, SEEK_SET);
|
||||||
if (seekStatus != 0)
|
return m_file.ReadBytes(out_ptr, nbytes);
|
||||||
return false;
|
|
||||||
size_t bytesRead = fread(out_ptr, 1, nbytes, file_);
|
|
||||||
return bytesRead == nbytes;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -19,23 +19,23 @@
|
||||||
#define _FILE_BLOB_H
|
#define _FILE_BLOB_H
|
||||||
|
|
||||||
#include "Blob.h"
|
#include "Blob.h"
|
||||||
|
#include "FileUtil.h"
|
||||||
#include <cstdio>
|
|
||||||
|
|
||||||
namespace DiscIO
|
namespace DiscIO
|
||||||
{
|
{
|
||||||
|
|
||||||
class PlainFileReader : public IBlobReader
|
class PlainFileReader : public IBlobReader
|
||||||
{
|
{
|
||||||
FILE* file_;
|
PlainFileReader(std::FILE* file);
|
||||||
PlainFileReader(FILE* file__);
|
|
||||||
s64 size;
|
File::IOFile m_file;
|
||||||
|
s64 m_size;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static PlainFileReader* Create(const char* filename);
|
static PlainFileReader* Create(const char* filename);
|
||||||
~PlainFileReader();
|
|
||||||
u64 GetDataSize() const { return size; }
|
u64 GetDataSize() const { return m_size; }
|
||||||
u64 GetRawSize() const { return size; }
|
u64 GetRawSize() const { return m_size; }
|
||||||
bool Read(u64 offset, u64 nbytes, u8* out_ptr);
|
bool Read(u64 offset, u64 nbytes, u8* out_ptr);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
#include "FileHandlerARC.h"
|
#include "FileHandlerARC.h"
|
||||||
#include "StringUtil.h"
|
#include "StringUtil.h"
|
||||||
#include "Blob.h"
|
#include "Blob.h"
|
||||||
|
#include "FileUtil.h"
|
||||||
|
|
||||||
#define ARC_ID 0x55aa382d
|
#define ARC_ID 0x55aa382d
|
||||||
|
|
||||||
|
@ -144,16 +144,9 @@ CARCFile::ExportFile(const std::string& _rFullPath, const std::string& _rExportF
|
||||||
return(false);
|
return(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE* pFile = fopen(_rExportFilename.c_str(), "wb");
|
File::IOFile pFile(_rExportFilename, "wb");
|
||||||
|
|
||||||
if (pFile == NULL)
|
return pFile.WriteBytes(&m_pBuffer[pFileInfo->m_Offset], (size_t) pFileInfo->m_FileSize);
|
||||||
{
|
|
||||||
return(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
fwrite(&m_pBuffer[pFileInfo->m_Offset], (size_t) pFileInfo->m_FileSize, 1, pFile);
|
|
||||||
fclose(pFile);
|
|
||||||
return(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -101,7 +101,7 @@ bool CFileSystemGCWii::ExportFile(const char* _rFullPath, const char* _rExportFi
|
||||||
u64 remainingSize = pFileInfo->m_FileSize;
|
u64 remainingSize = pFileInfo->m_FileSize;
|
||||||
u64 fileOffset = pFileInfo->m_Offset;
|
u64 fileOffset = pFileInfo->m_Offset;
|
||||||
|
|
||||||
FILE* f = fopen(_rExportFilename, "wb");
|
File::IOFile f(_rExportFilename, "wb");
|
||||||
if (!f)
|
if (!f)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -122,7 +122,7 @@ bool CFileSystemGCWii::ExportFile(const char* _rFullPath, const char* _rExportFi
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
fwrite(buffer, readSize, 1, f);
|
f.WriteBytes(buffer, readSize);
|
||||||
|
|
||||||
remainingSize -= readSize;
|
remainingSize -= readSize;
|
||||||
fileOffset += readSize;
|
fileOffset += readSize;
|
||||||
|
@ -130,8 +130,6 @@ bool CFileSystemGCWii::ExportFile(const char* _rFullPath, const char* _rExportFi
|
||||||
delete[] buffer;
|
delete[] buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(f);
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,11 +145,11 @@ bool CFileSystemGCWii::ExportApploader(const char* _rExportFolder) const
|
||||||
{
|
{
|
||||||
char exportName[512];
|
char exportName[512];
|
||||||
sprintf(exportName, "%s/apploader.img", _rExportFolder);
|
sprintf(exportName, "%s/apploader.img", _rExportFolder);
|
||||||
FILE* AppFile = fopen(exportName, "wb");
|
|
||||||
|
File::IOFile AppFile(exportName, "wb");
|
||||||
if (AppFile)
|
if (AppFile)
|
||||||
{
|
{
|
||||||
fwrite(buffer, AppSize, 1, AppFile);
|
AppFile.WriteBytes(buffer, AppSize);
|
||||||
fclose(AppFile);
|
|
||||||
delete[] buffer;
|
delete[] buffer;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -189,11 +187,10 @@ bool CFileSystemGCWii::ExportDOL(const char* _rExportFolder) const
|
||||||
{
|
{
|
||||||
char exportName[512];
|
char exportName[512];
|
||||||
sprintf(exportName, "%s/boot.dol", _rExportFolder);
|
sprintf(exportName, "%s/boot.dol", _rExportFolder);
|
||||||
FILE* DolFile = fopen(exportName, "wb");
|
File::IOFile DolFile(exportName, "wb");
|
||||||
if (DolFile)
|
if (DolFile)
|
||||||
{
|
{
|
||||||
fwrite(buffer, DolSize, 1, DolFile);
|
DolFile.WriteBytes(buffer, DolSize);
|
||||||
fclose(DolFile);
|
|
||||||
delete[] buffer;
|
delete[] buffer;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,19 +36,12 @@ CSharedContent::CSharedContent()
|
||||||
lastID = 0;
|
lastID = 0;
|
||||||
sprintf(contentMap, "%sshared1/content.map", File::GetUserPath(D_WIIUSER_IDX).c_str());
|
sprintf(contentMap, "%sshared1/content.map", File::GetUserPath(D_WIIUSER_IDX).c_str());
|
||||||
|
|
||||||
if (File::Exists(contentMap))
|
File::IOFile pFile(contentMap, "rb");
|
||||||
|
SElement Element;
|
||||||
|
while (pFile.ReadArray(&Element, 1))
|
||||||
{
|
{
|
||||||
FILE* pFile = fopen(contentMap, "rb");
|
m_Elements.push_back(Element);
|
||||||
while(!feof(pFile))
|
lastID++;
|
||||||
{
|
|
||||||
SElement Element;
|
|
||||||
if (fread(&Element, sizeof(SElement), 1, pFile) == 1)
|
|
||||||
{
|
|
||||||
m_Elements.push_back(Element);
|
|
||||||
lastID++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fclose(pFile);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,12 +77,10 @@ std::string CSharedContent::AddSharedContent(u8* _pHash)
|
||||||
m_Elements.push_back(Element);
|
m_Elements.push_back(Element);
|
||||||
|
|
||||||
File::CreateFullPath(contentMap);
|
File::CreateFullPath(contentMap);
|
||||||
FILE* pFile = fopen(contentMap, "ab");
|
|
||||||
if (pFile)
|
File::IOFile pFile(contentMap, "ab");
|
||||||
{
|
pFile.WriteArray(&Element, 1);
|
||||||
fwrite(&Element, sizeof(SElement), 1, pFile);
|
|
||||||
fclose(pFile);
|
|
||||||
}
|
|
||||||
sprintf(tempFilename, "%sshared1/%s.app", File::GetUserPath(D_WIIUSER_IDX).c_str(), c_ID);
|
sprintf(tempFilename, "%sshared1/%s.app", File::GetUserPath(D_WIIUSER_IDX).c_str(), c_ID);
|
||||||
szFilename = tempFilename;
|
szFilename = tempFilename;
|
||||||
lastID++;
|
lastID++;
|
||||||
|
@ -205,16 +196,17 @@ bool CNANDContentLoader::CreateFromDirectory(const std::string& _rPath)
|
||||||
std::string TMDFileName(_rPath);
|
std::string TMDFileName(_rPath);
|
||||||
TMDFileName += "/title.tmd";
|
TMDFileName += "/title.tmd";
|
||||||
|
|
||||||
FILE* pTMDFile = fopen(TMDFileName.c_str(), "rb");
|
File::IOFile pTMDFile(TMDFileName, "rb");
|
||||||
if (pTMDFile == NULL) {
|
if (!pTMDFile)
|
||||||
|
{
|
||||||
ERROR_LOG(DISCIO, "CreateFromDirectory: error opening %s",
|
ERROR_LOG(DISCIO, "CreateFromDirectory: error opening %s",
|
||||||
TMDFileName.c_str());
|
TMDFileName.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
u64 Size = File::GetSize(TMDFileName);
|
u64 Size = File::GetSize(TMDFileName);
|
||||||
u8* pTMD = new u8[(u32)Size];
|
u8* pTMD = new u8[(u32)Size];
|
||||||
fread(pTMD, (size_t)Size, 1, pTMDFile);
|
pTMDFile.ReadBytes(pTMD, (size_t)Size);
|
||||||
fclose(pTMDFile);
|
pTMDFile.Close();
|
||||||
|
|
||||||
memcpy(m_TicketView, pTMD + 0x180, TICKET_VIEW_SIZE);
|
memcpy(m_TicketView, pTMD + 0x180, TICKET_VIEW_SIZE);
|
||||||
memcpy(m_TmdHeader, pTMD, TMD_HEADER_SIZE);
|
memcpy(m_TmdHeader, pTMD, TMD_HEADER_SIZE);
|
||||||
|
@ -257,16 +249,15 @@ bool CNANDContentLoader::CreateFromDirectory(const std::string& _rPath)
|
||||||
|
|
||||||
INFO_LOG(DISCIO, "NANDContentLoader: load %s", szFilename);
|
INFO_LOG(DISCIO, "NANDContentLoader: load %s", szFilename);
|
||||||
|
|
||||||
FILE* pFile = fopen(szFilename, "rb");
|
File::IOFile pFile(szFilename, "rb");
|
||||||
if (pFile != NULL)
|
if (pFile)
|
||||||
{
|
{
|
||||||
u64 ContentSize = File::GetSize(szFilename);
|
const u64 ContentSize = File::GetSize(szFilename);
|
||||||
rContent.m_pData = new u8[(u32)ContentSize];
|
rContent.m_pData = new u8[(u32)ContentSize];
|
||||||
|
|
||||||
_dbg_assert_msg_(BOOT, rContent.m_Size==ContentSize, "TMDLoader: Filesize doesnt fit (%s %i)... prolly you have a bad dump", szFilename, i);
|
_dbg_assert_msg_(BOOT, rContent.m_Size==ContentSize, "TMDLoader: Filesize doesnt fit (%s %i)... prolly you have a bad dump", szFilename, i);
|
||||||
|
|
||||||
fread(rContent.m_pData, (size_t)ContentSize, 1, pFile);
|
pFile.ReadBytes(rContent.m_pData, (size_t)ContentSize);
|
||||||
fclose(pFile);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -422,34 +413,26 @@ cUIDsys::cUIDsys()
|
||||||
{
|
{
|
||||||
sprintf(uidSys, "%ssys/uid.sys", File::GetUserPath(D_WIIUSER_IDX).c_str());
|
sprintf(uidSys, "%ssys/uid.sys", File::GetUserPath(D_WIIUSER_IDX).c_str());
|
||||||
lastUID = 0x00001000;
|
lastUID = 0x00001000;
|
||||||
if (File::Exists(uidSys))
|
|
||||||
|
File::IOFile pFile(uidSys, "rb");
|
||||||
|
SElement Element;
|
||||||
|
while (pFile.ReadArray(&Element, 1))
|
||||||
{
|
{
|
||||||
FILE* pFile = fopen(uidSys, "rb");
|
*(u32*)&(Element.UID) = Common::swap32(lastUID++);
|
||||||
while(!feof(pFile))
|
m_Elements.push_back(Element);
|
||||||
{
|
|
||||||
SElement Element;
|
|
||||||
if (fread(&Element, sizeof(SElement), 1, pFile) == 1)
|
|
||||||
{
|
|
||||||
*(u32*)&(Element.UID) = Common::swap32(lastUID++);
|
|
||||||
m_Elements.push_back(Element);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fclose(pFile);
|
|
||||||
}
|
}
|
||||||
if(!m_Elements.size())
|
pFile.Close();
|
||||||
|
|
||||||
|
if (m_Elements.empty())
|
||||||
{
|
{
|
||||||
SElement Element;
|
SElement Element;
|
||||||
*(u64*)&(Element.titleID) = Common::swap64(TITLEID_SYSMENU);
|
*(u64*)&(Element.titleID) = Common::swap64(TITLEID_SYSMENU);
|
||||||
*(u32*)&(Element.UID) = Common::swap32(lastUID++);
|
*(u32*)&(Element.UID) = Common::swap32(lastUID++);
|
||||||
|
|
||||||
File::CreateFullPath(uidSys);
|
File::CreateFullPath(uidSys);
|
||||||
FILE* pFile = fopen(uidSys, "wb");
|
pFile.Open(uidSys, "wb");
|
||||||
if (pFile)
|
if (!pFile.WriteArray(&Element, 1))
|
||||||
{
|
ERROR_LOG(DISCIO, "Failed to write to %s", uidSys);
|
||||||
if (fwrite(&Element, sizeof(SElement), 1, pFile) != 1)
|
|
||||||
ERROR_LOG(DISCIO, "Failed to write to %s", uidSys);
|
|
||||||
fclose(pFile);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -480,13 +463,10 @@ bool cUIDsys::AddTitle(u64 _TitleID)
|
||||||
m_Elements.push_back(Element);
|
m_Elements.push_back(Element);
|
||||||
|
|
||||||
File::CreateFullPath(uidSys);
|
File::CreateFullPath(uidSys);
|
||||||
FILE* pFile = fopen(uidSys, "ab");
|
File::IOFile pFile(uidSys, "ab");
|
||||||
if (pFile)
|
|
||||||
{
|
if (pFile.WriteArray(&Element, 1))
|
||||||
if (fwrite(&Element, sizeof(SElement), 1, pFile) != 1)
|
ERROR_LOG(DISCIO, "fwrite failed");
|
||||||
ERROR_LOG(DISCIO, "fwrite failed");
|
|
||||||
fclose(pFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -280,34 +280,33 @@ void CCodeWindow::OnSymbolsMenu(wxCommandEvent& event)
|
||||||
|
|
||||||
case IDM_RENAME_SYMBOLS:
|
case IDM_RENAME_SYMBOLS:
|
||||||
{
|
{
|
||||||
wxString path = wxFileSelector(
|
const wxString path = wxFileSelector(
|
||||||
_("Apply signature file"), wxEmptyString,
|
_("Apply signature file"), wxEmptyString,
|
||||||
wxEmptyString, wxEmptyString,
|
wxEmptyString, wxEmptyString,
|
||||||
_T("Dolphin Symbol Rename File (*.sym)|*.sym"),
|
_T("Dolphin Symbol Rename File (*.sym)|*.sym"),
|
||||||
wxFD_OPEN | wxFD_FILE_MUST_EXIST, this);
|
wxFD_OPEN | wxFD_FILE_MUST_EXIST, this);
|
||||||
if (! path.IsEmpty())
|
|
||||||
{
|
|
||||||
FILE *f = fopen(path.mb_str(), "r");
|
|
||||||
if (!f)
|
|
||||||
return;
|
|
||||||
|
|
||||||
while (!feof(f))
|
if (!path.IsEmpty())
|
||||||
|
{
|
||||||
|
std::ifstream f(path.mb_str());
|
||||||
|
|
||||||
|
std::string line;
|
||||||
|
while (std::getline(f, line))
|
||||||
{
|
{
|
||||||
char line[512];
|
if (line.length() < 12)
|
||||||
fgets(line, 511, f);
|
|
||||||
if (strlen(line) < 4)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
u32 address, type;
|
u32 address, type;
|
||||||
char name[512];
|
std::string name;
|
||||||
sscanf(line, "%08x %02i %s", &address, &type, name);
|
|
||||||
|
std::istringstream ss(line);
|
||||||
|
ss >> std::hex >> address >> std::dec >> type >> name;
|
||||||
|
|
||||||
Symbol *symbol = g_symbolDB.GetSymbolFromAddr(address);
|
Symbol *symbol = g_symbolDB.GetSymbolFromAddr(address);
|
||||||
if (symbol) {
|
if (symbol)
|
||||||
symbol->name = line+12;
|
symbol->name = line.substr(12);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
fclose(f);
|
|
||||||
Host_NotifyMapLoaded();
|
Host_NotifyMapLoaded();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -228,40 +228,31 @@ void CMemoryWindow::OnHostMessage(wxCommandEvent& event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DumpArray(const std::string& filename, const u8* data, size_t length)
|
||||||
|
{
|
||||||
|
if (data)
|
||||||
|
{
|
||||||
|
File::IOFile f(filename, "wb");
|
||||||
|
f.WriteBytes(data, length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Write mram to file
|
// Write mram to file
|
||||||
void CMemoryWindow::OnDumpMemory( wxCommandEvent& event )
|
void CMemoryWindow::OnDumpMemory( wxCommandEvent& event )
|
||||||
{
|
{
|
||||||
FILE* f = fopen(File::GetUserPath(F_RAMDUMP_IDX).c_str(), "wb");
|
DumpArray(File::GetUserPath(F_RAMDUMP_IDX), Memory::m_pRAM, Memory::REALRAM_SIZE);
|
||||||
if (f && Memory::m_pRAM)
|
|
||||||
{
|
|
||||||
fwrite(Memory::m_pRAM, Memory::REALRAM_SIZE, 1, f);
|
|
||||||
fclose(f);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write exram (aram or mem2) to file
|
// Write exram (aram or mem2) to file
|
||||||
void CMemoryWindow::OnDumpMem2( wxCommandEvent& event )
|
void CMemoryWindow::OnDumpMem2( wxCommandEvent& event )
|
||||||
{
|
{
|
||||||
FILE* f = NULL;
|
|
||||||
|
|
||||||
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii)
|
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii)
|
||||||
{
|
{
|
||||||
f = fopen(File::GetUserPath(F_ARAMDUMP_IDX).c_str(), "wb");
|
DumpArray(File::GetUserPath(F_ARAMDUMP_IDX), Memory::m_pEXRAM, Memory::EXRAM_SIZE);
|
||||||
if (f && Memory::m_pEXRAM)
|
|
||||||
{
|
|
||||||
fwrite(Memory::m_pEXRAM, Memory::EXRAM_SIZE, 1, f);
|
|
||||||
fclose(f);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
u8* aram = DSP::GetARAMPtr();
|
DumpArray(File::GetUserPath(F_ARAMDUMP_IDX), DSP::GetARAMPtr(), DSP::ARAM_SIZE);
|
||||||
f = fopen(File::GetUserPath(F_ARAMDUMP_IDX).c_str(), "wb");
|
|
||||||
if (f && aram)
|
|
||||||
{
|
|
||||||
fwrite(aram, DSP::ARAM_SIZE, 1, f);
|
|
||||||
fclose(f);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -136,15 +136,15 @@ CISOProperties::CISOProperties(const std::string fileName, wxWindow* parent, wxW
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Will fail out if GameConfig folder doesn't exist
|
// Will fail out if GameConfig folder doesn't exist
|
||||||
FILE *f = fopen(GameIniFile.c_str(), "w");
|
std::ofstream f(GameIniFile.c_str());
|
||||||
if (f)
|
if (f)
|
||||||
{
|
{
|
||||||
fprintf(f, "# %s - %s\n", OpenISO->GetUniqueID().c_str(), OpenISO->GetName().c_str());
|
f << "# " << OpenISO->GetUniqueID() << " - " << OpenISO->GetName() << '\n'
|
||||||
fprintf(f, "[Core] Values set here will override the main dolphin settings.\n");
|
<< "[Core] Values set here will override the main dolphin settings.\n"
|
||||||
fprintf(f, "[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.\n");
|
<< "[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.\n"
|
||||||
fprintf(f, "[OnFrame] Add memory patches to be applied every frame here.\n");
|
<< "[OnFrame] Add memory patches to be applied every frame here.\n"
|
||||||
fprintf(f, "[ActionReplay] Add action replay cheats here.\n");
|
<< "[ActionReplay] Add action replay cheats here.\n";
|
||||||
fclose(f);
|
f.close();
|
||||||
}
|
}
|
||||||
if (GameIni.Load(GameIniFile.c_str()))
|
if (GameIni.Load(GameIniFile.c_str()))
|
||||||
LoadGameConfig();
|
LoadGameConfig();
|
||||||
|
|
|
@ -67,21 +67,20 @@ CFrame* main_frame = NULL;
|
||||||
LONG WINAPI MyUnhandledExceptionFilter(LPEXCEPTION_POINTERS e) {
|
LONG WINAPI MyUnhandledExceptionFilter(LPEXCEPTION_POINTERS e) {
|
||||||
//EnterCriticalSection(&g_uefcs);
|
//EnterCriticalSection(&g_uefcs);
|
||||||
|
|
||||||
FILE* file = NULL;
|
File::IOFile file("exceptioninfo.txt", "a");
|
||||||
fopen_s(&file, "exceptioninfo.txt", "a");
|
file.Seek(0, SEEK_END);
|
||||||
fseeko(file, 0, SEEK_END);
|
etfprint(file.GetHandle(), "\n");
|
||||||
etfprint(file, "\n");
|
|
||||||
//etfprint(file, g_buildtime);
|
//etfprint(file, g_buildtime);
|
||||||
//etfprint(file, "\n");
|
//etfprint(file, "\n");
|
||||||
//dumpCurrentDate(file);
|
//dumpCurrentDate(file);
|
||||||
etfprintf(file, "Unhandled Exception\n Code: 0x%08X\n",
|
etfprintf(file.GetHandle(), "Unhandled Exception\n Code: 0x%08X\n",
|
||||||
e->ExceptionRecord->ExceptionCode);
|
e->ExceptionRecord->ExceptionCode);
|
||||||
#ifndef _M_X64
|
#ifndef _M_X64
|
||||||
STACKTRACE2(file, e->ContextRecord->Eip, e->ContextRecord->Esp, e->ContextRecord->Ebp);
|
STACKTRACE2(file.GetHandle(), e->ContextRecord->Eip, e->ContextRecord->Esp, e->ContextRecord->Ebp);
|
||||||
#else
|
#else
|
||||||
STACKTRACE2(file, e->ContextRecord->Rip, e->ContextRecord->Rsp, e->ContextRecord->Rbp);
|
STACKTRACE2(file.GetHandle(), e->ContextRecord->Rip, e->ContextRecord->Rsp, e->ContextRecord->Rbp);
|
||||||
#endif
|
#endif
|
||||||
fclose(file);
|
file.Close();
|
||||||
_flushall();
|
_flushall();
|
||||||
|
|
||||||
//LeaveCriticalSection(&g_uefcs);
|
//LeaveCriticalSection(&g_uefcs);
|
||||||
|
@ -211,20 +210,16 @@ bool DolphinApp::OnInit()
|
||||||
#else
|
#else
|
||||||
"x64");
|
"x64");
|
||||||
#endif
|
#endif
|
||||||
FILE* workingDir = fopen(tmp, "r");
|
std::ifstream workingDir(tmp);
|
||||||
if (!workingDir)
|
if (!workingDir)
|
||||||
{
|
{
|
||||||
if (PanicYesNoT("Dolphin has not been configured with an install location,\nKeep Dolphin portable?"))
|
if (PanicYesNoT("Dolphin has not been configured with an install location,\nKeep Dolphin portable?"))
|
||||||
{
|
{
|
||||||
FILE* portable = fopen((File::GetUserPath(D_CONFIG_IDX) + "portable").c_str(), "w");
|
std::ofstream portable((File::GetUserPath(D_CONFIG_IDX) + "portable").c_str());
|
||||||
if (!portable)
|
if (!portable)
|
||||||
{
|
{
|
||||||
PanicAlertT("Portable Setting could not be saved\n Are you running Dolphin from read only media or from a directory that dolphin is not located in?");
|
PanicAlertT("Portable Setting could not be saved\n Are you running Dolphin from read only media or from a directory that dolphin is not located in?");
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
fclose(portable);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -232,14 +227,12 @@ bool DolphinApp::OnInit()
|
||||||
sprintf(CWD, "%s", (const char*)wxGetCwd().mb_str());
|
sprintf(CWD, "%s", (const char*)wxGetCwd().mb_str());
|
||||||
if (PanicYesNoT("Set install location to:\n %s ?", CWD))
|
if (PanicYesNoT("Set install location to:\n %s ?", CWD))
|
||||||
{
|
{
|
||||||
FILE* workingDirF = fopen(tmp, "w");
|
std::ofstream workingDirF(tmp);
|
||||||
if (!workingDirF)
|
if (!workingDirF)
|
||||||
PanicAlertT("Install directory could not be saved");
|
PanicAlertT("Install directory could not be saved");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fwrite(CWD, ((std::string)CWD).size()+1, 1, workingDirF);
|
workingDirF << CWD << '\n';
|
||||||
fwrite("", 1, 1, workingDirF); //seems to be needed on linux
|
|
||||||
fclose(workingDirF);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -248,16 +241,12 @@ bool DolphinApp::OnInit()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char *tmpChar;
|
std::string tmpChar;
|
||||||
size_t len = (size_t)File::GetSize(workingDir);
|
std::getline(workingDir, tmpChar);
|
||||||
tmpChar = new char[len];
|
if (!wxSetWorkingDirectory(wxString::From8BitData(tmpChar.c_str())))
|
||||||
fread(tmpChar, len, 1, workingDir);
|
|
||||||
fclose(workingDir);
|
|
||||||
if (!wxSetWorkingDirectory(wxString::From8BitData(tmpChar)))
|
|
||||||
{
|
{
|
||||||
INFO_LOG(CONSOLE, "set working directory failed");
|
INFO_LOG(CONSOLE, "set working directory failed");
|
||||||
}
|
}
|
||||||
delete [] tmpChar;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -63,30 +63,27 @@ void decodeCI8image(u32* dst, u8* src, u16* pal, int width, int height)
|
||||||
|
|
||||||
GCMemcard::GCMemcard(const char *filename)
|
GCMemcard::GCMemcard(const char *filename)
|
||||||
{
|
{
|
||||||
FILE *mcd = fopen(filename, "r+b");
|
mcdFile.Open(filename, "r+b");
|
||||||
mcdFile = mcd;
|
|
||||||
fail = false;
|
fail = false;
|
||||||
if (!mcd)
|
if (!mcdFile)
|
||||||
{
|
{
|
||||||
if (!AskYesNoT("\"%s\" does not exist.\n Create a new 16MB Memcard?", filename))
|
if (!AskYesNoT("\"%s\" does not exist.\n Create a new 16MB Memcard?", filename))
|
||||||
{
|
{
|
||||||
fail = true;
|
fail = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mcd = fopen(filename, "wb");
|
mcdFile.Open(filename, "wb");
|
||||||
if (!mcd)
|
if (!mcdFile)
|
||||||
{
|
{
|
||||||
fail = true;
|
fail = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mcdFile = mcd;
|
|
||||||
Format(!AskYesNoT("Format as ascii (NTSC\\PAL)?\nChoose no for sjis (NTSC-J)"));
|
Format(!AskYesNoT("Format as ascii (NTSC\\PAL)?\nChoose no for sjis (NTSC-J)"));
|
||||||
fclose(mcd);
|
mcdFile.Open(filename, "r+b");
|
||||||
mcd = fopen(filename, "r+b");
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//This function can be removed once more about hdr is known and we can check for a valid header
|
//This function can be removed once more about hdr is known and we can check for a valid header
|
||||||
std::string fileType;
|
std::string fileType;
|
||||||
SplitPath(filename, NULL, NULL, &fileType);
|
SplitPath(filename, NULL, NULL, &fileType);
|
||||||
if (strcasecmp(fileType.c_str(), ".raw") && strcasecmp(fileType.c_str(), ".gcp"))
|
if (strcasecmp(fileType.c_str(), ".raw") && strcasecmp(fileType.c_str(), ".gcp"))
|
||||||
|
@ -97,41 +94,39 @@ GCMemcard::GCMemcard(const char *filename)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fseeko(mcd, 0, SEEK_SET);
|
mcdFile.Seek(0, SEEK_SET);
|
||||||
if (fread(&hdr, 1, BLOCK_SIZE, mcd) != BLOCK_SIZE)
|
fail = true;
|
||||||
|
if (!mcdFile.ReadBytes(&hdr, BLOCK_SIZE))
|
||||||
{
|
{
|
||||||
fail = true;
|
|
||||||
PanicAlertT("Failed to read header correctly\n(0x0000-0x1FFF)");
|
PanicAlertT("Failed to read header correctly\n(0x0000-0x1FFF)");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (fread(&dir, 1, BLOCK_SIZE, mcd) != BLOCK_SIZE)
|
else if (!mcdFile.ReadBytes(&dir, BLOCK_SIZE))
|
||||||
{
|
{
|
||||||
fail = true;
|
|
||||||
PanicAlertT("Failed to read directory correctly\n(0x2000-0x3FFF)");
|
PanicAlertT("Failed to read directory correctly\n(0x2000-0x3FFF)");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (fread(&dir_backup, 1, BLOCK_SIZE, mcd) != BLOCK_SIZE)
|
else if (!mcdFile.ReadBytes(&dir_backup, BLOCK_SIZE))
|
||||||
{
|
{
|
||||||
fail = true;
|
|
||||||
PanicAlertT("Failed to read directory backup correctly\n(0x4000-0x5FFF)");
|
PanicAlertT("Failed to read directory backup correctly\n(0x4000-0x5FFF)");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (fread(&bat, 1, BLOCK_SIZE, mcd) != BLOCK_SIZE)
|
else if (!mcdFile.ReadBytes(&bat, BLOCK_SIZE))
|
||||||
{
|
{
|
||||||
fail = true;
|
|
||||||
PanicAlertT("Failed to read block allocation table correctly\n(0x6000-0x7FFF)");
|
PanicAlertT("Failed to read block allocation table correctly\n(0x6000-0x7FFF)");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (fread(&bat_backup, 1, BLOCK_SIZE, mcd) != BLOCK_SIZE)
|
else if (!mcdFile.ReadBytes(&bat_backup, BLOCK_SIZE))
|
||||||
{
|
{
|
||||||
fail = true;
|
|
||||||
PanicAlertT("Failed to read block allocation table backup correctly\n(0x8000-0x9FFF)");
|
PanicAlertT("Failed to read block allocation table backup correctly\n(0x8000-0x9FFF)");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
fail = false;
|
||||||
|
|
||||||
u32 csums = TestChecksums();
|
u32 csums = TestChecksums();
|
||||||
|
|
||||||
if (csums&1)
|
if (csums & 0x1)
|
||||||
{
|
{
|
||||||
// header checksum error!
|
// header checksum error!
|
||||||
// invalid files do not always get here
|
// invalid files do not always get here
|
||||||
|
@ -140,9 +135,9 @@ GCMemcard::GCMemcard(const char *filename)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (csums&2) // directory checksum error!
|
if (csums & 0x2) // directory checksum error!
|
||||||
{
|
{
|
||||||
if (csums&4)
|
if (csums & 0x4)
|
||||||
{
|
{
|
||||||
// backup is also wrong!
|
// backup is also wrong!
|
||||||
fail = true;
|
fail = true;
|
||||||
|
@ -160,9 +155,9 @@ GCMemcard::GCMemcard(const char *filename)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (csums&8) // BAT checksum error!
|
if (csums & 0x8) // BAT checksum error!
|
||||||
{
|
{
|
||||||
if (csums&16)
|
if (csums & 0x10)
|
||||||
{
|
{
|
||||||
// backup is also wrong!
|
// backup is also wrong!
|
||||||
fail = true;
|
fail = true;
|
||||||
|
@ -188,7 +183,7 @@ GCMemcard::GCMemcard(const char *filename)
|
||||||
// bat = bat_backup; // needed?
|
// bat = bat_backup; // needed?
|
||||||
}
|
}
|
||||||
|
|
||||||
fseeko(mcd, 0xa000, SEEK_SET);
|
mcdFile.Seek(0xa000, SEEK_SET);
|
||||||
|
|
||||||
u16 sizeMb = BE16(hdr.SizeMb);
|
u16 sizeMb = BE16(hdr.SizeMb);
|
||||||
switch (sizeMb)
|
switch (sizeMb)
|
||||||
|
@ -204,8 +199,7 @@ GCMemcard::GCMemcard(const char *filename)
|
||||||
mc_data_size = (maxBlock - MC_FST_BLOCKS) * BLOCK_SIZE;
|
mc_data_size = (maxBlock - MC_FST_BLOCKS) * BLOCK_SIZE;
|
||||||
mc_data = new u8[mc_data_size];
|
mc_data = new u8[mc_data_size];
|
||||||
|
|
||||||
size_t read = fread(mc_data, 1, mc_data_size, mcd);
|
if (!mcdFile.ReadBytes(mc_data, mc_data_size))
|
||||||
if (mc_data_size != read)
|
|
||||||
{
|
{
|
||||||
fail = true;
|
fail = true;
|
||||||
PanicAlertT("Failed to read save data\n(0xA000-)\nMemcard may be truncated");
|
PanicAlertT("Failed to read save data\n(0xA000-)\nMemcard may be truncated");
|
||||||
|
@ -218,15 +212,9 @@ GCMemcard::GCMemcard(const char *filename)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GCMemcard::~GCMemcard()
|
|
||||||
{
|
|
||||||
if (!mcdFile) return;
|
|
||||||
fclose((FILE*)mcdFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GCMemcard::IsOpen()
|
bool GCMemcard::IsOpen()
|
||||||
{
|
{
|
||||||
return (mcdFile!=NULL);
|
return mcdFile.IsOpen();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GCMemcard::IsAsciiEncoding()
|
bool GCMemcard::IsAsciiEncoding()
|
||||||
|
@ -236,16 +224,16 @@ bool GCMemcard::IsAsciiEncoding()
|
||||||
|
|
||||||
bool GCMemcard::Save()
|
bool GCMemcard::Save()
|
||||||
{
|
{
|
||||||
bool completeWrite = true;
|
mcdFile.Seek(0, SEEK_SET);
|
||||||
FILE *mcd=(FILE*)mcdFile;
|
|
||||||
fseeko(mcd, 0, SEEK_SET);
|
mcdFile.WriteBytes(&hdr, BLOCK_SIZE);
|
||||||
if (fwrite(&hdr, 1, BLOCK_SIZE, mcd) != BLOCK_SIZE) completeWrite = false;
|
mcdFile.WriteBytes(&dir, BLOCK_SIZE);
|
||||||
if (fwrite(&dir, 1, BLOCK_SIZE, mcd) != BLOCK_SIZE) completeWrite = false;
|
mcdFile.WriteBytes(&dir_backup, BLOCK_SIZE);
|
||||||
if (fwrite(&dir_backup, 1, BLOCK_SIZE, mcd) != BLOCK_SIZE) completeWrite = false;
|
mcdFile.WriteBytes(&bat, BLOCK_SIZE);
|
||||||
if (fwrite(&bat, 1, BLOCK_SIZE ,mcd) != BLOCK_SIZE) completeWrite = false;
|
mcdFile.WriteBytes(&bat_backup, BLOCK_SIZE);
|
||||||
if (fwrite(&bat_backup, 1, BLOCK_SIZE, mcd) != BLOCK_SIZE) completeWrite = false;
|
mcdFile.WriteBytes(mc_data, mc_data_size);
|
||||||
if (fwrite(mc_data, 1, mc_data_size, mcd) != mc_data_size) completeWrite = false;
|
|
||||||
return completeWrite;
|
return mcdFile.IsGood();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GCMemcard::calc_checksumsBE(u16 *buf, u32 num, u16 *c1, u16 *c2)
|
void GCMemcard::calc_checksumsBE(u16 *buf, u32 num, u16 *c1, u16 *c2)
|
||||||
|
@ -269,7 +257,8 @@ void GCMemcard::calc_checksumsBE(u16 *buf, u32 num, u16 *c1, u16 *c2)
|
||||||
|
|
||||||
u32 GCMemcard::TestChecksums()
|
u32 GCMemcard::TestChecksums()
|
||||||
{
|
{
|
||||||
if (!mcdFile) return 0xFFFFFFFF;
|
if (!mcdFile)
|
||||||
|
return 0xFFFFFFFF;
|
||||||
|
|
||||||
u16 csum1=0,
|
u16 csum1=0,
|
||||||
csum2=0;
|
csum2=0;
|
||||||
|
@ -296,12 +285,13 @@ u32 GCMemcard::TestChecksums()
|
||||||
if (BE16(bat_backup.CheckSum1) != csum1) results |= 16;
|
if (BE16(bat_backup.CheckSum1) != csum1) results |= 16;
|
||||||
if (BE16(bat_backup.CheckSum2) != csum2) results |= 16;
|
if (BE16(bat_backup.CheckSum2) != csum2) results |= 16;
|
||||||
|
|
||||||
return 0;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GCMemcard::FixChecksums()
|
bool GCMemcard::FixChecksums()
|
||||||
{
|
{
|
||||||
if (!mcdFile) return false;
|
if (!mcdFile)
|
||||||
|
return false;
|
||||||
|
|
||||||
u16 csum1=0,
|
u16 csum1=0,
|
||||||
csum2=0;
|
csum2=0;
|
||||||
|
@ -341,7 +331,9 @@ bool GCMemcard::FixChecksums()
|
||||||
|
|
||||||
u8 GCMemcard::GetNumFiles()
|
u8 GCMemcard::GetNumFiles()
|
||||||
{
|
{
|
||||||
if (!mcdFile) return 0;
|
if (!mcdFile)
|
||||||
|
return 0;
|
||||||
|
|
||||||
u8 j = 0;
|
u8 j = 0;
|
||||||
for (int i = 0; i < DIRLEN; i++)
|
for (int i = 0; i < DIRLEN; i++)
|
||||||
{
|
{
|
||||||
|
@ -353,13 +345,16 @@ u8 GCMemcard::GetNumFiles()
|
||||||
|
|
||||||
u16 GCMemcard::GetFreeBlocks()
|
u16 GCMemcard::GetFreeBlocks()
|
||||||
{
|
{
|
||||||
if (!mcdFile) return 0;
|
if (!mcdFile)
|
||||||
|
return 0;
|
||||||
|
|
||||||
return BE16(bat.FreeBlocks);
|
return BE16(bat.FreeBlocks);
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 GCMemcard::TitlePresent(DEntry d)
|
u8 GCMemcard::TitlePresent(DEntry d)
|
||||||
{
|
{
|
||||||
if (!mcdFile) return DIRLEN;
|
if (!mcdFile)
|
||||||
|
return DIRLEN;
|
||||||
|
|
||||||
u8 i = 0;
|
u8 i = 0;
|
||||||
while(i < DIRLEN)
|
while(i < DIRLEN)
|
||||||
|
@ -379,7 +374,8 @@ u8 GCMemcard::TitlePresent(DEntry d)
|
||||||
|
|
||||||
bool GCMemcard::DEntry_GameCode(u8 index, char *buffer)
|
bool GCMemcard::DEntry_GameCode(u8 index, char *buffer)
|
||||||
{
|
{
|
||||||
if (!mcdFile) return false;
|
if (!mcdFile)
|
||||||
|
return false;
|
||||||
|
|
||||||
memcpy(buffer, dir.Dir[index].Gamecode, 4);
|
memcpy(buffer, dir.Dir[index].Gamecode, 4);
|
||||||
buffer[4] = 0;
|
buffer[4] = 0;
|
||||||
|
@ -388,14 +384,17 @@ bool GCMemcard::DEntry_GameCode(u8 index, char *buffer)
|
||||||
|
|
||||||
bool GCMemcard::DEntry_Markercode(u8 index, char *buffer)
|
bool GCMemcard::DEntry_Markercode(u8 index, char *buffer)
|
||||||
{
|
{
|
||||||
if (!mcdFile) return false;
|
if (!mcdFile)
|
||||||
|
return false;
|
||||||
|
|
||||||
memcpy(buffer, dir.Dir[index].Markercode, 2);
|
memcpy(buffer, dir.Dir[index].Markercode, 2);
|
||||||
buffer[2] = 0;
|
buffer[2] = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool GCMemcard::DEntry_BIFlags(u8 index, char *buffer)
|
bool GCMemcard::DEntry_BIFlags(u8 index, char *buffer)
|
||||||
{
|
{
|
||||||
if (!mcdFile) return false;
|
if (!mcdFile)
|
||||||
|
return false;
|
||||||
|
|
||||||
int x = dir.Dir[index].BIFlags;
|
int x = dir.Dir[index].BIFlags;
|
||||||
for (int i = 0; i < 8; i++)
|
for (int i = 0; i < 8; i++)
|
||||||
|
@ -409,7 +408,9 @@ bool GCMemcard::DEntry_BIFlags(u8 index, char *buffer)
|
||||||
|
|
||||||
bool GCMemcard::DEntry_FileName(u8 index, char *buffer)
|
bool GCMemcard::DEntry_FileName(u8 index, char *buffer)
|
||||||
{
|
{
|
||||||
if (!mcdFile) return false;
|
if (!mcdFile)
|
||||||
|
return false;
|
||||||
|
|
||||||
memcpy (buffer, (const char*)dir.Dir[index].Filename, DENTRY_STRLEN);
|
memcpy (buffer, (const char*)dir.Dir[index].Filename, DENTRY_STRLEN);
|
||||||
buffer[31] = 0;
|
buffer[31] = 0;
|
||||||
return true;
|
return true;
|
||||||
|
@ -463,7 +464,9 @@ u8 GCMemcard::DEntry_CopyCounter(u8 index)
|
||||||
|
|
||||||
u16 GCMemcard::DEntry_FirstBlock(u8 index)
|
u16 GCMemcard::DEntry_FirstBlock(u8 index)
|
||||||
{
|
{
|
||||||
if (!mcdFile) return 0xFFFF;
|
if (!mcdFile)
|
||||||
|
return 0xFFFF;
|
||||||
|
|
||||||
u16 block = BE16(dir.Dir[index].FirstBlock);
|
u16 block = BE16(dir.Dir[index].FirstBlock);
|
||||||
if (block > (u16) maxBlock) return 0xFFFF;
|
if (block > (u16) maxBlock) return 0xFFFF;
|
||||||
return block;
|
return block;
|
||||||
|
@ -471,7 +474,8 @@ u16 GCMemcard::DEntry_FirstBlock(u8 index)
|
||||||
|
|
||||||
u16 GCMemcard::DEntry_BlockCount(u8 index)
|
u16 GCMemcard::DEntry_BlockCount(u8 index)
|
||||||
{
|
{
|
||||||
if (!mcdFile) return 0xFFFF;
|
if (!mcdFile)
|
||||||
|
return 0xFFFF;
|
||||||
|
|
||||||
u16 blocks = BE16(dir.Dir[index].BlockCount);
|
u16 blocks = BE16(dir.Dir[index].BlockCount);
|
||||||
if (blocks > (u16) maxBlock) return 0xFFFF;
|
if (blocks > (u16) maxBlock) return 0xFFFF;
|
||||||
|
@ -485,7 +489,8 @@ u32 GCMemcard::DEntry_CommentsAddress(u8 index)
|
||||||
|
|
||||||
bool GCMemcard::DEntry_Comment1(u8 index, char* buffer)
|
bool GCMemcard::DEntry_Comment1(u8 index, char* buffer)
|
||||||
{
|
{
|
||||||
if (!mcdFile) return false;
|
if (!mcdFile)
|
||||||
|
return false;
|
||||||
|
|
||||||
u32 Comment1 = BE32(dir.Dir[index].CommentsAddr);
|
u32 Comment1 = BE32(dir.Dir[index].CommentsAddr);
|
||||||
u32 DataBlock = BE16(dir.Dir[index].FirstBlock) - MC_FST_BLOCKS;
|
u32 DataBlock = BE16(dir.Dir[index].FirstBlock) - MC_FST_BLOCKS;
|
||||||
|
@ -501,7 +506,8 @@ bool GCMemcard::DEntry_Comment1(u8 index, char* buffer)
|
||||||
|
|
||||||
bool GCMemcard::DEntry_Comment2(u8 index, char* buffer)
|
bool GCMemcard::DEntry_Comment2(u8 index, char* buffer)
|
||||||
{
|
{
|
||||||
if (!mcdFile) return false;
|
if (!mcdFile)
|
||||||
|
return false;
|
||||||
|
|
||||||
u32 Comment1 = BE32(dir.Dir[index].CommentsAddr);
|
u32 Comment1 = BE32(dir.Dir[index].CommentsAddr);
|
||||||
u32 Comment2 = Comment1 + DENTRY_STRLEN;
|
u32 Comment2 = Comment1 + DENTRY_STRLEN;
|
||||||
|
@ -518,7 +524,8 @@ bool GCMemcard::DEntry_Comment2(u8 index, char* buffer)
|
||||||
|
|
||||||
bool GCMemcard::DEntry_Copy(u8 index, GCMemcard::DEntry& info)
|
bool GCMemcard::DEntry_Copy(u8 index, GCMemcard::DEntry& info)
|
||||||
{
|
{
|
||||||
if (!mcdFile) return false;
|
if (!mcdFile)
|
||||||
|
return false;
|
||||||
|
|
||||||
info = dir.Dir[index];
|
info = dir.Dir[index];
|
||||||
return true;
|
return true;
|
||||||
|
@ -526,7 +533,8 @@ bool GCMemcard::DEntry_Copy(u8 index, GCMemcard::DEntry& info)
|
||||||
|
|
||||||
u32 GCMemcard::DEntry_GetSaveData(u8 index, u8* dest, bool old)
|
u32 GCMemcard::DEntry_GetSaveData(u8 index, u8* dest, bool old)
|
||||||
{
|
{
|
||||||
if (!mcdFile) return NOMEMCARD;
|
if (!mcdFile)
|
||||||
|
return NOMEMCARD;
|
||||||
|
|
||||||
u16 block = DEntry_FirstBlock(index);
|
u16 block = DEntry_FirstBlock(index);
|
||||||
u16 saveLength = DEntry_BlockCount(index);
|
u16 saveLength = DEntry_BlockCount(index);
|
||||||
|
@ -564,7 +572,8 @@ u32 GCMemcard::DEntry_GetSaveData(u8 index, u8* dest, bool old)
|
||||||
|
|
||||||
u32 GCMemcard::ImportFile(DEntry& direntry, u8* contents, int remove)
|
u32 GCMemcard::ImportFile(DEntry& direntry, u8* contents, int remove)
|
||||||
{
|
{
|
||||||
if (!mcdFile) return NOMEMCARD;
|
if (!mcdFile)
|
||||||
|
return NOMEMCARD;
|
||||||
|
|
||||||
if (GetNumFiles() >= DIRLEN)
|
if (GetNumFiles() >= DIRLEN)
|
||||||
{
|
{
|
||||||
|
@ -665,7 +674,8 @@ u32 GCMemcard::ImportFile(DEntry& direntry, u8* contents, int remove)
|
||||||
|
|
||||||
u32 GCMemcard::RemoveFile(u8 index) //index in the directory array
|
u32 GCMemcard::RemoveFile(u8 index) //index in the directory array
|
||||||
{
|
{
|
||||||
if (!mcdFile) return NOMEMCARD;
|
if (!mcdFile)
|
||||||
|
return NOMEMCARD;
|
||||||
|
|
||||||
//error checking
|
//error checking
|
||||||
u16 startingblock = 0;
|
u16 startingblock = 0;
|
||||||
|
@ -747,7 +757,8 @@ u32 GCMemcard::RemoveFile(u8 index) //index in the directory array
|
||||||
|
|
||||||
u32 GCMemcard::CopyFrom(GCMemcard& source, u8 index)
|
u32 GCMemcard::CopyFrom(GCMemcard& source, u8 index)
|
||||||
{
|
{
|
||||||
if (!mcdFile) return NOMEMCARD;
|
if (!mcdFile)
|
||||||
|
return NOMEMCARD;
|
||||||
|
|
||||||
DEntry tempDEntry;
|
DEntry tempDEntry;
|
||||||
if (!source.DEntry_Copy(index, tempDEntry)) return NOMEMCARD;
|
if (!source.DEntry_Copy(index, tempDEntry)) return NOMEMCARD;
|
||||||
|
@ -773,18 +784,19 @@ u32 GCMemcard::CopyFrom(GCMemcard& source, u8 index)
|
||||||
|
|
||||||
u32 GCMemcard::ImportGci(const char *inputFile, std::string outputFile)
|
u32 GCMemcard::ImportGci(const char *inputFile, std::string outputFile)
|
||||||
{
|
{
|
||||||
if (outputFile.empty() && !mcdFile) return OPENFAIL;
|
if (outputFile.empty() && !mcdFile)
|
||||||
|
return OPENFAIL;
|
||||||
|
|
||||||
FILE *gci = fopen(inputFile, "rb");
|
File::IOFile gci(inputFile, "rb");
|
||||||
if (!gci) return OPENFAIL;
|
if (!gci)
|
||||||
|
return OPENFAIL;
|
||||||
|
|
||||||
u32 result = ImportGciInternal(gci, inputFile, outputFile);
|
u32 result = ImportGciInternal(gci.ReleaseHandle(), inputFile, outputFile);
|
||||||
fclose(gci);
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 GCMemcard::ImportGciInternal(FILE *gci, const char *inputFile, std::string outputFile)
|
u32 GCMemcard::ImportGciInternal(File::IOFile gci, const char *inputFile, std::string outputFile)
|
||||||
{
|
{
|
||||||
int offset;
|
int offset;
|
||||||
char tmp[0xD];
|
char tmp[0xD];
|
||||||
|
@ -795,7 +807,7 @@ u32 GCMemcard::ImportGciInternal(FILE *gci, const char *inputFile, std::string o
|
||||||
offset = GCI;
|
offset = GCI;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fread(tmp, 1, 0xD, gci);
|
gci.ReadBytes(tmp, 0xD);
|
||||||
if (!strcasecmp(fileType.c_str(), ".gcs"))
|
if (!strcasecmp(fileType.c_str(), ".gcs"))
|
||||||
{
|
{
|
||||||
if (!memcmp(tmp, "GCSAVE", 6)) // Header must be uppercase
|
if (!memcmp(tmp, "GCSAVE", 6)) // Header must be uppercase
|
||||||
|
@ -813,29 +825,29 @@ u32 GCMemcard::ImportGciInternal(FILE *gci, const char *inputFile, std::string o
|
||||||
else
|
else
|
||||||
return OPENFAIL;
|
return OPENFAIL;
|
||||||
}
|
}
|
||||||
fseeko(gci, offset, SEEK_SET);
|
gci.Seek(offset, SEEK_SET);
|
||||||
|
|
||||||
DEntry *tempDEntry = new DEntry;
|
DEntry *tempDEntry = new DEntry;
|
||||||
fread(tempDEntry, 1, DENTRY_SIZE, gci);
|
gci.ReadBytes(tempDEntry, DENTRY_SIZE);
|
||||||
int fStart = (int) ftello(gci);
|
const int fStart = (int)gci.Tell();
|
||||||
fseeko(gci, 0, SEEK_END);
|
gci.Seek(0, SEEK_END);
|
||||||
int length = (int) ftello(gci) - fStart;
|
const int length = (int)gci.Tell() - fStart;
|
||||||
fseeko(gci, offset + DENTRY_SIZE, SEEK_SET);
|
gci.Seek(offset + DENTRY_SIZE, SEEK_SET);
|
||||||
|
|
||||||
Gcs_SavConvert(tempDEntry, offset, length);
|
Gcs_SavConvert(tempDEntry, offset, length);
|
||||||
|
|
||||||
if (length != BE16(tempDEntry->BlockCount) * BLOCK_SIZE)
|
if (length != BE16(tempDEntry->BlockCount) * BLOCK_SIZE)
|
||||||
return LENGTHFAIL;
|
return LENGTHFAIL;
|
||||||
if (ftello(gci) != offset + DENTRY_SIZE) // Verify correct file position
|
if (gci.Tell() != offset + DENTRY_SIZE) // Verify correct file position
|
||||||
return OPENFAIL;
|
return OPENFAIL;
|
||||||
|
|
||||||
u32 size = BE16((tempDEntry->BlockCount)) * BLOCK_SIZE;
|
u32 size = BE16((tempDEntry->BlockCount)) * BLOCK_SIZE;
|
||||||
u8 *tempSaveData = new u8[size];
|
u8 *tempSaveData = new u8[size];
|
||||||
fread(tempSaveData, 1, size, gci);
|
gci.ReadBytes(tempSaveData, size);
|
||||||
u32 ret;
|
u32 ret;
|
||||||
if(!outputFile.empty())
|
if (!outputFile.empty())
|
||||||
{
|
{
|
||||||
FILE *gci2 = fopen(outputFile.c_str(), "wb");
|
File::IOFile gci2(outputFile, "wb");
|
||||||
bool completeWrite = true;
|
bool completeWrite = true;
|
||||||
if (!gci2)
|
if (!gci2)
|
||||||
{
|
{
|
||||||
|
@ -843,18 +855,19 @@ u32 GCMemcard::ImportGciInternal(FILE *gci, const char *inputFile, std::string o
|
||||||
delete tempDEntry;
|
delete tempDEntry;
|
||||||
return OPENFAIL;
|
return OPENFAIL;
|
||||||
}
|
}
|
||||||
fseeko(gci2, 0, SEEK_SET);
|
gci2.Seek(0, SEEK_SET);
|
||||||
|
|
||||||
if (fwrite(tempDEntry, 1, DENTRY_SIZE, gci2) != DENTRY_SIZE)
|
if (!gci2.WriteBytes(tempDEntry, DENTRY_SIZE))
|
||||||
completeWrite = false;
|
completeWrite = false;
|
||||||
int fileBlocks = BE16(tempDEntry->BlockCount);
|
int fileBlocks = BE16(tempDEntry->BlockCount);
|
||||||
fseeko(gci2, DENTRY_SIZE, SEEK_SET);
|
gci2.Seek(DENTRY_SIZE, SEEK_SET);
|
||||||
|
|
||||||
if (fwrite(tempSaveData, 1, BLOCK_SIZE * fileBlocks, gci2) != (unsigned)(BLOCK_SIZE * fileBlocks))
|
if (!gci2.WriteBytes(tempSaveData, BLOCK_SIZE * fileBlocks))
|
||||||
completeWrite = false;
|
completeWrite = false;
|
||||||
fclose(gci2);
|
if (completeWrite)
|
||||||
if (completeWrite) ret = GCS;
|
ret = GCS;
|
||||||
else ret = WRITEFAIL;
|
else
|
||||||
|
ret = WRITEFAIL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ret = ImportFile(*tempDEntry, tempSaveData, 0);
|
ret = ImportFile(*tempDEntry, tempSaveData, 0);
|
||||||
|
@ -866,7 +879,7 @@ u32 GCMemcard::ImportGciInternal(FILE *gci, const char *inputFile, std::string o
|
||||||
|
|
||||||
u32 GCMemcard::ExportGci(u8 index, const char *fileName, std::string *fileName2)
|
u32 GCMemcard::ExportGci(u8 index, const char *fileName, std::string *fileName2)
|
||||||
{
|
{
|
||||||
FILE *gci;
|
File::IOFile gci;
|
||||||
int offset = GCI;
|
int offset = GCI;
|
||||||
if (!strcasecmp(fileName, "."))
|
if (!strcasecmp(fileName, "."))
|
||||||
{
|
{
|
||||||
|
@ -879,12 +892,12 @@ u32 GCMemcard::ExportGci(u8 index, const char *fileName, std::string *fileName2)
|
||||||
DEntry_GameCode(index, GameCode);
|
DEntry_GameCode(index, GameCode);
|
||||||
|
|
||||||
sprintf(filename, "%s/%s_%s.gci", fileName2->c_str(), GameCode, dir.Dir[index].Filename);
|
sprintf(filename, "%s/%s_%s.gci", fileName2->c_str(), GameCode, dir.Dir[index].Filename);
|
||||||
gci = fopen((const char *)filename, "wb");
|
gci.Open(filename, "wb");
|
||||||
delete[] filename;
|
delete[] filename;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gci = fopen(fileName, "wb");
|
gci.Open(fileName, "wb");
|
||||||
|
|
||||||
std::string fileType;
|
std::string fileType;
|
||||||
SplitPath(fileName, NULL, NULL, &fileType);
|
SplitPath(fileName, NULL, NULL, &fileType);
|
||||||
|
@ -898,10 +911,10 @@ u32 GCMemcard::ExportGci(u8 index, const char *fileName, std::string *fileName2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gci) return OPENFAIL;
|
if (!gci)
|
||||||
bool completeWrite = true;
|
return OPENFAIL;
|
||||||
|
|
||||||
fseeko(gci, 0, SEEK_SET);
|
gci.Seek(0, SEEK_SET);
|
||||||
|
|
||||||
switch(offset)
|
switch(offset)
|
||||||
{
|
{
|
||||||
|
@ -909,54 +922,54 @@ u32 GCMemcard::ExportGci(u8 index, const char *fileName, std::string *fileName2)
|
||||||
u8 gcsHDR[GCS];
|
u8 gcsHDR[GCS];
|
||||||
memset(gcsHDR, 0, GCS);
|
memset(gcsHDR, 0, GCS);
|
||||||
memcpy(gcsHDR, "GCSAVE", 6);
|
memcpy(gcsHDR, "GCSAVE", 6);
|
||||||
if (fwrite(gcsHDR, 1, GCS, gci) != GCS) completeWrite = false;
|
gci.WriteArray(gcsHDR, GCS);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SAV:
|
case SAV:
|
||||||
u8 savHDR[SAV];
|
u8 savHDR[SAV];
|
||||||
memset(savHDR, 0, SAV);
|
memset(savHDR, 0, SAV);
|
||||||
memcpy(savHDR, "DATELGC_SAVE", 0xC);
|
memcpy(savHDR, "DATELGC_SAVE", 0xC);
|
||||||
if (fwrite(savHDR, 1, SAV, gci) != SAV) completeWrite = false;
|
gci.WriteArray(savHDR, SAV);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEntry tempDEntry;
|
DEntry tempDEntry;
|
||||||
if (!DEntry_Copy(index, tempDEntry))
|
if (!DEntry_Copy(index, tempDEntry))
|
||||||
{
|
{
|
||||||
fclose(gci);
|
|
||||||
return NOMEMCARD;
|
return NOMEMCARD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Gcs_SavConvert(&tempDEntry, offset);
|
Gcs_SavConvert(&tempDEntry, offset);
|
||||||
if (fwrite(&tempDEntry, 1, DENTRY_SIZE, gci) != DENTRY_SIZE) completeWrite = false;
|
gci.WriteBytes(&tempDEntry, DENTRY_SIZE);
|
||||||
|
|
||||||
u32 size = DEntry_BlockCount(index);
|
u32 size = DEntry_BlockCount(index);
|
||||||
if (size == 0xFFFF)
|
if (size == 0xFFFF)
|
||||||
{
|
{
|
||||||
fclose(gci);
|
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
size *= BLOCK_SIZE;
|
size *= BLOCK_SIZE;
|
||||||
u8 *tempSaveData = new u8[size];
|
u8 *tempSaveData = new u8[size];
|
||||||
|
|
||||||
switch(DEntry_GetSaveData(index, tempSaveData, true))
|
switch(DEntry_GetSaveData(index, tempSaveData, true))
|
||||||
{
|
{
|
||||||
case FAIL:
|
case FAIL:
|
||||||
fclose(gci);
|
|
||||||
delete[] tempSaveData;
|
delete[] tempSaveData;
|
||||||
return FAIL;
|
return FAIL;
|
||||||
|
|
||||||
case NOMEMCARD:
|
case NOMEMCARD:
|
||||||
fclose(gci);
|
|
||||||
delete[] tempSaveData;
|
delete[] tempSaveData;
|
||||||
return NOMEMCARD;
|
return NOMEMCARD;
|
||||||
}
|
}
|
||||||
fseeko(gci, DENTRY_SIZE + offset, SEEK_SET);
|
gci.Seek(DENTRY_SIZE + offset, SEEK_SET);
|
||||||
if (fwrite(tempSaveData, 1, size, gci) != size)
|
gci.WriteBytes(tempSaveData, size);
|
||||||
completeWrite = false;
|
|
||||||
fclose(gci);
|
|
||||||
delete[] tempSaveData;
|
delete[] tempSaveData;
|
||||||
if (completeWrite) return SUCCESS;
|
|
||||||
else return WRITEFAIL;
|
if (gci.IsGood())
|
||||||
|
return SUCCESS;
|
||||||
|
else
|
||||||
|
return WRITEFAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GCMemcard::Gcs_SavConvert(DEntry* tempDEntry, int saveType, int length)
|
void GCMemcard::Gcs_SavConvert(DEntry* tempDEntry, int saveType, int length)
|
||||||
|
@ -999,7 +1012,8 @@ void GCMemcard::Gcs_SavConvert(DEntry* tempDEntry, int saveType, int length)
|
||||||
|
|
||||||
bool GCMemcard::ReadBannerRGBA8(u8 index, u32* buffer)
|
bool GCMemcard::ReadBannerRGBA8(u8 index, u32* buffer)
|
||||||
{
|
{
|
||||||
if (!mcdFile) return false;
|
if (!mcdFile)
|
||||||
|
return false;
|
||||||
|
|
||||||
int flags = dir.Dir[index].BIFlags;
|
int flags = dir.Dir[index].BIFlags;
|
||||||
// Timesplitters 2 is the only game that I see this in
|
// Timesplitters 2 is the only game that I see this in
|
||||||
|
@ -1039,7 +1053,8 @@ bool GCMemcard::ReadBannerRGBA8(u8 index, u32* buffer)
|
||||||
|
|
||||||
u32 GCMemcard::ReadAnimRGBA8(u8 index, u32* buffer, u8 *delays)
|
u32 GCMemcard::ReadAnimRGBA8(u8 index, u32* buffer, u8 *delays)
|
||||||
{
|
{
|
||||||
if (!mcdFile) return 0;
|
if (!mcdFile)
|
||||||
|
return 0;
|
||||||
|
|
||||||
// To ensure only one type of icon is used
|
// To ensure only one type of icon is used
|
||||||
// Sonic Heroes it the only game I have seen that tries to use a CI8 and RGB5A3 icon
|
// Sonic Heroes it the only game I have seen that tries to use a CI8 and RGB5A3 icon
|
||||||
|
@ -1137,12 +1152,10 @@ u32 GCMemcard::ReadAnimRGBA8(u8 index, u32* buffer, u8 *delays)
|
||||||
|
|
||||||
bool GCMemcard::Format(bool sjis, bool New, int slot, u16 SizeMb, bool hdrOnly)
|
bool GCMemcard::Format(bool sjis, bool New, int slot, u16 SizeMb, bool hdrOnly)
|
||||||
{
|
{
|
||||||
//Currently only formats cards for slot A
|
// Currently only formats cards for slot A
|
||||||
u32 data_size = BLOCK_SIZE * (SizeMb * MBIT_TO_BLOCKS - MC_FST_BLOCKS);
|
const u32 data_size = BLOCK_SIZE * (SizeMb * MBIT_TO_BLOCKS - MC_FST_BLOCKS);
|
||||||
|
|
||||||
SRAM m_SRAM;
|
SRAM m_SRAM;
|
||||||
FILE * pStream;
|
|
||||||
u64 time, rand;
|
|
||||||
|
|
||||||
if (New)
|
if (New)
|
||||||
{
|
{
|
||||||
|
@ -1152,18 +1165,19 @@ bool GCMemcard::Format(bool sjis, bool New, int slot, u16 SizeMb, bool hdrOnly)
|
||||||
// Only Format 16MB memcards for now
|
// Only Format 16MB memcards for now
|
||||||
if ((SizeMb != MemCard2043Mb) || (data_size != mc_data_size)) return false;
|
if ((SizeMb != MemCard2043Mb) || (data_size != mc_data_size)) return false;
|
||||||
|
|
||||||
pStream = fopen(File::GetUserPath(F_GCSRAM_IDX).c_str(), "rb");
|
File::IOFile pStream(File::GetUserPath(F_GCSRAM_IDX), "rb");
|
||||||
if (pStream)
|
if (pStream)
|
||||||
{
|
{
|
||||||
fread(&m_SRAM, 1, 64, pStream);
|
pStream.ReadBytes(&m_SRAM, 64);
|
||||||
fclose(pStream);
|
pStream.Close();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_SRAM = sram_dump;
|
m_SRAM = sram_dump;
|
||||||
}
|
}
|
||||||
time = CEXIIPL::GetGCTime();
|
|
||||||
rand = Common::swap64(time);
|
const u64 time = CEXIIPL::GetGCTime();
|
||||||
|
u64 rand = Common::swap64(time);
|
||||||
|
|
||||||
memset(&hdr, 0xFF, BLOCK_SIZE);
|
memset(&hdr, 0xFF, BLOCK_SIZE);
|
||||||
for(int i = 0; i < 12; i++)
|
for(int i = 0; i < 12; i++)
|
||||||
|
@ -1203,4 +1217,3 @@ bool GCMemcard::Format(bool sjis, bool New, int slot, u16 SizeMb, bool hdrOnly)
|
||||||
Save();
|
Save();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -71,7 +71,7 @@ class GCMemcard
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
friend class CMemcardManagerDebug;
|
friend class CMemcardManagerDebug;
|
||||||
void* mcdFile;
|
File::IOFile mcdFile;
|
||||||
|
|
||||||
u32 maxBlock;
|
u32 maxBlock;
|
||||||
u32 mc_data_size;
|
u32 mc_data_size;
|
||||||
|
@ -167,12 +167,8 @@ private:
|
||||||
public:
|
public:
|
||||||
bool fail;
|
bool fail;
|
||||||
|
|
||||||
// constructor
|
|
||||||
GCMemcard(const char* fileName);
|
GCMemcard(const char* fileName);
|
||||||
|
|
||||||
// destructor
|
|
||||||
~GCMemcard();
|
|
||||||
|
|
||||||
bool IsOpen();
|
bool IsOpen();
|
||||||
bool IsAsciiEncoding();
|
bool IsAsciiEncoding();
|
||||||
bool Save();
|
bool Save();
|
||||||
|
@ -232,7 +228,7 @@ public:
|
||||||
// if remove > 0 it will pad bat.map with 0's sizeof remove
|
// if remove > 0 it will pad bat.map with 0's sizeof remove
|
||||||
u32 ImportFile(DEntry& direntry, u8* contents, int remove);
|
u32 ImportFile(DEntry& direntry, u8* contents, int remove);
|
||||||
private:
|
private:
|
||||||
u32 ImportGciInternal(FILE *gci, const char *inputFile, std::string outputFile);
|
u32 ImportGciInternal(File::IOFile gci, const char *inputFile, std::string outputFile);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// delete a file from the directory
|
// delete a file from the directory
|
||||||
|
|
|
@ -86,20 +86,20 @@ CWiiSaveCrypted::CWiiSaveCrypted(const char* FileName, u64 title)
|
||||||
|
|
||||||
void CWiiSaveCrypted::ReadHDR()
|
void CWiiSaveCrypted::ReadHDR()
|
||||||
{
|
{
|
||||||
fpData_bin = fopen(pathData_bin, "rb");
|
File::IOFile fpData_bin(pathData_bin, "rb");
|
||||||
if (!fpData_bin)
|
if (!fpData_bin)
|
||||||
{
|
{
|
||||||
PanicAlertT("Cannot open %s", pathData_bin);
|
PanicAlertT("Cannot open %s", pathData_bin);
|
||||||
b_valid = false;
|
b_valid = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (fread(&_encryptedHeader, HEADER_SZ, 1, fpData_bin) != 1)
|
if (!fpData_bin.ReadBytes(&_encryptedHeader, HEADER_SZ))
|
||||||
{
|
{
|
||||||
PanicAlertT("failed to read header");
|
PanicAlertT("failed to read header");
|
||||||
b_valid = false;
|
b_valid = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fclose(fpData_bin);
|
fpData_bin.Close();
|
||||||
|
|
||||||
AES_cbc_encrypt((const u8*)&_encryptedHeader, (u8*)&_header, HEADER_SZ, &m_AES_KEY, SD_IV, AES_DECRYPT);
|
AES_cbc_encrypt((const u8*)&_encryptedHeader, (u8*)&_header, HEADER_SZ, &m_AES_KEY, SD_IV, AES_DECRYPT);
|
||||||
_bannerSize = Common::swap32(_header.hdr.BannerSize);
|
_bannerSize = Common::swap32(_header.hdr.BannerSize);
|
||||||
|
@ -129,12 +129,8 @@ void CWiiSaveCrypted::ReadHDR()
|
||||||
if (!File::Exists(pathBanner_bin) || AskYesNoT("%s already exists, overwrite?", pathBanner_bin))
|
if (!File::Exists(pathBanner_bin) || AskYesNoT("%s already exists, overwrite?", pathBanner_bin))
|
||||||
{
|
{
|
||||||
INFO_LOG(CONSOLE, "creating file %s", pathBanner_bin);
|
INFO_LOG(CONSOLE, "creating file %s", pathBanner_bin);
|
||||||
fpBanner_bin = fopen(pathBanner_bin, "wb");
|
File::IOFile fpBanner_bin(pathBanner_bin, "wb");
|
||||||
if (fpBanner_bin)
|
fpBanner_bin.WriteBytes(_header.BNR, _bannerSize);
|
||||||
{
|
|
||||||
fwrite(_header.BNR, _bannerSize, 1, fpBanner_bin);
|
|
||||||
fclose(fpBanner_bin);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,31 +145,24 @@ void CWiiSaveCrypted::WriteHDR()
|
||||||
memcpy(_header.hdr.Md5, MD5_BLANKER, 0x10);
|
memcpy(_header.hdr.Md5, MD5_BLANKER, 0x10);
|
||||||
_header.hdr.Permissions = 0x3C;//0x35;
|
_header.hdr.Permissions = 0x3C;//0x35;
|
||||||
|
|
||||||
fpBanner_bin = fopen(pathBanner_bin, "rb");
|
File::IOFile fpBanner_bin(pathBanner_bin, "rb");
|
||||||
if (fpBanner_bin)
|
if (!fpBanner_bin.ReadBytes(_header.BNR, Common::swap32(_header.hdr.BannerSize)))
|
||||||
{
|
{
|
||||||
if (fread(_header.BNR, Common::swap32(_header.hdr.BannerSize), 1, fpBanner_bin) != 1)
|
PanicAlertT("Failed to read banner.bin");
|
||||||
{
|
b_valid = false;
|
||||||
PanicAlertT("Failed to read banner.bin");
|
return;
|
||||||
b_valid = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
fclose(fpBanner_bin);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
md5((u8*)&_header, HEADER_SZ, md5_calc);
|
md5((u8*)&_header, HEADER_SZ, md5_calc);
|
||||||
memcpy(_header.hdr.Md5, md5_calc, 0x10);
|
memcpy(_header.hdr.Md5, md5_calc, 0x10);
|
||||||
|
|
||||||
AES_cbc_encrypt((const unsigned char *)&_header, (u8*)&_encryptedHeader, HEADER_SZ, &m_AES_KEY, SD_IV, AES_ENCRYPT);
|
AES_cbc_encrypt((const unsigned char *)&_header, (u8*)&_encryptedHeader, HEADER_SZ, &m_AES_KEY, SD_IV, AES_ENCRYPT);
|
||||||
fpData_bin = fopen(pathData_bin, "wb");
|
|
||||||
if (fpData_bin)
|
File::IOFile fpData_bin(pathData_bin, "wb");
|
||||||
|
if (!fpData_bin.WriteBytes(&_encryptedHeader, HEADER_SZ))
|
||||||
{
|
{
|
||||||
if (fwrite(&_encryptedHeader, HEADER_SZ, 1, fpData_bin) != 1)
|
PanicAlertT("Failed to write header for %s", pathData_bin);
|
||||||
{
|
b_valid = false;
|
||||||
PanicAlertT("Failed to write header for %s", pathData_bin);
|
|
||||||
b_valid = false;
|
|
||||||
}
|
|
||||||
fclose(fpData_bin);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,21 +172,21 @@ void CWiiSaveCrypted::ReadBKHDR()
|
||||||
{
|
{
|
||||||
if (!b_valid) return;
|
if (!b_valid) return;
|
||||||
|
|
||||||
fpData_bin = fopen(pathData_bin, "rb");
|
File::IOFile fpData_bin(pathData_bin, "rb");
|
||||||
if (!fpData_bin)
|
if (!fpData_bin)
|
||||||
{
|
{
|
||||||
PanicAlertT("Cannot open %s", pathData_bin);
|
PanicAlertT("Cannot open %s", pathData_bin);
|
||||||
b_valid = false;
|
b_valid = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fseeko(fpData_bin, HEADER_SZ, SEEK_SET);
|
fpData_bin.Seek(HEADER_SZ, SEEK_SET);
|
||||||
if (fread(&bkhdr, BK_SZ, 1, fpData_bin) != 1)
|
if (!fpData_bin.ReadBytes(&bkhdr, BK_SZ))
|
||||||
{
|
{
|
||||||
PanicAlertT("failed to read bk header");
|
PanicAlertT("failed to read bk header");
|
||||||
b_valid = false;
|
b_valid = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fclose(fpData_bin);
|
fpData_bin.Close();
|
||||||
|
|
||||||
if (bkhdr.size != Common::swap32(BK_LISTED_SZ) ||
|
if (bkhdr.size != Common::swap32(BK_LISTED_SZ) ||
|
||||||
bkhdr.magic != Common::swap32(BK_HDR_MAGIC))
|
bkhdr.magic != Common::swap32(BK_HDR_MAGIC))
|
||||||
|
@ -215,8 +204,6 @@ void CWiiSaveCrypted::ReadBKHDR()
|
||||||
WARN_LOG(CONSOLE, "Size(%x) + cert(%x) does not equal totalsize(%x)", _sizeOfFiles, FULL_CERT_SZ, _totalSize);
|
WARN_LOG(CONSOLE, "Size(%x) + cert(%x) does not equal totalsize(%x)", _sizeOfFiles, FULL_CERT_SZ, _totalSize);
|
||||||
if (_saveGameTitle != Common::swap64(bkhdr.SaveGameTitle))
|
if (_saveGameTitle != Common::swap64(bkhdr.SaveGameTitle))
|
||||||
WARN_LOG(CONSOLE, "encrypted title (%llx) does not match unencrypted title (%llx)", _saveGameTitle, Common::swap64(bkhdr.SaveGameTitle));
|
WARN_LOG(CONSOLE, "encrypted title (%llx) does not match unencrypted title (%llx)", _saveGameTitle, Common::swap64(bkhdr.SaveGameTitle));
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWiiSaveCrypted::WriteBKHDR()
|
void CWiiSaveCrypted::WriteBKHDR()
|
||||||
|
@ -241,15 +228,11 @@ void CWiiSaveCrypted::WriteBKHDR()
|
||||||
//
|
//
|
||||||
memcpy(bkhdr.MACaddress, MAC, 6);
|
memcpy(bkhdr.MACaddress, MAC, 6);
|
||||||
|
|
||||||
fpData_bin = fopen(pathData_bin, "ab");
|
File::IOFile fpData_bin(pathData_bin, "ab");
|
||||||
if(fpData_bin)
|
if (!fpData_bin.WriteBytes(&bkhdr, BK_SZ))
|
||||||
{
|
{
|
||||||
if (fwrite(&bkhdr, BK_SZ, 1, fpData_bin) != 1)
|
PanicAlertT("Failed to write bkhdr");
|
||||||
{
|
b_valid = false;
|
||||||
PanicAlertT("Failed to write bkhdr");
|
|
||||||
b_valid = false;
|
|
||||||
}
|
|
||||||
fclose(fpData_bin);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,7 +240,7 @@ void CWiiSaveCrypted::ImportWiiSaveFiles()
|
||||||
{
|
{
|
||||||
if (!b_valid) return;
|
if (!b_valid) return;
|
||||||
|
|
||||||
fpData_bin = fopen(pathData_bin, "rb");
|
File::IOFile fpData_bin(pathData_bin, "rb");
|
||||||
if (!fpData_bin)
|
if (!fpData_bin)
|
||||||
{
|
{
|
||||||
PanicAlertT("Cannot open %s", pathData_bin);
|
PanicAlertT("Cannot open %s", pathData_bin);
|
||||||
|
@ -272,19 +255,19 @@ void CWiiSaveCrypted::ImportWiiSaveFiles()
|
||||||
|
|
||||||
for(u32 i = 0; i < _numberOfFiles; i++)
|
for(u32 i = 0; i < _numberOfFiles; i++)
|
||||||
{
|
{
|
||||||
fseeko(fpData_bin, lastpos, SEEK_SET);
|
fpData_bin.Seek(lastpos, SEEK_SET);
|
||||||
memset(&_tmpFileHDR, 0, FILE_HDR_SZ);
|
memset(&_tmpFileHDR, 0, FILE_HDR_SZ);
|
||||||
memset(IV, 0, 0x10);
|
memset(IV, 0, 0x10);
|
||||||
_fileSize = 0;
|
_fileSize = 0;
|
||||||
|
|
||||||
if (fread(&_tmpFileHDR, FILE_HDR_SZ, 1, fpData_bin) != 1)
|
if (!fpData_bin.ReadBytes(&_tmpFileHDR, FILE_HDR_SZ))
|
||||||
{
|
{
|
||||||
PanicAlertT("Failed to write header for file %d", i);
|
PanicAlertT("Failed to write header for file %d", i);
|
||||||
b_valid = false;
|
b_valid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
lastpos += FILE_HDR_SZ;
|
lastpos += FILE_HDR_SZ;
|
||||||
if(Common::swap32(_tmpFileHDR.magic) != FILE_HDR_MAGIC)
|
if (Common::swap32(_tmpFileHDR.magic) != FILE_HDR_MAGIC)
|
||||||
{
|
{
|
||||||
PanicAlertT("Bad File Header");
|
PanicAlertT("Bad File Header");
|
||||||
break;
|
break;
|
||||||
|
@ -306,7 +289,7 @@ void CWiiSaveCrypted::ImportWiiSaveFiles()
|
||||||
lastpos += ROUND_UP(_fileSize, BLOCK_SZ);
|
lastpos += ROUND_UP(_fileSize, BLOCK_SZ);
|
||||||
_encryptedData = new u8[_fileSize];
|
_encryptedData = new u8[_fileSize];
|
||||||
_data = new u8[_fileSize];
|
_data = new u8[_fileSize];
|
||||||
if (fread(_encryptedData, _fileSize, 1, fpData_bin) != 1)
|
if (!fpData_bin.ReadBytes(_encryptedData, _fileSize))
|
||||||
{
|
{
|
||||||
PanicAlertT("Failed to read data from file %d", i);
|
PanicAlertT("Failed to read data from file %d", i);
|
||||||
b_valid = false;
|
b_valid = false;
|
||||||
|
@ -322,19 +305,13 @@ void CWiiSaveCrypted::ImportWiiSaveFiles()
|
||||||
{
|
{
|
||||||
INFO_LOG(CONSOLE, "creating file %s", pathRawSave);
|
INFO_LOG(CONSOLE, "creating file %s", pathRawSave);
|
||||||
|
|
||||||
fpRawSaveFile = fopen(pathRawSave, "wb");
|
File::IOFile fpRawSaveFile(pathRawSave, "wb");
|
||||||
if (fpRawSaveFile)
|
fpRawSaveFile.WriteBytes(_data, _fileSize);
|
||||||
{
|
|
||||||
fwrite(_data, _fileSize, 1, fpRawSaveFile);
|
|
||||||
fclose(fpRawSaveFile);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
delete []_data;
|
delete []_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fclose(fpData_bin);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWiiSaveCrypted::ExportWiiSaveFiles()
|
void CWiiSaveCrypted::ExportWiiSaveFiles()
|
||||||
|
@ -381,11 +358,9 @@ void CWiiSaveCrypted::ExportWiiSaveFiles()
|
||||||
}
|
}
|
||||||
strncpy((char *)tmpFileHDR.name, __name.c_str(), __name.length());
|
strncpy((char *)tmpFileHDR.name, __name.c_str(), __name.length());
|
||||||
|
|
||||||
fpData_bin = fopen(pathData_bin, "ab");
|
|
||||||
if (fpData_bin)
|
|
||||||
{
|
{
|
||||||
fwrite(&tmpFileHDR, FILE_HDR_SZ, 1, fpData_bin);
|
File::IOFile fpData_bin(pathData_bin, "ab");
|
||||||
fclose(fpData_bin);
|
fpData_bin.WriteBytes(&tmpFileHDR, FILE_HDR_SZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tmpFileHDR.type == 1)
|
if (tmpFileHDR.type == 1)
|
||||||
|
@ -396,7 +371,7 @@ void CWiiSaveCrypted::ExportWiiSaveFiles()
|
||||||
b_valid = false;
|
b_valid = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fpRawSaveFile = fopen(FilesList[i].c_str(), "rb");
|
File::IOFile fpRawSaveFile(FilesList[i], "rb");
|
||||||
if (!fpRawSaveFile)
|
if (!fpRawSaveFile)
|
||||||
{
|
{
|
||||||
PanicAlertT("%s failed to open", FilesList[i].c_str());
|
PanicAlertT("%s failed to open", FilesList[i].c_str());
|
||||||
|
@ -405,20 +380,17 @@ void CWiiSaveCrypted::ExportWiiSaveFiles()
|
||||||
__data = new u8[_roundedfileSize];
|
__data = new u8[_roundedfileSize];
|
||||||
__ENCdata = new u8[_roundedfileSize];
|
__ENCdata = new u8[_roundedfileSize];
|
||||||
memset(__data, 0, _roundedfileSize);
|
memset(__data, 0, _roundedfileSize);
|
||||||
if (fread(__data, _fileSize, 1, fpRawSaveFile) != 1)
|
if (!fpRawSaveFile.ReadBytes(__data, _fileSize))
|
||||||
{
|
{
|
||||||
PanicAlertT("failed to read data from file: %s", FilesList[i].c_str());
|
PanicAlertT("failed to read data from file: %s", FilesList[i].c_str());
|
||||||
b_valid = false;
|
b_valid = false;
|
||||||
}
|
}
|
||||||
fclose(fpRawSaveFile);
|
|
||||||
|
|
||||||
AES_cbc_encrypt((const u8*)__data, __ENCdata, _roundedfileSize, &m_AES_KEY, tmpFileHDR.IV, AES_ENCRYPT);
|
AES_cbc_encrypt((const u8*)__data, __ENCdata, _roundedfileSize, &m_AES_KEY, tmpFileHDR.IV, AES_ENCRYPT);
|
||||||
fpData_bin = fopen(pathData_bin, "ab");
|
|
||||||
if (fpData_bin)
|
File::IOFile fpData_bin(pathData_bin, "ab");
|
||||||
{
|
fpData_bin.WriteBytes(__ENCdata, _roundedfileSize);
|
||||||
fwrite(__ENCdata, _roundedfileSize, 1, fpData_bin);
|
|
||||||
fclose(fpData_bin);
|
|
||||||
}
|
|
||||||
delete [] __data;
|
delete [] __data;
|
||||||
delete [] __ENCdata;
|
delete [] __ENCdata;
|
||||||
|
|
||||||
|
@ -466,7 +438,7 @@ void CWiiSaveCrypted::do_sig()
|
||||||
|
|
||||||
data_size = Common::swap32(bkhdr.sizeOfFiles) + 0x80;
|
data_size = Common::swap32(bkhdr.sizeOfFiles) + 0x80;
|
||||||
|
|
||||||
fpData_bin = fopen(pathData_bin, "rb");
|
File::IOFile fpData_bin(pathData_bin, "rb");
|
||||||
if (!fpData_bin)
|
if (!fpData_bin)
|
||||||
{
|
{
|
||||||
b_valid = false;
|
b_valid = false;
|
||||||
|
@ -474,14 +446,15 @@ void CWiiSaveCrypted::do_sig()
|
||||||
}
|
}
|
||||||
data = new u8[data_size];
|
data = new u8[data_size];
|
||||||
|
|
||||||
fseeko(fpData_bin, 0xf0c0, SEEK_SET);
|
fpData_bin.Seek(0xf0c0, SEEK_SET);
|
||||||
if (fread(data, data_size, 1, fpData_bin) != 1)
|
if (!fpData_bin.ReadBytes(data, data_size))
|
||||||
PanicAlert("read data for sig check");
|
PanicAlert("read data for sig check");
|
||||||
|
|
||||||
sha1(data, data_size, hash);
|
sha1(data, data_size, hash);
|
||||||
sha1(hash, 20, hash);
|
sha1(hash, 20, hash);
|
||||||
fclose(fpData_bin);
|
|
||||||
delete []data;
|
delete []data;
|
||||||
fpData_bin = fopen(pathData_bin, "ab");
|
|
||||||
|
fpData_bin.Open(pathData_bin, "ab");
|
||||||
if (!fpData_bin)
|
if (!fpData_bin)
|
||||||
{
|
{
|
||||||
b_valid = false;
|
b_valid = false;
|
||||||
|
@ -490,15 +463,12 @@ void CWiiSaveCrypted::do_sig()
|
||||||
generate_ecdsa(sig, sig + 30, ap_priv, hash);
|
generate_ecdsa(sig, sig + 30, ap_priv, hash);
|
||||||
*(u32*)(sig + 60) = Common::swap32(0x2f536969);
|
*(u32*)(sig + 60) = Common::swap32(0x2f536969);
|
||||||
|
|
||||||
|
if (!fpData_bin.WriteArray(sig, sizeof(sig)))
|
||||||
|
|
||||||
if (fwrite(sig, sizeof sig, 1, fpData_bin) != 1)
|
|
||||||
PanicAlert("write sig");
|
PanicAlert("write sig");
|
||||||
if (fwrite(ng_cert, sizeof ng_cert, 1, fpData_bin) != 1)
|
if (!fpData_bin.WriteArray(ng_cert, sizeof(ng_cert)))
|
||||||
PanicAlert("write NG cert");
|
PanicAlert("write NG cert");
|
||||||
if (fwrite(ap_cert, sizeof ap_cert, 1, fpData_bin) != 1)
|
if (!fpData_bin.WriteArray(ap_cert, sizeof(ap_cert)))
|
||||||
PanicAlert("write AP cert");
|
PanicAlert("write AP cert");
|
||||||
fclose(fpData_bin);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -50,10 +50,6 @@ private:
|
||||||
u8 SD_IV[0x10];
|
u8 SD_IV[0x10];
|
||||||
std::vector<std::string> FilesList;
|
std::vector<std::string> FilesList;
|
||||||
|
|
||||||
FILE *fpData_bin,
|
|
||||||
*fpBanner_bin,
|
|
||||||
*fpRawSaveFile;
|
|
||||||
|
|
||||||
char pathData_bin[2048],
|
char pathData_bin[2048],
|
||||||
pathSavedir[2048],
|
pathSavedir[2048],
|
||||||
pathBanner_bin[2048], //should always be FULL_WII_USER_DIR "title/%08x/%08x/data/"
|
pathBanner_bin[2048], //should always be FULL_WII_USER_DIR "title/%08x/%08x/data/"
|
||||||
|
|
|
@ -15,11 +15,11 @@
|
||||||
// Official SVN repository and contact information can be found at
|
// Official SVN repository and contact information can be found at
|
||||||
// http://code.google.com/p/dolphin-emu/
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "ImageWrite.h"
|
#include "ImageWrite.h"
|
||||||
|
#include "FileUtil.h"
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
|
|
||||||
|
@ -47,32 +47,30 @@ struct TGA_HEADER
|
||||||
|
|
||||||
bool SaveTGA(const char* filename, int width, int height, void* pdata)
|
bool SaveTGA(const char* filename, int width, int height, void* pdata)
|
||||||
{
|
{
|
||||||
TGA_HEADER hdr;
|
TGA_HEADER hdr;
|
||||||
FILE* f = fopen(filename, "wb");
|
File::IOFile f(filename, "wb");
|
||||||
if (f == NULL)
|
if (!f)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
_assert_(sizeof(TGA_HEADER) == 18 && sizeof(hdr) == 18);
|
_assert_(sizeof(TGA_HEADER) == 18 && sizeof(hdr) == 18);
|
||||||
|
|
||||||
memset(&hdr, 0, sizeof(hdr));
|
memset(&hdr, 0, sizeof(hdr));
|
||||||
hdr.imagetype = 2;
|
hdr.imagetype = 2;
|
||||||
hdr.bits = 32;
|
hdr.bits = 32;
|
||||||
hdr.width = width;
|
hdr.width = width;
|
||||||
hdr.height = height;
|
hdr.height = height;
|
||||||
hdr.descriptor |= 8|(1<<5); // 8bit alpha, flip vertical
|
hdr.descriptor |= 8|(1<<5); // 8bit alpha, flip vertical
|
||||||
|
|
||||||
fwrite(&hdr, sizeof(hdr), 1, f);
|
f.WriteArray(&hdr, 1);
|
||||||
fwrite(pdata, width * height * 4, 1, f);
|
f.WriteBytes(pdata, width * height * 4);
|
||||||
fclose(f);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SaveData(const char* filename, const char* data)
|
bool SaveData(const char* filename, const char* data)
|
||||||
{
|
{
|
||||||
FILE *f = fopen(filename, "wb");
|
std::ofstream f(filename, std::ios::binary);
|
||||||
if (!f)
|
f << data;
|
||||||
return false;
|
|
||||||
fwrite(data, strlen(data), 1, f);
|
return true;
|
||||||
fclose(f);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,22 +105,20 @@ void TexDecoder_OpenCL_Initialize()
|
||||||
filename = File::GetUserPath(D_OPENCL_IDX) + "kernel.bin";
|
filename = File::GetUserPath(D_OPENCL_IDX) + "kernel.bin";
|
||||||
snprintf(dolphin_rev, HEADER_SIZE, "%-31s", svn_rev_str);
|
snprintf(dolphin_rev, HEADER_SIZE, "%-31s", svn_rev_str);
|
||||||
|
|
||||||
FILE *input = NULL;
|
{
|
||||||
|
File::IOFile input(filename, "rb");
|
||||||
input = fopen(filename.c_str(), "rb");
|
if (!input)
|
||||||
if (input == NULL)
|
|
||||||
{
|
{
|
||||||
binary_size = 0;
|
binary_size = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
binary_size = File::GetSize(input);
|
binary_size = input.GetSize();
|
||||||
header = new char[HEADER_SIZE];
|
header = new char[HEADER_SIZE];
|
||||||
binary = new char[binary_size];
|
binary = new char[binary_size];
|
||||||
fread(header, sizeof(char), HEADER_SIZE, input);
|
input.ReadBytes(header, HEADER_SIZE);
|
||||||
binary_size = fread(binary, sizeof(char),
|
input.ReadBytes(binary, binary_size);
|
||||||
binary_size - HEADER_SIZE, input);
|
}
|
||||||
fclose(input);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (binary_size > 0)
|
if (binary_size > 0)
|
||||||
|
@ -202,19 +200,17 @@ void TexDecoder_OpenCL_Initialize()
|
||||||
if (!err)
|
if (!err)
|
||||||
{
|
{
|
||||||
filename = File::GetUserPath(D_OPENCL_IDX) + "kernel.bin";
|
filename = File::GetUserPath(D_OPENCL_IDX) + "kernel.bin";
|
||||||
FILE *output = NULL;
|
|
||||||
output = fopen(filename.c_str(), "wb");
|
|
||||||
|
|
||||||
if (output == NULL)
|
File::IOFile output(filename, "wb");
|
||||||
|
if (!output)
|
||||||
{
|
{
|
||||||
binary_size = 0;
|
binary_size = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Supporting one OpenCL device for now
|
// Supporting one OpenCL device for now
|
||||||
fwrite(dolphin_rev, sizeof(char), HEADER_SIZE, output);
|
output.WriteBytes(dolphin_rev, HEADER_SIZE);
|
||||||
fwrite(binaries[0], sizeof(char), binary_sizes[0], output);
|
output.WriteBytes(binaries[0], binary_sizes[0]);
|
||||||
fclose(output);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,7 +111,7 @@ RasterFont* s_pfont = NULL;
|
||||||
#if defined _WIN32 || defined HAVE_LIBAV
|
#if defined _WIN32 || defined HAVE_LIBAV
|
||||||
static bool s_bAVIDumping = false;
|
static bool s_bAVIDumping = false;
|
||||||
#else
|
#else
|
||||||
static FILE* f_pFrameDump;
|
static File::IOFile f_pFrameDump;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// 1 for no MSAA. Use s_MSAASamples > 1 to check for MSAA.
|
// 1 for no MSAA. Use s_MSAASamples > 1 to check for MSAA.
|
||||||
|
@ -1158,7 +1158,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
}
|
}
|
||||||
|
|
||||||
// Frame dumps are handled a little differently in Windows
|
// Frame dumps are handled a little differently in Windows
|
||||||
#if defined _WIN32 || defined HAVE_LIBAV
|
#if defined _WIN32 || defined HAVE_LIBAV && 0
|
||||||
if (g_ActiveConfig.bDumpFrames)
|
if (g_ActiveConfig.bDumpFrames)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lk(s_criticalScreenshot);
|
std::lock_guard<std::mutex> lk(s_criticalScreenshot);
|
||||||
|
@ -1236,8 +1236,8 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
if (!s_bLastFrameDumped)
|
if (!s_bLastFrameDumped)
|
||||||
{
|
{
|
||||||
movie_file_name = File::GetUserPath(D_DUMPFRAMES_IDX) + "framedump.raw";
|
movie_file_name = File::GetUserPath(D_DUMPFRAMES_IDX) + "framedump.raw";
|
||||||
f_pFrameDump = fopen(movie_file_name.c_str(), "wb");
|
f_pFrameDump.Open(movie_file_name, "wb");
|
||||||
if (f_pFrameDump == NULL)
|
if (!f_pFrameDump)
|
||||||
OSD::AddMessage("Error opening framedump.raw for writing.", 2000);
|
OSD::AddMessage("Error opening framedump.raw for writing.", 2000);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1246,11 +1246,11 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
OSD::AddMessage(msg, 2000);
|
OSD::AddMessage(msg, 2000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (f_pFrameDump != NULL)
|
if (f_pFrameDump)
|
||||||
{
|
{
|
||||||
FlipImageData(data, w, h);
|
FlipImageData(data, w, h);
|
||||||
fwrite(data, w * 3, h, f_pFrameDump);
|
f_pFrameDump.WriteBytes(data, w * 3 * h);
|
||||||
fflush(f_pFrameDump);
|
f_pFrameDump.Flush();
|
||||||
}
|
}
|
||||||
s_bLastFrameDumped = true;
|
s_bLastFrameDumped = true;
|
||||||
}
|
}
|
||||||
|
@ -1259,11 +1259,8 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (s_bLastFrameDumped && f_pFrameDump != NULL)
|
if (s_bLastFrameDumped)
|
||||||
{
|
f_pFrameDump.Close();
|
||||||
fclose(f_pFrameDump);
|
|
||||||
f_pFrameDump = NULL;
|
|
||||||
}
|
|
||||||
s_bLastFrameDumped = false;
|
s_bLastFrameDumped = false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue