Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Line3d fixes #2854

Merged
merged 3 commits into from
Jul 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 43 additions & 28 deletions src/GraphicsDrawer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -984,47 +984,59 @@ void GraphicsDrawer::drawDMATriangles(u32 _numVtx)
dropRenderState();
}

void GraphicsDrawer::_drawThickLine(u32 _v0, u32 _v1, float _width)
static void correctLineVerticesColor(SPVertex _vertexBuf[2], SPVertex& _v0)
{
auto copyColors = [](f32 const* src, f32* dst1, f32* dst2)
{
for (u32 i = 0; i < 4; ++i)
dst1[i] = dst2[i] = src[i];
};

auto convertNormalsToColors = [](f32 const* normals, f32* dst)
{
// Line3D* microcodes have no lighting code
// Original colors are stored in vertex normals, which need to be converted back to colors.
for (u32 i = 0; i < 3; ++i) {
f32 color = normals[i] * 0.5f;
if (color < 0.0f)
color += 1.0f;
dst[i] = color;
}
};

SPVertex & vtx1 = _vertexBuf[0];
SPVertex & vtx2 = _vertexBuf[1];
if ((gSP.geometryMode & G_LIGHTING) == 0) {
if ((gSP.geometryMode & G_SHADE) == 0) {
SPVertex & vtx1 = triangles.vertices[_v0];
vtx1.flat_r = gDP.primColor.r;
vtx1.flat_g = gDP.primColor.g;
vtx1.flat_b = gDP.primColor.b;
vtx1.flat_a = gDP.primColor.a;
SPVertex & vtx2 = triangles.vertices[_v1];
vtx2.flat_r = gDP.primColor.r;
vtx2.flat_g = gDP.primColor.g;
vtx2.flat_b = gDP.primColor.b;
vtx2.flat_a = gDP.primColor.a;
}
else if ((gSP.geometryMode & G_SHADING_SMOOTH) == 0) {
copyColors(&gDP.primColor.r, &vtx1.r, &vtx1.flat_r);
copyColors(&gDP.primColor.r, &vtx2.r, &vtx2.flat_r);
} else if ((gSP.geometryMode & G_SHADING_SMOOTH) == 0) {
// Flat shading
SPVertex & vtx0 = triangles.vertices[_v0 + ((RSP.w1 >> 24) & 3)];
SPVertex & vtx1 = triangles.vertices[_v0];
vtx1.r = vtx1.flat_r = vtx0.r;
vtx1.g = vtx1.flat_g = vtx0.g;
vtx1.b = vtx1.flat_b = vtx0.b;
vtx1.a = vtx1.flat_a = vtx0.a;
SPVertex & vtx2 = triangles.vertices[_v1];
vtx2.r = vtx2.flat_r = vtx0.r;
vtx2.g = vtx2.flat_g = vtx0.g;
vtx2.b = vtx2.flat_b = vtx0.b;
vtx2.a = vtx2.flat_a = vtx0.a;
copyColors(&_v0.r, &vtx1.r, &vtx1.flat_r);
copyColors(&_v0.r, &vtx2.r, &vtx2.flat_r);
}
}
else {
convertNormalsToColors(&vtx1.nx, &vtx1.r);
convertNormalsToColors(&vtx2.nx, &vtx2.r);
}
}

