summaryrefslogtreecommitdiff
path: root/src/newgrf.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/newgrf.cpp')
-rw-r--r--src/newgrf.cpp104
1 files changed, 42 insertions, 62 deletions
diff --git a/src/newgrf.cpp b/src/newgrf.cpp
index 51002f721..0b0fe63b4 100644
--- a/src/newgrf.cpp
+++ b/src/newgrf.cpp
@@ -160,9 +160,9 @@ public:
return end - data;
}
- FORCEINLINE bool HasData() const
+ FORCEINLINE bool HasData(size_t count = 1) const
{
- return data < end;
+ return data + count <= end;
}
FORCEINLINE byte *Data()
@@ -479,6 +479,40 @@ static void MapSpriteMappingRecolour(PalSpriteID *grf_sprite)
}
/**
+ * Read a sprite and a palette from the GRF and convert them into a format
+ * suitable to OpenTTD.
+ * @param buf Input stream.
+ * @param invert_action1_flag Set to true, if palette bit 15 means 'not from action 1'.
+ * @param action1_offset Offset to add to action 1 sprites.
+ * @param action1_pitch Factor to multiply action 1 sprite indices with.
+ * @param action1_max Maximal valid action 1 index.
+ * @param [out] grf_sprite Read sprite and palette.
+ */
+static void ReadSpriteLayoutSprite(ByteReader *buf, bool invert_action1_flag, uint action1_offset, uint action1_pitch, uint action1_max, PalSpriteID *grf_sprite)
+{
+ grf_sprite->sprite = buf->ReadWord();
+ grf_sprite->pal = buf->ReadWord();
+
+ MapSpriteMappingRecolour(grf_sprite);
+
+ bool custom_sprite = HasBit(grf_sprite->pal, 15) != invert_action1_flag;
+ ClrBit(grf_sprite->pal, 15);
+ if (custom_sprite) {
+ /* Use sprite from Action 1 */
+ uint index = GB(grf_sprite->sprite, 0, 14);
+ if (action1_pitch == 0 || index >= action1_max) {
+ grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d", index);
+ grf_sprite->sprite = SPR_IMG_QUERY;
+ grf_sprite->pal = PAL_NONE;
+ } else {
+ SpriteID sprite = action1_offset + index * action1_pitch;
+ SB(grf_sprite->sprite, 0, SPRITE_WIDTH, sprite);
+ SetBit(grf_sprite->sprite, SPRITE_MODIFIER_CUSTOM_SPRITE);
+ }
+ }
+}
+
+/**
* Converts TTD(P) Base Price pointers into the enum used by OTTD
* See http://wiki.ttdpatch.net/tiki-index.php?page=BaseCosts
* @param base_pointer TTD(P) Base Price Pointer
@@ -1229,20 +1263,14 @@ static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, Byte
for (uint t = 0; t < statspec->tiles; t++) {
NewGRFSpriteLayout *dts = &statspec->renderdata[t];
- dts->ground.sprite = buf->ReadWord();
- dts->ground.pal = buf->ReadWord();
- if (dts->ground.sprite == 0 && dts->ground.pal == 0) {
+ if (buf->HasData(4) && *(uint32*)buf->Data() == 0) {
+ buf->Skip(4);
extern const DrawTileSprites _station_display_datas_rail[8];
dts->Clone(&_station_display_datas_rail[t % 8]);
continue;
}
- if (HasBit(dts->ground.pal, 15)) {
- /* Use sprite from Action 1 */
- ClrBit(dts->ground.pal, 15);
- SetBit(dts->ground.sprite, SPRITE_MODIFIER_CUSTOM_SPRITE);
- }
- MapSpriteMappingRecolour(&dts->ground);
+ ReadSpriteLayoutSprite(buf, false, 0, 1, UINT_MAX, &dts->ground);
static SmallVector<DrawTileSeqStruct, 8> tmp_layout;
tmp_layout.Clear();
@@ -1258,17 +1286,8 @@ static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, Byte
dtss->size_x = buf->ReadByte();
dtss->size_y = buf->ReadByte();
dtss->size_z = buf->ReadByte();
- dtss->image.sprite = buf->ReadWord();
- dtss->image.pal = buf->ReadWord();
- if (HasBit(dtss->image.pal, 15)) {
- ClrBit(dtss->image.pal, 15);
- } else {
- /* Use sprite from Action 1 (yes, this is inverse to above) */
- SetBit(dtss->image.sprite, SPRITE_MODIFIER_CUSTOM_SPRITE);
- }
-
- MapSpriteMappingRecolour(&dtss->image);
+ ReadSpriteLayoutSprite(buf, true, 0, 1, UINT_MAX, &dtss->image);
}
dts->Clone(tmp_layout.Begin());
}
@@ -3952,55 +3971,16 @@ static void NewSpriteGroup(ByteReader *buf)
group->num_building_stages = max((uint8)1, num_spriteset_ents);
/* Groundsprite */
- group->dts.ground.sprite = buf->ReadWord();
- group->dts.ground.pal = buf->ReadWord();
-
- /* Remap transparent/colour modifier bits */
- MapSpriteMappingRecolour(&group->dts.ground);
-
- if (HasBit(group->dts.ground.pal, 15)) {
- /* Bit 31 set means this is a custom sprite, so rewrite it to the
- * last spriteset defined. */
- uint spriteset = GB(group->dts.ground.sprite, 0, 14);
- if (num_spriteset_ents == 0 || spriteset >= num_spritesets) {
- grfmsg(1, "NewSpriteGroup: Spritelayout uses undefined custom spriteset %d", spriteset);
- group->dts.ground.sprite = SPR_IMG_QUERY;
- group->dts.ground.pal = PAL_NONE;
- } else {
- SpriteID sprite = _cur_grffile->spriteset_start + spriteset * num_spriteset_ents;
- SB(group->dts.ground.sprite, 0, SPRITE_WIDTH, sprite);
- ClrBit(group->dts.ground.pal, 15);
- SetBit(group->dts.ground.sprite, SPRITE_MODIFIER_CUSTOM_SPRITE);
- }
- }
+ ReadSpriteLayoutSprite(buf, false, _cur_grffile->spriteset_start, num_spriteset_ents, num_spritesets, &group->dts.ground);
group->dts.Allocate(num_building_sprites);
for (i = 0; i < num_building_sprites; i++) {
DrawTileSeqStruct *seq = const_cast<DrawTileSeqStruct*>(&group->dts.seq[i]);
- seq->image.sprite = buf->ReadWord();
- seq->image.pal = buf->ReadWord();
+ ReadSpriteLayoutSprite(buf, false, _cur_grffile->spriteset_start, num_spriteset_ents, num_spritesets, &seq->image);
seq->delta_x = buf->ReadByte();
seq->delta_y = buf->ReadByte();
- MapSpriteMappingRecolour(&seq->image);
-
- if (HasBit(seq->image.pal, 15)) {
- /* Bit 31 set means this is a custom sprite, so rewrite it to the
- * last spriteset defined. */
- uint spriteset = GB(seq->image.sprite, 0, 14);
- if (num_spriteset_ents == 0 || spriteset >= num_spritesets) {
- grfmsg(1, "NewSpriteGroup: Spritelayout uses undefined custom spriteset %d", spriteset);
- seq->image.sprite = SPR_IMG_QUERY;
- seq->image.pal = PAL_NONE;
- } else {
- SpriteID sprite = _cur_grffile->spriteset_start + spriteset * num_spriteset_ents;
- SB(seq->image.sprite, 0, SPRITE_WIDTH, sprite);
- ClrBit(seq->image.pal, 15);
- SetBit(seq->image.sprite, SPRITE_MODIFIER_CUSTOM_SPRITE);
- }
- }
-
if (type > 0) {
seq->delta_z = buf->ReadByte();
if (!seq->IsParentSprite()) continue;