From c0079919b41a0fbb8bbf104ecdc59ce2bb6e3e55 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Thu, 21 May 2015 01:35:24 +0100 Subject: [PATCH] implement user_string_allocate --- src/localisation/localisation.h | 1 + src/localisation/string_ids.h | 2 ++ src/localisation/user.c | 45 ++++++++++++++++++++++++++++----- 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/src/localisation/localisation.h b/src/localisation/localisation.h index e220b85a7a..c7bee7a75c 100644 --- a/src/localisation/localisation.h +++ b/src/localisation/localisation.h @@ -35,6 +35,7 @@ int get_string_length(char* buffer); void user_string_clear_all(); rct_string_id user_string_allocate(int base, const char *text); void user_string_free(rct_string_id id); +bool is_user_string_id(rct_string_id stringId); int win1252_to_utf8(utf8string dst, const char *src, int maxBufferLength); diff --git a/src/localisation/string_ids.h b/src/localisation/string_ids.h index eca3eac66f..1ba40c1d81 100644 --- a/src/localisation/string_ids.h +++ b/src/localisation/string_ids.h @@ -71,6 +71,8 @@ enum { STR_MONTH_SHORT_DEC = STR_MONTH_SHORT_JAN + 11, STR_CLOSE_X = 824, + STR_CHOSEN_NAME_IN_USE_ALREADY = 825, + STR_TOO_MANY_NAMES_DEFINED = 826, STR_CLOSE_WINDOW_TIP = 828, STR_WINDOW_TITLE_TIP = 829, diff --git a/src/localisation/user.c b/src/localisation/user.c index 54a856ef02..82a3375288 100644 --- a/src/localisation/user.c +++ b/src/localisation/user.c @@ -23,6 +23,8 @@ char *gUserStrings = (char*)0x0135A8F4; +static bool user_string_exists(const char *text); + /** * * rct2: 0x006C4209 @@ -38,13 +40,24 @@ void user_string_clear_all() */ rct_string_id user_string_allocate(int base, const char *text) { - int eax, ebx, ecx, edx, esi, edi, ebp; + int highBits = (base & 0x7F) << 9; + bool allowDuplicates = base & 0x80; - ecx = base; - edi = (int)text; - RCT2_CALLFUNC_X(0x006C421D, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); - - return eax & 0xFFFF; + if (!allowDuplicates && user_string_exists(text)) { + RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, rct_string_id) = STR_CHOSEN_NAME_IN_USE_ALREADY; + return 0; + } + + char *userString = gUserStrings; + for (int i = 0; i < MAX_USER_STRINGS; i++, userString += USER_STRING_MAX_LENGTH) { + if (userString[0] != 0) + continue; + + strncpy(userString, text, USER_STRING_MAX_LENGTH - 1); + return 0x8000 + (i | highBits); + } + RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, rct_string_id) = STR_TOO_MANY_NAMES_DEFINED; + return 0; } /** @@ -53,9 +66,27 @@ rct_string_id user_string_allocate(int base, const char *text) */ void user_string_free(rct_string_id id) { - if (id < 0x8000 || id >= 0x9000) + if (!is_user_string_id(id)) return; id %= MAX_USER_STRINGS; gUserStrings[id * USER_STRING_MAX_LENGTH] = 0; +} + +static bool user_string_exists(const char *text) +{ + char *userString = gUserStrings; + for (int i = 0; i < MAX_USER_STRINGS; i++, userString += USER_STRING_MAX_LENGTH) { + if (userString[0] == 0) + continue; + + if (_stricmp(userString, text) == 0) + return true; + } + return false; +} + +bool is_user_string_id(rct_string_id stringId) +{ + return stringId >= 0x8000 && id < 0x9000; } \ No newline at end of file