Changeset - r3775:510ec99b1193
[Not reviewed]
master
0 6 0
peter1138 - 18 years ago 2006-05-07 10:58:53
peter1138@openttd.org
(svn r4767) - Newstations: fix loading / use of custom ground sprites
6 files changed with 77 insertions and 41 deletions:
0 comments (0 inline, 0 general)
newgrf.c
Show inline comments
 
@@ -823,25 +823,16 @@ static bool StationChangeInfo(uint stid,
 
				statspec->renderdata = calloc(statspec->tiles, sizeof(*statspec->renderdata));
 
				statspec->copied_renderdata = false;
 

	
 
				for (t = 0; t < statspec->tiles; t++) {
 
					DrawTileSprites *dts = &statspec->renderdata[t];
 
					uint seq_count = 0;
 
					PalSpriteID ground_sprite;
 

	
 
					dts->seq = NULL;
 
					ground_sprite = grf_load_dword(&buf);
 
					if (ground_sprite == 0) 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->ground_sprite = grf_load_dword(&buf);
 
					if (dts->ground_sprite == 0) continue;
 

	
 
					while (buf < *bufp + len) {
 
						DrawTileSeqStruct *dtss;
 

	
 
						// no relative bounding box support
 
						dts->seq = realloc((void*)dts->seq, ++seq_count * sizeof(DrawTileSeqStruct));
 
@@ -853,19 +844,21 @@ static bool StationChangeInfo(uint stid,
 
						dtss->delta_z = grf_load_byte(&buf);
 
						dtss->width = grf_load_byte(&buf);
 
						dtss->height = grf_load_byte(&buf);
 
						dtss->unk = grf_load_byte(&buf);
 
						dtss->image = grf_load_dword(&buf);
 

	
 
						/* Remap the colour map bit from 14 to 31 */
 
						/* Remap flags as ours collide */
 
						if (HASBIT(dtss->image, 31)) {
 
							CLRBIT(dtss->image, 31);
 
							SETBIT(dtss->image, 30);
 
						}
 
						if (HASBIT(dtss->image, 14)) {
 
							CLRBIT(dtss->image, 14);
 
							SETBIT(dtss->image, 31);
 
						}
 

	
 
						dtss->image -= 0x42D;
 
					}
 
				}
 
			}
 
			break;
 

	
 
		case 0x0A: /* Copy sprite layout */
 
@@ -1497,17 +1490,12 @@ static void NewSpriteGroup(byte *buf, in
 

	
 
					if (_cur_grffile->spriteset_start == 0) {
 
						grfmsg(GMS_ERROR, "NewSpriteGroup: No sprite set to work on! Skipping.");
 
						return;
 
					}
 

	
 
					if (_cur_grffile->first_spriteset == 0) {
 
						DEBUG(grf, 6) ("NewSpriteGroup: Setting 0x%X as first Sprite ID", _cur_grffile->spriteset_start);
 
						_cur_grffile->first_spriteset = _cur_grffile->spriteset_start;
 
					}
 

	
 
					check_length(bufend - buf, 2 * num_loaded + 2 * num_loading, "NewSpriteGroup (Real) (1)");
 

	
 
					group = AllocateSpriteGroup();
 
					group->type = SGT_REAL;
 

	
 
					group->g.real.num_loaded  = num_loaded;
 
@@ -1625,12 +1613,13 @@ static void NewVehicle_SpriteGroupMappin
 

	
 
			for (i = 0; i < idcount; i++) {
 
				uint8 stid = buf[3 + i];
 
				StationSpec *statspec = _cur_grffile->stations[stid];
 

	
 
				statspec->spritegroup[GC_DEFAULT] = _cur_grffile->spritegroups[groupid];
 
				statspec->groundgroup = _cur_grffile->spritegroups[0];
 
				statspec->grfid = _cur_grffile->grfid;
 
				statspec->localidx = stid;
 
				SetCustomStationSpec(statspec);
 
			}
 
		}
 
		return;
newgrf.h
Show inline comments
 
@@ -15,13 +15,12 @@ typedef struct GRFLabel {
 

	
 
typedef struct GRFFile {
 
	char *filename;
 
	uint32 grfid;
 
	uint16 flags;
 
	uint16 sprite_offset;
 
	SpriteID first_spriteset; ///< Holds the first spriteset's sprite offset.
 
	byte grf_version;
 
	struct GRFFile *next;
 

	
 
	/* A sprite group contains all sprites of a given vehicle (or multiple
 
	 * vehicles) when carrying given cargo. It consists of several sprite
 
	 * sets.  Group ids are refered as "cargo id"s by TTDPatch
newgrf_station.c
Show inline comments
 
@@ -462,13 +462,39 @@ SpriteID GetCustomStationRelocation(cons
 
	if ((group == NULL || group->type != SGT_RESULT) && ctype != GC_DEFAULT) {
 
		group = Resolve(statspec->spritegroup[GC_DEFAULT], &object);
 
	}
 

	
 
	if (group == NULL || group->type != SGT_RESULT) return 0;
 

	
 
	return group->g.result.sprite;
 
	return group->g.result.sprite - 0x42D;
 
}
 

	
 

	
 
SpriteID GetCustomStationGroundRelocation(const StationSpec *statspec, const Station *st, TileIndex tile)
 
{
 
	const SpriteGroup *group;
 
	ResolverObject object;
 
	CargoID ctype = (st == NULL) ? GC_PURCHASE : GC_DEFAULT_NA;
 

	
 
	NewStationResolver(&object, statspec, st, tile);
 
	object.callback_param1 = 1; /* Indicate we are resolving the ground sprite */
 

	
 
	group = Resolve(statspec->spritegroup[ctype], &object);
 
	if ((group == NULL || group->type != SGT_RESULT) && ctype != GC_DEFAULT_NA) {
 
		group = Resolve(statspec->spritegroup[GC_DEFAULT_NA], &object);
 
	}
 
	if ((group == NULL || group->type != SGT_RESULT) && ctype != GC_DEFAULT) {
 
		group = Resolve(statspec->spritegroup[GC_DEFAULT], &object);
 
	}
 
	if ((group == NULL || group->type != SGT_RESULT)) {
 
		group = Resolve(statspec->groundgroup, &object);
 
	}
 

	
 
	if (group == NULL || group->type != SGT_RESULT) return 0;
 

	
 
	return group->g.result.sprite - 0x42D;
 
}
 

	
 

	
 
uint16 GetStationCallback(uint16 callback, uint32 param1, uint32 param2, const StationSpec *statspec, const Station *st, TileIndex tile)
 
{
 
	const SpriteGroup *group;
 
@@ -590,14 +616,12 @@ bool DeallocateSpecFromStation(Station *
 
 * @param railtype Rail type.
 
 * @param sclass, station Type of station.
 
 * @return True if the tile was drawn (allows for fallback to default graphic)
 
 */
 
bool DrawStationTile(int x, int y, RailType railtype, Axis axis, StationClassID sclass, uint station)
 
{
 
	extern uint16 _custom_sprites_base;
 

	
 
	const StationSpec *statspec;
 
	const DrawTileSprites *sprites;
 
	const DrawTileSeqStruct *seq;
 
	const RailtypeInfo *rti = GetRailTypeInfo(railtype);
 
	SpriteID relocation;
 
	PalSpriteID image;
 
@@ -613,26 +637,37 @@ bool DrawStationTile(int x, int y, RailT
 
		uint16 callback = GetStationCallback(CBID_STATION_SPRITE_LAYOUT, 0x2110000, 0, statspec, NULL, INVALID_TILE);
 
		if (callback != CALLBACK_FAILED) tile = callback;
 
	}
 

	
 
	if (statspec->renderdata == NULL) {
 
		sprites = GetStationTileLayout(tile + axis);
 
		relocation -= 0x42D;
 
	} else {
 
		sprites = &statspec->renderdata[(tile < statspec->tiles) ? tile + axis : axis];
 
	}
 

	
 
	image = sprites->ground_sprite;
 
	image += (image < _custom_sprites_base) ? rti->total_offset : rti->custom_ground_offset;
 
	if (HASBIT(image, 31)) {
 
		CLRBIT(image, 31);
 
		image += GetCustomStationGroundRelocation(statspec, NULL, INVALID_TILE);
 
		image += rti->custom_ground_offset;
 
	} else {
 
		image += rti->total_offset;
 
	}
 

	
 
	if (image & PALETTE_MODIFIER_COLOR) image &= SPRITE_MASK;
 
	DrawSprite(image, x, y);
 

	
 
	foreach_draw_tile_seq(seq, sprites->seq) {
 
		Point pt;
 
		image = seq->image + relocation;
 
		image = seq->image;
 
		if (HASBIT(image, 30)) {
 
			CLRBIT(image, 30);
 
			image += rti->total_offset;
 
		} else {
 
			image += relocation;
 
		}
 

	
 
		if ((byte)seq->delta_z != 0x80) {
 
			pt = RemapCoords(seq->delta_x, seq->delta_y, seq->delta_z);
 
			DrawSprite((image & SPRITE_MASK) | colourmod, x + pt.x, y + pt.y);
 
		}
 
	}
newgrf_station.h
Show inline comments
 
@@ -68,12 +68,13 @@ typedef struct StationSpec {
 
	/**
 
	 * NUM_GLOBAL_CID sprite groups.
 
	 * Used for obtaining the sprite offset of custom sprites, and for
 
	 * evaluating callbacks.
 
	 */
 
	SpriteGroup *spritegroup[NUM_GLOBAL_CID];
 
	SpriteGroup *groundgroup;
 
} StationSpec;
 

	
 
/**
 
 * Struct containing information relating to station classes.
 
 */
 
typedef struct StationClass {
 
@@ -100,12 +101,13 @@ const StationSpec *GetCustomStationSpecB
 
uint32 GetPlatformInfo(Axis axis, byte tile, int platforms, int length, int x, int y, bool centred);
 

	
 
/* Get sprite offset for a given custom station and station structure (may be
 
 * NULL - that means we are in a build dialog). The station structure is used
 
 * for variational sprite groups. */
 
SpriteID GetCustomStationRelocation(const StationSpec *statspec, const Station *st, TileIndex tile);
 
SpriteID GetCustomStationGroundRelocation(const StationSpec *statspec, const Station *st, TileIndex tile);
 
uint16 GetStationCallback(uint16 callback, uint32 param1, uint32 param2, const StationSpec *statspec, const Station *st, TileIndex tile);
 

	
 
/* Check if a rail station tile is traversable. */
 
bool IsStationTileBlocked(TileIndex tile);
 

	
 
/* Allocate a StationSpec to a Station. This is called once per build operation. */
rail_cmd.c
Show inline comments
 
@@ -27,14 +27,12 @@
 
#include "rail.h"
 
#include "railtypes.h" // include table for railtypes
 
#include "newgrf.h"
 
#include "newgrf_callbacks.h"
 
#include "newgrf_station.h"
 

	
 
extern uint16 _custom_sprites_base;
 

	
 
const byte _track_sloped_sprites[14] = {
 
	14, 15, 22, 13,
 
	 0, 21, 17, 12,
 
	23,  0, 18, 20,
 
	19, 16
 
};
 
@@ -1335,21 +1333,26 @@ static void DrawTile_Track(TileInfo *ti)
 
					uint16 callback = GetStationCallback(CBID_STATION_SPRITE_LAYOUT, 0, 0, statspec, st, ti->tile);
 
					if (callback != CALLBACK_FAILED) tile = callback;
 
				}
 

	
 
				if (statspec->renderdata == NULL) {
 
					cust = GetStationTileLayout(tile);
 
					relocation -= 0x42D;
 
				} else {
 
					cust = &statspec->renderdata[(tile < statspec->tiles ? tile : 0) + GetWaypointAxis(ti->tile)];
 
				}
 

	
 
				/* If there is no sprite layout, we fall back to the default waypoint graphics. */
 
				if (cust != NULL && cust->seq != NULL) {
 
					image = cust->ground_sprite;
 
					image += (image < _custom_sprites_base) ? rti->total_offset : rti->custom_ground_offset;
 
					if (HASBIT(image, 31)) {
 
						CLRBIT(image, 31);
 
						image += GetCustomStationGroundRelocation(statspec, st, ti->tile);
 
						image += rti->custom_ground_offset;
 
					} else {
 
						image += rti->total_offset;
 
					}
 

	
 
					DrawGroundSprite(image);
 

	
 
					if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenary(ti);
 

	
 
					foreach_draw_tile_seq(seq, cust->seq) {
station_cmd.c
Show inline comments
 
@@ -1983,24 +1983,23 @@ static int32 RemoveDock(Station *st, uin
 

	
 
const DrawTileSprites *GetStationTileLayout(byte gfx)
 
{
 
	return &_station_display_datas[gfx];
 
}
 

	
 
extern uint16 _custom_sprites_base;
 

	
 
static void DrawTile_Station(TileInfo *ti)
 
{
 
	uint32 image_or_modificator;
 
	uint32 image;
 
	const DrawTileSeqStruct *dtss;
 
	const DrawTileSprites *t = NULL;
 
	RailType railtype = GetRailType(ti->tile);
 
	const RailtypeInfo *rti = GetRailTypeInfo(railtype);
 
	SpriteID offset;
 
	uint32 relocation = 0;
 
	const Station *st = NULL;
 
	const StationSpec *statspec = NULL;
 

	
 
	{
 
		PlayerID owner = GetTileOwner(ti->tile);
 
		image_or_modificator = PALETTE_TO_GREY; /* NOTE: possible bug in ttd here? */
 
		if (owner < MAX_PLAYERS) image_or_modificator = PLAYER_SPRITE_COLOR(owner);
 
	}
 
@@ -2008,14 +2007,14 @@ static void DrawTile_Station(TileInfo *t
 
	// don't show foundation for docks
 
	if (ti->tileh != SLOPE_FLAT && !IsDock(ti->tile))
 
		DrawFoundation(ti, ti->tileh);
 

	
 
	if (IsCustomStationSpecIndex(ti->tile)) {
 
		// look for customization
 
		const Station *st = GetStationByTile(ti->tile);
 
		const StationSpec *statspec = st->speclist[GetCustomStationSpecIndex(ti->tile)].spec;
 
		st = GetStationByTile(ti->tile);
 
		statspec = st->speclist[GetCustomStationSpecIndex(ti->tile)].spec;
 

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

	
 
		if (statspec != NULL) {
 
			uint tile = GetStationGfx(ti->tile);
 

	
 
@@ -2033,27 +2032,36 @@ static void DrawTile_Station(TileInfo *t
 
		}
 
	}
 

	
 
	if (t == NULL || t->seq == NULL) t = &_station_display_datas[GetStationGfx(ti->tile)];
 

	
 
	image = t->ground_sprite;
 
	if (HASBIT(image, 31)) {
 
		CLRBIT(image, 31);
 
		image += GetCustomStationGroundRelocation(statspec, st, ti->tile);
 
		image += rti->custom_ground_offset;
 
	} else {
 
		image += rti->total_offset;
 
	}
 
	if (image & PALETTE_MODIFIER_COLOR) image |= image_or_modificator;
 

	
 
	// For custom sprites, there's no railtype-based pitching.
 
	offset = (image & SPRITE_MASK) < _custom_sprites_base ? rti->total_offset : rti->custom_ground_offset;
 
	image += offset;
 

	
 
	// 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
 
	DrawGroundSprite(image);
 

	
 
	if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenary(ti);
 

	
 
	foreach_draw_tile_seq(dtss, t->seq) {
 
		image = dtss->image + relocation;
 
		image += offset;
 
		image = dtss->image;
 
		if (HASBIT(image, 30)) {
 
			CLRBIT(image, 30);
 
			image += rti->total_offset;
 
		} else {
 
			image += relocation;
 
		}
 

	
 
		if (_display_opt & DO_TRANS_BUILDINGS) {
 
			MAKE_TRANSPARENT(image);
 
		} else {
 
			if (image & PALETTE_MODIFIER_COLOR) image |= image_or_modificator;
 
		}
 

	
0 comments (0 inline, 0 general)