Changeset - r14608:a81032019c31
[Not reviewed]
master
0 7 0
yexo - 15 years ago 2010-02-22 14:16:41
yexo@openttd.org
(svn r19195) -Codechange: actually draw newgrf airport tiles
7 files changed with 272 insertions and 2 deletions:
0 comments (0 inline, 0 general)
src/newgrf_airporttiles.cpp
Show inline comments
 
@@ -10,9 +10,17 @@
 
/** @file newgrf_airporttiles.cpp NewGRF handling of airport tiles. */
 

	
 
#include "stdafx.h"
 
#include "debug.h"
 
#include "airport.h"
 
#include "newgrf.h"
 
#include "newgrf_airporttiles.h"
 
#include "newgrf_spritegroup.h"
 
#include "station_base.h"
 
#include "water.h"
 
#include "viewport_func.h"
 
#include "landscape.h"
 
#include "company_base.h"
 
#include "town.h"
 
#include "table/airporttiles.h"
 

	
 

	
 
@@ -67,3 +75,220 @@ void AirportTileOverrideManager::SetEnti
 
	}
 
}
 

	
 
/**
 
 * Do airporttile gfx ID translation for NewGRFs.
 
 * @param gfx the type to get the override for.
 
 * @return the gfx to actually work with.
 
 */
 
StationGfx GetTranslatedAirportTileID(StationGfx gfx)
 
{
 
	assert(gfx < NUM_AIRPORTTILES);
 
	const AirportTileSpec *it = AirportTileSpec::Get(gfx);
 
	return it->grf_prop.override == INVALID_AIRPORTTILE ? gfx : it->grf_prop.override;
 
}
 

	
 

	
 
static const SpriteGroup *AirportTileResolveReal(const ResolverObject *object, const RealSpriteGroup *group)
 
{
 
	/* AirportTile do not have 'real' groups. */
 
	return NULL;
 
}
 

	
 
/**
 
 * Based on newhouses/newindustries equivalent, but adapted for airports.
 
 * @param parameter from callback. It's in fact a pair of coordinates
 
 * @param tile TileIndex from which the callback was initiated
 
 * @param index of the industry been queried for
 
 * @return a construction of bits obeying the newgrf format
 
 */
 
uint32 GetNearbyAirportTileInformation(byte parameter, TileIndex tile, StationID index)
 
{
 
	if (parameter != 0) tile = GetNearbyTile(parameter, tile); // only perform if it is required
 
	bool is_same_airport = (IsTileType(tile, MP_STATION) && IsAirport(tile) && GetStationIndex(tile) == index);
 

	
 
	return GetNearbyTileInformation(tile) | (is_same_airport ? 1 : 0) << 8;
 
}
 

	
 

	
 
/**
 
 * Make an analysis of a tile and check whether it belongs to the same
 
 * airport, and/or the same grf file
 
 * @param tile TileIndex of the tile to query
 
 * @param st Station to which to compare the tile to
 
 * @param cur_grfid GRFID of the current callback
 
 * @return value encoded as per NFO specs
 
 */
 
static uint32 GetAirportTileIDAtOffset(TileIndex tile, const Station *st, uint32 cur_grfid)
 
