mirror of https://github.com/OpenTTD/OpenTTD
(svn r610) -newgrf: Support for some basic deterministical spritegroups regarding stations. Waypoints look changes based on year now :^) (pasky).
parent
c2193ce1a8
commit
ec434b208e
|
@ -13,7 +13,7 @@ CFILES = ai.c aircraft_cmd.c aircraft_gui.c airport_gui.c
|
||||||
train_cmd.c train_gui.c tree_cmd.c ttd.c
|
train_cmd.c train_gui.c tree_cmd.c ttd.c
|
||||||
tunnelbridge_cmd.c unmovable_cmd.c vehicle.c
|
tunnelbridge_cmd.c unmovable_cmd.c vehicle.c
|
||||||
viewport.c water_cmd.c widget.c window.c screenshot.c
|
viewport.c water_cmd.c widget.c window.c screenshot.c
|
||||||
airport.c grfspecial.c terraform_gui.c ;
|
airport.c grfspecial.c terraform_gui.c sprite.c ;
|
||||||
|
|
||||||
|
|
||||||
LANGFILES = english.txt swedish.txt french.txt german.txt italian.txt slovak.txt hungarian.txt norwegian.txt danish.txt czech.txt galician.txt polish.txt romanian.txt;
|
LANGFILES = english.txt swedish.txt french.txt german.txt italian.txt slovak.txt hungarian.txt norwegian.txt danish.txt czech.txt galician.txt polish.txt romanian.txt;
|
||||||
|
|
2
Makefile
2
Makefile
|
@ -504,7 +504,7 @@ ttd_SOURCES = \
|
||||||
pathfind.c player_gui.c players.c queue.c rail_cmd.c rail_gui.c rev.c \
|
pathfind.c player_gui.c players.c queue.c rail_cmd.c rail_gui.c rev.c \
|
||||||
road_cmd.c road_gui.c roadveh_cmd.c roadveh_gui.c saveload.c \
|
road_cmd.c road_gui.c roadveh_cmd.c roadveh_gui.c saveload.c \
|
||||||
screenshot.c settings.c settings_gui.c ship_cmd.c ship_gui.c \
|
screenshot.c settings.c settings_gui.c ship_cmd.c ship_gui.c \
|
||||||
smallmap_gui.c sound.c spritecache.c station_cmd.c station_gui.c \
|
smallmap_gui.c sound.c sprite.c spritecache.c station_cmd.c station_gui.c \
|
||||||
strings.c subsidy_gui.c terraform_gui.c texteff.c town_cmd.c \
|
strings.c subsidy_gui.c terraform_gui.c texteff.c town_cmd.c \
|
||||||
town_gui.c train_cmd.c train_gui.c tree_cmd.c ttd.c tunnelbridge_cmd.c \
|
town_gui.c train_cmd.c train_gui.c tree_cmd.c ttd.c tunnelbridge_cmd.c \
|
||||||
unmovable_cmd.c vehicle.c vehicle_gui.c viewport.c water_cmd.c widget.c window.c \
|
unmovable_cmd.c vehicle.c vehicle_gui.c viewport.c water_cmd.c widget.c window.c \
|
||||||
|
|
|
@ -1112,8 +1112,8 @@ static void NewSpriteGroup(byte *buf, int len)
|
||||||
/* XXX: If multiple surreal sets attach a surreal
|
/* XXX: If multiple surreal sets attach a surreal
|
||||||
* set this way, we are in trouble. */
|
* set this way, we are in trouble. */
|
||||||
dg->ranges[i].group = _cur_grffile->spritegroups[setid];
|
dg->ranges[i].group = _cur_grffile->spritegroups[setid];
|
||||||
dg->ranges[i].range_low = grf_load_byte(&buf);
|
dg->ranges[i].low = grf_load_byte(&buf);
|
||||||
dg->ranges[i].range_high = grf_load_byte(&buf);
|
dg->ranges[i].high = grf_load_byte(&buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
dg->default_group = malloc(sizeof(*dg->default_group));
|
dg->default_group = malloc(sizeof(*dg->default_group));
|
||||||
|
|
20
rail_cmd.c
20
rail_cmd.c
|
@ -744,6 +744,7 @@ int32 CmdBuildTrainWaypoint(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||||
|
|
||||||
cp->deleted = 0;
|
cp->deleted = 0;
|
||||||
cp->xy = tile;
|
cp->xy = tile;
|
||||||
|
cp->build_date = _date;
|
||||||
|
|
||||||
if (cp->town_or_string == 0) MakeDefaultWaypointName(cp); else RedrawWaypointSign(cp);
|
if (cp->town_or_string == 0) MakeDefaultWaypointName(cp); else RedrawWaypointSign(cp);
|
||||||
UpdateWaypointSign(cp);
|
UpdateWaypointSign(cp);
|
||||||
|
@ -1427,6 +1428,22 @@ static void DrawSpecialBuilding(uint32 image, uint32 tracktype_offs,
|
||||||
AddSortableSpriteToDraw(image, ti->x + x, ti->y + y, xsize, ysize, zsize, ti->z + z);
|
AddSortableSpriteToDraw(image, ti->x + x, ti->y + y, xsize, ysize, zsize, ti->z + z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This hacks together some dummy one-shot Station structure for a waypoint. */
|
||||||
|
static Station *ComposeWaypointStation(uint tile)
|
||||||
|
{
|
||||||
|
Waypoint *waypt = &_waypoints[GetWaypointByTile(tile)];
|
||||||
|
static Station stat;
|
||||||
|
|
||||||
|
stat.train_tile = stat.xy = waypt->xy;
|
||||||
|
/* FIXME - We should always keep town. */
|
||||||
|
stat.town = waypt->town_or_string & 0xC000 ? &_towns[waypt->town_or_string & 0xFF] : NULL;
|
||||||
|
stat.string_id = waypt->town_or_string & 0xC000 ? /* FIXME? */ 0 : waypt->town_or_string;
|
||||||
|
stat.build_date = waypt->build_date;
|
||||||
|
stat.class_id = 6; stat.stat_id = waypt->stat_id;
|
||||||
|
|
||||||
|
return &stat;
|
||||||
|
}
|
||||||
|
|
||||||
static void DrawTile_Track(TileInfo *ti)
|
static void DrawTile_Track(TileInfo *ti)
|
||||||
{
|
{
|
||||||
uint32 tracktype_offs, image;
|
uint32 tracktype_offs, image;
|
||||||
|
@ -1551,8 +1568,7 @@ static void DrawTile_Track(TileInfo *ti)
|
||||||
DrawTileSeqStruct const *seq;
|
DrawTileSeqStruct const *seq;
|
||||||
// emulate station tile - open with building
|
// emulate station tile - open with building
|
||||||
DrawTileSprites *cust = &stat->renderdata[2 + (m5 & 0x1)];
|
DrawTileSprites *cust = &stat->renderdata[2 + (m5 & 0x1)];
|
||||||
/* FIXME: NULL Station! --pasky */
|
uint32 relocation = GetCustomStationRelocation(stat, ComposeWaypointStation(ti->tile), 0);
|
||||||
uint32 relocation = GetCustomStationRelocation(stat, NULL, 0);
|
|
||||||
|
|
||||||
image = cust->ground_sprite;
|
image = cust->ground_sprite;
|
||||||
if (image & 0x8000) image = (image & 0x7FFF) + tracktype_offs;
|
if (image & 0x8000) image = (image & 0x7FFF) + tracktype_offs;
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
#include "stdafx.h"
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include "ttd.h"
|
||||||
|
#include "sprite.h"
|
||||||
|
|
||||||
|
|
||||||
|
struct SpriteGroup *EvalDeterministicSpriteGroup(struct DeterministicSpriteGroup *dsg, int value)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
value >>= dsg->shift_num; // This should bring us to the byte range.
|
||||||
|
value &= dsg->and_mask;
|
||||||
|
|
||||||
|
if (dsg->operation != DSG_OP_NONE)
|
||||||
|
value += (signed char) dsg->add_val;
|
||||||
|
|
||||||
|
switch (dsg->operation) {
|
||||||
|
case DSG_OP_DIV:
|
||||||
|
value /= (signed char) dsg->divmod_val;
|
||||||
|
break;
|
||||||
|
case DSG_OP_MOD:
|
||||||
|
value %= (signed char) dsg->divmod_val;
|
||||||
|
break;
|
||||||
|
case DSG_OP_NONE:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < dsg->num_ranges; i++) {
|
||||||
|
struct DeterministicSpriteGroupRange *range = &dsg->ranges[i];
|
||||||
|
|
||||||
|
if (range->low <= value && value <= range->high)
|
||||||
|
return &range->group;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dsg->default_group;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetDeterministicSpriteValue(byte var)
|
||||||
|
{
|
||||||
|
switch (var) {
|
||||||
|
case 0x00:
|
||||||
|
return _date;
|
||||||
|
case 0x01:
|
||||||
|
return _cur_year;
|
||||||
|
case 0x02:
|
||||||
|
return _cur_month;
|
||||||
|
case 0x03:
|
||||||
|
return _opt.landscape;
|
||||||
|
case 0x09:
|
||||||
|
return _date_fract;
|
||||||
|
case 0x0A:
|
||||||
|
return _tick_counter;
|
||||||
|
case 0x0C:
|
||||||
|
/* If we got here, it means there was no callback or
|
||||||
|
* callbacks aren't supported on our callpath. */
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
14
sprite.h
14
sprite.h
|
@ -76,7 +76,7 @@ struct DeterministicSpriteGroup {
|
||||||
|
|
||||||
// And apply it to this:
|
// And apply it to this:
|
||||||
byte num_ranges;
|
byte num_ranges;
|
||||||
struct DeterministicSpriteGroupRanges *ranges; // Dynamically allocated
|
struct DeterministicSpriteGroupRange *ranges; // Dynamically allocated
|
||||||
|
|
||||||
// Dynamically allocated, this is the sole owner
|
// Dynamically allocated, this is the sole owner
|
||||||
struct SpriteGroup *default_group;
|
struct SpriteGroup *default_group;
|
||||||
|
@ -95,16 +95,22 @@ struct SpriteGroup {
|
||||||
} g;
|
} g;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DeterministicSpriteGroupRanges {
|
struct DeterministicSpriteGroupRange {
|
||||||
struct SpriteGroup group;
|
struct SpriteGroup group;
|
||||||
byte range_low;
|
byte low;
|
||||||
byte range_high;
|
byte high;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* This is a temporary helper for SpriteGroup users not supporting variational
|
/* This is a temporary helper for SpriteGroup users not supporting variational
|
||||||
* sprite groups yet - it just traverses those cowardly, always taking the
|
* sprite groups yet - it just traverses those cowardly, always taking the
|
||||||
* default choice until it hits a real sprite group, returning it. */
|
* default choice until it hits a real sprite group, returning it. */
|
||||||
static struct RealSpriteGroup *TriviallyGetRSG(struct SpriteGroup *sg);
|
static struct RealSpriteGroup *TriviallyGetRSG(struct SpriteGroup *sg);
|
||||||
|
/* This takes value (probably of the variable specified in the group) and
|
||||||
|
* chooses corresponding SpriteGroup accordingly to the given
|
||||||
|
* DeterministicSpriteGroup. */
|
||||||
|
struct SpriteGroup *EvalDeterministicSpriteGroup(struct DeterministicSpriteGroup *dsg, int value);
|
||||||
|
/* Get value of a common deterministic SpriteGroup variable. */
|
||||||
|
int GetDeterministicSpriteValue(byte var);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1006,15 +1006,81 @@ struct StationSpec *GetCustomStation(uint32 classid, byte stid)
|
||||||
return &_waypoint_data[stid];
|
return &_waypoint_data[stid];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct RealSpriteGroup *
|
||||||
|
ResolveStationSpriteGroup(struct SpriteGroup *spritegroup, struct Station *stat)
|
||||||
|
{
|
||||||
|
switch (spritegroup->type) {
|
||||||
|
case SGT_REAL:
|
||||||
|
return &spritegroup->g.real;
|
||||||
|
|
||||||
|
case SGT_DETERMINISTIC: {
|
||||||
|
struct DeterministicSpriteGroup *dsg = &spritegroup->g.determ;
|
||||||
|
struct SpriteGroup *target;
|
||||||
|
int value = -1;
|
||||||
|
|
||||||
|
if ((dsg->variable >> 6) == 0) {
|
||||||
|
/* General property */
|
||||||
|
value = GetDeterministicSpriteValue(dsg->variable);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
/* Station-specific property. */
|
||||||
|
if (dsg->var_scope == VSG_SCOPE_PARENT) {
|
||||||
|
/* TODO: Town structure. */
|
||||||
|
|
||||||
|
} else /* VSG_SELF */ {
|
||||||
|
if (dsg->variable == 0x40
|
||||||
|
|| dsg->variable == 0x41) {
|
||||||
|
/* FIXME: This is ad hoc only
|
||||||
|
* for waypoints. */
|
||||||
|
value = 0x01010000;
|
||||||
|
} else {
|
||||||
|
/* TODO: Only small fraction done. */
|
||||||
|
// 0x80 + offset - 0x10
|
||||||
|
switch (dsg->variable - 0x70) {
|
||||||
|
case 0x80:
|
||||||
|
if (stat) value = stat->facilities;
|
||||||
|
break;
|
||||||
|
case 0x81:
|
||||||
|
if (stat) value = stat->airport_type;
|
||||||
|
break;
|
||||||
|
case 0x82:
|
||||||
|
if (stat) value = stat->truck_stop_status;
|
||||||
|
break;
|
||||||
|
case 0x83:
|
||||||
|
if (stat) value = stat->bus_stop_status;
|
||||||
|
break;
|
||||||
|
case 0x86:
|
||||||
|
if (stat) value = stat->airport_flags & 0xFFFF;
|
||||||
|
break;
|
||||||
|
case 0x87:
|
||||||
|
if (stat) value = (stat->airport_flags >> 8) & 0xFF;
|
||||||
|
break;
|
||||||
|
case 0x8A:
|
||||||
|
if (stat) value = stat->build_date;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
target = value != -1 ? EvalDeterministicSpriteGroup(dsg, value) : dsg->default_group;
|
||||||
|
return ResolveStationSpriteGroup(target, stat);
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
case SGT_RANDOM:
|
||||||
|
error("I don't know how to handle random spritegroups yet!");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint32 GetCustomStationRelocation(struct StationSpec *spec, struct Station *stat, byte ctype)
|
uint32 GetCustomStationRelocation(struct StationSpec *spec, struct Station *stat, byte ctype)
|
||||||
{
|
{
|
||||||
struct RealSpriteGroup *rsg;
|
struct RealSpriteGroup *rsg;
|
||||||
|
|
||||||
assert(spec->classid == 'WAYP');
|
assert(spec->classid == 'WAYP');
|
||||||
|
|
||||||
/* In the future, variational spritegroups will kick in through this
|
rsg = ResolveStationSpriteGroup(&spec->spritegroup[ctype], stat);
|
||||||
* accessor, using @stat. */
|
|
||||||
rsg = TriviallyGetRSG(&spec->spritegroup[ctype]);
|
|
||||||
|
|
||||||
if (rsg->sprites_per_set != 0) {
|
if (rsg->sprites_per_set != 0) {
|
||||||
if (rsg->loading_count != 0) {
|
if (rsg->loading_count != 0) {
|
||||||
|
|
|
@ -752,6 +752,9 @@
|
||||||
BasicRuntimeChecks="3"/>
|
BasicRuntimeChecks="3"/>
|
||||||
</FileConfiguration>
|
</FileConfiguration>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\sprite.c">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="spritecache.c">
|
RelativePath="spritecache.c">
|
||||||
<FileConfiguration
|
<FileConfiguration
|
||||||
|
|
Loading…
Reference in New Issue