summaryrefslogtreecommitdiff
path: root/src/shpanim.c
diff options
context:
space:
mode:
authorSteven Fuller <relnev@icculus.org>2001-07-01 00:55:22 +0000
committerPatryk Obara <dreamer.tan@gmail.com>2019-08-20 02:09:04 +0200
commit2186d5f3f95cd74a070a490d899291648d58667a (patch)
tree55241a1afa3e1a22e0b6593a8dead0b703800f44 /src/shpanim.c
parent218ca90543758a20ac326e444ca0643174ca7384 (diff)
Initial revision
Diffstat (limited to 'src/shpanim.c')
-rw-r--r--src/shpanim.c486
1 files changed, 486 insertions, 0 deletions
diff --git a/src/shpanim.c b/src/shpanim.c
new file mode 100644
index 0000000..37fb6fc
--- /dev/null
+++ b/src/shpanim.c
@@ -0,0 +1,486 @@
+#include "3dc.h"
+
+#define UseLocalAssert Yes
+#include "ourasert.h"
+
+extern int NormalFrameTime;
+extern int NumActiveBlocks;
+extern DISPLAYBLOCK * ActiveBlockList[];
+
+
+void CopyAnimationFrameToShape (SHAPEANIMATIONCONTROLDATA *sacd, DISPLAYBLOCK * dptr)
+{
+ SHAPEHEADER * shp = dptr->ObShapeData;
+
+ GLOBALASSERT (sacd->current_frame >= 0);
+ GLOBALASSERT (sacd->current_frame < (signed)sacd->sequence->num_frames);
+
+ shp->points[0] = sacd->sequence->anim_frames[sacd->current_frame].vertices;
+ shp->sh_normals[0] = sacd->sequence->anim_frames[sacd->current_frame].item_normals;
+}
+
+static void CopyAnimationSequenceDataToObject (SHAPEANIMATIONSEQUENCE * sas, DISPLAYBLOCK * dptr)
+{
+ dptr->ObRadius = sas->radius;
+
+ dptr->ObMaxX = sas->max_x;
+ dptr->ObMinX = sas->min_x;
+
+ dptr->ObMaxY = sas->max_y;
+ dptr->ObMinY = sas->min_y;
+
+ dptr->ObMaxZ = sas->max_z;
+ dptr->ObMinZ = sas->min_z;
+}
+
+static void ChooseNextFrame (SHAPEANIMATIONCONTROLDATA *current)
+{
+ while (current->time_to_next_frame <= 0)
+ {
+ current->time_to_next_frame += current->seconds_per_frame;
+
+ if (current->reversed)
+ current->current_frame --;
+ else
+ current->current_frame ++;
+
+ current->done_a_frame = 1;
+
+ if (current->current_frame >= (signed)current->sequence->num_frames)
+ current->current_frame = 0;
+ else if (current->current_frame < 0)
+ current->current_frame = current->sequence->num_frames-1;
+
+ if (current->current_frame == (signed)current->end_frame
+ && current->done_a_frame
+ && (current->stop_at_end || current->pause_at_end))
+ {
+ break;
+ }
+ }
+}
+
+void DoShapeAnimation (DISPLAYBLOCK * dptr)
+{
+ SHAPEANIMATIONCONTROLLER * sac = dptr->ShapeAnimControlBlock;
+ SHAPEANIMATIONCONTROLDATA * active_sequence = &sac->current;
+
+ GLOBALASSERT (sac);
+
+ if (!sac->playing)
+ return;
+
+ if (active_sequence->empty)
+ return;
+
+ active_sequence->time_to_next_frame -= NormalFrameTime;
+
+ if (active_sequence->time_to_next_frame > 0)
+ return;
+
+ // At this point we may have switched to the last frame
+ // but still had a bit of time left on it
+
+ if ((active_sequence->current_frame == (signed)active_sequence->end_frame
+ && active_sequence->done_a_frame
+ && active_sequence->stop_at_end) || active_sequence->stop_now)
+ {
+ // set to next, or finished
+ if (sac->next.empty)
+ {
+ sac->finished = 1;
+ sac->playing = 0;
+ return;
+ }
+ else
+ {
+ sac->next.time_to_next_frame = sac->current.time_to_next_frame;
+ sac->current = sac->next;
+ sac->next.empty = 1;
+
+ active_sequence->time_to_next_frame += active_sequence->seconds_per_frame;
+ ChooseNextFrame (active_sequence);
+
+ CopyAnimationSequenceDataToObject (active_sequence->sequence, dptr);
+ return;
+ }
+ }
+ else if ( active_sequence->current_frame == (signed)active_sequence->end_frame
+ && active_sequence->done_a_frame
+ && active_sequence->pause_at_end)
+ {
+ active_sequence->pause_at_end = 0;
+ sac->playing = 0;
+ active_sequence->done_a_frame = 0;
+ return;
+ }
+
+ ChooseNextFrame (active_sequence);
+
+ // if we have reached the last frame and we still have time
+ // continue else swap sequences
+
+ if (active_sequence->time_to_next_frame <= 0)
+ {
+ if (active_sequence->current_frame == (signed)active_sequence->end_frame
+ && active_sequence->done_a_frame
+ && active_sequence->stop_at_end)
+ {
+ // set to next, or finished
+ if (sac->next.empty)
+ {
+ sac->finished = 1;
+ sac->playing = 0;
+ return;
+ }
+ else
+ {
+ sac->next.time_to_next_frame = sac->current.time_to_next_frame;
+
+ // this will change the active_sequence pointers contents
+ sac->current = sac->next;
+ CopyAnimationSequenceDataToObject (active_sequence->sequence, dptr);
+
+
+ // If I had a linked list (or queue) of sequences
+ // I may want to put the next bit of code differently
+
+ active_sequence->time_to_next_frame += active_sequence->seconds_per_frame;
+
+ ChooseNextFrame (active_sequence);
+
+ return;
+ }
+ }
+ else if ( active_sequence->current_frame == (signed)active_sequence->end_frame
+ && active_sequence->done_a_frame
+ && active_sequence->pause_at_end)
+ {
+ active_sequence->pause_at_end = 0;
+ sac->playing = 0;
+ active_sequence->done_a_frame = 0;
+ return;
+ }
+ else
+ {
+ // Shouldn't be here
+ GLOBALASSERT (0);
+ }
+ }
+
+}
+
+
+void DoAllShapeAnimations ()
+{
+ int i;
+
+ for (i=0; i<NumActiveBlocks; i++)
+ {
+ DISPLAYBLOCK * dptr = ActiveBlockList[i];
+
+ if (dptr->ShapeAnimControlBlock)
+ {
+ DoShapeAnimation(dptr);
+ }
+
+ }
+
+}
+
+
+unsigned int SetShapeAnimationSequence (DISPLAYBLOCK * dptr, SHAPEANIMATIONCONTROLDATA * sacd)
+{
+ SHAPEANIMATIONCONTROLLER * sac = dptr->ShapeAnimControlBlock;
+
+ GLOBALASSERT(sac);
+ GLOBALASSERT(sacd);
+ GLOBALASSERT(sacd->sequence_no < sac->anim_header->num_sequences);
+
+ sac->next.empty = 1;
+
+ sac->playing = 1;
+ sac->finished = 0;
+
+ sac->current.sequence_no = sacd->sequence_no;
+
+ sac->current.reversed = sacd->reversed;
+ sac->current.stop_at_end = sacd->stop_at_end;
+
+
+ sac->current.empty = 0;
+ sac->current.done_a_frame = 0;
+ sac->current.sequence = &sac->anim_header->anim_sequences[sacd->sequence_no];
+ sac->current.stop_now = 0;
+ sac->current.pause_at_end = 0;
+
+ if (sacd->default_start_and_end_frames)
+ {
+ if (sacd->reversed)
+ {
+ sac->current.start_frame = sac->current.sequence->num_frames-1;
+ sac->current.end_frame = 0;
+ }
+ else
+ {
+ sac->current.start_frame = 0;
+ sac->current.end_frame = sac->current.sequence->num_frames-1;
+ }
+ }
+ else
+ {
+ sac->current.start_frame = sacd->start_frame;
+ sac->current.end_frame = sacd->end_frame;
+ }
+
+ sac->current.seconds_per_frame = sacd->seconds_per_frame;
+
+ sac->current.current_frame = sac->current.start_frame;
+
+ sac->current.time_to_next_frame = sac->current.seconds_per_frame;
+
+ CopyAnimationSequenceDataToObject (sac->current.sequence, dptr);
+
+ return(1);
+
+
+}
+
+
+unsigned int SetNextShapeAnimationSequence (DISPLAYBLOCK * dptr, SHAPEANIMATIONCONTROLDATA * sacd)
+{
+ SHAPEANIMATIONCONTROLLER * sac = dptr->ShapeAnimControlBlock;
+
+ GLOBALASSERT(sac);
+ GLOBALASSERT(sacd);
+ GLOBALASSERT(sacd->sequence_no < sac->anim_header->num_sequences);
+
+
+ if (sac->current.empty)
+ {
+ return(SetShapeAnimationSequence (dptr,sacd));
+ }
+
+ if (sac->finished)
+ {
+ return(0);
+ }
+
+
+ sac->next.sequence_no = sacd->sequence_no;
+
+ sac->next.reversed = sacd->reversed;
+ sac->next.stop_at_end = sacd->stop_at_end;
+
+
+ sac->next.empty = 0;
+ sac->next.done_a_frame = 0;
+ sac->next.sequence = &sac->anim_header->anim_sequences[sacd->sequence_no];
+ sac->next.stop_now = 0;
+ sac->next.pause_at_end = 0;
+
+ if (sacd->default_start_and_end_frames)
+ {
+ if (sacd->reversed)
+ {
+ sac->next.start_frame = sac->next.sequence->num_frames-1;
+ sac->next.end_frame = 0;
+ }
+ else
+ {
+ sac->next.start_frame = 0;
+ sac->next.end_frame = sac->next.sequence->num_frames-1;
+ }
+ }
+ else
+ {
+ sac->next.start_frame = sacd->start_frame;
+ sac->next.end_frame = sacd->end_frame;
+ }
+
+ sac->next.seconds_per_frame = sacd->seconds_per_frame;
+
+ sac->next.current_frame = sac->next.start_frame;
+
+ sac->next.time_to_next_frame = sac->next.seconds_per_frame;
+
+ return(1);
+
+
+}
+
+void InitShapeAnimationController (SHAPEANIMATIONCONTROLLER * sac, SHAPEHEADER * shd)
+{
+ GLOBALASSERT(shd);
+ GLOBALASSERT(shd->animation_header);
+
+ sac->current.empty = 1;
+ sac->next.empty = 1;
+
+ sac->anim_header = shd->animation_header;
+
+ sac->playing = 0;
+
+}
+
+void SetCurrentShapeAnimationToStop (DISPLAYBLOCK * dptr, unsigned long stop_now, signed long end_frame)
+{
+ SHAPEANIMATIONCONTROLLER * sac = dptr->ShapeAnimControlBlock;
+
+ GLOBALASSERT(sac);
+
+ if (stop_now)
+ {
+ sac->current.stop_now = 1;
+ return;
+ }
+
+ if (end_frame != -1)
+ {
+ GLOBALASSERT (end_frame >= 0);
+ GLOBALASSERT (end_frame < (signed)sac->current.sequence->num_frames);
+
+ sac->current.end_frame = end_frame;
+ }
+
+ sac->current.stop_at_end = 1;
+
+}
+
+
+SHAPEANIMATIONCONTROLDATA const * GetCurrentShapeAnimationSequenceData (DISPLAYBLOCK * dptr)
+{
+ SHAPEANIMATIONCONTROLLER * sac = dptr->ShapeAnimControlBlock;
+
+ if (sac)
+ {
+ if (!sac->current.empty)
+ return(&sac->current);
+ }
+
+ return(0);
+}
+
+
+SHAPEANIMATIONCONTROLDATA const * GetNextShapeAnimationSequenceData (DISPLAYBLOCK * dptr)
+{
+ SHAPEANIMATIONCONTROLLER * sac = dptr->ShapeAnimControlBlock;
+
+ if (sac)
+ {
+ if (!sac->next.empty)
+ return(&sac->next);
+ }
+
+ return(0);
+
+}
+
+
+void PauseCurrentShapeAnimation (DISPLAYBLOCK * dptr, unsigned long pause_now, signed long end_frame)
+{
+ SHAPEANIMATIONCONTROLLER * sac = dptr->ShapeAnimControlBlock;
+
+ GLOBALASSERT(sac);
+
+ if (pause_now)
+ {
+ sac->playing = 0;
+ return;
+ }
+
+ if (end_frame != -1)
+ {
+ GLOBALASSERT (end_frame >= 0);
+ GLOBALASSERT (end_frame < (signed)sac->current.sequence->num_frames);
+
+ sac->current.end_frame = end_frame;
+ }
+
+ sac->current.pause_at_end = 1;
+
+}
+
+void RestartCurrentShapeAnimation (DISPLAYBLOCK * dptr)
+{
+ SHAPEANIMATIONCONTROLLER * sac = dptr->ShapeAnimControlBlock;
+
+ GLOBALASSERT(sac);
+
+ sac->playing = 1;
+
+ sac->current.pause_at_end = 0;
+
+}
+
+
+void InitShapeAnimationControlData (SHAPEANIMATIONCONTROLDATA * sacd)
+{
+ GLOBALASSERT(sacd);
+
+ sacd->seconds_per_frame = 8192;
+
+ sacd->sequence_no = 0;
+
+ sacd->default_start_and_end_frames = 1;
+ sacd->reversed = 0;
+
+ sacd->stop_at_end = 0;
+
+}
+
+unsigned int SetOrphanedShapeAnimationSequence (SHAPEANIMATIONCONTROLLER * sac, SHAPEANIMATIONCONTROLDATA * sacd)
+{
+
+ GLOBALASSERT(sac);
+ GLOBALASSERT(sacd);
+ GLOBALASSERT(sacd->sequence_no < sac->anim_header->num_sequences);
+
+ sac->next.empty = 1;
+
+ sac->playing = 1;
+ sac->finished = 0;
+
+ sac->current.sequence_no = sacd->sequence_no;
+
+ sac->current.reversed = sacd->reversed;
+ sac->current.stop_at_end = sacd->stop_at_end;
+
+
+ sac->current.empty = 0;
+ sac->current.done_a_frame = 0;
+ sac->current.sequence = &sac->anim_header->anim_sequences[sacd->sequence_no];
+ sac->current.stop_now = 0;
+ sac->current.pause_at_end = 0;
+
+ if (sacd->default_start_and_end_frames)
+ {
+ if (sacd->reversed)
+ {
+ sac->current.start_frame = sac->current.sequence->num_frames-1;
+ sac->current.end_frame = 0;
+ }
+ else
+ {
+ sac->current.start_frame = 0;
+ sac->current.end_frame = sac->current.sequence->num_frames-1;
+ }
+ }
+ else
+ {
+ sac->current.start_frame = sacd->start_frame;
+ sac->current.end_frame = sacd->end_frame;
+ }
+
+ sac->current.seconds_per_frame = sacd->seconds_per_frame;
+
+ sac->current.current_frame = sac->current.start_frame;
+
+ sac->current.time_to_next_frame = sac->current.seconds_per_frame;
+
+ /* CopyAnimationSequenceDataToObject (sac->current.sequence, dptr); */
+
+ return(1);
+
+
+}