strings.c
changeset 2055 9361b56db8ba
parent 2053 940cea81b43c
child 2056 4cd298c2e658
equal deleted inserted replaced
2054:e313dd080bd3 2055:9361b56db8ba
   123 		STR_NOTHING
   123 		STR_NOTHING
   124 	}
   124 	}
   125 };
   125 };
   126 
   126 
   127 
   127 
       
   128 #define NUM_BOUND_STRINGS 8
       
   129 
       
   130 // Array to hold the bound strings.
       
   131 static const char *_bound_strings[NUM_BOUND_STRINGS];
       
   132 
       
   133 // This index is used to implement a "round-robin" allocating of
       
   134 // slots for BindCString. NUM_BOUND_STRINGS slots are reserved.
       
   135 // Which means that after NUM_BOUND_STRINGS calls to BindCString,
       
   136 // the indices will be reused.
       
   137 static int _bind_index;
       
   138 
   128 static const char *GetStringPtr(StringID string)
   139 static const char *GetStringPtr(StringID string)
   129 {
   140 {
   130 	return _langpack_offs[_langtab_start[string >> 11] + (string & 0x7FF)];
   141 	return _langpack_offs[_langtab_start[string >> 11] + (string & 0x7FF)];
   131 }
   142 }
   132 
   143 
   140 			error("!invalid string id 0 in GetString");
   151 			error("!invalid string id 0 in GetString");
   141 			break;
   152 			break;
   142 
   153 
   143 		case 0x30D1:
   154 		case 0x30D1:
   144 			return StationGetSpecialString(buffr);
   155 			return StationGetSpecialString(buffr);
   145 
       
   146 		case STR_SPEC_SCREENSHOT_NAME:
       
   147 			return DecodeString(buffr, _screenshot_name);
       
   148 	}
   156 	}
   149 
   157 
   150 	switch (tab) {
   158 	switch (tab) {
   151 		case 4:
   159 		case 4:
   152 			if (index >= 0xC0) return GetSpecialTownNameString(buffr, index - 0xC0);
   160 			if (index >= 0xC0) return GetSpecialTownNameString(buffr, index - 0xC0);
   158 
   166 
   159 		case 15:
   167 		case 15:
   160 			return GetName(index, buffr);
   168 			return GetName(index, buffr);
   161 
   169 
   162 		case 31: // special or dynamic strings
   170 		case 31: // special or dynamic strings
   163 			return DecodeString(buffr, _userstring);
   171 			if (index < (STR_SPEC_USERSTRING & 0x7FF)) {
       
   172 				return DecodeString(buffr, _bound_strings[index]);
       
   173 			} else {
       
   174 				return DecodeString(buffr, _userstring);
       
   175 			}
   164 
   176 
   165 		default:
   177 		default:
   166 			break;
   178 			break;
   167 	}
   179 	}
   168 
   180 
   171 			"!String 0x%X is invalid. "
   183 			"!String 0x%X is invalid. "
   172 			"Probably because an old version of the .lng file.\n", string
   184 			"Probably because an old version of the .lng file.\n", string
   173 		);
   185 		);
   174 
   186 
   175 	return DecodeString(buffr, GetStringPtr(string));
   187 	return DecodeString(buffr, GetStringPtr(string));
       
   188 }
       
   189 
       
   190 // This function takes a C-string and allocates a temporary string ID.
       
   191 // The duration of the bound string is valid only until the next GetString,
       
   192 // so be careful.
       
   193 StringID BindCString(const char *str)
       
   194 {
       
   195 	int idx = (++_bind_index) & (NUM_BOUND_STRINGS - 1);
       
   196 	_bound_strings[idx] = str;
       
   197 	return idx + STR_SPEC_DYNSTRING;
       
   198 }
       
   199 
       
   200 // This function is used to "bind" a C string to a OpenTTD dparam slot.
       
   201 void SetDParamStr(uint n, const char *str)
       
   202 {
       
   203 	SetDParam(n, BindCString(str));
   176 }
   204 }
   177 
   205 
   178 void InjectDParam(int amount)
   206 void InjectDParam(int amount)
   179 {
   207 {
   180 	memmove(_decode_parameters + amount, _decode_parameters, sizeof(_decode_parameters) - amount * sizeof(uint32));
   208 	memmove(_decode_parameters + amount, _decode_parameters, sizeof(_decode_parameters) - amount * sizeof(uint32));