summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd/modules/debugger/win
diff options
context:
space:
mode:
Diffstat (limited to 'src/osd/modules/debugger/win')
-rw-r--r--src/osd/modules/debugger/win/consolewininfo.cpp620
-rw-r--r--src/osd/modules/debugger/win/consolewininfo.h21
-rw-r--r--src/osd/modules/debugger/win/debugbaseinfo.cpp27
-rw-r--r--src/osd/modules/debugger/win/debugbaseinfo.h9
-rw-r--r--src/osd/modules/debugger/win/debugviewinfo.cpp492
-rw-r--r--src/osd/modules/debugger/win/debugviewinfo.h27
-rw-r--r--src/osd/modules/debugger/win/debugwin.h20
-rw-r--r--src/osd/modules/debugger/win/debugwininfo.cpp162
-rw-r--r--src/osd/modules/debugger/win/debugwininfo.h53
-rw-r--r--src/osd/modules/debugger/win/disasmbasewininfo.cpp47
-rw-r--r--src/osd/modules/debugger/win/disasmbasewininfo.h13
-rw-r--r--src/osd/modules/debugger/win/disasmviewinfo.cpp32
-rw-r--r--src/osd/modules/debugger/win/disasmviewinfo.h15
-rw-r--r--src/osd/modules/debugger/win/disasmwininfo.cpp44
-rw-r--r--src/osd/modules/debugger/win/disasmwininfo.h14
-rw-r--r--src/osd/modules/debugger/win/editwininfo.cpp59
-rw-r--r--src/osd/modules/debugger/win/editwininfo.h15
-rw-r--r--src/osd/modules/debugger/win/logviewinfo.cpp6
-rw-r--r--src/osd/modules/debugger/win/logviewinfo.h11
-rw-r--r--src/osd/modules/debugger/win/logwininfo.cpp25
-rw-r--r--src/osd/modules/debugger/win/logwininfo.h12
-rw-r--r--src/osd/modules/debugger/win/memoryviewinfo.cpp143
-rw-r--r--src/osd/modules/debugger/win/memoryviewinfo.h39
-rw-r--r--src/osd/modules/debugger/win/memorywininfo.cpp262
-rw-r--r--src/osd/modules/debugger/win/memorywininfo.h13
-rw-r--r--src/osd/modules/debugger/win/pointswininfo.cpp99
-rw-r--r--src/osd/modules/debugger/win/pointswininfo.h13
-rw-r--r--src/osd/modules/debugger/win/uimetrics.cpp93
-rw-r--r--src/osd/modules/debugger/win/uimetrics.h46
29 files changed, 1812 insertions, 620 deletions
diff --git a/src/osd/modules/debugger/win/consolewininfo.cpp b/src/osd/modules/debugger/win/consolewininfo.cpp
index a9811f5fc93..a5dfd04cc55 100644
--- a/src/osd/modules/debugger/win/consolewininfo.cpp
+++ b/src/osd/modules/debugger/win/consolewininfo.cpp
@@ -2,7 +2,7 @@
// copyright-holders:Aaron Giles, Vas Crabb
//============================================================
//
-// consolewininfo.c - Win32 debug window handling
+// consolewininfo.cpp - Win32 debug window handling
//
//============================================================
@@ -12,47 +12,245 @@
#include "debugviewinfo.h"
#include "uimetrics.h"
-#include "debugger.h"
+// devices
+#include "imagedev/cassette.h"
+
+// emu
#include "debug/debugcon.h"
+#include "debugger.h"
+#include "image.h"
+#include "softlist_dev.h"
#include "debug/debugcpu.h"
-#include "imagedev/cassette.h"
-#include "strconv.h"
+// util
+#include "util/xmlfile.h"
+
+// osd/windows
#include "winutf8.h"
+// osd
+#include "strconv.h"
+
+// C++
+#include <vector>
+
+// Windows
+#include <commctrl.h>
+#include <shlobj.h>
+#include <shobjidl.h>
+#include <shtypes.h>
+#include <wrl/client.h>
+
+
+namespace osd::debugger::win {
+
+namespace {
+
+class comdlg_filter_helper
+{
+public:
+ comdlg_filter_helper(comdlg_filter_helper const &) = delete;
+ comdlg_filter_helper &operator=(comdlg_filter_helper const &) = delete;
+
+ comdlg_filter_helper(device_image_interface &device, bool include_archives)
+ {
+ m_count = 0U;
+
+ std::wstring const extensions = osd::text::to_wstring(device.file_extensions());
+ std::wstring_view extview = extensions;
+ m_description = L"Media Image Files (";
+ for (auto comma = extview.find(','); !extview.empty(); comma = extview.find(','))
+ {
+ bool const found = std::wstring_view::npos != comma;
+ std::wstring_view const ext = found ? extview.substr(0, comma) : extview;
+ extview.remove_prefix(found ? (comma + 1) : extview.length());
+ if (m_extensions.empty())
+ {
+ m_default = ext;
+ m_description.append(L"*.");
+ m_extensions.append(L"*.");
+ }
+ else
+ {
+ m_description.append(L"; *.");
+ m_extensions.append(L";*.");
+ }
+ m_description.append(ext);
+ m_extensions.append(ext);
+ }
+ m_description.append(1, L')');
+ m_specs[m_count].pszName = m_description.c_str();
+ m_specs[m_count].pszSpec = m_extensions.c_str();
+ ++m_count;
+
+ if (include_archives)
+ {
+ m_specs[m_count].pszName = L"Archive Files (*.zip; *.7z)";
+ m_specs[m_count].pszSpec = L"*.zip;*.7z";
+ ++m_count;
+ }
+
+ m_specs[m_count].pszName = L"All Files (*.*)";
+ m_specs[m_count].pszSpec = L"*.*";
+ ++m_count;
+ }
+
+ UINT file_types() const noexcept
+ {
+ return m_count;
+ }
+
+ COMDLG_FILTERSPEC const *filter_spec() const noexcept
+ {
+ return m_specs;
+ }
+
+ LPCWSTR default_extension() const noexcept
+ {
+ return m_default.c_str();
+ }
+
+private:
+ COMDLG_FILTERSPEC m_specs[3];
+ std::wstring m_description;
+ std::wstring m_extensions;
+ std::wstring m_default;
+ UINT m_count;
+};
+
+
+template <typename T>
+void choose_image(device_image_interface &device, HWND owner, REFCLSID class_id, bool allow_archives, T &&handler)
+{
+ HRESULT hr;
+
+ // create file dialog
+ Microsoft::WRL::ComPtr<IFileDialog> dialog;
+ hr = CoCreateInstance(class_id, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&dialog));
+
+ // set file types
+ if (SUCCEEDED(hr))
+ {
+ DWORD flags;
+ hr = dialog->GetOptions(&flags);
+ if (SUCCEEDED(hr))
+ hr = dialog->SetOptions(flags | FOS_NOCHANGEDIR | FOS_FORCEFILESYSTEM);
+ comdlg_filter_helper filters(device, allow_archives);
+ if (SUCCEEDED(hr))
+ hr = dialog->SetFileTypes(filters.file_types(), filters.filter_spec());
+ if (SUCCEEDED(hr))
+ hr = dialog->SetFileTypeIndex(1);
+ if (SUCCEEDED(hr))
+ hr = dialog->SetDefaultExtension(filters.default_extension());
+ }
+
+ // set starting folder
+ if (SUCCEEDED(hr))
+ {
+ std::string dir = device.working_directory();
+ if (dir.empty())
+ {
+ dir = device.device().machine().image().setup_working_directory();
+ device.set_working_directory(dir);
+ }
+ std::string full;
+ if (!dir.empty() && !osd_get_full_path(full, dir))
+ {
+ // FIXME: strip off archive names - opening a file inside an archive decompresses it to a temporary location
+ std::wstring wfull = osd::text::to_wstring(full);
+ Microsoft::WRL::ComPtr<IShellItem> item;
+ if (SUCCEEDED(SHCreateItemFromParsingName(wfull.c_str(), nullptr, IID_PPV_ARGS(&item))))
+ {
+ //dialog->SetFolder(item); disabled until
+ }
+ }
+ }
+
+ // show the dialog
+ if (SUCCEEDED(hr))
+ {
+ hr = dialog->Show(owner);
+ if (HRESULT_FROM_WIN32(ERROR_CANCELLED) == hr)
+ return;
+ }
+ if (SUCCEEDED(hr))
+ {
+ Microsoft::WRL::ComPtr<IShellItem> result;
+ hr = dialog->GetResult(&result);
+ if (SUCCEEDED(hr))
+ {
+ PWSTR selection = nullptr;
+ hr = result->GetDisplayName(SIGDN_FILESYSPATH, &selection);
+ if (SUCCEEDED(hr))
+ {
+ std::string const utf_selection = osd::text::from_wstring(selection);
+ CoTaskMemFree(selection);
+ handler(utf_selection);
+ }
+ }
+ }
+
+ if (!SUCCEEDED(hr))
+ {
+ int pressed;
+ TaskDialog(
+ owner,
+ nullptr, // instance
+ nullptr, // title
+ L"Error showing file dialog",
+ nullptr, // content
+ TDCBF_OK_BUTTON,
+ TD_ERROR_ICON,
+ &pressed);
+ }
+}
+
+} // anonymous namespace
+
+
consolewin_info::consolewin_info(debugger_windows_interface &debugger) :
disasmbasewin_info(debugger, true, "Debug", nullptr),
m_current_cpu(nullptr),
m_devices_menu(nullptr)
{
- if ((window() == nullptr) || (m_views[0] == nullptr))
+ if (!window() || !m_views[0])
goto cleanup;
// create the views
- m_views[1].reset(global_alloc(debugview_info(debugger, *this, window(), DVT_STATE)));
+ m_views[1].reset(new debugview_info(debugger, *this, window(), DVT_STATE));
if (!m_views[1]->is_valid())
goto cleanup;
- m_views[2].reset(global_alloc(debugview_info(debugger, *this, window(), DVT_CONSOLE)));
+ m_views[2].reset(new debugview_info(debugger, *this, window(), DVT_CONSOLE));
if (!m_views[2]->is_valid())
goto cleanup;
{
- // Add image menu only if image devices exist
- image_interface_iterator iter(machine().root_device());
+ // add image menu only if image devices exist
+ image_interface_enumerator iter(machine().root_device());
if (iter.first() != nullptr)
{
m_devices_menu = CreatePopupMenu();
for (device_image_interface &img : iter)
{
- if (!img.user_loadable())
- continue;
- osd::text::tstring tc_buf = osd::text::to_tstring(string_format("%s : %s", img.device().name(), img.exists() ? img.filename() : "[no image]"));
- AppendMenu(m_devices_menu, MF_ENABLED, 0, tc_buf.c_str());
+ if (img.user_loadable())
+ {
+ osd::text::tstring tc_buf = osd::text::to_tstring(string_format("%s : %s", img.device().name(), img.exists() ? img.filename() : "[no image]"));
+ AppendMenu(m_devices_menu, MF_ENABLED, 0, tc_buf.c_str());
+ }
}
AppendMenu(GetMenu(window()), MF_ENABLED | MF_POPUP, (UINT_PTR)m_devices_menu, TEXT("Media"));
}
+ // add the settings menu
+ HMENU const settingsmenu = CreatePopupMenu();
+ AppendMenu(settingsmenu, MF_ENABLED, ID_SAVE_WINDOWS, TEXT("Save Window Arrangement"));
+ AppendMenu(settingsmenu, MF_ENABLED, ID_GROUP_WINDOWS, TEXT("Group Debugger Windows (requires restart)"));
+ AppendMenu(settingsmenu, MF_DISABLED | MF_SEPARATOR, 0, TEXT(""));
+ AppendMenu(settingsmenu, MF_ENABLED, ID_LIGHT_BACKGROUND, TEXT("Light Background"));
+ AppendMenu(settingsmenu, MF_ENABLED, ID_DARK_BACKGROUND, TEXT("Dark Background"));
+ AppendMenu(GetMenu(window()), MF_ENABLED | MF_POPUP, (UINT_PTR)settingsmenu, TEXT("Settings"));
+
// get the work bounds
RECT work_bounds, bounds;
SystemParametersInfo(SPI_GETWORKAREA, 0, &work_bounds, 0);
@@ -78,7 +276,7 @@ consolewin_info::consolewin_info(debugger_windows_interface &debugger) :
}
// recompute the children
- set_cpu(*machine().debugger().cpu().get_visible_cpu());
+ set_cpu(*machine().debugger().console().get_visible_cpu());
// mark the edit box as the default focus and set it
editwin_info::set_default_focus();
@@ -163,11 +361,11 @@ void consolewin_info::update_menu()
{
disasmbasewin_info::update_menu();
- if (m_devices_menu != nullptr)
+ if (m_devices_menu)
{
// create the image menu
uint32_t cnt = 0;
- for (device_image_interface &img : image_interface_iterator(machine().root_device()))
+ for (device_image_interface &img : image_interface_enumerator(machine().root_device()))
{
if (!img.user_loadable())
continue;
@@ -184,8 +382,8 @@ void consolewin_info::update_menu()
if (img.is_readonly())
flags_for_writing |= MF_GRAYED;
- // not working properly, removed for now until investigation can be done
- //if (get_softlist_info(&img))
+ // FIXME: needs a real software item picker to be useful
+ //if (get_softlist_info(img))
// AppendMenu(devicesubmenu, MF_STRING, new_item + DEVOPTION_ITEM, TEXT("Mount Item..."));
AppendMenu(devicesubmenu, MF_STRING, new_item + DEVOPTION_OPEN, TEXT("Mount File..."));
@@ -199,7 +397,7 @@ void consolewin_info::update_menu()
if (img.device().type() == CASSETTE)
{
- cassette_state const state = cassette_state(downcast<cassette_image_device *>(&img.device())->get_state() & CASSETTE_MASK_UISTATE);
+ cassette_state const state = downcast<cassette_image_device *>(&img.device())->get_state() & CASSETTE_MASK_UISTATE;
AppendMenu(devicesubmenu, MF_SEPARATOR, 0, nullptr);
AppendMenu(devicesubmenu, flags_for_exists | ((state == CASSETTE_STOPPED) ? MF_CHECKED : 0), new_item + DEVOPTION_CASSETTE_STOPPAUSE, TEXT("Pause/Stop"));
AppendMenu(devicesubmenu, flags_for_exists | ((state == CASSETTE_PLAY) ? MF_CHECKED : 0), new_item + DEVOPTION_CASSETTE_PLAY, TEXT("Play"));
@@ -208,9 +406,9 @@ void consolewin_info::update_menu()
AppendMenu(devicesubmenu, flags_for_exists, new_item + DEVOPTION_CASSETTE_FASTFORWARD, TEXT("Fast Forward"));
AppendMenu(devicesubmenu, MF_SEPARATOR, 0, nullptr);
// Motor state can be overriden by the driver
- cassette_state const motor_state = cassette_state(downcast<cassette_image_device *>(&img.device())->get_state() & CASSETTE_MASK_MOTOR);
+ cassette_state const motor_state = downcast<cassette_image_device *>(&img.device())->get_state() & CASSETTE_MASK_MOTOR;
AppendMenu(devicesubmenu, flags_for_exists | ((motor_state == CASSETTE_MOTOR_ENABLED) ? MF_CHECKED : 0), new_item + DEVOPTION_CASSETTE_MOTOR, TEXT("Motor"));
- cassette_state const speaker_state = cassette_state(downcast<cassette_image_device *>(&img.device())->get_state() & CASSETTE_MASK_SPEAKER);
+ cassette_state const speaker_state = downcast<cassette_image_device *>(&img.device())->get_state() & CASSETTE_MASK_SPEAKER;
AppendMenu(devicesubmenu, flags_for_exists | ((speaker_state == CASSETTE_SPEAKER_ENABLED) ? MF_CHECKED : 0), new_item + DEVOPTION_CASSETTE_SOUND, TEXT("Audio while Loading"));
}
}
@@ -249,239 +447,105 @@ void consolewin_info::update_menu()
cnt++;
}
}
+
+ HMENU const menu = GetMenu(window());
+ CheckMenuItem(menu, ID_SAVE_WINDOWS, MF_BYCOMMAND | (debugger().get_save_window_arrangement() ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(menu, ID_GROUP_WINDOWS, MF_BYCOMMAND | (debugger().get_group_windows_setting() ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(menu, ID_LIGHT_BACKGROUND, MF_BYCOMMAND | ((ui_metrics::THEME_LIGHT_BACKGROUND == metrics().get_color_theme()) ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(menu, ID_DARK_BACKGROUND, MF_BYCOMMAND | ((ui_metrics::THEME_DARK_BACKGROUND == metrics().get_color_theme()) ? MF_CHECKED : MF_UNCHECKED));
}
bool consolewin_info::handle_command(WPARAM wparam, LPARAM lparam)
{
- if ((HIWORD(wparam) == 0) && (LOWORD(wparam) >= ID_DEVICE_OPTIONS))
+ if (HIWORD(wparam) == 0)
{
- uint32_t const devid = (LOWORD(wparam) - ID_DEVICE_OPTIONS) / DEVOPTION_MAX;
- image_interface_iterator iter(machine().root_device());
- device_image_interface *const img = iter.byindex(devid);
- if (img != nullptr)
+ if (LOWORD(wparam) >= ID_DEVICE_OPTIONS)
{
- switch ((LOWORD(wparam) - ID_DEVICE_OPTIONS) % DEVOPTION_MAX)
+ uint32_t const devid = (LOWORD(wparam) - ID_DEVICE_OPTIONS) / DEVOPTION_MAX;
+ image_interface_enumerator iter(machine().root_device());
+ device_image_interface *const img = iter.byindex(devid);
+ if (img != nullptr)
{
- case DEVOPTION_ITEM :
- {
- std::string filter;
- build_generic_filter(nullptr, false, filter);
- {
- osd::text::tstring t_filter = osd::text::to_tstring(filter);
-
- // convert a pipe-char delimited string into a NUL delimited string
- for (int i = 0; t_filter[i] != '\0'; i++)
- {
- if (t_filter[i] == '|')
- t_filter[i] = '\0';
- }
-
- std::string opt_name = img->instance_name();
- std::string as = slmap.find(opt_name)->second;
-
- /* Make sure a folder was specified, and that it exists */
- if ((!osd::directory::open(as.c_str())) || (as.find(':') == std::string::npos))
- {
- /* Default to emu directory */
- osd_get_full_path(as, ".");
- }
- osd::text::tstring t_dir = osd::text::to_tstring(as);
-
- // display the dialog
- TCHAR selectedFilename[MAX_PATH];
- selectedFilename[0] = '\0';
- OPENFILENAME ofn;
- memset(&ofn, 0, sizeof(ofn));
- ofn.lStructSize = sizeof(ofn);
- ofn.hwndOwner = nullptr;
- ofn.lpstrFile = selectedFilename;
- ofn.lpstrFile[0] = '\0';
- ofn.nMaxFile = MAX_PATH;
- ofn.lpstrFilter = t_filter.c_str();
- ofn.nFilterIndex = 1;
- ofn.lpstrFileTitle = nullptr;
- ofn.nMaxFileTitle = 0;
- ofn.lpstrInitialDir = t_dir.c_str();
- ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
-
- if (GetOpenFileName(&ofn))
- {
- std::string buf = std::string(osd::text::from_tstring(selectedFilename));
- // Get the Item name out of the full path
- size_t t1 = buf.find(".zip"); // get rid of zip name and anything after
- if (t1 != std::string::npos)
- buf.erase(t1);
- t1 = buf.find(".7z"); // get rid of 7zip name and anything after
- if (t1 != std::string::npos)
- buf.erase(t1);
- t1 = buf.find_last_of("\\"); // put the swlist name in
- buf[t1] = ':';
- t1 = buf.find_last_of("\\"); // get rid of path; we only want the item name
- buf.erase(0, t1+1);
-
- // load software
- img->load_software( buf.c_str());
- }
- }
- }
- return true;
- case DEVOPTION_OPEN :
- {
- std::string filter;
- build_generic_filter(img, false, filter);
- {
- osd::text::tstring t_filter = osd::text::to_tstring(filter);
-
- // convert a pipe-char delimited string into a NUL delimited string
- for (int i = 0; t_filter[i] != '\0'; i++)
- {
- if (t_filter[i] == '|')
- t_filter[i] = '\0';
- }
-
- char buf[400];
- std::string as;
- strcpy(buf, machine().options().emu_options::sw_path());
- // This pulls out the first path from a multipath field
- const char* t1 = strtok(buf, ";");
- if (t1)
- as = t1; // the first path of many
- else
- as = buf; // the only path
-
- /* Make sure a folder was specified, and that it exists */
- if ((!osd::directory::open(as.c_str())) || (as.find(':') == std::string::npos))
- {
- /* Default to emu directory */
- osd_get_full_path(as, ".");
- }
- osd::text::tstring t_dir = osd::text::to_tstring(as);
-
- TCHAR selectedFilename[MAX_PATH];
- selectedFilename[0] = '\0';
- OPENFILENAME ofn;
- memset(&ofn, 0, sizeof(ofn));
- ofn.lStructSize = sizeof(ofn);
- ofn.hwndOwner = nullptr;
- ofn.lpstrFile = selectedFilename;
- ofn.lpstrFile[0] = '\0';
- ofn.nMaxFile = MAX_PATH;
- ofn.lpstrFilter = t_filter.c_str();
- ofn.nFilterIndex = 1;
- ofn.lpstrFileTitle = nullptr;
- ofn.nMaxFileTitle = 0;
- ofn.lpstrInitialDir = t_dir.c_str();
- ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
-
- if (GetOpenFileName(&ofn))
- {
- auto utf8_buf = osd::text::from_tstring(selectedFilename);
- img->load(utf8_buf.c_str());
- }
- }
- }
- return true;
- case DEVOPTION_CREATE:
- {
- std::string filter;
- build_generic_filter(img, true, filter);
- {
- osd::text::tstring t_filter = osd::text::to_tstring(filter);
- // convert a pipe-char delimited string into a NUL delimited string
- for (int i = 0; t_filter[i] != '\0'; i++)
- {
- if (t_filter[i] == '|')
- t_filter[i] = '\0';
- }
-
- char buf[400];
- std::string as;
- strcpy(buf, machine().options().emu_options::sw_path());
- // This pulls out the first path from a multipath field
- const char* t1 = strtok(buf, ";");
- if (t1)
- as = t1; // the first path of many
- else
- as = buf; // the only path
-
- /* Make sure a folder was specified, and that it exists */
- if ((!osd::directory::open(as.c_str())) || (as.find(':') == std::string::npos))
- {
- /* Default to emu directory */
- osd_get_full_path(as, ".");
- }
- osd::text::tstring t_dir = osd::text::to_tstring(as);
-
- TCHAR selectedFilename[MAX_PATH];
- selectedFilename[0] = '\0';
- OPENFILENAME ofn;
- memset(&ofn, 0, sizeof(ofn));
- ofn.lStructSize = sizeof(ofn);
- ofn.hwndOwner = nullptr;
- ofn.lpstrFile = selectedFilename;
- ofn.lpstrFile[0] = '\0';
- ofn.nMaxFile = MAX_PATH;
- ofn.lpstrFilter = t_filter.c_str();
- ofn.nFilterIndex = 1;
- ofn.lpstrFileTitle = nullptr;
- ofn.nMaxFileTitle = 0;
- ofn.lpstrInitialDir = t_dir.c_str();
- ofn.Flags = OFN_PATHMUSTEXIST;
-
- if (GetSaveFileName(&ofn))
- {
- auto utf8_buf = osd::text::from_tstring(selectedFilename);
- img->create(utf8_buf.c_str(), img->device_get_indexed_creatable_format(0), nullptr);
- }
- }
- }
- return true;
- case DEVOPTION_CLOSE:
- img->unload();
- return true;
- }
- if (img->device().type() == CASSETTE)
- {
- cassette_image_device *const cassette = downcast<cassette_image_device *>(&img->device());
- bool s;
switch ((LOWORD(wparam) - ID_DEVICE_OPTIONS) % DEVOPTION_MAX)
{
- case DEVOPTION_CASSETTE_STOPPAUSE:
- cassette->change_state(CASSETTE_STOPPED, CASSETTE_MASK_UISTATE);
+ case DEVOPTION_ITEM:
+ // TODO: this is supposed to show a software list item picker - it never worked properly
return true;
- case DEVOPTION_CASSETTE_PLAY:
- cassette->change_state(CASSETTE_PLAY, CASSETTE_MASK_UISTATE);
+ case DEVOPTION_OPEN :
+ open_image_file(*img);
return true;
- case DEVOPTION_CASSETTE_RECORD:
- cassette->change_state(CASSETTE_RECORD, CASSETTE_MASK_UISTATE);
+ case DEVOPTION_CREATE:
+ create_image_file(*img);
return true;
- case DEVOPTION_CASSETTE_REWIND:
- cassette->seek(0.0, SEEK_SET); // to start
+ case DEVOPTION_CLOSE:
+ img->unload();
return true;
- case DEVOPTION_CASSETTE_FASTFORWARD:
- cassette->seek(+300.0, SEEK_CUR); // 5 minutes forward or end, whichever comes first
- break;
- case DEVOPTION_CASSETTE_MOTOR:
- s =((cassette->get_state() & CASSETTE_MASK_MOTOR) == CASSETTE_MOTOR_DISABLED);
- cassette->change_state(s ? CASSETTE_MOTOR_ENABLED : CASSETTE_MOTOR_DISABLED, CASSETTE_MASK_MOTOR);
- break;
- case DEVOPTION_CASSETTE_SOUND:
- s =((cassette->get_state() & CASSETTE_MASK_SPEAKER) == CASSETTE_SPEAKER_MUTED);
- cassette->change_state(s ? CASSETTE_SPEAKER_ENABLED : CASSETTE_SPEAKER_MUTED, CASSETTE_MASK_SPEAKER);
- break;
+ }
+ if (img->device().type() == CASSETTE)
+ {
+ auto *const cassette = downcast<cassette_image_device *>(&img->device());
+ bool s;
+ switch ((LOWORD(wparam) - ID_DEVICE_OPTIONS) % DEVOPTION_MAX)
+ {
+ case DEVOPTION_CASSETTE_STOPPAUSE:
+ cassette->change_state(CASSETTE_STOPPED, CASSETTE_MASK_UISTATE);
+ return true;
+ case DEVOPTION_CASSETTE_PLAY:
+ cassette->change_state(CASSETTE_PLAY, CASSETTE_MASK_UISTATE);
+ return true;
+ case DEVOPTION_CASSETTE_RECORD:
+ cassette->change_state(CASSETTE_RECORD, CASSETTE_MASK_UISTATE);
+ return true;
+ case DEVOPTION_CASSETTE_REWIND:
+ cassette->seek(0.0, SEEK_SET); // to start
+ return true;
+ case DEVOPTION_CASSETTE_FASTFORWARD:
+ cassette->seek(+300.0, SEEK_CUR); // 5 minutes forward or end, whichever comes first
+ return true;
+ case DEVOPTION_CASSETTE_MOTOR:
+ s = ((cassette->get_state() & CASSETTE_MASK_MOTOR) == CASSETTE_MOTOR_DISABLED);
+ cassette->change_state(s ? CASSETTE_MOTOR_ENABLED : CASSETTE_MOTOR_DISABLED, CASSETTE_MASK_MOTOR);
+ return true;
+ case DEVOPTION_CASSETTE_SOUND:
+ s = ((cassette->get_state() & CASSETTE_MASK_SPEAKER) == CASSETTE_SPEAKER_MUTED);
+ cassette->change_state(s ? CASSETTE_SPEAKER_ENABLED : CASSETTE_SPEAKER_MUTED, CASSETTE_MASK_SPEAKER);
+ return true;
+ }
}
}
}
+ else switch (LOWORD(wparam))
+ {
+ case ID_SAVE_WINDOWS:
+ debugger().set_save_window_arrangement(!debugger().get_save_window_arrangement());
+ return true;
+ case ID_GROUP_WINDOWS:
+ debugger().set_group_windows_setting(!debugger().get_group_windows_setting());
+ return true;
+ case ID_LIGHT_BACKGROUND:
+ debugger().set_color_theme(ui_metrics::THEME_LIGHT_BACKGROUND);
+ return true;
+ case ID_DARK_BACKGROUND:
+ debugger().set_color_theme(ui_metrics::THEME_DARK_BACKGROUND);
+ return true;
+ }
}
return disasmbasewin_info::handle_command(wparam, lparam);
}
+void consolewin_info::save_configuration_to_node(util::xml::data_node &node)
+{
+ disasmbasewin_info::save_configuration_to_node(node);
+ node.set_attribute_int(ATTR_WINDOW_TYPE, WINDOW_TYPE_CONSOLE);
+}
+
+
void consolewin_info::process_string(std::string const &string)
{
if (string.empty()) // an empty string is a single step
- machine().debugger().cpu().get_visible_cpu()->debug()->single_step();
+ machine().debugger().console().get_visible_cpu()->debug()->single_step();
else // otherwise, just process the command
machine().debugger().console().execute_command(string, true);
@@ -490,94 +554,60 @@ void consolewin_info::process_string(std::string const &string)
}
-void consolewin_info::build_generic_filter(device_image_interface *img, bool is_save, std::string &filter)
+void consolewin_info::open_image_file(device_image_interface &device)
{
- std::string file_extension;
-
- if (img)
- file_extension = img->file_extensions();
-
- if (!is_save)
- file_extension.append(",zip,7z");
-
- add_filter_entry(filter, "Common image types", file_extension.c_str());
-
- filter.append("All files (*.*)|*.*|");
-
- if (!is_save)
- filter.append("Compressed Images (*.zip;*.7z)|*.zip;*.7z|");
+ choose_image(
+ device,
+ window(),
+ CLSID_FileOpenDialog,
+ true,
+ [this, &device] (std::string_view selection)
+ {
+ auto [err, message] = device.load(selection);
+ if (err)
+ machine().debugger().console().printf("Error mounting image file: %s\n", !message.empty() ? message : err.message());
+ });
}
-void consolewin_info::add_filter_entry(std::string &dest, const char *description, const char *extensions)
+void consolewin_info::create_image_file(device_image_interface &device)
{
- // add the description
- dest.append(description);
- dest.append(" (");
-
- // add the extensions to the description
- copy_extension_list(dest, extensions);
-
- // add the trailing rparen and '|' character
- dest.append(")|");
-
- // now add the extension list itself
- copy_extension_list(dest, extensions);
-
- // append a '|'
- dest.append("|");
+ choose_image(
+ device,
+ window(),
+ CLSID_FileSaveDialog,
+ false,
+ [this, &device] (std::string_view selection)
+ {
+ auto [err, message] = device.create(selection, device.device_get_indexed_creatable_format(0), nullptr);
+ if (err)
+ machine().debugger().console().printf("Error creating image file: %s\n", !message.empty() ? message : err.message());
+ });
}
-void consolewin_info::copy_extension_list(std::string &dest, const char *extensions)
-{
- // our extension lists are comma delimited; Win32 expects to see lists
- // delimited by semicolons
- char const *s = extensions;
- while (*s)
- {
- // append a semicolon if not at the beginning
- if (s != extensions)
- dest.push_back(';');
-
- // append ".*"
- dest.append("*.");
-
- // append the file extension
- while (*s && (*s != ','))
- dest.push_back(*s++);
-
- // if we found a comma, advance
- while(*s == ',')
- s++;
- }
-}
-
-//============================================================
-// get_softlist_info
-//============================================================
-bool consolewin_info::get_softlist_info(device_image_interface *img)
+bool consolewin_info::get_softlist_info(device_image_interface &device)
{
bool has_software = false;
bool passes_tests = false;
- std::string sl_dir, opt_name = img->instance_name();
+ std::string sl_dir, opt_name = device.instance_name();
// Get the path to suitable software
- for (software_list_device &swlist : software_list_device_iterator(machine().root_device()))
+ for (software_list_device &swlist : software_list_device_enumerator(machine().root_device()))
{
for (const software_info &swinfo : swlist.get_info())
{
const software_part &part = swinfo.parts().front();
if (swlist.is_compatible(part) == SOFTWARE_IS_COMPATIBLE)
{
- for (device_image_interface &image : image_interface_iterator(machine().root_device()))
+ for (device_image_interface &image : image_interface_enumerator(machine().root_device()))
{
if (!image.user_loadable())
continue;
if (!has_software && (opt_name == image.instance_name()))
{
- const char *interface = image.image_interface();
- if (interface && part.matches_interface(interface))
+ const char *intf = image.image_interface();
+ if (intf && part.matches_interface(intf))
{
sl_dir = "\\" + swlist.list_name();
has_software = true;
@@ -598,7 +628,7 @@ bool consolewin_info::get_softlist_info(device_image_interface *img)
while (sl_root && !passes_tests)
{
std::string test_path = sl_root + sl_dir;
- if (osd::directory::open(test_path.c_str()))
+ if (osd::directory::open(test_path))
{
passes_tests = true;
slmap[opt_name] = test_path;
@@ -609,3 +639,5 @@ bool consolewin_info::get_softlist_info(device_image_interface *img)
return passes_tests;
}
+
+} // namespace osd::debugger::win
diff --git a/src/osd/modules/debugger/win/consolewininfo.h b/src/osd/modules/debugger/win/consolewininfo.h
index 7f8ccc13aec..e79ba667a11 100644
--- a/src/osd/modules/debugger/win/consolewininfo.h
+++ b/src/osd/modules/debugger/win/consolewininfo.h
@@ -5,15 +5,18 @@
// consolewininfo.h - Win32 debug window handling
//
//============================================================
+#ifndef MAME_DEBUGGER_WIN_CONSOLEWININFO_H
+#define MAME_DEBUGGER_WIN_CONSOLEWININFO_H
-#ifndef __DEBUG_WIN_CONSOLE_WIN_INFO_H__
-#define __DEBUG_WIN_CONSOLE_WIN_INFO_H__
+#pragma once
#include "debugwin.h"
#include "disasmbasewininfo.h"
+namespace osd::debugger::win {
+
class consolewin_info : public disasmbasewin_info
{
public:
@@ -26,6 +29,7 @@ protected:
virtual void recompute_children() override;
virtual void update_menu() override;
virtual bool handle_command(WPARAM wparam, LPARAM lparam) override;
+ virtual void save_configuration_to_node(util::xml::data_node &node) override;
private:
enum
@@ -46,14 +50,15 @@ private:
virtual void process_string(std::string const &string) override;
- static void build_generic_filter(device_image_interface *img, bool is_save, std::string &filter);
- static void add_filter_entry(std::string &dest, char const *description, char const *extensions);
- static void copy_extension_list(std::string &dest, char const *extensions);
- bool get_softlist_info(device_image_interface *img);
+ void open_image_file(device_image_interface &device);
+ void create_image_file(device_image_interface &device);
+ bool get_softlist_info(device_image_interface &img);
device_t *m_current_cpu;
- HMENU m_devices_menu;
+ HMENU m_devices_menu;
std::map<std::string,std::string> slmap;
};
-#endif
+} // namespace osd::debugger::win
+
+#endif // MAME_DEBUGGER_WIN_CONSOLEWININFO_H
diff --git a/src/osd/modules/debugger/win/debugbaseinfo.cpp b/src/osd/modules/debugger/win/debugbaseinfo.cpp
index 4914d54cfad..0de7331cbc8 100644
--- a/src/osd/modules/debugger/win/debugbaseinfo.cpp
+++ b/src/osd/modules/debugger/win/debugbaseinfo.cpp
@@ -10,6 +10,8 @@
#include "debugbaseinfo.h"
+namespace osd::debugger::win {
+
debugbase_info::debugbase_info(debugger_windows_interface &debugger) :
m_debugger(debugger),
m_machine(debugger.machine()),
@@ -21,12 +23,10 @@ debugbase_info::debugbase_info(debugger_windows_interface &debugger) :
void debugbase_info::smart_set_window_bounds(HWND wnd, HWND parent, RECT const &bounds)
{
- RECT curbounds;
- int flags = 0;
-
// first get the current bounds, relative to the parent
+ RECT curbounds;
GetWindowRect(wnd, &curbounds);
- if (parent != nullptr)
+ if (parent)
{
RECT parentbounds;
GetWindowRect(parent, &parentbounds);
@@ -37,6 +37,7 @@ void debugbase_info::smart_set_window_bounds(HWND wnd, HWND parent, RECT const &
}
// if the position matches, don't change it
+ int flags = 0;
if (curbounds.top == bounds.top && curbounds.left == bounds.left)
flags |= SWP_NOMOVE;
if ((curbounds.bottom - curbounds.top) == (bounds.bottom - bounds.top) &&
@@ -45,17 +46,21 @@ void debugbase_info::smart_set_window_bounds(HWND wnd, HWND parent, RECT const &
// if we need to, reposition the window
if (flags != (SWP_NOMOVE | SWP_NOSIZE))
- SetWindowPos(wnd, nullptr,
- bounds.left, bounds.top,
- bounds.right - bounds.left, bounds.bottom - bounds.top,
- SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER | flags);
+ {
+ SetWindowPos(
+ wnd, nullptr,
+ bounds.left, bounds.top,
+ bounds.right - bounds.left, bounds.bottom - bounds.top,
+ SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER | flags);
+ }
}
-
void debugbase_info::smart_show_window(HWND wnd, bool show)
{
- BOOL const visible = IsWindowVisible(wnd);
- if ((visible && !show) || (!visible && show))
+ bool const visible = bool(IsWindowVisible(wnd));
+ if (visible != show)
ShowWindow(wnd, show ? SW_SHOW : SW_HIDE);
}
+
+} // namespace osd::debugger::win
diff --git a/src/osd/modules/debugger/win/debugbaseinfo.h b/src/osd/modules/debugger/win/debugbaseinfo.h
index 03fd5a8018d..da874a6b8fd 100644
--- a/src/osd/modules/debugger/win/debugbaseinfo.h
+++ b/src/osd/modules/debugger/win/debugbaseinfo.h
@@ -5,13 +5,15 @@
// debugbaseinfo.h - Win32 debug window handling
//
//============================================================
+#ifndef MAME_DEBUGGER_WIN_DEBUGBASEINFO_H
+#define MAME_DEBUGGER_WIN_DEBUGBASEINFO_H
-#ifndef __DEBUG_WIN_DEBUG_BASE_INFO_H__
-#define __DEBUG_WIN_DEBUG_BASE_INFO_H__
+#pragma once
#include "debugwin.h"
+namespace osd::debugger::win {
class debugbase_info
{
@@ -35,5 +37,6 @@ private:
bool const &m_waiting_for_debugger;
};
+} // namespace osd::debugger::win
-#endif
+#endif // MAME_DEBUGGER_WIN_DEBUGBASEINFO_H
diff --git a/src/osd/modules/debugger/win/debugviewinfo.cpp b/src/osd/modules/debugger/win/debugviewinfo.cpp
index 97238ff8862..8f3f05c16d2 100644
--- a/src/osd/modules/debugger/win/debugviewinfo.cpp
+++ b/src/osd/modules/debugger/win/debugviewinfo.cpp
@@ -2,7 +2,7 @@
// copyright-holders:Aaron Giles, Vas Crabb
//============================================================
//
-// debugview.c - Win32 debug window handling
+// debugviewinfo.cpp - Win32 debug window handling
//
//============================================================
@@ -12,12 +12,20 @@
#include "debugwininfo.h"
#include "uimetrics.h"
#include "debugger.h"
+
+#include "debug/debugcon.h"
#include "debug/debugcpu.h"
+#include "util/xmlfile.h"
+
#include "strconv.h"
#include "winutil.h"
+#include <mmsystem.h>
+
+
+namespace osd::debugger::win {
// debugger view styles
#define DEBUG_VIEW_STYLE WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN
@@ -45,14 +53,15 @@ debugview_info::debugview_info(debugger_windows_interface &debugger, debugwin_in
m_view(nullptr),
m_wnd(nullptr),
m_hscroll(nullptr),
- m_vscroll(nullptr)
+ m_vscroll(nullptr),
+ m_contextmenu(nullptr)
{
register_window_class();
// create the child view
m_wnd = CreateWindowEx(DEBUG_VIEW_STYLE_EX, TEXT("MAMEDebugView"), nullptr, DEBUG_VIEW_STYLE,
0, 0, 100, 100, parent, nullptr, GetModuleHandleUni(), this);
- if (m_wnd == nullptr)
+ if (!m_wnd)
goto cleanup;
// create the scroll bars
@@ -60,27 +69,27 @@ debugview_info::debugview_info(debugger_windows_interface &debugger, debugwin_in
0, 0, 100, CW_USEDEFAULT, m_wnd, nullptr, GetModuleHandleUni(), this);
m_vscroll = CreateWindowEx(VSCROLL_STYLE_EX, TEXT("SCROLLBAR"), nullptr, VSCROLL_STYLE,
0, 0, CW_USEDEFAULT, 100, m_wnd, nullptr, GetModuleHandleUni(), this);
- if ((m_hscroll == nullptr) || (m_vscroll == nullptr))
+ if (!m_hscroll || !m_vscroll)
goto cleanup;
// create the debug view
m_view = machine().debug_view().alloc_view(type, &debugview_info::static_update, this);
- if (m_view == nullptr)
+ if (!m_view)
goto cleanup;
return;
cleanup:
- if (m_hscroll != nullptr)
+ if (m_hscroll)
DestroyWindow(m_hscroll);
m_hscroll = nullptr;
- if (m_vscroll != nullptr)
+ if (m_vscroll)
DestroyWindow(m_vscroll);
m_vscroll = nullptr;
- if (m_wnd != nullptr)
+ if (m_wnd)
DestroyWindow(m_wnd);
m_wnd = nullptr;
- if (m_view != nullptr)
+ if (m_view)
machine().debug_view().free_view(*m_view);
m_view = nullptr;
}
@@ -88,7 +97,9 @@ cleanup:
debugview_info::~debugview_info()
{
- if (m_wnd != nullptr)
+ if (m_contextmenu)
+ DestroyMenu(m_contextmenu);
+ if (m_wnd)
DestroyWindow(m_wnd);
if (m_view)
machine().debug_view().free_view(*m_view);
@@ -111,14 +122,14 @@ uint32_t debugview_info::maxwidth()
{
uint32_t max = m_view->total_size().x;
debug_view_source const *const cursource = m_view->source();
- for (const debug_view_source &source : m_view->source_list())
+ for (auto &source : m_view->source_list())
{
- m_view->set_source(source);
+ m_view->set_source(*source);
uint32_t const chars = m_view->total_size().x;
if (max < chars)
max = chars;
}
- if (cursource != nullptr)
+ if (cursource)
m_view->set_source(*cursource);
return (max * metrics().debug_font_width()) + metrics().vscroll_width();
}
@@ -163,27 +174,35 @@ void debugview_info::send_vscroll(int delta)
void debugview_info::send_pageup()
{
if (m_vscroll)
- {
SendMessage(m_wnd, WM_VSCROLL, SB_PAGELEFT, (LPARAM)m_vscroll);
- }
}
void debugview_info::send_pagedown()
{
if (m_vscroll)
- {
SendMessage(m_wnd, WM_VSCROLL, SB_PAGERIGHT, (LPARAM)m_vscroll);
+}
+
+
+int debugview_info::source_index() const
+{
+ if (m_view)
+ {
+ debug_view_source const *const source = m_view->source();
+ if (source)
+ return m_view->source_index(*source);
}
+ return -1;
}
char const *debugview_info::source_name() const
{
- if (m_view != nullptr)
+ if (m_view)
{
debug_view_source const *const source = m_view->source();
- if (source != nullptr)
+ if (source)
return source->name();
}
return "";
@@ -192,10 +211,10 @@ char const *debugview_info::source_name() const
device_t *debugview_info::source_device() const
{
- if (m_view != nullptr)
+ if (m_view)
{
debug_view_source const *const source = m_view->source();
- if (source != nullptr)
+ if (source)
return source->device();
}
return nullptr;
@@ -204,10 +223,10 @@ device_t *debugview_info::source_device() const
bool debugview_info::source_is_visible_cpu() const
{
- if (m_view != nullptr)
+ if (m_view)
{
const debug_view_source *const source = m_view->source();
- return (source != nullptr) && (machine().debugger().cpu().get_visible_cpu() == source->device());
+ return source && (machine().debugger().console().get_visible_cpu() == source->device());
}
return false;
}
@@ -215,10 +234,10 @@ bool debugview_info::source_is_visible_cpu() const
bool debugview_info::set_source_index(int index)
{
- if (m_view != nullptr)
+ if (m_view)
{
- const debug_view_source *const source = m_view->source_list().find(index);
- if (source != nullptr)
+ const debug_view_source *const source = m_view->source(index);
+ if (source)
{
m_view->set_source(*source);
return true;
@@ -230,10 +249,10 @@ bool debugview_info::set_source_index(int index)
bool debugview_info::set_source_for_device(device_t &device)
{
- if (m_view != nullptr)
+ if (m_view)
{
const debug_view_source *const source = m_view->source_for_device(&device);
- if (source != nullptr)
+ if (source)
{
m_view->set_source(*source);
return true;
@@ -245,8 +264,8 @@ bool debugview_info::set_source_for_device(device_t &device)
bool debugview_info::set_source_for_visible_cpu()
{
- device_t *const curcpu = machine().debugger().cpu().get_visible_cpu();
- if (curcpu != nullptr)
+ device_t *const curcpu = machine().debugger().console().get_visible_cpu();
+ if (curcpu)
return set_source_for_device(*curcpu);
else
return false;
@@ -264,7 +283,7 @@ HWND debugview_info::create_source_combobox(HWND parent, LONG_PTR userdata)
// populate the combobox
debug_view_source const *const cursource = m_view->source();
int maxlength = 0;
- for (debug_view_source const *source = m_view->first_source(); source != nullptr; source = source->next())
+ for (auto &source : m_view->source_list())
{
int const length = strlen(source->name());
if (length > maxlength)
@@ -272,9 +291,9 @@ HWND debugview_info::create_source_combobox(HWND parent, LONG_PTR userdata)
auto t_name = osd::text::to_tstring(source->name());
SendMessage(result, CB_ADDSTRING, 0, (LPARAM)t_name.c_str());
}
- if (cursource != nullptr)
+ if (cursource)
{
- SendMessage(result, CB_SETCURSEL, m_view->source_list().indexof(*cursource), 0);
+ SendMessage(result, CB_SETCURSEL, m_view->source_index(*cursource), 0);
SendMessage(result, CB_SETDROPPEDWIDTH, ((maxlength + 2) * metrics().debug_font_width()) + metrics().vscroll_width(), 0);
m_view->set_source(*cursource);
}
@@ -282,6 +301,165 @@ HWND debugview_info::create_source_combobox(HWND parent, LONG_PTR userdata)
}
+void debugview_info::restore_configuration_from_node(util::xml::data_node const &node)
+{
+ if (m_view->cursor_supported())
+ {
+ util::xml::data_node const *const selection = node.get_child(NODE_WINDOW_SELECTION);
+ if (selection)
+ {
+ debug_view_xy pos = m_view->cursor_position();
+ m_view->set_cursor_visible(0 != selection->get_attribute_int(ATTR_SELECTION_CURSOR_VISIBLE, m_view->cursor_visible() ? 1 : 0));
+ selection->get_attribute_int(ATTR_SELECTION_CURSOR_X, pos.x);
+ selection->get_attribute_int(ATTR_SELECTION_CURSOR_Y, pos.y);
+ m_view->set_cursor_position(pos);
+ }
+ }
+
+ util::xml::data_node const *const scroll = node.get_child(NODE_WINDOW_SCROLL);
+ if (scroll)
+ {
+ debug_view_xy origin = m_view->visible_position();
+ origin.x = scroll->get_attribute_int(ATTR_SCROLL_ORIGIN_X, origin.x * metrics().debug_font_width()) / metrics().debug_font_width();
+ origin.y = scroll->get_attribute_int(ATTR_SCROLL_ORIGIN_Y, origin.y * metrics().debug_font_height()) / metrics().debug_font_height();
+ m_view->set_visible_position(origin);
+ }
+}
+
+
+void debugview_info::save_configuration_to_node(util::xml::data_node &node)
+{
+ if (m_view->cursor_supported())
+ {
+ util::xml::data_node *const selection = node.add_child(NODE_WINDOW_SELECTION, nullptr);
+ if (selection)
+ {
+ debug_view_xy const pos = m_view->cursor_position();
+ selection->set_attribute_int(ATTR_SELECTION_CURSOR_VISIBLE, m_view->cursor_visible() ? 1 : 0);
+ selection->set_attribute_int(ATTR_SELECTION_CURSOR_X, pos.x);
+ selection->set_attribute_int(ATTR_SELECTION_CURSOR_Y, pos.y);
+ }
+ }
+
+ util::xml::data_node *const scroll = node.add_child(NODE_WINDOW_SCROLL, nullptr);
+ if (scroll)
+ {
+ debug_view_xy const origin = m_view->visible_position();
+ scroll->set_attribute_int(ATTR_SCROLL_ORIGIN_X, origin.x * metrics().debug_font_width());
+ scroll->set_attribute_int(ATTR_SCROLL_ORIGIN_Y, origin.y * metrics().debug_font_height());
+ }
+}
+
+
+void debugview_info::add_items_to_context_menu(HMENU menu)
+{
+ AppendMenu(menu, MF_ENABLED, ID_CONTEXT_COPY_VISIBLE, TEXT("Copy Visible"));
+ AppendMenu(menu, MF_ENABLED, ID_CONTEXT_PASTE, TEXT("Paste"));
+}
+
+
+void debugview_info::update_context_menu(HMENU menu)
+{
+ EnableMenuItem(menu, ID_CONTEXT_PASTE, MF_BYCOMMAND | (IsClipboardFormatAvailable(CF_UNICODETEXT) ? MF_ENABLED : MF_GRAYED));
+}
+
+
+void debugview_info::handle_context_menu(unsigned command)
+{
+ switch (command)
+ {
+ case ID_CONTEXT_COPY_VISIBLE:
+ {
+ // get visible text
+ debug_view_xy const visarea = m_view->visible_size();
+ debug_view_char const *viewdata = m_view->viewdata();
+ if (!viewdata)
+ {
+ PlaySound(TEXT("SystemAsterisk"), nullptr, SND_SYNC);
+ break;
+ }
+
+ // turn into a plain string, trimming trailing whitespace
+ std::wstring text;
+ for (uint32_t row = 0; row < visarea.y; row++, viewdata += visarea.x)
+ {
+ std::wstring::size_type const start = text.length();
+ for (uint32_t col = 0; col < visarea.x; ++col)
+ text += wchar_t(viewdata[col].byte);
+ std::wstring::size_type const nonblank = text.find_last_not_of(L"\t\n\v\r ");
+ if (nonblank != std::wstring::npos)
+ text.resize((std::max)(start, nonblank + 1));
+ text += L"\r\n";
+ }
+
+ // copy to the clipboard
+ HGLOBAL const clip = GlobalAlloc(GMEM_MOVEABLE, (text.length() + 1) * sizeof(wchar_t));
+ if (!clip)
+ {
+ PlaySound(TEXT("SystemAsterisk"), nullptr, SND_SYNC);
+ break;
+ }
+ if (!OpenClipboard(m_wnd))
+ {
+ GlobalFree(clip);
+ PlaySound(TEXT("SystemAsterisk"), nullptr, SND_SYNC);
+ break;
+ }
+ EmptyClipboard();
+ LPWSTR const lock = reinterpret_cast<LPWSTR>(GlobalLock(clip));
+ std::copy_n(text.c_str(), text.length() + 1, lock);
+ GlobalUnlock(clip);
+ if (!SetClipboardData(CF_UNICODETEXT, clip))
+ {
+ GlobalFree(clip);
+ PlaySound(TEXT("SystemAsterisk"), nullptr, SND_SYNC);
+ }
+ CloseClipboard();
+ break;
+ }
+
+ case ID_CONTEXT_PASTE:
+ if (!IsClipboardFormatAvailable(CF_UNICODETEXT) || !OpenClipboard(m_wnd))
+ {
+ PlaySound(TEXT("SystemAsterisk"), nullptr, SND_SYNC);
+ }
+ else
+ {
+ HGLOBAL const clip = GetClipboardData(CF_UNICODETEXT);
+ LPCWSTR lock = clip ? reinterpret_cast<LPCWSTR>(GlobalLock(clip)) : nullptr;
+ if (!clip || !lock)
+ {
+ PlaySound(TEXT("SystemAsterisk"), nullptr, SND_SYNC);
+ }
+ else
+ {
+ try
+ {
+ while (*lock)
+ {
+ if ((32 <= *lock) && (127 >= *lock))
+ m_view->process_char(*lock);
+ ++lock;
+ }
+ }
+ catch (...)
+ {
+ GlobalUnlock(clip);
+ CloseClipboard();
+ throw;
+ }
+ GlobalUnlock(clip);
+ }
+ CloseClipboard();
+ }
+ break;
+
+ default:
+ osd_printf_warning("debugview_info: unhandled context menu item %u\n", command);
+ }
+}
+
+
void debugview_info::draw_contents(HDC windc)
{
debug_view_char const *viewdata = m_view->viewdata();
@@ -290,18 +468,22 @@ void debugview_info::draw_contents(HDC windc)
// get the client rect
RECT client;
GetClientRect(m_wnd, &client);
+ bool const need_filldown = client.bottom > (metrics().debug_font_height() * visarea.y);
// create a compatible DC and an offscreen bitmap
HDC const dc = CreateCompatibleDC(windc);
- if (dc == nullptr)
+ if (!dc)
return;
HBITMAP const bitmap = CreateCompatibleBitmap(windc, client.right, client.bottom);
- if (bitmap == nullptr)
+ if (!bitmap)
{
DeleteDC(dc);
return;
}
HGDIOBJ const oldbitmap = SelectObject(dc, bitmap);
+ bool const show_hscroll = m_hscroll && IsWindowVisible(m_hscroll);
+ if (show_hscroll)
+ client.bottom -= metrics().hscroll_height();
// set the font
HGDIOBJ const oldfont = SelectObject(dc, metrics().debug_font());
@@ -312,11 +494,13 @@ void debugview_info::draw_contents(HDC windc)
// iterate over rows and columns
for (uint32_t row = 0; row < visarea.y; row++)
{
+ bool do_filldown = (row == (visarea.y - 1)) && need_filldown;
+
// loop twice; once to fill the background and once to draw the text
for (int iter = 0; iter < 2; iter++)
{
COLORREF fgcolor;
- COLORREF bgcolor = RGB(0xff,0xff,0xff);
+ COLORREF bgcolor = metrics().view_colors(DCA_NORMAL).second;
HBRUSH bgbrush = nullptr;
int last_attrib = -1;
TCHAR buffer[256];
@@ -340,41 +524,49 @@ void debugview_info::draw_contents(HDC windc)
{
COLORREF oldbg = bgcolor;
- // reset to standard colors
- fgcolor = RGB(0x00,0x00,0x00);
- bgcolor = RGB(0xff,0xff,0xff);
-
- // pick new fg/bg colors
- if (viewdata[col].attrib & DCA_VISITED) bgcolor = RGB(0xc6, 0xe2, 0xff);
- if (viewdata[col].attrib & DCA_ANCILLARY) bgcolor = RGB(0xe0,0xe0,0xe0);
- if (viewdata[col].attrib & DCA_SELECTED) bgcolor = RGB(0xff,0x80,0x80);
- if (viewdata[col].attrib & DCA_CURRENT) bgcolor = RGB(0xff,0xff,0x00);
- if ((viewdata[col].attrib & DCA_SELECTED) && (viewdata[col].attrib & DCA_CURRENT)) bgcolor = RGB(0xff,0xc0,0x80);
- if (viewdata[col].attrib & DCA_CHANGED) fgcolor = RGB(0xff,0x00,0x00);
- if (viewdata[col].attrib & DCA_INVALID) fgcolor = RGB(0x00,0x00,0xff);
- if (viewdata[col].attrib & DCA_DISABLED) fgcolor = RGB((GetRValue(fgcolor) + GetRValue(bgcolor)) / 2, (GetGValue(fgcolor) + GetGValue(bgcolor)) / 2, (GetBValue(fgcolor) + GetBValue(bgcolor)) / 2);
- if (viewdata[col].attrib & DCA_COMMENT) fgcolor = RGB(0x00,0x80,0x00);
+ // pick new colors
+ std::tie(fgcolor, bgcolor) = metrics().view_colors(viewdata[col].attrib);
// flush any pending drawing
if (count > 0)
{
bounds.right = bounds.left + (count * metrics().debug_font_width());
if (iter == 0)
+ {
FillRect(dc, &bounds, bgbrush);
+ if (do_filldown)
+ {
+ COLORREF const filldown = metrics().view_colors(last_attrib & DCA_ANCILLARY).second;
+ if (oldbg != filldown)
+ {
+ DeleteObject(bgbrush);
+ bgbrush = CreateSolidBrush(filldown);
+ oldbg = filldown;
+ }
+ RECT padding = bounds;
+ padding.top = padding.bottom;
+ padding.bottom = client.bottom;
+ FillRect(dc, &padding, bgbrush);
+ }
+ }
else
+ {
ExtTextOut(dc, bounds.left, bounds.top, 0, nullptr, buffer, count, nullptr);
+ }
bounds.left = bounds.right;
count = 0;
}
// set the new colors
- if (iter == 0 && oldbg != bgcolor)
+ if (iter == 1)
+ {
+ SetTextColor(dc, fgcolor);
+ }
+ else if (oldbg != bgcolor)
{
DeleteObject(bgbrush);
bgbrush = CreateSolidBrush(bgcolor);
}
- else if (iter == 1)
- SetTextColor(dc, fgcolor);
last_attrib = viewdata[col].attrib;
}
@@ -383,33 +575,43 @@ void debugview_info::draw_contents(HDC windc)
}
// flush any remaining stuff
- if (count > 0)
- {
- bounds.right = bounds.left + (count * metrics().debug_font_width());
- if (iter == 0)
- FillRect(dc, &bounds, bgbrush);
- else
- ExtTextOut(dc, bounds.left, bounds.top, 0, nullptr, buffer, count, nullptr);
- }
-
- // erase to the end of the line
+ bounds.right = bounds.left + (count * metrics().debug_font_width());
if (iter == 0)
{
- bounds.left = bounds.right;
+ // erase to the end of the line
bounds.right = client.right;
FillRect(dc, &bounds, bgbrush);
+ if (do_filldown)
+ {
+ COLORREF const filldown = metrics().view_colors(last_attrib & DCA_ANCILLARY).second;
+ if (bgcolor != filldown)
+ {
+ DeleteObject(bgbrush);
+ bgbrush = CreateSolidBrush(filldown);
+ }
+ bounds.top = bounds.bottom;
+ bounds.bottom = client.bottom;
+ FillRect(dc, &bounds, bgbrush);
+ }
DeleteObject(bgbrush);
}
+ else if (count > 0)
+ {
+ ExtTextOut(dc, bounds.left, bounds.top, 0, nullptr, buffer, count, nullptr);
+ }
}
// advance viewdata
viewdata += visarea.x;
}
- // erase anything beyond the bottom with white
- GetClientRect(m_wnd, &client);
- client.top = visarea.y * metrics().debug_font_height();
- FillRect(dc, &client, (HBRUSH)GetStockObject(WHITE_BRUSH));
+ // prevent garbage from showing in the corner
+ if (show_hscroll)
+ {
+ client.top = client.bottom;
+ client.bottom = client.top + metrics().hscroll_height();
+ FillRect(dc, &client, (HBRUSH)GetStockObject(WHITE_BRUSH));
+ }
// reset the font
SetBkMode(dc, oldbkmode);
@@ -428,47 +630,48 @@ void debugview_info::draw_contents(HDC windc)
void debugview_info::update()
{
- RECT bounds, vscroll_bounds, hscroll_bounds;
- debug_view_xy totalsize, visiblesize, topleft;
- bool show_vscroll, show_hscroll;
SCROLLINFO scrollinfo;
+ // get the updated total rows/cols and left row/col
+ debug_view_xy const totalsize = m_view->total_size();
+ debug_view_xy topleft = m_view->visible_position();
+
// get the view window bounds
+ RECT bounds;
GetClientRect(m_wnd, &bounds);
+ debug_view_xy visiblesize;
visiblesize.x = (bounds.right - bounds.left) / metrics().debug_font_width();
visiblesize.y = (bounds.bottom - bounds.top) / metrics().debug_font_height();
- // get the updated total rows/cols and left row/col
- totalsize = m_view->total_size();
- topleft = m_view->visible_position();
-
// determine if we need to show the scrollbars
- show_vscroll = show_hscroll = false;
- if (totalsize.x > visiblesize.x && bounds.bottom >= metrics().hscroll_height())
+ bool const fit_hscroll = (bounds.bottom - bounds.top) > metrics().hscroll_height();
+ bool show_hscroll = fit_hscroll && (totalsize.x > visiblesize.x);
+ if (show_hscroll)
{
bounds.bottom -= metrics().hscroll_height();
visiblesize.y = (bounds.bottom - bounds.top) / metrics().debug_font_height();
- show_hscroll = true;
- }
- if (totalsize.y > visiblesize.y && bounds.right >= metrics().vscroll_width())
- {
- bounds.right -= metrics().vscroll_width();
- visiblesize.x = (bounds.right - bounds.left) / metrics().debug_font_width();
- show_vscroll = true;
}
- if (!show_vscroll && totalsize.y > visiblesize.y && bounds.right >= metrics().vscroll_width())
+ bool const fit_vscroll = (bounds.right - bounds.left) > metrics().vscroll_width();
+ bool const show_vscroll = fit_vscroll && (totalsize.y > visiblesize.y);
+ if (show_vscroll)
{
bounds.right -= metrics().vscroll_width();
visiblesize.x = (bounds.right - bounds.left) / metrics().debug_font_width();
- show_vscroll = true;
+ if (fit_hscroll && !show_hscroll && (totalsize.x > visiblesize.x))
+ {
+ bounds.bottom -= metrics().hscroll_height();
+ visiblesize.y = (bounds.bottom - bounds.top) / metrics().debug_font_height();
+ show_hscroll = true;
+ }
}
// compute the bounds of the scrollbars
+ RECT vscroll_bounds;
GetClientRect(m_wnd, &vscroll_bounds);
vscroll_bounds.left = vscroll_bounds.right - metrics().vscroll_width();
if (show_hscroll)
vscroll_bounds.bottom -= metrics().hscroll_height();
-
+ RECT hscroll_bounds;
GetClientRect(m_wnd, &hscroll_bounds);
hscroll_bounds.top = hscroll_bounds.bottom - metrics().hscroll_height();
if (show_vscroll)
@@ -481,26 +684,34 @@ void debugview_info::update()
topleft.x = std::max(totalsize.x - visiblesize.x, 0);
// fill out the scroll info struct for the vertical scrollbar
- scrollinfo.cbSize = sizeof(scrollinfo);
- scrollinfo.fMask = SIF_PAGE | SIF_POS | SIF_RANGE;
- scrollinfo.nMin = 0;
- scrollinfo.nMax = totalsize.y - 1;
- scrollinfo.nPage = visiblesize.y;
- scrollinfo.nPos = topleft.y;
- SetScrollInfo(m_vscroll, SB_CTL, &scrollinfo, TRUE);
+ if (m_vscroll)
+ {
+ scrollinfo.cbSize = sizeof(scrollinfo);
+ scrollinfo.fMask = SIF_PAGE | SIF_POS | SIF_RANGE;
+ scrollinfo.nMin = 0;
+ scrollinfo.nMax = totalsize.y - 1;
+ scrollinfo.nPage = visiblesize.y;
+ scrollinfo.nPos = topleft.y;
+ SetScrollInfo(m_vscroll, SB_CTL, &scrollinfo, TRUE);
+ }
// fill out the scroll info struct for the horizontal scrollbar
- scrollinfo.cbSize = sizeof(scrollinfo);
- scrollinfo.fMask = SIF_PAGE | SIF_POS | SIF_RANGE;
- scrollinfo.nMin = 0;
- scrollinfo.nMax = totalsize.x - 1;
- scrollinfo.nPage = visiblesize.x;
- scrollinfo.nPos = topleft.x;
- SetScrollInfo(m_hscroll, SB_CTL, &scrollinfo, TRUE);
+ if (m_hscroll)
+ {
+ scrollinfo.cbSize = sizeof(scrollinfo);
+ scrollinfo.fMask = SIF_PAGE | SIF_POS | SIF_RANGE;
+ scrollinfo.nMin = 0;
+ scrollinfo.nMax = totalsize.x - 1;
+ scrollinfo.nPage = visiblesize.x;
+ scrollinfo.nPos = topleft.x;
+ SetScrollInfo(m_hscroll, SB_CTL, &scrollinfo, TRUE);
+ }
// update window info
- visiblesize.y++;
- visiblesize.x++;
+ if (((bounds.right - bounds.left) > (visiblesize.x * metrics().debug_font_width())) && ((topleft.x + visiblesize.x) < totalsize.x))
+ visiblesize.x++;
+ if (((bounds.bottom - bounds.top) > (visiblesize.y * metrics().debug_font_height())) && ((topleft.y + visiblesize.y) < totalsize.y))
+ visiblesize.y++;
m_view->set_visible_size(visiblesize);
m_view->set_visible_position(topleft);
@@ -580,7 +791,41 @@ uint32_t debugview_info::process_scroll(WORD type, HWND wnd)
scrollinfo.nPos = result;
SetScrollInfo(wnd, SB_CTL, &scrollinfo, TRUE);
- return (uint32_t)result;
+ return uint32_t(result);
+}
+
+
+bool debugview_info::process_context_menu(int x, int y)
+{
+ // don't show a menu if not in client rect
+ RECT clientrect;
+ GetClientRect(m_wnd, &clientrect);
+ POINT loc{ x, y };
+ ScreenToClient(m_wnd, &loc);
+ if (!PtInRect(&clientrect, loc))
+ return false;
+
+ // create the context menu if we haven’t already
+ if (!m_contextmenu)
+ {
+ m_contextmenu = CreatePopupMenu();
+ if (!m_contextmenu)
+ return false;
+ add_items_to_context_menu(m_contextmenu);
+ }
+
+ // show the context menu
+ update_context_menu(m_contextmenu);
+ BOOL const command(TrackPopupMenu(
+ m_contextmenu,
+ (GetSystemMetrics(SM_MENUDROPALIGNMENT) ? TPM_RIGHTALIGN : TPM_LEFTALIGN) | TPM_LEFTBUTTON | TPM_NONOTIFY | TPM_RETURNCMD,
+ x, y,
+ 0,
+ m_wnd,
+ nullptr));
+ if (command)
+ handle_context_menu(command);
+ return true;
}
@@ -603,7 +848,7 @@ LRESULT debugview_info::view_proc(UINT message, WPARAM wparam, LPARAM lparam)
case WM_SYSKEYDOWN:
if (wparam != VK_F10)
return DefWindowProc(m_wnd, message, wparam, lparam);
- // (fall through)
+ [[fallthrough]];
case WM_KEYDOWN:
{
if (m_owner.handle_key(wparam, lparam))
@@ -717,17 +962,33 @@ LRESULT debugview_info::view_proc(UINT message, WPARAM wparam, LPARAM lparam)
// mouse click
case WM_LBUTTONDOWN:
+ case WM_MBUTTONDOWN:
{
- debug_view_xy topleft = m_view->visible_position();
+ debug_view_xy const topleft = m_view->visible_position();
+ debug_view_xy const visiblesize = m_view->visible_size();
debug_view_xy newpos;
- newpos.x = topleft.x + GET_X_LPARAM(lparam) / metrics().debug_font_width();
- newpos.y = topleft.y + GET_Y_LPARAM(lparam) / metrics().debug_font_height();
- m_view->process_click(DCK_LEFT_CLICK, newpos);
+ newpos.x = std::max(std::min<int>(topleft.x + GET_X_LPARAM(lparam) / metrics().debug_font_width(), topleft.x + visiblesize.x - 1), 0);
+ newpos.y = std::max(std::min<int>(topleft.y + GET_Y_LPARAM(lparam) / metrics().debug_font_height(), topleft.y + visiblesize.y - 1), 0);
+ m_view->process_click((message == WM_LBUTTONDOWN) ? DCK_LEFT_CLICK : DCK_MIDDLE_CLICK, newpos);
SetFocus(m_wnd);
break;
}
- // hscroll
+ // right click
+ case WM_RBUTTONDOWN:
+ if (m_view->cursor_supported())
+ {
+ debug_view_xy const topleft = m_view->visible_position();
+ debug_view_xy const visiblesize = m_view->visible_size();
+ debug_view_xy newpos;
+ newpos.x = std::max(std::min<int>(topleft.x + GET_X_LPARAM(lparam) / metrics().debug_font_width(), topleft.x + visiblesize.x - 1), 0);
+ newpos.y = std::max(std::min<int>(topleft.y + GET_Y_LPARAM(lparam) / metrics().debug_font_height(), topleft.y + visiblesize.y - 1), 0);
+ m_view->set_cursor_position(newpos);
+ m_view->set_cursor_visible(true);
+ }
+ return DefWindowProc(m_wnd, message, wparam, lparam);
+
+ // horizontal scroll
case WM_HSCROLL:
{
debug_view_xy topleft = m_view->visible_position();
@@ -737,7 +998,7 @@ LRESULT debugview_info::view_proc(UINT message, WPARAM wparam, LPARAM lparam)
break;
}
- // vscroll
+ // vertical scroll
case WM_VSCROLL:
{
debug_view_xy topleft = m_view->visible_position();
@@ -747,6 +1008,11 @@ LRESULT debugview_info::view_proc(UINT message, WPARAM wparam, LPARAM lparam)
break;
}
+ case WM_CONTEXTMENU:
+ if (!process_context_menu(GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam)))
+ return DefWindowProc(m_wnd, message, wparam, lparam);
+ break;
+
// everything else: defaults
default:
return DefWindowProc(m_wnd, message, wparam, lparam);
@@ -758,7 +1024,7 @@ LRESULT debugview_info::view_proc(UINT message, WPARAM wparam, LPARAM lparam)
void debugview_info::static_update(debug_view &view, void *osdprivate)
{
- debugview_info *const info = (debugview_info *)osdprivate;
+ auto *const info = (debugview_info *)osdprivate;
assert(info->m_view == &view);
info->update();
}
@@ -774,7 +1040,7 @@ LRESULT CALLBACK debugview_info::static_view_proc(HWND wnd, UINT message, WPARAM
return 0;
}
- debugview_info *const info = (debugview_info *)(uintptr_t)GetWindowLongPtr(wnd, GWLP_USERDATA);
+ auto *const info = (debugview_info *)(uintptr_t)GetWindowLongPtr(wnd, GWLP_USERDATA);
if (info == nullptr)
return DefWindowProc(wnd, message, wparam, lparam);
@@ -810,3 +1076,5 @@ void debugview_info::register_window_class()
s_window_class_registered = true;
}
}
+
+} // namespace osd::debugger::win
diff --git a/src/osd/modules/debugger/win/debugviewinfo.h b/src/osd/modules/debugger/win/debugviewinfo.h
index 37d6930e445..a009c368441 100644
--- a/src/osd/modules/debugger/win/debugviewinfo.h
+++ b/src/osd/modules/debugger/win/debugviewinfo.h
@@ -5,9 +5,10 @@
// debugviewinfo.h - Win32 debug window handling
//
//============================================================
+#ifndef MAME_DEBUGGER_WIN_DEBUGVIEWINFO_H
+#define MAME_DEBUGGER_WIN_DEBUGVIEWINFO_H
-#ifndef __DEBUG_WIN_DEBUG_VIEW_INFO_H__
-#define __DEBUG_WIN_DEBUG_VIEW_INFO_H__
+#pragma once
#include "debugwin.h"
@@ -16,6 +17,8 @@
#include "debug/debugvw.h"
+namespace osd::debugger::win {
+
class debugview_info : protected debugbase_info
{
public:
@@ -41,6 +44,7 @@ public:
bool cursor_supported() const { return m_view->cursor_supported(); }
bool cursor_visible() const { return m_view->cursor_visible(); }
+ int source_index() const;
char const *source_name() const;
device_t *source_device() const;
bool source_is_visible_cpu() const;
@@ -50,13 +54,27 @@ public:
HWND create_source_combobox(HWND parent, LONG_PTR userdata);
+ virtual void restore_configuration_from_node(util::xml::data_node const &node);
+ virtual void save_configuration_to_node(util::xml::data_node &node);
+
protected:
+ enum
+ {
+ ID_CONTEXT_COPY_VISIBLE = 1,
+ ID_CONTEXT_PASTE
+ };
+
template <typename T> T *view() const { return downcast<T *>(m_view); }
+ virtual void add_items_to_context_menu(HMENU menu);
+ virtual void update_context_menu(HMENU menu);
+ virtual void handle_context_menu(unsigned command);
+
private:
void draw_contents(HDC windc);
void update();
uint32_t process_scroll(WORD type, HWND wnd);
+ bool process_context_menu(int x, int y);
LRESULT view_proc(UINT message, WPARAM wparam, LPARAM lparam);
static void static_update(debug_view &view, void *osdprivate);
@@ -69,8 +87,11 @@ private:
HWND m_wnd;
HWND m_hscroll;
HWND m_vscroll;
+ HMENU m_contextmenu;
static bool s_window_class_registered;
};
-#endif
+} // namespace osd::debugger::win
+
+#endif // MAME_DEBUGGER_WIN_DEBUGVIEWINFO_H
diff --git a/src/osd/modules/debugger/win/debugwin.h b/src/osd/modules/debugger/win/debugwin.h
index ea78f126d5b..d8af29b795e 100644
--- a/src/osd/modules/debugger/win/debugwin.h
+++ b/src/osd/modules/debugger/win/debugwin.h
@@ -5,9 +5,12 @@
// debugwin.h - Win32 debug window handling
//
//============================================================
+#ifndef MAME_DEBUGGER_WIN_DEBUGWIN_H
+#define MAME_DEBUGGER_WIN_DEBUGWIN_H
-#ifndef __DEBUG_WIN_DEBUG_WIN_H__
-#define __DEBUG_WIN_DEBUG_WIN_H__
+#pragma once
+
+#include "../xmlconfig.h"
// standard windows headers
#include <windows.h>
@@ -19,6 +22,7 @@
#endif
+namespace osd::debugger::win {
class debugview_info;
class debugwin_info;
@@ -33,6 +37,12 @@ public:
virtual running_machine &machine() const = 0;
virtual ui_metrics &metrics() const = 0;
+ virtual void set_color_theme(int index) = 0;
+ virtual bool get_save_window_arrangement() const = 0;
+ virtual void set_save_window_arrangement(bool save) = 0;
+ virtual bool get_group_windows() const = 0;
+ virtual bool get_group_windows_setting() const = 0;
+ virtual void set_group_windows_setting(bool group) = 0;
virtual bool const &waiting_for_debugger() const = 0;
virtual bool seq_pressed() const = 0;
@@ -45,6 +55,10 @@ public:
virtual void show_all() = 0;
virtual void hide_all() = 0;
+
+ virtual void stagger_window(HWND window, int width, int height) = 0;
};
-#endif
+} // namespace osd::debugger::win
+
+#endif // MAME_DEBUGGER_WIN_DEBUGWIN_H
diff --git a/src/osd/modules/debugger/win/debugwininfo.cpp b/src/osd/modules/debugger/win/debugwininfo.cpp
index ac60b980439..f27f7933f08 100644
--- a/src/osd/modules/debugger/win/debugwininfo.cpp
+++ b/src/osd/modules/debugger/win/debugwininfo.cpp
@@ -2,7 +2,7 @@
// copyright-holders:Aaron Giles, Vas Crabb
//============================================================
//
-// debugwininfo.c - Win32 debug window handling
+// debugwininfo.cpp - Win32 debug window handling
//
//============================================================
@@ -12,13 +12,21 @@
#include "debugviewinfo.h"
#include "debugger.h"
+#include "debug/debugcon.h"
#include "debug/debugcpu.h"
+
+#include "util/xmlfile.h"
+
#include "window.h"
#include "winutf8.h"
-
#include "winutil.h"
+
#include "modules/lib/osdobj_common.h"
+#include <cstring>
+
+
+namespace osd::debugger::win {
bool debugwin_info::s_window_class_registered = false;
@@ -36,9 +44,16 @@ debugwin_info::debugwin_info(debugger_windows_interface &debugger, bool is_main_
{
register_window_class();
- m_wnd = win_create_window_ex_utf8(DEBUG_WINDOW_STYLE_EX, "MAMEDebugWindow", title, DEBUG_WINDOW_STYLE,
- 0, 0, 100, 100, std::static_pointer_cast<win_window_info>(osd_common_t::s_window_list.front())->platform_window(), create_standard_menubar(), GetModuleHandleUni(), this);
- if (m_wnd == nullptr)
+ m_wnd = win_create_window_ex_utf8(
+ DEBUG_WINDOW_STYLE_EX, "MAMEDebugWindow", title, DEBUG_WINDOW_STYLE,
+ 0, 0, 100, 100,
+ debugger.get_group_windows()
+ ? dynamic_cast<win_window_info &>(*osd_common_t::window_list().front()).platform_window()
+ : nullptr,
+ create_standard_menubar(),
+ GetModuleHandleUni(),
+ this);
+ if (!m_wnd)
return;
RECT work_bounds;
@@ -53,6 +68,12 @@ debugwin_info::~debugwin_info()
}
+void debugwin_info::redraw()
+{
+ RedrawWindow(m_wnd, nullptr, nullptr, RDW_INVALIDATE | RDW_ALLCHILDREN);
+}
+
+
void debugwin_info::destroy()
{
for (int curview = 0; curview < MAX_VIEWS; curview++)
@@ -250,6 +271,89 @@ bool debugwin_info::handle_key(WPARAM wparam, LPARAM lparam)
}
+void debugwin_info::save_configuration(util::xml::data_node &parentnode)
+{
+ util::xml::data_node *const node = parentnode.add_child(NODE_WINDOW, nullptr);
+ if (node)
+ save_configuration_to_node(*node);
+}
+
+
+void debugwin_info::restore_configuration_from_node(util::xml::data_node const &node)
+{
+ // get current size to use for defaults
+ RECT bounds;
+ POINT origin;
+ origin.x = 0;
+ origin.y = 0;
+ if (!GetClientRect(window(), &bounds) && ClientToScreen(window(), &origin))
+ return;
+
+ // get saved size and adjust for window chrome
+ RECT desired;
+ desired.left = node.get_attribute_int(ATTR_WINDOW_POSITION_X, origin.x);
+ desired.top = node.get_attribute_int(ATTR_WINDOW_POSITION_Y, origin.y);
+ desired.right = desired.left + node.get_attribute_int(ATTR_WINDOW_WIDTH, bounds.right);
+ desired.bottom = desired.top + node.get_attribute_int(ATTR_WINDOW_HEIGHT, bounds.bottom);
+ // TODO: sanity checks...
+ if (!AdjustWindowRectEx(&desired, DEBUG_WINDOW_STYLE, GetMenu(window()) ? TRUE : FALSE, DEBUG_WINDOW_STYLE_EX))
+ return;
+
+ // actually move the window
+ MoveWindow(
+ window(),
+ desired.left,
+ desired.top,
+ desired.right - desired.left,
+ desired.bottom - desired.top,
+ TRUE);
+
+ // restrict to one monitor and avoid toolbars
+ HMONITOR const nearest_monitor = MonitorFromWindow(window(), MONITOR_DEFAULTTONEAREST);
+ if (nearest_monitor)
+ {
+ MONITORINFO info;
+ std::memset(&info, 0, sizeof(info));
+ info.cbSize = sizeof(info);
+ if (GetMonitorInfo(nearest_monitor, &info))
+ {
+ if (desired.right > info.rcWork.right)
+ {
+ desired.left -= desired.right - info.rcWork.right;
+ desired.right = info.rcWork.right;
+ }
+ if (desired.bottom > info.rcWork.bottom)
+ {
+ desired.top -= desired.bottom - info.rcWork.bottom;
+ desired.bottom = info.rcWork.bottom;
+ }
+ if (desired.left < info.rcWork.left)
+ {
+ desired.right += info.rcWork.left - desired.left;
+ desired.left = info.rcWork.left;
+ }
+ if (desired.top < info.rcWork.top)
+ {
+ desired.bottom += info.rcWork.top - desired.top;
+ desired.top = info.rcWork.top;
+ }
+ desired.bottom = std::min(info.rcWork.bottom, desired.bottom);
+ desired.right = std::min(info.rcWork.right, desired.right);
+ MoveWindow(
+ window(),
+ desired.left,
+ desired.top,
+ desired.right - desired.left,
+ desired.bottom - desired.top,
+ TRUE);
+ }
+ }
+
+ // sort out contents
+ recompute_children();
+}
+
+
void debugwin_info::recompute_children()
{
if (m_views[0] != nullptr)
@@ -299,39 +403,40 @@ bool debugwin_info::handle_command(WPARAM wparam, LPARAM lparam)
case ID_RUN_AND_HIDE:
debugger().hide_all();
+ [[fallthrough]];
case ID_RUN:
- machine().debugger().cpu().get_visible_cpu()->debug()->go();
+ machine().debugger().console().get_visible_cpu()->debug()->go();
return true;
case ID_NEXT_CPU:
- machine().debugger().cpu().get_visible_cpu()->debug()->go_next_device();
+ machine().debugger().console().get_visible_cpu()->debug()->go_next_device();
return true;
case ID_RUN_VBLANK:
- machine().debugger().cpu().get_visible_cpu()->debug()->go_vblank();
+ machine().debugger().console().get_visible_cpu()->debug()->go_vblank();
return true;
case ID_RUN_IRQ:
- machine().debugger().cpu().get_visible_cpu()->debug()->go_interrupt();
+ machine().debugger().console().get_visible_cpu()->debug()->go_interrupt();
return true;
case ID_STEP:
- machine().debugger().cpu().get_visible_cpu()->debug()->single_step();
+ machine().debugger().console().get_visible_cpu()->debug()->single_step();
return true;
case ID_STEP_OVER:
- machine().debugger().cpu().get_visible_cpu()->debug()->single_step_over();
+ machine().debugger().console().get_visible_cpu()->debug()->single_step_over();
return true;
case ID_STEP_OUT:
- machine().debugger().cpu().get_visible_cpu()->debug()->single_step_out();
+ machine().debugger().console().get_visible_cpu()->debug()->single_step_out();
return true;
case ID_REWIND_STEP:
machine().rewind_step();
// clear all PC & memory tracks
- for (device_t &device : device_iterator(machine().root_device()))
+ for (device_t &device : device_enumerator(machine().root_device()))
{
device.debug()->track_pc_data_clear();
device.debug()->track_mem_data_clear();
@@ -348,7 +453,7 @@ bool debugwin_info::handle_command(WPARAM wparam, LPARAM lparam)
case ID_SOFT_RESET:
machine().schedule_soft_reset();
- machine().debugger().cpu().get_visible_cpu()->debug()->go();
+ machine().debugger().console().get_visible_cpu()->debug()->go();
return true;
case ID_EXIT:
@@ -390,6 +495,22 @@ void debugwin_info::draw_border(HDC dc, RECT &bounds)
}
+void debugwin_info::save_configuration_to_node(util::xml::data_node &node)
+{
+ RECT bounds;
+ POINT origin;
+ origin.x = 0;
+ origin.y = 0;
+ if (GetClientRect(window(), &bounds) && ClientToScreen(window(), &origin))
+ {
+ node.set_attribute_int(ATTR_WINDOW_POSITION_X, origin.x);
+ node.set_attribute_int(ATTR_WINDOW_POSITION_Y, origin.y);
+ node.set_attribute_int(ATTR_WINDOW_WIDTH, bounds.right);
+ node.set_attribute_int(ATTR_WINDOW_HEIGHT, bounds.bottom);
+ }
+}
+
+
void debugwin_info::draw_border(HDC dc, HWND child)
{
RECT bounds;
@@ -437,11 +558,10 @@ LRESULT debugwin_info::window_proc(UINT message, WPARAM wparam, LPARAM lparam)
// get min/max info: set the minimum window size
case WM_GETMINMAXINFO:
{
- MINMAXINFO *minmax = (MINMAXINFO *)lparam;
+ auto *minmax = (MINMAXINFO *)lparam;
minmax->ptMinTrackSize.x = m_minwidth;
minmax->ptMinTrackSize.y = m_minheight;
- minmax->ptMaxSize.x = minmax->ptMaxTrackSize.x = m_maxwidth;
- minmax->ptMaxSize.y = minmax->ptMaxTrackSize.y = m_maxheight;
+ // Leave default ptMaxSize and ptMaxTrackSize so maximum size is not restricted
break;
}
@@ -507,7 +627,7 @@ LRESULT debugwin_info::window_proc(UINT message, WPARAM wparam, LPARAM lparam)
if (m_is_main_console)
{
debugger().hide_all();
- machine().debugger().cpu().get_visible_cpu()->debug()->go();
+ machine().debugger().console().get_visible_cpu()->debug()->go();
}
else
{
@@ -575,14 +695,14 @@ LRESULT CALLBACK debugwin_info::static_window_proc(HWND wnd, UINT message, WPARA
{
// set the info pointer
CREATESTRUCT const *const createinfo = (CREATESTRUCT *)lparam;
- debugwin_info *const info = (debugwin_info *)createinfo->lpCreateParams;
+ auto *const info = (debugwin_info *)createinfo->lpCreateParams;
SetWindowLongPtr(wnd, GWLP_USERDATA, (LONG_PTR)createinfo->lpCreateParams);
if (info->m_handler)
SetWindowLongPtr(wnd, GWLP_WNDPROC, (LONG_PTR)info->m_handler);
return 0;
}
- debugwin_info *const info = (debugwin_info *)(uintptr_t)GetWindowLongPtr(wnd, GWLP_USERDATA);
+ auto *const info = (debugwin_info *)(uintptr_t)GetWindowLongPtr(wnd, GWLP_USERDATA);
if (info == nullptr)
return DefWindowProc(wnd, message, wparam, lparam);
@@ -618,3 +738,5 @@ void debugwin_info::register_window_class()
s_window_class_registered = true;
}
}
+
+} // namespace osd::debugger::win
diff --git a/src/osd/modules/debugger/win/debugwininfo.h b/src/osd/modules/debugger/win/debugwininfo.h
index 2090985d3f9..cf3587253f6 100644
--- a/src/osd/modules/debugger/win/debugwininfo.h
+++ b/src/osd/modules/debugger/win/debugwininfo.h
@@ -5,20 +5,21 @@
// debugwininfo.h - Win32 debug window handling
//
//============================================================
+#ifndef MAME_DEBUGGER_WIN_DEBUGWININFO_H
+#define MAME_DEBUGGER_WIN_DEBUGWININFO_H
-#ifndef __DEBUG_WIN_DEBUG_WIN_INFO_H__
-#define __DEBUG_WIN_DEBUG_WIN_INFO_H__
+#pragma once
#include "debugwin.h"
#include "debugbaseinfo.h"
+namespace osd::debugger::win {
class debugwin_info : protected debugbase_info
{
public:
- debugwin_info(debugger_windows_interface &debugger, bool is_main_console, LPCSTR title, WNDPROC handler);
virtual ~debugwin_info();
bool is_valid() const { return m_wnd != nullptr; }
@@ -40,6 +41,7 @@ public:
void show() const { smart_show_window(m_wnd, true); }
void hide() const { smart_show_window(m_wnd, false); }
void set_foreground() const { SetForegroundWindow(m_wnd); }
+ void redraw();
void destroy();
virtual bool set_default_focus();
@@ -49,6 +51,9 @@ public:
virtual bool handle_key(WPARAM wparam, LPARAM lparam);
+ void save_configuration(util::xml::data_node &parentnode);
+ virtual void restore_configuration_from_node(util::xml::data_node const &node);
+
protected:
static DWORD const DEBUG_WINDOW_STYLE = (WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN) & (~WS_MINIMIZEBOX & ~WS_MAXIMIZEBOX);
static DWORD const DEBUG_WINDOW_STYLE_EX = 0;
@@ -75,13 +80,20 @@ protected:
ID_SOFT_RESET,
ID_EXIT,
- ID_1_BYTE_CHUNKS,
- ID_2_BYTE_CHUNKS,
- ID_4_BYTE_CHUNKS,
- ID_8_BYTE_CHUNKS,
- ID_FLOATING_POINT_32BIT,
- ID_FLOATING_POINT_64BIT,
- ID_FLOATING_POINT_80BIT,
+ ID_1_BYTE_CHUNKS_HEX,
+ ID_2_BYTE_CHUNKS_HEX,
+ ID_4_BYTE_CHUNKS_HEX,
+ ID_8_BYTE_CHUNKS_HEX,
+ ID_1_BYTE_CHUNKS_OCT,
+ ID_2_BYTE_CHUNKS_OCT,
+ ID_4_BYTE_CHUNKS_OCT,
+ ID_8_BYTE_CHUNKS_OCT,
+ ID_FLOAT_32BIT,
+ ID_FLOAT_64BIT,
+ ID_FLOAT_80BIT,
+ ID_HEX_ADDRESSES,
+ ID_DEC_ADDRESSES,
+ ID_OCT_ADDRESSES,
ID_LOGICAL_ADDRESSES,
ID_PHYSICAL_ADDRESSES,
ID_REVERSE_VIEW,
@@ -97,12 +109,21 @@ protected:
ID_SHOW_BREAKPOINTS,
ID_SHOW_WATCHPOINTS,
+ ID_SHOW_REGISTERPOINTS,
+ ID_SHOW_EXCEPTIONPOINTS,
ID_CLEAR_LOG,
+ ID_SAVE_WINDOWS,
+ ID_GROUP_WINDOWS,
+ ID_LIGHT_BACKGROUND,
+ ID_DARK_BACKGROUND,
+
ID_DEVICE_OPTIONS // always keep this at the end
};
+ debugwin_info(debugger_windows_interface &debugger, bool is_main_console, LPCSTR title, WNDPROC handler);
+
bool is_main_console() const { return m_is_main_console; }
HWND window() const { return m_wnd; }
uint32_t minwidth() const { return m_minwidth; }
@@ -117,6 +138,8 @@ protected:
void draw_border(HDC dc, RECT &bounds);
void draw_border(HDC dc, HWND child);
+ virtual void save_configuration_to_node(util::xml::data_node &node);
+
std::unique_ptr<debugview_info> m_views[MAX_VIEWS];
private:
@@ -133,12 +156,14 @@ private:
HWND m_wnd;
WNDPROC const m_handler;
- uint32_t m_minwidth, m_maxwidth;
- uint32_t m_minheight, m_maxheight;
+ uint32_t m_minwidth, m_maxwidth;
+ uint32_t m_minheight, m_maxheight;
- uint16_t m_ignore_char_lparam;
+ uint16_t m_ignore_char_lparam;
static bool s_window_class_registered;
};
-#endif
+} // namespace osd::debugger::win
+
+#endif // MAME_DEBUGGER_WIN_DEBUGWININFO_H
diff --git a/src/osd/modules/debugger/win/disasmbasewininfo.cpp b/src/osd/modules/debugger/win/disasmbasewininfo.cpp
index c466e059f23..48771c4f133 100644
--- a/src/osd/modules/debugger/win/disasmbasewininfo.cpp
+++ b/src/osd/modules/debugger/win/disasmbasewininfo.cpp
@@ -2,7 +2,7 @@
// copyright-holders:Aaron Giles, Vas Crabb
//============================================================
//
-// disasmbasewininfo.c - Win32 debug window handling
+// disasmbasewininfo.cpp - Win32 debug window handling
//
//============================================================
@@ -15,18 +15,21 @@
#include "debugger.h"
#include "debug/debugcon.h"
#include "debug/debugcpu.h"
+#include "debug/points.h"
//#include "winutf8.h"
+namespace osd::debugger::win {
+
disasmbasewin_info::disasmbasewin_info(debugger_windows_interface &debugger, bool is_main_console, LPCSTR title, WNDPROC handler) :
editwin_info(debugger, is_main_console, title, handler)
{
if (!window())
return;
- m_views[0].reset(global_alloc(disasmview_info(debugger, *this, window())));
- if ((m_views[0] == nullptr) || !m_views[0]->is_valid())
+ m_views[0].reset(new disasmview_info(debugger, *this, window()));
+ if (!m_views[0] || !m_views[0]->is_valid())
{
m_views[0].reset();
return;
@@ -105,7 +108,7 @@ void disasmbasewin_info::update_menu()
{
editwin_info::update_menu();
- disasmview_info *const dasmview = downcast<disasmview_info *>(m_views[0].get());
+ auto *const dasmview = downcast<disasmview_info *>(m_views[0].get());
HMENU const menu = GetMenu(window());
bool const disasm_cursor_visible = dasmview->cursor_visible();
@@ -115,9 +118,9 @@ void disasmbasewin_info::update_menu()
device_debug *const debug = dasmview->source_device()->debug();
// first find an existing breakpoint at this address
- const device_debug::breakpoint *bp = debug->breakpoint_find(address);
+ const debug_breakpoint *bp = debug->breakpoint_find(address);
- if (bp == nullptr)
+ if (!bp)
{
ModifyMenu(menu, ID_TOGGLE_BREAKPOINT, MF_BYCOMMAND, ID_TOGGLE_BREAKPOINT, TEXT("Set breakpoint at cursor\tF9"));
ModifyMenu(menu, ID_DISABLE_BREAKPOINT, MF_BYCOMMAND, ID_DISABLE_BREAKPOINT, TEXT("Disable breakpoint at cursor\tShift+F9"));
@@ -130,7 +133,7 @@ void disasmbasewin_info::update_menu()
else
ModifyMenu(menu, ID_DISABLE_BREAKPOINT, MF_BYCOMMAND, ID_DISABLE_BREAKPOINT, TEXT("Enable breakpoint at cursor\tShift+F9"));
}
- bool const available = (bp != nullptr) && (!is_main_console() || dasmview->source_is_visible_cpu());
+ bool const available = bp && (!is_main_console() || dasmview->source_is_visible_cpu());
EnableMenuItem(menu, ID_DISABLE_BREAKPOINT, MF_BYCOMMAND | (available ? MF_ENABLED : MF_GRAYED));
}
else
@@ -151,7 +154,7 @@ void disasmbasewin_info::update_menu()
bool disasmbasewin_info::handle_command(WPARAM wparam, LPARAM lparam)
{
- disasmview_info *const dasmview = downcast<disasmview_info *>(m_views[0].get());
+ auto *const dasmview = downcast<disasmview_info *>(m_views[0].get());
switch (HIWORD(wparam))
{
@@ -166,14 +169,14 @@ bool disasmbasewin_info::handle_command(WPARAM wparam, LPARAM lparam)
device_debug *const debug = dasmview->source_device()->debug();
// first find an existing breakpoint at this address
- const device_debug::breakpoint *bp = debug->breakpoint_find(address);
+ const debug_breakpoint *bp = debug->breakpoint_find(address);
// if it doesn't exist, add a new one
if (!is_main_console())
{
if (bp == nullptr)
{
- int32_t bpindex = debug->breakpoint_set(address, nullptr, nullptr);
+ int32_t bpindex = debug->breakpoint_set(address);
machine().debugger().console().printf("Breakpoint %X set\n", bpindex);
}
else
@@ -192,7 +195,7 @@ bool disasmbasewin_info::handle_command(WPARAM wparam, LPARAM lparam)
command = string_format("bpset 0x%X", address);
else
command = string_format("bpclear 0x%X", bp->index());
- machine().debugger().console().execute_command(command.c_str(), true);
+ machine().debugger().console().execute_command(command, true);
}
}
return true;
@@ -204,7 +207,7 @@ bool disasmbasewin_info::handle_command(WPARAM wparam, LPARAM lparam)
device_debug *const debug = dasmview->source_device()->debug();
// first find an existing breakpoint at this address
- const device_debug::breakpoint *bp = debug->breakpoint_find(address);
+ const debug_breakpoint *bp = debug->breakpoint_find(address);
// if it doesn't exist, add a new one
if (bp != nullptr)
@@ -220,7 +223,7 @@ bool disasmbasewin_info::handle_command(WPARAM wparam, LPARAM lparam)
{
std::string command;
command = string_format(bp->enabled() ? "bpdisable 0x%X" : "bpenable 0x%X", (uint32_t)bp->index());
- machine().debugger().console().execute_command(command.c_str(), true);
+ machine().debugger().console().execute_command(command, true);
}
}
}
@@ -234,7 +237,7 @@ bool disasmbasewin_info::handle_command(WPARAM wparam, LPARAM lparam)
{
std::string command;
command = string_format("go 0x%X", address);
- machine().debugger().console().execute_command(command.c_str(), true);
+ machine().debugger().console().execute_command(command, true);
}
else
{
@@ -262,3 +265,19 @@ bool disasmbasewin_info::handle_command(WPARAM wparam, LPARAM lparam)
}
return editwin_info::handle_command(wparam, lparam);
}
+
+
+void disasmbasewin_info::restore_configuration_from_node(util::xml::data_node const &node)
+{
+ editwin_info::restore_configuration_from_node(node);
+ m_views[0]->restore_configuration_from_node(node);
+}
+
+
+void disasmbasewin_info::save_configuration_to_node(util::xml::data_node &node)
+{
+ editwin_info::save_configuration_to_node(node);
+ m_views[0]->save_configuration_to_node(node);
+}
+
+} // namespace osd::debugger::win
diff --git a/src/osd/modules/debugger/win/disasmbasewininfo.h b/src/osd/modules/debugger/win/disasmbasewininfo.h
index 26cd481b7f6..1ef8245b5a0 100644
--- a/src/osd/modules/debugger/win/disasmbasewininfo.h
+++ b/src/osd/modules/debugger/win/disasmbasewininfo.h
@@ -5,15 +5,18 @@
// disasmbasewininfo.h - Win32 debug window handling
//
//============================================================
+#ifndef MAME_DEBUGGER_WIN_DISASMBASEWININFO_H
+#define MAME_DEBUGGER_WIN_DISASMBASEWININFO_H
-#ifndef __DEBUG_WIN_DISASM_BASE_WIN_INFO_H__
-#define __DEBUG_WIN_DISASM_BASE_WIN_INFO_H__
+#pragma once
#include "debugwin.h"
#include "editwininfo.h"
+namespace osd::debugger::win {
+
class disasmbasewin_info : public editwin_info
{
public:
@@ -21,10 +24,14 @@ public:
virtual ~disasmbasewin_info();
virtual bool handle_key(WPARAM wparam, LPARAM lparam) override;
+ virtual void restore_configuration_from_node(util::xml::data_node const &node) override;
protected:
virtual void update_menu() override;
virtual bool handle_command(WPARAM wparam, LPARAM lparam) override;
+ virtual void save_configuration_to_node(util::xml::data_node &node) override;
};
-#endif
+} // namespace osd::debugger::win
+
+#endif // MAME_DEBUGGER_WIN_DISASMBASEWININFO_H
diff --git a/src/osd/modules/debugger/win/disasmviewinfo.cpp b/src/osd/modules/debugger/win/disasmviewinfo.cpp
index 8884bee5195..3cf9dbd70ff 100644
--- a/src/osd/modules/debugger/win/disasmviewinfo.cpp
+++ b/src/osd/modules/debugger/win/disasmviewinfo.cpp
@@ -2,13 +2,17 @@
// copyright-holders:Aaron Giles, Vas Crabb
//============================================================
//
-// disasmviewinfo.c - Win32 debug window handling
+// disasmviewinfo.cpp - Win32 debug window handling
//
//============================================================
#include "emu.h"
#include "disasmviewinfo.h"
+#include "util/xmlfile.h"
+
+
+namespace osd::debugger::win {
disasmview_info::disasmview_info(debugger_windows_interface &debugger, debugwin_info &owner, HWND parent) :
debugview_info(debugger, owner, parent, DVT_DISASSEMBLY)
@@ -21,6 +25,12 @@ disasmview_info::~disasmview_info()
}
+char const *disasmview_info::expression() const
+{
+ return view<debug_view_disasm>()->expression();
+}
+
+
disasm_right_column disasmview_info::right_column() const
{
return view<debug_view_disasm>()->right_column();
@@ -43,3 +53,23 @@ void disasmview_info::set_right_column(disasm_right_column contents)
{
view<debug_view_disasm>()->set_right_column(contents);
}
+
+
+void disasmview_info::restore_configuration_from_node(util::xml::data_node const &node)
+{
+ debug_view_disasm &dasmview(*view<debug_view_disasm>());
+ dasmview.set_right_column(disasm_right_column(node.get_attribute_int(ATTR_WINDOW_DISASSEMBLY_RIGHT_COLUMN, dasmview.right_column())));
+
+ debugview_info::restore_configuration_from_node(node);
+}
+
+
+void disasmview_info::save_configuration_to_node(util::xml::data_node &node)
+{
+ debugview_info::save_configuration_to_node(node);
+
+ debug_view_disasm &dasmview(*view<debug_view_disasm>());
+ node.set_attribute_int(ATTR_WINDOW_DISASSEMBLY_RIGHT_COLUMN, dasmview.right_column());
+}
+
+} // namespace osd::debugger::win
diff --git a/src/osd/modules/debugger/win/disasmviewinfo.h b/src/osd/modules/debugger/win/disasmviewinfo.h
index d1e7090ef2f..809f92b0c14 100644
--- a/src/osd/modules/debugger/win/disasmviewinfo.h
+++ b/src/osd/modules/debugger/win/disasmviewinfo.h
@@ -5,9 +5,10 @@
// disasmviewinfo.h - Win32 debug window handling
//
//============================================================
+#ifndef MAME_DEBUGGER_WIN_DISASMVIEWINFO_H
+#define MAME_DEBUGGER_WIN_DISASMVIEWINFO_H
-#ifndef __DEBUG_WIN_DISASM_VIEW_INFO_H__
-#define __DEBUG_WIN_DISASM_VIEW_INFO_H__
+#pragma once
#include "debugwin.h"
@@ -16,17 +17,25 @@
#include "debug/dvdisasm.h"
+namespace osd::debugger::win {
+
class disasmview_info : public debugview_info
{
public:
disasmview_info(debugger_windows_interface &debugger, debugwin_info &owner, HWND parent);
virtual ~disasmview_info();
+ char const *expression() const;
disasm_right_column right_column() const;
offs_t selected_address() const;
void set_expression(const std::string &expression);
void set_right_column(disasm_right_column contents);
+
+ virtual void restore_configuration_from_node(util::xml::data_node const &node) override;
+ virtual void save_configuration_to_node(util::xml::data_node &node) override;
};
-#endif
+} // namespace osd::debugger::win
+
+#endif // MAME_DEBUGGER_WIN_DISASMVIEWINFO_H
diff --git a/src/osd/modules/debugger/win/disasmwininfo.cpp b/src/osd/modules/debugger/win/disasmwininfo.cpp
index b94eadbba03..6b38609ace8 100644
--- a/src/osd/modules/debugger/win/disasmwininfo.cpp
+++ b/src/osd/modules/debugger/win/disasmwininfo.cpp
@@ -2,7 +2,7 @@
// copyright-holders:Aaron Giles, Vas Crabb
//============================================================
//
-// disasmwininfo.c - Win32 debug window handling
+// disasmwininfo.cpp - Win32 debug window handling
//
//============================================================
@@ -12,9 +12,14 @@
#include "debugviewinfo.h"
#include "disasmviewinfo.h"
#include "uimetrics.h"
+
+#include "util/xmlfile.h"
+
#include "winutf8.h"
+namespace osd::debugger::win {
+
disasmwin_info::disasmwin_info(debugger_windows_interface &debugger) :
disasmbasewin_info(debugger, false, "Disassembly", nullptr),
m_combownd(nullptr)
@@ -34,11 +39,11 @@ disasmwin_info::disasmwin_info(debugger_windows_interface &debugger) :
update_caption();
// recompute the children once to get the maxwidth
- disasmwin_info::recompute_children();
+ recompute_children();
// position the window and recompute children again
- SetWindowPos(window(), HWND_TOP, 100, 100, maxwidth(), 200, SWP_SHOWWINDOW);
- disasmwin_info::recompute_children();
+ debugger.stagger_window(window(), maxwidth(), 200);
+ recompute_children();
// mark the edit box as the default focus and set it
editwin_info::set_default_focus();
@@ -143,3 +148,34 @@ void disasmwin_info::update_caption()
{
win_set_window_text_utf8(window(), std::string("Disassembly: ").append(m_views[0]->source_name()).c_str());
}
+
+
+void disasmwin_info::restore_configuration_from_node(util::xml::data_node const &node)
+{
+ m_views[0]->set_source_index(node.get_attribute_int(ATTR_WINDOW_DISASSEMBLY_CPU, m_views[0]->source_index()));
+ int const cursource = m_views[0]->source_index();
+ if (0 <= cursource)
+ SendMessage(m_combownd, CB_SETCURSEL, cursource, 0);
+ update_caption();
+
+ util::xml::data_node const *const expr = node.get_child(NODE_WINDOW_EXPRESSION);
+ if (expr && expr->get_value())
+ {
+ set_editwnd_text(expr->get_value());
+ process_string(expr->get_value());
+ }
+
+ disasmbasewin_info::restore_configuration_from_node(node);
+}
+
+
+void disasmwin_info::save_configuration_to_node(util::xml::data_node &node)
+{
+ disasmbasewin_info::save_configuration_to_node(node);
+
+ node.set_attribute_int(ATTR_WINDOW_TYPE, WINDOW_TYPE_DISASSEMBLY_VIEWER);
+ node.set_attribute_int(ATTR_WINDOW_DISASSEMBLY_CPU, m_views[0]->source_index());
+ node.add_child(NODE_WINDOW_EXPRESSION, downcast<disasmview_info *>(m_views[0].get())->expression());
+}
+
+} // namespace osd::debugger::win
diff --git a/src/osd/modules/debugger/win/disasmwininfo.h b/src/osd/modules/debugger/win/disasmwininfo.h
index 34e8275f2f9..e5a5ceaaa0e 100644
--- a/src/osd/modules/debugger/win/disasmwininfo.h
+++ b/src/osd/modules/debugger/win/disasmwininfo.h
@@ -5,25 +5,31 @@
// disasmwininfo.h - Win32 debug window handling
//
//============================================================
+#ifndef MAME_DEBUGGER_WIN_DISASMWININFO_H
+#define MAME_DEBUGGER_WIN_DISASMWININFO_H
-#ifndef __DEBUG_WIN_DISASM_WIN_INFO_H__
-#define __DEBUG_WIN_DISASM_WIN_INFO_H__
+#pragma once
#include "debugwin.h"
#include "disasmbasewininfo.h"
+namespace osd::debugger::win {
+
class disasmwin_info : public disasmbasewin_info
{
public:
disasmwin_info(debugger_windows_interface &debugger);
virtual ~disasmwin_info();
+ virtual void restore_configuration_from_node(util::xml::data_node const &node) override;
+
protected:
virtual void recompute_children() override;
virtual bool handle_command(WPARAM wparam, LPARAM lparam) override;
virtual void draw_contents(HDC dc) override;
+ virtual void save_configuration_to_node(util::xml::data_node &node) override;
private:
virtual void process_string(const std::string &string) override;
@@ -33,4 +39,6 @@ private:
HWND m_combownd;
};
-#endif
+} // namespace osd::debugger::win
+
+#endif // MAME_DEBUGGER_WIN_DISASMWININFO_H
diff --git a/src/osd/modules/debugger/win/editwininfo.cpp b/src/osd/modules/debugger/win/editwininfo.cpp
index af3dd1bf66e..c62d2b1f4f7 100644
--- a/src/osd/modules/debugger/win/editwininfo.cpp
+++ b/src/osd/modules/debugger/win/editwininfo.cpp
@@ -2,7 +2,7 @@
// copyright-holders:Aaron Giles, Vas Crabb
//============================================================
//
-// editwininfo.c - Win32 debug window handling
+// editwininfo.cpp - Win32 debug window handling
//
//============================================================
@@ -12,18 +12,22 @@
#include "debugviewinfo.h"
#include "uimetrics.h"
+#include "xmlfile.h"
+
#include "strconv.h"
#include "winutil.h"
+namespace osd::debugger::win {
+
namespace {
constexpr DWORD EDIT_BOX_STYLE = WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL;
constexpr DWORD EDIT_BOX_STYLE_EX = 0;
constexpr int MAX_EDIT_STRING = 256;
-constexpr int HISTORY_LENGTH = 20;
+constexpr int HISTORY_LENGTH = 100;
} // anonymous namespace
@@ -34,7 +38,7 @@ editwin_info::editwin_info(debugger_windows_interface &debugger, bool is_main_co
m_edit_defstr(),
m_original_editproc(nullptr),
m_history(),
- m_last_history(0)
+ m_last_history(-1)
{
if (window() == nullptr)
return;
@@ -105,6 +109,43 @@ void editwin_info::draw_contents(HDC dc)
}
+void editwin_info::restore_configuration_from_node(util::xml::data_node const &node)
+{
+ m_history.clear();
+ util::xml::data_node const *const hist = node.get_child(NODE_WINDOW_HISTORY);
+ if (hist)
+ {
+ util::xml::data_node const *item = hist->get_child(NODE_HISTORY_ITEM);
+ while (item)
+ {
+ if (item->get_value() && *item->get_value())
+ {
+ while (m_history.size() >= HISTORY_LENGTH)
+ m_history.pop_back();
+ m_history.emplace_front(osd::text::to_tstring(item->get_value()));
+ }
+ item = item->get_next_sibling(NODE_HISTORY_ITEM);
+ }
+ }
+ m_last_history = -1;
+
+ debugwin_info::restore_configuration_from_node(node);
+}
+
+
+void editwin_info::save_configuration_to_node(util::xml::data_node &node)
+{
+ debugwin_info::save_configuration_to_node(node);
+
+ util::xml::data_node *const hist = node.add_child(NODE_WINDOW_HISTORY, nullptr);
+ if (hist)
+ {
+ for (auto it = m_history.crbegin(); m_history.crend() != it; ++it)
+ hist->add_child(NODE_HISTORY_ITEM, osd::text::from_tstring(*it).c_str());
+ }
+}
+
+
LRESULT editwin_info::edit_proc(UINT message, WPARAM wparam, LPARAM lparam)
{
// handle a few messages
@@ -114,7 +155,7 @@ LRESULT editwin_info::edit_proc(UINT message, WPARAM wparam, LPARAM lparam)
case WM_SYSKEYDOWN:
if (wparam != VK_F10)
return CallWindowProc(m_original_editproc, m_editwnd, message, wparam, lparam);
- // (fall through)
+ [[fallthrough]];
case WM_KEYDOWN:
switch (wparam)
{
@@ -185,7 +226,7 @@ LRESULT editwin_info::edit_proc(UINT message, WPARAM wparam, LPARAM lparam)
case 13: // carriage return
{
// fetch the text
- SendMessage(m_editwnd, WM_GETTEXT, WPARAM(ARRAY_LENGTH(buffer)), LPARAM(buffer));
+ SendMessage(m_editwnd, WM_GETTEXT, WPARAM(std::size(buffer)), LPARAM(buffer));
// add to the history if it's not a repeat of the last one
if (buffer[0] && (m_history.empty() || _tcscmp(buffer, m_history[0].c_str())))
@@ -194,12 +235,12 @@ LRESULT editwin_info::edit_proc(UINT message, WPARAM wparam, LPARAM lparam)
m_history.pop_back();
m_history.emplace_front(buffer);
}
- m_last_history = m_history.size() - 1;
+ m_last_history = -1;
// process
{
auto utf8_buffer = osd::text::from_tstring(buffer);
- process_string(utf8_buffer.c_str());
+ process_string(utf8_buffer);
}
}
break;
@@ -237,7 +278,9 @@ LRESULT editwin_info::edit_proc(UINT message, WPARAM wparam, LPARAM lparam)
LRESULT CALLBACK editwin_info::static_edit_proc(HWND wnd, UINT message, WPARAM wparam, LPARAM lparam)
{
- editwin_info *const info = (editwin_info *)uintptr_t(GetWindowLongPtr(wnd, GWLP_USERDATA));
+ auto *const info = (editwin_info *)uintptr_t(GetWindowLongPtr(wnd, GWLP_USERDATA));
assert(info->m_editwnd == wnd);
return info->edit_proc(message, wparam, lparam);
}
+
+} // namespace osd::debugger::win
diff --git a/src/osd/modules/debugger/win/editwininfo.h b/src/osd/modules/debugger/win/editwininfo.h
index 1aaee55f1e9..e2c0ce3c4b8 100644
--- a/src/osd/modules/debugger/win/editwininfo.h
+++ b/src/osd/modules/debugger/win/editwininfo.h
@@ -5,9 +5,10 @@
// editwininfo.h - Win32 debug window handling
//
//============================================================
+#ifndef MAME_DEBUGGER_WIN_EDITWININFO_H
+#define MAME_DEBUGGER_WIN_EDITWININFO_H
-#ifndef MAME_DEBUG_WIN_EDIT_WIN_INFO_H
-#define MAME_DEBUG_WIN_EDIT_WIN_INFO_H
+#pragma once
#include "debugwin.h"
@@ -17,6 +18,8 @@
#include <string>
+namespace osd::debugger::win {
+
class editwin_info : public debugwin_info
{
public:
@@ -27,6 +30,8 @@ public:
virtual bool set_default_focus() override;
+ virtual void restore_configuration_from_node(util::xml::data_node const &node) override;
+
protected:
constexpr static DWORD COMBO_BOX_STYLE = WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST | WS_VSCROLL;
constexpr static DWORD COMBO_BOX_STYLE_EX = 0;
@@ -38,6 +43,8 @@ protected:
virtual void draw_contents(HDC dc) override;
+ virtual void save_configuration_to_node(util::xml::data_node &node) override;
+
private:
typedef std::deque<std::basic_string<TCHAR> > history_deque;
@@ -54,4 +61,6 @@ private:
int m_last_history;
};
-#endif
+} // namespace osd::debugger::win
+
+#endif // MAME_DEBUGGER_WIN_EDITWININFO_H
diff --git a/src/osd/modules/debugger/win/logviewinfo.cpp b/src/osd/modules/debugger/win/logviewinfo.cpp
index affd4acd17a..c6bbdfacb88 100644
--- a/src/osd/modules/debugger/win/logviewinfo.cpp
+++ b/src/osd/modules/debugger/win/logviewinfo.cpp
@@ -2,7 +2,7 @@
// copyright-holders:Samuele Zannoli
//============================================================
//
-// logviewinfo.c - Win32 debug log window handling
+// logviewinfo.cpp - Win32 debug log window handling
//
//============================================================
@@ -12,6 +12,8 @@
#include "debug/dvtext.h"
+namespace osd::debugger::win {
+
logview_info::logview_info(debugger_windows_interface &debugger, debugwin_info &owner, HWND parent) :
debugview_info(debugger, owner, parent, DVT_LOG)
{
@@ -27,3 +29,5 @@ void logview_info::clear()
{
view<debug_view_log>()->clear();
}
+
+} // namespace osd::debugger::win
diff --git a/src/osd/modules/debugger/win/logviewinfo.h b/src/osd/modules/debugger/win/logviewinfo.h
index da598038864..15de2a3a095 100644
--- a/src/osd/modules/debugger/win/logviewinfo.h
+++ b/src/osd/modules/debugger/win/logviewinfo.h
@@ -5,15 +5,18 @@
// logviewinfo.h - Win32 debug log window handling
//
//============================================================
+#ifndef MAME_DEBUGGER_WIN_LOGVIEWINFO_H
+#define MAME_DEBUGGER_WIN_LOGVIEWINFO_H
-#ifndef __DEBUG_WIN_LOG_VIEW_INFO_H__
-#define __DEBUG_WIN_LOG_VIEW_INFO_H__
+#pragma once
#include "debugwin.h"
#include "debugviewinfo.h"
+namespace osd::debugger::win {
+
class logview_info : public debugview_info
{
public:
@@ -23,4 +26,6 @@ public:
void clear();
};
-#endif
+} // namespace osd::debugger::win
+
+#endif // MAME_DEBUGGER_WIN_LOGVIEWINFO_H
diff --git a/src/osd/modules/debugger/win/logwininfo.cpp b/src/osd/modules/debugger/win/logwininfo.cpp
index 6d2cd59b554..40515906bb1 100644
--- a/src/osd/modules/debugger/win/logwininfo.cpp
+++ b/src/osd/modules/debugger/win/logwininfo.cpp
@@ -2,7 +2,7 @@
// copyright-holders:Aaron Giles, Vas Crabb
//============================================================
//
-// logwininfo.c - Win32 debug window handling
+// logwininfo.cpp - Win32 debug window handling
//
//============================================================
@@ -12,6 +12,10 @@
#include "debugviewinfo.h"
#include "logviewinfo.h"
+#include "util/xmlfile.h"
+
+
+namespace osd::debugger::win {
logwin_info::logwin_info(debugger_windows_interface &debugger) :
debugwin_info(debugger, false, std::string("Errorlog: ").append(debugger.machine().system().type.fullname()).append(" [").append(debugger.machine().system().name).append("]").c_str(), nullptr)
@@ -19,7 +23,7 @@ logwin_info::logwin_info(debugger_windows_interface &debugger) :
if (!window())
return;
- m_views[0].reset(global_alloc(logview_info(debugger, *this, window())));
+ m_views[0].reset(new logview_info(debugger, *this, window()));
if ((m_views[0] == nullptr) || !m_views[0]->is_valid())
{
m_views[0].reset();
@@ -41,11 +45,9 @@ logwin_info::logwin_info(debugger_windows_interface &debugger) :
// clamp the min/max size
set_maxwidth(bounds.right - bounds.left);
- // position the window at the bottom-right
- SetWindowPos(window(), HWND_TOP, 100, 100, bounds.right - bounds.left, bounds.bottom - bounds.top, SWP_SHOWWINDOW);
-
- // recompute the children
- debugwin_info::recompute_children();
+ // position the window and recompute children
+ debugger.stagger_window(window(), bounds.right - bounds.left, bounds.bottom - bounds.top);
+ recompute_children();
}
@@ -63,3 +65,12 @@ bool logwin_info::handle_command(WPARAM wparam, LPARAM lparam)
}
return debugwin_info::handle_command(wparam, lparam);
}
+
+
+void logwin_info::save_configuration_to_node(util::xml::data_node &node)
+{
+ debugwin_info::save_configuration_to_node(node);
+ node.set_attribute_int(ATTR_WINDOW_TYPE, WINDOW_TYPE_ERROR_LOG_VIEWER);
+}
+
+} // namespace osd::debugger::win
diff --git a/src/osd/modules/debugger/win/logwininfo.h b/src/osd/modules/debugger/win/logwininfo.h
index a816b6f3da3..4e822f1b534 100644
--- a/src/osd/modules/debugger/win/logwininfo.h
+++ b/src/osd/modules/debugger/win/logwininfo.h
@@ -5,15 +5,18 @@
// logwininfo.h - Win32 debug window handling
//
//============================================================
+#ifndef MAME_DEBUGGER_WIN_LOGWININFO_H
+#define MAME_DEBUGGER_WIN_LOGWININFO_H
-#ifndef __DEBUG_WIN_LOG_WIN_INFO_H__
-#define __DEBUG_WIN_LOG_WIN_INFO_H__
+#pragma once
#include "debugwin.h"
#include "debugwininfo.h"
+namespace osd::debugger::win {
+
class logwin_info : public debugwin_info
{
public:
@@ -22,6 +25,9 @@ public:
protected:
virtual bool handle_command(WPARAM wparam, LPARAM lparam) override;
+ virtual void save_configuration_to_node(util::xml::data_node &node) override;
};
-#endif
+} // namespace osd::debugger::win
+
+#endif // MAME_DEBUGGER_WIN_LOGWININFO_H
diff --git a/src/osd/modules/debugger/win/memoryviewinfo.cpp b/src/osd/modules/debugger/win/memoryviewinfo.cpp
index 423679f26a9..90e23a557a9 100644
--- a/src/osd/modules/debugger/win/memoryviewinfo.cpp
+++ b/src/osd/modules/debugger/win/memoryviewinfo.cpp
@@ -2,15 +2,19 @@
// copyright-holders:Aaron Giles, Vas Crabb
//============================================================
//
-// memoryviewinfo.c - Win32 debug window handling
+// memoryviewinfo.cpp - Win32 debug window handling
//
//============================================================
#include "emu.h"
#include "memoryviewinfo.h"
-#include "debug/dvmemory.h"
+#include "util/xmlfile.h"
+#include "strconv.h"
+
+
+namespace osd::debugger::win {
memoryview_info::memoryview_info(debugger_windows_interface &debugger, debugwin_info &owner, HWND parent) :
debugview_info(debugger, owner, parent, DVT_MEMORY)
@@ -23,7 +27,13 @@ memoryview_info::~memoryview_info()
}
-uint8_t memoryview_info::data_format() const
+char const *memoryview_info::expression() const
+{
+ return view<debug_view_memory>()->expression();
+}
+
+
+debug_view_memory::data_format memoryview_info::data_format() const
{
return view<debug_view_memory>()->get_data_format();
}
@@ -46,13 +56,18 @@ bool memoryview_info::physical() const
return view<debug_view_memory>()->physical();
}
+int memoryview_info::address_radix() const
+{
+ return view<debug_view_memory>()->address_radix();
+}
+
void memoryview_info::set_expression(const std::string &string)
{
view<debug_view_memory>()->set_expression(string);
}
-void memoryview_info::set_data_format(uint8_t dataformat)
+void memoryview_info::set_data_format(debug_view_memory::data_format dataformat)
{
view<debug_view_memory>()->set_data_format(dataformat);
}
@@ -71,3 +86,123 @@ void memoryview_info::set_physical(bool physical)
{
view<debug_view_memory>()->set_physical(physical);
}
+
+void memoryview_info::set_address_radix(int radix)
+{
+ view<debug_view_memory>()->set_address_radix(radix);
+}
+
+
+void memoryview_info::restore_configuration_from_node(util::xml::data_node const &node)
+{
+ debug_view_memory &memview(*view<debug_view_memory>());
+ memview.set_reverse(0 != node.get_attribute_int(ATTR_WINDOW_MEMORY_REVERSE_COLUMNS, memview.reverse() ? 1 : 0));
+ memview.set_physical(0 != node.get_attribute_int(ATTR_WINDOW_MEMORY_ADDRESS_MODE, memview.physical() ? 1 : 0));
+ memview.set_address_radix(node.get_attribute_int(ATTR_WINDOW_MEMORY_ADDRESS_RADIX, memview.address_radix()));
+ memview.set_data_format(debug_view_memory::data_format(node.get_attribute_int(ATTR_WINDOW_MEMORY_DATA_FORMAT, int(memview.get_data_format()))));
+ memview.set_chunks_per_row(node.get_attribute_int(ATTR_WINDOW_MEMORY_ROW_CHUNKS, memview.chunks_per_row()));
+
+ debugview_info::restore_configuration_from_node(node);
+}
+
+
+void memoryview_info::save_configuration_to_node(util::xml::data_node &node)
+{
+ debugview_info::save_configuration_to_node(node);
+
+ debug_view_memory &memview(*view<debug_view_memory>());
+ node.set_attribute_int(ATTR_WINDOW_MEMORY_REVERSE_COLUMNS, memview.reverse() ? 1 : 0);
+ node.set_attribute_int(ATTR_WINDOW_MEMORY_ADDRESS_MODE, memview.physical() ? 1 : 0);
+ node.set_attribute_int(ATTR_WINDOW_MEMORY_ADDRESS_RADIX, memview.address_radix());
+ node.set_attribute_int(ATTR_WINDOW_MEMORY_DATA_FORMAT, int(memview.get_data_format()));
+ node.set_attribute_int(ATTR_WINDOW_MEMORY_ROW_CHUNKS, memview.chunks_per_row());
+}
+
+
+void memoryview_info::add_items_to_context_menu(HMENU menu)
+{
+ debugview_info::add_items_to_context_menu(menu);
+
+ AppendMenu(menu, MF_DISABLED | MF_SEPARATOR, 0, TEXT(""));
+ AppendMenu(menu, MF_GRAYED, ID_CONTEXT_LAST_PC, TEXT("Last PC"));
+}
+
+void memoryview_info::update_context_menu(HMENU menu)
+{
+ debugview_info::update_context_menu(menu);
+
+ bool enable = false;
+ debug_view_memory &memview(*view<debug_view_memory>());
+ debug_view_memory_source const &source = downcast<debug_view_memory_source const &>(*memview.source());
+ address_space *const space = source.space();
+ if (space)
+ {
+ if (memview.cursor_visible())
+ {
+ // get the last known PC to write to this memory location
+ debug_view_xy const pos = memview.cursor_position();
+ offs_t const address = space->byte_to_address(memview.addressAtCursorPosition(pos));
+ offs_t a = address & space->logaddrmask();
+ address_space *tspace;
+ if (!space->device().memory().translate(space->spacenum(), device_memory_interface::TR_READ, a, tspace))
+ {
+ m_lastpc = "Bad address";
+ }
+ else
+ {
+ uint64_t memval = tspace->unmap();
+ auto dis = tspace->device().machine().disable_side_effects();
+ switch (tspace->data_width())
+ {
+ case 8: memval = tspace->read_byte(a); break;
+ case 16: memval = tspace->read_word_unaligned(a); break;
+ case 32: memval = tspace->read_dword_unaligned(a); break;
+ case 64: memval = tspace->read_qword_unaligned(a); break;
+ }
+
+ offs_t const pc = source.device()->debug()->track_mem_pc_from_space_address_data(
+ tspace->spacenum(),
+ address,
+ memval);
+ if (pc != offs_t(-1))
+ {
+ if (tspace->is_octal())
+ m_lastpc = util::string_format("Address %o written at PC=%o", address, pc);
+ else
+ m_lastpc = util::string_format("Address %x written at PC=%x", address, pc);
+ enable = true;
+ }
+ else
+ {
+ m_lastpc = "Unknown PC";
+ }
+ }
+ }
+ else
+ {
+ m_lastpc = "No address";
+ }
+ }
+ else
+ {
+ m_lastpc = "Not an address space";
+ }
+ ModifyMenuW(menu, ID_CONTEXT_LAST_PC, MF_BYCOMMAND, ID_CONTEXT_LAST_PC, osd::text::to_wstring(m_lastpc).c_str());
+ EnableMenuItem(menu, ID_CONTEXT_LAST_PC, MF_BYCOMMAND | (enable ? MF_ENABLED : MF_GRAYED));
+}
+
+void memoryview_info::handle_context_menu(unsigned command)
+{
+ switch (command)
+ {
+ case ID_CONTEXT_LAST_PC:
+ // TODO: copy to clipboard
+ return;
+
+ default:
+ debugview_info::handle_context_menu(command);
+ };
+
+}
+
+} // namespace osd::debugger::win
diff --git a/src/osd/modules/debugger/win/memoryviewinfo.h b/src/osd/modules/debugger/win/memoryviewinfo.h
index 2ab810654f3..514c6c13ec6 100644
--- a/src/osd/modules/debugger/win/memoryviewinfo.h
+++ b/src/osd/modules/debugger/win/memoryviewinfo.h
@@ -5,14 +5,20 @@
// memoryviewinfo.h - Win32 debug window handling
//
//============================================================
+#ifndef MAME_DEBUGGER_WIN_MEMORYVIEWINFO_H
+#define MAME_DEBUGGER_WIN_MEMORYVIEWINFO_H
-#ifndef __DEBUG_WIN_MEMORY_VIEW_INFO_H__
-#define __DEBUG_WIN_MEMORY_VIEW_INFO_H__
+#pragma once
#include "debugwin.h"
-
#include "debugviewinfo.h"
+#include "debug/dvmemory.h"
+
+#include <string>
+
+
+namespace osd::debugger::win {
class memoryview_info : public debugview_info
{
@@ -20,16 +26,37 @@ public:
memoryview_info(debugger_windows_interface &debugger, debugwin_info &owner, HWND parent);
virtual ~memoryview_info();
- uint8_t data_format() const;
+ char const *expression() const;
+ debug_view_memory::data_format data_format() const;
uint32_t chunks_per_row() const;
bool reverse() const;
bool physical() const;
+ int address_radix() const;
void set_expression(const std::string &string);
- void set_data_format(uint8_t dataformat);
+ void set_data_format(debug_view_memory::data_format dataformat);
void set_chunks_per_row(uint32_t rowchunks);
void set_reverse(bool reverse);
void set_physical(bool physical);
+ void set_address_radix(int radix);
+
+ virtual void restore_configuration_from_node(util::xml::data_node const &node) override;
+ virtual void save_configuration_to_node(util::xml::data_node &node) override;
+
+protected:
+ enum
+ {
+ ID_CONTEXT_LAST_PC = 101
+ };
+
+ virtual void add_items_to_context_menu(HMENU menu) override;
+ virtual void update_context_menu(HMENU menu) override;
+ virtual void handle_context_menu(unsigned command) override;
+
+private:
+ std::string m_lastpc;
};
-#endif
+} // namespace osd::debugger::win
+
+#endif // MAME_DEBUGGER_WIN_MEMORYVIEWINFO_H
diff --git a/src/osd/modules/debugger/win/memorywininfo.cpp b/src/osd/modules/debugger/win/memorywininfo.cpp
index 6f461295ec2..92078854e2e 100644
--- a/src/osd/modules/debugger/win/memorywininfo.cpp
+++ b/src/osd/modules/debugger/win/memorywininfo.cpp
@@ -2,7 +2,7 @@
// copyright-holders:Aaron Giles, Vas Crabb
//============================================================
//
-// memorywininfo.c - Win32 debug window handling
+// memorywininfo.cpp - Win32 debug window handling
//
//============================================================
@@ -13,9 +13,13 @@
#include "memoryviewinfo.h"
#include "uimetrics.h"
+#include "util/xmlfile.h"
+
#include "winutf8.h"
+namespace osd::debugger::win {
+
memorywin_info::memorywin_info(debugger_windows_interface &debugger) :
editwin_info(debugger, false, "Memory", nullptr),
m_combownd(nullptr)
@@ -23,7 +27,7 @@ memorywin_info::memorywin_info(debugger_windows_interface &debugger) :
if (!window())
return;
- m_views[0].reset(global_alloc(memoryview_info(debugger, *this, window())));
+ m_views[0].reset(new memoryview_info(debugger, *this, window()));
if ((m_views[0] == nullptr) || !m_views[0]->is_valid())
{
m_views[0].reset();
@@ -32,21 +36,29 @@ memorywin_info::memorywin_info(debugger_windows_interface &debugger) :
// 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_ENABLED, ID_1_BYTE_CHUNKS_HEX, TEXT("1-byte Chunks (Hex)\tCtrl+1"));
+ AppendMenu(optionsmenu, MF_ENABLED, ID_2_BYTE_CHUNKS_HEX, TEXT("2-byte Chunks (Hex)\tCtrl+2"));
+ AppendMenu(optionsmenu, MF_ENABLED, ID_4_BYTE_CHUNKS_HEX, TEXT("4-byte Chunks (Hex)\tCtrl+4"));
+ AppendMenu(optionsmenu, MF_ENABLED, ID_8_BYTE_CHUNKS_HEX, TEXT("8-byte Chunks (Hex)\tCtrl+8"));
+ AppendMenu(optionsmenu, MF_ENABLED, ID_1_BYTE_CHUNKS_OCT, TEXT("1-byte Chunks (Octal)\tCtrl+3"));
+ AppendMenu(optionsmenu, MF_ENABLED, ID_2_BYTE_CHUNKS_OCT, TEXT("2-byte Chunks (Octal)\tCtrl+5"));
+ AppendMenu(optionsmenu, MF_ENABLED, ID_4_BYTE_CHUNKS_OCT, TEXT("4-byte Chunks (Octal)\tCtrl+7"));
+ AppendMenu(optionsmenu, MF_ENABLED, ID_8_BYTE_CHUNKS_OCT, TEXT("8-byte Chunks (Octal)\tCtrl+9"));
+ AppendMenu(optionsmenu, MF_ENABLED, ID_FLOAT_32BIT, TEXT("32-bit Floating Point\tCtrl+Shift+F"));
+ AppendMenu(optionsmenu, MF_ENABLED, ID_FLOAT_64BIT, TEXT("64-bit Floating Point\tCtrl+Shift+D"));
+ AppendMenu(optionsmenu, MF_ENABLED, ID_FLOAT_80BIT, TEXT("80-bit Floating Point\tCtrl+Shift+E"));
+ AppendMenu(optionsmenu, MF_DISABLED | MF_SEPARATOR, 0, TEXT(""));
+ AppendMenu(optionsmenu, MF_ENABLED, ID_HEX_ADDRESSES, TEXT("Hexadecimal Addresses\tCtrl+Shift+H"));
+ AppendMenu(optionsmenu, MF_ENABLED, ID_DEC_ADDRESSES, TEXT("Decimal Addresses"));
+ AppendMenu(optionsmenu, MF_ENABLED, ID_OCT_ADDRESSES, TEXT("Octal Addresses\tCtrl+Shift+O"));
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(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
@@ -63,11 +75,11 @@ memorywin_info::memorywin_info(debugger_windows_interface &debugger) :
update_caption();
// recompute the children once to get the maxwidth
- memorywin_info::recompute_children();
+ recompute_children();
// position the window and recompute children again
- SetWindowPos(window(), HWND_TOP, 100, 100, maxwidth(), 200, SWP_SHOWWINDOW);
- memorywin_info::recompute_children();
+ debugger.stagger_window(window(), maxwidth(), 200);
+ recompute_children();
// mark the edit box as the default focus and set it
editwin_info::set_default_focus();
@@ -83,47 +95,87 @@ bool memorywin_info::handle_key(WPARAM wparam, LPARAM lparam)
{
if (GetAsyncKeyState(VK_CONTROL) & 0x8000)
{
- switch (wparam)
+ if (GetAsyncKeyState(VK_SHIFT))
{
- case '1':
- SendMessage(window(), WM_COMMAND, ID_1_BYTE_CHUNKS, 0);
- return true;
+ switch (wparam)
+ {
+ case 'F':
+ SendMessage(window(), WM_COMMAND, ID_FLOAT_32BIT, 0);
+ return true;
- case '2':
- SendMessage(window(), WM_COMMAND, ID_2_BYTE_CHUNKS, 0);
- return true;
+ case 'D':
+ SendMessage(window(), WM_COMMAND, ID_FLOAT_64BIT, 0);
+ return true;
- case '4':
- SendMessage(window(), WM_COMMAND, ID_4_BYTE_CHUNKS, 0);
- return true;
+ case 'E':
+ SendMessage(window(), WM_COMMAND, ID_FLOAT_80BIT, 0);
+ return true;
- case '8':
- SendMessage(window(), WM_COMMAND, ID_8_BYTE_CHUNKS, 0);
- return true;
+ case 'H':
+ SendMessage(window(), WM_COMMAND, ID_HEX_ADDRESSES, 0);
+ return true;
- case '9':
- SendMessage(window(), WM_COMMAND, ID_FLOATING_POINT_32BIT, 0);
- return true;
+ case 'O':
+ SendMessage(window(), WM_COMMAND, ID_OCT_ADDRESSES, 0);
+ return true;
+ }
+ }
+ else
+ {
+ switch (wparam)
+ {
+ case '1':
+ SendMessage(window(), WM_COMMAND, ID_1_BYTE_CHUNKS_HEX, 0);
+ return true;
- case 'L':
- SendMessage(window(), WM_COMMAND, ID_LOGICAL_ADDRESSES, 0);
- return true;
+ case '2':
+ SendMessage(window(), WM_COMMAND, ID_2_BYTE_CHUNKS_HEX, 0);
+ return true;
- case 'Y':
- SendMessage(window(), WM_COMMAND, ID_PHYSICAL_ADDRESSES, 0);
- return true;
+ case '4':
+ SendMessage(window(), WM_COMMAND, ID_4_BYTE_CHUNKS_HEX, 0);
+ return true;
- case 'R':
- SendMessage(window(), WM_COMMAND, ID_REVERSE_VIEW, 0);
- return true;
+ case '8':
+ SendMessage(window(), WM_COMMAND, ID_8_BYTE_CHUNKS_HEX, 0);
+ return true;
- case 'P':
- SendMessage(window(), WM_COMMAND, ID_INCREASE_MEM_WIDTH, 0);
- return true;
+ case '3':
+ SendMessage(window(), WM_COMMAND, ID_1_BYTE_CHUNKS_OCT, 0);
+ return true;
- case 'O':
- SendMessage(window(), WM_COMMAND, ID_DECREASE_MEM_WIDTH, 0);
- return true;
+ case '5':
+ SendMessage(window(), WM_COMMAND, ID_2_BYTE_CHUNKS_OCT, 0);
+ return true;
+
+ case '7':
+ SendMessage(window(), WM_COMMAND, ID_4_BYTE_CHUNKS_OCT, 0);
+ return true;
+
+ case '9':
+ SendMessage(window(), WM_COMMAND, ID_8_BYTE_CHUNKS_OCT, 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);
@@ -178,25 +230,37 @@ void memorywin_info::update_menu()
{
editwin_info::update_menu();
- memoryview_info *const memview = downcast<memoryview_info *>(m_views[0].get());
+ 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() == 1 ? MF_CHECKED : MF_UNCHECKED));
- CheckMenuItem(menu, ID_2_BYTE_CHUNKS, MF_BYCOMMAND | (memview->data_format() == 2 ? MF_CHECKED : MF_UNCHECKED));
- CheckMenuItem(menu, ID_4_BYTE_CHUNKS, MF_BYCOMMAND | (memview->data_format() == 4 ? MF_CHECKED : MF_UNCHECKED));
- CheckMenuItem(menu, ID_8_BYTE_CHUNKS, MF_BYCOMMAND | (memview->data_format() == 8 ? MF_CHECKED : MF_UNCHECKED));
- CheckMenuItem(menu, ID_FLOATING_POINT_32BIT, MF_BYCOMMAND | (memview->data_format() == 9 ? MF_CHECKED : MF_UNCHECKED));
- CheckMenuItem(menu, ID_FLOATING_POINT_64BIT, MF_BYCOMMAND | (memview->data_format() == 10 ? MF_CHECKED : MF_UNCHECKED));
- CheckMenuItem(menu, ID_FLOATING_POINT_80BIT, MF_BYCOMMAND | (memview->data_format() == 11 ? MF_CHECKED : MF_UNCHECKED));
+
+ CheckMenuItem(menu, ID_1_BYTE_CHUNKS_HEX, MF_BYCOMMAND | ((memview->data_format() == debug_view_memory::data_format::HEX_8BIT) ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(menu, ID_2_BYTE_CHUNKS_HEX, MF_BYCOMMAND | ((memview->data_format() == debug_view_memory::data_format::HEX_16BIT) ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(menu, ID_4_BYTE_CHUNKS_HEX, MF_BYCOMMAND | ((memview->data_format() == debug_view_memory::data_format::HEX_32BIT) ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(menu, ID_8_BYTE_CHUNKS_HEX, MF_BYCOMMAND | ((memview->data_format() == debug_view_memory::data_format::HEX_64BIT) ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(menu, ID_1_BYTE_CHUNKS_OCT, MF_BYCOMMAND | ((memview->data_format() == debug_view_memory::data_format::OCTAL_8BIT) ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(menu, ID_2_BYTE_CHUNKS_OCT, MF_BYCOMMAND | ((memview->data_format() == debug_view_memory::data_format::OCTAL_16BIT) ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(menu, ID_4_BYTE_CHUNKS_OCT, MF_BYCOMMAND | ((memview->data_format() == debug_view_memory::data_format::OCTAL_32BIT) ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(menu, ID_8_BYTE_CHUNKS_OCT, MF_BYCOMMAND | ((memview->data_format() == debug_view_memory::data_format::OCTAL_64BIT) ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(menu, ID_FLOAT_32BIT, MF_BYCOMMAND | ((memview->data_format() == debug_view_memory::data_format::FLOAT_32BIT) ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(menu, ID_FLOAT_64BIT, MF_BYCOMMAND | ((memview->data_format() == debug_view_memory::data_format::FLOAT_64BIT) ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(menu, ID_FLOAT_80BIT, MF_BYCOMMAND | ((memview->data_format() == debug_view_memory::data_format::FLOAT_80BIT) ? MF_CHECKED : MF_UNCHECKED));
+
+ CheckMenuItem(menu, ID_HEX_ADDRESSES, MF_BYCOMMAND | ((memview->address_radix() == 16) ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(menu, ID_DEC_ADDRESSES, MF_BYCOMMAND | ((memview->address_radix() == 10) ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(menu, ID_OCT_ADDRESSES, MF_BYCOMMAND | ((memview->address_radix() == 8) ? 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)
{
- memoryview_info *const memview = downcast<memoryview_info *>(m_views[0].get());
+ auto *const memview = downcast<memoryview_info *>(m_views[0].get());
switch (HIWORD(wparam))
{
// combo box selection changed
@@ -219,32 +283,60 @@ bool memorywin_info::handle_command(WPARAM wparam, LPARAM lparam)
case 0:
switch (LOWORD(wparam))
{
- case ID_1_BYTE_CHUNKS:
- memview->set_data_format(1);
+ case ID_1_BYTE_CHUNKS_HEX:
+ memview->set_data_format(debug_view_memory::data_format::HEX_8BIT);
+ return true;
+
+ case ID_2_BYTE_CHUNKS_HEX:
+ memview->set_data_format(debug_view_memory::data_format::HEX_16BIT);
+ return true;
+
+ case ID_4_BYTE_CHUNKS_HEX:
+ memview->set_data_format(debug_view_memory::data_format::HEX_32BIT);
+ return true;
+
+ case ID_8_BYTE_CHUNKS_HEX:
+ memview->set_data_format(debug_view_memory::data_format::HEX_64BIT);
return true;
- case ID_2_BYTE_CHUNKS:
- memview->set_data_format(2);
+ case ID_1_BYTE_CHUNKS_OCT:
+ memview->set_data_format(debug_view_memory::data_format::OCTAL_8BIT);
return true;
- case ID_4_BYTE_CHUNKS:
- memview->set_data_format(4);
+ case ID_2_BYTE_CHUNKS_OCT:
+ memview->set_data_format(debug_view_memory::data_format::OCTAL_16BIT);
return true;
- case ID_8_BYTE_CHUNKS:
- memview->set_data_format(8);
+ case ID_4_BYTE_CHUNKS_OCT:
+ memview->set_data_format(debug_view_memory::data_format::OCTAL_32BIT);
return true;
- case ID_FLOATING_POINT_32BIT:
- memview->set_data_format(9);
+ case ID_8_BYTE_CHUNKS_OCT:
+ memview->set_data_format(debug_view_memory::data_format::OCTAL_64BIT);
return true;
- case ID_FLOATING_POINT_64BIT:
- memview->set_data_format(10);
+ case ID_FLOAT_32BIT:
+ memview->set_data_format(debug_view_memory::data_format::FLOAT_32BIT);
return true;
- case ID_FLOATING_POINT_80BIT:
- memview->set_data_format(11);
+ case ID_FLOAT_64BIT:
+ memview->set_data_format(debug_view_memory::data_format::FLOAT_64BIT);
+ return true;
+
+ case ID_FLOAT_80BIT:
+ memview->set_data_format(debug_view_memory::data_format::FLOAT_80BIT);
+ return true;
+
+ case ID_HEX_ADDRESSES:
+ memview->set_address_radix(16);
+ return true;
+
+ case ID_DEC_ADDRESSES:
+ memview->set_address_radix(10);
+ return true;
+
+ case ID_OCT_ADDRESSES:
+ memview->set_address_radix(8);
return true;
case ID_LOGICAL_ADDRESSES:
@@ -300,3 +392,37 @@ void memorywin_info::update_caption()
{
win_set_window_text_utf8(window(), std::string("Memory: ").append(m_views[0]->source_name()).c_str());
}
+
+
+void memorywin_info::restore_configuration_from_node(util::xml::data_node const &node)
+{
+ m_views[0]->set_source_index(node.get_attribute_int(ATTR_WINDOW_MEMORY_REGION, m_views[0]->source_index()));
+ int const cursource = m_views[0]->source_index();
+ if (0 <= cursource)
+ SendMessage(m_combownd, CB_SETCURSEL, cursource, 0);
+ update_caption();
+
+ util::xml::data_node const *const expr = node.get_child(NODE_WINDOW_EXPRESSION);
+ if (expr && expr->get_value())
+ {
+ set_editwnd_text(expr->get_value());
+ process_string(expr->get_value());
+ }
+
+ editwin_info::restore_configuration_from_node(node);
+
+ m_views[0]->restore_configuration_from_node(node);
+}
+
+
+void memorywin_info::save_configuration_to_node(util::xml::data_node &node)
+{
+ editwin_info::save_configuration_to_node(node);
+
+ node.set_attribute_int(ATTR_WINDOW_TYPE, WINDOW_TYPE_MEMORY_VIEWER);
+ node.set_attribute_int(ATTR_WINDOW_MEMORY_REGION, m_views[0]->source_index());
+ node.add_child(NODE_WINDOW_EXPRESSION, downcast<memoryview_info *>(m_views[0].get())->expression());
+ m_views[0]->save_configuration_to_node(node);
+}
+
+} // namespace osd::debugger::win
diff --git a/src/osd/modules/debugger/win/memorywininfo.h b/src/osd/modules/debugger/win/memorywininfo.h
index 501d7acc76f..a0a4072be0f 100644
--- a/src/osd/modules/debugger/win/memorywininfo.h
+++ b/src/osd/modules/debugger/win/memorywininfo.h
@@ -5,15 +5,18 @@
// memorywininfo.h - Win32 debug window handling
//
//============================================================
+#ifndef MAME_DEBUGGER_WIN_MEMORYWININFO_H
+#define MAME_DEBUGGER_WIN_MEMORYWININFO_H
-#ifndef __DEBUG_WIN_MEMORY_WIN_INFO_H__
-#define __DEBUG_WIN_MEMORY_WIN_INFO_H__
+#pragma once
#include "debugwin.h"
#include "editwininfo.h"
+namespace osd::debugger::win {
+
class memorywin_info : public editwin_info
{
public:
@@ -21,12 +24,14 @@ public:
virtual ~memorywin_info();
virtual bool handle_key(WPARAM wparam, LPARAM lparam) override;
+ virtual void restore_configuration_from_node(util::xml::data_node const &node) override;
protected:
virtual void recompute_children() override;
virtual void update_menu() override;
virtual bool handle_command(WPARAM wparam, LPARAM lparam) override;
virtual void draw_contents(HDC dc) override;
+ virtual void save_configuration_to_node(util::xml::data_node &node) override;
private:
virtual void process_string(const std::string &string) override;
@@ -36,4 +41,6 @@ private:
HWND m_combownd;
};
-#endif
+} // namespace osd::debugger::win
+
+#endif // MAME_DEBUGGER_WIN_MEMORYWININFO_H
diff --git a/src/osd/modules/debugger/win/pointswininfo.cpp b/src/osd/modules/debugger/win/pointswininfo.cpp
index 24a8f865e6f..70ec6606280 100644
--- a/src/osd/modules/debugger/win/pointswininfo.cpp
+++ b/src/osd/modules/debugger/win/pointswininfo.cpp
@@ -2,7 +2,7 @@
// copyright-holders:Aaron Giles, Vas Crabb
//============================================================
//
-// pointswininfo.c - Win32 debug window handling
+// pointswininfo.cpp - Win32 debug window handling
//
//============================================================
@@ -11,16 +11,20 @@
#include "debugviewinfo.h"
+#include "util/xmlfile.h"
+
#include "winutf8.h"
+namespace osd::debugger::win {
+
pointswin_info::pointswin_info(debugger_windows_interface &debugger) :
debugwin_info(debugger, false, std::string("All Breakpoints").c_str(), nullptr)
{
if (!window())
return;
- m_views[0].reset(global_alloc(debugview_info(debugger, *this, window(), DVT_BREAK_POINTS)));
+ m_views[0].reset(new debugview_info(debugger, *this, window(), DVT_BREAK_POINTS));
if ((m_views[0] == nullptr) || !m_views[0]->is_valid())
{
m_views[0].reset();
@@ -31,6 +35,8 @@ pointswin_info::pointswin_info(debugger_windows_interface &debugger) :
HMENU const optionsmenu = CreatePopupMenu();
AppendMenu(optionsmenu, MF_ENABLED, ID_SHOW_BREAKPOINTS, TEXT("Breakpoints\tCtrl+1"));
AppendMenu(optionsmenu, MF_ENABLED, ID_SHOW_WATCHPOINTS, TEXT("Watchpoints\tCtrl+2"));
+ AppendMenu(optionsmenu, MF_ENABLED, ID_SHOW_REGISTERPOINTS, TEXT("Registerpoints\tCtrl+3"));
+ AppendMenu(optionsmenu, MF_ENABLED, ID_SHOW_EXCEPTIONPOINTS, TEXT("Exceptionpoints\tCtrl+4"));
AppendMenu(GetMenu(window()), MF_ENABLED | MF_POPUP, (UINT_PTR)optionsmenu, TEXT("Options"));
// compute a client rect
@@ -43,11 +49,9 @@ pointswin_info::pointswin_info(debugger_windows_interface &debugger) :
// clamp the min/max size
set_maxwidth(bounds.right - bounds.left);
- // position the window at the bottom-right
- SetWindowPos(window(), HWND_TOP, 100, 100, bounds.right - bounds.left, bounds.bottom - bounds.top, SWP_SHOWWINDOW);
-
- // recompute the children
- debugwin_info::recompute_children();
+ // position the window and recompute children
+ debugger.stagger_window(window(), bounds.right - bounds.left, bounds.bottom - bounds.top);
+ recompute_children();
}
@@ -69,6 +73,14 @@ bool pointswin_info::handle_key(WPARAM wparam, LPARAM lparam)
case '2':
SendMessage(window(), WM_COMMAND, ID_SHOW_WATCHPOINTS, 0);
return true;
+
+ case '3':
+ SendMessage(window(), WM_COMMAND, ID_SHOW_REGISTERPOINTS, 0);
+ return true;
+
+ case '4':
+ SendMessage(window(), WM_COMMAND, ID_SHOW_EXCEPTIONPOINTS, 0);
+ return true;
}
}
@@ -83,6 +95,8 @@ void pointswin_info::update_menu()
HMENU const menu = GetMenu(window());
CheckMenuItem(menu, ID_SHOW_BREAKPOINTS, MF_BYCOMMAND | (m_views[0]->type() == DVT_BREAK_POINTS ? MF_CHECKED : MF_UNCHECKED));
CheckMenuItem(menu, ID_SHOW_WATCHPOINTS, MF_BYCOMMAND | (m_views[0]->type() == DVT_WATCH_POINTS ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(menu, ID_SHOW_REGISTERPOINTS, MF_BYCOMMAND | (m_views[0]->type() == DVT_REGISTER_POINTS ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(menu, ID_SHOW_EXCEPTIONPOINTS, MF_BYCOMMAND | (m_views[0]->type() == DVT_EXCEPTION_POINTS ? MF_CHECKED : MF_UNCHECKED));
}
@@ -96,7 +110,7 @@ bool pointswin_info::handle_command(WPARAM wparam, LPARAM lparam)
{
case ID_SHOW_BREAKPOINTS:
m_views[0].reset();
- m_views[0].reset(global_alloc(debugview_info(debugger(), *this, window(), DVT_BREAK_POINTS)));
+ m_views[0].reset(new debugview_info(debugger(), *this, window(), DVT_BREAK_POINTS));
if (!m_views[0]->is_valid())
m_views[0].reset();
win_set_window_text_utf8(window(), "All Breakpoints");
@@ -105,14 +119,81 @@ bool pointswin_info::handle_command(WPARAM wparam, LPARAM lparam)
case ID_SHOW_WATCHPOINTS:
m_views[0].reset();
- m_views[0].reset(global_alloc(debugview_info(debugger(), *this, window(), DVT_WATCH_POINTS)));
+ m_views[0].reset(new debugview_info(debugger(), *this, window(), DVT_WATCH_POINTS));
if (!m_views[0]->is_valid())
m_views[0].reset();
win_set_window_text_utf8(window(), "All Watchpoints");
recompute_children();
return true;
+
+ case ID_SHOW_REGISTERPOINTS:
+ m_views[0].reset();
+ m_views[0].reset(new debugview_info(debugger(), *this, window(), DVT_REGISTER_POINTS));
+ if (!m_views[0]->is_valid())
+ m_views[0].reset();
+ win_set_window_text_utf8(window(), "All Registerpoints");
+ recompute_children();
+ return true;
+
+ case ID_SHOW_EXCEPTIONPOINTS:
+ m_views[0].reset();
+ m_views[0].reset(new debugview_info(debugger(), *this, window(), DVT_EXCEPTION_POINTS));
+ if (!m_views[0]->is_valid())
+ m_views[0].reset();
+ win_set_window_text_utf8(window(), "All Exceptionpoints");
+ recompute_children();
+ return true;
}
break;
}
return debugwin_info::handle_command(wparam, lparam);
}
+
+
+void pointswin_info::restore_configuration_from_node(util::xml::data_node const &node)
+{
+ switch (node.get_attribute_int(ATTR_WINDOW_POINTS_TYPE, -1))
+ {
+ case 0:
+ SendMessage(window(), WM_COMMAND, ID_SHOW_BREAKPOINTS, 0);
+ break;
+ case 1:
+ SendMessage(window(), WM_COMMAND, ID_SHOW_WATCHPOINTS, 0);
+ break;
+ case 2:
+ SendMessage(window(), WM_COMMAND, ID_SHOW_REGISTERPOINTS, 0);
+ break;
+ case 3:
+ SendMessage(window(), WM_COMMAND, ID_SHOW_EXCEPTIONPOINTS, 0);
+ break;
+ }
+
+ debugwin_info::restore_configuration_from_node(node);
+}
+
+
+void pointswin_info::save_configuration_to_node(util::xml::data_node &node)
+{
+ debugwin_info::save_configuration_to_node(node);
+
+ node.set_attribute_int(ATTR_WINDOW_TYPE, WINDOW_TYPE_POINTS_VIEWER);
+ switch (m_views[0]->type())
+ {
+ case DVT_BREAK_POINTS:
+ node.set_attribute_int(ATTR_WINDOW_POINTS_TYPE, 0);
+ break;
+ case DVT_WATCH_POINTS:
+ node.set_attribute_int(ATTR_WINDOW_POINTS_TYPE, 1);
+ break;
+ case DVT_REGISTER_POINTS:
+ node.set_attribute_int(ATTR_WINDOW_POINTS_TYPE, 2);
+ break;
+ case DVT_EXCEPTION_POINTS:
+ node.set_attribute_int(ATTR_WINDOW_POINTS_TYPE, 3);
+ break;
+ default:
+ break;
+ }
+}
+
+} // namespace osd::debugger::win
diff --git a/src/osd/modules/debugger/win/pointswininfo.h b/src/osd/modules/debugger/win/pointswininfo.h
index 8ba1b31fc00..506c68519e8 100644
--- a/src/osd/modules/debugger/win/pointswininfo.h
+++ b/src/osd/modules/debugger/win/pointswininfo.h
@@ -5,15 +5,18 @@
// pointswininfo.h - Win32 debug window handling
//
//============================================================
+#ifndef MAME_DEBUGGER_WIN_POINTSWININFO_H
+#define MAME_DEBUGGER_WIN_POINTSWININFO_H
-#ifndef __DEBUG_WIN_POINTS_WIN_INFO_H__
-#define __DEBUG_WIN_POINTS_WIN_INFO_H__
+#pragma once
#include "debugwin.h"
#include "debugwininfo.h"
+namespace osd::debugger::win {
+
class pointswin_info : public debugwin_info
{
public:
@@ -21,10 +24,14 @@ public:
virtual ~pointswin_info();
virtual bool handle_key(WPARAM wparam, LPARAM lparam) override;
+ virtual void restore_configuration_from_node(util::xml::data_node const &node) override;
protected:
virtual void update_menu() override;
virtual bool handle_command(WPARAM wparam, LPARAM lparam) override;
+ virtual void save_configuration_to_node(util::xml::data_node &node) override;
};
-#endif
+} // namespace osd::debugger::win
+
+#endif // MAME_DEBUGGER_WIN_POINTSWININFO_H
diff --git a/src/osd/modules/debugger/win/uimetrics.cpp b/src/osd/modules/debugger/win/uimetrics.cpp
index 67eb045c619..e3d21cda06d 100644
--- a/src/osd/modules/debugger/win/uimetrics.cpp
+++ b/src/osd/modules/debugger/win/uimetrics.cpp
@@ -2,15 +2,48 @@
// copyright-holders:Aaron Giles, Vas Crabb
//============================================================
//
-// uimetrics.c - Win32 debug window handling
+// uimetrics.cpp - Win32 debug window handling
//
//============================================================
#include "emu.h"
#include "uimetrics.h"
+#include "debug/debugvw.h"
+
#include "strconv.h"
+#include <algorithm>
+
+
+namespace osd::debugger::win {
+
+COLORREF const ui_metrics::s_themes[][COLOR_COUNT] = {
+ {
+ RGB(0x00, 0x00, 0x00), // foreground normal
+ RGB(0xff, 0x00, 0x00), // foreground changed
+ RGB(0x00, 0x00, 0xff), // foreground invalid
+ RGB(0x00, 0x80, 0x00), // foreground comment
+ RGB(0xff, 0xff, 0xff), // background normal
+ RGB(0xff, 0x80, 0x80), // background selected
+ RGB(0xe0, 0xe0, 0xe0), // background ancillary
+ RGB(0xff, 0xff, 0x00), // background current
+ RGB(0xff, 0xc0, 0x80), // background current selected
+ RGB(0xc0, 0xe0, 0xff) // background visited
+ },
+ {
+ RGB(0xe0, 0xe0, 0xe0), // foreground normal
+ RGB(0xff, 0x60, 0xff), // foreground changed
+ RGB(0x00, 0xc0, 0xe0), // foreground invalid
+ RGB(0x00, 0xe0, 0x00), // foreground comment
+ RGB(0x00, 0x00, 0x00), // background normal
+ RGB(0xe0, 0x00, 0x00), // background selected
+ RGB(0x40, 0x40, 0x40), // background ancillary
+ RGB(0x00, 0x00, 0xc0), // background current
+ RGB(0xb0, 0x60, 0x00), // background current selected
+ RGB(0x00, 0x40, 0x80) // background visited
+ } };
+
ui_metrics::ui_metrics(osd_options const &options) :
m_debug_font(nullptr),
@@ -22,7 +55,7 @@ ui_metrics::ui_metrics(osd_options const &options) :
{
// create a temporary DC
HDC const temp_dc = GetDC(nullptr);
- if (temp_dc != nullptr)
+ if (temp_dc)
{
float const size = options.debugger_font_size();
char const *const face = options.debugger_font();
@@ -47,6 +80,9 @@ ui_metrics::ui_metrics(osd_options const &options) :
SelectObject(temp_dc, old_font);
ReleaseDC(nullptr, temp_dc);
}
+
+ // set default color theme
+ set_color_theme(THEME_LIGHT_BACKGROUND);
}
@@ -69,3 +105,56 @@ ui_metrics::~ui_metrics()
if (m_debug_font)
DeleteObject(m_debug_font);
}
+
+
+std::pair<COLORREF, COLORREF> ui_metrics::view_colors(u8 attrib) const
+{
+ std::pair<COLORREF, COLORREF> result;
+
+ if (attrib & DCA_SELECTED)
+ result.second = (attrib & DCA_CURRENT) ? m_colors[COLOR_BG_CURRENT_SELECTED] : m_colors[COLOR_BG_SELECTED];
+ else if (attrib & DCA_CURRENT)
+ result.second = m_colors[COLOR_BG_CURRENT];
+ else if (attrib & DCA_ANCILLARY)
+ result.second = m_colors[COLOR_BG_ANCILLARY];
+ else if (attrib & DCA_VISITED)
+ result.second = m_colors[COLOR_BG_VISITED];
+ else
+ result.second = m_colors[COLOR_BG_NORMAL];
+
+ if (DCA_COMMENT & attrib)
+ {
+ result.first = m_colors[COLOR_FG_COMMENT];
+ }
+ else
+ {
+ if (attrib & DCA_INVALID)
+ result.first = m_colors[COLOR_FG_INVALID];
+ else if (attrib & DCA_CHANGED)
+ result.first = m_colors[COLOR_FG_CHANGED];
+ else
+ result.first = m_colors[COLOR_FG_NORMAL];
+
+ if (attrib & DCA_DISABLED)
+ {
+ result.first = RGB(
+ (GetRValue(result.first) + GetRValue(result.second) + 1) >> 1,
+ (GetGValue(result.first) + GetGValue(result.second) + 1) >> 1,
+ (GetBValue(result.first) + GetBValue(result.second) + 1) >> 1);
+ }
+ }
+
+ return result;
+}
+
+
+void ui_metrics::set_color_theme(int index)
+{
+ if ((0 <= index) && (std::size(s_themes) > index))
+ {
+ std::copy(std::begin(s_themes[index]), std::end(s_themes[index]), m_colors);
+ m_color_theme = index;
+ }
+}
+
+} // namespace osd::debugger::win
diff --git a/src/osd/modules/debugger/win/uimetrics.h b/src/osd/modules/debugger/win/uimetrics.h
index a360d66924e..e45ae810fa6 100644
--- a/src/osd/modules/debugger/win/uimetrics.h
+++ b/src/osd/modules/debugger/win/uimetrics.h
@@ -5,19 +5,29 @@
// uimetrics.h - Win32 debug window handling
//
//============================================================
+#ifndef MAME_DEBUGGER_WIN_UIMETRICS_H
+#define MAME_DEBUGGER_WIN_UIMETRICS_H
-#ifndef __DEBUG_WIN_UI_METRICS_H__
-#define __DEBUG_WIN_UI_METRICS_H__
+#pragma once
#include "debugwin.h"
-
#include "modules/lib/osdobj_common.h"
+#include <utility>
+
+
+namespace osd::debugger::win {
class ui_metrics
{
public:
+ enum
+ {
+ THEME_LIGHT_BACKGROUND,
+ THEME_DARK_BACKGROUND
+ };
+
ui_metrics(osd_options const &options);
ui_metrics(ui_metrics const &that);
~ui_metrics();
@@ -30,7 +40,28 @@ public:
uint32_t hscroll_height() const { return m_hscroll_height; }
uint32_t vscroll_width() const { return m_vscroll_width; }
+ std::pair<COLORREF, COLORREF> view_colors(u8 attrib) const;
+ int get_color_theme() const { return m_color_theme; }
+ void set_color_theme(int index);
+
private:
+ enum
+ {
+ COLOR_FG_NORMAL,
+ COLOR_FG_CHANGED,
+ COLOR_FG_INVALID,
+ COLOR_FG_COMMENT,
+
+ COLOR_BG_NORMAL,
+ COLOR_BG_SELECTED,
+ COLOR_BG_ANCILLARY,
+ COLOR_BG_CURRENT,
+ COLOR_BG_CURRENT_SELECTED,
+ COLOR_BG_VISITED,
+
+ COLOR_COUNT
+ };
+
HFONT m_debug_font;
uint32_t m_debug_font_height;
uint32_t m_debug_font_width;
@@ -38,6 +69,13 @@ private:
uint32_t const m_hscroll_height;
uint32_t const m_vscroll_width;
+
+ COLORREF m_colors[COLOR_COUNT];
+ int m_color_theme;
+
+ static COLORREF const s_themes[][COLOR_COUNT];
};
-#endif
+} // namespace osd::debugger::win
+
+#endif // MAME_DEBUGGER_WIN_UIMETRICS_H