summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd/modules/debugger/debugwin.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/osd/modules/debugger/debugwin.c')
-rw-r--r--src/osd/modules/debugger/debugwin.c3095
1 files changed, 131 insertions, 2964 deletions
diff --git a/src/osd/modules/debugger/debugwin.c b/src/osd/modules/debugger/debugwin.c
index 658731bc09c..448f35b122c 100644
--- a/src/osd/modules/debugger/debugwin.c
+++ b/src/osd/modules/debugger/debugwin.c
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Aaron Giles
+// copyright-holders:Aaron Giles, Vas Crabb
//============================================================
//
// debugwin.c - Win32 debug window handling
@@ -11,3090 +11,257 @@
#if defined(OSD_WINDOWS) /*|| defined(SDLMAME_WIN32)*/
-// standard windows headers
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#include <windowsx.h>
-#include <tchar.h>
-#include <commdlg.h>
-#ifdef _MSC_VER
-#include <zmouse.h>
-#endif
+#include "win/debugwin.h"
+
+#include "win/consolewininfo.h"
+#include "win/debugwininfo.h"
+#include "win/disasmwininfo.h"
+#include "win/logwininfo.h"
+#include "win/memorywininfo.h"
+#include "win/pointswininfo.h"
+#include "win/uimetrics.h"
-// MAME headers
#include "emu.h"
#include "uiinput.h"
-#include "imagedev/cassette.h"
#include "debugger.h"
-#include "debug/debugvw.h"
-#include "debug/dvdisasm.h"
-#include "debug/dvmemory.h"
-#include "debug/dvstate.h"
-#include "debug/debugvw.h"
-#include "debug/debugcon.h"
-#include "debug/debugcpu.h"
-// MAMEOS headers
-#include "winmain.h"
#include "window.h"
+#include "winmain.h"
#include "../../windows/input.h"
-#include "strconv.h"
-#include "winutf8.h"
-class debugger_windows : public osd_module, public debug_module
+
+class debugger_windows : public osd_module, public debug_module, protected debugger_windows_interface
{
public:
- debugger_windows()
- : osd_module(OSD_DEBUG_PROVIDER, "windows"), debug_module(),
- m_machine(NULL)
+ debugger_windows() :
+ osd_module(OSD_DEBUG_PROVIDER, "windows"),
+ debug_module(),
+ m_machine(NULL),
+ m_metrics(),
+ m_waiting_for_debugger(false),
+ m_window_list(),
+ m_main_console(NULL)
{
}
virtual ~debugger_windows() { }
- virtual int init() { return 0;}
+ virtual int init() { return 0; }
virtual void exit();
virtual void init_debugger(running_machine &machine);
virtual void wait_for_debugger(device_t &device, bool firststop);
virtual void debugger_update();
-private:
- running_machine *m_machine;
-};
-//============================================================
-// PARAMETERS
-//============================================================
-
-#define MAX_VIEWS 4
-#define EDGE_WIDTH 3
-#define MAX_EDIT_STRING 256
-#define HISTORY_LENGTH 20
-#define MAX_OTHER_WND 4
-
-// debugger window styles
-#define DEBUG_WINDOW_STYLE (WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN) & (~WS_MINIMIZEBOX & ~WS_MAXIMIZEBOX)
-#define DEBUG_WINDOW_STYLE_EX 0
-
-// debugger view styles
-#define DEBUG_VIEW_STYLE WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN
-#define DEBUG_VIEW_STYLE_EX 0
+protected:
+ virtual running_machine &machine() const { return *m_machine; }
-// edit box styles
-#define EDIT_BOX_STYLE WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL
-#define EDIT_BOX_STYLE_EX 0
+ virtual ui_metrics &metrics() const { return *m_metrics; }
-// combo box styles
-#define COMBO_BOX_STYLE WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST | WS_VSCROLL
-#define COMBO_BOX_STYLE_EX 0
+ virtual bool const &waiting_for_debugger() const { return m_waiting_for_debugger; }
+ virtual bool seq_pressed() const;
-// horizontal scroll bar styles
-#define HSCROLL_STYLE WS_CHILD | WS_VISIBLE | SBS_HORZ
-#define HSCROLL_STYLE_EX 0
+ virtual void create_memory_window() { create_window<memorywin_info>(); }
+ virtual void create_disasm_window() { create_window<disasmwin_info>(); }
+ virtual void create_log_window() { create_window<logwin_info>(); }
+ virtual void create_points_window() { create_window<pointswin_info>(); }
+ virtual void remove_window(debugwin_info &info);
-// vertical scroll bar styles
-#define VSCROLL_STYLE WS_CHILD | WS_VISIBLE | SBS_VERT
-#define VSCROLL_STYLE_EX 0
-
-
-enum
-{
- ID_NEW_MEMORY_WND = 1,
- ID_NEW_DISASM_WND,
- ID_NEW_LOG_WND,
- ID_RUN,
- ID_RUN_AND_HIDE,
- ID_RUN_VBLANK,
- ID_RUN_IRQ,
- ID_NEXT_CPU,
- ID_STEP,
- ID_STEP_OVER,
- ID_STEP_OUT,
- ID_HARD_RESET,
- ID_SOFT_RESET,
- ID_EXIT,
-
- ID_1_BYTE_CHUNKS,
- ID_2_BYTE_CHUNKS,
- ID_4_BYTE_CHUNKS,
- ID_8_BYTE_CHUNKS,
- ID_LOGICAL_ADDRESSES,
- ID_PHYSICAL_ADDRESSES,
- ID_REVERSE_VIEW,
- ID_INCREASE_MEM_WIDTH,
- ID_DECREASE_MEM_WIDTH,
-
- ID_SHOW_RAW,
- ID_SHOW_ENCRYPTED,
- ID_SHOW_COMMENTS,
- ID_RUN_TO_CURSOR,
- ID_TOGGLE_BREAKPOINT,
-
- ID_DEVICE_OPTIONS // keep this always at the end
-};
-
-
-
-//============================================================
-// TYPES
-//============================================================
-
-struct debugview_info;
-class debugwin_info;
+ virtual void show_all();
+ virtual void hide_all();
+private:
+ template <typename T> T *create_window();
-struct debugview_info
-{
- debugwin_info * owner;
- debug_view * view;
- HWND wnd;
- HWND hscroll;
- HWND vscroll;
+ running_machine *m_machine;
+ auto_pointer<ui_metrics> m_metrics;
+ bool m_waiting_for_debugger;
+ simple_list<debugwin_info> m_window_list;
+ consolewin_info *m_main_console;
};
-class debugwin_info
+void debugger_windows::exit()
{
-public:
- debugwin_info(running_machine &machine)
- : m_machine(machine) { }
-
- running_machine &machine() const { return m_machine; }
-
- debugwin_info * next;
- HWND wnd;
- HWND focuswnd;
- WNDPROC handler;
-
- UINT32 minwidth, maxwidth;
- UINT32 minheight, maxheight;
- void (*recompute_children)(debugwin_info *);
- void (*update_menu)(debugwin_info *);
-
- int (*handle_command)(debugwin_info *, WPARAM, LPARAM);
- int (*handle_key)(debugwin_info *, WPARAM, LPARAM);
- UINT16 ignore_char_lparam;
-
- debugview_info view[MAX_VIEWS];
-
- HWND editwnd;
- char edit_defstr[256];
- void (*process_string)(debugwin_info *, const char *);
- WNDPROC original_editproc;
- TCHAR history[HISTORY_LENGTH][MAX_EDIT_STRING];
- int history_count;
- int last_history;
-
- HWND otherwnd[MAX_OTHER_WND];
-
-private:
- running_machine & m_machine;
-};
-
-
-//============================================================
-// LOCAL VARIABLES
-//============================================================
-
-static debugwin_info *window_list = NULL;
-static debugwin_info *main_console;
-static UINT32 main_console_regwidth;
-
-static UINT8 waiting_for_debugger;
-
-static HFONT debug_font;
-static UINT32 debug_font_height;
-static UINT32 debug_font_width;
-static UINT32 debug_font_ascent;
-
-static UINT32 hscroll_height;
-static UINT32 vscroll_width;
-
-
-
-//============================================================
-// PROTOTYPES
-//============================================================
-
-static debugwin_info *debugwin_window_create(running_machine &machine, LPCSTR title, WNDPROC handler);
-static void debugwin_window_free(debugwin_info *info);
-static LRESULT CALLBACK debugwin_window_proc(HWND wnd, UINT message, WPARAM wparam, LPARAM lparam);
-
-static void debugwin_view_draw_contents(debugview_info *view, HDC dc);
-static LRESULT CALLBACK debugwin_view_proc(HWND wnd, UINT message, WPARAM wparam, LPARAM lparam);
-static void debugwin_view_update(debug_view &view, void *osdprivate);
-static int debugwin_view_create(debugwin_info *info, int which, debug_view_type type);
-
-static LRESULT CALLBACK debugwin_edit_proc(HWND wnd, UINT message, WPARAM wparam, LPARAM lparam);
-
-//static void generic_create_window(int type);
-static void generic_recompute_children(debugwin_info *info);
-
-static void memory_create_window(running_machine &machine);
-static void memory_recompute_children(debugwin_info *info);
-static void memory_process_string(debugwin_info *info, const char *string);
-static void memory_update_menu(debugwin_info *info);
-static int memory_handle_command(debugwin_info *info, WPARAM wparam, LPARAM lparam);
-static int memory_handle_key(debugwin_info *info, WPARAM wparam, LPARAM lparam);
-static void memory_update_caption(running_machine &machine, HWND wnd);
-
-static void disasm_create_window(running_machine &machine);
-static void disasm_recompute_children(debugwin_info *info);
-static void disasm_process_string(debugwin_info *info, const char *string);
-static void disasm_update_menu(debugwin_info *info);
-static int disasm_handle_command(debugwin_info *info, WPARAM wparam, LPARAM lparam);
-static int disasm_handle_key(debugwin_info *info, WPARAM wparam, LPARAM lparam);
-static void disasm_update_caption(running_machine &machine, HWND wnd);
+ // loop over windows and free them
+ while (m_window_list.first() != NULL)
+ m_window_list.first()->destroy();
-static void console_create_window(running_machine &machine);
-static void console_recompute_children(debugwin_info *info);
-static void console_process_string(debugwin_info *info, const char *string);
-static void console_set_cpu(device_t *device);
+ m_main_console = NULL;
+ m_metrics.reset();
+ m_machine = NULL;
+}
-static HMENU create_standard_menubar(void);
-static int global_handle_command(debugwin_info *info, WPARAM wparam, LPARAM lparam);
-static int global_handle_key(debugwin_info *info, WPARAM wparam, LPARAM lparam);
-static void smart_set_window_bounds(HWND wnd, HWND parent, RECT *bounds);
-static void smart_show_window(HWND wnd, BOOL show);
-static void smart_show_all(BOOL show);
-static void image_update_menu(debugwin_info *info);
+void debugger_windows::init_debugger(running_machine &machine)
+{
+ m_machine = &machine;
+ m_metrics.reset(global_alloc(ui_metrics(downcast<windows_options &>(m_machine->options()))));
+}
-//============================================================
-// wait_for_debugger
-//============================================================
-
void debugger_windows::wait_for_debugger(device_t &device, bool firststop)
{
- MSG message;
-
// create a console window
- if (main_console == NULL)
- console_create_window(*m_machine);
+ if (m_main_console == NULL)
+ m_main_console = create_window<consolewin_info>();
// update the views in the console to reflect the current CPU
- if (main_console != NULL)
- console_set_cpu(&device);
+ if (m_main_console != NULL)
+ m_main_console->set_cpu(device);
// when we are first stopped, adjust focus to us
- if (firststop && main_console != NULL)
+ if (firststop && (m_main_console != NULL))
{
- SetForegroundWindow(main_console->wnd);
+ m_main_console->set_foreground();
if (winwindow_has_focus())
- SetFocus(main_console->editwnd);
+ m_main_console->set_default_focus();
}
// make sure the debug windows are visible
- waiting_for_debugger = TRUE;
- smart_show_all(TRUE);
+ m_waiting_for_debugger = true;
+ show_all();
// run input polling to ensure that our status is in sync
wininput_poll(*m_machine);
// get and process messages
+ MSG message;
GetMessage(&message, NULL, 0, 0);
switch (message.message)
{
- // check for F10 -- we need to capture that ourselves
- case WM_SYSKEYDOWN:
- case WM_SYSKEYUP:
- if (message.wParam == VK_F4 && message.message == WM_SYSKEYDOWN)
- SendMessage(GetAncestor(GetFocus(), GA_ROOT), WM_CLOSE, 0, 0);
- if (message.wParam == VK_F10)
- SendMessage(GetAncestor(GetFocus(), GA_ROOT), (message.message == WM_SYSKEYDOWN) ? WM_KEYDOWN : WM_KEYUP, message.wParam, message.lParam);
- break;
+ // check for F10 -- we need to capture that ourselves
+ case WM_SYSKEYDOWN:
+ case WM_SYSKEYUP:
+ if (message.wParam == VK_F4 && message.message == WM_SYSKEYDOWN)
+ SendMessage(GetAncestor(GetFocus(), GA_ROOT), WM_CLOSE, 0, 0);
+ if (message.wParam == VK_F10)
+ SendMessage(GetAncestor(GetFocus(), GA_ROOT), (message.message == WM_SYSKEYDOWN) ? WM_KEYDOWN : WM_KEYUP, message.wParam, message.lParam);
+ break;
- // process everything else
- default:
- winwindow_dispatch_message(*m_machine, &message);
- break;
+ // process everything else
+ default:
+ winwindow_dispatch_message(*m_machine, &message);
+ break;
}
// mark the debugger as active
- waiting_for_debugger = FALSE;
+ m_waiting_for_debugger = false;
}
-
-//============================================================
-// debugwin_seq_pressed
-//============================================================
-
-static int debugwin_seq_pressed(running_machine &machine)
-{
- const input_seq &seq = machine.ioport().type_seq(IPT_UI_DEBUG_BREAK);
- int result = FALSE;
- int invert = FALSE;
- int first = TRUE;
- int codenum;
-
- // iterate over all of the codes
- int length = seq.length();
- for (codenum = 0; codenum < length; codenum++)
- {
- input_code code = seq[codenum];
-
- // handle NOT
- if (code == input_seq::not_code)
- invert = TRUE;
-
- // handle OR and END
- else if (code == input_seq::or_code || code == input_seq::end_code)
- {
- // if we have a positive result from the previous set, we're done
- if (result || code == input_seq::end_code)
- break;
-
- // otherwise, reset our state
- result = FALSE;
- invert = FALSE;
- first = TRUE;
- }
-
- // handle everything else as a series of ANDs
- else
- {
- int vkey = wininput_vkey_for_mame_code(code);
- int pressed = (vkey != 0 && (GetAsyncKeyState(vkey) & 0x8000) != 0);
-
- // if this is the first in the sequence, result is set equal
- if (first)
- result = pressed ^ invert;
-
- // further values are ANDed
- else if (result)
- result &= pressed ^ invert;
-
- // no longer first, and clear the invert flag
- first = invert = FALSE;
- }
- }
-
- // return the result if we queried at least one switch
- return result;
-}
-
-
-
-//============================================================
-// debugwin_init_windows
-//============================================================
-
-void debugger_windows::init_debugger(running_machine &machine)
-{
- static int class_registered;
-
- m_machine = &machine;
- // register the window classes
- if (!class_registered)
- {
- WNDCLASS wc = { 0 };
-
- // initialize the description of the window class
- wc.lpszClassName = TEXT("MAMEDebugWindow");
- wc.hInstance = GetModuleHandle(NULL);
- wc.lpfnWndProc = debugwin_window_proc;
- wc.hCursor = LoadCursor(NULL, IDC_ARROW);
- wc.hIcon = LoadIcon(wc.hInstance, MAKEINTRESOURCE(2));
- wc.lpszMenuName = NULL;
- wc.hbrBackground = NULL;
- wc.style = 0;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
-
- // register the class; fail if we can't
- if (!RegisterClass(&wc))
- fatalerror("Unable to register debug window class\n");
-
- // initialize the description of the view class
- wc.lpszClassName = TEXT("MAMEDebugView");
- wc.lpfnWndProc = debugwin_view_proc;
-
- // register the class; fail if we can't
- if (!RegisterClass(&wc))
- fatalerror("Unable to register debug view class\n");
-
- class_registered = TRUE;
- }
-
- // create the font
- if (debug_font == NULL)
- {
- // create a temporary DC
- HDC temp_dc = GetDC(NULL);
- TEXTMETRIC metrics;
- HGDIOBJ old_font;
-
- if (temp_dc != NULL)
- {
- windows_options &options = downcast<windows_options &>(m_machine->options());
- int size = options.debugger_font_size();
- TCHAR *t_face;
-
- // create a standard font
- t_face = tstring_from_utf8(options.debugger_font());
- debug_font = CreateFont(-MulDiv(size, GetDeviceCaps(temp_dc, LOGPIXELSY), 72), 0, 0, 0, FW_MEDIUM, FALSE, FALSE, FALSE,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FIXED_PITCH, t_face);
- osd_free(t_face);
- t_face = NULL;
-
- if (debug_font == NULL)
- fatalerror("Unable to create debugger font\n");
-
- // get the metrics
- old_font = SelectObject(temp_dc, debug_font);
- if (GetTextMetrics(temp_dc, &metrics))
- {
- debug_font_width = metrics.tmAveCharWidth;
- debug_font_height = metrics.tmHeight;
- debug_font_ascent = metrics.tmAscent + metrics.tmExternalLeading;
- }
- SelectObject(temp_dc, old_font);
- ReleaseDC(NULL, temp_dc);
- }
- }
-
- // get other metrics
- hscroll_height = GetSystemMetrics(SM_CYHSCROLL);
- vscroll_width = GetSystemMetrics(SM_CXVSCROLL);
-}
-
-
-
-//============================================================
-// debugwin_destroy_windows
-//============================================================
-
-void debugger_windows::exit()
-{
- // loop over windows and free them
- while (window_list != NULL)
- {
- // clear the view list because they will be freed by the core
- memset(window_list->view, 0, sizeof(window_list->view));
- DestroyWindow(window_list->wnd);
- }
-
- main_console = NULL;
-}
-
-
-
-//============================================================
-// debugger_update
-//============================================================
-
void debugger_windows::debugger_update()
{
// if we're running live, do some checks
- if (!winwindow_has_focus() && !debug_cpu_is_stopped(*m_machine) && m_machine->phase() == MACHINE_PHASE_RUNNING)
+ if (!winwindow_has_focus() && !debug_cpu_is_stopped(*m_machine) && (m_machine->phase() == MACHINE_PHASE_RUNNING))
{
// see if the interrupt key is pressed and break if it is
- if (debugwin_seq_pressed(*m_machine))
+ if (seq_pressed())
{
- HWND focuswnd = GetFocus();
- debugwin_info *info;
+ HWND const focuswnd = GetFocus();
debug_cpu_get_visible_cpu(*m_machine)->debug()->halt_on_next_instruction("User-initiated break\n");
// if we were focused on some window's edit box, reset it to default
- for (info = window_list; info != NULL; info = info->next)
- if (focuswnd == info->editwnd)
- {
- SendMessage(focuswnd, WM_SETTEXT, (WPARAM)0, (LPARAM)info->edit_defstr);
- SendMessage(focuswnd, EM_SETSEL, (WPARAM)0, (LPARAM)-1);
- }
- }
- }
-}
-
-
-
-//============================================================
-// debugwin_window_create
-//============================================================
-
-static debugwin_info *debugwin_window_create(running_machine &machine, LPCSTR title, WNDPROC handler)
-{
- debugwin_info *info = NULL;
- RECT work_bounds;
-
- // allocate memory
- info = global_alloc_clear(debugwin_info(machine));
-
- // create the window
- info->handler = handler;
- info->wnd = win_create_window_ex_utf8(DEBUG_WINDOW_STYLE_EX, "MAMEDebugWindow", title, DEBUG_WINDOW_STYLE,
- 0, 0, 100, 100, win_window_list->m_hwnd, create_standard_menubar(), GetModuleHandle(NULL), info);
- if (info->wnd == NULL)
- goto cleanup;
-
- // fill in some defaults
- SystemParametersInfo(SPI_GETWORKAREA, 0, &work_bounds, 0);
- info->minwidth = 200;
- info->minheight = 200;
- info->maxwidth = work_bounds.right - work_bounds.left;
- info->maxheight = work_bounds.bottom - work_bounds.top;
-
- // set the default handlers
- info->handle_command = global_handle_command;
- info->handle_key = global_handle_key;
- strcpy(info->edit_defstr, "");
-
- // hook us in
- info->next = window_list;
- window_list = info;
-
- return info;
-
-cleanup:
- if (info->wnd != NULL)
- DestroyWindow(info->wnd);
- global_free(info);
- return NULL;
-}
-
-
-
-//============================================================
-// debugwin_window_free
-//============================================================
-
-static void debugwin_window_free(debugwin_info *info)
-{
- debugwin_info **scanptr;
- int viewnum;
-
- // first unlink us from the list
- for (scanptr = &window_list; *scanptr != NULL; scanptr = &(*scanptr)->next)
- if (*scanptr == info)
- {
- *scanptr = info->next;
- break;
+ for (debugwin_info *info = m_window_list.first(); info != NULL; info = info->next())
+ info->restore_field(focuswnd);
}
-
- // free any views
- for (viewnum = 0; viewnum < ARRAY_LENGTH(info->view); viewnum++)
- if (info->view[viewnum].view != NULL)
- {
- info->machine().debug_view().free_view(*info->view[viewnum].view);
- info->view[viewnum].view = NULL;
- }
-
- // free our memory
- global_free(info);
-}
-
-
-
-//============================================================
-// debugwin_window_draw_contents
-//============================================================
-
-static void debugwin_window_draw_contents(debugwin_info *info, HDC dc)
-{
- RECT bounds, parent;
- int curview, curwnd;
-
- // fill the background with light gray
- GetClientRect(info->wnd, &parent);
- FillRect(dc, &parent, (HBRUSH)GetStockObject(LTGRAY_BRUSH));
-
- // get the parent bounds in screen coords
- ClientToScreen(info->wnd, &((POINT *)&parent)[0]);
- ClientToScreen(info->wnd, &((POINT *)&parent)[1]);
-
- // draw edges around all views
- for (curview = 0; curview < MAX_VIEWS; curview++)
- if (info->view[curview].wnd)
- {
- GetWindowRect(info->view[curview].wnd, &bounds);
- bounds.top -= parent.top;
- bounds.bottom -= parent.top;
- bounds.left -= parent.left;
- bounds.right -= parent.left;
- InflateRect(&bounds, EDGE_WIDTH, EDGE_WIDTH);
- DrawEdge(dc, &bounds, EDGE_SUNKEN, BF_RECT);
- }
-
- // draw edges around all children
- if (info->editwnd)
- {
- GetWindowRect(info->editwnd, &bounds);
- bounds.top -= parent.top;
- bounds.bottom -= parent.top;
- bounds.left -= parent.left;
- bounds.right -= parent.left;
- InflateRect(&bounds, EDGE_WIDTH, EDGE_WIDTH);
- DrawEdge(dc, &bounds, EDGE_SUNKEN, BF_RECT);
}
-
- for (curwnd = 0; curwnd < MAX_OTHER_WND; curwnd++)
- if (info->otherwnd[curwnd])
- {
- GetWindowRect(info->otherwnd[curwnd], &bounds);
- bounds.top -= parent.top;
- bounds.bottom -= parent.top;
- bounds.left -= parent.left;
- bounds.right -= parent.left;
- InflateRect(&bounds, EDGE_WIDTH, EDGE_WIDTH);
- DrawEdge(dc, &bounds, EDGE_SUNKEN, BF_RECT);
- }
}
-
-//============================================================
-// debugwin_window_proc
-//============================================================
-
-static LRESULT CALLBACK debugwin_window_proc(HWND wnd, UINT message, WPARAM wparam, LPARAM lparam)
+bool debugger_windows::seq_pressed() const
{
- debugwin_info *info = (debugwin_info *)(FPTR)GetWindowLongPtr(wnd, GWLP_USERDATA);
-
- // handle a few messages
- switch (message)
- {
- // set the info pointer
- case WM_CREATE:
- {
- CREATESTRUCT *createinfo = (CREATESTRUCT *)lparam;
- info = (debugwin_info *)createinfo->lpCreateParams;
- SetWindowLongPtr(wnd, GWLP_USERDATA, (LONG_PTR)createinfo->lpCreateParams);
- if (info->handler)
- SetWindowLongPtr(wnd, GWLP_WNDPROC, (LONG_PTR)info->handler);
- break;
- }
-
- // paint: draw bezels as necessary
- case WM_PAINT:
- {
- PAINTSTRUCT pstruct;
- HDC dc = BeginPaint(wnd, &pstruct);
- debugwin_window_draw_contents(info, dc);
- EndPaint(wnd, &pstruct);
- break;
- }
-
- // keydown: handle debugger keys
- case WM_KEYDOWN:
- if ((*info->handle_key)(info, wparam, lparam))
- info->ignore_char_lparam = lparam >> 16;
- break;
-
- // char: ignore chars associated with keys we've handled
- case WM_CHAR:
- if (info->ignore_char_lparam == (lparam >> 16))
- info->ignore_char_lparam = 0;
- else if (waiting_for_debugger || !debugwin_seq_pressed(info->machine()))
- return DefWindowProc(wnd, message, wparam, lparam);
- break;
-
- // activate: set the focus
- case WM_ACTIVATE:
- if (wparam != WA_INACTIVE && info->focuswnd != NULL)
- SetFocus(info->focuswnd);
- break;
-
- // get min/max info: set the minimum window size
- case WM_GETMINMAXINFO:
- {
- MINMAXINFO *minmax = (MINMAXINFO *)lparam;
- if (info)
- {
- minmax->ptMinTrackSize.x = info->minwidth;
- minmax->ptMinTrackSize.y = info->minheight;
- minmax->ptMaxSize.x = minmax->ptMaxTrackSize.x = info->maxwidth;
- minmax->ptMaxSize.y = minmax->ptMaxTrackSize.y = info->maxheight;
- }
- break;
- }
-
- // sizing: recompute child window locations
- case WM_SIZE:
- case WM_SIZING:
- if (info->recompute_children != NULL)
- (*info->recompute_children)(info);
- InvalidateRect(wnd, NULL, FALSE);
- break;
-
- // mouse wheel: forward to the first view
- case WM_MOUSEWHEEL:
- {
- static int units_carryover = 0;
-
- UINT lines_per_click;
- if (!SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &lines_per_click, 0))
- lines_per_click = 3;
-
- int units = GET_WHEEL_DELTA_WPARAM(wparam) + units_carryover;
- int clicks = units / WHEEL_DELTA;
- units_carryover = units % WHEEL_DELTA;
-
- int delta = clicks * lines_per_click;
- int viewnum = 0;
- POINT point;
- HWND child;
-
- // figure out which view we are hovering over
- GetCursorPos(&point);
- ScreenToClient(info->wnd, &point);
- child = ChildWindowFromPoint(info->wnd, point);
- if (child)
- {
- for (viewnum = 0; viewnum < MAX_VIEWS; viewnum++)
- if (info->view[viewnum].wnd == child)
- break;
- if (viewnum == MAX_VIEWS)
- break;
- }
-
- // send the appropriate message to this view's scrollbar
- if (info->view[viewnum].wnd && info->view[viewnum].vscroll)
- {
- int message_type = SB_LINEUP;
- if (delta < 0)
- {
- message_type = SB_LINEDOWN;
- delta = -delta;
- }
- while (delta > 0)
- {
- SendMessage(info->view[viewnum].wnd, WM_VSCROLL, message_type, (LPARAM)info->view[viewnum].vscroll);
- delta--;
- }
- }
- break;
- }
-
- // activate: set the focus
- case WM_INITMENU:
- if (info->update_menu != NULL)
- (*info->update_menu)(info);
- break;
-
- // command: handle a comment
- case WM_COMMAND:
- if (!(*info->handle_command)(info, wparam, lparam))
- return DefWindowProc(wnd, message, wparam, lparam);
- break;
+ input_seq const &seq = m_machine->ioport().type_seq(IPT_UI_DEBUG_BREAK);
+ bool result = false;
+ bool invert = false;
+ bool first = true;
- // close: close the window if it's not the main console
- case WM_CLOSE:
- if (main_console && main_console->wnd == wnd)
- {
- smart_show_all(FALSE);
- debug_cpu_get_visible_cpu(info->machine())->debug()->go();
- }
- else
- DestroyWindow(wnd);
- break;
-
- // destroy: close down the window
- case WM_NCDESTROY:
- debugwin_window_free(info);
- break;
-
- // everything else: defaults
- default:
- return DefWindowProc(wnd, message, wparam, lparam);
- }
-
- return 0;
-}
-
-
-
-//============================================================
-// debugwin_view_create
-//============================================================
-
-static int debugwin_view_create(debugwin_info *info, int which, debug_view_type type)
-{
- debugview_info *view = &info->view[which];
-
- // set the owner
- view->owner = info;
-
- // create the child view
- view->wnd = CreateWindowEx(DEBUG_VIEW_STYLE_EX, TEXT("MAMEDebugView"), NULL, DEBUG_VIEW_STYLE,
- 0, 0, 100, 100, info->wnd, NULL, GetModuleHandle(NULL), view);
- if (view->wnd == NULL)
- goto cleanup;
-
- // create the scroll bars
- view->hscroll = CreateWindowEx(HSCROLL_STYLE_EX, TEXT("SCROLLBAR"), NULL, HSCROLL_STYLE,
- 0, 0, 100, CW_USEDEFAULT, view->wnd, NULL, GetModuleHandle(NULL), view);
- view->vscroll = CreateWindowEx(VSCROLL_STYLE_EX, TEXT("SCROLLBAR"), NULL, VSCROLL_STYLE,
- 0, 0, CW_USEDEFAULT, 100, view->wnd, NULL, GetModuleHandle(NULL), view);
- if (view->hscroll == NULL || view->vscroll == NULL)
- goto cleanup;
-
- // create the debug view
- view->view = info->machine().debug_view().alloc_view(type, debugwin_view_update, view);
- if (view->view == NULL)
- goto cleanup;
-
- return 1;
-
-cleanup:
- if (view->view)
- info->machine().debug_view().free_view(*view->view);
- if (view->hscroll)
- DestroyWindow(view->hscroll);
- if (view->vscroll)
- DestroyWindow(view->vscroll);
- if (view->wnd)
- DestroyWindow(view->wnd);
- return 0;
-}
-
-
-
-//============================================================
-// debugwin_view_set_bounds
-//============================================================
-
-static void debugwin_view_set_bounds(debugview_info *info, HWND parent, const RECT *newbounds)
-{
- RECT bounds = *newbounds;
-
- // account for the edges and set the bounds
- if (info->wnd)
- smart_set_window_bounds(info->wnd, parent, &bounds);
-
- // update
- debugwin_view_update(*info->view, info);
-}
-
-
-
-//============================================================
-// debugwin_view_draw_contents
-//============================================================
-
-static void debugwin_view_draw_contents(debugview_info *view, HDC windc)
-{
- const debug_view_char *viewdata = view->view->viewdata();
- debug_view_xy visarea = view->view->visible_size();
- HGDIOBJ oldfont, oldbitmap;
- COLORREF oldfgcolor;
- UINT32 col, row;
- HBITMAP bitmap;
- int oldbkmode;
- RECT client;
- HDC dc;
-
- // get the client rect
- GetClientRect(view->wnd, &client);
-
- // create a compatible DC and an offscreen bitmap
- dc = CreateCompatibleDC(windc);
- if (dc == NULL)
- return;
- bitmap = CreateCompatibleBitmap(windc, client.right, client.bottom);
- if (bitmap == NULL)
- {
- DeleteDC(dc);
- return;
- }
- oldbitmap = SelectObject(dc, bitmap);
-
- // set the font
- oldfont = SelectObject(dc, debug_font);
- oldfgcolor = GetTextColor(dc);
- oldbkmode = GetBkMode(dc);
- SetBkMode(dc, TRANSPARENT);
-
- // iterate over rows and columns
- for (row = 0; row < visarea.y; row++)
- {
- int iter;
-
- // loop twice; once to fill the background and once to draw the text
- for (iter = 0; iter < 2; iter++)
- {
- COLORREF fgcolor = RGB(0x00,0x00,0x00);
- COLORREF bgcolor = RGB(0xff,0xff,0xff);
- HBRUSH bgbrush = NULL;
- int last_attrib = -1;
- TCHAR buffer[256];
- int count = 0;
- RECT bounds;
-
- // initialize the text bounds
- bounds.left = bounds.right = 0;
- bounds.top = row * debug_font_height;
- bounds.bottom = bounds.top + debug_font_height;
-
- // start with a brush on iteration #0
- if (iter == 0)
- bgbrush = CreateSolidBrush(bgcolor);
-
- // iterate over columns
- for (col = 0; col < visarea.x; col++)
- {
- // if the attribute changed, adjust the colors
- if (viewdata[col].attrib != last_attrib)
- {
- 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_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);
-
- // flush any pending drawing
- if (count > 0)
- {
- bounds.right = bounds.left + count * debug_font_width;
- if (iter == 0)
- FillRect(dc, &bounds, bgbrush);
- else
- ExtTextOut(dc, bounds.left, bounds.top, 0, NULL, buffer, count, NULL);
- bounds.left = bounds.right;
- count = 0;
- }
-
- // set the new colors
- if (iter == 0 && oldbg != bgcolor)
- {
- DeleteObject(bgbrush);
- bgbrush = CreateSolidBrush(bgcolor);
- }
- else if (iter == 1)
- SetTextColor(dc, fgcolor);
- last_attrib = viewdata[col].attrib;
- }
-
- // add this character to the buffer
- buffer[count++] = viewdata[col].byte;
- }
-
- // flush any remaining stuff
- if (count > 0)
- {
- bounds.right = bounds.left + count * debug_font_width;
- if (iter == 0)
- FillRect(dc, &bounds, bgbrush);
- else
- ExtTextOut(dc, bounds.left, bounds.top, 0, NULL, buffer, count, NULL);
- }
-
- // erase to the end of the line
- if (iter == 0)
- {
- bounds.left = bounds.right;
- bounds.right = client.right;
- FillRect(dc, &bounds, bgbrush);
- DeleteObject(bgbrush);
- }
- }
-
- // advance viewdata
- viewdata += visarea.x;
- }
-
- // erase anything beyond the bottom with white
- GetClientRect(view->wnd, &client);
- client.top = visarea.y * debug_font_height;
- FillRect(dc, &client, (HBRUSH)GetStockObject(WHITE_BRUSH));
-
- // reset the font
- SetBkMode(dc, oldbkmode);
- SetTextColor(dc, oldfgcolor);
- SelectObject(dc, oldfont);
-
- // blit the final results
- BitBlt(windc, 0, 0, client.right, client.bottom, dc, 0, 0, SRCCOPY);
-
- // undo the offscreen stuff
- SelectObject(dc, oldbitmap);
- DeleteObject(bitmap);
- DeleteDC(dc);
-}
-
-
-
-//============================================================
-// debugwin_view_update
-//============================================================
-
-static void debugwin_view_update(debug_view &view, void *osdprivate)
-{
- debugview_info *info = (debugview_info *)osdprivate;
- RECT bounds, vscroll_bounds, hscroll_bounds;
- debug_view_xy totalsize, visiblesize, topleft;
- int show_vscroll, show_hscroll;
- SCROLLINFO scrollinfo;
-
- assert(info->view == &view);
-
- // get the view window bounds
- GetClientRect(info->wnd, &bounds);
- visiblesize.x = (bounds.right - bounds.left) / debug_font_width;
- visiblesize.y = (bounds.bottom - bounds.top) / debug_font_height;
-
- // get the updated total rows/cols and left row/col
- totalsize = view.total_size();
- topleft = view.visible_position();
-
- // determine if we need to show the scrollbars
- show_vscroll = show_hscroll = FALSE;
- if (totalsize.x > visiblesize.x && bounds.bottom >= hscroll_height)
- {
- bounds.bottom -= hscroll_height;
- visiblesize.y = (bounds.bottom - bounds.top) / debug_font_height;
- show_hscroll = TRUE;
- }
- if (totalsize.y > visiblesize.y && bounds.right >= vscroll_width)
- {
- bounds.right -= vscroll_width;
- visiblesize.x = (bounds.right - bounds.left) / debug_font_width;
- show_vscroll = TRUE;
- }
- if (!show_vscroll && totalsize.y > visiblesize.y && bounds.right >= vscroll_width)
- {
- bounds.right -= vscroll_width;
- visiblesize.x = (bounds.right - bounds.left) / debug_font_width;
- show_vscroll = TRUE;
- }
-
- // compute the bounds of the scrollbars
- GetClientRect(info->wnd, &vscroll_bounds);
- vscroll_bounds.left = vscroll_bounds.right - vscroll_width;
- if (show_hscroll)
- vscroll_bounds.bottom -= hscroll_height;
-
- GetClientRect(info->wnd, &hscroll_bounds);
- hscroll_bounds.top = hscroll_bounds.bottom - hscroll_height;
- if (show_vscroll)
- hscroll_bounds.right -= vscroll_width;
-
- // if we hid the scrollbars, make sure we reset the top/left corners
- if (topleft.y + visiblesize.y > totalsize.y)
- topleft.y = MAX(totalsize.y - visiblesize.y, 0);
- if (topleft.x + visiblesize.x > totalsize.x)
- topleft.x = 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(info->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(info->hscroll, SB_CTL, &scrollinfo, TRUE);
-
- // update window info
- visiblesize.y++;
- visiblesize.x++;
- view.set_visible_size(visiblesize);
- view.set_visible_position(topleft);
-
- // invalidate the bounds
- InvalidateRect(info->wnd, NULL, FALSE);
-
- // adjust the bounds of the scrollbars and show/hide them
- if (info->vscroll)
- {
- if (show_vscroll)
- smart_set_window_bounds(info->vscroll, info->wnd, &vscroll_bounds);
- smart_show_window(info->vscroll, show_vscroll);
- }
- if (info->hscroll)
- {
- if (show_hscroll)
- smart_set_window_bounds(info->hscroll, info->wnd, &hscroll_bounds);
- smart_show_window(info->hscroll, show_hscroll);
- }
-}
-
-
-
-//============================================================
-// debugwin_view_process_scroll
-//============================================================
-
-static UINT32 debugwin_view_process_scroll(debugview_info *info, WORD type, HWND wnd)
-{
- SCROLLINFO scrollinfo;
- INT32 maxval;
- INT32 result;
-
- // get the current info
- scrollinfo.cbSize = sizeof(scrollinfo);
- scrollinfo.fMask = SIF_PAGE | SIF_POS | SIF_RANGE | SIF_TRACKPOS;
- GetScrollInfo(wnd, SB_CTL, &scrollinfo);
-
- // by default we stay put
- result = scrollinfo.nPos;
-
- // determine the maximum value
- maxval = (scrollinfo.nMax > scrollinfo.nPage) ? (scrollinfo.nMax - scrollinfo.nPage + 1) : 0;
-
- // handle the message
- switch (type)
- {
- case SB_THUMBTRACK:
- result = scrollinfo.nTrackPos;
- break;
-
- case SB_LEFT:
- result = 0;
- break;
-
- case SB_RIGHT:
- result = maxval;
- break;
-
- case SB_LINELEFT:
- result -= 1;
- break;
-
- case SB_LINERIGHT:
- result += 1;
- break;
-
- case SB_PAGELEFT:
- result -= scrollinfo.nPage - 1;
- break;
-
- case SB_PAGERIGHT:
- result += scrollinfo.nPage - 1;
- break;
- }
-
- // generic rangecheck
- if (result < 0)
- result = 0;
- if (result > maxval)
- result = maxval;
-
- // set the new position
- scrollinfo.fMask = SIF_POS;
- scrollinfo.nPos = result;
- SetScrollInfo(wnd, SB_CTL, &scrollinfo, TRUE);
-
- return (UINT32)result;
-}
-
-
-
-//============================================================
-// debugwin_view_prev_view
-//============================================================
-
-static void debugwin_view_prev_view(debugwin_info *info, debugview_info *curview)
-{
- int curindex = 1;
- int numviews;
-
- // count the number of views
- for (numviews = 0; numviews < MAX_VIEWS; numviews++)
- if (info->view[numviews].wnd == NULL)
- break;
-
- // if we have a curview, find out its index
- if (curview)
- curindex = curview - &info->view[0];
-
- // loop until we find someone to take focus
- while (1)
- {
- // advance to the previous index
- curindex--;
- if (curindex < -1)
- curindex = numviews - 1;
-
- // negative numbers mean the focuswnd
- if (curindex < 0 && info->focuswnd != NULL)
- {
- SetFocus(info->focuswnd);
- break;
- }
-
- // positive numbers mean a view
- else if (curindex >= 0 && info->view[curindex].wnd != NULL && info->view[curindex].view->cursor_supported())
- {
- SetFocus(info->view[curindex].wnd);
- break;
- }
- }
-}
-
-
-
-//============================================================
-// debugwin_view_next_view
-//============================================================
-
-static void debugwin_view_next_view(debugwin_info *info, debugview_info *curview)
-{
- int curindex = -1;
- int numviews;
-
- // count the number of views
- for (numviews = 0; numviews < MAX_VIEWS; numviews++)
- if (info->view[numviews].wnd == NULL)
- break;
-
- // if we have a curview, find out its index
- if (curview)
- curindex = curview - &info->view[0];
-
- // loop until we find someone to take focus
- while (1)
- {
- // advance to the previous index
- curindex++;
- if (curindex >= numviews)
- curindex = -1;
-
- // negative numbers mean the focuswnd
- if (curindex < 0 && info->focuswnd != NULL)
- {
- SetFocus(info->focuswnd);
- break;
- }
-
- // positive numbers mean a view
- else if (curindex >= 0 && info->view[curindex].wnd != NULL && info->view[curindex].view->cursor_supported())
- {
- SetFocus(info->view[curindex].wnd);
- InvalidateRect(info->view[curindex].wnd, NULL, FALSE);
- break;
- }
- }
-}
-
-
-
-//============================================================
-// debugwin_view_proc
-//============================================================
-
-static LRESULT CALLBACK debugwin_view_proc(HWND wnd, UINT message, WPARAM wparam, LPARAM lparam)
-{
- debugview_info *info = (debugview_info *)(FPTR)GetWindowLongPtr(wnd, GWLP_USERDATA);
-
- // handle a few messages
- switch (message)
+ // iterate over all of the codes
+ for (int codenum = 0, length = seq.length(); codenum < length; codenum++)
{
- // set the info pointer
- case WM_CREATE:
- {
- CREATESTRUCT *createinfo = (CREATESTRUCT *)lparam;
- SetWindowLongPtr(wnd, GWLP_USERDATA, (LONG_PTR)createinfo->lpCreateParams);
- break;
- }
-
- // paint: redraw the last bitmap
- case WM_PAINT:
- {
- PAINTSTRUCT pstruct;
- HDC dc = BeginPaint(wnd, &pstruct);
- debugwin_view_draw_contents(info, dc);
- EndPaint(wnd, &pstruct);
- break;
- }
-
- // keydown: handle debugger keys
- case WM_SYSKEYDOWN:
- if (wparam != VK_F10)
- return DefWindowProc(wnd, message, wparam, lparam);
- // (fall through)
- case WM_KEYDOWN:
- {
- if ((*info->owner->handle_key)(info->owner, wparam, lparam))
- info->owner->ignore_char_lparam = lparam >> 16;
- else
- {
- switch (wparam)
- {
- case VK_UP:
- info->view->process_char(DCH_UP);
- info->owner->ignore_char_lparam = lparam >> 16;
- break;
-
- case VK_DOWN:
- info->view->process_char(DCH_DOWN);
- info->owner->ignore_char_lparam = lparam >> 16;
- break;
-
- case VK_LEFT:
- if (GetAsyncKeyState(VK_CONTROL) & 0x8000)
- info->view->process_char(DCH_CTRLLEFT);
- else
- info->view->process_char(DCH_LEFT);
- info->owner->ignore_char_lparam = lparam >> 16;
- break;
-
- case VK_RIGHT:
- if (GetAsyncKeyState(VK_CONTROL) & 0x8000)
- info->view->process_char(DCH_CTRLRIGHT);
- else
- info->view->process_char(DCH_RIGHT);
- info->owner->ignore_char_lparam = lparam >> 16;
- break;
-
- case VK_PRIOR:
- info->view->process_char(DCH_PUP);
- info->owner->ignore_char_lparam = lparam >> 16;
- break;
-
- case VK_NEXT:
- info->view->process_char(DCH_PDOWN);
- info->owner->ignore_char_lparam = lparam >> 16;
- break;
-
- case VK_HOME:
- if (GetAsyncKeyState(VK_CONTROL) & 0x8000)
- info->view->process_char(DCH_CTRLHOME);
- else
- info->view->process_char(DCH_HOME);
- info->owner->ignore_char_lparam = lparam >> 16;
- break;
-
- case VK_END:
- if (GetAsyncKeyState(VK_CONTROL) & 0x8000)
- info->view->process_char(DCH_CTRLEND);
- else
- info->view->process_char(DCH_END);
- info->owner->ignore_char_lparam = lparam >> 16;
- break;
-
- case VK_ESCAPE:
- if (info->owner->focuswnd != NULL)
- SetFocus(info->owner->focuswnd);
- info->owner->ignore_char_lparam = lparam >> 16;
- break;
-
- case VK_TAB:
- if (GetAsyncKeyState(VK_SHIFT) & 0x8000)
- debugwin_view_prev_view(info->owner, info);
- else
- debugwin_view_next_view(info->owner, info);
- info->owner->ignore_char_lparam = lparam >> 16;
- break;
- }
- }
- break;
- }
-
- // char: ignore chars associated with keys we've handled
- case WM_CHAR:
- {
- if (info->owner->ignore_char_lparam == (lparam >> 16))
- info->owner->ignore_char_lparam = 0;
- else if (waiting_for_debugger || !debugwin_seq_pressed(info->owner->machine()))
- {
- if (wparam >= 32 && wparam < 127 && info->view->cursor_supported())
- info->view->process_char(wparam);
- else
- return DefWindowProc(wnd, message, wparam, lparam);
- }
- break;
- }
-
- // gaining focus
- case WM_SETFOCUS:
- {
- if (info->view->cursor_supported())
- info->view->set_cursor_visible(true);
- break;
- }
-
- // losing focus
- case WM_KILLFOCUS:
- {
- if (info->view->cursor_supported())
- info->view->set_cursor_visible(false);
- break;
- }
-
- // mouse click
- case WM_LBUTTONDOWN:
- {
- if (info->view->cursor_supported())
- {
- debug_view_xy topleft = info->view->visible_position();
- debug_view_xy newpos;
- newpos.x = topleft.x + GET_X_LPARAM(lparam) / debug_font_width;
- newpos.y = topleft.y + GET_Y_LPARAM(lparam) / debug_font_height;
- info->view->set_cursor_position(newpos);
- SetFocus(wnd);
- }
- break;
- }
+ input_code code = seq[codenum];
- // hscroll
- case WM_HSCROLL:
+ if (code == input_seq::not_code)
{
- debug_view_xy topleft = info->view->visible_position();
- topleft.x = debugwin_view_process_scroll(info, LOWORD(wparam), (HWND)lparam);
- info->view->set_visible_position(topleft);
- info->owner->machine().debug_view().flush_osd_updates();
- break;
+ // handle NOT
+ invert = true;
}
-
- // vscroll
- case WM_VSCROLL:
+ else if (code == input_seq::or_code || code == input_seq::end_code)
{
- debug_view_xy topleft = info->view->visible_position();
- topleft.y = debugwin_view_process_scroll(info, LOWORD(wparam), (HWND)lparam);
- info->view->set_visible_position(topleft);
- info->owner->machine().debug_view().flush_osd_updates();
- break;
- }
-
- // everything else: defaults
- default:
- return DefWindowProc(wnd, message, wparam, lparam);
- }
-
- return 0;
-}
-
-
-
-//============================================================
-// debugwin_edit_proc
-//============================================================
-
-static LRESULT CALLBACK debugwin_edit_proc(HWND wnd, UINT message, WPARAM wparam, LPARAM lparam)
-{
- debugwin_info *info = (debugwin_info *)(FPTR)GetWindowLongPtr(wnd, GWLP_USERDATA);
- TCHAR buffer[MAX_EDIT_STRING];
-
- // handle a few messages
- switch (message)
- {
- // key down: handle navigation in the attached view
- case WM_SYSKEYDOWN:
- if (wparam != VK_F10)
- return CallWindowProc(info->original_editproc, wnd, message, wparam, lparam);
- // (fall through)
- case WM_KEYDOWN:
- switch (wparam)
- {
- case VK_UP:
- if (info->last_history < info->history_count - 1)
- info->last_history++;
- else
- info->last_history = 0;
- SendMessage(wnd, WM_SETTEXT, (WPARAM)0, (LPARAM)&info->history[info->last_history][0]);
- SendMessage(wnd, EM_SETSEL, (WPARAM)MAX_EDIT_STRING, (LPARAM)MAX_EDIT_STRING);
- break;
-
- case VK_DOWN:
- if (info->last_history > 0)
- info->last_history--;
- else if (info->history_count > 0)
- info->last_history = info->history_count - 1;
- else
- info->last_history = 0;
- SendMessage(wnd, WM_SETTEXT, (WPARAM)0, (LPARAM)&info->history[info->last_history][0]);
- SendMessage(wnd, EM_SETSEL, (WPARAM)MAX_EDIT_STRING, (LPARAM)MAX_EDIT_STRING);
- break;
-
- case VK_PRIOR:
- if (info->view[0].wnd && info->view[0].vscroll)
- SendMessage(info->view[0].wnd, WM_VSCROLL, SB_PAGELEFT, (LPARAM)info->view[0].vscroll);
- break;
-
- case VK_NEXT:
- if (info->view[0].wnd && info->view[0].vscroll)
- SendMessage(info->view[0].wnd, WM_VSCROLL, SB_PAGERIGHT, (LPARAM)info->view[0].vscroll);
- break;
-
- case VK_TAB:
- if (GetAsyncKeyState(VK_SHIFT) & 0x8000)
- debugwin_view_prev_view(info, NULL);
- else
- debugwin_view_next_view(info, NULL);
- info->ignore_char_lparam = lparam >> 16;
- break;
-
- default:
- if ((*info->handle_key)(info, wparam, lparam))
- info->ignore_char_lparam = lparam >> 16;
- else
- return CallWindowProc(info->original_editproc, wnd, message, wparam, lparam);
- break;
- }
- break;
-
- // char: handle the return key
- case WM_CHAR:
-
- // ignore chars associated with keys we've handled
- if (info->ignore_char_lparam == (lparam >> 16))
- info->ignore_char_lparam = 0;
- else if (waiting_for_debugger || !debugwin_seq_pressed(info->machine()))
- {
- switch (wparam)
- {
- case 13:
- {
- // fetch the text
- SendMessage(wnd, WM_GETTEXT, (WPARAM)ARRAY_LENGTH(buffer), (LPARAM)buffer);
-
- // add to the history if it's not a repeat of the last one
- if (buffer[0] != 0 && _tcscmp(buffer, &info->history[0][0]))
- {
- memmove(&info->history[1][0], &info->history[0][0], (HISTORY_LENGTH - 1) * MAX_EDIT_STRING);
- _tcscpy(&info->history[0][0], buffer);
- if (info->history_count < HISTORY_LENGTH)
- info->history_count++;
- }
- info->last_history = info->history_count - 1;
-
- // process
- if (info->process_string)
- {
- char *utf8_buffer = utf8_from_tstring(buffer);
- if (utf8_buffer != NULL)
- {
- (*info->process_string)(info, utf8_buffer);
- osd_free(utf8_buffer);
- }
- }
- break;
- }
-
- case 27:
- {
- // fetch the text
- SendMessage(wnd, WM_GETTEXT, (WPARAM)sizeof(buffer), (LPARAM)buffer);
-
- // if it's not empty, clear the text
- if (_tcslen(buffer) > 0)
- {
- info->ignore_char_lparam = lparam >> 16;
- SendMessage(wnd, WM_SETTEXT, (WPARAM)0, (LPARAM)info->edit_defstr);
- }
- break;
- }
-
- default:
- return CallWindowProc(info->original_editproc, wnd, message, wparam, lparam);
- }
- }
- break;
-
- // everything else: defaults
- default:
- return CallWindowProc(info->original_editproc, wnd, message, wparam, lparam);
- }
-
- return 0;
-}
-
-
+ // handle OR and END
-//============================================================
-// generic_create_window
-//============================================================
-
-#ifdef UNUSED_FUNCTION
-static void generic_create_window(running_machine &machine, debug_view_type type)
-{
- debugwin_info *info;
- char title[256];
-
- // create the window
- _snprintf(title, ARRAY_LENGTH(title), "Debug: %s [%s]", machine.system().description, machine.system().name);
- info = debugwin_window_create(machine, title, NULL);
- if (info == NULL || !debugwin_view_create(info, 0, type))
- return;
-
- // set the child function
- info->recompute_children = generic_recompute_children;
-
- // recompute the children once to get the maxwidth
- generic_recompute_children(info);
-
- // position the window and recompute children again
- SetWindowPos(info->wnd, HWND_TOP, 100, 100, info->maxwidth, 200, SWP_SHOWWINDOW);
- generic_recompute_children(info);
-}
-#endif
-
-
-
-//============================================================
-// generic_recompute_children
-//============================================================
-
-static void generic_recompute_children(debugwin_info *info)
-{
- debug_view_xy totalsize = info->view[0].view->total_size();
- RECT parent;
- RECT bounds;
-
- // compute a client rect
- bounds.top = bounds.left = 0;
- bounds.right = totalsize.x * debug_font_width + vscroll_width + 2 * EDGE_WIDTH;
- bounds.bottom = 200;
- AdjustWindowRectEx(&bounds, DEBUG_WINDOW_STYLE, FALSE, DEBUG_WINDOW_STYLE_EX);
-
- // clamp the min/max size
- info->maxwidth = bounds.right - bounds.left;
-
- // get the parent's dimensions
- GetClientRect(info->wnd, &parent);
-
- // view gets the remaining space
- InflateRect(&parent, -EDGE_WIDTH, -EDGE_WIDTH);
- debugwin_view_set_bounds(&info->view[0], info->wnd, &parent);
-}
-
-
-
-//============================================================
-// log_create_window
-//============================================================
-
-static void log_create_window(running_machine &machine)
-{
- debug_view_xy totalsize;
- debugwin_info *info;
- char title[256];
- RECT bounds;
-
- // create the window
- _snprintf(title, ARRAY_LENGTH(title), "Errorlog: %s [%s]", machine.system().description, machine.system().name);
- info = debugwin_window_create(machine, title, NULL);
- if (info == NULL || !debugwin_view_create(info, 0, DVT_LOG))
- return;
-
- // set the child function
- info->recompute_children = generic_recompute_children;
-
- // get the view width
- totalsize = info->view[0].view->total_size();
-
- // compute a client rect
- bounds.top = bounds.left = 0;
- bounds.right = totalsize.x * debug_font_width + vscroll_width + 2 * EDGE_WIDTH;
- bounds.bottom = 200;
- AdjustWindowRectEx(&bounds, DEBUG_WINDOW_STYLE, FALSE, DEBUG_WINDOW_STYLE_EX);
-
- // clamp the min/max size
- info->maxwidth = bounds.right - bounds.left;
-
- // position the window at the bottom-right
- SetWindowPos(info->wnd, HWND_TOP,
- 100, 100,
- bounds.right - bounds.left, bounds.bottom - bounds.top,
- SWP_SHOWWINDOW);
-
- // recompute the children and set focus on the edit box
- generic_recompute_children(info);
-}
-
-
-
-//============================================================
-// memory_create_window
-//============================================================
-
-static void memory_create_window(running_machine &machine)
-{
- device_t *curcpu = debug_cpu_get_visible_cpu(machine);
- debugwin_info *info;
- HMENU optionsmenu;
-
- // create the window
- info = debugwin_window_create(machine, "Memory", NULL);
- if (info == NULL || !debugwin_view_create(info, 0, DVT_MEMORY))
- return;
-
- // set the handlers
- info->handle_command = memory_handle_command;
- info->handle_key = memory_handle_key;
- info->update_menu = memory_update_menu;
-
- // create the options menu
- 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_DISABLED | MF_SEPARATOR, 0, TEXT(""));
- AppendMenu(optionsmenu, MF_ENABLED, ID_LOGICAL_ADDRESSES, TEXT("Logical Addresses\tCtrl+L"));
- AppendMenu(optionsmenu, MF_ENABLED, ID_PHYSICAL_ADDRESSES, TEXT("Physical Addresses\tCtrl+Y"));
- AppendMenu(optionsmenu, MF_DISABLED | MF_SEPARATOR, 0, TEXT(""));
- AppendMenu(optionsmenu, MF_ENABLED, ID_REVERSE_VIEW, TEXT("Reverse View\tCtrl+R"));
- AppendMenu(optionsmenu, MF_DISABLED | MF_SEPARATOR, 0, TEXT(""));
- AppendMenu(optionsmenu, MF_ENABLED, ID_INCREASE_MEM_WIDTH, TEXT("Increase bytes per line\tCtrl+P"));
- AppendMenu(optionsmenu, MF_ENABLED, ID_DECREASE_MEM_WIDTH, TEXT("Decrease bytes per line\tCtrl+O"));
- AppendMenu(GetMenu(info->wnd), MF_ENABLED | MF_POPUP, (UINT_PTR)optionsmenu, TEXT("Options"));
-
- // set up the view to track the initial expression
- downcast<debug_view_memory *>(info->view[0].view)->set_expression("0");
- strcpy(info->edit_defstr, "0");
-
- // create an edit box and override its key handling
- info->editwnd = CreateWindowEx(EDIT_BOX_STYLE_EX, TEXT("EDIT"), NULL, EDIT_BOX_STYLE,
- 0, 0, 100, 100, info->wnd, NULL, GetModuleHandle(NULL), NULL);
- info->original_editproc = (WNDPROC)(FPTR)GetWindowLongPtr(info->editwnd, GWLP_WNDPROC);
- SetWindowLongPtr(info->editwnd, GWLP_USERDATA, (LONG_PTR)info);
- SetWindowLongPtr(info->editwnd, GWLP_WNDPROC, (LONG_PTR)debugwin_edit_proc);
- SendMessage(info->editwnd, WM_SETFONT, (WPARAM)debug_font, (LPARAM)FALSE);
- SendMessage(info->editwnd, WM_SETTEXT, (WPARAM)0, (LPARAM)TEXT("0"));
- SendMessage(info->editwnd, EM_LIMITTEXT, (WPARAM)MAX_EDIT_STRING, (LPARAM)0);
- SendMessage(info->editwnd, EM_SETSEL, (WPARAM)0, (LPARAM)-1);
-
- // create a combo box
- info->otherwnd[0] = CreateWindowEx(COMBO_BOX_STYLE_EX, TEXT("COMBOBOX"), NULL, COMBO_BOX_STYLE,
- 0, 0, 100, 1000, info->wnd, NULL, GetModuleHandle(NULL), NULL);
- SetWindowLongPtr(info->otherwnd[0], GWLP_USERDATA, (LONG_PTR)info);
- SendMessage(info->otherwnd[0], WM_SETFONT, (WPARAM)debug_font, (LPARAM)FALSE);
-
- // populate the combobox
- int maxlength = 0;
- for (const debug_view_source *source = info->view[0].view->first_source(); source != NULL; source = source->next())
- {
- int length = strlen(source->name());
- if (length > maxlength)
- maxlength = length;
- TCHAR *t_name = tstring_from_utf8(source->name());
- SendMessage(info->otherwnd[0], CB_ADDSTRING, 0, (LPARAM)t_name);
- osd_free(t_name);
- }
- const debug_view_source *source = info->view[0].view->source_for_device(curcpu);
- SendMessage(info->otherwnd[0], CB_SETCURSEL, info->view[0].view->source_list().indexof(*source), 0);
- SendMessage(info->otherwnd[0], CB_SETDROPPEDWIDTH, (maxlength + 2) * debug_font_width + vscroll_width, 0);
- info->view[0].view->set_source(*source);
-
- // set the child functions
- info->recompute_children = memory_recompute_children;
- info->process_string = memory_process_string;
-
- // set the caption
- memory_update_caption(machine, info->wnd);
-
- // recompute the children once to get the maxwidth
- memory_recompute_children(info);
-
- // position the window and recompute children again
- SetWindowPos(info->wnd, HWND_TOP, 100, 100, info->maxwidth, 200, SWP_SHOWWINDOW);
- memory_recompute_children(info);
-
- // mark the edit box as the default focus and set it
- info->focuswnd = info->editwnd;
- SetFocus(info->editwnd);
-}
-
-
-
-//============================================================
-// memory_recompute_children
-//============================================================
-
-static void memory_recompute_children(debugwin_info *info)
-{
- debug_view_xy totalsize = info->view[0].view->total_size();
- RECT parent, memrect, editrect, comborect;
- RECT bounds;
-
- // compute a client rect
- bounds.top = bounds.left = 0;
- bounds.right = totalsize.x * debug_font_width + vscroll_width + 2 * EDGE_WIDTH;
- bounds.bottom = 200;
- AdjustWindowRectEx(&bounds, DEBUG_WINDOW_STYLE, FALSE, DEBUG_WINDOW_STYLE_EX);
-
- // clamp the min/max size
- info->maxwidth = bounds.right - bounds.left;
-
- // get the parent's dimensions
- GetClientRect(info->wnd, &parent);
-
- // edit box gets half of the width
- editrect.top = parent.top + EDGE_WIDTH;
- editrect.bottom = editrect.top + debug_font_height + 4;
- editrect.left = parent.left + EDGE_WIDTH;
- editrect.right = parent.left + (parent.right - parent.left) / 2 - EDGE_WIDTH;
-
- // combo box gets the other half of the width
- comborect.top = editrect.top;
- comborect.bottom = editrect.bottom;
- comborect.left = editrect.right + 2 * EDGE_WIDTH;
- comborect.right = parent.right - EDGE_WIDTH;
-
- // memory view gets the rest
- memrect.top = editrect.bottom + 2 * EDGE_WIDTH;
- memrect.bottom = parent.bottom - EDGE_WIDTH;
- memrect.left = parent.left + EDGE_WIDTH;
- memrect.right = parent.right - EDGE_WIDTH;
-
- // set the bounds of things
- debugwin_view_set_bounds(&info->view[0], info->wnd, &memrect);
- smart_set_window_bounds(info->editwnd, info->wnd, &editrect);
- smart_set_window_bounds(info->otherwnd[0], info->wnd, &comborect);
-}
-
-
-
-//============================================================
-// memory_process_string
-//============================================================
-
-static void memory_process_string(debugwin_info *info, const char *string)
-{
- // set the string to the memory view
- downcast<debug_view_memory *>(info->view[0].view)->set_expression(string);
-
- // select everything in the edit text box
- SendMessage(info->editwnd, EM_SETSEL, (WPARAM)0, (LPARAM)-1);
-
- // update the default string to match
- strncpy(info->edit_defstr, string, sizeof(info->edit_defstr) - 1);
-}
-
-
-
-//============================================================
-// memory_update_menu
-//============================================================
-
-static void memory_update_menu(debugwin_info *info)
-{
- debug_view_memory *memview = downcast<debug_view_memory *>(info->view[0].view);
- CheckMenuItem(GetMenu(info->wnd), ID_1_BYTE_CHUNKS, MF_BYCOMMAND | (memview->bytes_per_chunk() == 1 ? MF_CHECKED : MF_UNCHECKED));
- CheckMenuItem(GetMenu(info->wnd), ID_2_BYTE_CHUNKS, MF_BYCOMMAND | (memview->bytes_per_chunk() == 2 ? MF_CHECKED : MF_UNCHECKED));
- CheckMenuItem(GetMenu(info->wnd), ID_4_BYTE_CHUNKS, MF_BYCOMMAND | (memview->bytes_per_chunk() == 4 ? MF_CHECKED : MF_UNCHECKED));
- CheckMenuItem(GetMenu(info->wnd), ID_8_BYTE_CHUNKS, MF_BYCOMMAND | (memview->bytes_per_chunk() == 8 ? MF_CHECKED : MF_UNCHECKED));
- CheckMenuItem(GetMenu(info->wnd), ID_LOGICAL_ADDRESSES, MF_BYCOMMAND | (memview->physical() ? MF_UNCHECKED : MF_CHECKED));
- CheckMenuItem(GetMenu(info->wnd), ID_PHYSICAL_ADDRESSES, MF_BYCOMMAND | (memview->physical() ? MF_CHECKED : MF_UNCHECKED));
- CheckMenuItem(GetMenu(info->wnd), ID_REVERSE_VIEW, MF_BYCOMMAND | (memview->reverse() ? MF_CHECKED : MF_UNCHECKED));
-}
-
-
-
-//============================================================
-// memory_handle_command
-//============================================================
-
-static int memory_handle_command(debugwin_info *info, WPARAM wparam, LPARAM lparam)
-{
- debug_view_memory *memview = downcast<debug_view_memory *>(info->view[0].view);
- switch (HIWORD(wparam))
- {
- // combo box selection changed
- case CBN_SELCHANGE:
- {
- int sel = SendMessage((HWND)lparam, CB_GETCURSEL, 0, 0);
- if (sel != CB_ERR)
- {
- memview->set_source(*memview->source_list().find(sel));
- memory_update_caption(info->machine(), info->wnd);
+ // if we have a positive result from the previous set, we're done
+ if (result || code == input_seq::end_code)
+ break;
- // reset the focus
- SetFocus(info->focuswnd);
- return 1;
- }
- break;
+ // otherwise, reset our state
+ result = false;
+ invert = false;
+ first = true;
}
-
- // menu selections
- case 0:
- switch (LOWORD(wparam))
- {
- case ID_1_BYTE_CHUNKS:
- memview->set_bytes_per_chunk(1);
- return 1;
-
- case ID_2_BYTE_CHUNKS:
- memview->set_bytes_per_chunk(2);
- return 1;
-
- case ID_4_BYTE_CHUNKS:
- memview->set_bytes_per_chunk(4);
- return 1;
-
- case ID_8_BYTE_CHUNKS:
- memview->set_bytes_per_chunk(8);
- return 1;
-
- case ID_LOGICAL_ADDRESSES:
- memview->set_physical(false);
- return 1;
-
- case ID_PHYSICAL_ADDRESSES:
- memview->set_physical(true);
- return 1;
-
- case ID_REVERSE_VIEW:
- memview->set_reverse(!memview->reverse());
- return 1;
-
- case ID_INCREASE_MEM_WIDTH:
- memview->set_chunks_per_row(memview->chunks_per_row() + 1);
- return 1;
-
- case ID_DECREASE_MEM_WIDTH:
- memview->set_chunks_per_row(memview->chunks_per_row() - 1);
- return 1;
- }
- break;
- }
- return global_handle_command(info, wparam, lparam);
-}
-
-
-
-//============================================================
-// memory_handle_key
-//============================================================
-
-static int memory_handle_key(debugwin_info *info, WPARAM wparam, LPARAM lparam)
-{
- if (GetAsyncKeyState(VK_CONTROL) & 0x8000)
- {
- switch (wparam)
+ else
{
- case '1':
- SendMessage(info->wnd, WM_COMMAND, ID_1_BYTE_CHUNKS, 0);
- return 1;
-
- case '2':
- SendMessage(info->wnd, WM_COMMAND, ID_2_BYTE_CHUNKS, 0);
- return 1;
-
- case '4':
- SendMessage(info->wnd, WM_COMMAND, ID_4_BYTE_CHUNKS, 0);
- return 1;
-
- case '8':
- SendMessage(info->wnd, WM_COMMAND, ID_8_BYTE_CHUNKS, 0);
- return 1;
-
- case 'L':
- SendMessage(info->wnd, WM_COMMAND, ID_LOGICAL_ADDRESSES, 0);
- return 1;
-
- case 'Y':
- SendMessage(info->wnd, WM_COMMAND, ID_PHYSICAL_ADDRESSES, 0);
- return 1;
+ // handle everything else as a series of ANDs
+ int const vkey = wininput_vkey_for_mame_code(code);
+ bool const pressed = (vkey != 0) && ((GetAsyncKeyState(vkey) & 0x8000) != 0);
- case 'R':
- SendMessage(info->wnd, WM_COMMAND, ID_REVERSE_VIEW, 0);
- return 1;
-
- case 'P':
- SendMessage(info->wnd, WM_COMMAND, ID_INCREASE_MEM_WIDTH, 0);
- return 1;
+ if (first) // if this is the first in the sequence, result is set equal
+ result = pressed ^ invert;
+ else if (result) // further values are ANDed
+ result = result && (pressed ^ invert);
- case 'O':
- SendMessage(info->wnd, WM_COMMAND, ID_DECREASE_MEM_WIDTH, 0);
- return 1;
+ // no longer first, and clear the invert flag
+ first = invert = false;
}
}
- return global_handle_key(info, wparam, lparam);
-}
-
-
-
-//============================================================
-// memory_update_caption
-//============================================================
-
-static void memory_update_caption(running_machine &machine, HWND wnd)
-{
- debugwin_info *info = (debugwin_info *)(FPTR)GetWindowLongPtr(wnd, GWLP_USERDATA);
- astring title;
-
- title.printf("Memory: %s", info->view[0].view->source()->name());
- win_set_window_text_utf8(wnd, title);
-}
-
-
-
-//============================================================
-// disasm_create_window
-//============================================================
-
-static void disasm_create_window(running_machine &machine)
-{
- device_t *curcpu = debug_cpu_get_visible_cpu(machine);
- debugwin_info *info;
- HMENU optionsmenu;
-
- // create the window
- info = debugwin_window_create(machine, "Disassembly", NULL);
- if (info == NULL || !debugwin_view_create(info, 0, DVT_DISASSEMBLY))
- return;
-
- // create the options menu
- optionsmenu = CreatePopupMenu();
- AppendMenu(optionsmenu, MF_ENABLED, ID_TOGGLE_BREAKPOINT, TEXT("Set breakpoint at cursor\tF9"));
- AppendMenu(optionsmenu, MF_ENABLED, ID_RUN_TO_CURSOR, TEXT("Run to cursor\tF4"));
- AppendMenu(optionsmenu, MF_DISABLED | MF_SEPARATOR, 0, TEXT(""));
- AppendMenu(optionsmenu, MF_ENABLED, ID_SHOW_RAW, TEXT("Raw opcodes\tCtrl+R"));
- AppendMenu(optionsmenu, MF_ENABLED, ID_SHOW_ENCRYPTED, TEXT("Encrypted opcodes\tCtrl+E"));
- AppendMenu(optionsmenu, MF_ENABLED, ID_SHOW_COMMENTS, TEXT("Comments\tCtrl+M"));
- AppendMenu(GetMenu(info->wnd), MF_ENABLED | MF_POPUP, (UINT_PTR)optionsmenu, TEXT("Options"));
-
- // set the handlers
- info->handle_command = disasm_handle_command;
- info->handle_key = disasm_handle_key;
- info->update_menu = disasm_update_menu;
-
- // set up the view to track the initial expression
- downcast<debug_view_disasm *>(info->view[0].view)->set_expression("curpc");
- strcpy(info->edit_defstr, "curpc");
-
- // create an edit box and override its key handling
- info->editwnd = CreateWindowEx(EDIT_BOX_STYLE_EX, TEXT("EDIT"), NULL, EDIT_BOX_STYLE,
- 0, 0, 100, 100, info->wnd, NULL, GetModuleHandle(NULL), NULL);
- info->original_editproc = (WNDPROC)(FPTR)GetWindowLongPtr(info->editwnd, GWLP_WNDPROC);
- SetWindowLongPtr(info->editwnd, GWLP_USERDATA, (LONG_PTR)info);
- SetWindowLongPtr(info->editwnd, GWLP_WNDPROC, (LONG_PTR)debugwin_edit_proc);
- SendMessage(info->editwnd, WM_SETFONT, (WPARAM)debug_font, (LPARAM)FALSE);
- SendMessage(info->editwnd, WM_SETTEXT, (WPARAM)0, (LPARAM)TEXT("curpc"));
- SendMessage(info->editwnd, EM_LIMITTEXT, (WPARAM)MAX_EDIT_STRING, (LPARAM)0);
- SendMessage(info->editwnd, EM_SETSEL, (WPARAM)0, (LPARAM)-1);
-
- // create a combo box
- info->otherwnd[0] = CreateWindowEx(COMBO_BOX_STYLE_EX, TEXT("COMBOBOX"), NULL, COMBO_BOX_STYLE,
- 0, 0, 100, 1000, info->wnd, NULL, GetModuleHandle(NULL), NULL);
- SetWindowLongPtr(info->otherwnd[0], GWLP_USERDATA, (LONG_PTR)info);
- SendMessage(info->otherwnd[0], WM_SETFONT, (WPARAM)debug_font, (LPARAM)FALSE);
-
- // populate the combobox
- int maxlength = 0;
- for (const debug_view_source *source = info->view[0].view->first_source(); source != NULL; source = source->next())
- {
- int length = strlen(source->name());
- if (length > maxlength)
- maxlength = length;
- TCHAR *t_name = tstring_from_utf8(source->name());
- SendMessage(info->otherwnd[0], CB_ADDSTRING, 0, (LPARAM)t_name);
- osd_free(t_name);
- }
- const debug_view_source *source = info->view[0].view->source_for_device(curcpu);
- SendMessage(info->otherwnd[0], CB_SETCURSEL, info->view[0].view->source_list().indexof(*source), 0);
- SendMessage(info->otherwnd[0], CB_SETDROPPEDWIDTH, (maxlength + 2) * debug_font_width + vscroll_width, 0);
- info->view[0].view->set_source(*source);
-
- // set the child functions
- info->recompute_children = disasm_recompute_children;
- info->process_string = disasm_process_string;
-
- // set the caption
- disasm_update_caption(machine, info->wnd);
-
- // recompute the children once to get the maxwidth
- disasm_recompute_children(info);
-
- // position the window and recompute children again
- SetWindowPos(info->wnd, HWND_TOP, 100, 100, info->maxwidth, 200, SWP_SHOWWINDOW);
- disasm_recompute_children(info);
-
- // mark the edit box as the default focus and set it
- info->focuswnd = info->editwnd;
- SetFocus(info->editwnd);
-}
-
-
-
-//============================================================
-// disasm_recompute_children
-//============================================================
-
-static void disasm_recompute_children(debugwin_info *info)
-{
- debug_view_xy totalsize = info->view[0].view->total_size();
- RECT parent, dasmrect, editrect, comborect;
- RECT bounds;
- // compute a client rect
- bounds.top = bounds.left = 0;
- bounds.right = totalsize.x * debug_font_width + vscroll_width + 2 * EDGE_WIDTH;
- bounds.bottom = 200;
- AdjustWindowRectEx(&bounds, DEBUG_WINDOW_STYLE, FALSE, DEBUG_WINDOW_STYLE_EX);
-
- // clamp the min/max size
- info->maxwidth = bounds.right - bounds.left;
-
- // get the parent's dimensions
- GetClientRect(info->wnd, &parent);
-
- // edit box gets half of the width
- editrect.top = parent.top + EDGE_WIDTH;
- editrect.bottom = editrect.top + debug_font_height + 4;
- editrect.left = parent.left + EDGE_WIDTH;
- editrect.right = parent.left + (parent.right - parent.left) / 2 - EDGE_WIDTH;
-
- // combo box gets the other half of the width
- comborect.top = editrect.top;
- comborect.bottom = editrect.bottom;
- comborect.left = editrect.right + 2 * EDGE_WIDTH;
- comborect.right = parent.right - EDGE_WIDTH;
-
- // disasm view gets the rest
- dasmrect.top = editrect.bottom + 2 * EDGE_WIDTH;
- dasmrect.bottom = parent.bottom - EDGE_WIDTH;
- dasmrect.left = parent.left + EDGE_WIDTH;
- dasmrect.right = parent.right - EDGE_WIDTH;
-
- // set the bounds of things
- debugwin_view_set_bounds(&info->view[0], info->wnd, &dasmrect);
- smart_set_window_bounds(info->editwnd, info->wnd, &editrect);
- smart_set_window_bounds(info->otherwnd[0], info->wnd, &comborect);
+ // return the result if we queried at least one switch
+ return result;
}
-
-//============================================================
-// disasm_process_string
-//============================================================
-
-static void disasm_process_string(debugwin_info *info, const char *string)
+void debugger_windows::remove_window(debugwin_info &info)
{
- // set the string to the disasm view
- downcast<debug_view_disasm *>(info->view[0].view)->set_expression(string);
-
- // select everything in the edit text box
- SendMessage(info->editwnd, EM_SETSEL, (WPARAM)0, (LPARAM)-1);
-
- // update the default string to match
- strncpy(info->edit_defstr, string, sizeof(info->edit_defstr) - 1);
+ m_window_list.remove(info);
}
-
-//============================================================
-// disasm_update_menu
-//============================================================
-
-static void disasm_update_menu(debugwin_info *info)
+void debugger_windows::show_all()
{
- disasm_right_column rightcol = downcast<debug_view_disasm *>(info->view[0].view)->right_column();
- CheckMenuItem(GetMenu(info->wnd), ID_SHOW_RAW, MF_BYCOMMAND | (rightcol == DASM_RIGHTCOL_RAW ? MF_CHECKED : MF_UNCHECKED));
- CheckMenuItem(GetMenu(info->wnd), ID_SHOW_ENCRYPTED, MF_BYCOMMAND | (rightcol == DASM_RIGHTCOL_ENCRYPTED ? MF_CHECKED : MF_UNCHECKED));
- CheckMenuItem(GetMenu(info->wnd), ID_SHOW_COMMENTS, MF_BYCOMMAND | (rightcol == DASM_RIGHTCOL_COMMENTS ? MF_CHECKED : MF_UNCHECKED));
+ for (debugwin_info *info = m_window_list.first(); info != NULL; info = info->next())
+ info->show();
}
-
-//============================================================
-// disasm_handle_command
-//============================================================
-
-static int disasm_handle_command(debugwin_info *info, WPARAM wparam, LPARAM lparam)
+void debugger_windows::hide_all()
{
- debug_view_disasm *dasmview = downcast<debug_view_disasm *>(info->view[0].view);
- char command[64];
-
- switch (HIWORD(wparam))
- {
- // combo box selection changed
- case CBN_SELCHANGE:
- {
- int sel = SendMessage((HWND)lparam, CB_GETCURSEL, 0, 0);
- if (sel != CB_ERR)
- {
- dasmview->set_source(*dasmview->source_list().find(sel));
- disasm_update_caption(info->machine(), info->wnd);
-
- // reset the focus
- SetFocus(info->focuswnd);
- return 1;
- }
- break;
- }
-
- // menu selections
- case 0:
- switch (LOWORD(wparam))
- {
- case ID_SHOW_RAW:
- dasmview->set_right_column(DASM_RIGHTCOL_RAW);
- (*info->recompute_children)(info);
- return 1;
-
- case ID_SHOW_ENCRYPTED:
- dasmview->set_right_column(DASM_RIGHTCOL_ENCRYPTED);
- (*info->recompute_children)(info);
- return 1;
-
- case ID_SHOW_COMMENTS:
- dasmview->set_right_column(DASM_RIGHTCOL_COMMENTS);
- (*info->recompute_children)(info);
- return 1;
-
- case ID_RUN_TO_CURSOR:
- if (dasmview->cursor_visible() && debug_cpu_get_visible_cpu(info->machine()) == dasmview->source()->device())
- {
- offs_t address = dasmview->selected_address();
- sprintf(command, "go 0x%X", address);
- debug_console_execute_command(info->machine(), command, 1);
- }
- return 1;
-
- case ID_TOGGLE_BREAKPOINT:
- if (dasmview->cursor_visible() && debug_cpu_get_visible_cpu(info->machine()) == dasmview->source()->device())
- {
- offs_t address = dasmview->selected_address();
- device_debug *debug = dasmview->source()->device()->debug();
- INT32 bpindex = -1;
-
- /* first find an existing breakpoint at this address */
- for (device_debug::breakpoint *bp = debug->breakpoint_first(); bp != NULL; bp = bp->next())
- if (address == bp->address())
- {
- bpindex = bp->index();
- break;
- }
-
- /* if it doesn't exist, add a new one */
- if (bpindex == -1)
- sprintf(command, "bpset 0x%X", address);
- else
- sprintf(command, "bpclear 0x%X", bpindex);
- debug_console_execute_command(info->machine(), command, 1);
- }
- return 1;
- }
- break;
- }
- return global_handle_command(info, wparam, lparam);
+ SetForegroundWindow(win_window_list->m_hwnd);
+ for (debugwin_info *info = m_window_list.first(); info != NULL; info = info->next())
+ info->hide();
}
-
-//============================================================
-// disasm_handle_key
-//============================================================
-
-static int disasm_handle_key(debugwin_info *info, WPARAM wparam, LPARAM lparam)
+template <typename T> T *debugger_windows::create_window()
{
- if (GetAsyncKeyState(VK_CONTROL) & 0x8000)
- {
- switch (wparam)
- {
- case 'R':
- SendMessage(info->wnd, WM_COMMAND, ID_SHOW_RAW, 0);
- return 1;
-
- case 'E':
- SendMessage(info->wnd, WM_COMMAND, ID_SHOW_ENCRYPTED, 0);
- return 1;
-
- case 'N':
- SendMessage(info->wnd, WM_COMMAND, ID_SHOW_COMMENTS, 0);
- return 1;
- }
- }
-
- switch (wparam)
- {
- /* ajg - steals the F4 from the global key handler - but ALT+F4 didn't work anyways ;) */
- case VK_F4:
- SendMessage(info->wnd, WM_COMMAND, ID_RUN_TO_CURSOR, 0);
- return 1;
-
- case VK_F9:
- SendMessage(info->wnd, WM_COMMAND, ID_TOGGLE_BREAKPOINT, 0);
- return 1;
-
- case VK_RETURN:
- if (info->view[0].view->cursor_visible())
- {
- SendMessage(info->wnd, WM_COMMAND, ID_STEP, 0);
- return 1;
- }
- break;
- }
-
- return global_handle_key(info, wparam, lparam);
-}
-
-
-
-//============================================================
-// disasm_update_caption
-//============================================================
-
-static void disasm_update_caption(running_machine &machine, HWND wnd)
-{
- debugwin_info *info = (debugwin_info *)(FPTR)GetWindowLongPtr(wnd, GWLP_USERDATA);
- astring title;
-
- title.printf("Disassembly: %s", info->view[0].view->source()->name());
- win_set_window_text_utf8(wnd, title);
-}
-
-
-enum
-{
- DEVOPTION_OPEN,
- DEVOPTION_CREATE,
- DEVOPTION_CLOSE,
- DEVOPTION_CASSETTE_STOPPAUSE,
- DEVOPTION_CASSETTE_PLAY,
- DEVOPTION_CASSETTE_RECORD,
- DEVOPTION_CASSETTE_REWIND,
- DEVOPTION_CASSETTE_FASTFORWARD,
- DEVOPTION_MAX
-};
-
-//============================================================
-// memory_update_menu
-//============================================================
-
-static void image_update_menu(debugwin_info *info)
-{
- UINT32 cnt = 0;
- HMENU devicesmenu;
-
- DeleteMenu(GetMenu(info->wnd), 2, MF_BYPOSITION);
-
- // create the image menu
- devicesmenu = CreatePopupMenu();
- image_interface_iterator iter(info->machine().root_device());
- for (device_image_interface *img = iter.first(); img != NULL; img = iter.next())
- {
- astring temp;
- UINT flags_for_exists;
- UINT flags_for_writing;
- HMENU devicesubmenu = CreatePopupMenu();
-
- UINT_PTR new_item = ID_DEVICE_OPTIONS + (cnt * DEVOPTION_MAX);
-
- flags_for_exists = MF_ENABLED | MF_STRING;
-
- if (!img->exists())
- flags_for_exists |= MF_GRAYED;
-
- flags_for_writing = flags_for_exists;
- if (img->is_readonly())
- flags_for_writing |= MF_GRAYED;
-
- AppendMenu(devicesubmenu, MF_STRING, new_item + DEVOPTION_OPEN, TEXT("Mount..."));
-
- /*if (img->is_creatable())
- AppendMenu(devicesubmenu, MF_STRING, new_item + DEVOPTION_CREATE, TEXT("Create..."));
- */
- AppendMenu(devicesubmenu, flags_for_exists, new_item + DEVOPTION_CLOSE, TEXT("Unmount"));
-
- if (img->device().type() == CASSETTE)
- {
- cassette_state state;
- state = (cassette_state)(img->exists() ? (dynamic_cast<cassette_image_device*>(&img->device())->get_state() & CASSETTE_MASK_UISTATE) : CASSETTE_STOPPED);
- AppendMenu(devicesubmenu, MF_SEPARATOR, 0, NULL);
- 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"));
- AppendMenu(devicesubmenu, flags_for_writing | ((state == CASSETTE_RECORD) ? MF_CHECKED : 0), new_item + DEVOPTION_CASSETTE_RECORD, TEXT("Record"));
- AppendMenu(devicesubmenu, flags_for_exists, new_item + DEVOPTION_CASSETTE_REWIND, TEXT("Rewind"));
- AppendMenu(devicesubmenu, flags_for_exists, new_item + DEVOPTION_CASSETTE_FASTFORWARD, TEXT("Fast Forward"));
- }
-
- temp.format("%s :%s", img->device().name(), img->exists() ? img->filename() : "[empty slot]");
-
- AppendMenu(devicesmenu, MF_ENABLED | MF_POPUP, (UINT_PTR)devicesubmenu, tstring_from_utf8(temp.cstr()));
-
- cnt++;
- }
- AppendMenu(GetMenu(info->wnd), MF_ENABLED | MF_POPUP, (UINT_PTR)devicesmenu, TEXT("Images"));
-
-}
-
-//============================================================
-// console_create_window
-//============================================================
-
-void console_create_window(running_machine &machine)
-{
- debugwin_info *info;
- int bestwidth, bestheight;
- RECT bounds, work_bounds;
- HMENU optionsmenu;
- UINT32 conchars;
-
- // create the window
- info = debugwin_window_create(machine, "Debug", NULL);
- if (info == NULL)
- return;
- main_console = info;
-
- // create the views
- if (!debugwin_view_create(info, 0, DVT_DISASSEMBLY))
- goto cleanup;
- if (!debugwin_view_create(info, 1, DVT_STATE))
- goto cleanup;
- if (!debugwin_view_create(info, 2, DVT_CONSOLE))
- goto cleanup;
-
- // create the options menu
- optionsmenu = CreatePopupMenu();
- AppendMenu(optionsmenu, MF_ENABLED, ID_TOGGLE_BREAKPOINT, TEXT("Set breakpoint at cursor\tF9"));
- AppendMenu(optionsmenu, MF_ENABLED, ID_RUN_TO_CURSOR, TEXT("Run to cursor\tF4"));
- AppendMenu(optionsmenu, MF_DISABLED | MF_SEPARATOR, 0, TEXT(""));
- AppendMenu(optionsmenu, MF_ENABLED, ID_SHOW_RAW, TEXT("Raw opcodes\tCtrl+R"));
- AppendMenu(optionsmenu, MF_ENABLED, ID_SHOW_ENCRYPTED, TEXT("Encrypted opcodes\tCtrl+E"));
- AppendMenu(optionsmenu, MF_ENABLED, ID_SHOW_COMMENTS, TEXT("Comments\tCtrl+N"));
- AppendMenu(GetMenu(info->wnd), MF_ENABLED | MF_POPUP, (UINT_PTR)optionsmenu, TEXT("Options"));
-
- // Add image menu only if image devices exist
- {
- image_interface_iterator iter(machine.root_device());
- if (iter.first() != NULL) {
- info->update_menu = image_update_menu;
- image_update_menu(info);
- }
- }
-
- // set the handlers
- info->handle_command = disasm_handle_command;
- info->handle_key = disasm_handle_key;
-
- // create an edit box and override its key handling
- info->editwnd = CreateWindowEx(EDIT_BOX_STYLE_EX, TEXT("EDIT"), NULL, EDIT_BOX_STYLE,
- 0, 0, 100, 100, info->wnd, NULL, GetModuleHandle(NULL), NULL);
- info->original_editproc = (WNDPROC)(FPTR)GetWindowLongPtr(info->editwnd, GWLP_WNDPROC);
- SetWindowLongPtr(info->editwnd, GWLP_USERDATA, (LONG_PTR)info);
- SetWindowLongPtr(info->editwnd, GWLP_WNDPROC, (LONG_PTR)debugwin_edit_proc);
- SendMessage(info->editwnd, WM_SETFONT, (WPARAM)debug_font, (LPARAM)FALSE);
- SendMessage(info->editwnd, EM_LIMITTEXT, (WPARAM)MAX_EDIT_STRING, (LPARAM)0);
-
- // set the child functions
- info->recompute_children = console_recompute_children;
- info->process_string = console_process_string;
-
- // loop over all register views and get the maximum size
- main_console_regwidth = 0;
- for (const debug_view_source *source = info->view[1].view->first_source(); source != NULL; source = source->next())
- {
- UINT32 regchars;
-
- // set the view and fetch the width
- info->view[1].view->set_source(*source);
- regchars = info->view[1].view->total_size().x;
-
- // track the maximum
- main_console_regwidth = MAX(regchars, main_console_regwidth);
- }
-
- // determine the width of the console (this is fixed)
- conchars = info->view[2].view->total_size().x;
-
- // loop over all CPUs and compute the width range based on dasm width
- info->minwidth = 0;
- info->maxwidth = 0;
- for (const debug_view_source *source = info->view[0].view->first_source(); source != NULL; source = source->next())
+ // allocate memory
+ T *info = global_alloc(T(*this));
+ if (info->is_valid())
{
- UINT32 minwidth, maxwidth, dischars;
-
- // set the view and fetch the width
- info->view[0].view->set_source(*source);
- dischars = info->view[0].view->total_size().x;
-
- // compute the preferred width
- minwidth = EDGE_WIDTH + main_console_regwidth * debug_font_width + vscroll_width + 2 * EDGE_WIDTH + 100 + EDGE_WIDTH;
- maxwidth = EDGE_WIDTH + main_console_regwidth * debug_font_width + vscroll_width + 2 * EDGE_WIDTH + MAX(dischars, conchars) * debug_font_width + vscroll_width + EDGE_WIDTH;
- info->minwidth = MAX(info->minwidth, minwidth);
- info->maxwidth = MAX(info->maxwidth, maxwidth);
+ m_window_list.prepend(*info);
+ return info;
}
-
- // get the work bounds
- SystemParametersInfo(SPI_GETWORKAREA, 0, &work_bounds, 0);
-
- // adjust the min/max sizes for the window style
- bounds.top = bounds.left = 0;
- bounds.right = bounds.bottom = info->minwidth;
- AdjustWindowRectEx(&bounds, DEBUG_WINDOW_STYLE, FALSE, DEBUG_WINDOW_STYLE_EX);
- info->minwidth = bounds.right - bounds.left;
-
- bounds.top = bounds.left = 0;
- bounds.right = bounds.bottom = info->maxwidth;
- AdjustWindowRectEx(&bounds, DEBUG_WINDOW_STYLE, FALSE, DEBUG_WINDOW_STYLE_EX);
- info->maxwidth = bounds.right - bounds.left;
-
- // position the window at the bottom-right
- bestwidth = (info->maxwidth < (work_bounds.right - work_bounds.left)) ? info->maxwidth : (work_bounds.right - work_bounds.left);
- bestheight = (500 < (work_bounds.bottom - work_bounds.top)) ? 500 : (work_bounds.bottom - work_bounds.top);
- SetWindowPos(info->wnd, HWND_TOP,
- work_bounds.right - bestwidth, work_bounds.bottom - bestheight,
- bestwidth, bestheight,
- SWP_SHOWWINDOW);
-
- // recompute the children
- console_set_cpu(debug_cpu_get_visible_cpu(machine));
-
- // set up the disassembly view to track the current pc
- downcast<debug_view_disasm *>(info->view[0].view)->set_expression("curpc");
-
- // mark the edit box as the default focus and set it
- info->focuswnd = info->editwnd;
- SetFocus(info->editwnd);
- return;
-
-cleanup:
- if (info->view[2].view)
- machine.debug_view().free_view(*info->view[2].view);
- if (info->view[1].view)
- machine.debug_view().free_view(*info->view[1].view);
- if (info->view[0].view)
- machine.debug_view().free_view(*info->view[0].view);
-}
-
-
-
-//============================================================
-// console_recompute_children
-//============================================================
-
-static void console_recompute_children(debugwin_info *info)
-{
- RECT parent, regrect, disrect, conrect, editrect;
- UINT32 regchars;//, dischars, conchars;
-
- // get the parent's dimensions
- GetClientRect(info->wnd, &parent);
-
- // get the total width of all three children
- //dischars = info->view[0].view->total_size().x;
- regchars = main_console_regwidth;
- //conchars = info->view[2].view->total_size().x;
-
- // registers always get their desired width, and span the entire height
- regrect.top = parent.top + EDGE_WIDTH;
- regrect.bottom = parent.bottom - EDGE_WIDTH;
- regrect.left = parent.left + EDGE_WIDTH;
- regrect.right = regrect.left + debug_font_width * regchars + vscroll_width;
-
- // edit box goes at the bottom of the remaining area
- editrect.bottom = parent.bottom - EDGE_WIDTH;
- editrect.top = editrect.bottom - debug_font_height - 4;
- editrect.left = regrect.right + EDGE_WIDTH * 2;
- editrect.right = parent.right - EDGE_WIDTH;
-
- // console and disassembly split the difference
- disrect.top = parent.top + EDGE_WIDTH;
- disrect.bottom = (editrect.top - parent.top) / 2 - EDGE_WIDTH;
- disrect.left = regrect.right + EDGE_WIDTH * 2;
- disrect.right = parent.right - EDGE_WIDTH;
-
- conrect.top = disrect.bottom + EDGE_WIDTH * 2;
- conrect.bottom = editrect.top - EDGE_WIDTH;
- conrect.left = regrect.right + EDGE_WIDTH * 2;
- conrect.right = parent.right - EDGE_WIDTH;
-
- // set the bounds of things
- debugwin_view_set_bounds(&info->view[0], info->wnd, &disrect);
- debugwin_view_set_bounds(&info->view[1], info->wnd, &regrect);
- debugwin_view_set_bounds(&info->view[2], info->wnd, &conrect);
- smart_set_window_bounds(info->editwnd, info->wnd, &editrect);
-}
-
-
-
-//============================================================
-// console_process_string
-//============================================================
-
-static void console_process_string(debugwin_info *info, const char *string)
-{
- TCHAR buffer = 0;
-
- // an empty string is a single step
- if (string[0] == 0)
- debug_cpu_get_visible_cpu(info->machine())->debug()->single_step();
-
- // otherwise, just process the command
else
- debug_console_execute_command(info->machine(), string, 1);
-
- // clear the edit text box
- SendMessage(info->editwnd, WM_SETTEXT, 0, (LPARAM)&buffer);
-}
-
-
-
-//============================================================
-// console_set_cpu
-//============================================================
-
-static void console_set_cpu(device_t *device)
-{
- // first set all the views to the new cpu number
- main_console->view[0].view->set_source(*main_console->view[0].view->source_for_device(device));
- main_console->view[1].view->set_source(*main_console->view[1].view->source_for_device(device));
-
- // then update the caption
- char curtitle[256];
- astring title;
-
- title.printf("Debug: %s - %s '%s'", device->machine().system().name, device->name(), device->tag());
- win_get_window_text_utf8(main_console->wnd, curtitle, ARRAY_LENGTH(curtitle));
- if (title.cmp(curtitle) != 0)
- win_set_window_text_utf8(main_console->wnd, title);
-
- // and recompute the children
- console_recompute_children(main_console);
-}
-
-
-
-//============================================================
-// create_standard_menubar
-//============================================================
-
-static HMENU create_standard_menubar(void)
-{
- HMENU menubar, debugmenu;
-
- // create the debug menu
- debugmenu = CreatePopupMenu();
- if (debugmenu == NULL)
- return NULL;
- AppendMenu(debugmenu, MF_ENABLED, ID_NEW_MEMORY_WND, TEXT("New Memory Window\tCtrl+M"));
- AppendMenu(debugmenu, MF_ENABLED, ID_NEW_DISASM_WND, TEXT("New Disassembly Window\tCtrl+D"));
- AppendMenu(debugmenu, MF_ENABLED, ID_NEW_LOG_WND, TEXT("New Error Log Window\tCtrl+L"));
- AppendMenu(debugmenu, MF_DISABLED | MF_SEPARATOR, 0, TEXT(""));
- AppendMenu(debugmenu, MF_ENABLED, ID_RUN, TEXT("Run\tF5"));
- AppendMenu(debugmenu, MF_ENABLED, ID_RUN_AND_HIDE, TEXT("Run and Hide Debugger\tF12"));
- AppendMenu(debugmenu, MF_ENABLED, ID_NEXT_CPU, TEXT("Run to Next CPU\tF6"));
- AppendMenu(debugmenu, MF_ENABLED, ID_RUN_IRQ, TEXT("Run until Next Interrupt on This CPU\tF7"));
- AppendMenu(debugmenu, MF_ENABLED, ID_RUN_VBLANK, TEXT("Run until Next VBLANK\tF8"));
- AppendMenu(debugmenu, MF_DISABLED | MF_SEPARATOR, 0, TEXT(""));
- AppendMenu(debugmenu, MF_ENABLED, ID_STEP, TEXT("Step Into\tF11"));
- AppendMenu(debugmenu, MF_ENABLED, ID_STEP_OVER, TEXT("Step Over\tF10"));
- AppendMenu(debugmenu, MF_ENABLED, ID_STEP_OUT, TEXT("Step Out\tShift+F11"));
- AppendMenu(debugmenu, MF_DISABLED | MF_SEPARATOR, 0, TEXT(""));
- AppendMenu(debugmenu, MF_ENABLED, ID_SOFT_RESET, TEXT("Soft Reset\tF3"));
- AppendMenu(debugmenu, MF_ENABLED, ID_HARD_RESET, TEXT("Hard Reset\tShift+F3"));
- AppendMenu(debugmenu, MF_ENABLED, ID_EXIT, TEXT("Exit"));
-
- // create the menu bar
- menubar = CreateMenu();
- if (menubar == NULL)
{
- DestroyMenu(debugmenu);
+ global_free(info);
return NULL;
}
- AppendMenu(menubar, MF_ENABLED | MF_POPUP, (UINT_PTR)debugmenu, TEXT("Debug"));
-
- return menubar;
-}
-
-//============================================================
-// copy_extension_list
-//============================================================
-
-static int copy_extension_list(char *dest, size_t dest_len, const char *extensions)
-{
- const char *s;
- int pos = 0;
-
- // our extension lists are comma delimited; Win32 expects to see lists
- // delimited by semicolons
- s = extensions;
- while(*s)
- {
- // append a semicolon if not at the beginning
- if (s != extensions)
- pos += snprintf(&dest[pos], dest_len - pos, ";");
-
- // append ".*"
- pos += snprintf(&dest[pos], dest_len - pos, "*.");
-
- // append the file extension
- while(*s && (*s != ','))
- {
- pos += snprintf(&dest[pos], dest_len - pos, "%c", *s);
- s++;
- }
-
- // if we found a comma, advance
- while(*s == ',')
- s++;
- }
- return pos;
-}
-
-//============================================================
-// add_filter_entry
-//============================================================
-
-static int add_filter_entry(char *dest, size_t dest_len, const char *description, const char *extensions)
-{
- int pos = 0;
-
- // add the description
- pos += snprintf(&dest[pos], dest_len - pos, "%s (", description);
-
- // add the extensions to the description
- pos += copy_extension_list(&dest[pos], dest_len - pos, extensions);
-
- // add the trailing rparen and '|' character
- pos += snprintf(&dest[pos], dest_len - pos, ")|");
-
- // now add the extension list itself
- pos += copy_extension_list(&dest[pos], dest_len - pos, extensions);
-
- // append a '|'
- pos += snprintf(&dest[pos], dest_len - pos, "|");
-
- return pos;
-}
-//============================================================
-// build_generic_filter
-//============================================================
-
-static void build_generic_filter(device_image_interface *img, int is_save, char *filter, size_t filter_len)
-{
- char *s;
-
- const char *file_extension;
-
- /* copy the string */
- file_extension = img->file_extensions();
-
- // start writing the filter
- s = filter;
-
- // common image types
- s += add_filter_entry(filter, filter_len, "Common image types", file_extension);
-
- // all files
- s += sprintf(s, "All files (*.*)|*.*|");
-
- // compressed
- if (!is_save)
- s += sprintf(s, "Compressed Images (*.zip)|*.zip|");
-
- *(s++) = '\0';
-}
-
-//============================================================
-// global_handle_command
-//============================================================
-
-static int global_handle_command(debugwin_info *info, WPARAM wparam, LPARAM lparam)
-{
- if (HIWORD(wparam) == 0)
- switch (LOWORD(wparam))
- {
- case ID_NEW_MEMORY_WND:
- memory_create_window(info->machine());
- return 1;
-
- case ID_NEW_DISASM_WND:
- disasm_create_window(info->machine());
- return 1;
-
- case ID_NEW_LOG_WND:
- log_create_window(info->machine());
- return 1;
-
- case ID_RUN_AND_HIDE:
- smart_show_all(FALSE);
- case ID_RUN:
- debug_cpu_get_visible_cpu(info->machine())->debug()->go();
- return 1;
-
- case ID_NEXT_CPU:
- debug_cpu_get_visible_cpu(info->machine())->debug()->go_next_device();
- return 1;
-
- case ID_RUN_VBLANK:
- debug_cpu_get_visible_cpu(info->machine())->debug()->go_vblank();
- return 1;
-
- case ID_RUN_IRQ:
- debug_cpu_get_visible_cpu(info->machine())->debug()->go_interrupt();
- return 1;
-
- case ID_STEP:
- debug_cpu_get_visible_cpu(info->machine())->debug()->single_step();
- return 1;
-
- case ID_STEP_OVER:
- debug_cpu_get_visible_cpu(info->machine())->debug()->single_step_over();
- return 1;
-
- case ID_STEP_OUT:
- debug_cpu_get_visible_cpu(info->machine())->debug()->single_step_out();
- return 1;
-
- case ID_HARD_RESET:
- info->machine().schedule_hard_reset();
- return 1;
-
- case ID_SOFT_RESET:
- info->machine().schedule_soft_reset();
- debug_cpu_get_visible_cpu(info->machine())->debug()->go();
- return 1;
-
- case ID_EXIT:
- if (info->focuswnd != NULL)
- SetFocus(info->focuswnd);
- info->machine().schedule_exit();
- return 1;
- }
- if (LOWORD(wparam) >= ID_DEVICE_OPTIONS) {
- UINT32 devid = (LOWORD(wparam) - ID_DEVICE_OPTIONS) / DEVOPTION_MAX;
- image_interface_iterator iter(info->machine().root_device());
- device_image_interface *img = iter.byindex(devid);
- if (img!=NULL) {
- switch ((LOWORD(wparam) - ID_DEVICE_OPTIONS) % DEVOPTION_MAX)
- {
- case DEVOPTION_OPEN :
- {
- char filter[2048];
- build_generic_filter(img, FALSE, filter, ARRAY_LENGTH(filter));
-
- TCHAR selectedFilename[MAX_PATH];
- selectedFilename[0] = '\0';
- LPTSTR buffer;
- LPTSTR t_filter = NULL;
-
- buffer = tstring_from_utf8(filter);
-
- // convert a pipe-char delimited string into a NUL delimited string
- t_filter = (LPTSTR) alloca((_tcslen(buffer) + 2) * sizeof(*t_filter));
- int i = 0;
- for (i = 0; buffer[i] != '\0'; i++)
- t_filter[i] = (buffer[i] != '|') ? buffer[i] : '\0';
- t_filter[i++] = '\0';
- t_filter[i++] = '\0';
- osd_free(buffer);
-
-
- OPENFILENAME ofn;
- memset(&ofn,0,sizeof(ofn));
- ofn.lStructSize = sizeof(ofn);
- ofn.hwndOwner = NULL;
- ofn.lpstrFile = selectedFilename;
- ofn.lpstrFile[0] = '\0';
- ofn.nMaxFile = MAX_PATH;
- ofn.lpstrFilter = t_filter;
- ofn.nFilterIndex = 1;
- ofn.lpstrFileTitle = NULL;
- ofn.nMaxFileTitle = 0;
- ofn.lpstrInitialDir = NULL;
- ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
-
- if (GetOpenFileName(&ofn)) {
- img->load(utf8_from_tstring(selectedFilename));
- }
- }
- return 1;
-/* case DEVOPTION_CREATE:
- return 1;*/
- case DEVOPTION_CLOSE:
- img->unload();
- return 1;
- default:
- if (img->device().type() == CASSETTE) {
- cassette_image_device* cassette = dynamic_cast<cassette_image_device*>(&img->device());
- switch ((LOWORD(wparam) - ID_DEVICE_OPTIONS) % DEVOPTION_MAX)
- {
- case DEVOPTION_CASSETTE_STOPPAUSE:
- cassette->change_state(CASSETTE_STOPPED, CASSETTE_MASK_UISTATE);
- return 1;
- case DEVOPTION_CASSETTE_PLAY:
- cassette->change_state(CASSETTE_PLAY, CASSETTE_MASK_UISTATE);
- return 1;
- case DEVOPTION_CASSETTE_RECORD:
- cassette->change_state(CASSETTE_RECORD, CASSETTE_MASK_UISTATE);
- return 1;
- case DEVOPTION_CASSETTE_REWIND:
- cassette->seek(-60.0, SEEK_CUR);
- return 1;
- case DEVOPTION_CASSETTE_FASTFORWARD:
- cassette->seek(+60.0, SEEK_CUR);
- return 1;
- }
- }
- }
- }
- }
- return 0;
-}
-
-
-
-//============================================================
-// global_handle_key
-//============================================================
-
-static int global_handle_key(debugwin_info *info, WPARAM wparam, LPARAM lparam)
-{
- /* ignore any keys that are received while the debug key is down */
- if (!waiting_for_debugger && debugwin_seq_pressed(info->machine()))
- return 1;
-
- switch (wparam)
- {
- case VK_F3:
- if (GetAsyncKeyState(VK_SHIFT) & 0x8000)
- SendMessage(info->wnd, WM_COMMAND, ID_HARD_RESET, 0);
- else
- SendMessage(info->wnd, WM_COMMAND, ID_SOFT_RESET, 0);
- return 1;
-
- case VK_F4:
- if (GetAsyncKeyState(VK_MENU) & 0x8000)
- {
- /* ajg - never gets here since 'alt' seems to be captured somewhere else - menu maybe? */
- SendMessage(info->wnd, WM_COMMAND, ID_EXIT, 0);
- return 1;
- }
- break;
-
- case VK_F5:
- SendMessage(info->wnd, WM_COMMAND, ID_RUN, 0);
- return 1;
-
- case VK_F6:
- SendMessage(info->wnd, WM_COMMAND, ID_NEXT_CPU, 0);
- return 1;
-
- case VK_F7:
- SendMessage(info->wnd, WM_COMMAND, ID_RUN_IRQ, 0);
- return 1;
-
- case VK_F8:
- SendMessage(info->wnd, WM_COMMAND, ID_RUN_VBLANK, 0);
- return 1;
-
- case VK_F10:
- SendMessage(info->wnd, WM_COMMAND, ID_STEP_OVER, 0);
- return 1;
-
- case VK_F11:
- if (GetAsyncKeyState(VK_SHIFT) & 0x8000)
- SendMessage(info->wnd, WM_COMMAND, ID_STEP_OUT, 0);
- else
- SendMessage(info->wnd, WM_COMMAND, ID_STEP, 0);
- return 1;
-
- case VK_F12:
- SendMessage(info->wnd, WM_COMMAND, ID_RUN_AND_HIDE, 0);
- return 1;
-
- case 'M':
- if (GetAsyncKeyState(VK_CONTROL) & 0x8000)
- {
- SendMessage(info->wnd, WM_COMMAND, ID_NEW_MEMORY_WND, 0);
- return 1;
- }
- break;
-
- case 'D':
- if (GetAsyncKeyState(VK_CONTROL) & 0x8000)
- {
- SendMessage(info->wnd, WM_COMMAND, ID_NEW_DISASM_WND, 0);
- return 1;
- }
- break;
-
- case 'L':
- if (GetAsyncKeyState(VK_CONTROL) & 0x8000)
- {
- SendMessage(info->wnd, WM_COMMAND, ID_NEW_LOG_WND, 0);
- return 1;
- }
- break;
- }
-
- return 0;
-}
-
-
-
-//============================================================
-// smart_set_window_bounds
-//============================================================
-
-static void smart_set_window_bounds(HWND wnd, HWND parent, RECT *bounds)
-{
- RECT curbounds;
- int flags = 0;
-
- // first get the current bounds, relative to the parent
- GetWindowRect(wnd, &curbounds);
- if (parent != NULL)
- {
- RECT parentbounds;
- GetWindowRect(parent, &parentbounds);
- curbounds.top -= parentbounds.top;
- curbounds.bottom -= parentbounds.top;
- curbounds.left -= parentbounds.left;
- curbounds.right -= parentbounds.left;
- }
-
- // if the position matches, don't change it
- if (curbounds.top == bounds->top && curbounds.left == bounds->left)
- flags |= SWP_NOMOVE;
- if ((curbounds.bottom - curbounds.top) == (bounds->bottom - bounds->top) &&
- (curbounds.right - curbounds.left) == (bounds->right - bounds->left))
- flags |= SWP_NOSIZE;
-
- // if we need to, reposition the window
- if (flags != (SWP_NOMOVE | SWP_NOSIZE))
- SetWindowPos(wnd, NULL,
- bounds->left, bounds->top,
- bounds->right - bounds->left, bounds->bottom - bounds->top,
- SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER | flags);
}
-
-//============================================================
-// smart_show_window
-//============================================================
-
-static void smart_show_window(HWND wnd, BOOL show)
-{
- BOOL visible = IsWindowVisible(wnd);
- if ((visible && !show) || (!visible && show))
- ShowWindow(wnd, show ? SW_SHOW : SW_HIDE);
-}
-
-
-
-//============================================================
-// smart_show_all
-//============================================================
-
-static void smart_show_all(BOOL show)
-{
- debugwin_info *info;
- if (!show)
- SetForegroundWindow(win_window_list->m_hwnd);
- for (info = window_list; info != NULL; info = info->next)
- smart_show_window(info->wnd, show);
-}
#else /* not windows */
- MODULE_NOT_SUPPORTED(debugger_windows, OSD_DEBUG_PROVIDER, "windows")
+MODULE_NOT_SUPPORTED(debugger_windows, OSD_DEBUG_PROVIDER, "windows")
#endif
MODULE_DEFINITION(DEBUG_WINDOWS, debugger_windows)