/*****************************************************************************
  Name : KMOnly.c
  Date : August 1998
  Platform : ANSI compatible
 
  * Description : 
  This file is part of the KAMUI TOOLS library (KMTools.lib) used
  with the SDK demos for PowerVR series 2.

  Set of specific functions for Kamui. 

  Copyright : 1998 by VideoLogic Limited. All rights reserved.
******************************************************************************/
#include "KMShell.h"

/* Shinobi for VideoInit only */
#include <sg_sycbl.h>

/* Linking with Ninja for Pad Control only */
#include <Ninja.h>
#include <ninjapad.h>

#include "tpApi.H"
MovieStruct movie1;

#ifndef M_KNOT
#define M_KNOT 0
#endif

/* Globals */
KMVERTEXBUFFDESC VertexBufferDesc;

/* Variables for Maple controler */
NJS_PERIPHERAL *PadPointer;
unsigned Pad;

PKMDWORD KMShellGetMaple (void);

void Counter(MovieStruct movie)
{
	sdSysServer();

	tpVSyncHandler(&movie1);
}

/************************************************************************
 *      MAIN
 ************************************************************************/
void main (void)
{
 	int Chain_hdl;
	char *nextMovie(void);

	extern PLAYER_STATUS_CODE tp_setupDisplay(MovieHandle movie);
	extern PLAYER_STATUS_CODE tp_setupAudioDriver(MovieHandle movie);
	int tp_command,exitPlayLoop=0,tpStatus;

#ifdef __GNUC__
    shinobi_workaround();
#endif
	tp_VCRControlSet(VCR_PLAY);

    InitApplication (); 
	
	/* get a list of movie names */
	if (!getMovieList(".")) /* try current directory */
		getMovieList("MOVIE"); /* try directory named "MOVIE" */

	/* re-initialize the movie structure */
	tp_MovieStructInit(&movie1, tp_setupDisplay,tp_setupAudioDriver);

	/* install vertical blanking interrupt (see truecore/shinobi/tpShinobiSnd.c) */
	Chain_hdl = syChainAddHandler( 0x0900, Counter , 0x70 , &movie1 );

	do{
		/* use the name of the "next" movie */
		strcpy(movie1.fileName,nextMovie());

		/* set the buffer to 512K */
		movie1.HFB_bufferSize = 512*1024;

		/*tp_MovieInitAndPlay(&movie1);*/

		tp_MovieServerExec(&movie1, VCR_INIT);

		tp_VCRControlSet(VCR_PLAY);

		exitPlayLoop = 0;

		/*   MAIN LOOP */
		while(!exitPlayLoop)
		{
			tp_command = tp_VCRKeyboardGet(&movie1);

			switch( tpStatus = tp_MovieServerExec(&movie1, tp_command)) {
				case TP_OK:
					continue; /* if nothing done, don't render */
				case TP_SKIPPED:
				case TP_PLAYING:
					break;

				case TP_FINISHED:
					exitPlayLoop = 1;
					break;

				case TP_EOF:
					tp_MovieServerExec(&movie1, VCR_FINISH);
					break;

				default:
					if (tpStatus < 0)
						exitPlayLoop = -1;
					break;
			}

			/*
			 * Controler data 
			 */
			
			KMShellGetMaple ();
			
			PadControl();

			/* 
			 * render the video background triangles 
			 */
			renderVideo();

			/*
			 * Draw our scene while TRUE is returned
			 */

			if (!RenderScene ()) break;


			/*
			 * Rendering start 
			 */
			kmRender();

			/* 
			 * Flip screen  
			 */
			kmFlipFrameBuffer();

		} /* End of while */

		/* shutdown movie server */
		tp_MovieServerExec(&movie1, VCR_SHUTDOWN);

	}while(1);

	QuitApplication();

	KMShellQuitKamui();
}
/*----------------------------------------------------------------------*/
/*  Function Name   : KMShellSetVideo                                   */
/*  Inputs          : VGAOn fOpaq fOpaqMV fTrans fTransMV fPnchTh       */  
/*  Outputs         : None                                              */
/*  Returns         : ErrorCode                                         */
/*  Globals Used    : VertexBufferDesc                                  */
/*  Description     : Init Kamui Video.                                 */ 
/*----------------------------------------------------------------------*/
KMDWORD KMShellSetVideo (BOOL bIsPreSort) 
{
KMPACKEDARGB   cBorder;
SYE_CBL_CABLE  cblCable;
        
	    /* Initialize the display device and set the frame buffer mode. */ 
        cblCable = syCblCheckCable();
    
        switch( cblCable ) 
        {
		default:
        case SYE_CBL_CABLE_VGA:
                sbInitSystem (KM_DSPMODE_VGA, KM_DSPBPP_RGB565, 2); 
                break;
     	   
	   case SYE_CBL_CABLE_NTSC_RGB:
	   case SYE_CBL_CABLE_NTSC:
                sbInitSystem (KM_DSPMODE_NTSCNI640x480, KM_DSPBPP_RGB565, 2); 
                break;
        }
	
	/* PRE-SORTING */
	if (bIsPreSort) kmSetAutoSortMode(FALSE); 

	/* Black Border */
	cBorder.dwPacked	=	0x00000000;
	kmSetBorderColor(cBorder);
    
}
/*----------------------------------------------------------------------*/
/*  Function Name   : KMShellSetBuffers                                 */
/*  Inputs          : VGAOn fOpaq fOpaqMV fTrans fTransMV fPnchTh       */  
/*  Outputs         : None                                              */
/*  Returns         : ErrorCode                                         */
/*  Globals Used    : VertexBufferDesc                                  */
/*  Description     : Init Kamui buffers.                               */ 
/*                    The size of each vertex buffer is given in %      */
/*----------------------------------------------------------------------*/
KMDWORD KMShellSetBuffers (float fOpaq, float fOpaqMV, float fTrans, float fTransMV,  float fPnchTh) 
{
PKMSURFACEDESC			pFB[2];
KMSYSTEMCONFIGSTRUCT	SystemConfig;
KMSURFACEDESC			PrimarySurfaceDesc;	
KMSURFACEDESC			BackSurfaceDesc; 
static unsigned char	*pCurrentPos;
static int				BuffPtr = 0x0CD80000;
KMDWORD					ErrorCode;

	pFB[0] = &PrimarySurfaceDesc;
	pFB[1] = &BackSurfaceDesc;
	SystemConfig.dwSize	=	sizeof(KMSYSTEMCONFIGSTRUCT);
	SystemConfig.flags	=	
		KM_CONFIGFLAG_ENABLE_CLEAR_FRAMEBUFFER |
		KM_CONFIGFLAG_NOWAIT_FINISH_TEXTUREDMA,

	/* for Frame buffer */
	SystemConfig.ppSurfaceDescArray	=	pFB;
	SystemConfig.nNumOfFrameBuffer	=	2;
	SystemConfig.nWidth				=	640; 
	SystemConfig.nHeight			=	480; 
	SystemConfig.nBpp				=	KM_DSPBPP_RGB565; 

	/* for Texture Memory */
	SystemConfig.nTextureMemorySize	=	(0x400000/sizeof(KMDWORD));	/* 4M byte Texture */

	/* for Vertex buffer */
	SystemConfig.pBufferDesc		=	&VertexBufferDesc;			/* VertexBufferDesc */

	pCurrentPos = (unsigned char *)(((unsigned long)BuffPtr + 0x1F) & ~0x1F);
	pCurrentPos	=	(void *)((((int)syMalloc(2*0x100000)&0x3FFFFFE0)|0xA0000000)+32);

	SystemConfig.pVertexBuffer		=	(PKMDWORD)(((KMDWORD)pCurrentPos  & 0x0FFFFFFF) | 0xA0000000 );
	
	SystemConfig.nVertexBufferSize	=	((0x27F000)/sizeof(KMDWORD));	/* VertexBuffer:1.5MB */

	/* These amounts in % */
	SystemConfig.fBufferSize[0]		=	fOpaq;	
	SystemConfig.fBufferSize[1]		=	fOpaqMV;	
	SystemConfig.fBufferSize[2]		=   fTrans;	
	SystemConfig.fBufferSize[3]		=	fTransMV;	
	SystemConfig.fBufferSize[4]		=	fPnchTh;	

	/* for Latency Model */
	SystemConfig.nVbufModel			=	 KM_VERTEXBUFMODEL_NORMAL;

	ErrorCode = kmSetSystemConfiguration( &SystemConfig );
	if (ErrorCode != KMSTATUS_SUCCESS) return ErrorCode;

	/* Everything's OK */
	return KMSTATUS_SUCCESS;
}

