From 3bbde68a25530f6dce10f7fe676c2afe4a254128 Mon Sep 17 00:00:00 2001
From: Joris <joris.dauphin@gmail.com>
Date: Fri, 27 Apr 2012 12:36:48 +0200
Subject: [PATCH] Factorize code with new function clamp.

---
 src/action/action_still.cpp | 11 +----------
 src/action/actions.cpp      | 19 ++++++-------------
 src/include/map.h           |  2 ++
 src/include/stratagus.h     |  1 +
 src/include/util.h          | 14 ++++++++++++++
 src/map/map_draw.cpp        | 12 ++----------
 src/sound/script_sound.cpp  | 17 +++++------------
 src/sound/sound.cpp         | 22 +++++-----------------
 src/sound/sound_server.cpp  | 18 ++++--------------
 src/stratagus/spells.cpp    |  9 ++-------
 src/ui/interface.cpp        | 12 ++----------
 src/ui/mouse.cpp            | 21 ++++-----------------
 src/unit/unit.cpp           | 11 +----------
 src/unit/unit_cache.cpp     |  6 ++++++
 14 files changed, 55 insertions(+), 120 deletions(-)

diff --git a/src/action/action_still.cpp b/src/action/action_still.cpp
index 8d90e6d8b..368aee6f6 100644
--- a/src/action/action_still.cpp
+++ b/src/action/action_still.cpp
@@ -184,16 +184,7 @@ static bool MoveRandomly(CUnit &unit)
 	}
 
 	// restrict to map
-	if (pos.x < 0) {
-		pos.x = 0;
-	} else if (pos.x >= Map.Info.MapWidth) {
-		pos.x = Map.Info.MapWidth - 1;
-	}
-	if (pos.y < 0) {
-		pos.y = 0;
-	} else if (pos.y >= Map.Info.MapHeight) {
-		pos.y = Map.Info.MapHeight - 1;
-	}
+	Map.Clamp(pos);
 
 	// move if possible
 	if (pos != unit.tilePos) {
diff --git a/src/action/actions.cpp b/src/action/actions.cpp
index c768cfe6c..a99be16a9 100644
--- a/src/action/actions.cpp
+++ b/src/action/actions.cpp
@@ -293,24 +293,17 @@ static void HandleBuffs(CUnit &unit, int amount)
 
 	unit.Variable[SHIELD_INDEX].Increase = 1;
 
+	const bool lastStatusIsHidden = unit.Variable[INVISIBLE_INDEX].Value > 0;
 	// User defined variables
 	for (unsigned int i = 0; i < UnitTypeVar.GetNumberVariable(); i++) {
 		if (unit.Variable[i].Enable && unit.Variable[i].Increase) {
-			if (i == INVISIBLE_INDEX &&
-				unit.Variable[INVISIBLE_INDEX].Value > 0 &&
-				unit.Variable[INVISIBLE_INDEX].Value +
-				unit.Variable[INVISIBLE_INDEX].Increase <= 0) {
-				UnHideUnit(unit);
-			} else {
-				unit.Variable[i].Value += unit.Variable[i].Increase;
-				if (unit.Variable[i].Value <= 0) {
-					unit.Variable[i].Value = 0;
-				} else if (unit.Variable[i].Value > unit.Variable[i].Max) {
-					unit.Variable[i].Value = unit.Variable[i].Max;
-				}
-			}
+			unit.Variable[i].Value += unit.Variable[i].Increase;
+			clamp(&unit.Variable[i].Value, 0, unit.Variable[i].Max);
 		}
 	}
+	if (lastStatusIsHidden && unit.Variable[INVISIBLE_INDEX].Value == 0) {
+		UnHideUnit(unit);
+	}
 }
 
 
diff --git a/src/include/map.h b/src/include/map.h
index 2e6d48351..a6bf697e3 100644
--- a/src/include/map.h
+++ b/src/include/map.h
@@ -503,6 +503,8 @@ public:
 	/// Remove unit from cache
 	void Remove(CUnit &unit);
 
