Changeset - r16692:f5d38cba4303
[Not reviewed]
master
0 3 0
yexo - 13 years ago 2010-12-08 13:44:01
yexo@openttd.org
(svn r21435) -Fix: NewGRF strings that referenced a value that was set by a string command later in the string failed
3 files changed with 51 insertions and 2 deletions:
0 comments (0 inline, 0 general)
src/newgrf_text.cpp
Show inline comments
 
@@ -863,6 +863,13 @@ struct TextRefStack {
 

	
 
	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++]; }
 
	int8   PopSignedByte()    { return (int8)this->PopUnsignedByte(); }
 

	
 
@@ -920,6 +927,34 @@ static TextRefStack _newgrf_error_textre
 
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
 
 * @param numEntries number of entries to copy from the registers
 
 */
src/newgrf_text.h
Show inline comments
 
@@ -39,6 +39,9 @@ void StopTextRefStackUsage();
 
void SwitchToNormalRefStack();
 
void SwitchToErrorRefStack();
 
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);
 

	
 
StringID TTDPStringIDToOTTDStringIDMapping(StringID string);
src/strings.cpp
Show inline comments
 
@@ -56,7 +56,7 @@ static char *StationGetSpecialString(cha
 
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 *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 {
 
	char data[]; // list of strings
 
@@ -583,8 +583,19 @@ uint ConvertDisplaySpeedToSpeed(uint spe
 
	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;
 
	int64 *argv_orig = argv;
 
	uint modifier = 0;
0 comments (0 inline, 0 general)