diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/Debugger/Debugger.cpp b/Source/Plugins/Plugin_DSP_HLE/Src/Debugger/Debugger.cpp index 7aba8938e0..1d129baebf 100644 --- a/Source/Plugins/Plugin_DSP_HLE/Src/Debugger/Debugger.cpp +++ b/Source/Plugins/Plugin_DSP_HLE/Src/Debugger/Debugger.cpp @@ -26,6 +26,9 @@ // externals extern int gUpdFreq; +extern bool gSSBM; +extern bool gSSBMremedy1; +extern bool gSSBMremedy2; // ======================================================================================= // Declare events @@ -33,6 +36,9 @@ BEGIN_EVENT_TABLE(CDebugger,wxDialog) EVT_CLOSE(CDebugger::OnClose) EVT_BUTTON(ID_UPD,CDebugger::OnUpdate) EVT_CHECKBOX(IDC_CHECK2,CDebugger::ShowHideConsole) + EVT_CHECKBOX(IDC_CHECK3,CDebugger::SSBM) + EVT_CHECKBOX(IDC_CHECK4,CDebugger::SSBMremedy1) + EVT_CHECKBOX(IDC_CHECK5,CDebugger::SSBMremedy2) EVT_RADIOBOX(IDC_RADIO1,CDebugger::ChangeFrequency) END_EVENT_TABLE() // ======================================================================================= @@ -131,7 +137,30 @@ SetTitle(wxT("Sound Debugging")); m_checkSizer->Add(m_Check[1], 0, 0, 5); m_checkSizer->Add(m_Check[2], 0, 0, 5); // ------------------------ + + // settings checkboxes ----------------------------------------------------- + m_Label[1] = new wxStaticBox(this, IDG_LABEL2, wxT("Settings"), + wxDefaultPosition, wxDefaultSize, 0); + wxStaticBoxSizer * m_checkSizer2 = new wxStaticBoxSizer (m_Label[1], wxVERTICAL); + + // checkboxes + m_Check[3] = new wxCheckBox(this, IDC_CHECK3, wxT("SSBM fix"), + wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); + m_Check[3]->SetValue(gSSBM); + m_Check[4] = new wxCheckBox(this, IDC_CHECK4, wxT("SSBM remedy 1"), + wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); + m_Check[4]->SetValue(gSSBMremedy1); + m_Check[5] = new wxCheckBox(this, IDC_CHECK5, wxT("SSBM remedy 2"), + wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); + m_Check[5]->SetValue(gSSBMremedy2); + + m_checkSizer2->Add(m_Check[3], 0, 0, 5); + m_checkSizer2->Add(m_Check[4], 0, 0, 5); + m_checkSizer2->Add(m_Check[5], 0, 0, 5); + // ------------------------ + + // radio boxes ----------------------------------------------------- int m_radioBoxNChoices[2]; @@ -154,12 +183,18 @@ SetTitle(wxT("Sound Debugging")); m_Presets = new wxButton(this, ID_PRESETS, wxT("Presets"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); - sLeft = new wxStaticBoxSizer(wxVERTICAL, this, wxT("Current Status")); + // right buttons + wxBoxSizer* sButtons2; + sButtons2 = new wxBoxSizer(wxVERTICAL); + sButtons2->AddStretchSpacer(1); + sButtons2->Add(m_checkSizer2, 0, 2, 5); + sButtons2->AddStretchSpacer(1); + + // left buttons wxBoxSizer* sButtons; sButtons = new wxBoxSizer(wxVERTICAL); - sButtons->AddStretchSpacer(1); sButtons->Add(m_Upd, 0, 0, 5); @@ -180,13 +215,16 @@ SetTitle(wxT("Sound Debugging")); sButtons->AddStretchSpacer(1); - + // blocks view + sLeft = new wxStaticBoxSizer(wxVERTICAL, this, wxT("Current Status")); sLeft->Add(m_GPRListView, 1, wxEXPAND|wxALL, 5); + // add all stuff to the main container sMain = new wxBoxSizer(wxHORIZONTAL); sMain->Add(sLeft, 1, wxEXPAND|wxALL, 5); sMain->Add(sButtons, 0, wxEXPAND, 0); + sMain->Add(sButtons2, 0, wxEXPAND, 0); this->SetSizer(sMain); sMain->SetSizeHints(this); @@ -208,6 +246,38 @@ void CDebugger::OnUpdate(wxCommandEvent& /*event*/) this->NotifyUpdate(); } + +// ======================================================================================= +// Settings +// -------------- +void CDebugger::SSBM(wxCommandEvent& event) +{ + if(m_Check[3]->IsChecked() == 1) + {gSSBM = true;} + else + {gSSBM = false;} +} + +void CDebugger::SSBMremedy1(wxCommandEvent& event) +{ + if(m_Check[4]->IsChecked() == 1) + {gSSBMremedy1 = true;} + else + {gSSBMremedy1 = false;} +} +void CDebugger::SSBMremedy2(wxCommandEvent& event) +{ + if(m_Check[5]->IsChecked() == 1) + {gSSBMremedy2 = true;} + else + {gSSBMremedy2 = false;} +} +// ======================================================================================= + + +// ======================================================================================= +// Change update frequency +// -------------- void CDebugger::ChangeFrequency(wxCommandEvent& event) { DoChangeFrequency(); @@ -228,7 +298,13 @@ void CDebugger::DoChangeFrequency() gUpdFreq = 30; } } +// ============== + + +// ======================================================================================= +// Show or hide console window +// -------------- void CDebugger::ShowHideConsole(wxCommandEvent& event) { DoShowHideConsole(); @@ -247,6 +323,8 @@ void CDebugger::DoShowHideConsole() CloseConsole(); } } +// ============== + void CDebugger::NotifyUpdate() { diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/Debugger/Debugger.h b/Source/Plugins/Plugin_DSP_HLE/Src/Debugger/Debugger.h index 19541f90bf..7c1370ddb1 100644 --- a/Source/Plugins/Plugin_DSP_HLE/Src/Debugger/Debugger.h +++ b/Source/Plugins/Plugin_DSP_HLE/Src/Debugger/Debugger.h @@ -72,6 +72,9 @@ class CDebugger : public wxDialog void DoShowHideConsole(); void ChangeFrequency(wxCommandEvent& event); void DoChangeFrequency(); + void SSBM(wxCommandEvent& event); + void SSBMremedy1(wxCommandEvent& event); + void SSBMremedy2(wxCommandEvent& event); CPBView* m_GPRListView; @@ -91,11 +94,15 @@ class CDebugger : public wxDialog IDC_CHECK0 = 2000, IDC_CHECK1, IDC_CHECK2, + IDC_CHECK3, + IDC_CHECK4, + IDC_CHECK5, IDC_RADIO0, IDC_RADIO1, IDC_RADIO2, IDC_RADIO3, IDG_LABEL1, + IDG_LABEL2, ID_UPD, ID_SELC, ID_PRESETS, diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/Logging/Logging.cpp b/Source/Plugins/Plugin_DSP_HLE/Src/Logging/Logging.cpp index 1b1cd985e7..c122a9cde5 100644 --- a/Source/Plugins/Plugin_DSP_HLE/Src/Logging/Logging.cpp +++ b/Source/Plugins/Plugin_DSP_HLE/Src/Logging/Logging.cpp @@ -45,7 +45,9 @@ float ratioFactor; // a global to get the ratio factor from MixAdd int gUpdFreq = 5; u32 gLastBlock; - +extern bool gSSBM; +extern bool gSSBMremedy1; +extern bool gSSBMremedy2; // Parameter blocks @@ -96,16 +98,16 @@ bool iupdonce = false; std::vector viupd(15); // the length of the update frequency bar int vectorLengthGUI = 8; // length of playback history bar for the GUI version int vectorLength = 15; // for console version +int vectorLength2 = 100; // for console version // More stuff -std::vector< std::vector > vector1(64, std::vector(100,0)); +// should we worry about the additonal memory these lists require? bool will allocate +// very little memory +std::vector< std::vector > vector1(64, std::vector(vectorLength,0)); +std::vector< std::vector > vector2(64, std::vector(vectorLength2,0)); std::vector numberRunning(64); -std::vector vector62(vectorLength); -std::vector vector63(vectorLength); - - // Classes @@ -114,15 +116,13 @@ extern CDebugger* m_frame; -// I placed this in CUCode_AX because there was some kind of problem to call it otherwise, -// I'm sure it's simple to fix but I couldn't. +// I placed this in CUCode_AX because it needs access to private members of that class. void CUCode_AX::Logging(short* _pBuffer, int _iSize, int a) { AXParamBlock PBs[NUMBER_OF_PBS]; int numberOfPBs = ReadOutPBs(PBs, NUMBER_OF_PBS); - // Control how often the screen is updated j++; @@ -130,8 +130,9 @@ void CUCode_AX::Logging(short* _pBuffer, int _iSize, int a) if (j > (200/gUpdFreq)) { - - // Move all items back - vector1 is a vector1[64][100] vector, I think + // ======================================================================================= + // Move all items back - Vector1 is a vector1[64][100] vector + // -------------- /* Move all items back like this: 1 to 2 @@ -153,6 +154,35 @@ void CUCode_AX::Logging(short* _pBuffer, int _iSize, int a) { vector1.at(i).at(vectorLength-1) = PBs[i].running; } + // ============== + + + // ======================================================================================= + // Have a separate set for which ones to show + // -------------- + /* + Move all items back like this: + 1 to 2 + 2 3 + 3 ... + */ + for (int i = 0; i < 64; i++) + { + for (int j = 1; j < vectorLength2; j++) + { + vector2.at(i).at(j-1) = vector2.at(i).at(j); + } + } + + + // Save the latest value + + for (int i = 0; i < numberOfPBs; i++) + { + vector2.at(i).at(vectorLength2-1) = PBs[i].running; + } + // ============== + // ======================================================================================= // Count how many we have running now @@ -160,9 +190,9 @@ void CUCode_AX::Logging(short* _pBuffer, int _iSize, int a) int jj = 0; for (int i = 0; i < 64; i++) { - for (int j = 0; j < vectorLength-1; j++) + for (int j = 0; j < vectorLength2-1; j++) { - if (vector1.at(i).at(j) == 1) + if (vector2.at(i).at(j) == 1) { jj++; } @@ -344,7 +374,6 @@ void CUCode_AX::Logging(short* _pBuffer, int _iSize, int a) - // ======================================================================================= // Write global values // --------------- @@ -352,6 +381,15 @@ void CUCode_AX::Logging(short* _pBuffer, int _iSize, int a) sbuff = sbuff + buffer; strcpy(buffer, ""); // =============== + + // ======================================================================================= + // Write settings + // --------------- + sprintf(buffer, "\nSettings: SSBM fix %i | SSBM remedy 1 %i | SSBM remedy 2 %i \n", + gSSBM, gSSBMremedy1, gSSBMremedy2); + sbuff = sbuff + buffer; strcpy(buffer, ""); + // =============== + // ======================================================================================= // Show update frequency diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_AX.cpp b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_AX.cpp index 08bd17ff95..34bb872dd8 100644 --- a/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_AX.cpp +++ b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_AX.cpp @@ -27,14 +27,19 @@ #include "UCode_AXStructs.h" #include "UCode_AX.h" + // --------------------------------------------------------------------------------------- // Externals // ----------- extern float ratioFactor; extern u32 gLastBlock; +bool gSSBM = true; // used externally +bool gSSBMremedy1 = true; // used externally +bool gSSBMremedy2 = true; // used externally extern CDebugger* m_frame; // ----------- + CUCode_AX::CUCode_AX(CMailHandler& _rMailHandler, bool wii) : IUCode(_rMailHandler) , m_addressPBs(0xFFFFFFFF) @@ -150,52 +155,82 @@ void CUCode_AX::MixAdd(short* _pBuffer, int _iSize) AXParamBlock& pb = PBs[i]; - - // ======================================================================================= - // Sequenced music fix - This seems to work allright. I'm not sure which detection method cause - // the least side effects, but pred_scale seems to be nice and simple. Please report any side - // effects. - // ------------ - if (!pb.running && pb.adpcm_loop_info.pred_scale) - /* - if (!pb.running && - (pb.updates.num_updates[0] || pb.updates.num_updates[1] || pb.updates.num_updates[2] - || pb.updates.num_updates[3] || pb.updates.num_updates[4]) - ) - */ - { - pb.running = true; - } - // ============= - - - // ======================================================================================= /* - Fix a problem introduced with the SSBM fix - Sometimes when a music stream ended sampleEnd + Fix problems introduced with the SSBM fix - Sometimes when a music stream ended sampleEnd would become extremely high and the game would play random sound data from ARAM resulting in - a strange noise. This should take care of that. However, when you leave the Continue menu there's - some kind of buzing or interference noise in the music. But it goes away, so I guess it's not a - big issue. Please report any side effects. + a strange noise. This should take care of that. - Some games (Monkey Ball 1 and Tales of + Symphonia) also had one odd block with a strange high loopPos and strange num_updates values, + the loopPos limit turns those off also. - Please report any side effects.Please report any + side effects. */ // ------------ const u32 sampleEnd = (pb.audio_addr.end_addr_hi << 16) | pb.audio_addr.end_addr_lo; - if (sampleEnd > 0x10000000) + const u32 loopPos = (pb.audio_addr.loop_addr_hi << 16) | pb.audio_addr.loop_addr_lo; + if ( + sampleEnd > 0x10000000 || loopPos > 0x10000000 + && gSSBMremedy1 + ) { pb.running = 0; // also reset all values if it makes any difference - pb.audio_addr.cur_addr_hi = 0; - pb.audio_addr.cur_addr_lo = 0; - pb.audio_addr.end_addr_hi = 0; - pb.audio_addr.end_addr_lo = 0; - pb.audio_addr.loop_addr_hi = 0; - pb.audio_addr.loop_addr_lo = 0; + pb.audio_addr.cur_addr_hi = 0; pb.audio_addr.cur_addr_lo = 0; + pb.audio_addr.end_addr_hi = 0; pb.audio_addr.end_addr_lo = 0; + pb.audio_addr.loop_addr_hi = 0; pb.audio_addr.loop_addr_lo = 0; pb.audio_addr.looping = 0; pb.adpcm_loop_info.pred_scale = 0; - pb.adpcm_loop_info.yn1 = 0; - pb.adpcm_loop_info.yn2 = 0; + pb.adpcm_loop_info.yn1 = 0; pb.adpcm_loop_info.yn2 = 0; + } + + /* + // the fact that no settings are reset (except running) after a SSBM type music stream has ended + could cause loud garbled sound to be played from several blocks. It could be seen as five or six + simultaneous looping blocks that presumable produced garbled music. My guess is that it was sound + effects that were placed in previous music blocks and mutated into these looping noise machines. + */ + if ( + // detect blocks that have recently been running that we should reset + pb.running == 0 && pb.audio_addr.looping == 1 + + // this prevents us from ruining sequenced music blocks + && !(pb.updates.num_updates[0] || pb.updates.num_updates[1] || pb.updates.num_updates[2] + || pb.updates.num_updates[3] || pb.updates.num_updates[4]) + + && gSSBMremedy2 // let us turn this fix on and off + ) + { + // reset all values, or mostly all + pb.audio_addr.cur_addr_hi = 0; pb.audio_addr.cur_addr_lo = 0; + pb.audio_addr.end_addr_hi = 0; pb.audio_addr.end_addr_lo = 0; + pb.audio_addr.loop_addr_hi = 0; pb.audio_addr.loop_addr_lo = 0; + + pb.audio_addr.looping = 0; + pb.adpcm_loop_info.pred_scale = 0; + pb.adpcm_loop_info.yn1 = 0; pb.adpcm_loop_info.yn2 = 0; + } + + // ============= + + + // ======================================================================================= + /* + // Sequenced music fix - Because SSBM type music did no have its pred_scale (or any other parameter + except running) turned off after a song was stopped a pred_scale check here had the effect of + turning those blocks on immediately after the stopped. Because the pred_scale check caused these + effects I'm trying the num_updates check instead. Please report any side effects. + */ + // ------------ + //if (!pb.running && pb.adpcm_loop_info.pred_scale) + /**/ + if (!pb.running && + (pb.updates.num_updates[0] || pb.updates.num_updates[1] || pb.updates.num_updates[2] + || pb.updates.num_updates[3] || pb.updates.num_updates[4]) + ) + + { + pb.running = 1; } // ============= @@ -204,8 +239,7 @@ void CUCode_AX::MixAdd(short* _pBuffer, int _iSize) // ======================================================================================= // Set initial parameters // ------------ - //constants - const u32 loopPos = (pb.audio_addr.loop_addr_hi << 16) | pb.audio_addr.loop_addr_lo; + //constants const u32 ratio = (u32)(((pb.src.ratio_hi << 16) + pb.src.ratio_lo) * ratioFactor); //variables @@ -236,11 +270,14 @@ void CUCode_AX::MixAdd(short* _pBuffer, int _iSize) // ======================================================================================= - // Games that use looping to play non-looping music streams. SSBM has info in all pb.adpcm_loop_info - // parameters but has pb.audio_addr.looping = 0. If we treat these streams like any other looping - // streams the music works. + // Games that use looping to play non-looping music streams - SSBM has info in all + // pb.adpcm_loop_info parameters but has pb.audio_addr.looping = 0. If we treat these streams + // like any other looping streams the music works. // --------------------------------------------------------------------------------------- - if(pb.adpcm_loop_info.pred_scale || pb.adpcm_loop_info.yn1 || pb.adpcm_loop_info.yn2) + if( + pb.adpcm_loop_info.pred_scale || pb.adpcm_loop_info.yn1 || pb.adpcm_loop_info.yn2 + && gSSBM + ) { pb.audio_addr.looping = 1; } @@ -248,22 +285,18 @@ void CUCode_AX::MixAdd(short* _pBuffer, int _iSize) // ======================================================================================= - // Streaming music and volume - A lot of music in Paper Mario use the exact same settings, namely - // these: + // Streaming music and volume - The streaming music in Paper Mario use these settings: // Base settings // is_stream = 1 // src_type = 0 - // coef (unknown1) = 1 // PBAudioAddr - // audio_addr.looping = 1 (adpcm_loop_info.pred_scale = value, .yn1 = 0, .yn2 = 0) - // However. Some of the ingame music and seemingly randomly some other music incorrectly get - // volume = 0 for both left and right. There's also an issue of a hanging very similar to the Baten - // hanging. The Baten issue fixed itself when the music stream was allowed to play to the end and - // then stop. However, all five music streams that is playing when the gate locks up in Paper Mario - // is loooping streams... I don't know what may be wrong. - // --------------------------------------------------------------------------------------- - // A game that may be used as a comparison is Starfox Assault also has is_stream = 1, but it - // has src_type = 1, coef (unknown1) = 0 and its pb.src.ratio_lo (fraction) != 0 + // audio_addr.looping = 1 (adpcm_loop_info.pred_scale = value, .yn1 = 0, .yn2 = 0) + /* + However. Some of the ingame music and seemingly randomly some other music incorrectly get + volume = 0 for both left and right. This also affects Fire Emblem. But Starfox Assault + that also use is_stream = 1 has no problem wuth the volume, but its settings are somewhat + different, it uses src_type = 1 and pb.src.ratio_lo (fraction) != 0 + */ // ======================================================================================= @@ -620,6 +653,9 @@ int CUCode_AX::ReadOutPBs(AXParamBlock* _pPBs, int _num) for (size_t p = 0; p < sizeof(AXParamBlock) / 2; p++) { pDest[p] = Common::swap16(pSrc[p]); + + // To avoid a performance drop in the Release build I place this in the debug + // build only #if defined(_DEBUG) || defined(DEBUGFAST) gLastBlock = blockAddr + p*2 + 2; // save last block location #endif