Changeset - r6583:63b4cb964287
[Not reviewed]
master
0 7 2
peter1138 - 17 years ago 2007-05-06 18:14:33
peter1138@openttd.org
(svn r9797) -Feature: [NewGRF] Add action 1, 2 and 3 support for canals.
9 files changed with 242 insertions and 42 deletions:
0 comments (0 inline, 0 general)
projects/openttd.vcproj
Show inline comments
 
@@ -513,6 +513,9 @@
 
				RelativePath=".\..\src\newgrf_callbacks.h">
 
			</File>
 
			<File
 
				RelativePath=".\..\src\newgrf_canal.h">
 
			</File>
 
			<File
 
				RelativePath=".\..\src\newgrf_cargo.h">
 
			</File>
 
			<File
 
@@ -935,6 +938,9 @@
 
				RelativePath=".\..\src\newgrf.cpp">
 
			</File>
 
			<File
 
				RelativePath=".\..\src\newgrf_canal.cpp">
 
			</File>
 
			<File
 
				RelativePath=".\..\src\newgrf_cargo.cpp">
 
			</File>
 
			<File
projects/openttd_vs80.vcproj
Show inline comments
 
@@ -912,6 +912,10 @@
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\newgrf_canal.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\newgrf_cargo.h"
 
				>
 
			</File>
 
@@ -1468,6 +1472,10 @@
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\newgrf_canal.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\newgrf_cargo.cpp"
 
				>
 
			</File>
source.list
Show inline comments
 
@@ -138,6 +138,7 @@ network/network_server.h
 
network/network_udp.h
 
newgrf.h
 
newgrf_callbacks.h
 
newgrf_canal.h
 
newgrf_cargo.h
 
newgrf_config.h
 
newgrf_engine.h
 
@@ -282,6 +283,7 @@ ai/trolly/trolly.cpp
 

	
 
# NewGRF
 
newgrf.cpp
 
newgrf_canal.cpp
 
newgrf_cargo.cpp
 
newgrf_config.cpp
 
newgrf_engine.cpp
src/newgrf.cpp
Show inline comments
 
@@ -39,6 +39,7 @@
 
#include "table/town_land.h"
 
#include "cargotype.h"
 
#include "industry.h"
 
#include "newgrf_canal.h"
 

	
 
/* TTDPatch extended GRF format codec
 
 * (c) Petr Baudis 2004 (GPL'd)
 
@@ -2244,6 +2245,7 @@ static void NewSpriteGroup(byte *buf, in
 
				case GSF_SHIP:
 
				case GSF_AIRCRAFT:
 
				case GSF_STATION:
 
				case GSF_CANAL:
 
				case GSF_CARGOS:
 
				{
 
					byte sprites     = _cur_grffile->spriteset_numents;
 
@@ -2513,6 +2515,30 @@ static void VehicleMapSpriteGroup(byte *
 
}
 

	
 

	
 
static void CanalMapSpriteGroup(byte *buf, uint8 idcount, uint8 cidcount)
 
{
 
	byte *bp = &buf[4 + idcount + cidcount * 3];
 
	uint16 groupid = grf_load_word(&bp);
 

	
 
	if (groupid >= _cur_grffile->spritegroups_count || _cur_grffile->spritegroups[groupid] == NULL) {
 
		grfmsg(1, "CanalMapSpriteGroup: Spriteset 0x%04X out of range 0x%X or empty, skipping.",
 
		       groupid, _cur_grffile->spritegroups_count);
 
		return;
 
	}
 

	
 
	for (uint i = 0; i < idcount; i++) {
 
		CanalFeature cf = (CanalFeature)buf[3 + i];
 

	
 
		if (cf >= CF_END) {
 
			grfmsg(1, "CanalMapSpriteGroup: Canal subset %d out of range, skipping", cf);
 
			continue;
 
		}
 

	
 
		_canal_sg[cf] = _cur_grffile->spritegroups[groupid];
 
	}
 
}
 

	
 

	
 
static void StationMapSpriteGroup(byte *buf, uint8 idcount, uint8 cidcount)
 
{
 
	for (uint i = 0; i < idcount; i++) {
 
@@ -2661,6 +2687,10 @@ static void FeatureMapSpriteGroup(byte *
 
			VehicleMapSpriteGroup(buf, feature, idcount, cidcount, wagover);
 
			return;
 

	
 
		case GSF_CANAL:
 
			CanalMapSpriteGroup(buf, idcount, cidcount);
 
			return;
 

	
 
		case GSF_STATION:
 
			StationMapSpriteGroup(buf, idcount, cidcount);
 
			return;
 
@@ -4315,6 +4345,9 @@ static void ResetNewGRFData()
 
	ResetStationClasses();
 
	ResetCustomStations();
 

	
 
	/* Reset canal sprite groups */
 
	memset(_canal_sg, 0, sizeof(_canal_sg));
 

	
 
	/* Reset the snowline table. */
 
	ClearSnowLine();
 

	
