mirror of
https://github.com/blawar/GLideN64.git
synced 2024-07-02 09:03:37 +00:00
Implement T3DUX ucode.
Ucode decoded by olivieryuyu. Details: Toukon road 1 & 2, last legion UX: HLE implementation (extended turbo3D)? #624 https://github.com/gonetz/GLideN64/wiki/T3DUX-ucode
This commit is contained in:
parent
312a9a77f2
commit
4722a75b24
|
@ -355,6 +355,7 @@
|
|||
<ClCompile Include="..\..\src\RSP.cpp" />
|
||||
<ClCompile Include="..\..\src\RSP_LoadMatrixX86.cpp" />
|
||||
<ClCompile Include="..\..\src\SoftwareRender.cpp" />
|
||||
<ClCompile Include="..\..\src\T3DUX.cpp" />
|
||||
<ClCompile Include="..\..\src\TexrectDrawer.cpp" />
|
||||
<ClCompile Include="..\..\src\TextDrawer.cpp" />
|
||||
<ClCompile Include="..\..\src\TextureFilterHandler.cpp" />
|
||||
|
@ -480,6 +481,7 @@
|
|||
<ClInclude Include="..\..\src\GraphicsDrawer.h" />
|
||||
<ClInclude Include="..\..\src\RSP.h" />
|
||||
<ClInclude Include="..\..\src\SoftwareRender.h" />
|
||||
<ClInclude Include="..\..\src\T3DUX.h" />
|
||||
<ClInclude Include="..\..\src\TexrectDrawer.h" />
|
||||
<ClInclude Include="..\..\src\TextDrawer.h" />
|
||||
<ClInclude Include="..\..\src\TextureFilterHandler.h" />
|
||||
|
|
|
@ -338,9 +338,6 @@
|
|||
<ClCompile Include="..\..\src\TexrectDrawer.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\F3DTEXA.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\Graphics\ObjectHandle.cpp">
|
||||
<Filter>Source Files\Graphics</Filter>
|
||||
</ClCompile>
|
||||
|
@ -353,6 +350,12 @@
|
|||
<ClCompile Include="..\..\src\xxHash\xxhash.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\F3DTEXA.cpp">
|
||||
<Filter>Source Files\uCodes</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\T3DUX.cpp">
|
||||
<Filter>Source Files\uCodes</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\src\3DMath.h">
|
||||
|
@ -649,11 +652,14 @@
|
|||
<ClInclude Include="..\..\src\TexrectDrawer.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\F3DTEXA.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\xxHash\xxhash.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\T3DUX.h">
|
||||
<Filter>Header Files\uCodes</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\F3DTEXA.h">
|
||||
<Filter>Header Files\uCodes</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -50,6 +50,7 @@ set(GLideN64_SOURCES
|
|||
S2DEX2.cpp
|
||||
S2DEX.cpp
|
||||
SoftwareRender.cpp
|
||||
T3DUX.cpp
|
||||
TexrectDrawer.cpp
|
||||
TextDrawer.cpp
|
||||
TextureFilterHandler.cpp
|
||||
|
|
|
@ -57,8 +57,10 @@ SpecialMicrocodeInfo specialMicrocodes[] =
|
|||
{ F3DPD, true, 0x1c4f7869, "Perfect Dark" },
|
||||
{ Turbo3D, false, 0x2bdcfc8a, "Turbo3D" },
|
||||
{ F3DEX2CBFD, true, 0x1b4ace88, "Conker's Bad Fur Day" },
|
||||
{ F3DEX2MM, true, 0xd39a0d4f, "Animal Forest" },
|
||||
{ S2DEX2, false, 0x2c399dd, "Animal Forest" }
|
||||
{ F3DEX2MM, true, 0xd39a0d4f, "Animal Forest" },
|
||||
{ S2DEX2, false, 0x2c399dd, "Animal Forest" },
|
||||
{ T3DUX, false, 0xbad437f2, "T3DUX vers 0.83 for Toukon Road" },
|
||||
{ T3DUX, false, 0xd0a1aa3d, "T3DUX vers 0.85 for Toukon Road 2" }
|
||||
};
|
||||
|
||||
u32 G_RDPHALF_1, G_RDPHALF_2, G_RDPHALF_CONT;
|
||||
|
@ -192,6 +194,7 @@ void GBIInfo::_makeCurrent(MicrocodeInfo * _pCurrent)
|
|||
case F3DGOLDEN: F3DGOLDEN_Init(); break;
|
||||
case F3DEX2MM: F3DEX2MM_Init(); break;
|
||||
case F3DTEXA: F3DTEXA_Init(); break;
|
||||
case T3DUX: F3D_Init(); break;
|
||||
}
|
||||
|
||||
if (gfxContext.isSupported(graphics::SpecialFeatures::NearPlaneClipping)) {
|
||||
|
|
|
@ -25,7 +25,8 @@
|
|||
#define F3DSETA 16
|
||||
#define F3DEX2MM 17
|
||||
#define F3DTEXA 18
|
||||
#define NONE 19
|
||||
#define T3DUX 19
|
||||
#define NONE 20
|
||||
|
||||
// Fixed point conversion factors
|
||||
#define FIXED2FLOATRECIP1 0.5f
|
||||
|
|
10
src/RSP.cpp
10
src/RSP.cpp
|
@ -6,6 +6,7 @@
|
|||
#include "N64.h"
|
||||
#include "F3D.h"
|
||||
#include "Turbo3D.h"
|
||||
#include "T3DUX.h"
|
||||
#include "VI.h"
|
||||
#include "Combiner.h"
|
||||
#include "FrameBuffer.h"
|
||||
|
@ -70,9 +71,14 @@ void RSP_ProcessDList()
|
|||
|
||||
depthBufferList().setNotCleared();
|
||||
|
||||
if (GBI.getMicrocodeType() == Turbo3D)
|
||||
switch (GBI.getMicrocodeType()) {
|
||||
case Turbo3D:
|
||||
RunTurbo3D();
|
||||
else {
|
||||
break;
|
||||
case T3DUX:
|
||||
RunT3DUX();
|
||||
break;
|
||||
default:
|
||||
while (!RSP.halt) {
|
||||
if ((RSP.PC[RSP.PCi] + 8) > RDRAMSize) {
|
||||
#ifdef DEBUG
|
||||
|
|
231
src/T3DUX.cpp
Normal file
231
src/T3DUX.cpp
Normal file
|
@ -0,0 +1,231 @@
|
|||
#include "T3DUX.h"
|
||||
#include "N64.h"
|
||||
#include "RSP.h"
|
||||
#include "RDP.h"
|
||||
#include "gSP.h"
|
||||
#include "gDP.h"
|
||||
#include "DisplayWindow.h"
|
||||
|
||||
/******************T3DUX microcode*************************/
|
||||
|
||||
struct T3DGlobState
|
||||
{
|
||||
u16 pad0;
|
||||
u16 perspNorm;
|
||||
u32 flag;
|
||||
u32 othermode0;
|
||||
u32 othermode1;
|
||||
u32 segBases[16];
|
||||
/* the viewport to use */
|
||||
s16 vsacle1;
|
||||
s16 vsacle0;
|
||||
s16 vsacle3;
|
||||
s16 vsacle2;
|
||||
s16 vtrans1;
|
||||
s16 vtrans0;
|
||||
s16 vtrans3;
|
||||
s16 vtrans2;
|
||||
u32 rdpCmds;
|
||||
};
|
||||
|
||||
struct T3DState
|
||||
{
|
||||
u32 renderState; /* render state */
|
||||
|
||||
u8 dmemVtxAddr;
|
||||
u8 vtxCount; /* number of verts */
|
||||
u8 texmode;
|
||||
u8 geommode;
|
||||
|
||||
u8 dmemVtxAttribsAddr;
|
||||
u8 attribsCount; /* number of colors and texture coords */
|
||||
u8 matrixFlag;
|
||||
u8 triCount; /* how many tris? */
|
||||
|
||||
u32 rdpCmds; /* ptr (segment address) to RDP DL */
|
||||
u32 othermode0;
|
||||
u32 othermode1;
|
||||
};
|
||||
|
||||
|
||||
struct T3DTriN
|
||||
{
|
||||
u8 flag, v2, v1, v0; /* flag is which one for flat shade */
|
||||
u8 pal, v2tex, v1tex, v0tex; /* indexes in texture coords list */
|
||||
};
|
||||
|
||||
static u32 t32uxSetTileW0 = 0;
|
||||
static u32 t32uxSetTileW1 = 0;
|
||||
|
||||
static
|
||||
void T3DUX_ProcessRDP(u32 _cmds)
|
||||
{
|
||||
u32 addr = RSP_SegmentToPhysical(_cmds) >> 2;
|
||||
if (addr != 0) {
|
||||
RSP.bLLE = true;
|
||||
u32 w0 = ((u32*)RDRAM)[addr++];
|
||||
u32 w1 = ((u32*)RDRAM)[addr++];
|
||||
RSP.cmd = _SHIFTR( w0, 24, 8 );
|
||||
while (w0 + w1 != 0) {
|
||||
GBI.cmd[RSP.cmd]( w0, w1 );
|
||||
w0 = ((u32*)RDRAM)[addr++];
|
||||
w1 = ((u32*)RDRAM)[addr++];
|
||||
RSP.cmd = _SHIFTR( w0, 24, 8 );
|
||||
switch (RSP.cmd) {
|
||||
case G_TEXRECT:
|
||||
case G_TEXRECTFLIP:
|
||||
RDP.w2 = ((u32*)RDRAM)[addr++];
|
||||
RDP.w3 = ((u32*)RDRAM)[addr++];
|
||||
break;
|
||||
case G_SETTILE:
|
||||
t32uxSetTileW0 = w0;
|
||||
t32uxSetTileW1 = w1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
RSP.bLLE = false;
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void T3DUX_LoadGlobState(u32 pgstate)
|
||||
{
|
||||
const u32 addr = RSP_SegmentToPhysical(pgstate);
|
||||
T3DGlobState *gstate = (T3DGlobState*)&RDRAM[addr];
|
||||
const u32 w0 = gstate->othermode0;
|
||||
const u32 w1 = gstate->othermode1;
|
||||
gDPSetOtherMode( _SHIFTR( w0, 0, 24 ), // mode0
|
||||
w1 ); // mode1
|
||||
|
||||
for (int s = 0; s < 16; ++s)
|
||||
gSPSegment(s, gstate->segBases[s] & 0x00FFFFFF);
|
||||
|
||||
gSPViewport(pgstate + 80);
|
||||
|
||||
T3DUX_ProcessRDP(gstate->rdpCmds);
|
||||
}
|
||||
|
||||
static
|
||||
void T3DUX_LoadObject(u32 pstate, u32 pvtx, u32 ptri, u32 pcol)
|
||||
{
|
||||
T3DState *ostate = (T3DState*)&RDRAM[RSP_SegmentToPhysical(pstate)];
|
||||
// TODO: fix me
|
||||
const u32 tile = 0;
|
||||
gSP.texture.tile = tile;
|
||||
gSP.textureTile[0] = &gDP.tiles[tile];
|
||||
gSP.textureTile[1] = &gDP.tiles[(tile + 1) & 7];
|
||||
gSP.texture.scales = 1.0f;
|
||||
gSP.texture.scalet = 1.0f;
|
||||
|
||||
const u32 w0 = ostate->othermode0;
|
||||
const u32 w1 = ostate->othermode1;
|
||||
gDPSetOtherMode( _SHIFTR( w0, 0, 24 ), // mode0
|
||||
w1 ); // mode1
|
||||
|
||||
if ((ostate->matrixFlag & 1) == 0) //load matrix
|
||||
gSPForceMatrix(pstate + sizeof(T3DState));
|
||||
|
||||
gSPClearGeometryMode(G_LIGHTING | G_FOG);
|
||||
gSPSetGeometryMode(ostate->renderState | G_SHADING_SMOOTH | G_SHADE | G_ZBUFFER | G_CULL_BACK);
|
||||
|
||||
if (pvtx != 0) //load vtx
|
||||
gSPT3DUXVertex(pvtx, ostate->vtxCount, pcol);
|
||||
|
||||
T3DUX_ProcessRDP(ostate->rdpCmds);
|
||||
|
||||
if (ptri == 0)
|
||||
return;
|
||||
|
||||
GraphicsDrawer & drawer = dwnd().getDrawer();
|
||||
const u32 coladdr = RSP_SegmentToPhysical(pcol);
|
||||
const T3DTriN * tri = (const T3DTriN*)&RDRAM[RSP_SegmentToPhysical(ptri)];
|
||||
u8 pal = _SHIFTR(t32uxSetTileW1, 20, 4);
|
||||
t32uxSetTileW1 &= 0xFF0FFFFF;
|
||||
const bool flatShading = (ostate->geommode & 0x0F) == 0;
|
||||
const bool texturing = ostate->texmode != 1;
|
||||
f32 flatr, flatg, flatb, flata;
|
||||
|
||||
drawer.setDMAVerticesSize(ostate->triCount * 3);
|
||||
SPVertex * pVtx = drawer.getDMAVerticesData();
|
||||
for (int t = 0; t < ostate->triCount; ++t, ++tri) {
|
||||
if (texturing && tri->pal != 0) {
|
||||
const u32 w1 = t32uxSetTileW1 | (tri->pal << 20);
|
||||
const u32 newPal = _SHIFTR(w1, 20, 4);
|
||||
if (pal != newPal) {
|
||||
drawer.drawDMATriangles(pVtx - drawer.getDMAVerticesData());
|
||||
pVtx = drawer.getDMAVerticesData();
|
||||
pal = newPal;
|
||||
RDP_SetTile(t32uxSetTileW0, w1);
|
||||
}
|
||||
}
|
||||
|
||||
if (tri->v0 >= ostate->vtxCount || tri->v1 >= ostate->vtxCount || tri->v2 >= ostate->vtxCount)
|
||||
continue;
|
||||
|
||||
if (drawer.isClipped(tri->v0, tri->v1, tri->v2))
|
||||
continue;
|
||||
|
||||
if (flatShading) {
|
||||
struct T3DUXColor
|
||||
{
|
||||
u8 a;
|
||||
u8 b;
|
||||
u8 g;
|
||||
u8 r;
|
||||
} color = *(T3DUXColor*)&RDRAM[coladdr + ((tri->flag << 2) & 0x03FC)];
|
||||
flata = _FIXED2FLOAT(color.a, 8);
|
||||
flatb = _FIXED2FLOAT(color.b, 8);
|
||||
flatg = _FIXED2FLOAT(color.g, 8);
|
||||
flatr = _FIXED2FLOAT(color.r, 8);
|
||||
}
|
||||
|
||||
u32 vtxIdx[3] = { tri->v0, tri->v1, tri->v2 };
|
||||
u32 texIdx[3] = { tri->v0tex, tri->v1tex, tri->v2tex };
|
||||
for (u32 v = 0; v < 3; ++v) {
|
||||
*pVtx = drawer.getVertex(vtxIdx[v]);
|
||||
|
||||
if (texturing) {
|
||||
u32 texcoords = *(const u32*)&RDRAM[coladdr + (texIdx[v] << 2)];
|
||||
pVtx->s = _FIXED2FLOAT(_SHIFTR(texcoords, 16, 16), 5);
|
||||
pVtx->t = _FIXED2FLOAT(_SHIFTR(texcoords, 0, 16), 5);
|
||||
} else {
|
||||
pVtx->s = 0.0f;
|
||||
pVtx->t = 0.0f;
|
||||
}
|
||||
|
||||
if (flatShading) {
|
||||
pVtx->r = flatr;
|
||||
pVtx->g = flatg;
|
||||
pVtx->b = flatb;
|
||||
pVtx->a = flata;
|
||||
}
|
||||
|
||||
++pVtx;
|
||||
}
|
||||
}
|
||||
|
||||
drawer.drawDMATriangles(pVtx - drawer.getDMAVerticesData());
|
||||
}
|
||||
|
||||
void RunT3DUX()
|
||||
{
|
||||
u32 pstate;
|
||||
do {
|
||||
u32 addr = RSP.PC[RSP.PCi] >> 2;
|
||||
const u32 pgstate = ((u32*)RDRAM)[addr++];
|
||||
pstate = ((u32*)RDRAM)[addr++];
|
||||
const u32 pvtx = ((u32*)RDRAM)[addr++];
|
||||
const u32 ptri = ((u32*)RDRAM)[addr++];
|
||||
const u32 pcol = ((u32*)RDRAM)[addr++];
|
||||
//const u32 pstore = ((u32*)RDRAM)[addr];
|
||||
if (pstate == 0) {
|
||||
RSP.halt = 1;
|
||||
break;
|
||||
}
|
||||
if (pgstate != 0)
|
||||
T3DUX_LoadGlobState(pgstate);
|
||||
T3DUX_LoadObject(pstate, pvtx, ptri, pcol);
|
||||
// Go to the next instruction
|
||||
RSP.PC[RSP.PCi] += 24;
|
||||
} while (pstate != 0);
|
||||
}
|
6
src/T3DUX.h
Normal file
6
src/T3DUX.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
#ifndef T3DUX_H
|
||||
#define T3DUX_H
|
||||
|
||||
void RunT3DUX();
|
||||
|
||||
#endif // T3DUX_H
|
62
src/gSP.cpp
62
src/gSP.cpp
|
@ -1241,6 +1241,68 @@ void gSPCBFDVertex( u32 a, u32 n, u32 v0 )
|
|||
}
|
||||
}
|
||||
|
||||
void gSPT3DUXVertex(u32 a, u32 n, u32 ci)
|
||||
{
|
||||
const u32 address = RSP_SegmentToPhysical(a);
|
||||
const u32 colors = RSP_SegmentToPhysical(ci);
|
||||
|
||||
struct T3DUXVertex {
|
||||
s16 y;
|
||||
s16 x;
|
||||
u16 flag;
|
||||
s16 z;
|
||||
} *vertex = (T3DUXVertex*)&RDRAM[address];
|
||||
|
||||
struct T3DUXColor
|
||||
{
|
||||
u8 a;
|
||||
u8 b;
|
||||
u8 g;
|
||||
u8 r;
|
||||
} *color = (T3DUXColor*)&RDRAM[colors];
|
||||
|
||||
if ((address + sizeof(T3DUXVertex)* n) > RDRAMSize)
|
||||
return;
|
||||
|
||||
GraphicsDrawer & drawer = dwnd().getDrawer();
|
||||
u32 i = 0;
|
||||
#ifdef __VEC4_OPT
|
||||
for (; i < n - (n % 4); i += 4) {
|
||||
u32 v = i;
|
||||
for (int j = 0; j < 4; ++j) {
|
||||
SPVertex & vtx = drawer.getVertex(v + j);
|
||||
vtx.x = vertex->x;
|
||||
vtx.y = vertex->y;
|
||||
vtx.z = vertex->z;
|
||||
vtx.s = 0;
|
||||
vtx.t = 0;
|
||||
vtx.r = _FIXED2FLOAT(color->r, 8);
|
||||
vtx.g = _FIXED2FLOAT(color->g, 8);
|
||||
vtx.b = _FIXED2FLOAT(color->b, 8);
|
||||
vtx.a = _FIXED2FLOAT(color->a, 8);
|
||||
vertex++;
|
||||
color++;
|
||||
}
|
||||
gSPProcessVertex4(v);
|
||||
}
|
||||
#endif
|
||||
for (; i < n; ++i) {
|
||||
SPVertex & vtx = drawer.getVertex(i);
|
||||
vtx.x = vertex->x;
|
||||
vtx.y = vertex->y;
|
||||
vtx.z = vertex->z;
|
||||
vtx.s = 0;
|
||||
vtx.t = 0;
|
||||
vtx.r = _FIXED2FLOAT(color->r, 8);
|
||||
vtx.g = _FIXED2FLOAT(color->g, 8);
|
||||
vtx.b = _FIXED2FLOAT(color->b, 8);
|
||||
vtx.a = _FIXED2FLOAT(color->a, 8);
|
||||
gSPProcessVertex(i);
|
||||
vertex++;
|
||||
color++;
|
||||
}
|
||||
}
|
||||
|
||||
void gSPDisplayList( u32 dl )
|
||||
{
|
||||
u32 address = RSP_SegmentToPhysical( dl );
|
||||
|
|
|
@ -153,7 +153,8 @@ void gSPVertex( u32 v, u32 n, u32 v0 );
|
|||
void gSPCIVertex( u32 v, u32 n, u32 v0 );
|
||||
void gSPDMAVertex( u32 v, u32 n, u32 v0 );
|
||||
void gSPCBFDVertex( u32 v, u32 n, u32 v0 );
|
||||
void gSPDisplayList( u32 dl );
|
||||
void gSPT3DUXVertex(u32 v, u32 n, u32 ci);
|
||||
void gSPDisplayList(u32 dl);
|
||||
void gSPBranchList( u32 dl );
|
||||
void gSPBranchLessZ( u32 branchdl, u32 vtx, u32 zval );
|
||||
void gSPBranchLessW( u32 branchdl, u32 vtx, u32 wval );
|
||||
|
|
|
@ -60,6 +60,7 @@ MY_LOCAL_SRC_FILES := \
|
|||
$(SRCDIR)/S2DEX2.cpp \
|
||||
$(SRCDIR)/S2DEX.cpp \
|
||||
$(SRCDIR)/SoftwareRender.cpp \
|
||||
$(SRCDIR)/T3DUX.cpp \
|
||||
$(SRCDIR)/TexrectDrawer.cpp \
|
||||
$(SRCDIR)/TextDrawer.cpp \
|
||||
$(SRCDIR)/TextureFilterHandler.cpp \
|
||||
|
|
Loading…
Reference in New Issue
Block a user