mirror of
https://github.com/holub/mame
synced 2025-06-16 01:09:09 +03:00
303 lines
9.2 KiB
C++
303 lines
9.2 KiB
C++
// license:BSD-3-Clause
|
|
// copyright-holders:Aaron Giles, Vas Crabb
|
|
//============================================================
|
|
//
|
|
// memorywininfo.c - Win32 debug window handling
|
|
//
|
|
//============================================================
|
|
|
|
#include "emu.h"
|
|
#include "memorywininfo.h"
|
|
|
|
#include "debugviewinfo.h"
|
|
#include "memoryviewinfo.h"
|
|
#include "uimetrics.h"
|
|
|
|
#include "winutf8.h"
|
|
|
|
|
|
memorywin_info::memorywin_info(debugger_windows_interface &debugger) :
|
|
editwin_info(debugger, false, "Memory", nullptr),
|
|
m_combownd(nullptr)
|
|
{
|
|
if (!window())
|
|
return;
|
|
|
|
m_views[0].reset(new memoryview_info(debugger, *this, window()));
|
|
if ((m_views[0] == nullptr) || !m_views[0]->is_valid())
|
|
{
|
|
m_views[0].reset();
|
|
return;
|
|
}
|
|
|
|
// create the options menu
|
|
HMENU const optionsmenu = CreatePopupMenu();
|
|
AppendMenu(optionsmenu, MF_ENABLED, ID_1_BYTE_CHUNKS, TEXT("1-byte chunks\tCtrl+1"));
|
|
AppendMenu(optionsmenu, MF_ENABLED, ID_2_BYTE_CHUNKS, TEXT("2-byte chunks\tCtrl+2"));
|
|
AppendMenu(optionsmenu, MF_ENABLED, ID_4_BYTE_CHUNKS, TEXT("4-byte chunks\tCtrl+4"));
|
|
AppendMenu(optionsmenu, MF_ENABLED, ID_8_BYTE_CHUNKS, TEXT("8-byte chunks\tCtrl+8"));
|
|
AppendMenu(optionsmenu, MF_ENABLED, ID_FLOATING_POINT_32BIT, TEXT("32 bit floating point\tCtrl+9"));
|
|
AppendMenu(optionsmenu, MF_ENABLED, ID_FLOATING_POINT_64BIT, TEXT("64 bit floating point"));
|
|
AppendMenu(optionsmenu, MF_ENABLED, ID_FLOATING_POINT_80BIT, TEXT("80 bit floating point"));
|
|
AppendMenu(optionsmenu, MF_DISABLED | MF_SEPARATOR, 0, TEXT(""));
|
|
AppendMenu(optionsmenu, MF_ENABLED, ID_LOGICAL_ADDRESSES, TEXT("Logical Addresses\tCtrl+L"));
|
|
AppendMenu(optionsmenu, MF_ENABLED, ID_PHYSICAL_ADDRESSES, TEXT("Physical Addresses\tCtrl+Y"));
|
|
AppendMenu(optionsmenu, MF_DISABLED | MF_SEPARATOR, 0, TEXT(""));
|
|
AppendMenu(optionsmenu, MF_ENABLED, ID_REVERSE_VIEW, TEXT("Reverse View\tCtrl+R"));
|
|
AppendMenu(optionsmenu, MF_DISABLED | MF_SEPARATOR, 0, TEXT(""));
|
|
AppendMenu(optionsmenu, MF_ENABLED, ID_INCREASE_MEM_WIDTH, TEXT("Increase bytes per line\tCtrl+P"));
|
|
AppendMenu(optionsmenu, MF_ENABLED, ID_DECREASE_MEM_WIDTH, TEXT("Decrease bytes per line\tCtrl+O"));
|
|
AppendMenu(GetMenu(window()), MF_ENABLED | MF_POPUP, (UINT_PTR)optionsmenu, TEXT("Options"));
|
|
|
|
// set up the view to track the initial expression
|
|
downcast<memoryview_info *>(m_views[0].get())->set_expression("0");
|
|
set_edit_defstr("0");
|
|
set_editwnd_text("0");
|
|
editwnd_select_all();
|
|
|
|
// create a combo box
|
|
m_views[0]->set_source_for_visible_cpu();
|
|
m_combownd = m_views[0]->create_source_combobox(window(), (LONG_PTR)this);
|
|
|
|
// set the caption
|
|
update_caption();
|
|
|
|
// recompute the children once to get the maxwidth
|
|
memorywin_info::recompute_children();
|
|
|
|
// position the window and recompute children again
|
|
SetWindowPos(window(), HWND_TOP, 100, 100, maxwidth(), 200, SWP_SHOWWINDOW);
|
|
memorywin_info::recompute_children();
|
|
|
|
// mark the edit box as the default focus and set it
|
|
editwin_info::set_default_focus();
|
|
}
|
|
|
|
|
|
memorywin_info::~memorywin_info()
|
|
{
|
|
}
|
|
|
|
|
|
bool memorywin_info::handle_key(WPARAM wparam, LPARAM lparam)
|
|
{
|
|
if (GetAsyncKeyState(VK_CONTROL) & 0x8000)
|
|
{
|
|
switch (wparam)
|
|
{
|
|
case '1':
|
|
SendMessage(window(), WM_COMMAND, ID_1_BYTE_CHUNKS, 0);
|
|
return true;
|
|
|
|
case '2':
|
|
SendMessage(window(), WM_COMMAND, ID_2_BYTE_CHUNKS, 0);
|
|
return true;
|
|
|
|
case '4':
|
|
SendMessage(window(), WM_COMMAND, ID_4_BYTE_CHUNKS, 0);
|
|
return true;
|
|
|
|
case '8':
|
|
SendMessage(window(), WM_COMMAND, ID_8_BYTE_CHUNKS, 0);
|
|
return true;
|
|
|
|
case '9':
|
|
SendMessage(window(), WM_COMMAND, ID_FLOATING_POINT_32BIT, 0);
|
|
return true;
|
|
|
|
case 'L':
|
|
SendMessage(window(), WM_COMMAND, ID_LOGICAL_ADDRESSES, 0);
|
|
return true;
|
|
|
|
case 'Y':
|
|
SendMessage(window(), WM_COMMAND, ID_PHYSICAL_ADDRESSES, 0);
|
|
return true;
|
|
|
|
case 'R':
|
|
SendMessage(window(), WM_COMMAND, ID_REVERSE_VIEW, 0);
|
|
return true;
|
|
|
|
case 'P':
|
|
SendMessage(window(), WM_COMMAND, ID_INCREASE_MEM_WIDTH, 0);
|
|
return true;
|
|
|
|
case 'O':
|
|
SendMessage(window(), WM_COMMAND, ID_DECREASE_MEM_WIDTH, 0);
|
|
return true;
|
|
}
|
|
}
|
|
return editwin_info::handle_key(wparam, lparam);
|
|
}
|
|
|
|
|
|
void memorywin_info::recompute_children()
|
|
{
|
|
// compute a client rect
|
|
RECT bounds;
|
|
bounds.top = bounds.left = 0;
|
|
bounds.right = m_views[0]->prefwidth() + (2 * EDGE_WIDTH);
|
|
bounds.bottom = 200;
|
|
AdjustWindowRectEx(&bounds, DEBUG_WINDOW_STYLE, FALSE, DEBUG_WINDOW_STYLE_EX);
|
|
|
|
// clamp the min/max size
|
|
set_maxwidth(bounds.right - bounds.left);
|
|
|
|
// get the parent's dimensions
|
|
RECT parent;
|
|
GetClientRect(window(), &parent);
|
|
|
|
// edit box gets half of the width
|
|
RECT editrect;
|
|
editrect.top = parent.top + EDGE_WIDTH;
|
|
editrect.bottom = editrect.top + metrics().debug_font_height() + 4;
|
|
editrect.left = parent.left + EDGE_WIDTH;
|
|
editrect.right = parent.left + ((parent.right - parent.left) / 2) - EDGE_WIDTH;
|
|
|
|
// combo box gets the other half of the width
|
|
RECT comborect;
|
|
comborect.top = editrect.top;
|
|
comborect.bottom = editrect.bottom;
|
|
comborect.left = editrect.right + (2 * EDGE_WIDTH);
|
|
comborect.right = parent.right - EDGE_WIDTH;
|
|
|
|
// memory view gets the rest
|
|
RECT memrect;
|
|
memrect.top = editrect.bottom + (2 * EDGE_WIDTH);
|
|
memrect.bottom = parent.bottom - EDGE_WIDTH;
|
|
memrect.left = parent.left + EDGE_WIDTH;
|
|
memrect.right = parent.right - EDGE_WIDTH;
|
|
|
|
// set the bounds of things
|
|
m_views[0]->set_bounds(memrect);
|
|
set_editwnd_bounds(editrect);
|
|
smart_set_window_bounds(m_combownd, window(), comborect);
|
|
}
|
|
|
|
|
|
void memorywin_info::update_menu()
|
|
{
|
|
editwin_info::update_menu();
|
|
|
|
auto *const memview = downcast<memoryview_info *>(m_views[0].get());
|
|
HMENU const menu = GetMenu(window());
|
|
CheckMenuItem(menu, ID_1_BYTE_CHUNKS, MF_BYCOMMAND | (memview->data_format() == debug_view_memory::data_format::HEX_8BIT ? MF_CHECKED : MF_UNCHECKED));
|
|
CheckMenuItem(menu, ID_2_BYTE_CHUNKS, MF_BYCOMMAND | (memview->data_format() == debug_view_memory::data_format::HEX_16BIT ? MF_CHECKED : MF_UNCHECKED));
|
|
CheckMenuItem(menu, ID_4_BYTE_CHUNKS, MF_BYCOMMAND | (memview->data_format() == debug_view_memory::data_format::HEX_32BIT ? MF_CHECKED : MF_UNCHECKED));
|
|
CheckMenuItem(menu, ID_8_BYTE_CHUNKS, MF_BYCOMMAND | (memview->data_format() == debug_view_memory::data_format::HEX_64BIT ? MF_CHECKED : MF_UNCHECKED));
|
|
CheckMenuItem(menu, ID_FLOATING_POINT_32BIT, MF_BYCOMMAND | (memview->data_format() == debug_view_memory::data_format::FLOAT_32BIT ? MF_CHECKED : MF_UNCHECKED));
|
|
CheckMenuItem(menu, ID_FLOATING_POINT_64BIT, MF_BYCOMMAND | (memview->data_format() == debug_view_memory::data_format::FLOAT_64BIT ? MF_CHECKED : MF_UNCHECKED));
|
|
CheckMenuItem(menu, ID_FLOATING_POINT_80BIT, MF_BYCOMMAND | (memview->data_format() == debug_view_memory::data_format::FLOAT_80BIT ? MF_CHECKED : MF_UNCHECKED));
|
|
CheckMenuItem(menu, ID_LOGICAL_ADDRESSES, MF_BYCOMMAND | (memview->physical() ? MF_UNCHECKED : MF_CHECKED));
|
|
CheckMenuItem(menu, ID_PHYSICAL_ADDRESSES, MF_BYCOMMAND | (memview->physical() ? MF_CHECKED : MF_UNCHECKED));
|
|
CheckMenuItem(menu, ID_REVERSE_VIEW, MF_BYCOMMAND | (memview->reverse() ? MF_CHECKED : MF_UNCHECKED));
|
|
EnableMenuItem(menu, ID_DECREASE_MEM_WIDTH, MF_BYCOMMAND | ((memview->chunks_per_row() > 1) ? MF_ENABLED : MF_GRAYED));
|
|
}
|
|
|
|
|
|
bool memorywin_info::handle_command(WPARAM wparam, LPARAM lparam)
|
|
{
|
|
auto *const memview = downcast<memoryview_info *>(m_views[0].get());
|
|
switch (HIWORD(wparam))
|
|
{
|
|
// combo box selection changed
|
|
case CBN_SELCHANGE:
|
|
{
|
|
int const sel = SendMessage((HWND)lparam, CB_GETCURSEL, 0, 0);
|
|
if (sel != CB_ERR)
|
|
{
|
|
memview->set_source_index(sel);
|
|
update_caption();
|
|
|
|
// reset the focus
|
|
set_default_focus();
|
|
return true;
|
|
}
|
|
break;
|
|
}
|
|
|
|
// menu selections
|
|
case 0:
|
|
switch (LOWORD(wparam))
|
|
{
|
|
case ID_1_BYTE_CHUNKS:
|
|
memview->set_data_format(1);
|
|
return true;
|
|
|
|
case ID_2_BYTE_CHUNKS:
|
|
memview->set_data_format(2);
|
|
return true;
|
|
|
|
case ID_4_BYTE_CHUNKS:
|
|
memview->set_data_format(4);
|
|
return true;
|
|
|
|
case ID_8_BYTE_CHUNKS:
|
|
memview->set_data_format(8);
|
|
return true;
|
|
|
|
case ID_FLOATING_POINT_32BIT:
|
|
memview->set_data_format(9);
|
|
return true;
|
|
|
|
case ID_FLOATING_POINT_64BIT:
|
|
memview->set_data_format(10);
|
|
return true;
|
|
|
|
case ID_FLOATING_POINT_80BIT:
|
|
memview->set_data_format(11);
|
|
return true;
|
|
|
|
case ID_LOGICAL_ADDRESSES:
|
|
memview->set_physical(false);
|
|
return true;
|
|
|
|
case ID_PHYSICAL_ADDRESSES:
|
|
memview->set_physical(true);
|
|
return true;
|
|
|
|
case ID_REVERSE_VIEW:
|
|
memview->set_reverse(!memview->reverse());
|
|
return true;
|
|
|
|
case ID_INCREASE_MEM_WIDTH:
|
|
memview->set_chunks_per_row(memview->chunks_per_row() + 1);
|
|
recompute_children();
|
|
return true;
|
|
|
|
case ID_DECREASE_MEM_WIDTH:
|
|
memview->set_chunks_per_row(memview->chunks_per_row() - 1);
|
|
recompute_children();
|
|
return true;
|
|
}
|
|
break;
|
|
}
|
|
return editwin_info::handle_command(wparam, lparam);
|
|
}
|
|
|
|
|
|
void memorywin_info::draw_contents(HDC dc)
|
|
{
|
|
editwin_info::draw_contents(dc);
|
|
if (m_combownd)
|
|
draw_border(dc, m_combownd);
|
|
}
|
|
|
|
|
|
void memorywin_info::process_string(const std::string &string)
|
|
{
|
|
// set the string to the memory view
|
|
downcast<memoryview_info *>(m_views[0].get())->set_expression(string);
|
|
|
|
// select everything in the edit text box
|
|
editwnd_select_all();
|
|
|
|
// update the default string to match
|
|
set_edit_defstr(string);
|
|
}
|
|
|
|
|
|
void memorywin_info::update_caption()
|
|
{
|
|
win_set_window_text_utf8(window(), std::string("Memory: ").append(m_views[0]->source_name()).c_str());
|
|
}
|