src/newgrf_canal.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
#include "stdafx.h"
 
#include "openttd.h"
 
#include "variables.h"
 
#include "landscape.h"
 
#include "debug.h"
 
#include "newgrf.h"
 
#include "newgrf_callbacks.h"
 
#include "newgrf_spritegroup.h"
 
#include "newgrf_canal.h"
 

	
 

	
 
/** Table of canal 'feature' sprite groups */
 
const SpriteGroup *_canal_sg[CF_END];
 

	
 

	
 
/* Random bits and triggers are not supported for canals, so the following
 
 * three functions are stubs. */
 
static uint32 CanalGetRandomBits(const ResolverObject *object)
 
{
 
	return 0;
 
}
 

	
 

	
 
static uint32 CanalGetTriggers(const ResolverObject *object)
 
{
 
	return 0;
 
}
 

	
 

	
 
static void CanalSetTriggers(const ResolverObject *object, int triggers)
 
{
 
	return;
 
}
 

	
 

	
 
static uint32 CanalGetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available)
 
{
 
	TileIndex tile = object->u.canal.tile;
 

	
 
	switch (variable) {
 
		case 0x80:
 
			return TileHeight(tile);
 

	
 
		case 0x81:
 
			return ((_opt.landscape == LT_ARCTIC && GetTileZ(tile) > GetSnowLine()) ? 4 : 0) |
 
			       (_opt.landscape == LT_TROPIC ? GetTropicZone(tile) : 0);
 
	}
 

	
 
	DEBUG(grf, 1, "Unhandled canal property 0x%02X", variable);
 

	
 
	*available = false;
 
	return 0;
 
}
 

	
 

	
 
static const SpriteGroup *CanalResolveReal(const ResolverObject *object, const SpriteGroup *group)
 
{
 
	if (group->g.real.num_loaded == 0) return NULL;
 

	
 
	return group->g.real.loaded[0];
 
}
 

	
 

	
 
static void NewCanalResolver(ResolverObject *res, TileIndex tile)
 
