mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-04 05:51:27 +12:00
Added fs::file_ptr, fom::rewrite, cleanup
This commit is contained in:
parent
009aa3dcb9
commit
a4db58f5f2
19 changed files with 130 additions and 54 deletions
|
@ -96,6 +96,7 @@ bool truncate_file(const std::string& file, u64 length)
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
#include <sys/mman.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
@ -306,14 +307,16 @@ bool fs::rename(const std::string& from, const std::string& to)
|
||||||
|
|
||||||
int OSCopyFile(const char* source, const char* destination, bool overwrite)
|
int OSCopyFile(const char* source, const char* destination, bool overwrite)
|
||||||
{
|
{
|
||||||
/* This function was taken from http://stackoverflow.com/questions/2180079/how-can-i-copy-a-file-on-unix-using-c */
|
/* Source: http://stackoverflow.com/questions/2180079/how-can-i-copy-a-file-on-unix-using-c */
|
||||||
|
|
||||||
int input, output;
|
const int input = open(source, O_RDONLY);
|
||||||
if ((input = open(source, O_RDONLY)) == -1)
|
if (input == -1)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if ((output = open(destination, O_WRONLY | O_CREAT | (overwrite ? O_TRUNC : O_EXCL), 0666)) == -1)
|
|
||||||
|
const int output = open(destination, O_WRONLY | O_CREAT | (overwrite ? O_TRUNC : O_EXCL), 0666);
|
||||||
|
if (output == -1)
|
||||||
{
|
{
|
||||||
close(input);
|
close(input);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -322,13 +325,12 @@ int OSCopyFile(const char* source, const char* destination, bool overwrite)
|
||||||
//Here we use kernel-space copying for performance reasons
|
//Here we use kernel-space copying for performance reasons
|
||||||
#if defined(__APPLE__) || defined(__FreeBSD__)
|
#if defined(__APPLE__) || defined(__FreeBSD__)
|
||||||
//fcopyfile works on FreeBSD and OS X 10.5+
|
//fcopyfile works on FreeBSD and OS X 10.5+
|
||||||
int result = fcopyfile(input, output, 0, COPYFILE_ALL);
|
const int result = fcopyfile(input, output, 0, COPYFILE_ALL);
|
||||||
#else
|
#else
|
||||||
//sendfile will work with non-socket output (i.e. regular file) on Linux 2.6.33+
|
//sendfile will work with non-socket output (i.e. regular file) on Linux 2.6.33+
|
||||||
off_t bytesCopied = 0;
|
off_t bytesCopied = 0;
|
||||||
struct stat fileinfo = { 0 };
|
struct stat fileinfo = { 0 };
|
||||||
fstat(input, &fileinfo);
|
const int result = fstat(input, &fileinfo) == -1 || sendfile(output, input, &bytesCopied, fileinfo.st_size) == -1 ? -1 : 0;
|
||||||
int result = sendfile(output, input, &bytesCopied, fileinfo.st_size) == -1 ? -1 : 0;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
close(input);
|
close(input);
|
||||||
|
@ -662,6 +664,36 @@ fs::dir::~dir()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void fs::file_ptr::reset(const file& f)
|
||||||
|
{
|
||||||
|
reset();
|
||||||
|
|
||||||
|
if (f)
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
const HANDLE handle = ::CreateFileMapping((HANDLE)f.m_fd, NULL, PAGE_READONLY, 0, 0, NULL);
|
||||||
|
m_ptr = (char*)::MapViewOfFile(handle, FILE_MAP_READ, 0, 0, 0);
|
||||||
|
m_size = f.size();
|
||||||
|
::CloseHandle(handle);
|
||||||
|
#else
|
||||||
|
m_ptr = (char*)::mmap(nullptr, m_size = f.size(), PROT_READ, MAP_SHARED, f.m_fd, 0);
|
||||||
|
if (m_ptr == (void*)-1) m_ptr = nullptr;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void fs::file_ptr::reset()
|
||||||
|
{
|
||||||
|
if (m_ptr)
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
::UnmapViewOfFile(m_ptr);
|
||||||
|
#else
|
||||||
|
::munmap(m_ptr, m_size);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool fs::dir::open(const std::string& dirname)
|
bool fs::dir::open(const std::string& dirname)
|
||||||
{
|
{
|
||||||
this->close();
|
this->close();
|
||||||
|
|
|
@ -11,12 +11,14 @@ namespace fom // file open mode
|
||||||
{
|
{
|
||||||
enum : u32
|
enum : u32
|
||||||
{
|
{
|
||||||
read = 1 << 0,
|
read = 1 << 0, // enable reading
|
||||||
write = 1 << 1,
|
write = 1 << 1, // enable writing
|
||||||
append = 1 << 2,
|
append = 1 << 2, // enable appending (always write to the end of file)
|
||||||
create = 1 << 3,
|
create = 1 << 3, // create file if it doesn't exist
|
||||||
trunc = 1 << 4,
|
trunc = 1 << 4, // clear opened file if it's not empty
|
||||||
excl = 1 << 5,
|
excl = 1 << 5, // failure if the file already exists (used with `create`)
|
||||||
|
|
||||||
|
rewrite = write | create | trunc, // write + create + trunc
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -81,6 +83,8 @@ namespace fs
|
||||||
|
|
||||||
handle_type m_fd = null;
|
handle_type m_fd = null;
|
||||||
|
|
||||||
|
friend class file_ptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
file() = default;
|
file() = default;
|
||||||
|
|
||||||
|
@ -133,14 +137,63 @@ namespace fs
|
||||||
// Write the data to the file and return the amount of data actually written
|
// Write the data to the file and return the amount of data actually written
|
||||||
u64 write(const void* buffer, u64 count) const;
|
u64 write(const void* buffer, u64 count) const;
|
||||||
|
|
||||||
// Write std::string
|
|
||||||
u64 write(const std::string& string) const { return write(string.data(), string.size()); }
|
|
||||||
|
|
||||||
// Move file pointer
|
// Move file pointer
|
||||||
u64 seek(s64 offset, fsm seek_mode = fsm::begin) const;
|
u64 seek(s64 offset, fsm seek_mode = fsm::begin) const;
|
||||||
|
|
||||||
// Get file size
|
// Get file size
|
||||||
u64 size() const;
|
u64 size() const;
|
||||||
|
|
||||||
|
// Write std::string
|
||||||
|
const file& operator <<(const std::string& str) const
|
||||||
|
{
|
||||||
|
CHECK_ASSERTION(write(str.data(), str.size()) == str.size());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class file_ptr final
|
||||||
|
{
|
||||||
|
char* m_ptr = nullptr;
|
||||||
|
u64 m_size;
|
||||||
|
|
||||||
|
public:
|
||||||
|
file_ptr() = default;
|
||||||
|
|
||||||
|
file_ptr(file_ptr&& right)
|
||||||
|
: m_ptr(right.m_ptr)
|
||||||
|
, m_size(right.m_size)
|
||||||
|
{
|
||||||
|
right.m_ptr = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
file_ptr& operator =(file_ptr&& right)
|
||||||
|
{
|
||||||
|
std::swap(m_ptr, right.m_ptr);
|
||||||
|
std::swap(m_size, right.m_size);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
file_ptr(const file& f)
|
||||||
|
{
|
||||||
|
reset(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
~file_ptr()
|
||||||
|
{
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open file mapping
|
||||||
|
void reset(const file& f);
|
||||||
|
|
||||||
|
// Close file mapping
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
// Get pointer
|
||||||
|
operator char*() const
|
||||||
|
{
|
||||||
|
return m_ptr;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class dir final
|
class dir final
|
||||||
|
|
|
@ -94,7 +94,7 @@ struct FileListener : LogListener
|
||||||
bool mPrependChannelName;
|
bool mPrependChannelName;
|
||||||
|
|
||||||
FileListener(const std::string& name = _PRGNAME_, bool prependChannel = true)
|
FileListener(const std::string& name = _PRGNAME_, bool prependChannel = true)
|
||||||
: mFile(rPlatform::getConfigDir() + name + ".log", fom::write | fom::create | fom::trunc)
|
: mFile(rPlatform::getConfigDir() + name + ".log", fom::rewrite)
|
||||||
, mPrependChannelName(prependChannel)
|
, mPrependChannelName(prependChannel)
|
||||||
{
|
{
|
||||||
if (!mFile)
|
if (!mFile)
|
||||||
|
@ -120,7 +120,7 @@ struct FileListener : LogListener
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mFile.write(text.c_str(), text.size());
|
mFile << text;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -821,7 +821,7 @@ int DecryptEDAT(const std::string& input_file_name, const std::string& output_fi
|
||||||
{
|
{
|
||||||
// Prepare the files.
|
// Prepare the files.
|
||||||
fs::file input(input_file_name);
|
fs::file input(input_file_name);
|
||||||
fs::file output(output_file_name, fom::write | fom::create | fom::trunc);
|
fs::file output(output_file_name, fom::rewrite);
|
||||||
fs::file rap(rap_file_name);
|
fs::file rap(rap_file_name);
|
||||||
|
|
||||||
// Set keys (RIF and DEVKLIC).
|
// Set keys (RIF and DEVKLIC).
|
||||||
|
|
|
@ -59,7 +59,7 @@ static bool CheckHeader(const fs::file& pkg_f, PKGHeader& header)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PKG Decryption
|
// PKG Decryption
|
||||||
bool UnpackPKG(const fs::file& pkg_f, const std::string& dir, volatile f64& progress)
|
bool pkg_install(const fs::file& pkg_f, const std::string& dir, volatile f64& progress)
|
||||||
{
|
{
|
||||||
const std::size_t BUF_SIZE = 8192 * 1024; // 8 MB
|
const std::size_t BUF_SIZE = 8192 * 1024; // 8 MB
|
||||||
|
|
||||||
|
|
|
@ -57,4 +57,4 @@ struct PKGEntry
|
||||||
be_t<u32> pad; // Padding (zeros)
|
be_t<u32> pad; // Padding (zeros)
|
||||||
};
|
};
|
||||||
|
|
||||||
bool UnpackPKG(const class fs::file& pkg_f, const std::string& dir, volatile f64& progress);
|
bool pkg_install(const class fs::file& pkg_f, const std::string& dir, volatile f64& progress);
|
||||||
|
|
|
@ -1085,8 +1085,8 @@ bool SELFDecrypter::DecryptData()
|
||||||
bool SELFDecrypter::MakeElf(const std::string& elf, bool isElf32)
|
bool SELFDecrypter::MakeElf(const std::string& elf, bool isElf32)
|
||||||
{
|
{
|
||||||
// Create a new ELF file.
|
// Create a new ELF file.
|
||||||
fs::file e(elf, fom::write | fom::create | fom::trunc);
|
fs::file e(elf, fom::rewrite);
|
||||||
if (!e)
|
if(!e)
|
||||||
{
|
{
|
||||||
LOG_ERROR(LOADER, "Could not create ELF file! (%s)", elf.c_str());
|
LOG_ERROR(LOADER, "Could not create ELF file! (%s)", elf.c_str());
|
||||||
return false;
|
return false;
|
||||||
|
@ -1309,7 +1309,7 @@ bool CheckDebugSelf(const std::string& self, const std::string& elf)
|
||||||
CHECK_ASSERTION(s.seek(elf_offset) != -1);
|
CHECK_ASSERTION(s.seek(elf_offset) != -1);
|
||||||
|
|
||||||
// Write the real ELF file back.
|
// Write the real ELF file back.
|
||||||
fs::file e(elf, fom::write | fom::create | fom::trunc);
|
fs::file e(elf, fom::rewrite);
|
||||||
if (!e)
|
if (!e)
|
||||||
{
|
{
|
||||||
LOG_ERROR(LOADER, "Could not create ELF file! (%s)", elf.c_str());
|
LOG_ERROR(LOADER, "Could not create ELF file! (%s)", elf.c_str());
|
||||||
|
|
|
@ -12,7 +12,7 @@ AudioDumper::~AudioDumper()
|
||||||
|
|
||||||
bool AudioDumper::Init(u8 ch)
|
bool AudioDumper::Init(u8 ch)
|
||||||
{
|
{
|
||||||
if ((m_init = m_output.open("audio.wav", fom::write | fom::create | fom::trunc)))
|
if ((m_init = m_output.open("audio.wav", fom::rewrite)))
|
||||||
{
|
{
|
||||||
m_header = WAVHeader(ch);
|
m_header = WAVHeader(ch);
|
||||||
WriteHeader();
|
WriteHeader();
|
||||||
|
|
|
@ -33,9 +33,7 @@ spu_recompiler::spu_recompiler()
|
||||||
|
|
||||||
LOG_SUCCESS(SPU, "SPU Recompiler (ASMJIT) created...");
|
LOG_SUCCESS(SPU, "SPU Recompiler (ASMJIT) created...");
|
||||||
|
|
||||||
const std::string str = fmt::format("SPU JIT initialization...\n\nTitle: %s\nTitle ID: %s\n\n", Emu.GetTitle().c_str(), Emu.GetTitleID().c_str());
|
fs::file("SPUJIT.log", fom::rewrite) << fmt::format("SPU JIT initialization...\n\nTitle: %s\nTitle ID: %s\n\n", Emu.GetTitle().c_str(), Emu.GetTitleID().c_str());
|
||||||
|
|
||||||
fs::file("SPUJIT.log", fom::write | fom::create | fom::trunc).write(str.c_str(), str.size());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void spu_recompiler::compile(spu_function_t& f)
|
void spu_recompiler::compile(spu_function_t& f)
|
||||||
|
@ -220,7 +218,7 @@ void spu_recompiler::compile(spu_function_t& f)
|
||||||
log += "\n\n\n";
|
log += "\n\n\n";
|
||||||
|
|
||||||
// Append log file
|
// Append log file
|
||||||
fs::file("SPUJIT.log", fom::write | fom::append | fom::create).write(log.c_str(), log.size());
|
fs::file("SPUJIT.log", fom::write | fom::append) << log;
|
||||||
}
|
}
|
||||||
|
|
||||||
spu_recompiler::XmmLink spu_recompiler::XmmAlloc() // get empty xmm register
|
spu_recompiler::XmmLink spu_recompiler::XmmAlloc() // get empty xmm register
|
||||||
|
|
|
@ -21,7 +21,7 @@ void vfsHDDManager::CreateEntry(vfsHDD_Entry& entry)
|
||||||
|
|
||||||
void vfsHDDManager::CreateHDD(const std::string& path, u64 size, u64 block_size)
|
void vfsHDDManager::CreateHDD(const std::string& path, u64 size, u64 block_size)
|
||||||
{
|
{
|
||||||
fs::file f(path, fom::write | fom::create | fom::trunc);
|
fs::file f(path, fom::rewrite);
|
||||||
|
|
||||||
static const u64 cur_dir_block = 1;
|
static const u64 cur_dir_block = 1;
|
||||||
|
|
||||||
|
|
|
@ -164,8 +164,7 @@ struct D3D12Traits
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: This shouldn't use current dir
|
// TODO: This shouldn't use current dir
|
||||||
std::string filename = "./FragmentProgram" + std::to_string(ID) + ".hlsl";
|
fs::file("./FragmentProgram" + std::to_string(ID) + ".hlsl", fom::rewrite) << shader;
|
||||||
fs::file(filename, fom::write | fom::create | fom::trunc).write(shader.c_str(), shader.size());
|
|
||||||
fragmentProgramData.id = (u32)ID;
|
fragmentProgramData.id = (u32)ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,8 +176,7 @@ struct D3D12Traits
|
||||||
vertexProgramData.Compile(shaderCode, Shader::SHADER_TYPE::SHADER_TYPE_VERTEX);
|
vertexProgramData.Compile(shaderCode, Shader::SHADER_TYPE::SHADER_TYPE_VERTEX);
|
||||||
vertexProgramData.vertex_shader_inputs = VS.input_slots;
|
vertexProgramData.vertex_shader_inputs = VS.input_slots;
|
||||||
// TODO: This shouldn't use current dir
|
// TODO: This shouldn't use current dir
|
||||||
std::string filename = "./VertexProgram" + std::to_string(ID) + ".hlsl";
|
fs::file("./VertexProgram" + std::to_string(ID) + ".hlsl", fom::rewrite) << shaderCode;
|
||||||
fs::file(filename, fom::write | fom::create | fom::trunc).write(shaderCode.c_str(), shaderCode.size());
|
|
||||||
vertexProgramData.id = (u32)ID;
|
vertexProgramData.id = (u32)ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -469,7 +469,7 @@ void GLTexture::save(rsx::texture& tex, const std::string& name)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fs::file(name + ".raw", fom::write | fom::create | fom::trunc).write(alldata, texPixelCount * 4);
|
fs::file(name + ".raw", fom::rewrite).write(alldata, texPixelCount * 4);
|
||||||
|
|
||||||
u8* data = new u8[texPixelCount * 3];
|
u8* data = new u8[texPixelCount * 3];
|
||||||
u8* alpha = new u8[texPixelCount];
|
u8* alpha = new u8[texPixelCount];
|
||||||
|
|
|
@ -19,7 +19,7 @@ struct GLTraits
|
||||||
//checkForGlError("m_fragment_prog.Compile");
|
//checkForGlError("m_fragment_prog.Compile");
|
||||||
|
|
||||||
// TODO: This shouldn't use current dir
|
// TODO: This shouldn't use current dir
|
||||||
fs::file("./FragmentProgram.txt", fom::write | fom::create | fom::trunc).write(fragmentProgramData.shader.c_str(), fragmentProgramData.shader.size());
|
fs::file("./FragmentProgram.txt", fom::rewrite) << fragmentProgramData.shader;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
|
@ -30,7 +30,7 @@ struct GLTraits
|
||||||
//checkForGlError("m_vertex_prog.Compile");
|
//checkForGlError("m_vertex_prog.Compile");
|
||||||
|
|
||||||
// TODO: This shouldn't use current dir
|
// TODO: This shouldn't use current dir
|
||||||
fs::file("./VertexProgram.txt", fom::write | fom::create | fom::trunc).write(vertexProgramData.shader.c_str(), vertexProgramData.shader.size());
|
fs::file("./VertexProgram.txt", fom::rewrite) << vertexProgramData.shader;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
|
|
|
@ -753,7 +753,7 @@ bool sdata_check(u32 version, u32 flags, u64 filesizeInput, u64 filesizeTmp)
|
||||||
s32 sdata_unpack(const std::string& packed_file, const std::string& unpacked_file)
|
s32 sdata_unpack(const std::string& packed_file, const std::string& unpacked_file)
|
||||||
{
|
{
|
||||||
std::shared_ptr<vfsFileBase> packed_stream(Emu.GetVFS().OpenFile(packed_file, fom::read));
|
std::shared_ptr<vfsFileBase> packed_stream(Emu.GetVFS().OpenFile(packed_file, fom::read));
|
||||||
std::shared_ptr<vfsFileBase> unpacked_stream(Emu.GetVFS().OpenFile(unpacked_file, fom::write | fom::create | fom::trunc));
|
std::shared_ptr<vfsFileBase> unpacked_stream(Emu.GetVFS().OpenFile(unpacked_file, fom::rewrite));
|
||||||
|
|
||||||
if (!packed_stream || !packed_stream->IsOpened())
|
if (!packed_stream || !packed_stream->IsOpened())
|
||||||
{
|
{
|
||||||
|
|
|
@ -622,7 +622,7 @@ never_inline s32 savedata_op(PPUThread& ppu, u32 operation, u32 version, vm::cpt
|
||||||
// Write PARAM.SFO
|
// Write PARAM.SFO
|
||||||
if (psf)
|
if (psf)
|
||||||
{
|
{
|
||||||
vfsFile f(sfo_path, fom::write | fom::create | fom::trunc);
|
vfsFile f(sfo_path, fom::rewrite);
|
||||||
psf.Save(f);
|
psf.Save(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -96,7 +96,7 @@ void AutoPauseManagerDialog::LoadEntries(void)
|
||||||
//This would always use a 0xFFFFFFFF as end of the pause.bin
|
//This would always use a 0xFFFFFFFF as end of the pause.bin
|
||||||
void AutoPauseManagerDialog::SaveEntries(void)
|
void AutoPauseManagerDialog::SaveEntries(void)
|
||||||
{
|
{
|
||||||
fs::file list("pause.bin", fom::write | fom::create | fom::trunc);
|
fs::file list("pause.bin", fom::rewrite);
|
||||||
//System calls ID and Function calls ID are all u32 iirc.
|
//System calls ID and Function calls ID are all u32 iirc.
|
||||||
u32 num = 0;
|
u32 num = 0;
|
||||||
CHECK_ASSERTION(list.seek(0) != -1);
|
CHECK_ASSERTION(list.seek(0) != -1);
|
||||||
|
|
|
@ -252,25 +252,20 @@ void MainFrame::InstallPkg(wxCommandEvent& WXUNUSED(event))
|
||||||
Emu.GetVFS().GetDevice("/dev_hdd0/game/", local_path);
|
Emu.GetVFS().GetDevice("/dev_hdd0/game/", local_path);
|
||||||
|
|
||||||
// Open PKG file
|
// Open PKG file
|
||||||
fs::file pkg_f{ ctrl.GetPath().ToStdString() };
|
fs::file pkg_f(ctrl.GetPath().ToStdString());
|
||||||
|
|
||||||
if (!pkg_f)
|
// Open file mapping (test)
|
||||||
|
fs::file_ptr pkg_ptr(pkg_f);
|
||||||
|
|
||||||
|
if (!pkg_f || !pkg_ptr)
|
||||||
{
|
{
|
||||||
LOG_ERROR(LOADER, "PKG: Failed to open %s", ctrl.GetPath().ToStdString());
|
LOG_ERROR(LOADER, "PKG: Failed to open %s", ctrl.GetPath().ToStdString());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch title ID from the header
|
|
||||||
char title_id[10] = "?????????";
|
|
||||||
|
|
||||||
CHECK_ASSERTION(pkg_f.seek(55) != -1);
|
|
||||||
|
|
||||||
pkg_f.read(title_id, 9);
|
|
||||||
pkg_f.seek(0);
|
|
||||||
|
|
||||||
// Append title ID to the path
|
// Append title ID to the path
|
||||||
local_path += '/';
|
local_path += '/';
|
||||||
local_path += title_id;
|
local_path += { pkg_ptr + 55, 9 };
|
||||||
|
|
||||||
if (!fs::create_dir(local_path))
|
if (!fs::create_dir(local_path))
|
||||||
{
|
{
|
||||||
|
@ -294,7 +289,7 @@ void MainFrame::InstallPkg(wxCommandEvent& WXUNUSED(event))
|
||||||
volatile f64 progress = 0.0;
|
volatile f64 progress = 0.0;
|
||||||
|
|
||||||
// Run PKG unpacking asynchronously
|
// Run PKG unpacking asynchronously
|
||||||
auto result = std::async(WRAP_EXPR(UnpackPKG(pkg_f, local_path + "/", progress)));
|
auto result = std::async(WRAP_EXPR(pkg_install(pkg_f, local_path + "/", progress)));
|
||||||
|
|
||||||
// Wait for the completion
|
// Wait for the completion
|
||||||
while (result.wait_for(15ms) != std::future_status::ready)
|
while (result.wait_for(15ms) != std::future_status::ready)
|
||||||
|
|
|
@ -124,7 +124,7 @@ bool TROPUSRLoader::Save(const std::string& filepath)
|
||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_file = Emu.GetVFS().OpenFile(filepath, fom::write | fom::create | fom::trunc);
|
m_file = Emu.GetVFS().OpenFile(filepath, fom::rewrite);
|
||||||
m_file->Write(&m_header, sizeof(TROPUSRHeader));
|
m_file->Write(&m_header, sizeof(TROPUSRHeader));
|
||||||
|
|
||||||
for (const TROPUSRTableHeader& tableHeader : m_tableHeaders)
|
for (const TROPUSRTableHeader& tableHeader : m_tableHeaders)
|
||||||
|
|
|
@ -36,7 +36,7 @@ bool TRPLoader::Install(std::string dest, bool show)
|
||||||
char* buffer = new char [(u32)entry.size];
|
char* buffer = new char [(u32)entry.size];
|
||||||
trp_f.Seek(entry.offset);
|
trp_f.Seek(entry.offset);
|
||||||
trp_f.Read(buffer, entry.size);
|
trp_f.Read(buffer, entry.size);
|
||||||
vfsFile(dest + entry.name, fom::write | fom::create | fom::trunc).Write(buffer, entry.size);
|
vfsFile(dest + entry.name, fom::rewrite).Write(buffer, entry.size);
|
||||||
delete[] buffer;
|
delete[] buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue