~ubuntu-branches/ubuntu/vivid/fceux/vivid

« back to all changes in this revision

Viewing changes to src/drivers/win/tracer.cpp

  • Committer: Package Import Robot
  • Author(s): Joe Nahmias
  • Date: 2014-03-02 19:22:04 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20140302192204-9f0aehi5stfnhn7d
Tags: 2.2.2+dfsg0-1
* Imported Upstream version 2.2.2
  + remove patches merged upstream; refresh remaining
  + remove windows compiled help files and non-free Visual C files
* Use C++11 standard static assertion functionality
* fix upstream installation of support files
* New patch 0004-ignore-missing-windows-help-CHM-file.patch
* update d/copyright for new, renamed, deleted files
* d/control: bump std-ver to 3.9.5, no changes needed

Show diffs side-by-side

added added

removed removed

Lines of Context:
33
33
#include "tracer.h"
34
34
#include "memview.h"
35
35
#include "main.h" //for GetRomName()
 
36
#include "utils/xstring.h"
36
37
 
37
38
//Used to determine the current hotkey mapping for the pause key in order to display on the dialog
38
39
#include "mapinput.h"
50
51
extern Name* lastBankNames;
51
52
extern Name* loadedBankNames;
52
53
extern Name* ramBankNames;
53
 
extern int lastBank;
54
 
extern int loadedBank;
55
 
extern int myNumWPs;
56
54
 
57
55
// ################################## End of SP CODE ###########################
58
56
 
61
59
int log_update_window = 0;
62
60
//int tracer_open=0;
63
61
volatile int logtofile = 0, logging = 0;
 
62
 
64
63
HWND hTracer;
 
64
bool tracerIsReadyForResizing = false;
 
65
int tracerMinWidth = 0;
 
66
int tracerMinHeight = 0;
 
67
int Tracer_wndx = 0, Tracer_wndy = 0;
 
68
int Tracer_wndWidth = 640, Tracer_wndHeight = 500;
 
69
int tracerInitialClientWidth = 0, tracerInitialClientHeight = 0;
 
70
int tracerCurrentClientWidth = 0, tracerCurrentClientHeight = 0;
 
71
 
 
72
// this structure stores the data of an existing window pos and how it should be resized. The data is calculated at runtime
 
73
struct WindowItemPosData
 
74
{
 
75
        HWND itemHWND;
 
76
        int initialLeft;
 
77
        int initialTop;
 
78
        int initialRight;
 
79
        int initialBottom;
 
80
        unsigned int leftResizeType;
 
81
        unsigned int topResizeType;
 
82
        unsigned int rightResizeType;
 
83
        unsigned int bottomResizeType;
 
84
};
 
85
std::vector<WindowItemPosData> arrayOfWindowItemPosData;        // the data is filled in WM_INITDIALOG
 
86
 
 
87
// this structure holds the data how a known item should be resized. The data is prepared
 
88
struct KnownWindowItemPosData
 
89
{
 
90
        int id;
 
91
        unsigned int leftResizeType;
 
92
        unsigned int topResizeType;
 
93
        unsigned int rightResizeType;
 
94
        unsigned int bottomResizeType;
 
95
};
 
96
//  not all window items have to be mentioned here, others will be resized by default method (WINDOW_ITEM_RESIZE_TYPE_MULTIPLY, WINDOW_ITEM_RESIZE_TYPE_RIGHT_ALIGNED, WINDOW_ITEM_RESIZE_TYPE_MULTIPLY, WINDOW_ITEM_RESIZE_TYPE_RIGHT_ALIGNED)
 
97
KnownWindowItemPosData tracerKnownWindowItems[] = {
 
98
        IDC_TRACER_LOG, WINDOW_ITEM_RESIZE_TYPE_LEFT_ALIGNED, WINDOW_ITEM_RESIZE_TYPE_LEFT_ALIGNED, WINDOW_ITEM_RESIZE_TYPE_RIGHT_ALIGNED, WINDOW_ITEM_RESIZE_TYPE_RIGHT_ALIGNED,
 
99
        IDC_SCRL_TRACER_LOG, WINDOW_ITEM_RESIZE_TYPE_RIGHT_ALIGNED, WINDOW_ITEM_RESIZE_TYPE_LEFT_ALIGNED, WINDOW_ITEM_RESIZE_TYPE_RIGHT_ALIGNED, WINDOW_ITEM_RESIZE_TYPE_RIGHT_ALIGNED,
 
100
        IDC_BTN_START_STOP_LOGGING, WINDOW_ITEM_RESIZE_TYPE_CENTER_ALIGNED, WINDOW_ITEM_RESIZE_TYPE_RIGHT_ALIGNED, WINDOW_ITEM_RESIZE_TYPE_CENTER_ALIGNED, WINDOW_ITEM_RESIZE_TYPE_RIGHT_ALIGNED,
 
101
        IDC_RADIO_LOG_LAST, WINDOW_ITEM_RESIZE_TYPE_LEFT_ALIGNED, WINDOW_ITEM_RESIZE_TYPE_RIGHT_ALIGNED, WINDOW_ITEM_RESIZE_TYPE_LEFT_ALIGNED, WINDOW_ITEM_RESIZE_TYPE_RIGHT_ALIGNED,
 
102
        IDC_TRACER_LOG_SIZE, WINDOW_ITEM_RESIZE_TYPE_LEFT_ALIGNED, WINDOW_ITEM_RESIZE_TYPE_RIGHT_ALIGNED, WINDOW_ITEM_RESIZE_TYPE_LEFT_ALIGNED, WINDOW_ITEM_RESIZE_TYPE_RIGHT_ALIGNED,
 
103
        IDC_TEXT_LINES_TO_THIS_WINDOW, WINDOW_ITEM_RESIZE_TYPE_LEFT_ALIGNED, WINDOW_ITEM_RESIZE_TYPE_RIGHT_ALIGNED, WINDOW_ITEM_RESIZE_TYPE_LEFT_ALIGNED, WINDOW_ITEM_RESIZE_TYPE_RIGHT_ALIGNED,
 
104
        IDC_RADIO_LOG_TO_FILE, WINDOW_ITEM_RESIZE_TYPE_LEFT_ALIGNED, WINDOW_ITEM_RESIZE_TYPE_RIGHT_ALIGNED, WINDOW_ITEM_RESIZE_TYPE_LEFT_ALIGNED, WINDOW_ITEM_RESIZE_TYPE_RIGHT_ALIGNED,
 
105
        IDC_BTN_LOG_BROWSE, WINDOW_ITEM_RESIZE_TYPE_LEFT_ALIGNED, WINDOW_ITEM_RESIZE_TYPE_RIGHT_ALIGNED, WINDOW_ITEM_RESIZE_TYPE_LEFT_ALIGNED, WINDOW_ITEM_RESIZE_TYPE_RIGHT_ALIGNED,
 
106
};
 
107
 
65
108
int log_optn_intlst[LOG_OPTION_SIZE]  = {3000000, 1000000, 300000, 100000, 30000, 10000, 3000, 1000, 300, 100};
66
109
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"};
67
110
int log_lines_option = 5;       // 10000 lines by default
69
112
int oldcodecount, olddatacount;
70
113
 
71
114
SCROLLINFO tracesi;
72
 
char **tracelogbuf;
73
 
int tracelogbufsize, tracelogbufpos;
74
 
int tracelogbufusedsize;
 
115
 
 
116
char **tracelogbuf = 0;
 
117
std::vector<std::vector<uint16>> tracelogbufAddressesLog;
 
118
int tracelogbufsize = 0, tracelogbufpos = 0;
 
119
int tracelogbufusedsize = 0;
75
120
 
76
121
char str_axystate[LOG_AXYSTATE_MAX_LEN] = {0}, str_procstatus[LOG_PROCSTATUS_MAX_LEN] = {0};
77
122
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};
 
