//////////////////////////////////////////////////////////////////////////////
//
// Asura_PS2_GSMDefines.h
//
// Copyright (c) 2002-2003 Rebellion. All rights reserved.
//
//  Notes:
//
//      - The GSM VU µcode is written mainly for use with MSCALs. The only
//        place where an MSCNT is ok for rendering a strip. Note that ITOP
//        needs to be set to the vertex count before the MSCNT and that
//        executing the dummy NOP µprogram will be necessary if anything
//        other than the BEGIN_STRIP µprogram has been run immediately
//        beforehand.
//
//      - For point lighting, the number of lights is assumed to be in the
//        range [0, 7]. The light count is stored in the w component of the
//        2nd QW of each light buffer; we don't use the alpha component of
//        the light colours so this is spare.
//
//      - Prelighting components should be integers in [0, 255]
//        (when UNPACKed.)
//
//      - Dynamic light components should be floating point in [0.0, 255.0]
//        (again, when UNPACKed.)
//
//      - Mesh RGBA is ignored for prelit vertices, apart from for SH-list
//        meshes in which case only the alpha is used. In this case the alpha
//        should be in the range [0, 1].
//
//      - Only prelit meshes should be sent without any lights. Non-prelit
//        meshes require at least a mesh colour. (Cheapest way is probably to
//        do directional lighting with 3 black lights.)
//
//      - Camera flags should be set so that for camera c, bit (7 - 2c) is
//        high iff the mesh is visible to it and bit (6 - 2c) is high iff
//        clipping is required. This slightly odd arrangement is for
//        convenience in the microcode - it's easy to shift up but basically
//        impossible to shift down.
//
//      - If general multipass is required, a second set of STs should be
//        uploaded to the z and w components of the ST QW. A second texture
//        and an alpha blend need to be setup, as with an ST scale&trans pass.
//
// VU memory usage:
//
//      Buffer sizes, etc.:
//
//          GIF tags                    = 4               \
//          Constant cam data buffer    = 4 * 5            |-- constant input
//          Constant shadow data buffer = 1               /
//          
//          Renderstate                 = 2 * 10          \
//          Per-mesh camera data buffer = 2 * 4 * 12       |
//          Lighting data buffers       = 2 * (1 + 14)     |__ input that changes sporadically, though at least once per mesh
//          Shadow data buffers         = 2 * 6            |
//          ST scale/trans parameters   = 1                |
//          Y scale/trans parameters    = 2               /
//          
//          Input buffers               = 2 * 4N          >--- input per strip
//
//          ST overwrite buffer         = N               \___ intermediate data
//          Clip input buffer           = 3N              /
//
//          Geom output buffers         = 2 * (1 + 3N)    \___ output data
//          RS output buffer            = 8               /
//
//          VI reg stack                = 6               >--- internal usage
//
//      Max vertices:
//
//          4 + 4*5 + 1 + 2*10 + 2*4*12 + 2*(1+14) + 2*6 + 1 + 2 + 2*4N + N + 3N + 2*(1+3N) + 8 + 6 <= 1024
//              =>
//          202 + 18N <= 1024
//              =>  .
//          N <= 45.6
//
//          However, set N=44 to allow a little slack for future changes.
//
//      Memory layout:
//      
//             0   /--------------------------\
//                 |         GIF tags         |    4 QWs - geometry setup and draw, shadow setup and draw
//             4   |--------------------------|
//                 |    constant cam data     |   20 QWs - (SCISSOR, XYOFFSET, GBC->S scale, GBC->S trans, GBC->SC scale) * 4
//            24   |--------------------------|
//                 |   constant shadow data   |    1 QW  - RGBAQ
//            25   |--------------------------|
//                 |        renderstate       |   20 QWs - (base (ALPHA, TEX1, TEX0, MIPTBP1, TEST), self illum ALPHA, ST overwrite (ALPHA, TEX1, TEX0, MIPTBP1)) * 2
//            45   |--------------------------|
//                 |     per-mesh cam data    |   96 QWs - (O->GBC mat, O->V mat, tex mat) * 4 * 2
//           141   |--------------------------|
//                 |        light data        |   30 QWs - (mesh RGBA, point/dir light data) * 2
//           171   |--------------------------|
//                 |      shadow buffers      |   12 QWs - (shadow proj mat, shadow quad pos + size, shadow ST scales) * 2
//           183   |--------------------------|
//                 |  ST scale/trans params   |    1 QW
//           184   |--------------------------|
//                 |   Y scale/trans params   |    2 QWs - (angle params, Y params)
//           186   |--------------------------|
//                 |       input buffers      |  352 QWs - (XYZ, ST, RGBA, normal) * N * 2
//           538   |--------------------------|
//                 |    ST overwrite buffer   |   47 QWs - (ST) * N, plus space for overrun of up to three vertices
//           585   |--------------------------|
//                 |     clip input buffer    |  132 QWs - (XYZW, ST + should-clip flag, RGBA) * N
//           717   |--------------------------|
//                 |      output buffers      |  266 QWs - (draw GIF tag, (ST, RGBAQ, XYZ) * N) * 2
//           983   |--------------------------|
//                 |     RS output buffer     |    8 QWs - (setup GIF tag, up to 7 registers)
//           991   |--------------------------|
//                 |       VI reg stack       |    6 QWs
//           997   |--------------------------|
//                 |         <unused>         |   27 QWs
//          1024   \--------------------------/
//
//      Memory layout of the output buffers during clipping:
//
//                 :                          :
//             K   |--------------------------|
//                 |   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.
//
//              1+3M + 36 + 36 + M <= 133
//                  =>
//              73 + 4M <= 133
//                  =>
//              M <= 15
//
//          => set M=15.
//
//          (NB: M must be at least 9 since just a single input tri can
//          generate that many output vertices.)
//
//////////////////////////////////////////////////////////////////////////////

