Compare commits
3 Commits
main
...
olympus-su
Author | SHA1 | Date |
---|---|---|
Alexander Batalov | 8d4057366e | |
Alexander Batalov | 80b58bd174 | |
Alexander Batalov | ca268ecb2c |
31
src/dfile.cc
31
src/dfile.cc
|
@ -43,6 +43,8 @@ static int dfileReadCharInternal(DFile* stream);
|
|||
static bool dfileReadCompressed(DFile* stream, void* ptr, size_t size);
|
||||
static void dfileUngetCompressed(DFile* stream, int ch);
|
||||
|
||||
static void dfile_normalize_path(char* path);
|
||||
|
||||
// Reads .DAT file contents.
|
||||
//
|
||||
// 0x4E4F58
|
||||
|
@ -122,6 +124,9 @@ DBase* dbaseOpen(const char* filePath)
|
|||
|
||||
entry->path[pathLength] = '\0';
|
||||
|
||||
// CE: Normalize entry path.
|
||||
dfile_normalize_path(entry->path);
|
||||
|
||||
if (fread(&(entry->compressed), sizeof(entry->compressed), 1, stream) != 1) {
|
||||
break;
|
||||
}
|
||||
|
@ -201,11 +206,18 @@ bool dbaseClose(DBase* dbase)
|
|||
// 0x4E5308
|
||||
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++) {
|
||||
DBaseEntry* entry = &(dbase->entries[index]);
|
||||
if (fpattern_match(pattern, entry->path)) {
|
||||
if (fpattern_match(normalizedPattern, entry->path)) {
|
||||
strcpy(findFileData->fileName, entry->path);
|
||||
strcpy(findFileData->pattern, pattern);
|
||||
strcpy(findFileData->pattern, normalizedPattern);
|
||||
findFileData->index = index;
|
||||
return true;
|
||||
}
|
||||
|
@ -632,7 +644,14 @@ static int dbaseFindEntryByFilePath(const void* a1, const void* a2)
|
|||
// 0x4E5D9C
|
||||
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) {
|
||||
goto err;
|
||||
}
|
||||
|
@ -854,4 +873,10 @@ static void dfileUngetCompressed(DFile* stream, int ch)
|
|||
stream->position--;
|
||||
}
|
||||
|
||||
static void dfile_normalize_path(char* path)
|
||||
{
|
||||
compat_windows_path_to_native(path);
|
||||
compat_strlwr(path);
|
||||
}
|
||||
|
||||
} // namespace fallout
|
||||
|
|
|
@ -4663,8 +4663,31 @@ static void opGetPartyMember(Program* program)
|
|||
// 0x45C6DC
|
||||
static void opGetRotationToTile(Program* program)
|
||||
{
|
||||
int tile2 = programStackPopInteger(program);
|
||||
int tile1 = programStackPopInteger(program);
|
||||
// CE: There is a bug in Olympus (tgrdqest) - object is passed as one of the
|
||||
// arguments instead of tile. Original game (x86) does not distinguish
|
||||
// between integers and pointers, so one of the tiles is silently ignored
|
||||
// while calculating rotation. As a workaround this opcode now accepts
|
||||
// both integers and objects.
|
||||
ProgramValue value2 = programStackPopValue(program);
|
||||
ProgramValue value1 = programStackPopValue(program);
|
||||
|
||||
int tile2;
|
||||
if (value2.isInt()) {
|
||||
tile2 = value2.integerValue;
|
||||
} else if (value2.isPointer()) {
|
||||
tile2 = static_cast<Object*>(value2.pointerValue)->tile;
|
||||
} else {
|
||||
programFatalError("script error: %s: invalid arg 2 to rotation_to_tile", program->name);
|
||||
}
|
||||
|
||||
int tile1;
|
||||
if (value1.isInt()) {
|
||||
tile1 = value1.integerValue;
|
||||
} else if (value1.isPointer()) {
|
||||
tile1 = static_cast<Object*>(value1.pointerValue)->tile;
|
||||
} else {
|
||||
programFatalError("script error: %s: invalid arg 1 to rotation_to_tile", program->name);
|
||||
}
|
||||
|
||||
int rotation = tileGetRotationTo(tile1, tile2);
|
||||
programStackPushInteger(program, rotation);
|
||||
|
|
|
@ -46,17 +46,21 @@ bool sfall_gl_scr_init()
|
|||
*end = '\0';
|
||||
}
|
||||
|
||||
char drive[COMPAT_MAX_DRIVE];
|
||||
char dir[COMPAT_MAX_DIR];
|
||||
compat_splitpath(curr, drive, dir, nullptr, nullptr);
|
||||
char path[COMPAT_MAX_PATH];
|
||||
strcpy(path, curr);
|
||||
|
||||
char* fname = strrchr(path, '\\');
|
||||
if (fname != nullptr) {
|
||||
fname += 1;
|
||||
} else {
|
||||
fname = path;
|
||||
}
|
||||
|
||||
char** files;
|
||||
int filesLength = fileNameListInit(curr, &files, 0, 0);
|
||||
if (filesLength != 0) {
|
||||
for (int index = 0; index < filesLength; index++) {
|
||||
char path[COMPAT_MAX_PATH];
|
||||
compat_makepath(path, drive, dir, files[index], nullptr);
|
||||
|
||||
strcpy(fname, files[index]);
|
||||
state->paths.push_back(std::string { path });
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue