/*----------------------------------------------------------------
   Name   : Blend.c  (Alpha blending Test - ARC1 demo - Beta3 version)
   Author : Carlos Sarria
   Date   : Jan 1998

   Copyright : 1998 by VideoLogic Limited. All rights reserved.
   Modified  : 09, June, 1998 by Takeshi Muto / NEC Software,Ltd. for KAMUI
 -----------------------------------------------------------------*/

/*
#define		_X86_
*/
/* _X86_ flag for win95 : SET2 */

#define		_DISPLAY_STRING_
/* if defined then display strings on screen */

#define		_DISP_PERFORMANCE_
/* Display performance : for windows */

#include <stdio.h>
#include <math.h>

#include	<shinobi.h>

#if defined(_X86_)
	#include <conio.h>
#endif

#pragma warning (disable : 4244) /* Disables float to double conversion warning */

#include	"kamui.h"				/* for Kamui Call */
#include	"dispstr.h"				/* for DisplayString */
/* #include "sgl2.h" */

#define _KM_USE_VERTEX_MACRO_
#define _KM_USE_VERTEX_MACRO_L3_
#include	"kamuix.h"

/* Set Display Mode */
#define NTSC 1

#define PI	3.1416f

#define K_ESC    27
#define K_SPC    32
#define K_F1     59
#define K_F2     60
#define K_F3     61
#define K_F4     62
#define K_F5     63
#define K_F6     64
#define K_F7     65
#define K_F8     66
#define K_F9     67
#define K_F10    68
#define K_F11    133
#define K_F12    134
#define K_UP     72
#define K_DOWN   80
#define K_LEFT   75
#define K_RIGHT  77


#define RGBAColour(r, g, b, a)   ((unsigned long) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b)))

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

#define	RGBColour(r, g, b)	((KMUINT32) (((r) << 16) | ((g) << 8) | (b)))
#define	RGBA(r, g, b, a)	((KMUINT32) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b)))

/* Macros for kamui */
#define		GetRED(col)			((KMFLOAT) ( ((col) & 0x00ff0000) >> 16 ) / 256.0f)
#define		GetGREEN(col)		((KMFLOAT) ( ((col) & 0x0000ff00) >>  8 ) / 256.0f)
#define		GetBLUE(col)		((KMFLOAT) ( ((col) & 0x000000ff)       ) / 256.0f)
#define		GetALPHA(col)		((KMFLOAT) ( ((col) & 0xff000000) >> 24 ) / 256.0f)


typedef int			sgl_bool;
typedef	KMUINT32	sgl_uint32;		/* type of sgl_uint32 */
typedef float		sgl_vector[3];	/* type of sgl_vector */
typedef float		sgl_2d_vec[2];	/* type of sgl_2d_vec */
typedef float		sgl_colour[3];	/* type of sgl_colour */
/* --------- */
/* SGLVERTEX */
/* --------- */
/* This structure is currently physically equivalent to Direct3D's D3DTLVERTEX */
/* (so one can be cast to the other), with the exception that Direct3D's u and */
/* v values must be multiplied by the 1/w value.  RAVE vertices already contain */
/* u/w and v/w. */
typedef struct tagSGLVERTEX
{
	/* Projected screen coordinates: */
	float		fX;		/* 0 <= fX < screen width (up to 1024) */
	float		fY;		/* 0 <= fY < screen height (up to 1024) */
	float		fZ;		/* 0.01 <= fZ <= 1, where 1 is infinite distance away */
	/* 1/w for the perspective projection (should be set to 1.0/fZ; fZ is */
	/* actually ignored): */
	float		fInvW;
	KMUINT32	u32Colour;			/* Material colour (D3DCOLOR format): */
	KMUINT32	u32Specular;		/* Specular colour (D3DCOLOR format): */
	float		fUOverW, fVOverW;	/* Texture coordinates: */
} SGLVERTEX, *PSGLVERTEX;
/****************************************************************************/
/**	Valuables for KAMUI *****************************************************/
/****************************************************************************/
	KMSTATUS			status;					/* return status of KAMUI API */
	KMVERSIONINFO		VersionInfo;			/* KAMUI Version information */
	KMSURFACEDESC		PrimarySurfaceDesc;		/* Primary frame buffer */
	KMSURFACEDESC		BackSurfaceDesc;		/* Back-buffer frame buffer */
	KMVERTEXBUFFDESC	VertexBufferDesc;		/* Vertex-buffer */
	KMVERTEXCONTEXT		VertexContextGold;		/* Vertex context */
	KMVERTEXCONTEXT		VertexContextTrans;		/* Vertex context */
	KMDWORD				FogDensity;				/* Fog density */
	KMDWORD				FogD = 1;

	PKMSURFACEDESC			pFB[2];
	KMSYSTEMCONFIGSTRUCT	SystemConfig;
	PKMDWORD				dwDataPtr;

/*------------------------------- Global Variables -----------------------------------*/
/* Globals */
/*--
static SGLCONTEXT	SGLContext;
static SGLCONTEXT2	SGLContext2;
static unsigned		TexOpaq, TexTrans, TexBack, TexGold;
--*/
KMSURFACEDESC		TexOpaq, TexTrans, TexBack, TexGold;
static unsigned		Frame			= 0;
static int			BlendSrc		= 4;	/* SRCA */
static int			BlendDst		= 5;	/* INVSRCA */
static int			BlendModulate	= TRUE;	/* MODULATE */
#if 0
static int			AlphaSource		= 1;	/* VERTEX ALPHA */
#endif
static int			AlphaSource		= 0;	/* TEXTURE ALPHA */
static int			PosZ			= 800;


/* Info Structure */

struct
{
	sgl_bool	VertexAlpha;
	sgl_bool    AlphaBlend;

} Info =
{
   	TRUE,      /* VertexAlpha */
	TRUE		/* AlphaBlend  */
};


/* Prototypes */

static void SetContext			(void);
static void SetTextures			(void);
static void NextFrame			(void);
static void DisplayInformation	(void);
static void SetPlane			(int Num, KMVERTEXCONTEXT VertexContext );
static void SetBackground		(PKMSURFACEDESC TextureID);

static void ReadMaple			(void);		/* Maple data read routine */

/* Textures */
extern unsigned char Opaq;
extern unsigned char Trans;
extern unsigned char Back;
extern unsigned char Gold;

/* Macros for kamui */
#define		GetRED(col)			((KMFLOAT) ( ((col) & 0x00ff0000) >> 16 ) / 256.0f)
#define		GetGREEN(col)		((KMFLOAT) ( ((col) & 0x0000ff00) >>  8 ) / 256.0f)
#define		GetBLUE(col)		((KMFLOAT) ( ((col) & 0x000000ff)       ) / 256.0f)
#define		GetALPHA(col)		((KMFLOAT) ( ((col) & 0xff000000) >> 24 ) / 256.0f)