{
 
	res->GetRandomBits = &CanalGetRandomBits;
 
	res->GetTriggers   = &CanalGetTriggers;
 
	res->SetTriggers   = &CanalSetTriggers;
 
	res->GetVariable   = &CanalGetVariable;
 
	res->ResolveReal   = &CanalResolveReal;
 

	
 
	res->u.canal.tile = tile;
 

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

	
 

	
 
SpriteID GetCanalSprite(CanalFeature feature, TileIndex tile)
 
{
 
	ResolverObject object;
 
	const SpriteGroup *group;
 

	
 
	NewCanalResolver(&object, tile);
 

	
 
	group = Resolve(_canal_sg[feature], &object);
 
	if (group == NULL || group->type != SGT_RESULT) return 0;
 

	
 
	return group->g.result.sprite;
 
}
src/newgrf_canal.h
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
#ifndef NEWGRF_CANAL_H
 
#define NEWGRF_CANAL_H
 

	
 
/** List of different canal 'features'.
 
 * Each feature gets an entry in the canal spritegroup table */
 
enum CanalFeature {
 
	CF_WATERSLOPE,
 
	CF_LOCKS,
 
	CF_DIKES,
 
	CF_ICON,
 
	CF_DOCKS,
 
	CF_END,
 
};
 

	
 

	
 
/** Table of canal 'feature' sprite groups */
 
extern const SpriteGroup *_canal_sg[CF_END];
 

	
 

	
 
/** Lookup the base sprite to use for a canal.
 
 * @param feature Which canal feature we want.
 
 * @param tile Tile index of canal, if appropriate.
 
 * @return Base sprite returned by GRF, or 0 if none.
 
 */
 
SpriteID GetCanalSprite(CanalFeature feature, TileIndex tile);
 

	
 
#endif /* NEWGRF_CANAL_H */
src/newgrf_spritegroup.h
Show inline comments
 
@@ -184,6 +184,9 @@ struct ResolverObject {
 
		} vehicle;
 
		struct {
 
			TileIndex tile;
 
		} canal;
 
		struct {
 
			TileIndex tile;
 
			const struct Station *st;
 
			const struct StationSpec *statspec;
 
			CargoID cargo_type;
src/table/water_land.h
Show inline comments
 
@@ -47,86 +47,86 @@ static const WaterDrawTileStruct* const 
 
};
 

	
 
static const WaterDrawTileStruct _shiplift_display_seq_0[] = {
 
	BEGIN(SPR_CANALS_BASE + 6),
 
	{ 0,   0, 0, 0x10, 1, 0x14, SPR_CANALS_BASE + 9 + 0 + 1 },
 
	{ 0, 0xF, 0, 0x10, 1, 0x14, SPR_CANALS_BASE + 9 + 4 + 1 },
 
	BEGIN(1),
 
	{ 0,   0, 0, 0x10, 1, 0x14, 0 + 1 },
 
	{ 0, 0xF, 0, 0x10, 1, 0x14, 4 + 1 },
 
	END(0)
 
};
 

	
 
static const WaterDrawTileStruct _shiplift_display_seq_1[] = {
 
	BEGIN(SPR_CANALS_BASE + 5),
 
	{   0, 0, 0, 1, 0x10, 0x14, SPR_CANALS_BASE + 9 + 0 },
 
	{ 0xF, 0, 0, 1, 0x10, 0x14, SPR_CANALS_BASE + 9 + 4 },
 
	BEGIN(0),
 
	{   0, 0, 0, 1, 0x10, 0x14, 0 },
 
	{ 0xF, 0, 0, 1, 0x10, 0x14, 4 },
 
	END(0)
 
};
 

	
 
static const WaterDrawTileStruct _shiplift_display_seq_2[] = {
 
	BEGIN(SPR_CANALS_BASE + 7),
 
	{ 0,   0, 0, 0x10, 1, 0x14, SPR_CANALS_BASE + 9 + 0 + 2 },
 
	{ 0, 0xF, 0, 0x10, 1, 0x14, SPR_CANALS_BASE + 9 + 4 + 2 },
 
	BEGIN(2),
 
	{ 0,   0, 0, 0x10, 1, 0x14, 0 + 2 },
 
	{ 0, 0xF, 0, 0x10, 1, 0x14, 4 + 2 },
 
	END(0)
 
};
 

	
 
static const WaterDrawTileStruct _shiplift_display_seq_3[] = {
 
	BEGIN(SPR_CANALS_BASE + 8),
 
	{   0, 0, 0, 1, 0x10, 0x14, SPR_CANALS_BASE + 9 + 0 + 3 },
 
	{ 0xF, 0, 0, 1, 0x10, 0x14, SPR_CANALS_BASE + 9 + 4 + 3 },
 
	BEGIN(3),
 
	{   0, 0, 0, 1, 0x10, 0x14, 0 + 3 },
 
	{ 0xF, 0, 0, 1, 0x10, 0x14, 4 + 3 },
 
	END(0)
 
};
 

	
 
static const WaterDrawTileStruct _shiplift_display_seq_0b[] = {
 
	BEGIN(0xFDD),
 
	{ 0,   0, 0, 0x10, 1, 0x14, SPR_CANALS_BASE + 9 + 8 + 1 },
 
	{ 0, 0xF, 0, 0x10, 1, 0x14, SPR_CANALS_BASE + 9 + 12 + 1 },
 
	{ 0,   0, 0, 0x10, 1, 0x14, 8 + 1 },
 
	{ 0, 0xF, 0, 0x10, 1, 0x14, 12 + 1 },
 
	END(0)
 
};
 

	
 
static const WaterDrawTileStruct _shiplift_display_seq_1b[] = {
 
	BEGIN(0xFDD),
 
	{   0, 0, 0, 0x1, 0x10, 0x14, SPR_CANALS_BASE + 9 + 8 },
 
	{ 0xF, 0, 0, 0x1, 0x10, 0x14, SPR_CANALS_BASE + 9 + 12 },
 
	{   0, 0, 0, 0x1, 0x10, 0x14, 8 },
 
	{ 0xF, 0, 0, 0x1, 0x10, 0x14, 12 },
 
	END(0)
 
};
 

	
 
static const WaterDrawTileStruct _shiplift_display_seq_2b[] = {
 
	BEGIN(0xFDD),
 
	{ 0,   0, 0, 0x10, 1, 0x14, SPR_CANALS_BASE + 9 + 8 + 2 },
 
	{ 0, 0xF, 0, 0x10, 1, 0x14, SPR_CANALS_BASE + 9 + 12 + 2 },
 
	{ 0,   0, 0, 0x10, 1, 0x14, 8 + 2 },
 
	{ 0, 0xF, 0, 0x10, 1, 0x14, 12 + 2 },
 
	END(0)
 
};
 

	
 
static const WaterDrawTileStruct _shiplift_display_seq_3b[] = {
 
	BEGIN(0xFDD),
 
	{   0, 0, 0, 1, 0x10, 0x14, SPR_CANALS_BASE + 9 + 8 + 3 },
 
	{ 0xF, 0, 0, 1, 0x10, 0x14, SPR_CANALS_BASE + 9 + 12 + 3 },
 
	{   0, 0, 0, 1, 0x10, 0x14, 8 + 3 },
 
	{ 0xF, 0, 0, 1, 0x10, 0x14, 12 + 3 },
 
	END(0)
 
};
 

	
 
static const WaterDrawTileStruct _shiplift_display_seq_0t[] = {
 
	BEGIN(0xFDD),
 
	{ 0,   0, 0, 0x10, 1, 0x14, SPR_CANALS_BASE + 9 + 16 + 1 },
 
	{ 0, 0xF, 0, 0x10, 1, 0x14, SPR_CANALS_BASE + 9 + 20 + 1 },
 
	{ 0,   0, 0, 0x10, 1, 0x14, 16 + 1 },
 
	{ 0, 0xF, 0, 0x10, 1, 0x14, 20 + 1 },
 
	END(8)
 
};
 

	
 
static const WaterDrawTileStruct _shiplift_display_seq_1t[] = {
 
	BEGIN(0xFDD),
 
	{   0, 0, 0, 0x1, 0x10, 0x14, SPR_CANALS_BASE + 9 + 16 },
 
	{ 0xF, 0, 0, 0x1, 0x10, 0x14, SPR_CANALS_BASE + 9 + 20 },
 
	{   0, 0, 0, 0x1, 0x10, 0x14, 16 },
 
	{ 0xF, 0, 0, 0x1, 0x10, 0x14, 20 },
 
	END(8)
 
};
 

	
 
static const WaterDrawTileStruct _shiplift_display_seq_2t[] = {
 
	BEGIN(0xFDD),
 
	{ 0,   0, 0, 0x10, 1, 0x14, SPR_CANALS_BASE + 9 + 16 + 2 },
 
	{ 0, 0xF, 0, 0x10, 1, 0x14, SPR_CANALS_BASE + 9 + 20 + 2 },
 
	{ 0,   0, 0, 0x10, 1, 0x14, 16 + 2 },
 
	{ 0, 0xF, 0, 0x10, 1, 0x14, 20 + 2 },
 
	END(8)
 
};
 

	
 
static const WaterDrawTileStruct _shiplift_display_seq_3t[] = {
 
	BEGIN(0xFDD),
 
	{   0, 0, 0, 1, 0x10, 0x14, SPR_CANALS_BASE + 9 + 16 + 3 },
 
	{ 0xF, 0, 0, 1, 0x10, 0x14, SPR_CANALS_BASE + 9 + 20 + 3 },
 
	{   0, 0, 0, 1, 0x10, 0x14, 16 + 3 },
 
	{ 0xF, 0, 0, 1, 0x10, 0x14, 20 + 3 },
 
	END(8)
 
};
 

	
src/water_cmd.cpp
Show inline comments
 
@@ -25,6 +25,7 @@
 
#include "train.h"
 
#include "water_map.h"
 
#include "newgrf.h"
 
#include "newgrf_canal.h"
 

	
 
static const SpriteID _water_shore_sprites[] = {
 
	0,
 
@@ -373,39 +374,43 @@ void DrawCanalWater(TileIndex tile)
 
{
 
	uint wa;
 

	
 
	/* Test for custom graphics, else use the default */
 
	SpriteID dikes_base = GetCanalSprite(CF_DIKES, tile);
 
	if (dikes_base == 0) dikes_base = SPR_CANALS_BASE + 57;
 

	
 
	/* determine the edges around with water. */
 
	wa = IsWateredTile(TILE_ADDXY(tile, -1, 0)) << 0;
 
	wa += IsWateredTile(TILE_ADDXY(tile, 0, 1)) << 1;
 
	wa += IsWateredTile(TILE_ADDXY(tile, 1, 0)) << 2;
 
	wa += IsWateredTile(TILE_ADDXY(tile, 0, -1)) << 3;
 

	
 
	if (!(wa & 1)) DrawGroundSprite(SPR_CANALS_BASE + 57, PAL_NONE);
 
	if (!(wa & 2)) DrawGroundSprite(SPR_CANALS_BASE + 58, PAL_NONE);
 
	if (!(wa & 4)) DrawGroundSprite(SPR_CANALS_BASE + 59, PAL_NONE);
 
	if (!(wa & 8)) DrawGroundSprite(SPR_CANALS_BASE + 60, PAL_NONE);
 
	if (!(wa & 1)) DrawGroundSprite(dikes_base,     PAL_NONE);
 
	if (!(wa & 2)) DrawGroundSprite(dikes_base + 1, PAL_NONE);
 
	if (!(wa & 4)) DrawGroundSprite(dikes_base + 2, PAL_NONE);
 
	if (!(wa & 8)) DrawGroundSprite(dikes_base + 3, PAL_NONE);
 

	
 
	/* right corner */
 
	switch (wa & 0x03) {
 
		case 0: DrawGroundSprite(SPR_CANALS_BASE + 57 + 4, PAL_NONE); break;
 
		case 3: if (!IsWateredTile(TILE_ADDXY(tile, -1, 1))) DrawGroundSprite(SPR_CANALS_BASE + 57 + 8, PAL_NONE); break;
 
		case 0: DrawGroundSprite(dikes_base + 4, PAL_NONE); break;
 
		case 3: if (!IsWateredTile(TILE_ADDXY(tile, -1, 1))) DrawGroundSprite(dikes_base + 8, PAL_NONE); break;
 
	}
 

	
 
	/* bottom corner */
 
	switch (wa & 0x06) {
 
		case 0: DrawGroundSprite(SPR_CANALS_BASE + 57 + 5, PAL_NONE); break;
 
		case 6: if (!IsWateredTile(TILE_ADDXY(tile, 1, 1))) DrawGroundSprite(SPR_CANALS_BASE + 57 + 9, PAL_NONE); break;
 
		case 0: DrawGroundSprite(dikes_base + 5, PAL_NONE); break;
 
		case 6: if (!IsWateredTile(TILE_ADDXY(tile, 1, 1))) DrawGroundSprite(dikes_base + 9, PAL_NONE); break;
 
	}
 

	
 
	/* left corner */
 
	switch (wa & 0x0C) {
 
		case  0: DrawGroundSprite(SPR_CANALS_BASE + 57 + 6, PAL_NONE); break;
 
		case 12: if (!IsWateredTile(TILE_ADDXY(tile, 1, -1))) DrawGroundSprite(SPR_CANALS_BASE + 57 + 10, PAL_NONE); break;
 
		case  0: DrawGroundSprite(dikes_base + 6, PAL_NONE); break;
 
		case 12: if (!IsWateredTile(TILE_ADDXY(tile, 1, -1))) DrawGroundSprite(dikes_base + 10, PAL_NONE); break;
 
	}
 

	
 
	/* upper corner */
 
	switch (wa & 0x09) {
 
		case 0: DrawGroundSprite(SPR_CANALS_BASE + 57 + 7, PAL_NONE); break;
 
		case 9: if (!IsWateredTile(TILE_ADDXY(tile, -1, -1))) DrawGroundSprite(SPR_CANALS_BASE + 57 + 11, PAL_NONE); break;
 
		case 0: DrawGroundSprite(dikes_base + 7, PAL_NONE); break;
 
		case 9: if (!IsWateredTile(TILE_ADDXY(tile, -1, -1))) DrawGroundSprite(dikes_base + 11, PAL_NONE); break;
 
	}
 
}
 

	
 
@@ -421,12 +426,30 @@ static void DrawWaterStuff(const TileInf
 
	SpriteID palette, uint base
 
)
 
{
 
	DrawGroundSprite(wdts++->image, PAL_NONE);
 
	SpriteID image;
 
	SpriteID water_base = GetCanalSprite(CF_WATERSLOPE, ti->tile);
 
	SpriteID locks_base = GetCanalSprite(CF_LOCKS, ti->tile);
 

	
 
	/* If no custom graphics, use defaults */
 
	if (water_base == 0) water_base = SPR_CANALS_BASE + 5;
 
	if (locks_base == 0) {
 
		locks_base = SPR_CANALS_BASE + 9;
 
	} else {
 
		/* If using custom graphics, ignore the variation on height */
 
		base = 0;
 
	}
 

	
 
	image = wdts++->image;
 
	if (image < 4) image += water_base;
 
	DrawGroundSprite(image, PAL_NONE);
 

	
 
	for (; wdts->delta_x != 0x80; wdts++) {
 
		SpriteID image = wdts->image + base;
 
		SpriteID image = wdts->image;
 
		SpriteID pal;
 

	
 
		if (image < 24) image += locks_base;
 
		image += base;
 

	
 
		if (HASBIT(_transparent_opt, TO_BUILDINGS)) {
 
			SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
 
			pal = PALETTE_TO_TRANSPARENT;
0 comments (0 inline, 0 general)