File diff r448:4e5a3380e573 → r449:046a2e56577f
station_cmd.c
Show inline comments
 
@@ -700,8 +700,16 @@ static byte FORCEINLINE *CreateMulti(byt
 
}
 

	
 
// stolen from TTDPatch
 
static void GetStationLayout(byte *layout, int numtracks, int plat_len)
 
static void GetStationLayout(byte *layout, int numtracks, int plat_len, struct StationSpec *spec)
 
{
 
	if (spec != NULL && spec->lengths >= plat_len && spec->platforms[plat_len - 1] >= numtracks
 
	    && spec->layouts[plat_len - 1][numtracks - 1]) {
 
		/* Custom layout defined, follow it. */
 
		memcpy(layout, spec->layouts[plat_len - 1][numtracks - 1],
 
		       plat_len * numtracks);
 
		return;
 
	}
 

	
 
	if (plat_len == 1) {
 
		CreateSingle(layout, numtracks);
 
	} else {
 
@@ -720,7 +728,9 @@ static void GetStationLayout(byte *layou
 
 * p1 & 1 - orientation
 
 * (p1 >> 8) & 0xFF - numtracks
 
 * (p1 >> 16) & 0xFF - platform length
 
 * p2  - railtype
 
 * p2 & 0xF  - railtype
 
 * p2 & 0x10 - set for custom station
 
 * p2 >> 8   - custom station id
 
 */
 

	
 
int32 CmdBuildRailroadStation(int x_org, int y_org, uint32 flags, uint32 p1, uint32 p2)
 
@@ -815,6 +825,7 @@ int32 CmdBuildRailroadStation(int x_org,
 
		int tile_delta;
 
		byte *layout_ptr;
 
		uint station_index = st->index;
 
		struct StationSpec *statspec;
 

	
 
		// Now really clear the land below the station
 
		// It should never return CMD_ERROR.. but you never know ;)
 
@@ -833,8 +844,9 @@ int32 CmdBuildRailroadStation(int x_org,
 

	
 
		tile_delta = direction ? TILE_XY(0,1) : TILE_XY(1,0);
 

	
 
		statspec = (p2 & 0x10) != 0 ? GetCustomStation(STAT_CLASS_DFLT, p2 >> 8) : NULL;
 
		layout_ptr = alloca(numtracks * plat_len);
 
		GetStationLayout(layout_ptr, numtracks, plat_len);
 
		GetStationLayout(layout_ptr, numtracks, plat_len, statspec);
 

	
 
		do {
 
			int tile = tile_org;
 
@@ -843,9 +855,10 @@ int32 CmdBuildRailroadStation(int x_org,
 

	
 
				ModifyTile(tile,
 
					MP_SETTYPE(MP_STATION) | MP_MAPOWNER_CURRENT |
 
					MP_MAP2 | MP_MAP5 | MP_MAP3LO | MP_MAP3HI_CLEAR,
 
					MP_MAP2 | MP_MAP5 | MP_MAP3LO | MP_MAP3HI,
 
					station_index, /* map2 parameter */
 
					p2,				/* map3lo parameter */
 
					p2 & 0xFF,     /* map3lo parameter */
 
					p2 >> 8,       /* map3hi parameter */
 
					(*layout_ptr++) + direction   /* map5 parameter */
 
				);
 

	
 
@@ -958,24 +971,26 @@ uint GetStationPlatforms(Station *st, ui
 
}
 

	
 

	
 
/* TODO: Multiple classes! */
 

	
 
static int _waypoint_highest_id = -1;
 
static struct StationSpec _waypoint_data[256];
 
/* TODO: Custom classes! */
 
/* Indexed by class, just STAT_CLASS_DFLT and STAT_CLASS_WAYP supported. */
 
static int _statspec_highest_id[2] = {-1, -1};
 
static struct StationSpec _station_spec[2][256];
 

	
 
void SetCustomStation(byte local_stid, struct StationSpec *spec)
 
{
 
	enum StationClass sclass;
 
	int stid = -1;
 

	
 
	assert(spec->sclass == STAT_CLASS_WAYP);
 
	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 <= _waypoint_highest_id; i++) {
 
			if (_waypoint_data[i].grfid == spec->grfid
 
			    && _waypoint_data[i].localidx == local_stid + 1) {
 
		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
 
@@ -987,23 +1002,26 @@ void SetCustomStation(byte local_stid, s
 

	
 
	if (stid == -1) {
 
		/* Allocate new one. */
 
		if (_waypoint_highest_id >= 255) {
 
		if (_statspec_highest_id[sclass] >= 255) {
 
			error("Too many custom stations allocated.");
 
			return;
 
		}
 
		stid = ++_waypoint_highest_id;
 
		stid = ++_statspec_highest_id[sclass];
 
		spec->localidx = local_stid + 1;
 
	}
 

	
 
	memcpy(&_waypoint_data[stid], spec, sizeof(*spec));
 
	//debug("Registering station #%d of class %d", stid, sclass);
 
	memcpy(&_station_spec[sclass][stid], spec, sizeof(*spec));
 
}
 

	
 
struct StationSpec *GetCustomStation(enum StationClass sclass, byte stid)
 
{
 
	assert(sclass == STAT_CLASS_WAYP);
 
	if (stid > _waypoint_highest_id)
 
	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 &_waypoint_data[stid];
 
	return &_station_spec[sclass][stid];
 
}
 

	
 
static struct RealSpriteGroup *
 
@@ -1092,8 +1110,6 @@ uint32 GetCustomStationRelocation(struct
 
{
 
	struct RealSpriteGroup *rsg;
 

	
 
	assert(spec->sclass == STAT_CLASS_WAYP);
 

	
 
	rsg = ResolveStationSpriteGroup(&spec->spritegroup[ctype], stat);
 

	
 
	if (rsg->sprites_per_set != 0) {
 
@@ -1114,8 +1130,9 @@ uint32 GetCustomStationRelocation(struct
 

	
 
int GetCustomStationsCount(enum StationClass sclass)
 
{
 
	assert(sclass == STAT_CLASS_WAYP);
 
	return _waypoint_highest_id + 1;
 
	assert(sclass == STAT_CLASS_DFLT || sclass == STAT_CLASS_WAYP);
 
	sclass--;
 
	return _statspec_highest_id[sclass] + 1;
 
}
 

	
 

	
 
@@ -1879,17 +1896,16 @@ static int32 RemoveDock(Station *st, uin
 
#include "table/station_land.h"
 

	
 

	
 
extern uint16 _custom_sprites_base;
 

	
 
static void DrawTile_Station(TileInfo *ti)
 
{
 
	uint32 image_or_modificator;
 
	uint32 base_img, image;
 
	uint32 image;
 
	const DrawTileSeqStruct *dtss;
 
	const DrawTileSprites *t;
 

	
 
	// station_land array has been increased from 82 elements to 114
 
	// but this is something else. If AI builds station with 114 it looks all weird
 
	base_img = (_map3_lo[ti->tile] & 0xF) * 82;
 
	const DrawTileSprites *t = NULL;
 
	byte railtype = _map3_lo[ti->tile] & 0xF;
 
	uint32 relocation = 0;
 

	
 
	{
 
		uint owner = _map_owner[ti->tile];
 
@@ -1902,15 +1918,36 @@ static void DrawTile_Station(TileInfo *t
 
	if (ti->tileh != 0 && (ti->map5 < 0x4C || ti->map5 > 0x51))
 
		DrawFoundation(ti, ti->tileh);
 

	
 
	t = &_station_display_datas[ti->map5];
 
	if (_map3_lo[ti->tile] & 0x10) {
 
		// look for customization
 
		struct StationSpec *statspec = GetCustomStation(STAT_CLASS_DFLT, _map3_hi[ti->tile]);
 

	
 
		//debug("Cust-o-mized %p", statspec);
 

	
 
		if (statspec != NULL) {
 
			Station *st = DEREF_STATION(_map2[ti->tile]);
 

	
 
			relocation = GetCustomStationRelocation(statspec, st, 0);
 
			//debug("Relocation %d", relocation);
 
			t = &statspec->renderdata[ti->map5];
 
		}
 
	}
 

	
 
	if (t == NULL) t = &_station_display_datas[ti->map5];
 

	
 
	image = t->ground_sprite;
 
	if (image & 0x8000)
 
		image |= image_or_modificator;
 
	DrawGroundSprite(image + base_img);
 

	
 
	// station_land array has been increased from 82 elements to 114
 
	// but this is something else. If AI builds station with 114 it looks all weird
 
	image += railtype * ((image < _custom_sprites_base) ? TRACKTYPE_SPRITE_PITCH : 1);
 
	DrawGroundSprite(image);
 

	
 
	foreach_draw_tile_seq(dtss, t->seq) {
 
		image =	dtss->image + base_img;
 
		image =	dtss->image + relocation;
 
		// XXX: Do we want to do this for custom stations? --pasky
 
		image += railtype * ((image < _custom_sprites_base) ? TRACKTYPE_SPRITE_PITCH : 1);
 
		if (_display_opt & DO_TRANS_BUILDINGS) {
 
			if (image&0x8000) image |= image_or_modificator;	
 
		} else {