/***************************************************************************
 *
 * n64res.c
 *
 ***************************************************************************
 *
 * code for dealing with N64 resources
 *
 ***************************************************************************/

/*
 * includes
 */

#include "ult_64.h"
#include "n64res.h"
#include "n64cmd.h"

/*
 * defines
 */

#define USE2TRI

/*
 * typedefs
 */

/*
 * structures
 */

/*
 * globals
 */

int loveMonkey=0;

int disablePrimCol=0;
int n64ResAlpha=0xFF;
int n64ShpSize;

/*
 * function prototypes
 */

/*
 * code
 */


#if 0	// ------------- not needed in Kobe 2

/***************************************************************************
 *
 * int N64ResGenerateDL(n64Script *scr,Gfx *dl,unsigned long size,vtxMap *m)
 *
 ***************************************************************************
 *
 * Generate a display list from a script and a vtx (tag->tex) map
 *
 ***************************************************************************/

int N64ResGenerateDL(n64Script *scr,Gfx *dl,unsigned long size,vtxMap *m)
{
	Gfx *w;
	unsigned char *s;
	int i,j,k;
	Vtx *v;
	texture *t;
	int lsx,lsy,sx,sy;
	unsigned char *bmpPtr;
	int xFlg,yFlg;
	int hTriangle;
	int ht[3];

	w=dl;
	s=&(scr->data[0]);
	v=*(scr->vertices);

	hTriangle=0;

	while(1)
	{
		if(s[0]==CMD_END)
		{
			if(hTriangle)
			{
				gSP1Triangle(w++,ht[0],ht[1],ht[2],0);
				hTriangle=0;
			}
			gSPEndDisplayList(w++);
			break;
		}

		switch(s[0])
		{
			case CMD_LOAD_MATRIX:
				s+=4;
				break;

			case CMD_LOAD_VERTICES:
				if(hTriangle)
				{
					gSP1Triangle(w++,ht[0],ht[1],ht[2],0);
					hTriangle=0;
				}
				i=s[1];
				j=((unsigned short *)s)[1];
				gSPVertex(w++,&v[j],i,0);
				s+=4;
				break;
			case CMD_LOAD_VERTICES_OFFSET:
				if(hTriangle)
				{
					gSP1Triangle(w++,ht[0],ht[1],ht[2],0);
					hTriangle=0;
				}
				i=s[1];
				j=((unsigned short *)s)[1];
				gSPVertex(w++,&v[j],i,s[4]);
				s+=8;
				break;
			case CMD_GO_FLAT:
				if(hTriangle)
				{
					gSP1Triangle(w++,ht[0],ht[1],ht[2],0);
					hTriangle=0;
				}
				gDPPipeSync(w++);
				gSPTexture(w++,0,0,0,0,G_OFF);
				gDPSetCombineMode(w++,G_CC_PRIMITIVE,G_CC_PRIMITIVE);
				s+=4;
				break;
			case CMD_PRIM_COL:
				if(hTriangle)
				{
					gSP1Triangle(w++,ht[0],ht[1],ht[2],0);
					hTriangle=0;
				}
				if(!disablePrimCol)
				{
					gDPPipeSync(w++);
					gDPSetPrimColor(w++,0,0,s[1],s[2],s[3],n64ResAlpha);
				}
				else
				{
					// need padding... keep same size!
					gDPPipeSync(w++);
					gDPPipeSync(w++);
				}
				s+=4;
				break;
			case CMD_TRIANGLE:
#ifdef USE2TRI
				if(!hTriangle)
				{
					ht[0]=s[1];
					ht[1]=s[2];
					ht[2]=s[3];
					hTriangle=1;
				}
				else
				{
					gSP2Triangles(w++,
						      ht[0],ht[1],ht[2],0,
					              s[1],s[2],s[3],0);
					hTriangle=0;
				}
#else
				gSP1Triangle(w++,s[1],s[2],s[3],0);
#endif
				s+=4;
				break;
			case CMD_GO_TEXTURED:
				if(hTriangle)
				{
					gSP1Triangle(w++,ht[0],ht[1],ht[2],0);
					hTriangle=0;
				}
				gDPPipeSync(w++);
				gSPTexture(w++,0x8000,0x8000,0,G_TX_RENDERTILE,G_ON);
				gDPSetCombineMode(w++,G_CC_DECALRGB,G_CC_DECALRGB);
				s+=4;
				break;
			case CMD_LOAD_TEXTURE:
				if(hTriangle)
				{
					gSP1Triangle(w++,ht[0],ht[1],ht[2],0);
					hTriangle=0;
				}
				if(!m)
				{
					s+=8;
					break;
				}

				xFlg=(s[3] & 1)?G_TX_WRAP:G_TX_CLAMP;
				yFlg=(s[3] & 2)?G_TX_WRAP:G_TX_CLAMP;
				lsx=s[2] & 0xF;
				lsy=(s[2]>>4)&0xF;
				sx=1 << lsx;
				sy=1 << lsy;

				if(s[1]==1)
				{
					// get texture handle
					t=*((((texture ***)s)[1]));
					bmpPtr=*(t->bitmapHandle);
				}
				else if(s[1]==2)
				{
					bmpPtr=*((((unsigned char ***)s)[1]));
				}
				else if(s[1]==0)
				{
					// use VTX
					t=NULL;
					j=((long int *)s)[1];
					for(i=0;i<m->count;i++)
					{
						if(m->entries[i].tag == j)
						{
							t=*(m->entries[i].tex);
						}
					}
					if(!t) return(1);
					bmpPtr=*(t->bitmapHandle);
				}

				gDPLoadTextureBlock(w++,
						    bmpPtr,
						    G_IM_FMT_CI,
						    G_IM_SIZ_8b,
						    sx,
						    sy,
						    0,
						    xFlg,yFlg,
						    lsx,lsy,
						    G_TX_NOLOD,G_TX_NOLOD);
				s+=8;
				break;
		}
	}
	if(hTriangle)
	{
		gSP1Triangle(w++,ht[0],ht[1],ht[2],0);
		hTriangle=0;
	}

	i=w-dl;

	n64ShpSize+=i*sizeof(Gfx);

	return(0);
}


