diff --git a/Source/Core/DolphinWX/Src/FifoPlayerDlg.cpp b/Source/Core/DolphinWX/Src/FifoPlayerDlg.cpp index 89a5144127..4a6476c58c 100644 --- a/Source/Core/DolphinWX/Src/FifoPlayerDlg.cpp +++ b/Source/Core/DolphinWX/Src/FifoPlayerDlg.cpp @@ -218,19 +218,26 @@ void FifoPlayerDlg::CreateGUIControls() sAnalyzePage = new wxBoxSizer(wxVERTICAL); wxStaticBoxSizer* sTestSizer; - sTestSizer = new wxStaticBoxSizer(new wxStaticBox(m_AnalyzePage, wxID_ANY, _("Frame info")), wxHORIZONTAL); + sTestSizer = new wxStaticBoxSizer(new wxStaticBox(m_AnalyzePage, wxID_ANY, _("Frame info")), wxVERTICAL); + + wxBoxSizer* sListsSizer = new wxBoxSizer(wxHORIZONTAL); m_framesList = new wxListBox(m_AnalyzePage, wxID_ANY); m_framesList->SetMinSize(wxSize(100, 250)); - sTestSizer->Add(m_framesList, 0, wxALL, 5); + sListsSizer->Add(m_framesList, 0, wxALL, 5); m_objectsList = new wxListBox(m_AnalyzePage, wxID_ANY); m_objectsList->SetMinSize(wxSize(110, 250)); - sTestSizer->Add(m_objectsList, 0, wxALL, 5); + sListsSizer->Add(m_objectsList, 0, wxALL, 5); m_objectCmdList = new wxListBox(m_AnalyzePage, wxID_ANY); m_objectCmdList->SetMinSize(wxSize(175, 250)); - sTestSizer->Add(m_objectCmdList, 0, wxALL, 5); + sListsSizer->Add(m_objectCmdList, 0, wxALL, 5); + + sTestSizer->Add(sListsSizer, 0, wxALL, 5); + + m_objectCmdInfo = new wxStaticText(m_AnalyzePage, wxID_ANY, wxString()); + sTestSizer->Add(m_objectCmdInfo, 0, wxALL, 5); sAnalyzePage->Add(sTestSizer, 0, wxEXPAND, 5); @@ -388,7 +395,7 @@ void FifoPlayerDlg::OnFrameListSelectionChanged(wxCommandEvent& event) m_objectsList->SetSelection(-1); } -void FifoPlayerDlg::OnObjectListSelectionChanged (wxCommandEvent& event) +void FifoPlayerDlg::OnObjectListSelectionChanged(wxCommandEvent& event) { FifoPlayer& player = FifoPlayer::GetInstance(); @@ -396,6 +403,7 @@ void FifoPlayerDlg::OnObjectListSelectionChanged (wxCommandEvent& event) int object_idx = event.GetInt(); m_objectCmdList->Clear(); + m_objectCmdOffsets.clear(); if (frame_idx != -1 && object_idx != -1) { const AnalyzedFrameInfo& frame = player.GetAnalyzedFrameInfo(frame_idx); @@ -413,11 +421,12 @@ void FifoPlayerDlg::OnObjectListSelectionChanged (wxCommandEvent& event) if ((objectdata_end - objectdata) % stream_size) newLabel += _("NOTE: Stream size doesn't match actual data length\n"); while (objectdata < objectdata_end) { - // Group bytes by vertex + // Group bytes by vertex - TODO: Won't work.. newLabel += wxString::Format(wxT("%02X"), *objectdata++); if (((objectdata - (objectdata_start+3)) % vertex_size) == 0) newLabel += wxT(" "); } m_objectCmdList->Append(newLabel); + m_objectCmdOffsets.push_back(0); // Between objectdata_end and next_objdata_start, there are register setting commands @@ -426,6 +435,7 @@ void FifoPlayerDlg::OnObjectListSelectionChanged (wxCommandEvent& event) const u8* next_objdata_start = &fifo_frame.fifoData[frame.objectStarts[object_idx+1]]; while (objectdata < next_objdata_start) { + m_objectCmdOffsets.push_back(objectdata - objectdata_start); int cmd = *objectdata++; switch (cmd) { @@ -509,9 +519,46 @@ void FifoPlayerDlg::OnObjectListSelectionChanged (wxCommandEvent& event) m_objectCmdList->SetSelection(-1); } -void FifoPlayerDlg::OnObjectCmdListSelectionChanged (wxCommandEvent& event) +void FifoPlayerDlg::OnObjectCmdListSelectionChanged(wxCommandEvent& event) { + const int frame_idx = m_framesList->GetSelection(); + const int object_idx = m_objectsList->GetSelection(); + if (event.GetInt() == -1 || frame_idx == -1 || object_idx == -1) + { + m_objectCmdInfo->SetLabel(wxString()); + return; + } + + FifoPlayer& player = FifoPlayer::GetInstance(); + const AnalyzedFrameInfo& frame = player.GetAnalyzedFrameInfo(frame_idx); + const FifoFrameInfo& fifo_frame = player.GetFile()->GetFrame(frame_idx); + const u8* cmddata = &fifo_frame.fifoData[frame.objectStarts[object_idx]] + m_objectCmdOffsets[event.GetInt()]; + + // TODO: Not sure whether we should bother translating the descriptions + wxString newLabel; + if (*cmddata == GX_LOAD_BP_REG) + { + char name[64]="\0", desc[512]="\0"; + GetBPRegInfo(cmddata+1, name, sizeof(name), desc, sizeof(desc)); + newLabel = _("BP register "); + newLabel += (name[0] != '\0') ? wxString::From8BitData(name) : wxString::Format(_("UNKNOWN_%02X"), *(cmddata+1)); + newLabel += wxT(":\n"); + if (desc[0] != '\0') + newLabel += wxString::From8BitData(desc); + else + newLabel += _("No description available"); + } + else if (*cmddata == GX_LOAD_CP_REG) + newLabel = _("CP reg"); + else if (*cmddata == GX_LOAD_XF_REG) + newLabel = _("XF reg"); + else + newLabel = _("No description available"); + + m_objectCmdInfo->SetLabel(newLabel); + Layout(); + Fit(); } void FifoPlayerDlg::OnCloseClick(wxCommandEvent& WXUNUSED(event)) diff --git a/Source/Core/DolphinWX/Src/FifoPlayerDlg.h b/Source/Core/DolphinWX/Src/FifoPlayerDlg.h index 8bcb5ee29b..cc9cbdd5e3 100644 --- a/Source/Core/DolphinWX/Src/FifoPlayerDlg.h +++ b/Source/Core/DolphinWX/Src/FifoPlayerDlg.h @@ -18,6 +18,7 @@ #ifndef __FIFO_PLAYER_DLG_h__ #define __FIFO_PLAYER_DLG_h__ +#include #include #include @@ -99,6 +100,8 @@ private: wxListBox* m_framesList; wxListBox* m_objectsList; wxListBox* m_objectCmdList; + std::vector m_objectCmdOffsets; + wxStaticText* m_objectCmdInfo; wxButton* m_Close; diff --git a/Source/Core/VideoCommon/Src/BPMemory.cpp b/Source/Core/VideoCommon/Src/BPMemory.cpp index da09893f35..95e801a433 100644 --- a/Source/Core/VideoCommon/Src/BPMemory.cpp +++ b/Source/Core/VideoCommon/Src/BPMemory.cpp @@ -66,3 +66,113 @@ void BPReload() } } } + + +void GetBPRegInfo(const u8* data, char* name, size_t name_size, char* desc, size_t desc_size) +{ + const char* yes_no[2] = { "Yes", "No" }; + + u32 cmddata = Common::swap32(*(u32*)data) & 0xFFFFFF; + switch (data[0]) + { + // Macro to set the register name and make sure it was written correctly via compile time assertion + #define SetRegName(reg) \ + snprintf(name, name_size, #reg); \ + (void)(reg); + + case BPMEM_DISPLAYCOPYFILER: // 0x01 + // TODO: This is actually the sample pattern used for copies from an antialiased EFB + SetRegName(BPMEM_DISPLAYCOPYFILER); + // TODO: Description + break; + + case 0x02: // 0x02 + case 0x03: // 0x03 + case 0x04: // 0x04 + // TODO: same as BPMEM_DISPLAYCOPYFILER + break; + + case BPMEM_EFB_TL: // 0x49 + { + SetRegName(BPMEM_EFB_TL); + X10Y10 left_top; left_top.hex = cmddata; + snprintf(desc, desc_size, "Left: %d\nTop: %d", left_top.x, left_top.y); + } + break; + + case BPMEM_EFB_BR: // 0x4A + { + // TODO: Misleading name, should be BPMEM_EFB_WH instead + SetRegName(BPMEM_EFB_BR); + X10Y10 width_height; width_height.hex = cmddata; + snprintf(desc, desc_size, "Width: %d\nHeight: %d", width_height.x+1, width_height.y+1); + } + break; + + case BPMEM_EFB_ADDR: // 0x4B + SetRegName(BPMEM_EFB_ADDR); + snprintf(desc, desc_size, "Target address (32 byte aligned): %06x", cmddata << 5); + break; + + case BPMEM_COPYYSCALE: // 0x4E + SetRegName(BPMEM_COPYYSCALE); + snprintf(desc, desc_size, "Scaling factor (XFB copy only): 0x%X (%f or inverted %f)", cmddata, (float)cmddata/256.f, 256.f/(float)cmddata); + break; + + case BPMEM_CLEAR_AR: // 0x4F + SetRegName(BPMEM_CLEAR_AR); + snprintf(desc, desc_size, "Alpha: %02X\nRed: %02x", (cmddata&0xFF00)>>8, cmddata&0xFF); + break; + + case BPMEM_CLEAR_GB: // 0x50 + SetRegName(BPMEM_CLEAR_GB); + snprintf(desc, desc_size, "Green: %02X\nBlue: %02x", (cmddata&0xFF00)>>8, cmddata&0xFF); + break; + + case BPMEM_CLEAR_Z: // 0x51 + SetRegName(BPMEM_CLEAR_Z); + snprintf(desc, desc_size, "Z value: %06X", cmddata); + break; + + case BPMEM_TRIGGER_EFB_COPY: // 0x52 + { + SetRegName(BPMEM_TRIGGER_EFB_COPY); + UPE_Copy copy; copy.Hex = cmddata; + snprintf(desc, desc_size, "Clamping: %s\n" + "Converting from RGB to YUV: %s\n" + "Target pixel format: 0x%X\n" + "Gamma correction: %s\n" + "Mipmap filter: %s\n" + "Vertical scaling: %s\n" + "Clear: %s\n" + "Frame to field: 0x%01X\n" + "Copy to XFB: %s\n" + "Intensity format: %s\n" + "Automatic color conversion: %s\n", + (copy.clamp0 && copy.clamp1) ? "Top and Bottom" : (copy.clamp0) ? "Top only" : (copy.clamp1) ? "Bottom only" : "None", + yes_no[copy.yuv], + copy.tp_realFormat(), + (copy.gamma==0)?"1.0":(copy.gamma==1)?"1.7":(copy.gamma==2)?"2.2":"Invalid value 0x3?", + yes_no[copy.half_scale], + yes_no[copy.scale_invert], + yes_no[copy.clear], + copy.frame_to_field, + yes_no[copy.copy_to_xfb], + yes_no[copy.intensity_fmt], + yes_no[copy.auto_conv]); + } + break; + + case BPMEM_COPYFILTER0: // 0x53 + SetRegName(BPMEM_COPYFILTER0); + // TODO: Description + break; + + case BPMEM_COPYFILTER1: // 0x54 + SetRegName(BPMEM_COPYFILTER1); + // TODO: Description + break; + +#undef SET_REG_NAME + } +} diff --git a/Source/Core/VideoCommon/Src/BPMemory.h b/Source/Core/VideoCommon/Src/BPMemory.h index 1f6f453a77..51f2c0a5b5 100644 --- a/Source/Core/VideoCommon/Src/BPMemory.h +++ b/Source/Core/VideoCommon/Src/BPMemory.h @@ -978,4 +978,6 @@ extern BPMemory bpmem; void LoadBPReg(u32 value0); +void GetBPRegInfo(const u8* data, char* name, size_t name_size, char* desc, size_t desc_size); + #endif // _BPMEMORY_H