// 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_GSMDEFINES_H___
#define ___ASURA_PS2_GSMDEFINES_H___ 1

// M A C R O S ///////////////////////////////////////////////////////////////

// Limits.
#define ASURA_PS2_GSM__MAX_VERTS_PER_STRIP              (44)
#define ASURA_PS2_GSM__MAX_POINT_LIGHTS                 (7)
#define ASURA_PS2_GSM__MAX_CAMERAS                      (4)
#define ASURA_PS2_GSM__MAX_DUAL_TEXTURE_PALETTE_SIZE    (10)

// ITOP data: mesh flags.
#define ASURA_PS2_GSM__FLAG__DUAL_TEXTURE               (0x001)
#define ASURA_PS2_GSM__FLAG__PASS_0_ST_SCALE_AND_TRANS  (0x002)
#define ASURA_PS2_GSM__FLAG__PASS_2_ST_SCALE_AND_TRANS  (0x004)
#define ASURA_PS2_GSM__FLAG__Y_SCALE_AND_TRANS          (0x008)
#define ASURA_PS2_GSM__FLAG__SHADOW                     (0x010)
#define ASURA_PS2_GSM__FLAG__SELFILLUMINATED            (0x020)
#define ASURA_PS2_GSM__FLAG__REFLECTIVE                 (0x040)
#define ASURA_PS2_GSM__FLAG__POINT_LIT                  (0x080)
#define ASURA_PS2_GSM__FLAG__PRELIT                     (0x100)
#define ASURA_PS2_GSM__FLAG__PROJECTED_TEXTURE			(0x200)
#define ASURA_PS2_GSM__MASK__ST_SCALE_AND_TRANS         (ASURA_PS2_GSM__FLAG__PASS_0_ST_SCALE_AND_TRANS | ASURA_PS2_GSM__FLAG__PASS_2_ST_SCALE_AND_TRANS)
#define ASURA_PS2_GSM__MASK__ANY_VTX_MANIPULATIONS      (ASURA_PS2_GSM__FLAG__DUAL_TEXTURE | ASURA_PS2_GSM__MASK__ST_SCALE_AND_TRANS | ASURA_PS2_GSM__FLAG__Y_SCALE_AND_TRANS | ASURA_PS2_GSM__FLAG__PROJECTED_TEXTURE)
#define ASURA_PS2_GSM__MASK__PASS_1                     (ASURA_PS2_GSM__FLAG__SELFILLUMINATED)
#define ASURA_PS2_GSM__MASK__PASS_2                     (ASURA_PS2_GSM__FLAG__DUAL_TEXTURE | ASURA_PS2_GSM__FLAG__REFLECTIVE | ASURA_PS2_GSM__FLAG__PASS_2_ST_SCALE_AND_TRANS)
#define ASURA_PS2_GSM__MASK__MULTIPASS                  (ASURA_PS2_GSM__MASK__PASS_1 | ASURA_PS2_GSM__MASK__PASS_2)

