mirror of
https://github.com/fallout2-ce/fallout2-ce.git
synced 2026-07-27 16:47:11 -07:00
Fix global script loading on non-Windows (#347)
* Fix global script loading on non-Windows Previously, global scripts in .dats and in local FS didn't work due to path separator confusion. Now: * Hardcode global script path to "scripts\gl*.int" (windows separator) * Use Windows fpattern matching inside of dFile (.dats, which always use windows separators) * Use \-paths when listing found global scripts The awkward part is having to vendor a copy of fpattern to force it to use "windows mode". It's possible that we could use this everywhere since windows allows / as separator, but that could cause bugs where we're using fpattern on the native FS. For now keeping the dFile implementation separate makes sense.
This commit is contained in:
@@ -434,6 +434,7 @@ endif()
|
||||
|
||||
add_subdirectory("third_party/fpattern")
|
||||
target_link_libraries(${EXECUTABLE_NAME} fpattern::fpattern)
|
||||
target_link_libraries(${EXECUTABLE_NAME} fpattern_windows::fpattern_windows)
|
||||
|
||||
target_link_libraries(${EXECUTABLE_NAME} ${ZLIB_LIBRARIES})
|
||||
target_include_directories(${EXECUTABLE_NAME} PRIVATE ${ZLIB_INCLUDE_DIRS})
|
||||
|
||||
@@ -197,11 +197,6 @@ NumbersInDialogue=0
|
||||
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
[Scripts]
|
||||
|
||||
;Comma-separated list of masked paths to load global scripts from
|
||||
;Only use single backslash \ as the directory separator
|
||||
;Paths outside of scripts folder are supported
|
||||
;GlobalScriptPaths=scripts\gl_*.int,scripts\sfall\gl*.int
|
||||
|
||||
;Uncomment the option to specify an additional directory for ini files used by scripts
|
||||
;The game will search for ini files first relative to this directory and then relative to the root directory if not found
|
||||
;The path length is limited to 61 characters
|
||||
|
||||
+2
-14
@@ -30,22 +30,10 @@ compile.exe -q -p -l -O2 -d -s -n -I<sfall_headers_id> <script_name.ssl>
|
||||
|
||||
- Install [VSCode Extension](https://marketplace.visualstudio.com/items?itemName=BGforge.bgforge-mls)
|
||||
|
||||
|
||||
|
||||
## Run test script
|
||||
|
||||
1. Move compiled `.int` file into game folder as `data/scripts/gl_<script_name>.int`
|
||||
1. Move compiled `.int` file into game folder as `scripts/gl_<script_name>.int`
|
||||
|
||||
2. Change `ddraw.ini` and add this section:
|
||||
```ini
|
||||
[Scripts]
|
||||
GlobalScriptPaths=data/scripts/gl*.int
|
||||
```
|
||||
|
||||
(or add new path using comma as separator)
|
||||
|
||||
Note that on non-Windows it have to be `/` as folder separator
|
||||
|
||||
3. Run game, check that game displays message about tests
|
||||
2. Run game, check that game displays message about tests
|
||||
|
||||
|
||||
|
||||
+4
-3
@@ -7,7 +7,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <fpattern/fpattern.h>
|
||||
#include "fpattern_windows.h"
|
||||
|
||||
#include "platform_compat.h"
|
||||
|
||||
@@ -201,9 +201,10 @@ bool dbaseClose(DBase* dbase)
|
||||
// 0x4E5308
|
||||
bool dbaseFindFirstEntry(DBase* dbase, DFileFindData* findFileData, const char* pattern)
|
||||
{
|
||||
// .dat files always have windows style paths
|
||||
for (int index = 0; index < dbase->entriesLength; index++) {
|
||||
DBaseEntry* entry = &(dbase->entries[index]);
|
||||
if (fpattern_match(pattern, entry->path)) {
|
||||
if (fpattern_windows_match(pattern, entry->path)) {
|
||||
strcpy(findFileData->fileName, entry->path);
|
||||
strcpy(findFileData->pattern, pattern);
|
||||
findFileData->index = index;
|
||||
@@ -219,7 +220,7 @@ bool dbaseFindNextEntry(DBase* dbase, DFileFindData* findFileData)
|
||||
{
|
||||
for (int index = findFileData->index + 1; index < dbase->entriesLength; index++) {
|
||||
DBaseEntry* entry = &(dbase->entries[index]);
|
||||
if (fpattern_match(findFileData->pattern, entry->path)) {
|
||||
if (fpattern_windows_match(findFileData->pattern, entry->path)) {
|
||||
strcpy(findFileData->fileName, entry->path);
|
||||
findFileData->index = index;
|
||||
return true;
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
#ifndef FALLOUT_FPATTERN_WINDOWS_H_
|
||||
#define FALLOUT_FPATTERN_WINDOWS_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int fpattern_windows_isvalid(const char* pat);
|
||||
int fpattern_windows_match(const char* pat, const char* fname);
|
||||
int fpattern_windows_matchn(const char* pat, const char* fname);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -62,8 +62,6 @@ bool sfallConfigInit(int argc, char** argv)
|
||||
configSetBool(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_CITIES_LIMIT_FIX, true);
|
||||
|
||||
configSetString(&gSfallConfig, SFALL_CONFIG_SCRIPTS_KEY, SFALL_CONFIG_INI_CONFIG_FOLDER, "");
|
||||
configSetString(&gSfallConfig, SFALL_CONFIG_SCRIPTS_KEY, SFALL_CONFIG_GLOBAL_SCRIPT_PATHS, "");
|
||||
|
||||
configSetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_PIPBOY_AVAILABLE_AT_GAMESTART, 0);
|
||||
configSetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_USE_WALK_DISTANCE, 5);
|
||||
configSetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_AUTO_OPEN_DOORS, 0);
|
||||
|
||||
@@ -71,7 +71,6 @@ namespace fallout {
|
||||
#define SFALL_CONFIG_EXTRA_MESSAGE_LISTS_KEY "ExtraGameMsgFileList"
|
||||
#define SFALL_CONFIG_NUMBERS_IS_DIALOG_KEY "NumbersInDialogue"
|
||||
#define SFALL_CONFIG_INI_CONFIG_FOLDER "IniConfigFolder"
|
||||
#define SFALL_CONFIG_GLOBAL_SCRIPT_PATHS "GlobalScriptPaths"
|
||||
#define SFALL_CONFIG_AUTO_QUICK_SAVE "AutoQuickSave"
|
||||
#define SFALL_CONFIG_VERSION_STRING "VersionString"
|
||||
#define SFALL_CONFIG_CONFIG_FILE "ConfigFile"
|
||||
|
||||
@@ -37,41 +37,21 @@ bool sfall_gl_scr_init()
|
||||
return false;
|
||||
}
|
||||
|
||||
char* paths;
|
||||
configGetString(&gSfallConfig, SFALL_CONFIG_SCRIPTS_KEY, SFALL_CONFIG_GLOBAL_SCRIPT_PATHS, &paths);
|
||||
|
||||
char* curr = paths;
|
||||
while (curr != nullptr && *curr != '\0') {
|
||||
char* end = strchr(curr, ',');
|
||||
if (end != nullptr) {
|
||||
*end = '\0';
|
||||
}
|
||||
|
||||
char drive[COMPAT_MAX_DRIVE];
|
||||
char dir[COMPAT_MAX_DIR];
|
||||
compat_splitpath(curr, drive, dir, nullptr, nullptr);
|
||||
|
||||
// CE: always use "scripts\gl*.int" as global script path
|
||||
const char* scriptPath = "scripts\\gl*.int";
|
||||
const char* dir = "scripts";
|
||||
char** files;
|
||||
int filesLength = fileNameListInit(curr, &files);
|
||||
int filesLength = fileNameListInit(scriptPath, &files);
|
||||
if (filesLength != 0) {
|
||||
for (int index = 0; index < filesLength; index++) {
|
||||
char path[COMPAT_MAX_PATH];
|
||||
compat_makepath(path, drive, dir, files[index], nullptr);
|
||||
|
||||
snprintf(path, sizeof(path), "%s\\%s", dir, files[index]);
|
||||
state->paths.push_back(std::string { path });
|
||||
}
|
||||
|
||||
fileNameListFree(&files, 0);
|
||||
}
|
||||
|
||||
if (end != nullptr) {
|
||||
*end = ',';
|
||||
curr = end + 1;
|
||||
} else {
|
||||
curr = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
std::sort(state->paths.begin(), state->paths.end());
|
||||
|
||||
return true;
|
||||
|
||||
Vendored
+30
-8
@@ -1,11 +1,33 @@
|
||||
include(FetchContent)
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
FetchContent_Declare(fpattern
|
||||
GIT_REPOSITORY "https://github.com/alexbatalov/fpattern"
|
||||
GIT_TAG 8523173ec252c3b796fcdfca0fcc6329642fbbe3 # v1.9
|
||||
GIT_SHALLOW TRUE
|
||||
GIT_PROGRESS TRUE
|
||||
EXCLUDE_FROM_ALL
|
||||
project(fpattern
|
||||
LANGUAGES C
|
||||
VERSION "1.0.0"
|
||||
)
|
||||
|
||||
FetchContent_MakeAvailable(fpattern)
|
||||
add_library(fpattern-static src/fpattern.c)
|
||||
add_library(fpattern::fpattern ALIAS fpattern-static)
|
||||
|
||||
if(NOT WIN32)
|
||||
target_compile_definitions(fpattern-static PRIVATE
|
||||
unix=1
|
||||
)
|
||||
endif()
|
||||
|
||||
target_include_directories(fpattern-static PUBLIC
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include"
|
||||
)
|
||||
|
||||
add_library(fpattern-windows-static src/fpattern.c)
|
||||
add_library(fpattern_windows::fpattern_windows ALIAS fpattern-windows-static)
|
||||
|
||||
target_compile_definitions(fpattern-windows-static PRIVATE
|
||||
FPAT_WINDOWS_PATHS
|
||||
fpattern_isvalid=fpattern_windows_isvalid
|
||||
fpattern_match=fpattern_windows_match
|
||||
fpattern_matchn=fpattern_windows_matchn
|
||||
)
|
||||
|
||||
target_include_directories(fpattern-windows-static PUBLIC
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include"
|
||||
)
|
||||
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
/******************************************************************************
|
||||
* debug.h
|
||||
*
|
||||
* Copyright ©1997-2015 by David R. Tribble, all rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef drt_debug_h
|
||||
#define drt_debug_h 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
/* Identification */
|
||||
|
||||
#ifndef NO_H_IDENT
|
||||
static const char drt_debug_h_id[] =
|
||||
"@(#)drt/src/lib/debug.h $Revision: 1.4 $ $Date: 2001/11/12 06:00:00 $";
|
||||
#endif
|
||||
|
||||
|
||||
/*==============================================================================
|
||||
* Debug macros
|
||||
*/
|
||||
|
||||
#ifndef DEBUG
|
||||
#define DEBUG 0
|
||||
#endif
|
||||
|
||||
#if DEBUG-0 <= 0
|
||||
#undef DEBUG
|
||||
#define DEBUG 0
|
||||
#endif
|
||||
|
||||
#if DEBUG
|
||||
#define DL(e) (opt_debug ? (void)(e) : (void)0)
|
||||
#else
|
||||
#define DL(e) ((void)0)
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* drt_debug_h */
|
||||
|
||||
/* End debug.h */
|
||||
+217
@@ -0,0 +1,217 @@
|
||||
/******************************************************************************
|
||||
* fpattern.h
|
||||
* Functions for matching filename patterns to filenames.
|
||||
*
|
||||
* Usage
|
||||
* Filename patterns are composed of regular (printable) characters which
|
||||
* may comprise a filename, as well as special pattern matching characters:
|
||||
*
|
||||
* . Matches a period (.).
|
||||
* Note that a period in a filename is not treated any
|
||||
* differently than any other character.
|
||||
*
|
||||
* ? Any.
|
||||
* Matches any single character except '/' or '\'.
|
||||
*
|
||||
* * Closure.
|
||||
* Matches zero or more occurences of any characters other
|
||||
* than '/' or '\'. Leading '*' characters are allowed.
|
||||
*
|
||||
* SUB Substitute (control-Z).
|
||||
* Similar to '*', this matches zero or more occurences of
|
||||
* any characters other than '/', '\', or '.'. Leading
|
||||
* '^Z' characters are allowed.
|
||||
*
|
||||
* [ab] Set.
|
||||
* Matches the single character 'a' or 'b'.
|
||||
* If the dash '-' character is to be included, it must
|
||||
* immediately follow the opening bracket '['. If the
|
||||
* closing bracket ']' character is to be included, it must
|
||||
* be preceded by a quote '`'.
|
||||
*
|
||||
* [a-z] Range.
|
||||
* Matches a single character in the range 'a' to 'z'.
|
||||
* Ranges and sets may be combined within the same set of
|
||||
* brackets.
|
||||
*
|
||||
* [!R] Exclusive range.
|
||||
* Matches a single character not in the range 'R'.
|
||||
* If range 'R' includes the dash '-' character, the dash
|
||||
* must immediately follow the caret '!'.
|
||||
*
|
||||
* ! Not.
|
||||
* Makes the following pattern (up to the next '/') match
|
||||
* any filename except those what it would normally match.
|
||||
*
|
||||
* / Path separator (UNIX and DOS).
|
||||
* Matches a '/' or '\' pathname (directory) separator.
|
||||
* Multiple separators are treated like a single separator.
|
||||
* A leading separator indicates an absolute pathname.
|
||||
*
|
||||
* \ Path separator (DOS).
|
||||
* Same as the '/' character. Note that this character
|
||||
* must be escaped if used within string constants ("\\").
|
||||
*
|
||||
* \ Quote (UNIX).
|
||||
* Makes the next character a regular (nonspecial)
|
||||
* character. Note that to match the quote character
|
||||
* itself, it must be quoted. Note that this character
|
||||
* must be escaped if used within string constants ("\\").
|
||||
*
|
||||
* ` Quote (DOS).
|
||||
* Makes the next character a regular (nonspecial)
|
||||
* character. Note that to match the quote character
|
||||
* itself, it must be quoted.
|
||||
*
|
||||
* Upper and lower case alphabetic characters are considered identical,
|
||||
* i.e., 'a' and 'A' match each other. (What constitutes a lowercase
|
||||
* letter depends on the current locale settings.)
|
||||
*
|
||||
* Spaces and control characters are treated as normal characters.
|
||||
*
|
||||
* Examples
|
||||
* The following patterns in the left column will match the filenames in
|
||||
* the middle column and will not match filenames in the right column:
|
||||
*
|
||||
* Pattern Will Match Will Not Match
|
||||
* ------- ---------- --------------
|
||||
* a a (only) (anything else)
|
||||
* a. a. (only) (anything else)
|
||||
* a?c abc, acc, arc, a.c a, ac, abbc
|
||||
* a*c ac, abc, abbc, acc, a.c a, ab, acb, bac
|
||||
* a* a, ab, abb, a., a.b b, ba
|
||||
* * a, ab, abb, a., .foo, a.foo (nothing)
|
||||
* *. a., ab., abb., a.foo. a, ab, a.foo, .foo
|
||||
* *.* a., a.b, ah.bc.foo a
|
||||
* ^Z a, ab, abb a., .foo, a.foo
|
||||
* ^Z. a., ab., abb. a, .foo, a.foo
|
||||
* ^Z.* a, a., .foo, a.foo ab, abb
|
||||
* *2.c 2.c, 12.c, foo2.c, foo.12.c 2x.c
|
||||
* a[b-z]c abc, acc, azc (only) (anything else)
|
||||
* [ab0-9]x ax, bx, 0x, 9x zx
|
||||
* a[-.]b a-b, a.b (only) (anything else)
|
||||
* a[!a-z]b a0b, a.b, a@b aab, azb, aa0b
|
||||
* a[!-b]x a0x, a+x, acx a-x, abx, axxx
|
||||
* a[-!b]x a-x, a!x, abx (only) (anything else)
|
||||
* a[`]]x a]x (only) (anything else)
|
||||
* a``x a`x (only) (anything else)
|
||||
* oh`! oh! (only) (anything else)
|
||||
* is`?it is?it (only) (anything else)
|
||||
* !a?c a, ac, ab, abb, acb, a.foo abc, a.c, azc
|
||||
*
|
||||
* History
|
||||
* 1.0, 1997-01-03, David Tribble.
|
||||
* First cut.
|
||||
*
|
||||
* 1.1, 1997-01-03, David Tribble.
|
||||
* Added '^Z' pattern character.
|
||||
* Added fpattern_matchn().
|
||||
*
|
||||
* 1.2, 1997-01-26, David Tribble.
|
||||
* Changed range negation character from '^' to '!', ala Unix.
|
||||
*
|
||||
* 1.3, 1997-08-02, David Tribble.
|
||||
* Added 'FPAT_XXX' macro constants.
|
||||
*
|
||||
* 1.4, 2001-11-21, David Tribble.
|
||||
* Revised slightly for Win32 compilations.
|
||||
*
|
||||
* Limitations
|
||||
* This code is copyrighted by the author, but permission is hereby granted
|
||||
* for its unlimited use provided that the original copyright and
|
||||
* authorship notices are retained intact.
|
||||
*
|
||||
* Queries about this source code can be sent to <david@tribble.com>.
|
||||
*
|
||||
* Copyright ©1997-2001 by David R. Tribble, all rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef drt_fpattern_h
|
||||
#define drt_fpattern_h 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
/* Identification */
|
||||
|
||||
#ifndef NO_H_IDENT
|
||||
static const char drt_fpattern_h_id[] =
|
||||
"@(#)drt/src/lib/fpattern.h $Revision: 1.4 $ $Date: 2001/11/12 06:00:00 $";
|
||||
#endif
|
||||
|
||||
|
||||
/* Manifest constants */
|
||||
|
||||
#define FPAT_QUOTE '\\' /* Quotes a special char */
|
||||
#define FPAT_QUOTE2 '`' /* Quotes a special char */
|
||||
#define FPAT_DEL '/' /* Path delimiter */
|
||||
#define FPAT_DEL2 '\\' /* Path delimiter */
|
||||
#define FPAT_DOT '.' /* Dot char */
|
||||
#define FPAT_NOT '!' /* Exclusion */
|
||||
#define FPAT_ANY '?' /* Any one char */
|
||||
#define FPAT_CLOS '*' /* Zero or more chars */
|
||||
#define FPAT_CLOSP '\x1A' /* Zero or more nondelimiters */
|
||||
#define FPAT_SET_L '[' /* Set/range open bracket */
|
||||
#define FPAT_SET_R ']' /* Set/range close bracket */
|
||||
#define FPAT_SET_NOT '!' /* Set exclusion */
|
||||
#define FPAT_SET_THRU '-' /* Set range of chars */
|
||||
|
||||
|
||||
/* Model-dependent extern aliases */
|
||||
|
||||
#ifdef __MSDOS__
|
||||
|
||||
#if defined(__SMALL__)
|
||||
#define fpattern_isvalid Sfpattern_isvalid
|
||||
#define fpattern_match Sfpattern_match
|
||||
#define fpattern_matchn Sfpattern_matchn
|
||||
#elif defined(__LARGE__)
|
||||
#define fpattern_isvalid Lfpattern_isvalid
|
||||
#define fpattern_match Lfpattern_match
|
||||
#define fpattern_matchn Lfpattern_matchn
|
||||
#elif defined(__COMPACT__)
|
||||
#define fpattern_isvalid Cfpattern_isvalid
|
||||
#define fpattern_match Cfpattern_match
|
||||
#define fpattern_matchn Cfpattern_matchn
|
||||
#elif defined(__MEDIUM__)
|
||||
#define fpattern_isvalid Mfpattern_isvalid
|
||||
#define fpattern_match Mfpattern_match
|
||||
#define fpattern_matchn Mfpattern_matchn
|
||||
#elif defined(__HUGE__)
|
||||
#define fpattern_isvalid Hfpattern_isvalid
|
||||
#define fpattern_match Hfpattern_match
|
||||
#define fpattern_matchn Hfpattern_matchn
|
||||
#elif defined(__TINY__)
|
||||
#define fpattern_isvalid Tfpattern_isvalid
|
||||
#define fpattern_match Tfpattern_match
|
||||
#define fpattern_matchn Tfpattern_matchn
|
||||
#else
|
||||
/* Memory model is not defined, use extern names as is. */
|
||||
#endif
|
||||
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
|
||||
/* Public variables */
|
||||
|
||||
/* (None) */
|
||||
|
||||
|
||||
/* Public functions */
|
||||
|
||||
extern int fpattern_isvalid(const char *pat);
|
||||
extern int fpattern_match(const char *pat, const char *fname);
|
||||
extern int fpattern_matchn(const char *pat, const char *fname);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* drt_fpattern_h */
|
||||
|
||||
/* End fpattern.h */
|
||||
Vendored
+824
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user