diff --git a/src/language.h b/src/language.h --- a/src/language.h +++ b/src/language.h @@ -21,10 +21,8 @@ static const uint8 CASE_GENDER_LEN = 16; static const uint8 MAX_NUM_GENDERS = 8; ///< Maximum number of supported genders. static const uint8 MAX_NUM_CASES = 16; ///< Maximum number of supported cases. -static const uint TAB_SIZE_OFFSET = 0; ///< The offset for the tab size. static const uint TAB_SIZE_BITS = 11; ///< The number of bits used for the tab size. static const uint TAB_SIZE = 1 << TAB_SIZE_BITS; ///< The number of values in a tab. -static const uint TAB_COUNT_OFFSET = TAB_SIZE_BITS; ///< The offset for the tab count. static const uint TAB_COUNT_BITS = 5; ///< The number of bits used for the amount of tabs. static const uint TAB_COUNT = 1 << TAB_COUNT_BITS; ///< The amount of tabs. diff --git a/src/saveload/company_sl.cpp b/src/saveload/company_sl.cpp --- a/src/saveload/company_sl.cpp +++ b/src/saveload/company_sl.cpp @@ -16,6 +16,7 @@ #include "../tunnelbridge_map.h" #include "../tunnelbridge.h" #include "../station_base.h" +#include "../strings_func.h" #include "saveload.h" @@ -501,11 +502,11 @@ static void Check_PLYR() /* We do not load old custom names */ if (IsSavegameVersionBefore(84)) { - if (GB(cprops->name_1, 11, 5) == 15) { + if (GetStringTab(cprops->name_1) == 15) { cprops->name_1 = STR_GAME_SAVELOAD_NOT_AVAILABLE; } - if (GB(cprops->president_name_1, 11, 5) == 15) { + if (GetStringTab(cprops->president_name_1) == 15) { cprops->president_name_1 = STR_GAME_SAVELOAD_NOT_AVAILABLE; } } diff --git a/src/saveload/strings_sl.cpp b/src/saveload/strings_sl.cpp --- a/src/saveload/strings_sl.cpp +++ b/src/saveload/strings_sl.cpp @@ -11,6 +11,7 @@ #include "../stdafx.h" #include "../string_func.h" +#include "../strings_func.h" #include "saveload_internal.h" #include "table/strings.h" @@ -60,7 +61,7 @@ char *_old_name_array = NULL; char *CopyFromOldName(StringID id) { /* Is this name an (old) custom name? */ - if (GB(id, 11, 5) != 15) return NULL; + if (GetStringTab(id) != 15) return NULL; if (IsSavegameVersionBefore(37)) { /* Allow for expansion when converted to UTF-8. */ diff --git a/src/saveload/town_sl.cpp b/src/saveload/town_sl.cpp --- a/src/saveload/town_sl.cpp +++ b/src/saveload/town_sl.cpp @@ -14,6 +14,7 @@ #include "../town.h" #include "../landscape.h" #include "../subsidy_func.h" +#include "../strings_func.h" #include "saveload.h" #include "newgrf_sl.h" @@ -285,7 +286,7 @@ static void Load_TOWN() SlObject(&t->received[i], _town_received_desc); } - if (t->townnamegrfid == 0 && !IsInsideMM(t->townnametype, SPECSTR_TOWNNAME_START, SPECSTR_TOWNNAME_LAST + 1) && GB(t->townnametype, 11, 5) != 15) { + if (t->townnamegrfid == 0 && !IsInsideMM(t->townnametype, SPECSTR_TOWNNAME_START, SPECSTR_TOWNNAME_LAST + 1) && GetStringTab(t->townnametype) != 15) { SlErrorCorrupt("Invalid town name generator"); } diff --git a/src/script/api/script_error.cpp b/src/script/api/script_error.cpp --- a/src/script/api/script_error.cpp +++ b/src/script/api/script_error.cpp @@ -13,6 +13,7 @@ #include "script_error.hpp" #include "../../core/bitmath_func.hpp" #include "../../string_func.h" +#include "../../strings_func.h" #include "../../safeguards.h" @@ -31,8 +32,8 @@ ScriptError::ScriptErrorMapString Script /* static */ ScriptErrorType ScriptError::StringToError(StringID internal_string_id) { - uint index = GB(internal_string_id, 11, 5); - switch (GB(internal_string_id, 11, 5)) { + uint index = GetStringIndex(internal_string_id); + switch (GetStringTab(internal_string_id)) { case 26: case 28: case 29: case 30: // NewGRF strings. return ERR_NEWGRF_SUPPLIED_ERROR; diff --git a/src/strings.cpp b/src/strings.cpp --- a/src/strings.cpp +++ b/src/strings.cpp @@ -194,14 +194,14 @@ static bool _scan_for_gender_data = fals const char *GetStringPtr(StringID string) { - switch (GB(string, TAB_COUNT_OFFSET, TAB_COUNT_BITS)) { - case GAME_TEXT_TAB: return GetGameStringPtr(GB(string, TAB_SIZE_OFFSET, TAB_SIZE_BITS)); + switch (GetStringTab(string)) { + case GAME_TEXT_TAB: return GetGameStringPtr(GetStringIndex(string)); /* 0xD0xx and 0xD4xx IDs have been converted earlier. */ case 26: NOT_REACHED(); - case 28: return GetGRFStringPtr(GB(string, TAB_SIZE_OFFSET, TAB_SIZE_BITS)); - case 29: return GetGRFStringPtr(GB(string, TAB_SIZE_OFFSET, TAB_SIZE_BITS) + 0x0800); - case 30: return GetGRFStringPtr(GB(string, TAB_SIZE_OFFSET, TAB_SIZE_BITS) + 0x1000); - default: return _langpack_offs[_langtab_start[GB(string, TAB_COUNT_OFFSET, TAB_COUNT_BITS)] + GB(string, TAB_SIZE_OFFSET, TAB_SIZE_BITS)]; + case 28: return GetGRFStringPtr(GetStringIndex(string)); + case 29: return GetGRFStringPtr(GetStringIndex(string) + 0x0800); + case 30: return GetGRFStringPtr(GetStringIndex(string) + 0x1000); + default: return _langpack_offs[_langtab_start[GetStringTab(string)] + GetStringIndex(string)]; } } @@ -219,8 +219,8 @@ char *GetStringWithArgs(char *buffr, Str { if (string == 0) return GetStringWithArgs(buffr, STR_UNDEFINED, args, last); - uint index = GB(string, TAB_SIZE_OFFSET, TAB_SIZE_BITS); - uint tab = GB(string, TAB_COUNT_OFFSET, TAB_COUNT_BITS); + uint index = GetStringIndex(string); + uint tab = GetStringTab(string); switch (tab) { case 4: @@ -886,7 +886,7 @@ static char *FormatString(char *buff, co buff = strecat(buff, "(invalid sub-StringID)", last); break; } - param = (GAME_TEXT_TAB << TAB_COUNT_OFFSET) + param; + param = MakeStringID(GAME_TEXT_TAB, param); } sub_args.SetParam(i++, param); @@ -901,7 +901,7 @@ static char *FormatString(char *buff, co /* If we didn't error out, we can actually print the string. */ if (*str != '\0') { str = p; - buff = GetStringWithArgs(buff, (GAME_TEXT_TAB << TAB_COUNT_OFFSET) + stringid, &sub_args, last, true); + buff = GetStringWithArgs(buff, MakeStringID(GAME_TEXT_TAB, stringid), &sub_args, last, true); } for (int i = 0; i < 20; i++) { @@ -1017,7 +1017,7 @@ static char *FormatString(char *buff, co case SCC_STRING: {// {STRING} StringID str = args->GetInt32(SCC_STRING); - if (game_script && GB(str, TAB_COUNT_OFFSET, TAB_COUNT_BITS) != GAME_TEXT_TAB) break; + if (game_script && GetStringTab(str) != GAME_TEXT_TAB) break; /* WARNING. It's prohibited for the included string to consume any arguments. * For included strings that consume argument, you should use STRING1, STRING2 etc. * To debug stuff you can set argv to NULL and it will tell you */ @@ -1036,7 +1036,7 @@ static char *FormatString(char *buff, co case SCC_STRING7: { // {STRING1..7} /* Strings that consume arguments */ StringID str = args->GetInt32(b); - if (game_script && GB(str, TAB_COUNT_OFFSET, TAB_COUNT_BITS) != GAME_TEXT_TAB) break; + if (game_script && GetStringTab(str) != GAME_TEXT_TAB) break; uint size = b - SCC_STRING1 + 1; if (game_script && size > args->GetDataLeft()) { buff = strecat(buff, "(too many parameters)", last); diff --git a/src/strings_func.h b/src/strings_func.h --- a/src/strings_func.h +++ b/src/strings_func.h @@ -15,6 +15,38 @@ #include "strings_type.h" #include "string_type.h" #include "gfx_type.h" +#include "core/bitmath_func.hpp" + +/** + * Extract the StringTab from a StringID. + * @param str String identifier + * @return StringTab from \a str + */ +static inline uint GetStringTab(StringID str) +{ + return GB(str, 11, 5); +} + +/** + * Extract the StringIndex from a StringID. + * @param str String identifier + * @return StringIndex from \a str + */ +static inline uint GetStringIndex(StringID str) +{ + return GB(str, 0, 11); +} + +/** + * Create a StringID + * @param tab StringTab + * @param index StringIndex + * @return StringID composed from \a tab and \a index + */ +static inline StringID MakeStringID(uint tab, uint index) +{ + return tab << 11 | index; +} class StringParameters { StringParameters *parent; ///< If not NULL, this instance references data from this parent instance.