/*
Tested with LINT
*/
#include"gli_st.h"
#include "GLI_Defn.h"
#include "light_st.h"
#include "PvObj_st.h"
#include "PRF.h"
 
#ifdef __cplusplus
extern "C"
{
#endif
 
#define GLI_C_fMagicNumber	(16384.0f + 8192.0f) 
 
#define M_vComputeMagicColor()\
    stTempColor.xR = p_stGP->GLI_stColorsAdd.xR + GLI_C_fMagicNumber;\
    stTempColor.xG = p_stGP->GLI_stColorsAdd.xG + GLI_C_fMagicNumber;\
    stTempColor.xB = p_stGP->GLI_stColorsAdd.xB + GLI_C_fMagicNumber;\
    stTempColor.xA = p_stGP->GLI_stColorsAdd.xA + GLI_C_fMagicNumber;
/*
 ----------------------------------------------------------------------------------------
  Description   : compute screen color (not alpha) for some vertices (index of vertices are in list)
  Author        : Steve McCalla
  Optimized     : Yes - got rid of almost all branches
 ----------------------------------------------------------------------------------------
 */
void GLI_vSerialComputeVertexColorIndexedNoAlpha(GLI_tdstInternalGlobalValuesFor3dEngine *p_stGP, ACP_tdxIndex xNumber, ACP_tdxIndex *p_ListOfIndexes)
{
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    unsigned long *p_ulFirstColor;
    unsigned long Alpha;
    unsigned long ulRed, ulGreen, ulBlue;
    GEO_tdstColor stComputedColor,*p_SRCColors;
    GEO_tdstColor stTempColor;
    ACP_tdxIndex *p_ListOfIndexesLast;
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    
    M_vComputeMagicColor()
 
    p_ListOfIndexesLast = p_ListOfIndexes + xNumber;
    p_ulFirstColor = &p_stGP->GLI_ScreenPoint->ulPackedColor;
 
    Alpha = (*((unsigned long *)&stTempColor.xA) & 0x00400000) ? ( (*((unsigned long *)&stTempColor.xA) & 0x0000FF00) ? 0xFF : (*((unsigned long *)&stTempColor.xA) & 0x000000FF) ) : 0;
    Alpha <<= 24;
    
    while (p_ListOfIndexes < p_ListOfIndexesLast)
    {
        p_SRCColors = p_stGP->GLI_aDEF_stColorsRLID + *p_ListOfIndexes;
 
        stComputedColor.xR = p_SRCColors->xR * p_stGP->GLI_stColorsMul.xR + stTempColor.xR ;
        stComputedColor.xG = p_SRCColors->xG * p_stGP->GLI_stColorsMul.xG + stTempColor.xG ;
        stComputedColor.xB = p_SRCColors->xB * p_stGP->GLI_stColorsMul.xB + stTempColor.xB ;
 
        ulRed   = (*((unsigned long *)&stComputedColor.xR) & 0x00400000) ? ( (*((unsigned long *)&stComputedColor.xR) & 0x0000FF00) ? 0xFF0000 : (*((unsigned long *)&stComputedColor.xR) & 0x000000FF)<<16 ) : 0;
        ulGreen = (*((unsigned long *)&stComputedColor.xG) & 0x00400000) ? ( (*((unsigned long *)&stComputedColor.xG) & 0x0000FF00) ? 0xFF00   : (*((unsigned long *)&stComputedColor.xG) & 0x000000FF)<<8  ) : 0;
        ulBlue  = (*((unsigned long *)&stComputedColor.xB) & 0x00400000) ? ( (*((unsigned long *)&stComputedColor.xB) & 0x0000FF00) ? 0xFF     : (*((unsigned long *)&stComputedColor.xB) & 0x000000FF)     ) : 0;
        
        /* p_ulFirstColor + 4 * index because size of GLI_tdstAligned2DVector is 4*/
        *(p_ulFirstColor + ((*p_ListOfIndexes++) << 2)) = Alpha | ulRed | ulGreen | ulBlue;
    }
}
 
/*
 ----------------------------------------------------------------------------------------
  Description   : compute screen color (but not alpha) for a number of sequential vertices
  Author        : Steve McCalla
  Optimized     : Yes
 ----------------------------------------------------------------------------------------
 */
void GLI_vSerialComputeVertexColor2NoAlpha(GLI_tdstInternalGlobalValuesFor3dEngine *p_stGP, ACP_tdxIndex xNumber)
{
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    GLI_tdstAligned2DVector *p_Baseu32Colors;
    GEO_tdstColor stComputedColor,*p_SRCColors;
    GEO_tdstColor stTempColor;
    unsigned long ulRed, ulGreen, ulBlue;
    unsigned long Alpha;
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    
    M_vComputeMagicColor();
    
    p_Baseu32Colors = (GLI_tdstAligned2DVector *) &p_stGP->GLI_ScreenPoint->ulPackedColor;
    p_SRCColors = p_stGP -> GLI_aDEF_stColorsRLID;
 
    Alpha = (*((unsigned long *)&stTempColor.xA) & 0x00400000) ? ( (*((unsigned long *)&stTempColor.xA) & 0x0000FF00) ? 0xFF : (*((unsigned long *)&stTempColor.xA) & 0x000000FF) ) : 0;
    Alpha <<= 24;
    
    while (xNumber--)
    {
        stComputedColor.xR = p_SRCColors->xR * p_stGP->GLI_stColorsMul.xR + stTempColor.xR ;
        stComputedColor.xG = p_SRCColors->xG * p_stGP->GLI_stColorsMul.xG + stTempColor.xG ;
        stComputedColor.xB = p_SRCColors->xB * p_stGP->GLI_stColorsMul.xB + stTempColor.xB ;
 
        ulBlue  = (*((unsigned long *)&stComputedColor.xB) & 0x00400000) ? ( (*((unsigned long *)&stComputedColor.xB) & 0x0000FF00) ? 0xFF     : (*((unsigned long *)&stComputedColor.xB) & 0x000000FF)     ) : 0;
        ulRed   = (*((unsigned long *)&stComputedColor.xR) & 0x00400000) ? ( (*((unsigned long *)&stComputedColor.xR) & 0x0000FF00) ? 0xFF0000 : (*((unsigned long *)&stComputedColor.xR) & 0x000000FF)<<16 ) : 0;
        ulGreen = (*((unsigned long *)&stComputedColor.xG) & 0x00400000) ? ( (*((unsigned long *)&stComputedColor.xG) & 0x0000FF00) ? 0xFF00   : (*((unsigned long *)&stComputedColor.xG) & 0x000000FF)<<8  ) : 0;
        
        *(long *) p_Baseu32Colors++ = Alpha | ulRed | ulGreen | ulBlue;
        p_SRCColors++;
    }
}
 
/*
 ----------------------------------------------------------------------------------------
  Description   : compute screen color for all vertex when Light is alpha sensitive
  Author        : Steve McCalla
  Optimized     : Yes
 ----------------------------------------------------------------------------------------
 */
void GLI_vSerialComputeVertexColorIndexedAlpha(GLI_tdstInternalGlobalValuesFor3dEngine *p_stGP, ACP_tdxIndex xNumber, ACP_tdxIndex *p_ListOfIndexes)
{
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    unsigned long           *p_Baseu32Colors;
    GEO_tdstColor           stTempColor, stComputedColor;
    unsigned long           ulTmpColor;
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
    M_vComputeMagicColor();
 
    while (xNumber--)	
    {
        p_Baseu32Colors = &(p_stGP->GLI_ScreenPoint + *p_ListOfIndexes)->ulPackedColor;
        ulTmpColor = 0;
        stComputedColor.xR = (p_stGP -> GLI_aDEF_stColorsRLID + (*p_ListOfIndexes)) -> xR * p_stGP -> GLI_stColorsMul . xR + stTempColor.xR;
        stComputedColor.xG = (p_stGP -> GLI_aDEF_stColorsRLID + (*p_ListOfIndexes)) -> xG * p_stGP -> GLI_stColorsMul . xG + stTempColor.xG ;
        stComputedColor.xB = (p_stGP -> GLI_aDEF_stColorsRLID + (*p_ListOfIndexes)) -> xB * p_stGP -> GLI_stColorsMul . xB + stTempColor.xB;
        stComputedColor.xA = (p_stGP -> GLI_aDEF_stColorsRLID + (*p_ListOfIndexes)) -> xA * p_stGP -> GLI_stColorsMul . xA + stTempColor.xA ;
        
        if (*((long *)&stComputedColor.xR) & 0x00400000)
        {
            if (*((unsigned long *)&stComputedColor.xR) & 0x0000FF00) 
                ulTmpColor |= 0x00FF0000;
            else
                ulTmpColor |= (*((unsigned long *)&stComputedColor.xR) & 0x000000FF) << 16;
        }
        
        if (*((long *)&stComputedColor.xG) & 0x00400000)
        {
            if (*((unsigned long *)&stComputedColor.xG) & 0x0000FF00) 
                ulTmpColor |= 0x0000FF00;
            else
                ulTmpColor |= (*((unsigned long *)&stComputedColor.xG) & 0x000000FF) <<  8;
        }
        
        if (*((long *)&stComputedColor.xB) & 0x00400000)
        {
            if (*((unsigned long *)&stComputedColor.xB) & 0x0000FF00) 
                ulTmpColor |= 0x000000FF;
            else
                ulTmpColor |= (*((unsigned long *)&stComputedColor.xB) & 0x000000FF)      ;
        }
        
        if (*((long *)&stComputedColor.xA) & 0x00400000)
        {
            if (*((unsigned long *)&stComputedColor.xA) & 0x0000FF00) 
                ulTmpColor |= 0xFF000000;
            else
                ulTmpColor |= (*((unsigned long *)&stComputedColor.xA) & 0x000000FF) << 24;
        }
        *p_Baseu32Colors = ulTmpColor;
        p_ListOfIndexes++;
    }
}
 
/*
 ----------------------------------------------------------------------------------------
  Description   : compute screen color for all vertex when Light is alpha sensitive
  Author        : Steve McCalla
  Optimized     : No (not called very often)
 ----------------------------------------------------------------------------------------
 */
void GLI_vSerialComputeVertexColor2Alpha(GLI_tdstInternalGlobalValuesFor3dEngine *p_stGP, ACP_tdxIndex xNumber)
{
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    GLI_tdstAligned2DVector *p_Baseu32Colors;
    GEO_tdstColor           stTempColor ,stComputedColor,*p_SRCColors;
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    
    M_vComputeMagicColor();
    
    p_Baseu32Colors = p_stGP->GLI_ScreenPoint;
    p_SRCColors = p_stGP -> GLI_aDEF_stColorsRLID;
    
    while (xNumber--)
    {
        p_Baseu32Colors->ulPackedColor = 0;
        stComputedColor.xR = (p_SRCColors)  ->xR * p_stGP->GLI_stColorsMul.xR + stTempColor.xR;
        stComputedColor.xG = (p_SRCColors)  ->xG * p_stGP->GLI_stColorsMul.xG + stTempColor.xG;
        stComputedColor.xB = (p_SRCColors)  ->xB * p_stGP->GLI_stColorsMul.xB + stTempColor.xB;
        stComputedColor.xA = (p_SRCColors++)->xA * p_stGP->GLI_stColorsMul.xA + stTempColor.xA;
        if (*((long *)&stComputedColor.xR) & 0x00400000)
        {
            if (*((unsigned long *)&stComputedColor.xR) & 0x0000FF00) 
                p_Baseu32Colors->ulPackedColor |= 0x00FF0000;
            else
                p_Baseu32Colors->ulPackedColor |= (*((unsigned long *)&stComputedColor.xR) & 0x000000FF) << 16;
        }
        if (*((long *)&stComputedColor.xG) & 0x00400000)
        {
            if (*((unsigned long *)&stComputedColor.xG) & 0x0000FF00) 
                p_Baseu32Colors->ulPackedColor |= 0x0000FF00;
            else
                p_Baseu32Colors->ulPackedColor |= (*((unsigned long *)&stComputedColor.xG) & 0x000000FF) <<  8;
        }
        if (*((long *)&stComputedColor.xB) & 0x00400000)
        {
            if (*((unsigned long *)&stComputedColor.xB) & 0x0000FF00) 
                p_Baseu32Colors->ulPackedColor |= 0x000000FF;
            else
                p_Baseu32Colors->ulPackedColor |= (*((unsigned long *)&stComputedColor.xB) & 0x000000FF)      ;
        }
        if (*((long *)&stComputedColor.xA) & 0x00400000)
        {
            if (*((unsigned long *)&stComputedColor.xA) & 0x0000FF00) 
                p_Baseu32Colors->ulPackedColor |= 0xFF000000;
            else
                p_Baseu32Colors->ulPackedColor |= (*((unsigned long *)&stComputedColor.xA) & 0x000000FF) << 24;
        }
        p_Baseu32Colors++;
    }
}
 
 
 
#ifdef __cplusplus
}/* extern "C" */
#endif
