/*********************************************************************************************/
/*                                                                                           */
/* General Game Type Definitions                                                             */
/*                                                                                           */
/*********************************************************************************************/

#ifndef TYPES_H
#define TYPES_H

#ifdef __cplusplus
extern "C" {
#endif

#include "objects.h"
/********************************* TYPE DEFINITIONS ******************************************/

#define GAME_FOV	80			   // Field of View for Game

/* Useful macros */
#define SQUARE(A) ((A)*(A))

/* Standard bits set in input longword */
#define IN_FORWARD  1
#define IN_BACK     (1<<1)
#define IN_LEFT     (1<<2)
#define IN_RIGHT    (1<<3)
#define IN_JUMP     (1<<4)
#define IN_DRAW     (1<<5)
#define IN_ACTION   (1<<6)
#define IN_SLOW     (1<<7)
#define IN_OPTION	(1<<8)
#define IN_LOOK	    (1<<9)
#define IN_STEPL    (1<<10)
#define IN_STEPR    (1<<11)
#define IN_ROLL		(1<<12)
#define IN_PAUSE	(1<<13)
#define IN_A        (1<<14)        // A to F are Debug thingys..
#define IN_B		(1<<15)
#define IN_C		(1<<16)
#define IN_D		(1<<17)
#define IN_E		(1<<18)
#define IN_F		(1<<19)
#define IN_SELECT	(1<<20)
#define IN_DESELECT	(1<<21)
#define IN_SAVE		(1<<22)
#define IN_LOAD		(1<<23)
#define IN_STEPSHIFT (1<<24)



enum sfx_types {
		SFX_LANDANDWATER = 0<<14,
		SFX_LANDONLY     = 1<<14,
		SFX_WATERONLY    = 2<<14
};

enum init_level_types {
		IL_TITLE,
		IL_NORMAL,
		IL_SAVED,
		IL_DEMO,
		IL_CUTSCENE,
		IL_STORY_SO_FAR,
		IL_QUIET,
		IL_STORY_SO_FAR_MIDLEVEL
};

/* Game options - bits determine what options appear on wheel */
#define NO_ACTION    0
#define GAME_ACTION  1
#define END_ACTION	 2
#define LOAD_ACTION  4
#define SAVE_ACTION  8
#define SOUND_ACTION 16
#define VIDEO_ACTION 32

#define GRAVITY           6
#define FASTFALL_SPEED  128

#define DONT_TARGET	(-16384)

#define DEMOCOUNT_MAX	(30*60*5)			// 5 Minutes Max of Demo..

#define UNIT_SHADOW		256
#define UNIT_SHADOW_SHIFT 8

/* For triggers */
#define ONESHOT     0x0100
#define CODE_BITS   0x3e00
#define REVERSE	  0x4000
#define NOT_VISIBLE ONESHOT
#define KILLED_ITEM (-0x8000)
#define CLEAR_BODY  KILLED_ITEM

#define MAX_CD_TRACKS 64
#define MAX_SECRETS 16

#define MAX_DYNAMICS 10

/******************* Animation Structure Prototypes ************************/

typedef struct game_vector {
	sint32 x, y, z;
	sint16 room_number, box_number;
} GAME_VECTOR;

/* Carbon copy of GAME_VECTOR but better names for CAMERAS, SINKS etc */
typedef struct object_vector {
	sint32 x, y, z;
	sint16 data, flags;
} OBJECT_VECTOR;

typedef struct	anim_struct {
			sint16			*frame_ptr;            // pointer to animation frame data
			sint16			interpolation;		   // amount of interpolation
			sint16			current_anim_state;
			sint32			velocity;
			sint32			acceleration;
			sint16			frame_base;
			sint16			frame_end;
			sint16			jump_anim_num;
			sint16			jump_frame_num;
			sint16			number_changes;
			sint16			change_index;
			sint16			number_commands;
			sint16			command_index;
}ANIM_STRUCT;

typedef struct	change_struct {
			sint16			goal_anim_state;
			sint16			number_ranges;
			sint16			range_index;
}CHANGE_STRUCT;

typedef struct	range_struct {
			sint16			start_frame;
			sint16			end_frame;
			sint16			link_anim_num;
			sint16			link_frame_num;
}RANGE_STRUCT;

enum command_types {
			COMMAND_NULL=0,
			COMMAND_MOVE_ORIGIN,
			COMMAND_JUMP_VELOCITY,
			COMMAND_ATTACK_READY,
			COMMAND_DEACTIVATE,
			COMMAND_SOUND_FX,
			COMMAND_EFFECT
};

/********************* Room structures **********************************/

#define END_BIT     0x8000
#define DATA_TYPE	  0x00ff
#define VALUE_BITS  0x03ff

#define MAX_ROOMS			1024
#define MAX_FLIPMAPS 		10

#define WALL_L  	 1024
#define WALL_SHIFT 10
#define STEP_L     (WALL_L/4)
#define NO_ROOM 	 0xff

#define NO_HEIGHT (-0x7f00)



enum height_types { WALL,SMALL_SLOPE,BIG_SLOPE };
extern int height_type;
extern int record_demo;

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

typedef struct floor_info {
	uint16 		index;
	sint16		box;
	unsigned char pit_room;
	signed char floor;
	unsigned char sky_room;
	signed char	ceiling;
} FLOOR_INFO;

typedef struct light_info {
	sint32		x;
	sint32		y;
	sint32		z;
	sint16		intensity, intensityB;
	sint32		falloff, falloffB;
} LIGHT_INFO;

typedef struct	mesh_info {
	sint32		x;
	sint32		y;
	sint32		z;
	PHD_ANGLE	y_rot;
	sint16		shade, shadeB;
	sint16      static_number; // STATIC_INFO structure that contains bounding info
} MESH_INFO;

/* ROOM_INFO flags */
#define UNDERWATER 1
#define SFX_ALWAYS 2 // NOTE: this is used by ambient SFX not room->flags
#define PITCH_SHIFT 4
#define OUTSIDE    8
#define DYNAMIC_LIT 16
#define NOT_INSIDE 32 // OUTSIDE means sky room, NOT_INSIDE just means in the wind/mist etc
#define INSIDE		64 // INSIDE means room *not adjacent* to an OUTSIDE room!!

typedef struct room_info {
	sint16 		*data;
	sint16 		*door;
	FLOOR_INFO 	*floor;	// 20
	LIGHT_INFO	*light;
	MESH_INFO	*mesh;
	sint32		x, y, z;  	// 12
	sint32		minfloor, maxceiling;	// 8
	sint16 		x_size, y_size;
	sint16		ambient, ambientB, lighting;
	sint16		num_lights;
	sint16		num_meshes;
	sint16		bound_active;
	sint16		left;
	sint16		right;
	sint16		top;
	sint16		bottom;
	sint16		test_left, test_right, test_top, test_bottom; // 14/8/97: better bounds testing?
	sint16		item_number;
	sint16		fx_number;
	sint16		flipped_room;			 // -1 normally, unless alternative room available
	uint16		flags;
} ROOM_INFO;

typedef struct bite_info {				// Offset into given Mesh
	sint32			x;					// where Baddie kicks off Bite Effect
	sint32			y;
	sint32			z;
	sint32			mesh_num;
} BITE_INFO;

enum coll_types {
			COLL_NONE  = 0,
			COLL_FRONT = 1,             // Solid Wall in Front
			COLL_LEFT  = 2,             // Solid Wall to LHS
			COLL_RIGHT = 4,             // Solid Wall to RHS
			COLL_TOP   = 8,             // MidPoint Ceiling
			COLL_TOPFRONT  = 16,        // MidPoint at Front
			COLL_CLAMP = 32,            // MidPoint Ceiling and Floor BAD!!!
};

typedef struct coll_info {
	sint32		mid_floor,mid_ceiling,mid_type;      	// relative floor and ceiling heights at midpoint
	sint32		front_floor,front_ceiling,front_type;  	// relative floor and ceiling heights at front
	sint32		left_floor,left_ceiling,left_type;    	// relative floor and ceiling heights at front/left side
	sint32		right_floor,right_ceiling,right_type;  	// relative floor and ceiling heights at front/right side
	sint32		radius;                     			// INPUT Collision Radius...
	sint32		bad_pos,bad_neg;            			// INPUT Relative Heights We want to Collide against...
	sint32		bad_ceiling;                			// INPUT Relative Bad Ceiling Height...
	PHD_VECTOR	shift;                      			// Shift/Push Values..
	PHD_VECTOR	old;                        			// INPUT Old Positions
	sint16		old_anim_state, old_anim_number, old_frame_number; // INPUT Old animation
	sint16		facing;                     			// INPUT Angle we are Moving...
	sint16		quadrant;                   			// Quadrant we are moving ( Not necessarily facing! )
	sint16		coll_type;                  			// Type of Collision
	sint16	  	*trigger;                   			// Trigger info index
   signed char tilt_x, tilt_z;             			// Type of Tilt of Floor
	char		hit_by_baddie;              			// Flag to indicate Lara has been hit by a Baddie
	char		hit_static;								// Flag to indicate Lara has collided with a Static object
	uint16		slopes_are_walls:1;                     // Treat big slopesUp as walls
	uint16		slopes_are_pits:1;						// Treat big slopesDown as pits
	uint16		lava_is_pit:1;                          // Treat Lava as Bad place to go onto
	uint16		enable_baddie_push:1;       			// Baddies Can push Lara
	uint16		enable_spaz:1;							// Spaz animations are enabled
} COLL_INFO;

/**************************** Object/Item Type Definitions *******************************/

#define NO_ITEM -1

/* DrawItem() allows 'extra_rotation' specified by setting object bone structure poppush bits.
	The actual rotation amount is read from item->data, which points to object specific struct
	such as WOLF_INFO - therefore WOLF_INFO must have 'sint16 extra_rotation[N]' as first part
	of its structure */
#define ROT_X 4
#define ROT_Y 8
#define ROT_Z 16

/* Possible active states */
#define NOT_ACTIVE  0
#define ACTIVE      1
#define DEACTIVATED 2
#define INVISIBLE	3

/* Individual item information e.g. wolf1 and wolf2 */
typedef struct item_info {
	sint32 		floor;
	uint32 		touch_bits;
	uint32 		mesh_bits;
	sint16 		object_number;
	sint16 		current_anim_state;
	sint16 		goal_anim_state;
	sint16 		required_anim_state; 		// May need to pass through several goals
	sint16 		anim_number;
	sint16 		frame_number;
	sint16 		room_number;
	sint16 		next_item;       			// For linked list within rooms
	sint16 		next_active;
	sint16 		speed;
	sint16 		fallspeed;
	sint16 		hit_points;
	sint16 		box_number;
	sint16 		timer;						// For timer switches
	sint16 		flags;						// For oneshot and code switches
	sint16 		shade, shadeB;				// -1 for dynamic lighting
	sint16		carried_item;				// 6/8/97: bad guys hold whatever pickup
	void  		*data;
	PHD_3DPOS 	pos;
	uint16		active:1;                   // Is Item Active or Not??
	uint16 		status:2;					// Bit packing fun
	uint16 		gravity_status:1;
	uint16 		hit_status:1;               // Has item been hit by a bullet
	uint16 		collidable:1;				// Can Lara Collide with It??
	uint16		looked_at:1;				// has item ever been a camera target
	uint16		dynamic_light:1;			// Used in cutscenes to attach light to first pivot point
	uint16		clear_body:1;				// do we want corpse to be cleared away?
} ITEM_INFO;

/* Individual Sprite Effects */
typedef struct fx_info {
	PHD_3DPOS	pos;
	sint16		room_number;
	sint16		object_number;
	sint16		next_fx;
	sint16		next_active;
	sint16		speed;
	sint16		fallspeed;
	sint16		frame_number;
	sint16		counter;
	sint16		shade;
} FX_INFO;


/* Definitions of object types e.g. WOLF */
typedef struct object_info {
	sint16 		nmeshes;						// -ve nmeshes => sprite
	sint16 		mesh_index;
	sint32 		bone_index;
	sint16 		*frame_base;
	void 		(*initialise)(sint16 item_number);
	void 		(*control)(sint16 item_number);
	void 		(*floor)(ITEM_INFO *item, sint32 x, sint32 y, sint32 z, sint32 *height);
	void 		(*ceiling)(ITEM_INFO *item, sint32 x, sint32 y, sint32 z, sint32 *height);
   	void 		(*draw_routine)( ITEM_INFO *item );
	void  		(*collision)( sint16 item_num, ITEM_INFO *laraitem, COLL_INFO *coll );
	sint16 		anim_index;
	sint16 		hit_points;
	sint16		pivot_length;           // replacement for 'head_size': distance from centre to neck rotation
	sint16 		radius;
	sint16 		shadow_size;                // Size of Shadow ( -1 if none )
	uint16 		loaded:1;                   // Is this Object Loaded on this Level
	uint16		intelligent:1;				// Does this Objecy need AI info??
	uint16		save_position:1;
	uint16		save_hitpoints:1;
	uint16		save_flags:1;
	uint16		save_anim:1;
	uint16		semi_transparent:1;			// is Sprite object semi transparent
	uint16		water_creature:1;			// is this is water based baddie? needed for SFX in shallow water
} OBJECT_INFO;

typedef struct static_info {
	sint16 	mesh_number;
	sint16	flags;										// Flags for collision and stuff.
	sint16 	x_minp,x_maxp,y_minp,y_maxp,z_minp,z_maxp;	// Draw bounds
	sint16  x_minc,x_maxc,y_minc,y_maxc,z_minc,z_maxc;  // Collision Bounds
} STATIC_INFO;

typedef struct sphere {
	sint32	x,y,z,r;
} SPHERE;


/************************************ Camera structure ***********************************/

#define NO_CAMERA -1

typedef enum camera_type {CHASE_CAMERA, FIXED_CAMERA, LOOK_CAMERA, COMBAT_CAMERA, CINEMATIC_CAMERA, HEAVY_CAMERA} CAMERA_TYPE;

/* Camera flags to modify basic behaviour */
#define FOLLOW_CENTRE 1
#define NO_CHUNKY     2
#define CHASE_OBJECT  3

typedef struct camera_info {
	GAME_VECTOR pos;
	GAME_VECTOR target;
	CAMERA_TYPE type;
	sint32 shift, flags, fixed_camera;
	sint32 number_frames, bounce, underwater;
	sint32 target_distance, target_square;
	sint16 target_angle, actual_angle;
	sint16 target_elevation;
	sint16 box;
	sint16 number, last, timer, speed;
	ITEM_INFO *item, *last_item;			// item to use as target (usually Lara)
	OBJECT_VECTOR *fixed;     // array of fixed camera positions
	int mike_at_lara;
	PHD_VECTOR mike_pos;	// world coordinate origin of projection plane (0,0,phd_persp in screen coordinates) (for sound)
} CAMERA_INFO;

typedef struct sample_info {
	sint16 number;			 // base sound effect number
	sint16 volume;			 // default volume of sound
	sint16 randomness;	     // Chance of playing sample 0-32767  0=Always
	sint16 flags;	         // Flags for all sorts of stuff
}SAMPLE_INFO;

#ifdef PSX_VERSION					// Jasons Gouraud definition...
typedef uint32 SG_COL;
#else
typedef uint16 SG_COL;
#endif


/* Include data types for particular object types + item specific prototypes */
#include "box.h"
#include "lara.h"
#include "traps.h"
#include "inventry.h"
#include "text.h"
#include "gameflow.h"
#include "title.h"
#include "gametext.h"
#include "savegame.h"

#ifdef __cplusplus
}
#endif

#endif