123
char str_result[LOG_LINE_MAX_LEN] = {0};
78
124
char str_temp[LOG_LINE_MAX_LEN] = {0};
79
 
char* tracer_decoration_name;
 
125
char str_decoration[NL_MAX_MULTILINE_COMMENT_LEN + 10] = {0};
 
126
char str_decoration_comment[NL_MAX_MULTILINE_COMMENT_LEN + 10] = {0};
80
127
char* tracer_decoration_comment;
81
 
char str_decoration[NL_MAX_MULTILINE_COMMENT_LEN + 2] = {0};
82
 
char str_decoration_comment[NL_MAX_MULTILINE_COMMENT_LEN + 2] = {0};
 
128
char* tracer_decoration_comment_end_pos;
 
129
std::vector<uint16> tempAddressesLog;
83
130
 
84
131
bool log_old_emu_paused = true;         // thanks to this flag the window only updates once after the game is paused
85
132
extern bool JustFrameAdvanced;
87
134
 
88
135
FILE *LOG_FP;
89
136
 
90
 
int Tracer_wndx=0, Tracer_wndy=0;
 
137
char trace_str[35000] = {0};
 
138
WNDPROC IDC_TRACER_LOG_oldWndProc = 0;
91
139
 
92
140
void ShowLogDirDialog(void);
93
141
void BeginLoggingSequence(void);
94
 
void EndLoggingSequence(void);
 
142
void ClearTraceLogBuf();
 
143
void EndLoggingSequence();
95
144
void UpdateLogWindow(void);
 
145
void ScrollLogWindowToLastLine();
96
146
void UpdateLogText(void);
97
147
void EnableTracerMenuItems(void);
98
148
int PromptForCDLogger(void);
99
149
 
 
150
// returns the address, or EOF if selection cursor points to something else
 
151
int Tracer_CheckClickingOnAnAddressOrSymbolicName(unsigned int lineNumber, bool onlyCheckWhenNothingSelected)
 
152
{
 
153
        if (!tracelogbufsize)
 
154
                return EOF;
 
155
 
 
156
        // trace_str contains the text in the log window
 
157
        int sel_start, sel_end;
 
158
        SendDlgItemMessage(hTracer, IDC_TRACER_LOG, EM_GETSEL, (WPARAM)&sel_start, (LPARAM)&sel_end);
 
159
        if (onlyCheckWhenNothingSelected)
 
160
                if (sel_end > sel_start)
 
161
                        return EOF;
 
162
 
 
163
        // find the "$" before sel_start
 
164
        int i = sel_start - 1;
 
165
        for (; i > sel_start - 6; i--)
 
166
                if (i >= 0 && trace_str[i] == '$')
 
167
                        break;
 
168
        if (i > sel_start - 6)
 
169
        {
 
170
                char offsetBuffer[5];
 
171
                strncpy(offsetBuffer, trace_str + i + 1, 4);
 
172
                offsetBuffer[4] = 0;
 
173
                // invalidate the string if a space or \r is found in it
 
174
                char* firstspace = strstr(offsetBuffer, " ");
 
175
                if (!firstspace)
 
176
                        firstspace = strstr(offsetBuffer, "\r");
 
177
                if (!firstspace)
 
178
                {
 
179
                        unsigned int offset;
 
180
                        if (sscanf(offsetBuffer, "%4X", &offset) != EOF)
 
181
                        {
 
182
                                // select the text
 
183
                                SendDlgItemMessage(hTracer, IDC_TRACER_LOG, EM_SETSEL, (WPARAM)(i + 1), (LPARAM)(i + 5));
 
184
                                if (hDebug)
 
185
                                        PrintOffsetToSeekAndBookmarkFields(offset);
 
186
                                return (int)offset;
 
187
                        }
 
188
                }
 
189
        }
 
190
 
 
191
        if (tracelogbufusedsize == tracelogbufsize)
 
192
                lineNumber = (tracelogbufpos + lineNumber) % tracelogbufsize;
 
193
 
 
194
        if (lineNumber < tracelogbufAddressesLog.size())
 
195
        {
 
196
                uint16 addr;
 
197
                Name* node;
 
198
                char* name;
 
199
                int nameLen;
 
200
                char* start_pos;
 
201
                char* pos;
 
202
        
 
203
                for (i = tracelogbufAddressesLog[lineNumber].size() - 1; i >= 0; i--)
 
204
                {
 
205
                        addr = tracelogbufAddressesLog[lineNumber][i];
 
206
                        node = findNode(getNamesPointerForAddress(addr), addr);
 
207
                        if (node && node->name && *(node->name))
 
208
                        {
 
209
                                name = node->name;
 
210
                                nameLen = strlen(name);
 
211
                                if (sel_start - nameLen <= 0)
 
212
                                        start_pos = trace_str;
 
213
                                else
 
214
                                        start_pos = trace_str + (sel_start - nameLen);
 
215
                                pos = strstr(start_pos, name);
 
216
                                if (pos && pos <= trace_str + sel_start)
 
217
                                {
 
218
                                        // clicked on the operand name
 
219
                                        // select the text
 
220
                                        SendDlgItemMessage(hTracer, IDC_TRACER_LOG, EM_SETSEL, (WPARAM)(int)(pos - trace_str), (LPARAM)((int)(pos - trace_str) + nameLen));
 
221
                                        if (hDebug)
 
222
                                                PrintOffsetToSeekAndBookmarkFields(addr);
 
223
                                        return (int)addr;
 
224
                                }
 
225
                        }
 
226
                }
 
227
        }
 
228
        
 
229
        return EOF;
 
230
}
 
231
 
 
232
BOOL CALLBACK IDC_TRACER_LOG_WndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
 
233
{
 
234
        switch(uMsg)
 
235
        {
 
236
                case WM_LBUTTONDBLCLK:
 
237
                {
 
238
                        int offset = Tracer_CheckClickingOnAnAddressOrSymbolicName(tracesi.nPos + (GET_Y_LPARAM(lParam) / debugSystem->fixedFontHeight), false);
 
239
                        if (offset != EOF)
 
240
                        {
 
241
                                // open Debugger at this address
 
242
                                DoDebug(0);
 
243
                                if (hDebug)
 
244
                                {
 
245
                                        Disassemble(hDebug, IDC_DEBUGGER_DISASSEMBLY, IDC_DEBUGGER_DISASSEMBLY_VSCR, offset);
 
246
                                        PrintOffsetToSeekAndBookmarkFields(offset);
 
247
                                }
 
248
                        }
 
249
                        return 0;
 
250
                }
 
251
                case WM_LBUTTONUP:
 
252
                {
 
253
                        Tracer_CheckClickingOnAnAddressOrSymbolicName(tracesi.nPos + (GET_Y_LPARAM(lParam) / debugSystem->fixedFontHeight), true);
 
254
                        break;
 
255
                }
 
256
                case WM_RBUTTONDOWN:
 
257
                {
 
258
                        // if nothing is selected, simulate Left-click
 
259
                        int sel_start, sel_end;
 
260
                        SendDlgItemMessage(hTracer, IDC_TRACER_LOG, EM_GETSEL, (WPARAM)&sel_start, (LPARAM)&sel_end);
 
261
                        if (sel_start == sel_end)
 
262
                        {
 
263
                                CallWindowProc(IDC_TRACER_LOG_oldWndProc, hwndDlg, WM_LBUTTONDOWN, wParam, lParam);
 
264
                                CallWindowProc(IDC_TRACER_LOG_oldWndProc, hwndDlg, WM_LBUTTONUP, wParam, lParam);
 
265
                                return 0;
 
266
                        }
 
267
                        break;
 
268
                }
 
269
                case WM_RBUTTONUP:
 
270
                {
 
271
                        // save current selection
 
272
                        int sel_start, sel_end;
 
273
                        SendDlgItemMessage(hTracer, IDC_TRACER_LOG, EM_GETSEL, (WPARAM)&sel_start, (LPARAM)&sel_end);
 
274
                        // simulate a click
 
275
                        CallWindowProc(IDC_TRACER_LOG_oldWndProc, hwndDlg, WM_LBUTTONDOWN, wParam, lParam);
 
276
                        CallWindowProc(IDC_TRACER_LOG_oldWndProc, hwndDlg, WM_LBUTTONUP, wParam, lParam);
 
277
                        // try bringing Symbolic Debug Naming dialog
 
278
                        int offset = Tracer_CheckClickingOnAnAddressOrSymbolicName(tracesi.nPos + (GET_Y_LPARAM(lParam) / debugSystem->fixedFontHeight), false);
 
279
                        if (offset != EOF)
 
280
                        {
 
281
                                if (DoSymbolicDebugNaming(offset, hTracer))
 
282
                                {
 
283
                                        if (hDebug)
 
284
                                                UpdateDebugger(false);
 
285
                                        if (hMemView)
 
286
                                                UpdateCaption();
 
287
                                } else
 
288
                                {
 
289
                                        // then restore old selection
 
290
                                        SendDlgItemMessage(hTracer, IDC_TRACER_LOG, EM_SETSEL, (WPARAM)sel_start, (LPARAM)sel_end);
 
291
                                }
 
292
                                return 0;
 
293
                        } else
 
294
                        {
 
295
                                // then restore old selection
 
296
                                SendDlgItemMessage(hTracer, IDC_TRACER_LOG, EM_SETSEL, (WPARAM)sel_start, (LPARAM)sel_end);
 
297
                        }
 
298
                        break;
 
299
                }
 
300
                case WM_MOUSEWHEEL:
 
301
                {
 
302
                        SendMessage(GetDlgItem(hTracer, IDC_SCRL_TRACER_LOG), uMsg, wParam, lParam);
 
303
                        return 0;
 
304
                }
 
305
        }
 
306
        return CallWindowProc(IDC_TRACER_LOG_oldWndProc, hwndDlg, uMsg, wParam, lParam);
 
307
}
 
