(svn r2564) Fix: Fixed conceptual issue in network_gui.c. AllocateName is not meant to be used by GUI-code, because it modifies the "game-state".
authorludde
Thu, 14 Jul 2005 09:43:59 +0000
changeset 2055 9361b56db8ba
parent 2054 e313dd080bd3
child 2056 4cd298c2e658
(svn r2564) Fix: Fixed conceptual issue in network_gui.c. AllocateName is not meant to be used by GUI-code, because it modifies the "game-state".
Added a way to bind a C-string to an openttd string which doesn't modify the game state.
landscape.c
network.c
network_gui.c
openttd.c
openttd.h
player_gui.c
settings_gui.c
strings.c
variables.h
--- a/landscape.c	Thu Jul 14 06:10:23 2005 +0000
+++ b/landscape.c	Thu Jul 14 09:43:59 2005 +0000
@@ -422,7 +422,7 @@
 	_cur_tileloop_tile = tile;
 }
 
-void InitializeLandscape()
+void InitializeLandscape(void)
 {
 	uint map_size;
 	uint i;
--- a/network.c	Thu Jul 14 06:10:23 2005 +0000
+++ b/network.c	Thu Jul 14 09:43:59 2005 +0000
@@ -93,7 +93,6 @@
 	const int duration = 10; // Game days the messages stay visible
 	char message[1024];
 	char temp[1024];
-	StringID TempStr = STR_NULL;
 
 	va_start(va, str);
 	vsprintf(buf, str, va);
@@ -110,11 +109,9 @@
 			break;
 		case NETWORK_ACTION_GIVE_MONEY:
 			if (self_send) {
-				TempStr = AllocateName(name, 0);
-				SetDParam(0, TempStr);
+				SetDParamStr(0, name);
 				SetDParam(1, atoi(buf));
 				GetString(temp, STR_NETWORK_GAVE_MONEY_AWAY);
-				DeleteName(TempStr);
 				snprintf(message, sizeof(message), "*** %s", temp);
 			} else {
 				SetDParam(0, atoi(buf));
@@ -124,31 +121,23 @@
 			break;
 		case NETWORK_ACTION_CHAT_PLAYER:
 			if (self_send) {
-				TempStr = AllocateName(name, 0);
-				SetDParam(0, TempStr);
+				SetDParamStr(0, name);
 				GetString(temp, STR_NETWORK_CHAT_TO_COMPANY);
-				DeleteName(TempStr);
 				snprintf(message, sizeof(message), "%s %s", temp, buf);
 			} else {
-				TempStr = AllocateName(name, 0);
-				SetDParam(0, TempStr);
+				SetDParamStr(0, name);
 				GetString(temp, STR_NETWORK_CHAT_COMPANY);
-				DeleteName(TempStr);
 				snprintf(message, sizeof(message), "%s %s", temp, buf);
 			}
 			break;
 		case NETWORK_ACTION_CHAT_CLIENT:
 			if (self_send) {
-				TempStr = AllocateName(name, 0);
-				SetDParam(0, TempStr);
+				SetDParamStr(0, name);
 				GetString(temp, STR_NETWORK_CHAT_TO_CLIENT);
-				DeleteName(TempStr);
 				snprintf(message, sizeof(message), "%s %s", temp, buf);
 			} else {
-				TempStr = AllocateName(name, 0);
-				SetDParam(0, TempStr);
+				SetDParamStr(0, name);
 				GetString(temp, STR_NETWORK_CHAT_CLIENT);
-				DeleteName(TempStr);
 				snprintf(message, sizeof(message), "%s %s", temp, buf);
 			}
 			break;
@@ -157,10 +146,8 @@
 			snprintf(message, sizeof(message), "*** %s %s %s", name, temp, buf);
 			break;
 		default:
-			TempStr = AllocateName(name, 0);
-			SetDParam(0, TempStr);
+			SetDParamStr(0, name);
 			GetString(temp, STR_NETWORK_CHAT_ALL);
-			DeleteName(TempStr);
 			snprintf(message, sizeof(message), "%s %s", temp, buf);
 			break;
 	}
--- a/network_gui.c	Thu Jul 14 06:10:23 2005 +0000
+++ b/network_gui.c	Thu Jul 14 09:43:59 2005 +0000
@@ -190,10 +190,11 @@
 
 			DrawStringMultiCenter(365, 30, STR_NETWORK_GAME_INFO, 0);
 
-			SetDParam(0, _str_game_name);
+
+			SetDParamStr(0, _selected_item->info.server_name);
 			DrawStringMultiCenter(365, 42, STR_ORANGE, 2); // game name
 
-			SetDParam(0, _str_map_name);
+			SetDParamStr(0, _selected_item->info.map_name);
 			DrawStringMultiCenter(365, 54, STR_02BD, 2); // map name
 
 			SetDParam(0, _selected_item->info.clients_on);
@@ -214,11 +215,11 @@
 			DrawString(260, y, STR_NETWORK_MAP_SIZE, 2); // map size
 			y+=10;
 
-			SetDParam(0, _str_server_version);
+			SetDParamStr(0, _selected_item->info.server_revision);
 			DrawString(260, y, STR_NETWORK_SERVER_VERSION, 2); // server version
 			y+=10;
 
-			SetDParam(0, _str_server_address);
+			SetDParamStr(0, _selected_item->info.hostname);
 			SetDParam(1, _selected_item->port);
 			DrawString(260, y, STR_NETWORK_SERVER_ADDRESS, 2); // server address
 			y+=10;
@@ -273,30 +274,6 @@
 					return;
 				}
 				_selected_item = cur_item;
