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 \