/***************************************************************************
 *                                                                         *
 * Module  : skyinst.h                                                     *
 *                                                                         *
 * Purpose : Custom instance stage for Playstation II                      *
 *                                                                         *
 **************************************************************************/

#ifndef SKYINST_H
#define SKYINST_H

/****************************************************************************
 Includes
 */

#include <eetypes.h>

#include "batypes.h"
#include "baimmedi.h"
#include "bacamera.h"

/****************************************************************************
 Defines
 */

/* RWPUBLIC */

/* Number of qWords in an inst vertex */
#define VERTEXSIZE 4

/* Size of various things for Vu1 dispatch (in qwords) */
#define PROLOGSIZE3D (17+2)
#define PROLOGSIZE2D (5+2)
#define COPYPKTSIZE 3
#define EPILOGSIZE 13

#define MAXVU1BATCHCNT 16

#if (MAXVU1BATCHCNT != 16) && (MAXVU1BATCHCNT != 8)
#error MAXVU1BATCHCNT must be 16 or 8
#endif /* MAXVU1BATCHCNT != 16 */

#if MAXVU1BATCHCNT == 16
#define MAXVU1BATCHCNTSHIFT 4
#define MAXVU1BATCHCNTMASK 0xf
#else /* MAXVU1BATCHCNT == 16 */
#define MAXVU1BATCHCNTSHIFT 3
#define MAXVU1BATCHCNTMASK 0x7
#endif /* MAXVU1BATCHCNT == 16 */

#define VU1DATABLOCKHIGH 0x3f0
#define VU1DATABLOCKLOW 0x3c3
#define VU1WATERMARK_VU1TRANS (MAXVU1BATCHCNT*3*VERTEXSIZE)
#define VU1_VU1TRANS_HBUFSIZE ((VU1LIGHTOFFSET-(MAXVU1BATCHCNT*3*VERTEXSIZE))>>1)
#define VU1WATERMARK_VU1TRANS1 (MAXVU1BATCHCNT*3*VERTEXSIZE)
#define VU1WATERMARK_VU1TRANS2 (VU1WATERMARK_VU1TRANS1+VU1_VU1TRANS_HBUFSIZE)
#define VU1WATERMARK_VU1TRANSL 272
#define VU1WATERMARK_VU1TRANSTS 272
#define VU1LIGHTOFFSET 0x3d0

/* Warning magic numbers ahoy. We transfer batches of up to 64 verts at a time
   This corresponds to 62 triangles, so the sums are abit messy.
 */
#define MAXTSLEN 62
#define MAXTSVERTS (MAXTSLEN+2)
/* WARNING: MAXTSVERTS must be divisible by 4 */

#if 1
/* Support for double buffered dispatch using path 2 */
#define VU1WATERMARK_VU1TRANSLMAP (VU1WATERMARK_VU1TRANSL+(((MAXTSLEN+1)>>1)+2)*3+1)
#define VU1TRANSLMAPGIF 0x3e2
#define VU1WATERMARK_VU1TRANSTSMAP (VU1WATERMARK_VU1TRANSTS+(((MAXTSLEN+1)>>1)+2)*3+1)
#define VU1TRANSTSMAPGIF 0x3e2
#else
/* Support for double buffered dispatch to allow a gloss/env map pass */
/* We halve the size of the output buffer, knowing that the map pass is */
/* 2 qw/v so will fit. This also allows us a buffer containing texture */
/* commands */
#define VU1WATERMARK_VU1TRANSLMAP (VU1WATERMARK_VU1TRANSL+(((MAXTSLEN+1)>>1)+2)*3+1)
#define VU1TRANSLMAPGIF (VU1WATERMARK_VU1TRANSLMAP+(((MAXTSLEN+1)>>1)+2)*2+1)
#define VU1TRANSLMAPSTATEMAIN (VU1WATERMARK_VU1TRANSLMAPGIF+1)
#define VU1TRANSLMAPSTATEMAP (((VU1LIGHTOFFSET-VU1WATERMARK_VU1TRANSLMAPSTATEMAIN+1)>>1)+VU1WATERMARK_VU1TRANSLMAPSTATEMAIN)

#define VU1WATERMARK_VU1TRANSTSMAP (VU1WATERMARK_VU1TRANSTS+(((MAXTSLEN+1)>>1)+2)*3+1)
#define VU1TRANSTSMAPGIF (VU1WATERMARK_VU1TRANSTSMAP+(((MAXTSLEN+1)>>1)+2)*2+1)
#define VU1TRANSTSMAPSTATEMAIN (VU1WATERMARK_VU1TRANSTSMAPGIF+1)
#define VU1TRANSTSMAPSTATEMAP (((VU1LIGHTOFFSET-VU1WATERMARK_VU1TRANSTSMAPSTATEMAIN+1)>>1)+VU1WATERMARK_VU1TRANSTSMAPSTATEMAIN)
#endif

/* Added on 00/07/21 by RP - copied from sky driver then modified for true clip tristrip support */
#define VU1_VU1TRANSTS_HBUFSIZE (((VU1LIGHTOFFSET >> 1 )-VU1WATERMARK_VU1TRANSTS)>>1)
#define VU1WATERMARK_VU1TRANSTS1 VU1WATERMARK_VU1TRANSTS
#define VU1WATERMARK_VU1TRANSTS2 (VU1WATERMARK_VU1TRANSTS1+VU1_VU1TRANSTS_HBUFSIZE)

