Changeset - r18205:e652606224ab
[Not reviewed]
master
0 1 0
yexo - 13 years ago 2011-10-20 16:53:34
yexo@openttd.org
(svn r23044) -Codechange: reorder parameter order so we can make use of the default=0 more often
1 file changed with 28 insertions and 28 deletions:
0 comments (0 inline, 0 general)
src/strings.cpp
Show inline comments
 
@@ -91,25 +91,25 @@ void CopyInDParam(int offs, const uint64
 
 * @param offs Index in the global array to copy the first string parameter from.
 
 * @param num  Number of string parameters to copy.
 
 */
 
void CopyOutDParam(uint64 *dst, int offs, int num)
 
{
 
	MemCpyT(dst, _global_string_params.GetPointerToOffset(offs), num);
 
}
 

	
 
static char *StationGetSpecialString(char *buff, int x, const char *last);
 
static char *GetSpecialTownNameString(char *buff, int ind, uint32 seed, const char *last);
 
static char *GetSpecialNameString(char *buff, int ind, StringParameters *args, const char *last);
 

	
 
static char *FormatString(char *buff, const char *str, StringParameters *args, uint case_index, const char *last, bool dry_run = false);
 
static char *FormatString(char *buff, const char *str, StringParameters *args, const char *last, uint case_index = 0, bool dry_run = false);
 

	
 
struct LanguagePack : public LanguagePackHeader {
 
	char data[]; // list of strings
 
};
 

	
 
static char **_langpack_offs;
 
static LanguagePack *_langpack;
 
static uint _langtab_num[32];   ///< Offset into langpack offs
 
static uint _langtab_start[32]; ///< Offset into langpack offs
 
static bool _keep_gender_data = false;  ///< Should we retain the gender data in the current string?
 

	
 

	
 
@@ -158,41 +158,41 @@ char *GetStringWithArgs(char *buffr, Str
 
			/* Old table for custom names. This is no longer used */
 
			error("Incorrect conversion of custom name string.");
 

	
 
		case 26:
 
			/* Include string within newgrf text (format code 81) */
 
			if (HasBit(index, 10)) {
 
				StringID string = GetGRFStringID(0, 0xD000 + GB(index, 0, 10));
 
				return GetStringWithArgs(buffr, string, args, last, case_index);
 
			}
 
			break;
 

	
 
		case 28:
 
			return FormatString(buffr, GetGRFStringPtr(index), args, case_index, last);
 
			return FormatString(buffr, GetGRFStringPtr(index), args, last, case_index);
 

	
 
		case 29:
 
			return FormatString(buffr, GetGRFStringPtr(index + 0x0800), args, case_index, last);
 
			return FormatString(buffr, GetGRFStringPtr(index + 0x0800), args, last, case_index);
 

	
 
		case 30:
 
			return FormatString(buffr, GetGRFStringPtr(index + 0x1000), args, case_index, last);
 
			return FormatString(buffr, GetGRFStringPtr(index + 0x1000), args, last, case_index);
 

	
 
		case 31:
 
			NOT_REACHED();
 
	}
 

	
 
	if (index >= _langtab_num[tab]) {
 
		error("String 0x%X is invalid. You are probably using an old version of the .lng file.\n", string);
 
	}
 

	
 
	return FormatString(buffr, GetStringPtr(string), args, case_index, last);
 
	return FormatString(buffr, GetStringPtr(string), args, last, case_index);
 
}
 

	
 
char *GetString(char *buffr, StringID string, const char *last)
 
{
 
	_global_string_params.ClearTypeInformation();
 
	_global_string_params.offset = 0;
 
	return GetStringWithArgs(buffr, string, &_global_string_params, last);
 
}
 

	
 

	
 
char *InlineString(char *buf, StringID string)
 
{
 
@@ -324,58 +324,58 @@ static char *FormatBytes(char *buff, int
 
		buff += seprintf(buff, last, "%i%s%01i", (int)number / 1024, decimal_separator, (int)(number % 1024) * 10 / 1024);
 
	} else {
 
		assert(number < 1024 * 1024);
 
		buff += seprintf(buff, last, "%i", (int)number / 1024);
 
	}
 

	
 
	assert(id < lengthof(iec_prefixes));
 
	buff += seprintf(buff, last, " %sB", iec_prefixes[id]);
 

	
 
	return buff;
 
}
 

	
 
