1 /*
2  *  Open Fodder
3  *  ---------------
4  *
5  *  Copyright (C) 2008-2018 Open Fodder
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 3 of the License, or
10  *  (at your option) any later version.
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License along
18  *  with this program; if not, write to the Free Software Foundation, Inc.,
19  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  */
22 
23 enum eSprites {
24 	eSprite_Player							= 0,
25 	eSprite_Grenade							= 2,
26 	eSprite_ShadowSmall						= 3,
27 	eSprite_Null							= 4,
28 	eSprite_Enemy							= 5,
29 	eSprite_Bullet							= 6,
30 
31 	eSprite_Explosion						= 12,
32 	eSprite_Shrub							= 13,
33 	eSprite_Tree							= 14,
34 	eSprite_BuildingRoof					= 15,
35 	eSprite_Snowman							= 16,
36 	eSprite_Shrub2							= 17,
37 	eSprite_Waterfall						= 18,
38 	eSprite_Bird2_Left						= 19,
39 
40 	eSprite_BuildingDoor					= 20,
41 	eSprite_Player_Rank						= 21,
42 	eSprite_Player_Shadow					= 22,
43 	eSprite_BloodTrail						= 23,
44 	eSprite_GroundHole						= 24,
45 	eSprite_BuildingDoor2					= 25,
46 	eSprite_Floating_Dead_Soldier			= 27,
47 	eSprite_Text_Complete					= 28,
48 	eSprite_Text_Mission					= 29,
49 
50 	eSprite_Text_Phase						= 30,
51 	eSprite_Rocket							= 33,
52 	eSprite_Text_GameOver					= 34,
53 	eSprite_Shadow							= 35,
54 	eSprite_Enemy_Rocket					= 36,
55 	eSprite_GrenadeBox						= 37,
56 	eSprite_RocketBox						= 38,
57 	eSprite_Building_Explosion				= 39,
58 
59 	eSprite_Helicopter_Grenade_Enemy			= 40,
60 	eSprite_Flashing_Light						= 41,
61 	eSprite_Helicopter_Grenade2_Enemy			= 42,
62 	eSprite_Helicopter_Missile_Enemy			= 43,
63 	eSprite_Helicopter_Homing_Enemy				= 44,
64 	eSprite_Missile								= 45,
65 	eSprite_MissileHoming						= 46,
66 	eSprite_Sparks								= 47,
67 	eSprite_FireTrail							= 48,
68 	eSprite_Helicopter_Grenade2_Human			= 49,
69 
70 	eSprite_Helicopter_Grenade_Human			= 50,
71 	eSprite_Helicopter_Missile_Human			= 51,
72 	eSprite_Helicopter_Homing_Human				= 52,
73 	eSprite_Helicopter_PropCrash				= 53,
74 	eSprite_Mine								= 54,
75 	eSprite_Mine2								= 55,
76 	eSprite_Spike								= 56,
77 	eSprite_Smoke								= 57,
78 	eSprite_Text_Try							= 58,
79 	eSprite_Text_Again							= 59,
80 
81 	eSprite_BoilingPot							= 60,
82 	eSprite_Civilian							= 61,
83 	eSprite_Civilian2							= 62,
84 	eSprite_VehicleNoGun_Human					= 63,		// Skidu
85 	eSprite_VehicleGun_Human					= 64,
86 	eSprite_Tank_Human							= 65,
87 	eSprite_Bird_Left							= 66,
88 	eSprite_Bird_Right							= 67,
89 	eSprite_Seal								= 68,
90 	eSprite_Tank_Enemy							= 69,
91 
92 	eSprite_Civilian_Spear					= 70,
93 	eSprite_Civilian_Spear2					= 71,
94 	eSprite_Hostage								= 72,
95 	eSprite_Hostage_Rescue_Tent					= 73,
96 	eSprite_Door_Civilian						= 74,
97 	eSprite_Door2_Civilian					= 75,
98 	eSprite_Door_Civilian_Spear				= 76,
99 	eSprite_Cannon								= 77,
100 	eSprite_Turret_Missile_Human				= 78,
101 	eSprite_Turret_Missile2_Human				= 79,
102 
103 	eSprite_VehicleNoGun_Enemy					= 80,
104 	eSprite_VehicleGun_Enemy					= 81,
105 	eSprite_Vehicle_Unk_Enemy					= 82,
106 	eSprite_Civilian_Invisible				= 83,
107 	eSprite_Turret_Missile_Enemy				= 84,
108 	eSprite_Turret_Missile2_Enemy				= 85,
109 	eSprite_Vehicle_Sinking_1					= 86,
110 	eSprite_Vehicle_Sinking_2					= 87,
111 	eSprite_BuildingDoor3						= 88,
112 	eSprite_Explosion2							= 89,
113 
114 	eSprite_Door_Civilian_Rescue				= 90,
115 	eSprite_Seal_Mine							= 91,
116 	eSprite_Spider_Mine							= 92,
117 	eSprite_Bonus_RankToGeneral					= 93,
118 	eSprite_Bonus_Rockets						= 94,
119 	eSprite_Bonus_Armour						= 95,
120 	eSprite_Bonus_RankHomingInvin_SquadLeader	= 96,
121 	eSprite_MissileHoming2						= 97,
122 	eSprite_Bonus_RankHomingInvin_Squad			= 98,
123 	eSprite_Helicopter_CallPad					= 99,
124 
125 	eSprite_BuildingDoor_Reinforced				= 100,
126 	eSprite_Helicopter_Grenade2_Human_Called	= 101,
127 	eSprite_Helicopter_Grenade_Human_Called		= 102,
128 	eSprite_Helicopter_Missile_Human_Called		= 103,
129 	eSprite_Helicopter_Homing_Human_Called		= 104,
130 	eSprite_Turret_HomingMissile_Enemy			= 105,
131 	eSprite_Enemy_Leader						= 106,
132 	eSprite_Helicopter_Homing_Enemy2			= 107,
133 	eSprite_Computer_1							= 108,
134 	eSprite_Computer_2							= 109,
135 	eSprite_Computer_3							= 110,
136 
137     // Cannon Fodder 2
138     eSprite_UFO_Callpad                         = 111,
139 
140     eSprite_Turret_Cannon_Invulnerable          = 112,
141     eSprite_Turret_Missile_Invulnerable         = 113,
142     eSprite_Looping_Vehicle_Left                = 114,
143     eSprite_Looping_Vehicle_Right               = 115,
144 
145     eSprite_Looping_Vehicle_Up                  = 116,
146     eSprite_Looping_Vehicle_Down                = 117
147 };
148 
149 enum eSprite_Flags {
150 	eSprite_Flag_HomingMissiles = 0x01,
151 	eSprite_Flag_Invincibility  = 0x02,
152 };
153 
154 enum eSprite_Anim {
155 	eSprite_Anim_None = 0x00,
156 	eSprite_Anim_Hit  = 0x01,
157 	eSprite_Anim_Hit2 = 0x02,
158 	eSprite_Anim_Hit3 = 0x03,
159 	eSprite_Anim_Die1 = 0x05,		// Cause a turret to explode, a soldier to be run over
160 	eSprite_Anim_Die2 = 0x06,
161 	eSprite_Anim_Die3 = 0x07,
162 	eSprite_Anim_Die4 = 0x09,
163 	eSprite_Anim_Die5 = 0x0A,
164 
165 	eSprite_Anim_Slide1 = 0x32,
166 	eSprite_Anim_Slide2 = 0x33,
167 	eSprite_Anim_Slide3 = 0x34,
168 	eSprite_Anim_Vehicle_Enter  = 0x5A,
169 	eSprite_Anim_Vehicle_Inside = 0x5B
170 };
171 
172 enum eSprite_PersonType {
173 	eSprite_PersonType_None = -1,
174 	eSprite_PersonType_Human = 0,
175 	eSprite_PersonType_AI = 1,
176 	eSprite_PersonType_Native = 2
177 };
178 
179 enum eVehicles {
180     eVehicle_Turret_Cannon = 0,
181     eVehicle_Turret_Missile = 1,
182     eVehicle_Jeep = 2,
183     eVehicle_JeepRocket = 3,
184     eVehicle_Tank = 4,
185     eVehicle_Helicopter = 5,
186     eVehicle_Helicopter_Grenade = 6,
187     eVehicle_Helicopter_Missile = 7,
188     eVehicle_Helicopter_Homing = 8,
189     eVehicle_Turret_Homing = 9,
190     eVehicle_DontTargetPlayer = 10
191 };
192 
193 enum ePstuff_Sprites {
194 
195 	eSprite_pStuff_Mouse_Cursor			 = 0x23,
196 	eSprite_pStuff_Mouse_Target			 = 0x24,
197 	eSprite_pStuff_Mouse_Arrow_DownRight = 0x25,
198 	eSprite_pStuff_Mouse_Arrow_UpLeft	 = 0x26,
199 	eSprite_pStuff_Mouse_Helicopter		 = 0x27,
200 };
201 
202 enum eSprite_DrawOrder {
203 	eSprite_Draw_First	= -1,
204 	eSprite_Draw_Second	= 0,
205 	eSprite_Draw_OnTop	= 1
206 };
207 
208 struct sMission_Troop;
209 
210 
211 // The reason none of the fields are labelled, is to simplify adding the remaining CF2 sprites.
212 // Once this is done, we can name all the fields
213 
214 struct sSprite {
215 	int16 field_0;		// X
216 	int16 field_2;
217 	int16 field_4;		// Y
218 	int16 field_6;
219 	int16 field_8;		// Animation   mSprite_SheetPtr[field_8][field_a]
220 	int16 field_A;		// FrameNumber mSprite_SheetPtr[field_8][field_a]
221 	int16 field_C;
222 	int16 field_E;
223 	int16 field_10;		// Next Direction
224 	int16 field_12;
225 	int16 field_14;     //  Projectile: Add to Y
226 	int16 field_16;     //  Projectile: Add to X
227 	int16 field_18;		// Sprite Type
228 
229 	union {
230 		int32		field_1A;
231 		sSprite*	field_1A_sprite;    // Created by Sprite
232 	};
233 
234 	union {
235 
236 		struct {
237 			int16 field_1E;
238 			int16 field_20;	// Height
239 		};
240 
241 		int32 field_1E_Big;
242 	};
243 
244 	int16 field_22;		// Player: eSprite_PersonType
245 	int16 field_24;
246 	int16 field_26;		// Target X
247 	int16 field_28;		// Target Y
248 	int16 field_2A;
249 	int16 field_2C;		// eSprite_DrawOrder
250 	int16 field_2E;		// Weapon Target X
251 	int16 field_30;		// Weapon Target Y
252 	int16 field_32;		// Player: Squad Number
253 	int16 field_34;
254 	int16 field_36;		// Speed ?
255 	int16 field_38;		// eSprite_Anim
256 	int16 field_3A;
257 	int16 field_3C;		// Player: Face Direction
258 	int16 field_3E;
259 	int16 field_40; // Player: Next Squad Walk Target Index
260 	int8 field_42;  // Player: Finished Walking
261 	int8 field_43;	// Player: Reached other Troop
262 	int8 field_44;
263 	int8 field_45;
264 
265 	// Eventually this should be replaced
266 	union {
267 		int32			field_46;
268 		sMission_Troop*  field_46_mission_troop;
269 		sSprite*		field_46_sprite;
270 	};
271 
272 	int16 field_4A;		// Player: Fire if mouse pressed
273 	int8 field_4C;
274 	int8 field_4D;
275 	int8 field_4E;
276 	int8 field_4F;			// Player: -1 = In water
277 	int16 field_50;
278 	int16 field_52;			// Video: Number of rows not to draw
279 	int8 field_54;			// Human: Fired Weapon
280 	int8 field_55;
281 	int8 field_56;
282 	int8 field_57;			// Human: Weapon Fired Cooldown
283 	int8 field_58;          // Has Shadow
284 	int8 field_59;
285 	int8 field_5A;
286 	int8 field_5B;			// Human: Is Sinking
287 	int8 field_5C;			// 1 = Was Drawn
288 
289 	int8 field_5D;          // 5E contains index into mGame_Data.mSoldiers_Allocated
290 
291     // Eventually this should be replaced
292     // Perhaps a linked list could replace mSprite and we use an iterator here
293     union {
294 		int32 field_5E_Squad;
295         size_t field_5E;			// Index inside mSprites (if 5D == false)
296         sMission_Troop *field_5E_SoldierAllocated;  // Soldier Ptr who killed sprite
297     };
298 
299 	int8 field_60;			// Current Terrain Type
300 	int8 field_61;
301 	int16 field_62;         // AI: Aggression
302 	int8 field_64;
303 	int8 field_65;			// -1 = Enabled?
304 	sSprite* field_66;		// Human-Player: Vehicle Walk Target
305 
306                             // Eventually this should be replaced
307 	union {
308 		int64	 field_6A;
309 		sSprite* field_6A_sprite;	// Human-Player: Current Vehicle
310 	};
311 
312 	int8 field_6E;			// Human-Player: In Vehicle;  Non-Human Player: Can't be run over
313 	int8 field_6F;			// Vehicle Type
314 	sSprite* field_70;		// Hostage: Following Sprite
315 	int8 field_74;			// Helicopter: Restart Anim Frame Number
316 	int8 field_75;			// Human-Player: 0x02 = invincibility, 0x01 = homing missiles
317 
sSpritesSprite318 	sSprite() {
319 		Clear();
320 	}
321 
322 	void Clear();
323 
getPositionsSprite324 	cPosition *getPosition() { return new cPosition(field_0, field_4); }
325 
getXsSprite326 	int getX() const { return field_0; }
setXsSprite327 	void setX(int pX) { field_0 = pX; }
328 
getYsSprite329 	int getY() const { return field_4; }
setYsSprite330 	void setY(int pY) { field_4 = pY; }
331 };
332 
333 struct sWeaponData {
334 	int16	mSpeed;
335 	int16	mAliveTime;			// Time bullet will travel
336 	int16	mCooldown;
337 	int16	mDeviatePotential;	// Potential for a bullet to deviate
338 	int16	field_8;
339 };
340 
341 
342 extern const int16 mEnemy_Unit_Types[];
343 
344 extern const int16 mSprite_Missile_CanLock[];
345 extern const int16 mSprite_Width[];
346 extern const int16 mSprite_Height_Top[];
347 extern const int16 mSprite_Height_Bottom[];
348 extern const int16 mSprite_Can_Be_RunOver[];
349 extern const int16 mSprite_Explosion_Area_PerFrame[];
350 extern const int16 mSprite_Explosion_Positions[];
351 extern const int16 mSprite_Turret_Positions[];
352 extern const int16 mSprite_Helicopter_Light_Positions[];
353 extern const int16 mSprite_Helicopter_Sounds[];
354 extern const int16 mSprite_SpiderMine_Frames[];
355 extern const int16 mSprite_Hostage_Frames[];
356 extern const int16 mSprite_Helicopter_CallPad_Frames[];
357 extern const sWeaponData mSprite_Bullet_UnitData[];
358 extern const int16 mSprite_Player_MissionOver_Frames[];
359 extern const int8 mSprite_Seal_AnimFrames[];
360 extern const int16 mSprite_VehiclePosition_Mod[];
361 extern const int16 mSprite_Computer_Animation[];
362 extern const int16 mSprite_Seal_Frames[];
363 extern const int16 mSprite_Computer_Frames[];
364 extern const int8 mSprite_Civilian_Sound_Death[];
365 extern const int8 mSprite_Soldier_Unk[];
366 extern const int16 mSprite_Direction_Frame_Unk[];
367 extern const int16* mSprite_AnimationPtrs[];
368 extern const int16 mSprite_Speed_Direction_Modifier[];
369 extern const std::vector<std::vector<int16>> mSoldier_Squad_Fire_RotationOrder;
370