/*
* Starfield Application
*
* University of Abertay Dundee
* May be used for educational purposed only
*
* Author - Dr Henry S Fortuna
*
* $Revision: 1.8 $
* $Date: 2008/01/12 10:32:26 $
*
*/

#include <sps2lib.h>
#include <sps2tags.h>
#include <sps2util.h>
#include <sps2regstructs.h>
#include "PS2Defines.h"
#include "ps2matrix4x4.h"
#include "sps2wrap.h"
#include "dma.h"
#include "primitives.h"

PS2Sprite::PS2Sprite()
{

	m_x = m_y = 0.0f; //init values
	Initialise();
}

PS2Sprite::PS2Sprite(float x, float y)
{
	m_x = x; m_y = y;
	Initialise();
	
}

PS2Sprite::~PS2Sprite()
{
	// Nothing to clean-up
}

void PS2Sprite::Initialise(void)
{
	m_z = 128.0f;						//set to 128 as z=0 will render nothing.
	m_w = m_h = 32.0f;
	m_r = m_g = m_b = m_a = 0x80;
	m_Vx = m_Vy = 0.0f;
	m_Vz = (float)(4 + rand()%10);
	
	m_TopLeft.x 		= -m_w/2.0f;
	m_TopLeft.y 		= -m_h/2.0f;
	m_BottomLeft.x 		= -m_w/2.0f;
	m_BottomLeft.y 		=  m_h/2.0f;
	m_TopRight.x 		=  m_w/2.0f;
	m_TopRight.y 		= -m_h/2.0f;
	m_BottomRight.x 	=  m_w/2.0f;
	m_BottomRight.y 	=  m_h/2.0f;
}

void PS2Sprite::MoveTo(float x, float y, float z)
{	
	m_x = x;
 	m_y = y;
	m_z = z;
}
void PS2Sprite::SetSize(float h, float w)
{
	m_h = h;
	m_w = w;
	m_TopLeft.x 		= -m_w/2.0f;
	m_TopLeft.y 		= -m_h/2.0f;
	m_BottomLeft.x 		= -m_w/2.0f;
	m_BottomLeft.y 		=  m_h/2.0f;
	m_TopRight.x 		=  m_w/2.0f;
	m_TopRight.y 		= -m_h/2.0f;
	m_BottomRight.x 	=  m_w/2.0f;
	m_BottomRight.y 	=  m_h/2.0f;
}
		
void PS2Sprite::MoveDeltaX(float x)
{
	m_x += x;
}

void PS2Sprite::MoveDeltaY(float y)
{
	m_y += y;
}

void PS2Sprite::MoveDeltaZ(float z)
{
	m_z += z;
}

void PS2Sprite::MoveDeltaZ(void)
{
	m_z += m_Vz;
}
void PS2Sprite::MoveDeltaZBack(float z)
{
	m_z -= z;
}
void PS2Sprite::MoveDeltaZBack(void)
{
	m_z -= m_Vz;
}
float PS2Sprite::GetX(void)
{
	return m_x;
}

float PS2Sprite::GetY(void)
{
	return m_y;
}

float PS2Sprite::GetZ(void)
{
	return m_z;
}
float PS2Sprite::GetHeight(void)
{
	return m_h;
}
float PS2Sprite::GetWidth(void)
{
	return m_w;
}
float PS2Sprite::Scale(void)
{
	m_h -= m_h;
	m_w -= m_w;
}