static char *FormatYmdString(char *buff, Date date, uint case_index, const char *last)
 
static char *FormatYmdString(char *buff, Date date, const char *last, uint case_index)
 
{
 
	YearMonthDay ymd;
 
	ConvertDateToYMD(date, &ymd);
 

	
 
	int64 args[] = {ymd.day + STR_ORDINAL_NUMBER_1ST - 1, STR_MONTH_ABBREV_JAN + ymd.month, ymd.year};
 
	StringParameters tmp_params(args);
 
	return FormatString(buff, GetStringPtr(STR_FORMAT_DATE_LONG), &tmp_params, case_index, last);
 
	return FormatString(buff, GetStringPtr(STR_FORMAT_DATE_LONG), &tmp_params, last, case_index);
 
}
 

	
 
static char *FormatMonthAndYear(char *buff, Date date, uint case_index, const char *last)
 
static char *FormatMonthAndYear(char *buff, Date date, const char *last, uint case_index)
 
{
 
	YearMonthDay ymd;
 
	ConvertDateToYMD(date, &ymd);
 

	
 
	int64 args[] = {STR_MONTH_JAN + ymd.month, ymd.year};
 
	StringParameters tmp_params(args);
 
	return FormatString(buff, GetStringPtr(STR_FORMAT_DATE_SHORT), &tmp_params, case_index, last);
 
	return FormatString(buff, GetStringPtr(STR_FORMAT_DATE_SHORT), &tmp_params, last, case_index);
 
}
 

	
 
static char *FormatTinyOrISODate(char *buff, Date date, StringID str, const char *last)
 
{
 
	YearMonthDay ymd;
 
	ConvertDateToYMD(date, &ymd);
 

	
 
	char day[3];
 
	char month[3];
 
	/* We want to zero-pad the days and months */
 
	snprintf(day,   lengthof(day),   "%02i", ymd.day);
 
	snprintf(month, lengthof(month), "%02i", ymd.month + 1);
 

	
 
	int64 args[] = {(int64)(size_t)day, (int64)(size_t)month, ymd.year};
 
	StringParameters tmp_params(args);
 
	return FormatString(buff, GetStringPtr(str), &tmp_params, 0, last);
 
	return FormatString(buff, GetStringPtr(str), &tmp_params, last);
 
}
 

	
 
static char *FormatGenericCurrency(char *buff, const CurrencySpec *spec, Money number, bool compact, const char *last)
 