/****************************************************************************/
/**	Check KAMUI function status *********************************************/
/****************************************************************************/
void	Check_Status(KMSTATUS status, char *func)
{
	switch(status) {
	case KMSTATUS_SUCCESS:
		/* No message is displayed when SUCCESS */
		break;
	case KMSTATUS_INVALID_DISPLAY_MODE:
		PRINTOUT(("%s:KMSTATUS_INVALID_DISPLAY_MODE\n",func)); break;
	case KMSTATUS_INVALID_VIDEO_MODE:
		PRINTOUT(("%s:KMSTATUS_INVALID_VIDEO_MODE\n",func)); break;
	case KMSTATUS_NOT_ENOUGH_MEMORY:
		PRINTOUT(("%s:KMSTATUS_NOT_ENOUGH_MEMORY\n",func)); break;
	case KMSTATUS_INVALID_TEXTURE_TYPE:
		PRINTOUT(("%s:KMSTATUS_INVALID_TEXTURE_TYPE\n",func)); break;
	case KMSTATUS_INVALID_MIPMAPED_TEXTURE:
		PRINTOUT(("%s:KMSTATUS_INVALID_MIPMAPED_TEXTURE\n",func)); break;
	case KMSTATUS_CANT_FLIP_SURFACE:
		PRINTOUT(("%s:KMSTATUS_CANT_FLIP_SURFACE\n",func)); break;
	case KMSTATUS_INVALID_ADDRESS:
		PRINTOUT(("%s:KMSTATUS_INVALID_ADDRESS\n",func)); break;
	case KMSTATUS_HARDWARE_NOT_PRESENTED:
		PRINTOUT(("%s:KMSTATUS_HARDWARE_NOT_PRESENTED\n",func)); break;
	case KMSTATUS_INVALID_SETTING:
		PRINTOUT(("%s:KMSTATUS_INVALID_SETTING\n",func)); break;
	case KMSTATUS_INVALID_VERTEX_TYPE:
		PRINTOUT(("%s:KMSTATUS_INVALID_VERTEX_TYPE\n",func)); break;
	case KMSTATUS_NOT_IMPLEMENTED:
		PRINTOUT(("%s:KMSTATUS_NOT_IMPREMENTED\n",func)); break;
	case KMSTATUS_INVALID_PARAMETER:
		PRINTOUT(("%s:KMSTATUS_INVALID_PARAMETER\n",func)); break;
	default:
		PRINTOUT(("%s:???Undefined status : %d\n", func, status));
		break;
	}
}

/****************************************************************************/
/**	kmtri_triangles  by T.Hirata ********************************************/
/****************************************************************************/
void 
kmtri_triangles ( KMVERTEXBUFFDESC		BufferDesc,
				  KMVERTEXCONTEXT		VertexContext,
				  int  					nNumFaces,
				  int  					pFaces[][3],
				  PSGLVERTEX  			pVertices,
				  int					bTexture)
{
	KMSTATUS	status;
	int			i;
	PSGLVERTEX	pVert;

	status = kmSetVertexRenderState(&VertexContext);
	Check_Status(status, "kmSetVertexRenderState");
	kmxxGetCurrentPtr(&BufferDesc);

	for(i = 0; i < nNumFaces; i++)
	{
		kmxxStartVertexStrip(&BufferDesc);
		if(bTexture == TRUE) {
			pVert = &pVertices[pFaces[i][0]];
			kmxxSetVertex_3(KM_VERTEXPARAM_NORMAL,
							pVert->fX,
							pVert->fY,
							pVert->fInvW,
							pVert->fUOverW,
							pVert->fVOverW,
							pVert->u32Colour,
							pVert->u32Specular
							);

			pVert = &pVertices[pFaces[i][1]];
			kmxxSetVertex_3(KM_VERTEXPARAM_NORMAL,
							pVert->fX,
							pVert->fY,
							pVert->fInvW,
							pVert->fUOverW,
							pVert->fVOverW,
							pVert->u32Colour,
							pVert->u32Specular
							);

			pVert = &pVertices[pFaces[i][2]];
			kmxxSetVertex_3(KM_VERTEXPARAM_ENDOFSTRIP,
							pVert->fX,
							pVert->fY,
							pVert->fInvW,
							pVert->fUOverW,
							pVert->fVOverW,
							pVert->u32Colour,
							pVert->u32Specular
							);
		}
		else {	/* if(bTexture == TRUE) : NO-TEXTURE */
			pVert = &pVertices[pFaces[i][0]];
			kmxxSetVertex_0(KM_VERTEXPARAM_NORMAL,
							pVert->fX,
							pVert->fY,
							pVert->fInvW,
							pVert->u32Colour
							);

			pVert = &pVertices[pFaces[i][1]];
			kmxxSetVertex_0(KM_VERTEXPARAM_NORMAL,
							pVert->fX,
							pVert->fY,
							pVert->fInvW,
							pVert->u32Colour
							);

			pVert = &pVertices[pFaces[i][2]];
			kmxxSetVertex_0(KM_VERTEXPARAM_ENDOFSTRIP,
							pVert->fX,
							pVert->fY,
							pVert->fInvW,
							pVert->u32Colour
							);
		} /* end of if(bTexture == TRUE) */
	}
	kmxxReleaseCurrentPtr(&BufferDesc);
}

/****************************************************************************/
/**	kmtri_quads  by T.Hirata ************************************************/
/****************************************************************************/
void 
kmtri_quads (	KMVERTEXBUFFDESC	BufferDesc,
				KMVERTEXCONTEXT		VertexContext,
				int					nNumFaces,
				int					pFaces[][4],
				PSGLVERTEX			pVertices,
				int					bTexture)
{
	KMSTATUS	status;
	int			i;
	PSGLVERTEX	pVert;

	status = kmSetVertexRenderState(&VertexContext);
	Check_Status(status, "kmSetVertexRenderState");
	kmxxGetCurrentPtr(&BufferDesc);

	for(i = 0; i < nNumFaces; i++)
	{
		kmxxStartVertexStrip(&BufferDesc);
		if(bTexture == TRUE) {
			pVert = &pVertices[pFaces[i][0]];
			kmxxSetVertex_3(KM_VERTEXPARAM_NORMAL,
							pVert->fX,
							pVert->fY,
							pVert->fInvW,
							pVert->fUOverW,
							pVert->fVOverW,
							pVert->u32Colour,
							pVert->u32Specular
							);

			pVert = &pVertices[pFaces[i][1]];
			kmxxSetVertex_3(KM_VERTEXPARAM_NORMAL,
							pVert->fX,
							pVert->fY,
							pVert->fInvW,
							pVert->fUOverW,
							pVert->fVOverW,
							pVert->u32Colour,
							pVert->u32Specular
							);

			pVert = &pVertices[pFaces[i][3]];
			kmxxSetVertex_3(KM_VERTEXPARAM_NORMAL,
							pVert->fX,
							pVert->fY,
							pVert->fInvW,
							pVert->fUOverW,
							pVert->fVOverW,
							pVert->u32Colour,
							pVert->u32Specular
							);

			pVert = &pVertices[pFaces[i][2]];
			kmxxSetVertex_3(KM_VERTEXPARAM_ENDOFSTRIP,
							pVert->fX,
							pVert->fY,
							pVert->fInvW,
							pVert->fUOverW,
							pVert->fVOverW,
							pVert->u32Colour,
							pVert->u32Specular
							);
		}
		else {	/* if(bTexture == TRUE) : NO-TEXTURE */
			pVert = &pVertices[pFaces[i][0]];
			kmxxSetVertex_0(KM_VERTEXPARAM_NORMAL,
							pVert->fX,
							pVert->fY,
							pVert->fInvW,
							pVert->u32Colour
							);

			pVert = &pVertices[pFaces[i][1]];
			kmxxSetVertex_0(KM_VERTEXPARAM_NORMAL,
							pVert->fX,
							pVert->fY,
							pVert->fInvW,
							pVert->u32Colour
							);

			pVert = &pVertices[pFaces[i][3]];
			kmxxSetVertex_0(KM_VERTEXPARAM_NORMAL,
							pVert->fX,
							pVert->fY,
							pVert->fInvW,
							pVert->u32Colour
							);

			pVert = &pVertices[pFaces[i][2]];
			kmxxSetVertex_0(KM_VERTEXPARAM_ENDOFSTRIP,
							pVert->fX,
							pVert->fY,
							pVert->fInvW,
							pVert->u32Colour
							);
		} /* end of if(bTexture == TRUE) */
	}
	kmxxReleaseCurrentPtr(&BufferDesc);
}

