/***************************************************************************
 *                                                                         *
 * Module  : wrldpipe.h                                                    *
 *                                                                         *
 * Purpose : See wrldpipe.c                                                *
 *                                                                         *
 **************************************************************************/

/* RWPUBLIC */

/**
 * \defgroup platformspecific Platform-Specific
 *
 * Platform-specific information
 */

/**
 * \defgroup sky2 PS2
 * \ingroup platformspecific
 *
 */

/**
 * \defgroup sky2functionoverview PS2 Functions Overview
 * \ingroup sky2
 *
 * PS2 Specific Functions, Typedefs and Structs
 */

/**
 * \defgroup rpworldp2sky2 PS2
 * \ingroup rpworldpowerpipe
 *
 * Manipulating world object custom pipelines (platform-specific) 
 */

/**
 * \defgroup rwim3dps2 PS2
 * \ingroup rwim3d
 *
 * Platform-specific
 */

/**
 * \defgroup rpworldsectorsky2 PS2
 * \ingroup rpworldsector
 *
 * Platform-specific
 */

/**
 * \defgroup rpatomicsky2 PS2
 * \ingroup rpatomic
 *
 * Platform-specific
 */

/**
 * \defgroup rpmeshsky2 PS2
 * \ingroup rpmesh
 *
 * Platform-specific
 */

/**
 * \defgroup rpmaterialsky2 PS2
 * \ingroup rpmaterial
 *
 * Platform-specific
 */

/**
 * \defgroup rpworldsubsky2 PS2
 * \ingroup rpworldsub
 *
 * Platform-specific
 */


/**
 * \ingroup sky2
 * \page platformspecificinfo Platform-Specific Information
 *
 * Listed below are references to all PlayStation 2 platform-specific 
 * information contained within this API Reference.
 *
 * \li \ref coresky2overview
 * \li \ref rpworldp2sky2overview
 *
 * Within the RenderWare Graphics API Reference there are PlayStation 2 
 * platform-specific functions which are described:
 * \li \ref sky2specific - functions that only exist for PlayStation 2
 * \li \ref platformdependent - functions that exist on all platforms which 
 * are platform dependent and therefore syntax varies between platforms.
 *
 */

