This gets set on most frames, though once the menu is fully open, they stop setting anything other than the color (which is set to black when drawing the transparent parts of the visor. among other things, and then switched back afterwards).
which also persists when you return to the pause menu. (During the HOME menu, the fog color isn't changed to black, but that starts happening again once you're back in the pause menu)
which disables fog and thus avoids the issue entirely.
Change to highlight fog commands in the fifo analyzer
diff --git a/Source/Core/Core/FifoPlayer/FifoPlayer.cpp b/Source/Core/Core/FifoPlayer/FifoPlayer.cpp
index 8f6a54916e..5190a2fca5 100644
--- a/Source/Core/Core/FifoPlayer/FifoPlayer.cpp
+++ b/Source/Core/Core/FifoPlayer/FifoPlayer.cpp
@@ -65,11 +65,15 @@ public:
bool m_start_of_primitives = false;
bool m_end_of_primitives = false;
bool m_efb_copy = false;
+ bool m_fog_command = false;
+ bool m_fog_color_command = false;
// Internal state, copied to above in OnCommand
bool m_was_primitive = false;
bool m_is_primitive = false;
bool m_is_copy = false;
bool m_is_nop = false;
+ bool m_is_fog_command = false;
+ bool m_is_fog_color_command = false;
CPState m_cpmem;
};
@@ -88,17 +92,24 @@ void FifoPlaybackAnalyzer::AnalyzeFrames(FifoDataFile* file,
u32 offset = 0;
u32 part_start = 0;
+ bool has_fog_command = false;
+ bool has_fog_color_command = false;
CPState cpmem;
while (offset < frame.fifoData.size())
{
const u32 cmd_size = OpcodeDecoder::RunCommand(&frame.fifoData[offset],
u32(frame.fifoData.size()) - offset, analyzer);
+ has_fog_command |= analyzer.m_fog_command;
+ has_fog_color_command |= analyzer.m_fog_color_command;
if (analyzer.m_start_of_primitives)
{
// Start of primitive data for an object
- analyzed.AddPart(FramePartType::Commands, part_start, offset, analyzer.m_cpmem);
+ analyzed.AddPart(FramePartType::Commands, part_start, offset, analyzer.m_cpmem,
+ has_fog_command, has_fog_color_command);
+ has_fog_command = false;
+ has_fog_color_command = false;
part_start = offset;
// Copy cpmem now, because end_of_primitives isn't triggered until the first opcode after
// primitive data, and the first opcode might update cpmem
@@ -109,7 +120,10 @@ void FifoPlaybackAnalyzer::AnalyzeFrames(FifoDataFile* file,
if (analyzer.m_end_of_primitives)
{
// End of primitive data for an object, and thus end of the object
- analyzed.AddPart(FramePartType::PrimitiveData, part_start, offset, cpmem);
+ analyzed.AddPart(FramePartType::PrimitiveData, part_start, offset, cpmem, has_fog_command,
+ has_fog_color_command);
+ has_fog_command = false;
+ has_fog_color_command = false;
part_start = offset;
}
@@ -118,7 +132,10 @@ void FifoPlaybackAnalyzer::AnalyzeFrames(FifoDataFile* file,
if (analyzer.m_efb_copy)
{
// We increase the offset beforehand, so that the trigger EFB copy command is included.
- analyzed.AddPart(FramePartType::EFBCopy, part_start, offset, analyzer.m_cpmem);
+ analyzed.AddPart(FramePartType::EFBCopy, part_start, offset, analyzer.m_cpmem,
+ has_fog_command, has_fog_color_command);
+ has_fog_command = false;
+ has_fog_color_command = false;
part_start = offset;
}
}
@@ -133,6 +150,10 @@ void FifoPlaybackAnalyzer::OnBP(u8 command, u32 value)
{
if (command == BPMEM_TRIGGER_EFB_COPY)
m_is_copy = true;
+ if (command >= BPMEM_FOGRANGE && command < BPMEM_FOGCOLOR)
+ m_is_fog_command = true;
+ if (command == BPMEM_FOGCOLOR)
+ m_is_fog_color_command = true;
}
void FifoPlaybackAnalyzer::OnPrimitiveCommand(OpcodeDecoder::Primitive primitive, u8 vat,
@@ -152,6 +173,8 @@ void FifoPlaybackAnalyzer::OnCommand(const u8* data, u32 size)
m_start_of_primitives = false;
m_end_of_primitives = false;
m_efb_copy = false;
+ m_fog_command = m_is_fog_command;
+ m_fog_color_command = m_is_fog_color_command;
if (!m_is_nop)
{
@@ -167,6 +190,8 @@ void FifoPlaybackAnalyzer::OnCommand(const u8* data, u32 size)
m_is_primitive = false;
m_is_copy = false;
m_is_nop = false;
+ m_is_fog_command = false;
+ m_is_fog_color_command = false;
}
} // namespace
diff --git a/Source/Core/Core/FifoPlayer/FifoPlayer.h b/Source/Core/Core/FifoPlayer/FifoPlayer.h
index 62ba207e64..92d72f6428 100644
--- a/Source/Core/Core/FifoPlayer/FifoPlayer.h
+++ b/Source/Core/Core/FifoPlayer/FifoPlayer.h
@@ -67,8 +67,10 @@ enum class FramePartType
struct FramePart
{
- constexpr FramePart(FramePartType type, u32 start, u32 end, const CPState& cpmem)
- : m_type(type), m_start(start), m_end(end), m_cpmem(cpmem)
+ constexpr FramePart(FramePartType type, u32 start, u32 end, const CPState& cpmem,
+ bool has_fog_command, bool has_fog_color_command)
+ : m_type(type), m_start(start), m_end(end), m_cpmem(cpmem),
+ m_has_fog_command(has_fog_command), m_has_fog_color_command(has_fog_color_command)
{
}
@@ -76,17 +78,24 @@ struct FramePart
const u32 m_start;
const u32 m_end;
const CPState m_cpmem;
+ const bool m_has_fog_command;
+ const bool m_has_fog_color_command;
};
struct AnalyzedFrameInfo
{
std::vector<FramePart> parts;
Common::EnumMap<u32, FramePartType::EFBCopy> part_type_counts;
+ bool m_has_fog_command = false;
+ bool m_has_fog_color_command = false;
- void AddPart(FramePartType type, u32 start, u32 end, const CPState& cpmem)
+ void AddPart(FramePartType type, u32 start, u32 end, const CPState& cpmem, bool has_fog_command,
+ bool has_fog_color_command)
{
- parts.emplace_back(type, start, end, cpmem);
+ parts.emplace_back(type, start, end, cpmem, has_fog_command, has_fog_color_command);
part_type_counts[type]++;
+ m_has_fog_command |= has_fog_command;
+ m_has_fog_color_command |= has_fog_color_command;
}
};
diff --git a/Source/Core/DolphinQt/FIFO/FIFOAnalyzer.cpp b/Source/Core/DolphinQt/FIFO/FIFOAnalyzer.cpp
index 2387ecf458..f59c62af4d 100644
--- a/Source/Core/DolphinQt/FIFO/FIFOAnalyzer.cpp
+++ b/Source/Core/DolphinQt/FIFO/FIFOAnalyzer.cpp
@@ -159,8 +159,15 @@ void FIFOAnalyzer::UpdateTree()
const AnalyzedFrameInfo& frame_info = m_fifo_player.GetAnalyzedFrameInfo(frame);
ASSERT(frame_info.parts.size() != 0);
+ if (frame_info.m_has_fog_command)
+ frame_item->setBackground(0, QBrush{Qt::magenta});
+ else if (frame_info.m_has_fog_color_command)
+ frame_item->setBackground(0, QBrush{Qt::green});
+
Common::EnumMap<u32, FramePartType::EFBCopy> part_counts;
u32 part_start = 0;
+ bool part_has_fog = false;
+ bool part_has_fog_color = false;
for (u32 part_nr = 0; part_nr < frame_info.parts.size(); part_nr++)
{
@@ -168,6 +175,8 @@ void FIFOAnalyzer::UpdateTree()
const u32 part_type_nr = part_counts[part.m_type];
part_counts[part.m_type]++;
+ part_has_fog |= part.m_has_fog_command;
+ part_has_fog_color |= part.m_has_fog_color_command;
QTreeWidgetItem* object_item = nullptr;
if (part.m_type == FramePartType::PrimitiveData)
@@ -186,6 +195,14 @@ void FIFOAnalyzer::UpdateTree()
object_item->setData(0, PART_END_ROLE, part_nr);
part_start = part_nr + 1;
+
+ if (part_has_fog)
+ object_item->setBackground(0, QBrush{Qt::magenta});
+ else if (part_has_fog_color)
+ object_item->setBackground(0, QBrush{Qt::green});
+
+ part_has_fog = false;
+ part_has_fog_color = false;
}
}
@@ -244,6 +261,11 @@ public:
.arg(command, 2, 16, QLatin1Char('0'))
.arg(value, 6, 16, QLatin1Char('0'))
.arg(QString::fromStdString(name));
+
+ if (command >= BPMEM_FOGRANGE && command < BPMEM_FOGCOLOR)
+ is_fog = true;
+ if (command == BPMEM_FOGCOLOR)
+ is_fog_color = true;
}
OPCODE_CALLBACK(void OnIndexedLoad(CPArray array, u32 index, u16 address, u8 size))
{
@@ -319,6 +341,8 @@ public:
}
QString text;
+ bool is_fog = false;
+ bool is_fog_color = false;
CPState m_cpmem;
};
} // namespace
@@ -366,13 +390,20 @@ void FIFOAnalyzer::UpdateDetails()
const u32 start_offset = object_offset;
m_object_data_offsets.push_back(start_offset);
+ callback.is_fog = false;
+ callback.is_fog_color = false;
object_offset += OpcodeDecoder::RunCommand(&fifo_frame.fifoData[object_start + start_offset],
object_size - start_offset, callback);
QString new_label =
QStringLiteral("%1: ").arg(object_start + start_offset, 8, 16, QLatin1Char('0')) +
callback.text;
- m_detail_list->addItem(new_label);
+ QListWidgetItem* item = new QListWidgetItem(new_label);
+ if (callback.is_fog)
+ item->setBackground(QBrush{Qt::magenta});
+ else if (callback.is_fog_color)
+ item->setBackground(QBrush{Qt::green});
+ m_detail_list->addItem(item);
}
// Needed to ensure the description updates when changing objects
I'm curious what a fifolog in Docking Bay Access from MayImilae when the issue is not occurring would look like; would it have that same value for "a" or is it something else?