mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-03-12 18:40:29 +00:00
(svn r21885) -Fix [FS#4422]: NewGRF string codes 0x80 and 0x81 were broken since the typechecking of string parameters
This commit is contained in:
parent
c9bd9b0c23
commit
0cdb1c78cd
@ -447,7 +447,7 @@ char *TranslateTTDPatchCodes(uint32 grfid, uint8 language_id, const char *str, i
|
|||||||
StringID string;
|
StringID string;
|
||||||
string = ((uint8)*str++);
|
string = ((uint8)*str++);
|
||||||
string |= ((uint8)*str++) << 8;
|
string |= ((uint8)*str++) << 8;
|
||||||
d += Utf8Encode(d, SCC_STRING_ID);
|
d += Utf8Encode(d, SCC_NEWGRF_STRINL);
|
||||||
d += Utf8Encode(d, MapGRFStringID(grfid, string));
|
d += Utf8Encode(d, MapGRFStringID(grfid, string));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1059,7 +1059,7 @@ uint RemapNewGRFStringControlCode(uint scc, char *buf_start, char **buff, const
|
|||||||
return SCC_CURRENCY;
|
return SCC_CURRENCY;
|
||||||
|
|
||||||
case SCC_NEWGRF_PRINT_STRING_ID:
|
case SCC_NEWGRF_PRINT_STRING_ID:
|
||||||
return SCC_STRING1;
|
return SCC_NEWGRF_PRINT_STRING_ID;
|
||||||
|
|
||||||
case SCC_NEWGRF_PRINT_DATE:
|
case SCC_NEWGRF_PRINT_DATE:
|
||||||
return SCC_DATE_LONG;
|
return SCC_DATE_LONG;
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
#include "smallmap_gui.h"
|
#include "smallmap_gui.h"
|
||||||
#include "window_func.h"
|
#include "window_func.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
#include <stack>
|
||||||
|
|
||||||
#include "table/strings.h"
|
#include "table/strings.h"
|
||||||
#include "table/control_codes.h"
|
#include "table/control_codes.h"
|
||||||
@ -121,6 +122,8 @@ static inline int64 *GetArgvPtr(int64 **argv, int n, const int64 *argve, WChar *
|
|||||||
const char *GetStringPtr(StringID string)
|
const char *GetStringPtr(StringID string)
|
||||||
{
|
{
|
||||||
switch (GB(string, 11, 5)) {
|
switch (GB(string, 11, 5)) {
|
||||||
|
/* GetGRFStringPtr doesn't handle 0xD4xx ids, we need to convert those to 0xD0xx. */
|
||||||
|
case 26: return GetStringPtr(GetGRFStringID(0, 0xD000 + GB(string, 0, 10)));
|
||||||
case 28: return GetGRFStringPtr(GB(string, 0, 11));
|
case 28: return GetGRFStringPtr(GB(string, 0, 11));
|
||||||
case 29: return GetGRFStringPtr(GB(string, 0, 11) + 0x0800);
|
case 29: return GetGRFStringPtr(GB(string, 0, 11) + 0x0800);
|
||||||
case 30: return GetGRFStringPtr(GB(string, 0, 11) + 0x1000);
|
case 30: return GetGRFStringPtr(GB(string, 0, 11) + 0x1000);
|
||||||
@ -622,7 +625,7 @@ uint ConvertDisplaySpeedToSpeed(uint speed)
|
|||||||
* @param argt Pointer to an array with the string codes used to parse the argv array.
|
* @param argt Pointer to an array with the string codes used to parse the argv array.
|
||||||
* @param dry_run True when the argt array is not yet initialized.
|
* @param dry_run True when the argt array is not yet initialized.
|
||||||
*/
|
*/
|
||||||
static char *FormatString(char *buff, const char *str, int64 *argv, const int64 *argve, uint casei, const char *last, WChar *argt, bool dry_run)
|
static char *FormatString(char *buff, const char *str_arg, int64 *argv, const int64 *argve, uint casei, const char *last, WChar *argt, bool dry_run)
|
||||||
{
|
{
|
||||||
/* When there is no array with types there is no need to do a dry run. */
|
/* When there is no array with types there is no need to do a dry run. */
|
||||||
if (argt == NULL) dry_run = true;
|
if (argt == NULL) dry_run = true;
|
||||||
@ -634,18 +637,26 @@ static char *FormatString(char *buff, const char *str, int64 *argv, const int64
|
|||||||
* pass makes sure the argv array is correctly filled and the second
|
* pass makes sure the argv array is correctly filled and the second
|
||||||
* pass can reference later values without problems. */
|
* pass can reference later values without problems. */
|
||||||
struct TextRefStack *backup = CreateTextRefStackBackup();
|
struct TextRefStack *backup = CreateTextRefStackBackup();
|
||||||
FormatString(buff, str, argv, argve, casei, last, argt, true);
|
FormatString(buff, str_arg, argv, argve, casei, last, argt, true);
|
||||||
RestoreTextRefStackBackup(backup);
|
RestoreTextRefStackBackup(backup);
|
||||||
} else if (!dry_run) {
|
} else if (!dry_run) {
|
||||||
FormatString(buff, str, argv, argve, casei, last, argt, true);
|
FormatString(buff, str_arg, argv, argve, casei, last, argt, true);
|
||||||
}
|
}
|
||||||
WChar b;
|
WChar b;
|
||||||
int64 *argv_orig = argv;
|
int64 *argv_orig = argv;
|
||||||
WChar *argt_orig = argt;
|
WChar *argt_orig = argt;
|
||||||
uint modifier = 0;
|
uint modifier = 0;
|
||||||
char *buf_start = buff;
|
char *buf_start = buff;
|
||||||
|
std::stack<const char *> str_stack;
|
||||||
|
str_stack.push(str_arg);
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
while (!str_stack.empty() && (b = Utf8Consume(&str_stack.top())) == '\0') {
|
||||||
|
str_stack.pop();
|
||||||
|
}
|
||||||
|
if (str_stack.empty()) break;
|
||||||
|
const char *&str = str_stack.top();
|
||||||
|
|
||||||
while ((b = Utf8Consume(&str)) != '\0') {
|
|
||||||
if (SCC_NEWGRF_FIRST <= b && b <= SCC_NEWGRF_LAST) {
|
if (SCC_NEWGRF_FIRST <= b && b <= SCC_NEWGRF_LAST) {
|
||||||
/* We need to pass some stuff as it might be modified; oh boy. */
|
/* We need to pass some stuff as it might be modified; oh boy. */
|
||||||
//todo: should argve be passed here too?
|
//todo: should argve be passed here too?
|
||||||
@ -654,6 +665,19 @@ static char *FormatString(char *buff, const char *str, int64 *argv, const int64
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (b) {
|
switch (b) {
|
||||||
|
case SCC_NEWGRF_STRINL: {
|
||||||
|
StringID substr = Utf8Consume(&str);
|
||||||
|
str_stack.push(GetStringPtr(substr));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SCC_NEWGRF_PRINT_STRING_ID: {
|
||||||
|
StringID substr = GetInt32(&argv, argve, &argt, SCC_NEWGRF_PRINT_STRING_ID);
|
||||||
|
str_stack.push(GetStringPtr(substr));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
case SCC_SETX: // {SETX}
|
case SCC_SETX: // {SETX}
|
||||||
if (buff + Utf8CharLen(SCC_SETX) + 1 < last) {
|
if (buff + Utf8CharLen(SCC_SETX) + 1 < last) {
|
||||||
buff += Utf8Encode(buff, SCC_SETX);
|
buff += Utf8Encode(buff, SCC_SETX);
|
||||||
|
@ -134,6 +134,8 @@ enum StringControlCode {
|
|||||||
SCC_NEWGRF_ROTATE_TOP_4_WORDS, ///< Rotate the top 4 words of the stack (W4 W1 W2 W3)
|
SCC_NEWGRF_ROTATE_TOP_4_WORDS, ///< Rotate the top 4 words of the stack (W4 W1 W2 W3)
|
||||||
SCC_NEWGRF_LAST = SCC_NEWGRF_ROTATE_TOP_4_WORDS,
|
SCC_NEWGRF_LAST = SCC_NEWGRF_ROTATE_TOP_4_WORDS,
|
||||||
|
|
||||||
|
SCC_NEWGRF_STRINL, ///< Inline another string at the current position, StringID is encoded in the string
|
||||||
|
|
||||||
/* Special printable symbols.
|
/* Special printable symbols.
|
||||||
* These are mapped to the original glyphs */
|
* These are mapped to the original glyphs */
|
||||||
SCC_LESSTHAN = SCC_SPRITE_START + 0x3C,
|
SCC_LESSTHAN = SCC_SPRITE_START + 0x3C,
|
||||||
|
Loading…
Reference in New Issue
Block a user