Convert XFMemory to BitField and enum class
Additionally a new ClipDisable union has been added (though it is not currently used by Dolphin).
This commit is contained in:
parent
953e09428f
commit
aab81d5aa0
|
@ -80,7 +80,7 @@ void TransformPosition(const InputVertexData* src, OutputVertexData* dst)
|
|||
const float* mat = &xfmem.posMatrices[src->posMtx * 4];
|
||||
MultiplyVec3Mat34(src->position, mat, dst->mvPosition);
|
||||
|
||||
if (xfmem.projection.type == GX_PERSPECTIVE)
|
||||
if (xfmem.projection.type == ProjectionType::Perspective)
|
||||
{
|
||||
MultipleVec3Perspective(dst->mvPosition, xfmem.projection.rawProjection,
|
||||
dst->projectedPosition);
|
||||
|
@ -115,39 +115,42 @@ static void TransformTexCoordRegular(const TexMtxInfo& texinfo, int coordNum,
|
|||
Vec3 src;
|
||||
switch (texinfo.sourcerow)
|
||||
{
|
||||
case XF_SRCGEOM_INROW:
|
||||
case SourceRow::Geom:
|
||||
src = srcVertex->position;
|
||||
break;
|
||||
case XF_SRCNORMAL_INROW:
|
||||
case SourceRow::Normal:
|
||||
src = srcVertex->normal[0];
|
||||
break;
|
||||
case XF_SRCBINORMAL_T_INROW:
|
||||
case SourceRow::BinormalT:
|
||||
src = srcVertex->normal[1];
|
||||
break;
|
||||
case XF_SRCBINORMAL_B_INROW:
|
||||
case SourceRow::BinormalB:
|
||||
src = srcVertex->normal[2];
|
||||
break;
|
||||
default:
|
||||
ASSERT(texinfo.sourcerow >= XF_SRCTEX0_INROW && texinfo.sourcerow <= XF_SRCTEX7_INROW);
|
||||
src.x = srcVertex->texCoords[texinfo.sourcerow - XF_SRCTEX0_INROW][0];
|
||||
src.y = srcVertex->texCoords[texinfo.sourcerow - XF_SRCTEX0_INROW][1];
|
||||
{
|
||||
ASSERT(texinfo.sourcerow >= SourceRow::Tex0 && texinfo.sourcerow <= SourceRow::Tex7);
|
||||
u32 texnum = static_cast<u32>(texinfo.sourcerow.Value()) - static_cast<u32>(SourceRow::Tex0);
|
||||
src.x = srcVertex->texCoords[texnum][0];
|
||||
src.y = srcVertex->texCoords[texnum][1];
|
||||
src.z = 1.0f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const float* mat = &xfmem.posMatrices[srcVertex->texMtx[coordNum] * 4];
|
||||
Vec3* dst = &dstVertex->texCoords[coordNum];
|
||||
|
||||
if (texinfo.projection == XF_TEXPROJ_ST)
|
||||
if (texinfo.projection == TexSize::ST)
|
||||
{
|
||||
if (texinfo.inputform == XF_TEXINPUT_AB11)
|
||||
if (texinfo.inputform == TexInputForm::AB11)
|
||||
MultiplyVec2Mat24(src, mat, *dst);
|
||||
else
|
||||
MultiplyVec3Mat24(src, mat, *dst);
|
||||
}
|
||||
else // texinfo.projection == XF_TEXPROJ_STQ
|
||||
else // texinfo.projection == TexSize::STQ
|
||||
{
|
||||
if (texinfo.inputform == XF_TEXINPUT_AB11)
|
||||
if (texinfo.inputform == TexInputForm::AB11)
|
||||
MultiplyVec2Mat34(src, mat, *dst);
|
||||
else
|
||||
MultiplyVec3Mat34(src, mat, *dst);
|
||||
|
@ -209,28 +212,28 @@ static float CalculateLightAttn(const LightPointer* light, Vec3* _ldir, const Ve
|
|||
|
||||
switch (chan.attnfunc)
|
||||
{
|
||||
case LIGHTATTN_NONE:
|
||||
case LIGHTATTN_DIR:
|
||||
case AttenuationFunc::None:
|
||||
case AttenuationFunc::Dir:
|
||||
{
|
||||
ldir = ldir.Normalized();
|
||||
if (ldir == Vec3(0.0f, 0.0f, 0.0f))
|
||||
ldir = normal;
|
||||
break;
|
||||
}
|
||||
case LIGHTATTN_SPEC:
|
||||
case AttenuationFunc::Spec:
|
||||
{
|
||||
ldir = ldir.Normalized();
|
||||
attn = (ldir * normal) >= 0.0 ? std::max(0.0f, light->dir * normal) : 0;
|
||||
Vec3 attLen = Vec3(1.0, attn, attn * attn);
|
||||
Vec3 cosAttn = light->cosatt;
|
||||
Vec3 distAttn = light->distatt;
|
||||
if (chan.diffusefunc != LIGHTDIF_NONE)
|
||||
if (chan.diffusefunc != DiffuseFunc::None)
|
||||
distAttn = distAttn.Normalized();
|
||||
|
||||
attn = SafeDivide(std::max(0.0f, attLen * cosAttn), attLen * distAttn);
|
||||
break;
|
||||
}
|
||||
case LIGHTATTN_SPOT:
|
||||
case AttenuationFunc::Spot:
|
||||
{
|
||||
float dist2 = ldir.Length2();
|
||||
float dist = sqrtf(dist2);
|
||||
|
@ -243,7 +246,7 @@ static float CalculateLightAttn(const LightPointer* light, Vec3* _ldir, const Ve
|
|||
break;
|
||||
}
|
||||
default:
|
||||
PanicAlertFmt("LightColor");
|
||||
PanicAlertFmt("Invalid attnfunc: {}", chan.attnfunc);
|
||||
}
|
||||
|
||||
return attn;
|
||||
|
@ -260,18 +263,18 @@ static void LightColor(const Vec3& pos, const Vec3& normal, u8 lightNum, const L
|
|||
float difAttn = ldir * normal;
|
||||
switch (chan.diffusefunc)
|
||||
{
|
||||
case LIGHTDIF_NONE:
|
||||
case DiffuseFunc::None:
|
||||
AddScaledIntegerColor(light->color, attn, lightCol);
|
||||
break;
|
||||
case LIGHTDIF_SIGN:
|
||||
case DiffuseFunc::Sign:
|
||||
AddScaledIntegerColor(light->color, attn * difAttn, lightCol);
|
||||
break;
|
||||
case LIGHTDIF_CLAMP:
|
||||
case DiffuseFunc::Clamp:
|
||||
difAttn = std::max(0.0f, difAttn);
|
||||
AddScaledIntegerColor(light->color, attn * difAttn, lightCol);
|
||||
break;
|
||||
default:
|
||||
ASSERT(0);
|
||||
PanicAlertFmt("Invalid diffusefunc: {}", chan.attnfunc);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -286,18 +289,18 @@ static void LightAlpha(const Vec3& pos, const Vec3& normal, u8 lightNum, const L
|
|||
float difAttn = ldir * normal;
|
||||
switch (chan.diffusefunc)
|
||||
{
|
||||
case LIGHTDIF_NONE:
|
||||
case DiffuseFunc::None:
|
||||
lightCol += light->color[0] * attn;
|
||||
break;
|
||||
case LIGHTDIF_SIGN:
|
||||
case DiffuseFunc::Sign:
|
||||
lightCol += light->color[0] * attn * difAttn;
|
||||
break;
|
||||
case LIGHTDIF_CLAMP:
|
||||
case DiffuseFunc::Clamp:
|
||||
difAttn = std::max(0.0f, difAttn);
|
||||
lightCol += light->color[0] * attn * difAttn;
|
||||
break;
|
||||
default:
|
||||
ASSERT(0);
|
||||
PanicAlertFmt("Invalid diffusefunc: {}", chan.attnfunc);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -311,17 +314,16 @@ void TransformColor(const InputVertexData* src, OutputVertexData* dst)
|
|||
|
||||
// color
|
||||
const LitChannel& colorchan = xfmem.color[chan];
|
||||
if (colorchan.matsource)
|
||||
matcolor = src->color[chan]; // vertex
|
||||
if (colorchan.matsource == MatSource::Vertex)
|
||||
matcolor = src->color[chan];
|
||||
else
|
||||
std::memcpy(matcolor.data(), &xfmem.matColor[chan], sizeof(u32));
|
||||
|
||||
if (colorchan.enablelighting)
|
||||
{
|
||||
Vec3 lightCol;
|
||||
if (colorchan.ambsource)
|
||||
if (colorchan.ambsource == AmbSource::Vertex)
|
||||
{
|
||||
// vertex
|
||||
lightCol.x = src->color[chan][1];
|
||||
lightCol.y = src->color[chan][2];
|
||||
lightCol.z = src->color[chan][3];
|
||||
|
@ -355,16 +357,16 @@ void TransformColor(const InputVertexData* src, OutputVertexData* dst)
|
|||
|
||||
// alpha
|
||||
const LitChannel& alphachan = xfmem.alpha[chan];
|
||||
if (alphachan.matsource)
|
||||
matcolor[0] = src->color[chan][0]; // vertex
|
||||
if (alphachan.matsource == MatSource::Vertex)
|
||||
matcolor[0] = src->color[chan][0];
|
||||
else
|
||||
matcolor[0] = xfmem.matColor[chan] & 0xff;
|
||||
|
||||
if (xfmem.alpha[chan].enablelighting)
|
||||
{
|
||||
float lightCol;
|
||||
if (alphachan.ambsource)
|
||||
lightCol = src->color[chan][0]; // vertex
|
||||
if (alphachan.ambsource == AmbSource::Vertex)
|
||||
lightCol = src->color[chan][0];
|
||||
else
|
||||
lightCol = static_cast<float>(xfmem.ambColor[chan] & 0xff);
|
||||
|
||||
|
@ -397,10 +399,10 @@ void TransformTexCoord(const InputVertexData* src, OutputVertexData* dst)
|
|||
|
||||
switch (texinfo.texgentype)
|
||||
{
|
||||
case XF_TEXGEN_REGULAR:
|
||||
case TexGenType::Regular:
|
||||
TransformTexCoordRegular(texinfo, coordNum, src, dst);
|
||||
break;
|
||||
case XF_TEXGEN_EMBOSS_MAP:
|
||||
case TexGenType::EmbossMap:
|
||||
{
|
||||
const LightPointer* light = (const LightPointer*)&xfmem.lights[texinfo.embosslightshift];
|
||||
|
||||
|
@ -413,22 +415,22 @@ void TransformTexCoord(const InputVertexData* src, OutputVertexData* dst)
|
|||
dst->texCoords[coordNum].z = dst->texCoords[texinfo.embosssourceshift].z;
|
||||
}
|
||||
break;
|
||||
case XF_TEXGEN_COLOR_STRGBC0:
|
||||
ASSERT(texinfo.sourcerow == XF_SRCCOLORS_INROW);
|
||||
ASSERT(texinfo.inputform == XF_TEXINPUT_AB11);
|
||||
case TexGenType::Color0:
|
||||
ASSERT(texinfo.sourcerow == SourceRow::Colors);
|
||||
ASSERT(texinfo.inputform == TexInputForm::AB11);
|
||||
dst->texCoords[coordNum].x = (float)dst->color[0][0] / 255.0f;
|
||||
dst->texCoords[coordNum].y = (float)dst->color[0][1] / 255.0f;
|
||||
dst->texCoords[coordNum].z = 1.0f;
|
||||
break;
|
||||
case XF_TEXGEN_COLOR_STRGBC1:
|
||||
ASSERT(texinfo.sourcerow == XF_SRCCOLORS_INROW);
|
||||
ASSERT(texinfo.inputform == XF_TEXINPUT_AB11);
|
||||
case TexGenType::Color1:
|
||||
ASSERT(texinfo.sourcerow == SourceRow::Colors);
|
||||
ASSERT(texinfo.inputform == TexInputForm::AB11);
|
||||
dst->texCoords[coordNum].x = (float)dst->color[1][0] / 255.0f;
|
||||
dst->texCoords[coordNum].y = (float)dst->color[1][1] / 255.0f;
|
||||
dst->texCoords[coordNum].z = 1.0f;
|
||||
break;
|
||||
default:
|
||||
ERROR_LOG_FMT(VIDEO, "Bad tex gen type {}", texinfo.texgentype.Value());
|
||||
ERROR_LOG_FMT(VIDEO, "Bad tex gen type {}", texinfo.texgentype);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ void GeometryShaderManager::SetConstants()
|
|||
{
|
||||
s_projection_changed = false;
|
||||
|
||||
if (xfmem.projection.type == GX_PERSPECTIVE)
|
||||
if (xfmem.projection.type == ProjectionType::Perspective)
|
||||
{
|
||||
float offset = (g_ActiveConfig.iStereoDepth / 1000.0f) *
|
||||
(g_ActiveConfig.iStereoDepthPercentage / 100.0f);
|
||||
|
|
|
@ -17,29 +17,32 @@ static void GenerateLightShader(ShaderCode& object, const LightingUidData& uid_d
|
|||
const char* swizzle = alpha ? "a" : "rgb";
|
||||
const char* swizzle_components = (alpha) ? "" : "3";
|
||||
|
||||
const u32 attnfunc = (uid_data.attnfunc >> (2 * litchan_index)) & 0x3;
|
||||
const u32 diffusefunc = (uid_data.diffusefunc >> (2 * litchan_index)) & 0x3;
|
||||
const auto attnfunc =
|
||||
static_cast<AttenuationFunc>((uid_data.attnfunc >> (2 * litchan_index)) & 0x3);
|
||||
const auto diffusefunc =
|
||||
static_cast<DiffuseFunc>((uid_data.diffusefunc >> (2 * litchan_index)) & 0x3);
|
||||
|
||||
switch (attnfunc)
|
||||
{
|
||||
case LIGHTATTN_NONE:
|
||||
case LIGHTATTN_DIR:
|
||||
case AttenuationFunc::None:
|
||||
case AttenuationFunc::Dir:
|
||||
object.Write("ldir = normalize(" LIGHT_POS ".xyz - pos.xyz);\n", LIGHT_POS_PARAMS(index));
|
||||
object.Write("attn = 1.0;\n");
|
||||
object.Write("if (length(ldir) == 0.0)\n\t ldir = _norm0;\n");
|
||||
break;
|
||||
case LIGHTATTN_SPEC:
|
||||
case AttenuationFunc::Spec:
|
||||
object.Write("ldir = normalize(" LIGHT_POS ".xyz - pos.xyz);\n", LIGHT_POS_PARAMS(index));
|
||||
object.Write("attn = (dot(_norm0, ldir) >= 0.0) ? max(0.0, dot(_norm0, " LIGHT_DIR
|
||||
".xyz)) : 0.0;\n",
|
||||
LIGHT_DIR_PARAMS(index));
|
||||
object.Write("cosAttn = " LIGHT_COSATT ".xyz;\n", LIGHT_COSATT_PARAMS(index));
|
||||
object.Write("distAttn = {}(" LIGHT_DISTATT ".xyz);\n",
|
||||
(diffusefunc == LIGHTDIF_NONE) ? "" : "normalize", LIGHT_DISTATT_PARAMS(index));
|
||||
(diffusefunc == DiffuseFunc::None) ? "" : "normalize",
|
||||
LIGHT_DISTATT_PARAMS(index));
|
||||
object.Write("attn = max(0.0f, dot(cosAttn, float3(1.0, attn, attn*attn))) / dot(distAttn, "
|
||||
"float3(1.0, attn, attn*attn));\n");
|
||||
break;
|
||||
case LIGHTATTN_SPOT:
|
||||
case AttenuationFunc::Spot:
|
||||
object.Write("ldir = " LIGHT_POS ".xyz - pos.xyz;\n", LIGHT_POS_PARAMS(index));
|
||||
object.Write("dist2 = dot(ldir, ldir);\n"
|
||||
"dist = sqrt(dist2);\n"
|
||||
|
@ -56,14 +59,14 @@ static void GenerateLightShader(ShaderCode& object, const LightingUidData& uid_d
|
|||
|
||||
switch (diffusefunc)
|
||||
{
|
||||
case LIGHTDIF_NONE:
|
||||
case DiffuseFunc::None:
|
||||
object.Write("lacc.{} += int{}(round(attn * float{}(" LIGHT_COL ")));\n", swizzle,
|
||||
swizzle_components, swizzle_components, LIGHT_COL_PARAMS(index, swizzle));
|
||||
break;
|
||||
case LIGHTDIF_SIGN:
|
||||
case LIGHTDIF_CLAMP:
|
||||
case DiffuseFunc::Sign:
|
||||
case DiffuseFunc::Clamp:
|
||||
object.Write("lacc.{} += int{}(round(attn * {}dot(ldir, _norm0)) * float{}(" LIGHT_COL ")));\n",
|
||||
swizzle, swizzle_components, diffusefunc != LIGHTDIF_SIGN ? "max(0.0," : "(",
|
||||
swizzle, swizzle_components, diffusefunc != DiffuseFunc::Sign ? "max(0.0," : "(",
|
||||
swizzle_components, LIGHT_COL_PARAMS(index, swizzle));
|
||||
break;
|
||||
default:
|
||||
|
@ -151,23 +154,23 @@ void GetLightingShaderUid(LightingUidData& uid_data)
|
|||
{
|
||||
for (u32 j = 0; j < NUM_XF_COLOR_CHANNELS; j++)
|
||||
{
|
||||
uid_data.matsource |= xfmem.color[j].matsource << j;
|
||||
uid_data.matsource |= xfmem.alpha[j].matsource << (j + 2);
|
||||
uid_data.matsource |= static_cast<u32>(xfmem.color[j].matsource.Value()) << j;
|
||||
uid_data.matsource |= static_cast<u32>(xfmem.alpha[j].matsource.Value()) << (j + 2);
|
||||
uid_data.enablelighting |= xfmem.color[j].enablelighting << j;
|
||||
uid_data.enablelighting |= xfmem.alpha[j].enablelighting << (j + 2);
|
||||
|
||||
if ((uid_data.enablelighting & (1 << j)) != 0) // Color lights
|
||||
{
|
||||
uid_data.ambsource |= xfmem.color[j].ambsource << j;
|
||||
uid_data.attnfunc |= xfmem.color[j].attnfunc << (2 * j);
|
||||
uid_data.diffusefunc |= xfmem.color[j].diffusefunc << (2 * j);
|
||||
uid_data.ambsource |= static_cast<u32>(xfmem.color[j].ambsource.Value()) << j;
|
||||
uid_data.attnfunc |= static_cast<u32>(xfmem.color[j].attnfunc.Value()) << (2 * j);
|
||||
uid_data.diffusefunc |= static_cast<u32>(xfmem.color[j].diffusefunc.Value()) << (2 * j);
|
||||
uid_data.light_mask |= xfmem.color[j].GetFullLightMask() << (8 * j);
|
||||
}
|
||||
if ((uid_data.enablelighting & (1 << (j + 2))) != 0) // Alpha lights
|
||||
{
|
||||
uid_data.ambsource |= xfmem.alpha[j].ambsource << (j + 2);
|
||||
uid_data.attnfunc |= xfmem.alpha[j].attnfunc << (2 * (j + 2));
|
||||
uid_data.diffusefunc |= xfmem.alpha[j].diffusefunc << (2 * (j + 2));
|
||||
uid_data.ambsource |= static_cast<u32>(xfmem.alpha[j].ambsource.Value()) << (j + 2);
|
||||
uid_data.attnfunc |= static_cast<u32>(xfmem.alpha[j].attnfunc.Value()) << (2 * (j + 2));
|
||||
uid_data.diffusefunc |= static_cast<u32>(xfmem.alpha[j].diffusefunc.Value()) << (2 * (j + 2));
|
||||
uid_data.light_mask |= xfmem.alpha[j].GetFullLightMask() << (8 * (j + 2));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -212,7 +212,8 @@ PixelShaderUid GetPixelShaderUid()
|
|||
for (unsigned int i = 0; i < uid_data->genMode_numtexgens; ++i)
|
||||
{
|
||||
// optional perspective divides
|
||||
uid_data->texMtxInfo_n_projection |= xfmem.texMtxInfo[i].projection << i;
|
||||
uid_data->texMtxInfo_n_projection |= static_cast<u32>(xfmem.texMtxInfo[i].projection.Value())
|
||||
<< i;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -39,26 +39,26 @@ void WriteLightingFunction(ShaderCode& out)
|
|||
" float dist, dist2, attn;\n"
|
||||
"\n"
|
||||
" switch (attnfunc) {{\n");
|
||||
out.Write(" case {}u: // LIGNTATTN_NONE\n", LIGHTATTN_NONE);
|
||||
out.Write(" case {}u: // LIGHTATTN_DIR\n", LIGHTATTN_DIR);
|
||||
out.Write(" case {:s}:\n", AttenuationFunc::None);
|
||||
out.Write(" case {:s}:\n", AttenuationFunc::Dir);
|
||||
out.Write(" ldir = normalize(" I_LIGHTS "[index].pos.xyz - pos.xyz);\n"
|
||||
" attn = 1.0;\n"
|
||||
" if (length(ldir) == 0.0)\n"
|
||||
" ldir = normal;\n"
|
||||
" break;\n\n");
|
||||
out.Write(" case {}u: // LIGHTATTN_SPEC\n", LIGHTATTN_SPEC);
|
||||
out.Write(" case {:s}:\n", AttenuationFunc::Spec);
|
||||
out.Write(" ldir = normalize(" I_LIGHTS "[index].pos.xyz - pos.xyz);\n"
|
||||
" attn = (dot(normal, ldir) >= 0.0) ? max(0.0, dot(normal, " I_LIGHTS
|
||||
"[index].dir.xyz)) : 0.0;\n"
|
||||
" cosAttn = " I_LIGHTS "[index].cosatt.xyz;\n");
|
||||
out.Write(" if (diffusefunc == {}u) // LIGHTDIF_NONE\n", LIGHTDIF_NONE);
|
||||
out.Write(" if (diffusefunc == {:s})\n", DiffuseFunc::None);
|
||||
out.Write(" distAttn = " I_LIGHTS "[index].distatt.xyz;\n"
|
||||
" else\n"
|
||||
" distAttn = normalize(" I_LIGHTS "[index].distatt.xyz);\n"
|
||||
" attn = max(0.0, dot(cosAttn, float3(1.0, attn, attn*attn))) / dot(distAttn, "
|
||||
"float3(1.0, attn, attn*attn));\n"
|
||||
" break;\n\n");
|
||||
out.Write(" case {}u: // LIGHTATTN_SPOT\n", LIGHTATTN_SPOT);
|
||||
out.Write(" case {:s}:\n", AttenuationFunc::Spot);
|
||||
out.Write(" ldir = " I_LIGHTS "[index].pos.xyz - pos.xyz;\n"
|
||||
" dist2 = dot(ldir, ldir);\n"
|
||||
" dist = sqrt(dist2);\n"
|
||||
|
@ -75,12 +75,12 @@ void WriteLightingFunction(ShaderCode& out)
|
|||
" }}\n"
|
||||
"\n"
|
||||
" switch (diffusefunc) {{\n");
|
||||
out.Write(" case {}u: // LIGHTDIF_NONE\n", LIGHTDIF_NONE);
|
||||
out.Write(" case {:s}:\n", DiffuseFunc::None);
|
||||
out.Write(" return int4(round(attn * float4(" I_LIGHTS "[index].color)));\n\n");
|
||||
out.Write(" case {}u: // LIGHTDIF_SIGN\n", LIGHTDIF_SIGN);
|
||||
out.Write(" case {:s}:\n", DiffuseFunc::Sign);
|
||||
out.Write(" return int4(round(attn * dot(ldir, normal) * float4(" I_LIGHTS
|
||||
"[index].color)));\n\n");
|
||||
out.Write(" case {}u: // LIGHTDIF_CLAMP\n", LIGHTDIF_CLAMP);
|
||||
out.Write(" case {:s}:\n", DiffuseFunc::Clamp);
|
||||
out.Write(" return int4(round(attn * max(0.0, dot(ldir, normal)) * float4(" I_LIGHTS
|
||||
"[index].color)));\n\n");
|
||||
out.Write(" default:\n"
|
||||
|
|
|
@ -403,27 +403,27 @@ static void GenVertexShaderTexGens(APIType api_type, u32 num_texgen, ShaderCode&
|
|||
out.Write(" float4 coord = float4(0.0, 0.0, 1.0, 1.0);\n"
|
||||
" uint texMtxInfo = xfmem_texMtxInfo(texgen);\n");
|
||||
out.Write(" switch ({}) {{\n", BitfieldExtract("texMtxInfo", TexMtxInfo().sourcerow));
|
||||
out.Write(" case {}u: // XF_SRCGEOM_INROW\n", XF_SRCGEOM_INROW);
|
||||
out.Write(" case {:s}:\n", SourceRow::Geom);
|
||||
out.Write(" coord.xyz = rawpos.xyz;\n");
|
||||
out.Write(" break;\n\n");
|
||||
out.Write(" case {}u: // XF_SRCNORMAL_INROW\n", XF_SRCNORMAL_INROW);
|
||||
out.Write(" case {:s}:\n", SourceRow::Normal);
|
||||
out.Write(
|
||||
" coord.xyz = ((components & {}u /* VB_HAS_NRM0 */) != 0u) ? rawnorm0.xyz : coord.xyz;",
|
||||
VB_HAS_NRM0);
|
||||
out.Write(" break;\n\n");
|
||||
out.Write(" case {}u: // XF_SRCBINORMAL_T_INROW\n", XF_SRCBINORMAL_T_INROW);
|
||||
out.Write(" case {:s}:\n", SourceRow::BinormalT);
|
||||
out.Write(
|
||||
" coord.xyz = ((components & {}u /* VB_HAS_NRM1 */) != 0u) ? rawnorm1.xyz : coord.xyz;",
|
||||
VB_HAS_NRM1);
|
||||
out.Write(" break;\n\n");
|
||||
out.Write(" case {}u: // XF_SRCBINORMAL_B_INROW\n", XF_SRCBINORMAL_B_INROW);
|
||||
out.Write(" case {:s}:\n", SourceRow::BinormalB);
|
||||
out.Write(
|
||||
" coord.xyz = ((components & {}u /* VB_HAS_NRM2 */) != 0u) ? rawnorm2.xyz : coord.xyz;",
|
||||
VB_HAS_NRM2);
|
||||
out.Write(" break;\n\n");
|
||||
for (u32 i = 0; i < 8; i++)
|
||||
{
|
||||
out.Write(" case {}u: // XF_SRCTEX{}_INROW\n", XF_SRCTEX0_INROW + i, i);
|
||||
out.Write(" case {:s}:\n", static_cast<SourceRow>(static_cast<u32>(SourceRow::Tex0) + i));
|
||||
out.Write(
|
||||
" coord = ((components & {}u /* VB_HAS_UV{} */) != 0u) ? float4(rawtex{}.x, rawtex{}.y, "
|
||||
"1.0, 1.0) : coord;\n",
|
||||
|
@ -434,8 +434,8 @@ static void GenVertexShaderTexGens(APIType api_type, u32 num_texgen, ShaderCode&
|
|||
"\n");
|
||||
|
||||
out.Write(" // Input form of AB11 sets z element to 1.0\n");
|
||||
out.Write(" if ({} == {}u) // inputform == XF_TEXINPUT_AB11\n",
|
||||
BitfieldExtract("texMtxInfo", TexMtxInfo().inputform), XF_TEXINPUT_AB11);
|
||||
out.Write(" if ({} == {:s}) // inputform == AB11\n",
|
||||
BitfieldExtract("texMtxInfo", TexMtxInfo().inputform), TexInputForm::AB11);
|
||||
out.Write(" coord.z = 1.0f;\n"
|
||||
"\n");
|
||||
|
||||
|
@ -444,7 +444,7 @@ static void GenVertexShaderTexGens(APIType api_type, u32 num_texgen, ShaderCode&
|
|||
out.Write(" float3 output_tex;\n"
|
||||
" switch (texgentype)\n"
|
||||
" {{\n");
|
||||
out.Write(" case {}u: // XF_TEXGEN_EMBOSS_MAP\n", XF_TEXGEN_EMBOSS_MAP);
|
||||
out.Write(" case {:s}:\n", TexGenType::EmbossMap);
|
||||
out.Write(" {{\n");
|
||||
out.Write(" uint light = {};\n",
|
||||
BitfieldExtract("texMtxInfo", TexMtxInfo().embosslightshift));
|
||||
|
@ -462,13 +462,14 @@ static void GenVertexShaderTexGens(APIType api_type, u32 num_texgen, ShaderCode&
|
|||
" }}\n"
|
||||
" }}\n"
|
||||
" break;\n\n");
|
||||
out.Write(" case {}u: // XF_TEXGEN_COLOR_STRGBC0\n", XF_TEXGEN_COLOR_STRGBC0);
|
||||
out.Write(" case {:s}:\n", TexGenType::Color0);
|
||||
out.Write(" output_tex.xyz = float3(o.colors_0.x, o.colors_0.y, 1.0);\n"
|
||||
" break;\n\n");
|
||||
out.Write(" case {}u: // XF_TEXGEN_COLOR_STRGBC1\n", XF_TEXGEN_COLOR_STRGBC1);
|
||||
out.Write(" case {:s}:\n", TexGenType::Color1);
|
||||
out.Write(" output_tex.xyz = float3(o.colors_1.x, o.colors_1.y, 1.0);\n"
|
||||
" break;\n\n");
|
||||
out.Write(" default: // Also XF_TEXGEN_REGULAR\n"
|
||||
out.Write(" case {:s}:\n", TexGenType::Regular);
|
||||
out.Write(" default:\n"
|
||||
" {{\n");
|
||||
out.Write(" if ((components & ({}u /* VB_HAS_TEXMTXIDX0 */ << texgen)) != 0u) {{\n",
|
||||
VB_HAS_TEXMTXIDX0);
|
||||
|
@ -480,8 +481,8 @@ static void GenVertexShaderTexGens(APIType api_type, u32 num_texgen, ShaderCode&
|
|||
out.Write(" case {}u: tmp = int(rawtex{}.z); break;\n", i, i);
|
||||
out.Write(" }}\n"
|
||||
"\n");
|
||||
out.Write(" if ({} == {}u) {{\n", BitfieldExtract("texMtxInfo", TexMtxInfo().projection),
|
||||
XF_TEXPROJ_STQ);
|
||||
out.Write(" if ({} == {:s}) {{\n", BitfieldExtract("texMtxInfo", TexMtxInfo().projection),
|
||||
TexSize::STQ);
|
||||
out.Write(" output_tex.xyz = float3(dot(coord, " I_TRANSFORMMATRICES "[tmp]),\n"
|
||||
" dot(coord, " I_TRANSFORMMATRICES "[tmp + 1]),\n"
|
||||
" dot(coord, " I_TRANSFORMMATRICES "[tmp + 2]));\n"
|
||||
|
@ -491,8 +492,8 @@ static void GenVertexShaderTexGens(APIType api_type, u32 num_texgen, ShaderCode&
|
|||
" 1.0);\n"
|
||||
" }}\n"
|
||||
" }} else {{\n");
|
||||
out.Write(" if ({} == {}u) {{\n", BitfieldExtract("texMtxInfo", TexMtxInfo().projection),
|
||||
XF_TEXPROJ_STQ);
|
||||
out.Write(" if ({} == {:s}) {{\n", BitfieldExtract("texMtxInfo", TexMtxInfo().projection),
|
||||
TexSize::STQ);
|
||||
out.Write(" output_tex.xyz = float3(dot(coord, " I_TEXMATRICES "[3u * texgen]),\n"
|
||||
" dot(coord, " I_TEXMATRICES "[3u * texgen + 1u]),\n"
|
||||
" dot(coord, " I_TEXMATRICES "[3u * texgen + 2u]));\n"
|
||||
|
@ -526,8 +527,7 @@ static void GenVertexShaderTexGens(APIType api_type, u32 num_texgen, ShaderCode&
|
|||
// When q is 0, the GameCube appears to have a special case
|
||||
// This can be seen in devkitPro's neheGX Lesson08 example for Wii
|
||||
// Makes differences in Rogue Squadron 3 (Hoth sky) and The Last Story (shadow culling)
|
||||
out.Write(" if (texgentype == {}u && output_tex.z == 0.0) // XF_TEXGEN_REGULAR\n",
|
||||
XF_TEXGEN_REGULAR);
|
||||
out.Write(" if (texgentype == {:s} && output_tex.z == 0.0)\n", TexGenType::Regular);
|
||||
out.Write(
|
||||
" output_tex.xy = clamp(output_tex.xy / 2.0f, float2(-1.0f,-1.0f), float2(1.0f,1.0f));\n"
|
||||
"\n");
|
||||
|
|
|
@ -408,10 +408,10 @@ void VertexManagerBase::Flush()
|
|||
for (u32 i = 0; i < xfmem.numTexGen.numTexGens; ++i)
|
||||
{
|
||||
TexMtxInfo tinfo = xfmem.texMtxInfo[i];
|
||||
if (tinfo.texgentype != XF_TEXGEN_EMBOSS_MAP)
|
||||
if (tinfo.texgentype != TexGenType::EmbossMap)
|
||||
tinfo.hex &= 0x7ff;
|
||||
if (tinfo.texgentype != XF_TEXGEN_REGULAR)
|
||||
tinfo.projection = 0;
|
||||
if (tinfo.texgentype != TexGenType::Regular)
|
||||
tinfo.projection = TexSize::ST;
|
||||
|
||||
PRIM_LOG("txgen{}: proj={}, input={}, gentype={}, srcrow={}, embsrc={}, emblght={}, "
|
||||
"postmtx={}, postnorm={}",
|
||||
|
@ -430,7 +430,7 @@ void VertexManagerBase::Flush()
|
|||
// Track some stats used elsewhere by the anamorphic widescreen heuristic.
|
||||
if (!SConfig::GetInstance().bWii)
|
||||
{
|
||||
const bool is_perspective = xfmem.projection.type == GX_PERSPECTIVE;
|
||||
const bool is_perspective = xfmem.projection.type == ProjectionType::Perspective;
|
||||
|
||||
auto& counts =
|
||||
is_perspective ? m_flush_statistics.perspective : m_flush_statistics.orthographic;
|
||||
|
|
|
@ -39,7 +39,7 @@ VertexShaderUid GetVertexShaderUid()
|
|||
// first transformation
|
||||
switch (texinfo.texgentype)
|
||||
{
|
||||
case XF_TEXGEN_EMBOSS_MAP: // calculate tex coords into bump map
|
||||
case TexGenType::EmbossMap: // calculate tex coords into bump map
|
||||
if ((uid_data->components & (VB_HAS_NRM1 | VB_HAS_NRM2)) != 0)
|
||||
{
|
||||
// transform the light dir into tangent space
|
||||
|
@ -51,18 +51,19 @@ VertexShaderUid GetVertexShaderUid()
|
|||
texinfo.embosssourceshift = xfmem.texMtxInfo[i].embosssourceshift;
|
||||
}
|
||||
break;
|
||||
case XF_TEXGEN_COLOR_STRGBC0:
|
||||
case XF_TEXGEN_COLOR_STRGBC1:
|
||||
case TexGenType::Color0:
|
||||
case TexGenType::Color1:
|
||||
break;
|
||||
case XF_TEXGEN_REGULAR:
|
||||
case TexGenType::Regular:
|
||||
default:
|
||||
uid_data->texMtxInfo_n_projection |= xfmem.texMtxInfo[i].projection << i;
|
||||
uid_data->texMtxInfo_n_projection |= static_cast<u32>(xfmem.texMtxInfo[i].projection.Value())
|
||||
<< i;
|
||||
break;
|
||||
}
|
||||
|
||||
uid_data->dualTexTrans_enabled = xfmem.dualTexTrans.enabled;
|
||||
// CHECKME: does this only work for regular tex gen types?
|
||||
if (uid_data->dualTexTrans_enabled && texinfo.texgentype == XF_TEXGEN_REGULAR)
|
||||
if (uid_data->dualTexTrans_enabled && texinfo.texgentype == TexGenType::Regular)
|
||||
{
|
||||
auto& postInfo = uid_data->postMtxInfo[i];
|
||||
postInfo.index = xfmem.postMtxInfo[i].index;
|
||||
|
@ -297,49 +298,48 @@ ShaderCode GenerateVertexShaderCode(APIType api_type, const ShaderHostConfig& ho
|
|||
out.Write("coord = float4(0.0, 0.0, 1.0, 1.0);\n");
|
||||
switch (texinfo.sourcerow)
|
||||
{
|
||||
case XF_SRCGEOM_INROW:
|
||||
case SourceRow::Geom:
|
||||
out.Write("coord.xyz = rawpos.xyz;\n");
|
||||
break;
|
||||
case XF_SRCNORMAL_INROW:
|
||||
case SourceRow::Normal:
|
||||
if ((uid_data->components & VB_HAS_NRM0) != 0)
|
||||
{
|
||||
out.Write("coord.xyz = rawnorm0.xyz;\n");
|
||||
}
|
||||
break;
|
||||
case XF_SRCCOLORS_INROW:
|
||||
ASSERT(texinfo.texgentype == XF_TEXGEN_COLOR_STRGBC0 ||
|
||||
texinfo.texgentype == XF_TEXGEN_COLOR_STRGBC1);
|
||||
case SourceRow::Colors:
|
||||
ASSERT(texinfo.texgentype == TexGenType::Color0 || texinfo.texgentype == TexGenType::Color1);
|
||||
break;
|
||||
case XF_SRCBINORMAL_T_INROW:
|
||||
case SourceRow::BinormalT:
|
||||
if ((uid_data->components & VB_HAS_NRM1) != 0)
|
||||
{
|
||||
out.Write("coord.xyz = rawnorm1.xyz;\n");
|
||||
}
|
||||
break;
|
||||
case XF_SRCBINORMAL_B_INROW:
|
||||
case SourceRow::BinormalB:
|
||||
if ((uid_data->components & VB_HAS_NRM2) != 0)
|
||||
{
|
||||
out.Write("coord.xyz = rawnorm2.xyz;\n");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ASSERT(texinfo.sourcerow <= XF_SRCTEX7_INROW);
|
||||
if ((uid_data->components & (VB_HAS_UV0 << (texinfo.sourcerow - XF_SRCTEX0_INROW))) != 0)
|
||||
ASSERT(texinfo.sourcerow >= SourceRow::Tex0 && texinfo.sourcerow <= SourceRow::Tex7);
|
||||
u32 texnum = static_cast<u32>(texinfo.sourcerow) - static_cast<u32>(SourceRow::Tex0);
|
||||
if ((uid_data->components & (VB_HAS_UV0 << (texnum))) != 0)
|
||||
{
|
||||
out.Write("coord = float4(rawtex{}.x, rawtex{}.y, 1.0, 1.0);\n",
|
||||
texinfo.sourcerow - XF_SRCTEX0_INROW, texinfo.sourcerow - XF_SRCTEX0_INROW);
|
||||
out.Write("coord = float4(rawtex{}.x, rawtex{}.y, 1.0, 1.0);\n", texnum, texnum);
|
||||
}
|
||||
break;
|
||||
}
|
||||
// Input form of AB11 sets z element to 1.0
|
||||
|
||||
if (texinfo.inputform == XF_TEXINPUT_AB11)
|
||||
if (texinfo.inputform == TexInputForm::AB11)
|
||||
out.Write("coord.z = 1.0;\n");
|
||||
|
||||
// first transformation
|
||||
switch (texinfo.texgentype)
|
||||
{
|
||||
case XF_TEXGEN_EMBOSS_MAP: // calculate tex coords into bump map
|
||||
case TexGenType::EmbossMap: // calculate tex coords into bump map
|
||||
|
||||
if ((uid_data->components & (VB_HAS_NRM1 | VB_HAS_NRM2)) != 0)
|
||||
{
|
||||
|
@ -359,18 +359,18 @@ ShaderCode GenerateVertexShaderCode(APIType api_type, const ShaderHostConfig& ho
|
|||
}
|
||||
|
||||
break;
|
||||
case XF_TEXGEN_COLOR_STRGBC0:
|
||||
case TexGenType::Color0:
|
||||
out.Write("o.tex{}.xyz = float3(o.colors_0.x, o.colors_0.y, 1);\n", i);
|
||||
break;
|
||||
case XF_TEXGEN_COLOR_STRGBC1:
|
||||
case TexGenType::Color1:
|
||||
out.Write("o.tex{}.xyz = float3(o.colors_1.x, o.colors_1.y, 1);\n", i);
|
||||
break;
|
||||
case XF_TEXGEN_REGULAR:
|
||||
case TexGenType::Regular:
|
||||
default:
|
||||
if ((uid_data->components & (VB_HAS_TEXMTXIDX0 << i)) != 0)
|
||||
{
|
||||
out.Write("int tmp = int(rawtex{}.z);\n", i);
|
||||
if (((uid_data->texMtxInfo_n_projection >> i) & 1) == XF_TEXPROJ_STQ)
|
||||
if (static_cast<TexSize>((uid_data->texMtxInfo_n_projection >> i) & 1) == TexSize::STQ)
|
||||
{
|
||||
out.Write("o.tex{}.xyz = float3(dot(coord, " I_TRANSFORMMATRICES
|
||||
"[tmp]), dot(coord, " I_TRANSFORMMATRICES
|
||||
|
@ -386,7 +386,7 @@ ShaderCode GenerateVertexShaderCode(APIType api_type, const ShaderHostConfig& ho
|
|||
}
|
||||
else
|
||||
{
|
||||
if (((uid_data->texMtxInfo_n_projection >> i) & 1) == XF_TEXPROJ_STQ)
|
||||
if (static_cast<TexSize>((uid_data->texMtxInfo_n_projection >> i) & 1) == TexSize::STQ)
|
||||
{
|
||||
out.Write("o.tex{}.xyz = float3(dot(coord, " I_TEXMATRICES
|
||||
"[{}]), dot(coord, " I_TEXMATRICES "[{}]), dot(coord, " I_TEXMATRICES
|
||||
|
@ -404,7 +404,7 @@ ShaderCode GenerateVertexShaderCode(APIType api_type, const ShaderHostConfig& ho
|
|||
}
|
||||
|
||||
// CHECKME: does this only work for regular tex gen types?
|
||||
if (uid_data->dualTexTrans_enabled && texinfo.texgentype == XF_TEXGEN_REGULAR)
|
||||
if (uid_data->dualTexTrans_enabled && texinfo.texgentype == TexGenType::Regular)
|
||||
{
|
||||
auto& postInfo = uid_data->postMtxInfo[i];
|
||||
|
||||
|
@ -427,7 +427,7 @@ ShaderCode GenerateVertexShaderCode(APIType api_type, const ShaderHostConfig& ho
|
|||
// This can be seen in devkitPro's neheGX Lesson08 example for Wii
|
||||
// Makes differences in Rogue Squadron 3 (Hoth sky) and The Last Story (shadow culling)
|
||||
// TODO: check if this only affects XF_TEXGEN_REGULAR
|
||||
if (texinfo.texgentype == XF_TEXGEN_REGULAR)
|
||||
if (texinfo.texgentype == TexGenType::Regular)
|
||||
{
|
||||
out.Write(
|
||||
"if(o.tex{0}.z == 0.0f)\n"
|
||||
|
|
|
@ -9,6 +9,9 @@
|
|||
#include "VideoCommon/ShaderGenCommon.h"
|
||||
|
||||
enum class APIType;
|
||||
enum class TexInputForm : u32;
|
||||
enum class TexGenType : u32;
|
||||
enum class SourceRow : u32;
|
||||
|
||||
// TODO should be reordered
|
||||
enum : int
|
||||
|
@ -47,9 +50,9 @@ struct vertex_shader_uid_data
|
|||
|
||||
struct
|
||||
{
|
||||
u32 inputform : 2;
|
||||
u32 texgentype : 3;
|
||||
u32 sourcerow : 5;
|
||||
TexInputForm inputform : 2;
|
||||
TexGenType texgentype : 3;
|
||||
SourceRow sourcerow : 5;
|
||||
u32 embosssourceshift : 3;
|
||||
u32 embosslightshift : 3;
|
||||
} texMtxInfo[8];
|
||||
|
|
|
@ -353,7 +353,7 @@ void VertexShaderManager::SetConstants()
|
|||
|
||||
switch (xfmem.projection.type)
|
||||
{
|
||||
case GX_PERSPECTIVE:
|
||||
case ProjectionType::Perspective:
|
||||
{
|
||||
const Common::Vec2 fov =
|
||||
g_freelook_camera.IsActive() ? g_freelook_camera.GetFieldOfView() : Common::Vec2{1, 1};
|
||||
|
@ -382,7 +382,7 @@ void VertexShaderManager::SetConstants()
|
|||
}
|
||||
break;
|
||||
|
||||
case GX_ORTHOGRAPHIC:
|
||||
case ProjectionType::Orthographic:
|
||||
{
|
||||
g_fProjectionMatrix[0] = rawProjection[0];
|
||||
g_fProjectionMatrix[1] = 0.0f;
|
||||
|
@ -419,7 +419,7 @@ void VertexShaderManager::SetConstants()
|
|||
|
||||
auto corrected_matrix = s_viewportCorrection * Common::Matrix44::FromArray(g_fProjectionMatrix);
|
||||
|
||||
if (g_freelook_camera.IsActive() && xfmem.projection.type == GX_PERSPECTIVE)
|
||||
if (g_freelook_camera.IsActive() && xfmem.projection.type == ProjectionType::Perspective)
|
||||
corrected_matrix *= g_freelook_camera.GetView();
|
||||
|
||||
memcpy(constants.projection.data(), corrected_matrix.data.data(), 4 * sizeof(float4));
|
||||
|
|
|
@ -4,10 +4,14 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
// X.h defines None to be 0, which causes problems with some of the enums
|
||||
#undef None
|
||||
|
||||
#include <array>
|
||||
|
||||
#include "Common/BitField.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/EnumFormatter.h"
|
||||
#include "VideoCommon/CPMemory.h"
|
||||
|
||||
class DataReader;
|
||||
|
@ -17,75 +21,164 @@ constexpr size_t NUM_XF_COLOR_CHANNELS = 2;
|
|||
// Lighting
|
||||
|
||||
// Projection
|
||||
enum : u32
|
||||
enum class TexSize : u32
|
||||
{
|
||||
XF_TEXPROJ_ST = 0,
|
||||
XF_TEXPROJ_STQ = 1
|
||||
ST = 0,
|
||||
STQ = 1
|
||||
};
|
||||
template <>
|
||||
struct fmt::formatter<TexSize> : EnumFormatter<TexSize::STQ>
|
||||
{
|
||||
formatter() : EnumFormatter({"ST (2x4 matrix)", "STQ (3x4 matrix)"}) {}
|
||||
};
|
||||
|
||||
// Input form
|
||||
enum : u32
|
||||
enum class TexInputForm : u32
|
||||
{
|
||||
XF_TEXINPUT_AB11 = 0,
|
||||
XF_TEXINPUT_ABC1 = 1
|
||||
AB11 = 0,
|
||||
ABC1 = 1
|
||||
};
|
||||
template <>
|
||||
struct fmt::formatter<TexInputForm> : EnumFormatter<TexInputForm::ABC1>
|
||||
{
|
||||
formatter() : EnumFormatter({"AB11", "ABC1"}) {}
|
||||
};
|
||||
|
||||
enum class NormalCount : u32
|
||||
{
|
||||
None = 0,
|
||||
Normals = 1,
|
||||
NormalsBinormals = 2
|
||||
};
|
||||
template <>
|
||||
struct fmt::formatter<NormalCount> : EnumFormatter<NormalCount::NormalsBinormals>
|
||||
{
|
||||
formatter() : EnumFormatter({"None", "Normals only", "Normals and binormals"}) {}
|
||||
};
|
||||
|
||||
// Texture generation type
|
||||
enum : u32
|
||||
enum class TexGenType : u32
|
||||
{
|
||||
XF_TEXGEN_REGULAR = 0,
|
||||
XF_TEXGEN_EMBOSS_MAP = 1, // Used when bump mapping
|
||||
XF_TEXGEN_COLOR_STRGBC0 = 2,
|
||||
XF_TEXGEN_COLOR_STRGBC1 = 3
|
||||
Regular = 0,
|
||||
EmbossMap = 1, // Used when bump mapping
|
||||
Color0 = 2,
|
||||
Color1 = 3
|
||||
};
|
||||
template <>
|
||||
struct fmt::formatter<TexGenType> : EnumFormatter<TexGenType::Color1>
|
||||
{
|
||||
static constexpr array_type names = {
|
||||
"Regular",
|
||||
"Emboss map (used when bump mapping)",
|
||||
"Color channel 0",
|
||||
"Color channel 1",
|
||||
};
|
||||
formatter() : EnumFormatter(names) {}
|
||||
};
|
||||
|
||||
// Source row
|
||||
enum : u32
|
||||
enum class SourceRow : u32
|
||||
{
|
||||
XF_SRCGEOM_INROW = 0, // Input is abc
|
||||
XF_SRCNORMAL_INROW = 1, // Input is abc
|
||||
XF_SRCCOLORS_INROW = 2,
|
||||
XF_SRCBINORMAL_T_INROW = 3, // Input is abc
|
||||
XF_SRCBINORMAL_B_INROW = 4, // Input is abc
|
||||
XF_SRCTEX0_INROW = 5,
|
||||
XF_SRCTEX1_INROW = 6,
|
||||
XF_SRCTEX2_INROW = 7,
|
||||
XF_SRCTEX3_INROW = 8,
|
||||
XF_SRCTEX4_INROW = 9,
|
||||
XF_SRCTEX5_INROW = 10,
|
||||
XF_SRCTEX6_INROW = 11,
|
||||
XF_SRCTEX7_INROW = 12
|
||||
Geom = 0, // Input is abc
|
||||
Normal = 1, // Input is abc
|
||||
Colors = 2,
|
||||
BinormalT = 3, // Input is abc
|
||||
BinormalB = 4, // Input is abc
|
||||
Tex0 = 5,
|
||||
Tex1 = 6,
|
||||
Tex2 = 7,
|
||||
Tex3 = 8,
|
||||
Tex4 = 9,
|
||||
Tex5 = 10,
|
||||
Tex6 = 11,
|
||||
Tex7 = 12
|
||||
};
|
||||
template <>
|
||||
struct fmt::formatter<SourceRow> : EnumFormatter<SourceRow::Tex7>
|
||||
{
|
||||
static constexpr array_type names = {
|
||||
"Geometry (input is ABC1)",
|
||||
"Normal (input is ABC1)",
|
||||
"Colors",
|
||||
"Binormal T (input is ABC1)",
|
||||
"Binormal B (input is ABC1)",
|
||||
"Tex 0",
|
||||
"Tex 1",
|
||||
"Tex 2",
|
||||
"Tex 3",
|
||||
"Tex 4",
|
||||
"Tex 5",
|
||||
"Tex 6",
|
||||
"Tex 7",
|
||||
};
|
||||
formatter() : EnumFormatter(names) {}
|
||||
};
|
||||
|
||||
// Control source
|
||||
enum : u32
|
||||
enum class MatSource : u32
|
||||
{
|
||||
GX_SRC_REG = 0,
|
||||
GX_SRC_VTX = 1
|
||||
MatColorRegister = 0,
|
||||
Vertex = 1,
|
||||
};
|
||||
template <>
|
||||
struct fmt::formatter<MatSource> : EnumFormatter<MatSource::Vertex>
|
||||
{
|
||||
formatter() : EnumFormatter({"Material color register", "Vertex color"}) {}
|
||||
};
|
||||
|
||||
enum class AmbSource : u32
|
||||
{
|
||||
AmbColorRegister = 0,
|
||||
Vertex = 1,
|
||||
};
|
||||
template <>
|
||||
struct fmt::formatter<AmbSource> : EnumFormatter<AmbSource::Vertex>
|
||||
{
|
||||
formatter() : EnumFormatter({"Ambient color register", "Vertex color"}) {}
|
||||
};
|
||||
|
||||
// Light diffuse attenuation function
|
||||
enum : u32
|
||||
enum class DiffuseFunc : u32
|
||||
{
|
||||
LIGHTDIF_NONE = 0,
|
||||
LIGHTDIF_SIGN = 1,
|
||||
LIGHTDIF_CLAMP = 2
|
||||
None = 0,
|
||||
Sign = 1,
|
||||
Clamp = 2
|
||||
};
|
||||
template <>
|
||||
struct fmt::formatter<DiffuseFunc> : EnumFormatter<DiffuseFunc::Clamp>
|
||||
{
|
||||
formatter() : EnumFormatter({"None", "Sign", "Clamp"}) {}
|
||||
};
|
||||
|
||||
// Light attenuation function
|
||||
enum : u32
|
||||
enum class AttenuationFunc : u32
|
||||
{
|
||||
LIGHTATTN_NONE = 0, // No attenuation
|
||||
LIGHTATTN_SPEC = 1, // Point light attenuation
|
||||
LIGHTATTN_DIR = 2, // Directional light attenuation
|
||||
LIGHTATTN_SPOT = 3 // Spot light attenuation
|
||||
None = 0, // No attenuation
|
||||
Spec = 1, // Point light attenuation
|
||||
Dir = 2, // Directional light attenuation
|
||||
Spot = 3 // Spot light attenuation
|
||||
};
|
||||
template <>
|
||||
struct fmt::formatter<AttenuationFunc> : EnumFormatter<AttenuationFunc::Spot>
|
||||
{
|
||||
static constexpr array_type names = {
|
||||
"No attenuation",
|
||||
"Point light attenuation",
|
||||
"Directional light attenuation",
|
||||
"Spot light attenuation",
|
||||
};
|
||||
formatter() : EnumFormatter(names) {}
|
||||
};
|
||||
|
||||
// Projection type
|
||||
enum : u32
|
||||
enum class ProjectionType : u32
|
||||
{
|
||||
GX_PERSPECTIVE = 0,
|
||||
GX_ORTHOGRAPHIC = 1
|
||||
Perspective = 0,
|
||||
Orthographic = 1
|
||||
};
|
||||
template <>
|
||||
struct fmt::formatter<ProjectionType> : EnumFormatter<ProjectionType::Orthographic>
|
||||
{
|
||||
formatter() : EnumFormatter({"Perspective", "Orthographic"}) {}
|
||||
};
|
||||
|
||||
// Registers and register ranges
|
||||
|
@ -137,12 +230,12 @@ enum
|
|||
|
||||
union LitChannel
|
||||
{
|
||||
BitField<0, 1, u32> matsource;
|
||||
BitField<1, 1, u32> enablelighting;
|
||||
BitField<0, 1, MatSource> matsource;
|
||||
BitField<1, 1, bool, u32> enablelighting;
|
||||
BitField<2, 4, u32> lightMask0_3;
|
||||
BitField<6, 1, u32> ambsource;
|
||||
BitField<7, 2, u32> diffusefunc; // LIGHTDIF_X
|
||||
BitField<9, 2, u32> attnfunc; // LIGHTATTN_X
|
||||
BitField<6, 1, AmbSource> ambsource;
|
||||
BitField<7, 2, DiffuseFunc> diffusefunc;
|
||||
BitField<9, 2, AttenuationFunc> attnfunc;
|
||||
BitField<11, 4, u32> lightMask4_7;
|
||||
u32 hex;
|
||||
|
||||
|
@ -152,26 +245,30 @@ union LitChannel
|
|||
}
|
||||
};
|
||||
|
||||
union ClipDisable
|
||||
{
|
||||
BitField<0, 1, bool, u32> disable_clipping_detection;
|
||||
BitField<1, 1, bool, u32> disable_trivial_rejection;
|
||||
BitField<2, 1, bool, u32> disable_cpoly_clipping_acceleration;
|
||||
u32 hex;
|
||||
};
|
||||
|
||||
union INVTXSPEC
|
||||
{
|
||||
struct
|
||||
{
|
||||
u32 numcolors : 2;
|
||||
u32 numnormals : 2; // 0 - nothing, 1 - just normal, 2 - normals and binormals
|
||||
u32 numtextures : 4;
|
||||
u32 unused : 24;
|
||||
};
|
||||
BitField<0, 2, u32> numcolors;
|
||||
BitField<2, 2, NormalCount> numnormals;
|
||||
BitField<4, 4, u32> numtextures;
|
||||
u32 hex;
|
||||
};
|
||||
|
||||
union TexMtxInfo
|
||||
{
|
||||
BitField<0, 1, u32> unknown; //
|
||||
BitField<1, 1, u32> projection; // XF_TEXPROJ_X
|
||||
BitField<2, 1, u32> inputform; // XF_TEXINPUT_X
|
||||
BitField<3, 1, u32> unknown2; //
|
||||
BitField<4, 3, u32> texgentype; // XF_TEXGEN_X
|
||||
BitField<7, 5, u32> sourcerow; // XF_SRCGEOM_X
|
||||
BitField<0, 1, u32> unknown;
|
||||
BitField<1, 1, TexSize> projection;
|
||||
BitField<2, 1, TexInputForm> inputform;
|
||||
BitField<3, 1, u32> unknown2;
|
||||
BitField<4, 3, TexGenType> texgentype;
|
||||
BitField<7, 5, SourceRow> sourcerow;
|
||||
BitField<12, 3, u32> embosssourceshift; // what generated texcoord to use
|
||||
BitField<15, 3, u32> embosslightshift; // light index that is used
|
||||
u32 hex;
|
||||
|
@ -179,36 +276,27 @@ union TexMtxInfo
|
|||
|
||||
union PostMtxInfo
|
||||
{
|
||||
BitField<0, 6, u32> index; // base row of dual transform matrix
|
||||
BitField<6, 2, u32> unused; //
|
||||
BitField<8, 1, u32> normalize; // normalize before send operation
|
||||
BitField<0, 6, u32> index; // base row of dual transform matrix
|
||||
BitField<6, 2, u32> unused; //
|
||||
BitField<8, 1, bool, u32> normalize; // normalize before send operation
|
||||
u32 hex;
|
||||
};
|
||||
|
||||
union NumColorChannel
|
||||
{
|
||||
struct
|
||||
{
|
||||
u32 numColorChans : 2;
|
||||
};
|
||||
BitField<0, 2, u32> numColorChans;
|
||||
u32 hex;
|
||||
};
|
||||
|
||||
union NumTexGen
|
||||
{
|
||||
struct
|
||||
{
|
||||
u32 numTexGens : 4;
|
||||
};
|
||||
BitField<0, 4, u32> numTexGens;
|
||||
u32 hex;
|
||||
};
|
||||
|
||||
union DualTexInfo
|
||||
{
|
||||
struct
|
||||
{
|
||||
u32 enabled : 1;
|
||||
};
|
||||
BitField<0, 1, bool, u32> enabled;
|
||||
u32 hex;
|
||||
};
|
||||
|
||||
|
@ -250,7 +338,7 @@ struct Projection
|
|||
using Raw = std::array<float, 6>;
|
||||
|
||||
Raw rawProjection;
|
||||
u32 type; // only GX_PERSPECTIVE or GX_ORTHOGRAPHIC are allowed
|
||||
ProjectionType type;
|
||||
};
|
||||
|
||||
struct XFMemory
|
||||
|
@ -267,7 +355,7 @@ struct XFMemory
|
|||
u32 state0; // 0x1002
|
||||
u32 state1; // 0x1003
|
||||
u32 xfClock; // 0x1004
|
||||
u32 clipDisable; // 0x1005
|
||||
ClipDisable clipDisable; // 0x1005
|
||||
u32 perf0; // 0x1006
|
||||
u32 perf1; // 0x1007
|
||||
INVTXSPEC hostinfo; // 0x1008 number of textures,colors,normals from vertex input
|
||||
|
|
|
@ -93,7 +93,7 @@ static void XFRegWritten(int transferSize, u32 baseAddress, DataReader src)
|
|||
break;
|
||||
|
||||
case XFMEM_DUALTEX:
|
||||
if (xfmem.dualTexTrans.enabled != (newValue & 1))
|
||||
if (xfmem.dualTexTrans.enabled != bool(newValue & 1))
|
||||
g_vertex_manager->Flush();
|
||||
VertexShaderManager::SetTexMatrixInfoChanged(-1);
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue