summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorludde <ludde@openttd.org>2005-07-14 09:43:59 +0000
committerludde <ludde@openttd.org>2005-07-14 09:43:59 +0000
commit3e62457107457c8295076370425e9a1df44fa58c (patch)
treef6981bd89e076320ae37ab99f9dbf0619bca554c
parent1a046ff4c6f0295328ccc0cd6a4cd7a491f7ddbf (diff)
downloadopenttd-3e62457107457c8295076370425e9a1df44fa58c.tar.xz
(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.
-rw-r--r--landscape.c2
-rw-r--r--network.c25
-rw-r--r--network_gui.c53
-rw-r--r--openttd.c2
-rw-r--r--openttd.h5
-rw-r--r--player_gui.c6
-rw-r--r--settings_gui.c7
-rw-r--r--strings.c36
-rw-r--r--variables.h10
9 files changed, 68 insertions, 78 deletions
diff --git a/landscape.c b/landscape.c
index 31f134e93..bd708aea4 100644
--- a/landscape.c
+++ b/landscape.c
@@ -422,7 +422,7 @@ void RunTileLoop(void)
_cur_tileloop_tile = tile;
}
-void InitializeLandscape()
+void InitializeLandscape(void)
{
uint map_size;
uint i;
diff --git a/network.c b/network.c
index 3dcff1b30..e422c5e20 100644
--- a/network.c
+++ b/network.c
@@ -93,7 +93,6 @@ void CDECL NetworkTextMessage(NetworkAction action, uint16 color, bool self_send
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 @@ void CDECL NetworkTextMessage(NetworkAction action, uint16 color, bool self_send
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 @@ void CDECL NetworkTextMessage(NetworkAction action, uint16 color, bool self_send
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 @@ void CDECL NetworkTextMessage(NetworkAction action, uint16 color, bool self_send
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;
}
diff --git a/network_gui.c b/network_gui.c
index 95911fa8a..0f33962d2 100644
--- a/network_gui.c
+++ b/network_gui.c
@@ -190,10 +190,11 @@ static void NetworkGameWindowWndProc(Window *w, WindowEvent *e)
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 @@ static void NetworkGameWindowWndProc(Window *w, WindowEvent *e)
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 @@ static void NetworkGameWindowWndProc(Window *w, WindowEvent *e)
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 @@ static void NetworkGameWindowWndProc(Window *w, WindowEvent *e)
}
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 @@ static void NetworkStartServerWindowWndProc(Window *w, WindowEvent *e)
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 @@ static void NetworkLobbyWindowWndProc(Window *w, WindowEvent *e)
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 @@ static void NetworkLobbyWindowWndProc(Window *w, WindowEvent *e)
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 @@ static void NetworkLobbyWindowWndProc(Window *w, WindowEvent *e)
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;
diff --git a/openttd.c b/openttd.c
index 9abf6e78a..26057a517 100644
--- a/openttd.c
+++ b/openttd.c
@@ -738,7 +738,7 @@ int ttd_main(int argc, char* argv[])
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);
diff --git a/openttd.h b/openttd.h
index a44ccdc95..317acd03f 100644
--- a/openttd.h
+++ b/openttd.h
@@ -517,8 +517,9 @@ enum SpecialStrings {
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);
diff --git a/player_gui.c b/player_gui.c
index 6359d97e6..d58eb0360 100644
--- a/player_gui.c
+++ b/player_gui.c
@@ -614,11 +614,9 @@ static void PlayerCompanyWndProc(Window *w, WindowEvent *e)
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;
diff --git a/settings_gui.c b/settings_gui.c
index b9a0e0037..c2e7944ae 100644
--- a/settings_gui.c
+++ b/settings_gui.c
@@ -1384,21 +1384,21 @@ static void CustCurrencyWndProc(Window *w, WindowEvent *e)
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 @@ static void CustCurrencyWndProc(Window *w, WindowEvent *e)
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;
diff --git a/strings.c b/strings.c
index c50933321..f91d17e1a 100644
--- a/strings.c
+++ b/strings.c
@@ -125,6 +125,17 @@ static const StringID _cargo_string_list[NUM_LANDSCAPE][NUM_CARGO] = {
};
+#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 @@ char *GetString(char *buffr, StringID string)
case 0x30D1:
return StationGetSpecialString(buffr);
-
- case STR_SPEC_SCREENSHOT_NAME:
- return DecodeString(buffr, _screenshot_name);
}
switch (tab) {
@@ -160,7 +168,11 @@ char *GetString(char *buffr, StringID string)
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 @@ char *GetString(char *buffr, StringID string)
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));
diff --git a/variables.h b/variables.h
index 3514ad54f..985390095 100644
--- a/variables.h
+++ b/variables.h
@@ -424,6 +424,16 @@ static inline uint32 GetDParam(uint n)
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))