/********************************************************************/
/* Kamui function test program										*/
/* Test of 2 parameter modifier volume								*/
/********************************************************************/
/*   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 */

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

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

/****************************************************************************/
/**	Main ********************************************************************/
/****************************************************************************/
int	main(void)
{
	int		frame = 0;
	int		i;

	// parameter for object 1
	float	ax1 = 0;
	float	ay1 = 0;
	float 	ax2, ay2;
	float	axd = 5;
	float	ayd = 5;

	// parameter for object 2
	float	bx1 = 100;
	float	by1 = 100;
	float 	bx2, by2;
	float	bxd = 8;
	float	byd = 8;

/****************************************************************************/
/**	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
	KMSURFACEDESC		TexSurfaceDesc3;		// texture surface
	KMVERTEXBUFFDESC	VertexBufferDesc;		// Vertex-buffer
	KMVERTEXCONTEXT		VertexContext01;		// Vertex context
	KMVERTEXCONTEXT		VertexContext02;		// Vertex context
	KMVERTEXCONTEXT		VertexContext03A;		// Modifier Vertex volume(First)
	KMVERTEXCONTEXT		VertexContext03B;		// Modifier Vertex volume(Normal)
	KMVERTEXCONTEXT		VertexContext03C;		// Modifier Vertex volume(Last)
	KMVERTEXCONTEXT		VertexContext04;		// Modifier volume
	KMVERTEX_11			V1[4];					// Vertexs 1
	KMVERTEX_05			V2[4];					// Vertexs 2
	KMVERTEX_17			MV[12];					// Modifier volume Vertex
	PKMDWORD			pTexture01;				// Pointer to texture
	KMTEXTURETYPE		nTextureType;			// texture type definition

/****************************************************************************/
/** Vertex Data *************************************************************/
/****************************************************************************/
	// Opaque Polygon(1)
	// Vertex #1
	V1[0].ParamControlWord	= KM_VERTEXPARAM_NORMAL;
	V1[0].fX				= 120.0f;
	V1[0].fY				= 440.0f;
	V1[0].fZ				=  0.5f;
	V1[0].fU0m				=  0.0f;
    V1[0].fV0m              =  1.0f;
	V1[0].fU1m				=  0.0f;
    V1[0].fV1m              =  1.0f;
	V1[0].uBaseRGB0m.byte.bBlue		=  255;
	V1[0].uBaseRGB0m.byte.bGreen	=  255;
	V1[0].uBaseRGB0m.byte.bRed		=  255;
	V1[0].uBaseRGB0m.byte.bAlpha	=  255;
	V1[0].uBaseRGB1m.byte.bBlue		=  255;
	V1[0].uBaseRGB1m.byte.bGreen	=  255;
	V1[0].uBaseRGB1m.byte.bRed		=  255;
	V1[0].uBaseRGB1m.byte.bAlpha	=  255;
	V1[0].uOffsetRGB0m.byte.bBlue	=    0;
	V1[0].uOffsetRGB0m.byte.bGreen	=    0;
	V1[0].uOffsetRGB0m.byte.bRed	=    0;
	V1[0].uOffsetRGB0m.byte.bAlpha	=  255;
	V1[0].uOffsetRGB1m.byte.bBlue	=    0;
	V1[0].uOffsetRGB1m.byte.bGreen	=    0;
	V1[0].uOffsetRGB1m.byte.bRed	=    0;
	V1[0].uOffsetRGB1m.byte.bAlpha	=  255;

	// Vertex #2
	V1[1].ParamControlWord	= KM_VERTEXPARAM_NORMAL;
	V1[1].fX				= 120.0f;
	V1[1].fY				=  40.0f;
	V1[1].fZ				=  0.5f;
	V1[1].fU0m				=  0.0f;
    V1[1].fV0m              =  0.0f;
	V1[1].fU1m				=  0.0f;
    V1[1].fV1m              =  0.0f;
	V1[1].uBaseRGB0m.byte.bBlue		=  255;
	V1[1].uBaseRGB0m.byte.bGreen	=  255;
	V1[1].uBaseRGB0m.byte.bRed		=  255;
	V1[1].uBaseRGB0m.byte.bAlpha	=  255;
	V1[1].uBaseRGB1m.byte.bBlue		=  255;
	V1[1].uBaseRGB1m.byte.bGreen	=  255;
	V1[1].uBaseRGB1m.byte.bRed		=  255;
	V1[1].uBaseRGB1m.byte.bAlpha	=  255;
	V1[1].uOffsetRGB0m.byte.bBlue	=    0;
	V1[1].uOffsetRGB0m.byte.bGreen	=    0;
	V1[1].uOffsetRGB0m.byte.bRed	=    0;
	V1[1].uOffsetRGB0m.byte.bAlpha	=  255;
	V1[1].uOffsetRGB1m.byte.bBlue	=    0;
	V1[1].uOffsetRGB1m.byte.bGreen	=    0;
	V1[1].uOffsetRGB1m.byte.bRed	=    0;
	V1[1].uOffsetRGB1m.byte.bAlpha	=  255;

	// Vertex #3
	V1[2].ParamControlWord	= KM_VERTEXPARAM_NORMAL;
	V1[2].fX				= 520.0f;
	V1[2].fY				= 440.0f;
	V1[2].fZ				=  0.5f;
	V1[2].fU0m				=  1.0f;
    V1[2].fV0m              =  1.0f;
	V1[2].fU1m				=  1.0f;
    V1[2].fV1m              =  1.0f;
	V1[2].uBaseRGB0m.byte.bBlue		=  255;
	V1[2].uBaseRGB0m.byte.bGreen	=  255;
	V1[2].uBaseRGB0m.byte.bRed		=  255;
	V1[2].uBaseRGB0m.byte.bAlpha	=  255;
	V1[2].uBaseRGB1m.byte.bBlue		=  255;
	V1[2].uBaseRGB1m.byte.bGreen	=  255;
	V1[2].uBaseRGB1m.byte.bRed		=  255;
	V1[2].uBaseRGB1m.byte.bAlpha	=  255;
	V1[2].uOffsetRGB0m.byte.bBlue	=    0;
	V1[2].uOffsetRGB0m.byte.bGreen	=    0;
	V1[2].uOffsetRGB0m.byte.bRed	=    0;
	V1[2].uOffsetRGB0m.byte.bAlpha	=  255;
	V1[2].uOffsetRGB1m.byte.bBlue	=    0;
	V1[2].uOffsetRGB1m.byte.bGreen	=    0;
	V1[2].uOffsetRGB1m.byte.bRed	=    0;
	V1[2].uOffsetRGB1m.byte.bAlpha	=  255;

	// Vertex #4
	V1[3].ParamControlWord	= KM_VERTEXPARAM_ENDOFSTRIP;
	V1[3].fX				= 520.0f;
	V1[3].fY				=  40.0f;
	V1[3].fZ				=  0.5f;
	V1[3].fU0m				=  1.0f;
    V1[3].fV0m              =  0.0f;
	V1[3].fU1m				=  1.0f;
    V1[3].fV1m              =  0.0f;
	V1[3].uBaseRGB0m.byte.bBlue		=  255;
	V1[3].uBaseRGB0m.byte.bGreen	=  255;
	V1[3].uBaseRGB0m.byte.bRed		=  255;
	V1[3].uBaseRGB0m.byte.bAlpha	=  255;
	V1[3].uBaseRGB1m.byte.bBlue		=  255;
	V1[3].uBaseRGB1m.byte.bGreen	=  255;
	V1[3].uBaseRGB1m.byte.bRed		=  255;
	V1[3].uBaseRGB1m.byte.bAlpha	=  255;
	V1[3].uOffsetRGB0m.byte.bBlue	=    0;
	V1[3].uOffsetRGB0m.byte.bGreen	=    0;
	V1[3].uOffsetRGB0m.byte.bRed	=    0;
	V1[3].uOffsetRGB0m.byte.bAlpha	=  255;
	V1[3].uOffsetRGB1m.byte.bBlue	=    0;
	V1[3].uOffsetRGB1m.byte.bGreen	=    0;
	V1[3].uOffsetRGB1m.byte.bRed	=    0;
	V1[3].uOffsetRGB1m.byte.bAlpha	=  255;

	// Opaque Polygon(2)
	// Vertex #1
	V2[0].ParamControlWord	= KM_VERTEXPARAM_NORMAL;
	V2[0].fX				= 120.0f;
	V2[0].fY				= 440.0f;
	V2[0].fZ				=  0.6f;
	V2[0].fU				=  0.0f;
    V2[0].fV                =  1.0f;
	V2[0].fBaseAlpha		=  1.0f;
	V2[0].fBaseRed			=  1.0f;
	V2[0].fBaseGreen		=  1.0f;
	V2[0].fBaseBlue			=  1.0f;
	V2[0].fOffsetAlpha		=  1.0f;
	V2[0].fOffsetRed		=  0.0f;
	V2[0].fOffsetGreen		=  0.0f;
	V2[0].fOffsetBlue		=  0.0f;

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

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

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

	// Opaque Modifier
	// Front
	MV[0].ParamControlWord	= KM_VERTEXPARAM_ENDOFSTRIP;
	MV[0].fAX	= 250.0f;	MV[0].fBX	= 250.0f;	MV[0].fCX	= 390.0f;
	MV[0].fAY	= 310.0f;	MV[0].fBY	= 170.0f;	MV[0].fCY	= 310.0f;
	MV[0].fAZ	=   0.7f;	MV[0].fBZ	=   0.7f;	MV[0].fCZ	=   0.7f;
	MV[1].ParamControlWord	= KM_VERTEXPARAM_ENDOFSTRIP;
	MV[1].fAX	= 390.0f;	MV[1].fBX	= 250.0f;	MV[1].fCX	= 390.0f;
	MV[1].fAY	= 310.0f;	MV[1].fBY	= 170.0f;	MV[1].fCY	= 170.0f;
	MV[1].fAZ	=   0.7f;	MV[1].fBZ	=   0.7f;	MV[1].fCZ	=   0.7f;
	// Back
	MV[2].ParamControlWord	= KM_VERTEXPARAM_ENDOFSTRIP;
	MV[2].fAX	= 420.0f;	MV[2].fBX	= 420.0f;	MV[2].fCX	= 220.0f;
	MV[2].fAY	= 340.0f;	MV[2].fBY	= 140.0f;	MV[2].fCY	= 340.0f;
	MV[2].fAZ	=   0.4f;	MV[2].fBZ	=   0.4f;	MV[2].fCZ	=   0.4f;
	MV[3].ParamControlWord	= KM_VERTEXPARAM_ENDOFSTRIP;
	MV[3].fAX	= 220.0f;	MV[3].fBX	= 420.0f;	MV[3].fCX	= 220.0f;
	MV[3].fAY	= 340.0f;	MV[3].fBY	= 140.0f;	MV[3].fCY	= 140.0f;
	MV[3].fAZ	=   0.4f;	MV[3].fBZ	=   0.4f;	MV[3].fCZ	=   0.4f;
	// Left
	MV[4].ParamControlWord	= KM_VERTEXPARAM_ENDOFSTRIP;
	MV[4].fAX	= 220.0f;	MV[4].fBX	= 220.0f;	MV[4].fCX	= 250.0f;
	MV[4].fAY	= 340.0f;	MV[4].fBY	= 140.0f;	MV[4].fCY	= 310.0f;
	MV[4].fAZ	=   0.4f;	MV[4].fBZ	=   0.4f;	MV[4].fCZ	=   0.7f;
	MV[5].ParamControlWord	= KM_VERTEXPARAM_ENDOFSTRIP;
	MV[5].fAX	= 250.0f;	MV[5].fBX	= 220.0f;	MV[5].fCX	= 250.0f;
	MV[5].fAY	= 310.0f;	MV[5].fBY	= 140.0f;	MV[5].fCY	= 170.0f;
	MV[5].fAZ	=   0.7f;	MV[5].fBZ	=   0.4f;	MV[5].fCZ	=   0.7f;
	// Right
	MV[6].ParamControlWord	= KM_VERTEXPARAM_ENDOFSTRIP;
	MV[6].fAX	= 390.0f;	MV[6].fBX	= 390.0f;	MV[6].fCX	= 420.0f;
	MV[6].fAY	= 310.0f;	MV[6].fBY	= 170.0f;	MV[6].fCY	= 340.0f;
	MV[6].fAZ	=   0.7f;	MV[6].fBZ	=   0.7f;	MV[6].fCZ	=   0.4f;
	MV[7].ParamControlWord	= KM_VERTEXPARAM_ENDOFSTRIP;
	MV[7].fAX	= 420.0f;	MV[7].fBX	= 390.0f;	MV[7].fCX	= 420.0f;
	MV[7].fAY	= 340.0f;	MV[7].fBY	= 170.0f;	MV[7].fCY	= 140.0f;
	MV[7].fAZ	=   0.4f;	MV[7].fBZ	=   0.7f;	MV[7].fCZ	=   0.4f;
	// Up
	MV[8].ParamControlWord	= KM_VERTEXPARAM_ENDOFSTRIP;
	MV[8].fAX	= 250.0f;	MV[8].fBX	= 220.0f;	MV[8].fCX	= 390.0f;
	MV[8].fAY	= 170.0f;	MV[8].fBY	= 140.0f;	MV[8].fCY	= 170.0f;
	MV[8].fAZ	=   0.7f;	MV[8].fBZ	=   0.4f;	MV[8].fCZ	=   0.7f;
	MV[9].ParamControlWord	= KM_VERTEXPARAM_ENDOFSTRIP;
	MV[9].fAX	= 390.0f;	MV[9].fBX	= 220.0f;	MV[9].fCX	= 420.0f;
	MV[9].fAY	= 170.0f;	MV[9].fBY	= 140.0f;	MV[9].fCY	= 140.0f;
	MV[9].fAZ	=   0.7f;	MV[9].fBZ	=   0.4f;	MV[9].fCZ	=   0.4f;
	// Down
	MV[10].ParamControlWord	= KM_VERTEXPARAM_ENDOFSTRIP;
	MV[10].fAX	= 220.0f;	MV[10].fBX	= 250.0f;	MV[10].fCX	= 420.0f;
	MV[10].fAY	= 340.0f;	MV[10].fBY	= 310.0f;	MV[10].fCY	= 340.0f;
	MV[10].fAZ	=   0.4f;	MV[10].fBZ	=   0.7f;	MV[10].fCZ	=   0.4f;
	MV[11].ParamControlWord	= KM_VERTEXPARAM_ENDOFSTRIP;
	MV[11].fAX	= 420.0f;	MV[11].fBX	= 250.0f;	MV[11].fCX	= 390.0f;
	MV[11].fAY	= 340.0f;	MV[11].fBY	= 310.0f;	MV[11].fCY	= 310.0f;
	MV[11].fAZ	=   0.4f;	MV[11].fBZ	=   0.7f;	MV[11].fCZ	=   0.7f;

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

	printf("**** KAMUI MODIFIER VOLUME TEST 01 ****\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);

	status = kmSetDisplayMode(	KM_DSPMODE_VGA,		// nDisplayMode
								KM_DSPBPP_RGB565,	// nBpp
								FALSE,				// 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)");

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

	//-----------------------------------------------------------------------------------
	// Create texture surface
	nTextureType = KM_TEXTURE_TWIDDLED | 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");

	nTextureType = KM_TEXTURE_TWIDDLED | KM_TEXTURE_ARGB4444;	// Set texture type
	status = kmCreateTextureSurface(
		&TexSurfaceDesc2,		// OUT	PKMSURFACEDESC	pSurfaceDesc
		256,					//	IN	KMINT32			nWidth
		256,					//	IN	KMINT32			nHeight
		nTextureType			//	IN	KMTEXTURETYPE	nTextureType
	);
	Check_Status(status, "kmCreateTextureSurface");

	nTextureType = KM_TEXTURE_TWIDDLED | KM_TEXTURE_RGB565;	// Set texture type
	status = kmCreateTextureSurface(
		&TexSurfaceDesc3,		// OUT	PKMSURFACEDESC	pSurfaceDesc
		256,					//	IN	KMINT32			nWidth
		256,					//	IN	KMINT32			nHeight
		nTextureType			//	IN	KMTEXTURETYPE	nTextureType
	);
	Check_Status(status, "kmCreateTextureSurface");

	//-----------------------------------------------------------------------------------
	// Load and set texture
    pTexture01 =  LoadTextureFile(".\\Starfish.pvr");    // RGB565
	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(".\\Reefback.pvr");    // ARGB4444
	status = kmLoadTexture(&TexSurfaceDesc2,	// PKMSURFACEDESC pSurfaceDesc
							pTexture01 + (16 / sizeof(KMDWORD)),			// PKMDWORD pTexture
							FALSE,				// KMBOOLEAN bAutoMipMap
							FALSE				// KMBOOLEAN bDither
							);
	Check_Status(status, "kmLoadTexture #2");
	free(pTexture01);

    pTexture01 =  LoadTextureFile(".\\Segalogo.pvr");    // RGB565
	status = kmLoadTexture(&TexSurfaceDesc3,	// PKMSURFACEDESC pSurfaceDesc
							pTexture01 + (16 / sizeof(KMDWORD)),			// PKMDWORD pTexture
							FALSE,				// KMBOOLEAN bAutoMipMap
							FALSE				// KMBOOLEAN bDither
							);
	Check_Status(status, "kmLoadTexture #1");
	free(pTexture01);

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

	//-----------------------------------------------------------------------------------
	// set VERTEXCONTEXT(1) : Object1 : Modifier volume valiant
	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 select modifier mode
	VertexContext01.RenderState	|= KM_MODIFIER;
	VertexContext01.SelectModifier	= KM_MODIFIER_A;
	// Set select color type
	VertexContext01.RenderState	|= KM_COLORTYPE;
	VertexContext01.ColorType	= KM_PACKEDCOLOR;
	// Set Texture Clamp
	VertexContext01.RenderState	|= KM_CLAMPUV;
	VertexContext01.ClampUV		 = KM_CLAMP_UV;

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

	//-----------------------------------------------------------------------------------
	// set VERTEXCONTEXT(2) : Object2 : Normal object
	memset( &VertexContext02, 0, sizeof(VertexContext02));	// Crear Context
	InitVertexContext( &VertexContext02);

	VertexContext02.RenderState	= 0;
	// Set shading mode
	VertexContext02.RenderState	|= KM_SHADINGMODE;
	VertexContext02.ShadingMode	= KM_TEXTUREGOURAUD;
	// Set texture surface
	VertexContext02.pTextureSurfaceDesc	= &TexSurfaceDesc2;
//	VertexContext02.pTextureSurfaceDesc	= &TexSurfaceDesc3;
	//
	VertexContext02.RenderState	|= KM_SRCBLENDINGMODE;
	VertexContext02.SRCBlendingMode	= KM_SRCALPHA;
	//
	VertexContext02.RenderState	|= KM_DSTBLENDINGMODE;
	VertexContext02.DSTBlendingMode	= KM_INVSRCALPHA;
	//
	VertexContext02.RenderState	|= KM_LISTTYPE;
	VertexContext02.ListType  = KM_TRANS_POLYGON;
	//
	VertexContext02.RenderState	|= KM_USEALPHA;
	VertexContext02.bUseAlpha = TRUE;

	// Set Texture Clamp
	VertexContext02.RenderState	|= KM_CLAMPUV;
	VertexContext02.ClampUV		 = KM_CLAMP_UV;

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

	//-----------------------------------------------------------------------------------
	// set VERTEXCONTEXT(3A) : Modifier volume(First)
	memset( &VertexContext03A, 0, sizeof(VertexContext03A));	// Crear Context
	InitVertexContext( &VertexContext03A);

	VertexContext03A.RenderState	= 0;
	// Set param type
	VertexContext03A.RenderState	|= KM_PARAMTYPE;
	VertexContext03A.ParamType		= KM_MODIFIERVOLUME;
	// Set list type
	VertexContext03A.RenderState	|= KM_LISTTYPE;
	VertexContext03A.ListType	= KM_OPAQUE_MODIFIER;

	// Shadow & BBOX
	VertexContext03A.ModifierInstruction = KM_MODIFIER_INCLUDE_FIRST_POLY;
//	VertexContext03A.fBoundingBoxXmin =   0.0f;
//	VertexContext03A.fBoundingBoxYmin =   0.0f;
//	VertexContext03A.fBoundingBoxXmax = 639.0f;
//	VertexContext03A.fBoundingBoxYmax = 479.0f;
    VertexContext03A.fBoundingBoxXmin = 192.0f;
    VertexContext03A.fBoundingBoxYmin = 112.0f;
    VertexContext03A.fBoundingBoxXmax = 448.0f;
    VertexContext03A.fBoundingBoxYmax = 368.0f;

	// Process & Set
	status = kmProcessVertexRenderState(&VertexContext03A);
	Check_Status(status, "kmProcessVertexRenderState");
	//-----------------------------------------------------------------------------------
	// set VERTEXCONTEXT(3B) : Modifier volume(Normal)
	memset( &VertexContext03B, 0, sizeof(VertexContext03B));	// Crear Context
	InitVertexContext( &VertexContext03B);

	VertexContext03B.RenderState	= 0;
	// Set param type
	VertexContext03B.RenderState	|= KM_PARAMTYPE;
	VertexContext03B.ParamType		= KM_MODIFIERVOLUME;
	// Set list type
	VertexContext03B.RenderState	|= KM_LISTTYPE;
	VertexContext03B.ListType	= KM_OPAQUE_MODIFIER;

	// Shadow & BBOX
	VertexContext03B.ModifierInstruction = KM_MODIFIER_NORMAL_POLY;
//	VertexContext03B.fBoundingBoxXmin =   0.0f;
//	VertexContext03B.fBoundingBoxYmin =   0.0f;
//	VertexContext03B.fBoundingBoxXmax = 639.0f;
//	VertexContext03B.fBoundingBoxYmax = 479.0f;
    VertexContext03B.fBoundingBoxXmin = 192.0f;
    VertexContext03B.fBoundingBoxYmin = 112.0f;
    VertexContext03B.fBoundingBoxXmax = 448.0f;
    VertexContext03B.fBoundingBoxYmax = 368.0f;

	// Process & Set
	status = kmProcessVertexRenderState(&VertexContext03B);
	Check_Status(status, "kmProcessVertexRenderState");
	//-----------------------------------------------------------------------------------
	// set VERTEXCONTEXT(3C) : Modifier volume(Last)
	memset( &VertexContext03C, 0, sizeof(VertexContext03C));	// Crear Context
	InitVertexContext( &VertexContext03C);

	VertexContext03C.RenderState	= 0;
	// Set param type
	VertexContext03C.RenderState	|= KM_PARAMTYPE;
	VertexContext03C.ParamType		= KM_MODIFIERVOLUME;
	// Set list type
	VertexContext03C.RenderState	|= KM_LISTTYPE;
	VertexContext03C.ListType	= KM_OPAQUE_MODIFIER;

	// Shadow & BBOX
	VertexContext03C.ModifierInstruction = KM_MODIFIER_INCLUDE_LAST_POLY;
//	VertexContext03C.fBoundingBoxXmin =   0.0f;
//	VertexContext03C.fBoundingBoxYmin =   0.0f;
//	VertexContext03C.fBoundingBoxXmax = 639.0f;
//	VertexContext03C.fBoundingBoxYmax = 479.0f;
    VertexContext03C.fBoundingBoxXmin = 192.0f;
    VertexContext03C.fBoundingBoxYmin = 112.0f;
    VertexContext03C.fBoundingBoxXmax = 448.0f;
    VertexContext03C.fBoundingBoxYmax = 368.0f;

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

	//-----------------------------------------------------------------------------------
	// set VERTEXCONTEXT(4) : Object1 2nd parameter (Modifier volume valiant)
	memset( &VertexContext04, 0, sizeof(VertexContext04));	// Crear Context
	InitVertexContext( &VertexContext04);

	VertexContext04.RenderState	= 0;
	// Set shading mode
	VertexContext04.RenderState	|= KM_SHADINGMODE;
	VertexContext04.ShadingMode	= KM_TEXTUREGOURAUD;

	// Set Texture Clamp
	VertexContext04.RenderState	|= KM_CLAMPUV;
	VertexContext04.ClampUV		 = KM_CLAMP_UV;

	// Set texture surface
	VertexContext04.pTextureSurfaceDesc	= &TexSurfaceDesc3;
	// Process & Set
	status = kmProcessVertexRenderState(&VertexContext04);
	Check_Status(status, "kmProcessVertexRenderState");

	//-----------------------------------------------------------------------------------
	do{
		ax1 += axd;
		if( ax1 > (640-200)){ ax1 -= axd; axd = -axd; }
		if( ax1 < 0)		{ ax1  =   0; axd = -axd; }
		ay1 += ayd;
		if( ay1 > (480-200)){ ay1 -= ayd; ayd = -ayd; }
		if( ay1 < 0)		{ ay1  =   0; ayd = -ayd; }
		ax2 = ax1 + 199;
		ay2 = ay1 + 199;
		V1[0].fX	= ax1;
		V1[0].fY	= ay2;
		V1[1].fX	= ax1;
		V1[1].fY	= ay1;
		V1[2].fX	= ax2;
		V1[2].fY	= ay2;
		V1[3].fX	= ax2;
		V1[3].fY	= ay1;

		bx1 += bxd;
		if( bx1 > (640-200)){ bx1 -= bxd; bxd = -bxd; }
		if( bx1 < 0)		{ bx1  =   0; bxd = -bxd; }
		by1 += byd;
		if( by1 > (480-200)){ by1 -= byd; byd = -byd; }
		if( by1 < 0)		{ by1  =   0; byd = -byd; }
		bx2 = bx1 + 199;
		by2 = by1 + 199;
		V2[0].fX	= bx1;
		V2[0].fY	= by2;
		V2[1].fX	= bx1;
		V2[1].fY	= by1;
		V2[2].fX	= bx2;
		V2[2].fY	= by2;
		V2[3].fX	= bx2;
		V2[3].fY	= by1;

	//-----------------------------------------------------------------------------------
	// Set Vertex context
	// Object1 : Modifier volume valiant
	status = kmSetVertexRenderState(&VertexContext01);
	Check_Status(status, "kmSetVertexRenderState");

	status = kmSetModifierRenderState(&VertexContext04);
	Check_Status(status, "kmSetVertexRenderState");

#if 1
	//-----------------------------------------------------------------------------------
	// Start Triangle strip
	// Object1 : Modifier volume valiant
	status = kmStartVertexStrip(&VertexBufferDesc);
	Check_Status(status, "kmStartVertexStrip");

	//-----------------------------------------------------------------------------------
	// set vertex data
	// Object1 : Modifier volume valiant
	status = kmSetVertex(	&VertexBufferDesc,		// pBufferDesc
							&V1[0],					// pVertex
							KM_VERTEXTYPE_11,		// VertexType
							sizeof(KMVERTEX_11)		// StructSize
							);
	Check_Status(status, "kmSetVertex(#1)");

	status = kmSetVertex(	&VertexBufferDesc,		// pBufferDesc
							&V1[1],					// pVertex
							KM_VERTEXTYPE_11,		// VertexType
							sizeof(KMVERTEX_11)		// StructSize
							);
	Check_Status(status, "kmSetVertex(#2)");

	status = kmSetVertex(	&VertexBufferDesc,		// pBufferDesc
							&V1[2],					// pVertex
							KM_VERTEXTYPE_11,		// VertexType
							sizeof(KMVERTEX_11)		// StructSize
							);
	Check_Status(status, "kmSetVertex(#3)");

	status = kmSetVertex(	&VertexBufferDesc,		// pBufferDesc
							&V1[3],					// pVertex
							KM_VERTEXTYPE_11,		// VertexType
							sizeof(KMVERTEX_11)		// StructSize
							);
	Check_Status(status, "kmSetVertex(#4)");
#endif

	//-----------------------------------------------------------------------------------
	// Set Vertex context
	// Object2 : Normal polygon
	status = kmSetVertexRenderState(&VertexContext02);
	Check_Status(status, "kmSetVertexRenderState");

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

	//-----------------------------------------------------------------------------------
	// set vertex data
	// Object2 : Normal polygon
	status = kmSetVertex(	&VertexBufferDesc,		// pBufferDesc
							&V2[0],					// pVertex
							KM_VERTEXTYPE_05,		// VertexType
							sizeof(KMVERTEX_05)		// StructSize
							);
	Check_Status(status, "kmSetVertex(#4)");

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

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

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

#if 1
	//-----------------------------------------------------------------------------------
	// Set Vertex context
	// Modifier volume(First)
	status = kmSetVertexRenderState(&VertexContext03A);
	Check_Status(status, "kmSetVertexRenderState");

		//First
		status = kmStartVertexStrip(&VertexBufferDesc);
		Check_Status(status, "kmStartVertexStrip");

		status = kmSetVertex(	&VertexBufferDesc,		// pBufferDesc
								&MV[0],					// pVertex
								KM_VERTEXTYPE_17,		// VertexType
								sizeof(KMVERTEX_17)		// StructSize
								);
		Check_Status(status, "kmSetVertex(Modifier)");

	//-----------------------------------------------------------------------------------
	// Start Modifier Volume vertex
	// Modifier volume(Normal)
	status = kmSetVertexRenderState(&VertexContext03B);
	Check_Status(status, "kmSetVertexRenderState");

	for(i = 1; i < 11; i++){
		status = kmStartVertexStrip(&VertexBufferDesc);
		Check_Status(status, "kmStartVertexStrip");

		status = kmSetVertex(	&VertexBufferDesc,		// pBufferDesc
								&MV[i],					// pVertex
								KM_VERTEXTYPE_17,		// VertexType
								sizeof(KMVERTEX_17)		// StructSize
								);
		Check_Status(status, "kmSetVertex(Modifier)");
	}

	// Modifier volume(Last)
	status = kmSetVertexRenderState(&VertexContext03C);
	Check_Status(status, "kmSetVertexRenderState");

		//First
		status = kmStartVertexStrip(&VertexBufferDesc);
		Check_Status(status, "kmStartVertexStrip");

		status = kmSetVertex(	&VertexBufferDesc,		// pBufferDesc
								&MV[11],					// pVertex
								KM_VERTEXTYPE_17,		// VertexType
								sizeof(KMVERTEX_17)		// StructSize
								);
		Check_Status(status, "kmSetVertex(Modifier)");

#endif
	//-----------------------------------------------------------------------------------
	// Rendering start
//	printf("Start Render\n");
	status = kmRender();
	Check_Status(status, "kmRender");
//	printf("End Render\n");

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

	//-----------------------------------------------------------------------------------
	// Loop
		frame++;
	}
	while(1);	// end of "do"

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

	printf("kmDiscadeVertexBuffer\n");

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

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

	printf("kmFreeTexture\n");

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

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