Skip to content

Commit

Permalink
Preliminary F3DEX3 LVP support (#2842)
Browse files Browse the repository at this point in the history
* F3DEX3: added initial primitive LVP implementation

* F3DEX3: rework checking for microcode

* F3DEX3: initialize MicrocodeInfo for f3dex3

* F3DEX3: added support for new lights encoding

* F3DEX3: advertise microcode in CMakeFile

* F3DEX3: fixed various nitpicks
  • Loading branch information
aglab2 authored Jun 30, 2024
1 parent 6816621 commit b36c440
Show file tree
Hide file tree
Showing 9 changed files with 492 additions and 54 deletions.
2 changes: 2 additions & 0 deletions projects/msvc/GLideN64.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,7 @@ copy /Y "$(OutDir)$(TargetName).*" "$(Mupen64PluginsDir_x64)")</Command>
<ClCompile Include="..\..\src\uCodes\F3DEX2.cpp" />
<ClCompile Include="..\..\src\uCodes\F3DEX2ACCLAIM.cpp" />
<ClCompile Include="..\..\src\uCodes\F3DEX2CBFD.cpp" />
<ClCompile Include="..\..\src\uCodes\F3DEX3.cpp" />
<ClCompile Include="..\..\src\uCodes\F3DZEX2.cpp" />
<ClCompile Include="..\..\src\uCodes\F3DFLX2.cpp" />
<ClCompile Include="..\..\src\uCodes\F3DGOLDEN.cpp" />
Expand Down Expand Up @@ -542,6 +543,7 @@ copy /Y "$(OutDir)$(TargetName).*" "$(Mupen64PluginsDir_x64)")</Command>
<ClInclude Include="..\..\src\uCodes\F3DEX2.h" />
<ClInclude Include="..\..\src\uCodes\F3DEX2ACCLAIM.h" />
<ClInclude Include="..\..\src\uCodes\F3DEX2CBFD.h" />
<ClInclude Include="..\..\src\uCodes\F3DEX3.h" />
<ClInclude Include="..\..\src\uCodes\F3DZEX2.h" />
<ClInclude Include="..\..\src\uCodes\F3DFLX2.h" />
<ClInclude Include="..\..\src\uCodes\F3DGOLDEN.h" />
Expand Down
6 changes: 6 additions & 0 deletions projects/msvc/GLideN64.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,9 @@
<ClCompile Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_CombinerProgramUniformFactoryFast.cpp">
<Filter>Source Files\Graphics\OpenGL\GLSL</Filter>
</ClCompile>
<ClCompile Include="..\..\src\uCodes\F3DEX3.cpp">
<Filter>Source Files\uCodes</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\src\3DMath.h">
Expand Down Expand Up @@ -817,6 +820,9 @@
<ClInclude Include="..\..\src\GLideNHQ\TxFilterExport.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\src\uCodes\F3DEX3.h">
<Filter>Header Files\uCodes</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\..\src\GLideN64.rc">
Expand Down
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ set(GLideN64_SOURCES
uCodes/F3DEX.cpp
uCodes/F3DAM.cpp
uCodes/F3DEX2.cpp
uCodes/F3DEX3.cpp
uCodes/F3DEX2ACCLAIM.cpp
uCodes/F3DEX2CBFD.cpp
uCodes/F3DZEX2.cpp
Expand Down
62 changes: 62 additions & 0 deletions src/GBI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "uCodes/F3D.h"
#include "uCodes/F3DEX.h"
#include "uCodes/F3DEX2.h"
#include "uCodes/F3DEX3.h"
#include "uCodes/L3D.h"
#include "uCodes/L3DEX.h"
#include "uCodes/L3DEX2.h"
Expand All @@ -39,6 +40,9 @@
#include "Graphics/Context.h"
#include "Graphics/Parameters.h"

#include <set>
#include <sstream>

u32 last_good_ucode = (u32) -1;

struct SpecialMicrocodeInfo
Expand Down Expand Up @@ -114,6 +118,7 @@ u32 G_OBJ_LOADTXTR, G_OBJ_LDTX_SPRITE, G_OBJ_LDTX_RECT, G_OBJ_LDTX_RECT_R;
u32 G_RDPHALF_0;
u32 G_PERSPNORM;
u32 G_ZOBJ, G_ZRDPCMD, G_ZWAITSIGNAL, G_ZMTXCAT, G_ZMULT_MPMTX, G_ZLIGHTING;
u32 G_TRISTRIP, G_TRIFAN, G_LIGHTTORDP, G_RELSEGMENT;


u32 G_MTX_STACKSIZE;
Expand Down Expand Up @@ -290,6 +295,10 @@ void GBIInfo::_makeCurrent(MicrocodeInfo * _pCurrent)
m_hwlSupported = false;
gSP.clipRatio = 2U;
break;
case F3DEX3:
F3DEX3_Init();
m_hwlSupported = false;
break;
case F3DTEXA:
F3DTEXA_Init();
m_hwlSupported = true;
Expand Down Expand Up @@ -352,6 +361,18 @@ bool GBIInfo::_makeExistingMicrocodeCurrent(u32 uc_start, u32 uc_dstart, u32 uc_
return true;
}

// based on musl libc
static inline int ascii_isupper(int c)
{
return (unsigned)c - 'A' < 26;
}

static inline int ascii_tolower(int c)
{
if (isupper(c)) return c | 32;
return c;
}

void GBIInfo::loadMicrocode(u32 uc_start, u32 uc_dstart, u16 uc_dsize)
{
if (_makeExistingMicrocodeCurrent(uc_start, uc_dstart, uc_dsize))
Expand Down Expand Up @@ -387,6 +408,47 @@ void GBIInfo::loadMicrocode(u32 uc_start, u32 uc_dstart, u16 uc_dsize)
char uc_str[256];
strcpy(uc_str, "Not Found");

// Check for F3DEX3 microcode
{
static const char F3DEX3_NAME[] = "f3dex3";
const char* probe = &uc_data[0x138];
char name_buffer[sizeof(F3DEX3_NAME) - 1];
memcpy(name_buffer, probe, sizeof(F3DEX3_NAME) - 1);
std::transform(name_buffer, name_buffer + sizeof(F3DEX3_NAME) - 1, name_buffer, ascii_tolower);
if (0 == memcmp(name_buffer, F3DEX3_NAME, sizeof(F3DEX3_NAME) - 1))
{
current.type = F3DEX3;
current.NoN = true;
current.negativeY = false;
current.fast3DPersp = false;
current.combineMatrices = false;

std::set<std::string> features;
{
// 0x180 is absolutely an overkill but it is ok for now
const char* name_end = (const char*)memchr(probe, ' ', 0x180);
size_t name_len = name_end - probe;
// It will look like F3DEX3_LVP_BrZ_NOC
std::string feature;
std::string name = std::string(probe, name_len);
std::transform(name.begin(), name.end(), name.begin(), ascii_tolower);
std::stringstream name_stream(name);
while (std::getline(name_stream, feature, '_'))
{
features.emplace(std::move(feature));
}
}

current.f3dex3.legacyVertexPipeline = features.find("lvp") != features.end();
current.f3dex3.noOcclusionPlane = features.find("noc") != features.end();
current.f3dex3.branchOnZ = features.find("brz") != features.end();

LOG(LOG_VERBOSE, "Load microcode (%s) type: %d crc: 0x%08x romname: %s\n", uc_str, current.type, uc_crc, RSP.romname);
_makeCurrent(&current);
return;
}
}

for (u32 i = 0; i < 2046; ++i) {
if ((uc_data[i] == 'R') && (uc_data[i+1] == 'S') && (uc_data[i+2] == 'P')) {
u32 j = 0;
Expand Down
16 changes: 14 additions & 2 deletions src/GBI.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@
#define F5Indi_Naboo 26
#define S2DEX_1_03 27
#define S2DEX_1_05 28
#define NONE 29
#define F3DEX3 29
#define NONE 30

// Fixed point conversion factors
#define FIXED2FLOATRECIP1 0.5f
Expand Down Expand Up @@ -401,6 +402,7 @@ extern u32 G_OBJ_LOADTXTR, G_OBJ_LDTX_SPRITE, G_OBJ_LDTX_RECT, G_OBJ_LDTX_RECT_R
extern u32 G_RDPHALF_0;
extern u32 G_PERSPNORM;
extern u32 G_ZOBJ, G_ZRDPCMD, G_ZWAITSIGNAL, G_ZMTXCAT, G_ZMULT_MPMTX, G_ZLIGHTING;
extern u32 G_TRISTRIP, G_TRIFAN, G_LIGHTTORDP, G_RELSEGMENT;

#define LIGHT_1 1
#define LIGHT_2 2
Expand Down Expand Up @@ -468,7 +470,7 @@ typedef struct

struct Light
{
u8 pad0, b, g, r;
u8 type, b, g, r;
u8 pad1, b2, g2, r2;
s8 pad2, z, y, x;
};
Expand All @@ -489,6 +491,13 @@ struct MicrocodeInfo
bool fast3DPersp = false;
bool texturePersp = true;
bool combineMatrices = false;
struct
{
// LVP is how microcodes other than F3DEX3 function
bool legacyVertexPipeline = true;
bool noOcclusionPlane = false;
bool branchOnZ = false;
} f3dex3;
};

struct GBIInfo
Expand All @@ -509,6 +518,9 @@ struct GBIInfo
bool isNegativeY() const { return m_pCurrent != nullptr ? m_pCurrent->negativeY : true; }
bool isTexturePersp() const { return m_pCurrent != nullptr ? m_pCurrent->texturePersp: true; }
bool isCombineMatrices() const { return m_pCurrent != nullptr ? m_pCurrent->combineMatrices: false; }
bool isLegacyVertexPipeline() const { return m_pCurrent != nullptr ? m_pCurrent->f3dex3.legacyVertexPipeline : true; }
bool isNoOcclusionPlane() const { return m_pCurrent != nullptr ? m_pCurrent->f3dex3.noOcclusionPlane : false; }
bool isBranchOnZ() const { return m_pCurrent != nullptr ? m_pCurrent->f3dex3.branchOnZ : false; }

private:
void _flushCommands();
Expand Down
Loading

0 comments on commit b36c440

Please sign in to comment.