//////////////////////////////////////////////////////////////////////////////
//
// Asura_PS2_ParticleDefines.h
//
// Copyright (c) 2002 Rebellion. All rights reserved.
//
// Description:
//
//     defines for VU1 particle renderer, included by VCL and .cpp files.
//
// VU memory usage:
//
//      Buffer sizes, etc.:
//
//			Viewport					= 2				\
//			Matrices					= 7				|
//			Billboards					= 2				|-- per camera data (*4)
//			Offset						= 1				|
//			Align vectors				= 2				/
//			Total per camera			= 14
//
//			Header						= 4				\_ input buffer (*2)
//			Input buffer				= 3 * N			/
//			Total per input buffer		= 4 + 3 * N
//
//			Clip buffer					= 12 * N		>- intermediate buffer
//
//			Header						= 1 + 2 + 1 = 4 \_ output buffer (*2)
//			Output buffer				= 12 * N		/
//			Total per output buffer		= 4 + 12 * N
//
//			Stack						= 4
//			Total for all cameras		= 14 * 4 = 56
//			Total for all input buffers	= 8 + 6 * N
//			Total for all clip buffers	= 12 * N
//			Total for all output buffers= 8 + 24 * N
//			Total						= 78 + 42 * N
//
//			Max particles:
//			76 + 42 * N <= 1024
//			N <= ~22.6
//			N = 22
//
//		Note: clip buffer could be smaller,
//		taking advantage of the fact that
//		vertex colour is constant per particle.
//		This would yield a maximum of 24 particles per packet.
//
//      Memory layout of the output buffers during clipping:
//
//                 :                          :
//             K   |--------------------------|
//                 |  non-clipped const data  |    4 QWs
//                 |--------------------------|
//                 |   clipped output buffer  | 1+3M QWs
//                 |--------------------------|
//                 |    clipper workspace 1   |   36 QWs
//                 |--------------------------|
//                 |    clipper workspace 2   |   36 QWs
//                 |--------------------------|
//                 |   clipped ST Overwrites  |    M QWs
//                 |--------------------------|
//                 :                          :
//
//          where M is the maximum number of vertices that will fit.
//
//              4 + 1+3M + 36 + 36 + M <= 4 + 12 * N = 268
//                  =>
//              77 + 4M <= 268
//                  =>
//              M <= 47.75
//
//          => set M = 47
//
//          (NB: M must be at least 9 since just a single input tri can
//          generate that many output vertices.)
//
//			We could increase this by removing the utterly unnecessary
//			clipped ST overwrites buffer, which was simply copied from the
//			GSM clipper for the sake of saving coding time (and coder sanity)
//
//////////////////////////////////////////////////////////////////////////////

// B E G I N   F I L E   W R A P P E R ///////////////////////////////////////

#ifdef ASURA_USE_PRAGMA_ONCE
    #pragma once
#endif

#ifndef ___ASURA_PS2_PARTICLEDEFINES_H___
#define ___ASURA_PS2_PARTICLEDEFINES_H___ 1

#define ASURA_PS2_PARTICLE_MAX_PARTICLES (22)
#define ASURA_PS2_PARTICLE_MAX_CLIPPED_VERTS (47)

#define ASURA_PS2_PARTICLE_INPUT_QWS_PER_PARTICLE (3)
#define ASURA_PS2_PARTICLE_CLIP_QWS_PER_PARTICLE (12)
#define ASURA_PS2_PARTICLE_OUTPUT_QWS_PER_PARTICLE (12)
#define ASURA_PS2_PARTICLE_MAX_CAMERAS (4)