308
 
 
309
BOOL CALLBACK TracerInitialEnumWindowsProc(HWND hwnd, LPARAM lParam)
 
310
{
 
311
        RECT rect;
 
312
        POINT p;
 
313
 
 
314
        // create new WindowItemPosData with default settings of resizing the item
 
315
        WindowItemPosData windowItemPosData;
 
316
        windowItemPosData.itemHWND = hwnd;
 
317
        GetWindowRect(hwnd, &rect);
 
318
        p.x = rect.left;
 
319
        p.y = rect.top;
 
320
        ScreenToClient(hTracer, &p);
 
321
        windowItemPosData.initialLeft = p.x;
 
322
        windowItemPosData.initialTop = p.y;
 
323
        p.x = rect.right;
 
324
        p.y = rect.bottom;
 
325
        ScreenToClient(hTracer, &p);
 
326
        windowItemPosData.initialRight = p.x;
 
327
        windowItemPosData.initialBottom = p.y;
 
328
        windowItemPosData.leftResizeType = WINDOW_ITEM_RESIZE_TYPE_MULTIPLY;
 
329
        windowItemPosData.topResizeType = WINDOW_ITEM_RESIZE_TYPE_RIGHT_ALIGNED;
 
330
        windowItemPosData.rightResizeType = WINDOW_ITEM_RESIZE_TYPE_MULTIPLY;
 
331
        windowItemPosData.bottomResizeType = WINDOW_ITEM_RESIZE_TYPE_RIGHT_ALIGNED;
 
332
 
 
333
        // try to find the info in tracerKnownWindowItems
 
334
        int controlID = GetDlgCtrlID(hwnd);
 
335
        int sizeofKnownWindowItemPosData = sizeof(KnownWindowItemPosData);
 
336
        int tracerKnownWindowItemsTotal = sizeof(tracerKnownWindowItems) / sizeofKnownWindowItemPosData;
 
337
        int i;
 
338
        for (i = 0; i < tracerKnownWindowItemsTotal; ++i)
 
339
        {
 
340
                if (tracerKnownWindowItems[i].id == controlID)
 
341
                        break;
 
342
        }
 
343
        if (i < tracerKnownWindowItemsTotal)
 
344
        {
 
345
                // this item is known, so its resizing method may differ from defaults
 
346
                windowItemPosData.leftResizeType = tracerKnownWindowItems[i].leftResizeType;
 
347
                windowItemPosData.topResizeType = tracerKnownWindowItems[i].topResizeType;
 
348
                windowItemPosData.rightResizeType = tracerKnownWindowItems[i].rightResizeType;
 
349
                windowItemPosData.bottomResizeType = tracerKnownWindowItems[i].bottomResizeType;
 
350
        }
 
351
 
 
352
        arrayOfWindowItemPosData.push_back(windowItemPosData);
 
353
        return TRUE;
 
354
}
 
355
BOOL CALLBACK TracerResizingEnumWindowsProc(HWND hwnd, LPARAM lParam)
 
356
{
 
357
        // find the data about resizing type
 
358
        for (int i = arrayOfWindowItemPosData.size() - 1; i >= 0; i--)
 
359
        {
 
360
                if (arrayOfWindowItemPosData[i].itemHWND == hwnd)
 
361
                {
 
362
                        // recalculate the coordinates according to the resizing type of the item
 
363
                        int left = recalculateResizedItemCoordinate(arrayOfWindowItemPosData[i].initialLeft, tracerInitialClientWidth, tracerCurrentClientWidth, arrayOfWindowItemPosData[i].leftResizeType);
 
364
                        int top = recalculateResizedItemCoordinate(arrayOfWindowItemPosData[i].initialTop, tracerInitialClientHeight, tracerCurrentClientHeight, arrayOfWindowItemPosData[i].topResizeType);
 
365
                        int right = recalculateResizedItemCoordinate(arrayOfWindowItemPosData[i].initialRight, tracerInitialClientWidth, tracerCurrentClientWidth, arrayOfWindowItemPosData[i].rightResizeType);
 
366
                        int bottom = recalculateResizedItemCoordinate(arrayOfWindowItemPosData[i].initialBottom, tracerInitialClientHeight, tracerCurrentClientHeight, arrayOfWindowItemPosData[i].bottomResizeType);
 
367
                        SetWindowPos(hwnd, 0, left, top, right - left, bottom - top, SWP_NOZORDER | SWP_NOOWNERZORDER);
 
368
                        return TRUE;
 
369
                }
 
370
        }
 
371
        return TRUE;
 
372
}
 
373
 