/****************************************************************************/
/**	Initialize Vertex Context ***********************************************/
/****************************************************************************/
void	InitVertexContext(PKMVERTEXCONTEXT pVertexContext, PKMSURFACEDESC pTexture)
{

	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;

	/* for ParameterControlWord  */
	pVertexContext->ParamType			= KM_POLYGON;
	pVertexContext->ListType			= KM_OPAQUE_POLYGON;
	pVertexContext->ColorType			= KM_PACKEDCOLOR;
	pVertexContext->bUseSpecular		= FALSE;
	pVertexContext->UVFormat			= KM_32BITUV;

	/* for ISP/TSP InstructionWord  */
	pVertexContext->DepthMode			= KM_GREATER;
	pVertexContext->CullingMode			= KM_NOCULLING;
/*	pVertexContext->CullingMode			= KM_CULLSMALL; */
	pVertexContext->ScreenCoordination	= KM_SCREEN;
	pVertexContext->ShadingMode			= KM_TEXTUREGOURAUD;
	pVertexContext->SelectModifier		= KM_NOMODIFIER;
	pVertexContext->bZWriteDisable		= FALSE;			/* ARC1にはない */

	/* for TSP ControlWord  */
	pVertexContext->SRCBlendingMode		= KM_ONE;
	pVertexContext->DSTBlendingMode		= KM_ZERO;
	pVertexContext->bSRCSel				= FALSE;			/* ARC1にはない */
	pVertexContext->bDSTSel				= FALSE;			/* ARC1にはない */
	pVertexContext->FogMode				= KM_NOFOG;			/* 11はリザーブ */
	pVertexContext->bUseSpecular		= FALSE;
	pVertexContext->bUseAlpha			= FALSE;
	pVertexContext->FlipUV				= KM_NOFLIP;
	pVertexContext->ClampUV				= KM_NOCLAMP;
/*	pVertexContext->FilterMode			= KM_POINT_SAMPLE; */
	pVertexContext->FilterMode			= KM_BILINEAR;
	pVertexContext->bSuperSample		= FALSE;
	pVertexContext->MipMapAdjust		= 0x00000004;		/* D=1.00 */
	pVertexContext->TextureShadingMode	= KM_MODULATE;
/*	pVertexContext->TextureShadingMode	= KM_MODULATE_ALPHA; */
	
	/* for Texture ControlBit */
	pVertexContext->pTextureSurfaceDesc	= pTexture;

	/* 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	= 1.0f;		/* Specular Color Alpha */
	pVertexContext->fOffsetColorRed		= 1.0f;		/* Specular Color Red */
	pVertexContext->fOffsetColorGreen	= 1.0f;		/* Specular Color Green */
	pVertexContext->fOffsetColorBlue	= 1.0f;		/* Specular Color Blue */

	kmProcessVertexRenderState(pVertexContext);
}

/*-------------------------------------------------------------------------------------*/
/*                                       MAIN                                          */
/*-------------------------------------------------------------------------------------*/

NJS_PERIPHERAL *per;

