/**************************************************************************** * * * Project64 - A Nintendo 64 emulator. * * http://www.pj64-emu.com/ * * Copyright (C) 2012 Project64. All rights reserved. * * * * License: * * GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * * * ****************************************************************************/ #include "stdafx.h" #include "DebuggerUI.h" CDebugExcBreakpoints::ExcCheckboxMeta CDebugExcBreakpoints::ExcCheckboxMap[] = { { IDC_CHK_INT, 0 }, { IDC_CHK_MOD, 1 }, { IDC_CHK_RMISS, 2 }, { IDC_CHK_WMISS, 3 }, { IDC_CHK_RADE, 4 }, { IDC_CHK_WADE, 5 }, { IDC_CHK_IBE, 6 }, { IDC_CHK_DBE, 7 }, { IDC_CHK_SYSCALL, 8 }, { IDC_CHK_BREAK, 9 }, { IDC_CHK_II, 10 }, { IDC_CHK_CPU, 11 }, { IDC_CHK_OV, 12 }, { IDC_CHK_TRAP, 13 }, { IDC_CHK_VCEI, 14 }, { IDC_CHK_FPE, 15 }, { IDC_CHK_WATCH, 23 }, { IDC_CHK_VCED, 31 }, { 0, 0 } }; CDebugExcBreakpoints::ExcCheckboxMeta CDebugExcBreakpoints::FpExcCheckboxMap[] = { { IDC_CHK_FP_CI, (1 << 0) }, { IDC_CHK_FP_CU, (1 << 1) }, { IDC_CHK_FP_CO, (1 << 2) }, { IDC_CHK_FP_CZ, (1 << 3) }, { IDC_CHK_FP_CV, (1 << 4) }, { IDC_CHK_FP_CE, (1 << 5) }, { 0, 0 } }; CDebugExcBreakpoints::ExcCheckboxMeta CDebugExcBreakpoints::IntrCheckboxMap[] = { { IDC_CHK_INTR_IP0, (1 << 0) }, { IDC_CHK_INTR_IP1, (1 << 1) }, { IDC_CHK_INTR_IP2, (1 << 2) }, { IDC_CHK_INTR_IP3, (1 << 3) }, { IDC_CHK_INTR_IP4, (1 << 4) }, { IDC_CHK_INTR_IP5, (1 << 5) }, { IDC_CHK_INTR_IP6, (1 << 6) }, { IDC_CHK_INTR_IP7, (1 << 7) }, { 0, 0 } }; CDebugExcBreakpoints::ExcCheckboxMeta CDebugExcBreakpoints::RcpIntrCheckboxMap[] = { { IDC_CHK_INTR_SP, (1 << 0) }, { IDC_CHK_INTR_SI, (1 << 1) }, { IDC_CHK_INTR_AI, (1 << 2) }, { IDC_CHK_INTR_VI, (1 << 3) }, { IDC_CHK_INTR_PI, (1 << 4) }, { IDC_CHK_INTR_DP, (1 << 5) }, { 0, 0 } }; CDebugExcBreakpoints::CDebugExcBreakpoints(CDebuggerUI* debugger) : CDebugDialog(debugger) { } CDebugExcBreakpoints::~CDebugExcBreakpoints() { } LRESULT CDebugExcBreakpoints::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) { DlgSavePos_Init(DebuggerUI_ExceptionBPPos); InitCheckboxes(ExcCheckboxMap, Debugger_ExceptionBreakpoints, true); InitCheckboxes(FpExcCheckboxMap, Debugger_FpExceptionBreakpoints); InitCheckboxes(IntrCheckboxMap, Debugger_IntrBreakpoints); InitCheckboxes(RcpIntrCheckboxMap, Debugger_RcpIntrBreakpoints); uint32_t excBreakpoints = g_Settings->LoadDword(Debugger_ExceptionBreakpoints); uint32_t intrBreakpoints = g_Settings->LoadDword(Debugger_IntrBreakpoints); bool intrEnabled = (excBreakpoints & 0x01) != 0; bool rcpIntrEnabled = (intrBreakpoints & 0x04) != 0; bool fpExcEnabled = (excBreakpoints & (1 << 15)) != 0; EnableCheckboxes(IntrCheckboxMap, intrEnabled); EnableCheckboxes(RcpIntrCheckboxMap, intrEnabled && rcpIntrEnabled); EnableCheckboxes(FpExcCheckboxMap, fpExcEnabled); LoadWindowPos(); WindowCreated(); return TRUE; } LRESULT CDebugExcBreakpoints::OnDestroy(void) { return 0; } LRESULT CDebugExcBreakpoints::OnClicked(WORD /*wNotifyCode*/, WORD wID, HWND, BOOL& /*bHandled*/) { switch (wID) { case IDOK: case IDCANCEL: EndDialog(0); return FALSE; } bool bChecked = (SendMessage(GetDlgItem(wID), BM_GETSTATE, 0, 0) & BST_CHECKED) != 0; if (wID == IDC_CHK_INT) { EnableCheckboxes(IntrCheckboxMap, bChecked); bool toggleRcpIntr = bChecked && (g_Settings->LoadDword(Debugger_IntrBreakpoints) & 0x04); EnableCheckboxes(RcpIntrCheckboxMap, toggleRcpIntr); } if (wID == IDC_CHK_FPE) { EnableCheckboxes(FpExcCheckboxMap, bChecked); } if (wID == IDC_CHK_INTR_IP2) { EnableCheckboxes(RcpIntrCheckboxMap, bChecked); } UpdateBpSetting(ExcCheckboxMap, Debugger_ExceptionBreakpoints, wID, bChecked, true); UpdateBpSetting(FpExcCheckboxMap, Debugger_FpExceptionBreakpoints, wID, bChecked); UpdateBpSetting(IntrCheckboxMap, Debugger_IntrBreakpoints, wID, bChecked); UpdateBpSetting(RcpIntrCheckboxMap, Debugger_RcpIntrBreakpoints, wID, bChecked); return FALSE; } void CDebugExcBreakpoints::OnExitSizeMove(void) { SaveWindowPos(0); } void CDebugExcBreakpoints::InitCheckboxes(ExcCheckboxMeta* checkboxMap, SettingID settingID, bool bShift) { uint32_t excBits = g_Settings->LoadDword(settingID); for (int i = 0; checkboxMap[i].ctrlId != 0; i++) { uint32_t excBit = bShift ? (1 << checkboxMap[i].exc) : checkboxMap[i].exc; if (excBits & excBit) { SendDlgItemMessage(checkboxMap[i].ctrlId, BM_SETCHECK, BST_CHECKED, 0); } } } void CDebugExcBreakpoints::UpdateBpSetting(ExcCheckboxMeta* checkboxMap, SettingID settingID, WORD wID, bool bChecked, bool bShift) { for (int i = 0; checkboxMap[i].ctrlId != 0; i++) { if (checkboxMap[i].ctrlId == wID) { uint32_t excBit = bShift ? (1 << checkboxMap[i].exc) : checkboxMap[i].exc; uint32_t bits = g_Settings->LoadDword(settingID); if (bChecked) { bits |= excBit; } else { bits &= ~excBit; } g_Settings->SaveDword(settingID, bits); return; } } } void CDebugExcBreakpoints::EnableCheckboxes(ExcCheckboxMeta* checkboxMap, bool bEnable) { for (int i = 0; checkboxMap[i].ctrlId != 0; i++) { ::EnableWindow(GetDlgItem(checkboxMap[i].ctrlId), bEnable); } }