100
374
BOOL CALLBACK TracerCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
101
375
{
102
376
        int i;
103
377
        switch(uMsg)
104
378
        {
105
 
                case WM_MOVE:
106
 
                {
107
 
                        if (!IsIconic(hwndDlg))
108
 
                        {
109
 
                                RECT wrect;
110
 
                                GetWindowRect(hwndDlg,&wrect);
111
 
                                Tracer_wndx = wrect.left;
112
 
                                Tracer_wndy = wrect.top;
113
 
                                WindowBoundsCheckNoResize(Tracer_wndx,Tracer_wndy,wrect.right);
114
 
                        }
115
 
                        break;
116
 
                }
117
379
                case WM_INITDIALOG:
118
380
                {
 
381
                        hTracer = hwndDlg;
 
382
                        // calculate initial size/positions of items
 
383
                        RECT mainRect;
 
384
                        GetClientRect(hTracer, &mainRect);
 
385
                        tracerInitialClientWidth = mainRect.right;
 
386
                        tracerInitialClientHeight = mainRect.bottom;
 
387
                        // set min size of the window to current size
 
388
                        GetWindowRect(hTracer, &mainRect);
 
389
                        tracerMinWidth = mainRect.right - mainRect.left;
 
390
                        tracerMinHeight = mainRect.bottom - mainRect.top;
 
391
                        if (Tracer_wndWidth < tracerMinWidth)
 
392
                                Tracer_wndWidth = tracerMinWidth;
 
393
                        if (Tracer_wndHeight < tracerMinHeight)
 
394
                                Tracer_wndHeight = tracerMinHeight;
 
395
                        // remember initial positions of all items
 
396
                        EnumChildWindows(hTracer, TracerInitialEnumWindowsProc, 0);
 
397
                        // restore position and size from config, also bring the window on top
119
398
                        if (Tracer_wndx==-32000) Tracer_wndx=0; //Just in case
120
399
                        if (Tracer_wndy==-32000) Tracer_wndy=0;
121
 
                        SetWindowPos(hwndDlg,0,Tracer_wndx,Tracer_wndy,0,0,SWP_NOSIZE|SWP_NOZORDER|SWP_NOOWNERZORDER);
122
 
                        hTracer = hwndDlg;
123
 
 
124
 
                        // setup font
125
 
                        SendDlgItemMessage(hwndDlg, IDC_TRACER_LOG, WM_SETFONT, (WPARAM)debugSystem->hFixedFont, FALSE);
126
 
 
 
400
                        SetWindowPos(hTracer, HWND_TOP, Tracer_wndx, Tracer_wndy, Tracer_wndWidth, Tracer_wndHeight, SWP_NOOWNERZORDER);
 
401
                        
127
402
                        // calculate tracesi.nPage
128
403
                        RECT wrect;
129
404
                        GetClientRect(GetDlgItem(hwndDlg, IDC_TRACER_LOG), &wrect);
130
405
                        tracesi.nPage = wrect.bottom / debugSystem->fixedFontHeight;
131
406
 
 
407
                        // setup font
 
408
                        SendDlgItemMessage(hwndDlg, IDC_TRACER_LOG, WM_SETFONT, (WPARAM)debugSystem->hFixedFont, FALSE);
 
409
 
132
410
                        //check the disabled radio button
133
411
                        CheckRadioButton(hwndDlg,IDC_RADIO_LOG_LAST,IDC_RADIO_LOG_TO_FILE,IDC_RADIO_LOG_LAST);
134
412
 
135
413
                        //EnableWindow(GetDlgItem(hwndDlg,IDC_SCRL_TRACER_LOG),FALSE);
136
 
                        //fill in the options for the log size
 
414
                        // fill in the options for the log size
137
415
                        for(i = 0;i < LOG_OPTION_SIZE;i++)
138
416
                        {
139
417
                                SendDlgItemMessage(hwndDlg, IDC_TRACER_LOG_SIZE, CB_INSERTSTRING, -1, (LPARAM)(LPSTR)log_optn_strlst[i]);
140
418
                        }
141
419
                        SendDlgItemMessage(hwndDlg, IDC_TRACER_LOG_SIZE, CB_SETCURSEL, (WPARAM)log_lines_option, 0);
142
 
                        SetDlgItemText(hwndDlg, IDC_TRACER_LOG, "Welcome to the Trace Logger.");
 
420
                        strcpy(trace_str, "Welcome to the Trace Logger.");
 
421
                        SetDlgItemText(hwndDlg, IDC_TRACER_LOG, trace_str);
143
422
                        logtofile = 0;
144
423
 
145
424
                        CheckDlgButton(hwndDlg, IDC_CHECK_LOG_REGISTERS, (logging_options & LOG_REGISTERS) ? BST_CHECKED : BST_UNCHECKED);
147
426
                        CheckDlgButton(hwndDlg, IDC_CHECK_LOG_NEW_INSTRUCTIONS, (logging_options & LOG_NEW_INSTRUCTIONS) ? BST_CHECKED : BST_UNCHECKED);
148
427
                        CheckDlgButton(hwndDlg, IDC_CHECK_LOG_NEW_DATA, (logging_options & LOG_NEW_DATA) ? BST_CHECKED : BST_UNCHECKED);
149
428
                        CheckDlgButton(hwndDlg, IDC_CHECK_LOG_STATUSES_TO_THE_LEFT, (logging_options & LOG_TO_THE_LEFT) ? BST_CHECKED : BST_UNCHECKED);
150
 
                        CheckDlgButton(hwndDlg, IDC_CHECK_LOG_FRAME_NUMBER, (logging_options & LOG_FRAME_NUMBER) ? BST_CHECKED : BST_UNCHECKED);
 
429
                        CheckDlgButton(hwndDlg, IDC_CHECK_LOG_FRAMES_COUNT, (logging_options & LOG_FRAMES_COUNT) ? BST_CHECKED : BST_UNCHECKED);
 
430
                        CheckDlgButton(hwndDlg, IDC_CHECK_LOG_CYCLES_COUNT, (logging_options & LOG_CYCLES_COUNT) ? BST_CHECKED : BST_UNCHECKED);
 
431
                        CheckDlgButton(hwndDlg, IDC_CHECK_LOG_INSTRUCTIONS_COUNT, (logging_options & LOG_INSTRUCTIONS_COUNT) ? BST_CHECKED : BST_UNCHECKED);
151
432
                        CheckDlgButton(hwndDlg, IDC_CHECK_LOG_MESSAGES, (logging_options & LOG_MESSAGES) ? BST_CHECKED : BST_UNCHECKED);
152
433
                        CheckDlgButton(hwndDlg, IDC_CHECK_LOG_BREAKPOINTS, (logging_options & LOG_BREAKPOINTS) ? BST_CHECKED : BST_UNCHECKED);
153
434
                        CheckDlgButton(hwndDlg, IDC_CHECK_SYMBOLIC_TRACING, (logging_options & LOG_SYMBOLIC) ? BST_CHECKED : BST_UNCHECKED);
157
438
                        EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_LOG_BROWSE), FALSE);
158
439
                        CheckDlgButton(hwndDlg, IDC_CHECK_LOG_UPDATE_WINDOW, log_update_window ? BST_CHECKED : BST_UNCHECKED);
159
440
                        EnableTracerMenuItems();
 
441
 
 
442
                        // subclass editfield
 
443
                        IDC_TRACER_LOG_oldWndProc = (WNDPROC)SetWindowLong(GetDlgItem(hwndDlg, IDC_TRACER_LOG), GWL_WNDPROC, (LONG)IDC_TRACER_LOG_WndProc);
 
444
                        break;
 
445
                }
 
446
                case WM_WINDOWPOSCHANGED:
 
