summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile1
-rw-r--r--functions.h1
-rw-r--r--gui.h1
-rw-r--r--main_gui.c16
-rw-r--r--misc.c2
-rw-r--r--misc_cmd.c119
-rw-r--r--oldloader.c15
-rw-r--r--signs.c233
-rw-r--r--signs.h33
-rw-r--r--terraform_gui.c2
-rw-r--r--tree_cmd.c1
-rw-r--r--ttd.c6
-rw-r--r--ttd.dsp8
-rw-r--r--ttd.h9
-rw-r--r--ttd.vcproj6
-rw-r--r--variables.h3
-rw-r--r--viewport.c13
17 files changed, 309 insertions, 160 deletions
diff --git a/Makefile b/Makefile
index 8e98f1c88..8d20ada64 100644
--- a/Makefile
+++ b/Makefile
@@ -613,6 +613,7 @@ C_SOURCES += settings.c
C_SOURCES += settings_gui.c
C_SOURCES += ship_cmd.c
C_SOURCES += ship_gui.c
+C_SOURCES += signs.c
C_SOURCES += smallmap_gui.c
C_SOURCES += sound.c
C_SOURCES += sprite.c
diff --git a/functions.h b/functions.h
index 0d20611fc..437bf6c04 100644
--- a/functions.h
+++ b/functions.h
@@ -232,7 +232,6 @@ void ShowNetworkChatQueryWindow(byte desttype, byte dest);
void ShowNetworkGiveMoneyWindow(byte player);
void ShowNetworkNeedGamePassword();
void ShowNetworkNeedCompanyPassword();
-void ShowRenameSignWindow(SignStruct *ss);
void ShowRenameWaypointWindow(Waypoint *cp);
int FindFirstBit(uint32 x);
void ShowHighscoreTable(int difficulty, int rank);
diff --git a/gui.h b/gui.h
index 0d2c8dda8..8a5bbf13f 100644
--- a/gui.h
+++ b/gui.h
@@ -6,7 +6,6 @@
/* main_gui.c */
void SetupColorsAndInitialWindow();
void CcPlaySound10(bool success, uint tile, uint32 p1, uint32 p2);
-void PlaceProc_Sign(uint tile);
/* settings_gui.c */
void ShowGameOptions();
diff --git a/main_gui.c b/main_gui.c
index 77c9d680e..1df9bcdae 100644
--- a/main_gui.c
+++ b/main_gui.c
@@ -14,6 +14,7 @@
#include "console.h"
#include "sound.h"
#include "network.h"
+#include "signs.h"
#ifdef ENABLE_NETWORK
#include "network_data.h"
@@ -370,7 +371,7 @@ void ShowNetworkNeedCompanyPassword()
void ShowRenameSignWindow(SignStruct *ss)
{
- _rename_id = ss - _sign_list;
+ _rename_id = ss->index;
_rename_what = 0;
ShowQueryString(ss->str, STR_280B_EDIT_SIGN_TEXT, 30, 180, 1, 0);
}
@@ -392,19 +393,6 @@ void ShowRenameWaypointWindow(Waypoint *cp)
ShowQueryString(STR_WAYPOINT_RAW, STR_EDIT_WAYPOINT_NAME, 30, 180, 1, 0);
}
-void CcPlaceSign(bool success, uint tile, uint32 p1, uint32 p2)
-{
- if (success) {
- ShowRenameSignWindow(_new_sign_struct);
- ResetObjectToPlace();
- }
-}
-
-void PlaceProc_Sign(uint tile)
-{
- DoCommandP(tile, 0, 0, CcPlaceSign, CMD_PLACE_SIGN | CMD_MSG(STR_2809_CAN_T_PLACE_SIGN_HERE));
-}
-
static void SelectSignTool()
{
if (_cursor.sprite == 0x2D2)
diff --git a/misc.c b/misc.c
index b000421b4..cb84f3ac7 100644
--- a/misc.c
+++ b/misc.c
@@ -162,6 +162,7 @@ void InitializeIndustries();
void InitializeLandscape();
void InitializeTowns();
void InitializeTrees();
+void InitializeSigns();
void InitializeStations();
static void InitializeNameMgr();
void InitializePlayers();
@@ -220,6 +221,7 @@ void InitializeGame()
InitializeDockGui();
InitializeTowns();
InitializeTrees();
+ InitializeSigns();
InitializeStations();
InitializeIndustries();
diff --git a/misc_cmd.c b/misc_cmd.c
index 714a22b5e..6d26c1d5c 100644
--- a/misc_cmd.c
+++ b/misc_cmd.c
@@ -172,89 +172,6 @@ int32 CmdChangePresidentName(int x, int y, uint32 flags, uint32 p1, uint32 p2)
return 0;
}
-static void UpdateSignVirtCoords(SignStruct *ss)
-{
- Point pt = RemapCoords(ss->x, ss->y, ss->z);
- SetDParam(0, ss->str);
- UpdateViewportSignPos(&ss->sign, pt.x, pt.y - 6, STR_2806);
-}
-
-void UpdateAllSignVirtCoords()
-{
- SignStruct *ss;
- for(ss=_sign_list; ss != endof(_sign_list); ss++)
- if (ss->str != 0)
- UpdateSignVirtCoords(ss);
-
-}
-
-static void MarkSignDirty(SignStruct *ss)
-{
- MarkAllViewportsDirty(
- ss->sign.left-6,
- ss->sign.top-3,
- ss->sign.left+ss->sign.width_1*4+12,
- ss->sign.top + 45
- );
-}
-
-
-int32 CmdPlaceSign(int x, int y, uint32 flags, uint32 p1, uint32 p2)
-{
- SignStruct *ss;
-
- for(ss=_sign_list; ss != endof(_sign_list); ss++) {
- if (ss->str == 0) {
- if (flags & DC_EXEC) {
- ss->str = STR_280A_SIGN;
- ss->x = x;
- ss->y = y;
- ss->z = GetSlopeZ(x,y);
- UpdateSignVirtCoords(ss);
- MarkSignDirty(ss);
- _new_sign_struct = ss;
- }
- return 0;
- }
- }
-
- return_cmd_error(STR_2808_TOO_MANY_SIGNS);
-}
-
-// p1 = sign index
-// p2: 1 -> remove sign
-int32 CmdRenameSign(int x, int y, uint32 flags, uint32 p1, uint32 p2)
-{
- StringID str,old_str;
- SignStruct *ss;
-
- if (_decode_parameters[0] != 0 && !p2) {
- str = AllocateNameUnique((byte*)_decode_parameters, 0);
- if (str == 0)
- return CMD_ERROR;
-
- if (flags & DC_EXEC) {
- ss = &_sign_list[p1];
- MarkSignDirty(ss);
- DeleteName(ss->str);
- ss->str = str;
- UpdateSignVirtCoords(ss);
- MarkSignDirty(ss);
- } else {
- DeleteName(str);
- }
- } else {
- if (flags & DC_EXEC) {
- ss = &_sign_list[p1];
- old_str = ss->str;
- ss->str = 0;
- DeleteName(old_str);
- MarkSignDirty(ss);
- }
- }
- return 0;
-}
-
// p1 = 0 decrease pause counter
// p1 = 1 increase pause counter
int32 CmdPause(int x, int y, uint32 flags, uint32 p1, uint32 p2)
@@ -318,39 +235,3 @@ int32 CmdChangeDifficultyLevel(int x, int y, uint32 flags, uint32 p1, uint32 p2)
}
return 0;
}
-
-static const byte _sign_desc[] = {
- SLE_VAR(SignStruct,str, SLE_UINT16),
- SLE_CONDVAR(SignStruct,x, SLE_FILE_I16 | SLE_VAR_I32, 0, 4),
- SLE_CONDVAR(SignStruct,y, SLE_FILE_I16 | SLE_VAR_I32, 0, 4),
- SLE_CONDVAR(SignStruct,x, SLE_INT32, 5, 255),
- SLE_CONDVAR(SignStruct,y, SLE_INT32, 5, 255),
- SLE_VAR(SignStruct,z, SLE_UINT8),
- SLE_END()
-};
-
-static void Save_SIGN()
-{
- SignStruct *s;
- int i;
- for(i=0,s=_sign_list; i!=lengthof(_sign_list); i++,s++) {
- if (s->str != 0) {
- SlSetArrayIndex(i);
- SlObject(s, _sign_desc);
- }
- }
-}
-
-static void Load_SIGN()
-{
- int index;
- while ((index = SlIterateArray()) != -1) {
- SlObject(&_sign_list[index], _sign_desc);
- }
-}
-
-const ChunkHandler _sign_chunk_handlers[] = {
- { 'SIGN', Save_SIGN, Load_SIGN, CH_ARRAY | CH_LAST},
-};
-
-
diff --git a/oldloader.c b/oldloader.c
index 459fc8ee9..cdeafa622 100644
--- a/oldloader.c
+++ b/oldloader.c
@@ -9,6 +9,7 @@
#include "player.h"
#include "engine.h"
#include "vehicle.h"
+#include "signs.h"
extern byte _name_array[512][32];
extern TileIndex _animated_tile_list[256];
@@ -1027,14 +1028,22 @@ static void FixName(OldName *o, int num)
}
}
-static void FixSign(SignStruct *n, OldSign *o, int num)
+static void FixSign(OldSign *o, int num)
{
+ SignStruct *n;
+ uint i = 0;
+
do {
+ if (o->text == 0)
+ continue;
+
+ n = GetSign(i);
+
n->str = o->text;
n->x = o->x;
n->y = o->y;
n->z = o->z;
- } while (n++,o++,--num);
+ } while (i++,o++,--num);
}
static void FixEngine(Engine *n, OldEngine *o, int num)
@@ -1452,7 +1461,7 @@ bool LoadOldSaveGame(const char *file)
FixPlayer(_players, m->players, lengthof(m->players), m->town_name_type);
FixName(m->names, lengthof(m->names));
- FixSign(_sign_list, m->signs, lengthof(m->signs));
+ FixSign(m->signs, lengthof(m->signs));
FixEngine(_engines, m->engines, lengthof(m->engines));
_opt.diff_level = m->difficulty_level;
diff --git a/signs.c b/signs.c
new file mode 100644
index 000000000..a3228ddcf
--- /dev/null
+++ b/signs.c
@@ -0,0 +1,233 @@
+#include "stdafx.h"
+#include "ttd.h"
+#include "table/strings.h"
+#include "signs.h"
+#include "saveload.h"
+#include "command.h"
+
+/**
+ *
+ * Update the coordinate of one sign
+ *
+ */
+static void UpdateSignVirtCoords(SignStruct *ss)
+{
+ Point pt = RemapCoords(ss->x, ss->y, ss->z);
+ SetDParam(0, ss->str);
+ UpdateViewportSignPos(&ss->sign, pt.x, pt.y - 6, STR_2806);
+}
+
+/**
+ *
+ * Update all coordinates of a sign
+ *
+ */
+void UpdateAllSignVirtCoords()
+{
+ SignStruct *ss;
+
+ FOR_ALL_SIGNS(ss)
+ if (ss->str != 0)
+ UpdateSignVirtCoords(ss);
+
+}
+
+/**
+ *
+ * Marks the region of a sign as dirty
+ *
+ * @param ss Pointer to the SignStruct
+ */
+static void MarkSignDirty(SignStruct *ss)
+{
+ MarkAllViewportsDirty(
+ ss->sign.left - 6,
+ ss->sign.top - 3,
+ ss->sign.left + ss->sign.width_1 * 4 + 12,
+ ss->sign.top + 45);
+}
+
+/**
+ *
+ * Allocates a new sign
+ *
+ * @return The pointer to the new sign, or NULL if there is no more free space
+ */
+static SignStruct *AllocateSign()
+{
+ SignStruct *s;
+ FOR_ALL_SIGNS(s)
+ if (s->str == 0)
+ return s;
+
+ return NULL;
+}
+
+/**
+ *
+ * Place a sign at the giving x/y
+ *
+ * @param p1 not used
+ * @param p2 not used
+ */
+int32 CmdPlaceSign(int x, int y, uint32 flags, uint32 p1, uint32 p2)
+{
+ SignStruct *ss;
+
+ /* Try to locate a new sign */
+ ss = AllocateSign();
+ if (ss == NULL)
+ return_cmd_error(STR_2808_TOO_MANY_SIGNS);
+
+ /* When we execute, really make the sign */
+ if (flags & DC_EXEC) {
+ ss->str = STR_280A_SIGN;
+ ss->x = x;
+ ss->y = y;
+ ss->z = GetSlopeZ(x,y);
+ UpdateSignVirtCoords(ss);
+ MarkSignDirty(ss);
+ _new_sign_struct = ss;
+ }
+
+ return 0;
+}
+
+/**
+ * Rename a sign
+ *
+ * @param sign_id Index of the sign
+ * @param remove If 1, sign will be removed
+ */
+int32 CmdRenameSign(int x, int y, uint32 flags, uint32 sign_id, uint32 remove)
+{
+ StringID str;
+ SignStruct *ss;
+
+ /* If GetDParam(0) == nothing, we delete the sign */
+ if (GetDParam(0) != 0 && remove != 1) {
+ /* Create the name */
+ str = AllocateName((byte*)_decode_parameters, 0);
+ if (str == 0)
+ return CMD_ERROR;
+
+ if (flags & DC_EXEC) {
+ ss = GetSign(sign_id);
+
+ MarkSignDirty(ss);
+
+ /* Delete the old name */
+ DeleteName(ss->str);
+ /* Assign the new one */
+ ss->str = str;
+
+ /* Update */
+ UpdateSignVirtCoords(ss);
+ MarkSignDirty(ss);
+ } else {
+ /* Free the name, because we did not assign it yet */
+ DeleteName(str);
+ }
+ } else {
+ /* Delete sign */
+ if (flags & DC_EXEC) {
+ ss = GetSign(sign_id);
+
+ /* Delete the name */
+ DeleteName(ss->str);
+ ss->str = 0;
+
+ MarkSignDirty(ss);
+ }
+ }
+
+ return 0;
+}
+
+/**
+ *
+ * Callback function that is called after a sign is placed
+ *
+ */
+void CcPlaceSign(bool success, uint tile, uint32 p1, uint32 p2)
+{
+ if (success) {
+ ShowRenameSignWindow(_new_sign_struct);
+ ResetObjectToPlace();
+ }
+}
+
+/**
+ *
+ * PlaceProc function, called when someone pressed the button if the
+ * sign-tool is selected
+ *
+ */
+void PlaceProc_Sign(uint tile)
+{
+ DoCommandP(tile, 0, 0, CcPlaceSign, CMD_PLACE_SIGN | CMD_MSG(STR_2809_CAN_T_PLACE_SIGN_HERE));
+}
+
+/**
+ *
+ * Initialize the signs
+ *
+ */
+void InitializeSigns()
+{
+ SignStruct *s;
+ int i;
+
+ memset(_sign_list, 0, sizeof(_sign_list[0]) * _sign_size);
+
+ i = 0;
+ FOR_ALL_SIGNS(s)
+ s->index = i++;
+}
+
+static const byte _sign_desc[] = {
+ SLE_VAR(SignStruct,str, SLE_UINT16),
+ SLE_CONDVAR(SignStruct,x, SLE_FILE_I16 | SLE_VAR_I32, 0, 4),
+ SLE_CONDVAR(SignStruct,y, SLE_FILE_I16 | SLE_VAR_I32, 0, 4),
+ SLE_CONDVAR(SignStruct,x, SLE_INT32, 5, 255),
+ SLE_CONDVAR(SignStruct,y, SLE_INT32, 5, 255),
+ SLE_VAR(SignStruct,z, SLE_UINT8),
+ SLE_END()
+};
+
+/**
+ *
+ * Save all signs
+ *
+ */
+static void Save_SIGN()
+{
+ SignStruct *s;
+
+ FOR_ALL_SIGNS(s) {
+ /* Don't save empty signs */
+ if (s->str != 0) {
+ SlSetArrayIndex(s->index);
+ SlObject(s, _sign_desc);
+ }
+ }
+}
+
+/**
+ *
+ * Load all signs
+ *
+ */
+static void Load_SIGN()
+{
+ int index;
+ while ((index = SlIterateArray()) != -1) {
+ SignStruct *s = GetSign(index);
+
+ SlObject(s, _sign_desc);
+ }
+}
+
+const ChunkHandler _sign_chunk_handlers[] = {
+ { 'SIGN', Save_SIGN, Load_SIGN, CH_ARRAY | CH_LAST},
+};
diff --git a/signs.h b/signs.h
new file mode 100644
index 000000000..4fffbb7b2
--- /dev/null
+++ b/signs.h
@@ -0,0 +1,33 @@
+#ifndef SIGNS_H
+#define SIGNS_H
+
+typedef struct SignStruct {
+ StringID str;
+ ViewportSign sign;
+ int32 x;
+ int32 y;
+ byte z;
+
+ uint16 index;
+} SignStruct;
+
+VARDEF SignStruct _sign_list[40];
+VARDEF uint _sign_size;
+
+static inline SignStruct *GetSign(uint index)
+{
+ assert(index < _sign_size);
+ return &_sign_list[index];
+}
+
+#define FOR_ALL_SIGNS(s) for(s = _sign_list; s != &_sign_list[_sign_size]; s++)
+
+VARDEF SignStruct *_new_sign_struct;
+
+void UpdateAllSignVirtCoords();
+void PlaceProc_Sign(uint tile);
+
+/* misc.c */
+void ShowRenameSignWindow(SignStruct *ss);
+
+#endif /* SIGNS_H */
diff --git a/terraform_gui.c b/terraform_gui.c
index 4186d9dcc..8d3d4ad57 100644
--- a/terraform_gui.c
+++ b/terraform_gui.c
@@ -8,7 +8,7 @@
#include "sound.h"
#include "command.h"
#include "vehicle.h"
-
+#include "signs.h"
void CcTerraform(bool success, uint tile, uint32 p1, uint32 p2)
{
diff --git a/tree_cmd.c b/tree_cmd.c
index d3a88aa07..fca9f1ef6 100644
--- a/tree_cmd.c
+++ b/tree_cmd.c
@@ -641,7 +641,6 @@ static void ChangeTileOwner_Trees(uint tile, byte old_player, byte new_player)
void InitializeTrees()
{
- memset(_sign_list, 0, sizeof(_sign_list));
_trees_tick_ctr = 0;
}
diff --git a/ttd.c b/ttd.c
index 24eb645fa..d90a66aec 100644
--- a/ttd.c
+++ b/ttd.c
@@ -26,6 +26,7 @@
#include "console.h"
#include "screenshot.h"
#include "network.h"
+#include "signs.h"
#include <stdarg.h>
@@ -44,7 +45,6 @@ void DeleteAllPlayerStations();
extern void SetDifficultyLevel(int mode, GameOptions *gm_opt);
extern void DoStartupNewPlayer(bool is_ai);
-extern void UpdateAllSignVirtCoords();
extern void ShowOSErrorBox(const char *buf);
void redsq_debug(int tile);
@@ -496,6 +496,8 @@ static void InitializeDynamicVariables(void)
_industries_size = lengthof(_industries);
_industry_sort = NULL;
+
+ _sign_size = lengthof(_sign_list);
}
static void UnInitializeDynamicVariables(void)
@@ -1263,7 +1265,7 @@ bool AfterLoadGame(uint version)
{
Window *w;
ViewPort *vp;
-
+
// in version 2.1 of the savegame, town owner was unified.
if (version <= 0x200) {
ConvertTownOwner();
diff --git a/ttd.dsp b/ttd.dsp
index 37bb0b65c..02681a03f 100644
--- a/ttd.dsp
+++ b/ttd.dsp
@@ -297,6 +297,10 @@ SOURCE=.\settings.c
# End Source File
# Begin Source File
+SOURCE=.\signs.c
+# End Source File
+
+# Begin Source File
SOURCE=.\sound.c
# End Source File
@@ -510,6 +514,10 @@ SOURCE=.\saveload.h
# End Source File
# Begin Source File
+SOURCE=.\signs.h
+# End Source File
+
+# Begin Source File
SOURCE=.\sound.h
# End Source File
diff --git a/ttd.h b/ttd.h
index 30be8623d..e6f9c4bd1 100644
--- a/ttd.h
+++ b/ttd.h
@@ -285,15 +285,6 @@ typedef struct {
byte width_1, width_2;
} ViewportSign;
-typedef struct SignStruct {
- StringID str;
- ViewportSign sign;
- int32 x;
- int32 y;
- byte z;
-} SignStruct;
-
-
typedef int32 CommandProc(int x, int y, uint32 flags, uint32 p1, uint32 p2);
typedef void DrawTileProc(TileInfo *ti);
diff --git a/ttd.vcproj b/ttd.vcproj
index 5050af342..2dad3071b 100644
--- a/ttd.vcproj
+++ b/ttd.vcproj
@@ -753,6 +753,9 @@
RelativePath=".\settings.c">
</File>
<File
+ RelativePath=".\signs.c">
+ </File>
+ <File
RelativePath="sound.c">
<FileConfiguration
Name="Release|Win32">
@@ -1219,6 +1222,9 @@
RelativePath=".\screenshot.h">
</File>
<File
+ RelativePath=".\signs.h">
+ </File>
+ <File
RelativePath="sound.h">
</File>
<File
diff --git a/variables.h b/variables.h
index 2d3834315..78ac26144 100644
--- a/variables.h
+++ b/variables.h
@@ -425,9 +425,6 @@ VARDEF char _screenshot_name[128];
VARDEF char _userstring[USERSTRING_LEN];
VARDEF byte _vehicle_design_names;
-VARDEF SignStruct _sign_list[40];
-VARDEF SignStruct *_new_sign_struct;
-
/* tunnelbridge */
#define MAX_BRIDGES 13
diff --git a/viewport.c b/viewport.c
index a7f9ef776..005379ef1 100644
--- a/viewport.c
+++ b/viewport.c
@@ -8,6 +8,7 @@
#include "station.h"
#include "gfx.h"
#include "town.h"
+#include "signs.h"
#define VIEWPORT_DRAW_MEM (65536 * 2)
@@ -885,7 +886,7 @@ static void ViewportAddSigns(DrawPixelInfo *dpi)
bottom = top + dpi->height;
if (dpi->zoom < 1) {
- for(ss=_sign_list; ss != endof(_sign_list); ss++) {
+ FOR_ALL_SIGNS(ss) {
if (ss->str &&
bottom > ss->sign.top &&
top < ss->sign.top + 12 &&
@@ -902,7 +903,7 @@ static void ViewportAddSigns(DrawPixelInfo *dpi)
} else if (dpi->zoom == 1) {
right += 2;
bottom += 2;
- for(ss=_sign_list; ss != endof(_sign_list); ss++) {
+ FOR_ALL_SIGNS(ss) {
if (ss->str &&
bottom > ss->sign.top &&
top < ss->sign.top + 24 &&
@@ -920,7 +921,7 @@ static void ViewportAddSigns(DrawPixelInfo *dpi)
right += 4;
bottom += 5;
- for(ss=_sign_list; ss != endof(_sign_list); ss++) {
+ FOR_ALL_SIGNS(ss) {
if (ss->str &&
bottom > ss->sign.top &&
top < ss->sign.top + 24 &&
@@ -1541,7 +1542,7 @@ static bool CheckClickOnSign(ViewPort *vp, int x, int y)
x = x - vp->left + vp->virtual_left;
y = y - vp->top + vp->virtual_top;
- for(ss = _sign_list; ss != endof(_sign_list); ss++) {
+ FOR_ALL_SIGNS(ss) {
if (ss->str &&
y >= ss->sign.top &&
y < ss->sign.top + 12 &&
@@ -1554,7 +1555,7 @@ static bool CheckClickOnSign(ViewPort *vp, int x, int y)
} else if (vp->zoom == 1) {
x = (x - vp->left + 1) * 2 + vp->virtual_left;
y = (y - vp->top + 1) * 2 + vp->virtual_top;
- for(ss = _sign_list; ss != endof(_sign_list); ss++) {
+ FOR_ALL_SIGNS(ss) {
if (ss->str &&
y >= ss->sign.top &&
y < ss->sign.top + 24 &&
@@ -1567,7 +1568,7 @@ static bool CheckClickOnSign(ViewPort *vp, int x, int y)
} else {
x = (x - vp->left + 3) * 4 + vp->virtual_left;
y = (y - vp->top + 3) * 4 + vp->virtual_top;
- for(ss = _sign_list; ss != endof(_sign_list); ss++) {
+ FOR_ALL_SIGNS(ss) {
if (ss->str &&
y >= ss->sign.top &&
y < ss->sign.top + 24 &&