diff --git a/projects/msvc12/GLideN64.vcxproj b/projects/msvc12/GLideN64.vcxproj
index 106ddd6c..9913c593 100644
--- a/projects/msvc12/GLideN64.vcxproj
+++ b/projects/msvc12/GLideN64.vcxproj
@@ -288,6 +288,7 @@
+
@@ -429,6 +430,7 @@
+
diff --git a/projects/msvc12/GLideN64.vcxproj.filters b/projects/msvc12/GLideN64.vcxproj.filters
index cf3f1466..6727a954 100644
--- a/projects/msvc12/GLideN64.vcxproj.filters
+++ b/projects/msvc12/GLideN64.vcxproj.filters
@@ -368,6 +368,9 @@
Source Files\uCodes
+
+ Source Files\uCodes
+
@@ -682,5 +685,8 @@
Header Files\uCodes
+
+ Header Files\uCodes
+
\ No newline at end of file
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 93785bd9..1e6ff519 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -28,6 +28,7 @@ set(GLideN64_SOURCES
F3DEX2CBFD.cpp
F3DEX2MM.cpp
F3DGOLDEN.cpp
+ F3DSWRS.cpp
F3DTEXA.cpp
F3DPD.cpp
F3DSETA.cpp
diff --git a/src/F3DSWRS.cpp b/src/F3DSWRS.cpp
new file mode 100644
index 00000000..cb844094
--- /dev/null
+++ b/src/F3DSWRS.cpp
@@ -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 );
+}
diff --git a/src/F3DSWRS.h b/src/F3DSWRS.h
new file mode 100644
index 00000000..3514a82f
--- /dev/null
+++ b/src/F3DSWRS.h
@@ -0,0 +1,6 @@
+#ifndef F3DSWRS_H
+#define F3DSWRS_H
+
+void F3DSWRS_Init();
+
+#endif // F3DSWRS_H
diff --git a/src/GBI.cpp b/src/GBI.cpp
index ba94cf21..d4f21dac 100644
--- a/src/GBI.cpp
+++ b/src/GBI.cpp
@@ -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)) {
diff --git a/src/GBI.h b/src/GBI.h
index 9bb7a468..8271dd89 100644
--- a/src/GBI.h
+++ b/src/GBI.h
@@ -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;
diff --git a/src/RDP.cpp b/src/RDP.cpp
index 4dc58b51..388bde34 100644
--- a/src/RDP.cpp
+++ b/src/RDP.cpp
@@ -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;
diff --git a/src/RSP.cpp b/src/RSP.cpp
index 52620567..63a5dbc8 100644
--- a/src/RSP.cpp
+++ b/src/RSP.cpp
@@ -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) {
diff --git a/src/RSP.h b/src/RSP.h
index 7e8aac55..924bd437 100644
--- a/src/RSP.h
+++ b/src/RSP.h
@@ -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;
diff --git a/src/gSP.cpp b/src/gSP.cpp
index fd138842..60dac1cc 100644
--- a/src/gSP.cpp
+++ b/src/gSP.cpp
@@ -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 );
diff --git a/src/gSP.h b/src/gSP.h
index 8bb24ff7..dd1dc204 100644
--- a/src/gSP.h
+++ b/src/gSP.h
@@ -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 );
diff --git a/src/mupen64plus-video-gliden64.mk b/src/mupen64plus-video-gliden64.mk
index db9c6b7e..48286ff7 100644
--- a/src/mupen64plus-video-gliden64.mk
+++ b/src/mupen64plus-video-gliden64.mk
@@ -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 \