void GraphicsDrawer::_drawThickLine(u32 _v0, u32 _v1, float _width, u32 _flag)
{
SPVertex vertexBuf[2] = { triangles.vertices[_v0], triangles.vertices[_v1] };
correctLineVerticesColor(vertexBuf, triangles.vertices[_flag]);

setDMAVerticesSize(4);
SPVertex * pVtx = getDMAVerticesData();
const f32 ySign = GBI.isNegativeY() ? -1.0f : 1.0f;
pVtx[0] = triangles.vertices[_v0];
pVtx[0] = vertexBuf[0];
pVtx[0].x = pVtx[0].x / pVtx[0].w * gSP.viewport.vscale[0] + gSP.viewport.vtrans[0];
pVtx[0].y = ySign * pVtx[0].y / pVtx[0].w * gSP.viewport.vscale[1] + gSP.viewport.vtrans[1];
pVtx[0].z = pVtx[0].z / pVtx[0].w;
pVtx[1] = pVtx[0];

pVtx[2] = triangles.vertices[_v1];
pVtx[2] = vertexBuf[1];
pVtx[2].x = pVtx[2].x / pVtx[2].w * gSP.viewport.vscale[0] + gSP.viewport.vtrans[0];
pVtx[2].y = ySign * pVtx[2].y / pVtx[2].w * gSP.viewport.vscale[1] + gSP.viewport.vtrans[1];
pVtx[2].z = pVtx[2].z / pVtx[2].w;
Expand Down Expand Up @@ -1060,7 +1072,7 @@ void GraphicsDrawer::_drawThickLine(u32 _v0, u32 _v1, float _width)
drawScreenSpaceTriangle(4);
}

void GraphicsDrawer::drawLine(u32 _v0, u32 _v1, float _width)
void GraphicsDrawer::drawLine(u32 _v0, u32 _v1, float _width, u32 _flag)
{
m_texrectDrawer.draw();
m_statistics.lines++;
Expand All @@ -1073,8 +1085,9 @@ void GraphicsDrawer::drawLine(u32 _v0, u32 _v1, float _width)
lineWidth *= dwnd().getScaleX();
else
lineWidth *= config.frameBufferEmulation.nativeResFactor;

if (lineWidth > m_maxLineWidth) {
_drawThickLine(_v0, _v1, _width * 0.5f);
_drawThickLine(_v0, _v1, _width * 0.5f, _flag);
return;
}

Expand All @@ -1089,6 +1102,8 @@ void GraphicsDrawer::drawLine(u32 _v0, u32 _v1, float _width)
_updateViewport();

SPVertex vertexBuf[2] = { triangles.vertices[_v0], triangles.vertices[_v1] };
correctLineVerticesColor(vertexBuf, triangles.vertices[_flag]);

gfxContext.drawLine(lineWidth, vertexBuf);
dropRenderState();
}
Expand Down
4 changes: 2 additions & 2 deletions src/GraphicsDrawer.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class GraphicsDrawer

void drawDMATriangles(u32 _numVtx);

void drawLine(u32 _v0, u32 _v1, float _width);
void drawLine(u32 _v0, u32 _v1, float _width, u32 _flag);

void drawRect(int _ulx, int _uly, int _lrx, int _lry);

Expand Down Expand Up @@ -210,7 +210,7 @@ class GraphicsDrawer
void _updateStates(DrawingState _drawingState) const;
void _prepareDrawTriangle(DrawingState _drawingState);
bool _canDraw() const;
void _drawThickLine(u32 _v0, u32 _v1, float _width);
void _drawThickLine(u32 _v0, u32 _v1, float _width, u32 _flag);

void _drawOSD(const char *_pText, float _x, float & _y);

Expand Down
13 changes: 3 additions & 10 deletions src/gSP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1972,18 +1972,11 @@ void gSPSetOtherMode_L(u32 _length, u32 _shift, u32 _data)
DebugMsg(DEBUG_NORMAL, " result: %08x\n", gDP.otherMode.l);
}

void gSPLine3D(u32 v0, u32 v1, u32 flag )
void gSPLine3D(u32 v0, u32 v1, s32 wd, u32 flag )
{
dwnd().getDrawer().drawLine(v0, v1, 1.5f);
dwnd().getDrawer().drawLine(v0, v1, 1.5f + wd * 0.5f, flag);

DebugMsg(DEBUG_NORMAL, "gSPLine3D( %i, %i, %i )\n", v0, v1, flag);
}

void gSPLineW3D(u32 v0, u32 v1, u32 wd, u32 flag )
{
dwnd().getDrawer().drawLine(v0, v1, 1.5f + wd * 0.5f);

DebugMsg(DEBUG_NORMAL, "gSPLineW3D( %i, %i, %i, %i )\n", v0, v1, wd, flag);
DebugMsg(DEBUG_NORMAL, "gSPLine3D( %i, %i, %i, %i )\n", v0, v1, wd, flag);
}

void gSPSetStatus(u32 sid, u32 val)
Expand Down
3 changes: 1 addition & 2 deletions src/gSP.h
Original file line number Diff line number Diff line change
Expand Up @@ -195,8 +195,7 @@ void gSPSetGeometryMode( u32 mode );
void gSPClearGeometryMode( u32 mode );
void gSPSetOtherMode_H(u32 _length, u32 _shift, u32 _data);
void gSPSetOtherMode_L(u32 _length, u32 _shift, u32 _data);
void gSPLine3D(u32 v0, u32 v1, u32 flag);
void gSPLineW3D( u32 v0, u32 v1, u32 wd, u32 flag );
void gSPLine3D( u32 v0, u32 v1, s32 wd, u32 flag );
void gSPSetStatus(u32 sid, u32 val);
void gSPSetDMAOffsets( u32 mtxoffset, u32 vtxoffset );
void gSPSetDMATexOffset(u32 _addr);
Expand Down
34 changes: 28 additions & 6 deletions src/uCodes/L3D.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,34 @@

void L3D_Line3D( u32 w0, u32 w1 )
{
u32 wd = _SHIFTR( w1, 0, 8 );
s32 wd = static_cast<s8>(_SHIFTR( w1, 0, 8 ));
u32 v0 = _SHIFTR(w1, 16, 8) / 10;
u32 v1 = _SHIFTR(w1, 8, 8) / 10;
u32 flag = _SHIFTR(w1, 24, 8);
gSPLine3D( v0, v1, wd, flag == 0 ? v0 : v1 );
}

if (wd == 0)
gSPLine3D( _SHIFTR( w1, 16, 8 ) / 10, _SHIFTR( w1, 8, 8 ) / 10, _SHIFTR( w1, 24, 8 ) );
else
gSPLineW3D( _SHIFTR( w1, 16, 8 ) / 10, _SHIFTR( w1, 8, 8 ) / 10, wd, _SHIFTR( w1, 24, 8 ) );
void L3D_Tri1(u32 w0, u32 w1)
{
u32 v0 = _SHIFTR(w1, 16, 8) / 10;
u32 v1 = _SHIFTR(w1, 8, 8) / 10;
u32 v2 = _SHIFTR(w0, 0, 8) / 10;
u32 flag = _SHIFTR(w1, 24, 8);
u32 flatShadeVtx = v0;
switch (flag) {
case 0x01:
flatShadeVtx = v1;
break;
case 0x02:
flatShadeVtx = v2;
break;
}
if (v0 != v1)
gSPLine3D(v0, v1, 0, flatShadeVtx);
if (v1 != v2)
gSPLine3D(v1, v2, 0, flatShadeVtx);
if (v2 != v0)
gSPLine3D(v2, v0, 0, flatShadeVtx);
}

void L3D_Init()
Expand All @@ -39,7 +61,7 @@ void L3D_Init()
GBI_SetGBI( G_RESERVED3, F3D_RESERVED3, F3D_Reserved3 );
GBI_SetGBI( G_SPRITE2D_BASE, F3D_SPRITE2D_BASE, F3D_Sprite2D_Base );

// GBI_SetGBI( G_TRI1, F3D_TRI1, F3D_Tri1 );
GBI_SetGBI( G_TRI1, L3D_TRI1, L3D_Tri1 );
GBI_SetGBI( G_CULLDL, F3D_CULLDL, F3D_CullDL );
GBI_SetGBI( G_POPMTX, F3D_POPMTX, F3D_PopMtx );
GBI_SetGBI( G_MOVEWORD, F3D_MOVEWORD, F3D_MoveWord );
Expand Down
1 change: 1 addition & 0 deletions src/uCodes/L3D.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "Types.h"

#define L3D_LINE3D 0xB5
#define L3D_TRI1 0xBF

void L3D_Line3D( u32 w0, u32 w1 );
void L3D_Init();
Expand Down
53 changes: 45 additions & 8 deletions src/uCodes/L3DEX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,49 @@

