/********************************************************************/
/* Kamui function test program										*/
/* Test of Rectangle texture										*/
/********************************************************************/
/*   COPYRIGHT (C) NEC Corporation 1997                             */
/*   All rights reserved by NEC Corporation. This program must be   */
/*   used solely for the purpose for which it was furnished by NEC  */
/*   Corporation. No part of this program may be reproduced or      */
/*   disclosed to others, in any form, without the prior written    */
/*   permission of NEC Corporation.                                 */
/*   Use of copyright notice does not evidence publication of this  */
/*   program.                                                       */
/********************************************************************/

#include    <stdlib.h>
#include	<stdio.h>
#include	<io.h>					/* for _filelength */
#include	<FCNTL.H>				/* for _open switches */
#include	<windows.h>
#include	"kamui.h"				/* for Kamui Call */

#include	"dumpdata.h"

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

/****************************************************************************/
/**	Initialize Vertex Context ***********************************************/
/****************************************************************************/
void	InitVertexContext(PKMVERTEXCONTEXT pVertexContext)
{
	// 頂点CONTEXTの生成
	pVertexContext->RenderState	= KM_DEPTHMODE  		| KM_CULLINGMODE				// ISP/TSP IW
								| KM_SCREENCOORDINATION	| KM_SHADINGMODE
								| KM_MODIFIER 			| KM_ZWRITEDISABLE				// TSP CW
								| 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 					// Param CW
								| KM_COLORTYPE			| KM_USESPECULAR
								| KM_UVFORMAT;

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

	// for ISP/TSP InstructionWord
	pVertexContext->DepthMode			= KM_GREATER;
	pVertexContext->CullingMode			= KM_NOCULLING;
	pVertexContext->ScreenCoordination	= KM_SCREEN;
	pVertexContext->ShadingMode			= KM_NOTEXTUREGOURAUD;
	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->bSuperSample		= FALSE;
	pVertexContext->MipMapAdjust		= 0x00000004;		/* D=1.00 */
	pVertexContext->TextureShadingMode	= KM_MODULATE;

	// for Texture ControlBit

	// 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);
}

/****************************************************************************/
/**	Load texture ************************************************************/
/****************************************************************************/
PKMDWORD LoadTextureFile(char *filename)
{
	int			hFile;
	long		filelen;
	PKMDWORD	pTexture;

	/* Open input file */
	hFile = _open(filename, _O_RDONLY | _O_BINARY);
	if(hFile != -1) {
		filelen = _filelength(hFile);			// length of texture file
		pTexture = (PKMDWORD)malloc(filelen);	// allocate mainmemory
		_read(hFile, pTexture, filelen);		// read in texture file
		_close(hFile);							// file close
		printf("LoadTextureFile: Texture file %s readed.\n",filename);
	}
	else {
		printf("LoadTextureFile: ERROR Can not read file %s.\n",filename);
	}
	return pTexture;
}

/****************************************************************************/
/**	Save texture ************************************************************/
/****************************************************************************/
BOOL SaveTextureFile(char *filename, PKMDWORD pTexture, int bytes)
{
	HANDLE			hFile;
	UINT			fResult;
	DWORD			nWrited;

	/* Open output file */
	hFile = CreateFile(	filename,					/* output filename */
						GENERIC_WRITE,				/* mode = write */
						0,							/* share mode = not share */
						NULL,						/* security attribute = cancel */
						CREATE_ALWAYS,				/* create file always */
						FILE_ATTRIBUTE_NORMAL,		/* file attribute = normal */
						NULL						/* template file = non */
						);
	if(hFile) {
		fResult = WriteFile(hFile,			/* IN  : file handle */
							pTexture,		/* IN  : pointer to write data */
							(DWORD)bytes,	/* IN  : number of data in bytes */
							&nWrited,		/* OUT : number of data just writed */
							NULL			/* IN  : pointer to OVERLAPPED structure */
						  	);
		CloseHandle(hFile);							/* close file */
		if(fResult == FALSE) {
			printf("SaveTextureFile: ERROR Can not write texture file %s.\n",filename);
		}
		else {
			printf("SaveTextureFile: Texture file %s writed.\n",filename);
		}
	}
	else {
		printf("SaveTextureFile: ERROR Can not write texture file %s.\n",filename);
	}
	return TRUE;
}

/****************************************************************************/
/**	Message box *************************************************************/
/****************************************************************************/
void messagebox(char *str)
{
	char	in;
	printf("%s [Hit return key]\n",str);
	scanf("%c",&in);
}

