/*----------------------------------------------------------------------*/
/*-                             Includes                               -*/
/*----------------------------------------------------------------------*/
#include <rpdbgerr.h>
#include <archive/rpmatfx310.h>

#include "../../driver/sky2/baasm.h"

#include "rpplugin.h"
#include "effectPipes.h"
#include "effectPipesSky.h"

#include "SKY2_AlphaBlender/dualPassPipe.h"
#include "SKY2_AlphaBlender/stddata.h"

#if (!defined(DOXYGEN))
static const char rcsid[] __RWUNUSED__ = 
    "@@@@(#)$Id: dualPassPipe.c,v 1.13 2001/09/26 10:48:07 johns Exp $";
#endif /* (!defined(DOXYGEN)) */

/*----------------------------------------------------------------------*/
/*-                                Definition                          -*/
/*----------------------------------------------------------------------*/

#define RWALIGN_skyAlphaBlenderTransforms \
        RWALIGN(skyAlphaBlenderTransforms, rpMATFXALIGNMENT) 

matFXVUcode 
RWALIGN_skyAlphaBlenderTransforms =
{
    &AlphaBlenderPRS, &vu1nullTrans,
    &AlphaBlenderPRL, &vu1nullTrans,
    &vu1nullTrans,    &vu1nullTrans, &vu1nullTrans, &vu1nullTrans,
    &vu1nullTrans,    &vu1nullTrans, &vu1nullTrans, &vu1nullTrans,
    &vu1nullTrans,    &vu1nullTrans, &vu1nullTrans, &vu1nullTrans,
    &vu1nullTrans,    &vu1nullTrans, &vu1nullTrans, &vu1nullTrans,
    &vu1nullTrans,    &vu1nullTrans, &vu1nullTrans, &vu1nullTrans,
    &vu1nullTrans,    &vu1nullTrans, &vu1nullTrans, &vu1nullTrans,
    &vu1nullTrans,    &vu1nullTrans, &vu1nullTrans, &vu1nullTrans
};

