(svn r22476) -Codechange: Deduplicate code for reading sprite layout sprites.

This commit is contained in:
frosch 2011-05-18 18:31:23 +00:00
parent 27e30521de
commit fae2477143
1 changed files with 42 additions and 62 deletions

View File

@ -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;