commit
aff35d3e58
|
@ -824,13 +824,12 @@ size_t WriteStringToFile(bool text_file, const std::string &str, const char *fil
|
||||||
|
|
||||||
size_t ReadFileToString(bool text_file, const char *filename, std::string &str)
|
size_t ReadFileToString(bool text_file, const char *filename, std::string &str)
|
||||||
{
|
{
|
||||||
FileUtil::IOFile file(filename, text_file ? "r" : "rb");
|
IOFile file(filename, text_file ? "r" : "rb");
|
||||||
auto const f = file.GetHandle();
|
|
||||||
|
|
||||||
if (!f)
|
if (!file)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
str.resize(static_cast<u32>(GetSize(f)));
|
str.resize(static_cast<u32>(file.GetSize()));
|
||||||
return file.ReadArray(&str[0], str.size());
|
return file.ReadArray(&str[0], str.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -877,15 +876,10 @@ void SplitFilename83(const std::string& filename, std::array<char, 9>& short_nam
|
||||||
}
|
}
|
||||||
|
|
||||||
IOFile::IOFile()
|
IOFile::IOFile()
|
||||||
: m_file(nullptr), m_good(true)
|
{
|
||||||
{}
|
}
|
||||||
|
|
||||||
IOFile::IOFile(std::FILE* file)
|
|
||||||
: m_file(file), m_good(true)
|
|
||||||
{}
|
|
||||||
|
|
||||||
IOFile::IOFile(const std::string& filename, const char openmode[])
|
IOFile::IOFile(const std::string& filename, const char openmode[])
|
||||||
: m_file(nullptr), m_good(true)
|
|
||||||
{
|
{
|
||||||
Open(filename, openmode);
|
Open(filename, openmode);
|
||||||
}
|
}
|
||||||
|
@ -896,7 +890,6 @@ IOFile::~IOFile()
|
||||||
}
|
}
|
||||||
|
|
||||||
IOFile::IOFile(IOFile&& other)
|
IOFile::IOFile(IOFile&& other)
|
||||||
: m_file(nullptr), m_good(true)
|
|
||||||
{
|
{
|
||||||
Swap(other);
|
Swap(other);
|
||||||
}
|
}
|
||||||
|
@ -935,26 +928,12 @@ bool IOFile::Close()
|
||||||
return m_good;
|
return m_good;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::FILE* IOFile::ReleaseHandle()
|
u64 IOFile::GetSize() const
|
||||||
{
|
|
||||||
std::FILE* const ret = m_file;
|
|
||||||
m_file = nullptr;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void IOFile::SetHandle(std::FILE* file)
|
|
||||||
{
|
|
||||||
Close();
|
|
||||||
Clear();
|
|
||||||
m_file = file;
|
|
||||||
}
|
|
||||||
|
|
||||||
u64 IOFile::GetSize()
|
|
||||||
{
|
{
|
||||||
if (IsOpen())
|
if (IsOpen())
|
||||||
return FileUtil::GetSize(m_file);
|
return FileUtil::GetSize(m_file);
|
||||||
else
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IOFile::Seek(s64 off, int origin)
|
bool IOFile::Seek(s64 off, int origin)
|
||||||
|
@ -965,12 +944,12 @@ bool IOFile::Seek(s64 off, int origin)
|
||||||
return m_good;
|
return m_good;
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 IOFile::Tell()
|
u64 IOFile::Tell() const
|
||||||
{
|
{
|
||||||
if (IsOpen())
|
if (IsOpen())
|
||||||
return ftello(m_file);
|
return ftello(m_file);
|
||||||
else
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IOFile::Flush()
|
bool IOFile::Flush()
|
||||||
|
|
|
@ -176,7 +176,6 @@ class IOFile : public NonCopyable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
IOFile();
|
IOFile();
|
||||||
explicit IOFile(std::FILE* file);
|
|
||||||
IOFile(const std::string& filename, const char openmode[]);
|
IOFile(const std::string& filename, const char openmode[]);
|
||||||
|
|
||||||
~IOFile();
|
~IOFile();
|
||||||
|
@ -192,6 +191,9 @@ public:
|
||||||
template <typename T>
|
template <typename T>
|
||||||
size_t ReadArray(T* data, size_t length)
|
size_t ReadArray(T* data, size_t length)
|
||||||
{
|
{
|
||||||
|
static_assert(std::is_standard_layout<T>(), "Given array does not consist of standard layout objects");
|
||||||
|
static_assert(std::is_trivially_copyable<T>(), "Given array does not consist of trivially copyable objects");
|
||||||
|
|
||||||
if (!IsOpen()) {
|
if (!IsOpen()) {
|
||||||
m_good = false;
|
m_good = false;
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -207,9 +209,8 @@ public:
|
||||||
template <typename T>
|
template <typename T>
|
||||||
size_t WriteArray(const T* data, size_t length)
|
size_t WriteArray(const T* data, size_t length)
|
||||||
{
|
{
|
||||||
static_assert(std::is_standard_layout<T>::value, "Given array does not consist of standard layout objects");
|
static_assert(std::is_standard_layout<T>(), "Given array does not consist of standard layout objects");
|
||||||
// TODO: gcc 4.8 does not support is_trivially_copyable, but we really should check for it here.
|
static_assert(std::is_trivially_copyable<T>(), "Given array does not consist of trivially copyable objects");
|
||||||
//static_assert(std::is_trivially_copyable<T>::value, "Given array does not consist of trivially copyable objects");
|
|
||||||
|
|
||||||
if (!IsOpen()) {
|
if (!IsOpen()) {
|
||||||
m_good = false;
|
m_good = false;
|
||||||
|
@ -243,25 +244,20 @@ public:
|
||||||
|
|
||||||
// m_good is set to false when a read, write or other function fails
|
// m_good is set to false when a read, write or other function fails
|
||||||
bool IsGood() const { return m_good; }
|
bool IsGood() const { return m_good; }
|
||||||
operator void*() { return m_good ? m_file : nullptr; }
|
explicit operator bool() const { return IsGood(); }
|
||||||
|
|
||||||
std::FILE* ReleaseHandle();
|
|
||||||
|
|
||||||
std::FILE* GetHandle() { return m_file; }
|
|
||||||
|
|
||||||
void SetHandle(std::FILE* file);
|
|
||||||
|
|
||||||
bool Seek(s64 off, int origin);
|
bool Seek(s64 off, int origin);
|
||||||
u64 Tell();
|
u64 Tell() const;
|
||||||
u64 GetSize();
|
u64 GetSize() const;
|
||||||
bool Resize(u64 size);
|
bool Resize(u64 size);
|
||||||
bool Flush();
|
bool Flush();
|
||||||
|
|
||||||
// clear error state
|
// clear error state
|
||||||
void Clear() { m_good = true; std::clearerr(m_file); }
|
void Clear() { m_good = true; std::clearerr(m_file); }
|
||||||
|
|
||||||
std::FILE* m_file;
|
private:
|
||||||
bool m_good;
|
std::FILE* m_file = nullptr;
|
||||||
|
bool m_good = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -586,6 +586,21 @@ TextureInfo TextureInfo::FromPicaRegister(const Regs::TextureConfig& config,
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_PNG
|
||||||
|
// Adapter functions to libpng to write/flush to File::IOFile instances.
|
||||||
|
static void WriteIOFile(png_structp png_ptr, png_bytep data, png_size_t length) {
|
||||||
|
auto* fp = static_cast<FileUtil::IOFile*>(png_get_io_ptr(png_ptr));
|
||||||
|
if (!fp->WriteBytes(data, length))
|
||||||
|
png_error(png_ptr, "Failed to write to output PNG file.");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FlushIOFile(png_structp png_ptr) {
|
||||||
|
auto* fp = static_cast<FileUtil::IOFile*>(png_get_io_ptr(png_ptr));
|
||||||
|
if (!fp->Flush())
|
||||||
|
png_error(png_ptr, "Failed to flush to output PNG file.");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void DumpTexture(const Pica::Regs::TextureConfig& texture_config, u8* data) {
|
void DumpTexture(const Pica::Regs::TextureConfig& texture_config, u8* data) {
|
||||||
#ifndef HAVE_PNG
|
#ifndef HAVE_PNG
|
||||||
return;
|
return;
|
||||||
|
@ -629,7 +644,7 @@ void DumpTexture(const Pica::Regs::TextureConfig& texture_config, u8* data) {
|
||||||
goto finalise;
|
goto finalise;
|
||||||
}
|
}
|
||||||
|
|
||||||
png_init_io(png_ptr, fp.GetHandle());
|
png_set_write_fn(png_ptr, static_cast<void*>(&fp), WriteIOFile, FlushIOFile);
|
||||||
|
|
||||||
// Write header (8 bit color depth)
|
// Write header (8 bit color depth)
|
||||||
png_set_IHDR(png_ptr, info_ptr, texture_config.width, texture_config.height,
|
png_set_IHDR(png_ptr, info_ptr, texture_config.width, texture_config.height,
|
||||||
|
|
Reference in New Issue