1 #include "3dc.h"
2 #include "inline.h"
3 
4 /*
5  externs for commonly used global variables and arrays
6 */
7 
8 extern MORPHDISPLAY MorphDisplay;
9 extern int NormalFrameTime;
10 
11 /*
12  Global Variables
13 */
14 
15 /*
16  Update Morphing Animation Control Block
17 */
18 
UpdateMorphing(MORPHCTRL * mcptr)19 void UpdateMorphing(MORPHCTRL *mcptr)
20 {
21 	MORPHHEADER *mhdr = mcptr->ObMorphHeader;
22 	int UpdateRate;
23 
24 
25 	/*textprint("UpdateMorphing\n");*/
26 
27 
28 	if(mcptr->ObMorphFlags & mph_flag_play) {
29 
30 		/* How fast? */
31 
32 		if(mcptr->ObMorphSpeed == ONE_FIXED) {
33 
34 			UpdateRate = NormalFrameTime;
35 
36 		}
37 
38 		else {
39 
40 			UpdateRate = MUL_FIXED(NormalFrameTime, mcptr->ObMorphSpeed);
41 
42 		}
43 
44 
45 		/* Update the current frame */
46 
47 		if(mcptr->ObMorphFlags & mph_flag_reverse) {
48 
49 			mcptr->ObMorphCurrFrame -= UpdateRate;
50 
51 			if(mcptr->ObMorphCurrFrame < 0) {
52 
53 				if(mcptr->ObMorphFlags & mph_flag_noloop) {
54 
55 					mcptr->ObMorphCurrFrame = 0;
56 
57 					/* The sequence has finished and we are at the start */
58 
59 					mcptr->ObMorphFlags |= (mph_flag_finished | mph_flag_start);
60 
61 				}
62 
63 				else {
64 
65 					mcptr->ObMorphCurrFrame += mhdr->mph_maxframes;
66 
67 					/* The sequence has looped and we are back at the end */
68 
69 					mcptr->ObMorphFlags |= (mph_flag_looped | mph_flag_end);
70 
71 				}
72 
73 			}
74 
75 		}
76 
77 		else {
78 
79 			mcptr->ObMorphCurrFrame += UpdateRate;
80 
81 			if(mcptr->ObMorphCurrFrame >= mhdr->mph_maxframes) {
82 
83 				if(mcptr->ObMorphFlags & mph_flag_noloop) {
84 
85 					/* The sequence has finished and we are at the end */
86 
87 					mcptr->ObMorphFlags |= (mph_flag_finished | mph_flag_end);
88 
89 					mcptr->ObMorphCurrFrame = mhdr->mph_maxframes - 1;
90 
91 				}
92 
93 				else {
94 
95 					mcptr->ObMorphCurrFrame -= mhdr->mph_maxframes;
96 
97 					/* The sequence has looped and we are back at the start */
98 
99 					mcptr->ObMorphFlags |= (mph_flag_looped | mph_flag_start);
100 
101 				}
102 
103 			}
104 
105 		}
106 
107 	}
108 
109 }
110 
111 
112 
113 /*
114 
115  Update the Morphing Animation for this object
116 
117 */
118 
UpdateMorphingDptr(DISPLAYBLOCK * dptr)119 void UpdateMorphingDptr(DISPLAYBLOCK *dptr)
120 {
121 	SHAPEHEADER *sptr1;
122 	SHAPEHEADER *sptr2;
123 
124 	/* Update object radius and extents */
125 
126 	GetMorphDisplay(&MorphDisplay, dptr);
127 
128 	sptr1 = MorphDisplay.md_sptr1;
129 	sptr2 = MorphDisplay.md_sptr2;
130 
131 	#if 0
132 	textprint("sptr1->shaperadius = %d\n", sptr1->shaperadius);
133 	textprint("sptr2->shaperadius = %d\n", sptr2->shaperadius);
134 	#endif
135 
136 
137 	/* Radius */
138 
139 	if(sptr1->shaperadius == sptr2->shaperadius) {
140 
141 		dptr->ObRadius = sptr1->shaperadius;
142 
143 	}
144 
145 	else {
146 
147 		dptr->ObRadius = WideMul2NarrowDiv(sptr1->shaperadius,
148 													MorphDisplay.md_one_minus_lerp,
149 													sptr2->shaperadius,
150 													MorphDisplay.md_lerp, ONE_FIXED);
151 
152 	}
153 
154 
155 	/* X Extent */
156 
157 	if(sptr1->shapemaxx == sptr2->shapemaxx) {
158 
159 		dptr->ObMaxX = sptr1->shapemaxx;
160 
161 	}
162 
163 	else {
164 
165 		dptr->ObMaxX = WideMul2NarrowDiv(sptr1->shapemaxx,
166 													MorphDisplay.md_one_minus_lerp,
167 													sptr2->shapemaxx,
168 													MorphDisplay.md_lerp, ONE_FIXED);
169 
170 	}
171 
172 	if(sptr1->shapeminx == sptr2->shapeminx) {
173 
174 		dptr->ObMinX = sptr1->shapeminx;
175 
176 	}
177 
178 	else {
179 
180 		dptr->ObMinX = WideMul2NarrowDiv(sptr1->shapeminx,
181 													MorphDisplay.md_one_minus_lerp,
182 													sptr2->shapeminx,
183 													MorphDisplay.md_lerp, ONE_FIXED);
184 
185 	}
186 
187 
188 	/* Y Extent */
189 
190 	if(sptr1->shapemaxy == sptr2->shapemaxy) {
191 
192 		dptr->ObMaxY = sptr1->shapemaxy;
193 
194 	}
195 
196 	else {
197 
198 		dptr->ObMaxY = WideMul2NarrowDiv(sptr1->shapemaxy,
199 													MorphDisplay.md_one_minus_lerp,
200 													sptr2->shapemaxy,
201 													MorphDisplay.md_lerp, ONE_FIXED);
202 
203 	}
204 
205 	if(sptr1->shapeminy == sptr2->shapeminy) {
206 
207 		dptr->ObMinY = sptr1->shapeminy;
208 
209 	}
210 
211 	else {
212 
213 		dptr->ObMinY = WideMul2NarrowDiv(sptr1->shapeminy,
214 													MorphDisplay.md_one_minus_lerp,
215 													sptr2->shapeminy,
216 													MorphDisplay.md_lerp, ONE_FIXED);
217 
218 	}
219 
220 
221 	/* Z Extent */
222 
223  	if(sptr1->shapemaxz == sptr2->shapemaxz) {
224 
225 		dptr->ObMaxZ = sptr1->shapemaxz;
226 
227 	}
228 
229 	else {
230 
231 		dptr->ObMaxZ = WideMul2NarrowDiv(sptr1->shapemaxz,
232 													MorphDisplay.md_one_minus_lerp,
233 													sptr2->shapemaxz,
234 													MorphDisplay.md_lerp, ONE_FIXED);
235 
236 	}
237 
238 	if(sptr1->shapeminz == sptr2->shapeminz) {
239 
240 		dptr->ObMinZ = sptr1->shapeminz;
241 
242 	}
243 
244 	else {
245 
246 		dptr->ObMinZ = WideMul2NarrowDiv(sptr1->shapeminz,
247 													MorphDisplay.md_one_minus_lerp,
248 													sptr2->shapeminz,
249 													MorphDisplay.md_lerp, ONE_FIXED);
250 
251 	}
252 
253 	#if 0
254 	textprint("dptr->ObRadius = %d\n", dptr->ObRadius);
255 	#endif
256 
257 }
258 
259 
260 
261 /*
262 
263  Using the current frame, calculate the lerp values and find out which two
264  shapes to interpolate between.
265 
266  Write this information back to a MORPHDISPLAY structure.
267 
268 */
269 
GetMorphDisplay(MORPHDISPLAY * md,DISPLAYBLOCK * dptr)270 void GetMorphDisplay(MORPHDISPLAY *md, DISPLAYBLOCK *dptr)
271 {
272 	MORPHFRAME *mdata;
273 	MORPHCTRL *mc = dptr->ObMorphCtrl;
274 	MORPHHEADER *mhdr = mc->ObMorphHeader;
275 
276 
277 	md->md_lerp = mc->ObMorphCurrFrame & 0xffff;
278 	md->md_one_minus_lerp = ONE_FIXED - md->md_lerp;
279 
280 	mdata = mhdr->mph_frames;
281 	mdata = &mdata[mc->ObMorphCurrFrame >> 16];
282 
283 	md->md_shape1 = mdata->mf_shape1;
284 	md->md_shape2 = mdata->mf_shape2;
285 
286 	md->md_sptr1 = GetShapeData(md->md_shape1);
287 	md->md_sptr2 = GetShapeData(md->md_shape2);
288 }
289 
290 
CopyMorphCtrl(MORPHCTRL * src,MORPHCTRL * dst)291 void CopyMorphCtrl(MORPHCTRL *src, MORPHCTRL *dst)
292 {
293 	dst->ObMorphCurrFrame = src->ObMorphCurrFrame;
294 	dst->ObMorphFlags     = src->ObMorphFlags;
295 	dst->ObMorphSpeed     = src->ObMorphSpeed;
296 	dst->ObMorphHeader    = src->ObMorphHeader;
297 }
298