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

Port of Lemmy's implementation of SWRS ucode.

This commit is contained in:
Sergey Lipskiy 2017-07-18 17:33:05 +07:00
parent 6bfe0adf0a
commit a9248c5a26
13 changed files with 462 additions and 26 deletions

View File

@ -288,6 +288,7 @@
<ClCompile Include="..\..\src\F3DGOLDEN.cpp" />
<ClCompile Include="..\..\src\F3DSETA.cpp" />
<ClCompile Include="..\..\src\F3DBETA.cpp" />
<ClCompile Include="..\..\src\F3DSWRS.cpp" />
<ClCompile Include="..\..\src\F3DTEXA.cpp" />
<ClCompile Include="..\..\src\FrameBuffer.cpp" />
<ClCompile Include="..\..\src\FrameBufferInfo.cpp" />
@ -429,6 +430,7 @@
<ClInclude Include="..\..\src\F3DEX2MM.h" />
<ClInclude Include="..\..\src\F3DGOLDEN.h" />
<ClInclude Include="..\..\src\F3DSETA.h" />
<ClInclude Include="..\..\src\F3DSWRS.h" />
<ClInclude Include="..\..\src\F3DTEXA.h" />
<ClInclude Include="..\..\src\FrameBuffer.h" />
<ClInclude Include="..\..\src\FrameBufferInfo.h" />

View File

