/************************************************************************************
	GLOVER PSX	(c) 1998-9 ISL

	object.h:		General object draw routines

************************************************************************************/

#ifndef _OBJECT_H_
#define _OBJECT_H_

extern int object_atlantis_waterflag;   //this should be removed!!!!

#define MAXMATRIXSTACK 11
extern MATRIX matrixstack[MAXMATRIXSTACK];
extern	ULONG matrixstackcount;

typedef struct _objectSegDataType {
   	SHORT	segStart;
   	SHORT	segEnd;
	SHORT 	numSegs;
   	UBYTE	segFlags;
   	UBYTE	segFPS;
}objectSegDataType;

typedef struct _AnimType {
	int					num;
	int					frame;
	int					frameFixed;
	int					length;
	int					inc;
	int					speed;
	objectSegDataType	*segInfo;
}AnimType;

enum {
	FIGHT_NONE,				//doing nothing - walking
	FIGHT_ATTACK,			//in process of attacking
	FIGHT_ATTACKHIT,		//attack hits
	FIGHT_BLOCK,			//blocking
	FIGHT_RECOIL,			//recoiling
	FIGHT_OUT,				//knocked out
	FIGHT_GETTING_UP,		//get up from floor
	FIGHT_ON_THE_FLOOR,		//laying on the floor
};

#if PALMODE==1
	#define GLOBALSPEED	7372
#else
	#define GLOBALSPEED	6144
#endif

typedef struct {
	short   nx, ny, nz;
	u_char  tu, tv;
}NORM;



typedef struct{
	VERT *vertop;         /* vertex top address of TMD format */
	u_long  vern;           /* the number of vertex of TMD format */	//this could be a ushort, but doesnt work!?
	NORM *nortop;         /* normal top address of TMD format */
	u_long  norn;           /* the number of normal of TMD format */   //this could be a ushort, but doesnt work!?
	u_long *primtop;        /* primitive top address of TMD format */
	u_long  primn;          /* the number of primitives of TMD format */  //this could be a ushort, but doesnt work!?
	USHORT	frames;			/*num of frames in animation*/
	USHORT  scale;          /* the scale factor of TMD format SQRT of width*height*length (from boundbox)*/
	UBYTE 	name[10];
	SHORT	boundminx,boundmaxx;			// X bounds
	SHORT	boundminy,boundmaxy;			// Y bounds
	SHORT	boundminz,boundmaxz;			// Z bounds
	SHORT	pad;	
	VERT	center;							//	center point of segment
	SHORT	sorttablesize[4];
  	int		*sorttable[4];
	ULONG   packetbuildsize;
}NEWTMD;

typedef struct{
	LONG x,y,z,w;
}QVECTOR;


#define SMALL_KEYFRAMES


#ifdef SMALL_KEYFRAMES
typedef struct{
	SHORT x,y,z;
}SHORTVECTOR;

typedef struct{
	SHORTQUAT vect;
	SHORT time;
}SQKEYFRAME;
typedef struct{
	SHORTVECTOR vect;
	SHORT time;
}SVKEYFRAME;

#endif




typedef struct _NEWOBJECT{
	unsigned long flags;	
	MATRIX  	matrixscale;		
	MATRIX  	matrix;
	USHORT		Animstart;
	USHORT		Animend;
	USHORT		numScaleKeys;
	USHORT		numMoveKeys;
	USHORT		numRotateKeys;
	USHORT		pad;

#ifdef SMALL_KEYFRAMES
	SVKEYFRAME	*scalekeys;
	SVKEYFRAME	*movekeys;
	SQKEYFRAME	*rotatekeys;
#else
	KEYFRAME	*scalekeys;
	KEYFRAME	*movekeys;
	KEYFRAME	*rotatekeys;
#endif
	struct		_NEWOBJECT *parent;
	struct		_NEWOBJECT *child; 
	struct		_NEWOBJECT *next; 
	IQUATERNION	qRot;
	IQUATERNION	qRotVel;
	IQUATERNION	qRotLight;
	IQUATERNION	qRotLightVel;
 	SVECTOR		rotate;			//angle of object vx,vy,vz
   	VECTOR		scale;
	NEWTMD		*meshdata;		//sort list size and pointers included in TMD
} NEWOBJECT;