// ITOP data: cam flags.
#define ASURA_PS2_GSM__FLAG__VIS_FOR_MORE_THAN_ONE_CAM  (0x100)
#define ASURA_PS2_GSM__MASK__CAM_VIS_FLAGS              (0x0AA)
#define ASURA_PS2_GSM__MASK__CAM_CLIP_FLAGS             (0x055)
#define ASURA_PS2_GSM__MASK__CAM_VIS_AND_CLIP_FLAGS     (ASURA_PS2_GSM__MASK__CAM_VIS_FLAGS | ASURA_PS2_GSM__MASK__CAM_CLIP_FLAGS)

// ITOP data: per-strip, inserted into the packet data at export time.
#define ASURA_PS2_GSM__STRIP_MASK__VERTEX_QTY           (0x07F)
// (Space for flags available at 0x080 and 0x100 but not currently required.)

// These match the VU1 clipping bits.
#define ASURA_PS2_GSM__CLIP_RIGHT                       (0x001)
#define ASURA_PS2_GSM__CLIP_LEFT                        (0x002)
#define ASURA_PS2_GSM__CLIP_BOTTOM                      (0x004)
#define ASURA_PS2_GSM__CLIP_TOP                         (0x008)
#define ASURA_PS2_GSM__CLIP_FAR                         (0x010)
#define ASURA_PS2_GSM__CLIP_NEAR                        (0x020)
#define ASURA_PS2_GSM__CLIP_ALL                         (0x03F)

// Sizes.
#define ASURA_PS2_GSM__SIZE__PER_POINT_LIGHT            (2)

// Data area addresses.
#define ASURA_PS2_GSM__ADDR__GIF_TAGS                   (0)
#define ASURA_PS2_GSM__ADDR__CONST_CAM_DATA             (4)
#define ASURA_PS2_GSM__ADDR__CONST_SHADOW_DATA          (24)
#define ASURA_PS2_GSM__ADDR__RENDERSTATE_BFR_0          (25)
#define ASURA_PS2_GSM__ADDR__RENDERSTATE_BFR_1          (35)
#define ASURA_PS2_GSM__ADDR__PER_OBJ_CAM_DATA_BFR_0     (45)
#define ASURA_PS2_GSM__ADDR__PER_OBJ_CAM_DATA_BFR_1     (93)
#define ASURA_PS2_GSM__ADDR__LIGHT_DATA_BFR_0           (141)
#define ASURA_PS2_GSM__ADDR__LIGHT_DATA_BFR_1           (156)
#define ASURA_PS2_GSM__ADDR__SHADOW_DATA_BFR_0          (171)
#define ASURA_PS2_GSM__ADDR__SHADOW_DATA_BFR_1          (177)
#define ASURA_PS2_GSM__ADDR__ST_SCALE_AND_TRANS_PARAMS  (183)
#define ASURA_PS2_GSM__ADDR__Y_SCALE_AND_TRANS_PARAMS   (184)
#define ASURA_PS2_GSM__ADDR__INPUT_BFR_0                (186)
#define ASURA_PS2_GSM__ADDR__INPUT_BFR_1                (362)
#define ASURA_PS2_GSM__ADDR__ST_OVERWRITE_BFR           (538)
#define ASURA_PS2_GSM__ADDR__CLIP_INPUT_BFR             (585)
#define ASURA_PS2_GSM__ADDR__GEOM_OUTPUT_BFR_0          (717)
#define ASURA_PS2_GSM__ADDR__GEOM_OUTPUT_BFR_1          (850)
#define ASURA_PS2_GSM__ADDR__RS_OUTPUT_BFR              (983)
#define ASURA_PS2_GSM__ADDR__VI_REG_STACK               (991)
#define ASURA_PS2_GSM__ADDR__SHADOW_PALETTE				(997)

