mirror of
https://github.com/thug1src/thug.git
synced 2025-01-22 05:43:47 +00:00
4824 lines
149 KiB
C++
4824 lines
149 KiB
C++
/********************************************************************************
|
|
* *
|
|
* Module: *
|
|
* NsGX *
|
|
* Description: *
|
|
* GXs matrices. *
|
|
* Written by: *
|
|
* Paul Robinson *
|
|
* Copyright: *
|
|
* 2001 Neversoft Entertainment - All rights reserved. *
|
|
* *
|
|
********************************************************************************/
|
|
|
|
/********************************************************************************
|
|
* Includes. *
|
|
********************************************************************************/
|
|
|
|
#undef __GX_H__
|
|
|
|
#ifdef __PLAT_WN32__
|
|
|
|
#include <memory.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <math.h>
|
|
#include <assert.h>
|
|
#include <Strip/Strip.h>
|
|
#include <GC/GameCubeConv.h>
|
|
//#include <List/Search.h>
|
|
//#include <Util.h>
|
|
#include <Misc/GenCRC.h>
|
|
#include <windows.h>
|
|
|
|
#include "Utility.h"
|
|
|
|
#endif // __PLAT_WN32__
|
|
|
|
#ifndef __PLAT_WN32__
|
|
#define __NO_DEFS__
|
|
#endif // __PLAT_WN32__
|
|
|
|
#include <dolphin\gd.h>
|
|
#include "p_GX.h"
|
|
|
|
#ifndef __PLAT_WN32__
|
|
#include <gfx\ngc\nx\render.h>
|
|
#endif // __PLAT_WN32__
|
|
|
|
int g_mat_passes = 4;
|
|
|
|
namespace GX
|
|
{
|
|
|
|
/********************************************************************************
|
|
* Defines. *
|
|
********************************************************************************/
|
|
|
|
#define TEV_KSEL_MASK_KCSEL \
|
|
(( 0x00001F << TEV_KSEL_KCSEL0_SHIFT ) | \
|
|
( 0x00001F << TEV_KSEL_KASEL0_SHIFT ) | \
|
|
( 0x00001F << TEV_KSEL_KCSEL1_SHIFT ) | \
|
|
( 0x00001F << TEV_KSEL_KASEL1_SHIFT ))
|
|
|
|
/********************************************************************************
|
|
* Structures. *
|
|
********************************************************************************/
|
|
|
|
/********************************************************************************
|
|
* Types. *
|
|
********************************************************************************/
|
|
|
|
typedef void (*_write_u8 )( u8 data );
|
|
typedef void (*_write_s8 )( s8 data );
|
|
typedef void (*_write_u16 )( u16 data );
|
|
typedef void (*_write_s16 )( s16 data );
|
|
typedef void (*_write_u32 )( u32 data );
|
|
typedef void (*_write_s32 )( s32 data );
|
|
typedef void (*_write_f32 )( f32 data );
|
|
typedef void (*_write_u24 )( u32 data );
|
|
|
|
typedef void (*_write_BPCmd )( u32 regval );
|
|
typedef void (*_write_CPCmd )( u8 addr, u32 val );
|
|
typedef void (*_write_XFCmd )( u16 addr, u32 val );
|
|
typedef void (*_write_XFCmdHdr )( u16 addr, u8 len );
|
|
typedef void (*_write_XFIndxACmd )( u16 addr, u8 len, u16 index );
|
|
typedef void (*_write_XFIndxBCmd )( u16 addr, u8 len, u16 index );
|
|
typedef void (*_write_XFIndxCCmd )( u16 addr, u8 len, u16 index );
|
|
typedef void (*_write_XFIndxDCmd )( u16 addr, u8 len, u16 index );
|
|
|
|
/********************************************************************************
|
|
* Local variables. *
|
|
********************************************************************************/
|
|
|
|
GDLObj g_dl;
|
|
//float g_projection[7];
|
|
|
|
u32 MyTmemRegions[8][2] = {
|
|
// TMEM LO, TMEM HI
|
|
{ 0x00000, 0x80000 }, // (default assignment for texmap 0)
|
|
{ 0x08000, 0x88000 }, // 1
|
|
{ 0x10000, 0x90000 }, // 2
|
|
{ 0x18000, 0x98000 }, // 3
|
|
{ 0x20000, 0xa0000 }, // 4
|
|
{ 0x28000, 0xa8000 }, // 5
|
|
{ 0x30000, 0xb0000 }, // 6
|
|
{ 0x38000, 0xb8000 } // 7
|
|
};
|
|
int tmem_count = 0;
|
|
int tlut_count = 0;
|
|
|
|
typedef enum
|
|
{
|
|
USE_DIRECT = 0,
|
|
USE_DL,
|
|
|
|
USE_MAX
|
|
} USE;
|
|
|
|
USE g_use = USE_MAX; // Currently set usage.
|
|
|
|
static _write_u8 _u8 = NULL;
|
|
static _write_s8 _s8 = NULL;
|
|
static _write_u16 _u16 = NULL;
|
|
static _write_s16 _s16 = NULL;
|
|
static _write_u32 _u32 = NULL;
|
|
static _write_s32 _s32 = NULL;
|
|
static _write_f32 _f32 = NULL;
|
|
static _write_u24 _u24 = NULL;
|
|
|
|
static _write_BPCmd _BPCmd = NULL;
|
|
static _write_CPCmd _CPCmd = NULL;
|
|
static _write_XFCmd _XFCmd = NULL;
|
|
static _write_XFCmdHdr _XFCmdHdr = NULL;
|
|
static _write_XFIndxACmd _XFIndxACmd = NULL;
|
|
static _write_XFIndxBCmd _XFIndxBCmd = NULL;
|
|
static _write_XFIndxCCmd _XFIndxCCmd = NULL;
|
|
static _write_XFIndxDCmd _XFIndxDCmd = NULL;
|
|
|
|
u8 GDTexMode0Ids[8] = {
|
|
TX_SETMODE0_I0_ID,
|
|
TX_SETMODE0_I1_ID,
|
|
TX_SETMODE0_I2_ID,
|
|
TX_SETMODE0_I3_ID,
|
|
TX_SETMODE0_I4_ID,
|
|
TX_SETMODE0_I5_ID,
|
|
TX_SETMODE0_I6_ID,
|
|
TX_SETMODE0_I7_ID,
|
|
};
|
|
|
|
u8 GDTexMode1Ids[8] = {
|
|
TX_SETMODE1_I0_ID,
|
|
TX_SETMODE1_I1_ID,
|
|
TX_SETMODE1_I2_ID,
|
|
TX_SETMODE1_I3_ID,
|
|
TX_SETMODE1_I4_ID,
|
|
TX_SETMODE1_I5_ID,
|
|
TX_SETMODE1_I6_ID,
|
|
TX_SETMODE1_I7_ID,
|
|
};
|
|
|
|
u8 GDTexImage0Ids[8] = {
|
|
TX_SETIMAGE0_I0_ID,
|
|
TX_SETIMAGE0_I1_ID,
|
|
TX_SETIMAGE0_I2_ID,
|
|
TX_SETIMAGE0_I3_ID,
|
|
TX_SETIMAGE0_I4_ID,
|
|
TX_SETIMAGE0_I5_ID,
|
|
TX_SETIMAGE0_I6_ID,
|
|
TX_SETIMAGE0_I7_ID,
|
|
};
|
|
|
|
u8 GDTexImage1Ids[8] = {
|
|
TX_SETIMAGE1_I0_ID,
|
|
TX_SETIMAGE1_I1_ID,
|
|
TX_SETIMAGE1_I2_ID,
|
|
TX_SETIMAGE1_I3_ID,
|
|
TX_SETIMAGE1_I4_ID,
|
|
TX_SETIMAGE1_I5_ID,
|
|
TX_SETIMAGE1_I6_ID,
|
|
TX_SETIMAGE1_I7_ID,
|
|
};
|
|
|
|
u8 GDTexImage2Ids[8] = {
|
|
TX_SETIMAGE2_I0_ID,
|
|
TX_SETIMAGE2_I1_ID,
|
|
TX_SETIMAGE2_I2_ID,
|
|
TX_SETIMAGE2_I3_ID,
|
|
TX_SETIMAGE2_I4_ID,
|
|
TX_SETIMAGE2_I5_ID,
|
|
TX_SETIMAGE2_I6_ID,
|
|
TX_SETIMAGE2_I7_ID,
|
|
};
|
|
|
|
u8 GDTexImage3Ids[8] = {
|
|
TX_SETIMAGE3_I0_ID,
|
|
TX_SETIMAGE3_I1_ID,
|
|
TX_SETIMAGE3_I2_ID,
|
|
TX_SETIMAGE3_I3_ID,
|
|
TX_SETIMAGE3_I4_ID,
|
|
TX_SETIMAGE3_I5_ID,
|
|
TX_SETIMAGE3_I6_ID,
|
|
TX_SETIMAGE3_I7_ID,
|
|
};
|
|
|
|
u8 GDTexTlutIds[8] = {
|
|
TX_SETTLUT_I0_ID,
|
|
TX_SETTLUT_I1_ID,
|
|
TX_SETTLUT_I2_ID,
|
|
TX_SETTLUT_I3_ID,
|
|
TX_SETTLUT_I4_ID,
|
|
TX_SETTLUT_I5_ID,
|
|
TX_SETTLUT_I6_ID,
|
|
TX_SETTLUT_I7_ID,
|
|
};
|
|
|
|
u8 GD2HWFiltConv[] = {
|
|
0, // TX_MIN_NEAREST, // GX_NEAR,
|
|
4, // TX_MIN_LINEAR, // GX_LINEAR,
|
|
1, // TX_MIN_NEAREST_MIPMAP_NEAREST, // GX_NEAR_MIP_NEAR,
|
|
5, // TX_MIN_LINEAR_MIPMAP_NEAREST, // GX_LIN_MIP_NEAR,
|
|
2, // TX_MIN_NEAREST_MIPMAP_LINEAR, // GX_NEAR_MIP_LIN,
|
|
6, // TX_MIN_LINEAR_MIPMAP_LINEAR, // GX_LIN_MIP_LIN
|
|
};
|
|
|
|
#define GX_TMEM_HI 0x80000
|
|
#define GX_32k 0x08000
|
|
#define GX_8k 0x02000
|
|
u32 GXTlutRegions[20] = {
|
|
GX_TMEM_HI + GX_32k*8 + GX_8k*0,
|
|
GX_TMEM_HI + GX_32k*8 + GX_8k*1,
|
|
GX_TMEM_HI + GX_32k*8 + GX_8k*2,
|
|
GX_TMEM_HI + GX_32k*8 + GX_8k*3,
|
|
GX_TMEM_HI + GX_32k*8 + GX_8k*4,
|
|
GX_TMEM_HI + GX_32k*8 + GX_8k*5,
|
|
GX_TMEM_HI + GX_32k*8 + GX_8k*6,
|
|
GX_TMEM_HI + GX_32k*8 + GX_8k*7,
|
|
GX_TMEM_HI + GX_32k*8 + GX_8k*8,
|
|
GX_TMEM_HI + GX_32k*8 + GX_8k*9,
|
|
GX_TMEM_HI + GX_32k*8 + GX_8k*10,
|
|
GX_TMEM_HI + GX_32k*8 + GX_8k*11,
|
|
GX_TMEM_HI + GX_32k*8 + GX_8k*12,
|
|
GX_TMEM_HI + GX_32k*8 + GX_8k*13,
|
|
GX_TMEM_HI + GX_32k*8 + GX_8k*14,
|
|
GX_TMEM_HI + GX_32k*8 + GX_8k*15,
|
|
GX_TMEM_HI + GX_32k*8 + GX_8k*16 + GX_32k*0,
|
|
GX_TMEM_HI + GX_32k*8 + GX_8k*16 + GX_32k*1,
|
|
GX_TMEM_HI + GX_32k*8 + GX_8k*16 + GX_32k*2,
|
|
GX_TMEM_HI + GX_32k*8 + GX_8k*16 + GX_32k*3,
|
|
};
|
|
|
|
/********************************************************************************
|
|
* Forward references. *
|
|
********************************************************************************/
|
|
|
|
/********************************************************************************
|
|
* Externs. *
|
|
********************************************************************************/
|
|
|
|
#ifndef __PLAT_WN32__
|
|
static void DirectWrite_u8(u8 data)
|
|
{
|
|
GXWGFifo.u8 = data;
|
|
}
|
|
|
|
static void DirectWrite_s8(s8 data)
|
|
{
|
|
GXWGFifo.s8 = data;
|
|
}
|
|
|
|
static void DirectWrite_u16(u16 data)
|
|
{
|
|
GXWGFifo.u16 = data;
|
|
}
|
|
|
|
static void DirectWrite_s16(s16 data)
|
|
{
|
|
GXWGFifo.s16 = data;
|
|
}
|
|
|
|
static void DirectWrite_u32(u32 data)
|
|
{
|
|
GXWGFifo.u32 = data;
|
|
}
|
|
|
|
static void DirectWrite_s32(s32 data)
|
|
{
|
|
GXWGFifo.s32 = data;
|
|
}
|
|
|
|
static void DirectWrite_f32(f32 data)
|
|
{
|
|
GXWGFifo.f32 = data;
|
|
}
|
|
|
|
static void DirectWrite_u24(u32 data)
|
|
{
|
|
GXWGFifo.u8 = (u8)((data >> 16) & 0xff);
|
|
GXWGFifo.u8 = (u8)((data >> 8) & 0xff);
|
|
GXWGFifo.u8 = (u8)((data >> 0) & 0xff);
|
|
}
|
|
|
|
static void DirectWriteBPCmd(u32 regval)
|
|
{
|
|
GXWGFifo.u8 = GX_LOAD_BP_REG;
|
|
GXWGFifo.u32 = regval;
|
|
}
|
|
|
|
static void DirectWriteCPCmd(u8 addr, u32 val)
|
|
{
|
|
GXWGFifo.u8 = GX_LOAD_CP_REG;
|
|
GXWGFifo.u8 = addr;
|
|
GXWGFifo.u32 = val;
|
|
}
|
|
static void DirectWriteXFCmd(u16 addr, u32 val)
|
|
{
|
|
GXWGFifo.u8 = GX_LOAD_XF_REG;
|
|
GXWGFifo.u16 = 0;
|
|
GXWGFifo.u16 = addr;
|
|
GXWGFifo.u32 = val;
|
|
}
|
|
|
|
static void DirectWriteXFCmdHdr(u16 addr, u8 len)
|
|
{
|
|
GXWGFifo.u8 = GX_LOAD_XF_REG;
|
|
GXWGFifo.u16 = (u16)((len) - 1);
|
|
GXWGFifo.u16 = addr;
|
|
}
|
|
|
|
static void DirectWriteXFIndxACmd(u16 addr, u8 len, u16 index)
|
|
{
|
|
GXWGFifo.u8 = GX_LOAD_INDX_A;
|
|
GXWGFifo.u16 = index;
|
|
GXWGFifo.u16 = __XFAddrLen((addr), ((len)-1));
|
|
}
|
|
|
|
static void DirectWriteXFIndxBCmd(u16 addr, u8 len, u16 index)
|
|
{
|
|
GXWGFifo.u8 = GX_LOAD_INDX_B;
|
|
GXWGFifo.u16 = index;
|
|
GXWGFifo.u16 = __XFAddrLen((addr), ((len)-1));
|
|
}
|
|
|
|
static void DirectWriteXFIndxCCmd(u16 addr, u8 len, u16 index)
|
|
{
|
|
GXWGFifo.u8 = GX_LOAD_INDX_C;
|
|
GXWGFifo.u16 = index;
|
|
GXWGFifo.u16 = __XFAddrLen((addr), ((len)-1));
|
|
}
|
|
|
|
static void DirectWriteXFIndxDCmd(u16 addr, u8 len, u16 index)
|
|
{
|
|
GXWGFifo.u8 = GX_LOAD_INDX_D;
|
|
GXWGFifo.u16 = index;
|
|
GXWGFifo.u16 = __XFAddrLen((addr), ((len)-1));
|
|
}
|
|
#endif // __PLAT_WN32__
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
|
|
void begin ( void * p_buffer, int max_size )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
if ( p_buffer && max_size )
|
|
{
|
|
// We're writing to a display list.
|
|
if ( g_use != USE_DL )
|
|
#endif // __PLAT_WN32__
|
|
{
|
|
_u8 = GDWrite_u8;
|
|
_s8 = GDWrite_s8;
|
|
_u16 = GDWrite_u16;
|
|
_s16 = GDWrite_s16;
|
|
_u32 = GDWrite_u32;
|
|
_s32 = GDWrite_s32;
|
|
_f32 = GDWrite_f32;
|
|
_u24 = GDWrite_u24;
|
|
|
|
_BPCmd = GDWriteBPCmd;
|
|
_CPCmd = GDWriteCPCmd;
|
|
_XFCmd = GDWriteXFCmd;
|
|
_XFCmdHdr = GDWriteXFCmdHdr;
|
|
_XFIndxACmd = GDWriteXFIndxACmd;
|
|
_XFIndxBCmd = GDWriteXFIndxBCmd;
|
|
_XFIndxCCmd = GDWriteXFIndxCCmd;
|
|
_XFIndxDCmd = GDWriteXFIndxDCmd;
|
|
g_use = USE_DL;
|
|
}
|
|
|
|
GDInitGDLObj( &g_dl, p_buffer, max_size );
|
|
GDSetCurrent( &g_dl );
|
|
#ifndef __PLAT_WN32__
|
|
}
|
|
else
|
|
{
|
|
// We're issuing direct commands.
|
|
if ( g_use != USE_DIRECT )
|
|
{
|
|
_u8 = DirectWrite_u8;
|
|
_s8 = DirectWrite_s8;
|
|
_u16 = DirectWrite_u16;
|
|
_s16 = DirectWrite_s16;
|
|
_u32 = DirectWrite_u32;
|
|
_s32 = DirectWrite_s32;
|
|
_f32 = DirectWrite_f32;
|
|
_u24 = DirectWrite_u24;
|
|
|
|
_BPCmd = DirectWriteBPCmd;
|
|
_CPCmd = DirectWriteCPCmd;
|
|
_XFCmd = DirectWriteXFCmd;
|
|
_XFCmdHdr = DirectWriteXFCmdHdr;
|
|
_XFIndxACmd = DirectWriteXFIndxACmd;
|
|
_XFIndxBCmd = DirectWriteXFIndxBCmd;
|
|
_XFIndxCCmd = DirectWriteXFIndxCCmd;
|
|
_XFIndxDCmd = DirectWriteXFIndxDCmd;
|
|
g_use = USE_DIRECT;
|
|
}
|
|
|
|
#ifndef __PLAT_WN32__
|
|
// _BPCmd(TX_SETIMAGE1( MyTmemRegions[7][0] >> 5, 0, 0, 1, GDTexImage1Ids[GX_TEXMAP7]));
|
|
// if (MyTmemRegions[7][1] < GX_TMEM_MAX) // need to define this!
|
|
// {
|
|
// _BPCmd(TX_SETIMAGE2( MyTmemRegions[7][1] >> 5, 0, 0, GDTexImage2Ids[GX_TEXMAP7]));
|
|
// }
|
|
#endif // __PLAT_WN32__
|
|
|
|
}
|
|
#endif // __PLAT_WN32__
|
|
tmem_count = 0;
|
|
tlut_count = 0;
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
int end( void )
|
|
{
|
|
int rv;
|
|
|
|
if ( g_use == USE_DL )
|
|
{
|
|
GDPadCurr32();
|
|
GDFlushCurrToMem();
|
|
rv = GDGetCurrOffset();
|
|
}
|
|
else
|
|
{
|
|
rv = 0;
|
|
}
|
|
|
|
#ifndef __PLAT_WN32__
|
|
// Usage always goes back to direct after a display list is constructed.
|
|
if ( g_use != USE_DIRECT )
|
|
{
|
|
_u8 = DirectWrite_u8;
|
|
_s8 = DirectWrite_s8;
|
|
_u16 = DirectWrite_u16;
|
|
_s16 = DirectWrite_s16;
|
|
_u32 = DirectWrite_u32;
|
|
_s32 = DirectWrite_s32;
|
|
_f32 = DirectWrite_f32;
|
|
_u24 = DirectWrite_u24;
|
|
|
|
_BPCmd = DirectWriteBPCmd;
|
|
_CPCmd = DirectWriteCPCmd;
|
|
_XFCmd = DirectWriteXFCmd;
|
|
_XFCmdHdr = DirectWriteXFCmdHdr;
|
|
_XFIndxACmd = DirectWriteXFIndxACmd;
|
|
_XFIndxBCmd = DirectWriteXFIndxBCmd;
|
|
_XFIndxCCmd = DirectWriteXFIndxCCmd;
|
|
_XFIndxDCmd = DirectWriteXFIndxDCmd;
|
|
g_use = USE_DIRECT;
|
|
}
|
|
#endif // __PLAT_WN32__
|
|
|
|
return rv;
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void SetChanCtrl( GXChannelID chan,
|
|
GXBool enable,
|
|
GXColorSrc amb_src,
|
|
GXColorSrc mat_src,
|
|
u32 light_mask,
|
|
GXDiffuseFn diff_fn,
|
|
GXAttnFn attn_fn )
|
|
{
|
|
u32 reg;
|
|
|
|
reg = XF_COLOR0CNTRL_F_PS( mat_src, enable, (light_mask & 0x0f), amb_src,
|
|
((attn_fn==GX_AF_SPEC) ? GX_DF_NONE : diff_fn),
|
|
(attn_fn != GX_AF_NONE),
|
|
(attn_fn != GX_AF_SPEC),
|
|
((light_mask >> 4) & 0x0f) );
|
|
_XFCmd( (u16) (XF_COLOR0CNTRL_ID + (chan & 3)), reg );
|
|
|
|
if (chan == GX_COLOR0A0 || chan == GX_COLOR1A1)
|
|
{
|
|
_XFCmd( (u16) (XF_COLOR0CNTRL_ID + ( chan - 2)), reg );
|
|
}
|
|
|
|
// GDSetChanCtrl( chan, enable, amb_src, mat_src, light_mask, diff_fn, attn_fn );
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void SetTevOrder( GXTevStageID evenStage,
|
|
GXTexCoordID coord0,
|
|
GXTexMapID map0,
|
|
GXChannelID color0,
|
|
GXTexCoordID coord1,
|
|
GXTexMapID map1,
|
|
GXChannelID color1 )
|
|
{
|
|
static u8 c2r[] = { // Convert enums to HW values
|
|
RAS1_CC_0, // GX_COLOR0
|
|
RAS1_CC_1, // GX_COLOR1
|
|
RAS1_CC_0, // GX_ALPHA0
|
|
RAS1_CC_1, // GX_ALPHA1
|
|
RAS1_CC_0, // GX_COLOR0A0
|
|
RAS1_CC_1, // GX_COLOR1A1
|
|
RAS1_CC_Z, // GX_COLOR_ZERO
|
|
RAS1_CC_B, // GX_COLOR_BUMP
|
|
RAS1_CC_BN, // GX_COLOR_BUMPN
|
|
0, // 9
|
|
0, // 10
|
|
0, // 11
|
|
0, // 12
|
|
0, // 13
|
|
0, // 14
|
|
RAS1_CC_Z // 15: GX_COLOR_NULL gets mapped here
|
|
};
|
|
|
|
_BPCmd( RAS1_TREF(
|
|
(map0 & 7), // map 0
|
|
(coord0 & 7), // tc 0
|
|
((map0 != GX_TEXMAP_NULL) && !(map0 & GX_TEX_DISABLE)), // enable 0
|
|
c2r[ color0 & 0xf ], // color 0
|
|
(map1 & 7), // map 1
|
|
(coord1 & 7), // tc 1
|
|
((map1 != GX_TEXMAP_NULL) && !(map1 & GX_TEX_DISABLE)), // enable 1
|
|
c2r[ color1 & 0xf ], // color 1
|
|
(RAS1_TREF0_ID + (evenStage/2)) ));
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void SetTevAlphaInOpSwap( GXTevStageID stage,
|
|
GXTevAlphaArg a,
|
|
GXTevAlphaArg b,
|
|
GXTevAlphaArg c,
|
|
GXTevAlphaArg d,
|
|
GXTevOp op,
|
|
GXTevBias bias,
|
|
GXTevScale scale,
|
|
GXBool clamp,
|
|
GXTevRegID out_reg,
|
|
GXTevSwapSel ras_sel,
|
|
GXTevSwapSel tex_sel )
|
|
{
|
|
if (op <= GX_TEV_SUB)
|
|
{
|
|
_BPCmd( TEV_ALPHA_ENV( ras_sel, tex_sel,
|
|
d, c, b, a,
|
|
bias, (op & 1), clamp, scale,
|
|
out_reg,
|
|
TEV_ALPHA_ENV_0_ID + 2 * (u32) stage ));
|
|
} else {
|
|
_BPCmd( TEV_ALPHA_ENV( ras_sel, tex_sel,
|
|
d, c, b, a,
|
|
GX_MAX_TEVBIAS, (op&1), clamp, ((op>>1)&3),
|
|
out_reg,
|
|
TEV_ALPHA_ENV_0_ID + 2 * (u32) stage ));
|
|
}
|
|
|
|
// GDSetTevAlphaCalcAndSwap( stage, a, b, c, d, op, bias, scale, clamp, out_reg, ras_sel, tex_sel );
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void SetTevColorInOp( GXTevStageID stage,
|
|
GXTevColorArg a,
|
|
GXTevColorArg b,
|
|
GXTevColorArg c,
|
|
GXTevColorArg d,
|
|
GXTevOp op,
|
|
GXTevBias bias,
|
|
GXTevScale scale,
|
|
GXBool clamp,
|
|
GXTevRegID out_reg )
|
|
{
|
|
if (op <= GX_TEV_SUB)
|
|
{
|
|
_BPCmd( TEV_COLOR_ENV( d, c, b, a,
|
|
bias, (op & 1), clamp, scale,
|
|
out_reg,
|
|
TEV_COLOR_ENV_0_ID + 2 * (u32) stage ));
|
|
} else {
|
|
_BPCmd( TEV_COLOR_ENV( d, c, b, a,
|
|
GX_MAX_TEVBIAS, (op&1), clamp, ((op>>1)&3),
|
|
out_reg,
|
|
TEV_COLOR_ENV_0_ID + 2 * (u32) stage ));
|
|
}
|
|
|
|
// GDSetTevColorCalc( stage, a, b, c, d, op, bias, scale, clamp, out_reg );
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void SetTevKSel( GXTevStageID even_stage,
|
|
GXTevKColorSel color_even,
|
|
GXTevKAlphaSel alpha_even,
|
|
GXTevKColorSel color_odd,
|
|
GXTevKAlphaSel alpha_odd )
|
|
{
|
|
_BPCmd( SS_MASK( TEV_KSEL_MASK_KCSEL ) );
|
|
_BPCmd( TEV_KSEL( 0, 0, color_even, alpha_even, color_odd, alpha_odd, TEV_KSEL_0_ID + (even_stage/2) ));
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void SetTevKColor( GXTevKColorID id,
|
|
GXColor color )
|
|
{
|
|
u32 regRA, regBG;
|
|
|
|
regRA = TEV_REGISTERL( color.r, color.a, TEV_KONSTANT_REG,
|
|
TEV_REGISTERL_0_ID + id * 2 );
|
|
regBG = TEV_REGISTERH( color.b, color.g, TEV_KONSTANT_REG,
|
|
TEV_REGISTERH_0_ID + id * 2 );
|
|
_BPCmd( regRA );
|
|
_BPCmd( regBG );
|
|
// The KColor registers do not have the load delay bug.
|
|
|
|
// GDSetTevKColor( id, color );
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void SetTevColor( GXTevRegID reg,
|
|
GXColor color )
|
|
{
|
|
u32 regRA, regBG;
|
|
|
|
regRA = TEV_REGISTERL( color.r, color.a, TEV_COLOR_REG,
|
|
TEV_REGISTERL_0_ID + reg * 2 );
|
|
regBG = TEV_REGISTERH( color.b, color.g, TEV_COLOR_REG,
|
|
TEV_REGISTERH_0_ID + reg * 2 );
|
|
_BPCmd( regRA );
|
|
_BPCmd( regBG );
|
|
// Due to color load delay bug, must put two more BP commands here...
|
|
_BPCmd( regBG );
|
|
_BPCmd( regBG );
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void SetTexCoordGen( GXTexCoordID dst_coord,
|
|
GXTexGenType func,
|
|
GXTexGenSrc src_param,
|
|
GXBool normalize,
|
|
u32 postmtx )
|
|
{
|
|
u32 form;
|
|
u32 tgType;
|
|
u32 proj;
|
|
u32 row;
|
|
u32 embossRow;
|
|
u32 embossLit;
|
|
|
|
form = XF_TEX_AB11;
|
|
proj = XF_TEX_ST;
|
|
row = XF_TEX0_INROW;
|
|
embossRow = XF_TEX0_INROW;
|
|
embossLit = 0;
|
|
|
|
#ifndef __PLAT_WN32__
|
|
ASSERTMSG((dst_coord < GX_MAX_TEXCOORD),
|
|
"GDSetTexCoordGen: invalid texcoord ID");
|
|
#endif // __PLAT_WN32__
|
|
|
|
switch (src_param) {
|
|
case GX_TG_POS: row = XF_GEOM_INROW; form = XF_TEX_ABC1; break;
|
|
case GX_TG_NRM: row = XF_NORMAL_INROW; form = XF_TEX_ABC1; break;
|
|
case GX_TG_BINRM: row = XF_BINORMAL_T_INROW; form = XF_TEX_ABC1; break;
|
|
case GX_TG_TANGENT: row = XF_BINORMAL_B_INROW; form = XF_TEX_ABC1; break;
|
|
case GX_TG_COLOR0: row = XF_COLORS_INROW; break;
|
|
case GX_TG_COLOR1: row = XF_COLORS_INROW; break;
|
|
case GX_TG_TEX0: row = XF_TEX0_INROW; break;
|
|
case GX_TG_TEX1: row = XF_TEX1_INROW; break;
|
|
case GX_TG_TEX2: row = XF_TEX2_INROW; break;
|
|
case GX_TG_TEX3: row = XF_TEX3_INROW; break;
|
|
case GX_TG_TEX4: row = XF_TEX4_INROW; break;
|
|
case GX_TG_TEX5: row = XF_TEX5_INROW; break;
|
|
case GX_TG_TEX6: row = XF_TEX6_INROW; break;
|
|
case GX_TG_TEX7: row = XF_TEX7_INROW; break;
|
|
case GX_TG_TEXCOORD0: embossRow = 0; break;
|
|
case GX_TG_TEXCOORD1: embossRow = 1; break;
|
|
case GX_TG_TEXCOORD2: embossRow = 2; break;
|
|
case GX_TG_TEXCOORD3: embossRow = 3; break;
|
|
case GX_TG_TEXCOORD4: embossRow = 4; break;
|
|
case GX_TG_TEXCOORD5: embossRow = 5; break;
|
|
case GX_TG_TEXCOORD6: embossRow = 6; break;
|
|
default:
|
|
#ifndef __PLAT_WN32__
|
|
ASSERTMSG(0, "GDSetTexCoordGen: invalid texgen source");
|
|
#endif // __PLAT_WN32__
|
|
break;
|
|
}
|
|
|
|
switch (func) {
|
|
case GX_TG_MTX2x4:
|
|
tgType = XF_TEXGEN_REGULAR;
|
|
break;
|
|
|
|
case GX_TG_MTX3x4:
|
|
tgType = XF_TEXGEN_REGULAR;
|
|
proj = XF_TEX_STQ;
|
|
break;
|
|
|
|
case GX_TG_BUMP0:
|
|
case GX_TG_BUMP1:
|
|
case GX_TG_BUMP2:
|
|
case GX_TG_BUMP3:
|
|
case GX_TG_BUMP4:
|
|
case GX_TG_BUMP5:
|
|
case GX_TG_BUMP6:
|
|
case GX_TG_BUMP7:
|
|
#ifndef __PLAT_WN32__
|
|
ASSERTMSG((src_param >= GX_TG_TEXCOORD0) &&
|
|
(src_param <= GX_TG_TEXCOORD6),
|
|
"GDSetTexCoordGen: invalid emboss source");
|
|
#endif // __PLAT_WN32__
|
|
tgType = XF_TEXGEN_EMBOSS_MAP;
|
|
embossLit = (u32) (func - GX_TG_BUMP0);
|
|
break;
|
|
|
|
case GX_TG_SRTG:
|
|
if (src_param == GX_TG_COLOR0) {
|
|
tgType = XF_TEXGEN_COLOR_STRGBC0;
|
|
} else {
|
|
tgType = XF_TEXGEN_COLOR_STRGBC1;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
#ifndef __PLAT_WN32__
|
|
ASSERTMSG(0, "GDSetTexCoordGen: invalid texgen function");
|
|
#endif // __PLAT_WN32__
|
|
tgType = XF_TEXGEN_REGULAR;
|
|
break;
|
|
}
|
|
|
|
_XFCmd( (u16) (XF_TEX0_ID + dst_coord), XF_TEX( proj, form, tgType, row, embossRow, embossLit ));
|
|
|
|
//---------------------------------------------------------------------
|
|
// Update DUALTEX state
|
|
//---------------------------------------------------------------------
|
|
|
|
_XFCmd( (u16) (XF_DUALTEX0_ID + dst_coord), XF_DUALTEX((postmtx - GX_PTTEXMTX0), normalize ));
|
|
|
|
// GDSetTexCoordGen ( dst_coord, func, src_param, normalize, postmtx );
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void UploadTexture( void * image_ptr,
|
|
u16 width,
|
|
u16 height,
|
|
GXTexFmt format,
|
|
GXTexWrapMode wrap_s,
|
|
GXTexWrapMode wrap_t,
|
|
GXBool mipmap,
|
|
GXTexFilter min_filt,
|
|
GXTexFilter mag_filt,
|
|
f32 min_lod,
|
|
f32 max_lod,
|
|
f32 lod_bias,
|
|
GXBool bias_clamp,
|
|
GXBool do_edge_lod,
|
|
GXAnisotropy max_aniso,
|
|
GXTexMapID id )
|
|
{
|
|
#if 0
|
|
GXTexObj to;
|
|
|
|
GXInitTexObj(
|
|
&to,
|
|
image_ptr,
|
|
width,
|
|
height,
|
|
format,
|
|
wrap_s,
|
|
wrap_t,
|
|
mipmap );
|
|
|
|
GXInitTexObjLOD(
|
|
&to,
|
|
min_filt,
|
|
mag_filt,
|
|
min_lod,
|
|
max_lod,
|
|
lod_bias,
|
|
bias_clamp,
|
|
do_edge_lod,
|
|
max_aniso );
|
|
|
|
GXLoadTexObj( &to, id );
|
|
#else
|
|
|
|
// GDSetTexLookupMode( id, wrap_s, wrap_t, min_filt, mag_filt, min_lod, max_lod, lod_bias, bias_clamp, do_edge_lod, max_aniso );
|
|
|
|
_BPCmd(TX_SETMODE0(wrap_s,
|
|
wrap_t,
|
|
(mag_filt == GX_LINEAR),
|
|
GD2HWFiltConv[min_filt],
|
|
!do_edge_lod,
|
|
(u8)((s8)(lod_bias*32.0f)),
|
|
max_aniso,
|
|
bias_clamp,
|
|
GDTexMode0Ids[id]));
|
|
_BPCmd(TX_SETMODE1((u8)(min_lod*16.0f),
|
|
(u8)(max_lod*16.0f),
|
|
GDTexMode1Ids[id]));
|
|
|
|
// GDSetTexImgAttr( id, width, height, format );
|
|
|
|
_BPCmd(TX_SETIMAGE0(width - 1,
|
|
height - 1,
|
|
format,
|
|
GDTexImage0Ids[id]));
|
|
|
|
// GDSetTexCached( id, MyTmemRegions[tmem_count][0], GX_TEXCACHE_32K,
|
|
// MyTmemRegions[tmem_count][1], GX_TEXCACHE_32K );
|
|
|
|
_BPCmd(TX_SETIMAGE1( MyTmemRegions[tmem_count][0] >> 5,
|
|
GX_TEXCACHE_32K+3,
|
|
GX_TEXCACHE_32K+3,
|
|
0,
|
|
GDTexImage1Ids[id]));
|
|
if (GX_TEXCACHE_32K != GX_TEXCACHE_NONE && MyTmemRegions[tmem_count][1] < GX_TMEM_MAX)
|
|
{
|
|
_BPCmd(TX_SETIMAGE2( MyTmemRegions[tmem_count][1] >> 5,
|
|
GX_TEXCACHE_32K+3,
|
|
GX_TEXCACHE_32K+3,
|
|
GDTexImage2Ids[id]));
|
|
}
|
|
|
|
tmem_count++;
|
|
tmem_count &= 7;
|
|
|
|
#ifdef __PLAT_WN32__
|
|
// GDSetTexImgPtrRaw( id, (uint32)image_ptr );
|
|
|
|
_BPCmd(TX_SETIMAGE3((uint32)image_ptr, GDTexImage3Ids[id]));
|
|
|
|
#else
|
|
// GDSetTexImgPtr( id, image_ptr );
|
|
|
|
_BPCmd(TX_SETIMAGE3(OSCachedToPhysical(image_ptr)>>5,
|
|
GDTexImage3Ids[id]));
|
|
#endif // __PLAT_WN32__
|
|
#endif
|
|
}
|
|
|
|
void UploadTexture( void * image_ptr,
|
|
u16 width,
|
|
u16 height,
|
|
GXCITexFmt format,
|
|
GXTexWrapMode wrap_s,
|
|
GXTexWrapMode wrap_t,
|
|
GXBool mipmap,
|
|
GXTexFilter min_filt,
|
|
GXTexFilter mag_filt,
|
|
f32 min_lod,
|
|
f32 max_lod,
|
|
f32 lod_bias,
|
|
GXBool bias_clamp,
|
|
GXBool do_edge_lod,
|
|
GXAnisotropy max_aniso,
|
|
GXTexMapID id )
|
|
{
|
|
UploadTexture( image_ptr,
|
|
width,
|
|
height,
|
|
(GXTexFmt)format,
|
|
wrap_s,
|
|
wrap_t,
|
|
mipmap,
|
|
min_filt,
|
|
mag_filt,
|
|
min_lod,
|
|
max_lod,
|
|
lod_bias,
|
|
bias_clamp,
|
|
do_edge_lod,
|
|
max_aniso,
|
|
id );
|
|
};
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void UploadPalette( void * tlut_ptr,
|
|
GXTlutFmt tlut_format,
|
|
GXTlutSize tlut_size,
|
|
GXTexMapID id )
|
|
{
|
|
// GDSetTexTlut ( GX_TEXMAP0, TLUT0_ADDR, GX_TL_RGB565 );
|
|
_BPCmd(TX_SETTLUT( (GXTlutRegions[tlut_count]-GX_TMEM_HALF) >> 9, tlut_format, GDTexTlutIds[id]));
|
|
|
|
// GDLoadTlutRaw ( 0, TLUT0_ADDR, GX_TLUT_256 );
|
|
#ifndef __PLAT_WN32__
|
|
ASSERTMSG((tlut_size <= 1024), "GDLoadTlut: invalid TLUT size");
|
|
#endif // __PLAT_WN32__
|
|
|
|
// Flush the texture state (without modifying the indirect mask)
|
|
_BPCmd(SS_MASK(0xffff00));
|
|
_BPCmd((BU_IMASK_ID << 24));
|
|
|
|
#ifdef __PLAT_WN32__
|
|
_BPCmd(TX_LOADTLUT0( ((uint32)tlut_ptr>>5), TX_LOADTLUT0_ID));
|
|
#else
|
|
_BPCmd(TX_LOADTLUT0( (OSCachedToPhysical(tlut_ptr)>>5), TX_LOADTLUT0_ID));
|
|
#endif // __PLAT_WN32__
|
|
|
|
// Writing to this register will initiate the actual loading:
|
|
_BPCmd(TX_LOADTLUT1( (GXTlutRegions[tlut_count]-GX_TMEM_HALF) >> 9, tlut_size,
|
|
TX_LOADTLUT1_ID));
|
|
|
|
// Flush the texture state (without modifying the indirect mask)
|
|
_BPCmd(SS_MASK(0xffff00));
|
|
_BPCmd((BU_IMASK_ID << 24));
|
|
|
|
tlut_count++;
|
|
tlut_count %= 20;
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void SetTexCoordScale( GXTexCoordID coord,
|
|
GXBool enable,
|
|
u16 ss,
|
|
u16 ts )
|
|
{
|
|
// GDSetTexCoordScaleAndTOEs( coord, ss, GX_DISABLE, GX_DISABLE, ts, GX_DISABLE, GX_DISABLE, GX_FALSE, GX_FALSE );
|
|
|
|
_BPCmd(SU_TS0( ss - 1, GX_DISABLE, GX_DISABLE, GX_TRUE, GX_TRUE,
|
|
SU_SSIZE0_ID + (u32) coord * 2));
|
|
_BPCmd(SU_TS1( ts - 1, GX_DISABLE, GX_DISABLE,
|
|
SU_TSIZE0_ID + (u32) coord * 2));
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void SetBlendMode( GXBlendMode type,
|
|
GXBlendFactor src_factor,
|
|
GXBlendFactor dst_factor,
|
|
GXLogicOp op,
|
|
GXBool color_update_enable,
|
|
GXBool alpha_update_enable,
|
|
GXBool dither_enable )
|
|
{
|
|
// GDSetBlendModeEtc( type, src_factor, dst_factor, op, GX_TRUE, GX_TRUE, GX_TRUE );
|
|
|
|
_BPCmd( PE_CMODE0(
|
|
((type == GX_BM_BLEND) || (type == GX_BM_SUBTRACT)),
|
|
(type == GX_BM_LOGIC),
|
|
GX_FALSE, //dither_enable,
|
|
color_update_enable,
|
|
GX_FALSE, //alpha_update_enable,
|
|
dst_factor,
|
|
src_factor,
|
|
(type == GX_BM_SUBTRACT),
|
|
op,
|
|
PE_CMODE0_ID ));
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void SetTexChanTevIndCull( u8 nTexGens,
|
|
u8 nChans,
|
|
u8 nTevs,
|
|
u8 nInds,
|
|
GXCullMode cm )
|
|
{
|
|
// GDSetGenMode2( nTexGens, nChans, nTevs, nInds, cm );
|
|
|
|
static u8 cm2hw[] = { 0, 2, 1, 3 };
|
|
_XFCmd( XF_NUMTEX_ID, XF_NUMTEX( nTexGens ));
|
|
_XFCmd( XF_NUMCOLORS_ID, XF_NUMCOLORS( nChans ));
|
|
_BPCmd( GEN_MODE( nTexGens, nChans, 0, (nTevs-1), cm2hw[cm], nInds, 0, GEN_MODE_ID ));
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void SetChanAmbColor( GXChannelID chan,
|
|
GXColor color )
|
|
{
|
|
_XFCmd( (u16) (XF_AMBIENT0_ID + (chan & 1)),
|
|
(((u32)color.r << 24) |
|
|
((u32)color.g << 16) |
|
|
((u32)color.b << 8) |
|
|
((u32)color.a)) );
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void SetChanMatColor( GXChannelID chan,
|
|
GXColor color )
|
|
{
|
|
_XFCmd( (u16) (XF_MATERIAL0_ID + (chan & 1)),
|
|
(((u32)color.r << 24) |
|
|
((u32)color.g << 16) |
|
|
((u32)color.b << 8) |
|
|
((u32)color.a)) );
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void SetPointSize( u8 pointSize,
|
|
GXTexOffset texOffsets )
|
|
{
|
|
//GDSetLPSize
|
|
_BPCmd( SU_LPSIZE( pointSize, pointSize, texOffsets, texOffsets, GX_FALSE, SU_LPSIZE_ID ));
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void SetFog( GXFogType type,
|
|
f32 startz,
|
|
f32 endz,
|
|
f32 nearz,
|
|
f32 farz,
|
|
GXColor color )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
f32 A, B, B_mant, C, A_f;
|
|
u32 b_expn, b_m, a_hex, c_hex;
|
|
u32 fsel, proj;
|
|
|
|
ASSERTMSG(farz >= 0, "GDSetFog: The farz should be positive value");
|
|
ASSERTMSG(farz >= nearz, "GDSetFog: The farz should be larger than nearz");
|
|
|
|
fsel = (u32)(type & 0x07);
|
|
proj = (u32)((type >> 3) & 0x01);
|
|
|
|
if ( proj ) // ORTHOGRAPHIC
|
|
{
|
|
// Calculate constants a and c (TEV HW requirements).
|
|
if ((farz == nearz) || (endz == startz))
|
|
{
|
|
// take care of the odd-ball case.
|
|
A_f = 0.0f;
|
|
C = 0.0f;
|
|
}
|
|
else
|
|
{
|
|
A = 1.0F / (endz - startz);
|
|
A_f = (farz - nearz) * A;
|
|
C = (startz - nearz) * A;
|
|
}
|
|
|
|
b_expn = 0;
|
|
b_m = 0;
|
|
}
|
|
else // PERSPECTIVE
|
|
{
|
|
// Calculate constants a, b, and c (TEV HW requirements).
|
|
if ((farz == nearz) || (endz == startz))
|
|
{
|
|
// take care of the odd-ball case.
|
|
A = 0.0f;
|
|
B = 0.5f;
|
|
C = 0.0f;
|
|
}
|
|
else
|
|
{
|
|
A = (farz * nearz) / ((farz-nearz) * (endz-startz));
|
|
B = farz / (farz-nearz);
|
|
C = startz / (endz-startz);
|
|
}
|
|
|
|
B_mant = B;
|
|
b_expn = 1;
|
|
while (B_mant > 1.0)
|
|
{
|
|
B_mant /= 2;
|
|
b_expn++;
|
|
}
|
|
while ((B_mant > 0) && (B_mant < 0.5))
|
|
{
|
|
B_mant *= 2;
|
|
b_expn--;
|
|
}
|
|
|
|
A_f = A / (1 << (b_expn));
|
|
b_m = (u32)(B_mant * 8388638);
|
|
}
|
|
|
|
a_hex = (* (u32 *) &A_f);
|
|
c_hex = (* (u32 *) &C);
|
|
|
|
// Write out register values.
|
|
_BPCmd( TEV_FOG_PARAM_0_PS( (a_hex >> 12), TEV_FOG_PARAM_0_ID ));
|
|
|
|
_BPCmd( TEV_FOG_PARAM_1( b_m, TEV_FOG_PARAM_1_ID ));
|
|
_BPCmd( TEV_FOG_PARAM_2( b_expn, TEV_FOG_PARAM_2_ID ));
|
|
|
|
_BPCmd( TEV_FOG_PARAM_3_PS( (c_hex >> 12), proj, fsel,
|
|
TEV_FOG_PARAM_3_ID ));
|
|
|
|
_BPCmd( TEV_FOG_COLOR( color.b, color.g, color.r, TEV_FOG_COLOR_ID ));
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void SetFogColor( GXColor color )
|
|
{
|
|
_BPCmd( TEV_FOG_COLOR( color.b, color.g, color.r, TEV_FOG_COLOR_ID ));
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void Begin( GXPrimitive type,
|
|
GXVtxFmt vtxfmt,
|
|
u16 nverts )
|
|
{
|
|
_u8((u8) (vtxfmt | type));
|
|
_u16(nverts);
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void End( void )
|
|
{
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void Position3f32( f32 x,
|
|
f32 y,
|
|
f32 z )
|
|
{
|
|
_f32( x );
|
|
_f32( y );
|
|
_f32( z );
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void Position3u8( u8 x,
|
|
u8 y,
|
|
u8 z )
|
|
{
|
|
_u8( x );
|
|
_u8( y );
|
|
_u8( z );
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void Position3s8( s8 x,
|
|
s8 y,
|
|
s8 z )
|
|
{
|
|
_s8( x );
|
|
_s8( y );
|
|
_s8( z );
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void Position3u16( u16 x,
|
|
u16 y,
|
|
u16 z )
|
|
{
|
|
_u16( x );
|
|
_u16( y );
|
|
_u16( z );
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void Position3s16( s16 x,
|
|
s16 y,
|
|
s16 z )
|
|
{
|
|
_s16( x );
|
|
_s16( y );
|
|
_s16( z );
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void Position2f32( f32 x,
|
|
f32 y )
|
|
{
|
|
_f32( x );
|
|
_f32( y );
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void Position2u8( u8 x,
|
|
u8 y )
|
|
{
|
|
_u8( x );
|
|
_u8( y );
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void Position2s8( s8 x,
|
|
s8 y )
|
|
{
|
|
_s8( x );
|
|
_s8( y );
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void Position2u16( u16 x,
|
|
u16 y )
|
|
{
|
|
_u16( x );
|
|
_u16( y );
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void Position2s16( s16 x,
|
|
s16 y )
|
|
{
|
|
_s16( x );
|
|
_s16( y );
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void Position1x16( u16 i )
|
|
{
|
|
_u16( i );
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void Position1x8( u8 i )
|
|
{
|
|
_u8( i );
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void Normal3f32( f32 x,
|
|
f32 y,
|
|
f32 z )
|
|
{
|
|
_f32( x );
|
|
_f32( y );
|
|
_f32( z );
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void Normal3s16( s16 x,
|
|
s16 y,
|
|
s16 z )
|
|
{
|
|
_s16( x );
|
|
_s16( y );
|
|
_s16( z );
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void Normal3s8( s8 x,
|
|
s8 y,
|
|
s8 z )
|
|
{
|
|
_s8( x );
|
|
_s8( y );
|
|
_s8( z );
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void Normal1x16( u16 i )
|
|
{
|
|
_u16( i );
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void Normal1x8( u8 i )
|
|
{
|
|
_u8( i );
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void Color4u8( u8 r,
|
|
u8 g,
|
|
u8 b,
|
|
u8 a )
|
|
{
|
|
_u8( r );
|
|
_u8( g );
|
|
_u8( b );
|
|
_u8( a );
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void Color1u32( u32 rgba )
|
|
{
|
|
_u32( rgba );
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void Color1x16( u16 i )
|
|
{
|
|
_u16( i );
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void Color1x8( u8 i )
|
|
{
|
|
_u8( i );
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void TexCoord2f32( f32 s,
|
|
f32 t )
|
|
{
|
|
_f32( s );
|
|
_f32( t );
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void TexCoord2s16( s16 s,
|
|
s16 t )
|
|
{
|
|
_s16( s );
|
|
_s16( t );
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void TexCoord2u16( u16 s,
|
|
u16 t )
|
|
{
|
|
_u16( s );
|
|
_u16( t );
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void TexCoord2s8( s8 s,
|
|
s8 t )
|
|
{
|
|
_s8( s );
|
|
_s8( t );
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void TexCoord2u8( u8 s,
|
|
u8 t )
|
|
{
|
|
_u8( s );
|
|
_u8( t );
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void TexCoord1f32( f32 s )
|
|
{
|
|
_f32( s );
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void TexCoord1s16( s16 s )
|
|
{
|
|
_s16( s );
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void TexCoord1u16( u16 s )
|
|
{
|
|
_u16( s );
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void TexCoord1s8( s8 s )
|
|
{
|
|
_s8( s );
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void TexCoord1u8( u8 s )
|
|
{
|
|
_u8( s );
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void TexCoord1x16( u16 i )
|
|
{
|
|
_u16( i );
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void TexCoord1x8( u8 i )
|
|
{
|
|
_u8( i );
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void MatrixIndex1u8( u8 i )
|
|
{
|
|
_u8( i );
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void SetZMode( GXBool compare_enable,
|
|
GXCompare func,
|
|
GXBool update_enable )
|
|
{
|
|
_BPCmd( PE_ZMODE( compare_enable, func, update_enable, PE_ZMODE_ID ));
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void SetVtxDesc( int items, ... )
|
|
{
|
|
u32 nnorms = 0;
|
|
u32 ncols = 0;
|
|
u32 ntexs = 0;
|
|
|
|
u32 pnMtxIdx = GX_NONE;
|
|
u32 txMtxIdxMask = 0;
|
|
u32 posn = GX_DIRECT;
|
|
u32 norm = GX_NONE;
|
|
u32 col0 = GX_NONE;
|
|
u32 col1 = GX_NONE;
|
|
u32 tex0 = GX_NONE;
|
|
u32 tex1 = GX_NONE;
|
|
u32 tex2 = GX_NONE;
|
|
u32 tex3 = GX_NONE;
|
|
u32 tex4 = GX_NONE;
|
|
u32 tex5 = GX_NONE;
|
|
u32 tex6 = GX_NONE;
|
|
u32 tex7 = GX_NONE;
|
|
|
|
// Start the arguments.
|
|
va_list vl;
|
|
va_start( vl, items );
|
|
|
|
for ( int item = 0; item < items; item++ )
|
|
{
|
|
// Get this item.
|
|
GXAttr attribute = va_arg( vl, GXAttr );
|
|
GXAttrType type = va_arg( vl, GXAttrType );
|
|
|
|
#ifndef __PLAT_WN32__
|
|
ASSERTMSG(((attribute >= GX_VA_PNMTXIDX) &&
|
|
(attribute <= GX_VA_MAX_ATTR)),
|
|
"GDSetVtxDescv: invalid attribute");
|
|
|
|
ASSERTMSG(((type >= GX_NONE) &&
|
|
(type <= GX_INDEX16)),
|
|
"GDSetVtxDescv: invalid type");
|
|
|
|
ASSERTMSG(((attribute >= GX_VA_PNMTXIDX) &&
|
|
(attribute <= GX_VA_TEX7MTXIDX)) ?
|
|
((type == GX_NONE) ||
|
|
(type == GX_DIRECT)) : 1,
|
|
"GDSetVtxDescv: invalid type for given attribute");
|
|
#endif // __PLAT_WN32__
|
|
|
|
switch (attribute) {
|
|
|
|
case GX_VA_PNMTXIDX: pnMtxIdx = type; break;
|
|
|
|
case GX_VA_TEX0MTXIDX:
|
|
txMtxIdxMask = (txMtxIdxMask & ~1) | (type << 0); break;
|
|
case GX_VA_TEX1MTXIDX:
|
|
txMtxIdxMask = (txMtxIdxMask & ~2) | (type << 1); break;
|
|
case GX_VA_TEX2MTXIDX:
|
|
txMtxIdxMask = (txMtxIdxMask & ~4) | (type << 2); break;
|
|
case GX_VA_TEX3MTXIDX:
|
|
txMtxIdxMask = (txMtxIdxMask & ~8) | (type << 3); break;
|
|
case GX_VA_TEX4MTXIDX:
|
|
txMtxIdxMask = (txMtxIdxMask & ~16) | (type << 4); break;
|
|
case GX_VA_TEX5MTXIDX:
|
|
txMtxIdxMask = (txMtxIdxMask & ~32) | (type << 5); break;
|
|
case GX_VA_TEX6MTXIDX:
|
|
txMtxIdxMask = (txMtxIdxMask & ~64) | (type << 6); break;
|
|
case GX_VA_TEX7MTXIDX:
|
|
txMtxIdxMask = (txMtxIdxMask & ~128) | (type << 7); break;
|
|
|
|
case GX_VA_POS: posn = type; break;
|
|
|
|
case GX_VA_NRM:
|
|
if (type != GX_NONE)
|
|
{ norm = type; nnorms = 1; }
|
|
break;
|
|
case GX_VA_NBT:
|
|
if (type != GX_NONE)
|
|
{ norm = type; nnorms = 2; }
|
|
break;
|
|
|
|
case GX_VA_CLR0: col0=type; ncols+=(col0 != GX_NONE); break;
|
|
case GX_VA_CLR1: col1=type; ncols+=(col1 != GX_NONE); break;
|
|
|
|
case GX_VA_TEX0: tex0=type; ntexs+=(tex0 != GX_NONE); break;
|
|
case GX_VA_TEX1: tex1=type; ntexs+=(tex1 != GX_NONE); break;
|
|
case GX_VA_TEX2: tex2=type; ntexs+=(tex2 != GX_NONE); break;
|
|
case GX_VA_TEX3: tex3=type; ntexs+=(tex3 != GX_NONE); break;
|
|
case GX_VA_TEX4: tex4=type; ntexs+=(tex4 != GX_NONE); break;
|
|
case GX_VA_TEX5: tex5=type; ntexs+=(tex5 != GX_NONE); break;
|
|
case GX_VA_TEX6: tex6=type; ntexs+=(tex6 != GX_NONE); break;
|
|
case GX_VA_TEX7: tex7=type; ntexs+=(tex7 != GX_NONE); break;
|
|
default: break;
|
|
}
|
|
}
|
|
|
|
va_end( vl );
|
|
|
|
// Write out the attributes.
|
|
_CPCmd( CP_VCD_LO_ID, CP_VCD_REG_LO_PS( pnMtxIdx, txMtxIdxMask, posn, norm, col0, col1 ));
|
|
|
|
_CPCmd( CP_VCD_HI_ID, CP_VCD_REG_HI( tex0, tex1, tex2, tex3, tex4, tex5, tex6, tex7 ));
|
|
|
|
_XFCmd( XF_INVTXSPEC_ID, XF_INVTXSPEC( ncols, nnorms, ntexs ));
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void LoadPosMtxImm( const f32 mtx[3][4],
|
|
u32 id )
|
|
{
|
|
_XFCmdHdr(__PosMtxToXFMem(id), (u8)(3*4));
|
|
|
|
_f32(mtx[0][0]);
|
|
_f32(mtx[0][1]);
|
|
_f32(mtx[0][2]);
|
|
_f32(mtx[0][3]);
|
|
|
|
_f32(mtx[1][0]);
|
|
_f32(mtx[1][1]);
|
|
_f32(mtx[1][2]);
|
|
_f32(mtx[1][3]);
|
|
|
|
_f32(mtx[2][0]);
|
|
_f32(mtx[2][1]);
|
|
_f32(mtx[2][2]);
|
|
_f32(mtx[2][3]);
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void LoadNrmMtxImm ( const f32 mtx[3][4],
|
|
u32 id )
|
|
{
|
|
_XFCmdHdr(__NrmMtxToXFMem(id), (u8)(3*3));
|
|
|
|
_f32(mtx[0][0]);
|
|
_f32(mtx[0][1]);
|
|
_f32(mtx[0][2]);
|
|
|
|
_f32(mtx[1][0]);
|
|
_f32(mtx[1][1]);
|
|
_f32(mtx[1][2]);
|
|
|
|
_f32(mtx[2][0]);
|
|
_f32(mtx[2][1]);
|
|
_f32(mtx[2][2]);
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void LoadTexMtxImm( const f32 mtx[3][4],
|
|
u32 id,
|
|
GXTexMtxType type )
|
|
{
|
|
u16 addr;
|
|
u8 count;
|
|
|
|
if (id >= GX_PTTEXMTX0)
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
ASSERTMSG(type == GX_MTX3x4, "GDLoadTexMtxImm: invalid matrix type");
|
|
#endif // __PLAT_WN32__
|
|
addr = __DTTMtxToXFMem(id);
|
|
count = (u8)(3*4);
|
|
} else {
|
|
addr = __TexMtxToXFMem(id);
|
|
count = (u8)((type == GX_MTX2x4) ? (2*4) : (3*4));
|
|
}
|
|
|
|
_XFCmdHdr(addr, count);
|
|
|
|
_f32(mtx[0][0]);
|
|
_f32(mtx[0][1]);
|
|
_f32(mtx[0][2]);
|
|
_f32(mtx[0][3]);
|
|
|
|
_f32(mtx[1][0]);
|
|
_f32(mtx[1][1]);
|
|
_f32(mtx[1][2]);
|
|
_f32(mtx[1][3]);
|
|
|
|
if (type == GX_MTX3x4)
|
|
{
|
|
_f32(mtx[2][0]);
|
|
_f32(mtx[2][1]);
|
|
_f32(mtx[2][2]);
|
|
_f32(mtx[2][3]);
|
|
}
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void SetAlphaCompare( GXCompare comp0,
|
|
u8 ref0,
|
|
GXAlphaOp op,
|
|
GXCompare comp1,
|
|
u8 ref1 )
|
|
{
|
|
_BPCmd( TEV_ALPHAFUNC( ref0, ref1, comp0, comp1, op, TEV_ALPHAFUNC_ID ));
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void SetCurrMtxPosTex03( u32 pn,
|
|
u32 t0,
|
|
u32 t1,
|
|
u32 t2,
|
|
u32 t3 )
|
|
{
|
|
u32 regA;
|
|
|
|
regA = MATIDX_REG_A(pn, t0, t1, t2, t3);
|
|
|
|
_CPCmd( CP_MATINDEX_A, regA ); // W1
|
|
|
|
_XFCmdHdr( XF_MATINDEX_A, 1 );
|
|
_u32( regA ); // W1
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void SetCurrMtxTex47( u32 t4,
|
|
u32 t5,
|
|
u32 t6,
|
|
u32 t7 )
|
|
{
|
|
u32 regB;
|
|
|
|
regB = MATIDX_REG_B(t4, t5, t6, t7);
|
|
|
|
_CPCmd( CP_MATINDEX_B, regB ); // W2
|
|
|
|
_XFCmdHdr( XF_MATINDEX_B, 1 );
|
|
_u32( regB ); // W2
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void SetProjection( const f32 mtx[4][4],
|
|
GXProjectionType type )
|
|
{
|
|
// u32 c;
|
|
//
|
|
// c = ( type == GX_ORTHOGRAPHIC ) ? 3u : 2u;
|
|
//
|
|
// GDWriteXFCmdHdr( XF_PROJECTION_ID, 7 );
|
|
// GDWrite_f32( mtx[0][0] );
|
|
// GDWrite_f32( mtx[0][c] );
|
|
// GDWrite_f32( mtx[1][1] );
|
|
// GDWrite_f32( mtx[1][c] );
|
|
// GDWrite_f32( mtx[2][2] );
|
|
// GDWrite_f32( mtx[2][3] );
|
|
// GDWrite_u32( type );
|
|
|
|
#ifndef __PLAT_WN32__
|
|
GXSetProjection( mtx, type );
|
|
#endif // __PLAT_WN32__
|
|
// u32 c;
|
|
//
|
|
// c = ( type == GX_ORTHOGRAPHIC ) ? 3u : 2u;
|
|
//
|
|
// _XFCmdHdr( XF_PROJECTION_ID, 7 );
|
|
// _f32( mtx[0][0] );
|
|
// _f32( mtx[0][c] );
|
|
// _f32( mtx[1][1] );
|
|
// _f32( mtx[1][c] );
|
|
// _f32( mtx[2][2] );
|
|
// _f32( mtx[2][3] );
|
|
// _u32( type );
|
|
//
|
|
// g_projection[0] = mtx[0][0];
|
|
// g_projection[1] = mtx[0][c];
|
|
// g_projection[2] = mtx[1][1];
|
|
// g_projection[3] = mtx[1][c];
|
|
// g_projection[4] = mtx[2][2];
|
|
// g_projection[5] = mtx[2][3];
|
|
// *((u32 *)&g_projection[6]) = type;
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
#define TEV_KSEL_MASK_SWAPMODETABLE \
|
|
(( 0x000003 << TEV_KSEL_XRB_SHIFT ) | \
|
|
( 0x000003 << TEV_KSEL_XGA_SHIFT ))
|
|
|
|
void SetTevSwapModeTable( GXTevSwapSel table,
|
|
GXTevColorChan red,
|
|
GXTevColorChan green,
|
|
GXTevColorChan blue,
|
|
GXTevColorChan alpha )
|
|
{
|
|
// Mask to avoid touching the konstant-color selects
|
|
_BPCmd( SS_MASK( TEV_KSEL_MASK_SWAPMODETABLE ) );
|
|
_BPCmd( TEV_KSEL( red, green, 0, 0, 0, 0, TEV_KSEL_0_ID + (table * 2) ));
|
|
_BPCmd( SS_MASK( TEV_KSEL_MASK_SWAPMODETABLE ) );
|
|
_BPCmd( TEV_KSEL( blue, alpha, 0, 0, 0, 0, TEV_KSEL_0_ID + (table * 2) + 1 ));
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void SetScissorBoxOffset( s32 x_off,
|
|
s32 y_off )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXSetScissorBoxOffset( x_off, y_off );
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void SetScissor( u32 left,
|
|
u32 top,
|
|
u32 wd,
|
|
u32 ht )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXSetScissor( left, top, wd, ht );
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void SetDispCopyGamma( GXGamma gamma )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXSetDispCopyGamma( gamma );
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
//typedef void (*GXBreakPtCallback)(void);
|
|
GXBreakPtCallback SetBreakPtCallback( GXBreakPtCallback cb )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
return GXSetBreakPtCallback( cb );
|
|
#else
|
|
return 0;
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void Flush( void )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXFlush();
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void GetFifoPtrs( GXFifoObj* fifo,
|
|
void** readPtr,
|
|
void** writePtr )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXGetFifoPtrs( fifo, readPtr, writePtr );
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
GXFifoObj* GetCPUFifo( void )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
return GXGetCPUFifo();
|
|
#else
|
|
return 0;
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
GXFifoObj* GetGPFifo( void )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
return GXGetGPFifo();
|
|
#else
|
|
return 0;
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void EnableBreakPt( void* breakPtr )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXEnableBreakPt( breakPtr );
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void DisableBreakPt( void )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXDisableBreakPt();
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void SetGPMetric( GXPerf0 perf0,
|
|
GXPerf1 perf1 )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXSetGPMetric( perf0, perf1 );
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void ClearGPMetric( void )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXClearGPMetric();
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void ReadGPMetric( u32 * cnt0,
|
|
u32 * cnt1 )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXReadGPMetric( cnt0, cnt1 );
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void SetDrawSync( u16 token )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXSetDrawSync( token );
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
u16 ReadDrawSync( void )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
return GXReadDrawSync();
|
|
#else
|
|
return 0;
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void SetCopyFilter( GXBool aa,
|
|
const u8 sample_pattern[12][2],
|
|
GXBool vf,
|
|
const u8 vfilter[7] )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXSetCopyFilter( aa, sample_pattern, vf, vfilter );
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void CopyDisp( void * dest,
|
|
GXBool clear )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXCopyDisp( dest, clear );
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void SetCopyClear( GXColor clear_clr,
|
|
u32 clear_z )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXSetCopyClear( clear_clr, clear_z );
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void PokeZ( u16 x,
|
|
u16 y,
|
|
u32 z )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXPokeZ( x, y, z );
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void PeekZ( u16 x,
|
|
u16 y,
|
|
u32* z )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXPeekZ( x, y, z );
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void PokeARGB( u16 x,
|
|
u16 y,
|
|
u32 color )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXPokeARGB( x, y, color );
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void PeekARGB( u16 x,
|
|
u16 y,
|
|
u32* color )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXPeekARGB( x, y, color );
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void SetClipMode( GXClipMode mode )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXSetClipMode( mode );
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void SetZCompLoc( GXBool before_tex )
|
|
{
|
|
// stb x61
|
|
|
|
//#ifndef __PLAT_WN32__
|
|
// GXSetZCompLoc( before_tex );
|
|
//#else
|
|
_BPCmd( ( PE_CONTROL_ID << 24 ) | GX_PF_RGB8_Z24 | ( before_tex << 6 ) );
|
|
//#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void SetPixelFmt( GXPixelFmt pix_fmt,
|
|
GXZFmt16 z_fmt )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXSetPixelFmt( pix_fmt, z_fmt );
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
GXFifoObj * Init( void * base,
|
|
u32 size )
|
|
{
|
|
begin();
|
|
#ifndef __PLAT_WN32__
|
|
return GXInit( base, size );
|
|
#else
|
|
return 0;
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void AdjustForOverscan( const GXRenderModeObj * rmin,
|
|
GXRenderModeObj * rmout,
|
|
u16 hor,
|
|
u16 ver )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXAdjustForOverscan( rmin, rmout, hor, ver );
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void SetViewport( f32 left,
|
|
f32 top,
|
|
f32 wd,
|
|
f32 ht,
|
|
f32 nearz,
|
|
f32 farz )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXSetViewport( left, top, wd, ht, nearz, farz );
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void SetDispCopySrc( u16 left,
|
|
u16 top,
|
|
u16 wd,
|
|
u16 ht )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXSetDispCopySrc( left, top, wd, ht );
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void SetDispCopyDst( u16 wd,
|
|
u16 ht )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXSetDispCopyDst( wd, ht );
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
u32 SetDispCopyYScale( f32 vscale )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
return GXSetDispCopyYScale( vscale );
|
|
#else
|
|
return 0;
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void SetVtxAttrFmt( GXVtxFmt vtxfmt,
|
|
GXAttr attr,
|
|
GXCompCnt cnt,
|
|
GXCompType type,
|
|
u8 frac )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXSetVtxAttrFmt( vtxfmt, attr, cnt, type, frac );
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void SetViewportJitter( f32 left,
|
|
f32 top,
|
|
f32 wd,
|
|
f32 ht,
|
|
f32 nearz,
|
|
f32 farz,
|
|
u32 field )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXSetViewportJitter( left, top, wd, ht, nearz, farz, field );
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void InvalidateVtxCache( void )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXInvalidateVtxCache();
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void InvalidateTexAll( void )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXInvalidateTexAll();
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
GXDrawSyncCallback SetDrawSyncCallback( GXDrawSyncCallback cb )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
return GXSetDrawSyncCallback( cb );
|
|
#else
|
|
return 0;
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void DrawDone( void )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXDrawDone();
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
void AbortFrame( void )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXAbortFrame();
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void SetDrawDone( void )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXSetDrawDone();
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void WaitDrawDone( void )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXWaitDrawDone();
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
GXDrawDoneCallback SetDrawDoneCallback( GXDrawDoneCallback cb )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
return GXSetDrawDoneCallback( cb );
|
|
#else
|
|
return 0;
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void ReadXfRasMetric( u32 * xf_wait_in,
|
|
u32 * xf_wait_out,
|
|
u32 * ras_busy,
|
|
u32 * clocks )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXReadXfRasMetric( xf_wait_in, xf_wait_out, ras_busy, clocks );
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void GetGPStatus( GXBool * overhi,
|
|
GXBool * underlow,
|
|
GXBool * readIdle,
|
|
GXBool * cmdIdle,
|
|
GXBool * brkpt )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXGetGPStatus( overhi, underlow, readIdle, cmdIdle, brkpt);
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void GetFifoStatus( GXFifoObj * fifo,
|
|
GXBool * overhi,
|
|
GXBool * underlow,
|
|
u32 * fifoCount,
|
|
GXBool * cpu_write,
|
|
GXBool * gp_read,
|
|
GXBool * fifowrap )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXGetFifoStatus( fifo, overhi, underlow, fifoCount, cpu_write, gp_read, fifowrap );
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void * GetFifoBase( const GXFifoObj * fifo )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
return GXGetFifoBase( fifo );
|
|
#else
|
|
return 0;
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
u32 GetFifoSize( const GXFifoObj * fifo )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
return GXGetFifoSize( fifo );
|
|
#else
|
|
return 0;
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void GetFifoLimits( const GXFifoObj * fifo,
|
|
u32 * hi,
|
|
u32 * lo )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXGetFifoLimits( fifo, hi, lo);
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
u32 GetOverflowCount( void )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
return GXGetOverflowCount();
|
|
#else
|
|
return 0;
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
u32 ResetOverflowCount( void )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
return GXResetOverflowCount();
|
|
#else
|
|
return 0;
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void EnableHang( void )
|
|
{
|
|
// Set up RAS Ready counter
|
|
_u8( GX_LOAD_BP_REG );
|
|
_u32( 0x2402c004 ); // ... 101 10000 00000 00100
|
|
|
|
// Set up SU Ready counter
|
|
_u8( GX_LOAD_BP_REG );
|
|
_u32( 0x23000020 ); // ... 100 000
|
|
|
|
// Set up XF TOP and BOT busy counters
|
|
_u8( GX_LOAD_XF_REG );
|
|
_u16( 0x0000 );
|
|
_u16( 0x1006 );
|
|
_u32( 0x00084400 ); // 10000 10001 00000 00000
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void DisableHang( void )
|
|
{
|
|
// Disable RAS counters
|
|
_u8( GX_LOAD_BP_REG );
|
|
_u32( 0x24000000 );
|
|
|
|
// Disable SU counters
|
|
_u8( GX_LOAD_BP_REG );
|
|
_u32( 0x23000000 );
|
|
|
|
// Disable XF counters
|
|
_u8( GX_LOAD_XF_REG );
|
|
_u16( 0x0000 );
|
|
_u16( 0x1006 );
|
|
_u32( 0x00000000 );
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void ResolveDLTexAddr( NxNgc::sTextureDL * p_dl,
|
|
NxNgc::sMaterialPassHeader * p_pass,
|
|
int num_passes )
|
|
{
|
|
// GX::begin( p_dl->mp_dl, p_dl->m_dl_size );
|
|
// multi_mesh( p_mat, p_pass, true, true );
|
|
// p_dl->m_dl_size = GX::end();
|
|
|
|
#ifndef __PLAT_WN32__
|
|
for ( int layer = 0; layer < num_passes; layer++ )
|
|
{
|
|
// Offset 0 = mode0 :: wrap, aniso, clamp, lod, filt
|
|
// Offset 5 = mode1 :: lod values
|
|
// Offset 10 = image0 :: width, height, format
|
|
// Offset 15 = image1 :: cache slot
|
|
// Offset 20 = image2 :: cache slot
|
|
// Offset 25 = image3 :: RAM Pointer
|
|
// Offset 30 = SU_TS0 :: Scale (texel only)
|
|
// Offset 35 = SU_TS1 :: Scale (texel only)
|
|
|
|
if ( p_pass[layer].m_texture.p_data )
|
|
{
|
|
unsigned char * p8;
|
|
uint32 address;
|
|
uint8 levels = p_pass[layer].m_texture.p_data->Levels;
|
|
u8 min = 0;
|
|
u8 max = (u8)( ( levels > 1 ? levels - 1.0f : 0.0f ) * 16.0f );
|
|
if ( p_pass[layer].m_texture.p_data->pTexelData && ( p_dl->m_tex_offset[layer] != -1 ) )
|
|
{
|
|
// Resolve address
|
|
p8 = &((unsigned char *)p_dl->mp_dl)[p_dl->m_tex_offset[layer]+25];
|
|
address = OSCachedToPhysical( p_pass[layer].m_texture.p_data->pTexelData ) >> 5;
|
|
p8[2] = (uint8)( ( address >> 16 ) & 0xff );
|
|
p8[3] = (uint8)( ( address >> 8 ) & 0xff );
|
|
p8[4] = (uint8)( ( address >> 0 ) & 0xff );
|
|
DCFlushRange ( &p8[2], 3 );
|
|
// Resolve MIP
|
|
p8 = &((unsigned char *)p_dl->mp_dl)[p_dl->m_tex_offset[layer]+5];
|
|
p8[3] = max;
|
|
p8[4] = min;
|
|
DCFlushRange ( &p8[2], 3 );
|
|
// Resolve Width & Height
|
|
p8 = &((unsigned char *)p_dl->mp_dl)[p_dl->m_tex_offset[layer]+10];
|
|
int width = p_pass[layer].m_texture.p_data->ActualWidth - 1;
|
|
int height = p_pass[layer].m_texture.p_data->ActualHeight - 1;
|
|
uint32 whf = ( width << 0 ) | ( height << 10 ) | ( GX_TF_CMPR << 20 );
|
|
p8[2] = (uint8)( ( whf >> 16 ) & 0xff );
|
|
p8[3] = (uint8)( ( whf >> 8 ) & 0xff );
|
|
p8[4] = (uint8)( ( whf >> 0 ) & 0xff );
|
|
DCFlushRange ( &p8[2], 3 );
|
|
p8 = &((unsigned char *)p_dl->mp_dl)[p_dl->m_tex_offset[layer]+30];
|
|
p8[3] = (uint8)( ( width >> 8 ) & 0xff );
|
|
p8[4] = (uint8)( ( width >> 0 ) & 0xff );
|
|
DCFlushRange ( &p8[3], 2 );
|
|
p8 = &((unsigned char *)p_dl->mp_dl)[p_dl->m_tex_offset[layer]+35];
|
|
p8[3] = (uint8)( ( height >> 8 ) & 0xff );
|
|
p8[4] = (uint8)( ( height >> 0 ) & 0xff );
|
|
DCFlushRange ( &p8[3], 2 );
|
|
}
|
|
if ( p_pass[layer].m_texture.p_data->pAlphaData && ( p_dl->m_alpha_offset[layer] != -1 ) )
|
|
{
|
|
// Resolve address
|
|
p8 = &((unsigned char *)p_dl->mp_dl)[p_dl->m_alpha_offset[layer]+25];
|
|
address = OSCachedToPhysical( p_pass[layer].m_texture.p_data->pAlphaData ) >> 5;
|
|
p8[2] = (uint8)( ( address >> 16 ) & 0xff );
|
|
p8[3] = (uint8)( ( address >> 8 ) & 0xff );
|
|
p8[4] = (uint8)( ( address >> 0 ) & 0xff );
|
|
DCFlushRange ( &p8[2], 3 );
|
|
// Resolve MIP
|
|
p8 = &((unsigned char *)p_dl->mp_dl)[p_dl->m_alpha_offset[layer]+5];
|
|
p8[3] = max;
|
|
p8[4] = min;
|
|
DCFlushRange ( &p8[3], 2 );
|
|
// Resolve Width & Height
|
|
p8 = &((unsigned char *)p_dl->mp_dl)[p_dl->m_tex_offset[layer]+10];
|
|
int width = p_pass[layer].m_texture.p_data->ActualWidth - 1;
|
|
int height = p_pass[layer].m_texture.p_data->ActualHeight - 1;
|
|
uint32 whf = ( width << 0 ) | ( height << 10 ) | ( GX_TF_CMPR << 20 );
|
|
p8[2] = (uint8)( ( whf >> 16 ) & 0xff );
|
|
p8[3] = (uint8)( ( whf >> 8 ) & 0xff );
|
|
p8[4] = (uint8)( ( whf >> 0 ) & 0xff );
|
|
DCFlushRange ( &p8[2], 3 );
|
|
}
|
|
}
|
|
}
|
|
DCFlushRange ( p_dl->mp_dl, p_dl->m_dl_size );
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void ChangeMaterialColor( unsigned char * p_dl,
|
|
unsigned int size,
|
|
GXColor color,
|
|
int pass )
|
|
{
|
|
// GX::begin( p_dl->mp_dl, p_dl->m_dl_size );
|
|
// multi_mesh( p_mat, p_pass, true, true );
|
|
// p_dl->m_dl_size = GX::end();
|
|
|
|
#ifndef __PLAT_WN32__
|
|
unsigned char * p8 = p_dl;
|
|
unsigned char * p_end = &p8[size];
|
|
|
|
bool quit = false;
|
|
|
|
while ( !quit )
|
|
{
|
|
switch ( p8[0] )
|
|
{
|
|
case GX_LOAD_BP_REG:
|
|
{
|
|
uint8 reg0 = TEV_REGISTERL_0_ID + ( pass * 2 );
|
|
uint8 reg1 = TEV_REGISTERH_0_ID + ( pass * 2 );
|
|
|
|
if ( ( p8[(0*5)+1] == reg0 ) && ( p8[(1*5)+1] == reg1 ) )
|
|
{
|
|
u32 regRA, regBG;
|
|
|
|
regRA = TEV_REGISTERL( color.r, color.a, TEV_KONSTANT_REG,
|
|
TEV_REGISTERL_0_ID + pass * 2 );
|
|
regBG = TEV_REGISTERH( color.b, color.g, TEV_KONSTANT_REG,
|
|
TEV_REGISTERH_0_ID + pass * 2 );
|
|
p8[(0*5)+1] = ( regRA >> 24 );
|
|
p8[(0*5)+2] = ( regRA >> 16 );
|
|
p8[(0*5)+3] = ( regRA >> 8 );
|
|
p8[(0*5)+4] = ( regRA >> 0 );
|
|
|
|
p8[(1*5)+1] = ( regBG >> 24 );
|
|
p8[(1*5)+2] = ( regBG >> 16 );
|
|
p8[(1*5)+3] = ( regBG >> 8 );
|
|
p8[(1*5)+4] = ( regBG >> 0 );
|
|
DCFlushRange ( p8, 10 );
|
|
}
|
|
p8 += 5;
|
|
}
|
|
break;
|
|
case GX_LOAD_CP_REG:
|
|
p8 += 6;
|
|
break;
|
|
case GX_LOAD_XF_REG:
|
|
p8 += 1 + 2 + 2 + 4 + ( 4 * ( ( p8[1] << 8 ) | p8[2] ) );
|
|
break;
|
|
default:
|
|
quit = true;
|
|
break;
|
|
}
|
|
if ( p8 >= p_end ) quit = true;
|
|
}
|
|
DCFlushRange ( p_dl, size );
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void SetTexCopySrc( u16 left,
|
|
u16 top,
|
|
u16 wd,
|
|
u16 ht )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXSetTexCopySrc( left, top, wd, ht );
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void SetTexCopyDst( u16 wd,
|
|
u16 ht,
|
|
GXTexFmt fmt,
|
|
GXBool mipmap )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXSetTexCopyDst( wd, ht, fmt, mipmap );
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void CopyTex( void * dest,
|
|
GXBool clear )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXCopyTex( dest, clear );
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void PixModeSync( void )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXPixModeSync();
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void PokeAlphaUpdate( GXBool update_enable )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXPokeAlphaUpdate( update_enable );
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void PokeColorUpdate( GXBool update_enable )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXPokeColorUpdate( update_enable );
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void GetProjectionv( f32 * p )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXGetProjectionv( p );
|
|
#endif // __PLAT_WN32__
|
|
// p[0] = g_projection[0];
|
|
// p[1] = g_projection[1];
|
|
// p[2] = g_projection[2];
|
|
// p[3] = g_projection[3];
|
|
// p[4] = g_projection[4];
|
|
// p[5] = g_projection[5];
|
|
// p[6] = g_projection[6];
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void SetProjectionv( const f32 * ptr )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXSetProjectionv( ptr );
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void GetViewportv( f32 * viewport )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXGetViewportv( viewport );
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void GetScissor( u32 * left,
|
|
u32 * top,
|
|
u32 * width,
|
|
u32 * height )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXGetScissor( left, top, width, height );
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void Project( f32 x, // model coordinates
|
|
f32 y,
|
|
f32 z,
|
|
const f32 mtx[3][4], // model-view matrix
|
|
const f32 * pm, // projection matrix, as returned by GXGetProjectionv
|
|
const f32 * vp, // viewport, as returned by GXGetViewportv
|
|
f32 * sx, // screen coordinates
|
|
f32 * sy,
|
|
f32 * sz )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXProject( x, y, z, mtx, pm, vp, sx, sy, sz );
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void SetArray( GXAttr attr,
|
|
const void * base_ptr,
|
|
u8 stride )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
// GDSetArray( attr, base_ptr, stride );
|
|
|
|
s32 cpAttr;
|
|
|
|
cpAttr = (attr == GX_VA_NBT) ? (GX_VA_NRM - GX_VA_POS) : (attr - GX_VA_POS);
|
|
|
|
_CPCmd( (u8) (CP_ARRAY_BASE_ID + cpAttr),
|
|
CP_ARRAY_BASE_REG( OSCachedToPhysical( base_ptr ) ));
|
|
|
|
_CPCmd( (u8) (CP_ARRAY_STRIDE_ID + cpAttr),
|
|
CP_ARRAY_STRIDE_REG( stride ));
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void InitLightAttn( GXLightObj* lt_obj,
|
|
f32 a0,
|
|
f32 a1,
|
|
f32 a2,
|
|
f32 k0,
|
|
f32 k1,
|
|
f32 k2 )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXInitLightAttn( lt_obj, a0, a1, a2, k0, k1, k2 );
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void InitLightAttnA( GXLightObj * lt_obj,
|
|
f32 a0,
|
|
f32 a1,
|
|
f32 a2 )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXInitLightAttnA( lt_obj, a0, a1, a2);
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void InitLightAttnK( GXLightObj * lt_obj,
|
|
f32 k0,
|
|
f32 k1,
|
|
f32 k2 )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXInitLightAttnK( lt_obj, k0, k1, k2 );
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void InitLightSpot( GXLightObj * lt_obj,
|
|
f32 cutoff,
|
|
GXSpotFn spot_func )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXInitLightSpot( lt_obj, cutoff, spot_func );
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void InitLightDistAttn( GXLightObj * lt_obj,
|
|
f32 ref_distance,
|
|
f32 ref_brightness,
|
|
GXDistAttnFn dist_func )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXInitLightDistAttn( lt_obj, ref_distance, ref_brightness, dist_func );
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void InitLightPos( GXLightObj * lt_obj,
|
|
f32 x,
|
|
f32 y,
|
|
f32 z )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXInitLightPos( lt_obj, x, y, z );
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void InitLightColor( GXLightObj * lt_obj,
|
|
GXColor color )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXInitLightColor( lt_obj, color );
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void LoadLightObjImm( const GXLightObj * lt_obj,
|
|
GXLightID light )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXLoadLightObjImm( lt_obj, light );
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void LoadLightObjIndx( u32 lt_obj_indx,
|
|
GXLightID light )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXLoadLightObjIndx( lt_obj_indx, light );
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void InitLightDir( GXLightObj * lt_obj,
|
|
f32 nx,
|
|
f32 ny,
|
|
f32 nz )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXInitLightDir( lt_obj, nx, ny, nz );
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void InitSpecularDir( GXLightObj * lt_obj,
|
|
f32 nx,
|
|
f32 ny,
|
|
f32 nz )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXInitSpecularDir( lt_obj, nx, ny, nz );
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void InitSpecularDirHA( GXLightObj * lt_obj,
|
|
f32 nx,
|
|
f32 ny,
|
|
f32 nz,
|
|
f32 hx,
|
|
f32 hy,
|
|
f32 hz )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXInitSpecularDirHA( lt_obj, nx, ny, nz, hx, hy, hz );
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void InitLightPosv( GXLightObj * lt_obj,
|
|
Vec * p )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXInitLightPos( lt_obj, p->x, p->y, p->z );
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void InitLightDirv( GXLightObj * lt_obj,
|
|
Vec * n )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXInitLightDir( lt_obj, n->x, n->y, n->z );
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void InitSpecularDirv( GXLightObj * lt_obj,
|
|
Vec * n )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXInitSpecularDir( lt_obj, n->x, n->y, n->z );
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void InitSpecularDirHAv( GXLightObj * lt_obj,
|
|
Vec * n,
|
|
Vec * h )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXInitSpecularDirHA( lt_obj, n->x, n->y, n->z, h->x, h->y, h->z );
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void InitLightShininess( GXLightObj * lt_obj,
|
|
float shininess )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXInitLightAttn( lt_obj, 0.0F, 0.0F, 1.0F, shininess / 2.0F, 0.0F, 1.0F - shininess / 2.0F );
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void CallDisplayList( const void * list,
|
|
u32 nbytes )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
GXCallDisplayList( list, nbytes );
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
void ResetGX( void )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
// Color definitions
|
|
|
|
#define GX_DEFAULT_BG (GXColor){64, 64, 64, 255}
|
|
#define BLACK (GXColor){0, 0, 0, 0}
|
|
#define WHITE (GXColor){255, 255, 255, 255}
|
|
|
|
//
|
|
// Render Mode
|
|
//
|
|
// (set 'rmode' based upon VIGetTvFormat(); code not shown)
|
|
|
|
//
|
|
// Geometry and Vertex
|
|
//
|
|
GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
|
|
GXSetTexCoordGen(GX_TEXCOORD1, GX_TG_MTX2x4, GX_TG_TEX1, GX_IDENTITY);
|
|
GXSetTexCoordGen(GX_TEXCOORD2, GX_TG_MTX2x4, GX_TG_TEX2, GX_IDENTITY);
|
|
GXSetTexCoordGen(GX_TEXCOORD3, GX_TG_MTX2x4, GX_TG_TEX3, GX_IDENTITY);
|
|
GXSetTexCoordGen(GX_TEXCOORD4, GX_TG_MTX2x4, GX_TG_TEX4, GX_IDENTITY);
|
|
GXSetTexCoordGen(GX_TEXCOORD5, GX_TG_MTX2x4, GX_TG_TEX5, GX_IDENTITY);
|
|
GXSetTexCoordGen(GX_TEXCOORD6, GX_TG_MTX2x4, GX_TG_TEX6, GX_IDENTITY);
|
|
GXSetTexCoordGen(GX_TEXCOORD7, GX_TG_MTX2x4, GX_TG_TEX7, GX_IDENTITY);
|
|
GXSetNumTexGens(1);
|
|
GXClearVtxDesc();
|
|
GXInvalidateVtxCache();
|
|
|
|
GXSetLineWidth(6, GX_TO_ZERO);
|
|
GXSetPointSize(6, GX_TO_ZERO);
|
|
GXEnableTexOffsets( GX_TEXCOORD0, GX_DISABLE, GX_DISABLE );
|
|
GXEnableTexOffsets( GX_TEXCOORD1, GX_DISABLE, GX_DISABLE );
|
|
GXEnableTexOffsets( GX_TEXCOORD2, GX_DISABLE, GX_DISABLE );
|
|
GXEnableTexOffsets( GX_TEXCOORD3, GX_DISABLE, GX_DISABLE );
|
|
GXEnableTexOffsets( GX_TEXCOORD4, GX_DISABLE, GX_DISABLE );
|
|
GXEnableTexOffsets( GX_TEXCOORD5, GX_DISABLE, GX_DISABLE );
|
|
GXEnableTexOffsets( GX_TEXCOORD6, GX_DISABLE, GX_DISABLE );
|
|
GXEnableTexOffsets( GX_TEXCOORD7, GX_DISABLE, GX_DISABLE );
|
|
|
|
//
|
|
// Transformation and Matrix
|
|
//
|
|
// (initialize 'identity_mtx' to identity; code not shown)
|
|
|
|
// Note: projection matrix is not initialized!
|
|
// GXLoadPosMtxImm(identity_mtx, GX_PNMTX0);
|
|
// GXLoadNrmMtxImm(identity_mtx, GX_PNMTX0);
|
|
GXSetCurrentMtx(GX_PNMTX0);
|
|
// GXLoadTexMtxImm(identity_mtx, GX_IDENTITY, GX_MTX3x4);
|
|
// GXLoadTexMtxImm(identity_mtx, GX_PTIDENTITY, GX_MTX3x4);
|
|
// GXSetViewport(0.0F, // left
|
|
// 0.0F, // top
|
|
// (float)rmode->fbWidth, // width
|
|
// (float)rmode->xfbHeight, // height
|
|
// 0.0F, // nearz
|
|
// 1.0F); // farz
|
|
|
|
//
|
|
// Clipping and Culling
|
|
//
|
|
// GXSetCoPlanar(GX_DISABLE);
|
|
GXSetCullMode(GX_CULL_BACK);
|
|
GXSetClipMode(GX_CLIP_ENABLE);
|
|
// GXSetScissor(0, 0, (u32)rmode->fbWidth, (u32)rmode->efbHeight);
|
|
// GXSetScissorBoxOffset(0, 0);
|
|
|
|
//
|
|
// Lighting - pass vertex color through
|
|
//
|
|
GXSetNumChans(0); // no colors by default
|
|
|
|
GXSetChanCtrl(
|
|
GX_COLOR0A0,
|
|
GX_DISABLE,
|
|
GX_SRC_REG,
|
|
GX_SRC_VTX,
|
|
GX_LIGHT_NULL,
|
|
GX_DF_NONE,
|
|
GX_AF_NONE );
|
|
|
|
GXSetChanAmbColor(GX_COLOR0A0, BLACK);
|
|
GXSetChanMatColor(GX_COLOR0A0, WHITE);
|
|
|
|
GXSetChanCtrl(
|
|
GX_COLOR1A1,
|
|
GX_DISABLE,
|
|
GX_SRC_REG,
|
|
GX_SRC_VTX,
|
|
GX_LIGHT_NULL,
|
|
GX_DF_NONE,
|
|
GX_AF_NONE );
|
|
|
|
GXSetChanAmbColor(GX_COLOR1A1, BLACK);
|
|
GXSetChanMatColor(GX_COLOR1A1, WHITE);
|
|
|
|
//
|
|
// Texture
|
|
//
|
|
GXInvalidateTexAll();
|
|
|
|
// Allocate 8 32k caches for RGBA texture mipmaps.
|
|
// Equal size caches to support 32b RGBA textures.
|
|
//
|
|
// (code not shown)
|
|
|
|
// Allocate color index caches in low bank of TMEM.
|
|
// Each cache is 32kB.
|
|
// Even and odd regions should be allocated on different address.
|
|
//
|
|
// (code not shown)
|
|
|
|
// Allocate TLUTs, 16 256-entry TLUTs and 4 1K-entry TLUTs.
|
|
// 256-entry TLUTs are 8kB, 1k-entry TLUTs are 32kB.
|
|
//
|
|
// (code not shown)
|
|
|
|
//
|
|
// Set texture region and tlut region Callbacks
|
|
//
|
|
// GXSetTexRegionCallback(__GXDefaultTexRegionCallback);
|
|
// GXSetTlutRegionCallback(__GXDefaultTlutRegionCallback);
|
|
//
|
|
//
|
|
// Texture Environment
|
|
//
|
|
GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0);
|
|
GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD1, GX_TEXMAP1, GX_COLOR0A0);
|
|
GXSetTevOrder(GX_TEVSTAGE2, GX_TEXCOORD2, GX_TEXMAP2, GX_COLOR0A0);
|
|
GXSetTevOrder(GX_TEVSTAGE3, GX_TEXCOORD3, GX_TEXMAP3, GX_COLOR0A0);
|
|
GXSetTevOrder(GX_TEVSTAGE4, GX_TEXCOORD4, GX_TEXMAP4, GX_COLOR0A0);
|
|
GXSetTevOrder(GX_TEVSTAGE5, GX_TEXCOORD5, GX_TEXMAP5, GX_COLOR0A0);
|
|
GXSetTevOrder(GX_TEVSTAGE6, GX_TEXCOORD6, GX_TEXMAP6, GX_COLOR0A0);
|
|
GXSetTevOrder(GX_TEVSTAGE7, GX_TEXCOORD7, GX_TEXMAP7, GX_COLOR0A0);
|
|
GXSetTevOrder(GX_TEVSTAGE8, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);
|
|
GXSetTevOrder(GX_TEVSTAGE9, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);
|
|
GXSetTevOrder(GX_TEVSTAGE10,GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);
|
|
GXSetTevOrder(GX_TEVSTAGE11,GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);
|
|
GXSetTevOrder(GX_TEVSTAGE12,GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);
|
|
GXSetTevOrder(GX_TEVSTAGE13,GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);
|
|
GXSetTevOrder(GX_TEVSTAGE14,GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);
|
|
GXSetTevOrder(GX_TEVSTAGE15,GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);
|
|
GXSetNumTevStages(1);
|
|
GXSetTevOp(GX_TEVSTAGE0, GX_REPLACE);
|
|
GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_AND, GX_ALWAYS, 0);
|
|
// GXSetZTexture(GX_ZT_DISABLE, GX_TF_Z8, 0);
|
|
//
|
|
for ( int i = GX_TEVSTAGE0; i < GX_MAX_TEVSTAGE; i++) {
|
|
GXSetTevKColorSel((GXTevStageID) i, GX_TEV_KCSEL_1_4 );
|
|
GXSetTevKAlphaSel((GXTevStageID) i, GX_TEV_KASEL_1 );
|
|
GXSetTevSwapMode ((GXTevStageID) i, GX_TEV_SWAP0, GX_TEV_SWAP0 );
|
|
}
|
|
// GXSetTevSwapModeTable(GX_TEV_SWAP0,
|
|
// GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA);
|
|
// GXSetTevSwapModeTable(GX_TEV_SWAP1,
|
|
// GX_CH_RED, GX_CH_RED, GX_CH_RED, GX_CH_ALPHA);
|
|
// GXSetTevSwapModeTable(GX_TEV_SWAP2,
|
|
// GX_CH_GREEN, GX_CH_GREEN, GX_CH_GREEN, GX_CH_ALPHA);
|
|
// GXSetTevSwapModeTable(GX_TEV_SWAP3,
|
|
// GX_CH_BLUE, GX_CH_BLUE, GX_CH_BLUE, GX_CH_ALPHA);
|
|
//
|
|
// // Indirect Textures.
|
|
// for (i = GX_TEVSTAGE0; i < GX_MAX_TEVSTAGE; i++) {
|
|
// GXSetTevDirect((GXTevStageID) i);
|
|
// }
|
|
// GXSetNumIndStages(0);
|
|
// GXSetIndTexCoordScale( GX_INDTEXSTAGE0, GX_ITS_1, GX_ITS_1 );
|
|
// GXSetIndTexCoordScale( GX_INDTEXSTAGE1, GX_ITS_1, GX_ITS_1 );
|
|
// GXSetIndTexCoordScale( GX_INDTEXSTAGE2, GX_ITS_1, GX_ITS_1 );
|
|
// GXSetIndTexCoordScale( GX_INDTEXSTAGE3, GX_ITS_1, GX_ITS_1 );
|
|
//
|
|
//
|
|
// Pixel Processing
|
|
//
|
|
GXSetFog(GX_FOG_NONE, 0.0F, 1.0F, 0.1F, 1.0F, BLACK);
|
|
GXSetFogRangeAdj( GX_DISABLE, 0, 0 );
|
|
GXSetBlendMode(GX_BM_NONE,
|
|
GX_BL_SRCALPHA, // src factor
|
|
GX_BL_INVSRCALPHA, // dst factor
|
|
GX_LO_CLEAR);
|
|
GXSetColorUpdate(GX_ENABLE);
|
|
GXSetAlphaUpdate(GX_ENABLE);
|
|
GXSetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE);
|
|
GXSetZCompLoc(GX_TRUE); // before texture
|
|
GXSetDither(GX_ENABLE);
|
|
GXSetDstAlpha(GX_DISABLE, 0);
|
|
// GXSetPixelFmt(GX_PF_RGB8_Z24, GX_ZC_LINEAR);
|
|
// GXSetFieldMask( GX_ENABLE, GX_ENABLE );
|
|
// GXSetFieldMode((GXBool)(rmode->field_rendering),
|
|
// ((rmode->viHeight == 2*rmode->xfbHeight) ?
|
|
// GX_ENABLE : GX_DISABLE));
|
|
//
|
|
// //
|
|
// // Frame buffer
|
|
// //
|
|
// GXSetCopyClear(GX_DEFAULT_BG, GX_MAX_Z24);
|
|
// GXSetDispCopySrc(0, 0, rmode->fbWidth, rmode->efbHeight);
|
|
// GXSetDispCopyDst(rmode->fbWidth, rmode->efbHeight);
|
|
// GXSetDispCopyYScale((f32)(rmode->xfbHeight) / (f32)(rmode->efbHeight));
|
|
// GXSetCopyClamp((GXFBClamp)(GX_CLAMP_TOP | GX_CLAMP_BOTTOM));
|
|
// GXSetCopyFilter(rmode->aa, rmode->sample_pattern, GX_TRUE, rmode->vfilter);
|
|
// GXSetDispCopyGamma( GX_GM_1_0 );
|
|
// GXSetDispCopyFrame2Field(GX_COPY_PROGRESSIVE);
|
|
// GXClearBoundingBox();
|
|
//
|
|
// //
|
|
// // CPU direct EFB access
|
|
// //
|
|
// GXPokeColorUpdate(GX_TRUE);
|
|
// GXPokeAlphaUpdate(GX_TRUE);
|
|
// GXPokeDither(GX_FALSE);
|
|
// GXPokeBlendMode(GX_BM_NONE, GX_BL_ZERO, GX_BL_ONE, GX_LO_SET);
|
|
// GXPokeAlphaMode(GX_ALWAYS, 0);
|
|
// GXPokeAlphaRead(GX_READ_FF);
|
|
// GXPokeDstAlpha(GX_DISABLE, 0);
|
|
// GXPokeZMode(GX_TRUE, GX_ALWAYS, GX_TRUE);
|
|
//
|
|
// //
|
|
// // Performance Counters
|
|
// //
|
|
// GXSetGPMetric(GX_PERF0_NONE, GX_PERF1_NONE);
|
|
// GXClearGPMetric();
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
|
|
/********************************************************************************
|
|
* *
|
|
********************************************************************************/
|
|
u32 GetTexBufferSize( u16 width,
|
|
u16 height,
|
|
u32 format,
|
|
GXBool mipmap,
|
|
u8 max_lod )
|
|
{
|
|
#ifndef __PLAT_WN32__
|
|
return GXGetTexBufferSize( width, height, format, mipmap, max_lod );
|
|
#else
|
|
return 0;
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
} // namespace GX
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#ifdef __PLAT_WN32__
|
|
short g_tex_off[4];
|
|
short g_alpha_off[4];
|
|
int g_num_tex;
|
|
#endif // __PLAT_WN32__
|
|
|
|
namespace NxNgc
|
|
{
|
|
|
|
static int stage_id = 0; // 0-15
|
|
static int tev_id = 0; // 0-3
|
|
static int uv_id = 0; // 0-7
|
|
static int uv_tex_id = 0; // 0-7
|
|
static int map_id = 0; // 0-3
|
|
static int layer_id = 0; // 1-3
|
|
static bool correct_color = false;
|
|
|
|
GXTexCoordID ordt[16];
|
|
GXTexMapID ordm[16];
|
|
GXChannelID ordc[16];
|
|
bool ord[16];
|
|
|
|
GXTevKAlphaSel asel[16];
|
|
GXTevKColorSel csel[16];
|
|
bool sel[16];
|
|
|
|
GXTexMtx texmtx[8];
|
|
bool settex = false;
|
|
|
|
bool _su;
|
|
bool _tb;
|
|
bool _tc;
|
|
bool _ta;
|
|
|
|
//typedef struct
|
|
//{
|
|
// GXTexCoordID id;
|
|
// GXTexGenType type;
|
|
// GXTexGenSrc src;
|
|
//} DEFER_GEN;
|
|
//
|
|
//DEFER_GEN defer_gen[16];
|
|
//int num_defer_gen = 0;
|
|
|
|
static void multi_start ( bool bl, bool tx )
|
|
{
|
|
// Set everything to 0.
|
|
// Set everything to 0.
|
|
stage_id = 0;
|
|
tev_id = 0;
|
|
uv_id = 0;
|
|
uv_tex_id = 0;
|
|
map_id = 0;
|
|
layer_id = 0;
|
|
|
|
|
|
// num_defer_gen = 0;
|
|
|
|
// Don't forget these!
|
|
// GXSetNumChans(2);
|
|
// GXSetNumTexGens(2);
|
|
// GXSetNumTevStages(2);
|
|
|
|
// See if we need to add 2 stages for color correction.
|
|
if ( correct_color )
|
|
{
|
|
if(bl && _su)
|
|
{
|
|
GX::SetTevAlphaInOpSwap( GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO,
|
|
GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVREG1,
|
|
GX_TEV_SWAP0, GX_TEV_SWAP0 );
|
|
|
|
GX::SetTevColorInOp( GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_TEXC,
|
|
GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVREG1 );
|
|
|
|
GX::SetTevAlphaInOpSwap( GX_TEVSTAGE1, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_TEXA,
|
|
GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVREG2,
|
|
GX_TEV_SWAP0, GX_TEV_SWAP1 );
|
|
|
|
GX::SetTevColorInOp( GX_TEVSTAGE1, GX_CC_TEXC, GX_CC_ZERO, GX_CC_ZERO, GX_CC_C1,
|
|
GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVREG2 );
|
|
}
|
|
stage_id += 2;
|
|
}
|
|
|
|
// // Create 2 dummy stages.
|
|
// GXTevStageID s_id = (GXTevStageID)(((int)GX_TEVSTAGE0)+stage_id);
|
|
//
|
|
// GXSetTevOrder( s_id, GX_TEXCOORD_NULL, GX_TEX_DISABLE, GX_COLOR_NULL );
|
|
// GXSetTevSwapMode( s_id, GX_TEV_SWAP0, GX_TEV_SWAP0 );
|
|
// GXSetTevAlphaOp(s_id, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV );
|
|
// GXSetTevColorOp(s_id, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV );
|
|
// GXSetTevAlphaIn ( s_id, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO );
|
|
// GXSetTevColorIn ( s_id, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO );
|
|
// stage_id++;
|
|
//
|
|
// s_id = (GXTevStageID)(((int)GX_TEVSTAGE0)+stage_id);
|
|
//
|
|
// GXSetTevOrder( s_id, GX_TEXCOORD_NULL, GX_TEX_DISABLE, GX_COLOR0A0 );
|
|
// GXSetTevSwapMode( s_id, GX_TEV_SWAP0, GX_TEV_SWAP0 );
|
|
// GXSetTevAlphaOp(s_id, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVREG2 );
|
|
// GXSetTevColorOp(s_id, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVREG2 );
|
|
// GXSetTevAlphaIn ( s_id, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_RASA );
|
|
// GXSetTevColorIn ( s_id, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_RASC );
|
|
// stage_id++;
|
|
|
|
// if ( !gCorrectColor || !gMeshUseCorrection )
|
|
// {
|
|
//// // Create 2 dummy stages.
|
|
//// GXTevStageID s_id = (GXTevStageID)(((int)GX_TEVSTAGE0)+stage_id);
|
|
////
|
|
//// GXSetTevOrder( s_id, GX_TEXCOORD_NULL, GX_TEX_DISABLE, GX_COLOR0A0 );
|
|
//// GXSetTevSwapMode( s_id, GX_TEV_SWAP0, GX_TEV_SWAP0 );
|
|
//// GXSetTevAlphaOp(s_id, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVREG2 );
|
|
//// GXSetTevColorOp(s_id, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVREG2 );
|
|
//// GXSetTevAlphaIn ( s_id, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_RASA );
|
|
//// GXSetTevColorIn ( s_id, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_RASC );
|
|
//// stage_id++;
|
|
// correct_color = false;
|
|
// }
|
|
|
|
// Clear out state settings.
|
|
int lp;
|
|
for ( lp = 0; lp < 16; lp++ )
|
|
{
|
|
asel[lp] = GX_TEV_KASEL_1;
|
|
csel[lp] = GX_TEV_KCSEL_1;
|
|
sel[lp] = false;
|
|
|
|
ordt[lp] = (GXTexCoordID)(lp&7);
|
|
ordm[lp] = (GXTexMapID)(lp&7);
|
|
ordc[lp] = GX_COLOR0A0;
|
|
ord[lp] = false;
|
|
}
|
|
|
|
for ( lp = 0; lp < 8; lp++ )
|
|
{
|
|
texmtx[lp] = GX_IDENTITY;
|
|
}
|
|
|
|
settex = false;
|
|
}
|
|
|
|
static void multi_add_layer ( BlendModes blendmode, int raw_fix, bool bl, bool tx )
|
|
{
|
|
// Set inputs.
|
|
GXTevStageID s_id = (GXTevStageID)(((int)GX_TEVSTAGE0)+stage_id);
|
|
|
|
// int reg_id = 1; //layer_id; //( layer_id > 1 ) ? 1 : layer_id; //( tev_id == 3 ) ? 2 : tev_id; // CPREV, C0, C1, C0.
|
|
// int reg_id = layer_id; //( layer_id == 3 ) ? 2 : layer_id; // CPREV, C0, C1, C0.
|
|
int reg_id = tev_id; // CPREV, C0, C1, C0.
|
|
|
|
// GXTevAlphaArg newa= (GXTevAlphaArg)(((int)GX_CA_APREV)+reg_id);
|
|
GXTevColorArg newc = (GXTevColorArg)(((int)GX_CC_CPREV)+(reg_id*2));
|
|
GXTevColorArg newca= (GXTevColorArg)(((int)GX_CC_APREV)+(reg_id*2));
|
|
|
|
|
|
// out_reg = (d (op) ((1.0 - c)*a + c*b) + bias) * scale;
|
|
|
|
// int fix = raw_fix; //( raw_fix >= 128 ) ? 255 : raw_fix * 2;
|
|
|
|
switch ( blendmode ) {
|
|
case vBLEND_MODE_ADD:
|
|
case vBLEND_MODE_ADD_FIXED:
|
|
// Add using texture or fixed alpha.
|
|
if(bl && _su)
|
|
{
|
|
ordt[(int)s_id] = GX_TEXCOORD0;
|
|
ordm[(int)s_id] = GX_TEX_DISABLE;
|
|
ordc[(int)s_id] = GX_COLOR_NULL;
|
|
ord[(int)s_id] = true;
|
|
}
|
|
|
|
if(bl && _su) GX::SetTevAlphaInOpSwap( s_id, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_APREV,
|
|
GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV,
|
|
GX_TEV_SWAP0, GX_TEV_SWAP0 );
|
|
|
|
if(bl && _su) GX::SetTevColorInOp( s_id, GX_CC_ZERO, newc, newca, GX_CC_CPREV,
|
|
GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV );
|
|
|
|
stage_id++;
|
|
break;
|
|
case vBLEND_MODE_SUBTRACT:
|
|
case vBLEND_MODE_SUB_FIXED:
|
|
// Subtract using texture or fixed alpha.
|
|
if(bl && _su)
|
|
{
|
|
ordt[(int)s_id] = GX_TEXCOORD0;
|
|
ordm[(int)s_id] = GX_TEX_DISABLE;
|
|
ordc[(int)s_id] = GX_COLOR_NULL;
|
|
ord[(int)s_id] = true;
|
|
}
|
|
|
|
if(bl && _su) GX::SetTevAlphaInOpSwap( s_id, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_APREV,
|
|
GX_TEV_SUB, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV,
|
|
GX_TEV_SWAP0, GX_TEV_SWAP0 );
|
|
if(bl && _su) GX::SetTevColorInOp ( s_id, GX_CC_ZERO, newc, newca, GX_CC_CPREV,
|
|
GX_TEV_SUB, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV );
|
|
stage_id++;
|
|
break;
|
|
case vBLEND_MODE_BLEND:
|
|
case vBLEND_MODE_BLEND_FIXED:
|
|
// Blend using texture or fixed alpha.
|
|
if(bl && _su)
|
|
{
|
|
ordt[(int)s_id] = GX_TEXCOORD0;
|
|
ordm[(int)s_id] = GX_TEX_DISABLE;
|
|
ordc[(int)s_id] = GX_COLOR_NULL;
|
|
ord[(int)s_id] = true;
|
|
}
|
|
|
|
if(bl && _su) GX::SetTevAlphaInOpSwap( s_id, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_APREV,
|
|
GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV,
|
|
GX_TEV_SWAP0, GX_TEV_SWAP0 );
|
|
if(bl && _su) GX::SetTevColorInOp ( s_id, GX_CC_CPREV, newc, newca, GX_CC_ZERO,
|
|
GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV );
|
|
stage_id++;
|
|
break;
|
|
case vBLEND_MODE_MODULATE:
|
|
// Modulate current layer with previous layer.
|
|
if(bl && _su)
|
|
{
|
|
ordt[(int)s_id] = GX_TEXCOORD0;
|
|
ordm[(int)s_id] = GX_TEX_DISABLE;
|
|
ordc[(int)s_id] = GX_COLOR_NULL;
|
|
ord[(int)s_id] = true;
|
|
}
|
|
|
|
if(bl && _su) GX::SetTevAlphaInOpSwap( s_id, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_APREV,
|
|
GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV,
|
|
GX_TEV_SWAP0, GX_TEV_SWAP0 );
|
|
if(bl && _su) GX::SetTevColorInOp( s_id, GX_CC_ZERO, newca, GX_CC_CPREV, GX_CC_ZERO,
|
|
GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV );
|
|
stage_id++;
|
|
break;
|
|
case vBLEND_MODE_MODULATE_FIXED:
|
|
// Modulate current layer with fixed alpha.
|
|
if(bl && _su)
|
|
{
|
|
csel[(int)s_id] = (GXTevKColorSel)(((int)GX_TEV_KCSEL_K0_A)+layer_id);
|
|
asel[(int)s_id] = GX_TEV_KASEL_1;
|
|
sel[(int)s_id] = true;
|
|
}
|
|
|
|
if(bl && _su)
|
|
{
|
|
ordt[(int)s_id] = GX_TEXCOORD0;
|
|
ordm[(int)s_id] = GX_TEX_DISABLE;
|
|
ordc[(int)s_id] = GX_COLOR_NULL;
|
|
ord[(int)s_id] = true;
|
|
}
|
|
|
|
if(bl && _su) GX::SetTevAlphaInOpSwap( s_id, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_APREV,
|
|
GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV,
|
|
GX_TEV_SWAP0, GX_TEV_SWAP0 );
|
|
if(bl && _su) GX::SetTevColorInOp( s_id, GX_CC_ZERO, GX_CC_CPREV, GX_CC_KONST, GX_CC_ZERO,
|
|
GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV );
|
|
stage_id++;
|
|
break;
|
|
case vBLEND_MODE_BRIGHTEN:
|
|
// Modulate current layer with previous layer, & add current layer.
|
|
if(bl && _su)
|
|
{
|
|
ordt[(int)s_id] = GX_TEXCOORD0;
|
|
ordm[(int)s_id] = GX_TEX_DISABLE;
|
|
ordc[(int)s_id] = GX_COLOR_NULL;
|
|
ord[(int)s_id] = true;
|
|
}
|
|
|
|
if(bl && _su) GX::SetTevAlphaInOpSwap( s_id, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_APREV,
|
|
GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV,
|
|
GX_TEV_SWAP0, GX_TEV_SWAP0 );
|
|
if(bl && _su) GX::SetTevColorInOp( s_id, GX_CC_ZERO, newca, GX_CC_CPREV, GX_CC_CPREV,
|
|
GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV );
|
|
stage_id++;
|
|
break;
|
|
case vBLEND_MODE_BRIGHTEN_FIXED:
|
|
// Modulate current layer with fixed alpha, & add current layer.
|
|
if(bl && _su)
|
|
{
|
|
csel[(int)s_id] = (GXTevKColorSel)(((int)GX_TEV_KCSEL_K0_A)+layer_id);
|
|
asel[(int)s_id] = GX_TEV_KASEL_1;
|
|
sel[(int)s_id] = true;
|
|
}
|
|
|
|
if(bl && _su)
|
|
{
|
|
ordt[(int)s_id] = GX_TEXCOORD0;
|
|
ordm[(int)s_id] = GX_TEX_DISABLE;
|
|
ordc[(int)s_id] = GX_COLOR_NULL;
|
|
ord[(int)s_id] = true;
|
|
}
|
|
|
|
if(bl && _su) GX::SetTevAlphaInOpSwap( s_id, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_APREV,
|
|
GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV,
|
|
GX_TEV_SWAP0, GX_TEV_SWAP0 );
|
|
if(bl && _su) GX::SetTevColorInOp( s_id, GX_CC_ZERO, GX_CC_CPREV, GX_CC_KONST, GX_CC_CPREV,
|
|
GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV );
|
|
stage_id++;
|
|
break;
|
|
case vBLEND_MODE_BLEND_PREVIOUS_MASK:
|
|
// Blend using previous alpha value.
|
|
if(bl && _su)
|
|
{
|
|
ordt[(int)s_id] = GX_TEXCOORD0;
|
|
ordm[(int)s_id] = GX_TEX_DISABLE;
|
|
ordc[(int)s_id] = GX_COLOR_NULL;
|
|
ord[(int)s_id] = true;
|
|
}
|
|
|
|
if(bl && _su) GX::SetTevAlphaInOpSwap( s_id, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_APREV,
|
|
GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV,
|
|
GX_TEV_SWAP0, GX_TEV_SWAP0 );
|
|
if(bl && _su) GX::SetTevColorInOp ( s_id, GX_CC_CPREV, newc, newca, GX_CC_ZERO,
|
|
GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV );
|
|
stage_id++;
|
|
break;
|
|
case vBLEND_MODE_BLEND_INVERSE_PREVIOUS_MASK:
|
|
// Blend using previous alpha value.
|
|
if(bl && _su)
|
|
{
|
|
ordt[(int)s_id] = GX_TEXCOORD0;
|
|
ordm[(int)s_id] = GX_TEX_DISABLE;
|
|
ordc[(int)s_id] = GX_COLOR_NULL;
|
|
ord[(int)s_id] = true;
|
|
}
|
|
|
|
if(bl && _su) GX::SetTevAlphaInOpSwap( s_id, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_APREV,
|
|
GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV,
|
|
GX_TEV_SWAP0, GX_TEV_SWAP0 );
|
|
if(bl && _su) GX::SetTevColorInOp ( s_id, newc, GX_CC_CPREV, newca, GX_CC_ZERO,
|
|
GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV );
|
|
stage_id++;
|
|
break;
|
|
case vBLEND_MODE_DIFFUSE:
|
|
default:
|
|
// Replace with this texture. Shouldn't ever be used, but here for compatibility.
|
|
if(bl && _su)
|
|
{
|
|
ordt[(int)s_id] = GX_TEXCOORD0;
|
|
ordm[(int)s_id] = GX_TEX_DISABLE;
|
|
ordc[(int)s_id] = GX_COLOR_NULL;
|
|
ord[(int)s_id] = true;
|
|
}
|
|
|
|
if(bl && _su) GX::SetTevAlphaInOpSwap( s_id, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_APREV,
|
|
GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV,
|
|
GX_TEV_SWAP0, GX_TEV_SWAP0 );
|
|
if(bl && _su) GX::SetTevColorInOp( s_id, newc, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO,
|
|
GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV );
|
|
stage_id++;
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void multi_add_texture ( sTexture * p_texture, GXColor matcol, GXTexWrapMode umode, GXTexWrapMode vmode, BlendModes blendmode, int fix, float k, float shininess, uint8 flags, int layer, bool ignore_alpha, bool bl, bool tx )
|
|
{
|
|
// Mesh
|
|
GXTexCoordID u_id = (GXTexCoordID)(((int)GX_TEXCOORD0)+uv_id);
|
|
|
|
if ( flags & ( (1<<1) | (1<<2) ) )
|
|
{
|
|
// Environment mapped or UV wibbled.
|
|
GXTexMtx mtx;
|
|
if ( flags & (1<<1) )
|
|
{
|
|
switch ( layer )
|
|
{
|
|
case 0:
|
|
mtx = GX_TEXMTX0;
|
|
break;
|
|
case 1:
|
|
mtx = GX_TEXMTX1;
|
|
break;
|
|
case 2:
|
|
mtx = GX_TEXMTX2;
|
|
break;
|
|
case 3:
|
|
mtx = GX_TEXMTX3;
|
|
break;
|
|
default:
|
|
mtx = GX_IDENTITY;
|
|
break;
|
|
}
|
|
|
|
|
|
// Force repeat mode for environment mapping & NRM uv generation.
|
|
umode = GX_REPEAT;
|
|
vmode = GX_REPEAT;
|
|
if(tx && _ta)
|
|
{
|
|
// defer_gen[num_defer_gen].id = u_id;
|
|
// defer_gen[num_defer_gen].type = GX_TG_MTX2x4;
|
|
// defer_gen[num_defer_gen].src = GX_TG_NRM;
|
|
// num_defer_gen++;
|
|
GX::SetTexCoordGen( u_id, GX_TG_MTX2x4, GX_TG_NRM, GX_FALSE, GX_PTIDENTITY );
|
|
texmtx[(int)u_id] = mtx;
|
|
settex = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch ( layer )
|
|
{
|
|
case 0:
|
|
mtx = GX_TEXMTX0;
|
|
break;
|
|
case 1:
|
|
mtx = GX_TEXMTX1;
|
|
break;
|
|
case 2:
|
|
mtx = GX_TEXMTX2;
|
|
break;
|
|
case 3:
|
|
mtx = GX_TEXMTX3;
|
|
break;
|
|
default:
|
|
mtx = GX_IDENTITY;
|
|
break;
|
|
}
|
|
|
|
|
|
// Use texcoords for wibbling & offset matrix.
|
|
if(tx && _ta)
|
|
{
|
|
// defer_gen[num_defer_gen].id = u_id;
|
|
// defer_gen[num_defer_gen].type = GX_TG_MTX2x4;
|
|
// defer_gen[num_defer_gen].src = (GXTexGenSrc)(((int)GX_TG_TEX0)+uv_id);
|
|
// num_defer_gen++;
|
|
GX::SetTexCoordGen( u_id, GX_TG_MTX2x4, (GXTexGenSrc)(((int)GX_TG_TEX0)+uv_tex_id), GX_FALSE, GX_PTIDENTITY );
|
|
texmtx[(int)u_id] = mtx;
|
|
settex = true;
|
|
uv_tex_id++;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Regular mapping.
|
|
if(tx && _ta)
|
|
{
|
|
// defer_gen[num_defer_gen].id = u_id;
|
|
// defer_gen[num_defer_gen].type = GX_TG_MTX2x4;
|
|
// defer_gen[num_defer_gen].src = (GXTexGenSrc)(((int)GX_TG_TEX0)+uv_id);
|
|
// num_defer_gen++;
|
|
GX::SetTexCoordGen( u_id, GX_TG_MTX2x4, (GXTexGenSrc)(((int)GX_TG_TEX0)+uv_tex_id), GX_FALSE, GX_PTIDENTITY );
|
|
texmtx[(int)u_id] = GX_IDENTITY;
|
|
settex = true;
|
|
uv_tex_id++;
|
|
}
|
|
}
|
|
uv_id++;
|
|
|
|
// Mat
|
|
if ( map_id >= 8 ) return;
|
|
|
|
#ifdef __PLAT_WN32__
|
|
unsigned char tb = 1; //( 0 << 4 ) | layer;
|
|
unsigned char ab = 1; //( 1 << 4 ) | layer;
|
|
|
|
void * p_tex_data = (void *)((tb<<16)|(tb<<8)|tb);
|
|
void * p_alpha_data = (p_texture->m_PaletteFormat & 1) ? (void *)((ab<<16)|(ab<<8)|ab) : NULL;
|
|
GXTevSwapSel alpha_swap = GX_TEV_SWAP1;
|
|
if ( (p_texture->m_PaletteFormat & 1) )
|
|
{
|
|
int channel = ( p_texture->m_PaletteFormat >> 8 ) & 255;
|
|
switch ( channel )
|
|
{
|
|
case 0:
|
|
default:
|
|
alpha_swap = GX_TEV_SWAP1; // Green
|
|
break;
|
|
case 1:
|
|
alpha_swap = GX_TEV_SWAP2; // Red
|
|
break;
|
|
case 2:
|
|
alpha_swap = GX_TEV_SWAP3; // Blue
|
|
break;
|
|
}
|
|
}
|
|
|
|
int width = p_texture->m_Width[0];
|
|
int height = p_texture->m_Height[0];
|
|
int levels = p_texture->m_MipLevels + 1;
|
|
#else
|
|
void * p_tex_data = p_texture->pTexelData;
|
|
bool has_alpha = ( p_texture->flags & NxNgc::sTexture::TEXTURE_FLAG_HAS_ALPHA ) ? true : false;
|
|
void * p_alpha_data = has_alpha ? p_texture->pAlphaData : NULL;
|
|
GXTevSwapSel alpha_swap = GX_TEV_SWAP1;
|
|
if ( has_alpha )
|
|
{
|
|
switch ( ( p_texture->flags & NxNgc::sTexture::TEXTURE_FLAG_CHANNEL_MASK ) )
|
|
{
|
|
case NxNgc::sTexture::TEXTURE_FLAG_CHANNEL_GREEN:
|
|
default:
|
|
alpha_swap = GX_TEV_SWAP1; // Green
|
|
break;
|
|
case NxNgc::sTexture::TEXTURE_FLAG_CHANNEL_RED:
|
|
alpha_swap = GX_TEV_SWAP2; // Red
|
|
break;
|
|
case NxNgc::sTexture::TEXTURE_FLAG_CHANNEL_BLUE:
|
|
alpha_swap = GX_TEV_SWAP3; // Blue
|
|
break;
|
|
}
|
|
}
|
|
int width = p_texture->ActualWidth;
|
|
int height = p_texture->ActualHeight;
|
|
int levels = p_texture->Levels;
|
|
#endif // __PLAT_WN32__
|
|
// int reg_id = tev_id; //( tev_id > 1 ) ? 1 : tev_id; //( tev_id == 3 ) ? 2 : tev_id; // CPREV, C0, C1, C0.
|
|
int reg_id = tev_id; // CPREV, C0, C1, C0.
|
|
|
|
GXTevAlphaArg rasa;
|
|
GXTevColorArg rasc;
|
|
GXTevColorArg rasca;
|
|
if ( correct_color )
|
|
{
|
|
rasa = GX_CA_A2;
|
|
rasc = GX_CC_C2;
|
|
rasca = GX_CC_A2;
|
|
}
|
|
else
|
|
{
|
|
rasa = GX_CA_RASA;
|
|
rasc = GX_CC_RASC;
|
|
rasca = GX_CC_RASA;
|
|
}
|
|
|
|
int cur_map = map_id + 1;
|
|
int alpha_map = -1;
|
|
|
|
if ( p_alpha_data )
|
|
{
|
|
switch ( blendmode )
|
|
{
|
|
case vBLEND_MODE_ADD:
|
|
case vBLEND_MODE_SUBTRACT:
|
|
case vBLEND_MODE_BLEND:
|
|
case vBLEND_MODE_BRIGHTEN:
|
|
case vBLEND_MODE_MODULATE:
|
|
case vBLEND_MODE_DIFFUSE:
|
|
if ( cur_map < 8 )
|
|
{
|
|
alpha_map = cur_map;
|
|
cur_map++;
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
// GXTexObj texObj;
|
|
// GXInitTexObj( &texObj, p_tex_data, width, height, ((GXTexFmt)p_texture->format), umode, vmode, levels > 1 ? GX_TRUE : GX_FALSE );
|
|
// if ( levels > 1 )
|
|
// {
|
|
//// if ( gMeshUseAniso && ( tev_id == 0 ) )
|
|
//// {
|
|
//// // If we're correcting the color, we also want ANISO_4.
|
|
//// GXInitTexObjLOD( &texObj, GX_LIN_MIP_LIN, GX_LINEAR, 0.0f, levels - 1, k, GX_FALSE, GX_TRUE, GX_ANISO_4 );
|
|
//// }
|
|
//// else
|
|
//// {
|
|
// GXInitTexObjLOD( &texObj, GX_LIN_MIP_LIN, GX_LINEAR, 0.0f, levels - 1, k, GX_FALSE, GX_TRUE, GX_ANISO_1 );
|
|
//// }
|
|
// }
|
|
// else
|
|
// {
|
|
// GXInitTexObjLOD( &texObj, GX_LINEAR, GX_LINEAR, 0.0f, 0.0f, k, GX_FALSE, GX_TRUE, GX_ANISO_1 );
|
|
// }
|
|
// GXLoadTexObj( &texObj, (GXTexMapID)(((int)GX_TEXMAP0)+map_id) );
|
|
// GXSetTexCoordScaleManually( u_id, GX_TRUE, width, height );
|
|
|
|
|
|
if(tx && _su)
|
|
{
|
|
void * p_td;
|
|
if ( blendmode == vBLEND_MODE_BRIGHTEN )
|
|
{
|
|
p_td = p_alpha_data;
|
|
}
|
|
else
|
|
{
|
|
p_td = p_tex_data;
|
|
}
|
|
|
|
if ( p_td )
|
|
{
|
|
#ifdef __PLAT_WN32__
|
|
g_tex_off[layer] = GDGetCurrOffset();
|
|
// printf( "\nAdded tex off: layer %d, off %d - %d %d %d %d", layer, g_tex_off[layer], _su, _tb, _tc, _ta );
|
|
#endif // __PLAT_WN32__
|
|
GX::UploadTexture( p_td,
|
|
width,
|
|
height,
|
|
#ifdef __PLAT_WN32__
|
|
/*( p_texture->m_PaletteFormat & 1 ) ? */GX_TF_CMPR/* : GX_TF_RGBA8*/,
|
|
#else
|
|
((GXTexFmt)p_texture->format),
|
|
#endif // __PLAT_WN32__
|
|
umode,
|
|
vmode,
|
|
( levels > 1 ? GX_TRUE : GX_FALSE ),
|
|
( levels > 1 ? GX_LIN_MIP_LIN : GX_LINEAR ),
|
|
GX_LINEAR,
|
|
0.0f,
|
|
( levels > 1 ? levels - 1.0f : 0.0f ),
|
|
k,
|
|
GX_FALSE,
|
|
GX_TRUE,
|
|
/*( layer == 0 ) ? GX_ANISO_2 :*/ GX_ANISO_1,
|
|
(GXTexMapID)(((int)GX_TEXMAP0)+map_id) );
|
|
}
|
|
}
|
|
|
|
if(tx && _su) GX::SetTexCoordScale( u_id, GX_TRUE, width, height );
|
|
|
|
if ( alpha_map >= 0 )
|
|
{
|
|
switch ( blendmode )
|
|
{
|
|
case vBLEND_MODE_ADD:
|
|
case vBLEND_MODE_SUBTRACT:
|
|
case vBLEND_MODE_BLEND:
|
|
case vBLEND_MODE_MODULATE:
|
|
case vBLEND_MODE_DIFFUSE:
|
|
if(tx && _su)
|
|
{
|
|
#ifdef __PLAT_WN32__
|
|
g_alpha_off[layer] = GDGetCurrOffset();
|
|
// printf( "\nAdded alp off %d - %d %d %d %d", layer, _su, _tb, _tc, _ta );
|
|
#endif // __PLAT_WN32__
|
|
GX::UploadTexture( p_alpha_data,
|
|
width,
|
|
height,
|
|
#ifdef __PLAT_WN32__
|
|
/*( p_texture->m_PaletteFormat & 1 ) ? */GX_TF_CMPR/* : GX_TF_RGBA8*/,
|
|
#else
|
|
((GXTexFmt)p_texture->format),
|
|
#endif // __PLAT_WN32__
|
|
umode,
|
|
vmode,
|
|
( levels > 1 ? GX_TRUE : GX_FALSE ),
|
|
( levels > 1 ? GX_LIN_MIP_LIN : GX_LINEAR ),
|
|
GX_LINEAR,
|
|
0.0f,
|
|
( levels > 1 ? levels - 1.0f : 0.0f ),
|
|
k,
|
|
GX_FALSE,
|
|
GX_TRUE,
|
|
/*( layer == 0 ) ? GX_ANISO_2 :*/ GX_ANISO_1,
|
|
(GXTexMapID)(((int)GX_TEXMAP0)+alpha_map) );
|
|
}
|
|
|
|
//if(tx && _su) GX::SetTexCoordScale( u_id, GX_TRUE, width, height );
|
|
break;
|
|
default:
|
|
p_alpha_data = NULL;
|
|
break;
|
|
}
|
|
}
|
|
|
|
GXTexMapID t_id = (GXTexMapID)(((int)GX_TEXMAP0)+map_id);
|
|
GXTevStageID s_id = (GXTevStageID)(((int)GX_TEVSTAGE0)+stage_id);
|
|
|
|
GXColor col;
|
|
if ( blendmode == vBLEND_MODE_BRIGHTEN_FIXED )
|
|
{
|
|
col.r = fix;
|
|
col.g = fix;
|
|
col.b = fix;
|
|
col.a = fix;
|
|
}
|
|
else
|
|
{
|
|
if ( ( blendmode == vBLEND_MODE_BRIGHTEN ) & !p_alpha_data )
|
|
{
|
|
col.r = 255;
|
|
col.g = 255;
|
|
col.b = 255;
|
|
col.a = 255;
|
|
}
|
|
else
|
|
{
|
|
col.r = matcol.r;
|
|
col.g = matcol.g;
|
|
col.b = matcol.b;
|
|
col.a = fix;
|
|
}
|
|
}
|
|
|
|
// Modulate material color.
|
|
GXTevColorArg color_source = rasc;
|
|
GXTevScale color_scale = GX_CS_SCALE_2;
|
|
switch ( blendmode )
|
|
{
|
|
case vBLEND_MODE_BRIGHTEN_FIXED:
|
|
if(tx && _su) GX::SetTevKColor( (GXTevKColorID)(((int)GX_KCOLOR0)+tev_id), col );
|
|
if(bl && _su)
|
|
{
|
|
csel[(int)s_id] = (GXTevKColorSel)(((int)GX_TEV_KCSEL_K0)+tev_id);
|
|
asel[(int)s_id] = GX_TEV_KASEL_1;
|
|
sel[(int)s_id] = true;
|
|
}
|
|
|
|
if(bl && _su)
|
|
{
|
|
ordt[(int)s_id] = GX_TEXCOORD0;
|
|
ordm[(int)s_id] = GX_TEX_DISABLE;
|
|
ordc[(int)s_id] = GX_COLOR0A0;
|
|
ord[(int)s_id] = true;
|
|
}
|
|
|
|
if(bl && _su) GX::SetTevAlphaInOpSwap( s_id, GX_CA_ZERO, rasa, GX_CA_KONST, GX_CA_ZERO,
|
|
GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, (GXTevRegID)(((int)GX_TEVPREV)+reg_id),
|
|
GX_TEV_SWAP0, GX_TEV_SWAP0 );
|
|
if(bl && _su) GX::SetTevColorInOp( s_id, GX_CC_ZERO, rasca, GX_CC_KONST, GX_CC_ZERO,
|
|
GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, (GXTevRegID)(((int)GX_TEVPREV)+reg_id) );
|
|
color_source = (GXTevColorArg)(((int)GX_CC_CPREV)+(reg_id*2));
|
|
color_scale = GX_CS_SCALE_2;
|
|
stage_id++;
|
|
s_id = (GXTevStageID)(((int)GX_TEVSTAGE0)+stage_id);
|
|
break;
|
|
case vBLEND_MODE_BRIGHTEN:
|
|
{
|
|
GXTevSwapSel aa;
|
|
|
|
#ifdef __PLAT_WN32__
|
|
int channel = ( p_texture->m_PaletteFormat >> 8 ) & 255;
|
|
switch ( channel )
|
|
{
|
|
case 0:
|
|
default:
|
|
aa = GX_TEV_SWAP1; // Green
|
|
break;
|
|
case 1:
|
|
aa = GX_TEV_SWAP2; // Blue
|
|
break;
|
|
case 2:
|
|
aa = GX_TEV_SWAP3; // Red
|
|
break;
|
|
}
|
|
#else
|
|
switch ( ( p_texture->flags & NxNgc::sTexture::TEXTURE_FLAG_CHANNEL_MASK ) )
|
|
{
|
|
case NxNgc::sTexture::TEXTURE_FLAG_CHANNEL_GREEN:
|
|
default:
|
|
aa = GX_TEV_SWAP1; // Green
|
|
break;
|
|
case NxNgc::sTexture::TEXTURE_FLAG_CHANNEL_RED:
|
|
aa = GX_TEV_SWAP2; // Blue
|
|
break;
|
|
case NxNgc::sTexture::TEXTURE_FLAG_CHANNEL_BLUE:
|
|
aa = GX_TEV_SWAP3; // Red
|
|
break;
|
|
}
|
|
#endif // __PLAT_WN32__
|
|
|
|
if ( p_alpha_data )
|
|
{
|
|
if(bl && _su)
|
|
{
|
|
ordt[(int)s_id] = u_id;
|
|
ordm[(int)s_id] = t_id;
|
|
ordc[(int)s_id] = GX_COLOR0A0;
|
|
ord[(int)s_id] = true;
|
|
}
|
|
|
|
if(bl && _su) GX::SetTevAlphaInOpSwap( s_id, GX_CA_ZERO, rasa, GX_CA_TEXA, GX_CA_ZERO,
|
|
GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_2, GX_ENABLE, (GXTevRegID)(((int)GX_TEVPREV)+reg_id),
|
|
GX_TEV_SWAP0, aa );
|
|
if(bl && _su) GX::SetTevColorInOp( s_id, GX_CC_ZERO, rasca, GX_CC_TEXC, GX_CC_ZERO,
|
|
GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_2, GX_ENABLE, (GXTevRegID)(((int)GX_TEVPREV)+reg_id) );
|
|
}
|
|
else
|
|
{
|
|
// No alpha, need to do same as BRIGHTEN_FIXED, but with a fix of 1.
|
|
if(tx && _su) GX::SetTevKColor( (GXTevKColorID)(((int)GX_KCOLOR0)+tev_id), col );
|
|
if(bl && _su)
|
|
{
|
|
csel[(int)s_id] = (GXTevKColorSel)(((int)GX_TEV_KCSEL_K0)+tev_id);
|
|
asel[(int)s_id] = GX_TEV_KASEL_1;
|
|
sel[(int)s_id] = true;
|
|
}
|
|
|
|
if(bl && _su)
|
|
{
|
|
ordt[(int)s_id] = GX_TEXCOORD0;
|
|
ordm[(int)s_id] = GX_TEX_DISABLE;
|
|
ordc[(int)s_id] = GX_COLOR0A0;
|
|
ord[(int)s_id] = true;
|
|
}
|
|
|
|
if(bl && _su) GX::SetTevAlphaInOpSwap( s_id, GX_CA_ZERO, rasa, GX_CA_KONST, GX_CA_ZERO,
|
|
GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, (GXTevRegID)(((int)GX_TEVPREV)+reg_id),
|
|
GX_TEV_SWAP0, GX_TEV_SWAP0 );
|
|
if(bl && _su) GX::SetTevColorInOp( s_id, GX_CC_ZERO, rasca, GX_CC_KONST, GX_CC_ZERO,
|
|
GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, (GXTevRegID)(((int)GX_TEVPREV)+reg_id) );
|
|
}
|
|
}
|
|
color_source = (GXTevColorArg)(((int)GX_CC_CPREV)+(reg_id*2));
|
|
color_scale = GX_CS_SCALE_2;
|
|
stage_id++;
|
|
s_id = (GXTevStageID)(((int)GX_TEVSTAGE0)+stage_id);
|
|
break;
|
|
default:
|
|
if ( alpha_map >= 0 )
|
|
{
|
|
if(tx && _su) GX::SetTevKColor( (GXTevKColorID)(((int)GX_KCOLOR0)+tev_id), col );
|
|
if(bl && _su)
|
|
{
|
|
csel[(int)s_id] = (GXTevKColorSel)(((int)GX_TEV_KCSEL_K0)+tev_id);
|
|
asel[(int)s_id] = GX_TEV_KASEL_1;
|
|
sel[(int)s_id] = true;
|
|
}
|
|
GXTexMapID a_id = (GXTexMapID)(((int)GX_TEXMAP0)+alpha_map);
|
|
if(bl && _su)
|
|
{
|
|
ordt[(int)s_id] = u_id;
|
|
ordm[(int)s_id] = a_id;
|
|
ordc[(int)s_id] = GX_COLOR0A0;
|
|
ord[(int)s_id] = true;
|
|
}
|
|
|
|
if(bl && _su) GX::SetTevAlphaInOpSwap( s_id, GX_CA_TEXA, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO,
|
|
GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, (GXTevRegID)(((int)GX_TEVPREV)+reg_id),
|
|
GX_TEV_SWAP0, alpha_swap );
|
|
if(bl && _su) GX::SetTevColorInOp( s_id, GX_CC_ZERO, rasc, GX_CC_KONST, GX_CC_ZERO,
|
|
GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_4, GX_ENABLE, (GXTevRegID)(((int)GX_TEVPREV)+reg_id) );
|
|
color_source = (GXTevColorArg)(((int)GX_CC_CPREV)+(reg_id*2));
|
|
color_scale = GX_CS_SCALE_2;
|
|
stage_id++;
|
|
s_id = (GXTevStageID)(((int)GX_TEVSTAGE0)+stage_id);
|
|
}
|
|
else
|
|
{
|
|
if ( ( col.r != 128 ) || ( col.g != 128 ) || ( col.b != 128 ) )
|
|
{
|
|
// Unique material color.
|
|
if(tx && _su) GX::SetTevKColor( (GXTevKColorID)(((int)GX_KCOLOR0)+tev_id), col );
|
|
if(bl && _su)
|
|
{
|
|
csel[(int)s_id] = (GXTevKColorSel)(((int)GX_TEV_KCSEL_K0)+tev_id);
|
|
asel[(int)s_id] = GX_TEV_KASEL_1;
|
|
sel[(int)s_id] = true;
|
|
}
|
|
if(bl && _su)
|
|
{
|
|
ordt[(int)s_id] = GX_TEXCOORD0;
|
|
ordm[(int)s_id] = GX_TEX_DISABLE;
|
|
ordc[(int)s_id] = GX_COLOR0A0;
|
|
ord[(int)s_id] = true;
|
|
}
|
|
|
|
if(bl && _su) GX::SetTevAlphaInOpSwap( s_id, rasa, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO,
|
|
GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, (GXTevRegID)(((int)GX_TEVPREV)+reg_id),
|
|
GX_TEV_SWAP0, GX_TEV_SWAP0 );
|
|
if(bl && _su) GX::SetTevColorInOp( s_id, GX_CC_ZERO, rasc, GX_CC_KONST, GX_CC_ZERO,
|
|
GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_4, GX_ENABLE, (GXTevRegID)(((int)GX_TEVPREV)+reg_id) );
|
|
color_source = (GXTevColorArg)(((int)GX_CC_CPREV)+(reg_id*2));
|
|
color_scale = GX_CS_SCALE_2;
|
|
stage_id++;
|
|
s_id = (GXTevStageID)(((int)GX_TEVSTAGE0)+stage_id);
|
|
}
|
|
else
|
|
{
|
|
// No need for material color stage.
|
|
color_source = rasc;
|
|
color_scale = GX_CS_SCALE_4;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
// Set texture coordinates. Note: If p_tex is NULL, it means this layer is environment mapped.
|
|
// if ( !(flags & MATFLAG_ENVIRONMENT) )
|
|
// {
|
|
//*p_uv_slot = uv_id;
|
|
// uv_id++;
|
|
// } else {
|
|
// *p_uv_slot = -1;
|
|
// }
|
|
|
|
// Load this texture up into a temporary register for use later.
|
|
// Note: conveniently, the 1st texture ends up in TEVPREV which means it will be fine
|
|
// if no blends are performed.
|
|
switch ( blendmode )
|
|
{
|
|
case vBLEND_MODE_BRIGHTEN:
|
|
case vBLEND_MODE_BRIGHTEN_FIXED:
|
|
// Just pass it on through...
|
|
break;
|
|
case vBLEND_MODE_ADD_FIXED:
|
|
case vBLEND_MODE_SUB_FIXED:
|
|
case vBLEND_MODE_BLEND_FIXED:
|
|
case vBLEND_MODE_MODULATE_FIXED:
|
|
// If we didn't upload with the material color, upload here.
|
|
if ( color_source == rasc )
|
|
{
|
|
if(tx && _su) GX::SetTevKColor( (GXTevKColorID)(((int)GX_KCOLOR0)+tev_id), col );
|
|
}
|
|
if(bl && _su)
|
|
{
|
|
csel[(int)s_id] = GX_TEV_KCSEL_1;
|
|
asel[(int)s_id] = (GXTevKAlphaSel)(((int)GX_TEV_KASEL_K0_A)+tev_id);
|
|
sel[(int)s_id] = true;
|
|
}
|
|
|
|
if(bl && _su)
|
|
{
|
|
ordt[(int)s_id] = u_id;
|
|
ordm[(int)s_id] = t_id;
|
|
ordc[(int)s_id] = GX_COLOR0A0;
|
|
ord[(int)s_id] = true;
|
|
}
|
|
|
|
if ( ignore_alpha )
|
|
{
|
|
if(bl && _su) GX::SetTevAlphaInOpSwap( s_id, GX_CA_KONST, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO,
|
|
GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_2, GX_ENABLE, (GXTevRegID)(((int)GX_TEVPREV)+reg_id),
|
|
GX_TEV_SWAP0, GX_TEV_SWAP0 );
|
|
}
|
|
else
|
|
{
|
|
if(bl && _su) GX::SetTevAlphaInOpSwap( s_id, GX_CA_ZERO, GX_CA_KONST, rasa, GX_CA_ZERO,
|
|
GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_4, GX_ENABLE, (GXTevRegID)(((int)GX_TEVPREV)+reg_id),
|
|
GX_TEV_SWAP0, GX_TEV_SWAP0 );
|
|
}
|
|
if(bl && _su) GX::SetTevColorInOp( s_id, GX_CC_ZERO, GX_CC_TEXC, color_source, GX_CC_ZERO,
|
|
GX_TEV_ADD, GX_TB_ZERO, color_scale, GX_ENABLE, (GXTevRegID)(((int)GX_TEVPREV)+reg_id) );
|
|
stage_id++;
|
|
break;
|
|
case vBLEND_MODE_BLEND_PREVIOUS_MASK:
|
|
case vBLEND_MODE_BLEND_INVERSE_PREVIOUS_MASK:
|
|
if(bl && _su)
|
|
{
|
|
ordt[(int)s_id] = u_id;
|
|
ordm[(int)s_id] = t_id;
|
|
ordc[(int)s_id] = GX_COLOR0A0;
|
|
ord[(int)s_id] = true;
|
|
}
|
|
|
|
if(bl && _su) GX::SetTevAlphaInOpSwap( s_id, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, (GXTevAlphaArg)(((int)GX_CA_APREV)+(reg_id-1)),
|
|
GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, (GXTevRegID)(((int)GX_TEVPREV)+reg_id),
|
|
GX_TEV_SWAP0, GX_TEV_SWAP0 );
|
|
if(bl && _su) GX::SetTevColorInOp( s_id, GX_CC_ZERO, GX_CC_TEXC, color_source, GX_CC_ZERO,
|
|
GX_TEV_ADD, GX_TB_ZERO, color_scale, GX_ENABLE, (GXTevRegID)(((int)GX_TEVPREV)+reg_id) );
|
|
stage_id++;
|
|
break;
|
|
case vBLEND_MODE_ADD:
|
|
case vBLEND_MODE_SUBTRACT:
|
|
case vBLEND_MODE_BLEND:
|
|
case vBLEND_MODE_MODULATE:
|
|
case vBLEND_MODE_DIFFUSE:
|
|
default:
|
|
// We need to add a stage, if we have an alpha map.
|
|
if ( ( alpha_map >= 0 )/* && ( blendmode != vBLEND_MODE_DIFFUSE )*/ )
|
|
{
|
|
// // Set inputs.
|
|
// GXTexMapID a_id = (GXTexMapID)(((int)GX_TEXMAP0)+alpha_map);
|
|
//
|
|
// if(bl && _su)
|
|
// {
|
|
// ordt[(int)s_id] = u_id;
|
|
// ordm[(int)s_id] = a_id;
|
|
// ordc[(int)s_id] = GX_COLOR0A0;
|
|
// ord[(int)s_id] = true;
|
|
// }
|
|
//
|
|
// if ( ignore_alpha )
|
|
// {
|
|
// if(bl && _su) GX::SetTevAlphaInOpSwap( s_id, GX_CA_TEXA, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO,
|
|
// GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, (GXTevRegID)(((int)GX_TEVPREV)+reg_id),
|
|
// GX_TEV_SWAP0, alpha_swap ); // Alpha map is in Green/Red/Blue channel, so use this to swap it to the alpha channel.
|
|
// }
|
|
// else
|
|
// {
|
|
// if(bl && _su) GX::SetTevAlphaInOpSwap( s_id, GX_CA_ZERO, GX_CA_TEXA, rasa, GX_CA_ZERO,
|
|
// GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_2, GX_ENABLE, (GXTevRegID)(((int)GX_TEVPREV)+reg_id),
|
|
// GX_TEV_SWAP0, alpha_swap ); // Alpha map is in Green/Red/Blue channel, so use this to swap it to the alpha channel.
|
|
// }
|
|
// if(bl && _su) GX::SetTevColorInOp( s_id, (GXTevColorArg)(((int)GX_CC_CPREV)+(reg_id*2)), GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO,
|
|
// GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, (GXTevRegID)(((int)GX_TEVPREV)+reg_id) );
|
|
// stage_id++;
|
|
// s_id = (GXTevStageID)(((int)GX_TEVSTAGE0)+stage_id);
|
|
|
|
if(bl && _su)
|
|
{
|
|
ordt[(int)s_id] = u_id;
|
|
ordm[(int)s_id] = t_id;
|
|
ordc[(int)s_id] = GX_COLOR0A0;
|
|
ord[(int)s_id] = true;
|
|
}
|
|
|
|
if ( ignore_alpha )
|
|
{
|
|
if(bl && _su) GX::SetTevAlphaInOpSwap( s_id, (GXTevAlphaArg)(((int)GX_CA_APREV)+reg_id), GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO,
|
|
GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, (GXTevRegID)(((int)GX_TEVPREV)+reg_id),
|
|
GX_TEV_SWAP0, GX_TEV_SWAP0 ); // Alpha map is in Green/Red/Blue channel, so use this to swap it to the alpha channel.
|
|
}
|
|
else
|
|
{
|
|
if(bl && _su) GX::SetTevAlphaInOpSwap( s_id, GX_CA_ZERO, (GXTevAlphaArg)(((int)GX_CA_APREV)+reg_id), rasa, GX_CA_ZERO,
|
|
GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_2, GX_ENABLE, (GXTevRegID)(((int)GX_TEVPREV)+reg_id),
|
|
GX_TEV_SWAP0, GX_TEV_SWAP0 ); // Alpha map is in Green/Red/Blue channel, so use this to swap it to the alpha channel.
|
|
}
|
|
|
|
//// if(bl && _su) GX::SetTevAlphaInOpSwap( s_id, (GXTevAlphaArg)(((int)GX_CA_APREV)+reg_id), GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO,
|
|
//// if(bl && _su) GX::SetTevAlphaInOpSwap( s_id, GX_CA_ZERO, (GXTevAlphaArg)(((int)GX_CA_APREV)+reg_id), GX_CA_TEXA, GX_CA_ZERO,
|
|
// if(bl && _su) GX::SetTevAlphaInOpSwap( s_id, (GXTevAlphaArg)(((int)GX_CA_APREV)+reg_id), GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO,
|
|
// GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, (GXTevRegID)(((int)GX_TEVPREV)+reg_id),
|
|
// GX_TEV_SWAP0, GX_TEV_SWAP0 );
|
|
if(bl && _su) GX::SetTevColorInOp( s_id, GX_CC_ZERO, GX_CC_TEXC, color_source, GX_CC_ZERO,
|
|
GX_TEV_ADD, GX_TB_ZERO, color_scale, GX_ENABLE, (GXTevRegID)(((int)GX_TEVPREV)+reg_id) );
|
|
stage_id++;
|
|
} else {
|
|
if(bl && _su)
|
|
{
|
|
ordt[(int)s_id] = u_id;
|
|
ordm[(int)s_id] = t_id;
|
|
ordc[(int)s_id] = GX_COLOR0A0;
|
|
ord[(int)s_id] = true;
|
|
}
|
|
|
|
if ( ignore_alpha )
|
|
{
|
|
if(bl && _su) GX::SetTevAlphaInOpSwap( s_id, GX_CA_TEXA, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO,
|
|
GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, (GXTevRegID)(((int)GX_TEVPREV)+reg_id),
|
|
GX_TEV_SWAP0, GX_TEV_SWAP0 );
|
|
}
|
|
else
|
|
{
|
|
if(bl && _su) GX::SetTevAlphaInOpSwap( s_id, GX_CA_ZERO, GX_CA_TEXA, rasa, GX_CA_ZERO,
|
|
GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_2, GX_ENABLE, (GXTevRegID)(((int)GX_TEVPREV)+reg_id),
|
|
GX_TEV_SWAP0, GX_TEV_SWAP0 );
|
|
}
|
|
if(bl && _su) GX::SetTevColorInOp( s_id, GX_CC_ZERO, GX_CC_TEXC, color_source, GX_CC_ZERO,
|
|
GX_TEV_ADD, GX_TB_ZERO, color_scale, GX_ENABLE, (GXTevRegID)(((int)GX_TEVPREV)+reg_id) );
|
|
stage_id++;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
// if ( shininess > 0 )
|
|
// {
|
|
// GXTevStageID s_id = (GXTevStageID)(((int)GX_TEVSTAGE0)+stage_id);
|
|
//
|
|
// // Need to add in specular component.
|
|
// if(bl && _su)
|
|
// {
|
|
// ordt[(int)s_id] = GX_TEXCOORD0;
|
|
// ordm[(int)s_id] = GX_TEX_DISABLE;
|
|
// ordc[(int)s_id] = GX_COLOR1A1;
|
|
// ord[(int)s_id] = true;
|
|
// }
|
|
// if(bl && _su) GX::SetTevAlphaInOpSwap( s_id, (GXTevAlphaArg)(((int)GX_CA_APREV)+reg_id), GX_CA_ZERO, GX_CA_ZERO, GX_CA_RASA,
|
|
// GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, (GXTevRegID)(((int)GX_TEVPREV)+reg_id),
|
|
// GX_TEV_SWAP0, GX_TEV_SWAP0 );
|
|
// if(bl && _su) GX::SetTevColorInOp( s_id, (GXTevColorArg)(((int)GX_CC_CPREV)+(reg_id*2)), GX_CC_ZERO, GX_CC_ZERO, GX_CC_RASC,
|
|
// GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, (GXTevRegID)(((int)GX_TEVPREV)+reg_id) );
|
|
// stage_id++;
|
|
// }
|
|
|
|
if ( tev_id > 0 ) {
|
|
multi_add_layer ( blendmode, fix, bl, tx );
|
|
} else {
|
|
// Set blend mode for base layer.
|
|
switch ( blendmode )
|
|
{
|
|
case vBLEND_MODE_ADD:
|
|
case vBLEND_MODE_ADD_FIXED:
|
|
if(bl && _su) GX::SetBlendMode( GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_ONE, GX_LO_CLEAR, GX_TRUE, GX_FALSE, GX_TRUE );
|
|
break;
|
|
case vBLEND_MODE_SUBTRACT:
|
|
case vBLEND_MODE_SUB_FIXED:
|
|
if(bl && _su) GX::SetBlendMode( GX_BM_SUBTRACT, GX_BL_ZERO, GX_BL_ZERO, GX_LO_CLEAR, GX_TRUE, GX_FALSE, GX_TRUE );
|
|
break;
|
|
case vBLEND_MODE_BLEND:
|
|
case vBLEND_MODE_BLEND_FIXED:
|
|
if(bl && _su) GX::SetBlendMode( GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR, GX_TRUE, GX_FALSE, GX_TRUE );
|
|
break;
|
|
case vBLEND_MODE_BRIGHTEN:
|
|
case vBLEND_MODE_BRIGHTEN_FIXED:
|
|
if(bl && _su) GX::SetBlendMode( GX_BM_BLEND, GX_BL_DSTCLR, GX_BL_ONE, GX_LO_CLEAR, GX_TRUE, GX_FALSE, GX_TRUE );
|
|
break;
|
|
case vBLEND_MODE_MODULATE_FIXED:
|
|
case vBLEND_MODE_MODULATE:
|
|
if(bl && _su) GX::SetBlendMode( GX_BM_BLEND, GX_BL_ZERO, GX_BL_SRCALPHA, GX_LO_CLEAR, GX_TRUE, GX_FALSE, GX_TRUE );
|
|
break;
|
|
case vBLEND_MODE_BLEND_PREVIOUS_MASK:
|
|
case vBLEND_MODE_BLEND_INVERSE_PREVIOUS_MASK:
|
|
case vBLEND_MODE_DIFFUSE:
|
|
default:
|
|
if(bl && _su) GX::SetBlendMode( GX_BM_NONE, GX_BL_ONE, GX_BL_ONE, GX_LO_CLEAR, GX_TRUE, GX_FALSE, GX_TRUE );
|
|
break;
|
|
}
|
|
}
|
|
layer_id++;
|
|
|
|
tev_id++;
|
|
map_id = cur_map;
|
|
#ifdef __PLAT_WN32__
|
|
g_num_tex = map_id;
|
|
#endif // __PLAT_WN32__
|
|
}
|
|
|
|
static void multi_end ( BlendModes blendmode, uint8 pass_flags, uint8 has_holes, uint8 alphacutoff, uint8 flags, bool bl, bool tx, bool cull )
|
|
{
|
|
int color_channels;
|
|
if ( correct_color )
|
|
{
|
|
GXTexCoordID u_id;
|
|
// Convert color0 to s,t for 2-D texture lookup (RG)
|
|
u_id = (GXTexCoordID)(((int)GX_TEXCOORD0)+uv_id);
|
|
if(tx && _ta) GX::SetTexCoordGen( u_id, GX_TG_SRTG, GX_TG_COLOR0, GX_FALSE, GX_PTIDENTITY );
|
|
if(tx && _su) GX::SetTexCoordScale( u_id, GX_TRUE, 64, 64 );
|
|
|
|
if(bl && _su)
|
|
{
|
|
ordt[(int)GX_TEVSTAGE0] = u_id;
|
|
ordm[(int)GX_TEVSTAGE0] = GX_TEXMAP7;
|
|
ordc[(int)GX_TEVSTAGE0] = GX_COLOR_NULL;
|
|
ord[(int)GX_TEVSTAGE0] = true;
|
|
}
|
|
|
|
uv_id++;
|
|
|
|
// Convert color1 to s,t for 2-D texture lookup (BA)
|
|
u_id = (GXTexCoordID)(((int)GX_TEXCOORD0)+uv_id);
|
|
if(tx && _ta) GX::SetTexCoordGen( u_id, GX_TG_SRTG, GX_TG_COLOR1, GX_FALSE, GX_PTIDENTITY );
|
|
if(tx && _su) GX::SetTexCoordScale( u_id, GX_TRUE, 64, 64 );
|
|
|
|
if(bl && _su)
|
|
{
|
|
ordt[(int)GX_TEVSTAGE1] = u_id;
|
|
ordm[(int)GX_TEVSTAGE1] = GX_TEXMAP7;
|
|
ordc[(int)GX_TEVSTAGE1] = GX_COLOR_NULL;
|
|
ord[(int)GX_TEVSTAGE1] = true;
|
|
}
|
|
|
|
uv_id++;
|
|
color_channels = 2;
|
|
}
|
|
else
|
|
{
|
|
color_channels = 1;
|
|
}
|
|
|
|
|
|
|
|
// Alpha cutoff.
|
|
if ( tx && _su ) GX::SetAlphaCompare(GX_GEQUAL, alphacutoff, GX_AOP_AND, GX_GEQUAL, alphacutoff );
|
|
// if ( tx ) GX::SetZCompLoc( has_holes ? GX_FALSE : GX_TRUE );
|
|
|
|
// Special case. If the base layer uses subtractive mode, we need to add a stage to
|
|
// modulate the color & alpha.
|
|
switch ( blendmode )
|
|
{
|
|
case vBLEND_MODE_SUB_FIXED:
|
|
case vBLEND_MODE_SUBTRACT:
|
|
{
|
|
GXTevStageID s_id = (GXTevStageID)(((int)GX_TEVSTAGE0)+stage_id);
|
|
|
|
if(bl && _su)
|
|
{
|
|
ordt[(int)s_id] = GX_TEXCOORD0;
|
|
ordm[(int)s_id] = GX_TEX_DISABLE;
|
|
ordc[(int)s_id] = GX_COLOR_NULL;
|
|
ord[(int)s_id] = true;
|
|
}
|
|
|
|
if(bl && _su) GX::SetTevAlphaInOpSwap( s_id, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_APREV,
|
|
GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV,
|
|
GX_TEV_SWAP0, GX_TEV_SWAP0 );
|
|
if(bl && _su) GX::SetTevColorInOp( s_id, GX_CC_ZERO, GX_CC_CPREV, GX_CC_APREV, GX_CC_ZERO,
|
|
GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV );
|
|
stage_id++;
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
// if ( blendmode == vBLEND_MODE_DIFFUSE )
|
|
// {
|
|
// //Always pass pixels with multi-texturing as the base must be opaque.
|
|
// GXSetAlphaCompare(GX_GEQUAL, 0, GX_AOP_AND, GX_GEQUAL, 0 );
|
|
// GXSetZCompLoc( GX_TRUE );
|
|
// }
|
|
// else
|
|
// {
|
|
// }
|
|
|
|
// if ( correct_color )
|
|
// {
|
|
// GXTexCoordID u_id;
|
|
// // Convert color0 to s,t for 2-D texture lookup (RG)
|
|
// u_id = (GXTexCoordID)(((int)GX_TEXCOORD0)+uv_id);
|
|
// GXSetTexCoordGen(u_id, GX_TG_SRTG, GX_TG_COLOR0, GX_IDENTITY);
|
|
// GXSetTevOrder(GX_TEVSTAGE0, u_id, GX_TEXMAP7, GX_COLOR_NULL);
|
|
// uv_id++;
|
|
//
|
|
// // Convert color1 to s,t for 2-D texture lookup (BA)
|
|
// u_id = (GXTexCoordID)(((int)GX_TEXCOORD0)+uv_id);
|
|
// GXSetTexCoordGen(u_id, GX_TG_SRTG, GX_TG_COLOR1, GX_IDENTITY);
|
|
// GXSetTevOrder(GX_TEVSTAGE1, u_id, GX_TEXMAP7, GX_COLOR_NULL);
|
|
// uv_id++;
|
|
// GXSetNumChans( 2 );
|
|
// }
|
|
// else
|
|
// {
|
|
// GXSetNumChans( 1 );
|
|
// }
|
|
//
|
|
// // Set final number of textures/stages.
|
|
// GXSetNumTexGens( uv_id );
|
|
// GXSetNumTevStages( stage_id );
|
|
|
|
GXCullMode cull_mode;
|
|
if ( pass_flags & (1<<3) )
|
|
{
|
|
// Semitransparent.
|
|
if ( flags & (1<<2) )
|
|
{
|
|
cull_mode = GX_CULL_FRONT;
|
|
}
|
|
else
|
|
{
|
|
cull_mode = GX_CULL_NONE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Opaque.
|
|
if ( flags & (1<<1) )
|
|
{
|
|
cull_mode = GX_CULL_NONE;
|
|
}
|
|
else
|
|
{
|
|
cull_mode = GX_CULL_FRONT;
|
|
}
|
|
}
|
|
if ( !cull )
|
|
{
|
|
cull_mode = GX_CULL_NONE;
|
|
}
|
|
|
|
//// if ( EngineGlobals.poly_culling && ( flags & (1<<1) ) )
|
|
// if ( flags & (1<<1) )
|
|
// {
|
|
// cull_mode = GX_CULL_FRONT;
|
|
// }
|
|
|
|
// if(bl && _ta) GX::SetChanCtrl( GX_COLOR0A0, GX_DISABLE, GX_SRC_VTX, GX_SRC_VTX, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE );
|
|
|
|
|
|
|
|
|
|
|
|
// Issue buffered commands.
|
|
int lp;
|
|
for ( lp = 0; lp < 16; lp += 2 )
|
|
{
|
|
if ( sel[lp] || sel[lp+1] )
|
|
{
|
|
if ( bl && _su ) GX::SetTevKSel( (GXTevStageID)lp, csel[lp], asel[lp], csel[lp+1], asel[lp+1] );
|
|
// GDSetTevKonstantSel( (GXTevStageID)lp, csel[lp], asel[lp], csel[lp+1], asel[lp+1] );
|
|
}
|
|
if ( ord[lp] || ord[lp+1] )
|
|
{
|
|
if ( bl && _su ) GX::SetTevOrder( (GXTevStageID)lp, ordt[lp], ordm[lp], ordc[lp], ordt[lp+1], ordm[lp+1], ordc[lp+1] );
|
|
// GDSetTevOrder( (GXTevStageID)lp, ordt[lp], ordm[lp], ordc[lp], ordt[lp+1], ordm[lp+1], ordc[lp+1] );
|
|
}
|
|
}
|
|
|
|
if ( settex )
|
|
{
|
|
GX::SetCurrMtxPosTex03( GX_PNMTX0, texmtx[0], texmtx[1], texmtx[2], texmtx[3] );
|
|
GX::SetCurrMtxTex47( GX_IDENTITY, GX_IDENTITY, GX_IDENTITY, GX_IDENTITY );
|
|
|
|
// GDSetCurrentMtx( GX_PNMTX0, // Will be overridden.
|
|
// texmtx[0],
|
|
// texmtx[1],
|
|
// texmtx[2],
|
|
// texmtx[3],
|
|
// texmtx[4],
|
|
// texmtx[5],
|
|
// texmtx[6],
|
|
// texmtx[7] );
|
|
}
|
|
|
|
|
|
if(bl && _ta) GX::SetTexChanTevIndCull( uv_id, color_channels, stage_id, 0, cull_mode );
|
|
// if(bl && _ta) GX::SetTexChanTevIndCull( uv_id, 1, stage_id, 0, GX_CULL_FRONT );
|
|
|
|
// for ( int lp = 0; lp < num_defer_gen; lp++ )
|
|
// {
|
|
// GX::SetTexCoordGen( defer_gen[lp].id, defer_gen[lp].type, defer_gen[lp].src, GX_FALSE, GX_PTIDENTITY );
|
|
// }
|
|
// num_defer_gen = 0;
|
|
|
|
// Clear so that subsequent flushes do nothing.
|
|
for ( lp = 0; lp < 16; lp++ )
|
|
{
|
|
asel[lp] = GX_TEV_KASEL_1;
|
|
csel[lp] = GX_TEV_KCSEL_1;
|
|
sel[lp] = false;
|
|
|
|
ordt[lp] = (GXTexCoordID)(lp&7);
|
|
ordm[lp] = (GXTexMapID)(lp&7);
|
|
ordc[lp] = GX_COLOR0A0;
|
|
ord[lp] = false;
|
|
}
|
|
|
|
for ( lp = 0; lp < 8; lp++ )
|
|
{
|
|
texmtx[lp] = GX_IDENTITY;
|
|
}
|
|
|
|
settex = false;
|
|
}
|
|
|
|
static void _multi_mesh( sMaterialHeader * p_mat, sMaterialPassHeader * p_base_pass, bool bl, bool tx, bool cull )
|
|
{
|
|
uint32 layer;
|
|
|
|
multi_start( bl, tx );
|
|
|
|
sMaterialPassHeader * p_pass = p_base_pass;
|
|
|
|
// int uv_set = 0;
|
|
|
|
int passes = p_mat->m_passes;
|
|
if ( g_mat_passes < passes )
|
|
{
|
|
if ( g_mat_passes > 0 )
|
|
{
|
|
passes = g_mat_passes;
|
|
}
|
|
}
|
|
|
|
for ( layer = 0; layer < (uint)passes; layer++, p_pass++ )
|
|
{
|
|
bool ignore_alpha = ( p_pass->m_flags & (1<<7) ) ? true : false;
|
|
|
|
GXTexWrapMode u_mode;
|
|
GXTexWrapMode v_mode;
|
|
|
|
u_mode = p_pass->m_flags & (1<<5) ? GX_CLAMP : GX_REPEAT;
|
|
v_mode = p_pass->m_flags & (1<<6) ? GX_CLAMP : GX_REPEAT;
|
|
|
|
if ( p_pass->m_texture.p_data )
|
|
{
|
|
multi_add_texture ( p_pass->m_texture.p_data,
|
|
p_pass->m_color,
|
|
u_mode,
|
|
v_mode,
|
|
(BlendModes)p_pass->m_blend_mode,
|
|
p_pass->m_alpha_fix,
|
|
(float)(p_pass->m_k) * (1.0f / (float)(1<<8)),
|
|
0.0f, //p_mat->m_shininess,
|
|
p_pass->m_flags,
|
|
layer,
|
|
ignore_alpha,
|
|
bl,
|
|
tx );
|
|
}
|
|
else
|
|
{
|
|
// Untextured.
|
|
GXTevStageID s_id = (GXTevStageID)(((int)GX_TEVSTAGE0)+stage_id);
|
|
BlendModes blend = (BlendModes)p_pass->m_blend_mode;
|
|
uint8 fix = p_pass->m_alpha_fix;
|
|
|
|
|
|
GXColor col;
|
|
if ( blend == vBLEND_MODE_BRIGHTEN_FIXED )
|
|
{
|
|
col.r = fix;
|
|
col.g = fix;
|
|
col.b = fix;
|
|
col.a = fix;
|
|
}
|
|
else
|
|
{
|
|
col.r = p_pass->m_color.r;
|
|
col.g = p_pass->m_color.g;
|
|
col.b = p_pass->m_color.b;
|
|
col.a = fix;
|
|
}
|
|
if(tx && _su) GX::SetTevKColor( (GXTevKColorID)(((int)GX_KCOLOR0)+tev_id),
|
|
col );
|
|
|
|
if(bl && _su)
|
|
{
|
|
csel[(int)s_id] = (GXTevKColorSel)(((int)GX_TEV_KCSEL_K0)+layer_id);
|
|
asel[(int)s_id] = (GXTevKAlphaSel)(((int)GX_TEV_KASEL_K0_A)+layer_id);
|
|
sel[(int)s_id] = true;
|
|
}
|
|
|
|
if(bl && _su)
|
|
{
|
|
ordt[(int)s_id] = GX_TEXCOORD0;
|
|
ordm[(int)s_id] = GX_TEX_DISABLE;
|
|
ordc[(int)s_id] = GX_COLOR0A0;
|
|
ord[(int)s_id] = true;
|
|
}
|
|
|
|
switch ( blend )
|
|
{
|
|
case vBLEND_MODE_BRIGHTEN_FIXED:
|
|
{
|
|
if(bl && _su) GX::SetTevAlphaInOpSwap( s_id, GX_CA_ZERO, GX_CA_KONST, GX_CA_RASA, GX_CA_ZERO,
|
|
GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, (GXTevRegID)(((int)GX_TEVPREV)+tev_id),
|
|
GX_TEV_SWAP0, GX_TEV_SWAP0 );
|
|
if(bl && _su) GX::SetTevColorInOp( s_id, GX_CC_ZERO, GX_CC_KONST, GX_CC_RASA, GX_CC_ZERO,
|
|
GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_2, GX_ENABLE, (GXTevRegID)(((int)GX_TEVPREV)+tev_id) );
|
|
stage_id++;
|
|
}
|
|
break;
|
|
case vBLEND_MODE_BRIGHTEN:
|
|
if(bl && _su) GX::SetTevAlphaInOpSwap( s_id, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO,
|
|
GX_TEV_ADD, GX_TB_ADDHALF, GX_CS_SCALE_2, GX_ENABLE, (GXTevRegID)(((int)GX_TEVPREV)+tev_id),
|
|
GX_TEV_SWAP0, GX_TEV_SWAP0 );
|
|
if ( ignore_alpha )
|
|
{
|
|
if(bl && _su) GX::SetTevColorInOp( s_id, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO,
|
|
GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_2, GX_ENABLE, (GXTevRegID)(((int)GX_TEVPREV)+tev_id) );
|
|
}
|
|
else
|
|
{
|
|
if(bl && _su) GX::SetTevColorInOp( s_id, GX_CC_RASA, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO,
|
|
GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_2, GX_ENABLE, (GXTevRegID)(((int)GX_TEVPREV)+tev_id) );
|
|
}
|
|
|
|
stage_id++;
|
|
break;
|
|
case vBLEND_MODE_ADD_FIXED:
|
|
case vBLEND_MODE_SUB_FIXED:
|
|
case vBLEND_MODE_BLEND_FIXED:
|
|
case vBLEND_MODE_MODULATE_FIXED:
|
|
{
|
|
if(bl && _su) GX::SetTevAlphaInOpSwap( s_id, GX_CA_KONST, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO,
|
|
GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, (GXTevRegID)(((int)GX_TEVPREV)+tev_id),
|
|
GX_TEV_SWAP0, GX_TEV_SWAP0 );
|
|
if(bl && _su) GX::SetTevColorInOp( s_id, GX_CC_ZERO, GX_CC_RASC, GX_CC_KONST, GX_CC_ZERO,
|
|
GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_2, GX_ENABLE, (GXTevRegID)(((int)GX_TEVPREV)+tev_id) );
|
|
stage_id++;
|
|
}
|
|
break;
|
|
case vBLEND_MODE_ADD:
|
|
case vBLEND_MODE_SUBTRACT:
|
|
case vBLEND_MODE_BLEND:
|
|
case vBLEND_MODE_DIFFUSE:
|
|
case vBLEND_MODE_MODULATE:
|
|
case vBLEND_MODE_BLEND_PREVIOUS_MASK:
|
|
case vBLEND_MODE_BLEND_INVERSE_PREVIOUS_MASK:
|
|
default:
|
|
if ( ignore_alpha )
|
|
{
|
|
if(bl && _su) GX::SetTevAlphaInOpSwap( s_id, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO,
|
|
GX_TEV_ADD, GX_TB_ADDHALF, GX_CS_SCALE_2, GX_ENABLE, (GXTevRegID)(((int)GX_TEVPREV)+tev_id),
|
|
GX_TEV_SWAP0, GX_TEV_SWAP0 );
|
|
}
|
|
else
|
|
{
|
|
if(bl && _su) GX::SetTevAlphaInOpSwap( s_id, GX_CA_RASA, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO,
|
|
GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_2, GX_ENABLE, (GXTevRegID)(((int)GX_TEVPREV)+tev_id),
|
|
GX_TEV_SWAP0, GX_TEV_SWAP0 );
|
|
}
|
|
|
|
if(bl && _su) GX::SetTevColorInOp( s_id, GX_CC_ZERO, GX_CC_RASC, GX_CC_KONST, GX_CC_ZERO,
|
|
GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_2, GX_ENABLE, (GXTevRegID)(((int)GX_TEVPREV)+tev_id) );
|
|
stage_id++;
|
|
break;
|
|
}
|
|
|
|
if ( tev_id > 0 ) {
|
|
multi_add_layer ( blend, fix, bl, tx );
|
|
} else {
|
|
// Set blend mode for base layer.
|
|
switch ( blend )
|
|
{
|
|
case vBLEND_MODE_ADD:
|
|
case vBLEND_MODE_ADD_FIXED:
|
|
if(bl && _su) GX::SetBlendMode ( GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_ONE, GX_LO_CLEAR, GX_TRUE, GX_FALSE, GX_TRUE );
|
|
break;
|
|
case vBLEND_MODE_SUBTRACT:
|
|
case vBLEND_MODE_SUB_FIXED:
|
|
if(bl && _su) GX::SetBlendMode ( GX_BM_SUBTRACT, GX_BL_ZERO, GX_BL_ZERO, GX_LO_CLEAR, GX_TRUE, GX_FALSE, GX_TRUE );
|
|
break;
|
|
case vBLEND_MODE_BLEND:
|
|
case vBLEND_MODE_BLEND_FIXED:
|
|
if(bl && _su) GX::SetBlendMode ( GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR, GX_TRUE, GX_FALSE, GX_TRUE );
|
|
break;
|
|
case vBLEND_MODE_BRIGHTEN:
|
|
case vBLEND_MODE_BRIGHTEN_FIXED:
|
|
if(bl && _su) GX::SetBlendMode ( GX_BM_BLEND, GX_BL_DSTCLR, GX_BL_ONE, GX_LO_CLEAR, GX_TRUE, GX_FALSE, GX_TRUE );
|
|
break;
|
|
case vBLEND_MODE_MODULATE_FIXED:
|
|
case vBLEND_MODE_MODULATE:
|
|
if(bl && _su) GX::SetBlendMode ( GX_BM_BLEND, GX_BL_ZERO, GX_BL_SRCALPHA, GX_LO_CLEAR, GX_TRUE, GX_FALSE, GX_TRUE );
|
|
break;
|
|
case vBLEND_MODE_BLEND_PREVIOUS_MASK:
|
|
case vBLEND_MODE_BLEND_INVERSE_PREVIOUS_MASK:
|
|
case vBLEND_MODE_DIFFUSE:
|
|
default:
|
|
if(bl && _su) GX::SetBlendMode ( GX_BM_NONE, GX_BL_ONE, GX_BL_ONE, GX_LO_CLEAR, GX_TRUE, GX_FALSE, GX_TRUE );
|
|
break;
|
|
}
|
|
}
|
|
tev_id++;
|
|
layer_id++;
|
|
}
|
|
}
|
|
|
|
#ifdef __PLAT_WN32__
|
|
uint8 has_holes = p_base_pass->m_texture.p_data ? ( ( p_base_pass->m_texture.p_data->m_PaletteFormat >> 1 ) & 1 ) : 0;
|
|
#else
|
|
uint8 has_holes = p_base_pass->m_texture.p_data ? ( ( p_base_pass->m_texture.p_data->flags & NxNgc::sTexture::TEXTURE_FLAG_HAS_HOLES ) ? 1 : 0 ) : 0;
|
|
#endif
|
|
multi_end( (BlendModes)p_base_pass->m_blend_mode, p_base_pass->m_flags, has_holes, p_mat->m_alpha_cutoff, p_mat->m_flags, bl, tx, cull );
|
|
}
|
|
|
|
void multi_mesh( sMaterialHeader * p_mat, sMaterialPassHeader * p_base_pass, bool bl, bool tx, bool should_correct_color, bool cull )
|
|
{
|
|
correct_color = should_correct_color;
|
|
#ifdef __PLAT_WN32__
|
|
g_tex_off[0] = -1;
|
|
g_tex_off[1] = -1;
|
|
g_tex_off[2] = -1;
|
|
g_tex_off[3] = -1;
|
|
|
|
g_alpha_off[0] = -1;
|
|
g_alpha_off[1] = -1;
|
|
g_alpha_off[2] = -1;
|
|
g_alpha_off[3] = -1;
|
|
#endif // __PLAT_WN32__
|
|
|
|
#ifdef __PLAT_WN32__
|
|
_su = true;
|
|
_tb = false;
|
|
_tc = false;
|
|
_ta = false;
|
|
_multi_mesh( p_mat, p_base_pass, bl, tx, cull );
|
|
_su = false;
|
|
_tb = true;
|
|
_tc = false;
|
|
_ta = false;
|
|
_multi_mesh( p_mat, p_base_pass, bl, tx, cull );
|
|
_su = false;
|
|
_tb = false;
|
|
_tc = true;
|
|
_ta = false;
|
|
_multi_mesh( p_mat, p_base_pass, bl, tx, cull );
|
|
_su = false;
|
|
_tb = false;
|
|
_tc = false;
|
|
_ta = true;
|
|
_multi_mesh( p_mat, p_base_pass, bl, tx, cull );
|
|
#else
|
|
_su = true;
|
|
_tb = true;
|
|
_tc = true;
|
|
_ta = true;
|
|
_multi_mesh( p_mat, p_base_pass, bl, tx, cull );
|
|
#endif // __PLAT_WN32__
|
|
|
|
// su = true;
|
|
// tb = true;
|
|
// tc = true;
|
|
// ta = true;
|
|
// _multi_mesh( p_mat, p_base_pass, true, false );
|
|
// _multi_mesh( p_mat, p_base_pass, false, true );
|
|
//// _multi_mesh( p_mat, p_base_pass, true, true );
|
|
}
|
|
|
|
} // namespace NxNgc
|
|
|
|
|
|
|