/**
 * \ingroup sky2functionoverview
 * \page sky2specific PS2 Specific Functions, Typedefs and Structs
 *
 * The functions, typedefs and structs listed in the folders below have been 
 * created specifically for PlayStation 2.
 *
 * \li RwCore
 * \li RwIm3D
 * \li PowerPipe
 * \li Unsupported RwCore
 * \li RpWorld
 * \li RpAtomic
 * \li RpWorldSector
 * \li Rt2d
 *
 * \subsection rwcorespecific RwCore
 * \par Functions
 * \li \ref RpSkyGetTrueTLClipper
 * \li \ref RpSkyGetTrueTSClipper
 * \li \ref RpSkyRenderStateGet
 * \li \ref RpSkyRenderStateSet
 * \li \ref RpSkySelectDeepZBuffer
 * \li \ref RpSkySelectTrueTLClipper
 * \li \ref RpSkySelectTrueTSClipper
 * \li \ref RpSkyTexCacheAccessRaster
 * \li \ref RpSkyTexCacheAccessSpeculate
 * \li \ref RpSkyTexCacheDisable
 * \li \ref RpSkyTexCacheFlush
 * \li \ref RpSkyTexCacheRasterGetAddr
 * \li \ref RpSkyTexCacheRasterLock
 * \li \ref RpSkyTexCacheRasterUnlockAll
 * \li \ref RpSkyTexCacheReleaseRaster
 * \li \ref RpSkyTexCacheRestore
 * \li \ref RpSkyTexCacheSetCallBack
 * \li \ref RpSkyTexCacheUploadRaster
 * \li \ref RpSkyTexCacheValidateRaster
 * \li \ref RpSkyTexGetMiptbp1
 * \li \ref RpSkyTexGetMiptbp12
 * \li \ref RpSkyTexGetSize
 * \li \ref RpSkyTexGetStartAddress
 * \li \ref RpSkyTexGetTex0
 * \li \ref RpSkyTexSetMiptbp1
 * \li \ref RpSkyTexSetMiptbp12
 * \li \ref RpSkyTexSetTex0
 * \li \ref RpSkyTextureCacheSetState
 * \li \ref RpSkyTextureGetDefaultMipmapK
 * \li \ref RpSkyTextureGetDefaultMipmapL
 * \li \ref RpSkyTextureGetMipmapK
 * \li \ref RpSkyTextureGetMipmapL
 * \li \ref RpSkyTextureSetDefaultMipmapK
 * \li \ref RpSkyTextureSetDefaultMipmapL
 * \li \ref RpSkyTextureSetMipmapK
 * \li \ref RpSkyTextureSetMipmapL
 * \li \ref RpSkyUploadPixelData
 *
 * \par Structures
 * \li RwSky2DVertex
 * \li RwSky2DVertexAlignmentOverlay
 * \li RwSky2DVertexFields
 * \li RwSkyMetrics
 *
 * \par Types
 * \li \ref RwSky2DVertex
 * \li \ref RwSky2DVertexAlignmentOverlay
 * \li \ref RwSky2DVertexFields
 * \li \ref RwSkyMetrics
 * 
 * \subsection rwim3dspecific RwIm3D
 * \par Functions
 * \li \ref RwIm3DSkyGetPS2ManagerRenderPipeline
 * \li \ref RwIm3DSkyGetPS2ManagerTransformPipeline
 *
 * \par Function Information
 * \li \ref RwIm3DGetTransformPipelineplatform
 * \li \ref RwIm3DGetRenderPipelineplatform
 *
 * \subsection rwcorepowerpipespecific PowerPipe Functions
 * \par Types
 * \li \ref RxObjUnion
 * \li \ref RxPS2DMASessionRecord
 * \li \ref RxPS2Mesh
 * \li \ref RxScrSpace2DVertex
 *
 * \par Enumerated Types
 * \li \ref RxSkyTransTypeFlags
 *
 * \subsection rwcoreunsupportedspecific Unsupported Core Library Functions
 * 
 * \par Functions
 * \li \ref _rwSkyFSAAMode0SetVisibleWidth
 * \li \ref _sweAddPkt
 * \li \ref sweCloseLocalPkt
 * \li \ref sweFinaliseOpenLocalPkt
 * \li \ref sweOpenLocalPkt
 *
 * \par Defines
 * \li \ref SWEADDCONTFAST
 * \li \ref SWEADDCONTGIFFAST
 * \li \ref SWEADDPRIMFAST
 * \li \ref SWEADDPRIMGIFFAST
 *
 * \subsection rpworldspecific RpWorld
 * \par Functions
 * \li \ref RxNodeDefinitionGetPS2Manager
 * \li \ref RxNodeDefinitionGetPS2MatBridge
 * \li \ref RxNodeDefinitionGetPS2MatInstance
 * \li \ref RxNodeDefinitionGetPS2ObjAllInOne
 * \li \ref RxPipelineNodePS2MatBridgeGetVU1CodeArray
 * \li \ref RxPipelineNodePS2MatBridgeNoTexture
 * \li \ref RxPipelineNodePS2MatBridgeSetVIFOffset
 * \li \ref RxPipelineNodePS2MatBridgeSetVU1CodeArray
 * \li \ref RxPipelineNodePS2ManagerGenerateCluster
 * \li \ref RxPipelineNodePS2ManagerGetVU1CodeArray
 * \li \ref RxPipelineNodePS2ManagerGetVUBatchSize
 * \li \ref RxPipelineNodePS2ManagerNoTexture
 * \li \ref RxPipelineNodePS2ManagerSetInstanceCallBack
 * \li \ref RxPipelineNodePS2ManagerSetLighting
 * \li \ref RxPipelineNodePS2ManagerSetPointListVUBufferSize
 * \li \ref RxPipelineNodePS2ManagerSetPostObjectCallBack
 * \li \ref RxPipelineNodePS2ManagerSetVIFOffset
 * \li \ref RxPipelineNodePS2ManagerSetVU1CodeArray
 * \li \ref RxPipelineNodePS2ManagerSetVUBufferSizes
 * \li \ref RxPipelineNodePS2MatInstanceGenerateCluster
 * \li \ref RxPipelineNodePS2MatInstanceSetPointListVUBufferSize
 * \li \ref RxPipelineNodePS2MatInstanceSetVUBufferSizes
 * \li \ref RxPipelineNodePS2ObjAllInOneSetGrouping
 * \li \ref RxPipelineNodePS2ObjAllInOneSetLighting
 *
 * \par Types
 * \li \ref RxPipelineNodePS2ManagerInstanceCallBack
 * \li \ref RxPipelineNodePS2ManagerPostObjectCallBack
 * \li \ref RxWorldApplyLightFunc
 * \li \ref RxWorldLightingCallBack
 *
 * \par Enumerated Types
 * \li \ref RxPS2ClusterAttrib
 * \li \ref RxPS2ClusterFormatAttrib
 * \li \ref RxPS2ClusterType
 * \li \ref RxPS2ObjectType
 *
 * \par Structures
 * \li RwMeshCache
 *
 * \subsection rpatomicspecific RpAtomic
 *
 * \par Functions
 * \li \ref RpAtomicSkyGetAllInOnePipeline
 * \li \ref RpAtomicSkyGetPS2ManagerPipeline
 * \li \ref RpAtomicSkyGetVanillaPipeline
 *
 * \subsection rpworldsectorspecific RpWorldSector
 * 
 * \par Functions
 * \li \ref RpWorldSectorSkyGetAllInOnePipeline
 * \li \ref RpWorldSectorSkyGetPS2ManagerPipeline
 * \li \ref RpWorldSectorSkyGetVanillaPipeline
 * 
 * \subsection rt2dspecific Rt2d Toolkit
 * \par Overview
 * \li \ref rt2dps2overview
 *
 * \par Functions
 * \li \ref Rt2dFontCacheFlush
 */