@ -368,6 +368,9 @@
<ClCompile Include="..\..\src\F3DAM.cpp">
<Filter>Source Files\uCodes</Filter>
</ClCompile>
<ClCompile Include="..\..\src\F3DSWRS.cpp">
<Filter>Source Files\uCodes</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\src\3DMath.h">
@ -682,5 +685,8 @@
<ClInclude Include="..\..\src\F3DAM.h">
<Filter>Header Files\uCodes</Filter>
</ClInclude>
<ClInclude Include="..\..\src\F3DSWRS.h">
<Filter>Header Files\uCodes</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -28,6 +28,7 @@ set(GLideN64_SOURCES
F3DEX2CBFD.cpp
F3DEX2MM.cpp
F3DGOLDEN.cpp
F3DSWRS.cpp
F3DTEXA.cpp
F3DPD.cpp
F3DSETA.cpp

283
src/F3DSWRS.cpp Normal file
View File

@ -0,0 +1,283 @@
/* Star Wars Rogue Squadron ucode
* Ported from Lemmy's LemNemu plugin
* Incomplete!
*/
#include "GLideN64.h"
#include "DebugDump.h"
#include "F3D.h"
#include "F3DEX.h"
#include "N64.h"
#include "RSP.h"
#include "RDP.h"
#include "gSP.h"
#include "gDP.h"
#include "GBI.h"
#include "DisplayWindow.h"
#define F3DSWRS_VTXCOLOR 0x02
#define F3DSWRS_MOVEMEM 0x03
#define F3DSWRS_VTX 0x04
#define F3DSWRS_JUMP3 0x05
#define F3DSWRS_DL 0x06
#define F3DSWRS_BRANCHDL 0x07
#define F3DSWRS_TRI2 0xB4
#define F3DSWRS_JUMP2 0xB5
#define F3DSWRS_MOVEWORD 0xBC
#define F3DSWRS_HEIGHTFIELD 0xBD
#define F3DSWRS_SETOTHERMODE_H_EX 0xBE
#define F3DSWRS_TRI1 0xBF
void F3DSWRS_VertexColor(u32, u32 _w1)
{
gSPSetVertexColorBase( _w1 );
}
void F3DSWRS_MoveMem(u32 _w0, u32)
{
u32 addr = RSP.PC[RSP.PCi] + 8;
switch (_SHIFTR( _w0, 16, 8 )) {
case F3D_MV_VIEWPORT://G_MV_VIEWPORT:
gSPViewport( addr );
break;
case G_MV_L0:
gSPLight( addr, LIGHT_1 );
break;
case G_MV_L1:
gSPLight( addr, LIGHT_2 );
break;
case G_MV_L2:
gSPLight( addr, LIGHT_3 );
break;
case G_MV_L3:
gSPLight( addr, LIGHT_4 );
break;
case G_MV_L4:
gSPLight( addr, LIGHT_5 );
break;
case G_MV_L5:
gSPLight( addr, LIGHT_6 );
break;
case G_MV_L6:
gSPLight( addr, LIGHT_7 );
break;
case G_MV_L7:
gSPLight( addr, LIGHT_8 );
break;
case G_MV_LOOKATY:
gSPLookAt(addr, 1);
break;
case G_MV_LOOKATX:
gSPLookAt(addr, 0);
break;
}
RSP.PC[RSP.PCi] += 16;
}
void F3DSWRS_Vtx(u32 _w0, u32 _w1)
{
gSPSWVertex( _w1, _SHIFTR( _w0, 10, 6 ), 0 );
}
void F3DSWRS_Jump2(u32, u32)
{
RSP.PC[RSP.PCi] = RSP.swDL[RSP.PCi].SWStartDL;
RSP.swDL[RSP.PCi].SWStartDL = _SHIFTR(*(u32*)&RDRAM[RSP.PC[RSP.PCi]], 0, 24);
RSP.swDL[RSP.PCi].SWOtherDL = _SHIFTR(*(u32*)&RDRAM[RSP.PC[RSP.PCi] + 4], 0, 24);
}
void F3DSWRS_Jump3(u32, u32)
{
RSP.PC[RSP.PCi] = RSP.swDL[RSP.PCi].SWOtherDL;
RSP.swDL[RSP.PCi].SWStartDL = _SHIFTR(*(u32*)&RDRAM[RSP.PC[RSP.PCi]], 0, 24);
RSP.swDL[RSP.PCi].SWOtherDL = _SHIFTR(*(u32*)&RDRAM[RSP.PC[RSP.PCi] + 4], 0, 24);
}
void F3DSWRS_DList(u32, u32 _w1)
{
gSPSWDisplayList(_w1);
}
void F3DSWRS_BranchDList(u32, u32 _w1)
{
gSPSWBranchList(_w1);
}
void F3DSWRS_Tri1(u32 _w0, u32 _w1)
{
u32 v1 = (_SHIFTR( _w1, 13, 11 ) & 0x7F8) / 40;
u32 v2 = (_SHIFTR( _w1, 5, 11 ) & 0x7F8) / 40;
u32 v3 = ((_w1 << 3) & 0x7F8) / 40;
u32 nextCMD = *(u32*)&RDRAM[RSP.PC[RSP.PCi] + 8];
GraphicsDrawer & drawer = dwnd().getDrawer();
SPVertex & vtx1 = drawer.getVertex(v1);
u8 *color = &RDRAM[gSP.vertexColorBase + _SHIFTR(nextCMD, 16, 8)];
vtx1.r = color[3] * 0.0039215689f;
vtx1.g = color[2] * 0.0039215689f;
vtx1.b = color[1] * 0.0039215689f;
vtx1.a = color[0] * 0.0039215689f;
SPVertex & vtx2 = drawer.getVertex(v2);
color = &RDRAM[gSP.vertexColorBase + _SHIFTR(nextCMD, 8, 8)];
vtx2.r = color[3] * 0.0039215689f;
vtx2.g = color[2] * 0.0039215689f;
vtx2.b = color[1] * 0.0039215689f;
vtx2.a = color[0] * 0.0039215689f;
SPVertex & vtx3 = drawer.getVertex(v3);
color = &RDRAM[gSP.vertexColorBase + _SHIFTR(nextCMD, 0, 8)];
vtx3.r = color[3] * 0.0039215689f;
vtx3.g = color[2] * 0.0039215689f;
vtx3.b = color[1] * 0.0039215689f;
vtx3.a = color[0] * 0.0039215689f;
if (_w0 & 2) {
// Lemmy's note: does something more here....real rsp code loads some vectors
u32 t1 = *(u32*)&RDRAM[RSP.PC[RSP.PCi] + 16];
vtx1.s = _FIXED2FLOAT( (s16)_SHIFTR(t1, 16, 16), 5 );
vtx1.t = _FIXED2FLOAT((s16)_SHIFTR(t1, 0, 16), 5);
u32 t2 = *(u32*)&RDRAM[RSP.PC[RSP.PCi] + 20];
vtx2.s = _FIXED2FLOAT((s16)_SHIFTR(t2, 16, 16), 5);
vtx2.t = _FIXED2FLOAT((s16)_SHIFTR(t2, 0, 16), 5);
u32 t3 = *(u32*)&RDRAM[RSP.PC[RSP.PCi] + 24];
vtx3.s = _FIXED2FLOAT((s16)_SHIFTR(t3, 16, 16), 5);
vtx3.t = _FIXED2FLOAT((s16)_SHIFTR(t3, 0, 16), 5);
RSP.PC[RSP.PCi] += 16;
}
gSP1Triangle(v1, v2, v3);
RSP.PC[RSP.PCi] += 8;
}
void F3DSWRS_Tri2(u32 _w0, u32 _w1)
{
u32 v1 = (_SHIFTR( _w1, 13, 11 ) & 0x7F8) / 40;
u32 v2 = (_SHIFTR( _w1, 5, 11 ) & 0x7F8) / 40;
u32 v3 = ((_w1 << 3) & 0x7F8) / 40;
u32 v4 = (_SHIFTR( _w1, 21, 11 ) & 0x7F8) / 40;
u32 nextCMD = *(u32*)&RDRAM[RSP.PC[RSP.PCi] + 8];
GraphicsDrawer & drawer = dwnd().getDrawer();
SPVertex & vtx1 = drawer.getVertex(v1);
u8 *color = &RDRAM[gSP.vertexColorBase + _SHIFTR(nextCMD, 16, 8)];
vtx1.r = color[3] * 0.0039215689f;
vtx1.g = color[2] * 0.0039215689f;
vtx1.b = color[1] * 0.0039215689f;
vtx1.a = color[0] * 0.0039215689f;
SPVertex & vtx2 = drawer.getVertex(v2);
color = &RDRAM[gSP.vertexColorBase + _SHIFTR(nextCMD, 8, 8)];
vtx2.r = color[3] * 0.0039215689f;
vtx2.g = color[2] * 0.0039215689f;
vtx2.b = color[1] * 0.0039215689f;
vtx2.a = color[0] * 0.0039215689f;
SPVertex & vtx3 = drawer.getVertex(v3);
color = &RDRAM[gSP.vertexColorBase + _SHIFTR(nextCMD, 0, 8)];
vtx3.r = color[3] * 0.0039215689f;
vtx3.g = color[2] * 0.0039215689f;
vtx3.b = color[1] * 0.0039215689f;
vtx3.a = color[0] * 0.0039215689f;
SPVertex & vtx4 = drawer.getVertex(v4);
color = &RDRAM[gSP.vertexColorBase + _SHIFTR(nextCMD, 24, 8)];
vtx4.r = color[3] * 0.0039215689f;
vtx4.g = color[2] * 0.0039215689f;
vtx4.b = color[1] * 0.0039215689f;
vtx4.a = color[0] * 0.0039215689f;
if (_w0 & 2) {
// Lemmy's note: does something more here....real rsp code loads some vectors
u32 t1 = *(u32*)&RDRAM[RSP.PC[RSP.PCi] + 16];
vtx1.s = _FIXED2FLOAT((s16)_SHIFTR(t1, 16, 16), 5);
vtx1.t = _FIXED2FLOAT((s16)_SHIFTR(t1, 0, 16), 5);
u32 t2 = *(u32*)&RDRAM[RSP.PC[RSP.PCi] + 20];
vtx2.s = _FIXED2FLOAT((s16)_SHIFTR(t2, 16, 16), 5);
vtx2.t = _FIXED2FLOAT((s16)_SHIFTR(t2, 0, 16), 5);
u32 t3 = *(u32*)&RDRAM[RSP.PC[RSP.PCi] + 24];
vtx3.s = _FIXED2FLOAT((s16)_SHIFTR(t3, 16, 16), 5);
vtx3.t = _FIXED2FLOAT((s16)_SHIFTR(t3, 0, 16), 5);
u32 t4 = *(u32*)&RDRAM[RSP.PC[RSP.PCi] + 28];
vtx4.s = _FIXED2FLOAT((s16)_SHIFTR(t4, 16, 16), 5);
vtx4.t = _FIXED2FLOAT((s16)_SHIFTR(t4, 0, 16), 5);
RSP.PC[RSP.PCi] += 16;
}
gSP2Triangles(v1, v2, v3, 0, v1, v3, v4, 0);
RSP.PC[RSP.PCi] += 8;
}
void F3DSWRS_MoveWord(u32 _w0, u32 _w1)
{
switch (_SHIFTR( _w0, 0, 8 )){
// case 0x58C: // This PC is used after a texrect in naboo
// State.NabooPCAfterTexRect = Segment[Command.dl.segment] + Command.dl.addr;
// break;
case G_MW_CLIP:
gSPClipRatio( _w1 );
break;
case G_MW_SEGMENT:
gSPSegment( _SHIFTR( _w0, 8, 16 ) >> 2, _w1 & 0x00FFFFFF );
break;
case G_MW_FOG:
gSPFogFactor( (s16)_SHIFTR( _w1, 16, 16 ), (s16)_SHIFTR( _w1, 0, 16 ) );
break;
case G_MW_LIGHTCOL:
gSPLightColor((_SHIFTR( _w0, 8, 8 ) / 32) + 1, _w1 );
break;
case G_MW_PERSPNORM:
gSPPerspNormalize( _w1 );
break;
}
}
void F3DSWRS_HeightField(u32, u32)
{
// Lemmy's note:
// seems to be similar to JUMP3, but calls actual function with A1=0x2C
// it *might* need the same jump/branch code as JUMP3
RSP.PC[RSP.PCi] += 16;
}
void F3DSWRS_SetOtherMode_H_EX(u32, u32 _w1)
{
RSP.PC[RSP.PCi] += 8;
gDP.otherMode.h &= *(u32*)&RDRAM[RSP.PC[RSP.PCi]];
gDP.otherMode.h |= _w1;
}
void F3DSWRS_Init()
{
gSPSetupFunctions();
// Set GeometryMode flags
GBI_InitFlags( F3D );
GBI.PCStackSize = 10;
// GBI Command Command Value Command Function
GBI_SetGBI( G_SPNOOP, F3D_SPNOOP, F3D_SPNoOp );
GBI_SetGBI( G_MTX, F3D_MTX, F3D_Mtx );
GBI_SetGBI( G_RESERVED0, F3DSWRS_VTXCOLOR, F3DSWRS_VertexColor );
GBI_SetGBI( G_MOVEMEM, F3DSWRS_MOVEMEM, F3DSWRS_MoveMem );
GBI_SetGBI( G_VTX, F3DSWRS_VTX, F3DSWRS_Vtx );
GBI_SetGBI( G_RESERVED1, F3DSWRS_JUMP3, F3DSWRS_Jump3 );
GBI_SetGBI( G_DL, F3DSWRS_DL, F3DSWRS_DList );
GBI_SetGBI( G_RESERVED2, F3DSWRS_BRANCHDL, F3DSWRS_BranchDList );
GBI_SetGBI( G_RESERVED3, F3D_RESERVED3, F3D_Reserved3 );
GBI_SetGBI( G_TRI1, F3DSWRS_TRI1, F3DSWRS_Tri1 );
GBI_SetGBI( G_CULLDL, F3DSWRS_SETOTHERMODE_H_EX,F3DSWRS_SetOtherMode_H_EX );
GBI_SetGBI( G_POPMTX, F3DSWRS_HEIGHTFIELD, F3DSWRS_HeightField );
GBI_SetGBI( G_MOVEWORD, F3DSWRS_MOVEWORD, F3DSWRS_MoveWord );
GBI_SetGBI( G_TEXTURE, F3D_TEXTURE, F3D_Texture );
GBI_SetGBI( G_SETOTHERMODE_H, F3D_SETOTHERMODE_H, F3D_SetOtherMode_H );
GBI_SetGBI( G_SETOTHERMODE_L, F3D_SETOTHERMODE_L, F3D_SetOtherMode_L );
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_QUAD, F3DSWRS_JUMP2, F3DSWRS_Jump2 );
GBI_SetGBI( G_RDPHALF_1, F3DSWRS_TRI2, F3DSWRS_Tri2 );
}