// ********* Don't Change anything in this method
void PS2Sprite::Render(void) const
{
	VIFDynamicDMA.StartDirect();
	
	// Add the GIFTag
	VIFDynamicDMA.Add128(GS_GIFTAG_BATCH(	4,							// NLOOP
											1,							// EOP
											1,							// PRE
											GS_PRIM(PRIM_TRI_STRIP, 	// PRIM
												PRIM_IIP_FLAT, 
												PRIM_TME_OFF,
												PRIM_FGE_OFF, 
												PRIM_ABE_OFF, 
												PRIM_AA1_OFF, 
												PRIM_FST_UV, 
												PRIM_CTXT_CONTEXT1, 
												PRIM_FIX_NOFIXDDA),
											GIF_FLG_PACKED,					//FLG
											GS_BATCH_2(	GIF_REG_RGBAQ, 
														GIF_REG_XYZ2)));	//BATCH	
		
	// Add the colour (Top Left)
	VIFDynamicDMA.Add128(PACKED_RGBA(m_r ,m_g, m_b, m_a));
		    	
	// Add the position (Top Left)  	   	
	VIFDynamicDMA.Add128(PACKED_XYZ2((int)((2048.0f + m_x + m_TopLeft.x)*16.0f), 
									 (int)((2048.0f + m_y + m_TopLeft.y)*16.0f),  
									 (int)m_z, 
									  0));
	
	// Add the colour (Bottom Left)
	VIFDynamicDMA.Add128(PACKED_RGBA(m_r ,m_g, m_b, m_a));
		    	
	// Add the position (Bottom Left)  	
	VIFDynamicDMA.Add128(PACKED_XYZ2((int)((2048.0f + m_x + m_BottomLeft.x)*16.0f), 
									 (int)((2048.0f + m_y + m_BottomLeft.y)*16.0f),  
									 (int)m_z, 
									  0));
									  
	
	// Add the colour (Top Right)
	VIFDynamicDMA.Add128(PACKED_RGBA(m_r ,m_g, m_b, m_a));
		    	
	// Add the position (Top Right)  	
	VIFDynamicDMA.Add128(PACKED_XYZ2((int)((2048.0f + m_x + m_TopRight.x)*16.0f), 
									 (int)((2048.0f + m_y + m_TopRight.y)*16.0f),  
									 (int)m_z, 
									  0));

	// Add the colour (Bottom Right)
	VIFDynamicDMA.Add128(PACKED_RGBA(m_r ,m_g, m_b, m_a));
		    	
	// Add the position  (Bottom Right)  	
	VIFDynamicDMA.Add128(PACKED_XYZ2((int)((2048.0f + m_x + m_BottomRight.x)*16.0f), 
									 (int)((2048.0f + m_y + m_BottomRight.y)*16.0f),  
									 (int)m_z, 
									  0));
	
	
	VIFDynamicDMA.EndDirect();
}

void PS2Sprite::RenderPerspective(void) const
{
	float NormalizedZ = m_z * 0.001f;
	
	VIFDynamicDMA.StartDirect();
	
	// Add the GIFTag
	VIFDynamicDMA.Add128(GS_GIFTAG_BATCH(	4,							// NLOOP
											1,							// EOP
											1,							// PRE
											GS_PRIM(PRIM_TRI_STRIP, 	// PRIM
												PRIM_IIP_FLAT, 
												PRIM_TME_OFF,
												PRIM_FGE_OFF, 
												PRIM_ABE_OFF, 
												PRIM_AA1_OFF, 
												PRIM_FST_UV, 
												PRIM_CTXT_CONTEXT1, 
												PRIM_FIX_NOFIXDDA),
											GIF_FLG_PACKED,					//FLG
											GS_BATCH_2(	GIF_REG_RGBAQ, 
														GIF_REG_XYZ2)));	//BATCH	
		
	// Add the colour (Top Left)
	VIFDynamicDMA.Add128(PACKED_RGBA(m_r ,m_g, m_b, m_a));
		    	
	// Add the position (Top Left)  	   	
	VIFDynamicDMA.Add128(PACKED_XYZ2((int)((2048.0f + NormalizedZ*m_x + NormalizedZ*m_TopLeft.x)*16.0f), 
									 (int)((2048.0f + NormalizedZ*m_y + NormalizedZ*m_TopLeft.y)*16.0f),  
									 (int)m_z, 
									  0));
	
	// Add the colour (Bottom Left)
	VIFDynamicDMA.Add128(PACKED_RGBA(m_r ,m_g, m_b, m_a));
		    	
	// Add the position (Bottom Left)  	
	VIFDynamicDMA.Add128(PACKED_XYZ2((int)((2048.0f + NormalizedZ*m_x + NormalizedZ*m_BottomLeft.x)*16.0f), 
									 (int)((2048.0f + NormalizedZ*m_y + NormalizedZ*m_BottomLeft.y)*16.0f),  
									 (int)m_z, 
									  0));
									  
	
	// Add the colour (Top Right)
	VIFDynamicDMA.Add128(PACKED_RGBA(m_r ,m_g, m_b, m_a));
		    	
	// Add the position (Top Right)  	
	VIFDynamicDMA.Add128(PACKED_XYZ2((int)((2048.0f + NormalizedZ*m_x + NormalizedZ*m_TopRight.x)*16.0f), 
									 (int)((2048.0f + NormalizedZ*m_y + NormalizedZ*m_TopRight.y)*16.0f),  
									 (int)m_z, 
									  0));

	// Add the colour (Bottom Right)
	VIFDynamicDMA.Add128(PACKED_RGBA(m_r ,m_g, m_b, m_a));
		    	
	// Add the position  (Bottom Right)  	
	VIFDynamicDMA.Add128(PACKED_XYZ2((int)((2048.0f + NormalizedZ*m_x + NormalizedZ*m_BottomRight.x)*16.0f), 
									 (int)((2048.0f + NormalizedZ*m_y + NormalizedZ*m_BottomRight.y)*16.0f),  
									 (int)m_z, 
									  0));
	
	
	VIFDynamicDMA.EndDirect();
}

