Use formatters in GetBPRegInfo; add missing commands

BPMEM_TEV_COLOR_ENV + 6 (0xC6) was missing due to a typo.  BPMEM_BP_MASK (0xFE) does not lend itself well to documentation with the current FIFO analyzer implementation (since it requires remembering the values in BP memory) but still shouldn't be treated as unknown.  BPMEM_TX_SETMODE0_4 and BPMEM_TX_SETMODE1_4 (0xA4-0xAB) were missing entirely.
This commit is contained in:
Pokechu22 2021-02-07 15:25:11 -08:00
parent 70f9fc4e75
commit df81210e96
3 changed files with 821 additions and 378 deletions

View File

@ -287,11 +287,17 @@ void FIFOAnalyzer::UpdateDetails()
case OpcodeDecoder::GX_LOAD_BP_REG: case OpcodeDecoder::GX_LOAD_BP_REG:
{ {
u32 cmd2 = Common::swap32(objectdata); const u8 cmd2 = *objectdata++;
objectdata += 4; const u32 cmddata = Common::swap24(objectdata);
new_label = QStringLiteral("BP %1 %2") objectdata += 3;
.arg(cmd2 >> 24, 2, 16, QLatin1Char('0'))
.arg(cmd2 & 0xFFFFFF, 6, 16, QLatin1Char('0')); const auto [name, desc] = GetBPRegInfo(cmd2, cmddata);
ASSERT(!name.empty());
new_label = QStringLiteral("BP %1 %2 %3")
.arg(cmd2, 2, 16, QLatin1Char('0'))
.arg(cmddata, 6, 16, QLatin1Char('0'))
.arg(QString::fromStdString(name));
} }
break; break;
@ -476,14 +482,14 @@ void FIFOAnalyzer::UpdateDescription()
QString text; QString text;
if (*cmddata == OpcodeDecoder::GX_LOAD_BP_REG) if (*cmddata == OpcodeDecoder::GX_LOAD_BP_REG)
{ {
std::string name; const u8 cmd = *(cmddata + 1);
std::string desc; const u32 value = Common::swap24(cmddata + 2);
GetBPRegInfo(cmddata + 1, &name, &desc);
const auto [name, desc] = GetBPRegInfo(cmd, value);
ASSERT(!name.empty());
text = tr("BP register "); text = tr("BP register ");
text += name.empty() ? text += QString::fromStdString(name);
QStringLiteral("UNKNOWN_%1").arg(*(cmddata + 1), 2, 16, QLatin1Char('0')) :
QString::fromStdString(name);
text += QLatin1Char{'\n'}; text += QLatin1Char{'\n'};
if (desc.empty()) if (desc.empty())

View File

@ -6,8 +6,10 @@
#include <array> #include <array>
#include <string> #include <string>
#include <utility>
#include "Common/BitField.h" #include "Common/BitField.h"
#include "Common/BitUtils.h"
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
#include "Common/EnumFormatter.h" #include "Common/EnumFormatter.h"
#include "Common/Inline.h" #include "Common/Inline.h"
@ -411,6 +413,50 @@ struct TevStageCombiner
ColorCombiner colorC; ColorCombiner colorC;
AlphaCombiner alphaC; AlphaCombiner alphaC;
}; };
template <>
struct fmt::formatter<TevStageCombiner::ColorCombiner>
{
constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
template <typename FormatContext>
auto format(const TevStageCombiner::ColorCombiner& cc, FormatContext& ctx)
{
return format_to(ctx.out(),
"a: {}\n"
"b: {}\n"
"c: {}\n"
"d: {}\n"
"Bias: {}\n"
"Op: {} / Comparison: {}\n"
"Clamp: {}\n"
"Scale factor: {} / Compare mode: {}\n"
"Dest: {}",
cc.a, cc.b, cc.c, cc.d, cc.bias, cc.op, cc.comparison, cc.clamp ? "Yes" : "No",
cc.scale, cc.compare_mode, cc.dest);
}
};
template <>
struct fmt::formatter<TevStageCombiner::AlphaCombiner>
{
constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
template <typename FormatContext>
auto format(const TevStageCombiner::AlphaCombiner& ac, FormatContext& ctx)
{
return format_to(ctx.out(),
"a: {}\n"
"b: {}\n"
"c: {}\n"
"d: {}\n"
"Bias: {}\n"
"Op: {} / Comparison: {}\n"
"Clamp: {}\n"
"Scale factor: {} / Compare mode: {}\n"
"Dest: {}\n"
"Ras sel: {}\n"
"Tex sel: {}",
ac.a, ac.b, ac.c, ac.d, ac.bias, ac.op, ac.comparison, ac.clamp ? "Yes" : "No",
ac.scale, ac.compare_mode, ac.dest, ac.rswap, ac.tswap);
}
};
// several discoveries: // several discoveries:
// GXSetTevIndBumpST(tevstage, indstage, matrixind) // GXSetTevIndBumpST(tevstage, indstage, matrixind)
@ -444,10 +490,33 @@ union TevStageIndirect
u32 unused : 11; u32 unused : 11;
}; };
u32 fullhex;
// If bs and mid are zero, the result of the stage is independent of // If bs and mid are zero, the result of the stage is independent of
// the texture sample data, so we can skip sampling the texture. // the texture sample data, so we can skip sampling the texture.
bool IsActive() const { return bs != IndTexBumpAlpha::Off || mid != 0; } bool IsActive() const { return bs != IndTexBumpAlpha::Off || mid != 0; }
}; };
template <>
struct fmt::formatter<TevStageIndirect>
{
constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
template <typename FormatContext>
auto format(const TevStageIndirect& tevind, FormatContext& ctx)
{
return format_to(ctx.out(),
"Indirect tex stage ID: {}\n"
"Format: {}\n"
"Bias: {}\n"
"Bump alpha: {}\n"
"Offset matrix ID: {}\n"
"Regular coord S wrapping factor: {}\n"
"Regular coord T wrapping factor: {}\n"
"Use modified texture coordinates for LOD computation: {}\n"
"Add texture coordinates from previous TEV stage: {}",
tevind.bt, tevind.fmt, tevind.bias, tevind.bs, tevind.mid, tevind.sw,
tevind.tw, tevind.lb_utclod ? "Yes" : "No", tevind.fb_addprev ? "Yes" : "No");
}
};
enum class RasColorChan : u32 enum class RasColorChan : u32
{ {
@ -485,6 +554,23 @@ union TwoTevStageOrders
u32 getEnable(int i) const { return i ? enable1.Value() : enable0.Value(); } u32 getEnable(int i) const { return i ? enable1.Value() : enable0.Value(); }
RasColorChan getColorChan(int i) const { return i ? colorchan1.Value() : colorchan0.Value(); } RasColorChan getColorChan(int i) const { return i ? colorchan1.Value() : colorchan0.Value(); }
}; };
template <>
struct fmt::formatter<TwoTevStageOrders>
{
constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
template <typename FormatContext>
auto format(const TwoTevStageOrders& stages, FormatContext& ctx)
{
return format_to(ctx.out(),
"Stage 0 texmap: {}\nStage 0 tex coord: {}\n"
"Stage 0 enable texmap: {}\nStage 0 color channel: {}\n"
"Stage 1 texmap: {}\nStage 1 tex coord: {}\n"
"Stage 1 enable texmap: {}\nStage 1 color channel: {}\n",
stages.texmap0, stages.texcoord0, stages.enable0 ? "Yes" : "No",
stages.colorchan0, stages.texmap1, stages.texcoord1,
stages.enable1 ? "Yes" : "No", stages.colorchan1);
}
};
union TEXSCALE union TEXSCALE
{ {
@ -494,6 +580,22 @@ union TEXSCALE
BitField<12, 4, u32> ts1; // Indirect tex stage 1 BitField<12, 4, u32> ts1; // Indirect tex stage 1
u32 hex; u32 hex;
}; };
template <>
struct fmt::formatter<TEXSCALE>
{
constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
template <typename FormatContext>
auto format(const TEXSCALE& scale, FormatContext& ctx)
{
return format_to(ctx.out(),
"Even stage S scale: {} ({})\n"
"Even stage T scale: {} ({})\n"
"Odd stage S scale: {} ({})\n"
"Odd stage T scale: {} ({})",
scale.ss0, 1.f / (1 << scale.ss0), scale.ts0, 1.f / (1 << scale.ts0),
scale.ss1, 1.f / (1 << scale.ss1), scale.ts1, 1.f / (1 << scale.ts1));
}
};
union RAS1_IREF union RAS1_IREF
{ {
@ -510,6 +612,23 @@ union RAS1_IREF
u32 getTexCoord(int i) const { return (hex >> (6 * i + 3)) & 7; } u32 getTexCoord(int i) const { return (hex >> (6 * i + 3)) & 7; }
u32 getTexMap(int i) const { return (hex >> (6 * i)) & 7; } u32 getTexMap(int i) const { return (hex >> (6 * i)) & 7; }
}; };
template <>
struct fmt::formatter<RAS1_IREF>
{
constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
template <typename FormatContext>
auto format(const RAS1_IREF& indref, FormatContext& ctx)
{
// The field names here are suspicious, since there is no bi3 or bc2
return format_to(ctx.out(),
"Stage 0 ntexmap: {}\nStage 0 ntexcoord: {}\n"
"Stage 1 ntexmap: {}\nStage 1 ntexcoord: {}\n"
"Stage 2 ntexmap: {}\nStage 2 ntexcoord: {}\n"
"Stage 3 ntexmap: {}\nStage 3 ntexcoord: {}",
indref.bi0, indref.bc0, indref.bi1, indref.bc1, indref.bi2, indref.bc3,
indref.bi4, indref.bc4);
}
};
// Texture structs // Texture structs
enum class WrapMode : u32 enum class WrapMode : u32
@ -583,12 +702,47 @@ union TexMode0
BitField<21, 1, bool, u32> lod_clamp; BitField<21, 1, bool, u32> lod_clamp;
u32 hex; u32 hex;
}; };
template <>
struct fmt::formatter<TexMode0>
{
constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
template <typename FormatContext>
auto format(const TexMode0& mode, FormatContext& ctx)
{
return format_to(ctx.out(),
"Wrap S: {}\n"
"Wrap T: {}\n"
"Mag filter: {}\n"
"Mipmap filter: {}\n"
"Min filter: {}\n"
"LOD type: {}\n"
"LOD bias: {} ({})\n"
"Max aniso: {}\n"
"LOD/bias clamp: {}",
mode.wrap_s, mode.wrap_t, mode.mag_filter, mode.mipmap_filter, mode.min_filter,
mode.diag_lod, mode.lod_bias, mode.lod_bias / 32.f, mode.max_aniso,
mode.lod_clamp ? "Yes" : "No");
}
};
union TexMode1 union TexMode1
{ {
BitField<0, 8, u32> min_lod; BitField<0, 8, u32> min_lod;
BitField<8, 8, u32> max_lod; BitField<8, 8, u32> max_lod;
u32 hex; u32 hex;
}; };
template <>
struct fmt::formatter<TexMode1>
{
constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
template <typename FormatContext>
auto format(const TexMode1& mode, FormatContext& ctx)
{
return format_to(ctx.out(), "Min LOD: {} ({})\nMax LOD: {} ({})", mode.min_lod,
mode.min_lod / 16.f, mode.max_lod, mode.max_lod / 16.f);
}
};
union TexImage0 union TexImage0
{ {
BitField<0, 10, u32> width; // Actually w-1 BitField<0, 10, u32> width; // Actually w-1
@ -596,6 +750,21 @@ union TexImage0
BitField<20, 4, TextureFormat> format; BitField<20, 4, TextureFormat> format;
u32 hex; u32 hex;
}; };
template <>
struct fmt::formatter<TexImage0>
{
constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
template <typename FormatContext>
auto format(const TexImage0& teximg, FormatContext& ctx)
{
return format_to(ctx.out(),
"Width: {}\n"
"Height: {}\n"
"Format: {}",
teximg.width + 1, teximg.height + 1, teximg.format);
}
};
union TexImage1 union TexImage1
{ {
BitField<0, 15, u32> tmem_even; // TMEM line index for even LODs BitField<0, 15, u32> tmem_even; // TMEM line index for even LODs
@ -606,6 +775,22 @@ union TexImage1
BitField<21, 1, bool, u32> cache_manually_managed; BitField<21, 1, bool, u32> cache_manually_managed;
u32 hex; u32 hex;
}; };
template <>
struct fmt::formatter<TexImage1>
{
constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
template <typename FormatContext>
auto format(const TexImage1& teximg, FormatContext& ctx)
{
return format_to(ctx.out(),
"Even TMEM Offset: {:x}\n"
"Even TMEM Width: {}\n"
"Even TMEM Height: {}\n"
"Cache is manually managed: {}",
teximg.tmem_even, teximg.cache_width, teximg.cache_height,
teximg.cache_manually_managed ? "Yes" : "No");
}
};
union TexImage2 union TexImage2
{ {
@ -614,18 +799,55 @@ union TexImage2
BitField<18, 3, u32> cache_height; BitField<18, 3, u32> cache_height;
u32 hex; u32 hex;
}; };
template <>
struct fmt::formatter<TexImage2>
{
constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
template <typename FormatContext>
auto format(const TexImage2& teximg, FormatContext& ctx)
{
return format_to(ctx.out(),
"Odd TMEM Offset: {:x}\n"
"Odd TMEM Width: {}\n"
"Odd TMEM Height: {}",
teximg.tmem_odd, teximg.cache_width, teximg.cache_height);
}
};
union TexImage3 union TexImage3
{ {
BitField<0, 24, u32> image_base; // address in memory >> 5 (was 20 for GC) BitField<0, 24, u32> image_base; // address in memory >> 5 (was 20 for GC)
u32 hex; u32 hex;
}; };
template <>
struct fmt::formatter<TexImage3>
{
constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
template <typename FormatContext>
auto format(const TexImage3& teximg, FormatContext& ctx)
{
return format_to(ctx.out(), "Source address (32 byte aligned): 0x{:06X}",
teximg.image_base << 5);
}
};
union TexTLUT union TexTLUT
{ {
BitField<0, 10, u32> tmem_offset; BitField<0, 10, u32> tmem_offset;
BitField<10, 2, TLUTFormat> tlut_format; BitField<10, 2, TLUTFormat> tlut_format;
u32 hex; u32 hex;
}; };
template <>
struct fmt::formatter<TexTLUT>
{
constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
template <typename FormatContext>
auto format(const TexTLUT& tlut, FormatContext& ctx)
{
return format_to(ctx.out(), "Address: {:08x}\nFormat: {}", tlut.tmem_offset << 9,
tlut.tlut_format);
}
};
union ZTex1 union ZTex1
{ {
@ -639,6 +861,16 @@ union ZTex2
BitField<2, 2, ZTexOp> op; BitField<2, 2, ZTexOp> op;
u32 hex; u32 hex;
}; };
template <>
struct fmt::formatter<ZTex2>
{
constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
template <typename FormatContext>
auto format(const ZTex2& ztex2, FormatContext& ctx)
{
return format_to(ctx.out(), "Type: {}\nOperation: {}", ztex2.type, ztex2.op);
}
};
struct FourTexUnits struct FourTexUnits
{ {
@ -686,6 +918,29 @@ union GenMode
u32 hex; u32 hex;
}; };
template <>
struct fmt::formatter<GenMode>
{
constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
template <typename FormatContext>
auto format(const GenMode& mode, FormatContext& ctx)
{
return format_to(ctx.out(),
"Num tex gens: {}\n"
"Num color channels: {}\n"
"Unused bit: {}\n"
"Flat shading (unconfirmed): {}\n"
"Multisampling: {}\n"
"Num TEV stages: {}\n"
"Cull mode: {}\n"
"Num indirect stages: {}\n"
"ZFreeze: {}",
mode.numtexgens, mode.numcolchans, mode.unused,
mode.flat_shading ? "Yes" : "No", mode.multisampling ? "Yes" : "No",
mode.numtevstages, mode.cullmode, mode.numindstages,
mode.zfreeze ? "Yes" : "No");
}
};
enum class AspectRatioAdjustment enum class AspectRatioAdjustment
{ {
@ -708,6 +963,23 @@ union LPSize
BitField<22, 1, AspectRatioAdjustment> adjust_for_aspect_ratio; BitField<22, 1, AspectRatioAdjustment> adjust_for_aspect_ratio;
u32 hex; u32 hex;
}; };
template <>
struct fmt::formatter<LPSize>
{
constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
template <typename FormatContext>
auto format(const LPSize& lp, FormatContext& ctx)
{
return format_to(ctx.out(),
"Line size: {} ({:.3} pixels)\n"
"Point size: {} ({:.3} pixels)\n"
"Line offset: {}\n"
"Point offset: {}\n"
"Adjust line aspect ratio: {}",
lp.linesize, lp.linesize / 6.f, lp.pointsize, lp.pointsize / 6.f, lp.lineoff,
lp.pointoff, lp.adjust_for_aspect_ratio);
}
};
union X12Y12 union X12Y12
{ {
@ -820,6 +1092,29 @@ union BlendMode
bool UseLogicOp() const; bool UseLogicOp() const;
}; };
template <>
struct fmt::formatter<BlendMode>
{
constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
template <typename FormatContext>
auto format(const BlendMode& mode, FormatContext& ctx)
{
static constexpr std::array<const char*, 2> no_yes = {"No", "Yes"};
return format_to(ctx.out(),
"Enable: {}\n"
"Logic ops: {}\n"
"Dither: {}\n"
"Color write: {}\n"
"Alpha write: {}\n"
"Dest factor: {}\n"
"Source factor: {}\n"
"Subtract: {}\n"
"Logic mode: {}",
no_yes[mode.blendenable], no_yes[mode.logicopenable], no_yes[mode.dither],
no_yes[mode.colorupdate], no_yes[mode.alphaupdate], mode.dstfactor,
mode.srcfactor, no_yes[mode.subtract], mode.logicmode);
}
};
union FogParam0 union FogParam0
{ {
@ -830,6 +1125,17 @@ union FogParam0
u32 hex; u32 hex;
float FloatValue() const; float FloatValue() const;
}; };
template <>
struct fmt::formatter<FogParam0>
{
constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
template <typename FormatContext>
auto format(const FogParam0& param, FormatContext& ctx)
{
return format_to(ctx.out(), "A value: {}\nMantissa: {}\nExponent: {}\nSign: {}",
param.FloatValue(), param.mant, param.exp, param.sign ? '-' : '+');
}
};
enum class FogProjection : u32 enum class FogProjection : u32
{ {
@ -878,6 +1184,19 @@ union FogParam3
u32 hex; u32 hex;
float FloatValue() const; float FloatValue() const;
}; };
template <>
struct fmt::formatter<FogParam3>
{
constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
template <typename FormatContext>
auto format(const FogParam3& param, FormatContext& ctx)
{
return format_to(ctx.out(),
"C value: {}\nMantissa: {}\nExponent: {}\nSign: {}\nProjection: {}\nFsel: {}",
param.FloatValue(), param.c_mant, param.c_exp, param.c_sign ? '-' : '+',
param.proj, param.fsel);
}
};
union FogRangeKElement union FogRangeKElement
{ {
@ -900,6 +1219,28 @@ struct FogRangeParams
RangeBase Base; RangeBase Base;
FogRangeKElement K[5]; FogRangeKElement K[5];
}; };
template <>
struct fmt::formatter<FogRangeParams::RangeBase>
{
constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
template <typename FormatContext>
auto format(const FogRangeParams::RangeBase& range, FormatContext& ctx)
{
return format_to(ctx.out(), "Center: {}\nEnabled: {}", range.Center,
range.Enabled ? "Yes" : "No");
}
};
template <>
struct fmt::formatter<FogRangeKElement>
{
constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
template <typename FormatContext>
auto format(const FogRangeKElement& range, FormatContext& ctx)
{
return format_to(ctx.out(), "High: {}\nLow: {}", range.HI, range.LO);
}
};
// final eq: ze = A/(B_MAG - (Zs>>B_SHF)); // final eq: ze = A/(B_MAG - (Zs>>B_SHF));
struct FogParams struct FogParams
{ {
@ -925,6 +1266,16 @@ struct FogParams
// amount to subtract from eyespacez after range adjustment // amount to subtract from eyespacez after range adjustment
float GetC() const; float GetC() const;
}; };
template <>
struct fmt::formatter<FogParams::FogColor>
{
constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
template <typename FormatContext>
auto format(const FogParams::FogColor& color, FormatContext& ctx)
{
return format_to(ctx.out(), "Red: {}\nGreen: {}\nBlue: {}", color.r, color.g, color.b);
}
};
enum class CompareMode : u32 enum class CompareMode : u32
{ {
@ -953,6 +1304,20 @@ union ZMode
u32 hex; u32 hex;
}; };
template <>
struct fmt::formatter<ZMode>
{
constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
template <typename FormatContext>
auto format(const ZMode& mode, FormatContext& ctx)
{
return format_to(ctx.out(),
"Enable test: {}\n"
"Compare function: {}\n"
"Enable updates: {}",
mode.testenable ? "Yes" : "No", mode.func, mode.updateenable ? "Yes" : "No");
}
};
union ConstantAlpha union ConstantAlpha
{ {
@ -960,6 +1325,19 @@ union ConstantAlpha
BitField<8, 1, bool, u32> enable; BitField<8, 1, bool, u32> enable;
u32 hex; u32 hex;
}; };
template <>
struct fmt::formatter<ConstantAlpha>
{
constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
template <typename FormatContext>
auto format(const ConstantAlpha& c, FormatContext& ctx)
{
return format_to(ctx.out(),
"Enable: {}\n"
"Alpha value: {:02x}",
c.enable ? "Yes" : "No", c.alpha);
}
};
union FieldMode union FieldMode
{ {
@ -967,6 +1345,17 @@ union FieldMode
BitField<0, 1, AspectRatioAdjustment> texLOD; BitField<0, 1, AspectRatioAdjustment> texLOD;
u32 hex; u32 hex;
}; };
template <>
struct fmt::formatter<FieldMode>
{
constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
template <typename FormatContext>
auto format(const FieldMode& mode, FormatContext& ctx)
{
return format_to(ctx.out(), "Adjust vertex tex LOD computation to account for interlacing: {}",
mode.texLOD);
}
};
enum class FieldMaskState : u32 enum class FieldMaskState : u32
{ {
@ -986,6 +1375,16 @@ union FieldMask
BitField<1, 1, FieldMaskState> even; BitField<1, 1, FieldMaskState> even;
u32 hex; u32 hex;
}; };
template <>
struct fmt::formatter<FieldMask>
{
constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
template <typename FormatContext>
auto format(const FieldMask& mask, FormatContext& ctx)
{
return format_to(ctx.out(), "Odd field: {}\nEven field: {}", mask.odd, mask.even);
}
};
enum class PixelFormat : u32 enum class PixelFormat : u32
{ {
@ -1038,6 +1437,20 @@ union PEControl
u32 hex; u32 hex;
}; };
template <>
struct fmt::formatter<PEControl>
{
constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
template <typename FormatContext>
auto format(const PEControl& config, FormatContext& ctx)
{
return format_to(ctx.out(),
"EFB pixel format: {}\n"
"Depth format: {}\n"
"Early depth test: {}",
config.pixel_format, config.zformat, config.early_ztest ? "Yes" : "No");
}
};
// Texture coordinate stuff // Texture coordinate stuff
@ -1051,6 +1464,25 @@ union TCInfo
BitField<19, 1, bool, u32> point_offset; BitField<19, 1, bool, u32> point_offset;
u32 hex; u32 hex;
}; };
template <>
struct fmt::formatter<TCInfo>
{
constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
template <typename FormatContext>
auto format(const TCInfo& info, FormatContext& ctx)
{
return format_to(ctx.out(),
"Scale: {}\n"
"Range bias: {}\n"
"Cylindric wrap: {}\n"
"Use line offset: {} (s only)\n"
"Use point offset: {} (s only)",
info.scale_minus_1 + 1, info.range_bias ? "Yes" : "No",
info.cylindric_wrap ? "Yes" : "No", info.line_offset ? "Yes" : "No",
info.point_offset ? "Yes" : "No");
}
};
struct TCoordInfo struct TCoordInfo
{ {
TCInfo s; TCInfo s;
@ -1062,6 +1494,11 @@ enum class TevRegType : u32
Color = 0, Color = 0,
Constant = 1, Constant = 1,
}; };
template <>
struct fmt::formatter<TevRegType> : EnumFormatter<TevRegType::Constant>
{
formatter() : EnumFormatter({"Color", "Constant"}) {}
};
struct TevReg struct TevReg
{ {
@ -1086,6 +1523,37 @@ struct TevReg
RA ra; RA ra;
BG bg; BG bg;
}; };
template <>
struct fmt::formatter<TevReg::RA>
{
constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
template <typename FormatContext>
auto format(const TevReg::RA& ra, FormatContext& ctx)
{
return format_to(ctx.out(), "Type: {}\nAlpha: {:03x}\nRed: {:03x}", ra.type, ra.alpha, ra.red);
}
};
template <>
struct fmt::formatter<TevReg::BG>
{
constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
template <typename FormatContext>
auto format(const TevReg::BG& bg, FormatContext& ctx)
{
return format_to(ctx.out(), "Type: {}\nGreen: {:03x}\nBlue: {:03x}", bg.type, bg.green,
bg.blue);
}
};
template <>
struct fmt::formatter<TevReg>
{
constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
template <typename FormatContext>
auto format(const TevReg& reg, FormatContext& ctx)
{
return format_to(ctx.out(), "{}\n{}", reg.ra, reg.bg);
}
};
enum class KonstSel : u32 enum class KonstSel : u32
{ {
@ -1172,6 +1640,19 @@ union TevKSel
KonstSel getKC(int i) const { return i ? kcsel1.Value() : kcsel0.Value(); } KonstSel getKC(int i) const { return i ? kcsel1.Value() : kcsel0.Value(); }
KonstSel getKA(int i) const { return i ? kasel1.Value() : kasel0.Value(); } KonstSel getKA(int i) const { return i ? kasel1.Value() : kasel0.Value(); }
}; };
template <>
struct fmt::formatter<TevKSel>
{
constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
template <typename FormatContext>
auto format(const TevKSel& ksel, FormatContext& ctx)
{
return format_to(ctx.out(),
"Swap 1: {}\nSwap 2: {}\nColor sel 0: {}\nAlpha sel 0: {}\n"
"Color sel 1: {}\nAlpha sel 1: {}",
ksel.swap1, ksel.swap2, ksel.kcsel0, ksel.kasel0, ksel.kcsel1, ksel.kasel1);
}
};
enum class AlphaTestOp : u32 enum class AlphaTestOp : u32
{ {
@ -1245,6 +1726,20 @@ union AlphaTest
return AlphaTestResult::Undetermined; return AlphaTestResult::Undetermined;
} }
}; };
template <>
struct fmt::formatter<AlphaTest>
{
constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
template <typename FormatContext>
auto format(const AlphaTest& test, FormatContext& ctx)
{
return format_to(ctx.out(),
"Test 1: {} (ref: 0x{:02x})\n"
"Test 2: {} (ref: 0x{:02x})\n"
"Logic: {}\n",
test.comp0, test.ref0, test.comp1, test.ref1, test.logic);
}
};
enum class FrameToField : u32 enum class FrameToField : u32
{ {
@ -1286,6 +1781,60 @@ union UPE_Copy
return static_cast<EFBCopyFormat>(target_pixel_format / 2 + (target_pixel_format & 1) * 8); return static_cast<EFBCopyFormat>(target_pixel_format / 2 + (target_pixel_format & 1) * 8);
} }
}; };
template <>
struct fmt::formatter<UPE_Copy>
{
constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
template <typename FormatContext>
auto format(const UPE_Copy& copy, FormatContext& ctx)
{
static constexpr std::array<const char*, 2> no_yes = {"No", "Yes"};
std::string_view clamp;
if (copy.clamp_top)
{
if (copy.clamp_bottom)
clamp = "Top and Bottom";
else
clamp = "Top only";
}
else
{
if (copy.clamp_bottom)
clamp = "Bottom only";
else
clamp = "None";
}
std::string_view gamma = "Invalid";
switch (copy.gamma)
{
case 0:
gamma = "1.0";
break;
case 1:
gamma = "1.7";
break;
case 2:
gamma = "2.2";
break;
}
return format_to(ctx.out(),
"Clamping: {}\n"
"Converting from RGB to YUV: {}\n"
"Target pixel format: {}\n"
"Gamma correction: {}\n"
"Mipmap filter: {}\n"
"Vertical scaling: {}\n"
"Clear: {}\n"
"Frame to field: {}\n"
"Copy to XFB: {}\n"
"Intensity format: {}\n"
"Automatic color conversion: {}",
clamp, no_yes[copy.yuv], copy.tp_realFormat(), gamma, no_yes[copy.half_scale],
no_yes[copy.scale_invert], no_yes[copy.clear], copy.frame_to_field,
no_yes[copy.copy_to_xfb], no_yes[copy.intensity_fmt], no_yes[copy.auto_conv]);
}
};
union CopyFilterCoefficients union CopyFilterCoefficients
{ {
@ -1321,6 +1870,16 @@ union BPU_PreloadTileInfo
BitField<15, 2, u32> type; BitField<15, 2, u32> type;
u32 hex; u32 hex;
}; };
template <>
struct fmt::formatter<BPU_PreloadTileInfo>
{
constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
template <typename FormatContext>
auto format(const BPU_PreloadTileInfo& info, FormatContext& ctx)
{
return format_to(ctx.out(), "Type: {}\nCount: {}", info.type, info.count);
}
};
struct BPS_TmemConfig struct BPS_TmemConfig
{ {
@ -1420,4 +1979,4 @@ extern BPMemory bpmem;
void LoadBPReg(u32 value0); void LoadBPReg(u32 value0);
void LoadBPRegPreprocess(u32 value0); void LoadBPRegPreprocess(u32 value0);
void GetBPRegInfo(const u8* data, std::string* name, std::string* desc); std::pair<std::string, std::string> GetBPRegInfo(u8 cmd, u32 cmddata);

View File

@ -745,61 +745,59 @@ void LoadBPRegPreprocess(u32 value0)
} }
} }
void GetBPRegInfo(const u8* data, std::string* name, std::string* desc) std::pair<std::string, std::string> GetBPRegInfo(u8 cmd, u32 cmddata)
{ {
const char* no_yes[2] = {"No", "Yes"}; // Macro to set the register name and make sure it was written correctly via compile time assertion
#define RegName(reg) ((void)(reg), #reg)
#define DescriptionlessReg(reg) std::make_pair(RegName(reg), "");
u8 cmd = data[0];
u32 cmddata = Common::swap32(data) & 0xFFFFFF;
switch (cmd) switch (cmd)
{ {
// Macro to set the register name and make sure it was written correctly via compile time assertion
#define SetRegName(reg) \
*name = #reg; \
(void)(reg);
case BPMEM_GENMODE: // 0x00 case BPMEM_GENMODE: // 0x00
SetRegName(BPMEM_GENMODE); return std::make_pair(RegName(BPMEM_GENMODE), fmt::to_string(GenMode{.hex = cmddata}));
// TODO: Description
break;
case BPMEM_DISPLAYCOPYFILTER: // 0x01 case BPMEM_DISPLAYCOPYFILTER: // 0x01
case BPMEM_DISPLAYCOPYFILTER + 1:
case BPMEM_DISPLAYCOPYFILTER + 2:
case BPMEM_DISPLAYCOPYFILTER + 3:
// TODO: This is actually the sample pattern used for copies from an antialiased EFB // TODO: This is actually the sample pattern used for copies from an antialiased EFB
SetRegName(BPMEM_DISPLAYCOPYFILTER); return DescriptionlessReg(BPMEM_DISPLAYCOPYFILTER);
// TODO: Description // TODO: Description
break;
case 0x02: // 0x02
case 0x03: // 0x03
case 0x04: // 0x04
// TODO: same as BPMEM_DISPLAYCOPYFILTER
break;
case BPMEM_IND_MTXA: // 0x06 case BPMEM_IND_MTXA: // 0x06
case BPMEM_IND_MTXA + 3:
case BPMEM_IND_MTXA + 6:
SetRegName(BPMEM_IND_MTXA);
// TODO: Description
break;
case BPMEM_IND_MTXB: // 0x07 case BPMEM_IND_MTXB: // 0x07
case BPMEM_IND_MTXB + 3:
case BPMEM_IND_MTXB + 6:
SetRegName(BPMEM_IND_MTXB);
// TODO: Descriptio
break;
case BPMEM_IND_MTXC: // 0x08 case BPMEM_IND_MTXC: // 0x08
case BPMEM_IND_MTXA + 3:
case BPMEM_IND_MTXB + 3:
case BPMEM_IND_MTXC + 3: case BPMEM_IND_MTXC + 3:
case BPMEM_IND_MTXA + 6:
case BPMEM_IND_MTXB + 6:
case BPMEM_IND_MTXC + 6: case BPMEM_IND_MTXC + 6:
SetRegName(BPMEM_IND_MTXC); {
// TODO: Description const u32 matrix_num = (cmd - BPMEM_IND_MTXA) / 3;
break; const u32 matrix_col = (cmd - BPMEM_IND_MTXA) % 3;
// These all use the same structure, though the meaning is *slightly* different;
// for conveninece implement it only once
const s32 row0 = cmddata & 0x0007ff; // ma or mc or me
const s32 row1 = (cmddata & 0x3ff800) >> 11; // mb or md or mf
const u32 scale = (cmddata & 0xc00000) >> 22; // 2 bits of a 6-bit field for each column
const float row0f = static_cast<float>(row0) / (1 << 10);
const float row1f = static_cast<float>(row0) / (1 << 10);
return std::make_pair(fmt::format("BPMEM_IND_MTX{} Matrix {}", "ABC"[matrix_col], matrix_num),
fmt::format("Matrix {} column {} ({})\n"
"Row 0 (m{}): {} ({})\n"
"Row 1 (m{}): {} ({})\n"
"Scale bits: {} (shifted: {})",
matrix_num, matrix_col, "ABC"[matrix_col], "ace"[matrix_col],
row0f, row0, "bdf"[matrix_col], row1f, row1, scale,
scale << (2 * matrix_col)));
}
case BPMEM_IND_IMASK: // 0x0F case BPMEM_IND_IMASK: // 0x0F
SetRegName(BPMEM_IND_IMASK); return DescriptionlessReg(BPMEM_IND_IMASK);
// TODO: Description // TODO: Description
break;
case BPMEM_IND_CMD: // 0x10 case BPMEM_IND_CMD: // 0x10
case BPMEM_IND_CMD + 1: case BPMEM_IND_CMD + 1:
@ -817,49 +815,47 @@ void GetBPRegInfo(const u8* data, std::string* name, std::string* desc)
case BPMEM_IND_CMD + 13: case BPMEM_IND_CMD + 13:
case BPMEM_IND_CMD + 14: case BPMEM_IND_CMD + 14:
case BPMEM_IND_CMD + 15: case BPMEM_IND_CMD + 15:
SetRegName(BPMEM_IND_CMD); return std::make_pair(fmt::format("BPMEM_IND_CMD command {}", cmd - BPMEM_IND_CMD),
// TODO: Description fmt::to_string(TevStageIndirect{.fullhex = cmddata}));
break;
case BPMEM_SCISSORTL: // 0x20 case BPMEM_SCISSORTL: // 0x20
SetRegName(BPMEM_SCISSORTL); {
// TODO: Description const X12Y12 top_left{.hex = cmddata};
break; return std::make_pair(RegName(BPMEM_SCISSORTL),
fmt::format("Scissor Top: {}\nScissor Left: {}", top_left.y, top_left.x));
}
case BPMEM_SCISSORBR: // 0x21 case BPMEM_SCISSORBR: // 0x21
SetRegName(BPMEM_SCISSORBR); {
// TODO: Description const X12Y12 bottom_right{.hex = cmddata};
break; return std::make_pair(
RegName(BPMEM_SCISSORBR),
fmt::format("Scissor Bottom: {}\nScissor Right: {}", bottom_right.y, bottom_right.x));
}
case BPMEM_LINEPTWIDTH: // 0x22 case BPMEM_LINEPTWIDTH: // 0x22
SetRegName(BPMEM_LINEPTWIDTH); return std::make_pair(RegName(BPMEM_LINEPTWIDTH), fmt::to_string(LPSize{.hex = cmddata}));
// TODO: Description
break;
case BPMEM_PERF0_TRI: // 0x23 case BPMEM_PERF0_TRI: // 0x23
SetRegName(BPMEM_PERF0_TRI); return DescriptionlessReg(BPMEM_PERF0_TRI);
// TODO: Description // TODO: Description
break;
case BPMEM_PERF0_QUAD: // 0x24 case BPMEM_PERF0_QUAD: // 0x24
SetRegName(BPMEM_PERF0_QUAD); return DescriptionlessReg(BPMEM_PERF0_QUAD);
// TODO: Description // TODO: Description
break;
case BPMEM_RAS1_SS0: // 0x25 case BPMEM_RAS1_SS0: // 0x25
SetRegName(BPMEM_RAS1_SS0); return std::make_pair(
// TODO: Description RegName(BPMEM_RAS1_SS0),
break; fmt::format("Indirect texture stages 0 and 1:\n{}", TEXSCALE{.hex = cmddata}));
case BPMEM_RAS1_SS1: // 0x26 case BPMEM_RAS1_SS1: // 0x26
SetRegName(BPMEM_RAS1_SS1); return std::make_pair(
// TODO: Description RegName(BPMEM_RAS1_SS1),
break; fmt::format("Indirect texture stages 2 and 3:\n{}", TEXSCALE{.hex = cmddata}));
case BPMEM_IREF: // 0x27 case BPMEM_IREF: // 0x27
SetRegName(BPMEM_IREF); return std::make_pair(RegName(BPMEM_IREF), fmt::to_string(RAS1_IREF{.hex = cmddata}));
// TODO: Description
break;
case BPMEM_TREF: // 0x28 case BPMEM_TREF: // 0x28
case BPMEM_TREF + 1: case BPMEM_TREF + 1:
@ -869,9 +865,8 @@ void GetBPRegInfo(const u8* data, std::string* name, std::string* desc)
case BPMEM_TREF + 5: case BPMEM_TREF + 5:
case BPMEM_TREF + 6: case BPMEM_TREF + 6:
case BPMEM_TREF + 7: case BPMEM_TREF + 7:
SetRegName(BPMEM_TREF); return std::make_pair(fmt::format("BPMEM_TREF number {}", cmd - BPMEM_TREF),
// TODO: Description fmt::to_string(TwoTevStageOrders{.hex = cmddata}));
break;
case BPMEM_SU_SSIZE: // 0x30 case BPMEM_SU_SSIZE: // 0x30
case BPMEM_SU_SSIZE + 2: case BPMEM_SU_SSIZE + 2:
@ -881,9 +876,8 @@ void GetBPRegInfo(const u8* data, std::string* name, std::string* desc)
case BPMEM_SU_SSIZE + 10: case BPMEM_SU_SSIZE + 10:
case BPMEM_SU_SSIZE + 12: case BPMEM_SU_SSIZE + 12:
case BPMEM_SU_SSIZE + 14: case BPMEM_SU_SSIZE + 14:
SetRegName(BPMEM_SU_SSIZE); return std::make_pair(fmt::format("BPMEM_SU_SSIZE number {}", (cmd - BPMEM_SU_SSIZE) / 2),
// TODO: Description fmt::format("S size info:\n{}", TCInfo{.hex = cmddata}));
break;
case BPMEM_SU_TSIZE: // 0x31 case BPMEM_SU_TSIZE: // 0x31
case BPMEM_SU_TSIZE + 2: case BPMEM_SU_TSIZE + 2:
@ -893,359 +887,283 @@ void GetBPRegInfo(const u8* data, std::string* name, std::string* desc)
case BPMEM_SU_TSIZE + 10: case BPMEM_SU_TSIZE + 10:
case BPMEM_SU_TSIZE + 12: case BPMEM_SU_TSIZE + 12:
case BPMEM_SU_TSIZE + 14: case BPMEM_SU_TSIZE + 14:
SetRegName(BPMEM_SU_TSIZE); return std::make_pair(fmt::format("BPMEM_SU_TSIZE number {}", (cmd - BPMEM_SU_TSIZE) / 2),
// TODO: Description fmt::format("T size info:\n{}", TCInfo{.hex = cmddata}));
break;
case BPMEM_ZMODE: // 0x40 case BPMEM_ZMODE: // 0x40
SetRegName(BPMEM_ZMODE); return std::make_pair(RegName(BPMEM_ZMODE), fmt::format("Z mode: {}", ZMode{.hex = cmddata}));
// TODO: Description
break;
case BPMEM_BLENDMODE: // 0x41 case BPMEM_BLENDMODE: // 0x41
{ return std::make_pair(RegName(BPMEM_BLENDMODE), fmt::to_string(BlendMode{.hex = cmddata}));
SetRegName(BPMEM_BLENDMODE);
BlendMode mode;
mode.hex = cmddata;
*desc = fmt::format("Enable: {}\n"
"Logic ops: {}\n"
"Dither: {}\n"
"Color write: {}\n"
"Alpha write: {}\n"
"Dest factor: {}\n"
"Source factor: {}\n"
"Subtract: {}\n"
"Logic mode: {}\n",
no_yes[mode.blendenable], no_yes[mode.logicopenable], no_yes[mode.dither],
no_yes[mode.colorupdate], no_yes[mode.alphaupdate], mode.dstfactor,
mode.srcfactor, no_yes[mode.subtract], mode.logicmode);
}
break;
case BPMEM_CONSTANTALPHA: // 0x42 case BPMEM_CONSTANTALPHA: // 0x42
SetRegName(BPMEM_CONSTANTALPHA); return std::make_pair(RegName(BPMEM_CONSTANTALPHA),
// TODO: Description fmt::to_string(ConstantAlpha{.hex = cmddata}));
break;
case BPMEM_ZCOMPARE: // 0x43 case BPMEM_ZCOMPARE: // 0x43
{ return std::make_pair(RegName(BPMEM_ZCOMPARE), fmt::to_string(PEControl{.hex = cmddata}));
SetRegName(BPMEM_ZCOMPARE);
PEControl config;
config.hex = cmddata;
*desc = fmt::format("EFB pixel format: {}\n"
"Depth format: {}\n"
"Early depth test: {}\n",
config.pixel_format, config.zformat, no_yes[config.early_ztest]);
}
break;
case BPMEM_FIELDMASK: // 0x44 case BPMEM_FIELDMASK: // 0x44
SetRegName(BPMEM_FIELDMASK); return std::make_pair(RegName(BPMEM_FIELDMASK), fmt::to_string(FieldMask{.hex = cmddata}));
// TODO: Description
break;
case BPMEM_SETDRAWDONE: // 0x45 case BPMEM_SETDRAWDONE: // 0x45
SetRegName(BPMEM_SETDRAWDONE); return DescriptionlessReg(BPMEM_SETDRAWDONE);
// TODO: Description // TODO: Description
break;
case BPMEM_BUSCLOCK0: // 0x46 case BPMEM_BUSCLOCK0: // 0x46
SetRegName(BPMEM_BUSCLOCK0); return DescriptionlessReg(BPMEM_BUSCLOCK0);
// TODO: Description // TODO: Description
break;
case BPMEM_PE_TOKEN_ID: // 0x47 case BPMEM_PE_TOKEN_ID: // 0x47
SetRegName(BPMEM_PE_TOKEN_ID); return DescriptionlessReg(BPMEM_PE_TOKEN_ID);
// TODO: Description // TODO: Description
break;
case BPMEM_PE_TOKEN_INT_ID: // 0x48 case BPMEM_PE_TOKEN_INT_ID: // 0x48
SetRegName(BPMEM_PE_TOKEN_INT_ID); return DescriptionlessReg(BPMEM_PE_TOKEN_INT_ID);
// TODO: Description // TODO: Description
break;
case BPMEM_EFB_TL: // 0x49 case BPMEM_EFB_TL: // 0x49
{ {
SetRegName(BPMEM_EFB_TL); const X10Y10 left_top{.hex = cmddata};
X10Y10 left_top; return std::make_pair(RegName(BPMEM_EFB_TL),
left_top.hex = cmddata; fmt::format("EFB Left: {}\nEFB Top: {}", left_top.x, left_top.y));
*desc = fmt::format("Left: {}\nTop: {}", u32(left_top.x), u32(left_top.y));
} }
break;
case BPMEM_EFB_WH: // 0x4A case BPMEM_EFB_WH: // 0x4A
{ {
SetRegName(BPMEM_EFB_WH); const X10Y10 width_height{.hex = cmddata};
X10Y10 width_height; return std::make_pair(
width_height.hex = cmddata; RegName(BPMEM_EFB_WH),
*desc = fmt::format("Width: {}\nHeight: {}", width_height.x + 1, width_height.y + 1); fmt::format("EFB Width: {}\nEFB Height: {}", width_height.x + 1, width_height.y + 1));
} }
break;
case BPMEM_EFB_ADDR: // 0x4B case BPMEM_EFB_ADDR: // 0x4B
SetRegName(BPMEM_EFB_ADDR); return std::make_pair(
*desc = fmt::format("Target address (32 byte aligned): 0x{:06X}", cmddata << 5); RegName(BPMEM_EFB_ADDR),
break; fmt::format("EFB Target address (32 byte aligned): 0x{:06X}", cmddata << 5));
case BPMEM_MIPMAP_STRIDE: // 0x4D case BPMEM_MIPMAP_STRIDE: // 0x4D
SetRegName(BPMEM_MIPMAP_STRIDE); return DescriptionlessReg(BPMEM_MIPMAP_STRIDE);
// TODO: Description // TODO: Description
break;
case BPMEM_COPYYSCALE: // 0x4E case BPMEM_COPYYSCALE: // 0x4E
SetRegName(BPMEM_COPYYSCALE); return std::make_pair(
*desc = fmt::format("Scaling factor (XFB copy only): 0x{:X} ({} or inverted {})", cmddata, RegName(BPMEM_COPYYSCALE),
static_cast<float>(cmddata) / 256.f, 256.f / static_cast<float>(cmddata)); fmt::format("Y scaling factor (XFB copy only): 0x{:X} ({}, reciprocal {})", cmddata,
break; static_cast<float>(cmddata) / 256.f, 256.f / static_cast<float>(cmddata)));
case BPMEM_CLEAR_AR: // 0x4F case BPMEM_CLEAR_AR: // 0x4F
SetRegName(BPMEM_CLEAR_AR); return std::make_pair(RegName(BPMEM_CLEAR_AR),
*desc = fmt::format("Alpha: 0x{:02X}\nRed: 0x{:02X}", (cmddata & 0xFF00) >> 8, cmddata & 0xFF); fmt::format("Clear color alpha: 0x{:02X}\nClear color red: 0x{:02X}",
break; (cmddata & 0xFF00) >> 8, cmddata & 0xFF));
case BPMEM_CLEAR_GB: // 0x50 case BPMEM_CLEAR_GB: // 0x50
SetRegName(BPMEM_CLEAR_GB); return std::make_pair(RegName(BPMEM_CLEAR_GB),
*desc = fmt::format("Green: 0x{:02X}\nBlue: 0x{:02X}", (cmddata & 0xFF00) >> 8, cmddata & 0xFF); fmt::format("Clear color green: 0x{:02X}\nClear color blue: 0x{:02X}",
break; (cmddata & 0xFF00) >> 8, cmddata & 0xFF));
case BPMEM_CLEAR_Z: // 0x51 case BPMEM_CLEAR_Z: // 0x51
SetRegName(BPMEM_CLEAR_Z); return std::make_pair(RegName(BPMEM_CLEAR_Z), fmt::format("Clear Z value: 0x{:06X}", cmddata));
*desc = fmt::format("Z value: 0x{:06X}", cmddata);
break;
case BPMEM_TRIGGER_EFB_COPY: // 0x52 case BPMEM_TRIGGER_EFB_COPY: // 0x52
{ return std::make_pair(RegName(BPMEM_TRIGGER_EFB_COPY),
SetRegName(BPMEM_TRIGGER_EFB_COPY); fmt::to_string(UPE_Copy{.Hex = cmddata}));
UPE_Copy copy;
copy.Hex = cmddata;
*desc = fmt::format(
"Clamping: {}\n"
"Converting from RGB to YUV: {}\n"
"Target pixel format: 0x{:X}\n"
"Gamma correction: {}\n"
"Mipmap filter: {}\n"
"Vertical scaling: {}\n"
"Clear: {}\n"
"Frame to field: {}\n"
"Copy to XFB: {}\n"
"Intensity format: {}\n"
"Automatic color conversion: {}",
(copy.clamp_top && copy.clamp_bottom) ?
"Top and Bottom" :
(copy.clamp_top) ? "Top only" : (copy.clamp_bottom) ? "Bottom only" : "None",
no_yes[copy.yuv], static_cast<int>(copy.tp_realFormat()),
(copy.gamma == 0) ?
"1.0" :
(copy.gamma == 1) ? "1.7" : (copy.gamma == 2) ? "2.2" : "Invalid value 0x3?",
no_yes[copy.half_scale], no_yes[copy.scale_invert], no_yes[copy.clear], copy.frame_to_field,
no_yes[copy.copy_to_xfb], no_yes[copy.intensity_fmt], no_yes[copy.auto_conv]);
}
break;
case BPMEM_COPYFILTER0: // 0x53 case BPMEM_COPYFILTER0: // 0x53
SetRegName(BPMEM_COPYFILTER0); {
// TODO: Description const u32 w0 = (cmddata & 0x00003f);
break; const u32 w1 = (cmddata & 0x000fc0) >> 6;
const u32 w2 = (cmddata & 0x03f000) >> 12;
const u32 w3 = (cmddata & 0xfc0000) >> 18;
return std::make_pair(RegName(BPMEM_COPYFILTER0),
fmt::format("w0: {}\nw1: {}\nw2: {}\nw3: {}", w0, w1, w2, w3));
}
case BPMEM_COPYFILTER1: // 0x54 case BPMEM_COPYFILTER1: // 0x54
SetRegName(BPMEM_COPYFILTER1); {
// TODO: Description const u32 w4 = (cmddata & 0x00003f);
break; const u32 w5 = (cmddata & 0x000fc0) >> 6;
const u32 w6 = (cmddata & 0x03f000) >> 12;
// There is no w7
return std::make_pair(RegName(BPMEM_COPYFILTER1),
fmt::format("w4: {}\nw5: {}\nw6: {}", w4, w5, w6));
}
case BPMEM_CLEARBBOX1: // 0x55 case BPMEM_CLEARBBOX1: // 0x55
SetRegName(BPMEM_CLEARBBOX1); return DescriptionlessReg(BPMEM_CLEARBBOX1);
// TODO: Description // TODO: Description
break;
case BPMEM_CLEARBBOX2: // 0x56 case BPMEM_CLEARBBOX2: // 0x56
SetRegName(BPMEM_CLEARBBOX2); return DescriptionlessReg(BPMEM_CLEARBBOX2);
// TODO: Description // TODO: Description
break;
case BPMEM_CLEAR_PIXEL_PERF: // 0x57 case BPMEM_CLEAR_PIXEL_PERF: // 0x57
SetRegName(BPMEM_CLEAR_PIXEL_PERF); return DescriptionlessReg(BPMEM_CLEAR_PIXEL_PERF);
// TODO: Description // TODO: Description
break;
case BPMEM_REVBITS: // 0x58 case BPMEM_REVBITS: // 0x58
SetRegName(BPMEM_REVBITS); return DescriptionlessReg(BPMEM_REVBITS);
// TODO: Description // TODO: Description
break;
case BPMEM_SCISSOROFFSET: // 0x59 case BPMEM_SCISSOROFFSET: // 0x59
SetRegName(BPMEM_SCISSOROFFSET); {
// TODO: Description const X10Y10 xy{.hex = cmddata};
break; return std::make_pair(RegName(BPMEM_EFB_TL),
fmt::format("Scissor X offset: {}\nScissor Y offset: {}", xy.x, xy.y));
}
case BPMEM_PRELOAD_ADDR: // 0x60 case BPMEM_PRELOAD_ADDR: // 0x60
SetRegName(BPMEM_PRELOAD_ADDR); return DescriptionlessReg(BPMEM_PRELOAD_ADDR);
// TODO: Description // TODO: Description
break;
case BPMEM_PRELOAD_TMEMEVEN: // 0x61 case BPMEM_PRELOAD_TMEMEVEN: // 0x61
SetRegName(BPMEM_PRELOAD_TMEMEVEN); return DescriptionlessReg(BPMEM_PRELOAD_TMEMEVEN);
// TODO: Description // TODO: Description
break;
case BPMEM_PRELOAD_TMEMODD: // 0x62 case BPMEM_PRELOAD_TMEMODD: // 0x62
SetRegName(BPMEM_PRELOAD_TMEMODD); return DescriptionlessReg(BPMEM_PRELOAD_TMEMODD);
// TODO: Description // TODO: Description
break;
case BPMEM_PRELOAD_MODE: // 0x63 case BPMEM_PRELOAD_MODE: // 0x63
SetRegName(BPMEM_PRELOAD_MODE); return std::make_pair(RegName(BPMEM_PRELOAD_MODE),
// TODO: Description fmt::to_string(BPU_PreloadTileInfo{.hex = cmddata}));
break;
case BPMEM_LOADTLUT0: // 0x64 case BPMEM_LOADTLUT0: // 0x64
SetRegName(BPMEM_LOADTLUT0); return DescriptionlessReg(BPMEM_LOADTLUT0);
// TODO: Description // TODO: Description
break;
case BPMEM_LOADTLUT1: // 0x65 case BPMEM_LOADTLUT1: // 0x65
SetRegName(BPMEM_LOADTLUT1); return DescriptionlessReg(BPMEM_LOADTLUT1);
// TODO: Description // TODO: Description
break;
case BPMEM_TEXINVALIDATE: // 0x66 case BPMEM_TEXINVALIDATE: // 0x66
SetRegName(BPMEM_TEXINVALIDATE); return DescriptionlessReg(BPMEM_TEXINVALIDATE);
// TODO: Description // TODO: Description
break;
case BPMEM_PERF1: // 0x67 case BPMEM_PERF1: // 0x67
SetRegName(BPMEM_PERF1); return DescriptionlessReg(BPMEM_PERF1);
// TODO: Description // TODO: Description
break;
case BPMEM_FIELDMODE: // 0x68 case BPMEM_FIELDMODE: // 0x68
SetRegName(BPMEM_FIELDMODE); return std::make_pair(RegName(BPMEM_FIELDMODE), fmt::to_string(FieldMode{.hex = cmddata}));
// TODO: Description
break;
case BPMEM_BUSCLOCK1: // 0x69 case BPMEM_BUSCLOCK1: // 0x69
SetRegName(BPMEM_BUSCLOCK1); return DescriptionlessReg(BPMEM_BUSCLOCK1);
// TODO: Description // TODO: Description
break;
case BPMEM_TX_SETMODE0: // 0x80 case BPMEM_TX_SETMODE0: // 0x80
case BPMEM_TX_SETMODE0 + 1: case BPMEM_TX_SETMODE0 + 1:
case BPMEM_TX_SETMODE0 + 2: case BPMEM_TX_SETMODE0 + 2:
case BPMEM_TX_SETMODE0 + 3: case BPMEM_TX_SETMODE0 + 3:
SetRegName(BPMEM_TX_SETMODE0); return std::make_pair(fmt::format("BPMEM_TX_SETMODE0 Texture Unit {}", cmd - BPMEM_TX_SETMODE0),
// TODO: Description fmt::to_string(TexMode0{.hex = cmddata}));
break;
case BPMEM_TX_SETMODE1: // 0x84 case BPMEM_TX_SETMODE1: // 0x84
case BPMEM_TX_SETMODE1 + 1: case BPMEM_TX_SETMODE1 + 1:
case BPMEM_TX_SETMODE1 + 2: case BPMEM_TX_SETMODE1 + 2:
case BPMEM_TX_SETMODE1 + 3: case BPMEM_TX_SETMODE1 + 3:
SetRegName(BPMEM_TX_SETMODE1); return std::make_pair(fmt::format("BPMEM_TX_SETMODE1 Texture Unit {}", cmd - BPMEM_TX_SETMODE1),
// TODO: Description fmt::to_string(TexMode1{.hex = cmddata}));
break;
case BPMEM_TX_SETIMAGE0: // 0x88 case BPMEM_TX_SETIMAGE0: // 0x88
case BPMEM_TX_SETIMAGE0 + 1: case BPMEM_TX_SETIMAGE0 + 1:
case BPMEM_TX_SETIMAGE0 + 2: case BPMEM_TX_SETIMAGE0 + 2:
case BPMEM_TX_SETIMAGE0 + 3: case BPMEM_TX_SETIMAGE0 + 3:
case BPMEM_TX_SETIMAGE0_4: // 0xA8 return std::make_pair(
case BPMEM_TX_SETIMAGE0_4 + 1: fmt::format("BPMEM_TX_SETIMAGE0 Texture Unit {}", cmd - BPMEM_TX_SETIMAGE0),
case BPMEM_TX_SETIMAGE0_4 + 2: fmt::to_string(TexImage0{.hex = cmddata}));
case BPMEM_TX_SETIMAGE0_4 + 3:
{
SetRegName(BPMEM_TX_SETIMAGE0);
int texnum =
(cmd < BPMEM_TX_SETIMAGE0_4) ? cmd - BPMEM_TX_SETIMAGE0 : cmd - BPMEM_TX_SETIMAGE0_4 + 4;
TexImage0 teximg;
teximg.hex = cmddata;
*desc = fmt::format("Texture Unit: {}\n"
"Width: {}\n"
"Height: {}\n"
"Format: {}\n",
texnum, u32(teximg.width) + 1, u32(teximg.height) + 1, teximg.format);
}
break;
case BPMEM_TX_SETIMAGE1: // 0x8C case BPMEM_TX_SETIMAGE1: // 0x8C
case BPMEM_TX_SETIMAGE1 + 1: case BPMEM_TX_SETIMAGE1 + 1:
case BPMEM_TX_SETIMAGE1 + 2: case BPMEM_TX_SETIMAGE1 + 2:
case BPMEM_TX_SETIMAGE1 + 3: case BPMEM_TX_SETIMAGE1 + 3:
case BPMEM_TX_SETIMAGE1_4: // 0xAC return std::make_pair(
case BPMEM_TX_SETIMAGE1_4 + 1: fmt::format("BPMEM_TX_SETIMAGE1 Texture Unit {}", cmd - BPMEM_TX_SETIMAGE1),
case BPMEM_TX_SETIMAGE1_4 + 2: fmt::to_string(TexImage1{.hex = cmddata}));
case BPMEM_TX_SETIMAGE1_4 + 3:
{
SetRegName(BPMEM_TX_SETIMAGE1);
int texnum =
(cmd < BPMEM_TX_SETIMAGE1_4) ? cmd - BPMEM_TX_SETIMAGE1 : cmd - BPMEM_TX_SETIMAGE1_4 + 4;
TexImage1 teximg;
teximg.hex = cmddata;
*desc = fmt::format("Texture Unit: {}\n"
"Even TMEM Offset: {:x}\n"
"Even TMEM Width: {}\n"
"Even TMEM Height: {}\n"
"Cache is manually managed: {}\n",
texnum, u32(teximg.tmem_even), u32(teximg.cache_width),
u32(teximg.cache_height), no_yes[teximg.cache_manually_managed]);
}
break;
case BPMEM_TX_SETIMAGE2: // 0x90 case BPMEM_TX_SETIMAGE2: // 0x90
case BPMEM_TX_SETIMAGE2 + 1: case BPMEM_TX_SETIMAGE2 + 1:
case BPMEM_TX_SETIMAGE2 + 2: case BPMEM_TX_SETIMAGE2 + 2:
case BPMEM_TX_SETIMAGE2 + 3: case BPMEM_TX_SETIMAGE2 + 3:
case BPMEM_TX_SETIMAGE2_4: // 0xB0 return std::make_pair(
case BPMEM_TX_SETIMAGE2_4 + 1: fmt::format("BPMEM_TX_SETIMAGE2 Texture Unit {}", cmd - BPMEM_TX_SETIMAGE2),
case BPMEM_TX_SETIMAGE2_4 + 2: fmt::to_string(TexImage2{.hex = cmddata}));
case BPMEM_TX_SETIMAGE2_4 + 3:
{
SetRegName(BPMEM_TX_SETIMAGE2);
int texnum =
(cmd < BPMEM_TX_SETIMAGE2_4) ? cmd - BPMEM_TX_SETIMAGE2 : cmd - BPMEM_TX_SETIMAGE2_4 + 4;
TexImage2 teximg;
teximg.hex = cmddata;
*desc = fmt::format("Texture Unit: {}\n"
"Odd TMEM Offset: {:x}\n"
"Odd TMEM Width: {}\n"
"Odd TMEM Height: {}\n",
texnum, u32(teximg.tmem_odd), u32(teximg.cache_width),
u32(teximg.cache_height));
}
break;
case BPMEM_TX_SETIMAGE3: // 0x94 case BPMEM_TX_SETIMAGE3: // 0x94
case BPMEM_TX_SETIMAGE3 + 1: case BPMEM_TX_SETIMAGE3 + 1:
case BPMEM_TX_SETIMAGE3 + 2: case BPMEM_TX_SETIMAGE3 + 2:
case BPMEM_TX_SETIMAGE3 + 3: case BPMEM_TX_SETIMAGE3 + 3:
case BPMEM_TX_SETIMAGE3_4: // 0xB4 return std::make_pair(
case BPMEM_TX_SETIMAGE3_4 + 1: fmt::format("BPMEM_TX_SETIMAGE3 Texture Unit {}", cmd - BPMEM_TX_SETIMAGE3),
case BPMEM_TX_SETIMAGE3_4 + 2: fmt::to_string(TexImage3{.hex = cmddata}));
case BPMEM_TX_SETIMAGE3_4 + 3:
{
SetRegName(BPMEM_TX_SETIMAGE3);
int texnum =
(cmd < BPMEM_TX_SETIMAGE3_4) ? cmd - BPMEM_TX_SETIMAGE3 : cmd - BPMEM_TX_SETIMAGE3_4 + 4;
TexImage3 teximg;
teximg.hex = cmddata;
*desc = fmt::format("Texture {} source address (32 byte aligned): 0x{:06X}", texnum,
teximg.image_base << 5);
}
break;
case BPMEM_TX_SETTLUT: // 0x98 case BPMEM_TX_SETTLUT: // 0x98
case BPMEM_TX_SETTLUT + 1: case BPMEM_TX_SETTLUT + 1:
case BPMEM_TX_SETTLUT + 2: case BPMEM_TX_SETTLUT + 2:
case BPMEM_TX_SETTLUT + 3: case BPMEM_TX_SETTLUT + 3:
return std::make_pair(fmt::format("BPMEM_TX_SETTLUT Texture Unit {}", cmd - BPMEM_TX_SETTLUT),
fmt::to_string(TexTLUT{.hex = cmddata}));
case BPMEM_TX_SETMODE0_4: // 0xA0
case BPMEM_TX_SETMODE0_4 + 1:
case BPMEM_TX_SETMODE0_4 + 2:
case BPMEM_TX_SETMODE0_4 + 3:
return std::make_pair(
fmt::format("BPMEM_TX_SETMODE0_4 Texture Unit {}", cmd - BPMEM_TX_SETMODE0_4 + 4),
fmt::to_string(TexMode0{.hex = cmddata}));
case BPMEM_TX_SETMODE1_4: // 0xA4
case BPMEM_TX_SETMODE1_4 + 1:
case BPMEM_TX_SETMODE1_4 + 2:
case BPMEM_TX_SETMODE1_4 + 3:
return std::make_pair(
fmt::format("BPMEM_TX_SETMODE1_4 Texture Unit {}", cmd - BPMEM_TX_SETMODE1_4 + 4),
fmt::to_string(TexMode1{.hex = cmddata}));
case BPMEM_TX_SETIMAGE0_4: // 0xA8
case BPMEM_TX_SETIMAGE0_4 + 1:
case BPMEM_TX_SETIMAGE0_4 + 2:
case BPMEM_TX_SETIMAGE0_4 + 3:
return std::make_pair(
fmt::format("BPMEM_TX_SETIMAGE0_4 Texture Unit {}", cmd - BPMEM_TX_SETIMAGE0_4 + 4),
fmt::to_string(TexImage0{.hex = cmddata}));
case BPMEM_TX_SETIMAGE1_4: // 0xAC
case BPMEM_TX_SETIMAGE1_4 + 1:
case BPMEM_TX_SETIMAGE1_4 + 2:
case BPMEM_TX_SETIMAGE1_4 + 3:
return std::make_pair(
fmt::format("BPMEM_TX_SETIMAGE1_4 Texture Unit {}", cmd - BPMEM_TX_SETIMAGE1_4 + 4),
fmt::to_string(TexImage1{.hex = cmddata}));
case BPMEM_TX_SETIMAGE2_4: // 0xB0
case BPMEM_TX_SETIMAGE2_4 + 1:
case BPMEM_TX_SETIMAGE2_4 + 2:
case BPMEM_TX_SETIMAGE2_4 + 3:
return std::make_pair(
fmt::format("BPMEM_TX_SETIMAGE2_4 Texture Unit {}", cmd - BPMEM_TX_SETIMAGE2_4 + 4),
fmt::to_string(TexImage2{.hex = cmddata}));
case BPMEM_TX_SETIMAGE3_4: // 0xB4
case BPMEM_TX_SETIMAGE3_4 + 1:
case BPMEM_TX_SETIMAGE3_4 + 2:
case BPMEM_TX_SETIMAGE3_4 + 3:
return std::make_pair(
fmt::format("BPMEM_TX_SETIMAGE3_4 Texture Unit {}", cmd - BPMEM_TX_SETIMAGE3_4 + 4),
fmt::to_string(TexImage3{.hex = cmddata}));
case BPMEM_TX_SETTLUT_4: // 0xB8 case BPMEM_TX_SETTLUT_4: // 0xB8
case BPMEM_TX_SETTLUT_4 + 1: case BPMEM_TX_SETTLUT_4 + 1:
case BPMEM_TX_SETTLUT_4 + 2: case BPMEM_TX_SETTLUT_4 + 2:
case BPMEM_TX_SETTLUT_4 + 3: case BPMEM_TX_SETTLUT_4 + 3:
SetRegName(BPMEM_TX_SETTLUT); return std::make_pair(
// TODO: Description fmt::format("BPMEM_TX_SETTLUT_4 Texture Unit {}", cmd - BPMEM_TX_SETTLUT_4 + 4),
break; fmt::to_string(TexTLUT{.hex = cmddata}));
case BPMEM_TEV_COLOR_ENV: // 0xC0 case BPMEM_TEV_COLOR_ENV: // 0xC0
case BPMEM_TEV_COLOR_ENV + 2: case BPMEM_TEV_COLOR_ENV + 2:
case BPMEM_TEV_COLOR_ENV + 4: case BPMEM_TEV_COLOR_ENV + 4:
case BPMEM_TEV_COLOR_ENV + 6:
case BPMEM_TEV_COLOR_ENV + 8: case BPMEM_TEV_COLOR_ENV + 8:
case BPMEM_TEV_COLOR_ENV + 10: case BPMEM_TEV_COLOR_ENV + 10:
case BPMEM_TEV_COLOR_ENV + 12: case BPMEM_TEV_COLOR_ENV + 12:
@ -1258,24 +1176,9 @@ void GetBPRegInfo(const u8* data, std::string* name, std::string* desc)
case BPMEM_TEV_COLOR_ENV + 26: case BPMEM_TEV_COLOR_ENV + 26:
case BPMEM_TEV_COLOR_ENV + 28: case BPMEM_TEV_COLOR_ENV + 28:
case BPMEM_TEV_COLOR_ENV + 30: case BPMEM_TEV_COLOR_ENV + 30:
{ return std::make_pair(
SetRegName(BPMEM_TEV_COLOR_ENV); fmt::format("BPMEM_TEV_COLOR_ENV Tev stage {}", (cmd - BPMEM_TEV_COLOR_ENV) / 2),
TevStageCombiner::ColorCombiner cc; fmt::to_string(TevStageCombiner::ColorCombiner{.hex = cmddata}));
cc.hex = cmddata;
*desc = fmt::format("Tev stage: {}\n"
"a: {}\n"
"b: {}\n"
"c: {}\n"
"d: {}\n"
"Bias: {}\n"
"Op: {}\n"
"Clamp: {}\n"
"Scale factor: {}\n"
"Dest: {}\n",
(data[0] - BPMEM_TEV_COLOR_ENV) / 2, cc.a, cc.b, cc.c, cc.d, cc.bias, cc.op,
no_yes[cc.clamp], cc.scale, cc.dest);
break;
}
case BPMEM_TEV_ALPHA_ENV: // 0xC1 case BPMEM_TEV_ALPHA_ENV: // 0xC1
case BPMEM_TEV_ALPHA_ENV + 2: case BPMEM_TEV_ALPHA_ENV + 2:
@ -1293,99 +1196,65 @@ void GetBPRegInfo(const u8* data, std::string* name, std::string* desc)
case BPMEM_TEV_ALPHA_ENV + 26: case BPMEM_TEV_ALPHA_ENV + 26:
case BPMEM_TEV_ALPHA_ENV + 28: case BPMEM_TEV_ALPHA_ENV + 28:
case BPMEM_TEV_ALPHA_ENV + 30: case BPMEM_TEV_ALPHA_ENV + 30:
{ return std::make_pair(
SetRegName(BPMEM_TEV_ALPHA_ENV); fmt::format("BPMEM_TEV_ALPHA_ENV Tev stage {}", (cmd - BPMEM_TEV_ALPHA_ENV) / 2),
TevStageCombiner::AlphaCombiner ac; fmt::to_string(TevStageCombiner::AlphaCombiner{.hex = cmddata}));
ac.hex = cmddata;
*desc = fmt::format("Tev stage: {}\n"
"a: {}\n"
"b: {}\n"
"c: {}\n"
"d: {}\n"
"Bias: {}\n"
"Op: {}\n"
"Clamp: {}\n"
"Scale factor: {}\n"
"Dest: {}\n"
"Ras sel: {}\n"
"Tex sel: {}\n",
(data[0] - BPMEM_TEV_ALPHA_ENV) / 2, ac.a, ac.b, ac.c, ac.d, ac.bias, ac.op,
no_yes[ac.clamp], ac.scale, ac.dest, ac.rswap.Value(), ac.tswap.Value());
break;
}
case BPMEM_TEV_COLOR_RA: // 0xE0 case BPMEM_TEV_COLOR_RA: // 0xE0
case BPMEM_TEV_COLOR_RA + 2: // 0xE2 case BPMEM_TEV_COLOR_RA + 2: // 0xE2
case BPMEM_TEV_COLOR_RA + 4: // 0xE4 case BPMEM_TEV_COLOR_RA + 4: // 0xE4
case BPMEM_TEV_COLOR_RA + 6: // 0xE6 case BPMEM_TEV_COLOR_RA + 6: // 0xE6
SetRegName(BPMEM_TEV_COLOR_RA); return std::make_pair(
// TODO: Description fmt::format("BPMEM_TEV_COLOR_RA Tev register {}", (cmd - BPMEM_TEV_COLOR_RA) / 2),
break; fmt::to_string(TevReg::RA{.hex = cmddata}));
case BPMEM_TEV_COLOR_BG: // 0xE1 case BPMEM_TEV_COLOR_BG: // 0xE1
case BPMEM_TEV_COLOR_BG + 2: // 0xE3 case BPMEM_TEV_COLOR_BG + 2: // 0xE3
case BPMEM_TEV_COLOR_BG + 4: // 0xE5 case BPMEM_TEV_COLOR_BG + 4: // 0xE5
case BPMEM_TEV_COLOR_BG + 6: // 0xE7 case BPMEM_TEV_COLOR_BG + 6: // 0xE7
SetRegName(BPMEM_TEV_COLOR_BG); return std::make_pair(
// TODO: Description fmt::format("BPMEM_TEV_COLOR_BG Tev register {}", (cmd - BPMEM_TEV_COLOR_BG) / 2),
break; fmt::to_string(TevReg::BG{.hex = cmddata}));
case BPMEM_FOGRANGE: // 0xE8 case BPMEM_FOGRANGE: // 0xE8
return std::make_pair("BPMEM_FOGRANGE Base",
fmt::to_string(FogRangeParams::RangeBase{.hex = cmddata}));
case BPMEM_FOGRANGE + 1: case BPMEM_FOGRANGE + 1:
case BPMEM_FOGRANGE + 2: case BPMEM_FOGRANGE + 2:
case BPMEM_FOGRANGE + 3: case BPMEM_FOGRANGE + 3:
case BPMEM_FOGRANGE + 4: case BPMEM_FOGRANGE + 4:
case BPMEM_FOGRANGE + 5: case BPMEM_FOGRANGE + 5:
SetRegName(BPMEM_FOGRANGE); return std::make_pair(fmt::format("BPMEM_FOGRANGE K element {}", cmd - BPMEM_FOGRANGE),
// TODO: Description fmt::to_string(FogRangeKElement{.HEX = cmddata}));
break;
case BPMEM_FOGPARAM0: // 0xEE case BPMEM_FOGPARAM0: // 0xEE
SetRegName(BPMEM_FOGPARAM0); return std::make_pair(RegName(BPMEM_FOGPARAM0), fmt::to_string(FogParam0{.hex = cmddata}));
// TODO: Description
break;
case BPMEM_FOGBMAGNITUDE: // 0xEF case BPMEM_FOGBMAGNITUDE: // 0xEF
SetRegName(BPMEM_FOGBMAGNITUDE); return DescriptionlessReg(BPMEM_FOGBMAGNITUDE);
// TODO: Description // TODO: Description
break;
case BPMEM_FOGBEXPONENT: // 0xF0 case BPMEM_FOGBEXPONENT: // 0xF0
SetRegName(BPMEM_FOGBEXPONENT); return DescriptionlessReg(BPMEM_FOGBEXPONENT);
// TODO: Description // TODO: Description
break;
case BPMEM_FOGPARAM3: // 0xF1 case BPMEM_FOGPARAM3: // 0xF1
SetRegName(BPMEM_FOGPARAM3); return std::make_pair(RegName(BPMEM_FOGPARAM3), fmt::to_string(FogParam3{.hex = cmddata}));
// TODO: Description
break;
case BPMEM_FOGCOLOR: // 0xF2 case BPMEM_FOGCOLOR: // 0xF2
SetRegName(BPMEM_FOGCOLOR); return std::make_pair(RegName(BPMEM_FOGCOLOR),
// TODO: Description fmt::to_string(FogParams::FogColor{.hex = cmddata}));
break;
case BPMEM_ALPHACOMPARE: // 0xF3 case BPMEM_ALPHACOMPARE: // 0xF3
{ return std::make_pair(RegName(BPMEM_ALPHACOMPARE), fmt::to_string(AlphaTest{.hex = cmddata}));
SetRegName(BPMEM_ALPHACOMPARE);
AlphaTest test;
test.hex = cmddata;
*desc = fmt::format("Test 1: {} (ref: 0x{:02x})\n"
"Test 2: {} (ref: 0x{:02x})\n"
"Logic: {}\n",
test.comp0, test.ref0.Value(), test.comp1, test.ref1.Value(), test.logic);
break;
}
case BPMEM_BIAS: // 0xF4 case BPMEM_BIAS: // 0xF4
SetRegName(BPMEM_BIAS); return DescriptionlessReg(BPMEM_BIAS);
// TODO: Description // TODO: Description
break;
case BPMEM_ZTEX2: // 0xF5 case BPMEM_ZTEX2: // 0xF5
SetRegName(BPMEM_ZTEX2); return std::make_pair(RegName(BPMEM_ZTEX2), fmt::to_string(ZTex2{.hex = cmddata}));
// TODO: Description
break;
case BPMEM_TEV_KSEL: // 0xF6 case BPMEM_TEV_KSEL: // 0xF6
case BPMEM_TEV_KSEL + 1: case BPMEM_TEV_KSEL + 1:
@ -1395,11 +1264,20 @@ void GetBPRegInfo(const u8* data, std::string* name, std::string* desc)
case BPMEM_TEV_KSEL + 5: case BPMEM_TEV_KSEL + 5:
case BPMEM_TEV_KSEL + 6: case BPMEM_TEV_KSEL + 6:
case BPMEM_TEV_KSEL + 7: case BPMEM_TEV_KSEL + 7:
SetRegName(BPMEM_TEV_KSEL); return std::make_pair(fmt::format("BPMEM_TEV_KSEL number {}", cmd - BPMEM_TEV_KSEL),
// TODO: Description fmt::to_string(TevKSel{.hex = cmddata}));
break;
#undef SetRegName case BPMEM_BP_MASK: // 0xFE
return std::make_pair(RegName(BPMEM_BP_MASK),
fmt::format("The next BP command will only update these bits; others "
"will retain their prior values: {:06x}",
cmddata));
default:
return std::make_pair(fmt::format("Unknown BP Reg: {:02x}={:06x}", cmd, cmddata), "");
#undef DescriptionlessReg
#undef RegName
} }
} }