6
src/F3DSWRS.h Normal file
View File

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

View File

@ -28,6 +28,7 @@
#include "F3DEX2MM.h"
#include "F3DTEXA.h"
#include "F3DEX2ACCLAIM.h"
#include "F3DSWRS.h"
#include "ZSort.h"
#include "CRC.h"
#include "Log.h"
@ -56,6 +57,7 @@ SpecialMicrocodeInfo specialMicrocodes[] =
{ F3DPD, true, true, 0x1c4f7869, "Perfect Dark" },
{ Turbo3D, false, true, 0x2bdcfc8a, "Turbo3D" },
{ F3DEX2CBFD, true, true, 0x1b4ace88, "Conker's Bad Fur Day" },
{ F3DSWRS, false, false, 0xda51ccdb, "Star Wars RS" },
{ F3DEX2MM, true, true, 0xd39a0d4f, "Animal Forest" },
{ S2DEX2, false, true, 0x2c399dd, "Animal Forest" },
{ T3DUX, false, true, 0xbad437f2, "T3DUX vers 0.83 for Toukon Road" },
@ -191,6 +193,7 @@ 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;
}
if (gfxContext.isSupported(graphics::SpecialFeatures::NearPlaneClipping)) {

View File

@ -28,7 +28,8 @@
#define T3DUX 19
#define F3DEX2ACCLAIM 21
#define F3DAM 22
#define NONE 23
#define F3DSWRS 23
#define NONE 24
// Fixed point conversion factors
#define FIXED2FLOATRECIP1 0.5f
@ -463,6 +464,13 @@ typedef struct
s16 t2, s2;
} DKRTriangle;
typedef struct
{
s16 y, x;
u16 flag;
s16 z;
} SWVertex;
struct Light
{
u8 pad0, b, g, r;

View File

@ -269,6 +269,12 @@ bool _getTexRectParams(u32 & w2, u32 & w3)
RSP.PC[RSP.PCi] += 8;
return false;
}
if (GBI.getMicrocodeType() == F3DSWRS) {
w2 = *(u32*)&RDRAM[RSP.PC[RSP.PCi] + 8];
w3 = *(u32*)&RDRAM[RSP.PC[RSP.PCi] + 12];
RSP.PC[RSP.PCi] += 8;
return true;
}
w2 = *(u32*)&RDRAM[RSP.PC[RSP.PCi] + 0];
w3 = *(u32*)&RDRAM[RSP.PC[RSP.PCi] + 4];
RSP.PC[RSP.PCi] += 8;

