mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2024-11-28 15:03:01 +00:00
6995b1a07c
This reverts commit f994ffbe8c
.
4819 lines
158 KiB
C
4819 lines
158 KiB
C
/**************************************************************************
|
|
* *
|
|
* Copyright (C) 1994, Silicon Graphics, Inc. *
|
|
* *
|
|
* These coded instructions, statements, and computer programs contain *
|
|
* unpublished proprietary information of Silicon Graphics, Inc., and *
|
|
* are protected by Federal copyright law. They may not be disclosed *
|
|
* to third parties or copied or duplicated in any form, in whole or *
|
|
* in part, without the prior written consent of Silicon Graphics, Inc. *
|
|
* *
|
|
**************************************************************************/
|
|
/**************************************************************************
|
|
*
|
|
* $Revision: 1.141 $
|
|
* $Date: 1999/09/03 03:43:08 $
|
|
* $Source: /exdisk2/cvs/N64OS/Master/cvsmdev2/PR/include/gbi.h,v $
|
|
*
|
|
**************************************************************************/
|
|
|
|
#ifndef _GBI_H_
|
|
#define _GBI_H_
|
|
|
|
#include <PR/ultratypes.h>
|
|
#include "gbi_extension.h"
|
|
|
|
/*
|
|
* To use the F3DEX ucodes, define F3DEX_GBI before include this file.
|
|
*
|
|
* #define F3DEX_GBI
|
|
* #include <ultra64.h>
|
|
*
|
|
* or
|
|
*
|
|
* cc -c -DF3DEX_GBI -I.... foo.c
|
|
*
|
|
*/
|
|
|
|
/**************************************************************************
|
|
*
|
|
* Graphics Binary Interface
|
|
*
|
|
**************************************************************************/
|
|
|
|
/*
|
|
* Graphics Commands, 'xxx' parts may be generated from ucode
|
|
*
|
|
* The command format is
|
|
*
|
|
* |00xxxxxx| = DMA 0,..,127
|
|
* |10xxxxxx| = Immediate Mode -65,..,-128
|
|
* |11xxxxxx| = RDP cmds -1,..,-64
|
|
*
|
|
* Note: in order for the RSP microcode to process RDP commands opaquely,
|
|
* we need to further identify those RDP commands that need DRAM address
|
|
* "fixup". To do this, we have the dummy command G_RDP_ADDR_FIXUP, and
|
|
* all |RDP commands| less than this are commands with embedded DRAM
|
|
* addresses. Further, the format of these commands should be similar so
|
|
* only one fixup routine is needed.
|
|
*
|
|
* Further explanation:
|
|
* The names of the commands are somewhat misleading. Here is clarification:
|
|
*
|
|
* - a 'DMA' type command has a pointer to additional data and
|
|
* causes a DMA transfer to bring that into DMEM.
|
|
*
|
|
* - an 'Immediate' type command isn't really 'immediate', in the
|
|
* traditional sense. This just means that the entire command fits
|
|
* in the 64-bit word, and the ucode can execute it 'immediately'
|
|
* without additional memory transfers.
|
|
*
|
|
* - an 'RDP' command is identified as such because the RDP
|
|
* commands can be passed-thru the RSP and sent to the RDP
|
|
* directly. One further confusing thing, is that some 'DP'
|
|
* macros below actually generate immediate commands, not
|
|
* not direct DP commands.
|
|
*
|
|
* IMPLEMENTATION NOTE:
|
|
* There is another group of RDP commands that includes the triangle commands
|
|
* generated by the RSP code. These are the raw commands the rasterizer
|
|
* hardware chews on, with slope info, etc. They will follow the RDP
|
|
* ordering...
|
|
*
|
|
* IMPLEMENTATION NOTE:
|
|
* The RDP hardware has some of these bit patterns wired up. If the hardware
|
|
* changes, we must adjust this table, likewise we can't change/add things
|
|
* once the hardware is frozen. (actually, the RDP hardware only looks at
|
|
* the lower 6 bits of the command byte)
|
|
*
|
|
*/
|
|
|
|
#ifdef F3DEX_GBI_2E
|
|
# ifndef F3DEX_GBI_2
|
|
# define F3DEX_GBI_2
|
|
# endif
|
|
# define GBI_FLOATS
|
|
#endif
|
|
|
|
#ifdef F3DEX_GBI_2
|
|
# ifndef F3DEX_GBI
|
|
# define F3DEX_GBI
|
|
# endif
|
|
#define G_NOOP 0x00
|
|
#define G_RDPHALF_2 0xf1
|
|
#define G_SETOTHERMODE_H 0xe3
|
|
#define G_SETOTHERMODE_L 0xe2
|
|
#define G_RDPHALF_1 0xe1
|
|
#define G_SPNOOP 0xe0
|
|
#define G_ENDDL 0xdf
|
|
#define G_DL 0xde
|
|
#define G_LOAD_UCODE 0xdd
|
|
#define G_MOVEMEM 0xdc
|
|
#define G_MOVEWORD 0xdb
|
|
#define G_MTX 0xda
|
|
#define G_GEOMETRYMODE 0xd9
|
|
#define G_POPMTX 0xd8
|
|
#define G_TEXTURE 0xd7
|
|
#define G_DMA_IO 0xd6
|
|
#define G_SPECIAL_1 0xd5
|
|
#define G_SPECIAL_2 0xd4
|
|
#define G_SPECIAL_3 0xd3
|
|
|
|
#ifdef F3DEX_GBI_2E
|
|
/* extended commands */
|
|
#define G_COPYMEM 0xd2
|
|
#endif
|
|
|
|
#define G_VTX 0x01
|
|
#define G_MODIFYVTX 0x02
|
|
#define G_CULLDL 0x03
|
|
#define G_BRANCH_Z 0x04
|
|
#define G_TRI1 0x05
|
|
#define G_TRI2 0x06
|
|
#define G_QUAD 0x07
|
|
#define G_LINE3D 0x08
|
|
#else /* F3DEX_GBI_2 */
|
|
|
|
/* DMA commands: */
|
|
#define G_SPNOOP 0 /* handle 0 gracefully */
|
|
#define G_MTX 1
|
|
#define G_RESERVED0 2 /* not implemeted */
|
|
#define G_MOVEMEM 3 /* move a block of memory (up to 4 words) to dmem */
|
|
#define G_VTX 4
|
|
#define G_RESERVED1 5 /* not implemeted */
|
|
#define G_DL 6
|
|
#define G_RESERVED2 7 /* not implemeted */
|
|
#define G_RESERVED3 8 /* not implemeted */
|
|
#define G_SPRITE2D_BASE 9 /* sprite command */
|
|
|
|
/* IMMEDIATE commands: */
|
|
#define G_IMMFIRST -65
|
|
#define G_TRI1 (G_IMMFIRST-0)
|
|
#define G_CULLDL (G_IMMFIRST-1)
|
|
#define G_POPMTX (G_IMMFIRST-2)
|
|
#define G_MOVEWORD (G_IMMFIRST-3)
|
|
#define G_TEXTURE (G_IMMFIRST-4)
|
|
#define G_SETOTHERMODE_H (G_IMMFIRST-5)
|
|
#define G_SETOTHERMODE_L (G_IMMFIRST-6)
|
|
#define G_ENDDL (G_IMMFIRST-7)
|
|
#define G_SETGEOMETRYMODE (G_IMMFIRST-8)
|
|
#define G_CLEARGEOMETRYMODE (G_IMMFIRST-9)
|
|
#define G_LINE3D (G_IMMFIRST-10)
|
|
#define G_RDPHALF_1 (G_IMMFIRST-11)
|
|
#define G_RDPHALF_2 (G_IMMFIRST-12)
|
|
#if (defined(F3DEX_GBI)||defined(F3DLP_GBI))
|
|
# define G_MODIFYVTX (G_IMMFIRST-13)
|
|
# define G_TRI2 (G_IMMFIRST-14)
|
|
# define G_BRANCH_Z (G_IMMFIRST-15)
|
|
# define G_LOAD_UCODE (G_IMMFIRST-16)
|
|
#else
|
|
# define G_RDPHALF_CONT (G_IMMFIRST-13)
|
|
#endif
|
|
|
|
/* We are overloading 2 of the immediate commands
|
|
to keep the byte alignment of dmem the same */
|
|
|
|
#define G_SPRITE2D_SCALEFLIP (G_IMMFIRST-1)
|
|
#define G_SPRITE2D_DRAW (G_IMMFIRST-2)
|
|
|
|
/* RDP commands: */
|
|
#define G_NOOP 0xc0 /* 0 */
|
|
|
|
#endif /* F3DEX_GBI_2 */
|
|
|
|
/* RDP commands: */
|
|
#define G_SETCIMG 0xff /* -1 */
|
|
#define G_SETZIMG 0xfe /* -2 */
|
|
#define G_SETTIMG 0xfd /* -3 */
|
|
#define G_SETCOMBINE 0xfc /* -4 */
|
|
#define G_SETENVCOLOR 0xfb /* -5 */
|
|
#define G_SETPRIMCOLOR 0xfa /* -6 */
|
|
#define G_SETBLENDCOLOR 0xf9 /* -7 */
|
|
#define G_SETFOGCOLOR 0xf8 /* -8 */
|
|
#define G_SETFILLCOLOR 0xf7 /* -9 */
|
|
#define G_FILLRECT 0xf6 /* -10 */
|
|
#define G_SETTILE 0xf5 /* -11 */
|
|
#define G_LOADTILE 0xf4 /* -12 */
|
|
#define G_LOADBLOCK 0xf3 /* -13 */
|
|
#define G_SETTILESIZE 0xf2 /* -14 */
|
|
#define G_LOADTLUT 0xf0 /* -16 */
|
|
#define G_RDPSETOTHERMODE 0xef /* -17 */
|
|
#define G_SETPRIMDEPTH 0xee /* -18 */
|
|
#define G_SETSCISSOR 0xed /* -19 */
|
|
#define G_SETCONVERT 0xec /* -20 */
|
|
#define G_SETKEYR 0xeb /* -21 */
|
|
#define G_SETKEYGB 0xea /* -22 */
|
|
#define G_RDPFULLSYNC 0xe9 /* -23 */
|
|
#define G_RDPTILESYNC 0xe8 /* -24 */
|
|
#define G_RDPPIPESYNC 0xe7 /* -25 */
|
|
#define G_RDPLOADSYNC 0xe6 /* -26 */
|
|
#define G_TEXRECTFLIP 0xe5 /* -27 */
|
|
#define G_TEXRECT 0xe4 /* -28 */
|
|
|
|
|
|
/*
|
|
* The following commands are the "generated" RDP commands; the user
|
|
* never sees them, the RSP microcode generates them.
|
|
*
|
|
* The layout of the bits is magical, to save work in the ucode.
|
|
* These id's are -56, -52, -54, -50, -55, -51, -53, -49, ...
|
|
* edge, shade, texture, zbuff bits: estz
|
|
*/
|
|
#define G_TRI_FILL 0xc8 /* fill triangle: 11001000 */
|
|
#define G_TRI_SHADE 0xcc /* shade triangle: 11001100 */
|
|
#define G_TRI_TXTR 0xca /* texture triangle: 11001010 */
|
|
#define G_TRI_SHADE_TXTR 0xce /* shade, texture triangle: 11001110 */
|
|
#define G_TRI_FILL_ZBUFF 0xc9 /* fill, zbuff triangle: 11001001 */
|
|
#define G_TRI_SHADE_ZBUFF 0xcd /* shade, zbuff triangle: 11001101 */
|
|
#define G_TRI_TXTR_ZBUFF 0xcb /* texture, zbuff triangle: 11001011 */
|
|
#define G_TRI_SHADE_TXTR_ZBUFF 0xcf /* shade, txtr, zbuff trngl: 11001111 */
|
|
|
|
/*
|
|
* A TRI_FILL triangle is just the edges. You need to set the DP
|
|
* to use primcolor, in order to see anything. (it is NOT a triangle
|
|
* that gets rendered in 'fill mode'. Triangles can't be rendered
|
|
* in 'fill mode')
|
|
*
|
|
* A TRI_SHADE is a gouraud triangle that has colors interpolated.
|
|
* Flat-shaded triangles (from the software) are still gouraud shaded,
|
|
* it's just the colors are all the same and the deltas are 0.
|
|
*
|
|
* Other triangle types, and combinations are more obvious.
|
|
*/
|
|
|
|
/* masks to build RDP triangle commands: */
|
|
#define G_RDP_TRI_FILL_MASK 0x08
|
|
#define G_RDP_TRI_SHADE_MASK 0x04
|
|
#define G_RDP_TRI_TXTR_MASK 0x02
|
|
#define G_RDP_TRI_ZBUFF_MASK 0x01
|
|
|
|
/*
|
|
* HACK:
|
|
* This is a dreadful hack. For version 1.0 hardware, there are still
|
|
* some 'bowtie' hangs. This parameter can be increased to avoid
|
|
* the hangs. Every increase of 4 chops one scanline off of every
|
|
* triangle. Values of 4,8,12 should be sufficient to avoid any
|
|
* bowtie hang.
|
|
*
|
|
* Change this value, then recompile ALL of your program (including static
|
|
* display lists!)
|
|
*
|
|
* THIS WILL BE REMOVED FOR HARDWARE VERSION 2.0!
|
|
*/
|
|
#define BOWTIE_VAL 0
|
|
|
|
|
|
/* gets added to RDP command, in order to test for addres fixup: */
|
|
#define G_RDP_ADDR_FIXUP 3 /* |RDP cmds| <= this, do addr fixup */
|
|
#ifdef _LANGUAGE_ASSEMBLY
|
|
#define G_RDP_TEXRECT_CHECK ((-1*G_TEXRECTFLIP)& 0xff)
|
|
#endif
|
|
|
|
/* macros for command parsing: */
|
|
#define GDMACMD(x) (x)
|
|
#define GIMMCMD(x) (G_IMMFIRST-(x))
|
|
#define GRDPCMD(x) (0xff-(x))
|
|
|
|
#define G_DMACMDSIZ 128
|
|
#define G_IMMCMDSIZ 64
|
|
#define G_RDPCMDSIZ 64
|
|
|
|
/*
|
|
* Coordinate shift values, number of bits of fraction
|
|
*/
|
|
#define G_TEXTURE_IMAGE_FRAC 2
|
|
#define G_TEXTURE_SCALE_FRAC 16
|
|
#define G_SCALE_FRAC 8
|
|
#define G_ROTATE_FRAC 16
|
|
|
|
/*
|
|
* Parameters to graphics commands
|
|
*/
|
|
|
|
/*
|
|
* Data packing macros
|
|
*/
|
|
|
|
/*
|
|
* Maximum z-buffer value, used to initialize the z-buffer.
|
|
* Note : this number is NOT the viewport z-scale constant.
|
|
* See the comment next to G_MAXZ for more info.
|
|
*/
|
|
#define G_MAXFBZ 0x3fff /* 3b exp, 11b mantissa */
|
|
|
|
#define GPACK_RGBA5551(r, g, b, a) ((((r)<<8) & 0xf800) | \
|
|
(((g)<<3) & 0x7c0) | \
|
|
(((b)>>2) & 0x3e) | ((a) & 0x1))
|
|
#define GPACK_ZDZ(z, dz) ((z) << 2 | (dz))
|
|
|
|
/*
|
|
* G_MTX: parameter flags
|
|
*/
|
|
#ifdef F3DEX_GBI_2
|
|
# define G_MTX_MODELVIEW 0x00 /* matrix types */
|
|
# define G_MTX_PROJECTION 0x04
|
|
# define G_MTX_MUL 0x00 /* concat or load */
|
|
# define G_MTX_LOAD 0x02
|
|
# define G_MTX_NOPUSH 0x00 /* push or not */
|
|
# define G_MTX_PUSH 0x01
|
|
#else /* F3DEX_GBI_2 */
|
|
# define G_MTX_MODELVIEW 0x00 /* matrix types */
|
|
# define G_MTX_PROJECTION 0x01
|
|
# define G_MTX_MUL 0x00 /* concat or load */
|
|
# define G_MTX_LOAD 0x02
|
|
# define G_MTX_NOPUSH 0x00 /* push or not */
|
|
# define G_MTX_PUSH 0x04
|
|
#endif /* F3DEX_GBI_2 */
|
|
|
|
/*
|
|
* flags for G_SETGEOMETRYMODE
|
|
* (this rendering state is maintained in RSP)
|
|
*
|
|
* DO NOT USE THE LOW 8 BITS OF GEOMETRYMODE:
|
|
* The weird bit-ordering is for the micro-code: the lower byte
|
|
* can be OR'd in with G_TRI_SHADE (11001100) to construct
|
|
* the triangle command directly. Don't break it...
|
|
*
|
|
* DO NOT USE THE HIGH 8 BITS OF GEOMETRYMODE:
|
|
* The high byte is OR'd with 0x703 to form the clip code mask.
|
|
* If it is set to 0x04, this will cause near clipping to occur.
|
|
* If it is zero, near clipping will not occur.
|
|
*
|
|
* Further explanation:
|
|
* G_SHADE is necessary in order to see the color that you passed
|
|
* down with the vertex. If G_SHADE isn't set, you need to set the DP
|
|
* appropriately and use primcolor to see anything.
|
|
*
|
|
* G_SHADING_SMOOTH enabled means use all 3 colors of the triangle.
|
|
* If it is not set, then do 'flat shading', where only one vertex color
|
|
* is used (and all 3 vertices are set to that same color by the ucode)
|
|
* See the man page for gSP1Triangle().
|
|
*
|
|
*/
|
|
#define G_ZBUFFER 0x00000001
|
|
#define G_SHADE 0x00000004 /* enable Gouraud interp */
|
|
/* rest of low byte reserved for setup ucode */
|
|
#ifdef F3DEX_GBI_2
|
|
# define G_TEXTURE_ENABLE 0x00000000 /* Ignored */
|
|
# define G_SHADING_SMOOTH 0x00200000 /* flat or smooth shaded */
|
|
# define G_CULL_FRONT 0x00000200
|
|
# define G_CULL_BACK 0x00000400
|
|
# define G_CULL_BOTH 0x00000600 /* To make code cleaner */
|
|
#else
|
|
# define G_TEXTURE_ENABLE 0x00000002 /* Microcode use only */
|
|
# define G_SHADING_SMOOTH 0x00000200 /* flat or smooth shaded */
|
|
# define G_CULL_FRONT 0x00001000
|
|
# define G_CULL_BACK 0x00002000
|
|
# define G_CULL_BOTH 0x00003000 /* To make code cleaner */
|
|
#endif
|
|
#define G_FOG 0x00010000
|
|
#define G_LIGHTING 0x00020000
|
|
#define G_TEXTURE_GEN 0x00040000
|
|
#define G_TEXTURE_GEN_LINEAR 0x00080000
|
|
#define G_LOD 0x00100000 /* NOT IMPLEMENTED */
|
|
#if (defined(F3DEX_GBI)||defined(F3DLP_GBI))
|
|
# define G_CLIPPING 0x00800000
|
|
#else
|
|
# define G_CLIPPING 0x00000000
|
|
#endif
|
|
|
|
#ifdef _LANGUAGE_ASSEMBLY
|
|
#define G_FOG_H (G_FOG/0x10000)
|
|
#define G_LIGHTING_H (G_LIGHTING/0x10000)
|
|
#define G_TEXTURE_GEN_H (G_TEXTURE_GEN/0x10000)
|
|
#define G_TEXTURE_GEN_LINEAR_H (G_TEXTURE_GEN_LINEAR/0x10000)
|
|
#define G_LOD_H (G_LOD/0x10000) /* NOT IMPLEMENTED */
|
|
#if (defined(F3DEX_GBI)||defined(F3DLP_GBI))
|
|
# define G_CLIPPING_H (G_CLIPPING/0x10000)
|
|
#endif
|
|
#endif
|
|
|
|
/* Need these defined for Sprite Microcode */
|
|
#ifdef _LANGUAGE_ASSEMBLY
|
|
#define G_TX_LOADTILE 7
|
|
#define G_TX_RENDERTILE 0
|
|
|
|
#define G_TX_NOMIRROR 0
|
|
#define G_TX_WRAP 0
|
|
#define G_TX_MIRROR 0x1
|
|
#define G_TX_CLAMP 0x2
|
|
#define G_TX_NOMASK 0
|
|
#define G_TX_NOLOD 0
|
|
#endif
|
|
|
|
/*
|
|
* G_SETIMG fmt: set image formats
|
|
*/
|
|
#define G_IM_FMT_RGBA 0
|
|
#define G_IM_FMT_YUV 1
|
|
#define G_IM_FMT_CI 2
|
|
#define G_IM_FMT_IA 3
|
|
#define G_IM_FMT_I 4
|
|
|
|
/*
|
|
* G_SETIMG siz: set image pixel size
|
|
*/
|
|
#define G_IM_SIZ_4b 0
|
|
#define G_IM_SIZ_8b 1
|
|
#define G_IM_SIZ_16b 2
|
|
#define G_IM_SIZ_32b 3
|
|
#define G_IM_SIZ_DD 5
|
|
|
|
#define G_IM_SIZ_4b_BYTES 0
|
|
#define G_IM_SIZ_4b_TILE_BYTES G_IM_SIZ_4b_BYTES
|
|
#define G_IM_SIZ_4b_LINE_BYTES G_IM_SIZ_4b_BYTES
|
|
|
|
#define G_IM_SIZ_8b_BYTES 1
|
|
#define G_IM_SIZ_8b_TILE_BYTES G_IM_SIZ_8b_BYTES
|
|
#define G_IM_SIZ_8b_LINE_BYTES G_IM_SIZ_8b_BYTES
|
|
|
|
#define G_IM_SIZ_16b_BYTES 2
|
|
#define G_IM_SIZ_16b_TILE_BYTES G_IM_SIZ_16b_BYTES
|
|
#define G_IM_SIZ_16b_LINE_BYTES G_IM_SIZ_16b_BYTES
|
|
|
|
#define G_IM_SIZ_32b_BYTES 4
|
|
#define G_IM_SIZ_32b_TILE_BYTES 2
|
|
#define G_IM_SIZ_32b_LINE_BYTES 2
|
|
|
|
#define G_IM_SIZ_4b_LOAD_BLOCK G_IM_SIZ_16b
|
|
#define G_IM_SIZ_8b_LOAD_BLOCK G_IM_SIZ_16b
|
|
#define G_IM_SIZ_16b_LOAD_BLOCK G_IM_SIZ_16b
|
|
#define G_IM_SIZ_32b_LOAD_BLOCK G_IM_SIZ_32b
|
|
|
|
#define G_IM_SIZ_4b_SHIFT 2
|
|
#define G_IM_SIZ_8b_SHIFT 1
|
|
#define G_IM_SIZ_16b_SHIFT 0
|
|
#define G_IM_SIZ_32b_SHIFT 0
|
|
|
|
#define G_IM_SIZ_4b_INCR 3
|
|
#define G_IM_SIZ_8b_INCR 1
|
|
#define G_IM_SIZ_16b_INCR 0
|
|
#define G_IM_SIZ_32b_INCR 0
|
|
|
|
/*
|
|
* G_SETCOMBINE: color combine modes
|
|
*/
|
|
/* Color combiner constants: */
|
|
#define G_CCMUX_COMBINED 0
|
|
#define G_CCMUX_TEXEL0 1
|
|
#define G_CCMUX_TEXEL1 2
|
|
#define G_CCMUX_PRIMITIVE 3
|
|
#define G_CCMUX_SHADE 4
|
|
#define G_CCMUX_ENVIRONMENT 5
|
|
#define G_CCMUX_CENTER 6
|
|
#define G_CCMUX_SCALE 6
|
|
#define G_CCMUX_COMBINED_ALPHA 7
|
|
#define G_CCMUX_TEXEL0_ALPHA 8
|
|
#define G_CCMUX_TEXEL1_ALPHA 9
|
|
#define G_CCMUX_PRIMITIVE_ALPHA 10
|
|
#define G_CCMUX_SHADE_ALPHA 11
|
|
#define G_CCMUX_ENV_ALPHA 12
|
|
#define G_CCMUX_LOD_FRACTION 13
|
|
#define G_CCMUX_PRIM_LOD_FRAC 14
|
|
#define G_CCMUX_NOISE 7
|
|
#define G_CCMUX_K4 7
|
|
#define G_CCMUX_K5 15
|
|
#define G_CCMUX_1 6
|
|
#define G_CCMUX_0 31
|
|
|
|
/* Alpha combiner constants: */
|
|
#define G_ACMUX_COMBINED 0
|
|
#define G_ACMUX_TEXEL0 1
|
|
#define G_ACMUX_TEXEL1 2
|
|
#define G_ACMUX_PRIMITIVE 3
|
|
#define G_ACMUX_SHADE 4
|
|
#define G_ACMUX_ENVIRONMENT 5
|
|
#define G_ACMUX_LOD_FRACTION 0
|
|
#define G_ACMUX_PRIM_LOD_FRAC 6
|
|
#define G_ACMUX_1 6
|
|
#define G_ACMUX_0 7
|
|
|
|
/* typical CC cycle 1 modes */
|
|
#define G_CC_PRIMITIVE 0, 0, 0, PRIMITIVE, 0, 0, 0, PRIMITIVE
|
|
#define G_CC_SHADE 0, 0, 0, SHADE, 0, 0, 0, SHADE
|
|
|
|
#define G_CC_MODULATEI TEXEL0, 0, SHADE, 0, 0, 0, 0, SHADE
|
|
#define G_CC_MODULATEIDECALA TEXEL0, 0, SHADE, 0, 0, 0, 0, TEXEL0
|
|
#define G_CC_MODULATEIFADE TEXEL0, 0, SHADE, 0, 0, 0, 0, ENVIRONMENT
|
|
|
|
#define G_CC_MODULATERGB G_CC_MODULATEI
|
|
#define G_CC_MODULATERGBDECALA G_CC_MODULATEIDECALA
|
|
#define G_CC_MODULATERGBFADE G_CC_MODULATEIFADE
|
|
|
|
#define G_CC_MODULATEIA TEXEL0, 0, SHADE, 0, TEXEL0, 0, SHADE, 0
|
|
#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_MODULATERGBA G_CC_MODULATEIA
|
|
#define G_CC_MODULATERGBFADEA G_CC_MODULATEIFADEA
|
|
|
|
#define G_CC_MODULATEI_PRIM TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, PRIMITIVE
|
|
#define G_CC_MODULATEIA_PRIM TEXEL0, 0, PRIMITIVE, 0, TEXEL0, 0, PRIMITIVE, 0
|
|
#define G_CC_MODULATEIDECALA_PRIM TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, TEXEL0
|
|
|
|
#define G_CC_MODULATERGB_PRIM G_CC_MODULATEI_PRIM
|
|
#define G_CC_MODULATERGBA_PRIM G_CC_MODULATEIA_PRIM
|
|
#define G_CC_MODULATERGBDECALA_PRIM G_CC_MODULATEIDECALA_PRIM
|
|
|
|
#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_DECALRGB 0, 0, 0, TEXEL0, 0, 0, 0, SHADE
|
|
#define G_CC_DECALRGBA 0, 0, 0, TEXEL0, 0, 0, 0, TEXEL0
|
|
#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_BLENDI ENVIRONMENT, SHADE, TEXEL0, SHADE, 0, 0, 0, SHADE
|
|
#define G_CC_BLENDIA ENVIRONMENT, SHADE, TEXEL0, SHADE, TEXEL0, 0, SHADE, 0
|
|
#define G_CC_BLENDIDECALA ENVIRONMENT, SHADE, TEXEL0, SHADE, 0, 0, 0, TEXEL0
|
|
|
|
#define G_CC_BLENDRGBA TEXEL0, SHADE, TEXEL0_ALPHA, SHADE, 0, 0, 0, SHADE
|
|
#define G_CC_BLENDRGBDECALA TEXEL0, SHADE, TEXEL0_ALPHA, SHADE, 0, 0, 0, TEXEL0
|
|
#define G_CC_BLENDRGBFADEA TEXEL0, SHADE, TEXEL0_ALPHA, SHADE, 0, 0, 0, ENVIRONMENT
|
|
|
|
#define G_CC_ADDRGB TEXEL0, 0, TEXEL0, SHADE, 0, 0, 0, SHADE
|
|
#define G_CC_ADDRGBDECALA TEXEL0, 0, TEXEL0, SHADE, 0, 0, 0, TEXEL0
|
|
#define G_CC_ADDRGBFADE TEXEL0, 0, TEXEL0, SHADE, 0, 0, 0, ENVIRONMENT
|
|
|
|
#define G_CC_REFLECTRGB ENVIRONMENT, 0, TEXEL0, SHADE, 0, 0, 0, SHADE
|
|
#define G_CC_REFLECTRGBDECALA ENVIRONMENT, 0, TEXEL0, SHADE, 0, 0, 0, TEXEL0
|
|
|
|
#define G_CC_HILITERGB PRIMITIVE, SHADE, TEXEL0, SHADE, 0, 0, 0, SHADE
|
|
#define G_CC_HILITERGBA PRIMITIVE, SHADE, TEXEL0, SHADE, PRIMITIVE, SHADE, TEXEL0, SHADE
|
|
#define G_CC_HILITERGBDECALA PRIMITIVE, SHADE, TEXEL0, SHADE, 0, 0, 0, TEXEL0
|
|
|
|
#define G_CC_SHADEDECALA 0, 0, 0, SHADE, 0, 0, 0, TEXEL0
|
|
#define G_CC_SHADEFADEA 0, 0, 0, SHADE, 0, 0, 0, ENVIRONMENT
|
|
|
|
#define G_CC_BLENDPE PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, SHADE, 0
|
|
#define G_CC_BLENDPEDECALA PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, 0, 0, 0, TEXEL0
|
|
|
|
/* oddball modes */
|
|
#define _G_CC_BLENDPE ENVIRONMENT, PRIMITIVE, TEXEL0, PRIMITIVE, TEXEL0, 0, SHADE, 0
|
|
#define _G_CC_BLENDPEDECALA ENVIRONMENT, PRIMITIVE, TEXEL0, PRIMITIVE, 0, 0, 0, TEXEL0
|
|
#define _G_CC_TWOCOLORTEX PRIMITIVE, SHADE, TEXEL0, SHADE, 0, 0, 0, SHADE
|
|
/* used for 1-cycle sparse mip-maps, primitive color has color of lowest LOD */
|
|
#define _G_CC_SPARSEST PRIMITIVE, TEXEL0, LOD_FRACTION, TEXEL0, PRIMITIVE, TEXEL0, LOD_FRACTION, TEXEL0
|
|
#define G_CC_TEMPLERP TEXEL1, TEXEL0, PRIM_LOD_FRAC, TEXEL0, TEXEL1, TEXEL0, PRIM_LOD_FRAC, TEXEL0
|
|
|
|
/* typical CC cycle 1 modes, usually followed by other cycle 2 modes */
|
|
#define G_CC_TRILERP TEXEL1, TEXEL0, LOD_FRACTION, TEXEL0, TEXEL1, TEXEL0, LOD_FRACTION, TEXEL0
|
|
#define G_CC_INTERFERENCE TEXEL0, 0, TEXEL1, 0, TEXEL0, 0, TEXEL1, 0
|
|
|
|
/*
|
|
* One-cycle color convert operation
|
|
*/
|
|
#define G_CC_1CYUV2RGB TEXEL0, K4, K5, TEXEL0, 0, 0, 0, SHADE
|
|
|
|
/*
|
|
* NOTE: YUV2RGB expects TF step1 color conversion to occur in 2nd clock.
|
|
* Therefore, CC looks for step1 results in TEXEL1
|
|
*/
|
|
#define G_CC_YUV2RGB TEXEL1, K4, K5, TEXEL1, 0, 0, 0, 0
|
|
|
|
/* typical CC cycle 2 modes */
|
|
#define G_CC_PASS2 0, 0, 0, COMBINED, 0, 0, 0, COMBINED
|
|
#define G_CC_MODULATEI2 COMBINED, 0, SHADE, 0, 0, 0, 0, SHADE
|
|
#define G_CC_MODULATEIA2 COMBINED, 0, SHADE, 0, COMBINED, 0, SHADE, 0
|
|
#define G_CC_MODULATERGB2 G_CC_MODULATEI2
|
|
#define G_CC_MODULATERGBA2 G_CC_MODULATEIA2
|
|
#define G_CC_MODULATEI_PRIM2 COMBINED, 0, PRIMITIVE, 0, 0, 0, 0, PRIMITIVE
|
|
#define G_CC_MODULATEIA_PRIM2 COMBINED, 0, PRIMITIVE, 0, COMBINED, 0, PRIMITIVE, 0
|
|
#define G_CC_MODULATERGB_PRIM2 G_CC_MODULATEI_PRIM2
|
|
#define G_CC_MODULATERGBA_PRIM2 G_CC_MODULATEIA_PRIM2
|
|
#define G_CC_DECALRGB2 0, 0, 0, COMBINED, 0, 0, 0, SHADE
|
|
/*
|
|
* ?
|
|
#define G_CC_DECALRGBA2 COMBINED, SHADE, COMBINED_ALPHA, SHADE, 0, 0, 0, SHADE
|
|
*/
|
|
#define G_CC_BLENDI2 ENVIRONMENT, SHADE, COMBINED, SHADE, 0, 0, 0, SHADE
|
|
#define G_CC_BLENDIA2 ENVIRONMENT, SHADE, COMBINED, SHADE, COMBINED, 0, SHADE, 0
|
|
#define G_CC_CHROMA_KEY2 TEXEL0, CENTER, SCALE, 0, 0, 0, 0, 0
|
|
#define G_CC_HILITERGB2 ENVIRONMENT, COMBINED, TEXEL0, COMBINED, 0, 0, 0, SHADE
|
|
#define G_CC_HILITERGBA2 ENVIRONMENT, COMBINED, TEXEL0, COMBINED, ENVIRONMENT, COMBINED, TEXEL0, COMBINED
|
|
#define G_CC_HILITERGBDECALA2 ENVIRONMENT, COMBINED, TEXEL0, COMBINED, 0, 0, 0, TEXEL0
|
|
#define G_CC_HILITERGBPASSA2 ENVIRONMENT, COMBINED, TEXEL0, COMBINED, 0, 0, 0, COMBINED
|
|
|
|
/*
|
|
* G_SETOTHERMODE_L sft: shift count
|
|
*/
|
|
#define G_MDSFT_ALPHACOMPARE 0
|
|
#define G_MDSFT_ZSRCSEL 2
|
|
#define G_MDSFT_RENDERMODE 3
|
|
#define G_MDSFT_BLENDER 16
|
|
|
|
/*
|
|
* G_SETOTHERMODE_H sft: shift count
|
|
*/
|
|
#define G_MDSFT_BLENDMASK 0 /* unsupported */
|
|
#define G_MDSFT_ALPHADITHER 4
|
|
#define G_MDSFT_RGBDITHER 6
|
|
|
|
#define G_MDSFT_COMBKEY 8
|
|
#define G_MDSFT_TEXTCONV 9
|
|
#define G_MDSFT_TEXTFILT 12
|
|
#define G_MDSFT_TEXTLUT 14
|
|
#define G_MDSFT_TEXTLOD 16
|
|
#define G_MDSFT_TEXTDETAIL 17
|
|
#define G_MDSFT_TEXTPERSP 19
|
|
#define G_MDSFT_CYCLETYPE 20
|
|
#define G_MDSFT_COLORDITHER 22 /* unsupported in HW 2.0 */
|
|
#define G_MDSFT_PIPELINE 23
|
|
|
|
/* G_SETOTHERMODE_H gPipelineMode */
|
|
#define G_PM_1PRIMITIVE (1 << G_MDSFT_PIPELINE)
|
|
#define G_PM_NPRIMITIVE (0 << G_MDSFT_PIPELINE)
|
|
|
|
/* G_SETOTHERMODE_H gSetCycleType */
|
|
#define G_CYC_1CYCLE (0 << G_MDSFT_CYCLETYPE)
|
|
#define G_CYC_2CYCLE (1 << G_MDSFT_CYCLETYPE)
|
|
#define G_CYC_COPY (2 << G_MDSFT_CYCLETYPE)
|
|
#define G_CYC_FILL (3 << G_MDSFT_CYCLETYPE)
|
|
|
|
/* G_SETOTHERMODE_H gSetTexturePersp */
|
|
#define G_TP_NONE (0 << G_MDSFT_TEXTPERSP)
|
|
#define G_TP_PERSP (1 << G_MDSFT_TEXTPERSP)
|
|
|
|
/* G_SETOTHERMODE_H gSetTextureDetail */
|
|
#define G_TD_CLAMP (0 << G_MDSFT_TEXTDETAIL)
|
|
#define G_TD_SHARPEN (1 << G_MDSFT_TEXTDETAIL)
|
|
#define G_TD_DETAIL (2 << G_MDSFT_TEXTDETAIL)
|
|
|
|
/* G_SETOTHERMODE_H gSetTextureLOD */
|
|
#define G_TL_TILE (0 << G_MDSFT_TEXTLOD)
|
|
#define G_TL_LOD (1 << G_MDSFT_TEXTLOD)
|
|
|
|
/* G_SETOTHERMODE_H gSetTextureLUT */
|
|
#define G_TT_NONE (0 << G_MDSFT_TEXTLUT)
|
|
#define G_TT_RGBA16 (2 << G_MDSFT_TEXTLUT)
|
|
#define G_TT_IA16 (3 << G_MDSFT_TEXTLUT)
|
|
|
|
/* G_SETOTHERMODE_H gSetTextureFilter */
|
|
#define G_TF_POINT (0 << G_MDSFT_TEXTFILT)
|
|
#define G_TF_AVERAGE (3 << G_MDSFT_TEXTFILT)
|
|
#define G_TF_BILERP (2 << G_MDSFT_TEXTFILT)
|
|
|
|
/* G_SETOTHERMODE_H gSetTextureConvert */
|
|
#define G_TC_CONV (0 << G_MDSFT_TEXTCONV)
|
|
#define G_TC_FILTCONV (5 << G_MDSFT_TEXTCONV)
|
|
#define G_TC_FILT (6 << G_MDSFT_TEXTCONV)
|
|
|
|
/* G_SETOTHERMODE_H gSetCombineKey */
|
|
#define G_CK_NONE (0 << G_MDSFT_COMBKEY)
|
|
#define G_CK_KEY (1 << G_MDSFT_COMBKEY)
|
|
|
|
/* G_SETOTHERMODE_H gSetColorDither */
|
|
#define G_CD_MAGICSQ (0 << G_MDSFT_RGBDITHER)
|
|
#define G_CD_BAYER (1 << G_MDSFT_RGBDITHER)
|
|
#define G_CD_NOISE (2 << G_MDSFT_RGBDITHER)
|
|
|
|
#ifndef _HW_VERSION_1
|
|
#define G_CD_DISABLE (3 << G_MDSFT_RGBDITHER)
|
|
#define G_CD_ENABLE G_CD_NOISE /* HW 1.0 compatibility mode */
|
|
#else
|
|
#define G_CD_ENABLE (1 << G_MDSFT_COLORDITHER)
|
|
#define G_CD_DISABLE (0 << G_MDSFT_COLORDITHER)
|
|
#endif
|
|
|
|
/* G_SETOTHERMODE_H gSetAlphaDither */
|
|
#define G_AD_PATTERN (0 << G_MDSFT_ALPHADITHER)
|
|
#define G_AD_NOTPATTERN (1 << G_MDSFT_ALPHADITHER)
|
|
#define G_AD_NOISE (2 << G_MDSFT_ALPHADITHER)
|
|
#define G_AD_DISABLE (3 << G_MDSFT_ALPHADITHER)
|
|
|
|
/* G_SETOTHERMODE_L gSetAlphaCompare */
|
|
#define G_AC_NONE (0 << G_MDSFT_ALPHACOMPARE)
|
|
#define G_AC_THRESHOLD (1 << G_MDSFT_ALPHACOMPARE)
|
|
#define G_AC_DITHER (3 << G_MDSFT_ALPHACOMPARE)
|
|
|
|
/* G_SETOTHERMODE_L gSetDepthSource */
|
|
#define G_ZS_PIXEL (0 << G_MDSFT_ZSRCSEL)
|
|
#define G_ZS_PRIM (1 << G_MDSFT_ZSRCSEL)
|
|
|
|
/* G_SETOTHERMODE_L gSetRenderMode */
|
|
#define AA_EN 0x8
|
|
#define Z_CMP 0x10
|
|
#define Z_UPD 0x20
|
|
#define IM_RD 0x40
|
|
#define CLR_ON_CVG 0x80
|
|
#define CVG_DST_CLAMP 0
|
|
#define CVG_DST_WRAP 0x100
|
|
#define CVG_DST_FULL 0x200
|
|
#define CVG_DST_SAVE 0x300
|
|
#define ZMODE_OPA 0
|
|
#define ZMODE_INTER 0x400
|
|
#define ZMODE_XLU 0x800
|
|
#define ZMODE_DEC 0xc00
|
|
#define CVG_X_ALPHA 0x1000
|
|
#define ALPHA_CVG_SEL 0x2000
|
|
#define FORCE_BL 0x4000
|
|
#define TEX_EDGE 0x0000 /* used to be 0x8000 */
|
|
|
|
#define G_BL_CLR_IN 0
|
|
#define G_BL_CLR_MEM 1
|
|
#define G_BL_CLR_BL 2
|
|
#define G_BL_CLR_FOG 3
|
|
#define G_BL_1MA 0
|
|
#define G_BL_A_MEM 1
|
|
#define G_BL_A_IN 0
|
|
#define G_BL_A_FOG 1
|
|
#define G_BL_A_SHADE 2
|
|
#define G_BL_1 2
|
|
#define G_BL_0 3
|
|
|
|
#define GBL_c1(m1a, m1b, m2a, m2b) \
|
|
(m1a) << 30 | (m1b) << 26 | (m2a) << 22 | (m2b) << 18
|
|
#define GBL_c2(m1a, m1b, m2a, m2b) \
|
|
(m1a) << 28 | (m1b) << 24 | (m2a) << 20 | (m2b) << 16
|
|
|
|
#define RM_AA_ZB_OPA_SURF(clk) \
|
|
AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_CLAMP | \
|
|
ZMODE_OPA | ALPHA_CVG_SEL | \
|
|
GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
|
|
|
|
#define RM_RA_ZB_OPA_SURF(clk) \
|
|
AA_EN | Z_CMP | Z_UPD | CVG_DST_CLAMP | \
|
|
ZMODE_OPA | ALPHA_CVG_SEL | \
|
|
GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
|
|
|
|
#define RM_AA_ZB_XLU_SURF(clk) \
|
|
AA_EN | Z_CMP | IM_RD | CVG_DST_WRAP | CLR_ON_CVG | \
|
|
FORCE_BL | ZMODE_XLU | \
|
|
GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
|
|
|
|
#define RM_AA_ZB_OPA_DECAL(clk) \
|
|
AA_EN | Z_CMP | IM_RD | CVG_DST_WRAP | ALPHA_CVG_SEL | \
|
|
ZMODE_DEC | \
|
|
GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
|
|
|
|
#define RM_RA_ZB_OPA_DECAL(clk) \
|
|
AA_EN | Z_CMP | CVG_DST_WRAP | ALPHA_CVG_SEL | \
|
|
ZMODE_DEC | \
|
|
GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
|
|
|
|
#define RM_AA_ZB_XLU_DECAL(clk) \
|
|
AA_EN | Z_CMP | IM_RD | CVG_DST_WRAP | CLR_ON_CVG | \
|
|
FORCE_BL | ZMODE_DEC | \
|
|
GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
|
|
|
|
#define RM_AA_ZB_OPA_INTER(clk) \
|
|
AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_CLAMP | \
|
|
ALPHA_CVG_SEL | ZMODE_INTER | \
|
|
GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
|
|
|
|
#define RM_RA_ZB_OPA_INTER(clk) \
|
|
AA_EN | Z_CMP | Z_UPD | CVG_DST_CLAMP | \
|
|
ALPHA_CVG_SEL | ZMODE_INTER | \
|
|
GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
|
|
|
|
#define RM_AA_ZB_XLU_INTER(clk) \
|
|
AA_EN | Z_CMP | IM_RD | CVG_DST_WRAP | CLR_ON_CVG | \
|
|
FORCE_BL | ZMODE_INTER | \
|
|
GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
|
|
|
|
#define RM_AA_ZB_XLU_LINE(clk) \
|
|
AA_EN | Z_CMP | IM_RD | CVG_DST_CLAMP | CVG_X_ALPHA | \
|
|
ALPHA_CVG_SEL | FORCE_BL | ZMODE_XLU | \
|
|
GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
|
|
|
|
#define RM_AA_ZB_DEC_LINE(clk) \
|
|
AA_EN | Z_CMP | IM_RD | CVG_DST_SAVE | CVG_X_ALPHA | \
|
|
ALPHA_CVG_SEL | FORCE_BL | ZMODE_DEC | \
|
|
GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
|
|
|
|
#define RM_AA_ZB_TEX_EDGE(clk) \
|
|
AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_CLAMP | \
|
|
CVG_X_ALPHA | ALPHA_CVG_SEL | ZMODE_OPA | TEX_EDGE | \
|
|
GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
|
|
|
|
#define RM_AA_ZB_TEX_INTER(clk) \
|
|
AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_CLAMP | \
|
|
CVG_X_ALPHA | ALPHA_CVG_SEL | ZMODE_INTER | TEX_EDGE | \
|
|
GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
|
|
|
|
#define RM_AA_ZB_SUB_SURF(clk) \
|
|
AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_FULL | \
|
|
ZMODE_OPA | ALPHA_CVG_SEL | \
|
|
GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
|
|
|
|
#define RM_AA_ZB_PCL_SURF(clk) \
|
|
AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_CLAMP | \
|
|
ZMODE_OPA | G_AC_DITHER | \
|
|
GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
|
|
|
|
#define RM_AA_ZB_OPA_TERR(clk) \
|
|
AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_CLAMP | \
|
|
ZMODE_OPA | ALPHA_CVG_SEL | \
|
|
GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
|
|
|
|
#define RM_AA_ZB_TEX_TERR(clk) \
|
|
AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_CLAMP | \
|
|
CVG_X_ALPHA | ALPHA_CVG_SEL | ZMODE_OPA | TEX_EDGE | \
|
|
GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
|
|
|
|
#define RM_AA_ZB_SUB_TERR(clk) \
|
|
AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_FULL | \
|
|
ZMODE_OPA | ALPHA_CVG_SEL | \
|
|
GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
|
|
|
|
|
|
#define RM_AA_OPA_SURF(clk) \
|
|
AA_EN | IM_RD | CVG_DST_CLAMP | \
|
|
ZMODE_OPA | ALPHA_CVG_SEL | \
|
|
GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
|
|
|
|
#define RM_RA_OPA_SURF(clk) \
|
|
AA_EN | CVG_DST_CLAMP | \
|
|
ZMODE_OPA | ALPHA_CVG_SEL | \
|
|
GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
|
|
|
|
#define RM_AA_XLU_SURF(clk) \
|
|
AA_EN | IM_RD | CVG_DST_WRAP | CLR_ON_CVG | FORCE_BL | \
|
|
ZMODE_OPA | \
|
|
GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
|
|
|
|
#define RM_AA_XLU_LINE(clk) \
|
|
AA_EN | IM_RD | CVG_DST_CLAMP | CVG_X_ALPHA | \
|
|
ALPHA_CVG_SEL | FORCE_BL | ZMODE_OPA | \
|
|
GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
|
|
|
|
#define RM_AA_DEC_LINE(clk) \
|
|
AA_EN | IM_RD | CVG_DST_FULL | CVG_X_ALPHA | \
|
|
ALPHA_CVG_SEL | FORCE_BL | ZMODE_OPA | \
|
|
GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
|
|
|
|
#define RM_AA_TEX_EDGE(clk) \
|
|
AA_EN | IM_RD | CVG_DST_CLAMP | \
|
|
CVG_X_ALPHA | ALPHA_CVG_SEL | ZMODE_OPA | TEX_EDGE | \
|
|
GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
|
|
|
|
#define RM_AA_SUB_SURF(clk) \
|
|
AA_EN | IM_RD | CVG_DST_FULL | \
|
|
ZMODE_OPA | ALPHA_CVG_SEL | \
|
|
GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
|
|
|
|
#define RM_AA_PCL_SURF(clk) \
|
|
AA_EN | IM_RD | CVG_DST_CLAMP | \
|
|
ZMODE_OPA | G_AC_DITHER | \
|
|
GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
|
|
|
|
#define RM_AA_OPA_TERR(clk) \
|
|
AA_EN | IM_RD | CVG_DST_CLAMP | \
|
|
ZMODE_OPA | ALPHA_CVG_SEL | \
|
|
GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
|
|
|
|
#define RM_AA_TEX_TERR(clk) \
|
|
AA_EN | IM_RD | CVG_DST_CLAMP | \
|
|
CVG_X_ALPHA | ALPHA_CVG_SEL | ZMODE_OPA | TEX_EDGE | \
|
|
GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
|
|
|
|
#define RM_AA_SUB_TERR(clk) \
|
|
AA_EN | IM_RD | CVG_DST_FULL | \
|
|
ZMODE_OPA | ALPHA_CVG_SEL | \
|
|
GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
|
|
|
|
|
|
#define RM_ZB_OPA_SURF(clk) \
|
|
Z_CMP | Z_UPD | CVG_DST_FULL | ALPHA_CVG_SEL | \
|
|
ZMODE_OPA | \
|
|
GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
|
|
|
|
#define RM_ZB_XLU_SURF(clk) \
|
|
Z_CMP | IM_RD | CVG_DST_FULL | FORCE_BL | ZMODE_XLU | \
|
|
GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
|
|
|
|
#define RM_ZB_OPA_DECAL(clk) \
|
|
Z_CMP | CVG_DST_FULL | ALPHA_CVG_SEL | ZMODE_DEC | \
|
|
GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
|
|
|
|
#define RM_ZB_XLU_DECAL(clk) \
|
|
Z_CMP | IM_RD | CVG_DST_FULL | FORCE_BL | ZMODE_DEC | \
|
|
GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
|
|
|
|
#define RM_ZB_CLD_SURF(clk) \
|
|
Z_CMP | IM_RD | CVG_DST_SAVE | FORCE_BL | ZMODE_XLU | \
|
|
GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
|
|
|
|
#define RM_ZB_OVL_SURF(clk) \
|
|
Z_CMP | IM_RD | CVG_DST_SAVE | FORCE_BL | ZMODE_DEC | \
|
|
GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
|
|
|
|
#define RM_ZB_PCL_SURF(clk) \
|
|
Z_CMP | Z_UPD | CVG_DST_FULL | ZMODE_OPA | \
|
|
G_AC_DITHER | \
|
|
GBL_c##clk(G_BL_CLR_IN, G_BL_0, G_BL_CLR_IN, G_BL_1)
|
|
|
|
|
|
#define RM_OPA_SURF(clk) \
|
|
CVG_DST_CLAMP | FORCE_BL | ZMODE_OPA | \
|
|
GBL_c##clk(G_BL_CLR_IN, G_BL_0, G_BL_CLR_IN, G_BL_1)
|
|
|
|
#define RM_XLU_SURF(clk) \
|
|
IM_RD | CVG_DST_FULL | FORCE_BL | ZMODE_OPA | \
|
|
GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
|
|
|
|
#define RM_TEX_EDGE(clk) \
|
|
CVG_DST_CLAMP | CVG_X_ALPHA | ALPHA_CVG_SEL | FORCE_BL |\
|
|
ZMODE_OPA | TEX_EDGE | AA_EN | \
|
|
GBL_c##clk(G_BL_CLR_IN, G_BL_0, G_BL_CLR_IN, G_BL_1)
|
|
|
|
#define RM_CLD_SURF(clk) \
|
|
IM_RD | CVG_DST_SAVE | FORCE_BL | ZMODE_OPA | \
|
|
GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
|
|
|
|
#define RM_PCL_SURF(clk) \
|
|
CVG_DST_FULL | FORCE_BL | ZMODE_OPA | \
|
|
G_AC_DITHER | \
|
|
GBL_c##clk(G_BL_CLR_IN, G_BL_0, G_BL_CLR_IN, G_BL_1)
|
|
|
|
#define RM_ADD(clk) \
|
|
IM_RD | CVG_DST_SAVE | FORCE_BL | ZMODE_OPA | \
|
|
GBL_c##clk(G_BL_CLR_IN, G_BL_A_FOG, G_BL_CLR_MEM, G_BL_1)
|
|
|
|
#define RM_NOOP(clk) \
|
|
GBL_c##clk(0, 0, 0, 0)
|
|
|
|
#define RM_VISCVG(clk) \
|
|
IM_RD | FORCE_BL | \
|
|
GBL_c##clk(G_BL_CLR_IN, G_BL_0, G_BL_CLR_BL, G_BL_A_MEM)
|
|
|
|
/* for rendering to an 8-bit framebuffer */
|
|
#define RM_OPA_CI(clk) \
|
|
CVG_DST_CLAMP | ZMODE_OPA | \
|
|
GBL_c##clk(G_BL_CLR_IN, G_BL_0, G_BL_CLR_IN, G_BL_1)
|
|
|
|
/* 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_AA_ZB_OPA_SURF RM_AA_ZB_OPA_SURF(1)
|
|
#define G_RM_AA_ZB_OPA_SURF2 RM_AA_ZB_OPA_SURF(2)
|
|
#define G_RM_AA_ZB_XLU_SURF RM_AA_ZB_XLU_SURF(1)
|
|
#define G_RM_AA_ZB_XLU_SURF2 RM_AA_ZB_XLU_SURF(2)
|
|
#define G_RM_AA_ZB_OPA_DECAL RM_AA_ZB_OPA_DECAL(1)
|
|
#define G_RM_AA_ZB_OPA_DECAL2 RM_AA_ZB_OPA_DECAL(2)
|
|
#define G_RM_AA_ZB_XLU_DECAL RM_AA_ZB_XLU_DECAL(1)
|
|
#define G_RM_AA_ZB_XLU_DECAL2 RM_AA_ZB_XLU_DECAL(2)
|
|
#define G_RM_AA_ZB_OPA_INTER RM_AA_ZB_OPA_INTER(1)
|
|
#define G_RM_AA_ZB_OPA_INTER2 RM_AA_ZB_OPA_INTER(2)
|
|
#define G_RM_AA_ZB_XLU_INTER RM_AA_ZB_XLU_INTER(1)
|
|
#define G_RM_AA_ZB_XLU_INTER2 RM_AA_ZB_XLU_INTER(2)
|
|
#define G_RM_AA_ZB_XLU_LINE RM_AA_ZB_XLU_LINE(1)
|
|
#define G_RM_AA_ZB_XLU_LINE2 RM_AA_ZB_XLU_LINE(2)
|
|
#define G_RM_AA_ZB_DEC_LINE RM_AA_ZB_DEC_LINE(1)
|
|
#define G_RM_AA_ZB_DEC_LINE2 RM_AA_ZB_DEC_LINE(2)
|
|
#define G_RM_AA_ZB_TEX_EDGE RM_AA_ZB_TEX_EDGE(1)
|
|
#define G_RM_AA_ZB_TEX_EDGE2 RM_AA_ZB_TEX_EDGE(2)
|
|
#define G_RM_AA_ZB_TEX_INTER RM_AA_ZB_TEX_INTER(1)
|
|
#define G_RM_AA_ZB_TEX_INTER2 RM_AA_ZB_TEX_INTER(2)
|
|
#define G_RM_AA_ZB_SUB_SURF RM_AA_ZB_SUB_SURF(1)
|
|
#define G_RM_AA_ZB_SUB_SURF2 RM_AA_ZB_SUB_SURF(2)
|
|
#define G_RM_AA_ZB_PCL_SURF RM_AA_ZB_PCL_SURF(1)
|
|
#define G_RM_AA_ZB_PCL_SURF2 RM_AA_ZB_PCL_SURF(2)
|
|
#define G_RM_AA_ZB_OPA_TERR RM_AA_ZB_OPA_TERR(1)
|
|
#define G_RM_AA_ZB_OPA_TERR2 RM_AA_ZB_OPA_TERR(2)
|
|
#define G_RM_AA_ZB_TEX_TERR RM_AA_ZB_TEX_TERR(1)
|
|
#define G_RM_AA_ZB_TEX_TERR2 RM_AA_ZB_TEX_TERR(2)
|
|
#define G_RM_AA_ZB_SUB_TERR RM_AA_ZB_SUB_TERR(1)
|
|
#define G_RM_AA_ZB_SUB_TERR2 RM_AA_ZB_SUB_TERR(2)
|
|
|
|
#define G_RM_RA_ZB_OPA_SURF RM_RA_ZB_OPA_SURF(1)
|
|
#define G_RM_RA_ZB_OPA_SURF2 RM_RA_ZB_OPA_SURF(2)
|
|
#define G_RM_RA_ZB_OPA_DECAL RM_RA_ZB_OPA_DECAL(1)
|
|
#define G_RM_RA_ZB_OPA_DECAL2 RM_RA_ZB_OPA_DECAL(2)
|
|
#define G_RM_RA_ZB_OPA_INTER RM_RA_ZB_OPA_INTER(1)
|
|
#define G_RM_RA_ZB_OPA_INTER2 RM_RA_ZB_OPA_INTER(2)
|
|
|
|
#define G_RM_AA_OPA_SURF RM_AA_OPA_SURF(1)
|
|
#define G_RM_AA_OPA_SURF2 RM_AA_OPA_SURF(2)
|
|
#define G_RM_AA_XLU_SURF RM_AA_XLU_SURF(1)
|
|
#define G_RM_AA_XLU_SURF2 RM_AA_XLU_SURF(2)
|
|
#define G_RM_AA_XLU_LINE RM_AA_XLU_LINE(1)
|
|
#define G_RM_AA_XLU_LINE2 RM_AA_XLU_LINE(2)
|
|
#define G_RM_AA_DEC_LINE RM_AA_DEC_LINE(1)
|
|
#define G_RM_AA_DEC_LINE2 RM_AA_DEC_LINE(2)
|
|
#define G_RM_AA_TEX_EDGE RM_AA_TEX_EDGE(1)
|
|
#define G_RM_AA_TEX_EDGE2 RM_AA_TEX_EDGE(2)
|
|
#define G_RM_AA_SUB_SURF RM_AA_SUB_SURF(1)
|
|
#define G_RM_AA_SUB_SURF2 RM_AA_SUB_SURF(2)
|
|
#define G_RM_AA_PCL_SURF RM_AA_PCL_SURF(1)
|
|
#define G_RM_AA_PCL_SURF2 RM_AA_PCL_SURF(2)
|
|
#define G_RM_AA_OPA_TERR RM_AA_OPA_TERR(1)
|
|
#define G_RM_AA_OPA_TERR2 RM_AA_OPA_TERR(2)
|
|
#define G_RM_AA_TEX_TERR RM_AA_TEX_TERR(1)
|
|
#define G_RM_AA_TEX_TERR2 RM_AA_TEX_TERR(2)
|
|
#define G_RM_AA_SUB_TERR RM_AA_SUB_TERR(1)
|
|
#define G_RM_AA_SUB_TERR2 RM_AA_SUB_TERR(2)
|
|
|
|
#define G_RM_RA_OPA_SURF RM_RA_OPA_SURF(1)
|
|
#define G_RM_RA_OPA_SURF2 RM_RA_OPA_SURF(2)
|
|
|
|
#define G_RM_ZB_OPA_SURF RM_ZB_OPA_SURF(1)
|
|
#define G_RM_ZB_OPA_SURF2 RM_ZB_OPA_SURF(2)
|
|
#define G_RM_ZB_XLU_SURF RM_ZB_XLU_SURF(1)
|
|
#define G_RM_ZB_XLU_SURF2 RM_ZB_XLU_SURF(2)
|
|
#define G_RM_ZB_OPA_DECAL RM_ZB_OPA_DECAL(1)
|
|
#define G_RM_ZB_OPA_DECAL2 RM_ZB_OPA_DECAL(2)
|
|
#define G_RM_ZB_XLU_DECAL RM_ZB_XLU_DECAL(1)
|
|
#define G_RM_ZB_XLU_DECAL2 RM_ZB_XLU_DECAL(2)
|
|
#define G_RM_ZB_CLD_SURF RM_ZB_CLD_SURF(1)
|
|
#define G_RM_ZB_CLD_SURF2 RM_ZB_CLD_SURF(2)
|
|
#define G_RM_ZB_OVL_SURF RM_ZB_OVL_SURF(1)
|
|
#define G_RM_ZB_OVL_SURF2 RM_ZB_OVL_SURF(2)
|
|
#define G_RM_ZB_PCL_SURF RM_ZB_PCL_SURF(1)
|
|
#define G_RM_ZB_PCL_SURF2 RM_ZB_PCL_SURF(2)
|
|
|
|
#define G_RM_OPA_SURF RM_OPA_SURF(1)
|
|
#define G_RM_OPA_SURF2 RM_OPA_SURF(2)
|
|
#define G_RM_XLU_SURF RM_XLU_SURF(1)
|
|
#define G_RM_XLU_SURF2 RM_XLU_SURF(2)
|
|
#define G_RM_CLD_SURF RM_CLD_SURF(1)
|
|
#define G_RM_CLD_SURF2 RM_CLD_SURF(2)
|
|
#define G_RM_TEX_EDGE RM_TEX_EDGE(1)
|
|
#define G_RM_TEX_EDGE2 RM_TEX_EDGE(2)
|
|
#define G_RM_PCL_SURF RM_PCL_SURF(1)
|
|
#define G_RM_PCL_SURF2 RM_PCL_SURF(2)
|
|
#define G_RM_ADD RM_ADD(1)
|
|
#define G_RM_ADD2 RM_ADD(2)
|
|
#define G_RM_NOOP RM_NOOP(1)
|
|
#define G_RM_NOOP2 RM_NOOP(2)
|
|
#define G_RM_VISCVG RM_VISCVG(1)
|
|
#define G_RM_VISCVG2 RM_VISCVG(2)
|
|
#define G_RM_OPA_CI RM_OPA_CI(1)
|
|
#define G_RM_OPA_CI2 RM_OPA_CI(2)
|
|
|
|
#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)
|
|
|
|
|
|
#define G_RM_FOG_SHADE_A GBL_c1(G_BL_CLR_FOG, G_BL_A_SHADE, G_BL_CLR_IN, G_BL_1MA)
|
|
#define G_RM_FOG_PRIM_A GBL_c1(G_BL_CLR_FOG, G_BL_A_FOG, G_BL_CLR_IN, G_BL_1MA)
|
|
#define G_RM_PASS GBL_c1(G_BL_CLR_IN, G_BL_0, G_BL_CLR_IN, G_BL_1)
|
|
|
|
/*
|
|
* G_SETCONVERT: K0-5
|
|
*/
|
|
#define G_CV_K0 175
|
|
#define G_CV_K1 -43
|
|
#define G_CV_K2 -89
|
|
#define G_CV_K3 222
|
|
#define G_CV_K4 114
|
|
#define G_CV_K5 42
|
|
|
|
/*
|
|
* G_SETSCISSOR: interlace mode
|
|
*/
|
|
#define G_SC_NON_INTERLACE 0
|
|
#define G_SC_ODD_INTERLACE 3
|
|
#define G_SC_EVEN_INTERLACE 2
|
|
|
|
/* flags to inhibit pushing of the display list (on branch) */
|
|
#define G_DL_PUSH 0x00
|
|
#define G_DL_NOPUSH 0x01
|
|
|
|
/*
|
|
* BEGIN C-specific section: (typedef's)
|
|
*/
|
|
#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS)
|
|
|
|
/*
|
|
* Data Structures
|
|
*
|
|
* NOTE:
|
|
* The DMA transfer hardware requires 64-bit aligned, 64-bit multiple-
|
|
* sized transfers. This important hardware optimization is unfortunately
|
|
* reflected in the programming interface, with some structures
|
|
* padded and alignment enforced.
|
|
*
|
|
* Since structures are aligned to the boundary of the "worst-case"
|
|
* element, we can't depend on the C compiler to align things
|
|
* properly.
|
|
*
|
|
* 64-bit structure alignment is enforced by wrapping structures with
|
|
* unions that contain a dummy "long long int". Why this works is
|
|
* explained in the ANSI C Spec, or on page 186 of the second edition
|
|
* of K&R, "The C Programming Language".
|
|
*
|
|
* The price we pay for this is a little awkwardness referencing the
|
|
* structures through the union. There is no memory penalty, since
|
|
* all the structures are at least 64-bits the dummy alignment field
|
|
* does not increase the size of the union.
|
|
*
|
|
* Static initialization of these union structures works because
|
|
* the ANSI C spec states that static initialization for unions
|
|
* works by using the first union element. We put the dummy alignment
|
|
* field last for this reason.
|
|
*
|
|
* (it's possible a newer 64-bit compiler from MIPS might make this
|
|
* easier with a flag, but we can't wait for it...)
|
|
*
|
|
*/
|
|
|
|
/*
|
|
* Vertex (set up for use with colors)
|
|
*/
|
|
typedef struct {
|
|
float ob[3]; /* x, y, z */
|
|
unsigned short flag;
|
|
short tc[2]; /* texture coord */
|
|
unsigned char cn[4]; /* color & alpha */
|
|
} Vtx_t;
|
|
|
|
/*
|
|
* Vertex (set up for use with normals)
|
|
*/
|
|
typedef struct {
|
|
float ob[3]; /* x, y, z */
|
|
unsigned short flag;
|
|
short tc[2]; /* texture coord */
|
|
signed char n[3]; /* normal */
|
|
unsigned char a; /* alpha */
|
|
} Vtx_tn;
|
|
|
|
typedef union {
|
|
Vtx_t v; /* Use this one for colors */
|
|
Vtx_tn n; /* Use this one for normals */
|
|
long long int force_structure_alignment;
|
|
} Vtx;
|
|
|
|
/*
|
|
* Sprite structure
|
|
*/
|
|
|
|
typedef struct {
|
|
void *SourceImagePointer;
|
|
void *TlutPointer;
|
|
short Stride;
|
|
short SubImageWidth;
|
|
short SubImageHeight;
|
|
char SourceImageType;
|
|
char SourceImageBitSize;
|
|
short SourceImageOffsetS;
|
|
short SourceImageOffsetT;
|
|
/* 20 bytes for above */
|
|
|
|
/* padding to bring structure size to 64 bit allignment */
|
|
char dummy[4];
|
|
|
|
} uSprite_t;
|
|
|
|
typedef union {
|
|
uSprite_t s;
|
|
|
|
/* Need to make sure this is 64 bit aligned */
|
|
long long int force_structure_allignment[3];
|
|
} uSprite;
|
|
|
|
/*
|
|
* Triangle face
|
|
*/
|
|
typedef struct {
|
|
unsigned char flag;
|
|
unsigned char v[3];
|
|
} Tri;
|
|
|
|
typedef struct {
|
|
float m[4][4];
|
|
} Mtx;
|
|
|
|
/*
|
|
* Viewport
|
|
*/
|
|
|
|
/*
|
|
*
|
|
* This magic value is the maximum INTEGER z-range of the hardware
|
|
* (there are also 16-bits of fraction, which are introduced during
|
|
* any transformations). This is not just a good idea, it's the law.
|
|
* Feeding the hardware eventual z-coordinates (after any transforms
|
|
* or scaling) bigger than this, will not work.
|
|
*
|
|
* This number is DIFFERENT than G_MAXFBZ, which is the maximum value
|
|
* you want to use to initialize the z-buffer.
|
|
*
|
|
* The reason these are different is mildly interesting, but too long
|
|
* to explain here. It is basically the result of optimizations in the
|
|
* hardware. A more generic API might hide this detail from the users,
|
|
* but we don't have the ucode to do that...
|
|
*
|
|
*/
|
|
#define G_MAXZ 0x03ff /* 10 bits of integer screen-Z precision */
|
|
|
|
/*
|
|
* The viewport structure elements have 2 bits of fraction, necessary
|
|
* to accomodate the sub-pixel positioning scaling for the hardware.
|
|
* This can also be exploited to handle odd-sized viewports.
|
|
*
|
|
* Accounting for these fractional bits, using the default projection
|
|
* and viewing matrices, the viewport structure is initialized thusly:
|
|
*
|
|
* (SCREEN_WD/2)*4, (SCREEN_HT/2)*4, G_MAXZ, 0,
|
|
* (SCREEN_WD/2)*4, (SCREEN_HT/2)*4, 0, 0,
|
|
*/
|
|
typedef struct {
|
|
short vscale[4]; /* scale, 2 bits fraction */
|
|
short vtrans[4]; /* translate, 2 bits fraction */
|
|
/* both the above arrays are padded to 64-bit boundary */
|
|
} Vp_t;
|
|
|
|
typedef union {
|
|
Vp_t vp;
|
|
long long int force_structure_alignment;
|
|
} Vp;
|
|
|
|
/*
|
|
* MOVEMEM indices
|
|
*
|
|
* Each of these indexes an entry in a dmem table
|
|
* which points to a 1-4 word block of dmem in
|
|
* which to store a 1-4 word DMA.
|
|
*
|
|
*/
|
|
#ifdef F3DEX_GBI_2
|
|
/* 0,4 are reserved by G_MTX */
|
|
# define G_MV_MMTX 2
|
|
# define G_MV_PMTX 6
|
|
# define G_MV_VIEWPORT 8
|
|
# define G_MV_LIGHT 10
|
|
# define G_MV_POINT 12
|
|
# define G_MV_MATRIX 14 /* NOTE: this is in moveword table */
|
|
# define G_MVO_LOOKATX (0*24)
|
|
# define G_MVO_LOOKATY (1*24)
|
|
# define G_MVO_L0 (2*24)
|
|
# define G_MVO_L1 (3*24)
|
|
# define G_MVO_L2 (4*24)
|
|
# define G_MVO_L3 (5*24)
|
|
# define G_MVO_L4 (6*24)
|
|
# define G_MVO_L5 (7*24)
|
|
# define G_MVO_L6 (8*24)
|
|
# define G_MVO_L7 (9*24)
|
|
#else /* F3DEX_GBI_2 */
|
|
# define G_MV_VIEWPORT 0x80
|
|
# define G_MV_LOOKATY 0x82
|
|
# define G_MV_LOOKATX 0x84
|
|
# define G_MV_L0 0x86
|
|
# define G_MV_L1 0x88
|
|
# define G_MV_L2 0x8a
|
|
# define G_MV_L3 0x8c
|
|
# define G_MV_L4 0x8e
|
|
# define G_MV_L5 0x90
|
|
# define G_MV_L6 0x92
|
|
# define G_MV_L7 0x94
|
|
# define G_MV_TXTATT 0x96
|
|
# define G_MV_MATRIX_1 0x9e /* NOTE: this is in moveword table */
|
|
# define G_MV_MATRIX_2 0x98
|
|
# define G_MV_MATRIX_3 0x9a
|
|
# define G_MV_MATRIX_4 0x9c
|
|
#endif /* F3DEX_GBI_2 */
|
|
|
|
/*
|
|
* MOVEWORD indices
|
|
*
|
|
* Each of these indexes an entry in a dmem table
|
|
* which points to a word in dmem in dmem where
|
|
* an immediate word will be stored.
|
|
*
|
|
*/
|
|
#define G_MW_MATRIX 0x00 /* NOTE: also used by movemem */
|
|
#define G_MW_NUMLIGHT 0x02
|
|
#define G_MW_CLIP 0x04
|
|
#define G_MW_SEGMENT 0x06
|
|
#define G_MW_FOG 0x08
|
|
#define G_MW_LIGHTCOL 0x0a
|
|
#ifdef F3DEX_GBI_2
|
|
# define G_MW_FORCEMTX 0x0c
|
|
#else /* F3DEX_GBI_2 */
|
|
# define G_MW_POINTS 0x0c
|
|
#endif /* F3DEX_GBI_2 */
|
|
#define G_MW_PERSPNORM 0x0e
|
|
|
|
/*
|
|
* These are offsets from the address in the dmem table
|
|
*/
|
|
#define G_MWO_NUMLIGHT 0x00
|
|
#define G_MWO_CLIP_RNX 0x04
|
|
#define G_MWO_CLIP_RNY 0x0c
|
|
#define G_MWO_CLIP_RPX 0x14
|
|
#define G_MWO_CLIP_RPY 0x1c
|
|
#define G_MWO_SEGMENT_0 0x00
|
|
#define G_MWO_SEGMENT_1 0x01
|
|
#define G_MWO_SEGMENT_2 0x02
|
|
#define G_MWO_SEGMENT_3 0x03
|
|
#define G_MWO_SEGMENT_4 0x04
|
|
#define G_MWO_SEGMENT_5 0x05
|
|
#define G_MWO_SEGMENT_6 0x06
|
|
#define G_MWO_SEGMENT_7 0x07
|
|
#define G_MWO_SEGMENT_8 0x08
|
|
#define G_MWO_SEGMENT_9 0x09
|
|
#define G_MWO_SEGMENT_A 0x0a
|
|
#define G_MWO_SEGMENT_B 0x0b
|
|
#define G_MWO_SEGMENT_C 0x0c
|
|
#define G_MWO_SEGMENT_D 0x0d
|
|
#define G_MWO_SEGMENT_E 0x0e
|
|
#define G_MWO_SEGMENT_F 0x0f
|
|
#define G_MWO_FOG 0x00
|
|
#define G_MWO_aLIGHT_1 0x00
|
|
#define G_MWO_bLIGHT_1 0x04
|
|
#ifdef F3DEX_GBI_2
|
|
#define G_MWO_aLIGHT_2 0x18
|
|
#define G_MWO_bLIGHT_2 0x1c
|
|
#define G_MWO_aLIGHT_3 0x30
|
|
#define G_MWO_bLIGHT_3 0x34
|
|
#define G_MWO_aLIGHT_4 0x48
|
|
#define G_MWO_bLIGHT_4 0x4c
|
|
#define G_MWO_aLIGHT_5 0x60
|
|
#define G_MWO_bLIGHT_5 0x64
|
|
#define G_MWO_aLIGHT_6 0x78
|
|
#define G_MWO_bLIGHT_6 0x7c
|
|
#define G_MWO_aLIGHT_7 0x90
|
|
#define G_MWO_bLIGHT_7 0x94
|
|
#define G_MWO_aLIGHT_8 0xa8
|
|
#define G_MWO_bLIGHT_8 0xac
|
|
#else
|
|
#define G_MWO_aLIGHT_2 0x20
|
|
#define G_MWO_bLIGHT_2 0x24
|
|
#define G_MWO_aLIGHT_3 0x40
|
|
#define G_MWO_bLIGHT_3 0x44
|
|
#define G_MWO_aLIGHT_4 0x60
|
|
#define G_MWO_bLIGHT_4 0x64
|
|
#define G_MWO_aLIGHT_5 0x80
|
|
#define G_MWO_bLIGHT_5 0x84
|
|
#define G_MWO_aLIGHT_6 0xa0
|
|
#define G_MWO_bLIGHT_6 0xa4
|
|
#define G_MWO_aLIGHT_7 0xc0
|
|
#define G_MWO_bLIGHT_7 0xc4
|
|
#define G_MWO_aLIGHT_8 0xe0
|
|
#define G_MWO_bLIGHT_8 0xe4
|
|
#endif
|
|
#define G_MWO_MATRIX_XX_XY_I 0x00
|
|
#define G_MWO_MATRIX_XZ_XW_I 0x04
|
|
#define G_MWO_MATRIX_YX_YY_I 0x08
|
|
#define G_MWO_MATRIX_YZ_YW_I 0x0c
|
|
#define G_MWO_MATRIX_ZX_ZY_I 0x10
|
|
#define G_MWO_MATRIX_ZZ_ZW_I 0x14
|
|
#define G_MWO_MATRIX_WX_WY_I 0x18
|
|
#define G_MWO_MATRIX_WZ_WW_I 0x1c
|
|
#define G_MWO_MATRIX_XX_XY_F 0x20
|
|
#define G_MWO_MATRIX_XZ_XW_F 0x24
|
|
#define G_MWO_MATRIX_YX_YY_F 0x28
|
|
#define G_MWO_MATRIX_YZ_YW_F 0x2c
|
|
#define G_MWO_MATRIX_ZX_ZY_F 0x30
|
|
#define G_MWO_MATRIX_ZZ_ZW_F 0x34
|
|
#define G_MWO_MATRIX_WX_WY_F 0x38
|
|
#define G_MWO_MATRIX_WZ_WW_F 0x3c
|
|
#define G_MWO_POINT_RGBA 0x10
|
|
#define G_MWO_POINT_ST 0x14
|
|
#define G_MWO_POINT_XYSCREEN 0x18
|
|
#define G_MWO_POINT_ZSCREEN 0x1c
|
|
|
|
/*
|
|
* Light structure.
|
|
*
|
|
* Note: only directional (infinite) lights are currently supported.
|
|
*
|
|
* Note: the weird order is for the DMEM alignment benefit of
|
|
* the microcode.
|
|
*
|
|
*/
|
|
|
|
typedef struct {
|
|
unsigned char col[3]; /* diffuse light value (rgba) */
|
|
char pad1;
|
|
unsigned char colc[3]; /* copy of diffuse light value (rgba) */
|
|
char pad2;
|
|
signed char dir[3]; /* direction of light (normalized) */
|
|
char pad3;
|
|
} Light_t;
|
|
|
|
typedef struct {
|
|
unsigned char col[3]; /* ambient light value (rgba) */
|
|
char pad1;
|
|
unsigned char colc[3]; /* copy of ambient light value (rgba) */
|
|
char pad2;
|
|
} Ambient_t;
|
|
|
|
typedef struct {
|
|
int x1,y1,x2,y2; /* texture offsets for highlight 1/2 */
|
|
} Hilite_t;
|
|
|
|
typedef union {
|
|
Light_t l;
|
|
long long int force_structure_alignment[2];
|
|
} Light;
|
|
|
|
typedef union {
|
|
Ambient_t l;
|
|
long long int force_structure_alignment[1];
|
|
} Ambient;
|
|
|
|
typedef struct {
|
|
Ambient a;
|
|
Light l[7];
|
|
} Lightsn;
|
|
|
|
typedef struct {
|
|
Ambient a;
|
|
Light l[1];
|
|
} Lights0;
|
|
|
|
typedef struct {
|
|
Ambient a;
|
|
Light l[1];
|
|
} Lights1;
|
|
|
|
typedef struct {
|
|
Ambient a;
|
|
Light l[2];
|
|
} Lights2;
|
|
|
|
typedef struct {
|
|
Ambient a;
|
|
Light l[3];
|
|
} Lights3;
|
|
|
|
typedef struct {
|
|
Ambient a;
|
|
Light l[4];
|
|
} Lights4;
|
|
|
|
typedef struct {
|
|
Ambient a;
|
|
Light l[5];
|
|
} Lights5;
|
|
|
|
typedef struct {
|
|
Ambient a;
|
|
Light l[6];
|
|
} Lights6;
|
|
|
|
typedef struct {
|
|
Ambient a;
|
|
Light l[7];
|
|
} Lights7;
|
|
|
|
typedef struct {
|
|
Light l[2];
|
|
} LookAt;
|
|
|
|
typedef union {
|
|
Hilite_t h;
|
|
long int force_structure_alignment[4];
|
|
} Hilite;
|
|
|
|
#define gdSPDefLights0(ar,ag,ab) \
|
|
{ {{ {ar,ag,ab},0,{ar,ag,ab},0}}, \
|
|
{{{ { 0, 0, 0},0,{ 0, 0, 0},0,{ 0, 0, 0},0}}} }
|
|
#define gdSPDefLights1(ar,ag,ab,r1,g1,b1,x1,y1,z1) \
|
|
{ {{ {ar,ag,ab},0,{ar,ag,ab},0}}, \
|
|
{{{ {r1,g1,b1},0,{r1,g1,b1},0,{x1,y1,z1},0}}} }
|
|
#define gdSPDefLights2(ar,ag,ab,r1,g1,b1,x1,y1,z1,r2,g2,b2,x2,y2,z2) \
|
|
{ {{ {ar,ag,ab},0,{ar,ag,ab},0}}, \
|
|
{{{ {r1,g1,b1},0,{r1,g1,b1},0,{x1,y1,z1},0}}, \
|
|
{{ {r2,g2,b2},0,{r2,g2,b2},0,{x2,y2,z2},0}}} }
|
|
#define gdSPDefLights3(ar,ag,ab,r1,g1,b1,x1,y1,z1,r2,g2,b2,x2,y2,z2,r3,g3,b3,x3,y3,z3) \
|
|
{ {{ {ar,ag,ab},0,{ar,ag,ab},0}}, \
|
|
{{{ {r1,g1,b1},0,{r1,g1,b1},0,{x1,y1,z1},0}}, \
|
|
{{ {r2,g2,b2},0,{r2,g2,b2},0,{x2,y2,z2},0}}, \
|
|
{{ {r3,g3,b3},0,{r3,g3,b3},0,{x3,y3,z3},0}}} }
|
|
#define gdSPDefLights4(ar,ag,ab,r1,g1,b1,x1,y1,z1,r2,g2,b2,x2,y2,z2,r3,g3,b3,x3,y3,z3,r4,g4,b4,x4,y4,z4) \
|
|
{ {{ {ar,ag,ab},0,{ar,ag,ab},0}}, \
|
|
{{{ {r1,g1,b1},0,{r1,g1,b1},0,{x1,y1,z1},0}}, \
|
|
{{ {r2,g2,b2},0,{r2,g2,b2},0,{x2,y2,z2},0}}, \
|
|
{{ {r3,g3,b3},0,{r3,g3,b3},0,{x3,y3,z3},0}}, \
|
|
{{ {r4,g4,b4},0,{r4,g4,b4},0,{x4,y4,z4},0}}} }
|
|
#define gdSPDefLights5(ar,ag,ab,r1,g1,b1,x1,y1,z1,r2,g2,b2,x2,y2,z2,r3,g3,b3,x3,y3,z3,r4,g4,b4,x4,y4,z4,r5,g5,b5,x5,y5,z5) \
|
|
{ {{ {ar,ag,ab},0,{ar,ag,ab},0}}, \
|
|
{{{ {r1,g1,b1},0,{r1,g1,b1},0,{x1,y1,z1},0}}, \
|
|
{{ {r2,g2,b2},0,{r2,g2,b2},0,{x2,y2,z2},0}}, \
|
|
{{ {r3,g3,b3},0,{r3,g3,b3},0,{x3,y3,z3},0}}, \
|
|
{{ {r4,g4,b4},0,{r4,g4,b4},0,{x4,y4,z4},0}}, \
|
|
{{ {r5,g5,b5},0,{r5,g5,b5},0,{x5,y5,z5},0}}} }
|
|
|
|
|
|
#define gdSPDefLights6(ar,ag,ab,r1,g1,b1,x1,y1,z1,r2,g2,b2,x2,y2,z2,r3,g3,b3,x3,y3,z3,r4,g4,b4,x4,y4,z4,r5,g5,b5,x5,y5,z5,r6,g6,b6,x6,y6,z6) \
|
|
{ {{ {ar,ag,ab},0,{ar,ag,ab},0}}, \
|
|
{{{ {r1,g1,b1},0,{r1,g1,b1},0,{x1,y1,z1},0}}, \
|
|
{{ {r2,g2,b2},0,{r2,g2,b2},0,{x2,y2,z2},0}}, \
|
|
{{ {r3,g3,b3},0,{r3,g3,b3},0,{x3,y3,z3},0}}, \
|
|
{{ {r4,g4,b4},0,{r4,g4,b4},0,{x4,y4,z4},0}}, \
|
|
{{ {r5,g5,b5},0,{r5,g5,b5},0,{x5,y5,z5},0}}, \
|
|
{{ {r6,g6,b6},0,{r6,g6,b6},0,{x6,y6,z6},0}}} }
|
|
|
|
|
|
#define gdSPDefLights7(ar,ag,ab,r1,g1,b1,x1,y1,z1,r2,g2,b2,x2,y2,z2,r3,g3,b3,x3,y3,z3,r4,g4,b4,x4,y4,z4,r5,g5,b5,x5,y5,z5,r6,g6,b6,x6,y6,z6,r7,g7,b7,x7,y7,z7) \
|
|
{ {{ {ar,ag,ab},0,{ar,ag,ab},0}}, \
|
|
{{{ {r1,g1,b1},0,{r1,g1,b1},0,{x1,y1,z1},0}}, \
|
|
{{ {r2,g2,b2},0,{r2,g2,b2},0,{x2,y2,z2},0}}, \
|
|
{{ {r3,g3,b3},0,{r3,g3,b3},0,{x3,y3,z3},0}}, \
|
|
{{ {r4,g4,b4},0,{r4,g4,b4},0,{x4,y4,z4},0}}, \
|
|
{{ {r5,g5,b5},0,{r5,g5,b5},0,{x5,y5,z5},0}}, \
|
|
{{ {r6,g6,b6},0,{r6,g6,b6},0,{x6,y6,z6},0}}, \
|
|
{{ {r7,g7,b7},0,{r7,g7,b7},0,{x7,y7,z7},0}}} }
|
|
|
|
|
|
#define gdSPDefLookAt(rightx,righty,rightz,upx,upy,upz) \
|
|
{ {{ {{0,0,0},0,{0,0,0},0,{rightx,righty,rightz},0}}, \
|
|
{ {{0,0x80,0},0,{0,0x80,0},0,{upx,upy,upz},0}}} }
|
|
|
|
/* Don't declare these for F3D_OLD to avoid bss reordering */
|
|
#ifndef F3D_OLD
|
|
/*
|
|
* Graphics DMA Packet
|
|
*/
|
|
typedef struct {
|
|
int cmd:8;
|
|
unsigned int par:8;
|
|
unsigned int len:16;
|
|
uintptr_t addr;
|
|
} Gdma;
|
|
|
|
/*
|
|
* Graphics Immediate Mode Packet types
|
|
*/
|
|
typedef struct {
|
|
int cmd:8;
|
|
int pad:24;
|
|
Tri tri;
|
|
} Gtri;
|
|
|
|
typedef struct {
|
|
int cmd:8;
|
|
int pad1:24;
|
|
int pad2:24;
|
|
unsigned char param:8;
|
|
} Gpopmtx;
|
|
|
|
/*
|
|
* typedef struct {
|
|
* int cmd:8;
|
|
* int pad0:24;
|
|
* int pad1:4;
|
|
* int number:4;
|
|
* int base:24;
|
|
* } Gsegment;
|
|
*/
|
|
typedef struct {
|
|
int cmd:8;
|
|
int pad0:8;
|
|
int mw_index:8;
|
|
int number:8;
|
|
int pad1:8;
|
|
int base:24;
|
|
} Gsegment;
|
|
|
|
typedef struct {
|
|
int cmd:8;
|
|
int pad0:8;
|
|
int sft:8;
|
|
int len:8;
|
|
unsigned int data:32;
|
|
} GsetothermodeL;
|
|
|
|
typedef struct {
|
|
int cmd:8;
|
|
int pad0:8;
|
|
int sft:8;
|
|
int len:8;
|
|
unsigned int data:32;
|
|
} GsetothermodeH;
|
|
|
|
typedef struct {
|
|
unsigned char cmd;
|
|
unsigned char lodscale;
|
|
unsigned char tile;
|
|
unsigned char on;
|
|
unsigned short s;
|
|
unsigned short t;
|
|
} Gtexture;
|
|
|
|
typedef struct {
|
|
int cmd:8;
|
|
int pad:24;
|
|
Tri line;
|
|
} Gline3D;
|
|
|
|
typedef struct {
|
|
int cmd:8;
|
|
int pad1:24;
|
|
short int pad2;
|
|
short int scale;
|
|
} Gperspnorm;
|
|
|
|
|
|
/*
|
|
* RDP Packet types
|
|
*/
|
|
typedef struct {
|
|
int cmd:8;
|
|
unsigned int fmt:3;
|
|
unsigned int siz:2;
|
|
unsigned int pad:7;
|
|
unsigned int wd:12; /* really only 10 bits, extra */
|
|
uintptr_t dram; /* to account for 1024 */
|
|
} Gsetimg;
|
|
|
|
typedef struct {
|
|
int cmd:8;
|
|
unsigned int muxs0:24;
|
|
unsigned int muxs1:32;
|
|
} Gsetcombine;
|
|
|
|
typedef struct {
|
|
int cmd:8;
|
|
unsigned char pad;
|
|
unsigned char prim_min_level;
|
|
unsigned char prim_level;
|
|
unsigned long color;
|
|
} Gsetcolor;
|
|
|
|
typedef struct {
|
|
int cmd:8;
|
|
int x0:10;
|
|
int x0frac:2;
|
|
int y0:10;
|
|
int y0frac:2;
|
|
unsigned int pad:8;
|
|
int x1:10;
|
|
int x1frac:2;
|
|
int y1:10;
|
|
int y1frac:2;
|
|
} Gfillrect;
|
|
|
|
typedef struct {
|
|
int cmd:8;
|
|
unsigned int fmt:3;
|
|
unsigned int siz:2;
|
|
unsigned int pad0:1;
|
|
unsigned int line:9;
|
|
unsigned int tmem:9;
|
|
unsigned int pad1:5;
|
|
unsigned int tile:3;
|
|
unsigned int palette:4;
|
|
unsigned int ct:1;
|
|
unsigned int mt:1;
|
|
unsigned int maskt:4;
|
|
unsigned int shiftt:4;
|
|
unsigned int cs:1;
|
|
unsigned int ms:1;
|
|
unsigned int masks:4;
|
|
unsigned int shifts:4;
|
|
} Gsettile;
|
|
|
|
typedef struct {
|
|
int cmd:8;
|
|
unsigned int sl:12;
|
|
unsigned int tl:12;
|
|
int pad:5;
|
|
unsigned int tile:3;
|
|
unsigned int sh:12;
|
|
unsigned int th:12;
|
|
} Gloadtile;
|
|
|
|
typedef Gloadtile Gloadblock;
|
|
|
|
typedef Gloadtile Gsettilesize;
|
|
|
|
typedef Gloadtile Gloadtlut;
|
|
|
|
typedef struct {
|
|
unsigned int cmd:8; /* command */
|
|
unsigned int xl:12; /* X coordinate of upper left */
|
|
unsigned int yl:12; /* Y coordinate of upper left */
|
|
unsigned int pad1:5; /* Padding */
|
|
unsigned int tile:3; /* Tile descriptor index */
|
|
unsigned int xh:12; /* X coordinate of lower right */
|
|
unsigned int yh:12; /* Y coordinate of lower right */
|
|
unsigned int s:16; /* S texture coord at top left */
|
|
unsigned int t:16; /* T texture coord at top left */
|
|
unsigned int dsdx:16;/* Change in S per change in X */
|
|
unsigned int dtdy:16;/* Change in T per change in Y */
|
|
} Gtexrect;
|
|
|
|
/*
|
|
* Textured rectangles are 128 bits not 64 bits
|
|
*/
|
|
typedef struct {
|
|
unsigned long w0;
|
|
unsigned long w1;
|
|
unsigned long w2;
|
|
unsigned long w3;
|
|
} TexRect;
|
|
#endif
|
|
|
|
#define MakeTexRect(xh,yh,flip,tile,xl,yl,s,t,dsdx,dtdy) \
|
|
G_TEXRECT, xh, yh, 0, flip, 0, tile, xl, yl, s, t, dsdx, dtdy
|
|
|
|
/*
|
|
* Generic Gfx Packet
|
|
*/
|
|
typedef struct {
|
|
uintptr_t w0;
|
|
uintptr_t w1;
|
|
} Gwords;
|
|
|
|
/*
|
|
* This union is the fundamental type of the display list.
|
|
* It is, by law, exactly 64 bits in size.
|
|
*
|
|
* (Edit: except on 64-bit, where it is exactly 128 bit. On little-endian or
|
|
* 64-bit systems, only the 'words' member may be accessed; the rest of the
|
|
* structs don't have matching layouts for now.)
|
|
*/
|
|
typedef union {
|
|
Gwords words;
|
|
#if !defined(F3D_OLD) && IS_BIG_ENDIAN && !IS_64_BIT
|
|
Gdma dma;
|
|
Gtri tri;
|
|
Gline3D line;
|
|
Gpopmtx popmtx;
|
|
Gsegment segment;
|
|
GsetothermodeH setothermodeH;
|
|
GsetothermodeL setothermodeL;
|
|
Gtexture texture;
|
|
Gperspnorm perspnorm;
|
|
Gsetimg setimg;
|
|
Gsetcombine setcombine;
|
|
Gsetcolor setcolor;
|
|
Gfillrect fillrect; /* use for setscissor also */
|
|
Gsettile settile;
|
|
Gloadtile loadtile; /* use for loadblock also, th is dxt */
|
|
Gsettilesize settilesize;
|
|
Gloadtlut loadtlut;
|
|
#endif
|
|
long long int force_structure_alignment;
|
|
} Gfx;
|
|
|
|
/*
|
|
* Macros to assemble the graphics display list
|
|
*/
|
|
|
|
/*
|
|
* DMA macros
|
|
*/
|
|
#define gDma0p(pkt, c, s, l) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
\
|
|
_g->words.w0 = _SHIFTL((c), 24, 8) | _SHIFTL((l), 0, 24); \
|
|
_g->words.w1 = (uintptr_t)(s); \
|
|
}
|
|
|
|
#define gsDma0p(c, s, l) \
|
|
{{ \
|
|
_SHIFTL((c), 24, 8) | _SHIFTL((l), 0, 24), (uintptr_t)(s) \
|
|
}}
|
|
|
|
#define gDma1p(pkt, c, s, l, p) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
\
|
|
_g->words.w0 = (_SHIFTL((c), 24, 8) | _SHIFTL((p), 16, 8) | \
|
|
_SHIFTL((l), 0, 16)); \
|
|
_g->words.w1 = (uintptr_t)(s); \
|
|
}
|
|
|
|
#define gsDma1p(c, s, l, p) \
|
|
{{ \
|
|
(_SHIFTL((c), 24, 8) | _SHIFTL((p), 16, 8) | \
|
|
_SHIFTL((l), 0, 16)), \
|
|
(uintptr_t)(s) \
|
|
}}
|
|
|
|
#define gDma2p(pkt, c, adrs, len, idx, ofs) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
_g->words.w0 = (_SHIFTL((c),24,8)|_SHIFTL(((len)-1)/8,19,5)| \
|
|
_SHIFTL((ofs)/8,8,8)|_SHIFTL((idx),0,8)); \
|
|
_g->words.w1 = (uintptr_t)(adrs); \
|
|
}
|
|
#define gsDma2p(c, adrs, len, idx, ofs) \
|
|
{{ \
|
|
(_SHIFTL((c),24,8)|_SHIFTL(((len)-1)/8,19,5)| \
|
|
_SHIFTL((ofs)/8,8,8)|_SHIFTL((idx),0,8)), \
|
|
(uintptr_t)(adrs) \
|
|
}}
|
|
|
|
#ifdef F3DEX_GBI_2E
|
|
#define gCopyMemEXT(pkt, c, idx, dst, src, len) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
_g->words.w0 = (_SHIFTL((c),24,8)|_SHIFTL((src)/8,16,8)| \
|
|
_SHIFTL((dst)/8,8,8)|_SHIFTL((idx),0,8)); \
|
|
_g->words.w1 = (uintptr_t)(((len)-1)/8); \
|
|
}
|
|
#define gsCopyMemEXT(c, idx, dst, src, len) \
|
|
{{ \
|
|
(_SHIFTL((c),24,8)|_SHIFTL((src)/8,16,8)| \
|
|
_SHIFTL((dst)/8,8,8)|_SHIFTL((idx),0,8)), \
|
|
(uintptr_t)(((len)-1)/8) \
|
|
}}
|
|
#endif
|
|
|
|
#define gSPNoOp(pkt) gDma0p(pkt, G_SPNOOP, 0, 0)
|
|
#define gsSPNoOp() gsDma0p(G_SPNOOP, 0, 0)
|
|
|
|
#ifdef F3DEX_GBI_2
|
|
# define gSPMatrix(pkt, m, p) \
|
|
gDma2p((pkt),G_MTX,(m),sizeof(Mtx),(p)^G_MTX_PUSH,0)
|
|
# define gsSPMatrix(m, p) \
|
|
gsDma2p( G_MTX,(m),sizeof(Mtx),(p)^G_MTX_PUSH,0)
|
|
#else /* F3DEX_GBI_2 */
|
|
# define gSPMatrix(pkt, m, p) gDma1p(pkt, G_MTX, m, sizeof(Mtx), p)
|
|
# define gsSPMatrix(m, p) gsDma1p(G_MTX, m, sizeof(Mtx), p)
|
|
#endif /* F3DEX_GBI_2 */
|
|
|
|
#if defined(F3DEX_GBI_2)
|
|
/*
|
|
* F3DEX_GBI_2: G_VTX GBI format was changed.
|
|
*
|
|
* +--------+----+---+---+----+------+-+
|
|
* G_VTX | cmd:8 |0000| n:8 |0000|v0+n:7|0|
|
|
* +-+---+--+----+---+---+----+------+-+
|
|
* | |seg| address |
|
|
* +-+---+-----------------------------+
|
|
*/
|
|
# define gSPVertex(pkt, v, n, v0) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
_g->words.w0 = \
|
|
_SHIFTL(G_VTX,24,8)|_SHIFTL((n),12,8)|_SHIFTL((v0)+(n),1,7); \
|
|
_g->words.w1 = (uintptr_t)(v); \
|
|
}
|
|
# define gsSPVertex(v, n, v0) \
|
|
{{ \
|
|
(_SHIFTL(G_VTX,24,8)|_SHIFTL((n),12,8)|_SHIFTL((v0)+(n),1,7)), \
|
|
(uintptr_t)(v) \
|
|
}}
|
|
#elif (defined(F3DEX_GBI)||defined(F3DLP_GBI))
|
|
/*
|
|
* F3DEX_GBI: G_VTX GBI format was changed to support 64 vertice.
|
|
*
|
|
* +--------+--------+------+----------+
|
|
* G_VTX | cmd:8 | v0:8 | n:6 |length:10 |
|
|
* +-+---+--+--------+------+----------+
|
|
* | |seg| address |
|
|
* +-+---+-----------------------------+
|
|
*/
|
|
# define gSPVertex(pkt, v, n, v0) \
|
|
gDma1p((pkt),G_VTX,(v),((n)<<10)|(sizeof(Vtx)*(n)-1),(v0)*2)
|
|
# define gsSPVertex(v, n, v0) \
|
|
gsDma1p(G_VTX,(v),((n)<<10)|(sizeof(Vtx)*(n)-1),(v0)*2)
|
|
#else
|
|
# define gSPVertex(pkt, v, n, v0) \
|
|
gDma1p(pkt, G_VTX, v, sizeof(Vtx)*(n),((n)-1)<<4|(v0))
|
|
# define gsSPVertex(v, n, v0) \
|
|
gsDma1p(G_VTX, v, sizeof(Vtx)*(n), ((n)-1)<<4|(v0))
|
|
#endif
|
|
|
|
|
|
#ifdef F3DEX_GBI_2
|
|
# define gSPViewport(pkt, v) \
|
|
gDma2p((pkt), G_MOVEMEM, (v), sizeof(Vp), G_MV_VIEWPORT, 0)
|
|
# define gsSPViewport(v) \
|
|
gsDma2p( G_MOVEMEM, (v), sizeof(Vp), G_MV_VIEWPORT, 0)
|
|
#else /* F3DEX_GBI_2 */
|
|
# define gSPViewport(pkt,v) \
|
|
gDma1p((pkt), G_MOVEMEM, (v), sizeof(Vp), G_MV_VIEWPORT)
|
|
# define gsSPViewport(v) \
|
|
gsDma1p( G_MOVEMEM, (v), sizeof(Vp), G_MV_VIEWPORT)
|
|
#endif /* F3DEX_GBI_2 */
|
|
|
|
#define gSPDisplayList(pkt,dl) gDma1p(pkt,G_DL,dl,0,G_DL_PUSH)
|
|
#define gsSPDisplayList( dl) gsDma1p( G_DL,dl,0,G_DL_PUSH)
|
|
|
|
#define gSPBranchList(pkt,dl) gDma1p(pkt,G_DL,dl,0,G_DL_NOPUSH)
|
|
#define gsSPBranchList( dl) gsDma1p( G_DL,dl,0,G_DL_NOPUSH)
|
|
|
|
#define gSPSprite2DBase(pkt, s) gDma1p(pkt, G_SPRITE2D_BASE, s, sizeof(uSprite), 0)
|
|
#define gsSPSprite2DBase(s) gsDma1p(G_SPRITE2D_BASE, s, sizeof(uSprite), 0)
|
|
|
|
/*
|
|
* RSP short command (no DMA required) macros
|
|
*/
|
|
#define gImmp0(pkt, c) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
\
|
|
_g->words.w0 = _SHIFTL((c), 24, 8); \
|
|
}
|
|
|
|
#define gsImmp0(c) \
|
|
{{ \
|
|
_SHIFTL((c), 24, 8) \
|
|
}}
|
|
|
|
#define gImmp1(pkt, c, p0) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
\
|
|
_g->words.w0 = _SHIFTL((c), 24, 8); \
|
|
_g->words.w1 = (uintptr_t)(p0); \
|
|
}
|
|
|
|
#define gsImmp1(c, p0) \
|
|
{{ \
|
|
_SHIFTL((c), 24, 8), (uintptr_t)(p0) \
|
|
}}
|
|
|
|
#define gImmp2(pkt, c, p0, p1) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
\
|
|
_g->words.w0 = _SHIFTL((c), 24, 8); \
|
|
_g->words.w1 = _SHIFTL((p0), 16, 16) | _SHIFTL((p1), 8, 8); \
|
|
}
|
|
|
|
#define gsImmp2(c, p0, p1) \
|
|
{{ \
|
|
_SHIFTL((c), 24, 8), _SHIFTL((p0), 16, 16) | _SHIFTL((p1), 8, 8)\
|
|
}}
|
|
|
|
#define gImmp3(pkt, c, p0, p1, p2) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
\
|
|
_g->words.w0 = _SHIFTL((c), 24, 8); \
|
|
_g->words.w1 = (_SHIFTL((p0), 16, 16) | _SHIFTL((p1), 8, 8) | \
|
|
_SHIFTL((p2), 0, 8)); \
|
|
}
|
|
|
|
#define gsImmp3(c, p0, p1, p2) \
|
|
{{ \
|
|
_SHIFTL((c), 24, 8), (_SHIFTL((p0), 16, 16) | \
|
|
_SHIFTL((p1), 8, 8) | _SHIFTL((p2), 0, 8))\
|
|
}}
|
|
|
|
#define gImmp21(pkt, c, p0, p1, dat) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
\
|
|
_g->words.w0 = (_SHIFTL((c), 24, 8) | _SHIFTL((p0), 8, 16) | \
|
|
_SHIFTL((p1), 0, 8)); \
|
|
_g->words.w1 = (uintptr_t) (dat); \
|
|
}
|
|
|
|
#define gsImmp21(c, p0, p1, dat) \
|
|
{{ \
|
|
_SHIFTL((c), 24, 8) | _SHIFTL((p0), 8, 16) | _SHIFTL((p1), 0, 8),\
|
|
(uintptr_t) (dat) \
|
|
}}
|
|
|
|
#ifdef F3DEX_GBI_2
|
|
#define gMoveWd(pkt, index, offset, data) \
|
|
gDma1p((pkt), G_MOVEWORD, data, offset, index)
|
|
#define gsMoveWd( index, offset, data) \
|
|
gsDma1p( G_MOVEWORD, data, offset, index)
|
|
#else /* F3DEX_GBI_2 */
|
|
#define gMoveWd(pkt, index, offset, data) \
|
|
gImmp21((pkt), G_MOVEWORD, offset, index, data)
|
|
#define gsMoveWd( index, offset, data) \
|
|
gsImmp21( G_MOVEWORD, offset, index, data)
|
|
#endif /* F3DEX_GBI_2 */
|
|
|
|
/* Sprite immediate macros, there is also a sprite dma macro above */
|
|
|
|
#define gSPSprite2DScaleFlip(pkt, sx, sy, fx, fy) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
\
|
|
_g->words.w0 = (_SHIFTL(G_SPRITE2D_SCALEFLIP, 24, 8) | \
|
|
_SHIFTL((fx), 8, 8) | \
|
|
_SHIFTL((fy), 0, 8)); \
|
|
_g->words.w1 = (_SHIFTL((sx), 16, 16) | \
|
|
_SHIFTL((sy), 0, 16)); \
|
|
}
|
|
|
|
#define gsSPSprite2DScaleFlip(sx, sy, fx, fy) \
|
|
{{ \
|
|
(_SHIFTL(G_SPRITE2D_SCALEFLIP, 24, 8) | \
|
|
_SHIFTL((fx), 8, 8) | \
|
|
_SHIFTL((fy), 0, 8)), \
|
|
(_SHIFTL((sx), 16, 16) | \
|
|
_SHIFTL((sy), 0, 16)) \
|
|
}}
|
|
|
|
#define gSPSprite2DDraw(pkt, px, py) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
\
|
|
_g->words.w0 = (_SHIFTL(G_SPRITE2D_DRAW, 24, 8)); \
|
|
_g->words.w1 = (_SHIFTL((px), 16, 16) | \
|
|
_SHIFTL((py), 0, 16)); \
|
|
}
|
|
|
|
#define gsSPSprite2DDraw(px, py) \
|
|
{{ \
|
|
(_SHIFTL(G_SPRITE2D_DRAW, 24, 8)), \
|
|
(_SHIFTL((px), 16, 16) | \
|
|
_SHIFTL((py), 0, 16)) \
|
|
}}
|
|
|
|
|
|
/*
|
|
* Note: the SP1Triangle() and line macros multiply the vertex indices
|
|
* by 10, this is an optimization for the microcode.
|
|
*/
|
|
#if (defined(F3DLP_GBI)||defined(F3DEX_GBI))
|
|
# define __gsSP1Triangle_w1(v0, v1, v2) \
|
|
(_SHIFTL((v0)*2,16,8)|_SHIFTL((v1)*2,8,8)|_SHIFTL((v2)*2,0,8))
|
|
# define __gsSP1Triangle_w1f(v0, v1, v2, flag) \
|
|
(((flag) == 0) ? __gsSP1Triangle_w1(v0, v1, v2): \
|
|
((flag) == 1) ? __gsSP1Triangle_w1(v1, v2, v0): \
|
|
__gsSP1Triangle_w1(v2, v0, v1))
|
|
# define __gsSPLine3D_w1(v0, v1, wd) \
|
|
(_SHIFTL((v0)*2,16,8)|_SHIFT((v1)*2,8,8)|_SHIFT((wd),0,8))
|
|
# define __gsSPLine3D_w1f(v0, v1, wd, flag) \
|
|
(((flag) == 0) ? __gsSPLine3D_w1(v0, v1, wd): \
|
|
__gsSPLine3D_w1(v1, v0, wd))
|
|
# define __gsSP1Quadrangle_w1f(v0, v1, v2, v3, flag) \
|
|
(((flag) == 0) ? __gsSP1Triangle_w1(v0, v1, v2): \
|
|
((flag) == 1) ? __gsSP1Triangle_w1(v1, v2, v3): \
|
|
((flag) == 2) ? __gsSP1Triangle_w1(v2, v3, v0): \
|
|
__gsSP1Triangle_w1(v3, v0, v1))
|
|
# define __gsSP1Quadrangle_w2f(v0, v1, v2, v3, flag) \
|
|
(((flag) == 0) ? __gsSP1Triangle_w1(v0, v2, v3): \
|
|
((flag) == 1) ? __gsSP1Triangle_w1(v1, v3, v0): \
|
|
((flag) == 2) ? __gsSP1Triangle_w1(v2, v0, v1): \
|
|
__gsSP1Triangle_w1(v3, v1, v2))
|
|
#else
|
|
# define __gsSP1Triangle_w1f(v0, v1, v2, flag) \
|
|
(_SHIFTL((flag), 24,8)|_SHIFTL((v0)*10,16,8)| \
|
|
_SHIFTL((v1)*10, 8,8)|_SHIFTL((v2)*10, 0,8))
|
|
# define __gsSPLine3D_w1f(v0, v1, wd, flag) \
|
|
(_SHIFTL((flag), 24,8)|_SHIFTL((v0)*10,16,8)| \
|
|
_SHIFTL((v1)*10, 8,8)|_SHIFTL((wd), 0,8))
|
|
#endif
|
|
|
|
#ifdef F3DEX_GBI_2
|
|
/***
|
|
*** 1 Triangle
|
|
***/
|
|
#define gSP1Triangle(pkt, v0, v1, v2, flag) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
\
|
|
_g->words.w0 = _SHIFTL(G_TRI1, 24, 8)| \
|
|
__gsSP1Triangle_w1f(v0, v1, v2, flag); \
|
|
_g->words.w1 = 0; \
|
|
}
|
|
#define gsSP1Triangle(v0, v1, v2, flag) \
|
|
{{ \
|
|
_SHIFTL(G_TRI1, 24, 8)|__gsSP1Triangle_w1f(v0, v1, v2, flag), \
|
|
0 \
|
|
}}
|
|
|
|
/***
|
|
*** Line
|
|
***/
|
|
#define gSPLine3D(pkt, v0, v1, flag) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
\
|
|
_g->words.w0 = _SHIFTL(G_LINE3D, 24, 8)| \
|
|
__gsSPLine3D_w1f(v0, v1, 0, flag); \
|
|
_g->words.w1 = 0; \
|
|
}
|
|
#define gsSPLine3D(v0, v1, flag) \
|
|
{{ \
|
|
_SHIFTL(G_LINE3D, 24, 8)|__gsSPLine3D_w1f(v0, v1, 0, flag), \
|
|
0 \
|
|
}}
|
|
|
|
/***
|
|
*** LineW
|
|
***/
|
|
/* these macros are the same as SPLine3D, except they have an
|
|
* additional parameter for width. The width is added to the "minimum"
|
|
* thickness, which is 1.5 pixels. The units for width are in
|
|
* half-pixel units, so a width of 1 translates to (.5 + 1.5) or
|
|
* a 2.0 pixels wide line.
|
|
*/
|
|
#define gSPLineW3D(pkt, v0, v1, wd, flag) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
\
|
|
_g->words.w0 = _SHIFTL(G_LINE3D, 24, 8)| \
|
|
__gsSPLine3D_w1f(v0, v1, wd, flag); \
|
|
_g->words.w1 = 0; \
|
|
}
|
|
#define gsSPLineW3D(v0, v1, wd, flag) \
|
|
{{ \
|
|
_SHIFTL(G_LINE3D, 24, 8)|__gsSPLine3D_w1f(v0, v1, wd, flag), \
|
|
0 \
|
|
}}
|
|
|
|
/***
|
|
*** 1 Quadrangle
|
|
***/
|
|
#define gSP1Quadrangle(pkt, v0, v1, v2, v3, flag) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
\
|
|
_g->words.w0 = (_SHIFTL(G_QUAD, 24, 8)| \
|
|
__gsSP1Quadrangle_w1f(v0, v1, v2, v3, flag)); \
|
|
_g->words.w1 = __gsSP1Quadrangle_w2f(v0, v1, v2, v3, flag); \
|
|
}
|
|
|
|
#define gsSP1Quadrangle(v0, v1, v2, v3, flag) \
|
|
{{ \
|
|
(_SHIFTL(G_QUAD, 24, 8)| \
|
|
__gsSP1Quadrangle_w1f(v0, v1, v2, v3, flag)), \
|
|
__gsSP1Quadrangle_w2f(v0, v1, v2, v3, flag) \
|
|
}}
|
|
#else /* F3DEX_GBI_2 */
|
|
|
|
/***
|
|
*** 1 Triangle
|
|
***/
|
|
#define gSP1Triangle(pkt, v0, v1, v2, flag) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
\
|
|
_g->words.w0 = _SHIFTL(G_TRI1, 24, 8); \
|
|
_g->words.w1 = __gsSP1Triangle_w1f(v0, v1, v2, flag); \
|
|
}
|
|
#define gsSP1Triangle(v0, v1, v2, flag) \
|
|
{{ \
|
|
_SHIFTL(G_TRI1, 24, 8), \
|
|
__gsSP1Triangle_w1f(v0, v1, v2, flag) \
|
|
}}
|
|
|
|
/***
|
|
*** Line
|
|
***/
|
|
#define gSPLine3D(pkt, v0, v1, flag) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
\
|
|
_g->words.w0 = _SHIFTL(G_LINE3D, 24, 8); \
|
|
_g->words.w1 = __gsSPLine3D_w1f(v0, v1, 0, flag); \
|
|
}
|
|
#define gsSPLine3D(v0, v1, flag) \
|
|
{{ \
|
|
_SHIFTL(G_LINE3D, 24, 8), \
|
|
__gsSPLine3D_w1f(v0, v1, 0, flag) \
|
|
}}
|
|
|
|
/***
|
|
*** LineW
|
|
***/
|
|
/* these macros are the same as SPLine3D, except they have an
|
|
* additional parameter for width. The width is added to the "minimum"
|
|
* thickness, which is 1.5 pixels. The units for width are in
|
|
* half-pixel units, so a width of 1 translates to (.5 + 1.5) or
|
|
* a 2.0 pixels wide line.
|
|
*/
|
|
#define gSPLineW3D(pkt, v0, v1, wd, flag) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
\
|
|
_g->words.w0 = _SHIFTL(G_LINE3D, 24, 8); \
|
|
_g->words.w1 = __gsSPLine3D_w1f(v0, v1, wd, flag); \
|
|
}
|
|
#define gsSPLineW3D(v0, v1, wd, flag) \
|
|
{{ \
|
|
_SHIFTL(G_LINE3D, 24, 8), \
|
|
__gsSPLine3D_w1f(v0, v1, wd, flag) \
|
|
}}
|
|
|
|
/***
|
|
*** 1 Quadrangle
|
|
***/
|
|
#define gSP1Quadrangle(pkt, v0, v1, v2, v3, flag) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
\
|
|
_g->words.w0 = (_SHIFTL(G_TRI2, 24, 8)| \
|
|
__gsSP1Quadrangle_w1f(v0, v1, v2, v3, flag)); \
|
|
_g->words.w1 = __gsSP1Quadrangle_w2f(v0, v1, v2, v3, flag); \
|
|
}
|
|
|
|
#define gsSP1Quadrangle(v0, v1, v2, v3, flag) \
|
|
{{ \
|
|
(_SHIFTL(G_TRI2, 24, 8)| \
|
|
__gsSP1Quadrangle_w1f(v0, v1, v2, v3, flag)), \
|
|
__gsSP1Quadrangle_w2f(v0, v1, v2, v3, flag) \
|
|
}}
|
|
#endif /* F3DEX_GBI_2 */
|
|
|
|
#if (defined(F3DLP_GBI)||defined(F3DEX_GBI))
|
|
/***
|
|
*** 2 Triangles
|
|
***/
|
|
#define gSP2Triangles(pkt, v00, v01, v02, flag0, v10, v11, v12, flag1) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
\
|
|
_g->words.w0 = (_SHIFTL(G_TRI2, 24, 8)| \
|
|
__gsSP1Triangle_w1f(v00, v01, v02, flag0)); \
|
|
_g->words.w1 = __gsSP1Triangle_w1f(v10, v11, v12, flag1); \
|
|
}
|
|
|
|
#define gsSP2Triangles(v00, v01, v02, flag0, v10, v11, v12, flag1) \
|
|
{{ \
|
|
(_SHIFTL(G_TRI2, 24, 8)| \
|
|
__gsSP1Triangle_w1f(v00, v01, v02, flag0)), \
|
|
__gsSP1Triangle_w1f(v10, v11, v12, flag1) \
|
|
}}
|
|
#else
|
|
#define gSP2Triangles(pkt, v00, v01, v02, flag0, v10, v11, v12, flag1) \
|
|
{ \
|
|
gSP1Triangle(pkt, v00, v01, v02, flag0); \
|
|
gSP1Triangle(pkt, v10, v11, v12, flag1); \
|
|
}
|
|
#define gsSP2Triangles(v00, v01, v02, flag0, v10, v11, v12, flag1) \
|
|
gsSP1Triangle(v00, v01, v02, flag0), \
|
|
gsSP1Triangle(v10, v11, v12, flag1)
|
|
#endif /* F3DEX_GBI/F3DLP_GBI */
|
|
|
|
#if (defined(F3DEX_GBI)||defined(F3DLP_GBI))
|
|
#define gSPCullDisplayList(pkt,vstart,vend) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
\
|
|
_g->words.w0 = _SHIFTL(G_CULLDL, 24, 8) | \
|
|
_SHIFTL((vstart)*2, 0, 16); \
|
|
_g->words.w1 = _SHIFTL((vend)*2, 0, 16); \
|
|
}
|
|
|
|
#define gsSPCullDisplayList(vstart,vend) \
|
|
{{ \
|
|
_SHIFTL(G_CULLDL, 24, 8) | _SHIFTL((vstart)*2, 0, 16), \
|
|
_SHIFTL((vend)*2, 0, 16) \
|
|
}}
|
|
|
|
#else
|
|
#define gSPCullDisplayList(pkt,vstart,vend) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
\
|
|
_g->words.w0 = _SHIFTL(G_CULLDL, 24, 8) | \
|
|
((0x0f & (vstart))*40); \
|
|
_g->words.w1 = (unsigned int)((0x0f & ((vend)+1))*40); \
|
|
}
|
|
|
|
#define gsSPCullDisplayList(vstart,vend) \
|
|
{{ \
|
|
_SHIFTL(G_CULLDL, 24, 8) | ((0x0f & (vstart))*40), \
|
|
((0x0f & ((vend)+1))*40) \
|
|
}}
|
|
#endif
|
|
|
|
#define gSPSegment(pkt, segment, base) \
|
|
gMoveWd(pkt, G_MW_SEGMENT, (segment)*4, base)
|
|
#define gsSPSegment(segment, base) \
|
|
gsMoveWd( G_MW_SEGMENT, (segment)*4, base)
|
|
|
|
/*
|
|
* Clipping Macros
|
|
*/
|
|
#define FR_NEG_FRUSTRATIO_1 0x00000001
|
|
#define FR_POS_FRUSTRATIO_1 0x0000ffff
|
|
#define FR_NEG_FRUSTRATIO_2 0x00000002
|
|
#define FR_POS_FRUSTRATIO_2 0x0000fffe
|
|
#define FR_NEG_FRUSTRATIO_3 0x00000003
|
|
#define FR_POS_FRUSTRATIO_3 0x0000fffd
|
|
#define FR_NEG_FRUSTRATIO_4 0x00000004
|
|
#define FR_POS_FRUSTRATIO_4 0x0000fffc
|
|
#define FR_NEG_FRUSTRATIO_5 0x00000005
|
|
#define FR_POS_FRUSTRATIO_5 0x0000fffb
|
|
#define FR_NEG_FRUSTRATIO_6 0x00000006
|
|
#define FR_POS_FRUSTRATIO_6 0x0000fffa
|
|
/*
|
|
* r should be one of: FRUSTRATIO_1, FRUSTRATIO_2, FRUSTRATIO_3, ... FRUSTRATIO_6
|
|
*/
|
|
#define gSPClipRatio(pkt, r) \
|
|
{ \
|
|
gMoveWd(pkt, G_MW_CLIP, G_MWO_CLIP_RNX, FR_NEG_##r); \
|
|
gMoveWd(pkt, G_MW_CLIP, G_MWO_CLIP_RNY, FR_NEG_##r); \
|
|
gMoveWd(pkt, G_MW_CLIP, G_MWO_CLIP_RPX, FR_POS_##r); \
|
|
gMoveWd(pkt, G_MW_CLIP, G_MWO_CLIP_RPY, FR_POS_##r); \
|
|
}
|
|
|
|
#define gsSPClipRatio(r) \
|
|
gsMoveWd(G_MW_CLIP, G_MWO_CLIP_RNX, FR_NEG_##r), \
|
|
gsMoveWd(G_MW_CLIP, G_MWO_CLIP_RNY, FR_NEG_##r), \
|
|
gsMoveWd(G_MW_CLIP, G_MWO_CLIP_RPX, FR_POS_##r), \
|
|
gsMoveWd(G_MW_CLIP, G_MWO_CLIP_RPY, FR_POS_##r)
|
|
|
|
/*
|
|
* Insert values into Matrix
|
|
*
|
|
* where = element of matrix (byte offset)
|
|
* num = new element (32 bit value replacing 2 int or 2 frac matrix
|
|
* componants
|
|
*/
|
|
#ifdef F3DEX_GBI_2
|
|
#define gSPInsertMatrix(pkt, where, num) \
|
|
ERROR!! gSPInsertMatrix is no longer supported.
|
|
#define gsSPInsertMatrix(where, num) \
|
|
ERROR!! gsSPInsertMatrix is no longer supported.
|
|
#else
|
|
#define gSPInsertMatrix(pkt, where, num) \
|
|
gMoveWd(pkt, G_MW_MATRIX, where, num)
|
|
#define gsSPInsertMatrix(where, num) \
|
|
gsMoveWd(G_MW_MATRIX, where, num)
|
|
#endif
|
|
|
|
/*
|
|
* Load new matrix directly
|
|
*
|
|
* mptr = pointer to matrix
|
|
*/
|
|
#ifdef F3DEX_GBI_2
|
|
#define gSPForceMatrix(pkt, mptr) \
|
|
{ gDma2p((pkt),G_MOVEMEM,(mptr),sizeof(Mtx),G_MV_MATRIX,0); \
|
|
gMoveWd((pkt), G_MW_FORCEMTX,0,0x00010000); \
|
|
}
|
|
#define gsSPForceMatrix(mptr) \
|
|
gsDma2p(G_MOVEMEM,(mptr),sizeof(Mtx),G_MV_MATRIX,0), \
|
|
gsMoveWd(G_MW_FORCEMTX,0,0x00010000)
|
|
|
|
#else /* F3DEX_GBI_2 */
|
|
#define gSPForceMatrix(pkt, mptr) \
|
|
{ \
|
|
gDma1p(pkt, G_MOVEMEM, mptr, 16, G_MV_MATRIX_1); \
|
|
gDma1p(pkt, G_MOVEMEM, (char *)(mptr)+16, 16, G_MV_MATRIX_2); \
|
|
gDma1p(pkt, G_MOVEMEM, (char *)(mptr)+32, 16, G_MV_MATRIX_3); \
|
|
gDma1p(pkt, G_MOVEMEM, (char *)(mptr)+48, 16, G_MV_MATRIX_4); \
|
|
}
|
|
#define gsSPForceMatrix(mptr) \
|
|
gsDma1p( G_MOVEMEM, mptr, 16, G_MV_MATRIX_1), \
|
|
gsDma1p( G_MOVEMEM, (char *)(mptr)+16, 16, G_MV_MATRIX_2), \
|
|
gsDma1p( G_MOVEMEM, (char *)(mptr)+32, 16, G_MV_MATRIX_3), \
|
|
gsDma1p( G_MOVEMEM, (char *)(mptr)+48, 16, G_MV_MATRIX_4)
|
|
#endif /* F3DEX_GBI_2 */
|
|
|
|
/*
|
|
* Insert values into Points
|
|
*
|
|
* point = point number 0-15
|
|
* where = which element of point to modify (byte offset into point)
|
|
* num = new value (32 bit)
|
|
*/
|
|
#if (defined(F3DEX_GBI)||defined(F3DLP_GBI))
|
|
# define gSPModifyVertex(pkt, vtx, where, val) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
_g->words.w0 = (_SHIFTL(G_MODIFYVTX,24,8)| \
|
|
_SHIFTL((where),16,8)|_SHIFTL((vtx)*2,0,16)); \
|
|
_g->words.w1 = (unsigned int)(val); \
|
|
}
|
|
# define gsSPModifyVertex(vtx, where, val) \
|
|
{{ \
|
|
_SHIFTL(G_MODIFYVTX,24,8)| \
|
|
_SHIFTL((where),16,8)|_SHIFTL((vtx)*2,0,16), \
|
|
(unsigned int)(val) \
|
|
}}
|
|
#else
|
|
# define gSPModifyVertex(pkt, vtx, where, val) \
|
|
gMoveWd(pkt, G_MW_POINTS, (vtx)*40+(where), val)
|
|
# define gsSPModifyVertex(vtx, where, val) \
|
|
gsMoveWd(G_MW_POINTS, (vtx)*40+(where), val)
|
|
#endif
|
|
|
|
#if (defined(F3DEX_GBI)||defined(F3DLP_GBI))
|
|
/*
|
|
* gSPBranchLessZ Branch DL if (vtx.z) less than or equal (zval).
|
|
*
|
|
* dl = DL branch to
|
|
* vtx = Vertex
|
|
* zval = Screen depth
|
|
* near = Near plane
|
|
* far = Far plane
|
|
* flag = G_BZ_PERSP or G_BZ_ORTHO
|
|
*/
|
|
|
|
#define G_BZ_PERSP 0
|
|
#define G_BZ_ORTHO 1
|
|
|
|
#define G_DEPTOZSrg(zval, near, far, flag, zmin, zmax) \
|
|
(((unsigned int)FTOFIX32(((flag) == G_BZ_PERSP ? \
|
|
(1.0f-(float)(near)/(float)(zval)) / \
|
|
(1.0f-(float)(near)/(float)(far )) : \
|
|
((float)(zval) - (float)(near)) / \
|
|
((float)(far ) - (float)(near))))) * \
|
|
(((int)((zmax) - (zmin)))&~1) + (int)FTOFIX32(zmin))
|
|
|
|
#define G_DEPTOZS(zval, near, far, flag) \
|
|
G_DEPTOZSrg(zval, near, far, flag, 0, G_MAXZ)
|
|
|
|
#define gSPBranchLessZrg(pkt, dl, vtx, zval, near, far, flag, zmin, zmax) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
_g->words.w0 = _SHIFTL(G_RDPHALF_1,24,8); \
|
|
_g->words.w1 = (uintptr_t)(dl); \
|
|
_g = (Gfx *)(pkt); \
|
|
_g->words.w0 = (_SHIFTL(G_BRANCH_Z,24,8)| \
|
|
_SHIFTL((vtx)*5,12,12)|_SHIFTL((vtx)*2,0,12)); \
|
|
_g->words.w1 = G_DEPTOZSrg(zval, near, far, flag, zmin, zmax); \
|
|
}
|
|
|
|
#define gsSPBranchLessZrg(dl, vtx, zval, near, far, flag, zmin, zmax) \
|
|
{{ _SHIFTL(G_RDPHALF_1,24,8), \
|
|
(uintptr_t)(dl), }}, \
|
|
{{ _SHIFTL(G_BRANCH_Z,24,8)|_SHIFTL((vtx)*5,12,12)|_SHIFTL((vtx)*2,0,12),\
|
|
G_DEPTOZSrg(zval, near, far, flag, zmin, zmax), }}
|
|
|
|
#define gSPBranchLessZ(pkt, dl, vtx, zval, near, far, flag) \
|
|
gSPBranchLessZrg(pkt, dl, vtx, zval, near, far, flag, 0, G_MAXZ)
|
|
#define gsSPBranchLessZ(dl, vtx, zval, near, far, flag) \
|
|
gsSPBranchLessZrg(dl, vtx, zval, near, far, flag, 0, G_MAXZ)
|
|
|
|
/*
|
|
* gSPBranchLessZraw Branch DL if (vtx.z) less than or equal (raw zval).
|
|
*
|
|
* dl = DL branch to
|
|
* vtx = Vertex
|
|
* zval = Raw value of screen depth
|
|
*/
|
|
#define gSPBranchLessZraw(pkt, dl, vtx, zval) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
_g->words.w0 = _SHIFTL(G_RDPHALF_1,24,8); \
|
|
_g->words.w1 = (uintptr_t)(dl); \
|
|
_g = (Gfx *)(pkt); \
|
|
_g->words.w0 = (_SHIFTL(G_BRANCH_Z,24,8)| \
|
|
_SHIFTL((vtx)*5,12,12)|_SHIFTL((vtx)*2,0,12)); \
|
|
_g->words.w1 = (unsigned int)(zval); \
|
|
}
|
|
|
|
#define gsSPBranchLessZraw(dl, vtx, zval) \
|
|
{{ _SHIFTL(G_RDPHALF_1,24,8), \
|
|
(uintptr_t)(dl), }}, \
|
|
{{ _SHIFTL(G_BRANCH_Z,24,8)|_SHIFTL((vtx)*5,12,12)|_SHIFTL((vtx)*2,0,12),\
|
|
(unsigned int)(zval), }}
|
|
|
|
/*
|
|
* gSPLoadUcode RSP loads specified ucode.
|
|
*
|
|
* uc_start = ucode text section start
|
|
* uc_dstart = ucode data section start
|
|
*/
|
|
#define gSPLoadUcodeEx(pkt, uc_start, uc_dstart, uc_dsize) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
_g->words.w0 = _SHIFTL(G_RDPHALF_1,24,8); \
|
|
_g->words.w1 = (uintptr_t)(uc_dstart); \
|
|
_g = (Gfx *)(pkt); \
|
|
_g->words.w0 = (_SHIFTL(G_LOAD_UCODE,24,8)| \
|
|
_SHIFTL((int)(uc_dsize)-1,0,16)); \
|
|
_g->words.w1 = (uintptr_t)(uc_start); \
|
|
}
|
|
|
|
#define gsSPLoadUcodeEx(uc_start, uc_dstart, uc_dsize) \
|
|
{{ _SHIFTL(G_RDPHALF_1,24,8), \
|
|
(uintptr_t)(uc_dstart), }}, \
|
|
{{ _SHIFTL(G_LOAD_UCODE,24,8)| \
|
|
_SHIFTL((int)(uc_dsize)-1,0,16), \
|
|
(uintptr_t)(uc_start), }}
|
|
|
|
#define gSPLoadUcode(pkt, uc_start, uc_dstart) \
|
|
gSPLoadUcodeEx((pkt), (uc_start), (uc_dstart), SP_UCODE_DATA_SIZE)
|
|
#define gsSPLoadUcode(uc_start, uc_dstart) \
|
|
gsSPLoadUcodeEx((uc_start), (uc_dstart), SP_UCODE_DATA_SIZE)
|
|
|
|
#define gSPLoadUcodeL(pkt, ucode) \
|
|
gSPLoadUcode((pkt), OS_K0_TO_PHYSICAL(&##ucode##TextStart), \
|
|
OS_K0_TO_PHYSICAL(&##ucode##DataStart))
|
|
#define gsSPLoadUcodeL(ucode) \
|
|
gsSPLoadUcode(OS_K0_TO_PHYSICAL(&##ucode##TextStart), \
|
|
OS_K0_TO_PHYSICAL(&##ucode##DataStart))
|
|
#endif
|
|
|
|
#ifdef F3DEX_GBI_2
|
|
/*
|
|
* gSPDma_io DMA to/from DMEM/IMEM for DEBUG.
|
|
*/
|
|
#define gSPDma_io(pkt, flag, dmem, dram, size) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
_g->words.w0 = _SHIFTL(G_DMA_IO,24,8)|_SHIFTL((flag),23,1)| \
|
|
_SHIFTL((dmem)/8,13,10)|_SHIFTL((size)-1,0,12); \
|
|
_g->words.w1 = (uintptr_t)(dram); \
|
|
}
|
|
|
|
#define gsSPDma_io(flag, dmem, dram, size) \
|
|
{{ \
|
|
_SHIFTL(G_DMA_IO,24,8)|_SHIFTL((flag),23,1)| \
|
|
_SHIFTL((dmem)/8,13,10)|_SHIFTL((size)-1,0,12), \
|
|
(uintptr_t)(dram) \
|
|
}}
|
|
|
|
#define gSPDmaRead(pkt,dmem,dram,size) gSPDma_io((pkt),0,(dmem),(dram),(size))
|
|
#define gsSPDmaRead(dmem,dram,size) gsSPDma_io(0,(dmem),(dram),(size))
|
|
#define gSPDmaWrite(pkt,dmem,dram,size) gSPDma_io((pkt),1,(dmem),(dram),(size))
|
|
#define gsSPDmaWrite(dmem,dram,size) gsSPDma_io(1,(dmem),(dram),(size))
|
|
#endif
|
|
|
|
/*
|
|
* Lighting Macros
|
|
*/
|
|
#ifdef F3DEX_GBI_2
|
|
# define NUML(n) ((n)*24)
|
|
#else
|
|
# define NUML(n) (((n)+1)*32 + 0x80000000)
|
|
#endif
|
|
#define NUMLIGHTS_0 1
|
|
#define NUMLIGHTS_1 1
|
|
#define NUMLIGHTS_2 2
|
|
#define NUMLIGHTS_3 3
|
|
#define NUMLIGHTS_4 4
|
|
#define NUMLIGHTS_5 5
|
|
#define NUMLIGHTS_6 6
|
|
#define NUMLIGHTS_7 7
|
|
/*
|
|
* n should be one of: NUMLIGHTS_0, NUMLIGHTS_1, ..., NUMLIGHTS_7
|
|
* NOTE: in addition to the number of directional lights specified,
|
|
* there is always 1 ambient light
|
|
*/
|
|
#define gSPNumLights(pkt, n) \
|
|
gMoveWd(pkt, G_MW_NUMLIGHT, G_MWO_NUMLIGHT, NUML(n))
|
|
#define gsSPNumLights(n) \
|
|
gsMoveWd( G_MW_NUMLIGHT, G_MWO_NUMLIGHT, NUML(n))
|
|
|
|
#define LIGHT_1 1
|
|
#define LIGHT_2 2
|
|
#define LIGHT_3 3
|
|
#define LIGHT_4 4
|
|
#define LIGHT_5 5
|
|
#define LIGHT_6 6
|
|
#define LIGHT_7 7
|
|
#define LIGHT_8 8
|
|
/*
|
|
* l should point to a Light struct
|
|
* n should be one of: LIGHT_1, LIGHT_2, ..., LIGHT_8
|
|
* NOTE: the highest numbered light is always the ambient light (eg if there are
|
|
* 3 directional lights defined: gsSPNumLights(NUMLIGHTS_3), then lights
|
|
* LIGHT_1 through LIGHT_3 will be the directional lights and light
|
|
* LIGHT_4 will be the ambient light.
|
|
*/
|
|
#ifdef F3DEX_GBI_2
|
|
# define gSPLight(pkt, l, n) \
|
|
gDma2p((pkt),G_MOVEMEM,(l),sizeof(Light),G_MV_LIGHT,(n)*24+24)
|
|
# define gsSPLight(l, n) \
|
|
gsDma2p( G_MOVEMEM,(l),sizeof(Light),G_MV_LIGHT,(n)*24+24)
|
|
#else /* F3DEX_GBI_2 */
|
|
# define gSPLight(pkt, l, n) \
|
|
gDma1p(pkt, G_MOVEMEM, l, sizeof(Light),((n)-1)*2+G_MV_L0)
|
|
# define gsSPLight(l, n) \
|
|
gsDma1p( G_MOVEMEM, l, sizeof(Light),((n)-1)*2+G_MV_L0)
|
|
#endif /* F3DEX_GBI_2 */
|
|
|
|
/*
|
|
* EXTENDED COMMAND
|
|
* Copy one light's parameters to the other.
|
|
*/
|
|
#ifdef F3DEX_GBI_2E
|
|
#define gSPCopyLightEXT(pkt, dst, src) \
|
|
gCopyMemEXT((pkt),G_COPYMEM,G_MV_LIGHT,(dst)*24+24,(src)*24+24,sizeof(Light))
|
|
#define gsSPCopyLightEXT(dst, src) \
|
|
gsCopyMemEXT( G_COPYMEM,G_MV_LIGHT,(dst)*24+24,(src)*24+24,sizeof(Light))
|
|
#define gSPCopyLightsPlayerPart(pkt, part) \
|
|
gSPCopyLightEXT((pkt), 1, ((2 * ((part) + 1)) + 1)); \
|
|
gSPCopyLightEXT((pkt), 2, ((2 * ((part) + 1)) + 2));
|
|
#define gsSPCopyLightsPlayerPart(part) \
|
|
gsSPCopyLightEXT(1, ((2 * ((part) + 1)) + 1)), \
|
|
gsSPCopyLightEXT(2, ((2 * ((part) + 1)) + 2))
|
|
#endif
|
|
|
|
/*
|
|
* gSPLightColor changes color of light without recalculating light direction
|
|
* col is a 32 bit word with r,g,b,a (alpha is ignored)
|
|
* n should be one of LIGHT_1, LIGHT_2, ..., LIGHT_8
|
|
*/
|
|
#define gSPLightColor(pkt, n, col) \
|
|
{ \
|
|
gMoveWd(pkt, G_MW_LIGHTCOL, G_MWO_a##n, col); \
|
|
gMoveWd(pkt, G_MW_LIGHTCOL, G_MWO_b##n, col); \
|
|
}
|
|
#define gsSPLightColor(n, col) \
|
|
gsMoveWd(G_MW_LIGHTCOL, G_MWO_a##n, col), \
|
|
gsMoveWd(G_MW_LIGHTCOL, G_MWO_b##n, col)
|
|
|
|
/* These macros use a structure "name" which is init'd with the gdSPDefLights macros*/
|
|
|
|
#define gSPSetLights0(pkt,name) \
|
|
{ \
|
|
gSPNumLights(pkt,NUMLIGHTS_0); \
|
|
gSPLight(pkt,&name.l[0],1); \
|
|
gSPLight(pkt,&name.a,2); \
|
|
}
|
|
#define gsSPSetLights0(name) \
|
|
gsSPNumLights(NUMLIGHTS_0), \
|
|
gsSPLight(&name.l[0],1), \
|
|
gsSPLight(&name.a,2)
|
|
|
|
#define gSPSetLights1(pkt,name) \
|
|
{ \
|
|
gSPNumLights(pkt,NUMLIGHTS_1); \
|
|
gSPLight(pkt,&name.l[0],1); \
|
|
gSPLight(pkt,&name.a,2); \
|
|
}
|
|
#define gsSPSetLights1(name) \
|
|
gsSPNumLights(NUMLIGHTS_1), \
|
|
gsSPLight(&name.l[0],1), \
|
|
gsSPLight(&name.a,2)
|
|
|
|
#define gSPSetLights2(pkt,name) \
|
|
{ \
|
|
gSPNumLights(pkt,NUMLIGHTS_2); \
|
|
gSPLight(pkt,&name.l[0],1); \
|
|
gSPLight(pkt,&name.l[1],2); \
|
|
gSPLight(pkt,&name.a,3); \
|
|
}
|
|
#define gsSPSetLights2(name) \
|
|
gsSPNumLights(NUMLIGHTS_2), \
|
|
gsSPLight(&name.l[0],1), \
|
|
gsSPLight(&name.l[1],2), \
|
|
gsSPLight(&name.a,3)
|
|
|
|
#define gSPSetLights3(pkt,name) \
|
|
{ \
|
|
gSPNumLights(pkt,NUMLIGHTS_3); \
|
|
gSPLight(pkt,&name.l[0],1); \
|
|
gSPLight(pkt,&name.l[1],2); \
|
|
gSPLight(pkt,&name.l[2],3); \
|
|
gSPLight(pkt,&name.a,4); \
|
|
}
|
|
#define gsSPSetLights3(name) \
|
|
gsSPNumLights(NUMLIGHTS_3), \
|
|
gsSPLight(&name.l[0],1), \
|
|
gsSPLight(&name.l[1],2), \
|
|
gsSPLight(&name.l[2],3), \
|
|
gsSPLight(&name.a,4)
|
|
|
|
#define gSPSetLights4(pkt,name) \
|
|
{ \
|
|
gSPNumLights(pkt,NUMLIGHTS_4); \
|
|
gSPLight(pkt,&name.l[0],1); \
|
|
gSPLight(pkt,&name.l[1],2); \
|
|
gSPLight(pkt,&name.l[2],3); \
|
|
gSPLight(pkt,&name.l[3],4); \
|
|
gSPLight(pkt,&name.a,5); \
|
|
}
|
|
#define gsSPSetLights4(name) \
|
|
gsSPNumLights(NUMLIGHTS_4), \
|
|
gsSPLight(&name.l[0],1), \
|
|
gsSPLight(&name.l[1],2), \
|
|
gsSPLight(&name.l[2],3), \
|
|
gsSPLight(&name.l[3],4), \
|
|
gsSPLight(&name.a,5)
|
|
|
|
#define gSPSetLights5(pkt,name) \
|
|
{ \
|
|
gSPNumLights(pkt,NUMLIGHTS_5); \
|
|
gSPLight(pkt,&name.l[0],1); \
|
|
gSPLight(pkt,&name.l[1],2); \
|
|
gSPLight(pkt,&name.l[2],3); \
|
|
gSPLight(pkt,&name.l[3],4); \
|
|
gSPLight(pkt,&name.l[4],5); \
|
|
gSPLight(pkt,&name.a,6); \
|
|
}
|
|
|
|
#define gsSPSetLights5(name) \
|
|
gsSPNumLights(NUMLIGHTS_5), \
|
|
gsSPLight(&name.l[0],1), \
|
|
gsSPLight(&name.l[1],2), \
|
|
gsSPLight(&name.l[2],3), \
|
|
gsSPLight(&name.l[3],4), \
|
|
gsSPLight(&name.l[4],5), \
|
|
gsSPLight(&name.a,6)
|
|
|
|
#define gSPSetLights6(pkt,name) \
|
|
{ \
|
|
gSPNumLights(pkt,NUMLIGHTS_6); \
|
|
gSPLight(pkt,&name.l[0],1); \
|
|
gSPLight(pkt,&name.l[1],2); \
|
|
gSPLight(pkt,&name.l[2],3); \
|
|
gSPLight(pkt,&name.l[3],4); \
|
|
gSPLight(pkt,&name.l[4],5); \
|
|
gSPLight(pkt,&name.l[5],6); \
|
|
gSPLight(pkt,&name.a,7); \
|
|
}
|
|
|
|
#define gsSPSetLights6(name) \
|
|
gsSPNumLights(NUMLIGHTS_6), \
|
|
gsSPLight(&name.l[0],1), \
|
|
gsSPLight(&name.l[1],2), \
|
|
gsSPLight(&name.l[2],3), \
|
|
gsSPLight(&name.l[3],4), \
|
|
gsSPLight(&name.l[4],5), \
|
|
gsSPLight(&name.l[5],6), \
|
|
gsSPLight(&name.a,7)
|
|
|
|
#define gSPSetLights7(pkt,name) \
|
|
{ \
|
|
gSPNumLights(pkt,NUMLIGHTS_7); \
|
|
gSPLight(pkt,&name.l[0],1); \
|
|
gSPLight(pkt,&name.l[1],2); \
|
|
gSPLight(pkt,&name.l[2],3); \
|
|
gSPLight(pkt,&name.l[3],4); \
|
|
gSPLight(pkt,&name.l[4],5); \
|
|
gSPLight(pkt,&name.l[5],6); \
|
|
gSPLight(pkt,&name.l[6],7); \
|
|
gSPLight(pkt,&name.a,8); \
|
|
}
|
|
|
|
#define gsSPSetLights7(name) \
|
|
gsSPNumLights(NUMLIGHTS_7), \
|
|
gsSPLight(&name.l[0],1), \
|
|
gsSPLight(&name.l[1],2), \
|
|
gsSPLight(&name.l[2],3), \
|
|
gsSPLight(&name.l[3],4), \
|
|
gsSPLight(&name.l[4],5), \
|
|
gsSPLight(&name.l[5],6), \
|
|
gsSPLight(&name.l[6],7), \
|
|
gsSPLight(&name.a,8)
|
|
|
|
/*
|
|
* Reflection/Hiliting Macros
|
|
*/
|
|
#ifdef F3DEX_GBI_2
|
|
# define gSPLookAtX(pkt, l) \
|
|
gDma2p((pkt),G_MOVEMEM,(l),sizeof(Light),G_MV_LIGHT,G_MVO_LOOKATX)
|
|
# define gsSPLookAtX(l) \
|
|
gsDma2p( G_MOVEMEM,(l),sizeof(Light),G_MV_LIGHT,G_MVO_LOOKATX)
|
|
# define gSPLookAtY(pkt, l) \
|
|
gDma2p((pkt),G_MOVEMEM,(l),sizeof(Light),G_MV_LIGHT,G_MVO_LOOKATY)
|
|
# define gsSPLookAtY(l) \
|
|
gsDma2p( G_MOVEMEM,(l),sizeof(Light),G_MV_LIGHT,G_MVO_LOOKATY)
|
|
#else /* F3DEX_GBI_2 */
|
|
# define gSPLookAtX(pkt, l) \
|
|
gDma1p(pkt, G_MOVEMEM, l, sizeof(Light),G_MV_LOOKATX)
|
|
# define gsSPLookAtX(l) \
|
|
gsDma1p( G_MOVEMEM, l, sizeof(Light),G_MV_LOOKATX)
|
|
# define gSPLookAtY(pkt, l) \
|
|
gDma1p(pkt, G_MOVEMEM, l, sizeof(Light),G_MV_LOOKATY)
|
|
# define gsSPLookAtY(l) \
|
|
gsDma1p( G_MOVEMEM, l, sizeof(Light),G_MV_LOOKATY)
|
|
#endif /* F3DEX_GBI_2 */
|
|
|
|
#define gSPLookAt(pkt, la) \
|
|
{ \
|
|
gSPLookAtX(pkt,la) \
|
|
gSPLookAtY(pkt,(char *)(la)+16) \
|
|
}
|
|
#define gsSPLookAt(la) \
|
|
gsSPLookAtX(la), \
|
|
gsSPLookAtY((char *)(la)+16)
|
|
|
|
#define gDPSetHilite1Tile(pkt, tile, hilite, width, height) \
|
|
gDPSetTileSize(pkt, tile, (hilite)->h.x1 & 0xfff, (hilite)->h.y1 & 0xfff, \
|
|
((((width)-1)*4)+(hilite)->h.x1) & 0xfff, ((((height)-1)*4)+(hilite)->h.y1) & 0xfff)
|
|
|
|
#define gDPSetHilite2Tile(pkt, tile, hilite, width, height) \
|
|
gDPSetTileSize(pkt, tile, (hilite)->h.x2 & 0xfff, (hilite)->h.y2 & 0xfff, \
|
|
((((width)-1)*4)+(hilite)->h.x2) & 0xfff, ((((height)-1)*4)+(hilite)->h.y2) & 0xfff)
|
|
|
|
|
|
/*
|
|
* FOG macros
|
|
* fm = z multiplier
|
|
* fo = z offset
|
|
* FOG FORMULA: alpha(fog) = (eyespace z) * fm + fo CLAMPED 0 to 255
|
|
* note: (eyespace z) ranges -1 to 1
|
|
*
|
|
* Alternate method of setting fog:
|
|
* min, max: range 0 to 1000: 0=nearplane, 1000=farplane
|
|
* min is where fog begins (usually less than max and often 0)
|
|
* max is where fog is thickest (usually 1000)
|
|
*
|
|
*/
|
|
#define gSPFogFactor(pkt, fm, fo) \
|
|
gMoveWd(pkt, G_MW_FOG, G_MWO_FOG, \
|
|
(_SHIFTL(fm,16,16) | _SHIFTL(fo,0,16)))
|
|
|
|
#define gsSPFogFactor(fm, fo) \
|
|
gsMoveWd(G_MW_FOG, G_MWO_FOG, \
|
|
(_SHIFTL(fm,16,16) | _SHIFTL(fo,0,16)))
|
|
|
|
#define gSPFogPosition(pkt, min, max) \
|
|
gMoveWd(pkt, G_MW_FOG, G_MWO_FOG, \
|
|
(_SHIFTL((128000/((max)-(min))),16,16) | \
|
|
_SHIFTL(((500-(min))*256/((max)-(min))),0,16)))
|
|
|
|
#define gsSPFogPosition(min, max) \
|
|
gsMoveWd(G_MW_FOG, G_MWO_FOG, \
|
|
(_SHIFTL((128000/((max)-(min))),16,16) | \
|
|
_SHIFTL(((500-(min))*256/((max)-(min))),0,16)))
|
|
|
|
#ifdef F3DEX_GBI_2
|
|
/*
|
|
* Macros to turn texture on/off
|
|
*/
|
|
# define gSPTexture(pkt, s, t, level, tile, on) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
\
|
|
_g->words.w0 = (_SHIFTL(G_TEXTURE,24,8) | \
|
|
_SHIFTL(BOWTIE_VAL,16,8) | \
|
|
_SHIFTL((level),11,3) | _SHIFTL((tile),8,3) | \
|
|
_SHIFTL((on),1,7)); \
|
|
_g->words.w1 = (_SHIFTL((s),16,16) | _SHIFTL((t),0,16)); \
|
|
}
|
|
# define gsSPTexture(s, t, level, tile, on) \
|
|
{{ \
|
|
(_SHIFTL(G_TEXTURE,24,8) | _SHIFTL(BOWTIE_VAL,16,8) | \
|
|
_SHIFTL((level),11,3) | _SHIFTL((tile),8,3) | _SHIFTL((on),1,7)),\
|
|
(_SHIFTL((s),16,16) | _SHIFTL((t),0,16)) \
|
|
}}
|
|
/*
|
|
* Different version of SPTexture macro, has an additional parameter
|
|
* which is currently reserved in the microcode.
|
|
*/
|
|
# define gSPTextureL(pkt, s, t, level, xparam, tile, on) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
\
|
|
_g->words.w0 = (_SHIFTL(G_TEXTURE,24,8) | \
|
|
_SHIFTL((xparam),16,8) | \
|
|
_SHIFTL((level),11,3) | _SHIFTL((tile),8,3) | \
|
|
_SHIFTL((on),1,7)); \
|
|
_g->words.w1 = (_SHIFTL((s),16,16) | _SHIFTL((t),0,16)); \
|
|
}
|
|
# define gsSPTextureL(s, t, level, xparam, tile, on) \
|
|
{{ \
|
|
(_SHIFTL(G_TEXTURE,24,8) | _SHIFTL((xparam),16,8) | \
|
|
_SHIFTL((level),11,3) | _SHIFTL((tile),8,3) | _SHIFTL((on),1,7)),\
|
|
(_SHIFTL((s),16,16) | _SHIFTL((t),0,16)) \
|
|
}}
|
|
#else
|
|
/*
|
|
* Macros to turn texture on/off
|
|
*/
|
|
# define gSPTexture(pkt, s, t, level, tile, on) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
\
|
|
_g->words.w0 = (_SHIFTL(G_TEXTURE,24,8)|_SHIFTL(BOWTIE_VAL,16,8)|\
|
|
_SHIFTL((level),11,3)|_SHIFTL((tile),8,3)| \
|
|
_SHIFTL((on),0,8)); \
|
|
_g->words.w1 = (_SHIFTL((s),16,16)|_SHIFTL((t),0,16)); \
|
|
}
|
|
# define gsSPTexture(s, t, level, tile, on) \
|
|
{{ \
|
|
(_SHIFTL(G_TEXTURE,24,8)|_SHIFTL(BOWTIE_VAL,16,8)| \
|
|
_SHIFTL((level),11,3)|_SHIFTL((tile),8,3)|_SHIFTL((on),0,8)), \
|
|
(_SHIFTL((s),16,16)|_SHIFTL((t),0,16)) \
|
|
}}
|
|
/*
|
|
* Different version of SPTexture macro, has an additional parameter
|
|
* which is currently reserved in the microcode.
|
|
*/
|
|
# define gSPTextureL(pkt, s, t, level, xparam, tile, on) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
\
|
|
_g->words.w0 = (_SHIFTL(G_TEXTURE,24,8)|_SHIFTL((xparam),16,8)| \
|
|
_SHIFTL((level),11,3)|_SHIFTL((tile),8,3)| \
|
|
_SHIFTL((on),0,8)); \
|
|
_g->words.w1 = (_SHIFTL((s),16,16)|_SHIFTL((t),0,16)); \
|
|
}
|
|
# define gsSPTextureL(s, t, level, xparam, tile, on) \
|
|
{{ \
|
|
(_SHIFTL(G_TEXTURE,24,8)|_SHIFTL((xparam),16,8)| \
|
|
_SHIFTL((level),11,3)|_SHIFTL((tile),8,3)|_SHIFTL((on),0,8)), \
|
|
(_SHIFTL((s),16,16)|_SHIFTL((t),0,16)) \
|
|
}}
|
|
#endif
|
|
|
|
#ifndef F3D_OLD
|
|
# define gSPPerspNormalize(pkt, s) gMoveWd(pkt, G_MW_PERSPNORM, 0, (s))
|
|
# define gsSPPerspNormalize(s) gsMoveWd( G_MW_PERSPNORM, 0, (s))
|
|
#else
|
|
# define gSPPerspNormalize(pkt, s) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
\
|
|
_g->words.w0 = _SHIFTL(G_RDPHALF_1, 24, 8); \
|
|
_g->words.w1 = (s); \
|
|
}
|
|
# define gsSPPerspNormalize(s) \
|
|
{{ \
|
|
_SHIFTL(G_RDPHALF_1, 24, 8), \
|
|
(s) \
|
|
}}
|
|
#endif
|
|
|
|
#ifdef F3DEX_GBI_2
|
|
# define gSPPopMatrixN(pkt, n, num) gDma2p((pkt),G_POPMTX,(num)*64,64,2,0)
|
|
# define gsSPPopMatrixN(n, num) gsDma2p( G_POPMTX,(num)*64,64,2,0)
|
|
# define gSPPopMatrix(pkt, n) gSPPopMatrixN((pkt), (n), 1)
|
|
# define gsSPPopMatrix(n) gsSPPopMatrixN( (n), 1)
|
|
#else /* F3DEX_GBI_2 */
|
|
# define gSPPopMatrix(pkt, n) gImmp1(pkt, G_POPMTX, n)
|
|
# define gsSPPopMatrix(n) gsImmp1( G_POPMTX, n)
|
|
#endif /* F3DEX_GBI_2 */
|
|
|
|
#define gSPEndDisplayList(pkt) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
\
|
|
_g->words.w0 = _SHIFTL(G_ENDDL, 24, 8); \
|
|
_g->words.w1 = 0; \
|
|
}
|
|
|
|
#define gsSPEndDisplayList() \
|
|
{{ \
|
|
_SHIFTL(G_ENDDL, 24, 8), 0 \
|
|
}}
|
|
|
|
#ifdef F3DEX_GBI_2
|
|
/*
|
|
* One gSPGeometryMode(pkt,c,s) GBI is equal to these two GBIs.
|
|
*
|
|
* gSPClearGeometryMode(pkt,c)
|
|
* gSPSetGeometryMode(pkt,s)
|
|
*
|
|
* gSPLoadGeometryMode(pkt, word) sets GeometryMode directly.
|
|
*/
|
|
#define gSPGeometryMode(pkt, c, s) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
_g->words.w0 = _SHIFTL(G_GEOMETRYMODE,24,8)|_SHIFTL(~(u32)(c),0,24);\
|
|
_g->words.w1 = (u32)(s); \
|
|
}
|
|
|
|
#define gsSPGeometryMode(c, s) \
|
|
{{ \
|
|
(_SHIFTL(G_GEOMETRYMODE,24,8)|_SHIFTL(~(u32)(c),0,24)),(u32)(s) \
|
|
}}
|
|
#define gSPSetGeometryMode(pkt, word) gSPGeometryMode((pkt),0,(word))
|
|
#define gsSPSetGeometryMode(word) gsSPGeometryMode(0,(word))
|
|
#define gSPClearGeometryMode(pkt, word) gSPGeometryMode((pkt),(word),0)
|
|
#define gsSPClearGeometryMode(word) gsSPGeometryMode((word),0)
|
|
#define gSPLoadGeometryMode(pkt, word) gSPGeometryMode((pkt),-1,(word))
|
|
#define gsSPLoadGeometryMode(word) gsSPGeometryMode(-1,(word))
|
|
#define gsSPGeometryModeSetFirst(c, s) gsSPGeometryMode(c, s)
|
|
#else /* F3DEX_GBI_2 */
|
|
#define gSPSetGeometryMode(pkt, word) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
\
|
|
_g->words.w0 = _SHIFTL(G_SETGEOMETRYMODE, 24, 8); \
|
|
_g->words.w1 = (unsigned int)(word); \
|
|
}
|
|
|
|
#define gsSPSetGeometryMode(word) \
|
|
{{ \
|
|
_SHIFTL(G_SETGEOMETRYMODE, 24, 8), (unsigned int)(word) \
|
|
}}
|
|
|
|
#define gSPClearGeometryMode(pkt, word) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
\
|
|
_g->words.w0 = _SHIFTL(G_CLEARGEOMETRYMODE, 24, 8); \
|
|
_g->words.w1 = (unsigned int)(word); \
|
|
}
|
|
|
|
#define gsSPClearGeometryMode(word) \
|
|
{{ \
|
|
_SHIFTL(G_CLEARGEOMETRYMODE, 24, 8), (unsigned int)(word) \
|
|
}}
|
|
|
|
/*
|
|
* gsSPGeometryMode
|
|
* In Fast3DEX2 it is better to use this, as the RSP geometry mode
|
|
* is able to be set and cleared in a single command.
|
|
*/
|
|
#define gsSPGeometryMode(c, s) \
|
|
gsSPClearGeometryMode(c), \
|
|
gsSPSetGeometryMode(s)
|
|
#define gsSPGeometryModeSetFirst(c, s) \
|
|
gsSPSetGeometryMode(s), \
|
|
gsSPClearGeometryMode(c)
|
|
#endif /* F3DEX_GBI_2 */
|
|
|
|
#ifdef F3DEX_GBI_2
|
|
#define gSPSetOtherMode(pkt, cmd, sft, len, data) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
_g->words.w0 = (_SHIFTL(cmd,24,8)|_SHIFTL(32-(sft)-(len),8,8)| \
|
|
_SHIFTL((len)-1,0,8)); \
|
|
_g->words.w1 = (unsigned int)(data); \
|
|
}
|
|
|
|
#define gsSPSetOtherMode(cmd, sft, len, data) \
|
|
{{ \
|
|
_SHIFTL(cmd,24,8)|_SHIFTL(32-(sft)-(len),8,8)|_SHIFTL((len)-1,0,8), \
|
|
(unsigned int)(data) \
|
|
}}
|
|
#else
|
|
#define gSPSetOtherMode(pkt, cmd, sft, len, data) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
\
|
|
_g->words.w0 = (_SHIFTL(cmd, 24, 8) | _SHIFTL(sft, 8, 8) | \
|
|
_SHIFTL(len, 0, 8)); \
|
|
_g->words.w1 = (unsigned int)(data); \
|
|
}
|
|
|
|
#define gsSPSetOtherMode(cmd, sft, len, data) \
|
|
{{ \
|
|
_SHIFTL(cmd, 24, 8) | _SHIFTL(sft, 8, 8) | _SHIFTL(len, 0, 8), \
|
|
(unsigned int)(data) \
|
|
}}
|
|
#endif
|
|
|
|
/*
|
|
* RDP setothermode register commands - register shadowed in RSP
|
|
*/
|
|
#define gDPPipelineMode(pkt, mode) \
|
|
gSPSetOtherMode(pkt, G_SETOTHERMODE_H, G_MDSFT_PIPELINE, 1, mode)
|
|
#define gsDPPipelineMode(mode) \
|
|
gsSPSetOtherMode(G_SETOTHERMODE_H, G_MDSFT_PIPELINE, 1, mode)
|
|
|
|
#define gDPSetCycleType(pkt, type) \
|
|
gSPSetOtherMode(pkt, G_SETOTHERMODE_H, G_MDSFT_CYCLETYPE, 2, type)
|
|
#define gsDPSetCycleType(type) \
|
|
gsSPSetOtherMode(G_SETOTHERMODE_H, G_MDSFT_CYCLETYPE, 2, type)
|
|
|
|
#define gDPSetTexturePersp(pkt, type) \
|
|
gSPSetOtherMode(pkt, G_SETOTHERMODE_H, G_MDSFT_TEXTPERSP, 1, type)
|
|
#define gsDPSetTexturePersp(type) \
|
|
gsSPSetOtherMode(G_SETOTHERMODE_H, G_MDSFT_TEXTPERSP, 1, type)
|
|
|
|
#define gDPSetTextureDetail(pkt, type) \
|
|
gSPSetOtherMode(pkt, G_SETOTHERMODE_H, G_MDSFT_TEXTDETAIL, 2, type)
|
|
#define gsDPSetTextureDetail(type) \
|
|
gsSPSetOtherMode(G_SETOTHERMODE_H, G_MDSFT_TEXTDETAIL, 2, type)
|
|
|
|
#define gDPSetTextureLOD(pkt, type) \
|
|
gSPSetOtherMode(pkt, G_SETOTHERMODE_H, G_MDSFT_TEXTLOD, 1, type)
|
|
#define gsDPSetTextureLOD(type) \
|
|
gsSPSetOtherMode(G_SETOTHERMODE_H, G_MDSFT_TEXTLOD, 1, type)
|
|
|
|
#define gDPSetTextureLUT(pkt, type) \
|
|
gSPSetOtherMode(pkt, G_SETOTHERMODE_H, G_MDSFT_TEXTLUT, 2, type)
|
|
#define gsDPSetTextureLUT(type) \
|
|
gsSPSetOtherMode(G_SETOTHERMODE_H, G_MDSFT_TEXTLUT, 2, type)
|
|
|
|
#define gDPSetTextureFilter(pkt, type) \
|
|
gSPSetOtherMode(pkt, G_SETOTHERMODE_H, G_MDSFT_TEXTFILT, 2, type)
|
|
#define gsDPSetTextureFilter(type) \
|
|
gsSPSetOtherMode(G_SETOTHERMODE_H, G_MDSFT_TEXTFILT, 2, type)
|
|
|
|
#define gDPSetTextureConvert(pkt, type) \
|
|
gSPSetOtherMode(pkt, G_SETOTHERMODE_H, G_MDSFT_TEXTCONV, 3, type)
|
|
#define gsDPSetTextureConvert(type) \
|
|
gsSPSetOtherMode(G_SETOTHERMODE_H, G_MDSFT_TEXTCONV, 3, type)
|
|
|
|
#define gDPSetCombineKey(pkt, type) \
|
|
gSPSetOtherMode(pkt, G_SETOTHERMODE_H, G_MDSFT_COMBKEY, 1, type)
|
|
#define gsDPSetCombineKey(type) \
|
|
gsSPSetOtherMode(G_SETOTHERMODE_H, G_MDSFT_COMBKEY, 1, type)
|
|
|
|
#ifndef _HW_VERSION_1
|
|
#define gDPSetColorDither(pkt, mode) \
|
|
gSPSetOtherMode(pkt, G_SETOTHERMODE_H, G_MDSFT_RGBDITHER, 2, mode)
|
|
#define gsDPSetColorDither(mode) \
|
|
gsSPSetOtherMode(G_SETOTHERMODE_H, G_MDSFT_RGBDITHER, 2, mode)
|
|
#else
|
|
#define gDPSetColorDither(pkt, mode) \
|
|
gSPSetOtherMode(pkt, G_SETOTHERMODE_H, G_MDSFT_COLORDITHER, 1, mode)
|
|
#define gsDPSetColorDither(mode) \
|
|
gsSPSetOtherMode(G_SETOTHERMODE_H, G_MDSFT_COLORDITHER, 1, mode)
|
|
#endif
|
|
|
|
#ifndef _HW_VERSION_1
|
|
#define gDPSetAlphaDither(pkt, mode) \
|
|
gSPSetOtherMode(pkt, G_SETOTHERMODE_H, G_MDSFT_ALPHADITHER, 2, mode)
|
|
#define gsDPSetAlphaDither(mode) \
|
|
gsSPSetOtherMode(G_SETOTHERMODE_H, G_MDSFT_ALPHADITHER, 2, mode)
|
|
#endif
|
|
|
|
/* 'blendmask' is not supported anymore.
|
|
* The bits are reserved for future use.
|
|
* Fri May 26 13:45:55 PDT 1995
|
|
*/
|
|
#define gDPSetBlendMask(pkt, mask) gDPNoOp(pkt)
|
|
#define gsDPSetBlendMask(mask) gsDPNoOp()
|
|
|
|
#define gDPSetAlphaCompare(pkt, type) \
|
|
gSPSetOtherMode(pkt, G_SETOTHERMODE_L, G_MDSFT_ALPHACOMPARE, 2, type)
|
|
#define gsDPSetAlphaCompare(type) \
|
|
gsSPSetOtherMode(G_SETOTHERMODE_L, G_MDSFT_ALPHACOMPARE, 2, type)
|
|
|
|
#define gDPSetDepthSource(pkt, src) \
|
|
gSPSetOtherMode(pkt, G_SETOTHERMODE_L, G_MDSFT_ZSRCSEL, 1, src)
|
|
#define gsDPSetDepthSource(src) \
|
|
gsSPSetOtherMode(G_SETOTHERMODE_L, G_MDSFT_ZSRCSEL, 1, src)
|
|
|
|
#define gDPSetRenderMode(pkt, c0, c1) \
|
|
gSPSetOtherMode(pkt, G_SETOTHERMODE_L, G_MDSFT_RENDERMODE, 29, \
|
|
(c0) | (c1))
|
|
#define gsDPSetRenderMode(c0, c1) \
|
|
gsSPSetOtherMode(G_SETOTHERMODE_L, G_MDSFT_RENDERMODE, 29, \
|
|
(c0) | (c1))
|
|
|
|
#define gSetImage(pkt, cmd, fmt, siz, width, i) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
\
|
|
_g->words.w0 = _SHIFTL(cmd, 24, 8) | _SHIFTL(fmt, 21, 3) | \
|
|
_SHIFTL(siz, 19, 2) | _SHIFTL((width)-1, 0, 12); \
|
|
_g->words.w1 = (uintptr_t)(i); \
|
|
}
|
|
|
|
#define gsSetImage(cmd, fmt, siz, width, i) \
|
|
{{ \
|
|
_SHIFTL(cmd, 24, 8) | _SHIFTL(fmt, 21, 3) | \
|
|
_SHIFTL(siz, 19, 2) | _SHIFTL((width)-1, 0, 12), \
|
|
(uintptr_t)(i) \
|
|
}}
|
|
|
|
#define gDPSetColorImage(pkt, f, s, w, i) gSetImage(pkt, G_SETCIMG, f, s, w, i)
|
|
#define gsDPSetColorImage(f, s, w, i) gsSetImage(G_SETCIMG, f, s, w, i)
|
|
|
|
|
|
/* use these for new code */
|
|
#define gDPSetDepthImage(pkt, i) gSetImage(pkt, G_SETZIMG, 0, 0, 1, i)
|
|
#define gsDPSetDepthImage(i) gsSetImage(G_SETZIMG, 0, 0, 1, i)
|
|
/* kept for compatibility */
|
|
#define gDPSetMaskImage(pkt, i) gDPSetDepthImage(pkt, i)
|
|
#define gsDPSetMaskImage(i) gsDPSetDepthImage(i)
|
|
|
|
#define gDPSetTextureImage(pkt, f, s, w, i) gSetImage(pkt, G_SETTIMG, f, s, w, i)
|
|
#define gsDPSetTextureImage(f, s, w, i) gsSetImage(G_SETTIMG, f, s, w, i)
|
|
|
|
/*
|
|
* RDP macros
|
|
*/
|
|
|
|
#define gDPSetCombine(pkt, muxs0, muxs1) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
\
|
|
_g->words.w0 = _SHIFTL(G_SETCOMBINE, 24, 8) | _SHIFTL(muxs0, 0, 24);\
|
|
_g->words.w1 = (unsigned int)(muxs1); \
|
|
}
|
|
|
|
#define gsDPSetCombine(muxs0, muxs1) \
|
|
{{ \
|
|
_SHIFTL(G_SETCOMBINE, 24, 8) | _SHIFTL(muxs0, 0, 24), \
|
|
(unsigned int)(muxs1) \
|
|
}}
|
|
|
|
#define GCCc0w0(saRGB0, mRGB0, saA0, mA0) \
|
|
(_SHIFTL((saRGB0), 20, 4) | _SHIFTL((mRGB0), 15, 5) | \
|
|
_SHIFTL((saA0), 12, 3) | _SHIFTL((mA0), 9, 3))
|
|
|
|
#define GCCc1w0(saRGB1, mRGB1) \
|
|
(_SHIFTL((saRGB1), 5, 4) | _SHIFTL((mRGB1), 0, 5))
|
|
|
|
#define GCCc0w1(sbRGB0, aRGB0, sbA0, aA0) \
|
|
(_SHIFTL((sbRGB0), 28, 4) | _SHIFTL((aRGB0), 15, 3) | \
|
|
_SHIFTL((sbA0), 12, 3) | _SHIFTL((aA0), 9, 3))
|
|
|
|
#define GCCc1w1(sbRGB1, saA1, mA1, aRGB1, sbA1, aA1) \
|
|
(_SHIFTL((sbRGB1), 24, 4) | _SHIFTL((saA1), 21, 3) | \
|
|
_SHIFTL((mA1), 18, 3) | _SHIFTL((aRGB1), 6, 3) | \
|
|
_SHIFTL((sbA1), 3, 3) | _SHIFTL((aA1), 0, 3))
|
|
|
|
#define gDPSetCombineLERP(pkt, a0, b0, c0, d0, Aa0, Ab0, Ac0, Ad0, \
|
|
a1, b1, c1, d1, Aa1, Ab1, Ac1, Ad1) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
\
|
|
_g->words.w0 = _SHIFTL(G_SETCOMBINE, 24, 8) | \
|
|
_SHIFTL(GCCc0w0(G_CCMUX_##a0, G_CCMUX_##c0, \
|
|
G_ACMUX_##Aa0, G_ACMUX_##Ac0) | \
|
|
GCCc1w0(G_CCMUX_##a1, G_CCMUX_##c1), \
|
|
0, 24); \
|
|
_g->words.w1 = (unsigned int)(GCCc0w1(G_CCMUX_##b0, \
|
|
G_CCMUX_##d0, \
|
|
G_ACMUX_##Ab0, \
|
|
G_ACMUX_##Ad0) | \
|
|
GCCc1w1(G_CCMUX_##b1, \
|
|
G_ACMUX_##Aa1, \
|
|
G_ACMUX_##Ac1, \
|
|
G_CCMUX_##d1, \
|
|
G_ACMUX_##Ab1, \
|
|
G_ACMUX_##Ad1)); \
|
|
}
|
|
|
|
#define gsDPSetCombineLERP(a0, b0, c0, d0, Aa0, Ab0, Ac0, Ad0, \
|
|
a1, b1, c1, d1, Aa1, Ab1, Ac1, Ad1) \
|
|
{{ \
|
|
_SHIFTL(G_SETCOMBINE, 24, 8) | \
|
|
_SHIFTL(GCCc0w0(G_CCMUX_##a0, G_CCMUX_##c0, \
|
|
G_ACMUX_##Aa0, G_ACMUX_##Ac0) | \
|
|
GCCc1w0(G_CCMUX_##a1, G_CCMUX_##c1), 0, 24), \
|
|
(unsigned int)(GCCc0w1(G_CCMUX_##b0, G_CCMUX_##d0, \
|
|
G_ACMUX_##Ab0, G_ACMUX_##Ad0) | \
|
|
GCCc1w1(G_CCMUX_##b1, G_ACMUX_##Aa1, \
|
|
G_ACMUX_##Ac1, G_CCMUX_##d1, \
|
|
G_ACMUX_##Ab1, G_ACMUX_##Ad1)) \
|
|
}}
|
|
|
|
/*
|
|
* SetCombineMode macros are NOT redunant. It allow the C preprocessor
|
|
* to substitute single parameter which includes commas in the token and
|
|
* rescan for higher parameter count macro substitution.
|
|
*
|
|
* eg. gsDPSetCombineMode(G_CC_MODULATE, G_CC_MODULATE) turns into
|
|
* gsDPSetCombineLERP(TEXEL0, 0, SHADE, 0, TEXEL0, 0, SHADE, 0,
|
|
* TEXEL0, 0, SHADE, 0, TEXEL0, 0, SHADE, 0)
|
|
*/
|
|
|
|
#define gDPSetCombineMode(pkt, a, b) gDPSetCombineLERP(pkt, a, b)
|
|
#define gsDPSetCombineMode(a, b) gsDPSetCombineLERP(a, b)
|
|
|
|
#define gDPSetColor(pkt, c, d) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
\
|
|
_g->words.w0 = _SHIFTL(c, 24, 8); \
|
|
_g->words.w1 = (unsigned int)(d); \
|
|
}
|
|
|
|
#define gsDPSetColor(c, d) \
|
|
{{ \
|
|
_SHIFTL(c, 24, 8), (unsigned int)(d) \
|
|
}}
|
|
|
|
#define DPRGBColor(pkt, cmd, r, g, b, a) \
|
|
gDPSetColor(pkt, cmd, \
|
|
(_SHIFTL(r, 24, 8) | _SHIFTL(g, 16, 8) | \
|
|
_SHIFTL(b, 8, 8) | _SHIFTL(a, 0, 8)))
|
|
#define sDPRGBColor(cmd, r, g, b, a) \
|
|
gsDPSetColor(cmd, \
|
|
(_SHIFTL(r, 24, 8) | _SHIFTL(g, 16, 8) | \
|
|
_SHIFTL(b, 8, 8) | _SHIFTL(a, 0, 8)))
|
|
|
|
#define gDPSetEnvColor(pkt, r, g, b, a) \
|
|
DPRGBColor(pkt, G_SETENVCOLOR, r,g,b,a)
|
|
#define gsDPSetEnvColor(r, g, b, a) \
|
|
sDPRGBColor(G_SETENVCOLOR, r,g,b,a)
|
|
#define gDPSetBlendColor(pkt, r, g, b, a) \
|
|
DPRGBColor(pkt, G_SETBLENDCOLOR, r,g,b,a)
|
|
#define gsDPSetBlendColor(r, g, b, a) \
|
|
sDPRGBColor(G_SETBLENDCOLOR, r,g,b,a)
|
|
#define gDPSetFogColor(pkt, r, g, b, a) \
|
|
DPRGBColor(pkt, G_SETFOGCOLOR, r,g,b,a)
|
|
#define gsDPSetFogColor(r, g, b, a) \
|
|
sDPRGBColor(G_SETFOGCOLOR, r,g,b,a)
|
|
#define gDPSetFillColor(pkt, d) \
|
|
gDPSetColor(pkt, G_SETFILLCOLOR, (d))
|
|
#define gsDPSetFillColor(d) \
|
|
gsDPSetColor(G_SETFILLCOLOR, (d))
|
|
|
|
#define gDPSetPrimDepth(pkt, z, dz) \
|
|
gDPSetColor(pkt, G_SETPRIMDEPTH, \
|
|
_SHIFTL(z, 16, 16) | _SHIFTL(dz, 0, 16))
|
|
#define gsDPSetPrimDepth(z, dz) \
|
|
gsDPSetColor(G_SETPRIMDEPTH, _SHIFTL(z, 16, 16) | \
|
|
_SHIFTL(dz, 0, 16))
|
|
|
|
#define gDPSetPrimColor(pkt, m, l, r, g, b, a) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
\
|
|
_g->words.w0 = (_SHIFTL(G_SETPRIMCOLOR, 24, 8) | \
|
|
_SHIFTL(m, 8, 8) | _SHIFTL(l, 0, 8)); \
|
|
_g->words.w1 = (_SHIFTL(r, 24, 8) | _SHIFTL(g, 16, 8) | \
|
|
_SHIFTL(b, 8, 8) | _SHIFTL(a, 0, 8)); \
|
|
}
|
|
|
|
#define gsDPSetPrimColor(m, l, r, g, b, a) \
|
|
{{ \
|
|
(_SHIFTL(G_SETPRIMCOLOR, 24, 8) | _SHIFTL(m, 8, 8) | \
|
|
_SHIFTL(l, 0, 8)), \
|
|
(_SHIFTL(r, 24, 8) | _SHIFTL(g, 16, 8) | _SHIFTL(b, 8, 8) | \
|
|
_SHIFTL(a, 0, 8)) \
|
|
}}
|
|
|
|
/*
|
|
* gDPSetOtherMode (This is for expert user.)
|
|
*
|
|
* This command makes all othermode parameters set.
|
|
* Do not use this command in the same DL with another g*SPSetOtherMode DLs.
|
|
*
|
|
* [Usage]
|
|
* gDPSetOtherMode(pkt, modeA, modeB)
|
|
*
|
|
* 'modeA' is described all parameters of GroupA GBI command.
|
|
* 'modeB' is also described all parameters of GroupB GBI command.
|
|
*
|
|
* GroupA:
|
|
* gDPPipelineMode, gDPSetCycleType, gSPSetTexturePersp,
|
|
* gDPSetTextureDetail, gDPSetTextureLOD, gDPSetTextureLUT,
|
|
* gDPSetTextureFilter, gDPSetTextureConvert, gDPSetCombineKey,
|
|
* gDPSetColorDither, gDPSetAlphaDither
|
|
*
|
|
* GroupB:
|
|
* gDPSetAlphaCompare, gDPSetDepthSource, gDPSetRenderMode
|
|
*
|
|
* Use 'OR' operation to get modeA and modeB.
|
|
*
|
|
* modeA = G_PM_* | G_CYC_* | G_TP_* | G_TD_* | G_TL_* | G_TT_* | G_TF_*
|
|
* G_TC_* | G_CK_* | G_CD_* | G_AD_*;
|
|
*
|
|
* modeB = G_AC_* | G_ZS_* | G_RM_* | G_RM_*2;
|
|
*/
|
|
#define gDPSetOtherMode(pkt, mode0, mode1) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
\
|
|
_g->words.w0 = _SHIFTL(G_RDPSETOTHERMODE,24,8)|_SHIFTL(mode0,0,24);\
|
|
_g->words.w1 = (unsigned int)(mode1); \
|
|
}
|
|
|
|
#define gsDPSetOtherMode(mode0, mode1) \
|
|
{{ \
|
|
_SHIFTL(G_RDPSETOTHERMODE,24,8)|_SHIFTL(mode0,0,24), \
|
|
(unsigned int)(mode1) \
|
|
}}
|
|
|
|
/*
|
|
* Texturing macros
|
|
*/
|
|
|
|
/* These are also defined defined above for Sprite Microcode */
|
|
|
|
#define G_TX_LOADTILE 7
|
|
#define G_TX_RENDERTILE 0
|
|
|
|
#define G_TX_NOMIRROR 0
|
|
#define G_TX_WRAP 0
|
|
#define G_TX_MIRROR 0x1
|
|
#define G_TX_CLAMP 0x2
|
|
#define G_TX_NOMASK 0
|
|
#define G_TX_NOLOD 0
|
|
|
|
|
|
#ifndef MAX
|
|
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
|
#endif
|
|
|
|
#ifndef MIN
|
|
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
|
#endif
|
|
|
|
/*
|
|
* Dxt is the inverse of the number of 64-bit words in a line of
|
|
* the texture being loaded using the load_block command. If
|
|
* there are any 1's to the right of the 11th fractional bit,
|
|
* dxt should be rounded up. The following macros accomplish
|
|
* this. The 4b macros are a special case since 4-bit textures
|
|
* are loaded as 8-bit textures. Dxt is fixed point 1.11. RJM
|
|
*/
|
|
#define G_TX_DXT_FRAC 11
|
|
|
|
/*
|
|
* For RCP 2.0, the maximum number of texels that can be loaded
|
|
* using a load_block command is 2048. In order to load the total
|
|
* 4kB of Tmem, change the texel size when loading to be G_IM_SIZ_16b,
|
|
* then change the tile to the proper texel size after the load.
|
|
* The g*DPLoadTextureBlock macros already do this, so this change
|
|
* will be transparent if you use these macros. If you use
|
|
* the g*DPLoadBlock macros directly, you will need to handle this
|
|
* tile manipulation yourself. RJM.
|
|
*/
|
|
#ifdef _HW_VERSION_1
|
|
#define G_TX_LDBLK_MAX_TXL 4095
|
|
#else
|
|
#define G_TX_LDBLK_MAX_TXL 2047
|
|
#endif /* _HW_VERSION_1 */
|
|
|
|
#define TXL2WORDS(txls, b_txl) MAX(1, ((txls)*(b_txl)/8))
|
|
#define CALC_DXT(width, b_txl) \
|
|
(((1 << G_TX_DXT_FRAC) + TXL2WORDS(width, b_txl) - 1) / \
|
|
TXL2WORDS(width, b_txl))
|
|
|
|
#define TXL2WORDS_4b(txls) MAX(1, ((txls)/16))
|
|
#define CALC_DXT_4b(width) \
|
|
(((1 << G_TX_DXT_FRAC) + TXL2WORDS_4b(width) - 1) / \
|
|
TXL2WORDS_4b(width))
|
|
|
|
#define gDPLoadTileGeneric(pkt, c, tile, uls, ult, lrs, lrt) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
\
|
|
_g->words.w0 = _SHIFTL(c, 24, 8) | _SHIFTL(uls, 12, 12) | \
|
|
_SHIFTL(ult, 0, 12); \
|
|
_g->words.w1 = _SHIFTL(tile, 24, 3) | _SHIFTL(lrs, 12, 12) | \
|
|
_SHIFTL(lrt, 0, 12); \
|
|
}
|
|
|
|
#define gsDPLoadTileGeneric(c, tile, uls, ult, lrs, lrt) \
|
|
{{ \
|
|
_SHIFTL(c, 24, 8) | _SHIFTL(uls, 12, 12) | _SHIFTL(ult, 0, 12), \
|
|
_SHIFTL(tile, 24, 3) | _SHIFTL(lrs, 12, 12) | _SHIFTL(lrt, 0, 12)\
|
|
}}
|
|
|
|
#define gDPSetTileSize(pkt, t, uls, ult, lrs, lrt) \
|
|
gDPLoadTileGeneric(pkt, G_SETTILESIZE, t, uls, ult, lrs, lrt)
|
|
#define gsDPSetTileSize(t, uls, ult, lrs, lrt) \
|
|
gsDPLoadTileGeneric(G_SETTILESIZE, t, uls, ult, lrs, lrt)
|
|
#define gDPLoadTile(pkt, t, uls, ult, lrs, lrt) \
|
|
gDPLoadTileGeneric(pkt, G_LOADTILE, t, uls, ult, lrs, lrt)
|
|
#define gsDPLoadTile(t, uls, ult, lrs, lrt) \
|
|
gsDPLoadTileGeneric(G_LOADTILE, t, uls, ult, lrs, lrt)
|
|
|
|
#define gDPSetTile(pkt, fmt, siz, line, tmem, tile, palette, cmt, \
|
|
maskt, shiftt, cms, masks, shifts) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
\
|
|
_g->words.w0 = _SHIFTL(G_SETTILE, 24, 8) | _SHIFTL(fmt, 21, 3) |\
|
|
_SHIFTL(siz, 19, 2) | _SHIFTL(line, 9, 9) | \
|
|
_SHIFTL(tmem, 0, 9); \
|
|
_g->words.w1 = _SHIFTL(tile, 24, 3) | _SHIFTL(palette, 20, 4) | \
|
|
_SHIFTL(cmt, 18, 2) | _SHIFTL(maskt, 14, 4) | \
|
|
_SHIFTL(shiftt, 10, 4) |_SHIFTL(cms, 8, 2) | \
|
|
_SHIFTL(masks, 4, 4) | _SHIFTL(shifts, 0, 4); \
|
|
}
|
|
|
|
#define gsDPSetTile(fmt, siz, line, tmem, tile, palette, cmt, \
|
|
maskt, shiftt, cms, masks, shifts) \
|
|
{{ \
|
|
(_SHIFTL(G_SETTILE, 24, 8) | _SHIFTL(fmt, 21, 3) | \
|
|
_SHIFTL(siz, 19, 2) | _SHIFTL(line, 9, 9) | _SHIFTL(tmem, 0, 9)),\
|
|
(_SHIFTL(tile, 24, 3) | _SHIFTL(palette, 20, 4) | \
|
|
_SHIFTL(cmt, 18, 2) | _SHIFTL(maskt, 14, 4) | \
|
|
_SHIFTL(shiftt, 10, 4) | _SHIFTL(cms, 8, 2) | \
|
|
_SHIFTL(masks, 4, 4) | _SHIFTL(shifts, 0, 4)) \
|
|
}}
|
|
|
|
/*
|
|
* For RCP 2.0, the maximum number of texels that can be loaded
|
|
* using a load_block command is 2048. In order to load the total
|
|
* 4kB of Tmem, change the texel size when loading to be G_IM_SIZ_16b,
|
|
* then change the tile to the proper texel size after the load.
|
|
* The g*DPLoadTextureBlock macros already do this, so this change
|
|
* will be transparent if you use these macros. If you use
|
|
* the g*DPLoadBlock macros directly, you will need to handle this
|
|
* tile manipulation yourself. RJM.
|
|
*/
|
|
#define gDPLoadBlock(pkt, tile, uls, ult, lrs, dxt) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
\
|
|
_g->words.w0 = (_SHIFTL(G_LOADBLOCK, 24, 8) | \
|
|
_SHIFTL(uls, 12, 12) | _SHIFTL(ult, 0, 12)); \
|
|
_g->words.w1 = (_SHIFTL(tile, 24, 3) | \
|
|
_SHIFTL((MIN(lrs,G_TX_LDBLK_MAX_TXL)), 12, 12) |\
|
|
_SHIFTL(dxt, 0, 12)); \
|
|
}
|
|
|
|
#define gsDPLoadBlock(tile, uls, ult, lrs, dxt) \
|
|
{{ \
|
|
(_SHIFTL(G_LOADBLOCK, 24, 8) | _SHIFTL(uls, 12, 12) | \
|
|
_SHIFTL(ult, 0, 12)), \
|
|
(_SHIFTL(tile, 24, 3) | \
|
|
_SHIFTL((MIN(lrs,G_TX_LDBLK_MAX_TXL)), 12, 12) | \
|
|
_SHIFTL(dxt, 0, 12)) \
|
|
}}
|
|
|
|
#define gDPLoadTLUTCmd(pkt, tile, count) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)pkt; \
|
|
\
|
|
_g->words.w0 = _SHIFTL(G_LOADTLUT, 24, 8); \
|
|
_g->words.w1 = _SHIFTL((tile), 24, 3) | _SHIFTL((count), 14, 10);\
|
|
}
|
|
|
|
#define gsDPLoadTLUTCmd(tile, count) \
|
|
{{ \
|
|
_SHIFTL(G_LOADTLUT, 24, 8), \
|
|
_SHIFTL((tile), 24, 3) | _SHIFTL((count), 14, 10) \
|
|
}}
|
|
|
|
#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)); \
|
|
gDPPipeSync(pkt); \
|
|
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) \
|
|
}
|
|
|
|
#define gDPLoadTextureBlockYuv(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)); \
|
|
gDPPipeSync(pkt); \
|
|
gDPSetTile(pkt, fmt, siz, \
|
|
(((width) * 1)+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) \
|
|
}
|
|
|
|
/* Load fix rww 27jun95 */
|
|
/* The S at the end means odd lines are already word Swapped */
|
|
|
|
#define gDPLoadTextureBlockS(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,0); \
|
|
gDPPipeSync(pkt); \
|
|
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) \
|
|
}
|
|
|
|
/*
|
|
* Allow tmem address and render tile to be specified.
|
|
* The S at the end means odd lines are already word Swapped
|
|
*/
|
|
#define gDPLoadMultiBlockS(pkt, timg, tmem, rtile, 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, tmem, 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,0); \
|
|
gDPPipeSync(pkt); \
|
|
gDPSetTile(pkt, fmt, siz, \
|
|
(((width) * siz##_LINE_BYTES)+7)>>3, tmem, \
|
|
rtile, pal, cmt, maskt, shiftt, cms, masks, \
|
|
shifts); \
|
|
gDPSetTileSize(pkt, rtile, 0, 0, \
|
|
((width)-1) << G_TEXTURE_IMAGE_FRAC, \
|
|
((height)-1) << G_TEXTURE_IMAGE_FRAC) \
|
|
}
|
|
|
|
|
|
#define gDPLoadTextureBlockYuvS(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,0); \
|
|
gDPPipeSync(pkt); \
|
|
gDPSetTile(pkt, fmt, siz, \
|
|
(((width) * 1)+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) \
|
|
}
|
|
|
|
/*
|
|
* allows tmem address to be specified
|
|
*/
|
|
#define _gDPLoadTextureBlock(pkt, timg, tmem, 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, tmem, 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)); \
|
|
gDPPipeSync(pkt); \
|
|
gDPSetTile(pkt, fmt, siz, (((width) * siz##_LINE_BYTES)+7)>>3, \
|
|
tmem, 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) \
|
|
}
|
|
|
|
/*
|
|
* allows tmem address and render tile to be specified
|
|
*/
|
|
#define _gDPLoadTextureBlockTile(pkt, timg, tmem, rtile, 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, tmem, 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)); \
|
|
gDPPipeSync(pkt); \
|
|
gDPSetTile(pkt, fmt, siz, (((width) * siz##_LINE_BYTES)+7)>>3, \
|
|
tmem, rtile, pal, cmt, \
|
|
maskt, shiftt, cms, masks, shifts); \
|
|
gDPSetTileSize(pkt, rtile, 0, 0, \
|
|
((width)-1) << G_TEXTURE_IMAGE_FRAC, \
|
|
((height)-1) << G_TEXTURE_IMAGE_FRAC) \
|
|
}
|
|
|
|
/*
|
|
* allows tmem address and render tile to be specified
|
|
*/
|
|
#define gDPLoadMultiBlock(pkt, timg, tmem, rtile, 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, tmem, 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)); \
|
|
gDPPipeSync(pkt); \
|
|
gDPSetTile(pkt, fmt, siz, (((width) * siz##_LINE_BYTES)+7)>>3, \
|
|
tmem, rtile, pal, cmt, \
|
|
maskt, shiftt, cms, masks, shifts); \
|
|
gDPSetTileSize(pkt, rtile, 0, 0, \
|
|
((width)-1) << G_TEXTURE_IMAGE_FRAC, \
|
|
((height)-1) << G_TEXTURE_IMAGE_FRAC) \
|
|
}
|
|
|
|
#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)), \
|
|
gsDPPipeSync(), \
|
|
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)
|
|
|
|
/* Here is the static form of the pre-swapped texture block loading */
|
|
/* See gDPLoadTextureBlockS() for reference. Basically, just don't
|
|
calculate DxT, use 0 */
|
|
|
|
#define gsDPLoadTextureBlockS(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, 0 ),\
|
|
gsDPPipeSync(), \
|
|
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)
|
|
|
|
/*
|
|
* Allow tmem address to be specified
|
|
*/
|
|
#define _gsDPLoadTextureBlock(timg, tmem, fmt, siz, width, height, \
|
|
pal, cms, cmt, masks, maskt, shifts, shiftt) \
|
|
\
|
|
gsDPSetTextureImage(fmt, siz##_LOAD_BLOCK, 1, timg), \
|
|
gsDPSetTile(fmt, siz##_LOAD_BLOCK, 0, tmem, 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)), \
|
|
gsDPPipeSync(), \
|
|
gsDPSetTile(fmt, siz, \
|
|
((((width) * siz##_LINE_BYTES)+7)>>3), tmem, \
|
|
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)
|
|
|
|
|
|
/*
|
|
* Allow tmem address and render_tile to be specified
|
|
*/
|
|
#define _gsDPLoadTextureBlockTile(timg, tmem, rtile, fmt, siz, width, \
|
|
height, pal, cms, cmt, masks, maskt, shifts, shiftt) \
|
|
\
|
|
gsDPSetTextureImage(fmt, siz##_LOAD_BLOCK, 1, timg), \
|
|
gsDPSetTile(fmt, siz##_LOAD_BLOCK, 0, tmem, 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)), \
|
|
gsDPPipeSync(), \
|
|
gsDPSetTile(fmt, siz, \
|
|
((((width) * siz##_LINE_BYTES)+7)>>3), tmem, \
|
|
rtile, pal, cmt, maskt, shiftt, cms, masks, \
|
|
shifts), \
|
|
gsDPSetTileSize(rtile, 0, 0, \
|
|
((width)-1) << G_TEXTURE_IMAGE_FRAC, \
|
|
((height)-1) << G_TEXTURE_IMAGE_FRAC)
|
|
|
|
|
|
/*
|
|
* Allow tmem address and render_tile to be specified, useful when loading
|
|
* mutilple tiles at a time.
|
|
*/
|
|
#define gsDPLoadMultiBlock(timg, tmem, rtile, fmt, siz, width, \
|
|
height, pal, cms, cmt, masks, maskt, shifts, shiftt) \
|
|
\
|
|
gsDPSetTextureImage(fmt, siz##_LOAD_BLOCK, 1, timg), \
|
|
gsDPSetTile(fmt, siz##_LOAD_BLOCK, 0, tmem, 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)), \
|
|
gsDPPipeSync(), \
|
|
gsDPSetTile(fmt, siz, \
|
|
((((width) * siz##_LINE_BYTES)+7)>>3), tmem, \
|
|
rtile, pal, cmt, maskt, shiftt, cms, masks, \
|
|
shifts), \
|
|
gsDPSetTileSize(rtile, 0, 0, \
|
|
((width)-1) << G_TEXTURE_IMAGE_FRAC, \
|
|
((height)-1) << G_TEXTURE_IMAGE_FRAC)
|
|
|
|
/*
|
|
* Allows tmem and render tile to be specified. Useful when loading
|
|
* several tiles at a time.
|
|
*
|
|
* Here is the static form of the pre-swapped texture block loading
|
|
* See gDPLoadTextureBlockS() for reference. Basically, just don't
|
|
* calculate DxT, use 0
|
|
*/
|
|
|
|
#define gsDPLoadMultiBlockS(timg, tmem, rtile, fmt, siz, width, height, \
|
|
pal, cms, cmt, masks, maskt, shifts, shiftt) \
|
|
\
|
|
gsDPSetTextureImage(fmt, siz##_LOAD_BLOCK, 1, timg), \
|
|
gsDPSetTile(fmt, siz##_LOAD_BLOCK, 0, tmem, G_TX_LOADTILE, 0 , \
|
|
cmt, maskt,shiftt, cms, masks, shifts), \
|
|
gsDPLoadSync(), \
|
|
gsDPLoadBlock(G_TX_LOADTILE, 0, 0, \
|
|
(((width)*(height) + siz##_INCR) >> siz##_SHIFT)-1, 0 ),\
|
|
gsDPPipeSync(), \
|
|
gsDPSetTile(fmt, siz, ((((width) * siz##_LINE_BYTES)+7)>>3), tmem,\
|
|
rtile, pal, cmt, maskt, shiftt, cms, masks, \
|
|
shifts), \
|
|
gsDPSetTileSize(rtile, 0, 0, \
|
|
((width)-1) << G_TEXTURE_IMAGE_FRAC, \
|
|
((height)-1) << G_TEXTURE_IMAGE_FRAC)
|
|
|
|
|
|
#define gDPLoadTextureBlock_4b(pkt, timg, fmt, width, height, \
|
|
pal, cms, cmt, masks, maskt, shifts, shiftt) \
|
|
{ \
|
|
gDPSetTextureImage(pkt, fmt, G_IM_SIZ_16b, 1, timg); \
|
|
gDPSetTile(pkt, fmt, G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, 0, \
|
|
cmt, maskt, shiftt, cms, masks, shifts); \
|
|
gDPLoadSync(pkt); \
|
|
gDPLoadBlock(pkt, G_TX_LOADTILE, 0, 0, \
|
|
(((width)*(height)+3)>>2)-1, \
|
|
CALC_DXT_4b(width)); \
|
|
gDPPipeSync(pkt); \
|
|
gDPSetTile(pkt, fmt, G_IM_SIZ_4b, ((((width)>>1)+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) \
|
|
}
|
|
|
|
/* Load fix rww 27jun95 */
|
|
/* The S at the end means odd lines are already word Swapped */
|
|
|
|
#define gDPLoadTextureBlock_4bS(pkt, timg, fmt, width, height, \
|
|
pal, cms, cmt, masks, maskt, shifts, shiftt) \
|
|
{ \
|
|
gDPSetTextureImage(pkt, fmt, G_IM_SIZ_16b, 1, timg); \
|
|
gDPSetTile(pkt, fmt, G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, 0, \
|
|
cmt, maskt, shiftt, cms, masks, shifts); \
|
|
gDPLoadSync(pkt); \
|
|
gDPLoadBlock(pkt, G_TX_LOADTILE, 0, 0, \
|
|
(((width)*(height)+3)>>2)-1, 0 ); \
|
|
gDPPipeSync(pkt); \
|
|
gDPSetTile(pkt, fmt, G_IM_SIZ_4b, ((((width)>>1)+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) \
|
|
}
|
|
|
|
/*
|
|
* 4-bit load block. Useful when loading multiple tiles
|
|
*/
|
|
#define gDPLoadMultiBlock_4b(pkt, timg, tmem, rtile, fmt, width, height,\
|
|
pal, cms, cmt, masks, maskt, shifts, shiftt) \
|
|
{ \
|
|
gDPSetTextureImage(pkt, fmt, G_IM_SIZ_16b, 1, timg); \
|
|
gDPSetTile(pkt, fmt, G_IM_SIZ_16b, 0, tmem, G_TX_LOADTILE, 0, \
|
|
cmt, maskt, shiftt, cms, masks, shifts); \
|
|
gDPLoadSync(pkt); \
|
|
gDPLoadBlock(pkt, G_TX_LOADTILE, 0, 0, \
|
|
(((width)*(height)+3)>>2)-1, \
|
|
CALC_DXT_4b(width)); \
|
|
gDPPipeSync(pkt); \
|
|
gDPSetTile(pkt, fmt, G_IM_SIZ_4b, ((((width)>>1)+7)>>3), tmem, \
|
|
rtile, pal, cmt, maskt, shiftt, cms, masks, \
|
|
shifts); \
|
|
gDPSetTileSize(pkt, rtile, 0, 0, \
|
|
((width)-1) << G_TEXTURE_IMAGE_FRAC, \
|
|
((height)-1) << G_TEXTURE_IMAGE_FRAC) \
|
|
}
|
|
|
|
/*
|
|
* 4-bit load block. Allows tmem and render tile to be specified. Useful when
|
|
* loading multiple tiles. The S means odd lines are already word swapped.
|
|
*/
|
|
#define gDPLoadMultiBlock_4bS(pkt, timg, tmem, rtile, fmt, width, height,\
|
|
pal, cms, cmt, masks, maskt, shifts, shiftt) \
|
|
{ \
|
|
gDPSetTextureImage(pkt, fmt, G_IM_SIZ_16b, 1, timg); \
|
|
gDPSetTile(pkt, fmt, G_IM_SIZ_16b, 0, tmem, G_TX_LOADTILE, 0, \
|
|
cmt, maskt, shiftt, cms, masks, shifts); \
|
|
gDPLoadSync(pkt); \
|
|
gDPLoadBlock(pkt, G_TX_LOADTILE, 0, 0, \
|
|
(((width)*(height)+3)>>2)-1, 0 ); \
|
|
gDPPipeSync(pkt); \
|
|
gDPSetTile(pkt, fmt, G_IM_SIZ_4b, ((((width)>>1)+7)>>3), tmem, \
|
|
rtile, pal, cmt, maskt, shiftt, cms, masks, \
|
|
shifts); \
|
|
gDPSetTileSize(pkt, rtile, 0, 0, \
|
|
((width)-1) << G_TEXTURE_IMAGE_FRAC, \
|
|
((height)-1) << G_TEXTURE_IMAGE_FRAC) \
|
|
}
|
|
|
|
|
|
#define _gDPLoadTextureBlock_4b(pkt, timg, tmem, fmt, width, height, \
|
|
pal, cms, cmt, masks, maskt, shifts, shiftt) \
|
|
{ \
|
|
gDPSetTextureImage(pkt, fmt, G_IM_SIZ_16b, 1, timg); \
|
|
gDPSetTile(pkt, fmt, G_IM_SIZ_16b, 0, tmem, G_TX_LOADTILE, 0, \
|
|
cmt, maskt, shiftt, cms, masks, shifts); \
|
|
gDPLoadSync(pkt); \
|
|
gDPLoadBlock(pkt, G_TX_LOADTILE, 0, 0, \
|
|
(((width)*(height)+3)>>2)-1, \
|
|
CALC_DXT_4b(width)); \
|
|
gDPPipeSync(pkt); \
|
|
gDPSetTile(pkt, fmt, G_IM_SIZ_4b, ((((width)>>1)+7)>>3), tmem, \
|
|
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) \
|
|
}
|
|
|
|
#define gsDPLoadTextureBlock_4b(timg, fmt, width, height, \
|
|
pal, cms, cmt, masks, maskt, shifts, shiftt) \
|
|
\
|
|
gsDPSetTextureImage(fmt, G_IM_SIZ_16b, 1, timg), \
|
|
gsDPSetTile(fmt, G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, 0 , cmt, \
|
|
maskt, shiftt, cms, masks, shifts), \
|
|
gsDPLoadSync(), \
|
|
gsDPLoadBlock(G_TX_LOADTILE, 0, 0, (((width)*(height)+3)>>2)-1, \
|
|
CALC_DXT_4b(width)), \
|
|
gsDPPipeSync(), \
|
|
gsDPSetTile(fmt, G_IM_SIZ_4b, ((((width)>>1)+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)
|
|
|
|
#define gsDPLoadTextureBlock_4bS(timg, fmt, width, height, \
|
|
pal, cms, cmt, masks, maskt, shifts, shiftt) \
|
|
\
|
|
gsDPSetTextureImage(fmt, G_IM_SIZ_16b, 1, timg), \
|
|
gsDPSetTile(fmt, G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, 0 , cmt, \
|
|
maskt, shiftt, cms, masks, shifts), \
|
|
gsDPLoadSync(), \
|
|
gsDPLoadBlock(G_TX_LOADTILE, 0, 0, (((width)*(height)+3)>>2)-1,0),\
|
|
gsDPPipeSync(), \
|
|
gsDPSetTile(fmt, G_IM_SIZ_4b, ((((width)>>1)+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)
|
|
|
|
/*
|
|
* 4-bit load block. Allows tmem address and render tile to be specified.
|
|
* Useful when loading multiple tiles.
|
|
*/
|
|
#define gsDPLoadMultiBlock_4b(timg, tmem, rtile, fmt, width, height, \
|
|
pal, cms, cmt, masks, maskt, shifts, shiftt) \
|
|
\
|
|
gsDPSetTextureImage(fmt, G_IM_SIZ_16b, 1, timg), \
|
|
gsDPSetTile(fmt, G_IM_SIZ_16b, 0, tmem, G_TX_LOADTILE, 0 , cmt, \
|
|
maskt, shiftt, cms, masks, shifts), \
|
|
gsDPLoadSync(), \
|
|
gsDPLoadBlock(G_TX_LOADTILE, 0, 0, (((width)*(height)+3)>>2)-1, \
|
|
CALC_DXT_4b(width)), \
|
|
gsDPPipeSync(), \
|
|
gsDPSetTile(fmt, G_IM_SIZ_4b, ((((width)>>1)+7)>>3), tmem, \
|
|
rtile, pal, cmt, maskt, shiftt, cms, masks, \
|
|
shifts), \
|
|
gsDPSetTileSize(rtile, 0, 0, \
|
|
((width)-1) << G_TEXTURE_IMAGE_FRAC, \
|
|
((height)-1) << G_TEXTURE_IMAGE_FRAC)
|
|
|
|
|
|
/*
|
|
* 4-bit load block. Allows tmem address and render tile to be specified.
|
|
* Useful when loading multiple tiles. S means odd lines are already swapped.
|
|
*/
|
|
#define gsDPLoadMultiBlock_4bS(timg, tmem, rtile, fmt, width, height, \
|
|
pal, cms, cmt, masks, maskt, shifts, shiftt) \
|
|
\
|
|
gsDPSetTextureImage(fmt, G_IM_SIZ_16b, 1, timg), \
|
|
gsDPSetTile(fmt, G_IM_SIZ_16b, 0, tmem, G_TX_LOADTILE, 0 , cmt, \
|
|
maskt, shiftt, cms, masks, shifts), \
|
|
gsDPLoadSync(), \
|
|
gsDPLoadBlock(G_TX_LOADTILE, 0, 0, (((width)*(height)+3)>>2)-1,0),\
|
|
gsDPPipeSync(), \
|
|
gsDPSetTile(fmt, G_IM_SIZ_4b, ((((width)>>1)+7)>>3), tmem, \
|
|
rtile, pal, cmt, maskt, shiftt, cms, masks, \
|
|
shifts), \
|
|
gsDPSetTileSize(rtile, 0, 0, \
|
|
((width)-1) << G_TEXTURE_IMAGE_FRAC, \
|
|
((height)-1) << G_TEXTURE_IMAGE_FRAC)
|
|
|
|
|
|
/*
|
|
* Allows tmem address to be specified
|
|
*/
|
|
#define _gsDPLoadTextureBlock_4b(timg, tmem, fmt, width, height, \
|
|
pal, cms, cmt, masks, maskt, shifts, shiftt) \
|
|
\
|
|
gsDPSetTextureImage(fmt, G_IM_SIZ_16b, 1, timg), \
|
|
gsDPSetTile(fmt, G_IM_SIZ_16b, 0, tmem, G_TX_LOADTILE, 0 , cmt, \
|
|
maskt, shiftt, cms, masks, shifts), \
|
|
gsDPLoadSync(), \
|
|
gsDPLoadBlock(G_TX_LOADTILE, 0, 0, (((width)*(height)+3)>>2)-1, \
|
|
CALC_DXT_4b(width)), \
|
|
gsDPPipeSync(), \
|
|
gsDPSetTile(fmt, G_IM_SIZ_4b, ((((width)>>1)+7)>>3), tmem, \
|
|
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)
|
|
|
|
#ifndef _HW_VERSION_1
|
|
|
|
#define gDPLoadTextureTile(pkt, timg, fmt, siz, width, height, \
|
|
uls, ult, lrs, lrt, pal, \
|
|
cms, cmt, masks, maskt, shifts, shiftt) \
|
|
{ \
|
|
gDPSetTextureImage(pkt, fmt, siz, width, timg); \
|
|
gDPSetTile(pkt, fmt, siz, \
|
|
(((((lrs)-(uls)+1) * siz##_TILE_BYTES)+7)>>3), 0, \
|
|
G_TX_LOADTILE, 0 , cmt, maskt, shiftt, cms, masks, \
|
|
shifts); \
|
|
gDPLoadSync(pkt); \
|
|
gDPLoadTile( pkt, G_TX_LOADTILE, \
|
|
(uls)<<G_TEXTURE_IMAGE_FRAC, \
|
|
(ult)<<G_TEXTURE_IMAGE_FRAC, \
|
|
(lrs)<<G_TEXTURE_IMAGE_FRAC, \
|
|
(lrt)<<G_TEXTURE_IMAGE_FRAC); \
|
|
gDPPipeSync(pkt); \
|
|
gDPSetTile(pkt, fmt, siz, \
|
|
(((((lrs)-(uls)+1) * siz##_LINE_BYTES)+7)>>3), 0, \
|
|
G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks, \
|
|
shifts); \
|
|
gDPSetTileSize(pkt, G_TX_RENDERTILE, \
|
|
(uls)<<G_TEXTURE_IMAGE_FRAC, \
|
|
(ult)<<G_TEXTURE_IMAGE_FRAC, \
|
|
(lrs)<<G_TEXTURE_IMAGE_FRAC, \
|
|
(lrt)<<G_TEXTURE_IMAGE_FRAC) \
|
|
}
|
|
|
|
#else /******** WORKAROUND hw 1 load tile bug ********/
|
|
|
|
#define gDPLoadTextureTile(pkt, timg, fmt, siz, width, height, \
|
|
uls, ult, lrs, lrt, pal, \
|
|
cms, cmt, masks, maskt, shifts, shiftt) \
|
|
\
|
|
{ \
|
|
int _loadtile_i, _loadtile_nw; Gfx *_loadtile_temp = pkt; \
|
|
guDPLoadTextureTile(_loadtile_temp, timg, fmt, siz, \
|
|
width, height, \
|
|
uls, ult, lrs, lrt, pal, \
|
|
cms, cmt, masks, maskt, shifts, shiftt); \
|
|
_loadtile_nw = guGetDPLoadTextureTileSz(ult, lrt) - 1; \
|
|
for(_loadtile_i = 0; _loadtile_i < _loadtile_nw; _loadtile_i++) \
|
|
pkt; \
|
|
}
|
|
|
|
#endif /* HW_VERSION_1 */
|
|
|
|
/*
|
|
* Load texture tile. Allows tmem address and render tile to be specified.
|
|
* Useful for loading multiple tiles.
|
|
*/
|
|
#define gDPLoadMultiTile(pkt, timg, tmem, rtile, fmt, siz, width, height,\
|
|
uls, ult, lrs, lrt, pal, \
|
|
cms, cmt, masks, maskt, shifts, shiftt) \
|
|
{ \
|
|
gDPSetTextureImage(pkt, fmt, siz, width, timg); \
|
|
gDPSetTile(pkt, fmt, siz, \
|
|
(((((lrs)-(uls)+1) * siz##_TILE_BYTES)+7)>>3), tmem, \
|
|
G_TX_LOADTILE, 0 , cmt, maskt, shiftt, cms, masks, \
|
|
shifts); \
|
|
gDPLoadSync(pkt); \
|
|
gDPLoadTile( pkt, G_TX_LOADTILE, \
|
|
(uls)<<G_TEXTURE_IMAGE_FRAC, \
|
|
(ult)<<G_TEXTURE_IMAGE_FRAC, \
|
|
(lrs)<<G_TEXTURE_IMAGE_FRAC, \
|
|
(lrt)<<G_TEXTURE_IMAGE_FRAC); \
|
|
gDPPipeSync(pkt); \
|
|
gDPSetTile(pkt, fmt, siz, \
|
|
(((((lrs)-(uls)+1) * siz##_LINE_BYTES)+7)>>3), tmem, \
|
|
rtile, pal, cmt, maskt, shiftt, cms, masks, \
|
|
shifts); \
|
|
gDPSetTileSize(pkt, rtile, \
|
|
(uls)<<G_TEXTURE_IMAGE_FRAC, \
|
|
(ult)<<G_TEXTURE_IMAGE_FRAC, \
|
|
(lrs)<<G_TEXTURE_IMAGE_FRAC, \
|
|
(lrt)<<G_TEXTURE_IMAGE_FRAC) \
|
|
}
|
|
|
|
|
|
#define gsDPLoadTextureTile(timg, fmt, siz, width, height, \
|
|
uls, ult, lrs, lrt, pal, \
|
|
cms, cmt, masks, maskt, shifts, shiftt) \
|
|
\
|
|
gsDPSetTextureImage(fmt, siz, width, timg), \
|
|
gsDPSetTile(fmt, siz, \
|
|
(((((lrs)-(uls)+1) * siz##_TILE_BYTES)+7)>>3), 0, \
|
|
G_TX_LOADTILE, 0 , cmt, maskt, shiftt, cms, masks, \
|
|
shifts), \
|
|
gsDPLoadSync(), \
|
|
gsDPLoadTile( G_TX_LOADTILE, \
|
|
(uls)<<G_TEXTURE_IMAGE_FRAC, \
|
|
(ult)<<G_TEXTURE_IMAGE_FRAC, \
|
|
(lrs)<<G_TEXTURE_IMAGE_FRAC, \
|
|
(lrt)<<G_TEXTURE_IMAGE_FRAC), \
|
|
gsDPPipeSync(), \
|
|
gsDPSetTile(fmt, siz, \
|
|
(((((lrs)-(uls)+1) * siz##_LINE_BYTES)+7)>>3), 0, \
|
|
G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks,\
|
|
shifts), \
|
|
gsDPSetTileSize(G_TX_RENDERTILE, \
|
|
(uls)<<G_TEXTURE_IMAGE_FRAC, \
|
|
(ult)<<G_TEXTURE_IMAGE_FRAC, \
|
|
(lrs)<<G_TEXTURE_IMAGE_FRAC, \
|
|
(lrt)<<G_TEXTURE_IMAGE_FRAC)
|
|
|
|
/*
|
|
* Load texture tile. Allows tmem address and render tile to be specified.
|
|
* Useful for loading multiple tiles.
|
|
*/
|
|
#define gsDPLoadMultiTile(timg, tmem, rtile, fmt, siz, width, height, \
|
|
uls, ult, lrs, lrt, pal, \
|
|
cms, cmt, masks, maskt, shifts, shiftt) \
|
|
\
|
|
gsDPSetTextureImage(fmt, siz, width, timg), \
|
|
gsDPSetTile(fmt, siz, \
|
|
(((((lrs)-(uls)+1) * siz##_TILE_BYTES)+7)>>3), \
|
|
tmem, G_TX_LOADTILE, 0 , cmt, maskt, shiftt, cms, \
|
|
masks, shifts), \
|
|
gsDPLoadSync(), \
|
|
gsDPLoadTile( G_TX_LOADTILE, \
|
|
(uls)<<G_TEXTURE_IMAGE_FRAC, \
|
|
(ult)<<G_TEXTURE_IMAGE_FRAC, \
|
|
(lrs)<<G_TEXTURE_IMAGE_FRAC, \
|
|
(lrt)<<G_TEXTURE_IMAGE_FRAC), \
|
|
gsDPPipeSync(), \
|
|
gsDPSetTile(fmt, siz, \
|
|
(((((lrs)-(uls)+1) * siz##_LINE_BYTES)+7)>>3), \
|
|
tmem, rtile, pal, cmt, maskt, shiftt, cms, masks, \
|
|
shifts), \
|
|
gsDPSetTileSize(rtile, \
|
|
(uls)<<G_TEXTURE_IMAGE_FRAC, \
|
|
(ult)<<G_TEXTURE_IMAGE_FRAC, \
|
|
(lrs)<<G_TEXTURE_IMAGE_FRAC, \
|
|
(lrt)<<G_TEXTURE_IMAGE_FRAC)
|
|
|
|
#define gDPLoadTextureTile_4b(pkt, timg, fmt, width, height, \
|
|
uls, ult, lrs, lrt, pal, \
|
|
cms, cmt, masks, maskt, shifts, shiftt) \
|
|
{ \
|
|
gDPSetTextureImage(pkt, fmt, G_IM_SIZ_8b, ((width)>>1), timg); \
|
|
gDPSetTile(pkt, fmt, G_IM_SIZ_8b, \
|
|
(((((lrs)-(uls)+1)>>1)+7)>>3), 0, \
|
|
G_TX_LOADTILE, 0 , cmt, maskt, shiftt, cms, masks, \
|
|
shifts); \
|
|
gDPLoadSync(pkt); \
|
|
gDPLoadTile( pkt, G_TX_LOADTILE, \
|
|
(uls)<<(G_TEXTURE_IMAGE_FRAC-1), \
|
|
(ult)<<(G_TEXTURE_IMAGE_FRAC), \
|
|
(lrs)<<(G_TEXTURE_IMAGE_FRAC-1), \
|
|
(lrt)<<(G_TEXTURE_IMAGE_FRAC)); \
|
|
gDPPipeSync(pkt); \
|
|
gDPSetTile(pkt, fmt, G_IM_SIZ_4b, \
|
|
(((((lrs)-(uls)+1)>>1)+7)>>3), 0, \
|
|
G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, \
|
|
masks, shifts); \
|
|
gDPSetTileSize(pkt, G_TX_RENDERTILE, \
|
|
(uls)<<G_TEXTURE_IMAGE_FRAC, \
|
|
(ult)<<G_TEXTURE_IMAGE_FRAC, \
|
|
(lrs)<<G_TEXTURE_IMAGE_FRAC, \
|
|
(lrt)<<G_TEXTURE_IMAGE_FRAC) \
|
|
}
|
|
|
|
/*
|
|
* Load texture tile. Allows tmem address and render tile to be specified.
|
|
* Useful for loading multiple tiles.
|
|
*/
|
|
#define gDPLoadMultiTile_4b(pkt, timg, tmem, rtile, fmt, width, height, \
|
|
uls, ult, lrs, lrt, pal, \
|
|
cms, cmt, masks, maskt, shifts, shiftt) \
|
|
{ \
|
|
gDPSetTextureImage(pkt, fmt, G_IM_SIZ_8b, ((width)>>1), timg); \
|
|
gDPSetTile(pkt, fmt, G_IM_SIZ_8b, \
|
|
(((((lrs)-(uls)+1)>>1)+7)>>3), tmem, \
|
|
G_TX_LOADTILE, 0 , cmt, maskt, shiftt, cms, masks, \
|
|
shifts); \
|
|
gDPLoadSync(pkt); \
|
|
gDPLoadTile( pkt, G_TX_LOADTILE, \
|
|
(uls)<<(G_TEXTURE_IMAGE_FRAC-1), \
|
|
(ult)<<(G_TEXTURE_IMAGE_FRAC), \
|
|
(lrs)<<(G_TEXTURE_IMAGE_FRAC-1), \
|
|
(lrt)<<(G_TEXTURE_IMAGE_FRAC)); \
|
|
gDPPipeSync(pkt); \
|
|
gDPSetTile(pkt, fmt, G_IM_SIZ_4b, \
|
|
(((((lrs)-(uls)+1)>>1)+7)>>3), tmem, \
|
|
rtile, pal, cmt, maskt, shiftt, cms, masks, \
|
|
shifts); \
|
|
gDPSetTileSize(pkt, rtile, \
|
|
(uls)<<G_TEXTURE_IMAGE_FRAC, \
|
|
(ult)<<G_TEXTURE_IMAGE_FRAC, \
|
|
(lrs)<<G_TEXTURE_IMAGE_FRAC, \
|
|
(lrt)<<G_TEXTURE_IMAGE_FRAC) \
|
|
}
|
|
|
|
#define gsDPLoadTextureTile_4b(timg, fmt, width, height, \
|
|
uls, ult, lrs, lrt, pal, \
|
|
cms, cmt, masks, maskt, shifts, shiftt) \
|
|
\
|
|
gsDPSetTextureImage(fmt, G_IM_SIZ_8b, ((width)>>1), timg), \
|
|
gsDPSetTile(fmt, G_IM_SIZ_8b, (((((lrs)-(uls)+1)>>1)+7)>>3), 0, \
|
|
G_TX_LOADTILE, 0 , cmt, maskt, shiftt, cms, masks, \
|
|
shifts), \
|
|
gsDPLoadSync(), \
|
|
gsDPLoadTile( G_TX_LOADTILE, \
|
|
(uls)<<(G_TEXTURE_IMAGE_FRAC-1), \
|
|
(ult)<<(G_TEXTURE_IMAGE_FRAC), \
|
|
(lrs)<<(G_TEXTURE_IMAGE_FRAC-1), \
|
|
(lrt)<<(G_TEXTURE_IMAGE_FRAC)), \
|
|
gsDPPipeSync(), \
|
|
gsDPSetTile(fmt, G_IM_SIZ_4b, (((((lrs)-(uls)+1)>>1)+7)>>3), 0, \
|
|
G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks, \
|
|
shifts), \
|
|
gsDPSetTileSize(G_TX_RENDERTILE, \
|
|
(uls)<<G_TEXTURE_IMAGE_FRAC, \
|
|
(ult)<<G_TEXTURE_IMAGE_FRAC, \
|
|
(lrs)<<G_TEXTURE_IMAGE_FRAC, \
|
|
(lrt)<<G_TEXTURE_IMAGE_FRAC)
|
|
|
|
/*
|
|
* Load texture tile. Allows tmem address and render tile to be specified.
|
|
* Useful for loading multiple tiles.
|
|
*/
|
|
#define gsDPLoadMultiTile_4b(timg, tmem, rtile, fmt, width, height, \
|
|
uls, ult, lrs, lrt, pal, \
|
|
cms, cmt, masks, maskt, shifts, shiftt) \
|
|
\
|
|
gsDPSetTextureImage(fmt, G_IM_SIZ_8b, ((width)>>1), timg), \
|
|
gsDPSetTile(fmt, G_IM_SIZ_8b, (((((lrs)-(uls)+1)>>1)+7)>>3), \
|
|
tmem, G_TX_LOADTILE, 0 , cmt, maskt, shiftt, cms, \
|
|
masks, shifts), \
|
|
gsDPLoadSync(), \
|
|
gsDPLoadTile( G_TX_LOADTILE, \
|
|
(uls)<<(G_TEXTURE_IMAGE_FRAC-1), \
|
|
(ult)<<(G_TEXTURE_IMAGE_FRAC), \
|
|
(lrs)<<(G_TEXTURE_IMAGE_FRAC-1), \
|
|
(lrt)<<(G_TEXTURE_IMAGE_FRAC)), \
|
|
gsDPPipeSync(), \
|
|
gsDPSetTile(fmt, G_IM_SIZ_4b, (((((lrs)-(uls)+1)>>1)+7)>>3), \
|
|
tmem, rtile, pal, cmt, maskt, shiftt, cms, masks, \
|
|
shifts), \
|
|
gsDPSetTileSize(rtile, \
|
|
(uls)<<G_TEXTURE_IMAGE_FRAC, \
|
|
(ult)<<G_TEXTURE_IMAGE_FRAC, \
|
|
(lrs)<<G_TEXTURE_IMAGE_FRAC, \
|
|
(lrt)<<G_TEXTURE_IMAGE_FRAC)
|
|
|
|
/*
|
|
* Load a 16-entry palette (for 4-bit CI textures)
|
|
* Assumes a 16 entry tlut is being loaded, palette # is 0-15
|
|
*/
|
|
#ifndef _HW_VERSION_1
|
|
|
|
#define gDPLoadTLUT_pal16(pkt, pal, dram) \
|
|
{ \
|
|
gDPSetTextureImage(pkt, G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, dram); \
|
|
gDPTileSync(pkt); \
|
|
gDPSetTile(pkt, 0, 0, 0, (256+(((pal)&0xf)*16)), \
|
|
G_TX_LOADTILE, 0 , 0, 0, 0, 0, 0, 0); \
|
|
gDPLoadSync(pkt); \
|
|
gDPLoadTLUTCmd(pkt, G_TX_LOADTILE, 15); \
|
|
gDPPipeSync(pkt) \
|
|
}
|
|
|
|
#else /* **** WORKAROUND hardware 1 load_tlut bug ****** */
|
|
|
|
#define gDPLoadTLUT_pal16(pkt, pal, dram) \
|
|
\
|
|
_gDPLoadTextureBlock(pkt, dram, (256+(((pal)&0xf)*16)), \
|
|
G_IM_FMT_RGBA, G_IM_SIZ_16b, 4*16, 1, \
|
|
pal, 0, 0, 0, 0, 0, 0)
|
|
|
|
#endif /* _HW_VERSION_1 */
|
|
|
|
|
|
/*
|
|
* Load a 16-entry palette (for 4-bit CI textures)
|
|
* Assumes a 16 entry tlut is being loaded, palette # is 0-15
|
|
*/
|
|
#ifndef _HW_VERSION_1
|
|
|
|
#define gsDPLoadTLUT_pal16(pal, dram) \
|
|
\
|
|
gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, dram), \
|
|
gsDPTileSync(), \
|
|
gsDPSetTile(0, 0, 0, (256+(((pal)&0xf)*16)), \
|
|
G_TX_LOADTILE, 0 , 0, 0, 0, 0, 0, 0), \
|
|
gsDPLoadSync(), \
|
|
gsDPLoadTLUTCmd(G_TX_LOADTILE, 15), \
|
|
gsDPPipeSync()
|
|
|
|
#else /* **** WORKAROUND hardware 1 load_tlut bug ****** */
|
|
|
|
#define gsDPLoadTLUT_pal16(pal, dram) \
|
|
\
|
|
_gsDPLoadTextureBlock(dram, (256+(((pal)&0xf)*16)), \
|
|
G_IM_FMT_RGBA, G_IM_SIZ_16b, 4*16, 1, \
|
|
pal, 0, 0, 0, 0, 0, 0)
|
|
|
|
#endif /* _HW_VERSION_1 */
|
|
|
|
/*
|
|
* Load a 256-entry palette (for 8-bit CI textures)
|
|
* Assumes a 256 entry tlut is being loaded, palette # is not used
|
|
*/
|
|
#ifndef _HW_VERSION_1
|
|
|
|
#define gDPLoadTLUT_pal256(pkt, dram) \
|
|
{ \
|
|
gDPSetTextureImage(pkt, G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, dram); \
|
|
gDPTileSync(pkt); \
|
|
gDPSetTile(pkt, 0, 0, 0, 256, \
|
|
G_TX_LOADTILE, 0 , 0, 0, 0, 0, 0, 0); \
|
|
gDPLoadSync(pkt); \
|
|
gDPLoadTLUTCmd(pkt, G_TX_LOADTILE, 255); \
|
|
gDPPipeSync(pkt) \
|
|
}
|
|
|
|
#else /* **** WORKAROUND hardware 1 load_tlut bug ****** */
|
|
|
|
#define gDPLoadTLUT_pal256(pkt, dram) \
|
|
\
|
|
_gDPLoadTextureBlock(pkt, dram, 256, \
|
|
G_IM_FMT_RGBA, G_IM_SIZ_16b, 4*256, 1, \
|
|
0, 0, 0, 0, 0, 0, 0)
|
|
|
|
|
|
#endif /* _HW_VERSION_1 */
|
|
|
|
|
|
#ifndef _HW_VERSION_1
|
|
|
|
#define gsDPLoadTLUT_pal256(dram) \
|
|
\
|
|
gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, dram), \
|
|
gsDPTileSync(), \
|
|
gsDPSetTile(0, 0, 0, 256, \
|
|
G_TX_LOADTILE, 0 , 0, 0, 0, 0, 0, 0), \
|
|
gsDPLoadSync(), \
|
|
gsDPLoadTLUTCmd(G_TX_LOADTILE, 255), \
|
|
gsDPPipeSync()
|
|
|
|
#else /* **** WORKAROUND hardware 1 load_tlut bug ****** */
|
|
|
|
#define gsDPLoadTLUT_pal256(dram) \
|
|
\
|
|
_gsDPLoadTextureBlock(dram, 256, \
|
|
G_IM_FMT_RGBA, G_IM_SIZ_16b, 4*256, 1, \
|
|
0, 0, 0, 0, 0, 0, 0)
|
|
|
|
#endif /* _HW_VERSION_1 */
|
|
|
|
|
|
#ifndef _HW_VERSION_1
|
|
|
|
#define gDPLoadTLUT(pkt, count, tmemaddr, dram) \
|
|
{ \
|
|
gDPSetTextureImage(pkt, G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, dram); \
|
|
gDPTileSync(pkt); \
|
|
gDPSetTile(pkt, 0, 0, 0, tmemaddr, \
|
|
G_TX_LOADTILE, 0 , 0, 0, 0, 0, 0, 0); \
|
|
gDPLoadSync(pkt); \
|
|
gDPLoadTLUTCmd(pkt, G_TX_LOADTILE, ((count)-1)); \
|
|
gDPPipeSync(pkt); \
|
|
}
|
|
|
|
#else /* **** WORKAROUND hardware 1 load_tlut bug ****** */
|
|
|
|
#define gDPLoadTLUT(pkt, count, tmemaddr, dram) \
|
|
\
|
|
_gDPLoadTextureBlock(pkt, dram, tmemaddr, \
|
|
G_IM_FMT_RGBA, G_IM_SIZ_16b, 4, count, \
|
|
0, 0, 0, 0, 0, 0, 0)
|
|
|
|
#endif /* _HW_VERSION_1 */
|
|
|
|
|
|
#ifndef _HW_VERSION_1
|
|
|
|
#define gsDPLoadTLUT(count, tmemaddr, dram) \
|
|
\
|
|
gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, dram), \
|
|
gsDPTileSync(), \
|
|
gsDPSetTile(0, 0, 0, tmemaddr, \
|
|
G_TX_LOADTILE, 0 , 0, 0, 0, 0, 0, 0), \
|
|
gsDPLoadSync(), \
|
|
gsDPLoadTLUTCmd(G_TX_LOADTILE, ((count)-1)), \
|
|
gsDPPipeSync()
|
|
|
|
#else /* **** WORKAROUND hardware 1 load_tlut bug ****** */
|
|
#define gsDPLoadTLUT(count, tmemaddr, dram) \
|
|
\
|
|
_gsDPLoadTextureBlock(dram, tmemaddr, \
|
|
G_IM_FMT_RGBA, G_IM_SIZ_16b, 4, count, \
|
|
0, 0, 0, 0, 0, 0, 0)
|
|
|
|
#endif /* _HW_VERSION_1 */
|
|
|
|
#define gDPSetScissor(pkt, mode, ulx, uly, lrx, lry) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)pkt; \
|
|
\
|
|
_g->words.w0 = _SHIFTL(G_SETSCISSOR, 24, 8) | \
|
|
_SHIFTL((int)((float)(ulx)*4.0F), 12, 12) | \
|
|
_SHIFTL((int)((float)(uly)*4.0F), 0, 12); \
|
|
_g->words.w1 = _SHIFTL(mode, 24, 2) | \
|
|
_SHIFTL((int)((float)(lrx)*4.0F), 12, 12) | \
|
|
_SHIFTL((int)((float)(lry)*4.0F), 0, 12); \
|
|
}
|
|
|
|
|
|
#define gDPSetScissorFrac(pkt, mode, ulx, uly, lrx, lry) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)pkt; \
|
|
\
|
|
_g->words.w0 = _SHIFTL(G_SETSCISSOR, 24, 8) | \
|
|
_SHIFTL((int)((ulx)), 12, 12) | \
|
|
_SHIFTL((int)((uly)), 0, 12); \
|
|
_g->words.w1 = _SHIFTL(mode, 24, 2) | \
|
|
_SHIFTL((int)((lrx)), 12, 12) | \
|
|
_SHIFTL((int)((lry)), 0, 12); \
|
|
}
|
|
|
|
#define gsDPSetScissor(mode, ulx, uly, lrx, lry) \
|
|
{{ \
|
|
_SHIFTL(G_SETSCISSOR, 24, 8) | \
|
|
_SHIFTL((int)((float)(ulx)*4.0F), 12, 12) | \
|
|
_SHIFTL((int)((float)(uly)*4.0F), 0, 12), \
|
|
_SHIFTL(mode, 24, 2) | \
|
|
_SHIFTL((int)((float)(lrx)*4.0F), 12, 12) | \
|
|
_SHIFTL((int)((float)(lry)*4.0F), 0, 12) \
|
|
}}
|
|
|
|
#define gsDPSetScissorFrac(mode, ulx, uly, lrx, lry) \
|
|
{{ \
|
|
_SHIFTL(G_SETSCISSOR, 24, 8) | \
|
|
_SHIFTL((int)((ulx)), 12, 12) | \
|
|
_SHIFTL((int)((uly)), 0, 12), \
|
|
_SHIFTL(mode, 24, 2) | \
|
|
_SHIFTL((int)(lrx), 12, 12) | \
|
|
_SHIFTL((int)(lry), 0, 12) \
|
|
}}
|
|
|
|
/* Fraction never used in fill */
|
|
#ifdef F3DEX_GBI_2E
|
|
#define gDPFillRectangle(pkt, ulx, uly, lrx, lry) \
|
|
{ \
|
|
Gfx *_g0 = (Gfx *)(pkt), *_g1 = (Gfx *)(pkt); \
|
|
_g0->words.w0 = _SHIFTL(G_FILLRECT, 24, 8) | \
|
|
_SHIFTL((lrx), 2, 22); \
|
|
_g0->words.w1 = _SHIFTL((lry), 2, 22); \
|
|
_g1->words.w0 = _SHIFTL((ulx), 2, 22); \
|
|
_g1->words.w1 = _SHIFTL((uly), 2, 22); \
|
|
}
|
|
#define gsDPFillRectangle(ulx, uly, lrx, lry) \
|
|
{{ \
|
|
(_SHIFTL(G_FILLRECT, 24, 8) | _SHIFTL((lrx), 2, 22)), \
|
|
_SHIFTL((lry), 2, 22), \
|
|
}}, \
|
|
{{ \
|
|
_SHIFTL((ulx), 2, 22), \
|
|
_SHIFTL((uly), 2, 22), \
|
|
}}
|
|
#else
|
|
#define gDPFillRectangle(pkt, ulx, uly, lrx, lry) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
\
|
|
_g->words.w0 = (_SHIFTL(G_FILLRECT, 24, 8) | \
|
|
_SHIFTL((lrx), 14, 10) | _SHIFTL((lry), 2, 10));\
|
|
_g->words.w1 = (_SHIFTL((ulx), 14, 10) | _SHIFTL((uly), 2, 10));\
|
|
}
|
|
#define gsDPFillRectangle(ulx, uly, lrx, lry) \
|
|
{{ \
|
|
(_SHIFTL(G_FILLRECT, 24, 8) | _SHIFTL((lrx), 14, 10) | \
|
|
_SHIFTL((lry), 2, 10)), \
|
|
(_SHIFTL((ulx), 14, 10) | _SHIFTL((uly), 2, 10)) \
|
|
}}
|
|
#endif
|
|
|
|
/* like gDPFillRectangle but accepts negative arguments */
|
|
#ifndef F3DEX_GBI_2E
|
|
#define gDPScisFillRectangle(pkt, ulx, uly, lrx, lry) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
\
|
|
_g->words.w0 = (_SHIFTL(G_FILLRECT, 24, 8) | \
|
|
_SHIFTL(MAX((lrx),0), 14, 10) | \
|
|
_SHIFTL(MAX((lry),0), 2, 10)); \
|
|
_g->words.w1 = (_SHIFTL(MAX((ulx),0), 14, 10) | \
|
|
_SHIFTL(MAX((uly),0), 2, 10)); \
|
|
}
|
|
#endif
|
|
|
|
#define gDPSetConvert(pkt, k0, k1, k2, k3, k4, k5) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
\
|
|
_g->words.w0 = (_SHIFTL(G_SETCONVERT, 24, 8) | \
|
|
_SHIFTL(k0, 13, 9) | _SHIFTL(k1, 4, 9) | \
|
|
_SHIFTR(k2, 5, 4)); \
|
|
_g->words.w1 = (_SHIFTL(k2, 27, 5) | _SHIFTL(k3, 18, 9) | \
|
|
_SHIFTL(k4, 9, 9) | _SHIFTL(k5, 0, 9)); \
|
|
}
|
|
|
|
#define gsDPSetConvert(k0, k1, k2, k3, k4, k5) \
|
|
{{ \
|
|
(_SHIFTL(G_SETCONVERT, 24, 8) | \
|
|
_SHIFTL(k0, 13, 9) | _SHIFTL(k1, 4, 9) | _SHIFTR(k2, 5, 4)), \
|
|
(_SHIFTL(k2, 27, 5) | _SHIFTL(k3, 18, 9) | _SHIFTL(k4, 9, 9) | \
|
|
_SHIFTL(k5, 0, 9)) \
|
|
}}
|
|
|
|
#define gDPSetKeyR(pkt, cR, sR, wR) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
\
|
|
_g->words.w0 = _SHIFTL(G_SETKEYR, 24, 8); \
|
|
_g->words.w1 = (_SHIFTL(wR, 16, 12) | _SHIFTL(cR, 8, 8) | \
|
|
_SHIFTL(sR, 0, 8)); \
|
|
}
|
|
|
|
#define gsDPSetKeyR(cR, sR, wR) \
|
|
{{ \
|
|
_SHIFTL(G_SETKEYR, 24, 8), \
|
|
_SHIFTL(wR, 16, 12) | _SHIFTL(cR, 8, 8) | _SHIFTL(sR, 0, 8) \
|
|
}}
|
|
|
|
#define gDPSetKeyGB(pkt, cG, sG, wG, cB, sB, wB) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
\
|
|
_g->words.w0 = (_SHIFTL(G_SETKEYGB, 24, 8) | \
|
|
_SHIFTL(wG, 12, 12) | _SHIFTL(wB, 0, 12)); \
|
|
_g->words.w1 = (_SHIFTL(cG, 24, 8) | _SHIFTL(sG, 16, 8) | \
|
|
_SHIFTL(cB, 8, 8) | _SHIFTL(sB, 0, 8)); \
|
|
}
|
|
|
|
#define gsDPSetKeyGB(cG, sG, wG, cB, sB, wB) \
|
|
{{ \
|
|
(_SHIFTL(G_SETKEYGB, 24, 8) | _SHIFTL(wG, 12, 12) | \
|
|
_SHIFTL(wB, 0, 12)), \
|
|
(_SHIFTL(cG, 24, 8) | _SHIFTL(sG, 16, 8) | _SHIFTL(cB, 8, 8) | \
|
|
_SHIFTL(sB, 0, 8)) \
|
|
}}
|
|
|
|
#define gDPNoParam(pkt, cmd) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
\
|
|
_g->words.w0 = _SHIFTL(cmd, 24, 8); \
|
|
_g->words.w1 = 0; \
|
|
}
|
|
|
|
#define gsDPNoParam(cmd) \
|
|
{{ \
|
|
_SHIFTL(cmd, 24, 8), 0 \
|
|
}}
|
|
|
|
#define gDPParam(pkt, cmd, param) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
\
|
|
_g->words.w0 = _SHIFTL(cmd, 24, 8); \
|
|
_g->words.w1 = (param); \
|
|
}
|
|
|
|
#define gsDPParam(cmd, param) \
|
|
{{ \
|
|
_SHIFTL(cmd, 24, 8), (param) \
|
|
}}
|
|
|
|
/* Notice that textured rectangles are 128-bit commands, therefore
|
|
* gsDPTextureRectangle() should not be used in display lists
|
|
* under normal circumstances (use gsSPTextureRectangle()).
|
|
* That is also why there is no gDPTextureRectangle() macros.
|
|
*/
|
|
#define gsDPTextureRectangle(xl, yl, xh, yh, tile, s, t, dsdx, dtdy) \
|
|
{{ \
|
|
(_SHIFTL(G_TEXRECT, 24, 8) | _SHIFTL(xh, 12, 12) | \
|
|
_SHIFTL(yh, 0, 12)), \
|
|
(_SHIFTL(tile, 24, 3) | _SHIFTL(xl, 12, 12) | _SHIFTL(yl, 0, 12)), \
|
|
}}, \
|
|
{{ \
|
|
_SHIFTL(s, 16, 16) | _SHIFTL(t, 0, 16), \
|
|
_SHIFTL(dsdx, 16, 16) | _SHIFTL(dtdy, 0, 16) \
|
|
}}
|
|
|
|
#define gDPTextureRectangle(pkt, xl, yl, xh, yh, tile, s, t, dsdx, dtdy)\
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
if (pkt); \
|
|
_g->words.w0 = (_SHIFTL(G_TEXRECT, 24, 8) | _SHIFTL(xh, 12, 12) | \
|
|
_SHIFTL(yh, 0, 12)); \
|
|
_g->words.w1 = (_SHIFTL(tile, 24, 3) | _SHIFTL(xl, 12, 12) | \
|
|
_SHIFTL(yl, 0, 12)); \
|
|
_g ++; \
|
|
_g->words.w0 = (_SHIFTL(s, 16, 16) | _SHIFTL(t, 0, 16)); \
|
|
_g->words.w1 = (_SHIFTL(dsdx, 16, 16) | _SHIFTL(dtdy, 0, 16)); \
|
|
}
|
|
|
|
#define gsDPTextureRectangleFlip(xl, yl, xh, yh, tile, s, t, dsdx, dtdy) \
|
|
{{ \
|
|
(_SHIFTL(G_TEXRECTFLIP, 24, 8) | _SHIFTL(xh, 12, 12) | \
|
|
_SHIFTL(yh, 0, 12)), \
|
|
(_SHIFTL(tile, 24, 3) | _SHIFTL(xl, 12, 12) | _SHIFTL(yl, 0, 12)), \
|
|
}}, \
|
|
{{ \
|
|
_SHIFTL(s, 16, 16) | _SHIFTL(t, 0, 16), \
|
|
_SHIFTL(dsdx, 16, 16) | _SHIFTL(dtdy, 0, 16) \
|
|
}}
|
|
|
|
#define gDPTextureRectangleFlip(pkt, xl, yl, xh, yh, tile, s, t, dsdx, dtdy)\
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
if (pkt); \
|
|
_g->words.w0 = (_SHIFTL(G_TEXRECTFLIP, 24, 8) | _SHIFTL(xh, 12, 12) | \
|
|
_SHIFTL(yh, 0, 12)); \
|
|
_g->words.w1 = (_SHIFTL(tile, 24, 3) | _SHIFTL(xl, 12, 12) | \
|
|
_SHIFTL(yl, 0, 12)); \
|
|
_g ++; \
|
|
_g->words.w0 = (_SHIFTL(s, 16, 16) | _SHIFTL(t, 0, 16)); \
|
|
_g->words.w1 = (_SHIFTL(dsdx, 16, 16) | _SHIFTL(dtdy, 0, 16)); \
|
|
}
|
|
|
|
#ifdef F3D_OLD
|
|
# define gSPTextureRectangle(pkt, xl, yl, xh, yh, tile, s, t, dsdx, dtdy)\
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
\
|
|
_g->words.w0 = (_SHIFTL(G_TEXRECT, 24, 8) | _SHIFTL(xh, 12, 12) | \
|
|
_SHIFTL(yh, 0, 12)); \
|
|
_g->words.w1 = (_SHIFTL(tile, 24, 3) | _SHIFTL(xl, 12, 12) | \
|
|
_SHIFTL(yl, 0, 12)); \
|
|
gImmp1(pkt, G_RDPHALF_2, (_SHIFTL(s, 16, 16) | _SHIFTL(t, 0, 16))); \
|
|
gImmp1(pkt, G_RDPHALF_CONT, (_SHIFTL(dsdx, 16, 16) | _SHIFTL(dtdy, 0, 16)));\
|
|
}
|
|
|
|
#define gsSPTextureRectangle(xl, yl, xh, yh, tile, s, t, dsdx, dtdy) \
|
|
{{(_SHIFTL(G_TEXRECT, 24, 8) | _SHIFTL(xh, 12, 12) | _SHIFTL(yh, 0, 12)),\
|
|
(_SHIFTL(tile, 24, 3) | _SHIFTL(xl, 12, 12) | _SHIFTL(yl, 0, 12))}}, \
|
|
gsImmp1(G_RDPHALF_2, (_SHIFTL(s, 16, 16) | _SHIFTL(t, 0, 16))), \
|
|
gsImmp1(G_RDPHALF_CONT, (_SHIFTL(dsdx, 16, 16) | _SHIFTL(dtdy, 0, 16)))
|
|
|
|
/* like gSPTextureRectangle but accepts negative position arguments */
|
|
# define gSPScisTextureRectangle(pkt, xl, yl, xh, yh, tile, s, t, dsdx, dtdy) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
\
|
|
_g->words.w0 = (_SHIFTL(G_TEXRECT, 24, 8) | \
|
|
_SHIFTL(MAX((s16)(xh),0), 12, 12) | \
|
|
_SHIFTL(MAX((s16)(yh),0), 0, 12)); \
|
|
_g->words.w1 = (_SHIFTL((tile), 24, 3) | \
|
|
_SHIFTL(MAX((s16)(xl),0), 12, 12) | \
|
|
_SHIFTL(MAX((s16)(yl),0), 0, 12)); \
|
|
gImmp1(pkt, G_RDPHALF_2, \
|
|
(_SHIFTL(((s) - \
|
|
(((s16)(xl) < 0) ? \
|
|
(((s16)(dsdx) < 0) ? \
|
|
(MAX((((s16)(xl)*(s16)(dsdx))>>7),0)) : \
|
|
(MIN((((s16)(xl)*(s16)(dsdx))>>7),0))) : 0)), \
|
|
16, 16) | \
|
|
_SHIFTL(((t) - \
|
|
(((yl) < 0) ? \
|
|
(((s16)(dtdy) < 0) ? \
|
|
(MAX((((s16)(yl)*(s16)(dtdy))>>7),0)) : \
|
|
(MIN((((s16)(yl)*(s16)(dtdy))>>7),0))) : 0)), \
|
|
0, 16))); \
|
|
gImmp1(pkt, G_RDPHALF_CONT, (_SHIFTL((dsdx), 16, 16) | \
|
|
_SHIFTL((dtdy), 0, 16))); \
|
|
}
|
|
|
|
# define gsSPTextureRectangleFlip(xl, yl, xh, yh, tile, s, t, dsdx, dtdy) \
|
|
{{(_SHIFTL(G_TEXRECTFLIP, 24, 8) | _SHIFTL(xh, 12, 12) | \
|
|
_SHIFTL(yh, 0, 12)), \
|
|
(_SHIFTL(tile, 24, 3) | _SHIFTL(xl, 12, 12) | _SHIFTL(yl, 0, 12))}}, \
|
|
gsImmp1(G_RDPHALF_2, (_SHIFTL(s, 16, 16) | _SHIFTL(t, 0, 16))), \
|
|
gsImmp1(G_RDPHALF_CONT, (_SHIFTL(dsdx, 16, 16) | _SHIFTL(dtdy, 0, 16)))
|
|
|
|
# define gSPTextureRectangleFlip(pkt, xl, yl, xh, yh, tile, s, t, dsdx, dtdy) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
\
|
|
_g->words.w0 = (_SHIFTL(G_TEXRECTFLIP, 24, 8) | _SHIFTL(xh, 12, 12) |\
|
|
_SHIFTL(yh, 0, 12)); \
|
|
_g->words.w1 = (_SHIFTL(tile, 24, 3) | _SHIFTL(xl, 12, 12) | \
|
|
_SHIFTL(yl, 0, 12)); \
|
|
gImmp1(pkt, G_RDPHALF_2, (_SHIFTL(s, 16, 16) | _SHIFTL(t, 0, 16))); \
|
|
gImmp1(pkt, G_RDPHALF_CONT, (_SHIFTL(dsdx, 16, 16) | _SHIFTL(dtdy, 0, 16))); \
|
|
}
|
|
#elif defined(F3DEX_GBI_2E)
|
|
# define gSPTextureRectangle(pkt, xl, yl, xh, yh, tile, s, t, dsdx, dtdy)\
|
|
{ \
|
|
Gfx *_g0 = (Gfx *)(pkt), *_g1 = (Gfx *)(pkt), *_g2 = (Gfx *)(pkt); \
|
|
\
|
|
_g0->words.w0 = _SHIFTL(G_TEXRECT, 24, 8) | \
|
|
_SHIFTL((xh), 0, 24); \
|
|
_g0->words.w1 = _SHIFTL((yh), 0, 24); \
|
|
_g1->words.w0 = (_SHIFTL(tile, 24, 3) | _SHIFTL((xl), 0, 24)); \
|
|
_g1->words.w1 = _SHIFTL((yl), 0, 24); \
|
|
_g2->words.w0 = (_SHIFTL(s, 16, 16) | _SHIFTL(t, 0, 16)); \
|
|
_g2->words.w1 = (_SHIFTL(dsdx, 16, 16) | _SHIFTL(dtdy, 0, 16)); \
|
|
}
|
|
|
|
# define gsSPTextureRectangle(xl, yl, xh, yh, tile, s, t, dsdx, dtdy) \
|
|
{{ \
|
|
(_SHIFTL(G_TEXRECT, 24, 8) | _SHIFTL((xh), 0, 24)), \
|
|
_SHIFTL((yh), 0, 24), \
|
|
}}, \
|
|
{{ \
|
|
(_SHIFTL((tile), 24, 3) | _SHIFTL((xl), 0, 24)), \
|
|
_SHIFTL((yl), 0, 24), \
|
|
}}, \
|
|
{{ \
|
|
_SHIFTL(s, 16, 16) | _SHIFTL(t, 0, 16), \
|
|
_SHIFTL(dsdx, 16, 16) | _SHIFTL(dtdy, 0, 16) \
|
|
}}
|
|
|
|
# define gSPTextureRectangleFlip(pkt, xl, yl, xh, yh, tile, s, t, dsdx, dtdy) \
|
|
{ \
|
|
Gfx *_g0 = (Gfx *)(pkt), *_g1 = (Gfx *)(pkt), *_g2 = (Gfx *)(pkt); \
|
|
\
|
|
_g0->words.w0 = _SHIFTL(G_TEXRECTFLIP, 24, 8) | \
|
|
_SHIFTL((xh), 0, 24); \
|
|
_g0->words.w1 = _SHIFTL((yh), 0, 24); \
|
|
_g1->words.w0 = (_SHIFTL(tile, 24, 3) | _SHIFTL((xl), 0, 24)); \
|
|
_g1->words.w1 = _SHIFTL((yl), 0, 24); \
|
|
_g2->words.w0 = (_SHIFTL(s, 16, 16) | _SHIFTL(t, 0, 16)); \
|
|
_g2->words.w1 = (_SHIFTL(dsdx, 16, 16) | _SHIFTL(dtdy, 0, 16)); \
|
|
}
|
|
#else
|
|
# define gSPTextureRectangle(pkt, xl, yl, xh, yh, tile, s, t, dsdx, dtdy)\
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
\
|
|
_g->words.w0 = (_SHIFTL(G_TEXRECT, 24, 8) | _SHIFTL(xh, 12, 12) | \
|
|
_SHIFTL(yh, 0, 12)); \
|
|
_g->words.w1 = (_SHIFTL(tile, 24, 3) | _SHIFTL(xl, 12, 12) | \
|
|
_SHIFTL(yl, 0, 12)); \
|
|
gImmp1(pkt, G_RDPHALF_1, (_SHIFTL(s, 16, 16) | _SHIFTL(t, 0, 16))); \
|
|
gImmp1(pkt, G_RDPHALF_2, (_SHIFTL(dsdx, 16, 16) | _SHIFTL(dtdy, 0, 16)));\
|
|
}
|
|
|
|
#define gsSPTextureRectangle(xl, yl, xh, yh, tile, s, t, dsdx, dtdy) \
|
|
{{(_SHIFTL(G_TEXRECT, 24, 8) | _SHIFTL(xh, 12, 12) | _SHIFTL(yh, 0, 12)),\
|
|
(_SHIFTL(tile, 24, 3) | _SHIFTL(xl, 12, 12) | _SHIFTL(yl, 0, 12))}}, \
|
|
gsImmp1(G_RDPHALF_1, (_SHIFTL(s, 16, 16) | _SHIFTL(t, 0, 16))), \
|
|
gsImmp1(G_RDPHALF_2, (_SHIFTL(dsdx, 16, 16) | _SHIFTL(dtdy, 0, 16)))
|
|
|
|
/* like gSPTextureRectangle but accepts negative position arguments */
|
|
# define gSPScisTextureRectangle(pkt, xl, yl, xh, yh, tile, s, t, dsdx, dtdy) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
\
|
|
_g->words.w0 = (_SHIFTL(G_TEXRECT, 24, 8) | \
|
|
_SHIFTL(MAX((s16)(xh),0), 12, 12) | \
|
|
_SHIFTL(MAX((s16)(yh),0), 0, 12)); \
|
|
_g->words.w1 = (_SHIFTL((tile), 24, 3) | \
|
|
_SHIFTL(MAX((s16)(xl),0), 12, 12) | \
|
|
_SHIFTL(MAX((s16)(yl),0), 0, 12)); \
|
|
gImmp1(pkt, G_RDPHALF_1, \
|
|
(_SHIFTL(((s) - \
|
|
(((s16)(xl) < 0) ? \
|
|
(((s16)(dsdx) < 0) ? \
|
|
(MAX((((s16)(xl)*(s16)(dsdx))>>7),0)) : \
|
|
(MIN((((s16)(xl)*(s16)(dsdx))>>7),0))) : 0)), \
|
|
16, 16) | \
|
|
_SHIFTL(((t) - \
|
|
(((yl) < 0) ? \
|
|
(((s16)(dtdy) < 0) ? \
|
|
(MAX((((s16)(yl)*(s16)(dtdy))>>7),0)) : \
|
|
(MIN((((s16)(yl)*(s16)(dtdy))>>7),0))) : 0)), \
|
|
0, 16))); \
|
|
gImmp1(pkt, G_RDPHALF_2, (_SHIFTL((dsdx), 16, 16) | \
|
|
_SHIFTL((dtdy), 0, 16))); \
|
|
}
|
|
|
|
# define gsSPTextureRectangleFlip(xl, yl, xh, yh, tile, s, t, dsdx, dtdy) \
|
|
{{(_SHIFTL(G_TEXRECTFLIP, 24, 8) | _SHIFTL(xh, 12, 12) | \
|
|
_SHIFTL(yh, 0, 12)), \
|
|
(_SHIFTL(tile, 24, 3) | _SHIFTL(xl, 12, 12) | _SHIFTL(yl, 0, 12))}}, \
|
|
gsImmp1(G_RDPHALF_1, (_SHIFTL(s, 16, 16) | _SHIFTL(t, 0, 16))), \
|
|
gsImmp1(G_RDPHALF_2, (_SHIFTL(dsdx, 16, 16) | _SHIFTL(dtdy, 0, 16)))
|
|
|
|
# define gSPTextureRectangleFlip(pkt, xl, yl, xh, yh, tile, s, t, dsdx, dtdy) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
\
|
|
_g->words.w0 = (_SHIFTL(G_TEXRECTFLIP, 24, 8) | _SHIFTL(xh, 12, 12) |\
|
|
_SHIFTL(yh, 0, 12)); \
|
|
_g->words.w1 = (_SHIFTL(tile, 24, 3) | _SHIFTL(xl, 12, 12) | \
|
|
_SHIFTL(yl, 0, 12)); \
|
|
gImmp1(pkt, G_RDPHALF_1, (_SHIFTL(s, 16, 16) | _SHIFTL(t, 0, 16))); \
|
|
gImmp1(pkt, G_RDPHALF_2, (_SHIFTL(dsdx, 16, 16) | _SHIFTL(dtdy, 0, 16))); \
|
|
}
|
|
#endif
|
|
|
|
#define gsDPWord(wordhi, wordlo) \
|
|
gsImmp1(G_RDPHALF_1, (uintptr_t)(wordhi)), \
|
|
gsImmp1(G_RDPHALF_2, (uintptr_t)(wordlo))
|
|
|
|
#define gDPWord(pkt, wordhi, wordlo) \
|
|
{ \
|
|
Gfx *_g = (Gfx *)(pkt); \
|
|
\
|
|
gImmp1(pkt, G_RDPHALF_1, (uintptr_t)(wordhi)); \
|
|
gImmp1(pkt, G_RDPHALF_2, (uintptr_t)(wordlo)); \
|
|
}
|
|
|
|
#define gDPFullSync(pkt) gDPNoParam(pkt, G_RDPFULLSYNC)
|
|
#define gsDPFullSync() gsDPNoParam(G_RDPFULLSYNC)
|
|
#define gDPTileSync(pkt) gDPNoParam(pkt, G_RDPTILESYNC)
|
|
#define gsDPTileSync() gsDPNoParam(G_RDPTILESYNC)
|
|
#define gDPPipeSync(pkt) gDPNoParam(pkt, G_RDPPIPESYNC)
|
|
#define gsDPPipeSync() gsDPNoParam(G_RDPPIPESYNC)
|
|
#define gDPLoadSync(pkt) gDPNoParam(pkt, G_RDPLOADSYNC)
|
|
#define gsDPLoadSync() gsDPNoParam(G_RDPLOADSYNC)
|
|
#define gDPNoOp(pkt) gDPNoParam(pkt, G_NOOP)
|
|
#define gsDPNoOp() gsDPNoParam(G_NOOP)
|
|
#define gDPNoOpTag(pkt, tag) gDPParam(pkt, G_NOOP, tag)
|
|
#define gsDPNoOpTag(tag) gsDPParam(G_NOOP, tag)
|
|
|
|
#endif /* _LANGUAGE_C */
|
|
|
|
|
|
#endif /* _GBI_H_ */
|