447
                {
 
448
                        WINDOWPOS* windowpos = (WINDOWPOS*)lParam;
 
449
                        if (!(windowpos->flags & SWP_NOSIZE))
 
450
                        {
 
451
                                // window was resized
 
452
                                if (!IsIconic(hwndDlg))
 
453
                                {
 
454
                                        if (arrayOfWindowItemPosData.size())
 
455
                                        {
 
456
                                                RECT mainRect;
 
457
                                                GetWindowRect(hTracer, &mainRect);
 
458
                                                Tracer_wndWidth = mainRect.right - mainRect.left;
 
459
                                                Tracer_wndHeight = mainRect.bottom - mainRect.top;
 
460
                                                // resize all items
 
461
                                                GetClientRect(hTracer, &mainRect);
 
462
                                                tracerCurrentClientWidth = mainRect.right;
 
463
                                                tracerCurrentClientHeight = mainRect.bottom;
 
464
                                                EnumChildWindows(hTracer, TracerResizingEnumWindowsProc, 0);
 
465
                                                InvalidateRect(hTracer, 0, TRUE);
 
466
                                        }
 
467
                                        // recalculate tracesi.nPage
 
468
                                        RECT wrect;
 
469
                                        GetClientRect(GetDlgItem(hwndDlg, IDC_TRACER_LOG), &wrect);
 
470
                                        int newPageSize = wrect.bottom / debugSystem->fixedFontHeight;
 
471
                                        if (tracesi.nPage != newPageSize)
 
472
                                        {
 
473
                                                tracesi.nPage = newPageSize;
 
474
                                                if ((tracesi.nPos + (int)tracesi.nPage) > tracesi.nMax)
 
475
                                                        tracesi.nPos = tracesi.nMax - (int)tracesi.nPage;
 
476
                                                if (tracesi.nPos < tracesi.nMin)
 
477
                                                        tracesi.nPos = tracesi.nMin;
 
478
                                                SetScrollInfo(GetDlgItem(hTracer, IDC_SCRL_TRACER_LOG), SB_CTL, &tracesi, TRUE);
 
479
                                                if (!logtofile)
 
480
                                                        UpdateLogText();
 
481
                                        }
 
482
                                }
 
483
                        }
 
484
                        if (!(windowpos->flags & SWP_NOMOVE))
 
485
                        {
 
486
                                // window was moved
 
487
                                if (!IsIconic(hwndDlg) && arrayOfWindowItemPosData.size())
 
488
                                {
 
489
                                        RECT mainRect;
 
490
                                        GetWindowRect(hTracer, &mainRect);
 
491
                                        Tracer_wndWidth = mainRect.right - mainRect.left;
 
492
                                        Tracer_wndHeight = mainRect.bottom - mainRect.top;
 
493
                                        Tracer_wndx = mainRect.left;
 
494
                                        Tracer_wndy = mainRect.top;
 
495
                                        WindowBoundsCheckNoResize(Tracer_wndx, Tracer_wndy, mainRect.right);
 
496
                                }
 
497
                        }
 
498
                        break;
 
499
                }
 
500
                case WM_GETMINMAXINFO:
 
501
                {
 
502
                        if (tracerMinWidth)
 
503
                        {
 
504
                                ((MINMAXINFO*)lParam)->ptMinTrackSize.x = tracerMinWidth;
 
505
                                ((MINMAXINFO*)lParam)->ptMinTrackSize.y = tracerMinHeight;
 
506
                        }
160
507
                        break;
161
508
                }
162
509
                case WM_CLOSE:
163
510
                case WM_QUIT:
164
 
                        if(logging)
 
511
                        if (logging)
165
512
                                EndLoggingSequence();
 
513
                        ClearTraceLogBuf();
166
514
                        hTracer = 0;
167
515
                        EndDialog(hwndDlg,0);
168
516
                        break;
169
517
                case WM_COMMAND:
170
 
                        switch(HIWORD(wParam)) {
 
518
                        switch(HIWORD(wParam))
 
519
                        {
171
520
                                case BN_CLICKED:
172
 
                                        switch(LOWORD(wParam)) {
 
521
                                {
 
522
                                        switch(LOWORD(wParam))
 
523
                                        {
173
524
                                                case IDC_BTN_START_STOP_LOGGING:
174
 
                                                        if(logging)EndLoggingSequence();
175
 
                                                        else BeginLoggingSequence();
 
525
                                                        if (logging)
 
526
                                                                EndLoggingSequence();
 
527
                                                        else
 
528
                                                                BeginLoggingSequence();
176
529
                                                        EnableTracerMenuItems();
177
530
                                                        break;
178
531
                                                case IDC_RADIO_LOG_LAST:
195
548
                                                        logging_options ^= LOG_TO_THE_LEFT;
196
549
                                                        CheckDlgButton(hwndDlg, IDC_CHECK_LOG_STATUSES_TO_THE_LEFT, (logging_options & LOG_TO_THE_LEFT) ? BST_CHECKED : BST_UNCHECKED);
197
550
                                                        break;
198
 
                                                case IDC_CHECK_LOG_FRAME_NUMBER:
199
 
                                                        logging_options ^= LOG_FRAME_NUMBER;
200
 
                                                        CheckDlgButton(hwndDlg, IDC_CHECK_LOG_FRAME_NUMBER, (logging_options & LOG_FRAME_NUMBER) ? BST_CHECKED : BST_UNCHECKED);
 
551
                                                case IDC_CHECK_LOG_FRAMES_COUNT:
 
552
                                                        logging_options ^= LOG_FRAMES_COUNT;
 
553
                                                        CheckDlgButton(hwndDlg, IDC_CHECK_LOG_FRAMES_COUNT, (logging_options & LOG_FRAMES_COUNT) ? BST_CHECKED : BST_UNCHECKED);
 
554
                                                        break;
 
555
                                                case IDC_CHECK_LOG_CYCLES_COUNT:
 
556
                                                        logging_options ^= LOG_CYCLES_COUNT;
 
557
                                                        CheckDlgButton(hwndDlg, IDC_CHECK_LOG_CYCLES_COUNT, (logging_options & LOG_CYCLES_COUNT) ? BST_CHECKED : BST_UNCHECKED);
 
558
                                                        break;
 
559
                                                case IDC_CHECK_LOG_INSTRUCTIONS_COUNT:
 
560
                                                        logging_options ^= LOG_INSTRUCTIONS_COUNT;
 
561
                                                        CheckDlgButton(hwndDlg, IDC_CHECK_LOG_INSTRUCTIONS_COUNT, (logging_options & LOG_INSTRUCTIONS_COUNT) ? BST_CHECKED : BST_UNCHECKED);
201
562
                                                        break;
202
563
                                                case IDC_CHECK_LOG_MESSAGES:
203
564
                                                        logging_options ^= LOG_MESSAGES;
235
596
                                                        if(!FCEUI_EmulationPaused() && !log_update_window)
236
597
                                                        {
237
598
                                                                // Assemble the message to pause the game.  Uses the current hotkey mapping dynamically
238
 
                                                                string m1 = "Pause the game (press ";
239
 
                                                                string m2 = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_PAUSE]);
240
 
                                                                string m3 = " key or snap the Debugger) to update this window.\r\n";
241
 
                                                                string pauseMessage = m1 + m2 + m3;
242
 
                                                                SetDlgItemText(hTracer, IDC_TRACER_LOG, pauseMessage.c_str());
 
599
                                                                strcpy(trace_str, "Pause the game (press ");
 
600
                                                                strcat(trace_str, GetKeyComboName(FCEUD_CommandMapping[EMUCMD_PAUSE]));
 
601
                                                                strcat(trace_str, " key or snap the Debugger) to update this window.\r\n");
 
602
                                                                SetDlgItemText(hTracer, IDC_TRACER_LOG, trace_str);
243
603
                                                        }
244
604
                                                        break;
245
605
                                                }
248
608
                                                        break;
249
609
                                        }
250
610
                                        break;
 
611
                                }
251
612
                        }
252
613
                        break;
253
614
                case WM_MOVING:
254
615
                        break;
255
 
        }
256
 
 
257
 
 
258
 
        switch(uMsg) {
 
616
 
259
617
                case WM_VSCROLL:
260
 
                        if (lParam) {
261
 
                                if ((!logging) || logtofile) break;
 
618
                {
 
619
                        if (lParam)
 
620
                        {
 
621
                                if (!tracelogbuf)
 
622
                                        break;
262
623
 
263
 
                                if(!FCEUI_EmulationPaused() && !log_update_window) break; //mbg merge 7/19/06 changd to use EmulationPaused()
 
624
                                if (!FCEUI_EmulationPaused() && !log_update_window)
 
625
                                        break;
264
626
 
265
627
                                GetScrollInfo((HWND)lParam,SB_CTL,&tracesi);
266
628
                                switch(LOWORD(wParam))
283
645
                                UpdateLogText();
284
646
                        }
285
647
                        break;
 
648
                }
 
649
                case WM_MOUSEWHEEL:
 
650
                {
 
651
                        GetScrollInfo(GetDlgItem(hTracer, IDC_SCRL_TRACER_LOG), SB_CTL, &tracesi);
 
652
                        i = GET_WHEEL_DELTA_WPARAM(wParam) / WHEEL_DELTA;
 
653
                        if (i < -1 || i > 1)
 
654
                                i *= 2;
 
655
                        tracesi.nPos -= i;
 
656
                        if ((tracesi.nPos + (int)tracesi.nPage) > tracesi.nMax)
 
657
                                tracesi.nPos = tracesi.nMax - tracesi.nPage;
 
658
                        if (tracesi.nPos < tracesi.nMin)
 
659
                                tracesi.nPos = tracesi.nMin;
 
660
                        SetScrollInfo(GetDlgItem(hTracer, IDC_SCRL_TRACER_LOG), SB_CTL, &tracesi, TRUE);
 
661
                        UpdateLogText();
 
662
                        break;
 
663
                }
286
664
        }
287
665
        return FALSE;
288
666
}
289
667
 