View File

@ -22,6 +22,72 @@ using namespace std;
RSPInfo RSP;
static
void _ProcessDList()
{
while (!RSP.halt) {
if ((RSP.PC[RSP.PCi] + 8) > RDRAMSize) {
#ifdef DEBUG
switch (Debug.level)
{
case DEBUG_LOW:
DebugMsg(DEBUG_LOW | DEBUG_ERROR, "ATTEMPTING TO EXECUTE RSP COMMAND AT INVALID RDRAM LOCATION\n");
break;
case DEBUG_MEDIUM:
DebugMsg(DEBUG_MEDIUM | DEBUG_ERROR, "Attempting to execute RSP command at invalid RDRAM location\n");
break;
case DEBUG_HIGH:
DebugMsg(DEBUG_HIGH | DEBUG_ERROR, "// Attempting to execute RSP command at invalid RDRAM location\n");
break;
}
#endif
break;
}
RSP.w0 = *(u32*)&RDRAM[RSP.PC[RSP.PCi]];
RSP.w1 = *(u32*)&RDRAM[RSP.PC[RSP.PCi] + 4];
RSP.cmd = _SHIFTR(RSP.w0, 24, 8);
#ifdef DEBUG
DebugRSPState(RSP.PCi, RSP.PC[RSP.PCi], _SHIFTR(RSP.w0, 24, 8), RSP.w0, RSP.w1);
DebugMsg(DEBUG_LOW | DEBUG_HANDLED, "0x%08lX: CMD=0x%02lX W0=0x%08lX W1=0x%08lX\n", RSP.PC[RSP.PCi], _SHIFTR(RSP.w0, 24, 8), RSP.w0, RSP.w1);
#endif
RSP.PC[RSP.PCi] += 8;
u32 pci = RSP.PCi;
if (RSP.count == 1)
--pci;
RSP.nextCmd = _SHIFTR(*(u32*)&RDRAM[RSP.PC[pci]], 24, 8);
GBI.cmd[RSP.cmd](RSP.w0, RSP.w1);
RSP_CheckDLCounter();
}
}
static
void _ProcessDListSWRS()
{
// Lemmy's note: read first 64 bits of this dlist
RSP.swDL[0].SWStartDL = _SHIFTR(*(u32*)&RDRAM[RSP.PC[0]], 0, 24);
RSP.swDL[0].SWOtherDL = _SHIFTR(*(u32*)&RDRAM[RSP.PC[0] + 4], 0, 24);
RSP.PC[0] += 8;
while (!RSP.halt) {
if ((RSP.PC[RSP.PCi] + 8) > RDRAMSize) {
break;
}
RSP.w0 = *(u32*)&RDRAM[RSP.PC[RSP.PCi]];
RSP.w1 = *(u32*)&RDRAM[RSP.PC[RSP.PCi] + 4];
RSP.cmd = _SHIFTR(RSP.w0, 24, 8);
RSP.nextCmd = _SHIFTR(*(u32*)&RDRAM[RSP.PC[RSP.PCi] + 8], 24, 8);
GBI.cmd[RSP.cmd](RSP.w0, RSP.w1);
RSP.PC[RSP.PCi] += 8;
RSP_CheckDLCounter();
}
}
void RSP_CheckDLCounter()
{
if (RSP.count != -1) {
@ -84,30 +150,12 @@ void RSP_ProcessDList()
case T3DUX:
RunT3DUX();
break;
case F3DSWRS:
_ProcessDListSWRS();
break;
default:
while (!RSP.halt) {
if ((RSP.PC[RSP.PCi] + 8) > RDRAMSize) {
DebugMsg(DEBUG_NORMAL | DEBUG_ERROR, "ATTEMPTING TO EXECUTE RSP COMMAND AT INVALID RDRAM LOCATION\n");
break;
}
RSP.w0 = *(u32*)&RDRAM[RSP.PC[RSP.PCi]];
RSP.w1 = *(u32*)&RDRAM[RSP.PC[RSP.PCi] + 4];
RSP.cmd = _SHIFTR(RSP.w0, 24, 8);
// DebugRSPState( RSP.PCi, RSP.PC[RSP.PCi], _SHIFTR( RSP.w0, 24, 8 ), RSP.w0, RSP.w1 );
// DebugMsg( DEBUG_LOW | DEBUG_HANDLED, "0x%08lX: CMD=0x%02lX W0=0x%08lX W1=0x%08lX\n", RSP.PC[RSP.PCi], _SHIFTR( RSP.w0, 24, 8 ), RSP.w0, RSP.w1 );
DebugMsg(DEBUG_LOW, "%08x (w0:%08x, w1:%08x): ", RSP.PC[RSP.PCi], RSP.w0, RSP.w1);
RSP.PC[RSP.PCi] += 8;
u32 pci = RSP.PCi;
if (RSP.count == 1)
--pci;
RSP.nextCmd = _SHIFTR(*(u32*)&RDRAM[RSP.PC[pci]], 24, 8);
GBI.cmd[RSP.cmd](RSP.w0, RSP.w1);
RSP_CheckDLCounter();
}
_ProcessDList();
break;
}
if (config.frameBufferEmulation.copyDepthToRDRAM != Config::cdDisable) {

View File

@ -12,6 +12,10 @@ typedef struct
bool bLLE;
char romname[21];
wchar_t pluginpath[PLUGIN_PATH_SIZE];
struct {
u32 SWStartDL;
u32 SWOtherDL;
} swDL[18];
} RSPInfo;
extern RSPInfo RSP;

View File

@ -1440,6 +1440,49 @@ void gSPF3DAMVertex(u32 a, u32 n, u32 v0)
}
}
void gSPSWVertex(u32 a, u32 n, u32 v0)
{
u32 address = RSP_SegmentToPhysical(a);
if ((address + sizeof(SWVertex)* n) > RDRAMSize)
return;
SWVertex *vertex = (SWVertex*)&RDRAM[address];
GraphicsDrawer & drawer = dwnd().getDrawer();
if ((n + v0) <= INDEXMAP_SIZE) {
unsigned int i = v0;
#ifdef __VEC4_OPT
for (; i < n - (n % 4) + v0; i += 4) {
u32 v = i;
for (unsigned 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.st_scaled = 0;
vertex++;
}
gSPProcessVertex4(v);
}
#endif
for (; i < n + v0; ++i) {
u32 v = i;
SPVertex & vtx = drawer.getVertex(v);
vtx.x = vertex->x;
vtx.y = vertex->y;
vtx.z = vertex->z;
gSPProcessVertex(v);
vtx.y = -vtx.y;
vertex++;
}
} else {
LOG(LOG_ERROR, "Using Vertex outside buffer v0=%i, n=%i\n", v0, n);
}
}
void gSPDisplayList( u32 dl )
{
u32 address = RSP_SegmentToPhysical( dl );
@ -1462,6 +1505,17 @@ void gSPDisplayList( u32 dl )
}
}
void gSPSWDisplayList(u32 dl)
{
// Lemmy's note:
// differs from the other DL commands because it does skip the first command
// the first 32 bits are stored, because they are
// used as branch target address in the command in the QUAD "slot"
gSPDisplayList(dl);
RSP.swDL[RSP.PCi].SWStartDL = _SHIFTR(*(u32*)&RDRAM[RSP.PC[RSP.PCi]], 0, 24);
RSP.swDL[RSP.PCi].SWOtherDL = _SHIFTR(*(u32*)&RDRAM[RSP.PC[RSP.PCi] + 4], 0, 24);
}
void gSPBranchList( u32 dl )
{
u32 address = RSP_SegmentToPhysical( dl );
@ -1478,7 +1532,18 @@ void gSPBranchList( u32 dl )
RSP.nextCmd = _SHIFTR( *(u32*)&RDRAM[address], 24, 8 );
}
void gSPBranchLessZ( u32 branchdl, u32 vtx, u32 zval )
void gSPSWBranchList(u32 dl)
{
// Lemmy's note:
// differs from the other DL commands because it does skip the first command
// the first 32 bits are stored, because they are
// used as branch target address in the command in the QUAD "slot"
gSPBranchList(dl);
RSP.swDL[RSP.PCi].SWStartDL = _SHIFTR(*(u32*)&RDRAM[RSP.PC[RSP.PCi]], 0, 24);
RSP.swDL[RSP.PCi].SWOtherDL = _SHIFTR(*(u32*)&RDRAM[RSP.PC[RSP.PCi] + 4], 0, 24);
}
void gSPBranchLessZ(u32 branchdl, u32 vtx, u32 zval)
{
const u32 address = RSP_SegmentToPhysical( branchdl );

View File

@ -159,9 +159,12 @@ void gSPDMAVertex( u32 v, u32 n, u32 v0 );
void gSPCBFDVertex( u32 v, u32 n, u32 v0 );
void gSPT3DUXVertex(u32 v, u32 n, u32 ci);
void gSPF3DAMVertex( u32 v, u32 n, u32 v0 );
void gSPSWVertex(u32 a, u32 n, u32 v0);
void gSPDisplayList(u32 dl);
void gSPSWDisplayList(u32 dl);
void gSPBranchList( u32 dl );
void gSPBranchLessZ( u32 branchdl, u32 vtx, u32 zval );
void gSPSWBranchList(u32 dl);
void gSPBranchLessZ(u32 branchdl, u32 vtx, u32 zval);
void gSPBranchLessW( u32 branchdl, u32 vtx, u32 wval );
void gSPDlistCount(u32 count, u32 v);
void gSPSprite2DBase(u32 _base );

View File

@ -40,6 +40,7 @@ MY_LOCAL_SRC_FILES := \
$(SRCDIR)/F3DGOLDEN.cpp \
$(SRCDIR)/F3DPD.cpp \
$(SRCDIR)/F3DSETA.cpp \
$(SRCDIR)/F3DSWRS.cpp \
$(SRCDIR)/F3DTEXA.cpp \
$(SRCDIR)/FrameBuffer.cpp \
$(SRCDIR)/FrameBufferInfo.cpp \