int main (void)
{
int Control = 0, Device, Val = 0;

#if 0
    Device = sgl_create_screen_device (0, 640, 480, sgl_device_16bit, TRUE);
	if (Device<0) return -1;
#endif

	txt_ClearScreen();	/* Clear text screen */
	PRINTOUT(("** Blend : Blending mode test **\n"));

	/*----------------------------------------------------------------------------------- */
	/* Initialize Hardware */
#if NTSC
	sbInitSystem( NJD_RESOLUTION_640x480_NTSCNI, NJD_FRAMEBUFFER_MODE_RGB565, 1 );
#else
	sbInitSystem( NJD_RESOLUTION_VGA, NJD_FRAMEBUFFER_MODE_RGB565, 1 );
#endif

	kmGetVersionInfo(&VersionInfo);
	PRINTOUT(("MajorVersion      0x0%08x\n",VersionInfo.kmMajorVersion));
	PRINTOUT(("LocalVersion      0x0%08x\n",VersionInfo.kmLocalVersion));
	PRINTOUT(("kmFrameBufferSize 0x0%08x\n",VersionInfo.kmFrameBufferSize));


	/*----------------------------------------------------------------------------------- */
	/* Create frame buffer and vertex buffer */

	pFB[0] = &PrimarySurfaceDesc;
	pFB[1] = &BackSurfaceDesc;

	/* VertexBufferPointer(set5) */
	dwDataPtr = (PKMDWORD)0xACB00000;

	SystemConfig.dwSize	=	sizeof(KMSYSTEMCONFIGSTRUCT);
	SystemConfig.flags	=	KM_CONFIGFLAG_ENABLE_CLEAR_FRAMEBUFFER;

	/* for Frame buffer */
	SystemConfig.ppSurfaceDescArray	=	pFB;	/* Array of SurfaceDesc	pointer     */
	SystemConfig.nNumOfFrameBuffer	=	2;		/* Number Of Frame Buffer			*/
	SystemConfig.nWidth				=	0;		/* Width of Frame buffer			*/
	SystemConfig.nHeight			=	0;		/* Height of Frame buffer			*/
	SystemConfig.nBpp				=	0;		/* Bit Per Depth for Frame buffer	*/
	/* for Texture Memory */
	SystemConfig.nTextureMemorySize	=	262144 * 2;	/* Texture Memory size : 1MB * 2 */
	/* for Vertex buffer */
	SystemConfig.pBufferDesc		=	&VertexBufferDesc;	/* pointer to VERTEXBUFFDESC 		*/
	SystemConfig.pVertexBuffer		=	dwDataPtr;			/* pointer to Vertex buffer 		*/
	SystemConfig.nVertexBufferSize	=	262144 * 2;	/* size of Vertex buffer : 1MB * 2 */
	SystemConfig.fBufferSize[0]		=	50.0f;		/* Opaque polygon buffer size        : 35% */
	SystemConfig.fBufferSize[1]		=	 0.0f;		/* Opaque modifier buffer size       :  0% */
	SystemConfig.fBufferSize[2]		=	50.0f;		/* Trans polygon buffer size         : 30% */
	SystemConfig.fBufferSize[3]		=	 0.0f;		/* Trans modifier buffer size        :  0% */
	SystemConfig.fBufferSize[4]		=	 0.0f;		/* Punchthrough polygon buffer size  : 35% */

	SystemConfig.nVbufModel			=	 KM_VERTEXBUFMODEL_NORMAL;	/* VertexBuffer Model		*/
	status = kmSetSystemConfiguration( &SystemConfig );
	Check_Status(status, "kmSetSystemConfiguration");

	/*-----------------------------------------------------------------------------------*/
	/* Initialize DisplayString routine */
	txt_InitDisplayString();

	/*----------------------------------------------------------------------------------- */
	/* some initializes */
	SetTextures ();
	SetBackground (&TexBack);
	SetContext();


    DisplayInformation ();
    NextFrame ();

   	while (TRUE)
	{
#if defined(_X86_)
	   while(!kbhit())  NextFrame ();
	   Val = _getch ();

	   switch (Val)
	   {

			case K_ESC:
				 goto Finish;

			case K_SPC:
				while(!kbhit());
				break;

			case K_UP:
				 if(PosZ>0) PosZ-=10;
				 DisplayInformation ();
				 break;
			case K_DOWN:
				 PosZ+=10;
				 DisplayInformation ();
				 break;

   			case K_F1 :
			     BlendSrc++; if (BlendSrc==8) BlendSrc=0;
				 DisplayInformation ();
				 break;

            case K_F2 :
			     BlendDst++; if (BlendDst==8) BlendDst=0;
				 DisplayInformation ();
				 break;

			case K_F3 :
				 AlphaSource++; if (AlphaSource==3) AlphaSource=0;
				 Info.VertexAlpha = (AlphaSource==1) ? 1:0;
				 DisplayInformation ();
				 break;

			case K_F4 :
				 BlendModulate = !BlendModulate;
				 DisplayInformation ();
				 break;

	   }
	   Val = 0;
	   NextFrame ();
#else	/* not _X86_ */
		ReadMaple ();
		NextFrame ();
#endif
	}


Finish:
/*	FreeAllBMPTextures	(); */
/*	sgl_delete_device	(Device); */
    return 0;
}
/*----------------------------------------------------------------------*/
/*  Function Name   : ReadMaple                                         */
/*  Inputs          :                                                   */
/*  Outputs         :                                                   */
/*  Returns         :                                                   */
/*  Globals Used    : PosZ, BlendSrc, BlendDst, AlphaSource,            */
/*                    BlendModulate                                     */
/*  Description     : Read MAPLE status                                 */
/*----------------------------------------------------------------------*/
void ReadMaple (void)
{
	static	int	swadelay = 0;	/* flag for cancel chattering of A button */
	static	int	swbdelay = 0;	/* flag for cancel chattering of B button */
	static	int	swxdelay = 0;	/* flag for cancel chattering of X button */
	static	int	swydelay = 0;	/* flag for cancel chattering of Y button */

	txt_SetCursor(0,16);

	per = (NJS_PERIPHERAL *) njGetPeripheral(NJD_PORT_A0);

	if ( per->on ) {
		PRINTOUT(("MAPLE DATA : %08X \n",per->on));

		/* UP cross key */
		if ( per->on & NJD_DGT_KU ){
				 if(PosZ>0) PosZ-=10;
				 DisplayInformation ();
		}
		/* DOWN cross key */
		if ( per->on & NJD_DGT_KD ){
				 PosZ+=10;
				 DisplayInformation ();
		}

		/* A button */
		if ( swadelay == 0 ) {
			if ( per->on & NJD_DGT_TA ){
				BlendSrc++; if (BlendSrc==8) BlendSrc=0;
				DisplayInformation ();
				swadelay = 1;
			}
		} else {
			if ( per->off & NJD_DGT_TA ){
				swadelay = 0;
			}
		}

		/* B button */
		if ( swbdelay == 0 ) {
			if ( per->on & NJD_DGT_TB ){
				BlendDst++; if (BlendDst==8) BlendDst=0;
				DisplayInformation ();
				swbdelay = 1;
			}
		} else {
			if ( per->off & NJD_DGT_TB ){
				swbdelay = 0;
			}
		}

		/* X button */
		if ( swxdelay == 0 ) {
			if ( per->on & NJD_DGT_TX ){
				AlphaSource++; if (AlphaSource==3) AlphaSource=0;
				Info.VertexAlpha = (AlphaSource==1) ? 1:0;
				DisplayInformation ();
				swxdelay = 1;
			}
		} else {
			if ( per->off & NJD_DGT_TX ){
				swxdelay = 0;
			}
		}

		/* Y button */
		if ( swydelay == 0 ) {
			if ( per->on & NJD_DGT_TY ){
				BlendModulate = !BlendModulate;
				DisplayInformation ();
				swydelay = 1;
			}
		} else {
			if ( per->off & NJD_DGT_TY ){
				swydelay = 0;
			}
		}

	}	/* end of if ( per->on ) */
	 else {
		PRINTOUT(("MAPLE : NO-INPUT\n"));
	}

}

/*----------------------------------------------------------------------*/
/*  Function Name   : SetContext                                        */
/*  Inputs          :                                                   */
/*  Outputs         :                                                   */
/*  Returns         :                                                   */
/*  Globals Used    : SGLContex SGLContext2                             */
/*  Description     : Sets SGLContext and SGLContext2                   */
/*----------------------------------------------------------------------*/
void SetContext (void)
{
#if 0
	SGLContext2.u32Flags			= 0;
	SGLContext2.n32DeviceName		= 0;
	SGLContext2.u32BlendCntl		= 0;
	SGLContext2.eDepthCntl			= sgl_zcomp_lessequal;
	SGLContext2.fShadowScaling		= 0.0f;
	SGLContext2.fVertexFogR			= 1.0f;
	SGLContext2.fVertexFogG			= 1.0f;
	SGLContext2.fVertexFogB			= 1.0f;

	SGLContext.pSGLContext2			= &SGLContext2;

    SGLContext.bFogOn               = FALSE;
	SGLContext.bCullBackfacing      = FALSE;
    SGLContext.bDoClipping          = TRUE;
    SGLContext.cBackgroundColour[0] = 0.0f;
	SGLContext.cBackgroundColour[1] = 0.0f;
	SGLContext.cBackgroundColour[2] = 0.0f;
	SGLContext.eShadowLightVolMode  = NO_SHADOWS_OR_LIGHTVOLS;
	SGLContext.bFlipU               = TRUE;
	SGLContext.bFlipV               = TRUE;
    SGLContext.bDoUVTimesInvW       = TRUE;
	SGLContext.RenderRegions        = 0;
    SGLContext.n32MipmapOffset      = 0;
    SGLContext.u32GlobalTrans       = 0x000000;
    SGLContext.eFilterType          = sgl_tf_bilinear;

    SGLContext.u32Flags =  SGLTT_TEXTURE | SGLTT_GOURAUD | SGLTT_DIRECT_EXTENSIONS;
#endif

	/*-------------------------------------------------------------------------------- */
	/* Initialize Vertex Context */
	/*-------------------------------------------------------------------------------- */

	/* Gold */
	memset( &VertexContextGold, 0, sizeof(VertexContextGold));	/* Crear Context */
	InitVertexContext(&VertexContextGold,&TexGold);				/* Initialize context */

	/* Opaq / Trans */
	memset( &VertexContextTrans, 0, sizeof(VertexContextTrans));	/* Crear Context */
	InitVertexContext(&VertexContextTrans,&TexOpaq);				/* Initialize context */
}

