diff --git a/Src/Graphics/IRender3D.h b/Src/Graphics/IRender3D.h
index 5cb74d6..38c2759 100644
--- a/Src/Graphics/IRender3D.h
+++ b/Src/Graphics/IRender3D.h
@@ -16,13 +16,14 @@ public:
   virtual void EndFrame(void) = 0;
   virtual void UploadTextures(unsigned level, unsigned x, unsigned y, unsigned width, unsigned height) = 0;
   virtual void AttachMemory(const uint32_t *cullingRAMLoPtr, const uint32_t *cullingRAMHiPtr, const uint32_t *polyRAMPtr, const uint32_t *vromPtr, const uint16_t *textureRAMPtr) = 0;
-  virtual void SetStepping(int stepping) = 0;
-  virtual bool Init(unsigned xOffset, unsigned yOffset, unsigned xRes, unsigned yRes, unsigned totalXRes, unsigned totalYRes) = 0;
-  virtual void SetSunClamp(bool enable) = 0;
-  
-  virtual ~IRender3D()
-  {
-  }
+  virtual void SetStepping(int stepping) = 0;
+  virtual bool Init(unsigned xOffset, unsigned yOffset, unsigned xRes, unsigned yRes, unsigned totalXRes, unsigned totalYRes) = 0;
+  virtual void SetSunClamp(bool enable) = 0;
+  virtual void SetSignedShade(bool enable) = 0;
+
+  virtual ~IRender3D()
+  {
+  }
 };
 
 #endif  // INCLUDED_IRENDER3D_H
diff --git a/Src/Graphics/Legacy3D/Legacy3D.cpp b/Src/Graphics/Legacy3D/Legacy3D.cpp
index 276f947..18e289f 100644
--- a/Src/Graphics/Legacy3D/Legacy3D.cpp
+++ b/Src/Graphics/Legacy3D/Legacy3D.cpp
@@ -1298,12 +1298,16 @@ bool CLegacy3D::Init(unsigned xOffset, unsigned yOffset, unsigned xRes, unsigned
 }
 
 void CLegacy3D::SetSunClamp(bool enable)
