|
|
|
@ -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()
|
|
|
|
@ -478,6 +478,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
|
|
|
|
@ -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;
|
|
|
|
|