// Data area sizes.
#define ASURA_PS2_GSM__SIZE__GIF_TAGS                   (4)
#define ASURA_PS2_GSM__SIZE__CONST_CAM_DATA             (20)
#define ASURA_PS2_GSM__SIZE__CONST_SHADOW_DATA          (1)
#define ASURA_PS2_GSM__SIZE__RENDERSTATE_BFR            (10)
#define ASURA_PS2_GSM__SIZE__PER_OBJ_CAM_DATA_BFR       (48)
#define ASURA_PS2_GSM__SIZE__LIGHT_DATA_BFR             (15)
#define ASURA_PS2_GSM__SIZE__SHADOW_DATA_BFR            (6)
#define ASURA_PS2_GSM__SIZE__ST_SCALE_AND_TRANS_PARAMS  (1)
#define ASURA_PS2_GSM__SIZE__Y_SCALE_AND_TRANS_PARAMS   (2)
#define ASURA_PS2_GSM__SIZE__INPUT_BFR                  (176)
#define ASURA_PS2_GSM__SIZE__ST_OVERWRITE_BFR           (47)
#define ASURA_PS2_GSM__SIZE__CLIP_INPUT_BFR             (132)
#define ASURA_PS2_GSM__SIZE__OUTPUT_BFR                 (133)
#define ASURA_PS2_GSM__SIZE__RS_OUTPUT_BFR              (8)
#define ASURA_PS2_GSM__SIZE__VI_REG_STACK               (6)
#define ASURA_PS2_GSM__SIZE__SHADOW_PALETTE				(25)	// allows 5 shadows of 5 QW each (matrix plus falloff controls)

// GIF tag buffer details.
#define ASURA_PS2_GSM__OFFSET__GIF_TAGS_GEOM_SETUP      (0)
#define ASURA_PS2_GSM__OFFSET__GIF_TAGS_GEOM_DRAW       (1)
#define ASURA_PS2_GSM__OFFSET__GIF_TAGS_SHADOW_SETUP    (2)
#define ASURA_PS2_GSM__OFFSET__GIF_TAGS_SHADOW_DRAW     (3)

// Constant cam data buffer details.
#define ASURA_PS2_GSM__OFFSET__CONST_CAM_SCISSOR        (0)
#define ASURA_PS2_GSM__OFFSET__CONST_CAM_XYOFFSET       (1)
#define ASURA_PS2_GSM__OFFSET__CONST_CAM_GBC2S_SCALE    (2)
#define ASURA_PS2_GSM__OFFSET__CONST_CAM_GBC2S_TRANS    (3)
#define ASURA_PS2_GSM__OFFSET__CONST_CAM_GBC2SC_SCALE   (4)
#define ASURA_PS2_GSM__OFFSET__CONST_CAM_NEXT_CAM       (5)

// Constant shadow data buffer details.
#define ASURA_PS2_GSM__OFFSET__CONST_SHADOW_RGBAQ       (0)

