summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon
diff options
context:
space:
mode:
authorRodolfo Osvaldo Bogado <rodolfoosvaldobogado@gmail.com>2011-01-29 04:31:56 +0000
committerRodolfo Osvaldo Bogado <rodolfoosvaldobogado@gmail.com>2011-01-29 04:31:56 +0000
commit4c58c7ea031d518f3bbb936fc8f97fa2aad878a3 (patch)
treee3ba23a76be651db0277874a5d5e4d2d93aa52f0 /Source/Core/VideoCommon
parent64af8abcaebf48e183897908f434896f3432bb53 (diff)
initial implementation of fog range adjust, I don't think is correct or work right but is a start.
some tweaks and fixes. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6957 8ced0084-cf51-0410-be5f-012b33b47a6e
Diffstat (limited to 'Source/Core/VideoCommon')
-rw-r--r--Source/Core/VideoCommon/Src/BPMemory.h32
-rw-r--r--Source/Core/VideoCommon/Src/BPStructs.cpp3
-rw-r--r--Source/Core/VideoCommon/Src/PixelShaderGen.cpp30
-rw-r--r--Source/Core/VideoCommon/Src/PixelShaderGen.h2
-rw-r--r--Source/Core/VideoCommon/Src/PixelShaderManager.cpp28
-rw-r--r--Source/Core/VideoCommon/Src/PixelShaderManager.h2
-rw-r--r--Source/Core/VideoCommon/Src/VideoCommon.h12
7 files changed, 83 insertions, 26 deletions
diff --git a/Source/Core/VideoCommon/Src/BPMemory.h b/Source/Core/VideoCommon/Src/BPMemory.h
index abafe201d2..422b515dcc 100644
--- a/Source/Core/VideoCommon/Src/BPMemory.h
+++ b/Source/Core/VideoCommon/Src/BPMemory.h
@@ -678,6 +678,33 @@ union FogParam3
u32 hex;
};
+union FogRangeKElement
+{
+ struct
+ {
+ u32 HI : 12;
+ u32 LO : 12;
+ u32 regid : 8;
+ };
+ u32 HEX;
+};
+
+struct FogRangeParams
+{
+ union RangeBase
+ {
+ struct
+ {
+ u32 Center : 10;
+ u32 Enabled : 1;
+ u32 unused : 13;
+ u32 regid : 8;
+ };
+ u32 hex;
+ };
+ RangeBase Base;
+ FogRangeKElement K[5];
+};
// final eq: ze = A/(B_MAG - (Zs>>B_SHF));
struct FogParams
{
@@ -902,10 +929,7 @@ struct BPMemory
FourTexUnits tex[2]; //80-bf
TevStageCombiner combiners[16]; //0xC0-0xDF
TevReg tevregs[4]; //0xE0
- u32 fogRangeAdj; //0xE8
- u32 unknown15[3]; //0xe9,0xea,0xeb - fog related
- u32 tev_range_adj_c; //0xec - screenx center for range adjustment, range adjustment enable
- u32 tev_range_adj_k; //0xed - specifies range adjustment function = sqrt(x*x+k*k)/k
+ FogRangeParams fogRange;
FogParams fog; //0xEE,0xEF,0xF0,0xF1,0xF2
AlphaFunc alphaFunc; //0xF3
ZTex1 ztex1; //0xf4,0xf5
diff --git a/Source/Core/VideoCommon/Src/BPStructs.cpp b/Source/Core/VideoCommon/Src/BPStructs.cpp
index 9a8e5af10c..17ca146653 100644
--- a/Source/Core/VideoCommon/Src/BPStructs.cpp
+++ b/Source/Core/VideoCommon/Src/BPStructs.cpp
@@ -320,6 +320,9 @@ void BPWritten(const BPCmd& bp)
case BPMEM_FOGRANGE+3:
case BPMEM_FOGRANGE+4:
case BPMEM_FOGRANGE+5:
+ if (!GetConfig(CONFIG_DISABLEFOG))
+ PixelShaderManager::SetFogRangeAdjustChanged();
+ break;
case BPMEM_FOGPARAM0:
case BPMEM_FOGBMAGNITUDE:
case BPMEM_FOGBEXPONENT:
diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp
index 8c3805df9a..f5f9c84f46 100644
--- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp
+++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp
@@ -61,7 +61,7 @@ void GetPixelShaderId(PIXELSHADERUID *uid, DSTALPHA_MODE dstAlphaMode)
uid->values[2] = (u32)bpmem.fog.c_proj_fsel.fsel |
((u32)bpmem.fog.c_proj_fsel.proj << 3) |
- ((u32)enableZTexture << 4);
+ ((u32)enableZTexture << 4) | ((u32)bpmem.fogRange.Base.Enabled << 5);
if(g_ActiveConfig.bEnablePixelLigting && g_ActiveConfig.backend_info.bSupportsPixelLighting)
{
@@ -504,7 +504,7 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType
WRITE(p, "uniform float4 "I_ZBIAS"[2] : register(c%d);\n", C_ZBIAS);
WRITE(p, "uniform float4 "I_INDTEXSCALE"[2] : register(c%d);\n", C_INDTEXSCALE);
WRITE(p, "uniform float4 "I_INDTEXMTX"[6] : register(c%d);\n", C_INDTEXMTX);
- WRITE(p, "uniform float4 "I_FOG"[2] : register(c%d);\n", C_FOG);
+ WRITE(p, "uniform float4 "I_FOG"[3] : register(c%d);\n", C_FOG);
if(g_ActiveConfig.bEnablePixelLigting && g_ActiveConfig.backend_info.bSupportsPixelLighting)
{
@@ -521,7 +521,7 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType
WRITE(p, " out float4 ocol0 : COLOR0,%s%s\n in float4 rawpos : %s,\n",
dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND ? "\n out float4 ocol1 : COLOR1," : "",
DepthTextureEnable ? "\n out float depth : DEPTH," : "",
- ApiType == API_OPENGL ? "WPOS" : "POSITION");
+ ApiType == API_OPENGL ? "WPOS" : "VPOS");
}
else
{
@@ -792,7 +792,7 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType
}
// emulation of unisgned 8 overflow when casting if needed
if(RegisterStates[0].AlphaNeedOverflowControl || RegisterStates[0].ColorNeedOverflowControl)
- WRITE(p, "prev = frac(4.0f + prev * (255.0f/256.0f)) * (256.0f/255.0f);\n");
+ WRITE(p, "prev = frac(prev * (255.0f/256.0f)) * (256.0f/255.0f);\n");
if (!WriteAlphaTest(p, ApiType, dstAlphaMode))
{
@@ -997,7 +997,7 @@ static void WriteStage(char *&p, int n, API_TYPE ApiType)
if(bCRas || bARas)
{
WRITE(p, "rastemp = %s.%s;\n", tevRasTable[bpmem.tevorders[n / 2].getColorChan(n & 1)], rasswap);
- WRITE(p, "crastemp = frac(4.0f + rastemp * (255.0f/256.0f)) * (256.0f/255.0f);\n");
+ WRITE(p, "crastemp = frac(rastemp * (255.0f/256.0f)) * (256.0f/255.0f);\n");
}
@@ -1030,7 +1030,7 @@ static void WriteStage(char *&p, int n, API_TYPE ApiType)
WRITE(p, "konsttemp = float4(%s, %s);\n", tevKSelTableC[kc], tevKSelTableA[ka]);
if(kc > 7 || ka > 7)
{
- WRITE(p, "ckonsttemp = frac(4.0f + konsttemp * (255.0f/256.0f)) * (256.0f/255.0f);\n");
+ WRITE(p, "ckonsttemp = frac(konsttemp * (255.0f/256.0f)) * (256.0f/255.0f);\n");
}
else
{
@@ -1050,7 +1050,7 @@ static void WriteStage(char *&p, int n, API_TYPE ApiType)
{
if(RegisterStates[0].AlphaNeedOverflowControl || RegisterStates[0].ColorNeedOverflowControl)
{
- WRITE(p, "cprev = frac(4.0f + prev * (255.0f/256.0f)) * (256.0f/255.0f);\n");
+ WRITE(p, "cprev = frac(prev * (255.0f/256.0f)) * (256.0f/255.0f);\n");
RegisterStates[0].AlphaNeedOverflowControl = false;
RegisterStates[0].ColorNeedOverflowControl = false;
}
@@ -1073,7 +1073,7 @@ static void WriteStage(char *&p, int n, API_TYPE ApiType)
{
if(RegisterStates[1].AlphaNeedOverflowControl || RegisterStates[1].ColorNeedOverflowControl)
{
- WRITE(p, "cc0 = frac(4.0f + c0 * (255.0f/256.0f)) * (256.0f/255.0f);\n");
+ WRITE(p, "cc0 = frac(c0 * (255.0f/256.0f)) * (256.0f/255.0f);\n");
RegisterStates[1].AlphaNeedOverflowControl = false;
RegisterStates[1].ColorNeedOverflowControl = false;
}
@@ -1096,7 +1096,7 @@ static void WriteStage(char *&p, int n, API_TYPE ApiType)
{
if(RegisterStates[2].AlphaNeedOverflowControl || RegisterStates[2].ColorNeedOverflowControl)
{
- WRITE(p, "cc1 = frac(4.0f + c1 * (255.0f/256.0f)) * (256.0f/255.0f);\n");
+ WRITE(p, "cc1 = frac(c1 * (255.0f/256.0f)) * (256.0f/255.0f);\n");
RegisterStates[2].AlphaNeedOverflowControl = false;
RegisterStates[2].ColorNeedOverflowControl = false;
}
@@ -1119,7 +1119,7 @@ static void WriteStage(char *&p, int n, API_TYPE ApiType)
{
if(RegisterStates[3].AlphaNeedOverflowControl || RegisterStates[3].ColorNeedOverflowControl)
{
- WRITE(p, "cc2 = frac(4.0f + c2 * (255.0f/256.0f)) * (256.0f/255.0f);\n");
+ WRITE(p, "cc2 = frac(c2 * (255.0f/256.0f)) * (256.0f/255.0f);\n");
RegisterStates[3].AlphaNeedOverflowControl = false;
RegisterStates[3].ColorNeedOverflowControl = false;
}
@@ -1340,10 +1340,15 @@ static void WriteFog(char *&p)
WRITE (p, " float ze = "I_FOG"[1].x * zCoord;\n");
}
- // stuff to do!
- // here, where we'll have to add/handle x range adjustment (if related BP register it's enabled)
// x_adjust = sqrt((x-center)^2 + k^2)/k
// ze *= x_adjust
+ //this is complitly teorical as the real hard seems to use a table intead of calculate the values.
+ if(bpmem.fogRange.Base.Enabled)
+ {
+ WRITE (p, " float x_adjust = (2.0f * (clipPos.x / "I_FOG"[2].y)) - 1.0f - "I_FOG"[2].x;\n");
+ WRITE (p, " x_adjust = sqrt(x_adjust * x_adjust + "I_FOG"[2].z * "I_FOG"[2].z) / "I_FOG"[2].z;\n");
+ WRITE (p, " ze *= x_adjust;\n");
+ }
WRITE (p, " float fog = saturate(ze - "I_FOG"[1].z);\n");
@@ -1359,4 +1364,5 @@ static void WriteFog(char *&p)
WRITE(p, " prev.rgb = lerp(prev.rgb,"I_FOG"[0].rgb,fog);\n");
+
}
diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.h b/Source/Core/VideoCommon/Src/PixelShaderGen.h
index e2d8ca847e..10c39ad34e 100644
--- a/Source/Core/VideoCommon/Src/PixelShaderGen.h
+++ b/Source/Core/VideoCommon/Src/PixelShaderGen.h
@@ -41,7 +41,7 @@
#define C_INDTEXMTX (C_INDTEXSCALE + 2) //21
#define C_FOG (C_INDTEXMTX + 6) //27
-#define C_PLIGHTS (C_FOG + 2)
+#define C_PLIGHTS (C_FOG + 3)
#define C_PMATERIALS (C_PLIGHTS + 40)
#define C_PENVCONST_END (C_PMATERIALS + 4)
#define PIXELSHADERUID_MAX_VALUES (5 + 32 + 6 + 11 + 2)
diff --git a/Source/Core/VideoCommon/Src/PixelShaderManager.cpp b/Source/Core/VideoCommon/Src/PixelShaderManager.cpp
index fb484ca0c0..96ba2cb3f2 100644
--- a/Source/Core/VideoCommon/Src/PixelShaderManager.cpp
+++ b/Source/Core/VideoCommon/Src/PixelShaderManager.cpp
@@ -22,6 +22,7 @@
#include "PixelShaderManager.h"
#include "VideoCommon.h"
#include "VideoConfig.h"
+#include "RenderBase.h"
static float GC_ALIGNED16(s_fMaterials[16]);
static int s_nColorsChanged[2]; // 0 - regular colors, 1 - k colors
static int s_nIndTexMtxChanged;
@@ -31,6 +32,7 @@ static bool s_bZTextureTypeChanged;
static bool s_bDepthRangeChanged;
static bool s_bFogColorChanged;
static bool s_bFogParamChanged;
+static bool s_bFogRangeAdjustChanged;
static int nLightsChanged[2]; // min,max
static float lastDepthRange[2]; // 0 = far z, 1 = far - near
static float lastRGBAfull[2][4][4];
@@ -57,7 +59,7 @@ void PixelShaderManager::Dirty()
s_nIndTexScaleChanged = 0xFF;
s_nIndTexMtxChanged = 15;
s_bAlphaChanged = s_bZBiasChanged = s_bZTextureTypeChanged = s_bDepthRangeChanged = true;
- s_bFogColorChanged = s_bFogParamChanged = true;
+ s_bFogRangeAdjustChanged = s_bFogColorChanged = s_bFogParamChanged = true;
nLightsChanged[0] = 0; nLightsChanged[1] = 0x80;
nMaterialsChanged = 15;
}
@@ -214,6 +216,25 @@ void PixelShaderManager::SetConstants()
s_bFogParamChanged = false;
}
+ if (s_bFogRangeAdjustChanged)
+ {
+ if(!g_ActiveConfig.bDisableFog && bpmem.fogRange.Base.Enabled == 1)
+ {
+ //bpmem.fogRange.Base.Center : center of the viewport in x axis. observation: bpmem.fogRange.Base.Center = realcenter + 342;
+ int center = ((u32)bpmem.fogRange.Base.Center) - 342;
+ // normalice center to make calculations easy
+ float ScreenSpaceCenter = center / (2.0f * xfregs.rawViewport[0]);
+ ScreenSpaceCenter = (ScreenSpaceCenter * 2.0f) - 1.0f;
+ //bpmem.fogRange.K seems to be a table of precalculated coeficients for the adjust factor
+ //observations: bpmem.fogRange.K[0].LO apears to be the lowest value and bpmem.fogRange.K[4].HI the largest
+ // they always seems to be larger than 256 so my teory is :
+ // they are the coeficients from the center to th e border of the screen
+ // so to simplify i use the hi coeficient as K in the shader taking 256 as the scale
+ SetPSConstant4f(C_FOG + 2, ScreenSpaceCenter, (float)Renderer::EFBToScaledX((int)(2.0f * xfregs.rawViewport[0])), bpmem.fogRange.K[4].HI / 256.0f,0.0f);
+ }
+ s_bFogRangeAdjustChanged = false;
+ }
+
if (g_ActiveConfig.bEnablePixelLigting && g_ActiveConfig.backend_info.bSupportsPixelLighting && nLightsChanged[0] >= 0) // config check added because the code in here was crashing for me inside SetPSConstant4f
{
// lights don't have a 1 to 1 mapping, the color component needs to be converted to 4 floats
@@ -394,6 +415,11 @@ void PixelShaderManager::SetFogParamChanged()
s_bFogParamChanged = true;
}
+void PixelShaderManager::SetFogRangeAdjustChanged()
+{
+ s_bFogRangeAdjustChanged = true;
+}
+
void PixelShaderManager::SetColorMatrix(const float* pmatrix)
{
SetMultiPSConstant4fv(C_COLORMATRIX,7,pmatrix);
diff --git a/Source/Core/VideoCommon/Src/PixelShaderManager.h b/Source/Core/VideoCommon/Src/PixelShaderManager.h
index de46341441..f3428eda6f 100644
--- a/Source/Core/VideoCommon/Src/PixelShaderManager.h
+++ b/Source/Core/VideoCommon/Src/PixelShaderManager.h
@@ -51,9 +51,11 @@ public:
static void SetTexCoordChanged(u8 texmapid);
static void SetFogColorChanged();
static void SetFogParamChanged();
+ static void SetFogRangeAdjustChanged();
static void SetColorMatrix(const float* pmatrix);
static void InvalidateXFRange(int start, int end);
static void SetMaterialColor(int index, u32 data);
+
};
diff --git a/Source/Core/VideoCommon/Src/VideoCommon.h b/Source/Core/VideoCommon/Src/VideoCommon.h
index 5a573369cd..0b29874178 100644
--- a/Source/Core/VideoCommon/Src/VideoCommon.h
+++ b/Source/Core/VideoCommon/Src/VideoCommon.h
@@ -157,14 +157,10 @@ inline u32 RGBA8ToRGBA6ToRGBA8(u32 src)
inline u32 RGBA8ToRGB565ToRGBA8(u32 src)
{
- u32 color = src;
- u32 dstr5 = (color & 0xFF0000) >> 19;
- u32 dstg6 = (color & 0xFF00) >> 10;
- u32 dstb5 = (color & 0xFF) >> 3;
- u32 dstr8 = (dstr5 << 3) | (dstr5 >> 2);
- u32 dstg8 = (dstg6 << 2) | (dstg6 >> 4);
- u32 dstb8 = (dstb5 << 3) | (dstb5 >> 2);
- color = 0xFF000000 | (dstr8 << 16) | (dstg8 << 8) | dstb8;
+ u32 color = (src & 0xF8FCF8);
+ color |= (color >> 5) & 0x070007;
+ color |= (color >> 6) & 0x000300;
+ color |= 0xFF000000;
return color;
}