Changeset - r14610:ca137edec6fe
[Not reviewed]
master
0 5 0
yexo - 15 years ago 2010-02-22 14:16:57
yexo@openttd.org
(svn r19197) -Codechange: introduce animation callbacks for airport tiles
5 files changed with 148 insertions and 6 deletions:
0 comments (0 inline, 0 general)
src/economy.cpp
Show inline comments
 
@@ -27,6 +27,7 @@
 
#include "newgrf_industries.h"
 
#include "newgrf_industrytiles.h"
 
#include "newgrf_station.h"
 
#include "newgrf_airporttiles.h"
 
#include "unmovable.h"
 
#include "group.h"
 
#include "strings_func.h"
 
@@ -1288,6 +1289,7 @@ static void LoadUnloadVehicle(Vehicle *v
 
			st->last_vehicle_type = v->type;
 

	
 
			StationAnimationTrigger(st, st->xy, STAT_ANIM_CARGO_TAKEN, v->cargo_type);
 
			AirportAnimationTrigger(st, AAT_STATION_CARGO_TAKEN, v->cargo_type);
 

	
 
			unloading_time += cap;
 

	
src/newgrf_airporttiles.cpp
Show inline comments
 
@@ -15,12 +15,17 @@
 
#include "newgrf.h"
 
#include "newgrf_airporttiles.h"
 
#include "newgrf_spritegroup.h"
 
#include "newgrf_sound.h"
 
#include "animated_tile_func.h"
 
#include "station_base.h"
 
#include "water.h"
 
#include "viewport_func.h"
 
#include "landscape.h"
 
#include "company_base.h"
 
#include "town.h"
 
#include "variables.h"
 
#include "functions.h"
 
#include "core/random_func.hpp"
 
#include "table/airporttiles.h"
 

	
 

	
 
@@ -124,9 +129,7 @@ static uint32 GetAirportTileIDAtOffset(T
 
		return 0xFFFF;
 
	}
 

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

	
 
	if (gfx < NEW_AIRPORTTILE_OFFSET) { // Does it belongs to an old type?
 
@@ -291,4 +294,110 @@ bool DrawNewAirportTile(TileInfo *ti, St
 
	return true;
 
}
 

	
 
void AnimateAirportTile(TileIndex tile)
 
{
 
	Station *st = Station::GetByTile(tile);
 
	StationGfx gfx = GetAirportGfx(tile);
 
	const AirportTileSpec *ats = AirportTileSpec::Get(gfx);
 
	uint8 animation_speed = ats->animation_speed;
 

	
 
	if (HasBit(ats->callback_flags, CBM_AIRT_ANIM_SPEED)) {
 
		uint16 callback_res = GetAirportTileCallback(CBID_AIRPTILE_ANIMATION_SPEED, 0, 0, gfx, st, tile);
 
		if (callback_res != CALLBACK_FAILED) animation_speed = Clamp(callback_res & 0xFF, 0, 16);
 
	}
 

	
 
	/* An animation speed of 2 means the animation frame changes 4 ticks, and
 
	 * increasing this value by one doubles the wait. 0 is the minimum value
 
	 * allowed for animation_speed, which corresponds to 30ms, and 16 is the
 
	 * maximum, corresponding to around 33 minutes. */
 
	if ((_tick_counter % (1 << animation_speed)) != 0) return;
 

	
 
	bool frame_set_by_callback = false;
 
	uint8 frame      = GetStationAnimationFrame(tile);
 
	uint16 num_frames = GB(ats->animation_info, 0, 8);
 

	
 
	if (HasBit(ats->callback_flags, CBM_AIRT_ANIM_NEXT_FRAME)) {
 
		uint16 callback_res = GetAirportTileCallback(CBID_AIRPTILE_ANIM_NEXT_FRAME, HasBit(ats->animation_special_flags, 0) ? Random() : 0, 0, gfx, st, tile);
 

	
 
		if (callback_res != CALLBACK_FAILED) {
 
			frame_set_by_callback = true;
 

	
 
			switch (callback_res & 0xFF) {
 
				case 0xFF:
 
					DeleteAnimatedTile(tile);
 
					break;
 
				case 0xFE:
 
					/* Carry on as normal. */
 
					frame_set_by_callback = false;
 
					break;
 
				default:
 
					frame = callback_res & 0xFF;
 
					break;
 
			}
 

	
 
			/* If the lower 7 bits of the upper byte of the callback
 
			 * result are not empty, it is a sound effect. */
 
			if (GB(callback_res, 8, 7) != 0) PlayTileSound(ats->grf_prop.grffile, GB(callback_res, 8, 7), tile);
 
		}
 
	}
 

	
 
	if (!frame_set_by_callback) {
 
		if (frame < num_frames) {
 
			frame++;
 
		} else if (frame == num_frames && GB(ats->animation_info, 8, 8) == 1) {
 
			/* This animation loops, so start again from the beginning */
 
			frame = 0;
 
		} else {
 
			/* This animation doesn't loop, so stay here */
 
			DeleteAnimatedTile(tile);
 
		}
 
	}
 

	
 
	SetStationAnimationFrame(tile, frame);
 
	MarkTileDirtyByTile(tile);
 
}
 

	
 
static void ChangeAirportTileAnimationFrame(const AirportTileSpec *ats, TileIndex tile, AirpAnimationTrigger trigger, StationGfx gfx, Station *st)
 
{
 
	uint16 callback_res = GetAirportTileCallback(CBID_AIRPTILE_ANIM_START_STOP, Random(), trigger, gfx, st, tile);
 
	if (callback_res == CALLBACK_FAILED) return;
 

	
 
	switch (callback_res & 0xFF) {
 
		case 0xFD: /* Do nothing. */         break;
 
		case 0xFE: AddAnimatedTile(tile);    break;
 
		case 0xFF: DeleteAnimatedTile(tile); break;
 
		default:
 
			SetStationAnimationFrame(tile, callback_res & 0xFF);
 
			AddAnimatedTile(tile);
 
			break;
 
	}
 

	
 
	/* If the lower 7 bits of the upper byte of the callback
 
	 * result are not empty, it is a sound effect. */
 
	if (GB(callback_res, 8, 7) != 0) PlayTileSound(ats->grf_prop.grffile, GB(callback_res, 8, 7), tile);
 
}
 

	
 
void AirportTileAnimationTrigger(Station *st, TileIndex tile, AirpAnimationTrigger trigger, CargoID cargo_type)
 
{
 
	StationGfx gfx = GetAirportGfx(tile);
 
	const AirportTileSpec *ats = AirportTileSpec::Get(gfx);
 

	
 
	if (!HasBit(ats->animation_triggers, trigger)) return;
 

	
 
	ChangeAirportTileAnimationFrame(ats, tile, trigger, gfx, st);
 
	return;
 
}
 

	
 
void AirportAnimationTrigger(Station *st, AirpAnimationTrigger trigger, CargoID cargo_type)
 
{
 
	if (st->airport_tile == INVALID_TILE) return;
 

	
 
	const AirportSpec *as = st->GetAirportSpec();
 
	int w = as->size_x;
 
	int h = as->size_y;
 

	
 
	TILE_LOOP(tile, w, h, st->airport_tile) {
 
		if (st->TileBelongsToAirport(tile)) AirportTileAnimationTrigger(st, tile, trigger, cargo_type);
 
	}
 
}
 

	
src/newgrf_airporttiles.h
Show inline comments
 
@@ -17,6 +17,15 @@
 
#include "newgrf_commons.h"
 
#include "airport.h"
 

	
 
/** Animation triggers for airport tiles */
 
enum AirpAnimationTrigger {
 
	AAT_BUILT,               ///< Triggered when the airport it build (for all tiles at the same time)
 
	AAT_TILELOOP,            ///< Triggered in the periodic tile loop
 
	AAT_STATION_NEW_CARGO,   ///< Triggered when new cargo arrives at the station (for all tiles at the same time)
 
	AAT_STATION_CARGO_TAKEN, ///< Triggered when a cargo type is completely removed from the station (for all tiles at the same time)
 
	AAT_STATION_250_ticks,   ///< Triggered every 250 ticks (for all tiles at the same time)
 
};
 

	
 
/**
 
 * Defines the data structure of each indivudual tile of an airport.
 
 */
 
@@ -40,6 +49,10 @@ private:
 
	friend void AirportTileOverrideManager::SetEntitySpec(const AirportTileSpec *airpts);
 
};
 

	
 
StationGfx GetTranslatedAirportTileID(StationGfx gfx);
 
void AnimateAirportTile(TileIndex tile);
 
void AirportTileAnimationTrigger(Station *st, TileIndex tile, AirpAnimationTrigger trigger, CargoID cargo_type = CT_INVALID);
 
void AirportAnimationTrigger(Station *st, AirpAnimationTrigger trigger, CargoID cargo_type = CT_INVALID);
 
bool DrawNewAirportTile(TileInfo *ti, Station *st, StationGfx gfx, const AirportTileSpec *airts);
 

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

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

	
 
	/** Called for periodically starting or stopping the animation. */
 
	CBID_AIRPTILE_ANIM_START_STOP        = 0x152, // 15 bit callback
 

	
 
	/** Called to determine airport tile next animation frame. */
 
	CBID_AIRPTILE_ANIM_NEXT_FRAME        = 0x153, // 15 bit callback
 

	
 
	/** Called to indicate how long the current animation frame should last. */
 
	CBID_AIRPTILE_ANIMATION_SPEED        = 0x154, // 8 bit callback
 
};
 

	
 
