mirror of
https://github.com/blawar/GLideN64.git
synced 2024-07-04 10:03:36 +00:00
Add F3DFLX2 ucode for F-Zero. Implement F3DFLX2 lighting method.
This commit is contained in:
parent
ef6f470df7
commit
47d718f287
|
@ -289,6 +289,7 @@
|
|||
<ClCompile Include="..\..\src\F3DEX2ACCLAIM.cpp" />
|
||||
<ClCompile Include="..\..\src\F3DEX2CBFD.cpp" />
|
||||
<ClCompile Include="..\..\src\F3DEX2MM.cpp" />
|
||||
<ClCompile Include="..\..\src\F3DFLX2.cpp" />
|
||||
<ClCompile Include="..\..\src\F3DGOLDEN.cpp" />
|
||||
<ClCompile Include="..\..\src\F3DSETA.cpp" />
|
||||
<ClCompile Include="..\..\src\F3DBETA.cpp" />
|
||||
|
@ -432,6 +433,7 @@
|
|||
<ClInclude Include="..\..\src\F3DEX2ACCLAIM.h" />
|
||||
<ClInclude Include="..\..\src\F3DEX2CBFD.h" />
|
||||
<ClInclude Include="..\..\src\F3DEX2MM.h" />
|
||||
<ClInclude Include="..\..\src\F3DFLX2.h" />
|
||||
<ClInclude Include="..\..\src\F3DGOLDEN.h" />
|
||||
<ClInclude Include="..\..\src\F3DSETA.h" />
|
||||
<ClInclude Include="..\..\src\F3DSWRS.h" />
|
||||
|
|
|
@ -371,6 +371,9 @@
|
|||
<ClCompile Include="..\..\src\F3DSWRS.cpp">
|
||||
<Filter>Source Files\uCodes</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\F3DFLX2.cpp">
|
||||
<Filter>Source Files\uCodes</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\src\3DMath.h">
|
||||
|
@ -688,5 +691,8 @@
|
|||
<ClInclude Include="..\..\src\F3DSWRS.h">
|
||||
<Filter>Header Files\uCodes</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\F3DFLX2.h">
|
||||
<Filter>Header Files\uCodes</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -31,6 +31,7 @@ set(GLideN64_SOURCES
|
|||
F3DEX2ACCLAIM.cpp
|
||||
F3DEX2CBFD.cpp
|
||||
F3DEX2MM.cpp
|
||||
F3DFLX2.cpp
|
||||
F3DGOLDEN.cpp
|
||||
F3DSWRS.cpp
|
||||
F3DTEXA.cpp
|
||||
|
|
|
@ -134,6 +134,7 @@ void F3DEX2_GeometryMode( u32 w0, u32 w1 )
|
|||
|
||||
void F3DEX2_DMAIO( u32 w0, u32 w1 )
|
||||
{
|
||||
gSP.DMAIO_address = RSP_SegmentToPhysical(w1);
|
||||
}
|
||||
|
||||
void F3DEX2_Special_1( u32 w0, u32 w1 )
|
||||
|
|
90
src/F3DFLX2.cpp
Normal file
90
src/F3DFLX2.cpp
Normal file
|
@ -0,0 +1,90 @@
|
|||
#include "GLideN64.h"
|
||||
#include "3DMath.h"
|
||||
#include "F3D.h"
|
||||
#include "F3DEX.h"
|
||||
#include "F3DEX2.h"
|
||||
#include "F3DFLX2.h"
|
||||
#include "RSP.h"
|
||||
#include "gSP.h"
|
||||
#include "DebugDump.h"
|
||||
|
||||
inline
|
||||
void F3DFLX2_LoadAlphaLight(u32 _a)
|
||||
{
|
||||
const u32 address = RSP_SegmentToPhysical(_a);
|
||||
|
||||
const s16* const data = reinterpret_cast<const s16*>(RDRAM + address);
|
||||
|
||||
// gSP.lookat.xyz[0][X] = static_cast<f32>(data[4 ^ 1]);
|
||||
// gSP.lookat.xyz[0][Y] = static_cast<f32>(data[5 ^ 1]);
|
||||
// gSP.lookat.xyz[0][Z] = static_cast<f32>(data[6 ^ 1]);
|
||||
gSP.lookat.xyz[0][X] = _FIXED2FLOAT(data[4 ^ 1], 8);
|
||||
gSP.lookat.xyz[0][Y] = _FIXED2FLOAT(data[5 ^ 1], 8);
|
||||
gSP.lookat.xyz[0][Z] = _FIXED2FLOAT(data[6 ^ 1], 8);
|
||||
|
||||
gSP.lookatEnable = true;
|
||||
|
||||
Normalize(gSP.lookat.xyz[0]);
|
||||
gSP.changed |= CHANGED_LOOKAT;
|
||||
DebugMsg(DEBUG_NORMAL, "F3DFLX2_LoadAlphaLight( 0x%08X );\n", _a);
|
||||
}
|
||||
|
||||
static
|
||||
void F3DFLX2_MoveMem(u32 w0, u32 w1)
|
||||
{
|
||||
switch (_SHIFTR(w0, 0, 8))
|
||||
{
|
||||
case G_MV_LIGHT:
|
||||
{
|
||||
const u32 offset = (w0 >> 5) & 0x7F8;
|
||||
const u32 n = offset / 24;
|
||||
if (n == 1)
|
||||
F3DFLX2_LoadAlphaLight(w1);
|
||||
else
|
||||
gSPLight(w1, n - 1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
F3DEX2_MoveMem(w0, w1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void F3DFLX2_Init()
|
||||
{
|
||||
gSPSetupFunctions();
|
||||
// Set GeometryMode flags
|
||||
GBI_InitFlags( F3DEX2 );
|
||||
|
||||
GBI.PCStackSize = 18;
|
||||
|
||||
// GBI Command Command Value Command Function
|
||||
GBI_SetGBI( G_RDPHALF_2, F3DEX2_RDPHALF_2, F3D_RDPHalf_2 );
|
||||
GBI_SetGBI( G_SETOTHERMODE_H, F3DEX2_SETOTHERMODE_H, F3DEX2_SetOtherMode_H );
|
||||
GBI_SetGBI( G_SETOTHERMODE_L, F3DEX2_SETOTHERMODE_L, F3DEX2_SetOtherMode_L );
|
||||
GBI_SetGBI( G_RDPHALF_1, F3DEX2_RDPHALF_1, F3D_RDPHalf_1 );
|
||||
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_MOVEMEM, F3DEX2_MOVEMEM, F3DFLX2_MoveMem );
|
||||
GBI_SetGBI( G_MOVEWORD, F3DEX2_MOVEWORD, F3DEX2_MoveWord );
|
||||
GBI_SetGBI( G_MTX, F3DEX2_MTX, F3DEX2_Mtx );
|
||||
GBI_SetGBI( G_GEOMETRYMODE, F3DEX2_GEOMETRYMODE, F3DEX2_GeometryMode );
|
||||
GBI_SetGBI( G_POPMTX, F3DEX2_POPMTX, F3DEX2_PopMtx );
|
||||
GBI_SetGBI( G_TEXTURE, F3DEX2_TEXTURE, F3DEX2_Texture );
|
||||
GBI_SetGBI( G_DMA_IO, F3DEX2_DMA_IO, F3DEX2_DMAIO );
|
||||
GBI_SetGBI( G_SPECIAL_1, F3DEX2_SPECIAL_1, F3DEX2_Special_1 );
|
||||
GBI_SetGBI( G_SPECIAL_2, F3DEX2_SPECIAL_2, F3DEX2_Special_2 );
|
||||
GBI_SetGBI( G_SPECIAL_3, F3DEX2_SPECIAL_3, F3DEX2_Special_3 );
|
||||
|
||||
GBI_SetGBI( G_VTX, F3DEX2_VTX, F3DEX2_Vtx );
|
||||
GBI_SetGBI( G_MODIFYVTX, F3DEX2_MODIFYVTX, F3DEX_ModifyVtx );
|
||||
GBI_SetGBI( G_CULLDL, F3DEX2_CULLDL, F3DEX_CullDL );
|
||||
GBI_SetGBI( G_BRANCH_Z, F3DEX2_BRANCH_Z, F3DEX_Branch_Z );
|
||||
GBI_SetGBI( G_TRI1, F3DEX2_TRI1, F3DEX2_Tri1 );
|
||||
GBI_SetGBI( G_TRI2, F3DEX2_TRI2, F3DEX_Tri2 );
|
||||
GBI_SetGBI( G_QUAD, F3DEX2_QUAD, F3DEX2_Quad );
|
||||
GBI_SetGBI( G_LINE3D, F3DEX2_LINE3D, F3DEX2_Line3D );
|
||||
}
|
6
src/F3DFLX2.h
Normal file
6
src/F3DFLX2.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
#ifndef F3DFLX2_H
|
||||
#define F3DFLX2_H
|
||||
|
||||
void F3DFLX2_Init();
|
||||
|
||||
#endif // F3DFLX2_H
|
|
@ -29,6 +29,7 @@
|
|||
#include "F3DTEXA.h"
|
||||
#include "F3DEX2ACCLAIM.h"
|
||||
#include "F3DSWRS.h"
|
||||
#include "F3DFLX2.h"
|
||||
#include "ZSort.h"
|
||||
#include "CRC.h"
|
||||
#include "Log.h"
|
||||
|
@ -193,7 +194,8 @@ void GBIInfo::_makeCurrent(MicrocodeInfo * _pCurrent)
|
|||
case F3DTEXA: F3DTEXA_Init(); break;
|
||||
case T3DUX: F3D_Init(); break;
|
||||
case F3DEX2ACCLAIM: F3DEX2ACCLAIM_Init(); break;
|
||||
case F3DSWRS: F3DSWRS_Init(); break;
|
||||
case F3DSWRS: F3DSWRS_Init(); break;
|
||||
case F3DFLX2: F3DFLX2_Init(); break;
|
||||
}
|
||||
|
||||
if (gfxContext.isSupported(graphics::SpecialFeatures::NearPlaneClipping)) {
|
||||
|
@ -249,7 +251,6 @@ void GBIInfo::loadMicrocode(u32 uc_start, u32 uc_dstart, u16 uc_dsize)
|
|||
current.dataSize = uc_dsize;
|
||||
current.NoN = false;
|
||||
current.negativeY = true;
|
||||
current.textureGen = true;
|
||||
current.texturePersp = true;
|
||||
current.combineMatrices = false;
|
||||
current.type = NONE;
|
||||
|
@ -298,8 +299,8 @@ void GBIInfo::loadMicrocode(u32 uc_start, u32 uc_dstart, u16 uc_dsize)
|
|||
if (uc_str[35] == 'H')
|
||||
current.combineMatrices = true;
|
||||
}
|
||||
if (strncmp(&uc_str[14], "F3DF", 4) == 0)
|
||||
current.textureGen = false;
|
||||
if (strncmp(&uc_str[14], "F3DFLX", 6) == 0)
|
||||
type = F3DFLX2;
|
||||
else if (strncmp(&uc_str[14], "F3DZEX", 6) == 0) {
|
||||
// Zelda games
|
||||
// Check ucode version
|
||||
|
|
|
@ -28,8 +28,9 @@
|
|||
#define T3DUX 19
|
||||
#define F3DEX2ACCLAIM 21
|
||||
#define F3DAM 22
|
||||
#define F3DSWRS 23
|
||||
#define NONE 24
|
||||
#define F3DSWRS 23
|
||||
#define F3DFLX2 24
|
||||
#define NONE 25
|
||||
|
||||
// Fixed point conversion factors
|
||||
#define FIXED2FLOATRECIP1 0.5f
|
||||
|
@ -499,7 +500,6 @@ struct MicrocodeInfo
|
|||
u32 crc;
|
||||
bool NoN;
|
||||
bool negativeY;
|
||||
bool textureGen;
|
||||
bool texturePersp;
|
||||
bool combineMatrices;
|
||||
};
|
||||
|
@ -517,7 +517,6 @@ struct GBIInfo
|
|||
bool isHWLSupported() const;
|
||||
bool isNoN() const { return m_pCurrent != nullptr ? m_pCurrent->NoN : false; }
|
||||
bool isNegativeY() const { return m_pCurrent != nullptr ? m_pCurrent->negativeY : true; }
|
||||
bool isTextureGen() const { return m_pCurrent != nullptr ? m_pCurrent->textureGen: true; }
|
||||
bool isTexturePersp() const { return m_pCurrent != nullptr ? m_pCurrent->texturePersp: true; }
|
||||
bool isCombineMatrices() const { return m_pCurrent != nullptr ? m_pCurrent->combineMatrices: false; }
|
||||
|
||||
|
|
|
@ -250,9 +250,6 @@ public:
|
|||
}
|
||||
|
||||
int nFogUsage = ((gSP.geometryMode & G_FOG) != 0) ? 1 : 0;
|
||||
if (!GBI.isTextureGen())
|
||||
// F-Zero ucode seems to always use fog mode when fog is used in blender.
|
||||
nFogUsage |= (gDP.otherMode.c1_m1a == 3 || gDP.otherMode.c1_m2a == 3) ? 1 : 0;
|
||||
if (GBI.getMicrocodeType() == F3DAM) {
|
||||
const s16 fogMode = ((gSP.geometryMode >> 13) & 9) + 0xFFF8;
|
||||
if (fogMode == 0)
|
||||
|
|
99
src/gSP.cpp
99
src/gSP.cpp
|
@ -369,28 +369,37 @@ void gSPProcessVertex4(u32 v)
|
|||
else
|
||||
gSPLightVertex4(v);
|
||||
|
||||
if (GBI.isTextureGen() && (gSP.geometryMode & G_TEXTURE_GEN) != 0) {
|
||||
for(int i = 0; i < 4; ++i) {
|
||||
SPVertex & vtx = drawer.getVertex(v+i);
|
||||
f32 fLightDir[3] = {vtx.nx, vtx.ny, vtx.nz};
|
||||
f32 x, y;
|
||||
if (gSP.lookatEnable) {
|
||||
x = DotProduct(gSP.lookat.i_xyz[0], fLightDir);
|
||||
y = DotProduct(gSP.lookat.i_xyz[1], fLightDir);
|
||||
} else {
|
||||
fLightDir[0] *= 128.0f;
|
||||
fLightDir[1] *= 128.0f;
|
||||
fLightDir[2] *= 128.0f;
|
||||
TransformVectorNormalize(fLightDir, gSP.matrix.modelView[gSP.matrix.modelViewi]);
|
||||
x = fLightDir[0];
|
||||
y = fLightDir[1];
|
||||
if ((gSP.geometryMode & G_TEXTURE_GEN) != 0) {
|
||||
if (GBI.getMicrocodeType() != F3DFLX2) {
|
||||
for(int i = 0; i < 4; ++i) {
|
||||
SPVertex & vtx = drawer.getVertex(v+i);
|
||||
f32 fLightDir[3] = {vtx.nx, vtx.ny, vtx.nz};
|
||||
f32 x, y;
|
||||
if (gSP.lookatEnable) {
|
||||
x = DotProduct(gSP.lookat.i_xyz[0], fLightDir);
|
||||
y = DotProduct(gSP.lookat.i_xyz[1], fLightDir);
|
||||
} else {
|
||||
fLightDir[0] *= 128.0f;
|
||||
fLightDir[1] *= 128.0f;
|
||||
fLightDir[2] *= 128.0f;
|
||||
TransformVectorNormalize(fLightDir, gSP.matrix.modelView[gSP.matrix.modelViewi]);
|
||||
x = fLightDir[0];
|
||||
y = fLightDir[1];
|
||||
}
|
||||
if (gSP.geometryMode & G_TEXTURE_GEN_LINEAR) {
|
||||
vtx.s = acosf(-x) * 325.94931f;
|
||||
vtx.t = acosf(-y) * 325.94931f;
|
||||
} else { // G_TEXTURE_GEN
|
||||
vtx.s = (x + 1.0f) * 512.0f;
|
||||
vtx.t = (y + 1.0f) * 512.0f;
|
||||
}
|
||||
}
|
||||
if (gSP.geometryMode & G_TEXTURE_GEN_LINEAR) {
|
||||
vtx.s = acosf(-x) * 325.94931f;
|
||||
vtx.t = acosf(-y) * 325.94931f;
|
||||
} else { // G_TEXTURE_GEN
|
||||
vtx.s = (x + 1.0f) * 512.0f;
|
||||
vtx.t = (y + 1.0f) * 512.0f;
|
||||
} else {
|
||||
for(int i = 0; i < 4; ++i) {
|
||||
SPVertex & vtx = drawer.getVertex(v+i);
|
||||
const f32 intensity = DotProduct(gSP.lookat.i_xyz[0], &vtx.nx) * 128.0f;
|
||||
const s16 index = static_cast<s16>(intensity);
|
||||
vtx.a = _FIXED2FLOAT(RDRAM[(gSP.DMAIO_address + 128 + index) ^ 3], 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -612,8 +621,8 @@ void gSPProcessVertex(u32 v)
|
|||
DisplayWindow & wnd = dwnd();
|
||||
GraphicsDrawer & drawer = wnd.getDrawer();
|
||||
SPVertex & vtx = drawer.getVertex(v);
|
||||
float vPos[3] = {(float)vtx.x, (float)vtx.y, (float)vtx.z};
|
||||
gSPTransformVertex( &vtx.x, gSP.matrix.combined );
|
||||
f32 vPos[3] = {vtx.x, vtx.y, vtx.z};
|
||||
gSPTransformVertex(&vtx.x, gSP.matrix.combined);
|
||||
|
||||
if (wnd.isAdjustScreen() && (gDP.colorImage.width > VI.width * 98 / 100)) {
|
||||
vtx.x *= wnd.getAdjustScale();
|
||||
|
@ -640,26 +649,32 @@ void gSPProcessVertex(u32 v)
|
|||
else
|
||||
gSPLightVertex(vtx);
|
||||
|
||||
if (GBI.isTextureGen() && (gSP.geometryMode & G_TEXTURE_GEN) != 0) {
|
||||
f32 fLightDir[3] = {vtx.nx, vtx.ny, vtx.nz};
|
||||
f32 x, y;
|
||||
if (gSP.lookatEnable) {
|
||||
x = DotProduct(gSP.lookat.i_xyz[0], fLightDir);
|
||||
y = DotProduct(gSP.lookat.i_xyz[1], fLightDir);
|
||||
if ((gSP.geometryMode & G_TEXTURE_GEN) != 0) {
|
||||
if (GBI.getMicrocodeType() != F3DFLX2) {
|
||||
f32 fLightDir[3] = {vtx.nx, vtx.ny, vtx.nz};
|
||||
f32 x, y;
|
||||
if (gSP.lookatEnable) {
|
||||
x = DotProduct(gSP.lookat.i_xyz[0], fLightDir);
|
||||
y = DotProduct(gSP.lookat.i_xyz[1], fLightDir);
|
||||
} else {
|
||||
fLightDir[0] *= 128.0f;
|
||||
fLightDir[1] *= 128.0f;
|
||||
fLightDir[2] *= 128.0f;
|
||||
TransformVectorNormalize(fLightDir, gSP.matrix.modelView[gSP.matrix.modelViewi]);
|
||||
x = fLightDir[0];
|
||||
y = fLightDir[1];
|
||||
}
|
||||
if (gSP.geometryMode & G_TEXTURE_GEN_LINEAR) {
|
||||
vtx.s = acosf(-x) * 325.94931f;
|
||||
vtx.t = acosf(-y) * 325.94931f;
|
||||
} else { // G_TEXTURE_GEN
|
||||
vtx.s = (x + 1.0f) * 512.0f;
|
||||
vtx.t = (y + 1.0f) * 512.0f;
|
||||
}
|
||||
} else {
|
||||
fLightDir[0] *= 128.0f;
|
||||
fLightDir[1] *= 128.0f;
|
||||
fLightDir[2] *= 128.0f;
|
||||
TransformVectorNormalize(fLightDir, gSP.matrix.modelView[gSP.matrix.modelViewi]);
|
||||
x = fLightDir[0];
|
||||
y = fLightDir[1];
|
||||
}
|
||||
if (gSP.geometryMode & G_TEXTURE_GEN_LINEAR) {
|
||||
vtx.s = acosf(-x) * 325.94931f;
|
||||
vtx.t = acosf(-y) * 325.94931f;
|
||||
} else { // G_TEXTURE_GEN
|
||||
vtx.s = (x + 1.0f) * 512.0f;
|
||||
vtx.t = (y + 1.0f) * 512.0f;
|
||||
const f32 intensity = DotProduct(gSP.lookat.i_xyz[0], &vtx.nx) * 128.0f;
|
||||
const s16 index = static_cast<s16>(intensity);
|
||||
vtx.a = _FIXED2FLOAT(RDRAM[(gSP.DMAIO_address + 128 + index) ^ 3], 8);
|
||||
}
|
||||
}
|
||||
} else if (gSP.geometryMode & G_ACCLAIM_LIGHTING) {
|
||||
|
|
|
@ -134,6 +134,8 @@ struct gSPInfo
|
|||
u32 vtx, mtx, tex_offset, tex_shift, tex_count;
|
||||
} DMAOffsets;
|
||||
|
||||
u32 DMAIO_address;
|
||||
|
||||
// CBFD
|
||||
u32 vertexNormalBase;
|
||||
f32 vertexCoordMod[16];
|
||||
|
|
|
@ -37,6 +37,7 @@ MY_LOCAL_SRC_FILES := \
|
|||
$(SRCDIR)/F3DEX2ACCLAIM.cpp \
|
||||
$(SRCDIR)/F3DEX2CBFD.cpp \
|
||||
$(SRCDIR)/F3DEX2MM.cpp \
|
||||
$(SRCDIR)/F3DFLX2.cpp \
|
||||
$(SRCDIR)/F3DGOLDEN.cpp \
|
||||
$(SRCDIR)/F3DPD.cpp \
|
||||
$(SRCDIR)/F3DSETA.cpp \
|
||||
|
|
Loading…
Reference in New Issue
Block a user