#define ASURA_PS2_PARTICLE_NUM_VIEWPORT_REGS (2)
#define ASURA_PS2_PARTICLE_NUM_QWS_FOR_CAMERA_MATRICES (7)     // 1 4x4 object to guardband matrix + guardband to screen scale + translate + clip scale vectors.
#define ASURA_PS2_PARTICLE_NUM_QWS_FOR_CAMERA_BILLBOARDS (2)   // deltax and delta y
#define ASURA_PS2_PARTICLE_NUM_QWS_FOR_CAMERA_OFFSET (1)       // Offset vector per camera, to allow us to support skybox PFX effects.
// We have to define this as a constant instead of adding everything,
// because VCL chokes if there are too many tokens in a calculation.
#define ASURA_PS2_PARTICLE_NUM_QWS_PER_CAMERA (12)
// However, make sure it's correct here
#if ( ASURA_PS2_PARTICLE_NUM_QWS_PER_CAMERA != (ASURA_PS2_PARTICLE_NUM_VIEWPORT_REGS + ASURA_PS2_PARTICLE_NUM_QWS_FOR_CAMERA_MATRICES + ASURA_PS2_PARTICLE_NUM_QWS_FOR_CAMERA_BILLBOARDS + ASURA_PS2_PARTICLE_NUM_QWS_FOR_CAMERA_OFFSET) )
#error ASURA_PS2_PARTICLE_NUM_QWS_PER_CAMERA is incorrect.
#endif

#define ASURA_PS2_PARTICLE_NUM_QWS_PER_ALIGN_VECTORS (2)

#define ASURA_PS2_PARTICLE_OFFSET_CAM_VIEWPORT0			(0)
#define ASURA_PS2_PARTICLE_OFFSET_CAM_VIEWPORT1			(1)
#define ASURA_PS2_PARTICLE_OFFSET_CAM_O2GBC_MAT			(2) // 4 QWs
#define ASURA_PS2_PARTICLE_OFFSET_CAM_GBC2S_SCALE		(6)
#define ASURA_PS2_PARTICLE_OFFSET_CAM_GBC2S_TRANS		(7)
#define ASURA_PS2_PARTICLE_OFFSET_CAM_GBC2SC_SCALE		(8)
#define ASURA_PS2_PARTICLE_OFFSET_CAM_BILLBOARDX		(9)
#define ASURA_PS2_PARTICLE_OFFSET_CAM_BILLBOARDY		(10)
#define ASURA_PS2_PARTICLE_OFFSET_CAM_OFFSET			(11)

#define ASURA_PS2_PARTICLE_HEADER_QWS (4)
#define ASURA_PS2_PARTICLE_INPUT_BUFFER_SIZE (ASURA_PS2_PARTICLE_HEADER_QWS + (ASURA_PS2_PARTICLE_INPUT_QWS_PER_PARTICLE * ASURA_PS2_PARTICLE_MAX_PARTICLES))
#define ASURA_PS2_PARTICLE_CLIP_BUFFER_SIZE ((ASURA_PS2_PARTICLE_CLIP_QWS_PER_PARTICLE * ASURA_PS2_PARTICLE_MAX_PARTICLES))
#define ASURA_PS2_PARTICLE_OUTPUT_BUFFER_SIZE (268)
#if (ASURA_PS2_PARTICLE_OUTPUT_BUFFER_SIZE != (2 + ASURA_PS2_PARTICLE_NUM_VIEWPORT_REGS + (ASURA_PS2_PARTICLE_OUTPUT_QWS_PER_PARTICLE * ASURA_PS2_PARTICLE_MAX_PARTICLES)))
#error ASURA_PS2_PARTICLE_OUTPUT_BUFFER_SIZE is incorrect.
#endif

// memory layout
#define ASURA_PS2_PARTICLE_CAMERA_DATA_START    (0)
#define ASURA_PS2_PARTICLE_NUM_CAMERAS_PTR_W    (ASURA_PS2_PARTICLE_CAMERA_DATA_START + ASURA_PS2_PARTICLE_NUM_VIEWPORT_REGS + ASURA_PS2_PARTICLE_NUM_QWS_FOR_CAMERA_MATRICES)
#define ASURA_PS2_PARTICLE_ALIGN_VECTORS_START  (ASURA_PS2_PARTICLE_CAMERA_DATA_START + (ASURA_PS2_PARTICLE_NUM_QWS_PER_CAMERA * ASURA_PS2_PARTICLE_MAX_CAMERAS))
#define ASURA_PS2_PARTICLE_INPUT_BUFFERS_START  (ASURA_PS2_PARTICLE_ALIGN_VECTORS_START + 8)
#define ASURA_PS2_PARTICLE_CLIP_BUFFER_START	(ASURA_PS2_PARTICLE_INPUT_BUFFERS_START + (2 * ASURA_PS2_PARTICLE_INPUT_BUFFER_SIZE))
#define ASURA_PS2_PARTICLE_OUTPUT1_START		(ASURA_PS2_PARTICLE_CLIP_BUFFER_START + ASURA_PS2_PARTICLE_CLIP_BUFFER_SIZE)    
#define ASURA_PS2_PARTICLE_OUTPUT2_START        (ASURA_PS2_PARTICLE_OUTPUT1_START + ASURA_PS2_PARTICLE_OUTPUT_BUFFER_SIZE)
#define ASURA_PS2_PARTICLE_VI_STACK_0			(ASURA_PS2_PARTICLE_OUTPUT1_START + 2 * ASURA_PS2_PARTICLE_OUTPUT_BUFFER_SIZE)
#define ASURA_PS2_PARTICLE_VI_STACK_1			(ASURA_PS2_PARTICLE_VI_STACK_0 + 1)
#define ASURA_PS2_PARTICLE_VI_STACK_2			(ASURA_PS2_PARTICLE_VI_STACK_0 + 2)
#define ASURA_PS2_PARTICLE_VI_STACK_3			(ASURA_PS2_PARTICLE_VI_STACK_0 + 3)

