From cf5251331e5e482cdcce17b4540d7f3dd8b98dec Mon Sep 17 00:00:00 2001 From: John Peterson Date: Thu, 2 Oct 2008 22:00:20 +0000 Subject: [PATCH] Added a console window to the LLE plugin to show the current AX status. TODO: Make it automatically get AXLIST_PBADDR. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@750 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Plugins/Plugin_DSP_HLE/Src/Globals.cpp | 2 +- .../Plugin_DSP_LLE/Plugin_DSP_LLE.vcproj | 30 +- Source/Plugins/Plugin_DSP_LLE/Src/Globals.cpp | 8 +- Source/Plugins/Plugin_DSP_LLE/Src/Globals.h | 22 +- .../Plugin_DSP_LLE/Src/Logging/Console.cpp | 179 +++++++++ .../Plugin_DSP_LLE/Src/Logging/Console.h | 8 + .../Plugin_DSP_LLE/Src/Logging/Logging.cpp | 353 ++++++++++++++++++ .../Plugin_DSP_LLE/Src/Logging/Logging.h | 5 + .../Plugin_DSP_LLE/Src/Logging/ReadPBs.cpp | 114 ++++++ .../Src/Logging/UCode_AXStructs.h | 145 +++++++ Source/Plugins/Plugin_DSP_LLE/Src/main.cpp | 66 ++-- 11 files changed, 896 insertions(+), 36 deletions(-) create mode 100644 Source/Plugins/Plugin_DSP_LLE/Src/Logging/Console.cpp create mode 100644 Source/Plugins/Plugin_DSP_LLE/Src/Logging/Console.h create mode 100644 Source/Plugins/Plugin_DSP_LLE/Src/Logging/Logging.cpp create mode 100644 Source/Plugins/Plugin_DSP_LLE/Src/Logging/Logging.h create mode 100644 Source/Plugins/Plugin_DSP_LLE/Src/Logging/ReadPBs.cpp create mode 100644 Source/Plugins/Plugin_DSP_LLE/Src/Logging/UCode_AXStructs.h diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/Globals.cpp b/Source/Plugins/Plugin_DSP_HLE/Src/Globals.cpp index 7db52df79d..f524188eac 100644 --- a/Source/Plugins/Plugin_DSP_HLE/Src/Globals.cpp +++ b/Source/Plugins/Plugin_DSP_HLE/Src/Globals.cpp @@ -10,7 +10,7 @@ void __Log(int, const char *fmt, ...) void DebugLog(const char* _fmt, ...) { -#ifdef _DEBUG +#if defined(_DEBUG) || defined(DEBUGFAST) char Msg[512]; va_list ap; diff --git a/Source/Plugins/Plugin_DSP_LLE/Plugin_DSP_LLE.vcproj b/Source/Plugins/Plugin_DSP_LLE/Plugin_DSP_LLE.vcproj index 83d97d424e..0aff2fc067 100644 --- a/Source/Plugins/Plugin_DSP_LLE/Plugin_DSP_LLE.vcproj +++ b/Source/Plugins/Plugin_DSP_LLE/Plugin_DSP_LLE.vcproj @@ -330,7 +330,7 @@ + + + + + + + + + + + + + + diff --git a/Source/Plugins/Plugin_DSP_LLE/Src/Globals.cpp b/Source/Plugins/Plugin_DSP_LLE/Src/Globals.cpp index 8fb99f7991..4f33b8fb78 100644 --- a/Source/Plugins/Plugin_DSP_LLE/Src/Globals.cpp +++ b/Source/Plugins/Plugin_DSP_LLE/Src/Globals.cpp @@ -21,9 +21,12 @@ #include "Globals.h" +// ======================================================================================= +// This is to verbose, it has to be turned on manually for now +// -------------- void DebugLog(const char* _fmt, ...) { -#ifdef _DEBUG +#if defined(_DEBUG) || defined(DEBUGFAST) /* char Msg[512]; va_list ap; @@ -37,6 +40,7 @@ void DebugLog(const char* _fmt, ...) */ #endif } +// ============= void ErrorLog(const char* _fmt, ...) @@ -53,7 +57,7 @@ void ErrorLog(const char* _fmt, ...) ::MessageBox(NULL, Msg, "Error", MB_OK); #endif - DSP_DebugBreak(); + DSP_DebugBreak(); // NOTICE: we also break the emulation if this happens } diff --git a/Source/Plugins/Plugin_DSP_LLE/Src/Globals.h b/Source/Plugins/Plugin_DSP_LLE/Src/Globals.h index 563b52ba03..62d6c453dd 100644 --- a/Source/Plugins/Plugin_DSP_LLE/Src/Globals.h +++ b/Source/Plugins/Plugin_DSP_LLE/Src/Globals.h @@ -31,21 +31,21 @@ void DSP_DebugBreak(); #ifndef _dbg_assert_ -#ifdef _DEBUG + #if defined(_DEBUG) || defined(DEBUGFAST) -#undef _dbg_assert_ -#undef _dbg_assert_msg_ -#define _dbg_assert_(_a_) if (!(_a_)){DebugBreak();} -#define _dbg_assert_msg_(_a_, _desc_, ...)\ - if (!(_a_)){\ - if (MessageBox(NULL, _desc_, "*** Fatal Error ***", MB_YESNO | MB_ICONERROR) == IDNO){DebugBreak();}} + #undef _dbg_assert_ + #undef _dbg_assert_msg_ + #define _dbg_assert_(_a_) if (!(_a_)){DebugBreak();} + #define _dbg_assert_msg_(_a_, _desc_, ...)\ + if (!(_a_)){\ + if (MessageBox(NULL, _desc_, "*** Fatal Error ***", MB_YESNO | MB_ICONERROR) == IDNO){DebugBreak();}} -#else + #else -#define _dbg_assert_(_a_); -#define _dbg_assert_msg_(_a_, _desc_, ...); + #define _dbg_assert_(_a_); + #define _dbg_assert_msg_(_a_, _desc_, ...); -#endif + #endif #endif typedef unsigned char uint8; diff --git a/Source/Plugins/Plugin_DSP_LLE/Src/Logging/Console.cpp b/Source/Plugins/Plugin_DSP_LLE/Src/Logging/Console.cpp new file mode 100644 index 0000000000..51051a8165 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_LLE/Src/Logging/Console.cpp @@ -0,0 +1,179 @@ +#ifdef _WIN32 + + + +// ======================================================================================= +// Includes +// -------------- +#include +#include +#include + + +// --------------------------------------------------------------------------------------- +// Defines and settings +// -------------- +bool g_consoleEnable = true; +#define DEBUGG +//#define DEBUGG_FILEONLY +//#define DEBUGG_NOFILE +// --------------------------------------------------------------------------------------- + + +// --------------------------------------------------------------------------------------- +// Handles +// -------------- +#ifdef DEBUGG + FILE* __fStdOut = NULL; +#endif +#ifndef DEBUGG_FILEONLY + HANDLE __hStdOut = NULL; +#endif +// ============== + + +// ======================================================================================= +// Width and height is the size of console window, if you specify fname, +// the output will also be writton to this file. The file pointer is automatically closed +// when you close the app +// -------------- +void startConsoleWin(int width, int height, char* fname) +{ +#ifdef DEBUGG + +#ifndef DEBUGG_FILEONLY + AllocConsole(); + + SetConsoleTitle(fname); + __hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); + + COORD co = {width,height}; + SetConsoleScreenBufferSize(__hStdOut, co); + + SMALL_RECT coo = {0,0,(width - 1),70}; // top, left, right, bottom + SetConsoleWindowInfo(__hStdOut, TRUE, &coo); + +#endif +#ifndef DEBUGG_NOFILE + // --------------------------------------------------------------------------------------- + // Write to a file + if(fname) + { + // Edit the log file name + std::string FileEnding = ".log"; + std::string FileName = fname; + std::string FullFilename = (FileName + FileEnding); + __fStdOut = fopen(FullFilename.c_str(), "w"); + } + // ----------------- +#endif + +#endif +} + + +void ClearScreen(); +int wprintf(char *fmt, ...) +{ +#ifdef DEBUGG + char s[4000]; // WARNING: mind this value + va_list argptr; + int cnt; + + va_start(argptr, fmt); + cnt = vsnprintf(s, 3000, fmt, argptr); + va_end(argptr); + + DWORD cCharsWritten; + + // --------------------------------------------------------------------------------------- +#ifndef DEBUGG_FILEONLY + if(__hStdOut) + { + WriteConsole(__hStdOut, s, strlen(s), &cCharsWritten, NULL); + } +#endif +#ifndef DEBUGG_NOFILE + // --------------------------------------------------------------------------------------- + + if(__fStdOut) + fprintf(__fStdOut, s); + // --------------------------------------------------------------------------------------- +#endif + + return(cnt); +#else + return 0; +#endif +} + + +// ======================================================================================= +// Clear screen +// -------------- +void ClearScreen() +{ + if(g_consoleEnable) + { + COORD coordScreen = { 0, 0 }; + DWORD cCharsWritten; + CONSOLE_SCREEN_BUFFER_INFO csbi; + DWORD dwConSize; + + HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); + //HANDLE hConsole = __hStdOut; + + GetConsoleScreenBufferInfo(hConsole, &csbi); + dwConSize = csbi.dwSize.X * csbi.dwSize.Y; + FillConsoleOutputCharacter(hConsole, TEXT(' '), dwConSize, + coordScreen, &cCharsWritten); + GetConsoleScreenBufferInfo(hConsole, &csbi); + FillConsoleOutputAttribute(hConsole, csbi.wAttributes, dwConSize, + coordScreen, &cCharsWritten); + SetConsoleCursorPosition(hConsole, coordScreen); + } +} + + +// ======================================================================================= +// Get console HWND to be able to use MoveWindow() +// -------------- +HWND GetConsoleHwnd(void) +{ + #define MY_BUFSIZE 1024 // Buffer size for console window titles. + HWND hwndFound; // This is what is returned to the caller. + char pszNewWindowTitle[MY_BUFSIZE]; // Contains fabricated + // WindowTitle. + char pszOldWindowTitle[MY_BUFSIZE]; // Contains original + // WindowTitle. + + // Fetch current window title. + + GetConsoleTitle(pszOldWindowTitle, MY_BUFSIZE); + + // Format a "unique" NewWindowTitle. + + wsprintf(pszNewWindowTitle,"%d/%d", + GetTickCount(), + GetCurrentProcessId()); + + // Change current window title. + + SetConsoleTitle(pszNewWindowTitle); + + // Ensure window title has been updated. + + Sleep(40); + + // Look for NewWindowTitle. + + hwndFound = FindWindow(NULL, pszNewWindowTitle); + + // Restore original window title. + + SetConsoleTitle(pszOldWindowTitle); + + return(hwndFound); +} + +#endif \ No newline at end of file diff --git a/Source/Plugins/Plugin_DSP_LLE/Src/Logging/Console.h b/Source/Plugins/Plugin_DSP_LLE/Src/Logging/Console.h new file mode 100644 index 0000000000..0b7577dd78 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_LLE/Src/Logging/Console.h @@ -0,0 +1,8 @@ +#ifdef _WIN32 + +void startConsoleWin(int width, int height, char* fname); +int wprintf(char *fmt, ...); +void ClearScreen(); +HWND GetConsoleHwnd(void); + +#endif \ No newline at end of file diff --git a/Source/Plugins/Plugin_DSP_LLE/Src/Logging/Logging.cpp b/Source/Plugins/Plugin_DSP_LLE/Src/Logging/Logging.cpp new file mode 100644 index 0000000000..85a0b79843 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_LLE/Src/Logging/Logging.cpp @@ -0,0 +1,353 @@ +#ifdef _WIN32 + + +// ======================================================================================= +// Includes +// -------------- +#include +#include +#include // So that we can test if std::string == abc +#include + +#include "Common.h" + +#include "UCode_AXStructs.h" // they are only in a virtual dir called UCodes AX +#include "Console.h" // For wprintf, ClearScreen + +// --------------------------------------------------------------------------------------- +// Declarations +// -------------- +#define NUMBER_OF_PBS 64 // Todo: move this to a logging class + + + +// --------------------------------------------------------------------------------------- +// Externals +// -------------- +extern u32 m_addressPBs; +float ratioFactor; +int globaliSize; +short globalpBuffer; +u32 gLastBlock; +// -------------- + + +// --------------------------------------------------------------------------------------- +// Vectors and other stuff +// -------------- +std::vector gloopPos(64); +std::vector gsampleEnd(64); +std::vector gsamplePos(64); + std::vector gratio(64); + std::vector gratiohi(64); + std::vector gratiolo(64); + std::vector gfrac(64); + std::vector gcoef(64); +// PBSampleRateConverter mixer + std::vector gvolume_left(64); + std::vector gvolume_right(64); + +std::vector gaudioFormat(64); +std::vector glooping(64); +std::vector gsrc_type(64); +std::vector gis_stream(64); + +// loop + std::vector gloop1(64); + std::vector gloop2(64); + std::vector gloop3(64); + std::vector gadloop1(64); + std::vector gadloop2(64); + std::vector gadloop3(64); + +// updates + std::vector gupdates1(64); + std::vector gupdates2(64); + std::vector gupdates3(64); + std::vector gupdates4(64); + std::vector gupdates5(64); + std::vector gupdates_addr(64); + +// other stuff +std::vector Jump(64); // this is 1 or 0 +std::vector musicLength(64); +std::vector< std::vector > vector1(64, std::vector(100,0)); +std::vector numberRunning(64); + +int j = 0; +int k = 0; +__int64 l = 0; +int iupd = 0; +bool iupdonce = false; +std::vector viupd(15); // the length of the update frequency bar +int vectorLength = 15; // the length of the playback history bar and how long +// old blocks are shown + +std::vector vector62(vectorLength); +std::vector vector63(vectorLength); + +int ReadOutPBs(AXParamBlock * _pPBs, int _num); +// =========== + + +// ======================================================================================= +// Main logging function +// -------------- +void Logging() +{ + // --------------------------------------------------------------------------------------- + + + // --------------------------------------------------------------------------------------- + // Control how often the screen is updated + j++; + l++; + if (j>1000000) // TODO: make the update frequency adjustable from the logging window + { + + AXParamBlock PBs[NUMBER_OF_PBS]; + int numberOfPBs = ReadOutPBs(PBs, NUMBER_OF_PBS); + + // ======================================================================================= + // Vector1 is a vector1[64][100] vector + /* + Move all items back like this + 1 to 2 + 2 3 + 3 ... + */ + // ---------------- + for (int i = 0; i < 64; i++) + { + for (int j = 1; j < vectorLength; j++) + { + vector1.at(i).at(j-1) = vector1.at(i).at(j); + } + } + // ================= + + // --------------------------------------------------------------------------------------- + // Enter the latest value + for (int i = 0; i < numberOfPBs; i++) + { + vector1.at(i).at(vectorLength-1) = PBs[i].running; + } + // ----------------- + + + // --------------------------------------------------------------------------------------- + // Count how many blocks we have running now + int jj = 0; + for (int i = 0; i < 64; i++) + { + for (int j = 0; j < vectorLength-1; j++) + { + if (vector1.at(i).at(j) == 1) + { + jj++; + } + numberRunning.at(i) = jj; + } + } + // -------------- + + + // --------------------------------------------------------------------------------------- + // Write the first row + char buffer [1000] = ""; + std::string sbuff; + //sbuff = sbuff + " Nr | | frac ratio | old new \n"; // 5 + sbuff = sbuff + " Nr pos / end lpos | voll volr | isl[pre yn1 yn2] iss | frac ratio[hi lo] | 1 2 3 4 5\n"; + // -------------- + + + // --------------------------------------------------------------------------------------- + // Read out values for all blocks + for (int i = 0; i < numberOfPBs; i++) + { + if (numberRunning.at(i) > 0) + { + // ======================================================================================= + // Write the playback bar + // ------------- + for (int j = 0; j < vectorLength; j++) + { + if(vector1.at(i).at(j) == 0) + { + sbuff = sbuff + " "; + } + else + { + sprintf(buffer, "%c", 177); + sbuff = sbuff + buffer; strcpy(buffer, ""); + } + } + // ============== + + + // ================================================================================================ + int sampleJump; + int loopJump; + //if (PBs[i].running && PBs[i].adpcm_loop_info.yn1 && PBs[i].mixer.volume_left) + if (true) + { + // --------------------------------------------------------------------------------------- + // AXPB base + //int running = pb.running; + gcoef[i] = PBs[i].unknown1; + + sampleJump = ((PBs[i].audio_addr.cur_addr_hi << 16) | PBs[i].audio_addr.cur_addr_lo) - gsamplePos[i]; + loopJump = ((PBs[i].audio_addr.loop_addr_hi << 16) | PBs[i].audio_addr.loop_addr_lo) - gloopPos[i]; + + gloopPos[i] = (PBs[i].audio_addr.loop_addr_hi << 16) | PBs[i].audio_addr.loop_addr_lo; + gsampleEnd[i] = (PBs[i].audio_addr.end_addr_hi << 16) | PBs[i].audio_addr.end_addr_lo; + gsamplePos[i] = (PBs[i].audio_addr.cur_addr_hi << 16) | PBs[i].audio_addr.cur_addr_lo; + + // PBSampleRateConverter src + + gratio[i] = (u32)(((PBs[i].src.ratio_hi << 16) + PBs[i].src.ratio_lo) * ratioFactor); + gratiohi[i] = PBs[i].src.ratio_hi; + gratiolo[i] = PBs[i].src.ratio_lo; + gfrac[i] = PBs[i].src.cur_addr_frac; + + // adpcm_loop_info + gadloop1[i] = PBs[i].adpcm.pred_scale; + gadloop2[i] = PBs[i].adpcm.yn1; + gadloop3[i] = PBs[i].adpcm.yn2; + + gloop1[i] = PBs[i].adpcm_loop_info.pred_scale; + gloop2[i] = PBs[i].adpcm_loop_info.yn1; + gloop3[i] = PBs[i].adpcm_loop_info.yn2; + + // updates + gupdates1[i] = PBs[i].updates.num_updates[0]; + gupdates2[i] = PBs[i].updates.num_updates[1]; + gupdates3[i] = PBs[i].updates.num_updates[2]; + gupdates4[i] = PBs[i].updates.num_updates[3]; + gupdates5[i] = PBs[i].updates.num_updates[4]; + + gupdates_addr[i] = (PBs[i].updates.data_hi << 16) | PBs[i].updates.data_lo; + + gaudioFormat[i] = PBs[i].audio_addr.sample_format; + glooping[i] = PBs[i].audio_addr.looping; + gsrc_type[i] = PBs[i].src_type; + gis_stream[i] = PBs[i].is_stream; + + // mixer + gvolume_left[i] = PBs[i].mixer.volume_left; + gvolume_right[i] = PBs[i].mixer.volume_right; + + // other stuff + Jump[i] = (gfrac[i] >> 16); // This is 1 or 0 + musicLength[i] = gsampleEnd[i] - gloopPos[i]; + } + + // ================================================================================================ + + + + // ======================================================================================= + // PRESETS + // --------------------------------------------------------------------------------------- + /* + /" Nr pos / end lpos | voll volr | isl[pre yn1 yn2] iss | frac ratio[hi lo] | 1 2 3 4 5\n"; + "---------------|00 12341234/12341234 12341234 | 00000 00000 | 0[000 00000 00000] 0 | 00000 00000[0 00000] | + */ + sprintf(buffer,"%c%i %08i/%08i %08i | %05i %05i | %i[%03i %05i %05i] %i | %05i %05i[%i %05i] | %i %i %i %i %i", + 223, i, gsamplePos[i], gsampleEnd[i], gloopPos[i], + gvolume_left[i], gvolume_right[i], + glooping[i], gloop1[i], gloop2[i], gloop3[i], gis_stream[i], + gfrac[i], gratio[i], gratiohi[i], gratiolo[i], + gupdates1[i], gupdates2[i], gupdates3[i], gupdates4[i], gupdates5[i] + ); + // ======================================================================================= + + // write a new line + sbuff = sbuff + buffer; strcpy(buffer, ""); + sbuff = sbuff + "\n"; + + } // end of if (true) + + + } // end of big loop - for (int i = 0; i < numberOfPBs; i++) + + + // ======================================================================================= + // Write global values + sprintf(buffer, "\nParameter blocks span from %08x | to %08x | distance %i %i\n", m_addressPBs, gLastBlock, (gLastBlock-m_addressPBs), (gLastBlock-m_addressPBs) / 192); + sbuff = sbuff + buffer; strcpy(buffer, ""); + // ============== + + + // ======================================================================================= + // Show update frequency + // --------------- + sbuff = sbuff + "\n"; + if(!iupdonce) + { + /* + for (int i = 0; i < 10; i++) + { + viupd.at(i) == 0; + } + */ + viupd.at(0) = 1; + viupd.at(1) = 1; + viupd.at(2) = 1; + iupdonce = true; + } + + for (int i = 0; i < viupd.size(); i++) // 0, 1,..., 9 + { + if (i < viupd.size()-1) + { + viupd.at(viupd.size()-i-1) = viupd.at(viupd.size()-i-2); // move all forward + } + else + { + viupd.at(0) = viupd.at(viupd.size()-1); + } + + // Correction + if (viupd.at(viupd.size()-3) == 1 && viupd.at(viupd.size()-2) == 1 && viupd.at(viupd.size()-1) == 1) + { + viupd.at(0) = 0; + } + if(viupd.at(0) == 0 && viupd.at(1) == 1 && viupd.at(2) == 1 && viupd.at(3) == 0) + { + viupd.at(0) = 1; + } + } + + for (int i = 0; i < viupd.size(); i++) + { + if(viupd.at(i) == 0) + sbuff = sbuff + " "; + else + sbuff = sbuff + "."; + } + // ================ + + + // ======================================================================================= + // Print + // --------------- + ClearScreen(); + wprintf("%s", sbuff.c_str()); + sbuff.clear(); strcpy(buffer, ""); + // --------------- + k=0; + j=0; + // --------------- + } + + // --------------------------------------------------------------------------------------- + +} +// ======================================================================================= + + + + + +#endif \ No newline at end of file diff --git a/Source/Plugins/Plugin_DSP_LLE/Src/Logging/Logging.h b/Source/Plugins/Plugin_DSP_LLE/Src/Logging/Logging.h new file mode 100644 index 0000000000..a8fda99be5 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_LLE/Src/Logging/Logging.h @@ -0,0 +1,5 @@ +#ifdef _WIN32 + +void Logging(); + +#endif \ No newline at end of file diff --git a/Source/Plugins/Plugin_DSP_LLE/Src/Logging/ReadPBs.cpp b/Source/Plugins/Plugin_DSP_LLE/Src/Logging/ReadPBs.cpp new file mode 100644 index 0000000000..acc7af84b8 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_LLE/Src/Logging/ReadPBs.cpp @@ -0,0 +1,114 @@ +#ifdef _WIN32 + +// ======================================================================================= +// Turn on and off logging modes +// -------------- +//#define LOG1 // writes selected parameters only and with more readable formatting +//#define LOG2 // writes all parameters +// ============== + + + +// ======================================================================================= +// Includes +// -------------- +#include "Common.h" +#include "../Globals.h" +#include "CommonTypes.h" // Pluginspecs + +#include "UCode_AXStructs.h" // For the AXParamBlock structure +#include "Console.h" // For wprintf, ClearScreen +// ============== + + +// ======================================================================================= +// TODO: make this automatic +// -------------- +//u32 m_addressPBs = 0x804a1a60; // SSBM (PAL) +//u32 m_addressPBs = 0x802798c0; // Baten +//u32 m_addressPBs = 0x80576d20; // Symphonia +u32 m_addressPBs = 0x80671d00; // Paper Mario +// -------------- +extern u32 gLastBlock; +// ============== + + + +// ======================================================================================= +int m = 0; +int n = 0; +#ifdef LOG2 +bool logall = true; +#else +bool logall = false; +#endif +int ReadOutPBs(AXParamBlock * _pPBs, int _num) +{ + int count = 0; + u32 blockAddr = m_addressPBs; + u32 OldblockAddr = blockAddr; + u32 paraAddr = blockAddr; + int myDifference; + + + // reading and 'halfword' swap + n++; + if (n > 20 && logall) {ClearScreen();} + for (int i = 0; i < _num; i++) + { + // --------------------------------------------------------------------------------------- + // Check if there is something here. + const short * pSrc = (const short *)g_dspInitialize.pGetMemoryPointer(blockAddr); + // ------------- + + if (pSrc != NULL) // only read non-blank blocks + { + // --------------------------------------------------------------------------------------- + // Create a shortcut that let us update struct members + short * pDest = (short *) & _pPBs[i]; + + if (n > 20 && logall) {wprintf("%c%i:", 223, i);} // logging + + // -------------- + // Here we update the PB. We do it by going through all 192 / 2 = 96 u16 values + for (size_t p = 0; p < sizeof(AXParamBlock) / 2; p++) + { + paraAddr += 2; + + if(pSrc != NULL) + { + if (pSrc[p] != 0 && n > 20 && logall) + { + wprintf("%i %04x | ", p, Common::swap16(pSrc[p])); + } + } + + pDest[p] = Common::swap16(pSrc[p]); + + } + + if(n > 20 && logall) {wprintf("\n");} // logging + // -------------- + // Here we update the block address to the starting point of the next PB + blockAddr = (_pPBs[i].next_pb_hi << 16) | _pPBs[i].next_pb_lo; + // -------------- + // save some values + count++; + gLastBlock = paraAddr; // blockAddr + // ============ + } + else + { + break; + } + + } // end of the big loop + if (n > 20) {n = 0;} // for logging + + + // return the number of readed PBs + return count; +} +// ======================================================================================= + +#endif \ No newline at end of file diff --git a/Source/Plugins/Plugin_DSP_LLE/Src/Logging/UCode_AXStructs.h b/Source/Plugins/Plugin_DSP_LLE/Src/Logging/UCode_AXStructs.h new file mode 100644 index 0000000000..aa0fab47cd --- /dev/null +++ b/Source/Plugins/Plugin_DSP_LLE/Src/Logging/UCode_AXStructs.h @@ -0,0 +1,145 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ +#ifdef _WIN32 + + +#ifndef UCODE_AX_STRUCTS +#define UCODE_AX_STRUCTS + +struct PBMixer +{ + u16 volume_left; + u16 unknown; + u16 volume_right; + u16 unknown2; + + u16 unknown3[8]; + u16 unknown4[6]; +}; + +struct PBInitialTimeDelay +{ + u16 unknown[7]; +}; + +// Update data - read these each 1ms subframe and use them! +// It seems that to provide higher time precisions for MIDI events, some games +// use this thing to update the parameter blocks per 1ms sub-block (a block is 5ms). +// Using this data should fix games that are missing MIDI notes. +struct PBUpdates +{ + u16 num_updates[5]; + u16 data_hi; // These point to main RAM. Not sure about the structure of the data. + u16 data_lo; +}; + +struct PBUnknown +{ + s16 unknown[9]; +}; + +struct PBVolumeEnvelope +{ + u16 cur_volume; + s16 cur_volume_delta; +}; + +struct PBUnknown2 +{ + u16 unknown_reserved[3]; +}; + +struct PBAudioAddr +{ + u16 looping; + u16 sample_format; + u16 loop_addr_hi; // Start of loop (this will point to a shared "zero" buffer if one-shot mode is active) + u16 loop_addr_lo; + u16 end_addr_hi; // End of sample (and loop), inclusive + u16 end_addr_lo; + u16 cur_addr_hi; + u16 cur_addr_lo; +}; + +struct PBADPCMInfo +{ + s16 coefs[16]; + u16 unknown; + u16 pred_scale; + s16 yn1; + s16 yn2; +}; + +struct PBSampleRateConverter +{ + u16 ratio_hi; + u16 ratio_lo; + u16 cur_addr_frac; + u16 last_samples[4]; +}; + +struct PBADPCMLoopInfo +{ + u16 pred_scale; + u16 yn1; + u16 yn2; +}; + +struct AXParamBlock +{ + u16 next_pb_hi; + u16 next_pb_lo; + + u16 this_pb_hi; + u16 this_pb_lo; + + u16 src_type; // Type of sample rate converter (2 = none, ?, linear) + u16 unknown1; + + u16 mixer_control; + u16 running; // 1=RUN 0=STOP + u16 is_stream; // 1 = stream, 0 = one shot + + PBMixer mixer; + PBInitialTimeDelay initial_time_delay; + PBUpdates updates; + PBUnknown unknown2; + PBVolumeEnvelope vol_env; + PBUnknown2 unknown3; + PBAudioAddr audio_addr; + PBADPCMInfo adpcm; + PBSampleRateConverter src; + PBADPCMLoopInfo adpcm_loop_info; + u16 unknown_maybe_padding[3]; +}; + +enum { + AUDIOFORMAT_ADPCM = 0, + AUDIOFORMAT_PCM8 = 0x19, + AUDIOFORMAT_PCM16 = 0xA, +}; + +enum { + SRCTYPE_LINEAR = 1, + SRCTYPE_NEAREST = 2, + MIXCONTROL_RAMPING = 8, +}; + + +#endif + +#endif // win32 \ No newline at end of file diff --git a/Source/Plugins/Plugin_DSP_LLE/Src/main.cpp b/Source/Plugins/Plugin_DSP_LLE/Src/main.cpp index 3d871175ac..61470cc75e 100644 --- a/Source/Plugins/Plugin_DSP_LLE/Src/main.cpp +++ b/Source/Plugins/Plugin_DSP_LLE/Src/main.cpp @@ -24,22 +24,24 @@ #include "disassemble.h" #ifdef _WIN32 -#include "DisAsmDlg.h" -#include "DSoundStream.h" + #include "DisAsmDlg.h" + #include "DSoundStream.h" + #include "Logging/Console.h" // For wprintf, ClearScreen + #include "Logging/Logging.h" // For Logging -HINSTANCE g_hInstance = NULL; -HANDLE g_hDSPThread = NULL; -CRITICAL_SECTION g_CriticalSection; -CDisAsmDlg g_Dialog; + HINSTANCE g_hInstance = NULL; + HANDLE g_hDSPThread = NULL; + CRITICAL_SECTION g_CriticalSection; + CDisAsmDlg g_Dialog; #else -#define WINAPI -#define LPVOID void* -#include -#include -#include -#include -#include "AOSoundStream.h" -pthread_t g_hDSPThread = NULL; + #define WINAPI + #define LPVOID void* + #include + #include + #include + #include + #include "AOSoundStream.h" + pthread_t g_hDSPThread = NULL; #endif #include "ChunkFile.h" @@ -105,13 +107,23 @@ void DSP_DoState(unsigned char **ptr, int mode) { void DllDebugger(HWND _hParent) { -#if defined (_DEBUG) && defined (_WIN32) +#if (defined (_DEBUG) || defined (DEBUGFAST)) && defined (_WIN32) g_Dialog.Create(NULL); //_hParent); g_Dialog.ShowWindow(SW_SHOW); -#endif + // Open the console window + startConsoleWin(155, 10000, "Sound Debugging"); // give room for 2000 rows + wprintf("DllDebugger > Console opened\n"); + // TODO: Make this adjustable from the Debugging window + MoveWindow(GetConsoleHwnd(), 0,400, 1280,500, true); + +#endif } + +// ======================================================================================= +// Regular thread +// -------------- #ifdef _WIN32 DWORD WINAPI dsp_thread(LPVOID lpParameter) #else @@ -128,8 +140,12 @@ void* dsp_thread(void* lpParameter) } } } +// ============== +// ======================================================================================= +// Debug thread +// -------------- #ifdef _WIN32 DWORD WINAPI dsp_thread_debug(LPVOID lpParameter) #else @@ -139,11 +155,14 @@ void* dsp_thread_debug(void* lpParameter) //if (g_hDSPThread) //{ - // return NULL; + // return NULL; // enable this to disable the plugin //} -#ifdef _WIN32 +#ifdef _WIN32 + while (1) { + Logging(); // logging + if (g_Dialog.CanDoStep()) { gdsp_runx(1); @@ -156,13 +175,13 @@ void* dsp_thread_debug(void* lpParameter) #endif return NULL; } - +// ============== void DSP_DebugBreak() { #ifdef _WIN32 -#ifdef _DEBUG +#if defined(_DEBUG) || defined(DEBUGFAST) g_Dialog.DebugBreak(); #endif #endif @@ -207,14 +226,19 @@ void DSP_Initialize(DSPInitialize _dspInitialize) if(!bCanWork) return; // TODO: Don't let it work +// --------------------------------------------------------------------------------------- +// First create DSP_UCode.bin by setting "#define DUMP_DSP_IMEM 1" in Globals.h. Then +// make the disassembled file here. +// -------------- /* Dump UCode to file... FILE* t = fopen("e:\\hmm.txt", "wb"); gd_globals_t gdg; gd_dis_file(&gdg, "D:\\DSP_UCode.bin", t); fclose(t); */ +// -------------- #ifdef _WIN32 -#if _DEBUG +#if defined(_DEBUG) || defined(DEBUGFAST) g_hDSPThread = CreateThread(NULL, 0, dsp_thread_debug, 0, 0, NULL); #else g_hDSPThread = CreateThread(NULL, 0, dsp_thread, 0, 0, NULL);