mirror of
https://github.com/JGRennison/OpenTTD-patches.git
synced 2024-11-08 01:10:28 +00:00
(svn r21435) -Fix: NewGRF strings that referenced a value that was set by a string command later in the string failed
This commit is contained in:
parent
a2f8d89444
commit
70fe377930
@ -863,6 +863,13 @@ struct TextRefStack {
|
|||||||
|
|
||||||
TextRefStack() : used(false) {}
|
TextRefStack() : used(false) {}
|
||||||
|
|
||||||
|
TextRefStack(const TextRefStack &stack) :
|
||||||
|
position(stack.position),
|
||||||
|
used(stack.used)
|
||||||
|
{
|
||||||
|
memcpy(this->stack, stack.stack, sizeof(this->stack));
|
||||||
|
}
|
||||||
|
|
||||||
uint8 PopUnsignedByte() { assert(this->position < lengthof(this->stack)); return this->stack[this->position++]; }
|
uint8 PopUnsignedByte() { assert(this->position < lengthof(this->stack)); return this->stack[this->position++]; }
|
||||||
int8 PopSignedByte() { return (int8)this->PopUnsignedByte(); }
|
int8 PopSignedByte() { return (int8)this->PopUnsignedByte(); }
|
||||||
|
|
||||||
@ -919,6 +926,34 @@ static TextRefStack _newgrf_error_textrefstack;
|
|||||||
/** The stack that is used for TTDP compatible string code parsing */
|
/** The stack that is used for TTDP compatible string code parsing */
|
||||||
static TextRefStack *_newgrf_textrefstack = &_newgrf_normal_textrefstack;
|
static TextRefStack *_newgrf_textrefstack = &_newgrf_normal_textrefstack;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether the NewGRF text stack is in use.
|
||||||
|
* @return True iff the NewGRF text stack is used.
|
||||||
|
*/
|
||||||
|
bool UsingNewGRFTextStack()
|
||||||
|
{
|
||||||
|
return _newgrf_textrefstack->used;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a backup of the current NewGRF text stack.
|
||||||
|
* @return A copy of the current text stack.
|
||||||
|
*/
|
||||||
|
struct TextRefStack *CreateTextRefStackBackup()
|
||||||
|
{
|
||||||
|
return new TextRefStack(*_newgrf_textrefstack);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restore a copy of the text stack to the used stack.
|
||||||
|
* @param backup The copy to restore.
|
||||||
|
*/
|
||||||
|
void RestoreTextRefStackBackup(struct TextRefStack *backup)
|
||||||
|
{
|
||||||
|
*_newgrf_textrefstack = *backup;
|
||||||
|
delete backup;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepare the TTDP compatible string code parsing
|
* Prepare the TTDP compatible string code parsing
|
||||||
* @param numEntries number of entries to copy from the registers
|
* @param numEntries number of entries to copy from the registers
|
||||||
|
@ -39,6 +39,9 @@ void StopTextRefStackUsage();
|
|||||||
void SwitchToNormalRefStack();
|
void SwitchToNormalRefStack();
|
||||||
void SwitchToErrorRefStack();
|
void SwitchToErrorRefStack();
|
||||||
void RewindTextRefStack();
|
void RewindTextRefStack();
|
||||||
|
bool UsingNewGRFTextStack();
|
||||||
|
struct TextRefStack *CreateTextRefStackBackup();
|
||||||
|
void RestoreTextRefStackBackup(struct TextRefStack *backup);
|
||||||
uint RemapNewGRFStringControlCode(uint scc, char *buf_start, char **buff, const char **str, int64 *argv);
|
uint RemapNewGRFStringControlCode(uint scc, char *buf_start, char **buff, const char **str, int64 *argv);
|
||||||
|
|
||||||
StringID TTDPStringIDToOTTDStringIDMapping(StringID string);
|
StringID TTDPStringIDToOTTDStringIDMapping(StringID string);
|
||||||
|
@ -56,7 +56,7 @@ static char *StationGetSpecialString(char *buff, int x, const char *last);
|
|||||||
static char *GetSpecialTownNameString(char *buff, int ind, uint32 seed, const char *last);
|
static char *GetSpecialTownNameString(char *buff, int ind, uint32 seed, const char *last);
|
||||||
static char *GetSpecialNameString(char *buff, int ind, int64 *argv, const char *last);
|
static char *GetSpecialNameString(char *buff, int ind, int64 *argv, const char *last);
|
||||||
|
|
||||||
static char *FormatString(char *buff, const char *str, int64 *argv, uint casei, const char *last);
|
static char *FormatString(char *buff, const char *str, int64 *argv, uint casei, const char *last, bool dry_run = false);
|
||||||
|
|
||||||
struct LanguagePack : public LanguagePackHeader {
|
struct LanguagePack : public LanguagePackHeader {
|
||||||
char data[]; // list of strings
|
char data[]; // list of strings
|
||||||
@ -583,8 +583,19 @@ uint ConvertDisplaySpeedToSpeed(uint speed)
|
|||||||
return ((speed << units[_settings_game.locale.units].s_s) + units[_settings_game.locale.units].s_m / 2) / units[_settings_game.locale.units].s_m;
|
return ((speed << units[_settings_game.locale.units].s_s) + units[_settings_game.locale.units].s_m / 2) / units[_settings_game.locale.units].s_m;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *FormatString(char *buff, const char *str, int64 *argv, uint casei, const char *last)
|
static char *FormatString(char *buff, const char *str, int64 *argv, uint casei, const char *last, bool dry_run)
|
||||||
{
|
{
|
||||||
|
if (UsingNewGRFTextStack() && !dry_run) {
|
||||||
|
/* Values from the NewGRF text stack are only copied to the normal
|
||||||
|
* argv array at the time they are encountered. That means that if
|
||||||
|
* another string command references a value later in the string it
|
||||||
|
* would fail. We solve that by running FormatString twice. The first
|
||||||
|
* pass makes sure the argv array is correctly filled and the second
|
||||||
|
* pass can reference later values without problems. */
|
||||||
|
struct TextRefStack *backup = CreateTextRefStackBackup();
|
||||||
|
FormatString(buff, str, argv, casei, last, true);
|
||||||
|
RestoreTextRefStackBackup(backup);
|
||||||
|
}
|
||||||
WChar b;
|
WChar b;
|
||||||
int64 *argv_orig = argv;
|
int64 *argv_orig = argv;
|
||||||
uint modifier = 0;
|
uint modifier = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user