* Tracer: added "Log current Frame number" option

* Tracer: added "Log emulator messages" option
* Tracer: added "Log breakpoint hits" option
* Tracer: added "Symbolic tracing" option
* Taseditor: added deselection stretching by Ctrl+clicking in a selected frame
This commit is contained in:
ansstuff 2012-09-22 15:33:31 +00:00
parent 76607d6b02
commit 48a55b2fa2
20 changed files with 470 additions and 220 deletions

View File

@ -543,7 +543,7 @@ void breakpoint()
//if the current instruction is bad, and we are breaking on bad opcodes, then hit the breakpoint
if(dbgstate.badopbreak && (opsize[opcode[0]] == 0))
BreakHit(BREAK_TYPE_STEP, true);
BreakHit(BREAK_TYPE_BADOP, true);
//if we're stepping out, track the nest level
if (dbgstate.stepout) {

View File

@ -17,8 +17,9 @@
#define BT_S 0x40 //break type, sprite mem
#define BREAK_TYPE_STEP -1
#define BREAK_TYPE_CYCLES_EXCEED -2
#define BREAK_TYPE_INSTRUCTIONS_EXCEED -3
#define BREAK_TYPE_BADOP -2
#define BREAK_TYPE_CYCLES_EXCEED -3
#define BREAK_TYPE_INSTRUCTIONS_EXCEED -4
//opbrktype is used to grab the breakpoint type that each instruction will cause.
//WP_X is not used because ALL opcodes will have the execute bit set.

View File

@ -170,7 +170,7 @@ BOOL CALLBACK CheatConsoleCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM l
//setup font
hFont = (HFONT)SendMessage(hwndDlg, WM_GETFONT, 0, 0);
GetObject(hFont, sizeof(LOGFONT), &lf);
strcpy(lf.lfFaceName,"Courier");
strcpy(lf.lfFaceName,"Courier New");
hNewFont = CreateFontIndirect(&lf);
SendDlgItemMessage(hwndDlg,IDC_CHEAT_ADDR,WM_SETFONT,(WPARAM)hNewFont,FALSE);

View File

@ -89,9 +89,8 @@ extern int PPUViewPosX,PPUViewPosY;
extern int MainWindow_wndx, MainWindow_wndy;
extern int MemWatch_wndx, MemWatch_wndy;
extern int Monitor_wndx, Monitor_wndy;
extern bool tracer_lines_tabbing;
extern bool tracer_statuses_to_the_left;
extern int logging_options;
extern int log_lines_option;
extern int Tracer_wndx, Tracer_wndy;
extern int CDLogger_wndx, CDLogger_wndy;
extern int GGConv_wndx, GGConv_wndy;
@ -286,9 +285,8 @@ static CFGSTRUCT fceuconfig[] = {
AC(MemWatch_wndy),
AC(Monitor_wndx),
AC(Monitor_wndy),
AC(tracer_lines_tabbing),
AC(tracer_statuses_to_the_left),
AC(logging_options),
AC(log_lines_option),
AC(Tracer_wndx),
AC(Tracer_wndy),
AC(CDLogger_wndx),

View File

@ -354,6 +354,7 @@ void Disassemble(HWND hWnd, int id, int scrollid, unsigned int addr) {
// ################################## Start of SP CODE ###########################
if (symbDebugEnabled)
loadNameFiles();
// ################################## End of SP CODE ###########################
@ -364,7 +365,7 @@ void Disassemble(HWND hWnd, int id, int scrollid, unsigned int addr) {
//figure out how many lines we can draw
RECT rect;
GetClientRect(hWnd,&rect);
int lines = (rect.bottom-rect.top)/14;
int lines = (rect.bottom-rect.top) / debugSystem->fixedFontHeight;
for (int i = 0; i < lines; i++)
{
@ -405,8 +406,8 @@ void Disassemble(HWND hWnd, int id, int scrollid, unsigned int addr) {
{
sprintf(chr, "%02X UNDEFINED", GetMem(addr++));
strcat(str,chr);
}
else {
} else
{
char* a;
if ((addr+size) > 0x10000) { //should this be 0xFFFF?
while (addr < 0x10000) {
@ -426,7 +427,7 @@ void Disassemble(HWND hWnd, int id, int scrollid, unsigned int addr) {
// ################################## Start of SP CODE ###########################
a = Disassemble(addr,opcode);
a = Disassemble(addr, opcode);
if (symbDebugEnabled)
{
@ -576,7 +577,34 @@ bool inDebugger = false;
//this code enters the debugger when a breakpoint was hit
void FCEUD_DebugBreakpoint(int bp_num)
{
// log the Breakpoint Hit into Trace Logger log if needed
if (logging && (logging_options & LOG_MESSAGES))
{
char str_temp[500];
if (bp_num >= 0)
{
// normal breakpoint
sprintf(str_temp, "Breakpoint %u Hit at $%04X: ", bp_num, X.PC);
strcat(str_temp, BreakToText(bp_num));
//watchpoint[num].condText
OutputLogLine(str_temp);
} else if (bp_num == BREAK_TYPE_BADOP)
{
sprintf(str_temp, "Bad Opcode Breakpoint Hit at $%04X", X.PC);
OutputLogLine(str_temp);
} else if (bp_num == BREAK_TYPE_CYCLES_EXCEED)
{
sprintf(str_temp, "Breakpoint Hit at $%04X: cycles count %lu exceeds %lu", X.PC, (long)(timestampbase + timestamp - total_cycles_base), (long)break_cycles_limit);
OutputLogLine(str_temp);
} else if (bp_num == BREAK_TYPE_INSTRUCTIONS_EXCEED)
{
sprintf(str_temp, "Breakpoint Hit at $%04X: instructions count %lu exceeds %lu", X.PC, (long)total_instructions, (long)break_instructions_limit);
OutputLogLine(str_temp);
}
}
UpdateDebugger();
UpdateOtherDebuggingDialogs(); // Keeps the debugging windows updating smoothly when stepping
if (bp_num >= 0)
{
@ -596,9 +624,10 @@ void FCEUD_DebugBreakpoint(int bp_num)
else if (bp_num == BREAK_TYPE_INSTRUCTIONS_EXCEED)
SendMessage(GetDlgItem(hDebug, IDC_DEBUGGER_VAL_INSTRUCTIONS_COUNT), EM_SETSEL, 0, -1);
}
UpdateOtherDebuggingDialogs(); // Keeps the debugging windows updating smoothly when stepping
void win_debuggerLoop(); // HACK to let user interact with the Debugger while emulator isn't updating
win_debuggerLoop();
// since we unfreezed emulation, reset delta_cycles counter
ResetDebugStatisticsDeltaCounters();
}
@ -755,15 +784,16 @@ void UpdateDebugger()
DebuggerWasUpdated = true;
}
char *BreakToText(unsigned int num) {
static char str[230],chr[8];
char* BreakToText(unsigned int num)
{
static char str[300], chr[8];
sprintf(str, "$%04X", watchpoint[num].address);
if (watchpoint[num].endaddress) {
sprintf(chr, "-$%04X", watchpoint[num].endaddress);
sprintf(chr, "-%04X", watchpoint[num].endaddress);
strcat(str,chr);
}
if (watchpoint[num].flags&WP_E) strcat(str,": E"); else strcat(str,": -");
if (watchpoint[num].flags&WP_E) strcat(str,":E"); else strcat(str,":-");
if (watchpoint[num].flags&BT_P) strcat(str,"P"); else if (watchpoint[num].flags&BT_S) strcat(str,"S"); else strcat(str,"C");
if (watchpoint[num].flags&WP_R) strcat(str,"R"); else strcat(str,"-");
if (watchpoint[num].flags&WP_W) strcat(str,"W"); else strcat(str,"-");
@ -771,10 +801,18 @@ char *BreakToText(unsigned int num) {
if (watchpoint[num].flags&WP_F) strcat(str,"F"); else strcat(str,"-");
// ################################## Start of SP CODE ###########################
if (watchpoint[num].desc)
if (watchpoint[num].desc && strlen(watchpoint[num].desc))
{
strcat(str, " : ");
strcat(str, " ");
strcat(str, watchpoint[num].desc);
strcat(str, " ");
}
if (watchpoint[num].condText && strlen(watchpoint[num].condText))
{
strcat(str, " Condition:");
strcat(str, watchpoint[num].condText);
}
// ################################## End of SP CODE ###########################
@ -1184,7 +1222,7 @@ BOOL CALLBACK IDC_DEBUGGER_DISASSEMBLY_WndProc(HWND hwndDlg, UINT uMsg, WPARAM w
// select the text
CallWindowProc(IDC_DEBUGGER_DISASSEMBLY_oldWndProc, hwndDlg, uMsg, wParam, lParam);
int mouse_y = GET_Y_LPARAM(lParam);
int tmp = mouse_y / 14, tmp2;
int tmp = mouse_y / debugSystem->fixedFontHeight, tmp2;
int i = si.nPos;
while (tmp > 0)
{
@ -1259,8 +1297,7 @@ BOOL CALLBACK DebuggerCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPara
SendDlgItemMessage(hwndDlg,IDC_DEBUGGER_VAL_PC,WM_SETFONT,(WPARAM)debugSystem->hFixedFont,FALSE);
SendDlgItemMessage(hwndDlg,IDC_DEBUGGER_STACK_CONTENTS,WM_SETFONT,(WPARAM)debugSystem->hFixedFont,FALSE);
SendDlgItemMessage(hwndDlg,IDC_DEBUGGER_VAL_PCSEEK,WM_SETFONT,(WPARAM)debugSystem->hFixedFont,FALSE);
//SendDlgItemMessage(hwndDlg,IDC_DEBUGGER_VAL_PPU,WM_SETFONT,(WPARAM)debugSystem->hFixedFont,FALSE);
//SendDlgItemMessage(hwndDlg,IDC_DEBUGGER_VAL_SPR,WM_SETFONT,(WPARAM)debugSystem->hFixedFont,FALSE);
SendDlgItemMessage(hwndDlg,IDC_DEBUGGER_BP_LIST,WM_SETFONT,(WPARAM)debugSystem->hFixedFont,FALSE);
//text limits
SendDlgItemMessage(hwndDlg,IDC_DEBUGGER_VAL_A,EM_SETLIMITTEXT,2,0);
@ -1531,7 +1568,7 @@ BOOL CALLBACK DebuggerCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPara
//mbg merge 7/18/06 changed pausing check
if (FCEUI_EmulationPaused() && (mouse_x > 8) && (mouse_x < 22) && (mouse_y > 10) && (mouse_y < 538))
{
tmp = (mouse_y - 10) / 14;
tmp = (mouse_y - 10) / debugSystem->fixedFontHeight;
// ################################## End of SP CODE ###########################
i = si.nPos;
while (tmp > 0) {
@ -1558,7 +1595,7 @@ BOOL CALLBACK DebuggerCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPara
//mbg merge 7/18/06 changed pausing check
if (FCEUI_EmulationPaused() && (mouse_x > 8) && (mouse_x < 22) && (mouse_y > 10) && (mouse_y < 538))
{
tmp = (mouse_y - 10) / 14;
tmp = (mouse_y - 10) / debugSystem->fixedFontHeight;
i = si.nPos;
while (tmp > 0) {
if ((tmp2=opsize[GetMem(i)]) == 0) tmp2++;
@ -1584,7 +1621,7 @@ BOOL CALLBACK DebuggerCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPara
//mbg merge 7/18/06 changed pausing check
if (FCEUI_EmulationPaused() && (mouse_x > 8) && (mouse_x < 22) && (mouse_y > 10) && (mouse_y < 538))
{
tmp = (mouse_y - 10) / 14;
tmp = (mouse_y - 10) / debugSystem->fixedFontHeight;
i = si.nPos;
while (tmp > 0) {
if ((tmp2=opsize[GetMem(i)]) == 0) tmp2++;
@ -1896,7 +1933,7 @@ DebugSystem* debugSystem;
DebugSystem::DebugSystem()
{
hFixedFont = CreateFont(14, 8, /*Height,Width*/
hFixedFont = CreateFont(FIXED_FONT_HEIGHT, 8, /*Height,Width*/
0,0, /*escapement,orientation*/
FW_REGULAR,FALSE,FALSE,FALSE, /*weight, italic, underline, strikeout*/
ANSI_CHARSET,OUT_DEVICE_PRECIS,CLIP_MASK, /*charset, precision, clipping*/

View File

@ -5,6 +5,9 @@
#include <windows.h>
//#include "debug.h"
// this is default value, but use debugSystem->fixedFontHeight in calculations
#define FIXED_FONT_HEIGHT 14
// TODO: Maybe change breakpoint array to std::vector
// Maximum number of breakpoints supported
#define MAXIMUM_NUMBER_OF_BREAKPOINTS 64
@ -28,6 +31,7 @@ void UpdatePatcher(HWND hwndDlg);
int GetEditHex(HWND hwndDlg, int id);
extern void AddBreakList();
extern char* BreakToText(unsigned int num);
void UpdateDebugger();
void DoDebug(uint8 halt);

View File

@ -196,10 +196,10 @@ int parseLine(char* line, Name* n)
*pos = 0;
// The only requirement for a name of an address is that it's not of size 0
if (*line)
{
if (strlen(line) > NL_MAX_NAME_LEN)
line[NL_MAX_NAME_LEN] = 0;
n->name = (char*)malloc(strlen(line) + 1);
strcpy(n->name, line);
}
@ -216,6 +216,8 @@ int parseLine(char* line, Name* n)
if (*line > 0x0D)
{
if (strlen(line) > NL_MAX_MULTILINE_COMMENT_LEN)
line[NL_MAX_MULTILINE_COMMENT_LEN] = 0;
n->comment = (char*)malloc(strlen(line) + 1);
strcpy(n->comment, line);
}
@ -626,8 +628,7 @@ void decorateAddress(unsigned int addr, char* str)
{
// Search address definition node for a RAM address
n = searchNode(ramBankNames, temp_chr);
}
else
} else
{
// Search address definition node for a ROM address
n = addr >= 0xC000 ? searchNode(lastBankNames, temp_chr) : searchNode(loadedBankNames, temp_chr);

View File

@ -18,7 +18,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <windows.h>
#include <windows.h>
#define NL_MAX_NAME_LEN 50
#define NL_MAX_MULTILINE_COMMENT_LEN 1024
//mbg merge 7/17/06 made struct sane c++
struct Name

View File

@ -1,5 +1,6 @@
#include <stdlib.h>
#include "common.h"
#include "tracer.h"
static HWND logwin = 0;
@ -209,7 +210,7 @@ void AddLogText(const char *text, unsigned int add_newline)
}
// Add a final newline if requested
if(add_newline)
if (add_newline)
{
*msg_iterator = '\r';
msg_iterator++;
@ -220,6 +221,13 @@ void AddLogText(const char *text, unsigned int add_newline)
// Terminating 0-byte
*msg_iterator = 0;
// also log the text into Trace Logger log if needed
if (logging && (logging_options & LOG_MESSAGES))
{
OutputLogLine(strdup(logtext[truncated_logcount()]), add_newline);
log_old_emu_paused = false; // force Trace Logger update
}
// Keep track of the added log
logcount++;

View File

@ -200,7 +200,7 @@ void InitControls(HWND hwndDlg)
LOGFONT lf;
HFONT hFont = (HFONT)SendMessage(hwndDlg, WM_GETFONT, 0, 0);
GetObject(hFont, sizeof(LOGFONT), &lf);
strcpy(lf.lfFaceName,"Courier");
strcpy(lf.lfFaceName,"Courier New");
hNewFont = CreateFontIndirect(&lf);
// HFONT hFont = CreateFont(0, 0, 0, 0, FW_THIN, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, 0, PROOF_QUALITY, DEFAULT_PITCH | FF_MODERN, "Courier New" );

View File

@ -1114,17 +1114,19 @@ BEGIN
PUSHBUTTON "Seek PC",IDC_DEBUGGER_SEEK_PC,391,71,39,14
PUSHBUTTON "Seek To:",IDC_DEBUGGER_SEEK_TO,350,54,38,14
EDITTEXT IDC_DEBUGGER_VAL_PCSEEK,391,55,38,12,ES_UPPERCASE | ES_WANTRETURN
EDITTEXT IDC_DEBUGGER_VAL_SLINE,383,203,14,12,ES_UPPERCASE | ES_READONLY | ES_WANTRETURN | NOT WS_BORDER,WS_EX_TRANSPARENT
EDITTEXT IDC_DEBUGGER_VAL_PPUPIXEL,372,216,14,12,ES_UPPERCASE | ES_READONLY | ES_WANTRETURN | NOT WS_BORDER | NOT WS_TABSTOP,WS_EX_TRANSPARENT
GROUPBOX "",IDC_DEBUGGER_VAL_S2,349,174,50,53,WS_TABSTOP
EDITTEXT IDC_DEBUGGER_VAL_CYCLES_COUNT,442,179,46,12,ES_NOHIDESEL | ES_READONLY | ES_WANTRETURN | NOT WS_BORDER | NOT WS_TABSTOP,WS_EX_TRANSPARENT
EDITTEXT IDC_DEBUGGER_VAL_CYCLES_COUNT2,489,179,51,12,ES_READONLY | ES_WANTRETURN | NOT WS_BORDER | NOT WS_TABSTOP,WS_EX_TRANSPARENT
EDITTEXT IDC_DEBUGGER_VAL_INSTRUCTIONS_COUNT,441,204,46,12,ES_NOHIDESEL | ES_READONLY | ES_WANTRETURN | NOT WS_BORDER | NOT WS_TABSTOP,WS_EX_TRANSPARENT
EDITTEXT IDC_DEBUGGER_VAL_INSTRUCTIONS_COUNT2,489,204,51,12,ES_READONLY | ES_WANTRETURN | NOT WS_BORDER | NOT WS_TABSTOP,WS_EX_TRANSPARENT
LTEXT "PPU:",65531,352,179,17,10
LTEXT "Sprite:",65530,352,191,20,10
EDITTEXT IDC_DEBUGGER_VAL_PPU,371,179,25,12,ES_UPPERCASE | ES_READONLY | ES_WANTRETURN | NOT WS_BORDER,WS_EX_TRANSPARENT
EDITTEXT IDC_DEBUGGER_VAL_SPR,374,191,15,12,ES_UPPERCASE | ES_READONLY | ES_WANTRETURN | NOT WS_BORDER,WS_EX_TRANSPARENT
LTEXT "Scanline:",IDC_STATIC,352,203,31,8
LTEXT "Pixel:",IDC_STATIC,352,216,17,8
EDITTEXT IDC_DEBUGGER_VAL_PPU,371,179,25,10,ES_UPPERCASE | ES_READONLY | ES_WANTRETURN | NOT WS_BORDER,WS_EX_TRANSPARENT
EDITTEXT IDC_DEBUGGER_VAL_SPR,374,191,15,10,ES_UPPERCASE | ES_READONLY | ES_WANTRETURN | NOT WS_BORDER,WS_EX_TRANSPARENT
EDITTEXT IDC_DEBUGGER_VAL_SLINE,383,203,14,10,ES_UPPERCASE | ES_READONLY | ES_WANTRETURN | NOT WS_BORDER,WS_EX_TRANSPARENT
EDITTEXT IDC_DEBUGGER_VAL_PPUPIXEL,372,216,14,10,ES_UPPERCASE | ES_READONLY | ES_WANTRETURN | NOT WS_BORDER | NOT WS_TABSTOP,WS_EX_TRANSPARENT
GROUPBOX "",IDC_DEBUGGER_VAL_S2,349,174,50,53,WS_TABSTOP
EDITTEXT IDC_DEBUGGER_VAL_CYCLES_COUNT,442,179,46,10,ES_NOHIDESEL | ES_READONLY | ES_WANTRETURN | NOT WS_BORDER | NOT WS_TABSTOP,WS_EX_TRANSPARENT
EDITTEXT IDC_DEBUGGER_VAL_CYCLES_COUNT2,489,179,51,10,ES_READONLY | ES_WANTRETURN | NOT WS_BORDER | NOT WS_TABSTOP,WS_EX_TRANSPARENT
EDITTEXT IDC_DEBUGGER_VAL_INSTRUCTIONS_COUNT,441,204,46,10,ES_NOHIDESEL | ES_READONLY | ES_WANTRETURN | NOT WS_BORDER | NOT WS_TABSTOP,WS_EX_TRANSPARENT
EDITTEXT IDC_DEBUGGER_VAL_INSTRUCTIONS_COUNT2,489,204,51,10,ES_READONLY | ES_WANTRETURN | NOT WS_BORDER | NOT WS_TABSTOP,WS_EX_TRANSPARENT
CONTROL "",IDC_DEBUGGER_ADDR_LINE,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,4,308,341,11
CONTROL "Break on Bad Opcode",IDC_DEBUGGER_BREAK_ON_BAD_OP,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,438,125,89,10
@ -1141,13 +1143,11 @@ BEGIN
LTEXT "Default window size",IDC_STATIC,364,308,68,9
PUSHBUTTON "Run Line",IDC_DEBUGGER_RUN_LINE,350,37,38,14
PUSHBUTTON "128 Lines",IDC_DEBUGGER_RUN_FRAME2,391,37,39,14
LTEXT "Scanline:",IDC_STATIC,352,203,31,8
CONTROL ".DEB files",DEBUGLOADDEB,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,489,306,46,13
CONTROL "Auto-open",DEBUGAUTOLOAD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,438,306,47,13
LTEXT "CPU cycles:",IDC_STATIC,402,179,39,8
PUSHBUTTON "Reset counters",IDC_DEBUGGER_RESET_COUNTERS,471,229,64,14
CONTROL "Break when exceed",IDC_DEBUGGER_BREAK_ON_CYCLES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,403,191,77,10
LTEXT "Pixel:",IDC_STATIC,352,216,17,8
EDITTEXT IDC_DEBUGGER_CYCLES_EXCEED,481,190,53,12,ES_UPPERCASE | ES_NOHIDESEL | ES_WANTRETURN | ES_NUMBER
LTEXT "Instructions:",IDC_STATIC,402,204,40,8
CONTROL "Break when exceed",IDC_DEBUGGER_BREAK_ON_INSTRUCTIONS,
@ -1157,7 +1157,7 @@ BEGIN
CONTROL "Display ROM offsets",IDC_DEBUGGER_ROM_OFFSETS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,442,249,82,10
END
TRACER DIALOGEX 65527, 65513, 403, 316
TRACER DIALOGEX 65527, 65513, 403, 332
STYLE DS_SETFONT | DS_MODALFRAME | DS_3DLOOK | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Trace Logger"
FONT 8, "MS Sans Serif", 400, 0, 0x0
@ -1166,27 +1166,32 @@ BEGIN
EDITTEXT IDC_TRACER_LOG,4,4,384,169,ES_MULTILINE | ES_NOHIDESEL | ES_READONLY | WS_HSCROLL
CONTROL "Log last",IDC_RADIO_LOG_LAST,"Button",BS_AUTORADIOBUTTON | BS_LEFT,17,195,38,10
CONTROL "Log to File",IDC_RADIO_LOG_TO_FILE,"Button",BS_AUTORADIOBUTTON | BS_LEFT,17,214,49,10
LTEXT "instructions to this window",106,108,195,87,10
LTEXT "lines to this window",106,109,195,72,10
PUSHBUTTON "Start Logging",IDC_BTN_START_STOP_LOGGING,181,176,67,14,BS_CENTER | BS_VCENTER
COMBOBOX IDC_TRACER_LOG_SIZE,57,193,48,127,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
GROUPBOX "Extra Log Options",109,12,232,378,39
GROUPBOX "Extra Log Options",109,12,232,378,53
CONTROL "Log state of A, X, Y and S registers",IDC_CHECK_LOG_REGISTERS,
"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,18,243,126,10
CONTROL "Log Processor Status Flags",IDC_CHECK_LOG_PROCESSOR_STATUS,
"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,148,243,102,10
CONTROL "Log Processor Status flags",IDC_CHECK_LOG_PROCESSOR_STATUS,
"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,148,243,104,10
PUSHBUTTON "Browse...",IDC_BTN_LOG_BROWSE,66,212,45,14,BS_CENTER | BS_VCENTER
LTEXT "",IDC_TRACER_STATS,121,213,246,12
CONTROL "Only log newly mapped code",IDC_CHECK_LOG_NEW_INSTRUCTIONS,
"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,18,284,107,10
GROUPBOX "Extra Log Options that work with the Code/Data Logger",113,12,272,378,40
"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,18,298,107,10
GROUPBOX "Extra Log Options that work with the Code/Data Logger",113,12,287,378,39
CONTROL "Only log code that accesses newly mapped data",IDC_CHECK_LOG_NEW_DATA,
"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,18,297,169,10
"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,18,311,169,10
CONTROL "Automatically update Window while logging",IDC_CHECK_LOG_UPDATE_WINDOW,
"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,202,195,156,10
CONTROL "Use Stack Pointer for lines tabbing (nesting visualization)",IDC_CHECK_LINES_TABBING,
"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,18,256,197,10
CONTROL "Use Stack Pointer for code tabbing (nesting visualization)",IDC_CHECK_CODE_TABBING,
"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,148,270,197,10
CONTROL "To the left from disassembly text",IDC_CHECK_LOG_STATUSES_TO_THE_LEFT,
"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,261,243,121,10
"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,261,243,119,10
CONTROL "Log current Frame number",IDC_CHECK_LOG_FRAME_NUMBER,
"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,18,256,102,10
CONTROL "Symbolic tracing",IDC_CHECK_SYMBOLIC_TRACING,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,18,270,72,10
CONTROL "Log emulator messages",IDC_CHECK_LOG_MESSAGES,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,148,256,94,10
CONTROL "Log breakpoint hits",IDC_CHECK_LOG_BREAKPOINTS,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,261,256,82,10
END
ADDBP DIALOGEX 66, 83, 196, 130

View File

@ -72,7 +72,6 @@
#define IDC_ADDBP_MODE_X 104
#define IDC_ROMPATCHER_CURRENT_DATA_BOX 104
#define IDC_NTVIEW_PROPERTIES_LINE_2 104
#define CHECK_PALETTE_GRAYSCALE2 104
#define CHECK_PALETTE_CUSTOM 104
#define COMBO_PAD2 105
#define CB_SET_HIGH_PRIORITY 105
@ -147,15 +146,20 @@
#define IDC_DEBUGGER_RESET_ON_STEP 117
#define IDC_DEBUGGER_BREAK_ON_CYCLES 117
#define IDC_CHECK_LINES_TABBING 117
#define IDC_CHECK_CODE_TABBING 117
#define CHEAT_CONTEXT_POKECHEATVALUE 118
#define IDC_DEBUGGER_RESET_ON_BP0 118
#define IDC_CHECK_LOG_STATUSES_TO_THE_LEFT 118
#define CHEAT_CONTEXT_GOTOINHEXEDITOR 119
#define IDC_DEBUGGER_BREAK_ON_INSTRUCTIONS 119
#define IDC_CHECK_LOG_FRAME_NUMBER 119
#define CHECK_SOUND_8BIT 122
#define IDD_DIALOG3 123
#define IDC_CHECK_SYMBOLIC_TRACING 123
#define CHECK_SOUND_GLOBAL_FOCUS 124
#define INSERTCOMMENTSUBTITLE 124
#define IDC_CHECK_LOG_MESSAGES 124
#define IDC_CHECK_LOG_BREAKPOINTS 125
#define CHECK_SOUND_ENABLED 126
#define CTL_LATENCY_TRACKBAR 128
#define COMBO_SOUND_QUALITY 129

View File

@ -718,6 +718,27 @@ void PIANO_ROLL::update()
}
break;
}
case DRAG_MODE_DESELECTION:
{
int new_drag_selection_ending_frame = real_row_under_mouse;
// if trying to deselect above Piano Roll, deselect from frame 0
if (new_drag_selection_ending_frame < 0)
new_drag_selection_ending_frame = 0;
else if (new_drag_selection_ending_frame >= currMovieData.getNumRecords())
new_drag_selection_ending_frame = currMovieData.getNumRecords() - 1;
if (new_drag_selection_ending_frame >= 0 && new_drag_selection_ending_frame != drag_selection_ending_frame)
{
// change Deselection shape
if (new_drag_selection_ending_frame >= drag_selection_starting_frame)
// deselecting from upper to lower
selection.ClearRegionSelection(drag_selection_starting_frame, new_drag_selection_ending_frame + 1);
else
// deselecting from lower to upper
selection.ClearRegionSelection(new_drag_selection_ending_frame, drag_selection_starting_frame + 1);
drag_selection_ending_frame = new_drag_selection_ending_frame;
}
break;
}
}
// update MarkerDragBox when it's flying away
if (hwndMarkerDragBox && drag_mode != DRAG_MODE_MARKER)
@ -1069,6 +1090,15 @@ void PIANO_ROLL::StartSelectingDrag(int start_frame)
drag_selection_ending_frame = drag_selection_starting_frame; // assuming that start_frame is already selected
}
}
void PIANO_ROLL::StartDeselectingDrag(int start_frame)
{
if (drag_mode == DRAG_MODE_NONE)
{
drag_mode = DRAG_MODE_DESELECTION;
drag_selection_starting_frame = start_frame;
drag_selection_ending_frame = drag_selection_starting_frame; // assuming that start_frame is already deselected
}
}
void PIANO_ROLL::DragPlaybackCursor()
{
@ -1767,6 +1797,7 @@ LRESULT APIENTRY ListWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
else
selection.SetRegionSelection(row_index, selection_beginning + 1);
}
piano_roll.StartSelectingDrag(row_index);
} else if (alt_pressed)
{
// make Selection by Pattern
@ -1779,20 +1810,32 @@ LRESULT APIENTRY ListWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
else
selection.SetRegionSelectionPattern(row_index, selection_beginning);
}
if (selection.GetRowSelection(row_index))
piano_roll.StartDeselectingDrag(row_index);
else
piano_roll.StartSelectingDrag(row_index);
} else if (fwKeys & MK_CONTROL)
{
// clone current selection, so that user will be able to revert
if (selection.GetCurrentSelectionSize() > 0)
selection.AddCurrentSelectionToHistory();
if (selection.GetRowSelection(row_index))
{
selection.ClearRowSelection(row_index);
else
piano_roll.StartDeselectingDrag(row_index);
} else
{
selection.SetRowSelection(row_index);
piano_roll.StartSelectingDrag(row_index);
}
} else // just click
{
selection.ClearSelection();
selection.SetRowSelection(row_index);
}
piano_roll.StartSelectingDrag(row_index);
}
}
}
} else if (column_index >= COLUMN_JOYPAD1_A && column_index <= COLUMN_JOYPAD4_R)
{
// clicked on Input

View File

@ -80,6 +80,7 @@ enum DRAG_MODES
DRAG_MODE_SET,
DRAG_MODE_UNSET,
DRAG_MODE_SELECTION,
DRAG_MODE_DESELECTION,
};
// when there's too many button columns, there's need for 2nd Frame# column at the end
@ -181,6 +182,7 @@ public:
void StartDraggingPlaybackCursor();
void StartDraggingMarker(int mouse_x, int mouse_y, int row_index, int column_index);
void StartSelectingDrag(int start_frame);
void StartDeselectingDrag(int start_frame);
void GetDispInfo(NMLVDISPINFO* nmlvDispInfo);
LONG CustomDraw(NMLVCUSTOMDRAW* msg);

View File

@ -430,6 +430,27 @@ void SELECTION::AddNewSelectionToHistory()
// add
selections_history[(history_start_pos + history_cursor_pos) % history_size] = selectionFrames;
}
void SELECTION::AddCurrentSelectionToHistory()
{
// create the copy of current selection
SelectionFrames selectionFrames = selections_history[(history_start_pos + history_cursor_pos) % history_size];
// increase current position
// history uses conveyor of selections (vector with fixed size) to avoid resizing
if (history_cursor_pos+1 >= history_size)
{
// reached the end of available history_size - move history_start_pos (thus deleting oldest selection)
history_cursor_pos = history_size-1;
history_start_pos = (history_start_pos + 1) % history_size;
} else
{
// didn't reach the end of history yet
history_cursor_pos++;
if (history_cursor_pos >= history_total_items)
history_total_items = history_cursor_pos+1;
}
// add
selections_history[(history_start_pos + history_cursor_pos) % history_size] = selectionFrames;
}
void SELECTION::JumpInTime(int new_pos)
{

View File

@ -31,6 +31,7 @@ public:
void ItemChanged(NMLISTVIEW* info);
void AddNewSelectionToHistory();
void AddCurrentSelectionToHistory();
void undo();
void redo();

View File

@ -373,6 +373,7 @@ void TASEDITOR_WINDOW::update()
case DRAG_MODE_SET:
case DRAG_MODE_UNSET:
case DRAG_MODE_SELECTION:
case DRAG_MODE_DESELECTION:
// user is drawing/selecting - show normal arrow
break;
}
@ -911,7 +912,7 @@ BOOL CALLBACK WndprocTasEditor(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara
break;
case ID_EDIT_DESELECT:
case ID_SELECTED_DESELECT:
if (piano_roll.drag_mode != DRAG_MODE_SELECTION)
if (piano_roll.drag_mode != DRAG_MODE_SELECTION && piano_roll.drag_mode != DRAG_MODE_DESELECTION)
selection.ClearSelection();
break;
case ID_EDIT_SELECTALL:
@ -919,7 +920,7 @@ BOOL CALLBACK WndprocTasEditor(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara
SendMessage(playback.hwndPlaybackMarkerEdit, EM_SETSEL, 0, -1);
else if (markers_manager.marker_note_edit == MARKER_NOTE_EDIT_LOWER)
SendMessage(selection.hwndSelectionMarkerEdit, EM_SETSEL, 0, -1);
else if (piano_roll.drag_mode != DRAG_MODE_SELECTION)
else if (piano_roll.drag_mode != DRAG_MODE_SELECTION && piano_roll.drag_mode != DRAG_MODE_DESELECTION)
selection.SelectAll();
break;
case ACCEL_CTRL_X:
@ -1176,12 +1177,12 @@ BOOL CALLBACK WndprocTasEditor(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara
SendMessage(playback.hwndPlaybackMarkerEdit, EM_SETSEL, 0, -1);
else if (markers_manager.marker_note_edit == MARKER_NOTE_EDIT_LOWER)
SendMessage(selection.hwndSelectionMarkerEdit, EM_SETSEL, 0, -1);
else if (piano_roll.drag_mode != DRAG_MODE_SELECTION)
else if (piano_roll.drag_mode != DRAG_MODE_SELECTION && piano_roll.drag_mode != DRAG_MODE_DESELECTION)
selection.SelectBetweenMarkers();
break;
case ID_EDIT_SELECTMIDMARKERS:
case ID_SELECTED_SELECTMIDMARKERS:
if (piano_roll.drag_mode != DRAG_MODE_SELECTION)
if (piano_roll.drag_mode != DRAG_MODE_SELECTION && piano_roll.drag_mode != DRAG_MODE_DESELECTION)
selection.SelectBetweenMarkers();
break;
case ACCEL_CTRL_INSERT:
@ -1213,7 +1214,7 @@ BOOL CALLBACK WndprocTasEditor(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara
case ID_EDIT_SELECTIONUNDO:
case ACCEL_CTRL_Q:
{
if (piano_roll.drag_mode != DRAG_MODE_SELECTION)
if (piano_roll.drag_mode != DRAG_MODE_SELECTION && piano_roll.drag_mode != DRAG_MODE_DESELECTION)
{
selection.undo();
piano_roll.FollowSelection();
@ -1223,7 +1224,7 @@ BOOL CALLBACK WndprocTasEditor(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara
case ID_EDIT_SELECTIONREDO:
case ACCEL_CTRL_W:
{
if (piano_roll.drag_mode != DRAG_MODE_SELECTION)
if (piano_roll.drag_mode != DRAG_MODE_SELECTION && piano_roll.drag_mode != DRAG_MODE_DESELECTION)
{
selection.redo();
piano_roll.FollowSelection();
@ -1233,7 +1234,7 @@ BOOL CALLBACK WndprocTasEditor(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara
case ID_EDIT_RESELECTCLIPBOARD:
case ACCEL_CTRL_B:
{
if (piano_roll.drag_mode != DRAG_MODE_SELECTION)
if (piano_roll.drag_mode != DRAG_MODE_SELECTION && piano_roll.drag_mode != DRAG_MODE_DESELECTION)
{
selection.ReselectClipboard();
piano_roll.FollowSelection();
@ -1328,7 +1329,7 @@ BOOL CALLBACK WndprocTasEditor(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara
case ACCEL_CTRL_HOME:
{
// transpose Selection to the beginning and scroll to it
if (piano_roll.drag_mode != DRAG_MODE_SELECTION)
if (piano_roll.drag_mode != DRAG_MODE_SELECTION && piano_roll.drag_mode != DRAG_MODE_DESELECTION)
{
int selection_beginning = selection.GetCurrentSelectionBeginning();
if (selection_beginning >= 0)
@ -1342,7 +1343,7 @@ BOOL CALLBACK WndprocTasEditor(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara
case ACCEL_CTRL_END:
{
// transpose Selection to the end and scroll to it
if (piano_roll.drag_mode != DRAG_MODE_SELECTION)
if (piano_roll.drag_mode != DRAG_MODE_SELECTION && piano_roll.drag_mode != DRAG_MODE_DESELECTION)
{
int selection_end = selection.GetCurrentSelectionEnd();
if (selection_end >= 0)
@ -1354,16 +1355,16 @@ BOOL CALLBACK WndprocTasEditor(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara
break;
}
case ACCEL_CTRL_PGUP:
if (piano_roll.drag_mode != DRAG_MODE_SELECTION)
if (piano_roll.drag_mode != DRAG_MODE_SELECTION && piano_roll.drag_mode != DRAG_MODE_DESELECTION)
selection.JumpPrevMarker();
break;
case ACCEL_CTRL_PGDN:
if (piano_roll.drag_mode != DRAG_MODE_SELECTION)
if (piano_roll.drag_mode != DRAG_MODE_SELECTION && piano_roll.drag_mode != DRAG_MODE_DESELECTION)
selection.JumpNextMarker();
break;
case ACCEL_CTRL_UP:
// transpose Selection 1 frame up and scroll to it
if (piano_roll.drag_mode != DRAG_MODE_SELECTION)
if (piano_roll.drag_mode != DRAG_MODE_SELECTION && piano_roll.drag_mode != DRAG_MODE_DESELECTION)
{
selection.Transpose(-1);
int selection_beginning = selection.GetCurrentSelectionBeginning();
@ -1373,7 +1374,7 @@ BOOL CALLBACK WndprocTasEditor(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara
break;
case ACCEL_CTRL_DOWN:
// transpose Selection 1 frame down and scroll to it
if (piano_roll.drag_mode != DRAG_MODE_SELECTION)
if (piano_roll.drag_mode != DRAG_MODE_SELECTION && piano_roll.drag_mode != DRAG_MODE_DESELECTION)
{
selection.Transpose(1);
int selection_end = selection.GetCurrentSelectionEnd();
@ -1493,7 +1494,7 @@ LRESULT APIENTRY IDC_SELECTION_MARKER_WndProc(HWND hWnd, UINT msg, WPARAM wParam
{
case WM_LBUTTONDOWN:
case WM_LBUTTONDBLCLK:
if (piano_roll.drag_mode != DRAG_MODE_SELECTION)
if (piano_roll.drag_mode != DRAG_MODE_SELECTION && piano_roll.drag_mode != DRAG_MODE_DESELECTION)
piano_roll.FollowSelection();
if (GetFocus() != hWnd)
SetFocus(hWnd);

View File

@ -43,15 +43,28 @@ using namespace std;
//#define LOG_SKIP_UNMAPPED 4
//#define LOG_ADD_PERIODS 8
// ################################## Start of SP CODE ###########################
#include "debuggersp.h"
extern Name* lastBankNames;
extern Name* loadedBankNames;
extern Name* ramBankNames;
extern int lastBank;
extern int loadedBank;
extern int myNumWPs;
// ################################## End of SP CODE ###########################
//int logaxy = 1, logopdata = 1; //deleteme
int logging_options = LOG_REGISTERS | LOG_PROCESSOR_STATUS;
int logging_options = LOG_REGISTERS | LOG_PROCESSOR_STATUS | LOG_TO_THE_LEFT | LOG_MESSAGES | LOG_BREAKPOINTS | LOG_CODE_TABBING;
int log_update_window = 0;
//int tracer_open=0;
volatile int logtofile = 0, logging = 0;
HWND hTracer;
HFONT hlogFont, hlogNewFont;
int log_optn_intlst[LOG_OPTION_SIZE] = {10000,8000,6000,4000,2000,1000,700,400,200,100};
char *log_optn_strlst[LOG_OPTION_SIZE] = {"10000","8000","6000","4000","2000","1000","700","400","200","100"};
int log_optn_intlst[LOG_OPTION_SIZE] = {3000000, 1000000, 300000, 100000, 30000, 10000, 3000, 1000, 300, 100};
char *log_optn_strlst[LOG_OPTION_SIZE] = {"3 000 000", "1 000 000", "300 000", "100 000", "30 000", "10 000", "3000", "1000", "300", "100"};
int log_lines_option = 5; // 10000 lines by default
char *logfilename = 0;
int oldcodecount, olddatacount;
@ -60,11 +73,14 @@ char **tracelogbuf;
int tracelogbufsize, tracelogbufpos;
int tracelogbufusedsize;
bool tracer_lines_tabbing = true;
bool tracer_statuses_to_the_left = false;
char str_axystate[LOG_AXYSTATE_MAX_LEN] = {0}, str_procstatus[LOG_PROCSTATUS_MAX_LEN] = {0};
char str_tabs[LOG_TABS_MASK+1] = {0}, str_address[LOG_ADDRESS_MAX_LEN] = {0}, str_data[LOG_DATA_MAX_LEN] = {0}, str_disassembly[LOG_DISASSEMBLY_MAX_LEN] = {0};
char str_temp[LOG_LINE_MAX_LEN] = {0};
char str_decoration[NL_MAX_MULTILINE_COMMENT_LEN + NL_MAX_NAME_LEN + 10] = {0};
bool old_emu_paused = true; // thanks to this flag the window only updates once after the game is paused
bool log_old_emu_paused = true; // thanks to this flag the window only updates once after the game is paused
extern bool JustFrameAdvanced;
extern int currFrameCounter;
FILE *LOG_FP;
@ -73,7 +89,6 @@ int Tracer_wndx=0, Tracer_wndy=0;
void ShowLogDirDialog(void);
void BeginLoggingSequence(void);
void LogInstruction(void);
void OutputLogLine(char *str);
void EndLoggingSequence(void);
//void PauseLoggingSequence(void);
void UpdateLogWindow(void);
@ -84,61 +99,69 @@ int PromptForCDLogger(void);
BOOL CALLBACK TracerCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
int i;
LOGFONT lf;
switch(uMsg) {
case WM_MOVE: {
if (!IsIconic(hwndDlg)) {
switch(uMsg)
{
case WM_MOVE:
{
if (!IsIconic(hwndDlg))
{
RECT wrect;
GetWindowRect(hwndDlg,&wrect);
Tracer_wndx = wrect.left;
Tracer_wndy = wrect.top;
#ifdef WIN32
WindowBoundsCheckNoResize(Tracer_wndx,Tracer_wndy,wrect.right);
#endif
}
break;
};
}
case WM_INITDIALOG:
{
if (Tracer_wndx==-32000) Tracer_wndx=0; //Just in case
if (Tracer_wndy==-32000) Tracer_wndy=0;
SetWindowPos(hwndDlg,0,Tracer_wndx,Tracer_wndy,0,0,SWP_NOSIZE|SWP_NOZORDER|SWP_NOOWNERZORDER);
hTracer = hwndDlg;
//setup font
hlogFont = (HFONT)SendMessage(hwndDlg, WM_GETFONT, 0, 0);
GetObject(hlogFont, sizeof(LOGFONT), &lf);
strcpy(lf.lfFaceName,"Courier New");
hlogNewFont = CreateFontIndirect(&lf);
SendDlgItemMessage(hwndDlg,IDC_TRACER_LOG,WM_SETFONT,(WPARAM)hlogNewFont,FALSE);
// setup font
SendDlgItemMessage(hwndDlg, IDC_TRACER_LOG, WM_SETFONT, (WPARAM)debugSystem->hFixedFont, FALSE);
// calculate tracesi.nPage
RECT wrect;
GetClientRect(GetDlgItem(hwndDlg, IDC_TRACER_LOG), &wrect);
tracesi.nPage = wrect.bottom / debugSystem->fixedFontHeight;
//check the disabled radio button
CheckRadioButton(hwndDlg,IDC_RADIO_LOG_LAST,IDC_RADIO_LOG_TO_FILE,IDC_RADIO_LOG_LAST);
//EnableWindow(GetDlgItem(hwndDlg,IDC_SCRL_TRACER_LOG),FALSE);
//fill in the options for the log size
for(i = 0;i < LOG_OPTION_SIZE;i++){
SendDlgItemMessage(hwndDlg,IDC_TRACER_LOG_SIZE,CB_INSERTSTRING,-1,(LPARAM)(LPSTR)log_optn_strlst[i]);
for(i = 0;i < LOG_OPTION_SIZE;i++)
{
SendDlgItemMessage(hwndDlg, IDC_TRACER_LOG_SIZE, CB_INSERTSTRING, -1, (LPARAM)(LPSTR)log_optn_strlst[i]);
}
SendDlgItemMessage(hwndDlg,IDC_TRACER_LOG_SIZE,CB_SETCURSEL,0,0);
SendDlgItemMessage(hwndDlg, IDC_TRACER_LOG_SIZE, CB_SETCURSEL, (WPARAM)log_lines_option, 0);
SetDlgItemText(hwndDlg, IDC_TRACER_LOG, "Welcome to the Trace Logger.");
logtofile = 0;
CheckDlgButton(hwndDlg, IDC_CHECK_LINES_TABBING, tracer_lines_tabbing ? BST_CHECKED : BST_UNCHECKED);
CheckDlgButton(hwndDlg, IDC_CHECK_LOG_STATUSES_TO_THE_LEFT, tracer_statuses_to_the_left ? BST_CHECKED : BST_UNCHECKED);
CheckDlgButton(hwndDlg, IDC_CHECK_LOG_REGISTERS, (logging_options & LOG_REGISTERS) ? BST_CHECKED : BST_UNCHECKED);
CheckDlgButton(hwndDlg, IDC_CHECK_LOG_PROCESSOR_STATUS, (logging_options & LOG_PROCESSOR_STATUS) ? BST_CHECKED : BST_UNCHECKED);
EnableWindow(GetDlgItem(hwndDlg,IDC_TRACER_LOG_SIZE),TRUE);
EnableWindow(GetDlgItem(hwndDlg,IDC_BTN_LOG_BROWSE),FALSE);
CheckDlgButton(hwndDlg, IDC_CHECK_LOG_NEW_INSTRUCTIONS, (logging_options & LOG_NEW_INSTRUCTIONS) ? BST_CHECKED : BST_UNCHECKED);
CheckDlgButton(hwndDlg, IDC_CHECK_LOG_NEW_DATA, (logging_options & LOG_NEW_DATA) ? BST_CHECKED : BST_UNCHECKED);
CheckDlgButton(hwndDlg, IDC_CHECK_LOG_STATUSES_TO_THE_LEFT, (logging_options & LOG_TO_THE_LEFT) ? BST_CHECKED : BST_UNCHECKED);
CheckDlgButton(hwndDlg, IDC_CHECK_LOG_FRAME_NUMBER, (logging_options & LOG_FRAME_NUMBER) ? BST_CHECKED : BST_UNCHECKED);
CheckDlgButton(hwndDlg, IDC_CHECK_LOG_MESSAGES, (logging_options & LOG_MESSAGES) ? BST_CHECKED : BST_UNCHECKED);
CheckDlgButton(hwndDlg, IDC_CHECK_LOG_BREAKPOINTS, (logging_options & LOG_BREAKPOINTS) ? BST_CHECKED : BST_UNCHECKED);
CheckDlgButton(hwndDlg, IDC_CHECK_SYMBOLIC_TRACING, (logging_options & LOG_SYMBOLIC) ? BST_CHECKED : BST_UNCHECKED);
CheckDlgButton(hwndDlg, IDC_CHECK_CODE_TABBING, (logging_options & LOG_CODE_TABBING) ? BST_CHECKED : BST_UNCHECKED);
EnableWindow(GetDlgItem(hwndDlg, IDC_TRACER_LOG_SIZE), TRUE);
EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_LOG_BROWSE), FALSE);
CheckDlgButton(hwndDlg, IDC_CHECK_LOG_UPDATE_WINDOW, log_update_window ? BST_CHECKED : BST_UNCHECKED);
EnableTracerMenuItems();
break;
}
case WM_CLOSE:
case WM_QUIT:
if(logging)EndLoggingSequence();
DeleteObject(hlogNewFont);
logging_options &= 3;
if(logging)
EndLoggingSequence();
hTracer = 0;
EndDialog(hwndDlg,0);
break;
@ -161,30 +184,48 @@ BOOL CALLBACK TracerCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
break;
case IDC_CHECK_LOG_REGISTERS:
logging_options ^= LOG_REGISTERS;
CheckDlgButton(hwndDlg, IDC_CHECK_LOG_REGISTERS, (logging_options & LOG_REGISTERS) ? BST_CHECKED : BST_UNCHECKED);
break;
case IDC_CHECK_LOG_PROCESSOR_STATUS:
logging_options ^= LOG_PROCESSOR_STATUS;
CheckDlgButton(hwndDlg, IDC_CHECK_LOG_PROCESSOR_STATUS, (logging_options & LOG_PROCESSOR_STATUS) ? BST_CHECKED : BST_UNCHECKED);
break;
case IDC_CHECK_LOG_STATUSES_TO_THE_LEFT:
tracer_statuses_to_the_left ^= 1;
logging_options ^= LOG_TO_THE_LEFT;
CheckDlgButton(hwndDlg, IDC_CHECK_LOG_STATUSES_TO_THE_LEFT, (logging_options & LOG_TO_THE_LEFT) ? BST_CHECKED : BST_UNCHECKED);
break;
case IDC_CHECK_LINES_TABBING:
tracer_lines_tabbing ^= 1;
case IDC_CHECK_LOG_FRAME_NUMBER:
logging_options ^= LOG_FRAME_NUMBER;
CheckDlgButton(hwndDlg, IDC_CHECK_LOG_FRAME_NUMBER, (logging_options & LOG_FRAME_NUMBER) ? BST_CHECKED : BST_UNCHECKED);
break;
case IDC_CHECK_LOG_MESSAGES:
logging_options ^= LOG_MESSAGES;
CheckDlgButton(hwndDlg, IDC_CHECK_LOG_MESSAGES, (logging_options & LOG_MESSAGES) ? BST_CHECKED : BST_UNCHECKED);
break;
case IDC_CHECK_LOG_BREAKPOINTS:
logging_options ^= LOG_BREAKPOINTS;
CheckDlgButton(hwndDlg, IDC_CHECK_LOG_BREAKPOINTS, (logging_options & LOG_BREAKPOINTS) ? BST_CHECKED : BST_UNCHECKED);
break;
case IDC_CHECK_SYMBOLIC_TRACING:
logging_options ^= LOG_SYMBOLIC;
CheckDlgButton(hwndDlg, IDC_CHECK_SYMBOLIC_TRACING, (logging_options & LOG_SYMBOLIC) ? BST_CHECKED : BST_UNCHECKED);
break;
case IDC_CHECK_CODE_TABBING:
logging_options ^= LOG_CODE_TABBING;
CheckDlgButton(hwndDlg, IDC_CHECK_CODE_TABBING, (logging_options & LOG_CODE_TABBING) ? BST_CHECKED : BST_UNCHECKED);
break;
case IDC_CHECK_LOG_NEW_INSTRUCTIONS:
logging_options ^= LOG_NEW_INSTRUCTIONS;
if(logging && (!PromptForCDLogger())){
logging_options ^= LOG_NEW_INSTRUCTIONS; //turn it back off
CheckDlgButton(hTracer, IDC_CHECK_LOG_NEW_INSTRUCTIONS, BST_UNCHECKED);
}
if(logging && (!PromptForCDLogger()))
logging_options &= ~LOG_NEW_INSTRUCTIONS; //turn it back off
CheckDlgButton(hwndDlg, IDC_CHECK_LOG_NEW_INSTRUCTIONS, (logging_options & LOG_NEW_INSTRUCTIONS) ? BST_CHECKED : BST_UNCHECKED);
//EnableTracerMenuItems();
break;
case IDC_CHECK_LOG_NEW_DATA:
logging_options ^= LOG_NEW_DATA;
if(logging && (!PromptForCDLogger())){
logging_options ^= LOG_NEW_DATA; //turn it back off
CheckDlgButton(hTracer, IDC_CHECK_LOG_NEW_DATA, BST_UNCHECKED);
}
if(logging && (!PromptForCDLogger()))
logging_options &= ~LOG_NEW_DATA; //turn it back off
CheckDlgButton(hwndDlg, IDC_CHECK_LOG_NEW_DATA, (logging_options & LOG_NEW_DATA) ? BST_CHECKED : BST_UNCHECKED);
break;
case IDC_CHECK_LOG_UPDATE_WINDOW:
{
@ -225,20 +266,22 @@ BOOL CALLBACK TracerCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
if(!FCEUI_EmulationPaused() && !log_update_window) break; //mbg merge 7/19/06 changd to use EmulationPaused()
GetScrollInfo((HWND)lParam,SB_CTL,&tracesi);
switch(LOWORD(wParam)) {
switch(LOWORD(wParam))
{
case SB_ENDSCROLL:
case SB_TOP:
case SB_BOTTOM: break;
case SB_LINEUP: tracesi.nPos--; break;
case SB_LINEDOWN:tracesi.nPos++; break;
case SB_PAGEUP: tracesi.nPos-=tracesi.nPage; break;
case SB_PAGEDOWN: tracesi.nPos+=tracesi.nPage; break;
case SB_PAGEUP: tracesi.nPos -= tracesi.nPage; break;
case SB_PAGEDOWN: tracesi.nPos += tracesi.nPage; break;
case SB_THUMBPOSITION: //break;
case SB_THUMBTRACK: tracesi.nPos = tracesi.nTrackPos; break;
}
if(tracesi.nPos < tracesi.nMin) tracesi.nPos = tracesi.nMin;
if((tracesi.nPos+(int)tracesi.nPage) > tracesi.nMax) tracesi.nPos = tracesi.nMax-(int)tracesi.nPage; //mbg merge 7/19/06 added casts
if(tracesi.nPos < 0)tracesi.nPos = 0; //this fixes a bad crash that occurs if you scroll up when only a few isntructions were logged
if ((tracesi.nPos + (int)tracesi.nPage) > tracesi.nMax)
tracesi.nPos = tracesi.nMax - (int)tracesi.nPage;
if (tracesi.nPos < tracesi.nMin)
tracesi.nPos = tracesi.nMin;
SetScrollInfo((HWND)lParam,SB_CTL,&tracesi,TRUE);
UpdateLogText();
}
@ -268,9 +311,12 @@ void BeginLoggingSequence(void)
fprintf(LOG_FP,FCEU_NAME_AND_VERSION" - Trace Log File\n"); //mbg merge 7/19/06 changed string
} else
{
log_lines_option = SendDlgItemMessage(hTracer, IDC_TRACER_LOG_SIZE, CB_GETCURSEL, 0, 0);
if (log_lines_option == CB_ERR)
log_lines_option = 0;
strcpy(str,"Allocating Memory...\r\n");
SetDlgItemText(hTracer, IDC_TRACER_LOG, str);
tracelogbufsize = j = log_optn_intlst[SendDlgItemMessage(hTracer,IDC_TRACER_LOG_SIZE,CB_GETCURSEL,0,0)];
tracelogbufsize = j = log_optn_intlst[log_lines_option];
tracelogbuf = (char**)malloc(j*sizeof(char *)); //mbg merge 7/19/06 added cast
for(i = 0;i < j;i++)
{
@ -332,83 +378,132 @@ done:
}*/
//todo: really speed this up
void FCEUD_TraceInstruction(){
if(!logging) return;
void FCEUD_TraceInstruction()
{
if (!logging)
return;
char str_tabs[LOG_TABS_MASK+1], address[7], data[11], disassembly[LOG_DISASSEMBLY_MAX_LEN], axystate[21], procstatus[12];
char str[LOG_LINE_MAX_LEN];
int addr=X.PC;
unsigned int addr = X.PC;
int size, j;
uint8 opcode[3], tmp;
static int unloggedlines;
if(((logging_options & LOG_NEW_INSTRUCTIONS) && (oldcodecount != codecount)) ||
((logging_options & LOG_NEW_DATA) && (olddatacount != datacount))){//something new was logged
((logging_options & LOG_NEW_DATA) && (olddatacount != datacount)))
{
//something new was logged
oldcodecount = codecount;
olddatacount = datacount;
if(unloggedlines > 0){
sprintf(str,"(%d lines skipped)",unloggedlines);
OutputLogLine(str);
if(unloggedlines > 0)
{
sprintf(str_temp, "(%d lines skipped)", unloggedlines);
OutputLogLine(str_temp);
unloggedlines = 0;
}
} else {
} else
{
if((logging_options & LOG_NEW_INSTRUCTIONS) ||
(logging_options & LOG_NEW_DATA)){
if(FCEUI_GetLoggingCD())unloggedlines++;
(logging_options & LOG_NEW_DATA))
{
if(FCEUI_GetLoggingCD())
unloggedlines++;
return;
}
}
sprintf(str_address, "$%04X:", addr);
sprintf(address, "$%04X:", addr);
axystate[0] = str[0] = 0;
size = opsize[GetMem(addr)];
if ((addr+size) > 0xFFFF)
{
sprintf(data, "%02X ", GetMem(addr&0xFFFF));
sprintf(disassembly,"OVERFLOW");
sprintf(str_data, "%02X ", GetMem(addr&0xFFFF));
sprintf(str_disassembly, "OVERFLOW");
} else
{
switch(size)
char* a;
switch (size)
{
case 0:
sprintf(data, "%02X ", GetMem(addr));
sprintf(disassembly,"UNDEFINED");
sprintf(str_data, "%02X ", GetMem(addr));
sprintf(str_disassembly,"UNDEFINED");
break;
case 1:
opcode[0]=GetMem(addr++);
sprintf(data, "%02X ", opcode[0]);
strcpy(disassembly,Disassemble(addr,opcode));
sprintf(str_data, "%02X ", opcode[0]);
a = Disassemble(addr, opcode);
break;
case 2:
opcode[0]=GetMem(addr++);
opcode[1]=GetMem(addr++);
sprintf(data, "%02X %02X ", opcode[0],opcode[1]);
strcpy(disassembly,Disassemble(addr,opcode));
sprintf(str_data, "%02X %02X ", opcode[0],opcode[1]);
a = Disassemble(addr, opcode);
break;
case 3:
opcode[0]=GetMem(addr++);
opcode[1]=GetMem(addr++);
opcode[2]=GetMem(addr++);
sprintf(data, "%02X %02X %02X ", opcode[0],opcode[1],opcode[2]);
strcpy(disassembly,Disassemble(addr,opcode));
sprintf(str_data, "%02X %02X %02X ", opcode[0],opcode[1],opcode[2]);
a = Disassemble(addr, opcode);
break;
}
if (logging_options & LOG_SYMBOLIC)
{
loadNameFiles();
// Insert Name and Comment line if needed
str_decoration[0] = 0;
decorateAddress(X.PC, str_decoration);
if (str_decoration[0])
{
// divide the str_decoration into strings (Name, Comment1, Comment2, ...)
char* start_pos = str_decoration;
char* end_pos = strstr(str_decoration, "\r");
while (end_pos)
{
end_pos[0] = 0; // set \0 instead of \r
OutputLogLine(start_pos, true);
end_pos += 2;
start_pos = end_pos;
end_pos = strstr(end_pos, "\r");
}
}
replaceNames(ramBankNames, a);
replaceNames(loadedBankNames, a);
replaceNames(lastBankNames, a);
}
strcpy(str_disassembly, a);
}
//stretch the disassembly string out if we have to output other stuff.
if((logging_options & (LOG_REGISTERS|LOG_PROCESSOR_STATUS)) && !tracer_statuses_to_the_left)
if ((logging_options & (LOG_REGISTERS|LOG_PROCESSOR_STATUS)) && !(logging_options & LOG_TO_THE_LEFT))
{
for(j = strlen(disassembly);j < LOG_DISASSEMBLY_MAX_LEN - 1;j++)disassembly[j] = ' ';
disassembly[LOG_DISASSEMBLY_MAX_LEN - 1] = 0;
for(j = strlen(str_disassembly);j < LOG_DISASSEMBLY_MAX_LEN - 1;j++)
str_disassembly[j] = ' ';
str_disassembly[LOG_DISASSEMBLY_MAX_LEN - 1] = 0;
}
if(logging_options & LOG_REGISTERS){
sprintf(axystate,"A:%02X X:%02X Y:%02X S:%02X",(X.A),(X.X),(X.Y),(X.S));
// Start filling the str_temp line: Frame number, AXYS state, Processor status, Tabs, Address, Data, Disassembly
if (logging_options & LOG_FRAME_NUMBER)
{
sprintf(str_temp, "%06u: ", currFrameCounter);
} else
{
str_temp[0] = 0;
}
if(logging_options & LOG_PROCESSOR_STATUS){
if (logging_options & LOG_REGISTERS)
{
sprintf(str_axystate,"A:%02X X:%02X Y:%02X S:%02X ",(X.A),(X.X),(X.Y),(X.S));
}
if (logging_options & LOG_PROCESSOR_STATUS)
{
tmp = X.P^0xFF;
sprintf(procstatus,"P:%c%c%c%c%c%c%c%c",
sprintf(str_procstatus,"P:%c%c%c%c%c%c%c%c ",
'N'|(tmp&0x80)>>2,
'V'|(tmp&0x40)>>1,
'U'|(tmp&0x20),
@ -420,59 +515,64 @@ void FCEUD_TraceInstruction(){
);
}
if (tracer_statuses_to_the_left)
if (logging_options & LOG_TO_THE_LEFT)
{
if (logging_options & LOG_REGISTERS)
strcat(str, axystate);
if ((logging_options & LOG_REGISTERS) && (logging_options & LOG_PROCESSOR_STATUS))
strcat(str, " ");
strcat(str_temp, str_axystate);
if (logging_options & LOG_PROCESSOR_STATUS)
strcat(str, procstatus);
if ((logging_options & LOG_REGISTERS) || (logging_options & LOG_PROCESSOR_STATUS))
strcat(str, " ");
strcat(str_temp, str_procstatus);
}
if (tracer_lines_tabbing)
if (logging_options & LOG_CODE_TABBING)
{
// add spaces at the beginning of the line according to stack pointer
int spaces = (0xFF - X.S) & LOG_TABS_MASK;
for (int i = 0; i < spaces; i++)
str_tabs[i] = ' ';
str_tabs[spaces] = 0;
strcat(str, str_tabs);
strcat(str_temp, str_tabs);
}
strcat(str, address);
strcat(str, data);
strcat(str, disassembly);
strcat(str_temp, str_address);
strcat(str_temp, str_data);
strcat(str_temp, str_disassembly);
if (!tracer_statuses_to_the_left)
if (!(logging_options & LOG_TO_THE_LEFT))
{
if (logging_options & LOG_REGISTERS)
strcat(str,axystate);
if ((logging_options & LOG_REGISTERS) && (logging_options & LOG_PROCESSOR_STATUS))
strcat(str," ");
strcat(str_temp, str_axystate);
if (logging_options & LOG_PROCESSOR_STATUS)
strcat(str,procstatus);
strcat(str_temp, str_procstatus);
}
OutputLogLine(str);
OutputLogLine(str_temp);
return;
}
void OutputLogLine(char *str){
if(logtofile){
strcat(str,"\n");
fputs(str,LOG_FP);
void OutputLogLine(const char *str, bool add_newline)
{
if(logtofile)
{
fputs(str, LOG_FP);
if (add_newline)
fputs("\n", LOG_FP);
fflush(LOG_FP);
}else{
strcat(str,"\r\n");
if(strlen(str) < LOG_LINE_MAX_LEN)
strcpy(tracelogbuf[tracelogbufpos],str);
} else
{
if (add_newline)
{
strncpy(tracelogbuf[tracelogbufpos], str, LOG_LINE_MAX_LEN - 3);
tracelogbuf[tracelogbufpos][LOG_LINE_MAX_LEN - 3] = 0;
strcat(tracelogbuf[tracelogbufpos], "\r\n");
} else
{
strncpy(tracelogbuf[tracelogbufpos], str, LOG_LINE_MAX_LEN - 1);
tracelogbuf[tracelogbufpos][LOG_LINE_MAX_LEN - 1] = 0;
}
tracelogbufpos++;
if(tracelogbufusedsize < tracelogbufsize)tracelogbufusedsize++;
tracelogbufpos%=tracelogbufsize;
if (tracelogbufusedsize < tracelogbufsize)
tracelogbufusedsize++;
tracelogbufpos %= tracelogbufsize;
}
}
@ -503,27 +603,28 @@ void UpdateLogWindow(void)
// only update the window when some emulation occured
// and only update the window when emulator is paused or log_update_window=true
bool emu_paused = (FCEUI_EmulationPaused() != 0);
if ((!emu_paused && !log_update_window) || (old_emu_paused && !JustFrameAdvanced)) //mbg merge 7/19/06 changd to use EmulationPaused()
if ((!emu_paused && !log_update_window) || (log_old_emu_paused && !JustFrameAdvanced)) //mbg merge 7/19/06 changd to use EmulationPaused()
{
old_emu_paused = emu_paused;
log_old_emu_paused = emu_paused;
return;
}
old_emu_paused = emu_paused;
log_old_emu_paused = emu_paused;
tracesi.cbSize = sizeof(SCROLLINFO);
tracesi.fMask = SIF_ALL;
tracesi.nPage = 21;
tracesi.nMin = 0;
tracesi.nMax = tracelogbufusedsize; //todo: try -2
tracesi.nPos = tracesi.nMax-tracesi.nPage;
if (tracesi.nPos < tracesi.nMin) tracesi.nPos = tracesi.nMin;
tracesi.nMax = tracelogbufusedsize;
tracesi.nPos = tracesi.nMax - tracesi.nPage;
if (tracesi.nPos < tracesi.nMin)
tracesi.nPos = tracesi.nMin;
SetScrollInfo(GetDlgItem(hTracer,IDC_SCRL_TRACER_LOG),SB_CTL,&tracesi,TRUE);
UpdateLogText();
return;
}
void UpdateLogText(void){
void UpdateLogText(void)
{
int i, j;
char str[3000];
str[0] = 0;
@ -535,9 +636,11 @@ void UpdateLogText(void){
}
*/
for(i = tracesi.nPos;i < std::min(tracesi.nMax,tracesi.nPos+21);i++){
for(i = tracesi.nPos;i < std::min(tracesi.nMax,tracesi.nPos+21);i++)
{
j = i;
if(tracelogbufusedsize == tracelogbufsize){
if(tracelogbufusedsize == tracelogbufsize)
{
j = (tracelogbufpos+i)%tracelogbufsize;
}
strcat(str,tracelogbuf[j]);

View File

@ -1,20 +1,43 @@
#define LOG_OPTION_SIZE 10
#define LOG_REGISTERS 1
#define LOG_PROCESSOR_STATUS 2
#define LOG_NEW_INSTRUCTIONS 4
#define LOG_NEW_DATA 8
#define LOG_TO_THE_LEFT 16
#define LOG_FRAME_NUMBER 32
#define LOG_MESSAGES 64
#define LOG_BREAKPOINTS 128
#define LOG_SYMBOLIC 256
#define LOG_CODE_TABBING 512
#define LOG_LINE_MAX_LEN 120
#define LOG_LINE_MAX_LEN 150
// Frame number - 7+1 symbols
// AXYS state - 20
// Processor status - 11
// Tabs - 31
// Address - 6
// Data - 10
// Disassembly - 63
// EOL (/0) - 1
// ------------------------
// 150 symbols total
#define LOG_AXYSTATE_MAX_LEN 21
#define LOG_PROCSTATUS_MAX_LEN 12
#define LOG_TABS_MASK 31
#define LOG_DISASSEMBLY_MAX_LEN 30
#define LOG_ADDRESS_MAX_LEN 7
#define LOG_DATA_MAX_LEN 11
#define LOG_DISASSEMBLY_MAX_LEN 64
extern HWND hTracer;
extern int log_update_window;
extern volatile int logtofile, logging;
extern int logging_options;
extern bool log_old_emu_paused;
void EnableTracerMenuItems(void);
void LogInstruction(void);
void DoTracer();
//void PauseLoggingSequence();
void UpdateLogWindow(void);
void OutputLogLine(const char *str, bool add_newline = true);

View File

@ -622,11 +622,6 @@ void FCEUI_Emulate(uint8 **pXBuf, int32 **SoundBuf, int32 *SoundBufSize, int ski
//skip initiates frame skip if 1, or frame skip and sound skip if 2
int r,ssize;
#ifdef WIN32
UpdateLogWindow();
#endif
JustFrameAdvanced = false;
if (frameAdvanceRequested)