diff options
Diffstat (limited to 'src/shpanim.c')
| -rw-r--r-- | src/shpanim.c | 486 |
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); + + +} |