/*----------------------------------------------------------------------*/
/*  Function Name   : SetTextures                                       */
/*  Inputs          :                                                   */
/*  Outputs         :                                                   */
/*  Returns         :                                                   */
/*  Globals Used    : TexOpaq TexTrans TexGold Texback                  */
/*  Description     : Loads BMP files                                   */
/*----------------------------------------------------------------------*/
void SetTextures (void)
{
#if 0
	TexOpaq  =  LoadBMPTexture ("forgrnd.bmp",  FALSE, FALSE, FALSE);
	TexTrans =  LoadBMPTexture ("forgrnd.bmp",  TRUE,  FALSE, FALSE);
	/*TexGold  =  LoadBMPTexture ("Gold.bmp",     FALSE, FALSE, FALSE); */
	/*TexBack  =  LoadBMPTexture ("backgrnd.bmp", FALSE, FALSE, FALSE); */

	TexGold  =  LoadVQTexture ("Gold.vqf");
	TexBack  =  LoadVQTexture ("backgrnd.vqf");
#endif

	PKMDWORD			pTexture01;				/* Pointer to texture */
	KMTEXTURETYPE		nTextureType;			/* texture type definition */

	/*----------------------------------------------------------------------------------- */
	/* Create texture surface */
	nTextureType = KM_TEXTURE_TWIDDLED | KM_TEXTURE_RGB565;	/* Set texture type */
	status = kmCreateTextureSurface(
		&TexOpaq,				/* OUT	PKMSURFACEDESC	pSurfaceDesc */
		256,					/*	IN	KMINT32			nWidth  */
		256,					/*	IN	KMINT32			nHeight  */
		nTextureType			/*	IN	KMTEXTURETYPE	nTextureType */
	);
	Check_Status(status, "kmCreateTextureSurface #1");
	/*----------------------------------------------------------------------------------- */
	/* Create texture surface */
	nTextureType = KM_TEXTURE_TWIDDLED | KM_TEXTURE_ARGB4444;	/* Set texture type */
	status = kmCreateTextureSurface(
		&TexTrans,				/* OUT	PKMSURFACEDESC	pSurfaceDesc */
		256,					/*	IN	KMINT32			nWidth  */
		256,					/*	IN	KMINT32			nHeight  */
		nTextureType			/*	IN	KMTEXTURETYPE	nTextureType */
	);
	Check_Status(status, "kmCreateTextureSurface #2");
	/*----------------------------------------------------------------------------------- */
	/* Create texture surface */
	nTextureType = KM_TEXTURE_TWIDDLED | KM_TEXTURE_RGB565;	/* Set texture type */
	status = kmCreateTextureSurface(
		&TexBack,				/* OUT	PKMSURFACEDESC	pSurfaceDesc */
		256,					/*	IN	KMINT32			nWidth  */
		256,					/*	IN	KMINT32			nHeight  */
		nTextureType			/*	IN	KMTEXTURETYPE	nTextureType */
	);
	Check_Status(status, "kmCreateTextureSurface #3");
	/*----------------------------------------------------------------------------------- */
	/* Create texture surface */
	nTextureType = KM_TEXTURE_TWIDDLED | KM_TEXTURE_RGB565;	/* Set texture type */
	status = kmCreateTextureSurface(
		&TexGold,				/* OUT	PKMSURFACEDESC	pSurfaceDesc */
		128,					/*	IN	KMINT32			nWidth  */
		128,					/*	IN	KMINT32			nHeight  */
		nTextureType			/*	IN	KMTEXTURETYPE	nTextureType */
	);
	Check_Status(status, "kmCreateTextureSurface #4");
	/*----------------------------------------------------------------------------------- */
	/* Load and set texture */
	pTexture01 = (unsigned long *)&Opaq;
	status = kmLoadTexture(&TexOpaq,			/* PKMSURFACEDESC pSurfaceDesc */
							pTexture01 + (16 / sizeof(KMDWORD)),			/* PKMDWORD pTexture */
							FALSE,				/* KMBOOLEAN bAutoMipMap */
							FALSE				/* KMBOOLEAN bDither */
							);
	Check_Status(status, "kmLoadTexture #1");
	/*----------------------------------------------------------------------------------- */
	/* Load and set texture */
	pTexture01 = (unsigned long *)&Trans;
	status = kmLoadTexture(&TexTrans,			/* PKMSURFACEDESC pSurfaceDesc */
							pTexture01 + (16 / sizeof(KMDWORD)),			/* PKMDWORD pTexture */
							FALSE,				/* KMBOOLEAN bAutoMipMap */
							FALSE				/* KMBOOLEAN bDither */
							);
	Check_Status(status, "kmLoadTexture #2");
	/*----------------------------------------------------------------------------------- */
	/* Load and set texture */
	pTexture01 = (unsigned long *)&Back;
	status = kmLoadTexture(&TexBack,			/* PKMSURFACEDESC pSurfaceDesc */
							pTexture01 + (16 / sizeof(KMDWORD)),			/* PKMDWORD pTexture */
							FALSE,				/* KMBOOLEAN bAutoMipMap */
							FALSE				/* KMBOOLEAN bDither */
							);
	Check_Status(status, "kmLoadTexture #3");
	/*----------------------------------------------------------------------------------- */
	/* Load and set texture */
	pTexture01 = (unsigned long *)&Gold;
	status = kmLoadTexture(&TexGold,			/* PKMSURFACEDESC pSurfaceDesc */
							pTexture01 + (16 / sizeof(KMDWORD)),			/* PKMDWORD pTexture */
							FALSE,				/* KMBOOLEAN bAutoMipMap */
							FALSE				/* KMBOOLEAN bDither */
							);
	Check_Status(status, "kmLoadTexture #4");

}