// These match the VU1 clipping bits.
#define ASURA_PS2_PARTICLE_CLIP_RIGHT                       (0x001)
#define ASURA_PS2_PARTICLE_CLIP_LEFT                        (0x002)
#define ASURA_PS2_PARTICLE_CLIP_BOTTOM                      (0x004)
#define ASURA_PS2_PARTICLE_CLIP_TOP                         (0x008)
#define ASURA_PS2_PARTICLE_CLIP_FAR                         (0x010)
#define ASURA_PS2_PARTICLE_CLIP_NEAR                        (0x020)
#define ASURA_PS2_PARTICLE_CLIP_ALL                         (0x03F)

#define ASURA_PS2_PARTICLE_SIZE__CLIP_WORKSPACE             (36)  // Up to 9 Svertices with 4 QWs per vertex.
#define ASURA_PS2_PARTICLE_SIZE__CLIPPED_STS                (ASURA_PS2_PARTICLE_MAX_CLIPPED_VERTS)  // See memory map above for calculations.
#define ASURA_PS2_PARTICLE_OFFSET__CLIP_WORKSPACE           (146)
#define ASURA_PS2_PARTICLE_OFFSET__CLIPPED_STS              (218)
#define ASURA_PS2_PARTICLE_OFFSET__GEOM_OUT_DRAW_GIF_TAG    (4)
#define ASURA_PS2_PARTICLE_OFFSET__GEOM_OUT_FIRST_VERTEX    (5)

// sanity checks
#if (ASURA_PS2_PARTICLE_OFFSET__GEOM_OUT_FIRST_VERTEX + 3 * ASURA_PS2_PARTICLE_MAX_CLIPPED_VERTS != ASURA_PS2_PARTICLE_OFFSET__CLIP_WORKSPACE)
#error sanity check fail
#endif

#if (ASURA_PS2_PARTICLE_OFFSET__CLIP_WORKSPACE + 2 * ASURA_PS2_PARTICLE_SIZE__CLIP_WORKSPACE != ASURA_PS2_PARTICLE_OFFSET__CLIPPED_STS)
#error sanity check fail
#endif

#if (ASURA_PS2_PARTICLE_OFFSET__CLIPPED_STS + ASURA_PS2_PARTICLE_SIZE__CLIPPED_STS > ASURA_PS2_PARTICLE_OUTPUT_BUFFER_SIZE)
#error buffer overflow
#endif

// error checking
#if ( (ASURA_PS2_PARTICLE_VI_STACK_0 + 4) > 1024)
#error buffers overflowed
#endif

#define ASURA_PS2_PARTICLE_FLAG_USEMOTIONBLUR 0x0001
#define ASURA_PS2_PARTICLE_FLAG_USEROTATION   0x0002
#define ASURA_PS2_PARTICLE_FLAG_HEATHAZE	  0x0004
#define ASURA_PS2_PARTICLE_FLAG_CLIPPED		  0x0008

// E N D   F I L E   W R A P P E R ///////////////////////////////////////////

#endif // #ifndef ___ASURA_PS2_PARTICLEDEFINES_H___
