

// Custom_Dyn
// An optimal psi-plotter for dynamic lighting
// Removed from islpsi.c, because we're using "*4, possibly cached" vertex numbers

/**************************************************************************
	FUNCTION:	PSIDrawSortedPrims
	PURPOSE:	draw dynamic sorted polys
	PARAMETERS:	
	RETURNS:	
**************************************************************************/
#include "global.h"
#include "custom.h"


#ifdef INCLUDE_OLD_VERSION_RENDERER


#define GETX(n)( ((SHORTXY *)( (int)(tfv) +(n) ))->x )
#define GETY(n)( ((SHORTXY *)( (int)(tfv) +(n) ))->y )
#define GETV(n)(  *(u_long *)( (int)(tfv) +(n) ) )
#define GETD(n)(  *(u_long *)( (int)(tfd) +(n) ) )
#define GETN(n)( ((VERT *)( (int)(tfn) +(n<<1) )) )

void customPsiDrawSortedPrimitives(int depth,long *tfv)
{
	register PACKET*		packet = currentDisplayPage->primPtr;
//	register long			*tfv = transformedVertices;
	VERT 					*tfn = transformedNormals;
	register TMD_P_GT4I		*opcd;
	int						primsleft;
	ULONG					*sorts = sortedIndex;
	register long			t1;
	register long			t2;
	unsigned long *ot = currentDisplayPage->ot+depth;
	int						gteH;

	gte_ReadGeomScreen(&gteH);

	opcd = 0;
 
	for(primsleft = sortCount; primsleft; primsleft--)
	{

		while(opcd==0)
		{
			(int)opcd = *(sorts++);
		}

		switch (opcd->cd & (0xff-2))
		{

/*-----------------------------------------------------------------------------------------------------------------*/
// Was rmvd
#define si ((POLY_FT3*)packet)
#define op ((TMD_P_FT3I*)opcd)

			case GPU_COM_TF3:
				INCPOLYCOUNT(MODEL_POLYS);
//				BEGINPRIM(si, POLY_FT3);
				addPrimLen(ot,si,FT3_PRIMLEN,t1);

				gte_ldsxy3(GETV(op->v0), GETV(op->v1), GETV(op->v2));		// Load 1st three vertices
			
//				*(u_long *)  (&si->u0) = *(u_long *) (&op->tu0);		// Texture coords
//				*(u_long *)  (&si->u1) = *(u_long *) (&op->tu1);

				t1 = *(u_long *) (&op->tu0);
				t2 = *(u_long *) (&op->tu1);
				*(u_long *)  (&si->u0) = t1;
				*(u_long *)  (&si->u1) = t2;
				
				*(u_long *)  (&si->u2) = *(u_long *) (&op->tu2);

				gte_stsxy3_ft3(si);
				gte_ldv0(GETN(op->v0));
				gte_ncs();
				op = op->next;
				gte_strgb(&si->r0);
				si->code = GPU_COM_TF3;
				si++;
				break;
#undef si
#undef op

/*-----------------------------------------------------------------------------------------------------------------*/
// Was rmvd
#define si ((POLY_FT4*)packet)
#define op ((TMD_P_FT4I*)opcd)
				
				case GPU_COM_TF4:
				INCPOLYCOUNT(MODEL_POLYS);

//				BEGINPRIM(si, POLY_FT4);
				addPrimLen(ot,si,FT4_PRIMLEN,t1);

   			
				gte_ldsxy3(GETV(op->v0), GETV(op->v1), GETV(op->v2));		// Load 1st three vertices

				t1 = *(u_long *) (&op->tu0);
				t2 = *(u_long *) (&op->tu1);
				*(u_long *)  (&si->u0) = t1;
				*(u_long *)  (&si->u1) = t2;
				
//				*(u_long *)  (&si->u0) = *(u_long *) (&op->tu0);		// Texture coords
//				*(u_long *)  (&si->u1) = *(u_long *) (&op->tu1);

				gte_stsxy3_ft4(si);

				*(u_long *)  (&si->x3) = *(u_long *) (&GETV(op->v3));
				gte_ldv0(GETN(op->v0));
				gte_ncs();			
				gte_strgb(&si->r0);
				*(u_long *)  (&si->u2) = *(u_long *) (&op->tu2);
				*(u_long *)  (&si->u3) = *(u_long *) (&op->tu3);

				setPolyFT4(si);
				si->code = op->cd;
// 				ENDPRIM(si, depth, POLY_FT4);
				op = op->next;
				si++;
				break;
#undef si
#undef op

/*-----------------------------------------------------------------------------------------------------------------*/
// Okay, I've been optimising the GT3 to hell & gone...
// (The others, I'll do if & when we need 'em)
#define si ((POLY_GT3*)packet)
#define op ((TMD_P_GT3I*)opcd)

			case GPU_COM_TG3:
				INCPOLYCOUNT(MODEL_POLYS);
				gte_ldsxy3(GETV(op->v0), GETV(op->v1), GETV(op->v2));		// Load 1st three vertices
				
				t1 = *(u_long *) (&op->tu0);
				gte_stsxy3_gt3(si);	// 3 swc2's
				t2 = *(u_long *) (&op->tu1);
				gte_ldv3(GETN(op->v0), GETN(op->v1), GETN(op->v2));

				*(u_long *)  (&si->u0) = t1;
				*(u_long *)  (&si->u1) = t2;


// For the nct_b, we *must* have a couple of instructions beforehand to
// occupy the buffering NOP slots between it and the ldv3
// We can stick a fair amount of code into the (30 cycle) calculation
// zone that's enforced before the strgb3
//				gte_nct();
				gte_nct_b();


				addPrimLen(ot,si,GT3_PRIMLEN,t2);
				t1 = *(u_long *) (&op->tu2);
				op = op->next;

				*(u_long *)  (&si->u2) = t1;

				gte_strgb3(&si->r0, &si->r1, &si->r2);	// 3 swc2's
				si->code = GPU_COM_TG3;	// top bit of rgb0
				si++;
				break;
#undef si
#undef op
/*-----------------------------------------------------------------------------------------------------------------*/

#define si ((POLY_GT4*)packet)
#define op opcd

			case GPU_COM_TG4:
				INCPOLYCOUNT(MODEL_POLYS);
				addPrimLen(ot,si,GT4_PRIMLEN,t1);

				gte_ldsxy3(GETV(op->v0), GETV(op->v1), GETV(op->v2));		// Load 1st three vertices

				t1 = *(u_long *) (&op->tu0);
				t2 = *(u_long *) (&op->tu1);
				*(u_long *)  (&si->u0) = t1;
				*(u_long *)  (&si->u1) = t2;
					
				gte_stsxy3_gt4(si);

				t1 = *(u_long *) (&op->tu2);
				t2 = *(u_long *) (&op->tu3);
				*(u_long *)  (&si->u2) = t1;
				*(u_long *)  (&si->u3) = t2;
										
				*(u_long *)  (&si->x3) = *(u_long *) (&GETV(op->v3));
				gte_ldv3(GETN(op->v0), GETN(op->v1), GETN(op->v2));
				gte_nct();			
				gte_strgb3(&si->r0, &si->r1, &si->r2);

				gte_ldv0(GETN(op->v3));
				gte_ncs();			// NormalColorCol
				(int)op = op->next;

				gte_strgb(&si->r3);
				si->code = GPU_COM_TG4;	//op->cd;
				si++;
				break;

#undef si
#undef op

/*-----------------------------------------------------------------------------------------------------------------*/
// was rmvd
#define si ((POLY_FT4*)packet)
#define op ((TMD_P_FT4I*)opcd)

			case GPU_COM_TF4SPR :
				INCPOLYCOUNT(MODEL_POLYS);
				{
/*
				int			width, height;





				BEGINPRIM(si, POLY_FT4);

//	We can't use the "quick" scaling method in skinned objects, since we don't know which
//	bone the sprite is attached to, hence we can't rtps the vertex and get the scaled width/height,
//	so we have to do the scaling based on the distance ourselves.

				width = ((op->v2 * gteH) / tfd[op->v0]) / 2;
				height = ((op->v3 * gteH) / tfd[op->v0]) / 4;













 				*(u_long *)&si->r0 = *(u_long *)&op->r0;			// Texture coords / colors
				*(u_long *)&si->u0 = *(u_long *)&op->tu0;
				*(u_long *)&si->u1 = *(u_long *)&op->tu1;
				*(u_long *)&si->u2 = *(u_long *)&op->tu2;
				*(u_long *)&si->u3 = *(u_long *)&op->tu3;

				si->x1 = si->x3 = ((DVECTOR *)tfv)[op->v0].vx + width;
				si->x0 = si->x2 = ((DVECTOR *)tfv)[op->v0].vx - width;
				si->y2 = si->y3 = ((DVECTOR *)tfv)[op->v0].vy + height;
				si->y0 = si->y1 = ((DVECTOR *)tfv)[op->v0].vy - height;
				


				setPolyFT4(si);

				si->code = op->cd | modctrl->semitrans;

 				ENDPRIM(si, depth, POLY_FT4);
				op = op->next;
				}
*/


			}
//			si++;
			break;

#undef si
#undef op

/*-----------------------------------------------------------------------------------------------------------------*/
// was rmvd
#define si ((POLY_G4*)packet)
#define op ((TMD_P_FG4I*)opcd)
			case GPU_COM_G4:
			case GPU_COM_F4:
				INCPOLYCOUNT(MODEL_POLYS);
				
//				BEGINPRIM(si, POLY_G4);
				addPrimLen(ot,si,G4_PRIMLEN,t1);
   			
				gte_ldsxy3(GETV(op->v0), GETV(op->v1), GETV(op->v2));		// Load 1st three vertices

				*(u_long *)  (&si->x3) = *(u_long *) (&GETV(op->v3));
 
				
				gte_stsxy3_g4(si);

				gte_ldv3(GETN(op->v0), GETN(op->v1), GETN(op->v2));
				gte_nct();			
				gte_strgb3(&si->r0, &si->r1, &si->r2);

				gte_ldv0(GETN(op->v3));
				gte_ncs();			// NormalColorCol
				gte_strgb(&si->r3);

				setPolyG4(si);
				si->code = op->cd;
// 				ENDPRIM(si, depth, POLY_G4);
				op = op->next;
				si++;
				break;
#undef si
#undef op

/*-----------------------------------------------------------------------------------------------------------------*/

// At the moment, Ginger's crest is untextured
// (ummm, why?)
#define si ((POLY_G3*)packet)
#define op ((TMD_P_FG3I*)opcd)
			
			case GPU_COM_G3:
			case GPU_COM_F3:
				INCPOLYCOUNT(MODEL_POLYS);


				addPrimLen(ot,si,G3_PRIMLEN,t1);
 			
				gte_ldsxy3(GETV(op->v0), GETV(op->v1), GETV(op->v2));		// Load 1st three vertices

//				*(u_long *)  (&si->r0) = *(u_long *) (&op->r0);
				t1 = *((u_long *) (&op->r0));
				
				gte_stsxy3_g3(si);

				gte_ldv3(&tfn[op->v0], &tfn[op->v1], &tfn[op->v2]);

				*(u_long *)  (&si->r0) = t1;

				gte_nct();
				gte_strgb3(&si->r0, &si->r1, &si->r2);

				setPolyG3(si);
				si->code = op->cd;
				op = op->next;

				si++;
				break;
#undef si
#undef op

/*-----------------------------------------------------------------------------------------------------------------*/
		default:
			printf("prim %d\n",opcd->cd);
			break;
		}
	}
	currentDisplayPage->primPtr = packet;

}

#endif
