007/include/gbi_extension.h

303 lines
13 KiB
C

#ifndef _GBI_EXT_H_
# define _GBI_EXT_H_
#include <PR/gbi.h>
#define TRI4_Ext
/**
* This file should contain most of the extensions to gbi avoiding loosing
* changes should the OS ever be updated.
*/
/**
These are some helper constants. Since they relate to nothing else except GBI
macros, Ill place them here, to save reserving names that might be used
elsewhere - though doubtfull.
*/
#define MASK_2 1
#define MASK_4 2
#define MASK_8 3
#define MASK_16 4
#define MASK_32 5
#define MASK_64 6
#define MASK_128 7
#define MASK_256 8
#define MASK_512 9
#define MASK_1024 10
/* Set the Texel Scale (0.0 - 1.0) for multiplying UV's eg, 0.5 * (31 << 6) = 31.0 */
#define CALC_TEXSCALE(scale) scale < 1.0f ? scale * 0x10000 : 0xffff
/* Set the Lower Right S Coordinate using texture width */
#define CALC_LRS(width, height, siz) ((((width) * (height) + siz##_INCR) >> siz##_SHIFT) - 1)
#define CALC_TILESIZE(texel) ((texel)-1) << G_TEXTURE_IMAGE_FRAC
#ifdef TRI4_Ext
# define G_TRI4 (G_IMMFIRST - 14)
# define G_SETTEX 0xc0 /* 0 */
#endif
/* Fade Modes ... for GE? */
#define G_CC_MODULATEIFADE TEXEL0, 0, SHADE, 0, 0, 0, 0, ENVIRONMENT
#define G_CC_MODULATERGBFADE G_CC_MODULATEIFADE
#define G_CC_MODULATEIFADEA TEXEL0, 0, SHADE, 0, TEXEL0, 0, ENVIRONMENT, 0
#define G_CC_MODULATEFADE TEXEL0, 0, SHADE, 0, ENVIRONMENT, 0, TEXEL0, 0
#define G_CC_MODULATERGBFADEA G_CC_MODULATEIFADEA
#define G_CC_FADE SHADE, 0, ENVIRONMENT, 0, SHADE, 0, ENVIRONMENT, 0
#define G_CC_FADEA TEXEL0, 0, ENVIRONMENT, 0, TEXEL0, 0, ENVIRONMENT, 0
#define G_CC_DECALFADE 0, 0, 0, TEXEL0, 0, 0, 0, ENVIRONMENT
#define G_CC_DECALFADEA 0, 0, 0, TEXEL0, TEXEL0, 0, ENVIRONMENT, 0
#define G_CC_BLENDRGBFADEA TEXEL0, SHADE, TEXEL0_ALPHA, SHADE, 0, 0, 0, ENVIRONMENT
#define G_CC_ADDRGBFADE TEXEL0, 0, TEXEL0, SHADE, 0, 0, 0, ENVIRONMENT
#define G_CC_SHADEFADEA 0, 0, 0, SHADE, 0, 0, 0, ENVIRONMENT
/* Custom version of RM_AA_ZB_XLU_SURF with Z_UPD */
#define RM_CUSTOM_AA_ZB_XLU_SURF(clk) \
RM_AA_ZB_XLU_SURF(clk) | Z_UPD
#define G_RM_CUSTOM_AA_ZB_XLU_SURF RM_CUSTOM_AA_ZB_XLU_SURF(1)
#define G_RM_CUSTOM_AA_ZB_XLU_SURF2 RM_CUSTOM_AA_ZB_XLU_SURF(2)
#ifdef TRI4_Ext
/***
*** 4 Triangles
***/
/**
* Remarks:
* Ryan: I've been learning a lot about PD's graphics microcode lately. It's likely that the decision to
* implement tri4 was to reduce memory usage in RDRAM. But to fit 4 tris in one command they had to limit
* themselves to 4 bits per vertex, which means they can only address up to 16 vertices. They could have
* fit 32 vertices in DMEM if they wanted. In stock microcodes the vertex IDs are pre-multiplied by 10
* which makes it easy for the RSP to calculate the vertex offset in the DMEM buffer (it can use a
* single shift operation). But because PD is using a compact format there's more work for the RSP to
* calculate it. So they've sacrificed RSP performance for memory saving.
*/
//cannot use 2tri with 4tri, so lets just make sure they are undefined so errors happen.
#undef gSP2Triangles
#undef gsSP2Triangles
/**
Draw up to 4 triangles at a time.
Vertex index is 0-15, to use a higher index use gSP1Triangle
*/
#define gSP4Triangles(pkt, x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4) \
{ \
Gfx *_g = (Gfx *)(pkt); \
\
_g->words.w0 = (_SHIFTL(G_TRI4, 24, 8) \
| _SHIFTL(z4, 12, 4) \
| _SHIFTL(z3, 8, 4) \
| _SHIFTL(z2, 4, 4) \
| _SHIFTL(z1, 0, 4)); \
_g->words.w1 = (_SHIFTL(y4, 28, 4) \
| _SHIFTL(x4, 24, 4) \
| _SHIFTL(y3, 20, 4) \
| _SHIFTL(x3, 16, 4) \
| _SHIFTL(y2, 12, 4) \
| _SHIFTL(x2, 8, 4) \
| _SHIFTL(y1, 4, 4) \
| _SHIFTL(x1, 0, 4)); \
}
/**
Draw up to 4 triangles at a time.
Vertex index is 0-15, to use a higher index use gSP1Triangle
*/
#define gsSP4Triangles(x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4) \
{ \
{ \
(_SHIFTL(G_TRI4, 24, 8) \
| _SHIFTL(z4, 12, 4) \
| _SHIFTL(z3, 8, 4) \
| _SHIFTL(z2, 4, 4) \
| _SHIFTL(z1, 0, 4)), \
(_SHIFTL(y4, 28, 4) \
| _SHIFTL(x4, 24, 4) \
| _SHIFTL(y3, 20, 4) \
| _SHIFTL(x3, 16, 4) \
| _SHIFTL(y2, 12, 4) \
| _SHIFTL(x2, 8, 4) \
| _SHIFTL(y1, 4, 4) \
| _SHIFTL(x1, 0, 4)) \
} \
}
/**
Source compatable F3DEX gSP2Triangles for GE
Vertex index is 0-15, to use a higher index use gSP1Triangle
*/
#define gSP2Triangles(pkt, x1, y1, z1, flag0, x2, y2, z2, flag1) \
gSP4Triangles(pkt, x1, y1, z1, x2, y2, z2, 0, 0, 0, 0, 0, 0)
#define gsSP2Triangles(x1, y1, z1, flag0, x2, y2, z2, flag1) \
gsSP4Triangles(x1, y1, z1, x2, y2, z2, 0, 0, 0, 0, 0, 0)
/**
* B1 rsp_tri4
* Draws up to four triangles at a time.
* Expects values from 0-F, corresponding with # points declared by vertex command.
* Triangles with all points set to 0 are not drawn.
*
* upper word
* 0000F000 z4
* 00000F00 z3
* 000000F0 z2
* 0000000F z1
*
* lower word
* f0000000 y4
* 0f000000 x4
* 00f00000 y3
* 000f0000 x3
* 0000f000 y2
* 00000f00 x2
* 000000f0 y1
* 0000000f x1
*/
#define gDPTri4(pkt, x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4) \
{ \
Gfx *_g = (Gfx *)(pkt); \
_g->words.w0 = (_SHIFTL(G_TRI4, 24, 8) \
| _SHIFTL(z4, 12, 4) \
| _SHIFTL(z3, 8, 4) \
| _SHIFTL(z2, 4, 4) \
| _SHIFTL(z1, 0, 4)); \
_g->words.w1 = (_SHIFTL(y4, 28, 4) \
| _SHIFTL(x4, 24, 4) \
| _SHIFTL(y3, 20, 4) \
| _SHIFTL(x3, 16, 4) \
| _SHIFTL(y2, 12, 4) \
| _SHIFTL(x2, 8, 4) \
| _SHIFTL(y1, 4, 4) \
| _SHIFTL(x1, 0, 4)); \
}
#define gDPTri3(pkt, x1, y1, z1, x2, y2, z2, x3, y3, z3) \
gDPTri4(pkt, x1, y1, z1, x2, y2, z2, x3, y3, z3, 0, 0, 0)
#define gDPTri2(pkt, x1, y1, z1, x2, y2, z2) \
gDPTri4(pkt, x1, y1, z1, x2, y2, z2, 0, 0, 0, 0, 0, 0)
#define gDPTri1(pkt, x1, y1, z1) \
gDPTri4(pkt, x1, y1, z1, 0, 0, 0, 0, 0, 0, 0, 0, 0)
#define gDPLoadTLUT06(pkt, a, b, c, d) \
{ \
Gfx *_g = (Gfx *)pkt; \
_g->words.w0 = _SHIFTL(G_LOADTLUT, 24, 8) | _SHIFTL((a), 14, 10) | _SHIFTL((b), 2, 10); \
_g->words.w1 = _SHIFTL(0x06, 24, 8) | _SHIFTL((c), 14, 10) | _SHIFTL((d), 2, 10); \
}
#define gDPLoadTLUT07(pkt, a, b, c, d) \
{ \
Gfx *_g = (Gfx *)pkt; \
_g->words.w0 = _SHIFTL(G_LOADTLUT, 24, 8) | _SHIFTL((a), 14, 10) | _SHIFTL((b), 2, 10); \
_g->words.w1 = _SHIFTL(0x07, 24, 8) | _SHIFTL((c), 14, 10) | _SHIFTL((d), 2, 10); \
}
#define gDPLoadTLUTCmd2(pkt, tile, count) \
{ \
Gfx *_g = (Gfx *)pkt; \
\
_g->words.w0 = _SHIFTL(G_LOADTLUT, 24, 8) | 0xff0; \
_g->words.w1 = _SHIFTL((tile), 24, 3) | _SHIFTL((count), 14, 10) | 0xff0;\
}
/*
* Texturing macro Overrides
*/
#define gsSPUseTexture()\
{ \
{ \
(_SHIFTL(G_SETTEX, 24, 8) | \
/*STUFF GOES HERE*/), \
/*STUFF GOES HERE*/ \
} \
}
#endif
/**
* Like gDPSetPrimColor, but is useful when the input colour is already in
* RGBA format. It avoids unnecessary bitshifting and masking.
*/
#define gDPSetPrimColorViaWord(pkt, m, l, rgba) \
{ \
Gfx *_g = (Gfx *)(pkt); \
_g->words.w0 = (_SHIFTL(G_SETPRIMCOLOR, 24, 8) \
| _SHIFTL(m, 8, 8) \
| _SHIFTL(l, 0, 8)); \
_g->words.w1 = (rgba); \
}
#define gDPSetEnvColorViaWord(pkt, rgba) gDPSetColor(pkt, G_SETENVCOLOR, rgba)
#define gDPSetFogColorViaWord(pkt, rgba) gDPSetColor(pkt, G_SETFOGCOLOR, rgba)
#if 0 //Rare - so far - didnt seem to use this
#undef gDPLoadTextureBlock
/**
Override of Load Texture Block without the PipeSync.
Loads a Texture and sets its tile
@param timg: Address of the texture image. E.g. IMAGESEG(IMAGE_SMOKE_0)
@param fmt: Texture image format: E.g. G_IM_FMT_IA
@param siz: Pixel component size: E.g. G_IM_SIZ_8b
@param width: Texture image width
@param height: Texture image height
@param pal: Location of palette for 4-bit color index texture (0 - 15)
@param cms: s-axis mirror, no-mirror, wrap, and clamp flags
@param cmt: t-axis mirror, no-mirror, wrap, and clamp flags
@param masks: s-axis mask (0 - 15 or G_TX_NOMASK)
@param maskt: t-axis mask (0 - 15 or G_TX_NOMASK)
@param shifts: s-coordinate shift value or G_TX_NOLOD
@param shiftt: t-coordinate shift value or G_TX_NOLOD
*/
#define gDPLoadTextureBlock(pkt, timg, fmt, siz, width, height, pal, cms, cmt, masks, maskt, shifts, shiftt) \
{ \
gDPSetTextureImage(pkt, fmt, siz##_LOAD_BLOCK, 1, timg); \
gDPSetTile(pkt, fmt, siz##_LOAD_BLOCK, 0, 0, G_TX_LOADTILE, 0, cmt, maskt, shiftt, cms, masks, shifts); \
gDPLoadSync(pkt); \
gDPLoadBlock(pkt, G_TX_LOADTILE, 0, 0, (((width) * (height) + siz##_INCR) >> siz##_SHIFT) - 1, CALC_DXT(width, siz##_BYTES)); \
gDPSetTile(pkt, fmt, siz, (((width)*siz##_LINE_BYTES) + 7) >> 3, 0, G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks, shifts); \
gDPSetTileSize(pkt, G_TX_RENDERTILE, 0, 0, ((width)-1) << G_TEXTURE_IMAGE_FRAC, ((height)-1) << G_TEXTURE_IMAGE_FRAC) \
}
#undef gsDPLoadTextureBlock
/**
Override of Load Texture Block (static) without the PipeSync.
Loads a Texture and sets its tile
@param timg: Address of the texture image. E.g. IMAGESEG(IMAGE_SMOKE_0)
@param fmt: Texture image format: E.g. G_IM_FMT_IA
@param siz: Pixel component size: E.g. G_IM_SIZ_8b
@param width: Texture image width
@param height: Texture image height
@param pal: Location of palette for 4-bit color index texture (0 - 15)
@param cms: s-axis mirror, no-mirror, wrap, and clamp flags
@param cmt: t-axis mirror, no-mirror, wrap, and clamp flags
@param masks: s-axis mask (0 - 15 or G_TX_NOMASK)
@param maskt: t-axis mask (0 - 15 or G_TX_NOMASK)
@param shifts: s-coordinate shift value or G_TX_NOLOD
@param shiftt: t-coordinate shift value or G_TX_NOLOD
*/
#define gsDPLoadTextureBlock(timg, fmt, siz, width, height, pal, cms, cmt, masks, maskt, shifts, shiftt) \
\
gsDPSetTextureImage(fmt, siz##_LOAD_BLOCK, 1, timg), \
gsDPSetTile(fmt, siz##_LOAD_BLOCK, 0, 0, G_TX_LOADTILE, 0, cmt, maskt, shiftt, cms, masks, shifts), \
gsDPLoadSync(), \
gsDPLoadBlock(G_TX_LOADTILE, 0, 0, (((width) * (height) + siz##_INCR) >> siz##_SHIFT) - 1, CALC_DXT(width, siz##_BYTES)), \
gsDPSetTile(fmt, siz, ((((width)*siz##_LINE_BYTES) + 7) >> 3), 0, G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks, shifts), \
gsDPSetTileSize(G_TX_RENDERTILE, 0, 0, ((width)-1) << G_TEXTURE_IMAGE_FRAC, ((height)-1) << G_TEXTURE_IMAGE_FRAC)
#endif
#endif