forked from mirror/OpenTTD
(svn r22924) -Codechange: Enhance NewGRFSpriteLayout for drawing construction stages in spritelayouts with inconsistent number of sprites per spriteset.
This commit is contained in:
@@ -607,9 +607,11 @@ static void MapSpriteMappingRecolour(PalSpriteID *grf_sprite)
|
||||
* @param use_cur_spritesets Whether to use currently referenceable action 1 sets.
|
||||
* @param feature GrfSpecFeature to use spritesets from.
|
||||
* @param [out] grf_sprite Read sprite and palette.
|
||||
* @param [out] max_sprite_offset Optionally returns the number of sprites in the spriteset of the sprite. (0 if no spritset)
|
||||
* @param [out] max_palette_offset Optionally returns the number of sprites in the spriteset of the palette. (0 if no spritset)
|
||||
* @return Read TileLayoutFlags.
|
||||
*/
|
||||
static TileLayoutFlags ReadSpriteLayoutSprite(ByteReader *buf, bool read_flags, bool invert_action1_flag, bool use_cur_spritesets, byte feature, PalSpriteID *grf_sprite)
|
||||
static TileLayoutFlags ReadSpriteLayoutSprite(ByteReader *buf, bool read_flags, bool invert_action1_flag, bool use_cur_spritesets, int feature, PalSpriteID *grf_sprite, uint16 *max_sprite_offset = NULL, uint16 *max_palette_offset = NULL)
|
||||
{
|
||||
grf_sprite->sprite = buf->ReadWord();
|
||||
grf_sprite->pal = buf->ReadWord();
|
||||
@@ -628,6 +630,7 @@ static TileLayoutFlags ReadSpriteLayoutSprite(ByteReader *buf, bool read_flags,
|
||||
grf_sprite->pal = PAL_NONE;
|
||||
} else {
|
||||
SpriteID sprite = use_cur_spritesets ? _cur.GetSprite(feature, index) : index;
|
||||
if (max_sprite_offset != NULL) *max_sprite_offset = use_cur_spritesets ? _cur.GetNumEnts(feature, index) : UINT16_MAX;
|
||||
SB(grf_sprite->sprite, 0, SPRITE_WIDTH, sprite);
|
||||
SetBit(grf_sprite->sprite, SPRITE_MODIFIER_CUSTOM_SPRITE);
|
||||
}
|
||||
@@ -645,6 +648,7 @@ static TileLayoutFlags ReadSpriteLayoutSprite(ByteReader *buf, bool read_flags,
|
||||
grf_sprite->pal = PAL_NONE;
|
||||
} else {
|
||||
SpriteID sprite = use_cur_spritesets ? _cur.GetSprite(feature, index) : index;
|
||||
if (max_palette_offset != NULL) *max_palette_offset = use_cur_spritesets ? _cur.GetNumEnts(feature, index) : UINT16_MAX;
|
||||
SB(grf_sprite->pal, 0, SPRITE_WIDTH, sprite);
|
||||
SetBit(grf_sprite->pal, SPRITE_MODIFIER_CUSTOM_SPRITE);
|
||||
}
|
||||
@@ -726,8 +730,13 @@ static bool ReadSpriteLayout(ByteReader *buf, uint num_building_sprites, bool us
|
||||
if (!allow_var10) valid_flags &= ~TLF_VAR10_FLAGS;
|
||||
dts->Allocate(num_building_sprites); // allocate before reading groundsprite flags
|
||||
|
||||
uint16 *max_sprite_offset = AllocaM(uint16, num_building_sprites + 1);
|
||||
uint16 *max_palette_offset = AllocaM(uint16, num_building_sprites + 1);
|
||||
MemSetT(max_sprite_offset, 0, num_building_sprites + 1);
|
||||
MemSetT(max_palette_offset, 0, num_building_sprites + 1);
|
||||
|
||||
/* Groundsprite */
|
||||
TileLayoutFlags flags = ReadSpriteLayoutSprite(buf, has_flags, false, use_cur_spritesets, feature, &dts->ground);
|
||||
TileLayoutFlags flags = ReadSpriteLayoutSprite(buf, has_flags, false, use_cur_spritesets, feature, &dts->ground, max_sprite_offset, max_palette_offset);
|
||||
if (_cur.skip_sprites < 0) return true;
|
||||
|
||||
if (flags & ~(valid_flags & ~TLF_NON_GROUND_FLAGS)) {
|
||||
@@ -742,7 +751,7 @@ static bool ReadSpriteLayout(ByteReader *buf, uint num_building_sprites, bool us
|
||||
for (uint i = 0; i < num_building_sprites; i++) {
|
||||
DrawTileSeqStruct *seq = const_cast<DrawTileSeqStruct*>(&dts->seq[i]);
|
||||
|
||||
flags = ReadSpriteLayoutSprite(buf, has_flags, false, use_cur_spritesets, feature, &seq->image);
|
||||
flags = ReadSpriteLayoutSprite(buf, has_flags, false, use_cur_spritesets, feature, &seq->image, max_sprite_offset + i + 1, max_palette_offset + i + 1);
|
||||
if (_cur.skip_sprites < 0) return true;
|
||||
|
||||
if (flags & ~valid_flags) {
|
||||
@@ -766,6 +775,42 @@ static bool ReadSpriteLayout(ByteReader *buf, uint num_building_sprites, bool us
|
||||
if (_cur.skip_sprites < 0) return true;
|
||||
}
|
||||
|
||||
/* Check if the number of sprites per spriteset is consistent */
|
||||
bool is_consistent = true;
|
||||
dts->consistent_max_offset = 0;
|
||||
for (uint i = 0; i < num_building_sprites + 1; i++) {
|
||||
if (max_sprite_offset[i] > 0) {
|
||||
if (dts->consistent_max_offset == 0) {
|
||||
dts->consistent_max_offset = max_sprite_offset[i];
|
||||
} else if (dts->consistent_max_offset != max_sprite_offset[i]) {
|
||||
is_consistent = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (max_palette_offset[i] > 0) {
|
||||
if (dts->consistent_max_offset == 0) {
|
||||
dts->consistent_max_offset = max_palette_offset[i];
|
||||
} else if (dts->consistent_max_offset != max_palette_offset[i]) {
|
||||
is_consistent = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* When the Action1 sets are unknown, everything should be 0 (no spriteset usage) or UINT16_MAX (some spriteset usage) */
|
||||
assert(use_cur_spritesets || (is_consistent && (dts->consistent_max_offset == 0 || dts->consistent_max_offset == UINT16_MAX)));
|
||||
|
||||
if (!is_consistent || dts->registers != NULL) {
|
||||
dts->consistent_max_offset = 0;
|
||||
if (dts->registers == NULL) dts->AllocateRegisters();
|
||||
|
||||
for (uint i = 0; i < num_building_sprites + 1; i++) {
|
||||
TileLayoutRegisters ®s = const_cast<TileLayoutRegisters&>(dts->registers[i]);
|
||||
regs.max_sprite_offset = max_sprite_offset[i];
|
||||
regs.max_palette_offset = max_palette_offset[i];
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1584,6 +1629,7 @@ static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, Byte
|
||||
|
||||
for (uint t = 0; t < statspec->tiles; t++) {
|
||||
NewGRFSpriteLayout *dts = &statspec->renderdata[t];
|
||||
dts->consistent_max_offset = UINT16_MAX; // Spritesets are unknown, so no limit.
|
||||
|
||||
if (buf->HasData(4) && *(uint32*)buf->Data() == 0) {
|
||||
buf->Skip(4);
|
||||
@@ -4403,13 +4449,6 @@ static void NewSpriteGroup(ByteReader *buf)
|
||||
assert(TileLayoutSpriteGroup::CanAllocateItem());
|
||||
TileLayoutSpriteGroup *group = new TileLayoutSpriteGroup();
|
||||
act_group = group;
|
||||
/* num_building_stages should be 1, if we are only using non-custom sprites */
|
||||
if (_cur.HasValidSpriteSets(feature)) {
|
||||
/* This assumes that all spritesets have the same number of sprites. */
|
||||
group->num_building_stages = max(1u, _cur.GetNumEnts(feature, 0));
|
||||
} else {
|
||||
group->num_building_stages = 1;
|
||||
}
|
||||
|
||||
/* On error, bail out immediately. Temporary GRF data was already freed */
|
||||
if (ReadSpriteLayout(buf, num_building_sprites, true, feature, false, type == 0, &group->dts)) return;
|
||||
|
Reference in New Issue
Block a user