//=============================================================================
//
// Copyright 1998 by Captivation Digital Laboratories, Inc.
// All Rights Reserved.
//
//=============================================================================
//
// "KRAD" -- Kamui Rendering/Animation Demonstration
//
// Implementation of the C++ wrapper around Kamui
//
//=============================================================================
//-----------------------------------------------------------------------------
// $Revision: 4 $
// $NoKeywords: $
//=============================================================================

#include "krad.h"
#include "kamuipp.h"
#include "globals.h"

//=============================================================================	::CheckKamuiError()
// returns true if an error is caught
//
// this function is automatically called by the "KAMUI_TRY(x)" macro
//-----------------------------------------------------------------------------
bool CheckKamuiError	(	KMSTATUS	status,
							char*		command,
							char*		filename,
							int			linenum
						)
{
	if (status==KMSTATUS_SUCCESS)
		return false;

	infoout << "KAMUI: ";

	switch (status)
	{
		case KMSTATUS_SUCCESS:
			return(false);
			break;

		case KMSTATUS_INVALID_DISPLAY_MODE:		infoout << "KMSTATUS_INVALID_DISPLAY_MODE";		break;
		case KMSTATUS_INVALID_VIDEO_MODE:		infoout << "KMSTATUS_INVALID_VIDEO_MODE";		break;
		case KMSTATUS_NOT_ENOUGH_MEMORY:		infoout << "KMSTATUS_NOT_ENOUGH_MEMORY";		break;
		case KMSTATUS_INVALID_TEXTURE_TYPE:		infoout << "KMSTATUS_INVALID_TEXTURE_TYPE";		break;
		case KMSTATUS_INVALID_MIPMAPED_TEXTURE:	infoout << "KMSTATUS_INVALID_MIPMAPED_TEXTURE";	break;
		case KMSTATUS_CANT_FLIP_SURFACE:		infoout << "KMSTATUS_CANT_FLIP_SURFACE";		break;
		case KMSTATUS_INVALID_ADDRESS:			infoout << "KMSTATUS_INVALID_ADDRESS";			break;
		case KMSTATUS_HARDWARE_NOT_PRESENTED:	infoout << "KMSTATUS_HARDWARE_NOT_PRESENTED";	break;
		case KMSTATUS_INVALID_SETTING:			infoout << "KMSTATUS_INVALID_SETTING";			break;
		case KMSTATUS_INVALID_VERTEX_TYPE:		infoout << "KMSTATUS_INVALID_VERTEX_TYPE";		break;
		case KMSTATUS_INVALID_LIST_TYPE:		infoout << "KMSTATUS_INVALID_LIST_TYPE";		break;
		case KMSTATUS_NOT_IMPLEMENTED:			infoout << "KMSTATUS_NOT_IMPLEMENTED";			break;
		case KMSTATUS_INVALID_PARAMETER:		infoout << "KMSTATUS_INVALID_PARAMETER";		break;
		default:
			infoout << "UNKNOWN ERROR IN STATUS";
			break;
	}

	infoout << endl;
	infoout << "\tFile: " << filename << "(line " << linenum << ")" << endl;
	infoout << "\t" << command << endl;

	return true;
}

//=============================================================================
//============================================================================= CALLBACKS
//=============================================================================

//============================================================================= EORCallback
// End of Render
//-----------------------------------------------------------------------------
void KamuiEORCallback (void*)
{
	theKamui->EORLine() = theKamui->ReadScanline();
	theKamui->EORCount()++;
}

//============================================================================= EOVCallback()
// End of Vertex Transfer
//-----------------------------------------------------------------------------
void KamuiEOVCallback (void*)
{
	theKamui->EOVLine() = theKamui->ReadScanline();
}

//============================================================================= VBLCallback()
// Start of VSync
//-----------------------------------------------------------------------------
void KamuiVBLCallback (void*)
{
	theKamui->VBLLine() = theKamui->ReadScanline();
	theKamui->VBLCount()++;
}

//=============================================================================
//=============================================================================	CLASS KKamui
//=============================================================================

//============================================================================= KKamui::Kamui()
// The constructor basically just initializes the system
//-----------------------------------------------------------------------------
KKamui::KKamui	(	KMINT32			nKForOpaquePoly,
			  		KMINT32			nKForOpaqueMod,
					KMINT32			nKForTransPoly,
					KMINT32			nKForTransMod,
					KMVIDEOMODE		nVideoMode,
					KMDISPLAYMODE	nDisplayMode,
					KMBPPMODE		nBpp,
					KMBOOLEAN		nDither,
					KMBOOLEAN		nAntiAlias
				)
:	mVBLCount		(0),
	mEORCount		(0),
	mEORLine		(0),
	mEOVLine		(0),
	mVBLLine		(0)
{
	// -- Initialize the hardware --
	KAMUI_TRY (kmResetRenderer	());
	KAMUI_TRY (kmInitDevice		(nVideoMode));
	KAMUI_TRY (kmSetDisplayMode (nDisplayMode, nBpp, nDither, nAntiAlias));

	// -- Allocate vertex buffer / TABuffer --
	#ifdef KAMUI_DIRECT
	KAMUI_TRY (kmCreateTABuffer 	(	&mVertBuff,
										(nKForOpaquePoly+nKForOpaqueMod+nKForTransPoly+nKForTransMod)*1024));
	#else
	KAMUI_TRY (kmCreateVertexBuffer (	&mVertBuff,
										nKForOpaquePoly*1024/4,
										nKForOpaqueMod *1024/4,
										nKForTransPoly *1024/4,
										nKForTransMod  *1024/4  ));
	#endif

	// -- make the frame buffers --
	KAMUI_TRY	(kmCreateFrameBufferSurface (&mFrontBuffer,0, 0, FALSE, FALSE));
	KAMUI_TRY	(kmCreateFrameBufferSurface (&mBackBuffer, 0, 0, FALSE, FALSE));
	KAMUI_TRY	(kmActivateFrameBuffer		(&mFrontBuffer, &mBackBuffer, FALSE, FALSE));

	// -- Get version information and output --
	KMVERSIONINFO ver;
	KAMUI_TRY (kmGetVersionInfo(&ver));

    infoout << "Kamui Major Version: " << ver.kmMajorVersion;
    switch (ver.kmMajorVersion)
    {
        case 1: infoout << " [ARC1 - PC]";
                break;
        case 2: infoout << " [ARC1 - SH]";
                break;
        case 3: infoout << " [HOLLY]";
                break;
        default:
                infoout << " [UNKNOWN]";
                break;
    }

	infoout << endl;
	infoout << "Local Version: 0x" << hex << ver.kmLocalVersion << endl;
	infoout << "FrameBufferSize: 0x" << hex << ver.kmFrameBufferSize << " bytes" << endl;
}

//============================================================================= KKamui::~Kamui()
//-----------------------------------------------------------------------------
KKamui::~KKamui()
{

}

//============================================================================= KKamui::EnableCallbacks()
//-----------------------------------------------------------------------------
void KKamui::EnableCallbacks(void)
{
	// -- setup callbacks --
	KAMUI_TRY (kmSetEORCallback			(KamuiEORCallback, NULL));
	KAMUI_TRY (kmSetVSyncCallback		(KamuiVBLCallback, NULL));
	KAMUI_TRY (kmSetEndOfVertexCallback	(KamuiEOVCallback, NULL));
}

//=============================================================================	END-OF-FILE