mirror of
https://github.com/blawar/GLideN64.git
synced 2024-06-25 22:09:35 +00:00
Correct lighting for CBFD.
Code refactoring.
This commit is contained in:
parent
b036a8296e
commit
31e2c7e11a
|
@ -138,6 +138,7 @@ void RSP_ProcessDList()
|
|||
gSP.status[0] = gSP.status[1] = gSP.status[2] = gSP.status[3] = 0;
|
||||
gSP.changed |= CHANGED_MATRIX | CHANGED_LIGHT | CHANGED_LOOKAT;
|
||||
gSP.tri_num = 0;
|
||||
gSP.cbfd.advancedLighting = false;
|
||||
gDP.changed &= ~CHANGED_CPU_FB_WRITE;
|
||||
gDPSetTexturePersp(G_TP_PERSP);
|
||||
|
||||
|
|
183
src/gSP.cpp
183
src/gSP.cpp
|
@ -511,26 +511,34 @@ void gSPLightVertexStandard(u32 v, SPVertex * spVtx)
|
|||
}
|
||||
|
||||
template <u32 VNUM>
|
||||
void gSPLightVertexCBFD(u32 v, SPVertex * spVtx)
|
||||
void gSPLightVertexCBFD_basic(u32 v, SPVertex * spVtx)
|
||||
{
|
||||
for (int j = 0; j < VNUM; ++j) {
|
||||
SPVertex & vtx = spVtx[v + j];
|
||||
vtx.HWLight = 0;
|
||||
if (vtx.flag < 0)
|
||||
continue;
|
||||
|
||||
f32 r = gSP.lights.rgb[gSP.numLights][R];
|
||||
f32 g = gSP.lights.rgb[gSP.numLights][G];
|
||||
f32 b = gSP.lights.rgb[gSP.numLights][B];
|
||||
f32 recip = FIXED2FLOATRECIP16;
|
||||
const f32 vPos[3] = {
|
||||
(vtx.x + gSP.cbfd.vertexCoordMod[ 8])*gSP.cbfd.vertexCoordMod[12],
|
||||
(vtx.y + gSP.cbfd.vertexCoordMod[ 9])*gSP.cbfd.vertexCoordMod[13],
|
||||
(vtx.z + gSP.cbfd.vertexCoordMod[10])*gSP.cbfd.vertexCoordMod[14]
|
||||
};
|
||||
|
||||
for (u32 l = 0; l < gSP.numLights; ++l) {
|
||||
const f32 vx = (vtx.x + gSP.vertexCoordMod[8])*gSP.vertexCoordMod[12] - gSP.lights.pos_xyzw[l][X];
|
||||
const f32 vy = (vtx.y + gSP.vertexCoordMod[9])*gSP.vertexCoordMod[13] - gSP.lights.pos_xyzw[l][Y];
|
||||
const f32 vz = (vtx.z + gSP.vertexCoordMod[10])*gSP.vertexCoordMod[14] - gSP.lights.pos_xyzw[l][Z];
|
||||
const f32 vw = (vtx.w + gSP.vertexCoordMod[11])*gSP.vertexCoordMod[15] - gSP.lights.pos_xyzw[l][W];
|
||||
const f32 len = (vx*vx + vy*vy + vz*vz + vw*vw) * recip;
|
||||
f32 intensity = gSP.lights.ca[l] / len;
|
||||
if (intensity > 1.0f) intensity = 1.0f;
|
||||
r += gSP.lights.rgb[l][R] * intensity;
|
||||
g += gSP.lights.rgb[l][G] * intensity;
|
||||
b += gSP.lights.rgb[l][B] * intensity;
|
||||
for (int l = gSP.numLights - 2; l >= 0; --l) {
|
||||
const f32 vx = vPos[X] - gSP.lights.pos_xyzw[l][X];
|
||||
const f32 vy = vPos[Y] - gSP.lights.pos_xyzw[l][Y];
|
||||
const f32 vz = vPos[Z] - gSP.lights.pos_xyzw[l][Z];
|
||||
const f32 len = 2.0f * (vx*vx + vy*vy + vz*vz) * FIXED2FLOATRECIP16;
|
||||
f32 intensity = std::min(1.0f, gSP.lights.ca[l] / len);
|
||||
if (intensity > 0.0f) {
|
||||
r += gSP.lights.rgb[l][R] * intensity;
|
||||
g += gSP.lights.rgb[l][G] * intensity;
|
||||
b += gSP.lights.rgb[l][B] * intensity;
|
||||
}
|
||||
}
|
||||
|
||||
r = min(1.0f, r);
|
||||
|
@ -540,16 +548,69 @@ void gSPLightVertexCBFD(u32 v, SPVertex * spVtx)
|
|||
vtx.r *= r;
|
||||
vtx.g *= g;
|
||||
vtx.b *= b;
|
||||
}
|
||||
}
|
||||
|
||||
template <u32 VNUM>
|
||||
void gSPLightVertexCBFD_advanced(u32 v, SPVertex * spVtx)
|
||||
{
|
||||
for (int j = 0; j < VNUM; ++j) {
|
||||
SPVertex & vtx = spVtx[v + j];
|
||||
vtx.HWLight = 0;
|
||||
if (vtx.flag < 0)
|
||||
continue;
|
||||
|
||||
const f32 vPos[3] = {
|
||||
(vtx.x + gSP.cbfd.vertexCoordMod[ 8])*gSP.cbfd.vertexCoordMod[12],
|
||||
(vtx.y + gSP.cbfd.vertexCoordMod[ 9])*gSP.cbfd.vertexCoordMod[13],
|
||||
(vtx.z + gSP.cbfd.vertexCoordMod[10])*gSP.cbfd.vertexCoordMod[14]
|
||||
};
|
||||
int l = gSP.numLights;
|
||||
f32 r = gSP.lights.rgb[l][R];
|
||||
f32 g = gSP.lights.rgb[l][G];
|
||||
f32 b = gSP.lights.rgb[l][B];
|
||||
--l;
|
||||
f32 intensity = std::min(1.0f, DotProduct(&vtx.nx, gSP.lights.i_xyz[l]));
|
||||
if (intensity > 0.0f) {
|
||||
r += gSP.lights.rgb[l][R] * intensity;
|
||||
g += gSP.lights.rgb[l][G] * intensity;
|
||||
b += gSP.lights.rgb[l][B] * intensity;
|
||||
}
|
||||
|
||||
while (--l >= 0) {
|
||||
const f32 vx = vPos[X] - gSP.lights.pos_xyzw[l][X];
|
||||
const f32 vy = vPos[Y] - gSP.lights.pos_xyzw[l][Y];
|
||||
const f32 vz = vPos[Z] - gSP.lights.pos_xyzw[l][Z];
|
||||
const f32 len = 2.0f * (vx*vx + vy*vy + vz*vz) * FIXED2FLOATRECIP16;
|
||||
intensity = std::min(1.0f, gSP.lights.ca[l] / len);
|
||||
if ((gSP.geometryMode & G_POINT_LIGHTING) != 0)
|
||||
intensity *= std::min(1.0f, DotProduct(&vtx.nx, gSP.lights.i_xyz[l]));;
|
||||
if (intensity > 0.0f) {
|
||||
r += gSP.lights.rgb[l][R] * intensity;
|
||||
g += gSP.lights.rgb[l][G] * intensity;
|
||||
b += gSP.lights.rgb[l][B] * intensity;
|
||||
}
|
||||
}
|
||||
|
||||
r = min(1.0f, r);
|
||||
g = min(1.0f, g);
|
||||
b = min(1.0f, b);
|
||||
|
||||
vtx.r *= r;
|
||||
vtx.g *= g;
|
||||
vtx.b *= b;
|
||||
}
|
||||
}
|
||||
|
||||
template <u32 VNUM>
|
||||
void gSPLightVertex(u32 _v, SPVertex * _spVtx)
|
||||
{
|
||||
if (g_ConkerUcode)
|
||||
gSPLightVertexCBFD<VNUM>(_v, _spVtx);
|
||||
else
|
||||
if (g_ConkerUcode) {
|
||||
if (gSP.cbfd.advancedLighting)
|
||||
gSPLightVertexCBFD_advanced<VNUM>(_v, _spVtx);
|
||||
else
|
||||
gSPLightVertexCBFD_basic<VNUM>(_v, _spVtx);
|
||||
} else
|
||||
gSPLightVertexStandard<VNUM>(_v, _spVtx);
|
||||
}
|
||||
|
||||
|
@ -617,59 +678,15 @@ void gSPPointLightVertexZeldaMM(u32 v, float _vecPos[VNUM][4], SPVertex * spVtx)
|
|||
}
|
||||
}
|
||||
|
||||
template <u32 VNUM>
|
||||
void gSPPointLightVertexCBFD(u32 v, SPVertex * spVtx)
|
||||
{
|
||||
f32 intensity = 0.0f;
|
||||
for (int j = 0; j < VNUM; ++j) {
|
||||
SPVertex & vtx = spVtx[v + j];
|
||||
f32 r = gSP.lights.rgb[gSP.numLights][R];
|
||||
f32 g = gSP.lights.rgb[gSP.numLights][G];
|
||||
f32 b = gSP.lights.rgb[gSP.numLights][B];
|
||||
|
||||
for (u32 l = 0; l < gSP.numLights - 1; ++l) {
|
||||
intensity = DotProduct(&vtx.nx, gSP.lights.xyz[l]);
|
||||
if ((gSP.lights.rgb[l][R] == 0.0f && gSP.lights.rgb[l][G] == 0.0f && gSP.lights.rgb[l][B] == 0.0f) || intensity < 0.0f)
|
||||
continue;
|
||||
if (gSP.lights.ca[l] > 0.0f) {
|
||||
const f32 vx = (vtx.x + gSP.vertexCoordMod[8])*gSP.vertexCoordMod[12] - gSP.lights.pos_xyzw[l][X];
|
||||
const f32 vy = (vtx.y + gSP.vertexCoordMod[9])*gSP.vertexCoordMod[13] - gSP.lights.pos_xyzw[l][Y];
|
||||
const f32 vz = (vtx.z + gSP.vertexCoordMod[10])*gSP.vertexCoordMod[14] - gSP.lights.pos_xyzw[l][Z];
|
||||
const f32 vw = (vtx.w + gSP.vertexCoordMod[11])*gSP.vertexCoordMod[15] - gSP.lights.pos_xyzw[l][W];
|
||||
const f32 len = _FIXED2FLOAT((vx*vx + vy*vy + vz*vz + vw*vw),16);
|
||||
float p_i = gSP.lights.ca[l] / len;
|
||||
if (p_i > 1.0f) p_i = 1.0f;
|
||||
intensity *= p_i;
|
||||
}
|
||||
r += gSP.lights.rgb[l][R] * intensity;
|
||||
g += gSP.lights.rgb[l][G] * intensity;
|
||||
b += gSP.lights.rgb[l][B] * intensity;
|
||||
}
|
||||
|
||||
intensity = DotProduct(&vtx.nx, gSP.lights.i_xyz[gSP.numLights - 1]);
|
||||
if ((gSP.lights.i_xyz[gSP.numLights - 1][R] != 0.0 || gSP.lights.i_xyz[gSP.numLights - 1][G] != 0.0 || gSP.lights.i_xyz[gSP.numLights - 1][B] != 0.0) && intensity > 0) {
|
||||
r += gSP.lights.rgb[gSP.numLights - 1][R] * intensity;
|
||||
g += gSP.lights.rgb[gSP.numLights - 1][G] * intensity;
|
||||
b += gSP.lights.rgb[gSP.numLights - 1][B] * intensity;
|
||||
}
|
||||
|
||||
r = min(1.0f, r);
|
||||
g = min(1.0f, g);
|
||||
b = min(1.0f, b);
|
||||
|
||||
vtx.r *= r;
|
||||
vtx.g *= g;
|
||||
vtx.b *= b;
|
||||
vtx.HWLight = 0;
|
||||
}
|
||||
}
|
||||
|
||||
template <u32 VNUM>
|
||||
void gSPPointLightVertex(u32 _v, float _vecPos[VNUM][4], SPVertex * _spVtx)
|
||||
{
|
||||
if (g_ConkerUcode)
|
||||
gSPPointLightVertexCBFD<VNUM>(_v, _spVtx);
|
||||
else
|
||||
if (g_ConkerUcode) {
|
||||
if (gSP.cbfd.advancedLighting)
|
||||
gSPLightVertexCBFD_advanced<VNUM>(_v, _spVtx);
|
||||
else
|
||||
gSPLightVertexCBFD_basic<VNUM>(_v, _spVtx);
|
||||
} else
|
||||
gSPPointLightVertexZeldaMM<VNUM>(_v, _vecPos, _spVtx);
|
||||
}
|
||||
|
||||
|
@ -1070,10 +1087,11 @@ u32 gSPLoadCBFDVertexData(const Vertex *orgVtx, SPVertex * spVtx, u32 v0, u32 vi
|
|||
vtx.z = orgVtx->z;
|
||||
vtx.s = _FIXED2FLOAT( orgVtx->s, 5 );
|
||||
vtx.t = _FIXED2FLOAT( orgVtx->t, 5 );
|
||||
vtx.flag = orgVtx->flag;
|
||||
if (gSP.geometryMode & G_LIGHTING) {
|
||||
const u32 normaleAddrOffset = ((vi+j)<<1);
|
||||
vtx.nx = _FIXED2FLOATCOLOR(((s8*)RDRAM)[(gSP.vertexNormalBase + normaleAddrOffset + 0) ^ 3], 7);
|
||||
vtx.ny = _FIXED2FLOATCOLOR(((s8*)RDRAM)[(gSP.vertexNormalBase + normaleAddrOffset + 1) ^ 3], 7);
|
||||
vtx.nx = _FIXED2FLOATCOLOR(((s8*)RDRAM)[(gSP.cbfd.vertexNormalBase + normaleAddrOffset + 0) ^ 3], 7);
|
||||
vtx.ny = _FIXED2FLOATCOLOR(((s8*)RDRAM)[(gSP.cbfd.vertexNormalBase + normaleAddrOffset + 1) ^ 3], 7);
|
||||
vtx.nz = _FIXED2FLOATCOLOR((s8)(orgVtx->flag & 0xFF), 7);
|
||||
}
|
||||
vtx.r = _FIXED2FLOATCOLOR(orgVtx->color.r, 8);
|
||||
|
@ -1433,13 +1451,6 @@ void gSPSetVertexColorBase( u32 base )
|
|||
DebugMsg(DEBUG_NORMAL, "gSPSetVertexColorBase( 0x%08X );\n", base );
|
||||
}
|
||||
|
||||
void gSPSetVertexNormaleBase( u32 base )
|
||||
{
|
||||
gSP.vertexNormalBase = RSP_SegmentToPhysical( base );
|
||||
|
||||
DebugMsg(DEBUG_NORMAL, "gSPSetVertexNormaleBase( 0x%08X );\n", base );
|
||||
}
|
||||
|
||||
void gSPDMATriangles( u32 tris, u32 n ){
|
||||
const u32 address = RSP_SegmentToPhysical( tris );
|
||||
|
||||
|
@ -1713,28 +1724,6 @@ void gSPPerspNormalize( u16 scale )
|
|||
DebugMsg(DEBUG_NORMAL| DEBUG_IGNORED, "gSPPerspNormalize( %i );\n", scale);
|
||||
}
|
||||
|
||||
void gSPCoordMod(u32 _w0, u32 _w1)
|
||||
{
|
||||
DebugMsg(DEBUG_NORMAL, "gSPCoordMod( %u, %u );\n", _w0, _w1);
|
||||
if ((_w0 & 8) != 0)
|
||||
return;
|
||||
u32 idx = _SHIFTR(_w0, 1, 2);
|
||||
u32 pos = _w0&0x30;
|
||||
if (pos == 0) {
|
||||
gSP.vertexCoordMod[0+idx] = (f32)(s16)_SHIFTR(_w1, 16, 16);
|
||||
gSP.vertexCoordMod[1+idx] = (f32)(s16)_SHIFTR(_w1, 0, 16);
|
||||
} else if (pos == 0x10) {
|
||||
assert(idx < 3);
|
||||
gSP.vertexCoordMod[4+idx] = _FIXED2FLOAT(_SHIFTR(_w1, 16, 16),16);
|
||||
gSP.vertexCoordMod[5+idx] = _FIXED2FLOAT(_SHIFTR(_w1, 0, 16),16);
|
||||
gSP.vertexCoordMod[12+idx] = gSP.vertexCoordMod[0+idx] + gSP.vertexCoordMod[4+idx];
|
||||
gSP.vertexCoordMod[13+idx] = gSP.vertexCoordMod[1+idx] + gSP.vertexCoordMod[5+idx];
|
||||
} else if (pos == 0x20) {
|
||||
gSP.vertexCoordMod[8+idx] = (f32)(s16)_SHIFTR(_w1, 16, 16);
|
||||
gSP.vertexCoordMod[9+idx] = (f32)(s16)_SHIFTR(_w1, 0, 16);
|
||||
}
|
||||
}
|
||||
|
||||
void gSPTexture( f32 sc, f32 tc, u32 level, u32 tile, u32 on )
|
||||
{
|
||||
gSP.texture.on = on;
|
||||
|
|
11
src/gSP.h
11
src/gSP.h
|
@ -134,9 +134,12 @@ struct gSPInfo
|
|||
|
||||
u32 clipRatio;
|
||||
|
||||
// CBFD
|
||||
u32 vertexNormalBase;
|
||||
f32 vertexCoordMod[16];
|
||||
struct
|
||||
{
|
||||
u32 vertexNormalBase;
|
||||
f32 vertexCoordMod[16];
|
||||
bool advancedLighting;
|
||||
} cbfd;
|
||||
|
||||
u32 textureCoordScaleOrg;
|
||||
u32 textureCoordScale[2];
|
||||
|
@ -194,8 +197,6 @@ void gSPSetStatus(u32 sid, u32 val);
|
|||
void gSPSetDMAOffsets( u32 mtxoffset, u32 vtxoffset );
|
||||
void gSPSetDMATexOffset(u32 _addr);
|
||||
void gSPSetVertexColorBase( u32 base );
|
||||
void gSPSetVertexNormaleBase( u32 base );
|
||||
void gSPCoordMod(u32 _w0, u32 _w1);
|
||||
void gSPCombineMatrices(u32 _mode);
|
||||
|
||||
void gSPTriangle(s32 v0, s32 v1, s32 v2);
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "gDP.h"
|
||||
#include "GBI.h"
|
||||
|
||||
static
|
||||
void F3DEX2CBFD_Vtx( u32 w0, u32 w1 )
|
||||
{
|
||||
u32 n = _SHIFTR( w0, 12, 8 );
|
||||
|
@ -18,6 +19,31 @@ void F3DEX2CBFD_Vtx( u32 w0, u32 w1 )
|
|||
gSPCBFDVertex( w1, n, _SHIFTR( w0, 1, 7 ) - n );
|
||||
}
|
||||
|
||||
static
|
||||
void F3DEX2CBFD_CoordMod(u32 _w0, u32 _w1)
|
||||
{
|
||||
DebugMsg(DEBUG_NORMAL, "gSPCoordMod( %u, %u );\n", _w0, _w1);
|
||||
if ((_w0 & 8) != 0)
|
||||
return;
|
||||
u32 idx = _SHIFTR(_w0, 1, 2);
|
||||
u32 pos = _w0 & 0x30;
|
||||
if (pos == 0) {
|
||||
gSP.cbfd.vertexCoordMod[0 + idx] = (f32)(s16)_SHIFTR(_w1, 16, 16);
|
||||
gSP.cbfd.vertexCoordMod[1 + idx] = (f32)(s16)_SHIFTR(_w1, 0, 16);
|
||||
}
|
||||
else if (pos == 0x10) {
|
||||
gSP.cbfd.vertexCoordMod[4 + idx] = _FIXED2FLOAT(_SHIFTR(_w1, 16, 16), 16);
|
||||
gSP.cbfd.vertexCoordMod[5 + idx] = _FIXED2FLOAT(_SHIFTR(_w1, 0, 16), 16);
|
||||
gSP.cbfd.vertexCoordMod[12 + idx] = gSP.cbfd.vertexCoordMod[0 + idx] + gSP.cbfd.vertexCoordMod[4 + idx];
|
||||
gSP.cbfd.vertexCoordMod[13 + idx] = gSP.cbfd.vertexCoordMod[1 + idx] + gSP.cbfd.vertexCoordMod[5 + idx];
|
||||
}
|
||||
else if (pos == 0x20) {
|
||||
gSP.cbfd.vertexCoordMod[8 + idx] = (f32)(s16)_SHIFTR(_w1, 16, 16);
|
||||
gSP.cbfd.vertexCoordMod[9 + idx] = (f32)(s16)_SHIFTR(_w1, 0, 16);
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void F3DEX2CBFD_MoveWord( u32 w0, u32 w1 )
|
||||
{
|
||||
switch (_SHIFTR( w0, 16, 8 ))
|
||||
|
@ -38,11 +64,12 @@ void F3DEX2CBFD_MoveWord( u32 w0, u32 w1 )
|
|||
gSPPerspNormalize( w1 );
|
||||
break;
|
||||
case G_MW_COORD_MOD:
|
||||
gSPCoordMod( w0, w1 );
|
||||
F3DEX2CBFD_CoordMod( w0, w1 );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void F3DEX2CBFD_MoveMem( u32 w0, u32 w1 )
|
||||
{
|
||||
switch (_SHIFTR( w0, 0, 8 ))
|
||||
|
@ -61,11 +88,13 @@ void F3DEX2CBFD_MoveMem( u32 w0, u32 w1 )
|
|||
}
|
||||
break;
|
||||
case G_MV_NORMALES:
|
||||
gSPSetVertexNormaleBase(w1);
|
||||
gSP.cbfd.vertexNormalBase = RSP_SegmentToPhysical(w1);
|
||||
DebugMsg(DEBUG_NORMAL, "gSPSetVertexNormaleBase( 0x%08X );\n", w1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void F3DEX2CBFD_Tri4( u32 w0, u32 w1 )
|
||||
{
|
||||
gSP4Triangles( _SHIFTR( w0, 23, 5 ), _SHIFTR( w0, 18, 5 ), (_SHIFTR( w0, 15, 3 )<<2)|_SHIFTR( w1, 30, 2 ),
|
||||
|
@ -74,6 +103,12 @@ void F3DEX2CBFD_Tri4( u32 w0, u32 w1 )
|
|||
_SHIFTR( w1, 10, 5 ), _SHIFTR( w1, 5, 5 ), _SHIFTR( w1, 0, 5 ) );
|
||||
}
|
||||
|
||||
static
|
||||
void F3DEX2CBFD_SwitchLightingMode(u32, u32)
|
||||
{
|
||||
gSP.cbfd.advancedLighting = true;
|
||||
}
|
||||
|
||||
void F3DEX2CBFD_Init()
|
||||
{
|
||||
gSPSetupFunctions();
|
||||
|
@ -90,7 +125,7 @@ void F3DEX2CBFD_Init()
|
|||
GBI_SetGBI( G_SPNOOP, F3DEX2_SPNOOP, F3D_SPNoOp );
|
||||
GBI_SetGBI( G_ENDDL, F3DEX2_ENDDL, F3D_EndDL );
|
||||
GBI_SetGBI( G_DL, F3DEX2_DL, F3D_DList );
|
||||
GBI_SetGBI( G_LOAD_UCODE, F3DEX2_LOAD_UCODE, F3DEX_Load_uCode );
|
||||
GBI_SetGBI( G_LOAD_UCODE, F3DEX2_LOAD_UCODE, F3DEX2CBFD_SwitchLightingMode );
|
||||
GBI_SetGBI( G_MOVEMEM, F3DEX2_MOVEMEM, F3DEX2CBFD_MoveMem );
|
||||
GBI_SetGBI( G_MOVEWORD, F3DEX2_MOVEWORD, F3DEX2CBFD_MoveWord );
|
||||
GBI_SetGBI( G_MTX, F3DEX2_MTX, F3DEX2_Mtx );
|
||||
|
|
Loading…
Reference in New Issue
Block a user