From 700123c55b2319cdc9628b5e62be096647499d36 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Tue, 3 Jan 2012 02:30:37 +0100 Subject: [PATCH 1/6] FifoPlayer: Add an "Analyzer" tab which allows browsing through all rendered objects per frame and through all register setting commands per object --- .../Src/FifoPlayer/FifoPlaybackAnalyzer.cpp | 10 +- .../Core/Core/Src/FifoPlayer/FifoPlayer.cpp | 5 +- Source/Core/Core/Src/FifoPlayer/FifoPlayer.h | 2 + Source/Core/DolphinWX/Src/FifoPlayerDlg.cpp | 218 +++++++++++++++++- Source/Core/DolphinWX/Src/FifoPlayerDlg.h | 11 + 5 files changed, 229 insertions(+), 17 deletions(-) diff --git a/Source/Core/Core/Src/FifoPlayer/FifoPlaybackAnalyzer.cpp b/Source/Core/Core/Src/FifoPlayer/FifoPlaybackAnalyzer.cpp index 4aea2acc98..a8ba627019 100644 --- a/Source/Core/Core/Src/FifoPlayer/FifoPlaybackAnalyzer.cpp +++ b/Source/Core/Core/Src/FifoPlayer/FifoPlaybackAnalyzer.cpp @@ -71,10 +71,10 @@ void FifoPlaybackAnalyzer::AnalyzeFrames(FifoDataFile *file, std::vector prevCmds; - + while (cmdStart < frame.fifoDataSize) { // Add memory updates that have occured before this point in the frame @@ -83,9 +83,9 @@ void FifoPlaybackAnalyzer::AnalyzeFrames(FifoDataFile *file, std::vectorGetFrame(m_CurrentFrame), m_FrameInfo[m_CurrentFrame]); - ++m_CurrentFrame; + WriteFrame(m_File->GetFrame(m_CurrentFrame), m_FrameInfo[m_CurrentFrame]); + + ++m_CurrentFrame; } } } diff --git a/Source/Core/Core/Src/FifoPlayer/FifoPlayer.h b/Source/Core/Core/Src/FifoPlayer/FifoPlayer.h index 486c3c69e4..9db6c0d980 100644 --- a/Source/Core/Core/Src/FifoPlayer/FifoPlayer.h +++ b/Source/Core/Core/Src/FifoPlayer/FifoPlayer.h @@ -44,6 +44,8 @@ public: u32 GetFrameObjectCount(); u32 GetCurrentFrameNum() { return m_CurrentFrame; } + const AnalyzedFrameInfo& GetAnalyzedFrameInfo(u32 frame) { return m_FrameInfo[frame]; } + // Frame range u32 GetFrameRangeStart() { return m_FrameRangeStart; } void SetFrameRangeStart(u32 start); diff --git a/Source/Core/DolphinWX/Src/FifoPlayerDlg.cpp b/Source/Core/DolphinWX/Src/FifoPlayerDlg.cpp index cd863095a1..5a321298a1 100644 --- a/Source/Core/DolphinWX/Src/FifoPlayerDlg.cpp +++ b/Source/Core/DolphinWX/Src/FifoPlayerDlg.cpp @@ -21,6 +21,7 @@ #include "Thread.h" #include "FifoPlayer/FifoPlayer.h" #include "FifoPlayer/FifoRecorder.h" +#include "OpcodeDecoding.h" #include DECLARE_EVENT_TYPE(RECORDING_FINISHED_EVENT, -1) @@ -65,6 +66,10 @@ FifoPlayerDlg::~FifoPlayerDlg() m_FramesToRecordCtrl->Disconnect(wxEVT_COMMAND_SPINCTRL_UPDATED, wxSpinEventHandler(FifoPlayerDlg::OnNumFramesToRecord), NULL, this); m_Close->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FifoPlayerDlg::OnCloseClick), NULL, this); + m_framesList->Disconnect(wxEVT_COMMAND_LISTBOX_SELECTED, wxCommandEventHandler(FifoPlayerDlg::OnFrameListSelectionChanged), NULL, this); + m_objectsList->Disconnect(wxEVT_COMMAND_LISTBOX_SELECTED, wxCommandEventHandler(FifoPlayerDlg::OnObjectListSelectionChanged), NULL, this); + m_objectCmdList->Disconnect(wxEVT_COMMAND_LISTBOX_SELECTED, wxCommandEventHandler(FifoPlayerDlg::OnObjectCmdListSelectionChanged), NULL, this); + FifoPlayer::GetInstance().SetFrameWrittenCallback(NULL); sMutex.lock(); @@ -80,6 +85,8 @@ void FifoPlayerDlg::CreateGUIControls() sMain = new wxBoxSizer(wxVERTICAL); m_Notebook = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0); + + { m_PlayPage = new wxPanel(m_Notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); wxBoxSizer* sPlayPage; sPlayPage = new wxBoxSizer(wxVERTICAL); @@ -151,6 +158,9 @@ void FifoPlayerDlg::CreateGUIControls() m_PlayPage->Layout(); sPlayPage->Fit(m_PlayPage); m_Notebook->AddPage(m_PlayPage, _("Play"), true); + } + + { m_RecordPage = new wxPanel(m_Notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); wxBoxSizer* sRecordPage; sRecordPage = new wxBoxSizer(wxVERTICAL); @@ -199,28 +209,58 @@ void FifoPlayerDlg::CreateGUIControls() m_RecordPage->Layout(); sRecordPage->Fit(m_RecordPage); m_Notebook->AddPage(m_RecordPage, _("Record"), false); + } + + // Analyze page + { + m_AnalyzePage = new wxPanel(m_Notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); + wxBoxSizer* sAnalyzePage; + sAnalyzePage = new wxBoxSizer(wxVERTICAL); + + wxStaticBoxSizer* sTestSizer; + sTestSizer = new wxStaticBoxSizer(new wxStaticBox(m_AnalyzePage, wxID_ANY, _("Frame info")), wxHORIZONTAL); + + m_framesList = new wxListBox(m_AnalyzePage, wxID_ANY); + m_framesList->SetMinSize(wxSize(100, 250)); + sTestSizer->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); + + m_objectCmdList = new wxListBox(m_AnalyzePage, wxID_ANY); + m_objectCmdList->SetMinSize(wxSize(175, 250)); + sTestSizer->Add(m_objectCmdList, 0, wxALL, 5); + + sAnalyzePage->Add(sTestSizer, 0, wxEXPAND, 5); + m_AnalyzePage->SetSizer(sAnalyzePage); + m_AnalyzePage->Layout(); + sAnalyzePage->Fit(m_AnalyzePage); + m_Notebook->AddPage(m_AnalyzePage, _("Analyze"), false); + } + sMain->Add(m_Notebook, 1, wxEXPAND | wxALL, 5); - + wxBoxSizer* sButtons; sButtons = new wxBoxSizer(wxHORIZONTAL); - + wxBoxSizer* sCloseButtonExpander; sCloseButtonExpander = new wxBoxSizer(wxHORIZONTAL); - + sButtons->Add(sCloseButtonExpander, 1, wxEXPAND, 5); - + m_Close = new wxButton(this, wxID_ANY, _("Close"), wxDefaultPosition, wxDefaultSize, 0); sButtons->Add(m_Close, 0, wxALL, 5); - + sMain->Add(sButtons, 0, wxEXPAND, 5); - + SetSizer(sMain); Layout(); sMain->Fit(this); - + Center(wxBOTH); - + // Connect Events Connect(wxEVT_PAINT, wxPaintEventHandler(FifoPlayerDlg::OnPaint)); m_FrameFromCtrl->Connect(wxEVT_COMMAND_SPINCTRL_UPDATED, wxSpinEventHandler(FifoPlayerDlg::OnFrameFrom), NULL, this); @@ -231,7 +271,11 @@ void FifoPlayerDlg::CreateGUIControls() m_RecordStop->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FifoPlayerDlg::OnRecordStop), NULL, this); m_Save->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FifoPlayerDlg::OnSaveFile), NULL, this); m_FramesToRecordCtrl->Connect(wxEVT_COMMAND_SPINCTRL_UPDATED, wxSpinEventHandler(FifoPlayerDlg::OnNumFramesToRecord), NULL, this); - m_Close->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FifoPlayerDlg::OnCloseClick), NULL, this); + Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FifoPlayerDlg::OnCloseClick), NULL, this); + + m_framesList->Connect(wxEVT_COMMAND_LISTBOX_SELECTED, wxCommandEventHandler(FifoPlayerDlg::OnFrameListSelectionChanged), NULL, this); + m_objectsList->Connect(wxEVT_COMMAND_LISTBOX_SELECTED, wxCommandEventHandler(FifoPlayerDlg::OnObjectListSelectionChanged), NULL, this); + m_objectCmdList->Connect(wxEVT_COMMAND_LISTBOX_SELECTED, wxCommandEventHandler(FifoPlayerDlg::OnObjectCmdListSelectionChanged), NULL, this); Connect(RECORDING_FINISHED_EVENT, wxCommandEventHandler(FifoPlayerDlg::OnRecordingFinished), NULL, this); Connect(FRAME_WRITTEN_EVENT, wxCommandEventHandler(FifoPlayerDlg::OnFrameWritten), NULL, this); @@ -243,6 +287,7 @@ void FifoPlayerDlg::OnPaint(wxPaintEvent& event) { UpdatePlayGui(); UpdateRecorderGui(); + UpdateAnalyzerGui(); event.Skip(); } @@ -250,10 +295,11 @@ void FifoPlayerDlg::OnPaint(wxPaintEvent& event) void FifoPlayerDlg::OnFrameFrom(wxSpinEvent& event) { FifoPlayer &player = FifoPlayer::GetInstance(); + player.SetFrameRangeStart(event.GetPosition()); m_FrameFromCtrl->SetValue(player.GetFrameRangeStart()); - m_FrameToCtrl->SetValue(player.GetFrameRangeEnd()); + m_FrameToCtrl->SetValue(player.GetFrameRangeEnd()); } void FifoPlayerDlg::OnFrameTo(wxSpinEvent& event) @@ -326,6 +372,141 @@ void FifoPlayerDlg::OnNumFramesToRecord(wxSpinEvent& event) m_FramesToRecord = -1; } +void FifoPlayerDlg::OnFrameListSelectionChanged(wxCommandEvent& event) +{ + FifoPlayer& player = FifoPlayer::GetInstance(); + + m_objectsList->Clear(); + if (event.GetInt() != -1) + { + int num_objects = player.GetAnalyzedFrameInfo(event.GetInt()).objectStarts.size(); + for (int i = 0; i < num_objects; ++i) + m_objectsList->Append(wxString::Format(wxT("Object %i"), i)); + } + + // Call OnObjectListSelectionChanged + m_objectsList->SetSelection(-1); +} + +void FifoPlayerDlg::OnObjectListSelectionChanged (wxCommandEvent& event) +{ + FifoPlayer& player = FifoPlayer::GetInstance(); + + int frame_idx = m_framesList->GetSelection(); + int object_idx = event.GetInt(); + + m_objectCmdList->Clear(); + if (frame_idx != -1 && object_idx != -1) + { + const AnalyzedFrameInfo& frame = player.GetAnalyzedFrameInfo(frame_idx); + const FifoFrameInfo& fifo_frame = player.GetFile()->GetFrame(frame_idx); + const u8* objectdata_start = &fifo_frame.fifoData[frame.objectStarts[object_idx]]; + const u8* objectdata_end = &fifo_frame.fifoData[frame.objectEnds[object_idx]]; + u8* objectdata = (u8*)objectdata_start; + const int obj_offset = objectdata_start - &fifo_frame.fifoData[frame.objectStarts[0]]; + + int cmd = *objectdata++; + int stream_size = Common::swap16(objectdata); + objectdata += 2; + int vertex_size = (objectdata_end - objectdata) / stream_size; + wxString newLabel = wxString::Format(wxT("%08X: %02X %04X "), obj_offset, cmd, stream_size); + 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 + newLabel += wxString::Format(wxT("%02X"), *objectdata++); + if (((objectdata - (objectdata_start+3)) % vertex_size) == 0) newLabel += wxT(" "); + } + m_objectCmdList->Append(newLabel); + + + // Between objectdata_end and next_objdata_start, there are register setting commands + if (object_idx + 1 < frame.objectStarts.size()) + { + const u8* next_objdata_start = &fifo_frame.fifoData[frame.objectStarts[object_idx+1]]; + while (objectdata < next_objdata_start) + { + int cmd = *objectdata++; + switch (cmd) + { + case GX_NOP: + newLabel = _("NOP"); + break; + + case 0x44: + newLabel = _("0x44"); + break; + + case GX_CMD_INVL_VC: + newLabel = _("GX_CMD_INVL_VC"); + break; + + case GX_LOAD_CP_REG: + { + u32 cmd2 = *objectdata++; + u32 value = Common::swap32(objectdata); + objectdata += 4; + + newLabel = wxString::Format(wxT("CP %02X %08X"), cmd2, value); + } + break; + + case GX_LOAD_XF_REG: + { + u32 cmd2 = Common::swap32(objectdata); + objectdata += 4; + u8 streamSize = ((cmd2 >> 16) & 15) + 1; + + newLabel = wxString::Format(wxT("XF %08X(%02X) ..."), cmd2, streamSize); + + objectdata += streamSize * 4; + } + break; + + case GX_LOAD_INDX_A: + case GX_LOAD_INDX_B: + case GX_LOAD_INDX_C: + case GX_LOAD_INDX_D: + objectdata += 4; + newLabel = wxString::Format(wxT("LOAD INDX %s"), (cmd == GX_LOAD_INDX_A) ? "A" : + (cmd == GX_LOAD_INDX_B) ? "B" : + (cmd == GX_LOAD_INDX_C) ? "C" : "D"); + break; + + case GX_CMD_CALL_DL: + // The recorder should have expanded display lists into the fifo stream and skipped the call to start them + // That is done to make it easier to track where memory is updated + _assert_(false); + objectdata += 8; + newLabel = wxString::Format(wxT("CALL DL")); + break; + + case GX_LOAD_BP_REG: + { + u32 cmd2 = Common::swap32(objectdata); + objectdata += 4; + newLabel = wxString::Format(wxT("BP %02X %06X"), cmd2 >> 24, cmd2 & 0xFFFFFF); + } + break; + + default: + newLabel = _("Unexpected 0x80 call? Aborting..."); + objectdata = (u8*)next_objdata_start; + break; + } + m_objectCmdList->Append(newLabel); + } + } + } + // Call OnObjectCmdListSelectionChanged + m_objectCmdList->SetSelection(-1); +} + +void FifoPlayerDlg::OnObjectCmdListSelectionChanged (wxCommandEvent& event) +{ + +} + void FifoPlayerDlg::OnCloseClick(wxCommandEvent& WXUNUSED(event)) { Hide(); @@ -375,6 +556,23 @@ void FifoPlayerDlg::UpdateRecorderGui() m_Save->Enable(GetSaveButtonEnabled()); } +void FifoPlayerDlg::UpdateAnalyzerGui() +{ + FifoPlayer &player = FifoPlayer::GetInstance(); + FifoDataFile* file = player.GetFile(); + + int num_frames = (file) ? player.GetFile()->GetFrameCount() : 0; + if (m_framesList->GetCount() != num_frames) + { + m_framesList->Clear(); + for (int i = 0; i < num_frames; ++i) + { + m_framesList->Append(wxString::Format(wxT("Frame %i"), i)); + } + m_framesList->SetSelection(-1); + } +} + wxString FifoPlayerDlg::CreateFileFrameCountLabel() const { FifoDataFile *file = FifoPlayer::GetInstance().GetFile(); diff --git a/Source/Core/DolphinWX/Src/FifoPlayerDlg.h b/Source/Core/DolphinWX/Src/FifoPlayerDlg.h index 7ecbef8de3..8bcb5ee29b 100644 --- a/Source/Core/DolphinWX/Src/FifoPlayerDlg.h +++ b/Source/Core/DolphinWX/Src/FifoPlayerDlg.h @@ -47,8 +47,13 @@ private: void OnRecordingFinished(wxCommandEvent& event); void OnFrameWritten(wxCommandEvent& event); + void OnFrameListSelectionChanged(wxCommandEvent& event); + void OnObjectListSelectionChanged(wxCommandEvent& event); + void OnObjectCmdListSelectionChanged(wxCommandEvent& event); + void UpdatePlayGui(); void UpdateRecorderGui(); + void UpdateAnalyzerGui(); wxString CreateFileFrameCountLabel() const; wxString CreateCurrentFrameLabel() const; @@ -89,6 +94,12 @@ private: wxButton* m_Save; wxStaticText* m_FramesToRecordLabel; wxSpinCtrl* m_FramesToRecordCtrl; + + wxPanel* m_AnalyzePage; + wxListBox* m_framesList; + wxListBox* m_objectsList; + wxListBox* m_objectCmdList; + wxButton* m_Close; s32 m_FramesToRecord; From 8c62a56c7167cf93b0ba755fcfda4e7f97924ac8 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Tue, 3 Jan 2012 22:26:54 +0100 Subject: [PATCH 2/6] FifoPlayer: Show full data of XF register loads (Did I do this correctly?) --- Source/Core/DolphinWX/Src/FifoPlayerDlg.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Source/Core/DolphinWX/Src/FifoPlayerDlg.cpp b/Source/Core/DolphinWX/Src/FifoPlayerDlg.cpp index 5a321298a1..89a5144127 100644 --- a/Source/Core/DolphinWX/Src/FifoPlayerDlg.cpp +++ b/Source/Core/DolphinWX/Src/FifoPlayerDlg.cpp @@ -455,11 +455,18 @@ void FifoPlayerDlg::OnObjectListSelectionChanged (wxCommandEvent& event) { u32 cmd2 = Common::swap32(objectdata); objectdata += 4; + u8 streamSize = ((cmd2 >> 16) & 15) + 1; - newLabel = wxString::Format(wxT("XF %08X(%02X) ..."), cmd2, streamSize); + const u8* stream_start = objectdata; + const u8* stream_end = stream_start + streamSize * 4; - objectdata += streamSize * 4; + newLabel = wxString::Format(wxT("XF %08X "), cmd2); + while (objectdata < stream_end) + { + newLabel += wxString::Format(wxT("%02X"), *objectdata++); + if (((objectdata - stream_start) % 4) == 0) newLabel += wxT(" "); + } } break; From 5eb24a51cfa57ad4bbdc6b9ccc77af4a4f2b289e Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Thu, 5 Jan 2012 17:49:46 +0100 Subject: [PATCH 3/6] FifoPlayer: Add a description label for the currently selected object command. Requires adding such descriptions for all BP/CP/XF registers. For now, I added descriptions for EFB copy related BP registers. --- Source/Core/DolphinWX/Src/FifoPlayerDlg.cpp | 61 +++++++++-- Source/Core/DolphinWX/Src/FifoPlayerDlg.h | 3 + Source/Core/VideoCommon/Src/BPMemory.cpp | 110 ++++++++++++++++++++ Source/Core/VideoCommon/Src/BPMemory.h | 2 + 4 files changed, 169 insertions(+), 7 deletions(-) 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 From ecb616f7fff1a3e01452367af9204f0a547d24cd Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Sat, 7 Jan 2012 17:38:00 +0100 Subject: [PATCH 4/6] FifoPlayer: Make sure that we actually display "Yes" if some variable is true... FifoPlayer: More consistency of output (display "0x" in front of hex numbers, write hex numbers in capital letters) --- Source/Core/VideoCommon/Src/BPMemory.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Source/Core/VideoCommon/Src/BPMemory.cpp b/Source/Core/VideoCommon/Src/BPMemory.cpp index 95e801a433..3f21e1acb0 100644 --- a/Source/Core/VideoCommon/Src/BPMemory.cpp +++ b/Source/Core/VideoCommon/Src/BPMemory.cpp @@ -70,7 +70,7 @@ 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" }; + const char* no_yes[2] = { "No", "Yes" }; u32 cmddata = Common::swap32(*(u32*)data) & 0xFFFFFF; switch (data[0]) @@ -111,7 +111,7 @@ void GetBPRegInfo(const u8* data, char* name, size_t name_size, char* desc, size case BPMEM_EFB_ADDR: // 0x4B SetRegName(BPMEM_EFB_ADDR); - snprintf(desc, desc_size, "Target address (32 byte aligned): %06x", cmddata << 5); + snprintf(desc, desc_size, "Target address (32 byte aligned): 0x%06X", cmddata << 5); break; case BPMEM_COPYYSCALE: // 0x4E @@ -121,17 +121,17 @@ void GetBPRegInfo(const u8* data, char* name, size_t name_size, char* desc, size case BPMEM_CLEAR_AR: // 0x4F SetRegName(BPMEM_CLEAR_AR); - snprintf(desc, desc_size, "Alpha: %02X\nRed: %02x", (cmddata&0xFF00)>>8, cmddata&0xFF); + snprintf(desc, desc_size, "Alpha: 0x%02X\nRed: 0x%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); + snprintf(desc, desc_size, "Green: 0x%02X\nBlue: 0x%02X", (cmddata&0xFF00)>>8, cmddata&0xFF); break; case BPMEM_CLEAR_Z: // 0x51 SetRegName(BPMEM_CLEAR_Z); - snprintf(desc, desc_size, "Z value: %06X", cmddata); + snprintf(desc, desc_size, "Z value: 0x%06X", cmddata); break; case BPMEM_TRIGGER_EFB_COPY: // 0x52 @@ -150,16 +150,16 @@ void GetBPRegInfo(const u8* data, char* name, size_t name_size, char* desc, size "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], + no_yes[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], + no_yes[copy.half_scale], + no_yes[copy.scale_invert], + no_yes[copy.clear], copy.frame_to_field, - yes_no[copy.copy_to_xfb], - yes_no[copy.intensity_fmt], - yes_no[copy.auto_conv]); + no_yes[copy.copy_to_xfb], + no_yes[copy.intensity_fmt], + no_yes[copy.auto_conv]); } break; From ad1a4d7ce318232acf2086bc59c44d66d83e6180 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Sat, 21 Jan 2012 13:40:14 +0100 Subject: [PATCH 5/6] FifoPlayer: Add a search function for the analyzer tab. Also some tiny fixes. --- Source/Core/DolphinWX/Src/FifoPlayerDlg.cpp | 252 ++++++++++++++++++-- Source/Core/DolphinWX/Src/FifoPlayerDlg.h | 20 ++ Source/Core/VideoCommon/Src/BPMemory.cpp | 2 +- 3 files changed, 249 insertions(+), 25 deletions(-) diff --git a/Source/Core/DolphinWX/Src/FifoPlayerDlg.cpp b/Source/Core/DolphinWX/Src/FifoPlayerDlg.cpp index 4a6476c58c..dcb0050a49 100644 --- a/Source/Core/DolphinWX/Src/FifoPlayerDlg.cpp +++ b/Source/Core/DolphinWX/Src/FifoPlayerDlg.cpp @@ -37,7 +37,7 @@ wxEvtHandler *volatile FifoPlayerDlg::m_EvtHandler = NULL; FifoPlayerDlg::FifoPlayerDlg(wxWindow * const parent) : wxDialog(parent, wxID_ANY, _("FIFO Player"), wxDefaultPosition, wxDefaultSize), - m_FramesToRecord(1) + m_search_result_idx(0), m_FramesToRecord(1) { CreateGUIControls(); @@ -79,8 +79,6 @@ FifoPlayerDlg::~FifoPlayerDlg() void FifoPlayerDlg::CreateGUIControls() { - SetSizeHints(wxDefaultSize, wxDefaultSize); - wxBoxSizer* sMain; sMain = new wxBoxSizer(wxVERTICAL); @@ -153,7 +151,8 @@ void FifoPlayerDlg::CreateGUIControls() sPlayOptions->Add(m_EarlyMemoryUpdates, 0, wxALL, 5); sPlayPage->Add(sPlayOptions, 0, wxEXPAND, 5); - + sPlayPage->AddStretchSpacer(); + m_PlayPage->SetSizer(sPlayPage); m_PlayPage->Layout(); sPlayPage->Fit(m_PlayPage); @@ -204,7 +203,8 @@ void FifoPlayerDlg::CreateGUIControls() sRecordingOptions->Add(m_FramesToRecordCtrl, 0, wxALL, 5); sRecordPage->Add(sRecordingOptions, 0, wxEXPAND, 5); - + sRecordPage->AddStretchSpacer(); + m_RecordPage->SetSizer(sRecordPage); m_RecordPage->Layout(); sRecordPage->Fit(m_RecordPage); @@ -217,8 +217,8 @@ void FifoPlayerDlg::CreateGUIControls() wxBoxSizer* sAnalyzePage; sAnalyzePage = new wxBoxSizer(wxVERTICAL); - wxStaticBoxSizer* sTestSizer; - sTestSizer = new wxStaticBoxSizer(new wxStaticBox(m_AnalyzePage, wxID_ANY, _("Frame info")), wxVERTICAL); + wxStaticBoxSizer* sFrameInfoSizer; + sFrameInfoSizer = new wxStaticBoxSizer(new wxStaticBox(m_AnalyzePage, wxID_ANY, _("Frame Info")), wxVERTICAL); wxBoxSizer* sListsSizer = new wxBoxSizer(wxHORIZONTAL); @@ -234,13 +234,45 @@ void FifoPlayerDlg::CreateGUIControls() m_objectCmdList->SetMinSize(wxSize(175, 250)); sListsSizer->Add(m_objectCmdList, 0, wxALL, 5); - sTestSizer->Add(sListsSizer, 0, wxALL, 5); + sFrameInfoSizer->Add(sListsSizer, 0, wxALL, 5); m_objectCmdInfo = new wxStaticText(m_AnalyzePage, wxID_ANY, wxString()); - sTestSizer->Add(m_objectCmdInfo, 0, wxALL, 5); + sFrameInfoSizer->Add(m_objectCmdInfo, 0, wxALL, 5); + + sAnalyzePage->Add(sFrameInfoSizer, 0, wxEXPAND, 5); + + wxStaticBoxSizer* sSearchSizer = new wxStaticBoxSizer(new wxStaticBox(m_AnalyzePage, wxID_ANY, _("Search current Object")), wxVERTICAL); + + wxBoxSizer* sSearchField = new wxBoxSizer(wxHORIZONTAL); + + sSearchField->Add(new wxStaticText(m_AnalyzePage, wxID_ANY, _("Search for hex Value:")), 0, wxALIGN_CENTER_VERTICAL, 5); + // TODO: ugh, wxValidator sucks - but we should use it anyway. + m_searchField = new wxTextCtrl(m_AnalyzePage, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER); + m_numResultsText = new wxStaticText(m_AnalyzePage, wxID_ANY, wxEmptyString); + + sSearchField->Add(m_searchField, 0, wxALL, 5); + sSearchField->Add(m_numResultsText, 0, wxALIGN_CENTER_VERTICAL, 5); + + wxBoxSizer* sSearchButtons = new wxBoxSizer(wxHORIZONTAL); + + m_beginSearch = new wxButton(m_AnalyzePage, wxID_ANY, _("Search")); + m_findNext = new wxButton(m_AnalyzePage, wxID_ANY, _("Find next")); + m_findPrevious = new wxButton(m_AnalyzePage, wxID_ANY, _("Find previous")); + + m_beginSearch->Disable(); + m_findNext->Disable(); + m_findPrevious->Disable(); + + sSearchButtons->Add(m_beginSearch, 0, wxALL, 5); + sSearchButtons->Add(m_findNext, 0, wxALL, 5); + sSearchButtons->Add(m_findPrevious, 0, wxALL, 5); + + sSearchSizer->Add(sSearchField, 0, wxEXPAND, 5); + sSearchSizer->Add(sSearchButtons, 0, wxEXPAND, 5); + + sAnalyzePage->Add(sSearchSizer, 0, wxEXPAND, 5); + sAnalyzePage->AddStretchSpacer(); - sAnalyzePage->Add(sTestSizer, 0, wxEXPAND, 5); - m_AnalyzePage->SetSizer(sAnalyzePage); m_AnalyzePage->Layout(); sAnalyzePage->Fit(m_AnalyzePage); @@ -284,6 +316,13 @@ void FifoPlayerDlg::CreateGUIControls() m_objectsList->Connect(wxEVT_COMMAND_LISTBOX_SELECTED, wxCommandEventHandler(FifoPlayerDlg::OnObjectListSelectionChanged), NULL, this); m_objectCmdList->Connect(wxEVT_COMMAND_LISTBOX_SELECTED, wxCommandEventHandler(FifoPlayerDlg::OnObjectCmdListSelectionChanged), NULL, this); + m_beginSearch->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FifoPlayerDlg::OnBeginSearch), NULL, this); + m_findNext->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FifoPlayerDlg::OnFindNextClick), NULL, this); + m_findPrevious->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FifoPlayerDlg::OnFindPreviousClick), NULL, this); + + m_searchField->Connect(wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler(FifoPlayerDlg::OnBeginSearch), NULL, this); + m_searchField->Connect(wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler(FifoPlayerDlg::OnSearchFieldTextChanged), NULL, this); + Connect(RECORDING_FINISHED_EVENT, wxCommandEventHandler(FifoPlayerDlg::OnRecordingFinished), NULL, this); Connect(FRAME_WRITTEN_EVENT, wxCommandEventHandler(FifoPlayerDlg::OnFrameWritten), NULL, this); @@ -379,6 +418,165 @@ void FifoPlayerDlg::OnNumFramesToRecord(wxSpinEvent& event) m_FramesToRecord = -1; } +void FifoPlayerDlg::OnBeginSearch(wxCommandEvent& event) +{ + wxString str_search_val = m_searchField->GetValue(); + + if (m_framesList->GetSelection() == -1) + return; + + // TODO: Limited to even str lengths... + if (str_search_val.Length() && str_search_val.Length() % 2) + { + m_numResultsText->SetLabel(_("Invalid search string (only even string lengths supported)")); + return; + } + + unsigned int val_length = str_search_val.Length() / 2; + u8* search_val = new u8[val_length]; + for (unsigned int i = 0; i < val_length; ++i) + { + wxString char_str = str_search_val.Mid(2*i, 2); + unsigned long val; + if (!char_str.ToULong(&val, 16)) + { + m_numResultsText->SetLabel(_("Invalid search string (couldn't convert to number)")); + delete[] search_val; + return; + } + search_val[i] = (u8)val; + } + search_results.clear(); + + u8* start_ptr; + u8* end_ptr; + + int frame_idx = m_framesList->GetSelection(); + FifoPlayer& player = FifoPlayer::GetInstance(); + const AnalyzedFrameInfo& frame = player.GetAnalyzedFrameInfo(frame_idx); + const FifoFrameInfo& fifo_frame = player.GetFile()->GetFrame(frame_idx); + + // TODO: Support searching through the last object... How do we know were the cmd data ends? + // TODO: Support searching for bit patterns + int obj_idx = m_objectsList->GetSelection(); + if (obj_idx == -1) + { + m_numResultsText->SetLabel(_("Invalid search parameters (no object selected)")); + return; + } + start_ptr = &fifo_frame.fifoData[frame.objectStarts[obj_idx]]; + end_ptr = &fifo_frame.fifoData[frame.objectStarts[obj_idx+1]]; + + for (u8* ptr = start_ptr; ptr < end_ptr-val_length+1; ++ptr) + { + if (memcmp(ptr, search_val, val_length) == 0) + { + SearchResult result; + result.frame_idx = frame_idx; + + int obj_idx = m_objectsList->GetSelection(); + result.obj_idx = obj_idx; + result.cmd_idx = 0; + for (unsigned int cmd_idx = 1; cmd_idx < m_objectCmdOffsets.size(); ++cmd_idx) + { + if (ptr < start_ptr + m_objectCmdOffsets[cmd_idx]) + { + result.cmd_idx = cmd_idx-1; + break; + } + } + search_results.push_back(result); + } + } + delete[] search_val; + + ChangeSearchResult(0); + m_beginSearch->Disable(); + m_findNext->Enable(); + m_findPrevious->Enable(); + m_numResultsText->SetLabel(wxString::Format(_("Found %d results for \'"), search_results.size()) + m_searchField->GetValue() + _("\'")); +} + +void FifoPlayerDlg::OnSearchFieldTextChanged(wxCommandEvent& event) +{ + m_beginSearch->Enable(m_searchField->GetLineLength(0) > 0); + m_findNext->Disable(); + m_findPrevious->Disable(); +} + +void FifoPlayerDlg::OnFindNextClick(wxCommandEvent& event) +{ + int cur_cmd_index = m_objectCmdList->GetSelection(); + if (cur_cmd_index == -1) + { + ChangeSearchResult(0); + return; + } + + for (std::vector::iterator it = search_results.begin(); it != search_results.end(); ++it) + { + if (it->cmd_idx > cur_cmd_index) + { + ChangeSearchResult(it - search_results.begin()); + return; + } + } +} + +void FifoPlayerDlg::OnFindPreviousClick(wxCommandEvent& event) +{ + int cur_cmd_index = m_objectCmdList->GetSelection(); + if (cur_cmd_index == -1) + { + ChangeSearchResult(search_results.size() - 1); + return; + } + + for (std::vector::reverse_iterator it = search_results.rbegin(); it != search_results.rend(); ++it) + { + if (it->cmd_idx < cur_cmd_index) + { + ChangeSearchResult(search_results.size()-1 - (it - search_results.rbegin())); + return; + } + } +} + +void FifoPlayerDlg::ChangeSearchResult(unsigned int result_idx) +{ + if (search_results.size() > result_idx) + { + m_search_result_idx = result_idx; + int prev_frame = m_framesList->GetSelection(); + int prev_obj = m_objectsList->GetSelection(); + int prev_cmd = m_objectCmdList->GetSelection(); + m_framesList->SetSelection(search_results[result_idx].frame_idx); + m_objectsList->SetSelection(search_results[result_idx].obj_idx); + m_objectCmdList->SetSelection(search_results[result_idx].cmd_idx); + + wxCommandEvent ev(wxEVT_COMMAND_LISTBOX_SELECTED); + if (prev_frame != m_framesList->GetSelection()) + { + ev.SetInt(m_framesList->GetSelection()); + OnFrameListSelectionChanged(ev); + } + if (prev_obj != m_objectsList->GetSelection()) + { + ev.SetInt(m_objectsList->GetSelection()); + OnObjectListSelectionChanged(ev); + } + if (prev_cmd != m_objectCmdList->GetSelection()) + { + ev.SetInt(m_objectCmdList->GetSelection()); + OnObjectCmdListSelectionChanged(ev); + } + } + else if (search_results.size()) + { + ChangeSearchResult(search_results.size() - 1); + } +} + void FifoPlayerDlg::OnFrameListSelectionChanged(wxCommandEvent& event) { FifoPlayer& player = FifoPlayer::GetInstance(); @@ -391,8 +589,10 @@ void FifoPlayerDlg::OnFrameListSelectionChanged(wxCommandEvent& event) m_objectsList->Append(wxString::Format(wxT("Object %i"), i)); } - // Call OnObjectListSelectionChanged - m_objectsList->SetSelection(-1); + // Update object list + wxCommandEvent ev = wxCommandEvent(wxEVT_COMMAND_LISTBOX_SELECTED); + ev.SetInt(-1); + OnObjectListSelectionChanged(ev); } void FifoPlayerDlg::OnObjectListSelectionChanged(wxCommandEvent& event) @@ -421,21 +621,20 @@ 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 - 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 - if (object_idx + 1 < frame.objectStarts.size()) + if (object_idx + 1 < (int)frame.objectStarts.size()) { 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 new_offset = objectdata - &fifo_frame.fifoData[frame.objectStarts[0]]; int cmd = *objectdata++; switch (cmd) { @@ -485,9 +684,9 @@ void FifoPlayerDlg::OnObjectListSelectionChanged(wxCommandEvent& event) case GX_LOAD_INDX_C: case GX_LOAD_INDX_D: objectdata += 4; - newLabel = wxString::Format(wxT("LOAD INDX %s"), (cmd == GX_LOAD_INDX_A) ? "A" : - (cmd == GX_LOAD_INDX_B) ? "B" : - (cmd == GX_LOAD_INDX_C) ? "C" : "D"); + newLabel = wxString::Format(wxT("LOAD INDX %s"), (cmd == GX_LOAD_INDX_A) ? _("A") : + (cmd == GX_LOAD_INDX_B) ? _("B") : + (cmd == GX_LOAD_INDX_C) ? _("C") : _("D")); break; case GX_CMD_CALL_DL: @@ -511,12 +710,15 @@ void FifoPlayerDlg::OnObjectListSelectionChanged(wxCommandEvent& event) objectdata = (u8*)next_objdata_start; break; } + newLabel = wxString::Format(_("%08X: "), new_offset) + newLabel; m_objectCmdList->Append(newLabel); } } } - // Call OnObjectCmdListSelectionChanged - m_objectCmdList->SetSelection(-1); + // Update command list + wxCommandEvent ev = wxCommandEvent(wxEVT_COMMAND_LISTBOX_SELECTED); + ev.SetInt(-1); + OnObjectCmdListSelectionChanged(ev); } void FifoPlayerDlg::OnObjectCmdListSelectionChanged(wxCommandEvent& event) @@ -526,7 +728,7 @@ void FifoPlayerDlg::OnObjectCmdListSelectionChanged(wxCommandEvent& event) if (event.GetInt() == -1 || frame_idx == -1 || object_idx == -1) { - m_objectCmdInfo->SetLabel(wxString()); + m_objectCmdInfo->SetLabel(wxEmptyString); return; } @@ -616,14 +818,16 @@ void FifoPlayerDlg::UpdateAnalyzerGui() FifoDataFile* file = player.GetFile(); int num_frames = (file) ? player.GetFile()->GetFrameCount() : 0; - if (m_framesList->GetCount() != num_frames) + if ((int)m_framesList->GetCount() != num_frames) { m_framesList->Clear(); for (int i = 0; i < num_frames; ++i) { m_framesList->Append(wxString::Format(wxT("Frame %i"), i)); } - m_framesList->SetSelection(-1); + wxCommandEvent ev = wxCommandEvent(wxEVT_COMMAND_LISTBOX_SELECTED); + ev.SetInt(-1); + OnFrameListSelectionChanged(ev); } } diff --git a/Source/Core/DolphinWX/Src/FifoPlayerDlg.h b/Source/Core/DolphinWX/Src/FifoPlayerDlg.h index cc9cbdd5e3..4e2c24fdd6 100644 --- a/Source/Core/DolphinWX/Src/FifoPlayerDlg.h +++ b/Source/Core/DolphinWX/Src/FifoPlayerDlg.h @@ -45,6 +45,12 @@ private: void OnNumFramesToRecord( wxSpinEvent& event ); void OnCloseClick( wxCommandEvent& event ); + void OnBeginSearch(wxCommandEvent& event); + void OnFindNextClick(wxCommandEvent& event); + void OnFindPreviousClick(wxCommandEvent& event); + void OnSearchFieldTextChanged(wxCommandEvent& event); + void ChangeSearchResult(unsigned int result_idx); + void OnRecordingFinished(wxCommandEvent& event); void OnFrameWritten(wxCommandEvent& event); @@ -103,6 +109,20 @@ private: std::vector m_objectCmdOffsets; wxStaticText* m_objectCmdInfo; + wxTextCtrl* m_searchField; + wxButton* m_beginSearch; + wxButton* m_findNext; + wxButton* m_findPrevious; + wxStaticText* m_numResultsText; + + struct SearchResult { + int frame_idx; + int obj_idx; + int cmd_idx; + }; + std::vector search_results; + unsigned int m_search_result_idx; + wxButton* m_Close; s32 m_FramesToRecord; diff --git a/Source/Core/VideoCommon/Src/BPMemory.cpp b/Source/Core/VideoCommon/Src/BPMemory.cpp index 3f21e1acb0..43a4facacf 100644 --- a/Source/Core/VideoCommon/Src/BPMemory.cpp +++ b/Source/Core/VideoCommon/Src/BPMemory.cpp @@ -148,7 +148,7 @@ void GetBPRegInfo(const u8* data, char* name, size_t name_size, char* desc, size "Frame to field: 0x%01X\n" "Copy to XFB: %s\n" "Intensity format: %s\n" - "Automatic color conversion: %s\n", + "Automatic color conversion: %s", (copy.clamp0 && copy.clamp1) ? "Top and Bottom" : (copy.clamp0) ? "Top only" : (copy.clamp1) ? "Bottom only" : "None", no_yes[copy.yuv], copy.tp_realFormat(), From 04c2f2382fdd9601e6b80bf22a66ae72919c2342 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Tue, 7 Feb 2012 13:32:21 +0100 Subject: [PATCH 6/6] FifoPlayerDlg: Don't use wxString::fromAscii() --- Source/Core/DolphinWX/Src/FifoPlayerDlg.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Core/DolphinWX/Src/FifoPlayerDlg.cpp b/Source/Core/DolphinWX/Src/FifoPlayerDlg.cpp index dcb0050a49..cb467389ee 100644 --- a/Source/Core/DolphinWX/Src/FifoPlayerDlg.cpp +++ b/Source/Core/DolphinWX/Src/FifoPlayerDlg.cpp @@ -744,10 +744,10 @@ void FifoPlayerDlg::OnObjectCmdListSelectionChanged(wxCommandEvent& event) 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 += (name[0] != '\0') ? wxString(name, *wxConvCurrent) : wxString::Format(_("UNKNOWN_%02X"), *(cmddata+1)); newLabel += wxT(":\n"); if (desc[0] != '\0') - newLabel += wxString::From8BitData(desc); + newLabel += wxString(desc, *wxConvCurrent); else newLabel += _("No description available"); }