void L3DEX_Line3D( u32 w0, u32 w1 )
{
u32 wd = _SHIFTR( w1, 0, 8 );
u32 v0 = _SHIFTR(w1, 17, 7);
u32 v1 = _SHIFTR(w1, 9, 7);
s32 wd = static_cast<s8>(_SHIFTR( w1, 0, 8 ));
gSPLine3D( v0, v1, wd, v0 );
}

void L3DEX_Tri1(u32 w0, u32 w1)
{
u32 v0 = _SHIFTR(w1, 17, 7);
u32 v1 = _SHIFTR(w1, 9, 7);
u32 v2 = _SHIFTR(w1, 1, 7);

if (v0 != v1)
gSPLine3D(v0, v1, 0, v0);
if (v1 != v2)
gSPLine3D(v1, v2, 0, v0);
if (v2 != v0)
gSPLine3D(v2, v0, 0, v0);
}

void L3DEX_Tri2(u32 w0, u32 w1)
{
u32 v00 = _SHIFTR(w0, 17, 7);
u32 v01 = _SHIFTR(w0, 9, 7);
u32 v02 = _SHIFTR(w0, 1, 7);

u32 v10 = _SHIFTR(w1, 17, 7);
u32 v11 = _SHIFTR(w1, 9, 7);
u32 v12 = _SHIFTR(w1, 1, 7);

if (v00 != v01)
gSPLine3D(v00, v01, 0, v00);
if (v01 != v02)
gSPLine3D(v01, v02, 0, v00);
if (v02 != v00)
gSPLine3D(v02, v00, 0, v00);

if (wd == 0)
gSPLine3D( _SHIFTR( w1, 17, 7 ), _SHIFTR( w1, 9, 7 ), 0 );
else
gSPLineW3D( _SHIFTR( w1, 17, 7 ), _SHIFTR( w1, 9, 7 ), wd, 0 );
if (v10 != v11)
gSPLine3D(v10, v11, 0, v10);
if (v11 != v12)
gSPLine3D(v11, v12, 0, v10);
if (v12 != v10)
gSPLine3D(v12, v10, 0, v10);
}

void L3DEX_Init()
Expand All @@ -41,7 +78,7 @@ void L3DEX_Init()
GBI_SetGBI( G_RESERVED3, F3D_RESERVED3, F3D_Reserved3 );
GBI_SetGBI( G_SPRITE2D_BASE, F3D_SPRITE2D_BASE, F3D_Sprite2D_Base );

// GBI_SetGBI( G_TRI1, F3D_TRI1, F3DEX_Tri1 );
GBI_SetGBI( G_TRI1, L3DEX_TRI1, L3DEX_Tri1 );
GBI_SetGBI( G_CULLDL, F3D_CULLDL, F3DEX_CullDL );
GBI_SetGBI( G_POPMTX, F3D_POPMTX, F3D_PopMtx );
GBI_SetGBI( G_MOVEWORD, F3D_MOVEWORD, F3D_MoveWord );
Expand All @@ -51,11 +88,11 @@ void L3DEX_Init()
GBI_SetGBI( G_ENDDL, F3D_ENDDL, F3D_EndDL );
GBI_SetGBI( G_SETGEOMETRYMODE, F3D_SETGEOMETRYMODE, F3D_SetGeometryMode );
GBI_SetGBI( G_CLEARGEOMETRYMODE, F3D_CLEARGEOMETRYMODE, F3D_ClearGeometryMode );
GBI_SetGBI( G_LINE3D, L3D_LINE3D, L3DEX_Line3D );
GBI_SetGBI( G_LINE3D, L3DEX_LINE3D, L3DEX_Line3D );
GBI_SetGBI( G_RDPHALF_1, F3D_RDPHALF_1, F3D_RDPHalf_1 );
GBI_SetGBI( G_RDPHALF_2, F3D_RDPHALF_2, F3D_RDPHalf_2 );
GBI_SetGBI( G_MODIFYVTX, F3DEX_MODIFYVTX, F3DEX_ModifyVtx );
// GBI_SetGBI( G_TRI2, F3DEX_TRI2, F3DEX_Tri2 );
GBI_SetGBI( G_TRI2, L3DEX_TRI2, L3DEX_Tri2 );
GBI_SetGBI( G_BRANCH_Z, F3DEX_BRANCH_Z, F3DEX_Branch_Z );
GBI_SetGBI( G_LOAD_UCODE, F3DEX_LOAD_UCODE, F3DEX_Load_uCode );
}
Expand Down
4 changes: 4 additions & 0 deletions src/uCodes/L3DEX.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
#define L3DEX_H
#include "Types.h"

