#include <shinobi.h>
#include <kamui2.h>
#include <kmutil.h>
#include <sg_sycbl.h>
#include <sg_sytmr.h>
#include "dispstrex.h"
#include "key.h"

/* Read From Texture */
extern KMSURFACEDESC Texture[];

#define TEXTUREMEMORYSIZE 	(0x400000)
#define VERTEXBUFFERSIZE	(0x80000)
#define TEXTUREBUFSIZE		(256 * 256 * 2 + 2048)

/*
	Prototypes
*/
Int UserMain(void);
Int UserInit(void);

/*
	Global Params
*/

KMVERTEXBUFFDESC 		VertexBufferDesc;
KMSYSTEMCONFIGSTRUCT 	SystemConfig;
KMSURFACEDESC           PrimarySurfaceDesc;
KMSURFACEDESC           BackSurfaceDesc;

NJS_PERIPHERAL 			*per;

KMDWORD					frameCount = 0;

void main(void)
{
    SYE_CBL_CABLE cable;

	/* Initialize Video Mode */
    cable = syCblCheckCable();
    if (cable == SYE_CBL_CABLE_VGA) {
		sbInitSystem((int)KM_DSPMODE_VGA, (int)KM_DSPBPP_RGB565, 1);
    } else {
		sbInitSystem((int)KM_DSPMODE_NTSCNI640x480, (int)KM_DSPBPP_RGB565, 1);
    }

	UserInit();

	/* Render Loop */
	while(UserMain())
	{
		pdExecPeripheralServer();
	}
	sbExitSystem();
}

/*
*		Init
*/
Int UserInit(void)
{
	PKMSURFACEDESC	pFB[2];
	KMWORKAREASIZE	TexWorkArea;
	KMPACKEDARGB	BorderColor;

	pFB[0] = &PrimarySurfaceDesc;
	pFB[1] = &BackSurfaceDesc;
	SystemConfig.dwSize				=	sizeof(KMSYSTEMCONFIGSTRUCT);
	SystemConfig.flags				=	KM_CONFIGFLAG_NOWAITVSYNC | KM_CONFIGFLAG_ENABLE_CLEAR_FRAMEBUFFER | KM_CONFIGFLAG_ENABLE_2V_LATENCY;
	SystemConfig.pBufferDesc 		= 	&VertexBufferDesc;
	SystemConfig.ppSurfaceDescArray	=	pFB;
	SystemConfig.fb.nNumOfFrameBuffer	=	2;
	SystemConfig.nNumOfVertexBank	=	2;
	SystemConfig.nPassDepth			= 	2;

	/*
		Texture Memory Settings 
	*/
	SystemConfig.nTextureMemorySize = 	TEXTUREMEMORYSIZE;	/* Texture 4MB */

	TexWorkArea.dwNumberOfFameBuffes 	= SystemConfig.fb.nNumOfFrameBuffer;		/* Number of Frame buffers */
	TexWorkArea.dwNumberOfNativeBuffers	= 2;										/* Number of Native buffer */
	TexWorkArea.dwNumberOfTextures		= 1024;			/* Number of Textures (No small VQ) */
	TexWorkArea.dwNumberOf8x8SmallVQ	= 0;		/* Number of 8x8 small VQ texture */
	TexWorkArea.dwNumberOf8x8SmallVQmm	= 0;		/* Number of 8x8 small VQ mipmap texture */
	TexWorkArea.dwNumberOf16x16SmallVQ	= 0;		/* Number of 16x16 small VQ texture */
	TexWorkArea.dwNumberOf16x16SmallVQmm= 0;	/* Number of 16x16 small VQ mipmap texture */
	TexWorkArea.dwNumberOf32x32SmallVQ	= 0;		/* Number of 32x32 small VQ texture */
	TexWorkArea.dwNumberOf32x32SmallVQmm= 0;	/* Number of 32x32 small VQ mipmap texture */
	TexWorkArea.dwNumberOf64x64SmallVQ	= 0;		/* Number of 64x64 small VQ texture */
	TexWorkArea.dwNumberOf64x64SmallVQmm= 0;	/* Number of 64x64 small VQ mipmap texture */
	kmuCalculateKamuiWorkareaSize( &TexWorkArea );

	SystemConfig.nNumOfTextureStruct 	= 1024;
	SystemConfig.nNumOfSmallVQStruct 	= 0;
	SystemConfig.pTextureWork			= (PKMDWORD)syMalloc(TexWorkArea.dwKamuiWorkareaSize);

	/*
		Vertex Buffer Settings 
	*/
	SystemConfig.pVertexBuffer 			= (PKMDWORD)(((KMDWORD)syMalloc(VERTEXBUFFERSIZE) & 0x0FFFFFFFUL ) | 0xA0000000UL);
										  /* Map to Cache Through Area */
	SystemConfig.nVertexBufferSize 		= VERTEXBUFFERSIZE;

	/* 1Pass */
	SystemConfig.Pass[0].dwRegionArrayFlag = KM_PASSINFO_AUTOSORT;
	SystemConfig.Pass[0].nDirectTransferList = KM_OPAQUE_POLYGON;
	SystemConfig.Pass[0].fBufferSize[0] =   0.0f;
	SystemConfig.Pass[0].fBufferSize[1] =   0.0f;
	SystemConfig.Pass[0].fBufferSize[2] = 100.0f;
	SystemConfig.Pass[0].fBufferSize[3] =   0.0f;
	SystemConfig.Pass[0].fBufferSize[4] =   0.0f;

	/* 2Pass for Information */

	SystemConfig.Pass[1].dwRegionArrayFlag = KM_PASSINFO_PRESORT;
	SystemConfig.Pass[1].nDirectTransferList = KM_TRANS_POLYGON;
	SystemConfig.Pass[1].fBufferSize[0] =   0.0f;
	SystemConfig.Pass[1].fBufferSize[1] =   0.0f;
	SystemConfig.Pass[1].fBufferSize[2] =   0.0f;
	SystemConfig.Pass[1].fBufferSize[3] =   0.0f;
	SystemConfig.Pass[1].fBufferSize[4] =   0.0f;

	BorderColor.dwPacked = 0x00000000;
	kmSetBorderColor(BorderColor);

	kmSetSystemConfiguration(&SystemConfig);
	txt_InitDisplayString();
	txt_ClearScreen();		/* Clear text screen	*/
	PRINTOUT(("Dreamcast Console Version 0.01 Alpha\n"));
	PRINTOUT(("Programmed by M.Imanishi and S.Ohya\n"));
	PRINTOUT((">"));

	/* Init Command */
	InitializeCommand();

	InitMemCommand();			/* mem */
	InitBorderCommand();		/* bordar */
	InitClsCommand();			/* cls */
	InitHelpCommand();			/* Help or ? */

}

/*
*		Main Loop
*/
Int UserMain(void)
{
	KeyBoardServer();							/* キーボードサーバーを呼ぶ */
	ExecutePreprocess();						/* Preprocessサーバーを呼ぶ */

	kmBeginScene(&SystemConfig);
	{
		/* 1Pass */
		kmBeginPass(&VertexBufferDesc);
		{
			ExecuteDrawCommand(&VertexBufferDesc);
		}kmEndPass(&VertexBufferDesc);

		/* 2Pass */
		kmBeginPass(&VertexBufferDesc);
		{
			txt_DispScreen(&VertexBufferDesc);		/* Display screen */
		}kmEndPass(&VertexBufferDesc);

		kmRender(KM_RENDER_FLIP);
	}kmEndScene(&SystemConfig);

	frameCount++;
	return 1;
}
