* 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 the current instruction is bad, and we are breaking on bad opcodes, then hit the breakpoint
if(dbgstate.badopbreak && (opsize[opcode[0]] == 0)) 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 we're stepping out, track the nest level
if (dbgstate.stepout) { if (dbgstate.stepout) {

View File

@ -17,8 +17,9 @@
#define BT_S 0x40 //break type, sprite mem #define BT_S 0x40 //break type, sprite mem
#define BREAK_TYPE_STEP -1 #define BREAK_TYPE_STEP -1
#define BREAK_TYPE_CYCLES_EXCEED -2 #define BREAK_TYPE_BADOP -2
#define BREAK_TYPE_INSTRUCTIONS_EXCEED -3 #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. //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. //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 //setup font
hFont = (HFONT)SendMessage(hwndDlg, WM_GETFONT, 0, 0); hFont = (HFONT)SendMessage(hwndDlg, WM_GETFONT, 0, 0);
GetObject(hFont, sizeof(LOGFONT), &lf); GetObject(hFont, sizeof(LOGFONT), &lf);
strcpy(lf.lfFaceName,"Courier"); strcpy(lf.lfFaceName,"Courier New");
hNewFont = CreateFontIndirect(&lf); hNewFont = CreateFontIndirect(&lf);
SendDlgItemMessage(hwndDlg,IDC_CHEAT_ADDR,WM_SETFONT,(WPARAM)hNewFont,FALSE); 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 MainWindow_wndx, MainWindow_wndy;
extern int MemWatch_wndx, MemWatch_wndy; extern int MemWatch_wndx, MemWatch_wndy;
extern int Monitor_wndx, Monitor_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 logging_options;
extern int log_lines_option;
extern int Tracer_wndx, Tracer_wndy; extern int Tracer_wndx, Tracer_wndy;
extern int CDLogger_wndx, CDLogger_wndy; extern int CDLogger_wndx, CDLogger_wndy;
extern int GGConv_wndx, GGConv_wndy; extern int GGConv_wndx, GGConv_wndy;
@ -286,9 +285,8 @@ static CFGSTRUCT fceuconfig[] = {
AC(MemWatch_wndy), AC(MemWatch_wndy),
AC(Monitor_wndx), AC(Monitor_wndx),
AC(Monitor_wndy), AC(Monitor_wndy),
AC(tracer_lines_tabbing),
AC(tracer_statuses_to_the_left),
AC(logging_options), AC(logging_options),
AC(log_lines_option),
AC(Tracer_wndx), AC(Tracer_wndx),
AC(Tracer_wndy), AC(Tracer_wndy),
AC(CDLogger_wndx), AC(CDLogger_wndx),

View File

@ -354,7 +354,8 @@ void Disassemble(HWND hWnd, int id, int scrollid, unsigned int addr) {
// ################################## Start of SP CODE ########################### // ################################## Start of SP CODE ###########################
loadNameFiles(); if (symbDebugEnabled)
loadNameFiles();
// ################################## End of SP CODE ########################### // ################################## 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 //figure out how many lines we can draw
RECT rect; RECT rect;
GetClientRect(hWnd,&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++) 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++)); sprintf(chr, "%02X UNDEFINED", GetMem(addr++));
strcat(str,chr); strcat(str,chr);
} } else
else { {
char* a; char* a;
if ((addr+size) > 0x10000) { //should this be 0xFFFF? if ((addr+size) > 0x10000) { //should this be 0xFFFF?
while (addr < 0x10000) { while (addr < 0x10000) {
@ -426,7 +427,7 @@ void Disassemble(HWND hWnd, int id, int scrollid, unsigned int addr) {
// ################################## Start of SP CODE ########################### // ################################## Start of SP CODE ###########################
a = Disassemble(addr,opcode); a = Disassemble(addr, opcode);
if (symbDebugEnabled) if (symbDebugEnabled)
{ {
@ -576,8 +577,35 @@ bool inDebugger = false;
//this code enters the debugger when a breakpoint was hit //this code enters the debugger when a breakpoint was hit
void FCEUD_DebugBreakpoint(int bp_num) 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(); UpdateDebugger();
UpdateOtherDebuggingDialogs(); // Keeps the debugging windows updating smoothly when stepping
if (bp_num >= 0) if (bp_num >= 0)
{ {
// highlight bp_num item in IDC_DEBUGGER_BP_LIST // highlight bp_num item in IDC_DEBUGGER_BP_LIST
@ -596,9 +624,10 @@ void FCEUD_DebugBreakpoint(int bp_num)
else if (bp_num == BREAK_TYPE_INSTRUCTIONS_EXCEED) else if (bp_num == BREAK_TYPE_INSTRUCTIONS_EXCEED)
SendMessage(GetDlgItem(hDebug, IDC_DEBUGGER_VAL_INSTRUCTIONS_COUNT), EM_SETSEL, 0, -1); 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 void win_debuggerLoop(); // HACK to let user interact with the Debugger while emulator isn't updating
win_debuggerLoop(); win_debuggerLoop();
// since we unfreezed emulation, reset delta_cycles counter // since we unfreezed emulation, reset delta_cycles counter
ResetDebugStatisticsDeltaCounters(); ResetDebugStatisticsDeltaCounters();
} }
@ -755,15 +784,16 @@ void UpdateDebugger()
DebuggerWasUpdated = true; DebuggerWasUpdated = true;
} }
char *BreakToText(unsigned int num) { char* BreakToText(unsigned int num)
static char str[230],chr[8]; {
static char str[300], chr[8];
sprintf(str, "$%04X", watchpoint[num].address); sprintf(str, "$%04X", watchpoint[num].address);
if (watchpoint[num].endaddress) { if (watchpoint[num].endaddress) {
sprintf(chr, "-$%04X", watchpoint[num].endaddress); sprintf(chr, "-%04X", watchpoint[num].endaddress);
strcat(str,chr); 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&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_R) strcat(str,"R"); else strcat(str,"-");
if (watchpoint[num].flags&WP_W) strcat(str,"W"); 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,"-"); if (watchpoint[num].flags&WP_F) strcat(str,"F"); else strcat(str,"-");
// ################################## Start of SP CODE ########################### // ################################## 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, 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 ########################### // ################################## End of SP CODE ###########################
@ -1184,7 +1222,7 @@ BOOL CALLBACK IDC_DEBUGGER_DISASSEMBLY_WndProc(HWND hwndDlg, UINT uMsg, WPARAM w
// select the text // select the text
CallWindowProc(IDC_DEBUGGER_DISASSEMBLY_oldWndProc, hwndDlg, uMsg, wParam, lParam); CallWindowProc(IDC_DEBUGGER_DISASSEMBLY_oldWndProc, hwndDlg, uMsg, wParam, lParam);
int mouse_y = GET_Y_LPARAM(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; int i = si.nPos;
while (tmp > 0) 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_VAL_PC,WM_SETFONT,(WPARAM)debugSystem->hFixedFont,FALSE);
SendDlgItemMessage(hwndDlg,IDC_DEBUGGER_STACK_CONTENTS,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_PCSEEK,WM_SETFONT,(WPARAM)debugSystem->hFixedFont,FALSE);
//SendDlgItemMessage(hwndDlg,IDC_DEBUGGER_VAL_PPU,WM_SETFONT,(WPARAM)debugSystem->hFixedFont,FALSE); SendDlgItemMessage(hwndDlg,IDC_DEBUGGER_BP_LIST,WM_SETFONT,(WPARAM)debugSystem->hFixedFont,FALSE);
//SendDlgItemMessage(hwndDlg,IDC_DEBUGGER_VAL_SPR,WM_SETFONT,(WPARAM)debugSystem->hFixedFont,FALSE);
//text limits //text limits
SendDlgItemMessage(hwndDlg,IDC_DEBUGGER_VAL_A,EM_SETLIMITTEXT,2,0); 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 //mbg merge 7/18/06 changed pausing check
if (FCEUI_EmulationPaused() && (mouse_x > 8) && (mouse_x < 22) && (mouse_y > 10) && (mouse_y < 538)) 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 ########################### // ################################## End of SP CODE ###########################
i = si.nPos; i = si.nPos;
while (tmp > 0) { 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 //mbg merge 7/18/06 changed pausing check
if (FCEUI_EmulationPaused() && (mouse_x > 8) && (mouse_x < 22) && (mouse_y > 10) && (mouse_y < 538)) 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; i = si.nPos;
while (tmp > 0) { while (tmp > 0) {
if ((tmp2=opsize[GetMem(i)]) == 0) tmp2++; 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 //mbg merge 7/18/06 changed pausing check
if (FCEUI_EmulationPaused() && (mouse_x > 8) && (mouse_x < 22) && (mouse_y > 10) && (mouse_y < 538)) 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; i = si.nPos;
while (tmp > 0) { while (tmp > 0) {
if ((tmp2=opsize[GetMem(i)]) == 0) tmp2++; if ((tmp2=opsize[GetMem(i)]) == 0) tmp2++;
@ -1896,7 +1933,7 @@ DebugSystem* debugSystem;
DebugSystem::DebugSystem() DebugSystem::DebugSystem()
{ {
hFixedFont = CreateFont(14, 8, /*Height,Width*/ hFixedFont = CreateFont(FIXED_FONT_HEIGHT, 8, /*Height,Width*/
0,0, /*escapement,orientation*/ 0,0, /*escapement,orientation*/
FW_REGULAR,FALSE,FALSE,FALSE, /*weight, italic, underline, strikeout*/ FW_REGULAR,FALSE,FALSE,FALSE, /*weight, italic, underline, strikeout*/
ANSI_CHARSET,OUT_DEVICE_PRECIS,CLIP_MASK, /*charset, precision, clipping*/ ANSI_CHARSET,OUT_DEVICE_PRECIS,CLIP_MASK, /*charset, precision, clipping*/

View File

@ -5,6 +5,9 @@
#include <windows.h> #include <windows.h>
//#include "debug.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 // TODO: Maybe change breakpoint array to std::vector
// Maximum number of breakpoints supported // Maximum number of breakpoints supported
#define MAXIMUM_NUMBER_OF_BREAKPOINTS 64 #define MAXIMUM_NUMBER_OF_BREAKPOINTS 64
@ -28,6 +31,7 @@ void UpdatePatcher(HWND hwndDlg);
int GetEditHex(HWND hwndDlg, int id); int GetEditHex(HWND hwndDlg, int id);
extern void AddBreakList(); extern void AddBreakList();
extern char* BreakToText(unsigned int num);
void UpdateDebugger(); void UpdateDebugger();
void DoDebug(uint8 halt); void DoDebug(uint8 halt);

View File

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

View File

@ -1,5 +1,6 @@
#include <stdlib.h> #include <stdlib.h>
#include "common.h" #include "common.h"
#include "tracer.h"
static HWND logwin = 0; static HWND logwin = 0;
@ -209,7 +210,7 @@ void AddLogText(const char *text, unsigned int add_newline)
} }
// Add a final newline if requested // Add a final newline if requested
if(add_newline) if (add_newline)
{ {
*msg_iterator = '\r'; *msg_iterator = '\r';
msg_iterator++; msg_iterator++;
@ -220,6 +221,13 @@ void AddLogText(const char *text, unsigned int add_newline)
// Terminating 0-byte // Terminating 0-byte
*msg_iterator = 0; *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 // Keep track of the added log
logcount++; logcount++;

View File

@ -200,7 +200,7 @@ void InitControls(HWND hwndDlg)
LOGFONT lf; LOGFONT lf;
HFONT hFont = (HFONT)SendMessage(hwndDlg, WM_GETFONT, 0, 0); HFONT hFont = (HFONT)SendMessage(hwndDlg, WM_GETFONT, 0, 0);
GetObject(hFont, sizeof(LOGFONT), &lf); GetObject(hFont, sizeof(LOGFONT), &lf);
strcpy(lf.lfFaceName,"Courier"); strcpy(lf.lfFaceName,"Courier New");
hNewFont = CreateFontIndirect(&lf); 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" ); // 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 PC",IDC_DEBUGGER_SEEK_PC,391,71,39,14
PUSHBUTTON "Seek To:",IDC_DEBUGGER_SEEK_TO,350,54,38,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_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 "PPU:",65531,352,179,17,10
LTEXT "Sprite:",65530,352,191,20,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 LTEXT "Scanline:",IDC_STATIC,352,203,31,8
EDITTEXT IDC_DEBUGGER_VAL_SPR,374,191,15,12,ES_UPPERCASE | ES_READONLY | ES_WANTRETURN | NOT WS_BORDER,WS_EX_TRANSPARENT 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 "",IDC_DEBUGGER_ADDR_LINE,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,4,308,341,11
CONTROL "Break on Bad Opcode",IDC_DEBUGGER_BREAK_ON_BAD_OP, CONTROL "Break on Bad Opcode",IDC_DEBUGGER_BREAK_ON_BAD_OP,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,438,125,89,10 "Button",BS_AUTOCHECKBOX | WS_TABSTOP,438,125,89,10
@ -1141,13 +1143,11 @@ BEGIN
LTEXT "Default window size",IDC_STATIC,364,308,68,9 LTEXT "Default window size",IDC_STATIC,364,308,68,9
PUSHBUTTON "Run Line",IDC_DEBUGGER_RUN_LINE,350,37,38,14 PUSHBUTTON "Run Line",IDC_DEBUGGER_RUN_LINE,350,37,38,14
PUSHBUTTON "128 Lines",IDC_DEBUGGER_RUN_FRAME2,391,37,39,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 ".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 CONTROL "Auto-open",DEBUGAUTOLOAD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,438,306,47,13
LTEXT "CPU cycles:",IDC_STATIC,402,179,39,8 LTEXT "CPU cycles:",IDC_STATIC,402,179,39,8
PUSHBUTTON "Reset counters",IDC_DEBUGGER_RESET_COUNTERS,471,229,64,14 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 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 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 LTEXT "Instructions:",IDC_STATIC,402,204,40,8
CONTROL "Break when exceed",IDC_DEBUGGER_BREAK_ON_INSTRUCTIONS, 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 CONTROL "Display ROM offsets",IDC_DEBUGGER_ROM_OFFSETS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,442,249,82,10
END 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 STYLE DS_SETFONT | DS_MODALFRAME | DS_3DLOOK | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Trace Logger" CAPTION "Trace Logger"
FONT 8, "MS Sans Serif", 400, 0, 0x0 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 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 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 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 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 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, 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 "Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,18,243,126,10
CONTROL "Log Processor Status Flags",IDC_CHECK_LOG_PROCESSOR_STATUS, CONTROL "Log Processor Status flags",IDC_CHECK_LOG_PROCESSOR_STATUS,
"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,148,243,102,10 "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 PUSHBUTTON "Browse...",IDC_BTN_LOG_BROWSE,66,212,45,14,BS_CENTER | BS_VCENTER
LTEXT "",IDC_TRACER_STATS,121,213,246,12 LTEXT "",IDC_TRACER_STATS,121,213,246,12
CONTROL "Only log newly mapped code",IDC_CHECK_LOG_NEW_INSTRUCTIONS, CONTROL "Only log newly mapped code",IDC_CHECK_LOG_NEW_INSTRUCTIONS,
"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,18,284,107,10 "Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,18,298,107,10
GROUPBOX "Extra Log Options that work with the Code/Data Logger",113,12,272,378,40 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, 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, CONTROL "Automatically update Window while logging",IDC_CHECK_LOG_UPDATE_WINDOW,
"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,202,195,156,10 "Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,202,195,156,10
CONTROL "Use Stack Pointer for lines tabbing (nesting visualization)",IDC_CHECK_LINES_TABBING, CONTROL "Use Stack Pointer for code tabbing (nesting visualization)",IDC_CHECK_CODE_TABBING,
"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,18,256,197,10 "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, 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 END
ADDBP DIALOGEX 66, 83, 196, 130 ADDBP DIALOGEX 66, 83, 196, 130

View File

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

View File

@ -718,6 +718,27 @@ void PIANO_ROLL::update()
} }
break; 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 // update MarkerDragBox when it's flying away
if (hwndMarkerDragBox && drag_mode != DRAG_MODE_MARKER) 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 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() void PIANO_ROLL::DragPlaybackCursor()
{ {
@ -1767,6 +1797,7 @@ LRESULT APIENTRY ListWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
else else
selection.SetRegionSelection(row_index, selection_beginning + 1); selection.SetRegionSelection(row_index, selection_beginning + 1);
} }
piano_roll.StartSelectingDrag(row_index);
} else if (alt_pressed) } else if (alt_pressed)
{ {
// make Selection by Pattern // make Selection by Pattern
@ -1779,18 +1810,30 @@ LRESULT APIENTRY ListWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
else else
selection.SetRegionSelectionPattern(row_index, selection_beginning); 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) } 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)) if (selection.GetRowSelection(row_index))
{
selection.ClearRowSelection(row_index); selection.ClearRowSelection(row_index);
else piano_roll.StartDeselectingDrag(row_index);
} else
{
selection.SetRowSelection(row_index); selection.SetRowSelection(row_index);
piano_roll.StartSelectingDrag(row_index);
}
} else // just click } else // just click
{ {
selection.ClearSelection(); selection.ClearSelection();
selection.SetRowSelection(row_index); selection.SetRowSelection(row_index);
piano_roll.StartSelectingDrag(row_index);
} }
piano_roll.StartSelectingDrag(row_index);
} }
} }
} else if (column_index >= COLUMN_JOYPAD1_A && column_index <= COLUMN_JOYPAD4_R) } else if (column_index >= COLUMN_JOYPAD1_A && column_index <= COLUMN_JOYPAD4_R)

View File

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

View File

@ -430,6 +430,27 @@ void SELECTION::AddNewSelectionToHistory()
// add // add
selections_history[(history_start_pos + history_cursor_pos) % history_size] = selectionFrames; 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) void SELECTION::JumpInTime(int new_pos)
{ {

View File

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

View File

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

View File

@ -43,15 +43,28 @@ using namespace std;
//#define LOG_SKIP_UNMAPPED 4 //#define LOG_SKIP_UNMAPPED 4
//#define LOG_ADD_PERIODS 8 //#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 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 log_update_window = 0;
//int tracer_open=0; //int tracer_open=0;
volatile int logtofile = 0, logging = 0; volatile int logtofile = 0, logging = 0;
HWND hTracer; HWND hTracer;
HFONT hlogFont, hlogNewFont; int log_optn_intlst[LOG_OPTION_SIZE] = {3000000, 1000000, 300000, 100000, 30000, 10000, 3000, 1000, 300, 100};
int log_optn_intlst[LOG_OPTION_SIZE] = {10000,8000,6000,4000,2000,1000,700,400,200,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"};
char *log_optn_strlst[LOG_OPTION_SIZE] = {"10000","8000","6000","4000","2000","1000","700","400","200","100"}; int log_lines_option = 5; // 10000 lines by default
char *logfilename = 0; char *logfilename = 0;
int oldcodecount, olddatacount; int oldcodecount, olddatacount;
@ -60,11 +73,14 @@ char **tracelogbuf;
int tracelogbufsize, tracelogbufpos; int tracelogbufsize, tracelogbufpos;
int tracelogbufusedsize; int tracelogbufusedsize;
bool tracer_lines_tabbing = true; char str_axystate[LOG_AXYSTATE_MAX_LEN] = {0}, str_procstatus[LOG_PROCSTATUS_MAX_LEN] = {0};
bool tracer_statuses_to_the_left = false; 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 bool JustFrameAdvanced;
extern int currFrameCounter;
FILE *LOG_FP; FILE *LOG_FP;
@ -73,7 +89,6 @@ int Tracer_wndx=0, Tracer_wndy=0;
void ShowLogDirDialog(void); void ShowLogDirDialog(void);
void BeginLoggingSequence(void); void BeginLoggingSequence(void);
void LogInstruction(void); void LogInstruction(void);
void OutputLogLine(char *str);
void EndLoggingSequence(void); void EndLoggingSequence(void);
//void PauseLoggingSequence(void); //void PauseLoggingSequence(void);
void UpdateLogWindow(void); void UpdateLogWindow(void);
@ -84,61 +99,69 @@ int PromptForCDLogger(void);
BOOL CALLBACK TracerCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) BOOL CALLBACK TracerCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{ {
int i; int i;
LOGFONT lf; switch(uMsg)
switch(uMsg) { {
case WM_MOVE: { case WM_MOVE:
if (!IsIconic(hwndDlg)) { {
RECT wrect; if (!IsIconic(hwndDlg))
GetWindowRect(hwndDlg,&wrect); {
Tracer_wndx = wrect.left; RECT wrect;
Tracer_wndy = wrect.top; GetWindowRect(hwndDlg,&wrect);
Tracer_wndx = wrect.left;
#ifdef WIN32 Tracer_wndy = wrect.top;
WindowBoundsCheckNoResize(Tracer_wndx,Tracer_wndy,wrect.right); WindowBoundsCheckNoResize(Tracer_wndx,Tracer_wndy,wrect.right);
#endif
} }
break; break;
}; }
case WM_INITDIALOG: case WM_INITDIALOG:
{
if (Tracer_wndx==-32000) Tracer_wndx=0; //Just in case if (Tracer_wndx==-32000) Tracer_wndx=0; //Just in case
if (Tracer_wndy==-32000) Tracer_wndy=0; if (Tracer_wndy==-32000) Tracer_wndy=0;
SetWindowPos(hwndDlg,0,Tracer_wndx,Tracer_wndy,0,0,SWP_NOSIZE|SWP_NOZORDER|SWP_NOOWNERZORDER); SetWindowPos(hwndDlg,0,Tracer_wndx,Tracer_wndy,0,0,SWP_NOSIZE|SWP_NOZORDER|SWP_NOOWNERZORDER);
hTracer = hwndDlg; hTracer = hwndDlg;
//setup font // setup font
hlogFont = (HFONT)SendMessage(hwndDlg, WM_GETFONT, 0, 0); SendDlgItemMessage(hwndDlg, IDC_TRACER_LOG, WM_SETFONT, (WPARAM)debugSystem->hFixedFont, FALSE);
GetObject(hlogFont, sizeof(LOGFONT), &lf);
strcpy(lf.lfFaceName,"Courier New"); // calculate tracesi.nPage
hlogNewFont = CreateFontIndirect(&lf); RECT wrect;
SendDlgItemMessage(hwndDlg,IDC_TRACER_LOG,WM_SETFONT,(WPARAM)hlogNewFont,FALSE); GetClientRect(GetDlgItem(hwndDlg, IDC_TRACER_LOG), &wrect);
tracesi.nPage = wrect.bottom / debugSystem->fixedFontHeight;
//check the disabled radio button //check the disabled radio button
CheckRadioButton(hwndDlg,IDC_RADIO_LOG_LAST,IDC_RADIO_LOG_TO_FILE,IDC_RADIO_LOG_LAST); CheckRadioButton(hwndDlg,IDC_RADIO_LOG_LAST,IDC_RADIO_LOG_TO_FILE,IDC_RADIO_LOG_LAST);
//EnableWindow(GetDlgItem(hwndDlg,IDC_SCRL_TRACER_LOG),FALSE); //EnableWindow(GetDlgItem(hwndDlg,IDC_SCRL_TRACER_LOG),FALSE);
//fill in the options for the log size //fill in the options for the log size
for(i = 0;i < LOG_OPTION_SIZE;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_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."); SetDlgItemText(hwndDlg, IDC_TRACER_LOG, "Welcome to the Trace Logger.");
logtofile = 0; 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_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); CheckDlgButton(hwndDlg, IDC_CHECK_LOG_PROCESSOR_STATUS, (logging_options & LOG_PROCESSOR_STATUS) ? BST_CHECKED : BST_UNCHECKED);
EnableWindow(GetDlgItem(hwndDlg,IDC_TRACER_LOG_SIZE),TRUE); CheckDlgButton(hwndDlg, IDC_CHECK_LOG_NEW_INSTRUCTIONS, (logging_options & LOG_NEW_INSTRUCTIONS) ? BST_CHECKED : BST_UNCHECKED);
EnableWindow(GetDlgItem(hwndDlg,IDC_BTN_LOG_BROWSE),FALSE); 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); CheckDlgButton(hwndDlg, IDC_CHECK_LOG_UPDATE_WINDOW, log_update_window ? BST_CHECKED : BST_UNCHECKED);
EnableTracerMenuItems(); EnableTracerMenuItems();
break; break;
}
case WM_CLOSE: case WM_CLOSE:
case WM_QUIT: case WM_QUIT:
if(logging)EndLoggingSequence(); if(logging)
DeleteObject(hlogNewFont); EndLoggingSequence();
logging_options &= 3;
hTracer = 0; hTracer = 0;
EndDialog(hwndDlg,0); EndDialog(hwndDlg,0);
break; break;
@ -161,30 +184,48 @@ BOOL CALLBACK TracerCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
break; break;
case IDC_CHECK_LOG_REGISTERS: case IDC_CHECK_LOG_REGISTERS:
logging_options ^= LOG_REGISTERS; logging_options ^= LOG_REGISTERS;
CheckDlgButton(hwndDlg, IDC_CHECK_LOG_REGISTERS, (logging_options & LOG_REGISTERS) ? BST_CHECKED : BST_UNCHECKED);
break; break;
case IDC_CHECK_LOG_PROCESSOR_STATUS: case IDC_CHECK_LOG_PROCESSOR_STATUS:
logging_options ^= 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; break;
case IDC_CHECK_LOG_STATUSES_TO_THE_LEFT: 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; break;
case IDC_CHECK_LINES_TABBING: case IDC_CHECK_LOG_FRAME_NUMBER:
tracer_lines_tabbing ^= 1; 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; break;
case IDC_CHECK_LOG_NEW_INSTRUCTIONS: case IDC_CHECK_LOG_NEW_INSTRUCTIONS:
logging_options ^= LOG_NEW_INSTRUCTIONS; logging_options ^= LOG_NEW_INSTRUCTIONS;
if(logging && (!PromptForCDLogger())){ if(logging && (!PromptForCDLogger()))
logging_options ^= LOG_NEW_INSTRUCTIONS; //turn it back off logging_options &= ~LOG_NEW_INSTRUCTIONS; //turn it back off
CheckDlgButton(hTracer, IDC_CHECK_LOG_NEW_INSTRUCTIONS, BST_UNCHECKED); CheckDlgButton(hwndDlg, IDC_CHECK_LOG_NEW_INSTRUCTIONS, (logging_options & LOG_NEW_INSTRUCTIONS) ? BST_CHECKED : BST_UNCHECKED);
}
//EnableTracerMenuItems(); //EnableTracerMenuItems();
break; break;
case IDC_CHECK_LOG_NEW_DATA: case IDC_CHECK_LOG_NEW_DATA:
logging_options ^= LOG_NEW_DATA; logging_options ^= LOG_NEW_DATA;
if(logging && (!PromptForCDLogger())){ if(logging && (!PromptForCDLogger()))
logging_options ^= LOG_NEW_DATA; //turn it back off logging_options &= ~LOG_NEW_DATA; //turn it back off
CheckDlgButton(hTracer, IDC_CHECK_LOG_NEW_DATA, BST_UNCHECKED); CheckDlgButton(hwndDlg, IDC_CHECK_LOG_NEW_DATA, (logging_options & LOG_NEW_DATA) ? BST_CHECKED : BST_UNCHECKED);
}
break; break;
case IDC_CHECK_LOG_UPDATE_WINDOW: 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() if(!FCEUI_EmulationPaused() && !log_update_window) break; //mbg merge 7/19/06 changd to use EmulationPaused()
GetScrollInfo((HWND)lParam,SB_CTL,&tracesi); GetScrollInfo((HWND)lParam,SB_CTL,&tracesi);
switch(LOWORD(wParam)) { switch(LOWORD(wParam))
{
case SB_ENDSCROLL: case SB_ENDSCROLL:
case SB_TOP: case SB_TOP:
case SB_BOTTOM: break; case SB_BOTTOM: break;
case SB_LINEUP: tracesi.nPos--; break; case SB_LINEUP: tracesi.nPos--; break;
case SB_LINEDOWN:tracesi.nPos++; break; case SB_LINEDOWN:tracesi.nPos++; break;
case SB_PAGEUP: tracesi.nPos-=tracesi.nPage; break; case SB_PAGEUP: tracesi.nPos -= tracesi.nPage; break;
case SB_PAGEDOWN: tracesi.nPos+=tracesi.nPage; break; case SB_PAGEDOWN: tracesi.nPos += tracesi.nPage; break;
case SB_THUMBPOSITION: //break; case SB_THUMBPOSITION: //break;
case SB_THUMBTRACK: tracesi.nPos = tracesi.nTrackPos; 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)
if((tracesi.nPos+(int)tracesi.nPage) > tracesi.nMax) tracesi.nPos = tracesi.nMax-(int)tracesi.nPage; //mbg merge 7/19/06 added casts tracesi.nPos = tracesi.nMax - (int)tracesi.nPage;
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 < tracesi.nMin)
tracesi.nPos = tracesi.nMin;
SetScrollInfo((HWND)lParam,SB_CTL,&tracesi,TRUE); SetScrollInfo((HWND)lParam,SB_CTL,&tracesi,TRUE);
UpdateLogText(); 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 fprintf(LOG_FP,FCEU_NAME_AND_VERSION" - Trace Log File\n"); //mbg merge 7/19/06 changed string
} else } 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"); strcpy(str,"Allocating Memory...\r\n");
SetDlgItemText(hTracer, IDC_TRACER_LOG, str); 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 tracelogbuf = (char**)malloc(j*sizeof(char *)); //mbg merge 7/19/06 added cast
for(i = 0;i < j;i++) for(i = 0;i < j;i++)
{ {
@ -332,83 +378,132 @@ done:
}*/ }*/
//todo: really speed this up //todo: really speed this up
void FCEUD_TraceInstruction(){ void FCEUD_TraceInstruction()
if(!logging) return; {
if (!logging)
return;
char str_tabs[LOG_TABS_MASK+1], address[7], data[11], disassembly[LOG_DISASSEMBLY_MAX_LEN], axystate[21], procstatus[12]; unsigned int addr = X.PC;
char str[LOG_LINE_MAX_LEN];
int addr=X.PC;
int size, j; int size, j;
uint8 opcode[3], tmp; uint8 opcode[3], tmp;
static int unloggedlines; static int unloggedlines;
if(((logging_options & LOG_NEW_INSTRUCTIONS) && (oldcodecount != codecount)) || 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; oldcodecount = codecount;
olddatacount = datacount; olddatacount = datacount;
if(unloggedlines > 0){ if(unloggedlines > 0)
sprintf(str,"(%d lines skipped)",unloggedlines); {
OutputLogLine(str); sprintf(str_temp, "(%d lines skipped)", unloggedlines);
OutputLogLine(str_temp);
unloggedlines = 0; unloggedlines = 0;
} }
} else {
if((logging_options & LOG_NEW_INSTRUCTIONS) ||
(logging_options & LOG_NEW_DATA)){
if(FCEUI_GetLoggingCD())unloggedlines++;
return;
}
}
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");
} else } else
{ {
switch(size) if((logging_options & LOG_NEW_INSTRUCTIONS) ||
(logging_options & LOG_NEW_DATA))
{
if(FCEUI_GetLoggingCD())
unloggedlines++;
return;
}
}
sprintf(str_address, "$%04X:", addr);
size = opsize[GetMem(addr)];
if ((addr+size) > 0xFFFF)
{
sprintf(str_data, "%02X ", GetMem(addr&0xFFFF));
sprintf(str_disassembly, "OVERFLOW");
} else
{
char* a;
switch (size)
{ {
case 0: case 0:
sprintf(data, "%02X ", GetMem(addr)); sprintf(str_data, "%02X ", GetMem(addr));
sprintf(disassembly,"UNDEFINED"); sprintf(str_disassembly,"UNDEFINED");
break; break;
case 1: case 1:
opcode[0]=GetMem(addr++); opcode[0]=GetMem(addr++);
sprintf(data, "%02X ", opcode[0]); sprintf(str_data, "%02X ", opcode[0]);
strcpy(disassembly,Disassemble(addr,opcode)); a = Disassemble(addr, opcode);
break; break;
case 2: case 2:
opcode[0]=GetMem(addr++); opcode[0]=GetMem(addr++);
opcode[1]=GetMem(addr++); opcode[1]=GetMem(addr++);
sprintf(data, "%02X %02X ", opcode[0],opcode[1]); sprintf(str_data, "%02X %02X ", opcode[0],opcode[1]);
strcpy(disassembly,Disassemble(addr,opcode)); a = Disassemble(addr, opcode);
break; break;
case 3: case 3:
opcode[0]=GetMem(addr++); opcode[0]=GetMem(addr++);
opcode[1]=GetMem(addr++); opcode[1]=GetMem(addr++);
opcode[2]=GetMem(addr++); opcode[2]=GetMem(addr++);
sprintf(data, "%02X %02X %02X ", opcode[0],opcode[1],opcode[2]); sprintf(str_data, "%02X %02X %02X ", opcode[0],opcode[1],opcode[2]);
strcpy(disassembly,Disassemble(addr,opcode)); a = Disassemble(addr, opcode);
break; 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. //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] = ' '; for(j = strlen(str_disassembly);j < LOG_DISASSEMBLY_MAX_LEN - 1;j++)
disassembly[LOG_DISASSEMBLY_MAX_LEN - 1] = 0; str_disassembly[j] = ' ';
str_disassembly[LOG_DISASSEMBLY_MAX_LEN - 1] = 0;
} }
if(logging_options & LOG_REGISTERS){ // Start filling the str_temp line: Frame number, AXYS state, Processor status, Tabs, Address, Data, Disassembly
sprintf(axystate,"A:%02X X:%02X Y:%02X S:%02X",(X.A),(X.X),(X.Y),(X.S));
if (logging_options & LOG_FRAME_NUMBER)
{
sprintf(str_temp, "%06u: ", currFrameCounter);
} else
{
str_temp[0] = 0;
}
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){ if (logging_options & LOG_PROCESSOR_STATUS)
{
tmp = X.P^0xFF; 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, 'N'|(tmp&0x80)>>2,
'V'|(tmp&0x40)>>1, 'V'|(tmp&0x40)>>1,
'U'|(tmp&0x20), '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) if (logging_options & LOG_REGISTERS)
strcat(str, axystate); strcat(str_temp, str_axystate);
if ((logging_options & LOG_REGISTERS) && (logging_options & LOG_PROCESSOR_STATUS))
strcat(str, " ");
if (logging_options & LOG_PROCESSOR_STATUS) if (logging_options & LOG_PROCESSOR_STATUS)
strcat(str, procstatus); strcat(str_temp, str_procstatus);
if ((logging_options & LOG_REGISTERS) || (logging_options & LOG_PROCESSOR_STATUS))
strcat(str, " ");
} }
if (tracer_lines_tabbing) if (logging_options & LOG_CODE_TABBING)
{ {
// add spaces at the beginning of the line according to stack pointer // add spaces at the beginning of the line according to stack pointer
int spaces = (0xFF - X.S) & LOG_TABS_MASK; int spaces = (0xFF - X.S) & LOG_TABS_MASK;
for (int i = 0; i < spaces; i++) for (int i = 0; i < spaces; i++)
str_tabs[i] = ' '; str_tabs[i] = ' ';
str_tabs[spaces] = 0; str_tabs[spaces] = 0;
strcat(str, str_tabs); strcat(str_temp, str_tabs);
} }
strcat(str, address); strcat(str_temp, str_address);
strcat(str, data); strcat(str_temp, str_data);
strcat(str, disassembly); strcat(str_temp, str_disassembly);
if (!tracer_statuses_to_the_left) if (!(logging_options & LOG_TO_THE_LEFT))
{ {
if (logging_options & LOG_REGISTERS) if (logging_options & LOG_REGISTERS)
strcat(str,axystate); strcat(str_temp, str_axystate);
if ((logging_options & LOG_REGISTERS) && (logging_options & LOG_PROCESSOR_STATUS))
strcat(str," ");
if (logging_options & LOG_PROCESSOR_STATUS) if (logging_options & LOG_PROCESSOR_STATUS)
strcat(str,procstatus); strcat(str_temp, str_procstatus);
} }
OutputLogLine(str); OutputLogLine(str_temp);
return; return;
} }
void OutputLogLine(char *str){ void OutputLogLine(const char *str, bool add_newline)
if(logtofile){ {
strcat(str,"\n"); if(logtofile)
fputs(str,LOG_FP); {
fputs(str, LOG_FP);
if (add_newline)
fputs("\n", LOG_FP);
fflush(LOG_FP); fflush(LOG_FP);
}else{ } else
strcat(str,"\r\n"); {
if(strlen(str) < LOG_LINE_MAX_LEN) if (add_newline)
strcpy(tracelogbuf[tracelogbufpos],str); {
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++; tracelogbufpos++;
if(tracelogbufusedsize < tracelogbufsize)tracelogbufusedsize++; if (tracelogbufusedsize < tracelogbufsize)
tracelogbufpos%=tracelogbufsize; tracelogbufusedsize++;
tracelogbufpos %= tracelogbufsize;
} }
} }
@ -496,34 +596,35 @@ void EndLoggingSequence(void){
//void PauseLoggingSequence(void){ //void PauseLoggingSequence(void){
void UpdateLogWindow(void) void UpdateLogWindow(void)
{ {
//we don't want to continue if the trace logger isn't logging, or if its logging to a file. //we don't want to continue if the trace logger isn't logging, or if its logging to a file.
if ((!logging) || logtofile) if ((!logging) || logtofile)
return; return;
// only update the window when some emulation occured // only update the window when some emulation occured
// and only update the window when emulator is paused or log_update_window=true // and only update the window when emulator is paused or log_update_window=true
bool emu_paused = (FCEUI_EmulationPaused() != 0); 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; return;
} }
old_emu_paused = emu_paused; log_old_emu_paused = emu_paused;
tracesi.cbSize = sizeof(SCROLLINFO); tracesi.cbSize = sizeof(SCROLLINFO);
tracesi.fMask = SIF_ALL; tracesi.fMask = SIF_ALL;
tracesi.nPage = 21;
tracesi.nMin = 0; tracesi.nMin = 0;
tracesi.nMax = tracelogbufusedsize; //todo: try -2 tracesi.nMax = tracelogbufusedsize;
tracesi.nPos = tracesi.nMax-tracesi.nPage; tracesi.nPos = tracesi.nMax - tracesi.nPage;
if (tracesi.nPos < tracesi.nMin) tracesi.nPos = tracesi.nMin; if (tracesi.nPos < tracesi.nMin)
tracesi.nPos = tracesi.nMin;
SetScrollInfo(GetDlgItem(hTracer,IDC_SCRL_TRACER_LOG),SB_CTL,&tracesi,TRUE); SetScrollInfo(GetDlgItem(hTracer,IDC_SCRL_TRACER_LOG),SB_CTL,&tracesi,TRUE);
UpdateLogText(); UpdateLogText();
return; return;
} }
void UpdateLogText(void){ void UpdateLogText(void)
{
int i, j; int i, j;
char str[3000]; char str[3000];
str[0] = 0; 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; j = i;
if(tracelogbufusedsize == tracelogbufsize){ if(tracelogbufusedsize == tracelogbufsize)
{
j = (tracelogbufpos+i)%tracelogbufsize; j = (tracelogbufpos+i)%tracelogbufsize;
} }
strcat(str,tracelogbuf[j]); strcat(str,tracelogbuf[j]);

View File

@ -1,20 +1,43 @@
#define LOG_OPTION_SIZE 10 #define LOG_OPTION_SIZE 10
#define LOG_REGISTERS 1 #define LOG_REGISTERS 1
#define LOG_PROCESSOR_STATUS 2 #define LOG_PROCESSOR_STATUS 2
#define LOG_NEW_INSTRUCTIONS 4 #define LOG_NEW_INSTRUCTIONS 4
#define LOG_NEW_DATA 8 #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_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 HWND hTracer;
extern int log_update_window; extern int log_update_window;
extern volatile int logtofile, logging; extern volatile int logtofile, logging;
extern int logging_options; extern int logging_options;
extern bool log_old_emu_paused;
void EnableTracerMenuItems(void); void EnableTracerMenuItems(void);
void LogInstruction(void); void LogInstruction(void);
void DoTracer(); void DoTracer();
//void PauseLoggingSequence(); //void PauseLoggingSequence();
void UpdateLogWindow(void); 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 //skip initiates frame skip if 1, or frame skip and sound skip if 2
int r,ssize; int r,ssize;
#ifdef WIN32
UpdateLogWindow();
#endif
JustFrameAdvanced = false; JustFrameAdvanced = false;
if (frameAdvanceRequested) if (frameAdvanceRequested)