+	void Clamp(Vec2i &pos) const;
+
 	//Warning: we expect typical usage as xmin = x - range
 	void FixSelectionArea(Vec2i &minpos, Vec2i &maxpos) {
 		minpos.x = std::max<short>(0, minpos.x);
diff --git a/src/include/stratagus.h b/src/include/stratagus.h
index bde79ff55..b3886d0e4 100644
--- a/src/include/stratagus.h
+++ b/src/include/stratagus.h
@@ -87,6 +87,7 @@
 #endif
 
 #include <stdlib.h>
+#include <stdio.h>
 
 /*============================================================================
 ==  Macro
diff --git a/src/include/util.h b/src/include/util.h
index 6509fd193..fc587f923 100644
--- a/src/include/util.h
+++ b/src/include/util.h
@@ -176,6 +176,20 @@ extern inline int MyAbs(int x) { return (x ^ (x >> 31)) - (x >> 31); }
 /// Compute a square root using ints
 extern long isqrt(long num);
 
+
+template <typename T>
+void clamp(T* value, T minValue, T maxValue)
+{
+	Assert(minValue < maxValue);
+
+	if (*value < minValue) {
+		*value = minValue;
+	} else if (maxValue < *value) {
+		*value = maxValue;
+	}
+}
+
+
 /*----------------------------------------------------------------------------
 --  Strings
 ----------------------------------------------------------------------------*/
diff --git a/src/map/map_draw.cpp b/src/map/map_draw.cpp
index 2cb8492f1..620fe9ba4 100644
--- a/src/map/map_draw.cpp
+++ b/src/map/map_draw.cpp
@@ -65,16 +65,8 @@ bool CViewport::Contains(const PixelPos &screenPos) const
 
 void CViewport::Restrict(int &screenPosX, int &screenPosY) const
 {
-	if (screenPosX < this->GetTopLeftPos().x) {
-		screenPosX = this->GetTopLeftPos().x;
-	} else if (screenPosX > this->GetBottomRightPos().x - 1) {
-		screenPosX = this->GetBottomRightPos().x - 1;
-	}
-	if (screenPosY < this->GetTopLeftPos().y) {
-		screenPosY = this->GetTopLeftPos().y;
-	} else if (screenPosY > this->GetBottomRightPos().y - 1) {
-		screenPosY = this->GetBottomRightPos().y - 1;
-	}
+	clamp(&screenPosX, this->GetTopLeftPos().x, this->GetBottomRightPos().x - 1);
+	clamp(&screenPosY, this->GetTopLeftPos().y, this->GetBottomRightPos().y - 1);
 }
 
 PixelSize CViewport::GetPixelSize() const
diff --git a/src/sound/script_sound.cpp b/src/sound/script_sound.cpp
index ee4341fb3..3f7afa6ff 100644
--- a/src/sound/script_sound.cpp
+++ b/src/sound/script_sound.cpp
@@ -472,22 +472,15 @@ static int CclSetGlobalSoundRange(lua_State *l)
 */
 static int CclSetSoundRange(lua_State *l)
 {
-	unsigned char theRange;
-	int tmp;
-	CSound *id;
 
 	LuaCheckArgs(l, 2);
 
-	tmp = LuaToNumber(l, 2);
-	if (tmp < 0) {
-		theRange = 0;
-	} else if (tmp > 255) {
-		theRange = 255;
-	} else {
-		theRange = (unsigned char)tmp;
-	}
+	int tmp = LuaToNumber(l, 2);
+	clamp(&tmp, 0, 255);
+	const unsigned char theRange = static_cast<unsigned char>(tmp);
+
 	lua_pushvalue(l, 1);
-	id = CclGetSound(l);
+	CSound *id = CclGetSound(l);
 	SetSoundRange(id, theRange);
 	return 1;
 }
diff --git a/src/sound/sound.cpp b/src/sound/sound.cpp
index 021ab7f62..91bb6c1cb 100644
--- a/src/sound/sound.cpp
+++ b/src/sound/sound.cpp
@@ -251,17 +251,10 @@ static unsigned char CalculateVolume(bool isVolume, int power, unsigned char ran
 */
 static char CalculateStereo(const CUnit &unit)
 {
-	int stereo;
-
-	stereo = ((unit.tilePos.x * PixelTileSize.x + unit.Type->TileWidth * PixelTileSize.x / 2 +
-			   unit.IX - UI.SelectedViewport->MapX * PixelTileSize.x) * 256 /
-			  ((UI.SelectedViewport->MapWidth - 1) * PixelTileSize.x)) - 128;
-	if (stereo < -128) {
-		stereo = -128;
-	} else if (stereo > 127) {
-		stereo = 127;
-	}
-
+	int stereo = ((unit.tilePos.x * PixelTileSize.x + unit.Type->TileWidth * PixelTileSize.x / 2 +
+				  unit.IX - UI.SelectedViewport->MapX * PixelTileSize.x) * 256 /
+				  ((UI.SelectedViewport->MapWidth - 1) * PixelTileSize.x)) - 128;
+	clamp(&stereo, -128, 127);
 	return stereo;
 }
 
@@ -321,12 +314,7 @@ void PlayMissileSound(const Missile *missile, CSound *sound)
 	int stereo = ((missile->position.x + missile->Type->G->Width / 2 -
 				   UI.SelectedViewport->MapX * PixelTileSize.x) * 256 /
 				  ((UI.SelectedViewport->MapWidth - 1) * PixelTileSize.x)) - 128;
-
-	if (stereo < -128) {
-		stereo = -128;
-	} else if (stereo > 127) {
-		stereo = 127;
-	}
+	clamp(&stereo, -128, 127);
 
 	Origin source = {NULL, 0};
 
diff --git a/src/sound/sound_server.cpp b/src/sound/sound_server.cpp
index 3bf7089bd..4a7eb9b78 100644
--- a/src/sound/sound_server.cpp
+++ b/src/sound/sound_server.cpp
@@ -585,13 +585,8 @@ int PlaySoundFile(const std::string &name)
 */
 void SetEffectsVolume(int volume)
 {
-	if (volume < 0) {
-		EffectsVolume = 0;
-	} else if (volume > MaxVolume) {
-		EffectsVolume = MaxVolume;
-	} else {
-		EffectsVolume = volume;
-	}
+	clamp(&volume, 0, MaxVolume);
+	EffectsVolume = volume;
 }
 
 /**
@@ -717,13 +712,8 @@ void StopMusic()
 */
 void SetMusicVolume(int volume)
 {
-	if (volume < 0) {
-		MusicVolume = 0;
-	} else if (volume > MaxVolume) {
-		MusicVolume = MaxVolume;
-	} else {
-		MusicVolume = volume;
-	}
+	clamp(&volume, 0, MaxVolume);
+	MusicVolume = volume;
 }
 
 /**
diff --git a/src/stratagus/spells.cpp b/src/stratagus/spells.cpp
index f7e1ff265..927456da5 100644
--- a/src/stratagus/spells.cpp
+++ b/src/stratagus/spells.cpp
@@ -364,14 +364,9 @@ int AdjustVariable::Cast(CUnit &caster, const SpellType *, CUnit *target, const
 			unit->Variable[i].Value = this->Var[i].Value;
 		}
 		unit->Variable[i].Value += this->Var[i].AddValue;
-		unit->Variable[i].Value += this->Var[i].IncreaseTime
-								   * unit->Variable[i].Increase;
+		unit->Variable[i].Value += this->Var[i].IncreaseTime * unit->Variable[i].Increase;
 
-		if (unit->Variable[i].Value <= 0) {
-			unit->Variable[i].Value = 0;
-		} else if (unit->Variable[i].Value > unit->Variable[i].Max) {
-			unit->Variable[i].Value = unit->Variable[i].Max;
-		}
+		clamp(&unit->Variable[i].Value, 0, unit->Variable[i].Max);
 	}
 	return 1;
 }
diff --git a/src/ui/interface.cpp b/src/ui/interface.cpp
index 42aa6da03..bab05c537 100644
--- a/src/ui/interface.cpp
+++ b/src/ui/interface.cpp
@@ -1204,16 +1204,8 @@ int HandleMouseScrollArea(int x, int y)
 void HandleCursorMove(int *x, int *y)
 {
 	//  Reduce coordinates to window-size.
-	if (*x < 0) {
-		*x = 0;
-	} else if (*x >= Video.Width) {
-		*x = Video.Width - 1;
-	}
-	if (*y < 0) {
-		*y = 0;
-	} else if (*y >= Video.Height) {
-		*y = Video.Height - 1;
-	}
+	clamp(x, 0, Video.Width - 1);
+	clamp(y, 0, Video.Height - 1);
 	CursorX = *x;
 	CursorY = *y;
 }
diff --git a/src/ui/mouse.cpp b/src/ui/mouse.cpp
index 1549106fd..27ffe294d 100644
--- a/src/ui/mouse.cpp
+++ b/src/ui/mouse.cpp
@@ -766,24 +766,11 @@ void RestrictCursorToViewport()
 */
 void RestrictCursorToMinimap()
 {
-	if (CursorX < UI.Minimap.X) {
-		CursorStartX = UI.Minimap.X;
-	} else if (CursorX >= UI.Minimap.X + UI.Minimap.W) {
-		CursorStartX = UI.Minimap.X + UI.Minimap.W - 1;
-	} else {
-		CursorStartX = CursorX;
-	}
+	clamp(&CursorX, UI.Minimap.X, UI.Minimap.X + UI.Minimap.W - 1);
+	clamp(&CursorY, UI.Minimap.Y, UI.Minimap.Y + UI.Minimap.H - 1);
 
-	if (CursorY < UI.Minimap.Y) {
-		CursorStartY = UI.Minimap.Y;
-	} else if (CursorY >= UI.Minimap.Y + UI.Minimap.H) {
-		CursorStartY = UI.Minimap.Y + UI.Minimap.H - 1;
-	} else {
-		CursorStartY = CursorY;
-	}
-
-	CursorX = UI.MouseWarpX = CursorStartX;
-	CursorY = UI.MouseWarpY = CursorStartY;
+	UI.MouseWarpX = CursorStartX = CursorX;
+	UI.MouseWarpY = CursorStartY = CursorY;
 	CursorOn = CursorOnMinimap;
 }
 
diff --git a/src/unit/unit.cpp b/src/unit/unit.cpp
index e71be729e..178dee3be 100644
--- a/src/unit/unit.cpp
+++ b/src/unit/unit.cpp
@@ -2955,17 +2955,8 @@ void HitUnit(CUnit *attacker, CUnit &target, int damage)
 			d = 1;
 		}
 		pos.x = target.tilePos.x + (pos.x * 5) / d + (SyncRand() & 3);
-		if (pos.x < 0) {
-			pos.x = 0;
-		} else if (pos.x >= Map.Info.MapWidth) {
-			pos.x = Map.Info.MapWidth - 1;
-		}
 		pos.y = target.tilePos.y + (pos.y * 5) / d + (SyncRand() & 3);
-		if (pos.y < 0) {
-			pos.y = 0;
-		} else if (pos.y >= Map.Info.MapHeight) {
-			pos.y = Map.Info.MapHeight - 1;
-		}
+		Map.Clamp(pos);
 		CommandStopUnit(target);
 		CommandMove(target, pos, 0);
 	}
diff --git a/src/unit/unit_cache.cpp b/src/unit/unit_cache.cpp
index 55ed3462a..a548363f5 100644
--- a/src/unit/unit_cache.cpp
+++ b/src/unit/unit_cache.cpp
@@ -93,6 +93,12 @@ void CMap::Remove(CUnit &unit)
 }
 
 
+void CMap::Clamp(Vec2i &pos) const
+{
+	clamp<short int>(&pos.x, 0, this->Info.MapWidth - 1);
+	clamp<short int>(&pos.y, 0, this->Info.MapHeight - 1);
+}
+
 class NoFilter
 {
 public: