/****************************************************************************
 *                                                                          *
 * module : nodeps2manager.h                                                *
 *                                                                          *
 * purpose: see nodeps2manager.c                                            *
 *                                                                          *
 ****************************************************************************/

#ifndef NODEPS2MANAGER_H
#define NODEPS2MANAGER_H

#include <rwcore.h>

#include "bamesh.h"
#include "wrldpipe.h"

#include "nodeps2objallinone.h"

/****************************************************************************
 global types
 */

/* RWPUBLIC */

/**
 * \ingroup rpworldp2sky2
 * \ref RxPipelineNodePS2ManagerInstanceCallBack is the callback to be called,
 * for the owning PS2Manager pipeline node, after standard instancing
 * has occurred. Within this callback, code may instance data for user
 * clusters and setup other DMA data (such as a second texture to upload
 * for use in environment mapping).
 *
 * This callback will receive pointers to cluster data for all clusters
 * (requested through \ref RxPipelineNodePS2ManagerGenerateCluster) which
 * have CL_ATTRIB_READ or CL_ATTRIB_WRITE attributes. This is guaranteed
 * to include, in addition to user-generated clusters, the \ref RxPS2Mesh
 * cluster (placed first in the array) and the \ref RxPS2DMASessionRecord
 * cluster (placed second in the array). Even if there are no other
 * user-generated clusters with CL_ATTRIB_READ or CL_ATTRIB_WRITE
 * attributes, the callback is still called.
 *
 * If the callback returns FALSE then the current mesh will not be
 * rendered. The rest of the object's meshes will be processed as normal.
 *
 * \param  clusterData   An array of pointers to the data of
 * clusters with CL_ATTRIB_READ or CL_ATTRIB_WRITE attributes.
 * \param  numClusters   A count of the number of pointers
 * in the clusterData array. This value is guaranteed to be at least two.
 *
 * \return TRUE to continue rendering, FALSE to skip rendering this mesh.
 *
 * \see RxPipelineNodePS2ManagerSetInstanceCallBack
 * \see RxPipelineNodePS2ManagerSetPostObjectCallBack
 * \see RxPipelineNodePS2ManagerGenerateCluster
 */
typedef RwBool (*RxPipelineNodePS2ManagerInstanceCallBack) (void **clusterData,
                                                            RwUInt32 numClusters);

/* LEGACY-SUPPORT define for old typedef name */
#define RxNodePS2ManagerInstanceCallBack RxPipelineNodePS2ManagerInstanceCallBack


/**
 * \ingroup rpworldp2sky2
 * \ref RxPipelineNodePS2ManagerPostObjectCallBack is the callback to be
 * called, for the owning PS2Manager pipeline node, after all meshes in an
 * object have been processed (remember that PS2Manager is used in object
 * pipelines, not material pipelines), such that cleanup may be performed
 * at the end of the object's pipeline execution (without having to
 * interfere with the object's render callback).
 *
 * This callback will receive a pointer to the data of the
 * \ref RxPS2DMASessionRecord cluster.
 *
 * The callback should return FALSE to indicate an error.
 *
 * \param  dmaSesRec   a pointer to the data of the
 * \ref RxPS2DMASessionRecord cluster
 *
 * \return TRUE on success, FALSE otherwise
 *
 * \see RxPipelineNodePS2ManagerSetInstanceCallBack
 * \see RxPipelineNodePS2ManagerSetPostObjectCallBack
 * \see RxPipelineNodePS2ManagerGenerateCluster
 */
typedef RwBool (*RxPipelineNodePS2ManagerPostObjectCallBack) (RxPS2DMASessionRecord *dmaSesRec);

/* LEGACY-SUPPORT define for old typedef name */
#define RxNodePS2ManagerPostObjectCallBack RxPipelineNodePS2ManagerPostObjectCallBack

/* RWPUBLICEND */

/****************************************************************************
 global prototypes
 */

/* RWPUBLIC */

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

/* RWPUBLICEND */

#if (defined(GSB))
extern unsigned long skyGCVTValue;
extern RwInt32 skyNumSeqFrms;
extern RwInt32 skyRenderSlot;
#endif /* (defined(GSB)) */

/* RWPUBLIC */


extern RxNodeDefinition *RxNodeDefinitionGetPS2Manager(RwInt32 objType);

extern void
RxPipelineNodePS2ManagerSetLighting(RxPipelineNode *self,
                                    RxWorldLightingCallBack newLightingFunc);
extern RxPipelineNode *
RxPipelineNodePS2ManagerSetVUBufferSizes(RxPipelineNode *self,
                                         RwInt32 strideOfInputCluster,
                                         RwInt32 vuTSVertexMaxCount,
                                         RwInt32 vuTLTriMaxCount);
extern RxPipelineNode *
RxPipelineNodePS2ManagerSetPointListVUBufferSize(RxPipelineNode *self,
                                                 RwInt32 strideOfInputCluster,
                                                 RwInt32 vuPLVertexMaxCount);


extern RxPipelineNode *
RxPipelineNodePS2ManagerGenerateCluster(RxPipelineNode      *self,
                                        RxClusterDefinition *cluster2generate,
                                        RwUInt32             type);

extern RwInt32
RxPipelineNodePS2ManagerGetVUBatchSize(RxPipelineNode *self,
                                       RpMeshHeaderFlags flags);

extern RxPipelineNode *
RxPipelineNodePS2ManagerSetVU1CodeArray(RxPipelineNode *self,
                                        void **VU1CodeArray);

extern const void **
RxPipelineNodePS2ManagerGetVU1CodeArray(RxPipelineNode *self);

extern RxPipelineNode *
RxPipelineNodePS2ManagerSetVIFOffset(RxPipelineNode *self,
                                     int vifOffset);

extern RxPipelineNode *
RxPipelineNodePS2ManagerNoTexture(RxPipelineNode * self,
                                  RwBool noTexture);

/* Allow instancing of user data, and misc other DMA setup, to
 * occur within PS2Manager after the (embedded) matInstance stage */
extern RxPipelineNode *
RxPipelineNodePS2ManagerSetInstanceCallBack(
    RxPipelineNode *node,
    RxPipelineNodePS2ManagerInstanceCallBack callBack);

/* Allow post-object cleanup without interfering with the render callback */
extern RxPipelineNode *
RxPipelineNodePS2ManagerSetPostObjectCallBack(
    RxPipelineNode *self,
    RxPipelineNodePS2ManagerPostObjectCallBack callBack);

#ifdef    __cplusplus
}
#endif /* __cplusplus */

/* RWPUBLICEND */

#endif /* NODEPS2MANAGER_H */

