changeset 17696:da0307478527 draft

(svn r22476) -Codechange: Deduplicate code for reading sprite layout sprites.
author frosch <frosch@openttd.org>
date Wed, 18 May 2011 18:31:23 +0000
parents 05cd0d7611d8
children a968e3a43dfd
files src/newgrf.cpp
diffstat 1 files changed, 44 insertions(+), 64 deletions(-) [+]
line wrap: on
line diff
--- a/src/newgrf.cpp
+++ b/src/newgrf.cpp
@@ -160,9 +160,9 @@
 		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 @@
 }
 
 /**
+ * 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 @@
 				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 @@
 						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 @@
 					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;