1,2d0
< /* $Id: strings.c 2717 2005-07-26 19:04:19Z tron $ */
< 
4,7c2
< #include "openttd.h"
< #include "functions.h"
< #include "string.h"
< #include "strings.h"
---
> #include "ttd.h"
9d3
< #include "namegen.h"
15d8
< <<<<<<< .mine
17,27d9
< =======
< #include "waypoint.h"
< #include "industry.h"
< #include "variables.h"
< >>>>>>> .r2761
< 
< char _userstring[128];
< 
< static char *StationGetSpecialString(char *buff, int x);
< static char *GetSpecialTownNameString(char *buff, int ind, uint32 seed);
< static char *GetSpecialPlayerNameString(char *buff, int ind, const int32 *argv);
29c11,22
< static char *FormatString(char *buff, const char *str, const int32 *argv, uint casei);
---
> #define USE_TABLE(x)  { assert(index < lengthof(x)); str = x[index]; break; }
> 
> static byte *StationGetSpecialString(byte *buff);
> static byte *GetSpecialTownNameString(byte *buff, int ind);
> static byte *GetSpecialPlayerNameString(byte *buff, int ind);
> 
> static byte *DecodeString(byte *buff, const byte *str);
> 
> static byte **_langpack_offs;
> static byte *_langpack;
> static uint _langtab_num[32]; // Offset into langpack offs
> static uint _langtab_start[32]; // Offset into langpack offs
33c26,28
< typedef struct LanguagePack {
---
> typedef byte *PlayerNameGeneratorProc(byte *buffr);
> 
> typedef struct {
38d32
< <<<<<<< .mine
43,45d36
< =======
< 	char isocode[16];	// the ISO code for the language (not country code)
< >>>>>>> .r2761
47,50c38
< 	byte plural_form;		// how to compute plural forms
< 	byte pad[3];				// pad header to be a multiple of 4
< 	char data[VARARRAY_SIZE];
< } LanguagePack;
---
> } LanguagePackHeader;
52,57c40
< 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
< 
< const StringID _currency_string_list[] = {
---
> const uint16 _currency_string_list[] = {
85,144c68,72
< static const StringID _cargo_string_list[NUM_LANDSCAPE][NUM_CARGO] = {
< 	{ /* LT_NORMAL */
< 		STR_PASSENGERS,
< 		STR_TONS,
< 		STR_BAGS,
< 		STR_LITERS,
< 		STR_ITEMS,
< 		STR_CRATES,
< 		STR_TONS,
< 		STR_TONS,
< 		STR_TONS,
< 		STR_TONS,
< 		STR_BAGS,
< 		STR_RES_OTHER
< 	},
< 
< 	{ /* LT_HILLY */
< 		STR_PASSENGERS,
< 		STR_TONS,
< 		STR_BAGS,
< 		STR_LITERS,
< 		STR_ITEMS,
< 		STR_CRATES,
< 		STR_TONS,
< 		STR_TONS,
< 		STR_RES_OTHER,
< 		STR_TONS,
< 		STR_BAGS,
< 		STR_TONS
< 	},
< 
< 	{ /* LT_DESERT */
< 		STR_PASSENGERS,
< 		STR_LITERS,
< 		STR_BAGS,
< 		STR_LITERS,
< 		STR_TONS,
< 		STR_CRATES,
< 		STR_TONS,
< 		STR_TONS,
< 		STR_TONS,
< 		STR_LITERS,
< 		STR_BAGS,
< 		STR_TONS
< 	},
< 
< 	{ /* LT_CANDY */
< 		STR_PASSENGERS,
< 		STR_TONS,
< 		STR_BAGS,
< 		STR_NOTHING,
< 		STR_NOTHING,
< 		STR_TONS,
< 		STR_TONS,
< 		STR_LITERS,
< 		STR_TONS,
< 		STR_NOTHING,
< 		STR_LITERS,
< 		STR_NOTHING
< 	}
---
> static const uint16 _cargo_string_list[NUM_LANDSCAPE][NUM_CARGO] = {
> 	/* LT_NORMAL */ {STR_PASSENGERS, STR_TONS, STR_BAGS, STR_LITERS, STR_ITEMS, STR_CRATES, STR_TONS, STR_TONS, STR_TONS, STR_TONS, STR_BAGS, STR_RES_OTHER},
> 	/* LT_HILLY */  {STR_PASSENGERS, STR_TONS, STR_BAGS, STR_LITERS, STR_ITEMS, STR_CRATES, STR_TONS, STR_TONS, STR_RES_OTHER, STR_TONS, STR_BAGS, STR_TONS},
> 	/* LT_DESERT */ {STR_PASSENGERS, STR_LITERS, STR_BAGS, STR_LITERS, STR_TONS, STR_CRATES, STR_TONS, STR_TONS, STR_TONS, STR_LITERS, STR_BAGS, STR_TONS},
> 	/* LT_CANDY */  {STR_PASSENGERS, STR_TONS, STR_BAGS, STR_NOTHING, STR_NOTHING, STR_TONS, STR_TONS, STR_LITERS, STR_TONS, STR_NOTHING, STR_LITERS, STR_NOTHING}
147,149c75
< 
< // Read an int64 from the argv array.
< static inline int64 GetInt64(const int32 **argv)
---
> static byte *str_cat(byte *dst, const byte *src)
151,156c77,78
< 	int64 result;
< 
< 	assert(argv);
< 	result = (uint32)(*argv)[0] + ((uint64)(uint32)(*argv)[1] << 32);
< 	(*argv)+=2;
< 	return result;
---
> 	while ( (*dst++ = *src++) != 0) {}
> 	return dst - 1;
159,160c81
< // Read an int32 from the argv array.
< static inline int32 GetInt32(const int32 **argv)
---
> static byte *GetStringPtr(uint16 string)
162,163c83
< 	assert(argv);
< 	return *(*argv)++;
---
> 	return _langpack_offs[_langtab_start[string >> 11] + (string & 0x7FF)];
166,167c86
< // Read an array from the argv array.
< static inline const int32 *GetArgvPtr(const int32 **argv, int n)
---
> byte *GetString(byte *buffr, uint16 string)
169,174c88,89
< 	const int32 *result;
< 	assert(*argv);
< 	result = *argv;
< 	(*argv) += n;
< 	return result;
< }
---
> 	uint index = string & 0x7FF;
> 	uint tab = string >> 11;
175a91
> 	if (string == 0) error("!invalid string id 0 in GetString");
177c93,94
< #define NUM_BOUND_STRINGS 8
---
> 	if ( tab == 4 && index >= 0xC0)
> 		return GetSpecialTownNameString(buffr, index - 0xC0);
179,180c96,97
< // Array to hold the bound strings.
< static const char *_bound_strings[NUM_BOUND_STRINGS];
---
> 	if ( tab == 6 && index == 0xD1)
> 		return StationGetSpecialString(buffr);
182,191c99,100
< // This index is used to implement a "round-robin" allocating of
< // slots for BindCString. NUM_BOUND_STRINGS slots are reserved.
< // Which means that after NUM_BOUND_STRINGS calls to BindCString,
< // the indices will be reused.
< static int _bind_index;
< 
< static const char *GetStringPtr(StringID string)
< {
< 	return _langpack_offs[_langtab_start[string >> 11] + (string & 0x7FF)];
< }
---
> 	if ( tab == 14 && index >= 0xE4)
> 		return GetSpecialPlayerNameString(buffr, index - 0xE4);
193,200c102,103
< // The highest 8 bits of string contain the "case index".
< // These 8 bits will only be set when FormatString wants to print
< // the string in a different case. No one else except FormatString
< // should set those bits.
< char *GetStringWithArgs(char *buffr, uint string, const int32 *argv)
< {
< 	uint index = GB(string,  0, 11);
< 	uint tab   = GB(string, 11,  5);
---
> 	if ( tab == 15)
> 		return GetName(index, buffr);
202,203c105,107
< 	if (!(string & 0xFFFF)) {
< 		error("!invalid string id 0 in GetString");
---
> 	// tab 31 is used for special or dynamic strings
> 	if ( tab == 31) {
> 		return DecodeString(buffr, index == (STR_SPEC_SCREENSHOT_NAME & 0x7FF) ? _screenshot_name : _userstring);
206,219c110,111
< 	switch (tab) {
< 		case 4:
< 			if (index >= 0xC0)
< 				return GetSpecialTownNameString(buffr, index - 0xC0, GetInt32(&argv));
< 			break;
< 
< 		case 14:
< 			if (index >= 0xE4)
< 				return GetSpecialPlayerNameString(buffr, index - 0xE4, argv);
< 			break;
< 
< 		// User defined name
< 		case 15:
< 			return GetName(index, buffr);
---
> 	if (index >= _langtab_num[tab])
> 		error("!String 0x%X is invalid. Probably because an old version of the .lng file.\n", string);
221,226c113,114
< 		case 31:
< 			// dynamic strings. These are NOT to be passed through the formatter,
< 			// but passed through verbatim.
< 			if (index < (STR_SPEC_USERSTRING & 0x7FF)) {
< 				return strecpy(buffr, _bound_strings[index], NULL);
< 			}
---
> 	return DecodeString(buffr, GetStringPtr(string));
> }
228,229c116,119
< 			return FormatString(buffr, _userstring, NULL, 0);
< 	}
---
> void InjectDparam(int amount)
> {
> 	memmove(_decode_parameters + amount, _decode_parameters, sizeof(_decode_parameters) - amount * sizeof(uint32));
> }
231,235d120
< 	if (index >= _langtab_num[tab])
< 		error(
< 			"!String 0x%X is invalid. "
< 			"Probably because an old version of the .lng file.\n", string
< 		);
237c122,126
< 	return FormatString(buffr, GetStringPtr(string&0xFFFF), argv, string >> 24);
---
> int32 GetParamInt32(void)
> {
> 	int32 result = GetDParam(0);
> 	memmove(&_decode_parameters[0], &_decode_parameters[1], sizeof(uint32) * (lengthof(_decode_parameters)-1));
> 	return result;
240c129
< char *GetString(char *buffr, StringID string)
---
> static int64 GetParamInt64(void)
242c131,133
< 	return GetStringWithArgs(buffr, string, (int32*)_decode_parameters);
---
> 	int64 result = GetDParam(0) + ((uint64)GetDParam(1) << 32);
> 	memmove(&_decode_parameters[0], &_decode_parameters[2], sizeof(uint32) * (lengthof(_decode_parameters)-2));
> 	return result;
246,249c137
< // This function takes a C-string and allocates a temporary string ID.
< // The duration of the bound string is valid only until the next GetString,
< // so be careful.
< StringID BindCString(const char *str)
---
> int GetParamInt16(void)
251,253c139,141
< 	int idx = (++_bind_index) & (NUM_BOUND_STRINGS - 1);
< 	_bound_strings[idx] = str;
< 	return idx + STR_SPEC_DYNSTRING;
---
> 	int result = (int16)GetDParam(0);
> 	memmove(&_decode_parameters[0], &_decode_parameters[1], sizeof(uint32) * (lengthof(_decode_parameters)-1));
> 	return result;
256,257c144
< // This function is used to "bind" a C string to a OpenTTD dparam slot.
< void SetDParamStr(uint n, const char *str)
---
> int GetParamInt8(void)
259c146,148
< 	SetDParam(n, BindCString(str));
---
> 	int result = (int8)GetDParam(0);
> 	memmove(&_decode_parameters[0], &_decode_parameters[1], sizeof(uint32) * (lengthof(_decode_parameters)-1));
> 	return result;
262c151
< void InjectDParam(int amount)
---
> int GetParamUint16(void)
264c153,155
< 	memmove(_decode_parameters + amount, _decode_parameters, sizeof(_decode_parameters) - amount * sizeof(uint32));
---
> 	int result = GetDParam(0);
> 	memmove(&_decode_parameters[0], &_decode_parameters[1], sizeof(uint32) * (lengthof(_decode_parameters)-1));
> 	return result;
281c172
< static char *FormatCommaNumber(char *buff, int32 number)
---
> static byte *FormatCommaNumber(byte *buff, int32 number)
296c187
< 	for (i = 0; i != 10; i++) {
---
> 	for(i=0; i!=10; i++) {
303,305c194,196
< 		if (tot |= quot || i == 9) {
< 			*buff++ = '0' + quot;
< 			if (i == 0 || i == 3 || i == 6) *buff++ = ',';
---
> 		if (tot|=quot || i==9) {
> 			*buff++ = (byte)('0' + quot);
> 			if (i==0 || i==3 || i==6) *buff++ = ',';
309c200
< 	*buff = '\0';
---
> 	*buff = 0;
314c205
< static char *FormatNoCommaNumber(char *buff, int32 number)
---
> static byte *FormatNoCommaNumber(byte *buff, int32 number)
329c220
< 	for (i = 0; i != 10; i++) {
---
> 	for(i=0; i!=10; i++) {
336,337c227,228
< 		if (tot |= quot || i == 9) {
< 			*buff++ = '0' + quot;
---
> 		if (tot|=quot || i==9) {
> 			*buff++ = (byte)('0' + quot);
341c232
< 	*buff = '\0';
---
> 	*buff = 0;
347c238
< static char *FormatYmdString(char *buff, uint16 number)
---
> static byte *FormatYmdString(byte *buff, uint16 number)
349c240
< 	const char *src;
---
> 	const byte *src;
354c245
< 	for (src = GetStringPtr(ymd.day + STR_01AC_1ST - 1); (*buff++ = *src++) != '\0';) {}
---
> 	for(src = GetStringPtr(ymd.day+STR_01AC_1ST-1); (*buff++=*src++) != 0;) {}
363c254
< static char *FormatMonthAndYear(char *buff, uint16 number)
---
> static byte *FormatMonthAndYear(byte *buff, uint16 number)
370c261
< 	for (src = GetStringPtr(STR_MONTH_JAN + ymd.month); (*buff++ = *src++) != '\0';) {}
---
> 	for(src = GetStringPtr(STR_MONTH_JAN + ymd.month); (*buff++=*src++) != 0;) {}
376c267
< static char *FormatTinyDate(char *buff, uint16 number)
---
> static byte *FormatTinyDate(byte *buff, uint16 number)
388c279
< 	return _currency_specs[_opt_ptr->currency].rate;
---
>     return (&_currency_specs[_opt.currency])->rate;
391c282
< static char *FormatGenericCurrency(char *buff, const CurrencySpec *spec, int64 number, bool compact)
---
> static byte *FormatGenericCurrency(byte *buff, const CurrencySpec *spec, int64 number, bool compact)
402,405c293
< 	if (number < 0) {
< 		*buff++ = '-';
< 		number = -number;
< 	}
---
> 	if (number < 0) { *buff++ = '-'; number = -number; }
409c297
< 	while (s != spec->prefix + lengthof(spec->prefix) && (c = *s++) != '\0') *buff++ = c;
---
> 	while (s != spec->prefix + lengthof(spec->prefix) && (c=*s++)) *buff++ = c;
427,430c315
< 		if (--j == 0) {
< 			*p++ = spec->separator;
< 			j = 3;
< 		}
---
> 		if (--j == 0) { *p++ = spec->separator; j = 3; }
439c324
< 	while (s != spec->suffix + lengthof(spec->suffix) && (c = *s++) != '\0') *buff++ = c;
---
> 	while (s != spec->suffix + lengthof(spec->suffix) && (c=*s++)) *buff++ = c;
444,527c329
< static int DeterminePluralForm(int32 n)
< {
< 	// The absolute value determines plurality
< 	if (n < 0) n = -n;
< 
< 	switch(_langpack->plural_form) {
< 	// Two forms, singular used for one only
< 	// Used in:
< 	//   Danish, Dutch, English, German, Norwegian, Swedish, Estonian, Finnish,
< 	//   Greek, Hebrew, Italian, Portuguese, Spanish, Esperanto
< 	case 0:
< 	default:
< 		return n != 1;
< 
< 	// Only one form
< 	// Used in:
< 	//   Hungarian, Japanese, Korean, Turkish
< 	case 1:
< 		return 0;
< 
< 	// Two forms, singular used for zero and one
< 	// Used in:
< 	//   French, Brazilian Portuguese
< 	case 2:
< 		return n > 1;
< 
< 	// Three forms, special case for zero
< 	// Used in:
< 	//   Latvian
< 	case 3:
< 		return n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2;
< 
< 	// Three forms, special case for one and two
< 	// Used in:
< 	//   Gaelige (Irish)
< 	case 4:
< 		return n==1 ? 0 : n==2 ? 1 : 2;
< 
< 	// Three forms, special case for numbers ending in 1[2-9]
< 	// Used in:
< 	//   Lithuanian
< 	case 5:
< 		return n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2;
< 
< 	// Three forms, special cases for numbers ending in 1 and 2, 3, 4, except those ending in 1[1-4]
< 	// Used in:
< 	//   Croatian, Czech, Russian, Slovak, Ukrainian
< 	case 6:
< 		return n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;
< 
< 	// Three forms, special case for one and some numbers ending in 2, 3, or 4
< 	// Used in:
< 	//   Polish
< 	case 7:
< 		return n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;
< 
< 	// Four forms, special case for one and all numbers ending in 02, 03, or 04
< 	// Used in:
< 	//   Slovenian
< 	case 8:
< 		return n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3;
< 	}
< }
< 
< static const char *ParseStringChoice(const char *b, uint form, char *dst, int *dstlen)
< {
< 	//<NUM> {Length of each string} {each string}
< 	uint n = (byte)*b++;
< 	uint pos,i, mylen=0,mypos=0;
< 	for(i=pos=0; i!=n; i++) {
< 		uint len = (byte)*b++;
< 		if (i == form) {
< 			mypos = pos;
< 			mylen = len;
< 		}
< 		pos += len;
< 	}
< 	*dstlen = mylen;
< 	memcpy(dst, b + mypos, mylen);
< 	return b + pos;
< }
< 
< 
< static char *FormatString(char *buff, const char *str, const int32 *argv, uint casei)
---
> static byte *DecodeString(byte *buff, const byte *str)
530,531d331
< 	const int32 *argv_orig = argv;
< 	uint modifier = 0;
533,534c333,334
< 	while ((b = *str++) != '\0') {
< 		switch (b) {
---
> 	while((b = *str++) != 0) {
> 		switch(b) {
544,545c344,345
< 		case 0x7B: // {COMMA}
< 			buff = FormatCommaNumber(buff, GetInt32(&argv));
---
> 		case 0x7B: // {COMMA32}
> 			buff = FormatCommaNumber(buff, GetParamInt32());
547,548c347,348
< 		case 0x7C: // Move argument pointer
< 			argv = argv_orig + (byte)*str++;
---
> 		case 0x7C: // {COMMA16}
> 			buff = FormatCommaNumber(buff, GetParamInt16());
550,554c350,351
< 		case 0x7D: { // {P}
< 			int32 v = argv_orig[(byte)*str++]; // contains the number that determines plural
< 			int len;
< 			str = ParseStringChoice(str, DeterminePluralForm(v), buff, &len);
< 			buff += len;
---
> 		case 0x7D: // {COMMA8}
> 			buff = FormatCommaNumber(buff, GetParamInt8());
556,558c353,354
< 		}
< 		case 0x7E: // {NUM}
< 			buff = FormatNoCommaNumber(buff, GetInt32(&argv));
---
> 		case 0x7E: // {NUMU16}
> 			buff = FormatNoCommaNumber(buff, GetParamInt16());
561c357
< 			buff = FormatGenericCurrency(buff, &_currency_specs[_opt_ptr->currency], GetInt32(&argv), false);
---
> 			buff = FormatGenericCurrency(buff, &_currency_specs[_opt.currency], GetParamInt32(), false);
566c362
< 			buff = GetStringWithArgs(buff, READ_LE_UINT16(str-2), argv);
---
> 			buff = GetString(buff, READ_LE_UINT16(str-2));
569c365
< 			buff = FormatYmdString(buff, GetInt32(&argv));
---
> 			buff = FormatYmdString(buff, GetParamUint16());
572c368
< 			buff = FormatMonthAndYear(buff, GetInt32(&argv));
---
> 			buff = FormatMonthAndYear(buff, GetParamUint16());
575,576c371,372
< 			int value = GetInt32(&argv);
< 			if (_opt_ptr->kilometers) value = value * 1648 >> 10;
---
> 			int value = GetParamInt16();
> 			if (_opt.kilometers) value = value * 1648 >> 10;
578c374
< 			if (_opt_ptr->kilometers) {
---
> 			if (_opt.kilometers) {
586a383
> 
589c386
< 			switch (*str++) {
---
> 			switch(*str++) {
591c388,391
< 				buff = FormatGenericCurrency(buff, &_currency_specs[_opt_ptr->currency], GetInt32(&argv), true);
---
> 				buff = FormatGenericCurrency(buff, &_currency_specs[_opt.currency], GetParamInt32(), true);
> 				break;
> 			case 1: /* {INT32} */
> 				buff = FormatNoCommaNumber(buff, GetParamInt32());
594c394
< 				buff = strecpy(buff, _openttd_revision, NULL);
---
> 				buff = str_cat(buff, (const byte*)_openttd_revision);
600c400,401
< 				StringID cargo_str = _cargo_string_list[_opt_ptr->landscape][GetInt32(&argv)];
---
> 				char *s;
> 				uint16 cargo_str = _cargo_string_list[_opt.landscape][(byte)GetParamInt8()];
603,676c404,405
< 				buff = FormatCommaNumber(buff, GetInt32(&argv) * multiplier);
< 				buff = strecpy(buff, " ", NULL);
< 				buff = strecpy(buff, GetStringPtr(cargo_str), NULL);
< 			} break;
< 			case 4: {/* {CURRCOMPACT64} */
< 				// 64 bit compact currency-unit
< 				buff = FormatGenericCurrency(buff, &_currency_specs[_opt_ptr->currency], GetInt64(&argv), true);
< 				break;
< 			}
< 			case 5: { /* {STRING1} */
< 				// String that consumes ONE argument
< 				uint str = modifier + GetInt32(&argv);
< 				buff = GetStringWithArgs(buff, str, GetArgvPtr(&argv, 1));
< 				modifier = 0;
< 				break;
< 			}
< 			case 6: { /* {STRING2} */
< 				// String that consumes TWO arguments
< 				uint str = modifier + GetInt32(&argv);
< 				buff = GetStringWithArgs(buff, str, GetArgvPtr(&argv, 2));
< 				modifier = 0;
< 				break;
< 			}
< 			case 7: { /* {STRING3} */
< 				// String that consumes THREE arguments
< 				uint str = modifier + GetInt32(&argv);
< 				buff = GetStringWithArgs(buff, str, GetArgvPtr(&argv, 3));
< 				modifier = 0;
< 				break;
< 			}
< 			case 8: { /* {STRING4} */
< 				// String that consumes FOUR arguments
< 				uint str = modifier + GetInt32(&argv);
< 				buff = GetStringWithArgs(buff, str, GetArgvPtr(&argv, 4));
< 				modifier = 0;
< 				break;
< 			}
< 			case 9: { /* {STRING5} */
< 				// String that consumes FIVE arguments
< 				uint str = modifier + GetInt32(&argv);
< 				buff = GetStringWithArgs(buff, str, GetArgvPtr(&argv, 5));
< 				modifier = 0;
< 				break;
< 			}
< 
< 			case 10: { /* {STATIONFEATURES} */
< 				buff = StationGetSpecialString(buff, GetInt32(&argv));
< 				break;
< 			}
< 
< 			case 11: { /* {INDUSTRY} */
< 				Industry *i = GetIndustry(GetInt32(&argv));
< 				int32 args[2];
< 
< 				// industry not valid anymore?
< 				if (i->xy == 0)
< 					break;
< 
< 				// First print the town name and the industry type name
< 				// The string STR_INDUSTRY_PATTERN controls the formatting
< 				args[0] = i->town->index;
< 				args[1] = i->type + STR_4802_COAL_MINE;
< 				buff = FormatString(buff, GetStringPtr(STR_INDUSTRY_FORMAT), args, modifier >> 24);
< 				modifier = 0;
< 				break;
< 			}
< 
< 			case 12: { // {VOLUME}
< 				buff = FormatCommaNumber(buff, GetInt32(&argv) * 1000);
< 				buff = strecpy(buff, " ", NULL);
< 				buff = FormatString(buff, GetStringPtr(STR_LITERS), NULL, modifier >> 24);
< 				modifier = 0;
< 				break;
< 			}
---
> 				buff = FormatCommaNumber(buff, GetParamInt16() * multiplier );
> 				s = GetStringPtr(cargo_str);
678,699c407,412
< 			case 13: { // {G 0 Der Die Das}
< 				byte *s = (byte*)GetStringPtr(argv_orig[(byte)*str++]); // contains the string that determines gender.
< 				int len;
< 				int gender = 0;
< 				if (s && s[0] == 0x87)
< 					gender = s[1];
< 				str = ParseStringChoice(str, gender, buff, &len);
< 				buff += len;
< 				break;
< 			}
< 
< 			case 14: { // {DATE_TINY}
< 				buff = FormatTinyDate(buff, GetInt32(&argv));
< 				break;
< 			}
< 
< 			case 15: { // {CARGO}
< 				// Layout now is:
< 				//   8bit   - cargo type
< 				//   16-bit - cargo count
< 				StringID cargo_str = _cargoc.names_long[GetInt32(&argv)];
< 				buff = GetStringWithArgs(buff, cargo_str, argv++);
---
> 				memcpy(buff++, " ", 1);
> 				while (*s) *buff++ = *s++;
> 			}	break;
> 			case 4: /* {CURRCOMPACT64} */
> 				// 64 bit compact currency-unit
> 				buff = FormatGenericCurrency(buff, &_currency_specs[_opt.currency], GetParamInt64(), true);
701d413
< 			}
709c421,422
< 			argv++;
---
> 			GetParamInt16();
> 			//assert(0);
711,724c424,429
< 
< 		// 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 0x87: // {GENDER 0}
< 			str++;
< 			break;
< 
< 		case 0x88: {// {STRING}
< 			uint str = modifier + GetInt32(&argv);
< 			// WARNING. It's prohibited for the included string to consume any arguments.
< 			// For included strings that consume argument, you should use STRING1, STRING2 etc.
< 			// To debug stuff you can set argv to NULL and it will tell you
< 			buff = GetStringWithArgs(buff, str, argv);
< 			modifier = 0;
---
> 		case 0x87: { // {VOLUME}
> 			char *s;
> 			buff = FormatCommaNumber(buff, GetParamInt16() * 1000);
> 			memcpy(buff++, " ", 1);
> 			s = GetStringPtr(STR_LITERS);
> 			while (*s) *buff++ = *s++;
728,740c433,446
< 		case 0x99: { // {WAYPOINT}
< 			int32 temp[2];
< 			Waypoint *wp = GetWaypoint(GetInt32(&argv));
< 			StringID str;
< 			if (wp->string != STR_NULL) {
< 				str = wp->string;
< 			} else {
< 				temp[0] = wp->town_index;
< 				temp[1] = wp->town_cn + 1;
< 				str = wp->town_cn == 0 ? STR_WAYPOINTNAME_CITY : STR_WAYPOINTNAME_CITY_SERIAL;
< 			}
< 			buff = GetStringWithArgs(buff, str, temp);
< 		} break;
---
> 		case 0x88: // {STRING}
> 			buff = GetString(buff, (uint16)GetParamUint16());
> 			break;
> 
> 		case 0x99: { // {CARGO}
> 			// Layout now is:
> 			//   8bit   - cargo type
> 			//   16-bit - cargo count
> 			int cargo_str = _cargoc.names_long_s[GetParamInt8()];
> 			// Now check if the cargo count is 1, if it is, increase string by 32.
> 			if (GetDParam(0) != 1) cargo_str += 32;
> 			buff = GetString(buff, cargo_str);
> 			break;
> 		}
744,748c450,453
< 			int32 temp[2];
< 
< 			st = GetStation(GetInt32(&argv));
< 			if (st->xy == 0) { // station doesn't exist anymore
< 				buff = GetStringWithArgs(buff, STR_UNKNOWN_DESTINATION, NULL);
---
> 			InjectDparam(1);
> 			st = GetStation(GetDParam(1));
> 			if (!st->xy) { // station doesn't exist anymore
> 				buff = GetString(buff, STR_UNKNOWN_DESTINATION);
751,753c456,458
< 			temp[0] = st->town->townnametype;
< 			temp[1] = st->town->townnameparts;
< 			buff = GetStringWithArgs(buff, st->string_id, temp);
---
> 			SetDParam(0, st->town->townnametype);
> 			SetDParam(1, st->town->townnameparts);
> 			buff = GetString(buff, st->string_id);
758,759c463
< 			int32 temp[1];
< 			t = GetTown(GetInt32(&argv));
---
> 			t = GetTown(GetDParam(0));
761,762c465,466
< 			temp[0] = t->townnameparts;
< 			buff = GetStringWithArgs(buff, t->townnametype, temp);
---
> 			SetDParam(0, t->townnameparts);
> 			buff = GetString(buff, t->townnametype);
767,774c471
< 			buff = FormatGenericCurrency(buff, &_currency_specs[_opt_ptr->currency], GetInt64(&argv), false);
< 			break;
< 		}
< 
< 		case 0x9D: { // {SETCASE}
< 		             // This is a pseudo command, it's outputted when someone does {STRING.ack}
< 			// The modifier is added to all subsequent GetStringWithArgs that accept the modifier.
< 			modifier = (byte)*str++ << 24;
---
> 			buff = FormatGenericCurrency(buff, &_currency_specs[_opt.currency], GetParamInt64(), false);
778,786c475,489
< 		case 0x9E: { // {Used to implement case switching}
< 			// <0x9E> <NUM CASES> <CASE1> <LEN1> <STRING1> <CASE2> <LEN2> <STRING2> <CASE3> <LEN3> <STRING3> <STRINGDEFAULT>
< 			// Each LEN is printed using 2 bytes in big endian order.
< 			uint num = (byte)*str++;
< 			while (num) {
< 				if ((byte)str[0] == casei) {
< 					// Found the case, adjust str pointer and continue
< 					str += 3;
< 					break;
---
> 		case 0x9D: { // {WAYPOINT}
> 			Waypoint *cp = &_waypoints[GetDParam(0)];
> 			StringID str;
> 			int idx;
> 			if (~cp->town_or_string & 0xC000) {
> 				GetParamInt32(); // skip it
> 				str = cp->town_or_string;
> 			} else {
> 				idx = (cp->town_or_string >> 8) & 0x3F;
> 				if (idx == 0) {
> 					str = STR_WAYPOINTNAME_CITY;
> 				} else {
> 					InjectDparam(1);
> 					SetDParam(1, idx + 1);
> 					str = STR_WAYPOINTNAME_CITY_SERIAL;
788,790c491
< 				// Otherwise skip to the next case
< 				str += 3 + (str[1] << 8) + str[2];
< 				num--;
---
> 				SetDParam(0, cp->town_or_string & 0xFF);
791a493,498
> 
> 			buff = GetString(buff, str);
> 		} break;
> 
> 		case 0x9E: { // {DATE_TINY}
> 			buff = FormatTinyDate(buff, GetParamUint16());
803c510
< 	*buff = '\0';
---
> 	buff[0] = 0;
808c515
< static char *StationGetSpecialString(char *buff, int x)
---
> static byte *StationGetSpecialString(byte *buff)
810,815c517,523
< 	if (x & 0x01) *buff++ = '\xB4';
< 	if (x & 0x02) *buff++ = '\xB5';
< 	if (x & 0x04) *buff++ = '\xB6';
< 	if (x & 0x08) *buff++ = '\xB7';
< 	if (x & 0x10) *buff++ = '\xB8';
< 	*buff = '\0';
---
> 	int x = GetParamInt8();
> 	if (x & 1) *buff++ = 0xB4;
> 	if (x & 2) *buff++ = 0xB5;
> 	if (x & 4) *buff++ = 0xB6;
> 	if (x & 8) *buff++ = 0xB7;
> 	if (x & 16) *buff++ = 0xB8;
> 	*buff = 0;
819,821c527,530
< static char *GetSpecialTownNameString(char *buff, int ind, uint32 seed)
< {
< 	_town_name_generators[ind](buff, seed);
---
> static byte *GetSpecialTownNameString(byte *buff, int ind) {
> 	uint32 x = GetParamInt32();
> 
> 	_town_name_generators[ind](buff, x);
823c532
< 	while (*buff != '\0') buff++;
---
> 	while (*buff != 0) buff++;
887,889c596,597
< static const char _initial_name_letters[] = {
< 	'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
< 	'K', 'L', 'M', 'N', 'P', 'R', 'S', 'T', 'W',
---
> static const byte _initial_name_letters[] = {
> 	'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'P', 'R', 'S', 'T', 'W',
892c600
< static char *GenAndCoName(char *buff, uint32 arg)
---
> static byte *GenAndCoName(byte *buff)
893a602
> 	uint32 x = GetParamInt32();
898c607
< 	if (_opt_ptr->landscape == LT_CANDY) {
---
> 	if (_opt.landscape == LT_CANDY) {
903,904c612,613
< 	buff = strecpy(buff, _surname_list[base + (num * GB(arg, 16, 8) >> 8)], NULL);
< 	buff = strecpy(buff, " & Co.", NULL);
---
> 	buff = str_cat(buff, _surname_list[base + ((num * (byte)(x >> 16)) >> 8)]);
> 	buff = str_cat(buff, " & Co.");
909c618
< static char *GenPresidentName(char *buff, uint32 x)
---
> static byte *GenPlayerName_4(byte *buff)
910a620
> 	uint32 x = GetParamInt32();
913c623
< 	buff[0] = _initial_name_letters[sizeof(_initial_name_letters) * GB(x, 0, 8) >> 8];
---
> 	buff[0] = _initial_name_letters[ (sizeof(_initial_name_letters) * (byte)x) >> 8];
918c628
< 	i = (sizeof(_initial_name_letters) + 35) * GB(x, 8, 8) >> 8;
---
> 	i = ((sizeof(_initial_name_letters) + 35) * (byte)(x >> 8)) >> 8;
928c638
< 	if (_opt_ptr->landscape == LT_CANDY) {
---
> 	if (_opt.landscape == LT_CANDY) {
933c643
< 	buff = strecpy(buff, _surname_list[base + (num * GB(x, 16, 8) >> 8)], NULL);
---
> 	buff = str_cat(buff, _surname_list[base + ((num * (byte)(x >> 16)) >> 8)]);
963c673
< static char *GetSpecialPlayerNameString(char *buff, int ind, const int32 *argv)
---
> static byte *GetSpecialPlayerNameString(byte *buff, int ind)
965,967c675
< 	switch (ind) {
< 		case 1: // not used
< 			return strecpy(buff, _silly_company_names[GetInt32(&argv) & 0xFFFF], NULL);
---
> 	switch(ind) {
969,970c677,684
< 		case 2: // used for Foobar & Co company names
< 			return GenAndCoName(buff, GetInt32(&argv));
---
> 	// not used
> 	case 1: {
> 		int i = GetParamInt32() & 0xFFFF;
> 		return str_cat(buff, _silly_company_names[i]);
> 	}
> 
> 	case 2: // used for Foobar & Co company names
> 		return GenAndCoName(buff);
972,973c686,687
< 		case 3: // President name
< 			return GenPresidentName(buff, GetInt32(&argv));
---
> 	case 3: // President name
> 		return GenPlayerName_4(buff);
975,976c689,693
< 		case 4: // song names
< 			return strecpy(buff, _song_names[GetInt32(&argv) - 1], NULL);
---
> 	// song names
> 	case 4: {
> 		const char *song = _song_names[GetParamUint16() - 1];
> 		return str_cat(buff, song);
> 	}
980,982c697,699
< 	if (IS_INT_INSIDE(ind - 6, 0, SPECSTR_TOWNNAME_LAST-SPECSTR_TOWNNAME_START + 1)) {
< 		buff = GetSpecialTownNameString(buff, ind - 6, GetInt32(&argv));
< 		return strecpy(buff, " Transport", NULL);
---
> 	if (IS_INT_INSIDE(ind-6, 0, SPECSTR_TOWNNAME_LAST-SPECSTR_TOWNNAME_START+1)) {
> 		buff = GetSpecialTownNameString(buff, ind - 6);
> 		return str_cat(buff, " Transport");
988,989c705
< 		return strecpy(buff,
< 			i == _dynlang.curr ? _langpack->own_name : _dynlang.ent[i].name, NULL);
---
> 		return str_cat(buff, i == _dynlang.curr ? ((LanguagePackHeader*)_langpack)->own_name : _dynlang.ent[i].name);
1001c717
< 		return strecpy(buff, GetScreenshotFormatDesc(i), NULL);
---
> 		return str_cat(buff, GetScreenshotFormatDesc(i));
1003a720
> 
1011,1026c728,736
< 	switch (s) {
< 		case 0x0006: return STR_SV_EMPTY;
< 		case 0x7000: return STR_SV_UNNAMED;
< 		case 0x70E4: return SPECSTR_PLAYERNAME_ENGLISH;
< 		case 0x70E9: return SPECSTR_PLAYERNAME_ENGLISH;
< 		case 0x8864: return STR_SV_TRAIN_NAME;
< 		case 0x902B: return STR_SV_ROADVEH_NAME;
< 		case 0x9830: return STR_SV_SHIP_NAME;
< 		case 0xA02F: return STR_SV_AIRCRAFT_NAME;
< 
< 		default:
< 			if (IS_INT_INSIDE(s, 0x300F, 0x3030))
< 				return s - 0x300F + STR_SV_STNAME;
< 			else
< 				return s;
< 	}
---
> 	if (s == 0x7000) s = STR_SV_UNNAMED;
> 	else if (s == 0x0006) s = STR_SV_EMPTY;
> 	else if (s == 0x8864) s = STR_SV_TRAIN_NAME;
> 	else if (s == 0x902B) s = STR_SV_ROADVEH_NAME;
> 	else if (s == 0x9830) s = STR_SV_SHIP_NAME;
> 	else if (s == 0xA02F) s = STR_SV_AIRCRAFT_NAME;
> 	else if (IS_INT_INSIDE(s, 0x300F, 0x3030)) s = s - 0x300F + STR_SV_STNAME;
> 	else if (s == 0x70E4 || s == 0x70E9) s = SPECSTR_PLAYERNAME_ENGLISH;
> 	return s;
1029,1030c739
< bool ReadLanguagePack(int lang_index)
< {
---
> bool ReadLanguagePack(int lang_index) {
1032c741
< 	LanguagePack *lang_pack;
---
> 	byte *lang_pack;
1034,1035c743,744
< 	char **langpack_offs;
< 	char *s;
---
> 	byte **langpack_offs;
> 	byte *s;
1036a746
> #define HDR ((LanguagePackHeader*)lang_pack)
1043,1045c753,755
< 	if (len < sizeof(LanguagePack) ||
< 			lang_pack->ident != TO_LE32(LANGUAGE_PACK_IDENT) ||
< 			lang_pack->version != TO_LE32(LANGUAGE_PACK_VERSION)) {
---
> 	if (len < sizeof(LanguagePackHeader) ||
> 			HDR->ident != TO_LE32(LANGUAGE_PACK_IDENT) ||
> 			HDR->version != TO_LE32(LANGUAGE_PACK_VERSION)) {
1049d758
< <<<<<<< .mine
1055c764
< 			ShowInfoF("Fonts: Small Font '%s' for '%s' could not be reloaded.", HDR->small_font_name, HDR->name);
---
> 			ShowInfoF("Fonts: Small Font '%s' for '%s' could not be read.", hdr.small_font_name, hdr.name);
1058c767
< 			ShowInfoF("Fonts: Medium Font '%s' for '%s' could not be reloaded.", HDR->medium_font_name, HDR->name);
---
> 			ShowInfoF("Fonts: Medium Font '%s' for '%s' could not be read.", hdr.medium_font_name, hdr.name);
1061c770
< 			ShowInfoF("Fonts: Large Font '%s' for '%s' could not be reloaded.", HDR->large_font_name, HDR->name);
---
> 			ShowInfoF("Fonts: Large Font '%s' for '%s' could not be read.", hdr.large_font_name, hdr.name);
1065,1066d773
< =======
< >>>>>>> .r2761
1069,1070c776,777
< 	for (i = 0; i != 32; i++) {
< 		lang_pack->offsets[i] = READ_LE_UINT16(&lang_pack->offsets[i]);
---
> 	for(i=0; i!=32; i++) {
> 		((LanguagePackHeader*)lang_pack)->offsets[i] = READ_LE_UINT16(&((LanguagePackHeader*)lang_pack)->offsets[i]);
1075,1076c782,783
< 	for (i = 0; i != 32; i++) {
< 		uint num = lang_pack->offsets[i];
---
> 	for(i=0; i!=32; i++) {
> 		uint num = ((LanguagePackHeader*)lang_pack)->offsets[i];
1083c790
< 	langpack_offs = malloc(tot_count * sizeof(*langpack_offs));
---
> 	langpack_offs = (byte**)malloc(tot_count * sizeof(byte*));
1086,1090c793,797
< 	s = lang_pack->data;
< 	for (i = 0; i != tot_count; i++) {
< 		len = (byte)*s;
< 		*s++ = '\0'; // zero terminate the string before.
< 		if (len >= 0xC0) len = ((len & 0x3F) << 8) + (byte)*s++;
---
> 	s = lang_pack + sizeof(LanguagePackHeader);
> 	for(i=0; i!=tot_count; i++) {
> 		len = *s;
> 		*s++ = 0; // zero terminate the string before.
> 		if (len >= 0xC0) { len = ((len & 0x3F) << 8) + *s++; }
1095c802
< 	free(_langpack);
---
> 	if (_langpack) free(_langpack);
1098c805
< 	free(_langpack_offs);
---
> 	if (_langpack_offs) free(_langpack_offs);
1112d818
< <<<<<<< .mine
1115,1121d820
< =======
< 	int i;
< 	int n;
< 	int m;
< 	int def;
< 	LanguagePack hdr;
< >>>>>>> .r2761
1130,1132c829
< 	for (i = m = 0; i != n; i++) {
< 		int j;
< 
---
> 	for(i=m=0; i!=n; i++) {
1136c833
< 		if (in == NULL ||
---
> 		if (!in ||
1156c853
< 		if (strcmp(hdr.name, "English") == 0) def = m;
---
> 		if (!strcmp(hdr.name, "English")) def = m;
1165c862
< 	for (i = 0; i != dl->num; i++)
---
> 	for(i=0; i!=dl->num; i++)
1169,1170c866,867
< 	for (i = 0; i != dl->num; i++)
< 		if (strcmp(dl->ent[i].file, dl->curr_file) == 0) {
---
> 	for(i=0; i!=dl->num; i++)
> 		if (!strcmp(dl->ent[i].file, dl->curr_file)) {
1178d874
< 