290
668
void BeginLoggingSequence(void)
291
669
{
292
 
        char str[2048], str2[100];
 
670
        char str2[100];
293
671
        int i, j;
294
672
 
295
 
        if(!PromptForCDLogger())return; //do nothing if user selected no and CD Logger is needed
 
673
        if (!PromptForCDLogger())
 
674
                return; //do nothing if user selected no and CD Logger is needed
296
675
 
297
 
        if(logtofile)
 
676
        if (logtofile)
298
677
        {
299
678
                if(logfilename == NULL) ShowLogDirDialog();
300
679
                if (!logfilename) return;
301
680
                LOG_FP = fopen(logfilename,"w");
302
 
                if(LOG_FP == NULL){
303
 
                        sprintf(str,"Error Opening File %s",logfilename);
304
 
                        MessageBox(hTracer,str, "File Error", MB_OK);
 
681
                if (LOG_FP == NULL)
 
682
                {
 
683
                        sprintf(trace_str, "Error Opening File %s", logfilename);
 
684
                        MessageBox(hTracer, trace_str, "File Error", MB_OK);
305
685
                        return;
306
686
                }
307
687
                fprintf(LOG_FP,FCEU_NAME_AND_VERSION" - Trace Log File\n"); //mbg merge 7/19/06 changed string
308
688
        } else
309
689
        {
 
690
                ClearTraceLogBuf();
 
691
                // create new log
310
692
                log_lines_option = SendDlgItemMessage(hTracer, IDC_TRACER_LOG_SIZE, CB_GETCURSEL, 0, 0);
311
693
                if (log_lines_option == CB_ERR)
312
694
                        log_lines_option = 0;
313
 
                strcpy(str,"Allocating Memory...\r\n");
314
 
                SetDlgItemText(hTracer, IDC_TRACER_LOG, str);
 
695
                strcpy(trace_str, "Allocating Memory...\r\n");
 
696
                SetDlgItemText(hTracer, IDC_TRACER_LOG, trace_str);
315
697
                tracelogbufsize = j = log_optn_intlst[log_lines_option];
316
 
                tracelogbuf = (char**)malloc(j*sizeof(char *)); //mbg merge 7/19/06 added cast
317
 
                for(i = 0;i < j;i++)
 
698
                tracelogbuf = (char**)malloc(j * sizeof(char *));
 
699
                for (i = 0;i < j;i++)
318
700
                {
319
 
                        tracelogbuf[i] = (char*)malloc(LOG_LINE_MAX_LEN); //mbg merge 7/19/06 added cast
 
701
                        tracelogbuf[i] = (char*)malloc(LOG_LINE_MAX_LEN);
320
702
                        tracelogbuf[i][0] = 0;
321
703
                }
322
704
                sprintf(str2, "%d Bytes Allocated...\r\n", j * LOG_LINE_MAX_LEN);
323
 
                strcat(str,str2);
 
705
                strcat(trace_str, str2);
 
706
                tracelogbufAddressesLog.resize(0);
 
707
                tracelogbufAddressesLog.resize(tracelogbufsize);
324
708
                // Assemble the message to pause the game.  Uses the current hotkey mapping dynamically
325
 
                string m1 = "Pause the game (press ";
326
 
                string m2 = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_PAUSE]);
327
 
                string m3 = " key or snap the Debugger) to update this window.\r\n";
328
 
                string pauseMessage = m1 + m2 + m3;
329
 
                strcat(str, pauseMessage.c_str());
330
 
                SetDlgItemText(hTracer, IDC_TRACER_LOG, str);
 
709
                strcat(trace_str, "Pause the game (press ");
 
710
                strcat(trace_str, GetKeyComboName(FCEUD_CommandMapping[EMUCMD_PAUSE]));
 
711
                strcat(trace_str, " key or snap the Debugger) to update this window.\r\n");
 
712
                SetDlgItemText(hTracer, IDC_TRACER_LOG, trace_str);
331
713
                tracelogbufpos = tracelogbufusedsize = 0;
332
714
        }
333
715
        
351
733
 
352
734
        // if instruction executed from the RAM, skip this, log all instead
353
735
        // TODO: loops folding mame-lyke style