-{
-}
-
-CLegacy3D::CLegacy3D(const Util::Config::Node &config)
-  : m_config(config)
-{ 
+{
+}
+
+void CLegacy3D::SetSignedShade(bool enable)
+{
+}
+
+CLegacy3D::CLegacy3D(const Util::Config::Node &config)
+  : m_config(config)
+{ 
   cullingRAMLo = NULL;
   cullingRAMHi = NULL;
   polyRAM = NULL;
diff --git a/Src/Graphics/Legacy3D/Legacy3D.h b/Src/Graphics/Legacy3D/Legacy3D.h
index a067114..c50beec 100644
--- a/Src/Graphics/Legacy3D/Legacy3D.h
+++ b/Src/Graphics/Legacy3D/Legacy3D.h
@@ -334,13 +334,23 @@ public:
 	* Sets or unsets the clamped light model
 	*
 	* Parameters:
-	*		enable	Set clamp mode
-	*/
-	void SetSunClamp(bool enable);
-	 
-	/*
-	 * CLegacy3D(void):
-	 * ~CLegacy3D(void):
+	*		enable	Set clamp mode
+	*/
+	void SetSunClamp(bool enable);
+
+	/*
+	* SetSignedShade(bool enable);
+	*
+	* Sets the sign-ness of fixed shading value
+	*
+	* Parameters:
+	*		enable	Fixed shading is expressed as signed value
+	*/
+	void SetSignedShade(bool enable);
+
+	/*
+	 * CLegacy3D(void):
+	 * ~CLegacy3D(void):
 	 *
 	 * Parameters:
 	 *    config  Configuration object.
diff --git a/Src/Graphics/New3D/New3D.cpp b/Src/Graphics/New3D/New3D.cpp
index 4bece97..e4ddb5d 100644
--- a/Src/Graphics/New3D/New3D.cpp
+++ b/Src/Graphics/New3D/New3D.cpp
@@ -15,9 +15,9 @@
 namespace New3D {
 
 CNew3D::CNew3D(const Util::Config::Node &config, std::string gameName)
-  : m_r3dShader(config),
-    m_r3dScrollFog(config),
-	m_gameName(gameName)
+	: m_r3dShader(config),
+	  m_r3dScrollFog(config),
+	  m_gameName(gameName)
 {
 	m_cullingRAMLo	= nullptr;
 	m_cullingRAMHi	= nullptr;
@@ -25,6 +25,10 @@ CNew3D::CNew3D(const Util::Config::Node &config, std::string gameName)
 	m_vrom			= nullptr;
 	m_textureRAM	= nullptr;
 	m_sunClamp		= true;
+	m_shadeIsSigned = true;
+
+	// Fall-back mechanism for games with patched (not working) JTAG
+	if (m_gameName == "swtrilgy") m_shadeIsSigned = false;
 }
 
 CNew3D::~CNew3D()
@@ -1130,7 +1134,7 @@ void CNew3D::CacheModel(Model *m, const UINT32 *data)
 				float shade;
 				//==========
 
-				if (ph.SpecularEnabled()) {
+				if (!m_shadeIsSigned) {
 					shade = (ix & 0xFF) / 255.f;									// Star wars is the only game to use unsigned fixed shaded values. It's also the only game to set the specular flag on these polys
 				}
 				else {
@@ -1599,5 +1603,9 @@ void CNew3D::SetSunClamp(bool enable)
 	m_sunClamp = enable;
 }
 
-} // New3D
+void CNew3D::SetSignedShade(bool enable)
+{
+	m_shadeIsSigned = enable;
+}
 
+} // New3D
diff --git a/Src/Graphics/New3D/New3D.h b/Src/Graphics/New3D/New3D.h
index a0bda9d..71ac4a5 100644
--- a/Src/Graphics/New3D/New3D.h
+++ b/Src/Graphics/New3D/New3D.h
@@ -149,12 +149,22 @@ public:
 	* Parameters:
 	*		enable	Set clamp mode
 	*/
-	void SetSunClamp(bool enable);
-
-	/*
-	* CRender3D(config):
-	* ~CRender3D(void):
-	*
+	void SetSunClamp(bool enable);
+
+	/*
+	* SetSignedShade(bool enable);
+	*
+	* Sets the sign-ness of fixed shading value
+	*
+	* Parameters:
+	*		enable	Fixed shading is expressed as signed value
+	*/
+	void SetSignedShade(bool enable);
+
+	/*
+	* CRender3D(config):
+	* ~CRender3D(void):
+	*
 	* Constructor and destructor.
 	*
 	* Parameters:
@@ -200,13 +210,16 @@ private:
 	/*
 	* Data
 	*/
-
-	// Misc
-	std::string m_gameName;
-	bool m_sunClamp;
-
-	// Stepping
-	int		m_step;
+
+	// Misc
+	std::string m_gameName;
+
+	// GPU configuration
+	bool m_sunClamp;
+	bool m_shadeIsSigned;
+
+	// Stepping
+	int		m_step;
 	int		m_offset;			// offset to subtract for words 3 and higher of culling nodes
 	float	m_vertexFactor;		// fixed-point conversion factor for vertices
 
diff --git a/Src/Model3/Real3D.cpp b/Src/Model3/Real3D.cpp
index 601384c..f7cf0ec 100644
--- a/Src/Model3/Real3D.cpp
+++ b/Src/Model3/Real3D.cpp
@@ -150,13 +150,15 @@ void CReal3D::LoadState(CBlockFile *SaveState)
  Rendering
 ******************************************************************************/
 
-static void UpdateRenderConfig(IRender3D *Render3D, uint64_t internalRenderConfig[])
-{
-  bool noSunClamp = (internalRenderConfig[0] & 0x800000) != 0 && (internalRenderConfig[1] & 0x400000) != 0;
-  Render3D->SetSunClamp(!noSunClamp);
-}
-
-void CReal3D::BeginVBlank(int statusCycles)
+static void UpdateRenderConfig(IRender3D *Render3D, uint64_t internalRenderConfig[])
+{
+  bool noSunClamp = (internalRenderConfig[0] & 0x800000) != 0 && (internalRenderConfig[1] & 0x400000) != 0;
+  bool shadeIsSigned = (internalRenderConfig[0] & 0x1) == 0;
+  Render3D->SetSunClamp(!noSunClamp);
+  Render3D->SetSignedShade(shadeIsSigned);
+}
+
+void CReal3D::BeginVBlank(int statusCycles)
 {
 #ifndef NEW_FRAME_TIMING
   // Calculate point at which status bit should change value.  Currently the same timing is used for both the status bit in ReadRegister