1
0
mirror of https://github.com/blawar/GLideN64.git synced 2024-07-02 09:03:37 +00:00

Add F3DFLX2 ucode for F-Zero. Implement F3DFLX2 lighting method.

This commit is contained in:
Sergey Lipskiy 2017-09-06 17:12:28 +07:00
parent ef6f470df7
commit 47d718f287
12 changed files with 174 additions and 53 deletions

View File

@ -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" />

View File

@ -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>

View File

@ -31,6 +31,7 @@ set(GLideN64_SOURCES
F3DEX2ACCLAIM.cpp
F3DEX2CBFD.cpp
F3DEX2MM.cpp
F3DFLX2.cpp
F3DGOLDEN.cpp
F3DSWRS.cpp
F3DTEXA.cpp

View File

@ -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
View 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
View File

@ -0,0 +1,6 @@
#ifndef F3DFLX2_H
#define F3DFLX2_H
void F3DFLX2_Init();
#endif // F3DFLX2_H

View File

@ -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

View File

@ -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; }

View File

@ -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)

View File

@ -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) {

View File

@ -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];

View File

@ -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 \