/****************************************************************************/
/**	Background surface setting **********************************************/
/****************************************************************************/
void	InitBackGround(void)
{
	KMSTATUS			status;
	KMVERTEXCONTEXT		BackVertexContext;		// Vertex context
	KMVERTEX_00			BV[3];					// pointer to Vertex
	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.ColorType				= KM_PACKEDCOLOR;
	BackVertexContext.bUseSpecular			= FALSE;
	BackVertexContext.UVFormat				= KM_32BITUV;

	// for ISP/TSP InstructionWord
	BackVertexContext.DepthMode				= KM_GREATER;
	BackVertexContext.CullingMode			= KM_NOCULLING;
	BackVertexContext.ScreenCoordination	= KM_SCREEN;
	BackVertexContext.ShadingMode			= KM_NOTEXTUREGOURAUD;
	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;			/* 11 is reserved */
	BackVertexContext.bUseSpecular			= FALSE;
	BackVertexContext.bUseAlpha				= FALSE;
	BackVertexContext.ClampUV				= KM_NOCLAMP;
	BackVertexContext.FilterMode			= KM_POINT_SAMPLE;
	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

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

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

	// Vertex #1
	BV[0].ParamControlWord	= KM_VERTEXPARAM_NORMAL;
	BV[0].fX					=   0.0f;
	BV[0].fY					= 479.0f;
	BV[0].fZ					=   0.2f;
	BV[0].uBaseRGB.byte.bBlue	=    255;
	BV[0].uBaseRGB.byte.bGreen	=      0;
	BV[0].uBaseRGB.byte.bRed	=      0;
	BV[0].uBaseRGB.byte.bAlpha	=    255;

	// Vertex #2
	BV[1].ParamControlWord	= KM_VERTEXPARAM_NORMAL;
	BV[1].fX					= 320.0f;
	BV[1].fY					=   0.0f;
	BV[1].fZ					=   0.2f;
	BV[1].uBaseRGB.byte.bBlue	=      0;
	BV[1].uBaseRGB.byte.bGreen	=    255;
	BV[1].uBaseRGB.byte.bRed	=      0;
	BV[1].uBaseRGB.byte.bAlpha	=    255;

	// Vertex #3
	BV[2].ParamControlWord	= KM_VERTEXPARAM_ENDOFSTRIP;
	BV[2].fX					= 639.0f;
	BV[2].fY					= 479.0f;
	BV[2].fZ					=   0.2f;
	BV[2].uBaseRGB.byte.bBlue	=    255;
	BV[2].uBaseRGB.byte.bGreen	=      0;
	BV[2].uBaseRGB.byte.bRed	=      0;
	BV[2].uBaseRGB.byte.bAlpha	=    255;

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

	//-----------------------------------------------------------------------------------
	// set VERTEX
	status = kmSetBackGroundPlane(	pBV,					// pVertex
									KM_VERTEXTYPE_00,		// VertexType
									sizeof(KMVERTEX_00)		// StructSize
									);
	Check_Status(status, "kmSetBackGroundPlane");
}

