mirror of https://github.com/OpenRCT2/OpenRCT2.git
finish partial support for language loading... new string test in cheat window
This commit is contained in:
parent
045cef2e0a
commit
cc93e6b7db
254
src/string_ids.c
254
src/string_ids.c
|
@ -1065,6 +1065,110 @@ char real_name_initials[] = {
|
|||
'B', 'C', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'R', 'S', 'T', 'W'
|
||||
};
|
||||
|
||||
#pragma region Format codes
|
||||
|
||||
typedef struct {
|
||||
char code;
|
||||
char *token;
|
||||
} format_code_token;
|
||||
|
||||
format_code_token format_code_tokens[] = {
|
||||
{ FORMAT_MOVE_X, "MOVE_X" },
|
||||
{ FORMAT_ADJUST_PALETTE, "ADJUST_PALETTE" },
|
||||
{ FORMAT_NEWLINE, "NEWLINE" },
|
||||
{ FORMAT_NEWLINE_SMALLER, "NEWLINE_SMALLER" },
|
||||
{ FORMAT_TINYFONT, "TINYFONT" },
|
||||
{ FORMAT_BIGFONT, "BIGFONT" },
|
||||
{ FORMAT_MEDIUMFONT, "MEDIUMFONT" },
|
||||
{ FORMAT_SMALLFONT, "SMALLFONT" },
|
||||
{ FORMAT_OUTLINE, "OUTLINE" },
|
||||
{ FORMAT_OUTLINE_OFF, "OUTLINE_OFF" },
|
||||
{ FORMAT_WINDOW_COLOUR_1, "WINDOW_COLOUR_1" },
|
||||
{ FORMAT_WINDOW_COLOUR_2, "WINDOW_COLOUR_2" },
|
||||
{ FORMAT_WINDOW_COLOUR_3, "WINDOW_COLOUR_3" },
|
||||
{ FORMAT_NEWLINE_X_Y, "NEWLINE_X_Y" },
|
||||
{ FORMAT_INLINE_SPRITE, "INLINE_SPRITE" },
|
||||
{ FORMAT_ENDQUOTES, "ENDQUOTES" },
|
||||
{ FORMAT_ARGUMENT_CODE_START, "ARGUMENT_CODE_START" },
|
||||
{ FORMAT_COMMA32, "COMMA32" },
|
||||
{ FORMAT_INT32, "INT32" },
|
||||
{ FORMAT_COMMA2DP32, "COMMA2DP32" },
|
||||
{ FORMAT_COMMA16, "COMMA16" },
|
||||
{ FORMAT_UINT16, "UINT16" },
|
||||
{ FORMAT_CURRENCY2DP, "CURRENCY2DP" },
|
||||
{ FORMAT_CURRENCY, "CURRENCY" },
|
||||
{ FORMAT_STRINGID, "STRINGID" },
|
||||
{ FORMAT_STRINGID2, "STRINGID2" },
|
||||
{ FORMAT_STRING, "STRING" },
|
||||
{ FORMAT_MONTHYEAR, "MONTHYEAR" },
|
||||
{ FORMAT_MONTH, "MONTH" },
|
||||
{ FORMAT_VELOCITY, "VELOCITY" },
|
||||
{ FORMAT_POP16, "POP16" },
|
||||
{ FORMAT_PUSH16, "PUSH16" },
|
||||
{ FORMAT_DURATION, "DURATION" },
|
||||
{ FORMAT_REALTIME, "REALTIME" },
|
||||
{ FORMAT_LENGTH, "LENGTH" },
|
||||
{ FORMAT_SPRITE, "SPRITE" },
|
||||
{ FORMAT_COLOUR_CODE_START, "COLOUR_CODE_START" },
|
||||
{ FORMAT_BLACK, "BLACK" },
|
||||
{ FORMAT_GREY, "GREY" },
|
||||
{ FORMAT_WHITE, "WHITE" },
|
||||
{ FORMAT_RED, "RED" },
|
||||
{ FORMAT_GREEN, "GREEN" },
|
||||
{ FORMAT_YELLOW, "YELLOW" },
|
||||
{ FORMAT_TOPAZ, "TOPAZ" },
|
||||
{ FORMAT_CELADON, "CELADON" },
|
||||
{ FORMAT_BABYBLUE, "BABYBLUE" },
|
||||
{ FORMAT_PALELAVENDER, "PALELAVENDER" },
|
||||
{ FORMAT_PALEGOLD, "PALEGOLD" },
|
||||
{ FORMAT_LIGHTPINK, "LIGHTPINK" },
|
||||
{ FORMAT_PEARLAQUA, "PEARLAQUA" },
|
||||
{ FORMAT_PALESILVER, "PALESILVER" },
|
||||
{ FORMAT_COLOUR_CODE_END, "COLOUR_CODE_END" },
|
||||
{ FORMAT_AMINUSCULE, "AMINUSCULE" },
|
||||
{ FORMAT_UP, "UP" },
|
||||
{ FORMAT_POUND, "POUND" },
|
||||
{ FORMAT_YEN, "YEN" },
|
||||
{ FORMAT_COPYRIGHT, "COPYRIGHT" },
|
||||
{ FORMAT_DOWN, "DOWN" },
|
||||
{ FORMAT_LEFTGUILLEMET, "LEFTGUILLEMET" },
|
||||
{ FORMAT_TICK, "TICK" },
|
||||
{ FORMAT_CROSS, "CROSS" },
|
||||
{ FORMAT_RIGHT, "RIGHT" },
|
||||
{ FORMAT_DEGREE, "DEGREE" },
|
||||
{ FORMAT_SQUARED, "SQUARED" },
|
||||
{ FORMAT_OPENQUOTES, "OPENQUOTES" },
|
||||
{ FORMAT_EURO, "EURO" },
|
||||
{ FORMAT_APPROX, "APPROX" },
|
||||
{ FORMAT_POWERNEGATIVEONE, "POWERNEGATIVEONE" },
|
||||
{ FORMAT_BULLET, "BULLET" },
|
||||
{ FORMAT_RIGHTGUILLEMET, "RIGHTGUILLEMET" },
|
||||
{ FORMAT_SMALLUP, "SMALLUP" },
|
||||
{ FORMAT_SMALLDOWN, "SMALLDOWN" },
|
||||
{ FORMAT_LEFT, "LEFT" },
|
||||
{ FORMAT_INVERTEDQUESTION, "INVERTEDQUESTION" }
|
||||
};
|
||||
|
||||
char format_get_code(const char *token)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < countof(format_code_tokens); i++)
|
||||
if (strcmpi(token, format_code_tokens[i].token) == 0)
|
||||
return format_code_tokens[i].code;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *format_get_token(char code)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < countof(format_code_tokens); i++)
|
||||
if (code == format_code_tokens[i].code)
|
||||
return format_code_tokens[i].token;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#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);
|
||||
|
||||
|
@ -1564,81 +1668,15 @@ void generate_string_file()
|
|||
|
||||
fprintf(f, "STR_%04d :", i);
|
||||
while (*c != '\0') {
|
||||
switch (*c) {
|
||||
case 7: fputs("{TINYFONT}", f); break;
|
||||
case 8: fputs("{BIGFONT}", f); break;
|
||||
case 9: fputs("{MEDIUMFONT}", f); break;
|
||||
case 10: fputs("{SMALLFONT}", f); break;
|
||||
|
||||
case 11: fputs("{OUTLINE}", f); break;
|
||||
|
||||
case 34: fputs("{ENDQUOTES}", f); break;
|
||||
|
||||
case 123: fputs("{COMMA32}", f); break;
|
||||
case 124: fputs("{INT32}", f); break;
|
||||
case 125: fputs("{COMMA2DP32}", f); break;
|
||||
case 126: fputs("{COMMA16}", f); break;
|
||||
case 127: fputs("{UINT16}", f); break;
|
||||
case 128: fputs("{CURRENCY2DP}", f); break;
|
||||
case 129: fputs("{CURRENCY}", f); break;
|
||||
case 130: fputs("{STRINGID}", f); break;
|
||||
case 131: fputs("{STRINGID2}", f); break;
|
||||
case 132: fputs("{STRING}", f); break;
|
||||
case 133: fputs("{MONTHYEAR}", f); break;
|
||||
case 134: fputs("{MONTH}", f); break;
|
||||
case 135: fputs("{VELOCITY}", f); break;
|
||||
case 136: fputs("{POP16}", f); break;
|
||||
case 137: fputs("{PUSH16}", f); break;
|
||||
case 138: fputs("{DURATION}", f); break;
|
||||
case 139: fputs("{REALTIME}", f); break;
|
||||
case 140: fputs("{LENGTH}", f); break;
|
||||
case 141: fputs("{SPRITE}", f); break;
|
||||
|
||||
case 142: fputs("{BLACK}", f); break;
|
||||
case 143: fputs("{GREY}", f); break;
|
||||
case 144: fputs("{WHITE}", f); break;
|
||||
case 145: fputs("{RED}", f); break;
|
||||
case 146: fputs("{GREEN}", f); break;
|
||||
case 147: fputs("{YELLOW}", f); break;
|
||||
case 148: fputs("{TOPAZ}", f); break;
|
||||
case 149: fputs("{CELADON}", f); break;
|
||||
case 150: fputs("{BABYBLUE}", f); break;
|
||||
case 151: fputs("{PALELAVENDER}", f); break;
|
||||
case 152: fputs("{PALEGOLD}", f); break;
|
||||
case 153: fputs("{LIGHTPINK}", f); break;
|
||||
case 154: fputs("{PEARLAQUA}", f); break;
|
||||
case 155: fputs("{PALESILVER}", f); break;
|
||||
|
||||
case 159: fputs("{AMINUSCULE}", f); break;
|
||||
case 160: fputs("{UP}", f); break;
|
||||
case 163: fputs("{POUND}", f); break;
|
||||
case 165: fputs("{YEN}", f); break;
|
||||
case 169: fputs("{COPYRIGHT}", f); break;
|
||||
case 170: fputs("{DOWN}", f); break;
|
||||
case 171: fputs("{LEFTGUILLEMET}", f); break;
|
||||
case 172: fputs("{TICK}", f); break;
|
||||
case 173: fputs("{CROSS}", f); break;
|
||||
case 175: fputs("{RIGHT}", f); break;
|
||||
case 176: fputs("{DEGREE}", f); break;
|
||||
case 178: fputs("{SQUARED}", f); break;
|
||||
case 180: fputs("{OPENQUOTES}", f); break;
|
||||
case 181: fputs("{EURO}", f); break;
|
||||
case 184: fputs("{APPROX}", f); break;
|
||||
case 185: fputs("{POWERNEGATIVEONE}", f); break;
|
||||
case 186: fputs("{BULLET}", f); break;
|
||||
case 187: fputs("{RIGHTGUILLEMET}", f); break;
|
||||
case 188: fputs("{SMALLUP}", f); break;
|
||||
case 189: fputs("{SMALLDOWN}", f); break;
|
||||
case 190: fputs("{LEFT}", f); break;
|
||||
case 191: fputs("{INVERTEDQUESTION}", f); break;
|
||||
default:
|
||||
const char *token = format_get_token(*c);
|
||||
if (token != NULL) {
|
||||
fprintf(f, "{%s}", token);
|
||||
} else {
|
||||
if (*c < 32 || *c > 127)
|
||||
fprintf(f, "{%d}", *c);
|
||||
else
|
||||
fputc(*c, f);
|
||||
break;
|
||||
}
|
||||
|
||||
c++;
|
||||
}
|
||||
fputc('\n', f);
|
||||
|
@ -1667,23 +1705,29 @@ char **language_strings = NULL;
|
|||
|
||||
const char *get_string(rct_string_id id)
|
||||
{
|
||||
const char *str = language_strings == NULL ?
|
||||
RCT2_ADDRESS(0x009BF2D4, const char*)[id] :
|
||||
language_strings[id];
|
||||
|
||||
const char *rct = RCT2_ADDRESS(0x009BF2D4, const char*)[id];
|
||||
const char *openrct = language_strings == NULL ? NULL : language_strings[id];
|
||||
const char *str = (openrct == NULL || strlen(openrct) == 0 ? rct : openrct);
|
||||
return str == NULL ? "" : str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Partial support to open a uncompiled language file which parses tokens and converts them to the corresponding character
|
||||
* code. Due to resource strings (strings in scenarios and objects) being written to the original game's string table,
|
||||
* get_string will use those if the same entry in the loaded language is empty.
|
||||
*
|
||||
* Unsure at how the original game decides which entries to write resource strings to, but this could affect adding new
|
||||
* strings for the time being. Further investigation is required.
|
||||
*
|
||||
* Also note that all strings are currently still ASCII. It probably can't be converted to UTF-8 until all game functions that
|
||||
* read / write strings in some way is decompiled. The original game used a DIY extended 8-bit extended ASCII set for special
|
||||
* characters, format codes and accents.
|
||||
*
|
||||
* In terms of reading the language files, the STR_XXXX part is completely ignored at the moment. It just parses each line from
|
||||
* the colon and thus not allowing gaps in the string indices.
|
||||
*/
|
||||
int language_open(const char *filename)
|
||||
{
|
||||
// WIP, file can be loaded in but not in a suitable state.
|
||||
// Due to loading an uncompiled text language file, tokens surrounded with braces need to be converted to the correct
|
||||
// format character code. Therefore the language can not stay in its raw form and must be re-written as the text file is
|
||||
// parsed.
|
||||
|
||||
// get_string returns the original game string address if no language is loaded in.
|
||||
return 0;
|
||||
|
||||
FILE *f = fopen(filename, "rb");
|
||||
if (f == NULL)
|
||||
return 0;
|
||||
|
@ -1697,18 +1741,46 @@ int language_open(const char *filename)
|
|||
|
||||
language_strings = calloc(STR_COUNT, sizeof(char*));
|
||||
|
||||
int i, stringIndex = 0, searchForEndLine = 0;
|
||||
char *dst, *token;
|
||||
char tokenBuffer[64];
|
||||
int i, stringIndex = 0, mode = 0;
|
||||
for (i = 0; i < language_buffer_size; i++) {
|
||||
char *c = &language_buffer[i];
|
||||
char *src = &language_buffer[i];
|
||||
|
||||
if (searchForEndLine) {
|
||||
if (*c == '\n' || *c == '\r') {
|
||||
*c = 0;
|
||||
searchForEndLine = 0;
|
||||
switch (mode) {
|
||||
case 0:
|
||||
// Search for colon
|
||||
if (*src == ':') {
|
||||
dst = src + 1;
|
||||
language_strings[stringIndex++] = dst;
|
||||
mode = 1;
|
||||
}
|
||||
} else if (*c == ':') {
|
||||
language_strings[stringIndex++] = c + 1;
|
||||
searchForEndLine = 1;
|
||||
break;
|
||||
case 1:
|
||||
// Copy string over, stop at line break
|
||||
if (*src == '{') {
|
||||
token = src + 1;
|
||||
mode = 2;
|
||||
} else if (*src == '\n' || *src == '\r') {
|
||||
*dst = 0;
|
||||
mode = 0;
|
||||
} else {
|
||||
*dst++ = *src;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
// Read token, convert to code
|
||||
if (*src == '}') {
|
||||
int tokenLength = min(src - token, sizeof(tokenBuffer) - 1);
|
||||
memcpy(tokenBuffer, token, tokenLength);
|
||||
tokenBuffer[tokenLength] = 0;
|
||||
char code = format_get_code(tokenBuffer);
|
||||
if (code == 0)
|
||||
code = atoi(tokenBuffer);
|
||||
*dst++ = code;
|
||||
mode = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
language_num_strings = stringIndex;
|
||||
|
|
|
@ -760,7 +760,8 @@ enum {
|
|||
STR_PAGE_4 = STR_PAGE_1 + 3,
|
||||
STR_PAGE_5 = STR_PAGE_1 + 4,
|
||||
|
||||
STR_COUNT = 4000
|
||||
// Have to include resource strings (from scenarios and objects) for the time being now that language is partially working
|
||||
STR_COUNT = 32768
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -89,7 +89,7 @@ static rct_widget window_cheats_money_widgets[] = {
|
|||
{ WWT_TAB, 1, 3, 33, 17, 43, 0x2000144E, 2462}, // tab 1
|
||||
{ WWT_TAB, 1, 34, 64, 17, 43, 0x2000144E, 2462}, // tab 2
|
||||
{ WWT_TAB, 1, 65, 95, 17, 43, 0x2000144E, 2462}, // tab 3
|
||||
{ WWT_CLOSEBOX, 1, XPL(0), WPL(0), YPL(1), HPL(1), STR_VERY_HIGH, STR_VERY_HIGH}, // high money
|
||||
{ WWT_CLOSEBOX, 1, XPL(0), WPL(0), YPL(1), HPL(1), 2760, STR_VERY_HIGH}, // high money
|
||||
{ WWT_CLOSEBOX, 1, XPL(0), WPL(0), YPL(3), HPL(3), STR_FREE, STR_FREE}, //Park Entrance Fee Toggle
|
||||
{ WIDGETS_END },
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue