diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/newgrf.cpp | 104 |
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; |