ppsspp/Windows/Debugger/BreakpointWindow.cpp
Henrik Rydgård ff8148dd92 Move native/util, native/data and native/i18 to Common/Data.
Also move colorutil.cpp/h

linking build fix experiment

Delete a bunch of unused CMakeLists.txt files

CMakeLists.txt linking fix

Don't include NativeApp.h from any headers.

Android.mk buildfix

Half of the UWP fix

Buildfix

Minor project file cleanup

Buildfixes

Guess what? More buildfixes!
2020-10-04 07:28:29 +02:00

285 lines
8 KiB
C++

#include <cstdio>
#include "Common/Data/Encoding/Utf8.h"
#include "BreakpointWindow.h"
#include "../resource.h"
BreakpointWindow* BreakpointWindow::bp;
INT_PTR CALLBACK BreakpointWindow::dlgFunc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
char str[128];
switch (iMsg)
{
case WM_INITDIALOG:
SendMessage(GetDlgItem(hwnd,IDC_BREAKPOINT_EXECUTE),BM_SETCHECK,bp->memory ? BST_UNCHECKED : BST_CHECKED,0);
SendMessage(GetDlgItem(hwnd,IDC_BREAKPOINT_MEMORY),BM_SETCHECK,bp->memory ? BST_CHECKED : BST_UNCHECKED,0);
SendMessage(GetDlgItem(hwnd,IDC_BREAKPOINT_READ),BM_SETCHECK, bp->read ? BST_CHECKED : BST_UNCHECKED,0);
SendMessage(GetDlgItem(hwnd,IDC_BREAKPOINT_WRITE),BM_SETCHECK, bp->write ? BST_CHECKED : BST_UNCHECKED,0);
SendMessage(GetDlgItem(hwnd,IDC_BREAKPOINT_ONCHANGE),BM_SETCHECK, bp->onChange ? BST_CHECKED : BST_UNCHECKED,0);
SendMessage(GetDlgItem(hwnd,IDC_BREAKPOINT_ENABLED),BM_SETCHECK, bp->enabled ? BST_CHECKED : BST_UNCHECKED,0);
SendMessage(GetDlgItem(hwnd,IDC_BREAKPOINT_LOG),BM_SETCHECK, bp->log ? BST_CHECKED : BST_UNCHECKED,0);
EnableWindow(GetDlgItem(hwnd,IDC_BREAKPOINT_READ),bp->memory);
EnableWindow(GetDlgItem(hwnd,IDC_BREAKPOINT_WRITE),bp->memory);
EnableWindow(GetDlgItem(hwnd,IDC_BREAKPOINT_ONCHANGE),bp->memory);
EnableWindow(GetDlgItem(hwnd,IDC_BREAKPOINT_SIZE),bp->memory);
EnableWindow(GetDlgItem(hwnd,IDC_BREAKPOINT_CONDITION),!bp->memory);
EnableWindow(GetDlgItem(hwnd,IDC_BREAKPOINT_LOG_FORMAT), bp->log);
if (bp->address != -1)
{
snprintf(str, sizeof(str), "0x%08X", bp->address);
SetWindowTextA(GetDlgItem(hwnd,IDC_BREAKPOINT_ADDRESS),str);
}
snprintf(str, sizeof(str), "0x%08X", bp->size);
SetWindowTextA(GetDlgItem(hwnd, IDC_BREAKPOINT_SIZE),str);
SetWindowTextW(GetDlgItem(hwnd, IDC_BREAKPOINT_CONDITION), ConvertUTF8ToWString(bp->condition).c_str());
SetWindowTextW(GetDlgItem(hwnd, IDC_BREAKPOINT_LOG_FORMAT), ConvertUTF8ToWString(bp->logFormat).c_str());
return TRUE;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDC_BREAKPOINT_EXECUTE:
switch (HIWORD(wParam))
{
case BN_CLICKED:
bp->memory = false;
EnableWindow(GetDlgItem(hwnd,IDC_BREAKPOINT_READ),bp->memory);
EnableWindow(GetDlgItem(hwnd,IDC_BREAKPOINT_WRITE),bp->memory);
EnableWindow(GetDlgItem(hwnd,IDC_BREAKPOINT_ONCHANGE),bp->memory);
EnableWindow(GetDlgItem(hwnd,IDC_BREAKPOINT_SIZE),bp->memory);
EnableWindow(GetDlgItem(hwnd,IDC_BREAKPOINT_CONDITION),!bp->memory);
break;
}
break;
case IDC_BREAKPOINT_MEMORY:
switch (HIWORD(wParam))
{
case BN_CLICKED:
bp->memory = true;
EnableWindow(GetDlgItem(hwnd,IDC_BREAKPOINT_READ),bp->memory);
EnableWindow(GetDlgItem(hwnd,IDC_BREAKPOINT_WRITE),bp->memory);
EnableWindow(GetDlgItem(hwnd,IDC_BREAKPOINT_ONCHANGE),bp->memory);
EnableWindow(GetDlgItem(hwnd,IDC_BREAKPOINT_SIZE),bp->memory);
EnableWindow(GetDlgItem(hwnd,IDC_BREAKPOINT_CONDITION),!bp->memory);
break;
}
break;
case IDC_BREAKPOINT_LOG:
switch (HIWORD(wParam))
{
case BN_CLICKED:
EnableWindow(GetDlgItem(hwnd, IDC_BREAKPOINT_LOG_FORMAT), bp->GetCheckState(hwnd, IDC_BREAKPOINT_LOG));
break;
}
break;
case IDC_BREAKPOINT_OK:
switch (HIWORD(wParam))
{
case BN_CLICKED:
if (bp->fetchDialogData(hwnd))
{
EndDialog(hwnd,true);
}
break;
};
break;
case IDC_BREAKPOINT_CANCEL:
switch (HIWORD(wParam))
{
case BN_CLICKED:
EndDialog(hwnd,false);
break;
};
break;
case IDOK:
if (bp->fetchDialogData(hwnd))
{
EndDialog(hwnd,true);
}
break;
case IDCANCEL:
EndDialog(hwnd,false);
break;
}
case WM_KEYDOWN:
break;
}
return FALSE;
}
bool BreakpointWindow::fetchDialogData(HWND hwnd)
{
char str[256],errorMessage[512];
PostfixExpression exp;
memory = GetCheckState(hwnd, IDC_BREAKPOINT_MEMORY);
read = GetCheckState(hwnd, IDC_BREAKPOINT_READ);
write = GetCheckState(hwnd, IDC_BREAKPOINT_WRITE);
enabled = GetCheckState(hwnd, IDC_BREAKPOINT_ENABLED);
log = GetCheckState(hwnd, IDC_BREAKPOINT_LOG);
onChange = GetCheckState(hwnd, IDC_BREAKPOINT_ONCHANGE);
// parse address
GetWindowTextA(GetDlgItem(hwnd,IDC_BREAKPOINT_ADDRESS),str,256);
if (cpu->initExpression(str,exp) == false)
{
snprintf(errorMessage, sizeof(errorMessage), "Invalid expression \"%s\".",str);
MessageBoxA(hwnd,errorMessage,"Error",MB_OK);
return false;
}
if (cpu->parseExpression(exp,address) == false)
{
snprintf(errorMessage, sizeof(errorMessage), "Invalid expression \"%s\".",str);
MessageBoxA(hwnd,errorMessage,"Error",MB_OK);
return false;
}
if (memory)
{
// parse size
GetWindowTextA(GetDlgItem(hwnd,IDC_BREAKPOINT_SIZE),str,256);
if (cpu->initExpression(str,exp) == false)
{
snprintf(errorMessage, sizeof(errorMessage), "Invalid expression \"%s\".",str);
MessageBoxA(hwnd,errorMessage,"Error",MB_OK);
return false;
}
if (cpu->parseExpression(exp,size) == false)
{
snprintf(errorMessage, sizeof(errorMessage), "Invalid expression \"%s\".",str);
MessageBoxA(hwnd,errorMessage,"Error",MB_OK);
return false;
}
}
// condition
wchar_t tempCond[512];
GetWindowTextW(GetDlgItem(hwnd, IDC_BREAKPOINT_CONDITION), tempCond, 512);
condition = ConvertWStringToUTF8(tempCond);
compiledCondition.clear();
if (!condition.empty())
{
if (cpu->initExpression(condition.c_str(), compiledCondition) == false)
{
snprintf(errorMessage, sizeof(errorMessage), "Invalid expression \"%s\".",str);
MessageBoxA(hwnd,errorMessage,"Error",MB_OK);
return false;
}
}
wchar_t tempLogFormat[512];
GetWindowTextW(GetDlgItem(hwnd, IDC_BREAKPOINT_LOG_FORMAT), tempLogFormat, 512);
logFormat = ConvertWStringToUTF8(tempLogFormat);
if (!CBreakPoints::ValidateLogFormat(cpu, logFormat)) {
snprintf(errorMessage, sizeof(errorMessage), "Invalid log format (example: \"{a1}\").");
MessageBoxA(hwnd, errorMessage, "Error", MB_OK);
return false;
}
return true;
}
bool BreakpointWindow::GetCheckState(HWND hwnd, int dlgItem) {
return SendMessage(GetDlgItem(hwnd, dlgItem), BM_GETCHECK, 0, 0) != 0;
}
bool BreakpointWindow::exec()
{
bp = this;
bool result = DialogBoxParam(GetModuleHandle(0),MAKEINTRESOURCE(IDD_BREAKPOINT),parentHwnd,dlgFunc,(LPARAM)this) != 0;
return result;
}
void BreakpointWindow::addBreakpoint()
{
BreakAction result = BREAK_ACTION_IGNORE;
if (log)
result |= BREAK_ACTION_LOG;
if (enabled)
result |= BREAK_ACTION_PAUSE;
if (memory)
{
// add memcheck
int cond = 0;
if (read)
cond |= MEMCHECK_READ;
if (write)
cond |= MEMCHECK_WRITE;
if (onChange)
cond |= MEMCHECK_WRITE_ONCHANGE;
CBreakPoints::AddMemCheck(address, address + size, (MemCheckCondition)cond, result);
CBreakPoints::ChangeMemCheckLogFormat(address, address + size, logFormat);
} else {
// add breakpoint
CBreakPoints::AddBreakPoint(address,false);
if (!condition.empty())
{
BreakPointCond cond;
cond.debug = cpu;
cond.expressionString = condition;
cond.expression = compiledCondition;
CBreakPoints::ChangeBreakPointAddCond(address,cond);
}
CBreakPoints::ChangeBreakPoint(address, result);
CBreakPoints::ChangeBreakPointLogFormat(address, logFormat);
}
}
void BreakpointWindow::loadFromMemcheck(MemCheck& memcheck)
{
memory = true;
read = (memcheck.cond & MEMCHECK_READ) != 0;
write = (memcheck.cond & MEMCHECK_WRITE) != 0;
onChange = (memcheck.cond & MEMCHECK_WRITE_ONCHANGE) != 0;
log = (memcheck.result & BREAK_ACTION_LOG) != 0;
enabled = (memcheck.result & BREAK_ACTION_PAUSE) != 0;
address = memcheck.start;
size = memcheck.end-address;
logFormat = memcheck.logFormat;
}
void BreakpointWindow::loadFromBreakpoint(BreakPoint& breakpoint)
{
memory = false;
log = (breakpoint.result & BREAK_ACTION_LOG) != 0;
enabled = (breakpoint.result & BREAK_ACTION_PAUSE) != 0;
address = breakpoint.addr;
size = 1;
if (breakpoint.hasCond) {
condition = breakpoint.cond.expressionString;
} else {
condition.clear();
}
logFormat = breakpoint.logFormat;
}
void BreakpointWindow::initBreakpoint(u32 _address)
{
memory = false;
enabled = true;
address = _address;
size = 1;
condition.clear();
}