Index: source/graphics/Terrain.cpp
===================================================================
--- source/graphics/Terrain.cpp	(Revision 7429)
+++ source/graphics/Terrain.cpp	(Arbeitskopie)
@@ -340,6 +340,24 @@
 		   + zf  * ((1 - xf) * h01 + xf * h11)));
 }
 
+CFixed_23_8 CTerrain::GetExactGroundLevelFixed(CFixed_23_8 x, CFixed_23_8 z) const
+{
+	// Clamp to size-2 so we can use the tiles (xi,zi)-(xi+1,zi+1)
+	const ssize_t xi = clamp((ssize_t)(x/CELL_SIZE).ToInt_RoundToZero(), (ssize_t)0, m_MapSize-2);
+	const ssize_t zi = clamp((ssize_t)(z/CELL_SIZE).ToInt_RoundToZero(), (ssize_t)0, m_MapSize-2);
+
+	const CFixed_23_8 xf = clamp((x/CELL_SIZE)-CFixed_23_8::FromInt(xi), CFixed_23_8::FromInt(0), CFixed_23_8::FromInt(1));
+	const CFixed_23_8 zf = clamp((z/CELL_SIZE)-CFixed_23_8::FromInt(zi), CFixed_23_8::FromInt(0), CFixed_23_8::FromInt(1));
+
+	u16 h00 = m_Heightmap[zi*m_MapSize + xi];
+	u16 h01 = m_Heightmap[(zi+1)*m_MapSize + xi];
+	u16 h10 = m_Heightmap[zi*m_MapSize + (xi+1)];
+	u16 h11 = m_Heightmap[(zi+1)*m_MapSize + (xi+1)];
+	// Linearly interpolate
+	return (((CFixed_23_8::FromInt(1) - zf).Multiply((CFixed_23_8::FromInt(1) - xf) * h00 + xf * h10)
+			   + zf.Multiply((CFixed_23_8::FromInt(1) - xf) * h01 + xf * h11))/HEIGHT_UNITS_PER_METRE);
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 // Resize: resize this terrain to the given size (in patches per side)
 void CTerrain::Resize(ssize_t size)
Index: source/graphics/Terrain.h
===================================================================
--- source/graphics/Terrain.h	(Revision 7429)
+++ source/graphics/Terrain.h	(Arbeitskopie)
@@ -23,6 +23,7 @@
 #define INCLUDED_TERRAIN
 
 #include "maths/Vector3D.h"
+#include "maths/Fixed.h"
 #include "graphics/SColor.h"
 #include "lib/sysdep/cpu.h"
 
@@ -80,6 +81,7 @@
 
 	float GetVertexGroundLevel(ssize_t i, ssize_t j) const;
 	float GetExactGroundLevel(float x, float z) const;
+	CFixed_23_8 GetExactGroundLevelFixed(CFixed_23_8 x, CFixed_23_8 z) const;
 	float GetExactGroundLevel(const CVector2D& v) const;
 
 	float GetSlope(float x, float z) const ;
Index: source/simulation2/components/CCmpTerrain.cpp
===================================================================
--- source/simulation2/components/CCmpTerrain.cpp	(Revision 7429)
+++ source/simulation2/components/CCmpTerrain.cpp	(Arbeitskopie)
@@ -60,10 +60,7 @@
 
 	virtual entity_pos_t GetGroundLevel(entity_pos_t x, entity_pos_t z)
 	{
-		float height = m_Terrain->GetExactGroundLevel(x.ToFloat(), z.ToFloat());
-		// TODO: get rid of floats
-
-		return entity_pos_t::FromFloat(height);
+		return m_Terrain->GetExactGroundLevelFixed(x, z);
 	}
 
 	virtual float GetGroundLevel(float x, float z)

