/****************************************************************************
 * RAGE128 Chapter 6 Sample Code                                            *
 *                                                                          *
 * alphblnd.c - Functions for setting alpha blending states.                * 
 *                                                                          *
 * Copyright (c) 1999 ATI Technologies Inc.  All rights reserved.           *
 ****************************************************************************/

#include <stdio.h>
#include "..\..\util\regdef.h"
#include "..\..\util\defines.h"
#include "..\..\util\main.h"
#include "..\..\util\cce.h"
#include "cntx3d.h"
#include "alphblnd.h"

extern CONTEXT3D gContext3D;
extern DWORD gCommandBuf[];

	
/****************************************************************************
 * R128_SetAlphaBlendState									                *
 *  Function: set an enumerated alpha blending state.                       *
 *    Inputs: eAlphaBlendState - EALPHABLENDSTATE enum of state to be set.	*
 *			  data - state-sepcific data to be set.							*
 *   Outputs: TRUE - successful.                                            *
 *			  FALSE - unsuccessful.											*
 ****************************************************************************/

BOOL R128_SetAlphaBlendState (EALPHABLENDSTATE eAlphaBlendState, DWORD data)
{
	int i = 0;

	switch (eAlphaBlendState)
	{
	// Enable alpha blending.

	case ALPHABLENDSTATE_ENABLE:

		if (data == FALSE)
		{
			gContext3D.regTEX_CNTL_C &= ~(TEX_CNTL_ALPHA_EN_ON);
		}
		else
		{
			gContext3D.regTEX_CNTL_C |= TEX_CNTL_ALPHA_EN_ON;
		}

		// Set TEX_CNTL_C:ALPHA_EN field.

		gCommandBuf[i++] = CCE_PACKET0 | (TEX_CNTL_C >> 2);
		gCommandBuf[i++] = gContext3D.regTEX_CNTL_C;
		R128_CCESubmitPackets (gCommandBuf, i);
		return TRUE;

	// Set source blending factor.

	case ALPHABLENDSTATE_SRCBLEND:

		switch ((EBLEND)data)
		{
		case BLEND_ZERO:
		case BLEND_ONE:
		case BLEND_SRCCOLOR:
		case BLEND_INVSRCCOLOR:
		case BLEND_SRCALPHA:
		case BLEND_INVSRCALPHA:
		case BLEND_DSTALPHA:
		case BLEND_INVDSTALPHA:
		case BLEND_DSTCOLOR:
		case BLEND_INVDSTCOLOR:
		case BLEND_SRCALPHASAT:
		case BLEND_BOTHSRCALPHA:
		case BLEND_BOTHINVSRCALPHA:
        case BLEND_SRCSRCALPHA_DSTINVSRCALPHA:
        case BLEND_SRCINVSRCALPHA_DSTSRCALPHA:
			break;

		default:
            return FALSE;
		}

		// Set MISC_3D_STATE_CNTL_REG:ALPHA_BLEND_SRC field.

		gContext3D.regMISC_3D_STATE_CNTL_REG &= ~(0x0000000f << 16);
		gContext3D.regMISC_3D_STATE_CNTL_REG |= (data << 16);
		break;

	// Set destination blending factor.

	case ALPHABLENDSTATE_DSTBLEND:

		switch ((EBLEND)data)
		{
		case BLEND_ZERO:
		case BLEND_ONE:
		case BLEND_SRCCOLOR:
		case BLEND_INVSRCCOLOR:
		case BLEND_SRCALPHA:
		case BLEND_INVSRCALPHA:
		case BLEND_DSTALPHA:
		case BLEND_INVDSTALPHA:
		case BLEND_DSTCOLOR:
		case BLEND_INVDSTCOLOR:
		case BLEND_SRCALPHASAT:
			break;

		default:
            return FALSE;
		}

		// Set MISC_3D_STATE_CNTL_REG:ALPHA_BLEND_DST field.

		gContext3D.regMISC_3D_STATE_CNTL_REG &= ~(0x0000000f << 20);
		gContext3D.regMISC_3D_STATE_CNTL_REG |= (data << 20);
		break;

	// Set alpha blending combine function.

	case ALPHABLENDSTATE_COMBFNC:

		switch ((ECOMBFNC) data)
		{
		case COMBFNC_ADD_CLAMP:
		case COMBFNC_ADD_NOCLAMP:
		case COMBFNC_SUB_DSTSRC_CLAMP:
		case COMBFNC_SUB_DSTSRC_NOCLAMP:
			break;

		default:
            return FALSE;
		}

		// Set MISC_3D_STATE_CNTL_REG:ALPHA_COMB_FCN field.

		gContext3D.regMISC_3D_STATE_CNTL_REG &= ~(0x00000003 << 12);
		gContext3D.regMISC_3D_STATE_CNTL_REG |= (data << 12);
		break;

	default:
        return FALSE;
	} // switch

	// Submit MISC_3D_STATE_CNTL_REG.

	gCommandBuf[i++] = CCE_PACKET0 | (MISC_3D_STATE_CNTL_REG >> 2);
	gCommandBuf[i++] = gContext3D.regMISC_3D_STATE_CNTL_REG;
	R128_CCESubmitPackets (gCommandBuf, i);

	return TRUE;
}