/*PS2SpriteT::PS2SpriteT()
{
	m_tu = 0;
	m_tv = 0;
	m_tw = 256;
	m_th = 256;
	
}
	
PS2SpriteT::PS2SpriteT(const float x, const float y):
PS2Sprite(x, y)
{
	m_tu = 0;
	m_tv = 0;
	m_tw = 64;
	m_th = 64;
}

PS2SpriteT::~PS2SpriteT()
{
	// Nothing to destruct
}*/

PS2SpriteT::PS2SpriteT()
{
	m_tu = 0;
	m_tv = 0;
	m_tw = 64;
	m_th = 64;

	animate = false;		//initialise animate flag
}
	

PS2SpriteT::~PS2SpriteT()
{
	
	// Nothing to destruct
}
void PS2SpriteT::ChangeSize(int x, int y)
{
	m_tw = x;
	m_th = y;
}
void PS2SpriteT::ChangePic(int x, int y)
{
	m_tu = x;
	m_tv = y;
}
float PS2SpriteT::GetPic(void)
{
	return m_tv;
}
void PS2SpriteT::SetAnimCount(int speed, int num_frames)
{
	m_AnimCountMax		=  speed;
	m_NumFrames = num_frames;
}
void PS2SpriteT::Animate(void)
{
	if((m_AnimCounter++)%m_AnimCountMax == 0)
		{
			m_tu += m_tw;
			if(m_tu > (m_NumFrames - 1) * m_tw)
			{
				m_tu = 0;
			}
		}
}
void PS2SpriteT::AnimateOnce(void)
{
	if((m_AnimCounter++)%m_AnimCountMax == 0)
		{
			m_tu += m_tw;
			if(m_tu > (m_NumFrames - 1) * m_tw)
			{
				m_tu = 0;
				animate = false;
			}
		}
}
// ********* Don't Change anything in this method
void PS2SpriteT::Render(void) const
{
	VIFDynamicDMA.StartDirect();
	
	// Add the GIFTag
	VIFDynamicDMA.Add128(GS_GIFTAG_BATCH(	4,							// NLOOP
											1,							// EOP
											1,							// PRE
											GS_PRIM(PRIM_TRI_STRIP, 	// PRIM
												PRIM_IIP_FLAT, 
												PRIM_TME_ON,
												PRIM_FGE_OFF, 
												PRIM_ABE_ON, 
												PRIM_AA1_OFF, 
												PRIM_FST_UV, 
												PRIM_CTXT_CONTEXT1, 
												PRIM_FIX_NOFIXDDA),
											GIF_FLG_PACKED,					//FLG
											GS_BATCH_3(	GIF_REG_RGBAQ,
														GIF_REG_UV, 
														GIF_REG_XYZ2)));	//BATCH	
		
	// Add the colour (Top Left)
	VIFDynamicDMA.Add128(PACKED_RGBA(m_r ,m_g, m_b, m_a));
	
	// Add UV texture coordinates (Top Left)
    VIFDynamicDMA.Add128(PACKED_UV(	((m_tu)<<4)+8, ((m_tv)<<4)+8));
		    	
	// Add the position (Top Left)  	   	
	VIFDynamicDMA.Add128(PACKED_XYZ2((int)((2048.0f + m_x + m_TopLeft.x)*16.0f), 
									 (int)((2048.0f + m_y + m_TopLeft.y)*16.0f),  
									 (int)m_z, 
									  0));
	
	// Add the colour (Bottom Left)
	VIFDynamicDMA.Add128(PACKED_RGBA(m_r ,m_g, m_b, m_a));
	
	// Add UV texture coordinates (Bottom Left)
    VIFDynamicDMA.Add128(PACKED_UV(	((m_tu)<<4)+8, ((m_tv + m_th)<<4)+8));
	
		    	
	// Add the position (Bottom Left)  	
	VIFDynamicDMA.Add128(PACKED_XYZ2((int)((2048.0f + m_x + m_BottomLeft.x)*16.0f), 
									 (int)((2048.0f + m_y + m_BottomLeft.y)*16.0f),  
									 (int)m_z, 
									  0));
									  
	
	// Add the colour (Top Right)
	VIFDynamicDMA.Add128(PACKED_RGBA(m_r ,m_g, m_b, m_a));
	
	// Add UV texture coordinates (Top Right)
    VIFDynamicDMA.Add128(PACKED_UV(	((m_tu + m_tw)<<4)+8, ((m_tv)<<4)+8));
		    	
	// Add the position (Top Right)  	
	VIFDynamicDMA.Add128(PACKED_XYZ2((int)((2048.0f + m_x + m_TopRight.x)*16.0f), 
									 (int)((2048.0f + m_y + m_TopRight.y)*16.0f),  
									 (int)m_z, 
									  0));

	// Add the colour (Bottom Right)
	VIFDynamicDMA.Add128(PACKED_RGBA(m_r ,m_g, m_b, m_a));
	
	// Add UV texture coordinates
    VIFDynamicDMA.Add128(PACKED_UV(	((m_tu + m_tw)<<4)+8, ((m_tv + m_th)<<4)+8));
		    	
	// Add the position  (Bottom Right)  	
	VIFDynamicDMA.Add128(PACKED_XYZ2((int)((2048.0f + m_x + m_BottomRight.x)*16.0f), 
									 (int)((2048.0f + m_y + m_BottomRight.y)*16.0f),  
									 (int)m_z, 
									  0));
	
	
	VIFDynamicDMA.EndDirect();
}

