From e79611db893cda85cf365dc51c653f122f23ea92 Mon Sep 17 00:00:00 2001
From: jsalmon3 <>
Date: Sat, 28 Aug 2004 20:43:09 +0000
Subject: [PATCH] Cleaned up missile graphics

---
 src/include/missile.h            |  5 +--
 src/sound/sound.cpp              |  2 +-
 src/stratagus/mainloop.cpp       |  4 +-
 src/stratagus/missile.cpp        | 69 +++++++++++++++-----------------
 src/stratagus/script_missile.cpp | 17 ++++++--
 src/stratagus/spells.cpp         |  2 +-
 6 files changed, 51 insertions(+), 48 deletions(-)

diff --git a/src/include/missile.h b/src/include/missile.h
index c62340327..cde508292 100644
--- a/src/include/missile.h
+++ b/src/include/missile.h
@@ -399,10 +399,7 @@ enum _missile_class_ {
 	/// Base structure of missile-types
 struct _missile_type_ {
 	char* Ident;          ///< missile name
-	char* File;           ///< missile sprite file
 	int   Transparency;   ///< missile transparency possible value is 50 (later 25 and 75)
-	int   Width;          ///< missile width in pixels
-	int   Height;         ///< missile height in pixels
 	int   DrawLevel;      ///< Level to draw missile at
 	int   SpriteFrames;   ///< number of sprite frames in graphic
 	int   NumDirections;  ///< number of directions missile can face
@@ -429,7 +426,7 @@ struct _missile_type_ {
 	MissileType* SmokeMissile;   ///< Trailling missile
 
 // --- FILLED UP ---
-	struct _graphic_* Sprite;    ///< missile sprite image
+	struct _graphic_* G;         ///< missile graphic
 };
 
 /*----------------------------------------------------------------------------
diff --git a/src/sound/sound.cpp b/src/sound/sound.cpp
index 11c4e3836..7001b57eb 100644
--- a/src/sound/sound.cpp
+++ b/src/sound/sound.cpp
@@ -210,7 +210,7 @@ void PlayMissileSound(const Missile* missile, SoundId sound)
 {
 	int stereo;
 
-	stereo = ((missile->X + missile->Type->Width / 2 -
+	stereo = ((missile->X + missile->Type->G->Width / 2 -
 		TheUI.SelectedViewport->MapX * TileSizeX) * 256 /
 		((TheUI.SelectedViewport->MapWidth - 1) * TileSizeX)) - 128;
 	if (stereo < -128) {
diff --git a/src/stratagus/mainloop.cpp b/src/stratagus/mainloop.cpp
index 577d54835..95a655e27 100644
--- a/src/stratagus/mainloop.cpp
+++ b/src/stratagus/mainloop.cpp
@@ -228,7 +228,7 @@ static void DrawMapViewport(Viewport* vp)
 					}
 #endif
 					GraphicPlayerPixels(missiletable[j]->SourceUnit->Player,
-						missiletable[j]->Type->Sprite);
+						missiletable[j]->Type->G);
 				}
 				switch (missiletable[j]->Type->Class) {
 					case MissileClassHit:
@@ -258,7 +258,7 @@ static void DrawMapViewport(Viewport* vp)
 				}
 #endif
 				GraphicPlayerPixels(missiletable[j]->SourceUnit->Player,
-					missiletable[j]->Type->Sprite);
+					missiletable[j]->Type->G);
 			}
 			switch (missiletable[j]->Type->Class) {
 				case MissileClassHit:
diff --git a/src/stratagus/missile.cpp b/src/stratagus/missile.cpp
index 697e839ab..d1b10e042 100644
--- a/src/stratagus/missile.cpp
+++ b/src/stratagus/missile.cpp
@@ -146,15 +146,13 @@ BurningBuildingFrame* BurningBuildingFrames; /// Burning building frames
 */
 void LoadMissileSprite(MissileType* mtype)
 {
-	if (mtype->File) {
-		mtype->Sprite = NewGraphic(
-			mtype->File, mtype->Width, mtype->Height);
-		LoadGraphic(mtype->Sprite);
-		FlipGraphic(mtype->Sprite);
+	if (mtype->G && !GraphicLoaded(mtype->G)) {
+		LoadGraphic(mtype->G);
+		FlipGraphic(mtype->G);
 
 		// Correct the number of frames in graphic
-		Assert(mtype->Sprite->NumFrames >= mtype->SpriteFrames);
-		mtype->Sprite->NumFrames = mtype->SpriteFrames;
+		Assert(mtype->G->NumFrames >= mtype->SpriteFrames);
+		mtype->G->NumFrames = mtype->SpriteFrames;
 		// FIXME: Don't use NumFrames as number of frames.
 	}
 }
@@ -272,10 +270,10 @@ static Missile* NewLocalMissile(void)
 static Missile* InitMissile(Missile* missile, MissileType* mtype, int sx,
 	int sy, int dx, int dy)
 {
-	missile->X = sx - mtype->Width / 2;
-	missile->Y = sy - mtype->Height / 2;
-	missile->DX = dx - mtype->Width / 2;
-	missile->DY = dy - mtype->Height / 2;
+	missile->X = sx - mtype->G->Width / 2;
+	missile->Y = sy - mtype->G->Height / 2;
+	missile->DX = dx - mtype->G->Width / 2;
+	missile->DY = dy - mtype->G->Height / 2;
 	missile->SourceX = missile->X;
 	missile->SourceY = missile->Y;
 	missile->Type = mtype;
@@ -568,8 +566,8 @@ static void GetMissileMapArea(const Missile* missile, int* sx, int* sy,
 #define Bound(x, y) (x) < 0 ? 0 : ((x) > (y) ? (y) : (x))
 	*sx = Bound(missile->X / TileSizeX, TheMap.Width - 1);
 	*sy = Bound(missile->Y / TileSizeY, TheMap.Height - 1);
-	*ex = Bound((missile->X + missile->Type->Width) / TileSizeX, TheMap.Width - 1);
-	*ey = Bound((missile->Y + missile->Type->Height) / TileSizeY, TheMap.Height - 1);
+	*ex = Bound((missile->X + missile->Type->G->Width) / TileSizeX, TheMap.Width - 1);
+	*ey = Bound((missile->Y + missile->Type->G->Height) / TileSizeY, TheMap.Height - 1);
 #undef Bound
 }
 
@@ -616,7 +614,7 @@ static int MissileVisibleInViewport(const Viewport* vp, const Missile* missile)
 void DrawMissile(MissileType* mtype, int frame, int x, int y)
 {
 #ifdef DYNAMIC_LOAD
-	if (!mtype->Sprite) {
+	if (!GraphicLoaded(mtype->G)) {
 		LoadMissileSprite(mtype);
 	}
 #endif
@@ -624,15 +622,15 @@ void DrawMissile(MissileType* mtype, int frame, int x, int y)
 	if (mtype->Flip) {
 		if (frame < 0) {
 			if (mtype->Transparency == 50) {
-				VideoDrawClipXTrans50(mtype->Sprite, -frame - 1, x, y);
+				VideoDrawClipXTrans50(mtype->G, -frame - 1, x, y);
 			} else {
-				VideoDrawClipX(mtype->Sprite, -frame - 1, x, y);
+				VideoDrawClipX(mtype->G, -frame - 1, x, y);
 			}
 		} else {
 			if (mtype->Transparency == 50) {
-				VideoDrawClipTrans50(mtype->Sprite, frame, x, y);
+				VideoDrawClipTrans50(mtype->G, frame, x, y);
 			} else {
-				VideoDrawClip(mtype->Sprite, frame, x, y);
+				VideoDrawClip(mtype->G, frame, x, y);
 			}
 		}
 	} else {
@@ -645,9 +643,9 @@ void DrawMissile(MissileType* mtype, int frame, int x, int y)
 			frame = (frame / row) * mtype->NumDirections + frame % row;
 		}
 		if (mtype->Transparency == 50) {
-			VideoDrawClipTrans50(mtype->Sprite, frame, x, y);
+			VideoDrawClipTrans50(mtype->G, frame, x, y);
 		} else {
-			VideoDrawClip(mtype->Sprite, frame, x, y);
+			VideoDrawClip(mtype->G, frame, x, y);
 		}
 	}
 }
@@ -814,8 +812,8 @@ static int PointToPointMissile(Missile* missile)
 	missile->X = missile->SourceX + xstep * missile->CurrentStep / 1024;
 	missile->Y = missile->SourceY + ystep * missile->CurrentStep / 1024;
 	if (missile->Type->SmokeMissile && missile->CurrentStep) {
-		x = missile->X + missile->Type->Width / 2;
-		y = missile->Y + missile->Type->Height / 2;
+		x = missile->X + missile->Type->G->Width / 2;
+		y = missile->Y + missile->Type->G->Height / 2;
 		MakeMissile(missile->Type->SmokeMissile, x, y, x, y);
 	}
 	return 0;
@@ -866,8 +864,8 @@ static int ParabolicMissile(Missile* missile)
 	missile->Y += Z * ZprojToY / 64;
 	MissileNewHeadingFromXY(missile, missile->X - orig_x, missile->Y - orig_y);
 	if (missile->Type->SmokeMissile && missile->CurrentStep) {
-		x = missile->X + missile->Type->Width / 2;
-		y = missile->Y + missile->Type->Height / 2;
+		x = missile->X + missile->Type->G->Width / 2;
+		y = missile->Y + missile->Type->G->Height / 2;
 		MakeMissile(missile->Type->SmokeMissile, x, y, x, y);
 	}
 	return 0;
@@ -952,8 +950,8 @@ void MissileHit(Missile* missile)
 		PlayMissileSound(missile, missile->Type->ImpactSound.Sound);
 	}
 
-	x = missile->X + missile->Type->Width / 2;
-	y = missile->Y + missile->Type->Height / 2;
+	x = missile->X + missile->Type->G->Width / 2;
+	y = missile->Y + missile->Type->G->Height / 2;
 
 	//
 	// The impact generates a new missile.
@@ -1214,8 +1212,8 @@ int ViewPointDistanceToMissile(const Missile* missile)
 	int x;
 	int y;
 
-	x = (missile->X + missile->Type->Width / 2) / TileSizeX;
-	y = (missile->Y + missile->Type->Height / 2) / TileSizeY;  // pixel -> tile
+	x = (missile->X + missile->Type->G->Width / 2) / TileSizeX;
+	y = (missile->Y + missile->Type->G->Height / 2) / TileSizeY;  // pixel -> tile
 
 	return ViewPointDistance(x, y);
 }
@@ -1357,12 +1355,11 @@ void CleanMissileTypes(void)
 		hash_del(MissileTypeHash, mtype->Ident);
 
 		free(mtype->Ident);
-		free(mtype->File);
 		free(mtype->FiredSound.Name);
 		free(mtype->ImpactSound.Name);
 		free(mtype->ImpactName);
 		free(mtype->SmokeName);
-		FreeGraphic(mtype->Sprite);
+		FreeGraphic(mtype->G);
 	}
 	free(MissileTypes);
 	MissileTypes = NULL;
@@ -1584,11 +1581,11 @@ void MissileActionFire(Missile* missile)
 			unit->Burning = 0;
 		} else {
 			if (missile->Type != fire) {
-				missile->X += missile->Type->Width / 2;
-				missile->Y += missile->Type->Height / 2;
+				missile->X += missile->Type->G->Width / 2;
+				missile->Y += missile->Type->G->Height / 2;
 				missile->Type = fire;
-				missile->X -= missile->Type->Width / 2;
-				missile->Y -= missile->Type->Height / 2;
+				missile->X -= missile->Type->G->Width / 2;
+				missile->Y -= missile->Type->G->Height / 2;
 			}
 		}
 	}
