/********************************************************************/
/* Kamui function test program										*/
/* Test of Twiddled / Twiddled mipmap 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 <shinobi.h>
#include <kamui.h>

#define     TEX_NAME1   "Sega_vq.pvr"
#define     TEX_NAME2   "Star_vq.pvr"
#define     TEX_NAME3   "Back.pvr"
/*#define       TEX_NAME4   "M512vq.pvr" */
#define     TEX_NAME4   "Fish_vq.pvr"

/****************************************************************************/
/**	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)
{
    PKMDWORD    pTexture;
    GDFS        gdfs;
    long        fileblocks;

    /* Open input file. */
    if (!(gdfs = gdFsOpen (filename, NULL)))
        return NULL;

    /* Get file size (in blocks/sectors). */
    gdFsGetFileSctSize (gdfs, &fileblocks);

    /* Allocate memory for file to nearest block size (2048 bytes). */
    pTexture = syMalloc (fileblocks * 2048);

    /* Read file. */
    gdFsReqRd32 (gdfs, fileblocks, pTexture);

    /* Wait for file access to finish. */
    while (gdFsGetStat (gdfs) != 1)
        ;

    /* Close file. */
    gdFsClose (gdfs);

    return (PKMDWORD) pTexture;
}

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

/****************************************************************************/
/**	Background surface setting **********************************************/
/****************************************************************************/
void	InitBackGround(KMSURFACEDESC TexSurfaceDesc)
{
	KMSTATUS			status;
    KMVERTEXCONTEXT     BackVertexContext;      /* Vertex context */
    KMVERTEX_05         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_FLOATINGCOLOR;
	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_TEXTUREGOURAUD;
	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 */

    /* Set texture surface */
	BackVertexContext.pTextureSurfaceDesc	= &TexSurfaceDesc;

	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].u.fZ                =   0.2f;
	BV[0].fU				=   0.0f;
    BV[0].fV                =   0.46875f;
	BV[0].fBaseAlpha		=   1.0f;
	BV[0].fBaseRed			=   1.0f;
	BV[0].fBaseGreen		=   1.0f;
	BV[0].fBaseBlue			=   1.0f;
	BV[0].fOffsetAlpha		=   1.0f;
	BV[0].fOffsetRed		=   0.0f;
	BV[0].fOffsetGreen		=   0.0f;
	BV[0].fOffsetBlue		=   0.0f;

    /* Vertex #2 */
	BV[1].ParamControlWord	= KM_VERTEXPARAM_NORMAL;
	BV[1].fX				=   0.0f;
	BV[1].fY				=   0.0f;
    BV[1].u.fZ                =   0.2f;
	BV[1].fU				=   0.0f;
    BV[1].fV                =   0.0f;
	BV[1].fBaseAlpha		=   1.0f;
	BV[1].fBaseRed			=   1.0f;
	BV[1].fBaseGreen		=   1.0f;
	BV[1].fBaseBlue			=   1.0f;
	BV[1].fOffsetAlpha		=   1.0f;
	BV[1].fOffsetRed		=   0.0f;
	BV[1].fOffsetGreen		=   0.0f;
	BV[1].fOffsetBlue		=   0.0f;

    /* Vertex #3 */
	BV[2].ParamControlWord	= KM_VERTEXPARAM_ENDOFSTRIP;
	BV[2].fX				= 639.0f;
	BV[2].fY				= 479.0f;
    BV[2].u.fZ                =   0.2f;
	BV[2].fU				=   0.625f;
    BV[2].fV                =   0.46875f;
	BV[2].fBaseAlpha		=   1.0f;
	BV[2].fBaseRed			=   1.0f;
	BV[2].fBaseGreen		=   1.0f;
	BV[2].fBaseBlue			=   1.0f;
	BV[2].fOffsetAlpha		=   1.0f;
	BV[2].fOffsetRed		=   0.0f;
	BV[2].fOffsetGreen		=   0.0f;
	BV[2].fOffsetBlue		=   0.0f;

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

    /*----------------------------------------------------------------------------------- */
    /* set VERTEX */
    status = kmSetBackGroundPlane(  pBV,                    /* pVertex */
                                    KM_VERTEXTYPE_05,       /* VertexType */
                                    sizeof(KMVERTEX_05)     /* 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 */
    KMSURFACEDESC       TexSurfaceDesc3;        /* texture surface */
    KMSURFACEDESC       TexSurfaceDesc4;        /* 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].u.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].u.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].u.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].u.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 03 : VQ texture ****\n\n"); */

    /*----------------------------------------------------------------------------------- */
    /* Initialize the display device and set the frame buffer mode. */
    sbInitSystem (0, 0, 0);

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

    /*----------------------------------------------------------------------------------- */
    /* 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_VQ | KM_TEXTURE_ARGB1555; /* Set texture type */
	status = kmCreateCombinedTextureSurface(
        &TexSurfaceDesc1,       /* OUT  PKMSURFACEDESC  pSurfaceDesc */
        &TexSurfaceDesc2,       /* OUT  PKMSURFACEDESC  pSurfaceDesc */
        256,                    /*  IN  KMINT32         nWidth */
        256,                    /*  IN  KMINT32         nHeight */
        nTextureType            /*  IN  KMTEXTURETYPE   nTextureType */
	);
	Check_Status(status, "kmCreateTextureSurface");

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

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

    /*----------------------------------------------------------------------------------- */
    /* Load and set texture */
	pTexture01 =  LoadTextureFile(TEX_NAME1);
    status = kmLoadTexture(&TexSurfaceDesc1,    /* PKMSURFACEDESC pSurfaceDesc */
                            pTexture01 + (16 / sizeof(KMDWORD)),            /* PKMDWORD pTexture */
                            FALSE,              /* KMBOOLEAN bAutoMipMap */
                            FALSE               /* KMBOOLEAN bDither */
							);
	Check_Status(status, "kmLoadTexture");
    syFree (pTexture01);

	pTexture01 =  LoadTextureFile(TEX_NAME2);
    status = kmLoadTexture(&TexSurfaceDesc2,    /* PKMSURFACEDESC pSurfaceDesc */
                            pTexture01 + (16 / sizeof(KMDWORD)),            /* PKMDWORD pTexture */
                            FALSE,              /* KMBOOLEAN bAutoMipMap */
                            FALSE               /* KMBOOLEAN bDither */
							);
	Check_Status(status, "kmLoadTexture");
    syFree (pTexture01);

	pTexture01 =  LoadTextureFile(TEX_NAME3);
    status = kmLoadTexture(&TexSurfaceDesc3,    /* PKMSURFACEDESC pSurfaceDesc */
                            pTexture01 + (16 / sizeof(KMDWORD)),            /* PKMDWORD pTexture */
                            FALSE,              /* KMBOOLEAN bAutoMipMap */
                            FALSE               /* KMBOOLEAN bDither */
							);
	Check_Status(status, "kmLoadTexture");
    syFree (pTexture01);

	pTexture01 =  LoadTextureFile(TEX_NAME4);
    status = kmLoadTexture(&TexSurfaceDesc4,    /* PKMSURFACEDESC pSurfaceDesc */
                            pTexture01 + (16 / sizeof(KMDWORD)),            /* PKMDWORD pTexture */
                            FALSE,              /* KMBOOLEAN bAutoMipMap */
                            FALSE               /* KMBOOLEAN bDither */
							);
	Check_Status(status, "kmLoadTexture");
    syFree (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(TexSurfaceDesc3);

    /*----------------------------------------------------------------------------------- */
    /* 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 */
	switch(j % 3) {
	case 0:
        /* Set texture surface */
		VertexContext01.pTextureSurfaceDesc	= &TexSurfaceDesc2;
		break;
	case 1:
        /* Set texture surface */
		VertexContext01.pTextureSurfaceDesc	= &TexSurfaceDesc4;
        /* */
		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;
		break;
	case 2:
        /* 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;
		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)syMalloc(TexSurfaceDesc1.uSize.dwTextureSize + 16);  /* allocate mainmemory */
    memset(pTexture01,'A',TexSurfaceDesc1.uSize.dwTextureSize + 16);
	status = kmGetTexture(pTexture01 + (16 / sizeof(KMDWORD)), &TexSurfaceDesc1);
	Check_Status(status, "kmGetTexture #1");
    /* SaveTextureFile("txtest03.pvr", pTexture01, (TexSurfaceDesc1.dwTextureSize + 16)); */
    syFree (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");

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

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

	messagebox("** Test program terminated. **");

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

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