/** 
 * \ingroup sky2functionoverview
 * \page platformdependent Platform Dependent
 *
 * These are functions, typedefs, structs and #defines which exist on 
 * all platforms. However, the syntax varies between platforms. They are
 * listed below in two sections:
 * \li RwCore
 * \li RpWorld
 * 
 * \subsection rwcoredependent RwCore
 *
 * \par Types
 * \li \ref RxColorUnion
 * \li \ref RxObjSpace3DLitVertex 
 * \li \ref RxObjSpace3DVertex 
 * \li \ref RwIm3DVertex 
 * \li \ref RwIm2DVertex 
 * \li \ref RxVertexIndex 
 * \li \ref RwImVertexIndex 
 *
 * \par Structures
 * \li RxColorUnion
 * \li RxObjSpace3DVertex 
 *
 * \par Defines
 * \li \ref RWIM2DVERTEX
 * \li \ref RwIm3DVertex
 * \li \ref RWIMVERTEXINDEX
 *
 * \par Function information
 * \li \ref RwIm3DGetTransformPipelineplatform
 * \li \ref RwIm3DGetRenderPipelineplatform
 *
 * \subsection rpworlddependent RpWorld
 * \par Function information
 * \li \ref RpAtomicGetDefaultPipelineplatform
 * \li \ref RpMaterialGetDefaultPipelineplatform
 * \li \ref RpWorldGetDefaultSectorPipelineplatform
 *
 */


