mirror of
https://github.com/isledecomp/isle-portable.git
synced 2026-01-11 18:41:14 +00:00
Map internal paths to filesystem paths (#100)
* Map internal paths to actual filesystem paths * Only do this on non-Windows * Update LEGO1/omni/src/common/mxstring.cpp Co-authored-by: Anonymous Maarten <madebr@users.noreply.github.com> * add priority * Revert for now --------- Co-authored-by: Anonymous Maarten <madebr@users.noreply.github.com>
This commit is contained in:
parent
543edf292a
commit
5ae47c2b56
@ -172,7 +172,7 @@ MxResult LegoWorldPresenter::LoadWorld(char* p_worldName, LegoWorld* p_world)
|
||||
}
|
||||
|
||||
strcat(wdbPath, "lego\\data\\world.wdb");
|
||||
MxString::NormalizePath(wdbPath);
|
||||
MxString::MapPathToFilesystem(wdbPath);
|
||||
|
||||
SDL_IOStream* wdbFile;
|
||||
|
||||
@ -184,7 +184,7 @@ MxResult LegoWorldPresenter::LoadWorld(char* p_worldName, LegoWorld* p_world)
|
||||
}
|
||||
|
||||
strcat(wdbPath, "lego\\data\\world.wdb");
|
||||
MxString::NormalizePath(wdbPath);
|
||||
MxString::MapPathToFilesystem(wdbPath);
|
||||
|
||||
if ((wdbFile = SDL_IOFromFile(wdbPath, "rb")) == NULL) {
|
||||
return FAILURE;
|
||||
|
||||
@ -121,7 +121,7 @@ LegoResult LegoFile::Open(const char* p_name, LegoU32 p_mode)
|
||||
}
|
||||
|
||||
MxString path(p_name);
|
||||
path.NormalizePath();
|
||||
path.MapPathToFilesystem();
|
||||
|
||||
if (!(m_file = SDL_IOFromFile(path.GetData(), mode))) {
|
||||
return FAILURE;
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
#include "lego1_export.h"
|
||||
#include "mxcore.h"
|
||||
#include "mxcriticalsection.h"
|
||||
#include "mxstl/stlcompat.h"
|
||||
#include "mxstring.h"
|
||||
|
||||
#include <SDL3/SDL_video.h>
|
||||
@ -42,7 +43,8 @@ class MxOmni : public MxCore {
|
||||
LEGO1_EXPORT static void SetCD(const char* p_cd);
|
||||
LEGO1_EXPORT static void SetHD(const char* p_hd);
|
||||
LEGO1_EXPORT static void SetSound3D(MxBool p_use3dSound);
|
||||
static void NormalizePath(char* p_path);
|
||||
static const vector<MxString>& GetHDFiles() { return g_hdFiles; }
|
||||
static const vector<MxString>& GetCDFiles() { return g_cdFiles; }
|
||||
|
||||
MxOmni();
|
||||
~MxOmni() override;
|
||||
@ -105,6 +107,10 @@ class MxOmni : public MxCore {
|
||||
|
||||
protected:
|
||||
static MxOmni* g_instance;
|
||||
static vector<MxString> g_hdFiles;
|
||||
static vector<MxString> g_cdFiles;
|
||||
|
||||
static vector<MxString> GlobIsleFiles(const MxString& p_path);
|
||||
|
||||
MxString m_mediaPath; // 0x08
|
||||
HWND m_windowHandle; // 0x18
|
||||
|
||||
@ -18,7 +18,7 @@ class MxString : public MxCore {
|
||||
void Reverse();
|
||||
void ToUpperCase();
|
||||
void ToLowerCase();
|
||||
void NormalizePath() { NormalizePath(m_data); }
|
||||
void MapPathToFilesystem() { MapPathToFilesystem(m_data); }
|
||||
|
||||
MxString& operator=(const MxString& p_str);
|
||||
const MxString& operator=(const char* p_str);
|
||||
@ -27,7 +27,7 @@ class MxString : public MxCore {
|
||||
MxString& operator+=(const char* p_str);
|
||||
|
||||
static void CharSwap(char* p_a, char* p_b);
|
||||
static void NormalizePath(char* p_path);
|
||||
static void MapPathToFilesystem(char* p_path);
|
||||
|
||||
// FUNCTION: BETA10 0x10017c50
|
||||
char* GetData() const { return m_data; }
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
#include "mxstring.h"
|
||||
|
||||
#include "decomp.h"
|
||||
#include "mxomni.h"
|
||||
|
||||
#include <SDL3/SDL_log.h>
|
||||
#include <SDL3/SDL_platform_defines.h>
|
||||
#include <SDL3/SDL_stdinc.h>
|
||||
#include <stdlib.h>
|
||||
@ -188,13 +190,11 @@ void MxString::CharSwap(char* p_a, char* p_b)
|
||||
*p_b = t;
|
||||
}
|
||||
|
||||
void MxString::NormalizePath(char* p_path)
|
||||
void MxString::MapPathToFilesystem(char* p_path)
|
||||
{
|
||||
// [library:filesystem]
|
||||
// This function is used to build a consistent path that will eventually be used to read a file.
|
||||
// The input may come with Windows path separators, i.e. \lego\scripts\infocntr\infomain
|
||||
// We have to replace the backslashes with forward slashes to be able to access the files
|
||||
// on non-Windows systems
|
||||
// This function is used to map an internal Windows-style path (found in SI files or in the code)
|
||||
// to an actual file on disk or CD. We have to account for both Windows path separators and case.
|
||||
#if !defined(SDL_PLATFORM_WINDOWS)
|
||||
char* path = p_path;
|
||||
while (*path) {
|
||||
@ -204,5 +204,30 @@ void MxString::NormalizePath(char* p_path)
|
||||
|
||||
path++;
|
||||
}
|
||||
|
||||
size_t pathLen = SDL_strlen(p_path);
|
||||
|
||||
auto mapPath = [p_path, pathLen](const vector<MxString>& p_files) -> bool {
|
||||
for (const MxString& file : p_files) {
|
||||
// Test whether file is a suffix of the provided path (case insensitive)
|
||||
// If yes, copy the original file system path into p_path.
|
||||
for (size_t i = pathLen, j = file.GetLength(); i != 0 && j != 0; i--, j--) {
|
||||
if (SDL_tolower(p_path[i - 1]) != SDL_tolower(file.GetData()[j - 1])) {
|
||||
break;
|
||||
}
|
||||
else if (j == 1) {
|
||||
SDL_strlcpy(&p_path[i - 1], file.GetData(), file.GetLength() + 1);
|
||||
SDL_Log("Resolved file path to %s", p_path);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
if (!mapPath(MxOmni::GetHDFiles())) {
|
||||
mapPath(MxOmni::GetCDFiles());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -17,6 +17,9 @@
|
||||
#include "mxvariabletable.h"
|
||||
#include "mxvideomanager.h"
|
||||
|
||||
#include <SDL3/SDL_filesystem.h>
|
||||
#include <SDL3/SDL_log.h>
|
||||
|
||||
// GLOBAL: LEGO1 0x101015b8
|
||||
MxString g_hdPath = "";
|
||||
|
||||
@ -29,6 +32,9 @@ MxBool g_use3dSound = FALSE;
|
||||
// GLOBAL: LEGO1 0x101015b0
|
||||
MxOmni* MxOmni::g_instance = NULL;
|
||||
|
||||
vector<MxString> MxOmni::g_hdFiles;
|
||||
vector<MxString> MxOmni::g_cdFiles;
|
||||
|
||||
// FUNCTION: LEGO1 0x100aef10
|
||||
MxOmni::MxOmni()
|
||||
{
|
||||
@ -357,6 +363,7 @@ const char* MxOmni::GetHD()
|
||||
void MxOmni::SetHD(const char* p_hd)
|
||||
{
|
||||
g_hdPath = p_hd;
|
||||
g_hdFiles = GlobIsleFiles(g_hdPath);
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100b0940
|
||||
@ -369,6 +376,7 @@ const char* MxOmni::GetCD()
|
||||
void MxOmni::SetCD(const char* p_cd)
|
||||
{
|
||||
g_cdPath = p_cd;
|
||||
g_cdFiles = GlobIsleFiles(g_cdPath);
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100b0980
|
||||
@ -415,3 +423,26 @@ void MxOmni::Resume()
|
||||
m_paused = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
vector<MxString> MxOmni::GlobIsleFiles(const MxString& p_path)
|
||||
{
|
||||
int count;
|
||||
char** files = SDL_GlobDirectory(p_path.GetData(), NULL, 0, &count);
|
||||
vector<MxString> result;
|
||||
|
||||
if (files == NULL) {
|
||||
SDL_Log("Error enumerating files for path %s (%s)", p_path.GetData(), SDL_GetError());
|
||||
return result;
|
||||
}
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (!SDL_strncasecmp(files[i], "lego", 4)) {
|
||||
result.emplace_back(files[i]);
|
||||
}
|
||||
}
|
||||
|
||||
SDL_Log("Found %d game files in %s", count, p_path.GetData());
|
||||
|
||||
SDL_free(files);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -41,7 +41,7 @@ MxU16 MXIOINFO::Open(const char* p_filename, MxULong p_flags)
|
||||
m_info.lDiskOffset = m_info.lBufOffset = 0;
|
||||
|
||||
MxString path(p_filename);
|
||||
path.NormalizePath();
|
||||
path.MapPathToFilesystem();
|
||||
ASSIGN_M_FILE(SDL_IOFromFile(path.GetData(), "rb"));
|
||||
|
||||
if (M_FILE != NULL) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user