#define L3DEX_TRI1 0xBF
#define L3DEX_TRI2 0xB1
#define L3DEX_LINE3D 0xB5

void L3DEX_Line3D( u32 w0, u32 w1 );
void L3DEX_Init();
#endif
Expand Down
52 changes: 45 additions & 7 deletions src/uCodes/L3DEX2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,50 @@

void L3DEX2_Line3D( u32 w0, u32 w1 )
{
u32 wd = _SHIFTR( (w0 + 1), 0, 8 );
s32 wd = static_cast<s8>(_SHIFTR( w0, 0, 8 ));
u32 v0 = _SHIFTR(w0, 17, 7);
u32 v1 = _SHIFTR(w0, 9, 7);
gSPLine3D( v0, v1, wd, v0 );
}

void L3DEX2_Tri1(u32 w0, u32 w1)
{
s32 wd = static_cast<s8>(_SHIFTR(w1, 24, 8));
u32 v0 = _SHIFTR(w0, 17, 7);
u32 v1 = _SHIFTR(w0, 9, 7);
u32 v2 = _SHIFTR(w0, 1, 7);

if (v0 != v1)
gSPLine3D(v0, v1, wd, v0);
if (v1 != v2)
gSPLine3D(v1, v2, wd, v0);
if (v2 != v0)
gSPLine3D(v2, v0, wd, v0);
}

void L3DEX2_Tri2(u32 w0, u32 w1)
{
s32 wd = static_cast<s8>(_SHIFTR(w1, 24, 8));
u32 v0 = _SHIFTR(w0, 17, 7);
u32 v1 = _SHIFTR(w0, 9, 7);
u32 v2 = _SHIFTR(w0, 1, 7);
u32 v3 = _SHIFTR(w1, 17, 7);
u32 v4 = _SHIFTR(w1, 9, 7);
u32 v5 = _SHIFTR(w1, 1, 7);

if (v0 != v1)
gSPLine3D(v0, v1, wd, v0);
if (v1 != v2)
gSPLine3D(v1, v2, wd, v0);
if (v2 != v0)
gSPLine3D(v2, v0, wd, v0);

if (wd == 0)
gSPLine3D( _SHIFTR( w0, 17, 7 ), _SHIFTR( w0, 9, 7 ), 0 );
else
gSPLineW3D( _SHIFTR( w0, 17, 7 ), _SHIFTR( w0, 9, 7 ), wd, 0 );
if (v3 != v4)
gSPLine3D(v3, v4, wd, v3);
if (v4 != v5)
gSPLine3D(v4, v5, wd, v3);
if (v5 != v3)
gSPLine3D(v5, v3, wd, v3);
}

void L3DEX2_Init()
Expand Down Expand Up @@ -54,8 +92,8 @@ void L3DEX2_Init()
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_TRI1, L3DEX2_TRI1, L3DEX2_Tri1 );
GBI_SetGBI( G_TRI2, L3DEX2_TRI2, L3DEX2_Tri2 );
// GBI_SetGBI( G_QUAD, F3DEX2_QUAD, F3DEX2_Quad );
GBI_SetGBI( G_LINE3D, L3DEX2_LINE3D, L3DEX2_Line3D );
}
Expand Down
5 changes: 3 additions & 2 deletions src/uCodes/L3DEX2.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
#define L3DEX2_H
#include "Types.h"

#define L3DEX2_LINE3D 0x08
#define L3DEX2_TRI1 0x05
#define L3DEX2_TRI2 0x06
#define L3DEX2_LINE3D 0x08

void L3DEX2_Line3D( u32 w0, u32 w1 );
void L3DEX2_Init();
#endif