Fix global scripts on non-Windows platforms

This commit is contained in:
Alexander Batalov 2023-06-03 08:14:19 +03:00
parent cf5f865a23
commit ca268ecb2c
2 changed files with 38 additions and 9 deletions

View File

@ -43,6 +43,8 @@ static int dfileReadCharInternal(DFile* stream);
static bool dfileReadCompressed(DFile* stream, void* ptr, size_t size); static bool dfileReadCompressed(DFile* stream, void* ptr, size_t size);
static void dfileUngetCompressed(DFile* stream, int ch); static void dfileUngetCompressed(DFile* stream, int ch);
static void dfile_normalize_path(char* path);
// Reads .DAT file contents. // Reads .DAT file contents.
// //
// 0x4E4F58 // 0x4E4F58
@ -122,6 +124,9 @@ DBase* dbaseOpen(const char* filePath)
entry->path[pathLength] = '\0'; entry->path[pathLength] = '\0';
// CE: Normalize entry path.
dfile_normalize_path(entry->path);
if (fread(&(entry->compressed), sizeof(entry->compressed), 1, stream) != 1) { if (fread(&(entry->compressed), sizeof(entry->compressed), 1, stream) != 1) {
break; break;
} }
@ -201,11 +206,18 @@ bool dbaseClose(DBase* dbase)
// 0x4E5308 // 0x4E5308
bool dbaseFindFirstEntry(DBase* dbase, DFileFindData* findFileData, const char* pattern) bool dbaseFindFirstEntry(DBase* dbase, DFileFindData* findFileData, const char* pattern)
{ {
// CE: Normalize pattern to match entries. Underlying `fpattern`
// implementation is case-sensitive on non-Windows platforms, so both
// pattern and entries should match in case and have native path separators.
char normalizedPattern[COMPAT_MAX_PATH];
strcpy(normalizedPattern, pattern);
dfile_normalize_path(normalizedPattern);
for (int index = 0; index < dbase->entriesLength; index++) { for (int index = 0; index < dbase->entriesLength; index++) {
DBaseEntry* entry = &(dbase->entries[index]); DBaseEntry* entry = &(dbase->entries[index]);
if (fpattern_match(pattern, entry->path)) { if (fpattern_match(normalizedPattern, entry->path)) {
strcpy(findFileData->fileName, entry->path); strcpy(findFileData->fileName, entry->path);
strcpy(findFileData->pattern, pattern); strcpy(findFileData->pattern, normalizedPattern);
findFileData->index = index; findFileData->index = index;
return true; return true;
} }
@ -632,7 +644,14 @@ static int dbaseFindEntryByFilePath(const void* a1, const void* a2)
// 0x4E5D9C // 0x4E5D9C
static DFile* dfileOpenInternal(DBase* dbase, const char* filePath, const char* mode, DFile* dfile) static DFile* dfileOpenInternal(DBase* dbase, const char* filePath, const char* mode, DFile* dfile)
{ {
DBaseEntry* entry = (DBaseEntry*)bsearch(filePath, dbase->entries, dbase->entriesLength, sizeof(*dbase->entries), dbaseFindEntryByFilePath); // CE: Normalize path to match entries. Even though
// `dbaseFindEntryByFilePath` uses case-insensitive compare, it still needs
// native path separators.
char normalizedFilePath[COMPAT_MAX_PATH];
strcpy(normalizedFilePath, filePath);
dfile_normalize_path(normalizedFilePath);
DBaseEntry* entry = (DBaseEntry*)bsearch(normalizedFilePath, dbase->entries, dbase->entriesLength, sizeof(*dbase->entries), dbaseFindEntryByFilePath);
if (entry == NULL) { if (entry == NULL) {
goto err; goto err;
} }
@ -854,4 +873,10 @@ static void dfileUngetCompressed(DFile* stream, int ch)
stream->position--; stream->position--;
} }
static void dfile_normalize_path(char* path)
{
compat_windows_path_to_native(path);
compat_strlwr(path);
}
} // namespace fallout } // namespace fallout

View File

@ -46,17 +46,21 @@ bool sfall_gl_scr_init()
*end = '\0'; *end = '\0';
} }
char drive[COMPAT_MAX_DRIVE]; char path[COMPAT_MAX_PATH];
char dir[COMPAT_MAX_DIR]; strcpy(path, curr);
compat_splitpath(curr, drive, dir, nullptr, nullptr);
char *fname = strrchr(path, '\\');
if (fname != nullptr) {
fname += 1;
} else {
fname = path;
}
char** files; char** files;
int filesLength = fileNameListInit(curr, &files, 0, 0); int filesLength = fileNameListInit(curr, &files, 0, 0);
if (filesLength != 0) { if (filesLength != 0) {
for (int index = 0; index < filesLength; index++) { for (int index = 0; index < filesLength; index++) {
char path[COMPAT_MAX_PATH]; strcpy(fname, files[index]);
compat_makepath(path, drive, dir, files[index], nullptr);
state->paths.push_back(std::string { path }); state->paths.push_back(std::string { path });
} }