/*----------------------------------------------------------------------*/
/*  Function Name   : KMShellGetMaple                                   */
/*  Inputs          : None                                              */  
/*  Outputs         : None                                              */
/*  Returns         : None                                              */
/*  Globals Used    : VertexBufferDesc                                  */
/*  Description     :                                                   */
/*----------------------------------------------------------------------*/
PKMDWORD KMShellGetMaple (void)
{
	pdExecPeripheralServer();    

	PadPointer = njGetPeripheral(NJD_PORT_A0);

	if (PadPointer)
	{
		Pad = (unsigned)PadPointer->on;

		if(PadPointer->x1 < -100) Pad |= NJD_DGT_KL;
		if(PadPointer->x1 >  100) Pad |= NJD_DGT_KR;
		if(PadPointer->y1 < -100) Pad |= NJD_DGT_KU;
		if(PadPointer->y1 >  100) Pad |= NJD_DGT_KD;
	}
	else	Pad = (unsigned) 0;
}
/*----------------------------------------------------------------------*/

BOOL IsAKey(void) { return ((Pad & NJD_DGT_TA) ? TRUE : FALSE); }
BOOL IsBKey(void) { return ((Pad & NJD_DGT_TB) ? TRUE : FALSE); }
BOOL IsXKey(void) { return ((Pad & NJD_DGT_TX) ? TRUE : FALSE); }
BOOL IsYKey(void) { return ((Pad & NJD_DGT_TY) ? TRUE : FALSE); }

