mirror of
https://github.com/thunderbrewhq/thunderbrew
synced 2025-12-12 03:02:30 +00:00
fix(gx): SFile can read from an MPQ-archived file or a plain file
This commit is contained in:
parent
e20f185f75
commit
70642dec21
2 changed files with 90 additions and 24 deletions
|
|
@ -4,6 +4,7 @@
|
||||||
#include <StormLib.h>
|
#include <StormLib.h>
|
||||||
#include <storm/Memory.hpp>
|
#include <storm/Memory.hpp>
|
||||||
#include <storm/String.hpp>
|
#include <storm/String.hpp>
|
||||||
|
#include <bc/file/File.hpp>
|
||||||
#include "util/Filesystem.hpp"
|
#include "util/Filesystem.hpp"
|
||||||
|
|
||||||
static char s_basepath[STORM_MAX_PATH] = {0};
|
static char s_basepath[STORM_MAX_PATH] = {0};
|
||||||
|
|
@ -11,15 +12,46 @@ static char s_datapath[STORM_MAX_PATH] = {0};
|
||||||
|
|
||||||
// TODO Proper implementation
|
// TODO Proper implementation
|
||||||
int32_t SFile::Close(SFile* file) {
|
int32_t SFile::Close(SFile* file) {
|
||||||
|
switch (file->m_type) {
|
||||||
|
case SFILE_PLAIN:
|
||||||
|
Blizzard::File::Close(reinterpret_cast<Blizzard::File::StreamRecord*>(file->m_handle));
|
||||||
|
break;
|
||||||
|
case SFILE_PAQ:
|
||||||
SFileCloseFile(file->m_handle);
|
SFileCloseFile(file->m_handle);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
STORM_ASSERT(0);
|
||||||
|
}
|
||||||
|
|
||||||
delete file;
|
delete file;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO Proper implementation
|
// TODO Proper implementation
|
||||||
uint32_t SFile::GetFileSize(SFile* file, uint32_t* filesizeHigh) {
|
uint32_t SFile::GetFileSize(SFile* file, uint32_t* filesizeHigh) {
|
||||||
DWORD high = 0;
|
uint32_t high = 0;
|
||||||
DWORD low = SFileGetFileSize(file->m_handle, &high);
|
uint32_t low = 0;
|
||||||
|
|
||||||
|
switch (file->m_type) {
|
||||||
|
case SFILE_PAQ:
|
||||||
|
{
|
||||||
|
// Get size from stormlib
|
||||||
|
DWORD dwHigh = 0;
|
||||||
|
DWORD dwLow = SFileGetFileSize(file->m_handle, &dwHigh);
|
||||||
|
low = static_cast<uint32_t>(dwLow);
|
||||||
|
high = static_cast<uint32_t>(dwHigh);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SFILE_PLAIN:
|
||||||
|
{
|
||||||
|
uint64_t size = Blizzard::File::GetFileInfo(reinterpret_cast<Blizzard::File::StreamRecord*>(file->m_handle))->size;
|
||||||
|
low = size & 0xFFFFFFFF;
|
||||||
|
high = size >> 32;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
STORM_ASSERT(0);
|
||||||
|
}
|
||||||
|
|
||||||
if (filesizeHigh) {
|
if (filesizeHigh) {
|
||||||
*filesizeHigh = high;
|
*filesizeHigh = high;
|
||||||
|
|
@ -96,24 +128,44 @@ int32_t SFile::OpenEx(SArchive* archive, const char* filename, uint32_t flags, S
|
||||||
}
|
}
|
||||||
|
|
||||||
SStrCopy(path, filename, STORM_MAX_PATH);
|
SStrCopy(path, filename, STORM_MAX_PATH);
|
||||||
OsFileToNativeSlashes(path);
|
|
||||||
|
|
||||||
|
SFILE_TYPE filetype = SFILE_PLAIN;
|
||||||
|
void* filehandle;
|
||||||
HANDLE handle;
|
HANDLE handle;
|
||||||
if (!SFileOpenFileEx(nullptr, path, SFILE_OPEN_LOCAL_FILE, &handle)) {
|
|
||||||
OsFileToBackSlashes(path);
|
uint32_t openflags = BC_FILE_OPEN_MUST_EXIST | BC_FILE_OPEN_SHARE_READ | BC_FILE_OPEN_READ;
|
||||||
if (!SFileOpenFileEx(g_mpqHandle, path, SFILE_OPEN_FROM_MPQ, &handle)) {
|
Blizzard::File::StreamRecord* stream;
|
||||||
|
|
||||||
|
// Attempt to open plain file first
|
||||||
|
if (Blizzard::File::Open(path, openflags, stream)) {
|
||||||
|
// plain file was opened
|
||||||
|
filehandle = reinterpret_cast<void*>(stream);
|
||||||
|
// Attempt to open MPQ archived file
|
||||||
|
} else if (SFileOpenFileEx(g_mpqHandle, path, SFILE_OPEN_FROM_MPQ, &handle)) {
|
||||||
|
filetype = SFILE_PAQ;
|
||||||
|
filehandle = static_cast<void*>(handle);
|
||||||
|
} else {
|
||||||
|
// could not open either plain or MPQ archived file
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
*file = new SFile;
|
*file = new SFile;
|
||||||
(*file)->m_handle = handle;
|
(*file)->m_handle = filehandle;
|
||||||
|
(*file)->m_type = filetype;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO Proper implementation
|
// TODO Proper implementation
|
||||||
int32_t SFile::Read(SFile* file, void* buffer, size_t bytestoread, size_t* bytesread, SOVERLAPPED* overlapped, TASYNCPARAMBLOCK* asyncparam) {
|
int32_t SFile::Read(SFile* file, void* buffer, size_t bytestoread, size_t* bytesread, SOVERLAPPED* overlapped, TASYNCPARAMBLOCK* asyncparam) {
|
||||||
|
switch (file->m_type) {
|
||||||
|
case SFILE_PLAIN:
|
||||||
|
{
|
||||||
|
Blizzard::File::Read(file->m_stream, buffer, bytestoread, bytesread);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
case SFILE_PAQ:
|
||||||
|
{
|
||||||
DWORD read = 0;
|
DWORD read = 0;
|
||||||
if (SFileReadFile(file->m_handle, buffer, static_cast<DWORD>(bytestoread), &read, nullptr)) {
|
if (SFileReadFile(file->m_handle, buffer, static_cast<DWORD>(bytestoread), &read, nullptr)) {
|
||||||
if (bytesread) {
|
if (bytesread) {
|
||||||
|
|
@ -126,6 +178,12 @@ int32_t SFile::Read(SFile* file, void* buffer, size_t bytestoread, size_t* bytes
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
STORM_ASSERT(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t SFile::Unload(void* ptr) {
|
int32_t SFile::Unload(void* ptr) {
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,13 @@ class StreamRecord;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum SFILE_TYPE {
|
||||||
|
SFILE_PLAIN = 0x0,
|
||||||
|
SFILE_COMPRESSED = 0x1,
|
||||||
|
SFILE_PAQ = 0x2,
|
||||||
|
SFILE_OLD_SFILE = 0x3,
|
||||||
|
SFILE_ZIP_FILE = 0x4
|
||||||
|
};
|
||||||
|
|
||||||
class SFile {
|
class SFile {
|
||||||
public:
|
public:
|
||||||
|
|
@ -31,6 +38,7 @@ class SFile {
|
||||||
static int32_t GetDataPath(char* path, size_t capacity);
|
static int32_t GetDataPath(char* path, size_t capacity);
|
||||||
|
|
||||||
// Member variables
|
// Member variables
|
||||||
|
SFILE_TYPE m_type;
|
||||||
void* m_handle;
|
void* m_handle;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue