Added a console window to the DSP HLE plugin to more easily see the current parameter block status. TODO: add more presets to show different parameters and add more file logging options.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@755 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
John Peterson
2008-10-03 10:59:56 +00:00
parent a8f484a668
commit 2c78946797
15 changed files with 717 additions and 141 deletions

View File

@ -0,0 +1,196 @@
// 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/
// ---------------------------------------------------------------------------------------
// Includes
// --------------------
#include <string>
#include <stdio.h>
#ifdef _WIN32
#include <windows.h>
#endif
// --------------------
// ---------------------------------------------------------------------------------------
// On and off
// --------------------
bool g_consoleEnable = true;
#define DEBUGG
//#define DEBUGG_FILEONLY
//#define DEBUGG_NOFILE
// --------------------
// ---------------------------------------------------------------------------------------
// Create handles
// --------------------
#ifdef DEBUGG
FILE* __fStdOut = NULL;
#endif
#ifndef DEBUGG_FILEONLY
HANDLE __hStdOut = NULL;
#endif
// --------------------
// =======================================================================================
/* Start console window - 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)
{
#if defined(DEBUGG) && defined(_WIN32)
#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
}
// ---------------------------------------------------------------------------------------
// Printf function
int wprintf(char *fmt, ...)
{
#if defined(DEBUGG) && defined(_WIN32)
char s[3000]; // 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
}
void ClearScreen()
{
#if defined(DEBUGG) && defined(_WIN32)
if(g_consoleEnable)
{
COORD coordScreen = { 0, 0 };
DWORD cCharsWritten;
CONSOLE_SCREEN_BUFFER_INFO csbi;
DWORD dwConSize;
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
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);
}
#endif
}
#if defined(DEBUGG) && defined(_WIN32)
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 // win32

View File

@ -0,0 +1,26 @@
// 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/
int wprintf(char *fmt, ...);
void ClearScreen();
void OpenConsole();
void CloseConsole();
#ifdef _WIN32
HWND GetConsoleHwnd(void);
#endif

View File

@ -28,7 +28,7 @@
#include <vector>
#include <string> // so that we can test std::string == abc
#ifdef _WIN32
#include <windows.h>
#include <windows.h>
#endif
#include "../UCodes/UCodes.h"
@ -37,9 +37,15 @@
#include "../Debugger/PBView.h"
#include "../Debugger/Debugger.h"
#include "Console.h" // open and close console, clear console window
// Externals
float ratioFactor; // a global to get the ratio factor from MixAdd
int gUpdFreq = 5;
u32 gLastBlock;
// Parameter blocks
@ -85,14 +91,17 @@ std::vector<u16> gis_stream(64);
int j = 0;
int k = 0;
long int l = 0;
int iupd = 0;
bool iupdonce = false;
std::vector<u16> 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
// More stuff
std::vector< std::vector<int> > vector1(64, std::vector<int>(100,0));
int vectorLength = 8;
std::vector<int> numberRunning(64);
std::vector<u16> vector62(vectorLength);
std::vector<u16> vector63(vectorLength);
@ -118,16 +127,16 @@ void CUCode_AX::Logging(short* _pBuffer, int _iSize, int a)
// Control how often the screen is updated
j++;
l++;
if (j>20)
if (j > (200/gUpdFreq))
{
// Move all items back - vector1 is a vector1[64][100] vector, I think
/*
Move all items back like this:
1 to 2
2 3
3
3 ...
*/
for (int i = 0; i < 64; i++)
{
@ -137,8 +146,6 @@ void CUCode_AX::Logging(short* _pBuffer, int _iSize, int a)
}
}
// Save the latest value
@ -147,37 +154,86 @@ void CUCode_AX::Logging(short* _pBuffer, int _iSize, int a)
vector1.at(i).at(vectorLength-1) = PBs[i].running;
}
// =======================================================================================
// Count how many 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;
}
}
// ==============
// go through all blocks, or only some
// =======================================================================================
// Write header
// --------------
char buffer [1000] = "";
std::string sbuff;
sbuff = sbuff + " Nr pos / end lpos | voll volr | isl[pre yn1 yn2] iss | frac ratio[hi lo] | 1 2 3 4 5\n";
// ==============
// go through all running blocks
for (int i = 0; i < numberOfPBs; i++)
{
//if (PBs[i].running)
//if (PBs[i].running && PBs[i].adpcm_loop_info.yn1 && PBs[i].mixer.volume_left)
if(true)
if (numberRunning.at(i) > 0)
{
// Playback history for the GUI debugger
std::string sbuff;
// Playback history for the GUI debugger --------------------------
if(m_frame)
{
std::string guipr; // gui progress
for (int j = 0; j < vectorLengthGUI; j++)
{
if(vector1.at(i).at(j) == 0)
{
guipr = guipr + "0";
}
else
{
guipr = guipr + "1";
}
}
u32 run = atoi( guipr.c_str());
m_frame->m_GPRListView->m_CachedRegs[1][i] = run;
guipr.clear();
}
// Playback history for the console debugger --------------------------
for (int j = 0; j < vectorLength; j++)
{
if(vector1.at(i).at(j) == 0)
{
sbuff = sbuff + "0";
//strcat(buffer, " ");
sbuff = sbuff + " ";
}
else
{
sbuff = sbuff + "1";
//sprintf(buffer, "%s%c", buffer, 177); // this will add strange letters if buffer has
// not been given any string yet
sprintf(buffer, "%c", 177);
//strcat(buffer, tmpbuff);
//strcpy(buffer, "");
//sprintf(buffer, "%c", 177);
sbuff = sbuff + buffer; strcpy(buffer, "");
}
}
// ---------
u32 run = atoi( sbuff.c_str());
m_frame->m_GPRListView->m_CachedRegs[1][i] = run;
sbuff.clear();
// We could chose to update these only if a block is currently running - Later I'll add options
// to see both the current and the lastets active value.
@ -185,89 +241,178 @@ void CUCode_AX::Logging(short* _pBuffer, int _iSize, int a)
if (true)
{
// AXPB base
gcoef[i] = PBs[i].unknown1;
// AXPB base
gcoef[i] = PBs[i].unknown1;
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
// 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;
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;
// 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;
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];
// 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;
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;
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;
// mixer
gvolume_left[i] = PBs[i].mixer.volume_left;
gvolume_right[i] = PBs[i].mixer.volume_right;
}
// hopefully this is false if we don't have a debugging window and so it doesn't cause a crash
if(m_frame)
{
m_frame->m_GPRListView->m_CachedRegs[2][i] = gsamplePos[i];
m_frame->m_GPRListView->m_CachedRegs[2][i] = gsampleEnd[i];
m_frame->m_GPRListView->m_CachedRegs[3][i] = gloopPos[i];
// hopefully this is false if we don't have a debugging window and so it doesn't cause a crash
if(m_frame)
{
m_frame->m_GPRListView->m_CachedRegs[2][i] = gsamplePos[i];
m_frame->m_GPRListView->m_CachedRegs[2][i] = gsampleEnd[i];
m_frame->m_GPRListView->m_CachedRegs[3][i] = gloopPos[i];
m_frame->m_GPRListView->m_CachedRegs[4][i] = gvolume_left[i];
m_frame->m_GPRListView->m_CachedRegs[5][i] = gvolume_right[i];
m_frame->m_GPRListView->m_CachedRegs[4][i] = gvolume_left[i];
m_frame->m_GPRListView->m_CachedRegs[5][i] = gvolume_right[i];
m_frame->m_GPRListView->m_CachedRegs[6][i] = glooping[i];
m_frame->m_GPRListView->m_CachedRegs[7][i] = gloop1[i];
m_frame->m_GPRListView->m_CachedRegs[8][i] = gloop2[i];
m_frame->m_GPRListView->m_CachedRegs[9][i] = gloop3[i];
m_frame->m_GPRListView->m_CachedRegs[6][i] = glooping[i];
m_frame->m_GPRListView->m_CachedRegs[7][i] = gloop1[i];
m_frame->m_GPRListView->m_CachedRegs[8][i] = gloop2[i];
m_frame->m_GPRListView->m_CachedRegs[9][i] = gloop3[i];
m_frame->m_GPRListView->m_CachedRegs[10][i] = gis_stream[i];
m_frame->m_GPRListView->m_CachedRegs[10][i] = gis_stream[i];
m_frame->m_GPRListView->m_CachedRegs[11][i] = gaudioFormat[i];
m_frame->m_GPRListView->m_CachedRegs[12][i] = gsrc_type[i];
m_frame->m_GPRListView->m_CachedRegs[13][i] = gcoef[i];
m_frame->m_GPRListView->m_CachedRegs[11][i] = gaudioFormat[i];
m_frame->m_GPRListView->m_CachedRegs[12][i] = gsrc_type[i];
m_frame->m_GPRListView->m_CachedRegs[13][i] = gcoef[i];
m_frame->m_GPRListView->m_CachedRegs[14][i] = gfrac[i];
m_frame->m_GPRListView->m_CachedRegs[14][i] = gfrac[i];
m_frame->m_GPRListView->m_CachedRegs[15][i] = gratio[i];
m_frame->m_GPRListView->m_CachedRegs[16][i] = gratiohi[i];
m_frame->m_GPRListView->m_CachedRegs[17][i] = gratiolo[i];
m_frame->m_GPRListView->m_CachedRegs[15][i] = gratio[i];
m_frame->m_GPRListView->m_CachedRegs[16][i] = gratiohi[i];
m_frame->m_GPRListView->m_CachedRegs[17][i] = gratiolo[i];
m_frame->m_GPRListView->m_CachedRegs[18][i] = gupdates1[i];
m_frame->m_GPRListView->m_CachedRegs[19][i] = gupdates2[i];
m_frame->m_GPRListView->m_CachedRegs[20][i] = gupdates3[i];
m_frame->m_GPRListView->m_CachedRegs[21][i] = gupdates4[i];
m_frame->m_GPRListView->m_CachedRegs[22][i] = gupdates5[i];
}
m_frame->m_GPRListView->m_CachedRegs[18][i] = gupdates1[i];
m_frame->m_GPRListView->m_CachedRegs[19][i] = gupdates2[i];
m_frame->m_GPRListView->m_CachedRegs[20][i] = gupdates3[i];
m_frame->m_GPRListView->m_CachedRegs[21][i] = gupdates4[i];
m_frame->m_GPRListView->m_CachedRegs[22][i] = gupdates5[i];
}
} // end of if (PBs[i].running)
// =======================================================================================
// 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]
);
// add new line
sbuff = sbuff + buffer; strcpy(buffer, "");
sbuff = sbuff + "\n";
} // end of if (PBs[i].running)
} // end of big loop - for (int i = 0; i < numberOfPBs; i++)
// =======================================================================================
// Write global values
// ---------------
sprintf(buffer, "\nThe parameter 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();
// we'll always have one to many \n at the end, remove it
//wprintf("%s", sbuff.substr(0, sbuff.length()-1).c_str());
wprintf("%s", sbuff.c_str());
sbuff.clear(); strcpy(buffer, "");
// New values are written so update - DISABLED - It flickered a lot, even worse than a
// console window. I'll add a console window later to show the current status.