/* This size used to be defined by the number of RxSkyTransTypeFlags
 * as flags were used directly as an index into the array. However,
 * this is no longer necessarily the case (since there are so many
 * flags these days and we have packed, multi-purpose transforms, and
 * different plugins use different subsets of flag combinations, etc).
 * This size may change or become obsolete (used only by the driver). */
#define VU1CODEARRAYSIZE 32

/**
 * \ingroup corep2sky2
 * \ref RxSkyTransTypeFlags
 * Flags specifying the desired behavior for the current VU1 transform.
 */
enum RxSkyTransTypeFlags
{
    rxSKYTRANSTYPENATRANSTYPE = 0,

    /* These correspond to bits in skyTransType.
     * They are used in the driver to select transforms from the VU1CodeArray.
     * The flags use to be used directly as the index into this array, but
     * this is no longer necessarily so (we have combined many permutations
     * into single, multi-purpose transforms and there are just too many flags
     * these days) index is specified separately (see \ref RxPS2DMASessionRecord) */
    rxSKYTRANSTYPEFOG  = 1,  /**< The transform should fog */
    rxSKYTRANSTYPECLIP = 2,  /**< The transform should clip (see \ref RpSkySelectTrueTSClipper) */
    rxSKYTRANSTYPELIST = 4,  /**< The transform should process triangles as trilists not tristrips */
    rxSKYTRANSTYPEISO  = 8,  /**< The transform should do orthogonal, not perspective, projection */
    rxSKYTRANSTYPELINE = 16, /**< The transform should process input data as lines, not triangles or points */
    rxSKYTRANSTYPECULL = 32, /**< The transform should do culling based on culling renderstate
                              *   (as opposed to always drawing front and back) */

    rxSKYTRANSTYPEFLAGSFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};

#define TRANSFOG  rxSKYTRANSTYPEFOG
#define TRANSCLIP rxSKYTRANSTYPECLIP
#define TRANSLIST rxSKYTRANSTYPELIST
#define TRANSISO  rxSKYTRANSTYPEISO
#define TRANSLINE rxSKYTRANSTYPELINE
#define TRANSCULL rxSKYTRANSTYPECULL
/* For documentation - remember not to test flags against these! */
#define TRANSNFOG  0
#define TRANSNCL   0
#define TRANSSTRIP 0
#define TRANSPER   0
#define TRANSTRI   0

/**
 * \ingroup corep2sky2
 * \typedef RxSkyTransTypeFlags
 * Typedef for the RxSkyTransTypeFlags enum
 */
typedef enum RxSkyTransTypeFlags RxSkyTransTypeFlags;


/****************************************************************************
 Global variables
 */

extern RwUInt8 skyTransType;

extern const void *skyUploadedCode;
extern void* skyVU1Transforms[VU1CODEARRAYSIZE] __attribute__ ((aligned(64)));

extern u_long128 nullLightCall;
extern u_long128 dma1Header128;
extern u_long128 maskCmd128;
extern u_long128 unmaskCmd128;
extern u_long128 runCmd128;
extern u_long128 contCmd128;
extern u_long128 dma1Ret128;
extern u_long128 gifTag128;
extern u_long128 gifTagPrim128;
extern u_long128 surfLightCoeffs;
extern u_long128 nullLightBlock[2];
extern u_long128 skyClipVect1;
extern u_long128 skyClipVect2;
extern u_long128 skyCClipVect1;
extern u_long128 skyCClipVect2;
extern RwUInt32  skyUserSwitch1;
extern RwUInt32  skyUserSwitch2;
extern RwBool    skyTSClipperMode;
extern RwBool    skyTLClipperMode;

/* RWPUBLICEND */


/* Driver Linear Fog Parameters */
/* Other bits of the driver need to access these */
extern RwBool   useFarClip;
extern RwReal   farFogPlane;

typedef RwBool (*openPktFn)(RwUInt32 batchCost,
                            RwUInt32 primCost,
                            RwUInt32 numPrims,
                            RwUInt32 primCode,
                            const void *code,
                            const RwMatrix *matrix);

extern RwBool (*overloadWorldPipes)(void);
extern RwBool (*unOverloadWorldPipes)(void);

/****************************************************************************
 Function prototypes
 */

/* RWPUBLIC */

#ifdef    __cplusplus
extern "C"
{
#endif                          /* __cplusplus */

extern RwBool openVU1SetupPkt(RwUInt32 primCode, const void *code, const RwMatrix *matrix,
                              const u_long128 *lightPkt, RwUInt32 lightPktLen);
/* This version is for use with newer pipelines (CPU-side and VU1). It is
 * used by PS2All and expects new vector code. It does not set up primitive
 * type, vector code, material color or surface properties (these should be
 * done in a RxPipelineNodePS2AllMatBridgeCallBack) and can take a NULL
 * matrix pointer. It has also been optimized (fewer DMA tags). */
extern RwBool openVU1SetupPktNew(const RwMatrix *matrix,
                                 const u_long128 *lightPkt,
                                 RwUInt32 lightPktLen);

/* RWPUBLICEND */

extern void _rwSkyPipeSetupForCamera(RwCamera *camera);

extern void _rwSkyOverloadPipelines(void);
extern void _rwSkyUnOverloadPipelines(void);

/* RWPUBLIC */

#ifdef    __cplusplus
}
#endif                          /* __cplusplus */

/* RWPUBLICEND */


#endif /* SKYINST_H */
