1 #include "3dc.h"
2 
3 #define UseLocalAssert Yes
4 #include "ourasert.h"
5 
6 extern int NormalFrameTime;
7 extern int NumActiveBlocks;
8 extern DISPLAYBLOCK * ActiveBlockList[];
9 
10 
CopyAnimationFrameToShape(SHAPEANIMATIONCONTROLDATA * sacd,DISPLAYBLOCK * dptr)11 void CopyAnimationFrameToShape (SHAPEANIMATIONCONTROLDATA *sacd, DISPLAYBLOCK * dptr)
12 {
13 	SHAPEHEADER * shp = dptr->ObShapeData;
14 
15 	GLOBALASSERT (sacd->current_frame >= 0);
16 	GLOBALASSERT (sacd->current_frame < (signed)sacd->sequence->num_frames);
17 
18 	shp->points[0] = sacd->sequence->anim_frames[sacd->current_frame].vertices;
19 	shp->sh_normals[0] = sacd->sequence->anim_frames[sacd->current_frame].item_normals;
20 }
21 
CopyAnimationSequenceDataToObject(SHAPEANIMATIONSEQUENCE * sas,DISPLAYBLOCK * dptr)22 static void CopyAnimationSequenceDataToObject (SHAPEANIMATIONSEQUENCE * sas, DISPLAYBLOCK * dptr)
23 {
24 	dptr->ObRadius = sas->radius;
25 
26 	dptr->ObMaxX = sas->max_x;
27 	dptr->ObMinX = sas->min_x;
28 
29 	dptr->ObMaxY = sas->max_y;
30 	dptr->ObMinY = sas->min_y;
31 
32 	dptr->ObMaxZ = sas->max_z;
33 	dptr->ObMinZ = sas->min_z;
34 }
35 
ChooseNextFrame(SHAPEANIMATIONCONTROLDATA * current)36 static void ChooseNextFrame (SHAPEANIMATIONCONTROLDATA *current)
37 {
38 	while (current->time_to_next_frame <= 0)
39 	{
40 		current->time_to_next_frame += current->seconds_per_frame;
41 
42 		if (current->reversed)
43 			current->current_frame --;
44 		else
45 			current->current_frame ++;
46 
47 		current->done_a_frame = 1;
48 
49 		if (current->current_frame >= (signed)current->sequence->num_frames)
50 			current->current_frame = 0;
51 		else if (current->current_frame < 0)
52 			current->current_frame = current->sequence->num_frames-1;
53 
54 		if (current->current_frame == (signed)current->end_frame
55 				&& current->done_a_frame
56 				&& (current->stop_at_end || current->pause_at_end))
57 		{
58 			break;
59 		}
60 	}
61 }
62 
DoShapeAnimation(DISPLAYBLOCK * dptr)63 void DoShapeAnimation (DISPLAYBLOCK * dptr)
64 {
65 	SHAPEANIMATIONCONTROLLER * sac = dptr->ShapeAnimControlBlock;
66 	SHAPEANIMATIONCONTROLDATA * active_sequence = &sac->current;
67 
68 	GLOBALASSERT (sac);
69 
70 	if (!sac->playing)
71 		return;
72 
73 	if (active_sequence->empty)
74 		return;
75 
76 	active_sequence->time_to_next_frame -= NormalFrameTime;
77 
78 	if (active_sequence->time_to_next_frame > 0)
79 		return;
80 
81 	// At this point we may have switched to the last frame
82 	// but still had a bit of time left on it
83 
84 	if ((active_sequence->current_frame == (signed)active_sequence->end_frame
85 			&& active_sequence->done_a_frame
86 			&& active_sequence->stop_at_end) || active_sequence->stop_now)
87 	{
88 		// set to next, or finished
89 		if (sac->next.empty)
90 		{
91 			sac->finished = 1;
92 			sac->playing = 0;
93 			return;
94 		}
95 		else
96 		{
97 			sac->next.time_to_next_frame = sac->current.time_to_next_frame;
98 			sac->current = sac->next;
99 			sac->next.empty = 1;
100 
101 			active_sequence->time_to_next_frame += active_sequence->seconds_per_frame;
102 			ChooseNextFrame (active_sequence);
103 
104 			CopyAnimationSequenceDataToObject (active_sequence->sequence, dptr);
105 			return;
106 		}
107 	}
108 	else if ( active_sequence->current_frame == (signed)active_sequence->end_frame
109 						&& active_sequence->done_a_frame
110 						&& active_sequence->pause_at_end)
111 	{
112 		active_sequence->pause_at_end = 0;
113 		sac->playing = 0;
114 		active_sequence->done_a_frame = 0;
115 		return;
116 	}
117 
118 	ChooseNextFrame (active_sequence);
119 
120 	// if we have reached the last frame and we still have time
121 	// continue else swap sequences
122 
123 	if (active_sequence->time_to_next_frame <= 0)
124 	{
125 		if (active_sequence->current_frame == (signed)active_sequence->end_frame
126 				&& active_sequence->done_a_frame
127 				&& active_sequence->stop_at_end)
128 		{
129 			// set to next, or finished
130 			if (sac->next.empty)
131 			{
132 				sac->finished = 1;
133 				sac->playing = 0;
134 				return;
135 			}
136 			else
137 			{
138 				sac->next.time_to_next_frame = sac->current.time_to_next_frame;
139 
140 				// this will change the active_sequence pointers contents
141 				sac->current = sac->next;
142 				CopyAnimationSequenceDataToObject (active_sequence->sequence, dptr);
143 
144 
145 				// If I had a linked list (or queue) of sequences
146 				// I may want to put the next bit of code differently
147 
148 				active_sequence->time_to_next_frame += active_sequence->seconds_per_frame;
149 
150 				ChooseNextFrame (active_sequence);
151 
152 				return;
153 			}
154 		}
155 		else if ( active_sequence->current_frame == (signed)active_sequence->end_frame
156 							&& active_sequence->done_a_frame
157 							&& active_sequence->pause_at_end)
158 		{
159 			active_sequence->pause_at_end = 0;
160 			sac->playing = 0;
161 			active_sequence->done_a_frame = 0;
162 			return;
163 		}
164 		else
165 		{
166 			// Shouldn't be here
167 			GLOBALASSERT (0);
168 		}
169 	}
170 
171 }
172 
173 
DoAllShapeAnimations()174 void DoAllShapeAnimations ()
175 {
176 	int i;
177 
178 	for (i=0; i<NumActiveBlocks; i++)
179 	{
180 		DISPLAYBLOCK * dptr = ActiveBlockList[i];
181 
182 		if (dptr->ShapeAnimControlBlock)
183 		{
184 			DoShapeAnimation(dptr);
185 		}
186 
187 	}
188 
189 }
190 
191 
SetShapeAnimationSequence(DISPLAYBLOCK * dptr,SHAPEANIMATIONCONTROLDATA * sacd)192 unsigned int SetShapeAnimationSequence (DISPLAYBLOCK * dptr, SHAPEANIMATIONCONTROLDATA * sacd)
193 {
194 	SHAPEANIMATIONCONTROLLER * sac = dptr->ShapeAnimControlBlock;
195 
196 	GLOBALASSERT(sac);
197 	GLOBALASSERT(sacd);
198 	GLOBALASSERT(sacd->sequence_no < sac->anim_header->num_sequences);
199 
200 	sac->next.empty = 1;
201 
202 	sac->playing = 1;
203 	sac->finished = 0;
204 
205 	sac->current.sequence_no = sacd->sequence_no;
206 
207 	sac->current.reversed = sacd->reversed;
208 	sac->current.stop_at_end = sacd->stop_at_end;
209 
210 
211 	sac->current.empty = 0;
212 	sac->current.done_a_frame = 0;
213 	sac->current.sequence = &sac->anim_header->anim_sequences[sacd->sequence_no];
214 	sac->current.stop_now = 0;
215 	sac->current.pause_at_end = 0;
216 
217 	if (sacd->default_start_and_end_frames)
218 	{
219 		if (sacd->reversed)
220 		{
221 			sac->current.start_frame = sac->current.sequence->num_frames-1;
222 			sac->current.end_frame = 0;
223 		}
224 		else
225 		{
226 			sac->current.start_frame = 0;
227 			sac->current.end_frame = sac->current.sequence->num_frames-1;
228 		}
229 	}
230 	else
231 	{
232 		sac->current.start_frame = sacd->start_frame;
233 		sac->current.end_frame = sacd->end_frame;
234 	}
235 
236 	sac->current.seconds_per_frame = sacd->seconds_per_frame;
237 
238 	sac->current.current_frame = sac->current.start_frame;
239 
240 	sac->current.time_to_next_frame = sac->current.seconds_per_frame;
241 
242 	CopyAnimationSequenceDataToObject (sac->current.sequence, dptr);
243 
244 	return(1);
245 
246 
247 }
248 
249 
SetNextShapeAnimationSequence(DISPLAYBLOCK * dptr,SHAPEANIMATIONCONTROLDATA * sacd)250 unsigned int SetNextShapeAnimationSequence (DISPLAYBLOCK * dptr, SHAPEANIMATIONCONTROLDATA * sacd)
251 {
252 	SHAPEANIMATIONCONTROLLER * sac = dptr->ShapeAnimControlBlock;
253 
254 	GLOBALASSERT(sac);
255 	GLOBALASSERT(sacd);
256 	GLOBALASSERT(sacd->sequence_no < sac->anim_header->num_sequences);
257 
258 
259 	if (sac->current.empty)
260 	{
261 		return(SetShapeAnimationSequence (dptr,sacd));
262 	}
263 
264 	if (sac->finished)
265 	{
266 		return(0);
267 	}
268 
269 
270 	sac->next.sequence_no = sacd->sequence_no;
271 
272 	sac->next.reversed = sacd->reversed;
273 	sac->next.stop_at_end = sacd->stop_at_end;
274 
275 
276 	sac->next.empty = 0;
277 	sac->next.done_a_frame = 0;
278 	sac->next.sequence = &sac->anim_header->anim_sequences[sacd->sequence_no];
279 	sac->next.stop_now = 0;
280 	sac->next.pause_at_end = 0;
281 
282 	if (sacd->default_start_and_end_frames)
283 	{
284 		if (sacd->reversed)
285 		{
286 			sac->next.start_frame = sac->next.sequence->num_frames-1;
287 			sac->next.end_frame = 0;
288 		}
289 		else
290 		{
291 			sac->next.start_frame = 0;
292 			sac->next.end_frame = sac->next.sequence->num_frames-1;
293 		}
294 	}
295 	else
296 	{
297 		sac->next.start_frame = sacd->start_frame;
298 		sac->next.end_frame = sacd->end_frame;
299 	}
300 
301 	sac->next.seconds_per_frame = sacd->seconds_per_frame;
302 
303 	sac->next.current_frame = sac->next.start_frame;
304 
305 	sac->next.time_to_next_frame = sac->next.seconds_per_frame;
306 
307 	return(1);
308 
309 
310 }
311 
InitShapeAnimationController(SHAPEANIMATIONCONTROLLER * sac,SHAPEHEADER * shd)312 void InitShapeAnimationController (SHAPEANIMATIONCONTROLLER * sac, SHAPEHEADER * shd)
313 {
314 	GLOBALASSERT(shd);
315 	GLOBALASSERT(shd->animation_header);
316 
317 	sac->current.empty = 1;
318 	sac->next.empty = 1;
319 
320 	sac->anim_header = shd->animation_header;
321 
322 	sac->playing = 0;
323 
324 }
325 
SetCurrentShapeAnimationToStop(DISPLAYBLOCK * dptr,unsigned long stop_now,signed long end_frame)326 void SetCurrentShapeAnimationToStop (DISPLAYBLOCK * dptr, unsigned long stop_now, signed long end_frame)
327 {
328 	SHAPEANIMATIONCONTROLLER * sac = dptr->ShapeAnimControlBlock;
329 
330 	GLOBALASSERT(sac);
331 
332 	if (stop_now)
333 	{
334 		sac->current.stop_now = 1;
335 		return;
336 	}
337 
338 	if (end_frame != -1)
339 	{
340 		GLOBALASSERT (end_frame >= 0);
341 		GLOBALASSERT (end_frame < (signed)sac->current.sequence->num_frames);
342 
343 		sac->current.end_frame = end_frame;
344 	}
345 
346 	sac->current.stop_at_end = 1;
347 
348 }
349 
350 
GetCurrentShapeAnimationSequenceData(DISPLAYBLOCK * dptr)351 SHAPEANIMATIONCONTROLDATA const * GetCurrentShapeAnimationSequenceData (DISPLAYBLOCK * dptr)
352 {
353 	SHAPEANIMATIONCONTROLLER * sac = dptr->ShapeAnimControlBlock;
354 
355 	if (sac)
356 	{
357 		if (!sac->current.empty)
358 			return(&sac->current);
359 	}
360 
361 	return(0);
362 }
363 
364 
GetNextShapeAnimationSequenceData(DISPLAYBLOCK * dptr)365 SHAPEANIMATIONCONTROLDATA const * GetNextShapeAnimationSequenceData (DISPLAYBLOCK * dptr)
366 {
367 	SHAPEANIMATIONCONTROLLER * sac = dptr->ShapeAnimControlBlock;
368 
369 	if (sac)
370 	{
371 		if (!sac->next.empty)
372 			return(&sac->next);
373 	}
374 
375 	return(0);
376 
377 }
378 
379 
PauseCurrentShapeAnimation(DISPLAYBLOCK * dptr,unsigned long pause_now,signed long end_frame)380 void PauseCurrentShapeAnimation (DISPLAYBLOCK * dptr, unsigned long pause_now, signed long end_frame)
381 {
382 	SHAPEANIMATIONCONTROLLER * sac = dptr->ShapeAnimControlBlock;
383 
384 	GLOBALASSERT(sac);
385 
386 	if (pause_now)
387 	{
388 		sac->playing = 0;
389 		return;
390 	}
391 
392 	if (end_frame != -1)
393 	{
394 		GLOBALASSERT (end_frame >= 0);
395 		GLOBALASSERT (end_frame < (signed)sac->current.sequence->num_frames);
396 
397 		sac->current.end_frame = end_frame;
398 	}
399 
400 	sac->current.pause_at_end = 1;
401 
402 }
403 
RestartCurrentShapeAnimation(DISPLAYBLOCK * dptr)404 void RestartCurrentShapeAnimation (DISPLAYBLOCK * dptr)
405 {
406 	SHAPEANIMATIONCONTROLLER * sac = dptr->ShapeAnimControlBlock;
407 
408 	GLOBALASSERT(sac);
409 
410 	sac->playing = 1;
411 
412 	sac->current.pause_at_end = 0;
413 
414 }
415 
416 
InitShapeAnimationControlData(SHAPEANIMATIONCONTROLDATA * sacd)417 void InitShapeAnimationControlData (SHAPEANIMATIONCONTROLDATA * sacd)
418 {
419 	GLOBALASSERT(sacd);
420 
421 	sacd->seconds_per_frame = 8192;
422 
423 	sacd->sequence_no = 0;
424 
425 	sacd->default_start_and_end_frames = 1;
426 	sacd->reversed = 0;
427 
428 	sacd->stop_at_end = 0;
429 
430 }
431 
SetOrphanedShapeAnimationSequence(SHAPEANIMATIONCONTROLLER * sac,SHAPEANIMATIONCONTROLDATA * sacd)432 unsigned int SetOrphanedShapeAnimationSequence (SHAPEANIMATIONCONTROLLER * sac, SHAPEANIMATIONCONTROLDATA * sacd)
433 {
434 
435 	GLOBALASSERT(sac);
436 	GLOBALASSERT(sacd);
437 	GLOBALASSERT(sacd->sequence_no < sac->anim_header->num_sequences);
438 
439 	sac->next.empty = 1;
440 
441 	sac->playing = 1;
442 	sac->finished = 0;
443 
444 	sac->current.sequence_no = sacd->sequence_no;
445 
446 	sac->current.reversed = sacd->reversed;
447 	sac->current.stop_at_end = sacd->stop_at_end;
448 
449 
450 	sac->current.empty = 0;
451 	sac->current.done_a_frame = 0;
452 	sac->current.sequence = &sac->anim_header->anim_sequences[sacd->sequence_no];
453 	sac->current.stop_now = 0;
454 	sac->current.pause_at_end = 0;
455 
456 	if (sacd->default_start_and_end_frames)
457 	{
458 		if (sacd->reversed)
459 		{
460 			sac->current.start_frame = sac->current.sequence->num_frames-1;
461 			sac->current.end_frame = 0;
462 		}
463 		else
464 		{
465 			sac->current.start_frame = 0;
466 			sac->current.end_frame = sac->current.sequence->num_frames-1;
467 		}
468 	}
469 	else
470 	{
471 		sac->current.start_frame = sacd->start_frame;
472 		sac->current.end_frame = sacd->end_frame;
473 	}
474 
475 	sac->current.seconds_per_frame = sacd->seconds_per_frame;
476 
477 	sac->current.current_frame = sac->current.start_frame;
478 
479 	sac->current.time_to_next_frame = sac->current.seconds_per_frame;
480 
481 	/* CopyAnimationSequenceDataToObject (sac->current.sequence, dptr); */
482 
483 	return(1);
484 
485 
486 }
487