(svn r11152) -Fix: GetIndustryIDAtOffset crashed when translation of the GFX ID would be needed. Fix by Belugas.
authorrubidium
Sun, 23 Sep 2007 19:55:42 +0000
changeset 7622 12388e4d86bb
parent 7621 09824471f144
child 7623 2841df003253
(svn r11152) -Fix: GetIndustryIDAtOffset crashed when translation of the GFX ID would be needed. Fix by Belugas.
-Fix: GetIndustryIDAtOffset crashed when the industry->xy tile was not an industry tile.
src/industry_map.h
src/newgrf_industries.cpp
src/newgrf_industries.h
src/newgrf_industrytiles.cpp
--- a/src/industry_map.h	Sun Sep 23 19:27:35 2007 +0000
+++ b/src/industry_map.h	Sun Sep 23 19:55:42 2007 +0000
@@ -124,6 +124,12 @@
 	SB(_m[tile].m1, 0, 2, value);
 }
 
+static inline IndustryGfx GetCleanIndustryGfx(TileIndex t)
+{
+	assert(IsTileType(t, MP_INDUSTRY));
+	return _m[t].m5 | (GB(_m[t].m6, 2, 1) << 8);
+}
+
 /**
  * Get the industry graphics ID for the given industry tile
  * @param t the tile to get the gfx for
@@ -133,7 +139,7 @@
 static inline IndustryGfx GetIndustryGfx(TileIndex t)
 {
 	assert(IsTileType(t, MP_INDUSTRY));
-	return GetTranslatedIndustryTileID(_m[t].m5 | (GB(_m[t].m6, 2, 1) << 8));
+	return GetTranslatedIndustryTileID(GetCleanIndustryGfx(t));
 }
 
 /**
@@ -145,7 +151,8 @@
 static inline void SetIndustryGfx(TileIndex t, IndustryGfx gfx)
 {
 	assert(IsTileType(t, MP_INDUSTRY));
-	_m[t].m5 = gfx;
+	_m[t].m5 = GB(gfx, 0, 8);
+	SB(_m[t].m6, 2, 1, GB(gfx, 8, 1));
 }
 
 /**
--- a/src/newgrf_industries.cpp	Sun Sep 23 19:27:35 2007 +0000
+++ b/src/newgrf_industries.cpp	Sun Sep 23 19:55:42 2007 +0000
@@ -78,47 +78,44 @@
 
 /** Make an analysis of a tile and check for its belonging to the same
  * industry, and/or the same grf file
- * @param new_tile TileIndex of the tile to query
- * @param old_tile TileIndex of the reference tile
- * @param i Industry to which old_tile belongs to
+ * @param tile TileIndex of the tile to query
+ * @param i Industry to which to compare the tile to
  * @return value encoded as per NFO specs */