/*----------------------------------------------------------------------*/
/*-                                Functions                           -*/
/*----------------------------------------------------------------------*/
RwBool
_rpMatFXDualInstanceCallBack( void **clusterData,
                              RwUInt32 __RWUNUSED__ numClusters )
{
    /* --------------- Pipe --------------------------------------*/
    RxPS2Mesh                      *mesh = (RxPS2Mesh *)clusterData[0];
    RxPS2DMASessionRecord *dmaSessionRec = (RxPS2DMASessionRecord *)clusterData[1];
    rpMatFXMaterialData    *materialData = 
                (rpMatFXMaterialData *)*MATFXMATERIALGETDATA(mesh->mesh->material);
    /* --------------- Dual --------------------------------------*/
    RwTexture          *texture = (RwTexture *) NULL;
    RwTexture          *basetex = (RwTexture *) NULL;
    RwUInt64            alpha_2;
    RwUInt64            clamp_2;
    RwUInt64            test_2;
    RwUInt64            primSwitch = 0x4l;
    RwUInt64            fogSwitch  = 0x0l;

    RWFUNCTION(RWSTRING("_rpMatFXDualInstanceCallBack"));
    RWASSERT(mesh);
    RWASSERT(materialData);

    /* Grab our data. */
    texture = materialData->data[rpSECONDPASS].data.dual.texture;
    alpha_2 = materialData->data[rpSECONDPASS].data.dual.alpha_2;
    clamp_2 = materialData->data[rpSECONDPASS].data.dual.clamp_2;
    test_2  = materialData->data[rpSECONDPASS].data.dual.test_2;

    /*---- 2nd Context prim setting ----*/
    if (dmaSessionRec->transType & 4)
    {
        primSwitch = 0x3l;
    }
    /*---- 2nd context fog setting -----*/
    if (dmaSessionRec->transType & 1)
    {
        fogSwitch = 0x1l;
    }
    {
        RwUInt128           ltmp    = 0;
        RwUInt64            prim    = 0x0l;
        RwUInt64            rastex1 = 0;
        RwUInt64            rastex2 = 0;
        RwUInt64            tmp, tmp1;
        RwUInt32			val1, val2;

		/*--- Need to upload the base texture ---*/
		basetex = mesh->mesh->material->texture;
        if (NULL != basetex)
        {
	        _rpMatFXUploadTexture(basetex, dmaSessionRec, mesh);
	        skyTexGetTex0(basetex->raster, &val1, &val2); 
	        rastex1 = ((RwUInt64) val1 << 32) | val2; 
	    }
	    
        /*------ Upload the second texture ------*/
        if (NULL != texture)
        {
	        skyTexCacheAccessRaster(texture->raster, TRUE);
  	        skyTexGetTex0(texture->raster, &val1, &val2);
    	    rastex2 = ((RwUInt64) val1 << 32) | val2;            

            if ((texture->raster->depth <=8) && (basetex)
                && (basetex->raster->depth <= 8))
            {
                skyTextureRaster = (RwRaster*)-1;
            }
        }
        
        /*------ DMA data transfer --------------*/
        sweFinaliseOpenLocalPkt((int) (SWE_PKT_DMA_MODE_CHAIN_TTE |
                                       SWE_PKT_LOCAL |
                                       SWE_PKT_VU1 |
                                       SWE_PKT_CIRCALLOC), /**/ -12 /**/);
        if (!sweLocalPacket)
        {
            RWRETURN(FALSE);
        }                                       
        tmp  = ((1l << 28)      | (/**/  10  /**/));
        tmp1 = ((((0x6cl << 24) | (/**/  5   /**/ << 16) |
               ((long) (pipeASymbStaticDualPassStart))) << 32) |
               ((1l << 24) | (4 << 8) | (4)));
        MAKE128(ltmp, tmp1, tmp);
        SWEADDCONTFAST(ltmp);

        /*------ 2nd Context Giftag -------------*/
        prim = ( /* fix  */ 0x0l << 10        |
                 /* ctxt */ 0x1l << 9         |
                 /* fst  */ 0x0l << 8         |
                 /* aa1  */ 0x0l << 7         |
                 /* abe  */ 0x1l << 6         |
                 /* fge  */ fogSwitch << 5    |
                 /* tme  */ 0x1l << 4         |
                 /* iip  */ 0x1l << 3         |
                 /* prim */ primSwitch << 0);
        tmp  = ( /* regs */ 0x3l << (60 - 32) |
                 /* flg  */ 0x0l << (58 - 32) |
                 /* prim */ prim << (47 - 32) |
                 /* pre  */ 0x1l << (46 - 32)) << 32;
        MAKE128(ltmp, 0x412l, tmp);
        SWEADDCONTFAST(ltmp);

        /*--------- Palette info context 1 ------------------*/
        tmp  = /* NLOOP */  1l
             | /* EOP   */ (1l << 15)
             | /* PRE   */ (0l << 46)
             | /* FLG   */ (0l << 58)
             | /* NREG  */ (1l << 60);
        MAKE128(ltmp, 0xel, tmp);
        SWEADDCONTFAST(ltmp);
        MAKE128(ltmp, GS_TEX0_1, rastex1);
        SWEADDCONTFAST(ltmp);

        /*--------- Palette info context 2 ------------------*/
        tmp  = /* NLOOP */ 1l
             | /* EOP   */ (1l << 15)
             | /* PRE   */ (0l << 46)
             | /* FLG   */ (0l << 58)
             | /* NREG  */ (1l << 60);
        MAKE128(ltmp, 0xel, tmp);
        SWEADDCONTFAST(ltmp);
        MAKE128(ltmp, GS_TEX0_2, rastex2);
        SWEADDCONTFAST(ltmp);

        /*------------ Padding ------------------------------*/
        tmp  = VIFCMD_NOP   | (VIFCMD_NOP << 32);
        tmp1 = (VIFCMD_NOP) | ((VIFCMD_DIRECT | /**/ 4 /**/) << 32);
        MAKE128(ltmp, tmp1, tmp);
        SWEADDCONTFAST(ltmp);
        /*---------------------------------------------------*/

        /*------------- Second Context Registers ------------*/
        tmp  = /* NLOOP */ 3l
             | /* EOP   */ (1l << 15)
             | /* PRE   */ (0l << 46)
             | /* FLG   */ (0l << 58)
             | /* NREG  */ (1l << 60);
        MAKE128(ltmp, 0xel, tmp);
        SWEADDCONTFAST(ltmp);
        MAKE128(ltmp, GS_ALPHA_2, (8l << 32) | alpha_2);
        SWEADDCONTFAST(ltmp);
        MAKE128(ltmp, GS_CLAMP_2, clamp_2);
        SWEADDCONTFAST(ltmp);
        MAKE128(ltmp, GS_TEST_2,  test_2);
        SWEADDCONTFAST(ltmp);

        /*------- Terminate the DMA with an interrupt -------*/
        MAKE128(ltmp, 0l, (0xfl << 28));
        SWEADDCONTFAST(ltmp);

        /*---------------------------------------------------*/
        sweFinaliseOpenLocalPkt(SWE_LPS_CONT, 0);
    }
    RWRETURN(TRUE);
}