/**
 * \ingroup sky2functionoverview
 * \page ps2allspecific PS2All Specific Functions, Typedefs and Structs
 *
 * The functions, typedefs and structs listed in the folders below have been 
 * created specifically for PlayStation 2. These are all (including the
 * RwIm3D functionality) provided with the RpWorld plugin. See the
 * \ref rpworldp2sky2overview for an introduction to PS2-specific code in
 * the RpWorld plugin.
 *
 * \li RpAtomic
 * \li RpMaterial
 * \li RpMesh
 * \li RpWorldSector
 * \li RwIm3D
 * \li PowerPipe
 *
 * \subsection rpatomicspecificps2all RpAtomic
 * \par Functions
 * \li \ref RpAtomicPS2AllClear
 * \li \ref RpAtomicPS2AllFrustumTest
 * \li \ref RpAtomicPS2AllGatherObjMetrics
 * \li \ref RpAtomicPS2AllGetMeshHeaderMeshCache
 * \li \ref RpAtomicPS2AllLightingSetup
 * \li \ref RpAtomicPS2AllMatModulateSetup
 * \li \ref RpAtomicPS2AllMorphSetup
 * \li \ref RpAtomicPS2AllObjectSetupCallBack
 * \li \ref RpAtomicPS2AllObjInstanceTest
 * \li \ref RpAtomicPS2AllPrimTypeTransTypeSetup
 * \li \ref RpAtomicPS2AllResEntryAlloc
 * \li \ref RpAtomicPS2AllTransformSetup
 * \li \ref RpAtomicSkyGetPS2AllPipeline
 *
 * \subsection rpmaterialspecificps2all RpMaterial
 * \par Functions
 * \li \ref RpMaterialSkyGetDefaultPS2AllMatPipeline
 * \li \ref RpMaterialSkyGetPS2AllMatPipeline
 * \li \ref RpMaterialSkySetDefaultPS2AllMatPipeline
 * 
 * \subsection rpmeshspecificps2all RpMesh
 * \par Functions
 * \li \ref RpMeshPS2AllAsyncTextureUpload
 * \li \ref RpMeshPS2AllBridgeCallBack
 * \li \ref RpMeshPS2AllClipInfoUpload
 * \li \ref RpMeshPS2AllEndVIFUploads
 * \li \ref RpMeshPS2AllGatherMeshMetrics
 * \li \ref RpMeshPS2AllGIFTagUpload
 * \li \ref RpMeshPS2AllMatColUpload
 * \li \ref RpMeshPS2AllMeshInstanceTestCallBack
 * \li \ref RpMeshPS2AllPostMeshCallBack
 * \li \ref RpMeshPS2AllResEntryAllocCallBack
 * \li \ref RpMeshPS2AllStartVIFUploads
 * \li \ref RpMeshPS2AllSurfPropsUpload
 * \li \ref RpMeshPS2AllSyncTextureUpload
 * \li \ref RpMeshPS2AllTestMeshID
 * \li \ref RpMeshPS2AllTestNumVerts
 * \li \ref RpMeshPS2AllTextureStateUpload
 * \li \ref RpMeshPS2AllVU1CodeIndexSetup
 * \li \ref RpMeshPS2AllVU1CodeUpload
 *
 * \subsection rpworldsectorspecificps2all RpWorldSector
 * \par Functions
 * \li \ref RpWorldSectorPS2AllFrustumTest
 * \li \ref RpWorldSectorPS2AllGatherObjMetrics
 * \li \ref RpWorldSectorPS2AllGetMeshHeaderMeshCache
 * \li \ref RpWorldSectorPS2AllLightingSetup
 * \li \ref RpWorldSectorPS2AllMatModulateSetup
 * \li \ref RpWorldSectorPS2AllObjectSetupCallBack
 * \li \ref RpWorldSectorPS2AllObjInstanceTest
 * \li \ref RpWorldSectorPS2AllResEntryAlloc
 * \li \ref RpWorldSectorPS2AllTransformSetup
 * \li \ref RpWorldSectorSkyGetPS2AllPipeline
 *
 * \subsection rwim3dspecificps2all RwIm3D
 * \par Functions
 * \li \ref RwIm3DPS2AllBridgeCallBack
 * \li \ref RwIm3DPS2AllFrustumTest
 * \li \ref RwIm3DPS2AllGatherMeshMetrics
 * \li \ref RwIm3DPS2AllGatherObjMetrics
 * \li \ref RwIm3DPS2AllGetMeshHeaderMeshCache
 * \li \ref RwIm3DPS2AllInstanceCallBack
 * \li \ref RwIm3DPS2AllObjectSetupCallBack
 * \li \ref RwIm3DPS2AllObjInstanceTest
 * \li \ref RwIm3DPS2AllPostMeshCallBack
 * \li \ref RwIm3DPS2AllResEntryAlloc
 * \li \ref RwIm3DPS2AllResEntryAllocCallBack
 * \li \ref RwIm3DPS2AllTransformSetup
 * \li \ref RwIm3DSkyGetPS2AllMatPipeline
 * \li \ref RwIm3DSkyGetPS2AllRenderPipeline
 *
 * \subsection rxpipelinenodespecificps2all PowerPipe Functions
 * \par Functions
 * \li \ref RxNodeDefinitionGetPS2All
 * \li \ref RxNodeDefinitionGetPS2AllMat
 * \li \ref RxPipelineNodePS2AllGroupMeshes
 * \li \ref RxPipelineNodePS2AllMatGenerateCluster
 * \li \ref RxPipelineNodePS2AllMatGetVU1CodeArray
 * \li \ref RxPipelineNodePS2AllMatGetVUBatchSize
 * \li \ref RxPipelineNodePS2AllMatSetCallBack
 * \li \ref RxPipelineNodePS2AllMatSetPointListVUBufferSize
 * \li \ref RxPipelineNodePS2AllMatSetVIFOffset
 * \li \ref RxPipelineNodePS2AllMatSetVU1CodeArray
 * \li \ref RxPipelineNodePS2AllMatSetVUBufferSizes
 * \li \ref RxPipelineNodePS2AllSetCallBack
 *
 * \par Enumerated Types
 * \li \ref RxPipelineNodePS2AllCallBackType
 * \li \ref RxPipelineNodePS2AllMatCallBackType
 * \li \ref RxInstanceFlags
 *
 * \par Types
 * \li \ref RxPipelineNodePS2AllMatBridgeCallBack
 * \li \ref RxPipelineNodePS2AllMatInstanceCallBack
 * \li \ref RxPipelineNodePS2AllMatMeshInstanceTestCallBack
 * \li \ref RxPipelineNodePS2AllMatPostMeshCallBack
 * \li \ref RxPipelineNodePS2AllMatResEntryAllocCallBack
 * \li \ref RxPipelineNodePS2AllObjectFinalizeCallBack
 * \li \ref RxPipelineNodePS2AllObjectSetupCallBack
 *
 * \par Structures
 * \li \ref RxPS2AllPipeData
 */


/* RWPUBLICEND */

#ifndef WRLDPIPE_H
#define WRLDPIPE_H

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

#include <rwcore.h>

#include "baworld.h"
#include "baclump.h"


/****************************************************************************
 Global types
 */

/* RWPUBLIC */

/* RWPUBLICEND
 * Don't change these
 * RWPUBLIC */

/**
 * \ingroup rpworldp2sky2
 * \ref RxPS2ObjectType
 * Values identifying different PS2-specific object types.
 */
enum RxPS2ObjectType
{
    rxOBJTYPE_WORLDSECTOR = 0, /**< The object is an \ref RpWorldSector */
    rxOBJTYPE_ATOMIC      = 1, /**< The object is an \ref RpAtomic */
    /* RWPUBLICEND
     * Temporary until PS2MANAGER rendering gets moved into the core
     * RWPUBLIC */
    rxOBJTYPE_IM3D        = 2, /**< The object is an _rwIm3DPoolStash */
    rxOBJTYPEFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
typedef enum RxPS2ObjectType RxPS2ObjectType;

typedef union RxObjUnion RxObjUnion;
/**
 * \ingroup rpworldp2sky2
 * \union RxObjUnion
 * A union used by the \ref RxPS2DMASessionRecord structure
 */
union RxObjUnion
{
    RpWorldSector *worldSector; /**< \ref RpWorldSector pointer union member */
    RpAtomic *atomic;           /**< \ref RpAtomic pointer union member */
    void *agnostic;             /**< void pointer union member */
};


typedef struct RxPS2DMASessionRecord RxPS2DMASessionRecord;
/**
 * \ingroup rpworldp2sky2
 * \struct RxPS2DMASessionRecord
 * Describes information for an object's DMA packet(s)
 */
struct RxPS2DMASessionRecord
{
    RxPS2ObjectType objType;       /**< \ref RxPS2ObjectType type identifier */
    RxObjUnion sourceObject;       /**< \ref RxObjUnion referencing the source object */
    RwFrustumTestResult inFrustum; /**< \ref RwFrustumTestResult frustum test result */
    RwUInt16 serialNum;            /**< \ref RwUInt16 serial number used when
                                    *   choosing whether to re-instance object data */
    RwUInt8 vu1CodeIndex;             /**< \ref RwUInt8 index into VU code array,
                                    *   specifying the transform to use. */
    RwUInt8 primType;              /**< \ref RwUInt8 code for the primitive type that will
                                    *   be submitted by VU1 to the GS (see GS manual ~p113). */
    RxSkyTransTypeFlags transType; /**< \ref RxSkyTransTypeFlags flags, specifying the type
                                    *   of transform to use (ortho/persp, fog/not, etc). */
};


typedef struct RxPS2Mesh RxPS2Mesh;
/**
 * \ingroup rpworldp2sky2
 * \struct RxPS2Mesh
 * Describes PS2-specific information for a mesh
 */
struct RxPS2Mesh
{
    const RpMesh *mesh;          /**< A pointer to the source \ref RpMesh */
    RwResEntry  **cacheEntryRef; /**< A pointer to a pointer to a \ref RwResEntry
                                  *   holding the instance data for the mesh */
    RwUInt32      meshNum;       /**< The number of the current mesh within
                                  *   its parent object (from zero) */
    RwUInt32      pad;           /**< Alignment padding to 16 bytes/1 QW */
};


/* RWPUBLICEND */
/****************************************************************************
 Global variables
 */
/* RWPUBLIC */

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

/* RWPUBLICEND */
extern long vu1nullTrans   __attribute__((section(".vudata")));
/* RWPUBLIC */

extern RxClusterDefinition RxClPS2DMAChain ;
extern RxClusterDefinition RxClPS2LightsBlock ;
extern RxClusterDefinition RxClPS2DMASessionRecord ;
extern RxClusterDefinition RxClPS2Mesh ;
extern RxClusterDefinition RxClPS2xyz ;
extern RxClusterDefinition RxClPS2uv;
extern RxClusterDefinition RxClPS2uv2;
extern RxClusterDefinition RxClPS2rgba;
extern RxClusterDefinition RxClPS2normal;

extern RxClusterDefinition RxClPS2user1;
extern RxClusterDefinition RxClPS2user2;
extern RxClusterDefinition RxClPS2user3;
extern RxClusterDefinition RxClPS2user4;

extern RwChar              RxPS2AttributeSet[];

#ifdef    __cplusplus
}
#endif                          /* __cplusplus */


