/*************************************************************************
 *
 * anim.h
 *
 *************************************************************************
 *
 * animation structures
 *
 *************************************************************************/

#ifndef ANIM_H_INCLUDED
#define ANIM_H_INCLUDED

/*
 * includes
 */

#include "ult_64.h"
#include "3dtypes.h"

/*
 * defines
 */

#define FASTCOS(x) (sin_tbl[(((x>>4)+0x200)&0x7FF)])
#define FASTSIN(x) (sin_tbl[(x>>4)&0x7FF])

#define ANIM_FLAG_COMPRESSED		1
#define ANIM_FLAG_NOTAGS		2
#define ANIM_FLAG_BLOCK_SHIFT	4


/*
 * typedefs
 */

/*
 * structures
 */

typedef struct _animFrame
{
	long x,y,z;
	Quat q[17];
} animFrame;

typedef struct _anim
{
	long numNodes;
	long numFrames;
	unsigned long flags;
	long fps;
	unsigned char *data;
//	unsigned long tags[1];
	u8 tags[20];
} anim;

typedef struct _animCacheEntry
{
	anim		*header;
	int		timeStamp;
	int		startBlock;
	s32	pad;
	char		data[4];
} animCacheEntry;

typedef struct _animCache
{
	int		numNodes;
	int		numEntries;
	int		bytesPerFrame;
	int		bytesPerEntry;
	char		entries[4];
} animCache;

/*
 * globals
 */

extern SW sin_tbl[];

/*
 * function prototypes
 */

// cache management
extern void   AnimCacheOpen(void);
extern void   AnimCacheClose(void);
extern short *AnimCache(anim *a,int frame);

// the actual anim evaluation functions
extern void AnimEvaluate(anim *a,long int root,long int frame,animFrame *f);
extern void AnimEvaluateBlend(anim *a,long int root,long int frame,animFrame *f,long int weighting);
extern void AnimEvaluateMirror(anim *a,long int root,long int frame,animFrame *f);
extern void AnimEvaluateBlendMirror(anim *a,long int root,long int frame,animFrame *f,long int weighting);

// handy matrix functions
extern void MakeMat64PRH(long *ll,int p,int r,int h,int x,int y,int z,int scale);
extern void Mat64Invert(short *s);
extern void MakeMatPRH(matrix *m,int p,int r,int h);
extern void MatInvert(matrix *m);
extern void VecMulMat(vector *v,matrix *m,vector *v2);
extern void MatMulMat(matrix *m1,matrix *m2,matrix *m3);

#endif