BOOL IsLFKey(void) { return ((Pad & NJD_DGT_TL) ? TRUE : FALSE); }
BOOL IsRFKey(void) { return ((Pad & NJD_DGT_TR) ? TRUE : FALSE); }

BOOL IsSTARTKey(void) { return ((Pad & NJD_DGT_ST) ? TRUE : FALSE); }
BOOL IsUPKey(void)	  { return ((Pad & NJD_DGT_KU) ? TRUE : FALSE); }
BOOL IsDOWNKey(void)  { return ((Pad & NJD_DGT_KD) ? TRUE : FALSE); }
BOOL IsLEFTKey(void)  { return ((Pad & NJD_DGT_KL) ? TRUE : FALSE); }
BOOL IsRIGHTKey(void) { return ((Pad & NJD_DGT_KR) ? TRUE : FALSE); }

/*----------------------------------------------------------------------*/
/*  Function Name   : KMShellQuitKamui                                  */
/*  Inputs          : None                                              */  
/*  Outputs         : None                                              */
/*  Returns         : None                                              */
/*  Globals Used    : VertexBufferDesc                                  */
/*  Description     : Free all buffers.                                 */
/*----------------------------------------------------------------------*/
void	KMShellQuitKamui(void)
{
	/* Free vertex buffer */
	kmDiscardVertexBuffer(&VertexBufferDesc);

	/* End display */
	kmStopDisplayFrameBuffer();

	/* Dreamcast end */
	sbExitSystem();
}

/*----------------------------------------------------------------------*/
/*  Function Name   :  KMShellInitVertexContext                         */
/*  Inputs          :  pVertexContext, *pTexSurfDesc                    */  
/*  Outputs         :  None                                             */
/*  Returns         :  None                                             */
/*  Globals Used    :  RenderInfo                                       */
/*  Description     :  Sets standard render parameters.                 */
/*----------------------------------------------------------------------*/
void KMShellInitVertexContext(PKMVERTEXCONTEXT pVertexContext, KMSURFACEDESC  *pTexSurfDesc, int nMode)
{
int nPoly;

    nPoly = nMode & 3;

    memset(pVertexContext, 0, sizeof(KMVERTEXCONTEXT));

	/*CONTEXT*/
	pVertexContext->RenderState	= KM_DEPTHMODE  		| KM_CULLINGMODE			
								| KM_SCREENCOORDINATION	| KM_SHADINGMODE
								| KM_MODIFIER 			| KM_ZWRITEDISABLE		
								| KM_SRCBLENDINGMODE	| KM_DSTBLENDINGMODE
								| KM_SRCSELECT			| KM_DSTSELECT
								| KM_FOGMODE			| KM_USESPECULAR
		 						| KM_USEALPHA			| KM_IGNORETEXTUREALPHA
								| KM_FLIPUV 			| KM_CLAMPUV 
								| KM_FILTERMODE			| KM_SUPERSAMPLE
								| KM_MIPMAPDADJUST 		| KM_TEXTURESHADINGMODE
								| KM_PARAMTYPE 			| KM_LISTTYPE 					
								| KM_COLORTYPE			| KM_USESPECULAR
								| KM_UVFORMAT;
    /* Texture */
	if (pTexSurfDesc) pVertexContext->pTextureSurfaceDesc	= pTexSurfDesc;

	pVertexContext->ParamType			= KM_POLYGON;
	pVertexContext->ColorType			= KM_PACKEDCOLOR;
	pVertexContext->UVFormat			= KM_32BITUV;
	pVertexContext->DepthMode			= KM_GREATEREQUAL;
	pVertexContext->ScreenCoordination	= KM_SCREEN;
	pVertexContext->SelectModifier		= KM_NOMODIFIER;
	pVertexContext->bZWriteDisable		= FALSE;			/* ARC1*/
	pVertexContext->SRCBlendingMode		= KM_ONE;
	pVertexContext->DSTBlendingMode		= KM_ZERO;
	pVertexContext->bSRCSel				= FALSE;			/* ARC1*/
	pVertexContext->bDSTSel				= FALSE;			/* ARC1*/
	pVertexContext->FlipUV				= KM_FLIP_UV;
	pVertexContext->ClampUV				= KM_NOCLAMP;
	pVertexContext->FilterMode			= KM_BILINEAR;
	pVertexContext->bSuperSample		= FALSE; 
	pVertexContext->MipMapAdjust		= KM_MIPMAP_D_ADJUST_1_00;
	pVertexContext->TextureShadingMode	= KM_MODULATE_ALPHA;

	/* No effect on ARC1 */
	pVertexContext->bColorClamp		= FALSE;
	pVertexContext->PaletteBank		= 0;

	/* for GlobalColorData */
	pVertexContext->fFaceColorAlpha		= 1.0f;		/* Face Color Alpha */
	pVertexContext->fFaceColorRed		= 1.0f;		/* Face Color Red */
	pVertexContext->fFaceColorGreen		= 1.0f;		/* Face Color Green */
	pVertexContext->fFaceColorBlue		= 1.0f;		/* Face Color Blue */
	pVertexContext->fOffsetColorAlpha	= 0.0f;		/* Specular Color Alpha */
	pVertexContext->fOffsetColorRed		= 0.0f;		/* Specular Color Red */
	pVertexContext->fOffsetColorGreen	= 0.0f;		/* Specular Color Green */
	pVertexContext->fOffsetColorBlue	= 0.0f;		/* Specular Color Blue */

	/* FLIP UV */
	if (nMode & VC_UVFLIP) 
		pVertexContext->FlipUV			= KM_FLIP_UV;
	else 
		pVertexContext->FlipUV			= KM_NOFLIP;

	/* POLYGON */
	pVertexContext->ListType			= KM_OPAQUE_POLYGON; /* opaque by default */
	if (nPoly==VC_TRANS || nPoly==VC_ADDITIVE) 
		pVertexContext->ListType	    = KM_TRANS_POLYGON;
	if (nPoly==VC_PUNCHTHROUGH) 
		pVertexContext->ListType	    = KM_PUNCHTHROUGH_POLYGON;

	/* CULLING */
	pVertexContext->CullingMode			= KM_NOCULLING;
	if(nMode & VC_CULLING)
		pVertexContext->CullingMode		= KM_CULLCCW;

	/* TEXTURED */
	pVertexContext->ShadingMode			= KM_TEXTUREGOURAUD;
	if (nMode & VC_NONTEXTURED)
		pVertexContext->ShadingMode		= KM_NOTEXTUREGOURAUD;

	/* BLEND */
	if (nPoly==VC_TRANS | nPoly==VC_PUNCHTHROUGH)
	{
		pVertexContext->SRCBlendingMode		= KM_SRCALPHA;
		pVertexContext->DSTBlendingMode		= KM_INVSRCALPHA;
	}

	if (nPoly==VC_ADDITIVE)
	{
		pVertexContext->SRCBlendingMode		= KM_ONE;
		pVertexContext->DSTBlendingMode		= KM_ONE;
	}

	/* FOG */
	pVertexContext->FogMode				= KM_NOFOG;	
	if (nMode & VC_FOGVERTEX)
		pVertexContext->FogMode			= KM_FOGVERTEX;	
	if (nMode & VC_FOGTABLE)
		pVertexContext->FogMode			= KM_FOGTABLE;	

	/* SPECULAR */
	pVertexContext->bUseSpecular		= FALSE;
	if (nMode & VC_SPECULAR)

		pVertexContext->bUseSpecular	= TRUE;

    /* TRANSLUCENCY */
	pVertexContext->bUseAlpha			= (nPoly==VC_TRANS | nPoly==VC_PUNCHTHROUGH | nPoly==VC_ADDITIVE);
	

	kmProcessVertexRenderState(pVertexContext);

}
/*----------------------------------------------------------------------*/
/*  Function Name   : KMShellLoadTexture                                */
/*  Inputs          : pTextureSurfaceDesc, pSourceTex, SizeX, SizeY,    */  
/*                    nTextureType,                                     */
/*  Outputs         : None                                              */
/*  Returns         : ErrorCode                                         */
/*  Globals Used    : None                                              */
/*  Description     : This function loads in video memory a square      */
/*                    texture already set in a memory buffer.           */       
/*----------------------------------------------------------------------*/
KMDWORD KMShellLoadTexture(KMSURFACEDESC *pTexSurfaceDesc, unsigned long *pSourceTex, KMINT32 Size, KMTEXTURETYPE nTextureType)
{
KMDWORD ErrorCode;

	/* Create texture surface */
	ErrorCode = kmCreateTextureSurface(
		pTexSurfaceDesc,		/* OUT	PKMSURFACEDESC	pSurfaceDesc */
		Size,					/*	IN	KMINT32			nWidth */
		Size,					/*	IN	KMINT32			nHeight */
		nTextureType			/*	IN	KMTEXTURETYPE	nTextureType */
	);

	if (ErrorCode != KMSTATUS_SUCCESS) return ErrorCode;


	/* Load and set texture */
	ErrorCode = kmLoadTexture( 
		pTexSurfaceDesc,						/* PKMSURFACEDESC pSurfaceDesc */
		pSourceTex + (16 / sizeof(KMDWORD)),	/* PKMDWORD pTexture */
		FALSE,									/* KMBOOLEAN bAutoMipMap */
		FALSE									/* KMBOOLEAN bDither */
	);

	if (ErrorCode != KMSTATUS_SUCCESS) return ErrorCode;

	/* Everything's OK */
	return KMSTATUS_SUCCESS;
}
/*----------------------------------------------------------------------*/
/*  Function Name   : KMShellStrips                                     */
/*  Inputs          : nNumStrips *pLen *pStrips *pVertices              */  
/*  Outputs         : None                                              */
/*  Returns         : None                                              */
/*  Globals Used    : VertexBufferDesc                                  */
/*  Description     : This is a Kamui version of sgltri_index_strips.   */
/*----------------------------------------------------------------------*/
void KMShellStrips (PKMVERTEXCONTEXT pVertexContext, unsigned nNumStrips, unsigned short *pLen, 
						unsigned short *pStrips, KMVERTEX_03 *pVertices)
{
int i, j;
int nVertices;
int nFace, nFacesCont=0;

    kmSetVertexRenderState (pVertexContext);

	/* Textured Vertices KMVERTEX_03 */

	if ((pVertexContext->ShadingMode == KM_TEXTUREGOURAUD) ||
		(pVertexContext->ShadingMode == KM_TEXTUREFLAT))
	{

		for (j=0; j<nNumStrips; j++)
		{
			nVertices = *(pLen+j) + 1;

			/* Strip start */
			kmxxGetCurrentPtr(&VertexBufferDesc);
			kmxxStartVertexStrip(&VertexBufferDesc);

			/* Setting vertices */
			for(i = nVertices; i >= 0; i--)
			{
				nFace = *(pStrips+nFacesCont++);
				(pVertices+nFace)->ParamControlWord	= (i!=0)?KM_VERTEXPARAM_NORMAL:KM_VERTEXPARAM_ENDOFSTRIP;

				kmxxSetVertex_3((pVertices+nFace)->ParamControlWord, 
							(pVertices+nFace)->fX, (pVertices+nFace)->fY, (pVertices+nFace)->u.fZ, 
							(pVertices+nFace)->fU, (pVertices+nFace)->fV,
							(pVertices+nFace)->uBaseRGB.dwPacked, (pVertices+nFace)->uOffsetRGB.dwPacked);
			}

			/* Strip end */
			kmxxReleaseCurrentPtr(&VertexBufferDesc);
		}					
	}
	else /* NonTextured  KMVERTEX_00 */
	{
		for (j=0; j<nNumStrips; j++)
		{
			nVertices = *(pLen+j) + 1;

			/* Strip start */
			kmxxGetCurrentPtr(&VertexBufferDesc);
			kmxxStartVertexStrip(&VertexBufferDesc);

			/* Setting vertices */
			for(i = nVertices; i >= 0; i--)
			{
				nFace = *(pStrips+nFacesCont++);
				(pVertices+nFace)->ParamControlWord	= (i!=0)?KM_VERTEXPARAM_NORMAL:KM_VERTEXPARAM_ENDOFSTRIP;

				kmxxSetVertex_0((pVertices+nFace)->ParamControlWord, 
							(pVertices+nFace)->fX, (pVertices+nFace)->fY, (pVertices+nFace)->u.fZ, 
							(pVertices+nFace)->uBaseRGB.dwPacked);
			}

			/* Strip end */
			kmxxReleaseCurrentPtr(&VertexBufferDesc);
		}					
	}
}
/*------------------------------------------------------------------------*/
/*  Function Name   : KMShellTriangles                                    */
/*  Inputs          : nNumfaces *pFaces *pVertices                        */  
/*  Outputs         : None                                                */
/*  Returns         : None                                                */
/*  Globals Used    : VertexBufferDesc                                    */
/*  Description     : This is a Kamui version of sgltri_index_triangles.  */
/*                                                                        */
/*  Warning			: To use triangles(one-poly strip) is not recomended  */
/*					  because it generates more pointers in the parameter */
/*					  buffer than longer strips.     					  */								
/*------------------------------------------------------------------------*/
void KMShellTriangles (PKMVERTEXCONTEXT pVertexContext, unsigned nNumFaces,
						unsigned short *pFaces, KMVERTEX_03	*pVertices)
{
int nFace, nFacesCont=0, i;

	kmSetVertexRenderState (pVertexContext);

	/* Textured Vertices KMVERTEX_03 */

	if ((pVertexContext->ShadingMode == KM_TEXTUREGOURAUD) ||
		(pVertexContext->ShadingMode == KM_TEXTUREFLAT))
	{

		for(i = 0; i < nNumFaces; i++)
		{
			/* Strip start */
			kmxxGetCurrentPtr(&VertexBufferDesc);
			kmxxStartVertexStrip(&VertexBufferDesc);

			/* Vertex 1 */
			nFace = *(pFaces+nFacesCont++);
			kmxxSetVertex_3(KM_VERTEXPARAM_NORMAL, 
							(pVertices+nFace)->fX, (pVertices+nFace)->fY, (pVertices+nFace)->u.fZ, 
							(pVertices+nFace)->fU, (pVertices+nFace)->fV,
							(pVertices+nFace)->uBaseRGB.dwPacked, (pVertices+nFace)->uOffsetRGB.dwPacked);

			/* Vertex 2 */
			nFace = *(pFaces+nFacesCont++);
			kmxxSetVertex_3(KM_VERTEXPARAM_NORMAL, 
							(pVertices+nFace)->fX, (pVertices+nFace)->fY, (pVertices+nFace)->u.fZ, 
							(pVertices+nFace)->fU, (pVertices+nFace)->fV,
							(pVertices+nFace)->uBaseRGB.dwPacked, (pVertices+nFace)->uOffsetRGB.dwPacked);
			
			/* Vertex 3 */
			nFace = *(pFaces+nFacesCont++);
			kmxxSetVertex_3(KM_VERTEXPARAM_ENDOFSTRIP, 
							(pVertices+nFace)->fX, (pVertices+nFace)->fY, (pVertices+nFace)->u.fZ, 
							(pVertices+nFace)->fU, (pVertices+nFace)->fV,
							(pVertices+nFace)->uBaseRGB.dwPacked, (pVertices+nFace)->uOffsetRGB.dwPacked);

			/* Strip end */
			kmxxReleaseCurrentPtr(&VertexBufferDesc);
		}								
	}
	else /* NonTextured */
	{
		for(i = 0; i < nNumFaces; i++)
		{
			/* Strip start */
			kmxxGetCurrentPtr(&VertexBufferDesc);
			kmxxStartVertexStrip(&VertexBufferDesc);

			/* Vertex 1 */
			nFace = *(pFaces+nFacesCont++);
			kmxxSetVertex_0(KM_VERTEXPARAM_NORMAL, 
							(pVertices+nFace)->fX, (pVertices+nFace)->fY, (pVertices+nFace)->u.fZ, 
							(pVertices+nFace)->uBaseRGB.dwPacked);

			/* Vertex 2 */
			nFace = *(pFaces+nFacesCont++);
			kmxxSetVertex_0(KM_VERTEXPARAM_NORMAL, 
							(pVertices+nFace)->fX, (pVertices+nFace)->fY, (pVertices+nFace)->u.fZ, 
							(pVertices+nFace)->uBaseRGB.dwPacked);
			
			/* Vertex 3 */
			nFace = *(pFaces+nFacesCont++);
			kmxxSetVertex_0(KM_VERTEXPARAM_ENDOFSTRIP, 
							(pVertices+nFace)->fX, (pVertices+nFace)->fY, (pVertices+nFace)->u.fZ, 
							(pVertices+nFace)->uBaseRGB.dwPacked);

			/* Strip end */
			kmxxReleaseCurrentPtr(&VertexBufferDesc);
		}				
	}
}

/*----------------------------------------------------------------------*/
/*  Function Name   :  KMShellGetVertexBuffer                           */
/*  Inputs          :  *VertexContext                                   */  
/*  Outputs         :  None                                             */
/*  Returns         :  None                                             */
/*  Globals Used    :  VertexBufferDesc                                 */
/*  Description     :  Retrieve the vertex buffer pointer               */
/*----------------------------------------------------------------------*/
KMVERTEXBUFFDESC *KMShellGetVertexBuffer (void)
{
	return (&VertexBufferDesc);
}

