Browse Source

Improve asset file opening

Avoid wrapping asset files via StormLib, open them directly via SDL
instead.
pull/3238/head
Gleb Mazovetskiy 4 years ago
parent
commit
7d91bc461a
  1. 1
      Source/init.cpp
  2. 22
      Source/storm/storm.cpp
  3. 1
      Source/storm/storm.h
  4. 24
      Source/storm/storm_sdl_rw.cpp
  5. 13
      Source/utils/paths.cpp
  6. 2
      Source/utils/paths.h
  7. 10
      test/pack_test.cpp

1
Source/init.cpp

@ -174,7 +174,6 @@ void init_archives()
// Load devilutionx.mpq first to get the font file for error messages
devilutionx_mpq = LoadMPQ(paths, "devilutionx.mpq");
font_mpq = LoadMPQ(paths, "fonts.mpq"); // Extra fonts
SFileSetAssetsPath(paths::AppPath() + "assets/");
if (strcasecmp("en", sgOptions.Language.szCode) != 0 || strlen(sgOptions.Language.szCode) != 2) {
char langMpqName[9] = {};

22
Source/storm/storm.cpp

@ -32,7 +32,6 @@ namespace {
bool directFileAccess = false;
std::optional<std::string> SBasePath;
std::optional<std::string> AssetsPath;
SdlMutex Mutex;
@ -126,22 +125,6 @@ bool SFileOpenFile(const char *filename, HANDLE *phFile)
result = SFileOpenFileEx((HANDLE)diabdat_mpq, filename, SFILE_OPEN_FROM_MPQ, phFile);
}
// As last fallback always search app content folder
if (!result && AssetsPath) {
std::string path = *AssetsPath + filename;
for (std::size_t i = AssetsPath->size(); i < path.size(); ++i)
path[i] = AsciiToLowerTable_Path[static_cast<unsigned char>(path[i])];
result = SFileOpenFileEx((HANDLE) nullptr, path.c_str(), SFILE_OPEN_LOCAL_FILE, phFile);
}
if (!result || (*phFile == nullptr)) {
const auto error = SErrGetLastError();
if (error == STORM_ERROR_FILE_NOT_FOUND) {
LogVerbose("{}(\"{}\") File not found", __FUNCTION__, filename);
} else {
LogError("{}(\"{}\") Failed with error code {}", __FUNCTION__, filename, error);
}
}
return result;
}
@ -160,11 +143,6 @@ void SFileSetBasePath(string_view path)
SBasePath.emplace(path);
}
void SFileSetAssetsPath(string_view path)
{
AssetsPath.emplace(path);
}
bool SFileEnableDirectAccess(bool enable)
{
directFileAccess = enable;

1
Source/storm/storm.h

@ -250,7 +250,6 @@ void SErrSetLastError(uint32_t dwErrCode);
void SStrCopy(char *dest, const char *src, int max_length);
void SFileSetBasePath(string_view path);
void SFileSetAssetsPath(string_view path);
bool SNetGetOwnerTurnsWaiting(uint32_t *);
bool SNetUnregisterEventHandler(event_type);
bool SNetRegisterEventHandler(event_type, SEVTHANDLER);

24
Source/storm/storm_sdl_rw.cpp

@ -1,11 +1,13 @@
#include "storm/storm_sdl_rw.h"
#include <algorithm>
#include <cstdint>
#include <cstring>
#include "engine.h"
#include "storm/storm.h"
#include "utils/log.hpp"
#include "utils/paths.h"
namespace devilution {
@ -106,14 +108,24 @@ SDL_RWops *SFileOpenRw(const char *filename)
if (SFileOpenFile(filename, &handle))
return SFileRw_FromStormHandle(handle);
#ifdef __ANDROID__
std::string relativePath = filename;
for (std::size_t i = 0; i < relativePath.size(); ++i) {
if (relativePath[i] == '\\')
relativePath[i] = '/';
#ifndef _WIN32
std::replace(relativePath.begin(), relativePath.end(), '\\', '/');
#endif
SDL_RWops *rwops;
if (relativePath[0] == '/') {
return SDL_RWFromFile(relativePath.c_str(), "rb");
}
SDL_RWops *rwops = SDL_RWFromFile(relativePath.c_str(), "rb");
if (rwops != nullptr)
const std::string path = paths::AssetsPath() + relativePath;
if ((rwops = SDL_RWFromFile(path.c_str(), "rb")) != nullptr)
return rwops;
#ifdef __ANDROID__
// On Android, fall back to the APK's assets.
// This is handled by SDL when we pass a relative path.
if (!paths::AssetsPath().empty() && (rwops = SDL_RWFromFile(relativePath.c_str(), "rb")))
return rwops;
#endif

13
Source/utils/paths.cpp

@ -21,6 +21,7 @@ std::optional<std::string> appPath;
std::optional<std::string> basePath;
std::optional<std::string> prefPath;
std::optional<std::string> configPath;
std::optional<std::string> assetsPath;
void AddTrailingSlash(std::string &path)
{
@ -84,6 +85,13 @@ const std::string &ConfigPath()
return *configPath;
}
const std::string &AssetsPath()
{
if (!assetsPath)
assetsPath.emplace(AppPath() + "assets/");
return *assetsPath;
}
void SetBasePath(const std::string &path)
{
basePath = path;
@ -102,6 +110,11 @@ void SetConfigPath(const std::string &path)
AddTrailingSlash(*configPath);
}
void SetMpqDir(const std::string &path)
{
mpqDir = std::string(path);
}
} // namespace paths
} // namespace devilution

2
Source/utils/paths.h

@ -10,10 +10,12 @@ const std::string &AppPath();
const std::string &BasePath();
const std::string &PrefPath();
const std::string &ConfigPath();
const std::string &AssetsPath();
void SetBasePath(const std::string &path);
void SetPrefPath(const std::string &path);
void SetConfigPath(const std::string &path);
void SetMpqDir(const std::string &path);
} // namespace paths