// GIF tag and renderstate input buffer details.
#define ASURA_PS2_GSM__OFFSET__RS_IN_BASE_ALPHA         (0)
#define ASURA_PS2_GSM__OFFSET__RS_IN_BASE_TEX1          (1)	
#define ASURA_PS2_GSM__OFFSET__RS_IN_BASE_MIPTBP1       (2)
#define ASURA_PS2_GSM__OFFSET__RS_IN_BASE_TEX0          (3)
#define ASURA_PS2_GSM__OFFSET__RS_IN_BASE_TEST          (4)
#define ASURA_PS2_GSM__OFFSET__RS_IN_SELF_ILLUM_ALPHA   (5)
#define ASURA_PS2_GSM__OFFSET__RS_IN_ST_OV_ALPHA        (6)
#define ASURA_PS2_GSM__OFFSET__RS_IN_ST_OV_TEX1         (7)
#define ASURA_PS2_GSM__OFFSET__RS_IN_ST_OV_MIPTBP1      (8)
#define ASURA_PS2_GSM__OFFSET__RS_IN_ST_OV_TEX0         (9)

// Additional usage for rendering shadows - base stuff is the same but we reuse the 
// multi-pass stuff to allow quick and easy replacement of texture pointer for up to 5 shadows
#define ASURA_PS2_GSM__OFFSET__RS_IN_TEX0_SHADOW0       (5)       
#define ASURA_PS2_GSM__OFFSET__RS_IN_TEX0_SHADOW1       (6) 
#define ASURA_PS2_GSM__OFFSET__RS_IN_TEX0_SHADOW2       (7)       
#define ASURA_PS2_GSM__OFFSET__RS_IN_TEX0_SHADOW3       (8)       
#define ASURA_PS2_GSM__OFFSET__RS_IN_TEX0_SHADOW4       (9)    

#define ASURA_PS2_GSM__OFFSET__RS_IN_SHADOW_CLAMP       (2)	// overload unused MIP with CLAMP

// Per-object cam data buffer details.
#define ASURA_PS2_GSM__OFFSET__CAM_PER_OBJ_O2GBC_MAT    (0)
#define ASURA_PS2_GSM__OFFSET__CAM_PER_OBJ_O2V_MAT      (4)
#define ASURA_PS2_GSM__OFFSET__CAM_PER_OBJ_TEX_MAT      (8)
#define ASURA_PS2_GSM__OFFSET__CAM_PER_OBJ_NEXT_CAM     (12)

// Light data buffer details.
#define ASURA_PS2_GSM__OFFSET__QW_CONTAINING_QTY        (1)

// Shadow data buffer details.
#define ASURA_PS2_GSM__OFFSET__SHADOW_PROJ_MAT          (0)
#define ASURA_PS2_GSM__OFFSET__SHADOW_QUAD_PARAMS_0     (4)
#define ASURA_PS2_GSM__OFFSET__SHADOW_QUAD_PARAMS_1     (5)

// Y params buffer details.
#define ASURA_PS2_GSM__OFFSET__Y_PARAMS_ANGLE           (0)
#define ASURA_PS2_GSM__OFFSET__Y_PARAMS_Y               (1)

// Clipper workspace buffer details.
#define ASURA_PS2_GSM__SIZE__CLIP_WORKSPACE             (36)  // Up to 9 vertices with 4 QWs per vertex.
#define ASURA_PS2_GSM__SIZE__CLIPPED_STS                (15)  // See memory map above for calculations.
#define ASURA_PS2_GSM__OFFSET__CLIP_WORKSPACE           (46)  //                  "
#define ASURA_PS2_GSM__OFFSET__CLIPPED_STS              (118) //                  "

// Geometry output buffer details for normal geometry.
#define ASURA_PS2_GSM__OFFSET__GEOM_OUT_DRAW_GIF_TAG    (0)
#define ASURA_PS2_GSM__OFFSET__GEOM_OUT_FIRST_VERTEX    (1)

// Geometry output buffer details for shadow geometry.
#define ASURA_PS2_GSM__OFFSET__SHADOW_OUT_SETUP_GIF_TAG (0)
#define ASURA_PS2_GSM__OFFSET__SHADOW_OUT_RGBAQ         (1)
#define ASURA_PS2_GSM__OFFSET__SHADOW_OUT_DRAW_GIF_TAG  (2)
#define ASURA_PS2_GSM__OFFSET__SHADOW_OUT_FIRST_VTX     (3)