-
-				DeleteName(_str_game_name);
-				DeleteName(_str_map_name);
-				DeleteName(_str_server_version);
-				DeleteName(_str_server_address);
-				if (_selected_item->info.server_name[0] != '\0')
-					_str_game_name = AllocateName(_selected_item->info.server_name, 0);
-				else
-					_str_game_name = STR_EMPTY;
-
-				if (_selected_item->info.map_name[0] != '\0')
-					_str_map_name = AllocateName(_selected_item->info.map_name, 0);
-				else
-					_str_map_name = STR_EMPTY;
-
-				if (_selected_item->info.server_revision[0] != '\0')
-					_str_server_version = AllocateName(_selected_item->info.server_revision, 0);
-				else
-					_str_server_version = STR_EMPTY;
-
-				if (_selected_item->info.hostname[0] != '\0')
-					_str_server_address = AllocateName(_selected_item->info.hostname, 0);
-				else
-					_str_server_address = STR_EMPTY;
 			}
 			SetWindowDirty(w);
 		} break;
@@ -307,16 +284,13 @@
 			}
 			break;
 		case 12: { // Add a server
-				StringID str = AllocateName(_network_default_ip, 0);
-
 				ShowQueryString(
-				str,
+				BindCString(_network_default_ip),
 				STR_NETWORK_ENTER_IP,
 				31 | 0x1000,  // maximum number of characters OR
 				250, // characters up to this width pixels, whichever is satisfied first
 				w->window_class,
 				w->window_number);
-				DeleteName(str);
 		} break;
 		case 13: /* Start server */
 			ShowNetworkStartServerWindow();