{
 
	/* We are going to make number absolute for printing, so
 
	 * keep this piece of data as we need it later on */
 
	bool negative = number < 0;
 
	const char *multiplier = "";
 

	
 
	number *= spec->rate;
 

	
 
	/* convert from negative */
 
@@ -652,42 +652,42 @@ uint ConvertDisplaySpeedToSpeed(uint spe
 
	return _units[_settings_game.locale.units].c_velocity.FromDisplay(speed);
 
}
 

	
 
/**
 
 * Parse most format codes within a string and write the result to a buffer.
 
 * @param buff  The buffer to write the final string to.
 
 * @param str   The original string with format codes.
 
 * @param args  Pointer to extra arguments used by various string codes.
 
 * @param case_index
 
 * @param last  Pointer to just past the end of the buff array.
 
 * @param dry_run True when the argt array is not yet initialized.
 
 */
 
static char *FormatString(char *buff, const char *str_arg, StringParameters *args, uint case_index, const char *last, bool dry_run)
 
static char *FormatString(char *buff, const char *str_arg, StringParameters *args, const char *last, uint case_index, bool dry_run)
 
{
 
	uint orig_offset = args->offset;
 

	
 
	/* When there is no array with types there is no need to do a dry run. */
 
	if (args->HasTypeInformation() && !dry_run) {
 
		if (UsingNewGRFTextStack()) {
 
			/* 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_arg, args, case_index, last, true);
 
			FormatString(buff, str_arg, args, last, case_index, true);
 
			RestoreTextRefStackBackup(backup);
 
		} else {
 
			FormatString(buff, str_arg, args, case_index, last, true);
 
			FormatString(buff, str_arg, args, last, case_index, true);
 
		}
 
		/* We have to restore the original offset here to to read the correct values. */
 
		args->offset = orig_offset;
 
	}
 
	WChar b;
 
	uint next_substr_case_index = 0;
 
	char *buf_start = buff;
 
	std::stack<const char *> str_stack;
 
	str_stack.push(str_arg);
 

	
 
	for (;;) {
 
		while (!str_stack.empty() && (b = Utf8Consume(&str_stack.top())) == '\0') {
 
@@ -731,80 +731,80 @@ static char *FormatString(char *buff, co
 
					buff += Utf8Encode(buff, SCC_SETXY);
 
					*buff++ = *str++;
 
					*buff++ = *str++;
 
				}
 
				break;
 

	
 
			case SCC_STRING_ID: // {STRINL}
 
				buff = GetStringWithArgs(buff, Utf8Consume(&str), args, last);
 
				break;
 

	
 
			case SCC_RAW_STRING_POINTER: { // {RAW_STRING}
 
				const char *str = (const char *)(size_t)args->GetInt64();
 
				buff = FormatString(buff, str, args, case_index, last);
 
				buff = FormatString(buff, str, args, last);
 
				break;
 
			}
 

	
 
			case SCC_DATE_LONG: // {DATE_LONG}
 
				buff = FormatYmdString(buff, args->GetInt32(SCC_DATE_LONG), next_substr_case_index, last);
 
				buff = FormatYmdString(buff, args->GetInt32(SCC_DATE_LONG), last, next_substr_case_index);
 
				next_substr_case_index = 0;
 
				break;
 

	
 
			case SCC_DATE_SHORT: // {DATE_SHORT}
 
				buff = FormatMonthAndYear(buff, args->GetInt32(SCC_DATE_SHORT), next_substr_case_index, last);
 
				buff = FormatMonthAndYear(buff, args->GetInt32(SCC_DATE_SHORT), last, next_substr_case_index);
 
				next_substr_case_index = 0;
 
				break;
 

	
 
			case SCC_VELOCITY: { // {VELOCITY}
 
				assert(_settings_game.locale.units < lengthof(_units));
 
				int64 args_array[] = {ConvertSpeedToDisplaySpeed(args->GetInt64(SCC_VELOCITY) * 10 / 16)};
 
				StringParameters tmp_params(args_array);
 
				buff = FormatString(buff, GetStringPtr(_units[_settings_game.locale.units].velocity), &tmp_params, 0, last);
 
				buff = FormatString(buff, GetStringPtr(_units[_settings_game.locale.units].velocity), &tmp_params, last);
 
				break;
 
			}
 

	
 
			case SCC_HEIGHT: { // {HEIGHT}
 
				int64 args_array[] = {_units[_settings_game.locale.units].c_height.ToDisplay(args->GetInt64())};
 
				StringParameters tmp_params(args_array);
 
				buff = FormatString(buff, GetStringPtr(_units[_settings_game.locale.units].height), &tmp_params, 0, last);
 
				buff = FormatString(buff, GetStringPtr(_units[_settings_game.locale.units].height), &tmp_params, last);
 
				break;
 
			}
 

	
 
			case SCC_CURRENCY_COMPACT: // {CURRCOMPACT}
 
				buff = FormatGenericCurrency(buff, _currency, args->GetInt64(), true, last);
 
				break;
 

	
 
			case SCC_REVISION: // {REV}
 
				buff = strecpy(buff, _openttd_revision, last);
 
				break;
 

	
 
			case SCC_CARGO_SHORT: { // {SHORTCARGO}
 
				/* Short description of cargotypes. Layout:
 
				 * 8-bit = cargo type
 
				 * 16-bit = cargo count */
 
				StringID cargo_str = CargoSpec::Get(args->GetInt32(SCC_CARGO_SHORT))->units_volume;
 
				switch (cargo_str) {
 
					case STR_TONS: {
 
						assert(_settings_game.locale.units < lengthof(_units));
 
						int64 args_array[] = {_units[_settings_game.locale.units].c_weight.ToDisplay(args->GetInt64())};
 
						StringParameters tmp_params(args_array);
 
						buff = FormatString(buff, GetStringPtr(_units[_settings_game.locale.units].l_weight), &tmp_params, 0, last);
 
						buff = FormatString(buff, GetStringPtr(_units[_settings_game.locale.units].l_weight), &tmp_params, last);
 
						break;
 
					}
 

	
 
					case STR_LITERS: {
 
						assert(_settings_game.locale.units < lengthof(_units));
 
						int64 args_array[] = {_units[_settings_game.locale.units].c_volume.ToDisplay(args->GetInt64())};
 
						StringParameters tmp_params(args_array);
 
						buff = FormatString(buff, GetStringPtr(_units[_settings_game.locale.units].l_volume), &tmp_params, 0, last);
 
						buff = FormatString(buff, GetStringPtr(_units[_settings_game.locale.units].l_volume), &tmp_params, last);
 
						break;
 
					}
 

	
 
					default: {
 
						StringParameters tmp_params(*args, 1);
 
						buff = GetStringWithArgs(buff, cargo_str, &tmp_params, last);
 
						break;
 
					}
 
				}
 
				break;
 
			}
 

	
 
@@ -859,55 +859,55 @@ static char *FormatString(char *buff, co
 
			}
 

	
 
			case SCC_INDUSTRY_NAME: { // {INDUSTRY}
 
				const Industry *i = Industry::Get(args->GetInt32(SCC_INDUSTRY_NAME));
 

	
 
				/* industry not valid anymore? */
 
				assert(i != NULL);
 

	
 
				/* First print the town name and the industry type name. */
 
				int64 args_array[2] = {i->town->index, GetIndustrySpec(i->type)->name};
 
				StringParameters tmp_params(args_array);
 

	
 
				buff = FormatString(buff, GetStringPtr(STR_FORMAT_INDUSTRY_NAME), &tmp_params, next_substr_case_index, last);
 
				buff = FormatString(buff, GetStringPtr(STR_FORMAT_INDUSTRY_NAME), &tmp_params, last, next_substr_case_index);
 
				next_substr_case_index = 0;
 
				break;
 
			}
 

	
 
			case SCC_VOLUME: { // {VOLUME}
 
				assert(_settings_game.locale.units < lengthof(_units));
 
				int64 args_array[1] = {_units[_settings_game.locale.units].c_volume.ToDisplay(args->GetInt64(SCC_VOLUME))};
 
				StringParameters tmp_params(args_array);
 
				buff = FormatString(buff, GetStringPtr(_units[_settings_game.locale.units].l_volume), &tmp_params, 0, last);
 
				buff = FormatString(buff, GetStringPtr(_units[_settings_game.locale.units].l_volume), &tmp_params, last);
 
				break;
 
			}
 

	
 
			case SCC_GENDER_LIST: { // {G 0 Der Die Das}
 
				/* First read the meta data from the language file. */
 
				uint offset = orig_offset + (byte)*str++;
 
				int gender = 0;
 
				if (!dry_run && args->GetTypeAtOffset(offset) != 0) {
 
					/* Now we need to figure out what text to resolve, i.e.
 
					 * what do we need to draw? So get the actual raw string
 
					 * first using the control code to get said string. */
 
					char input[4 + 1];
 
					char *p = input + Utf8Encode(input, args->GetTypeAtOffset(offset));
 
					*p = '\0';
 

	
 
					/* Now do the string formatting. */
 
					char buf[256];
 
					bool old_kgd = _keep_gender_data;
 
					_keep_gender_data = true;
 
					StringParameters tmp_params(args->GetPointerToOffset(offset), args->num_param - offset, NULL);
 
					p = FormatString(buf, input, &tmp_params, 0, lastof(buf));
 
					p = FormatString(buf, input, &tmp_params, lastof(buf));
 
					_keep_gender_data = old_kgd;
 
					*p = '\0';
 

	
 
					/* And determine the string. */
 
					const char *s = buf;
 
					WChar c = Utf8Consume(&s);
 
					/* Does this string have a gender, if so, set it */
 
					if (c == SCC_GENDER_INDEX) gender = (byte)s[0];
 
				}
 
				str = ParseStringChoice(str, gender, &buff, last);
 
				break;
 
			}
 
@@ -926,57 +926,57 @@ static char *FormatString(char *buff, co
 
				/* First parameter is cargo type, second parameter is cargo count */
 
				CargoID cargo = args->GetInt32(SCC_CARGO);
 
				StringID cargo_str = (cargo == CT_INVALID) ? STR_QUANTITY_N_A : CargoSpec::Get(cargo)->quantifier;
 
				StringParameters tmp_args(*args, 1);
 
				buff = GetStringWithArgs(buff, cargo_str, &tmp_args, last);
 
				break;
 
			}
 

	
 
			case SCC_POWER: { // {POWER}
 
				assert(_settings_game.locale.units < lengthof(_units));
 
				int64 args_array[1] = {_units[_settings_game.locale.units].c_power.ToDisplay(args->GetInt64())};
 
				StringParameters tmp_params(args_array);
 
				buff = FormatString(buff, GetStringPtr(_units[_settings_game.locale.units].power), &tmp_params, 0, last);
 
				buff = FormatString(buff, GetStringPtr(_units[_settings_game.locale.units].power), &tmp_params, last);
 
				break;
 
			}
 

	
 
			case SCC_VOLUME_SHORT: { // {VOLUME_S}
 
				assert(_settings_game.locale.units < lengthof(_units));
 
				int64 args_array[1] = {_units[_settings_game.locale.units].c_volume.ToDisplay(args->GetInt64())};
 
				StringParameters tmp_params(args_array);
 
				buff = FormatString(buff, GetStringPtr(_units[_settings_game.locale.units].s_volume), &tmp_params, 0, last);
 
				buff = FormatString(buff, GetStringPtr(_units[_settings_game.locale.units].s_volume), &tmp_params, last);
 
				break;
 
			}
 

	
 
			case SCC_WEIGHT: { // {WEIGHT}
 
				assert(_settings_game.locale.units < lengthof(_units));
 
				int64 args_array[1] = {_units[_settings_game.locale.units].c_weight.ToDisplay(args->GetInt64(SCC_WEIGHT))};
 
				StringParameters tmp_params(args_array);
 
				buff = FormatString(buff, GetStringPtr(_units[_settings_game.locale.units].l_weight), &tmp_params, 0, last);
 
				buff = FormatString(buff, GetStringPtr(_units[_settings_game.locale.units].l_weight), &tmp_params, last);
 
				break;
 
			}
 

	
 
			case SCC_WEIGHT_SHORT: { // {WEIGHT_S}
 
				assert(_settings_game.locale.units < lengthof(_units));
 
				int64 args_array[1] = {_units[_settings_game.locale.units].c_weight.ToDisplay(args->GetInt64())};
 
				StringParameters tmp_params(args_array);
 
				buff = FormatString(buff, GetStringPtr(_units[_settings_game.locale.units].s_weight), &tmp_params, 0, last);
 
				buff = FormatString(buff, GetStringPtr(_units[_settings_game.locale.units].s_weight), &tmp_params, last);
 
				break;
 
			}
 

	
 
			case SCC_FORCE: { // {FORCE}
 
				assert(_settings_game.locale.units < lengthof(_units));
 
				int64 args_array[1] = {_units[_settings_game.locale.units].c_force.ToDisplay(args->GetInt64())};
 
				StringParameters tmp_params(args_array);
 
				buff = FormatString(buff, GetStringPtr(_units[_settings_game.locale.units].force), &tmp_params, 0, last);
 
				buff = FormatString(buff, GetStringPtr(_units[_settings_game.locale.units].force), &tmp_params, last);
 
				break;
 
			}
 

	
 
			/* This sets up the gender for the string.
 
			 * We just ignore this one. It's used in {G 0 Der Die Das} to determine the case. */
 
			case SCC_GENDER_INDEX: // {GENDER 0}
 
				if (_keep_gender_data) {
 
					buff += Utf8Encode(buff, SCC_GENDER_INDEX);
 
					*buff++ = *str++;
 
				} else {
 
					str++;
 
				}
0 comments (0 inline, 0 general)