mirror of
https://github.com/zeldaret/tww.git
synced 2024-11-23 13:29:53 +00:00
Copy dolphin/gx progress from TP
This commit is contained in:
parent
340d18c6bc
commit
3e7ece6ff5
@ -22,27 +22,77 @@ extern "C" {
|
||||
|
||||
// Pack value into bitfield
|
||||
#define GX_BITFIELD_SET(field, pos, size, value) (field) = __rlwimi((field), (value), 31 - (pos) - (size) + 1, (pos), (pos) + (size)-1)
|
||||
#define GX_BITFIELD_TRUNC(field, pos, size, value) (__rlwimi((field), (value), 0, (pos), (pos) + (size)-1))
|
||||
|
||||
#define GX_BITGET(field, pos, size) ((field) >> (31 - (pos) - (size) + 1) & ((1 << (size)) - 1))
|
||||
#define GX_GET_REG(reg, st, end) GX_BITGET(reg, st, (end - st + 1))
|
||||
#define GX_SET_REG(reg, x, st, end) GX_BITFIELD_SET(reg, st, (end - st + 1), x)
|
||||
#define GX_SET_TRUNC(reg, x, st, end) GX_BITFIELD_TRUNC((reg), (st), ((end) - (st) + 1), (x))
|
||||
|
||||
#define GXCOLOR_AS_U32(color) (*((u32*)&(color)))
|
||||
|
||||
#define INSERT_FIELD(reg, value, nbits, shift) \
|
||||
(reg) = ((u32) (reg) & ~(((1 << (nbits)) - 1) << (shift))) | \
|
||||
((u32) (value) << (shift));
|
||||
|
||||
#define FAST_FLAG_SET(regOrg, newFlag, shift, size) \
|
||||
do { \
|
||||
(regOrg) = (u32)__rlwimi((int)(regOrg), (int)(newFlag), (shift), (32 - (shift) - (size)), (31 - (shift))); \
|
||||
} while (0);
|
||||
|
||||
#define GX_LOAD_BP_REG 0x61
|
||||
#define GX_NOP 0
|
||||
|
||||
typedef union {
|
||||
u8 u8;
|
||||
u16 u16;
|
||||
u32 u32;
|
||||
u64 u64;
|
||||
s8 s8;
|
||||
s16 s16;
|
||||
s32 s32;
|
||||
s64 s64;
|
||||
f32 f32;
|
||||
f64 f64;
|
||||
u8 u8;
|
||||
u16 u16;
|
||||
u32 u32;
|
||||
u64 u64;
|
||||
s8 s8;
|
||||
s16 s16;
|
||||
s32 s32;
|
||||
s64 s64;
|
||||
f32 f32;
|
||||
f64 f64;
|
||||
} PPCWGPipe;
|
||||
|
||||
volatile PPCWGPipe GXFIFO AT_ADDRESS(0xCC008000);
|
||||
#define GXFIFO_ADDR 0xCC008000
|
||||
volatile PPCWGPipe GXFIFO AT_ADDRESS(GXFIFO_ADDR);
|
||||
|
||||
#define GX_CP_LOAD_REG(addr, data) \
|
||||
GXFIFO.s8 = GX_FIFO_CMD_LOAD_CP_REG; \
|
||||
GXFIFO.s8 = (addr); \
|
||||
GXFIFO.s32 = (data);
|
||||
|
||||
/**
|
||||
* Header for an XF register load
|
||||
*/
|
||||
#define GX_XF_LOAD_REG_HDR(addr) \
|
||||
GXFIFO.s8 = GX_FIFO_CMD_LOAD_XF_REG; \
|
||||
GXFIFO.s32 = (addr);
|
||||
|
||||
/**
|
||||
* Load immediate value into XF register
|
||||
*/
|
||||
#define GX_XF_LOAD_REG(addr, data) \
|
||||
GX_XF_LOAD_REG_HDR(addr); \
|
||||
GXFIFO.s32 = (data);
|
||||
|
||||
/**
|
||||
* Load immediate value into BP register
|
||||
*/
|
||||
#define GX_BP_LOAD_REG(data) \
|
||||
GXFIFO.s8 = GX_FIFO_CMD_LOAD_BP_REG; \
|
||||
GXFIFO.s32 = (data);
|
||||
|
||||
/**
|
||||
* Load immediate values into multiple XF registers
|
||||
*/
|
||||
#define GX_XF_LOAD_REGS(size, addr) \
|
||||
{ \
|
||||
u32 cmd = (size) << 16 | addr; \
|
||||
GX_XF_LOAD_REG_HDR(cmd); \
|
||||
}
|
||||
|
||||
// Direct
|
||||
inline void GXPosition2f32(f32 x, f32 z) {
|
||||
@ -118,8 +168,8 @@ inline void GXTexCoord2u16(u16 x, u16 y) {
|
||||
}
|
||||
|
||||
inline void GXTexCoord2s16(const s16 u, const s16 v) {
|
||||
GXFIFO.s16 = u;
|
||||
GXFIFO.s16 = v;
|
||||
GXFIFO.s16 = u;
|
||||
GXFIFO.s16 = v;
|
||||
}
|
||||
|
||||
// Indexed
|
||||
|
@ -24,7 +24,7 @@ void GXSetVtxDescv(GXVtxDescList* list);
|
||||
void __GXSetVCD(void);
|
||||
void __GXCalculateVLim(void);
|
||||
void GXClearVtxDesc(void);
|
||||
void GXSetVtxAttrFmt(GXVtxFmt fmt, GXAttr attr, GXCompCnt cnt, GXCompType type, u32);
|
||||
void GXSetVtxAttrFmt(GXVtxFmt fmt, GXAttr attr, GXCompCnt cnt, GXCompType type, u8 frac);
|
||||
void GXSetVtxAttrFmtv(GXVtxFmt fmt, GXVtxAttrFmtList* list);
|
||||
void __GXSetVAT(void);
|
||||
void GXSetArray(GXAttr attr, void* base, u8);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -9,27 +9,29 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef void (*GXBreakPtCallback)(void);
|
||||
|
||||
void GXInitFifoBase(GXFifoObj* fifo, void* base, u32 size);
|
||||
void GXInitFifoPtrs(GXFifoObj* fifo, void* read_ptr, void* write_ptr);
|
||||
void GXSetCPUFifo(void);
|
||||
void GXSetGPFifo(void);
|
||||
void GXSetCPUFifo(GXFifoObj* fifo);
|
||||
void GXSetGPFifo(GXFifoObj* fifo);
|
||||
void GXSaveCPUFifo(GXFifoObj* fifo);
|
||||
void __GXSaveCPUFifoAux(GXFifoObj* fifo);
|
||||
void GXGetGPStatus(GXBool* overhi, GXBool* underlo, GXBool* read_idle, GXBool* cmd_idle, GXBool* breakpoint);
|
||||
void* GXGetFifoBase(GXFifoObj* fifo);
|
||||
u32 GXGetFifoSize(GXFifoObj* fifo);
|
||||
void GXSetBreakPtCallback(void);
|
||||
GXBreakPtCallback GXSetBreakPtCallback(GXBreakPtCallback cb);
|
||||
void __GXFifoInit(void);
|
||||
void __GXFifoReadEnable(void);
|
||||
void __GXFifoReadDisable(void);
|
||||
void __GXFifoLink(u8);
|
||||
void __GXWriteFifoIntEnable(u8, u8);
|
||||
void __GXWriteFifoIntReset(u8, u8);
|
||||
void __GXWriteFifoIntEnable(u32 p1, u32 p2);
|
||||
void __GXWriteFifoIntReset(u32 p1, u32 p2);
|
||||
void __GXCleanGPFifo(void);
|
||||
OSThread* GXSetCurrentGXThread(void);
|
||||
OSThread* GXGetCurrentGXThread(void);
|
||||
GXFifoObj* GXGetCPUFifo(void);
|
||||
u32 GXGetGPFifo(void);
|
||||
GXFifoObj* GXGetGPFifo(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
|
@ -17,7 +17,7 @@ extern GXRenderModeObj GXEurgb60Hz480IntDf;
|
||||
void GXSetDispCopySrc(u16 left, u16 top, u16 width, u16 height);
|
||||
void GXSetTexCopySrc(u16 left, u16 top, u16 width, u16 height);
|
||||
void GXSetDispCopyDst(u16 arg0, u16 arg1);
|
||||
void GXSetTexCopyDst(u16 width, u16 height, s32 fmt, GXBool mipmap);
|
||||
void GXSetTexCopyDst(u16 width, u16 height, GXTexFmt format, GXBool useMIPmap);
|
||||
void GXSetDispCopyFrame2Field(GXCopyMode mode);
|
||||
void GXSetCopyClamp(GXFBClamp clamp);
|
||||
u16 GXGetNumXfbLines(u16 efb_height, f32 y_scale);
|
||||
|
@ -5,112 +5,159 @@
|
||||
#include "dolphin/gx/GXStruct.h"
|
||||
#include "dolphin/mtx/mtx.h"
|
||||
|
||||
typedef GXTexRegion (*GXTexRegionCallback)(GXTexObj* obj);
|
||||
typedef GXTlutRegion* (*GXTlutRegionCallback)(u32 name);
|
||||
typedef GXTexRegion* (*GXTexRegionCallback)(const GXTexObj* t_obj, GXTexMapID id);
|
||||
typedef GXTlutRegion* (*GXTlutRegionCallback)(u32 idx);
|
||||
|
||||
typedef struct _GXData {
|
||||
/* 0x000 */ u16 field_0x0;
|
||||
/* 0x002 */ u16 field_0x2;
|
||||
/* 0x004 */ u16 field_0x4;
|
||||
/* 0x006 */ u16 field_0x6;
|
||||
/* 0x008 */ u32 field_0x8;
|
||||
/* 0x00C */ u32 field_0xc;
|
||||
/* 0x010 */ u32 field_0x10;
|
||||
/* 0x014 */ u32 field_0x14;
|
||||
/* 0x018 */ GXAttrType field_0x18;
|
||||
/* 0x01C */ GXCompCnt field_0x1c[8];
|
||||
/* 0x03C */ GXCompCnt field_0x3c[8];
|
||||
/* 0x05C */ u32 field_0x5c[8];
|
||||
/* 0x07C */ u32 field_0x7c;
|
||||
/* 0x080 */ u32 field_0x80;
|
||||
/* 0x084 */ u32 field_0x84;
|
||||
/* 0x088 */ u8 field_0x88[0xA8 - 0x88];
|
||||
/* 0x0A8 */ GXColor ambColors[2];
|
||||
/* 0x0B0 */ GXColor matColors[2];
|
||||
/* 0x0B8 */ u32 field_0xb8[8]; // GX_MAX_TEXCOORD
|
||||
/* 0x0D8 */ u32 field_0xd8[8]; // GX_MAX_TEXCOORD
|
||||
/* 0x0F8 */ u32 field_0xf8;
|
||||
/* 0x0FC */ u32 field_0xfc;
|
||||
/* 0x100 */ u32 field_0x100[GX_MAX_TEVSTAGE / 2];
|
||||
/* 0x120 */ u32 field_0x120;
|
||||
/* 0x124 */ u32 field_0x124;
|
||||
/* 0x128 */ u32 field_0x128;
|
||||
/* 0x12C */ u32 field_0x12c;
|
||||
/* 0x130 */ u32 field_0x130[GX_MAX_TEVSTAGE];
|
||||
/* 0x170 */ u32 field_0x170[GX_MAX_TEVSTAGE];
|
||||
/* 0x1B0 */ u32 field_0x1b0[GX_MAX_TEVSTAGE / 2];
|
||||
/* 0x1D0 */ u32 field_0x1d0;
|
||||
/* 0x1D4 */ u32 field_0x1d4;
|
||||
/* 0x1D8 */ u32 field_0x1d8;
|
||||
/* 0x1DC */ u32 field_0x1dc;
|
||||
/* 0x1E0 */ u32 field_0x1e0;
|
||||
/* 0x1E4 */ u32 field_0x1e4;
|
||||
/* 0x1E8 */ u32 field_0x1e8;
|
||||
/* 0x1EC */ u32 field_0x1ec;
|
||||
/* 0x1F0 */ u32 field_0x1f0;
|
||||
/* 0x1F4 */ u32 field_0x1f4;
|
||||
/* 0x1F8 */ u32 field_0x1f8;
|
||||
/* 0x1FC */ u32 field_0x1fc;
|
||||
/* 0x200 */ u8 field_0x200;
|
||||
/* 0x204 */ u32 field_0x204;
|
||||
/* 0x208 */ GXTexRegion field_0x208[8];
|
||||
/* 0x288 */ GXTexRegion field_0x288[8];
|
||||
/* 0x308 */ GXTexRegion field_0x308[8];
|
||||
/* 0x388 */ GXTlutRegion field_0x388[16];
|
||||
/* 0x488 */ GXTlutRegion field_0x488[4];
|
||||
/* 0x4C8 */ GXTexRegionCallback field_0x4c8;
|
||||
/* 0x4CC */ GXTlutRegionCallback field_0x4cc;
|
||||
/* 0x4D0 */ GXAttrType field_0x4d0;
|
||||
/* 0x4D4 */ u8 field_0x4d4;
|
||||
/* 0x4D5 */ u8 field_0x4d5;
|
||||
/* 0x4D8 */ GXProjectionType field_0x4d8;
|
||||
/* 0x4DC */ Mtx field_0x4dc;
|
||||
/* 0x50C */ f32 field_0x50c;
|
||||
/* 0x510 */ f32 field_0x510;
|
||||
/* 0x514 */ u32 field_0x514[8];
|
||||
/* 0x534 */ u32 field_0x534[8];
|
||||
/* 0x554 */ u32 field_0x554;
|
||||
/* 0x558 */ u32 field_0x558[8];
|
||||
/* 0x578 */ u8 field_0x578[0x594 - 0x578];
|
||||
/* 0x594 */ u32 field_0x594;
|
||||
/* 0x598 */ u32 field_0x598;
|
||||
/* 0x59C */ u32 field_0x59c;
|
||||
/* 0x5A0 */ u8 field_0x5a0[4];
|
||||
/* 0x5A4 */ u32 field_0x5a4;
|
||||
/* 0x5A8 */ u8 field_0x5a8;
|
||||
/* 0x5A9 */ u8 field_0x5a9;
|
||||
/* 0x5AA */ u8 field_0x5aa;
|
||||
/* 0x5AB */ u8 field_0x5ab;
|
||||
/* 0x5AC */ u32 field_0x5ac;
|
||||
// Bypass and vertex info
|
||||
/* 0x000 */ u16 vNumNot;
|
||||
/* 0x002 */ u16 bpSentNot;
|
||||
/* 0x004 */ u16 vNum;
|
||||
/* 0x006 */ u16 vLim;
|
||||
|
||||
// Command process (CP) regs
|
||||
/* 0x008 */ u32 cpEnable;
|
||||
/* 0x00C */ u32 cpStatus;
|
||||
/* 0x010 */ u32 cpClr;
|
||||
/* 0x014 */ u32 vcdLo;
|
||||
/* 0x018 */ u32 vcdHi;
|
||||
/* 0x01C */ u32 vatA[8];
|
||||
/* 0x03C */ u32 vatB[8];
|
||||
/* 0x05C */ u32 vatC[8];
|
||||
/* 0x07C */ u32 lpSize;
|
||||
/* 0x080 */ u32 matIdxA;
|
||||
/* 0x084 */ u32 matIdxB;
|
||||
|
||||
// Index loading base/stride regs (pos, nrm, tex, light)
|
||||
/* 0x088 */ u32 indexBase[4];
|
||||
/* 0x098 */ u32 indexStride[4];
|
||||
|
||||
// Transform and lighting regs
|
||||
/* 0x0A8 */ u32 ambColor[2];
|
||||
/* 0x0B0 */ u32 matColor[2];
|
||||
|
||||
// Setup regs
|
||||
/* 0x0B8 */ u32 suTs0[8];
|
||||
/* 0x0D8 */ u32 suTs1[8];
|
||||
/* 0x0F8 */ u32 suScis0;
|
||||
/* 0x0FC */ u32 suScis1;
|
||||
|
||||
// Raster regs
|
||||
/* 0x100 */ u32 tref[8];
|
||||
/* 0x120 */ u32 iref;
|
||||
|
||||
// Bump/Indirect texture regs
|
||||
/* 0x124 */ u32 bpMask;
|
||||
/* 0x128 */ u32 IndTexScale0;
|
||||
/* 0x12C */ u32 IndTexScale1;
|
||||
|
||||
// Tev regs
|
||||
/* 0x130 */ u32 tevc[16];
|
||||
/* 0x170 */ u32 teva[16];
|
||||
/* 0x1B0 */ u32 tevKsel[8];
|
||||
|
||||
// Performance regs
|
||||
/* 0x1D0 */ u32 cmode0;
|
||||
/* 0x1D4 */ u32 cmode1;
|
||||
/* 0x1D8 */ u32 zmode;
|
||||
/* 0x1DC */ u32 peCtrl;
|
||||
|
||||
// Display copy regs
|
||||
/* 0x1E0 */ u32 cpDispSrc;
|
||||
/* 0x1E4 */ u32 cpDispSize;
|
||||
/* 0x1E8 */ u32 cpDispStride;
|
||||
/* 0x1EC */ u32 cpDisp;
|
||||
|
||||
// Texture copy regs
|
||||
/* 0x1F0 */ u32 cpTexSrc;
|
||||
/* 0x1F4 */ u32 cpTexSize;
|
||||
/* 0x1F8 */ u32 cpTexStride;
|
||||
/* 0x1FC */ u32 cpTex;
|
||||
/* 0x200 */ GXBool cpTexZ;
|
||||
|
||||
// General raster mode
|
||||
/* 0x204 */ u32 genMode;
|
||||
|
||||
// Texture regions
|
||||
/* 0x208 */ GXTexRegion TexRegions0[GX_MAX_TEXMAP];
|
||||
/* 0x288 */ GXTexRegion TexRegions1[GX_MAX_TEXMAP];
|
||||
/* 0x308 */ GXTexRegion TexRegions2[GX_MAX_TEXMAP];
|
||||
|
||||
// Texture lookup table regions
|
||||
/* 0x388 */ GXTlutRegion TlutRegions[GX_MAX_TLUT_ALL];
|
||||
/* 0x4C8 */ GXTexRegionCallback texRegionCallback;
|
||||
/* 0x4CC */ GXTlutRegionCallback tlutRegionCallback;
|
||||
|
||||
// Command processor vars
|
||||
/* 0x4D0 */ GXAttrType nrmType;
|
||||
/* 0x4D4 */ GXBool hasNrms;
|
||||
/* 0x4D5 */ GXBool hasBiNrms;
|
||||
/* 0x4D8 */ u32 projType;
|
||||
/* 0x4DC */ f32 projMtx[6];
|
||||
|
||||
// Viewport parms
|
||||
/* 0x4F4 */ f32 vpLeft;
|
||||
/* 0x4F8 */ f32 vpTop;
|
||||
/* 0x4FC */ f32 vpWd;
|
||||
/* 0x500 */ f32 vpHt;
|
||||
/* 0x504 */ f32 vpNearz;
|
||||
/* 0x508 */ f32 vpFarz;
|
||||
/* 0x50C */ f32 zOffset;
|
||||
/* 0x510 */ f32 zScale;
|
||||
|
||||
// Texture regs
|
||||
/* 0x514 */ u32 tImage0[8];
|
||||
/* 0x534 */ u32 tMode0[8];
|
||||
/* 0x554 */ u32 texmapId[16];
|
||||
/* 0x594 */ u32 tcsManEnab;
|
||||
/* 0x598 */ u32 tevTcEnab;
|
||||
|
||||
// Performance metrics
|
||||
/* 0x59C */ GXPerf0 perf0;
|
||||
/* 0x5A0 */ GXPerf1 perf1;
|
||||
/* 0x5A4 */ u32 perfSel;
|
||||
|
||||
// Flags
|
||||
/* 0x5A8 */ GXBool inDispList;
|
||||
/* 0x5A9 */ GXBool dlSaveContext;
|
||||
/* 0x5AA */ GXBool abtWaitPECopy;
|
||||
/* 0x5AB */ u8 dirtyVAT;
|
||||
/* 0x5AC */ u32 dirtyState;
|
||||
} GXData; // Size: 0x5B0
|
||||
|
||||
STATIC_ASSERT(sizeof(GXData) == 0x5B0);
|
||||
|
||||
extern GXData* const __GXData;
|
||||
|
||||
// Define register addresses.
|
||||
#define GX_CP_ADDR (0x0C000000)
|
||||
#define GX_PE_ADDR (0x0C001000)
|
||||
#define GX_PI_ADDR (0x0C003000)
|
||||
#define GX_MEM_ADDR (0x0C004000)
|
||||
|
||||
extern u32* __piReg;
|
||||
extern u16* __cpReg;
|
||||
extern u8 __peReg[4];
|
||||
extern u8 __memReg[4];
|
||||
extern u16* __peReg;
|
||||
extern vu16* __memReg;
|
||||
|
||||
inline void GXSetWasteFlags() {
|
||||
GXData* data = __GXData;
|
||||
data->field_0x5ac |= 0x3;
|
||||
data->field_0x2 = 0;
|
||||
GXData* data = __GXData;
|
||||
data->dirtyState |= GX_DIRTY_SU_TEX | GX_DIRTY_BP_MASK;
|
||||
data->bpSentNot = 0;
|
||||
}
|
||||
|
||||
static inline void set_x2(u16 value)
|
||||
{
|
||||
__GXData->field_0x2 = value;
|
||||
__GXData->bpSentNot = value;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
GXTexRegion* __GXDefaultTexRegionCallback(GXTexObj* obj, GXTexMapID mapID);
|
||||
GXTexRegion* __GXDefaultTexRegionCallback(const GXTexObj* obj, GXTexMapID id);
|
||||
GXTlutRegion* __GXDefaultTlutRegionCallback(u32 tlut);
|
||||
void __GXShutdown(s32);
|
||||
BOOL __GXShutdown(BOOL final);
|
||||
void __GXInitRevisionBits(void);
|
||||
GXFifoObj* GXInit(void* base, u32 size);
|
||||
void __GXInitGX(void);
|
||||
|
@ -7,7 +7,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void GXSetMisc(u32 id, u32 value);
|
||||
void GXSetMisc(GXMiscToken token, u32 val);
|
||||
void GXFlush(void);
|
||||
void __GXAbort(void);
|
||||
void GXAbortFrame(void);
|
||||
@ -21,7 +21,7 @@ void GXPokeBlendMode(GXBlendMode mode, GXBlendFactor src_factor, GXBlendFactor d
|
||||
void GXPokeColorUpdate(GXBool enable_update);
|
||||
void GXPokeDstAlpha(GXBool enable, u8 alpha);
|
||||
void GXPokeDither(GXBool enable);
|
||||
void GXPokeZMode(GXBool enable_compare, GXCompare comp);
|
||||
void GXPokeZMode(GXBool enable_compare, GXCompare comp, GXBool update_enable);
|
||||
void GXPeekARGB(u16 x, u16 y, u32* color);
|
||||
void GXPeekZ(u16 x, u16 y, u32* z);
|
||||
|
||||
@ -30,7 +30,7 @@ GXDrawSyncCallback GXSetDrawSyncCallback(GXDrawSyncCallback callback);
|
||||
void GXSetDrawSync(GXBool enable);
|
||||
|
||||
typedef void (*GXDrawDoneCallback)(void);
|
||||
void GXSetDrawDoneCallback(GXDrawDoneCallback callback);
|
||||
GXDrawDoneCallback GXSetDrawDoneCallback(GXDrawDoneCallback callback);
|
||||
void __GXPEInit(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -1,13 +1,13 @@
|
||||
#ifndef GXPERF_H
|
||||
#define GXPERF_H
|
||||
|
||||
#include "dolphin/types.h"
|
||||
#include "dolphin/gx/GXEnum.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void GXSetGPMetric(u32 perf0, u32 perf1);
|
||||
void GXSetGPMetric(GXPerf0 perf0, GXPerf1 perf1);
|
||||
void GXClearGPMetric(void);
|
||||
void GXReadXfRasMetric(u32*, u32*, u32*, u32*);
|
||||
|
||||
|
@ -2,6 +2,8 @@
|
||||
#define GXSTRUCT_H
|
||||
|
||||
#include "global.h"
|
||||
#include "dolphin/gx/GXEnum.h"
|
||||
#include "dolphin/vi/vi.h"
|
||||
|
||||
typedef struct _GXColor {
|
||||
/* 0x0 */ u8 r;
|
||||
@ -72,18 +74,18 @@ typedef struct _GXLightObj {
|
||||
} GXLightObj;
|
||||
|
||||
typedef struct _GXFogAdjTable {
|
||||
/* 0x0 */ u16 r[10];
|
||||
/* 0x0 */ u16 fogVals[10];
|
||||
} GXFogAdjTable;
|
||||
|
||||
typedef struct _GXFifoObj {
|
||||
/* 0x00 */ void* base;
|
||||
/* 0x04 */ u32 end;
|
||||
/* 0x04 */ void* end;
|
||||
/* 0x08 */ u32 size;
|
||||
/* 0x0C */ u32 high_wtrmark;
|
||||
/* 0x10 */ u32 low_wtrmark;
|
||||
/* 0x14 */ void* read_ptr;
|
||||
/* 0x18 */ void* write_ptr;
|
||||
/* 0x1C */ void* rw_dst;
|
||||
/* 0x1C */ s32 rw_dst;
|
||||
/* 0x20 */ u8 fifo_wrap;
|
||||
/* 0x21 */ u8 cpu_fifo_ready;
|
||||
/* 0x22 */ u8 gp_fifo_ready;
|
||||
@ -91,11 +93,16 @@ typedef struct _GXFifoObj {
|
||||
} GXFifoObj; // Size: 0x80
|
||||
|
||||
typedef struct _GXTexRegion {
|
||||
/* 0x00 */ u8 dummy[0x10];
|
||||
u32 unk0; // _00
|
||||
u32 unk4; // _04
|
||||
u32 unk8; // _08
|
||||
u8 unkC; // _0C
|
||||
u8 unkD; // _0D
|
||||
} GXTexRegion; // Size: 0x10
|
||||
|
||||
typedef struct _GXTlutRegion {
|
||||
/* 0x00 */ u8 dummy[0x10];
|
||||
/* 0x00 */ u32 unk0;
|
||||
/* 0x04 */ GXTlutObj tlutObj;
|
||||
} GXTlutRegion; // Size: 0x10
|
||||
|
||||
#endif /* GXSTRUCT_H */
|
||||
|
@ -8,7 +8,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
u32 GXGetTexBufferSize(u16 width, u16 height, u32 format, GXBool mipmap, u8 max_lod);
|
||||
void __GetImageTileCount(u32 arg0, s16 arg1, s16 arg2, s32* arg3, s32* arg4, s32* arg5);
|
||||
void __GetImageTileCount(GXTexFmt format, u16 width, u16 height, u32* a, u32* b, u32* c);
|
||||
void GXInitTexObj(GXTexObj* obj, void* image, u16 width, u16 height, GXTexFmt fmt,
|
||||
GXTexWrapMode wrapS, GXTexWrapMode wrapT, GXBool mipmap);
|
||||
void GXInitTexObjCI(GXTexObj* obj, void* image, u16 width, u16 height, GXCITexFmt format,
|
||||
@ -19,10 +19,10 @@ void GXInitTexObjLOD(GXTexObj* obj, GXTexFilter min_filter, GXTexFilter max_filt
|
||||
void* GXGetTexObjData(GXTexObj* obj);
|
||||
u16 GXGetTexObjWidth(GXTexObj* obj);
|
||||
u16 GXGetTexObjHeight(GXTexObj* obj);
|
||||
GXTexFmt GXGetTexObjFmt(GXTexObj* obj);
|
||||
GXTexFmt GXGetTexObjFmt(const GXTexObj* obj);
|
||||
GXTexWrapMode GXGetTexObjWrapS(GXTexObj* obj);
|
||||
GXTexWrapMode GXGetTexObjWrapT(GXTexObj* obj);
|
||||
GXBool GXGetTexObjMipMap(GXTexObj* obj);
|
||||
GXBool GXGetTexObjMipMap(const GXTexObj* obj);
|
||||
u32 GXGetTexObjTlut(GXTexObj* obj);
|
||||
void GXLoadTexObj(GXTexObj* obj, GXTexMapID id);
|
||||
void GXInitTlutObj(GXTlutObj* obj, void* lut, GXTlutFmt fmt, u16 entry_num);
|
||||
|
@ -9,18 +9,18 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
void GXProject(f32 model_x, f32 model_y, f32 model_z, Mtx model_mtx, f32* proj, f32* viewpoint, f32* screen_x, f32* screen_y, f32* screen_z);
|
||||
void GXSetProjection(Mtx44 mtx, GXProjectionType type);
|
||||
void GXSetProjection(const Mtx44 proj, GXProjectionType type);
|
||||
void GXSetProjectionv(f32* p);
|
||||
void GXGetProjectionv(f32* p);
|
||||
void GXLoadPosMtxImm(Mtx mtx, u32 id);
|
||||
void GXLoadNrmMtxImm(Mtx mtx, u32 id);
|
||||
void GXSetCurrentMtx(u32 id);
|
||||
void GXLoadTexMtxImm(Mtx mtx, u32 id, GXTexMtxType type);
|
||||
void GXLoadTexMtxImm(const Mtx mtx, u32 id, GXTexMtxType type);
|
||||
void GXSetViewport(f32 x_orig, f32 y_orig, f32 width, f32 height, f32 near_z, f32 far_z);
|
||||
void GXGetViewportv(f32* p);
|
||||
void GXSetScissor(u32 left, u32 top, u32 width, u32 height);
|
||||
void GXGetScissor(u32* left, u32* top, u32* width, u32* height);
|
||||
void GXSetScissorBoxOffset(u32 x_offset, u32 y_offset);
|
||||
void GXSetScissorBoxOffset(s32 x, s32 y);
|
||||
void GXSetClipMode(GXClipMode mode);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -41,7 +41,7 @@ typedef enum {
|
||||
EXCEPTION_FLOATING_POINT,
|
||||
EXCEPTION_DECREMENTER,
|
||||
EXCEPTION_SYSTEM_CALL,
|
||||
EXCEPTION_TRACE ,
|
||||
EXCEPTION_TRACE,
|
||||
EXCEPTION_PERFORMANCE_MONITOR,
|
||||
EXCEPTION_BREAKPOINT,
|
||||
EXCEPTION_RESERVED,
|
||||
|
@ -23,7 +23,7 @@ typedef struct OSMessageQueue {
|
||||
#define OS_MESSAGE_BLOCK 1
|
||||
|
||||
typedef enum {
|
||||
OS_MSG_PERSISTENT = (1 << 0),
|
||||
OS_MSG_PERSISTENT = (1 << 0),
|
||||
} OSMessageFlags;
|
||||
|
||||
void OSInitMessageQueue(OSMessageQueue* queue, OSMessage* msgArray, s32 msgCount);
|
||||
|
@ -10,37 +10,120 @@ extern "C" {
|
||||
|
||||
typedef struct _GXRenderModeObj GXRenderModeObj;
|
||||
|
||||
#define VI_TVMODE(format, interlace) (((format) << 2) + (interlace))
|
||||
#define VI_INTERLACE (0)
|
||||
#define VI_NON_INTERLACE (1)
|
||||
#define VI_PROGRESSIVE (2)
|
||||
#define VI_3D (3)
|
||||
|
||||
#define VI_INTERLACE 0
|
||||
#define VI_NON_INTERLACE 1
|
||||
#define VI_PROGRESSIVE 2
|
||||
// Video output formats
|
||||
#define VI_NTSC (0)
|
||||
#define VI_PAL (1)
|
||||
#define VI_MPAL (2)
|
||||
#define VI_DEBUG (3)
|
||||
#define VI_DEBUG_PAL (4)
|
||||
#define VI_EURGB60 (5)
|
||||
#define VI_GCA (6)
|
||||
|
||||
#define VI_NTSC 0
|
||||
#define VI_PAL 1
|
||||
#define VI_MPAL 2
|
||||
#define VI_DEBUG 3
|
||||
#define VI_DEBUG_PAL 4
|
||||
#define VI_EURGB60 5
|
||||
// Conversion to TVMode used in enums
|
||||
#define VI_TVMODE(FMT, INT) (((FMT) << 2) + (INT))
|
||||
|
||||
// TV Modes
|
||||
typedef enum {
|
||||
VI_TVMODE_NTSC_INT = VI_TVMODE(VI_NTSC, VI_INTERLACE),
|
||||
VI_TVMODE_NTSC_DS = VI_TVMODE(VI_NTSC, VI_NON_INTERLACE),
|
||||
VI_TVMODE_NTSC_PROG = VI_TVMODE(VI_NTSC, VI_PROGRESSIVE),
|
||||
VI_TVMODE_PAL_INT = VI_TVMODE(VI_PAL, VI_INTERLACE),
|
||||
VI_TVMODE_PAL_DS = VI_TVMODE(VI_PAL, VI_NON_INTERLACE),
|
||||
VI_TVMODE_EURGB60_INT = VI_TVMODE(VI_EURGB60, VI_INTERLACE),
|
||||
VI_TVMODE_EURGB60_DS = VI_TVMODE(VI_EURGB60, VI_NON_INTERLACE),
|
||||
VI_TVMODE_MPAL_INT = VI_TVMODE(VI_MPAL, VI_INTERLACE),
|
||||
VI_TVMODE_MPAL_DS = VI_TVMODE(VI_MPAL, VI_NON_INTERLACE),
|
||||
VI_TVMODE_DEBUG_INT = VI_TVMODE(VI_DEBUG, VI_INTERLACE),
|
||||
VI_TVMODE_DEBUG_PAL_INT = VI_TVMODE(VI_DEBUG_PAL, VI_INTERLACE),
|
||||
VI_TVMODE_DEBUG_PAL_DS = VI_TVMODE(VI_DEBUG_PAL, VI_NON_INTERLACE)
|
||||
// NTSC
|
||||
VI_TVMODE_NTSC_INT = VI_TVMODE(VI_NTSC, VI_INTERLACE), // 0
|
||||
VI_TVMODE_NTSC_DS = VI_TVMODE(VI_NTSC, VI_NON_INTERLACE), // 1
|
||||
VI_TVMODE_NTSC_PROG = VI_TVMODE(VI_NTSC, VI_PROGRESSIVE), // 2
|
||||
VI_TVMODE_NTSC_3D = VI_TVMODE(VI_NTSC, VI_3D), // 3
|
||||
|
||||
// PAL
|
||||
VI_TVMODE_PAL_INT = VI_TVMODE(VI_PAL, VI_INTERLACE), // 4
|
||||
VI_TVMODE_PAL_DS = VI_TVMODE(VI_PAL, VI_NON_INTERLACE), // 5
|
||||
|
||||
// MPAL
|
||||
VI_TVMODE_MPAL_INT = VI_TVMODE(VI_MPAL, VI_INTERLACE), // 8
|
||||
VI_TVMODE_MPAL_DS = VI_TVMODE(VI_MPAL, VI_NON_INTERLACE), // 9
|
||||
|
||||
// Debug
|
||||
VI_TVMODE_DEBUG_INT = VI_TVMODE(VI_DEBUG, VI_INTERLACE), // 12
|
||||
|
||||
// Debug PAL
|
||||
VI_TVMODE_DEBUG_PAL_INT = VI_TVMODE(VI_DEBUG_PAL, VI_INTERLACE), // 16
|
||||
VI_TVMODE_DEBUG_PAL_DS = VI_TVMODE(VI_DEBUG_PAL, VI_NON_INTERLACE), // 17
|
||||
|
||||
// EU RGB60
|
||||
VI_TVMODE_EURGB60_INT = VI_TVMODE(VI_EURGB60, VI_INTERLACE), // 20
|
||||
VI_TVMODE_EURGB60_DS = VI_TVMODE(VI_EURGB60, VI_NON_INTERLACE), // 21
|
||||
|
||||
// GCA
|
||||
VI_TVMODE_GCA_INT = VI_TVMODE(VI_GCA, VI_INTERLACE), // 24
|
||||
VI_TVMODE_GCA_DS = VI_TVMODE(VI_GCA, VI_NON_INTERLACE), // 25
|
||||
VI_TVMODE_GCA_PROG = VI_TVMODE(VI_GCA, VI_PROGRESSIVE), // 26
|
||||
} VITVMode;
|
||||
|
||||
typedef enum { VI_XFBMODE_SF = 0, VI_XFBMODE_DF } VIXFBMode;
|
||||
|
||||
typedef void (*VIRetraceCallback)(u32);
|
||||
typedef void (*VIPositionCallback)(s16 x, s16 y);
|
||||
|
||||
typedef struct VITimingInfo {
|
||||
u8 equ; // _00
|
||||
u16 acv; // _02
|
||||
u16 prbOdd; // _04
|
||||
u16 prbEven; // _06
|
||||
u16 psbOdd; // _08
|
||||
u16 psbEven; // _0A
|
||||
u8 bs1; // _0C
|
||||
u8 bs2; // _0D
|
||||
u8 bs3; // _0E
|
||||
u8 bs4; // _0F
|
||||
u16 be1; // _10
|
||||
u16 be2; // _12
|
||||
u16 be3; // _14
|
||||
u16 be4; // _16
|
||||
u16 numHalfLines; // _18
|
||||
u16 hlw; // _1A
|
||||
u8 hsy; // _1C
|
||||
u8 hcs; // _1D
|
||||
u8 hce; // _1E
|
||||
u8 hbe640; // _1F
|
||||
u16 hbs640; // _20
|
||||
u8 hbeCCIR656; // _24
|
||||
u16 hbsCCIR656; // _26
|
||||
} VITimingInfo;
|
||||
|
||||
typedef struct VIPositionInfo {
|
||||
u16 dispPosX; // _00
|
||||
u16 dispPosY; // _02
|
||||
u16 dispSizeX; // _04
|
||||
u16 dispSizeY; // _06
|
||||
u16 adjDispPosX; // _08
|
||||
u16 adjDispPosY; // _0A
|
||||
u16 adjDispSizeY; // _0C
|
||||
u16 adjPanPosY; // _0E
|
||||
u16 adjPanSizeY; // _10
|
||||
u16 fbSizeX; // _12
|
||||
u16 fbSizeY; // _14
|
||||
u16 panPosX; // _16
|
||||
u16 panPosY; // _18
|
||||
u16 panSizeX; // _1A
|
||||
u16 panSizeY; // _1C
|
||||
VIXFBMode xfbMode; // _20
|
||||
u32 nonInter; // _24
|
||||
u32 tv; // _28
|
||||
u8 wordPerLine; // _2C
|
||||
u8 std; // _2D
|
||||
u8 wpl; // _2E
|
||||
u32 bufAddr; // _30
|
||||
u32 tfbb; // _34
|
||||
u32 bfbb; // _38
|
||||
u8 xof; // _3C
|
||||
BOOL isBlack; // _40
|
||||
BOOL is3D; // _44
|
||||
u32 rbufAddr; // _48
|
||||
u32 rtfbb; // _4C
|
||||
u32 rbfbb; // _50
|
||||
VITimingInfo* timing; // _54
|
||||
} VIPositionInfo;
|
||||
|
||||
void VIWaitForRetrace(void);
|
||||
void VISetNextFrameBuffer(void*);
|
||||
|
@ -502,7 +502,7 @@ void J3DGDSetFog(GXFogType type, f32 startZ, f32 endZ, f32 nearZ, f32 farZ, GXCo
|
||||
void J3DGDSetFogRangeAdj(u8 enabled, u16 center, GXFogAdjTable* pFogAdjTable) {
|
||||
if (enabled) {
|
||||
for (s32 i = 0; i < 10; i += 2) {
|
||||
J3DGDWriteBPCmd((0xe9 + i / 2) << 24 | pFogAdjTable->r[i + 1] << 12 | pFogAdjTable->r[i] << 0);
|
||||
J3DGDWriteBPCmd((0xe9 + i / 2) << 24 | pFogAdjTable->fogVals[i + 1] << 12 | pFogAdjTable->fogVals[i] << 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -148,7 +148,7 @@ void J3DSys::setTexCacheRegion(GXTexCacheSize size) {
|
||||
|
||||
/* 802D8EE0-802D956C .text drawInit__6J3DSysFv */
|
||||
void J3DSys::drawInit() {
|
||||
GXSetMisc(2, 0);
|
||||
GXSetMisc(GX_MT_DL_SAVE_CONTEXT, 0);
|
||||
GXInvalidateVtxCache();
|
||||
GXSetCurrentMtx(GX_PNMTX0);
|
||||
GXSetCullMode(GX_CULL_BACK);
|
||||
|
@ -822,7 +822,7 @@ void JPADraw::drawParticle() {
|
||||
GXSetCullMode(GX_CULL_NONE);
|
||||
if (dc.pbsp->isClipOn()) {
|
||||
GXSetClipMode(GX_CLIP_ENABLE);
|
||||
GXSetMisc(1, 8);
|
||||
GXSetMisc(GX_MT_XF_FLUSH, 8);
|
||||
} else {
|
||||
GXSetClipMode(GX_CLIP_DISABLE);
|
||||
}
|
||||
@ -845,7 +845,7 @@ void JPADraw::drawParticle() {
|
||||
}
|
||||
}
|
||||
|
||||
GXSetMisc(1, 0);
|
||||
GXSetMisc(GX_MT_XF_FLUSH, 0);
|
||||
}
|
||||
|
||||
/* 8026BC2C-8026BF88 .text drawChild__7JPADrawFv */
|
||||
@ -871,7 +871,7 @@ void JPADraw::drawChild() {
|
||||
|
||||
if (dc.pssp->isClipOn()) {
|
||||
GXSetClipMode(GX_CLIP_ENABLE);
|
||||
GXSetMisc(1, 8);
|
||||
GXSetMisc(GX_MT_XF_FLUSH, 8);
|
||||
} else {
|
||||
GXSetClipMode(GX_CLIP_DISABLE);
|
||||
}
|
||||
@ -894,7 +894,7 @@ void JPADraw::drawChild() {
|
||||
}
|
||||
}
|
||||
|
||||
GXSetMisc(1, 0);
|
||||
GXSetMisc(GX_MT_XF_FLUSH, 0);
|
||||
}
|
||||
|
||||
/* 8026BF88-8026C024 .text zDraw__7JPADrawFv */
|
||||
@ -922,7 +922,7 @@ void JPADraw::zDrawParticle() {
|
||||
GXSetCullMode(GX_CULL_NONE);
|
||||
if (dc.pbsp->isClipOn()) {
|
||||
GXSetClipMode(GX_CLIP_ENABLE);
|
||||
GXSetMisc(1, 8);
|
||||
GXSetMisc(GX_MT_XF_FLUSH, 8);
|
||||
} else {
|
||||
GXSetClipMode(GX_CLIP_DISABLE);
|
||||
}
|
||||
@ -945,7 +945,7 @@ void JPADraw::zDrawParticle() {
|
||||
}
|
||||
}
|
||||
|
||||
GXSetMisc(1, 0);
|
||||
GXSetMisc(GX_MT_XF_FLUSH, 0);
|
||||
}
|
||||
|
||||
/* 8026C24C-8026C4DC .text zDrawChild__7JPADrawFv */
|
||||
@ -971,7 +971,7 @@ void JPADraw::zDrawChild() {
|
||||
|
||||
if (dc.pssp->isClipOn()) {
|
||||
GXSetClipMode(GX_CLIP_ENABLE);
|
||||
GXSetMisc(1, 8);
|
||||
GXSetMisc(GX_MT_XF_FLUSH, 8);
|
||||
} else {
|
||||
GXSetClipMode(GX_CLIP_DISABLE);
|
||||
}
|
||||
@ -994,7 +994,7 @@ void JPADraw::zDrawChild() {
|
||||
}
|
||||
}
|
||||
|
||||
GXSetMisc(1, 0);
|
||||
GXSetMisc(GX_MT_XF_FLUSH, 0);
|
||||
}
|
||||
|
||||
/* 8026C4DC-8026C640 .text loadYBBMtx__7JPADrawFPA4_f */
|
||||
|
@ -441,7 +441,7 @@ dKyd_Schedule* dKyd_schejule_menu_getp() {
|
||||
/* 80086F34-80086F74 .text dKyd_xfog_table_set__FUc */
|
||||
void dKyd_xfog_table_set(u8 i_idx) {
|
||||
for (int i = 0; i < 10; i++) {
|
||||
u16 fogAdjTableEntry = S_xfog_table_data[i_idx].r[i];
|
||||
g_env_light.mFogAdjTable.r[i] = fogAdjTableEntry;
|
||||
u16 fogAdjTableEntry = S_xfog_table_data[i_idx].fogVals[i];
|
||||
g_env_light.mFogAdjTable.fogVals[i] = fogAdjTableEntry;
|
||||
}
|
||||
}
|
||||
|
751
src/dolphin/gx/GXAttr.c
Normal file
751
src/dolphin/gx/GXAttr.c
Normal file
@ -0,0 +1,751 @@
|
||||
#include "dolphin/gx/GXAttr.h"
|
||||
#include "dolphin/gx/GX.h"
|
||||
|
||||
static inline void SETVCDATTR(GXAttr name, GXAttrType type) {
|
||||
switch (name) {
|
||||
case GX_VA_PNMTXIDX:
|
||||
GX_SET_REG(__GXData->vcdLo, type, GX_CP_VCD_LO_POSMTXIDX_ST, GX_CP_VCD_LO_POSMTXIDX_END);
|
||||
break;
|
||||
case GX_VA_TEX0MTXIDX:
|
||||
GX_SET_REG(__GXData->vcdLo, type, GX_CP_VCD_LO_TEX0MTXIDX_ST,
|
||||
GX_CP_VCD_LO_TEX0MTXIDX_END);
|
||||
break;
|
||||
case GX_VA_TEX1MTXIDX:
|
||||
GX_SET_REG(__GXData->vcdLo, type, GX_CP_VCD_LO_TEX1MTXIDX_ST,
|
||||
GX_CP_VCD_LO_TEX1MTXIDX_END);
|
||||
break;
|
||||
case GX_VA_TEX2MTXIDX:
|
||||
GX_SET_REG(__GXData->vcdLo, type, GX_CP_VCD_LO_TEX2MTXIDX_ST,
|
||||
GX_CP_VCD_LO_TEX2MTXIDX_END);
|
||||
break;
|
||||
case GX_VA_TEX3MTXIDX:
|
||||
GX_SET_REG(__GXData->vcdLo, type, GX_CP_VCD_LO_TEX3MTXIDX_ST,
|
||||
GX_CP_VCD_LO_TEX3MTXIDX_END);
|
||||
break;
|
||||
case GX_VA_TEX4MTXIDX:
|
||||
GX_SET_REG(__GXData->vcdLo, type, GX_CP_VCD_LO_TEX4MTXIDX_ST,
|
||||
GX_CP_VCD_LO_TEX4MTXIDX_END);
|
||||
break;
|
||||
case GX_VA_TEX5MTXIDX:
|
||||
GX_SET_REG(__GXData->vcdLo, type, GX_CP_VCD_LO_TEX5MTXIDX_ST,
|
||||
GX_CP_VCD_LO_TEX5MTXIDX_END);
|
||||
break;
|
||||
case GX_VA_TEX6MTXIDX:
|
||||
GX_SET_REG(__GXData->vcdLo, type, GX_CP_VCD_LO_TEX6MTXIDX_ST,
|
||||
GX_CP_VCD_LO_TEX6MTXIDX_END);
|
||||
break;
|
||||
case GX_VA_TEX7MTXIDX:
|
||||
GX_SET_REG(__GXData->vcdLo, type, GX_CP_VCD_LO_TEX7MTXIDX_ST,
|
||||
GX_CP_VCD_LO_TEX7MTXIDX_END);
|
||||
break;
|
||||
case GX_VA_POS:
|
||||
GX_SET_REG(__GXData->vcdLo, type, GX_CP_VCD_LO_POS_ST, GX_CP_VCD_LO_POS_END);
|
||||
break;
|
||||
case GX_VA_NRM:
|
||||
if (type != GX_NONE) {
|
||||
__GXData->hasNrms = TRUE;
|
||||
__GXData->hasBiNrms = FALSE;
|
||||
__GXData->nrmType = type;
|
||||
} else {
|
||||
__GXData->hasNrms = FALSE;
|
||||
}
|
||||
break;
|
||||
case GX_VA_NBT:
|
||||
if (type != GX_NONE) {
|
||||
__GXData->hasBiNrms = TRUE;
|
||||
__GXData->hasNrms = FALSE;
|
||||
__GXData->nrmType = type;
|
||||
} else {
|
||||
__GXData->hasBiNrms = FALSE;
|
||||
}
|
||||
break;
|
||||
case GX_VA_CLR0:
|
||||
GX_SET_REG(__GXData->vcdLo, type, GX_CP_VCD_LO_CLRDIF_ST, GX_CP_VCD_LO_CLRDIF_END);
|
||||
break;
|
||||
case GX_VA_CLR1:
|
||||
GX_SET_REG(__GXData->vcdLo, type, GX_CP_VCD_LO_CLRSPEC_ST, GX_CP_VCD_LO_CLRSPEC_END);
|
||||
break;
|
||||
case GX_VA_TEX0:
|
||||
GX_SET_REG(__GXData->vcdHi, type, GX_CP_VCD_HI_TEX0COORD_ST, GX_CP_VCD_HI_TEX0COORD_END);
|
||||
break;
|
||||
case GX_VA_TEX1:
|
||||
GX_SET_REG(__GXData->vcdHi, type, GX_CP_VCD_HI_TEX1COORD_ST, GX_CP_VCD_HI_TEX1COORD_END);
|
||||
break;
|
||||
case GX_VA_TEX2:
|
||||
GX_SET_REG(__GXData->vcdHi, type, GX_CP_VCD_HI_TEX2COORD_ST, GX_CP_VCD_HI_TEX2COORD_END);
|
||||
break;
|
||||
case GX_VA_TEX3:
|
||||
GX_SET_REG(__GXData->vcdHi, type, GX_CP_VCD_HI_TEX3COORD_ST, GX_CP_VCD_HI_TEX3COORD_END);
|
||||
break;
|
||||
case GX_VA_TEX4:
|
||||
GX_SET_REG(__GXData->vcdHi, type, GX_CP_VCD_HI_TEX4COORD_ST, GX_CP_VCD_HI_TEX4COORD_END);
|
||||
break;
|
||||
case GX_VA_TEX5:
|
||||
GX_SET_REG(__GXData->vcdHi, type, GX_CP_VCD_HI_TEX5COORD_ST, GX_CP_VCD_HI_TEX5COORD_END);
|
||||
break;
|
||||
case GX_VA_TEX6:
|
||||
GX_SET_REG(__GXData->vcdHi, type, GX_CP_VCD_HI_TEX6COORD_ST, GX_CP_VCD_HI_TEX6COORD_END);
|
||||
break;
|
||||
case GX_VA_TEX7:
|
||||
GX_SET_REG(__GXData->vcdHi, type, GX_CP_VCD_HI_TEX7COORD_ST, GX_CP_VCD_HI_TEX7COORD_END);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void GXSetVtxDesc(GXAttr name, GXAttrType type) {
|
||||
SETVCDATTR(name, type);
|
||||
|
||||
// Set normal data type if enabled
|
||||
if (__GXData->hasNrms || __GXData->hasBiNrms) {
|
||||
GX_BITFIELD_SET(__GXData->vcdLo, 19, 2, __GXData->nrmType);
|
||||
} else {
|
||||
GX_BITFIELD_SET(__GXData->vcdLo, 19, 2, 0);
|
||||
}
|
||||
|
||||
__GXData->dirtyState |= GX_DIRTY_VCD;
|
||||
}
|
||||
|
||||
void GXSetVtxDescv(GXVtxDescList* list) {
|
||||
for (; list->attr != GX_VA_NULL; list++) {
|
||||
SETVCDATTR(list->attr, list->type);
|
||||
}
|
||||
|
||||
// Set normal data type if enabled
|
||||
if (__GXData->hasNrms || __GXData->hasBiNrms) {
|
||||
GX_BITFIELD_SET(__GXData->vcdLo, 19, 2, __GXData->nrmType);
|
||||
} else {
|
||||
GX_BITFIELD_SET(__GXData->vcdLo, 19, 2, 0);
|
||||
}
|
||||
|
||||
__GXData->dirtyState |= GX_DIRTY_VCD;
|
||||
}
|
||||
|
||||
static void __GXXfVtxSpecs(void) {
|
||||
u32 normCount, colorCount, texCount;
|
||||
|
||||
normCount = __GXData->hasBiNrms ? 2 : (__GXData->hasNrms ? 1 : 0);
|
||||
|
||||
// Both fields in one access
|
||||
colorCount = 33 - __cntlzw((__GXData->vcdLo & (0xf << 0xd)) >> 0xd);
|
||||
colorCount /= 2; // equivalent to /=2 and >>= 1
|
||||
|
||||
// All 16 assigned bits in VCD_Hi
|
||||
texCount = 33 - __cntlzw((__GXData->vcdHi & (0xffff << 0)) >> 0);
|
||||
texCount /= 2; // equivalent to /=2 and >>= 1
|
||||
|
||||
GX_XF_LOAD_REG(GX_XF_REG_INVERTEXSPEC, (colorCount) | (normCount << 2) | (texCount << 4));
|
||||
__GXData->bpSentNot = GX_TRUE;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void __GXSetVCD(void) {
|
||||
GX_CP_LOAD_REG(GX_CP_REG_VCD_LO, __GXData->vcdLo);
|
||||
GX_CP_LOAD_REG(GX_CP_REG_VCD_HI, __GXData->vcdHi);
|
||||
|
||||
__GXXfVtxSpecs();
|
||||
}
|
||||
|
||||
void __GXCalculateVLim(void) {
|
||||
static u8 tbl1[] = {0, 4, 1, 2};
|
||||
static u8 tbl2[] = {0, 8, 1, 2};
|
||||
static u8 tbl3[] = {0, 12, 1, 2};
|
||||
|
||||
u32 vlim;
|
||||
u32 vcdLoReg;
|
||||
u32 vcdHiReg;
|
||||
s32 compCnt;
|
||||
|
||||
if (__GXData->vNum == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
vcdLoReg = __GXData->vcdLo;
|
||||
vcdHiReg = __GXData->vcdHi;
|
||||
|
||||
// GXCompCnt bit of normal parameters
|
||||
compCnt = __GXData->vatA[GX_VTXFMT0];
|
||||
compCnt = (compCnt & 0x200) >> 9;
|
||||
|
||||
vlim = GX_GET_REG(vcdLoReg, GX_CP_VCD_LO_POSMTXIDX_ST, GX_CP_VCD_LO_POSMTXIDX_END);
|
||||
vlim += GX_GET_REG(vcdLoReg, GX_CP_VCD_LO_TEX0MTXIDX_ST, GX_CP_VCD_LO_TEX0MTXIDX_END);
|
||||
vlim += GX_GET_REG(vcdLoReg, GX_CP_VCD_LO_TEX1MTXIDX_ST, GX_CP_VCD_LO_TEX1MTXIDX_END);
|
||||
vlim += GX_GET_REG(vcdLoReg, GX_CP_VCD_LO_TEX2MTXIDX_ST, GX_CP_VCD_LO_TEX2MTXIDX_END);
|
||||
vlim += GX_GET_REG(vcdLoReg, GX_CP_VCD_LO_TEX3MTXIDX_ST, GX_CP_VCD_LO_TEX3MTXIDX_END);
|
||||
vlim += GX_GET_REG(vcdLoReg, GX_CP_VCD_LO_TEX4MTXIDX_ST, GX_CP_VCD_LO_TEX4MTXIDX_END);
|
||||
vlim += GX_GET_REG(vcdLoReg, GX_CP_VCD_LO_TEX5MTXIDX_ST, GX_CP_VCD_LO_TEX5MTXIDX_END);
|
||||
vlim += GX_GET_REG(vcdLoReg, GX_CP_VCD_LO_TEX6MTXIDX_ST, GX_CP_VCD_LO_TEX6MTXIDX_END);
|
||||
vlim += GX_GET_REG(vcdLoReg, GX_CP_VCD_LO_TEX7MTXIDX_ST, GX_CP_VCD_LO_TEX7MTXIDX_END);
|
||||
|
||||
vlim += tbl3[GX_GET_REG(vcdLoReg, GX_CP_VCD_LO_POS_ST, GX_CP_VCD_LO_POS_END)];
|
||||
vlim += tbl3[GX_GET_REG(vcdLoReg, GX_CP_VCD_LO_NRM_ST, GX_CP_VCD_LO_NRM_END)] *
|
||||
(compCnt == GX_NRM_NBT ? 3 : 1);
|
||||
vlim += tbl1[GX_GET_REG(vcdLoReg, GX_CP_VCD_LO_CLRDIF_ST, GX_CP_VCD_LO_CLRDIF_END)];
|
||||
vlim += tbl1[GX_GET_REG(vcdLoReg, GX_CP_VCD_LO_CLRSPEC_ST, GX_CP_VCD_LO_CLRSPEC_END)];
|
||||
|
||||
vlim += tbl2[GX_GET_REG(vcdHiReg, GX_CP_VCD_HI_TEX0COORD_ST, GX_CP_VCD_HI_TEX0COORD_END)];
|
||||
vlim += tbl2[GX_GET_REG(vcdHiReg, GX_CP_VCD_HI_TEX1COORD_ST, GX_CP_VCD_HI_TEX1COORD_END)];
|
||||
vlim += tbl2[GX_GET_REG(vcdHiReg, GX_CP_VCD_HI_TEX2COORD_ST, GX_CP_VCD_HI_TEX2COORD_END)];
|
||||
vlim += tbl2[GX_GET_REG(vcdHiReg, GX_CP_VCD_HI_TEX3COORD_ST, GX_CP_VCD_HI_TEX3COORD_END)];
|
||||
vlim += tbl2[GX_GET_REG(vcdHiReg, GX_CP_VCD_HI_TEX4COORD_ST, GX_CP_VCD_HI_TEX4COORD_END)];
|
||||
vlim += tbl2[GX_GET_REG(vcdHiReg, GX_CP_VCD_HI_TEX5COORD_ST, GX_CP_VCD_HI_TEX5COORD_END)];
|
||||
vlim += tbl2[GX_GET_REG(vcdHiReg, GX_CP_VCD_HI_TEX6COORD_ST, GX_CP_VCD_HI_TEX6COORD_END)];
|
||||
vlim += tbl2[GX_GET_REG(vcdHiReg, GX_CP_VCD_HI_TEX7COORD_ST, GX_CP_VCD_HI_TEX7COORD_END)];
|
||||
|
||||
__GXData->vLim = vlim;
|
||||
}
|
||||
|
||||
void GXGetVtxDesc(int param_0, GXAttrType* param_1) {
|
||||
int local_38;
|
||||
|
||||
switch (param_0) {
|
||||
case 0:
|
||||
local_38 = __GXData->vcdLo & 1;
|
||||
break;
|
||||
case 1:
|
||||
local_38 = (__GXData->vcdLo & 2) >> 1;
|
||||
break;
|
||||
case 2:
|
||||
local_38 = (__GXData->vcdLo & 4) >> 2;
|
||||
break;
|
||||
case 3:
|
||||
local_38 = (__GXData->vcdLo & 8) >> 3;
|
||||
break;
|
||||
case 4:
|
||||
local_38 = (__GXData->vcdLo & 0x10) >> 4;
|
||||
break;
|
||||
case 5:
|
||||
local_38 = (__GXData->vcdLo & 0x20) >> 5;
|
||||
break;
|
||||
case 6:
|
||||
local_38 = (__GXData->vcdLo & 0x40) >> 6;
|
||||
break;
|
||||
case 7:
|
||||
local_38 = (__GXData->vcdLo & 0x80) >> 7;
|
||||
break;
|
||||
case 8:
|
||||
local_38 = (__GXData->vcdLo & 0x100) >> 8;
|
||||
break;
|
||||
case 9:
|
||||
local_38 = (__GXData->vcdLo & 0x600) >> 9;
|
||||
break;
|
||||
case 10:
|
||||
if (__GXData->hasNrms != 0) {
|
||||
local_38 = (__GXData->vcdLo & 0x1800) >> 11;
|
||||
} else {
|
||||
local_38 = 0;
|
||||
}
|
||||
break;
|
||||
case 0x19:
|
||||
if (__GXData->hasBiNrms != 0) {
|
||||
local_38 = (__GXData->vcdLo & 0x1800) >> 11;
|
||||
} else {
|
||||
local_38 = 0;
|
||||
}
|
||||
break;
|
||||
case 11:
|
||||
local_38 = (__GXData->vcdLo & 0x6000) >> 13;
|
||||
break;
|
||||
case 12:
|
||||
local_38 = (__GXData->vcdLo & 0x18000) >> 15;
|
||||
break;
|
||||
case 13:
|
||||
local_38 = (__GXData->vcdHi & 3);
|
||||
break;
|
||||
case 14:
|
||||
local_38 = (__GXData->vcdHi & 0xC) >> 2;
|
||||
break;
|
||||
case 15:
|
||||
local_38 = (__GXData->vcdHi & 0x30) >> 4;
|
||||
break;
|
||||
case 16:
|
||||
local_38 = (__GXData->vcdHi & 0xC0) >> 6;
|
||||
break;
|
||||
case 17:
|
||||
local_38 = (__GXData->vcdHi & 0x300) >> 8;
|
||||
break;
|
||||
case 18:
|
||||
local_38 = (__GXData->vcdHi & 0xC00) >> 10;
|
||||
break;
|
||||
case 19:
|
||||
local_38 = (__GXData->vcdHi & 0x3000) >> 12;
|
||||
break;
|
||||
case 20:
|
||||
local_38 = (__GXData->vcdHi & 0xC000) >> 14;
|
||||
break;
|
||||
default:
|
||||
local_38 = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
*param_1 = local_38;
|
||||
}
|
||||
|
||||
void GXGetVtxDescv(GXVtxDescList* attrPtr) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i <= 0x14; i++) {
|
||||
attrPtr[i].attr = (GXAttr)i;
|
||||
GXGetVtxDesc(i, &attrPtr[i].type);
|
||||
}
|
||||
|
||||
attrPtr[i].attr = (GXAttr)0x19;
|
||||
GXGetVtxDesc(0x19, &attrPtr[i].type);
|
||||
|
||||
i++;
|
||||
attrPtr[i].attr = (GXAttr)0xFF;
|
||||
}
|
||||
|
||||
void GXClearVtxDesc(void) {
|
||||
__GXData->vcdLo = 0;
|
||||
GX_BITFIELD_SET(__GXData->vcdLo, 0x15, 2, GX_DIRECT);
|
||||
__GXData->vcdHi = 0;
|
||||
__GXData->hasNrms = FALSE;
|
||||
__GXData->hasBiNrms = FALSE;
|
||||
__GXData->dirtyState |= GX_DIRTY_VCD;
|
||||
}
|
||||
|
||||
/* ############################################################################################## */
|
||||
|
||||
static inline void SETVAT(u32* vatA, u32* vatB, u32* vatC, GXAttr attr, GXCompCnt compCnt,
|
||||
GXCompType compType, u8 shift) {
|
||||
switch (attr) {
|
||||
case GX_VA_POS:
|
||||
GX_SET_REG(*vatA, compCnt, GX_CP_VAT_GRP0_POS_CNT_ST, GX_CP_VAT_GRP0_POS_CNT_END);
|
||||
GX_SET_REG(*vatA, compType, GX_CP_VAT_GRP0_POS_TYPE_ST, GX_CP_VAT_GRP0_POS_TYPE_END);
|
||||
GX_SET_REG(*vatA, shift, GX_CP_VAT_GRP0_POS_SHIFT_ST, GX_CP_VAT_GRP0_POS_SHIFT_END);
|
||||
break;
|
||||
case GX_VA_NRM:
|
||||
case GX_VA_NBT:
|
||||
GX_SET_REG(*vatA, compType, GX_CP_VAT_GRP0_NRM_TYPE_ST, GX_CP_VAT_GRP0_NRM_TYPE_END);
|
||||
if (compCnt == GX_NRM_NBT3) {
|
||||
// Probably because the compCnt can only be one bit?
|
||||
GX_SET_REG(*vatA, GX_NRM_NBT, GX_CP_VAT_GRP0_NRM_CNT_ST, GX_CP_VAT_GRP0_NRM_CNT_END);
|
||||
GX_SET_REG(*vatA, TRUE, GX_CP_VAT_GRP0_NRMIDX3_ST, GX_CP_VAT_GRP0_NRMIDX3_END);
|
||||
} else {
|
||||
GX_SET_REG(*vatA, compCnt, GX_CP_VAT_GRP0_NRM_CNT_ST, GX_CP_VAT_GRP0_NRM_CNT_END);
|
||||
GX_SET_REG(*vatA, FALSE, GX_CP_VAT_GRP0_NRMIDX3_ST, GX_CP_VAT_GRP0_NRMIDX3_END);
|
||||
}
|
||||
break;
|
||||
case GX_VA_CLR0:
|
||||
GX_SET_REG(*vatA, compCnt, GX_CP_VAT_GRP0_CLRDIFF_CNT_ST, GX_CP_VAT_GRP0_CLRDIFF_CNT_END);
|
||||
GX_SET_REG(*vatA, compType, GX_CP_VAT_GRP0_CLRDIFF_TYPE_ST,
|
||||
GX_CP_VAT_GRP0_CLRDIFF_TYPE_END);
|
||||
break;
|
||||
case GX_VA_CLR1:
|
||||
GX_SET_REG(*vatA, compCnt, GX_CP_VAT_GRP0_CLRSPEC_CNT_ST, GX_CP_VAT_GRP0_CLRSPEC_CNT_END);
|
||||
GX_SET_REG(*vatA, compType, GX_CP_VAT_GRP0_CLRSPEC_TYPE_ST,
|
||||
GX_CP_VAT_GRP0_CLRSPEC_TYPE_END);
|
||||
break;
|
||||
case GX_VA_TEX0:
|
||||
GX_SET_REG(*vatA, compCnt, GX_CP_VAT_GRP0_TXC0_CNT_ST, GX_CP_VAT_GRP0_TXC0_CNT_END);
|
||||
GX_SET_REG(*vatA, compType, GX_CP_VAT_GRP0_TXC0_TYPE_ST, GX_CP_VAT_GRP0_TXC0_TYPE_END);
|
||||
GX_SET_REG(*vatA, shift, GX_CP_VAT_GRP0_TXC0_SHIFT_ST, GX_CP_VAT_GRP0_TXC0_SHIFT_END);
|
||||
break;
|
||||
case GX_VA_TEX1:
|
||||
GX_SET_REG(*vatB, compCnt, GX_CP_VAT_GRP1_TXC1_CNT_ST, GX_CP_VAT_GRP1_TXC1_CNT_END);
|
||||
GX_SET_REG(*vatB, compType, GX_CP_VAT_GRP1_TXC1_TYPE_ST, GX_CP_VAT_GRP1_TXC1_TYPE_END);
|
||||
GX_SET_REG(*vatB, shift, GX_CP_VAT_GRP1_TXC1_SHIFT_ST, GX_CP_VAT_GRP1_TXC1_SHIFT_END);
|
||||
break;
|
||||
case GX_VA_TEX2:
|
||||
GX_SET_REG(*vatB, compCnt, GX_CP_VAT_GRP1_TXC2_CNT_ST, GX_CP_VAT_GRP1_TXC2_CNT_END);
|
||||
GX_SET_REG(*vatB, compType, GX_CP_VAT_GRP1_TXC2_TYPE_ST, GX_CP_VAT_GRP1_TXC2_TYPE_END);
|
||||
GX_SET_REG(*vatB, shift, GX_CP_VAT_GRP1_TXC2_SHIFT_ST, GX_CP_VAT_GRP1_TXC2_SHIFT_END);
|
||||
break;
|
||||
case GX_VA_TEX3:
|
||||
GX_SET_REG(*vatB, compCnt, GX_CP_VAT_GRP1_TXC3_CNT_ST, GX_CP_VAT_GRP1_TXC3_CNT_END);
|
||||
GX_SET_REG(*vatB, compType, GX_CP_VAT_GRP1_TXC3_TYPE_ST, GX_CP_VAT_GRP1_TXC3_TYPE_END);
|
||||
GX_SET_REG(*vatB, shift, GX_CP_VAT_GRP1_TXC3_SHIFT_ST, GX_CP_VAT_GRP1_TXC3_SHIFT_END);
|
||||
break;
|
||||
case GX_VA_TEX4:
|
||||
GX_SET_REG(*vatB, compCnt, GX_CP_VAT_GRP1_TXC4_CNT_ST, GX_CP_VAT_GRP1_TXC4_CNT_END);
|
||||
GX_SET_REG(*vatB, compType, GX_CP_VAT_GRP1_TXC4_TYPE_ST, GX_CP_VAT_GRP1_TXC4_TYPE_END);
|
||||
GX_SET_REG(*vatC, shift, GX_CP_VAT_GRP2_TXC4_SHIFT_ST, GX_CP_VAT_GRP2_TXC4_SHIFT_END);
|
||||
break;
|
||||
case GX_VA_TEX5:
|
||||
GX_SET_REG(*vatC, compCnt, GX_CP_VAT_GRP2_TXC5_CNT_ST, GX_CP_VAT_GRP2_TXC5_CNT_END);
|
||||
GX_SET_REG(*vatC, compType, GX_CP_VAT_GRP2_TXC5_TYPE_ST, GX_CP_VAT_GRP2_TXC5_TYPE_END);
|
||||
GX_SET_REG(*vatC, shift, GX_CP_VAT_GRP2_TXC5_SHIFT_ST, GX_CP_VAT_GRP2_TXC5_SHIFT_END);
|
||||
break;
|
||||
case GX_VA_TEX6:
|
||||
GX_SET_REG(*vatC, compCnt, GX_CP_VAT_GRP2_TXC6_CNT_ST, GX_CP_VAT_GRP2_TXC6_CNT_END);
|
||||
GX_SET_REG(*vatC, compType, GX_CP_VAT_GRP2_TXC6_TYPE_ST, GX_CP_VAT_GRP2_TXC6_TYPE_END);
|
||||
GX_SET_REG(*vatC, shift, GX_CP_VAT_GRP2_TXC6_SHIFT_ST, GX_CP_VAT_GRP2_TXC6_SHIFT_END);
|
||||
break;
|
||||
case GX_VA_TEX7:
|
||||
GX_SET_REG(*vatC, compCnt, GX_CP_VAT_GRP2_TXC7_CNT_ST, GX_CP_VAT_GRP2_TXC7_CNT_END);
|
||||
GX_SET_REG(*vatC, compType, GX_CP_VAT_GRP2_TXC7_TYPE_ST, GX_CP_VAT_GRP2_TXC7_TYPE_END);
|
||||
GX_SET_REG(*vatC, shift, GX_CP_VAT_GRP2_TXC7_SHIFT_ST, GX_CP_VAT_GRP2_TXC7_SHIFT_END);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void GXSetVtxAttrFmt(GXVtxFmt format, GXAttr attr, GXCompCnt count, GXCompType type, u8 frac) {
|
||||
u32* vA = (u32*)&__GXData->vatA[format];
|
||||
u32* vB = (u32*)&__GXData->vatB[format];
|
||||
u32* vC = &__GXData->vatC[format];
|
||||
|
||||
SETVAT(vA, vB, vC, attr, count, type, frac);
|
||||
|
||||
__GXData->dirtyState |= GX_DIRTY_VAT;
|
||||
__GXData->dirtyVAT |= (u8)(1 << (u8)format);
|
||||
}
|
||||
|
||||
void GXSetVtxAttrFmtv(GXVtxFmt format, GXVtxAttrFmtList* list) {
|
||||
u32* vatA;
|
||||
u32* vatB;
|
||||
u32* vatC;
|
||||
|
||||
vatA = (u32*)&__GXData->vatA[format];
|
||||
vatB = (u32*)&__GXData->vatB[format];
|
||||
vatC = &__GXData->vatC[format];
|
||||
|
||||
for (; list->mAttrib != GX_VA_NULL; list++) {
|
||||
SETVAT(vatA, vatB, vatC, list->mAttrib, list->mCompCnt, list->mCompType, list->mCompShift);
|
||||
}
|
||||
|
||||
__GXData->dirtyState |= GX_DIRTY_VAT;
|
||||
__GXData->dirtyVAT |= (u8)(1 << (u8)format);
|
||||
}
|
||||
|
||||
void __GXSetVAT(void) {
|
||||
u32 i = 0;
|
||||
u32 dirtyVAT = __GXData->dirtyVAT;
|
||||
do {
|
||||
if (dirtyVAT & (1)) {
|
||||
GX_CP_LOAD_REG(GX_CP_REG_VAT_GRP0 | i, __GXData->vatA[i]);
|
||||
GX_CP_LOAD_REG(GX_CP_REG_VAT_GRP1 | i, __GXData->vatB[i]);
|
||||
GX_CP_LOAD_REG(GX_CP_REG_VAT_GRP2 | i, __GXData->vatC[i]);
|
||||
}
|
||||
dirtyVAT >>= 1;
|
||||
i++;
|
||||
} while (dirtyVAT != 0);
|
||||
|
||||
__GXData->dirtyVAT = 0;
|
||||
}
|
||||
|
||||
static u8 GetFracForNrm(int param_0) {
|
||||
int var_r31;
|
||||
|
||||
switch (param_0) {
|
||||
case 1:
|
||||
var_r31 = 6;
|
||||
break;
|
||||
case 3:
|
||||
var_r31 = 14;
|
||||
break;
|
||||
default:
|
||||
case 2:
|
||||
var_r31 = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return var_r31;
|
||||
}
|
||||
|
||||
void GXGetVtxAttrFmtv(GXVtxFmt param_0, GXVtxAttrFmtList* param_1) {
|
||||
s32 tmp;
|
||||
s32 tmp2;
|
||||
s32 tmp3;
|
||||
int i;
|
||||
|
||||
#ifdef DEBUG
|
||||
// not fully matching
|
||||
/* tmp = 1;
|
||||
if (data_8074d3c8 != 0) {
|
||||
OSPanic("GXAttr.c", 941, "\'GXGetVtxAttrFmtv\' is not allowed between GXBegin/GXEnd");
|
||||
tmp = 0;
|
||||
}
|
||||
|
||||
tmp2 = 1;
|
||||
if (param_1 == NULL) {
|
||||
OSPanic("GXAttr.c", 942, "GXSetVtxAttrFmt: list pointer is NULL");
|
||||
tmp2 = 0;
|
||||
}
|
||||
|
||||
tmp3 = 1;
|
||||
if (param_0 >= 8) {
|
||||
OSPanic("GXAttr.c", 943, "GXSetVtxAttrFmt: Format Index is out of range");
|
||||
tmp3 = 0;
|
||||
} */
|
||||
#endif
|
||||
|
||||
for (i = 9; i <= 0x14; i++) {
|
||||
param_1->mAttrib = i;
|
||||
GXGetVtxAttrFmt(param_0, i, ¶m_1->mCompCnt, ¶m_1->mCompType, ¶m_1->mCompShift);
|
||||
param_1++;
|
||||
}
|
||||
|
||||
param_1->mAttrib = 0xFF;
|
||||
}
|
||||
|
||||
void GXGetVtxAttrFmt(GXVtxFmt param_0, int param_1, GXCompCnt* param_2, GXCompType* param_3,
|
||||
u8* param_4) {
|
||||
s32 tmp;
|
||||
s32 tmp2;
|
||||
GXCompCnt* tmp_1;
|
||||
GXCompCnt* tmp_2;
|
||||
u32* tmp_3;
|
||||
|
||||
#ifdef DEBUG
|
||||
// not fully matching
|
||||
/* tmp = 1;
|
||||
if (data_8074d3c8) {
|
||||
OSPanic("GXAttr.c", 844, "\'GXGetVtxAttrFmt\' is not allowed between GXBegin/GXEnd");
|
||||
tmp = 0;
|
||||
}
|
||||
|
||||
tmp2 = 1;
|
||||
if (param_0 >= 8) {
|
||||
OSPanic("GXAttr.c", 845, "GXSetVtxAttrFmt: Format Index is out of range");
|
||||
tmp2 = 0;
|
||||
} */
|
||||
#endif
|
||||
|
||||
tmp_1 = (GXCompCnt*)&__GXData->vatA[param_0];
|
||||
tmp_2 = (GXCompCnt*)&__GXData->vatB[param_0];
|
||||
tmp_3 = &__GXData->vatC[param_0];
|
||||
|
||||
switch (param_1) {
|
||||
case 9:
|
||||
*param_2 = *tmp_1 & 1;
|
||||
*param_3 = (*tmp_1 & 0xE) >> 1;
|
||||
*param_4 = (*tmp_1 & 0x1F0) >> 4;
|
||||
break;
|
||||
case 10:
|
||||
case 0x19:
|
||||
*param_2 = (*tmp_1 & 0x200) >> 9;
|
||||
if (*param_2 == 1 && ((*tmp_1 & 0x80000000) >> 31) != 0) {
|
||||
*param_2 = 2;
|
||||
}
|
||||
|
||||
*param_3 = (*tmp_1 & 0x1C00) >> 10;
|
||||
*param_4 = GetFracForNrm(*param_3);
|
||||
break;
|
||||
case 11:
|
||||
*param_2 = (*tmp_1 & 0x2000) >> 0xd;
|
||||
*param_3 = (*tmp_1 & 0x1C000) >> 0xe;
|
||||
*param_4 = 0;
|
||||
break;
|
||||
case 12:
|
||||
*param_2 = (*tmp_1 & 0x20000) >> 0x11;
|
||||
*param_3 = (*tmp_1 & 0x1C0000) >> 0x12;
|
||||
*param_4 = 0;
|
||||
break;
|
||||
case 13:
|
||||
*param_2 = (*tmp_1 & 0x200000) >> 0x15;
|
||||
*param_3 = (*tmp_1 & 0x1C00000) >> 0x16;
|
||||
*param_4 = ((*tmp_1 & 0x3e000000)) >> 25;
|
||||
break;
|
||||
case 14:
|
||||
*param_2 = *tmp_2 & 1;
|
||||
*param_3 = (*tmp_2 & 0xE) >> 1;
|
||||
*param_4 = (*tmp_2 & 0x1F0) >> 4;
|
||||
break;
|
||||
case 15:
|
||||
*param_2 = (*tmp_2 & 0x200) >> 9;
|
||||
*param_3 = (*tmp_2 & 0x1C00) >> 10;
|
||||
*param_4 = (*tmp_2 & 0x3E000) >> 13;
|
||||
break;
|
||||
case 16:
|
||||
*param_2 = (*tmp_2 & 0x40000) >> 0x12;
|
||||
*param_3 = (*tmp_2 & 0x380000) >> 0x13;
|
||||
*param_4 = (*tmp_2 & 0x7C00000) >> 0x16;
|
||||
break;
|
||||
case 17:
|
||||
*param_2 = (*tmp_2 & 0x8000000) >> 0x1B;
|
||||
*param_3 = (*tmp_2 & 0x70000000) >> 0x1C;
|
||||
*param_4 = (*tmp_3 & 0x1F);
|
||||
break;
|
||||
case 18:
|
||||
*param_2 = (*tmp_3 & 0x20) >> 5;
|
||||
*param_3 = (*tmp_3 & 0x1C0) >> 6;
|
||||
*param_4 = (*tmp_3 & 0x3E00) >> 9;
|
||||
break;
|
||||
case 19:
|
||||
*param_2 = (*tmp_3 & 0x4000) >> 0xe;
|
||||
*param_3 = (*tmp_3 & 0x38000) >> 0xf;
|
||||
*param_4 = (*tmp_3 & 0x7c0000) >> 0x12;
|
||||
break;
|
||||
case 20:
|
||||
*param_2 = (*tmp_3 & 0x800000) >> 0x17;
|
||||
*param_3 = (*tmp_3 & 0x7000000) >> 0x18;
|
||||
*param_4 = (*tmp_3 & 0xF8000000) >> 0x1b;
|
||||
break;
|
||||
default:
|
||||
*param_2 = 1;
|
||||
*param_3 = 0;
|
||||
*param_4 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void GXSetArray(GXAttr attr, void* basePtr, u8 stride) {
|
||||
s32 newAttr;
|
||||
s32 attrReg;
|
||||
|
||||
newAttr = attr;
|
||||
if (newAttr == GX_VA_NBT) {
|
||||
newAttr = GX_VA_NRM;
|
||||
}
|
||||
|
||||
attrReg = newAttr - GX_VA_POS;
|
||||
|
||||
GX_CP_LOAD_REG(GX_BP_REG_SETMODE0_TEX4 | attrReg,
|
||||
// Address -> offset?
|
||||
(u32)basePtr & ~0xC0000000);
|
||||
|
||||
GX_CP_LOAD_REG(GX_BP_REG_SETIMAGE2_TEX4 | attrReg, stride);
|
||||
}
|
||||
|
||||
void GXInvalidateVtxCache(void) {
|
||||
GXFIFO.u8 = GX_FIFO_CMD_INVAL_VTX;
|
||||
}
|
||||
|
||||
void GXSetTexCoordGen2(GXTexCoordID id, GXTexGenType type, GXTexGenSrc src, u32 texMtxIdx,
|
||||
GXBool normalize, u32 dualTexMtxIdx) {
|
||||
u32 reg;
|
||||
u32 inputRow;
|
||||
GXXfTexReg inputForm;
|
||||
|
||||
reg = 0;
|
||||
inputForm = GX_XF_TEX_FORM_AB11;
|
||||
inputRow = 5;
|
||||
|
||||
switch (src) {
|
||||
case GX_TG_POS:
|
||||
inputRow = 0;
|
||||
inputForm = GX_XF_TEX_FORM_ABC1;
|
||||
break;
|
||||
case GX_TG_NRM:
|
||||
inputRow = 1;
|
||||
inputForm = GX_XF_TEX_FORM_ABC1;
|
||||
break;
|
||||
case GX_TG_BINRM:
|
||||
inputRow = 3;
|
||||
inputForm = GX_XF_TEX_FORM_ABC1;
|
||||
break;
|
||||
case GX_TG_TANGENT:
|
||||
inputRow = 4;
|
||||
inputForm = GX_XF_TEX_FORM_ABC1;
|
||||
break;
|
||||
case GX_TG_COLOR0:
|
||||
inputRow = 2;
|
||||
break;
|
||||
case GX_TG_COLOR1:
|
||||
inputRow = 2;
|
||||
break;
|
||||
case GX_TG_TEX0:
|
||||
inputRow = 5;
|
||||
break;
|
||||
case GX_TG_TEX1:
|
||||
inputRow = 6;
|
||||
break;
|
||||
case GX_TG_TEX2:
|
||||
inputRow = 7;
|
||||
break;
|
||||
case GX_TG_TEX3:
|
||||
inputRow = 8;
|
||||
break;
|
||||
case GX_TG_TEX4:
|
||||
inputRow = 9;
|
||||
break;
|
||||
case GX_TG_TEX5:
|
||||
inputRow = 10;
|
||||
break;
|
||||
case GX_TG_TEX6:
|
||||
inputRow = 11;
|
||||
break;
|
||||
case GX_TG_TEX7:
|
||||
inputRow = 12;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case GX_TG_NRM:
|
||||
GX_SET_REG(reg, GX_XF_TEX_PROJ_ST, GX_XF_TEX_PROJTYPE_ST,
|
||||
GX_XF_TEX_PROJTYPE_END); // 2x4 projection
|
||||
GX_SET_REG(reg, inputForm, GX_XF_TEX_INPUTFORM_ST, GX_XF_TEX_INPUTFORM_END);
|
||||
GX_SET_REG(reg, GX_TG_POS, GX_XF_TEX_TEXGENTYPE_ST, GX_XF_TEX_TEXGENTYPE_END);
|
||||
GX_SET_REG(reg, inputRow, GX_XF_TEX_SRCROW_ST, GX_XF_TEX_SRCROW_END);
|
||||
break;
|
||||
case GX_TG_POS:
|
||||
GX_SET_REG(reg, GX_XF_TEX_PROJ_STQ, GX_XF_TEX_PROJTYPE_ST,
|
||||
GX_XF_TEX_PROJTYPE_END); // 3x4 projection
|
||||
GX_SET_REG(reg, inputForm, GX_XF_TEX_INPUTFORM_ST, GX_XF_TEX_INPUTFORM_END);
|
||||
GX_SET_REG(reg, GX_TG_POS, GX_XF_TEX_TEXGENTYPE_ST, GX_XF_TEX_TEXGENTYPE_END);
|
||||
GX_SET_REG(reg, inputRow, GX_XF_TEX_SRCROW_ST, GX_XF_TEX_SRCROW_END);
|
||||
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:
|
||||
GX_SET_REG(reg, GX_XF_TEX_PROJ_ST, GX_XF_TEX_PROJTYPE_ST,
|
||||
GX_XF_TEX_PROJTYPE_END); // 2x4 projection
|
||||
GX_SET_REG(reg, inputForm, GX_XF_TEX_INPUTFORM_ST, GX_XF_TEX_INPUTFORM_END);
|
||||
GX_SET_REG(reg, GX_TG_NRM, GX_XF_TEX_TEXGENTYPE_ST, GX_XF_TEX_TEXGENTYPE_END);
|
||||
GX_SET_REG(reg, inputRow, GX_XF_TEX_SRCROW_ST, GX_XF_TEX_SRCROW_END);
|
||||
GX_SET_REG(reg, src - GX_TG_TEXCOORD0, GX_XF_TEX_BUMPSRCTEX_ST, GX_XF_TEX_BUMPSRCTEX_END);
|
||||
GX_SET_REG(reg, type - GX_TG_BUMP0, GX_XF_TEX_BUMPSRCLIGHT_ST, GX_XF_TEX_BUMPSRCLIGHT_END);
|
||||
break;
|
||||
case GX_TG_SRTG:
|
||||
GX_SET_REG(reg, GX_XF_TEX_PROJ_ST, GX_XF_TEX_PROJTYPE_ST,
|
||||
GX_XF_TEX_PROJTYPE_END); // 2x4 projection
|
||||
GX_SET_REG(reg, inputForm, GX_XF_TEX_INPUTFORM_ST, GX_XF_TEX_INPUTFORM_END);
|
||||
|
||||
if (src == GX_TG_COLOR0) {
|
||||
GX_SET_REG(reg, GX_XF_TG_CLR0, GX_XF_TEX_TEXGENTYPE_ST, GX_XF_TEX_TEXGENTYPE_END);
|
||||
} else {
|
||||
GX_SET_REG(reg, GX_XF_TG_CLR1, GX_XF_TEX_TEXGENTYPE_ST, GX_XF_TEX_TEXGENTYPE_END);
|
||||
}
|
||||
GX_SET_REG(reg, 2, GX_XF_TEX_SRCROW_ST, GX_XF_TEX_SRCROW_END);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
GX_XF_LOAD_REG(GX_XF_REG_TEX0 + id, reg);
|
||||
|
||||
reg = 0;
|
||||
GX_SET_REG(reg, dualTexMtxIdx - 0x40, GX_XF_MTXIDX0_GEOM_ST, GX_XF_MTXIDX0_GEOM_END);
|
||||
GX_SET_REG(reg, normalize, GX_XF_DUALTEX_NORMALISE_ST, GX_XF_DUALTEX_NORMALISE_END);
|
||||
|
||||
GX_XF_LOAD_REG(GX_XF_REG_DUALTEX0 + id, reg);
|
||||
|
||||
switch (id) {
|
||||
case GX_TEXCOORD0:
|
||||
GX_SET_REG(__GXData->matIdxA, texMtxIdx, GX_XF_MTXIDX0_TEX0_ST, GX_XF_MTXIDX0_TEX0_END);
|
||||
break;
|
||||
case GX_TEXCOORD1:
|
||||
GX_SET_REG(__GXData->matIdxA, texMtxIdx, GX_XF_MTXIDX0_TEX1_ST, GX_XF_MTXIDX0_TEX1_END);
|
||||
break;
|
||||
case GX_TEXCOORD2:
|
||||
GX_SET_REG(__GXData->matIdxA, texMtxIdx, GX_XF_MTXIDX0_TEX2_ST, GX_XF_MTXIDX0_TEX2_END);
|
||||
break;
|
||||
case GX_TEXCOORD3:
|
||||
GX_SET_REG(__GXData->matIdxA, texMtxIdx, GX_XF_MTXIDX0_TEX3_ST, GX_XF_MTXIDX0_TEX3_END);
|
||||
break;
|
||||
case GX_TEXCOORD4:
|
||||
GX_SET_REG(__GXData->matIdxB, texMtxIdx, GX_XF_MTXIDX1_TEX4_ST, GX_XF_MTXIDX1_TEX4_END);
|
||||
break;
|
||||
case GX_TEXCOORD5:
|
||||
GX_SET_REG(__GXData->matIdxB, texMtxIdx, GX_XF_MTXIDX1_TEX5_ST, GX_XF_MTXIDX1_TEX5_END);
|
||||
break;
|
||||
case GX_TEXCOORD6:
|
||||
GX_SET_REG(__GXData->matIdxB, texMtxIdx, GX_XF_MTXIDX1_TEX6_ST, GX_XF_MTXIDX1_TEX6_END);
|
||||
break;
|
||||
default:
|
||||
GX_SET_REG(__GXData->matIdxB, texMtxIdx, GX_XF_MTXIDX1_TEX7_ST, GX_XF_MTXIDX1_TEX7_END);
|
||||
break;
|
||||
}
|
||||
__GXSetMatrixIndex(id + 1);
|
||||
}
|
||||
|
||||
void GXSetNumTexGens(u8 count) {
|
||||
GX_SET_REG(__GXData->genMode, count, GX_BP_GENMODE_NUMTEX_ST, GX_BP_GENMODE_NUMTEX_END);
|
||||
GX_XF_LOAD_REG(GX_XF_REG_NUMTEX, count);
|
||||
__GXData->dirtyState |= GX_DIRTY_GEN_MODE;
|
||||
}
|
194
src/dolphin/gx/GXBump.c
Normal file
194
src/dolphin/gx/GXBump.c
Normal file
@ -0,0 +1,194 @@
|
||||
/**
|
||||
* GXBump.c
|
||||
* Description:
|
||||
*/
|
||||
|
||||
#include "dolphin/gx/GXBump.h"
|
||||
#include "dolphin/gx/GX.h"
|
||||
|
||||
void GXSetTevIndirect(GXTevStageID tevStage, GXIndTexStageID texStage, GXIndTexFormat texFmt,
|
||||
GXIndTexBiasSel biasSel, GXIndTexMtxID mtxID, GXIndTexWrap wrapS,
|
||||
GXIndTexWrap wrapT, u8 addPrev, u8 utcLod, GXIndTexAlphaSel alphaSel) {
|
||||
u32 field = 0;
|
||||
u32 stage = tevStage + 0x10;
|
||||
|
||||
GX_BITFIELD_SET(field, 30, 2, texStage);
|
||||
GX_BITFIELD_SET(field, 28, 2, texFmt);
|
||||
GX_BITFIELD_SET(field, 25, 3, biasSel);
|
||||
GX_BITFIELD_SET(field, 23, 2, alphaSel);
|
||||
GX_BITFIELD_SET(field, 19, 4, mtxID);
|
||||
GX_BITFIELD_SET(field, 16, 3, wrapS);
|
||||
GX_BITFIELD_SET(field, 13, 3, wrapT);
|
||||
GX_BITFIELD_SET(field, 12, 1, utcLod);
|
||||
GX_BITFIELD_SET(field, 11, 1, addPrev);
|
||||
GX_BITFIELD_SET(field, 0, 8, stage);
|
||||
|
||||
GXFIFO.u8 = 0x61;
|
||||
GXFIFO.s32 = field;
|
||||
|
||||
__GXData->bpSentNot = 0;
|
||||
}
|
||||
|
||||
void GXSetIndTexMtx(GXIndTexMtxID mtxID, f32 offset[6], s8 scale_exp) {
|
||||
u32 val;
|
||||
u32 field;
|
||||
f32 mtx2[6];
|
||||
|
||||
scale_exp += 17;
|
||||
|
||||
switch (mtxID) {
|
||||
case GX_ITM_0:
|
||||
case GX_ITM_1:
|
||||
case GX_ITM_2:
|
||||
val = mtxID - 1;
|
||||
break;
|
||||
case GX_ITM_S0:
|
||||
case GX_ITM_S1:
|
||||
case GX_ITM_S2:
|
||||
val = mtxID - 5;
|
||||
break;
|
||||
case GX_ITM_T0:
|
||||
case GX_ITM_T1:
|
||||
case GX_ITM_T2:
|
||||
val = mtxID - 9;
|
||||
break;
|
||||
case GX_ITM_3:
|
||||
case GX_ITM_S3:
|
||||
default:
|
||||
val = 0;
|
||||
}
|
||||
|
||||
field = 0;
|
||||
GX_BITFIELD_SET(field, 21, 11, 1024.0f * offset[0]);
|
||||
GX_BITFIELD_SET(field, 10, 11, 1024.0f * offset[3]);
|
||||
GX_BITFIELD_SET(field, 8, 2, (scale_exp >> 0) & 3);
|
||||
GX_BITFIELD_SET(field, 0, 8, val * 3 + 6);
|
||||
GXFIFO.u8 = 0x61;
|
||||
GXFIFO.s32 = field;
|
||||
|
||||
field = 0;
|
||||
GX_BITFIELD_SET(field, 21, 11, 1024.0f * offset[1]);
|
||||
GX_BITFIELD_SET(field, 10, 11, 1024.0f * offset[4]);
|
||||
GX_BITFIELD_SET(field, 8, 2, (scale_exp >> 2) & 3);
|
||||
GX_BITFIELD_SET(field, 0, 8, val * 3 + 7);
|
||||
GXFIFO.u8 = 0x61;
|
||||
GXFIFO.s32 = field;
|
||||
|
||||
field = 0;
|
||||
GX_BITFIELD_SET(field, 21, 11, 1024.0f * offset[2]);
|
||||
GX_BITFIELD_SET(field, 10, 11, 1024.0f * offset[5]);
|
||||
GX_BITFIELD_SET(field, 8, 2, (scale_exp >> 4) & 3);
|
||||
GX_BITFIELD_SET(field, 0, 8, val * 3 + 8);
|
||||
GXFIFO.u8 = 0x61;
|
||||
GXFIFO.s32 = field;
|
||||
|
||||
__GXData->bpSentNot = 0;
|
||||
}
|
||||
|
||||
void GXSetIndTexCoordScale(GXIndTexStageID texStage, GXIndTexScale scaleS, GXIndTexScale scaleT) {
|
||||
GXData* data;
|
||||
|
||||
switch (texStage) {
|
||||
case GX_INDTEXSTAGE0:
|
||||
data = __GXData;
|
||||
GX_BITFIELD_SET(data->IndTexScale0, 28, 4, scaleS);
|
||||
GX_BITFIELD_SET(data->IndTexScale0, 24, 4, scaleT);
|
||||
GX_BITFIELD_SET(data->IndTexScale0, 0, 8, 0x25);
|
||||
GXFIFO.u8 = 0x61;
|
||||
GXFIFO.s32 = data->IndTexScale0;
|
||||
break;
|
||||
case GX_INDTEXSTAGE1:
|
||||
data = __GXData;
|
||||
GX_BITFIELD_SET(data->IndTexScale0, 20, 4, scaleS);
|
||||
GX_BITFIELD_SET(data->IndTexScale0, 16, 4, scaleT);
|
||||
GX_BITFIELD_SET(data->IndTexScale0, 0, 8, 0x25);
|
||||
GXFIFO.u8 = 0x61;
|
||||
GXFIFO.s32 = data->IndTexScale0;
|
||||
break;
|
||||
case GX_INDTEXSTAGE2:
|
||||
data = __GXData;
|
||||
GX_BITFIELD_SET(data->IndTexScale1, 28, 4, scaleS);
|
||||
GX_BITFIELD_SET(data->IndTexScale1, 24, 4, scaleT);
|
||||
GX_BITFIELD_SET(data->IndTexScale1, 0, 8, 0x26);
|
||||
GXFIFO.u8 = 0x61;
|
||||
GXFIFO.s32 = data->IndTexScale1;
|
||||
break;
|
||||
case GX_INDTEXSTAGE3:
|
||||
data = __GXData;
|
||||
GX_BITFIELD_SET(data->IndTexScale1, 20, 4, scaleS);
|
||||
GX_BITFIELD_SET(data->IndTexScale1, 16, 4, scaleT);
|
||||
GX_BITFIELD_SET(data->IndTexScale1, 0, 8, 0x26);
|
||||
GXFIFO.u8 = 0x61;
|
||||
GXFIFO.s32 = data->IndTexScale1;
|
||||
break;
|
||||
}
|
||||
|
||||
__GXData->bpSentNot = 0;
|
||||
}
|
||||
|
||||
void GXSetIndTexOrder(GXIndTexStageID stage, GXTexCoordID coord, GXTexMapID map) {
|
||||
GXData* data;
|
||||
|
||||
if (map == 0xFF) {
|
||||
map = GX_TEXMAP0;
|
||||
}
|
||||
|
||||
if (coord == 0xFF) {
|
||||
coord = GX_TEXCOORD0;
|
||||
}
|
||||
|
||||
switch (stage) {
|
||||
case GX_INDTEXSTAGE0:
|
||||
data = __GXData;
|
||||
GX_BITFIELD_SET(data->iref, 29, 3, map);
|
||||
GX_BITFIELD_SET(data->iref, 26, 3, coord);
|
||||
break;
|
||||
case GX_INDTEXSTAGE1:
|
||||
data = __GXData;
|
||||
GX_BITFIELD_SET(data->iref, 23, 3, map);
|
||||
GX_BITFIELD_SET(data->iref, 20, 3, coord);
|
||||
break;
|
||||
case GX_INDTEXSTAGE2:
|
||||
data = __GXData;
|
||||
GX_BITFIELD_SET(data->iref, 17, 3, map);
|
||||
GX_BITFIELD_SET(data->iref, 14, 3, coord);
|
||||
break;
|
||||
case GX_INDTEXSTAGE3:
|
||||
data = __GXData;
|
||||
GX_BITFIELD_SET(data->iref, 11, 3, map);
|
||||
GX_BITFIELD_SET(data->iref, 8, 3, coord);
|
||||
break;
|
||||
}
|
||||
|
||||
GXFIFO.u8 = 0x61;
|
||||
GXFIFO.s32 = __GXData->iref;
|
||||
GXSetWasteFlags();
|
||||
}
|
||||
|
||||
void GXSetNumIndStages(u8 num) {
|
||||
GXData* data = __GXData;
|
||||
GX_BITFIELD_SET(data->genMode, 13, 3, num);
|
||||
data->dirtyState |= GX_DIRTY_BP_MASK | GX_DIRTY_GEN_MODE;
|
||||
}
|
||||
|
||||
void GXSetTevDirect(GXTevStageID stage) {
|
||||
GXSetTevIndirect(stage, GX_INDTEXSTAGE0, GX_ITF_8, GX_ITB_NONE, GX_ITM_OFF, GX_ITW_OFF,
|
||||
GX_ITW_OFF, FALSE, FALSE, GX_ITBA_OFF);
|
||||
}
|
||||
|
||||
void __GXUpdateBPMask(void) {}
|
||||
|
||||
void __GXSetIndirectMask(u32 mask) {
|
||||
GXData* data = __GXData;
|
||||
|
||||
GX_BITFIELD_SET(data->bpMask, 24, 8, mask);
|
||||
GXFIFO.u8 = 0x61;
|
||||
GXFIFO.s32 = data->bpMask;
|
||||
data->bpSentNot = 0;
|
||||
}
|
||||
|
||||
void __GXFlushTextureState(void) {
|
||||
GXFIFO.u8 = 0x61;
|
||||
GXFIFO.s32 = __GXData->bpMask;
|
||||
__GXData->bpSentNot = 0;
|
||||
}
|
21
src/dolphin/gx/GXDisplayList.c
Normal file
21
src/dolphin/gx/GXDisplayList.c
Normal file
@ -0,0 +1,21 @@
|
||||
/**
|
||||
* GXDisplayList.c
|
||||
* Description:
|
||||
*/
|
||||
|
||||
#include "dolphin/gx/GXDisplayList.h"
|
||||
#include "dolphin/gx/GX.h"
|
||||
|
||||
void GXCallDisplayList(void* list, u32 nbytes) {
|
||||
if (__GXData->dirtyState != 0) {
|
||||
__GXSetDirtyState();
|
||||
}
|
||||
|
||||
if (*(u32*)__GXData == 0) {
|
||||
__GXSendFlushPrim();
|
||||
}
|
||||
|
||||
GXFIFO.u8 = 0x40;
|
||||
GXFIFO.u32 = (u32)list;
|
||||
GXFIFO.u32 = nbytes;
|
||||
}
|
71
src/dolphin/gx/GXDraw.c
Normal file
71
src/dolphin/gx/GXDraw.c
Normal file
@ -0,0 +1,71 @@
|
||||
#include "dolphin/gx/GXDraw.h"
|
||||
#include "dolphin/gx/GX.h"
|
||||
|
||||
static GXVtxDescList vcd[27];
|
||||
static GXVtxAttrFmtList vat[27];
|
||||
|
||||
void GetVertState(void) {
|
||||
GXGetVtxDescv(vcd);
|
||||
GXGetVtxAttrFmtv(GX_VTXFMT3, vat);
|
||||
GXClearVtxDesc();
|
||||
GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
|
||||
GXSetVtxDesc(GX_VA_NRM, GX_DIRECT);
|
||||
GXSetVtxAttrFmt(GX_VTXFMT3, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
|
||||
GXSetVtxAttrFmt(GX_VTXFMT3, GX_VA_NRM, GX_NRM_XYZ, GX_F32, 0);
|
||||
}
|
||||
|
||||
void RestoreVertState(void) {
|
||||
GXSetVtxDescv(vcd);
|
||||
GXSetVtxAttrFmtv(GX_VTXFMT3, vat);
|
||||
}
|
||||
|
||||
// doesn't fully match debug
|
||||
void GXDrawCylinder(u8 numEdges) {
|
||||
f32 temp_f29;
|
||||
f32 temp_f30;
|
||||
f32 temp_f31;
|
||||
|
||||
s32 i;
|
||||
|
||||
f32 sp1A0[100];
|
||||
f32 sp10[100];
|
||||
|
||||
temp_f31 = 1.0f;
|
||||
temp_f30 = -temp_f31;
|
||||
|
||||
GetVertState();
|
||||
for (i = 0; i <= numEdges; i++) {
|
||||
temp_f29 = (i * 2.0f * 3.141593f) / numEdges;
|
||||
sp1A0[i] = cosf(temp_f29);
|
||||
sp10[i] = sinf(temp_f29);
|
||||
}
|
||||
|
||||
GXBegin(GX_TRIANGLESTRIP, GX_VTXFMT3, (numEdges + 1) * 2);
|
||||
for (i = 0; i <= numEdges; i++) {
|
||||
GXPosition3f32(sp1A0[i], sp10[i], temp_f30);
|
||||
GXNormal3f32(sp1A0[i], sp10[i], 0.0f);
|
||||
GXPosition3f32(sp1A0[i], sp10[i], temp_f31);
|
||||
GXNormal3f32(sp1A0[i], sp10[i], 0.0f);
|
||||
}
|
||||
GXEnd();
|
||||
|
||||
GXBegin(GX_TRIANGLEFAN, GX_VTXFMT3, numEdges + 2);
|
||||
GXPosition3f32(0.0f, 0.0f, temp_f31);
|
||||
GXNormal3f32(0.0f, 0.0f, 1.0f);
|
||||
for (i = 0; i <= numEdges; i++) {
|
||||
GXPosition3f32(sp1A0[i], -sp10[i], temp_f31);
|
||||
GXNormal3f32(0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
GXEnd();
|
||||
|
||||
GXBegin(GX_TRIANGLEFAN, GX_VTXFMT3, numEdges + 2);
|
||||
GXPosition3f32(0.0f, 0.0f, temp_f30);
|
||||
GXNormal3f32(0.0f, 0.0f, -1.0f);
|
||||
for (i = 0; i <= numEdges; i++) {
|
||||
GXPosition3f32(sp1A0[i], sp10[i], temp_f30);
|
||||
GXNormal3f32(0.0f, 0.0f, -1.0f);
|
||||
}
|
||||
GXEnd();
|
||||
|
||||
RestoreVertState();
|
||||
}
|
337
src/dolphin/gx/GXFifo.c
Normal file
337
src/dolphin/gx/GXFifo.c
Normal file
@ -0,0 +1,337 @@
|
||||
#include "dolphin/gx/GXFifo.h"
|
||||
#include "dolphin/gx/GX.h"
|
||||
#include "dolphin/os/OS.h"
|
||||
|
||||
static void GXInitFifoLimits(GXFifoObj* fifo, u32 hi_watermark, u32 lo_watermark);
|
||||
|
||||
static GXFifoObj* CPUFifo;
|
||||
|
||||
static GXFifoObj* GPFifo;
|
||||
|
||||
static OSThread* __GXCurrentThread;
|
||||
|
||||
static GXBool data_80451954;
|
||||
|
||||
static u32 GXOverflowSuspendInProgress;
|
||||
|
||||
static GXBreakPtCallback BreakPointCB;
|
||||
|
||||
static u32 __GXOverflowCount;
|
||||
|
||||
static void GXOverflowHandler() {
|
||||
__GXOverflowCount += 1;
|
||||
__GXWriteFifoIntEnable(0, 1);
|
||||
__GXWriteFifoIntReset(1, 0);
|
||||
GXOverflowSuspendInProgress = TRUE;
|
||||
OSSuspendThread(__GXCurrentThread);
|
||||
}
|
||||
|
||||
static void GXUnderflowHandler() {
|
||||
OSResumeThread(__GXCurrentThread);
|
||||
GXOverflowSuspendInProgress = FALSE;
|
||||
__GXWriteFifoIntReset(1, 1);
|
||||
__GXWriteFifoIntEnable(1, 0);
|
||||
}
|
||||
|
||||
static void GXBreakPointHandler(OSContext* context) {
|
||||
OSContext bpContext;
|
||||
|
||||
FAST_FLAG_SET(__GXData->cpEnable, 0, 5, 1);
|
||||
GX_SET_CP_REG(1, __GXData->cpEnable);
|
||||
|
||||
if (BreakPointCB) {
|
||||
OSClearContext(&bpContext);
|
||||
OSSetCurrentContext(&bpContext);
|
||||
BreakPointCB();
|
||||
OSClearContext(&bpContext);
|
||||
OSSetCurrentContext(context);
|
||||
}
|
||||
}
|
||||
|
||||
static void GXCPInterruptHandler(s16 p1, OSContext* context) {
|
||||
__GXData->cpStatus = GX_GET_CP_REG(0);
|
||||
|
||||
if ((__GXData->cpEnable >> 3 & 1) && (__GXData->cpStatus >> 1 & 1)) {
|
||||
GXUnderflowHandler();
|
||||
}
|
||||
|
||||
if ((__GXData->cpEnable >> 2 & 1) && (__GXData->cpStatus >> 0 & 1)) {
|
||||
GXOverflowHandler();
|
||||
}
|
||||
|
||||
if ((__GXData->cpEnable >> 5 & 1) && (__GXData->cpStatus >> 4 & 1)) {
|
||||
GXBreakPointHandler(context);
|
||||
}
|
||||
}
|
||||
|
||||
void GXInitFifoBase(GXFifoObj* fifo, void* base, u32 size) {
|
||||
fifo->base = base;
|
||||
fifo->end = (void*)((u32)base + size - 4);
|
||||
fifo->size = size;
|
||||
fifo->rw_dst = 0;
|
||||
GXInitFifoLimits(fifo, size - 0x4000, OSRoundDown32B(size / 2));
|
||||
GXInitFifoPtrs(fifo, base, base);
|
||||
}
|
||||
|
||||
void GXInitFifoPtrs(GXFifoObj* fifo, void* readPtr, void* writePtr) {
|
||||
int interrupts = OSDisableInterrupts();
|
||||
fifo->read_ptr = readPtr;
|
||||
fifo->write_ptr = writePtr;
|
||||
fifo->rw_dst = (u32)writePtr - (u32)readPtr;
|
||||
if (fifo->rw_dst < 0) {
|
||||
fifo->rw_dst += fifo->size;
|
||||
}
|
||||
OSRestoreInterrupts(interrupts);
|
||||
}
|
||||
|
||||
static void GXInitFifoLimits(GXFifoObj* fifo, u32 hi_watermark, u32 lo_watermark) {
|
||||
fifo->high_wtrmark = hi_watermark;
|
||||
fifo->low_wtrmark = lo_watermark;
|
||||
}
|
||||
|
||||
void GXSetCPUFifo(GXFifoObj* fifo) {
|
||||
BOOL interrupts;
|
||||
interrupts = OSDisableInterrupts();
|
||||
|
||||
CPUFifo = fifo;
|
||||
|
||||
if (fifo == GPFifo) {
|
||||
u32 reg;
|
||||
GX_SET_PI_REG(3, (u32)fifo->base & 0x3FFFFFFF);
|
||||
GX_SET_PI_REG(4, (u32)fifo->end & 0x3FFFFFFF);
|
||||
reg = 0;
|
||||
GX_BITFIELD_SET(reg, 6, 21, (u32)fifo->write_ptr >> 5);
|
||||
GX_BITFIELD_SET(reg, 5, 1, 0);
|
||||
GX_SET_PI_REG(5, reg);
|
||||
|
||||
data_80451954 = GX_TRUE;
|
||||
|
||||
__GXWriteFifoIntReset(1, 1);
|
||||
__GXWriteFifoIntEnable(1, 0);
|
||||
__GXFifoLink(1);
|
||||
} else {
|
||||
u32 reg;
|
||||
if (data_80451954) {
|
||||
__GXFifoLink(0);
|
||||
data_80451954 = GX_FALSE;
|
||||
}
|
||||
__GXWriteFifoIntEnable(0, 0);
|
||||
|
||||
GX_SET_PI_REG(3, (u32)fifo->base & 0x3FFFFFFF);
|
||||
GX_SET_PI_REG(4, (u32)fifo->end & 0x3FFFFFFF);
|
||||
reg = 0;
|
||||
GX_BITFIELD_SET(reg, 6, 21, (u32)fifo->write_ptr >> 5);
|
||||
GX_BITFIELD_SET(reg, 5, 1, 0);
|
||||
GX_SET_PI_REG(5, reg);
|
||||
}
|
||||
|
||||
PPCSync();
|
||||
|
||||
OSRestoreInterrupts(interrupts);
|
||||
}
|
||||
|
||||
void GXSetGPFifo(GXFifoObj* fifo) {
|
||||
int interrupts = OSDisableInterrupts();
|
||||
u32 reg;
|
||||
__GXFifoReadDisable();
|
||||
__GXWriteFifoIntEnable(0, 0);
|
||||
GPFifo = fifo;
|
||||
GX_SET_CP_REG(16, (u16)fifo->base);
|
||||
GX_SET_CP_REG(18, (u16)fifo->end);
|
||||
GX_SET_CP_REG(24, (u16)fifo->rw_dst);
|
||||
GX_SET_CP_REG(26, (u16)fifo->write_ptr);
|
||||
GX_SET_CP_REG(28, (u16)fifo->read_ptr);
|
||||
GX_SET_CP_REG(20, (u16)fifo->high_wtrmark);
|
||||
GX_SET_CP_REG(22, (u16)fifo->low_wtrmark);
|
||||
|
||||
GX_SET_CP_REG(17, ((u32)fifo->base & 0x3FFFFFFF) >> 16);
|
||||
GX_SET_CP_REG(19, ((u32)fifo->end & 0x3FFFFFFF) >> 16);
|
||||
GX_SET_CP_REG(25, (fifo->rw_dst) >> 16);
|
||||
GX_SET_CP_REG(27, ((u32)fifo->write_ptr & 0x3FFFFFFF) >> 16);
|
||||
GX_SET_CP_REG(29, ((u32)fifo->read_ptr & 0x3FFFFFFF) >> 16);
|
||||
GX_SET_CP_REG(21, (fifo->high_wtrmark) >> 16);
|
||||
GX_SET_CP_REG(23, (fifo->low_wtrmark) >> 16);
|
||||
|
||||
PPCSync();
|
||||
|
||||
if (CPUFifo == GPFifo) {
|
||||
data_80451954 = 1;
|
||||
__GXWriteFifoIntEnable(1, 0);
|
||||
__GXFifoLink(1);
|
||||
} else {
|
||||
data_80451954 = 0;
|
||||
__GXWriteFifoIntEnable(0, 0);
|
||||
__GXFifoLink(0);
|
||||
}
|
||||
reg = __GXData->cpEnable;
|
||||
GX_BITFIELD_SET(reg, 0x1e, 1, 0);
|
||||
GX_BITFIELD_SET(reg, 0x1a, 1, 0);
|
||||
GX_SET_CP_REG(1, reg);
|
||||
GX_SET_CP_REG(1, __GXData->cpEnable);
|
||||
__GXWriteFifoIntReset(1, 1);
|
||||
__GXFifoReadEnable();
|
||||
OSRestoreInterrupts(interrupts);
|
||||
}
|
||||
|
||||
void GXSaveCPUFifo(GXFifoObj* fifo) {
|
||||
GXFlush();
|
||||
__GXSaveCPUFifoAux(fifo);
|
||||
}
|
||||
|
||||
void __GXSaveCPUFifoAux(GXFifoObj* fifo) {
|
||||
int interrupts = OSDisableInterrupts();
|
||||
fifo->base = OSPhysicalToCached(GX_GET_PI_REG(3));
|
||||
fifo->end = OSPhysicalToCached(GX_GET_PI_REG(4));
|
||||
fifo->write_ptr = OSPhysicalToCached(GX_GET_PI_REG(5) & ~0x4000000);
|
||||
if (data_80451954 != 0) {
|
||||
u32 reg2 = GX_GET_CP_REG(28) | (GX_GET_CP_REG(29) << 16);
|
||||
fifo->read_ptr = (void*)(reg2 + -0x80000000);
|
||||
fifo->rw_dst = (((u32)GX_GET_CP_REG(24) | (GX_GET_CP_REG(25) << 16)));
|
||||
} else {
|
||||
fifo->rw_dst = (u32)fifo->write_ptr - (u32)fifo->read_ptr;
|
||||
if (fifo->rw_dst < 0) {
|
||||
fifo->rw_dst += fifo->size;
|
||||
}
|
||||
}
|
||||
OSRestoreInterrupts(interrupts);
|
||||
}
|
||||
|
||||
void GXGetGPStatus(GXBool* overhi, GXBool* underlow, GXBool* readIdle, GXBool* cmdIdle,
|
||||
GXBool* brkpt) {
|
||||
__GXData->cpStatus = GX_GET_CP_REG(0);
|
||||
*overhi = __GXData->cpStatus & 1;
|
||||
*underlow = (__GXData->cpStatus >> 1) & 1;
|
||||
*readIdle = (__GXData->cpStatus >> 2) & 1;
|
||||
*cmdIdle = (__GXData->cpStatus >> 3) & 1;
|
||||
*brkpt = (__GXData->cpStatus >> 4) & 1;
|
||||
}
|
||||
|
||||
void* GXGetFifoBase(GXFifoObj* fifo) {
|
||||
return fifo->base;
|
||||
}
|
||||
|
||||
u32 GXGetFifoSize(GXFifoObj* fifo) {
|
||||
return fifo->size;
|
||||
}
|
||||
|
||||
GXBreakPtCallback GXSetBreakPtCallback(GXBreakPtCallback cb) {
|
||||
GXBreakPtCallback oldCallback = BreakPointCB;
|
||||
int interrupts = OSDisableInterrupts();
|
||||
BreakPointCB = cb;
|
||||
OSRestoreInterrupts(interrupts);
|
||||
return oldCallback;
|
||||
}
|
||||
|
||||
void __GXFifoInit(void) {
|
||||
__OSSetInterruptHandler(0x11, GXCPInterruptHandler);
|
||||
__OSUnmaskInterrupts(0x4000);
|
||||
__GXCurrentThread = OSGetCurrentThread();
|
||||
GXOverflowSuspendInProgress = 0;
|
||||
CPUFifo = NULL;
|
||||
GPFifo = NULL;
|
||||
}
|
||||
|
||||
void __GXFifoReadEnable(void) {
|
||||
FAST_FLAG_SET(__GXData->cpEnable, 1, 0, 1);
|
||||
GX_SET_CP_REG(1, __GXData->cpEnable);
|
||||
}
|
||||
|
||||
void __GXFifoReadDisable(void) {
|
||||
FAST_FLAG_SET(__GXData->cpEnable, 0, 0, 1);
|
||||
GX_SET_CP_REG(1, __GXData->cpEnable);
|
||||
}
|
||||
|
||||
void __GXFifoLink(u8 link) {
|
||||
u32 b;
|
||||
if (link) {
|
||||
b = 1;
|
||||
} else {
|
||||
b = 0;
|
||||
}
|
||||
FAST_FLAG_SET(__GXData->cpEnable, b, 4, 1);
|
||||
GX_SET_CP_REG(1, __GXData->cpEnable);
|
||||
}
|
||||
|
||||
void __GXWriteFifoIntEnable(u32 p1, u32 p2) {
|
||||
FAST_FLAG_SET(__GXData->cpEnable, p1, 2, 1);
|
||||
FAST_FLAG_SET(__GXData->cpEnable, (u8)p2, 3, 1);
|
||||
GX_SET_CP_REG(1, __GXData->cpEnable);
|
||||
}
|
||||
|
||||
void __GXWriteFifoIntReset(u32 p1, u32 p2) {
|
||||
FAST_FLAG_SET(__GXData->cpClr, p1, 0, 1);
|
||||
FAST_FLAG_SET(__GXData->cpClr, (u8)p2, 1, 1);
|
||||
GX_SET_CP_REG(2, __GXData->cpClr);
|
||||
}
|
||||
|
||||
void __GXCleanGPFifo(void) {
|
||||
BOOL interrupts;
|
||||
GXFifoObj tempObj; // 0x14
|
||||
u32 i, j, k; // stack alloc
|
||||
GXFifoObj* gpFifo; // r31
|
||||
GXFifoObj* cpuFifo; // r30
|
||||
void* tempPtr; // r29
|
||||
|
||||
gpFifo = GXGetGPFifo();
|
||||
if (!gpFifo) {
|
||||
return;
|
||||
}
|
||||
|
||||
cpuFifo = GXGetCPUFifo();
|
||||
tempPtr = gpFifo->base;
|
||||
|
||||
tempObj = *gpFifo;
|
||||
|
||||
interrupts = OSDisableInterrupts();
|
||||
|
||||
tempObj.read_ptr = tempPtr;
|
||||
tempObj.write_ptr = tempPtr;
|
||||
tempObj.rw_dst = 0;
|
||||
if (tempObj.rw_dst < 0) {
|
||||
tempObj.rw_dst += tempObj.size;
|
||||
}
|
||||
|
||||
OSRestoreInterrupts(interrupts);
|
||||
|
||||
GXSetGPFifo(&tempObj);
|
||||
|
||||
if (cpuFifo == gpFifo) {
|
||||
GXSetCPUFifo(&tempObj);
|
||||
}
|
||||
|
||||
interrupts = OSDisableInterrupts();
|
||||
|
||||
gpFifo->read_ptr = tempPtr;
|
||||
gpFifo->write_ptr = tempPtr;
|
||||
gpFifo->rw_dst = 0;
|
||||
|
||||
if (gpFifo->rw_dst < 0) {
|
||||
gpFifo->rw_dst += gpFifo->size;
|
||||
}
|
||||
OSRestoreInterrupts(interrupts);
|
||||
|
||||
GXSetGPFifo(gpFifo);
|
||||
if (cpuFifo == gpFifo) {
|
||||
GXSetCPUFifo(cpuFifo);
|
||||
}
|
||||
}
|
||||
|
||||
OSThread* GXSetCurrentGXThread(void) {
|
||||
BOOL interrupts = OSDisableInterrupts();
|
||||
OSThread* prevThread = __GXCurrentThread;
|
||||
__GXCurrentThread = OSGetCurrentThread();
|
||||
OSRestoreInterrupts(interrupts);
|
||||
return prevThread;
|
||||
}
|
||||
|
||||
OSThread* GXGetCurrentGXThread(void) {
|
||||
return *(OSThread**)(&__GXCurrentThread);
|
||||
}
|
||||
|
||||
GXFifoObj* GXGetCPUFifo(void) {
|
||||
return *(GXFifoObj**)(&CPUFifo);
|
||||
}
|
||||
|
||||
GXFifoObj* GXGetGPFifo(void) {
|
||||
return GPFifo;
|
||||
}
|
638
src/dolphin/gx/GXFrameBuf.c
Normal file
638
src/dolphin/gx/GXFrameBuf.c
Normal file
@ -0,0 +1,638 @@
|
||||
#include "dolphin/gx/GXFrameBuf.h"
|
||||
#include "dolphin/gx/GX.h"
|
||||
|
||||
GXRenderModeObj GXNtsc480IntDf = {
|
||||
VI_TVMODE_NTSC_INT,
|
||||
640,
|
||||
480,
|
||||
480,
|
||||
40,
|
||||
0,
|
||||
640,
|
||||
480,
|
||||
VI_XFBMODE_DF,
|
||||
GX_FALSE,
|
||||
GX_FALSE,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
8,
|
||||
8,
|
||||
10,
|
||||
12,
|
||||
10,
|
||||
8,
|
||||
8,
|
||||
};
|
||||
|
||||
GXRenderModeObj GXNtsc480Int = {
|
||||
VI_TVMODE_NTSC_INT,
|
||||
640,
|
||||
480,
|
||||
480,
|
||||
40,
|
||||
0,
|
||||
640,
|
||||
480,
|
||||
VI_XFBMODE_DF,
|
||||
GX_FALSE,
|
||||
GX_FALSE,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
0,
|
||||
0,
|
||||
21,
|
||||
22,
|
||||
21,
|
||||
0,
|
||||
0,
|
||||
};
|
||||
|
||||
GXRenderModeObj GXMpal480IntDf = {
|
||||
VI_TVMODE_MPAL_INT,
|
||||
640,
|
||||
480,
|
||||
480,
|
||||
40,
|
||||
0,
|
||||
640,
|
||||
480,
|
||||
VI_XFBMODE_DF,
|
||||
GX_FALSE,
|
||||
GX_FALSE,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
8,
|
||||
8,
|
||||
10,
|
||||
12,
|
||||
10,
|
||||
8,
|
||||
8,
|
||||
};
|
||||
|
||||
GXRenderModeObj GXPal528IntDf = {
|
||||
VI_TVMODE_PAL_INT,
|
||||
640,
|
||||
528,
|
||||
528,
|
||||
40,
|
||||
23,
|
||||
640,
|
||||
528,
|
||||
VI_XFBMODE_DF,
|
||||
GX_FALSE,
|
||||
GX_FALSE,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
8,
|
||||
8,
|
||||
10,
|
||||
12,
|
||||
10,
|
||||
8,
|
||||
8,
|
||||
};
|
||||
|
||||
GXRenderModeObj GXEurgb60Hz480IntDf = {
|
||||
VI_TVMODE_EURGB60_INT,
|
||||
640,
|
||||
480,
|
||||
480,
|
||||
40,
|
||||
0,
|
||||
640,
|
||||
480,
|
||||
VI_XFBMODE_DF,
|
||||
GX_FALSE,
|
||||
GX_FALSE,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
8,
|
||||
8,
|
||||
10,
|
||||
12,
|
||||
10,
|
||||
8,
|
||||
8,
|
||||
};
|
||||
|
||||
void GXSetDispCopySrc(u16 left, u16 top, u16 width, u16 height) {
|
||||
__GXData->cpDispSrc = 0;
|
||||
GX_BITFIELD_SET(__GXData->cpDispSrc, 22, 10, left);
|
||||
GX_BITFIELD_SET(__GXData->cpDispSrc, 12, 10, top);
|
||||
GX_BITFIELD_SET(__GXData->cpDispSrc, 0, 8, 73);
|
||||
|
||||
__GXData->cpDispSize = 0;
|
||||
GX_BITFIELD_SET(__GXData->cpDispSize, 22, 10, width - 1);
|
||||
GX_BITFIELD_SET(__GXData->cpDispSize, 12, 10, height - 1);
|
||||
GX_BITFIELD_SET(__GXData->cpDispSize, 0, 8, 74);
|
||||
}
|
||||
|
||||
void GXSetTexCopySrc(u16 left, u16 top, u16 width, u16 height) {
|
||||
__GXData->cpTexSrc = 0;
|
||||
GX_BITFIELD_SET(__GXData->cpTexSrc, 22, 10, left);
|
||||
GX_BITFIELD_SET(__GXData->cpTexSrc, 12, 10, top);
|
||||
GX_BITFIELD_SET(__GXData->cpTexSrc, 0, 8, 0x49);
|
||||
__GXData->cpTexSize = 0;
|
||||
GX_BITFIELD_SET(__GXData->cpTexSize, 22, 10, width - 1);
|
||||
GX_BITFIELD_SET(__GXData->cpTexSize, 12, 10, height - 1);
|
||||
GX_BITFIELD_SET(__GXData->cpTexSize, 0, 8, 0x4A);
|
||||
}
|
||||
|
||||
void GXSetDispCopyDst(u16 arg0, u16 arg1) {
|
||||
s32 val = (s32)((arg0 << 1) & 0xFFFE) >> 5;
|
||||
__GXData->cpDispStride = 0;
|
||||
GX_BITFIELD_SET(__GXData->cpDispStride, 22, 10, val);
|
||||
GX_BITFIELD_SET(__GXData->cpDispStride, 0, 8, 0x4D);
|
||||
}
|
||||
|
||||
void GXSetTexCopyDst(u16 width, u16 height, GXTexFmt format, GXBool useMIPmap) {
|
||||
u32 sp20, sp1C, sp18;
|
||||
u32 value;
|
||||
u8 depthRelated;
|
||||
|
||||
__GXData->cpTexZ = GX_NONE;
|
||||
|
||||
depthRelated = format & 0xf;
|
||||
if (format == GX_TF_Z16) {
|
||||
depthRelated = 0xb;
|
||||
}
|
||||
|
||||
switch (format) {
|
||||
case GX_TF_I4:
|
||||
case GX_TF_I8:
|
||||
case GX_TF_IA4:
|
||||
case GX_TF_IA8:
|
||||
case GX_CTF_A8:
|
||||
GX_SET_REG(__GXData->cpTex, 3, 15, 16);
|
||||
break;
|
||||
default:
|
||||
GX_SET_REG(__GXData->cpTex, 2, 15, 16);
|
||||
break;
|
||||
}
|
||||
|
||||
__GXData->cpTexZ = (format & 0x10) == 0x10;
|
||||
|
||||
value = depthRelated >> 3;
|
||||
|
||||
GX_SET_REG(__GXData->cpTex, value, 28, 28);
|
||||
|
||||
depthRelated &= 7;
|
||||
|
||||
__GetImageTileCount(format, width, height, &sp20, &sp1C, &sp18);
|
||||
|
||||
__GXData->cpTexStride = GX_NONE;
|
||||
GX_SET_REG(__GXData->cpTexStride, sp20 * sp18, 22, 31);
|
||||
GX_SET_REG(__GXData->cpTexStride, 0x4D, 0, 7);
|
||||
|
||||
GX_SET_REG(__GXData->cpTex, useMIPmap, 22, 22);
|
||||
GX_SET_REG(__GXData->cpTex, depthRelated, 25, 27);
|
||||
}
|
||||
|
||||
void GXSetDispCopyFrame2Field(GXCopyMode arg0) {
|
||||
GX_BITFIELD_SET(__GXData->cpDisp, 18, 2, arg0);
|
||||
GX_BITFIELD_SET(__GXData->cpTex, 18, 2, 0);
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
#define INSERT_FIELD(reg, value, nbits, shift) \
|
||||
(reg) = ((u32) (reg) & ~(((1 << (nbits)) - 1) << (shift))) | \
|
||||
((u32) (value) << (shift));
|
||||
// clang-format on
|
||||
|
||||
void GXSetCopyClamp(GXFBClamp clamp) {
|
||||
u8 isTop = (clamp & GX_CLAMP_TOP) == GX_CLAMP_TOP;
|
||||
u8 isBottom = (clamp & GX_CLAMP_BOTTOM) == GX_CLAMP_BOTTOM;
|
||||
__GXData->cpDisp = __rlwimi(__GXData->cpDisp, isTop, 0, 31, 31);
|
||||
__GXData->cpDisp = __rlwimi(__GXData->cpDisp, isBottom, 1, 30, 30);
|
||||
__GXData->cpTex = __rlwimi(__GXData->cpTex, isTop, 0, 31, 31);
|
||||
__GXData->cpTex = __rlwimi(__GXData->cpTex, isBottom, 1, 30, 30);
|
||||
}
|
||||
|
||||
static u32 __GXGetNumXfbLines(u32 height, u32 scale) {
|
||||
u32 numLines;
|
||||
u32 actualHeight;
|
||||
u32 newScale;
|
||||
|
||||
numLines = (height - 1) * 0x100;
|
||||
actualHeight = (numLines / scale) + 1;
|
||||
|
||||
newScale = scale;
|
||||
|
||||
if (newScale > 0x80 && newScale < 0x100) {
|
||||
while (newScale % 2 == 0) {
|
||||
newScale /= 2;
|
||||
}
|
||||
|
||||
if (height % newScale == 0) {
|
||||
actualHeight++;
|
||||
}
|
||||
}
|
||||
|
||||
if (actualHeight > 0x400) {
|
||||
actualHeight = 0x400;
|
||||
}
|
||||
|
||||
return actualHeight;
|
||||
}
|
||||
|
||||
u16 GXGetNumXfbLines(const u16 efbHeight, f32 yScale) {
|
||||
u32 scale = (u32)(256.0f / yScale) & 0x1FF;
|
||||
|
||||
return __GXGetNumXfbLines(efbHeight, scale);
|
||||
}
|
||||
|
||||
f32 GXGetYScaleFactor(u16 efbHeight, u16 xfbHeight) {
|
||||
u32 scale;
|
||||
u32 height1;
|
||||
u32 height2;
|
||||
f32 scale2;
|
||||
f32 scale1;
|
||||
|
||||
height1 = xfbHeight;
|
||||
scale1 = (f32)xfbHeight / (f32)efbHeight;
|
||||
scale = (u32)(256.0f / scale1) & 0x1FF;
|
||||
height2 = __GXGetNumXfbLines(efbHeight, scale);
|
||||
|
||||
while (height2 > xfbHeight) {
|
||||
height1--;
|
||||
scale1 = (f32)height1 / (f32)efbHeight;
|
||||
scale = (u32)(256.0f / scale1) & 0x1FF;
|
||||
height2 = __GXGetNumXfbLines(efbHeight, scale);
|
||||
}
|
||||
|
||||
scale2 = scale1;
|
||||
while (height2 < xfbHeight) {
|
||||
scale2 = scale1;
|
||||
height1++;
|
||||
scale1 = (f32)height1 / (f32)efbHeight;
|
||||
scale = (u32)(256.0f / scale1) & 0x1FF;
|
||||
height2 = __GXGetNumXfbLines(efbHeight, scale);
|
||||
}
|
||||
|
||||
return scale2;
|
||||
}
|
||||
|
||||
u32 GXSetDispCopyYScale(f32 vertScale) {
|
||||
u32 scale;
|
||||
GXBool check;
|
||||
u32 height;
|
||||
u32 reg;
|
||||
|
||||
scale = (u32)(256.0f / vertScale) & 0x1FF;
|
||||
check = (scale != 0x100);
|
||||
|
||||
reg = 0;
|
||||
GX_SET_REG(reg, scale, 23, 31);
|
||||
GX_SET_REG(reg, 0x4E, 0, 7);
|
||||
GX_BP_LOAD_REG(reg);
|
||||
__GXData->bpSentNot = GX_FALSE;
|
||||
|
||||
GX_SET_REG(__GXData->cpDisp, check, 21, 21);
|
||||
|
||||
height = (__GXData->cpDispSize >> 10 & 0x3FF) + 1;
|
||||
|
||||
return __GXGetNumXfbLines(height, scale);
|
||||
}
|
||||
|
||||
void GXSetCopyClear(GXColor color, u32 clear_z) {
|
||||
u32 r6 = 0;
|
||||
GX_BITFIELD_SET(r6, 24, 8, color.r);
|
||||
GX_BITFIELD_SET(r6, 16, 8, color.a);
|
||||
GX_BITFIELD_SET(r6, 0, 8, 0x4f);
|
||||
GXFIFO.u8 = 0x61;
|
||||
GXFIFO.u32 = r6;
|
||||
|
||||
r6 = 0;
|
||||
GX_BITFIELD_SET(r6, 24, 8, color.b);
|
||||
GX_BITFIELD_SET(r6, 16, 8, color.g);
|
||||
GX_BITFIELD_SET(r6, 0, 8, 0x50);
|
||||
GXFIFO.u8 = 0x61;
|
||||
GXFIFO.u32 = r6;
|
||||
|
||||
r6 = 0;
|
||||
GX_BITFIELD_SET(r6, 8, 24, clear_z);
|
||||
GX_BITFIELD_SET(r6, 0, 8, 0x51);
|
||||
GXFIFO.u8 = 0x61;
|
||||
GXFIFO.u32 = r6;
|
||||
|
||||
__GXData->bpSentNot = 0;
|
||||
}
|
||||
|
||||
void GXSetCopyFilter(GXBool useAA, u8 samplePattern[12][2], GXBool doVertFilt, u8 vFilt[7]) {
|
||||
u32 vals[4];
|
||||
u32 unk1;
|
||||
u32 unk2;
|
||||
|
||||
if (useAA) {
|
||||
vals[0] = 0;
|
||||
GX_SET_REG(vals[0], samplePattern[0][0], 28, 31);
|
||||
GX_SET_REG(vals[0], samplePattern[0][1], 24, 27);
|
||||
GX_SET_REG(vals[0], samplePattern[1][0], 20, 23);
|
||||
GX_SET_REG(vals[0], samplePattern[1][1], 16, 19);
|
||||
GX_SET_REG(vals[0], samplePattern[2][0], 12, 15);
|
||||
GX_SET_REG(vals[0], samplePattern[2][1], 8, 11);
|
||||
GX_SET_REG(vals[0], 1, 0, 7);
|
||||
|
||||
vals[1] = 0;
|
||||
GX_SET_REG(vals[1], samplePattern[3][0], 28, 31);
|
||||
GX_SET_REG(vals[1], samplePattern[3][1], 24, 27);
|
||||
GX_SET_REG(vals[1], samplePattern[4][0], 20, 23);
|
||||
GX_SET_REG(vals[1], samplePattern[4][1], 16, 19);
|
||||
GX_SET_REG(vals[1], samplePattern[5][0], 12, 15);
|
||||
GX_SET_REG(vals[1], samplePattern[5][1], 8, 11);
|
||||
GX_SET_REG(vals[1], 2, 0, 7);
|
||||
|
||||
vals[2] = 0;
|
||||
GX_SET_REG(vals[2], samplePattern[6][0], 28, 31);
|
||||
GX_SET_REG(vals[2], samplePattern[6][1], 24, 27);
|
||||
GX_SET_REG(vals[2], samplePattern[7][0], 20, 23);
|
||||
GX_SET_REG(vals[2], samplePattern[7][1], 16, 19);
|
||||
GX_SET_REG(vals[2], samplePattern[8][0], 12, 15);
|
||||
GX_SET_REG(vals[2], samplePattern[8][1], 8, 11);
|
||||
GX_SET_REG(vals[2], 3, 0, 7);
|
||||
|
||||
vals[3] = 0;
|
||||
GX_SET_REG(vals[3], samplePattern[9][0], 28, 31);
|
||||
GX_SET_REG(vals[3], samplePattern[9][1], 24, 27);
|
||||
GX_SET_REG(vals[3], samplePattern[10][0], 20, 23);
|
||||
GX_SET_REG(vals[3], samplePattern[10][1], 16, 19);
|
||||
GX_SET_REG(vals[3], samplePattern[11][0], 12, 15);
|
||||
GX_SET_REG(vals[3], samplePattern[11][1], 8, 11);
|
||||
GX_SET_REG(vals[3], 4, 0, 7);
|
||||
} else {
|
||||
vals[0] = 0x01666666;
|
||||
vals[1] = 0x02666666;
|
||||
vals[2] = 0x03666666;
|
||||
vals[3] = 0x04666666;
|
||||
}
|
||||
|
||||
GX_BP_LOAD_REG(vals[0]);
|
||||
GX_BP_LOAD_REG(vals[1]);
|
||||
GX_BP_LOAD_REG(vals[2]);
|
||||
GX_BP_LOAD_REG(vals[3]);
|
||||
|
||||
unk1 = 0;
|
||||
GX_SET_REG(unk1, 0x53, 0, 7);
|
||||
unk2 = 0;
|
||||
GX_SET_REG(unk2, 0x54, 0, 7);
|
||||
|
||||
if (doVertFilt) {
|
||||
GX_SET_REG(unk1, vFilt[0], 26, 31);
|
||||
GX_SET_REG(unk1, vFilt[1], 20, 25);
|
||||
GX_SET_REG(unk1, vFilt[2], 14, 19);
|
||||
GX_SET_REG(unk1, vFilt[3], 8, 13);
|
||||
GX_SET_REG(unk2, vFilt[4], 26, 31);
|
||||
GX_SET_REG(unk2, vFilt[5], 20, 25);
|
||||
GX_SET_REG(unk2, vFilt[6], 14, 19);
|
||||
|
||||
} else {
|
||||
GX_SET_REG(unk1, 0, 26, 31);
|
||||
GX_SET_REG(unk1, 0, 20, 25);
|
||||
GX_SET_REG(unk1, 21, 14, 19);
|
||||
GX_SET_REG(unk1, 22, 8, 13);
|
||||
GX_SET_REG(unk2, 21, 26, 31);
|
||||
GX_SET_REG(unk2, 0, 20, 25);
|
||||
GX_SET_REG(unk2, 0, 14, 19);
|
||||
}
|
||||
|
||||
GX_BP_LOAD_REG(unk1);
|
||||
GX_BP_LOAD_REG(unk2);
|
||||
|
||||
__GXData->bpSentNot = GX_FALSE;
|
||||
}
|
||||
|
||||
void GXSetDispCopyGamma(GXGamma gamma) {
|
||||
GX_BITFIELD_SET(__GXData->cpDisp, 23, 2, gamma);
|
||||
}
|
||||
|
||||
void GXCopyDisp(void* dest, GXBool doClear) {
|
||||
u32 reg;
|
||||
u32 newDest;
|
||||
GXBool check;
|
||||
|
||||
if (doClear) {
|
||||
reg = __GXData->zmode;
|
||||
GX_SET_REG(reg, 1, 31, 31);
|
||||
GX_SET_REG(reg, 7, 28, 30);
|
||||
GX_BP_LOAD_REG(reg);
|
||||
|
||||
reg = __GXData->cmode0;
|
||||
GX_SET_REG(reg, 0, 31, 31);
|
||||
GX_SET_REG(reg, 0, 30, 30);
|
||||
GX_BP_LOAD_REG(reg);
|
||||
}
|
||||
|
||||
check = GX_FALSE;
|
||||
if ((doClear || (__GXData->peCtrl & 0x7) == 3) && (__GXData->peCtrl >> 6 & 0x1) == 1) {
|
||||
check = GX_TRUE;
|
||||
reg = __GXData->peCtrl;
|
||||
GX_SET_REG(reg, 0, 25, 25);
|
||||
GX_BP_LOAD_REG(reg);
|
||||
}
|
||||
|
||||
GX_BP_LOAD_REG(__GXData->cpDispSrc);
|
||||
GX_BP_LOAD_REG(__GXData->cpDispSize);
|
||||
GX_BP_LOAD_REG(__GXData->cpDispStride);
|
||||
|
||||
newDest = (u32)dest & 0x3FFFFFFF;
|
||||
reg = 0;
|
||||
GX_SET_REG(reg, newDest >> 5, 11, 31);
|
||||
GX_SET_REG(reg, 0x4B, 0, 7);
|
||||
GX_BP_LOAD_REG(reg);
|
||||
|
||||
GX_SET_REG(__GXData->cpDisp, doClear, 20, 20);
|
||||
GX_SET_REG(__GXData->cpDisp, 1, 17, 17);
|
||||
GX_SET_REG(__GXData->cpDisp, 0x52, 0, 7);
|
||||
GX_BP_LOAD_REG(__GXData->cpDisp);
|
||||
|
||||
if (doClear) {
|
||||
GX_BP_LOAD_REG(__GXData->zmode);
|
||||
GX_BP_LOAD_REG(__GXData->cmode0);
|
||||
}
|
||||
|
||||
if (check) {
|
||||
GX_BP_LOAD_REG(__GXData->peCtrl);
|
||||
}
|
||||
|
||||
__GXData->bpSentNot = GX_FALSE;
|
||||
}
|
||||
|
||||
void GXCopyTex(void* dest, GXBool doClear) {
|
||||
u32 reg;
|
||||
u32 reg2;
|
||||
u32 newDest;
|
||||
GXBool check;
|
||||
|
||||
if (doClear) {
|
||||
reg = __GXData->zmode;
|
||||
GX_SET_REG(reg, 1, 31, 31);
|
||||
GX_SET_REG(reg, 7, 28, 30);
|
||||
GX_BP_LOAD_REG(reg);
|
||||
|
||||
reg = __GXData->cmode0;
|
||||
GX_SET_REG(reg, 0, 31, 31);
|
||||
GX_SET_REG(reg, 0, 30, 30);
|
||||
GX_BP_LOAD_REG(reg);
|
||||
}
|
||||
|
||||
check = GX_FALSE;
|
||||
reg2 = __GXData->peCtrl;
|
||||
if (__GXData->cpTexZ && (reg2 & 0x7) != 3) {
|
||||
check = GX_TRUE;
|
||||
GX_SET_REG(reg2, 3, 29, 31);
|
||||
}
|
||||
|
||||
if ((doClear || (reg2 & 0x7) == 3) && (reg2 >> 6 & 0x1) == 1) {
|
||||
check = GX_TRUE;
|
||||
GX_SET_REG(reg2, 0, 25, 25);
|
||||
}
|
||||
|
||||
if (check) {
|
||||
GX_BP_LOAD_REG(reg2);
|
||||
}
|
||||
|
||||
GX_BP_LOAD_REG(__GXData->cpTexSrc);
|
||||
GX_BP_LOAD_REG(__GXData->cpTexSize);
|
||||
GX_BP_LOAD_REG(__GXData->cpTexStride);
|
||||
|
||||
newDest = (u32)dest & 0x3FFFFFFF;
|
||||
reg = 0;
|
||||
GX_SET_REG(reg, newDest >> 5, 11, 31);
|
||||
GX_SET_REG(reg, 0x4B, 0, 7);
|
||||
GX_BP_LOAD_REG(reg);
|
||||
|
||||
GX_SET_REG(__GXData->cpTex, doClear, 20, 20);
|
||||
GX_SET_REG(__GXData->cpTex, 0, 17, 17);
|
||||
GX_SET_REG(__GXData->cpTex, 0x52, 0, 7);
|
||||
GX_BP_LOAD_REG(__GXData->cpTex);
|
||||
|
||||
if (doClear) {
|
||||
GX_BP_LOAD_REG(__GXData->zmode);
|
||||
GX_BP_LOAD_REG(__GXData->cmode0);
|
||||
}
|
||||
|
||||
if (check) {
|
||||
GX_BP_LOAD_REG(__GXData->peCtrl);
|
||||
}
|
||||
|
||||
__GXData->bpSentNot = GX_FALSE;
|
||||
}
|
||||
|
||||
void GXClearBoundingBox(void) {
|
||||
GXFIFO.u8 = GX_LOAD_BP_REG;
|
||||
GXFIFO.u32 = 0x550003FF;
|
||||
GXFIFO.u8 = GX_LOAD_BP_REG;
|
||||
GXFIFO.u32 = 0x560003FF;
|
||||
set_x2(GX_FALSE);
|
||||
}
|
149
src/dolphin/gx/GXGeometry.c
Normal file
149
src/dolphin/gx/GXGeometry.c
Normal file
@ -0,0 +1,149 @@
|
||||
/**
|
||||
* GXGeometry.c
|
||||
* Description:
|
||||
*/
|
||||
|
||||
#include "dolphin/gx/GXGeometry.h"
|
||||
#include "dolphin/gx/GX.h"
|
||||
|
||||
void __GXSetDirtyState(void) {
|
||||
u32 dirtyFlags = __GXData->dirtyState;
|
||||
|
||||
if (dirtyFlags & GX_DIRTY_SU_TEX) {
|
||||
__GXSetSUTexRegs();
|
||||
}
|
||||
|
||||
if (dirtyFlags & GX_DIRTY_BP_MASK) {
|
||||
__GXUpdateBPMask();
|
||||
}
|
||||
|
||||
if (dirtyFlags & GX_DIRTY_GEN_MODE) {
|
||||
__GXSetGenMode();
|
||||
}
|
||||
|
||||
if (dirtyFlags & GX_DIRTY_VCD) {
|
||||
__GXSetVCD();
|
||||
}
|
||||
|
||||
if (dirtyFlags & GX_DIRTY_VAT) {
|
||||
__GXSetVAT();
|
||||
}
|
||||
|
||||
if (dirtyFlags & GX_DIRTY_VLIM) {
|
||||
__GXCalculateVLim();
|
||||
}
|
||||
|
||||
__GXData->dirtyState = 0;
|
||||
}
|
||||
|
||||
void GXBegin(GXPrimitive type, GXVtxFmt fmt, u16 vert_num) {
|
||||
GXData* data = __GXData;
|
||||
u32 dirtyFlags = data->dirtyState;
|
||||
|
||||
if (data->dirtyState != 0) {
|
||||
if (dirtyFlags & GX_DIRTY_SU_TEX) {
|
||||
__GXSetSUTexRegs();
|
||||
}
|
||||
|
||||
if (dirtyFlags & GX_DIRTY_BP_MASK) {
|
||||
__GXUpdateBPMask();
|
||||
}
|
||||
|
||||
if (dirtyFlags & GX_DIRTY_GEN_MODE) {
|
||||
__GXSetGenMode();
|
||||
}
|
||||
|
||||
if (dirtyFlags & GX_DIRTY_VCD) {
|
||||
__GXSetVCD();
|
||||
}
|
||||
|
||||
if (dirtyFlags & GX_DIRTY_VAT) {
|
||||
__GXSetVAT();
|
||||
}
|
||||
|
||||
if (dirtyFlags & GX_DIRTY_VLIM) {
|
||||
__GXCalculateVLim();
|
||||
}
|
||||
|
||||
__GXData->dirtyState = 0;
|
||||
}
|
||||
|
||||
if (*(u32*)__GXData == 0) {
|
||||
__GXSendFlushPrim();
|
||||
}
|
||||
|
||||
GXFIFO.u8 = fmt | type;
|
||||
GXFIFO.u16 = vert_num;
|
||||
}
|
||||
|
||||
void __GXSendFlushPrim(void) {
|
||||
u32 i;
|
||||
u32 sz = __GXData->vNum * __GXData->vLim;
|
||||
|
||||
GXFIFO.u8 = 0x98;
|
||||
GXFIFO.u16 = __GXData->vNum;
|
||||
|
||||
for (i = 0; i < sz; i += 4) {
|
||||
GXFIFO.s32 = 0;
|
||||
}
|
||||
|
||||
__GXData->bpSentNot = 1;
|
||||
}
|
||||
|
||||
void GXSetLineWidth(u8 width, GXTexOffset offsets) {
|
||||
GXData* data = __GXData;
|
||||
|
||||
GX_BITFIELD_SET(data->lpSize, 24, 8, width);
|
||||
GX_BITFIELD_SET(data->lpSize, 13, 3, offsets);
|
||||
GXFIFO.u8 = 0x61;
|
||||
GXFIFO.u32 = data->lpSize;
|
||||
data->bpSentNot = 0;
|
||||
}
|
||||
|
||||
void GXSetPointSize(u8 size, GXTexOffset offsets) {
|
||||
GXData* data = __GXData;
|
||||
|
||||
GX_BITFIELD_SET(data->lpSize, 16, 8, size);
|
||||
GX_BITFIELD_SET(data->lpSize, 10, 3, offsets);
|
||||
GXFIFO.u8 = 0x61;
|
||||
GXFIFO.u32 = data->lpSize;
|
||||
data->bpSentNot = 0;
|
||||
}
|
||||
|
||||
void GXEnableTexOffsets(GXTexCoordID coord, GXBool line, GXBool point) {
|
||||
GXData* data = __GXData;
|
||||
|
||||
GX_BITFIELD_SET(data->suTs0[coord], 13, 1, line);
|
||||
GX_BITFIELD_SET(data->suTs0[coord], 12, 1, point);
|
||||
GXFIFO.u8 = 0x61;
|
||||
GXFIFO.u32 = data->suTs0[coord];
|
||||
data->bpSentNot = 0;
|
||||
}
|
||||
|
||||
void GXSetCullMode(GXCullMode mode) {
|
||||
GXData* data;
|
||||
GXCullMode mode2;
|
||||
data = __GXData;
|
||||
|
||||
mode2 = (mode >> 1) & 1;
|
||||
GX_BITFIELD_SET(mode2, 30, 1, mode);
|
||||
|
||||
GX_BITFIELD_SET(data->genMode, 16, 2, mode2);
|
||||
data->dirtyState |= GX_DIRTY_GEN_MODE;
|
||||
}
|
||||
|
||||
void GXSetCoPlanar(GXBool enable) {
|
||||
GXData* data = __GXData;
|
||||
|
||||
GX_BITFIELD_SET(data->genMode, 12, 1, enable);
|
||||
GXFIFO.u8 = 0x61;
|
||||
GXFIFO.u32 = 0xFE080000;
|
||||
GXFIFO.u8 = 0x61;
|
||||
GXFIFO.u32 = data->genMode;
|
||||
}
|
||||
|
||||
void __GXSetGenMode(void) {
|
||||
GXFIFO.u8 = 0x61;
|
||||
GXFIFO.u32 = __GXData->genMode;
|
||||
__GXData->bpSentNot = 0;
|
||||
}
|
561
src/dolphin/gx/GXInit.c
Normal file
561
src/dolphin/gx/GXInit.c
Normal file
@ -0,0 +1,561 @@
|
||||
#include "dolphin/gx/GX.h"
|
||||
#include "dolphin/os/OS.h"
|
||||
#include "dolphin/vi/vi.h"
|
||||
|
||||
char* __GXVersion = "<< Dolphin SDK - GX release build: Nov 10 2004 06:27:12 (0x2301) >>";
|
||||
|
||||
static GXFifoObj FifoObj;
|
||||
|
||||
static GXData gxData;
|
||||
|
||||
GXData* const __GXData = &gxData;
|
||||
|
||||
GXTexRegion* __GXDefaultTexRegionCallback(const GXTexObj* obj, GXTexMapID id) {
|
||||
GXTexFmt format; // r31
|
||||
GXBool isMipMap; // r3
|
||||
|
||||
format = GXGetTexObjFmt(obj);
|
||||
isMipMap = GXGetTexObjMipMap(obj);
|
||||
id = (GXTexMapID)(id % GX_MAX_TEXMAP);
|
||||
|
||||
switch (format) {
|
||||
case GX_TF_RGBA8:
|
||||
if (isMipMap) {
|
||||
return &__GXData->TexRegions2[id];
|
||||
}
|
||||
return &__GXData->TexRegions1[id];
|
||||
|
||||
case GX_TF_C4:
|
||||
case GX_TF_C8:
|
||||
case GX_TF_C14X2:
|
||||
return &__GXData->TexRegions0[id];
|
||||
|
||||
default:
|
||||
if (isMipMap) {
|
||||
return &__GXData->TexRegions1[id];
|
||||
}
|
||||
return &__GXData->TexRegions0[id];
|
||||
}
|
||||
}
|
||||
|
||||
GXTlutRegion* __GXDefaultTlutRegionCallback(u32 tlut) {
|
||||
if (tlut >= 0x14) {
|
||||
return NULL;
|
||||
} else {
|
||||
return &__GXData->TlutRegions[tlut];
|
||||
}
|
||||
}
|
||||
|
||||
u32 resetFuncRegistered;
|
||||
|
||||
u32 calledOnce;
|
||||
|
||||
OSTime time;
|
||||
|
||||
u32 peCount;
|
||||
|
||||
vu16* __memReg;
|
||||
|
||||
u16* __peReg;
|
||||
|
||||
u16* __cpReg;
|
||||
|
||||
/* ############################################################################################## */
|
||||
u32* __piReg;
|
||||
|
||||
BOOL __GXShutdown(BOOL final) {
|
||||
u32 val;
|
||||
u32 newPeCount;
|
||||
OSTime newTime;
|
||||
|
||||
if (!final) {
|
||||
if (!calledOnce) {
|
||||
peCount = GXReadMEMReg(0x28, 0x27);
|
||||
time = OSGetTime();
|
||||
calledOnce = 1;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
newTime = OSGetTime();
|
||||
newPeCount = GXReadMEMReg(0x28, 0x27);
|
||||
|
||||
if (newTime - time < 10) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (newPeCount != peCount) {
|
||||
peCount = newPeCount;
|
||||
time = newTime;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
} else {
|
||||
GXSetBreakPtCallback(NULL);
|
||||
GXSetDrawSyncCallback(NULL);
|
||||
GXSetDrawDoneCallback(NULL);
|
||||
|
||||
GX_WRITE_U32(0);
|
||||
GX_WRITE_U32(0);
|
||||
GX_WRITE_U32(0);
|
||||
GX_WRITE_U32(0);
|
||||
GX_WRITE_U32(0);
|
||||
GX_WRITE_U32(0);
|
||||
GX_WRITE_U32(0);
|
||||
GX_WRITE_U32(0);
|
||||
|
||||
PPCSync();
|
||||
|
||||
GX_SET_CP_REG(1, 0);
|
||||
GX_SET_CP_REG(2, 3);
|
||||
|
||||
__GXData->abtWaitPECopy = GX_TRUE;
|
||||
|
||||
__GXAbort();
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void __GXInitRevisionBits(void) {
|
||||
u32 i;
|
||||
for (i = 0; i < 8; i++) {
|
||||
FAST_FLAG_SET(__GXData->vatA[i], 1, 30, 33);
|
||||
FAST_FLAG_SET(__GXData->vatB[i], 1, 31, 33);
|
||||
|
||||
GX_WRITE_U8(0x8);
|
||||
GX_WRITE_U8(i | 0x80);
|
||||
GX_WRITE_U32(__GXData->vatB[i]);
|
||||
}
|
||||
|
||||
{
|
||||
u32 reg1 = 0;
|
||||
u32 reg2 = 0;
|
||||
|
||||
FAST_FLAG_SET(reg1, 1, 0, 1);
|
||||
FAST_FLAG_SET(reg1, 1, 1, 1);
|
||||
FAST_FLAG_SET(reg1, 1, 2, 1);
|
||||
FAST_FLAG_SET(reg1, 1, 3, 1);
|
||||
FAST_FLAG_SET(reg1, 1, 4, 1);
|
||||
FAST_FLAG_SET(reg1, 1, 5, 1);
|
||||
GX_WRITE_U8(0x10);
|
||||
GX_WRITE_U32(0x1000);
|
||||
GX_WRITE_U32(reg1);
|
||||
|
||||
FAST_FLAG_SET(reg2, 1, 0, 1);
|
||||
GX_WRITE_U8(0x10);
|
||||
GX_WRITE_U32(0x1012);
|
||||
GX_WRITE_U32(reg2);
|
||||
}
|
||||
|
||||
{
|
||||
u32 reg = 0;
|
||||
FAST_FLAG_SET(reg, 1, 0, 1);
|
||||
FAST_FLAG_SET(reg, 1, 1, 1);
|
||||
FAST_FLAG_SET(reg, 1, 2, 1);
|
||||
FAST_FLAG_SET(reg, 1, 3, 1);
|
||||
FAST_FLAG_SET(reg, 0x58, 24, 8);
|
||||
GX_WRITE_U8(0x61);
|
||||
GX_WRITE_U32(reg);
|
||||
}
|
||||
}
|
||||
|
||||
static u16 DefaultTexData[] ALIGN_DECL(32) = {
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||
};
|
||||
|
||||
static GXVtxAttrFmtList GXDefaultVATList[] = {
|
||||
{GX_VA_POS, GX_POS_XYZ, GX_F32, 0},
|
||||
{GX_VA_NRM, GX_NRM_XYZ, GX_F32, 0},
|
||||
{GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0},
|
||||
{GX_VA_CLR1, GX_CLR_RGBA, GX_RGBA8, 0},
|
||||
{GX_VA_TEX0, GX_TEX_ST, GX_F32, 0},
|
||||
{GX_VA_TEX1, GX_TEX_ST, GX_F32, 0},
|
||||
{GX_VA_TEX2, GX_TEX_ST, GX_F32, 0},
|
||||
{GX_VA_TEX3, GX_TEX_ST, GX_F32, 0},
|
||||
{GX_VA_TEX4, GX_TEX_ST, GX_F32, 0},
|
||||
{GX_VA_TEX5, GX_TEX_ST, GX_F32, 0},
|
||||
{GX_VA_TEX6, GX_TEX_ST, GX_F32, 0},
|
||||
{GX_VA_TEX7, GX_TEX_ST, GX_F32, 0},
|
||||
{GX_VA_NULL, GX_COMPCNT_NULL, GX_COMP_NULL, 0},
|
||||
};
|
||||
|
||||
static f32 GXDefaultProjData[] = {1.0f, 0.0f, 1.0f, 0.0f, -1.0f, -2.0f, 0.0f};
|
||||
|
||||
static u32 GXTexRegionAddrTable[] = {
|
||||
0x00000, 0x10000, 0x20000, 0x30000, 0x40000, 0x50000, 0x60000, 0x70000, 0x08000, 0x18000,
|
||||
0x28000, 0x38000, 0x48000, 0x58000, 0x68000, 0x78000, 0x00000, 0x90000, 0x20000, 0xB0000,
|
||||
0x40000, 0x98000, 0x60000, 0xB8000, 0x80000, 0x10000, 0xA0000, 0x30000, 0x88000, 0x50000,
|
||||
0xA8000, 0x70000, 0x00000, 0x90000, 0x20000, 0xB0000, 0x40000, 0x90000, 0x60000, 0xB0000,
|
||||
0x80000, 0x10000, 0xA0000, 0x30000, 0x80000, 0x50000, 0xA0000, 0x70000,
|
||||
};
|
||||
|
||||
static OSResetFunctionInfo GXResetFuncInfo = {__GXShutdown, OS_RESET_PRIO_GX};
|
||||
|
||||
static void EnableWriteGatherPipe() {
|
||||
u32 hid2; // r31
|
||||
hid2 = PPCMfhid2();
|
||||
PPCMtwpar(OSUncachedToPhysical((void*)GXFIFO_ADDR));
|
||||
hid2 |= 0x40000000;
|
||||
PPCMthid2(hid2);
|
||||
}
|
||||
|
||||
GXFifoObj* GXInit(void* base, u32 size) {
|
||||
u32 i;
|
||||
u32 pad2; // for stack matching
|
||||
|
||||
OSRegisterVersion(__GXVersion);
|
||||
__GXData->inDispList = GX_FALSE;
|
||||
__GXData->dlSaveContext = GX_TRUE;
|
||||
__GXData->abtWaitPECopy = GX_TRUE;
|
||||
|
||||
__GXData->tcsManEnab = 0;
|
||||
__GXData->tevTcEnab = 0;
|
||||
|
||||
GXSetMisc(GX_MT_XF_FLUSH, 0);
|
||||
|
||||
__piReg = (void*)OSPhysicalToUncached(GX_PI_ADDR);
|
||||
__cpReg = (void*)OSPhysicalToUncached(GX_CP_ADDR);
|
||||
__peReg = (void*)OSPhysicalToUncached(GX_PE_ADDR);
|
||||
__memReg = (void*)OSPhysicalToUncached(GX_MEM_ADDR);
|
||||
|
||||
__GXFifoInit();
|
||||
|
||||
GXInitFifoBase(&FifoObj, base, size);
|
||||
GXSetCPUFifo(&FifoObj);
|
||||
GXSetGPFifo(&FifoObj);
|
||||
|
||||
if (!resetFuncRegistered) {
|
||||
OSRegisterResetFunction(&GXResetFuncInfo);
|
||||
resetFuncRegistered = 1;
|
||||
}
|
||||
|
||||
__GXPEInit();
|
||||
EnableWriteGatherPipe();
|
||||
|
||||
__GXData->genMode = 0;
|
||||
FAST_FLAG_SET(__GXData->genMode, 0, 24, 8);
|
||||
|
||||
__GXData->bpMask = 255;
|
||||
FAST_FLAG_SET(__GXData->bpMask, 0xF, 24, 8);
|
||||
|
||||
__GXData->lpSize = 0;
|
||||
FAST_FLAG_SET(__GXData->lpSize, 34, 24, 8);
|
||||
|
||||
for (i = 0; i < GX_MAX_TEVSTAGE; i++) {
|
||||
__GXData->tevc[i] = 0;
|
||||
__GXData->teva[i] = 0;
|
||||
__GXData->tref[i / 2] = 0;
|
||||
__GXData->texmapId[i] = GX_TEXMAP_NULL;
|
||||
|
||||
FAST_FLAG_SET(__GXData->tevc[i], 0xC0 + i * 2, 24, 8);
|
||||
FAST_FLAG_SET(__GXData->teva[i], 0xC1 + i * 2, 24, 8);
|
||||
FAST_FLAG_SET(__GXData->tevKsel[i / 2], 0xF6 + i / 2, 24, 8);
|
||||
FAST_FLAG_SET(__GXData->tref[i / 2], 0x28 + i / 2, 24, 8);
|
||||
}
|
||||
|
||||
__GXData->iref = 0;
|
||||
FAST_FLAG_SET(__GXData->iref, 0x27, 24, 8);
|
||||
|
||||
for (i = 0; i < GX_MAXCOORD; i++) {
|
||||
__GXData->suTs0[i] = 0;
|
||||
__GXData->suTs1[i] = 0;
|
||||
|
||||
FAST_FLAG_SET(__GXData->suTs0[i], 0x30 + i * 2, 24, 8);
|
||||
FAST_FLAG_SET(__GXData->suTs1[i], 0x31 + i * 2, 24, 8);
|
||||
}
|
||||
|
||||
FAST_FLAG_SET(__GXData->suScis0, 0x20, 24, 8);
|
||||
FAST_FLAG_SET(__GXData->suScis1, 0x21, 24, 8);
|
||||
|
||||
FAST_FLAG_SET(__GXData->cmode0, 0x41, 24, 8);
|
||||
FAST_FLAG_SET(__GXData->cmode1, 0x42, 24, 8);
|
||||
|
||||
FAST_FLAG_SET(__GXData->zmode, 0x40, 24, 8);
|
||||
FAST_FLAG_SET(__GXData->peCtrl, 0x43, 24, 8);
|
||||
|
||||
FAST_FLAG_SET(__GXData->cpTex, 0, 7, 2);
|
||||
|
||||
__GXData->zScale = 1.6777216E7f;
|
||||
__GXData->zOffset = 0.0f;
|
||||
|
||||
__GXData->dirtyState = 0;
|
||||
__GXData->dirtyVAT = 0;
|
||||
|
||||
{
|
||||
u32 val1;
|
||||
u32 val2;
|
||||
|
||||
val2 = OS_BUS_CLOCK / 500;
|
||||
|
||||
__GXFlushTextureState();
|
||||
|
||||
val1 = (val2 / 2048) | 0x69000400;
|
||||
|
||||
GX_WRITE_U8(0x61);
|
||||
GX_WRITE_U32(val1);
|
||||
|
||||
__GXFlushTextureState();
|
||||
|
||||
val1 = (val2 / 4224) | 0x46000200;
|
||||
GX_WRITE_U8(0x61);
|
||||
GX_WRITE_U32(val1);
|
||||
}
|
||||
|
||||
__GXInitRevisionBits();
|
||||
|
||||
for (i = 0; i < GX_MAX_TEXMAP; i++) {
|
||||
GXInitTexCacheRegion(&__GXData->TexRegions0[i], GX_FALSE, GXTexRegionAddrTable[i],
|
||||
GX_TEXCACHE_32K, GXTexRegionAddrTable[i + 8], GX_TEXCACHE_32K);
|
||||
GXInitTexCacheRegion(&__GXData->TexRegions1[i], GX_FALSE, GXTexRegionAddrTable[i + 16],
|
||||
GX_TEXCACHE_32K, GXTexRegionAddrTable[i + 24], GX_TEXCACHE_32K);
|
||||
GXInitTexCacheRegion(&__GXData->TexRegions2[i], GX_TRUE, GXTexRegionAddrTable[i + 32],
|
||||
GX_TEXCACHE_32K, GXTexRegionAddrTable[i + 40], GX_TEXCACHE_32K);
|
||||
}
|
||||
|
||||
for (i = 0; i < GX_MAX_TLUT; i++) {
|
||||
GXInitTlutRegion(&__GXData->TlutRegions[i], 0xC0000 + 0x2000 * i, GX_TLUT_256);
|
||||
}
|
||||
|
||||
for (i = 0; i < GX_MAX_BIGTLUT; i++) {
|
||||
GXInitTlutRegion(&__GXData->TlutRegions[i + 16], 0xE0000 + 0x8000 * i, GX_TLUT_1K);
|
||||
}
|
||||
|
||||
GX_SET_CP_REG(3, 0);
|
||||
|
||||
FAST_FLAG_SET(__GXData->perfSel, 0, 4, 4);
|
||||
|
||||
GX_WRITE_U8(0x8);
|
||||
GX_WRITE_U8(0x20);
|
||||
GX_WRITE_U32(__GXData->perfSel);
|
||||
|
||||
GX_WRITE_U8(0x10);
|
||||
GX_WRITE_U32(0x1006);
|
||||
GX_WRITE_U32(0);
|
||||
|
||||
GX_WRITE_U8(0x61);
|
||||
GX_WRITE_U32(0x23000000);
|
||||
|
||||
GX_WRITE_U8(0x61);
|
||||
GX_WRITE_U32(0x24000000);
|
||||
|
||||
GX_WRITE_U8(0x61);
|
||||
GX_WRITE_U32(0x67000000);
|
||||
|
||||
__GXSetIndirectMask(0);
|
||||
__GXSetTmemConfig(2);
|
||||
__GXInitGX();
|
||||
|
||||
return &FifoObj;
|
||||
}
|
||||
|
||||
void __GXInitGX(void) {
|
||||
GXRenderModeObj* renderObj;
|
||||
GXTexObj texObj;
|
||||
Mtx ident;
|
||||
GXColor clearColor = {64, 64, 64, 255};
|
||||
GXColor ambColor = {0, 0, 0, 0};
|
||||
GXColor matColor = {255, 255, 255, 255};
|
||||
u32 i;
|
||||
|
||||
switch (VIGetTvFormat()) {
|
||||
case VI_NTSC:
|
||||
renderObj = &GXNtsc480IntDf;
|
||||
break;
|
||||
|
||||
case VI_PAL:
|
||||
renderObj = &GXPal528IntDf;
|
||||
break;
|
||||
|
||||
case VI_EURGB60:
|
||||
renderObj = &GXEurgb60Hz480IntDf;
|
||||
break;
|
||||
|
||||
case VI_MPAL:
|
||||
renderObj = &GXMpal480IntDf;
|
||||
break;
|
||||
|
||||
default:
|
||||
renderObj = &GXNtsc480IntDf;
|
||||
break;
|
||||
}
|
||||
|
||||
GXSetCopyClear(clearColor, 0xFFFFFF);
|
||||
|
||||
GXSetTexCoordGen2(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY, GX_FALSE, GX_PTIDENTITY);
|
||||
GXSetTexCoordGen2(GX_TEXCOORD1, GX_TG_MTX2x4, GX_TG_TEX1, GX_IDENTITY, GX_FALSE, GX_PTIDENTITY);
|
||||
GXSetTexCoordGen2(GX_TEXCOORD2, GX_TG_MTX2x4, GX_TG_TEX2, GX_IDENTITY, GX_FALSE, GX_PTIDENTITY);
|
||||
GXSetTexCoordGen2(GX_TEXCOORD3, GX_TG_MTX2x4, GX_TG_TEX3, GX_IDENTITY, GX_FALSE, GX_PTIDENTITY);
|
||||
GXSetTexCoordGen2(GX_TEXCOORD4, GX_TG_MTX2x4, GX_TG_TEX4, GX_IDENTITY, GX_FALSE, GX_PTIDENTITY);
|
||||
GXSetTexCoordGen2(GX_TEXCOORD5, GX_TG_MTX2x4, GX_TG_TEX5, GX_IDENTITY, GX_FALSE, GX_PTIDENTITY);
|
||||
GXSetTexCoordGen2(GX_TEXCOORD6, GX_TG_MTX2x4, GX_TG_TEX6, GX_IDENTITY, GX_FALSE, GX_PTIDENTITY);
|
||||
GXSetTexCoordGen2(GX_TEXCOORD7, GX_TG_MTX2x4, GX_TG_TEX7, GX_IDENTITY, GX_FALSE, GX_PTIDENTITY);
|
||||
|
||||
GXSetNumTexGens(1);
|
||||
GXClearVtxDesc();
|
||||
GXInvalidateVtxCache();
|
||||
|
||||
for (i = GX_VA_POS; i <= GX_LIGHT_ARRAY; i++) {
|
||||
GXSetArray((GXAttr)i, __GXData, 0);
|
||||
}
|
||||
|
||||
for (i = 0; i < GX_MAX_VTXFMT; i++) {
|
||||
GXSetVtxAttrFmtv((GXVtxFmt)i, GXDefaultVATList);
|
||||
}
|
||||
|
||||
GXSetLineWidth(6, GX_TO_ZERO);
|
||||
GXSetPointSize(6, GX_TO_ZERO);
|
||||
GXEnableTexOffsets(GX_TEXCOORD0, GX_FALSE, GX_FALSE);
|
||||
GXEnableTexOffsets(GX_TEXCOORD1, GX_FALSE, GX_FALSE);
|
||||
GXEnableTexOffsets(GX_TEXCOORD2, GX_FALSE, GX_FALSE);
|
||||
GXEnableTexOffsets(GX_TEXCOORD3, GX_FALSE, GX_FALSE);
|
||||
GXEnableTexOffsets(GX_TEXCOORD4, GX_FALSE, GX_FALSE);
|
||||
GXEnableTexOffsets(GX_TEXCOORD5, GX_FALSE, GX_FALSE);
|
||||
GXEnableTexOffsets(GX_TEXCOORD6, GX_FALSE, GX_FALSE);
|
||||
GXEnableTexOffsets(GX_TEXCOORD7, GX_FALSE, GX_FALSE);
|
||||
|
||||
ident[0][0] = 1.0f;
|
||||
ident[0][1] = 0.0f;
|
||||
ident[0][2] = 0.0f;
|
||||
ident[0][3] = 0.0f;
|
||||
|
||||
ident[1][0] = 0.0f;
|
||||
ident[1][1] = 1.0f;
|
||||
ident[1][2] = 0.0f;
|
||||
ident[1][3] = 0.0f;
|
||||
|
||||
ident[2][0] = 0.0f;
|
||||
ident[2][1] = 0.0f;
|
||||
ident[2][2] = 1.0f;
|
||||
ident[2][3] = 0.0f;
|
||||
|
||||
GXLoadPosMtxImm(ident, GX_PNMTX0);
|
||||
GXLoadNrmMtxImm(ident, GX_PNMTX0);
|
||||
GXSetCurrentMtx(GX_PNMTX0);
|
||||
|
||||
GXLoadTexMtxImm(ident, GX_IDENTITY, GX_MTX3x4);
|
||||
GXLoadTexMtxImm(ident, GX_PTIDENTITY, GX_MTX3x4);
|
||||
|
||||
GXSetViewport(0.0f, 0.0f, renderObj->fb_width, renderObj->xfb_height, 0.0f, 1.0f);
|
||||
|
||||
GXSetProjectionv(GXDefaultProjData);
|
||||
|
||||
GXSetCoPlanar(GX_FALSE);
|
||||
GXSetCullMode(GX_CULL_BACK);
|
||||
GXSetClipMode(GX_CLIP_ENABLE);
|
||||
|
||||
GXSetScissor(0, 0, renderObj->fb_width, renderObj->efb_height);
|
||||
GXSetScissorBoxOffset(0, 0);
|
||||
|
||||
GXSetNumChans(0);
|
||||
GXSetChanCtrl(GX_COLOR0A0, GX_FALSE, GX_SRC_REG, GX_SRC_VTX, 0, GX_DF_NONE, GX_AF_NONE);
|
||||
GXSetChanAmbColor(GX_COLOR0A0, ambColor);
|
||||
GXSetChanMatColor(GX_COLOR0A0, matColor);
|
||||
|
||||
GXSetChanCtrl(GX_COLOR1A1, GX_FALSE, GX_SRC_REG, GX_SRC_VTX, 0, GX_DF_NONE, GX_AF_NONE);
|
||||
GXSetChanAmbColor(GX_COLOR1A1, ambColor);
|
||||
GXSetChanMatColor(GX_COLOR1A1, matColor);
|
||||
|
||||
GXInvalidateTexAll();
|
||||
GXSetTexRegionCallback(__GXDefaultTexRegionCallback);
|
||||
GXSetTlutRegionCallback(__GXDefaultTlutRegionCallback);
|
||||
|
||||
GXInitTexObj(&texObj, DefaultTexData, 4, 4, GX_TF_IA8, GX_CLAMP, GX_CLAMP, GX_FALSE);
|
||||
GXLoadTexObj(&texObj, GX_TEXMAP0);
|
||||
GXLoadTexObj(&texObj, GX_TEXMAP1);
|
||||
GXLoadTexObj(&texObj, GX_TEXMAP2);
|
||||
GXLoadTexObj(&texObj, GX_TEXMAP3);
|
||||
GXLoadTexObj(&texObj, GX_TEXMAP4);
|
||||
GXLoadTexObj(&texObj, GX_TEXMAP5);
|
||||
GXLoadTexObj(&texObj, GX_TEXMAP6);
|
||||
GXLoadTexObj(&texObj, GX_TEXMAP7);
|
||||
|
||||
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 (i = 0; 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);
|
||||
|
||||
for (i = 0; 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);
|
||||
|
||||
GXSetFog(GX_FOG_NONE, 0.0f, 1.0f, 0.1f, 1.0f, ambColor);
|
||||
GXSetFogRangeAdj(GX_FALSE, 0, NULL);
|
||||
|
||||
GXSetBlendMode(GX_BM_NONE, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_CLEAR);
|
||||
|
||||
GXSetColorUpdate(GX_TRUE);
|
||||
GXSetAlphaUpdate(GX_TRUE);
|
||||
|
||||
GXSetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE);
|
||||
GXSetZCompLoc(GX_TRUE);
|
||||
|
||||
GXSetDither(GX_TRUE);
|
||||
|
||||
GXSetDstAlpha(GX_FALSE, 0);
|
||||
GXSetPixelFmt(GX_PF_RGB8_Z24, GX_ZC_LINEAR);
|
||||
|
||||
GXSetFieldMask(GX_TRUE, GX_TRUE);
|
||||
GXSetFieldMode(
|
||||
(GXBool)renderObj->field_rendering,
|
||||
(GXBool)((renderObj->vi_height == 2 * renderObj->xfb_height) ? GX_TRUE : GX_FALSE));
|
||||
|
||||
GXSetDispCopySrc(0, 0, renderObj->fb_width, renderObj->efb_height);
|
||||
GXSetDispCopyDst(renderObj->fb_width, renderObj->efb_height);
|
||||
GXSetDispCopyYScale((f32)renderObj->xfb_height / (f32)renderObj->efb_height);
|
||||
GXSetCopyClamp(GX_CLAMP_BOTH);
|
||||
|
||||
GXSetCopyFilter(renderObj->antialiasing, renderObj->sample_pattern, GX_TRUE,
|
||||
renderObj->vfilter);
|
||||
GXSetDispCopyGamma(GX_GM_1_0);
|
||||
GXSetDispCopyFrame2Field(GX_COPY_PROGRESSIVE);
|
||||
GXClearBoundingBox();
|
||||
|
||||
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_FALSE, 0);
|
||||
GXPokeZMode(GX_TRUE, GX_ALWAYS, GX_TRUE);
|
||||
GXSetGPMetric(GX_PERF0_NONE, GX_PERF1_NONE);
|
||||
GXClearGPMetric();
|
||||
}
|
294
src/dolphin/gx/GXLight.c
Normal file
294
src/dolphin/gx/GXLight.c
Normal file
@ -0,0 +1,294 @@
|
||||
/**
|
||||
* GXLight.c
|
||||
* Description:
|
||||
*/
|
||||
|
||||
#include "dolphin/gx/GXLight.h"
|
||||
#include "dolphin/gx/GX.h"
|
||||
#include "math.h"
|
||||
|
||||
void GXInitLightAttn(GXLightObj* obj, f32 a0, f32 a1, f32 a2, f32 k0, f32 k1, f32 k2) {
|
||||
obj->a0 = a0;
|
||||
obj->a1 = a1;
|
||||
obj->a2 = a2;
|
||||
obj->k0 = k0;
|
||||
obj->k1 = k1;
|
||||
obj->k2 = k2;
|
||||
}
|
||||
|
||||
void GXInitLightSpot(GXLightObj* obj, f32 cutoff, GXSpotFn spot_fn) {
|
||||
f32 rad;
|
||||
f32 a, b, c, d;
|
||||
|
||||
if (cutoff <= 0.0f || cutoff > 90.0f) {
|
||||
spot_fn = GX_SP_OFF;
|
||||
}
|
||||
|
||||
rad = cosf((3.1415927f * cutoff) / 180.0f);
|
||||
|
||||
switch (spot_fn) {
|
||||
case GX_SP_FLAT:
|
||||
a = -1000.0f * rad;
|
||||
b = 1000.0f;
|
||||
c = 0.0f;
|
||||
break;
|
||||
case GX_SP_COS:
|
||||
b = 1.0f / (1.0f - rad);
|
||||
a = -rad * b;
|
||||
c = 0.0f;
|
||||
break;
|
||||
case GX_SP_COS2:
|
||||
c = 1.0f / (1.0f - rad);
|
||||
a = 0.0f;
|
||||
b = -rad * c;
|
||||
break;
|
||||
case GX_SP_SHARP:
|
||||
d = 1.0f / ((1.0f - rad) * (1.0f - rad));
|
||||
a = (rad * (rad - 2.0f)) * d;
|
||||
b = 2.0f * d;
|
||||
c = -d;
|
||||
break;
|
||||
case GX_SP_RING1:
|
||||
d = 1.0f / ((1.0f - rad) * (1.0f - rad));
|
||||
c = -4.0f * d;
|
||||
a = c * rad;
|
||||
b = 4.0f * (1.0f + rad) * d;
|
||||
break;
|
||||
case GX_SP_RING2:
|
||||
d = 1.0f / ((1.0f - rad) * (1.0f - rad));
|
||||
a = 1.0f - 2.0f * rad * rad * d;
|
||||
b = 4.0f * rad * d;
|
||||
c = -2.0f * d;
|
||||
break;
|
||||
case GX_SP_OFF:
|
||||
default:
|
||||
a = 1.0f;
|
||||
b = 0.0f;
|
||||
c = 0.0f;
|
||||
break;
|
||||
}
|
||||
|
||||
obj->a0 = a;
|
||||
obj->a1 = b;
|
||||
obj->a2 = c;
|
||||
}
|
||||
|
||||
void GXInitLightDistAttn(GXLightObj* obj, f32 dist, f32 brightness, GXDistAttnFn dist_fn) {
|
||||
f32 a, b, c;
|
||||
|
||||
if (dist < 0.0f) {
|
||||
dist_fn = GX_DA_OFF;
|
||||
}
|
||||
|
||||
if (brightness <= 0.0f || brightness >= 1.0f) {
|
||||
dist_fn = GX_DA_OFF;
|
||||
}
|
||||
|
||||
switch (dist_fn) {
|
||||
case GX_DA_GENTLE:
|
||||
a = 1.0f;
|
||||
b = (1.0f - brightness) / (brightness * dist);
|
||||
c = 0.0f;
|
||||
break;
|
||||
case GX_DA_MEDIUM:
|
||||
a = 1.0f;
|
||||
b = (0.5f * (1.0f - brightness)) / (brightness * dist);
|
||||
c = (0.5f * (1.0f - brightness)) / (dist * (brightness * dist));
|
||||
break;
|
||||
case GX_DA_STEEP:
|
||||
a = 1.0f;
|
||||
b = 0.0f;
|
||||
c = (1.0f - brightness) / (dist * (brightness * dist));
|
||||
break;
|
||||
case GX_DA_OFF:
|
||||
default:
|
||||
a = 1.0f;
|
||||
b = 0.0f;
|
||||
c = 0.0f;
|
||||
break;
|
||||
}
|
||||
|
||||
obj->k0 = a;
|
||||
obj->k1 = b;
|
||||
obj->k2 = c;
|
||||
}
|
||||
|
||||
void GXInitLightPos(GXLightObj* obj, f32 x, f32 y, f32 z) {
|
||||
obj->posX = x;
|
||||
obj->posY = y;
|
||||
obj->posZ = z;
|
||||
}
|
||||
|
||||
void GXInitLightDir(GXLightObj* obj, f32 x, f32 y, f32 z) {
|
||||
obj->dirX = -x;
|
||||
obj->dirY = -y;
|
||||
obj->dirZ = -z;
|
||||
}
|
||||
|
||||
void GXInitLightColor(GXLightObj* obj, GXColor color) {
|
||||
*(u32*)&obj->color = *(u32*)&color;
|
||||
}
|
||||
|
||||
static inline void PushLight(const register GXLightObj* lt_obj, register void* dest) {
|
||||
register u32 zero, color;
|
||||
register f32 a0_a1, a2_k0, k1_k2;
|
||||
register f32 px_py, pz_dx, dy_dz;
|
||||
#ifdef __MWERKS__ // clang-format off
|
||||
asm {
|
||||
lwz color, 12(lt_obj)
|
||||
xor zero, zero, zero
|
||||
psq_l a0_a1, 16(lt_obj), 0, 0
|
||||
psq_l a2_k0, 24(lt_obj), 0, 0
|
||||
psq_l k1_k2, 32(lt_obj), 0, 0
|
||||
psq_l px_py, 40(lt_obj), 0, 0
|
||||
psq_l pz_dx, 48(lt_obj), 0, 0
|
||||
psq_l dy_dz, 56(lt_obj), 0, 0
|
||||
|
||||
stw zero, 0(dest)
|
||||
stw zero, 0(dest)
|
||||
stw zero, 0(dest)
|
||||
stw color, 0(dest)
|
||||
psq_st a0_a1, 0(dest), 0, 0
|
||||
psq_st a2_k0, 0(dest), 0, 0
|
||||
psq_st k1_k2, 0(dest), 0, 0
|
||||
psq_st px_py, 0(dest), 0, 0
|
||||
psq_st pz_dx, 0(dest), 0, 0
|
||||
psq_st dy_dz, 0(dest), 0, 0
|
||||
}
|
||||
#endif // clang-format on
|
||||
}
|
||||
|
||||
void GXLoadLightObjImm(GXLightObj* obj, GXLightID light) {
|
||||
u32 addr;
|
||||
u32 idx;
|
||||
GXLightObj* pObj = (GXLightObj*)obj;
|
||||
|
||||
idx = 31 - __cntlzw(light);
|
||||
idx &= 7;
|
||||
|
||||
addr = 0x600 + idx * 0x10;
|
||||
|
||||
GX_XF_LOAD_REG_HDR(addr | (0x10 - 1) << 16);
|
||||
|
||||
PushLight(pObj, (void*)GXFIFO_ADDR);
|
||||
__GXData->bpSentNot = 1;
|
||||
}
|
||||
|
||||
void GXSetChanAmbColor(GXChannelID channel, GXColor color) {
|
||||
u32 reg;
|
||||
u32 colorID;
|
||||
u8 alpha;
|
||||
|
||||
switch (channel) {
|
||||
case GX_COLOR0:
|
||||
reg = __GXData->ambColor[GX_COLOR0];
|
||||
reg = GX_SET_TRUNC(reg, GXCOLOR_AS_U32(color), 0, 23);
|
||||
colorID = GX_COLOR0;
|
||||
break;
|
||||
case GX_COLOR1:
|
||||
reg = __GXData->ambColor[GX_COLOR1];
|
||||
reg = GX_SET_TRUNC(reg, GXCOLOR_AS_U32(color), 0, 23);
|
||||
colorID = GX_COLOR1;
|
||||
break;
|
||||
case GX_ALPHA0:
|
||||
reg = __GXData->ambColor[GX_COLOR0];
|
||||
reg = GX_SET_TRUNC(reg, color.a, 24, 31);
|
||||
colorID = GX_COLOR0;
|
||||
break;
|
||||
case GX_ALPHA1:
|
||||
reg = __GXData->ambColor[GX_COLOR1];
|
||||
reg = GX_SET_TRUNC(reg, color.a, 24, 31);
|
||||
colorID = GX_COLOR1;
|
||||
break;
|
||||
case GX_COLOR0A0:
|
||||
reg = GXCOLOR_AS_U32(color);
|
||||
colorID = GX_COLOR0;
|
||||
break;
|
||||
case GX_COLOR1A1:
|
||||
reg = GXCOLOR_AS_U32(color);
|
||||
colorID = GX_COLOR1;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
GX_XF_LOAD_REG(GX_XF_REG_AMBIENT0 + colorID, reg);
|
||||
__GXData->bpSentNot = GX_TRUE;
|
||||
__GXData->ambColor[colorID] = reg;
|
||||
}
|
||||
|
||||
void GXSetChanMatColor(GXChannelID channel, GXColor color) {
|
||||
u32 reg = 0;
|
||||
GXChannelID colorID;
|
||||
|
||||
switch (channel) {
|
||||
case GX_COLOR0:
|
||||
reg = __GXData->matColor[GX_COLOR0];
|
||||
reg = GX_SET_TRUNC(reg, GXCOLOR_AS_U32(color), 0, 23);
|
||||
colorID = GX_COLOR0;
|
||||
break;
|
||||
case GX_COLOR1:
|
||||
reg = __GXData->matColor[GX_COLOR1];
|
||||
reg = GX_SET_TRUNC(reg, GXCOLOR_AS_U32(color), 0, 23);
|
||||
colorID = GX_COLOR1;
|
||||
break;
|
||||
case GX_ALPHA0:
|
||||
reg = __GXData->matColor[GX_COLOR0];
|
||||
reg = GX_SET_TRUNC(reg, color.a, 24, 31);
|
||||
colorID = GX_COLOR0;
|
||||
break;
|
||||
case GX_ALPHA1:
|
||||
reg = __GXData->matColor[GX_COLOR1];
|
||||
reg = GX_SET_TRUNC(reg, color.a, 24, 31);
|
||||
colorID = GX_COLOR1;
|
||||
break;
|
||||
case GX_COLOR0A0:
|
||||
reg = GXCOLOR_AS_U32(color);
|
||||
colorID = GX_COLOR0;
|
||||
break;
|
||||
case GX_COLOR1A1:
|
||||
reg = GXCOLOR_AS_U32(color);
|
||||
colorID = GX_COLOR1;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
GX_XF_LOAD_REG(GX_XF_REG_MATERIAL0 + colorID, reg);
|
||||
__GXData->bpSentNot = GX_TRUE;
|
||||
__GXData->matColor[colorID] = reg;
|
||||
}
|
||||
|
||||
void GXSetNumChans(u8 count) {
|
||||
GX_SET_REG(__GXData->genMode, count, 25, 27);
|
||||
GX_XF_LOAD_REG(GX_XF_REG_NUMCOLORS, count);
|
||||
__GXData->dirtyState |= GX_DIRTY_GEN_MODE;
|
||||
}
|
||||
|
||||
void GXSetChanCtrl(GXChannelID channel, GXBool doEnable, GXColorSrc ambSrc, GXColorSrc matSrc,
|
||||
u32 mask, GXDiffuseFn diffFunc, GXAttnFn attnFunc) {
|
||||
const u32 colorID = (u32)channel & 0x3;
|
||||
u32 reg = 0;
|
||||
|
||||
GX_SET_REG(reg, doEnable, GX_XF_CLR0CTRL_LIGHT_ST, GX_XF_CLR0CTRL_LIGHT_END);
|
||||
GX_SET_REG(reg, matSrc, GX_XF_CLR0CTRL_MTXSRC_ST, GX_XF_CLR0CTRL_MTXSRC_END);
|
||||
GX_SET_REG(reg, ambSrc, GX_XF_CLR0CTRL_AMBSRC_ST, GX_XF_CLR0CTRL_AMBSRC_END);
|
||||
GX_SET_REG(reg, (attnFunc == GX_AF_SPEC ? GX_DF_NONE : diffFunc), GX_XF_CLR0CTRL_DIFATTN_ST,
|
||||
GX_XF_CLR0CTRL_DIFATTN_END);
|
||||
GX_SET_REG(reg, (attnFunc != GX_AF_NONE), GX_XF_CLR0CTRL_ATTNENABLE_ST,
|
||||
GX_XF_CLR0CTRL_ATTNENABLE_END);
|
||||
GX_SET_REG(reg, (attnFunc != GX_AF_SPEC), GX_XF_CLR0CTRL_ATTNSEL_ST,
|
||||
GX_XF_CLR0CTRL_ATTNSEL_END);
|
||||
GX_BITFIELD_SET(reg, 26, 4, (u32)mask);
|
||||
reg = __rlwimi(reg, (u32)mask, 7, 0x11, 0x14);
|
||||
|
||||
GX_XF_LOAD_REG(GX_XF_REG_COLOR0CNTRL + colorID, reg);
|
||||
|
||||
if (channel == GX_COLOR0A0) {
|
||||
GX_XF_LOAD_REG(GX_XF_REG_ALPHA0CNTRL, reg);
|
||||
} else if (channel == GX_COLOR1A1) {
|
||||
GX_XF_LOAD_REG(GX_XF_REG_ALPHA1CNTRL, reg);
|
||||
}
|
||||
|
||||
__GXData->bpSentNot = GX_TRUE;
|
||||
}
|
266
src/dolphin/gx/GXMisc.c
Normal file
266
src/dolphin/gx/GXMisc.c
Normal file
@ -0,0 +1,266 @@
|
||||
#include "dolphin/gx/GXMisc.h"
|
||||
#include "dolphin/gx/GX.h"
|
||||
#include "dolphin/os/OSInterrupt.h"
|
||||
#include "dolphin/os/OSReset.h"
|
||||
#include "dolphin/os/OSTime.h"
|
||||
|
||||
static void GXTokenInterruptHandler(__OSInterrupt interrupt, OSContext* context);
|
||||
static void GXFinishInterruptHandler(__OSInterrupt interrupt, OSContext* pContext);
|
||||
|
||||
void GXSetMisc(GXMiscToken token, u32 val) {
|
||||
switch (token) {
|
||||
case GX_MT_NULL:
|
||||
break;
|
||||
|
||||
case GX_MT_XF_FLUSH:
|
||||
__GXData->vNum = val;
|
||||
__GXData->vNumNot = !__GXData->vNum;
|
||||
__GXData->bpSentNot = GX_TRUE;
|
||||
|
||||
if (__GXData->vNum) {
|
||||
__GXData->dirtyState |= GX_DIRTY_VCD;
|
||||
}
|
||||
break;
|
||||
|
||||
case GX_MT_DL_SAVE_CONTEXT:
|
||||
__GXData->dlSaveContext = (val != 0);
|
||||
break;
|
||||
|
||||
case GX_MT_ABORT_WAIT_COPYOUT:
|
||||
__GXData->abtWaitPECopy = (val != 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void GXFlush(void) {
|
||||
if (__GXData->dirtyState) {
|
||||
__GXSetDirtyState();
|
||||
}
|
||||
|
||||
GXFIFO.u32 = 0;
|
||||
GXFIFO.u32 = 0;
|
||||
GXFIFO.u32 = 0;
|
||||
GXFIFO.u32 = 0;
|
||||
GXFIFO.u32 = 0;
|
||||
GXFIFO.u32 = 0;
|
||||
GXFIFO.u32 = 0;
|
||||
GXFIFO.u32 = 0;
|
||||
|
||||
PPCSync();
|
||||
}
|
||||
|
||||
static void __GXAbortWait(u32 clocks) {
|
||||
OSTime time0, time1;
|
||||
time0 = OSGetTime();
|
||||
|
||||
do {
|
||||
time1 = OSGetTime();
|
||||
} while (time1 - time0 <= clocks / 4);
|
||||
}
|
||||
|
||||
static void __GXAbortWaitPECopyDone(void) {
|
||||
u32 peCnt0, peCnt1;
|
||||
|
||||
peCnt0 = GXReadMEMReg(0x28, 0x27);
|
||||
do {
|
||||
peCnt1 = peCnt0;
|
||||
__GXAbortWait(32);
|
||||
|
||||
peCnt0 = GXReadMEMReg(0x28, 0x27);
|
||||
} while (peCnt0 != peCnt1);
|
||||
}
|
||||
|
||||
void __GXAbort(void) {
|
||||
if (__GXData->abtWaitPECopy && GXGetGPFifo()) {
|
||||
__GXAbortWaitPECopyDone();
|
||||
}
|
||||
|
||||
__PIRegs[0x18 / 4] = 1;
|
||||
__GXAbortWait(200);
|
||||
__PIRegs[0x18 / 4] = 0;
|
||||
__GXAbortWait(20);
|
||||
}
|
||||
|
||||
void GXAbortFrame(void) {
|
||||
__GXAbort();
|
||||
if (GXGetGPFifo()) {
|
||||
__GXCleanGPFifo();
|
||||
__GXInitRevisionBits();
|
||||
__GXData->dirtyState = 0;
|
||||
GXFlush();
|
||||
}
|
||||
}
|
||||
|
||||
/* ############################################################################################## */
|
||||
static GXDrawSyncCallback TokenCB;
|
||||
|
||||
static GXDrawDoneCallback DrawDoneCB;
|
||||
|
||||
static GXBool DrawDone;
|
||||
|
||||
void GXSetDrawDone(void) {
|
||||
u8 padding[8];
|
||||
BOOL restore = OSDisableInterrupts();
|
||||
GFWriteBPCmd(0x45000002);
|
||||
GXFlush();
|
||||
DrawDone = 0;
|
||||
OSRestoreInterrupts(restore);
|
||||
}
|
||||
|
||||
/* ############################################################################################## */
|
||||
static OSThreadQueue FinishQueue;
|
||||
|
||||
static void GXWaitDrawDone(void) {
|
||||
BOOL restore = OSDisableInterrupts();
|
||||
while (DrawDone == 0) {
|
||||
OSSleepThread(&FinishQueue);
|
||||
}
|
||||
OSRestoreInterrupts(restore);
|
||||
}
|
||||
|
||||
void GXDrawDone(void) {
|
||||
u8 padding[8];
|
||||
GXSetDrawDone();
|
||||
GXWaitDrawDone();
|
||||
}
|
||||
|
||||
void GXPixModeSync(void) {
|
||||
GXFIFO.u8 = 0x61;
|
||||
GXFIFO.u32 = __GXData->peCtrl;
|
||||
__GXData->bpSentNot = 0;
|
||||
}
|
||||
|
||||
void GXPokeAlphaMode(GXCompare comp, u8 threshold) {
|
||||
__peReg[3] = (comp << 8) | threshold;
|
||||
}
|
||||
|
||||
void GXPokeAlphaRead(GXAlphaReadMode mode) {
|
||||
u32 val = 0;
|
||||
GX_BITFIELD_SET(val, 0x1e, 2, mode);
|
||||
GX_BITFIELD_SET(val, 0x1d, 1, 1);
|
||||
__peReg[4] = val;
|
||||
}
|
||||
|
||||
void GXPokeAlphaUpdate(GXBool enable_update) {
|
||||
GX_BITFIELD_SET(__peReg[1], 0x1b, 1, enable_update);
|
||||
}
|
||||
|
||||
void GXPokeBlendMode(GXBlendMode mode, GXBlendFactor srcFactor, GXBlendFactor destFactor,
|
||||
GXLogicOp op) {
|
||||
u32 reg;
|
||||
|
||||
reg = GX_GET_PE_REG(1);
|
||||
GX_SET_REG(reg, (mode == GX_BM_BLEND) || (mode == GX_BM_SUBTRACT), 31, 31);
|
||||
GX_SET_REG(reg, (mode == GX_BM_SUBTRACT), 20, 20);
|
||||
GX_SET_REG(reg, (mode == GX_BM_LOGIC), 30, 30);
|
||||
GX_SET_REG(reg, op, 16, 19);
|
||||
GX_SET_REG(reg, srcFactor, 21, 23);
|
||||
GX_SET_REG(reg, destFactor, 24, 26);
|
||||
GX_SET_REG(reg, 0x41, 0, 7);
|
||||
GX_SET_PE_REG(1, reg);
|
||||
}
|
||||
|
||||
void GXPokeColorUpdate(GXBool enable_update) {
|
||||
GX_BITFIELD_SET(__peReg[1], 0x1c, 1, enable_update);
|
||||
}
|
||||
|
||||
void GXPokeDstAlpha(GXBool enable, u8 alpha) {
|
||||
u32 val = 0;
|
||||
GX_BITFIELD_SET(val, 0x18, 8, alpha);
|
||||
GX_BITFIELD_SET(val, 0x17, 1, enable);
|
||||
__peReg[2] = val;
|
||||
}
|
||||
|
||||
void GXPokeDither(GXBool enable) {
|
||||
GX_BITFIELD_SET(__peReg[1], 0x1d, 1, enable);
|
||||
}
|
||||
|
||||
void GXPokeZMode(GXBool enable_compare, GXCompare comp, GXBool update_enable) {
|
||||
u32 val = 0;
|
||||
GX_BITFIELD_SET(val, 0x1f, 1, enable_compare);
|
||||
GX_BITFIELD_SET(val, 0x1c, 3, comp);
|
||||
GX_BITFIELD_SET(val, 0x1b, 1, update_enable);
|
||||
__peReg[0] = val;
|
||||
}
|
||||
|
||||
void GXPeekZ(u16 x, u16 y, u32* z) {
|
||||
u32 addr = 0xc8000000;
|
||||
GX_BITFIELD_SET(addr, 0x14, 10, x);
|
||||
GX_BITFIELD_SET(addr, 0xa, 10, y);
|
||||
GX_BITFIELD_SET(addr, 8, 2, 1);
|
||||
*z = *(u32*)addr;
|
||||
}
|
||||
|
||||
GXDrawSyncCallback GXSetDrawSyncCallback(GXDrawSyncCallback callback) {
|
||||
BOOL restore;
|
||||
GXDrawSyncCallback prevCb = TokenCB;
|
||||
restore = OSDisableInterrupts();
|
||||
TokenCB = callback;
|
||||
OSRestoreInterrupts(restore);
|
||||
return prevCb;
|
||||
}
|
||||
|
||||
static void GXTokenInterruptHandler(__OSInterrupt interrupt, OSContext* context) {
|
||||
u16 token;
|
||||
OSContext exceptContext;
|
||||
u32 reg;
|
||||
|
||||
token = GX_GET_PE_REG(7);
|
||||
|
||||
if (TokenCB) {
|
||||
OSClearContext(&exceptContext);
|
||||
OSSetCurrentContext(&exceptContext);
|
||||
TokenCB(token);
|
||||
OSClearContext(&exceptContext);
|
||||
OSSetCurrentContext(context);
|
||||
}
|
||||
|
||||
reg = GX_GET_PE_REG(5);
|
||||
GX_SET_REG(reg, 1, 29, 29);
|
||||
GX_SET_PE_REG(5, reg);
|
||||
}
|
||||
|
||||
GXDrawDoneCallback GXSetDrawDoneCallback(GXDrawDoneCallback callback) {
|
||||
BOOL restore;
|
||||
GXDrawDoneCallback prevCb = DrawDoneCB;
|
||||
restore = OSDisableInterrupts();
|
||||
DrawDoneCB = callback;
|
||||
OSRestoreInterrupts(restore);
|
||||
return prevCb;
|
||||
}
|
||||
|
||||
static void GXFinishInterruptHandler(__OSInterrupt interrupt, OSContext* context) {
|
||||
OSContext exceptContext;
|
||||
u32 reg;
|
||||
|
||||
reg = GX_GET_PE_REG(5);
|
||||
GX_SET_REG(reg, 1, 28, 28);
|
||||
GX_SET_PE_REG(5, reg);
|
||||
|
||||
DrawDone = GX_TRUE;
|
||||
|
||||
if (DrawDoneCB) {
|
||||
OSClearContext(&exceptContext);
|
||||
OSSetCurrentContext(&exceptContext);
|
||||
DrawDoneCB();
|
||||
OSClearContext(&exceptContext);
|
||||
OSSetCurrentContext(context);
|
||||
}
|
||||
|
||||
OSWakeupThread(&FinishQueue);
|
||||
}
|
||||
|
||||
void __GXPEInit(void) {
|
||||
u32 val;
|
||||
__OSSetInterruptHandler(OS_INTR_PI_PE_TOKEN, GXTokenInterruptHandler);
|
||||
__OSSetInterruptHandler(OS_INTR_PI_PE_FINISH, GXFinishInterruptHandler);
|
||||
OSInitThreadQueue(&FinishQueue);
|
||||
__OSUnmaskInterrupts(OS_INTERRUPTMASK_PI_PE_TOKEN);
|
||||
__OSUnmaskInterrupts(OS_INTERRUPTMASK_PI_PE_FINISH);
|
||||
val = __peReg[5];
|
||||
GX_BITFIELD_SET(val, 0x1d, 1, 1);
|
||||
GX_BITFIELD_SET(val, 0x1c, 1, 1);
|
||||
GX_BITFIELD_SET(val, 0x1f, 1, 1);
|
||||
GX_BITFIELD_SET(val, 0x1e, 1, 1);
|
||||
__peReg[5] = val;
|
||||
}
|
384
src/dolphin/gx/GXPerf.c
Normal file
384
src/dolphin/gx/GXPerf.c
Normal file
@ -0,0 +1,384 @@
|
||||
#include "dolphin/gx/GXPerf.h"
|
||||
#include "dolphin/gx/GX.h"
|
||||
|
||||
void GXSetGPMetric(GXPerf0 perf0, GXPerf1 perf1) {
|
||||
switch (__GXData->perf0) {
|
||||
case GX_PERF0_VERTICES:
|
||||
case GX_PERF0_CLIP_VTX:
|
||||
case GX_PERF0_CLIP_CLKS:
|
||||
case GX_PERF0_XF_WAIT_IN:
|
||||
case GX_PERF0_XF_WAIT_OUT:
|
||||
case GX_PERF0_XF_XFRM_CLKS:
|
||||
case GX_PERF0_XF_LIT_CLKS:
|
||||
case GX_PERF0_XF_BOT_CLKS:
|
||||
case GX_PERF0_XF_REGLD_CLKS:
|
||||
case GX_PERF0_XF_REGRD_CLKS:
|
||||
case GX_PERF0_CLIP_RATIO:
|
||||
case GX_PERF0_CLOCKS:
|
||||
GX_WRITE_U8(0x10);
|
||||
GX_WRITE_U32(0x1006);
|
||||
GX_WRITE_U32(0);
|
||||
break;
|
||||
|
||||
case GX_PERF0_TRIANGLES:
|
||||
case GX_PERF0_TRIANGLES_CULLED:
|
||||
case GX_PERF0_TRIANGLES_PASSED:
|
||||
case GX_PERF0_TRIANGLES_SCISSORED:
|
||||
case GX_PERF0_TRIANGLES_0TEX:
|
||||
case GX_PERF0_TRIANGLES_1TEX:
|
||||
case GX_PERF0_TRIANGLES_2TEX:
|
||||
case GX_PERF0_TRIANGLES_3TEX:
|
||||
case GX_PERF0_TRIANGLES_4TEX:
|
||||
case GX_PERF0_TRIANGLES_5TEX:
|
||||
case GX_PERF0_TRIANGLES_6TEX:
|
||||
case GX_PERF0_TRIANGLES_7TEX:
|
||||
case GX_PERF0_TRIANGLES_8TEX:
|
||||
case GX_PERF0_TRIANGLES_0CLR:
|
||||
case GX_PERF0_TRIANGLES_1CLR:
|
||||
case GX_PERF0_TRIANGLES_2CLR:
|
||||
GX_WRITE_U8(0x61);
|
||||
GX_WRITE_U32(0x23000000);
|
||||
break;
|
||||
|
||||
case GX_PERF0_QUAD_0CVG:
|
||||
case GX_PERF0_QUAD_NON0CVG:
|
||||
case GX_PERF0_QUAD_1CVG:
|
||||
case GX_PERF0_QUAD_2CVG:
|
||||
case GX_PERF0_QUAD_3CVG:
|
||||
case GX_PERF0_QUAD_4CVG:
|
||||
case GX_PERF0_AVG_QUAD_CNT:
|
||||
GX_WRITE_U8(0x61);
|
||||
GX_WRITE_U32(0x24000000);
|
||||
break;
|
||||
|
||||
case GX_PERF0_NONE:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (__GXData->perf1) {
|
||||
case GX_PERF1_TEXELS:
|
||||
case GX_PERF1_TX_IDLE:
|
||||
case GX_PERF1_TX_REGS:
|
||||
case GX_PERF1_TX_MEMSTALL:
|
||||
case GX_PERF1_TC_CHECK1_2:
|
||||
case GX_PERF1_TC_CHECK3_4:
|
||||
case GX_PERF1_TC_CHECK5_6:
|
||||
case GX_PERF1_TC_CHECK7_8:
|
||||
case GX_PERF1_TC_MISS:
|
||||
case GX_PERF1_CLOCKS:
|
||||
GX_WRITE_U8(0x61);
|
||||
GX_WRITE_U32(0x67000000);
|
||||
break;
|
||||
|
||||
case GX_PERF1_VC_ELEMQ_FULL:
|
||||
case GX_PERF1_VC_MISSQ_FULL:
|
||||
case GX_PERF1_VC_MEMREQ_FULL:
|
||||
case GX_PERF1_VC_STATUS7:
|
||||
case GX_PERF1_VC_MISSREP_FULL:
|
||||
case GX_PERF1_VC_STREAMBUF_LOW:
|
||||
case GX_PERF1_VC_ALL_STALLS:
|
||||
case GX_PERF1_VERTICES:
|
||||
FAST_FLAG_SET(__GXData->perfSel, 0, 4, 4);
|
||||
GX_WRITE_U8(8);
|
||||
GX_WRITE_U8(32);
|
||||
GX_WRITE_U32(__GXData->perfSel);
|
||||
break;
|
||||
|
||||
case GX_PERF1_FIFO_REQ:
|
||||
case GX_PERF1_CALL_REQ:
|
||||
case GX_PERF1_VC_MISS_REQ:
|
||||
case GX_PERF1_CP_ALL_REQ:
|
||||
GX_SET_CP_REG(3, 0);
|
||||
break;
|
||||
|
||||
case GX_PERF1_NONE:
|
||||
break;
|
||||
}
|
||||
|
||||
__GXData->perf0 = perf0;
|
||||
|
||||
switch (__GXData->perf0) {
|
||||
case GX_PERF0_VERTICES:
|
||||
GX_WRITE_U8(0x10);
|
||||
GX_WRITE_U32(0x1006);
|
||||
GX_WRITE_U32(0x273);
|
||||
break;
|
||||
case GX_PERF0_CLIP_VTX:
|
||||
GX_WRITE_U8(0x10);
|
||||
GX_WRITE_U32(0x1006);
|
||||
GX_WRITE_U32(0x14A);
|
||||
break;
|
||||
case GX_PERF0_CLIP_CLKS:
|
||||
GX_WRITE_U8(0x10);
|
||||
GX_WRITE_U32(0x1006);
|
||||
GX_WRITE_U32(0x16B);
|
||||
break;
|
||||
case GX_PERF0_XF_WAIT_IN:
|
||||
GX_WRITE_U8(0x10);
|
||||
GX_WRITE_U32(0x1006);
|
||||
GX_WRITE_U32(0x84);
|
||||
break;
|
||||
case GX_PERF0_XF_WAIT_OUT:
|
||||
GX_WRITE_U8(0x10);
|
||||
GX_WRITE_U32(0x1006);
|
||||
GX_WRITE_U32(0xC6);
|
||||
break;
|
||||
case GX_PERF0_XF_XFRM_CLKS:
|
||||
GX_WRITE_U8(0x10);
|
||||
GX_WRITE_U32(0x1006);
|
||||
GX_WRITE_U32(0x210);
|
||||
break;
|
||||
case GX_PERF0_XF_LIT_CLKS:
|
||||
GX_WRITE_U8(0x10);
|
||||
GX_WRITE_U32(0x1006);
|
||||
GX_WRITE_U32(0x252);
|
||||
break;
|
||||
case GX_PERF0_XF_BOT_CLKS:
|
||||
GX_WRITE_U8(0x10);
|
||||
GX_WRITE_U32(0x1006);
|
||||
GX_WRITE_U32(0x231);
|
||||
break;
|
||||
case GX_PERF0_XF_REGLD_CLKS:
|
||||
GX_WRITE_U8(0x10);
|
||||
GX_WRITE_U32(0x1006);
|
||||
GX_WRITE_U32(0x1AD);
|
||||
break;
|
||||
case GX_PERF0_XF_REGRD_CLKS:
|
||||
GX_WRITE_U8(0x10);
|
||||
GX_WRITE_U32(0x1006);
|
||||
GX_WRITE_U32(0x1CE);
|
||||
break;
|
||||
case GX_PERF0_CLOCKS:
|
||||
GX_WRITE_U8(0x10);
|
||||
GX_WRITE_U32(0x1006);
|
||||
GX_WRITE_U32(0x21);
|
||||
break;
|
||||
case GX_PERF0_CLIP_RATIO:
|
||||
GX_WRITE_U8(0x10);
|
||||
GX_WRITE_U32(0x1006);
|
||||
GX_WRITE_U32(0x153);
|
||||
break;
|
||||
|
||||
case GX_PERF0_TRIANGLES:
|
||||
GX_WRITE_U8(0x61);
|
||||
GX_WRITE_U32(0x2300AE7F);
|
||||
break;
|
||||
case GX_PERF0_TRIANGLES_CULLED:
|
||||
GX_WRITE_U8(0x61);
|
||||
GX_WRITE_U32(0x23008E7F);
|
||||
break;
|
||||
case GX_PERF0_TRIANGLES_PASSED:
|
||||
GX_WRITE_U8(0x61);
|
||||
GX_WRITE_U32(0x23009E7F);
|
||||
break;
|
||||
case GX_PERF0_TRIANGLES_SCISSORED:
|
||||
GX_WRITE_U8(0x61);
|
||||
GX_WRITE_U32(0x23001E7F);
|
||||
break;
|
||||
case GX_PERF0_TRIANGLES_0TEX:
|
||||
GX_WRITE_U8(0x61);
|
||||
GX_WRITE_U32(0x2300AC3F);
|
||||
break;
|
||||
case GX_PERF0_TRIANGLES_1TEX:
|
||||
GX_WRITE_U8(0x61);
|
||||
GX_WRITE_U32(0x2300AC7F);
|
||||
break;
|
||||
case GX_PERF0_TRIANGLES_2TEX:
|
||||
GX_WRITE_U8(0x61);
|
||||
GX_WRITE_U32(0x2300ACBF);
|
||||
break;
|
||||
case GX_PERF0_TRIANGLES_3TEX:
|
||||
GX_WRITE_U8(0x61);
|
||||
GX_WRITE_U32(0x2300ACFF);
|
||||
break;
|
||||
case GX_PERF0_TRIANGLES_4TEX:
|
||||
GX_WRITE_U8(0x61);
|
||||
GX_WRITE_U32(0x2300AD3F);
|
||||
break;
|
||||
case GX_PERF0_TRIANGLES_5TEX:
|
||||
GX_WRITE_U8(0x61);
|
||||
GX_WRITE_U32(0x2300AD7F);
|
||||
break;
|
||||
case GX_PERF0_TRIANGLES_6TEX:
|
||||
GX_WRITE_U8(0x61);
|
||||
GX_WRITE_U32(0x2300ADBF);
|
||||
break;
|
||||
case GX_PERF0_TRIANGLES_7TEX:
|
||||
GX_WRITE_U8(0x61);
|
||||
GX_WRITE_U32(0x2300ADFF);
|
||||
break;
|
||||
case GX_PERF0_TRIANGLES_8TEX:
|
||||
GX_WRITE_U8(0x61);
|
||||
GX_WRITE_U32(0x2300AE3F);
|
||||
break;
|
||||
case GX_PERF0_TRIANGLES_0CLR:
|
||||
GX_WRITE_U8(0x61);
|
||||
GX_WRITE_U32(0x2300A27F);
|
||||
break;
|
||||
case GX_PERF0_TRIANGLES_1CLR:
|
||||
GX_WRITE_U8(0x61);
|
||||
GX_WRITE_U32(0x2300A67F);
|
||||
break;
|
||||
case GX_PERF0_TRIANGLES_2CLR:
|
||||
GX_WRITE_U8(0x61);
|
||||
GX_WRITE_U32(0x2300AA7F);
|
||||
break;
|
||||
|
||||
case GX_PERF0_QUAD_0CVG:
|
||||
GX_WRITE_U8(0x61);
|
||||
GX_WRITE_U32(0x2402C0C6);
|
||||
break;
|
||||
case GX_PERF0_QUAD_NON0CVG:
|
||||
GX_WRITE_U8(0x61);
|
||||
GX_WRITE_U32(0x2402C16B);
|
||||
break;
|
||||
case GX_PERF0_QUAD_1CVG:
|
||||
GX_WRITE_U8(0x61);
|
||||
GX_WRITE_U32(0x2402C0E7);
|
||||
break;
|
||||
case GX_PERF0_QUAD_2CVG:
|
||||
GX_WRITE_U8(0x61);
|
||||
GX_WRITE_U32(0x2402C108);
|
||||
break;
|
||||
case GX_PERF0_QUAD_3CVG:
|
||||
GX_WRITE_U8(0x61);
|
||||
GX_WRITE_U32(0x2402C129);
|
||||
break;
|
||||
case GX_PERF0_QUAD_4CVG:
|
||||
GX_WRITE_U8(0x61);
|
||||
GX_WRITE_U32(0x2402C14A);
|
||||
break;
|
||||
case GX_PERF0_AVG_QUAD_CNT:
|
||||
GX_WRITE_U8(0x61);
|
||||
GX_WRITE_U32(0x2402C1AD);
|
||||
break;
|
||||
|
||||
case GX_PERF0_NONE:
|
||||
break;
|
||||
}
|
||||
|
||||
__GXData->perf1 = perf1;
|
||||
|
||||
switch (__GXData->perf1) {
|
||||
case GX_PERF1_TEXELS:
|
||||
GX_WRITE_U8(0x61);
|
||||
GX_WRITE_U32(0x67000042);
|
||||
break;
|
||||
case GX_PERF1_TX_IDLE:
|
||||
GX_WRITE_U8(0x61);
|
||||
GX_WRITE_U32(0x67000084);
|
||||
break;
|
||||
case GX_PERF1_TX_REGS:
|
||||
GX_WRITE_U8(0x61);
|
||||
GX_WRITE_U32(0x67000063);
|
||||
break;
|
||||
case GX_PERF1_TX_MEMSTALL:
|
||||
GX_WRITE_U8(0x61);
|
||||
GX_WRITE_U32(0x67000129);
|
||||
break;
|
||||
case GX_PERF1_TC_MISS:
|
||||
GX_WRITE_U8(0x61);
|
||||
GX_WRITE_U32(0x67000252);
|
||||
break;
|
||||
case GX_PERF1_CLOCKS:
|
||||
GX_WRITE_U8(0x61);
|
||||
GX_WRITE_U32(0x67000021);
|
||||
break;
|
||||
case GX_PERF1_TC_CHECK1_2:
|
||||
GX_WRITE_U8(0x61);
|
||||
GX_WRITE_U32(0x6700014B);
|
||||
break;
|
||||
case GX_PERF1_TC_CHECK3_4:
|
||||
GX_WRITE_U8(0x61);
|
||||
GX_WRITE_U32(0x6700018D);
|
||||
break;
|
||||
case GX_PERF1_TC_CHECK5_6:
|
||||
GX_WRITE_U8(0x61);
|
||||
GX_WRITE_U32(0x670001CF);
|
||||
break;
|
||||
case GX_PERF1_TC_CHECK7_8:
|
||||
GX_WRITE_U8(0x61);
|
||||
GX_WRITE_U32(0x67000211);
|
||||
break;
|
||||
|
||||
case GX_PERF1_VC_ELEMQ_FULL:
|
||||
FAST_FLAG_SET(__GXData->perfSel, 2, 4, 4);
|
||||
GX_WRITE_U8(8);
|
||||
GX_WRITE_U8(32);
|
||||
GX_WRITE_U32(__GXData->perfSel);
|
||||
break;
|
||||
case GX_PERF1_VC_MISSQ_FULL:
|
||||
FAST_FLAG_SET(__GXData->perfSel, 3, 4, 4);
|
||||
GX_WRITE_U8(8);
|
||||
GX_WRITE_U8(32);
|
||||
GX_WRITE_U32(__GXData->perfSel);
|
||||
break;
|
||||
case GX_PERF1_VC_MEMREQ_FULL:
|
||||
FAST_FLAG_SET(__GXData->perfSel, 4, 4, 4);
|
||||
GX_WRITE_U8(8);
|
||||
GX_WRITE_U8(32);
|
||||
GX_WRITE_U32(__GXData->perfSel);
|
||||
break;
|
||||
case GX_PERF1_VC_STATUS7:
|
||||
FAST_FLAG_SET(__GXData->perfSel, 5, 4, 4);
|
||||
GX_WRITE_U8(8);
|
||||
GX_WRITE_U8(32);
|
||||
GX_WRITE_U32(__GXData->perfSel);
|
||||
break;
|
||||
case GX_PERF1_VC_MISSREP_FULL:
|
||||
FAST_FLAG_SET(__GXData->perfSel, 6, 4, 4);
|
||||
GX_WRITE_U8(8);
|
||||
GX_WRITE_U8(32);
|
||||
GX_WRITE_U32(__GXData->perfSel);
|
||||
break;
|
||||
case GX_PERF1_VC_STREAMBUF_LOW:
|
||||
FAST_FLAG_SET(__GXData->perfSel, 7, 4, 4);
|
||||
GX_WRITE_U8(8);
|
||||
GX_WRITE_U8(32);
|
||||
GX_WRITE_U32(__GXData->perfSel);
|
||||
break;
|
||||
case GX_PERF1_VC_ALL_STALLS:
|
||||
FAST_FLAG_SET(__GXData->perfSel, 9, 4, 4);
|
||||
GX_WRITE_U8(8);
|
||||
GX_WRITE_U8(32);
|
||||
GX_WRITE_U32(__GXData->perfSel);
|
||||
break;
|
||||
case GX_PERF1_VERTICES:
|
||||
FAST_FLAG_SET(__GXData->perfSel, 8, 4, 4);
|
||||
GX_WRITE_U8(8);
|
||||
GX_WRITE_U8(32);
|
||||
GX_WRITE_U32(__GXData->perfSel);
|
||||
break;
|
||||
|
||||
case GX_PERF1_FIFO_REQ:
|
||||
GX_SET_CP_REG(3, 2);
|
||||
break;
|
||||
case GX_PERF1_CALL_REQ:
|
||||
GX_SET_CP_REG(3, 3);
|
||||
break;
|
||||
case GX_PERF1_VC_MISS_REQ:
|
||||
GX_SET_CP_REG(3, 4);
|
||||
break;
|
||||
case GX_PERF1_CP_ALL_REQ:
|
||||
GX_SET_CP_REG(3, 5);
|
||||
break;
|
||||
|
||||
case GX_PERF1_NONE:
|
||||
break;
|
||||
}
|
||||
|
||||
__GXData->bpSentNot = GX_FALSE;
|
||||
}
|
||||
|
||||
void GXClearGPMetric(void) {
|
||||
GX_SET_CP_REG(2, 4);
|
||||
}
|
||||
|
||||
#pragma scheduling off
|
||||
void GXReadXfRasMetric(u32* xfWaitIn, u32* xfWaitOut, u32* rasBusy, u32* clocks) {
|
||||
*rasBusy = GXReadCPReg(32, 33);
|
||||
*clocks = GXReadCPReg(34, 35);
|
||||
*xfWaitIn = GXReadCPReg(36, 37);
|
||||
*xfWaitOut = GXReadCPReg(38, 39);
|
||||
}
|
||||
#pragma scheduling reset
|
235
src/dolphin/gx/GXPixel.c
Normal file
235
src/dolphin/gx/GXPixel.c
Normal file
@ -0,0 +1,235 @@
|
||||
#include "dolphin/gx/GXPixel.h"
|
||||
#include "dolphin/gx/GX.h"
|
||||
|
||||
void GXSetFog(GXFogType type, f32 startz, f32 endz, f32 nearz, f32 farz, GXColor color) {
|
||||
f32 a, c;
|
||||
u32 a_bits, c_bits;
|
||||
|
||||
u32 fogColorReg = 0;
|
||||
u32 fogParamReg0 = 0;
|
||||
u32 fogParamReg1 = 0;
|
||||
u32 fogParamReg2 = 0;
|
||||
u32 fogParamReg3 = 0;
|
||||
|
||||
u32 fsel = type & 7;
|
||||
BOOL isOrtho = (type >> 3) & 1;
|
||||
u32 col;
|
||||
|
||||
if (isOrtho) {
|
||||
if (farz == nearz || endz == startz) {
|
||||
a = 0.0f;
|
||||
c = 0.0f;
|
||||
} else {
|
||||
a = (1.0f / (endz - startz)) * (farz - nearz);
|
||||
c = (1.0f / (endz - startz)) * (startz - nearz);
|
||||
}
|
||||
} else {
|
||||
f32 tmpA, tmpB, tmpC;
|
||||
u32 expB, magB, shiftB;
|
||||
|
||||
if (farz == nearz || endz == startz) {
|
||||
tmpA = 0.0f;
|
||||
tmpB = 0.5f;
|
||||
tmpC = 0.0f;
|
||||
} else {
|
||||
tmpA = (farz * nearz) / ((farz - nearz) * (endz - startz));
|
||||
tmpB = farz / (farz - nearz);
|
||||
tmpC = startz / (endz - startz);
|
||||
}
|
||||
|
||||
expB = 0;
|
||||
while (tmpB > 1.0) {
|
||||
tmpB /= 2.0f;
|
||||
expB++;
|
||||
}
|
||||
while (tmpB > 0.0f && tmpB < 0.5) {
|
||||
tmpB *= 2.0f;
|
||||
expB--;
|
||||
}
|
||||
|
||||
a = tmpA / (1 << expB + 1);
|
||||
magB = 8388638.0f * tmpB;
|
||||
shiftB = expB + 1;
|
||||
c = tmpC;
|
||||
|
||||
GX_SET_REG(fogParamReg1, magB, GX_BP_FOGPARAM1_B_MAG_ST, GX_BP_FOGPARAM1_B_MAG_END);
|
||||
GX_SET_REG(fogParamReg2, shiftB, GX_BP_FOGPARAM2_B_SHIFT_ST, GX_BP_FOGPARAM2_B_SHIFT_END);
|
||||
|
||||
GX_SET_REG(fogParamReg1, GX_BP_REG_FOGPARAM1, 0, 7);
|
||||
GX_SET_REG(fogParamReg2, GX_BP_REG_FOGPARAM2, 0, 7);
|
||||
}
|
||||
|
||||
a_bits = *(u32*)&a;
|
||||
c_bits = *(u32*)&c;
|
||||
|
||||
GX_SET_REG(fogParamReg0, a_bits >> 12, GX_BP_FOGPARAM0_A_MANT_ST, GX_BP_FOGPARAM0_A_MANT_END);
|
||||
GX_SET_REG(fogParamReg0, a_bits >> 23, GX_BP_FOGPARAM0_A_EXP_ST, GX_BP_FOGPARAM0_A_EXP_END);
|
||||
GX_SET_REG(fogParamReg0, a_bits >> 31, GX_BP_FOGPARAM0_A_SIGN_ST, GX_BP_FOGPARAM0_A_SIGN_END);
|
||||
GX_SET_REG(fogParamReg0, GX_BP_REG_FOGPARAM0, 0, 7);
|
||||
|
||||
GX_SET_REG(fogParamReg3, c_bits >> 12, GX_BP_FOGPARAM3_C_MANT_ST, GX_BP_FOGPARAM3_C_MANT_END);
|
||||
GX_SET_REG(fogParamReg3, c_bits >> 23, GX_BP_FOGPARAM3_C_EXP_ST, GX_BP_FOGPARAM3_C_EXP_END);
|
||||
GX_SET_REG(fogParamReg3, c_bits >> 31, GX_BP_FOGPARAM3_C_SIGN_ST, GX_BP_FOGPARAM3_C_SIGN_END);
|
||||
GX_SET_REG(fogParamReg3, isOrtho, GX_BP_FOGPARAM3_PROJ_ST, GX_BP_FOGPARAM3_PROJ_END);
|
||||
GX_SET_REG(fogParamReg3, fsel, GX_BP_FOGPARAM3_FSEL_ST, GX_BP_FOGPARAM3_FSEL_END);
|
||||
GX_SET_REG(fogParamReg3, GX_BP_REG_FOGPARAM3, 0, 7);
|
||||
|
||||
col = *(u32*)&color;
|
||||
GX_SET_REG(fogColorReg, col >> 8, GX_BP_FOGCOLOR_RGB_ST, GX_BP_FOGCOLOR_RGB_END);
|
||||
GX_SET_REG(fogColorReg, GX_BP_REG_FOGCOLOR, 0, 7);
|
||||
|
||||
GX_BP_LOAD_REG(fogParamReg0);
|
||||
GX_BP_LOAD_REG(fogParamReg1);
|
||||
GX_BP_LOAD_REG(fogParamReg2);
|
||||
GX_BP_LOAD_REG(fogParamReg3);
|
||||
GX_BP_LOAD_REG(fogColorReg);
|
||||
|
||||
__GXData->bpSentNot = GX_FALSE;
|
||||
}
|
||||
|
||||
void GXSetFogRangeAdj(GXBool enable, u16 center, GXFogAdjTable* table) {
|
||||
u32 fogRangeReg;
|
||||
u32 fogRangeRegK;
|
||||
u32 i;
|
||||
|
||||
if (enable) {
|
||||
for (i = 0; i < 10; i += 2) {
|
||||
fogRangeRegK = 0;
|
||||
GX_SET_REG(fogRangeRegK, table->fogVals[i], GX_BP_FOGRANGEK_HI_ST,
|
||||
GX_BP_FOGRANGEK_HI_END);
|
||||
GX_SET_REG(fogRangeRegK, table->fogVals[i + 1], GX_BP_FOGRANGEK_LO_ST,
|
||||
GX_BP_FOGRANGEK_LO_END);
|
||||
GX_SET_REG(fogRangeRegK, GX_BP_REG_FOGRANGEK0 + (i / 2), 0, 7);
|
||||
GX_BP_LOAD_REG(fogRangeRegK);
|
||||
}
|
||||
}
|
||||
|
||||
fogRangeReg = 0;
|
||||
GX_SET_REG(fogRangeReg, center + 342, GX_BP_FOGRANGE_CENTER_ST, GX_BP_FOGRANGE_CENTER_END);
|
||||
GX_SET_REG(fogRangeReg, enable, GX_BP_FOGRANGE_ENABLED_ST, GX_BP_FOGRANGE_ENABLED_END);
|
||||
GX_SET_REG(fogRangeReg, GX_BP_REG_FOGRANGE, 0, 7);
|
||||
GX_BP_LOAD_REG(fogRangeReg);
|
||||
|
||||
__GXData->bpSentNot = GX_FALSE;
|
||||
}
|
||||
|
||||
void GXSetBlendMode(GXBlendMode type, GXBlendFactor src_factor, GXBlendFactor dst_factor,
|
||||
GXLogicOp op) {
|
||||
u32 blendModeReg = __GXData->cmode0;
|
||||
GX_SET_REG(blendModeReg, type == GX_BM_SUBTRACT, GX_BP_BLENDMODE_SUBTRACT_ST,
|
||||
GX_BP_BLENDMODE_SUBTRACT_END);
|
||||
GX_SET_REG(blendModeReg, type, GX_BP_BLENDMODE_ENABLE_ST, GX_BP_BLENDMODE_ENABLE_END);
|
||||
GX_SET_REG(blendModeReg, type == GX_BM_LOGIC, GX_BP_BLENDMODE_LOGIC_OP_ST,
|
||||
GX_BP_BLENDMODE_LOGIC_OP_END);
|
||||
GX_SET_REG(blendModeReg, op, GX_BP_BLENDMODE_LOGICMODE_ST, GX_BP_BLENDMODE_LOGICMODE_END);
|
||||
GX_SET_REG(blendModeReg, src_factor, GX_BP_BLENDMODE_SRCFACTOR_ST,
|
||||
GX_BP_BLENDMODE_SRCFACTOR_END);
|
||||
GX_SET_REG(blendModeReg, dst_factor, GX_BP_BLENDMODE_DSTFACTOR_ST,
|
||||
GX_BP_BLENDMODE_DSTFACTOR_END);
|
||||
|
||||
GX_BP_LOAD_REG(blendModeReg);
|
||||
__GXData->cmode0 = blendModeReg;
|
||||
|
||||
__GXData->bpSentNot = FALSE;
|
||||
}
|
||||
|
||||
void GXSetColorUpdate(GXBool updateEnable) {
|
||||
u32 blendModeReg = __GXData->cmode0;
|
||||
GX_SET_REG(blendModeReg, updateEnable, GX_BP_BLENDMODE_COLOR_UPDATE_ST,
|
||||
GX_BP_BLENDMODE_COLOR_UPDATE_END);
|
||||
GX_BP_LOAD_REG(blendModeReg);
|
||||
__GXData->cmode0 = blendModeReg;
|
||||
__GXData->bpSentNot = GX_FALSE;
|
||||
}
|
||||
|
||||
void GXSetAlphaUpdate(GXBool updateEnable) {
|
||||
u32 blendModeReg = __GXData->cmode0;
|
||||
GX_SET_REG(blendModeReg, updateEnable, GX_BP_BLENDMODE_ALPHA_UPDATE_ST,
|
||||
GX_BP_BLENDMODE_ALPHA_UPDATE_END);
|
||||
GX_BP_LOAD_REG(blendModeReg);
|
||||
__GXData->cmode0 = blendModeReg;
|
||||
__GXData->bpSentNot = GX_FALSE;
|
||||
}
|
||||
|
||||
void GXSetZMode(GXBool compareEnable, GXCompare func, GXBool updateEnable) {
|
||||
u32 zModeReg = __GXData->zmode;
|
||||
GX_SET_REG(zModeReg, compareEnable, GX_BP_ZMODE_TEST_ENABLE_ST, GX_BP_ZMODE_TEST_ENABLE_END);
|
||||
GX_SET_REG(zModeReg, func, GX_BP_ZMODE_COMPARE_ST, GX_BP_ZMODE_COMPARE_END);
|
||||
GX_SET_REG(zModeReg, updateEnable, GX_BP_ZMODE_UPDATE_ENABLE_ST, GX_BP_ZMODE_UPDATE_ENABLE_END);
|
||||
GX_BP_LOAD_REG(zModeReg);
|
||||
__GXData->zmode = zModeReg;
|
||||
__GXData->bpSentNot = GX_FALSE;
|
||||
}
|
||||
|
||||
void GXSetZCompLoc(GXBool beforeTex) {
|
||||
GX_SET_REG(__GXData->peCtrl, beforeTex, GX_BP_ZCONTROL_BEFORE_TEX_ST,
|
||||
GX_BP_ZCONTROL_BEFORE_TEX_END);
|
||||
GX_BP_LOAD_REG(__GXData->peCtrl);
|
||||
__GXData->bpSentNot = GX_FALSE;
|
||||
}
|
||||
|
||||
void GXSetPixelFmt(GXPixelFmt pixelFmt, GXZFmt16 zFmt) {
|
||||
GXBool isZ16;
|
||||
static u32 p2f[GX_PF_MAX] = {GX_PF_RGB8_Z24, GX_PF_RGBA6_Z24, GX_PF_RGB565_Z16, GX_PF_Z24,
|
||||
GX_PF_Y8, GX_PF_Y8, GX_PF_Y8, GX_PF_U8};
|
||||
|
||||
const u32 zControlRegOld = __GXData->peCtrl;
|
||||
|
||||
GX_SET_REG(__GXData->peCtrl, p2f[pixelFmt], GX_BP_ZCONTROL_PIXEL_FMT_ST,
|
||||
GX_BP_ZCONTROL_PIXEL_FMT_END);
|
||||
GX_SET_REG(__GXData->peCtrl, zFmt, GX_BP_ZCONTROL_Z_FMT_ST, GX_BP_ZCONTROL_Z_FMT_END);
|
||||
|
||||
if (zControlRegOld != __GXData->peCtrl) {
|
||||
GX_BP_LOAD_REG(__GXData->peCtrl);
|
||||
isZ16 = (pixelFmt == GX_PF_RGB565_Z16) ? GX_TRUE : GX_FALSE;
|
||||
GX_SET_REG(__GXData->genMode, isZ16, GX_BP_GENMODE_MULTISAMPLE_ST,
|
||||
GX_BP_GENMODE_MULTISAMPLE_END);
|
||||
__GXData->dirtyState |= GX_DIRTY_GEN_MODE;
|
||||
}
|
||||
|
||||
if (p2f[pixelFmt] == GX_PF_Y8) {
|
||||
GX_SET_REG(__GXData->cmode1, pixelFmt - GX_PF_Y8, GX_BP_DSTALPHA_YUV_FMT_ST,
|
||||
GX_BP_DSTALPHA_YUV_FMT_END);
|
||||
GX_SET_REG(__GXData->cmode1, GX_BP_REG_DSTALPHA, 0, 7);
|
||||
GX_BP_LOAD_REG(__GXData->cmode1);
|
||||
}
|
||||
|
||||
__GXData->bpSentNot = FALSE;
|
||||
}
|
||||
|
||||
void GXSetDither(GXBool dither) {
|
||||
u32 blendModeReg = __GXData->cmode0;
|
||||
GX_SET_REG(blendModeReg, dither, GX_BP_BLENDMODE_DITHER_ST, GX_BP_BLENDMODE_DITHER_END);
|
||||
GX_BP_LOAD_REG(blendModeReg);
|
||||
__GXData->cmode0 = blendModeReg;
|
||||
__GXData->bpSentNot = GX_FALSE;
|
||||
}
|
||||
|
||||
void GXSetDstAlpha(GXBool enable, u8 alpha) {
|
||||
u32 dstAlpha = __GXData->cmode1;
|
||||
GX_SET_REG(dstAlpha, alpha, GX_BP_DSTALPHA_ALPHA_ST, GX_BP_DSTALPHA_ALPHA_END);
|
||||
GX_SET_REG(dstAlpha, enable, GX_BP_DSTALPHA_ENABLE_ST, GX_BP_DSTALPHA_ENABLE_END);
|
||||
GX_BP_LOAD_REG(dstAlpha);
|
||||
__GXData->cmode1 = dstAlpha;
|
||||
__GXData->bpSentNot = GX_FALSE;
|
||||
}
|
||||
|
||||
void GXSetFieldMask(GXBool enableEven, GXBool enableOdd) {
|
||||
u32 fieldMaskReg = 0;
|
||||
GX_SET_REG(fieldMaskReg, enableOdd, GX_BP_FIELDMASK_ODD_ST, GX_BP_FIELDMASK_ODD_END);
|
||||
GX_SET_REG(fieldMaskReg, enableEven, GX_BP_FIELDMASK_EVEN_ST, GX_BP_FIELDMASK_EVEN_END);
|
||||
GX_SET_REG(fieldMaskReg, GX_BP_REG_FIELDMASK, 0, 7);
|
||||
|
||||
GX_BP_LOAD_REG(fieldMaskReg);
|
||||
__GXData->bpSentNot = GX_FALSE;
|
||||
}
|
||||
|
||||
void GXSetFieldMode(GXBool texLOD, GXBool adjustAR) {
|
||||
GX_SET_REG(__GXData->lpSize, adjustAR, GX_BP_LINEPTWIDTH_ADJUST_ST,
|
||||
GX_BP_LINEPTWIDTH_ADJUST_END);
|
||||
GX_BP_LOAD_REG(__GXData->lpSize);
|
||||
|
||||
__GXFlushTextureState();
|
||||
GX_BP_LOAD_REG(GX_BP_REG_FIELDMODE << 24 | texLOD);
|
||||
__GXFlushTextureState();
|
||||
}
|
366
src/dolphin/gx/GXTev.c
Normal file
366
src/dolphin/gx/GXTev.c
Normal file
@ -0,0 +1,366 @@
|
||||
#include "dolphin/gx/GXTev.h"
|
||||
#include "dolphin/gx/GX.h"
|
||||
|
||||
/* ############################################################################################## */
|
||||
static u32 TEVCOpTableST0[] = {
|
||||
0xC008F8AF, // modulate
|
||||
0xC008A89F, // decal
|
||||
0xC008AC8F, // blend
|
||||
0xC008FFF8, // replace
|
||||
0xC008FFFA, // passclr
|
||||
};
|
||||
|
||||
static u32 TEVCOpTableST1[] = {
|
||||
0xC008F80F, // modulate
|
||||
0xC008089F, // decal
|
||||
0xC0080C8F, // blend
|
||||
0xC008FFF8, // replace
|
||||
0xC008FFF0, // passclr
|
||||
};
|
||||
|
||||
static u32 TEVAOpTableST0[] = {
|
||||
0xC108F2F0, // modulate
|
||||
0xC108FFD0, // decal
|
||||
0xC108F2F0, // blend
|
||||
0xC108FFC0, // replace
|
||||
0xC108FFD0, // passclr
|
||||
};
|
||||
|
||||
static u32 TEVAOpTableST1[] = {
|
||||
0xC108F070, // modulate
|
||||
0xC108FF80, // decal
|
||||
0xC108F070, // blend
|
||||
0xC108FFC0, // replace
|
||||
0xC108FF80, // passclr
|
||||
};
|
||||
|
||||
void GXSetTevOp(GXTevStageID stage, GXTevMode mode) {
|
||||
u32* color;
|
||||
u32* alpha;
|
||||
u32 tevReg;
|
||||
|
||||
if (stage == GX_TEVSTAGE0) {
|
||||
color = &TEVCOpTableST0[mode];
|
||||
alpha = &TEVAOpTableST0[mode];
|
||||
} else {
|
||||
color = &TEVCOpTableST1[mode];
|
||||
alpha = &TEVAOpTableST1[mode];
|
||||
}
|
||||
|
||||
tevReg = __GXData->tevc[stage];
|
||||
tevReg = (*color & ~0xFF000000) | (tevReg & 0xFF000000);
|
||||
|
||||
GX_WRITE_U8(0x61);
|
||||
GX_WRITE_U32(tevReg);
|
||||
|
||||
__GXData->tevc[stage] = tevReg;
|
||||
|
||||
tevReg = __GXData->teva[stage];
|
||||
tevReg = (*alpha & ~0xFF00000F) | (tevReg & 0xFF00000F);
|
||||
|
||||
GX_WRITE_U8(0x61);
|
||||
GX_WRITE_U32(tevReg);
|
||||
|
||||
__GXData->teva[stage] = tevReg;
|
||||
|
||||
__GXData->bpSentNot = GX_FALSE;
|
||||
}
|
||||
|
||||
void GXSetTevColorIn(GXTevStageID stage, GXTevColorArg a, GXTevColorArg b, GXTevColorArg c,
|
||||
GXTevColorArg d) {
|
||||
u32 tevReg;
|
||||
|
||||
tevReg = __GXData->tevc[stage];
|
||||
|
||||
FAST_FLAG_SET(tevReg, a, 12, 4);
|
||||
FAST_FLAG_SET(tevReg, b, 8, 4);
|
||||
FAST_FLAG_SET(tevReg, c, 4, 4);
|
||||
FAST_FLAG_SET(tevReg, d, 0, 4);
|
||||
|
||||
GX_WRITE_U8(0x61);
|
||||
GX_WRITE_U32(tevReg);
|
||||
|
||||
__GXData->tevc[stage] = tevReg;
|
||||
__GXData->bpSentNot = GX_FALSE;
|
||||
}
|
||||
|
||||
void GXSetTevAlphaIn(GXTevStageID stage, GXTevAlphaArg a, GXTevAlphaArg b, GXTevAlphaArg c,
|
||||
GXTevAlphaArg d) {
|
||||
u32 tevReg;
|
||||
|
||||
tevReg = __GXData->teva[stage];
|
||||
|
||||
FAST_FLAG_SET(tevReg, a, 13, 3);
|
||||
FAST_FLAG_SET(tevReg, b, 10, 3);
|
||||
FAST_FLAG_SET(tevReg, c, 7, 3);
|
||||
FAST_FLAG_SET(tevReg, d, 4, 3);
|
||||
|
||||
GX_WRITE_U8(0x61);
|
||||
GX_WRITE_U32(tevReg);
|
||||
|
||||
__GXData->teva[stage] = tevReg;
|
||||
__GXData->bpSentNot = GX_FALSE;
|
||||
}
|
||||
|
||||
void GXSetTevColorOp(GXTevStageID stage, GXTevOp op, GXTevBias bias, GXTevScale scale,
|
||||
GXBool doClamp, GXTevRegID outReg) {
|
||||
u32 tevReg;
|
||||
|
||||
tevReg = __GXData->tevc[stage];
|
||||
FAST_FLAG_SET(tevReg, op & 1, 18, 1);
|
||||
|
||||
if (op <= 1) {
|
||||
FAST_FLAG_SET(tevReg, scale, 20, 2);
|
||||
FAST_FLAG_SET(tevReg, bias, 16, 2);
|
||||
} else {
|
||||
FAST_FLAG_SET(tevReg, (op >> 1) & 3, 20, 2);
|
||||
FAST_FLAG_SET(tevReg, 3, 16, 2);
|
||||
}
|
||||
|
||||
FAST_FLAG_SET(tevReg, doClamp, 19, 1);
|
||||
FAST_FLAG_SET(tevReg, outReg, 22, 2);
|
||||
|
||||
GX_WRITE_U8(0x61);
|
||||
GX_WRITE_U32(tevReg);
|
||||
__GXData->tevc[stage] = tevReg;
|
||||
__GXData->bpSentNot = GX_FALSE;
|
||||
}
|
||||
|
||||
void GXSetTevAlphaOp(GXTevStageID stage, GXTevOp op, GXTevBias bias, GXTevScale scale,
|
||||
GXBool doClamp, GXTevRegID outReg) {
|
||||
u32 tevReg;
|
||||
|
||||
tevReg = __GXData->teva[stage];
|
||||
FAST_FLAG_SET(tevReg, op & 1, 18, 1);
|
||||
|
||||
if (op <= 1) {
|
||||
FAST_FLAG_SET(tevReg, scale, 20, 2);
|
||||
FAST_FLAG_SET(tevReg, bias, 16, 2);
|
||||
} else {
|
||||
FAST_FLAG_SET(tevReg, (op >> 1) & 3, 20, 2);
|
||||
FAST_FLAG_SET(tevReg, 3, 16, 2);
|
||||
}
|
||||
|
||||
FAST_FLAG_SET(tevReg, doClamp, 19, 1);
|
||||
FAST_FLAG_SET(tevReg, outReg, 22, 2);
|
||||
|
||||
GX_WRITE_U8(0x61);
|
||||
GX_WRITE_U32(tevReg);
|
||||
__GXData->teva[stage] = tevReg;
|
||||
__GXData->bpSentNot = GX_FALSE;
|
||||
}
|
||||
|
||||
void GXSetTevColor(GXTevRegID reg, GXColor color) {
|
||||
u32 col = *(u32*)&color;
|
||||
u32 ra = (0xE0 + reg * 2) << 24;
|
||||
u32 bg = (0xE1 + reg * 2) << 24;
|
||||
|
||||
GX_SET_REG(ra, col >> 24, 24, 31);
|
||||
GX_SET_REG(bg, col >> 8, 24, 31);
|
||||
GX_SET_REG(bg, col >> 16, 12, 19);
|
||||
GX_SET_REG(ra, col & 0xFF, 12, 19);
|
||||
|
||||
GX_BP_LOAD_REG(ra);
|
||||
GX_BP_LOAD_REG(bg);
|
||||
GX_BP_LOAD_REG(bg);
|
||||
GX_BP_LOAD_REG(bg);
|
||||
|
||||
__GXData->bpSentNot = GX_FALSE;
|
||||
}
|
||||
|
||||
void GXSetTevColorS10(GXTevRegID reg, GXColorS10 color) {
|
||||
u32 col = *(u32*)&color;
|
||||
u32 col1 = ((u32*)&color)[1];
|
||||
u32 ra = (0xE0 + reg * 2) << 24;
|
||||
u32 bg = (0xE1 + reg * 2) << 24;
|
||||
|
||||
GX_SET_REG(ra, col >> 16, 21, 31);
|
||||
GX_SET_REG(bg, col1 >> 16, 21, 31);
|
||||
GX_SET_REG(bg, col & 0x7FF, 9, 19);
|
||||
GX_SET_REG(ra, col1 & 0x7FF, 9, 19);
|
||||
|
||||
GX_BP_LOAD_REG(ra);
|
||||
GX_BP_LOAD_REG(bg);
|
||||
GX_BP_LOAD_REG(bg);
|
||||
GX_BP_LOAD_REG(bg);
|
||||
|
||||
__GXData->bpSentNot = GX_FALSE;
|
||||
}
|
||||
|
||||
void GXSetTevKColor(GXTevKColorID id, GXColor color) {
|
||||
u32 col = *(u32*)&color;
|
||||
u32 ra;
|
||||
u32 bg;
|
||||
|
||||
ra = (0xE0 + id * 2) << 24;
|
||||
GX_SET_REG(ra, col >> 24, 24, 31);
|
||||
GX_SET_REG(ra, col & 0xFF, 12, 19);
|
||||
GX_SET_REG(ra, 8, 8, 11);
|
||||
|
||||
bg = (0xE1 + id * 2) << 24;
|
||||
GX_SET_REG(bg, col >> 8, 24, 31);
|
||||
GX_SET_REG(bg, col >> 16, 12, 19);
|
||||
GX_SET_REG(bg, 8, 8, 11);
|
||||
|
||||
GX_BP_LOAD_REG(ra);
|
||||
GX_BP_LOAD_REG(bg);
|
||||
|
||||
__GXData->bpSentNot = GX_FALSE;
|
||||
}
|
||||
|
||||
void GXSetTevKColorSel(GXTevStageID stage, GXTevKColorSel sel) {
|
||||
u32* reg;
|
||||
|
||||
reg = &__GXData->tevKsel[stage >> 1];
|
||||
|
||||
if (stage & 1) {
|
||||
GX_SET_REG(*reg, sel, 13, 17);
|
||||
} else {
|
||||
GX_SET_REG(*reg, sel, 23, 27);
|
||||
}
|
||||
|
||||
GX_BP_LOAD_REG(*reg);
|
||||
|
||||
__GXData->bpSentNot = GX_FALSE;
|
||||
}
|
||||
|
||||
void GXSetTevKAlphaSel(GXTevStageID stage, GXTevKAlphaSel sel) {
|
||||
u32* reg;
|
||||
|
||||
reg = &__GXData->tevKsel[stage >> 1];
|
||||
|
||||
if (stage & 1) {
|
||||
GX_SET_REG(*reg, sel, 8, 12);
|
||||
} else {
|
||||
GX_SET_REG(*reg, sel, 18, 22);
|
||||
}
|
||||
|
||||
GX_BP_LOAD_REG(*reg);
|
||||
|
||||
__GXData->bpSentNot = GX_FALSE;
|
||||
}
|
||||
|
||||
void GXSetTevSwapMode(GXTevStageID stage, GXTevSwapSel rasSel, GXTevSwapSel texSel) {
|
||||
u32* reg = &__GXData->teva[stage];
|
||||
GX_SET_REG(*reg, rasSel, 30, 31);
|
||||
GX_SET_REG(*reg, texSel, 28, 29);
|
||||
|
||||
GX_BP_LOAD_REG(*reg);
|
||||
|
||||
__GXData->bpSentNot = GX_FALSE;
|
||||
}
|
||||
|
||||
void GXSetTevSwapModeTable(GXTevSwapSel table, GXTevColorChan red, GXTevColorChan green,
|
||||
GXTevColorChan blue, GXTevColorChan alpha) {
|
||||
u32* reg;
|
||||
|
||||
reg = &__GXData->tevKsel[table << 1];
|
||||
GX_SET_REG(*reg, red, 30, 31);
|
||||
GX_SET_REG(*reg, green, 28, 29);
|
||||
|
||||
GX_BP_LOAD_REG(*reg);
|
||||
|
||||
reg = &__GXData->tevKsel[(table << 1) + 1];
|
||||
GX_SET_REG(*reg, blue, 30, 31);
|
||||
GX_SET_REG(*reg, alpha, 28, 29);
|
||||
|
||||
GX_BP_LOAD_REG(*reg);
|
||||
|
||||
__GXData->bpSentNot = GX_FALSE;
|
||||
}
|
||||
|
||||
void GXSetAlphaCompare(GXCompare comp0, u8 ref0, GXAlphaOp op, GXCompare comp1, u8 ref1) {
|
||||
u32 reg = 0xF3000000;
|
||||
|
||||
GX_SET_REG(reg, ref0, 24, 31);
|
||||
GX_SET_REG(reg, ref1, 16, 23);
|
||||
GX_SET_REG(reg, comp0, 13, 15);
|
||||
GX_SET_REG(reg, comp1, 10, 12);
|
||||
GX_SET_REG(reg, op, 8, 9);
|
||||
|
||||
GX_BP_LOAD_REG(reg);
|
||||
|
||||
__GXData->bpSentNot = GX_FALSE;
|
||||
}
|
||||
|
||||
void GXSetZTexture(GXZTexOp op, GXTexFmt format, u32 bias) {
|
||||
u32 val1;
|
||||
u32 val2;
|
||||
u32 val3;
|
||||
|
||||
val1 = 0;
|
||||
GX_SET_REG(val1, bias, 8, 31);
|
||||
GX_SET_REG(val1, 0xF4, 0, 7);
|
||||
|
||||
val2 = 0;
|
||||
switch (format) {
|
||||
case GX_TF_Z8:
|
||||
val3 = 0;
|
||||
break;
|
||||
case GX_TF_Z16:
|
||||
val3 = 1;
|
||||
break;
|
||||
case GX_TF_Z24X8:
|
||||
val3 = 2;
|
||||
break;
|
||||
default:
|
||||
val3 = 2;
|
||||
break;
|
||||
}
|
||||
|
||||
GX_SET_REG(val2, val3, 30, 31);
|
||||
GX_SET_REG(val2, op, 28, 29);
|
||||
GX_SET_REG(val2, 0xF5, 0, 7);
|
||||
|
||||
GX_BP_LOAD_REG(val1);
|
||||
|
||||
GX_BP_LOAD_REG(val2);
|
||||
|
||||
__GXData->bpSentNot = GX_FALSE;
|
||||
}
|
||||
|
||||
void GXSetTevOrder(GXTevStageID stage, GXTexCoordID coord, GXTexMapID map, GXChannelID color) {
|
||||
static int c2r[] = {0, 1, 0, 1, 0, 1, 7, 5, 6};
|
||||
|
||||
u32* reg;
|
||||
u32 tempMap;
|
||||
u32 tempCoord;
|
||||
|
||||
reg = &__GXData->tref[stage / 2];
|
||||
__GXData->texmapId[stage] = map;
|
||||
|
||||
tempMap = map & ~0x100;
|
||||
tempMap = (tempMap >= GX_MAX_TEXMAP) ? GX_TEXMAP0 : tempMap;
|
||||
|
||||
if (coord >= GX_MAXCOORD) {
|
||||
tempCoord = GX_TEXCOORD0;
|
||||
__GXData->tevTcEnab = __GXData->tevTcEnab & ~(1 << stage);
|
||||
} else {
|
||||
tempCoord = coord;
|
||||
__GXData->tevTcEnab = __GXData->tevTcEnab | (1 << stage);
|
||||
}
|
||||
|
||||
if (stage & 1) {
|
||||
GX_SET_REG(*reg, tempMap, 17, 19);
|
||||
GX_SET_REG(*reg, tempCoord, 14, 16);
|
||||
GX_SET_REG(*reg, (color == GX_COLOR_NULL ? 7 : c2r[color]), 10, 12);
|
||||
GX_SET_REG(*reg, ((map != GX_TEXMAP_NULL) && !(map & 0x100)), 13, 13);
|
||||
|
||||
} else {
|
||||
GX_SET_REG(*reg, tempMap, 29, 31);
|
||||
GX_SET_REG(*reg, tempCoord, 26, 28);
|
||||
GX_SET_REG(*reg, (color == GX_COLOR_NULL ? 7 : c2r[color]), 22, 24);
|
||||
GX_SET_REG(*reg, ((map != GX_TEXMAP_NULL) && !(map & 0x100)), 25, 25);
|
||||
}
|
||||
|
||||
GX_BP_LOAD_REG(*reg);
|
||||
|
||||
__GXData->bpSentNot = GX_FALSE;
|
||||
__GXData->dirtyState |= 1;
|
||||
}
|
||||
|
||||
void GXSetNumTevStages(u8 count) {
|
||||
GX_SET_REG(__GXData->genMode, count - 1, 18, 21);
|
||||
|
||||
__GXData->dirtyState |= 0x4;
|
||||
}
|
593
src/dolphin/gx/GXTexture.c
Normal file
593
src/dolphin/gx/GXTexture.c
Normal file
@ -0,0 +1,593 @@
|
||||
#include "dolphin/gx/GXTexture.h"
|
||||
#include "dolphin/gx/GX.h"
|
||||
|
||||
#define GET_TILE_COUNT(a, b) (((a) + (1 << (b)) - 1) >> (b))
|
||||
|
||||
inline void __GXGetTexTileShift(GXTexFmt format, u32* widthTiles, u32* heightTiles) {
|
||||
switch (format) {
|
||||
case GX_TF_I4:
|
||||
case GX_TF_C4:
|
||||
case GX_TF_CMPR:
|
||||
case GX_CTF_R4:
|
||||
case GX_CTF_Z4:
|
||||
*widthTiles = 3;
|
||||
*heightTiles = 3;
|
||||
break;
|
||||
|
||||
case GX_TF_I8:
|
||||
case GX_TF_IA4:
|
||||
case GX_TF_C8:
|
||||
case GX_TF_Z8:
|
||||
case GX_CTF_RA4:
|
||||
case GX_CTF_R8:
|
||||
case GX_CTF_G8:
|
||||
case GX_CTF_B8:
|
||||
case GX_CTF_RG8:
|
||||
case GX_CTF_Z8M:
|
||||
case GX_CTF_Z8L:
|
||||
*widthTiles = 3;
|
||||
*heightTiles = 2;
|
||||
break;
|
||||
|
||||
case GX_TF_IA8:
|
||||
case GX_TF_RGB565:
|
||||
case GX_TF_RGB5A3:
|
||||
case GX_TF_RGBA8:
|
||||
case GX_TF_C14X2:
|
||||
case GX_TF_Z16:
|
||||
case GX_TF_Z24X8:
|
||||
case GX_CTF_RA8:
|
||||
case GX_CTF_GB8:
|
||||
case 44:
|
||||
case GX_CTF_Z16L:
|
||||
*widthTiles = 2;
|
||||
*heightTiles = 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
*heightTiles = 0;
|
||||
*widthTiles = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
u32 GXGetTexBufferSize(u16 width, u16 height, u32 format, GXBool mipmap, u8 max_lod) {
|
||||
u32 widthTiles, heightTiles, tileSize, bufferSize, numX, numY, i;
|
||||
|
||||
__GXGetTexTileShift(format, &widthTiles, &heightTiles);
|
||||
|
||||
if (format == GX_TF_RGBA8 || format == GX_TF_Z24X8) {
|
||||
tileSize = 0x40;
|
||||
} else {
|
||||
tileSize = 0x20;
|
||||
}
|
||||
|
||||
if (mipmap == GX_TRUE) {
|
||||
bufferSize = 0;
|
||||
|
||||
for (i = 0; i < max_lod; i++) {
|
||||
numX = GET_TILE_COUNT(width, widthTiles);
|
||||
numY = GET_TILE_COUNT(height, heightTiles);
|
||||
|
||||
bufferSize += numX * numY * tileSize;
|
||||
if (width == 1 && height == 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
width = (width > 1) ? (width >> 1) : 1;
|
||||
height = (height > 1) ? (height >> 1) : 1;
|
||||
}
|
||||
|
||||
} else {
|
||||
numX = GET_TILE_COUNT(width, widthTiles);
|
||||
numY = GET_TILE_COUNT(height, heightTiles);
|
||||
bufferSize = numX * numY * tileSize;
|
||||
}
|
||||
|
||||
return bufferSize;
|
||||
}
|
||||
|
||||
void __GetImageTileCount(GXTexFmt format, u16 width, u16 height, u32* a, u32* b, u32* c) {
|
||||
u32 widthTiles, heightTiles;
|
||||
|
||||
__GXGetTexTileShift(format, &widthTiles, &heightTiles);
|
||||
|
||||
if (width <= 0) {
|
||||
width = 1;
|
||||
}
|
||||
|
||||
if (height <= 0) {
|
||||
height = 1;
|
||||
}
|
||||
|
||||
*a = GET_TILE_COUNT(width, widthTiles);
|
||||
*b = GET_TILE_COUNT(height, heightTiles);
|
||||
*c = (format == GX_TF_RGBA8 || format == GX_TF_Z24X8) ? 2 : 1;
|
||||
}
|
||||
|
||||
void GXInitTexObj(GXTexObj* obj, void* imagePtr, u16 width, u16 height, GXTexFmt format,
|
||||
GXTexWrapMode sWrap, GXTexWrapMode tWrap, GXBool useMIPmap) {
|
||||
u32 imageBase;
|
||||
u16 a, b;
|
||||
u32 c, d;
|
||||
|
||||
GXTexObj* internal = (GXTexObj*)obj;
|
||||
memset(internal, 0, sizeof(*internal));
|
||||
|
||||
GX_SET_REG(internal->texture_filter, sWrap, 30, 31);
|
||||
GX_SET_REG(internal->texture_filter, tWrap, 28, 29);
|
||||
GX_SET_REG(internal->texture_filter, GX_TRUE, 27, 27);
|
||||
|
||||
if (useMIPmap) {
|
||||
u32 maxDimSize;
|
||||
internal->texture_flags |= 1;
|
||||
if (format == 8 || format == 9 || format == 10) {
|
||||
GX_SET_REG(internal->texture_filter, 5, 24, 26);
|
||||
} else {
|
||||
GX_SET_REG(internal->texture_filter, 6, 24, 26);
|
||||
}
|
||||
|
||||
maxDimSize = width > height ? 31 - __cntlzw(width) : 31 - __cntlzw(height);
|
||||
|
||||
GX_SET_REG(internal->texture_lod, (maxDimSize) * 16.f, 16, 23);
|
||||
} else {
|
||||
GX_SET_REG(internal->texture_filter, 4, 24, 26);
|
||||
}
|
||||
|
||||
internal->texture_format = format;
|
||||
GX_SET_REG(internal->texture_size, width - 1, 22, 31);
|
||||
GX_SET_REG(internal->texture_size, height - 1, 12, 21);
|
||||
|
||||
GX_SET_REG(internal->texture_size, format & 0xf, 8, 11);
|
||||
imageBase = (u32)imagePtr >> 5;
|
||||
GX_SET_REG(internal->texture_address, imageBase, 11, 31);
|
||||
|
||||
switch (format & 0xf) {
|
||||
case 0:
|
||||
case 8:
|
||||
internal->texture_tile_type = 1;
|
||||
a = 3;
|
||||
b = 3;
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
case 9:
|
||||
internal->texture_tile_type = 2;
|
||||
a = 3;
|
||||
b = 2;
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case 10:
|
||||
internal->texture_tile_type = 2;
|
||||
a = 2;
|
||||
b = 2;
|
||||
break;
|
||||
case 6:
|
||||
internal->texture_tile_type = 3;
|
||||
a = 2;
|
||||
b = 2;
|
||||
break;
|
||||
case 0xe:
|
||||
internal->texture_tile_type = 0;
|
||||
a = 3;
|
||||
b = 3;
|
||||
break;
|
||||
default:
|
||||
internal->texture_tile_type = 2;
|
||||
a = 2;
|
||||
b = 2;
|
||||
break;
|
||||
}
|
||||
|
||||
internal->texture_time_count = (GET_TILE_COUNT(width, a) * GET_TILE_COUNT(height, b)) & 0x7fff;
|
||||
|
||||
internal->texture_flags |= 2;
|
||||
}
|
||||
|
||||
void GXInitTexObjCI(GXTexObj* obj, void* imagePtr, u16 width, u16 height, GXCITexFmt format,
|
||||
GXTexWrapMode sWrap, GXTexWrapMode tWrap, GXBool useMIPmap, u32 tlut_name) {
|
||||
GXTexObj* internal = (GXTexObj*)obj;
|
||||
|
||||
GXInitTexObj(obj, imagePtr, width, height, format, sWrap, tWrap, useMIPmap);
|
||||
|
||||
internal->texture_flags &= ~2;
|
||||
internal->tlut_name = tlut_name;
|
||||
}
|
||||
|
||||
u8 GXTexMode0Ids[8] = {0x80, 0x81, 0x82, 0x83, 0xA0, 0xA1, 0xA2, 0xA3};
|
||||
|
||||
u8 GXTexMode1Ids[8] = {0x84, 0x85, 0x86, 0x87, 0xA4, 0xA5, 0xA6, 0xA7};
|
||||
|
||||
u8 GXTexImage0Ids[8] = {0x88, 0x89, 0x8a, 0x8b, 0xA8, 0xA9, 0xAa, 0xAb};
|
||||
|
||||
u8 GXTexImage1Ids[8] = {0x8c, 0x8d, 0x8e, 0x8f, 0xAc, 0xAd, 0xAe, 0xAf};
|
||||
|
||||
u8 GXTexImage2Ids[8] = {0x90, 0x91, 0x92, 0x93, 0xB0, 0xB1, 0xB2, 0xB3};
|
||||
|
||||
u8 GXTexImage3Ids[8] = {0x94, 0x95, 0x96, 0x97, 0xB4, 0xB5, 0xB6, 0xB7};
|
||||
|
||||
u8 GXTexTlutIds[8] = {0x98, 0x99, 0x9a, 0x9b, 0xB8, 0xB9, 0xBa, 0xBb};
|
||||
|
||||
u8 GX2HWFiltConv[6] = {0x00, 0x04, 0x01, 0x05, 0x02, 0x06};
|
||||
|
||||
void GXInitTexObjLOD(GXTexObj* obj, GXTexFilter minFilter, GXTexFilter maxFilter, f32 minLOD,
|
||||
f32 maxLOD, f32 lodBias, GXBool doBiasClamp, GXBool doEdgeLOD,
|
||||
GXAnisotropy maxAniso) {
|
||||
GXTexObj* internal = (GXTexObj*)obj;
|
||||
u8 reg1, reg2;
|
||||
if (lodBias < -4.0f) {
|
||||
lodBias = -4.0f;
|
||||
} else if (lodBias >= 4.0f) {
|
||||
lodBias = 3.99f;
|
||||
}
|
||||
|
||||
GX_SET_REG(internal->texture_filter, lodBias * 32.0f, 15, 22);
|
||||
GX_SET_REG(internal->texture_filter, maxFilter == 1 ? 1 : 0, 27, 27);
|
||||
GX_SET_REG(internal->texture_filter, GX2HWFiltConv[minFilter], 24, 26);
|
||||
GX_SET_REG(internal->texture_filter, doEdgeLOD ? 0 : 1, 23, 23);
|
||||
GX_SET_REG(internal->texture_filter, 0, 14, 14);
|
||||
GX_SET_REG(internal->texture_filter, 0, 13, 13);
|
||||
GX_SET_REG(internal->texture_filter, maxAniso, 11, 12);
|
||||
GX_SET_REG(internal->texture_filter, doBiasClamp, 10, 10);
|
||||
|
||||
if (minLOD < 0.0f) {
|
||||
minLOD = 0.0f;
|
||||
} else if (minLOD > 10.0f) {
|
||||
minLOD = 10.0f;
|
||||
}
|
||||
reg1 = minLOD * 16.0f;
|
||||
|
||||
if (maxLOD < 0.0f) {
|
||||
maxLOD = 0.0f;
|
||||
} else if (maxLOD > 10.0f) {
|
||||
maxLOD = 10.0f;
|
||||
}
|
||||
reg2 = maxLOD * 16.0f;
|
||||
|
||||
GX_SET_REG(internal->texture_lod, reg1, 24, 31);
|
||||
GX_SET_REG(internal->texture_lod, reg2, 16, 23);
|
||||
}
|
||||
|
||||
u16 GXGetTexObjWidth(GXTexObj* obj) {
|
||||
return (obj->texture_size & 0x3ff) + 1;
|
||||
}
|
||||
|
||||
u16 GXGetTexObjHeight(GXTexObj* obj) {
|
||||
return ((obj->texture_size >> 10) & 0x3ff) + 1;
|
||||
}
|
||||
|
||||
GXTexFmt GXGetTexObjFmt(const GXTexObj* obj) {
|
||||
return obj->texture_format;
|
||||
}
|
||||
|
||||
GXTexWrapMode GXGetTexObjWrapS(GXTexObj* obj) {
|
||||
return obj->texture_filter & 0x3;
|
||||
}
|
||||
|
||||
GXTexWrapMode GXGetTexObjWrapT(GXTexObj* obj) {
|
||||
return (obj->texture_filter & 0xc) >> 2;
|
||||
}
|
||||
|
||||
GXBool GXGetTexObjMipMap(const GXTexObj* obj) {
|
||||
return (obj->texture_flags & 1) == 1;
|
||||
}
|
||||
|
||||
u32 GXGetTexObjTlut(GXTexObj* obj) {
|
||||
return obj->tlut_name;
|
||||
}
|
||||
|
||||
void GXLoadTexObjPreLoaded(GXTexObj* obj, GXTexRegion* region, GXTexMapID map) {
|
||||
u8 stackManipulation[0x18];
|
||||
|
||||
GXTexObj* internalObj = (GXTexObj*)obj;
|
||||
GXTexRegion* internalRegion = (GXTexRegion*)region;
|
||||
|
||||
GX_SET_REG(internalObj->texture_filter, GXTexMode0Ids[map], 0, 7);
|
||||
GX_SET_REG(internalObj->texture_lod, GXTexMode1Ids[map], 0, 7);
|
||||
GX_SET_REG(internalObj->texture_size, GXTexImage0Ids[map], 0, 7);
|
||||
|
||||
GX_SET_REG(internalRegion->unk0, GXTexImage1Ids[map], 0, 7);
|
||||
GX_SET_REG(internalRegion->unk4, GXTexImage2Ids[map], 0, 7);
|
||||
|
||||
GX_SET_REG(internalObj->texture_address, GXTexImage3Ids[map], 0, 7);
|
||||
|
||||
GX_BP_LOAD_REG(internalObj->texture_filter);
|
||||
GX_BP_LOAD_REG(internalObj->texture_lod);
|
||||
GX_BP_LOAD_REG(internalObj->texture_size);
|
||||
GX_BP_LOAD_REG(internalRegion->unk0);
|
||||
GX_BP_LOAD_REG(internalRegion->unk4);
|
||||
GX_BP_LOAD_REG(internalObj->texture_address);
|
||||
|
||||
if ((internalObj->texture_flags & 2) == 0) {
|
||||
GXTlutObj* tlut = (GXTlutObj*)__GXData->tlutRegionCallback(internalObj->tlut_name);
|
||||
GX_SET_REG(tlut->address, GXTexTlutIds[map], 0, 7);
|
||||
|
||||
GX_BP_LOAD_REG(tlut->address);
|
||||
}
|
||||
|
||||
__GXData->tImage0[map] = internalObj->texture_size;
|
||||
__GXData->tMode0[map] = internalObj->texture_filter;
|
||||
|
||||
__GXData->dirtyState |= GX_DIRTY_SU_TEX;
|
||||
__GXData->bpSentNot = GX_FALSE;
|
||||
}
|
||||
|
||||
void GXLoadTexObj(GXTexObj* obj, GXTexMapID map) {
|
||||
GXTexRegion* ret = (GXTexRegion*)__GXData->texRegionCallback(obj, map);
|
||||
|
||||
GXLoadTexObjPreLoaded(obj, ret, map);
|
||||
}
|
||||
|
||||
void GXInitTlutObj(GXTlutObj* obj, void* table, GXTlutFmt format, u16 numEntries) {
|
||||
GXTlutObj* internal = (GXTlutObj*)obj;
|
||||
|
||||
internal->format = 0;
|
||||
|
||||
GX_SET_REG(internal->format, format, 20, 21);
|
||||
GX_SET_REG(internal->address, (u32)table >> 5, 11, 31);
|
||||
GX_SET_REG(internal->address, 100, 0, 7);
|
||||
|
||||
internal->numEntries = numEntries;
|
||||
}
|
||||
|
||||
void GXLoadTlut(GXTlutObj* obj, u32 tlut_name) {
|
||||
GXTlutObj* internal = (GXTlutObj*)obj;
|
||||
GXTlutRegion* ret = (GXTlutRegion*)__GXData->tlutRegionCallback(tlut_name);
|
||||
u32 reg;
|
||||
|
||||
__GXFlushTextureState();
|
||||
|
||||
GX_BP_LOAD_REG(internal->address);
|
||||
GX_BP_LOAD_REG(ret->unk0);
|
||||
|
||||
__GXFlushTextureState();
|
||||
|
||||
reg = ret->unk0;
|
||||
GX_SET_REG(internal->format, reg, 22, 31);
|
||||
|
||||
ret->tlutObj = *internal;
|
||||
}
|
||||
|
||||
void GXInitTexCacheRegion(GXTexRegion* region, GXBool is32bMIPmap, u32 memEven,
|
||||
GXTexCacheSize sizeEven, u32 memOdd, GXTexCacheSize sizeOdd) {
|
||||
GXTexRegion* internal = (GXTexRegion*)region;
|
||||
|
||||
u32 reg;
|
||||
switch (sizeEven) {
|
||||
case 0:
|
||||
reg = 3;
|
||||
break;
|
||||
case 1:
|
||||
reg = 4;
|
||||
break;
|
||||
case 2:
|
||||
reg = 5;
|
||||
break;
|
||||
}
|
||||
|
||||
internal->unk0 = 0;
|
||||
|
||||
GX_SET_REG(internal->unk0, memEven >> 5, 17, 31);
|
||||
GX_SET_REG(internal->unk0, reg, 14, 16);
|
||||
GX_SET_REG(internal->unk0, reg, 11, 13);
|
||||
GX_SET_REG(internal->unk0, 0, 10, 10);
|
||||
|
||||
switch (sizeOdd) {
|
||||
case 0:
|
||||
reg = 3;
|
||||
break;
|
||||
case 1:
|
||||
reg = 4;
|
||||
break;
|
||||
case 2:
|
||||
reg = 5;
|
||||
break;
|
||||
case 3:
|
||||
reg = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
internal->unk4 = 0;
|
||||
GX_SET_REG(internal->unk4, memOdd >> 5, 17, 31);
|
||||
GX_SET_REG(internal->unk4, reg, 14, 16);
|
||||
GX_SET_REG(internal->unk4, reg, 11, 13);
|
||||
|
||||
internal->unkC = is32bMIPmap;
|
||||
internal->unkD = 1;
|
||||
}
|
||||
|
||||
void GXInitTlutRegion(GXTlutRegion* region, u32 memAddr, GXTlutSize tlutSize) {
|
||||
GXTlutRegion* internal = (GXTlutRegion*)region;
|
||||
|
||||
internal->unk0 = 0;
|
||||
GX_SET_REG(internal->unk0, (memAddr - 0x80000) >> 9, 22, 31);
|
||||
GX_SET_REG(internal->unk0, tlutSize, 11, 21);
|
||||
GX_SET_REG(internal->unk0, 0x65, 0, 7);
|
||||
}
|
||||
|
||||
void GXInvalidateTexAll(void) {
|
||||
__GXFlushTextureState();
|
||||
GXFIFO.u8 = 0x61;
|
||||
GXFIFO.u32 = 0x66001000;
|
||||
GXFIFO.u8 = 0x61;
|
||||
GXFIFO.u32 = 0x66001100;
|
||||
__GXFlushTextureState();
|
||||
}
|
||||
|
||||
GXTexRegionCallback GXSetTexRegionCallback(GXTexRegionCallback callback) {
|
||||
GXTexRegionCallback prev = __GXData->texRegionCallback;
|
||||
__GXData->texRegionCallback = callback;
|
||||
return prev;
|
||||
}
|
||||
|
||||
GXTlutRegionCallback GXSetTlutRegionCallback(GXTlutRegionCallback callback) {
|
||||
GXTlutRegionCallback prev = __GXData->tlutRegionCallback;
|
||||
__GXData->tlutRegionCallback = callback;
|
||||
return prev;
|
||||
}
|
||||
|
||||
void GXSetTexCoordScaleManually(GXTexCoordID coord, GXBool enable, u16 s_scale, u16 t_scale) {
|
||||
/* Nonmatching */
|
||||
}
|
||||
|
||||
void __SetSURegs(u32 texImgIndex, u32 setUpRegIndex) {
|
||||
u16 a1, a2;
|
||||
GXBool b, c;
|
||||
|
||||
a1 = GX_GET_REG(__GXData->tImage0[texImgIndex], 22, 31);
|
||||
a2 = (__GXData->tImage0[texImgIndex] & (0x3ff << 10)) >> 10;
|
||||
|
||||
GX_SET_REG(__GXData->suTs0[setUpRegIndex], a1, 16, 31);
|
||||
GX_SET_REG(__GXData->suTs1[setUpRegIndex], a2, 16, 31);
|
||||
|
||||
b = GX_GET_REG(__GXData->tMode0[texImgIndex], 30, 31) == 1;
|
||||
c = GX_GET_REG(__GXData->tMode0[texImgIndex], 28, 29) == 1;
|
||||
|
||||
GX_SET_REG(__GXData->suTs0[setUpRegIndex], b, 15, 15);
|
||||
GX_SET_REG(__GXData->suTs1[setUpRegIndex], c, 15, 15);
|
||||
|
||||
GX_BP_LOAD_REG(__GXData->suTs0[setUpRegIndex]);
|
||||
GX_BP_LOAD_REG(__GXData->suTs1[setUpRegIndex]);
|
||||
|
||||
__GXData->bpSentNot = GX_FALSE;
|
||||
}
|
||||
|
||||
#pragma dont_inline on
|
||||
void __GXSetSUTexRegs(void) {
|
||||
u32 i;
|
||||
u32 b;
|
||||
u32 a;
|
||||
u32 c;
|
||||
u32 d;
|
||||
u32 stackFiller;
|
||||
if (__GXData->tcsManEnab != 0xff) {
|
||||
a = GX_GET_REG(__GXData->genMode, 18, 21) + 1;
|
||||
b = GX_GET_REG(__GXData->genMode, 13, 15);
|
||||
for (i = 0; i < b; i++) {
|
||||
switch (i) {
|
||||
case 0:
|
||||
c = GX_GET_REG(__GXData->iref, 29, 31);
|
||||
d = GX_GET_REG(__GXData->iref, 26, 28);
|
||||
break;
|
||||
case 1:
|
||||
c = GX_GET_REG(__GXData->iref, 23, 25);
|
||||
d = GX_GET_REG(__GXData->iref, 20, 22);
|
||||
break;
|
||||
case 2:
|
||||
c = GX_GET_REG(__GXData->iref, 17, 19);
|
||||
d = GX_GET_REG(__GXData->iref, 14, 16);
|
||||
break;
|
||||
case 3:
|
||||
c = GX_GET_REG(__GXData->iref, 11, 13);
|
||||
d = GX_GET_REG(__GXData->iref, 8, 10);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(__GXData->tcsManEnab & (1 << d))) {
|
||||
__SetSURegs(c, d);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < a; i++) {
|
||||
u32* g = &__GXData->tref[i / 2];
|
||||
|
||||
c = __GXData->texmapId[i] & ~0x100;
|
||||
|
||||
if (i & 1) {
|
||||
d = GX_GET_REG(*g, 14, 16);
|
||||
} else {
|
||||
d = GX_GET_REG(*g, 26, 28);
|
||||
}
|
||||
|
||||
if (c != 0xff && !(__GXData->tcsManEnab & (1 << d)) && __GXData->tevTcEnab & (1 << i)) {
|
||||
__SetSURegs(c, d);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma dont_inline reset
|
||||
|
||||
void __GXSetTmemConfig(u32 config) {
|
||||
switch (config) {
|
||||
case 2:
|
||||
GX_BP_LOAD_REG(0x8c0d8000);
|
||||
GX_BP_LOAD_REG(0x900dc000);
|
||||
|
||||
GX_BP_LOAD_REG(0x8d0d8800);
|
||||
GX_BP_LOAD_REG(0x910dc800);
|
||||
|
||||
GX_BP_LOAD_REG(0x8e0d9000);
|
||||
GX_BP_LOAD_REG(0x920dd000);
|
||||
|
||||
GX_BP_LOAD_REG(0x8f0d9800);
|
||||
GX_BP_LOAD_REG(0x930dd800);
|
||||
|
||||
GX_BP_LOAD_REG(0xac0da000);
|
||||
GX_BP_LOAD_REG(0xb00dc400);
|
||||
|
||||
GX_BP_LOAD_REG(0xad0da800);
|
||||
GX_BP_LOAD_REG(0xb10dcc00);
|
||||
|
||||
GX_BP_LOAD_REG(0xae0db000);
|
||||
GX_BP_LOAD_REG(0xb20dd400);
|
||||
|
||||
GX_BP_LOAD_REG(0xaf0db800);
|
||||
GX_BP_LOAD_REG(0xb30ddc00);
|
||||
break;
|
||||
case 1:
|
||||
GX_BP_LOAD_REG(0x8c0d8000);
|
||||
GX_BP_LOAD_REG(0x900dc000);
|
||||
|
||||
GX_BP_LOAD_REG(0x8d0d8800);
|
||||
GX_BP_LOAD_REG(0x910dc800);
|
||||
|
||||
GX_BP_LOAD_REG(0x8e0d9000);
|
||||
GX_BP_LOAD_REG(0x920dd000);
|
||||
|
||||
GX_BP_LOAD_REG(0x8f0d9800);
|
||||
GX_BP_LOAD_REG(0x930dd800);
|
||||
|
||||
GX_BP_LOAD_REG(0xac0da000);
|
||||
GX_BP_LOAD_REG(0xb00de000);
|
||||
|
||||
GX_BP_LOAD_REG(0xad0da800);
|
||||
GX_BP_LOAD_REG(0xb10de800);
|
||||
|
||||
GX_BP_LOAD_REG(0xae0db000);
|
||||
GX_BP_LOAD_REG(0xb20df000);
|
||||
|
||||
GX_BP_LOAD_REG(0xaf0db800);
|
||||
GX_BP_LOAD_REG(0xb30df800);
|
||||
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
GX_BP_LOAD_REG(0x8c0d8000);
|
||||
GX_BP_LOAD_REG(0x900dc000);
|
||||
|
||||
GX_BP_LOAD_REG(0x8d0d8400);
|
||||
GX_BP_LOAD_REG(0x910dc400);
|
||||
|
||||
GX_BP_LOAD_REG(0x8e0d8800);
|
||||
GX_BP_LOAD_REG(0x920dc800);
|
||||
|
||||
GX_BP_LOAD_REG(0x8f0d8c00);
|
||||
GX_BP_LOAD_REG(0x930dcc00);
|
||||
|
||||
GX_BP_LOAD_REG(0xac0d9000);
|
||||
GX_BP_LOAD_REG(0xb00dd000);
|
||||
|
||||
GX_BP_LOAD_REG(0xad0d9400);
|
||||
GX_BP_LOAD_REG(0xb10dd400);
|
||||
|
||||
GX_BP_LOAD_REG(0xae0d9800);
|
||||
GX_BP_LOAD_REG(0xb20dd800);
|
||||
|
||||
GX_BP_LOAD_REG(0xaf0d9c00);
|
||||
GX_BP_LOAD_REG(0xb30ddc00);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
316
src/dolphin/gx/GXTransform.c
Normal file
316
src/dolphin/gx/GXTransform.c
Normal file
@ -0,0 +1,316 @@
|
||||
#include "dolphin/gx/GXTransform.h"
|
||||
#include "dolphin/gx/GX.h"
|
||||
#include "dolphin/os/OS.h"
|
||||
|
||||
void __GXSetMatrixIndex();
|
||||
|
||||
static void Copy6Floats(register f32 src[6], register f32 dst[6]) {
|
||||
register f32 ps_0, ps_1, ps_2;
|
||||
|
||||
// clang-format off
|
||||
asm {
|
||||
psq_l ps_0, 0(src), 0, 0
|
||||
psq_l ps_1, 8(src), 0, 0
|
||||
psq_l ps_2, 16(src), 0, 0
|
||||
psq_st ps_0, 0(dst), 0, 0
|
||||
psq_st ps_1, 8(dst), 0, 0
|
||||
psq_st ps_2, 16(dst), 0, 0
|
||||
}
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
static void WriteProjPS(const register f32 src[6], register volatile void* dst) {
|
||||
register f32 ps_0, ps_1, ps_2;
|
||||
|
||||
// clang-format off
|
||||
asm {
|
||||
psq_l ps_0, 0(src), 0, 0
|
||||
psq_l ps_1, 8(src), 0, 0
|
||||
psq_l ps_2, 16(src), 0, 0
|
||||
psq_st ps_0, 0(dst), 0, 0
|
||||
psq_st ps_1, 0(dst), 0, 0
|
||||
psq_st ps_2, 0(dst), 0, 0
|
||||
}
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
void GXProject(f32 model_x, f32 model_y, f32 model_z, Mtx model_mtx, f32* proj_mtx, f32* viewpoint,
|
||||
f32* screen_x, f32* screen_y, f32* screen_z) {
|
||||
f32 sp10[3];
|
||||
f32 var_f30;
|
||||
f32 var_f29;
|
||||
f32 var_f28;
|
||||
f32 var_f31;
|
||||
|
||||
ASSERTMSG(proj_mtx != NULL && viewpoint != NULL && screen_x != NULL && screen_y != NULL && screen_z != NULL, "GXGet*: invalid null pointer");
|
||||
|
||||
sp10[0] = (model_mtx[0][0] * model_x) + (model_mtx[0][1] * model_y) +
|
||||
(model_mtx[0][2] * model_z) + model_mtx[0][3];
|
||||
sp10[1] = (model_mtx[1][0] * model_x) + (model_mtx[1][1] * model_y) +
|
||||
(model_mtx[1][2] * model_z) + model_mtx[1][3];
|
||||
sp10[2] = (model_mtx[2][0] * model_x) + (model_mtx[2][1] * model_y) +
|
||||
(model_mtx[2][2] * model_z) + model_mtx[2][3];
|
||||
|
||||
if (proj_mtx[0] == 0.0f) {
|
||||
var_f30 = (sp10[0] * proj_mtx[1]) + (sp10[2] * proj_mtx[2]);
|
||||
var_f29 = (sp10[1] * proj_mtx[3]) + (sp10[2] * proj_mtx[4]);
|
||||
var_f28 = proj_mtx[6] + (sp10[2] * proj_mtx[5]);
|
||||
var_f31 = 1.0f / -sp10[2];
|
||||
} else {
|
||||
var_f30 = proj_mtx[2] + (sp10[0] * proj_mtx[1]);
|
||||
var_f29 = proj_mtx[4] + (sp10[1] * proj_mtx[3]);
|
||||
var_f28 = proj_mtx[6] + (sp10[2] * proj_mtx[5]);
|
||||
var_f31 = 1.0f;
|
||||
}
|
||||
|
||||
*screen_x = (viewpoint[2] / 2) + (viewpoint[0] + (var_f31 * (var_f30 * viewpoint[2] / 2)));
|
||||
*screen_y = (viewpoint[3] / 2) + (viewpoint[1] + (var_f31 * (-var_f29 * viewpoint[3] / 2)));
|
||||
*screen_z = viewpoint[5] + (var_f31 * (var_f28 * (viewpoint[5] - viewpoint[4])));
|
||||
}
|
||||
|
||||
void __GXSetProjection(void) {
|
||||
GX_XF_LOAD_REGS(6, GX_XF_REG_PROJECTIONA);
|
||||
WriteProjPS(__GXData->projMtx, (volatile void*)GXFIFO_ADDR);
|
||||
GX_WRITE_U32(__GXData->projType);
|
||||
}
|
||||
|
||||
void GXSetProjection(const Mtx44 proj, GXProjectionType type) {
|
||||
volatile void* fifo;
|
||||
__GXData->projType = type;
|
||||
|
||||
__GXData->projMtx[0] = proj[0][0];
|
||||
__GXData->projMtx[2] = proj[1][1];
|
||||
__GXData->projMtx[4] = proj[2][2];
|
||||
__GXData->projMtx[5] = proj[2][3];
|
||||
|
||||
if (type == GX_ORTHOGRAPHIC) {
|
||||
__GXData->projMtx[1] = proj[0][3];
|
||||
__GXData->projMtx[3] = proj[1][3];
|
||||
} else {
|
||||
__GXData->projMtx[1] = proj[0][2];
|
||||
__GXData->projMtx[3] = proj[1][2];
|
||||
}
|
||||
|
||||
__GXSetProjection();
|
||||
|
||||
__GXData->bpSentNot = GX_TRUE;
|
||||
}
|
||||
|
||||
void GXSetProjectionv(f32* proj) {
|
||||
__GXData->projType = proj[0] == 0.0f ? GX_PERSPECTIVE : GX_ORTHOGRAPHIC;
|
||||
Copy6Floats(&proj[1], __GXData->projMtx);
|
||||
|
||||
__GXSetProjection();
|
||||
__GXData->bpSentNot = GX_TRUE;
|
||||
}
|
||||
|
||||
void GXGetProjectionv(f32* proj) {
|
||||
*proj = (u32)__GXData->projType != GX_PERSPECTIVE ? 1.0f : 0.0f;
|
||||
Copy6Floats(__GXData->projMtx, &proj[1]);
|
||||
}
|
||||
|
||||
static void WriteMTXPS4x3(register volatile void* dst, register const Mtx src) {
|
||||
register f32 ps_0, ps_1, ps_2, ps_3, ps_4, ps_5;
|
||||
|
||||
// clang-format off
|
||||
asm {
|
||||
psq_l ps_0, 0(src), 0, 0
|
||||
psq_l ps_1, 8(src), 0, 0
|
||||
psq_l ps_2, 16(src), 0, 0
|
||||
psq_l ps_3, 24(src), 0, 0
|
||||
psq_l ps_4, 32(src), 0, 0
|
||||
psq_l ps_5, 40(src), 0, 0
|
||||
|
||||
psq_st ps_0, 0(dst), 0, 0
|
||||
psq_st ps_1, 0(dst), 0, 0
|
||||
psq_st ps_2, 0(dst), 0, 0
|
||||
psq_st ps_3, 0(dst), 0, 0
|
||||
psq_st ps_4, 0(dst), 0, 0
|
||||
psq_st ps_5, 0(dst), 0, 0
|
||||
}
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
void GXLoadPosMtxImm(Mtx mtx, u32 id) {
|
||||
GX_XF_LOAD_REGS(4 * 3 - 1, id * 4 + GX_XF_MEM_POSMTX);
|
||||
WriteMTXPS4x3(&GXFIFO, mtx);
|
||||
}
|
||||
|
||||
static void WriteMTXPS3x3(register volatile void* dst, register const Mtx src) {
|
||||
register f32 ps_0, ps_1, ps_2, ps_3, ps_4, ps_5;
|
||||
|
||||
// clang-format off
|
||||
asm {
|
||||
psq_l ps_0, 0(src), 0, 0
|
||||
lfs ps_1, 8(src)
|
||||
psq_l ps_2, 16(src), 0, 0
|
||||
lfs ps_3, 24(src)
|
||||
psq_l ps_4, 32(src), 0, 0
|
||||
lfs ps_5, 40(src)
|
||||
|
||||
psq_st ps_0, 0(dst), 0, 0
|
||||
stfs ps_1, 0(dst)
|
||||
psq_st ps_2, 0(dst), 0, 0
|
||||
stfs ps_3, 0(dst)
|
||||
psq_st ps_4, 0(dst), 0, 0
|
||||
stfs ps_5, 0(dst)
|
||||
}
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
void GXLoadNrmMtxImm(Mtx mtx, u32 id) {
|
||||
GX_XF_LOAD_REGS(3 * 3 - 1, id * 3 + GX_XF_MEM_NRMMTX);
|
||||
WriteMTXPS3x3(&GXFIFO, mtx);
|
||||
}
|
||||
|
||||
void GXSetCurrentMtx(u32 id) {
|
||||
GX_SET_REG(__GXData->matIdxA, id, GX_XF_MTXIDX0_GEOM_ST, GX_XF_MTXIDX0_GEOM_END);
|
||||
__GXSetMatrixIndex(GX_VA_PNMTXIDX);
|
||||
}
|
||||
|
||||
static void WriteMTXPS4x2(register volatile void* dst, register const Mtx src) {
|
||||
register f32 ps_0, ps_1, ps_2, ps_3;
|
||||
|
||||
// clang-format off
|
||||
asm {
|
||||
psq_l ps_0, 0(src), 0, 0
|
||||
psq_l ps_1, 8(src), 0, 0
|
||||
psq_l ps_2, 16(src), 0, 0
|
||||
psq_l ps_3, 24(src), 0, 0
|
||||
|
||||
psq_st ps_0, 0(dst), 0, 0
|
||||
psq_st ps_1, 0(dst), 0, 0
|
||||
psq_st ps_2, 0(dst), 0, 0
|
||||
psq_st ps_3, 0(dst), 0, 0
|
||||
}
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
void GXLoadTexMtxImm(const Mtx mtx, u32 id, GXTexMtxType type) {
|
||||
u32 addr;
|
||||
u32 num;
|
||||
u32 reg;
|
||||
|
||||
// Matrix address in XF memory
|
||||
addr = id >= GX_PTTEXMTX0 ? (id - GX_PTTEXMTX0) * 4 + GX_XF_MEM_DUALTEXMTX :
|
||||
id * 4 + (u64)GX_XF_MEM_POSMTX;
|
||||
|
||||
// Number of elements in matrix
|
||||
num = type == GX_MTX2x4 ? (u64)(2 * 4) : 3 * 4;
|
||||
|
||||
reg = addr | (num - 1) << 16;
|
||||
|
||||
GX_XF_LOAD_REG_HDR(reg);
|
||||
|
||||
if (type == GX_MTX3x4) {
|
||||
WriteMTXPS4x3(&GXFIFO, mtx);
|
||||
} else {
|
||||
WriteMTXPS4x2(&GXFIFO, mtx);
|
||||
}
|
||||
}
|
||||
|
||||
void __GXSetViewport(void) {
|
||||
f32 a, b, c, d, e, f;
|
||||
f32 near, far;
|
||||
|
||||
a = __GXData->vpWd / 2;
|
||||
b = -__GXData->vpHt / 2;
|
||||
d = __GXData->vpLeft + (__GXData->vpWd / 2) + 342.0f;
|
||||
e = __GXData->vpTop + (__GXData->vpHt / 2) + 342.0f;
|
||||
|
||||
near = __GXData->vpNearz * __GXData->zScale;
|
||||
far = __GXData->vpFarz * __GXData->zScale;
|
||||
|
||||
c = far - near;
|
||||
f = far + __GXData->zOffset;
|
||||
|
||||
GX_XF_LOAD_REGS(5, GX_XF_REG_SCALEX);
|
||||
GX_WRITE_F32(a);
|
||||
GX_WRITE_F32(b);
|
||||
GX_WRITE_F32(c);
|
||||
GX_WRITE_F32(d);
|
||||
GX_WRITE_F32(e);
|
||||
GX_WRITE_F32(f);
|
||||
}
|
||||
|
||||
void GXSetViewport(f32 left, f32 top, f32 width, f32 height, f32 nearZ, f32 farZ) {
|
||||
__GXData->vpLeft = left;
|
||||
__GXData->vpTop = top;
|
||||
__GXData->vpWd = width;
|
||||
__GXData->vpHt = height;
|
||||
__GXData->vpNearz = nearZ;
|
||||
__GXData->vpFarz = farZ;
|
||||
__GXSetViewport();
|
||||
__GXData->bpSentNot = GX_TRUE;
|
||||
}
|
||||
|
||||
void GXGetViewportv(f32* p) {
|
||||
Copy6Floats(&__GXData->vpLeft, p);
|
||||
}
|
||||
|
||||
void GXSetScissor(u32 left, u32 top, u32 width, u32 height) {
|
||||
u32 y1, x1, y2, x2;
|
||||
u32 reg;
|
||||
|
||||
y1 = top + 342;
|
||||
x1 = left + 342;
|
||||
|
||||
GX_SET_REG(__GXData->suScis0, y1, GX_BP_SCISSORTL_TOP_ST, GX_BP_SCISSORTL_TOP_END);
|
||||
GX_SET_REG(__GXData->suScis0, x1, GX_BP_SCISSORTL_LEFT_ST, GX_BP_SCISSORTL_LEFT_END);
|
||||
|
||||
y2 = y1 + height - 1;
|
||||
x2 = (x1 + width) - 1;
|
||||
|
||||
GX_SET_REG(__GXData->suScis1, y2, GX_BP_SCISSORBR_BOT_ST, GX_BP_SCISSORBR_BOT_END);
|
||||
GX_SET_REG(__GXData->suScis1, x2, GX_BP_SCISSORBR_RIGHT_ST, GX_BP_SCISSORBR_RIGHT_END);
|
||||
|
||||
GX_BP_LOAD_REG(__GXData->suScis0);
|
||||
GX_BP_LOAD_REG(__GXData->suScis1);
|
||||
__GXData->bpSentNot = FALSE;
|
||||
}
|
||||
|
||||
void GXGetScissor(u32* left, u32* top, u32* width, u32* height) {
|
||||
u32 y1 = (__GXData->suScis0 & 0x0007FF) >> 0;
|
||||
u32 x1 = (__GXData->suScis0 & 0x7FF000) >> 12;
|
||||
u32 y2 = (__GXData->suScis1 & 0x0007FF) >> 0;
|
||||
u32 x2 = (__GXData->suScis1 & 0x7FF000) >> 12;
|
||||
|
||||
*left = x1 - 0x156;
|
||||
*top = y1 - 0x156;
|
||||
*width = (x2 - x1) + 1;
|
||||
*height = (y2 - y1) + 1;
|
||||
}
|
||||
|
||||
void GXSetScissorBoxOffset(s32 x, s32 y) {
|
||||
u32 cmd = 0;
|
||||
u32 x1;
|
||||
u32 y1;
|
||||
|
||||
x1 = (u32)(x + 342) / 2;
|
||||
y1 = (u32)(y + 342) / 2;
|
||||
GX_SET_REG(cmd, x1, GX_BP_SCISSOROFS_OX_ST, GX_BP_SCISSOROFS_OX_END);
|
||||
GX_SET_REG(cmd, y1, GX_BP_SCISSOROFS_OY_ST, GX_BP_SCISSOROFS_OY_END);
|
||||
|
||||
GX_SET_REG(cmd, GX_BP_REG_SCISSOROFFSET, 0, 7);
|
||||
|
||||
GX_BP_LOAD_REG(cmd);
|
||||
__GXData->bpSentNot = GX_FALSE;
|
||||
}
|
||||
|
||||
void GXSetClipMode(GXClipMode mode) {
|
||||
GX_XF_LOAD_REG(GX_XF_REG_CLIPDISABLE, mode);
|
||||
__GXData->bpSentNot = GX_TRUE;
|
||||
}
|
||||
|
||||
void __GXSetMatrixIndex(GXAttr index) {
|
||||
// Tex4 and after is stored in XF MatrixIndex1
|
||||
if (index < GX_VA_TEX4MTXIDX) {
|
||||
GX_CP_LOAD_REG(GX_CP_REG_MTXIDXA, __GXData->matIdxA);
|
||||
GX_XF_LOAD_REG(GX_XF_REG_MATRIXINDEX0, __GXData->matIdxA);
|
||||
} else {
|
||||
GX_CP_LOAD_REG(GX_CP_REG_MTXIDXB, __GXData->matIdxB);
|
||||
GX_XF_LOAD_REG(GX_XF_REG_MATRIXINDEX1, __GXData->matIdxB);
|
||||
}
|
||||
|
||||
__GXData->bpSentNot = GX_TRUE;
|
||||
}
|
@ -522,7 +522,7 @@ void drawDepth(view_class* view, view_port_class* viewport, int depth) {
|
||||
GXCopyTex(zbuf, GX_FALSE);
|
||||
|
||||
GXSetTexCopySrc(x, y, w, h);
|
||||
GXSetTexCopyDst(hw, hh, mDoGph_gInf_c::getFrameBufferTimg()->format, GX_TRUE);
|
||||
GXSetTexCopyDst(hw, hh, (GXTexFmt)mDoGph_gInf_c::getFrameBufferTimg()->format, GX_TRUE);
|
||||
GXCopyTex(fbbuf, GX_FALSE);
|
||||
|
||||
GXInitTexObj(mDoGph_gInf_c::getZbufferTexObj(), zbuf, w, h, GX_TF_IA8, GX_CLAMP, GX_CLAMP, GX_FALSE);
|
||||
@ -933,7 +933,7 @@ bool mDoGph_screenCapture() {
|
||||
|
||||
setUpRectangle();
|
||||
GXSetTexCopySrc(centerX - sizeW, centerY - sizeH, sizeW2, sizeH2);
|
||||
GXSetTexCopyDst(sizeW, sizeH, mCaptureCaptureFormat, GX_TRUE);
|
||||
GXSetTexCopyDst(sizeW, sizeH, (_GXTexFmt)mCaptureCaptureFormat, GX_TRUE);
|
||||
DCInvalidateRange(mCaptureCaptureBuffer, mCaptureCaptureSize);
|
||||
GXCopyTex(mCaptureCaptureBuffer, GX_FALSE);
|
||||
GXPixModeSync();
|
||||
|
Loading…
Reference in New Issue
Block a user