@@ -536,10 +510,8 @@
 			ShowNetworkGameWindow();
 			break;
 		case 4: { /* Set password button */
-			StringID str;
-			str = AllocateName(_network_server_password, 0);
-			ShowQueryString(str, STR_NETWORK_SET_PASSWORD, 20, 250, w->window_class, w->window_number);
-			DeleteName(str);
+			ShowQueryString(BindCString(_network_server_password),
+				STR_NETWORK_SET_PASSWORD, 20, 250, w->window_class, w->window_number);
 			} break;
 		case 5: { /* Select map */
 			int y = (e->click.pt.y - NSSWND_START) / NSSWND_ROWSIZE;
@@ -697,7 +669,6 @@
 	switch(e->event) {
 	case WE_PAINT: {
 		int y = NET_PRC__OFFSET_TOP_WIDGET_COMPANY, pos;
-		StringID str;
 
 		w->disabled_state = (_selected_company_item == -1) ? 1 << 7 : 0;
 
@@ -745,10 +716,8 @@
 			uint xm;
 			y = 65;
 
-			str = AllocateName(_network_player_info[_selected_company_item].company_name, 0);
-			SetDParam(0, str);
+			SetDParamStr(0, _network_player_info[_selected_company_item].company_name);
 			DrawString(x, y, STR_NETWORK_COMPANY_NAME, 2);
-			DeleteName(str);
 			y += 10;
 
 			SetDParam(0, _network_player_info[_selected_company_item].inaugurated_year + MAX_YEAR_BEGIN_REAL);
@@ -787,10 +756,8 @@
 			DrawString(x, y, STR_NETWORK_STATIONS, 2); // stations
 			y += 10;
 
-			str = AllocateName(_network_player_info[_selected_company_item].players, 0);
-			SetDParam(0, str);
+			SetDParamStr(0, _network_player_info[_selected_company_item].players);
 			xm = DrawString(x, y, STR_NETWORK_PLAYERS, 2); // players
-			DeleteName(str);
 			y += 10;
 		}
 	}	break;
--- a/openttd.c	Thu Jul 14 06:10:23 2005 +0000
+++ b/openttd.c	Thu Jul 14 09:43:59 2005 +0000
@@ -738,7 +738,7 @@
 static void ShowScreenshotResult(bool b)
 {
 	if (b) {
-		SetDParam(0, STR_SPEC_SCREENSHOT_NAME);
+		SetDParamStr(0, _screenshot_name);
 		ShowErrorMessage(INVALID_STRING_ID, STR_031B_SCREENSHOT_SUCCESSFULLY, 0, 0);
 	} else {
 		ShowErrorMessage(INVALID_STRING_ID, STR_031C_SCREENSHOT_FAILED, 0, 0);
--- a/openttd.h	Thu Jul 14 06:10:23 2005 +0000
+++ b/openttd.h	Thu Jul 14 09:43:59 2005 +0000
@@ -517,8 +517,9 @@
 	SPECSTR_SCREENSHOT_START = 0x7140,
 	SPECSTR_SCREENSHOT_END = 0x715F,
 
-	STR_SPEC_SCREENSHOT_NAME = 0xF800,
-	STR_SPEC_USERSTRING = 0xF801,
+	// Used to implement SetDParamStr
+	STR_SPEC_DYNSTRING = 0xF800,
+	STR_SPEC_USERSTRING = 0xF808,
 };
 
 typedef void PlaceProc(TileIndex tile);
--- a/player_gui.c	Thu Jul 14 06:10:23 2005 +0000
+++ b/player_gui.c	Thu Jul 14 09:43:59 2005 +0000
@@ -614,11 +614,9 @@
 		case 11: { /* Password protect company */
 			#ifdef ENABLE_NETWORK
 			if (!IsWindowOfPrototype(w, _other_player_company_widgets)) {
-				StringID str;
 				WP(w,def_d).byte_1 = 2;
-				str = AllocateName(_network_player_info[_local_player].password, 0);
-				ShowQueryString(str, STR_SET_COMPANY_PASSWORD, sizeof(_network_player_info[_local_player].password), 250, w->window_class, w->window_number);
-				DeleteName(str);
+				ShowQueryString(BindCString(_network_player_info[_local_player].password),
+					STR_SET_COMPANY_PASSWORD, sizeof(_network_player_info[_local_player].password), 250, w->window_class, w->window_number);
 			}
 			#endif
 		}	break;
--- a/settings_gui.c	Thu Jul 14 06:10:23 2005 +0000
+++ b/settings_gui.c	Thu Jul 14 09:43:59 2005 +0000
@@ -1384,21 +1384,21 @@
 			case 1: // separator
 				if ( IS_INT_INSIDE(x, 10, 30) )  // clicked button
 					WP(w,def_d).data_1 =  (1 << (line * 2 + 1));
-				str = AllocateName(_str_separator, 0);
+				str = BindCString(_str_separator);
 				len = 1;
 				edittext = true;
 			break;
 			case 2: // prefix
 				if ( IS_INT_INSIDE(x, 10, 30) )  // clicked button
 					WP(w,def_d).data_1 =  (1 << (line * 2 + 1));
-				str = AllocateName(_currency_specs[23].prefix, 0);
+				str = BindCString(_currency_specs[23].prefix);
 				len = 12;
 				edittext = true;
 			break;
 			case 3: // suffix
 				if ( IS_INT_INSIDE(x, 10, 30) )  // clicked button
 					WP(w,def_d).data_1 =  (1 << (line * 2 + 1));
-				str = AllocateName(_currency_specs[23].suffix, 0);
+				str = BindCString(_currency_specs[23].suffix);
 				len = 12;
 				edittext = true;
 			break;
@@ -1432,7 +1432,6 @@
 			250, // characters up to this width pixels, whichever is satisfied first
 			w->window_class,
 			w->window_number);
-			if (str !=  STR_CONFIG_PATCHES_INT32) DeleteName(str);
 		}
 
 		w->flags4 |= 5 << WF_TIMEOUT_SHL;