354
 
        if(GetPRGAddress(addr) != -1) {
 
736
        if (GetPRGAddress(addr) != -1)
 
737
        {
355
738
                if(((logging_options & LOG_NEW_INSTRUCTIONS) && (oldcodecount != codecount)) ||
356
739
                   ((logging_options & LOG_NEW_DATA) && (olddatacount != datacount)))
357
740
                {
360
743
                        olddatacount = datacount;
361
744
                        if(unloggedlines > 0)
362
745
                        {
363
 
                                sprintf(str_temp, "(%d lines skipped)", unloggedlines);
364
 
                                OutputLogLine(str_temp);
 
746
                                sprintf(str_result, "(%d lines skipped)", unloggedlines);
 
747
                                OutputLogLine(str_result);
365
748
                                unloggedlines = 0;
366
749
                        }
367
750
                } else
398
781
                                {
399
782
                                        // add the beginning address of the subroutine that we exit from
400
783
                                        unsigned int caller_addr = GetMem(((X.S) + 1)|0x0100) + (GetMem(((X.S) + 2)|0x0100) << 8) - 0x2;
401
 
                                        unsigned int call_addr = GetMem(caller_addr + 1) + (GetMem(caller_addr + 2) << 8);
402
 
                                        sprintf(str_decoration, " (from $%04X)", call_addr);
403
 
                                        strcat(a, str_decoration);
 
784
                                        if (GetMem(caller_addr) == 0x20)
 
785
                                        {
 
786
                                                // this was a JSR instruction - take the subroutine address from it
 
787
                                                unsigned int call_addr = GetMem(caller_addr + 1) + (GetMem(caller_addr + 2) << 8);
 
788
                                                sprintf(str_decoration, " (from $%04X)", call_addr);
 
789
                                                strcat(a, str_decoration);
 
790
                                        }
404
791
                                }
405
792
                                break;
406
793
                        }
418
805
                {
419
806
                        if (logging_options & LOG_SYMBOLIC)
420
807
                        {
 
808
                                loadNameFiles();
 
809
                                tempAddressesLog.resize(0);
421
810
                                // Insert Name and Comment lines if needed
422
 
                                tracer_decoration_name = 0;
423
 
                                tracer_decoration_comment = 0;
424
 
                                decorateAddress(addr, &tracer_decoration_name, &tracer_decoration_comment);
425
 
                                if (tracer_decoration_name)
426
 
                                {
427
 
                                        strcpy(str_decoration, tracer_decoration_name);
428
 
                                        strcat(str_decoration, ": ");
429
 
                                        OutputLogLine(str_decoration, true);
430
 
                                }
431
 
                                if (tracer_decoration_comment)
432
 
                                {
433
 
                                        // make a copy
434
 
                                        strcpy(str_decoration_comment, tracer_decoration_comment);
435
 
                                        strcat(str_decoration_comment, "\r\n");
436
 
                                        tracer_decoration_comment = str_decoration_comment;
437
 
                                        // divide the str_decoration_comment into strings (Comment1, Comment2, ...)
438
 
                                        char* end_pos = strstr(tracer_decoration_comment, "\r");
439
 
                                        while (end_pos)
440
 
                                        {
441
 
                                                end_pos[0] = 0;         // set \0 instead of \r
442
 
                                                strcpy(str_decoration, "; ");
443
 
                                                strcat(str_decoration, tracer_decoration_comment);
444
 
                                                OutputLogLine(str_decoration, true);
445
 
                                                end_pos += 2;
446
 
                                                tracer_decoration_comment = end_pos;
447
 
                                                end_pos = strstr(tracer_decoration_comment, "\r");
448
 
                                        }
449
 
                                }
450
 
                                replaceNames(ramBankNames, a);
451
 
                                replaceNames(loadedBankNames, a);
452
 
                                replaceNames(lastBankNames, a);
 
811
                                Name* node = findNode(getNamesPointerForAddress(addr), addr);
 
812
                                if (node)
 
813
                                {
 
814
                                        if (node->name)
 
815
                                        {
 
816
                                                strcpy(str_decoration, node->name);
 
817
                                                strcat(str_decoration, ":");
 
818
                                                tempAddressesLog.push_back(addr);
 
819
                                                OutputLogLine(str_decoration, &tempAddressesLog);
 
820
                                        }
 
821
                                        if (node->comment)
 
822
                                        {
 
823
                                                // make a copy
 
824
                                                strcpy(str_decoration_comment, node->comment);
 
825
                                                strcat(str_decoration_comment, "\r\n");
 
826
                                                tracer_decoration_comment = str_decoration_comment;
 
827
                                                // divide the str_decoration_comment into strings (Comment1, Comment2, ...)
 
828
                                                char* tracer_decoration_comment_end_pos = strstr(tracer_decoration_comment, "\r\n");
 
829
                                                while (tracer_decoration_comment_end_pos)
 
830
                                                {
 
831
                                                        tracer_decoration_comment_end_pos[0] = 0;               // set \0 instead of \r
 
832
                                                        strcpy(str_decoration, "; ");
 
833
                                                        strcat(str_decoration, tracer_decoration_comment);
 
834
                                                        OutputLogLine(str_decoration, &tempAddressesLog);
 
835
                                                        tracer_decoration_comment_end_pos += 2;
 
836
                                                        tracer_decoration_comment = tracer_decoration_comment_end_pos;
 
837
                                                        tracer_decoration_comment_end_pos = strstr(tracer_decoration_comment_end_pos, "\r\n");
 
838
                                                }
 
839
                                        }
 
840
                                }
 
841
                                
 
842
                                replaceNames(ramBankNames, a, &tempAddressesLog);
 
843
                                replaceNames(loadedBankNames, a, &tempAddressesLog);
 
844
                                replaceNames(lastBankNames, a, &tempAddressesLog);
453
845
                        }
454
 
                        strcpy(str_disassembly, a);
 
846
                        strncpy(str_disassembly, a, LOG_DISASSEMBLY_MAX_LEN);
 
847
                        str_disassembly[LOG_DISASSEMBLY_MAX_LEN - 1] = 0;
455
848
                }
456
849
        }
457
850
 
473
866
                str_disassembly[LOG_DISASSEMBLY_MAX_LEN - 1] = 0;
474
867
        }
475
868
 
476
 
        // Start filling the str_temp line: Frame number, AXYS state, Processor status, Tabs, Address, Data, Disassembly
477
 
        if (logging_options & LOG_FRAME_NUMBER)
 
869
        // Start filling the str_temp line: Frame count, Cycles count, Instructions count, AXYS state, Processor status, Tabs, Address, Data, Disassembly
 
870
        if (logging_options & LOG_FRAMES_COUNT)
478
871
        {
479
 
                sprintf(str_temp, "%06u: ", currFrameCounter);
 
872
                sprintf(str_result, "f%-6u ", currFrameCounter);
480
873
        } else
481
874
        {
482
 
                str_temp[0] = 0;
483
 
        }
484
 
 
 
875
                str_result[0] = 0;
 
876
        }
 
877
        if (logging_options & LOG_CYCLES_COUNT)
 
878
        {
 
879
                int64 counter_value = timestampbase + (uint64)timestamp - total_cycles_base;
 
880
                if (counter_value < 0)  // sanity check
 
881
                {
 
882
                        ResetDebugStatisticsCounters();
 
883
                        counter_value = 0;
 
884
                }
 
885
                sprintf(str_temp, "c%-11llu ", counter_value);
 
886
                strcat(str_result, str_temp);
 
887
        }
 
888
        if (logging_options & LOG_INSTRUCTIONS_COUNT)
 
889
        {
 
890
                sprintf(str_temp, "i%-11llu ", total_instructions);
 
891
                strcat(str_result, str_temp);
 
892
        }
 
893
        
485
894
        if (logging_options & LOG_REGISTERS)
486
895
        {
487
896
                sprintf(str_axystate,"A:%02X X:%02X Y:%02X S:%02X ",(X.A),(X.X),(X.Y),(X.S));
505
914
        if (logging_options & LOG_TO_THE_LEFT)
506
915
        {
507
916
                if (logging_options & LOG_REGISTERS)
508
 
                        strcat(str_temp, str_axystate);
 
917
                        strcat(str_result, str_axystate);
509
918
                if (logging_options & LOG_PROCESSOR_STATUS)
510
 
                        strcat(str_temp, str_procstatus);
 
919
                        strcat(str_result, str_procstatus);
511
920
        }
512
921
 
513
922
        if (logging_options & LOG_CODE_TABBING)
517
926
                for (int i = 0; i < spaces; i++)
518
927
                        str_tabs[i] = ' ';
519
928
                str_tabs[spaces] = 0;
520
 
                strcat(str_temp, str_tabs);
 
929
                strcat(str_result, str_tabs);
521
930
        } else if (logging_options & LOG_TO_THE_LEFT)
522
931
        {
523
 
                strcat(str_temp, " ");
 
932
                strcat(str_result, " ");
524
933
        }
525
934
 
526
935
        sprintf(str_address, "$%04X:", addr);
527
 
        strcat(str_temp, str_address);
528
 
        strcat(str_temp, str_data);
529
 
        strcat(str_temp, str_disassembly);
 
936
        strcat(str_result, str_address);
 
937
        strcat(str_result, str_data);
 
938
        strcat(str_result, str_disassembly);
530
939
 
531
940
        if (!(logging_options & LOG_TO_THE_LEFT))
532
941
        {
533
942
                if (logging_options & LOG_REGISTERS)
534
 
                        strcat(str_temp, str_axystate);
 
943
                        strcat(str_result, str_axystate);
535
944
                if (logging_options & LOG_PROCESSOR_STATUS)
536
 
                        strcat(str_temp, str_procstatus);
 
945
                        strcat(str_result, str_procstatus);
537
946
        }
538
947
 
539
 
        OutputLogLine(str_temp);
 
948
        OutputLogLine(str_result, &tempAddressesLog);
 
949
        
540
950
        return;
541
951
}
542
952
 
543
 
void OutputLogLine(const char *str, bool add_newline)
 
953
void OutputLogLine(const char *str, std::vector<uint16>* addressesLog, bool add_newline)
544
954
{
545
 
        if(logtofile)
 
955
        if (logtofile)
546
956
        {
547
957
                fputs(str, LOG_FP);
548
958
                if (add_newline)
560
970
                        strncpy(tracelogbuf[tracelogbufpos], str, LOG_LINE_MAX_LEN - 1);
561
971
                        tracelogbuf[tracelogbufpos][LOG_LINE_MAX_LEN - 1] = 0;
562
972
                }
 
973
 
 
974
                if (addressesLog)
 
975
                        tracelogbufAddressesLog[tracelogbufpos] = (*addressesLog);
 
976
                else
 
977
                        tracelogbufAddressesLog[tracelogbufpos].resize(0);
 
978
 
563
979
                tracelogbufpos++;
564
980
                if (tracelogbufusedsize < tracelogbufsize)
565
981
                        tracelogbufusedsize++;
567
983
        }
