home *** CD-ROM | disk | FTP | other *** search
- /**********************************************************************
- *
- * File : Animate.c
- *
- * Abstract : Handle the loading, destruction and control of the
- * knight animation keyframes
- *
- **********************************************************************
- *
- * This file is a product of Criterion Software Ltd.
- *
- * This file is provided as is with no warranties of any kind and is
- * provided without any obligation on Criterion Software Ltd. or
- * Canon Inc. to assist in its use or modification.
- *
- * Criterion Software Ltd. will not, under any
- * circumstances, be liable for any lost revenue or other damages arising
- * from the use of this file.
- *
- * Copyright (c) 1995 Criterion Software Ltd.
- * All Rights Reserved.
- *
- * RenderWare is a trademark of Canon Inc.
- *
- ************************************************************************/
-
- /**********************************************************************
- *
- * Header files.
- *
- **********************************************************************/
-
- #define INCLUDE_SHELLAPI_H
-
- #include <windows.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <ctype.h>
-
- #include "rwlib.h"
- #include "rwwin.h"
-
- #include "animate.h"
- #include "knight.h"
-
- typedef float TyMatrix[12];
-
- typedef struct {
- int tag;
- TyMatrix m;
- } TyTokTransform;
-
- typedef enum {
- TK_NULL,
- TK_FRAME,
- TK_TRANSFORM,
- } EnToken;
-
- typedef struct {
- union {
- int frame;
- TyTokTransform transform;
- } u;
- } TyToken;
-
- TyToken tok;
- long FrameCount = 0;
-
- /*********************************************************************/
- int
- ReadInt(FILE * stream, int *val)
- {
- char buffer[256];
-
- for(;;)
- {
- if (fscanf(stream, "%250s", buffer) == 1)
- {
- if (buffer[0] == '#')
- {
- fgets(buffer, sizeof(buffer), stream);
- }
- else
- {
- return(sscanf(buffer, "%d", val));
- }
- }
- else
- {
- return(0);
- }
- }
- }
-
- /*********************************************************************/
- int
- ReadFloat(FILE *stream, float *val)
- {
- char buffer[256];
-
- for(;;)
- {
- if (fscanf(stream, "%250s", buffer) == 1)
- {
- if (buffer[0] == '#')
- {
- fgets(buffer, sizeof(buffer), stream);
- }
- else
- {
- if (sscanf(buffer, "%f", val))
- {
- return(1);
- }
- }
- }
- else
- {
- return(0);
- }
- }
- }
-
- /**********************************************************************/
- EnToken ReadToken(FILE *stream)
- {
- int c;
- int i;
- char *s;
- char string[128];
-
- /* skip whitespace */
- do
- {
- c = fgetc(stream);
- }
- while (isspace(c));
-
- i = 0;
- s = string;
- while ((c != EOF) && (!isspace(c)))
- {
- /*
- * Only append the characters read if there is room in the
- * output string (this will truncate the string read).
- */
- if (i < 127)
- {
- *s++ = (char)c;
- i++;
- }
- c = fgetc(stream);
- }
- /*
- * Put the terminating character back.
- */
- ungetc(c, stream);
- *s = '\0';
-
- strlwr(string);
- if (!strcmp(string, "frame"))
- {
- if (ReadInt(stream, &tok.u.frame))
- return(TK_FRAME);
- }
- else if (!strcmp(string, "transform"))
- {
- if (ReadInt(stream, &tok.u.transform.tag) &&
- ReadFloat(stream, &tok.u.transform.m[0]) &&
- ReadFloat(stream, &tok.u.transform.m[1]) &&
- ReadFloat(stream, &tok.u.transform.m[2]) &&
- ReadFloat(stream, &tok.u.transform.m[3]) &&
- ReadFloat(stream, &tok.u.transform.m[4]) &&
- ReadFloat(stream, &tok.u.transform.m[5]) &&
- ReadFloat(stream, &tok.u.transform.m[6]) &&
- ReadFloat(stream, &tok.u.transform.m[7]) &&
- ReadFloat(stream, &tok.u.transform.m[8]) &&
- ReadFloat(stream, &tok.u.transform.m[9]) &&
- ReadFloat(stream, &tok.u.transform.m[10]) &&
- ReadFloat(stream, &tok.u.transform.m[11]))
- return(TK_TRANSFORM);
- }
- return (TK_NULL);
- }
-
- void DestroyFrame(TyFrameData *fd)
- {
- int i;
- if (fd->frames)
- {
- for (i=0; i < fd->frames; i++)
- RwDestroyMatrix(fd->frame[i]);
-
- free(fd->frame);
- }
- fd->frames = 0;
- fd->frame = NULL;
- free(fd);
- }
-
- TyFrameData *CreateFrame(void)
- {
- TyFrameData *fd;
- RwMatrix4d **frame;
-
- fd = malloc(sizeof(TyFrameData));
- if (fd)
- {
- frame = malloc(sizeof(RwMatrix4d *));
- if (frame)
- {
- *frame = RwCreateMatrix();
- if (*frame)
- {
- fd->frames = 1;
- fd->frame = frame;
- return fd;
- }
- free(frame);
- }
- free(fd);
- }
- return NULL;
- }
-
- int AddFrame(TyFrameData *fd)
- {
- RwMatrix4d **new_frame;
-
- new_frame = realloc(fd->frame, sizeof(RwMatrix4d *) * (fd->frames +1));
- if (new_frame)
- {
- fd->frame = new_frame;
- fd->frame[fd->frames] = RwCreateMatrix();
- if (fd->frame[fd->frames])
- {
- fd->frames++;
- return TRUE;
- }
- }
- DestroyFrame(fd);
- return FALSE;
- }
- void DestroyAnimation(TyAnimationData *ad)
- {
- if (ad->animations)
- {
- free(ad->animation);
- }
- free(ad);
- }
-
- TyAnimationData *CreateAnimation(void)
- {
- TyAnimationData *ad;
- TyAnimation *new;
- ad = malloc(sizeof(TyAnimationData));
- if (ad)
- {
- new = malloc(sizeof(TyAnimation));
- if (new)
- {
- ad->current_frame = 0;
- ad->current_animation = NULL;
- ad->next_animation = NULL;
- ad->animations = 1;
- ad->animation = new;
- ad->state = A_ON;
- ad->opacity = CREAL(1.0);
- return ad;
- }
- free(ad);
- }
- return NULL;
- }
-
- TyAnimationData *AddAnimation(TyAnimationData *ad, char *name, int start, int end, int react)
- {
- TyAnimation *new;
-
- if (ad)
- {
- new = realloc(ad->animation, sizeof(TyAnimation) * (ad->animations +1));
- if (!new)
- {
- DestroyAnimation(ad);
- return NULL;
- }
- ad->animation = new;
- ad->animations++;
- }
- else
- {
- ad = CreateAnimation();
- if (!ad)
- {
- return NULL;
- }
- }
- ad->animation[ad->animations-1].start = start;
- ad->animation[ad->animations-1].end = end;
- ad->animation[ad->animations-1].react = react;
- strncpy(ad->animation[ad->animations-1].name, name, 15);
- ad->animation[ad->animations-1].name[15] = 0;
- return ad;
- }
-
- TyAnimation *FindAnimation(TyAnimationData *ad, char *name)
- {
- int i;
-
- for (i = 0; i < ad->animations; i++)
- {
- if (!strncmp(ad->animation[i].name, name,15))
- {
- return (&ad->animation[i]);
- }
- }
- return(NULL);
- }
-
- void SetAnimationState(RwClump *clump, EnAnimation state)
- {
- TyAnimationData *ad;
-
- ad = RwGetClumpData(clump);
- if (ad)
- {
- ad->state = state;
- }
- }
-
- EnAnimation GetAnimationState(RwClump *clump)
- {
- TyAnimationData *ad;
-
- ad = RwGetClumpData(clump);
- if (ad)
- {
- return (ad->state);
- }
- return (A_OFF);
- }
-
- /**********************************************************************/
- int LoadAnimation(RwClump *clump, char *filename)
- {
- int current_frame = 0;
- RwClump *active_clump;
- TyFrameData *fd;
- FILE *fp;
-
- fp = fopen(filename, "r");
- if (!fp)
- return FALSE;
-
- for(;;)
- {
- switch (ReadToken(fp))
- {
- case TK_FRAME:
- current_frame = tok.u.frame;
- break;
- case TK_TRANSFORM:
- active_clump = RwFindTaggedClump(clump, (RwInt32)tok.u.transform.tag);
- if (active_clump)
- {
- fd = RwGetClumpData(active_clump);
- if (!fd)
- {
- fd = CreateFrame();
- if (!fd)
- return FALSE;
- RwSetClumpData(active_clump, fd);
- }
- else
- {
- if (!AddFrame(fd))
- {
- RwSetClumpData(active_clump, NULL);
- return FALSE;
- }
- }
- if (current_frame != fd->frames -1)
- {
- DestroyFrame(fd);
- RwSetClumpData(active_clump, NULL);
- return(FALSE);
- }
- RwSetMatrixElement(fd->frame[current_frame], 0, 0, FL2REAL(tok.u.transform.m[0]));
- RwSetMatrixElement(fd->frame[current_frame], 0, 1, FL2REAL(tok.u.transform.m[1]));
- RwSetMatrixElement(fd->frame[current_frame], 0, 2, FL2REAL(tok.u.transform.m[2]));
- RwSetMatrixElement(fd->frame[current_frame], 0, 3, CREAL(0.0));
- RwSetMatrixElement(fd->frame[current_frame], 1, 0, FL2REAL(tok.u.transform.m[3]));
- RwSetMatrixElement(fd->frame[current_frame], 1, 1, FL2REAL(tok.u.transform.m[4]));
- RwSetMatrixElement(fd->frame[current_frame], 1, 2, FL2REAL(tok.u.transform.m[5]));
- RwSetMatrixElement(fd->frame[current_frame], 1, 3, CREAL(0.0));
- RwSetMatrixElement(fd->frame[current_frame], 2, 0, FL2REAL(tok.u.transform.m[6]));
- RwSetMatrixElement(fd->frame[current_frame], 2, 1, FL2REAL(tok.u.transform.m[7]));
- RwSetMatrixElement(fd->frame[current_frame], 2, 2, FL2REAL(tok.u.transform.m[8]));
- RwSetMatrixElement(fd->frame[current_frame], 2, 3, CREAL(0.0));
- RwSetMatrixElement(fd->frame[current_frame], 3, 0, FL2REAL(tok.u.transform.m[9]));
- RwSetMatrixElement(fd->frame[current_frame], 3, 1, FL2REAL(tok.u.transform.m[10]));
- RwSetMatrixElement(fd->frame[current_frame], 3, 2, FL2REAL(tok.u.transform.m[11]));
- RwSetMatrixElement(fd->frame[current_frame], 3, 3, CREAL(1.0));
- }
- break;
- default:
- fclose(fp);
- return TRUE;
- }
- }
- }
-
- void DefineAnimation(RwClump *clump, char *name, int start, int end, int react)
- {
- TyAnimationData *ad;
-
- ad = RwGetClumpData(clump);
- RwSetClumpData(clump, AddAnimation(ad, name, start, end, react));
- }
-
- void StartAnimation(RwClump *clump, char *name)
- {
- TyAnimationData *ad;
-
- ad = RwGetClumpData(clump);
-
- if (ad)
- {
- if (!ad->current_animation)
- {
- ad->current_animation = FindAnimation(ad, name);
- if (ad->current_animation)
- ad->current_frame = ad->current_animation->start;
- }
- else
- {
- ad->next_animation = FindAnimation(ad, name);
- }
- }
- }
-
- RwClump *SetClumpFrame(RwClump *c, RwInt32 frame)
- {
- TyFrameData *fd;
-
- if (RwGetClumpParent(c))
- {
- fd = RwGetClumpData(c);
- if (fd)
- {
- if (frame < fd->frames)
- {
- RwTransformClump(c, fd->frame[frame], rwREPLACE);
- }
- }
- }
- return c;
- }
-
- RwClump *SetClumpOpacity(RwClump *clump, RwReal opacity)
- {
- return (RwForAllPolygonsInClumpReal(clump, RwSetPolygonOpacity, opacity));
- }
-
- int ResolveClump(RwClump *clump)
- {
- TyAnimationData *ad;
-
- ad = RwGetClumpData(clump);
- if (ad)
- {
- ad->opacity = RAdd(ad->opacity, CREAL(0.05));
- if (ad->opacity > CREAL(1.0))
- ad->opacity = CREAL(1.0);
- RwForAllClumpsInHierarchyReal(clump, SetClumpOpacity, ad->opacity);
- if (ad->opacity < CREAL(1.0))
- return(FALSE);
- }
- return (TRUE);
- }
-
- int DissolveClump(RwClump *clump)
- {
- TyAnimationData *ad;
-
- ad = RwGetClumpData(clump);
- if (ad)
- {
- ad->opacity = RSub(ad->opacity, CREAL(0.05));
- if (ad->opacity < CREAL(0.0))
- ad->opacity = CREAL(0.0);
- RwForAllClumpsInHierarchyReal(clump, SetClumpOpacity, ad->opacity);
- if (ad->opacity > CREAL(0.0))
- return(FALSE);
- }
- return (TRUE);
- }
-
- RwClump *AnimateClump(RwClump *clump)
- {
- TyAnimationData *ad;
-
- if (RwGetClumpParent(clump)) /* only animate root clumps */
- return(clump);
-
- ad = RwGetClumpData(clump);
-
- if (ad)
- {
- switch (ad->state)
- {
- case A_DISSOLVE:
- if (DissolveClump(clump))
- {
- StartAnimation(clump, RandomKnight(clump));
- RwForAllClumpsInHierarchyInt(clump, SetClumpFrame, (RwInt32)ad->current_frame);
- SetAnimationState(clump, A_RESOLVE);
- }
- break;
- case A_RESOLVE:
- if (ResolveClump(clump))
- {
- SetAnimationState(clump, A_ON);
- }
- break;
- case A_ON:
- if (ad->current_animation)
- {
- if (ad->current_animation->start < ad->current_animation->end)
- ad->current_frame++;
- else
- ad->current_frame--;
-
- if (ad->current_frame == ad->current_animation->react)
- ReactKnight(clump, ad->current_animation);
-
- if (ad->current_frame >= ad->current_animation->end)
- {
- if (ad->next_animation)
- {
- ad->current_animation = ad->next_animation;
- ad->current_frame = ad->current_animation->start;
- ad->next_animation = NULL;
- }
- else
- {
- ad->current_animation = NULL;
- StartAnimation(clump, RandomKnight(clump));
- return(clump);
- }
- }
- RwForAllClumpsInHierarchyInt(clump, SetClumpFrame, (RwInt32)ad->current_frame);
- }
- break;
- }
- }
- return(clump);
- }
-
- void AnimateScene(void)
- {
- AnimateClump(Knight1);
- AnimateClump(Knight2);
- }
-