--- a/strings.c	Thu Jul 14 06:10:23 2005 +0000
+++ b/strings.c	Thu Jul 14 09:43:59 2005 +0000
@@ -125,6 +125,17 @@
 };
 
 
+#define NUM_BOUND_STRINGS 8
+
+// Array to hold the bound strings.
+static const char *_bound_strings[NUM_BOUND_STRINGS];
+
+// 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)];
@@ -142,9 +153,6 @@
 
 		case 0x30D1:
 			return StationGetSpecialString(buffr);
-
-		case STR_SPEC_SCREENSHOT_NAME:
-			return DecodeString(buffr, _screenshot_name);
 	}
 
 	switch (tab) {
@@ -160,7 +168,11 @@
 			return GetName(index, buffr);
 
 		case 31: // special or dynamic strings
-			return DecodeString(buffr, _userstring);
+			if (index < (STR_SPEC_USERSTRING & 0x7FF)) {
+				return DecodeString(buffr, _bound_strings[index]);
+			} else {
+				return DecodeString(buffr, _userstring);
+			}
 
 		default:
 			break;
@@ -175,6 +187,22 @@
 	return DecodeString(buffr, GetStringPtr(string));
 }
 
+// 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 idx = (++_bind_index) & (NUM_BOUND_STRINGS - 1);
+	_bound_strings[idx] = str;
+	return idx + STR_SPEC_DYNSTRING;
+}
+
+// This function is used to "bind" a C string to a OpenTTD dparam slot.
+void SetDParamStr(uint n, const char *str)
+{
+	SetDParam(n, BindCString(str));
+}
+
 void InjectDParam(int amount)
 {
 	memmove(_decode_parameters + amount, _decode_parameters, sizeof(_decode_parameters) - amount * sizeof(uint32));
--- a/variables.h	Thu Jul 14 06:10:23 2005 +0000
+++ b/variables.h	Thu Jul 14 09:43:59 2005 +0000
@@ -424,6 +424,16 @@
 	return _decode_parameters[n];
 }
 
+// Used to bind a C string name to a dparam number.
+// NOTE: This has a short lifetime. You can't
+//       use this string much later or it will be gone.
+void SetDParamStr(uint n, const char *str);
+
+// This function takes a C-string and allocates a temporary string ID.
+// The duration of the bound string is valid only until the next acll to GetString,
+// so be careful.
+StringID BindCString(const char *str);
+
 
 #define COPY_IN_DPARAM(offs,src,num) memcpy(_decode_parameters + offs, src, sizeof(uint32) * (num))
 #define COPY_OUT_DPARAM(dst,offs,num) memcpy(dst,_decode_parameters + offs, sizeof(uint32) * (num))