typedef struct	_NEWMODEL{
				NEWOBJECT	world;
				UBYTE		framenum;
				SHORT		depthoffset;
   				VECTOR		globalscale;
				VECTOR		inverseglobalscale;
				VECTOR		position;
				struct _NEWOBJECT	**segmenttable;
				ULONG		numberofsegments;
			}NEWMODEL;	 

#define OFFSCREEN_DEPTH 0

typedef struct _MODELCTRL
{
	USHORT 	depthoveride;	//0=sort normally, otherwise model will be at this depth;
	USHORT  PrimLeft;

	int*	SortPtr;
	ULONG*	PrimTop;
	VERT*	VertTop;
	VERT*	NormTop;

	LONG polysdrawn;
	LONG preclipped;
	LONG sorttable;

	ULONG	indDepth;		
	NEWMODEL *currentmodel;	// Fred, 5 mar 99, for sprite scales
	USHORT lastdepth;		// "offscreen_depth" if off

	UBYTE	specialFX;		
	UBYTE	subdivide;
	UBYTE	semitrans;		//0 or 2 for ON!
	UBYTE	lighting;		//OFF ON

	UBYTE halfgouraud;		
	UBYTE subdivflag;
	UBYTE brown;
}MODELCTRL;



extern MODELCTRL modelctrl;


/**************************************************************************
	FUNCTION:	objectDraw()
	PURPOSE:	Draw a generic hierarchical object
	PARAMETERS:	Model structure
	RETURNS:	
**************************************************************************/

void objectDraw(NEWMODEL *actor);

// Position is taken from the NEWMODEL structure. Radii are "small" (not *4096)
// This rou calls "getheightat". If the height of the shadow is known & fixed, call the shadow rou directly
// If the object is within "objradius" of the floor, the shadow will be inserted at the same OT position
// as the object, otherwise it will be independantly sorted
// (flags (will be) for things like height-dependant shadow radii)
void objectDrawWithShadow(NEWMODEL *actor,LONG objradius,LONG shadradius,int flags);



/**************************************************************************
	FUNCTION:	objectSetupSegmentSort()
	PURPOSE:	Set up object inter-segment sorting
	PARAMETERS:	Model structure
	RETURNS:	
**************************************************************************/

void objectSetupSegmentSort(NEWMODEL *model);


/**************************************************************************
	FUNCTION:	objectSetAnimation()
	PURPOSE:	Set keyframe information for current object frame
	PARAMETERS:	Model structure, frame number
	RETURNS:	
**************************************************************************/

void objectSetAnimation(NEWMODEL *actor, ULONG frame);


/**************************************************************************
	FUNCTION:	objectLoadSeg()
	PURPOSE:	Load animation segments for object
	PARAMETERS:	Seg info
	RETURNS:	
**************************************************************************/

objectSegDataType *objectLoadSeg(char *name);


/**************************************************************************
	FUNCTION:	objectFree()
	PURPOSE:	for freeing an actor
	PARAMETERS:	model pointer and object pointer
	RETURNS:	
**************************************************************************/

//void objectFree(NEWMODEL *mPtr, NEWOBJECT *oPtr);
// No longer needed, since models are now part of a BFF file
#define objectFree(a,b) {};


//void Set_Model_CoordsNew(NEWMODEL *model,LONG x,LONG y,LONG z,LONG vx,LONG vy,LONG vz);

/**************************************************************************
	FUNCTION:	polyDrawLineClipped()
	PURPOSE:	Clip line + add line to packet draw list
	PARAMETERS:	x0,y0,x1,y1, r,g,b, Depth value
	RETURNS:	
**************************************************************************/

void polyDrawLineClipped(int x0, int y0, int x1, int y1, char r, char g, char b, int depth);


void objectSetSegments(NEWMODEL *model,NEWOBJECT *object);
void objectCalcWorldMatrix(NEWMODEL *actor, NEWOBJECT *world);


void Reset_Modelctrl();




/*********************WAS MODEL .H *****************/
 



#endif