/*----------------------------------------------------------------------*/
/*  Function Name   : NextFrame                                         */
/*  Inputs          :                                                   */
/*  Outputs         :                                                   */
/*  Returns         :                                                   */
/*  Globals Used    : SGLContext SGLContext2 Info                       */
/*  Description     : Render a scene.                                   */
/*----------------------------------------------------------------------*/
void NextFrame (void)
{

/*    sgltri_startofframe (&SGLContext); */
/*		SetContext(); */
/*		SetBackground (&TexBack); */

/*		SGLContext.nTextureName  = TexGold; */
		SetPlane  (2,VertexContextGold);


#if 0
        if (Info.VertexAlpha)   SGLContext.u32Flags |=	SGLTT_VERTEXTRANS; 
		SGLContext.nTextureName  = (AlphaSource>0) ? TexOpaq : TexTrans ;

		/*
		 *  Blend settings... (SGLContex2)
		 */
		SGLContext2.u32Flags		= SGLTT2_BLENDCNTL | SGLTT2_TEXTUREBLEND;
		SGLContext2.eTextureBlend	= (BlendModulate) ? sgl_stb_texascale : sgl_stb_nominal;
        
  		SGLContext2.u32BlendCntl	= sgl_blend_cntl( BlendSrc,  BlendDst,  sgl_accum2_notused );

		SetPlane  (1);
#endif
	/* Clear render state */
	VertexContextTrans.RenderState	= 0;

	if(AlphaSource > 0) {	/* Texture Opaque */
		VertexContextTrans.pTextureSurfaceDesc	= &TexOpaq;
		if (Info.VertexAlpha == TRUE) {	/* use vertex alpha */
			/* LISTTYPE */
			VertexContextTrans.RenderState	|= KM_LISTTYPE;
			VertexContextTrans.ListType	= KM_TRANS_POLYGON;
			/* USEALPHA */
			VertexContextTrans.RenderState	|= KM_USEALPHA;
			VertexContextTrans.bUseAlpha = TRUE;
			if(BlendModulate == TRUE) {
				VertexContextTrans.RenderState	|= KM_TEXTURESHADINGMODE;
				VertexContextTrans.TextureShadingMode	= KM_MODULATE_ALPHA;
			}
			else {
				VertexContextTrans.RenderState	|= KM_TEXTURESHADINGMODE;
				VertexContextTrans.TextureShadingMode	= KM_DECAL_ALPHA;
			}
		}
		else{	/* not use vertex alpha */
			/* LISTTYPE */
			VertexContextTrans.RenderState	|= KM_LISTTYPE;
			VertexContextTrans.ListType	= KM_OPAQUE_POLYGON;
			/* USEALPHA */
			VertexContextTrans.RenderState	|= KM_USEALPHA;
			VertexContextTrans.bUseAlpha = FALSE;
			if(BlendModulate == 1) {
				VertexContextTrans.RenderState	|= KM_TEXTURESHADINGMODE;
				VertexContextTrans.TextureShadingMode	= KM_MODULATE;
			}
			else {
				VertexContextTrans.RenderState	|= KM_TEXTURESHADINGMODE;
				VertexContextTrans.TextureShadingMode	= KM_DECAL;
			}
		}
	}
	else {	/* Texture Trans */
		VertexContextTrans.pTextureSurfaceDesc	= &TexTrans;
		/* LISTTYPE */
		VertexContextTrans.RenderState	|= KM_LISTTYPE;
		VertexContextTrans.ListType	= KM_TRANS_POLYGON;
		/* USEALPHA */
		VertexContextTrans.RenderState	|= KM_USEALPHA;
		VertexContextTrans.bUseAlpha = TRUE;
		if(BlendModulate == TRUE) {
			VertexContextTrans.RenderState	|= KM_TEXTURESHADINGMODE;
			VertexContextTrans.TextureShadingMode	= KM_MODULATE_ALPHA;
		}
		else {
			VertexContextTrans.RenderState	|= KM_TEXTURESHADINGMODE;
			VertexContextTrans.TextureShadingMode	= KM_DECAL_ALPHA;
		}
	}

	/*********************/
	/* Set blending mode */
	/*********************/
	if((BlendSrc == 5)&&(BlendDst == 5)) {	/* Both INVSRCALPHA */
		VertexContextTrans.RenderState	|= KM_SRCBLENDINGMODE;
		VertexContextTrans.SRCBlendingMode	= KM_BOTHINVSRCALPHA;
		VertexContextTrans.RenderState	|= KM_DSTBLENDINGMODE;
		VertexContextTrans.DSTBlendingMode	= KM_BOTHINVSRCALPHA;
	}
	else if((BlendSrc == 4)&&(BlendDst == 4)) {	/* Both SRCALPHA */
		VertexContextTrans.RenderState	|= KM_SRCBLENDINGMODE;
		VertexContextTrans.SRCBlendingMode	= KM_BOTHSRCALPHA;
		VertexContextTrans.RenderState	|= KM_DSTBLENDINGMODE;
		VertexContextTrans.DSTBlendingMode	= KM_BOTHSRCALPHA;
	}
	else {
		/* SRC blending mode */
		switch(BlendSrc) {
			default:
			case 0 :	/* ZERO */
				VertexContextTrans.RenderState	|= KM_SRCBLENDINGMODE;
				VertexContextTrans.SRCBlendingMode	= KM_ZERO;
				break;
			case 1 :	/* ONE */
				VertexContextTrans.RenderState	|= KM_SRCBLENDINGMODE;
				VertexContextTrans.SRCBlendingMode	= KM_ONE;
				break;
			case 2 :	/* OTHER */
				VertexContextTrans.RenderState	|= KM_SRCBLENDINGMODE;
				VertexContextTrans.SRCBlendingMode	= KM_DESTCOLOR;
				break;
			case 3 :	/* INVOTHER */
				VertexContextTrans.RenderState	|= KM_SRCBLENDINGMODE;
				VertexContextTrans.SRCBlendingMode	= KM_INVDESTCOLOR;
				break;
			case 4 :	/* SRCA */
				VertexContextTrans.RenderState	|= KM_SRCBLENDINGMODE;
				VertexContextTrans.SRCBlendingMode	= KM_SRCALPHA;
				break;
			case 5 :	/* INVSRCA */
				VertexContextTrans.RenderState	|= KM_SRCBLENDINGMODE;
				VertexContextTrans.SRCBlendingMode	= KM_INVSRCALPHA;
				break;
			case 6 :	/* DSTA */
				VertexContextTrans.RenderState	|= KM_SRCBLENDINGMODE;
				VertexContextTrans.SRCBlendingMode	= KM_DESTALPHA;
				break;
			case 7 :	/* INVDSTA */
				VertexContextTrans.RenderState	|= KM_SRCBLENDINGMODE;
				VertexContextTrans.SRCBlendingMode	= KM_INVDESTALPHA;
				break;
		}
		/* DEST blending mode */
		switch(BlendDst) {
			default:
			case 0 :	/* ZERO */
				VertexContextTrans.RenderState	|= KM_DSTBLENDINGMODE;
				VertexContextTrans.DSTBlendingMode	= KM_ZERO;
				break;
			case 1 :	/* ONE */
				VertexContextTrans.RenderState	|= KM_DSTBLENDINGMODE;
				VertexContextTrans.DSTBlendingMode	= KM_ONE;
				break;
			case 2 :	/* OTHER */
				VertexContextTrans.RenderState	|= KM_DSTBLENDINGMODE;
				VertexContextTrans.DSTBlendingMode	= KM_SRCCOLOR;
				break;
			case 3 :	/* INVOTHER */
				VertexContextTrans.RenderState	|= KM_DSTBLENDINGMODE;
				VertexContextTrans.DSTBlendingMode	= KM_INVSRCCOLOR;
				break;
			case 4 :	/* SRCA */
				VertexContextTrans.RenderState	|= KM_DSTBLENDINGMODE;
				VertexContextTrans.DSTBlendingMode	= KM_SRCALPHA;
				break;
			case 5 :	/* INVSRCA */
				VertexContextTrans.RenderState	|= KM_DSTBLENDINGMODE;
				VertexContextTrans.DSTBlendingMode	= KM_INVSRCALPHA;
				break;
			case 6 :	/* DSTA */
				VertexContextTrans.RenderState	|= KM_DSTBLENDINGMODE;
				VertexContextTrans.DSTBlendingMode	= KM_DESTALPHA;
				break;
			case 7 :	/* INVDSTA */
				VertexContextTrans.RenderState	|= KM_DSTBLENDINGMODE;
				VertexContextTrans.DSTBlendingMode	= KM_INVDESTALPHA;
				break;
		}
	}

	/* Process VertexContext */
	status = kmProcessVertexRenderState(&VertexContextTrans);
	Check_Status(status, "kmProcessVertexRenderState");

	SetPlane  (1, VertexContextTrans);

	/*-----------------------------------------------------------------------------------*/
	/* Rendering start */
/*	sgltri_render   (&SGLContext); */
#if defined(_DISPLAY_STRING_)
	txt_DispScreen(VertexBufferDesc);		/* Display screen */
#endif
	status = kmRender();
	Check_Status(status, "kmRender");

	/*----------------------------------------------------------------------------------- */
	/* Flip screen */
	status = kmFlipFrameBuffer();
	Check_Status(status, "kmFlipFrameBuffer");

	pdExecPeripheralServer();

	Frame++;
}
/*----------------------------------------------------------------------*/
/*  Function Name   : DisplayInformation                                */
/*  Inputs          :                                                   */
/*  Outputs         :                                                   */
/*  Returns         :                                                   */
/*  Globals Used    : BlendScr BlendDst AlphaSource BlendShd            */
/*  Description     : Displays some information.                        */
/*----------------------------------------------------------------------*/
void DisplayInformation (void)
{
char *Flag[]     = { "FROM BMP", "FROM VERTEXALPHA", "ZERO"};
char *BlendStr[] = {"ZERO","ONE","OTHER","INVOTHER","SRCA","INVSCRA","DSTA","INVDSTA"};
char *Shade[]    = {"DECAL","MODULATE"};

	txt_SetCursor(0,17);

	PRINTOUT(( " A(F1) : Source        %s\n", BlendStr[BlendSrc]));
	PRINTOUT(( " B(F2) : Destination   %s\n", BlendStr[BlendDst]));
	PRINTOUT(( " X(F3) : Alpha Info    %s\n", Flag[AlphaSource]));
	PRINTOUT(( " Y(F4) : Blend         %s\n", Shade[BlendModulate]));

}