-uint32 GetIndustryIDAtOffset(TileIndex new_tile, TileIndex old_tile, const Industry *i)
+uint32 GetIndustryIDAtOffset(TileIndex tile, const Industry *i)
 {
-	if (IsTileType(new_tile, MP_INDUSTRY)) {  // Is this an industry tile?
-
-		if (GetIndustryIndex(new_tile) == i->index) {  // Does it belong to the same industry?
-			IndustryGfx gfx = GetIndustryGfx(new_tile);
-			const IndustryTileSpec *indtsp = GetIndustryTileSpec(gfx);
-			const IndustryTileSpec *indold = GetIndustryTileSpec(GetIndustryGfx(old_tile));
+	if (!IsTileType(tile, MP_INDUSTRY) || GetIndustryIndex(tile) == i->index) {
+		/* No industry and/or the tile does not have the same industry as the one we match it with */
+		return 0xFFFF;
+	}
 
-			if (gfx < NEW_INDUSTRYOFFSET) {  // Does it belongs to an old type?
-				/* It is an old tile.  We have to see if it's been overriden */
-				if (indtsp->grf_prop.override == INVALID_INDUSTRYTILE) {  // has it been overridden?
-					return 0xFF << 8 | gfx; // no. Tag FF + the gfx id of that tile
-				} else { // yes.  FInd out if it is from the same grf file or not
-					const IndustryTileSpec *old_tile_ovr = GetIndustryTileSpec(indtsp->grf_prop.override);
+	IndustryGfx gfx = GetCleanIndustryGfx(tile);
+	const IndustryTileSpec *indtsp = GetIndustryTileSpec(gfx);
+	const IndustrySpec *indold = GetIndustrySpec(i->type);
 
-					if (old_tile_ovr->grf_prop.grffile->grfid == indold->grf_prop.grffile->grfid) {
-						return old_tile_ovr->grf_prop.local_id; // same grf file
-					} else {
-						return 0xFFFE; // not the same grf file
-					}
-				}
-			} else {
-				if (indtsp->grf_prop.spritegroup != NULL) {  // tile has a spritegroup ?
-					if (indtsp->grf_prop.grffile->grfid == indold->grf_prop.grffile->grfid) {  // same industry, same grf ?
-						return indtsp->grf_prop.local_id;
-					} else {
-						return 0xFFFE;  // Defined in another grf file
-					}
-				} else {  // tile has no spritegroup
-					return 0xFF << 8 | indtsp->grf_prop.subst_id;  // so just give him the substitute
-				}
-			}
+	if (gfx < NEW_INDUSTRYOFFSET) { // Does it belongs to an old type?
+		/* It is an old tile.  We have to see if it's been overriden */
+		if (indtsp->grf_prop.override == INVALID_INDUSTRYTILE) { // has it been overridden?
+			return 0xFF << 8 | gfx; // no. Tag FF + the gfx id of that tile
+		}
+		/* Not overriden */
+		const IndustryTileSpec *tile_ovr = GetIndustryTileSpec(indtsp->grf_prop.override);
+
+		if (tile_ovr->grf_prop.grffile->grfid == indold->grf_prop.grffile->grfid) {
+			return tile_ovr->grf_prop.local_id; // same grf file
+		} else {
+			return 0xFFFE; // not the same grf file
 		}
 	}
-
-	return 0xFFFF; // tile is not an industry one or  does not belong to the current industry
+	/* Not an 'old type' tile */
+	if (indtsp->grf_prop.spritegroup != NULL) { // tile has a spritegroup ?
+		if (indtsp->grf_prop.grffile->grfid == indold->grf_prop.grffile->grfid) { // same industry, same grf ?
+			return indtsp->grf_prop.local_id;
+		} else {
+			return 0xFFFE; // Defined in another grf file
+		}
+	}
+	/* The tile has no spritegroup */
+	return 0xFF << 8 | indtsp->grf_prop.subst_id; // so just give him the substitute
 }
 
 static uint32 GetClosestIndustry(TileIndex tile, IndustryType type, const Industry *current)
@@ -215,7 +212,7 @@
 		case 0x44: return industry->selected_layout;
 
 		/* Get industry ID at offset param */
-		case 0x60: return GetIndustryIDAtOffset(GetNearbyTile(parameter, industry->xy), tile, industry);
+		case 0x60: return GetIndustryIDAtOffset(GetNearbyTile(parameter, industry->xy), industry);
 
 		/* Get random tile bits at offset param */
 		case 0x61:
--- a/src/newgrf_industries.h	Sun Sep 23 19:27:35 2007 +0000
+++ b/src/newgrf_industries.h	Sun Sep 23 19:55:42 2007 +0000
@@ -21,7 +21,7 @@
 /* in newgrf_industry.cpp */
 uint32 IndustryGetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available);
 uint16 GetIndustryCallback(CallbackID callback, uint32 param1, uint32 param2, Industry *industry, IndustryType type, TileIndex tile);
-uint32 GetIndustryIDAtOffset(TileIndex new_tile, TileIndex old_tile, const Industry *i);
+uint32 GetIndustryIDAtOffset(TileIndex new_tile, const Industry *i);
 void IndustryProductionCallback(Industry *ind, int reason);
 bool CheckIfCallBackAllowsCreation(TileIndex tile, IndustryType type, uint itspec_index);
 bool CheckIfCallBackAllowsAvailability(IndustryType type, IndustryAvailabilityCallType creation_type);
--- a/src/newgrf_industrytiles.cpp	Sun Sep 23 19:27:35 2007 +0000
+++ b/src/newgrf_industrytiles.cpp	Sun Sep 23 19:55:42 2007 +0000
@@ -99,7 +99,7 @@
 		}
 
 		/* Get industry tile ID at offset */
-		case 0x62 : return GetIndustryIDAtOffset(GetNearbyTile(parameter, tile), tile, inds);
+		case 0x62 : return GetIndustryIDAtOffset(GetNearbyTile(parameter, tile), inds);
 	}
 
 	DEBUG(grf, 1, "Unhandled industry tile property 0x%X", variable);