10
test/pack_test.cpp

@ -333,8 +333,6 @@ TEST(pack, UnPackItem_diablo)
Item id;
ItemPack is;
SFileSetAssetsPath(devilution::paths::AppPath() + "assets/");
gbIsHellfire = false;
gbIsMultiplayer = false;
gbIsSpawn = false;
@ -356,8 +354,6 @@ TEST(pack, UnPackItem_diablo_unique_bug)
ItemPack pkItemBug = { 6, 911, 14, 5, 60, 60, 0, 0, 0, 0 }; // Veil of Steel - with morph bug
ItemPack pkItem = { 6, 655, 14, 5, 60, 60, 0, 0, 0, 0 }; // Veil of Steel - fixed
SFileSetAssetsPath(devilution::paths::AppPath() + "assets/");
gbIsHellfire = false;
gbIsMultiplayer = false;
gbIsSpawn = false;
@ -408,8 +404,6 @@ TEST(pack, UnPackItem_spawn)
Item id;
ItemPack is;
SFileSetAssetsPath(devilution::paths::AppPath() + "assets/");
gbIsHellfire = false;
gbIsMultiplayer = false;
gbIsSpawn = true;
@ -454,8 +448,6 @@ TEST(pack, UnPackItem_diablo_multiplayer)
Item id;
ItemPack is;
SFileSetAssetsPath(devilution::paths::AppPath() + "assets/");
gbIsHellfire = false;
gbIsMultiplayer = true;
gbIsSpawn = false;
@ -665,8 +657,6 @@ TEST(pack, UnPackItem_hellfire)
Item id;
ItemPack is;
SFileSetAssetsPath(devilution::paths::AppPath() + "assets/");
gbIsHellfire = true;
gbIsMultiplayer = false;
gbIsSpawn = false;

Loading…
Cancel
Save