/***************************************************************************
 *
 *
 *
 ***************************************************************************
 *
 *
 *
 ***************************************************************************/

int N64ResGetSize(n64Script *scr,int useTex)
{
	unsigned char *s;
	int i;
	int hTriangle;

	i=0;
	s=&scr->data[0];

	hTriangle=0;

	while(1)
	{
		if(s[0]==CMD_END)
		{
			if(hTriangle)
			{
				i++; hTriangle=0;
			}
			i++;
			break;
		}

		switch(s[0])
		{
			case CMD_LOAD_MATRIX:
				s+=4;
				break;

			case CMD_LOAD_VERTICES:
				if(hTriangle)
				{
					i++; hTriangle=0;
				}
				i++;
				s+=4;
				break;
			case CMD_LOAD_VERTICES_OFFSET:
				if(hTriangle)
				{
					i++; hTriangle=0;
				}
				i++;
				s+=8;
#ifdef PIRACY
				s+=loveMonkey;	// ought to break something!
#endif
				break;
			case CMD_GO_FLAT:
				if(hTriangle)
				{
					i++; hTriangle=0;
				}
				i+=3;
				s+=4;
				break;
			case CMD_PRIM_COL:
				if(hTriangle)
				{
					i++; hTriangle=0;
				}
				i++;
				i++;
				s+=4;
				break;
			case CMD_TRIANGLE:
#ifdef USE2TRI
				if(hTriangle)
				{
					i++; hTriangle=0;
				}
				else
				{
					hTriangle=1;
				}
#else
				i++;
#endif
				s+=4;
				break;
			case CMD_GO_TEXTURED:
				if(hTriangle)
				{
					i++; hTriangle=0;
				}
				i+=3;
				s+=4;
				break;
			case CMD_LOAD_TEXTURE:
				if(hTriangle)
				{
					i++; hTriangle=0;
				}
				if(!useTex)
				{
					s+=8;
					break;
				}
				i+=7;
				s+=8;
				break;
		}
	}
	if(hTriangle)
	{
		i++; hTriangle=0;
	}

	return(i);
}

/***************************************************************************
 *
 *
 *
 ***************************************************************************
 *
 *
 *
 ***************************************************************************/

void N64ResAppendDL(n64Script *scr,Gfx **dl,vtxMap *m)
{
	if(!scr->size) scr->size=N64ResGetSize(scr,m?1:0);
	N64ResGenerateDL(scr,*dl,0,m);
	(*dl)+=scr->size-1;
}



#endif 	// ------------- not needed in Kobe 2



/***************************************************************************
 *
 * void N64ResSetAlpha(int a)
 *
 ***************************************************************************
 *
 *
 *
 ***************************************************************************/

void N64ResSetAlpha(int a)
{
	n64ResAlpha=a;
}


/***************************************************************************
 *
 *
 *
 ***************************************************************************
 *
 *
 *
 ***************************************************************************/

void N64ResDisablePrimCol(int yes)
{
	disablePrimCol=yes;
}

/***************************************************************************
 *
 *
 *
 ***************************************************************************
 *
 *
 *
 ***************************************************************************/



/***************************************************************************
 *
 *
 *
 ***************************************************************************
 *
 *
 *
 ***************************************************************************/