/****************************************************************************/
/**	Main ********************************************************************/
/****************************************************************************/
int	main(void)
{
	int		i, j;
	float	x1, y1, x2, y2;
/****************************************************************************/
/**	Valuables for KAMUI *****************************************************/
/****************************************************************************/
	KMSTATUS			status;
	KMVERSIONINFO		VersionInfo;			// KAMUI Version information
	KMSURFACEDESC		PrimarySurfaceDesc;		// Primary frame buffer
	KMSURFACEDESC		BackSurfaceDesc;		// Back-buffer frame buffer
	KMSURFACEDESC		TexSurfaceDesc1;		// texture surface
	KMSURFACEDESC		TexSurfaceDesc2;		// texture surface
	KMVERTEXBUFFDESC	VertexBufferDesc;		// Vertex-buffer
	KMVERTEXCONTEXT		VertexContext01;		// Vertex context
	KMVERTEX_05			V[4];					// Vertex
	PKMDWORD			pTexture01;				// Pointer to texture
	KMTEXTURETYPE		nTextureType;			// texture type definition

/****************************************************************************/
/** Vertex Data *************************************************************/
/****************************************************************************/
	// Vertex #1
	V[0].ParamControlWord	= KM_VERTEXPARAM_NORMAL;
	V[0].fX					= 120.0f;
	V[0].fY					= 440.0f;
	V[0].fZ					=  0.5f;
	V[0].fU					=  0.0f;
    V[0].fV                 =  1.0f;
	V[0].fBaseAlpha			=  1.0f;
	V[0].fBaseRed			=  1.0f;
	V[0].fBaseGreen			=  1.0f;
	V[0].fBaseBlue			=  1.0f;
	V[0].fOffsetAlpha		=  1.0f;
	V[0].fOffsetRed			=  0.0f;
	V[0].fOffsetGreen		=  0.0f;
	V[0].fOffsetBlue		=  0.0f;

	// Vertex #2
	V[1].ParamControlWord	= KM_VERTEXPARAM_NORMAL;
	V[1].fX					= 120.0f;
	V[1].fY					=  40.0f;
	V[1].fZ					=  0.5f;
	V[1].fU					=  0.0f;
    V[1].fV                 =  0.0f;
	V[1].fBaseAlpha			=  1.0f;
	V[1].fBaseRed			=  1.0f;
	V[1].fBaseGreen			=  1.0f;
	V[1].fBaseBlue			=  1.0f;
	V[1].fOffsetAlpha		=  1.0f;
	V[1].fOffsetRed			=  0.0f;
	V[1].fOffsetGreen		=  0.0f;
	V[1].fOffsetBlue		=  0.0f;

	// Vertex #3
	V[2].ParamControlWord	= KM_VERTEXPARAM_NORMAL;
	V[2].fX					= 520.0f;
	V[2].fY					= 440.0f;
	V[2].fZ					=  0.5f;
	V[2].fU					=  1.0f;
    V[2].fV                 =  1.0f;
	V[2].fBaseAlpha			=  1.0f;
	V[2].fBaseRed			=  1.0f;
	V[2].fBaseGreen			=  1.0f;
	V[2].fBaseBlue			=  1.0f;
	V[2].fOffsetAlpha		=  1.0f;
	V[2].fOffsetRed			=  0.0f;
	V[2].fOffsetGreen		=  0.0f;
	V[2].fOffsetBlue		=  0.0f;

	// Vertex #4
	V[3].ParamControlWord	= KM_VERTEXPARAM_ENDOFSTRIP;
	V[3].fX					= 520.0f;
	V[3].fY					=  40.0f;
	V[3].fZ					=  0.5f;
	V[3].fU					=  1.0f;
    V[3].fV                 =  0.0f;
	V[3].fBaseAlpha			=  1.0f;
	V[3].fBaseRed			=  1.0f;
	V[3].fBaseGreen			=  1.0f;
	V[3].fBaseBlue			=  1.0f;
	V[3].fOffsetAlpha		=  1.0f;
	V[3].fOffsetRed			=  0.0f;
	V[3].fOffsetGreen		=  0.0f;
	V[3].fOffsetBlue		=  0.0f;

/****************************************************************************/
/** Kamu Test Main **********************************************************/
/****************************************************************************/

	printf("**** KAMUI TEXTURE TEST 05 : Rectangle texture ****\n\n");

	//-----------------------------------------------------------------------------------
	// Initialize Hardware
	status = kmInitDevice(KM_VGA);
	Check_Status(status, "kmInitDevice");

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

	//-----------------------------------------------------------------------------------
	// set display mode
	status = kmSetDisplayMode(	KM_DSPMODE_VGA,		// nDisplayMode
								KM_DSPBPP_RGB565,	// nBpp
								TRUE,				// bDither
								FALSE				// bAntiAlias
								);
	Check_Status(status, "kmSetDisplayMode");

	//-----------------------------------------------------------------------------------
	// Create primary frame buffer surface
	status = kmCreateFrameBufferSurface(&PrimarySurfaceDesc,	// pSurfaceDesc
								640,	// nWidth
								480,	// nHeight
								FALSE,	// bStripBuffer
								FALSE	// bBufferClear
								);
	Check_Status(status, "kmCreateFrameBufferSurface(Primary)");

	//-----------------------------------------------------------------------------------
	// Create backbuffer frame buffer surface
	status = kmCreateFrameBufferSurface(&BackSurfaceDesc,	// pSurfaceDesc
								640,	// nWidth
								480,	// nHeight
								FALSE,	// bStripBuffer
								FALSE	// bBufferClear
								);
	Check_Status(status, "kmCreateFrameBufferSurface(Back-buffer)");

	//-----------------------------------------------------------------------------------
	// Create texture surface
	nTextureType = KM_TEXTURE_RECTANGLE | KM_TEXTURE_RGB565;	// Set texture type
	status = kmCreateTextureSurface(
		&TexSurfaceDesc1,		// OUT	PKMSURFACEDESC	pSurfaceDesc
		256,					//	IN	KMINT32			nWidth
		256,					//	IN	KMINT32			nHeight
		nTextureType			//	IN	KMTEXTURETYPE	nTextureType
	);
	Check_Status(status, "kmCreateTextureSurface #1");

	nTextureType = KM_TEXTURE_RECTANGLE | KM_TEXTURE_ARGB4444;	// Set texture type
	status = kmCreateTextureSurface(
		&TexSurfaceDesc2,		// OUT	PKMSURFACEDESC	pSurfaceDesc
		128,					//	IN	KMINT32			nWidth
		32,						//	IN	KMINT32			nHeight
		nTextureType			//	IN	KMTEXTURETYPE	nTextureType
	);
	Check_Status(status, "kmCreateTextureSurface #2");

//	debug_dump_SurfaceDesc("surface.txt", &TexSurfaceDesc1);

	//-----------------------------------------------------------------------------------
	// Load and set texture
    pTexture01 =  LoadTextureFile(".\\Turtle.pvr");
	status = kmLoadTexture(&TexSurfaceDesc1,	// PKMSURFACEDESC pSurfaceDesc
							pTexture01 + (16 / sizeof(KMDWORD)),			// PKMDWORD pTexture
							FALSE,				// KMBOOLEAN bAutoMipMap
							FALSE				// KMBOOLEAN bDither
							);
	Check_Status(status, "kmLoadTexture #1");
	free(pTexture01);

    pTexture01 =  LoadTextureFile(".\\128x32.pvr");
	status = kmLoadTexture(&TexSurfaceDesc2,	// PKMSURFACEDESC pSurfaceDesc
							pTexture01 + (16 / sizeof(KMDWORD)),			// PKMDWORD pTexture
							FALSE,				// KMBOOLEAN bAutoMipMap
							FALSE				// KMBOOLEAN bDither
							);
	Check_Status(status, "kmLoadTexture #2");
	free(pTexture01);

//	messagebox("** texture loaded **");

	//-----------------------------------------------------------------------------------
	// Create vertex buffer
	status = kmCreateVertexBuffer(&VertexBufferDesc,		// pBufferDesc
									131072,					// Opaque-Polygon 500KB
									0,						// Opaque-Modifier
									131072,					// Trans-Polygon 500KB
									0						// Trans-Modifier
									);
	Check_Status(status, "kmCreateVertexBuffer");

	//-----------------------------------------------------------------------------------
	// set VERTEXCONTEXT
	memset( &VertexContext01, 0, sizeof(VertexContext01));	// Crear Context
	InitVertexContext( &VertexContext01);

	VertexContext01.RenderState	= 0;
	// Set shading mode
	VertexContext01.RenderState	|= KM_SHADINGMODE;
	VertexContext01.ShadingMode	= KM_TEXTUREGOURAUD;
	// Set texture surface
	VertexContext01.pTextureSurfaceDesc	= &TexSurfaceDesc1;
	// Set texture surface
	VertexContext01.RenderState	|= KM_CLAMPUV;
	VertexContext01.ClampUV	= KM_CLAMP_UV;
	// Process & Set
	status = kmProcessVertexRenderState(&VertexContext01);
	Check_Status(status, "kmProcessVertexRenderState");
	status = kmSetVertexRenderState(&VertexContext01);
	Check_Status(status, "kmSetVertexRenderState");

	//-----------------------------------------------------------------------------------
	// set background plane
	InitBackGround();

	//-----------------------------------------------------------------------------------
	// set display surface
	status = kmActivateFrameBuffer(	&PrimarySurfaceDesc,	// pSurfaceDesc
									&BackSurfaceDesc,		// pSurfaceDesc
									FALSE,					// bStripBuffer
									TRUE					// bWaitVSync
									);
	Check_Status(status, "kmActivateFrameBuffer");

	//-----------------------------------------------------------------------------------
	// Start rendering loop
	for(j = 0; j < 12; j++){
	for(i = 10; i < 400; i += 5) {
		x1 = (float)((640.0 - (float)i) / 2.0);
		y1 = (float)((480.0 - (float)i) / 2.0);
		x2 = x1 + (float)i;
		y2 = y1 + (float)i;
		V[0].fX	= x1;
		V[0].fY	= y2;
		V[1].fX	= x1;
		V[1].fY	= y1;
		V[2].fX	= x2;
		V[2].fY	= y2;
		V[3].fX	= x2;
		V[3].fY	= y1;

	//-----------------------------------------------------------------------------------
	// Start Triangle strip
	status = kmStartVertexStrip(&VertexBufferDesc);
	Check_Status(status, "kmStartVertexStrip");

	//-----------------------------------------------------------------------------------
	// set vertex data
	status = kmSetVertex(	&VertexBufferDesc,		// pBufferDesc
							&V[0],					// pVertex
							KM_VERTEXTYPE_05,		// VertexType
							sizeof(KMVERTEX_05)		// StructSize
							);
	Check_Status(status, "kmSetVertex(#1)");

	status = kmSetVertex(	&VertexBufferDesc,		// pBufferDesc
							&V[1],					// pVertex
							KM_VERTEXTYPE_05,		// VertexType
							sizeof(KMVERTEX_05)		// StructSize
							);
	Check_Status(status, "kmSetVertex(#2)");

	status = kmSetVertex(	&VertexBufferDesc,		// pBufferDesc
							&V[2],					// pVertex
							KM_VERTEXTYPE_05,		// VertexType
							sizeof(KMVERTEX_05)		// StructSize
							);
	Check_Status(status, "kmSetVertex(#3)");

	status = kmSetVertex(	&VertexBufferDesc,		// pBufferDesc
							&V[3],					// pVertex
							KM_VERTEXTYPE_05,		// VertexType
							sizeof(KMVERTEX_05)		// StructSize
							);
	Check_Status(status, "kmSetVertex(#4)");

	//-----------------------------------------------------------------------------------
	// Rendering start
	status = kmRender();
	Check_Status(status, "kmRender");

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

	//-----------------------------------------------------------------------------------
	// Loop
	}	// end of for i

	//-----------------------------------------------------------------------------------
	// Change Texture
	VertexContext01.RenderState	= 0;
	switch(j % 2) {
	default:
	case 0:	// Set texture surface
			VertexContext01.pTextureSurfaceDesc	= &TexSurfaceDesc2;
			//
			VertexContext01.RenderState	|= KM_SRCBLENDINGMODE;
			VertexContext01.SRCBlendingMode	= KM_SRCALPHA;
			//
			VertexContext01.RenderState	|= KM_DSTBLENDINGMODE;
			VertexContext01.DSTBlendingMode	= KM_INVSRCALPHA;
			//
			VertexContext01.RenderState	|= KM_LISTTYPE;
			VertexContext01.ListType  = KM_TRANS_POLYGON;
			//
			VertexContext01.RenderState	|= KM_USEALPHA;
			VertexContext01.bUseAlpha = TRUE;
			printf(" now display ARGB1555 texture\n");
			break;
	case 1:	// Set texture surface
			VertexContext01.pTextureSurfaceDesc	= &TexSurfaceDesc1;
			//
			VertexContext01.RenderState	|= KM_DSTBLENDINGMODE;
			VertexContext01.DSTBlendingMode	= KM_ZERO;
			//
			VertexContext01.RenderState	|= KM_LISTTYPE;
			VertexContext01.ListType  = KM_OPAQUE_POLYGON;
			//
			VertexContext01.RenderState	|= KM_USEALPHA;
			VertexContext01.bUseAlpha = FALSE;
			printf(" now display RGB565 texture\n",j);
			break;
	}

	// Process & Set
	status = kmProcessVertexRenderState(&VertexContext01);
	Check_Status(status, "kmProcessVertexRenderState");
	status = kmSetVertexRenderState(&VertexContext01);
	Check_Status(status, "kmSetVertexRenderState");

	//-----------------------------------------------------------------------------------
	// Loop
	}	// end of for j

	//** kmGetTexture  **----------------------------------------------------------------
	pTexture01 = (PKMDWORD)malloc(TexSurfaceDesc1.dwTextureSize + 16);	// allocate mainmemory
	status = kmGetTexture(pTexture01 + (16 / sizeof(KMDWORD)), &TexSurfaceDesc1);
	Check_Status(status, "kmGetTexture #1");
	SaveTextureFile(".\\txtest05.pvr", pTexture01, (TexSurfaceDesc1.dwTextureSize + 16));
	free(pTexture01);

	//-----------------------------------------------------------------------------------
	// Free vertex buffer
	status = kmDiscardVertexBuffer(&VertexBufferDesc);
	Check_Status(status, "kmDiscadeVertexBuffer");

	//-----------------------------------------------------------------------------------
	// Free texture Surface
	status = kmFreeTexture(&TexSurfaceDesc1);
	Check_Status(status, "kmFreeTexture");

	status = kmFreeTexture(&TexSurfaceDesc2);
	Check_Status(status, "kmFreeTexture");

	//-----------------------------------------------------------------------------------
	// End display
	status = kmStopDisplayFrameBuffer();
	Check_Status(status, "kmStopDisplayFrameBuffer");

	printf("** End of test program **\n");
	return  0;
}