// RS output buffer details for first (base) pass.
#define ASURA_PS2_GSM__OFFSET__RS_OUT_0_SETUP_GIF_TAG   (0)
#define ASURA_PS2_GSM__OFFSET__RS_OUT_0_SCISSOR         (1)
#define ASURA_PS2_GSM__OFFSET__RS_OUT_0_XYOFFSET        (2)
#define ASURA_PS2_GSM__OFFSET__RS_OUT_0_ALPHA           (3)
#define ASURA_PS2_GSM__OFFSET__RS_OUT_0_TEX1            (4)
#define ASURA_PS2_GSM__OFFSET__RS_OUT_0_MIPTBP1         (5)
#define ASURA_PS2_GSM__OFFSET__RS_OUT_0_TEX0            (6)
#define ASURA_PS2_GSM__OFFSET__RS_OUT_0_TEST            (7)
#define ASURA_PS2_GSM__RS_OUT_0_NLOOP                   (7)

// RS output buffer details for second (self-illuminating) pass.
#define ASURA_PS2_GSM__OFFSET__RS_OUT_1_SETUP_GIF_TAG   (0)
#define ASURA_PS2_GSM__OFFSET__RS_OUT_1_ALPHA           (1)
#define ASURA_PS2_GSM__RS_OUT_1_NLOOP                   (1)

// RS output buffer details for third (ST overwrite) pass.
#define ASURA_PS2_GSM__OFFSET__RS_OUT_2_SETUP_GIF_TAG   (0)
#define ASURA_PS2_GSM__OFFSET__RS_OUT_2_ALPHA           (1)
#define ASURA_PS2_GSM__OFFSET__RS_OUT_2_TEX1            (2)
#define ASURA_PS2_GSM__OFFSET__RS_OUT_2_MIPTBP1         (3)
#define ASURA_PS2_GSM__OFFSET__RS_OUT_2_TEX0            (4)
#define ASURA_PS2_GSM__RS_OUT_2_NLOOP                   (4)

// VI register stack aliases.
#define ASURA_PS2_GSM__ADDR__VI_STACK_0                 (ASURA_PS2_GSM__ADDR__VI_REG_STACK + 0)
#define ASURA_PS2_GSM__ADDR__VI_STACK_1                 (ASURA_PS2_GSM__ADDR__VI_REG_STACK + 1)
#define ASURA_PS2_GSM__ADDR__VI_STACK_2                 (ASURA_PS2_GSM__ADDR__VI_REG_STACK + 2)
#define ASURA_PS2_GSM__ADDR__VI_STACK_3                 (ASURA_PS2_GSM__ADDR__VI_REG_STACK + 3)
#define ASURA_PS2_GSM__ADDR__VI_STACK_4                 (ASURA_PS2_GSM__ADDR__VI_REG_STACK + 4)
#define ASURA_PS2_GSM__ADDR__VI_STACK_5                 (ASURA_PS2_GSM__ADDR__VI_REG_STACK + 5)

// Shadow palette step size
#define ASURA_PS2_GSM__SIZE__SHADOW_PALETTE_ENTRY		(5)	// each entry is a WHOLE MATRIX plus 4 floats for the fall off calcs

// Change this to 0 in order to see what can be done with perspective adjustment for shadow stretch
// but be aware that it would require significant rewriting of all of GSM renderer to solve the problems with the clipped version that this causes
#define NO_PERSPECTIVE_ADJUST	1

// shadow projection front falloff slope adjustment
// use to modify how quickly shadows fade off above the objects centre - note MUST keep these the same value!
#define SHADOW_FALLOFF_SLOPE_SCALE    8.0
#define SHADOW_FALLOFF_SLOPE_SCALEF   8.0f

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

#endif // #ifndef ___ASURA_PS2_GSMDEFINES_H___
