diff --git a/src/drivers/win/debugger.cpp b/src/drivers/win/debugger.cpp index e942b3928..ec9aaa1f4 100644 --- a/src/drivers/win/debugger.cpp +++ b/src/drivers/win/debugger.cpp @@ -114,9 +114,9 @@ struct DBGCOLORMENU { bool ChangeColor(HWND hwnd, DBGCOLORMENU* item) { - if (ChangeColor(hwnd, (COLORMENU*)item)) + if (ChangeColor(hwnd, (CHOOSECOLORINFO*)item)) { - item->fmt->crTextColor = RGB(*item->menu.r, *item->menu.g, *item->menu.b); + item->fmt->crTextColor = RGB(*item->menu.info.r, *item->menu.info.g, *item->menu.info.b); return true; } return false; @@ -149,28 +149,51 @@ void UpdateOtherDebuggingDialogs() PPUViewDoBlit(); //PPU Viewer } -#define DISASM_DEFAULT_WIDTH (debuggerIDAFont ? 540 : 470) - +// owomomo: these values should alwasy sync with default debugger window size changes. +/* + The default width of disasm view. + ***NOTE: Currently disasm text is NOT scaled with the screen dpi, so DO NOT use + Muldiv(DISASM_DEFAULT_WIDTH, GetDeviceCaps(hdc, LOGPIXELSY), 96) to convert this + value! +*/ +#define DISASM_DEFAULT_WIDTH (debuggerIDAFont ? 540 : 470) + +/* + The left and right margin of the disasm view in the debugger window, it can be + caclulated by the size of the debugger and the disasm view. + Here's an fake code example of how to get this value: + + RECT wndRect, disasmRect; + GetWindowRect(hDebug, &wndRect); + GetWindowRect(GetDlgItem(hDebug, IDC_DEBUGGER_DISASSEMBLY), &disasmRect); + (disasmRect.left - wndRect.left) + (wndRect.right - disasmRect.right); + + The reason why I directly write it here is to deal with the situation when debugger + width is narrow that some of the left panel is not shown in the window, + (wndRect.right - disasmRect.right) can't get the right value. +*/ +#define DISASM_MARGIN 378 + +/* + When the window size is smaller than these values, the window itself can be shrinked + more, but the panel will keep their minimum size. +*/ #define DEBUGGER_MIN_HEIGHT_LEFT 120 // Minimum height for the left part #define DEBUGGER_MIN_HEIGHT_RIGHT 590 // Minimun height for the right part. +#define DEBUGGER_MIN_WIDTH 380 // Minimum width for debugger -#define DEBUGGER_MIN_WIDTH 360 // Minimum width for debugger #define DEBUGGER_DEFAULT_HEIGHT 594 // default height for debugger -// owomomo: default width of the debugger is depend on the default width of disasm view, so it's not defined here. - +/* + The default width of the debugger is depend on the default width of disasm view, + Since the margin varies from screen dpi but disasm view is not, they cant' use + so it's not defined here. +*/ +// #define DEBUGGER_DEFAULT_WIDTH (DISASM_MARGIN + DISASM_DEFAULT_WIDTH) void RestoreSize(HWND hwndDlg) { HDC hdc = GetDC(hwndDlg); - RECT wndRect, disasmRect; - GetWindowRect(hwndDlg, &wndRect); - GetWindowRect(GetDlgItem(hwndDlg, IDC_DEBUGGER_DISASSEMBLY), &disasmRect); - - int default_width = (disasmRect.left - wndRect.left) + DISASM_DEFAULT_WIDTH + (wndRect.right - disasmRect.right); - int default_height = MulDiv(DEBUGGER_DEFAULT_HEIGHT, GetDeviceCaps(hdc, LOGPIXELSY), 96); - + SetWindowPos(hwndDlg,HWND_TOP, DbgPosX, DbgPosY, MulDiv(DISASM_MARGIN, GetDeviceCaps(hdc, LOGPIXELSY), 96) + DISASM_DEFAULT_WIDTH, MulDiv(DEBUGGER_DEFAULT_HEIGHT, GetDeviceCaps(hdc, LOGPIXELSY), 96), SWP_SHOWWINDOW); ReleaseDC(hwndDlg, hdc); - - SetWindowPos(hwndDlg,HWND_TOP,DbgPosX,DbgPosY,default_width,default_height,SWP_SHOWWINDOW); } unsigned int NewBreakWindows(HWND hwndDlg, unsigned int num, bool enable) @@ -483,6 +506,7 @@ void HighlightSyntax(HWND hWnd, int lines) wordbreak = SendDlgItemMessage(hWnd, IDC_DEBUGGER_DISASSEMBLY, EM_FINDWORDBREAK, (WPARAM)WB_RIGHT, (LPARAM)newline.chrg.cpMin + 21); for (int ch = newline.chrg.cpMin; ; ch++) { + if (debug_wstr[ch] == L'=' || debug_wstr[ch] == L'@' || debug_wstr[ch] == L'\n' || debug_wstr[ch] == L'-' || debug_wstr[ch] == L';') { opbreak = ch; @@ -592,7 +616,7 @@ void Disassemble(HWND hWnd, int id, int scrollid, unsigned int addr) //figure out how many lines we can draw RECT rect; GetClientRect(GetDlgItem(hWnd, id), &rect); - int lines = (rect.bottom-rect.top) / debugSystem->disasmFontHeight; + int lines = (rect.bottom-rect.top) / debugSystem->disasmLineHeight; debug_wstr[0] = 0; PCLine = -1; @@ -983,6 +1007,21 @@ void UpdateBreakpointsCaption() SetDlgItemText(hDebug, IDC_DEBUGGER_BREAKPOINTS, str); } +int GetDebuggerLineHeight(HWND hwnd) +{ + FINDTEXT _newline = newline; + _newline.chrg.cpMin = 0; + _newline.chrg.cpMax = -1; + _newline.chrg.cpMin = SendDlgItemMessage(hwnd, IDC_DEBUGGER_DISASSEMBLY, EM_FINDTEXT, FR_DOWN, (LPARAM)&_newline) + 1; + _newline.chrg.cpMax = SendDlgItemMessage(hwnd, IDC_DEBUGGER_DISASSEMBLY, EM_FINDTEXT, FR_DOWN, (LPARAM)&_newline) + 1; + + POINT line1, line2; + SendDlgItemMessage(hwnd, IDC_DEBUGGER_DISASSEMBLY, EM_POSFROMCHAR, (WPARAM)&line1, _newline.chrg.cpMin); + SendDlgItemMessage(hwnd, IDC_DEBUGGER_DISASSEMBLY, EM_POSFROMCHAR, (WPARAM)&line2, _newline.chrg.cpMax); + + return line2.y - line1.y; +} + void UpdateDebugger(bool jump_to_pc) { //don't do anything if the debugger is not visible @@ -1003,7 +1042,7 @@ void UpdateDebugger(bool jump_to_pc) // ensure that PC pointer will be visible even after the window was resized RECT rect; GetClientRect(GetDlgItem(hDebug, IDC_DEBUGGER_DISASSEMBLY), &rect); - unsigned int lines = (rect.bottom-rect.top) / debugSystem->disasmFontHeight; + unsigned int lines = (rect.bottom-rect.top) / debugSystem->disasmLineHeight; if (PC_pointerOffset >= lines) PC_pointerOffset = 0; @@ -1799,7 +1838,7 @@ BOOL CALLBACK IDC_DEBUGGER_DISASSEMBLY_WndProc(HWND hwndDlg, UINT uMsg, WPARAM w { case WM_LBUTTONDBLCLK: { - int offset = Debugger_CheckClickingOnAnAddressOrSymbolicName(GET_Y_LPARAM(lParam) / debugSystem->disasmFontHeight, false); + int offset = Debugger_CheckClickingOnAnAddressOrSymbolicName(GET_Y_LPARAM(lParam) / debugSystem->disasmLineHeight, false); if (offset != EOF) { // bring "Add Breakpoint" dialog @@ -1813,7 +1852,7 @@ BOOL CALLBACK IDC_DEBUGGER_DISASSEMBLY_WndProc(HWND hwndDlg, UINT uMsg, WPARAM w } case WM_LBUTTONUP: { - Debugger_CheckClickingOnAnAddressOrSymbolicName(GET_Y_LPARAM(lParam) / debugSystem->disasmFontHeight, true); + Debugger_CheckClickingOnAnAddressOrSymbolicName(GET_Y_LPARAM(lParam) / debugSystem->disasmLineHeight, true); break; } case WM_RBUTTONDOWN: @@ -1838,7 +1877,7 @@ BOOL CALLBACK IDC_DEBUGGER_DISASSEMBLY_WndProc(HWND hwndDlg, UINT uMsg, WPARAM w CallWindowProc(IDC_DEBUGGER_DISASSEMBLY_oldWndProc, hwndDlg, WM_LBUTTONDOWN, wParam, lParam); CallWindowProc(IDC_DEBUGGER_DISASSEMBLY_oldWndProc, hwndDlg, WM_LBUTTONUP, wParam, lParam); // try bringing Symbolic Debug Naming dialog - int offset = Debugger_CheckClickingOnAnAddressOrSymbolicName(GET_Y_LPARAM(lParam) / debugSystem->disasmFontHeight, false); + int offset = Debugger_CheckClickingOnAnAddressOrSymbolicName(GET_Y_LPARAM(lParam) / debugSystem->disasmLineHeight, false); if (offset != EOF) { if (DoSymbolicDebugNaming(offset, hDebug)) @@ -1875,7 +1914,7 @@ BOOL CALLBACK IDC_DEBUGGER_DISASSEMBLY_WndProc(HWND hwndDlg, UINT uMsg, WPARAM w if(mouse_y < 0 || mouse_x < 0) break; - tmp = mouse_y / debugSystem->disasmFontHeight; + tmp = mouse_y / debugSystem->disasmLineHeight; if (tmp < (int)disassembly_addresses.size()) { i = disassembly_addresses[tmp]; @@ -1986,7 +2025,6 @@ INT_PTR CALLBACK DebuggerCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lP SetScrollInfo(GetDlgItem(hwndDlg,IDC_DEBUGGER_DISASSEMBLY_VSCR),SB_CTL,&si,TRUE); //setup font - SendDlgItemMessage(hwndDlg,IDC_DEBUGGER_DISASSEMBLY,WM_SETFONT,(WPARAM)debugSystem->hDisasmFont,FALSE); SendDlgItemMessage(hwndDlg,IDC_DEBUGGER_DISASSEMBLY_LEFT_PANEL,WM_SETFONT,(WPARAM)debugSystem->hFixedFont,FALSE); //SendDlgItemMessage(hwndDlg,IDC_DEBUGGER_VAL_A,WM_SETFONT,(WPARAM)debugSystem->hFixedFont,FALSE); //SendDlgItemMessage(hwndDlg,IDC_DEBUGGER_VAL_X,WM_SETFONT,(WPARAM)debugSystem->hFixedFont,FALSE); @@ -2037,6 +2075,25 @@ INT_PTR CALLBACK DebuggerCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lP // prevent the font of the edit control from screwing up when it contains MBC or characters not contained the current font. SendDlgItemMessage(hwndDlg, IDC_DEBUGGER_DISASSEMBLY, EM_SETLANGOPTIONS, 0, SendDlgItemMessage(hwndDlg, IDC_DEBUGGER_DISASSEMBLY, EM_GETLANGOPTIONS, 0, 0) & ~IMF_AUTOFONT); + /* owomomo: calculate the actural line height of the disassembly view. + the font height is not always equals to the line height in rich edit control. + As most developers uses latin letters, the font height and line height are + same in their Windows, but there are many languages aren't. + This is probably why this bug is not mentioned and fixed for a long time. + */ + SetDlgItemText(hwndDlg, IDC_DEBUGGER_DISASSEMBLY, "\r\n\r\n\r\n"); + + SendDlgItemMessage(hwndDlg, IDC_DEBUGGER_DISASSEMBLY, WM_SETFONT, (WPARAM)debugSystem->hIDAFont, FALSE); + debugSystem->IDAFontLineHeight = GetDebuggerLineHeight(hwndDlg); + + SendDlgItemMessage(hwndDlg, IDC_DEBUGGER_DISASSEMBLY, WM_SETFONT, (WPARAM)debugSystem->hFixedFont, FALSE); + debugSystem->fixedFontLineHeight = GetDebuggerLineHeight(hwndDlg); + + debugSystem->hDisasmFont = debuggerIDAFont ? debugSystem->hIDAFont : debugSystem->hFixedFont; + debugSystem->disasmLineHeight = debuggerIDAFont ? debugSystem->IDAFontLineHeight : debugSystem->fixedFontLineHeight; + if (debuggerIDAFont) + SendDlgItemMessage(hwndDlg, IDC_DEBUGGER_DISASSEMBLY, WM_SETFONT, (WPARAM)debugSystem->hDisasmFont, FALSE); + // subclass editfield IDC_DEBUGGER_DISASSEMBLY_oldWndProc = (WNDPROC)SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_DEBUGGER_DISASSEMBLY), GWLP_WNDPROC, (LONG_PTR)IDC_DEBUGGER_DISASSEMBLY_WndProc); @@ -2100,8 +2157,6 @@ INT_PTR CALLBACK DebuggerCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lP } break; } - - case WM_CLOSE: case WM_QUIT: //exitdebug: @@ -2140,7 +2195,7 @@ INT_PTR CALLBACK DebuggerCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lP case DEBUGIDAFONT: debuggerIDAFont ^= 1; debugSystem->hDisasmFont = debuggerIDAFont ? debugSystem->hIDAFont : debugSystem->hFixedFont; - debugSystem->disasmFontHeight = debuggerIDAFont ? IDAFontSize : debugSystem->fixedFontHeight; + debugSystem->disasmLineHeight = debuggerIDAFont ? debugSystem->IDAFontLineHeight : debugSystem->fixedFontLineHeight; SendDlgItemMessage(hwndDlg, IDC_DEBUGGER_DISASSEMBLY, WM_SETFONT, (WPARAM)debugSystem->hDisasmFont, FALSE); UpdateDebugger(false); break; @@ -2171,7 +2226,7 @@ INT_PTR CALLBACK DebuggerCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lP RestoreDefaultDebugColor(); RECT rect; GetClientRect(GetDlgItem(hwndDlg, IDC_DEBUGGER_DISASSEMBLY), &rect); - UpdateDisassembleView(hwndDlg, IDC_DEBUGGER_DISASSEMBLY, (rect.bottom - rect.top) / debugSystem->disasmFontHeight); + UpdateDisassembleView(hwndDlg, IDC_DEBUGGER_DISASSEMBLY, (rect.bottom - rect.top) / debugSystem->disasmLineHeight); HMENU hcolorpopupmenu = GetSubMenu(GetMenu(hwndDlg), 1); for (int i = 0; i < sizeof(dbgcolormenu) / sizeof(DBGCOLORMENU); ++i) ModifyColorMenu(hwndDlg, hcolorpopupmenu, &dbgcolormenu[i].menu, i, ID_COLOR_DEBUGGER + i); @@ -2197,7 +2252,7 @@ INT_PTR CALLBACK DebuggerCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lP { RECT rect; GetClientRect(GetDlgItem(hwndDlg, IDC_DEBUGGER_DISASSEMBLY), &rect); - UpdateDisassembleView(hwndDlg, IDC_DEBUGGER_DISASSEMBLY, (rect.bottom - rect.top) / debugSystem->disasmFontHeight); + UpdateDisassembleView(hwndDlg, IDC_DEBUGGER_DISASSEMBLY, (rect.bottom - rect.top) / debugSystem->disasmLineHeight); ModifyColorMenu(hwndDlg, GetSubMenu(GetMenu(hwndDlg), 1), &dbgcolormenu[index].menu, index, wParam); } } @@ -2344,11 +2399,11 @@ INT_PTR CALLBACK DebuggerCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lP } SetScrollInfo((HWND)lParam,SB_CTL,&si,TRUE); - Disassemble(hDebug, IDC_DEBUGGER_DISASSEMBLY, IDC_DEBUGGER_DISASSEMBLY_VSCR, si.nPos); + Disassemble(hwndDlg, IDC_DEBUGGER_DISASSEMBLY, IDC_DEBUGGER_DISASSEMBLY_VSCR, si.nPos); // "Address Bookmark Add" follows the address char str[16]; sprintf(str,"%04X", si.nPos); - SetDlgItemText(hDebug, IDC_DEBUGGER_BOOKMARK, str); + SetDlgItemText(hwndDlg, IDC_DEBUGGER_BOOKMARK, str); break; } case WM_KEYDOWN: @@ -2365,18 +2420,18 @@ INT_PTR CALLBACK DebuggerCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lP { setString = true; RECT rectDisassembly; - GetClientRect(GetDlgItem(hDebug,IDC_DEBUGGER_DISASSEMBLY),&rectDisassembly); + GetClientRect(GetDlgItem(hwndDlg,IDC_DEBUGGER_DISASSEMBLY),&rectDisassembly); int height = rectDisassembly.bottom-rectDisassembly.top; mouse_y -= 10; if(mouse_y > height) setString = false; - mouse_y /= debugSystem->disasmFontHeight; + mouse_y /= debugSystem->disasmLineHeight; } if (setString) - SetDlgItemText(hDebug, IDC_DEBUGGER_ADDR_LINE, "Leftclick = Inline Assembler. Midclick = Game Genie. Rightclick = Hexeditor."); + SetDlgItemText(hwndDlg, IDC_DEBUGGER_ADDR_LINE, "Leftclick = Inline Assembler. Midclick = Game Genie. Rightclick = Hexeditor."); else - SetDlgItemText(hDebug, IDC_DEBUGGER_ADDR_LINE, ""); + SetDlgItemText(hwndDlg, IDC_DEBUGGER_ADDR_LINE, ""); break; } case WM_LBUTTONDOWN: @@ -2391,7 +2446,7 @@ INT_PTR CALLBACK DebuggerCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lP if (FCEUI_EmulationPaused() && (mouse_x > 6) && (mouse_x < 30) && (mouse_y > 10)) { // ################################## End of SP CODE ########################### - int tmp = (mouse_y - 10) / debugSystem->disasmFontHeight; + int tmp = (mouse_y - 10) / debugSystem->disasmLineHeight; if (tmp < (int)disassembly_addresses.size()) { int i = disassembly_addresses[tmp]; @@ -2413,7 +2468,7 @@ INT_PTR CALLBACK DebuggerCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lP //mbg merge 7/18/06 changed pausing check if (FCEUI_EmulationPaused() && (mouse_x > 6) && (mouse_x < 30) && (mouse_y > 10)) { - int tmp = (mouse_y - 10) / debugSystem->disasmFontHeight; + int tmp = (mouse_y - 10) / debugSystem->disasmLineHeight; if (tmp < (int)disassembly_addresses.size()) { int i = disassembly_addresses[tmp]; @@ -2434,7 +2489,7 @@ INT_PTR CALLBACK DebuggerCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lP //mbg merge 7/18/06 changed pausing check if (FCEUI_EmulationPaused() && (mouse_x > 6) && (mouse_x < 30) && (mouse_y > 10)) { - int tmp = (mouse_y - 10) / debugSystem->disasmFontHeight; + int tmp = (mouse_y - 10) / debugSystem->disasmLineHeight; if (tmp < (int)disassembly_addresses.size()) { int i = disassembly_addresses[tmp]; @@ -2567,10 +2622,10 @@ INT_PTR CALLBACK DebuggerCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lP { sprintf(str,"%04X", tmp); SetDlgItemText(hwndDlg,IDC_DEBUGGER_VAL_PCSEEK,str); - Disassemble(hDebug, IDC_DEBUGGER_DISASSEMBLY, IDC_DEBUGGER_DISASSEMBLY_VSCR, tmp); + Disassemble(hwndDlg, IDC_DEBUGGER_DISASSEMBLY, IDC_DEBUGGER_DISASSEMBLY_VSCR, tmp); // "Address Bookmark Add" follows the address sprintf(str,"%04X", si.nPos); - SetDlgItemText(hDebug, IDC_DEBUGGER_BOOKMARK, str); + SetDlgItemText(hwndDlg, IDC_DEBUGGER_BOOKMARK, str); } break; } @@ -2839,7 +2894,6 @@ void DebugSystem::init() SelectObject(hdc,old); DeleteDC(hdc); hDisasmFont = debuggerIDAFont ? hIDAFont : hFixedFont; - disasmFontHeight = debuggerIDAFont ? IDAFontSize : fixedFontHeight; InitDbgCharFormat(); diff --git a/src/drivers/win/debugger.h b/src/drivers/win/debugger.h index 2063229e2..68abf8ab7 100644 --- a/src/drivers/win/debugger.h +++ b/src/drivers/win/debugger.h @@ -57,11 +57,14 @@ extern class DebugSystem { HFONT hFixedFont; int fixedFontWidth; int fixedFontHeight; + int fixedFontLineHeight; HFONT hIDAFont; + int IDAFontLineHeight; HFONT hDisasmFont; - int disasmFontHeight; + + int disasmLineHeight; HFONT hHexeditorFont; int HexeditorFontWidth; @@ -138,7 +141,7 @@ _OP(DbgRts, 187, 80, 93) /* Imayou */ #define SPCLR(pf, name, suf) pf SBCLR(name, suf) #define CSCLR(pf, name, suf, op, val) SPCLR(pf, name, suf) op val #define CNRGB(pf, name, op, r, g, b, sep) CSCLR(pf, name, R, op, r) sep CSCLR(pf, name, G, op, g) sep CSCLR(pf, name, B, op, b) -#define PPRGB(name) NULL, CNRGB(&, name, , , , , _COMMA) +#define PPRGB(name) CNRGB(&, name, , , , , _COMMA), NULL #define MKRGB(name) (RGB(SBCLR(name, R), SBCLR(name, G), SBCLR(name, B))) #define DEFRGB(name, r, g, b) CNRGB( , name, =, r, g, b, _COMMA) #define DCLRGB(name, r, g, b) CNRGB( , name, , , , , _COMMA) diff --git a/src/drivers/win/memview.cpp b/src/drivers/win/memview.cpp index 66367835b..50d48b103 100644 --- a/src/drivers/win/memview.cpp +++ b/src/drivers/win/memview.cpp @@ -2396,7 +2396,7 @@ LRESULT CALLBACK MemViewCallB(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa case ID_COLOR_HEXEDITOR + 9: { int index = wParam - ID_COLOR_HEXEDITOR; - if (ChangeColor(hwnd, &hexcolormenu[index])) + if (ChangeColor(hwnd, (CHOOSECOLORINFO*)&hexcolormenu[index])) { UpdateColorTable(); ModifyColorMenu(hwnd, GetHexColorMenu(hwnd), &hexcolormenu[index], index, wParam); @@ -2426,7 +2426,7 @@ LRESULT CALLBACK MemViewCallB(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa case ID_COLOR_CDLOGGER + 9: { int index = wParam - ID_COLOR_CDLOGGER; - if (ChangeColor(hwnd, &cdlcolormenu[index])) + if (ChangeColor(hwnd, (CHOOSECOLORINFO*)&cdlcolormenu[index])) { UpdateColorTable(); ModifyColorMenu(hwnd, GetCdlColorMenu(hwnd), &cdlcolormenu[index], index, wParam); @@ -2438,7 +2438,7 @@ LRESULT CALLBACK MemViewCallB(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa { RestoreDefaultCdlColor(); UpdateColorTable(); - for (int i = 0; i < sizeof(hexcolormenu) / sizeof(COLORMENU); ++i) + for (int i = 0; i < sizeof(cdlcolormenu) / sizeof(COLORMENU); ++i) ModifyColorMenu(hwnd, GetCdlColorMenu(hwnd), &cdlcolormenu[i], i, ID_COLOR_CDLOGGER + i); } break; @@ -3241,7 +3241,7 @@ void SwitchEditingText(int editingText) { } } -bool ChangeColor(HWND hwnd, COLORMENU* item) +bool ChangeColor(HWND hwnd, CHOOSECOLORINFO* item) { int backup = RGB(*item->r, *item->g, *item->b); CHOOSECOLOR choose; @@ -3249,8 +3249,10 @@ bool ChangeColor(HWND hwnd, COLORMENU* item) choose.lStructSize = sizeof(CHOOSECOLOR); choose.hwndOwner = hwnd; choose.rgbResult = backup; + choose.lCustData = (LPARAM)item; choose.lpCustColors = custom_color; - choose.Flags = CC_RGBINIT | CC_FULLOPEN | CC_ANYCOLOR; + choose.lpfnHook = (LPCCHOOKPROC)ChooseColorHookProc; + choose.Flags = CC_RGBINIT | CC_FULLOPEN | CC_ANYCOLOR | CC_ENABLEHOOK; if (ChooseColor(&choose) && choose.rgbResult != backup) { *item->r = GetRValue(choose.rgbResult); @@ -3270,26 +3272,16 @@ BOOL OpColorMenu(HWND hwnd, HMENU menu, COLORMENU* item, int pos, int id, BOOL ( memset(&info, 0, sizeof(MENUITEMINFO)); info.cbSize = sizeof(MENUITEMINFO); - if (item->text) + CHOOSECOLORINFO *color_info = (CHOOSECOLORINFO*)item; + if (color_info->name) { - HDC hdc = GetDC(hwnd); - HDC memdc = CreateCompatibleDC(hdc); - - int width = GetSystemMetrics(SM_CXMENUCHECK); - int height = GetSystemMetrics(SM_CYMENUCHECK); - - if (!item->bitmap) - item->bitmap = CreateCompatibleBitmap(hdc, width, height); - SelectObject(memdc, item->bitmap); - HBRUSH brush = CreateSolidBrush(RGB(*item->r, *item->g, *item->b)); - RECT rect = { 1, 1, width - 1, height - 1}; - FillRect(memdc, &rect, brush); - DeleteObject(brush); - DeleteDC(memdc); - ReleaseDC(hwnd, hdc); + + if (item->bitmap) + DeleteObject(item->bitmap); + item->bitmap = CreateColorBitmap(hwnd, GetSystemMetrics(SM_CXMENUCHECK), GetSystemMetrics(SM_CYMENUCHECK), RGB(*color_info->r, *color_info->g, *color_info->b)); char menu_str[64]; - sprintf(menu_str, "%s\t#%02X%02X%02X", item->text, *item->r, *item->g, *item->b); + sprintf(menu_str, "%s\t#%02X%02X%02X", color_info->name, *color_info->r, *color_info->g, *color_info->b); info.dwTypeData = menu_str; info.cch = strlen(menu_str); @@ -3306,4 +3298,68 @@ BOOL OpColorMenu(HWND hwnd, HMENU menu, COLORMENU* item, int pos, int id, BOOL ( } return opMenu(menu, pos, TRUE, &info); +} + +UINT CALLBACK ChooseColorHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam) +{ + static HICON icon; + + switch (uiMsg) + { + case WM_INITDIALOG: + { + CHOOSECOLORINFO* item = (CHOOSECOLORINFO*)((CHOOSECOLOR*)lParam)->lCustData; + + char title[128]; + strcpy(title, "Choose color for "); + strcat(title, item->name); + SetWindowText(hdlg, title); + + icon = CreateChooseColorIcon(hdlg, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), RGB(*item->r, *item->g, *item->b)); + SendMessage(hdlg, WM_SETICON, ICON_SMALL, (LPARAM)icon); + break; + } + case WM_CLOSE: + case WM_QUIT: + DestroyIcon(icon); + } + + return FALSE; +} + +HBITMAP CreateColorBitmap(HWND hwnd, int width, int height, COLORREF color) +{ + + HDC hdc = GetDC(hwnd); + HDC memdc = CreateCompatibleDC(hdc); + + HBITMAP bitmap = CreateCompatibleBitmap(hdc, width, height); + HGDIOBJ oldObj = SelectObject(memdc, bitmap); + HBRUSH brush = CreateSolidBrush(color); + RECT rect = { 1, 1, width - 1, height - 1 }; + FillRect(memdc, &rect, brush); + + SelectObject(memdc, oldObj); + DeleteObject(brush); + DeleteDC(memdc); + ReleaseDC(hwnd, hdc); + + return bitmap; +} + +HICON CreateChooseColorIcon(HWND hwnd, int width, int height, COLORREF color) +{ + + HBITMAP bitmap = CreateColorBitmap(hwnd, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), color); + + ICONINFO info; + memset(&info, 0, sizeof(ICONINFO)); + info.hbmColor = bitmap; + info.hbmMask = bitmap; + info.fIcon = true; + HICON icon = CreateIconIndirect(&info); + + DeleteObject(bitmap); + + return icon; } \ No newline at end of file diff --git a/src/drivers/win/memview.h b/src/drivers/win/memview.h index d943744fb..e83e274aa 100644 --- a/src/drivers/win/memview.h +++ b/src/drivers/win/memview.h @@ -21,15 +21,24 @@ extern int EditingMode; extern char* EditString[4]; +struct CHOOSECOLORINFO +{ + char* name; + int *r, *g, *b; +}; + struct COLORMENU { - char* text; + CHOOSECOLORINFO info; HBITMAP bitmap; - int *r, *g, *b; }; -bool ChangeColor(HWND hwnd, COLORMENU* item); +bool ChangeColor(HWND hwnd, CHOOSECOLORINFO* item); BOOL OpColorMenu(HWND hwnd, HMENU menu, COLORMENU* item, int pos, int id, BOOL (WINAPI *opMenu)(HMENU hmenu, UINT item, BOOL byPos, LPCMENUITEMINFO info)); #define InsertColorMenu(hwnd, menu, item, pos, id) OpColorMenu(hwnd, menu, item, pos, id, InsertMenuItem) #define ModifyColorMenu(hwnd, menu, item, pos, id) OpColorMenu(hwnd, menu, item, pos, id, SetMenuItemInfo) #define GetHexColorMenu(hwnd) (GetSubMenu(GetSubMenu(GetMenu(hwnd), HIGHLIGHTING_SUBMENU_POS), HEXEDITOR_COLOR_SUBMENU_POS)) #define GetCdlColorMenu(hwnd) (GetSubMenu(GetSubMenu(GetMenu(hwnd), HIGHLIGHTING_SUBMENU_POS), CDLOGGER_COLOR_SUBMENU_POS)) + +UINT CALLBACK ChooseColorHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam); +HBITMAP CreateColorBitmap(HWND hwnd, int width, int height, COLORREF color); +HICON CreateChooseColorIcon(HWND hwnd, int width, int height, COLORREF color); #endif \ No newline at end of file diff --git a/src/drivers/win/memwatch.cpp b/src/drivers/win/memwatch.cpp index 48948ab22..6765ab7ae 100644 --- a/src/drivers/win/memwatch.cpp +++ b/src/drivers/win/memwatch.cpp @@ -790,7 +790,7 @@ static INT_PTR CALLBACK MemWatchCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LP xPositions[i] = r.left; // experimental: limit the text length and input to hex values - SendDlgItemMessage(hwndDlg, MW_ADDR[i], EM_SETLIMITTEXT, 4, 0); + SendDlgItemMessage(hwndDlg, MW_ADDR[i], EM_SETLIMITTEXT, 6, 0); DefaultEditCtrlProc = (WNDPROC)SetWindowLongPtr(GetDlgItem(hwndDlg, MW_ADDR[i]), GWLP_WNDPROC, (LONG_PTR)FilterEditCtrlProc); } @@ -1085,8 +1085,8 @@ void RamChange() { case 0: whichADDR = 0; break; //Addr 1 case 1: whichADDR = 1; break; //Addr 2 - case 2: whichADDR = 11; break; //Addr 12 - case 3: whichADDR = 12; break; //Addr 13 + case 2: whichADDR = 12; break; //Addr 13 + case 3: whichADDR = 13; break; //Addr 14 } GetDlgItemText(hwndMemWatch, MW_ADDR[whichADDR], editboxnow[x], 6); //Get Address value of edit00 SetDlgItemText(hwndMemWatch, MW_RMADDR[x], editboxnow[x]); //Put Address value @@ -1129,11 +1129,11 @@ void RamChange() } sprintf(editchangem[x], "%d", editcount[x]); //Convert counter to text - SetDlgItemText(hwndMemWatch, EDIT00_RESULTS+x, editchangem[x]); //Display text in results box + SetDlgItemText(hwndMemWatch, MW_RESULT[x], editchangem[x]); //Display text in results box } else { - SetDlgItemText(hwndMemWatch, MEMW_EDIT00RMADDRESS+x, ""); + SetDlgItemText(hwndMemWatch, MW_RMADDR[x], ""); } } //End of for loop } diff --git a/src/drivers/win/palette.cpp b/src/drivers/win/palette.cpp index 7ca57ebf1..76283e93e 100644 --- a/src/drivers/win/palette.cpp +++ b/src/drivers/win/palette.cpp @@ -3,6 +3,11 @@ #include "main.h" #include "window.h" #include "gui.h" +#include "../../palette.h" +#include "memview.h" + +#define ToGrey(r, g, b) ((int)((float)(r) * 0.299F + (float)(g) * 0.587F + (float)(b) * 0.114F)) +#define GetPaletteIndex(x, y) ((x) > palpv->pvRect.left && (x) < palpv->pvRect.right && (y) > palpv->pvRect.top && (y) < palpv->pvRect.bottom ? floor((float)((x) - palpv->pvRect.left) / palpv->cell_width) + (int)floor((float)((y) - palpv->pvRect.top) / palpv->cell_height) * 16 : -1) int cpalette_count = 0; u8 cpalette[64*8*3] = {0}; @@ -12,7 +17,19 @@ extern int palsharpness; extern int palcontrast; extern int palbrightness; extern bool paldeemphswap; +bool palcolorindex = false; HWND hWndPal = NULL; +extern pal palette[512], rp2c04001[512], rp2c04002[512], rp2c04003[512], rp2c05004[512], palette_game[64*8], palette_ntsc[64*8], palette_user[64*8], palette_unvarying[23]; + +struct PALPV { + int mouse_index; + float cell_height, cell_width; + char buf[4]; + RECT pvRect; + SIZE pvSize; + HBITMAP pvBitmap; + HFONT font; +} *palpv; bool SetPalette(const char* nameo) { @@ -38,9 +55,9 @@ bool SetPalette(const char* nameo) * * @return Flag that indicates failure (0) or success (1) **/ -int LoadPaletteFile() +int LoadPaletteFile(HWND hwnd) { - const char filter[]="All usable files (*.pal)\0*.pal\0All Files (*.*)\0*.*\0\0"; + const char filter[]="Palette file (*.pal)\0*.pal\0All Files (*.*)\0*.*\0\0"; bool success = false; char nameo[2048]; @@ -61,20 +78,131 @@ int LoadPaletteFile() if(GetOpenFileName(&ofn)) { success = SetPalette(nameo); + if (!success) + MessageBox(hwnd, "Error loading palette file.", "Load palette file", MB_OK | MB_ICONERROR); } return success; } +/** +* Prompts the user for a palette file and saves that file. +* @return Flag that indicates failure (0) or success (1) +**/ +int SavePaletteFile(HWND hwnd) +{ + const char filter[] = "Palette file (*.pal)\0*.pal\0All Files (*.*)\0*.*\0\0"; + + bool success = false; + char nameo[2048]; + + // Display save file dialog + OPENFILENAME ofn; + memset(&ofn, 0, sizeof(ofn)); + ofn.lStructSize = sizeof(ofn); + ofn.hInstance = fceu_hInstance; + ofn.lpstrTitle = FCEU_NAME" Save Palette File..."; + ofn.lpstrFilter = filter; + ofn.lpstrDefExt = "pal"; + nameo[0] = 0; + ofn.lpstrFile = nameo; + ofn.nMaxFile = 256; + ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; + ofn.lpstrInitialDir = 0; + + if (GetSaveFileName(&ofn)) + { + FILE* pal_file = fopen(nameo, "wb"); + if (pal_file) + { + fwrite(palo, 64 * 3, 1, pal_file); + fclose(pal_file); + success = true; + } + else + MessageBox(hwnd, "Error saving palette file.", "Save palette file", MB_OK | MB_ICONERROR); + } + + return success; +} + +/** +* Notify the dialog to redraw the palette preview area +**/ +void InvalidatePalettePreviewRect(HWND hwnd) +{ + InvalidateRect(hwnd, &palpv->pvRect, FALSE); + UpdateWindow(hwnd); +} + +void UpdatePalettePreviewCaption(HWND hwnd, int x, int y) +{ + int mouse_index = GetPaletteIndex(x, y); + + if (palpv->mouse_index != mouse_index) + { + if (mouse_index != -1) + { + char str[64]; + if (force_grayscale) + sprintf(str, "Greyscale $%02X: #%02X (Actural: #%02X%02X%02X)", mouse_index, ToGrey(palo[mouse_index].r, palo[mouse_index].g, palo[mouse_index].b), palo[mouse_index].r, palo[mouse_index].g, palo[mouse_index].b); + else + sprintf(str, "Color $%02X: #%02X%02X%02X", mouse_index, palo[mouse_index].r, palo[mouse_index].g, palo[mouse_index].b); + SetDlgItemText(hwnd, IDC_PALETTE_PREVIEW_GROUPBOX, str); + } + else + SetDlgItemText(hwnd, IDC_PALETTE_PREVIEW_GROUPBOX, "Preview"); + palpv->mouse_index = mouse_index; + } +} + +void UpdatePalettePreviewCaption(HWND hwnd) +{ + POINT p; + GetCursorPos(&p); + ScreenToClient(hwnd, &p); + + palpv->mouse_index = -1; + UpdatePalettePreviewCaption(hwnd, p.x, p.y); + +} + +void UpdateCurrentPaletteName(HWND hwnd) +{ + if (!palo) + SetDlgItemText(hwnd, IDC_PALETTE_CURRENT, "None"); + else if (palo == (pal*)&palette) + SetDlgItemText(hwnd, IDC_PALETTE_CURRENT, "NES Default"); + else if (palo == (pal*)&rp2c04001) + SetDlgItemText(hwnd, IDC_PALETTE_CURRENT, "RP2C04-01"); + else if (palo == (pal*)&rp2c04002) + SetDlgItemText(hwnd, IDC_PALETTE_CURRENT, "RP2C04-02"); + else if (palo == (pal*)&rp2c04003) + SetDlgItemText(hwnd, IDC_PALETTE_CURRENT, "RP2C04-03"); + else if (palo == (pal*)&rp2c05004) + SetDlgItemText(hwnd, IDC_PALETTE_CURRENT, "RC2C05-04"); + else if (palo == (pal*)&palette_game) + SetDlgItemText(hwnd, IDC_PALETTE_CURRENT, "Game specific"); + else if (palo == (pal*)&palette_ntsc) + SetDlgItemText(hwnd, IDC_PALETTE_CURRENT, "NTSC"); + else if (palo == (pal*)&palette_user) + SetDlgItemText(hwnd, IDC_PALETTE_CURRENT, "Custom"); + else if (palo == (pal*)&palette_unvarying) + SetDlgItemText(hwnd, IDC_PALETTE_CURRENT, "Internal"); + else + SetDlgItemText(hwnd, IDC_PALETTE_CURRENT, "Unknown"); +} + /** * Callback function for the palette configuration dialog. **/ INT_PTR CALLBACK PaletteConCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { - char text[40]; + switch(uMsg) { case WM_INITDIALOG: + { if(ntsccol_enable) CheckDlgButton(hwndDlg, CHECK_PALETTE_ENABLED, BST_CHECKED); @@ -88,6 +216,9 @@ INT_PTR CALLBACK PaletteConCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM if (eoptions & EO_CPALETTE) CheckDlgButton(hwndDlg, CHECK_PALETTE_CUSTOM, BST_CHECKED); + if (palcolorindex) + CheckDlgButton(hwndDlg, CHECK_PALETTE_COLOR_INDEX, BST_CHECKED); + SendDlgItemMessage(hwndDlg, CTL_TINT_TRACKBAR, TBM_SETRANGE, 1, MAKELONG(0, 128)); SendDlgItemMessage(hwndDlg, CTL_HUE_TRACKBAR, TBM_SETRANGE, 1, MAKELONG(0, 128)); SendDlgItemMessage(hwndDlg, CTL_PALNOTCH_TRACKBAR, TBM_SETRANGE, 1, MAKELONG(0, 100)); @@ -96,6 +227,7 @@ INT_PTR CALLBACK PaletteConCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM SendDlgItemMessage(hwndDlg, CTL_PALCONTRAST_TRACKBAR,TBM_SETRANGE, 1, MAKELONG(0, 200)); SendDlgItemMessage(hwndDlg, CTL_PALBRIGHT_TRACKBAR, TBM_SETRANGE, 1, MAKELONG(0, 100)); + char text[40]; FCEUI_GetNTSCTH(&ntsctint, &ntschue); sprintf(text, "Notch: %d%%", palnotch); SendDlgItemMessage(hwndDlg, STATIC_NOTCHVALUE, WM_SETTEXT, 0, (LPARAM) text); @@ -123,9 +255,35 @@ INT_PTR CALLBACK PaletteConCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM EnableWindow(GetDlgItem(hwndDlg, CTL_HUE_TRACKBAR), ntsccol_enable); EnableWindow(GetDlgItem(hwndDlg, CTL_TINT_TRACKBAR), ntsccol_enable); - break; - + palpv = (PALPV*)malloc(sizeof(PALPV)); + + HWND hpalpv = GetDlgItem(hwndDlg, IDC_PALETTE_PREVIEW); + GetClientRect(hpalpv, &palpv->pvRect); + palpv->pvSize = *((SIZE*)&palpv->pvRect + 1); + ClientToScreen(hpalpv, (POINT*)&palpv->pvRect); + ClientToScreen(hpalpv, ((POINT*)&palpv->pvRect) + 1); + ScreenToClient(hwndDlg, (POINT*)&palpv->pvRect); + ScreenToClient(hwndDlg, ((POINT*)&palpv->pvRect) + 1); + + LOGFONT logFont; + GetObject((HANDLE)SendMessage(hwndDlg, WM_GETFONT, NULL, NULL), sizeof(logFont), &logFont); + palpv->font = (HFONT)CreateFontIndirect(&logFont); + + palpv->cell_width = (float)palpv->pvSize.cx / 16; + palpv->cell_height = (float)palpv->pvSize.cy / 4; + + HDC hdc = GetDC(hwndDlg); + HDC memdc = CreateCompatibleDC(hdc); + palpv->pvBitmap = CreateCompatibleBitmap(hdc, palpv->pvSize.cx, palpv->pvSize.cy); + DeleteDC(memdc); + ReleaseDC(hwndDlg, hdc); + + UpdateCurrentPaletteName(hwndDlg); + UpdatePalettePreviewCaption(hwndDlg); + } + break; case WM_HSCROLL: + { ntsctint = SendDlgItemMessage(hwndDlg, CTL_TINT_TRACKBAR, TBM_GETPOS, 0, (LPARAM)(LPSTR)0); ntschue = SendDlgItemMessage(hwndDlg, CTL_HUE_TRACKBAR, TBM_GETPOS, 0, (LPARAM)(LPSTR)0); palnotch = SendDlgItemMessage(hwndDlg, CTL_PALNOTCH_TRACKBAR, TBM_GETPOS, 0, (LPARAM)(LPSTR)0); @@ -135,6 +293,7 @@ INT_PTR CALLBACK PaletteConCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM palbrightness = SendDlgItemMessage(hwndDlg, CTL_PALBRIGHT_TRACKBAR, TBM_GETPOS, 0, (LPARAM)(LPSTR)0); FCEUI_SetNTSCTH(ntsccol_enable, ntsctint, ntschue); + char text[40]; sprintf(text, "Notch: %d%%", palnotch); SendDlgItemMessage(hwndDlg, STATIC_NOTCHVALUE, WM_SETTEXT, 0, (LPARAM) text); sprintf(text, "Saturation: %d%%", palsaturation); @@ -145,92 +304,244 @@ INT_PTR CALLBACK PaletteConCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM SendDlgItemMessage(hwndDlg, STATIC_CONTRASTVALUE,WM_SETTEXT, 0, (LPARAM) text); sprintf(text, "Brightness: %d%%", palbrightness); SendDlgItemMessage(hwndDlg, STATIC_BRIGHTVALUE, WM_SETTEXT, 0, (LPARAM) text); - break; - case WM_CLOSE: - case WM_QUIT: - goto gornk; + if (~eoptions & EO_CPALETTE) + { + UpdatePalettePreviewCaption(hwndDlg); + InvalidatePalettePreviewRect(hwndDlg); + } + } + break; + case WM_PAINT: + { + if (!palo) + break; + + PAINTSTRUCT paint; + HDC hdc = BeginPaint(hwndDlg, &paint); + HDC memdc = CreateCompatibleDC(hdc); + + HGDIOBJ oldObj = SelectObject(memdc, palpv->pvBitmap); + HFONT oldFont = SelectFont(memdc, palpv->font); + + RECT rect; + float left, top = -palpv->cell_height, right, bottom = 0.0F; + for (int i = 0; i < 64; ++i) + { + if (i % 16 == 0) + { + left = 0.0F; + right = palpv->cell_width; + top += palpv->cell_height; + bottom += palpv->cell_height; + } + else + { + left += palpv->cell_width; + right += palpv->cell_width; + } - case WM_COMMAND: - if(!(wParam>>16)) + rect.left = round(left); + rect.right = round(right); + rect.top = round(top); + rect.bottom = round(bottom); + + int grey = ToGrey(palo[i].r, palo[i].g, palo[i].b); + COLORREF color = force_grayscale ? RGB(grey, grey, grey) : RGB(palo[i].r, palo[i].g, palo[i].b); + HBRUSH brush = CreateSolidBrush(color); + FillRect(memdc, &rect, brush); + DeleteObject(brush); + + if (palcolorindex) + { + SetTextColor(memdc, grey > 127 ? RGB(0, 0, 0) : RGB(255, 255, 255)); + SetBkColor(memdc, color); + + sprintf(palpv->buf, "%X", i); + SIZE str_size; + GetTextExtentPoint(memdc, palpv->buf, strlen(palpv->buf), &str_size); + ExtTextOut(memdc, rect.left + (rect.right - rect.left - str_size.cx) / 2, rect.top + (rect.bottom - rect.top - str_size.cy) / 2, NULL, NULL, palpv->buf, strlen(palpv->buf), NULL); + } + } + + BitBlt(hdc, palpv->pvRect.left, palpv->pvRect.top, palpv->pvSize.cx, palpv->pvSize.cy, memdc, 0, 0, SRCCOPY); + + EndPaint(hwndDlg, &paint); + + SelectFont(memdc, oldFont); + SelectObject(memdc, oldObj); + DeleteDC(memdc); + + break; + } + case WM_MOUSEMOVE: + if (palo) + UpdatePalettePreviewCaption(hwndDlg, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); + break; + + case WM_LBUTTONDOWN: + if (palo && palpv->mouse_index != -1) { - switch(wParam&0xFFFF) + CHOOSECOLORINFO info; + char str[16]; + sprintf(str, "$%02X", palpv->mouse_index); + info.name = str; + + int r = palo[palpv->mouse_index].r; + int g = palo[palpv->mouse_index].g; + int b = palo[palpv->mouse_index].b; + + info.r = &r; + info.g = &g; + info.b = &b; + + if (ChangeColor(hwndDlg, &info)) { - case CHECK_PALETTE_ENABLED: - ntsccol_enable ^= 1; - FCEUI_SetNTSCTH(ntsccol_enable, ntsctint, ntschue); // it recalculates everything, use it for PAL block too! - EnableWindow(GetDlgItem(hwndDlg, 65463), ntsccol_enable); - EnableWindow(GetDlgItem(hwndDlg, 64395), ntsccol_enable); - EnableWindow(GetDlgItem(hwndDlg, CTL_HUE_TRACKBAR), ntsccol_enable); - EnableWindow(GetDlgItem(hwndDlg, CTL_TINT_TRACKBAR), ntsccol_enable); - - break; - - case CHECK_PALETTE_GRAYSCALE: - force_grayscale ^= 1; - FCEUI_SetNTSCTH(ntsccol_enable, ntsctint, ntschue); - break; - - case CHECK_DEEMPH_SWAP: - paldeemphswap ^= 1; - FCEUI_SetNTSCTH(ntsccol_enable, ntsctint, ntschue); - break; - - case CHECK_PALETTE_CUSTOM: + if (palo[palpv->mouse_index].r != r || palo[palpv->mouse_index].g != g || palo[palpv->mouse_index].b != b) { if (eoptions & EO_CPALETTE) { - //disable user palette - FCEUI_SetUserPalette(0,0); - eoptions &= ~EO_CPALETTE; - } else + palo[palpv->mouse_index].r = r; + palo[palpv->mouse_index].g = g; + palo[palpv->mouse_index].b = b; + FCEU_ResetPalette(); + } + else { - //switch to user palette (even if it isn't loaded yet!?) - FCEUI_SetUserPalette(cpalette,64); //just have to guess the size I guess + memcpy(cpalette, palo, 64 * 3); + pal* tmp_palo = (pal*)&cpalette; + tmp_palo[palpv->mouse_index].r = r; + tmp_palo[palpv->mouse_index].g = g; + tmp_palo[palpv->mouse_index].b = b; + FCEUI_SetUserPalette(cpalette, 64); eoptions |= EO_CPALETTE; + UpdateCurrentPaletteName(hwndDlg); + CheckDlgButton(hwndDlg, CHECK_PALETTE_CUSTOM, BST_CHECKED); } - break; - } - case BTN_PALETTE_LOAD: - if(LoadPaletteFile()) - CheckDlgButton(hwndDlg, CHECK_PALETTE_CUSTOM, BST_CHECKED); - break; - - case BTN_PALETTE_RESET: - palnotch = 100; - palsaturation = 100; - palsharpness = 0; - palcontrast = 100; - palbrightness = 50; - - sprintf(text, "Notch: %d%%", palnotch); - SendDlgItemMessage(hwndDlg, STATIC_NOTCHVALUE, WM_SETTEXT, 0, (LPARAM) text); - sprintf(text, "Saturation: %d%%", palsaturation); - SendDlgItemMessage(hwndDlg, STATIC_SATVALUE, WM_SETTEXT, 0, (LPARAM) text); - sprintf(text, "Sharpness: %d%%", palsharpness); - SendDlgItemMessage(hwndDlg, STATIC_SHARPVALUE, WM_SETTEXT, 0, (LPARAM) text); - sprintf(text, "Contrast: %d%%", palcontrast); - SendDlgItemMessage(hwndDlg, STATIC_CONTRASTVALUE,WM_SETTEXT, 0, (LPARAM) text); - sprintf(text, "Brightness: %d%%", palbrightness); - SendDlgItemMessage(hwndDlg, STATIC_BRIGHTVALUE, WM_SETTEXT, 0, (LPARAM) text); - - SendDlgItemMessage(hwndDlg, CTL_PALNOTCH_TRACKBAR, TBM_SETPOS, 1, palnotch); - SendDlgItemMessage(hwndDlg, CTL_PALSAT_TRACKBAR, TBM_SETPOS, 1, palsaturation); - SendDlgItemMessage(hwndDlg, CTL_PALSHARP_TRACKBAR, TBM_SETPOS, 1, palsharpness); - SendDlgItemMessage(hwndDlg, CTL_PALCONTRAST_TRACKBAR,TBM_SETPOS, 1, palcontrast); - SendDlgItemMessage(hwndDlg, CTL_PALBRIGHT_TRACKBAR, TBM_SETPOS, 1, palbrightness); - - FCEUI_SetNTSCTH(ntsccol_enable, ntsctint, ntschue); - break; - - case BUTTON_CLOSE: -gornk: - DestroyWindow(hwndDlg); - hWndPal = 0; // Yay for user race conditions. - break; + UpdatePalettePreviewCaption(hwndDlg); + InvalidatePalettePreviewRect(hwndDlg); + } } } + break; + + case WM_CLOSE: + case WM_QUIT: + goto gornk; + + case WM_COMMAND: + switch (HIWORD(wParam)) + { + case BN_CLICKED: + switch (LOWORD(wParam)) + { + case CHECK_PALETTE_ENABLED: + ntsccol_enable ^= 1; + FCEUI_SetNTSCTH(ntsccol_enable, ntsctint, ntschue); // it recalculates everything, use it for PAL block too! + EnableWindow(GetDlgItem(hwndDlg, CTL_HUE_TEXT), ntsccol_enable); + EnableWindow(GetDlgItem(hwndDlg, CTL_TINT_TEXT), ntsccol_enable); + EnableWindow(GetDlgItem(hwndDlg, CTL_HUE_TRACKBAR), ntsccol_enable); + EnableWindow(GetDlgItem(hwndDlg, CTL_TINT_TRACKBAR), ntsccol_enable); + UpdateCurrentPaletteName(hwndDlg); + UpdatePalettePreviewCaption(hwndDlg); + InvalidatePalettePreviewRect(hwndDlg); + break; + + case CHECK_PALETTE_GRAYSCALE: + force_grayscale ^= 1; + FCEUI_SetNTSCTH(ntsccol_enable, ntsctint, ntschue); + UpdatePalettePreviewCaption(hwndDlg); + InvalidatePalettePreviewRect(hwndDlg); + break; + + case CHECK_DEEMPH_SWAP: + paldeemphswap ^= 1; + FCEUI_SetNTSCTH(ntsccol_enable, ntsctint, ntschue); + UpdatePalettePreviewCaption(hwndDlg); + InvalidatePalettePreviewRect(hwndDlg); + break; + + case CHECK_PALETTE_CUSTOM: + if (eoptions & EO_CPALETTE) + { + //disable user palette + FCEUI_SetUserPalette(0, 0); + eoptions &= ~EO_CPALETTE; + } + else + { + //switch to user palette (even if it isn't loaded yet!?) + FCEUI_SetUserPalette(cpalette, 64); //just have to guess the size I guess + eoptions |= EO_CPALETTE; + } + UpdateCurrentPaletteName(hwndDlg); + UpdatePalettePreviewCaption(hwndDlg); + InvalidatePalettePreviewRect(hwndDlg); + break; + + case CHECK_PALETTE_COLOR_INDEX: + palcolorindex ^= 1; + InvalidatePalettePreviewRect(hwndDlg); + break; + + case BTN_PALETTE_LOAD: + if (LoadPaletteFile(hwndDlg)) + { + CheckDlgButton(hwndDlg, CHECK_PALETTE_CUSTOM, BST_CHECKED); + UpdateCurrentPaletteName(hwndDlg); + UpdatePalettePreviewCaption(hwndDlg); + InvalidatePalettePreviewRect(hwndDlg); + } + break; + + case BTN_PALETTE_SAVE: + SavePaletteFile(hwndDlg); + break; + + case BTN_PALETTE_RESET: + { + palnotch = 100; + palsaturation = 100; + palsharpness = 0; + palcontrast = 100; + palbrightness = 50; + + char text[40]; + sprintf(text, "Notch: %d%%", palnotch); + SendDlgItemMessage(hwndDlg, STATIC_NOTCHVALUE, WM_SETTEXT, 0, (LPARAM)text); + sprintf(text, "Saturation: %d%%", palsaturation); + SendDlgItemMessage(hwndDlg, STATIC_SATVALUE, WM_SETTEXT, 0, (LPARAM)text); + sprintf(text, "Sharpness: %d%%", palsharpness); + SendDlgItemMessage(hwndDlg, STATIC_SHARPVALUE, WM_SETTEXT, 0, (LPARAM)text); + sprintf(text, "Contrast: %d%%", palcontrast); + SendDlgItemMessage(hwndDlg, STATIC_CONTRASTVALUE, WM_SETTEXT, 0, (LPARAM)text); + sprintf(text, "Brightness: %d%%", palbrightness); + SendDlgItemMessage(hwndDlg, STATIC_BRIGHTVALUE, WM_SETTEXT, 0, (LPARAM)text); + + SendDlgItemMessage(hwndDlg, CTL_PALNOTCH_TRACKBAR, TBM_SETPOS, 1, palnotch); + SendDlgItemMessage(hwndDlg, CTL_PALSAT_TRACKBAR, TBM_SETPOS, 1, palsaturation); + SendDlgItemMessage(hwndDlg, CTL_PALSHARP_TRACKBAR, TBM_SETPOS, 1, palsharpness); + SendDlgItemMessage(hwndDlg, CTL_PALCONTRAST_TRACKBAR, TBM_SETPOS, 1, palcontrast); + SendDlgItemMessage(hwndDlg, CTL_PALBRIGHT_TRACKBAR, TBM_SETPOS, 1, palbrightness); + + FCEUI_SetNTSCTH(ntsccol_enable, ntsctint, ntschue); + + UpdatePalettePreviewCaption(hwndDlg); + InvalidatePalettePreviewRect(hwndDlg); + + break; + } + case BUTTON_CLOSE: + gornk: + DestroyWindow(hwndDlg); + hWndPal = 0; // Yay for user race conditions. + DeleteFont(palpv->font); + DeleteObject(palpv->pvBitmap); + free(palpv); + return 0; + } + } } return 0; @@ -246,4 +557,3 @@ void ConfigPalette() else SetFocus(hWndPal); } - diff --git a/src/drivers/win/ramwatch.cpp b/src/drivers/win/ramwatch.cpp index 60a73af1e..94c550c2c 100644 --- a/src/drivers/win/ramwatch.cpp +++ b/src/drivers/win/ramwatch.cpp @@ -1295,7 +1295,7 @@ INT_PTR CALLBACK RamWatchProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam // draw the separator // draw it with a different color when hilighted for eyes easy - SelectObject(hdc, state ? SeparatorCache::sepPenSel : SeparatorCache::sepPen); + HGDIOBJ oldObj = SelectObject(hdc, state ? SeparatorCache::sepPenSel : SeparatorCache::sepPen); MoveToEx(hdc, rect.left + sepCache.sepOffX, rect.top + SeparatorCache::sepOffY, NULL); LineTo(hdc, rect.right, rect.top + SeparatorCache::sepOffY); @@ -1309,6 +1309,7 @@ INT_PTR CALLBACK RamWatchProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam SelectObject(hdc, SeparatorCache::sepFon); DrawText(hdc, comment, strlen(comment), &rect, DT_LEFT); } + SelectObject(hdc, oldObj); } break; @@ -1684,8 +1685,9 @@ SeparatorCache::SeparatorCache(HWND hwnd, char* text) { SIZE size; HDC hdc = GetDC(hwnd); - SelectFont(hdc, sepFon); + HGDIOBJ oldObj = SelectFont(hdc, sepFon); GetTextExtentPoint(hdc, text, strlen(text), &size); + SelectObject(hdc, oldObj); ReleaseDC(hwnd, hdc); sepOffX = size.cx + 8; diff --git a/src/drivers/win/res.rc b/src/drivers/win/res.rc index e052bd118..e4b238885 100644 --- a/src/drivers/win/res.rc +++ b/src/drivers/win/res.rc @@ -375,36 +375,42 @@ BEGIN EDITTEXT IDC_NETMOO_PASS,60,182,67,12,ES_PASSWORD END -PALCONFIG DIALOGEX 16, 81, 228, 217 +PALCONFIG DIALOGEX 16, 81, 228, 280 STYLE DS_SETFONT | DS_MODALFRAME | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "Palette Configuration" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN - GROUPBOX "NES Palette",302,10,8,102,81,WS_GROUP - DEFPUSHBUTTON "&Load Palette...",BTN_PALETTE_LOAD,18,39,58,14 - CONTROL "Enabled",CHECK_PALETTE_ENABLED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,122,22,87,12 - CTEXT "Tint",65463,123,34,85,8,WS_DISABLED - CONTROL "Tint",CTL_TINT_TRACKBAR,"msctls_trackbar32",WS_DISABLED | WS_TABSTOP,121,44,91,11 - GROUPBOX "NTSC Color Emulation",101,115,8,103,81,WS_GROUP - CTEXT "Hue",64395,124,59,85,8,WS_DISABLED - CONTROL "Hue",CTL_HUE_TRACKBAR,"msctls_trackbar32",WS_DISABLED | WS_TABSTOP,121,69,91,11 - CONTROL "Force Grayscale",CHECK_PALETTE_GRAYSCALE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,19,57,85,12 - CONTROL "Use Custom Palette",CHECK_PALETTE_CUSTOM,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,19,22,85,12 - GROUPBOX "PAL Simulation",IDC_STATIC,10,89,208,66 - LTEXT "Saturation:",STATIC_SATVALUE,83,100,58,8 - CONTROL "",CTL_PALSAT_TRACKBAR,"msctls_trackbar32",TBS_NOTICKS | WS_TABSTOP,78,110,70,15 - PUSHBUTTON "Reset",BTN_PALETTE_RESET,161,132,50,14 - LTEXT "Notch:",STATIC_NOTCHVALUE,16,100,46,8 - CONTROL "",CTL_PALNOTCH_TRACKBAR,"msctls_trackbar32",TBS_NOTICKS | WS_TABSTOP,11,110,68,15 - LTEXT "Sharpness:",STATIC_SHARPVALUE,151,99,60,8 - CONTROL "",CTL_PALSHARP_TRACKBAR,"msctls_trackbar32",TBS_NOTICKS | WS_TABSTOP,146,109,71,15 - LTEXT "NTSC Color Emulation overrides Internal default Palette.\nIndividual Game Palette overrides Internal+NTSC Palettes.\nCustom Palette overrides all of the above.\nPAL Simulation overrides other choices when PAL filter is selected in Video Configuration.",IDC_STATIC,10,159,208,43 - LTEXT "Contrast: ",STATIC_CONTRASTVALUE,16,126,55,8 - CONTROL "",CTL_PALCONTRAST_TRACKBAR,"msctls_trackbar32",TBS_NOTICKS | WS_TABSTOP,11,134,67,15 - LTEXT "Brightness: ",STATIC_BRIGHTVALUE,83,125,61,8 - CONTROL "",CTL_PALBRIGHT_TRACKBAR,"msctls_trackbar32",TBS_NOTICKS | WS_TABSTOP,78,133,70,15 - CONTROL "De-emphasis bit swap",CHECK_DEEMPH_SWAP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,19,73,83,10 - DEFPUSHBUTTON "Close",BUTTON_CLOSE,162,195,56,14 + GROUPBOX "NES Palette", 302, 10, 8, 102, 81, WS_GROUP + CONTROL "Use Custom Palette", CHECK_PALETTE_CUSTOM, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, 19, 22, 85, 12 + DEFPUSHBUTTON "&Load Palette...", BTN_PALETTE_LOAD, 18, 39, 58, 14 + CONTROL "Force Grayscale", CHECK_PALETTE_GRAYSCALE, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, 19, 57, 85, 12 + CONTROL "De-emphasis bit swap", CHECK_DEEMPH_SWAP, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, 19, 73, 83, 10 + GROUPBOX "NTSC Color Emulation", 101, 115, 8, 103, 81, WS_GROUP + CONTROL "Enabled", CHECK_PALETTE_ENABLED, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, 122, 22, 87, 12 + CTEXT "Tint", CTL_TINT_TEXT, 123, 34, 85, 8, WS_DISABLED + CONTROL "Tint", CTL_TINT_TRACKBAR, "msctls_trackbar32", WS_DISABLED | WS_TABSTOP, 121, 44, 91, 11 + CTEXT "Hue", CTL_HUE_TEXT, 124, 59, 85, 8, WS_DISABLED + CONTROL "Hue", CTL_HUE_TRACKBAR, "msctls_trackbar32", WS_DISABLED | WS_TABSTOP, 121, 69, 91, 11 + GROUPBOX "PAL Emulation", IDC_STATIC, 10, 90, 208, 66, WS_DISABLED + LTEXT "Notch:", STATIC_NOTCHVALUE, 16, 100, 46, 8, WS_DISABLED + CONTROL "", CTL_PALNOTCH_TRACKBAR, "msctls_trackbar32", TBS_NOTICKS | WS_DISABLED | WS_TABSTOP, 11, 110, 68, 15 + LTEXT "Saturation:", STATIC_SATVALUE, 83, 100, 58, 8, WS_DISABLED + CONTROL "", CTL_PALSAT_TRACKBAR, "msctls_trackbar32", TBS_NOTICKS | WS_DISABLED | WS_TABSTOP, 78, 110, 70, 15 + LTEXT "Sharpness:", STATIC_SHARPVALUE, 161, 99, 50, 8, WS_DISABLED + CONTROL "", CTL_PALSHARP_TRACKBAR, "msctls_trackbar32", TBS_NOTICKS | WS_DISABLED | WS_TABSTOP, 156, 109, 61, 15 + LTEXT "Contrast: ", STATIC_CONTRASTVALUE, 16, 126, 55, 8, WS_DISABLED + CONTROL "", CTL_PALCONTRAST_TRACKBAR, "msctls_trackbar32", TBS_NOTICKS | WS_DISABLED | WS_TABSTOP, 11, 134, 67, 15 + LTEXT "Brightness: ", STATIC_BRIGHTVALUE, 83, 125, 61, 8, WS_DISABLED + CONTROL "", CTL_PALBRIGHT_TRACKBAR, "msctls_trackbar32", TBS_NOTICKS | WS_DISABLED | WS_TABSTOP, 78, 133, 70, 15 + PUSHBUTTON "Reset", BTN_PALETTE_RESET, 161, 132, 50, 14, WS_DISABLED + GROUPBOX "Preview", IDC_PALETTE_PREVIEW_GROUPBOX, 10, 157, 208, 68 + CONTROL "Color index", CHECK_PALETTE_COLOR_INDEX, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, 16, 166, 49, 10 + LTEXT "Current palette:", IDC_STATIC, 70, 167, 53, 8 + LTEXT "None", IDC_PALETTE_CURRENT, 127, 167, 46, 8 + PUSHBUTTON "Save...", BTN_PALETTE_SAVE, 177, 163, 38, 14 + LTEXT "", IDC_PALETTE_PREVIEW, 15, 178, 198, 43, NOT WS_VISIBLE + LTEXT "NTSC Color Emulation overrides Internal default Palette.\nIndividual Game Palette overrides Internal+NTSC Palettes.\nCustom Palette overrides all of the above.\nPAL Emulation overrides other choices when PAL filter is selected", IDC_STATIC, 10, 227, 217, 33 + DEFPUSHBUTTON "Close", BUTTON_CLOSE, 162, 261, 56, 14 END POWERPADDIALOG DIALOGEX 30, 123, 131, 119 @@ -1863,13 +1869,13 @@ BEGIN BOTTOMMARGIN, 201 END - "PALCONFIG", DIALOG - BEGIN - LEFTMARGIN, 10 - RIGHTMARGIN, 218 - TOPMARGIN, 8 - BOTTOMMARGIN, 209 - END + "PALCONFIG", DIALOG + BEGIN + LEFTMARGIN, 10 + RIGHTMARGIN, 218 + TOPMARGIN, 8 + BOTTOMMARGIN, 275 + END "POWERPADDIALOG", DIALOG BEGIN diff --git a/src/drivers/win/resource.h b/src/drivers/win/resource.h index ea863c968..7d6150df8 100644 --- a/src/drivers/win/resource.h +++ b/src/drivers/win/resource.h @@ -512,6 +512,7 @@ #define IDC_CHEAT_AUTOLOADSAVE 1013 #define IDC_CHECK_SHORTCUT 1013 #define IDC_CHECK_SYMBOLIC_ARRAY 1013 +#define CHECK_PALETTE_COLOR_INDEX 1013 #define IDC_RESTORE_BUTTON 1014 #define MW_VAL04 1014 #define MW_NAME05 1015 @@ -609,11 +610,15 @@ #define IDC_DEBUGGER_TEXT_A 1049 #define IDC_SUBMAPPER_TEXT 1050 #define MW_VAL16 1050 +#define IDC_PALETTE_PREVIEW 1050 #define IDC_PRGROM_TEXT 1051 #define MW_NAME17 1051 +#define IDC_PALETTE_PREVIEW_GROUPBOX 1051 #define MW_ADDR17 1052 +#define IDC_PALETTE_CURRENT 1052 #define IDC_CHRROM_TEXT 1053 #define MW_VAL17 1053 +#define BTN_PALETTE_SAVE 1053 #define MW_NAME18 1054 #define MW_ADDR18 1055 #define IDC_PRGRAM_TEXT 1055 @@ -1207,9 +1212,11 @@ #define CHEAT_CONTEXT_POSSI_ADDCHEAT 40601 #define CHEAT_CONTEXT_POSSI_ADDTORAMWATCH 40603 #define IDC_DEBUGGER_BOOKMARKS 45535 +#define CTL_HUE_TEXT 64395 #define MW_VALUELABEL2 65423 #define MW_VALUELABEL1 65426 #define IDC_STATIC_SLASHTEXT 65442 +#define CTL_TINT_TEXT 65463 #define IDC_DEBUGGER_TEXT_SPR 65530 #define IDC_DEBUGGER_TEXT_PPU 65531 #define IDC_BOOKMARK_NAME_TEXT 65532 @@ -1226,7 +1233,7 @@ #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 313 #define _APS_NEXT_COMMAND_VALUE 40012 -#define _APS_NEXT_CONTROL_VALUE 1050 +#define _APS_NEXT_CONTROL_VALUE 1054 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif diff --git a/src/drivers/win/window.cpp b/src/drivers/win/window.cpp index b36e74bcc..2230af040 100644 --- a/src/drivers/win/window.cpp +++ b/src/drivers/win/window.cpp @@ -1119,6 +1119,17 @@ bool ALoad(const char *nameo, char* innerFilename, bool silent) { DoDebug(0); } + + extern HWND hWndPal; + if (hWndPal) + { + extern void InvalidatePalettePreviewRect(HWND); + InvalidatePalettePreviewRect(hWndPal); + extern void UpdatePalettePreviewCaption(HWND); + UpdatePalettePreviewCaption(hWndPal); + extern void UpdateCurrentPaletteName(HWND); + UpdateCurrentPaletteName(hWndPal); + } } else { @@ -3377,6 +3388,8 @@ bool inline (*GetIsLetterLegal(UINT id))(char letter) case MW_ADDR12: case MW_ADDR13: case MW_ADDR14: case MW_ADDR15: case MW_ADDR16: case MW_ADDR17: case MW_ADDR18: case MW_ADDR19: case MW_ADDR20: case MW_ADDR21: case MW_ADDR22: case MW_ADDR23: + return IsLetterLegalMemoryWatch; + case IDC_EDIT_COMPAREADDRESS: return IsLetterLegalHex; @@ -3473,6 +3486,12 @@ inline wchar_t* GetLetterIllegalErrMsg(bool(*IsLetterLegal)(char letter)) "you must add a $ prefix to prevent ambiguous.\n" "eg. 10 is a decimal number,\n" "$10 means a hexademical number that is 16 in decimal."; + if (IsLetterLegal == IsLetterLegalMemoryWatch) + return + L"You can only type characters for hexadecimal number(0 - 9, A - F).\n" + "To display the value in hex, use a prefix of \"x\" (such as x00FD).\n" + "Use the prefix \"!\" to display a 2 byte value.\n" + "Use a prefix of \"X\" to watch a 2 byte value in hex."; return L"Your input contains invalid characters."; } @@ -3530,3 +3549,8 @@ inline bool IsLetterLegalUnsignedDecHexMixed(char letter) { return letter >= '0' && letter <= '9' || letter >= 'A' && letter <= 'F' || letter >= 'a' && letter <= 'f' || letter == '$'; } + +inline bool IsLetterLegalMemoryWatch(char letter) +{ + return IsLetterLegalHex(letter) || letter == 'X' || letter == 'x' || letter == '!'; +} \ No newline at end of file diff --git a/src/drivers/win/window.h b/src/drivers/win/window.h index 0127ad978..790d32aa0 100644 --- a/src/drivers/win/window.h +++ b/src/drivers/win/window.h @@ -141,6 +141,7 @@ inline bool IsLetterLegalSize(char letter); inline bool IsLetterLegalFloat(char letter); inline bool IsLetterLegalDecHexMixed(char letter); inline bool IsLetterLegalUnsignedDecHexMixed(char letter); +inline bool IsLetterLegalMemoryWatch(char letter); extern WNDPROC DefaultEditCtrlProc; extern LRESULT APIENTRY FilterEditCtrlProc(HWND hDlg, UINT msg, WPARAM wP, LPARAM lP);