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 \