/**
src/station_cmd.cpp
Show inline comments
 
@@ -2079,6 +2079,15 @@ CommandCost CmdBuildAirport(TileIndex ti
 
		do {
 
			TileIndex cur_tile = tile + ToTileIndexDiff(it->ti);
 
			MakeAirport(cur_tile, st->owner, st->index, it->gfx);
 

	
 
			if (AirportTileSpec::Get(GetTranslatedAirportTileID(it->gfx))->animation_info != 0xFFFF) AddAnimatedTile(cur_tile);
 
		} while ((++it)->ti.x != -0x80);
 

	
 
		/* Only call the animation trigger after all tiles have been built */
 
		it = as->table[0];
 
		do {
 
			TileIndex cur_tile = tile + ToTileIndexDiff(it->ti);
 
			AirportTileAnimationTrigger(st, cur_tile, AAT_BUILT);
 
		} while ((++it)->ti.x != -0x80);
 

	
 
		st->UpdateVirtCoord();
 
@@ -2703,9 +2712,7 @@ static void TileLoop_Station(TileIndex t
 
	 * hardcoded.....not good */
 
	switch (GetStationType(tile)) {
 
		case STATION_AIRPORT:
 
			if (AirportTileSpec::Get(GetStationGfx(tile))->animation_info != 0xFFFF) {
 
				AddAnimatedTile(tile);
 
			}
 
			AirportTileAnimationTrigger(Station::GetByTile(tile), tile, AAT_TILELOOP);
 
			break;
 

	
 
		case STATION_DOCK:
 
@@ -2982,6 +2989,7 @@ void OnTick_Station()
 
			/* Stop processing this station if it was deleted */
 
			if (!StationHandleBigTick(st)) continue;
 
			StationAnimationTrigger(st, st->xy, STAT_ANIM_250_TICKS);
 
			if (Station::IsExpected(st)) AirportAnimationTrigger(Station::From(st), AAT_STATION_250_ticks);
 
		}
 
	}
 
}
 
@@ -3016,6 +3024,7 @@ static void UpdateStationWaiting(Station
 
	SetBit(st->goods[type].acceptance_pickup, GoodsEntry::PICKUP);
 

	
 
	StationAnimationTrigger(st, st->xy, STAT_ANIM_NEW_CARGO, type);
 
	AirportAnimationTrigger(st, AAT_STATION_NEW_CARGO, type);
 

	
 
	SetWindowDirty(WC_STATION_VIEW, st->index);
 
	st->MarkTilesDirty(true);
0 comments (0 inline, 0 general)