1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2025-12-10 09:32:29 +01:00

Let user specify the data dir as cmdline option.

This adds --openrct-data-dir=<str> option to command line letting user
select where he wants OpenRCT2-specific data to be. By default the
search locations are:
* <exePath>/data (on all platforms)
* /var/lib/openrct2 (on Linux)
* /usr/share/openrct2 (on Linux)
This commit is contained in:
Michał Janiszewski
2015-12-17 22:49:39 +01:00
parent 859c35574a
commit ea6fa2c82a
10 changed files with 125 additions and 10 deletions

View File

@@ -76,6 +76,7 @@ int cmdline_run(const char **argv, int argc)
int version = 0, headless = 0, verbose = 0, width = 0, height = 0, port = 0; int version = 0, headless = 0, verbose = 0, width = 0, height = 0, port = 0;
char *server = NULL; char *server = NULL;
char *userDataPath = NULL; char *userDataPath = NULL;
char *openrctDataPath = NULL;
argparse_option_t options[] = { argparse_option_t options[] = {
OPT_HELP(), OPT_HELP(),
@@ -84,8 +85,9 @@ int cmdline_run(const char **argv, int argc)
OPT_BOOLEAN(0, "verbose", &verbose, "log verbose messages"), OPT_BOOLEAN(0, "verbose", &verbose, "log verbose messages"),
OPT_INTEGER('m', "mode", &sprite_mode, "the type of sprite conversion. 0 = default, 1 = simple closest pixel match, 2 = dithering"), OPT_INTEGER('m', "mode", &sprite_mode, "the type of sprite conversion. 0 = default, 1 = simple closest pixel match, 2 = dithering"),
OPT_STRING(0, "server", &server, "server to connect to"), OPT_STRING(0, "server", &server, "server to connect to"),
OPT_INTEGER(0, "port", &port, "port"), OPT_INTEGER(0, "port", &port, "Port to use. If used with --server, it will connect to specified server at this port, otherwise it will start the server"),
OPT_STRING(0, "user-data-path", &userDataPath, "path to the user data directory (containing config.ini)"), OPT_STRING(0, "user-data-path", &userDataPath, "path to the user data directory (containing config.ini)"),
OPT_STRING(0, "openrct-data-path", &openrctDataPath, "path to the OpenRCT2 data directory (containing languages)"),
OPT_END() OPT_END()
}; };
@@ -117,6 +119,10 @@ int cmdline_run(const char **argv, int argc)
safe_strncpy(gCustomUserDataPath, userDataPath, sizeof(gCustomUserDataPath)); safe_strncpy(gCustomUserDataPath, userDataPath, sizeof(gCustomUserDataPath));
} }
if (openrctDataPath != NULL) {
safe_strncpy(gCustomOpenrctDataPath, openrctDataPath, sizeof(gCustomOpenrctDataPath));
}
#ifndef DISABLE_NETWORK #ifndef DISABLE_NETWORK
if (port != 0) { if (port != 0) {
gNetworkStart = NETWORK_MODE_SERVER; gNetworkStart = NETWORK_MODE_SERVER;

View File

@@ -1359,6 +1359,7 @@ static void title_sequence_open(const char *path, const char *customName);
void title_sequences_set_default() void title_sequences_set_default()
{ {
char path[MAX_PATH]; char path[MAX_PATH];
char dataPath[MAX_PATH];
char sep = platform_get_path_separator(); char sep = platform_get_path_separator();
platform_get_user_directory(path, "title sequences"); platform_get_user_directory(path, "title sequences");
@@ -1367,12 +1368,14 @@ void title_sequences_set_default()
gConfigTitleSequences.presets = malloc(0); gConfigTitleSequences.presets = malloc(0);
gConfigTitleSequences.num_presets = 0; gConfigTitleSequences.num_presets = 0;
platform_get_openrct_data_path(dataPath);
// Load OpenRCT2 title sequence // Load OpenRCT2 title sequence
sprintf(path, "%s%c%s%c%s%c%s%c", gExePath, sep, "data", sep, "title", sep, "rct2", sep); sprintf(path, "%s%c%s%c%s%c", dataPath, sep, "title", sep, "rct2", sep);
title_sequence_open(path, language_get_string(5308)); title_sequence_open(path, language_get_string(5308));
// Load OpenRCT2 title sequence // Load OpenRCT2 title sequence
sprintf(path, "%s%c%s%c%s%c%s%c", gExePath, sep, "data", sep, "title", sep, "openrct2", sep); sprintf(path, "%s%c%s%c%s%c", dataPath, sep, "title", sep, "openrct2", sep);
title_sequence_open(path, language_get_string(5309)); title_sequence_open(path, language_get_string(5309));
} }

View File

@@ -82,7 +82,10 @@ int gfx_load_g2()
unsigned int i; unsigned int i;
char path[MAX_PATH]; char path[MAX_PATH];
sprintf(path, "%s%cdata%cg2.dat", gExePath, platform_get_path_separator(), platform_get_path_separator()); char dataPath[MAX_PATH];
platform_get_openrct_data_path(dataPath);
sprintf(path, "%s%cg2.dat", dataPath, platform_get_path_separator());
file = SDL_RWFromFile(path, "rb"); file = SDL_RWFromFile(path, "rb");
if (file != NULL) { if (file != NULL) {
if (SDL_RWread(file, &g2.header, 8, 1) == 1) { if (SDL_RWread(file, &g2.header, 8, 1) == 1) {

View File

@@ -146,19 +146,21 @@ const char *language_get_string(rct_string_id id)
int language_open(int id) int language_open(int id)
{ {
static const char *languagePath = "%s/data/language/%s.txt"; static const char *languagePath = "%s/language/%s.txt";
char filename[MAX_PATH]; char filename[MAX_PATH];
char dataPath[MAX_PATH];
language_close_all(); language_close_all();
if (id == LANGUAGE_UNDEFINED) if (id == LANGUAGE_UNDEFINED)
return 1; return 1;
platform_get_openrct_data_path(dataPath);
if (id != LANGUAGE_ENGLISH_UK) { if (id != LANGUAGE_ENGLISH_UK) {
sprintf(filename, languagePath, gExePath, LanguagesDescriptors[LANGUAGE_ENGLISH_UK].path); sprintf(filename, languagePath, dataPath, LanguagesDescriptors[LANGUAGE_ENGLISH_UK].path);
_languageFallback = LanguagePack::FromFile(LANGUAGE_ENGLISH_UK, filename); _languageFallback = LanguagePack::FromFile(LANGUAGE_ENGLISH_UK, filename);
} }
sprintf(filename, languagePath, gExePath, LanguagesDescriptors[id].path); sprintf(filename, languagePath, dataPath, LanguagesDescriptors[id].path);
_languageCurrent = LanguagePack::FromFile(id, filename); _languageCurrent = LanguagePack::FromFile(id, filename);
if (_languageCurrent != nullptr) { if (_languageCurrent != nullptr) {
gCurrentLanguage = id; gCurrentLanguage = id;

View File

@@ -53,6 +53,7 @@ int gOpenRCT2StartupAction = STARTUP_ACTION_TITLE;
utf8 gOpenRCT2StartupActionPath[512] = { 0 }; utf8 gOpenRCT2StartupActionPath[512] = { 0 };
utf8 gExePath[MAX_PATH]; utf8 gExePath[MAX_PATH];
utf8 gCustomUserDataPath[MAX_PATH] = { 0 }; utf8 gCustomUserDataPath[MAX_PATH] = { 0 };
utf8 gCustomOpenrctDataPath[MAX_PATH] = { 0 };
// This should probably be changed later and allow a custom selection of things to initialise like SDL_INIT // This should probably be changed later and allow a custom selection of things to initialise like SDL_INIT
bool gOpenRCT2Headless = false; bool gOpenRCT2Headless = false;
@@ -148,7 +149,6 @@ static void openrct2_copy_files_over(const utf8 *originalDirectory, const utf8 *
platform_enumerate_directories_end(fileEnumHandle); platform_enumerate_directories_end(fileEnumHandle);
} }
// TODO move to platform
static void openrct2_set_exe_path() static void openrct2_set_exe_path()
{ {
platform_get_exe_path(gExePath); platform_get_exe_path(gExePath);
@@ -173,6 +173,7 @@ bool openrct2_initialise()
{ {
utf8 userPath[MAX_PATH]; utf8 userPath[MAX_PATH];
platform_resolve_openrct_data_path();
platform_resolve_user_data_path(); platform_resolve_user_data_path();
platform_get_user_directory(userPath, NULL); platform_get_user_directory(userPath, NULL);
if (!platform_ensure_directory_exists(userPath)) { if (!platform_ensure_directory_exists(userPath)) {

View File

@@ -34,6 +34,7 @@ extern int gOpenRCT2StartupAction;
extern utf8 gOpenRCT2StartupActionPath[512]; extern utf8 gOpenRCT2StartupActionPath[512];
extern utf8 gExePath[MAX_PATH]; extern utf8 gExePath[MAX_PATH];
extern utf8 gCustomUserDataPath[MAX_PATH]; extern utf8 gCustomUserDataPath[MAX_PATH];
extern utf8 gCustomOpenrctDataPath[MAX_PATH];
extern bool gOpenRCT2Headless; extern bool gOpenRCT2Headless;
extern bool gOpenRCT2ShowChangelog; extern bool gOpenRCT2ShowChangelog;

View File

@@ -147,6 +147,8 @@ void platform_get_cursor_position(int *x, int *y);
void platform_set_cursor_position(int x, int y); void platform_set_cursor_position(int x, int y);
unsigned int platform_get_ticks(); unsigned int platform_get_ticks();
void platform_resolve_user_data_path(); void platform_resolve_user_data_path();
void platform_resolve_openrct_data_path();
void platform_get_openrct_data_path(utf8 *outPath);
void platform_get_user_directory(utf8 *outPath, const utf8 *subDirectory); void platform_get_user_directory(utf8 *outPath, const utf8 *subDirectory);
void platform_show_messagebox(utf8 *message); void platform_show_messagebox(utf8 *message);
int platform_open_common_file_dialog(int type, utf8 *title, utf8 *filename, utf8 *filterPattern, utf8 *filterName); int platform_open_common_file_dialog(int type, utf8 *title, utf8 *filename, utf8 *filterPattern, utf8 *filterName);

View File

@@ -42,6 +42,7 @@
#define SINGLE_INSTANCE_MUTEX_NAME "RollerCoaster Tycoon 2_GSKMUTEX" #define SINGLE_INSTANCE_MUTEX_NAME "RollerCoaster Tycoon 2_GSKMUTEX"
utf8 _userDataDirectoryPath[MAX_PATH] = { 0 }; utf8 _userDataDirectoryPath[MAX_PATH] = { 0 };
utf8 _openrctDataDirectoryPath[MAX_PATH] = { 0 };
/** /**
* The function that is called directly from the host application (rct2.exe)'s WinMain. This will be removed when OpenRCT2 can * The function that is called directly from the host application (rct2.exe)'s WinMain. This will be removed when OpenRCT2 can
@@ -568,6 +569,54 @@ void platform_resolve_user_data_path()
free(path); free(path);
} }
void platform_get_openrct_data_path(utf8 *outPath)
{
safe_strncpy(outPath, _openrctDataDirectoryPath, sizeof(_openrctDataDirectoryPath));
}
/**
* Default directory fallback is:
* - (command line argument)
* - <platform dependent>
*/
void platform_resolve_openrct_data_path()
{
const char separator[2] = { platform_get_path_separator(), 0 };
if (gCustomOpenrctDataPath[0] != 0) {
realpath(gCustomOpenrctDataPath, _openrctDataDirectoryPath);
// Ensure path ends with separator
int len = strlen(_openrctDataDirectoryPath);
if (_openrctDataDirectoryPath[len - 1] != separator[0]) {
strncat(_openrctDataDirectoryPath, separator, MAX_PATH - 1);
}
return;
}
char buffer[MAX_PATH] = { 0 };
platform_get_exe_path(buffer);
strncat(buffer, separator, MAX_PATH - strnlen(buffer, MAX_PATH) - 1);
strncat(buffer, "data", MAX_PATH - strnlen(buffer, MAX_PATH) - 1);
const utf8 *searchLocations[] = {
buffer,
#ifdef __linux__
"/var/lib/openrct2",
"/usr/share/openrct2",
#endif // __linux__
};
for (size_t i = 0; i < countof(searchLocations); i++)
{
if (platform_directory_exists(searchLocations[i]))
{
_openrctDataDirectoryPath[0] = '\0';
safe_strncpy(_openrctDataDirectoryPath, searchLocations[i], sizeof(_openrctDataDirectoryPath));
return;
}
}
}
void platform_get_user_directory(utf8 *outPath, const utf8 *subDirectory) void platform_get_user_directory(utf8 *outPath, const utf8 *subDirectory)
{ {
const char separator[2] = { platform_get_path_separator(), 0 }; const char separator[2] = { platform_get_path_separator(), 0 };

View File

@@ -38,6 +38,7 @@
#define SINGLE_INSTANCE_MUTEX_NAME "RollerCoaster Tycoon 2_GSKMUTEX" #define SINGLE_INSTANCE_MUTEX_NAME "RollerCoaster Tycoon 2_GSKMUTEX"
utf8 _userDataDirectoryPath[MAX_PATH] = { 0 }; utf8 _userDataDirectoryPath[MAX_PATH] = { 0 };
utf8 _openrctDataDirectoryPath[MAX_PATH] = { 0 };
utf8 **windows_get_command_line_args(int *outNumArgs); utf8 **windows_get_command_line_args(int *outNumArgs);
@@ -407,6 +408,51 @@ bool platform_file_delete(const utf8 *path)
return success == TRUE; return success == TRUE;
} }
void platform_resolve_openrct_data_path()
{
wchar_t wOutPath[MAX_PATH];
const char separator[2] = { platform_get_path_separator(), 0 };
if (gCustomOpenrctDataPath[0] != 0) {
wchar_t *customUserDataPathW = utf8_to_widechar(gCustomOpenrctDataPath);
if (GetFullPathNameW(customUserDataPathW, countof(wOutPath), wOutPath, NULL) == 0) {
log_fatal("Unable to resolve path '%s'.", gCustomOpenrctDataPath);
exit(-1);
}
utf8 *outPathTemp = widechar_to_utf8(wOutPath);
safe_strncpy(_userDataDirectoryPath, outPathTemp, sizeof(_userDataDirectoryPath));
free(outPathTemp);
free(customUserDataPathW);
// Ensure path ends with separator
int len = strlen(_userDataDirectoryPath);
if (_userDataDirectoryPath[len - 1] != separator[0]) {
strcat(_userDataDirectoryPath, separator);
}
return;
}
char buffer[MAX_PATH] = { 0 };
platform_get_exe_path(buffer);
strncat(buffer, separator, MAX_PATH - strnlen(buffer, MAX_PATH) - 1);
strncat(buffer, "data", MAX_PATH - strnlen(buffer, MAX_PATH) - 1);
if (platform_directory_exists(buffer))
{
_openrctDataDirectoryPath[0] = '\0';
safe_strncpy(_openrctDataDirectoryPath, buffer, sizeof(_openrctDataDirectoryPath));
return;
} else {
log_fatal("Unable to resolve openrct data path.");
exit(-1);
}
}
void platform_get_openrct_data_path(utf8 *outPath)
{
safe_strncpy(outPath, _openrctDataDirectoryPath, sizeof(_openrctDataDirectoryPath));
}
/** /**
* Default directory fallback is: * Default directory fallback is:
* - (command line argument) * - (command line argument)

View File

@@ -602,9 +602,11 @@ static uint8 *title_script_load()
char parts[3 * 128], *token, *part1, *part2, *src; char parts[3 * 128], *token, *part1, *part2, *src;
utf8 path[MAX_PATH]; utf8 path[MAX_PATH];
utf8 filePath[] = "data/title/script.txt"; utf8 dataPath[MAX_PATH];
utf8 filePath[] = "title/script.txt";
sprintf(path, "%s%c%s", gExePath, platform_get_path_separator(), filePath); platform_get_openrct_data_path(dataPath);
sprintf(path, "%s%c%s", dataPath, platform_get_path_separator(), filePath);
log_verbose("loading title script, %s", path); log_verbose("loading title script, %s", path);
file = SDL_RWFromFile(path, "r"); file = SDL_RWFromFile(path, "r");
if (file == NULL) { if (file == NULL) {