void PS2SpriteT::RenderPerspective(void) const
{
	float NormalizedZ = m_z * 0.001f;
	
	
	VIFDynamicDMA.StartDirect();
	
	// Add the GIFTag
	VIFDynamicDMA.Add128(GS_GIFTAG_BATCH(	4,							// NLOOP
											1,							// EOP
											1,							// PRE
											GS_PRIM(PRIM_TRI_STRIP, 	// PRIM
												PRIM_IIP_FLAT, 
												PRIM_TME_ON,
												PRIM_FGE_OFF, 
												PRIM_ABE_ON, 
												PRIM_AA1_OFF, 
												PRIM_FST_UV, 
												PRIM_CTXT_CONTEXT1, 
												PRIM_FIX_NOFIXDDA),
											GIF_FLG_PACKED,					//FLG
											GS_BATCH_3(	GIF_REG_RGBAQ,
														GIF_REG_UV, 
														GIF_REG_XYZ2)));	//BATCH	
		
	// Add the colour (Top Left)
	VIFDynamicDMA.Add128(PACKED_RGBA(m_r ,m_g, m_b, m_a));
	
	// Add UV texture coordinates (Top Left)
    VIFDynamicDMA.Add128(PACKED_UV(	((m_tu)<<4)+8, ((m_tv)<<4)+8));
		    	
	// Add the position (Top Left)  	   	
	VIFDynamicDMA.Add128(PACKED_XYZ2((int)((2048.0f + NormalizedZ*m_x + NormalizedZ*m_TopLeft.x)*16.0f), 
									 (int)((2048.0f + NormalizedZ*m_y + NormalizedZ*m_TopLeft.y)*16.0f),  
									 (int)m_z, 
									  0));
	
	// Add the colour (Bottom Left)
	VIFDynamicDMA.Add128(PACKED_RGBA(m_r ,m_g, m_b, m_a));
	
	// Add UV texture coordinates (Bottom Left)
    VIFDynamicDMA.Add128(PACKED_UV(	((m_tu)<<4)+8, ((m_tv + m_th)<<4)+8));
	
		    	
	// Add the position (Bottom Left)  	
	VIFDynamicDMA.Add128(PACKED_XYZ2((int)((2048.0f + NormalizedZ*m_x + NormalizedZ*m_BottomLeft.x)*16.0f), 
									 (int)((2048.0f + NormalizedZ*m_y + NormalizedZ*m_BottomLeft.y)*16.0f),  
									 (int)m_z, 
									  0));
									  
	
	// Add the colour (Top Right)
	VIFDynamicDMA.Add128(PACKED_RGBA(m_r ,m_g, m_b, m_a));
	
	// Add UV texture coordinates (Top Right)
    VIFDynamicDMA.Add128(PACKED_UV(	((m_tu + m_tw)<<4)+8, ((m_tv)<<4)+8));
		    	
	// Add the position (Top Right)  	
	VIFDynamicDMA.Add128(PACKED_XYZ2((int)((2048.0f + NormalizedZ*m_x + NormalizedZ*m_TopRight.x)*16.0f), 
									 (int)((2048.0f + NormalizedZ*m_y + NormalizedZ*m_TopRight.y)*16.0f),  
									 (int)m_z, 
									  0));

	// Add the colour (Bottom Right)
	VIFDynamicDMA.Add128(PACKED_RGBA(m_r ,m_g, m_b, m_a));
	
	// Add UV texture coordinates
    VIFDynamicDMA.Add128(PACKED_UV(	((m_tu + m_tw)<<4)+8, ((m_tv + m_th)<<4)+8));
		    	
	// Add the position  (Bottom Right)  	
	VIFDynamicDMA.Add128(PACKED_XYZ2((int)((2048.0f + NormalizedZ*m_x + NormalizedZ*m_BottomRight.x)*16.0f), 
									 (int)((2048.0f + NormalizedZ*m_y + NormalizedZ*m_BottomRight.y)*16.0f),  
									 (int)m_z, 
									  0));
	
	
	VIFDynamicDMA.EndDirect();
}