@@ -1761,8 +1758,8 @@ void MissileActionWhirlwind(Missile* missile)
 	//
 	// Center of the tornado
 	//
-	x = (missile->X + TileSizeX / 2 + missile->Type->Width / 2) / TileSizeX;
-	y = (missile->Y + TileSizeY + missile->Type->Height / 2) / TileSizeY;
+	x = (missile->X + TileSizeX / 2 + missile->Type->G->Width / 2) / TileSizeX;
+	y = (missile->Y + TileSizeY + missile->Type->G->Height / 2) / TileSizeY;
 
 #if 0
 	Unit* table[UnitMax];
diff --git a/src/stratagus/script_missile.cpp b/src/stratagus/script_missile.cpp
index 52c435180..e48dfb3fc 100644
--- a/src/stratagus/script_missile.cpp
+++ b/src/stratagus/script_missile.cpp
@@ -70,6 +70,9 @@ static int CclDefineMissileType(lua_State* l)
 	char* str;
 	MissileType* mtype;
 	unsigned i;
+	char* file;
+	int w;
+	int h;
 
 	if (lua_gettop(l) != 2 || !lua_istable(l, 2)) {
 		LuaError(l, "incorrect argument");
@@ -98,6 +101,9 @@ static int CclDefineMissileType(lua_State* l)
 	// Ensure we don't divide by zero.
 	mtype->SplashFactor = 100;
 
+	file = NULL;
+	w = h = 0;
+
 	//
 	// Parse the arguments
 	//
@@ -105,17 +111,16 @@ static int CclDefineMissileType(lua_State* l)
 	while (lua_next(l, 2)) {
 		value = LuaToString(l, -2);
 		if (!strcmp(value, "File")) {
-			free(mtype->File);
-			mtype->File = strdup(LuaToString(l, -1));
+			file = strdup(LuaToString(l, -1));
 		} else if (!strcmp(value, "Size")) {
 			if (!lua_istable(l, -1) || luaL_getn(l, -1) != 2) {
 				LuaError(l, "incorrect argument");
 			}
 			lua_rawgeti(l, -1, 1);
-			mtype->Width = LuaToNumber(l, -1);
+			w = LuaToNumber(l, -1);
 			lua_pop(l, 1);
 			lua_rawgeti(l, -1, 2);
-			mtype->Height = LuaToNumber(l, -1);
+			h = LuaToNumber(l, -1);
 			lua_pop(l, 1);
 		} else if (!strcmp(value, "Frames")) {
 			mtype->SpriteFrames = LuaToNumber(l, -1);
@@ -172,6 +177,10 @@ static int CclDefineMissileType(lua_State* l)
 		lua_pop(l, 1);
 	}
 
+	if (file) {
+		mtype->G = NewGraphic(file, w, h);
+	}
+
 	return 0;
 }
 
diff --git a/src/stratagus/spells.cpp b/src/stratagus/spells.cpp
index 8379ec42e..0504ab7d2 100644
--- a/src/stratagus/spells.cpp
+++ b/src/stratagus/spells.cpp
@@ -329,7 +329,7 @@ int CastAreaBombardment(Unit* caster, const SpellType* spell,
 			if (mis->Type->Speed) {
 				mis->Delay = i * mis->Type->Sleep * 2 * TileSizeX / mis->Type->Speed;
 			} else {
-				mis->Delay = i * mis->Type->Sleep * VideoGraphicFrames(mis->Type->Sprite);
+				mis->Delay = i * mis->Type->Sleep * VideoGraphicFrames(mis->Type->G);
 			}
 			mis->Damage = damage;
 			// FIXME: not correct -- blizzard should continue even if mage is