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