mirror of https://github.com/OpenRCT2/OpenRCT2.git
Refactor/Improve String and Path Handling
This commit is contained in:
parent
211a0d7863
commit
e5ff7412e4
|
@ -344,7 +344,7 @@ static exitcode_t HandleCommandSetRCT2(CommandLineArgEnumerator * enumerator)
|
|||
// Check user path that will contain the config
|
||||
utf8 userPath[MAX_PATH];
|
||||
platform_resolve_user_data_path();
|
||||
platform_get_user_directory(userPath, NULL);
|
||||
platform_get_user_directory(userPath, NULL, sizeof(userPath));
|
||||
if (!platform_ensure_directory_exists(userPath)) {
|
||||
Console::Error::WriteLine("Unable to access or create directory '%s'.", userPath);
|
||||
return EXITCODE_FAIL;
|
||||
|
|
|
@ -547,7 +547,7 @@ int cmdline_for_sprite(const char **argv, int argc)
|
|||
for (int x = 0; x < numbers; x++){
|
||||
outputPath[pathLen + x] = '0';
|
||||
}
|
||||
safe_strcpy(outputPath + pathLen + numbers, ".png", MAX_PATH);
|
||||
safe_strcpy(outputPath + pathLen + numbers, ".png", MAX_PATH - pathLen - numbers);
|
||||
|
||||
for (int spriteIndex = 0; spriteIndex < maxIndex; spriteIndex++){
|
||||
|
||||
|
@ -651,7 +651,9 @@ int cmdline_for_sprite(const char **argv, int argc)
|
|||
safe_strcpy(imagePath, resourcePath, MAX_PATH);
|
||||
if (resourcePath[resourceLength - 1] == '/' || resourcePath[resourceLength - 1] == '\\')
|
||||
imagePath[resourceLength - 1] = 0;
|
||||
sprintf(imagePath, "%s%c%d.png", imagePath, platform_get_path_separator(), i);
|
||||
char filename[16];
|
||||
snprintf(filename, 16, "%d.png", i);
|
||||
safe_strcat_path(imagePath, filename, MAX_PATH);
|
||||
|
||||
file = SDL_RWFromFile(imagePath, "r");
|
||||
if (file != NULL) {
|
||||
|
|
80
src/config.c
80
src/config.c
|
@ -371,7 +371,7 @@ static void rwopsprintf(SDL_RWops *file, const char *format, ...)
|
|||
va_start(args, format);
|
||||
|
||||
char buffer[64];
|
||||
vsprintf(buffer, format, args);
|
||||
vsnprintf(buffer, 64, format, args);
|
||||
|
||||
SDL_RWwrite(file, buffer, strlen(buffer), 1);
|
||||
|
||||
|
@ -380,7 +380,7 @@ static void rwopsprintf(SDL_RWops *file, const char *format, ...)
|
|||
|
||||
static void rwopswritenewline(SDL_RWops *file)
|
||||
{
|
||||
rwopswritestr(file, platform_get_new_line());
|
||||
rwopswritestr(file, PLATFORM_NEWLINE);
|
||||
}
|
||||
|
||||
static void rwopswritestresc(SDL_RWops *file, const char *str) {
|
||||
|
@ -468,17 +468,17 @@ void config_release()
|
|||
}
|
||||
}
|
||||
|
||||
void config_get_default_path(utf8 *outPath)
|
||||
void config_get_default_path(utf8 *outPath, size_t size)
|
||||
{
|
||||
platform_get_user_directory(outPath, NULL);
|
||||
strcat(outPath, "config.ini");
|
||||
platform_get_user_directory(outPath, NULL, size);
|
||||
safe_strcat_path(outPath, "config.ini", size);
|
||||
}
|
||||
|
||||
bool config_open_default()
|
||||
{
|
||||
utf8 path[MAX_PATH];
|
||||
|
||||
config_get_default_path(path);
|
||||
config_get_default_path(path, sizeof(path));
|
||||
if (config_open(path)) {
|
||||
currency_load_custom_currency_config();
|
||||
return true;
|
||||
|
@ -491,7 +491,7 @@ bool config_save_default()
|
|||
{
|
||||
utf8 path[MAX_PATH];
|
||||
|
||||
config_get_default_path(path);
|
||||
config_get_default_path(path, sizeof(path));
|
||||
if (config_save(path)) {
|
||||
return true;
|
||||
}
|
||||
|
@ -950,9 +950,8 @@ bool config_find_or_browse_install_directory()
|
|||
if (platform_original_game_data_exists(installPath))
|
||||
return true;
|
||||
|
||||
utf8 message[MAX_PATH] = { 0 };
|
||||
char separator = platform_get_path_separator();
|
||||
sprintf(message, "Could not find %s%cData%cg1.dat at this path", installPath, separator, separator);
|
||||
utf8 message[MAX_PATH];
|
||||
snprintf(message, MAX_PATH, "Could not find %s" PATH_SEPARATOR "Data" PATH_SEPARATOR "g1.dat at this path", installPath);
|
||||
platform_show_messagebox(message);
|
||||
}
|
||||
}
|
||||
|
@ -1043,10 +1042,10 @@ void config_reset_shortcut_keys()
|
|||
memcpy(gShortcutKeys, _defaultShortcutKeys, sizeof(gShortcutKeys));
|
||||
}
|
||||
|
||||
static void config_shortcut_keys_get_path(utf8 *outPath)
|
||||
static void config_shortcut_keys_get_path(utf8 *outPath, size_t size)
|
||||
{
|
||||
platform_get_user_directory(outPath, NULL);
|
||||
strcat(outPath, "hotkeys.cfg");
|
||||
platform_get_user_directory(outPath, NULL, size);
|
||||
safe_strcat_path(outPath, "hotkeys.cfg", size);
|
||||
}
|
||||
|
||||
bool config_shortcut_keys_load()
|
||||
|
@ -1056,7 +1055,7 @@ bool config_shortcut_keys_load()
|
|||
bool result;
|
||||
uint16 version;
|
||||
|
||||
config_shortcut_keys_get_path(path);
|
||||
config_shortcut_keys_get_path(path, sizeof(path));
|
||||
|
||||
file = SDL_RWFromFile(path, "rb");
|
||||
if (file != NULL) {
|
||||
|
@ -1086,7 +1085,7 @@ bool config_shortcut_keys_save()
|
|||
SDL_RWops *file;
|
||||
bool result;
|
||||
|
||||
config_shortcut_keys_get_path(path);
|
||||
config_shortcut_keys_get_path(path, sizeof(path));
|
||||
|
||||
file = SDL_RWFromFile(path, "wb");
|
||||
if (file != NULL) {
|
||||
|
@ -1112,34 +1111,39 @@ void title_sequences_set_default()
|
|||
{
|
||||
char path[MAX_PATH];
|
||||
char dataPath[MAX_PATH];
|
||||
char sep = platform_get_path_separator();
|
||||
|
||||
platform_get_user_directory(path, "title sequences");
|
||||
platform_get_user_directory(path, "title sequences", sizeof(path));
|
||||
platform_ensure_directory_exists(path);
|
||||
|
||||
gConfigTitleSequences.presets = malloc(0);
|
||||
gConfigTitleSequences.num_presets = 0;
|
||||
|
||||
platform_get_openrct_data_path(dataPath);
|
||||
platform_get_openrct_data_path(dataPath, sizeof(dataPath));
|
||||
safe_strcat_path(dataPath, "title", MAX_PATH);
|
||||
|
||||
// RCT1 title sequence
|
||||
sprintf(path, "%s%c%s%c%s%c", dataPath, sep, "title", sep, "rct1", sep);
|
||||
safe_strcpy(path, dataPath, MAX_PATH);
|
||||
safe_strcat_path(path, "rct1", MAX_PATH);
|
||||
title_sequence_open(path, language_get_string(STR_TITLE_SEQUENCE_RCT1));
|
||||
|
||||
// RCT1 (AA) title sequence
|
||||
sprintf(path, "%s%c%s%c%s%c", dataPath, sep, "title", sep, "rct1aa", sep);
|
||||
safe_strcpy(path, dataPath, MAX_PATH);
|
||||
safe_strcat_path(path, "rct1aa", MAX_PATH);
|
||||
title_sequence_open(path, language_get_string(STR_TITLE_SEQUENCE_RCT1_AA));
|
||||
|
||||
// RCT1 (AA + LL) title sequence
|
||||
sprintf(path, "%s%c%s%c%s%c", dataPath, sep, "title", sep, "rct1aall", sep);
|
||||
safe_strcpy(path, dataPath, MAX_PATH);
|
||||
safe_strcat_path(path, "rct1aall", MAX_PATH);
|
||||
title_sequence_open(path, language_get_string(STR_TITLE_SEQUENCE_RCT1_AA_LL));
|
||||
|
||||
// RCT2 title sequence
|
||||
sprintf(path, "%s%c%s%c%s%c", dataPath, sep, "title", sep, "rct2", sep);
|
||||
safe_strcpy(path, dataPath, MAX_PATH);
|
||||
safe_strcat_path(path, "rct2", MAX_PATH);
|
||||
title_sequence_open(path, language_get_string(STR_TITLE_SEQUENCE_RCT2));
|
||||
|
||||
// OpenRCT2 title sequence
|
||||
sprintf(path, "%s%c%s%c%s%c", dataPath, sep, "title", sep, "openrct2", sep);
|
||||
safe_strcpy(path, dataPath, MAX_PATH);
|
||||
safe_strcat_path(path, "openrct2", MAX_PATH);
|
||||
title_sequence_open(path, language_get_string(STR_TITLE_SEQUENCE_OPENRCT2));
|
||||
}
|
||||
|
||||
|
@ -1149,11 +1153,11 @@ void title_sequences_load_presets()
|
|||
int dirEnumHandle, i;
|
||||
|
||||
// Find all directories in the title sequences folder
|
||||
platform_get_user_directory(path, "title sequences");
|
||||
platform_get_user_directory(path, "title sequences", sizeof(path));
|
||||
dirEnumHandle = platform_enumerate_directories_begin(path);
|
||||
while (platform_enumerate_directories_next(dirEnumHandle, titleDir)) {
|
||||
platform_get_user_directory(path, "title sequences");
|
||||
strcat(path, titleDir);
|
||||
platform_get_user_directory(path, "title sequences", sizeof(path));
|
||||
safe_strcat(path, titleDir, sizeof(path));
|
||||
title_sequence_open(path, NULL);
|
||||
}
|
||||
platform_enumerate_directories_end(dirEnumHandle);
|
||||
|
@ -1197,8 +1201,8 @@ static void title_sequence_open(const char *path, const char *customName)
|
|||
char parts[3 * 128], *token, *part1, *part2;
|
||||
|
||||
// Check for the script file
|
||||
safe_strcpy(scriptPath, path, MAX_PATH);
|
||||
strcat(scriptPath, "script.txt");
|
||||
safe_strcpy(scriptPath, path, sizeof(scriptPath));
|
||||
safe_strcat_path(scriptPath, "script.txt", sizeof(scriptPath));
|
||||
if (!platform_file_exists(scriptPath)) {
|
||||
// No script file, title sequence is invalid
|
||||
return;
|
||||
|
@ -1221,9 +1225,9 @@ static void title_sequence_open(const char *path, const char *customName)
|
|||
safe_strcpy(nameBuffer, path, MAX_PATH);
|
||||
// Get folder name
|
||||
// First strip off the last folder separator
|
||||
*strrchr(nameBuffer, platform_get_path_separator()) = '\0';
|
||||
*strrchr(nameBuffer, *PATH_SEPARATOR) = '\0';
|
||||
// Then find the name of the folder
|
||||
char *name = strrchr(nameBuffer, platform_get_path_separator()) + 1;
|
||||
char *name = strrchr(nameBuffer, *PATH_SEPARATOR) + 1;
|
||||
safe_strcpy(gConfigTitleSequences.presets[preset].name, name, TITLE_SEQUENCE_NAME_SIZE);
|
||||
gConfigTitleSequences.presets[preset].path[0] = 0;
|
||||
}
|
||||
|
@ -1239,8 +1243,8 @@ static void title_sequence_open(const char *path, const char *customName)
|
|||
}
|
||||
|
||||
// Get the save file list
|
||||
safe_strcpy(titlePath, path, MAX_PATH);
|
||||
strcat(titlePath, "*.sv6");
|
||||
safe_strcpy(titlePath, path, sizeof(titlePath));
|
||||
safe_strcat_path(titlePath, "*.sv6", sizeof(titlePath));
|
||||
fileEnumHandle = platform_enumerate_files_begin(titlePath);
|
||||
while (platform_enumerate_files_next(fileEnumHandle, &fileInfo)) {
|
||||
gConfigTitleSequences.presets[preset].num_saves++;
|
||||
|
@ -1249,8 +1253,8 @@ static void title_sequence_open(const char *path, const char *customName)
|
|||
gConfigTitleSequences.presets[preset].saves[gConfigTitleSequences.presets[preset].num_saves - 1][TITLE_SEQUENCE_MAX_SAVE_LENGTH - 1] = '\0';
|
||||
}
|
||||
platform_enumerate_files_end(fileEnumHandle);
|
||||
safe_strcpy(titlePath, path, MAX_PATH);
|
||||
strcat(titlePath, "*.sc6");
|
||||
safe_strcpy(titlePath, path, sizeof(titlePath));
|
||||
safe_strcat_path(titlePath, "*.sc6", sizeof(titlePath));
|
||||
fileEnumHandle = platform_enumerate_files_begin(titlePath);
|
||||
while (platform_enumerate_files_next(fileEnumHandle, &fileInfo)) {
|
||||
gConfigTitleSequences.presets[preset].num_saves++;
|
||||
|
@ -1321,13 +1325,11 @@ void title_sequence_save_preset_script(int preset)
|
|||
utf8 path[MAX_PATH];
|
||||
SDL_RWops *file;
|
||||
int i;
|
||||
char separator = platform_get_path_separator();
|
||||
|
||||
|
||||
platform_get_user_directory(path, "title sequences");
|
||||
strcat(path, gConfigTitleSequences.presets[preset].name);
|
||||
strncat(path, &separator, 1);
|
||||
strcat(path, "script.txt");
|
||||
platform_get_user_directory(path, "title sequences", sizeof(path));
|
||||
safe_strcat_path(path, gConfigTitleSequences.presets[preset].name, MAX_PATH);
|
||||
safe_strcat_path(path, "script.txt", MAX_PATH);
|
||||
|
||||
file = SDL_RWFromFile(path, "wb");
|
||||
if (file == NULL) {
|
||||
|
|
|
@ -345,7 +345,7 @@ extern title_sequences_configuration gConfigTitleSequences;
|
|||
|
||||
extern uint16 gShortcutKeys[SHORTCUT_COUNT];
|
||||
|
||||
void config_get_default_path(utf8 *outPath);
|
||||
void config_get_default_path(utf8 *outPath, size_t size);
|
||||
void config_set_defaults();
|
||||
void config_release();
|
||||
bool config_open_default();
|
||||
|
|
|
@ -88,7 +88,7 @@ namespace Console
|
|||
|
||||
void WriteLine()
|
||||
{
|
||||
fputs(platform_get_new_line(), stderr);
|
||||
fputs(PLATFORM_NEWLINE, stderr);
|
||||
}
|
||||
|
||||
void WriteLine(const utf8 * format, ...)
|
||||
|
|
|
@ -75,7 +75,8 @@ namespace Guard
|
|||
if (message != nullptr)
|
||||
{
|
||||
strcat(buffer, "\r\n");
|
||||
vsprintf((char *)strchr(buffer, 0), message, args);
|
||||
char *bufend = (char *)strchr(buffer, 0);
|
||||
vsnprintf(bufend, sizeof(buffer) - (bufend - buffer), message, args);
|
||||
}
|
||||
int result = MessageBox(nullptr, buffer, OPENRCT2_NAME, MB_ABORTRETRYIGNORE | MB_ICONEXCLAMATION);
|
||||
if (result == IDABORT)
|
||||
|
|
|
@ -36,8 +36,7 @@ namespace Path
|
|||
|
||||
utf8 * GetDirectory(utf8 * buffer, size_t bufferSize, const utf8 * path)
|
||||
{
|
||||
const char pathSeperator = platform_get_path_separator();
|
||||
size_t lastPathSepIndex = String::LastIndexOf(path, pathSeperator);
|
||||
size_t lastPathSepIndex = String::LastIndexOf(path, *PATH_SEPARATOR);
|
||||
if (lastPathSepIndex == SIZE_MAX)
|
||||
{
|
||||
return String::Set(buffer, bufferSize, String::Empty);
|
||||
|
@ -54,7 +53,7 @@ namespace Path
|
|||
const utf8 * lastPathSeperator = nullptr;
|
||||
for (const utf8 * ch = path; *ch != '\0'; ch++)
|
||||
{
|
||||
if (*ch == platform_get_path_separator())
|
||||
if (*ch == *PATH_SEPARATOR)
|
||||
{
|
||||
lastPathSeperator = ch;
|
||||
}
|
||||
|
|
|
@ -277,7 +277,7 @@ public:
|
|||
if (_context == nullptr)
|
||||
{
|
||||
char szRequiredVersion[32];
|
||||
sprintf(szRequiredVersion, "OpenGL %d.%d", requiredVersion.Major, requiredVersion.Minor);
|
||||
snprintf(szRequiredVersion, 32, "OpenGL %d.%d", requiredVersion.Major, requiredVersion.Minor);
|
||||
throw Exception(std::string(szRequiredVersion) + std::string(" not available."));
|
||||
}
|
||||
SDL_GL_MakeCurrent(_window, _context);
|
||||
|
|
|
@ -70,7 +70,7 @@ GLuint OpenGLShader::GetShaderId()
|
|||
|
||||
void OpenGLShader::GetPath(char * buffer, size_t bufferSize, const char * name)
|
||||
{
|
||||
platform_get_openrct_data_path(buffer);
|
||||
platform_get_openrct_data_path(buffer, bufferSize);
|
||||
Path::Append(buffer, bufferSize, "shaders");
|
||||
Path::Append(buffer, bufferSize, name);
|
||||
if (_type == GL_VERTEX_SHADER)
|
||||
|
|
|
@ -133,12 +133,12 @@ static uint8 scrolling_text_get_colour(uint32 character)
|
|||
}
|
||||
}
|
||||
|
||||
static void scrolling_text_format(utf8 *dst, rct_draw_scroll_text *scrollText)
|
||||
static void scrolling_text_format(utf8 *dst, size_t size, rct_draw_scroll_text *scrollText)
|
||||
{
|
||||
if (gConfigGeneral.upper_case_banners) {
|
||||
format_string_to_upper(dst, scrollText->string_id, &scrollText->string_args_0);
|
||||
format_string_to_upper(dst, size, scrollText->string_id, &scrollText->string_args_0);
|
||||
} else {
|
||||
format_string(dst, scrollText->string_id, &scrollText->string_args_0);
|
||||
format_string(dst, size, scrollText->string_id, &scrollText->string_args_0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1442,7 +1442,7 @@ int scrolling_text_setup(rct_string_id stringId, uint16 scroll, uint16 scrolling
|
|||
|
||||
// Create the string to draw
|
||||
utf8 scrollString[256];
|
||||
scrolling_text_format(scrollString, scrollText);
|
||||
scrolling_text_format(scrollString, 256, scrollText);
|
||||
|
||||
const sint16* scrollingModePositions = _scrollPositions[scrollingMode];
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "../openrct2.h"
|
||||
#include "../platform/platform.h"
|
||||
#include "../sprites.h"
|
||||
#include "../util/util.h"
|
||||
#include "drawing.h"
|
||||
|
||||
void *_g1Buffer = NULL;
|
||||
|
@ -152,10 +153,9 @@ bool gfx_load_g2()
|
|||
unsigned int i;
|
||||
|
||||
char path[MAX_PATH];
|
||||
char dataPath[MAX_PATH];
|
||||
|
||||
platform_get_openrct_data_path(dataPath);
|
||||
sprintf(path, "%s%cg2.dat", dataPath, platform_get_path_separator());
|
||||
platform_get_openrct_data_path(path, sizeof(path));
|
||||
safe_strcat_path(path, "g2.dat", MAX_PATH);
|
||||
file = SDL_RWFromFile(path, "rb");
|
||||
if (file != NULL) {
|
||||
if (SDL_RWread(file, &g2.header, 8, 1) == 1) {
|
||||
|
|
|
@ -247,7 +247,7 @@ int gfx_wrap_string(utf8 *text, int width, int *outNumLines, int *outFontHeight)
|
|||
void gfx_draw_string_left_clipped(rct_drawpixelinfo* dpi, rct_string_id format, void* args, int colour, int x, int y, int width)
|
||||
{
|
||||
char* buffer = gCommonStringFormatBuffer;
|
||||
format_string(buffer, format, args);
|
||||
format_string(buffer, 256, format, args);
|
||||
|
||||
gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM;
|
||||
|
||||
|
@ -272,7 +272,7 @@ void gfx_draw_string_left_clipped(rct_drawpixelinfo* dpi, rct_string_id format,
|
|||
void gfx_draw_string_centred_clipped(rct_drawpixelinfo *dpi, rct_string_id format, void *args, int colour, int x, int y, int width)
|
||||
{
|
||||
char* buffer = gCommonStringFormatBuffer;
|
||||
format_string(buffer, format, args);
|
||||
format_string(buffer, 256, format, args);
|
||||
|
||||
gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM;
|
||||
|
||||
|
@ -301,7 +301,7 @@ void gfx_draw_string_centred_clipped(rct_drawpixelinfo *dpi, rct_string_id forma
|
|||
void gfx_draw_string_right(rct_drawpixelinfo* dpi, rct_string_id format, void* args, int colour, int x, int y)
|
||||
{
|
||||
char* buffer = gCommonStringFormatBuffer;
|
||||
format_string(buffer, format, args);
|
||||
format_string(buffer, 256, format, args);
|
||||
|
||||
// Measure text width
|
||||
short text_width = gfx_get_string_width(buffer);
|
||||
|
@ -347,7 +347,7 @@ int gfx_draw_string_centred_wrapped(rct_drawpixelinfo *dpi, void *args, int x, i
|
|||
|
||||
char *buffer = gCommonStringFormatBuffer;
|
||||
gfx_draw_string(dpi, "", colour, dpi->x, dpi->y);
|
||||
format_string(buffer, format, args);
|
||||
format_string(buffer, 256, format, args);
|
||||
|
||||
gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM;
|
||||
|
||||
|
@ -394,7 +394,7 @@ int gfx_draw_string_left_wrapped(rct_drawpixelinfo *dpi, void *args, int x, int
|
|||
|
||||
char *buffer = gCommonStringFormatBuffer;
|
||||
gfx_draw_string(dpi, "", colour, dpi->x, dpi->y);
|
||||
format_string(buffer, format, args);
|
||||
format_string(buffer, 256, format, args);
|
||||
|
||||
gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM;
|
||||
gfx_wrap_string(buffer, width, &numLines, &fontSpriteBase);
|
||||
|
@ -423,7 +423,7 @@ int gfx_draw_string_left_wrapped(rct_drawpixelinfo *dpi, void *args, int x, int
|
|||
void gfx_draw_string_left(rct_drawpixelinfo *dpi, rct_string_id format, void *args, int colour, int x, int y)
|
||||
{
|
||||
char* buffer = gCommonStringFormatBuffer;
|
||||
format_string(buffer, format, args);
|
||||
format_string(buffer, 256, format, args);
|
||||
gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM;
|
||||
gfx_draw_string(dpi, buffer, colour, x, y);
|
||||
}
|
||||
|
@ -435,7 +435,7 @@ void gfx_draw_string_left_centred(rct_drawpixelinfo *dpi, rct_string_id format,
|
|||
{
|
||||
gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM;
|
||||
char *buffer = gCommonStringFormatBuffer;
|
||||
format_string(buffer, format, args);
|
||||
format_string(buffer, 256, format, args);
|
||||
int height = string_get_height_raw(buffer);
|
||||
gfx_draw_string(dpi, buffer, colour, x, y - (height / 2));
|
||||
}
|
||||
|
@ -500,7 +500,7 @@ void draw_string_left_underline(rct_drawpixelinfo *dpi, rct_string_id format, vo
|
|||
char buffer[128];
|
||||
int width;
|
||||
|
||||
format_string(buffer, format, args);
|
||||
format_string(buffer, 128, format, args);
|
||||
gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM;
|
||||
width = gfx_get_string_width(buffer);
|
||||
gfx_draw_string(dpi, buffer, colour, x, y);
|
||||
|
@ -514,7 +514,7 @@ void draw_string_right_underline(rct_drawpixelinfo *dpi, rct_string_id format, v
|
|||
char buffer[128];
|
||||
int width;
|
||||
|
||||
format_string(buffer, format, args);
|
||||
format_string(buffer, 128, format, args);
|
||||
gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM;
|
||||
width = gfx_get_string_width(buffer);
|
||||
x -= width;
|
||||
|
@ -529,7 +529,7 @@ void draw_string_centred_underline(rct_drawpixelinfo *dpi, rct_string_id format,
|
|||
char buffer[128];
|
||||
int width;
|
||||
|
||||
format_string(buffer, format, args);
|
||||
format_string(buffer, 128, format, args);
|
||||
gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM;
|
||||
width = gfx_get_string_width(buffer);
|
||||
x -= width / 2;
|
||||
|
@ -655,7 +655,7 @@ void gfx_draw_string_centred_wrapped_partial(rct_drawpixelinfo *dpi, int x, int
|
|||
|
||||
gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM;
|
||||
gfx_draw_string(dpi, "", colour, dpi->x, dpi->y);
|
||||
format_string(buffer, format, args);
|
||||
format_string(buffer, 256, format, args);
|
||||
|
||||
|
||||
gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM;
|
||||
|
@ -844,7 +844,7 @@ bool ttf_initialise()
|
|||
TTFFontDescriptor *fontDesc = &(gCurrentTTFFontSet->size[i]);
|
||||
|
||||
utf8 fontPath[MAX_PATH];
|
||||
if (!platform_get_font_path(fontDesc, fontPath)) {
|
||||
if (!platform_get_font_path(fontDesc, fontPath, sizeof(fontPath))) {
|
||||
log_error("Unable to load font '%s'", fontDesc->font_name);
|
||||
return false;
|
||||
}
|
||||
|
@ -1345,7 +1345,7 @@ void shorten_path(utf8 *buffer, size_t bufferSize, const utf8 *path, int availab
|
|||
// Count path separators
|
||||
int path_separators = 0;
|
||||
for (size_t x = 0; x < length; x++) {
|
||||
if (path[x] == platform_get_path_separator()) {
|
||||
if (path[x] == *PATH_SEPARATOR) {
|
||||
path_separators++;
|
||||
}
|
||||
}
|
||||
|
@ -1358,7 +1358,7 @@ void shorten_path(utf8 *buffer, size_t bufferSize, const utf8 *path, int availab
|
|||
for (int x = 0; x < path_separators; x++){
|
||||
do {
|
||||
begin++;
|
||||
} while (path[begin] != platform_get_path_separator());
|
||||
} while (path[begin] != *PATH_SEPARATOR);
|
||||
|
||||
safe_strcpy(buffer + 3, path + begin, bufferSize - 3);
|
||||
if (gfx_get_string_width(buffer) <= availableWidth) {
|
||||
|
|
30
src/game.c
30
src/game.c
|
@ -675,8 +675,7 @@ static void rct2_to_utf8_self(char *buffer, size_t length)
|
|||
char tempBuffer[512];
|
||||
if (length > 0) {
|
||||
rct2_to_utf8(tempBuffer, buffer);
|
||||
strncpy(buffer, tempBuffer, length - 1);
|
||||
buffer[length - 1] = '\0';
|
||||
safe_strcpy(buffer, tempBuffer, length);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -954,8 +953,8 @@ static void limit_autosave_count(const size_t numberOfFilesToKeep)
|
|||
|
||||
size_t i=0;
|
||||
|
||||
platform_get_user_directory(filter, "save");
|
||||
strncat(filter, "autosave_*.sv6", sizeof(filter) - strnlen(filter, MAX_PATH) - 1);
|
||||
platform_get_user_directory(filter, "save", sizeof(filter));
|
||||
safe_strcat_path(filter, "autosave_*.sv6", sizeof(filter));
|
||||
|
||||
// At first, count how many autosaves there are
|
||||
fileEnumHandle = platform_enumerate_files_begin(filter);
|
||||
|
@ -977,8 +976,8 @@ static void limit_autosave_count(const size_t numberOfFilesToKeep)
|
|||
memset(autosaveFiles[i], 0, sizeof(utf8) * MAX_PATH);
|
||||
|
||||
if(platform_enumerate_files_next(fileEnumHandle, &fileInfo)) {
|
||||
platform_get_user_directory(autosaveFiles[i], "save");
|
||||
strcat(autosaveFiles[i], fileInfo.path);
|
||||
platform_get_user_directory(autosaveFiles[i], "save", sizeof(utf8) * MAX_PATH);
|
||||
safe_strcat_path(autosaveFiles[i], fileInfo.path, sizeof(utf8) * MAX_PATH);
|
||||
}
|
||||
}
|
||||
platform_enumerate_files_end(fileEnumHandle);
|
||||
|
@ -1008,7 +1007,7 @@ void game_autosave()
|
|||
{
|
||||
utf8 path[MAX_PATH];
|
||||
utf8 backupPath[MAX_PATH];
|
||||
utf8 timeString[21]="";
|
||||
utf8 timeName[34];
|
||||
|
||||
// retrieve current time
|
||||
rct2_date currentDate;
|
||||
|
@ -1016,18 +1015,15 @@ void game_autosave()
|
|||
rct2_time currentTime;
|
||||
platform_get_time_local(¤tTime);
|
||||
|
||||
sprintf(timeString, "%d-%02d-%02d_%02d-%02d-%02d", currentDate.year, currentDate.month, currentDate.day, currentTime.hour, currentTime.minute,currentTime.second);
|
||||
snprintf(timeName, 34, "autosave_%d-%02d-%02d_%02d-%02d-%02d.sv6", currentDate.year, currentDate.month, currentDate.day, currentTime.hour, currentTime.minute,currentTime.second);
|
||||
|
||||
limit_autosave_count(NUMBER_OF_AUTOSAVES_TO_KEEP);
|
||||
|
||||
platform_get_user_directory(path, "save");
|
||||
safe_strcpy(backupPath, path, MAX_PATH);
|
||||
platform_get_user_directory(path, "save", sizeof(path));
|
||||
safe_strcpy(backupPath, path, sizeof(backupPath));
|
||||
|
||||
strcat(path, "autosave_");
|
||||
strcat(path, timeString);
|
||||
strcat(path, ".sv6");
|
||||
|
||||
strcat(backupPath, "autosave.sv6.bak");
|
||||
safe_strcat_path(path, timeName, sizeof(path));
|
||||
safe_strcat_path(backupPath, "autosave.sv6.bak", sizeof(backupPath));
|
||||
|
||||
if (platform_file_exists(path)) {
|
||||
platform_file_copy(path, backupPath, true);
|
||||
|
@ -1048,10 +1044,10 @@ void rct2_exit_reason(rct_string_id title, rct_string_id body){
|
|||
// Before this would set a quit message
|
||||
|
||||
char exit_title[255];
|
||||
format_string(exit_title, title, 0);
|
||||
format_string(exit_title, 256, title, 0);
|
||||
|
||||
char exit_body[255];
|
||||
format_string(exit_body, body, 0);
|
||||
format_string(exit_body, 256, body, 0);
|
||||
|
||||
log_error(exit_title);
|
||||
log_error(exit_body);
|
||||
|
|
|
@ -644,7 +644,7 @@ namespace ThemeManager
|
|||
|
||||
void GetThemePath(utf8 * buffer, size_t bufferSize)
|
||||
{
|
||||
platform_get_user_directory(buffer, "themes");
|
||||
platform_get_user_directory(buffer, "themes", bufferSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -102,7 +102,7 @@ void chat_draw(rct_drawpixelinfo * dpi)
|
|||
continue;
|
||||
}
|
||||
|
||||
safe_strcpy(lineBuffer, chat_history_get(i), CHAT_INPUT_SIZE + 10);
|
||||
safe_strcpy(lineBuffer, chat_history_get(i), sizeof(lineBuffer));
|
||||
|
||||
int lineHeight = chat_string_wrapped_get_height((void*)&lineCh, _chatWidth - 10);
|
||||
_chatTop -= (lineHeight + 5);
|
||||
|
@ -134,7 +134,7 @@ void chat_draw(rct_drawpixelinfo * dpi)
|
|||
break;
|
||||
}
|
||||
|
||||
safe_strcpy(lineBuffer, chat_history_get(i), CHAT_INPUT_SIZE + 10);
|
||||
safe_strcpy(lineBuffer, chat_history_get(i), sizeof(lineBuffer));
|
||||
|
||||
stringHeight = chat_history_draw_string(dpi, (void*) &lineCh, x, y, _chatWidth - 10) + 5;
|
||||
gfx_set_dirty_blocks(x, y - stringHeight, x + _chatWidth, y + 20);
|
||||
|
@ -220,7 +220,7 @@ int chat_history_draw_string(rct_drawpixelinfo *dpi, void *args, int x, int y, i
|
|||
|
||||
gfx_draw_string(dpi, "", 255, dpi->x, dpi->y);
|
||||
char *buffer = gCommonStringFormatBuffer;
|
||||
format_string(buffer, STR_STRING, args);
|
||||
format_string(buffer, 256, STR_STRING, args);
|
||||
|
||||
gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM;
|
||||
gfx_wrap_string(buffer, width, &numLines, &fontSpriteBase);
|
||||
|
@ -251,7 +251,7 @@ int chat_string_wrapped_get_height(void *args, int width)
|
|||
gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM;
|
||||
|
||||
char *buffer = gCommonStringFormatBuffer;
|
||||
format_string(buffer, STR_STRING, args);
|
||||
format_string(buffer, 256, STR_STRING, args);
|
||||
|
||||
gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM;
|
||||
gfx_wrap_string(buffer, width, &numLines, &fontSpriteBase);
|
||||
|
|
|
@ -205,7 +205,7 @@ void console_draw(rct_drawpixelinfo *dpi)
|
|||
size_t lineLength = min(sizeof(lineBuffer) - (size_t)utf8_get_codepoint_length(FORMAT_WHITE), (size_t)(nextLine - ch));
|
||||
lineCh = lineBuffer;
|
||||
lineCh = utf8_write_codepoint(lineCh, FORMAT_WHITE);
|
||||
strncpy(lineCh, ch, lineLength);
|
||||
memcpy(lineCh, ch, lineLength);
|
||||
lineCh[lineLength] = 0;
|
||||
|
||||
gfx_draw_string(dpi, lineBuffer, 100, x, y); //Value 100 outlines the letters
|
||||
|
@ -226,7 +226,7 @@ void console_draw(rct_drawpixelinfo *dpi)
|
|||
// Draw current line
|
||||
lineCh = lineBuffer;
|
||||
lineCh = utf8_write_codepoint(lineCh, FORMAT_WHITE);
|
||||
strcpy(lineCh, _consoleCurrentLine);
|
||||
safe_strcpy(lineCh, _consoleCurrentLine, sizeof(lineBuffer) - (lineCh - lineBuffer));
|
||||
gfx_draw_string(dpi, lineBuffer, 255, x, y);
|
||||
|
||||
// Draw caret
|
||||
|
@ -301,8 +301,9 @@ void console_write(const utf8 *src)
|
|||
if (charactersToWrite > charactersRemainingInBuffer) {
|
||||
memmove(_consoleBuffer, _consoleBuffer + bufferShift, CONSOLE_BUFFER_SIZE - bufferShift);
|
||||
_consoleBufferPointer -= bufferShift;
|
||||
charactersRemainingInBuffer = CONSOLE_BUFFER_SIZE - (_consoleBufferPointer - _consoleBuffer) - 1;
|
||||
}
|
||||
strcpy(_consoleBufferPointer, src);
|
||||
safe_strcpy(_consoleBufferPointer, src, charactersRemainingInBuffer);
|
||||
_consoleBufferPointer += charactersToWrite;
|
||||
console_update_scroll();
|
||||
}
|
||||
|
@ -315,14 +316,14 @@ void console_writeline(const utf8 *src)
|
|||
|
||||
void console_writeline_error(const utf8 *src)
|
||||
{
|
||||
strcpy(_consoleErrorBuffer + 1, src);
|
||||
safe_strcpy(_consoleErrorBuffer + 1, src, CONSOLE_BUFFER_2_SIZE - 1);
|
||||
_consoleErrorBuffer[0] = FORMAT_RED;
|
||||
console_writeline(_consoleErrorBuffer);
|
||||
}
|
||||
|
||||
void console_writeline_warning(const utf8 *src)
|
||||
{
|
||||
strcpy(_consoleErrorBuffer + 1, src);
|
||||
safe_strcpy(_consoleErrorBuffer + 1, src, CONSOLE_BUFFER_2_SIZE - 1);
|
||||
_consoleErrorBuffer[0] = FORMAT_YELLOW;
|
||||
console_writeline(_consoleErrorBuffer);
|
||||
}
|
||||
|
@ -331,7 +332,7 @@ void console_printf(const utf8 *format, ...)
|
|||
{
|
||||
va_list list;
|
||||
va_start(list, format);
|
||||
vsprintf(_consolePrintfBuffer, format, list);
|
||||
vsnprintf(_consolePrintfBuffer, sizeof(_consolePrintfBuffer), format, list);
|
||||
va_end(list);
|
||||
console_writeline(_consolePrintfBuffer);
|
||||
}
|
||||
|
@ -449,7 +450,7 @@ static int cc_rides(const utf8 **argv, int argc)
|
|||
int i;
|
||||
FOR_ALL_RIDES(i, ride) {
|
||||
char name[128];
|
||||
format_string(name, ride->name, &ride->name_arguments);
|
||||
format_string(name, 128, ride->name, &ride->name_arguments);
|
||||
console_printf("rides %03d type: %02u subtype %03u name %s", i, ride->type, ride->subtype, name);
|
||||
}
|
||||
} else if (strcmp(argv[0], "set") == 0) {
|
||||
|
@ -515,7 +516,7 @@ static int cc_staff(const utf8 **argv, int argc)
|
|||
int i;
|
||||
FOR_ALL_STAFF(i, peep) {
|
||||
char name[128];
|
||||
format_string(name, peep->name_string_idx, &peep->id);
|
||||
format_string(name, 128, peep->name_string_idx, &peep->id);
|
||||
console_printf("staff id %03d type: %02u energy %03u name %s", i, peep->staff_type, peep->energy, name);
|
||||
}
|
||||
} else if (strcmp(argv[0], "set") == 0) {
|
||||
|
@ -1178,7 +1179,7 @@ void console_execute_silent(const utf8 *src)
|
|||
utf8 output[128];
|
||||
utf8 *dst = output;
|
||||
dst = utf8_write_codepoint(dst, FORMAT_TOPAZ);
|
||||
strcpy(dst, "Unknown command. Type help to list available commands.");
|
||||
safe_strcpy(dst, "Unknown command. Type help to list available commands.", sizeof(output) - (dst - output));
|
||||
console_writeline(output);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "../platform/platform.h"
|
||||
#include "../ride/track_paint.h"
|
||||
#include "../title.h"
|
||||
#include "../util/util.h"
|
||||
#include "keyboard_shortcut.h"
|
||||
#include "viewport.h"
|
||||
#include "widget.h"
|
||||
|
@ -92,33 +93,34 @@ void keyboard_shortcut_handle_command(int shortcutIndex)
|
|||
}
|
||||
}
|
||||
|
||||
void keyboard_shortcut_format_string(char *buffer, uint16 shortcutKey)
|
||||
void keyboard_shortcut_format_string(char *buffer, size_t size, uint16 shortcutKey)
|
||||
{
|
||||
char formatBuffer[256];
|
||||
|
||||
if (size == 0) return;
|
||||
*buffer = 0;
|
||||
if (shortcutKey == SHORTCUT_UNDEFINED) return;
|
||||
if (shortcutKey & 0x100) {
|
||||
format_string(formatBuffer, STR_SHIFT_PLUS, NULL);
|
||||
strcat(buffer, formatBuffer);
|
||||
format_string(formatBuffer, 256, STR_SHIFT_PLUS, NULL);
|
||||
safe_strcat(buffer, formatBuffer, size);
|
||||
}
|
||||
if (shortcutKey & 0x200) {
|
||||
format_string(formatBuffer, STR_CTRL_PLUS, NULL);
|
||||
strcat(buffer, formatBuffer);
|
||||
format_string(formatBuffer, 256, STR_CTRL_PLUS, NULL);
|
||||
safe_strcat(buffer, formatBuffer, size);
|
||||
}
|
||||
if (shortcutKey & 0x400) {
|
||||
#ifdef __MACOSX__
|
||||
format_string(formatBuffer, STR_OPTION_PLUS, NULL);
|
||||
format_string(formatBuffer, 256, STR_OPTION_PLUS, NULL);
|
||||
#else
|
||||
format_string(formatBuffer, STR_ALT_PLUS, NULL);
|
||||
format_string(formatBuffer, 256, STR_ALT_PLUS, NULL);
|
||||
#endif
|
||||
strcat(buffer, formatBuffer);
|
||||
safe_strcat(buffer, formatBuffer, size);
|
||||
}
|
||||
if (shortcutKey & 0x800) {
|
||||
format_string(formatBuffer, STR_CMD_PLUS, NULL);
|
||||
strcat(buffer, formatBuffer);
|
||||
format_string(formatBuffer, 256, STR_CMD_PLUS, NULL);
|
||||
safe_strcat(buffer, formatBuffer, size);
|
||||
}
|
||||
strcat(buffer, SDL_GetScancodeName(shortcutKey & 0xFF));
|
||||
safe_strcat(buffer, SDL_GetScancodeName(shortcutKey & 0xFF), size);
|
||||
}
|
||||
|
||||
#pragma region Shortcut Commands
|
||||
|
|
|
@ -25,6 +25,6 @@ extern uint8 gKeyboardShortcutChangeId;
|
|||
void keyboard_shortcut_set(int key);
|
||||
void keyboard_shortcut_handle(int key);
|
||||
void keyboard_shortcut_handle_command(int shortcutIndex);
|
||||
void keyboard_shortcut_format_string(char *buffer, uint16 shortcutKey);
|
||||
void keyboard_shortcut_format_string(char *buffer, size_t size, uint16 shortcutKey);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -67,18 +67,18 @@ static void screenshot_get_rendered_palette(rct_palette* palette) {
|
|||
}
|
||||
}
|
||||
|
||||
static int screenshot_get_next_path(char *path)
|
||||
static int screenshot_get_next_path(char *path, size_t size)
|
||||
{
|
||||
char screenshotPath[MAX_PATH];
|
||||
|
||||
platform_get_user_directory(screenshotPath, "screenshot");
|
||||
platform_get_user_directory(screenshotPath, "screenshot", sizeof(screenshotPath));
|
||||
if (!platform_ensure_directory_exists(screenshotPath)) {
|
||||
log_error("Unable to save screenshots in OpenRCT2 screenshot directory.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
char park_name[128] = { 0 };
|
||||
format_string(park_name, gParkName, &gParkNameArgs);
|
||||
char park_name[128];
|
||||
format_string(park_name, 128, gParkName, &gParkNameArgs);
|
||||
|
||||
// retrieve current time
|
||||
rct2_date currentDate;
|
||||
|
@ -87,7 +87,7 @@ static int screenshot_get_next_path(char *path)
|
|||
platform_get_time_local(¤tTime);
|
||||
|
||||
// Glue together path and filename
|
||||
sprintf(path, "%s%s %d-%02d-%02d %02d-%02d-%02d.png", screenshotPath, park_name, currentDate.year, currentDate.month, currentDate.day, currentTime.hour, currentTime.minute, currentTime.second);
|
||||
snprintf(path, size, "%s%s %d-%02d-%02d %02d-%02d-%02d.png", screenshotPath, park_name, currentDate.year, currentDate.month, currentDate.day, currentTime.hour, currentTime.minute, currentTime.second);
|
||||
|
||||
if (!platform_file_exists(path)) {
|
||||
return 0; // path ok
|
||||
|
@ -102,7 +102,7 @@ static int screenshot_get_next_path(char *path)
|
|||
int i;
|
||||
for (i = 1; i < 1000; i++) {
|
||||
// Glue together path and filename
|
||||
sprintf(path, "%s%s %d-%02d-%02d %02d-%02d-%02d (%d).png", screenshotPath, park_name, currentDate.year, currentDate.month, currentDate.day, currentTime.hour, currentTime.minute, currentTime.second, i);
|
||||
snprintf(path, size, "%s%s %d-%02d-%02d %02d-%02d-%02d (%d).png", screenshotPath, park_name, currentDate.year, currentDate.month, currentDate.day, currentTime.hour, currentTime.minute, currentTime.second, i);
|
||||
|
||||
if (!platform_file_exists(path)) {
|
||||
return i;
|
||||
|
@ -118,7 +118,7 @@ int screenshot_dump_png(rct_drawpixelinfo *dpi)
|
|||
// Get a free screenshot path
|
||||
int index;
|
||||
char path[MAX_PATH] = "";
|
||||
if ((index = screenshot_get_next_path(path)) == -1) {
|
||||
if ((index = screenshot_get_next_path(path, MAX_PATH)) == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -137,7 +137,7 @@ int screenshot_dump_png_32bpp(sint32 width, sint32 height, const void *pixels)
|
|||
// Get a free screenshot path
|
||||
int index;
|
||||
char path[MAX_PATH] = "";
|
||||
if ((index = screenshot_get_next_path(path)) == -1) {
|
||||
if ((index = screenshot_get_next_path(path, MAX_PATH)) == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -222,7 +222,7 @@ void screenshot_giant()
|
|||
// Get a free screenshot path
|
||||
char path[MAX_PATH];
|
||||
int index;
|
||||
if ((index = screenshot_get_next_path(path)) == -1) {
|
||||
if ((index = screenshot_get_next_path(path, MAX_PATH)) == -1) {
|
||||
log_error("Giant screenshot failed, unable to find a suitable destination path.");
|
||||
window_error_open(STR_SCREENSHOT_FAILED, STR_NONE);
|
||||
return;
|
||||
|
@ -236,9 +236,8 @@ void screenshot_giant()
|
|||
free(dpi.bits);
|
||||
|
||||
// Show user that screenshot saved successfully
|
||||
rct_string_id stringId = STR_PLACEHOLDER;
|
||||
strcpy((char*)language_get_string(stringId), path_get_filename(path));
|
||||
set_format_arg(0, rct_string_id, stringId);
|
||||
set_format_arg(0, rct_string_id, STR_STRING);
|
||||
set_format_arg(2, char *, path_get_filename(path));
|
||||
window_error_open(STR_SCREENSHOT_SAVED_AS, STR_NONE);
|
||||
}
|
||||
|
||||
|
|
|
@ -42,10 +42,10 @@ bool title_sequence_name_exists(const char *name)
|
|||
bool title_sequence_save_exists(int preset, const char *name)
|
||||
{
|
||||
utf8 newName[MAX_PATH];
|
||||
char *extension = (char*)path_get_extension(name);
|
||||
const char *extension = path_get_extension(name);
|
||||
safe_strcpy(newName, name, MAX_PATH);
|
||||
if (_stricmp(extension, ".sv6") != 0 && _stricmp(extension, ".sc6") != 0)
|
||||
strcat(newName, ".sv6");
|
||||
path_append_extension(newName, ".sv6", MAX_PATH);
|
||||
for (int i = 0; i < gConfigTitleSequences.presets[preset].num_saves; i++) {
|
||||
if (_stricmp(gConfigTitleSequences.presets[preset].saves[i], newName) == 0)
|
||||
return true;
|
||||
|
@ -102,8 +102,8 @@ void title_sequence_create_preset(const char *name)
|
|||
|
||||
// Create the folder
|
||||
utf8 path[MAX_PATH];
|
||||
platform_get_user_directory(path, "title sequences");
|
||||
strcat(path, gConfigTitleSequences.presets[preset].name);
|
||||
platform_get_user_directory(path, "title sequences", sizeof(path));
|
||||
safe_strcat_path(path, gConfigTitleSequences.presets[preset].name, MAX_PATH);
|
||||
platform_file_delete(path);
|
||||
platform_ensure_directory_exists(path);
|
||||
|
||||
|
@ -141,28 +141,25 @@ void title_sequence_duplicate_preset(int duplicate, const char *name)
|
|||
|
||||
// Create the folder
|
||||
utf8 path[MAX_PATH], srcPath[MAX_PATH];
|
||||
platform_get_user_directory(path, "title sequences");
|
||||
strcat(path, gConfigTitleSequences.presets[preset].name);
|
||||
platform_get_user_directory(path, "title sequences", sizeof(path));
|
||||
safe_strcat_path(path, gConfigTitleSequences.presets[preset].name, MAX_PATH);
|
||||
platform_file_delete(path);
|
||||
platform_ensure_directory_exists(path);
|
||||
|
||||
// Copy the saves
|
||||
char separator = platform_get_path_separator();
|
||||
for (int i = 0; i < gConfigTitleSequences.presets[preset].num_saves; i++) {
|
||||
if (gConfigTitleSequences.presets[duplicate].path[0]) {
|
||||
safe_strcpy(srcPath, gConfigTitleSequences.presets[duplicate].path, MAX_PATH);
|
||||
strcat(srcPath, gConfigTitleSequences.presets[duplicate].saves[i]);
|
||||
safe_strcat_path(srcPath, gConfigTitleSequences.presets[duplicate].saves[i], MAX_PATH);
|
||||
}
|
||||
else {
|
||||
platform_get_user_directory(srcPath, "title sequences");
|
||||
strcat(srcPath, gConfigTitleSequences.presets[duplicate].name);
|
||||
strncat(srcPath, &separator, 1);
|
||||
strcat(srcPath, gConfigTitleSequences.presets[duplicate].saves[i]);
|
||||
platform_get_user_directory(srcPath, "title sequences", sizeof(srcPath));
|
||||
safe_strcat_path(srcPath, gConfigTitleSequences.presets[duplicate].name, MAX_PATH);
|
||||
safe_strcat_path(srcPath, gConfigTitleSequences.presets[duplicate].saves[i], MAX_PATH);
|
||||
}
|
||||
platform_get_user_directory(path, "title sequences");
|
||||
strcat(path, gConfigTitleSequences.presets[preset].name);
|
||||
strncat(path, &separator, 1);
|
||||
strcat(path, gConfigTitleSequences.presets[preset].saves[i]);
|
||||
platform_get_user_directory(path, "title sequences", sizeof(path));
|
||||
safe_strcat_path(path, gConfigTitleSequences.presets[preset].name, MAX_PATH);
|
||||
safe_strcat_path(path, gConfigTitleSequences.presets[preset].saves[i], MAX_PATH);
|
||||
|
||||
platform_file_copy(srcPath, path, false);
|
||||
}
|
||||
|
@ -181,8 +178,8 @@ void title_sequence_delete_preset(int preset)
|
|||
if (preset >= TITLE_SEQUENCE_DEFAULT_PRESETS && preset < gConfigTitleSequences.num_presets) {
|
||||
// Delete the folder
|
||||
utf8 path[MAX_PATH];
|
||||
platform_get_user_directory(path, "title sequences");
|
||||
strcat(path, gConfigTitleSequences.presets[preset].name);
|
||||
platform_get_user_directory(path, "title sequences", sizeof(path));
|
||||
safe_strcat_path(path, gConfigTitleSequences.presets[preset].name, MAX_PATH);
|
||||
if (!platform_directory_delete(path)) {
|
||||
log_error("Failed to delete directory: \"%s\"", path);
|
||||
}
|
||||
|
@ -209,10 +206,10 @@ void title_sequence_rename_preset(int preset, const char *newName)
|
|||
if (preset >= TITLE_SEQUENCE_DEFAULT_PRESETS && preset < gConfigTitleSequences.num_presets && filename_valid_characters(newName) && !title_sequence_name_exists(newName)) {
|
||||
// Rename the folder
|
||||
utf8 src[MAX_PATH], dest[MAX_PATH];
|
||||
platform_get_user_directory(src, "title sequences");
|
||||
platform_get_user_directory(dest, "title sequences");
|
||||
strcat(src, gConfigTitleSequences.presets[preset].name);
|
||||
strcat(dest, newName);
|
||||
platform_get_user_directory(src, "title sequences", sizeof(src));
|
||||
platform_get_user_directory(dest, "title sequences", sizeof(dest));
|
||||
safe_strcat_path(src, gConfigTitleSequences.presets[preset].name, sizeof(src));
|
||||
safe_strcat_path(dest, newName, sizeof(dest));
|
||||
platform_file_move(src, dest);
|
||||
|
||||
safe_strcpy(gConfigTitleSequences.presets[preset].name, newName, TITLE_SEQUENCE_NAME_SIZE);
|
||||
|
@ -228,20 +225,18 @@ void title_sequence_rename_preset(int preset, const char *newName)
|
|||
void title_sequence_add_save(int preset, const char *path, const char *newName)
|
||||
{
|
||||
utf8 newPath[MAX_PATH];
|
||||
char *extension = (char*)path_get_extension(newName);
|
||||
const char *extension = path_get_extension(newName);
|
||||
safe_strcpy(newPath, newName, MAX_PATH);
|
||||
if (_stricmp(extension, ".sv6") != 0 && _stricmp(extension, ".sc6") != 0)
|
||||
strcat(newPath, ".sv6");
|
||||
path_append_extension(newPath, ".sv6", MAX_PATH);
|
||||
if (preset >= TITLE_SEQUENCE_DEFAULT_PRESETS && preset < gConfigTitleSequences.num_presets && filename_valid_characters(newPath) && !title_sequence_save_exists(preset, newPath) && platform_file_exists(path)) {
|
||||
// Copy the save file
|
||||
char separator = platform_get_path_separator();
|
||||
platform_get_user_directory(newPath, "title sequences");
|
||||
strcat(newPath, gConfigTitleSequences.presets[preset].name);
|
||||
strncat(newPath, &separator, 1);
|
||||
strcat(newPath, newName);
|
||||
platform_get_user_directory(newPath, "title sequences", sizeof(newPath));
|
||||
safe_strcat_path(newPath, gConfigTitleSequences.presets[preset].name, sizeof(newPath));
|
||||
safe_strcat_path(newPath, newName, sizeof(newPath));
|
||||
// Add the appropriate extension if needed
|
||||
if (_stricmp(extension, ".sv6") != 0 && _stricmp(extension, ".sc6") != 0)
|
||||
strcat(newPath, ".sv6");
|
||||
path_append_extension(newPath, ".sv6", sizeof(newPath));
|
||||
platform_file_copy(path, newPath, false);
|
||||
|
||||
gConfigTitleSequences.presets[preset].num_saves++;
|
||||
|
@ -250,7 +245,7 @@ void title_sequence_add_save(int preset, const char *path, const char *newName)
|
|||
safe_strcpy(gConfigTitleSequences.presets[preset].saves[gConfigTitleSequences.presets[preset].num_saves - 1], newName, TITLE_SEQUENCE_MAX_SAVE_LENGTH);
|
||||
// Add the appropriate extension if needed
|
||||
if (_stricmp(extension, ".sv6") != 0 && _stricmp(extension, ".sc6") != 0)
|
||||
strcat(gConfigTitleSequences.presets[preset].saves[gConfigTitleSequences.presets[preset].num_saves - 1], ".sv6");
|
||||
path_append_extension(gConfigTitleSequences.presets[preset].saves[gConfigTitleSequences.presets[preset].num_saves - 1], ".sv6", TITLE_SEQUENCE_MAX_SAVE_LENGTH);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -258,12 +253,10 @@ void title_sequence_remove_save(int preset, int index)
|
|||
{
|
||||
if (preset >= TITLE_SEQUENCE_DEFAULT_PRESETS && preset < gConfigTitleSequences.num_presets && index >= 0 && index < gConfigTitleSequences.presets[preset].num_saves) {
|
||||
// Delete the save file
|
||||
char separator = platform_get_path_separator();
|
||||
utf8 path[MAX_PATH];
|
||||
platform_get_user_directory(path, "title sequences");
|
||||
strcat(path, gConfigTitleSequences.presets[preset].name);
|
||||
strncat(path, &separator, 1);
|
||||
strcat(path, gConfigTitleSequences.presets[preset].saves[index]);
|
||||
platform_get_user_directory(path, "title sequences", sizeof(path));
|
||||
safe_strcat_path(path, gConfigTitleSequences.presets[preset].name, sizeof(path));
|
||||
safe_strcat_path(path, gConfigTitleSequences.presets[preset].saves[index], sizeof(path));
|
||||
platform_file_delete(path);
|
||||
|
||||
// Remove all references to this save in the commands and decrement save indices
|
||||
|
@ -291,26 +284,23 @@ void title_sequence_rename_save(int preset, int index, const char *newName)
|
|||
filename_valid_characters(newName) && !title_sequence_save_exists(preset, newName)) {
|
||||
|
||||
// Rename the save file
|
||||
char separator = platform_get_path_separator();
|
||||
utf8 src[MAX_PATH], dest[MAX_PATH];
|
||||
platform_get_user_directory(src, "title sequences");
|
||||
platform_get_user_directory(dest, "title sequences");
|
||||
strcat(src, gConfigTitleSequences.presets[preset].name);
|
||||
strcat(dest, gConfigTitleSequences.presets[preset].name);
|
||||
strncat(src, &separator, 1);
|
||||
strncat(dest, &separator, 1);
|
||||
strcat(src, gConfigTitleSequences.presets[preset].saves[index]);
|
||||
strcat(dest, newName);
|
||||
platform_get_user_directory(src, "title sequences", sizeof(src));
|
||||
platform_get_user_directory(dest, "title sequences", sizeof(dest));
|
||||
safe_strcat_path(src, gConfigTitleSequences.presets[preset].name, sizeof(src));
|
||||
safe_strcat_path(dest, gConfigTitleSequences.presets[preset].name, sizeof(dest));
|
||||
safe_strcat_path(src, gConfigTitleSequences.presets[preset].saves[index], sizeof(src));
|
||||
safe_strcat_path(dest, newName, sizeof(dest));
|
||||
// Add the appropriate extension if needed
|
||||
char *extension = (char*)path_get_extension(newName);
|
||||
const char *extension = path_get_extension(newName);
|
||||
if (_stricmp(extension, ".sv6") != 0 && _stricmp(extension, ".sc6") != 0)
|
||||
strcat(dest, ".sv6");
|
||||
path_append_extension(dest, ".sv6", sizeof(dest));
|
||||
platform_file_move(src, dest);
|
||||
|
||||
safe_strcpy(gConfigTitleSequences.presets[preset].saves[index], newName, TITLE_SEQUENCE_MAX_SAVE_LENGTH);
|
||||
// Add the appropriate extension if needed
|
||||
if (_stricmp(extension, ".sv6") != 0 && _stricmp(extension, ".sc6") != 0)
|
||||
strcat(gConfigTitleSequences.presets[preset].saves[index], ".sv6");
|
||||
path_append_extension(gConfigTitleSequences.presets[preset].saves[index], ".sv6", TITLE_SEQUENCE_MAX_SAVE_LENGTH);
|
||||
title_sequence_save_preset_script(preset);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2470,7 +2470,7 @@ void window_start_textbox(rct_window *call_w, int call_widget, rct_string_id exi
|
|||
// Enter in the the text input buffer any existing
|
||||
// text.
|
||||
if (existing_text != STR_NONE)
|
||||
format_string(gTextBoxInput, existing_text, &existing_args);
|
||||
format_string(gTextBoxInput, 512, existing_text, &existing_args);
|
||||
|
||||
// In order to prevent strings that exceed the maxLength
|
||||
// from crashing the game.
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#pragma endregion
|
||||
|
||||
#include "../config.h"
|
||||
#include "../util/util.h"
|
||||
#include "currency.h"
|
||||
#include "string_ids.h"
|
||||
|
||||
|
@ -42,5 +43,5 @@ void currency_load_custom_currency_config()
|
|||
{
|
||||
CurrencyDescriptors[CURRENCY_CUSTOM].rate = gConfigGeneral.custom_currency_rate;
|
||||
CurrencyDescriptors[CURRENCY_CUSTOM].affix_unicode = gConfigGeneral.custom_currency_affix;
|
||||
strncpy(CurrencyDescriptors[CURRENCY_CUSTOM].symbol_unicode, gConfigGeneral.custom_currency_symbol, CURRENCY_SYMBOL_MAX_SIZE);
|
||||
safe_strcpy(CurrencyDescriptors[CURRENCY_CUSTOM].symbol_unicode, gConfigGeneral.custom_currency_symbol, CURRENCY_SYMBOL_MAX_SIZE);
|
||||
}
|
||||
|
|
|
@ -148,7 +148,6 @@ const char *language_get_string(rct_string_id id)
|
|||
|
||||
bool language_open(int id)
|
||||
{
|
||||
static const char *languagePath = "%s/language/%s.txt";
|
||||
char filename[MAX_PATH];
|
||||
char dataPath[MAX_PATH];
|
||||
|
||||
|
@ -156,13 +155,19 @@ bool language_open(int id)
|
|||
if (id == LANGUAGE_UNDEFINED)
|
||||
return false;
|
||||
|
||||
platform_get_openrct_data_path(dataPath);
|
||||
platform_get_openrct_data_path(dataPath, sizeof(dataPath));
|
||||
if (id != LANGUAGE_ENGLISH_UK) {
|
||||
sprintf(filename, languagePath, dataPath, LanguagesDescriptors[LANGUAGE_ENGLISH_UK].locale);
|
||||
safe_strcpy(filename, dataPath, MAX_PATH);
|
||||
safe_strcat_path(filename, "language", MAX_PATH);
|
||||
safe_strcat_path(filename, LanguagesDescriptors[LANGUAGE_ENGLISH_UK].locale, MAX_PATH);
|
||||
path_append_extension(filename, ".txt", MAX_PATH);
|
||||
_languageFallback = LanguagePackFactory::FromFile(LANGUAGE_ENGLISH_UK, filename);
|
||||
}
|
||||
|
||||
sprintf(filename, languagePath, dataPath, LanguagesDescriptors[id].locale);
|
||||
safe_strcpy(filename, dataPath, MAX_PATH);
|
||||
safe_strcat_path(filename, "language", MAX_PATH);
|
||||
safe_strcat_path(filename, LanguagesDescriptors[id].locale, MAX_PATH);
|
||||
path_append_extension(filename, ".txt", MAX_PATH);
|
||||
_languageCurrent = LanguagePackFactory::FromFile(id, filename);
|
||||
if (_languageCurrent != nullptr) {
|
||||
gCurrentLanguage = id;
|
||||
|
|
|
@ -488,254 +488,391 @@ void utf8_remove_formatting(utf8* string, bool allowColours) {
|
|||
|
||||
#pragma endregion
|
||||
|
||||
void format_string_part_from_raw(char **dest, const char *src, char **args);
|
||||
void format_string_part(char **dest, rct_string_id format, char **args);
|
||||
#define format_push_char_safe(C) { *(*dest)++ = (C); --(*size); }
|
||||
#define format_handle_overflow(X) if ((*size) <= (X)) { *(*dest) = '\0'; (*size) = 0; return; }
|
||||
#define format_push_char(C) { format_handle_overflow(1); format_push_char_safe(C); }
|
||||
|
||||
static void format_integer(char **dest, long long value)
|
||||
#define format_push_wrap(C) { *ncur = (C); if (ncur == (*dest)) ncur = nbegin; }
|
||||
#define reverse_string() while (nbegin < nend) { tmp = *nbegin; *nbegin++ = *nend; *nend-- = tmp; }
|
||||
|
||||
static void format_string_part_from_raw(char **dest, size_t *size, const char *src, char **args);
|
||||
static void format_string_part(char **dest, size_t *size, rct_string_id format, char **args);
|
||||
|
||||
static void format_append_string(char **dest, size_t *size, const utf8 *string) {
|
||||
if ((*size) == 0) return;
|
||||
size_t length = strlen(string);
|
||||
if (length < (*size)) {
|
||||
memcpy((*dest), string, length);
|
||||
(*dest) += length;
|
||||
} else {
|
||||
memcpy((*dest), string, (*size) - 1);
|
||||
(*dest) += (*size) - 1;
|
||||
*(*dest)++ = '\0';
|
||||
(*size) = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void format_append_string_n(char **dest, size_t *size, const utf8 *string, size_t maxlen) {
|
||||
if ((*size) == 0) return;
|
||||
size_t length = min(maxlen, strlen(string));
|
||||
if (length < (*size)) {
|
||||
memcpy((*dest), string, length);
|
||||
(*dest) += length;
|
||||
} else {
|
||||
memcpy((*dest), string, (*size) - 1);
|
||||
(*dest) += (*size) - 1;
|
||||
*(*dest)++ = '\0';
|
||||
(*size) = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void format_integer(char **dest, size_t *size, long long value)
|
||||
{
|
||||
int digit;
|
||||
char *dst = *dest;
|
||||
char *finish;
|
||||
char *nbegin, *nend, *ncur;
|
||||
char tmp;
|
||||
|
||||
if ((*size) == 0) return;
|
||||
|
||||
// Negative sign
|
||||
if (value < 0) {
|
||||
*dst++ = '-';
|
||||
format_push_char('-');
|
||||
value = -value;
|
||||
}
|
||||
|
||||
*dest = dst;
|
||||
|
||||
if (value == 0) {
|
||||
*dst++ = '0';
|
||||
} else {
|
||||
format_push_char('0');
|
||||
return;
|
||||
}
|
||||
|
||||
nbegin = (*dest);
|
||||
|
||||
// Right to left
|
||||
while (value > 0 && (*size) > 1) {
|
||||
digit = value % 10;
|
||||
value /= 10;
|
||||
|
||||
format_push_char_safe('0' + digit);
|
||||
}
|
||||
|
||||
if (value > 0) {
|
||||
ncur = nbegin;
|
||||
|
||||
while (value > 0) {
|
||||
digit = value % 10;
|
||||
value /= 10;
|
||||
|
||||
*dst++ = '0' + digit;
|
||||
format_push_wrap('0' + digit);
|
||||
}
|
||||
}
|
||||
finish = dst;
|
||||
|
||||
// Reverse first half of string
|
||||
nend = ncur - 1;
|
||||
reverse_string();
|
||||
|
||||
// Reverse second half of string
|
||||
nbegin = ncur;
|
||||
nend = (*dest) - 1;
|
||||
reverse_string();
|
||||
|
||||
format_push_char_safe('\0'); // truncate overflowed string
|
||||
} else {
|
||||
// Reverse string
|
||||
dst--;
|
||||
while (*dest < dst) {
|
||||
tmp = **dest;
|
||||
**dest = *dst;
|
||||
*dst = tmp;
|
||||
(*dest)++;
|
||||
dst--;
|
||||
nend = (*dest) - 1;
|
||||
reverse_string();
|
||||
}
|
||||
*dest = finish;
|
||||
}
|
||||
|
||||
static void format_comma_separated_integer(char **dest, long long value)
|
||||
static void format_comma_separated_integer(char **dest, size_t *size, long long value)
|
||||
{
|
||||
int digit, groupIndex;
|
||||
char *dst = *dest;
|
||||
char *finish;
|
||||
char *nbegin, *nend, *ncur;
|
||||
char tmp;
|
||||
const char *commaMark = language_get_string(STR_LOCALE_THOUSANDS_SEPARATOR);
|
||||
const char *ch;
|
||||
const char *ch = NULL;
|
||||
|
||||
if ((*size) == 0) return;
|
||||
|
||||
// Negative sign
|
||||
if (value < 0) {
|
||||
*dst++ = '-';
|
||||
format_push_char('-');
|
||||
value = -value;
|
||||
}
|
||||
|
||||
*dest = dst;
|
||||
|
||||
if (value == 0) {
|
||||
*dst++ = '0';
|
||||
} else {
|
||||
format_push_char('0');
|
||||
return;
|
||||
}
|
||||
|
||||
nbegin = *dest;
|
||||
|
||||
// Groups of three digits, right to left
|
||||
groupIndex = 0;
|
||||
while (value > 0 && (*size) > 1) {
|
||||
// Append group separator
|
||||
if (groupIndex == 3) {
|
||||
groupIndex = 0;
|
||||
ch = commaMark;
|
||||
}
|
||||
|
||||
if (ch != NULL ) {
|
||||
format_push_char_safe(*ch++);
|
||||
if (*ch == '\0') ch = NULL;
|
||||
} else {
|
||||
digit = value % 10;
|
||||
value /= 10;
|
||||
|
||||
format_push_char_safe('0' + digit);
|
||||
groupIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
if (value > 0) {
|
||||
ncur = nbegin;
|
||||
|
||||
while (value > 0) {
|
||||
// Append group separator
|
||||
if (groupIndex == 3) {
|
||||
groupIndex = 0;
|
||||
|
||||
ch = commaMark;
|
||||
while (*ch != 0) {
|
||||
*dst++ = *ch++;
|
||||
}
|
||||
}
|
||||
|
||||
if (ch != NULL ) {
|
||||
format_push_wrap(*ch++);
|
||||
if (*ch == '\0') ch = NULL;
|
||||
} else {
|
||||
digit = value % 10;
|
||||
value /= 10;
|
||||
|
||||
*dst++ = '0' + digit;
|
||||
format_push_wrap('0' + digit);
|
||||
groupIndex++;
|
||||
}
|
||||
}
|
||||
finish = dst;
|
||||
|
||||
// Reverse first half of string
|
||||
nend = ncur - 1;
|
||||
reverse_string();
|
||||
|
||||
// Reverse second half of string
|
||||
nbegin = ncur;
|
||||
nend = (*dest) - 1;
|
||||
reverse_string();
|
||||
|
||||
format_push_char_safe('\0'); // truncate overflowed string
|
||||
} else {
|
||||
// Reverse string
|
||||
dst--;
|
||||
while (*dest < dst) {
|
||||
tmp = **dest;
|
||||
**dest = *dst;
|
||||
*dst = tmp;
|
||||
(*dest)++;
|
||||
dst--;
|
||||
nend = *dest - 1;
|
||||
reverse_string();
|
||||
}
|
||||
*dest = finish;
|
||||
}
|
||||
|
||||
static void format_comma_separated_fixed_1dp(char **dest, long long value)
|
||||
static void format_comma_separated_fixed_1dp(char **dest, size_t *size, long long value)
|
||||
{
|
||||
int digit, groupIndex;
|
||||
char *dst = *dest;
|
||||
char *finish;
|
||||
char *nbegin, *nend, *ncur;
|
||||
char tmp;
|
||||
const char *commaMark = language_get_string(STR_LOCALE_THOUSANDS_SEPARATOR);
|
||||
const char *decimalMark = language_get_string(STR_LOCALE_DECIMAL_POINT);
|
||||
const char *ch;
|
||||
int zeroNeeded = 1;
|
||||
|
||||
if ((*size) == 0) return;
|
||||
|
||||
// Negative sign
|
||||
if (value < 0) {
|
||||
*dst++ = '-';
|
||||
format_push_char('-');
|
||||
value = -value;
|
||||
}
|
||||
|
||||
*dest = dst;
|
||||
nbegin = (*dest);
|
||||
|
||||
// In the case of buffers this small,
|
||||
// all of this would be truncated anyways.
|
||||
format_handle_overflow(1);
|
||||
if ((*size) > 2) {
|
||||
// One decimal place
|
||||
digit = value % 10;
|
||||
value /= 10;
|
||||
*dst++ = '0' + digit;
|
||||
format_push_char_safe('0' + digit);
|
||||
|
||||
ch = decimalMark;
|
||||
while (*ch != 0) {
|
||||
*dst++ = *ch++;
|
||||
}
|
||||
value /= 10;
|
||||
|
||||
if (value == 0) {
|
||||
*dst++ = '0';
|
||||
} else {
|
||||
// Groups of three digits, right to left
|
||||
groupIndex = 0;
|
||||
while (value > 0) {
|
||||
while ((zeroNeeded || value > 0) && (*size) > 1) {
|
||||
// Append group separator
|
||||
if (groupIndex == 3) {
|
||||
groupIndex = 0;
|
||||
|
||||
ch = commaMark;
|
||||
while (*ch != 0) {
|
||||
*dst++ = *ch++;
|
||||
}
|
||||
}
|
||||
|
||||
if (ch != NULL ) {
|
||||
format_push_char_safe(*ch++);
|
||||
if (*ch == '\0') ch = NULL;
|
||||
} else {
|
||||
zeroNeeded = 0;
|
||||
digit = value % 10;
|
||||
value /= 10;
|
||||
|
||||
*dst++ = '0' + digit;
|
||||
format_push_char_safe('0' + digit);
|
||||
groupIndex++;
|
||||
}
|
||||
}
|
||||
finish = dst;
|
||||
|
||||
if (zeroNeeded || value > 0) {
|
||||
ncur = nbegin;
|
||||
|
||||
while (zeroNeeded || value > 0) {
|
||||
// Append group separator
|
||||
if (groupIndex == 3) {
|
||||
groupIndex = 0;
|
||||
ch = commaMark;
|
||||
}
|
||||
|
||||
if (ch != NULL ) {
|
||||
format_push_wrap(*ch++);
|
||||
if (*ch == '\0') ch = NULL;
|
||||
} else {
|
||||
zeroNeeded = 0;
|
||||
digit = value % 10;
|
||||
value /= 10;
|
||||
|
||||
format_push_wrap('0' + digit);
|
||||
groupIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
// Reverse first half of string
|
||||
nend = ncur - 1;
|
||||
reverse_string();
|
||||
|
||||
// Reverse second half of string
|
||||
nbegin = ncur;
|
||||
nend = (*dest) - 1;
|
||||
reverse_string();
|
||||
|
||||
format_push_char_safe('\0'); // truncate overflowed string
|
||||
} else {
|
||||
// Reverse string
|
||||
dst--;
|
||||
while (*dest < dst) {
|
||||
tmp = **dest;
|
||||
**dest = *dst;
|
||||
*dst = tmp;
|
||||
(*dest)++;
|
||||
dst--;
|
||||
nend = *dest - 1;
|
||||
reverse_string();
|
||||
}
|
||||
*dest = finish;
|
||||
}
|
||||
|
||||
static void format_comma_separated_fixed_2dp(char **dest, long long value)
|
||||
static void format_comma_separated_fixed_2dp(char **dest, size_t *size, long long value)
|
||||
{
|
||||
int digit, groupIndex;
|
||||
char *dst = *dest;
|
||||
char *finish;
|
||||
char *nbegin, *nend, *ncur;
|
||||
char tmp;
|
||||
const char *commaMark = language_get_string(STR_LOCALE_THOUSANDS_SEPARATOR);
|
||||
const char *decimalMark = language_get_string(STR_LOCALE_DECIMAL_POINT);
|
||||
const char *ch;
|
||||
const char *ch = NULL;
|
||||
int zeroNeeded = 1;
|
||||
|
||||
if ((*size) == 0) return;
|
||||
|
||||
// Negative sign
|
||||
if (value < 0) {
|
||||
*dst++ = '-';
|
||||
format_push_char('-');
|
||||
value = -value;
|
||||
}
|
||||
|
||||
*dest = dst;
|
||||
nbegin = (*dest);
|
||||
|
||||
// In the case of buffers this small,
|
||||
// all of this would be truncated anyways.
|
||||
format_handle_overflow(1);
|
||||
if ((*size) < 3) {
|
||||
value /= 100;
|
||||
} else {
|
||||
// Two decimal places
|
||||
digit = value % 10;
|
||||
value /= 10;
|
||||
*dst++ = '0' + digit;
|
||||
format_push_char_safe('0' + digit);
|
||||
|
||||
digit = value % 10;
|
||||
value /= 10;
|
||||
*dst++ = '0' + digit;
|
||||
format_push_char_safe('0' + digit);
|
||||
|
||||
ch = decimalMark;
|
||||
while (*ch != 0) {
|
||||
*dst++ = *ch++;
|
||||
}
|
||||
|
||||
if (value == 0) {
|
||||
*dst++ = '0';
|
||||
} else {
|
||||
// Groups of three digits, right to left
|
||||
groupIndex = 0;
|
||||
while (value > 0) {
|
||||
while ((zeroNeeded || value > 0) && (*size) > 1) {
|
||||
// Append group separator
|
||||
if (groupIndex == 3) {
|
||||
groupIndex = 0;
|
||||
|
||||
ch = commaMark;
|
||||
while (*ch != 0) {
|
||||
*dst++ = *ch++;
|
||||
}
|
||||
}
|
||||
|
||||
if (ch != NULL ) {
|
||||
format_push_char_safe(*ch++);
|
||||
if (*ch == '\0') ch = NULL;
|
||||
} else {
|
||||
zeroNeeded = 0;
|
||||
digit = value % 10;
|
||||
value /= 10;
|
||||
|
||||
*dst++ = '0' + digit;
|
||||
format_push_char_safe('0' + digit);
|
||||
groupIndex++;
|
||||
}
|
||||
}
|
||||
finish = dst;
|
||||
|
||||
if (zeroNeeded || value > 0) {
|
||||
ncur = nbegin;
|
||||
|
||||
while (zeroNeeded || value > 0) {
|
||||
// Append group separator
|
||||
if (groupIndex == 3) {
|
||||
groupIndex = 0;
|
||||
ch = commaMark;
|
||||
}
|
||||
|
||||
if (ch != NULL ) {
|
||||
format_push_wrap(*ch++);
|
||||
if (*ch == '\0') ch = NULL;
|
||||
} else {
|
||||
zeroNeeded = 0;
|
||||
digit = value % 10;
|
||||
value /= 10;
|
||||
|
||||
format_push_wrap('0' + digit);
|
||||
groupIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
// Reverse first half of string
|
||||
nend = ncur - 1;
|
||||
reverse_string();
|
||||
|
||||
// Reverse second half of string
|
||||
nbegin = ncur;
|
||||
nend = (*dest) - 1;
|
||||
reverse_string();
|
||||
|
||||
format_push_char_safe('\0'); // truncate overflowed string
|
||||
} else {
|
||||
// Reverse string
|
||||
dst--;
|
||||
while (*dest < dst) {
|
||||
tmp = **dest;
|
||||
**dest = *dst;
|
||||
*dst = tmp;
|
||||
(*dest)++;
|
||||
dst--;
|
||||
nend = *dest - 1;
|
||||
reverse_string();
|
||||
}
|
||||
*dest = finish;
|
||||
}
|
||||
|
||||
static void format_currency(char **dest, long long value)
|
||||
static void format_currency(char **dest, size_t *size, long long value)
|
||||
{
|
||||
if ((*size) == 0) return;
|
||||
|
||||
const currency_descriptor *currencyDesc = &CurrencyDescriptors[gConfigGeneral.currency_format];
|
||||
|
||||
int rate = currencyDesc->rate;
|
||||
value *= rate;
|
||||
value *= currencyDesc->rate;
|
||||
|
||||
// Negative sign
|
||||
if (value < 0) {
|
||||
// Round the value away from zero
|
||||
value = (value - 99) / 100;
|
||||
*(*dest)++ = '-';
|
||||
format_push_char('-');
|
||||
value = -value;
|
||||
}
|
||||
else{
|
||||
|
||||
//Round the value away from zero
|
||||
value = (value + 99) / 100;
|
||||
}
|
||||
|
||||
// Currency symbol
|
||||
const utf8 *symbol = currencyDesc->symbol_unicode;
|
||||
|
@ -746,22 +883,22 @@ static void format_currency(char **dest, long long value)
|
|||
}
|
||||
|
||||
// Prefix
|
||||
if (affix == CURRENCY_PREFIX) {
|
||||
safe_strcpy(*dest, symbol, CURRENCY_SYMBOL_MAX_SIZE);
|
||||
*dest += strlen(*dest);
|
||||
}
|
||||
if (affix == CURRENCY_PREFIX)
|
||||
format_append_string(dest, size, symbol);
|
||||
if ((*size) == 0) return;
|
||||
|
||||
format_comma_separated_integer(dest, value);
|
||||
format_comma_separated_integer(dest, size, value);
|
||||
if ((*size) == 0) return;
|
||||
|
||||
// Currency symbol suffix
|
||||
if (affix == CURRENCY_SUFFIX) {
|
||||
safe_strcpy(*dest, symbol, CURRENCY_SYMBOL_MAX_SIZE);
|
||||
*dest += strlen(*dest);
|
||||
}
|
||||
if (affix == CURRENCY_SUFFIX)
|
||||
format_append_string(dest, size, symbol);
|
||||
}
|
||||
|
||||
static void format_currency_2dp(char **dest, long long value)
|
||||
static void format_currency_2dp(char **dest, size_t *size, long long value)
|
||||
{
|
||||
if ((*size) == 0) return;
|
||||
|
||||
const currency_descriptor *currencyDesc = &CurrencyDescriptors[gConfigGeneral.currency_format];
|
||||
|
||||
int rate = currencyDesc->rate;
|
||||
|
@ -769,7 +906,7 @@ static void format_currency_2dp(char **dest, long long value)
|
|||
|
||||
// Negative sign
|
||||
if (value < 0) {
|
||||
*(*dest)++ = '-';
|
||||
format_push_char('-');
|
||||
value = -value;
|
||||
}
|
||||
|
||||
|
@ -782,34 +919,31 @@ static void format_currency_2dp(char **dest, long long value)
|
|||
}
|
||||
|
||||
// Prefix
|
||||
if (affix == CURRENCY_PREFIX) {
|
||||
safe_strcpy(*dest, symbol, CURRENCY_SYMBOL_MAX_SIZE);
|
||||
*dest += strlen(*dest);
|
||||
}
|
||||
if (affix == CURRENCY_PREFIX)
|
||||
format_append_string(dest, size, symbol);
|
||||
if ((*size) == 0) return;
|
||||
|
||||
// Drop the pennies for "large" currencies
|
||||
if (rate >= 100) {
|
||||
format_comma_separated_integer(dest, value / 100);
|
||||
format_comma_separated_integer(dest, size, value / 100);
|
||||
} else {
|
||||
format_comma_separated_fixed_2dp(dest, value);
|
||||
format_comma_separated_fixed_2dp(dest, size, value);
|
||||
}
|
||||
if ((*size) == 0) return;
|
||||
|
||||
// Currency symbol suffix
|
||||
if (affix == CURRENCY_SUFFIX) {
|
||||
safe_strcpy(*dest, symbol, CURRENCY_SYMBOL_MAX_SIZE);
|
||||
*dest += strlen(*dest);
|
||||
}
|
||||
if (affix == CURRENCY_SUFFIX)
|
||||
format_append_string(dest, size, symbol);
|
||||
}
|
||||
|
||||
static void format_date(char **dest, uint16 value)
|
||||
static void format_date(char **dest, size_t *size, uint16 value)
|
||||
{
|
||||
uint16 args[] = { date_get_month(value), date_get_year(value) + 1 };
|
||||
uint16 *argsRef = args;
|
||||
format_string_part(dest, STR_DATE_FORMAT_MY, (char**)&argsRef);
|
||||
(*dest)--;
|
||||
format_string_part(dest, size, STR_DATE_FORMAT_MY, (char**)&argsRef);
|
||||
}
|
||||
|
||||
static void format_length(char **dest, sint16 value)
|
||||
static void format_length(char **dest, size_t *size, sint16 value)
|
||||
{
|
||||
rct_string_id stringId = STR_UNIT_SUFFIX_METRES;
|
||||
|
||||
|
@ -819,11 +953,10 @@ static void format_length(char **dest, sint16 value)
|
|||
}
|
||||
|
||||
sint16 *argRef = &value;
|
||||
format_string_part(dest, stringId, (char**)&argRef);
|
||||
(*dest)--;
|
||||
format_string_part(dest, size, stringId, (char**)&argRef);
|
||||
}
|
||||
|
||||
static void format_velocity(char **dest, uint16 value)
|
||||
static void format_velocity(char **dest, size_t *size, uint16 value)
|
||||
{
|
||||
rct_string_id stringId;
|
||||
|
||||
|
@ -842,8 +975,7 @@ static void format_velocity(char **dest, uint16 value)
|
|||
}
|
||||
|
||||
uint16 *argRef = &value;
|
||||
format_string_part(dest, stringId, (char**)&argRef);
|
||||
(*dest)--;
|
||||
format_string_part(dest, size, stringId, (char**)&argRef);
|
||||
}
|
||||
|
||||
static const rct_string_id DurationFormats[][2] = {
|
||||
|
@ -852,7 +984,7 @@ static const rct_string_id DurationFormats[][2] = {
|
|||
{STR_DURATION_MINS_SEC, STR_DURATION_MINS_SECS},
|
||||
};
|
||||
|
||||
static void format_duration(char **dest, uint16 value)
|
||||
static void format_duration(char **dest, size_t *size, uint16 value)
|
||||
{
|
||||
uint16 minutes = value / 60;
|
||||
uint16 seconds = value % 60;
|
||||
|
@ -876,8 +1008,7 @@ static void format_duration(char **dest, uint16 value)
|
|||
|
||||
rct_string_id stringId = DurationFormats[minuteIndex][secondsIndex];
|
||||
|
||||
format_string_part(dest, stringId, (char**)&argsRef);
|
||||
(*dest)--;
|
||||
format_string_part(dest, size, stringId, (char**)&argsRef);
|
||||
}
|
||||
|
||||
static const rct_string_id RealtimeFormats[][2] = {
|
||||
|
@ -886,7 +1017,7 @@ static const rct_string_id RealtimeFormats[][2] = {
|
|||
{STR_REALTIME_HOURS_MIN, STR_REALTIME_HOURS_MINS},
|
||||
};
|
||||
|
||||
static void format_realtime(char ** dest, uint16 value)
|
||||
static void format_realtime(char **dest, size_t *size, uint16 value)
|
||||
{
|
||||
uint16 hours = value / 60;
|
||||
uint16 minutes = value % 60;
|
||||
|
@ -910,70 +1041,71 @@ static void format_realtime(char ** dest, uint16 value)
|
|||
|
||||
rct_string_id stringId = RealtimeFormats[hourIndex][minuteIndex];
|
||||
|
||||
format_string_part(dest, stringId, (char**)&argsRef);
|
||||
(*dest)--;
|
||||
format_string_part(dest, size, stringId, (char**)&argsRef);
|
||||
}
|
||||
|
||||
static void format_string_code(unsigned int format_code, char **dest, char **args)
|
||||
static void format_string_code(unsigned int format_code, char **dest, size_t *size, char **args)
|
||||
{
|
||||
intptr_t value;
|
||||
|
||||
if ((*size) == 0) return;
|
||||
|
||||
switch (format_code) {
|
||||
case FORMAT_COMMA32:
|
||||
// Pop argument
|
||||
value = *((sint32*)*args);
|
||||
*args += 4;
|
||||
|
||||
format_comma_separated_integer(dest, value);
|
||||
format_comma_separated_integer(dest, size, value);
|
||||
break;
|
||||
case FORMAT_INT32:
|
||||
// Pop argument
|
||||
value = *((sint32*)*args);
|
||||
*args += 4;
|
||||
|
||||
format_integer(dest, value);
|
||||
format_integer(dest, size, value);
|
||||
break;
|
||||
case FORMAT_COMMA2DP32:
|
||||
// Pop argument
|
||||
value = *((sint32*)*args);
|
||||
*args += 4;
|
||||
|
||||
format_comma_separated_fixed_2dp(dest, value);
|
||||
format_comma_separated_fixed_2dp(dest, size, value);
|
||||
break;
|
||||
case FORMAT_COMMA1DP16:
|
||||
// Pop argument
|
||||
value = *((sint16*)*args);
|
||||
*args += 2;
|
||||
|
||||
format_comma_separated_fixed_1dp(dest, value);
|
||||
format_comma_separated_fixed_1dp(dest, size, value);
|
||||
break;
|
||||
case FORMAT_COMMA16:
|
||||
// Pop argument
|
||||
value = *((sint16*)*args);
|
||||
*args += 2;
|
||||
|
||||
format_comma_separated_integer(dest, value);
|
||||
format_comma_separated_integer(dest, size, value);
|
||||
break;
|
||||
case FORMAT_UINT16:
|
||||
// Pop argument
|
||||
value = *((uint16*)*args);
|
||||
*args += 2;
|
||||
|
||||
format_integer(dest, value);
|
||||
format_integer(dest, size, value);
|
||||
break;
|
||||
case FORMAT_CURRENCY2DP:
|
||||
// Pop argument
|
||||
value = *((sint32*)*args);
|
||||
*args += 4;
|
||||
|
||||
format_currency_2dp(dest, value);
|
||||
format_currency_2dp(dest, size, value);
|
||||
break;
|
||||
case FORMAT_CURRENCY:
|
||||
// Pop argument
|
||||
value = *((sint32*)*args);
|
||||
*args += 4;
|
||||
|
||||
format_currency(dest, value);
|
||||
format_currency(dest, size, value);
|
||||
break;
|
||||
case FORMAT_STRINGID:
|
||||
case FORMAT_STRINGID2:
|
||||
|
@ -981,40 +1113,36 @@ static void format_string_code(unsigned int format_code, char **dest, char **arg
|
|||
value = *((uint16*)*args);
|
||||
*args += 2;
|
||||
|
||||
format_string_part(dest, (rct_string_id)value, args);
|
||||
(*dest)--;
|
||||
format_string_part(dest, size, (rct_string_id)value, args);
|
||||
break;
|
||||
case FORMAT_STRING:
|
||||
// Pop argument
|
||||
value = *((uintptr_t*)*args);
|
||||
*args += sizeof(uintptr_t);
|
||||
|
||||
if (value != 0) {
|
||||
strcpy(*dest, (char*)value);
|
||||
*dest += strlen(*dest);
|
||||
}
|
||||
if (value != 0)
|
||||
format_append_string(dest, size, (char*)value);
|
||||
break;
|
||||
case FORMAT_MONTHYEAR:
|
||||
// Pop argument
|
||||
value = *((uint16*)*args);
|
||||
*args += 2;
|
||||
|
||||
format_date(dest, (uint16)value);
|
||||
format_date(dest, size, (uint16)value);
|
||||
break;
|
||||
case FORMAT_MONTH:
|
||||
// Pop argument
|
||||
value = *((uint16*)*args);
|
||||
*args += 2;
|
||||
|
||||
strcpy(*dest, language_get_string(DateGameMonthNames[date_get_month((int)value)]));
|
||||
*dest += strlen(*dest);
|
||||
format_append_string(dest, size, language_get_string(DateGameMonthNames[date_get_month((int)value)]));
|
||||
break;
|
||||
case FORMAT_VELOCITY:
|
||||
// Pop argument
|
||||
value = *((sint16*)*args);
|
||||
*args += 2;
|
||||
|
||||
format_velocity(dest, (uint16)value);
|
||||
format_velocity(dest, size, (uint16)value);
|
||||
break;
|
||||
case FORMAT_POP16:
|
||||
*args += 2;
|
||||
|
@ -1027,76 +1155,84 @@ static void format_string_code(unsigned int format_code, char **dest, char **arg
|
|||
value = *((uint16*)*args);
|
||||
*args += 2;
|
||||
|
||||
format_duration(dest, (uint16)value);
|
||||
format_duration(dest, size, (uint16)value);
|
||||
break;
|
||||
case FORMAT_REALTIME:
|
||||
// Pop argument
|
||||
value = *((uint16*)*args);
|
||||
*args += 2;
|
||||
|
||||
format_realtime(dest, (uint16)value);
|
||||
format_realtime(dest, size, (uint16)value);
|
||||
break;
|
||||
case FORMAT_LENGTH:
|
||||
// Pop argument
|
||||
value = *((sint16*)*args);
|
||||
*args += 2;
|
||||
|
||||
format_length(dest, (sint16)value);
|
||||
format_length(dest, size, (sint16)value);
|
||||
break;
|
||||
case FORMAT_SPRITE:
|
||||
// Pop argument
|
||||
value = *((uint32*)*args);
|
||||
*args += 4;
|
||||
|
||||
*(*dest)++ = 23;
|
||||
format_handle_overflow(1 + sizeof(intptr_t));
|
||||
|
||||
format_push_char_safe('\x17');
|
||||
*((intptr_t*)(*dest)) = value;
|
||||
*dest += 4;
|
||||
(*dest) += sizeof(intptr_t);
|
||||
(*size) -= sizeof(intptr_t);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void format_string_part_from_raw(utf8 **dest, const utf8 *src, char **args)
|
||||
static void format_string_part_from_raw(utf8 **dest, size_t *size, const utf8 *src, char **args)
|
||||
{
|
||||
unsigned int code;
|
||||
while (1) {
|
||||
while (*size > 1) {
|
||||
code = utf8_get_next(src, &src);
|
||||
if (code < ' ') {
|
||||
if (code == 0) {
|
||||
*(*dest)++ = code;
|
||||
break;
|
||||
} else if (code <= 4) {
|
||||
*(*dest)++ = code;
|
||||
*(*dest)++ = *src++;
|
||||
format_handle_overflow(2);
|
||||
format_push_char_safe(code);
|
||||
format_push_char_safe(*src++);
|
||||
} else if (code <= 16) {
|
||||
*(*dest)++ = code;
|
||||
format_handle_overflow(1);
|
||||
format_push_char_safe(code);
|
||||
} else if (code <= 22) {
|
||||
*(*dest)++ = code;
|
||||
*(*dest)++ = *src++;
|
||||
*(*dest)++ = *src++;
|
||||
format_handle_overflow(3);
|
||||
format_push_char_safe(code);
|
||||
format_push_char_safe(*src++);
|
||||
format_push_char_safe(*src++);
|
||||
} else {
|
||||
*(*dest)++ = code;
|
||||
*(*dest)++ = *src++;
|
||||
*(*dest)++ = *src++;
|
||||
*(*dest)++ = *src++;
|
||||
*(*dest)++ = *src++;
|
||||
format_handle_overflow(5);
|
||||
format_push_char_safe(code);
|
||||
format_push_char_safe(*src++);
|
||||
format_push_char_safe(*src++);
|
||||
format_push_char_safe(*src++);
|
||||
format_push_char_safe(*src++);
|
||||
}
|
||||
} else if (code <= 'z') {
|
||||
*(*dest)++ = code;
|
||||
format_push_char(code);
|
||||
} else if (code < FORMAT_COLOUR_CODE_START || code == FORMAT_COMMA1DP16) {
|
||||
format_string_code(code, dest, args);
|
||||
format_string_code(code, dest, size, args);
|
||||
} else {
|
||||
format_handle_overflow((size_t) utf8_get_codepoint_length(code));
|
||||
*dest = utf8_write_codepoint(*dest, code);
|
||||
}
|
||||
}
|
||||
*(*dest) = '\0';
|
||||
}
|
||||
|
||||
void format_string_part(utf8 **dest, rct_string_id format, char **args)
|
||||
static void format_string_part(utf8 **dest, size_t *size, rct_string_id format, char **args)
|
||||
{
|
||||
if (format == STR_NONE) {
|
||||
**dest = 0;
|
||||
*(*dest) = '\0';
|
||||
} else if (format < 0x8000) {
|
||||
// Language string
|
||||
format_string_part_from_raw(dest, language_get_string(format), args);
|
||||
format_string_part_from_raw(dest, size, language_get_string(format), args);
|
||||
} else if (format < 0x9000) {
|
||||
// Custom string
|
||||
format -= 0x8000;
|
||||
|
@ -1105,16 +1241,18 @@ void format_string_part(utf8 **dest, rct_string_id format, char **args)
|
|||
*args += (format & 0xC00) >> 9;
|
||||
format &= ~0xC00;
|
||||
|
||||
safe_strcpy(*dest, &gUserStrings[format * 32], 32);
|
||||
*dest = strchr(*dest, 0) + 1;
|
||||
format_append_string_n(dest, size, &gUserStrings[format * 32], 32);
|
||||
if ((*size) > 0) *(*dest) = '\0';
|
||||
} else if (format < 0xE000) {
|
||||
// Real name
|
||||
format -= -0xA000;
|
||||
sprintf(*dest, "%s %c.",
|
||||
real_names[format % countof(real_names)],
|
||||
real_name_initials[(format >> 10) % countof(real_name_initials)]
|
||||
);
|
||||
*dest = strchr(*dest, 0) + 1;
|
||||
|
||||
format_append_string(dest, size, real_names[format % countof(real_names)]);
|
||||
if ((*size) == 0) return;
|
||||
format_push_char(' ');
|
||||
format_push_char(real_name_initials[(format >> 10) % countof(real_name_initials)]);
|
||||
format_push_char('.');
|
||||
*(*dest) = '\0';
|
||||
|
||||
*args += 4;
|
||||
} else {
|
||||
|
@ -1131,14 +1269,22 @@ void format_string_part(utf8 **dest, rct_string_id format, char **args)
|
|||
* format (ax)
|
||||
* args (ecx)
|
||||
*/
|
||||
void format_string(utf8 *dest, rct_string_id format, void *args)
|
||||
void format_string(utf8 *dest, size_t size, rct_string_id format, void *args)
|
||||
{
|
||||
format_string_part(&dest, format, (char**)&args);
|
||||
utf8 *end = dest;
|
||||
size_t left = size;
|
||||
format_string_part(&end, &left, format, (char**)&args);
|
||||
if (left == 0)
|
||||
log_warning("Truncating formatted string \"%s\" to %d bytes.", dest, size);
|
||||
}
|
||||
|
||||
void format_string_raw(utf8 *dest, utf8 *src, void *args)
|
||||
void format_string_raw(utf8 *dest, size_t size, utf8 *src, void *args)
|
||||
{
|
||||
format_string_part_from_raw(&dest, src, (char**)&args);
|
||||
utf8 *end = dest;
|
||||
size_t left = size;
|
||||
format_string_part_from_raw(&end, &left, src, (char**)&args);
|
||||
if (left == 0)
|
||||
log_warning("Truncating formatted string \"%s\" to %d bytes.", dest, size);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1148,12 +1294,16 @@ void format_string_raw(utf8 *dest, utf8 *src, void *args)
|
|||
* format (ax)
|
||||
* args (ecx)
|
||||
*/
|
||||
void format_string_to_upper(utf8 *dest, rct_string_id format, void *args)
|
||||
void format_string_to_upper(utf8 *dest, size_t size, rct_string_id format, void *args)
|
||||
{
|
||||
format_string(dest, format, args);
|
||||
utf8 *end;
|
||||
size_t left;
|
||||
format_string_part(&end, &left, format, args);
|
||||
if (left == 0)
|
||||
log_warning("Truncating formatted string \"%s\" to %d bytes.", dest, size);
|
||||
|
||||
char *ch = dest;
|
||||
while (*ch != 0) {
|
||||
while (ch < end) {
|
||||
*ch = toupper(*ch);
|
||||
ch++;
|
||||
}
|
||||
|
|
|
@ -31,9 +31,9 @@ int font_sprite_get_codepoint_offset(int codepoint);
|
|||
int utf8_get_format_code_arg_length(int codepoint);
|
||||
void utf8_remove_formatting(utf8* string, bool allowColours);
|
||||
|
||||
void format_string(char *dest, rct_string_id format, void *args);
|
||||
void format_string_raw(char *dest, char *src, void *args);
|
||||
void format_string_to_upper(char *dest, rct_string_id format, void *args);
|
||||
void format_string(char *dest, size_t size, rct_string_id format, void *args);
|
||||
void format_string_raw(char *dest, size_t size, char *src, void *args);
|
||||
void format_string_to_upper(char *dest, size_t size, rct_string_id format, void *args);
|
||||
void generate_string_file();
|
||||
utf8 *get_string_end(const utf8 *text);
|
||||
size_t get_string_size(const utf8 *text);
|
||||
|
|
|
@ -2563,7 +2563,7 @@ enum {
|
|||
STR_ERR_REASON_NOT_ENOUGH_MEMORY = 3162,
|
||||
// STR_3163 :Installing new data:
|
||||
STR_OBJECT_SELECTION_SELECTION_SIZE = 3164,
|
||||
STR_PLACEHOLDER = 3165,
|
||||
// STR_PLACEHOLDER = 3165, <placeholder strings are unsafe>
|
||||
// STR_3166 :{BLACK}(ID:
|
||||
// STR_3167 :{WINDOW_COLOUR_2}Includes: {BLACK}{COMMA16} objects
|
||||
STR_OBJECT_SELECTION_DESCRIPTION_SCENARIO_TEXT = 3168,
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "../localisation/localisation.h"
|
||||
#include "../peep/peep.h"
|
||||
#include "../ride/ride.h"
|
||||
#include "../util/util.h"
|
||||
#include "../world/park.h"
|
||||
#include "../world/sprite.h"
|
||||
#include "finance.h"
|
||||
|
@ -202,7 +203,7 @@ void finance_init() {
|
|||
gScenarioCompletedCompanyValue = MONEY32_UNDEFINED;
|
||||
gTotalAdmissions = 0;
|
||||
gTotalIncomeFromAdmissions = 0;
|
||||
strcpy(gScenarioCompletedBy, "?");
|
||||
safe_strcpy(gScenarioCompletedBy, "?", sizeof(gScenarioCompletedBy));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -282,7 +282,7 @@ void news_item_add_to_queue(uint8 type, rct_string_id string_id, uint32 assoc)
|
|||
utf8 buffer[256];
|
||||
void *args = gCommonFormatArgs;
|
||||
|
||||
format_string(buffer, string_id, args); // overflows possible?
|
||||
format_string(buffer, 256, string_id, args); // overflows possible?
|
||||
news_item_add_to_queue_raw(type, buffer, assoc);
|
||||
}
|
||||
|
||||
|
|
|
@ -191,7 +191,7 @@ void NetworkConnection::SetLastDisconnectReason(const utf8 * src)
|
|||
void NetworkConnection::SetLastDisconnectReason(const rct_string_id string_id, void *args)
|
||||
{
|
||||
char buffer[NETWORK_DISCONNECT_REASON_BUFFER_SIZE];
|
||||
format_string(buffer, string_id, args);
|
||||
format_string(buffer, NETWORK_DISCONNECT_REASON_BUFFER_SIZE, string_id, args);
|
||||
SetLastDisconnectReason(buffer);
|
||||
}
|
||||
|
||||
|
|
|
@ -337,7 +337,7 @@ std::string NetworkKey::PublicKeyHash()
|
|||
for (unsigned int i = 0; i < digest_size; i++)
|
||||
{
|
||||
char buf[3];
|
||||
sprintf(buf, "%02x", digest[i]);
|
||||
snprintf(buf, 3, "%02x", digest[i]);
|
||||
digest_out.append(buf);
|
||||
}
|
||||
return digest_out;
|
||||
|
|
|
@ -248,7 +248,7 @@ NetworkUser * NetworkUserManager::GetOrAddUser(const std::string &hash)
|
|||
|
||||
void NetworkUserManager::GetStorePath(utf8 * buffer, size_t bufferSize)
|
||||
{
|
||||
platform_get_user_directory(buffer, nullptr);
|
||||
platform_get_user_directory(buffer, nullptr, bufferSize);
|
||||
Path::Append(buffer, bufferSize, USER_STORE_FILENAME);
|
||||
}
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ void http_init()
|
|||
|
||||
#ifdef __WINDOWS__
|
||||
// Find SSL certificate bundle
|
||||
platform_get_exe_path(_caBundlePath);
|
||||
platform_get_exe_path(_caBundlePath, sizeof(_caBundlePath));
|
||||
Path::Append(_caBundlePath, sizeof(_caBundlePath), DEFAULT_CA_BUNDLE_PATH);
|
||||
if (!platform_file_exists(_caBundlePath)) {
|
||||
String::Set(_caBundlePath, sizeof(_caBundlePath), DEFAULT_CA_BUNDLE_PATH);
|
||||
|
|
|
@ -405,7 +405,7 @@ void Network::UpdateClient()
|
|||
{
|
||||
_lastConnectStatus = SOCKET_STATUS_RESOLVING;
|
||||
char str_resolving[256];
|
||||
format_string(str_resolving, STR_MULTIPLAYER_RESOLVING, NULL);
|
||||
format_string(str_resolving, 256, STR_MULTIPLAYER_RESOLVING, NULL);
|
||||
window_network_status_open(str_resolving, []() -> void {
|
||||
gNetwork.Close();
|
||||
});
|
||||
|
@ -418,7 +418,7 @@ void Network::UpdateClient()
|
|||
{
|
||||
_lastConnectStatus = SOCKET_STATUS_CONNECTING;
|
||||
char str_connecting[256];
|
||||
format_string(str_connecting, STR_MULTIPLAYER_CONNECTING, NULL);
|
||||
format_string(str_connecting, 256, STR_MULTIPLAYER_CONNECTING, NULL);
|
||||
window_network_status_open(str_connecting, []() -> void {
|
||||
gNetwork.Close();
|
||||
});
|
||||
|
@ -432,7 +432,7 @@ void Network::UpdateClient()
|
|||
server_connection.ResetLastPacketTime();
|
||||
Client_Send_TOKEN();
|
||||
char str_authenticating[256];
|
||||
format_string(str_authenticating, STR_MULTIPLAYER_AUTHENTICATING, NULL);
|
||||
format_string(str_authenticating, 256, STR_MULTIPLAYER_AUTHENTICATING, NULL);
|
||||
window_network_status_open(str_authenticating, []() -> void {
|
||||
gNetwork.Close();
|
||||
});
|
||||
|
@ -464,9 +464,9 @@ void Network::UpdateClient()
|
|||
|
||||
if (server_connection.GetLastDisconnectReason()) {
|
||||
const char * disconnect_reason = server_connection.GetLastDisconnectReason();
|
||||
format_string(str_disconnected, STR_MULTIPLAYER_DISCONNECTED_WITH_REASON, &disconnect_reason);
|
||||
format_string(str_disconnected, 256, STR_MULTIPLAYER_DISCONNECTED_WITH_REASON, &disconnect_reason);
|
||||
} else {
|
||||
format_string(str_disconnected, STR_MULTIPLAYER_DISCONNECTED_NO_REASON, NULL);
|
||||
format_string(str_disconnected, 256, STR_MULTIPLAYER_DISCONNECTED_NO_REASON, NULL);
|
||||
}
|
||||
|
||||
window_network_status_open(str_disconnected, NULL);
|
||||
|
@ -479,7 +479,7 @@ void Network::UpdateClient()
|
|||
if (!_desynchronised && !CheckSRAND(gCurrentTicks, gScenarioSrand0)) {
|
||||
_desynchronised = true;
|
||||
char str_desync[256];
|
||||
format_string(str_desync, STR_MULTIPLAYER_DESYNC, NULL);
|
||||
format_string(str_desync, 256, STR_MULTIPLAYER_DESYNC, NULL);
|
||||
window_network_status_open(str_desync, NULL);
|
||||
if (!gConfigNetwork.stay_connected) {
|
||||
Close();
|
||||
|
@ -534,8 +534,8 @@ const char* Network::FormatChat(NetworkPlayer* fromplayer, const char* text)
|
|||
if (fromplayer) {
|
||||
lineCh = utf8_write_codepoint(lineCh, FORMAT_OUTLINE);
|
||||
lineCh = utf8_write_codepoint(lineCh, FORMAT_BABYBLUE);
|
||||
safe_strcpy(lineCh, (const char*)fromplayer->name.c_str(), fromplayer->name.size() + 1);
|
||||
strcat(lineCh, ": ");
|
||||
safe_strcpy(lineCh, (const char *) fromplayer->name.c_str(), sizeof(formatted) - (lineCh - formatted));
|
||||
safe_strcat(lineCh, ": ", sizeof(formatted) - (lineCh - formatted));
|
||||
lineCh = strchr(lineCh, '\0');
|
||||
}
|
||||
lineCh = utf8_write_codepoint(lineCh, FORMAT_OUTLINE);
|
||||
|
@ -582,7 +582,7 @@ void Network::KickPlayer(int playerId)
|
|||
// Disconnect the client gracefully
|
||||
(*it)->SetLastDisconnectReason(STR_MULTIPLAYER_KICKED);
|
||||
char str_disconnect_msg[256];
|
||||
format_string(str_disconnect_msg, STR_MULTIPLAYER_KICKED_REASON, NULL);
|
||||
format_string(str_disconnect_msg, 256, STR_MULTIPLAYER_KICKED_REASON, NULL);
|
||||
Server_Send_SETDISCONNECTMSG(*(*it), str_disconnect_msg);
|
||||
(*it)->Socket->Disconnect();
|
||||
break;
|
||||
|
@ -695,8 +695,8 @@ void Network::SaveGroups()
|
|||
if (GetMode() == NETWORK_MODE_SERVER) {
|
||||
utf8 path[MAX_PATH];
|
||||
|
||||
platform_get_user_directory(path, NULL);
|
||||
strcat(path, "groups.json");
|
||||
platform_get_user_directory(path, NULL, sizeof(path));
|
||||
safe_strcat_path(path, "groups.json", sizeof(path));
|
||||
|
||||
json_t * jsonGroupsCfg = json_object();
|
||||
json_t * jsonGroups = json_array();
|
||||
|
@ -748,8 +748,8 @@ void Network::LoadGroups()
|
|||
|
||||
utf8 path[MAX_PATH];
|
||||
|
||||
platform_get_user_directory(path, NULL);
|
||||
strcat(path, "groups.json");
|
||||
platform_get_user_directory(path, NULL, sizeof(path));
|
||||
safe_strcat_path(path, "groups.json", sizeof(path));
|
||||
|
||||
json_t * json = nullptr;
|
||||
if (platform_file_exists(path)) {
|
||||
|
@ -790,7 +790,7 @@ void Network::BeginChatLog()
|
|||
strftime(filename, sizeof(filename), "%Y%m%d-%H%M%S.txt", tmInfo);
|
||||
|
||||
utf8 path[MAX_PATH];
|
||||
platform_get_user_directory(path, "chatlogs");
|
||||
platform_get_user_directory(path, "chatlogs", sizeof(path));
|
||||
Path::Append(path, sizeof(path), filename);
|
||||
|
||||
_chatLogPath = std::string(path);
|
||||
|
@ -819,7 +819,7 @@ void Network::AppendChatLog(const utf8 *text)
|
|||
|
||||
String::Append(buffer, sizeof(buffer), text);
|
||||
utf8_remove_formatting(buffer, false);
|
||||
String::Append(buffer, sizeof(buffer), platform_get_new_line());
|
||||
String::Append(buffer, sizeof(buffer), PLATFORM_NEWLINE);
|
||||
|
||||
SDL_RWwrite(_chatLogStream, buffer, strlen(buffer), 1);
|
||||
SDL_RWclose(_chatLogStream);
|
||||
|
@ -1216,9 +1216,9 @@ void Network::RemoveClient(std::unique_ptr<NetworkConnection>& connection)
|
|||
connection->GetLastDisconnectReason()
|
||||
};
|
||||
if (has_disconnected_args[1]) {
|
||||
format_string(text, STR_MULTIPLAYER_PLAYER_HAS_DISCONNECTED_WITH_REASON, has_disconnected_args);
|
||||
format_string(text, 256, STR_MULTIPLAYER_PLAYER_HAS_DISCONNECTED_WITH_REASON, has_disconnected_args);
|
||||
} else {
|
||||
format_string(text, STR_MULTIPLAYER_PLAYER_HAS_DISCONNECTED_NO_REASON, &(has_disconnected_args[0]));
|
||||
format_string(text, 256, STR_MULTIPLAYER_PLAYER_HAS_DISCONNECTED_NO_REASON, &(has_disconnected_args[0]));
|
||||
}
|
||||
|
||||
chat_history_add(text);
|
||||
|
@ -1408,7 +1408,7 @@ void Network::Server_Client_Joined(const char* name, const std::string &keyhash,
|
|||
if (player) {
|
||||
char text[256];
|
||||
const char * player_name = (const char *) player->name.c_str();
|
||||
format_string(text, STR_MULTIPLAYER_PLAYER_HAS_JOINED_THE_GAME, &player_name);
|
||||
format_string(text, 256, STR_MULTIPLAYER_PLAYER_HAS_JOINED_THE_GAME, &player_name);
|
||||
chat_history_add(text);
|
||||
Server_Send_MAP(&connection);
|
||||
gNetwork.Server_Send_EVENT_PLAYER_JOINED(player_name);
|
||||
|
@ -1511,7 +1511,7 @@ void Network::Client_Handle_MAP(NetworkConnection& connection, NetworkPacket& pa
|
|||
}
|
||||
char str_downloading_map[256];
|
||||
unsigned int downloading_map_args[2] = {(offset + chunksize) / 1024, size / 1024};
|
||||
format_string(str_downloading_map, STR_MULTIPLAYER_DOWNLOADING_MAP, downloading_map_args);
|
||||
format_string(str_downloading_map, 256, STR_MULTIPLAYER_DOWNLOADING_MAP, downloading_map_args);
|
||||
window_network_status_open(str_downloading_map, []() -> void {
|
||||
gNetwork.Close();
|
||||
});
|
||||
|
@ -1779,27 +1779,26 @@ void Network::Client_Handle_GROUPLIST(NetworkConnection& connection, NetworkPack
|
|||
|
||||
void Network::Client_Handle_EVENT(NetworkConnection& connection, NetworkPacket& packet)
|
||||
{
|
||||
char text[256];
|
||||
uint16 eventType;
|
||||
packet >> eventType;
|
||||
switch (eventType) {
|
||||
case SERVER_EVENT_PLAYER_JOINED:
|
||||
{
|
||||
char text[256];
|
||||
const char *playerName = packet.ReadString();
|
||||
format_string(text, STR_MULTIPLAYER_PLAYER_HAS_JOINED_THE_GAME, &playerName);
|
||||
format_string(text, 256, STR_MULTIPLAYER_PLAYER_HAS_JOINED_THE_GAME, &playerName);
|
||||
chat_history_add(text);
|
||||
break;
|
||||
}
|
||||
case SERVER_EVENT_PLAYER_DISCONNECTED:
|
||||
{
|
||||
char text[256];
|
||||
const char *playerName = packet.ReadString();
|
||||
const char *reason = packet.ReadString();
|
||||
const char *args[] = { playerName, reason };
|
||||
if (str_is_null_or_empty(reason)) {
|
||||
format_string(text, STR_MULTIPLAYER_PLAYER_HAS_DISCONNECTED_NO_REASON, args);
|
||||
format_string(text, 256, STR_MULTIPLAYER_PLAYER_HAS_DISCONNECTED_NO_REASON, args);
|
||||
} else {
|
||||
format_string(text, STR_MULTIPLAYER_PLAYER_HAS_DISCONNECTED_WITH_REASON, args);
|
||||
format_string(text, 256, STR_MULTIPLAYER_PLAYER_HAS_DISCONNECTED_WITH_REASON, args);
|
||||
}
|
||||
chat_history_add(text);
|
||||
break;
|
||||
|
@ -2022,13 +2021,13 @@ const char* network_get_group_name(unsigned int index)
|
|||
|
||||
void network_chat_show_connected_message()
|
||||
{
|
||||
// TODO: How does this work? 2525 is '???'
|
||||
char *templateString = (char*)language_get_string(STR_SHORTCUT_KEY_UNKNOWN);
|
||||
keyboard_shortcut_format_string(templateString, gShortcutKeys[SHORTCUT_OPEN_CHAT_WINDOW]);
|
||||
char templateBuffer[128];
|
||||
char *templateString = templateBuffer;
|
||||
keyboard_shortcut_format_string(templateBuffer, 128, gShortcutKeys[SHORTCUT_OPEN_CHAT_WINDOW]);
|
||||
utf8 buffer[256];
|
||||
NetworkPlayer server;
|
||||
server.name = "Server";
|
||||
format_string(buffer, STR_MULTIPLAYER_CONNECTED_CHAT_HINT, &templateString);
|
||||
format_string(buffer, 256, STR_MULTIPLAYER_CONNECTED_CHAT_HINT, &templateString);
|
||||
const char *formatted = Network::FormatChat(&server, buffer);
|
||||
chat_history_add(formatted);
|
||||
}
|
||||
|
@ -2349,7 +2348,7 @@ void network_append_chat_log(const utf8 *text)
|
|||
|
||||
static void network_get_keys_directory(utf8 *buffer, size_t bufferSize)
|
||||
{
|
||||
platform_get_user_directory(buffer, "keys");
|
||||
platform_get_user_directory(buffer, "keys", bufferSize);
|
||||
}
|
||||
|
||||
static void network_get_private_key_path(utf8 *buffer, size_t bufferSize, const utf8 * playerName)
|
||||
|
@ -2370,7 +2369,7 @@ static void network_get_public_key_path(utf8 *buffer, size_t bufferSize, const u
|
|||
|
||||
static void network_get_keymap_path(utf8 *buffer, size_t bufferSize)
|
||||
{
|
||||
platform_get_user_directory(buffer, NULL);
|
||||
platform_get_user_directory(buffer, NULL, bufferSize);
|
||||
Path::Append(buffer, bufferSize, "keymappings.json");
|
||||
}
|
||||
|
||||
|
|
|
@ -415,7 +415,7 @@ namespace Twitch
|
|||
if (is_user_string_id(peep->name_string_idx))
|
||||
{
|
||||
utf8 buffer[256];
|
||||
format_string(buffer, peep->name_string_idx, NULL);
|
||||
format_string(buffer, 256, peep->name_string_idx, NULL);
|
||||
|
||||
AudienceMember * member = nullptr;
|
||||
for (AudienceMember &m : members)
|
||||
|
@ -505,27 +505,6 @@ namespace Twitch
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Like strchr but allows searching for one of many characters.
|
||||
*/
|
||||
static char * strchrm(const char * str, const char * find)
|
||||
{
|
||||
do
|
||||
{
|
||||
const char * fch = find;
|
||||
while (*fch != '\0')
|
||||
{
|
||||
if (*str == *fch)
|
||||
{
|
||||
return (char *)str;
|
||||
}
|
||||
fch++;
|
||||
}
|
||||
}
|
||||
while (*str++ != '\0');
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static char * strskipwhitespace(const char * str)
|
||||
{
|
||||
while (*str == ' ' || *str == '\t')
|
||||
|
@ -546,17 +525,16 @@ namespace Twitch
|
|||
// Skip '!'
|
||||
message++;
|
||||
|
||||
// Set buffer to the next word / token and skip
|
||||
char buffer[32];
|
||||
const char * ch = strchrm(message, " \t");
|
||||
safe_strcpy(buffer, message, Math::Min(sizeof(buffer), (size_t)(ch - message + 1)));
|
||||
ch = strskipwhitespace(ch);
|
||||
|
||||
// Check what the word / token is
|
||||
if (String::Equals(buffer, "news", true))
|
||||
{
|
||||
DoChatMessageNews(ch);
|
||||
// Check that command is "news"
|
||||
const char *ch, *cmd;
|
||||
for (ch = message, cmd = "news"; *cmd != '\0'; ++ch, ++cmd) {
|
||||
if (*ch != *cmd) return;
|
||||
}
|
||||
|
||||
if (!isspace(*ch)) return;
|
||||
|
||||
ch = strskipwhitespace(ch);
|
||||
DoChatMessageNews(ch);
|
||||
}
|
||||
|
||||
static void DoChatMessageNews(const char * message)
|
||||
|
|
|
@ -116,7 +116,7 @@ bool object_entry_is_empty(const rct_object_entry *entry);
|
|||
bool object_entry_compare(const rct_object_entry *a, const rct_object_entry *b);
|
||||
int object_calculate_checksum(const rct_object_entry * entry, const void * data, size_t dataLength);
|
||||
int find_object_in_entry_group(const rct_object_entry* entry, uint8* entry_type, uint8* entry_index);
|
||||
void object_create_identifier_name(char* string_buffer, const rct_object_entry* object);
|
||||
void object_create_identifier_name(char* string_buffer, size_t size, const rct_object_entry* object);
|
||||
|
||||
rct_object_entry *object_list_find_by_name(const char *name);
|
||||
rct_object_entry *object_list_find(rct_object_entry *entry);
|
||||
|
|
|
@ -46,6 +46,7 @@ extern "C"
|
|||
#include "../platform/platform.h"
|
||||
#include "../scenario.h"
|
||||
#include "../util/sawyercoding.h"
|
||||
#include "../util/util.h"
|
||||
}
|
||||
|
||||
constexpr uint16 OBJECT_REPOSITORY_VERSION = 10;
|
||||
|
@ -634,8 +635,8 @@ private:
|
|||
|
||||
static void GetRepositoryPath(utf8 * buffer, size_t bufferSize)
|
||||
{
|
||||
platform_get_user_directory(buffer, nullptr);
|
||||
strcat(buffer, "objects.idx");
|
||||
platform_get_user_directory(buffer, nullptr, bufferSize);
|
||||
safe_strcat_path(buffer, "objects.idx", bufferSize);
|
||||
}
|
||||
|
||||
static void GetRCT2ObjectPath(utf8 * buffer, size_t bufferSize)
|
||||
|
@ -645,7 +646,7 @@ private:
|
|||
|
||||
static void GetUserObjectPath(utf8 * buffer, size_t bufferSize)
|
||||
{
|
||||
platform_get_user_directory(buffer, "object");
|
||||
platform_get_user_directory(buffer, "object", bufferSize);
|
||||
}
|
||||
|
||||
static uint32 GetPathChecksum(const utf8 * path)
|
||||
|
|
|
@ -122,9 +122,9 @@ bool object_entry_is_empty(const rct_object_entry *entry)
|
|||
*
|
||||
* rct2: 0x006AB344
|
||||
*/
|
||||
void object_create_identifier_name(char* string_buffer, const rct_object_entry* object)
|
||||
void object_create_identifier_name(char* string_buffer, size_t size, const rct_object_entry* object)
|
||||
{
|
||||
sprintf(string_buffer, "%.8s/%4X%4X", object->name, object->flags, object->checksum);
|
||||
snprintf(string_buffer, size, "%.8s/%4X%4X", object->name, object->flags, object->checksum);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -90,23 +90,25 @@ void openrct2_write_full_version_info(utf8 *buffer, size_t bufferSize)
|
|||
utf8 *ch = buffer;
|
||||
|
||||
// Name and version
|
||||
strcpy(ch, OPENRCT2_NAME);
|
||||
strcat(buffer, ", v");
|
||||
strcat(buffer, OPENRCT2_VERSION);
|
||||
safe_strcpy(ch, OPENRCT2_NAME ", v" OPENRCT2_VERSION, bufferSize - (ch - buffer));
|
||||
ch = strchr(ch, '\0');
|
||||
|
||||
// Build information
|
||||
if (!str_is_null_or_empty(gGitBranch)) {
|
||||
sprintf(strchr(buffer, 0), "-%s", gGitBranch);
|
||||
snprintf(ch, bufferSize - (ch - buffer), "-%s", gGitBranch);
|
||||
ch = strchr(ch, '\0');
|
||||
}
|
||||
if (!str_is_null_or_empty(gCommitSha1Short)) {
|
||||
sprintf(strchr(buffer, 0), " build %s", gCommitSha1Short);
|
||||
snprintf(ch, bufferSize - (ch - buffer), " build %s", gCommitSha1Short);
|
||||
ch = strchr(ch, '\0');
|
||||
}
|
||||
if (!str_is_null_or_empty(gBuildServer)) {
|
||||
sprintf(strchr(buffer, 0), " provided by %s", gBuildServer);
|
||||
snprintf(ch, bufferSize - (ch - buffer), " provided by %s", gBuildServer);
|
||||
ch = strchr(ch, '\0');
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
sprintf(strchr(buffer, 0), " (DEBUG)");
|
||||
snprintf(ch, bufferSize - (ch - buffer), " (DEBUG)");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -122,23 +124,23 @@ static void openrct2_copy_files_over(const utf8 *originalDirectory, const utf8 *
|
|||
}
|
||||
|
||||
// Create filter path
|
||||
safe_strcpy(filter, originalDirectory, MAX_PATH);
|
||||
safe_strcpy(filter, originalDirectory, sizeof(filter));
|
||||
ch = strchr(filter, '*');
|
||||
if (ch != NULL)
|
||||
*ch = 0;
|
||||
strcat(filter, "*");
|
||||
strcat(filter, extension);
|
||||
safe_strcat_path(filter, "*", sizeof(filter));
|
||||
path_append_extension(filter, extension, sizeof(filter));
|
||||
|
||||
fileEnumHandle = platform_enumerate_files_begin(filter);
|
||||
while (platform_enumerate_files_next(fileEnumHandle, &fileInfo)) {
|
||||
safe_strcpy(newPath, newDirectory, MAX_PATH);
|
||||
strcat(newPath, fileInfo.path);
|
||||
safe_strcpy(newPath, newDirectory, sizeof(newPath));
|
||||
safe_strcat_path(newPath, fileInfo.path, sizeof(newPath));
|
||||
|
||||
safe_strcpy(oldPath, originalDirectory, MAX_PATH);
|
||||
safe_strcpy(oldPath, originalDirectory, sizeof(oldPath));
|
||||
ch = strchr(oldPath, '*');
|
||||
if (ch != NULL)
|
||||
*ch = 0;
|
||||
strcat(oldPath, fileInfo.path);
|
||||
safe_strcat_path(oldPath, fileInfo.path, sizeof(oldPath));
|
||||
|
||||
if (!platform_file_exists(newPath))
|
||||
platform_file_copy(oldPath, newPath, false);
|
||||
|
@ -147,14 +149,14 @@ static void openrct2_copy_files_over(const utf8 *originalDirectory, const utf8 *
|
|||
|
||||
fileEnumHandle = platform_enumerate_directories_begin(originalDirectory);
|
||||
while (platform_enumerate_directories_next(fileEnumHandle, filter)) {
|
||||
safe_strcpy(newPath, newDirectory, MAX_PATH);
|
||||
strcat(newPath, filter);
|
||||
safe_strcpy(newPath, newDirectory, sizeof(newPath));
|
||||
safe_strcat_path(newPath, filter, sizeof(newPath));
|
||||
|
||||
safe_strcpy(oldPath, originalDirectory, MAX_PATH);
|
||||
ch = strchr(oldPath, '*');
|
||||
if (ch != NULL)
|
||||
*ch = 0;
|
||||
strcat(oldPath, filter);
|
||||
safe_strcat_path(oldPath, filter, sizeof(oldPath));
|
||||
|
||||
if (!platform_ensure_directory_exists(newPath)) {
|
||||
log_error("Could not create directory %s.", newPath);
|
||||
|
@ -167,7 +169,7 @@ static void openrct2_copy_files_over(const utf8 *originalDirectory, const utf8 *
|
|||
|
||||
static void openrct2_set_exe_path()
|
||||
{
|
||||
platform_get_exe_path(gExePath);
|
||||
platform_get_exe_path(gExePath, sizeof(gExePath));
|
||||
log_verbose("Setting exe path to %s", gExePath);
|
||||
}
|
||||
|
||||
|
@ -178,10 +180,10 @@ static void openrct2_copy_original_user_files_over()
|
|||
{
|
||||
utf8 path[MAX_PATH];
|
||||
|
||||
platform_get_user_directory(path, "save");
|
||||
platform_get_user_directory(path, "save", sizeof(path));
|
||||
openrct2_copy_files_over((utf8*)gRCT2AddressSavedGamesPath, path, ".sv6");
|
||||
|
||||
platform_get_user_directory(path, "landscape");
|
||||
platform_get_user_directory(path, "landscape", sizeof(path));
|
||||
openrct2_copy_files_over((utf8*)gRCT2AddressLandscapesPath, path, ".sc6");
|
||||
}
|
||||
|
||||
|
@ -196,7 +198,7 @@ bool openrct2_initialise()
|
|||
|
||||
platform_resolve_openrct_data_path();
|
||||
platform_resolve_user_data_path();
|
||||
platform_get_user_directory(userPath, NULL);
|
||||
platform_get_user_directory(userPath, NULL, sizeof(userPath));
|
||||
if (!platform_ensure_directory_exists(userPath)) {
|
||||
log_fatal("Could not create user directory (do you have write access to your documents folder?)");
|
||||
return false;
|
||||
|
@ -217,7 +219,7 @@ bool openrct2_initialise()
|
|||
gConfigGeneral.last_run_version = strndup(OPENRCT2_VERSION, strlen(OPENRCT2_VERSION));
|
||||
config_save_default();
|
||||
utf8 path[MAX_PATH];
|
||||
config_get_default_path(path);
|
||||
config_get_default_path(path, sizeof(path));
|
||||
log_fatal("An RCT2 install directory must be specified! Please edit \"game_path\" in %s.", path);
|
||||
return false;
|
||||
}
|
||||
|
@ -493,7 +495,7 @@ void openrct2_reset_object_tween_locations()
|
|||
|
||||
static void openrct2_get_segment_data_path(char * buffer, size_t bufferSize)
|
||||
{
|
||||
platform_get_exe_path(buffer);
|
||||
platform_get_exe_path(buffer, bufferSize);
|
||||
safe_strcat_path(buffer, "openrct2_data", bufferSize);
|
||||
}
|
||||
|
||||
|
|
|
@ -99,9 +99,9 @@ void banner_paint(uint8 direction, int height, rct_map_element* map_element)
|
|||
string_id = STR_BANNER_TEXT_FORMAT;
|
||||
}
|
||||
if (gConfigGeneral.upper_case_banners) {
|
||||
format_string_to_upper(gCommonStringFormatBuffer, string_id, gCommonFormatArgs);
|
||||
format_string_to_upper(gCommonStringFormatBuffer, 256, string_id, gCommonFormatArgs);
|
||||
} else {
|
||||
format_string(gCommonStringFormatBuffer, string_id, gCommonFormatArgs);
|
||||
format_string(gCommonStringFormatBuffer, 256, string_id, gCommonFormatArgs);
|
||||
}
|
||||
|
||||
gCurrentFontSpriteBase = FONT_SPRITE_BASE_TINY;
|
||||
|
|
|
@ -131,9 +131,9 @@ static void ride_entrance_exit_paint(uint8 direction, int height, rct_map_elemen
|
|||
|
||||
utf8 entrance_string[MAX_PATH];
|
||||
if (gConfigGeneral.upper_case_banners) {
|
||||
format_string_to_upper(entrance_string, string_id, gCommonFormatArgs);
|
||||
format_string_to_upper(entrance_string, MAX_PATH, string_id, gCommonFormatArgs);
|
||||
} else {
|
||||
format_string(entrance_string, string_id, gCommonFormatArgs);
|
||||
format_string(entrance_string, MAX_PATH, string_id, gCommonFormatArgs);
|
||||
}
|
||||
|
||||
gCurrentFontSpriteBase = FONT_SPRITE_BASE_TINY;
|
||||
|
@ -208,9 +208,9 @@ static void park_entrance_paint(uint8 direction, int height, rct_map_element* ma
|
|||
|
||||
utf8 park_name[MAX_PATH];
|
||||
if (gConfigGeneral.upper_case_banners) {
|
||||
format_string_to_upper(park_name, park_text_id, gCommonFormatArgs);
|
||||
format_string_to_upper(park_name, MAX_PATH, park_text_id, gCommonFormatArgs);
|
||||
} else {
|
||||
format_string(park_name, park_text_id, gCommonFormatArgs);
|
||||
format_string(park_name, MAX_PATH, park_text_id, gCommonFormatArgs);
|
||||
}
|
||||
|
||||
gCurrentFontSpriteBase = FONT_SPRITE_BASE_TINY;
|
||||
|
|
|
@ -367,9 +367,9 @@ void fence_paint(uint8 direction, int height, rct_map_element * map_element)
|
|||
utf8 signString[MAX_PATH];
|
||||
rct_string_id stringId = STR_SCROLLING_SIGN_TEXT;
|
||||
if (gConfigGeneral.upper_case_banners) {
|
||||
format_string_to_upper(signString, stringId, gCommonFormatArgs);
|
||||
format_string_to_upper(signString, MAX_PATH, stringId, gCommonFormatArgs);
|
||||
} else {
|
||||
format_string(signString, stringId, gCommonFormatArgs);
|
||||
format_string(signString, MAX_PATH, stringId, gCommonFormatArgs);
|
||||
}
|
||||
|
||||
gCurrentFontSpriteBase = FONT_SPRITE_BASE_TINY;
|
||||
|
|
|
@ -396,9 +396,9 @@ static void sub_6A4101(rct_map_element * map_element, uint16 height, uint32 ebp,
|
|||
string_id = STR_RIDE_ENTRANCE_NAME;
|
||||
}
|
||||
if (gConfigGeneral.upper_case_banners) {
|
||||
format_string_to_upper(gCommonStringFormatBuffer, string_id, gCommonFormatArgs);
|
||||
format_string_to_upper(gCommonStringFormatBuffer, 256, string_id, gCommonFormatArgs);
|
||||
} else {
|
||||
format_string(gCommonStringFormatBuffer, string_id, gCommonFormatArgs);
|
||||
format_string(gCommonStringFormatBuffer, 256, string_id, gCommonFormatArgs);
|
||||
}
|
||||
|
||||
gCurrentFontSpriteBase = FONT_SPRITE_BASE_TINY;
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "../../game.h"
|
||||
#include "../../interface/viewport.h"
|
||||
#include "../../localisation/localisation.h"
|
||||
#include "../../util/util.h"
|
||||
#include "../../world/map.h"
|
||||
#include "../../world/scenery.h"
|
||||
|
||||
|
@ -88,9 +89,9 @@ static int scenery_multiple_sign_text_height(const utf8 *str, rct_large_scenery_
|
|||
|
||||
static const utf8 *scenery_multiple_sign_fit_text(const utf8 *str, rct_large_scenery_text *text, bool height)
|
||||
{
|
||||
static utf8 fitStr[32] = {0};
|
||||
static utf8 fitStr[32];
|
||||
utf8 *fitStrEnd = fitStr;
|
||||
strncpy(fitStr, str, sizeof(fitStr) - 1);
|
||||
safe_strcpy(fitStr, str, sizeof(fitStr));
|
||||
int w = 0;
|
||||
uint32 codepoint;
|
||||
while (w <= text->max_width && (codepoint = utf8_get_next(fitStrEnd, (const utf8**)&fitStrEnd)) != 0) {
|
||||
|
@ -262,16 +263,16 @@ void scenery_multiple_paint(uint8 direction, uint16 height, rct_map_element *map
|
|||
stringId = ride->name;
|
||||
set_format_arg(0, uint32, ride->name_arguments);
|
||||
}
|
||||
utf8 signString[MAX_PATH] = {0};
|
||||
format_string(signString, stringId, gCommonFormatArgs);
|
||||
utf8 signString[MAX_PATH];
|
||||
format_string(signString, MAX_PATH, stringId, gCommonFormatArgs);
|
||||
rct_large_scenery_text *text = entry->large_scenery.text;
|
||||
int y_offset = (text->offset[(direction & 1)].y * 2);
|
||||
if (text->var_C & 0x1) {
|
||||
// Draw vertical sign:
|
||||
y_offset += 1;
|
||||
utf8 fitStr[32] = {0};
|
||||
utf8 fitStr[32];
|
||||
const utf8 *fitStrPtr = fitStr;
|
||||
strncpy(fitStr, scenery_multiple_sign_fit_text(signString, text, true), sizeof(fitStr) - 1);
|
||||
safe_strcpy(fitStr, scenery_multiple_sign_fit_text(signString, text, true), sizeof(fitStr));
|
||||
int height = scenery_multiple_sign_text_height(fitStr, text);
|
||||
uint32 codepoint;
|
||||
while ((codepoint = utf8_get_next(fitStrPtr, &fitStrPtr)) != 0) {
|
||||
|
@ -355,9 +356,9 @@ void scenery_multiple_paint(uint8 direction, uint16 height, rct_map_element *map
|
|||
utf8 signString[MAX_PATH];
|
||||
rct_string_id stringId = STR_SCROLLING_SIGN_TEXT;
|
||||
if (gConfigGeneral.upper_case_banners) {
|
||||
format_string_to_upper(signString, stringId, gCommonFormatArgs);
|
||||
format_string_to_upper(signString, MAX_PATH, stringId, gCommonFormatArgs);
|
||||
} else {
|
||||
format_string(signString, stringId, gCommonFormatArgs);
|
||||
format_string(signString, MAX_PATH, stringId, gCommonFormatArgs);
|
||||
}
|
||||
|
||||
gCurrentFontSpriteBase = FONT_SPRITE_BASE_TINY;
|
||||
|
|
|
@ -1094,7 +1094,7 @@ void viewport_draw_money_effects()
|
|||
draw_pixel_info_crop_by_zoom(&dpi);
|
||||
|
||||
do {
|
||||
format_string(buffer, ps->string_id, &ps->args);
|
||||
format_string(buffer, 256, ps->string_id, &ps->args);
|
||||
gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM;
|
||||
|
||||
bool forceSpriteFont = false;
|
||||
|
|
|
@ -7364,7 +7364,7 @@ int peep_check_easteregg_name(int index, rct_peep *peep)
|
|||
{
|
||||
char buffer[256];
|
||||
|
||||
format_string(buffer, peep->name_string_idx, &peep->id);
|
||||
format_string(buffer, 256, peep->name_string_idx, &peep->id);
|
||||
return _stricmp(buffer, gPeepEasterEggNames[index]) == 0;
|
||||
}
|
||||
|
||||
|
@ -7373,7 +7373,7 @@ int peep_get_easteregg_name_id(rct_peep *peep)
|
|||
char buffer[256];
|
||||
int i;
|
||||
|
||||
format_string(buffer, peep->name_string_idx, &peep->id);
|
||||
format_string(buffer, 256, peep->name_string_idx, &peep->id);
|
||||
|
||||
for (i = 0; i < countof(gPeepEasterEggNames); i++)
|
||||
if (_stricmp(buffer, gPeepEasterEggNames[i]) == 0)
|
||||
|
@ -9889,7 +9889,7 @@ static int guest_path_finding(rct_peep* peep)
|
|||
/* For guests, use the existing PEEP_FLAGS_TRACKING flag to
|
||||
* determine for which guest(s) the pathfinding debugging will
|
||||
* be output for. */
|
||||
format_string(gPathFindDebugPeepName, peep->name_string_idx, &(peep->id));
|
||||
format_string(gPathFindDebugPeepName, sizeof(gPathFindDebugPeepName), peep->name_string_idx, &(peep->id));
|
||||
gPathFindDebug = peep->peep_flags & PEEP_FLAGS_TRACKING;
|
||||
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
|
||||
|
@ -11888,9 +11888,9 @@ static int peep_compare(const void *sprite_index_a, const void *sprite_index_b)
|
|||
utf8 name_a[256];
|
||||
utf8 name_b[256];
|
||||
uint32 peepIndex = peep_a->id;
|
||||
format_string(name_a, peep_a->name_string_idx, &peepIndex);
|
||||
format_string(name_a, 256, peep_a->name_string_idx, &peepIndex);
|
||||
peepIndex = peep_b->id;
|
||||
format_string(name_b, peep_b->name_string_idx, &peepIndex);
|
||||
format_string(name_b, 256, peep_b->name_string_idx, &peepIndex);
|
||||
return strlogicalcmp(name_a, name_b);
|
||||
}
|
||||
|
||||
|
@ -12059,7 +12059,7 @@ money32 set_peep_name(int flags, int state, uint16 sprite_index, uint8* text_1,
|
|||
set_format_arg(0, uint32, peep->id);
|
||||
utf8* curName = gCommonStringFormatBuffer;
|
||||
rct_string_id curId = peep->name_string_idx;
|
||||
format_string(curName, curId, gCommonFormatArgs);
|
||||
format_string(curName, 256, curId, gCommonFormatArgs);
|
||||
|
||||
if (strcmp(curName, newName) == 0)
|
||||
return 0;
|
||||
|
|
|
@ -1100,7 +1100,7 @@ static uint8 staff_mechanic_direction_path(rct_peep* peep, uint8 validDirections
|
|||
/* For staff, there is no tracking button (any other similar
|
||||
* suitable existing mechanism?), so fall back to a crude
|
||||
* string comparison with a compile time hardcoded name. */
|
||||
format_string(gPathFindDebugPeepName, peep->name_string_idx, &(peep->id));
|
||||
format_string(gPathFindDebugPeepName, sizeof(gPathFindDebugPeepName), peep->name_string_idx, &(peep->id));
|
||||
|
||||
gPathFindDebug = strcmp(gPathFindDebugPeepName, "Mechanic Debug") == 0;
|
||||
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
|
|
|
@ -24,9 +24,6 @@
|
|||
#include <breakpad/client/windows/handler/exception_handler.h>
|
||||
#include <string>
|
||||
#include <ShlObj.h>
|
||||
#elif defined(__LINUX__)
|
||||
#include <breakpad/client/linux/handler/exception_handler.h>
|
||||
#define BREAKPAD_PATH "/tmp"
|
||||
#else
|
||||
#error Breakpad support not implemented yet for this platform
|
||||
#endif
|
||||
|
@ -68,12 +65,12 @@ static bool OnCrash(const wchar_t * dumpPath,
|
|||
// Get filenames
|
||||
wchar_t dumpFilePath[MAX_PATH];
|
||||
wchar_t saveFilePath[MAX_PATH];
|
||||
wsprintfW(dumpFilePath, L"%s%s.dmp", dumpPath, miniDumpId);
|
||||
wsprintfW(saveFilePath, L"%s%s.sv6", dumpPath, miniDumpId);
|
||||
swprintf_s(dumpFilePath, sizeof(dumpFilePath), L"%s%s.dmp", dumpPath, miniDumpId);
|
||||
swprintf_s(saveFilePath, sizeof(saveFilePath), L"%s%s.sv6", dumpPath, miniDumpId);
|
||||
|
||||
// Try to rename the files
|
||||
wchar_t dumpFilePathNew[MAX_PATH];
|
||||
wsprintfW(dumpFilePathNew, L"%s%s(%s).dmp", dumpPath, miniDumpId, _wszCommitSha1Short);
|
||||
swprintf_s(dumpFilePathNew, sizeof(dumpFilePathNew), L"%s%s(%s).dmp", dumpPath, miniDumpId, _wszCommitSha1Short);
|
||||
if (_wrename(dumpFilePath, dumpFilePathNew) == 0)
|
||||
{
|
||||
std::wcscpy(dumpFilePath, dumpFilePathNew);
|
||||
|
@ -141,7 +138,7 @@ static bool OnCrash(const wchar_t * dumpPath,
|
|||
static std::wstring GetDumpDirectory()
|
||||
{
|
||||
char userDirectory[MAX_PATH];
|
||||
platform_get_user_directory(userDirectory, NULL);
|
||||
platform_get_user_directory(userDirectory, NULL, sizeof(userDirectory));
|
||||
|
||||
wchar_t * userDirectoryW = utf8_to_widechar(userDirectory);
|
||||
auto result = std::wstring(userDirectoryW);
|
||||
|
|
|
@ -46,7 +46,7 @@ struct dummy {
|
|||
|
||||
typedef enum { DT_NONE, DT_KDIALOG, DT_ZENITY } dialog_type;
|
||||
|
||||
void platform_get_exe_path(utf8 *outPath)
|
||||
void platform_get_exe_path(utf8 *outPath, size_t outSize)
|
||||
{
|
||||
char exePath[MAX_PATH];
|
||||
ssize_t bytesRead;
|
||||
|
@ -55,17 +55,16 @@ void platform_get_exe_path(utf8 *outPath)
|
|||
log_fatal("failed to read /proc/self/exe");
|
||||
}
|
||||
exePath[bytesRead - 1] = '\0';
|
||||
char *exeDelimiter = strrchr(exePath, platform_get_path_separator());
|
||||
char *exeDelimiter = strrchr(exePath, *PATH_SEPARATOR);
|
||||
if (exeDelimiter == NULL)
|
||||
{
|
||||
log_error("should never happen here");
|
||||
outPath[0] = '\0';
|
||||
return;
|
||||
}
|
||||
int exeDelimiterIndex = (int)(exeDelimiter - exePath);
|
||||
*exeDelimiter = '\0';
|
||||
|
||||
exePath[exeDelimiterIndex] = '\0';
|
||||
safe_strcpy(outPath, exePath, exeDelimiterIndex + 1);
|
||||
safe_strcpy(outPath, exePath, outSize);
|
||||
}
|
||||
|
||||
bool platform_check_steam_overlay_attached() {
|
||||
|
@ -94,7 +93,7 @@ bool platform_check_steam_overlay_attached() {
|
|||
* - $XDG_CONFIG_HOME/OpenRCT2
|
||||
* - /home/[uid]/.config/OpenRCT2
|
||||
*/
|
||||
void platform_posix_sub_user_data_path(char *buffer, const char *homedir, const char *separator) {
|
||||
void platform_posix_sub_user_data_path(char *buffer, size_t size, const char *homedir) {
|
||||
const char *configdir = getenv("XDG_CONFIG_HOME");
|
||||
log_verbose("configdir = '%s'", configdir);
|
||||
if (configdir == NULL)
|
||||
|
@ -107,17 +106,15 @@ void platform_posix_sub_user_data_path(char *buffer, const char *homedir, const
|
|||
return;
|
||||
}
|
||||
|
||||
strncat(buffer, homedir, MAX_PATH - 1);
|
||||
strncat(buffer, separator, MAX_PATH - strnlen(buffer, MAX_PATH) - 1);
|
||||
strncat(buffer, ".config", MAX_PATH - strnlen(buffer, MAX_PATH) - 1);
|
||||
safe_strcpy(buffer, homedir, size);
|
||||
safe_strcat_path(buffer, ".config", size);
|
||||
}
|
||||
else
|
||||
{
|
||||
strncat(buffer, configdir, MAX_PATH - 1);
|
||||
safe_strcpy(buffer, configdir, size);
|
||||
}
|
||||
strncat(buffer, separator, MAX_PATH - strnlen(buffer, MAX_PATH) - 1);
|
||||
strncat(buffer, "OpenRCT2", MAX_PATH - strnlen(buffer, MAX_PATH) - 1);
|
||||
strncat(buffer, separator, MAX_PATH - strnlen(buffer, MAX_PATH) - 1);
|
||||
safe_strcat_path(buffer, "OpenRCT2", size);
|
||||
path_end_with_separator(buffer, size);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -128,7 +125,7 @@ void platform_posix_sub_user_data_path(char *buffer, const char *homedir, const
|
|||
* - /var/lib/openrct2
|
||||
* - /usr/share/openrct2
|
||||
*/
|
||||
void platform_posix_sub_resolve_openrct_data_path(utf8 *out) {
|
||||
void platform_posix_sub_resolve_openrct_data_path(utf8 *out, size_t size) {
|
||||
static const utf8 *searchLocations[] = {
|
||||
"../share/openrct2",
|
||||
#ifdef ORCT2_RESOURCE_DIR
|
||||
|
@ -144,8 +141,7 @@ void platform_posix_sub_resolve_openrct_data_path(utf8 *out) {
|
|||
log_verbose("Looking for OpenRCT2 data in %s", searchLocations[i]);
|
||||
if (platform_directory_exists(searchLocations[i]))
|
||||
{
|
||||
out[0] = '\0';
|
||||
safe_strcpy(out, searchLocations[i], MAX_PATH);
|
||||
safe_strcpy(out, searchLocations[i], size);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -169,7 +165,7 @@ uint16 platform_get_locale_language(){
|
|||
}
|
||||
}
|
||||
} //end strip
|
||||
strncpy(pattern,langString, length); //copy all until first '.' or '@'
|
||||
memcpy(pattern, langString, length); //copy all until first '.' or '@'
|
||||
pattern[length] = '\0';
|
||||
//find _ if present
|
||||
const char *strip = strchr(pattern, '_');
|
||||
|
@ -304,7 +300,7 @@ static dialog_type get_dialog_app(char *cmd, size_t *cmd_size) {
|
|||
return dtype;
|
||||
}
|
||||
|
||||
bool platform_open_common_file_dialog(utf8 *outFilename, file_dialog_desc *desc) {
|
||||
bool platform_open_common_file_dialog(utf8 *outFilename, file_dialog_desc *desc, size_t outSize) {
|
||||
int exit_value;
|
||||
char executable[MAX_PATH];
|
||||
char cmd[MAX_PATH];
|
||||
|
@ -428,7 +424,7 @@ bool platform_open_common_file_dialog(utf8 *outFilename, file_dialog_desc *desc)
|
|||
snprintf(msg, MAX_PATH, "\"%s\" not found: %s, please choose another file\n", result, strerror(errno));
|
||||
platform_show_messagebox(msg);
|
||||
|
||||
return platform_open_common_file_dialog(outFilename, desc);
|
||||
return platform_open_common_file_dialog(outFilename, desc, outSize);
|
||||
} else
|
||||
if (desc->type == FD_SAVE && access(result, F_OK) != -1 && dtype == DT_KDIALOG) {
|
||||
snprintf(cmd, MAX_PATH, "%s --yesno \"Overwrite %s?\"", executable, result);
|
||||
|
@ -441,7 +437,7 @@ bool platform_open_common_file_dialog(utf8 *outFilename, file_dialog_desc *desc)
|
|||
}
|
||||
}
|
||||
|
||||
strncpy(outFilename, result, MAX_PATH);
|
||||
safe_strcpy(outFilename, result, outSize);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -477,8 +473,7 @@ utf8 *platform_open_directory_browser(utf8 *title) {
|
|||
|
||||
result[size-1] = '\0';
|
||||
|
||||
return_value = (char*) malloc(strlen(result)+1);
|
||||
strcpy(return_value, result);
|
||||
return_value = _strdup(result);
|
||||
|
||||
return return_value;
|
||||
}
|
||||
|
@ -510,7 +505,7 @@ void platform_show_messagebox(char *message) {
|
|||
execute_cmd(cmd, 0, 0, 0);
|
||||
}
|
||||
|
||||
bool platform_get_font_path(TTFFontDescriptor *font, utf8 *buffer)
|
||||
bool platform_get_font_path(TTFFontDescriptor *font, utf8 *buffer, size_t size)
|
||||
{
|
||||
assert(buffer != NULL);
|
||||
assert(font != NULL);
|
||||
|
@ -538,7 +533,7 @@ bool platform_get_font_path(TTFFontDescriptor *font, utf8 *buffer)
|
|||
if (FcPatternGetString(match, FC_FILE, 0, &filename) == FcResultMatch)
|
||||
{
|
||||
found = true;
|
||||
safe_strcpy(buffer, (utf8*) filename, MAX_PATH);
|
||||
safe_strcpy(buffer, (utf8*) filename, size);
|
||||
log_verbose("FontConfig provided font %s", filename);
|
||||
}
|
||||
FcPatternDestroy(match);
|
||||
|
|
|
@ -29,8 +29,9 @@ bool platform_check_steam_overlay_attached() {
|
|||
return false;
|
||||
}
|
||||
|
||||
void platform_get_exe_path(utf8 *outPath)
|
||||
void platform_get_exe_path(utf8 *outPath, size_t outSize)
|
||||
{
|
||||
if (outSize == 0) return;
|
||||
char exePath[MAX_PATH];
|
||||
uint32_t size = MAX_PATH;
|
||||
int result = _NSGetExecutablePath(exePath, &size);
|
||||
|
@ -38,17 +39,16 @@ void platform_get_exe_path(utf8 *outPath)
|
|||
log_fatal("failed to get path");
|
||||
}
|
||||
exePath[MAX_PATH - 1] = '\0';
|
||||
char *exeDelimiter = strrchr(exePath, platform_get_path_separator());
|
||||
char *exeDelimiter = strrchr(exePath, *PATH_SEPARATOR);
|
||||
if (exeDelimiter == NULL)
|
||||
{
|
||||
log_error("should never happen here");
|
||||
outPath[0] = '\0';
|
||||
return;
|
||||
}
|
||||
int exeDelimiterIndex = (int)(exeDelimiter - exePath);
|
||||
*exeDelimiter = '\0';
|
||||
|
||||
safe_strcpy(outPath, exePath, exeDelimiterIndex + 1);
|
||||
outPath[exeDelimiterIndex] = '\0';
|
||||
safe_strcpy(outPath, exePath, outSize);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -56,7 +56,7 @@ void platform_get_exe_path(utf8 *outPath)
|
|||
* - (command line argument)
|
||||
* - ~/Library/Application Support/OpenRCT2
|
||||
*/
|
||||
void platform_posix_sub_user_data_path(char *buffer, const char *homedir, const char *separator) {
|
||||
void platform_posix_sub_user_data_path(char *buffer, size_t size, const char *homedir) {
|
||||
if (homedir == NULL)
|
||||
{
|
||||
log_fatal("Couldn't find user data directory");
|
||||
|
@ -64,14 +64,11 @@ void platform_posix_sub_user_data_path(char *buffer, const char *homedir, const
|
|||
return;
|
||||
}
|
||||
|
||||
strncat(buffer, homedir, MAX_PATH - 1);
|
||||
strncat(buffer, separator, MAX_PATH - strnlen(buffer, MAX_PATH) - 1);
|
||||
strncat(buffer, "Library", MAX_PATH - strnlen(buffer, MAX_PATH) - 1);
|
||||
strncat(buffer, separator, MAX_PATH - strnlen(buffer, MAX_PATH) - 1);
|
||||
strncat(buffer, "Application Support", MAX_PATH - strnlen(buffer, MAX_PATH) - 1);
|
||||
strncat(buffer, separator, MAX_PATH - strnlen(buffer, MAX_PATH) - 1);
|
||||
strncat(buffer, "OpenRCT2", MAX_PATH - strnlen(buffer, MAX_PATH) - 1);
|
||||
strncat(buffer, separator, MAX_PATH - strnlen(buffer, MAX_PATH) - 1);
|
||||
safe_strcpy(buffer, homedir, size);
|
||||
safe_strcat_path(buffer, "Library", size);
|
||||
safe_strcat_path(buffer, "Application Support", size);
|
||||
safe_strcat_path(buffer, "OpenRCT2", size);
|
||||
path_end_with_separator(buffer, size);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -80,7 +77,7 @@ void platform_posix_sub_user_data_path(char *buffer, const char *homedir, const
|
|||
* - <exePath>/data
|
||||
* - <Resources Folder>
|
||||
*/
|
||||
void platform_posix_sub_resolve_openrct_data_path(utf8 *out) {
|
||||
void platform_posix_sub_resolve_openrct_data_path(utf8 *out, size_t size) {
|
||||
@autoreleasepool
|
||||
{
|
||||
NSBundle *bundle = [NSBundle mainBundle];
|
||||
|
@ -90,7 +87,7 @@ void platform_posix_sub_resolve_openrct_data_path(utf8 *out) {
|
|||
if (platform_directory_exists(resources))
|
||||
{
|
||||
out[0] = '\0';
|
||||
safe_strcpy(out, resources, MAX_PATH);
|
||||
safe_strcpy(out, resources, size);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -121,14 +118,13 @@ utf8 *platform_open_directory_browser(utf8 *title)
|
|||
{
|
||||
NSString *selectedPath = panel.URL.path;
|
||||
const char *path = selectedPath.UTF8String;
|
||||
url = (utf8*)malloc(strlen(path) + 1);
|
||||
strcpy(url,path);
|
||||
url = _strdup(path);
|
||||
}
|
||||
return url;
|
||||
}
|
||||
}
|
||||
|
||||
bool platform_open_common_file_dialog(utf8 *outFilename, file_dialog_desc *desc) {
|
||||
bool platform_open_common_file_dialog(utf8 *outFilename, file_dialog_desc *desc, size_t outSize) {
|
||||
@autoreleasepool
|
||||
{
|
||||
NSMutableArray *extensions = [NSMutableArray new];
|
||||
|
@ -169,14 +165,14 @@ bool platform_open_common_file_dialog(utf8 *outFilename, file_dialog_desc *desc)
|
|||
SDL_RaiseWindow(gWindow);
|
||||
return false;
|
||||
} else {
|
||||
strcpy(outFilename, panel.URL.path.UTF8String);
|
||||
safe_strcpy(outFilename, panel.URL.path.UTF8String, outSize);
|
||||
SDL_RaiseWindow(gWindow);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool platform_get_font_path(TTFFontDescriptor *font, utf8 *buffer)
|
||||
bool platform_get_font_path(TTFFontDescriptor *font, utf8 *buffer, size_t size)
|
||||
{
|
||||
@autoreleasepool
|
||||
{
|
||||
|
@ -184,7 +180,7 @@ bool platform_get_font_path(TTFFontDescriptor *font, utf8 *buffer)
|
|||
CFURLRef url = (CFURLRef)CTFontDescriptorCopyAttribute(fontRef, kCTFontURLAttribute);
|
||||
if (url) {
|
||||
NSString *fontPath = [NSString stringWithString:[(NSURL *)CFBridgingRelease(url) path]];
|
||||
strcpy(buffer, fontPath.UTF8String);
|
||||
safe_strcpy(buffer, fontPath.UTF8String, size);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
|
|
@ -46,8 +46,10 @@
|
|||
|
||||
#ifdef __WINDOWS__
|
||||
#define PATH_SEPARATOR "\\"
|
||||
#define PLATFORM_NEWLINE "\r\n"
|
||||
#else
|
||||
#define PATH_SEPARATOR "/"
|
||||
#define PLATFORM_NEWLINE "\n"
|
||||
#endif
|
||||
|
||||
typedef struct resolution {
|
||||
|
@ -145,9 +147,7 @@ void platform_get_date_local(rct2_date *out_date);
|
|||
void platform_get_time_local(rct2_time *out_time);
|
||||
|
||||
// Platform specific definitions
|
||||
void platform_get_exe_path(utf8 *outPath);
|
||||
const char *platform_get_new_line();
|
||||
char platform_get_path_separator();
|
||||
void platform_get_exe_path(utf8 *outPath, size_t outSize);
|
||||
bool platform_file_exists(const utf8 *path);
|
||||
bool platform_directory_exists(const utf8 *path);
|
||||
bool platform_original_game_data_exists(const utf8 *path);
|
||||
|
@ -177,18 +177,18 @@ void platform_set_cursor_position(int x, int y);
|
|||
unsigned int platform_get_ticks();
|
||||
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_openrct_data_path(utf8 *outPath, size_t outSize);
|
||||
void platform_get_user_directory(utf8 *outPath, const utf8 *subDirectory, size_t outSize);
|
||||
utf8* platform_get_username();
|
||||
void platform_show_messagebox(utf8 *message);
|
||||
bool platform_open_common_file_dialog(utf8 *outFilename, file_dialog_desc *desc);
|
||||
bool platform_open_common_file_dialog(utf8 *outFilename, file_dialog_desc *desc, size_t outSize);
|
||||
utf8 *platform_open_directory_browser(utf8 *title);
|
||||
uint8 platform_get_locale_currency();
|
||||
uint8 platform_get_currency_value(const char *currencyCode);
|
||||
uint16 platform_get_locale_language();
|
||||
uint8 platform_get_locale_measurement_format();
|
||||
uint8 platform_get_locale_temperature_format();
|
||||
bool platform_get_font_path(TTFFontDescriptor *font, utf8 *buffer);
|
||||
bool platform_get_font_path(TTFFontDescriptor *font, utf8 *buffer, size_t size);
|
||||
|
||||
bool platform_check_steam_overlay_attached();
|
||||
|
||||
|
@ -212,8 +212,8 @@ datetime64 platform_get_datetime_now_utc();
|
|||
#endif // __WINDOWS__
|
||||
|
||||
#if defined(__LINUX__) || defined(__MACOSX__)
|
||||
void platform_posix_sub_user_data_path(char *buffer, const char *homedir, const char *separator);
|
||||
void platform_posix_sub_resolve_openrct_data_path(utf8 *out);
|
||||
void platform_posix_sub_user_data_path(char *buffer, size_t size, const char *homedir);
|
||||
void platform_posix_sub_resolve_openrct_data_path(utf8 *out, size_t size);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -111,16 +111,6 @@ void platform_get_time_local(rct2_time *out_time)
|
|||
out_time->hour = timeinfo->tm_hour;
|
||||
}
|
||||
|
||||
char platform_get_path_separator()
|
||||
{
|
||||
return '/';
|
||||
}
|
||||
|
||||
const char *platform_get_new_line()
|
||||
{
|
||||
return "\n";
|
||||
}
|
||||
|
||||
bool platform_file_exists(const utf8 *path)
|
||||
{
|
||||
wchar_t *wPath = utf8_to_widechar(path);
|
||||
|
@ -160,9 +150,10 @@ bool platform_original_game_data_exists(const utf8 *path)
|
|||
wcstombs(buffer, wPath, len);
|
||||
buffer[len] = '\0';
|
||||
free(wPath);
|
||||
char separator = platform_get_path_separator();
|
||||
char checkPath[MAX_PATH];
|
||||
sprintf(checkPath, "%s%c%s%c%s", buffer, separator, "Data", separator, "g1.dat");
|
||||
safe_strcpy(checkPath, buffer, MAX_PATH);
|
||||
safe_strcat_path(checkPath, "Data", MAX_PATH);
|
||||
safe_strcat_path(checkPath, "g1.dat", MAX_PATH);
|
||||
return platform_file_exists(checkPath);
|
||||
}
|
||||
|
||||
|
@ -198,8 +189,7 @@ bool platform_directory_delete(const utf8 *path)
|
|||
FTSENT *p, *chp;
|
||||
|
||||
// fts_open only accepts non const paths, so we have to take a copy
|
||||
char* ourPath = (char*)malloc(strlen(path) + 1);
|
||||
strcpy(ourPath, path);
|
||||
char* ourPath = _strdup(path);
|
||||
|
||||
utf8* const patharray[2] = {ourPath, NULL};
|
||||
if ((ftsp = fts_open(patharray, FTS_COMFOLLOW | FTS_LOGICAL | FTS_NOCHDIR, NULL)) == NULL) {
|
||||
|
@ -321,7 +311,7 @@ int platform_enumerate_files_begin(const utf8 *pattern)
|
|||
}
|
||||
log_verbose("begin file search, pattern: %s", npattern);
|
||||
|
||||
char *file_name = strrchr(npattern, platform_get_path_separator());
|
||||
char *file_name = strrchr(npattern, *PATH_SEPARATOR);
|
||||
char *dir_name;
|
||||
if (file_name != NULL)
|
||||
{
|
||||
|
@ -356,7 +346,6 @@ int platform_enumerate_files_begin(const utf8 *pattern)
|
|||
char **paths = enumFileInfo->paths;
|
||||
// 256 is size of dirent.d_name
|
||||
const int dir_name_len = strnlen(dir_name, MAX_PATH);
|
||||
char separator[] = {platform_get_path_separator(), 0};
|
||||
for (int idx = 0; idx < cnt; idx++)
|
||||
{
|
||||
struct dirent *d = enumFileInfo->fileListTemp[idx];
|
||||
|
@ -364,11 +353,9 @@ int platform_enumerate_files_begin(const utf8 *pattern)
|
|||
// 1 for separator, 1 for trailing null
|
||||
size_t path_len = sizeof(char) * min(MAX_PATH, entry_len + dir_name_len + 2);
|
||||
paths[idx] = malloc(path_len);
|
||||
paths[idx][0] = '\0';
|
||||
log_verbose("dir_name: %s", dir_name);
|
||||
strncat(paths[idx], dir_name, path_len - 2);
|
||||
strncat(paths[idx], separator, path_len - strnlen(paths[idx], path_len) - 1);
|
||||
strncat(paths[idx], d->d_name, path_len - strnlen(paths[idx], path_len) - 1);
|
||||
safe_strcpy(paths[idx], dir_name, path_len);
|
||||
safe_strcat_path(paths[idx], d->d_name, path_len);
|
||||
log_verbose("paths[%d] = %s", idx, paths[idx]);
|
||||
}
|
||||
enumFileInfo->handle = 0;
|
||||
|
@ -495,7 +482,6 @@ int platform_enumerate_directories_begin(const utf8 *directory)
|
|||
char **paths = enumFileInfo->paths;
|
||||
// 256 is size of dirent.d_name
|
||||
const int dir_name_len = strnlen(npattern, MAX_PATH);
|
||||
char separator[] = {platform_get_path_separator(), 0};
|
||||
for (int idx = 0; idx < cnt; idx++)
|
||||
{
|
||||
struct dirent *d = enumFileInfo->fileListTemp[idx];
|
||||
|
@ -503,11 +489,9 @@ int platform_enumerate_directories_begin(const utf8 *directory)
|
|||
// 1 for separator, 1 for trailing null
|
||||
size_t path_len = sizeof(char) * min(MAX_PATH, entry_len + dir_name_len + 2);
|
||||
paths[idx] = malloc(path_len);
|
||||
paths[idx][0] = '\0';
|
||||
log_verbose("dir_name: %s", npattern);
|
||||
strncat(paths[idx], npattern, path_len - 2);
|
||||
strncat(paths[idx], separator, path_len - strnlen(paths[idx], path_len) - 1);
|
||||
strncat(paths[idx], d->d_name, path_len - strnlen(paths[idx], path_len) - 1);
|
||||
safe_strcpy(paths[idx], npattern, path_len);
|
||||
safe_strcat_path(paths[idx], d->d_name, path_len);
|
||||
log_verbose("paths[%d] = %s", idx, paths[idx]);
|
||||
}
|
||||
enumFileInfo->handle = 0;
|
||||
|
@ -552,7 +536,7 @@ bool platform_enumerate_directories_next(int handle, utf8 *path)
|
|||
}
|
||||
// so very, very wrong
|
||||
safe_strcpy(path, basename(fileName), MAX_PATH);
|
||||
strncat(path, "/", MAX_PATH - strlen(path) - 1);
|
||||
path_end_with_separator(path, MAX_PATH);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
@ -679,7 +663,6 @@ static wchar_t *regular_to_wchar(const char* src)
|
|||
*/
|
||||
void platform_resolve_user_data_path()
|
||||
{
|
||||
const char separator[2] = { platform_get_path_separator(), 0 };
|
||||
|
||||
if (gCustomUserDataPath[0] != 0) {
|
||||
if (!platform_ensure_directory_exists(gCustomUserDataPath)) {
|
||||
|
@ -696,10 +679,7 @@ void platform_resolve_user_data_path()
|
|||
free(path);
|
||||
|
||||
// Ensure path ends with separator
|
||||
int len = strlen(_userDataDirectoryPath);
|
||||
if (_userDataDirectoryPath[len - 1] != separator[0]) {
|
||||
strncat(_userDataDirectoryPath, separator, MAX_PATH - 1);
|
||||
}
|
||||
path_end_with_separator(_userDataDirectoryPath, MAX_PATH);
|
||||
log_verbose("User data path resolved to: %s", _userDataDirectoryPath);
|
||||
if (!platform_directory_exists(_userDataDirectoryPath)) {
|
||||
log_error("Custom user data directory %s does not exist", _userDataDirectoryPath);
|
||||
|
@ -708,11 +688,10 @@ void platform_resolve_user_data_path()
|
|||
}
|
||||
|
||||
char buffer[MAX_PATH];
|
||||
buffer[0] = '\0';
|
||||
log_verbose("buffer = '%s'", buffer);
|
||||
|
||||
const char *homedir = getpwuid(getuid())->pw_dir;
|
||||
platform_posix_sub_user_data_path(buffer, homedir, separator);
|
||||
platform_posix_sub_user_data_path(buffer, MAX_PATH, homedir);
|
||||
|
||||
log_verbose("OpenRCT2 user data directory = '%s'", buffer);
|
||||
int len = strnlen(buffer, MAX_PATH);
|
||||
|
@ -725,9 +704,9 @@ void platform_resolve_user_data_path()
|
|||
log_verbose("User data path resolved to: %s", _userDataDirectoryPath);
|
||||
}
|
||||
|
||||
void platform_get_openrct_data_path(utf8 *outPath)
|
||||
void platform_get_openrct_data_path(utf8 *outPath, size_t outSize)
|
||||
{
|
||||
safe_strcpy(outPath, _openrctDataDirectoryPath, sizeof(_openrctDataDirectoryPath));
|
||||
safe_strcpy(outPath, _openrctDataDirectoryPath, outSize);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -738,27 +717,20 @@ void platform_get_openrct_data_path(utf8 *outPath)
|
|||
*/
|
||||
void platform_resolve_openrct_data_path()
|
||||
{
|
||||
const char separator[2] = { platform_get_path_separator(), 0 };
|
||||
|
||||
if (gCustomOpenrctDataPath[0] != 0) {
|
||||
if (realpath(gCustomOpenrctDataPath, _openrctDataDirectoryPath)) {
|
||||
log_error("Could not resolve path \"%s\"", gCustomOpenrctDataPath);
|
||||
return;
|
||||
}
|
||||
|
||||
// Ensure path ends with separator
|
||||
int len = strlen(_openrctDataDirectoryPath);
|
||||
if (_openrctDataDirectoryPath[len - 1] != separator[0]) {
|
||||
strncat(_openrctDataDirectoryPath, separator, MAX_PATH - 1);
|
||||
}
|
||||
path_end_with_separator(_openrctDataDirectoryPath, MAX_PATH);
|
||||
return;
|
||||
}
|
||||
|
||||
char buffer[MAX_PATH] = { 0 };
|
||||
platform_get_exe_path(buffer);
|
||||
char buffer[MAX_PATH];
|
||||
platform_get_exe_path(buffer, sizeof(buffer));
|
||||
|
||||
strncat(buffer, separator, MAX_PATH - strnlen(buffer, MAX_PATH) - 1);
|
||||
strncat(buffer, "data", MAX_PATH - strnlen(buffer, MAX_PATH) - 1);
|
||||
safe_strcat_path(buffer, "data", MAX_PATH);
|
||||
log_verbose("Looking for OpenRCT2 data in %s", buffer);
|
||||
if (platform_directory_exists(buffer))
|
||||
{
|
||||
|
@ -768,26 +740,25 @@ void platform_resolve_openrct_data_path()
|
|||
return;
|
||||
}
|
||||
|
||||
platform_posix_sub_resolve_openrct_data_path(_openrctDataDirectoryPath);
|
||||
platform_posix_sub_resolve_openrct_data_path(_openrctDataDirectoryPath, sizeof(_openrctDataDirectoryPath));
|
||||
log_verbose("Trying to use OpenRCT2 data in %s", _openrctDataDirectoryPath);
|
||||
}
|
||||
|
||||
void platform_get_user_directory(utf8 *outPath, const utf8 *subDirectory)
|
||||
void platform_get_user_directory(utf8 *outPath, const utf8 *subDirectory, size_t outSize)
|
||||
{
|
||||
const char separator[2] = { platform_get_path_separator(), 0 };
|
||||
char buffer[MAX_PATH];
|
||||
safe_strcpy(buffer, _userDataDirectoryPath, sizeof(buffer));
|
||||
if (subDirectory != NULL && subDirectory[0] != 0) {
|
||||
log_verbose("adding subDirectory '%s'", subDirectory);
|
||||
strncat(buffer, subDirectory, MAX_PATH - strnlen(buffer, MAX_PATH) - 1);
|
||||
strncat(buffer, separator, MAX_PATH - strnlen(buffer, MAX_PATH) - 1);
|
||||
safe_strcat_path(buffer, subDirectory, sizeof(buffer));
|
||||
path_end_with_separator(buffer, sizeof(buffer));
|
||||
}
|
||||
int len = strnlen(buffer, MAX_PATH);
|
||||
wchar_t *w_buffer = regular_to_wchar(buffer);
|
||||
w_buffer[len] = '\0';
|
||||
utf8 *path = widechar_to_utf8(w_buffer);
|
||||
free(w_buffer);
|
||||
safe_strcpy(outPath, path, MAX_PATH);
|
||||
safe_strcpy(outPath, path, outSize);
|
||||
free(path);
|
||||
log_verbose("outPath + subDirectory = '%s'", buffer);
|
||||
}
|
||||
|
|
|
@ -517,7 +517,7 @@ void platform_process_messages()
|
|||
break;
|
||||
case SDL_TEXTEDITING:
|
||||
// When inputting Korean characters, `e.edit.length` is always Zero.
|
||||
safe_strcpy(gTextInputComposition, e.edit.text, min((e.edit.length == 0) ? (strlen(e.edit.text)+1) : e.edit.length, 32));
|
||||
safe_strcpy(gTextInputComposition, e.edit.text, sizeof(gTextInputComposition));
|
||||
gTextInputCompositionStart = e.edit.start;
|
||||
gTextInputCompositionLength = e.edit.length;
|
||||
gTextInputCompositionActive = ((e.edit.length != 0 || strlen(e.edit.text) != 0) && gTextInputComposition[0] != 0);
|
||||
|
|
|
@ -178,16 +178,6 @@ void platform_get_time_local(rct2_time *out_time)
|
|||
out_time->second = systime.wSecond;
|
||||
}
|
||||
|
||||
char platform_get_path_separator()
|
||||
{
|
||||
return '\\';
|
||||
}
|
||||
|
||||
const char *platform_get_new_line()
|
||||
{
|
||||
return "\r\n";
|
||||
}
|
||||
|
||||
bool platform_file_exists(const utf8 *path)
|
||||
{
|
||||
wchar_t *wPath = utf8_to_widechar(path);
|
||||
|
@ -208,7 +198,9 @@ bool platform_directory_exists(const utf8 *path)
|
|||
bool platform_original_game_data_exists(const utf8 *path)
|
||||
{
|
||||
utf8 checkPath[MAX_PATH];
|
||||
sprintf(checkPath, "%s%c%s%c%s", path, platform_get_path_separator(), "Data", platform_get_path_separator(), "g1.dat");
|
||||
safe_strcpy(checkPath, path, MAX_PATH);
|
||||
safe_strcat_path(checkPath, "Data", MAX_PATH);
|
||||
safe_strcat_path(checkPath, "g1.dat", MAX_PATH);
|
||||
return platform_file_exists(checkPath);
|
||||
}
|
||||
|
||||
|
@ -465,8 +457,8 @@ bool platform_enumerate_directories_next(int handle, utf8 *path)
|
|||
}
|
||||
|
||||
utf8 *filename = widechar_to_utf8(enumFileInfo->data.cFileName);
|
||||
strncpy(path, filename, MAX_PATH);
|
||||
strncat(path, "\\", MAX_PATH);
|
||||
safe_strcpy(path, filename, MAX_PATH);
|
||||
path_end_with_separator(path, MAX_PATH);
|
||||
free(filename);
|
||||
return true;
|
||||
}
|
||||
|
@ -519,7 +511,6 @@ bool platform_file_delete(const utf8 *path)
|
|||
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);
|
||||
|
@ -532,18 +523,13 @@ void platform_resolve_openrct_data_path()
|
|||
free(outPathTemp);
|
||||
free(customUserDataPathW);
|
||||
|
||||
// Ensure path ends with separator
|
||||
size_t len = strlen(_userDataDirectoryPath);
|
||||
if (_userDataDirectoryPath[len - 1] != separator[0]) {
|
||||
strcat(_userDataDirectoryPath, separator);
|
||||
}
|
||||
path_end_with_separator(_userDataDirectoryPath, sizeof(_userDataDirectoryPath));
|
||||
return;
|
||||
}
|
||||
char buffer[MAX_PATH] = { 0 };
|
||||
platform_get_exe_path(buffer);
|
||||
char buffer[MAX_PATH];
|
||||
platform_get_exe_path(buffer, sizeof(buffer));
|
||||
|
||||
strncat(buffer, separator, MAX_PATH - strnlen(buffer, MAX_PATH) - 1);
|
||||
strncat(buffer, "data", MAX_PATH - strnlen(buffer, MAX_PATH) - 1);
|
||||
safe_strcat_path(buffer, "data", MAX_PATH);
|
||||
|
||||
if (platform_directory_exists(buffer))
|
||||
{
|
||||
|
@ -556,9 +542,9 @@ void platform_resolve_openrct_data_path()
|
|||
}
|
||||
}
|
||||
|
||||
void platform_get_openrct_data_path(utf8 *outPath)
|
||||
void platform_get_openrct_data_path(utf8 *outPath, size_t outSize)
|
||||
{
|
||||
safe_strcpy(outPath, _openrctDataDirectoryPath, sizeof(_openrctDataDirectoryPath));
|
||||
safe_strcpy(outPath, _openrctDataDirectoryPath, outSize);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -569,7 +555,6 @@ void platform_get_openrct_data_path(utf8 *outPath)
|
|||
void platform_resolve_user_data_path()
|
||||
{
|
||||
wchar_t wOutPath[MAX_PATH];
|
||||
const char separator[2] = { platform_get_path_separator(), 0 };
|
||||
|
||||
if (gCustomUserDataPath[0] != 0) {
|
||||
wchar_t *customUserDataPathW = utf8_to_widechar(gCustomUserDataPath);
|
||||
|
@ -582,11 +567,7 @@ void platform_resolve_user_data_path()
|
|||
free(outPathTemp);
|
||||
free(customUserDataPathW);
|
||||
|
||||
// Ensure path ends with separator
|
||||
size_t len = strlen(_userDataDirectoryPath);
|
||||
if (_userDataDirectoryPath[len - 1] != separator[0]) {
|
||||
strcat(_userDataDirectoryPath, separator);
|
||||
}
|
||||
path_end_with_separator(_userDataDirectoryPath, sizeof(_userDataDirectoryPath));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -595,23 +576,20 @@ void platform_resolve_user_data_path()
|
|||
safe_strcpy(_userDataDirectoryPath, outPathTemp, sizeof(_userDataDirectoryPath));
|
||||
free(outPathTemp);
|
||||
|
||||
strcat(_userDataDirectoryPath, separator);
|
||||
strcat(_userDataDirectoryPath, "OpenRCT2");
|
||||
strcat(_userDataDirectoryPath, separator);
|
||||
safe_strcat_path(_userDataDirectoryPath, "OpenRCT2", sizeof(_userDataDirectoryPath));
|
||||
path_end_with_separator(_userDataDirectoryPath, sizeof(_userDataDirectoryPath));
|
||||
} else {
|
||||
log_fatal("Unable to resolve user data path.");
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
void platform_get_user_directory(utf8 *outPath, const utf8 *subDirectory)
|
||||
void platform_get_user_directory(utf8 *outPath, const utf8 *subDirectory, size_t outSize)
|
||||
{
|
||||
const char separator[2] = { platform_get_path_separator(), 0 };
|
||||
|
||||
strcpy(outPath, _userDataDirectoryPath);
|
||||
safe_strcpy(outPath, _userDataDirectoryPath, outSize);
|
||||
if (subDirectory != NULL && subDirectory[0] != 0) {
|
||||
strcat(outPath, subDirectory);
|
||||
strcat(outPath, separator);
|
||||
safe_strcat_path(outPath, subDirectory, outSize);
|
||||
path_end_with_separator(outPath, outSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -624,7 +602,7 @@ void platform_show_messagebox(utf8 *message)
|
|||
*
|
||||
* rct2: 0x004080EA
|
||||
*/
|
||||
bool platform_open_common_file_dialog(utf8 *outFilename, file_dialog_desc *desc)
|
||||
bool platform_open_common_file_dialog(utf8 *outFilename, file_dialog_desc *desc, size_t outSize)
|
||||
{
|
||||
OPENFILENAMEW openFileName;
|
||||
wchar_t wcFilename[MAX_PATH];
|
||||
|
@ -651,9 +629,9 @@ bool platform_open_common_file_dialog(utf8 *outFilename, file_dialog_desc *desc)
|
|||
utf8 *ch = filters;
|
||||
for (int i = 0; i < countof(desc->filters); i++) {
|
||||
if (desc->filters[i].name != NULL) {
|
||||
strcpy(ch, desc->filters[i].name);
|
||||
safe_strcpy(ch, desc->filters[i].name, sizeof(filters) - (ch - filters));
|
||||
ch = strchr(ch, 0) + 1;
|
||||
strcpy(ch, desc->filters[i].pattern);
|
||||
safe_strcpy(ch, desc->filters[i].pattern, sizeof(filters) - (ch - filters));
|
||||
ch = strchr(ch, 0) + 1;
|
||||
}
|
||||
}
|
||||
|
@ -695,7 +673,7 @@ bool platform_open_common_file_dialog(utf8 *outFilename, file_dialog_desc *desc)
|
|||
|
||||
if (result) {
|
||||
utf8 *resultFilename = widechar_to_utf8(openFileName.lpstrFile);
|
||||
strcpy(outFilename, resultFilename);
|
||||
safe_strcpy(outFilename, resultFilename, outSize);
|
||||
free(resultFilename);
|
||||
|
||||
// If there is no extension, append the pattern
|
||||
|
@ -709,7 +687,7 @@ bool platform_open_common_file_dialog(utf8 *outFilename, file_dialog_desc *desc)
|
|||
const utf8 *pattern = desc->filters[filterIndex].pattern;
|
||||
const utf8 *patternExtension = path_get_extension(pattern);
|
||||
if (!str_is_null_or_empty(patternExtension)) {
|
||||
strcat(outFilename, patternExtension);
|
||||
safe_strcat_path(outFilename, patternExtension, outSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -775,10 +753,10 @@ int windows_get_registry_install_info(rct2_install_info *installInfo, char *sour
|
|||
HKEY hKey;
|
||||
DWORD type, size;
|
||||
|
||||
strcpy(subkeyInfogrames, "Software\\Infogrames\\");
|
||||
strcat(subkeyInfogrames, source);
|
||||
strcpy(subkeyFishTechGroup, "Software\\Fish Technology Group\\");
|
||||
strcat(subkeyFishTechGroup, source);
|
||||
safe_strcpy(subkeyInfogrames, "Software\\Infogrames\\", sizeof(subkeyInfogrames));
|
||||
safe_strcat(subkeyInfogrames, source, sizeof(subkeyInfogrames));
|
||||
safe_strcpy(subkeyFishTechGroup, "Software\\Fish Technology Group\\", sizeof(subkeyFishTechGroup));
|
||||
safe_strcat(subkeyFishTechGroup, source, sizeof(subkeyFishTechGroup));
|
||||
|
||||
if (RegOpenKeyA(HKEY_LOCAL_MACHINE, subkeyInfogrames, &hKey) != ERROR_SUCCESS)
|
||||
return 0;
|
||||
|
@ -798,7 +776,7 @@ int windows_get_registry_install_info(rct2_install_info *installInfo, char *sour
|
|||
size = 4;
|
||||
RegQueryValueExA(hKey, "InstallLevel", 0, &type, (LPBYTE)&installInfo->installLevel, &size);
|
||||
for (int i = 0; i <= 15; i++) {
|
||||
sprintf(keyName, "AddonPack%d", i);
|
||||
snprintf(keyName, 100, "AddonPack%d", i);
|
||||
size = sizeof(installInfo->expansionPackNames[i]);
|
||||
if (RegQueryValueExA(hKey, keyName, 0, &type, installInfo->expansionPackNames[i], &size) == ERROR_SUCCESS)
|
||||
installInfo->activeExpansionPacks |= (1 << i);
|
||||
|
@ -992,23 +970,21 @@ char *strndup(const char *src, size_t size)
|
|||
return (char *)dst;
|
||||
}
|
||||
|
||||
void platform_get_exe_path(utf8 *outPath)
|
||||
void platform_get_exe_path(utf8 *outPath, size_t outSize)
|
||||
{
|
||||
wchar_t exePath[MAX_PATH];
|
||||
wchar_t tempPath[MAX_PATH];
|
||||
wchar_t *exeDelimiter;
|
||||
int exeDelimiterIndex;
|
||||
|
||||
GetModuleFileNameW(NULL, exePath, MAX_PATH);
|
||||
exeDelimiter = wcsrchr(exePath, platform_get_path_separator());
|
||||
exeDelimiterIndex = (int)(exeDelimiter - exePath);
|
||||
lstrcpynW(tempPath, exePath, exeDelimiterIndex + 1);
|
||||
tempPath[exeDelimiterIndex] = L'\0';
|
||||
exeDelimiter = wcsrchr(exePath, *PATH_SEPARATOR);
|
||||
*exeDelimiter = L'\0';
|
||||
wcscpy_s(tempPath, MAX_PATH, exePath);
|
||||
_wfullpath(exePath, tempPath, MAX_PATH);
|
||||
WideCharToMultiByte(CP_UTF8, 0, exePath, countof(exePath), outPath, MAX_PATH, NULL, NULL);
|
||||
WideCharToMultiByte(CP_UTF8, 0, exePath, MAX_PATH, outPath, (int) outSize, NULL, NULL);
|
||||
}
|
||||
|
||||
bool platform_get_font_path(TTFFontDescriptor *font, utf8 *buffer)
|
||||
bool platform_get_font_path(TTFFontDescriptor *font, utf8 *buffer, size_t size)
|
||||
{
|
||||
#if !defined(__MINGW32__) && ((NTDDI_VERSION >= NTDDI_VISTA) && !defined(_USING_V110_SDK71_) && !defined(_ATL_XP_TARGETING))
|
||||
wchar_t *fontFolder;
|
||||
|
@ -1016,15 +992,13 @@ bool platform_get_font_path(TTFFontDescriptor *font, utf8 *buffer)
|
|||
{
|
||||
// Convert wchar to utf8, then copy the font folder path to the buffer.
|
||||
utf8 *outPathTemp = widechar_to_utf8(fontFolder);
|
||||
strcpy(buffer, outPathTemp);
|
||||
safe_strcpy(buffer, outPathTemp, size);
|
||||
free(outPathTemp);
|
||||
|
||||
CoTaskMemFree(fontFolder);
|
||||
|
||||
// Append the requested font's file name.
|
||||
const char separator[2] = { platform_get_path_separator(), 0 };
|
||||
strcat(buffer, separator);
|
||||
strcat(buffer, font->filename);
|
||||
safe_strcat_path(buffer, font->filename, size);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
@ -1033,8 +1007,8 @@ bool platform_get_font_path(TTFFontDescriptor *font, utf8 *buffer)
|
|||
}
|
||||
#else
|
||||
log_warning("Compatibility hack: falling back to C:\\Windows\\Fonts");
|
||||
strcpy(buffer, "C:\\Windows\\Fonts\\");
|
||||
strcat(buffer, font->filename);
|
||||
safe_strcpy(buffer, "C:\\Windows\\Fonts\\", size);
|
||||
safe_strcat_path(buffer, font->filename, size);
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
@ -1091,6 +1065,8 @@ static bool windows_setup_file_association(
|
|||
wchar_t exePathW[MAX_PATH];
|
||||
wchar_t dllPathW[MAX_PATH];
|
||||
|
||||
int printResult;
|
||||
|
||||
GetModuleFileNameW(NULL, exePathW, sizeof(exePathW));
|
||||
GetModuleFileNameW(_dllModule, dllPathW, sizeof(dllPathW));
|
||||
|
||||
|
@ -1126,7 +1102,8 @@ static bool windows_setup_file_association(
|
|||
}
|
||||
// [hRootKey\OpenRCT2.ext\DefaultIcon]
|
||||
wchar_t szIconW[MAX_PATH];
|
||||
wsprintfW(szIconW, L"\"%s\",%d", dllPathW, iconIndex);
|
||||
printResult = swprintf_s(szIconW, MAX_PATH, L"\"%s\",%d", dllPathW, iconIndex);
|
||||
assert(printResult >= 0);
|
||||
if (RegSetValueW(hKey, L"DefaultIcon", REG_SZ, szIconW, 0) != ERROR_SUCCESS) {
|
||||
goto fail;
|
||||
}
|
||||
|
@ -1143,7 +1120,8 @@ static bool windows_setup_file_association(
|
|||
|
||||
// [hRootKey\OpenRCT2.sv6\shell\open\command]
|
||||
wchar_t szCommandW[MAX_PATH];
|
||||
wsprintfW(szCommandW, L"\"%s\" %s", exePathW, commandArgsW);
|
||||
printResult = swprintf_s(szCommandW, MAX_PATH, L"\"%s\" %s", exePathW, commandArgsW);
|
||||
assert(printResult >= 0);
|
||||
if (RegSetValueW(hKey, L"shell\\open\\command", REG_SZ, szCommandW, 0) != ERROR_SUCCESS) {
|
||||
goto fail;
|
||||
}
|
||||
|
|
62
src/rct2.c
62
src/rct2.c
|
@ -204,59 +204,55 @@ int rct2_init_directories()
|
|||
{
|
||||
// windows_get_registry_install_info((rct2_install_info*)0x009AA10C, "RollerCoaster Tycoon 2 Setup", "MS Sans Serif", 0);
|
||||
|
||||
char separator[] = {platform_get_path_separator(), 0};
|
||||
|
||||
if (str_is_null_or_empty(gCustomRCT2DataPath)) {
|
||||
// check install directory
|
||||
if (!platform_original_game_data_exists(gConfigGeneral.game_path)) {
|
||||
log_verbose("install directory does not exist or invalid directory selected, %s", gConfigGeneral.game_path);
|
||||
if (!config_find_or_browse_install_directory()) {
|
||||
utf8 path[MAX_PATH];
|
||||
config_get_default_path(path);
|
||||
config_get_default_path(path, sizeof(path));
|
||||
log_fatal("Invalid RCT2 installation path. Please correct \"game_path\" in %s.", path);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
strcpy(gRCT2AddressAppPath, gConfigGeneral.game_path);
|
||||
safe_strcpy(gRCT2AddressAppPath, gConfigGeneral.game_path, sizeof(gRCT2AddressAppPath));
|
||||
} else {
|
||||
strcpy(gRCT2AddressAppPath, gCustomRCT2DataPath);
|
||||
safe_strcpy(gRCT2AddressAppPath, gCustomRCT2DataPath, sizeof(gRCT2AddressAppPath));
|
||||
}
|
||||
strcat(gRCT2AddressAppPath, separator);
|
||||
path_end_with_separator(gRCT2AddressAppPath, sizeof(gRCT2AddressAppPath));
|
||||
|
||||
strcpy(gRCT2AddressSavedGamesPath, gRCT2AddressAppPath);
|
||||
strcat(gRCT2AddressSavedGamesPath, "Saved Games");
|
||||
strcat(gRCT2AddressSavedGamesPath, separator);
|
||||
safe_strcpy(gRCT2AddressSavedGamesPath, gRCT2AddressAppPath, sizeof(gRCT2AddressSavedGamesPath));
|
||||
safe_strcat_path(gRCT2AddressSavedGamesPath, "Saved Games", sizeof(gRCT2AddressSavedGamesPath));
|
||||
path_end_with_separator(gRCT2AddressSavedGamesPath, sizeof(gRCT2AddressSavedGamesPath));
|
||||
|
||||
strcpy(gRCT2AddressScenariosPath, gRCT2AddressAppPath);
|
||||
strcat(gRCT2AddressScenariosPath, "Scenarios");
|
||||
strcat(gRCT2AddressScenariosPath, separator);
|
||||
strcat(gRCT2AddressScenariosPath, "*.SC6");
|
||||
safe_strcpy(gRCT2AddressScenariosPath, gRCT2AddressAppPath, sizeof(gRCT2AddressScenariosPath));
|
||||
safe_strcat_path(gRCT2AddressScenariosPath, "Scenarios", sizeof(gRCT2AddressScenariosPath));
|
||||
safe_strcat_path(gRCT2AddressScenariosPath, "*.SC6", sizeof(gRCT2AddressScenariosPath));
|
||||
|
||||
strcpy(gRCT2AddressLandscapesPath, gRCT2AddressAppPath);
|
||||
strcat(gRCT2AddressLandscapesPath, "Landscapes");
|
||||
strcat(gRCT2AddressLandscapesPath, separator);
|
||||
strcat(gRCT2AddressLandscapesPath, "*.SC6");
|
||||
safe_strcpy(gRCT2AddressLandscapesPath, gRCT2AddressAppPath, sizeof(gRCT2AddressLandscapesPath));
|
||||
safe_strcat_path(gRCT2AddressLandscapesPath, "Landscapes", sizeof(gRCT2AddressLandscapesPath));
|
||||
safe_strcat_path(gRCT2AddressLandscapesPath, "*.SC6", sizeof(gRCT2AddressLandscapesPath));
|
||||
|
||||
strcpy(gRCT2AddressObjectDataPath, gRCT2AddressAppPath);
|
||||
strcat(gRCT2AddressObjectDataPath, "ObjData");
|
||||
strcat(gRCT2AddressObjectDataPath, separator);
|
||||
strcat(gRCT2AddressObjectDataPath, "*.DAT");
|
||||
safe_strcpy(gRCT2AddressObjectDataPath, gRCT2AddressAppPath, sizeof(gRCT2AddressObjectDataPath));
|
||||
safe_strcat_path(gRCT2AddressObjectDataPath, "ObjData", sizeof(gRCT2AddressObjectDataPath));
|
||||
safe_strcat_path(gRCT2AddressObjectDataPath, "*.DAT", sizeof(gRCT2AddressObjectDataPath));
|
||||
|
||||
strcpy(gRCT2AddressTracksPath, gRCT2AddressAppPath);
|
||||
strcat(gRCT2AddressTracksPath, "Tracks");
|
||||
strcat(gRCT2AddressTracksPath, separator);
|
||||
strcat(gRCT2AddressTracksPath, "*.TD?");
|
||||
safe_strcpy(gRCT2AddressTracksPath, gRCT2AddressAppPath, sizeof(gRCT2AddressTracksPath));
|
||||
safe_strcat_path(gRCT2AddressTracksPath, "Tracks", sizeof(gRCT2AddressTracksPath));
|
||||
safe_strcat_path(gRCT2AddressTracksPath, "*.TD?", sizeof(gRCT2AddressTracksPath));
|
||||
|
||||
strcpy(gRCT2AddressSavedGamesPath2, gRCT2AddressSavedGamesPath);
|
||||
safe_strcpy(gRCT2AddressSavedGamesPath2, gRCT2AddressSavedGamesPath, sizeof(gRCT2AddressSavedGamesPath2));
|
||||
return 1;
|
||||
}
|
||||
|
||||
void substitute_path(char *dest, const char *path, const char *filename)
|
||||
void substitute_path(char *dest, size_t size, const char *path, const char *filename)
|
||||
{
|
||||
while (*path != '*') {
|
||||
size_t written = 0;
|
||||
while (*path != '*' && *path != '\0' && written < size) {
|
||||
*dest++ = *path++;
|
||||
++written;
|
||||
}
|
||||
strcpy(dest, filename);
|
||||
safe_strcpy(dest, filename, size - written);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -331,7 +327,7 @@ static void rct2_draw_fps(rct_drawpixelinfo *dpi)
|
|||
ch = utf8_write_codepoint(ch, FORMAT_OUTLINE);
|
||||
ch = utf8_write_codepoint(ch, FORMAT_WHITE);
|
||||
|
||||
sprintf(ch, "%d", _currentFPS);
|
||||
snprintf(ch, 64 - (ch - buffer), "%d", _currentFPS);
|
||||
|
||||
// Draw Text
|
||||
int stringWidth = gfx_get_string_width(buffer);
|
||||
|
@ -351,7 +347,7 @@ bool rct2_open_file(const char *path)
|
|||
extension++;
|
||||
|
||||
if (_stricmp(extension, "sv6") == 0) {
|
||||
strcpy((char*)gRCT2AddressSavedGamesPath2, path);
|
||||
safe_strcpy((char*)gRCT2AddressSavedGamesPath2, path, sizeof(gRCT2AddressSavedGamesPath2));
|
||||
if (game_load_save(path)) {
|
||||
gFirstTimeSave = 0;
|
||||
return true;
|
||||
|
@ -359,7 +355,7 @@ bool rct2_open_file(const char *path)
|
|||
} else if (_stricmp(extension, "sc6") == 0) {
|
||||
// TODO scenario install
|
||||
rct_scenario_basic scenarioBasic;
|
||||
strcpy(scenarioBasic.path, path);
|
||||
safe_strcpy(scenarioBasic.path, path, sizeof(scenarioBasic.path));
|
||||
if (scenario_load_and_play_from_path(scenarioBasic.path)) {
|
||||
return true;
|
||||
}
|
||||
|
@ -471,7 +467,7 @@ void rct2_update()
|
|||
const utf8 *get_file_path(int pathId)
|
||||
{
|
||||
static utf8 path[MAX_PATH];
|
||||
strcpy(path, gRCT2AddressAppPath);
|
||||
safe_strcpy(path, gRCT2AddressAppPath, sizeof(path));
|
||||
safe_strcat_path(path, RCT2FilePaths[pathId], sizeof(path));
|
||||
return path;
|
||||
}
|
||||
|
|
|
@ -292,7 +292,7 @@ int rct2_init_directories();
|
|||
int rct2_startup_checks();
|
||||
void rct2_dispose();
|
||||
void rct2_update();
|
||||
void substitute_path(char *dest, const char *path, const char *filename);
|
||||
void substitute_path(char *dest, size_t size, const char *path, const char *filename);
|
||||
int check_mutex();
|
||||
int check_file_paths();
|
||||
int check_file_path(int pathId);
|
||||
|
|
|
@ -38,6 +38,7 @@ extern "C"
|
|||
#include "../ride/ride_ratings.h"
|
||||
#include "../scenario.h"
|
||||
#include "../util/sawyercoding.h"
|
||||
#include "../util/util.h"
|
||||
#include "../world/climate.h"
|
||||
#include "../world/map_animation.h"
|
||||
#include "../world/park.h"
|
||||
|
@ -381,7 +382,7 @@ void S6Exporter::Export()
|
|||
memcpy(_s6.park_entrance_y, gParkEntranceY, sizeof(_s6.park_entrance_y));
|
||||
memcpy(_s6.park_entrance_z, gParkEntranceZ, sizeof(_s6.park_entrance_z));
|
||||
memcpy(_s6.park_entrance_direction, gParkEntranceDirection, sizeof(_s6.park_entrance_direction));
|
||||
strncpy(_s6.scenario_filename, _scenarioFileName, sizeof(_s6.scenario_filename) - 1);
|
||||
safe_strcpy(_s6.scenario_filename, _scenarioFileName, sizeof(_s6.scenario_filename));
|
||||
memcpy(_s6.saved_expansion_pack_names, gScenarioExpansionPacks, sizeof(_s6.saved_expansion_pack_names));
|
||||
memcpy(_s6.banners, gBanners, sizeof(_s6.banners));
|
||||
memcpy(_s6.custom_strings, gUserStrings, sizeof(_s6.custom_strings));
|
||||
|
|
|
@ -263,7 +263,7 @@ rct_ride_entry *get_ride_entry_by_ride(rct_ride *ride)
|
|||
if (type == NULL)
|
||||
{
|
||||
char oldname[128];
|
||||
format_string(oldname, ride->name, &ride->name_arguments);
|
||||
format_string(oldname, 128, ride->name, &ride->name_arguments);
|
||||
log_error("Invalid ride subtype for ride %s", oldname);
|
||||
}
|
||||
return type;
|
||||
|
@ -5607,7 +5607,7 @@ void game_command_set_ride_name(int *eax, int *ebx, int *ecx, int *edx, int *esi
|
|||
*ebx = MONEY32_UNDEFINED;
|
||||
return;
|
||||
}
|
||||
format_string(oldName, ride->name, &ride->name_arguments);
|
||||
format_string(oldName, 128, ride->name, &ride->name_arguments);
|
||||
if (strcmp(oldName, newName) == 0) {
|
||||
*ebx = 0;
|
||||
return;
|
||||
|
@ -5811,7 +5811,7 @@ static bool ride_name_exists(char *name)
|
|||
int i;
|
||||
|
||||
FOR_ALL_RIDES(i, ride) {
|
||||
format_string(buffer, ride->name, &ride->name_arguments);
|
||||
format_string(buffer, 256, ride->name, &ride->name_arguments);
|
||||
if (strcmp(buffer, name) == 0) {
|
||||
return true;
|
||||
}
|
||||
|
@ -6015,7 +6015,7 @@ foundRideEntry:
|
|||
name_args.number = 0;
|
||||
do {
|
||||
name_args.number++;
|
||||
format_string(rideNameBuffer, 1, &name_args);
|
||||
format_string(rideNameBuffer, 256, 1, &name_args);
|
||||
} while (ride_name_exists(rideNameBuffer));
|
||||
ride->name = 1;
|
||||
ride->name_arguments_type_name = name_args.type_name;
|
||||
|
@ -6031,7 +6031,7 @@ foundRideEntry:
|
|||
rct_string_id rideNameStringId = 0;
|
||||
for (int i = 0; i < 100; i++) {
|
||||
ride->name_arguments_number++;
|
||||
format_string(rideNameBuffer, ride->name, &ride->name_arguments);
|
||||
format_string(rideNameBuffer, 256, ride->name, &ride->name_arguments);
|
||||
|
||||
rideNameStringId = user_string_allocate(4, rideNameBuffer);
|
||||
if (rideNameStringId != 0) {
|
||||
|
@ -8589,7 +8589,7 @@ void ride_reset_all_names()
|
|||
name_args.number = 0;
|
||||
do {
|
||||
name_args.number++;
|
||||
format_string(rideNameBuffer, 1, &name_args);
|
||||
format_string(rideNameBuffer, 256, 1, &name_args);
|
||||
} while (ride_name_exists(rideNameBuffer));
|
||||
|
||||
ride->name = 1;
|
||||
|
|
|
@ -180,15 +180,15 @@ bool track_design_index_rename(const utf8 *path, const utf8 *newName)
|
|||
}
|
||||
|
||||
utf8 newPath[MAX_PATH];
|
||||
const char *lastPathSep = strrchr(path, platform_get_path_separator());
|
||||
const char *lastPathSep = strrchr(path, *PATH_SEPARATOR);
|
||||
if (lastPathSep == NULL) {
|
||||
gGameCommandErrorText = STR_CANT_RENAME_TRACK_DESIGN;
|
||||
return false;
|
||||
}
|
||||
size_t directoryLength = (size_t)(lastPathSep - path + 1);
|
||||
memcpy(newPath, path, directoryLength);
|
||||
strcpy(newPath + directoryLength, newName);
|
||||
strcat(newPath, ".td6");
|
||||
safe_strcpy(newPath + directoryLength, newName, sizeof(newPath) - directoryLength);
|
||||
path_append_extension(newPath, ".td6", sizeof(newPath));
|
||||
|
||||
if (!platform_file_move(path, newPath)) {
|
||||
gGameCommandErrorText = STR_ANOTHER_FILE_EXISTS_WITH_NAME_OR_FILE_IS_WRITE_PROTECTED;
|
||||
|
@ -271,7 +271,7 @@ static void track_design_index_scan()
|
|||
track_design_index_include(directory);
|
||||
|
||||
// Get track directory from user directory
|
||||
platform_get_user_directory(directory, "track");
|
||||
platform_get_user_directory(directory, "track", sizeof(directory));
|
||||
track_design_index_include(directory);
|
||||
|
||||
// Sort items by ride type then by filename
|
||||
|
@ -360,6 +360,6 @@ static void track_design_index_dispose()
|
|||
|
||||
static void track_design_index_get_path(utf8 * buffer, size_t bufferLength)
|
||||
{
|
||||
platform_get_user_directory(buffer, NULL);
|
||||
safe_strcat(buffer, "tracks.idx", bufferLength);
|
||||
platform_get_user_directory(buffer, NULL, bufferLength);
|
||||
safe_strcat_path(buffer, "tracks.idx", bufferLength);
|
||||
}
|
||||
|
|
|
@ -172,7 +172,7 @@ bool track_design_save(uint8 rideIndex)
|
|||
}
|
||||
|
||||
utf8 track_name[MAX_PATH];
|
||||
format_string(track_name, ride->name, &ride->name_arguments);
|
||||
format_string(track_name, MAX_PATH, ride->name, &ride->name_arguments);
|
||||
|
||||
window_loadsave_open(LOADSAVETYPE_TRACK | LOADSAVETYPE_SAVE, track_name);
|
||||
gLoadSaveCallback = track_design_save_callback;
|
||||
|
|
|
@ -237,15 +237,15 @@ void scenario_begin()
|
|||
char *buffer = gCommonStringFormatBuffer;
|
||||
|
||||
// Set localised park name
|
||||
format_string(buffer, stex->park_name, 0);
|
||||
format_string(buffer, 256, stex->park_name, 0);
|
||||
park_set_name(buffer);
|
||||
|
||||
// Set localised scenario name
|
||||
format_string(buffer, stex->scenario_name, 0);
|
||||
format_string(buffer, 256, stex->scenario_name, 0);
|
||||
safe_strcpy(gScenarioName, buffer, 64);
|
||||
|
||||
// Set localised scenario details
|
||||
format_string(buffer, stex->details, 0);
|
||||
format_string(buffer, 256, stex->details, 0);
|
||||
safe_strcpy(gScenarioDetails, buffer, 256);
|
||||
}
|
||||
}
|
||||
|
@ -253,15 +253,15 @@ void scenario_begin()
|
|||
|
||||
// Set the last saved game path
|
||||
char parkName[128];
|
||||
format_string(parkName, gParkName, &gParkNameArgs);
|
||||
format_string(parkName, 128, gParkName, &gParkNameArgs);
|
||||
|
||||
platform_get_user_directory(gScenarioSavePath, "save");
|
||||
strncat(gScenarioSavePath, parkName, sizeof(gScenarioSavePath) - strlen(gScenarioSavePath) - 1);
|
||||
strncat(gScenarioSavePath, ".sv6", sizeof(gScenarioSavePath) - strlen(gScenarioSavePath) - 1);
|
||||
platform_get_user_directory(gScenarioSavePath, "save", sizeof(gScenarioSavePath));
|
||||
safe_strcat_path(gScenarioSavePath, parkName, sizeof(gScenarioSavePath));
|
||||
path_append_extension(gScenarioSavePath, ".sv6", sizeof(gScenarioSavePath));
|
||||
|
||||
strcpy(gRCT2AddressSavedGamesPath2, gRCT2AddressSavedGamesPath);
|
||||
strcpy(gRCT2AddressSavedGamesPath2 + strlen(gRCT2AddressSavedGamesPath2), gScenarioSavePath);
|
||||
strcat(gRCT2AddressSavedGamesPath2, ".SV6");
|
||||
safe_strcpy(gRCT2AddressSavedGamesPath2, gRCT2AddressSavedGamesPath, MAX_PATH);
|
||||
safe_strcat_path(gRCT2AddressSavedGamesPath2, gScenarioSavePath, MAX_PATH);
|
||||
path_append_extension(gRCT2AddressSavedGamesPath2, ".SV6", MAX_PATH);
|
||||
|
||||
gCurrentExpenditure = 0;
|
||||
gCurrentProfit = 0;
|
||||
|
@ -270,7 +270,7 @@ void scenario_begin()
|
|||
gScenarioCompletedCompanyValue = MONEY32_UNDEFINED;
|
||||
gTotalAdmissions = 0;
|
||||
gTotalIncomeFromAdmissions = 0;
|
||||
strcpy(gScenarioCompletedBy, "?");
|
||||
safe_strcpy(gScenarioCompletedBy, "?", sizeof(gScenarioCompletedBy));
|
||||
park_reset_history();
|
||||
finance_reset_history();
|
||||
award_reset();
|
||||
|
@ -312,7 +312,7 @@ static void scenario_end()
|
|||
|
||||
void scenario_set_filename(const char *value)
|
||||
{
|
||||
substitute_path(_scenarioPath, gRCT2AddressScenariosPath, value);
|
||||
substitute_path(_scenarioPath, sizeof(_scenarioPath), gRCT2AddressScenariosPath, value);
|
||||
_scenarioFileName = path_get_filename(_scenarioPath);
|
||||
}
|
||||
|
||||
|
@ -679,14 +679,14 @@ int scenario_prepare_for_save()
|
|||
rct_stex_entry* stex = g_stexEntries[0];
|
||||
if ((intptr_t)stex != -1) {
|
||||
char buffer[256];
|
||||
format_string(buffer, stex->scenario_name, NULL);
|
||||
format_string(buffer, 256, stex->scenario_name, NULL);
|
||||
safe_strcpy(gS6Info.name, buffer, sizeof(gS6Info.name));
|
||||
|
||||
memcpy(&gS6Info.entry, &object_entry_groups[OBJECT_TYPE_SCENARIO_TEXT].entries[0], sizeof(rct_object_entry));
|
||||
}
|
||||
|
||||
if (gS6Info.name[0] == 0)
|
||||
format_string(gS6Info.name, gParkName, &gParkNameArgs);
|
||||
format_string(gS6Info.name, 64, gParkName, &gParkNameArgs);
|
||||
|
||||
gS6Info.objective_type = gScenarioObjectiveType;
|
||||
gS6Info.objective_arg_1 = gScenarioObjectiveYear;
|
||||
|
|
|
@ -38,7 +38,7 @@ static int scenario_list_sort_by_category(const void *a, const void *b);
|
|||
static int scenario_list_sort_by_index(const void *a, const void *b);
|
||||
|
||||
static bool scenario_scores_load();
|
||||
static void scenario_scores_legacy_get_path(utf8 *outPath);
|
||||
static void scenario_scores_legacy_get_path(utf8 *outPath, size_t size);
|
||||
static bool scenario_scores_legacy_load(const utf8 *path);
|
||||
static void scenario_highscore_remove(scenario_highscore_entry *higscore);
|
||||
static void scenario_highscore_list_dispose();
|
||||
|
@ -61,14 +61,14 @@ void scenario_load_list()
|
|||
scenario_list_include(directory);
|
||||
|
||||
// Get scenario directory from user directory
|
||||
platform_get_user_directory(directory, "scenario");
|
||||
platform_get_user_directory(directory, "scenario", sizeof(directory));
|
||||
scenario_list_include(directory);
|
||||
|
||||
scenario_list_sort();
|
||||
scenario_scores_load();
|
||||
|
||||
utf8 scoresPath[MAX_PATH];
|
||||
scenario_scores_legacy_get_path(scoresPath);
|
||||
scenario_scores_legacy_get_path(scoresPath, sizeof(scoresPath));
|
||||
scenario_scores_legacy_load(scoresPath);
|
||||
scenario_scores_legacy_load(get_file_path(PATH_ID_SCORES));
|
||||
}
|
||||
|
@ -289,19 +289,19 @@ scenario_index_entry *scenario_list_find_by_path(const utf8 *path)
|
|||
/**
|
||||
* Gets the path for the scenario scores path.
|
||||
*/
|
||||
static void scenario_scores_get_path(utf8 *outPath)
|
||||
static void scenario_scores_get_path(utf8 *outPath, size_t size)
|
||||
{
|
||||
platform_get_user_directory(outPath, NULL);
|
||||
strcat(outPath, "highscores.dat");
|
||||
platform_get_user_directory(outPath, NULL, size);
|
||||
safe_strcat_path(outPath, "highscores.dat", size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the path for the scenario scores path.
|
||||
*/
|
||||
static void scenario_scores_legacy_get_path(utf8 *outPath)
|
||||
static void scenario_scores_legacy_get_path(utf8 *outPath, size_t size)
|
||||
{
|
||||
platform_get_user_directory(outPath, NULL);
|
||||
strcat(outPath, "scores.dat");
|
||||
platform_get_user_directory(outPath, NULL, size);
|
||||
safe_strcat_path(outPath, "scores.dat", size);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -380,7 +380,7 @@ static bool scenario_scores_legacy_load(const utf8 *path)
|
|||
static bool scenario_scores_load()
|
||||
{
|
||||
utf8 scoresPath[MAX_PATH];
|
||||
scenario_scores_get_path(scoresPath);
|
||||
scenario_scores_get_path(scoresPath, sizeof(scoresPath));
|
||||
|
||||
// Load scores file
|
||||
SDL_RWops *file = SDL_RWFromFile(scoresPath, "rb");
|
||||
|
@ -431,7 +431,7 @@ static bool scenario_scores_load()
|
|||
bool scenario_scores_save()
|
||||
{
|
||||
utf8 scoresPath[MAX_PATH];
|
||||
scenario_scores_get_path(scoresPath);
|
||||
scenario_scores_get_path(scoresPath, sizeof(scoresPath));
|
||||
|
||||
SDL_RWops *file = SDL_RWFromFile(scoresPath, "wb");
|
||||
if (file == NULL) {
|
||||
|
|
17
src/title.c
17
src/title.c
|
@ -366,7 +366,6 @@ static void title_do_next_script_opcode()
|
|||
case TITLE_SCRIPT_LOAD:
|
||||
{
|
||||
char *ch, filename[32], path[MAX_PATH];
|
||||
char separator = platform_get_path_separator();
|
||||
|
||||
// Get filename
|
||||
ch = filename;
|
||||
|
@ -379,12 +378,11 @@ static void title_do_next_script_opcode()
|
|||
safe_strcpy(path, gConfigTitleSequences.presets[_scriptCurrentPreset].path, MAX_PATH);
|
||||
}
|
||||
else {
|
||||
platform_get_user_directory(path, "title sequences");
|
||||
strcat(path, gConfigTitleSequences.presets[_scriptCurrentPreset].name);
|
||||
strncat(path, &separator, 1);
|
||||
platform_get_user_directory(path, "title sequences", sizeof(path));
|
||||
safe_strcat_path(path, gConfigTitleSequences.presets[_scriptCurrentPreset].name, sizeof(path));
|
||||
}
|
||||
|
||||
strcat(path, filename);
|
||||
safe_strcat_path(path, filename, sizeof(path));
|
||||
if (title_load_park(path)) {
|
||||
_scriptNoLoadsSinceRestart = 0;
|
||||
gTitleScriptSave = gConfigTitleSequences.presets[gCurrentPreviewTitleSequence].commands[gTitleScriptCommand].saveIndex;
|
||||
|
@ -504,7 +502,7 @@ void DrawOpenRCT2(rct_drawpixelinfo *dpi, int x, int y)
|
|||
gfx_draw_string(dpi, buffer, 0, x + 5, y + 5 - 13);
|
||||
|
||||
// Write platform information
|
||||
sprintf(ch, "%s (%s)", OPENRCT2_PLATFORM, OPENRCT2_ARCHITECTURE);
|
||||
snprintf(ch, 256 - (ch - buffer), "%s (%s)", OPENRCT2_PLATFORM, OPENRCT2_ARCHITECTURE);
|
||||
gfx_draw_string(dpi, buffer, 0, x + 5, y + 5);
|
||||
}
|
||||
|
||||
|
@ -624,11 +622,10 @@ static uint8 *title_script_load()
|
|||
char parts[3 * 128], *token, *part1, *part2, *src;
|
||||
|
||||
utf8 path[MAX_PATH];
|
||||
utf8 dataPath[MAX_PATH];
|
||||
utf8 filePath[] = "title/script.txt";
|
||||
|
||||
platform_get_openrct_data_path(dataPath);
|
||||
sprintf(path, "%s%c%s", dataPath, platform_get_path_separator(), filePath);
|
||||
platform_get_openrct_data_path(path, sizeof(path));
|
||||
safe_strcat_path(path, "title", MAX_PATH);
|
||||
safe_strcat_path(path, "script.txt", MAX_PATH);
|
||||
log_verbose("loading title script, %s", path);
|
||||
file = SDL_RWFromFile(path, "r");
|
||||
if (file == NULL) {
|
||||
|
|
|
@ -65,7 +65,7 @@ bool filename_valid_characters(const utf8 *filename)
|
|||
utf8 *path_get_directory(const utf8 *path)
|
||||
{
|
||||
// Find the last slash or backslash in the path
|
||||
char *filename = strrchr(path, platform_get_path_separator());
|
||||
char *filename = strrchr(path, *PATH_SEPARATOR);
|
||||
|
||||
// If the path is invalid (e.g. just a file name), return NULL
|
||||
if (filename == NULL)
|
||||
|
@ -80,7 +80,7 @@ utf8 *path_get_directory(const utf8 *path)
|
|||
const char *path_get_filename(const utf8 *path)
|
||||
{
|
||||
// Find last slash or backslash in the path
|
||||
char *filename = strrchr(path, platform_get_path_separator());
|
||||
char *filename = strrchr(path, *PATH_SEPARATOR);
|
||||
|
||||
// Checks if the path is valid (e.g. not just a file name)
|
||||
if (filename == NULL)
|
||||
|
@ -112,24 +112,23 @@ const char *path_get_extension(const utf8 *path)
|
|||
return extension;
|
||||
}
|
||||
|
||||
void path_set_extension(utf8 *path, const utf8 *newExtension)
|
||||
void path_set_extension(utf8 *path, const utf8 *newExtension, size_t size)
|
||||
{
|
||||
// Remove existing extension (check first if there is one)
|
||||
if (path_get_extension(path) < strrchr(path, '\0'))
|
||||
path_remove_extension(path);
|
||||
// Append new extension
|
||||
path_append_extension(path, newExtension);
|
||||
path_append_extension(path, newExtension, size);
|
||||
}
|
||||
|
||||
void path_append_extension(utf8 *path, const utf8 *newExtension)
|
||||
void path_append_extension(utf8 *path, const utf8 *newExtension, size_t size)
|
||||
{
|
||||
// Append a dot to the filename if the new extension doesn't start with it
|
||||
char *endOfString = strrchr(path, '\0');
|
||||
if (newExtension[0] != '.')
|
||||
*endOfString++ = '.';
|
||||
safe_strcat(path, ".", size);
|
||||
|
||||
// Append the extension to the path
|
||||
safe_strcpy(endOfString, newExtension, MAX_PATH - (endOfString - path) - 1);
|
||||
safe_strcat(path, newExtension, size);
|
||||
}
|
||||
|
||||
void path_remove_extension(utf8 *path)
|
||||
|
@ -142,6 +141,14 @@ void path_remove_extension(utf8 *path)
|
|||
log_warning("No extension found. (path = %s)", path);
|
||||
}
|
||||
|
||||
void path_end_with_separator(utf8 *path, size_t size) {
|
||||
size_t length = strnlen(path, size);
|
||||
if (length >= size - 1) return;
|
||||
|
||||
if (path[length - 1] != *PATH_SEPARATOR)
|
||||
safe_strcat(path, PATH_SEPARATOR, size);
|
||||
}
|
||||
|
||||
bool readentirefile(const utf8 *path, void **outBuffer, size_t *outLength)
|
||||
{
|
||||
SDL_RWops *fp;
|
||||
|
@ -338,18 +345,7 @@ char *safe_strcat(char *destination, const char *source, size_t size)
|
|||
|
||||
char *safe_strcat_path(char *destination, const char *source, size_t size)
|
||||
{
|
||||
const char pathSeparator = platform_get_path_separator();
|
||||
|
||||
size_t length = strnlen(destination, size);
|
||||
if (length >= size - 1) {
|
||||
return destination;
|
||||
}
|
||||
|
||||
if (destination[length - 1] != pathSeparator) {
|
||||
destination[length] = pathSeparator;
|
||||
destination[length + 1] = '\0';
|
||||
}
|
||||
|
||||
path_end_with_separator(destination, size);
|
||||
return safe_strcat(destination, source, size);
|
||||
}
|
||||
|
||||
|
|
|
@ -31,9 +31,10 @@ bool filename_valid_characters(const utf8 *filename);
|
|||
char *path_get_directory(const utf8 *path);
|
||||
const char *path_get_filename(const utf8 *path);
|
||||
const char *path_get_extension(const utf8 *path);
|
||||
void path_set_extension(utf8 *path, const utf8 *newExtension);
|
||||
void path_append_extension(utf8 *path, const utf8 *newExtension);
|
||||
void path_set_extension(utf8 *path, const utf8 *newExtension, size_t size);
|
||||
void path_append_extension(utf8 *path, const utf8 *newExtension, size_t size);
|
||||
void path_remove_extension(utf8 *path);
|
||||
void path_end_with_separator(utf8 *path, size_t size);
|
||||
bool readentirefile(const utf8 *path, void **outBuffer, size_t *outLength);
|
||||
|
||||
int bitscanforward(int source);
|
||||
|
|
|
@ -205,7 +205,8 @@ static bool window_changelog_read_file()
|
|||
{
|
||||
window_changelog_dispose_file();
|
||||
utf8 path[MAX_PATH];
|
||||
sprintf(path, "%s%cchangelog.txt", gExePath, platform_get_path_separator());
|
||||
safe_strcpy(path, gExePath, MAX_PATH);
|
||||
safe_strcat_path(path, "changelog.txt", MAX_PATH);
|
||||
if (!readentirefile(path, (void**)&_changelogText, &_changelogTextSize)) {
|
||||
log_error("Unable to read changelog.txt");
|
||||
return false;
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "../localisation/localisation.h"
|
||||
#include "../interface/widget.h"
|
||||
#include "../interface/window.h"
|
||||
#include "../util/util.h"
|
||||
#include "dropdown.h"
|
||||
|
||||
enum WINDOW_CUSTOM_CURRENCY_WIDGET_IDX {
|
||||
|
@ -238,13 +239,13 @@ static void custom_currency_window_text_input(struct rct_window *w, int widgetIn
|
|||
char* end;
|
||||
switch(widgetIndex){
|
||||
case WIDX_SYMBOL_TEXT:
|
||||
strncpy(
|
||||
safe_strcpy(
|
||||
CurrencyDescriptors[CURRENCY_CUSTOM].symbol_unicode,
|
||||
text,
|
||||
CURRENCY_SYMBOL_MAX_SIZE
|
||||
);
|
||||
|
||||
strncpy(
|
||||
safe_strcpy(
|
||||
gConfigGeneral.custom_currency_symbol,
|
||||
CurrencyDescriptors[CURRENCY_CUSTOM].symbol_unicode,
|
||||
CURRENCY_SYMBOL_MAX_SIZE
|
||||
|
|
|
@ -133,7 +133,7 @@ void window_dropdown_show_text(int x, int y, int extray, uint8 colour, uint8 fla
|
|||
// Calculate the longest string width
|
||||
max_string_width = 0;
|
||||
for (i = 0; i < num_items; i++) {
|
||||
format_string(buffer, gDropdownItemsFormat[i], (void*)(&gDropdownItemsArgs[i]));
|
||||
format_string(buffer, 256, gDropdownItemsFormat[i], (void*)(&gDropdownItemsArgs[i]));
|
||||
gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM;
|
||||
string_width = gfx_get_string_width(buffer);
|
||||
max_string_width = max(string_width, max_string_width);
|
||||
|
|
|
@ -895,7 +895,7 @@ static void window_editor_inventions_list_scrollpaint(rct_window *w, rct_drawpix
|
|||
ptr = utf8_write_codepoint(ptr, colour & 0xFF);
|
||||
}
|
||||
|
||||
format_string(ptr, stringId, NULL);
|
||||
format_string(ptr, 256, stringId, NULL);
|
||||
|
||||
if (disableItemMovement) {
|
||||
gCurrentFontSpriteBase = -1;
|
||||
|
@ -931,7 +931,7 @@ static void window_editor_inventions_list_drag_open(rct_research_item *researchI
|
|||
_editorInventionsListDraggedItem = researchItem;
|
||||
|
||||
stringId = research_item_get_name(researchItem->entryIndex & 0xFFFFFF);
|
||||
format_string(buffer, stringId, NULL);
|
||||
format_string(buffer, 256, stringId, NULL);
|
||||
stringWidth = gfx_get_string_width(buffer);
|
||||
window_editor_inventions_list_drag_widgets[0].right = stringWidth;
|
||||
|
||||
|
|
|
@ -1446,13 +1446,13 @@ static void window_editor_object_selection_scrollpaint(rct_window *w, rct_drawpi
|
|||
if (ridePage) {
|
||||
// Draw ride type
|
||||
rct_string_id rideTypeStringId = get_ride_type_string_id(listItem->repositoryItem);
|
||||
strcpy(buffer, language_get_string(rideTypeStringId));
|
||||
safe_strcpy(buffer, language_get_string(rideTypeStringId), 256 - (buffer - bufferWithColour));
|
||||
gfx_draw_string(dpi, bufferWithColour, colour, x, y);
|
||||
x = w->widgets[WIDX_LIST_SORT_RIDE].left - w->widgets[WIDX_LIST].left;
|
||||
}
|
||||
|
||||
// Draw text
|
||||
strcpy(buffer, listItem->repositoryItem->Name);
|
||||
safe_strcpy(buffer, listItem->repositoryItem->Name, 256 - (buffer - bufferWithColour));
|
||||
if (gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER) {
|
||||
while (*buffer != 0 && *buffer != 9)
|
||||
buffer++;
|
||||
|
@ -1629,7 +1629,7 @@ static int window_editor_object_selection_select_object(uint8 bh, int flags, con
|
|||
|
||||
if (bh != 0 && !(flags & (1 << 1))) {
|
||||
char objectName[64];
|
||||
object_create_identifier_name(objectName, &item->ObjectEntry);
|
||||
object_create_identifier_name(objectName, 64, &item->ObjectEntry);
|
||||
set_format_arg(0, const char *, objectName);
|
||||
set_object_selection_error(bh, STR_OBJECT_SELECTION_ERR_SHOULD_SELECT_X_FIRST);
|
||||
return 0;
|
||||
|
|
|
@ -794,10 +794,10 @@ static void window_editor_objective_options_main_textinput(rct_window *w, int wi
|
|||
park_set_name(text);
|
||||
|
||||
if (gS6Info.name[0] == 0)
|
||||
format_string(gS6Info.name, gParkName, &gParkNameArgs);
|
||||
format_string(gS6Info.name, 64, gParkName, &gParkNameArgs);
|
||||
break;
|
||||
case WIDX_SCENARIO_NAME:
|
||||
strncpy(gS6Info.name, text, 64);
|
||||
safe_strcpy(gS6Info.name, text, 64);
|
||||
if (strnlen(gS6Info.name, 64) == 64)
|
||||
{
|
||||
gS6Info.name[64 - 1] = '\0';
|
||||
|
@ -806,7 +806,7 @@ static void window_editor_objective_options_main_textinput(rct_window *w, int wi
|
|||
window_invalidate(w);
|
||||
break;
|
||||
case WIDX_DETAILS:
|
||||
strncpy(gS6Info.details, text, 256);
|
||||
safe_strcpy(gS6Info.details, text, 256);
|
||||
if (strnlen(gS6Info.details, 256) == 256)
|
||||
{
|
||||
gS6Info.details[256 - 1] = '\0';
|
||||
|
|
|
@ -87,14 +87,14 @@ void window_error_open(rct_string_id title, rct_string_id message)
|
|||
// Format the title
|
||||
dst = utf8_write_codepoint(dst, FORMAT_BLACK);
|
||||
if (title != STR_NONE) {
|
||||
format_string(dst, title, gCommonFormatArgs);
|
||||
format_string(dst, 512 - (dst - _window_error_text), title, gCommonFormatArgs);
|
||||
dst = get_string_end(dst);
|
||||
}
|
||||
|
||||
// Format the message
|
||||
if (message != STR_NONE) {
|
||||
dst = utf8_write_codepoint(dst, FORMAT_NEWLINE);
|
||||
format_string(dst, message, gCommonFormatArgs);
|
||||
format_string(dst, 512 - (dst - _window_error_text), message, gCommonFormatArgs);
|
||||
dst = get_string_end(dst);
|
||||
}
|
||||
|
||||
|
|
|
@ -378,15 +378,15 @@ static void window_install_track_design(rct_window *w)
|
|||
{
|
||||
utf8 destPath[MAX_PATH];
|
||||
|
||||
platform_get_user_directory(destPath, "track");
|
||||
platform_get_user_directory(destPath, "track", sizeof(destPath));
|
||||
if (!platform_ensure_directory_exists(destPath)) {
|
||||
log_error("Unable to create directory '%s'", destPath);
|
||||
window_error_open(STR_CANT_SAVE_TRACK_DESIGN, STR_NONE);
|
||||
return;
|
||||
}
|
||||
|
||||
strcat(destPath, _trackName);
|
||||
strcat(destPath, ".td6");
|
||||
safe_strcat_path(destPath, _trackName, sizeof(destPath));
|
||||
path_append_extension(destPath, ".td6", sizeof(destPath));
|
||||
|
||||
if (platform_file_exists(destPath)) {
|
||||
log_info("%s already exists, prompting user for a different track design name", destPath);
|
||||
|
|
|
@ -139,12 +139,12 @@ static void window_loadsave_sort_list(int index, int endIndex);
|
|||
|
||||
static rct_window *window_overwrite_prompt_open(const char *name, const char *path);
|
||||
|
||||
static int window_loadsave_get_dir(utf8 *last_save, char *path, const char *subdir)
|
||||
static int window_loadsave_get_dir(utf8 *last_save, char *path, const char *subdir, size_t pathSize)
|
||||
{
|
||||
if (last_save && platform_ensure_directory_exists(last_save))
|
||||
safe_strcpy(path, last_save, MAX_PATH);
|
||||
safe_strcpy(path, last_save, pathSize);
|
||||
else
|
||||
platform_get_user_directory(path, subdir);
|
||||
platform_get_user_directory(path, subdir, pathSize);
|
||||
|
||||
if (!platform_ensure_directory_exists(path)) {
|
||||
log_error("Unable to create save directory.");
|
||||
|
@ -183,28 +183,28 @@ rct_window *window_loadsave_open(int type, char *defaultName)
|
|||
switch (type & 0x0E) {
|
||||
case LOADSAVETYPE_GAME:
|
||||
w->widgets[WIDX_TITLE].text = isSave ? STR_FILE_DIALOG_TITLE_SAVE_GAME : STR_FILE_DIALOG_TITLE_LOAD_GAME;
|
||||
if (window_loadsave_get_dir(gConfigGeneral.last_save_game_directory, path, "save")) {
|
||||
if (window_loadsave_get_dir(gConfigGeneral.last_save_game_directory, path, "save", sizeof(path))) {
|
||||
window_loadsave_populate_list(w, isSave, path, ".sv6");
|
||||
success = true;
|
||||
}
|
||||
break;
|
||||
case LOADSAVETYPE_LANDSCAPE:
|
||||
w->widgets[WIDX_TITLE].text = isSave ? STR_FILE_DIALOG_TITLE_SAVE_LANDSCAPE : STR_FILE_DIALOG_TITLE_LOAD_LANDSCAPE;
|
||||
if (window_loadsave_get_dir(gConfigGeneral.last_save_landscape_directory, path, "landscape")) {
|
||||
if (window_loadsave_get_dir(gConfigGeneral.last_save_landscape_directory, path, "landscape", sizeof(path))) {
|
||||
window_loadsave_populate_list(w, isSave, path, ".sc6");
|
||||
success = true;
|
||||
}
|
||||
break;
|
||||
case LOADSAVETYPE_SCENARIO:
|
||||
w->widgets[WIDX_TITLE].text = STR_FILE_DIALOG_TITLE_SAVE_SCENARIO;
|
||||
if (window_loadsave_get_dir(gConfigGeneral.last_save_scenario_directory, path, "scenario")) {
|
||||
if (window_loadsave_get_dir(gConfigGeneral.last_save_scenario_directory, path, "scenario", sizeof(path))) {
|
||||
window_loadsave_populate_list(w, isSave, path, ".sc6");
|
||||
success = true;
|
||||
}
|
||||
break;
|
||||
case LOADSAVETYPE_TRACK:
|
||||
w->widgets[WIDX_TITLE].text = isSave ? STR_FILE_DIALOG_TITLE_SAVE_TRACK : STR_FILE_DIALOG_TITLE_INSTALL_NEW_TRACK_DESIGN;
|
||||
if (window_loadsave_get_dir(gConfigGeneral.last_save_track_directory, path, "track")) {
|
||||
if (window_loadsave_get_dir(gConfigGeneral.last_save_track_directory, path, "track", sizeof(path))) {
|
||||
window_loadsave_populate_list(w, isSave, path, ".td?");
|
||||
success = true;
|
||||
}
|
||||
|
@ -233,11 +233,11 @@ static void window_loadsave_close(rct_window *w)
|
|||
window_close_by_class(WC_LOADSAVE_OVERWRITE_PROMPT);
|
||||
}
|
||||
|
||||
static bool browse(bool isSave, char *path)
|
||||
static bool browse(bool isSave, char *path, size_t pathSize)
|
||||
{
|
||||
safe_strcpy(path, _directory, MAX_PATH);
|
||||
safe_strcpy(path, _directory, pathSize);
|
||||
if (isSave)
|
||||
strcat(path, _defaultName);
|
||||
safe_strcat_path(path, _defaultName, pathSize);
|
||||
|
||||
file_dialog_desc desc = { 0 };
|
||||
desc.initial_directory = _directory;
|
||||
|
@ -269,7 +269,7 @@ static bool browse(bool isSave, char *path)
|
|||
}
|
||||
|
||||
desc.title = language_get_string(title);
|
||||
return platform_open_common_file_dialog(path, &desc);
|
||||
return platform_open_common_file_dialog(path, &desc, pathSize);
|
||||
}
|
||||
|
||||
static void window_loadsave_mouseup(rct_window *w, int widgetIndex)
|
||||
|
@ -291,7 +291,7 @@ static void window_loadsave_mouseup(rct_window *w, int widgetIndex)
|
|||
window_text_input_open(w, WIDX_NEW, STR_NONE, STR_FILEBROWSER_NAME_PROMPT, STR_STRING, (uintptr_t)&_defaultName, 64);
|
||||
break;
|
||||
case WIDX_BROWSE:
|
||||
if (browse(isSave, path))
|
||||
if (browse(isSave, path, sizeof(path)))
|
||||
window_loadsave_select(w, path);
|
||||
break;
|
||||
case WIDX_SORT_NAME:
|
||||
|
@ -317,16 +317,16 @@ static void window_loadsave_mouseup(rct_window *w, int widgetIndex)
|
|||
case WIDX_DEFAULT:
|
||||
switch (_type & 0x0E) {
|
||||
case LOADSAVETYPE_GAME:
|
||||
platform_get_user_directory(path, "save");
|
||||
platform_get_user_directory(path, "save", sizeof(path));
|
||||
break;
|
||||
case LOADSAVETYPE_LANDSCAPE:
|
||||
platform_get_user_directory(path, "landscape");
|
||||
platform_get_user_directory(path, "landscape", sizeof(path));
|
||||
break;
|
||||
case LOADSAVETYPE_SCENARIO:
|
||||
platform_get_user_directory(path, "scenario");
|
||||
platform_get_user_directory(path, "scenario", sizeof(path));
|
||||
break;
|
||||
case LOADSAVETYPE_TRACK:
|
||||
platform_get_user_directory(path, "track");
|
||||
platform_get_user_directory(path, "track", sizeof(path));
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -411,8 +411,8 @@ static void window_loadsave_textinput(rct_window *w, int widgetIndex, char *text
|
|||
}
|
||||
|
||||
safe_strcpy(path, _directory, sizeof(path));
|
||||
strncat(path, text, sizeof(path) - strnlen(path, MAX_PATH) - 1);
|
||||
strncat(path, _extension, sizeof(path) - strnlen(path, MAX_PATH) - 1);
|
||||
safe_strcat_path(path, text, sizeof(path));
|
||||
path_append_extension(path, _extension, sizeof(path));
|
||||
|
||||
overwrite = 0;
|
||||
for (i = 0; i < _listItemsCount; i++) {
|
||||
|
@ -563,7 +563,7 @@ static void window_loadsave_populate_list(rct_window *w, int includeNewItem, con
|
|||
// If the drive exists, list it
|
||||
loadsave_list_item *listItem = &_listItems[_listItemsCount];
|
||||
|
||||
sprintf(listItem->path, "%c:%c", 'A' + x, platform_get_path_separator());
|
||||
snprintf(listItem->path, sizeof(listItem->path), "%c:" PATH_SEPARATOR, 'A' + x);
|
||||
safe_strcpy(listItem->name, listItem->path, sizeof(listItem->name));
|
||||
listItem->type = TYPE_DIRECTORY;
|
||||
|
||||
|
@ -572,15 +572,14 @@ static void window_loadsave_populate_list(rct_window *w, int includeNewItem, con
|
|||
}
|
||||
}
|
||||
else {
|
||||
char separator = platform_get_path_separator();
|
||||
|
||||
// Remove the separator at the end of the path, if present
|
||||
safe_strcpy(_parentDirectory, directory, sizeof(_parentDirectory));
|
||||
if (_parentDirectory[strlen(_parentDirectory) - 1] == separator)
|
||||
if (_parentDirectory[strlen(_parentDirectory) - 1] == *PATH_SEPARATOR)
|
||||
_parentDirectory[strlen(_parentDirectory) - 1] = '\0';
|
||||
|
||||
// Remove everything past the now last separator
|
||||
char *ch = strrchr(_parentDirectory, separator);
|
||||
char *ch = strrchr(_parentDirectory, *PATH_SEPARATOR);
|
||||
if (ch != NULL) {
|
||||
*(ch + 1) = '\0';
|
||||
} else if (drives) {
|
||||
|
@ -588,7 +587,7 @@ static void window_loadsave_populate_list(rct_window *w, int includeNewItem, con
|
|||
_parentDirectory[0] = '\0';
|
||||
} else {
|
||||
// Else, go to the root directory
|
||||
sprintf(_parentDirectory, "%c", separator);
|
||||
snprintf(_parentDirectory, MAX_PATH, "%c", *PATH_SEPARATOR);
|
||||
}
|
||||
|
||||
// Disable the Up button if the current directory is the root directory
|
||||
|
@ -623,7 +622,7 @@ static void window_loadsave_populate_list(rct_window *w, int includeNewItem, con
|
|||
char filter[MAX_PATH];
|
||||
safe_strcpy(filter, directory, sizeof(filter));
|
||||
safe_strcat_path(filter, "*", sizeof(filter));
|
||||
safe_strcat(filter, extension, sizeof(filter));
|
||||
path_append_extension(filter, extension, sizeof(filter));
|
||||
|
||||
file_info fileInfo;
|
||||
fileEnumHandle = platform_enumerate_files_begin(filter);
|
||||
|
@ -675,10 +674,10 @@ static void window_loadsave_select(rct_window *w, const char *path)
|
|||
save_path(&gConfigGeneral.last_save_game_directory, path);
|
||||
if (gLoadSaveTitleSequenceSave) {
|
||||
utf8 newName[MAX_PATH];
|
||||
char *extension = (char*)path_get_extension(path);
|
||||
const char *extension = path_get_extension(path);
|
||||
safe_strcpy(newName, path_get_filename(path), MAX_PATH);
|
||||
if (_stricmp(extension, ".sv6") != 0 && _stricmp(extension, ".sc6") != 0)
|
||||
strcat(newName, ".sv6");
|
||||
path_append_extension(newName, ".sv6", sizeof(newName));
|
||||
if (title_sequence_save_exists(gCurrentTitleSequence, newName)) {
|
||||
set_format_arg(0, intptr_t, (intptr_t)&_listItems[w->selected_list_item].name);
|
||||
window_text_input_open(w, WIDX_SCROLL, STR_FILEBROWSER_RENAME_SAVE_TITLE, STR_ERROR_EXISTING_NAME, STR_STRING, (uintptr_t)_listItems[w->selected_list_item].name, TITLE_SEQUENCE_MAX_SAVE_LENGTH - 1);
|
||||
|
@ -789,10 +788,10 @@ static void window_loadsave_select(rct_window *w, const char *path)
|
|||
break;
|
||||
case (LOADSAVETYPE_SAVE | LOADSAVETYPE_TRACK) :
|
||||
{
|
||||
char *p = _strdup(path);
|
||||
path_set_extension(p, "td6");
|
||||
char p[MAX_PATH];
|
||||
safe_strcpy(p, path, sizeof(p));
|
||||
path_set_extension(p, "td6", sizeof(p));
|
||||
int success = track_design_save_to_file(p);
|
||||
free(p);
|
||||
|
||||
if (success) {
|
||||
window_close_by_class(WC_LOADSAVE);
|
||||
|
@ -914,15 +913,12 @@ static void window_overwrite_prompt_paint(rct_window *w, rct_drawpixelinfo *dpi)
|
|||
{
|
||||
window_draw_widgets(w, dpi);
|
||||
|
||||
rct_string_id templateStringId = STR_PLACEHOLDER;
|
||||
char *templateString;
|
||||
|
||||
templateString = (char*)language_get_string(templateStringId);
|
||||
strcpy(templateString, _window_overwrite_prompt_name);
|
||||
set_format_arg(0, rct_string_id, STR_STRING);
|
||||
set_format_arg(2, char *, _window_overwrite_prompt_name);
|
||||
|
||||
int x = w->x + w->width / 2;
|
||||
int y = w->y + (w->height / 2) - 3;
|
||||
gfx_draw_string_centred_wrapped(dpi, &templateStringId, x, y, w->width - 4, STR_FILEBROWSER_OVERWRITE_PROMPT, 0);
|
||||
gfx_draw_string_centred_wrapped(dpi, gCommonFormatArgs, x, y, w->width - 4, STR_FILEBROWSER_OVERWRITE_PROMPT, 0);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -610,7 +610,7 @@ static void window_multiplayer_players_scrollpaint(rct_window *w, rct_drawpixeli
|
|||
int colour = 0;
|
||||
if (i == w->selected_list_item) {
|
||||
gfx_fill_rect(dpi, 0, y, 800, y + 9, 0x02000031);
|
||||
safe_strcpy(&buffer[0], network_get_player_name(i), sizeof(buffer));
|
||||
safe_strcpy(buffer, network_get_player_name(i), sizeof(buffer));
|
||||
colour = w->colours[2];
|
||||
} else {
|
||||
if (network_get_player_flags(i) & NETWORK_PLAYER_FLAG_ISSERVER) {
|
||||
|
@ -652,7 +652,7 @@ static void window_multiplayer_players_scrollpaint(rct_window *w, rct_drawpixeli
|
|||
} else {
|
||||
lineCh = utf8_write_codepoint(lineCh, FORMAT_RED);
|
||||
}
|
||||
sprintf(lineCh, "%d ms", ping);
|
||||
snprintf(lineCh, sizeof(buffer) - (lineCh - buffer), "%d ms", ping);
|
||||
gfx_draw_string(dpi, buffer, colour, 356, y - 1);
|
||||
}
|
||||
y += 10;
|
||||
|
@ -819,11 +819,11 @@ static void window_multiplayer_groups_paint(rct_window *w, rct_drawpixelinfo *dp
|
|||
rct_widget* widget = &window_multiplayer_groups_widgets[WIDX_DEFAULT_GROUP];
|
||||
int group = network_get_group_index(network_get_default_group());
|
||||
if (group != -1) {
|
||||
char buffer[300] = {0};
|
||||
char buffer[300];
|
||||
char* lineCh;
|
||||
lineCh = buffer;
|
||||
lineCh = utf8_write_codepoint(lineCh, FORMAT_WINDOW_COLOUR_2);
|
||||
strcpy(lineCh, network_get_group_name(group));
|
||||
safe_strcpy(lineCh, network_get_group_name(group), sizeof(buffer) - (lineCh - buffer));
|
||||
set_format_arg(0, const char *, buffer);
|
||||
gfx_draw_string_centred_clipped(
|
||||
dpi,
|
||||
|
@ -848,11 +848,11 @@ static void window_multiplayer_groups_paint(rct_window *w, rct_drawpixelinfo *dp
|
|||
widget = &window_multiplayer_groups_widgets[WIDX_SELECTED_GROUP];
|
||||
group = network_get_group_index(_selectedGroup);
|
||||
if (group != -1) {
|
||||
char buffer[300] = {0};
|
||||
char buffer[300];
|
||||
char* lineCh;
|
||||
lineCh = buffer;
|
||||
lineCh = utf8_write_codepoint(lineCh, FORMAT_WINDOW_COLOUR_2);
|
||||
strcpy(lineCh, network_get_group_name(group));
|
||||
safe_strcpy(lineCh, network_get_group_name(group), sizeof(buffer) - (lineCh - buffer));
|
||||
set_format_arg(0, const char *, buffer);
|
||||
gfx_draw_string_centred_clipped(
|
||||
dpi,
|
||||
|
|
|
@ -145,7 +145,7 @@ static void window_network_status_update(rct_window *w)
|
|||
|
||||
static void window_network_status_textinput(rct_window *w, int widgetIndex, char *text)
|
||||
{
|
||||
strcpy(_password, "");
|
||||
_password[0] = '\0';
|
||||
switch (widgetIndex) {
|
||||
case WIDX_PASSWORD:
|
||||
if (text != NULL)
|
||||
|
@ -177,7 +177,7 @@ static void window_network_status_paint(rct_window *w, rct_drawpixelinfo *dpi)
|
|||
char buffer[sizeof(window_network_status_text) + 10];
|
||||
char* lineCh = buffer;
|
||||
lineCh = utf8_write_codepoint(lineCh, FORMAT_BLACK);
|
||||
strcpy(lineCh, window_network_status_text);
|
||||
safe_strcpy(lineCh, window_network_status_text, sizeof(buffer) - (lineCh - buffer));
|
||||
gfx_clip_string(buffer, w->widgets[WIDX_BACKGROUND].right - 50);
|
||||
int x = w->x + (w->width / 2);
|
||||
int y = w->y + (w->height / 2);
|
||||
|
|
|
@ -114,8 +114,8 @@ static int ride_name_compare(const void *a, const void *b)
|
|||
rideA = get_ride(*((uint8*)a));
|
||||
rideB = get_ride(*((uint8*)b));
|
||||
|
||||
format_string(rideAName, rideA->name, &rideA->name_arguments);
|
||||
format_string(rideBName, rideB->name, &rideB->name_arguments);
|
||||
format_string(rideAName, 256, rideA->name, &rideA->name_arguments);
|
||||
format_string(rideBName, 256, rideB->name, &rideB->name_arguments);
|
||||
|
||||
return _strcmpi(rideAName, rideBName);
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "../ride/ride_data.h"
|
||||
#include "../sprites.h"
|
||||
#include "../ride/track_data.h"
|
||||
#include "../util/util.h"
|
||||
|
||||
static uint8 _windowNewRideCurrentTab;
|
||||
static ride_list_item _windowNewRideHighlightedItem[6];
|
||||
|
@ -311,7 +312,7 @@ static void window_new_ride_populate_list()
|
|||
}
|
||||
|
||||
char preferredVehicleName[9];
|
||||
strcpy(preferredVehicleName," ");
|
||||
safe_strcpy(preferredVehicleName, " ", sizeof(preferredVehicleName));
|
||||
|
||||
if (ride_type_is_invented(rideType)) {
|
||||
int dh = 0;
|
||||
|
@ -338,11 +339,11 @@ static void window_new_ride_populate_list()
|
|||
// Skip if the vehicle isn't the preferred vehicle for this generic track type
|
||||
if (gConfigInterface.select_by_track_type && (!(rideEntry->flags & RIDE_ENTRY_FLAG_SEPARATE_RIDE) || rideTypeShouldLoseSeparateFlag(rideEntry))) {
|
||||
if (strcmp(preferredVehicleName, " \0") == 0) {
|
||||
strcpy(preferredVehicleName, rideEntryName);
|
||||
safe_strcpy(preferredVehicleName, rideEntryName, sizeof(preferredVehicleName));
|
||||
preferredVehicleName[8] = 0;
|
||||
} else {
|
||||
if (vehicle_preference_compare(rideType, preferredVehicleName, rideEntryName) == 1) {
|
||||
strcpy(preferredVehicleName, rideEntryName);
|
||||
safe_strcpy(preferredVehicleName, rideEntryName, sizeof(preferredVehicleName));
|
||||
preferredVehicleName[8] = 0;
|
||||
} else {
|
||||
continue;
|
||||
|
|
|
@ -360,11 +360,11 @@ void window_player_overview_paint(rct_window *w, rct_drawpixelinfo *dpi)
|
|||
int groupindex = network_get_group_index(network_get_player_group(player));
|
||||
if (groupindex != -1) {
|
||||
rct_widget* widget = &window_player_overview_widgets[WIDX_GROUP];
|
||||
char buffer[300] = {0};
|
||||
char buffer[300];
|
||||
char* lineCh;
|
||||
lineCh = buffer;
|
||||
lineCh = utf8_write_codepoint(lineCh, FORMAT_WINDOW_COLOUR_2);
|
||||
strcpy(lineCh, network_get_group_name(groupindex));
|
||||
safe_strcpy(lineCh, network_get_group_name(groupindex), sizeof(buffer) - (lineCh - buffer));
|
||||
set_format_arg(0, const char *, buffer);
|
||||
|
||||
gfx_draw_string_centred_clipped(
|
||||
|
@ -385,7 +385,7 @@ void window_player_overview_paint(rct_window *w, rct_drawpixelinfo *dpi)
|
|||
set_format_arg(0, rct_string_id, STR_PING);
|
||||
gfx_draw_string_left(dpi, STR_WINDOW_COLOUR_2_STRINGID, gCommonFormatArgs, 0, x, y);
|
||||
char ping[64];
|
||||
sprintf(ping, "%d ms", network_get_player_ping(player));
|
||||
snprintf(ping, 64, "%d ms", network_get_player_ping(player));
|
||||
gfx_draw_string(dpi, ping, w->colours[2], x + 30, y);
|
||||
|
||||
// Draw last action
|
||||
|
|
|
@ -729,10 +729,10 @@ static void window_ride_list_refresh_list(rct_window *w)
|
|||
int current_list_position = list_index;
|
||||
switch (w->list_information_type) {
|
||||
case INFORMATION_TYPE_STATUS:
|
||||
format_string_to_upper(bufferA, ride->name, &ride->name_arguments);
|
||||
format_string_to_upper(bufferA, 128, ride->name, &ride->name_arguments);
|
||||
while (--current_list_position >= 0) {
|
||||
otherRide = get_ride(w->list_item_positions[current_list_position]);
|
||||
format_string_to_upper(bufferB, otherRide->name, &otherRide->name_arguments);
|
||||
format_string_to_upper(bufferB, 128, otherRide->name, &otherRide->name_arguments);
|
||||
if (strcmp(bufferA, bufferB) >= 0)
|
||||
break;
|
||||
|
||||
|
|
|
@ -480,7 +480,7 @@ static void window_server_list_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi
|
|||
char players[32];
|
||||
players[0] = 0;
|
||||
if (serverDetails->maxplayers > 0) {
|
||||
sprintf(players, "%d/%d", serverDetails->players, serverDetails->maxplayers);
|
||||
snprintf(players, 32, "%d/%d", serverDetails->players, serverDetails->maxplayers);
|
||||
}
|
||||
int numPlayersStringWidth = gfx_get_string_width(players);
|
||||
gfx_draw_string(dpi, players, w->colours[1], right - numPlayersStringWidth, y + 3);
|
||||
|
@ -525,8 +525,8 @@ static void server_list_load_server_entries()
|
|||
utf8 path[MAX_PATH];
|
||||
SDL_RWops *file;
|
||||
|
||||
platform_get_user_directory(path, NULL);
|
||||
strcat(path, "servers.cfg");
|
||||
platform_get_user_directory(path, NULL, sizeof(path));
|
||||
safe_strcat_path(path, "servers.cfg", sizeof(path));
|
||||
|
||||
file = SDL_RWFromFile(path, "rb");
|
||||
if (file == NULL) {
|
||||
|
@ -564,8 +564,8 @@ static void server_list_save_server_entries()
|
|||
utf8 path[MAX_PATH];
|
||||
SDL_RWops *file;
|
||||
|
||||
platform_get_user_directory(path, NULL);
|
||||
strcat(path, "servers.cfg");
|
||||
platform_get_user_directory(path, NULL, sizeof(path));
|
||||
safe_strcat_path(path, "servers.cfg", sizeof(path));
|
||||
|
||||
file = SDL_RWFromFile(path, "wb");
|
||||
if (file == NULL) {
|
||||
|
|
|
@ -140,7 +140,7 @@ void window_server_start_open()
|
|||
window->page = 0;
|
||||
window->list_information_type = 0;
|
||||
|
||||
sprintf(_port, "%u", gConfigNetwork.default_port);
|
||||
snprintf(_port, 7, "%u", gConfigNetwork.default_port);
|
||||
safe_strcpy(_name, gConfigNetwork.server_name, sizeof(_name));
|
||||
}
|
||||
|
||||
|
|
|
@ -256,14 +256,13 @@ static void window_shortcut_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, i
|
|||
gfx_fill_rect(dpi, 0, y, 800, y + 9, 0x2000031);
|
||||
}
|
||||
|
||||
// TODO: How does this work? 2525 is '???'
|
||||
rct_string_id templateStringId = STR_SHORTCUT_KEY_UNKNOWN;
|
||||
char *templateString = (char*)language_get_string(templateStringId);
|
||||
keyboard_shortcut_format_string(templateString, gShortcutKeys[i]);
|
||||
char templateString[128];
|
||||
keyboard_shortcut_format_string(templateString, 128, gShortcutKeys[i]);
|
||||
|
||||
set_format_arg(0, rct_string_id, STR_SHORTCUT_ENTRY_FORMAT);
|
||||
set_format_arg(2, rct_string_id, ShortcutStringIds[i]);
|
||||
set_format_arg(4, rct_string_id, templateStringId);
|
||||
set_format_arg(4, rct_string_id, STR_STRING);
|
||||
set_format_arg(6, char *, templateString);
|
||||
gfx_draw_string_left(dpi, format, gCommonFormatArgs, 0, 0, y - 1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -107,11 +107,7 @@ void window_text_input_open(rct_window* call_w, int call_widget, rct_string_id t
|
|||
// Enter in the the text input buffer any existing
|
||||
// text.
|
||||
if (existing_text != STR_NONE)
|
||||
format_string(text_input, existing_text, &existing_args);
|
||||
|
||||
// In order to prevent strings that exceed the maxLength
|
||||
// from crashing the game.
|
||||
text_input[maxLength - 1] = '\0';
|
||||
format_string(text_input, maxLength, existing_text, &existing_args);
|
||||
|
||||
utf8_remove_format_codes(text_input, false);
|
||||
|
||||
|
|
|
@ -573,8 +573,8 @@ static void window_tile_inspector_paint(rct_window *w, rct_drawpixelinfo *dpi)
|
|||
gfx_draw_string_left(dpi, STR_TILE_INSPECTOR_CHOOSE_MSG, NULL, 12, x, y);
|
||||
} else {
|
||||
char buffer[256];
|
||||
sprintf(
|
||||
buffer,
|
||||
snprintf(
|
||||
buffer, 256,
|
||||
"X: %d, Y: %d",
|
||||
window_tile_inspector_tile_x,
|
||||
window_tile_inspector_tile_y
|
||||
|
@ -614,8 +614,8 @@ static void window_tile_inspector_scrollpaint(rct_window *w, rct_drawpixelinfo *
|
|||
|
||||
switch (type) {
|
||||
case MAP_ELEMENT_TYPE_SURFACE:
|
||||
sprintf(
|
||||
buffer,
|
||||
snprintf(
|
||||
buffer, 256,
|
||||
"Surface (%s, %s)",
|
||||
language_get_string(TerrainTypes[map_element_get_terrain(element)]),
|
||||
language_get_string(TerrainEdgeTypes[map_element_get_terrain_edge(element)])
|
||||
|
@ -628,16 +628,16 @@ static void window_tile_inspector_scrollpaint(rct_window *w, rct_drawpixelinfo *
|
|||
const uint8 pathHasScenery = footpath_element_has_path_scenery(element);
|
||||
const uint8 pathAdditionType = footpath_element_get_path_scenery_index(element);
|
||||
if (footpath_element_is_queue(element)) {
|
||||
sprintf(
|
||||
buffer, "Queue (%s)%s%s for (%d)",
|
||||
snprintf(
|
||||
buffer, 256, "Queue (%s)%s%s for (%d)",
|
||||
language_get_string(get_footpath_entry(pathType)->string_idx), // Path name
|
||||
pathHasScenery ? " with " : "", // Adds " with " when there is something on the path
|
||||
pathHasScenery ? language_get_string(get_footpath_item_entry(pathAdditionType)->name) : "", // Path addition name
|
||||
element->properties.path.ride_index // Ride index for queue
|
||||
);
|
||||
} else {
|
||||
sprintf(
|
||||
buffer, "Path (%s)%s%s",
|
||||
snprintf(
|
||||
buffer, 256, "Path (%s)%s%s",
|
||||
language_get_string(get_footpath_entry(pathType)->string_idx), // Path name
|
||||
pathHasScenery ? " with " : "", // Adds " with " when there is something on the path
|
||||
pathHasScenery ? language_get_string(get_footpath_item_entry(pathAdditionType)->name) : "" // Path addition name
|
||||
|
@ -647,32 +647,32 @@ static void window_tile_inspector_scrollpaint(rct_window *w, rct_drawpixelinfo *
|
|||
type_name = buffer;
|
||||
break;
|
||||
case MAP_ELEMENT_TYPE_TRACK:
|
||||
sprintf(
|
||||
buffer,
|
||||
snprintf(
|
||||
buffer, 256,
|
||||
"Track (%s)",
|
||||
language_get_string(RideNaming[get_ride(element->properties.track.ride_index)->type].name)
|
||||
);
|
||||
type_name = buffer;
|
||||
break;
|
||||
case MAP_ELEMENT_TYPE_SCENERY:
|
||||
sprintf(
|
||||
buffer,
|
||||
snprintf(
|
||||
buffer, 256,
|
||||
"Scenery (%s)",
|
||||
language_get_string(get_small_scenery_entry(element->properties.scenery.type)->name)
|
||||
);
|
||||
type_name = buffer;
|
||||
break;
|
||||
case MAP_ELEMENT_TYPE_ENTRANCE:
|
||||
sprintf(
|
||||
buffer,
|
||||
snprintf(
|
||||
buffer, 256,
|
||||
"Entrance (%s)",
|
||||
language_get_string(EntranceTypes[element->properties.entrance.type])
|
||||
);
|
||||
type_name = buffer;
|
||||
break;
|
||||
case MAP_ELEMENT_TYPE_FENCE:
|
||||
sprintf(
|
||||
buffer,
|
||||
snprintf(
|
||||
buffer, 256,
|
||||
"Fence (%s)",
|
||||
language_get_string(get_wall_entry(element->properties.scenery.type)->name)
|
||||
);
|
||||
|
@ -682,8 +682,8 @@ static void window_tile_inspector_scrollpaint(rct_window *w, rct_drawpixelinfo *
|
|||
type_name = "Scenery multiple";
|
||||
break;
|
||||
case MAP_ELEMENT_TYPE_BANNER:
|
||||
sprintf(
|
||||
buffer,
|
||||
snprintf(
|
||||
buffer, 256,
|
||||
"Banner (%d)",
|
||||
element->properties.banner.index
|
||||
);
|
||||
|
@ -692,7 +692,7 @@ static void window_tile_inspector_scrollpaint(rct_window *w, rct_drawpixelinfo *
|
|||
case MAP_ELEMENT_TYPE_CORRUPT:
|
||||
// fall-through
|
||||
default:
|
||||
sprintf(buffer, "Unknown (type %d)", type);
|
||||
snprintf(buffer, 256, "Unknown (type %d)", type);
|
||||
type_name = buffer;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "../interface/themes.h"
|
||||
#include "../interface/title_sequences.h"
|
||||
#include "../title.h"
|
||||
#include "../util/util.h"
|
||||
#include "dropdown.h"
|
||||
|
||||
typedef struct TITLE_COMMAND_ORDER {
|
||||
|
@ -448,7 +449,7 @@ static void window_title_command_editor_textinput(rct_window *w, int widgetIndex
|
|||
window_invalidate(w);
|
||||
}
|
||||
else {
|
||||
strcpy(textbox1Buffer, text);
|
||||
safe_strcpy(textbox1Buffer, text, sizeof(textbox1Buffer));
|
||||
}
|
||||
break;
|
||||
case WIDX_TEXTBOX_X:
|
||||
|
@ -459,7 +460,7 @@ static void window_title_command_editor_textinput(rct_window *w, int widgetIndex
|
|||
window_invalidate(w);
|
||||
}
|
||||
else {
|
||||
strcpy(textbox1Buffer, text);
|
||||
safe_strcpy(textbox1Buffer, text, sizeof(textbox1Buffer));
|
||||
}
|
||||
break;
|
||||
case WIDX_TEXTBOX_Y:
|
||||
|
@ -470,7 +471,7 @@ static void window_title_command_editor_textinput(rct_window *w, int widgetIndex
|
|||
window_invalidate(w);
|
||||
}
|
||||
else {
|
||||
strcpy(textbox2Buffer, text);
|
||||
safe_strcpy(textbox2Buffer, text, sizeof(textbox2Buffer));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -295,7 +295,6 @@ void window_title_editor_close(rct_window *w)
|
|||
static void window_title_editor_mouseup(rct_window *w, int widgetIndex)
|
||||
{
|
||||
char path[MAX_PATH];
|
||||
char separator = platform_get_path_separator();
|
||||
int defaultPreset, playing, inTitle, i, commandEditorOpen;
|
||||
|
||||
defaultPreset = (gCurrentTitleSequence < TITLE_SEQUENCE_DEFAULT_PRESETS);
|
||||
|
@ -360,12 +359,11 @@ static void window_title_editor_mouseup(rct_window *w, int widgetIndex)
|
|||
}
|
||||
else {
|
||||
// TODO: This should probably use a constant
|
||||
platform_get_user_directory(path, "title sequences");
|
||||
strcat(path, gConfigTitleSequences.presets[gCurrentTitleSequence].name);
|
||||
strncat(path, &separator, 1);
|
||||
platform_get_user_directory(path, "title sequences", sizeof(path));
|
||||
safe_strcat_path(path, gConfigTitleSequences.presets[gCurrentTitleSequence].name, sizeof(path));
|
||||
}
|
||||
|
||||
strcat(path, gConfigTitleSequences.presets[gCurrentTitleSequence].saves[w->selected_list_item]);
|
||||
safe_strcat_path(path, gConfigTitleSequences.presets[gCurrentTitleSequence].saves[w->selected_list_item], sizeof(path));
|
||||
game_load_save(path);
|
||||
window_title_editor_open(1);
|
||||
}
|
||||
|
@ -905,10 +903,10 @@ void window_title_editor_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, int
|
|||
|
||||
set_format_arg(0, uintptr_t, &title->saves[i]);
|
||||
if (selected || hover) {
|
||||
format_string(buffer, STR_STRING, gCommonFormatArgs);
|
||||
format_string(buffer, 256, STR_STRING, gCommonFormatArgs);
|
||||
}
|
||||
else {
|
||||
format_string(buffer + 1, STR_STRING, gCommonFormatArgs);
|
||||
format_string(buffer + 1, 255, STR_STRING, gCommonFormatArgs);
|
||||
buffer[0] = FORMAT_BLACK;
|
||||
}
|
||||
set_format_arg(0, uintptr_t, &buffer);
|
||||
|
@ -980,10 +978,10 @@ void window_title_editor_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, int
|
|||
}
|
||||
|
||||
if ((selected || hover) && !error) {
|
||||
format_string(buffer, commandName, gCommonFormatArgs);
|
||||
format_string(buffer, 256, commandName, gCommonFormatArgs);
|
||||
}
|
||||
else {
|
||||
format_string(buffer + 1, commandName, gCommonFormatArgs);
|
||||
format_string(buffer + 1, 255, commandName, gCommonFormatArgs);
|
||||
buffer[0] = (error ? ((selected || hover) ? FORMAT_LIGHTPINK : FORMAT_RED) : FORMAT_BLACK);
|
||||
}
|
||||
set_format_arg(0, uintptr_t, &buffer);
|
||||
|
|
|
@ -484,14 +484,16 @@ static void window_scenarioselect_scrollpaint(rct_window *w, rct_drawpixelinfo *
|
|||
bool isDisabled = listItem->scenario.is_locked;
|
||||
|
||||
// Draw scenario name
|
||||
rct_string_id placeholderStringId = STR_PLACEHOLDER;
|
||||
safe_strcpy((char*)language_get_string(placeholderStringId), scenario->name, 64);
|
||||
char buffer[64];
|
||||
safe_strcpy(buffer, scenario->name, sizeof(buffer));
|
||||
rct_string_id format = isDisabled ? STR_STRINGID : (isHighlighted ? highlighted_format : unhighlighted_format);
|
||||
set_format_arg(0, rct_string_id, STR_STRING);
|
||||
set_format_arg(2, char *, buffer);
|
||||
colour = isDisabled ? w->colours[1] | 0x40 : COLOUR_BLACK;
|
||||
if (isDisabled) {
|
||||
gCurrentFontSpriteBase = -1;
|
||||
}
|
||||
gfx_draw_string_centred(dpi, format, wide ? 270 : 210, y + 1, colour, &placeholderStringId);
|
||||
gfx_draw_string_centred(dpi, format, wide ? 270 : 210, y + 1, colour, gCommonFormatArgs);
|
||||
|
||||
// Check if scenario is completed
|
||||
if (isCompleted) {
|
||||
|
@ -503,9 +505,10 @@ static void window_scenarioselect_scrollpaint(rct_window *w, rct_drawpixelinfo *
|
|||
if (!str_is_null_or_empty(scenario->highscore->name)) {
|
||||
completedByName = scenario->highscore->name;
|
||||
}
|
||||
safe_strcpy((char*)language_get_string(placeholderStringId), completedByName, 64);
|
||||
safe_strcpy(buffer, completedByName, 64);
|
||||
set_format_arg(0, rct_string_id, STR_COMPLETED_BY);
|
||||
set_format_arg(2, rct_string_id, placeholderStringId);
|
||||
set_format_arg(2, rct_string_id, STR_STRING);
|
||||
set_format_arg(4, char *, buffer);
|
||||
gfx_draw_string_centred(dpi, format, wide ? 270 : 210, y + 11, 0, gCommonFormatArgs);
|
||||
}
|
||||
|
||||
|
@ -527,7 +530,7 @@ static void draw_category_heading(rct_window *w, rct_drawpixelinfo *dpi, int lef
|
|||
|
||||
// Get string dimensions
|
||||
utf8 *buffer = gCommonStringFormatBuffer;
|
||||
format_string(buffer, stringId, NULL);
|
||||
format_string(buffer, 256, stringId, NULL);
|
||||
int categoryStringHalfWidth = (gfx_get_string_width(buffer) / 2) + 4;
|
||||
int strLeft = centreX - categoryStringHalfWidth;
|
||||
int strRight = centreX + categoryStringHalfWidth;
|
||||
|
|
|
@ -88,7 +88,7 @@ void window_tooltip_show(rct_string_id id, int x, int y)
|
|||
|
||||
char* buffer = gCommonStringFormatBuffer;
|
||||
|
||||
format_string(buffer, id, gCommonFormatArgs);
|
||||
format_string(buffer, 256, id, gCommonFormatArgs);
|
||||
gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM;
|
||||
|
||||
int tooltip_text_width;
|
||||
|
|
|
@ -39,7 +39,7 @@ enum {
|
|||
|
||||
static rct_widget window_track_manage_widgets[] = {
|
||||
{ WWT_FRAME, 0, 0, 249, 0, 43, STR_NONE, STR_NONE },
|
||||
{ WWT_CAPTION, 0, 1, 248, 1, 14, 3155, STR_WINDOW_TITLE_TIP },
|
||||
{ WWT_CAPTION, 0, 1, 248, 1, 14, STR_STRING, STR_WINDOW_TITLE_TIP },
|
||||
{ WWT_CLOSEBOX, 0, 237, 247, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP },
|
||||
{ WWT_DROPDOWN_BUTTON, 0, 10, 119, 24, 35, STR_TRACK_MANAGE_RENAME, STR_NONE },
|
||||
{ WWT_DROPDOWN_BUTTON, 0, 130, 239, 24, 35, STR_TRACK_MANAGE_DELETE, STR_NONE },
|
||||
|
@ -166,10 +166,6 @@ void window_track_manage_open(track_design_file_ref *tdFileRef)
|
|||
trackDesignListWindow->track_list.var_484 |= 1;
|
||||
}
|
||||
|
||||
// TODO: 3155 appears to be empty. What is this supposed to do?
|
||||
utf8 *title = (utf8*)language_get_string(3155);
|
||||
format_string(title, STR_TRACK_LIST_NAME_FORMAT, &tdFileRef->name);
|
||||
|
||||
_trackDesignFileReference = tdFileRef;
|
||||
}
|
||||
|
||||
|
@ -240,6 +236,7 @@ static void window_track_manage_invalidate(rct_window *w)
|
|||
*/
|
||||
static void window_track_manage_paint(rct_window *w, rct_drawpixelinfo *dpi)
|
||||
{
|
||||
set_format_arg(0, char *, _trackDesignFileReference->name);
|
||||
window_draw_widgets(w, dpi);
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ enum {
|
|||
|
||||
static rct_widget window_track_place_widgets[] = {
|
||||
{ WWT_FRAME, 0, 0, 199, 0, 123, 0xFFFFFFFF, STR_NONE },
|
||||
{ WWT_CAPTION, 0, 1, 198, 1, 14, 3155, STR_WINDOW_TITLE_TIP },
|
||||
{ WWT_CAPTION, 0, 1, 198, 1, 14, STR_STRING, STR_WINDOW_TITLE_TIP },
|
||||
{ WWT_CLOSEBOX, 0, 187, 197, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP },
|
||||
{ WWT_FLATBTN, 0, 173, 196, 83, 106, SPR_ROTATE_ARROW, STR_ROTATE_90_TIP },
|
||||
{ WWT_FLATBTN, 0, 173, 196, 59, 82, SPR_MIRROR_ARROW, STR_MIRROR_IMAGE_TIP },
|
||||
|
@ -168,10 +168,6 @@ void window_track_place_open(const track_design_file_ref *tdFileRef)
|
|||
_currentTrackPieceDirection = (2 - get_current_rotation()) & 3;
|
||||
window_track_place_draw_mini_preview(td6);
|
||||
|
||||
// TODO: 3155 appears to be empty. What is this supposed to do?
|
||||
char *title = (char*)language_get_string(3155);
|
||||
format_string(title, STR_TRACK_LIST_NAME_FORMAT, &td6->name);
|
||||
|
||||
_trackDesign = td6;
|
||||
}
|
||||
|
||||
|
@ -445,6 +441,7 @@ static void window_track_place_attempt_placement(rct_track_td6 *td6, int x, int
|
|||
*/
|
||||
static void window_track_place_paint(rct_window *w, rct_drawpixelinfo *dpi)
|
||||
{
|
||||
set_format_arg(0, char *, _trackDesign->name);
|
||||
window_draw_widgets(w, dpi);
|
||||
|
||||
// Draw mini tile preview
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "../ride/track.h"
|
||||
#include "../ride/track_data.h"
|
||||
#include "../scenario.h"
|
||||
#include "../util/util.h"
|
||||
#include "banner.h"
|
||||
#include "climate.h"
|
||||
#include "footpath.h"
|
||||
|
@ -5249,7 +5250,7 @@ void game_command_set_banner_name(int* eax, int* ebx, int* ecx, int* edx, int* e
|
|||
utf8 *buffer = gCommonStringFormatBuffer;
|
||||
utf8 *dst = buffer;
|
||||
dst = utf8_write_codepoint(dst, FORMAT_COLOUR_CODE_START + banner->text_colour);
|
||||
strncpy(dst, newName, 32);
|
||||
safe_strcpy(dst, newName, 32);
|
||||
|
||||
rct_string_id stringId = user_string_allocate(128, buffer);
|
||||
if (stringId) {
|
||||
|
@ -5388,7 +5389,7 @@ void game_command_set_banner_style(int* eax, int* ebx, int* ecx, int* edx, int*
|
|||
int colourCodepoint = FORMAT_COLOUR_CODE_START + banner->text_colour;
|
||||
|
||||
utf8 buffer[256];
|
||||
format_string(buffer, banner->string_idx, 0);
|
||||
format_string(buffer, 256, banner->string_idx, 0);
|
||||
int firstCodepoint = utf8_get_next(buffer, NULL);
|
||||
if (firstCodepoint >= FORMAT_COLOUR_CODE_START && firstCodepoint <= FORMAT_COLOUR_CODE_END) {
|
||||
utf8_write_codepoint(buffer, colourCodepoint);
|
||||
|
|
|
@ -55,7 +55,7 @@ static void money_effect_create_at(money32 value, int x, int y, int z)
|
|||
value *= -1;
|
||||
stringId = 1399;
|
||||
}
|
||||
format_string(buffer, stringId, &value);
|
||||
format_string(buffer, 128, stringId, &value);
|
||||
gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM;
|
||||
moneyEffect->offset_x = -(gfx_get_string_width(buffer) / 2);
|
||||
moneyEffect->wiggle = 0;
|
||||
|
|
|
@ -147,7 +147,7 @@ void park_init()
|
|||
award_reset();
|
||||
|
||||
gS6Info.name[0] = '\0';
|
||||
format_string(gS6Info.details, STR_NO_DETAILS_YET, NULL);
|
||||
format_string(gS6Info.details, 256, STR_NO_DETAILS_YET, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -915,7 +915,7 @@ void game_command_set_park_name(int *eax, int *ebx, int *ecx, int *edx, int *esi
|
|||
return;
|
||||
}
|
||||
|
||||
format_string(oldName, gParkName, &gParkNameArgs);
|
||||
format_string(oldName, 128, gParkName, &gParkNameArgs);
|
||||
if (strcmp(oldName, newName) == 0) {
|
||||
*ebx = 0;
|
||||
return;
|
||||
|
|
|
@ -207,7 +207,7 @@ const char * sprite_checksum()
|
|||
char *x = (char *)_spriteChecksum;
|
||||
for (unsigned int i = 0; i < size; i++)
|
||||
{
|
||||
sprintf(x, "%02x", localhash[i]);
|
||||
snprintf(x, EVP_MAX_MD_SIZE + 1, "%02x", localhash[i]);
|
||||
x += 2;
|
||||
}
|
||||
*x = '\0';
|
||||
|
|
Loading…
Reference in New Issue