summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpeter1138 <peter1138@openttd.org>2005-11-12 00:19:34 +0000
committerpeter1138 <peter1138@openttd.org>2005-11-12 00:19:34 +0000
commitff8223150aa28b1dfec8d1697d27d6aa96c18f93 (patch)
treee5f727d749b6f788bedbdaeef17fab347dbfefbb
parentb1075ca7a43ea39cddf4ec4406f99bb5aa37a113 (diff)
downloadopenttd-ff8223150aa28b1dfec8d1697d27d6aa96c18f93.tar.xz
(svn r3167) - NewGRF: Start moving custom station code to separate files.
Rewrite handling of station classes. Allow for more than 8 station tile layouts. Start of code to unload custom stations.
-rw-r--r--Makefile1
-rw-r--r--newgrf.c73
-rw-r--r--newgrf.h1
-rw-r--r--rail_gui.c18
-rw-r--r--station.h74
-rw-r--r--station_cmd.c62
-rw-r--r--station_newgrf.c115
-rw-r--r--station_newgrf.h77
-rw-r--r--waypoint.c16
-rw-r--r--waypoint.h1
10 files changed, 259 insertions, 179 deletions
diff --git a/Makefile b/Makefile
index f038127b3..8036237c2 100644
--- a/Makefile
+++ b/Makefile
@@ -659,6 +659,7 @@ C_SOURCES += sprite.c
C_SOURCES += spritecache.c
C_SOURCES += station_cmd.c
C_SOURCES += station_gui.c
+C_SOURCES += station_newgrf.c
C_SOURCES += string.c
C_SOURCES += strings.c
C_SOURCES += subsidy_gui.c
diff --git a/newgrf.c b/newgrf.c
index f66cec1f5..0d0ed95cd 100644
--- a/newgrf.c
+++ b/newgrf.c
@@ -800,22 +800,7 @@ static bool StationChangeInfo(uint stid, int numinfo, int prop, byte **bufp, int
classid |= *(buf++) << 8;
classid |= *(buf++);
- switch (classid) {
- case 'DFLT':
- stat->sclass = STAT_CLASS_DFLT;
- break;
- case 'WAYP':
- stat->sclass = STAT_CLASS_WAYP;
- break;
- default:
- /* TODO: No support for custom
- * classes for now, so stuff
- * everything to the single
- * default one. --pasky */
- stat->sclass = STAT_CLASS_DFLT;
- //stat->sclass = STAT_CLASS_CUSTOM;
- break;
- }
+ stat->sclass = AllocateStationClass(classid);
}
break;
}
@@ -825,24 +810,28 @@ static bool StationChangeInfo(uint stid, int numinfo, int prop, byte **bufp, int
StationSpec *stat = &_cur_grffile->stations[stid + i];
int t;
- stat->tiles = grf_load_byte(&buf);
+ stat->tiles = grf_load_extended(&buf);
+ stat->renderdata = calloc(stat->tiles, sizeof(*stat->renderdata));
for (t = 0; t < stat->tiles; t++) {
DrawTileSprites *dts = &stat->renderdata[t];
int seq_count = 0;
+ PalSpriteID ground_sprite;
- if (t >= 8) {
- grfmsg(GMS_WARN, "StationChangeInfo: Sprite %d>=8, skipping.", t);
- grf_load_dword(&buf); // at least something
- continue;
- }
-
- dts->ground_sprite = grf_load_dword(&buf);
- if (!dts->ground_sprite) {
+ ground_sprite = grf_load_dword(&buf);
+ if (ground_sprite == 0) {
static const DrawTileSeqStruct empty = {0x80, 0, 0, 0, 0, 0, 0};
dts->seq = &empty;
continue;
}
+ if (HASBIT(ground_sprite, 31)) {
+ // Bit 31 indicates that we should use a custom sprite.
+ dts->ground_sprite = GB(ground_sprite, 0, 15) - 0x42D;
+ dts->ground_sprite += _cur_grffile->first_spriteset;
+ } else {
+ dts->ground_sprite = ground_sprite;
+ }
+
dts->seq = NULL;
while (buf < *bufp + len) {
DrawTileSeqStruct *dtss;
@@ -873,6 +862,7 @@ static bool StationChangeInfo(uint stid, int numinfo, int prop, byte **bufp, int
int t;
stat->tiles = srcstat->tiles;
+ stat->renderdata = calloc(stat->tiles, sizeof(*stat->renderdata));
for (t = 0; t < stat->tiles; t++) {
DrawTileSprites *dts = &stat->renderdata[t];
const DrawTileSprites *sdts = &srcstat->renderdata[t];
@@ -1548,6 +1538,9 @@ static void NewSpriteGroup(byte *buf, int len)
loaded_ptr = buf;
loading_ptr = buf + 2 * numloaded;
+ if (_cur_grffile->first_spriteset == 0)
+ _cur_grffile->first_spriteset = _cur_grffile->spriteset_start;
+
if (numloaded > 16) {
grfmsg(GMS_WARN, "NewSpriteGroup: More than 16 sprites in group %x, skipping the rest.", setid);
numloaded = 16;
@@ -1688,8 +1681,8 @@ static void NewVehicle_SpriteGroupMapping(byte *buf, int len)
stat->spritegroup[0] = _cur_grffile->spritegroups[groupid];
stat->spritegroup[0]->ref_count++;
stat->grfid = _cur_grffile->grfid;
- SetCustomStation(stid, stat);
- stat->sclass = STAT_CLASS_NONE;
+ stat->localidx = stid;
+ SetCustomStation(stat);
}
}
return;
@@ -2396,6 +2389,28 @@ static void ReleaseSpriteGroups(GRFFile *file)
file->spritegroups_count = 0;
}
+static void ResetCustomStations(void)
+{
+ GRFFile *file;
+ int i;
+ CargoID c;
+
+ for (file = _first_grffile; file != NULL; file = file->next) {
+ for (i = 0; i < 256; i++) {
+ if (file->stations[i].grfid != file->grfid)
+ continue;
+
+ // TODO: Release renderdata, platforms and layouts
+
+ // Release this stations sprite groups.
+ for (c = 0; c < NUM_GLOBAL_CID; c++) {
+ if (file->stations[i].spritegroup[c] != NULL)
+ UnloadSpriteGroup(&file->stations[i].spritegroup[c]);
+ }
+ }
+ }
+}
+
/**
* Reset all NewGRF loaded data
* TODO
@@ -2433,6 +2448,10 @@ static void ResetNewGRFData(void)
// Reset price base data
ResetPriceBaseMultipliers();
+
+ // Reset station classes
+ ResetStationClasses();
+ ResetCustomStations();
}
static void InitNewGRFFile(const char* filename, int sprite_offset)
diff --git a/newgrf.h b/newgrf.h
index 5abc5c95f..50b9ba462 100644
--- a/newgrf.h
+++ b/newgrf.h
@@ -12,6 +12,7 @@ struct GRFFile {
uint32 grfid;
uint16 flags;
uint16 sprite_offset;
+ SpriteID first_spriteset; ///< Holds the first spriteset's sprite offset.
GRFFile *next;
/* A sprite group contains all sprites of a given vehicle (or multiple
diff --git a/rail_gui.c b/rail_gui.c
index 8fee0cfbd..668e797ff 100644
--- a/rail_gui.c
+++ b/rail_gui.c
@@ -127,7 +127,7 @@ static void PlaceRail_Depot(TileIndex tile)
static void PlaceRail_Waypoint(TileIndex tile)
{
if (!_remove_button_clicked) {
- DoCommandP(tile, (_waypoint_count > 0) ? (0x100 + _cur_waypoint_type) : 0, 0, CcPlaySound1E, CMD_BUILD_TRAIN_WAYPOINT | CMD_MSG(STR_CANT_BUILD_TRAIN_WAYPOINT));
+ DoCommandP(tile, _cur_waypoint_type, 0, CcPlaySound1E, CMD_BUILD_TRAIN_WAYPOINT | CMD_MSG(STR_CANT_BUILD_TRAIN_WAYPOINT));
} else {
DoCommandP(tile, 0, 0, CcPlaySound1E, CMD_REMOVE_TRAIN_WAYPOINT | CMD_MSG(STR_CANT_REMOVE_TRAIN_WAYPOINT));
}
@@ -257,9 +257,9 @@ static void BuildRailClick_Depot(Window *w)
static void BuildRailClick_Waypoint(Window *w)
{
- _waypoint_count = GetCustomStationsCount(STAT_CLASS_WAYP);
+ _waypoint_count = GetNumCustomStations(STAT_CLASS_WAYP);
if (HandlePlacePushButton(w, 11, SPR_CURSOR_WAYPOINT, 1, PlaceRail_Waypoint)
- && _waypoint_count > 0)
+ && _waypoint_count > 1)
ShowBuildWaypointPicker();
}
@@ -829,14 +829,14 @@ static void BuildWaypointWndProc(Window *w, WindowEvent *e)
{
switch (e->event) {
case WE_PAINT: {
+ int i;
w->click_state = (1 << 3) << (_cur_waypoint_type - w->hscroll.pos);
DrawWindowWidgets(w);
- if(w->hscroll.pos + 0 <= _waypoint_count) DrawWaypointSprite(2, 25, w->hscroll.pos + 0, _cur_railtype);
- if(w->hscroll.pos + 1 <= _waypoint_count) DrawWaypointSprite(70, 25, w->hscroll.pos + 1, _cur_railtype);
- if(w->hscroll.pos + 2 <= _waypoint_count) DrawWaypointSprite(138, 25, w->hscroll.pos + 2, _cur_railtype);
- if(w->hscroll.pos + 3 <= _waypoint_count) DrawWaypointSprite(206, 25, w->hscroll.pos + 3, _cur_railtype);
- if(w->hscroll.pos + 4 <= _waypoint_count) DrawWaypointSprite(274, 25, w->hscroll.pos + 4, _cur_railtype);
+ for (i = 0; i < 5; i++)
+ if(w->hscroll.pos + i < _waypoint_count)
+ DrawWaypointSprite(2 + i * 68, 25, w->hscroll.pos + i, _cur_railtype);
+
break;
}
case WE_CLICK: {
@@ -889,7 +889,7 @@ static void ShowBuildWaypointPicker(void)
{
Window *w = AllocateWindowDesc(&_build_waypoint_desc);
w->hscroll.cap = 5;
- w->hscroll.count = _waypoint_count + 1;
+ w->hscroll.count = _waypoint_count;
}
diff --git a/station.h b/station.h
index 45f88fa9c..6fa329292 100644
--- a/station.h
+++ b/station.h
@@ -8,6 +8,7 @@
#include "sprite.h"
#include "tile.h"
#include "vehicle.h"
+#include "station_newgrf.h"
typedef struct GoodsEntry {
uint16 waiting_acceptance;
@@ -195,83 +196,10 @@ uint GetStationPlatforms(const Station *st, TileIndex tile);
void StationPickerDrawSprite(int x, int y, RailType railtype, int image);
-
-/* Station layout for given dimensions - it is a two-dimensional array
- * where index is computed as (x * platforms) + platform. */
-typedef byte *StationLayout;
-
-typedef enum StationClass {
- STAT_CLASS_NONE, // unused station slot or so
- STAT_CLASS_DFLT, // default station class
- STAT_CLASS_WAYP, // waypoints
-
- /* TODO: When we actually support custom classes, they are
- * going to be allocated dynamically (with some classid->sclass
- * mapping, there's a TTDPatch limit on 16 custom classes in
- * the whole game at the same time) with base at
- * STAT_CLASS_CUSTOM. --pasky */
- STAT_CLASS_CUSTOM, // some custom class
-} StationClass;
-
-typedef struct StationSpec {
- uint32 grfid;
- int localidx; // per-GRFFile station index + 1; SetCustomStation() takes care of this
-
- StationClass sclass;
-
- /* Bitmask of platform numbers/lengths available for the station. Bits
- * 0..6 correspond to 1..7, while bit 7 corresponds to >7 platforms or
- * lenght. */
- byte allowed_platforms;
- byte allowed_lengths;
-
- /* Custom sprites */
- byte tiles;
- /* 00 = plain platform
- * 02 = platform with building
- * 04 = platform with roof, left side
- * 06 = platform with roof, right side
- *
- * These numbers are used for stations in NE-SW direction, or these
- * numbers plus one for stations in the NW-SE direction. */
- DrawTileSprites renderdata[8];
-
- /* Custom layouts */
- /* The layout array is organized like [lenghts][platforms], both being
- * dynamic arrays, the field itself is length*platforms array containing
- * indexes to @renderdata (only even numbers allowed) for the given
- * station tile. */
- /* @lengths is length of the @platforms and @layouts arrays, that is
- * number of maximal length for which the layout is defined (since
- * arrays are indexed from 0, the length itself is at [length - 1]). */
- byte lengths;
- /* @platforms is array of number of platforms defined for each length.
- * Zero means no platforms defined. */
- byte *platforms;
- /* @layout is @layouts-sized array of @platforms-sized arrays,
- * containing pointers to length*platforms-sized arrays or NULL if
- * default OTTD station layout should be used for stations of these
- * dimensions. */
- StationLayout **layouts;
-
- /* Sprite offsets for renderdata->seq->image. spritegroup[0] is default
- * whilst spritegroup[1] is "GC_PURCHASE". */
- SpriteGroup *spritegroup[2];
-} StationSpec;
-
-/* Here, @stid is local per-GRFFile station index. If spec->localidx is not yet
- * set, it gets new dynamically allocated global index and spec->localidx is
- * set to @stid, otherwise we take it as that we are replacing it and try to
- * search for it first (that isn't much fast but we do it only very seldom). */
-void SetCustomStation(byte stid, StationSpec *spec);
-/* Here, @stid is global station index (in continous range 0..GetCustomStationsCount())
- * (lookup is therefore very fast as we do this very frequently). */
-StationSpec *GetCustomStation(StationClass sclass, byte stid);
/* Get sprite offset for a given custom station and station structure (may be
* NULL if ctype is set - that means we are in a build dialog). The station
* structure is used for variational sprite groups. */
uint32 GetCustomStationRelocation(const StationSpec *spec, const Station *st, byte ctype);
-int GetCustomStationsCount(StationClass sclass);
RoadStop * GetRoadStopByTile(TileIndex tile, RoadStopType type);
static inline int GetRoadStopType(TileIndex tile)
diff --git a/station_cmd.c b/station_cmd.c
index f46bd19a6..b0c88412c 100644
--- a/station_cmd.c
+++ b/station_cmd.c
@@ -1199,60 +1199,6 @@ uint GetStationPlatforms(const Station *st, TileIndex tile)
return len - 1;
}
-
-/* TODO: Custom classes! */
-/* Indexed by class, just STAT_CLASS_DFLT and STAT_CLASS_WAYP supported. */
-static int _statspec_highest_id[2] = {-1, -1};
-static StationSpec _station_spec[2][256];
-
-void SetCustomStation(byte local_stid, StationSpec *spec)
-{
- StationClass sclass;
- int stid = -1;
-
- assert(spec->sclass == STAT_CLASS_DFLT || spec->sclass == STAT_CLASS_WAYP);
- sclass = spec->sclass - 1;
-
- if (spec->localidx != 0) {
- /* Already allocated, try to resolve to global stid */
- int i;
-
- for (i = 0; i <= _statspec_highest_id[sclass]; i++) {
- if (_station_spec[sclass][i].grfid == spec->grfid &&
- _station_spec[sclass][i].localidx == local_stid + 1) {
- stid = i;
- /* FIXME: Release original SpriteGroup to
- * prevent leaks. But first we need to
- * refcount the SpriteGroup. --pasky */
- break;
- }
- }
- }
-
- if (stid == -1) {
- /* Allocate new one. */
- if (_statspec_highest_id[sclass] >= 255) {
- error("Too many custom stations allocated.");
- return;
- }
- stid = ++_statspec_highest_id[sclass];
- spec->localidx = local_stid + 1;
- }
-
- //debug("Registering station #%d of class %d", stid, sclass);
- memcpy(&_station_spec[sclass][stid], spec, sizeof(*spec));
-}
-
-StationSpec *GetCustomStation(StationClass sclass, byte stid)
-{
- assert(sclass == STAT_CLASS_DFLT || sclass == STAT_CLASS_WAYP);
- sclass--;
- //debug("Asking for station #%d of class %d", stid, sclass);
- if (stid > _statspec_highest_id[sclass])
- return NULL;
- return &_station_spec[sclass][stid];
-}
-
static const RealSpriteGroup *ResolveStationSpriteGroup(const SpriteGroup *spg, const Station *st)
{
switch (spg->type) {
@@ -1351,14 +1297,6 @@ uint32 GetCustomStationRelocation(const StationSpec *spec, const Station *st, by
return SPR_RAIL_PLATFORM_Y_FRONT;
}
-int GetCustomStationsCount(StationClass sclass)
-{
- assert(sclass == STAT_CLASS_DFLT || sclass == STAT_CLASS_WAYP);
- sclass--;
- return _statspec_highest_id[sclass] + 1;
-}
-
-
static int32 RemoveRailroadStation(Station *st, TileIndex tile, uint32 flags)
{
int w,h;
diff --git a/station_newgrf.c b/station_newgrf.c
new file mode 100644
index 000000000..1150a2376
--- /dev/null
+++ b/station_newgrf.c
@@ -0,0 +1,115 @@
+/* $Id$ */
+
+/** @file station_newgrf.c Functions for dealing with station classes and custom stations. */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "debug.h"
+#include "sprite.h"
+#include "station_newgrf.h"
+
+static StationClass station_classes[STAT_CLASS_MAX];
+
+/**
+ * Reset station classes to their default state.
+ * This includes initialising the Default and Waypoint classes with an empty
+ * entry, for standard stations and waypoints.
+ */
+void ResetStationClasses(void)
+{
+ StationClassID i;
+ for (i = 0; i < STAT_CLASS_MAX; i++) {
+ station_classes[i].id = 0;
+
+ free(station_classes[i].name);
+ station_classes[i].name = NULL;
+
+ station_classes[i].stations = 0;
+
+ free(station_classes[i].spec);
+ station_classes[i].spec = NULL;
+ }
+
+ // Set up initial data
+ station_classes[0].id = 'DFLT';
+ station_classes[0].name = strdup("Default");
+ station_classes[0].stations = 1;
+ station_classes[0].spec = malloc(sizeof(*station_classes[0].spec));
+ station_classes[0].spec[0] = NULL;
+
+ station_classes[1].id = 'WAYP';
+ station_classes[1].name = strdup("Waypoints");
+ station_classes[1].stations = 1;
+ station_classes[1].spec = malloc(sizeof(*station_classes[1].spec));
+ station_classes[1].spec[0] = NULL;
+}
+
+/**
+ * Allocate a station class for the given class id.
+ * @param classid A 32 bit value identifying the class.
+ * @return Index into station_classes of allocated class.
+ */
+StationClassID AllocateStationClass(uint32 class)
+{
+ StationClassID i;
+
+ for (i = 0; i < STAT_CLASS_MAX; i++) {
+ if (station_classes[i].id == class) {
+ // ClassID is already allocated, so reuse it.
+ return i;
+ } else if (station_classes[i].id == 0) {
+ // This class is empty, so allocate it to the ClassID.
+ station_classes[i].id = class;
+ return i;
+ }
+ }
+
+ DEBUG(grf, 2)("StationClassAllocate: Already allocated %d classes, using default.", STAT_CLASS_MAX);
+ return STAT_CLASS_DFLT;
+}
+
+/**
+ * Return the number of stations for the given station class.
+ * @param sclass Index of the station class.
+ * @return Number of stations in the class.
+ */
+uint GetNumCustomStations(StationClassID sclass)
+{
+ assert(sclass < STAT_CLASS_MAX);
+ return station_classes[sclass].stations;
+}
+
+/**
+ * Tie a station spec to its station class.
+ * @param spec The station spec.
+ */
+void SetCustomStation(StationSpec *spec)
+{
+ StationClass *station_class;
+ int i;
+
+ assert(spec->sclass < STAT_CLASS_MAX);
+ station_class = &station_classes[spec->sclass];
+
+ i = station_class->stations++;
+ station_class->spec = realloc(station_class->spec, station_class->stations * sizeof(*station_class->spec));
+
+ station_class->spec[i] = spec;
+}
+
+/**
+ * Retrieve a station spec from a class.
+ * @param sclass Index of the station class.
+ * @param station The station index with the class.
+ * @return The station spec.
+ */
+const StationSpec *GetCustomStation(StationClassID sclass, uint station)
+{
+ assert(sclass < STAT_CLASS_MAX);
+ if (station < station_classes[sclass].stations)
+ return station_classes[sclass].spec[station];
+
+ // If the custom station isn't defined any more, then the GRF file
+ // probably was not loaded.
+ return NULL;
+}
diff --git a/station_newgrf.h b/station_newgrf.h
new file mode 100644
index 000000000..b4bca4b46
--- /dev/null
+++ b/station_newgrf.h
@@ -0,0 +1,77 @@
+/* $Id$ */
+
+/** @file station_newgrf.h Header file for NewGRF stations */
+
+#ifndef STATION_NEWGRF_H
+#define STATION_NEWGRF_H
+
+#include "engine.h"
+
+typedef enum {
+ STAT_CLASS_DFLT, ///< Default station class.
+ STAT_CLASS_WAYP, ///< Waypoint class.
+ STAT_CLASS_MAX = 16, ///< Maximum number of classes.
+} StationClassID;
+
+/* Station layout for given dimensions - it is a two-dimensional array
+ * where index is computed as (x * platforms) + platform. */
+typedef byte *StationLayout;
+
+typedef struct stationspec {
+ uint32 grfid; ///< ID of GRF file station belongs to.
+ int localidx; ///< Index within GRF file of station.
+
+ StationClassID sclass; ///< The class to which this spec belongs.
+
+ /**
+ * Bitmask of number of platforms available for the station.
+ * 0..6 correpsond to 1..7, while bit 7 corresponds to >7 platforms.
+ */
+ byte allowed_platforms;
+ /**
+ * Bitmask of platform lengths available for the station.
+ * 0..6 correpsond to 1..7, while bit 7 corresponds to >7 tiles long.
+ */
+ byte allowed_lengths;
+
+ /** Number of tile layouts.
+ * A minimum of 8 is required is required for stations.
+ * 0-1 = plain platform
+ * 2-3 = platform with building
+ * 4-5 = platform with roof, left side
+ * 6-7 = platform with roof, right side
+ */
+ int tiles;
+ DrawTileSprites *renderdata; ///< Array of tile layouts.
+
+ byte lengths;
+ byte *platforms;
+ StationLayout **layouts;
+
+ /**
+ * NUM_GLOBAL_CID sprite groups.
+ * Used for obtaining the sprite offset of custom sprites, and for
+ * evaluating callbacks.
+ */
+ SpriteGroup *spritegroup[NUM_GLOBAL_CID];
+} StationSpec;
+
+/**
+ * Struct containing information relating to station classes.
+ */
+typedef struct stationclass {
+ uint32 id; ///< ID of this class, e.g. 'DFLT', 'WAYP', etc.
+ char *name; ///< Name of this class.
+ uint stations; ///< Number of stations in this class.
+ StationSpec **spec; ///< Array of station specifications.
+} StationClass;
+
+void ResetStationClasses(void);
+StationClassID AllocateStationClass(uint32 class);
+void SetStationClassName(StationClassID sclass, const char *name);
+uint GetNumCustomStations(StationClassID sclass);
+
+void SetCustomStation(StationSpec *spec);
+const StationSpec *GetCustomStation(StationClassID sclass, uint station);
+
+#endif /* STATION_NEWGRF_H */
diff --git a/waypoint.c b/waypoint.c
index c93492b7c..fd5c10e75 100644
--- a/waypoint.c
+++ b/waypoint.c
@@ -154,7 +154,7 @@ static Waypoint *FindDeletedWaypointCloseTo(TileIndex tile)
/** Convert existing rail to waypoint. Eg build a waypoint station over
* piece of rail
* @param x,y coordinates where waypoint will be built
- * @param p1 graphics for waypoint type, bit 8 signifies custom waypoint gfx (& 0x100)
+ * @param p1 graphics for waypoint type, 0 indicates standard graphics
* @param p2 unused
*
* @todo When checking for the tile slope,
@@ -170,7 +170,7 @@ int32 CmdBuildTrainWaypoint(int x, int y, uint32 flags, uint32 p1, uint32 p2)
SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
/* if custom gfx are used, make sure it is within bounds */
- if (p1 > 0x100 + (uint)GetCustomStationsCount(STAT_CLASS_WAYP)) return CMD_ERROR;
+ if (p1 >= GetNumCustomStations(STAT_CLASS_WAYP)) return CMD_ERROR;
if (!IsTileType(tile, MP_RAILWAY) || ((dir = 0, _m[tile].m5 != 1) && (dir = 1, _m[tile].m5 != 2)))
return_cmd_error(STR_1005_NO_SUITABLE_RAILROAD_TRACK);
@@ -200,10 +200,10 @@ int32 CmdBuildTrainWaypoint(int x, int y, uint32 flags, uint32 p1, uint32 p2)
if (flags & DC_EXEC) {
bool reserved = PBSTileReserved(tile) != 0;
ModifyTile(tile, MP_MAP5, RAIL_TYPE_WAYPOINT | dir);
- if (--p1 & 0x100) { // waypoint type 0 uses default graphics
+ if (p1 > 0) { // waypoint type 0 uses default graphics
// custom graphics
_m[tile].m3 |= 16;
- _m[tile].m4 = p1 & 0xff;
+ _m[tile].m4 = (p1 - 1) & 0xff;
}
if (reserved) {
PBSReserveTrack(tile, dir);
@@ -387,14 +387,14 @@ void DrawWaypointSprite(int x, int y, int stat_id, RailType railtype)
x += 33;
y += 17;
- /* draw default waypoint graphics of ID 0 */
- if (stat_id == 0) {
+ stat = GetCustomStation(STAT_CLASS_WAYP, stat_id);
+ if (stat == NULL) {
+ // stat is NULL for default waypoints and when waypoint graphics are
+ // not loaded.
DrawDefaultWaypointSprite(x, y, railtype);
return;
}
- stat = GetCustomStation(STAT_CLASS_WAYP, stat_id - 1);
- assert(stat);
relocation = GetCustomStationRelocation(stat, NULL, 1);
// emulate station tile - open with building
// add 1 to get the other direction
diff --git a/waypoint.h b/waypoint.h
index 537d86e69..a2b1c28bd 100644
--- a/waypoint.h
+++ b/waypoint.h
@@ -16,6 +16,7 @@ struct Waypoint {
ViewportSign sign;
uint16 build_date;
byte stat_id;
+ uint32 grfid;
byte deleted; // this is a delete counter. when it reaches 0, the waypoint struct is deleted.
};