/****************************************************************************
 * RAGE128 Chapter 6 Sample Code                                            *
 *                                                                          *
 * fog.c - Functions to set fog 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 "fog.h"

extern CONTEXT3D gContext3D;
extern DWORD gCommandBuf[];


/****************************************************************************
 * R128_SetFogState 												        *
 *  Function: set an enumerated fog state.								    *
 *    Inputs: eFogState - EFOGSTATE enum of state to be set.			    *
 *			  data - state-sepcific data to be set.							*
 *   Outputs: TRUE - successful.                                            *
 *			  FALSE - unsuccessful.											*
 ****************************************************************************/

BOOL R128_SetFogState (EFOGSTATE eFogState, DWORD data)
{
    int i;
    char* pfogtable;
    i = 0;

	switch (eFogState)
	{

	// Enable fog.

	case FOGSTATE_ENABLE:

		if (data == FALSE)
		{
			gContext3D.regTEX_CNTL_C &= ~(TEX_CNTL_FOG_EN_ON);
		}
		else // assume non-zero as true
		{
			gContext3D.regTEX_CNTL_C |= TEX_CNTL_FOG_EN_ON;
		}

		// Set the TEX_CNTL_C:FOG_EN field.

		gCommandBuf[i++] = CCE_PACKET0 | (TEX_CNTL_C >> 2);
		gCommandBuf[i++] = gContext3D.regTEX_CNTL_C;
		break;

	// Set the fog mode.

	case FOGSTATE_MODE:

		if (data == (EFOGMODE)FOGMODE_VERTEX)
		{
			gContext3D.regMISC_3D_STATE_CNTL_REG &= ~(MISC_3D_STATE_FOG_TABLE_EN_TABLE_FOG);
		}
		else if (data == (EFOGMODE)FOGMODE_TABLE)
		{
			gContext3D.regMISC_3D_STATE_CNTL_REG |= MISC_3D_STATE_FOG_TABLE_EN_TABLE_FOG;
		}
		else 
			return FALSE;

		// Set the MISC_3D_STATE_CNTL_REG:FOG_TABLE_EN field. 

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

	// Set the fog color.

	case FOGSTATE_COLOR:

		// Set the FOG_COLOR_C register.

		gCommandBuf[i++] = CCE_PACKET0 | (FOG_COLOR_C >> 2);
		gCommandBuf[i++] = data;
		break;

	// Set the fog table.

	case FOGSTATE_TABLE:

        if ((pfogtable = (char*)data) == NULL)
			return FALSE;

        // Copy the fog table passed into this fanction.

        gCommandBuf[0] = CCE_PACKET0 | (FOG_TABLE_INDEX >> 2);
        gCommandBuf[1] = 0x00000000;
        gCommandBuf[2] = CCE_PACKET0 | CCE_PACKET_0_ONE_REG_WR |
			(FOG_TABLE_DATA >> 2);
        for (i=3; i < 259; i++)
		{
            gCommandBuf[i] = gContext3D.FOG_TABLE[i-3] = 
                (DWORD)(pfogtable[i-3]);
		}
        gCommandBuf[2] |= (255L << 16);
        R128_CCESubmitPackets (gCommandBuf, 259);
		return TRUE;

	// Set the fog start value for table fog.

	case FOGSTATE_START:

		// Set the FOG_3D_TABLE_START register.

		gContext3D.regFOG_3D_TABLE_START = data;
		gCommandBuf[i++] = CCE_PACKET0 | (FOG_3D_TABLE_START >> 2);
		gCommandBuf[i++] = gContext3D.regFOG_3D_TABLE_START;
		break;

	// Set the fog end value for table fog.

	case FOGSTATE_END:

		// Set the FOG_3D_TABLE_END register.

		gContext3D.regFOG_3D_TABLE_END = data;
		gCommandBuf[i++] = CCE_PACKET0 | (FOG_3D_TABLE_END >> 2);
		gCommandBuf[i++] = gContext3D.regFOG_3D_TABLE_END;
		break;

	// Set the fog density value for table fog.

	case FOGSTATE_DENSITY:

		// Set the FOG_3D_TABLE_DENSITY register.

		gContext3D.regFOG_3D_TABLE_DENSITY = data;
		gCommandBuf[i++] = CCE_PACKET0 | (FOG_3D_TABLE_DENSITY >> 2);
		gCommandBuf[i++] = gContext3D.regFOG_3D_TABLE_DENSITY;
		break;

	default:
		return FALSE;
	} // switch

	gCommandBuf[0] |= ((i - 2) << 16);
	R128_CCESubmitPackets (gCommandBuf, i);

	return TRUE;
}