{
 
	if (!st->TileBelongsToAirport(tile)) {
 
		return 0xFFFF;
 
	}
 

	
 
	/* Don't use GetAirportGfx here as we want the original (not overriden)
 
	 * graphics id. */
 
	StationGfx gfx = GetStationGfx(tile);
 
	const AirportTileSpec *ats = AirportTileSpec::Get(gfx);
 

	
 
	if (gfx < NEW_AIRPORTTILE_OFFSET) { // Does it belongs to an old type?
 
		/* It is an old tile.  We have to see if it's been overriden */
 
		if (ats->grf_prop.override == INVALID_AIRPORTTILE) { // has it been overridden?
 
			return 0xFF << 8 | gfx; // no. Tag FF + the gfx id of that tile
 
		}
 
		/* Overriden */
 
		const AirportTileSpec *tile_ovr = AirportTileSpec::Get(ats->grf_prop.override);
 

	
 
		if (tile_ovr->grf_prop.grffile->grfid == cur_grfid) {
 
			return tile_ovr->grf_prop.local_id; // same grf file
 
		} else {
 
			return 0xFFFE; // not the same grf file
 
		}
 
	}
 
	/* Not an 'old type' tile */
 
	if (ats->grf_prop.spritegroup != NULL) { // tile has a spritegroup ?
 
		if (ats->grf_prop.grffile->grfid == cur_grfid) { // same airport, same grf ?
 
			return ats->grf_prop.local_id;
 
		} else {
 
			return 0xFFFE; // Defined in another grf file
 
		}
 
	}
 
	/* The tile has no spritegroup */
 
	return 0xFF << 8 | ats->grf_prop.subst_id; // so just give him the substitute
 
}
 

	
 
static uint32 AirportTileGetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available)
 
{
 
	const Station *st = object->u.airport.st;
 
	TileIndex tile    = object->u.airport.tile;
 
	assert(st != NULL);
 

	
 
	if (object->scope == VSG_SCOPE_PARENT) {
 
		DEBUG(grf, 1, "Parent scope for airport tiles unavailable");
 
		*available = false;
 
		return UINT_MAX;
 
	}
 

	
 
	extern uint32 GetRelativePosition(TileIndex tile, TileIndex ind_tile);
 

	
 
	switch (variable) {
 
		/* Terrain type */
 
		case 0x41: return GetTerrainType(tile);
 

	
 
		/* Current town zone of the tile in the nearest town */
 
		case 0x42: return GetTownRadiusGroup(ClosestTownFromTile(tile, UINT_MAX), tile);
 

	
 
		/* Position relative to most northern airport tile. */
 
		case 0x43: return GetRelativePosition(tile, st->airport_tile);
 

	
 
		/* Animation frame of tile */
 
		case 0x44: return GetStationAnimationFrame(tile);
 

	
 
		/* Land info of nearby tiles */
 
		case 0x60: return GetNearbyAirportTileInformation(parameter, tile, st->index);
 

	
 
		/* Animation stage of nearby tiles */
 
		case 0x61:
 
			tile = GetNearbyTile(parameter, tile);
 
			if (st->TileBelongsToAirport(tile)) {
 
				return GetStationAnimationFrame(tile);
 
			}
 
			return UINT_MAX;
 

	
 
		/* Get airport tile ID at offset */
 
		case 0x62: return GetAirportTileIDAtOffset(GetNearbyTile(parameter, tile), st, object->grffile->grfid);
 
	}
 

	
 
	DEBUG(grf, 1, "Unhandled airport tile property 0x%X", variable);
 

	
 
	*available = false;
 
	return UINT_MAX;
 
}
 

	
 
static void AirportTileResolver(ResolverObject *res, StationGfx gfx, TileIndex tile, Station *st)
 
{
 
	res->GetRandomBits = NULL;
 
	res->GetTriggers   = NULL;
 
	res->SetTriggers   = NULL;
 
	res->GetVariable   = AirportTileGetVariable;
 
	res->ResolveReal   = AirportTileResolveReal;
 

	
 
	assert(st != NULL);
 
	res->psa                  = NULL;
 
	res->u.airport.airport_id = st->airport_type;
 
	res->u.airport.st         = st;
 
	res->u.airport.tile       = tile;
 

	
 
	res->callback        = CBID_NO_CALLBACK;
 
	res->callback_param1 = 0;
 
	res->callback_param2 = 0;
 
	res->last_value      = 0;
 
	res->trigger         = 0;
 
	res->reseed          = 0;
 
	res->count           = 0;
 

	
 
	const AirportTileSpec *ats = AirportTileSpec::Get(gfx);
 
	res->grffile         = ats->grf_prop.grffile;
 
}
 

	
 
