You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
61 lines
1.6 KiB
61 lines
1.6 KiB
#include "mpq/mpq_sdl_rwops.hpp" |
|
|
|
#include <cstring> |
|
|
|
#include <mpqfs/mpqfs.h> |
|
|
|
namespace devilution { |
|
|
|
namespace { |
|
constexpr size_t MaxMpqPathSize = 256; |
|
} // namespace |
|
|
|
SdlRwopsType *SDL_RWops_FromMpqFile(MpqArchive &archive, |
|
uint32_t hashIndex, |
|
std::string_view filename, |
|
bool threadsafe) |
|
{ |
|
char pathBuf[MaxMpqPathSize]; |
|
if (filename.size() >= sizeof(pathBuf)) |
|
return nullptr; |
|
std::memcpy(pathBuf, filename.data(), filename.size()); |
|
pathBuf[filename.size()] = '\0'; |
|
|
|
if (threadsafe) { |
|
if (hashIndex != UINT32_MAX) { |
|
#ifdef USE_SDL3 |
|
SdlRwopsType *result = mpqfs_open_io_threadsafe_from_hash(archive.handle(), hashIndex); |
|
#else |
|
SdlRwopsType *result = mpqfs_open_rwops_threadsafe_from_hash(archive.handle(), hashIndex); |
|
#endif |
|
if (result != nullptr) |
|
return result; |
|
} |
|
#ifdef USE_SDL3 |
|
return mpqfs_open_io_threadsafe(archive.handle(), pathBuf); |
|
#else |
|
return mpqfs_open_rwops_threadsafe(archive.handle(), pathBuf); |
|
#endif |
|
} |
|
|
|
// Non-threadsafe path: use hash-based open if available to avoid re-hashing. |
|
// This may fail for encrypted files (which need the filename for key derivation), |
|
// so we fall back to filename-based open on failure. |
|
if (hashIndex != UINT32_MAX) { |
|
#ifdef USE_SDL3 |
|
SdlRwopsType *result = mpqfs_open_io_from_hash(archive.handle(), hashIndex); |
|
#else |
|
SdlRwopsType *result = mpqfs_open_rwops_from_hash(archive.handle(), hashIndex); |
|
#endif |
|
if (result != nullptr) |
|
return result; |
|
} |
|
|
|
#ifdef USE_SDL3 |
|
return mpqfs_open_io(archive.handle(), pathBuf); |
|
#else |
|
return mpqfs_open_rwops(archive.handle(), pathBuf); |
|
#endif |
|
} |
|
|
|
} // namespace devilution
|
|
|