mirror of https://github.com/OpenTTD/OpenTTD
(svn r20353) -Add: [NewGRF] Support for callback 0x147 ("add sprite offset") for canals.
parent
bd2f7e998c
commit
4d927af488
|
@ -105,3 +105,45 @@ SpriteID GetCanalSprite(CanalFeature feature, TileIndex tile)
|
||||||
|
|
||||||
return group->GetResult();
|
return group->GetResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run a specific callback for canals.
|
||||||
|
* @param callback Callback ID.
|
||||||
|
* @param param1 Callback parameter 1.
|
||||||
|
* @param param2 Callback parameter 2.
|
||||||
|
* @param feature For which feature to run the callback.
|
||||||
|
* @param tile Tile index of canal.
|
||||||
|
* @return Callback result or CALLBACK_FAILED if the callback failed.
|
||||||
|
*/
|
||||||
|
uint16 GetCanalCallback(CallbackID callback, uint32 param1, uint32 param2, CanalFeature feature, TileIndex tile)
|
||||||
|
{
|
||||||
|
ResolverObject object;
|
||||||
|
const SpriteGroup *group;
|
||||||
|
|
||||||
|
NewCanalResolver(&object, tile, _water_feature[feature].grffile);
|
||||||
|
|
||||||
|
object.callback = callback;
|
||||||
|
object.callback_param1 = param1;
|
||||||
|
object.callback_param2 = param2;
|
||||||
|
|
||||||
|
group = SpriteGroup::Resolve(_water_feature[feature].group, &object);
|
||||||
|
if (group == NULL) return CALLBACK_FAILED;
|
||||||
|
|
||||||
|
return group->GetCallbackResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the new sprite offset for a water tile.
|
||||||
|
* @param tile Tile index of the canal/water tile.
|
||||||
|
* @param feature For which feature to get the new sprite offset.
|
||||||
|
* @param cur_offset Current sprite offset.
|
||||||
|
* @return New sprite offset.
|
||||||
|
*/
|
||||||
|
uint GetCanalSpriteOffset(CanalFeature feature, TileIndex tile, uint cur_offset)
|
||||||
|
{
|
||||||
|
if (HasBit(_water_feature[feature].callback_mask, CBM_CANAL_SPRITE_OFFSET)) {
|
||||||
|
uint16 cb = GetCanalCallback(CBID_CANALS_SPRITE_OFFSET, cur_offset, 0, feature, tile);
|
||||||
|
if (cb != CALLBACK_FAILED) return cur_offset + cb;
|
||||||
|
}
|
||||||
|
return cur_offset;
|
||||||
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include "gfx_type.h"
|
#include "gfx_type.h"
|
||||||
#include "tile_type.h"
|
#include "tile_type.h"
|
||||||
#include "newgrf_generic.h"
|
#include "newgrf_generic.h"
|
||||||
|
#include "newgrf_callbacks.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of different canal 'features'.
|
* List of different canal 'features'.
|
||||||
|
@ -57,4 +58,7 @@ extern WaterFeature _water_feature[CF_END];
|
||||||
*/
|
*/
|
||||||
SpriteID GetCanalSprite(CanalFeature feature, TileIndex tile);
|
SpriteID GetCanalSprite(CanalFeature feature, TileIndex tile);
|
||||||
|
|
||||||
|
uint16 GetCanalCallback(CallbackID callback, uint32 param1, uint32 param2, CanalFeature feature, TileIndex tile);
|
||||||
|
uint GetCanalSpriteOffset(CanalFeature feature, TileIndex tile, uint cur_offset);
|
||||||
|
|
||||||
#endif /* NEWGRF_CANAL_H */
|
#endif /* NEWGRF_CANAL_H */
|
||||||
|
|
|
@ -507,8 +507,42 @@ static bool IsWateredTile(TileIndex tile, Direction from)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DrawWaterEdges(SpriteID base, TileIndex tile)
|
/**
|
||||||
|
* Draw a water sprite, potentially with a NewGRF-modified sprite offset.
|
||||||
|
* @param base Sprite base.
|
||||||
|
* @param offset Sprite offset.
|
||||||
|
* @param feature The type of sprite that is drawn.
|
||||||
|
* @param tile Tile index to draw.
|
||||||
|
*/
|
||||||
|
static void DrawWaterSprite(SpriteID base, uint offset, CanalFeature feature, TileIndex tile)
|
||||||
{
|
{
|
||||||
|
if (base != SPR_FLAT_WATER_TILE) {
|
||||||
|
/* Only call offset callback if the sprite is NewGRF-provided. */
|
||||||
|
offset = GetCanalSpriteOffset(feature, tile, offset);
|
||||||
|
}
|
||||||
|
DrawGroundSprite(base + offset, PAL_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draw canal or river edges.
|
||||||
|
* @param canal True if canal edges should be drawn, false for river edges.
|
||||||
|
* @param offset Sprite offset.
|
||||||
|
* @param tile Tile to draw.
|
||||||
|
*/
|
||||||
|
static void DrawWaterEdges(bool canal, uint offset, TileIndex tile)
|
||||||
|
{
|
||||||
|
CanalFeature feature;
|
||||||
|
SpriteID base = 0;
|
||||||
|
if (canal) {
|
||||||
|
feature = CF_DIKES;
|
||||||
|
base = GetCanalSprite(CF_DIKES, tile);
|
||||||
|
if (base == 0) base = SPR_CANAL_DIKES_BASE;
|
||||||
|
} else {
|
||||||
|
feature = CF_RIVER_EDGE;
|
||||||
|
base = GetCanalSprite(CF_RIVER_EDGE, tile);
|
||||||
|
if (base == 0) return; // Don't draw if no sprites provided.
|
||||||
|
}
|
||||||
|
|
||||||
uint wa;
|
uint wa;
|
||||||
|
|
||||||
/* determine the edges around with water. */
|
/* determine the edges around with water. */
|
||||||
|
@ -517,33 +551,33 @@ static void DrawWaterEdges(SpriteID base, TileIndex tile)
|
||||||
wa += IsWateredTile(TILE_ADDXY(tile, 1, 0), DIR_NE) << 2;
|
wa += IsWateredTile(TILE_ADDXY(tile, 1, 0), DIR_NE) << 2;
|
||||||
wa += IsWateredTile(TILE_ADDXY(tile, 0, -1), DIR_SE) << 3;
|
wa += IsWateredTile(TILE_ADDXY(tile, 0, -1), DIR_SE) << 3;
|
||||||
|
|
||||||
if (!(wa & 1)) DrawGroundSprite(base, PAL_NONE);
|
if (!(wa & 1)) DrawWaterSprite(base, offset, feature, tile);
|
||||||
if (!(wa & 2)) DrawGroundSprite(base + 1, PAL_NONE);
|
if (!(wa & 2)) DrawWaterSprite(base, offset + 1, feature, tile);
|
||||||
if (!(wa & 4)) DrawGroundSprite(base + 2, PAL_NONE);
|
if (!(wa & 4)) DrawWaterSprite(base, offset + 2, feature, tile);
|
||||||
if (!(wa & 8)) DrawGroundSprite(base + 3, PAL_NONE);
|
if (!(wa & 8)) DrawWaterSprite(base, offset + 3, feature, tile);
|
||||||
|
|
||||||
/* right corner */
|
/* right corner */
|
||||||
switch (wa & 0x03) {
|
switch (wa & 0x03) {
|
||||||
case 0: DrawGroundSprite(base + 4, PAL_NONE); break;
|
case 0: DrawWaterSprite(base, offset + 4, feature, tile); break;
|
||||||
case 3: if (!IsWateredTile(TILE_ADDXY(tile, -1, 1), DIR_W)) DrawGroundSprite(base + 8, PAL_NONE); break;
|
case 3: if (!IsWateredTile(TILE_ADDXY(tile, -1, 1), DIR_W)) DrawWaterSprite(base, offset + 8, feature, tile); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* bottom corner */
|
/* bottom corner */
|
||||||
switch (wa & 0x06) {
|
switch (wa & 0x06) {
|
||||||
case 0: DrawGroundSprite(base + 5, PAL_NONE); break;
|
case 0: DrawWaterSprite(base, offset + 5, feature, tile); break;
|
||||||
case 6: if (!IsWateredTile(TILE_ADDXY(tile, 1, 1), DIR_N)) DrawGroundSprite(base + 9, PAL_NONE); break;
|
case 6: if (!IsWateredTile(TILE_ADDXY(tile, 1, 1), DIR_N)) DrawWaterSprite(base, offset + 9, feature, tile); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* left corner */
|
/* left corner */
|
||||||
switch (wa & 0x0C) {
|
switch (wa & 0x0C) {
|
||||||
case 0: DrawGroundSprite(base + 6, PAL_NONE); break;
|
case 0: DrawWaterSprite(base, offset + 6, feature, tile); break;
|
||||||
case 12: if (!IsWateredTile(TILE_ADDXY(tile, 1, -1), DIR_E)) DrawGroundSprite(base + 10, PAL_NONE); break;
|
case 12: if (!IsWateredTile(TILE_ADDXY(tile, 1, -1), DIR_E)) DrawWaterSprite(base, offset + 10, feature, tile); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* upper corner */
|
/* upper corner */
|
||||||
switch (wa & 0x09) {
|
switch (wa & 0x09) {
|
||||||
case 0: DrawGroundSprite(base + 7, PAL_NONE); break;
|
case 0: DrawWaterSprite(base, offset + 7, feature, tile); break;
|
||||||
case 9: if (!IsWateredTile(TILE_ADDXY(tile, -1, -1), DIR_S)) DrawGroundSprite(base + 11, PAL_NONE); break;
|
case 9: if (!IsWateredTile(TILE_ADDXY(tile, -1, -1), DIR_S)) DrawWaterSprite(base, offset + 11, feature, tile); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -562,13 +596,9 @@ static void DrawCanalWater(TileIndex tile)
|
||||||
image = GetCanalSprite(CF_WATERSLOPE, tile);
|
image = GetCanalSprite(CF_WATERSLOPE, tile);
|
||||||
if (image == 0) image = SPR_FLAT_WATER_TILE;
|
if (image == 0) image = SPR_FLAT_WATER_TILE;
|
||||||
}
|
}
|
||||||
DrawGroundSprite(image, PAL_NONE);
|
DrawWaterSprite(image, 0, CF_WATERSLOPE, tile);
|
||||||
|
|
||||||
/* Test for custom graphics, else use the default */
|
DrawWaterEdges(true, 0, tile);
|
||||||
SpriteID dikes_base = GetCanalSprite(CF_DIKES, tile);
|
|
||||||
if (dikes_base == 0) dikes_base = SPR_CANAL_DIKES_BASE;
|
|
||||||
|
|
||||||
DrawWaterEdges(dikes_base, tile);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct LocksDrawTileStruct {
|
struct LocksDrawTileStruct {
|
||||||
|
@ -588,13 +618,15 @@ struct LocksDrawTileStruct {
|
||||||
* @param offset Additional sprite offset.
|
* @param offset Additional sprite offset.
|
||||||
* @param palette Palette to use.
|
* @param palette Palette to use.
|
||||||
*/
|
*/
|
||||||
static void DrawWaterTileStruct(const TileInfo *ti, const WaterDrawTileStruct *wdts, SpriteID base, uint offset, PaletteID palette)
|
static void DrawWaterTileStruct(const TileInfo *ti, const WaterDrawTileStruct *wdts, SpriteID base, uint offset, PaletteID palette, CanalFeature feature)
|
||||||
{
|
{
|
||||||
/* Don't draw if buildings are invisible. */
|
/* Don't draw if buildings are invisible. */
|
||||||
if (IsInvisibilitySet(TO_BUILDINGS)) return;
|
if (IsInvisibilitySet(TO_BUILDINGS)) return;
|
||||||
|
|
||||||
for (; wdts->delta_x != 0x80; wdts++) {
|
for (; wdts->delta_x != 0x80; wdts++) {
|
||||||
AddSortableSpriteToDraw(base + wdts->image + offset, palette,
|
uint tile_offs = offset + wdts->image;
|
||||||
|
if (feature < CF_END) tile_offs = GetCanalSpriteOffset(feature, ti->tile, tile_offs);
|
||||||
|
AddSortableSpriteToDraw(base + tile_offs, palette,
|
||||||
ti->x + wdts->delta_x, ti->y + wdts->delta_y,
|
ti->x + wdts->delta_x, ti->y + wdts->delta_y,
|
||||||
wdts->size_x, wdts->size_y,
|
wdts->size_x, wdts->size_y,
|
||||||
wdts->size_z, ti->z + wdts->delta_z,
|
wdts->size_z, ti->z + wdts->delta_z,
|
||||||
|
@ -636,7 +668,7 @@ static void DrawWaterLock(const TileInfo *ti)
|
||||||
zoffs = ti->z > wdts[3].delta_y ? 24 : 0;
|
zoffs = ti->z > wdts[3].delta_y ? 24 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawWaterTileStruct(ti, wdts, base, zoffs, PAL_NONE);
|
DrawWaterTileStruct(ti, wdts, base, zoffs, PAL_NONE, CF_LOCKS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Draw a ship depot tile. */
|
/** Draw a ship depot tile. */
|
||||||
|
@ -644,13 +676,14 @@ static void DrawWaterDepot(const TileInfo *ti)
|
||||||
{
|
{
|
||||||
DrawWaterClassGround(ti);
|
DrawWaterClassGround(ti);
|
||||||
/* Skip first entry in _shipdepot_display_seq as this is the ground sprite. */
|
/* Skip first entry in _shipdepot_display_seq as this is the ground sprite. */
|
||||||
DrawWaterTileStruct(ti, _shipdepot_display_seq[GetSection(ti->tile)] + 1, 0, 0, COMPANY_SPRITE_COLOUR(GetTileOwner(ti->tile)));
|
DrawWaterTileStruct(ti, _shipdepot_display_seq[GetSection(ti->tile)] + 1, 0, 0, COMPANY_SPRITE_COLOUR(GetTileOwner(ti->tile)), CF_END);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DrawRiverWater(const TileInfo *ti)
|
static void DrawRiverWater(const TileInfo *ti)
|
||||||
{
|
{
|
||||||
SpriteID image = SPR_FLAT_WATER_TILE;
|
SpriteID image = SPR_FLAT_WATER_TILE;
|
||||||
SpriteID edges_base = GetCanalSprite(CF_RIVER_EDGE, ti->tile);
|
uint offset = 0;
|
||||||
|
uint edges_offset = 0;
|
||||||
|
|
||||||
if (ti->tileh != SLOPE_FLAT || HasBit(_water_feature[CF_RIVER_SLOPE].flags, CFF_HAS_FLAT_SPRITE)) {
|
if (ti->tileh != SLOPE_FLAT || HasBit(_water_feature[CF_RIVER_SLOPE].flags, CFF_HAS_FLAT_SPRITE)) {
|
||||||
image = GetCanalSprite(CF_RIVER_SLOPE, ti->tile);
|
image = GetCanalSprite(CF_RIVER_SLOPE, ti->tile);
|
||||||
|
@ -664,24 +697,24 @@ static void DrawRiverWater(const TileInfo *ti)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Flag bit 0 indicates that the first sprite is flat water. */
|
/* Flag bit 0 indicates that the first sprite is flat water. */
|
||||||
uint offset = HasBit(_water_feature[CF_RIVER_SLOPE].flags, CFF_HAS_FLAT_SPRITE) ? 1 : 0;
|
offset = HasBit(_water_feature[CF_RIVER_SLOPE].flags, CFF_HAS_FLAT_SPRITE) ? 1 : 0;
|
||||||
|
|
||||||
switch (ti->tileh) {
|
switch (ti->tileh) {
|
||||||
case SLOPE_SE: edges_base += 12; break;
|
case SLOPE_SE: edges_offset += 12; break;
|
||||||
case SLOPE_NE: offset += 1; edges_base += 24; break;
|
case SLOPE_NE: offset += 1; edges_offset += 24; break;
|
||||||
case SLOPE_SW: offset += 2; edges_base += 36; break;
|
case SLOPE_SW: offset += 2; edges_offset += 36; break;
|
||||||
case SLOPE_NW: offset += 3; edges_base += 48; break;
|
case SLOPE_NW: offset += 3; edges_offset += 48; break;
|
||||||
default: offset = 0; break;
|
default: offset = 0; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
image += offset;
|
offset = GetCanalSpriteOffset(CF_RIVER_SLOPE, ti->tile, offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawGroundSprite(image, PAL_NONE);
|
DrawGroundSprite(image + offset, PAL_NONE);
|
||||||
|
|
||||||
/* Draw river edges if available. */
|
/* Draw river edges if available. */
|
||||||
if (edges_base > 48) DrawWaterEdges(edges_base, ti->tile);
|
DrawWaterEdges(false, edges_offset, ti->tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawShoreTile(Slope tileh)
|
void DrawShoreTile(Slope tileh)
|
||||||
|
|
Loading…
Reference in New Issue