diff --git a/projects/msvc12/GLideN64.vcxproj b/projects/msvc12/GLideN64.vcxproj index b93b38e6..013c03c0 100644 --- a/projects/msvc12/GLideN64.vcxproj +++ b/projects/msvc12/GLideN64.vcxproj @@ -281,6 +281,7 @@ + @@ -421,6 +422,7 @@ + diff --git a/projects/msvc12/GLideN64.vcxproj.filters b/projects/msvc12/GLideN64.vcxproj.filters index c0f72b5b..487dc88e 100644 --- a/projects/msvc12/GLideN64.vcxproj.filters +++ b/projects/msvc12/GLideN64.vcxproj.filters @@ -362,6 +362,9 @@ Source Files + + Source Files\uCodes + @@ -670,5 +673,8 @@ Header Files + + Header Files\uCodes + \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5cbdee67..1ae5d3b2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -23,6 +23,7 @@ set(GLideN64_SOURCES F3DDKR.cpp F3DEX.cpp F3DEX2.cpp + F3DEX2ACCLAIM.cpp F3DEX2CBFD.cpp F3DEX2MM.cpp F3DGOLDEN.cpp diff --git a/src/F3DEX2ACCLAIM.cpp b/src/F3DEX2ACCLAIM.cpp new file mode 100644 index 00000000..69bb8215 --- /dev/null +++ b/src/F3DEX2ACCLAIM.cpp @@ -0,0 +1,81 @@ +#include +#include +#include "GLideN64.h" +#include "RSP.h" +#include "gSP.h" +#include "F3D.h" +#include "F3DEX.h" +#include "F3DEX2.h" +#include "F3DEX2ACCLAIM.h" + +using namespace std; + +void F3DEX2ACCLAIM_MoveMem( u32 w0, u32 w1 ) +{ + switch (_SHIFTR( w0, 0, 8 )) + { + case F3DEX2_MV_VIEWPORT: + gSPViewport( w1 ); + break; + case G_MV_MATRIX: + gSPForceMatrix( w1 ); + + // force matrix takes two commands + RSP.PC[RSP.PCi] += 8; + break; + case G_MV_LIGHT: + { + const u32 offset = (_SHIFTR(w0, 5, 11))&0x7F8; + if (offset <= 24 * 3) { + const u32 n = offset / 24; + if (n < 2) + gSPLookAt(w1, n); + else + gSPLight(w1, n - 1); + } else { + const u32 n = 2 + (offset - 24 * 4) / 16; + gSPLightAcclaim(w1, n); + } + } + break; + } +} + +void F3DEX2ACCLAIM_Init() +{ + gSPSetupFunctions(); + // Set GeometryMode flags + GBI_InitFlags( F3DEX2 ); + + GBI.PCStackSize = 18; + + // GBI Command Command Value Command Function + GBI_SetGBI( G_RDPHALF_2, F3DEX2_RDPHALF_2, F3D_RDPHalf_2 ); + GBI_SetGBI( G_SETOTHERMODE_H, F3DEX2_SETOTHERMODE_H, F3DEX2_SetOtherMode_H ); + GBI_SetGBI( G_SETOTHERMODE_L, F3DEX2_SETOTHERMODE_L, F3DEX2_SetOtherMode_L ); + GBI_SetGBI( G_RDPHALF_1, F3DEX2_RDPHALF_1, F3D_RDPHalf_1 ); + GBI_SetGBI( G_SPNOOP, F3DEX2_SPNOOP, F3D_SPNoOp ); + GBI_SetGBI( G_ENDDL, F3DEX2_ENDDL, F3D_EndDL ); + GBI_SetGBI( G_DL, F3DEX2_DL, F3D_DList ); + GBI_SetGBI( G_LOAD_UCODE, F3DEX2_LOAD_UCODE, F3DEX_Load_uCode ); + GBI_SetGBI( G_MOVEMEM, F3DEX2_MOVEMEM, F3DEX2ACCLAIM_MoveMem ); + GBI_SetGBI( G_MOVEWORD, F3DEX2_MOVEWORD, F3DEX2_MoveWord ); + GBI_SetGBI( G_MTX, F3DEX2_MTX, F3DEX2_Mtx ); + GBI_SetGBI( G_GEOMETRYMODE, F3DEX2_GEOMETRYMODE, F3DEX2_GeometryMode ); + GBI_SetGBI( G_POPMTX, F3DEX2_POPMTX, F3DEX2_PopMtx ); + GBI_SetGBI( G_TEXTURE, F3DEX2_TEXTURE, F3DEX2_Texture ); + GBI_SetGBI( G_DMA_IO, F3DEX2_DMA_IO, F3DEX2_DMAIO ); + GBI_SetGBI( G_SPECIAL_1, F3DEX2_SPECIAL_1, F3DEX2_Special_1 ); + GBI_SetGBI( G_SPECIAL_2, F3DEX2_SPECIAL_2, F3DEX2_Special_2 ); + GBI_SetGBI( G_SPECIAL_3, F3DEX2_SPECIAL_3, F3DEX2_Special_3 ); + + GBI_SetGBI( G_VTX, F3DEX2_VTX, F3DEX2_Vtx ); + 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_QUAD, F3DEX2_QUAD, F3DEX2_Quad ); + GBI_SetGBI( G_LINE3D, F3DEX2_LINE3D, F3DEX2_Line3D ); +} + diff --git a/src/F3DEX2ACCLAIM.h b/src/F3DEX2ACCLAIM.h new file mode 100644 index 00000000..e6d5047a --- /dev/null +++ b/src/F3DEX2ACCLAIM.h @@ -0,0 +1,7 @@ +#ifndef F3DEX2_ACCLAIM_H +#define F3DEX2_ACCLAIM_H + +void F3DEX2ACCLAIM_Init(); + +#endif + diff --git a/src/GBI.cpp b/src/GBI.cpp index e0ab8f93..b4798ae2 100644 --- a/src/GBI.cpp +++ b/src/GBI.cpp @@ -26,6 +26,7 @@ #include "F3DEX2CBFD.h" #include "F3DEX2MM.h" #include "F3DTEXA.h" +#include "F3DEX2ACCLAIM.h" #include "ZSort.h" #include "CRC.h" #include "Log.h" @@ -57,7 +58,8 @@ SpecialMicrocodeInfo specialMicrocodes[] = { F3DEX2MM, true, true, 0xd39a0d4f, "Animal Forest" }, { S2DEX2, false, true, 0x2c399dd, "Animal Forest" }, { T3DUX, false, true, 0xbad437f2, "T3DUX vers 0.83 for Toukon Road" }, - { T3DUX, false, true, 0xd0a1aa3d, "T3DUX vers 0.85 for Toukon Road 2" } + { T3DUX, false, true, 0xd0a1aa3d, "T3DUX vers 0.85 for Toukon Road 2" }, + { F3DEX2ACCLAIM,true, true, 0xe44df568, "Acclaim games: Turok2 & 3, Armories and South park" } }; u32 G_RDPHALF_1, G_RDPHALF_2, G_RDPHALF_CONT; @@ -139,6 +141,7 @@ bool GBIInfo::isHWLSupported() const case F3DDKR: case F3DJFG: case F3DEX2CBFD: + case F3DEX2ACCLAIM: return false; } return true; @@ -165,26 +168,27 @@ void GBIInfo::_makeCurrent(MicrocodeInfo * _pCurrent) G_TRI1 = G_TRI2 = G_TRIX = G_QUAD = -1; // For correct work of gSPFlushTriangles() switch (m_pCurrent->type) { - case F3D: F3D_Init(); break; - case F3DEX: F3DEX_Init(); break; - case F3DEX2: F3DEX2_Init(); break; - case L3D: L3D_Init(); break; - case L3DEX: L3DEX_Init(); break; - case L3DEX2: L3DEX2_Init(); break; - case S2DEX: S2DEX_Init(); break; - case S2DEX2: S2DEX2_Init(); break; - case F3DDKR: F3DDKR_Init(); break; - case F3DJFG: F3DJFG_Init(); break; - case F3DBETA: F3DBETA_Init(); break; - case F3DPD: F3DPD_Init(); break; - case Turbo3D: F3D_Init(); break; - case ZSortp: ZSort_Init(); break; - case F3DEX2CBFD:F3DEX2CBFD_Init(); break; - case F3DSETA: F3DSETA_Init(); break; - case F3DGOLDEN: F3DGOLDEN_Init(); break; - case F3DEX2MM: F3DEX2MM_Init(); break; - case F3DTEXA: F3DTEXA_Init(); break; - case T3DUX: F3D_Init(); break; + case F3D: F3D_Init(); break; + case F3DEX: F3DEX_Init(); break; + case F3DEX2: F3DEX2_Init(); break; + case L3D: L3D_Init(); break; + case L3DEX: L3DEX_Init(); break; + case L3DEX2: L3DEX2_Init(); break; + case S2DEX: S2DEX_Init(); break; + case S2DEX2: S2DEX2_Init(); break; + case F3DDKR: F3DDKR_Init(); break; + case F3DJFG: F3DJFG_Init(); break; + case F3DBETA: F3DBETA_Init(); break; + case F3DPD: F3DPD_Init(); break; + case Turbo3D: F3D_Init(); break; + case ZSortp: ZSort_Init(); break; + case F3DEX2CBFD: F3DEX2CBFD_Init(); break; + case F3DSETA: F3DSETA_Init(); break; + case F3DGOLDEN: F3DGOLDEN_Init(); break; + case F3DEX2MM: F3DEX2MM_Init(); break; + case F3DTEXA: F3DTEXA_Init(); break; + case T3DUX: F3D_Init(); break; + case F3DEX2ACCLAIM: F3DEX2ACCLAIM_Init(); break; } if (gfxContext.isSupported(graphics::SpecialFeatures::NearPlaneClipping)) { diff --git a/src/GBI.h b/src/GBI.h index de8ffed1..6ab169e7 100644 --- a/src/GBI.h +++ b/src/GBI.h @@ -6,27 +6,28 @@ #include "Types.h" // Microcode Types -#define F3D 0 -#define F3DEX 1 -#define F3DEX2 2 -#define L3D 3 -#define L3DEX 4 -#define L3DEX2 5 -#define S2DEX 6 -#define S2DEX2 7 -#define F3DPD 8 -#define F3DDKR 9 -#define F3DJFG 10 -#define F3DGOLDEN 11 -#define F3DBETA 12 -#define F3DEX2CBFD 13 -#define Turbo3D 14 -#define ZSortp 15 -#define F3DSETA 16 -#define F3DEX2MM 17 -#define F3DTEXA 18 -#define T3DUX 19 -#define NONE 20 +#define F3D 0 +#define F3DEX 1 +#define F3DEX2 2 +#define L3D 3 +#define L3DEX 4 +#define L3DEX2 5 +#define S2DEX 6 +#define S2DEX2 7 +#define F3DPD 8 +#define F3DDKR 9 +#define F3DJFG 10 +#define F3DGOLDEN 11 +#define F3DBETA 12 +#define F3DEX2CBFD 13 +#define Turbo3D 14 +#define ZSortp 15 +#define F3DSETA 16 +#define F3DEX2MM 17 +#define F3DTEXA 18 +#define T3DUX 19 +#define F3DEX2ACCLAIM 21 +#define NONE 22 // Fixed point conversion factors #define FIXED2FLOATRECIP1 0.5f @@ -80,6 +81,7 @@ // These are all the constant flags #define G_ZBUFFER 0x00000001 #define G_SHADE 0x00000004 +#define G_ACCLAIM_LIGHTING 0x00000080 #define G_FOG 0x00010000 #define G_LIGHTING 0x00020000 #define G_TEXTURE_GEN 0x00040000 diff --git a/src/gSP.cpp b/src/gSP.cpp index 054f678e..1dfaba94 100644 --- a/src/gSP.cpp +++ b/src/gSP.cpp @@ -545,6 +545,33 @@ static void gSPPointLightVertex_CBFD(SPVertex & _vtx, float * /*_vPos*/) _vtx.HWLight = 0; } +static +void gSPPointLightVertex_Acclaim(SPVertex & _vtx) +{ + _vtx.HWLight = 0; + + for (u32 l = 2; l < 10; ++l) { + if (gSP.lights.ca[l] < 0) + continue; + + const f32 dX = fabsf(gSP.lights.pos_xyzw[l][X] - _vtx.x); + const f32 dY = fabsf(gSP.lights.pos_xyzw[l][Y] - _vtx.y); + const f32 dZ = fabsf(gSP.lights.pos_xyzw[l][Z] - _vtx.z); + const f32 distance = dX + dY + dZ - gSP.lights.ca[l]; + if (distance >= 0.0f) + continue; + + const f32 light_intensity = -distance * gSP.lights.la[l]; + _vtx.r += gSP.lights.rgb[l][R] * light_intensity; + _vtx.g += gSP.lights.rgb[l][G] * light_intensity; + _vtx.b += gSP.lights.rgb[l][B] * light_intensity; + } + + if (_vtx.r > 1.0f) _vtx.r = 1.0f; + if (_vtx.g > 1.0f) _vtx.g = 1.0f; + if (_vtx.b > 1.0f) _vtx.b = 1.0f; +} + static void gSPBillboardVertex_default(u32 v, u32 i) { GraphicsDrawer & drawer = dwnd().getDrawer(); @@ -625,8 +652,12 @@ void gSPProcessVertex(u32 v) vtx.t = (y + 1.0f) * 512.0f; } } - } else + } else if (gSP.geometryMode & G_ACCLAIM_LIGHTING) { + gSPPointLightVertex_Acclaim(vtx); + } else { vtx.HWLight = 0; + } + } void gSPLoadUcodeEx( u32 uc_start, u32 uc_dstart, u16 uc_dsize ) @@ -879,6 +910,28 @@ void gSPLightCBFD( u32 l, s32 n ) light->r, light->g, light->b ); } +void gSPLightAcclaim(u32 l, s32 n) +{ + u32 addrByte = RSP_SegmentToPhysical(l); + + if (n < 10) { + const u32 addrShort = addrByte >> 1; + gSP.lights.pos_xyzw[n][X] = (f32)(((s16*)RDRAM)[(addrShort + 0) ^ 1]); + gSP.lights.pos_xyzw[n][Y] = (f32)(((s16*)RDRAM)[(addrShort + 1) ^ 1]); + gSP.lights.pos_xyzw[n][Z] = (f32)(((s16*)RDRAM)[(addrShort + 2) ^ 1]); + gSP.lights.ca[n] = (f32)(((s16*)RDRAM)[(addrShort + 5) ^ 1]); + gSP.lights.la[n] = _FIXED2FLOAT((((u16*)RDRAM)[(addrShort + 6) ^ 1]), 16); + gSP.lights.qa[n] = (f32)(((u16*)RDRAM)[(addrShort + 7) ^ 1]); + gSP.lights.rgb[n][R] = _FIXED2FLOAT((RDRAM[(addrByte + 6) ^ 3]), 8); + gSP.lights.rgb[n][G] = _FIXED2FLOAT((RDRAM[(addrByte + 7) ^ 3]), 8); + gSP.lights.rgb[n][B] = _FIXED2FLOAT((RDRAM[(addrByte + 8) ^ 3]), 8); + } + + gSP.changed |= CHANGED_LIGHT; + + DebugMsg(DEBUG_NORMAL, "gSPLightAcclaim( 0x%08X, LIGHT_%i );\n", l, n); +} + void gSPLookAt( u32 _l, u32 _n ) { u32 address = RSP_SegmentToPhysical(_l); diff --git a/src/gSP.h b/src/gSP.h index f210f8ac..23306a44 100644 --- a/src/gSP.h +++ b/src/gSP.h @@ -149,6 +149,7 @@ void gSPForceMatrix( u32 mptr ); void gSPLight( u32 l, s32 n ); void gSPLightCBFD( u32 l, s32 n ); void gSPLookAt( u32 l, u32 n ); +void gSPLightAcclaim(u32 l, s32 n); void gSPVertex( u32 v, u32 n, u32 v0 ); void gSPCIVertex( u32 v, u32 n, u32 v0 ); void gSPDMAVertex( u32 v, u32 n, u32 v0 ); diff --git a/src/mupen64plus-video-gliden64.mk b/src/mupen64plus-video-gliden64.mk index dddf7189..5aa3b6e9 100644 --- a/src/mupen64plus-video-gliden64.mk +++ b/src/mupen64plus-video-gliden64.mk @@ -33,6 +33,7 @@ MY_LOCAL_SRC_FILES := \ $(SRCDIR)/F3DDKR.cpp \ $(SRCDIR)/F3DEX.cpp \ $(SRCDIR)/F3DEX2.cpp \ + $(SRCDIR)/F3DEX2ACCLAIM.cpp \ $(SRCDIR)/F3DEX2CBFD.cpp \ $(SRCDIR)/F3DEX2MM.cpp \ $(SRCDIR)/F3DGOLDEN.cpp \