/*----------------------------------------------------------------------*/
/*  Function Name   : SetPlane                                          */
/*  Inputs          :                                                   */
/*  Outputs         :                                                   */
/*  Returns         :                                                   */
/*  Globals Used    :                                                   */
/*  Description     : Draws an square a rotates it                      */
/*----------------------------------------------------------------------*/
void SetPlane (int Num, KMVERTEXCONTEXT VertexContext )
{
SGLVERTEX  Vert[4];
int Tri1[] = {0,1,2,3}, i;
float Temp, CamZ, CamF, CosA, SinA, Ang;
sgl_vector	Pnt[4]	=   {	{-128.0f, -128.0f, 0.0f},
							{ 128.0f, -128.0f, 0.0f},
							{ 128.0f,  128.0f, 0.0f},
							{-128.0f,  128.0f, 0.0f}};

    if (Num==2) Ang = Frame/300.0f;
	else        Ang = -(Frame/300.0f);

    CosA = cos(Ang); SinA = sin (Ang);

    for (i=0; i<4; i++){
            Temp      = Pnt[i][0] * CosA - Pnt[i][1] * SinA;
            Pnt[i][1] = Pnt[i][1] * CosA + Pnt[i][0] * SinA;
		    Pnt[i][0] = Temp;

	        CamZ = 1.0/ (float)(PosZ+Num);
			CamF = 800.0f * CamZ;

    	    Vert[i].fX    =  CamF * Pnt[i][0] + 320 ;
            Vert[i].fY    = -CamF * Pnt[i][1] + 240 ;
		    Vert[i].fInvW =  CamZ;
	}

	Vert[0].u32Colour  = RGBAColour (255,255,255, 255); 
	Vert[1].u32Colour  = RGBAColour (255,255,255, 0);   
	Vert[2].u32Colour  = RGBAColour (255,255,255, 0);   
	Vert[3].u32Colour  = RGBAColour (255,255,255, 255); 

	Vert[2].fUOverW=1.0f;   Vert[2].fVOverW=1.0f;
	Vert[3].fUOverW=0.0f;   Vert[3].fVOverW=1.0f;
	Vert[1].fUOverW=1.0f;   Vert[1].fVOverW=0.0f;
	Vert[0].fUOverW=0.0f;   Vert[0].fVOverW=0.0f;

/*	sgltri_quads (&SGLContext, 1, (int (*)[4])Tri1, Vert); */
	kmtri_quads (	VertexBufferDesc,	/* KMVERTEXBUFFDESC	BufferDesc, */
					VertexContext,		/* KMVERTEXCONTEXT		VertexContext, */
					1,					/* int  nNumFaces, */
					(int (*)[4])Tri1,	/* int  pFaces[][3], */
					Vert,				/* PSGLVERTEX  pVertices */
					TRUE				/* int	bTexture */
					);

}
/*----------------------------------------------------------------------*/
/*  Function Name   : SetBackground                                     */
/*  Inputs          : TextureID                                         */
/*  Outputs         :                                                   */
/*  Returns         :                                                   */
/*  Globals Used    : SGLContex                                         */
/*  Description     : Sets the background                               */
/*----------------------------------------------------------------------*/
#define BILINEAR_CORRECTION 1.0f/256.0f