568
984
}
569
985
 
570
 
void EndLoggingSequence(void){
571
 
        int j, i;
572
 
        if(logtofile){
573
 
                fclose(LOG_FP);
574
 
        } else {
575
 
                j = tracelogbufsize;
576
 
                for(i = 0;i < j;i++){
 
986
void ClearTraceLogBuf(void)
 
987
{
 
988
        if (tracelogbuf)
 
989
        {
 
990
                int j = tracelogbufsize;
 
991
                for(int i = 0; i < j;i++)
 
992
                {
577
993
                        free(tracelogbuf[i]);
578
994
                }
579
995
                free(tracelogbuf);
580
 
                SetDlgItemText(hTracer, IDC_TRACER_LOG, "Welcome to the Trace Logger.");
581
 
        }
582
 
        logging=0;
 
996
                tracelogbuf = 0;
 
997
        }
 
998
        tracelogbufAddressesLog.resize(0);
 
999
}
 
1000
 
 
1001
void EndLoggingSequence()
 
1002
{
 
1003
        if (logtofile)
 
1004
        {
 
1005
                fclose(LOG_FP);
 
1006
        } else
 
1007
        {
 
1008
                strcpy(str_result, "Logging finished.");
 
1009
                OutputLogLine(str_result);
 
1010
                ScrollLogWindowToLastLine();
 
1011
                UpdateLogText();
 
1012
                // do not clear the log window
 
1013
                // ClearTraceLogBuf();
 
1014
        }
 
1015
        logging = 0;
583
1016
        SetDlgItemText(hTracer, IDC_BTN_START_STOP_LOGGING,"Start Logging");
584
 
 
585
1017
}
586
1018
 
587
1019
void UpdateLogWindow(void)
600
1032
        }
601
1033
        log_old_emu_paused = emu_paused;
602
1034
 
 
1035
        ScrollLogWindowToLastLine();
 
1036
        UpdateLogText();
 
1037
        return;
 
1038
}
 
1039
 
 
1040
void ScrollLogWindowToLastLine()
 
1041
{
603
1042
        tracesi.cbSize = sizeof(SCROLLINFO);
604
1043
        tracesi.fMask = SIF_ALL;
605
1044
        tracesi.nMin = 0;
608
1047
        if (tracesi.nPos < tracesi.nMin)
609
1048
                tracesi.nPos = tracesi.nMin;
610
1049
        SetScrollInfo(GetDlgItem(hTracer,IDC_SCRL_TRACER_LOG),SB_CTL,&tracesi,TRUE);
611
 
 
612
 
        if (logging_options & LOG_SYMBOLIC)
613
 
                loadNameFiles();
614
 
 
615
 
        UpdateLogText();
616
 
 
617
 
        return;
618
1050
}
619
1051
 
620
1052
void UpdateLogText(void)
621
1053
{
622
 
        int i, j;
623
 
        char str[3000];
624
 
        str[0] = 0;
 
1054
        int j;
 
1055
        trace_str[0] = 0;
 
1056
 
 
1057
        if (!tracelogbuf || !tracelogbufpos || !tracelogbufsize)
 
1058
                return;
 
1059
 
625
1060
        int last_line = tracesi.nPos + tracesi.nPage;
626
1061
        if (last_line > tracesi.nMax)
627
1062
                last_line = tracesi.nMax;
628
1063
 
629
 
        for(i = tracesi.nPos; i < last_line; i++)
 
1064
        int i = tracesi.nPos;
 
1065
        if (i < tracesi.nMin)
 
1066
                i = tracesi.nMin;
 
1067
 
 
1068
        for (; i < last_line; i++)
630
1069
        {
631
1070
                j = i;
632
 
                if(tracelogbufusedsize == tracelogbufsize)
633
 
                {
634
 
                        j = (tracelogbufpos+i)%tracelogbufsize;
635
 
                }
636
 
                strcat(str,tracelogbuf[j]);
 
1071
                if (tracelogbufusedsize == tracelogbufsize)
 
1072
                        j = (tracelogbufpos + i) % tracelogbufsize;
 
1073
                strcat(trace_str, tracelogbuf[j]);
637
1074
        }
638
 
        SetDlgItemText(hTracer, IDC_TRACER_LOG, str);
639
 
        sprintf(str,"nPage = %d, nPos = %d, nMax = %d, nMin = %d",tracesi.nPage,tracesi.nPos,tracesi.nMax,tracesi.nMin);
640
 
        SetDlgItemText(hTracer, IDC_TRACER_STATS, str);
 
1075
        SetDlgItemText(hTracer, IDC_TRACER_LOG, trace_str);
 
1076
        //sprintf(str,"nPage = %d, nPos = %d, nMax = %d, nMin = %d",tracesi.nPage,tracesi.nPos,tracesi.nMax,tracesi.nMin);
 
1077
        //SetDlgItemText(hTracer, IDC_TRACER_STATS, str);
641
1078
        return;
642
1079
}
643
1080
 
644
 
void EnableTracerMenuItems(void){
645
 
        if(logging)
 
1081
void EnableTracerMenuItems(void)
 
1082
{
 
1083
        if (logging)
646
1084
        {
647
1085
                EnableWindow(GetDlgItem(hTracer,IDC_RADIO_LOG_LAST),FALSE);
648
1086
                EnableWindow(GetDlgItem(hTracer,IDC_RADIO_LOG_TO_FILE),FALSE);
657
1095
        EnableWindow(GetDlgItem(hTracer,IDC_BTN_LOG_BROWSE),TRUE);
658
1096
        EnableWindow(GetDlgItem(hTracer,IDC_CHECK_LOG_NEW_INSTRUCTIONS),TRUE);
659
1097
 
660
 
        if(logtofile)
 
1098
        if (logtofile)
661
1099
        {
662
1100
                EnableWindow(GetDlgItem(hTracer,IDC_TRACER_LOG_SIZE),FALSE);
663
1101
                EnableWindow(GetDlgItem(hTracer,IDC_BTN_LOG_BROWSE),TRUE);
705
1143
        ofn.hInstance=fceu_hInstance;
706
1144
        ofn.lpstrTitle="Log Trace As...";
707
1145
        ofn.lpstrFilter=filter;
708
 
        strcpy(nameo,GetRomName());
 
1146
        strcpy(nameo, mass_replace(GetRomName(), "|", ".").c_str());
709
1147
        ofn.lpstrFile=nameo;
710
1148
        ofn.nMaxFile=256;
711
1149
        ofn.Flags=OFN_EXPLORER|OFN_FILEMUSTEXIST|OFN_HIDEREADONLY;
712
1150
        ofn.hwndOwner = hTracer;
713
 
        if(GetSaveFileName(&ofn)){
 
1151
        if(GetSaveFileName(&ofn))
 
1152
        {
714
1153
                if (ofn.nFilterIndex == 1)
715
1154
                        AddExtensionIfMissing(nameo, sizeof(nameo), ".log");
716
1155
                else if (ofn.nFilterIndex == 2)
725
1164
 
726
1165
void DoTracer()
727
1166
{
728
 
        if (!GameInfo) {
 
1167
        if (!GameInfo)
 
1168
        {
729
1169
                FCEUD_PrintError("You must have a game loaded before you can use the Trace Logger.");
730
1170
                return;
731
1171
        }
734
1174
        //      return;
735
1175
        //}
736
1176
 
737
 
        if(!hTracer)
 
1177
        if (!hTracer)
738
1178
        {
 
1179
                arrayOfWindowItemPosData.resize(0);
739
1180
                CreateDialog(fceu_hInstance,"TRACER",NULL,TracerCallB);
740
1181
                //hTracer gets set in WM_INITDIALOG
741
1182
        } else