/* RWPUBLICEND */
/****************************************************************************
 Function prototypes
 */
/* RWPUBLIC */

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

/* RWPUBLICEND */
extern long vu1nullTrans   __attribute__((section(".vudata")));
/* RWPUBLIC */

/* PS2Manager and other all-in-one pipes don't use material pipes */
extern RxPipeline *RpMaterialSkyGetPS2AllMatPipeline(void);
extern RxPipeline *RpMaterialSkyGetVanillaPipeline(void);

extern RxPipeline *RpAtomicSkyGetPS2AllPipeline(void);
extern RxPipeline *RpAtomicSkyGetPS2ManagerPipeline(void);
extern RxPipeline *RpAtomicSkyGetAllInOnePipeline(void);
extern RxPipeline *RpAtomicSkyGetVanillaPipeline(void);

extern RxPipeline *RpWorldSectorSkyGetPS2AllPipeline(void);
extern RxPipeline *RpWorldSectorSkyGetPS2ManagerPipeline(void);
extern RxPipeline *RpWorldSectorSkyGetAllInOnePipeline(void);
extern RxPipeline *RpWorldSectorSkyGetVanillaPipeline(void);

/* RWPUBLICEND */

extern RwBool _rpCreatePlatformMaterialPipelines(void);
extern RwBool _rpCreatePlatformWorldSectorPipelines(void);
extern RwBool _rpCreatePlatformAtomicPipelines(void);

extern void _rpDestroyPlatformMaterialPipelines(void);
extern void _rpDestroyPlatformAtomicPipelines(void);
extern void _rpDestroyPlatformWorldSectorPipelines(void);

extern RwBool _rxWorldDevicePluginAttach(void);

/* RWPUBLIC */

#ifdef    __cplusplus
}
#endif /* __cplusplus */

/* RWPUBLICEND */

#endif /* WRLDPIPE_H */