uint16 GetAirportTileCallback(CallbackID callback, uint32 param1, uint32 param2, StationGfx gfx_id, Station *st, TileIndex tile)
 
{
 
	ResolverObject object;
 
	const SpriteGroup *group;
 

	
 
	AirportTileResolver(&object, gfx_id, tile, st);
 
	object.callback = callback;
 
	object.callback_param1 = param1;
 
	object.callback_param2 = param2;
 

	
 
	group = SpriteGroup::Resolve(AirportTileSpec::Get(gfx_id)->grf_prop.spritegroup, &object);
 
	if (group == NULL) return CALLBACK_FAILED;
 

	
 
	return group->GetCallbackResult();
 
}
 

	
 
static void AirportDrawTileLayout(const TileInfo *ti, const TileLayoutSpriteGroup *group, byte colour, StationGfx gfx)
 
{
 
	const DrawTileSprites *dts = group->dts;
 

	
 
	SpriteID image = dts->ground.sprite;
 
	SpriteID pal   = dts->ground.pal;
 

	
 
	if (GB(image, 0, SPRITE_WIDTH) != 0) {
 
		if (image == SPR_FLAT_WATER_TILE && GetWaterClass(ti->tile) != WATER_CLASS_INVALID) {
 
			DrawWaterClassGround(ti);
 
		} else {
 
			DrawGroundSprite(image, GroundSpritePaletteTransform(image, pal, GENERAL_SPRITE_COLOUR(colour)));
 
		}
 
	}
 

	
 
	DrawNewGRFTileSeq(ti, dts, TO_BUILDINGS, 0, GENERAL_SPRITE_COLOUR(colour));
 
}
 

	
 
bool DrawNewAirportTile(TileInfo *ti, Station *st, StationGfx gfx, const AirportTileSpec *airts)
 
{
 
	const SpriteGroup *group;
 
	ResolverObject object;
 

	
 
	if (ti->tileh != SLOPE_FLAT) {
 
		bool draw_old_one = true;
 
		if (HasBit(airts->callback_flags, CBM_AIRT_DRAW_FOUNDATIONS)) {
 
			/* Called to determine the type (if any) of foundation to draw */
 
			uint32 callback_res = GetAirportTileCallback(CBID_AIRPTILE_DRAW_FOUNDATIONS, 0, 0, gfx, st, ti->tile);
 
			draw_old_one = (callback_res != 0);
 
		}
 

	
 
		if (draw_old_one) DrawFoundation(ti, FOUNDATION_LEVELED);
 
	}
 

	
 
	AirportTileResolver(&object, gfx, ti->tile, st);
 

	
 
	group = SpriteGroup::Resolve(airts->grf_prop.spritegroup, &object);
 
	if (group == NULL || group->type != SGT_TILELAYOUT) {
 
		return false;
 
	}
 

	
 
	const TileLayoutSpriteGroup *tlgroup = (const TileLayoutSpriteGroup *)group;
 
	AirportDrawTileLayout(ti, tlgroup, Company::Get(st->owner)->colour, gfx);
 
	return true;
 
}
 

	
 

	
src/newgrf_airporttiles.h
Show inline comments
 
@@ -40,4 +40,6 @@ private:
 
	friend void AirportTileOverrideManager::SetEntitySpec(const AirportTileSpec *airpts);
 
};
 

	
 
bool DrawNewAirportTile(TileInfo *ti, Station *st, StationGfx gfx, const AirportTileSpec *airts);
 

	
 
#endif /* NEWGRF_AIRPORTTILES_H */
src/newgrf_callbacks.h
Show inline comments
 
@@ -220,6 +220,9 @@ enum CallbackID {
 

	
 
	/** Called to determine if one can alter the ground below a house tile */
 
	CBID_HOUSE_AUTOSLOPE                 = 0x14F, // 15 bit callback
 

	
 
	/** Called to determine the type (if any) of foundation to draw for an airport tile. */
 
	CBID_AIRPTILE_DRAW_FOUNDATIONS       = 0x150, // 15 bit callback
 
};
 

	
 