void SetBackground (PKMSURFACEDESC TextureID)
{
#if 0
SGLVERTEX2 Plane[3];

     Plane[0].fX		= 0.0f;
	 Plane[0].fY		= 0.0f;
	 Plane[0].fInvW		= 0.000001f;
	 Plane[0].u32Colour = RGBAColour (255, 255, 255, 255);
	 Plane[0].fU   = 0.0f + BILINEAR_CORRECTION;
     Plane[0].fV  = 2.0f - BILINEAR_CORRECTION;


	 Plane[1].fX		= 640.0f;
	 Plane[1].fY		= 0.0f;
	 Plane[1].fInvW		= 0.000001f;
	 Plane[1].u32Colour = RGBAColour (255, 255, 255, 255);
	 Plane[1].fU   = 2.0f - BILINEAR_CORRECTION;
     Plane[1].fV   = 2.0f - BILINEAR_CORRECTION;

	 Plane[2].fX		= 640.0f;
	 Plane[2].fY		= 480.0f;
	 Plane[2].fInvW		= 0.000001f;
	 Plane[2].u32Colour = RGBAColour (255, 255, 255, 255);
	 Plane[2].fU   = 2.0f - BILINEAR_CORRECTION;
     Plane[2].fV   = 0.0f + BILINEAR_CORRECTION;

	 SGLContext.nTextureName =  TextureID;

	 /*	
	  *  sgltri_set_background uses the new SGLVERTEX2 format 
	  */
	 sgltri_set_background (&SGLContext, Plane, 1/10000.0f);
#endif

	KMSTATUS			status;
	KMVERTEXCONTEXT		BackVertexContext;		/* Vertex context */
	KMVERTEX_01			BV01[3];				/* for NO-TEXTURE-GOURAUD */
	KMVERTEX_03			BV03[3];				/* for TEXTURE-GOURAUD */
	PVOID				pBV[3];					/* pointer to Vertex */

	/* Clear VertexContext */
	memset(&BackVertexContext,0,sizeof(KMVERTEXCONTEXT));

	/* Setup VertexContext */
	BackVertexContext.RenderState	= KM_DEPTHMODE  		| KM_CULLINGMODE				/* ISP/TSP IW */
									| KM_SCREENCOORDINATION	| KM_SHADINGMODE
									| KM_MODIFIER 			| KM_ZWRITEDISABLE				/* TSP CW */
									| KM_SRCBLENDINGMODE
									| 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 					/* Param CW */
									| KM_COLORTYPE			| KM_USESPECULAR
									| KM_UVFORMAT;

	/* for ParameterControlWord  */
	BackVertexContext.ParamType				= KM_POLYGON;
	BackVertexContext.ListType				= KM_OPAQUE_POLYGON;
	BackVertexContext.bUseSpecular			= FALSE;
	BackVertexContext.UVFormat				= KM_32BITUV;

	/* for ISP/TSP InstructionWord  */
	BackVertexContext.DepthMode				= KM_GREATER;
	BackVertexContext.CullingMode			= KM_NOCULLING;
	BackVertexContext.ScreenCoordination	= KM_SCREEN;
	BackVertexContext.SelectModifier		= KM_NOMODIFIER;
	BackVertexContext.bZWriteDisable		= FALSE;			/* not effective on ARC1 */

	/* for TSP ControlWord  */
	BackVertexContext.SRCBlendingMode		= KM_ONE;
/*	BackVertexContext.DSTBlendingMode		= KM_ZERO;	// must not set this parameter on background plane */
	BackVertexContext.bSRCSel				= FALSE;			/* not effective on ARC1 */
	BackVertexContext.bDSTSel				= FALSE;			/* not effective on ARC1 */
	BackVertexContext.FogMode				= KM_NOFOG;

	BackVertexContext.bUseSpecular			= FALSE;
	BackVertexContext.bUseAlpha				= FALSE;
	BackVertexContext.ClampUV				= KM_NOCLAMP;
	BackVertexContext.FilterMode			= KM_BILINEAR;
	BackVertexContext.bSuperSample			= FALSE;
	BackVertexContext.MipMapAdjust			= 0x00000004;		/* D=1.00 */
	BackVertexContext.TextureShadingMode	= KM_MODULATE;
	
	/* for Texture ControlBit */

	/* No effect on ARC1 */
	BackVertexContext.bColorClamp			= FALSE;
	BackVertexContext.PaletteBank			= 0;

	/* for GlobalColorData */
	BackVertexContext.fFaceColorAlpha		= 1.0f;		/* Face Color Alpha */
	BackVertexContext.fFaceColorRed			= 1.0f;		/* Face Color Red */
	BackVertexContext.fFaceColorGreen		= 1.0f;		/* Face Color Green */
	BackVertexContext.fFaceColorBlue		= 1.0f;		/* Face Color Blue */
	BackVertexContext.fOffsetColorAlpha		= 1.0f;		/* Specular Color Alpha */
	BackVertexContext.fOffsetColorRed		= 1.0f;		/* Specular Color Red */
	BackVertexContext.fOffsetColorGreen		= 1.0f;		/* Specular Color Green */
	BackVertexContext.fOffsetColorBlue		= 1.0f;		/* Specular Color Blue */

	if(TextureID == (PKMSURFACEDESC)NULL) {	/* No texture */
		BackVertexContext.ColorType				= KM_FLOATINGCOLOR;
		BackVertexContext.ShadingMode			= KM_NOTEXTUREGOURAUD;
	}
	else {					/* Use texture */
		BackVertexContext.ColorType				= KM_PACKEDCOLOR;
		BackVertexContext.ShadingMode			= KM_TEXTUREGOURAUD;
		BackVertexContext.pTextureSurfaceDesc	= TextureID;
	}

	status = kmProcessVertexRenderState(&BackVertexContext);
	Check_Status(status, "kmProcessVertexRenderState");
	status = kmSetBackGroundRenderState(&BackVertexContext);
	Check_Status(status, "kmSetBackGroundRenderState");

	/*----------------------------------------------------------------------------------- */
	/* set VERTEX DATA */

	if(TextureID == (PKMSURFACEDESC)NULL) {	/* No texture */
		/* Vertex #1 */
		BV01[0].ParamControlWord	= KM_VERTEXPARAM_NORMAL;
		BV01[0].fX				=   0.0f;
		BV01[0].fY				= 479.0f;
#if defined(_STRICT_UNION_)
		BV01[0].u.fZ			=  0.0001f;
#else
		BV01[0].fZ				=  0.0001f;
#endif
		BV01[0].fBaseAlpha		=   0.0f;
		BV01[0].fBaseRed		=   0.55f;
		BV01[0].fBaseGreen		=   0.87f;
		BV01[0].fBaseBlue		=   0.96f;

		/* Vertex #2 */
		BV01[1].ParamControlWord	= KM_VERTEXPARAM_NORMAL;
		BV01[1].fX				= 320.0f;
		BV01[1].fY				=   0.0f;
#if defined(_STRICT_UNION_)
		BV01[1].u.fZ			=  0.0001f;
#else
		BV01[1].fZ				=  0.0001f;
#endif
		BV01[1].fBaseAlpha		=   0.0f;
		BV01[1].fBaseRed		=   0.0f;
		BV01[1].fBaseGreen		=   0.15f;
		BV01[1].fBaseBlue		=   0.73f;

		/* Vertex #3 */
		BV01[2].ParamControlWord	= KM_VERTEXPARAM_ENDOFSTRIP;
		BV01[2].fX				= 639.0f;
		BV01[2].fY				= 479.0f;
#if defined(_STRICT_UNION_)
		BV01[2].u.fZ			=  0.0001f;
#else
		BV01[2].fZ				=  0.0001f;
#endif
		BV01[2].fBaseAlpha		=   0.0f;
		BV01[2].fBaseRed		=   0.55f;
		BV01[2].fBaseGreen		=   0.87f;
		BV01[2].fBaseBlue		=   0.96f;

		pBV[0] = &BV01[0];
		pBV[1] = &BV01[1];
		pBV[2] = &BV01[2];

		/* set VERTEX */
		status = kmSetBackGroundPlane(	pBV,					/* pVertex */
										KM_VERTEXTYPE_01,		/* VertexType */
										sizeof(KMVERTEX_01)		/* StructSize */
										);
		Check_Status(status, "kmSetBackGroundPlane");
	}
	else {		/* Use texture */
		/* Vertex #1 */
		BV03[0].ParamControlWord	= KM_VERTEXPARAM_NORMAL;
		BV03[0].fX					=  0.0f;
		BV03[0].fY					=  0.0f;
#if defined(_STRICT_UNION_)
		BV03[0].u.fZ				=  0.0001f;
#else
		BV03[0].fZ					=  0.0001f;
#endif
		BV03[0].fU					=  0.0f;
		BV03[0].fV					=  1.0f;
		BV03[0].uBaseRGB.dwPacked	=  RGBAColour (255, 255, 255, 255);
		BV03[0].uOffsetRGB.dwPacked	=  RGBAColour (255, 255, 255, 255);

		/* Vertex #2 */
		BV03[1].ParamControlWord	= KM_VERTEXPARAM_NORMAL;
		BV03[1].fX					= 640.0f;
		BV03[1].fY					=   0.0f;
#if defined(_STRICT_UNION_)
		BV03[1].u.fZ				=  0.0001f;
#else
		BV03[1].fZ					=  0.0001f;
#endif
		BV03[1].fU					= 1.0f;
		BV03[1].fV					= 1.0f;
		BV03[1].uBaseRGB.dwPacked	= RGBAColour (255, 255, 255, 255);
		BV03[1].uOffsetRGB.dwPacked	= RGBAColour (255, 255, 255, 255);

		/* Vertex #3 */
		BV03[2].ParamControlWord	= KM_VERTEXPARAM_ENDOFSTRIP;
		BV03[2].fX					= 640.0f;
		BV03[2].fY					= 480.0f;
#if defined(_STRICT_UNION_)
		BV03[2].u.fZ				=  0.0001f;
#else
		BV03[2].fZ					=  0.0001f;
#endif
		BV03[2].fU					= 1.0f;
		BV03[2].fV					= 0.0f;
		BV03[2].uBaseRGB.dwPacked	= RGBAColour (255, 255, 255, 255);
		BV03[2].uOffsetRGB.dwPacked	= RGBAColour (255, 255, 255, 255);

		pBV[0] = &BV03[0];
		pBV[1] = &BV03[1];
		pBV[2] = &BV03[2];

		/* set VERTEX */
		status = kmSetBackGroundPlane(	pBV,					/* pVertex */
										KM_VERTEXTYPE_03,		/* VertexType */
										sizeof(KMVERTEX_03)		/* StructSize */
										);
		Check_Status(status, "kmSetBackGroundPlane");
	}

}
/*--------------------------- End of File --------------------------------*/