/**
 
@@ -316,6 +319,17 @@ enum IndustryTileCallbackMask {
 
};
 

	
 
/**
 
 * Callback masks for airport tiles
 
 */
 
enum AirportTileCallbackMask {
 
	CBM_AIRT_ANIM_NEXT_FRAME          = 0,  ///< decides next animation frame
 
	CBM_AIRT_ANIM_SPEED               = 1,  ///< decides animation speed
 
	CBM_AIRT_SHAPE_CHECK              = 4,  ///< decides slope suitability
 
	CBM_AIRT_DRAW_FOUNDATIONS         = 5,  ///< decides if default foundations need to be drawn
 
	CBM_AIRT_AUTOSLOPE                = 6,  ///< decides allowance of autosloping
 
};
 

	
 
/**
 
 * Different values for Callback result evaluations
 
 */
 
enum {
src/newgrf_industrytiles.cpp
Show inline comments
 
@@ -55,7 +55,7 @@ uint32 GetNearbyIndustryTileInformation(
 
 * @param tile TileIndex of the tile to evaluate
 
 * @param ind_tile northernmost tile of the industry
 
 */
 
static uint32 GetRelativePosition(TileIndex tile, TileIndex ind_tile)
 
uint32 GetRelativePosition(TileIndex tile, TileIndex ind_tile)
 
{
 
	byte x = TileX(tile) - TileX(ind_tile);
 
	byte y = TileY(tile) - TileY(ind_tile);
src/newgrf_spritegroup.h
Show inline comments
 
@@ -342,6 +342,11 @@ struct ResolverObject {
 
		struct {
 
			TileIndex tile;
 
		} routes;
 
		struct {
 
			const struct Station *st;
 
			byte airport_id;
 
			TileIndex tile;
 
		} airport;
 
	} u;
 

	
 
	uint32 (*GetRandomBits)(const struct ResolverObject*);
src/station_cmd.cpp
Show inline comments
 
@@ -2398,7 +2398,18 @@ static void DrawTile_Station(TileInfo *t
 
	}
 

	
 
	if (IsAirport(ti->tile)) {
 
		switch (GetStationGfx(ti->tile)) {
 
		StationGfx gfx = GetAirportGfx(ti->tile);
 
		if (gfx >= NEW_AIRPORTTILE_OFFSET) {
 
			const AirportTileSpec *ats = AirportTileSpec::Get(gfx);
 
			if (ats->grf_prop.spritegroup != NULL && DrawNewAirportTile(ti, Station::GetByTile(ti->tile), gfx, ats)) {
 
				return;
 
			}
 
			/* No sprite group (or no valid one) found, meaning no graphics associated.
 
			 * Use the substitute one instead */
 
			assert(ats->grf_prop.subst_id != INVALID_AIRPORTTILE);
 
			gfx = ats->grf_prop.subst_id;
 
		}
 
		switch (gfx) {
 
			case APT_RADAR_GRASS_FENCE_SW:
 
				t = &_station_display_datas_airport_radar_grass_fence_sw[GetStationAnimationFrame(ti->tile)];
 
				break;
src/station_map.h
Show inline comments
 
@@ -263,6 +263,19 @@ static inline bool IsDriveThroughStopTil
 
}
 

	
 
/**
 
 * Get the station graphics of this airport tile
 
 * @param t the tile to query
 
 * @pre IsAirport(t)
 
 * @return the station graphics
 
 */
 
static inline StationGfx GetAirportGfx(TileIndex t)
 
{
 
	assert(IsAirport(t));
 
	extern StationGfx GetTranslatedAirportTileID(StationGfx gfx);
 
	return GetTranslatedAirportTileID(GetStationGfx(t));
 
}
 

	
 
/**
 
 * Gets the direction the road stop entrance points towards.
 
 * @param t the tile of the road stop
 
 * @pre IsRoadStopTile(t)
0 comments (0 inline, 0 general)